Revision 54e17933 hw/omap_i2c.c

b/hw/omap_i2c.c
19 19
#include "hw.h"
20 20
#include "i2c.h"
21 21
#include "omap.h"
22
#include "sysbus.h"
22 23

  
23
struct omap_i2c_s {
24

  
25
typedef struct OMAPI2CState {
26
    SysBusDevice busdev;
24 27
    MemoryRegion iomem;
25 28
    qemu_irq irq;
26 29
    qemu_irq drq[2];
27 30
    i2c_bus *bus;
28 31

  
29 32
    uint8_t revision;
33
    void *iclk;
34
    void *fclk;
35

  
30 36
    uint8_t mask;
31 37
    uint16_t stat;
32 38
    uint16_t dma;
......
40 46
    uint8_t divider;
41 47
    uint8_t times[2];
42 48
    uint16_t test;
43
};
49
} OMAPI2CState;
44 50

  
45 51
#define OMAP2_INTR_REV	0x34
46 52
#define OMAP2_GC_REV	0x34
47 53

  
48
static void omap_i2c_interrupts_update(struct omap_i2c_s *s)
54
static void omap_i2c_interrupts_update(OMAPI2CState *s)
49 55
{
50 56
    qemu_set_irq(s->irq, s->stat & s->mask);
51 57
    if ((s->dma >> 15) & 1)					/* RDMA_EN */
......
54 60
        qemu_set_irq(s->drq[1], (s->stat >> 4) & 1);		/* XRDY */
55 61
}
56 62

  
57
static void omap_i2c_fifo_run(struct omap_i2c_s *s)
63
static void omap_i2c_fifo_run(OMAPI2CState *s)
58 64
{
59 65
    int ack = 1;
60 66

  
......
122 128
        s->control &= ~(1 << 1);				/* STP */
123 129
}
124 130

  
125
void omap_i2c_reset(struct omap_i2c_s *s)
131
static void omap_i2c_reset(DeviceState *dev)
126 132
{
133
    OMAPI2CState *s = FROM_SYSBUS(OMAPI2CState,
134
                                  sysbus_from_qdev(dev));
127 135
    s->mask = 0;
128 136
    s->stat = 0;
129 137
    s->dma = 0;
......
143 151

  
144 152
static uint32_t omap_i2c_read(void *opaque, target_phys_addr_t addr)
145 153
{
146
    struct omap_i2c_s *s = (struct omap_i2c_s *) opaque;
154
    OMAPI2CState *s = opaque;
147 155
    int offset = addr & OMAP_MPUI_REG_MASK;
148 156
    uint16_t ret;
149 157

  
......
243 251
static void omap_i2c_write(void *opaque, target_phys_addr_t addr,
244 252
                uint32_t value)
245 253
{
246
    struct omap_i2c_s *s = (struct omap_i2c_s *) opaque;
254
    OMAPI2CState *s = opaque;
247 255
    int offset = addr & OMAP_MPUI_REG_MASK;
248 256
    int nack;
249 257

  
......
309 317
        }
310 318

  
311 319
        if (value & 2)
312
            omap_i2c_reset(s);
320
            omap_i2c_reset(&s->busdev.qdev);
313 321
        break;
314 322

  
315 323
    case 0x24:	/* I2C_CON */
316 324
        s->control = value & 0xcf87;
317 325
        if (~value & (1 << 15)) {				/* I2C_EN */
318 326
            if (s->revision < OMAP2_INTR_REV)
319
                omap_i2c_reset(s);
327
                omap_i2c_reset(&s->busdev.qdev);
320 328
            break;
321 329
        }
322 330
        if ((value & (1 << 15)) && !(value & (1 << 10))) {	/* MST */
......
385 393
static void omap_i2c_writeb(void *opaque, target_phys_addr_t addr,
386 394
                uint32_t value)
387 395
{
388
    struct omap_i2c_s *s = (struct omap_i2c_s *) opaque;
396
    OMAPI2CState *s = opaque;
389 397
    int offset = addr & OMAP_MPUI_REG_MASK;
390 398

  
391 399
    switch (offset) {
......
426 434
    .endianness = DEVICE_NATIVE_ENDIAN,
427 435
};
428 436

  
429
struct omap_i2c_s *omap_i2c_init(MemoryRegion *sysmem,
430
                                 target_phys_addr_t base,
431
                                 qemu_irq irq,
432
                                 qemu_irq *dma,
433
                                 omap_clk clk)
437
static int omap_i2c_init(SysBusDevice *dev)
434 438
{
435
    struct omap_i2c_s *s = (struct omap_i2c_s *)
436
            g_malloc0(sizeof(struct omap_i2c_s));
437

  
438
    /* TODO: set a value greater or equal to real hardware */
439
    s->revision = 0x11;
440
    s->irq = irq;
441
    s->drq[0] = dma[0];
442
    s->drq[1] = dma[1];
443
    s->bus = i2c_init_bus(NULL, "i2c");
444
    omap_i2c_reset(s);
439
    OMAPI2CState *s = FROM_SYSBUS(OMAPI2CState, dev);
445 440

  
446
    memory_region_init_io(&s->iomem, &omap_i2c_ops, s, "omap.i2c", 0x800);
447
    memory_region_add_subregion(sysmem, base, &s->iomem);
448

  
449
    return s;
441
    if (!s->fclk) {
442
        hw_error("omap_i2c: fclk not connected\n");
443
    }
444
    if (s->revision >= OMAP2_INTR_REV && !s->iclk) {
445
        /* Note that OMAP1 doesn't have a separate interface clock */
446
        hw_error("omap_i2c: iclk not connected\n");
447
    }
448
    sysbus_init_irq(dev, &s->irq);
449
    sysbus_init_irq(dev, &s->drq[0]);
450
    sysbus_init_irq(dev, &s->drq[1]);
451
    memory_region_init_io(&s->iomem, &omap_i2c_ops, s, "omap.i2c",
452
                          (s->revision < OMAP2_INTR_REV) ? 0x800 : 0x1000);
453
    sysbus_init_mmio(dev, &s->iomem);
454
    s->bus = i2c_init_bus(&dev->qdev, NULL);
455
    return 0;
450 456
}
451 457

  
452
struct omap_i2c_s *omap2_i2c_init(struct omap_target_agent_s *ta,
453
                qemu_irq irq, qemu_irq *dma, omap_clk fclk, omap_clk iclk)
454
{
455
    struct omap_i2c_s *s = (struct omap_i2c_s *)
456
            g_malloc0(sizeof(struct omap_i2c_s));
458
static Property omap_i2c_properties[] = {
459
    DEFINE_PROP_UINT8("revision", OMAPI2CState, revision, 0),
460
    DEFINE_PROP_PTR("iclk", OMAPI2CState, iclk),
461
    DEFINE_PROP_PTR("fclk", OMAPI2CState, fclk),
462
    DEFINE_PROP_END_OF_LIST(),
463
};
457 464

  
458
    s->revision = 0x34;
459
    s->irq = irq;
460
    s->drq[0] = dma[0];
461
    s->drq[1] = dma[1];
462
    s->bus = i2c_init_bus(NULL, "i2c");
463
    omap_i2c_reset(s);
465
static void omap_i2c_class_init(ObjectClass *klass, void *data)
466
{
467
    DeviceClass *dc = DEVICE_CLASS(klass);
468
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
469
    k->init = omap_i2c_init;
470
    dc->props = omap_i2c_properties;
471
    dc->reset = omap_i2c_reset;
472
}
464 473

  
465
    memory_region_init_io(&s->iomem, &omap_i2c_ops, s, "omap2.i2c",
466
                          omap_l4_region_size(ta, 0));
467
    omap_l4_attach(ta, 0, &s->iomem);
474
static TypeInfo omap_i2c_info = {
475
    .name = "omap_i2c",
476
    .parent = TYPE_SYS_BUS_DEVICE,
477
    .instance_size = sizeof(OMAPI2CState),
478
    .class_init = omap_i2c_class_init,
479
};
468 480

  
469
    return s;
481
static void omap_i2c_register_types(void)
482
{
483
    type_register_static(&omap_i2c_info);
470 484
}
471 485

  
472
i2c_bus *omap_i2c_bus(struct omap_i2c_s *s)
486
i2c_bus *omap_i2c_bus(DeviceState *omap_i2c)
473 487
{
488
    OMAPI2CState *s = FROM_SYSBUS(OMAPI2CState, sysbus_from_qdev(omap_i2c));
474 489
    return s->bus;
475 490
}
491

  
492
type_init(omap_i2c_register_types)

Also available in: Unified diff