linux i2c

32 篇文章 8 订阅

https://blog.csdn.net/chenliang0224/article/details/79069908

1.前言:

 

linux I2C体系结构由三部分组成

①I2C核心:提供I2C总线驱动和设备驱动的注册、注销方法

②I2C总线驱动:主要包括两个数据结构,适配器I2c_adapter(包括algorithm结构体指针)、和algorithm数据结构(最终I2C的通信是由algorithm结构控制发送与接受数据)

③I2C设备驱动:是对I2C硬件体系结构中设备端的实现,两个数据结构,分别是I2c_driver(包括I2C的依附、脱离、探测、移除、关闭、恢复、读写数据。。。)对应一对通信方法、I2c_cilent(包括I2C硬件的芯片地址,设备名称、等,其中该结构体包括适配器I2c_adapter,和I2c_driver指针,这样就可以直接访问了)该结构体对应实在的硬件

 

2.Platform_device i2c 平台设备注册

2.1 i2c IO中断、IO管脚寄存器资源

 

 
  1. static struct resource nuc970_i2c0_resource[] = {

  2. [0] = {

  3. .start = NUC970_PA_I2C0,

  4. .end = NUC970_PA_I2C0 + NUC970_SZ_I2C0 - 1,

  5. .flags = IORESOURCE_MEM,

  6. },

  7. [1] = {

  8. .start = IRQ_I2C0,

  9. .end = IRQ_I2C0,

  10. .flags = IORESOURCE_IRQ,

  11. }

  12. };

2.2 i2c设备平台私有数据

包括I2C总线编号、总线频率

 
  1. static struct nuc970_platform_i2c nuc970_i2c0_data = {

  2. .bus_num = 0, //I2C总线,这里使用的是总线0

  3. .bus_freq = 100000, //I2C总线频率

  4. };

2.3 i2c平台设备注册

 
  1. struct platform_device nuc970_device_i2c0 = {

  2. .name = "nuc970-i2c0",

  3. .id = -1,

  4. .num_resources = ARRAY_SIZE(nuc970_i2c0_resource),

  5. .resource = nuc970_i2c0_resource,

  6. .dev = {

  7. .platform_data = &nuc970_i2c0_data,

  8. }

  9. };

platform_device_register(nuc970_device_i2c0);

platform_device_register(...)将I2C设备注册到platform总线上,为了接下来的平台驱动匹配使用!
 

 

3.Board i2c从设备注册

3.1 i2c从设备结构体

 
  1. struct i2c_board_info {

  2. char type[I2C_NAME_SIZE]; //设备类型名称

  3. unsigned short flags;

  4. unsigned short addr; //I2C从设备地址

  5. void *platform_data;

  6. struct dev_archdata *archdata;

  7. struct device_node *of_node;

  8. struct acpi_dev_node acpi_node;

  9. int irq;

  10. };

 
  1. #define I2C_BOARD_INFO(dev_type, dev_addr) \

  2. .type = dev_type, .addr = (dev_addr)

3.2 i2c从设备信息结构初始化

注册一个从设备为“24c512”,从设备地址为0x50:

 

 
  1. static struct i2c_board_info __initdata nuc970_i2c_clients0[] =

  2. {

  3. {I2C_BOARD_INFO("24c512", 0x50),},

  4. };

3.3 i2c从设备注册到链表

i2c_register_board_info(0, nuc970_i2c_clients0, sizeof(nuc970_i2c_clients0)/sizeof(struct i2c_board_info));
 
  1. i2c_register_board_info(int busnum,

  2. struct i2c_board_info const *info, unsigned len)

  3. {

  4. int status;

  5.  
  6. down_write(&__i2c_board_lock);

  7.  
  8. /* dynamic bus numbers will be assigned after the last static one */

  9. if (busnum >= __i2c_first_dynamic_bus_num)

  10. __i2c_first_dynamic_bus_num = busnum + 1;

  11.  
  12. for (status = 0; len; len--, info++) {

  13. struct i2c_devinfo *devinfo;

  14.  
  15. devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL);

  16. if (!devinfo) {

  17. pr_debug("i2c-core: can't register boardinfo!\n");

  18. status = -ENOMEM;

  19. break;

  20. }

  21.  
  22. devinfo->busnum = busnum;

  23. devinfo->board_info = *info;

  24. list_add_tail(&devinfo->list, &__i2c_board_list);

  25. }

  26.  
  27. up_write(&__i2c_board_lock);

  28.  
  29. return status;

  30. }

这里主要将I2C从设备信息注册到全局链表__i2c_board_list中
 

4.Platform_driver i2c 平台驱动注册

4.1 i2c设备驱动注册

 
  1. static struct platform_driver nuc970_i2c0_driver = {

  2. .probe = nuc970_i2c0_probe,

  3. .remove = nuc970_i2c0_remove,

  4. .driver = {

  5. .name = "nuc970-i2c0",

  6. .owner = THIS_MODULE,

  7. },

  8. };

  9. module_platform_driver(nuc970_i2c0_driver);

设备驱动和设备通过名称"nuc970-i2c0"匹配相等(具体可以参考之前写的一篇文章:点击打开链接),调用探测函数nuc970_i2c0_probe(...)进行驱动注册。

