感谢支持
我们一直在努力

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设备并注册。

二、i2c核心初始化代码分析


    首先看一下i2c平台无关的核心初始化,代码位于drivers/i2c/i2c-core.c下:


[cpp]


  1. static int __init i2c_init(void)  

  2. {  

  3.     int retval;  

  4.    /* 

  5.     * 注册i2c_bus 

  6.     */  

  7.     retval = bus_register(&i2c_bus_type);                

  8.     if (retval)  

  9.         return retval;  

  10. #ifdef CONFIG_I2C_COMPAT                               

  11.    /* 

  12.     * 在sys/class下创建适配器目录 

  13.     */  

  14.     i2c_adapter_compat_class = class_compat_register(“i2c-adapter”);  

  15.     if (!i2c_adapter_compat_class) {  

  16.         retval = -ENOMEM;  

  17.         goto bus_err;  

  18.     }  

  19.       

  20. #endif   

  21.    /* 

  22.     * 增加一个虚拟的driver 

  23.     */  

  24.     retval = i2c_add_driver(&dummy_driver);               

  25.     if (retval)  

  26.         goto class_err;  

  27.     return 0;  

  28. class_err:  

  29. #ifdef CONFIG_I2C_COMPAT   

  30.     class_compat_unregister(i2c_adapter_compat_class);    

  31. bus_err:  

  32. #endif   

  33.     bus_unregister(&i2c_bus_type);  

  34.     return retval;  

  35. }  

  36. //其中的i2c_bus_type原型为:   

  37. struct bus_type i2c_bus_type = {  

  38.     .name       = “i2c”,  

  39.     .match      = i2c_device_match,  

  40.     .probe      = i2c_device_probe,  

  41.     .remove     = i2c_device_remove,  

  42.     .shutdown   = i2c_device_shutdown,  

  43.     .pm     = &i2c_device_pm_ops,  

  44. };  


三、i2c_add_driver分析


    驱动端的统一接口为i2c_add_driver:


