2
* TI OMAP on-chip I2C controller. Only "new I2C" mode supported.
4
* Copyright (C) 2007 Andrzej Zaborowski <balrog@zabor.org>
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.
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.
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/>.
25
typedef struct OMAPI2CState {
51
/* I2C controller revision register values */
52
#define OMAP1_INTR_REV 0x11
53
#define OMAP2_INTR_REV 0x34
54
#define OMAP3_INTR_REV 0x3c
55
#define OMAP3630_INTR_REV 0x40
57
static void omap_i2c_interrupts_update(OMAPI2CState *s)
59
qemu_set_irq(s->irq, s->stat & s->mask);
60
if ((s->dma >> 15) & 1) /* RDMA_EN */
61
qemu_set_irq(s->drq[0], (s->stat >> 3) & 1); /* RRDY */
62
if ((s->dma >> 7) & 1) /* XDMA_EN */
63
qemu_set_irq(s->drq[1], (s->stat >> 4) & 1); /* XRDY */
66
static void omap_i2c_fifo_run(OMAPI2CState *s)
70
if (!i2c_bus_busy(s->bus))
73
if ((s->control >> 2) & 1) { /* RM */
74
if ((s->control >> 1) & 1) { /* STP */
75
i2c_end_transfer(s->bus);
76
s->control &= ~(1 << 1); /* STP */
77
s->count_cur = s->count;
79
} else if ((s->control >> 9) & 1) { /* TRX */
80
while (ack && s->txlen)
81
ack = (i2c_send(s->bus,
82
(s->fifo >> ((-- s->txlen) << 3)) &
84
s->stat |= 1 << 4; /* XRDY */
87
s->fifo |= i2c_recv(s->bus) << ((s->rxlen ++) << 3);
88
s->stat |= 1 << 3; /* RRDY */
91
if ((s->control >> 9) & 1) { /* TRX */
92
while (ack && s->count_cur && s->txlen) {
93
ack = (i2c_send(s->bus,
94
(s->fifo >> ((-- s->txlen) << 3)) &
98
if (ack && s->count_cur)
99
s->stat |= 1 << 4; /* XRDY */
101
s->stat &= ~(1 << 4); /* XRDY */
103
s->stat |= 1 << 2; /* ARDY */
104
s->control &= ~(1 << 10); /* MST */
107
while (s->count_cur && s->rxlen < 4) {
108
s->fifo |= i2c_recv(s->bus) << ((s->rxlen ++) << 3);
112
s->stat |= 1 << 3; /* RRDY */
114
s->stat &= ~(1 << 3); /* RRDY */
117
if ((s->control >> 1) & 1) { /* STP */
118
i2c_end_transfer(s->bus);
119
s->control &= ~(1 << 1); /* STP */
120
s->count_cur = s->count;
123
s->stat |= 1 << 2; /* ARDY */
124
s->control &= ~(1 << 10); /* MST */
129
s->stat |= (!ack) << 1; /* NACK */
131
s->control &= ~(1 << 1); /* STP */
134
static void omap_i2c_reset(DeviceState *dev)
136
OMAPI2CState *s = FROM_SYSBUS(OMAPI2CState,
137
SYS_BUS_DEVICE(dev));
155
static uint32_t omap_i2c_read(void *opaque, hwaddr addr)
157
OMAPI2CState *s = opaque;
158
int offset = addr & OMAP_MPUI_REG_MASK;
162
case 0x00: /* I2C_REV */
163
return s->revision; /* REV */
165
case 0x04: /* I2C_IE */
168
case 0x08: /* I2C_STAT */
169
return s->stat | (i2c_bus_busy(s->bus) << 12);
171
case 0x0c: /* I2C_IV */
172
if (s->revision >= OMAP2_INTR_REV)
174
ret = ffs(s->stat & s->mask);
176
s->stat ^= 1 << (ret - 1);
177
omap_i2c_interrupts_update(s);
180
case 0x10: /* I2C_SYSS */
181
return (s->control >> 15) & 1; /* I2C_EN */
183
case 0x14: /* I2C_BUF */
186
case 0x18: /* I2C_CNT */
187
return s->count_cur; /* DCOUNT */
189
case 0x1c: /* I2C_DATA */
191
if (s->control & (1 << 14)) { /* BE */
192
ret |= ((s->fifo >> 0) & 0xff) << 8;
193
ret |= ((s->fifo >> 8) & 0xff) << 0;
195
ret |= ((s->fifo >> 8) & 0xff) << 8;
196
ret |= ((s->fifo >> 0) & 0xff) << 0;
199
s->stat |= 1 << 15; /* SBD */
201
} else if (s->rxlen > 1) {
206
/* XXX: remote access (qualifier) error - what's that? */
209
s->stat &= ~(1 << 3); /* RRDY */
210
if (((s->control >> 10) & 1) && /* MST */
211
((~s->control >> 9) & 1)) { /* TRX */
212
s->stat |= 1 << 2; /* ARDY */
213
s->control &= ~(1 << 10); /* MST */
216
s->stat &= ~(1 << 11); /* ROVR */
217
omap_i2c_fifo_run(s);
218
omap_i2c_interrupts_update(s);
221
case 0x20: /* I2C_SYSC */
224
case 0x24: /* I2C_CON */
227
case 0x28: /* I2C_OA */
230
case 0x2c: /* I2C_SA */
233
case 0x30: /* I2C_PSC */
236
case 0x34: /* I2C_SCLL */
239
case 0x38: /* I2C_SCLH */
242
case 0x3c: /* I2C_SYSTEST */
243
if (s->test & (1 << 15)) { /* ST_EN */
247
return s->test & ~0x300f;
254
static void omap_i2c_write(void *opaque, hwaddr addr,
257
OMAPI2CState *s = opaque;
258
int offset = addr & OMAP_MPUI_REG_MASK;
262
case 0x00: /* I2C_REV */
263
case 0x0c: /* I2C_IV */
264
case 0x10: /* I2C_SYSS */
268
case 0x04: /* I2C_IE */
269
s->mask = value & (s->revision < OMAP2_INTR_REV ? 0x1f : 0x3f);
272
case 0x08: /* I2C_STAT */
273
if (s->revision < OMAP2_INTR_REV) {
278
/* RRDY and XRDY are reset by hardware. (in all versions???) */
279
s->stat &= ~(value & 0x27);
280
omap_i2c_interrupts_update(s);
283
case 0x14: /* I2C_BUF */
284
s->dma = value & 0x8080;
285
if (value & (1 << 15)) /* RDMA_EN */
286
s->mask &= ~(1 << 3); /* RRDY_IE */
287
if (value & (1 << 7)) /* XDMA_EN */
288
s->mask &= ~(1 << 4); /* XRDY_IE */
291
case 0x18: /* I2C_CNT */
292
s->count = value; /* DCOUNT */
295
case 0x1c: /* I2C_DATA */
297
/* XXX: remote access (qualifier) error - what's that? */
302
if (s->control & (1 << 14)) { /* BE */
303
s->fifo |= ((value >> 8) & 0xff) << 8;
304
s->fifo |= ((value >> 0) & 0xff) << 0;
306
s->fifo |= ((value >> 0) & 0xff) << 8;
307
s->fifo |= ((value >> 8) & 0xff) << 0;
309
s->stat &= ~(1 << 10); /* XUDF */
311
s->stat &= ~(1 << 4); /* XRDY */
312
omap_i2c_fifo_run(s);
313
omap_i2c_interrupts_update(s);
316
case 0x20: /* I2C_SYSC */
317
if (s->revision < OMAP2_INTR_REV) {
323
omap_i2c_reset(&s->busdev.qdev);
326
case 0x24: /* I2C_CON */
327
s->control = value & 0xcf87;
328
if (~value & (1 << 15)) { /* I2C_EN */
329
if (s->revision < OMAP2_INTR_REV)
330
omap_i2c_reset(&s->busdev.qdev);
333
if ((value & (1 << 15)) && !(value & (1 << 10))) { /* MST */
334
fprintf(stderr, "%s: I^2C slave mode not supported\n",
338
if ((value & (1 << 15)) && value & (1 << 8)) { /* XA */
339
fprintf(stderr, "%s: 10-bit addressing mode not supported\n",
343
if ((value & (1 << 15)) && value & (1 << 0)) { /* STT */
344
nack = !!i2c_start_transfer(s->bus, s->addr[1], /* SA */
345
(~value >> 9) & 1); /* TRX */
346
s->stat |= nack << 1; /* NACK */
347
s->control &= ~(1 << 0); /* STT */
350
s->control &= ~(1 << 1); /* STP */
352
s->count_cur = s->count;
353
omap_i2c_fifo_run(s);
355
omap_i2c_interrupts_update(s);
359
case 0x28: /* I2C_OA */
360
s->addr[0] = value & 0x3ff;
363
case 0x2c: /* I2C_SA */
364
s->addr[1] = value & 0x3ff;
367
case 0x30: /* I2C_PSC */
371
case 0x34: /* I2C_SCLL */
375
case 0x38: /* I2C_SCLH */
379
case 0x3c: /* I2C_SYSTEST */
380
s->test = value & 0xf80f;
381
if (value & (1 << 11)) /* SBB */
382
if (s->revision >= OMAP2_INTR_REV) {
384
omap_i2c_interrupts_update(s);
386
if (value & (1 << 15)) /* ST_EN */
387
fprintf(stderr, "%s: System Test not supported\n", __FUNCTION__);
396
static void omap_i2c_writeb(void *opaque, hwaddr addr,
399
OMAPI2CState *s = opaque;
400
int offset = addr & OMAP_MPUI_REG_MASK;
403
case 0x1c: /* I2C_DATA */
405
/* XXX: remote access (qualifier) error - what's that? */
410
s->fifo |= value & 0xff;
411
s->stat &= ~(1 << 10); /* XUDF */
413
s->stat &= ~(1 << 4); /* XRDY */
414
omap_i2c_fifo_run(s);
415
omap_i2c_interrupts_update(s);
424
static const MemoryRegionOps omap_i2c_ops = {
427
omap_badwidth_read16,
429
omap_badwidth_read16,
432
omap_i2c_writeb, /* Only the last fifo write can be 8 bit. */
434
omap_badwidth_write16,
437
.endianness = DEVICE_NATIVE_ENDIAN,
440
static int omap_i2c_init(SysBusDevice *dev)
442
OMAPI2CState *s = FROM_SYSBUS(OMAPI2CState, dev);
445
hw_error("omap_i2c: fclk not connected\n");
447
if (s->revision >= OMAP2_INTR_REV && !s->iclk) {
448
/* Note that OMAP1 doesn't have a separate interface clock */
449
hw_error("omap_i2c: iclk not connected\n");
451
sysbus_init_irq(dev, &s->irq);
452
sysbus_init_irq(dev, &s->drq[0]);
453
sysbus_init_irq(dev, &s->drq[1]);
454
memory_region_init_io(&s->iomem, &omap_i2c_ops, s, "omap.i2c",
455
(s->revision < OMAP2_INTR_REV) ? 0x800 : 0x1000);
456
sysbus_init_mmio(dev, &s->iomem);
457
s->bus = i2c_init_bus(&dev->qdev, NULL);
461
static Property omap_i2c_properties[] = {
462
DEFINE_PROP_UINT8("revision", OMAPI2CState, revision, 0),
463
DEFINE_PROP_PTR("iclk", OMAPI2CState, iclk),
464
DEFINE_PROP_PTR("fclk", OMAPI2CState, fclk),
465
DEFINE_PROP_END_OF_LIST(),
468
static void omap_i2c_class_init(ObjectClass *klass, void *data)
470
DeviceClass *dc = DEVICE_CLASS(klass);
471
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
472
k->init = omap_i2c_init;
473
dc->props = omap_i2c_properties;
474
dc->reset = omap_i2c_reset;
477
static const TypeInfo omap_i2c_info = {
479
.parent = TYPE_SYS_BUS_DEVICE,
480
.instance_size = sizeof(OMAPI2CState),
481
.class_init = omap_i2c_class_init,
484
static void omap_i2c_register_types(void)
486
type_register_static(&omap_i2c_info);
489
i2c_bus *omap_i2c_bus(DeviceState *omap_i2c)
491
OMAPI2CState *s = FROM_SYSBUS(OMAPI2CState, SYS_BUS_DEVICE(omap_i2c));
495
type_init(omap_i2c_register_types)