fci_i2c.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /*****************************************************************************
  2. Copyright(c) 2012 FCI Inc. All Rights Reserved
  3. File name : fci_i2c.c
  4. Description : fci i2c driver
  5. *******************************************************************************/
  6. #include <linux/delay.h>
  7. #include <linux/mutex.h>
  8. #include "fci_types.h"
  9. #include "fci_oal.h"
  10. #include "fc8150_regs.h"
  11. #include "fci_hal.h"
  12. #define FEATURE_SIMPLE_INTERFACE
  13. #define I2CSTAT_TIP 0x02 /* Tip bit */
  14. #define I2CSTAT_NACK 0x80 /* Nack bit */
  15. #define I2C_TIMEOUT 100
  16. #define I2C_CR_STA 0x80
  17. #define I2C_CR_STO 0x40
  18. #define I2C_CR_RD 0x20
  19. #define I2C_CR_WR 0x10
  20. #define I2C_CR_NACK 0x08
  21. #define I2C_CR_IACK 0x01
  22. #define I2C_WRITE 0
  23. #define I2C_READ 1
  24. #define I2C_OK 0
  25. #define I2C_NOK 1
  26. #define I2C_NACK 2
  27. #define I2C_NOK_LA 3 /* Lost arbitration */
  28. #define I2C_NOK_TOUT 4 /* time out */
  29. #define FC8150_FREQ_XTAL BBM_XTAL_FREQ
  30. /* static OAL_SEMAPHORE hBbmMutex; */
  31. static DEFINE_MUTEX(fci_i2c_lock);
  32. static int WaitForXfer(HANDLE hDevice)
  33. {
  34. int res = I2C_OK;
  35. #ifdef FEATURE_SIMPLE_INTERFACE
  36. udelay(30);
  37. #else
  38. int i;
  39. u8 status;
  40. i = I2C_TIMEOUT * 20000;
  41. /* wait for transfer complete */
  42. do {
  43. bbm_read(hDevice, BBM_I2C_SR, &status);
  44. i--;
  45. } while ((i > 0) && (status & I2CSTAT_TIP));
  46. /* check time out or nack */
  47. if (status & I2CSTAT_TIP) {
  48. res = I2C_NOK_TOUT;
  49. } else {
  50. bbm_read(hDevice, BBM_I2C_SR, &status);
  51. if (status & I2CSTAT_NACK)
  52. res = I2C_NACK;
  53. else
  54. res = I2C_OK;
  55. }
  56. #endif
  57. return res;
  58. }
  59. static int fci_i2c_transfer(HANDLE hDevice, u8 cmd_type, u8 chip
  60. , u8 addr[], u8 addr_len, u8 data[], u8 data_len)
  61. {
  62. int i;
  63. int result = I2C_OK;
  64. switch (cmd_type) {
  65. case I2C_WRITE:
  66. bbm_write(hDevice, BBM_I2C_TXR, chip | cmd_type);
  67. bbm_write(hDevice, BBM_I2C_CR, I2C_CR_STA | I2C_CR_WR /*0x90*/);
  68. result = WaitForXfer(hDevice);
  69. if (result != I2C_OK)
  70. return result;
  71. if (addr && addr_len) {
  72. i = 0;
  73. while ((i < addr_len) && (result == I2C_OK)) {
  74. bbm_write(hDevice, BBM_I2C_TXR, addr[i]);
  75. bbm_write(hDevice, BBM_I2C_CR
  76. , I2C_CR_WR /*0x10*/);
  77. result = WaitForXfer(hDevice);
  78. if (result != I2C_OK)
  79. return result;
  80. i++;
  81. }
  82. }
  83. i = 0;
  84. while ((i < data_len) && (result == I2C_OK)) {
  85. bbm_write(hDevice, BBM_I2C_TXR, data[i]);
  86. bbm_write(hDevice, BBM_I2C_CR, I2C_CR_WR /*0x10*/);
  87. result = WaitForXfer(hDevice);
  88. if (result != I2C_OK)
  89. return result;
  90. i++;
  91. }
  92. bbm_write(hDevice, BBM_I2C_CR, I2C_CR_STO /*0x40*/);
  93. result = WaitForXfer(hDevice);
  94. if (result != I2C_OK)
  95. return result;
  96. break;
  97. case I2C_READ:
  98. if (addr && addr_len) {
  99. bbm_write(hDevice, BBM_I2C_TXR, chip | I2C_WRITE);
  100. bbm_write(hDevice, BBM_I2C_CR
  101. , I2C_CR_STA | I2C_CR_WR /*0x90*/);
  102. result = WaitForXfer(hDevice);
  103. if (result != I2C_OK)
  104. return result;
  105. i = 0;
  106. while ((i < addr_len) && (result == I2C_OK)) {
  107. bbm_write(hDevice, BBM_I2C_TXR, addr[i]);
  108. bbm_write(hDevice, BBM_I2C_CR
  109. , I2C_CR_WR /*0x10*/);
  110. result = WaitForXfer(hDevice);
  111. if (result != I2C_OK)
  112. return result;
  113. i++;
  114. }
  115. }
  116. bbm_write(hDevice, BBM_I2C_TXR, chip | I2C_READ);
  117. bbm_write(hDevice, BBM_I2C_CR, I2C_CR_STA | I2C_CR_WR /*0x90*/);
  118. result = WaitForXfer(hDevice);
  119. if (result != I2C_OK)
  120. return result;
  121. i = 0;
  122. while ((i < data_len) && (result == I2C_OK)) {
  123. if (i == data_len - 1) {
  124. bbm_write(hDevice, BBM_I2C_CR
  125. , I2C_CR_RD|I2C_CR_NACK/*0x28*/);
  126. result = WaitForXfer(hDevice);
  127. if ((result != I2C_NACK)
  128. && (result != I2C_OK)) {
  129. PRINTF(hDevice, "NACK4-0[%02x]\n"
  130. , result);
  131. return result;
  132. }
  133. } else {
  134. bbm_write(hDevice, BBM_I2C_CR
  135. , I2C_CR_RD /*0x20*/);
  136. result = WaitForXfer(hDevice);
  137. if (result != I2C_OK) {
  138. PRINTF(hDevice, "NACK4-1[%02x]\n"
  139. , result);
  140. return result;
  141. }
  142. }
  143. bbm_read(hDevice, BBM_I2C_RXR, &data[i]);
  144. i++;
  145. }
  146. bbm_write(hDevice, BBM_I2C_CR, I2C_CR_STO /*0x40*/);
  147. result = WaitForXfer(hDevice);
  148. if ((result != I2C_NACK) && (result != I2C_OK)) {
  149. PRINTF(hDevice, "NACK5[%02X]\n", result);
  150. return result;
  151. }
  152. break;
  153. default:
  154. return I2C_NOK;
  155. }
  156. return I2C_OK;
  157. }
  158. int fci_i2c_init(HANDLE hDevice, int speed, int slaveaddr)
  159. {
  160. u16 r = FC8150_FREQ_XTAL % (5 * speed);
  161. u16 pr = (FC8150_FREQ_XTAL - r) / (5 * speed) - 1;
  162. if (((5 * speed) >> 1) <= r)
  163. pr++;
  164. bbm_word_write(hDevice, BBM_I2C_PR_L, pr);
  165. bbm_write(hDevice, BBM_I2C_CTR, 0xc0);
  166. PRINTF(hDevice, "Internal I2C Pre-scale: 0x%02x\n", pr);
  167. return BBM_OK;
  168. }
  169. int fci_i2c_read(HANDLE hDevice, u8 chip, u8 addr, u8 alen, u8 *data, u8 len)
  170. {
  171. int ret;
  172. mutex_lock(&fci_i2c_lock);
  173. ret = fci_i2c_transfer(hDevice, I2C_READ, chip << 1, &addr
  174. , alen, data, len);
  175. mutex_unlock(&fci_i2c_lock);
  176. if (ret != I2C_OK) {
  177. PRINTF(hDevice, "fci_i2c_read() result=%d, addr = %x, data=%x\n"
  178. , ret, addr, *data);
  179. return ret;
  180. }
  181. return ret;
  182. }
  183. int fci_i2c_write(HANDLE hDevice, u8 chip, u8 addr, u8 alen, u8 *data, u8 len)
  184. {
  185. int ret;
  186. u8 *paddr = &addr;
  187. mutex_lock(&fci_i2c_lock);
  188. ret = fci_i2c_transfer(hDevice, I2C_WRITE, chip << 1
  189. , paddr, alen, data, len);
  190. mutex_unlock(&fci_i2c_lock);
  191. if (ret != I2C_OK)
  192. PRINTF(hDevice, "fci_i2c_write() result=%d, addr= %x, data=%x\n"
  193. , ret, addr, *data);
  194. return ret;
  195. }
  196. int fci_i2c_deinit(HANDLE hDevice)
  197. {
  198. bbm_write(hDevice, BBM_I2C_CTR, 0x00);
  199. return BBM_OK;
  200. }