首页 > 代码库 > I2C驱动实例解析

I2C驱动实例解析

简单的说,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 = http://www.mamicode.com/&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);


来创建。

以上就是简要说说,主要还是要看源码才能更深的理解这些流程。