[cpp]


  1. static inline int i2c_add_driver(struct i2c_driver *driver)  

  2. {  

  3.     /* 

  4.      *注册i2c driver,可能是adapter的,也可能是client的 

  5.      */  

  6.     return i2c_register_driver(THIS_MODULE, driver);  

  7. }  

  8. int i2c_register_driver(struct module *owner, struct i2c_driver *driver)  

  9. {  

  10.     int res;  

  11.     /* Can’t register until after driver model init*/  

  12.     if (unlikely(WARN_ON(!i2c_bus_type.p)))  

  13.         return -EAGAIN;  

  14.     /* add the driver to the list of i2c drivers in the driver core */  

  15.       

  16.     /* 

  17.      * i2c_driver内嵌的标准driver赋值,其bus指定为i2c_bus_type 

  18.      */  

  19.     driver->driver.owner = owner;  

  20.     driver->driver.bus = &i2c_bus_type;   

  21.     /* When registration returns, the driver core 

  22.      * will have called probe() for all matching-but-unbound devices. 

  23.      */  

  24.        

  25.     /*注册标准的driver,driver注册后会去i2c_bus_type的设备链表上匹配 

  26.      *设备,匹配函数用的是bus端的,也就是i2c_device_match,如果匹配成功 

  27.      *将建立标准关联,并且将调用bus端的probe函数初始化这个设备,即 

  28.      *函数i2c_device_probe,下面会逐个分析 

  29.      */  

  30.     res = driver_register(&driver->driver);  

  31.     if (res)  

  32.         return res;  

  33.     pr_debug(“i2c-core: driver [%s] registered/n”, driver->driver.name);  

  34.   /* 

  35.    * 把该driver的clients初始化,该成员连接着这个driver可以操作的具 

  36.    * 体设备 

  37.    */  

  38.     INIT_LIST_HEAD(&driver->clients);  

  39.     /* Walk the adapters that are already present */  

  40.     mutex_lock(&core_lock);  

  41.       

  42.   /*  

  43.    * 遍历挂接在该i2c设备链表上的设备,并对其都调用__process_new_driver 

  44.    * 函数 

  45.    */  

  46.     bus_for_each_dev(&i2c_bus_type, NULL, driver, __process_new_driver);  

  47.     mutex_unlock(&core_lock);  

  48.     return 0;  

  49. }  

  50. /**************************** 

  51. * 匹配函数i2c_device_match * 

  52. ****************************/  

  53. static int i2c_device_match(struct device *dev, struct device_driver *drv)  

  54. {  

  55.     /* 

  56.      * i2c_verify_client检查匹配的这个设备是否为i2c_client_type 

  57.      * 类型,如果不是则返回NULL,此处的匹配只是针对i2c设备的 

  58.      * 不是适配器 

  59.      */  

  60.       

  61.     struct i2c_client   *client = i2c_verify_client(dev);  

  62.     struct i2c_driver   *driver;  

  63.       /* 

  64.      * 如果不是i2c设备类型就返回 

  65.      */  

  66.     if (!client)  

  67.         return 0;  

  68.     /* Attempt an OF style match */  

  69.       

  70.     /* 

  71.      * 如果定义了CONFIG_OF_DEVICE,那么就利用 

  72.      * drv.of_match_table成员表进行匹配 

  73.      */  

  74.     if (of_driver_match_device(dev, drv))  

  75.         return 1;  

  76.       /* 

  77.      * 由内嵌的driver得到外面封装的i2c_driver 

  78.      */  

  79.     driver = to_i2c_driver(drv);  

  80.       

  81.     /* match on an id table if there is one */  

  82.       

  83.     /* 

  84.      * 如果i2c_driver->id_table存在,也就是支持的设备信息表 

  85.      * 存在,那么利用这个表进行匹配 

  86.      */  

  87.     if (driver->id_table)  

  88.         return i2c_match_id(driver->id_table, client) != NULL;  

  89.     return 0;  

  90. }  

  91. /********************************** 

  92. * 初始化设备函数i2c_device_probe * 

  93. **********************************/  

  94. static int i2c_device_probe(struct device *dev)  

  95. {  

  96.     /* 

  97.      * 检查如果设备类型不是client则返回 

  98.      */  

  99.     struct i2c_client   *client = i2c_verify_client(dev);  

  100.     struct i2c_driver   *driver;  

  101.     int status;  

  102.     if (!client)  

  103.         return 0;  

  104.     

  105.       /* 

  106.      * dev->driver指向匹配完成的driver,根据该标准 

  107.      * driver得到其外围封装的i2c_driver 

  108.      */  

  109.     driver = to_i2c_driver(dev->driver);  

  110.       

  111.     /* 

  112.      * 如果该i2c_driver的probe成员或者id_table成员为 

  113.      * NULL则退出 

  114.      */  

  115.     if (!driver->probe || !driver->id_table)  

  116.         return -ENODEV;  

  117.           

  118.     /* 

  119.      * client的driver成员赋值为该i2c_driver 

  120.      */  

  121.     client->driver = driver;  

  122.       

  123.     /* 

  124.      * 唤醒该设备 

  125.      */  

  126.     if (!device_can_wakeup(&client->dev))  

  127.         device_init_wakeup(&client->dev,  

  128.                     client->flags & I2C_CLIENT_WAKE);  

  129.     dev_dbg(dev, “probe/n”);  

  130.       

  131.      /* 

  132.      * 利用i2c_driver的probe成员初始化该设备,此部分为实际平台相关 

  133.      */  

  134.     status = driver->probe(client, i2c_match_id(driver->id_table, client));  

  135.       

  136.     /* 

  137.      * 失败则清除client指定的driver 

  138.      */  

  139.     if (status) {  

  140.         client->driver = NULL;  

  141.         i2c_set_clientdata(client, NULL);  

  142.     }  

  143.     return status;  

  144. }  

  145. /************************************************************* 

  146. * 下面看一下当找到一个dev后调用的__process_new_driver函数 * 

  147. *************************************************************/  

  148. static int __process_new_driver(struct device *dev, void *data)  

  149. {  

  150.     /* 

  151.      * 设备的类型如果不是i2c_adapter类型就推出 

  152.      * 下面的代码是针对i2c适配器的代码 

  153.      */  

  154.     if (dev->type != &i2c_adapter_type)   

  155.         return 0;  

  156.           

  157.     /* 

  158.      * 如果这个设备代表i2c适配器,则调用i2c_do_add_adapter 

  159.      * 此时的data类型为i2c_driver 

  160.      */  

  161.     return i2c_do_add_adapter(data, to_i2c_adapter(dev));//根据设备得到他的适配器   

  162.                              //i2c_driver。第一个是i2c_driver   

  163. }  

  164. /************************* 

  165. * i2c_do_add_adapter函数 * 

  166. *************************/  

  167. static int i2c_do_add_adapter(struct i2c_driver *driver,  

  168.                   struct i2c_adapter *adap)  

  169. {  

  170.     /* Detect supported devices on that bus, and instantiate them */  

  171.       

  172.     /* 

  173.      * 利用该适配器和该i2c_driver探测该适配器所在的这条i2c总线 

  174.      * 找到该driver支持的设备并实例化它 

  175.      */  

  176.     i2c_detect(adap, driver);   

  177.       

  178.     /* Let legacy drivers scan this bus for matching devices */  

  179.       

  180.     /* 

  181.      * 老版本的探测利用i2c_driver的attach_adapter函数 

  182.      */  

  183.     if (driver->attach_adapter) {  

  184.         /* We ignore the return code; if it fails, too bad */  

  185.         driver->attach_adapter(adap);  

  186.     }  

  187.     return 0;  

  188. }  

  189. /**************************** 

  190. * 重点看一下i2c_detect函数 * 

  191. ****************************/  

  192. static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver)  

  193. {  

  194.     const unsigned short *address_list;  

  195.     struct i2c_client *temp_client;  

  196.     int i, err = 0;  

  197.     int adap_id = i2c_adapter_id(adapter);  

  198.   /* 

  199.    * 得到该i2c_driver指定的client地址范围 

  200.    */  

  201.     address_list = driver->address_list;  

  202.       

  203.   /* 

  204.    * driver平台相关的detect函数和client地址范围不能为NULL 

  205.    */  

  206.     if (!driver->detect || !address_list)   

  207.         return 0;  

  208.     /* Set up a temporary client to help detect callback */  

  209.       

  210.   /* 

  211.    * 申请一块client内存 

  212.    */  

  213.     temp_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);  

  214.     if (!temp_client)  

  215.         return -ENOMEM;  

  216.           

  217.   /* 

  218.    * 申请的client结构的adapter成员设置为当前的adapter 

  219.    */  

  220.     temp_client->adapter = adapter;            

  221.     /* Stop here if the classes do not match */  

  222.       

  223.     /* 

  224.      * 当前adapter的类型如果和driver的类型不一样,则退出 

  225.      * 例如:适配器的类型可以为传感器,eeprom,driver类型必须 

  226.      * 与其匹配 

  227.      */  

  228.     if (!(adapter->class & driver->class))    

  229.         goto exit_free;  

  230.   /* 

  231.    * 根据指定的支持的地址范围开始逐一探测 

  232.    */  

  233.     for (i = 0; address_list[i] != I2C_CLIENT_END; i += 1) {  

  234.         dev_dbg(&adapter->dev, “found normal entry for adapter %d, “  

  235.             “addr 0x%02x/n”, adap_id, address_list[i]);  

  236.   /* 

  237.    * 临时申请的client的地址设置为这次要探测的地址 

  238.    */  

  239.         temp_client->addr = address_list[i];  

  240.         err = i2c_detect_address(temp_client, driver);    

  241.         if (err)  

  242.             goto exit_free;  

  243.     }  

  244.  exit_free:  

  245.     kfree(temp_client);  

  246.     return err;  

  247. }  

  248. /********************************** 

  249. * 继续跟进i2c_detect_address函数 * 

  250. **********************************/  

  251. static int i2c_detect_address(struct i2c_client *temp_client,  

  252.                   struct i2c_driver *driver)  

  253. {  

  254.     struct i2c_board_info info;  

  255.     struct i2c_adapter *adapter = temp_client->adapter;  

  256.     int addr = temp_client->addr;  

  257.     int err;  

  258.     /* Make sure the address is valid */  

  259.       

  260.   /* 

  261.    * 检查该地址是否有效,小于0x08或者大于0x77都是无效 

  262.    * 地址,该函数在后面介绍 

  263.    */  

  264.     err = i2c_check_addr_validity(addr);  

  265.     if (err) {  

  266.         dev_warn(&adapter->dev, “Invalid probe address 0x%02x/n”,  

  267.              addr);  

  268.         return err;  

  269.     }  

  270.     /* Skip if already in use */  

  271.       

  272.   /* 

  273.    * 如果地址在使用中则跳过 

  274.    */  

  275.     if (i2c_check_addr_busy(adapter, addr))  

  276.         return 0;  

  277.     /* Make sure there is something at this address */  

  278.       

  279.   /* 

  280.    * 默认初始化探测,确定该地址上有设备存在 

  281.    */  

  282.     if (!i2c_default_probe(adapter, addr))  

  283.         return 0;  

  284.     /* Finally call the custom detection function */  

  285.       

  286.   /* 

  287.    * 走到这里将调用平台相关的自定义探测函数去探测该地址 

  288.    * 上是否设备,并填充i2c_board_info结构体 

  289.    */  

  290.     memset(&info, 0, sizeof(struct i2c_board_info));  

  291.     info.addr = addr;  

  292.     err = driver->detect(temp_client, &info);  

  293.     if (err) {  

  294.         /* -ENODEV is returned if the detection fails. We catch it 

  295.            here as this isn’t an error. */  

  296.         return err == -ENODEV ? 0 : err;  

  297.     }  

  298.     /* Consistency check */  

  299.       

  300.     /* 

  301.      * 填充的info名字为空,则结束否则实例化这个设备 

  302.      */  

  303.     if (info.type[0] == ‘/0’) {  

  304.         dev_err(&adapter->dev, “%s detection function provided “  

  305.             “no name for 0x%x/n”, driver->driver.name,  

  306.             addr);  

  307.     } else {  

  308.         struct i2c_client *client;  

  309.         /* Detection succeeded, instantiate the device */  

  310.         dev_dbg(&adapter->dev, “Creating %s at 0x%02x/n”,  

  311.             info.type, info.addr);  

  312.               

  313.     /* 

  314.      * 根据当前适配器和填充的info实例化该地址上探测到的设备 

  315.      */  

  316.         client = i2c_new_device(adapter, &info);  

  317.           

  318.     /* 

  319.      * 实例化成功将该client挂到该driver的clients链表上 

  320.      */  

  321.         if (client)  

  322.             list_add_tail(&client->detected, &driver->clients); //驱动挂到driver下   

  323.         else  

  324.             dev_err(&adapter->dev, “Failed creating %s at 0x%02x/n”,  

  325.                 info.type, info.addr);  

  326.     }  

  327.     return 0;  

  328. }  

  329. /****************************** 

  330. * i2c_check_addr_validity函数 * 

  331. ******************************/  

  332. static int i2c_check_addr_validity(unsigned short addr)  

  333. {  

  334.     /* 

  335.      * Reserved addresses per I2C specification: 

  336.      *  0x00       General call address / START byte 

  337.      *  0x01       CBUS address 

  338.      *  0x02       Reserved for different bus format 

  339.      *  0x03       Reserved for future purposes 

  340.      *  0x04-0x07  Hs-mode master code 

  341.      *  0x78-0x7b  10-bit slave addressing 

  342.      *  0x7c-0x7f  Reserved for future purposes 

  343.      */  

  344.     if (addr < 0x08 || addr > 0x77)  

  345.         return -EINVAL;  

  346.     return 0;  

  347. }  

  348. /********************************* 

  349. * 再看一下i2c_default_probe函数 * 

  350. *********************************/  

  351. static int i2c_default_probe(struct i2c_adapter *adap, unsigned short addr)  

  352. {  

  353.     int err;  

  354.     union i2c_smbus_data dummy;  

  355. #ifdef CONFIG_X86   

  356.         /* 

  357.      * 这里是对intel特殊设备的检查,就不深入看下去了 

  358.      */  

  359.     if (addr == 0x73 && (adap->class & I2C_CLASS_HWMON)  

  360.      && i2c_check_functionality(adap, I2C_FUNC_SMBUS_READ_BYTE_DATA))  

  361.         err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_READ, 0,  

  362.                      I2C_SMBUS_BYTE_DATA, &dummy);  

  363.     else  

  364. #endif   

  365.         /* 

  366.      * 对特殊设备的检查 

  367.      */  

  368.     if (!((addr & ~0x07) == 0x30 || (addr & ~0x0f) == 0x50)  

  369.      && i2c_check_functionality(adap, I2C_FUNC_SMBUS_QUICK))  

  370.         err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_WRITE, 0,  

  371.                      I2C_SMBUS_QUICK, NULL);  

  372.   /* 

  373.    * i2c_check_functionality函数确定该i2c适配器所支持的通信方式 

  374.    * 如果支持该方式则调用i2c_smbus_xfer函数 

  375.    */  

  376.     else if (i2c_check_functionality(adap, I2C_FUNC_SMBUS_READ_BYTE))  

  377.         err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_READ, 0,  

  378.                      I2C_SMBUS_BYTE, &dummy);  

  379.     else {  

  380.         dev_warn(&adap->dev, “No suitable probing method supported/n”);  

  381.         err = -EOPNOTSUPP;  

  382.     }  

  383.     return err >= 0;  

  384. }  

  385. /****************************** 

  386. * i2c_check_functionality函数 * 

  387. ******************************/  

  388. static inline int i2c_check_functionality(struct i2c_adapter *adap, u32 func)  

  389. {  

  390.     return (func & i2c_get_functionality(adap)) == func;  

  391. }  

  392. static inline u32 i2c_get_functionality(struct i2c_adapter *adap)  

  393. {  

  394.    /* 

  395.     * 最终会调用adapter通信函数里面的functionality函数确定支持的 

  396.     * 通信方式 

  397.     */  

  398.     return adap->algo->functionality(adap);  

  399. }  

  400. /********************* 

  401. * i2c_smbus_xfer函数 * 

  402. *********************/  

  403. s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags,  

  404.            char read_write, u8 command, int protocol,  

  405.            union i2c_smbus_data *data)  

  406. {  

  407.     unsigned long orig_jiffies;  

  408.     int try;  

  409.     s32 res;  

  410.     flags &= I2C_M_TEN | I2C_CLIENT_PEC;  

  411.     

  412.    /* 

  413.     * 如果适配器通信函数中的smbus_xfer函数存在,则直接利用它进行发送 

  414.     */  

  415.     if (adapter->algo->smbus_xfer) {  

  416.         i2c_lock_adapter(adapter);  

  417.         /* Retry automatically on arbitration loss */  

  418.         orig_jiffies = jiffies;  

  419.         for (res = 0, try = 0; try <= adapter->retries; try++) {  

  420.             res = adapter->algo->smbus_xfer(adapter, addr, flags,  

  421.                             read_write, command,  

  422.                             protocol, data);  

  423.             if (res != -EAGAIN)  

  424.                 break;  

  425.             if (time_after(jiffies,  

  426.                        orig_jiffies + adapter->timeout))  

  427.                 break;  

  428.         }  

  429.         i2c_unlock_adapter(adapter);  

  430.     } else  

  431.           

  432.    /* 

  433.     * 否则利用i2c_smbus_xfer_emulated处理,此处也就是不支持smbus, 

  434.     * 则得利用i2c模拟smbus命令 

  435.     */  

  436.         res = i2c_smbus_xfer_emulated(adapter, addr, flags, read_write,  

  437.                           command, protocol, data);  

  438.     return res;  

  439. }  

  440. /****************************** 

  441. * i2c_smbus_xfer_emulated函数 * 

  442. ******************************/  

  443. static s32 i2c_smbus_xfer_emulated(struct i2c_adapter *adapter, u16 addr,  

  444.                    unsigned short flags,  

  445.                    char read_write, u8 command, int size,  

  446.                    union i2c_smbus_data *data)  

  447. {  

  448.     /* So we need to generate a series of msgs. In the case of writing, we 

  449.       need to use only one message; when reading, we need two. We initialize 

  450.       most things with sane defaults, to keep the code below somewhat 

  451.       simpler. */  

  452.         

  453.   /* 

  454.    * 为了进行通信我们必须创建msgs结构,当写时,我们需要一个这样的结构就 

  455.    * 够了,当读的时候,我们需要两个 

  456.    */  

  457.     unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX+3];  

  458.     unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX+2];  

  459.       

  460.   /* 

  461.    * 读的时候需要两次 

  462.    */  

  463.     int num = read_write == I2C_SMBUS_READ ? 2 : 1;  

  464.           

  465.   /* 

  466.    * 填充需要的两个msg结构 

  467.    */  

  468.     struct i2c_msg msg[2] = { { addr, flags, 1, msgbuf0 },  

  469.                               { addr, flags | I2C_M_RD, 0, msgbuf1 }  

  470.                             };  

  471.     int i;  

  472.     u8 partial_pec = 0;  

  473.     int status;  

  474.   /* 

  475.    * 将要发送的命令填充到msg0 

  476.    */  

  477.     msgbuf0[0] = command;  

  478.     switch (size) {  

  479.       

  480.   /* 

  481.    * 快速传输,多用于确定该地址有应答 

  482.    */  

  483.     case I2C_SMBUS_QUICK:  

  484.         msg[0].len = 0;  

  485.         /* Special case: The read/write field is used as data */  

  486.         msg[0].flags = flags | (read_write == I2C_SMBUS_READ ?  

  487.                     I2C_M_RD : 0);  

  488.         num = 1;  

  489.         break;  

  490.           

  491.   /* 

  492.    * 字节传输,一次读写一个字节 

  493.    */  

  494.     case I2C_SMBUS_BYTE:  

  495.         if (read_write == I2C_SMBUS_READ) {  

  496.             /* Special case: only a read! */  

  497.             msg[0].flags = I2C_M_RD | flags;  

  498.             num = 1;  

  499.         }  

  500.         break;  

  501.           

  502.   /* 

  503.    * 命令+单字节形式传输 

  504.    */  

  505.     case I2C_SMBUS_BYTE_DATA:  

  506.         if (read_write == I2C_SMBUS_READ)  

  507.             msg[1].len = 1;  

  508.         else {  

  509.             msg[0].len = 2;  

  510.             msgbuf0[1] = data->byte;  

  511.         }  

  512.         break;  

  513.           

  514.   /* 

  515.    * 命令+字形式传输 

  516.    */     

  517.     case I2C_SMBUS_WORD_DATA:  

  518.         if (read_write == I2C_SMBUS_READ)  

  519.             msg[1].len = 2;  

  520.         else {  

  521.             msg[0].len = 3;  

  522.             msgbuf0[1] = data->word & 0xff;  

  523.             msgbuf0[2] = data->word >> 8;  

  524.         }  

  525.         break;  

  526.           

  527.   /* 

  528.    * 命令+字形式,需要应答 

  529.    */     

  530.     case I2C_SMBUS_PROC_CALL:  

  531.         num = 2; /* Special case */  

  532.         read_write = I2C_SMBUS_READ;  

  533.         msg[0].len = 3;  

  534.         msg[1].len = 2;  

  535.         msgbuf0[1] = data->word & 0xff;  

  536.         msgbuf0[2] = data->word >> 8;  

  537.         break;  

  538.           

  539.   /* 

  540.    * 多字节数据模式,字节数传输中不确定 

  541.    */     

  542.     case I2C_SMBUS_BLOCK_DATA:  

  543.         if (read_write == I2C_SMBUS_READ) {  

  544.             msg[1].flags |= I2C_M_RECV_LEN;  

  545.             msg[1].len = 1; /* block length will be added by 

  546.                        the underlying bus driver */  

  547.         } else {  

  548.             msg[0].len = data->block[0] + 2;  

  549.             if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 2) {  

  550.                 dev_err(&adapter->dev,  

  551.                     “Invalid block write size %d/n”,  

  552.                     data->block[0]);  

  553.                 return -EINVAL;  

  554.             }  

  555.             for (i = 1; i < msg[0].len; i++)  

  556.                 msgbuf0[i] = data->block[i-1];  

  557.         }  

  558.         break;  

  559.           

  560.   /* 

  561.    * 多字节数据传输,需要应答 

  562.    */     

  563.     case I2C_SMBUS_BLOCK_PROC_CALL:  

  564.         num = 2; /* Another special case */  

  565.         read_write = I2C_SMBUS_READ;  

  566.         if (data->block[0] > I2C_SMBUS_BLOCK_MAX) {  

  567.             dev_err(&adapter->dev,  

  568.                 “Invalid block write size %d/n”,  

  569.                 data->block[0]);  

  570.             return -EINVAL;  

  571.         }  

  572.         msg[0].len = data->block[0] + 2;  

  573.         for (i = 1; i < msg[0].len; i++)  

  574.             msgbuf0[i] = data->block[i-1];  

  575.         msg[1].flags |= I2C_M_RECV_LEN;  

  576.         msg[1].len = 1; /* block length will be added by 

  577.                    the underlying bus driver */  

  578.         break;  

  579.           

  580.   /* 

  581.    * 多字节数据传输,传输字节数确定 

  582.    */     

  583.     case I2C_SMBUS_I2C_BLOCK_DATA:  

  584.         if (read_write == I2C_SMBUS_READ) {  

  585.             msg[1].len = data->block[0];  

  586.         } else {  

  587.             msg[0].len = data->block[0] + 1;  

  588.             if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 1) {  

  589.                 dev_err(&adapter->dev,  

  590.                     “Invalid block write size %d/n”,  

  591.                     data->block[0]);  

  592.                 return -EINVAL;  

  593.             }  

  594.             for (i = 1; i <= data->block[0]; i++)  

  595.                 msgbuf0[i] = data->block[i];  

  596.         }  

  597.         break;  

  598.     default:  

  599.         dev_err(&adapter->dev, “Unsupported transaction %d/n”, size);  

  600.         return -EOPNOTSUPP;  

  601.     }  

  602.     i = ((flags & I2C_CLIENT_PEC) && size != I2C_SMBUS_QUICK  

  603.                       && size != I2C_SMBUS_I2C_BLOCK_DATA);  

  604.     if (i) {  

  605.         /* Compute PEC if first message is a write */  

  606.         if (!(msg[0].flags & I2C_M_RD)) {  

  607.             if (num == 1) /* Write only */  

  608.                 i2c_smbus_add_pec(&msg[0]);  

  609.             else /* Write followed by read */  

  610.                 partial_pec = i2c_smbus_msg_pec(0, &msg[0]);  

  611.         }  

  612.         /* Ask for PEC if last message is a read */  

  613.         if (msg[num-1].flags & I2C_M_RD)  

  614.             msg[num-1].len++;  

  615.     }  

  616.   /* 

  617.    * 调用i2c_transfer传输 

  618.    */     

  619.     status = i2c_transfer(adapter, msg, num);  

  620.     if (status < 0)  

  621.         return status;  

  622.     /* Check PEC if last message is a read */  

  623.     if (i && (msg[num-1].flags & I2C_M_RD)) {  

  624.         status = i2c_smbus_check_pec(partial_pec, &msg[num-1]);  

  625.         if (status < 0)  

  626.             return status;  

  627.     }  

  628.     

  629.   /* 

  630.    * 将得到的数据回传给data 

  631.    */     

  632.     if (read_write == I2C_SMBUS_READ)  

  633.         switch (size) {  

  634.         case I2C_SMBUS_BYTE:  

  635.             data->byte = msgbuf0[0];  

  636.             break;  

  637.         case I2C_SMBUS_BYTE_DATA:  

  638.             data->byte = msgbuf1[0];  

  639.             break;  

  640.         case I2C_SMBUS_WORD_DATA:  

  641.         case I2C_SMBUS_PROC_CALL:  

  642.             data->word = msgbuf1[0] | (msgbuf1[1] << 8);  

  643.             break;  

  644.         case I2C_SMBUS_I2C_BLOCK_DATA:  

  645.             for (i = 0; i < data->block[0]; i++)  

  646.                 data->block[i+1] = msgbuf1[i];  

  647.             break;  

  648.         case I2C_SMBUS_BLOCK_DATA:  

  649.         case I2C_SMBUS_BLOCK_PROC_CALL:  

  650.             for (i = 0; i < msgbuf1[0] + 1; i++)  

  651.                 data->block[i] = msgbuf1[i];  

  652.             break;  

  653.         }  

  654.     return 0;  

  655. }  

  656. /******************* 

  657. * i2c_transfer函数 * 

  658. *******************/  

  659. int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)  

  660. {  

  661.     unsigned long orig_jiffies;  

  662.     int ret, try;  

  663.     /* REVISIT the fault reporting model here is weak: 

  664.      * 

  665.      *  – When we get an error after receiving N bytes from a slave, 

  666.      *    there is no way to report “N”. 

  667.      * 

  668.      *  – When we get a NAK after transmitting N bytes to a slave, 

  669.      *    there is no way to report “N” … or to let the master 

  670.      *    continue executing the rest of this combined message, if 

  671.      *    that’s the appropriate response. 

  672.      * 

  673.      *  – When for example “num” is two and we successfully complete 

  674.      *    the first message but get an error part way through the 

  675.      *    second, it’s unclear whether that should be reported as 

  676.      *    one (discarding status on the second message) or errno 

  677.      *    (discarding status on the first one). 

  678.      */  

  679.   /* 

  680.    * 如果适配器的adap->algo->master_xfer函数存在,则调用它把 

  681.    * 该信息发送出去 

  682.    */     

  683.     if (adap->algo->master_xfer) {  

  684. #ifdef DEBUG   

  685.         for (ret = 0; ret < num; ret++) {  

  686.             dev_dbg(&adap->dev, “master_xfer[%d] %c, addr=0x%02x, “  

  687.                 “len=%d%s/n”, ret, (msgs[ret].flags & I2C_M_RD)  

  688.                 ? ‘R’ : ‘W’, msgs[ret].addr, msgs[ret].len,  

  689.                 (msgs[ret].flags & I2C_M_RECV_LEN) ? “+” : “”);  

  690.         }  

  691. #endif   

  692.         if (in_atomic() || irqs_disabled()) {  

  693.             ret = i2c_trylock_adapter(adap);  

  694.             if (!ret)  

  695.                 /* I2C activity is ongoing. */  

  696.                 return -EAGAIN;  

  697.         } else {  

  698.             i2c_lock_adapter(adap);  

  699.         }  

  700.         /* Retry automatically on arbitration loss */  

  701.         orig_jiffies = jiffies;  

  702.         for (ret = 0, try = 0; try <= adap->retries; try++) {  

  703.             ret = adap->algo->master_xfer(adap, msgs, num);  

  704.             if (ret != -EAGAIN)  

  705.                 break;  

  706.             if (time_after(jiffies, orig_jiffies + adap->timeout))  

  707.                 break;  

  708.         }  

  709.         i2c_unlock_adapter(adap);  

  710.         return ret;  

  711.     } else {  

  712.         dev_dbg(&adap->dev, “I2C level transfers not supported/n”);  

  713.         return -EOPNOTSUPP;  

  714.     }  

  715. }  

  716. /********************************************** 

  717. * 回过头来看一下i2c_new_device这个实例化函数* 

  718. **********************************************/  

  719. struct i2c_client *  

  720. i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)  

  721. {  

  722.     struct i2c_client   *client;  

  723.     int         status;  

  724.     

  725.   /* 

  726.    * 为需要实例化的设备申请内存 

  727.    */     

  728.     client = kzalloc(sizeof *client, GFP_KERNEL);  

  729.     if (!client)  

  730.         return NULL;  

  731.     

  732.   /* 

  733.    * 指定适配器以及platform_data 

  734.    */  

  735.     client->adapter = adap;  

  736.     client->dev.platform_data = info->platform_data;  

  737.     

  738.   /* 

  739.    * info->archdata存在将其赋值给client 

  740.    */  

  741.     if (info->archdata)  

  742.         client->dev.archdata = *info->archdata;  

  743.   /* 

  744.    * 标志、地址、中断号、名字 

  745.    */  

  746.     client->flags = info->flags;  

  747.     client->addr = info->addr;  

  748.     client->irq = info->irq;  

  749.     strlcpy(client->name, info->type, sizeof(client->name));  

  750.     /* Check for address validity */  

  751.       

  752.   /* 

  753.    * 检查地址有效性 

  754.    */  

  755.     status = i2c_check_client_addr_validity(client);  

  756.     if (status) {  

  757.         dev_err(&adap->dev, “Invalid %d-bit I2C address 0x%02hx/n”,  

  758.             client->flags & I2C_CLIENT_TEN ? 10 : 7, client->addr);  

  759.         goto out_err_silent;  

  760.     }  

  761.     /* Check for address business */  

  762.       

  763.   /* 

  764.    * 检查地址是否被使用 

  765.    */  

  766.     status = i2c_check_addr_busy(adap, client->addr);  

  767.     if (status)  

  768.         goto out_err;  

  769.   /* 

  770.    * 内嵌标准device的赋值 

  771.    */  

  772.     client->dev.parent = &client->adapter->dev;  

  773.     client->dev.bus = &i2c_bus_type;  

  774.     client->dev.type = &i2c_client_type;  

  775. #ifdef CONFIG_OF   

  776.     client->dev.of_node = info->of_node;  

  777. #endif   

  778.     dev_set_name(&client->dev, “%d-%04x”, i2c_adapter_id(adap),  

  779.              client->addr);  

  780.   /* 

  781.    * 注册内嵌的标准device 

  782.    */  

  783.     status = device_register(&client->dev);   

  784.     if (status)  

  785.         goto out_err;  

  786.     dev_dbg(&adap->dev, “client [%s] registered with bus id %s/n”,  

  787.         client->name, dev_name(&client->dev));  

  788.     return client;  

  789. out_err:  

  790.     dev_err(&adap->dev, “Failed to register i2c client %s at 0x%02x “  

  791.         “(%d)/n”, client->name, client->addr, status);  

  792. out_err_silent:  

  793.     kfree(client);  

  794.     return NULL;  

  795. }  


     以上就是i2c通用driver添加的流程,下面看一下设备端,适配器的流程

