Statistics
| Branch: | Revision:

root / hw / omap_i2c.c @ 37952117

History | View | Annotate | Download (13.6 kB)

1 02645926 balrog
/*
2 02645926 balrog
 * TI OMAP on-chip I2C controller.  Only "new I2C" mode supported.
3 02645926 balrog
 *
4 02645926 balrog
 * Copyright (C) 2007 Andrzej Zaborowski  <balrog@zabor.org>
5 02645926 balrog
 *
6 02645926 balrog
 * This program is free software; you can redistribute it and/or
7 02645926 balrog
 * modify it under the terms of the GNU General Public License as
8 02645926 balrog
 * published by the Free Software Foundation; either version 2 of
9 02645926 balrog
 * the License, or (at your option) any later version.
10 02645926 balrog
 *
11 02645926 balrog
 * This program is distributed in the hope that it will be useful,
12 02645926 balrog
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 02645926 balrog
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 02645926 balrog
 * GNU General Public License for more details.
15 02645926 balrog
 *
16 fad6cb1a aurel32
 * You should have received a copy of the GNU General Public License along
17 8167ee88 Blue Swirl
 * with this program; if not, see <http://www.gnu.org/licenses/>.
18 02645926 balrog
 */
19 87ecb68b pbrook
#include "hw.h"
20 87ecb68b pbrook
#include "i2c.h"
21 87ecb68b pbrook
#include "omap.h"
22 54e17933 Juha Riihimäki
#include "sysbus.h"
23 02645926 balrog
24 54e17933 Juha Riihimäki
25 54e17933 Juha Riihimäki
typedef struct OMAPI2CState {
26 54e17933 Juha Riihimäki
    SysBusDevice busdev;
27 74878139 Benoît Canet
    MemoryRegion iomem;
28 02645926 balrog
    qemu_irq irq;
29 02645926 balrog
    qemu_irq drq[2];
30 02645926 balrog
    i2c_bus *bus;
31 02645926 balrog
32 29885477 balrog
    uint8_t revision;
33 54e17933 Juha Riihimäki
    void *iclk;
34 54e17933 Juha Riihimäki
    void *fclk;
35 54e17933 Juha Riihimäki
36 02645926 balrog
    uint8_t mask;
37 02645926 balrog
    uint16_t stat;
38 02645926 balrog
    uint16_t dma;
39 02645926 balrog
    uint16_t count;
40 02645926 balrog
    int count_cur;
41 02645926 balrog
    uint32_t fifo;
42 02645926 balrog
    int rxlen;
43 02645926 balrog
    int txlen;
44 02645926 balrog
    uint16_t control;
45 02645926 balrog
    uint16_t addr[2];
46 02645926 balrog
    uint8_t divider;
47 02645926 balrog
    uint8_t times[2];
48 02645926 balrog
    uint16_t test;
49 54e17933 Juha Riihimäki
} OMAPI2CState;
50 02645926 balrog
51 29885477 balrog
#define OMAP2_INTR_REV        0x34
52 29885477 balrog
#define OMAP2_GC_REV        0x34
53 29885477 balrog
54 54e17933 Juha Riihimäki
static void omap_i2c_interrupts_update(OMAPI2CState *s)
55 02645926 balrog
{
56 02645926 balrog
    qemu_set_irq(s->irq, s->stat & s->mask);
57 02645926 balrog
    if ((s->dma >> 15) & 1)                                        /* RDMA_EN */
58 02645926 balrog
        qemu_set_irq(s->drq[0], (s->stat >> 3) & 1);                /* RRDY */
59 02645926 balrog
    if ((s->dma >> 7) & 1)                                        /* XDMA_EN */
60 02645926 balrog
        qemu_set_irq(s->drq[1], (s->stat >> 4) & 1);                /* XRDY */
61 02645926 balrog
}
62 02645926 balrog
63 54e17933 Juha Riihimäki
static void omap_i2c_fifo_run(OMAPI2CState *s)
64 02645926 balrog
{
65 02645926 balrog
    int ack = 1;
66 02645926 balrog
67 02645926 balrog
    if (!i2c_bus_busy(s->bus))
68 02645926 balrog
        return;
69 02645926 balrog
70 02645926 balrog
    if ((s->control >> 2) & 1) {                                /* RM */
71 02645926 balrog
        if ((s->control >> 1) & 1) {                                /* STP */
72 02645926 balrog
            i2c_end_transfer(s->bus);
73 02645926 balrog
            s->control &= ~(1 << 1);                                /* STP */
74 02645926 balrog
            s->count_cur = s->count;
75 29885477 balrog
            s->txlen = 0;
76 02645926 balrog
        } else if ((s->control >> 9) & 1) {                        /* TRX */
77 02645926 balrog
            while (ack && s->txlen)
78 02645926 balrog
                ack = (i2c_send(s->bus,
79 02645926 balrog
                                        (s->fifo >> ((-- s->txlen) << 3)) &
80 02645926 balrog
                                        0xff) >= 0);
81 02645926 balrog
            s->stat |= 1 << 4;                                        /* XRDY */
82 02645926 balrog
        } else {
83 02645926 balrog
            while (s->rxlen < 4)
84 02645926 balrog
                s->fifo |= i2c_recv(s->bus) << ((s->rxlen ++) << 3);
85 02645926 balrog
            s->stat |= 1 << 3;                                        /* RRDY */
86 02645926 balrog
        }
87 02645926 balrog
    } else {
88 02645926 balrog
        if ((s->control >> 9) & 1) {                                /* TRX */
89 02645926 balrog
            while (ack && s->count_cur && s->txlen) {
90 02645926 balrog
                ack = (i2c_send(s->bus,
91 02645926 balrog
                                        (s->fifo >> ((-- s->txlen) << 3)) &
92 02645926 balrog
                                        0xff) >= 0);
93 02645926 balrog
                s->count_cur --;
94 02645926 balrog
            }
95 02645926 balrog
            if (ack && s->count_cur)
96 02645926 balrog
                s->stat |= 1 << 4;                                /* XRDY */
97 827df9f3 balrog
            else
98 827df9f3 balrog
                s->stat &= ~(1 << 4);                                /* XRDY */
99 02645926 balrog
            if (!s->count_cur) {
100 02645926 balrog
                s->stat |= 1 << 2;                                /* ARDY */
101 02645926 balrog
                s->control &= ~(1 << 10);                        /* MST */
102 02645926 balrog
            }
103 02645926 balrog
        } else {
104 02645926 balrog
            while (s->count_cur && s->rxlen < 4) {
105 02645926 balrog
                s->fifo |= i2c_recv(s->bus) << ((s->rxlen ++) << 3);
106 02645926 balrog
                s->count_cur --;
107 02645926 balrog
            }
108 02645926 balrog
            if (s->rxlen)
109 02645926 balrog
                s->stat |= 1 << 3;                                /* RRDY */
110 827df9f3 balrog
            else
111 827df9f3 balrog
                s->stat &= ~(1 << 3);                                /* RRDY */
112 02645926 balrog
        }
113 02645926 balrog
        if (!s->count_cur) {
114 02645926 balrog
            if ((s->control >> 1) & 1) {                        /* STP */
115 02645926 balrog
                i2c_end_transfer(s->bus);
116 02645926 balrog
                s->control &= ~(1 << 1);                        /* STP */
117 02645926 balrog
                s->count_cur = s->count;
118 29885477 balrog
                s->txlen = 0;
119 02645926 balrog
            } else {
120 02645926 balrog
                s->stat |= 1 << 2;                                /* ARDY */
121 02645926 balrog
                s->control &= ~(1 << 10);                        /* MST */
122 02645926 balrog
            }
123 02645926 balrog
        }
124 02645926 balrog
    }
125 02645926 balrog
126 02645926 balrog
    s->stat |= (!ack) << 1;                                        /* NACK */
127 02645926 balrog
    if (!ack)
128 02645926 balrog
        s->control &= ~(1 << 1);                                /* STP */
129 02645926 balrog
}
130 02645926 balrog
131 54e17933 Juha Riihimäki
static void omap_i2c_reset(DeviceState *dev)
132 02645926 balrog
{
133 54e17933 Juha Riihimäki
    OMAPI2CState *s = FROM_SYSBUS(OMAPI2CState,
134 54e17933 Juha Riihimäki
                                  sysbus_from_qdev(dev));
135 02645926 balrog
    s->mask = 0;
136 02645926 balrog
    s->stat = 0;
137 02645926 balrog
    s->dma = 0;
138 02645926 balrog
    s->count = 0;
139 02645926 balrog
    s->count_cur = 0;
140 02645926 balrog
    s->fifo = 0;
141 02645926 balrog
    s->rxlen = 0;
142 02645926 balrog
    s->txlen = 0;
143 02645926 balrog
    s->control = 0;
144 02645926 balrog
    s->addr[0] = 0;
145 02645926 balrog
    s->addr[1] = 0;
146 02645926 balrog
    s->divider = 0;
147 02645926 balrog
    s->times[0] = 0;
148 02645926 balrog
    s->times[1] = 0;
149 02645926 balrog
    s->test = 0;
150 02645926 balrog
}
151 02645926 balrog
152 c227f099 Anthony Liguori
static uint32_t omap_i2c_read(void *opaque, target_phys_addr_t addr)
153 02645926 balrog
{
154 54e17933 Juha Riihimäki
    OMAPI2CState *s = opaque;
155 cf965d24 balrog
    int offset = addr & OMAP_MPUI_REG_MASK;
156 02645926 balrog
    uint16_t ret;
157 02645926 balrog
158 02645926 balrog
    switch (offset) {
159 02645926 balrog
    case 0x00:        /* I2C_REV */
160 29885477 balrog
        return s->revision;                                        /* REV */
161 02645926 balrog
162 02645926 balrog
    case 0x04:        /* I2C_IE */
163 02645926 balrog
        return s->mask;
164 02645926 balrog
165 02645926 balrog
    case 0x08:        /* I2C_STAT */
166 02645926 balrog
        return s->stat | (i2c_bus_busy(s->bus) << 12);
167 02645926 balrog
168 02645926 balrog
    case 0x0c:        /* I2C_IV */
169 29885477 balrog
        if (s->revision >= OMAP2_INTR_REV)
170 29885477 balrog
            break;
171 02645926 balrog
        ret = ffs(s->stat & s->mask);
172 02645926 balrog
        if (ret)
173 02645926 balrog
            s->stat ^= 1 << (ret - 1);
174 02645926 balrog
        omap_i2c_interrupts_update(s);
175 02645926 balrog
        return ret;
176 02645926 balrog
177 29885477 balrog
    case 0x10:        /* I2C_SYSS */
178 29885477 balrog
        return (s->control >> 15) & 1;                                /* I2C_EN */
179 29885477 balrog
180 02645926 balrog
    case 0x14:        /* I2C_BUF */
181 02645926 balrog
        return s->dma;
182 02645926 balrog
183 02645926 balrog
    case 0x18:        /* I2C_CNT */
184 02645926 balrog
        return s->count_cur;                                        /* DCOUNT */
185 02645926 balrog
186 02645926 balrog
    case 0x1c:        /* I2C_DATA */
187 02645926 balrog
        ret = 0;
188 02645926 balrog
        if (s->control & (1 << 14)) {                                /* BE */
189 02645926 balrog
            ret |= ((s->fifo >> 0) & 0xff) << 8;
190 02645926 balrog
            ret |= ((s->fifo >> 8) & 0xff) << 0;
191 02645926 balrog
        } else {
192 02645926 balrog
            ret |= ((s->fifo >> 8) & 0xff) << 8;
193 02645926 balrog
            ret |= ((s->fifo >> 0) & 0xff) << 0;
194 02645926 balrog
        }
195 02645926 balrog
        if (s->rxlen == 1) {
196 02645926 balrog
            s->stat |= 1 << 15;                                        /* SBD */
197 02645926 balrog
            s->rxlen = 0;
198 02645926 balrog
        } else if (s->rxlen > 1) {
199 02645926 balrog
            if (s->rxlen > 2)
200 02645926 balrog
                s->fifo >>= 16;
201 02645926 balrog
            s->rxlen -= 2;
202 3ffd710e Blue Swirl
        } else {
203 3ffd710e Blue Swirl
            /* XXX: remote access (qualifier) error - what's that?  */
204 3ffd710e Blue Swirl
        }
205 02645926 balrog
        if (!s->rxlen) {
206 29885477 balrog
            s->stat &= ~(1 << 3);                                /* RRDY */
207 02645926 balrog
            if (((s->control >> 10) & 1) &&                        /* MST */
208 02645926 balrog
                            ((~s->control >> 9) & 1)) {                /* TRX */
209 02645926 balrog
                s->stat |= 1 << 2;                                /* ARDY */
210 02645926 balrog
                s->control &= ~(1 << 10);                        /* MST */
211 02645926 balrog
            }
212 02645926 balrog
        }
213 02645926 balrog
        s->stat &= ~(1 << 11);                                        /* ROVR */
214 02645926 balrog
        omap_i2c_fifo_run(s);
215 02645926 balrog
        omap_i2c_interrupts_update(s);
216 02645926 balrog
        return ret;
217 02645926 balrog
218 29885477 balrog
    case 0x20:        /* I2C_SYSC */
219 29885477 balrog
        return 0;
220 29885477 balrog
221 02645926 balrog
    case 0x24:        /* I2C_CON */
222 02645926 balrog
        return s->control;
223 02645926 balrog
224 02645926 balrog
    case 0x28:        /* I2C_OA */
225 02645926 balrog
        return s->addr[0];
226 02645926 balrog
227 02645926 balrog
    case 0x2c:        /* I2C_SA */
228 02645926 balrog
        return s->addr[1];
229 02645926 balrog
230 02645926 balrog
    case 0x30:        /* I2C_PSC */
231 02645926 balrog
        return s->divider;
232 02645926 balrog
233 02645926 balrog
    case 0x34:        /* I2C_SCLL */
234 02645926 balrog
        return s->times[0];
235 02645926 balrog
236 02645926 balrog
    case 0x38:        /* I2C_SCLH */
237 02645926 balrog
        return s->times[1];
238 02645926 balrog
239 02645926 balrog
    case 0x3c:        /* I2C_SYSTEST */
240 02645926 balrog
        if (s->test & (1 << 15)) {                                /* ST_EN */
241 02645926 balrog
            s->test ^= 0xa;
242 02645926 balrog
            return s->test;
243 02645926 balrog
        } else
244 02645926 balrog
            return s->test & ~0x300f;
245 02645926 balrog
    }
246 02645926 balrog
247 02645926 balrog
    OMAP_BAD_REG(addr);
248 02645926 balrog
    return 0;
249 02645926 balrog
}
250 02645926 balrog
251 c227f099 Anthony Liguori
static void omap_i2c_write(void *opaque, target_phys_addr_t addr,
252 02645926 balrog
                uint32_t value)
