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/>.
25
#define I2C_MAX_FIFO_SIZE (1 << 6)
26
#define I2C_FIFO_SIZE_MASK ((I2C_MAX_FIFO_SIZE) - 1)
28
typedef struct OMAPI2CState {
56
uint8_t fifo[I2C_MAX_FIFO_SIZE];
59
/* I2C controller revision register values */
60
#define OMAP1_INTR_REV 0x11
61
#define OMAP2_INTR_REV 0x34
62
#define OMAP3_INTR_REV 0x3c
63
#define OMAP3630_INTR_REV 0x40
65
static void omap_i2c_interrupts_update(OMAPI2CState *s)
67
qemu_set_irq(s->irq, s->stat & s->mask);
68
if ((s->dma >> 15) & 1) /* RDMA_EN */
69
qemu_set_irq(s->drq[0], (s->stat >> 3) & 1); /* RRDY */
70
if ((s->dma >> 7) & 1) /* XDMA_EN */
71
qemu_set_irq(s->drq[1], (s->stat >> 4) & 1); /* XRDY */
74
static void omap_i2c_fifo_run(OMAPI2CState *s)
78
if (!i2c_bus_busy(s->bus))
81
if ((s->control >> 2) & 1) { /* RM */
82
if ((s->control >> 1) & 1) { /* STP */
83
i2c_end_transfer(s->bus);
84
s->control &= ~(1 << 1); /* STP */
85
s->count_cur = s->count;
87
} else if ((s->control >> 9) & 1) { /* TRX */
88
while (ack && s->fifolen) {
89
ack = (i2c_send(s->bus, s->fifo[s->fifostart++]) >= 0);
90
s->fifostart &= I2C_FIFO_SIZE_MASK;
94
s->stat |= 1 << 4; /* XRDY */
96
for (i = 0; i < 4; i++)
97
s->fifo[(s->fifostart + i) & I2C_FIFO_SIZE_MASK] =
100
s->stat |= 1 << 3; /* RRDY */
103
if ((s->control >> 9) & 1) { /* TRX */
104
for (; ack && s->count_cur && s->fifolen; s->count_cur--) {
105
ack = (i2c_send(s->bus, s->fifo[s->fifostart++]) >= 0);
106
s->fifostart &= I2C_FIFO_SIZE_MASK;
109
s->stat &= ~0x4410; /* XDR | XUDF | XRDY */
110
if (ack && s->count_cur) { /* send more? */
111
/* we know that FIFO is empty */
112
if (s->revision < OMAP3_INTR_REV)
113
s->stat |= 1 << 4; /* XRDY */
115
if (s->count_cur > (s->dma & 0x3f)) /* XTRSH */
116
s->stat |= 1 << 4; /* XRDY */
118
s->stat |= 1 << 14; /* XDR */
121
if (!s->count_cur) /* everything sent? */
122
s->stat |= 1 << 2; /* ARDY */
124
for (; s->count_cur && s->fifolen < s->fifosize; s->count_cur--) {
125
i = i2c_recv(s->bus);
126
if (i < 0) break; /* stop receiving if nothing to receive */
127
s->fifo[(s->fifostart + s->fifolen++) & I2C_FIFO_SIZE_MASK] =
130
s->stat &= ~((1 << 3) | (1 << 13)); /* RRDY | RDR */
132
if (s->revision < OMAP3_INTR_REV)
133
s->stat |= 1 << 3; /* RRDY */
135
if (s->fifolen > ((s->dma >> 8) & 0x3f)) /* RTRSH */
136
s->stat |= 1 << 3; /* RRDY */
138
s->stat |= 1 << 13; /* RDR */
140
} else if (!s->count_cur && (s->control & 2)) /* STP */
141
s->stat |= 1 << 2; /* ARDY */
144
if ((s->control >> 1) & 1) { /* STP */
145
i2c_end_transfer(s->bus);
146
s->control &= ~0x0602; /* MST | TRX | STP */
147
s->count_cur = s->count;
152
s->stat |= (!ack) << 1; /* NACK */
154
s->control &= ~(1 << 1); /* STP */
157
static void omap_i2c_reset(DeviceState *dev)
159
OMAPI2CState *s = FROM_SYSBUS(OMAPI2CState,
160
SYS_BUS_DEVICE(dev));
182
i2c_end_transfer(s->bus);
185
static uint32_t omap_i2c_read(void *opaque, hwaddr addr)
187
OMAPI2CState *s = opaque;
188
int offset = addr & OMAP_MPUI_REG_MASK;
192
case 0x00: /* I2C_REV */
193
return s->revision; /* REV */
195
case 0x04: /* I2C_IE */
198
case 0x08: /* I2C_STAT */
199
return s->stat | (i2c_bus_busy(s->bus) << 12);
201
case 0x0c: /* I2C_IV / I2C_WE */
202
if (s->revision >= OMAP3_INTR_REV)
204
if (s->revision >= OMAP2_INTR_REV)
206
ret = ffs(s->stat & s->mask);
208
s->stat ^= 1 << (ret - 1);
209
omap_i2c_interrupts_update(s);
212
case 0x10: /* I2C_SYSS */
213
return (s->control >> 15) & 1; /* I2C_EN */
215
case 0x14: /* I2C_BUF */
218
case 0x18: /* I2C_CNT */
219
return s->count_cur; /* DCOUNT */
221
case 0x1c: /* I2C_DATA */
224
if (s->revision < OMAP3_INTR_REV) {
225
if (s->control & (1 << 14)) /* BE */
226
ret = (((uint16_t)s->fifo[s->fifostart]) << 8)
227
| s->fifo[(s->fifostart + 1) & I2C_FIFO_SIZE_MASK];
229
ret = (((uint16_t)s->fifo[(s->fifostart + 1) & I2C_FIFO_SIZE_MASK]) << 8)
230
| s->fifo[s->fifostart];
231
s->fifostart = (s->fifostart + 2) & I2C_FIFO_SIZE_MASK;
232
if (s->fifolen == 1) {
233
s->stat |= 1 << 15; /* SBD */
238
s->stat &= ~(1 << 3); /* RRDY */
239
s->stat |= 1 << 2; /* ARDY */
242
s->stat &= ~(1 << 7); /* AERR */
243
ret = s->fifo[s->fifostart++];
244
s->fifostart &= I2C_FIFO_SIZE_MASK;
246
if (s->fifolen <= ((s->dma >> 8) & 0x3f)) {
247
s->stat &= ~(1 << 3); /* RRDY */
248
s->stat |= 1 << 13; /* RDR */
251
s->stat &= ~((1 << 3) | (1 << 13)); /* RRDY | RDR */
252
s->stat |= 1 << 2; /* ARDY */
255
s->stat &= ~(1 << 11); /* ROVR */
256
} else if (s->revision >= OMAP3_INTR_REV)
257
s->stat |= (1 << 7); /* AERR */
258
omap_i2c_fifo_run(s);
259
omap_i2c_interrupts_update(s);
262
case 0x20: /* I2C_SYSC */
265
case 0x24: /* I2C_CON */
268
case 0x28: /* I2C_OA / I2C_OA0 */
269
return s->own_addr[0];
271
case 0x2c: /* I2C_SA */
272
return s->slave_addr;
274
case 0x30: /* I2C_PSC */
277
case 0x34: /* I2C_SCLL */
280
case 0x38: /* I2C_SCLH */
283
case 0x3c: /* I2C_SYSTEST */
284
if (s->test & (1 << 15)) { /* ST_EN */
288
return s->test & ~0x300f;
289
case 0x40: /* I2C_BUFSTAT */
290
if (s->revision >= OMAP3_INTR_REV) {
291
switch (s->fifosize) {
292
case 8: ret = 0x0000; break;
293
case 16: ret = 0x4000; break;
294
case 32: ret = 0x8000; break;
295
case 64: ret = 0xc000; break;
296
default: ret = 0x0000; break;
298
ret |= ((s->fifolen) & 0x3f) << 8; /* RXSTAT */
299
ret |= (s->count_cur) & 0x3f; /* TXSTAT */
303
case 0x44: /* I2C_OA1 */
304
case 0x48: /* I2C_OA2 */
305
case 0x4c: /* I2C_OA3 */
306
if (s->revision >= OMAP3_INTR_REV)
307
return s->own_addr[(addr >> 2) & 3];
309
case 0x50: /* I2C_ACTOA */
310
if (s->revision >= OMAP3_INTR_REV)
311
return 0; /* TODO: determine accessed slave own address */
313
case 0x54: /* I2C_SBLOCK */
314
if (s->revision >= OMAP3_INTR_REV)
325
static void omap_i2c_write(void *opaque, hwaddr addr,
328
OMAPI2CState *s = opaque;
329
int offset = addr & OMAP_MPUI_REG_MASK;
333
case 0x00: /* I2C_REV */
334
case 0x10: /* I2C_SYSS */
335
case 0x40: /* I2C_BUFSTAT */
336
case 0x50: /* I2C_ACTOA */
339
case 0x04: /* I2C_IE */
340
if (s->revision >= OMAP3_INTR_REV)
341
s->mask = value & 0x63ff;
343
s->mask = value & (s->revision < OMAP2_INTR_REV ? 0x1f : 0x3f);
344
omap_i2c_interrupts_update(s);
346
case 0x08: /* I2C_STAT */
347
if (s->revision < OMAP2_INTR_REV)
350
/* RRDY and XRDY are reset by hardware. (in all versions???) */
351
s->stat &= ~(value & (s->revision < OMAP3_INTR_REV ? 0x27 : 0x63e7));
352
omap_i2c_interrupts_update(s);
356
case 0x0c: /* I2C_IV / I2C_WE */
357
if (s->revision < OMAP3_INTR_REV)
360
s->we = value & 0x636f;
363
case 0x14: /* I2C_BUF */
364
if (s->revision < OMAP3_INTR_REV)
365
s->dma = value & 0x8080;
367
s->dma = value & 0xbfbf;
368
if ((value & (1 << 14)) /* RXFIFO_CLR */
369
|| (value & (1 << 6))) /* TXFIFO_CLR */
372
if (value & (1 << 15)) /* RDMA_EN */
373
s->mask &= ~(1 << 3); /* RRDY_IE */
374
if (value & (1 << 7)) /* XDMA_EN */
375
s->mask &= ~(1 << 4); /* XRDY_IE */
378
case 0x18: /* I2C_CNT */
379
s->count = value; /* DCOUNT */
382
case 0x1c: /* I2C_DATA */
383
if (s->revision < OMAP3_INTR_REV) {
384
if (s->fifolen > 2) {
385
/* XXX: remote access (qualifier) error - what's that? */
388
if (s->control & (1 << 14)) { /* BE */
389
s->fifo[(s->fifostart + s->fifolen++) & I2C_FIFO_SIZE_MASK] =
390
(uint8_t)((value >> 8) & 0xff);
391
s->fifo[(s->fifostart + s->fifolen++) & I2C_FIFO_SIZE_MASK] =
392
(uint8_t)(value & 0xff);
394
s->fifo[(s->fifostart + s->fifolen++) & I2C_FIFO_SIZE_MASK] =
395
(uint8_t)(value & 0xff);
396
s->fifo[(s->fifostart + s->fifolen++) & I2C_FIFO_SIZE_MASK] =
397
(uint8_t)((value >> 8) & 0xff);
400
if (s->fifolen < s->fifosize) {
401
s->stat &= ~(1 << 7); /* AERR */
402
s->fifo[(s->fifostart + s->fifolen++) & I2C_FIFO_SIZE_MASK] =
403
(uint8_t)(value & 0xff);
405
s->stat |= (1 << 7); /* AERR */
407
s->stat &= ~(1 << 10); /* XUDF */
408
omap_i2c_fifo_run(s);
409
omap_i2c_interrupts_update(s);
412
case 0x20: /* I2C_SYSC */
413
if (s->revision < OMAP2_INTR_REV) {
419
omap_i2c_reset(&s->busdev.qdev);
420
else if (s->revision >= OMAP3_INTR_REV)
421
s->sysc = value & 0x031d;
424
case 0x24: /* I2C_CON */
425
s->control = value & (s->revision < OMAP3_INTR_REV ? 0xcf87 : 0xbff3);
426
if (~value & (1 << 15)) { /* I2C_EN */
427
if (s->revision < OMAP2_INTR_REV)
428
omap_i2c_reset(&s->busdev.qdev);
431
if (s->revision >= OMAP3_INTR_REV && ((value >> 12) & 3) > 1) { /* OPMODE */
433
"%s: only FS and HS modes are supported\n",
437
if ((value & (1 << 10))) { /* MST */
438
if (value & 1) { /* STT */
439
nack = !!i2c_start_transfer(s->bus, s->slave_addr, /*SA*/
440
(~value >> 9) & 1); /* TRX */
441
s->stat |= nack << 1; /* NACK */
442
s->control &= ~(1 << 0); /* STT */
445
s->control &= ~(1 << 1); /* STP */
447
s->count_cur = s->count;
448
omap_i2c_fifo_run(s);
450
omap_i2c_interrupts_update(s);
451
} else if (value & 2) { /* STP, but not STT */
452
i2c_end_transfer(s->bus);
453
s->control &= ~0x0602; /* MST | TRX | STP */
454
s->count_cur = s->count;
458
case 0x28: /* I2C_OA / I2C_OA0 */
459
s->own_addr[0] = value & (s->revision < OMAP3_INTR_REV
461
/*i2c_set_slave_address(&s->slave[0],
462
value & (s->revision >= OMAP3_INTR_REV
463
&& (s->control & 0x80)
467
case 0x2c: /* I2C_SA */
468
s->slave_addr = value & 0x3ff;
471
case 0x30: /* I2C_PSC */
475
case 0x34: /* I2C_SCLL */
476
s->times[0] = value & (s->revision < OMAP3_INTR_REV ? 0xff : 0xffff);
479
case 0x38: /* I2C_SCLH */
480
s->times[1] = value & (s->revision < OMAP3_INTR_REV ? 0xff : 0xffff);
483
case 0x3c: /* I2C_SYSTEST */
484
value &= s->revision < OMAP3_INTR_REV ? 0xf805 : 0xf815;
485
if ((value & (1 << 15))) { /* ST_EN */
486
fprintf(stderr, "%s: System Test not supported\n",
488
s->test = (s->test & 0x0a) | value;
490
s->test = (s->test & 0x1f) | (value & 0xf800);
491
if (value & (1 << 11)) /* SBB */
492
if (s->revision >= OMAP2_INTR_REV) {
494
if (s->revision >= OMAP3_INTR_REV)
496
omap_i2c_interrupts_update(s);
500
case 0x44: /* I2C_OA1 */
501
case 0x48: /* I2C_OA2 */
502
case 0x4c: /* I2C_OA3 */
503
if (s->revision < OMAP3_INTR_REV)
506
addr = (addr >> 2) & 3;
507
s->own_addr[addr] = value & 0x3ff;
508
/*i2c_set_slave_address(&s->slave[addr],
509
value & ((s->control & (0x80 >> addr))
513
case 0x54: /* I2C_SBLOCK */
514
if (s->revision < OMAP3_INTR_REV)
517
s->sblock = value & 0x0f;
526
static void omap_i2c_writeb(void *opaque, hwaddr addr,
529
OMAPI2CState *s = opaque;
530
int offset = addr & OMAP_MPUI_REG_MASK;
533
case 0x1c: /* I2C_DATA */
534
if (s->revision < OMAP3_INTR_REV && s->fifolen > 2) {
535
/* XXX: remote access (qualifier) error - what's that? */
538
if (s->fifolen < s->fifosize) {
539
s->fifo[(s->fifostart + s->fifolen++) & I2C_FIFO_SIZE_MASK] =
540
(uint8_t)(value & 0xff);
541
if (s->revision >= OMAP3_INTR_REV)
542
s->stat &= ~(1 << 7); /* AERR */
543
s->stat &= ~(1 << 10); /* XUDF */
544
omap_i2c_fifo_run(s);
545
} else if (s->revision >= OMAP3_INTR_REV)
546
s->stat |= (1 << 7); /* AERR */
547
omap_i2c_interrupts_update(s);
555
static const MemoryRegionOps omap_i2c_ops = {
558
omap_badwidth_read16,
560
omap_badwidth_read16,
563
omap_i2c_writeb, /* Only the last fifo write can be 8 bit. */
565
omap_badwidth_write16,
568
.endianness = DEVICE_NATIVE_ENDIAN,
571
static int omap_i2c_init(SysBusDevice *dev)
573
OMAPI2CState *s = FROM_SYSBUS(OMAPI2CState, dev);
576
hw_error("omap_i2c: fclk not connected\n");
578
if (s->revision >= OMAP2_INTR_REV && !s->iclk) {
579
/* Note that OMAP1 doesn't have a separate interface clock */
580
hw_error("omap_i2c: iclk not connected\n");
582
sysbus_init_irq(dev, &s->irq);
583
sysbus_init_irq(dev, &s->drq[0]);
584
sysbus_init_irq(dev, &s->drq[1]);
585
memory_region_init_io(&s->iomem, &omap_i2c_ops, s, "omap.i2c",
586
(s->revision < OMAP2_INTR_REV) ? 0x800 : 0x1000);
587
sysbus_init_mmio(dev, &s->iomem);
588
s->bus = i2c_init_bus(&dev->qdev, NULL);
592
static Property omap_i2c_properties[] = {
593
DEFINE_PROP_UINT8("revision", OMAPI2CState, revision, 0),
594
DEFINE_PROP_UINT32("fifo-size", OMAPI2CState, fifosize, 4),
595
DEFINE_PROP_PTR("iclk", OMAPI2CState, iclk),
596
DEFINE_PROP_PTR("fclk", OMAPI2CState, fclk),
597
DEFINE_PROP_END_OF_LIST(),
600
static void omap_i2c_class_init(ObjectClass *klass, void *data)
602
DeviceClass *dc = DEVICE_CLASS(klass);
603
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
604
k->init = omap_i2c_init;
605
dc->props = omap_i2c_properties;
606
dc->reset = omap_i2c_reset;
609
static const TypeInfo omap_i2c_info = {
611
.parent = TYPE_SYS_BUS_DEVICE,
612
.instance_size = sizeof(OMAPI2CState),
613
.class_init = omap_i2c_class_init,
616
static void omap_i2c_register_types(void)
618
type_register_static(&omap_i2c_info);
621
i2c_bus *omap_i2c_bus(DeviceState *omap_i2c)
623
OMAPI2CState *s = FROM_SYSBUS(OMAPI2CState, SYS_BUS_DEVICE(omap_i2c));
627
type_init(omap_i2c_register_types)