四、i2c_add_adapter分析

[cpp]


  1. int i2c_add_adapter(struct i2c_adapter *adapter)  

  2. {  

  3.     int id, res = 0;  

  4. retry:  

  5.   /* 

  6.    * 得到bus号并将其插入搜索树,便于高效查找 

  7.    * 此处不做深入分析 

  8.    */  

  9.     if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0)  

  10.         return -ENOMEM;  

  11.     mutex_lock(&core_lock);  

  12.     /* “above” here means “above or equal to”, sigh */  

  13.     res = idr_get_new_above(&i2c_adapter_idr, adapter,  

  14.                 __i2c_first_dynamic_bus_num, &id);  

  15.     mutex_unlock(&core_lock);  

  16.     if (res < 0) {  

  17.         if (res == -EAGAIN)  

  18.             goto retry;  

  19.         return res;  

  20.     }  

  21.     

  22.   /* 

  23.    * 适配器号赋值,代表i2c的编号 

  24.    */  

  25.     adapter->nr = id;  

  26.     return i2c_register_adapter(adapter);  

  27. }  

  28. /*********************************************** 

  29. * 来看一下适配器的注册函数i2c_register_adapter* 

  30. ***********************************************/  

  31. static int i2c_register_adapter(struct i2c_adapter *adap)  

  32. {  

  33.     int res = 0;  

  34.     /* Can’t register until after driver model init */  

  35.       

  36.   /* 

  37.    * bus私有属性结构不能为NULL 

  38.    */  

  39.     if (unlikely(WARN_ON(!i2c_bus_type.p))) {  

  40.         res = -EAGAIN;  

  41.         goto out_list;  

  42.     }  

  43.     rt_mutex_init(&adap->bus_lock);  

  44.     mutex_init(&adap->userspace_clients_lock);  

  45.     INIT_LIST_HEAD(&adap->userspace_clients);  

  46.     /* Set default timeout to 1 second if not already set */  

  47.       

  48.   /* 

  49.    * 超时时间设置为1s 

  50.    */  

  51.     if (adap->timeout == 0)  

  52.         adap->timeout = HZ;  

  53.     

  54.   /* 

  55.    * 设置内嵌device的名字,指定bus,指定自身类型为适配器 

  56.    */  

  57.     dev_set_name(&adap->dev, “i2c-%d”, adap->nr);  

  58.     adap->dev.bus = &i2c_bus_type;        

  59.     adap->dev.type = &i2c_adapter_type;   

  60.       

  61.   /* 

  62.    * 注册内嵌的标准device,此时将会出现在i2c_bus目录下 

  63.    */  

  64.     res = device_register(&adap->dev);    

  65.     if (res)  

  66.         goto out_list;  

  67.     dev_dbg(&adap->dev, “adapter [%s] registered/n”, adap->name);  

  68. #ifdef CONFIG_I2C_COMPAT   

  69.     res = class_compat_create_link(i2c_adapter_compat_class, &adap->dev,  

  70.                        adap->dev.parent);  

  71.     if (res)  

  72.         dev_warn(&adap->dev,  

  73.              “Failed to create compatibility class link/n”);  

  74. #endif   

  75.     /* create pre-declared device nodes */  

  76.       

  77.   /* 

  78.    * client可以静态的添加,如果发现适配器号也就是i2c号 

  79.    * 小于动态bus号,说明设备静态添加,则进行扫描 

  80.    */  

  81.     if (adap->nr < __i2c_first_dynamic_bus_num)  

  82.         i2c_scan_static_board_info(adap);   

  83.     /* Notify drivers */  

  84.     mutex_lock(&core_lock);  

  85.       

  86.   /* 

  87.    * 遍历bus的驱动端,对于每一个driver都调用__process_new_adapter 

  88.    */  

  89.     bus_for_each_drv(&i2c_bus_type, NULL, adap, __process_new_adapter);  

  90.     mutex_unlock(&core_lock);  

  91.     return 0;  

  92. out_list:  

  93.     mutex_lock(&core_lock);  

  94.     idr_remove(&i2c_adapter_idr, adap->nr);  

  95.     mutex_unlock(&core_lock);  

  96.     return res;  

  97. }  

  98. /******************************************* 

  99. * 先来看一下i2c_scan_static_board_info函数* 

  100. *******************************************/  

  101. static void i2c_scan_static_board_info(struct i2c_adapter *adapter)  

  102. {  

  103.     struct i2c_devinfo  *devinfo;  

  104.     down_read(&__i2c_board_lock);  

  105.   /* 

  106.    * 遍历全局的i2c的client链表,找到该适配器器所代表 

  107.    * 总线上挂接的设备,用i2c_new_device实例化它, 

  108.    * i2c_new_device在前面已经分析过了,不在赘述 

  109.    */  

  110.     list_for_each_entry(devinfo, &__i2c_board_list, list) {  

  111.         if (devinfo->busnum == adapter->nr  

  112.                 && !i2c_new_device(adapter,  

  113.                         &devinfo->board_info))  

  114.             dev_err(&adapter->dev,  

  115.                 “Can’t create device at 0x%02x/n”,  

  116.                 devinfo->board_info.addr);  

  117.     }  

  118.     up_read(&__i2c_board_lock);  

  119. }  

  120. /************************************** 

  121. * 再来看一下__process_new_adapter函数* 

  122. **************************************/  

  123. static int __process_new_adapter(struct device_driver *d, void *data)  

  124. {  

  125.   /* 

  126.    * 同样的归宿到了i2c_do_add_adapter下面,与前面分析的 

  127.    * __process_new_driver相似,只是driver是针对适配器, 

  128.    * 而这次没有这个限制 

  129.    */  

  130.     return i2c_do_add_adapter(to_i2c_driver(d), data);  

  131. }  


  依据以上的分析画出流程图如下:


 