4.2 i2c probe(...)

 
  1. static int nuc970_i2c0_probe(struct platform_device *pdev)

  2. {

  3. struct nuc970_i2c *i2c;

  4. struct nuc970_platform_i2c *pdata;

  5. struct resource *res;

  6. int ret;

  7.  
  8. pdata = pdev->dev.platform_data; //这里为设备nuc970_i2c0_data[]结构体数据

  9. if (!pdata) {

  10. dev_err(&pdev->dev, "no platform data\n");

  11. return -EINVAL;

  12. }

  13.  
  14. i2c = kzalloc(sizeof(struct nuc970_i2c), GFP_KERNEL); //分配一个i2c控制器

  15. if (!i2c) {

  16. dev_err(&pdev->dev, "no memory for state\n");

  17. return -ENOMEM;

  18. }

  19.  
  20. //用这个更合理些:strlcpy(i2c->adap.name, pdev->dev.name, sizeof(i2c->adap.name));

  21. strlcpy(i2c->adap.name, "nuc970-i2c0", sizeof(i2c->adap.name)); //给i2c适配器命名

  22. i2c->adap.owner = THIS_MODULE;

  23. i2c->adap.algo = &nuc970_i2c0_algorithm; //i2c访问总线的方法,即读、写从设备操作

  24. i2c->adap.retries = 2; //尝试次数

  25. i2c->adap.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;

  26.  
  27. spin_lock_init(&i2c->lock);

  28. init_waitqueue_head(&i2c->wait); //初始化等待队列

  29.  
  30. /* find the clock and enable it */

  31.  
  32. i2c->dev = &pdev->dev;

  33. i2c->clk = clk_get(NULL, "i2c0");

  34. if (IS_ERR(i2c->clk)) {

  35. dev_err(&pdev->dev, "cannot get clock\n");

  36. ret = -ENOENT;

  37. goto err_noclk;

  38. }

  39.  
  40. dev_dbg(&pdev->dev, "clock source %p\n", i2c->clk);

  41.  
  42. clk_prepare(i2c->clk);

  43. clk_enable(i2c->clk);

  44.  
  45. /* map the registers */

  46.  
  47. res = platform_get_resource(pdev, IORESOURCE_MEM, 0); //获取IO寄存器资源

  48. if (res == NULL) {

  49. dev_err(&pdev->dev, "cannot find IO resource\n");

  50. ret = -ENOENT;

  51. goto err_clk;

  52. }

  53.  
  54. i2c->ioarea = request_mem_region(res->start, resource_size(res), //申请内存资源

  55. pdev->name);

  56.  
  57. if (i2c->ioarea == NULL) {

  58. dev_err(&pdev->dev, "cannot request IO\n");

  59. ret = -ENXIO;

  60. goto err_clk;

  61. }

  62.  
  63. i2c->regs = ioremap(res->start, resource_size(res)); //资源映射

  64.  
  65. if (i2c->regs == NULL) {

  66. dev_err(&pdev->dev, "cannot map IO\n");

  67. ret = -ENXIO;

  68. goto err_ioarea;

  69. }

  70.  
  71. dev_dbg(&pdev->dev, "registers %p (%p, %p)\n",

  72. i2c->regs, i2c->ioarea, res);

  73.  
  74. /* setup info block for the i2c core */

  75.  
  76. i2c->adap.algo_data = i2c; //适配器算法数据指针指向i2c控制器

  77. i2c->adap.dev.parent = &pdev->dev;

  78.  
  79. ret = clk_get_rate(i2c->clk)/(pdata->bus_freq * 5) - 1;

  80. writel(ret & 0xffff, i2c->regs + DIVIDER);

  81.  
  82. /* find the IRQ for this unit (note, this relies on the init call to

  83. * ensure no current IRQs pending

  84. */

  85.  
  86. i2c->irq = ret = platform_get_irq(pdev, 0);

  87. if (ret <= 0) {

  88. dev_err(&pdev->dev, "cannot find IRQ\n");

  89. goto err_iomap;

  90. }

  91.  
  92. ret = request_irq(i2c->irq, nuc970_i2c_irq, IRQF_SHARED, //申请i2c中断

  93. dev_name(&pdev->dev), i2c);

  94.  
  95. if (ret != 0) {

  96. dev_err(&pdev->dev, "cannot claim IRQ %d\n", i2c->irq);

  97. goto err_iomap;

  98. }

  99.  
  100. /* Note, previous versions of the driver used i2c_add_adapter()

  101. * to add the bus at any number. We now pass the bus number via

  102. * the platform data, so if unset it will now default to always

  103. * being bus 0.

  104. */

  105.  
  106. i2c->adap.nr = pdata->bus_num; //适配器所属i2c总线编号,这里为0

  107.  
  108. ret = i2c_add_numbered_adapter(&i2c->adap); //增加一个适配器

  109. if (ret < 0) {

  110. dev_err(&pdev->dev, "failed to add bus to i2c core\n");

  111. goto err_irq;

  112. }

  113.  
  114. platform_set_drvdata(pdev, i2c);

  115.  
  116. dev_info(&pdev->dev, "%s: nuc970 I2C adapter\n",

  117. dev_name(&i2c->adap.dev));

  118. return 0;

  119.  
  120. err_irq:

  121. free_irq(i2c->irq, i2c);

  122.  
  123. err_iomap:

  124. iounmap(i2c->regs);

  125.  
  126. err_ioarea:

  127. release_resource(i2c->ioarea);

  128. kfree(i2c->ioarea);

  129.  
  130. err_clk:

  131. clk_disable(i2c->clk);

  132. clk_put(i2c->clk);

  133.  
  134. err_noclk:

  135. kfree(i2c);

  136. return ret;

  137. }

i2c算法操作:

 
  1. static const struct i2c_algorithm nuc970_i2c0_algorithm = {

  2. .master_xfer = nuc970_i2c0_xfer,

  3. .functionality = nuc970_i2c0_func,

  4. };

 
  1. /* declare our i2c functionality */

  2. static u32 nuc970_i2c0_func(struct i2c_adapter *adap)

  3. {

  4. return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_NOSTART |

  5. I2C_FUNC_PROTOCOL_MANGLING;

  6. }

 
  1. static int nuc970_i2c0_xfer(struct i2c_adapter *adap,

  2. struct i2c_msg *msgs, int num)

  3. {

  4. struct nuc970_i2c *i2c = (struct nuc970_i2c *)adap->algo_data; //adap->algo_data指向i2c,见上代码

  5. int retry;

  6. int ret;

  7.  
  8. nuc970_i2c0_enable_irq(i2c); //使能中断

  9.  
  10. for (retry = 0; retry < adap->retries; retry++) { //尝试次数

  11.  
  12. ret = nuc970_i2c0_doxfer(i2c, msgs, num); //传输数据

  13.  
  14. if (ret != -EAGAIN)

  15. return ret;

  16.  
  17. dev_dbg(i2c->dev, "Retrying transmission (%d)\n", retry);

  18.  
  19. udelay(100);

  20. }

  21.  
  22. return -EREMOTEIO;

  23. }

 
  1. static int nuc970_i2c0_doxfer(struct nuc970_i2c *i2c,

  2. struct i2c_msg *msgs, int num)

  3. {

  4. unsigned long iicstat, timeout;

  5. int spins = 20;

  6. int ret;

  7.  
  8. ret = nuc970_i2c0_set_master(i2c);

  9. if (ret != 0) {

  10. dev_err(i2c->dev, "cannot get bus (error %d)\n", ret);

  11. ret = -EAGAIN;

  12. goto out;

  13. }

  14.  
  15. spin_lock_irq(&i2c->lock);

  16.  
  17. i2c->msg = msgs; //消息指针

  18. i2c->msg_num = num; //消息的个数

  19. i2c->msg_ptr = 0;

  20. i2c->msg_idx = 0;

  21. i2c->state = STATE_START; //I2C传输状态设置为启动

  22. nuc970_i2c0_message_start(i2c, msgs); //开始发送消息,当发送一个字节后将触发中断,本函数退出,进入下面的休眠zhuangta

  23. spin_unlock_irq(&i2c->lock);

  24.  
  25. //i2c->msg_num != 0 时wait_event_timeout(...)将等待HZ*5的超时时间

  26. timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);

  27.  
  28.  
  29. if(i2c->arblost) {

  30. printk("arb lost, stop\n");

  31. i2c->arblost = 0;

  32. nuc970_i2c0_stop(i2c, 0);

  33. }

  34.  
  35. ret = i2c->msg_idx;

  36.  
  37. /* having these next two as dev_err() makes life very

  38. * noisy when doing an i2cdetect

  39. */

  40.  
  41. if (timeout == 0)

  42. dev_dbg(i2c->dev, "timeout\n");

  43. else if (ret != num)

  44. dev_dbg(i2c->dev, "incomplete xfer (%d)\n", ret);

  45.  
  46. /* ensure the stop has been through the bus */

  47. dev_dbg(i2c->dev, "waiting for bus idle\n");

  48.  
  49. /* first, try busy waiting briefly */

  50. do {

  51. iicstat = readl(i2c->regs + CSR);

  52. } while ((iicstat & I2CBUSY) && --spins);

  53.  
  54. /* if that timed out sleep */

  55. if (!spins) {

  56. msleep(1);

  57. iicstat = readl(i2c->regs + CSR);

  58. }

  59.  
  60. if (iicstat & I2CBUSY)

  61. dev_warn(i2c->dev, "timeout waiting for bus idle\n");

  62.  
  63. out:

  64. return ret;

  65. }

