2
0

omap_i2c.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  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 "qemu/osdep.h"
  20. #include "qemu/log.h"
  21. #include "qemu/module.h"
  22. #include "hw/i2c/i2c.h"
  23. #include "hw/irq.h"
  24. #include "hw/qdev-properties.h"
  25. #include "hw/arm/omap.h"
  26. #include "hw/sysbus.h"
  27. #include "qemu/error-report.h"
  28. #include "qapi/error.h"
  29. struct OMAPI2CState {
  30. SysBusDevice parent_obj;
  31. MemoryRegion iomem;
  32. qemu_irq irq;
  33. qemu_irq drq[2];
  34. I2CBus *bus;
  35. uint8_t revision;
  36. void *iclk;
  37. void *fclk;
  38. uint8_t mask;
  39. uint16_t stat;
  40. uint16_t dma;
  41. uint16_t count;
  42. int count_cur;
  43. uint32_t fifo;
  44. int rxlen;
  45. int txlen;
  46. uint16_t control;
  47. uint16_t addr[2];
  48. uint8_t divider;
  49. uint8_t times[2];
  50. uint16_t test;
  51. };
  52. #define OMAP2_INTR_REV 0x34
  53. #define OMAP2_GC_REV 0x34
  54. static void omap_i2c_interrupts_update(OMAPI2CState *s)
  55. {
  56. qemu_set_irq(s->irq, s->stat & s->mask);
  57. if ((s->dma >> 15) & 1) /* RDMA_EN */
  58. qemu_set_irq(s->drq[0], (s->stat >> 3) & 1); /* RRDY */
  59. if ((s->dma >> 7) & 1) /* XDMA_EN */
  60. qemu_set_irq(s->drq[1], (s->stat >> 4) & 1); /* XRDY */
  61. }
  62. static void omap_i2c_fifo_run(OMAPI2CState *s)
  63. {
  64. int ack = 1;
  65. if (!i2c_bus_busy(s->bus))
  66. return;
  67. if ((s->control >> 2) & 1) { /* RM */
  68. if ((s->control >> 1) & 1) { /* STP */
  69. i2c_end_transfer(s->bus);
  70. s->control &= ~(1 << 1); /* STP */
  71. s->count_cur = s->count;
  72. s->txlen = 0;
  73. } else if ((s->control >> 9) & 1) { /* TRX */
  74. while (ack && s->txlen)
  75. ack = (i2c_send(s->bus,
  76. (s->fifo >> ((-- s->txlen) << 3)) &
  77. 0xff) >= 0);
  78. s->stat |= 1 << 4; /* XRDY */
  79. } else {
  80. while (s->rxlen < 4)
  81. s->fifo |= i2c_recv(s->bus) << ((s->rxlen ++) << 3);
  82. s->stat |= 1 << 3; /* RRDY */
  83. }
  84. } else {
  85. if ((s->control >> 9) & 1) { /* TRX */
  86. while (ack && s->count_cur && s->txlen) {
  87. ack = (i2c_send(s->bus,
  88. (s->fifo >> ((-- s->txlen) << 3)) &
  89. 0xff) >= 0);
  90. s->count_cur --;
  91. }
  92. if (ack && s->count_cur)
  93. s->stat |= 1 << 4; /* XRDY */
  94. else
  95. s->stat &= ~(1 << 4); /* XRDY */
  96. if (!s->count_cur) {
  97. s->stat |= 1 << 2; /* ARDY */
  98. s->control &= ~(1 << 10); /* MST */
  99. }
  100. } else {
  101. while (s->count_cur && s->rxlen < 4) {
  102. s->fifo |= i2c_recv(s->bus) << ((s->rxlen ++) << 3);
  103. s->count_cur --;
  104. }
  105. if (s->rxlen)
  106. s->stat |= 1 << 3; /* RRDY */
  107. else
  108. s->stat &= ~(1 << 3); /* RRDY */
  109. }
  110. if (!s->count_cur) {
  111. if ((s->control >> 1) & 1) { /* STP */
  112. i2c_end_transfer(s->bus);
  113. s->control &= ~(1 << 1); /* STP */
  114. s->count_cur = s->count;
  115. s->txlen = 0;
  116. } else {
  117. s->stat |= 1 << 2; /* ARDY */
  118. s->control &= ~(1 << 10); /* MST */
  119. }
  120. }
  121. }
  122. s->stat |= (!ack) << 1; /* NACK */
  123. if (!ack)
  124. s->control &= ~(1 << 1); /* STP */
  125. }
  126. static void omap_i2c_reset(DeviceState *dev)
  127. {
  128. OMAPI2CState *s = OMAP_I2C(dev);
  129. s->mask = 0;
  130. s->stat = 0;
  131. s->dma = 0;
  132. s->count = 0;
  133. s->count_cur = 0;
  134. s->fifo = 0;
  135. s->rxlen = 0;
  136. s->txlen = 0;
  137. s->control = 0;
  138. s->addr[0] = 0;
  139. s->addr[1] = 0;
  140. s->divider = 0;
  141. s->times[0] = 0;
  142. s->times[1] = 0;
  143. s->test = 0;
  144. }
  145. static uint32_t omap_i2c_read(void *opaque, hwaddr addr)
  146. {
  147. OMAPI2CState *s = opaque;
  148. int offset = addr & OMAP_MPUI_REG_MASK;
  149. uint16_t ret;
  150. switch (offset) {
  151. case 0x00: /* I2C_REV */
  152. return s->revision; /* REV */
  153. case 0x04: /* I2C_IE */
  154. return s->mask;
  155. case 0x08: /* I2C_STAT */
  156. return s->stat | (i2c_bus_busy(s->bus) << 12);
  157. case 0x0c: /* I2C_IV */
  158. if (s->revision >= OMAP2_INTR_REV)
  159. break;
  160. ret = ctz32(s->stat & s->mask);
  161. if (ret != 32) {
  162. s->stat ^= 1 << ret;
  163. ret++;
  164. } else {
  165. ret = 0;
  166. }
  167. omap_i2c_interrupts_update(s);
  168. return ret;
  169. case 0x10: /* I2C_SYSS */
  170. return (s->control >> 15) & 1; /* I2C_EN */
  171. case 0x14: /* I2C_BUF */
  172. return s->dma;
  173. case 0x18: /* I2C_CNT */
  174. return s->count_cur; /* DCOUNT */
  175. case 0x1c: /* I2C_DATA */
  176. ret = 0;
  177. if (s->control & (1 << 14)) { /* BE */
  178. ret |= ((s->fifo >> 0) & 0xff) << 8;
  179. ret |= ((s->fifo >> 8) & 0xff) << 0;
  180. } else {
  181. ret |= ((s->fifo >> 8) & 0xff) << 8;
  182. ret |= ((s->fifo >> 0) & 0xff) << 0;
  183. }
  184. if (s->rxlen == 1) {
  185. s->stat |= 1 << 15; /* SBD */
  186. s->rxlen = 0;
  187. } else if (s->rxlen > 1) {
  188. if (s->rxlen > 2)
  189. s->fifo >>= 16;
  190. s->rxlen -= 2;
  191. } else {
  192. /* XXX: remote access (qualifier) error - what's that? */
  193. }
  194. if (!s->rxlen) {
  195. s->stat &= ~(1 << 3); /* RRDY */
  196. if (((s->control >> 10) & 1) && /* MST */
  197. ((~s->control >> 9) & 1)) { /* TRX */
  198. s->stat |= 1 << 2; /* ARDY */
  199. s->control &= ~(1 << 10); /* MST */
  200. }
  201. }
  202. s->stat &= ~(1 << 11); /* ROVR */
  203. omap_i2c_fifo_run(s);
  204. omap_i2c_interrupts_update(s);
  205. return ret;
  206. case 0x20: /* I2C_SYSC */
  207. return 0;
  208. case 0x24: /* I2C_CON */
  209. return s->control;
  210. case 0x28: /* I2C_OA */
  211. return s->addr[0];
  212. case 0x2c: /* I2C_SA */
  213. return s->addr[1];
  214. case 0x30: /* I2C_PSC */
  215. return s->divider;
  216. case 0x34: /* I2C_SCLL */
  217. return s->times[0];
  218. case 0x38: /* I2C_SCLH */
  219. return s->times[1];
  220. case 0x3c: /* I2C_SYSTEST */
  221. if (s->test & (1 << 15)) { /* ST_EN */
  222. s->test ^= 0xa;
  223. return s->test;
  224. } else
  225. return s->test & ~0x300f;
  226. }
  227. OMAP_BAD_REG(addr);
  228. return 0;
  229. }
  230. static void omap_i2c_write(void *opaque, hwaddr addr,
  231. uint32_t value)
  232. {
  233. OMAPI2CState *s = opaque;
  234. int offset = addr & OMAP_MPUI_REG_MASK;
  235. int nack;
  236. switch (offset) {
  237. case 0x00: /* I2C_REV */
  238. case 0x0c: /* I2C_IV */
  239. case 0x10: /* I2C_SYSS */
  240. OMAP_RO_REG(addr);
  241. return;
  242. case 0x04: /* I2C_IE */
  243. s->mask = value & (s->revision < OMAP2_GC_REV ? 0x1f : 0x3f);
  244. break;
  245. case 0x08: /* I2C_STAT */
  246. if (s->revision < OMAP2_INTR_REV) {
  247. OMAP_RO_REG(addr);
  248. return;
  249. }
  250. /* RRDY and XRDY are reset by hardware. (in all versions???) */
  251. s->stat &= ~(value & 0x27);
  252. omap_i2c_interrupts_update(s);
  253. break;
  254. case 0x14: /* I2C_BUF */
  255. s->dma = value & 0x8080;
  256. if (value & (1 << 15)) /* RDMA_EN */
  257. s->mask &= ~(1 << 3); /* RRDY_IE */
  258. if (value & (1 << 7)) /* XDMA_EN */
  259. s->mask &= ~(1 << 4); /* XRDY_IE */
  260. break;
  261. case 0x18: /* I2C_CNT */
  262. s->count = value; /* DCOUNT */
  263. break;
  264. case 0x1c: /* I2C_DATA */
  265. if (s->txlen > 2) {
  266. /* XXX: remote access (qualifier) error - what's that? */
  267. break;
  268. }
  269. s->fifo <<= 16;
  270. s->txlen += 2;
  271. if (s->control & (1 << 14)) { /* BE */
  272. s->fifo |= ((value >> 8) & 0xff) << 8;
  273. s->fifo |= ((value >> 0) & 0xff) << 0;
  274. } else {
  275. s->fifo |= ((value >> 0) & 0xff) << 8;
  276. s->fifo |= ((value >> 8) & 0xff) << 0;
  277. }
  278. s->stat &= ~(1 << 10); /* XUDF */
  279. if (s->txlen > 2)
  280. s->stat &= ~(1 << 4); /* XRDY */
  281. omap_i2c_fifo_run(s);
  282. omap_i2c_interrupts_update(s);
  283. break;
  284. case 0x20: /* I2C_SYSC */
  285. if (s->revision < OMAP2_INTR_REV) {
  286. OMAP_BAD_REG(addr);
  287. return;
  288. }
  289. if (value & 2) {
  290. omap_i2c_reset(DEVICE(s));
  291. }
  292. break;
  293. case 0x24: /* I2C_CON */
  294. s->control = value & 0xcf87;
  295. if (~value & (1 << 15)) { /* I2C_EN */
  296. if (s->revision < OMAP2_INTR_REV) {
  297. omap_i2c_reset(DEVICE(s));
  298. }
  299. break;
  300. }
  301. if ((value & (1 << 15)) && !(value & (1 << 10))) { /* MST */
  302. qemu_log_mask(LOG_UNIMP, "%s: I^2C slave mode not supported\n",
  303. __func__);
  304. break;
  305. }
  306. if ((value & (1 << 15)) && value & (1 << 8)) { /* XA */
  307. qemu_log_mask(LOG_UNIMP,
  308. "%s: 10-bit addressing mode not supported\n",
  309. __func__);
  310. break;
  311. }
  312. if ((value & (1 << 15)) && value & (1 << 0)) { /* STT */
  313. nack = !!i2c_start_transfer(s->bus, s->addr[1], /* SA */
  314. (~value >> 9) & 1); /* TRX */
  315. s->stat |= nack << 1; /* NACK */
  316. s->control &= ~(1 << 0); /* STT */
  317. s->fifo = 0;
  318. if (nack)
  319. s->control &= ~(1 << 1); /* STP */
  320. else {
  321. s->count_cur = s->count;
  322. omap_i2c_fifo_run(s);
  323. }
  324. omap_i2c_interrupts_update(s);
  325. }
  326. break;
  327. case 0x28: /* I2C_OA */
  328. s->addr[0] = value & 0x3ff;
  329. break;
  330. case 0x2c: /* I2C_SA */
  331. s->addr[1] = value & 0x3ff;
  332. break;
  333. case 0x30: /* I2C_PSC */
  334. s->divider = value;
  335. break;
  336. case 0x34: /* I2C_SCLL */
  337. s->times[0] = value;
  338. break;
  339. case 0x38: /* I2C_SCLH */
  340. s->times[1] = value;
  341. break;
  342. case 0x3c: /* I2C_SYSTEST */
  343. s->test = value & 0xf80f;
  344. if (value & (1 << 11)) /* SBB */
  345. if (s->revision >= OMAP2_INTR_REV) {
  346. s->stat |= 0x3f;
  347. omap_i2c_interrupts_update(s);
  348. }
  349. if (value & (1 << 15)) { /* ST_EN */
  350. qemu_log_mask(LOG_UNIMP,
  351. "%s: System Test not supported\n", __func__);
  352. }
  353. break;
  354. default:
  355. OMAP_BAD_REG(addr);
  356. return;
  357. }
  358. }
  359. static void omap_i2c_writeb(void *opaque, hwaddr addr,
  360. uint32_t value)
  361. {
  362. OMAPI2CState *s = opaque;
  363. int offset = addr & OMAP_MPUI_REG_MASK;
  364. switch (offset) {
  365. case 0x1c: /* I2C_DATA */
  366. if (s->txlen > 2) {
  367. /* XXX: remote access (qualifier) error - what's that? */
  368. break;
  369. }
  370. s->fifo <<= 8;
  371. s->txlen += 1;
  372. s->fifo |= value & 0xff;
  373. s->stat &= ~(1 << 10); /* XUDF */
  374. if (s->txlen > 2)
  375. s->stat &= ~(1 << 4); /* XRDY */
  376. omap_i2c_fifo_run(s);
  377. omap_i2c_interrupts_update(s);
  378. break;
  379. default:
  380. OMAP_BAD_REG(addr);
  381. return;
  382. }
  383. }
  384. static uint64_t omap_i2c_readfn(void *opaque, hwaddr addr,
  385. unsigned size)
  386. {
  387. switch (size) {
  388. case 2:
  389. return omap_i2c_read(opaque, addr);
  390. default:
  391. return omap_badwidth_read16(opaque, addr);
  392. }
  393. }
  394. static void omap_i2c_writefn(void *opaque, hwaddr addr,
  395. uint64_t value, unsigned size)
  396. {
  397. switch (size) {
  398. case 1:
  399. /* Only the last fifo write can be 8 bit. */
  400. omap_i2c_writeb(opaque, addr, value);
  401. break;
  402. case 2:
  403. omap_i2c_write(opaque, addr, value);
  404. break;
  405. default:
  406. omap_badwidth_write16(opaque, addr, value);
  407. break;
  408. }
  409. }
  410. static const MemoryRegionOps omap_i2c_ops = {
  411. .read = omap_i2c_readfn,
  412. .write = omap_i2c_writefn,
  413. .valid.min_access_size = 1,
  414. .valid.max_access_size = 4,
  415. .endianness = DEVICE_NATIVE_ENDIAN,
  416. };
  417. static void omap_i2c_init(Object *obj)
  418. {
  419. DeviceState *dev = DEVICE(obj);
  420. OMAPI2CState *s = OMAP_I2C(obj);
  421. SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
  422. sysbus_init_irq(sbd, &s->irq);
  423. sysbus_init_irq(sbd, &s->drq[0]);
  424. sysbus_init_irq(sbd, &s->drq[1]);
  425. sysbus_init_mmio(sbd, &s->iomem);
  426. s->bus = i2c_init_bus(dev, NULL);
  427. }
  428. static void omap_i2c_realize(DeviceState *dev, Error **errp)
  429. {
  430. OMAPI2CState *s = OMAP_I2C(dev);
  431. memory_region_init_io(&s->iomem, OBJECT(dev), &omap_i2c_ops, s, "omap.i2c",
  432. (s->revision < OMAP2_INTR_REV) ? 0x800 : 0x1000);
  433. if (!s->fclk) {
  434. error_setg(errp, "omap_i2c: fclk not connected");
  435. return;
  436. }
  437. if (s->revision >= OMAP2_INTR_REV && !s->iclk) {
  438. /* Note that OMAP1 doesn't have a separate interface clock */
  439. error_setg(errp, "omap_i2c: iclk not connected");
  440. return;
  441. }
  442. }
  443. void omap_i2c_set_iclk(OMAPI2CState *i2c, omap_clk clk)
  444. {
  445. i2c->iclk = clk;
  446. }
  447. void omap_i2c_set_fclk(OMAPI2CState *i2c, omap_clk clk)
  448. {
  449. i2c->fclk = clk;
  450. }
  451. static Property omap_i2c_properties[] = {
  452. DEFINE_PROP_UINT8("revision", OMAPI2CState, revision, 0),
  453. DEFINE_PROP_END_OF_LIST(),
  454. };
  455. static void omap_i2c_class_init(ObjectClass *klass, void *data)
  456. {
  457. DeviceClass *dc = DEVICE_CLASS(klass);
  458. device_class_set_props(dc, omap_i2c_properties);
  459. dc->reset = omap_i2c_reset;
  460. /* Reason: pointer properties "iclk", "fclk" */
  461. dc->user_creatable = false;
  462. dc->realize = omap_i2c_realize;
  463. }
  464. static const TypeInfo omap_i2c_info = {
  465. .name = TYPE_OMAP_I2C,
  466. .parent = TYPE_SYS_BUS_DEVICE,
  467. .instance_size = sizeof(OMAPI2CState),
  468. .instance_init = omap_i2c_init,
  469. .class_init = omap_i2c_class_init,
  470. };
  471. static void omap_i2c_register_types(void)
  472. {
  473. type_register_static(&omap_i2c_info);
  474. }
  475. I2CBus *omap_i2c_bus(DeviceState *omap_i2c)
  476. {
  477. OMAPI2CState *s = OMAP_I2C(omap_i2c);
  478. return s->bus;
  479. }
  480. type_init(omap_i2c_register_types)