iic picture


      i2c_driver依据内部成员的设定,会走不同的分支,产生不同的作用,下面根据流程前后顺序总结一下:
当发现的是i2c_bus上的一个client时(发生在标准driver注册的匹配):
 1、首先会进入到bus定义的匹配函数i2c_device_match如果定义了CONFIG_OF_DEVICE宏并且内部的标准
    driver结构定义了of_match_table成员,则利用其进行匹配;
 2、否则如果driver->id_table成员设定,则利用其进行匹配,否则匹配失败。
 3、如果匹配成功会调用i2c_bus的i2c_device_probe函数,该函数会判断,如果该i2c_driver的probe成员
    或者id_table成员为NULL,则返回,否则利用i2c_driver->probe初始化这个client。
当发现的是代表该i2c_bus的上的adapter时(发生在bus的遍历):
 1、如果该driver的driver->detect或者address_list为NULL退出
 2、如果该adapter->class和driver->class不匹配也退出
 3、如果以上都成立最终会调用driver->detect函数,实例化支持的client
 4、如果driver->attach_adapter也被设定,含会走旧式的路线,直接利用driver->attach_adapter进行探测
      不过,一般不会让3&&4这种结果出现
  可见,i2c_driver的设置非常灵活,抓住关键成员就不难掌握其流程。

