msm7227平台Linux I2C驱动分析(2.6.29)(5)

注意这里分配并初始化了一个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   

linux

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwswys.html