注意这里分配并初始化了一个struct i2c_client结构.但是没有注册这个clinet.此外,这个函数中还有一个比较奇怪的操作.不是在前面已经将i2c_dev->adap指向要操作的adapter么?为什么还要以adapter->nr为关键字从i2c_adapter_idr去找这个操作的adapter呢?注意了,调用i2c_get_adapter()从总线号nr找到操作的adapter的时候,还会增加module的引用计数.这样可以防止模块意外被释放掉.也许有人会有这样的疑问,那 i2c_dev->adap->nr操作,如果i2c_dev->adap被释放掉的话,不是一样会引起系统崩溃么?这里因为,在i2cdev_attach_adapter()间接的增加了一次adapter的一次引用计数.如下:
static int i2cdev_attach_adapter(struct i2c_adapter *adap)
{
......
i2c_dev->dev = device_create(i2c_dev_class, &adap->dev,
MKDEV(I2C_MAJOR, adap->nr),
"i2c-%d", adap->nr);
......
}
看到了么,i2c_dev内嵌的device是以adap->dev为父结点,在device_create()中会增次adap->dev的一次引用计数.
好了,open()操作到此就完成了.
使用方法:(参考kernel-test/i2c-msm-test.c)
1、构造struct i2c_msg
[读] struct i2c_msg msgs[] = {
[0] = {
.addr = slave_address,
.flags = 0,
.buf = (void *)offset_data,
.len = ARRAY_SIZE(offset_data),
},
[1] = {
.addr = slave_address,
.flags = I2C_M_RD,
.buf = (void *)buf,
.len = count,
},
};
[写] struct i2c_msg msgs[] = {
[0] = {
.addr = slave_address,
.flags = 0,
.buf = (void *)data,
.len = (2 + len) * sizeof(*data),
},
}
[读] struct i2c_msg msgs[] = {
[0] = {
.addr = slave_address,
.flags = 0,
.buf = (void *)offset_data,
.len = ARRAY_SIZE(offset_data),
},
[1] = {
.addr = slave_address,
.flags = I2C_M_RD,
.buf = (void *)buf,
.len = count,
},
};
[写] struct i2c_msg msgs[] = {
[0] = {
.addr = slave_address,
.flags = 0,
.buf = (void *)data,
.len = (2 + len) * sizeof(*data),
},
}
2、通过ioctl操作设备
view plaincopy to clipboardprint?
static int do_rdwr(int fd, struct i2c_msg *msgs, int nmsgs)
{
struct i2c_rdwr_ioctl_data msgset = {
.msgs = msgs,
.nmsgs = nmsgs, /* msgs 个数*/
};
if (msgs == NULL || nmsgs <= 0)
return -1;
if (ioctl(fd, I2C_RDWR, &msgset) < 0)
return -1;
return 0;
}
static int do_rdwr(int fd, struct i2c_msg *msgs, int nmsgs)
{
struct i2c_rdwr_ioctl_data msgset = {
.msgs = msgs,
.nmsgs = nmsgs, /* msgs 个数*/
};
if (msgs == NULL || nmsgs <= 0)
return -1;
if (ioctl(fd, I2C_RDWR, &msgset) < 0)
return -1;
return 0;
}
3、ioctl命令字:
#define I2C_SMBUS_READ 1
#define I2C_SMBUS_WRITE 0
#define I2C_SMBUS_QUICK 0
#define I2C_SMBUS_BYTE 1
#define I2C_SMBUS_BYTE_DATA 2
#define I2C_SMBUS_WORD_DATA 3
#define I2C_SMBUS_PROC_CALL 4
#define I2C_SMBUS_BLOCK_DATA 5
#define I2C_SMBUS_I2C_BLOCK_DATA 6
#define I2C_SMBUS_BLOCK_PROC_CALL 7
#define I2C_RETRIES 0x0701
#define I2C_TIMEOUT 0x0702
#define I2C_SLAVE 0x0703
#define I2C_SLAVE_FORCE 0x0706
#define I2C_TENBIT 0x0704
#define I2C_FUNCS 0x0705
#define I2C_RDWR 0x0707
#define I2C_PEC 0x0708
#define I2C_SMBUS 0x0720