五、i2c关于dev下节点的产生及其操作


  该部分的代码位于rivers/i2c/i2c-dev.c下,我们从头看起:


 

[cpp]


  1. static int __init i2c_dev_init(void)  

  2. {  

  3.     int res;  

  4.     printk(KERN_INFO “i2c /dev entries driver/n”);  

  5.   /* 

  6.    * 注册名称为i2c主设备号为89的一个字符设备 

  7.    */  

  8.     res = register_chrdev(I2C_MAJOR, “i2c”, &i2cdev_fops);  

  9.     if (res)  

  10.         goto out;  

  11.   /* 

  12.    * 在class下产生i2c-dev节点,用于自动产生设备文件 

  13.    */  

  14.     i2c_dev_class = class_create(THIS_MODULE, “i2c-dev”);  

  15.     if (IS_ERR(i2c_dev_class)) {  

  16.         res = PTR_ERR(i2c_dev_class);  

  17.         goto out_unreg_chrdev;  

  18.     }  

  19.     

  20.   /* 

  21.    * i2c_add_driver在上面已经分析过了 

  22.    */  

  23.     res = i2c_add_driver(&i2cdev_driver);  

  24.     if (res)  

  25.         goto out_unreg_class;  

  26.     return 0;  

  27. out_unreg_class:  

  28.     class_destroy(i2c_dev_class);  

  29. out_unreg_chrdev:  

  30.     unregister_chrdev(I2C_MAJOR, “i2c”);  

  31. out:  

  32.     printk(KERN_ERR “%s: Driver Initialisation failed/n”, __FILE__);  

  33.     return res;  

  34. }  

  35. //其中i2cdev_driver结构为:   

  36. static struct i2c_driver i2cdev_driver = {  

  37.     .driver = {  

  38.         .name   = “dev_driver”,  

  39.     },  

  40.     .attach_adapter = i2cdev_attach_adapter,  

  41.     .detach_adapter = i2cdev_detach_adapter,  

  42. };  


     由于没有关于client的支持表的定义,因此匹配client时就会直接返回, 由于存在成员attach_adapter,因此当匹配adapter时会进入该函数。


