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, see <http://www.gnu.org/licenses/>.
21
#include "hw/i2c/i2c.h"
22
#include "hw/arm/omap.h"
23
#include "hw/sysbus.h"
25
#define TYPE_OMAP_I2C "omap_i2c"
26
#define OMAP_I2C(obj) OBJECT_CHECK(OMAPI2CState, (obj), TYPE_OMAP_I2C)
28
#define I2C_MAX_FIFO_SIZE (1 << 6)
29
#define I2C_FIFO_SIZE_MASK ((I2C_MAX_FIFO_SIZE) - 1)
31
typedef struct OMAPI2CState {
32
SysBusDevice parent_obj;
60
uint8_t fifo[I2C_MAX_FIFO_SIZE];
63
/* I2C controller revision register values */
64
#define OMAP1_INTR_REV 0x11
65
#define OMAP2_INTR_REV 0x34
66
#define OMAP3_INTR_REV 0x3c
67
#define OMAP3630_INTR_REV 0x40
69
static void omap_i2c_interrupts_update(OMAPI2CState *s)
71
qemu_set_irq(s->irq, s->stat & s->mask);
72
if ((s->dma >> 15) & 1) /* RDMA_EN */
73
qemu_set_irq(s->drq[0], (s->stat >> 3) & 1); /* RRDY */
74
if ((s->dma >> 7) & 1) /* XDMA_EN */
75
qemu_set_irq(s->drq[1], (s->stat >> 4) & 1); /* XRDY */
78
static void omap_i2c_fifo_run(OMAPI2CState *s)
82
if (!i2c_bus_busy(s->bus))
85
if ((s->control >> 2) & 1) { /* RM */
86
if ((s->control >> 1) & 1) { /* STP */
87
i2c_end_transfer(s->bus);
88
s->control &= ~(1 << 1); /* STP */
89
s->count_cur = s->count;
91
} else if ((s->control >> 9) & 1) { /* TRX */
92
while (ack && s->fifolen) {
93
ack = (i2c_send(s->bus, s->fifo[s->fifostart++]) >= 0);
94
s->fifostart &= I2C_FIFO_SIZE_MASK;
98
s->stat |= 1 << 4; /* XRDY */
100
for (i = 0; i < 4; i++)
101
s->fifo[(s->fifostart + i) & I2C_FIFO_SIZE_MASK] =
104
s->stat |= 1 << 3; /* RRDY */
107
if ((s->control >> 9) & 1) { /* TRX */
108
for (; ack && s->count_cur && s->fifolen; s->count_cur--) {
109
ack = (i2c_send(s->bus, s->fifo[s->fifostart++]) >= 0);
110
s->fifostart &= I2C_FIFO_SIZE_MASK;
113
s->stat &= ~0x4410; /* XDR | XUDF | XRDY */
114
if (ack && s->count_cur) { /* send more? */
115
/* we know that FIFO is empty */
116
if (s->revision < OMAP3_INTR_REV)
117
s->stat |= 1 << 4; /* XRDY */
119
if (s->count_cur > (s->dma & 0x3f)) /* XTRSH */
120
s->stat |= 1 << 4; /* XRDY */
122
s->stat |= 1 << 14; /* XDR */
125
if (!s->count_cur) /* everything sent? */
126
s->stat |= 1 << 2; /* ARDY */
128
for (; s->count_cur && s->fifolen < s->fifosize; s->count_cur--) {
129
i = i2c_recv(s->bus);
130
if (i < 0) break; /* stop receiving if nothing to receive */
131
s->fifo[(s->fifostart + s->fifolen++) & I2C_FIFO_SIZE_MASK] =
134
s->stat &= ~((1 << 3) | (1 << 13)); /* RRDY | RDR */
136
if (s->revision < OMAP3_INTR_REV)
137
s->stat |= 1 << 3; /* RRDY */
139
if (s->fifolen > ((s->dma >> 8) & 0x3f)) /* RTRSH */
140
s->stat |= 1 << 3; /* RRDY */
142
s->stat |= 1 << 13; /* RDR */
144
} else if (!s->count_cur && (s->control & 2)) /* STP */
145
s->stat |= 1 << 2; /* ARDY */
148
i2c_end_transfer(s->bus);
149
if ((s->control >> 1) & 1) { /* STP */
150
s->control &= ~0x0602; /* MST | TRX | STP */
151
s->count_cur = s->count;
156
s->stat |= (!ack) << 1; /* NACK */
158
s->control &= ~(1 << 1); /* STP */
161
static void omap_i2c_reset(DeviceState *dev)
163
OMAPI2CState *s = OMAP_I2C(dev);
186
i2c_end_transfer(s->bus);
189
static uint32_t omap_i2c_read(void *opaque, hwaddr addr)
191
OMAPI2CState *s = opaque;
192
int offset = addr & OMAP_MPUI_REG_MASK;
196
case 0x00: /* I2C_REV */
197
return s->revision; /* REV */
199
case 0x04: /* I2C_IE */
202
case 0x08: /* I2C_STAT */
203
ret = s->stat | (i2c_bus_busy(s->bus) << 12 );
204
if (s->revision >= OMAP3_INTR_REV && (s->stat & 0x4010)) /* XRDY or XDR */
205
s->stat |= 1 << 10; /* XUDF as required by errata 1.153 */
208
case 0x0c: /* I2C_IV / I2C_WE */
209
if (s->revision >= OMAP3_INTR_REV)
211
if (s->revision >= OMAP2_INTR_REV)
213
ret = ffs(s->stat & s->mask);
215
s->stat ^= 1 << (ret - 1);
216
omap_i2c_interrupts_update(s);
219
case 0x10: /* I2C_SYSS */
220
return (s->control >> 15) & 1; /* I2C_EN */
222
case 0x14: /* I2C_BUF */
225
case 0x18: /* I2C_CNT */
226
return s->count_cur; /* DCOUNT */
228
case 0x1c: /* I2C_DATA */
231
if (s->revision < OMAP3_INTR_REV) {
232
if (s->control & (1 << 14)) /* BE */
233
ret = (((uint16_t)s->fifo[s->fifostart]) << 8)
234
| s->fifo[(s->fifostart + 1) & I2C_FIFO_SIZE_MASK];
236
ret = (((uint16_t)s->fifo[(s->fifostart + 1) & I2C_FIFO_SIZE_MASK]) << 8)
237
| s->fifo[s->fifostart];
238
s->fifostart = (s->fifostart + 2) & I2C_FIFO_SIZE_MASK;
239
if (s->fifolen == 1) {
240
s->stat |= 1 << 15; /* SBD */
245
s->stat &= ~(1 << 3); /* RRDY */
246
s->stat |= 1 << 2; /* ARDY */
249
s->stat &= ~(1 << 7); /* AERR */
250
ret = s->fifo[s->fifostart++];
251
s->fifostart &= I2C_FIFO_SIZE_MASK;
253
if (s->fifolen <= ((s->dma >> 8) & 0x3f)) {
254
s->stat &= ~(1 << 3); /* RRDY */
255
s->stat |= 1 << 13; /* RDR */
258
s->stat &= ~((1 << 3) | (1 << 13)); /* RRDY | RDR */
259
s->stat |= 1 << 2; /* ARDY */
262
s->stat &= ~(1 << 11); /* ROVR */
263
} else if (s->revision >= OMAP3_INTR_REV)
264
s->stat |= (1 << 7); /* AERR */
265
omap_i2c_fifo_run(s);
266
omap_i2c_interrupts_update(s);
269
case 0x20: /* I2C_SYSC */
272
case 0x24: /* I2C_CON */
275
case 0x28: /* I2C_OA / I2C_OA0 */
276
return s->own_addr[0];
278
case 0x2c: /* I2C_SA */
279
return s->slave_addr;
281
case 0x30: /* I2C_PSC */
284
case 0x34: /* I2C_SCLL */
287
case 0x38: /* I2C_SCLH */
290
case 0x3c: /* I2C_SYSTEST */
291
if (s->test & (1 << 15)) { /* ST_EN */
295
return s->test & ~0x300f;
296
case 0x40: /* I2C_BUFSTAT */
297
if (s->revision >= OMAP3_INTR_REV) {
298
switch (s->fifosize) {
299
case 8: ret = 0x0000; break;
300
case 16: ret = 0x4000; break;
301
case 32: ret = 0x8000; break;
302
case 64: ret = 0xc000; break;
303
default: ret = 0x0000; break;
305
ret |= ((s->fifolen) & 0x3f) << 8; /* RXSTAT */
306
ret |= (s->count_cur) & 0x3f; /* TXSTAT */
310
case 0x44: /* I2C_OA1 */
311
case 0x48: /* I2C_OA2 */
312
case 0x4c: /* I2C_OA3 */
313
if (s->revision >= OMAP3_INTR_REV)
314
return s->own_addr[(addr >> 2) & 3];
316
case 0x50: /* I2C_ACTOA */
317
if (s->revision >= OMAP3_INTR_REV)
318
return 0; /* TODO: determine accessed slave own address */
320
case 0x54: /* I2C_SBLOCK */
321
if (s->revision >= OMAP3_INTR_REV)
332
static uint32_t omap_i2c_readb(void *opaque, hwaddr addr)
334
OMAPI2CState *s = opaque;
335
int offset = addr & OMAP_MPUI_REG_MASK;
339
case 0x1c: /* I2C_DATA */
342
if (s->revision < OMAP3_INTR_REV) {
343
if (s->control & (1 << 14)) /* BE */
344
ret = (((uint8_t)s->fifo[s->fifostart]) << 8)
345
| s->fifo[(s->fifostart + 1) & I2C_FIFO_SIZE_MASK];
347
ret = (((uint8_t)s->fifo[(s->fifostart + 1) & I2C_FIFO_SIZE_MASK]) << 8)
348
| s->fifo[s->fifostart];
349
s->fifostart = (s->fifostart + 2) & I2C_FIFO_SIZE_MASK;
350
if (s->fifolen == 1) {
351
s->stat |= 1 << 15; /* SBD */
356
s->stat &= ~(1 << 3); /* RRDY */
357
s->stat |= 1 << 2; /* ARDY */
360
s->stat &= ~(1 << 7); /* AERR */
361
ret = (uint8_t)s->fifo[s->fifostart++];
362
s->fifostart &= I2C_FIFO_SIZE_MASK;
364
if (s->fifolen <= ((s->dma >> 8) & 0x3f)) {
365
s->stat &= ~(1 << 3); /* RRDY */
366
s->stat |= 1 << 13; /* RDR */
369
s->stat &= ~((1 << 3) | (1 << 13)); /* RRDY | RDR */
370
s->stat |= 1 << 2; /* ARDY */
373
s->stat &= ~(1 << 11); /* ROVR */
374
} else if (s->revision >= OMAP3_INTR_REV)
375
s->stat |= (1 << 7); /* AERR */
376
omap_i2c_fifo_run(s);
377
omap_i2c_interrupts_update(s);
387
static void omap_i2c_write(void *opaque, hwaddr addr,
390
OMAPI2CState *s = opaque;
391
int offset = addr & OMAP_MPUI_REG_MASK;
395
case 0x00: /* I2C_REV */
396
case 0x10: /* I2C_SYSS */
397
case 0x40: /* I2C_BUFSTAT */
398
case 0x50: /* I2C_ACTOA */
401
case 0x04: /* I2C_IE */
402
if (s->revision < OMAP2_INTR_REV) {
403
s->mask = value & 0x1f;
404
} else if (s->revision < OMAP3_INTR_REV) {
405
s->mask = value & 0x3f;
406
} else if (s->revision == OMAP3_INTR_REV) {
407
s->mask = value & 0x63ff;
408
} else { /* omap3630 */
409
s->mask = value & 0x6fff;
411
omap_i2c_interrupts_update(s);
413
case 0x08: /* I2C_STAT */
414
if (s->revision < OMAP2_INTR_REV)
417
/* RRDY and XRDY are reset by hardware. (in all versions???) */
418
if (s->revision < OMAP3_INTR_REV) {
420
} else if (s->revision == OMAP3_INTR_REV) {
422
} else { /* omap3630 */
426
omap_i2c_interrupts_update(s);
430
case 0x0c: /* I2C_IV / I2C_WE */
431
if (s->revision < OMAP3_INTR_REV) {
433
} else if (s->revision == OMAP3_INTR_REV) {
434
s->we = value & 0x636f;
435
} else { /* omap3630 */
436
s->we = value & 0x6f6f;
440
case 0x14: /* I2C_BUF */
441
if (s->revision < OMAP3_INTR_REV)
442
s->dma = value & 0x8080;
444
s->dma = value & 0xbfbf;
445
if ((value & (1 << 14)) /* RXFIFO_CLR */
446
|| (value & (1 << 6))) /* TXFIFO_CLR */
449
if (value & (1 << 15)) /* RDMA_EN */
450
s->mask &= ~(1 << 3); /* RRDY_IE */
451
if (value & (1 << 7)) /* XDMA_EN */
452
s->mask &= ~(1 << 4); /* XRDY_IE */
455
case 0x18: /* I2C_CNT */
456
s->count = value; /* DCOUNT */
459
case 0x1c: /* I2C_DATA */
460
if (s->revision < OMAP3_INTR_REV) {
461
if (s->fifolen > 2) {
462
/* XXX: remote access (qualifier) error - what's that? */
465
if (s->control & (1 << 14)) { /* BE */
466
s->fifo[(s->fifostart + s->fifolen++) & I2C_FIFO_SIZE_MASK] =
467
(uint8_t)((value >> 8) & 0xff);
468
s->fifo[(s->fifostart + s->fifolen++) & I2C_FIFO_SIZE_MASK] =
469
(uint8_t)(value & 0xff);
471
s->fifo[(s->fifostart + s->fifolen++) & I2C_FIFO_SIZE_MASK] =
472
(uint8_t)(value & 0xff);
473
s->fifo[(s->fifostart + s->fifolen++) & I2C_FIFO_SIZE_MASK] =
474
(uint8_t)((value >> 8) & 0xff);
477
if (s->fifolen < s->fifosize) {
478
s->stat &= ~(1 << 7); /* AERR */
479
s->fifo[(s->fifostart + s->fifolen++) & I2C_FIFO_SIZE_MASK] =
480
(uint8_t)(value & 0xff);
482
s->stat |= (1 << 7); /* AERR */
484
s->stat &= ~(1 << 10); /* XUDF */
485
omap_i2c_fifo_run(s);
486
omap_i2c_interrupts_update(s);
489
case 0x20: /* I2C_SYSC */
490
if (s->revision < OMAP2_INTR_REV) {
496
omap_i2c_reset(DEVICE(s));
497
} else if (s->revision >= OMAP3_INTR_REV) {
498
s->sysc = value & 0x031d;
502
case 0x24: /* I2C_CON */
503
s->control = value & (s->revision < OMAP3_INTR_REV ? 0xcf87 : 0xbff3);
504
if (~value & (1 << 15)) { /* I2C_EN */
505
if (s->revision < OMAP2_INTR_REV) {
506
omap_i2c_reset(DEVICE(s));
510
if (s->revision >= OMAP3_INTR_REV && ((value >> 12) & 3) > 1) { /* OPMODE */
512
"%s: only FS and HS modes are supported\n",
516
if ((value & (1 << 10))) { /* MST */
517
if (value & 1) { /* STT */
518
nack = !!i2c_start_transfer(s->bus, s->slave_addr, /*SA*/
519
(~value >> 9) & 1); /* TRX */
520
s->stat |= nack << 1; /* NACK */
521
s->control &= ~(1 << 0); /* STT */
524
s->control &= ~(1 << 1); /* STP */
526
s->count_cur = s->count;
527
omap_i2c_fifo_run(s);
529
omap_i2c_interrupts_update(s);
530
} else if (value & 2) { /* STP, but not STT */
531
i2c_end_transfer(s->bus);
532
s->control &= ~0x0602; /* MST | TRX | STP */
533
s->count_cur = s->count;
537
case 0x28: /* I2C_OA / I2C_OA0 */
538
s->own_addr[0] = value & (s->revision < OMAP3_INTR_REV
540
/*i2c_set_slave_address(&s->slave[0],
541
value & (s->revision >= OMAP3_INTR_REV
542
&& (s->control & 0x80)
546
case 0x2c: /* I2C_SA */
547
s->slave_addr = value & 0x3ff;
550
case 0x30: /* I2C_PSC */
554
case 0x34: /* I2C_SCLL */
555
s->times[0] = value & (s->revision < OMAP3_INTR_REV ? 0xff : 0xffff);
558
case 0x38: /* I2C_SCLH */
559
s->times[1] = value & (s->revision < OMAP3_INTR_REV ? 0xff : 0xffff);
562
case 0x3c: /* I2C_SYSTEST */
563
if (s->revision < OMAP3_INTR_REV) {
565
} else if (s->revision == OMAP3_INTR_REV) {
567
} else { /* omap3630 */
568
value = (value & 0xf835) | 0x1c00;
570
if ((value & (1 << 15))) { /* ST_EN */
571
fprintf(stderr, "%s: System Test not supported\n",
573
s->test = (s->test & 0x0a) | value;
576
s->test = (s->test & 0x1f) | value;
578
if (value & (1 << 11)) { /* SBB */
579
if (s->revision >= OMAP2_INTR_REV) {
581
if (s->revision >= OMAP3_INTR_REV) {
583
if (s->revision > OMAP3_INTR_REV) {
587
omap_i2c_interrupts_update(s);
592
case 0x44: /* I2C_OA1 */
593
case 0x48: /* I2C_OA2 */
594
case 0x4c: /* I2C_OA3 */
595
if (s->revision < OMAP3_INTR_REV)
598
addr = (addr >> 2) & 3;
599
s->own_addr[addr] = value & 0x3ff;
600
/*i2c_set_slave_address(&s->slave[addr],
601
value & ((s->control & (0x80 >> addr))
605
case 0x54: /* I2C_SBLOCK */
606
if (s->revision < OMAP3_INTR_REV)
609
s->sblock = value & 0x0f;
618
static void omap_i2c_writeb(void *opaque, hwaddr addr,
621
OMAPI2CState *s = opaque;
622
int offset = addr & OMAP_MPUI_REG_MASK;
625
case 0x1c: /* I2C_DATA */
626
if (s->revision < OMAP3_INTR_REV && s->fifolen > 2) {
627
/* XXX: remote access (qualifier) error - what's that? */
630
if (s->fifolen < s->fifosize) {
631
s->fifo[(s->fifostart + s->fifolen++) & I2C_FIFO_SIZE_MASK] =
632
(uint8_t)(value & 0xff);
633
if (s->revision >= OMAP3_INTR_REV)
634
s->stat &= ~(1 << 7); /* AERR */
635
s->stat &= ~(1 << 10); /* XUDF */
636
omap_i2c_fifo_run(s);
637
} else if (s->revision >= OMAP3_INTR_REV)
638
s->stat |= (1 << 7); /* AERR */
639
omap_i2c_interrupts_update(s);
647
static const MemoryRegionOps omap_i2c_ops = {
652
omap_badwidth_read16,
655
omap_i2c_writeb, /* Only the last fifo write can be 8 bit. */
657
omap_badwidth_write16,
660
.endianness = DEVICE_NATIVE_ENDIAN,
663
static int omap_i2c_bus_post_load(void *opaque, int version_id)
665
OMAPI2CState *s = opaque;
666
omap_i2c_interrupts_update(s);
670
static const VMStateDescription vmstate_omap_i2c = {
673
.minimum_version_id = 1,
674
.post_load = omap_i2c_bus_post_load,
675
.fields = (VMStateField[]) {
676
VMSTATE_UINT16(mask, OMAPI2CState),
677
VMSTATE_UINT16(stat, OMAPI2CState),
678
VMSTATE_UINT16(we, OMAPI2CState),
679
VMSTATE_UINT16(dma, OMAPI2CState),
680
VMSTATE_UINT16(count, OMAPI2CState),
681
VMSTATE_INT32(count_cur, OMAPI2CState),
682
VMSTATE_UINT16(sysc, OMAPI2CState),
683
VMSTATE_UINT16(control, OMAPI2CState),
684
VMSTATE_UINT16_ARRAY(own_addr, OMAPI2CState, 4),
685
VMSTATE_UINT16(slave_addr, OMAPI2CState),
686
VMSTATE_UINT8(sblock, OMAPI2CState),
687
VMSTATE_UINT8(divider, OMAPI2CState),
688
VMSTATE_UINT16_ARRAY(times, OMAPI2CState, 2),
689
VMSTATE_UINT16(test, OMAPI2CState),
690
VMSTATE_INT32(fifostart, OMAPI2CState),
691
VMSTATE_INT32(fifolen, OMAPI2CState),
692
VMSTATE_UINT8_ARRAY(fifo, OMAPI2CState, I2C_MAX_FIFO_SIZE),
693
VMSTATE_END_OF_LIST()
697
static int omap_i2c_init(SysBusDevice *sbd)
699
DeviceState *dev = DEVICE(sbd);
700
OMAPI2CState *s = OMAP_I2C(dev);
703
hw_error("omap_i2c: fclk not connected\n");
705
if (s->revision >= OMAP2_INTR_REV && !s->iclk) {
706
/* Note that OMAP1 doesn't have a separate interface clock */
707
hw_error("omap_i2c: iclk not connected\n");
709
sysbus_init_irq(sbd, &s->irq);
710
sysbus_init_irq(sbd, &s->drq[0]);
711
sysbus_init_irq(sbd, &s->drq[1]);
712
memory_region_init_io(&s->iomem, OBJECT(s), &omap_i2c_ops, s, "omap.i2c",
713
(s->revision < OMAP2_INTR_REV) ? 0x800 : 0x1000);
714
sysbus_init_mmio(sbd, &s->iomem);
715
s->bus = i2c_init_bus(dev, NULL);
719
static Property omap_i2c_properties[] = {
720
DEFINE_PROP_UINT8("revision", OMAPI2CState, revision, 0),
721
DEFINE_PROP_UINT32("fifo-size", OMAPI2CState, fifosize, 4),
722
DEFINE_PROP_PTR("iclk", OMAPI2CState, iclk),
723
DEFINE_PROP_PTR("fclk", OMAPI2CState, fclk),
724
DEFINE_PROP_END_OF_LIST(),
727
static void omap_i2c_class_init(ObjectClass *klass, void *data)
729
DeviceClass *dc = DEVICE_CLASS(klass);
730
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
731
k->init = omap_i2c_init;
732
dc->props = omap_i2c_properties;
733
dc->reset = omap_i2c_reset;
734
dc->vmsd = &vmstate_omap_i2c;
737
static const TypeInfo omap_i2c_info = {
738
.name = TYPE_OMAP_I2C,
739
.parent = TYPE_SYS_BUS_DEVICE,
740
.instance_size = sizeof(OMAPI2CState),
741
.class_init = omap_i2c_class_init,
744
static void omap_i2c_register_types(void)
746
type_register_static(&omap_i2c_info);
749
i2c_bus *omap_i2c_bus(DeviceState *omap_i2c)
751
OMAPI2CState *s = OMAP_I2C(omap_i2c);
755
type_init(omap_i2c_register_types)