I2c在应用层读写有两种方式。
1
ioctl(fd,I2C_TIMEOUT,1);/*超时时间*/
ioctl(fd,I2C_RETRIES,2);/*重复次数*/
/***write data to e2prom**/
e2prom_data.nmsgs=1;
(e2prom_data.msgs[0]).len=2; //1个 e2prom 写入目标的地址和1个数据
(e2prom_data.msgs[0]).addr=0x50;//e2prom 设备地址
(e2prom_data.msgs[0]).flags=0; //write
(e2prom_data.msgs[0]).buf=(unsigned char*)malloc(2);
(e2prom_data.msgs[0]).buf[0]=0x10;// e2prom 写入目标的地址
(e2prom_data.msgs[0]).buf[1]=0x58;//the data to write
ret=ioctl(fd,I2C_RDWR,(unsigned long)&e2prom_data);
2
ioctl(fd,I2C_TIMEOUT,1);/*超时时间*/
ioctl(fd,I2C_RETRIES,2);/*重复次数*/
ioctl(fd,I2C_SLAVE,0向0);/*设置地址*/
wirte(fd,&addr,2);//写地址
read(fd,buf,1);//度数据
在内核里写i2c设备驱动的两种方式
.driver = {
.name = "ov3640",
},
.attach_adapter = ov3640_attach_adapter,
.probe = ov3640_probe,
.remove = ov3640_remove,
.command = ov3640_command,
.id_table = ov3640_i2c_id,
};
static __init int ov3640_init(void)
{
printk("ov3640 camera initialized\n");
return i2c_add_driver(&ov3640_i2c_driver);
}
{
int ret = 0;
struct i2c_board_info info;
printk("[ov3640]ov3640_attach_adapter.\n");
memset(&info, 0, sizeof(struct i2c_board_info));
strlcpy(info.type, "ov3640", I2C_NAME_SIZE);
info.addr = ov3640_data.addr;//地址信息包装成结构体i2c_board_info 这个信息最重要
ov3640_data.camera_data.client = i2c_new_device(adapter, &info);
if (!ov3640_data.camera_data.client)
{
printk("failed to abc ov3640 driver\n");
return -ENODEV;
}
if (!ov3640_data.camera_data.client->driver)
{
i2c_unregister_device(ov3640_data.camera_data.client);
ov3640_data.camera_data.client = NULL;
err("failed to attach ov3640 driver\n");
return -ENODEV;
}
list_add_tail(&ov3640_data.camera_data.client->detected,
&ov3640_data.camera_data.client->driver->clients);
s3c_fimc_register_camera(&ov3640_data.camera_data);
s3c_fimc_reset_camera(0);
return 0;
}
static int ov3640_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
i2c_set_clientdata(client, &ov3640_data);
//ov3640_start(client);
return 0;
}
到此一个I2C设备就注册成功了。
probe方式
.driver = {
.name = "at24",
.owner = THIS_MODULE,
},
.probe = at24_probe,
.remove = __devexit_p(at24_remove),
.id_table = at24_ids,
};
根据器id_table匹配是否调用probe函数。probe函数主要实现同方式一
● 注册i2c_board_info
对于Probe模式,通常在平台代码中要完成i2c_board_info的注册。方法如下:
static struct i2c_board_info __initdata test_i2c_devices[] = {
{
I2C_BOARD_INFO("pca9555", 0x27),//pca9555为芯片名称,0x27为芯片地址
.platform_data = &pca9555_data,
}, {
I2C_BOARD_INFO("mt9v022", 0x48),
.platform_data = &iclink[0], /* With extender */
}, {
I2C_BOARD_INFO("mt9m001", 0x5d),
.platform_data = &iclink[0], /* With extender */
},
};
i2c_register_board_info(0, test_i2c_devices,ARRAY_SIZE(test_i2c_devices)); //注册
i2c_client就是在注册过程中构建的。但有一点需要注意的是i2c_register_board_info并没有EXPORT_SYMBOL给模块使用。