[cpp]


  1. /************************************ 

  2. * 来看一下i2cdev_attach_adapter函数* 

  3. ************************************/  

  4. static int i2cdev_attach_adapter(struct i2c_adapter *adap)  

  5. {  

  6.     struct i2c_dev *i2c_dev;  

  7.     int res;  

  8.     i2c_dev = get_free_i2c_dev(adap);  

  9.     if (IS_ERR(i2c_dev))  

  10.         return PTR_ERR(i2c_dev);  

  11.     /* register this i2c device with the driver core */  

  12.       

  13.     /* 

  14.    * 以上面注册的i2c_dev_class为父节点在目录class/i2c-dev下 

  15.    * 产生i2c-0之类的节点,这样上层udev会根据该节点在dev目录下 

  16.    * 自动创建对应的设备文件 

  17.    */  

  18.     i2c_dev->dev = device_create(i2c_dev_class, &adap->dev,  

  19.                      MKDEV(I2C_MAJOR, adap->nr), NULL,  

  20.                      “i2c-%d”, adap->nr);  

  21.     if (IS_ERR(i2c_dev->dev)) {  

  22.         res = PTR_ERR(i2c_dev->dev);  

  23.         goto error;  

  24.     }  

  25.       

  26.   /* 

  27.    * 产生相关属性文件 

  28.    */  

  29.     res = device_create_file(i2c_dev->dev, &dev_attr_name);  

  30.     if (res)  

  31.         goto error_destroy;  

  32.     pr_debug(“i2c-dev: adapter [%s] registered as minor %d/n”,  

  33.          adap->name, adap->nr);  

  34.     return 0;  

  35. error_destroy:  

  36.     device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr));  

  37. error:  

  38.     return_i2c_dev(i2c_dev);  

  39.     return res;  

  40. }  


    通过以上分析可以看到i2c-dev层,找到一个adapter就会自动为其创建设备节点,形式类似于i2c-*,那么当应用层open对应的设备节点的时候,内核会自动调用刚才注册的字符设备的操作函数, 我们先来看一下刚才注册的字符设备的操作集:


[cpp]


  1.  static const struct file_operations i2cdev_fops = {  

  2.     .owner      = THIS_MODULE,  

  3.     .llseek     = no_llseek,  

  4.     .read       = i2cdev_read,  

  5.     .write      = i2cdev_write,  

  6.     .unlocked_ioctl = i2cdev_ioctl,  

  7.     .open       = i2cdev_open,  

  8.     .release    = i2cdev_release,  

  9. };  


    按照用户层的流程先看一下open函数i2cdev_open:


[cpp]


  1. static int i2cdev_open(struct inode *inode, struct file *file)  

  2. {  

  3.     unsigned int minor = iminor(inode);           //得到次设备号   

  4.     struct i2c_client *client;  

  5.     struct i2c_adapter *adap;  

  6.     struct i2c_dev *i2c_dev;  

  7.     

  8.   /* 

  9.    * 次设备号其实是对应i2c总线号,下面函数遍历由次设备构成的链表 

  10.    * i2c_dev_list,找到上面挂接的号码对应的i2c_dev结构 

  11.    */  

  12.     i2c_dev = i2c_dev_get_by_minor(minor);  

  13.       

  14.     if (!i2c_dev)                                 //没找到,出错   

  15.         return -ENODEV;  

  16.     adap = i2c_get_adapter(i2c_dev->adap->nr);    //得到绑定的adapter   

  17.     if (!adap)  

  18.         return -ENODEV;  

  19.     /* This creates an anonymous i2c_client, which may later be 

  20.      * pointed to some address using I2C_SLAVE or I2C_SLAVE_FORCE. 

  21.      * 

  22.      * This client is ** NEVER REGISTERED ** with the driver model 

  23.      * or I2C core code!!  It just holds private copies of addressing 

  24.      * information and maybe a PEC flag. 

  25.      */  

  26.     client = kzalloc(sizeof(*client), GFP_KERNEL); //申请个client内存   

  27.     if (!client) {  

  28.         i2c_put_adapter(adap);  

  29.         return -ENOMEM;  

  30.     }  

  31.       

  32.     //命名,依据adapter   

  33.     snprintf(client->name, I2C_NAME_SIZE, “i2c-dev %d”, adap->nr);  

  34.       

  35.     //指定driver,代表创建他的driver   

  36.     client->driver = &i2cdev_driver;  

  37.     

  38.         //指定适配器   

  39.     client->adapter = adap;  

  40.     //通过file的私有成员传递创建的这个client   

  41.     file->private_data = client;  

  42.     return 0;  

  43. }  


      由open可见,我们要操作i2c下的设备,始终是需要通过adapter,物理上也是如此,操作设备都是通过控制器进行读写的,因此我们打开的始终是adapter而open过程中会创建client,来表述我们主观上是要操作设备。下面在看一下read函数:


