2
0

omap_i2c.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537
  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, write to the Free Software Foundation, Inc.,
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  19. */
  20. #include "hw.h"
  21. #include "i2c.h"
  22. #include "omap.h"
  23. struct omap_i2c_s {
  24. qemu_irq irq;
  25. qemu_irq drq[2];
  26. i2c_slave slave;
  27. i2c_bus *bus;
  28. uint8_t revision;
  29. uint8_t mask;
  30. uint16_t stat;
  31. uint16_t dma;
  32. uint16_t count;
  33. int count_cur;
  34. uint32_t fifo;
  35. int rxlen;
  36. int txlen;
  37. uint16_t control;
  38. uint16_t addr[2];
  39. uint8_t divider;
  40. uint8_t times[2];
  41. uint16_t test;
  42. };
  43. #define OMAP2_INTR_REV 0x34
  44. #define OMAP2_GC_REV 0x34
  45. static void omap_i2c_interrupts_update(struct omap_i2c_s *s)
  46. {
  47. qemu_set_irq(s->irq, s->stat & s->mask);
  48. if ((s->dma >> 15) & 1) /* RDMA_EN */
  49. qemu_set_irq(s->drq[0], (s->stat >> 3) & 1); /* RRDY */
  50. if ((s->dma >> 7) & 1) /* XDMA_EN */
  51. qemu_set_irq(s->drq[1], (s->stat >> 4) & 1); /* XRDY */
  52. }
  53. /* These are only stubs now. */
  54. static void omap_i2c_event(i2c_slave *i2c, enum i2c_event event)
  55. {
  56. struct omap_i2c_s *s = (struct omap_i2c_s *) i2c;
  57. if ((~s->control >> 15) & 1) /* I2C_EN */
  58. return;
  59. switch (event) {
  60. case I2C_START_SEND:
  61. case I2C_START_RECV:
  62. s->stat |= 1 << 9; /* AAS */
  63. break;
  64. case I2C_FINISH:
  65. s->stat |= 1 << 2; /* ARDY */
  66. break;
  67. case I2C_NACK:
  68. s->stat |= 1 << 1; /* NACK */
  69. break;
  70. }
  71. omap_i2c_interrupts_update(s);
  72. }
  73. static int omap_i2c_rx(i2c_slave *i2c)
  74. {
  75. struct omap_i2c_s *s = (struct omap_i2c_s *) i2c;
  76. uint8_t ret = 0;
  77. if ((~s->control >> 15) & 1) /* I2C_EN */
  78. return -1;
  79. if (s->txlen)
  80. ret = s->fifo >> ((-- s->txlen) << 3) & 0xff;
  81. else
  82. s->stat |= 1 << 10; /* XUDF */
  83. s->stat |= 1 << 4; /* XRDY */
  84. omap_i2c_interrupts_update(s);
  85. return ret;
  86. }
  87. static int omap_i2c_tx(i2c_slave *i2c, uint8_t data)
  88. {
  89. struct omap_i2c_s *s = (struct omap_i2c_s *) i2c;
  90. if ((~s->control >> 15) & 1) /* I2C_EN */
  91. return 1;
  92. if (s->rxlen < 4)
  93. s->fifo |= data << ((s->rxlen ++) << 3);
  94. else
  95. s->stat |= 1 << 11; /* ROVR */
  96. s->stat |= 1 << 3; /* RRDY */
  97. omap_i2c_interrupts_update(s);
  98. return 1;
  99. }
  100. static void omap_i2c_fifo_run(struct omap_i2c_s *s)
  101. {
  102. int ack = 1;
  103. if (!i2c_bus_busy(s->bus))
  104. return;
  105. if ((s->control >> 2) & 1) { /* RM */
  106. if ((s->control >> 1) & 1) { /* STP */
  107. i2c_end_transfer(s->bus);
  108. s->control &= ~(1 << 1); /* STP */
  109. s->count_cur = s->count;
  110. s->txlen = 0;
  111. } else if ((s->control >> 9) & 1) { /* TRX */
  112. while (ack && s->txlen)
  113. ack = (i2c_send(s->bus,
  114. (s->fifo >> ((-- s->txlen) << 3)) &
  115. 0xff) >= 0);
  116. s->stat |= 1 << 4; /* XRDY */
  117. } else {
  118. while (s->rxlen < 4)
  119. s->fifo |= i2c_recv(s->bus) << ((s->rxlen ++) << 3);
  120. s->stat |= 1 << 3; /* RRDY */
  121. }
  122. } else {
  123. if ((s->control >> 9) & 1) { /* TRX */
  124. while (ack && s->count_cur && s->txlen) {
  125. ack = (i2c_send(s->bus,
  126. (s->fifo >> ((-- s->txlen) << 3)) &
  127. 0xff) >= 0);
  128. s->count_cur --;
  129. }
  130. if (ack && s->count_cur)
  131. s->stat |= 1 << 4; /* XRDY */
  132. else
  133. s->stat &= ~(1 << 4); /* XRDY */
  134. if (!s->count_cur) {
  135. s->stat |= 1 << 2; /* ARDY */
  136. s->control &= ~(1 << 10); /* MST */
  137. }
  138. } else {
  139. while (s->count_cur && s->rxlen < 4) {
  140. s->fifo |= i2c_recv(s->bus) << ((s->rxlen ++) << 3);
  141. s->count_cur --;
  142. }
  143. if (s->rxlen)
  144. s->stat |= 1 << 3; /* RRDY */
  145. else
  146. s->stat &= ~(1 << 3); /* RRDY */
  147. }
  148. if (!s->count_cur) {
  149. if ((s->control >> 1) & 1) { /* STP */
  150. i2c_end_transfer(s->bus);
  151. s->control &= ~(1 << 1); /* STP */
  152. s->count_cur = s->count;
  153. s->txlen = 0;
  154. } else {
  155. s->stat |= 1 << 2; /* ARDY */
  156. s->control &= ~(1 << 10); /* MST */
  157. }
  158. }
  159. }
  160. s->stat |= (!ack) << 1; /* NACK */
  161. if (!ack)
  162. s->control &= ~(1 << 1); /* STP */
  163. }
  164. void omap_i2c_reset(struct omap_i2c_s *s)
  165. {
  166. s->mask = 0;
  167. s->stat = 0;
  168. s->dma = 0;
  169. s->count = 0;
  170. s->count_cur = 0;
  171. s->fifo = 0;
  172. s->rxlen = 0;
  173. s->txlen = 0;
  174. s->control = 0;
  175. s->addr[0] = 0;
  176. s->addr[1] = 0;
  177. s->divider = 0;
  178. s->times[0] = 0;
  179. s->times[1] = 0;
  180. s->test = 0;
  181. }
  182. static uint32_t omap_i2c_read(void *opaque, target_phys_addr_t addr)
  183. {
  184. struct omap_i2c_s *s = (struct omap_i2c_s *) opaque;
  185. int offset = addr & OMAP_MPUI_REG_MASK;
  186. uint16_t ret;
  187. switch (offset) {
  188. case 0x00: /* I2C_REV */
  189. return s->revision; /* REV */
  190. case 0x04: /* I2C_IE */
  191. return s->mask;
  192. case 0x08: /* I2C_STAT */
  193. return s->stat | (i2c_bus_busy(s->bus) << 12);
  194. case 0x0c: /* I2C_IV */
  195. if (s->revision >= OMAP2_INTR_REV)
  196. break;
  197. ret = ffs(s->stat & s->mask);
  198. if (ret)
  199. s->stat ^= 1 << (ret - 1);
  200. omap_i2c_interrupts_update(s);
  201. return ret;
  202. case 0x10: /* I2C_SYSS */
  203. return (s->control >> 15) & 1; /* I2C_EN */
  204. case 0x14: /* I2C_BUF */
  205. return s->dma;
  206. case 0x18: /* I2C_CNT */
  207. return s->count_cur; /* DCOUNT */
  208. case 0x1c: /* I2C_DATA */
  209. ret = 0;
  210. if (s->control & (1 << 14)) { /* BE */
  211. ret |= ((s->fifo >> 0) & 0xff) << 8;
  212. ret |= ((s->fifo >> 8) & 0xff) << 0;
  213. } else {
  214. ret |= ((s->fifo >> 8) & 0xff) << 8;
  215. ret |= ((s->fifo >> 0) & 0xff) << 0;
  216. }
  217. if (s->rxlen == 1) {
  218. s->stat |= 1 << 15; /* SBD */
  219. s->rxlen = 0;
  220. } else if (s->rxlen > 1) {
  221. if (s->rxlen > 2)
  222. s->fifo >>= 16;
  223. s->rxlen -= 2;
  224. } else
  225. /* XXX: remote access (qualifier) error - what's that? */;
  226. if (!s->rxlen) {
  227. s->stat &= ~(1 << 3); /* RRDY */
  228. if (((s->control >> 10) & 1) && /* MST */
  229. ((~s->control >> 9) & 1)) { /* TRX */
  230. s->stat |= 1 << 2; /* ARDY */
  231. s->control &= ~(1 << 10); /* MST */
  232. }
  233. }
  234. s->stat &= ~(1 << 11); /* ROVR */
  235. omap_i2c_fifo_run(s);
  236. omap_i2c_interrupts_update(s);
  237. return ret;
  238. case 0x20: /* I2C_SYSC */
  239. return 0;
  240. case 0x24: /* I2C_CON */
  241. return s->control;
  242. case 0x28: /* I2C_OA */
  243. return s->addr[0];
  244. case 0x2c: /* I2C_SA */
  245. return s->addr[1];
  246. case 0x30: /* I2C_PSC */
  247. return s->divider;
  248. case 0x34: /* I2C_SCLL */
  249. return s->times[0];
  250. case 0x38: /* I2C_SCLH */
  251. return s->times[1];
  252. case 0x3c: /* I2C_SYSTEST */
  253. if (s->test & (1 << 15)) { /* ST_EN */
  254. s->test ^= 0xa;
  255. return s->test;
  256. } else
  257. return s->test & ~0x300f;
  258. }
  259. OMAP_BAD_REG(addr);
  260. return 0;
  261. }
  262. static void omap_i2c_write(void *opaque, target_phys_addr_t addr,
  263. uint32_t value)
  264. {
  265. struct omap_i2c_s *s = (struct omap_i2c_s *) opaque;
  266. int offset = addr & OMAP_MPUI_REG_MASK;
  267. int nack;
  268. switch (offset) {
  269. case 0x00: /* I2C_REV */
  270. case 0x0c: /* I2C_IV */
  271. case 0x10: /* I2C_SYSS */
  272. OMAP_RO_REG(addr);
  273. return;
  274. case 0x04: /* I2C_IE */
  275. s->mask = value & (s->revision < OMAP2_GC_REV ? 0x1f : 0x3f);
  276. break;
  277. case 0x08: /* I2C_STAT */
  278. if (s->revision < OMAP2_INTR_REV) {
  279. OMAP_RO_REG(addr);
  280. return;
  281. }
  282. /* RRDY and XRDY are reset by hardware. (in all versions???) */
  283. s->stat &= ~(value & 0x27);
  284. omap_i2c_interrupts_update(s);
  285. break;
  286. case 0x14: /* I2C_BUF */
  287. s->dma = value & 0x8080;
  288. if (value & (1 << 15)) /* RDMA_EN */
  289. s->mask &= ~(1 << 3); /* RRDY_IE */
  290. if (value & (1 << 7)) /* XDMA_EN */
  291. s->mask &= ~(1 << 4); /* XRDY_IE */
  292. break;
  293. case 0x18: /* I2C_CNT */
  294. s->count = value; /* DCOUNT */
  295. break;
  296. case 0x1c: /* I2C_DATA */
  297. if (s->txlen > 2) {
  298. /* XXX: remote access (qualifier) error - what's that? */
  299. break;
  300. }
  301. s->fifo <<= 16;
  302. s->txlen += 2;
  303. if (s->control & (1 << 14)) { /* BE */
  304. s->fifo |= ((value >> 8) & 0xff) << 8;
  305. s->fifo |= ((value >> 0) & 0xff) << 0;
  306. } else {
  307. s->fifo |= ((value >> 0) & 0xff) << 8;
  308. s->fifo |= ((value >> 8) & 0xff) << 0;
  309. }
  310. s->stat &= ~(1 << 10); /* XUDF */
  311. if (s->txlen > 2)
  312. s->stat &= ~(1 << 4); /* XRDY */
  313. omap_i2c_fifo_run(s);
  314. omap_i2c_interrupts_update(s);
  315. break;
  316. case 0x20: /* I2C_SYSC */
  317. if (s->revision < OMAP2_INTR_REV) {
  318. OMAP_BAD_REG(addr);
  319. return;
  320. }
  321. if (value & 2)
  322. omap_i2c_reset(s);
  323. break;
  324. case 0x24: /* I2C_CON */
  325. s->control = value & 0xcf87;
  326. if (~value & (1 << 15)) { /* I2C_EN */
  327. if (s->revision < OMAP2_INTR_REV)
  328. omap_i2c_reset(s);
  329. break;
  330. }
  331. if ((value & (1 << 15)) && !(value & (1 << 10))) { /* MST */
  332. fprintf(stderr, "%s: I^2C slave mode not supported\n",
  333. __FUNCTION__);
  334. break;
  335. }
  336. if ((value & (1 << 15)) && value & (1 << 8)) { /* XA */
  337. fprintf(stderr, "%s: 10-bit addressing mode not supported\n",
  338. __FUNCTION__);
  339. break;
  340. }
  341. if ((value & (1 << 15)) && value & (1 << 0)) { /* STT */
  342. nack = !!i2c_start_transfer(s->bus, s->addr[1], /* SA */
  343. (~value >> 9) & 1); /* TRX */
  344. s->stat |= nack << 1; /* NACK */
  345. s->control &= ~(1 << 0); /* STT */
  346. s->fifo = 0;
  347. if (nack)
  348. s->control &= ~(1 << 1); /* STP */
  349. else {
  350. s->count_cur = s->count;
  351. omap_i2c_fifo_run(s);
  352. }
  353. omap_i2c_interrupts_update(s);
  354. }
  355. break;
  356. case 0x28: /* I2C_OA */
  357. s->addr[0] = value & 0x3ff;
  358. i2c_set_slave_address(&s->slave, value & 0x7f);
  359. break;
  360. case 0x2c: /* I2C_SA */
  361. s->addr[1] = value & 0x3ff;
  362. break;
  363. case 0x30: /* I2C_PSC */
  364. s->divider = value;
  365. break;
  366. case 0x34: /* I2C_SCLL */
  367. s->times[0] = value;
  368. break;
  369. case 0x38: /* I2C_SCLH */
  370. s->times[1] = value;
  371. break;
  372. case 0x3c: /* I2C_SYSTEST */
  373. s->test = value & 0xf80f;
  374. if (value & (1 << 11)) /* SBB */
  375. if (s->revision >= OMAP2_INTR_REV) {
  376. s->stat |= 0x3f;
  377. omap_i2c_interrupts_update(s);
  378. }
  379. if (value & (1 << 15)) /* ST_EN */
  380. fprintf(stderr, "%s: System Test not supported\n", __FUNCTION__);
  381. break;
  382. default:
  383. OMAP_BAD_REG(addr);
  384. return;
  385. }
  386. }
  387. static void omap_i2c_writeb(void *opaque, target_phys_addr_t addr,
  388. uint32_t value)
  389. {
  390. struct omap_i2c_s *s = (struct omap_i2c_s *) opaque;
  391. int offset = addr & OMAP_MPUI_REG_MASK;
  392. switch (offset) {
  393. case 0x1c: /* I2C_DATA */
  394. if (s->txlen > 2) {
  395. /* XXX: remote access (qualifier) error - what's that? */
  396. break;
  397. }
  398. s->fifo <<= 8;
  399. s->txlen += 1;
  400. s->fifo |= value & 0xff;
  401. s->stat &= ~(1 << 10); /* XUDF */
  402. if (s->txlen > 2)
  403. s->stat &= ~(1 << 4); /* XRDY */
  404. omap_i2c_fifo_run(s);
  405. omap_i2c_interrupts_update(s);
  406. break;
  407. default:
  408. OMAP_BAD_REG(addr);
  409. return;
  410. }
  411. }
  412. static CPUReadMemoryFunc *omap_i2c_readfn[] = {
  413. omap_badwidth_read16,
  414. omap_i2c_read,
  415. omap_badwidth_read16,
  416. };
  417. static CPUWriteMemoryFunc *omap_i2c_writefn[] = {
  418. omap_i2c_writeb, /* Only the last fifo write can be 8 bit. */
  419. omap_i2c_write,
  420. omap_badwidth_write16,
  421. };
  422. struct omap_i2c_s *omap_i2c_init(target_phys_addr_t base,
  423. qemu_irq irq, qemu_irq *dma, omap_clk clk)
  424. {
  425. int iomemtype;
  426. struct omap_i2c_s *s = (struct omap_i2c_s *)
  427. qemu_mallocz(sizeof(struct omap_i2c_s));
  428. /* TODO: set a value greater or equal to real hardware */
  429. s->revision = 0x11;
  430. s->irq = irq;
  431. s->drq[0] = dma[0];
  432. s->drq[1] = dma[1];
  433. s->slave.event = omap_i2c_event;
  434. s->slave.recv = omap_i2c_rx;
  435. s->slave.send = omap_i2c_tx;
  436. s->bus = i2c_init_bus();
  437. omap_i2c_reset(s);
  438. iomemtype = cpu_register_io_memory(0, omap_i2c_readfn,
  439. omap_i2c_writefn, s);
  440. cpu_register_physical_memory(base, 0x800, iomemtype);
  441. return s;
  442. }
  443. struct omap_i2c_s *omap2_i2c_init(struct omap_target_agent_s *ta,
  444. qemu_irq irq, qemu_irq *dma, omap_clk fclk, omap_clk iclk)
  445. {
  446. int iomemtype;
  447. struct omap_i2c_s *s = (struct omap_i2c_s *)
  448. qemu_mallocz(sizeof(struct omap_i2c_s));
  449. s->revision = 0x34;
  450. s->irq = irq;
  451. s->drq[0] = dma[0];
  452. s->drq[1] = dma[1];
  453. s->slave.event = omap_i2c_event;
  454. s->slave.recv = omap_i2c_rx;
  455. s->slave.send = omap_i2c_tx;
  456. s->bus = i2c_init_bus();
  457. omap_i2c_reset(s);
  458. iomemtype = l4_register_io_memory(0, omap_i2c_readfn,
  459. omap_i2c_writefn, s);
  460. omap_l4_attach(ta, 0, iomemtype);
  461. return s;
  462. }
  463. i2c_bus *omap_i2c_bus(struct omap_i2c_s *s)
  464. {
  465. return s->bus;
  466. }