这里发送一个字节从设备地址,然后进入中断,发送数据,关于中断部分待分析!!!

 
  1. static void nuc970_i2c0_message_start(struct nuc970_i2c *i2c,

  2. struct i2c_msg *msg)

  3. {

  4. unsigned int addr = (msg->addr & 0x7f) << 1; //从设备地址

  5.  
  6. if (msg->flags & I2C_M_RD) //是否是读数据

  7. addr |= 0x1;

  8. writel(addr & 0xff, i2c->regs + TXR); //传输地址

  9. writel(I2C_CMD_START | I2C_CMD_WRITE, i2c->regs + CMDR);

  10. }

4.3 i2c中断函数

申请一个中断:

 
  1. ret = request_irq(i2c->irq, nuc970_i2c_irq, IRQF_SHARED, //申请i2c中断

  2. dev_name(&pdev->dev), i2c);

中断回调函数:

 
  1. static irqreturn_t nuc970_i2c_irq(int irqno, void *dev_id)

  2. {

  3. struct nuc970_i2c *i2c = dev_id;

  4. unsigned long status;

  5.  
  6. status = readl(i2c->regs + CSR);

  7. writel(status | IRQFLAG, i2c->regs + CSR);

  8.  
  9. if (status & ARBIT_LOST) {

  10. /* deal with arbitration loss */

  11. dev_err(i2c->dev, "deal with arbitration loss\n");

  12. i2c->arblost = 1;

  13. goto out;

  14. }

  15.  
  16. if (i2c->state == STATE_IDLE) {

  17. dev_dbg(i2c->dev, "IRQ: error i2c->state == IDLE\n");

  18. goto out;

  19. }

  20.  
  21. /* pretty much this leaves us with the fact that we've

  22. * transmitted or received whatever byte we last sent

  23. */

  24.  
  25. i2c_nuc970_irq_nextbyte(i2c, status);

  26.  
  27. out:

  28. return IRQ_HANDLED;

  29. }

进入到字节传输,i2c采用状态机的形式进行消息发送、接收,这个函数很重要:

 
  1. static void i2c_nuc970_irq_nextbyte(struct nuc970_i2c *i2c, unsigned long iicstat)

  2. {

  3. unsigned char byte;

  4.  
  5. switch (i2c->state) {

  6.  
  7. case STATE_IDLE:

  8. dev_err(i2c->dev, "%s: called in STATE_IDLE\n", __func__);

  9. break;

  10.  
  11. case STATE_STOP:

  12. nuc970_i2c0_disable_irq(i2c);

  13. break;

  14.  
  15. case STATE_START:

  16. /* last thing we did was send a start condition on the

  17. * bus, or started a new i2c message

  18. */

  19.  
  20. if (iicstat & SLAVE_ACK &&

  21. !(i2c->msg->flags & I2C_M_IGNORE_NAK)) {

  22. /* ack was not received... */

  23.  
  24. dev_dbg(i2c->dev, "ack was not received\n");

  25. nuc970_i2c0_stop(i2c, -ENXIO);

  26. break;

  27. }

  28.  
  29. if (i2c->msg->flags & I2C_M_RD)

  30. i2c->state = STATE_READ;

  31. else

  32. i2c->state = STATE_WRITE;

  33.  
  34. /* terminate the transfer if there is nothing to do

  35. * as this is used by the i2c probe to find devices.

  36. */

  37.  
  38. if (is_lastmsg(i2c) && i2c->msg->len == 0) {

  39. nuc970_i2c0_stop(i2c, 0);

  40. break;

  41. }

  42.  
  43. if (i2c->state == STATE_READ)

  44. goto prepare_read;

  45.  
  46. /* fall through to the write state, as we will need to

  47. * send a byte as well

  48. */

  49.  
  50. case STATE_WRITE:

  51. /* we are writing data to the device... check for the

  52. * end of the message, and if so, work out what to do

  53. */

  54.  
  55. if (!(i2c->msg->flags & I2C_M_IGNORE_NAK)) {

  56. if (iicstat & SLAVE_ACK) {

  57. dev_dbg(i2c->dev, "WRITE: No Ack\n");

  58.  
  59. nuc970_i2c0_stop(i2c, -ECONNREFUSED);

  60. break;

  61. }

  62. }

  63.  
  64. retry_write:

  65.  
  66. if (!is_msgend(i2c)) {

  67. byte = i2c->msg->buf[i2c->msg_ptr++];

  68. writeb(byte, i2c->regs + TXR);

  69. writel(I2C_CMD_WRITE, i2c->regs + CMDR);

  70.  
  71. } else if (!is_lastmsg(i2c)) { //是否是最后的msg消息,个数由i2c->msg_num决定

  72. /* we need to go to the next i2c message */

  73.  
  74. dev_dbg(i2c->dev, "WRITE: Next Message\n");

  75.  
  76. i2c->msg_ptr = 0; //msg消息清零

  77. i2c->msg_idx++; //msg消息个数索引

  78. i2c->msg++; //切换到下一个待发送的消息

  79.  
  80. /* check to see if we need to do another message */

  81. if (i2c->msg->flags & I2C_M_NOSTART) {

  82.  
  83. if (i2c->msg->flags & I2C_M_RD) {

  84. /* cannot do this, the controller

  85. * forces us to send a new START

  86. * when we change direction

  87. */

  88.  
  89. nuc970_i2c0_stop(i2c, -EINVAL);

  90. }

  91.  
  92. goto retry_write;

  93. } else {

  94. /* send the new start */

  95. nuc970_i2c0_message_start(i2c, i2c->msg); //发送消息

  96. i2c->state = STATE_START;

  97. }

  98.  
  99. } else {

  100. /* send stop */

  101.  
  102. nuc970_i2c0_stop(i2c, 0);

  103. }

  104. break;

  105.  
  106. case STATE_READ:

  107. /* we have a byte of data in the data register, do

  108. * something with it, and then work out whether we are

  109. * going to do any more read/write

  110. */

  111.  
  112. byte = readb(i2c->regs + RXR);

  113. i2c->msg->buf[i2c->msg_ptr++] = byte;

  114.  
  115. prepare_read:

  116. if (is_msglast(i2c)) { //是否是消息的最后一个字节

  117. /* last byte of buffer */

  118.  
  119. if (is_lastmsg(i2c)) //是否是最后的消息

  120. writel(I2C_CMD_READ | I2C_CMD_NACK,

  121. i2c->regs + CMDR);

  122.  
  123. } else if (is_msgend(i2c)) { //消息是否发送完

  124. /* ok, we've read the entire buffer, see if there

  125. * is anything else we need to do

  126. */

  127.  
  128. if (is_lastmsg(i2c)) { //是否是最后的消息

  129. /* last message, send stop and complete */

  130. dev_dbg(i2c->dev, "READ: Send Stop\n");

  131.  
  132. nuc970_i2c0_stop(i2c, 0);

  133. } else {

  134. /* go to the next transfer */

  135. dev_dbg(i2c->dev, "READ: Next Transfer\n");

  136.  
  137. i2c->msg_ptr = 0;

  138. i2c->msg_idx++;

  139. i2c->msg++;

  140.  
  141. writel(I2C_CMD_READ, i2c->regs + CMDR);

  142. }

  143.  
  144. } else {

  145. writel(I2C_CMD_READ, i2c->regs + CMDR);

  146. }

  147.  
  148. break;

  149. }

  150. }