253 02645926 balrog
{
254 54e17933 Juha Riihimäki
    OMAPI2CState *s = opaque;
255 cf965d24 balrog
    int offset = addr & OMAP_MPUI_REG_MASK;
256 02645926 balrog
    int nack;
257 02645926 balrog
258 02645926 balrog
    switch (offset) {
259 02645926 balrog
    case 0x00:        /* I2C_REV */
260 02645926 balrog
    case 0x0c:        /* I2C_IV */
261 29885477 balrog
    case 0x10:        /* I2C_SYSS */
262 29885477 balrog
        OMAP_RO_REG(addr);
263 02645926 balrog
        return;
264 02645926 balrog
265 02645926 balrog
    case 0x04:        /* I2C_IE */
266 29885477 balrog
        s->mask = value & (s->revision < OMAP2_GC_REV ? 0x1f : 0x3f);
267 29885477 balrog
        break;
268 29885477 balrog
269 29885477 balrog
    case 0x08:        /* I2C_STAT */
270 29885477 balrog
        if (s->revision < OMAP2_INTR_REV) {
271 29885477 balrog
            OMAP_RO_REG(addr);
272 29885477 balrog
            return;
273 29885477 balrog
        }
274 29885477 balrog
275 827df9f3 balrog
        /* RRDY and XRDY are reset by hardware. (in all versions???) */
276 827df9f3 balrog
        s->stat &= ~(value & 0x27);
277 29885477 balrog
        omap_i2c_interrupts_update(s);
278 02645926 balrog
        break;
279 02645926 balrog
280 02645926 balrog
    case 0x14:        /* I2C_BUF */
281 02645926 balrog
        s->dma = value & 0x8080;
282 02645926 balrog
        if (value & (1 << 15))                                        /* RDMA_EN */
283 02645926 balrog
            s->mask &= ~(1 << 3);                                /* RRDY_IE */
284 02645926 balrog
        if (value & (1 << 7))                                        /* XDMA_EN */
285 02645926 balrog
            s->mask &= ~(1 << 4);                                /* XRDY_IE */
286 02645926 balrog
        break;
287 02645926 balrog
288 02645926 balrog
    case 0x18:        /* I2C_CNT */
289 02645926 balrog
        s->count = value;                                        /* DCOUNT */
290 02645926 balrog
        break;
291 02645926 balrog
292 02645926 balrog
    case 0x1c:        /* I2C_DATA */
293 02645926 balrog
        if (s->txlen > 2) {
294 02645926 balrog
            /* XXX: remote access (qualifier) error - what's that?  */
295 02645926 balrog
            break;
296 02645926 balrog
        }
297 02645926 balrog
        s->fifo <<= 16;
298 02645926 balrog
        s->txlen += 2;
299 02645926 balrog
        if (s->control & (1 << 14)) {                                /* BE */
300 02645926 balrog
            s->fifo |= ((value >> 8) & 0xff) << 8;
301 02645926 balrog
            s->fifo |= ((value >> 0) & 0xff) << 0;
302 02645926 balrog
        } else {
303 02645926 balrog
            s->fifo |= ((value >> 0) & 0xff) << 8;
304 02645926 balrog
            s->fifo |= ((value >> 8) & 0xff) << 0;
305 02645926 balrog
        }
306 02645926 balrog
        s->stat &= ~(1 << 10);                                        /* XUDF */
307 02645926 balrog
        if (s->txlen > 2)
308 02645926 balrog
            s->stat &= ~(1 << 4);                                /* XRDY */
309 02645926 balrog
        omap_i2c_fifo_run(s);
310 02645926 balrog
        omap_i2c_interrupts_update(s);
311 02645926 balrog
        break;
312 02645926 balrog
313 29885477 balrog
    case 0x20:        /* I2C_SYSC */
314 29885477 balrog
        if (s->revision < OMAP2_INTR_REV) {
315 29885477 balrog
            OMAP_BAD_REG(addr);
316 29885477 balrog
            return;
317 29885477 balrog
        }
318 29885477 balrog
319 29885477 balrog
        if (value & 2)
320 54e17933 Juha Riihimäki
            omap_i2c_reset(&s->busdev.qdev);
321 29885477 balrog
        break;
322 29885477 balrog
323 02645926 balrog
    case 0x24:        /* I2C_CON */
324 29885477 balrog
        s->control = value & 0xcf87;
325 02645926 balrog
        if (~value & (1 << 15)) {                                /* I2C_EN */
326 29885477 balrog
            if (s->revision < OMAP2_INTR_REV)
327 54e17933 Juha Riihimäki
                omap_i2c_reset(&s->busdev.qdev);
328 02645926 balrog
            break;
329 02645926 balrog
        }
330 29885477 balrog
        if ((value & (1 << 15)) && !(value & (1 << 10))) {        /* MST */
331 827df9f3 balrog
            fprintf(stderr, "%s: I^2C slave mode not supported\n",
332 827df9f3 balrog
                            __FUNCTION__);
333 02645926 balrog
            break;
334 02645926 balrog
        }
335 29885477 balrog
        if ((value & (1 << 15)) && value & (1 << 8)) {                /* XA */
336 827df9f3 balrog
            fprintf(stderr, "%s: 10-bit addressing mode not supported\n",
337 827df9f3 balrog
                            __FUNCTION__);
338 02645926 balrog
            break;
339 02645926 balrog
        }
340 29885477 balrog
        if ((value & (1 << 15)) && value & (1 << 0)) {                /* STT */
341 02645926 balrog
            nack = !!i2c_start_transfer(s->bus, s->addr[1],        /* SA */
342 02645926 balrog
                            (~value >> 9) & 1);                        /* TRX */
343 02645926 balrog
            s->stat |= nack << 1;                                /* NACK */
344 02645926 balrog
            s->control &= ~(1 << 0);                                /* STT */
345 51fec3cc balrog
            s->fifo = 0;
346 02645926 balrog
            if (nack)
347 02645926 balrog
                s->control &= ~(1 << 1);                        /* STP */
348 29885477 balrog
            else {
349 29885477 balrog
                s->count_cur = s->count;
350 02645926 balrog
                omap_i2c_fifo_run(s);
351 29885477 balrog
            }
352 02645926 balrog
            omap_i2c_interrupts_update(s);
353 02645926 balrog
        }
354 02645926 balrog
        break;
355 02645926 balrog
356 02645926 balrog
    case 0x28:        /* I2C_OA */
357 02645926 balrog
        s->addr[0] = value & 0x3ff;
358 02645926 balrog
        break;
359 02645926 balrog
360 02645926 balrog
    case 0x2c:        /* I2C_SA */
361 02645926 balrog
        s->addr[1] = value & 0x3ff;
362 02645926 balrog
        break;
363 02645926 balrog
364 02645926 balrog
    case 0x30:        /* I2C_PSC */
365 02645926 balrog
        s->divider = value;
366 02645926 balrog
        break;
367 02645926 balrog
368 02645926 balrog
    case 0x34:        /* I2C_SCLL */
369 02645926 balrog
        s->times[0] = value;
370 02645926 balrog
        break;
371 02645926 balrog
372 02645926 balrog
    case 0x38:        /* I2C_SCLH */
373 02645926 balrog
        s->times[1] = value;
374 02645926 balrog
        break;
375 02645926 balrog
376 02645926 balrog
    case 0x3c:        /* I2C_SYSTEST */
377 29885477 balrog
        s->test = value & 0xf80f;
378 29885477 balrog
        if (value & (1 << 11))                                        /* SBB */
379 29885477 balrog
            if (s->revision >= OMAP2_INTR_REV) {
380 29885477 balrog
                s->stat |= 0x3f;
381 29885477 balrog
                omap_i2c_interrupts_update(s);
382 29885477 balrog
            }
383 02645926 balrog
        if (value & (1 << 15))                                        /* ST_EN */
384 827df9f3 balrog
            fprintf(stderr, "%s: System Test not supported\n", __FUNCTION__);
385 02645926 balrog
        break;
386 02645926 balrog
387 02645926 balrog
    default:
388 02645926 balrog
        OMAP_BAD_REG(addr);
389 02645926 balrog
        return;
390 02645926 balrog
    }
391 02645926 balrog
}
392 02645926 balrog
393 c227f099 Anthony Liguori
static void omap_i2c_writeb(void *opaque, target_phys_addr_t addr,
394 29885477 balrog
                uint32_t value)
