s3c44b0_i2c.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. /*
  2. * (C) Copyright 2004
  3. * DAVE Srl
  4. * http://www.dave-tech.it
  5. * http://www.wawnet.biz
  6. * mailto:info@wawnet.biz
  7. *
  8. * SPDX-License-Identifier: GPL-2.0+
  9. */
  10. #include <common.h>
  11. #include <command.h>
  12. #include <asm/hardware.h>
  13. /*
  14. * Initialization, must be called once on start up, may be called
  15. * repeatedly to change the speed and slave addresses.
  16. */
  17. void i2c_init(int speed, int slaveaddr)
  18. {
  19. /*
  20. setting up I2C support
  21. */
  22. unsigned int save_F,save_PF,rIICCON,rPCONA,rPDATA,rPCONF,rPUPF;
  23. save_F = PCONF;
  24. save_PF = PUPF;
  25. rPCONF = ((save_F & ~(0xF))| 0xa);
  26. rPUPF = (save_PF | 0x3);
  27. PCONF = rPCONF; /*PF0:IICSCL, PF1:IICSDA*/
  28. PUPF = rPUPF; /* Disable pull-up */
  29. /* Configuring pin for WC pin of EEprom */
  30. rPCONA = PCONA;
  31. rPCONA &= ~(1<<9);
  32. PCONA = rPCONA;
  33. rPDATA = PDATA;
  34. rPDATA &= ~(1<<9);
  35. PDATA = rPDATA;
  36. /*
  37. Enable ACK, IICCLK=MCLK/16, enable interrupt
  38. 75MHz/16/(12+1) = 390625 Hz
  39. */
  40. rIICCON=(1<<7)|(0<<6)|(1<<5)|(0xC);
  41. IICCON = rIICCON;
  42. IICADD = slaveaddr;
  43. }
  44. /*
  45. * Probe the given I2C chip address. Returns 0 if a chip responded,
  46. * not 0 on failure.
  47. */
  48. int i2c_probe(uchar chip)
  49. {
  50. /*
  51. not implemented
  52. */
  53. printf("i2c_probe chip %d\n", (int) chip);
  54. return -1;
  55. }
  56. /*
  57. * Read/Write interface:
  58. * chip: I2C chip address, range 0..127
  59. * addr: Memory (register) address within the chip
  60. * alen: Number of bytes to use for addr (typically 1, 2 for larger
  61. * memories, 0 for register type devices with only one
  62. * register)
  63. * buffer: Where to read/write the data
  64. * len: How many bytes to read/write
  65. *
  66. * Returns: 0 on success, not 0 on failure
  67. */
  68. #define S3C44B0X_rIIC_INTPEND (1<<4)
  69. #define S3C44B0X_rIIC_LAST_RECEIV_BIT (1<<0)
  70. #define S3C44B0X_rIIC_INTERRUPT_ENABLE (1<<5)
  71. #define S3C44B0_IIC_TIMEOUT 100
  72. int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
  73. {
  74. int k, j, temp;
  75. u32 rIICSTAT;
  76. /*
  77. send the device offset
  78. */
  79. rIICSTAT = 0xD0;
  80. IICSTAT = rIICSTAT;
  81. IICDS = chip; /* this is a write operation... */
  82. rIICSTAT |= (1<<5);
  83. IICSTAT = rIICSTAT;
  84. for(k=0; k<S3C44B0_IIC_TIMEOUT; k++) {
  85. temp = IICCON;
  86. if( (temp & S3C44B0X_rIIC_INTPEND) == S3C44B0X_rIIC_INTPEND)
  87. break;
  88. udelay(2000);
  89. }
  90. if (k==S3C44B0_IIC_TIMEOUT)
  91. return -1;
  92. /* wait and check ACK */
  93. temp = IICSTAT;
  94. if ((temp & S3C44B0X_rIIC_LAST_RECEIV_BIT) == S3C44B0X_rIIC_LAST_RECEIV_BIT )
  95. return -1;
  96. IICDS = addr;
  97. IICCON = IICCON & ~(S3C44B0X_rIIC_INTPEND);
  98. /* wait and check ACK */
  99. for(k=0; k<S3C44B0_IIC_TIMEOUT; k++) {
  100. temp = IICCON;
  101. if( (temp & S3C44B0X_rIIC_INTPEND) == S3C44B0X_rIIC_INTPEND)
  102. break;
  103. udelay(2000);
  104. }
  105. if (k==S3C44B0_IIC_TIMEOUT)
  106. return -1;
  107. temp = IICSTAT;
  108. if ((temp & S3C44B0X_rIIC_LAST_RECEIV_BIT) == S3C44B0X_rIIC_LAST_RECEIV_BIT )
  109. return -1;
  110. /*
  111. now we can start with the read operation...
  112. */
  113. IICDS = chip | 0x01; /* this is a read operation... */
  114. rIICSTAT = 0x90; /*master recv*/
  115. rIICSTAT |= (1<<5);
  116. IICSTAT = rIICSTAT;
  117. IICCON = IICCON & ~(S3C44B0X_rIIC_INTPEND);
  118. /* wait and check ACK */
  119. for(k=0; k<S3C44B0_IIC_TIMEOUT; k++) {
  120. temp = IICCON;
  121. if( (temp & S3C44B0X_rIIC_INTPEND) == S3C44B0X_rIIC_INTPEND)
  122. break;
  123. udelay(2000);
  124. }
  125. if (k==S3C44B0_IIC_TIMEOUT)
  126. return -1;
  127. temp = IICSTAT;
  128. if ((temp & S3C44B0X_rIIC_LAST_RECEIV_BIT) == S3C44B0X_rIIC_LAST_RECEIV_BIT )
  129. return -1;
  130. for (j=0; j<len-1; j++) {
  131. /*clear pending bit to resume */
  132. temp = IICCON & ~(S3C44B0X_rIIC_INTPEND);
  133. IICCON = temp;
  134. /* wait and check ACK */
  135. for(k=0; k<S3C44B0_IIC_TIMEOUT; k++) {
  136. temp = IICCON;
  137. if( (temp & S3C44B0X_rIIC_INTPEND) == S3C44B0X_rIIC_INTPEND)
  138. break;
  139. udelay(2000);
  140. }
  141. if (k==S3C44B0_IIC_TIMEOUT)
  142. return -1;
  143. buffer[j] = IICDS; /*save readed data*/
  144. } /*end for(j)*/
  145. /*
  146. reading the last data
  147. unset ACK generation
  148. */
  149. temp = IICCON & ~(S3C44B0X_rIIC_INTPEND | (1<<7));
  150. IICCON = temp;
  151. /* wait but NOT check ACK */
  152. for(k=0; k<S3C44B0_IIC_TIMEOUT; k++) {
  153. temp = IICCON;
  154. if( (temp & S3C44B0X_rIIC_INTPEND) == S3C44B0X_rIIC_INTPEND)
  155. break;
  156. udelay(2000);
  157. }
  158. if (k==S3C44B0_IIC_TIMEOUT)
  159. return -1;
  160. buffer[j] = IICDS; /*save readed data*/
  161. rIICSTAT = 0x90; /*master recv*/
  162. /* Write operation Terminate sending STOP */
  163. IICSTAT = rIICSTAT;
  164. /*Clear Int Pending Bit to RESUME*/
  165. temp = IICCON;
  166. IICCON = temp & (~S3C44B0X_rIIC_INTPEND);
  167. IICCON = IICCON | (1<<7); /*restore ACK generation*/
  168. return 0;
  169. }
  170. int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
  171. {
  172. int j, k;
  173. u32 rIICSTAT, temp;
  174. /*
  175. send the device offset
  176. */
  177. rIICSTAT = 0xD0;
  178. IICSTAT = rIICSTAT;
  179. IICDS = chip; /* this is a write operation... */
  180. rIICSTAT |= (1<<5);
  181. IICSTAT = rIICSTAT;
  182. IICCON = IICCON & ~(S3C44B0X_rIIC_INTPEND);
  183. /* wait and check ACK */
  184. for(k=0; k<S3C44B0_IIC_TIMEOUT; k++) {
  185. temp = IICCON;
  186. if( (temp & S3C44B0X_rIIC_INTPEND) == S3C44B0X_rIIC_INTPEND)
  187. break;
  188. udelay(2000);
  189. }
  190. if (k==S3C44B0_IIC_TIMEOUT)
  191. return -1;
  192. temp = IICSTAT;
  193. if ((temp & S3C44B0X_rIIC_LAST_RECEIV_BIT) == S3C44B0X_rIIC_LAST_RECEIV_BIT )
  194. return -1;
  195. IICDS = addr;
  196. IICCON = IICCON & ~(S3C44B0X_rIIC_INTPEND);
  197. /* wait and check ACK */
  198. for(k=0; k<S3C44B0_IIC_TIMEOUT; k++) {
  199. temp = IICCON;
  200. if( (temp & S3C44B0X_rIIC_INTPEND) == S3C44B0X_rIIC_INTPEND)
  201. break;
  202. udelay(2000);
  203. }
  204. if (k==S3C44B0_IIC_TIMEOUT)
  205. return -1;
  206. temp = IICSTAT;
  207. if ((temp & S3C44B0X_rIIC_LAST_RECEIV_BIT) == S3C44B0X_rIIC_LAST_RECEIV_BIT )
  208. return -1;
  209. /*
  210. now we can start with the read write operation
  211. */
  212. for (j=0; j<len; j++) {
  213. IICDS = buffer[j]; /*prerare data to write*/
  214. /*clear pending bit to resume*/
  215. temp = IICCON & ~(S3C44B0X_rIIC_INTPEND);
  216. IICCON = temp;
  217. /* wait but NOT check ACK */
  218. for(k=0; k<S3C44B0_IIC_TIMEOUT; k++) {
  219. temp = IICCON;
  220. if( (temp & S3C44B0X_rIIC_INTPEND) == S3C44B0X_rIIC_INTPEND)
  221. break;
  222. udelay(2000);
  223. }
  224. if (k==S3C44B0_IIC_TIMEOUT)
  225. return -1;
  226. } /* end for(j) */
  227. /* sending stop to terminate */
  228. rIICSTAT = 0xD0; /*master send*/
  229. IICSTAT = rIICSTAT;
  230. /*Clear Int Pending Bit to RESUME*/
  231. temp = IICCON;
  232. IICCON = temp & (~S3C44B0X_rIIC_INTPEND);
  233. return 0;
  234. }