4.4 向I2C核心增加适配器

ret = i2c_add_numbered_adapter(&i2c->adap); //增加一个适配器
 
  1. int i2c_add_numbered_adapter(struct i2c_adapter *adap)

  2. {

  3. if (adap->nr == -1) /* -1 means dynamically assign bus id */

  4. return i2c_add_adapter(adap);

  5.  
  6. return __i2c_add_numbered_adapter(adap);

  7. }

 
  1. static int __i2c_add_numbered_adapter(struct i2c_adapter *adap)

  2. {

  3. int id;

  4.  
  5. mutex_lock(&core_lock);

  6. id = idr_alloc(&i2c_adapter_idr, adap, adap->nr, adap->nr + 1,

  7. GFP_KERNEL);

  8. mutex_unlock(&core_lock);

  9. if (id < 0)

  10. return id == -ENOSPC ? -EBUSY : id;

  11.  
  12. return i2c_register_adapter(adap);

  13. }

idr_alloc(...)可以参考这位大神写的博客:点击打开链接,目的就是给这里的i2c适配器分配一个id号

 
  1. static int i2c_register_adapter(struct i2c_adapter *adap)

  2. {

  3. int res = 0;

  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. /* Sanity checks */

  12. if (unlikely(adap->name[0] == '\0')) {

  13. pr_err("i2c-core: Attempt to register an adapter with "

  14. "no name!\n");

  15. return -EINVAL;

  16. }

  17. if (unlikely(!adap->algo)) {

  18. pr_err("i2c-core: Attempt to register adapter '%s' with "

  19. "no algo!\n", adap->name);

  20. return -EINVAL;

  21. }

  22.  
  23. rt_mutex_init(&adap->bus_lock);

  24. mutex_init(&adap->userspace_clients_lock);

  25. INIT_LIST_HEAD(&adap->userspace_clients);

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

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

  29. adap->timeout = HZ;

  30.  
  31. dev_set_name(&adap->dev, "i2c-%d", adap->nr); //设置适配器的名称为“i2c-0”

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

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

  34. res = device_register(&adap->dev); //设备注册,下面重点讲解,不然不能够理解本章的核心思想!!!

  35. if (res)

  36. goto out_list;

  37.  
  38. dev_dbg(&adap->dev, "adapter [%s] registered\n", adap->name);

  39.  
  40. #ifdef CONFIG_I2C_COMPAT

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

  42. adap->dev.parent);

  43. if (res)

  44. dev_warn(&adap->dev,

  45. "Failed to create compatibility class link\n");

  46. #endif

  47.  
  48. /* bus recovery specific initialization */

  49. if (adap->bus_recovery_info) {

  50. struct i2c_bus_recovery_info *bri = adap->bus_recovery_info;

  51.  
  52. if (!bri->recover_bus) {

  53. dev_err(&adap->dev, "No recover_bus() found, not using recovery\n");

  54. adap->bus_recovery_info = NULL;

  55. goto exit_recovery;

  56. }

  57.  
  58. /* Generic GPIO recovery */

  59. if (bri->recover_bus == i2c_generic_gpio_recovery) {

  60. if (!gpio_is_valid(bri->scl_gpio)) {

  61. dev_err(&adap->dev, "Invalid SCL gpio, not using recovery\n");

  62. adap->bus_recovery_info = NULL;

  63. goto exit_recovery;

  64. }

  65.  
  66. if (gpio_is_valid(bri->sda_gpio))

  67. bri->get_sda = get_sda_gpio_value;

  68. else

  69. bri->get_sda = NULL;

  70.  
  71. bri->get_scl = get_scl_gpio_value;

  72. bri->set_scl = set_scl_gpio_value;

  73. } else if (!bri->set_scl || !bri->get_scl) {

  74. /* Generic SCL recovery */

  75. dev_err(&adap->dev, "No {get|set}_gpio() found, not using recovery\n");

  76. adap->bus_recovery_info = NULL;

  77. }

  78. }

  79.  
  80. exit_recovery:

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

  82. if (adap->nr < __i2c_first_dynamic_bus_num) //

  83. i2c_scan_static_board_info(adap);

  84.  
  85. /* Notify drivers */

  86. mutex_lock(&core_lock);

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

  88. mutex_unlock(&core_lock);

  89.  
  90. return 0;

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

设备注册流程如下:

a.  设备注册:device_register(&adap->dev)

 
  1. int device_register(struct device *dev)

  2. {

  3. device_initialize(dev);

  4. return device_add(dev);

  5. }

device_initialize(...)设备初始化,包括设备集合、设备对象,即在/sys/系统下的目录及文件

 

b. 设备增加:device_add(...)

c. 设备添加到总线:bus_add_device(...)

 
  1. int bus_add_device(struct device *dev)

  2. {

  3. struct bus_type *bus = bus_get(dev->bus);

  4. int error = 0;

  5.  
  6. if (bus) {

  7. pr_debug("bus: '%s': add device %s\n", bus->name, dev_name(dev));

  8. error = device_add_attrs(bus, dev);

  9. if (error)

  10. goto out_put;

  11. error = sysfs_create_link(&bus->p->devices_kset->kobj,

  12. &dev->kobj, dev_name(dev));

  13. if (error)

  14. goto out_id;

  15. error = sysfs_create_link(&dev->kobj,

  16. &dev->bus->p->subsys.kobj, "subsystem");

  17. if (error)

  18. goto out_subsys;

  19. //将本次设备的的链表dev->p->knode_bus添加到bus->p->klist_devices链表中,

  20. //这里很重要,设备驱动在注册的时候就是通过该链表与对应的设备进行匹配

  21. klist_add_tail(&dev->p->knode_bus, &bus->p->klist_devices);

  22. }

  23. return 0;

  24.  
  25. out_subsys:

  26. sysfs_remove_link(&bus->p->devices_kset->kobj, dev_name(dev));

  27. out_id:

  28. device_remove_attrs(bus, dev);

  29. out_put:

  30. bus_put(dev->bus);

  31. return error;

  32. }

这里将设备dev添加到i2c Bus总线的内核链表中bus->p->klist_devices,必须理解,下面在注册at24c512设备时会通过该链表进行匹配!!!

