一、板級設(shè)備掃描 | ||||
針對上一篇文章最后的i2c_scan_static_board_info(adap)函數(shù)處,首先先看下在系統(tǒng)啟動(dòng)的時(shí)候板級設(shè)備的注冊。 針對我現(xiàn)在使用的開發(fā)板,對于I2C設(shè)備注冊程序如下: 1. static struct i2c_board_info i2c_devices_info[] = { 2. #ifdef CONFIG_SND_SOC_ALC5623 3. { 4. I2C_BOARD_INFO("alc5623", 0x1a), 5. .platform_data = &alc5623_data, 6. }, 7. #endif 8. #ifdef CONFIG_RTC_DRV_DS3231M 9. { 10. I2C_BOARD_INFO("ds3231m", 0x68), 11. .platform_data = NULL, 12. }, 13. #endif 14. #ifdef CONFIG_RTC_DRV_PCF8563 15. { 16. I2C_BOARD_INFO("pcf8563", 0x51), 17. .platform_data = NULL, 18. }, 19. #endif 20. }; 21. static int __init gsc3280_i2c_devices_init(void) 22. { 23. i2c_register_board_info(0, i2c_devices_info, ARRAY_SIZE(i2c_devices_info)); 24. return 0; 25. } 26. device_initcall(gsc3280_i2c_devices_init);
1. DECLARE_RWSEM(__i2c_board_lock); 2. EXPORT_SYMBOL_GPL(__i2c_board_lock); 3. 4. LIST_HEAD(__i2c_board_list); 5. EXPORT_SYMBOL_GPL(__i2c_board_list); 6. 7. int __i2c_first_dynamic_bus_num; 8. EXPORT_SYMBOL_GPL(__i2c_first_dynamic_bus_num); 9. 10. int __init 11. i2c_register_board_info(int busnum, 12. struct i2c_board_info const *info, unsigned len) 13. { 14. int status; 15. down_write(&__i2c_board_lock); 16. /* dynamic bus numbers will be assigned after the last static one */ 17. if (busnum >= __i2c_first_dynamic_bus_num) 18. __i2c_first_dynamic_bus_num = busnum + 1; 19. for (status = 0; len; len--, info++) { 20. struct i2c_devinfo *devinfo; 21. devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL); 22. if (!devinfo) { 23. pr_debug("i2c-core: can't register boardinfo!\n"); 24. status = -ENOMEM; 25. break; 26. } 27. devinfo->busnum = busnum; 28. devinfo->board_info = *info; 29. list_add_tail(&devinfo->list, &__i2c_board_list); 30. } 31. up_write(&__i2c_board_lock); 32. return status; 33. } 上面的程序位于i2c-boardinfo.c中,i2c_register_board_info()函數(shù)的for循環(huán)中,首先會(huì)申請I2C設(shè)備信息結(jié)構(gòu)體,如果申請成功,將I2C總線號和設(shè)備信息賦值給設(shè)備信息結(jié)構(gòu)體,并且將設(shè)備信息結(jié)構(gòu)體的鏈表插入到__i2c_board_list中,此處尤為重要,在本文的開頭中所提的函數(shù)i2c_scan_static_board_info(adap);,此函數(shù)就是通過__i2c_board_list鏈表找到上面注冊的設(shè)備信息,結(jié)合gsc3280_i2c_devices_init()函數(shù)和i2c_devices_info結(jié)構(gòu)體,此處for循環(huán)的len為3,即正常情況下需要?jiǎng)?chuàng)建三個(gè)devinfo結(jié)構(gòu)體,for循環(huán)結(jié)束后,__i2c_board_list鏈表中也就有了三個(gè)I2C設(shè)備的鏈表項(xiàng),在程序的其他地方如果需要使用這里注冊的設(shè)備結(jié)構(gòu)信息,只需要遍歷鏈表__i2c_board_list,通過總線號即可找到相應(yīng)的設(shè)備信息。 接下來就可以看下函數(shù)i2c_scan_static_board_info(adap): 1. static void i2c_scan_static_board_info(struct i2c_adapter *adapter) 2. { 3. struct i2c_devinfo *devinfo; 4. down_read(&__i2c_board_lock); 5. list_for_each_entry(devinfo, &__i2c_board_list, list) { 6. if (devinfo->busnum == adapter->nr 7. && !i2c_new_device(adapter, 8. &devinfo->board_info)) 9. dev_err(&adapter->dev, 10. "Can't create device at 0x%02x\n", 11. devinfo->board_info.addr); 12. } 13. up_read(&__i2c_board_lock); 14. } 從上面程序可以看到,語句list_for_each_entry(devinfo, &__i2c_board_list, list) 實(shí)現(xiàn)對__i2c_board_list的遍歷,if語句的前半部分“devinfo->busnum ==adapter->nr”判斷是否是需要尋找的結(jié)構(gòu)體,如果是,就調(diào)用函數(shù)i2c_new_device()創(chuàng)建新的I2C設(shè)備,i2c_new_device函數(shù)如下: 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. client = kzalloc(sizeof *client, GFP_KERNEL); 7. if (!client) 8. return NULL; 9. client->adapter = adap; 10. client->dev.platform_data = info->platform_data; 11. if (info->archdata) 12. client->dev.archdata = *info->archdata; 13. client->flags = info->flags; 14. client->addr = info->addr; 15. client->irq = info->irq; 16. strlcpy(client->name, info->type, sizeof(client->name)); 17. /* Check for address validity */ 18. status = i2c_check_client_addr_validity(client); 19. if (status) { 20. dev_err(&adap->dev, "Invalid %d-bit I2C address 0x%02hx\n", 21. client->flags & I2C_CLIENT_TEN ? 10 : 7, client->addr); 22. goto out_err_silent; 23. } 24. /* Check for address business */ 25. status = i2c_check_addr_busy(adap, client->addr); 26. if (status) 27. goto out_err; 28. client->dev.parent = &client->adapter->dev; 29. client->dev.bus = &i2c_bus_type; 30. client->dev.type = &i2c_client_type; 31. client->dev.of_node = info->of_node; 32. dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap), 33. client->addr); 34. status = device_register(&client->dev); 35. if (status) 36. goto out_err; 37. dev_dbg(&adap->dev, "client [%s] registered with bus id %s\n", 38. client->name, dev_name(&client->dev)); 39. return client; 40. out_err: 41. dev_err(&adap->dev, "Failed to register i2c client %s at 0x%02x " 42. "(%d)\n", client->name, client->addr, status); 43. out_err_silent: 44. kfree(client); 45. return NULL; 46. } 47. EXPORT_SYMBOL_GPL(i2c_new_device);
i2c_client結(jié)構(gòu)體了,分別對應(yīng)alc5623、ds3231m和pcf8563。 到此位置,I2C總線驅(qū)動(dòng),I2C設(shè)備的注冊和相應(yīng)結(jié)構(gòu)體的申請就已經(jīng)完成了,接下來看下常用的I2C數(shù)據(jù)傳輸函數(shù),I2C設(shè)備驅(qū)動(dòng)主要調(diào)用這些數(shù)據(jù)傳輸接口完成數(shù)據(jù)的傳輸。 | ||||
二、I2C數(shù)據(jù)傳輸 | ||||
I2C數(shù)據(jù)傳輸分為兩種,一種為符合I2C協(xié)議的普通數(shù)據(jù)傳輸,另外一種為符合SMBUS協(xié)議的數(shù)據(jù)傳輸,接下來我們首先看下符合I2C協(xié)議的普通數(shù)據(jù)傳輸。 | ||||
1、I2C協(xié)議的普通數(shù)據(jù)傳輸 | ||||
I2C協(xié)議普通數(shù)據(jù)傳輸?shù)慕涌诤瘮?shù)基本為i2c_master_send和i2c_master_recv,查看其函數(shù)發(fā)現(xiàn),最后都是調(diào)用i2c_transfer函數(shù)實(shí)現(xiàn)傳輸?shù)模琲2c_transfer函數(shù)如下: 1. int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num) 2. { 3. int ret; 4. if (adap->algo->master_xfer) { 5. #ifdef DEBUG 6. for (ret = 0; ret < num; ret++) { 7. dev_dbg(&adap->dev, "master_xfer[%d] %c, addr=0x%02x, " 8. "len=%d%s/n", ret, (msgs[ret].flags & I2C_M_RD) 9. ? 'R' : 'W', msgs[ret].addr, msgs[ret].len, 10. (msgs[ret].flags & I2C_M_RECV_LEN) ? "+" : ""); 11. } 12. #endif 13. if (in_atomic() || irqs_disabled()) { 14. ret = mutex_trylock(&adap->bus_lock); 15. if (!ret) 16. /* I2C activity is ongoing. */ 17. return -EAGAIN; 18. } else { 19. mutex_lock_nested(&adap->bus_lock, adap->level); 20. } 21. ret = adap->algo->master_xfer(adap,msgs,num); 22. mutex_unlock(&adap->bus_lock); 23. return ret; 24. } else { 25. dev_dbg(&adap->dev, "I2C level transfers not supported/n"); 26. return -ENOSYS; 27. } 28. } 因?yàn)樵谶@里的同步用的是mutex。首先判斷是否允許睡眠,如果不允許,嘗試獲鎖,如果獲鎖失敗,則返回。這樣的操作是避免進(jìn)入睡眠,我們在后面也可以看到,實(shí)際的傳輸工作交給了adap->algo->master_xfer()完成,也就是我們在(一)中注冊的algorithm中的i2c_gsc_func函數(shù)。 | ||||
2、SMBUS協(xié)議I2C數(shù)據(jù)傳輸 | ||||
SMBUS協(xié)議的具體內(nèi)容可以參考網(wǎng)絡(luò),在I2C驅(qū)動(dòng)中,符合SMBUS協(xié)議傳輸?shù)暮瘮?shù)很多,包括i2c_smbus_read_byte、i2c_smbus_write_byte、i2c_smbus_read_byte_data、i2c_smbus_write_byte_data、i2c_smbus_read_word_data和i2c_smbus_write_word_data等,閱讀這些函數(shù)發(fā)現(xiàn),程序里面都是根據(jù)SMBUS協(xié)議和函數(shù)功能,完成對函數(shù)i2c_smbus_xfer形參的賦值,最后調(diào)用此函數(shù)來實(shí)現(xiàn)傳輸。接下來看下i2c_smbus_xfer函數(shù): 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. flags &= I2C_M_TEN | I2C_CLIENT_PEC; 9. if (adapter->algo->smbus_xfer) { 10. i2c_lock_adapter(adapter); 11. /* Retry automatically on arbitration loss */ 12. orig_jiffies = jiffies; 13. for (res = 0, try = 0; try <= adapter->retries; try++) { 14. res = adapter->algo->smbus_xfer(adapter, addr, flags, 15. read_write, command, 16. protocol, data); 17. if (res != -EAGAIN) 18. break; 19. if (time_after(jiffies, 20. orig_jiffies + adapter->timeout)) 21. break; 22. } 23. i2c_unlock_adapter(adapter); 24. } else 25. res = i2c_smbus_xfer_emulated(adapter, addr, flags, read_write, 26. command, protocol, data); 27. return res; 28. } 如果adapter有smbus_xfer()函數(shù),則直接調(diào)用它發(fā)送數(shù)據(jù)。否則也就是在adapter不支持smbus協(xié)議的情況下,調(diào)用i2c_smbus_xfer_emulated()繼續(xù)處理。根據(jù)(一)中的總線驅(qū)動(dòng)是不支持smbus協(xié)議的。繼續(xù)看函數(shù)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. //寫操作只會(huì)進(jìn)行一次交互,而讀操作,有時(shí)會(huì)有兩次操作. 11. //因?yàn)橛袝r(shí)候讀操作要先寫command,再從總線上讀數(shù)據(jù) 12. //在這里為了代碼的簡潔,使用了兩個(gè)緩存區(qū),將兩種情況統(tǒng)一起來. 13. unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX+3]; 14. unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX+2]; 15. //一般來說,讀操作要交互兩次,例外的情況我們在下面會(huì)接著分析 16. int num = read_write == I2C_SMBUS_READ?2:1; 17. //與設(shè)備交互的數(shù)據(jù),一般在msg[0]存放寫入設(shè)備的信息,在msb[1]里存放接收到的 18. //信息,不過也有例外的 19. //msg[2]的初始化,默認(rèn)發(fā)送緩存區(qū)占一個(gè)字節(jié),無接收緩存 20. struct i2c_msg msg[2] = { { addr, flags, 1, msgbuf0 }, 21. { addr, flags | I2C_M_RD, 0, msgbuf1 } 22. }; 23. int i; 24. u8 partial_pec = 0; 25. //將要發(fā)送的信息copy到發(fā)送緩存區(qū)的第一字節(jié) 26. msgbuf0[0] = command; 27. switch(size) { 28. //quick類型,它并不傳輸有效數(shù)據(jù),只是將地址寫到總線上,等待應(yīng)答即可 29. //所以將發(fā)送緩存區(qū)長度置為0。再根據(jù)讀/寫操作,調(diào)整msg[0]的標(biāo)志位 30. //這類傳輸只需要一次總線交互 31. case I2C_SMBUS_QUICK: 32. msg[0].len = 0; 33. /* Special case: The read/write field is used as data */ 34. msg[0].flags = flags | (read_write==I2C_SMBUS_READ)?I2C_M_RD:0; 35. num = 1; 36. break; 37. case I2C_SMBUS_BYTE: 38. //BYTE類型指一次寫和讀只有一個(gè)字節(jié).這種情況下,讀和寫都只會(huì)交互一次 39. //這種類型的讀有例外,它讀取出來的數(shù)據(jù)不是放在msg[1]中的,而是存放在msg[0] 40. if (read_write == I2C_SMBUS_READ) { 41. /* Special case: only a */ 42. msg[0].flags = I2C_M_RD | flags; 43. num = 1; 44. } 45. break; 46. case I2C_SMBUS_BYTE_DATA: 47. //Byte_Data是指命令+數(shù)據(jù)的傳輸形式,在這種情況下,寫只需要一次交互,讀卻要兩次 48. //第一次將command寫到總線上,第二次要轉(zhuǎn)換方向,要將設(shè)備地址和read標(biāo)志寫入總線. 49. //應(yīng)回答之后再進(jìn)行read操作 50. //寫操作占兩字節(jié),分別是command+data,讀操作的有效數(shù)據(jù)只有一個(gè)字節(jié) 51. //交互次數(shù)用初始化值就可以了 52. if (read_write == I2C_SMBUS_READ) 53. msg[1].len = 1; 54. else { 55. msg[0].len = 2; 56. msgbuf0[1] = data->byte; 57. } 58. break; 59. case I2C_SMBUS_WORD_DATA: 60. //Word_Data是指命令+雙字節(jié)的形式.這種情況跟Byte_Data的情況類似 61. //兩者相比只是交互的數(shù)據(jù)大小不同 62. if (read_write == I2C_SMBUS_READ) 63. msg[1].len = 2; 64. else { 65. msg[0].len=3; 66. msgbuf0[1] = data->word & 0xff; 67. msgbuf0[2] = data->word >> 8; 68. } 69. break; 70. case I2C_SMBUS_PROC_CALL: 71. //Proc_Call的方式與write 的Word_Data相似,只不過寫完Word_Data之后,要等待它的應(yīng)答 72. //應(yīng)該它需要交互兩次,一次寫一次讀 73. num = 2; /* Special case */ 74. read_write = I2C_SMBUS_READ; 75. msg[0].len = 3; 76. msg[1].len = 2; 77. msgbuf0[1] = data->word & 0xff; 78. msgbuf0[2] = data->word >> 8; 79. break; 80. case I2C_SMBUS_BLOCK_DATA: 81. //Block_Data:指command+N段數(shù)據(jù)的情況. 82. //如果是讀操作,它首先要寫command到總線,然后再讀N段數(shù)據(jù),要寫的command已經(jīng) 83. //放在msg[0]了,現(xiàn)在只需要將msg[1]的標(biāo)志置I2C_M_RECV_LEN位,msg[1]有效長度為1字節(jié),因?yàn)?/span> 84. //adapter驅(qū)動(dòng)會(huì)處理好的,現(xiàn)在還不知道要傳多少段數(shù)據(jù). 85. //對于寫的情況:msg[1]照例不需要.將要寫的數(shù)據(jù)全部都放到msb[0]中.相應(yīng)的也要更新 86. //msg[0]中的緩存區(qū)長度 87. if (read_write == I2C_SMBUS_READ) { 88. msg[1].flags |= I2C_M_RECV_LEN; 89. msg[1].len = 1; /* block length will be added by 90. the underlying bus driver */ 91. } else { 92. //data->block[0]表示后面有多少段數(shù)據(jù).總長度要加2是因?yàn)閏ommand+count+N段數(shù)據(jù) 93. msg[0].len = data->block[0] + 2; 94. if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 2) { 95. dev_err(&adapter->dev, "smbus_access called with " 96. "invalid block write size (%d)/n", 97. data->block[0]); 98. return -1; 99. } 100. for (i = 1; i < msg[0].len; i++) 101. msgbuf0 = data->block[i-1]; 102. } 103. break; 104. case I2C_SMBUS_BLOCK_PROC_CALL: 105. //Proc_Call:表示寫完Block_Data之后,要等它的應(yīng)答消息它和Block_Data相比,只是多了一部份應(yīng)答而已 106. num = 2; /* Another special case */ 107. read_write = I2C_SMBUS_READ; 108. if (data->block[0] > I2C_SMBUS_BLOCK_MAX) { 109. dev_err(&adapter->dev, "%s called with invalid " 110. "block proc call size (%d)/n", __func__, 111. data->block[0]); 112. return -1; 113. } 114. msg[0].len = data->block[0] + 2; 115. for (i = 1; i < msg[0].len; i++) 116. msgbuf0 = data->block[i-1]; 117. msg[1].flags |= I2C_M_RECV_LEN; 118. msg[1].len = 1; /* block length will be added by 119. the underlying bus driver */ 120. break; 121. case I2C_SMBUS_I2C_BLOCK_DATA: 122. //I2c Block_Data與Block_Data相似,只不過read的時(shí)候,數(shù)據(jù)長度是預(yù)先定義好了的.另外 123. //與Block_Data相比,中間不需要傳輸Count字段.(Count表示數(shù)據(jù)段數(shù)目) 124. if (read_write == I2C_SMBUS_READ) { 125. msg[1].len = data->block[0]; 126. } else { 127. msg[0].len = data->block[0] + 1; 128. if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 1) { 129. dev_err(&adapter->dev, "i2c_smbus_xfer_emulated called with " 130. "invalid block write size (%d)/n", 131. data->block[0]); 132. return -1; 133. } 134. for (i = 1; i <= data->block[0]; i++) 135. msgbuf0 = data->block; 136. } 137. break; 138. default: 139. dev_err(&adapter->dev, "smbus_access called with invalid size (%d)/n", 140. size); 141. return -1; 142. } 143. //如果啟用了PEC.Quick和I2c Block_Data是不支持PEC的 144. i = ((flags & I2C_CLIENT_PEC) && size != I2C_SMBUS_QUICK 145. && size != I2C_SMBUS_I2C_BLOCK_DATA); 146. if (i) { 147. /* Compute PEC if first message is a write */ 148. //如果第一個(gè)操作是寫操作 149. if (!(msg[0].flags & I2C_M_RD)) { 150. //如果只是寫操作 151. if (num == 1) /* Write only */ 152. //如果只有寫操作,寫緩存區(qū)要擴(kuò)充一個(gè)字節(jié),用來存放計(jì)算出來的PEC 153. i2c_smbus_add_pec(&msg[0]); 154. else /* Write followed by read */ 155. //如果后面還有讀操作,先計(jì)算前面寫部份的PEC(注意這種情況下不需要 156. //擴(kuò)充寫緩存區(qū),因?yàn)椴恍枰l(fā)送PEC.只會(huì)接收到PEC) 157. partial_pec = i2c_smbus_msg_pec(0, &msg[0]); 158. } 159. /* Ask for PEC if last message is a read */ 160. //如果最后一次是讀消息.還要接收到來自slave的PEC.所以接收緩存區(qū)要擴(kuò)充一個(gè)字節(jié) 161. if (msg[num-1].flags & I2C_M_RD) 162. msg[num-1].len++; 163. } 164. if (i2c_transfer(adapter, msg, num) < 0) 165. return -1; 166. /* Check PEC if last message is a read */ 167. //操作完了之后,如果最后一個(gè)操作是PEC的讀操作.檢驗(yàn)后面的PEC是否正確 168. if (i && (msg[num-1].flags & I2C_M_RD)) { 169. if (i2c_smbus_check_pec(partial_pec, &msg[num-1]) < 0) 170. return -1; 171. } 172. //操作完了,現(xiàn)在可以將數(shù)據(jù)放到data部份返回了. 173. if (read_write == I2C_SMBUS_READ) 174. switch(size) { 175. case I2C_SMBUS_BYTE: 176. data->byte = msgbuf0[0]; 177. break; 178. case I2C_SMBUS_BYTE_DATA: 179. data->byte = msgbuf1[0]; 180. break; 181. case I2C_SMBUS_WORD_DATA: 182. case I2C_SMBUS_PROC_CALL: 183. data->word = msgbuf1[0] | (msgbuf1[1] << 8); 184. break; 185. case I2C_SMBUS_I2C_BLOCK_DATA: 186. for (i = 0; i < data->block[0]; i++) 187. data->block[i+1] = msgbuf1; 188. break; 189. case I2C_SMBUS_BLOCK_DATA: 190. case I2C_SMBUS_BLOCK_PROC_CALL: 191. for (i = 0; i < msgbuf1[0] + 1; i++) 192. data->block = msgbuf1; 193. break; 194. } 195. return 0; 196.}
| ||||
原文請參見:http://blog.chinaunix.net/uid-25445243-id-3916323.html | ||||