1. 框架 1.1 硬件协议简介 1.2 驱动框架 1.3 bus-drv-dev模型及写程序 a. 设备的4种构建方法 a.1 定义一个i2c_board_info, 里面有:名字, 设备地址 然后i2c_register_board_info(busnum, ...) (把它们放入__i2c_board_list链表) list_add_tail(&devinfo->list, &__i2c_board_list); 链表何时使用: i2c_register_adapter > i2c_scan_static_board_info > i2c_new_device 使用限制:必须在 i2c_register_adapter 之前 i2c_register_board_info 所以:不适合我们动态加载insmod a.2 直接i2c_new_device, i2c_new_probed_device a.2.1 i2c_new_device : 认为设备肯定存在 a.2.2 i2c_new_probed_device :对于"已经识别出来的设备"(probed_device),才会创建("new") i2c_new_probed_device probe(adap, addr_list[i]) /* 确定设备是否真实存在 */ info->addr = addr_list[i]; i2c_new_device(adap, info); a.3 从用户空间创建设备 创建设备 echo at24c08 0x50 > /sys/class/i2c-adapter/i2c-0/new_device 导致i2c_new_device被调用 删除设备 echo 0x50 > /sys/class/i2c-adapter/i2c-0/delete_device 导致i2c_unregister_device a.4 前面的3种方法都要事先确定适配器(I2C总线,I2C控制器) 如果我事先并不知道这个I2C设备在哪个适配器上,怎么办?去class表示的所有的适配器上查找 有上一些I2C设备的地址是一样,怎么继续分配它是哪一款?用detect函数 static struct i2c_driver at24cxx_driver = { .class = I2C_CLASS_HWMON, /* 表示去哪些适配器上找设备 */ .driver = { .name = "100ask", .owner = THIS_MODULE, }, .probe = at24cxx_probe, .remove = __devexit_p(at24cxx_remove), .id_table = at24cxx_id_table, .detect = at24cxx_detect, /* 用这个函数来检测设备确实存在 */ .address_list = addr_list, /* 这些设备的地址 */ }; 去"class表示的这一类"I2C适配器,用"detect函数"来确定能否找到"address_list里的设备", 如果能找到就调用i2c_new_device来注册i2c_client, 这会和i2c_driver的id_table比较, 如果匹配,调用probe i2c_add_driver i2c_register_driver a. at24cxx_driver放入i2c_bus_type的drv链表 并且从dev链表里取出能匹配的i2c_client并调用probe driver_register b. 对于每一个适配器,调用__process_new_driver 对于每一个适配器,调用它的函数确定address_list里的设备是否存在 如果存在,再调用detect进一步确定、设置,然后i2c_new_device /* Walk the adapters that are already present */ i2c_for_each_dev(driver, __process_new_driver); __process_new_driver i2c_do_add_adapter /* Detect supported devices on that bus, and instantiate them */ i2c_detect(adap, driver); for (i = 0; address_list[i] != I2C_CLIENT_END; i += 1) { err = i2c_detect_address(temp_client, driver); /* 判断这个设备是否存在:简单的发出S信号确定有ACK */ if (!i2c_default_probe(adapter, addr)) return 0; memset(&info, 0, sizeof(struct i2c_board_info)); info.addr = addr; // 设置info.type err = driver->detect(temp_client, &info); i2c_new_device b. 驱动的写法 2. 完善设备驱动程序 3. 不自己写驱动直接访问 Device Drivers I2C support <*> I2C device interface 4. 编写"总线(适配器adapter)"驱动 Device Drivers I2C support I2C Hardware Bus support < > S3C2410 I2C Driver nfs 30000000 192.168.1.123:/work/nfs_root/uImage_noi2cbus; bootm 30000000