__i2c_first_dynamic_bus_num变量由上面i2c_register_board_info(...)函数注册时赋值,这里__i2c_first_dynamic_bus_num=1,adap->nr=0,条件成立,接下来扫描i2c的board_info信息板级文件信息:

 
  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. /*

  7. 检索在arch/arm/mach-nuc970/dev.c 中i2c_register_board_info() 注册的板级文件,

  8. 比对本次传入参数adapter适配器的I2C总线编号是否一致,一根总

  9. 线下可以挂接很多设备,当总线号相等时,这里会注册多个板

  10. 级文件中的设备.

  11. */

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

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

  14. && !i2c_new_device(adapter,

  15. &devinfo->board_info))

  16. dev_err(&adapter->dev,

  17. "Can't create device at 0x%02x\n",

  18. devinfo->board_info.addr);

  19. //printk("###kernel: i2c_scan_static_board_info(): devinfo->busnum=%d, adapter->nr=%d, devinfo->board_info.type=%s.\n", \

  20. // devinfo->busnum, adapter->nr, devinfo->board_info.type);

  21. }

  22. up_read(&__i2c_board_lock);

  23. }

 

通过全局链表__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. client = kzalloc(sizeof *client, GFP_KERNEL);

  8. if (!client)

  9. return NULL;

  10.  
  11. client->adapter = adap;

  12.  
  13. client->dev.platform_data = info->platform_data;

  14.  
  15. if (info->archdata)

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

  17.  
  18. client->flags = info->flags;

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

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

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

  23.  
  24. /* Check for address validity */

  25. status = i2c_check_client_addr_validity(client); //校验当前从设备地址是否有效

  26. if (status) {

  27. dev_err(&adap->dev, "Invalid %d-bit I2C address 0x%02hx\n",

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

  29. goto out_err_silent;

  30. }

  31.  
  32. /* Check for address business */

  33. status = i2c_check_addr_busy(adap, client->addr); //校验当前从设备地址是否已经注册

  34. if (status)

  35. goto out_err;

  36.  
  37. client->dev.parent = &client->adapter->dev;

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

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

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

  41. ACPI_HANDLE_SET(&client->dev, info->acpi_node.handle);

  42.  
  43. /* For 10-bit clients, add an arbitrary offset to avoid collisions */

  44. dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap),

  45. client->addr | ((client->flags & I2C_CLIENT_TEN)

  46. ? 0xa000 : 0));

  47. status = device_register(&client->dev); //将当前的客户端设备注册到设备树中

  48. if (status)

  49. goto out_err;

  50.  
  51. dev_dbg(&adap->dev, "client [%s] registered with bus id %s\n",

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

  53.  
  54. return client;

  55.  
  56. out_err:

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

  58. "(%d)\n", client->name, client->addr, status);

  59. out_err_silent:

  60. kfree(client);

  61. return NULL;

  62. }

i2c_new_device(...)的目的是通过“适配器参数+板级文件信息=创建一个I2C从设备客户端”,成功就返回该信息:


在回到i2c_register_adapter(...)

 
  1. /* Notify drivers */

  2. mutex_lock(&core_lock);

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

  4. mutex_unlock(&core_lock);

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. .pm = &i2c_device_pm_ops,

  8. };

5.at24c512设备驱动注册

5.1 at24c512驱动注册

at24系列产品型号,包括产品名称、存储空间、地址bit位数:

 
  1. static const struct i2c_device_id at24_ids[] = {

  2. /* needs 8 addresses as A0-A2 are ignored */

  3. { "24c00", AT24_DEVICE_MAGIC(128 / 8, AT24_FLAG_TAKE8ADDR) },

  4. /* old variants can't be handled with this generic entry! */

  5. { "24c01", AT24_DEVICE_MAGIC(1024 / 8, 0) },

  6. { "24c02", AT24_DEVICE_MAGIC(2048 / 8, 0) },

  7. /* spd is a 24c02 in memory DIMMs */

  8. { "spd", AT24_DEVICE_MAGIC(2048 / 8,

  9. AT24_FLAG_READONLY | AT24_FLAG_IRUGO) },

  10. { "24c04", AT24_DEVICE_MAGIC(4096 / 8, 0) },

  11. /* 24rf08 quirk is handled at i2c-core */

  12. { "24c08", AT24_DEVICE_MAGIC(8192 / 8, 0) },

  13. { "24c16", AT24_DEVICE_MAGIC(16384 / 8, 0) },

  14. { "24c32", AT24_DEVICE_MAGIC(32768 / 8, AT24_FLAG_ADDR16) },

  15. { "24c64", AT24_DEVICE_MAGIC(65536 / 8, AT24_FLAG_ADDR16) },

  16. { "24c128", AT24_DEVICE_MAGIC(131072 / 8, AT24_FLAG_ADDR16) },

  17. { "24c256", AT24_DEVICE_MAGIC(262144 / 8, AT24_FLAG_ADDR16) },

  18. { "24c512", AT24_DEVICE_MAGIC(524288 / 8, AT24_FLAG_ADDR16) },

  19. { "24c1024", AT24_DEVICE_MAGIC(1048576 / 8, AT24_FLAG_ADDR16) },

  20. { "at24", 0 },

  21. { /* END OF LIST */ }

  22. };

at24_driver驱动:

 
  1. static struct i2c_driver at24_driver = {

  2. .driver = {

  3. .name = "at24",

  4. .owner = THIS_MODULE,

  5. },

  6. .probe = at24_probe,

  7. .remove = at24_remove,

  8. .id_table = at24_ids,

  9. };

 
  1. static int __init at24_init(void)

  2. {

  3. if (!io_limit) {

  4. pr_err("at24: io_limit must not be 0!\n");

  5. return -EINVAL;

  6. }

  7.  
  8. io_limit = rounddown_pow_of_two(io_limit);

  9. return i2c_add_driver(&at24_driver);

  10. }

  11. module_init(at24_init);

 
  1. #define __define_initcall(level,fn) \

  2. static initcall_t __initcall_##fn __used \

  3. __attribute__((__section__(".initcall" level ".init"))) = fn

  4.  
  5. #define device_initcall(fn) __define_initcall(fn, 6)

  6.  
  7. #define __initcall(fn) device_initcall(fn)

  8.  
  9. #define module_init(x) __initcall(x);

module_init(...)宏路径:linux-3.10.x-20171019\include\linux\init.h

 

 
  1. #define i2c_add_driver(driver) \

  2. i2c_register_driver(THIS_MODULE, driver)

向i2c核心注册驱动i2c_register_driver(...)

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

  2. {

  3. int res;

  4.  
  5. /* Can't register until after driver model init */

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

  7. return -EAGAIN;

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

  10. driver->driver.owner = owner;

  11. driver->driver.bus = &i2c_bus_type; //绑定驱动的总线为i2c_bus_type

  12.  
  13. /* When registration returns, the driver core

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

  15. */

  16. res = driver_register(&driver->driver); //驱动注册

  17. if (res)

  18. return res;

  19.  
  20. /* Drivers should switch to dev_pm_ops instead. */

  21. if (driver->suspend)

  22. pr_warn("i2c-core: driver [%s] using legacy suspend method\n",

  23. driver->driver.name);

  24. if (driver->resume)

  25. pr_warn("i2c-core: driver [%s] using legacy resume method\n",

  26. driver->driver.name);

  27.  
  28. pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name);

  29.  
  30. INIT_LIST_HEAD(&driver->clients);

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

  32. i2c_for_each_dev(driver, __process_new_driver); //遍历i2c_bus_type结构体的链表,判定当前设备是否有匹配的,详见下面

  33.  
  34. return 0;

  35. }

