omap_i2c.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470
  1. /*
  2. * TI OMAP on-chip I2C controller. Only "new I2C" mode supported.
  3. *
  4. * Copyright (C) 2007 Andrzej Zaborowski <balrog@zabor.org>
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License as
  8. * published by the Free Software Foundation; either version 2 of
  9. * the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program; if not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "hw.h"
  20. #include "i2c.h"
  21. #include "omap.h"
  22. struct omap_i2c_s {
  23. qemu_irq irq;
  24. qemu_irq drq[2];
  25. i2c_bus *bus;
  26. uint8_t revision;
  27. uint8_t mask;
  28. uint16_t stat;
  29. uint16_t dma;
  30. uint16_t count;
  31. int count_cur;
  32. uint32_t fifo;
  33. int rxlen;
  34. int txlen;
  35. uint16_t control;
  36. uint16_t addr[2];
  37. uint8_t divider;
  38. uint8_t times[2];
  39. uint16_t test;
  40. };
  41. #define OMAP2_INTR_REV 0x34
  42. #define OMAP2_GC_REV 0x34
  43. static void omap_i2c_interrupts_update(struct omap_i2c_s *s)
  44. {
  45. qemu_set_irq(s->irq, s->stat & s->mask);
  46. if ((s->dma >> 15) & 1) /* RDMA_EN */
  47. qemu_set_irq(s->drq[0], (s->stat >> 3) & 1); /* RRDY */
  48. if ((s->dma >> 7) & 1) /* XDMA_EN */
  49. qemu_set_irq(s->drq[1], (s->stat >> 4) & 1); /* XRDY */
  50. }
  51. static void omap_i2c_fifo_run(struct omap_i2c_s *s)
  52. {
  53. int ack = 1;
  54. if (!i2c_bus_busy(s->bus))
  55. return;
  56. if ((s->control >> 2) & 1) { /* RM */
  57. if ((s->control >> 1) & 1) { /* STP */
  58. i2c_end_transfer(s->bus);
  59. s->control &= ~(1 << 1); /* STP */
  60. s->count_cur = s->count;
  61. s->txlen = 0;
  62. } else if ((s->control >> 9) & 1) { /* TRX */
  63. while (ack && s->txlen)
  64. ack = (i2c_send(s->bus,
  65. (s->fifo >> ((-- s->txlen) << 3)) &
  66. 0xff) >= 0);
  67. s->stat |= 1 << 4; /* XRDY */
  68. } else {
  69. while (s->rxlen < 4)
  70. s->fifo |= i2c_recv(s->bus) << ((s->rxlen ++) << 3);
  71. s->stat |= 1 << 3; /* RRDY */
  72. }
  73. } else {
  74. if ((s->control >> 9) & 1) { /* TRX */
  75. while (ack && s->count_cur && s->txlen) {
  76. ack = (i2c_send(s->bus,
  77. (s->fifo >> ((-- s->txlen) << 3)) &
  78. 0xff) >= 0);
  79. s->count_cur --;
  80. }
  81. if (ack && s->count_cur)
  82. s->stat |= 1 << 4; /* XRDY */
  83. else
  84. s->stat &= ~(1 << 4); /* XRDY */
  85. if (!s->count_cur) {
  86. s->stat |= 1 << 2; /* ARDY */
  87. s->control &= ~(1 << 10); /* MST */
  88. }
  89. } else {
  90. while (s->count_cur && s->rxlen < 4) {
  91. s->fifo |= i2c_recv(s->bus) << ((s->rxlen ++) << 3);
  92. s->count_cur --;
  93. }
  94. if (s->rxlen)
  95. s->stat |= 1 << 3; /* RRDY */
  96. else
  97. s->stat &= ~(1 << 3); /* RRDY */
  98. }
  99. if (!s->count_cur) {
  100. if ((s->control >> 1) & 1) { /* STP */
  101. i2c_end_transfer(s->bus);
  102. s->control &= ~(1 << 1); /* STP */
  103. s->count_cur = s->count;
  104. s->txlen = 0;
  105. } else {
  106. s->stat |= 1 << 2; /* ARDY */
  107. s->control &= ~(1 << 10); /* MST */
  108. }
  109. }
  110. }
  111. s->stat |= (!ack) << 1; /* NACK */
  112. if (!ack)
  113. s->control &= ~(1 << 1); /* STP */
  114. }
  115. void omap_i2c_reset(struct omap_i2c_s *s)
  116. {
  117. s->mask = 0;
  118. s->stat = 0;
  119. s->dma = 0;
  120. s->count = 0;
  121. s->count_cur = 0;
  122. s->fifo = 0;
  123. s->rxlen = 0;
  124. s->txlen = 0;
  125. s->control = 0;
  126. s->addr[0] = 0;
  127. s->addr[1] = 0;
  128. s->divider = 0;
  129. s->times[0] = 0;
  130. s->times[1] = 0;
  131. s->test = 0;
  132. }
  133. static uint32_t omap_i2c_read(void *opaque, target_phys_addr_t addr)
  134. {
  135. struct omap_i2c_s *s = (struct omap_i2c_s *) opaque;
  136. int offset = addr & OMAP_MPUI_REG_MASK;
  137. uint16_t ret;
  138. switch (offset) {
  139. case 0x00: /* I2C_REV */
  140. return s->revision; /* REV */
  141. case 0x04: /* I2C_IE */
  142. return s->mask;
  143. case 0x08: /* I2C_STAT */
  144. return s->stat | (i2c_bus_busy(s->bus) << 12);
  145. case 0x0c: /* I2C_IV */
  146. if (s->revision >= OMAP2_INTR_REV)
  147. break;
  148. ret = ffs(s->stat & s->mask);
  149. if (ret)
  150. s->stat ^= 1 << (ret - 1);
  151. omap_i2c_interrupts_update(s);
  152. return ret;
  153. case 0x10: /* I2C_SYSS */
  154. return (s->control >> 15) & 1; /* I2C_EN */
  155. case 0x14: /* I2C_BUF */
  156. return s->dma;
  157. case 0x18: /* I2C_CNT */
  158. return s->count_cur; /* DCOUNT */
  159. case 0x1c: /* I2C_DATA */
  160. ret = 0;
  161. if (s->control & (1 << 14)) { /* BE */
  162. ret |= ((s->fifo >> 0) & 0xff) << 8;
  163. ret |= ((s->fifo >> 8) & 0xff) << 0;
  164. } else {
  165. ret |= ((s->fifo >> 8) & 0xff) << 8;
  166. ret |= ((s->fifo >> 0) & 0xff) << 0;
  167. }
  168. if (s->rxlen == 1) {
  169. s->stat |= 1 << 15; /* SBD */
  170. s->rxlen = 0;
  171. } else if (s->rxlen > 1) {
  172. if (s->rxlen > 2)
  173. s->fifo >>= 16;
  174. s->rxlen -= 2;
  175. } else {
  176. /* XXX: remote access (qualifier) error - what's that? */
  177. }
  178. if (!s->rxlen) {
  179. s->stat &= ~(1 << 3); /* RRDY */
  180. if (((s->control >> 10) & 1) && /* MST */
  181. ((~s->control >> 9) & 1)) { /* TRX */
  182. s->stat |= 1 << 2; /* ARDY */
  183. s->control &= ~(1 << 10); /* MST */
  184. }
  185. }
  186. s->stat &= ~(1 << 11); /* ROVR */
  187. omap_i2c_fifo_run(s);
  188. omap_i2c_interrupts_update(s);
  189. return ret;
  190. case 0x20: /* I2C_SYSC */
  191. return 0;
  192. case 0x24: /* I2C_CON */
  193. return s->control;
  194. case 0x28: /* I2C_OA */
  195. return s->addr[0];
  196. case 0x2c: /* I2C_SA */
  197. return s->addr[1];
  198. case 0x30: /* I2C_PSC */
  199. return s->divider;
  200. case 0x34: /* I2C_SCLL */
  201. return s->times[0];
  202. case 0x38: /* I2C_SCLH */
  203. return s->times[1];
  204. case 0x3c: /* I2C_SYSTEST */
  205. if (s->test & (1 << 15)) { /* ST_EN */
  206. s->test ^= 0xa;
  207. return s->test;
  208. } else
  209. return s->test & ~0x300f;
  210. }
  211. OMAP_BAD_REG(addr);
  212. return 0;
  213. }
  214. static void omap_i2c_write(void *opaque, target_phys_addr_t addr,
  215. uint32_t value)
  216. {
  217. struct omap_i2c_s *s = (struct omap_i2c_s *) opaque;
  218. int offset = addr & OMAP_MPUI_REG_MASK;
  219. int nack;
  220. switch (offset) {
  221. case 0x00: /* I2C_REV */
  222. case 0x0c: /* I2C_IV */
  223. case 0x10: /* I2C_SYSS */
  224. OMAP_RO_REG(addr);
  225. return;
  226. case 0x04: /* I2C_IE */
  227. s->mask = value & (s->revision < OMAP2_GC_REV ? 0x1f : 0x3f);
  228. break;
  229. case 0x08: /* I2C_STAT */
  230. if (s->revision < OMAP2_INTR_REV) {
  231. OMAP_RO_REG(addr);
  232. return;
  233. }
  234. /* RRDY and XRDY are reset by hardware. (in all versions???) */
  235. s->stat &= ~(value & 0x27);
  236. omap_i2c_interrupts_update(s);
  237. break;
  238. case 0x14: /* I2C_BUF */
  239. s->dma = value & 0x8080;
  240. if (value & (1 << 15)) /* RDMA_EN */
  241. s->mask &= ~(1 << 3); /* RRDY_IE */
  242. if (value & (1 << 7)) /* XDMA_EN */
  243. s->mask &= ~(1 << 4); /* XRDY_IE */
  244. break;
  245. case 0x18: /* I2C_CNT */
  246. s->count = value; /* DCOUNT */
  247. break;
  248. case 0x1c: /* I2C_DATA */
  249. if (s->txlen > 2) {
  250. /* XXX: remote access (qualifier) error - what's that? */
  251. break;
  252. }
  253. s->fifo <<= 16;
  254. s->txlen += 2;
  255. if (s->control & (1 << 14)) { /* BE */
  256. s->fifo |= ((value >> 8) & 0xff) << 8;
  257. s->fifo |= ((value >> 0) & 0xff) << 0;
  258. } else {
  259. s->fifo |= ((value >> 0) & 0xff) << 8;
  260. s->fifo |= ((value >> 8) & 0xff) << 0;
  261. }
  262. s->stat &= ~(1 << 10); /* XUDF */
  263. if (s->txlen > 2)
  264. s->stat &= ~(1 << 4); /* XRDY */
  265. omap_i2c_fifo_run(s);
  266. omap_i2c_interrupts_update(s);
  267. break;
  268. case 0x20: /* I2C_SYSC */
  269. if (s->revision < OMAP2_INTR_REV) {
  270. OMAP_BAD_REG(addr);
  271. return;
  272. }
  273. if (value & 2)
  274. omap_i2c_reset(s);
  275. break;
  276. case 0x24: /* I2C_CON */
  277. s->control = value & 0xcf87;
  278. if (~value & (1 << 15)) { /* I2C_EN */
  279. if (s->revision < OMAP2_INTR_REV)
  280. omap_i2c_reset(s);
  281. break;
  282. }
  283. if ((value & (1 << 15)) && !(value & (1 << 10))) { /* MST */
  284. fprintf(stderr, "%s: I^2C slave mode not supported\n",
  285. __FUNCTION__);
  286. break;
  287. }
  288. if ((value & (1 << 15)) && value & (1 << 8)) { /* XA */
  289. fprintf(stderr, "%s: 10-bit addressing mode not supported\n",
  290. __FUNCTION__);
  291. break;
  292. }
  293. if ((value & (1 << 15)) && value & (1 << 0)) { /* STT */
  294. nack = !!i2c_start_transfer(s->bus, s->addr[1], /* SA */
  295. (~value >> 9) & 1); /* TRX */
  296. s->stat |= nack << 1; /* NACK */
  297. s->control &= ~(1 << 0); /* STT */
  298. s->fifo = 0;
  299. if (nack)
  300. s->control &= ~(1 << 1); /* STP */
  301. else {
  302. s->count_cur = s->count;
  303. omap_i2c_fifo_run(s);
  304. }
  305. omap_i2c_interrupts_update(s);
  306. }
  307. break;
  308. case 0x28: /* I2C_OA */
  309. s->addr[0] = value & 0x3ff;
  310. break;
  311. case 0x2c: /* I2C_SA */
  312. s->addr[1] = value & 0x3ff;
  313. break;
  314. case 0x30: /* I2C_PSC */
  315. s->divider = value;
  316. break;
  317. case 0x34: /* I2C_SCLL */
  318. s->times[0] = value;
  319. break;
  320. case 0x38: /* I2C_SCLH */
  321. s->times[1] = value;
  322. break;
  323. case 0x3c: /* I2C_SYSTEST */
  324. s->test = value & 0xf80f;
  325. if (value & (1 << 11)) /* SBB */
  326. if (s->revision >= OMAP2_INTR_REV) {
  327. s->stat |= 0x3f;
  328. omap_i2c_interrupts_update(s);
  329. }
  330. if (value & (1 << 15)) /* ST_EN */
  331. fprintf(stderr, "%s: System Test not supported\n", __FUNCTION__);
  332. break;
  333. default:
  334. OMAP_BAD_REG(addr);
  335. return;
  336. }
  337. }
  338. static void omap_i2c_writeb(void *opaque, target_phys_addr_t addr,
  339. uint32_t value)
  340. {
  341. struct omap_i2c_s *s = (struct omap_i2c_s *) opaque;
  342. int offset = addr & OMAP_MPUI_REG_MASK;
  343. switch (offset) {
  344. case 0x1c: /* I2C_DATA */
  345. if (s->txlen > 2) {
  346. /* XXX: remote access (qualifier) error - what's that? */
  347. break;
  348. }
  349. s->fifo <<= 8;
  350. s->txlen += 1;
  351. s->fifo |= value & 0xff;
  352. s->stat &= ~(1 << 10); /* XUDF */
  353. if (s->txlen > 2)
  354. s->stat &= ~(1 << 4); /* XRDY */
  355. omap_i2c_fifo_run(s);
  356. omap_i2c_interrupts_update(s);
  357. break;
  358. default:
  359. OMAP_BAD_REG(addr);
  360. return;
  361. }
  362. }
  363. static CPUReadMemoryFunc * const omap_i2c_readfn[] = {
  364. omap_badwidth_read16,
  365. omap_i2c_read,
  366. omap_badwidth_read16,
  367. };
  368. static CPUWriteMemoryFunc * const omap_i2c_writefn[] = {
  369. omap_i2c_writeb, /* Only the last fifo write can be 8 bit. */
  370. omap_i2c_write,
  371. omap_badwidth_write16,
  372. };
  373. struct omap_i2c_s *omap_i2c_init(target_phys_addr_t base,
  374. qemu_irq irq, qemu_irq *dma, omap_clk clk)
  375. {
  376. int iomemtype;
  377. struct omap_i2c_s *s = (struct omap_i2c_s *)
  378. qemu_mallocz(sizeof(struct omap_i2c_s));
  379. /* TODO: set a value greater or equal to real hardware */
  380. s->revision = 0x11;
  381. s->irq = irq;
  382. s->drq[0] = dma[0];
  383. s->drq[1] = dma[1];
  384. s->bus = i2c_init_bus(NULL, "i2c");
  385. omap_i2c_reset(s);
  386. iomemtype = cpu_register_io_memory(omap_i2c_readfn,
  387. omap_i2c_writefn, s, DEVICE_NATIVE_ENDIAN);
  388. cpu_register_physical_memory(base, 0x800, iomemtype);
  389. return s;
  390. }
  391. struct omap_i2c_s *omap2_i2c_init(struct omap_target_agent_s *ta,
  392. qemu_irq irq, qemu_irq *dma, omap_clk fclk, omap_clk iclk)
  393. {
  394. int iomemtype;
  395. struct omap_i2c_s *s = (struct omap_i2c_s *)
  396. qemu_mallocz(sizeof(struct omap_i2c_s));
  397. s->revision = 0x34;
  398. s->irq = irq;
  399. s->drq[0] = dma[0];
  400. s->drq[1] = dma[1];
  401. s->bus = i2c_init_bus(NULL, "i2c");
  402. omap_i2c_reset(s);
  403. iomemtype = l4_register_io_memory(omap_i2c_readfn,
  404. omap_i2c_writefn, s);
  405. omap_l4_attach(ta, 0, iomemtype);
  406. return s;
  407. }
  408. i2c_bus *omap_i2c_bus(struct omap_i2c_s *s)
  409. {
  410. return s->bus;
  411. }