zoukankan      html  css  js  c++  java
  • Linux I2C子系统分析I2C总线驱动

    Linux I2C子系统分析-I2C总线驱动

    最近在搞i2c-gpio
    分类: linux驱动 209人阅读 评论(0) 收藏 举报

    drivers/i2c/busses下包含各种I2C总线驱动,如S3C2440I2C总线驱动i2c-s3c2410.c,使用GPIO模拟I2C总线的驱动i2c-gpio.c,这里只分析i2c-gpio.c

    i2c-gpio.c它是gpio模拟I2C总线的驱动,总线也是个设备,在这里将总线当作平台设备处理,那驱动当然是平台设备驱动,看它的驱动注册和注销函数。

    1. static int __init i2c_gpio_init(void)  
    2. {  
    3.     int ret;  
    4.   
    5.     ret = platform_driver_register(&i2c_gpio_driver);  
    6.     if (ret)  
    7.         printk(KERN_ERR "i2c-gpio: probe failed: %d\n", ret);  
    8.   
    9.     return ret;  
    10. }  
    11. module_init(i2c_gpio_init);  
    12.   
    13. static void __exit i2c_gpio_exit(void)  
    14. {  
    15.     platform_driver_unregister(&i2c_gpio_driver);  
    16. }  
    17. module_exit(i2c_gpio_exit);  

    没有什么好说的,它的初始化和注销函数就是注册和注销一个平台设备驱动,直接看它的platform_driver结构i2c_gpio_driver

    1. static struct platform_driver i2c_gpio_driver = {  
    2.     .driver     = {  
    3.         .name   = "i2c-gpio",  
    4.         .owner  = THIS_MODULE,  
    5.     },  
    6.     .probe      = i2c_gpio_probe,  
    7.     .remove     = __devexit_p(i2c_gpio_remove),  
    8. };  

    小提示:是不是我们应该注册一个平台设备,以和这个驱动匹配,那先来注册这个平台设备。

    先定义这个平台设备结构,至于怎么注册平台设备我想大家都应该知道吧。

    1. #if defined(CONFIG_I2C_GPIO) | \   
    2.     defined(CONFIG_I2C_GPIO_MODULE)   
    3. static struct i2c_gpio_platform_data i2c_gpio_adapter_data = {   
    4.     .sda_pin = PINID_GPMI_D05,   
    5.     .scl_pin = PINID_GPMI_D04,   
    6.     .udelay = 5, //100KHz   
    7.     .timeout = 100,   
    8.     .sda_is_open_drain = 1,   
    9.     .scl_is_open_drain = 1,   
    10. };   
    11.   
    12. static struct platform_device i2c_gpio = {   
    13.     .name = "i2c-gpio",   
    14.     .id = 0,   
    15.     .dev = {   
    16.         .platform_data = &i2c_gpio_adapter_data,   
    17.         .release = mxs_nop_release,   
    18.         },   
    19. };   
    20. #endif  

    在这里struct platform_device结构中的name字段要和struct platform_driverdriver字段中name字段要相同,因为平台总线就是通过这个来判断设备和驱动是否匹配的。注意这里的id将它赋值了0,至于到底有什么用,后面再来细看。这个结构里面还包含一个最重要的数据i2c_gpio_adapter_data,它struct i2c_gpio_platform_data结构类型变量,这个结构体类型定义在include/linux/i2c-gpio.h中。

    1. struct i2c_gpio_platform_data {  
    2.     unsigned int    sda_pin;  
    3.     unsigned int    scl_pin;  
    4.     int     udelay;  
    5.     int     timeout;  
    6.     unsigned int    sda_is_open_drain:1;  
    7.     unsigned int    scl_is_open_drain:1;  
    8.     unsigned int    scl_is_output_only:1;  
    9. };  

    这个结构体主要描述gpio模拟i2c总线,sda_pinscl_pin表示使用哪两个IO管脚来模拟I2C总线,udelaytimeout分别为它的时钟频率和超时时间,sda_is_open_drainscl_is_open_drain表示sdascl这两个管脚是否是开漏(opendrain)电路,如果是设置为1scl_is_output_only表示scl这个管脚是否只是作为输出,如果是设置为1

    回到驱动中,看其中最重要的i2c_gpio_probe

    1. static int __devinit i2c_gpio_probe(struct platform_device *pdev)  
    2. {  
    3.     struct i2c_gpio_platform_data *pdata;  
    4.     struct i2c_algo_bit_data *bit_data;  
    5.     struct i2c_adapter *adap;  
    6.     int ret;  
    7.   
    8.     pdata = pdev->dev.platform_data;  
    9.     if (!pdata)  
    10.         return -ENXIO;  
    11.   
    12.     ret = -ENOMEM;  
    13.     adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);  
    14.     if (!adap)  
    15.         goto err_alloc_adap;  
    16.     bit_data = kzalloc(sizeof(struct i2c_algo_bit_data), GFP_KERNEL);  
    17.     if (!bit_data)  
    18.         goto err_alloc_bit_data;  
    19.   
    20.     ret = gpio_request(pdata->sda_pin, "sda");  
    21.     if (ret)  
    22.         goto err_request_sda;  
    23.     ret = gpio_request(pdata->scl_pin, "scl");  
    24.     if (ret)  
    25.         goto err_request_scl;  
    26.   
    27.     if (pdata->sda_is_open_drain) {  
    28.         gpio_direction_output(pdata->sda_pin, 1);  
    29.         bit_data->setsda = i2c_gpio_setsda_val;  
    30.     } else {  
    31.         gpio_direction_input(pdata->sda_pin);  
    32.         bit_data->setsda = i2c_gpio_setsda_dir;  
    33.     }  
    34.   
    35.     if (pdata->scl_is_open_drain || pdata->scl_is_output_only) {  
    36.         gpio_direction_output(pdata->scl_pin, 1);  
    37.         bit_data->setscl = i2c_gpio_setscl_val;  
    38.     } else {  
    39.         gpio_direction_input(pdata->scl_pin);  
    40.         bit_data->setscl = i2c_gpio_setscl_dir;  
    41.     }  
    42.   
    43.     if (!pdata->scl_is_output_only)  
    44.         bit_data->getscl = i2c_gpio_getscl;  
    45.     bit_data->getsda = i2c_gpio_getsda;  
    46.   
    47.     if (pdata->udelay)  
    48.         bit_data->udelay = pdata->udelay;  
    49.     else if (pdata->scl_is_output_only)  
    50.         bit_data->udelay = 50;           /* 10 kHz */  
    51.     else  
    52.         bit_data->udelay = 5;            /* 100 kHz */  
    53.   
    54.     if (pdata->timeout)  
    55.         bit_data->timeout = pdata->timeout;  
    56.     else  
    57.         bit_data->timeout = HZ / 10;     /* 100 ms */  
    58.   
    59.     bit_data->data = pdata;  
    60.   
    61.     adap->owner = THIS_MODULE;  
    62.     snprintf(adap->name, sizeof(adap->name), "i2c-gpio%d", pdev->id);  
    63.     adap->algo_data = bit_data;  
    64.     adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;  
    65.     adap->dev.parent = &pdev->dev;  
    66.   
    67.     /* 
    68.      * If "dev->id" is negative we consider it as zero. 
    69.      * The reason to do so is to avoid sysfs names that only make 
    70.      * sense when there are multiple adapters. 
    71.      */  
    72.     adap->nr = (pdev->id != -1) ? pdev->id : 0;  
    73.     ret = i2c_bit_add_numbered_bus(adap);  
    74.     if (ret)  
    75.         goto err_add_bus;  
    76.   
    77.     platform_set_drvdata(pdev, adap);  
    78.   
    79.     dev_info(&pdev->dev, "using pins %u (SDA) and %u (SCL%s)\n",  
    80.          pdata->sda_pin, pdata->scl_pin,  
    81.          pdata->scl_is_output_only  
    82.          ? ", no clock stretching" : "");  
    83.   
    84.     return 0;  
    85.   
    86. err_add_bus:  
    87.     gpio_free(pdata->scl_pin);  
    88. err_request_scl:  
    89.     gpio_free(pdata->sda_pin);  
    90. err_request_sda:  
    91.     kfree(bit_data);  
    92. err_alloc_bit_data:  
    93.     kfree(adap);  
    94. err_alloc_adap:  
    95.     return ret;  
    96. }  

    从这句开始pdata= pdev->dev.platform_data;这不正是我们在平台设备结构中定义的数据吗。然后是使用kzalloc申请两段内存空间,一个是为结构struct i2c_adapter申请的,另一个是为结构structi2c_algo_bit_data申请的。

    struct i2c_adapter结构定义在include/linux/i2c.h

    1. struct i2c_adapter {  
    2.     struct module *owner;  
    3.     unsigned int id;  
    4.     unsigned int class;       /* classes to allow probing for */  
    5.     const struct i2c_algorithm *algo; /* the algorithm to access the bus */  
    6.     void *algo_data;  
    7.   
    8.     /* data fields that are valid for all devices   */  
    9.     u8 level;           /* nesting level for lockdep */  
    10.     struct mutex bus_lock;  
    11.   
    12.     int timeout;            /* in jiffies */  
    13.     int retries;  
    14.     struct device dev;      /* the adapter device */  
    15.   
    16.     int nr;  
    17.     char name[48];  
    18.     struct completion dev_released;  
    19. };  

    I2C子系统中,I2C适配器使用结构struct i2c_adapter描述,代表一条实际的I2C总线。

    struct i2c_algo_bit_data结构定义在include/linux/i2c-algo-bit.h

    1. struct i2c_algo_bit_data {  
    2.     void *data;     /* private data for lowlevel routines */  
    3.     void (*setsda) (void *data, int state);  
    4.     void (*setscl) (void *data, int state);  
    5.     int  (*getsda) (void *data);  
    6.     int  (*getscl) (void *data);  
    7.   
    8.     /* local settings */  
    9.     int udelay;     /* half clock cycle time in us, 
    10.                    minimum 2 us for fast-mode I2C, 
    11.                    minimum 5 us for standard-mode I2C and SMBus, 
    12.                    maximum 50 us for SMBus */  
    13.     int timeout;        /* in jiffies */  
    14. };  

    这个结构主要用来定义对GPIO管脚的一些操作,还是回到probe

    接下来使用gpio_request去申请这个两个GPIO管脚,申请的目的是为了防止重复使用管脚。然后是根据struct i2c_gpio_platform_data结构中定义的后面三个数据对struct i2c_algo_bit_data结构中的函数指针做一些赋值操作。接下来是I2C时钟频率和超时设置,如果在struct i2c_gpio_platform_data结构中定义了值,那么就采用定义的值,否则就采用默认的值。然后是对struct i2c_adapter结构的一些赋值操作,比如指定它的父设备为这里的平台设备,前面在平台设备中定义了一个id,这里用到了,赋给了struct i2c_adapter中的nr成员,这个值表示总线号,这里的总线号和硬件无关,只是在软件上的区分。然后到了最后的主角i2c_bit_add_numbered_bus,这个函数定义在drivers/i2c/algos/i2c-algo-bit.c

    1. int i2c_bit_add_numbered_bus(struct i2c_adapter *adap)  
    2. {  
    3.     int err;  
    4.   
    5.     err = i2c_bit_prepare_bus(adap);  
    6.     if (err)  
    7.         return err;  
    8.   
    9.     return i2c_add_numbered_adapter(adap);  
    10. }  

    先看i2c_bit_prepare_bus函数

    1. static int i2c_bit_prepare_bus(struct i2c_adapter *adap)  
    2. {  
    3.     struct i2c_algo_bit_data *bit_adap = adap->algo_data;  
    4.   
    5.     if (bit_test) {  
    6.         int ret = test_bus(bit_adap, adap->name);  
    7.         if (ret < 0)  
    8.             return -ENODEV;  
    9.     }  
    10.   
    11.     /* register new adapter to i2c module... */  
    12.     adap->algo = &i2c_bit_algo;  
    13.     adap->retries = 3;  
    14.   
    15.     return 0;  
    16. }  

    bit_test为模块参数,这里不管它,看这样一句adap->algo= &i2c_bit_algo;

    来看这个结构定义

    1. static const struct i2c_algorithm i2c_bit_algo = {  
    2.     .master_xfer    = bit_xfer,  
    3.     .functionality  = bit_func,  
    4. };  

    先看这个结构类型在哪里定义的include/linux/i2c.h

    1. struct i2c_algorithm {  
    2.     /* If an adapter algorithm can't do I2C-level access, set master_xfer 
    3.        to NULL. If an adapter algorithm can do SMBus access, set 
    4.        smbus_xfer. If set to NULL, the SMBus protocol is simulated 
    5.        using common I2C messages */  
    6.     /* master_xfer should return the number of messages successfully 
    7.        processed, or a negative value on error */  
    8.     int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs,  
    9.                int num);  
    10.     int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,  
    11.                unsigned short flags, char read_write,  
    12.                u8 command, int size, union i2c_smbus_data *data);  
    13.   
    14.     /* To determine what the adapter supports */  
    15.     u32 (*functionality) (struct i2c_adapter *);  
    16. };  

    其实也没什么,就三个函数指针外加一长串注释

    这个结构的master_xfer指针为主机的数据传输,具体来看bit_xfer这个函数,这个函数和I2C协议相关,I2C协议规定要先发送起始信号,才能开始进行数据的传输,最后数据传输完成后发送停止信号,看接下来代码对I2C协议要熟悉,所以这里的关键点是I2C协议。

    1. static int bit_xfer(struct i2c_adapter *i2c_adap,  
    2.             struct i2c_msg msgs[], int num)  
    3. {  
    4.     struct i2c_msg *pmsg;  
    5.     struct i2c_algo_bit_data *adap = i2c_adap->algo_data;  
    6.     int i, ret;  
    7.     unsigned short nak_ok;  
    8.   
    9.     bit_dbg(3, &i2c_adap->dev, "emitting start condition\n");  
    10.     /*发送起始信号*/  
    11.     i2c_start(adap);  
    12.     for (i = 0; i < num; i++) {  
    13.         pmsg = &msgs[i];  
    14.         nak_ok = pmsg->flags & I2C_M_IGNORE_NAK;  
    15.         if (!(pmsg->flags & I2C_M_NOSTART)) {  
    16.             if (i) {  
    17.                 bit_dbg(3, &i2c_adap->dev, "emitting "  
    18.                     "repeated start condition\n");  
    19.                 i2c_repstart(adap);  
    20.             }  
    21.             ret = bit_doAddress(i2c_adap, pmsg);  
    22.             if ((ret != 0) && !nak_ok) {  
    23.                 bit_dbg(1, &i2c_adap->dev, "NAK from "  
    24.                     "device addr 0x%02x msg #%d\n",  
    25.                     msgs[i].addr, i);  
    26.                 goto bailout;  
    27.             }  
    28.         }  
    29.         if (pmsg->flags & I2C_M_RD) {  
    30.             /* read bytes into buffer*/  
    31.             ret = readbytes(i2c_adap, pmsg);  
    32.             if (ret >= 1)  
    33.                 bit_dbg(2, &i2c_adap->dev, "read %d byte%s\n",  
    34.                     ret, ret == 1 ? "" : "s");  
    35.             if (ret < pmsg->len) {  
    36.                 if (ret >= 0)  
    37.                     ret = -EREMOTEIO;  
    38.                 goto bailout;  
    39.             }  
    40.         } else {  
    41.             /* write bytes from buffer */  
    42.             ret = sendbytes(i2c_adap, pmsg);  
    43.             if (ret >= 1)  
    44.                 bit_dbg(2, &i2c_adap->dev, "wrote %d byte%s\n",  
    45.                     ret, ret == 1 ? "" : "s");  
    46.             if (ret < pmsg->len) {  
    47.                 if (ret >= 0)  
    48.                     ret = -EREMOTEIO;  
    49.                 goto bailout;  
    50.             }  
    51.         }  
    52.     }  
    53.     ret = i;  
    54.   
    55. bailout:  
    56.     bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n");  
    57.     i2c_stop(adap);  
    58.     return ret;  
    59. }  

    1.发送起始信号

    i2c_start(adap);

    看这个函数前,先看I2C协议怎么定义起始信号的


    起始信号就是在SCL为高电平期间,SDA从高到低的跳变,再来看代码是怎么实现的

    1. static void i2c_start(struct i2c_algo_bit_data *adap)  
    2. {  
    3.     /* assert: scl, sda are high */  
    4.     setsda(adap, 0);  
    5.     udelay(adap->udelay);  
    6.     scllo(adap);  
    7. }  

    这些setsdasetscl这些都是使用的总线的函数,在这里是使用的i2c-gpio.c中定义的函数,还记得那一系列判断赋值吗。

    1. #define setsda(adap, val)   adap->setsda(adap->data, val)  
    2. #define setscl(adap, val)   adap->setscl(adap->data, val)  
    3. #define getsda(adap)        adap->getsda(adap->data)  
    4. #define getscl(adap)        adap->getscl(adap->data)  

    2.往下是个大的for循环

    到了这里又不得不说这个struct i2c_msg结构,这个结构定义在include/linux/i2c.h

    1. struct i2c_msg {  
    2.     __u16 addr; /* slave address            */  
    3.     __u16 flags;  
    4. #define I2C_M_TEN       0x0010  /* this is a ten bit chip address */  
    5. #define I2C_M_RD        0x0001  /* read data, from slave to master */  
    6. #define I2C_M_NOSTART       0x4000  /* if I2C_FUNC_PROTOCOL_MANGLING */  
    7. #define I2C_M_REV_DIR_ADDR  0x2000  /* if I2C_FUNC_PROTOCOL_MANGLING */  
    8. #define I2C_M_IGNORE_NAK    0x1000  /* if I2C_FUNC_PROTOCOL_MANGLING */  
    9. #define I2C_M_NO_RD_ACK     0x0800  /* if I2C_FUNC_PROTOCOL_MANGLING */  
    10. #define I2C_M_RECV_LEN      0x0400  /* length will be first received byte */  
    11.     __u16 len;      /* msg length               */  
    12.     __u8 *buf;      /* pointer to msg data          */  
    13. };  

    这个结构专门用于数据传输相关的addrI2C设备地址,flags为一些标志位,len为数据的长度,buf为数据。这里宏定义的一些标志还是需要了解一下。

    I2C_M_TEN表示10位设备地址

    I2C_M_RD读标志

    I2C_M_NOSTART无起始信号标志

    I2C_M_IGNORE_NAK忽略应答信号标志

    回到for,这里的num代表有几个struct i2c_msg,进入for语句,接下来是个if语句,判断这个设备是否定义了I2C_M_NOSTART标志,这个标志主要用于写操作时,不必重新发送起始信号和设备地址,但是对于读操作就不同了,要调用i2c_repstart这个函数去重新发送起始信号,调用bit_doAddress函数去重新构造设备地址字节,来看这个函数。

    1. static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)  
    2. {  
    3.     unsigned short flags = msg->flags;  
    4.     unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK;  
    5.     struct i2c_algo_bit_data *adap = i2c_adap->algo_data;  
    6.   
    7.     unsigned char addr;  
    8.     int ret, retries;  
    9.   
    10.     retries = nak_ok ? 0 : i2c_adap->retries;  
    11.   
    12.     if (flags & I2C_M_TEN) {  
    13.         /* a ten bit address */  
    14.         addr = 0xf0 | ((msg->addr >> 7) & 0x03);  
    15.         bit_dbg(2, &i2c_adap->dev, "addr0: %d\n", addr);  
    16.         /* try extended address code...*/  
    17.         ret = try_address(i2c_adap, addr, retries);  
    18.         if ((ret != 1) && !nak_ok)  {  
    19.             dev_err(&i2c_adap->dev,  
    20.                 "died at extended address code\n");  
    21.             return -EREMOTEIO;  
    22.         }  
    23.         /* the remaining 8 bit address */  
    24.         ret = i2c_outb(i2c_adap, msg->addr & 0x7f);  
    25.         if ((ret != 1) && !nak_ok) {  
    26.             /* the chip did not ack / xmission error occurred */  
    27.             dev_err(&i2c_adap->dev, "died at 2nd address code\n");  
    28.             return -EREMOTEIO;  
    29.         }  
    30.         if (flags & I2C_M_RD) {  
    31.             bit_dbg(3, &i2c_adap->dev, "emitting repeated "  
    32.                 "start condition\n");  
    33.             i2c_repstart(adap);  
    34.             /* okay, now switch into reading mode */  
    35.             addr |= 0x01;  
    36.             ret = try_address(i2c_adap, addr, retries);  
    37.             if ((ret != 1) && !nak_ok) {  
    38.                 dev_err(&i2c_adap->dev,  
    39.                     "died at repeated address code\n");  
    40.                 return -EREMOTEIO;  
    41.             }  
    42.         }  
    43.     } else {        /* normal 7bit address  */  
    44.         addr = msg->addr << 1;  
    45.         if (flags & I2C_M_RD)  
    46.             addr |= 1;  
    47.         if (flags & I2C_M_REV_DIR_ADDR)  
    48.             addr ^= 1;  
    49.         ret = try_address(i2c_adap, addr, retries);  
    50.         if ((ret != 1) && !nak_ok)  
    51.             return -ENXIO;  
    52.     }  
    53.   
    54.     return 0;  
    55. }  

    这里先做了一个判断,10位设备地址和7位设备地址分别做不同的处理,通常一条I2C总线上不会挂那么多I2C设备,所以10位地址不常用,直接看对7位地址的处理。struct i2c_msgaddr中是真正的设备地址,而这里发送的addr7位才是设备地址,最低位为读写位,如果为读,最低位为1,如果为写,最低位为0。所以要将struct i2c_msgaddr向左移1位,如果定义了I2C_M_RD标志,就将addr或上1,前面就说过,这个标志就代表读,如果是写,这里就不用处理,因为最低位本身就是0。最后调用try_address函数将这个地址字节发送出去。

    1. static int try_address(struct i2c_adapter *i2c_adap,  
    2.                unsigned char addr, int retries)  
    3. {  
    4.     struct i2c_algo_bit_data *adap = i2c_adap->algo_data;  
    5.     int i, ret = 0;  
    6.   
    7.     for (i = 0; i <= retries; i++) {  
    8.         ret = i2c_outb(i2c_adap, addr);  
    9.         if (ret == 1 || i == retries)  
    10.             break;  
    11.         bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n");  
    12.         i2c_stop(adap);  
    13.         udelay(adap->udelay);  
    14.         yield();  
    15.         bit_dbg(3, &i2c_adap->dev, "emitting start condition\n");  
    16.         i2c_start(adap);  
    17.     }  
    18.     if (i && ret)  
    19.         bit_dbg(1, &i2c_adap->dev, "Used %d tries to %s client at "  
    20.             "0x%02x: %s\n", i + 1,  
    21.             addr & 1 ? "read from" : "write to", addr >> 1,  
    22.             ret == 1 ? "success" : "failed, timeout?");  
    23.     return ret;  
    24. }  

    最主要的就是调用i2c_outb发送一个字节,retries为重复次数,看前面adap->retries= 3;

    如果发送失败,也就是设备没有给出应答信号,那就发送停止信号,发送起始信号,再发送这个地址字节,这就叫retries。来看这个具体的i2c_outb函数

    1. static int i2c_outb(struct i2c_adapter *i2c_adap, unsigned char c)  
    2. {  
    3.     int i;  
    4.     int sb;  
    5.     int ack;  
    6.     struct i2c_algo_bit_data *adap = i2c_adap->algo_data;  
    7.   
    8.     /* assert: scl is low */  
    9.     for (i = 7; i >= 0; i--) {  
    10.         sb = (c >> i) & 1;  
    11.         setsda(adap, sb);  
    12.         udelay((adap->udelay + 1) / 2);  
    13.         if (sclhi(adap) < 0) { /* timed out */  
    14.             bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, "  
    15.                 "timeout at bit #%d\n", (int)c, i);  
    16.             return -ETIMEDOUT;  
    17.         }  
    18.         /* FIXME do arbitration here: 
    19.          * if (sb && !getsda(adap)) -> ouch! Get out of here. 
    20.          * 
    21.          * Report a unique code, so higher level code can retry 
    22.          * the whole (combined) message and *NOT* issue STOP. 
    23.          */  
    24.         scllo(adap);  
    25.     }  
    26.     sdahi(adap);  
    27.     if (sclhi(adap) < 0) { /* timeout */  
    28.         bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, "  
    29.             "timeout at ack\n", (int)c);  
    30.         return -ETIMEDOUT;  
    31.     }  
    32.   
    33.     /* read ack: SDA should be pulled down by slave, or it may 
    34.      * NAK (usually to report problems with the data we wrote). 
    35.      */  
    36.     ack = !getsda(adap);    /* ack: sda is pulled low -> success */  
    37.     bit_dbg(2, &i2c_adap->dev, "i2c_outb: 0x%02x %s\n", (int)c,  
    38.         ack ? "A" : "NA");  
    39.   
    40.     scllo(adap);  
    41.     return ack;  
    42.     /* assert: scl is low (sda undef) */  
    43. }  

    这个函数有两个参数,一个是structi2c_adapter代表I2C主机,一个是发送的字节数据。那么I2C是怎样将一个字节数据发送出去的呢,那再来看看协议。



    首先是发送字节数据的最高位,在时钟为高电平期间将一位数据发送出去,最后是发送字节数据的最低位。发送完成之后,我们需要一个ACK信号,要不然我怎么知道发送成功没有,ACK信号就是在第九个时钟周期时数据线为低,所以在一个字节数据传送完成后,还要将数据线拉高,我们看程序中就是这一句sdahi(adap);等待这个ACK信号的到来,这样一个字节数据就发送完成。

    回到bit_xfer函数中,前面只是将设备地址字节发送出去了,那么接下来就是该发送数据了。

    注意:这里的数据包括操作设备的基地址

    如果是读则调用readbytes函数去读,如果是写则调用sendbytes去写,先看readbytes函数

    1. static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)  
    2. {  
    3.     int inval;  
    4.     int rdcount = 0;    /* counts bytes read */  
    5.     unsigned char *temp = msg->buf;  
    6.     int count = msg->len;  
    7.     const unsigned flags = msg->flags;  
    8.   
    9.     while (count > 0) {  
    10.         inval = i2c_inb(i2c_adap);  
    11.         if (inval >= 0) {  
    12.             *temp = inval;  
    13.             rdcount++;  
    14.         } else {   /* read timed out */  
    15.             break;  
    16.         }  
    17.   
    18.         temp++;  
    19.         count--;  
    20.   
    21.         /* Some SMBus transactions require that we receive the 
    22.            transaction length as the first read byte. */  
    23.         if (rdcount == 1 && (flags & I2C_M_RECV_LEN)) {  
    24.             if (inval <= 0 || inval > I2C_SMBUS_BLOCK_MAX) {  
    25.                 if (!(flags & I2C_M_NO_RD_ACK))  
    26.                     acknak(i2c_adap, 0);  
    27.                 dev_err(&i2c_adap->dev, "readbytes: invalid "  
    28.                     "block length (%d)\n", inval);  
    29.                 return -EREMOTEIO;  
    30.             }  
    31.             /* The original count value accounts for the extra 
    32.                bytes, that is, either 1 for a regular transaction, 
    33.                or 2 for a PEC transaction. */  
    34.             count += inval;  
    35.             msg->len += inval;  
    36.         }  
    37.   
    38.         bit_dbg(2, &i2c_adap->dev, "readbytes: 0x%02x %s\n",  
    39.             inval,  
    40.             (flags & I2C_M_NO_RD_ACK)  
    41.                 ? "(no ack/nak)"  
    42.                 : (count ? "A" : "NA"));  
    43.   
    44.         if (!(flags & I2C_M_NO_RD_ACK)) {  
    45.             inval = acknak(i2c_adap, count);  
    46.             if (inval < 0)  
    47.                 return inval;  
    48.         }  
    49.     }  
    50.     return rdcount;  
    51. }  

    其中一个大的while循环,调用i2c_inb去读一个字节,count为数据的长度,单位为多少个字节,

    那就来看i2c_inb函数。

    1. static int i2c_inb(struct i2c_adapter *i2c_adap)  
    2. {  
    3.     /* read byte via i2c port, without start/stop sequence  */  
    4.     /* acknowledge is sent in i2c_read.         */  
    5.     int i;  
    6.     unsigned char indata = 0;  
    7.     struct i2c_algo_bit_data *adap = i2c_adap->algo_data;  
    8.   
    9.     /* assert: scl is low */  
    10.     sdahi(adap);  
    11.     for (i = 0; i < 8; i++) {  
    12.         if (sclhi(adap) < 0) { /* timeout */  
    13.             bit_dbg(1, &i2c_adap->dev, "i2c_inb: timeout at bit "  
    14.                 "#%d\n", 7 - i);  
    15.             return -ETIMEDOUT;  
    16.         }  
    17.         indata *= 2;  
    18.         if (getsda(adap))  
    19.             indata |= 0x01;  
    20.         setscl(adap, 0);  
    21.         udelay(i == 7 ? adap->udelay / 2 : adap->udelay);  
    22.     }  
    23.     /* assert: scl is low */  
    24.     return indata;  
    25. }  

    再来看sendbytes函数

    1. static int sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)  
    2. {  
    3.     const unsigned char *temp = msg->buf;  
    4.     int count = msg->len;  
    5.     unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK;  
    6.     int retval;  
    7.     int wrcount = 0;  
    8.   
    9.     while (count > 0) {  
    10.         retval = i2c_outb(i2c_adap, *temp);  
    11.   
    12.         /* OK/ACK; or ignored NAK */  
    13.         if ((retval > 0) || (nak_ok && (retval == 0))) {  
    14.             count--;  
    15.             temp++;  
    16.             wrcount++;  
    17.   
    18.         /* A slave NAKing the master means the slave didn't like 
    19.          * something about the data it saw.  For example, maybe 
    20.          * the SMBus PEC was wrong. 
    21.          */  
    22.         } else if (retval == 0) {  
    23.             dev_err(&i2c_adap->dev, "sendbytes: NAK bailout.\n");  
    24.             return -EIO;  
    25.   
    26.         /* Timeout; or (someday) lost arbitration 
    27.          * 
    28.          * FIXME Lost ARB implies retrying the transaction from 
    29.          * the first message, after the "winning" master issues 
    30.          * its STOP.  As a rule, upper layer code has no reason 
    31.          * to know or care about this ... it is *NOT* an error. 
    32.          */  
    33.         } else {  
    34.             dev_err(&i2c_adap->dev, "sendbytes: error %d\n",  
    35.                     retval);  
    36.             return retval;  
    37.         }  
    38.     }  
    39.     return wrcount;  
    40. }  

    也是一个大的while循环,同发送地址字节一样,也是调用i2c_outb去发送一个字节,count也是数据长度,由于i2c_outb函数在前面发送设备地址那里已经介绍了,这里也就不贴出来了。

    还是回到bit_xfer函数,数据传输完成后,调用i2c_stop函数发送停止信号。我们看停止信号函数怎么去实现的。

    1. static void i2c_stop(struct i2c_algo_bit_data *adap)  
    2. {  
    3.     /* assert: scl is low */  
    4.     sdalo(adap);  
    5.     sclhi(adap);  
    6.     setsda(adap, 1);  
    7.     udelay(adap->udelay);  
    8. }  

    看前面发送起始信号的那张图,停止信号就是在时钟为高电平期间,数据线从低到高的跳变。我们看程序是先将数据线拉低,将时钟线拉高,最后将数据拉高,这样就够成了一个停止信号。

    还是回到i2c_bit_add_numbered_bus这个函数中来,看另外一个函数调用i2c_add_numbered_adapter

    1. int i2c_add_numbered_adapter(struct i2c_adapter *adap)  
    2. {  
    3.     int id;  
    4.     int status;  
    5.   
    6.     if (adap->nr & ~MAX_ID_MASK)  
    7.         return -EINVAL;  
    8.   
    9. retry:  
    10.     if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0)  
    11.         return -ENOMEM;  
    12.   
    13.     mutex_lock(&core_lock);  
    14.     /* "above" here means "above or equal to", sigh; 
    15.      * we need the "equal to" result to force the result 
    16.      */  
    17.     status = idr_get_new_above(&i2c_adapter_idr, adap, adap->nr, &id);  
    18.     if (status == 0 && id != adap->nr) {  
    19.         status = -EBUSY;  
    20.         idr_remove(&i2c_adapter_idr, id);  
    21.     }  
    22.     mutex_unlock(&core_lock);  
    23.     if (status == -EAGAIN)  
    24.         goto retry;  
    25.   
    26.     if (status == 0)  
    27.         status = i2c_register_adapter(adap);  
    28.     return status;  
    29. }  

    最重要的是这句i2c_register_adapter,注册这条I2C总线,进去看看

    1. static int i2c_register_adapter(struct i2c_adapter *adap)  
    2. {  
    3.     int res = 0, dummy;  
    4.   
    5.     /* Can't register until after driver model init */  
    6.     if (unlikely(WARN_ON(!i2c_bus_type.p))) {  
    7.         res = -EAGAIN;  
    8.         goto out_list;  
    9.     }  
    10.   
    11.     mutex_init(&adap->bus_lock);  
    12.   
    13.     /* Set default timeout to 1 second if not already set */  
    14.     if (adap->timeout == 0)  
    15.         adap->timeout = HZ;  
    16.   
    17.     dev_set_name(&adap->dev, "i2c-%d", adap->nr);  
    18.     adap->dev.bus = &i2c_bus_type;  
    19.     adap->dev.type = &i2c_adapter_type;  
    20.     res = device_register(&adap->dev);  
    21.     if (res)  
    22.         goto out_list;  
    23.   
    24.     dev_dbg(&adap->dev, "adapter [%s] registered\n", adap->name);  
    25.   
    26. #ifdef CONFIG_I2C_COMPAT  
    27.     res = class_compat_create_link(i2c_adapter_compat_class, &adap->dev,  
    28.                        adap->dev.parent);  
    29.     if (res)  
    30.         dev_warn(&adap->dev,  
    31.              "Failed to create compatibility class link\n");  
    32. #endif  
    33.   
    34.     /* create pre-declared device nodes */  
    35.     if (adap->nr < __i2c_first_dynamic_bus_num)  
    36.         i2c_scan_static_board_info(adap);  
    37.   
    38.     /* Notify drivers */  
    39.     mutex_lock(&core_lock);  
    40.     dummy = bus_for_each_drv(&i2c_bus_type, NULL, adap,  
    41.                  i2c_do_add_adapter);  
    42.     mutex_unlock(&core_lock);  
    43.   
    44.     return 0;  
    45.   
    46. out_list:  
    47.     mutex_lock(&core_lock);  
    48.     idr_remove(&i2c_adapter_idr, adap->nr);  
    49.     mutex_unlock(&core_lock);  
    50.     return res;  
    51. }  

    看内核代码有时就会这样,会陷入内核代码的汪洋大海中,而拔不出来,直接后果是最后都忘记看这段代码的目的,丧失继续看下去的信心。所以为了避免这样情况出现,所以最好在开始看代码的时候要明确目标,我通过这段代码到底要了解什么东西,主干要抓住,其它枝叶就不要看了。

    在这里我认为主要的有

    1.注册这个I2C总线设备

    1. adap->dev.bus = &i2c_bus_type;  
    2. adap->dev.type = &i2c_adapter_type;  
    3. res = device_register(&adap->dev);  

    这个设备的总线类型为i2c_bus_type

    1. struct bus_type i2c_bus_type = {  
    2.     .name       = "i2c",  
    3.     .match      = i2c_device_match,  
    4.     .probe      = i2c_device_probe,  
    5.     .remove     = i2c_device_remove,  
    6.     .shutdown   = i2c_device_shutdown,  
    7.     .suspend    = i2c_device_suspend,  
    8.     .resume     = i2c_device_resume,  
    9. };  

    看一下它的match函数

    1. static int i2c_device_match(struct device *dev, struct device_driver *drv)  
    2. {  
    3.     struct i2c_client   *client = i2c_verify_client(dev);  
    4.     struct i2c_driver   *driver;  
    5.   
    6.     if (!client)  
    7.         return 0;  
    8.   
    9.     driver = to_i2c_driver(drv);  
    10.     /* match on an id table if there is one */  
    11.     if (driver->id_table)  
    12.         return i2c_match_id(driver->id_table, client) != NULL;  
    13.   
    14.     return 0;  
    15. }  

    这个match函数主要用来匹配我们的I2C设备和I2C驱动的,如果匹配成功,最后会调用驱动的probe函数,来看它如何匹配的。

    1. static const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id,  
    2.                         const struct i2c_client *client)  
    3. {  
    4.     while (id->name[0]) {  
    5.         if (strcmp(client->name, id->name) == 0)  
    6.             return id;  
    7.         id++;  
    8.     }  
    9.     return NULL;  
    10. }  

    就是判断I2C设备的name字段和驱动中id_table中定义的name字段是否相等。

    2.往这条总线上添加设备

    1. static void i2c_scan_static_board_info(struct i2c_adapter *adapter)  
    2. {  
    3.     struct i2c_devinfo  *devinfo;  
    4.   
    5.     down_read(&__i2c_board_lock);  
    6.     list_for_each_entry(devinfo, &__i2c_board_list, list) {  
    7.         if (devinfo->busnum == adapter->nr  
    8.                 && !i2c_new_device(adapter,  
    9.                         &devinfo->board_info))  
    10.             dev_err(&adapter->dev,  
    11.                 "Can't create device at 0x%02x\n",  
    12.                 devinfo->board_info.addr);  
    13.     }  
    14.     up_read(&__i2c_board_lock);  
    15. }  

    遍历__i2c_board_list这条链表,看下面的if语句,首先要让struct i2c_devinfo结构中的busnum等于struct i2c_adapter中的nr,我们前面也说了,这个nr就是i2c总线的总线号,这里可以理解为是在往这条总线上添加设备。所以,如果我们要向I2C注册一个I2C设备的话,直接向__i2c_board_list添加一个设备信息就可以了,先来看这个设备信息结构是怎么定义的。

    1. struct i2c_board_info {  
    2.     char        type[I2C_NAME_SIZE];  
    3.     unsigned short  flags;  
    4.     unsigned short  addr;  
    5.     void        *platform_data;  
    6.     struct dev_archdata *archdata;  
    7.     int     irq;  
    8. };  

    定义这样一个信息呢一般使用一个宏I2C_BOARD_INFO

    1. #define I2C_BOARD_INFO(dev_type, dev_addr) \  
    2.     .type = dev_type, .addr = (dev_addr)  

    dev_type为设备的名字,前面也说了,这个name一定要和I2C驱动相同。addr为设备的地址。

    定义了这样一组信息之后呢,接下来当然是往链表添加这些信息了。

    1. int __init  
    2. i2c_register_board_info(int busnum,  
    3.     struct i2c_board_info const *info, unsigned len)  
    4. {  
    5.     int status;  
    6.   
    7.     down_write(&__i2c_board_lock);  
    8.   
    9.     /* dynamic bus numbers will be assigned after the last static one */  
    10.     if (busnum >= __i2c_first_dynamic_bus_num)  
    11.         __i2c_first_dynamic_bus_num = busnum + 1;  
    12.   
    13.     for (status = 0; len; len--, info++) {  
    14.         struct i2c_devinfo  *devinfo;  
    15.   
    16.         devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL);  
    17.         if (!devinfo) {  
    18.             pr_debug("i2c-core: can't register boardinfo!\n");  
    19.             status = -ENOMEM;  
    20.             break;  
    21.         }  
    22.   
    23.         devinfo->busnum = busnum;  
    24.         devinfo->board_info = *info;  
    25.         list_add_tail(&devinfo->list, &__i2c_board_list);  
    26.     }  
    27.   
    28.     up_write(&__i2c_board_lock);  
    29.   
    30.     return status;  
    31. }  

    第一个参数呢需要注意,它是I2C总线号,一定要和具体的I2C总线对应。我们看又定义了这样一个结构struct i2c_devinfo

    1. struct i2c_devinfo {  
    2.     struct list_head    list;  
    3.     int         busnum;  
    4.     struct i2c_board_info   board_info;  
    5. };  

    最后是调用list_add_tail__i2c_board_list这条链表添加设备信息。

    然后是i2c_new_device

    1. struct i2c_client *  
    2. i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)  
    3. {  
    4.     struct i2c_client   *client;  
    5.     int         status;  
    6.   
    7.     /*为I2C设备申请内存*/  
    8.     client = kzalloc(sizeof *client, GFP_KERNEL);  
    9.     if (!client)  
    10.         return NULL;  
    11.   
    12.     /*指定I2C设备的总线*/  
    13.     client->adapter = adap;  
    14.   
    15.     client->dev.platform_data = info->platform_data;  
    16.   
    17.     if (info->archdata)  
    18.         client->dev.archdata = *info->archdata;  
    19.   
    20.     client->flags = info->flags;  
    21.     client->addr = info->addr; /*I2C设备地址*/  
    22.     client->irq = info->irq;  
    23.   
    24.     strlcpy(client->name, info->type, sizeof(client->name));  
    25.   
    26.     /*检查这个地址有没有被设备占用*/  
    27.     /* Check for address business */  
    28.     status = i2c_check_addr(adap, client->addr);  
    29.     if (status)  
    30.         goto out_err;  
    31.   
    32.     client->dev.parent = &client->adapter->dev; /*指定设备的父设备*/  
    33.     client->dev.bus = &i2c_bus_type; /*指定设备的总线类型*/  
    34.     client->dev.type = &i2c_client_type;  
    35.   
    36.     dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap),  
    37.              client->addr);  
    38.     status = device_register(&client->dev); /*注册设备*/  
    39.     if (status)  
    40.         goto out_err;  
    41.   
    42.     dev_dbg(&adap->dev, "client [%s] registered with bus id %s\n",  
    43.         client->name, dev_name(&client->dev));  
    44.   
    45.     return client;  
    46.   
    47. out_err:  
    48.     dev_err(&adap->dev, "Failed to register i2c client %s at 0x%02x "  
    49.         "(%d)\n", client->name, client->addr, status);  
    50.     kfree(client);  
    51.     return NULL;  
    52. }  

    这个函数的功能是新建一个I2C设备并注册它,在I2C子系统中,I2C设备使用结构structi2c_client描述,那么首先要申请内存空间,I2C设备的主机是谁,必须知道挂载到哪条总线上的,然后就是一些赋值操作,最后就是注册设备,那么这个设备就实实在在的挂在到这条总线上了,这也是新的I2C设备注册方式。

    3.i2c_do_add_adapter

    你看说着说着就跑远了

    1. static int i2c_do_add_adapter(struct device_driver *d, void *data)  
    2. {  
    3.     struct i2c_driver *driver = to_i2c_driver(d);  
    4.     struct i2c_adapter *adap = data;  
    5.   
    6.     /* Detect supported devices on that bus, and instantiate them */  
    7.     i2c_detect(adap, driver);  
    8.   
    9.     /* Let legacy drivers scan this bus for matching devices */  
    10.     if (driver->attach_adapter) {  
    11.         /* We ignore the return code; if it fails, too bad */  
    12.         driver->attach_adapter(adap);  
    13.     }  
    14.     return 0;  
    15. }  

    前面通过i2c_scan_static_board_infoI2C总线上添加设备是新的方式,而这里调用每个I2C设备驱动的attach_adapter函数,然后在attach_adapter函数中去实现设备的注册,这是老的方式,i2c-dev.c中就是采用的这种方式。至此,总线这块就看完了。

  • 相关阅读:
    关于oralce字符集问题(复制别人的,纯属自己学习)
    Linux下oracle11gR2系统安装到数据库建立配置及最后oracle的dmp文件导入一站式操作记录
    Linux下部署ASP.NET服务连接oracle遇到的问题记录
    前端金钱分转元,元转分精度问题解决
    vue-element的form表单显示图片
    vue页面刷新技巧--(v-if指令)以及vue动态设置css属性
    vue后端获取的数据无法进行双向数据绑定
    Vue实现勾选框全选和局部选择功能
    VUE/jQuery生成二维码扫描跳转地址
    uni-app之数据状态改动后页面不刷新踩坑
  • 原文地址:https://www.cnblogs.com/yuzaipiaofei/p/4124217.html
Copyright © 2011-2022 走看看