i2c_for_each_dev(....)函数:

 

 
  1. int i2c_for_each_dev(void *data, int (*fn)(struct device *, void *))

  2. {

  3. int res;

  4.  
  5. mutex_lock(&core_lock);

  6. res = bus_for_each_dev(&i2c_bus_type, NULL, data, fn);

  7. mutex_unlock(&core_lock);

  8.  
  9. return res;

  10. }

 
  1. int bus_for_each_dev(struct bus_type *bus, struct device *start,

  2. void *data, int (*fn)(struct device *, void *))

  3. {

  4. struct klist_iter i;

  5. struct device *dev;

  6. int error = 0;

  7.  
  8. if (!bus || !bus->p)

  9. return -EINVAL;

  10.  
  11. klist_iter_init_node(&bus->p->klist_devices, &i,//设备通过bus_add_device(...)添加时,最终会将设备加入到bus->p->klist_devices设备链表中

  12. (start ? &start->p->knode_bus : NULL));

  13. while ((dev = next_device(&i)) && !error)

  14. error = fn(dev, data);

  15. klist_iter_exit(&i);

  16. return error;

  17. }

在bus_for_each_dev(...)函数中,可以看到遍历bus->p->klist_devices链表,而该链表在前面提到过,就是设备加入到的链表,这里通过获取链表的设备(i2c_bus_type)与data(本次注册的at24c512设备),通过fn(...)函数指针__process_new_driver(...)进行调用,具体如下:

 

该函数的第二个参数如下:

 

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

  2. {

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

  4. return 0;

  5. return i2c_do_add_adapter(data, to_i2c_adapter(dev));

  6. }

 
  1. static int i2c_do_add_adapter(struct i2c_driver *driver,

  2. struct i2c_adapter *adap)

  3. {

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

  5. i2c_detect(adap, driver);

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

  8. if (driver->attach_adapter) {

  9. dev_warn(&adap->dev, "%s: attach_adapter method is deprecated\n",

  10. driver->driver.name);

  11. dev_warn(&adap->dev, "Please use another way to instantiate "

  12. "your i2c_client\n");

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

  14. driver->attach_adapter(adap);

  15. }

  16. return 0;

  17. }

i2c探测:

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

  2. {

  3. const unsigned short *address_list;

  4. struct i2c_client *temp_client;

  5. int i, err = 0;

  6. int adap_id = i2c_adapter_id(adapter);

  7.  
  8. address_list = driver->address_list;

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

  10. return 0;

  11.  
  12. /* Stop here if the classes do not match */

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

  14. return 0;

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

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

  18. if (!temp_client)

  19. return -ENOMEM;

  20. temp_client->adapter = adapter;

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

  23. dev_dbg(&adapter->dev, "found normal entry for adapter %d, "

  24. "addr 0x%02x\n", adap_id, address_list[i]);

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

  26. err = i2c_detect_address(temp_client, driver); //探测地址是否在i2c总线上

  27. if (unlikely(err))

  28. break;

  29. }

  30.  
  31. kfree(temp_client);

  32. return err;

  33. }

 
  1. static int i2c_detect_address(struct i2c_client *temp_client,

  2. struct i2c_driver *driver)

  3. {

  4. struct i2c_board_info info;

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

  6. int addr = temp_client->addr;

  7. int err;

  8.  
  9. /* Make sure the address is valid */

  10. err = i2c_check_addr_validity(addr);

  11. if (err) {

  12. dev_warn(&adapter->dev, "Invalid probe address 0x%02x\n",

  13. addr);

  14. return err;

  15. }

  16.  
  17. /* Skip if already in use */

  18. if (i2c_check_addr_busy(adapter, addr))

  19. return 0;

  20.  
  21. /* Make sure there is something at this address */

  22. if (!i2c_default_probe(adapter, addr)) //地址匹配,见下面分析!!!

  23. return 0;

  24.  
  25. /* Finally call the custom detection function */

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

  27. info.addr = addr;

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

  29. if (err) {

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

  31. here as this isn't an error. */

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

  33. }

  34.  
  35. /* Consistency check */

  36. if (info.type[0] == '\0') {

  37. dev_err(&adapter->dev, "%s detection function provided "

  38. "no name for 0x%x\n", driver->driver.name,

  39. addr);

  40. } else {

  41. struct i2c_client *client;

  42.  
  43. /* Detection succeeded, instantiate the device */

  44. dev_dbg(&adapter->dev, "Creating %s at 0x%02x\n",

  45. info.type, info.addr);

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

  47. if (client)

  48. list_add_tail(&client->detected, &driver->clients);

  49. else

  50. dev_err(&adapter->dev, "Failed creating %s at 0x%02x\n",

  51. info.type, info.addr);

  52. }

  53. return 0;

  54. }

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

  2. {

  3. int err;

  4. union i2c_smbus_data dummy;

  5.  
  6. #ifdef CONFIG_X86

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

  8. && i2c_check_functionality(adap, I2C_FUNC_SMBUS_READ_BYTE_DATA))

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

  10. I2C_SMBUS_BYTE_DATA, &dummy);

  11. else

  12. #endif

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

  14. && i2c_check_functionality(adap, I2C_FUNC_SMBUS_QUICK)) //校验SMBUS是否是快速的

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

  16. I2C_SMBUS_QUICK, NULL);

  17. else if (i2c_check_functionality(adap, I2C_FUNC_SMBUS_READ_BYTE)) //校验SMBUS是否支持读

  18. err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_READ, 0, //

  19. I2C_SMBUS_BYTE, &dummy);

  20. else {

  21. dev_warn(&adap->dev, "No suitable probing method supported\n");

  22. err = -EOPNOTSUPP;

  23. }

  24.  
  25. return err >= 0;

  26. }

其中i2c_check_functionality(...)函数用来校验i2c的功能,最红调用adap->algo->functionality(...)函数指针,该函数是上面nuc970_i2c0_algorithm结构体定义的:

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

  2. {

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

  4. }

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

  2. {

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

  4. }

这里重点分析i2c_smbus_xfer(...):

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

  2. char read_write, u8 command, int protocol,

  3. union i2c_smbus_data *data)

  4. {

  5. unsigned long orig_jiffies;

  6. int try;

  7. s32 res;

  8.  
  9. flags &= I2C_M_TEN | I2C_CLIENT_PEC | I2C_CLIENT_SCCB;

  10.  
  11. if (adapter->algo->smbus_xfer) { //判断适配器是否支持 smbus_xfer,通过前面的介绍,这里是不支持的!

  12. i2c_lock_adapter(adapter);

  13.  
  14. /* Retry automatically on arbitration loss */

  15. orig_jiffies = jiffies;

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

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

  18. read_write, command,

  19. protocol, data);

  20. if (res != -EAGAIN)

  21. break;

  22. if (time_after(jiffies,

  23. orig_jiffies + adapter->timeout))

  24. break;

  25. }

  26. i2c_unlock_adapter(adapter);

  27.  
  28. if (res != -EOPNOTSUPP || !adapter->algo->master_xfer)

  29. return res;

  30. /*

  31. * Fall back to i2c_smbus_xfer_emulated if the adapter doesn't

  32. * implement native support for the SMBus operation.

  33. */

  34. }

  35.  
  36. return i2c_smbus_xfer_emulated(adapter, addr, flags, read_write,

  37. command, protocol, data);

  38. }

