2 * TI OMAP on-chip I2C controller. Only "new I2C" mode supported.
4 * Copyright (C) 2007 Andrzej Zaborowski <balrog@zabor.org>
5 * Copyright (C) 2009 Nokia Corporation
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 #define I2C_MAX_FIFO_SIZE (1 << 6)
26 #define I2C_FIFO_SIZE_MASK ((I2C_MAX_FIFO_SIZE) - 1)
52 uint8_t fifo[I2C_MAX_FIFO_SIZE];
55 #define OMAP2_INTR_REV 0x34
56 #define OMAP2_GC_REV 0x34
57 #define OMAP3_INTR_REV 0x3c
61 #define TRACE(fmt, ...) fprintf(stderr, "%s " fmt "\n", __FUNCTION__, ##__VA_ARGS__)
66 static void omap_i2c_interrupts_update(struct omap_i2c_s *s)
68 TRACE("IRQ=%04x,RDRQ=%d,XDRQ=%d",
70 ((s->dma >> 15 ) & 1) & ((s->stat >> 3) & 1),
71 ((s->dma >> 7 ) & 1 )& ((s->stat >> 4 ) & 1));
72 qemu_set_irq(s->irq, s->stat & s->mask);
73 if ((s->dma >> 15) & 1) /* RDMA_EN */
74 qemu_set_irq(s->drq[0], (s->stat >> 3) & 1); /* RRDY */
75 if ((s->dma >> 7) & 1) /* XDMA_EN */
76 qemu_set_irq(s->drq[1], (s->stat >> 4) & 1); /* XRDY */
79 /* These are only stubs now. */
80 static void omap_i2c_event(i2c_slave *i2c, enum i2c_event event)
82 fprintf(stderr, "%s: I^2C slave mode not supported\n", __FUNCTION__);
84 /* code below is broken, i2c_slave CANNOT be cast to omap_i2c_s! */
86 //struct omap_i2c_s *s = (struct omap_i2c_s *) i2c;
88 //if ((~s->control >> 15) & 1) /* I2C_EN */
92 // case I2C_START_SEND:
93 // case I2C_START_RECV:
94 // s->stat |= 1 << 9; /* AAS */
97 // s->stat |= 1 << 2; /* ARDY */
100 // s->stat |= 1 << 1; /* NACK */
106 //omap_i2c_interrupts_update(s);
109 static int omap_i2c_rx(i2c_slave *i2c)
111 fprintf(stderr, "%s: I^2C slave mode not supported\n", __FUNCTION__);
114 /* code below is broken, i2c_slave CANNOT be cast to omap_i2c_s! */
116 //struct omap_i2c_s *s = (struct omap_i2c_s *) i2c;
119 //if ((~s->control >> 15) & 1) /* I2C_EN */
122 //if (s->rxlen < s->txlen)
123 // ret = s->fifo[s->rxlen++];
125 // s->stat |= 1 << 10; /* XUDF */
126 //s->stat |= 1 << 4; /* XRDY */
128 //omap_i2c_interrupts_update(s);
132 static int omap_i2c_tx(i2c_slave *i2c, uint8_t data)
134 fprintf(stderr, "%s: I^2C slave mode not supported\n", __FUNCTION__);
137 /* code below is broken, i2c_slave CANNOT be cast to omap_i2c_s! */
139 //struct omap_i2c_s *s = (struct omap_i2c_s *) i2c;
141 //if ((~s->control >> 15) & 1) /* I2C_EN */
144 //if (s->txlen < s->fifosize)
145 // s->fifo[s->txlen++] = data;
147 // s->stat |= 1 << 11; /* ROVR */
148 //s->stat |= 1 << 3; /* RRDY */
150 //omap_i2c_interrupts_update(s);
154 static void omap_i2c_fifo_run(struct omap_i2c_s *s)
158 if (!i2c_bus_busy(s->bus))
161 if ((s->control >> 2) & 1) { /* RM */
162 if ((s->control >> 1) & 1) { /* STP */
163 i2c_end_transfer(s->bus);
164 s->control &= ~(1 << 1); /* STP */
165 s->count_cur = s->count;
167 } else if ((s->control >> 9) & 1) { /* TRX */
168 while (ack && s->fifolen) {
169 ack = (i2c_send(s->bus, s->fifo[s->fifostart++]) >= 0);
170 s->fifostart &= I2C_FIFO_SIZE_MASK;
174 s->stat |= 1 << 4; /* XRDY */
176 for (i = 0; i < 4; i++)
177 s->fifo[(s->fifostart + i) & I2C_FIFO_SIZE_MASK] =
180 s->stat |= 1 << 3; /* RRDY */
183 if ((s->control >> 9) & 1) { /* TRX */
184 TRACE("master transmit, count_cur=%d, fifolen=%d",
185 s->count_cur, s->fifolen);
186 for (; ack && s->count_cur && s->fifolen; s->count_cur--) {
187 ack = (i2c_send(s->bus, s->fifo[s->fifostart++]) >= 0);
188 s->fifostart &= I2C_FIFO_SIZE_MASK;
191 s->stat &= ~0x4410; /* XDR | XUDF | XRDY */
192 if (ack && s->count_cur) { /* send more? */
193 /* we know that FIFO is empty */
194 if (s->revision < OMAP3_INTR_REV)
195 s->stat |= 1 << 4; /* XRDY */
197 if (s->count_cur > (s->dma & 0x3f)) /* XTRSH */
198 s->stat |= 1 << 4; /* XRDY */
200 s->stat |= 1 << 14; /* XDR */
203 if (!s->count_cur) /* everything sent? */
204 s->stat |= 1 << 2; /* ARDY */
206 TRACE("master receive");
207 for (; s->count_cur && s->fifolen < s->fifosize; s->count_cur--) {
208 i = i2c_recv(s->bus);
209 if (i < 0) break; /* stop receiving if nothing to receive */
210 s->fifo[(s->fifostart + s->fifolen++) & I2C_FIFO_SIZE_MASK] =
212 TRACE("received fifo[%02x] = %02x", s->fifolen - 1,
213 s->fifo[(s->fifostart + s->fifolen - 1) & I2C_FIFO_SIZE_MASK]);
215 s->stat &= ~((1 << 3) | (1 << 13)); /* RRDY | RDR */
217 if (s->revision < OMAP3_INTR_REV)
218 s->stat |= 1 << 3; /* RRDY */
220 if (s->fifolen > ((s->dma >> 8) & 0x3f)) /* RTRSH */
221 s->stat |= 1 << 3; /* RRDY */
223 s->stat |= 1 << 13; /* RDR */
225 } else if (!s->count_cur && (s->control & 2)) /* STP */
226 s->stat |= 1 << 2; /* ARDY */
229 TRACE("no more data to transmit/receive");
230 if ((s->control >> 1) & 1) { /* STP */
231 i2c_end_transfer(s->bus);
232 s->control &= ~0x0602; /* MST | TRX | STP */
233 s->count_cur = s->count;
238 s->stat |= (!ack) << 1; /* NACK */
240 s->control &= ~(1 << 1); /* STP */
241 TRACE("finished, STAT = %04x, CNT = %d", s->stat, s->count_cur);
244 void omap_i2c_reset(struct omap_i2c_s *s)
268 static uint32_t omap_i2c_read(void *opaque, target_phys_addr_t addr)
270 struct omap_i2c_s *s = (struct omap_i2c_s *) opaque;
271 int offset = addr & OMAP_MPUI_REG_MASK;
275 case 0x00: /* I2C_REV */
276 TRACE("REV returns %04x", s->revision);
278 case 0x04: /* I2C_IE */
279 TRACE("IE returns %04x", s->mask);
281 case 0x08: /* I2C_STAT */
282 TRACE("STAT returns %04x", s->stat | (i2c_bus_busy(s->bus) << 12));
283 return s->stat | (i2c_bus_busy(s->bus) << 12);
284 case 0x0c: /* I2C_IV / I2C_WE */
285 if (s->revision >= OMAP3_INTR_REV)
287 if (s->revision >= OMAP2_INTR_REV)
289 ret = ffs(s->stat & s->mask);
291 s->stat ^= 1 << (ret - 1);
292 omap_i2c_interrupts_update(s);
294 case 0x10: /* I2C_SYSS */
295 return (s->control >> 15) & 1; /* reset completed == I2C_EN */
296 case 0x14: /* I2C_BUF */
297 TRACE("BUF returns %04x", s->dma);
299 case 0x18: /* I2C_CNT */
300 TRACE("CNT returns %04x", s->count_cur);
301 return s->count_cur; /* DCOUNT */
302 case 0x1c: /* I2C_DATA */
305 if (s->revision < OMAP3_INTR_REV) {
306 if (s->control & (1 << 14)) /* BE */
307 ret = (((uint16_t)s->fifo[s->fifostart]) << 8)
308 | s->fifo[(s->fifostart + 1) & I2C_FIFO_SIZE_MASK];
310 ret = (((uint16_t)s->fifo[(s->fifostart + 1) & I2C_FIFO_SIZE_MASK]) << 8)
311 | s->fifo[s->fifostart];
312 s->fifostart = (s->fifostart + 2) & I2C_FIFO_SIZE_MASK;
313 if (s->fifolen == 1) {
314 s->stat |= 1 << 15; /* SBD */
319 s->stat &= ~(1 << 3); /* RRDY */
320 s->stat |= 1 << 2; /* ARDY */
323 s->stat &= ~(1 << 7); /* AERR */
324 ret = s->fifo[s->fifostart++];
325 s->fifostart &= I2C_FIFO_SIZE_MASK;
327 if (s->fifolen < ((s->dma & 0x3f) >> 8)) {
328 s->stat &= ~(1 << 3); /* RRDY */
329 s->stat |= 1 << 13; /* RDR */
332 s->stat &= ~((1 << 3) | (1 << 13)); /* RRDY | RDR */
333 s->stat |= 1 << 2; /* ARDY */
336 s->stat &= ~(1 << 11); /* ROVR */
337 } else if (s->revision >= OMAP3_INTR_REV)
338 s->stat |= (1 << 7); /* AERR */
339 TRACE("DATA returns %04x", ret);
340 omap_i2c_fifo_run(s);
341 omap_i2c_interrupts_update(s);
343 case 0x20: /* I2C_SYSC */
344 TRACE("SYSC returns %04x", s->sysc);
346 case 0x24: /* I2C_CON */
347 TRACE("CON returns %04x", s->control);
349 case 0x28: /* I2C_OA / I2C_OA0 */
350 return s->own_addr[0];
351 case 0x2c: /* I2C_SA */
352 return s->slave_addr;
353 case 0x30: /* I2C_PSC */
355 case 0x34: /* I2C_SCLL */
357 case 0x38: /* I2C_SCLH */
359 case 0x3c: /* I2C_SYSTEST */
360 if (s->test & (1 << 15)) { /* ST_EN */
364 return s->test & ~0x300f;
365 case 0x40: /* I2C_BUFSTAT */
366 if (s->revision >= OMAP3_INTR_REV) {
367 switch (s->fifosize) {
368 case 8: ret = 0x0000; break;
369 case 16: ret = 0x4000; break;
370 case 32: ret = 0x8000; break;
371 case 64: ret = 0xc000; break;
372 default: ret = 0x0000; break;
374 ret |= ((s->fifolen) & 0x3f) << 8; /* RXSTAT */
375 ret |= (s->count_cur) & 0x3f; /* TXSTAT */
376 TRACE("BUFSTAT returns %04x", ret);
380 case 0x44: /* I2C_OA1 */
381 case 0x48: /* I2C_OA2 */
382 case 0x4c: /* I2C_OA3 */
383 if (s->revision >= OMAP3_INTR_REV)
384 return s->own_addr[(addr >> 2) & 3];
386 case 0x50: /* I2C_ACTOA */
387 if (s->revision >= OMAP3_INTR_REV)
388 return 0; /* TODO: determine accessed slave own address */
390 case 0x54: /* I2C_SBLOCK */
391 if (s->revision >= OMAP3_INTR_REV)
402 static void omap_i2c_write(void *opaque, target_phys_addr_t addr,
405 struct omap_i2c_s *s = (struct omap_i2c_s *) opaque;
406 int offset = addr & OMAP_MPUI_REG_MASK;
410 case 0x00: /* I2C_REV */
411 case 0x10: /* I2C_SYSS */
412 case 0x40: /* I2C_BUFSTAT */
413 case 0x50: /* I2C_ACTOA */
416 case 0x04: /* I2C_IE */
417 TRACE("IE = %04x", value);
418 if (s->revision >= OMAP3_INTR_REV)
419 s->mask = value & 0x63ff;
421 s->mask = value & (s->revision < OMAP2_GC_REV ? 0x1f : 0x3f);
422 omap_i2c_interrupts_update(s);
424 case 0x08: /* I2C_STAT */
425 if (s->revision < OMAP2_INTR_REV)
428 TRACE("STAT = %04x", value);
429 /* RRDY and XRDY are reset by hardware. (in all versions???) */
430 s->stat &= ~(value & (s->revision < OMAP3_INTR_REV ? 0x27 : 0x63e7));
431 omap_i2c_interrupts_update(s);
434 case 0x0c: /* I2C_IV / I2C_WE */
435 if (s->revision < OMAP3_INTR_REV)
438 s->we = value & 0x636f;
440 case 0x14: /* I2C_BUF */
441 TRACE("BUF = %04x", value);
442 if (s->revision < OMAP3_INTR_REV)
443 s->dma = value & 0x8080;
445 s->dma = value & 0xbfbf;
446 if ((value & (1 << 14)) /* RXFIFO_CLR */
447 || (value & (1 << 6))) /* TXFIFO_CLR */
450 if (value & (1 << 15)) /* RDMA_EN */
451 s->mask &= ~(1 << 3); /* RRDY_IE */
452 if (value & (1 << 7)) /* XDMA_EN */
453 s->mask &= ~(1 << 4); /* XRDY_IE */
455 case 0x18: /* I2C_CNT */
456 TRACE("CNT = %04x", value);
457 s->count = value; /* DCOUNT */
459 case 0x1c: /* I2C_DATA */
460 TRACE("DATA = %04x", value);
461 if (s->revision < OMAP3_INTR_REV) {
462 if (s->fifolen > 2) {
463 /* XXX: remote access (qualifier) error - what's that? */
466 if (s->control & (1 << 14)) { /* BE */
467 s->fifo[(s->fifostart + s->fifolen++) & I2C_FIFO_SIZE_MASK] =
468 (uint8_t)((value >> 8) & 0xff);
469 s->fifo[(s->fifostart + s->fifolen++) & I2C_FIFO_SIZE_MASK] =
470 (uint8_t)(value & 0xff);
472 s->fifo[(s->fifostart + s->fifolen++) & I2C_FIFO_SIZE_MASK] =
473 (uint8_t)(value & 0xff);
474 s->fifo[(s->fifostart + s->fifolen++) & I2C_FIFO_SIZE_MASK] =
475 (uint8_t)((value >> 8) & 0xff);
478 if (s->fifolen < s->fifosize) {
479 s->stat &= ~(1 << 7); /* AERR */
480 s->fifo[(s->fifostart + s->fifolen++) & I2C_FIFO_SIZE_MASK] =
481 (uint8_t)(value & 0xff);
483 s->stat |= (1 << 7); /* AERR */
485 s->stat &= ~(1 << 10); /* XUDF */
486 omap_i2c_fifo_run(s);
487 omap_i2c_interrupts_update(s);
489 case 0x20: /* I2C_SYSC */
490 if (s->revision < OMAP2_INTR_REV) {
494 TRACE("SYSC = %04x", value);
497 else if (s->revision >= OMAP3_INTR_REV)
498 s->sysc = value & 0x031d;
500 case 0x24: /* I2C_CON */
501 TRACE("CON = %04x", value);
502 s->control = value & (s->revision < OMAP3_INTR_REV ? 0xcf87 : 0xbff3);
503 if (~value & (1 << 15)) { /* I2C_EN */
504 if (s->revision < OMAP2_INTR_REV)
508 if (s->revision >= OMAP3_INTR_REV && ((value >> 12) & 3) > 1) { /* OPMODE */
510 "%s: only FS and HS modes are supported\n",
514 if ((value & (1 << 10))) { /* MST */
515 if (value & 1) { /* STT */
516 nack = !!i2c_start_transfer(s->bus, s->slave_addr, /*SA*/
517 (~value >> 9) & 1); /*TRX*/
518 s->stat |= nack << 1; /* NACK */
519 s->control &= ~(1 << 0); /* STT */
522 s->control &= ~(1 << 1); /* STP */
524 s->count_cur = s->count;
525 omap_i2c_fifo_run(s);
527 omap_i2c_interrupts_update(s);
528 } else if (value & 2) { /* STP, but not STT */
529 i2c_end_transfer(s->bus);
530 s->control &= ~0x0602; /* MST | TRX | STP */
531 s->count_cur = s->count;
535 case 0x28: /* I2C_OA / I2C_OA0 */
536 TRACE("OA0 = %04x", value);
537 s->own_addr[0] = value & (s->revision < OMAP3_INTR_REV
539 i2c_set_slave_address(&s->slave[0],
540 value & (s->revision >= OMAP3_INTR_REV
541 && (s->control & 0x80)
544 case 0x2c: /* I2C_SA */
545 TRACE("SA = %04x", value);
546 s->slave_addr = value & 0x3ff;
548 case 0x30: /* I2C_PSC */
551 case 0x34: /* I2C_SCLL */
552 s->times[0] = value & (s->revision < OMAP3_INTR_REV
555 case 0x38: /* I2C_SCLH */
556 s->times[1] = value & (s->revision < OMAP3_INTR_REV
559 case 0x3c: /* I2C_SYSTEST */
560 value &= s->revision < OMAP3_INTR_REV ? 0xf805 : 0xf815;
561 if ((value & (1 << 15))) { /* ST_EN */
562 fprintf(stderr, "%s: System Test not supported\n",
564 s->test = (s->test & 0x0a) | value;
566 s->test = (s->test & 0x1f) | (value & 0xf800);
567 if (value & (1 << 11)) /* SBB */
568 if (s->revision >= OMAP2_INTR_REV) {
570 if (s->revision >= OMAP3_INTR_REV)
572 omap_i2c_interrupts_update(s);
575 case 0x44: /* I2C_OA1 */
576 case 0x48: /* I2C_OA2 */
577 case 0x4c: /* I2C_OA3 */
578 if (s->revision < OMAP3_INTR_REV)
581 addr = (addr >> 2) & 3;
582 TRACE("OA%d = %04x", (int)addr, value);
583 s->own_addr[addr] = value & 0x3ff;
584 i2c_set_slave_address(&s->slave[addr],
585 value & ((s->control & (0x80 >> addr))
589 case 0x54: /* I2C_SBLOCK */
590 if (s->revision < OMAP3_INTR_REV)
593 s->sblock = value & 0x0f;
602 static void omap_i2c_writeb(void *opaque, target_phys_addr_t addr,
605 struct omap_i2c_s *s = (struct omap_i2c_s *) opaque;
606 int offset = addr & OMAP_MPUI_REG_MASK;
609 case 0x1c: /* I2C_DATA */
610 TRACE("DATA = %02x", value);
611 if (s->revision < OMAP3_INTR_REV && s->fifolen > 2) {
612 /* XXX: remote access (qualifier) error - what's that? */
615 if (s->fifolen < s->fifosize) {
616 s->fifo[(s->fifostart + s->fifolen++) & I2C_FIFO_SIZE_MASK] =
617 (uint8_t)(value & 0xff);
618 if (s->revision >= OMAP3_INTR_REV)
619 s->stat &= ~(1 << 7); /* AERR */
620 s->stat &= ~(1 << 10); /* XUDF */
621 omap_i2c_fifo_run(s);
622 } else if (s->revision >= OMAP3_INTR_REV)
623 s->stat |= (1 << 7); /* AERR */
624 omap_i2c_interrupts_update(s);
632 static CPUReadMemoryFunc *omap_i2c_readfn[] = {
633 omap_badwidth_read16,
635 omap_badwidth_read16,
638 static CPUWriteMemoryFunc *omap_i2c_writefn[] = {
639 omap_i2c_writeb, /* Only the last fifo write can be 8 bit. */
641 omap_badwidth_write16,
644 static void omap_i2c_save_state(QEMUFile *f, void *opaque)
646 struct omap_i2c_s *s = (struct omap_i2c_s *)opaque;
648 /* TODO: slave setup(s) */
649 qemu_put_be16(f, s->mask);
650 qemu_put_be16(f, s->stat);
651 qemu_put_be16(f, s->we);
652 qemu_put_be16(f, s->dma);
653 qemu_put_be16(f, s->count);
654 qemu_put_sbe32(f, s->count_cur);
655 qemu_put_be16(f, s->sysc);
656 qemu_put_be16(f, s->control);
657 qemu_put_be16(f, s->own_addr[0]);
658 qemu_put_be16(f, s->own_addr[1]);
659 qemu_put_be16(f, s->own_addr[2]);
660 qemu_put_be16(f, s->own_addr[3]);
661 qemu_put_be16(f, s->slave_addr);
662 qemu_put_byte(f, s->sblock);
663 qemu_put_byte(f, s->divider);
664 qemu_put_be16(f, s->times[0]);
665 qemu_put_be16(f, s->times[1]);
666 qemu_put_be16(f, s->test);
667 qemu_put_sbe32(f, s->fifostart);
668 qemu_put_sbe32(f, s->fifolen);
669 qemu_put_sbe32(f, s->fifosize);
670 qemu_put_buffer(f, s->fifo, sizeof(s->fifo));
673 static int omap_i2c_load_state(QEMUFile *f, void *opaque, int version_id)
675 struct omap_i2c_s *s = (struct omap_i2c_s *)opaque;
680 /* TODO: slave setup(s) */
681 s->mask = qemu_get_be16(f);
682 s->stat = qemu_get_be16(f);
683 s->we = qemu_get_be16(f);
684 s->dma = qemu_get_be16(f);
685 s->count = qemu_get_be16(f);
686 s->count_cur = qemu_get_sbe32(f);
687 s->sysc = qemu_get_be16(f);
688 s->control = qemu_get_be16(f);
689 s->own_addr[0] = qemu_get_be16(f);
690 s->own_addr[1] = qemu_get_be16(f);
691 s->own_addr[2] = qemu_get_be16(f);
692 s->own_addr[3] = qemu_get_be16(f);
693 s->slave_addr = qemu_get_be16(f);
694 s->sblock = qemu_get_byte(f);
695 s->divider = qemu_get_byte(f);
696 s->times[0] = qemu_get_be16(f);
697 s->times[1] = qemu_get_be16(f);
698 s->test = qemu_get_be16(f);
699 s->fifostart = qemu_get_sbe32(f);
700 s->fifolen = qemu_get_sbe32(f);
701 s->fifosize = qemu_get_sbe32(f);
702 qemu_get_buffer(f, s->fifo, sizeof(s->fifo));
704 omap_i2c_interrupts_update(s);
709 static struct omap_i2c_s *omap_i2c_common_init(uint8_t rev, int fifosize,
710 qemu_irq irq, qemu_irq *dma)
712 struct omap_i2c_s *s = (struct omap_i2c_s *)
713 qemu_mallocz(sizeof(struct omap_i2c_s));
715 if (fifosize > I2C_MAX_FIFO_SIZE) {
716 fprintf(stderr, "%s: maximum FIFO size is %d (tried to use %d)\n",
717 __FUNCTION__, I2C_MAX_FIFO_SIZE, fifosize);
724 s->slave[0].event = s->slave[1].event = s->slave[2].event =
725 s->slave[3].event = omap_i2c_event;
726 s->slave[0].recv = s->slave[1].recv = s->slave[2].recv =
727 s->slave[3].recv = omap_i2c_rx;
728 s->slave[0].send = s->slave[1].send = s->slave[2].send =
729 s->slave[3].send = omap_i2c_tx;
730 s->bus = i2c_init_bus();
731 s->fifosize = fifosize;
736 struct omap_i2c_s *omap_i2c_init(target_phys_addr_t base,
737 qemu_irq irq, qemu_irq *dma, omap_clk clk)
739 struct omap_i2c_s *s = omap_i2c_common_init(0x11, 4, irq, dma);
741 cpu_register_physical_memory(base, 0x800,
742 cpu_register_io_memory(0, omap_i2c_readfn,
743 omap_i2c_writefn, s));
747 struct omap_i2c_s *omap2_i2c_init(struct omap_target_agent_s *ta,
748 qemu_irq irq, qemu_irq *dma, omap_clk fclk, omap_clk iclk)
750 struct omap_i2c_s *s = omap_i2c_common_init(0x34, 4, irq, dma);
752 omap_l4_attach(ta, 0, l4_register_io_memory(0, omap_i2c_readfn,
753 omap_i2c_writefn, s));
757 struct omap_i2c_s *omap3_i2c_init(struct omap_target_agent_s *ta,
758 qemu_irq irq, qemu_irq *dma,
759 omap_clk fclk, omap_clk iclk,
762 struct omap_i2c_s *s;
764 if (fifosize != 8 && fifosize != 16 && fifosize != 32 && fifosize != 64) {
765 fprintf(stderr, "%s: unsupported FIFO depth specified (%d)\n",
766 __FUNCTION__, fifosize);
769 s = omap_i2c_common_init(OMAP3_INTR_REV, fifosize, irq, dma);
771 omap_l4_attach(ta, 0, l4_register_io_memory(0, omap_i2c_readfn,
772 omap_i2c_writefn, s));
773 register_savevm("omap3_i2c", (ta->base >> 12) & 0xff, 0,
774 omap_i2c_save_state, omap_i2c_load_state, s);
778 i2c_bus *omap_i2c_bus(struct omap_i2c_s *s)