fti2c010.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. /*
  2. * Faraday I2C Controller
  3. *
  4. * (C) Copyright 2010 Faraday Technology
  5. * Dante Su <dantesu@faraday-tech.com>
  6. *
  7. * SPDX-License-Identifier: GPL-2.0+
  8. */
  9. #include <common.h>
  10. #include <asm/io.h>
  11. #include <i2c.h>
  12. #include "fti2c010.h"
  13. #ifndef CONFIG_HARD_I2C
  14. #error "fti2c010: CONFIG_HARD_I2C is not defined"
  15. #endif
  16. #ifndef CONFIG_SYS_I2C_SPEED
  17. #define CONFIG_SYS_I2C_SPEED 50000
  18. #endif
  19. #ifndef CONFIG_FTI2C010_FREQ
  20. #define CONFIG_FTI2C010_FREQ clk_get_rate("I2C")
  21. #endif
  22. /* command timeout */
  23. #define CFG_CMD_TIMEOUT 10 /* ms */
  24. /* 7-bit chip address + 1-bit read/write */
  25. #define I2C_RD(chip) ((((chip) << 1) & 0xff) | 1)
  26. #define I2C_WR(chip) (((chip) << 1) & 0xff)
  27. struct fti2c010_chip {
  28. void __iomem *regs;
  29. uint bus;
  30. uint speed;
  31. };
  32. static struct fti2c010_chip chip_list[] = {
  33. {
  34. .bus = 0,
  35. .regs = (void __iomem *)CONFIG_FTI2C010_BASE,
  36. },
  37. #ifdef CONFIG_I2C_MULTI_BUS
  38. # ifdef CONFIG_FTI2C010_BASE1
  39. {
  40. .bus = 1,
  41. .regs = (void __iomem *)CONFIG_FTI2C010_BASE1,
  42. },
  43. # endif
  44. # ifdef CONFIG_FTI2C010_BASE2
  45. {
  46. .bus = 2,
  47. .regs = (void __iomem *)CONFIG_FTI2C010_BASE2,
  48. },
  49. # endif
  50. # ifdef CONFIG_FTI2C010_BASE3
  51. {
  52. .bus = 3,
  53. .regs = (void __iomem *)CONFIG_FTI2C010_BASE3,
  54. },
  55. # endif
  56. #endif /* #ifdef CONFIG_I2C_MULTI_BUS */
  57. };
  58. static struct fti2c010_chip *curr = chip_list;
  59. static int fti2c010_wait(uint32_t mask)
  60. {
  61. int ret = -1;
  62. uint32_t stat, ts;
  63. struct fti2c010_regs *regs = curr->regs;
  64. for (ts = get_timer(0); get_timer(ts) < CFG_CMD_TIMEOUT; ) {
  65. stat = readl(&regs->sr);
  66. if ((stat & mask) == mask) {
  67. ret = 0;
  68. break;
  69. }
  70. }
  71. return ret;
  72. }
  73. /*
  74. * u-boot I2C API
  75. */
  76. /*
  77. * Initialization, must be called once on start up, may be called
  78. * repeatedly to change the speed and slave addresses.
  79. */
  80. void i2c_init(int speed, int slaveaddr)
  81. {
  82. if (speed || !curr->speed)
  83. i2c_set_bus_speed(speed);
  84. /* if slave mode disabled */
  85. if (!slaveaddr)
  86. return;
  87. /*
  88. * TODO:
  89. * Implement slave mode, but is it really necessary?
  90. */
  91. }
  92. /*
  93. * Probe the given I2C chip address. Returns 0 if a chip responded,
  94. * not 0 on failure.
  95. */
  96. int i2c_probe(uchar chip)
  97. {
  98. int ret;
  99. struct fti2c010_regs *regs = curr->regs;
  100. i2c_init(0, 0);
  101. /* 1. Select slave device (7bits Address + 1bit R/W) */
  102. writel(I2C_WR(chip), &regs->dr);
  103. writel(CR_ENABLE | CR_TBEN | CR_START, &regs->cr);
  104. ret = fti2c010_wait(SR_DT);
  105. if (ret)
  106. return ret;
  107. /* 2. Select device register */
  108. writel(0, &regs->dr);
  109. writel(CR_ENABLE | CR_TBEN, &regs->cr);
  110. ret = fti2c010_wait(SR_DT);
  111. return ret;
  112. }
  113. /*
  114. * Read/Write interface:
  115. * chip: I2C chip address, range 0..127
  116. * addr: Memory (register) address within the chip
  117. * alen: Number of bytes to use for addr (typically 1, 2 for larger
  118. * memories, 0 for register type devices with only one
  119. * register)
  120. * buffer: Where to read/write the data
  121. * len: How many bytes to read/write
  122. *
  123. * Returns: 0 on success, not 0 on failure
  124. */
  125. int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
  126. {
  127. int ret, pos;
  128. uchar paddr[4];
  129. struct fti2c010_regs *regs = curr->regs;
  130. i2c_init(0, 0);
  131. paddr[0] = (addr >> 0) & 0xFF;
  132. paddr[1] = (addr >> 8) & 0xFF;
  133. paddr[2] = (addr >> 16) & 0xFF;
  134. paddr[3] = (addr >> 24) & 0xFF;
  135. /*
  136. * Phase A. Set register address
  137. */
  138. /* A.1 Select slave device (7bits Address + 1bit R/W) */
  139. writel(I2C_WR(chip), &regs->dr);
  140. writel(CR_ENABLE | CR_TBEN | CR_START, &regs->cr);
  141. ret = fti2c010_wait(SR_DT);
  142. if (ret)
  143. return ret;
  144. /* A.2 Select device register */
  145. for (pos = 0; pos < alen; ++pos) {
  146. uint32_t ctrl = CR_ENABLE | CR_TBEN;
  147. writel(paddr[pos], &regs->dr);
  148. writel(ctrl, &regs->cr);
  149. ret = fti2c010_wait(SR_DT);
  150. if (ret)
  151. return ret;
  152. }
  153. /*
  154. * Phase B. Get register data
  155. */
  156. /* B.1 Select slave device (7bits Address + 1bit R/W) */
  157. writel(I2C_RD(chip), &regs->dr);
  158. writel(CR_ENABLE | CR_TBEN | CR_START, &regs->cr);
  159. ret = fti2c010_wait(SR_DT);
  160. if (ret)
  161. return ret;
  162. /* B.2 Get register data */
  163. for (pos = 0; pos < len; ++pos) {
  164. uint32_t ctrl = CR_ENABLE | CR_TBEN;
  165. uint32_t stat = SR_DR;
  166. if (pos == len - 1) {
  167. ctrl |= CR_NAK | CR_STOP;
  168. stat |= SR_ACK;
  169. }
  170. writel(ctrl, &regs->cr);
  171. ret = fti2c010_wait(stat);
  172. if (ret)
  173. break;
  174. buf[pos] = (uchar)(readl(&regs->dr) & 0xFF);
  175. }
  176. return ret;
  177. }
  178. /*
  179. * Read/Write interface:
  180. * chip: I2C chip address, range 0..127
  181. * addr: Memory (register) address within the chip
  182. * alen: Number of bytes to use for addr (typically 1, 2 for larger
  183. * memories, 0 for register type devices with only one
  184. * register)
  185. * buffer: Where to read/write the data
  186. * len: How many bytes to read/write
  187. *
  188. * Returns: 0 on success, not 0 on failure
  189. */
  190. int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)
  191. {
  192. int ret, pos;
  193. uchar paddr[4];
  194. struct fti2c010_regs *regs = curr->regs;
  195. i2c_init(0, 0);
  196. paddr[0] = (addr >> 0) & 0xFF;
  197. paddr[1] = (addr >> 8) & 0xFF;
  198. paddr[2] = (addr >> 16) & 0xFF;
  199. paddr[3] = (addr >> 24) & 0xFF;
  200. /*
  201. * Phase A. Set register address
  202. *
  203. * A.1 Select slave device (7bits Address + 1bit R/W)
  204. */
  205. writel(I2C_WR(chip), &regs->dr);
  206. writel(CR_ENABLE | CR_TBEN | CR_START, &regs->cr);
  207. ret = fti2c010_wait(SR_DT);
  208. if (ret)
  209. return ret;
  210. /* A.2 Select device register */
  211. for (pos = 0; pos < alen; ++pos) {
  212. uint32_t ctrl = CR_ENABLE | CR_TBEN;
  213. writel(paddr[pos], &regs->dr);
  214. writel(ctrl, &regs->cr);
  215. ret = fti2c010_wait(SR_DT);
  216. if (ret)
  217. return ret;
  218. }
  219. /*
  220. * Phase B. Set register data
  221. */
  222. for (pos = 0; pos < len; ++pos) {
  223. uint32_t ctrl = CR_ENABLE | CR_TBEN;
  224. if (pos == len - 1)
  225. ctrl |= CR_STOP;
  226. writel(buf[pos], &regs->dr);
  227. writel(ctrl, &regs->cr);
  228. ret = fti2c010_wait(SR_DT);
  229. if (ret)
  230. break;
  231. }
  232. return ret;
  233. }
  234. /*
  235. * Functions for setting the current I2C bus and its speed
  236. */
  237. #ifdef CONFIG_I2C_MULTI_BUS
  238. /*
  239. * i2c_set_bus_num:
  240. *
  241. * Change the active I2C bus. Subsequent read/write calls will
  242. * go to this one.
  243. *
  244. * bus - bus index, zero based
  245. *
  246. * Returns: 0 on success, not 0 on failure
  247. */
  248. int i2c_set_bus_num(uint bus)
  249. {
  250. if (bus >= ARRAY_SIZE(chip_list))
  251. return -1;
  252. curr = chip_list + bus;
  253. i2c_init(0, 0);
  254. return 0;
  255. }
  256. /*
  257. * i2c_get_bus_num:
  258. *
  259. * Returns index of currently active I2C bus. Zero-based.
  260. */
  261. uint i2c_get_bus_num(void)
  262. {
  263. return curr->bus;
  264. }
  265. #endif /* #ifdef CONFIG_I2C_MULTI_BUS */
  266. /*
  267. * i2c_set_bus_speed:
  268. *
  269. * Change the speed of the active I2C bus
  270. *
  271. * speed - bus speed in Hz
  272. *
  273. * Returns: 0 on success, not 0 on failure
  274. */
  275. int i2c_set_bus_speed(uint speed)
  276. {
  277. struct fti2c010_regs *regs = curr->regs;
  278. uint clk = CONFIG_FTI2C010_FREQ;
  279. uint gsr = 0, tsr = 32;
  280. uint spd, div;
  281. if (!speed)
  282. speed = CONFIG_SYS_I2C_SPEED;
  283. for (div = 0; div < 0x3ffff; ++div) {
  284. /* SCLout = PCLK/(2*(COUNT + 2) + GSR) */
  285. spd = clk / (2 * (div + 2) + gsr);
  286. if (spd <= speed)
  287. break;
  288. }
  289. if (curr->speed == spd)
  290. return 0;
  291. writel(CR_I2CRST, &regs->cr);
  292. mdelay(100);
  293. if (readl(&regs->cr) & CR_I2CRST) {
  294. printf("fti2c010: reset timeout\n");
  295. return -1;
  296. }
  297. curr->speed = spd;
  298. writel(TGSR_GSR(gsr) | TGSR_TSR(tsr), &regs->tgsr);
  299. writel(CDR_DIV(div), &regs->cdr);
  300. return 0;
  301. }
  302. /*
  303. * i2c_get_bus_speed:
  304. *
  305. * Returns speed of currently active I2C bus in Hz
  306. */
  307. uint i2c_get_bus_speed(void)
  308. {
  309. return curr->speed;
  310. }