395 29885477 balrog
{
396 54e17933 Juha Riihimäki
    OMAPI2CState *s = opaque;
397 29885477 balrog
    int offset = addr & OMAP_MPUI_REG_MASK;
398 29885477 balrog
399 29885477 balrog
    switch (offset) {
400 29885477 balrog
    case 0x1c:        /* I2C_DATA */
401 29885477 balrog
        if (s->txlen > 2) {
402 29885477 balrog
            /* XXX: remote access (qualifier) error - what's that?  */
403 29885477 balrog
            break;
404 29885477 balrog
        }
405 29885477 balrog
        s->fifo <<= 8;
406 29885477 balrog
        s->txlen += 1;
407 29885477 balrog
        s->fifo |= value & 0xff;
408 29885477 balrog
        s->stat &= ~(1 << 10);                                        /* XUDF */
409 29885477 balrog
        if (s->txlen > 2)
410 29885477 balrog
            s->stat &= ~(1 << 4);                                /* XRDY */
411 29885477 balrog
        omap_i2c_fifo_run(s);
412 29885477 balrog
        omap_i2c_interrupts_update(s);
413 29885477 balrog
        break;
414 29885477 balrog
415 29885477 balrog
    default:
416 29885477 balrog
        OMAP_BAD_REG(addr);
417 29885477 balrog
        return;
418 29885477 balrog
    }
419 29885477 balrog
}
420 29885477 balrog
421 74878139 Benoît Canet
static const MemoryRegionOps omap_i2c_ops = {
422 74878139 Benoît Canet
    .old_mmio = {
423 74878139 Benoît Canet
        .read = {
424 74878139 Benoît Canet
            omap_badwidth_read16,
425 74878139 Benoît Canet
            omap_i2c_read,
426 74878139 Benoît Canet
            omap_badwidth_read16,
427 74878139 Benoît Canet
        },
428 74878139 Benoît Canet
        .write = {
429 74878139 Benoît Canet
            omap_i2c_writeb, /* Only the last fifo write can be 8 bit.  */
430 74878139 Benoît Canet
            omap_i2c_write,
431 74878139 Benoît Canet
            omap_badwidth_write16,
432 74878139 Benoît Canet
        },
433 74878139 Benoît Canet
    },
434 74878139 Benoît Canet
    .endianness = DEVICE_NATIVE_ENDIAN,
435 02645926 balrog
};
436 02645926 balrog
437 54e17933 Juha Riihimäki
static int omap_i2c_init(SysBusDevice *dev)
438 02645926 balrog
{
439 54e17933 Juha Riihimäki
    OMAPI2CState *s = FROM_SYSBUS(OMAPI2CState, dev);
440 02645926 balrog
441 54e17933 Juha Riihimäki
    if (!s->fclk) {
442 54e17933 Juha Riihimäki
        hw_error("omap_i2c: fclk not connected\n");
443 54e17933 Juha Riihimäki
    }
444 54e17933 Juha Riihimäki
    if (s->revision >= OMAP2_INTR_REV && !s->iclk) {
445 54e17933 Juha Riihimäki
        /* Note that OMAP1 doesn't have a separate interface clock */
446 54e17933 Juha Riihimäki
        hw_error("omap_i2c: iclk not connected\n");
447 54e17933 Juha Riihimäki
    }
448 54e17933 Juha Riihimäki
    sysbus_init_irq(dev, &s->irq);
449 54e17933 Juha Riihimäki
    sysbus_init_irq(dev, &s->drq[0]);
450 54e17933 Juha Riihimäki
    sysbus_init_irq(dev, &s->drq[1]);
451 54e17933 Juha Riihimäki
    memory_region_init_io(&s->iomem, &omap_i2c_ops, s, "omap.i2c",
452 54e17933 Juha Riihimäki
                          (s->revision < OMAP2_INTR_REV) ? 0x800 : 0x1000);
453 54e17933 Juha Riihimäki
    sysbus_init_mmio(dev, &s->iomem);
454 54e17933 Juha Riihimäki
    s->bus = i2c_init_bus(&dev->qdev, NULL);
455 54e17933 Juha Riihimäki
    return 0;
456 02645926 balrog
}
457 02645926 balrog
458 54e17933 Juha Riihimäki
static Property omap_i2c_properties[] = {
459 54e17933 Juha Riihimäki
    DEFINE_PROP_UINT8("revision", OMAPI2CState, revision, 0),
460 54e17933 Juha Riihimäki
    DEFINE_PROP_PTR("iclk", OMAPI2CState, iclk),
461 54e17933 Juha Riihimäki
    DEFINE_PROP_PTR("fclk", OMAPI2CState, fclk),
462 54e17933 Juha Riihimäki
    DEFINE_PROP_END_OF_LIST(),
463 54e17933 Juha Riihimäki
};
464 29885477 balrog
465 54e17933 Juha Riihimäki
static void omap_i2c_class_init(ObjectClass *klass, void *data)
466 54e17933 Juha Riihimäki
{
467 54e17933 Juha Riihimäki
    DeviceClass *dc = DEVICE_CLASS(klass);
468 54e17933 Juha Riihimäki
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
469 54e17933 Juha Riihimäki
    k->init = omap_i2c_init;
470 54e17933 Juha Riihimäki
    dc->props = omap_i2c_properties;
471 54e17933 Juha Riihimäki
    dc->reset = omap_i2c_reset;
472 54e17933 Juha Riihimäki
}
473 29885477 balrog
474 54e17933 Juha Riihimäki
static TypeInfo omap_i2c_info = {
475 54e17933 Juha Riihimäki
    .name = "omap_i2c",
476 54e17933 Juha Riihimäki
    .parent = TYPE_SYS_BUS_DEVICE,
477 54e17933 Juha Riihimäki
    .instance_size = sizeof(OMAPI2CState),
478 54e17933 Juha Riihimäki
    .class_init = omap_i2c_class_init,
479 54e17933 Juha Riihimäki
};
480 29885477 balrog
481 54e17933 Juha Riihimäki
static void omap_i2c_register_types(void)
482 54e17933 Juha Riihimäki
{
483 54e17933 Juha Riihimäki
    type_register_static(&omap_i2c_info);
484 29885477 balrog
}
485 29885477 balrog
486 54e17933 Juha Riihimäki
i2c_bus *omap_i2c_bus(DeviceState *omap_i2c)
487 02645926 balrog
{
488 54e17933 Juha Riihimäki
    OMAPI2CState *s = FROM_SYSBUS(OMAPI2CState, sysbus_from_qdev(omap_i2c));
489 02645926 balrog
    return s->bus;
490 02645926 balrog
}
491 54e17933 Juha Riihimäki
492 54e17933 Juha Riihimäki
type_init(omap_i2c_register_types)