关闭

Linux I2C子系统分析之(一) ----- 用GPIO模拟I2C总线

标签: clinuxstructalgorithmoutputlist
12461人阅读 评论(1) 收藏 举报
分类:

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. };  

平台驱动设备放在arch/arm/mach-xxxx/board-xxx.c中

   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;  

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;  

这里先做了一个判断,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;  

再来看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;  

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

在这里我认为主要的有

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
# #define I2C_BOARD_INFO(dev_type, dev_addr) \  
#     .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

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

然后是i2c_new_device

# struct i2c_client *  
# i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)  
# {  
#     struct i2c_client   *client;  
#     int         status;  
#   
#     /*为I2C设备申请内存*/  
#     client = kzalloc(sizeof *client, GFP_KERNEL);  
#     if (!client)  
#         return NULL;  
#   
#     /*指定I2C设备的总线*/  
#     client->adapter = adap;  
#   
#     client->dev.platform_data = info->platform_data;  
#   
#     if (info->archdata)  
#         client->dev.archdata = *info->archdata;  
#   
#     client->flags = info->flags;  
#     client->addr = info->addr; /*I2C设备地址*/  
#     client->irq = info->irq;  
#   
#     strlcpy(client->name, info->type, sizeof(client->name));  
#   
#     /*检查这个地址有没有被设备占用*/  
#     /* Check for address business */  
#     status = i2c_check_addr(adap, client->addr);  
#     if (status)  
#         goto out_err;  
#   
#     client->dev.parent = &client->adapter->dev; /*指定设备的父设备*/  
#     client->dev.bus = &i2c_bus_type; /*指定设备的总线类型*/  
#     client->dev.type = &i2c_client_type;  
#   
#     dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap),  
#              client->addr);  
#     status = device_register(&client->dev); /*注册设备*/  
#     if (status)  
#         goto out_err;  
#   
#     dev_dbg(&adap->dev, "client [%s] registered with bus id %s\n",  
#         client->name, dev_name(&client->dev));  
#   
#     return client;  
#   
# out_err:  
#     dev_err(&adap->dev, "Failed to register i2c client %s at 0x%02x "  
#         "(%d)\n", client->name, client->addr, status);  
#     kfree(client);  
#     return NULL; 

这个函数的功能是新建一个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中就是采用的这种方式。至此,总线这块就看完了。






1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:1309838次
    • 积分:14727
    • 等级:
    • 排名:第784名
    • 原创:218篇
    • 转载:286篇
    • 译文:0篇
    • 评论:131条
    文章分类
    最新评论