Linux设备模型之i2c子系统

I2c子系统将i2c控制器(i2c寄存器所在的那块电路)抽象出来,用adapter(适配器)这个结构来描述,可以说一个适配器就代表一条i2c总线,而挂接在i2c总线上的设备是用client这个结构体来表述,另外i2c_bus上的设备链表挂接的不单单是连接的这条i2c上的client,同样adapter也作为一个设备挂在其所在的i2c_bus,也就是说控制器和设备都作为i2c_bus上的设备连接在设备链表,他们用内嵌的device的type这个成员来区分,适配器的类型为i2c_adapter_type,client的类型为i2c_client_type。

一、i2c相关的描述结构

     首先看一下i2c子系统给adapter定义的描述结构:

[cpp]
  1.  struct i2c_adapter {  
  2.     struct module *owner;  
  3.     unsigned int id;  
  4.     unsigned int class;                     // 适配器支持的类型,如传感器,eeprom等           
  5.     const struct i2c_algorithm *algo;        //该适配器的通信函数       
  6.     void *algo_data;  
  7.     /* data fields that are valid for all devices   */  
  8.     struct rt_mutex bus_lock;  
  9.     int timeout;                             //超时时间限定   
  10.     int retries;                             //通信重复次数限定   
  11.     /*  
  12.      * 内嵌的标准device,其中dev->type标识该设备 
  13.      * 是个adapter,其值为i2c_adapter_type 
  14.      */  
  15.     struct device dev;        
  16.       
  17.     int nr;                                  //适配器编号也是bus编号,第几条i2c总线   
  18.     char name[48];                           //名字   
  19.     struct completion dev_released;  
  20.     struct mutex userspace_clients_lock;  
  21.     struct list_head userspace_clients;  
  22. };  

   再来看一下client的描述结构:

[cpp]
  1.  struct i2c_client {  
  2.     unsigned short flags;                   //设备的标志,如唤醒标志等等   
  3.       
  4.     /* chip address - NOTE: 7bit    */  
  5.     /* addresses are stored in the  */  
  6.     /* _LOWER_ 7 bits       */  
  7.     unsigned short addr;                    //设备的地址   
  8.     char name[I2C_NAME_SIZE];               //设备的名字   
  9.     struct i2c_adapter *adapter;            //设备所属的适配器   
  10.     struct i2c_driver *driver;              //设备的driver   
  11.       
  12.     /*  
  13.      * 内嵌的标准device模型,其中dev->type标识该设备 
  14.      * 是个client,其值为i2c_client_type 
  15.      */  
  16.     struct device dev;      /* the device structure */  
  17.     int irq;                               //中断号   
  18.     struct list_head detected;             //挂接点,挂接在adapter   
  19. };  


    下面是driver的表述结构i2c_driver:

[cpp]
  1.  struct i2c_driver {  
  2. unsigned int class;                                   //支持的类型,与adapter的class相对   
  3. /* Notifies the driver that a new bus has appeared or is about to be 
  4.  * removed. You should avoid using this if you can, it will probably 
  5.  * be removed in a near future. 
  6.  */  
  7.    
  8. int (*attach_adapter)(struct i2c_adapter *);          //旧式探测函数   
  9. int (*detach_adapter)(struct i2c_adapter *);  
  10. /* Standard driver model interfaces */  
  11. int (*probe)(struct i2c_client *, const struct i2c_device_id *);  
  12. int (*remove)(struct i2c_client *);  
  13. /* driver model interfaces that don't relate to enumeration  */  
  14. void (*shutdown)(struct i2c_client *);  
  15. int (*suspend)(struct i2c_client *, pm_message_t mesg);  
  16. int (*resume)(struct i2c_client *);  
  17. /* Alert callback, for example for the SMBus alert protocol. 
  18.  * The format and meaning of the data value depends on the protocol. 
  19.  * For the SMBus alert protocol, there is a single bit of data passed 
  20.  * as the alert response's low bit ("event flag"). 
  21.  */  
  22. void (*alert)(struct i2c_client *, unsigned int data);  
  23. /* a ioctl like command that can be used to perform specific functions 
  24.  * with the device. 
  25.  */  
  26. int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);  
  27.  /* 
  28.  * 内嵌的标准driver,driver的of_match_table成员也用于标识其支持 
  29.  * 的设备,并且优先级高于id_table 
  30.  */  
  31. struct device_driver driver;  
  32.   
  33. const struct i2c_device_id *id_table;                            //支持的client信息表   
  34. /* Device detection callback for automatic device creation */  
  35.   
  36. int (*detect)(struct i2c_client *, struct i2c_board_info *);     //探测函数   
  37. const unsigned short *address_list;                              //driver支持的client地址   
  38. struct list_head clients;                                        //挂接其探测到的支持的设备   
  39. ;  

      另外client端有一条全局链表,用于串联所有i2c的client设备,为__i2c_board_list,也就是说client可以静态注册亦可动态
被探测,静态注册挂接在该链表上的结构为:

[cpp]
  1. struct i2c_devinfo {  
  2.     struct list_head    list;                     //连接指针指向前后设备   
  3.     int         busnum;                           //所在bus的编号   
  4.     struct i2c_board_info   board_info;           //板级平台信息相关的结构体   
  5. };  
  6. //其中 i2c_board_info结构的源码为:    
  7. struct i2c_board_info {  
  8.     char        type[I2C_NAME_SIZE];             //名字   
  9.     unsigned short  flags;                       //标志   
  10.     unsigned short  addr;                        //地址   
  11.     void        *platform_data;                  //私有特殊数据   
  12.     struct dev_archdata *archdata;  
  13. #ifdef CONFIG_OF   
  14.     struct device_node *of_node;                 //节点   
  15. #endi   
  16.     int     irq;                                 //中断号   
  17. };  

    i2c_devinfo结构静态注册的信息最后都会被整合集成到client中,形成一个标准的i2c_client设备并注册。

相关推荐