1
From 548ab59088ffe9abf79e9a7ce36b69a6b8e30577 Mon Sep 17 00:00:00 2001
2
From: Peter Maydell <peter.maydell@linaro.org>
3
Date: Mon, 18 Feb 2013 16:58:26 +0000
4
Subject: [PATCH 18/70] hw/omap_i2c: non-whitespace changes from overhaul patch
7
hw/i2c/omap_i2c.c | 171 ++++++++++++++++++++++++++++++++++++++++++------------
8
1 file changed, 135 insertions(+), 36 deletions(-)
10
diff --git a/hw/i2c/omap_i2c.c b/hw/i2c/omap_i2c.c
11
index c054815..565a3cd 100644
12
--- a/hw/i2c/omap_i2c.c
13
+++ b/hw/i2c/omap_i2c.c
15
* TI OMAP on-chip I2C controller. Only "new I2C" mode supported.
17
* Copyright (C) 2007 Andrzej Zaborowski <balrog@zabor.org>
18
+ * Copyright (C) 2009 Nokia Corporation
20
* This program is free software; you can redistribute it and/or
21
* modify it under the terms of the GNU General Public License as
22
@@ -40,15 +41,19 @@ typedef struct OMAPI2CState {
36
+ uint16_t own_addr[4];
37
+ uint16_t slave_addr;
45
@@ -162,15 +167,23 @@ static void omap_i2c_reset(DeviceState *dev)
67
+ i2c_end_transfer(s->bus);
70
static uint32_t omap_i2c_read(void *opaque, hwaddr addr)
71
@@ -189,7 +202,9 @@ static uint32_t omap_i2c_read(void *opaque, hwaddr addr)
72
case 0x08: /* I2C_STAT */
73
return s->stat | (i2c_bus_busy(s->bus) << 12);
75
- case 0x0c: /* I2C_IV */
76
+ case 0x0c: /* I2C_IV / I2C_WE */
77
+ if (s->revision >= OMAP3_INTR_REV)
79
if (s->revision >= OMAP2_INTR_REV)
81
ret = ffs(s->stat & s->mask);
82
@@ -249,16 +264,16 @@ static uint32_t omap_i2c_read(void *opaque, hwaddr addr)
85
case 0x20: /* I2C_SYSC */
89
case 0x24: /* I2C_CON */
92
- case 0x28: /* I2C_OA */
94
+ case 0x28: /* I2C_OA / I2C_OA0 */
95
+ return s->own_addr[0];
97
case 0x2c: /* I2C_SA */
99
+ return s->slave_addr;
101
case 0x30: /* I2C_PSC */
103
@@ -273,8 +288,38 @@ static uint32_t omap_i2c_read(void *opaque, hwaddr addr)
104
if (s->test & (1 << 15)) { /* ST_EN */
108
- return s->test & ~0x300f;
110
+ return s->test & ~0x300f;
111
+ case 0x40: /* I2C_BUFSTAT */
112
+ if (s->revision >= OMAP3_INTR_REV) {
113
+ switch (s->fifosize) {
114
+ case 8: ret = 0x0000; break;
115
+ case 16: ret = 0x4000; break;
116
+ case 32: ret = 0x8000; break;
117
+ case 64: ret = 0xc000; break;
118
+ default: ret = 0x0000; break;
120
+ ret |= ((s->fifolen) & 0x3f) << 8; /* RXSTAT */
121
+ ret |= (s->count_cur) & 0x3f; /* TXSTAT */
125
+ case 0x44: /* I2C_OA1 */
126
+ case 0x48: /* I2C_OA2 */
127
+ case 0x4c: /* I2C_OA3 */
128
+ if (s->revision >= OMAP3_INTR_REV)
129
+ return s->own_addr[(addr >> 2) & 3];
131
+ case 0x50: /* I2C_ACTOA */
132
+ if (s->revision >= OMAP3_INTR_REV)
133
+ return 0; /* TODO: determine accessed slave own address */
135
+ case 0x54: /* I2C_SBLOCK */
136
+ if (s->revision >= OMAP3_INTR_REV)
144
@@ -290,28 +335,44 @@ static void omap_i2c_write(void *opaque, hwaddr addr,
147
case 0x00: /* I2C_REV */
148
- case 0x0c: /* I2C_IV */
149
case 0x10: /* I2C_SYSS */
150
+ case 0x40: /* I2C_BUFSTAT */
151
+ case 0x50: /* I2C_ACTOA */
156
case 0x04: /* I2C_IE */
157
- s->mask = value & (s->revision < OMAP2_INTR_REV ? 0x1f : 0x3f);
158
+ if (s->revision >= OMAP3_INTR_REV)
159
+ s->mask = value & 0x63ff;
161
+ s->mask = value & (s->revision < OMAP2_INTR_REV ? 0x1f : 0x3f);
162
+ omap_i2c_interrupts_update(s);
165
case 0x08: /* I2C_STAT */
166
- if (s->revision < OMAP2_INTR_REV) {
167
+ if (s->revision < OMAP2_INTR_REV)
171
+ /* RRDY and XRDY are reset by hardware. (in all versions???) */
172
+ s->stat &= ~(value & (s->revision < OMAP3_INTR_REV ? 0x27 : 0x63e7));
173
+ omap_i2c_interrupts_update(s);
177
- /* RRDY and XRDY are reset by hardware. (in all versions???) */
178
- s->stat &= ~(value & 0x27);
179
- omap_i2c_interrupts_update(s);
180
+ case 0x0c: /* I2C_IV / I2C_WE */
181
+ if (s->revision < OMAP3_INTR_REV)
184
+ s->we = value & 0x636f;
187
case 0x14: /* I2C_BUF */
188
- s->dma = value & 0x8080;
189
+ if (s->revision < OMAP3_INTR_REV)
190
+ s->dma = value & 0x8080;
192
+ s->dma = value & 0xbfbf;
193
+ if ((value & (1 << 14)) /* RXFIFO_CLR */
194
+ || (value & (1 << 6))) /* TXFIFO_CLR */
197
if (value & (1 << 15)) /* RDMA_EN */
198
s->mask &= ~(1 << 3); /* RRDY_IE */
199
if (value & (1 << 7)) /* XDMA_EN */
200
@@ -355,25 +416,33 @@ static void omap_i2c_write(void *opaque, hwaddr addr,
201
case 0x20: /* I2C_SYSC */
202
if (s->revision < OMAP2_INTR_REV) {
209
omap_i2c_reset(DEVICE(s));
210
+ } else if (s->revision >= OMAP3_INTR_REV) {
211
+ s->sysc = value & 0x031d;
215
case 0x24: /* I2C_CON */
216
- s->control = value & 0xcf87;
217
+ s->control = value & (s->revision < OMAP3_INTR_REV ? 0xcf87 : 0xbff3);
218
if (~value & (1 << 15)) { /* I2C_EN */
219
if (s->revision < OMAP2_INTR_REV) {
220
omap_i2c_reset(DEVICE(s));
224
+ if (s->revision >= OMAP3_INTR_REV && ((value >> 12) & 3) > 1) { /* OPMODE */
226
+ "%s: only FS and HS modes are supported\n",
230
if ((value & (1 << 10))) { /* MST */
231
if (value & 1) { /* STT */
232
- nack = !!i2c_start_transfer(s->bus, s->addr[1], /*SA*/
233
+ nack = !!i2c_start_transfer(s->bus, s->slave_addr, /*SA*/
234
(~value >> 9) & 1); /* TRX */
235
s->stat |= nack << 1; /* NACK */
236
s->control &= ~(1 << 0); /* STT */
237
@@ -392,13 +461,17 @@ static void omap_i2c_write(void *opaque, hwaddr addr,
242
- case 0x28: /* I2C_OA */
243
- s->addr[0] = value & 0x3ff;
244
+ case 0x28: /* I2C_OA / I2C_OA0 */
245
+ s->own_addr[0] = value & (s->revision < OMAP3_INTR_REV
247
+ /*i2c_set_slave_address(&s->slave[0],
248
+ value & (s->revision >= OMAP3_INTR_REV
249
+ && (s->control & 0x80)
253
case 0x2c: /* I2C_SA */
254
- s->addr[1] = value & 0x3ff;
255
+ s->slave_addr = value & 0x3ff;
258
case 0x30: /* I2C_PSC */
259
@@ -406,27 +479,53 @@ static void omap_i2c_write(void *opaque, hwaddr addr,
262
case 0x34: /* I2C_SCLL */
263
- s->times[0] = value;
264
+ s->times[0] = value & (s->revision < OMAP3_INTR_REV ? 0xff : 0xffff);
267
case 0x38: /* I2C_SCLH */
268
- s->times[1] = value;
269
+ s->times[1] = value & (s->revision < OMAP3_INTR_REV ? 0xff : 0xffff);
272
case 0x3c: /* I2C_SYSTEST */
273
- s->test = value & 0xf80f;
274
+ value &= s->revision < OMAP3_INTR_REV ? 0xf805 : 0xf815;
275
+ if ((value & (1 << 15))) { /* ST_EN */
276
+ fprintf(stderr, "%s: System Test not supported\n",
278
+ s->test = (s->test & 0x0a) | value;
280
+ s->test = (s->test & 0x1f) | (value & 0xf800);
281
if (value & (1 << 11)) /* SBB */
282
if (s->revision >= OMAP2_INTR_REV) {
284
+ if (s->revision >= OMAP3_INTR_REV)
286
omap_i2c_interrupts_update(s);
288
- if (value & (1 << 15)) /* ST_EN */
289
- fprintf(stderr, "%s: System Test not supported\n", __FUNCTION__);
292
+ case 0x44: /* I2C_OA1 */
293
+ case 0x48: /* I2C_OA2 */
294
+ case 0x4c: /* I2C_OA3 */
295
+ if (s->revision < OMAP3_INTR_REV)
296
+ OMAP_BAD_REG(addr);
298
+ addr = (addr >> 2) & 3;
299
+ s->own_addr[addr] = value & 0x3ff;
300
+ /*i2c_set_slave_address(&s->slave[addr],
301
+ value & ((s->control & (0x80 >> addr))
305
+ case 0x54: /* I2C_SBLOCK */
306
+ if (s->revision < OMAP3_INTR_REV)
307
+ OMAP_BAD_REG(addr);
309
+ s->sblock = value & 0x0f;