[cpp]


  1. static ssize_t i2cdev_read(struct file *file, char __user *buf, size_t count,  

  2.         loff_t *offset)  

  3. {  

  4.     char *tmp;  

  5.     int ret;  

  6.   //得到由open传递过来的创建的client   

  7.     struct i2c_client *client = file->private_data;  

  8.     

  9.   //大小不能超过8192   

  10.     if (count > 8192)  

  11.         count = 8192;  

  12.     

  13.   //申请count大小内存   

  14.     tmp = kmalloc(count, GFP_KERNEL);  

  15.     if (tmp == NULL)  

  16.         return -ENOMEM;  

  17.     pr_debug(“i2c-dev: i2c-%d reading %zu bytes./n”,  

  18.         iminor(file->f_path.dentry->d_inode), count);  

  19.     

  20.   //调用i2c_master_recv进行进一步传送   

  21.     ret = i2c_master_recv(client, tmp, count);  

  22.     if (ret >= 0)  

  23.         //read的信息反馈给用户   

  24.         ret = copy_to_user(buf, tmp, count) ? -EFAULT : ret;  

  25.     kfree(tmp);  

  26.     return ret;  

  27. }  

  28. /**************************** 

  29. * 其中i2c_master_recv函数为* 

  30. ****************************/  

  31. int i2c_master_recv(struct i2c_client *client, char *buf, int count)  

  32. {  

  33.     struct i2c_adapter *adap = client->adapter;  

  34.     struct i2c_msg msg;  

  35.     int ret;  

  36.     

  37.   //利用msg组织信息结构   

  38.     msg.addr = client->addr;  

  39.     msg.flags = client->flags & I2C_M_TEN;  

  40.     msg.flags |= I2C_M_RD;  

  41.     msg.len = count;  

  42.     msg.buf = buf;  

  43.     

  44.   //调用i2c_transfer发送   

  45.     ret = i2c_transfer(adap, &msg, 1);  

  46.     /* If everything went ok (i.e. 1 msg transmitted), return #bytes 

  47.        transmitted, else error code. */  

  48.     return (ret == 1) ? count : ret;  

  49. }  


    i2c_transfer函数上面已经分析过了,其会最终调用client所在adapter的adap->algo->master_xfer函数发送。


六、总结


    分析了linux下i2c子系统模型及其关键点,针对核心的平台无关代码进行了描述,以上为个人观点,如有不妥,还望指正 ^_^

赞(0) 打赏
转载请注明出处:服务器评测 » Linux设备模型之i2c子系统
分享到: 更多 (0)

听说打赏我的人,都进福布斯排行榜啦!

支付宝扫一扫打赏

微信扫一扫打赏