由于adapter->algo->smbus_xfer条件不成立,所以这里会调用i2c_smbus_xfer_emulated(...):

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

  2. unsigned short flags,

  3. char read_write, u8 command, int size,

  4. union i2c_smbus_data *data)

  5. {

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

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

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

  9. simpler. */

  10. unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX+3];

  11. unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX+2];

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

  13. int i;

  14. u8 partial_pec = 0;

  15. int status;

  16. struct i2c_msg msg[2] = {

  17. {

  18. .addr = addr,

  19. .flags = flags,

  20. .len = 1,

  21. .buf = msgbuf0,

  22. }, {

  23. .addr = addr,

  24. .flags = flags | I2C_M_RD,

  25. .len = 0,

  26. .buf = msgbuf1,

  27. },

  28. };

  29.  
  30. msgbuf0[0] = command;

  31. switch (size) {

  32. case I2C_SMBUS_QUICK:

  33. msg[0].len = 0;

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

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

  36. I2C_M_RD : 0);

  37. num = 1;

  38. break;

  39. case I2C_SMBUS_BYTE:

  40. if (read_write == I2C_SMBUS_READ) {

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

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

  43. num = 1;

  44. }

  45. break;

  46. case I2C_SMBUS_BYTE_DATA:

  47. if (read_write == I2C_SMBUS_READ)

  48. msg[1].len = 1;

  49. else {

  50. msg[0].len = 2;

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

  52. }

  53. break;

  54. case I2C_SMBUS_WORD_DATA:

  55. if (read_write == I2C_SMBUS_READ)

  56. msg[1].len = 2;

  57. else {

  58. msg[0].len = 3;

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

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

  61. }

  62. break;

  63. case I2C_SMBUS_PROC_CALL:

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

  65. read_write = I2C_SMBUS_READ;

  66. msg[0].len = 3;

  67. msg[1].len = 2;

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

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

  70. break;

  71. case I2C_SMBUS_BLOCK_DATA:

  72. if (read_write == I2C_SMBUS_READ) {

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

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

  75. the underlying bus driver */

  76. } else {

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

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

  79. dev_err(&adapter->dev,

  80. "Invalid block write size %d\n",

  81. data->block[0]);

  82. return -EINVAL;

  83. }

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

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

  86. }

  87. break;

  88. case I2C_SMBUS_BLOCK_PROC_CALL:

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

  90. read_write = I2C_SMBUS_READ;

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

  92. dev_err(&adapter->dev,

  93. "Invalid block write size %d\n",

  94. data->block[0]);

  95. return -EINVAL;

  96. }

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

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

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

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

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

  102. the underlying bus driver */

  103. break;

  104. case I2C_SMBUS_I2C_BLOCK_DATA:

  105. if (read_write == I2C_SMBUS_READ) {

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

  107. } else {

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

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

  110. dev_err(&adapter->dev,

  111. "Invalid block write size %d\n",

  112. data->block[0]);

  113. return -EINVAL;

  114. }

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

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

  117. }

  118. break;

  119. default:

  120. dev_err(&adapter->dev, "Unsupported transaction %d\n", size);

  121. return -EOPNOTSUPP;

  122. }

  123.  
  124. i = ((flags & I2C_CLIENT_PEC) && size != I2C_SMBUS_QUICK

  125. && size != I2C_SMBUS_I2C_BLOCK_DATA);

  126. if (i) {

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

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

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

  130. i2c_smbus_add_pec(&msg[0]);

  131. else /* Write followed by read */

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

  133. }

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

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

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

  137. }

  138.  
  139. status = i2c_transfer(adapter, msg, num);

  140. if (status < 0)

  141. return status;

  142.  
  143. /* Check PEC if last message is a read */

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

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

  146. if (status < 0)

  147. return status;

  148. }

  149.  
  150. if (read_write == I2C_SMBUS_READ)

  151. switch (size) {

  152. case I2C_SMBUS_BYTE:

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

  154. break;

  155. case I2C_SMBUS_BYTE_DATA:

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

  157. break;

  158. case I2C_SMBUS_WORD_DATA:

  159. case I2C_SMBUS_PROC_CALL:

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

  161. break;

  162. case I2C_SMBUS_I2C_BLOCK_DATA:

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

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

  165. break;

  166. case I2C_SMBUS_BLOCK_DATA:

  167. case I2C_SMBUS_BLOCK_PROC_CALL:

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

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

  170. break;

  171. }

  172. return 0;

  173. }

i2c i2c_transfer(...)传输函数:

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

  2. {

  3. int ret;

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

  6. *

  7. * - When we get an error after receiving N bytes from a slave,

  8. * there is no way to report "N".

  9. *

  10. * - When we get a NAK after transmitting N bytes to a slave,

  11. * there is no way to report "N" ... or to let the master

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

  13. * that's the appropriate response.

  14. *

  15. * - When for example "num" is two and we successfully complete

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

  17. * second, it's unclear whether that should be reported as

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

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

  20. */

  21.  
  22. if (adap->algo->master_xfer) { //通过前面分析,该条件成立

  23. #ifdef DEBUG

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

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

  26. "len=%d%s\n", ret, (msgs[ret].flags & I2C_M_RD)

  27. ? 'R' : 'W', msgs[ret].addr, msgs[ret].len,

  28. (msgs[ret].flags & I2C_M_RECV_LEN) ? "+" : "");

  29. }

  30. #endif

  31.  
  32. if (in_atomic() || irqs_disabled()) {

  33. ret = i2c_trylock_adapter(adap);

  34. if (!ret)

  35. /* I2C activity is ongoing. */

  36. return -EAGAIN;

  37. } else {

  38. i2c_lock_adapter(adap);

  39. }

  40.  
  41. ret = __i2c_transfer(adap, msgs, num);

  42. i2c_unlock_adapter(adap);

  43.  
  44. return ret;

  45. } else {

  46. dev_dbg(&adap->dev, "I2C level transfers not supported\n");

  47. return -EOPNOTSUPP;

  48. }

  49. }

 
  1. int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)

  2. {

  3. unsigned long orig_jiffies;

  4. int ret, try;

  5.  
  6. /* Retry automatically on arbitration loss */

  7. orig_jiffies = jiffies;

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

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

  10. if (ret != -EAGAIN)

  11. break;

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

  13. break;

  14. }

  15.  
  16. return ret;

  17. }

到这里看到adap->algo->master_xfer(adap, msgs, num)函数指针为适配器结构体nuc970_i2c0_algorithm中成员nuc970_i2c0_xfer,关于该函数内部的实现细节,见前面的分析,至此就分析完了i2c 设备“at24c512”的注册、数据传输!

 

 

