简单的说,i2c驱动也就三步吧,注册i2c设备,注册i2c设备驱动,创建sysfs文件供上层调用。
1. 注册i2c设备。
先定义一个i2c_board_info
static struct i2c_board_info __initdata xxxx_i2c_info[] = { { I2C_BOARD_INFO("XXXX", 0x1D), .platform_data = &xxxx_platform_data, }, };
再注册,一般会注册一个client。
i2c_register_board_info()
强烈建议有兴趣的可以看看这个函数的源码,可以学到很多。
2. 注册i2c设备driver
定义再注册
static struct i2c_driver xxx_i2c_driver = { .id_table = xxx_i2c_id, .probe = xxx_i2c_probe, .remove = __exit_p(xxx_i2c_remove), .driver = { .name = "xxx", }, };
注册函数
i2c_add_driver(&xxx_i2c_driver);
注册过程中,主要是调用probe函数,如何跑到probe函数里同样需要跟代码。这里不详述。讲讲probe函数里主要干什么。
static int xxx_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { int rc = 0; printk("%s called!\n", __func__); if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { printk("i2c_check_functionality failed\n"); goto probe_failure; } xxx_sensorw = kzalloc(sizeof(struct xxx_work_t), GFP_KERNEL); if (!xxx_sensorw) { printk("kzalloc failed.\n"); rc = -ENOMEM; goto probe_failure; } i2c_set_clientdata(client, xxx_sensorw); xxx_init_client(client); xxx_client = client; msleep(50); printk("%s successed! rc = %d\n", __func__, rc); return 0; probe_failure: printk("%s failed! rc = %d\n", __func__, rc); return rc; }
probe函数主要是获取client,而后便可以通过client中adapter的方法来传输数据:
static int xxx_i2c_txdata(const uint16_t saddr, uint8_t *txdata, const uint16_t length) { struct i2c_msg msg[] = { { .addr = saddr, .flags = 0, .len = length, .buf = txdata, }, }; if (i2c_transfer(xxx_client->adapter, msg, 1) < 0) { printk("xxx_i2c_txdata faild 0x%x\n", saddr); return -EIO; } return 0; }
3. 创建sysfs供上层调用
可以通过函数
sysfs_create_group(&(pdev->dev.kobj), &xxx_attribute_group);
来创建。
以上就是简要说说,主要还是要看源码才能更深的理解这些流程。
I2C驱动实例解析
时间: 2024-11-03 05:28:34