6.at24_probe(...)

 
  1. static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)

  2. {

  3. struct at24_platform_data chip;

  4. bool writable;

  5. int use_smbus = 0;

  6. struct at24_data *at24;

  7. int err;

  8. unsigned i, num_addresses;

  9. kernel_ulong_t magic;

  10.  
  11. if (client->dev.platform_data) {

  12. chip = *(struct at24_platform_data *)client->dev.platform_data;

  13. } else {

  14. if (!id->driver_data) {

  15. err = -ENODEV;

  16. goto err_out;

  17. }

  18. magic = id->driver_data;

  19. chip.byte_len = BIT(magic & AT24_BITMASK(AT24_SIZE_BYTELEN));

  20. magic >>= AT24_SIZE_BYTELEN;

  21. chip.flags = magic & AT24_BITMASK(AT24_SIZE_FLAGS);

  22. /*

  23. * This is slow, but we can't know all eeproms, so we better

  24. * play safe. Specifying custom eeprom-types via platform_data

  25. * is recommended anyhow.

  26. */

  27. chip.page_size = 1;

  28.  
  29. /* update chipdata if OF is present */

  30. at24_get_ofdata(client, &chip);

  31.  
  32. chip.setup = NULL;

  33. chip.context = NULL;

  34. }

  35.  
  36. if (!is_power_of_2(chip.byte_len))

  37. dev_warn(&client->dev,

  38. "byte_len looks suspicious (no power of 2)!\n");

  39. if (!chip.page_size) {

  40. dev_err(&client->dev, "page_size must not be 0!\n");

  41. err = -EINVAL;

  42. goto err_out;

  43. }

  44. if (!is_power_of_2(chip.page_size))

  45. dev_warn(&client->dev,

  46. "page_size looks suspicious (no power of 2)!\n");

  47.  
  48. /* Use I2C operations unless we're stuck with SMBus extensions. */

  49. if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {

  50. if (chip.flags & AT24_FLAG_ADDR16) {

  51. err = -EPFNOSUPPORT;

  52. goto err_out;

  53. }

  54. if (i2c_check_functionality(client->adapter,

  55. I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {

  56. use_smbus = I2C_SMBUS_I2C_BLOCK_DATA;

  57. } else if (i2c_check_functionality(client->adapter,

  58. I2C_FUNC_SMBUS_READ_WORD_DATA)) {

  59. use_smbus = I2C_SMBUS_WORD_DATA;

  60. } else if (i2c_check_functionality(client->adapter,

  61. I2C_FUNC_SMBUS_READ_BYTE_DATA)) {

  62. use_smbus = I2C_SMBUS_BYTE_DATA;

  63. } else {

  64. err = -EPFNOSUPPORT;

  65. goto err_out;

  66. }

  67. }

  68.  
  69. if (chip.flags & AT24_FLAG_TAKE8ADDR)

  70. num_addresses = 8;

  71. else

  72. num_addresses = DIV_ROUND_UP(chip.byte_len,

  73. (chip.flags & AT24_FLAG_ADDR16) ? 65536 : 256);

  74.  
  75. at24 = kzalloc(sizeof(struct at24_data) +

  76. num_addresses * sizeof(struct i2c_client *), GFP_KERNEL);

  77. if (!at24) {

  78. err = -ENOMEM;

  79. goto err_out;

  80. }

  81.  
  82. mutex_init(&at24->lock);

  83. at24->use_smbus = use_smbus;

  84. at24->chip = chip;

  85. at24->num_addresses = num_addresses;

  86.  
  87. /*

  88. * Export the EEPROM bytes through sysfs, since that's convenient.

  89. * By default, only root should see the data (maybe passwords etc)

  90. */

  91. sysfs_bin_attr_init(&at24->bin);

  92. at24->bin.attr.name = "eeprom";

  93. at24->bin.attr.mode = chip.flags & AT24_FLAG_IRUGO ? S_IRUGO : S_IRUSR;

  94. at24->bin.read = at24_bin_read;

  95. at24->bin.size = chip.byte_len;

  96.  
  97. at24->macc.read = at24_macc_read;

  98.  
  99. writable = !(chip.flags & AT24_FLAG_READONLY);

  100. if (writable) {

  101. if (!use_smbus || i2c_check_functionality(client->adapter,

  102. I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) {

  103.  
  104. unsigned write_max = chip.page_size;

  105.  
  106. at24->macc.write = at24_macc_write;

  107.  
  108. at24->bin.write = at24_bin_write;

  109. at24->bin.attr.mode |= S_IWUSR;

  110.  
  111. if (write_max > io_limit)

  112. write_max = io_limit;

  113. if (use_smbus && write_max > I2C_SMBUS_BLOCK_MAX)

  114. write_max = I2C_SMBUS_BLOCK_MAX;

  115. at24->write_max = write_max;

  116.  
  117. /* buffer (data + address at the beginning) */

  118. at24->writebuf = kmalloc(write_max + 2, GFP_KERNEL);

  119. if (!at24->writebuf) {

  120. err = -ENOMEM;

  121. goto err_struct;

  122. }

  123. } else {

  124. dev_warn(&client->dev,

  125. "cannot write due to controller restrictions.");

  126. }

  127. }

  128.  
  129. at24->client[0] = client;

  130.  
  131. /* use dummy devices for multiple-address chips */

  132. for (i = 1; i < num_addresses; i++) {

  133. at24->client[i] = i2c_new_dummy(client->adapter,

  134. client->addr + i);

  135. if (!at24->client[i]) {

  136. dev_err(&client->dev, "address 0x%02x unavailable\n",

  137. client->addr + i);

  138. err = -EADDRINUSE;

  139. goto err_clients;

  140. }

  141. }

  142.  
  143. err = sysfs_create_bin_file(&client->dev.kobj, &at24->bin);

  144. if (err)

  145. goto err_clients;

  146.  
  147. i2c_set_clientdata(client, at24);

  148.  
  149. dev_info(&client->dev, "%zu byte %s EEPROM, %s, %u bytes/write\n",

  150. at24->bin.size, client->name,

  151. writable ? "writable" : "read-only", at24->write_max);

  152. if (use_smbus == I2C_SMBUS_WORD_DATA ||

  153. use_smbus == I2C_SMBUS_BYTE_DATA) {

  154. dev_notice(&client->dev, "Falling back to %s reads, "

  155. "performance will suffer\n", use_smbus ==

  156. I2C_SMBUS_WORD_DATA ? "word" : "byte");

  157. }

  158.  
  159. /* export data to kernel code */

  160. if (chip.setup)

  161. chip.setup(&at24->macc, chip.context);

  162.  
  163. return 0;

  164.  
  165. err_clients:

  166. for (i = 1; i < num_addresses; i++)

  167. if (at24->client[i])

  168. i2c_unregister_device(at24->client[i]);

  169.  
  170. kfree(at24->writebuf);

  171. err_struct:

  172. kfree(at24);

  173. err_out:

  174. dev_dbg(&client->dev, "probe error %d\n", err);

  175. return err;

  176. }

 

7.总结

 

①. i2c platfrom_device设备注册;

 

②. i2c板级文件"at24c512"加入到全局链表__i2c_board_list中;

 

③. i2c platform_driver设备驱动注册、总线适配器创建,并且将该设备加入到结构体内核链表bus->p->klist_devices中;

 

④. i2c 设备"at24c512"注册,通过i2c_for_each_dev(...)遍历内核链表bus->p->klist_devices,根据设备名“at24c513”进行匹配,条件成立将进行从设备地址探测,成功将在/dev下创建对应的设备(我原来在调试i2c-rtc驱动时,由于硬件电路        SCLK\SDA出现问题,导致探测失败,结果是没有在/dev下创建设备rtc0设备,所以这也是检验硬件电路的一种方式!)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值