xref: /qemu/hw/i2c/mpc_i2c.c (revision 8e5c952b370b57beb642826882c80e1b66a9cf12)
17abb479cSAndrew Randrianasulu /*
27abb479cSAndrew Randrianasulu  * Copyright (C) 2014 Freescale Semiconductor, Inc. All rights reserved.
37abb479cSAndrew Randrianasulu  *
47abb479cSAndrew Randrianasulu  * Author: Amit Tomar, <Amit.Tomar@freescale.com>
57abb479cSAndrew Randrianasulu  *
67abb479cSAndrew Randrianasulu  * Description:
77abb479cSAndrew Randrianasulu  * This file is derived from IMX I2C controller,
87abb479cSAndrew Randrianasulu  * by Jean-Christophe DUBOIS .
97abb479cSAndrew Randrianasulu  *
107abb479cSAndrew Randrianasulu  * Thanks to Scott Wood and Alexander Graf for their kind help on this.
117abb479cSAndrew Randrianasulu  *
127abb479cSAndrew Randrianasulu  * This program is free software; you can redistribute it and/or modify
137abb479cSAndrew Randrianasulu  * it under the terms of the GNU General Public License, version 2 or later,
147abb479cSAndrew Randrianasulu  * as published by the Free Software Foundation.
157abb479cSAndrew Randrianasulu  *
167abb479cSAndrew Randrianasulu  * You should have received a copy of the GNU Lesser General Public
177abb479cSAndrew Randrianasulu  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
187abb479cSAndrew Randrianasulu  */
197abb479cSAndrew Randrianasulu 
207abb479cSAndrew Randrianasulu #include "qemu/osdep.h"
217abb479cSAndrew Randrianasulu #include "hw/i2c/i2c.h"
2264552b6bSMarkus Armbruster #include "hw/irq.h"
237abb479cSAndrew Randrianasulu #include "qemu/log.h"
240b8fa32fSMarkus Armbruster #include "qemu/module.h"
257abb479cSAndrew Randrianasulu #include "hw/sysbus.h"
26d6454270SMarkus Armbruster #include "migration/vmstate.h"
277abb479cSAndrew Randrianasulu 
287abb479cSAndrew Randrianasulu /* #define DEBUG_I2C */
297abb479cSAndrew Randrianasulu 
307abb479cSAndrew Randrianasulu #ifdef DEBUG_I2C
317abb479cSAndrew Randrianasulu #define DPRINTF(fmt, ...)              \
327abb479cSAndrew Randrianasulu     do { fprintf(stderr, "mpc_i2c[%s]: " fmt, __func__, ## __VA_ARGS__); \
337abb479cSAndrew Randrianasulu     } while (0)
347abb479cSAndrew Randrianasulu #else
357abb479cSAndrew Randrianasulu #define DPRINTF(fmt, ...) do {} while (0)
367abb479cSAndrew Randrianasulu #endif
377abb479cSAndrew Randrianasulu 
387abb479cSAndrew Randrianasulu #define TYPE_MPC_I2C "mpc-i2c"
397abb479cSAndrew Randrianasulu #define MPC_I2C(obj) \
407abb479cSAndrew Randrianasulu     OBJECT_CHECK(MPCI2CState, (obj), TYPE_MPC_I2C)
417abb479cSAndrew Randrianasulu 
427abb479cSAndrew Randrianasulu #define MPC_I2C_ADR   0x00
437abb479cSAndrew Randrianasulu #define MPC_I2C_FDR   0x04
447abb479cSAndrew Randrianasulu #define MPC_I2C_CR    0x08
457abb479cSAndrew Randrianasulu #define MPC_I2C_SR    0x0c
467abb479cSAndrew Randrianasulu #define MPC_I2C_DR    0x10
477abb479cSAndrew Randrianasulu #define MPC_I2C_DFSRR 0x14
487abb479cSAndrew Randrianasulu 
497abb479cSAndrew Randrianasulu #define CCR_MEN  (1 << 7)
507abb479cSAndrew Randrianasulu #define CCR_MIEN (1 << 6)
517abb479cSAndrew Randrianasulu #define CCR_MSTA (1 << 5)
527abb479cSAndrew Randrianasulu #define CCR_MTX  (1 << 4)
537abb479cSAndrew Randrianasulu #define CCR_TXAK (1 << 3)
547abb479cSAndrew Randrianasulu #define CCR_RSTA (1 << 2)
557abb479cSAndrew Randrianasulu #define CCR_BCST (1 << 0)
567abb479cSAndrew Randrianasulu 
577abb479cSAndrew Randrianasulu #define CSR_MCF  (1 << 7)
587abb479cSAndrew Randrianasulu #define CSR_MAAS (1 << 6)
597abb479cSAndrew Randrianasulu #define CSR_MBB  (1 << 5)
607abb479cSAndrew Randrianasulu #define CSR_MAL  (1 << 4)
617abb479cSAndrew Randrianasulu #define CSR_SRW  (1 << 2)
627abb479cSAndrew Randrianasulu #define CSR_MIF  (1 << 1)
637abb479cSAndrew Randrianasulu #define CSR_RXAK (1 << 0)
647abb479cSAndrew Randrianasulu 
657abb479cSAndrew Randrianasulu #define CADR_MASK 0xFE
667abb479cSAndrew Randrianasulu #define CFDR_MASK 0x3F
677abb479cSAndrew Randrianasulu #define CCR_MASK  0xFC
687abb479cSAndrew Randrianasulu #define CSR_MASK  0xED
697abb479cSAndrew Randrianasulu #define CDR_MASK  0xFF
707abb479cSAndrew Randrianasulu 
717abb479cSAndrew Randrianasulu #define CYCLE_RESET 0xFF
727abb479cSAndrew Randrianasulu 
737abb479cSAndrew Randrianasulu typedef struct MPCI2CState {
747abb479cSAndrew Randrianasulu     SysBusDevice parent_obj;
757abb479cSAndrew Randrianasulu 
767abb479cSAndrew Randrianasulu     I2CBus *bus;
777abb479cSAndrew Randrianasulu     qemu_irq irq;
787abb479cSAndrew Randrianasulu     MemoryRegion iomem;
797abb479cSAndrew Randrianasulu 
807abb479cSAndrew Randrianasulu     uint8_t address;
817abb479cSAndrew Randrianasulu     uint8_t adr;
827abb479cSAndrew Randrianasulu     uint8_t fdr;
837abb479cSAndrew Randrianasulu     uint8_t cr;
847abb479cSAndrew Randrianasulu     uint8_t sr;
857abb479cSAndrew Randrianasulu     uint8_t dr;
867abb479cSAndrew Randrianasulu     uint8_t dfssr;
877abb479cSAndrew Randrianasulu } MPCI2CState;
887abb479cSAndrew Randrianasulu 
897abb479cSAndrew Randrianasulu static bool mpc_i2c_is_enabled(MPCI2CState *s)
907abb479cSAndrew Randrianasulu {
917abb479cSAndrew Randrianasulu     return s->cr & CCR_MEN;
927abb479cSAndrew Randrianasulu }
937abb479cSAndrew Randrianasulu 
947abb479cSAndrew Randrianasulu static bool mpc_i2c_is_master(MPCI2CState *s)
957abb479cSAndrew Randrianasulu {
967abb479cSAndrew Randrianasulu     return s->cr & CCR_MSTA;
977abb479cSAndrew Randrianasulu }
987abb479cSAndrew Randrianasulu 
997abb479cSAndrew Randrianasulu static bool mpc_i2c_direction_is_tx(MPCI2CState *s)
1007abb479cSAndrew Randrianasulu {
1017abb479cSAndrew Randrianasulu     return s->cr & CCR_MTX;
1027abb479cSAndrew Randrianasulu }
1037abb479cSAndrew Randrianasulu 
1047abb479cSAndrew Randrianasulu static bool mpc_i2c_irq_pending(MPCI2CState *s)
1057abb479cSAndrew Randrianasulu {
1067abb479cSAndrew Randrianasulu     return s->sr & CSR_MIF;
1077abb479cSAndrew Randrianasulu }
1087abb479cSAndrew Randrianasulu 
1097abb479cSAndrew Randrianasulu static bool mpc_i2c_irq_is_enabled(MPCI2CState *s)
1107abb479cSAndrew Randrianasulu {
1117abb479cSAndrew Randrianasulu     return s->cr & CCR_MIEN;
1127abb479cSAndrew Randrianasulu }
1137abb479cSAndrew Randrianasulu 
1147abb479cSAndrew Randrianasulu static void mpc_i2c_reset(DeviceState *dev)
1157abb479cSAndrew Randrianasulu {
1167abb479cSAndrew Randrianasulu     MPCI2CState *i2c = MPC_I2C(dev);
1177abb479cSAndrew Randrianasulu 
1187abb479cSAndrew Randrianasulu     i2c->address = 0xFF;
1197abb479cSAndrew Randrianasulu     i2c->adr = 0x00;
1207abb479cSAndrew Randrianasulu     i2c->fdr = 0x00;
1217abb479cSAndrew Randrianasulu     i2c->cr =  0x00;
1227abb479cSAndrew Randrianasulu     i2c->sr =  0x81;
1237abb479cSAndrew Randrianasulu     i2c->dr =  0x00;
1247abb479cSAndrew Randrianasulu }
1257abb479cSAndrew Randrianasulu 
1267abb479cSAndrew Randrianasulu static void mpc_i2c_irq(MPCI2CState *s)
1277abb479cSAndrew Randrianasulu {
1287abb479cSAndrew Randrianasulu     bool irq_active = false;
1297abb479cSAndrew Randrianasulu 
1307abb479cSAndrew Randrianasulu     if (mpc_i2c_is_enabled(s) && mpc_i2c_irq_is_enabled(s)
1317abb479cSAndrew Randrianasulu                               && mpc_i2c_irq_pending(s)) {
1327abb479cSAndrew Randrianasulu         irq_active = true;
1337abb479cSAndrew Randrianasulu     }
1347abb479cSAndrew Randrianasulu 
1357abb479cSAndrew Randrianasulu     if (irq_active) {
1367abb479cSAndrew Randrianasulu         qemu_irq_raise(s->irq);
1377abb479cSAndrew Randrianasulu     } else {
1387abb479cSAndrew Randrianasulu         qemu_irq_lower(s->irq);
1397abb479cSAndrew Randrianasulu     }
1407abb479cSAndrew Randrianasulu }
1417abb479cSAndrew Randrianasulu 
1427abb479cSAndrew Randrianasulu static void mpc_i2c_soft_reset(MPCI2CState *s)
1437abb479cSAndrew Randrianasulu {
1447abb479cSAndrew Randrianasulu     /* This is a soft reset. ADR is preserved during soft resets */
1457abb479cSAndrew Randrianasulu     uint8_t adr = s->adr;
1467abb479cSAndrew Randrianasulu     mpc_i2c_reset(DEVICE(s));
1477abb479cSAndrew Randrianasulu     s->adr = adr;
1487abb479cSAndrew Randrianasulu }
1497abb479cSAndrew Randrianasulu 
1507abb479cSAndrew Randrianasulu static void  mpc_i2c_address_send(MPCI2CState *s)
1517abb479cSAndrew Randrianasulu {
1527abb479cSAndrew Randrianasulu     /* if returns non zero slave address is not right */
1537abb479cSAndrew Randrianasulu     if (i2c_start_transfer(s->bus, s->dr >> 1, s->dr & (0x01))) {
1547abb479cSAndrew Randrianasulu         s->sr |= CSR_RXAK;
1557abb479cSAndrew Randrianasulu     } else {
1567abb479cSAndrew Randrianasulu         s->address = s->dr;
1577abb479cSAndrew Randrianasulu         s->sr &= ~CSR_RXAK;
1587abb479cSAndrew Randrianasulu         s->sr |=  CSR_MCF; /* Set after Byte Transfer is completed */
1597abb479cSAndrew Randrianasulu         s->sr |=  CSR_MIF; /* Set after Byte Transfer is completed */
1607abb479cSAndrew Randrianasulu         mpc_i2c_irq(s);
1617abb479cSAndrew Randrianasulu     }
1627abb479cSAndrew Randrianasulu }
1637abb479cSAndrew Randrianasulu 
1647abb479cSAndrew Randrianasulu static void  mpc_i2c_data_send(MPCI2CState *s)
1657abb479cSAndrew Randrianasulu {
1667abb479cSAndrew Randrianasulu     if (i2c_send(s->bus, s->dr)) {
1677abb479cSAndrew Randrianasulu         /* End of transfer */
1687abb479cSAndrew Randrianasulu         s->sr |= CSR_RXAK;
1697abb479cSAndrew Randrianasulu         i2c_end_transfer(s->bus);
1707abb479cSAndrew Randrianasulu     } else {
1717abb479cSAndrew Randrianasulu         s->sr &= ~CSR_RXAK;
1727abb479cSAndrew Randrianasulu         s->sr |=  CSR_MCF; /* Set after Byte Transfer is completed */
1737abb479cSAndrew Randrianasulu         s->sr |=  CSR_MIF; /* Set after Byte Transfer is completed */
1747abb479cSAndrew Randrianasulu         mpc_i2c_irq(s);
1757abb479cSAndrew Randrianasulu     }
1767abb479cSAndrew Randrianasulu }
1777abb479cSAndrew Randrianasulu 
1787abb479cSAndrew Randrianasulu static void  mpc_i2c_data_recive(MPCI2CState *s)
1797abb479cSAndrew Randrianasulu {
1807abb479cSAndrew Randrianasulu     int ret;
1817abb479cSAndrew Randrianasulu     /* get the next byte */
1827abb479cSAndrew Randrianasulu     ret = i2c_recv(s->bus);
1837abb479cSAndrew Randrianasulu     if (ret >= 0) {
1847abb479cSAndrew Randrianasulu         s->sr |= CSR_MCF; /* Set after Byte Transfer is completed */
1857abb479cSAndrew Randrianasulu         s->sr |= CSR_MIF; /* Set after Byte Transfer is completed */
1867abb479cSAndrew Randrianasulu         mpc_i2c_irq(s);
1877abb479cSAndrew Randrianasulu     } else {
1887abb479cSAndrew Randrianasulu         DPRINTF("read failed for device");
1897abb479cSAndrew Randrianasulu         ret = 0xff;
1907abb479cSAndrew Randrianasulu     }
1917abb479cSAndrew Randrianasulu     s->dr = ret;
1927abb479cSAndrew Randrianasulu }
1937abb479cSAndrew Randrianasulu 
1947abb479cSAndrew Randrianasulu static uint64_t mpc_i2c_read(void *opaque, hwaddr addr, unsigned size)
1957abb479cSAndrew Randrianasulu {
1967abb479cSAndrew Randrianasulu     MPCI2CState *s = opaque;
1977abb479cSAndrew Randrianasulu     uint8_t value;
1987abb479cSAndrew Randrianasulu 
1997abb479cSAndrew Randrianasulu     switch (addr) {
2007abb479cSAndrew Randrianasulu     case MPC_I2C_ADR:
2017abb479cSAndrew Randrianasulu         value = s->adr;
2027abb479cSAndrew Randrianasulu         break;
2037abb479cSAndrew Randrianasulu     case MPC_I2C_FDR:
2047abb479cSAndrew Randrianasulu         value = s->fdr;
2057abb479cSAndrew Randrianasulu         break;
2067abb479cSAndrew Randrianasulu     case MPC_I2C_CR:
2077abb479cSAndrew Randrianasulu         value = s->cr;
2087abb479cSAndrew Randrianasulu         break;
2097abb479cSAndrew Randrianasulu     case MPC_I2C_SR:
2107abb479cSAndrew Randrianasulu         value = s->sr;
2117abb479cSAndrew Randrianasulu         break;
2127abb479cSAndrew Randrianasulu     case MPC_I2C_DR:
2137abb479cSAndrew Randrianasulu         value = s->dr;
2147abb479cSAndrew Randrianasulu         if (mpc_i2c_is_master(s)) { /* master mode */
2157abb479cSAndrew Randrianasulu             if (mpc_i2c_direction_is_tx(s)) {
2167abb479cSAndrew Randrianasulu                 DPRINTF("MTX is set not in recv mode\n");
2177abb479cSAndrew Randrianasulu             } else {
2187abb479cSAndrew Randrianasulu                 mpc_i2c_data_recive(s);
2197abb479cSAndrew Randrianasulu             }
2207abb479cSAndrew Randrianasulu         }
2217abb479cSAndrew Randrianasulu         break;
2227abb479cSAndrew Randrianasulu     default:
2237abb479cSAndrew Randrianasulu         value = 0;
2247abb479cSAndrew Randrianasulu         DPRINTF("ERROR: Bad read addr 0x%x\n", (unsigned int)addr);
2257abb479cSAndrew Randrianasulu         break;
2267abb479cSAndrew Randrianasulu     }
2277abb479cSAndrew Randrianasulu 
2287abb479cSAndrew Randrianasulu     DPRINTF("%s: addr " TARGET_FMT_plx " %02" PRIx32 "\n", __func__,
2297abb479cSAndrew Randrianasulu                                          addr, value);
2307abb479cSAndrew Randrianasulu     return (uint64_t)value;
2317abb479cSAndrew Randrianasulu }
2327abb479cSAndrew Randrianasulu 
2337abb479cSAndrew Randrianasulu static void mpc_i2c_write(void *opaque, hwaddr addr,
2347abb479cSAndrew Randrianasulu                             uint64_t value, unsigned size)
2357abb479cSAndrew Randrianasulu {
2367abb479cSAndrew Randrianasulu     MPCI2CState *s = opaque;
2377abb479cSAndrew Randrianasulu 
2387abb479cSAndrew Randrianasulu     DPRINTF("%s: addr " TARGET_FMT_plx " val %08" PRIx64 "\n", __func__,
2397abb479cSAndrew Randrianasulu                                              addr, value);
2407abb479cSAndrew Randrianasulu     switch (addr) {
2417abb479cSAndrew Randrianasulu     case MPC_I2C_ADR:
2427abb479cSAndrew Randrianasulu         s->adr = value & CADR_MASK;
2437abb479cSAndrew Randrianasulu         break;
2447abb479cSAndrew Randrianasulu     case MPC_I2C_FDR:
2457abb479cSAndrew Randrianasulu         s->fdr = value & CFDR_MASK;
2467abb479cSAndrew Randrianasulu         break;
2477abb479cSAndrew Randrianasulu     case MPC_I2C_CR:
2487abb479cSAndrew Randrianasulu         if (mpc_i2c_is_enabled(s) && ((value & CCR_MEN) == 0)) {
2497abb479cSAndrew Randrianasulu             mpc_i2c_soft_reset(s);
2507abb479cSAndrew Randrianasulu             break;
2517abb479cSAndrew Randrianasulu         }
2527abb479cSAndrew Randrianasulu         /* normal write */
2537abb479cSAndrew Randrianasulu         s->cr = value & CCR_MASK;
2547abb479cSAndrew Randrianasulu         if (mpc_i2c_is_master(s)) { /* master mode */
2557abb479cSAndrew Randrianasulu             /* set the bus to busy after master is set as per RM */
2567abb479cSAndrew Randrianasulu             s->sr |= CSR_MBB;
2577abb479cSAndrew Randrianasulu         } else {
2587abb479cSAndrew Randrianasulu             /* bus is not busy anymore */
2597abb479cSAndrew Randrianasulu             s->sr &= ~CSR_MBB;
2607abb479cSAndrew Randrianasulu             /* Reset the address for fresh write/read cycle */
2617abb479cSAndrew Randrianasulu         if (s->address != CYCLE_RESET) {
2627abb479cSAndrew Randrianasulu             i2c_end_transfer(s->bus);
2637abb479cSAndrew Randrianasulu             s->address = CYCLE_RESET;
2647abb479cSAndrew Randrianasulu             }
2657abb479cSAndrew Randrianasulu         }
2667abb479cSAndrew Randrianasulu         /* For restart end the onging transfer */
2677abb479cSAndrew Randrianasulu         if (s->cr & CCR_RSTA) {
2687abb479cSAndrew Randrianasulu             if (s->address != CYCLE_RESET) {
2697abb479cSAndrew Randrianasulu                 s->address = CYCLE_RESET;
2707abb479cSAndrew Randrianasulu                 i2c_end_transfer(s->bus);
2717abb479cSAndrew Randrianasulu                 s->cr &= ~CCR_RSTA;
2727abb479cSAndrew Randrianasulu             }
2737abb479cSAndrew Randrianasulu         }
2747abb479cSAndrew Randrianasulu         break;
2757abb479cSAndrew Randrianasulu     case MPC_I2C_SR:
2767abb479cSAndrew Randrianasulu         s->sr = value & CSR_MASK;
2777abb479cSAndrew Randrianasulu         /* Lower the interrupt */
2787abb479cSAndrew Randrianasulu         if (!(s->sr & CSR_MIF) || !(s->sr & CSR_MAL)) {
2797abb479cSAndrew Randrianasulu             mpc_i2c_irq(s);
2807abb479cSAndrew Randrianasulu         }
2817abb479cSAndrew Randrianasulu         break;
2827abb479cSAndrew Randrianasulu     case MPC_I2C_DR:
2837abb479cSAndrew Randrianasulu         /* if the device is not enabled, nothing to do */
2847abb479cSAndrew Randrianasulu         if (!mpc_i2c_is_enabled(s)) {
2857abb479cSAndrew Randrianasulu             break;
2867abb479cSAndrew Randrianasulu         }
2877abb479cSAndrew Randrianasulu         s->dr = value & CDR_MASK;
2887abb479cSAndrew Randrianasulu         if (mpc_i2c_is_master(s)) { /* master mode */
2897abb479cSAndrew Randrianasulu             if (s->address == CYCLE_RESET) {
2907abb479cSAndrew Randrianasulu                 mpc_i2c_address_send(s);
2917abb479cSAndrew Randrianasulu             } else {
2927abb479cSAndrew Randrianasulu                 mpc_i2c_data_send(s);
2937abb479cSAndrew Randrianasulu             }
2947abb479cSAndrew Randrianasulu         }
2957abb479cSAndrew Randrianasulu         break;
2967abb479cSAndrew Randrianasulu     case MPC_I2C_DFSRR:
2977abb479cSAndrew Randrianasulu         s->dfssr = value;
2987abb479cSAndrew Randrianasulu         break;
2997abb479cSAndrew Randrianasulu     default:
3007abb479cSAndrew Randrianasulu         DPRINTF("ERROR: Bad write addr 0x%x\n", (unsigned int)addr);
3017abb479cSAndrew Randrianasulu         break;
3027abb479cSAndrew Randrianasulu     }
3037abb479cSAndrew Randrianasulu }
3047abb479cSAndrew Randrianasulu 
3057abb479cSAndrew Randrianasulu static const MemoryRegionOps i2c_ops = {
3067abb479cSAndrew Randrianasulu     .read =  mpc_i2c_read,
3077abb479cSAndrew Randrianasulu     .write =  mpc_i2c_write,
3087abb479cSAndrew Randrianasulu     .valid.max_access_size = 1,
3097abb479cSAndrew Randrianasulu     .endianness = DEVICE_NATIVE_ENDIAN,
3107abb479cSAndrew Randrianasulu };
3117abb479cSAndrew Randrianasulu 
3127abb479cSAndrew Randrianasulu static const VMStateDescription mpc_i2c_vmstate = {
3137abb479cSAndrew Randrianasulu     .name = TYPE_MPC_I2C,
3147abb479cSAndrew Randrianasulu     .version_id = 1,
3157abb479cSAndrew Randrianasulu     .minimum_version_id = 1,
3167abb479cSAndrew Randrianasulu     .fields = (VMStateField[]) {
3177abb479cSAndrew Randrianasulu         VMSTATE_UINT8(address, MPCI2CState),
3187abb479cSAndrew Randrianasulu         VMSTATE_UINT8(adr, MPCI2CState),
3197abb479cSAndrew Randrianasulu         VMSTATE_UINT8(fdr, MPCI2CState),
3207abb479cSAndrew Randrianasulu         VMSTATE_UINT8(cr, MPCI2CState),
3217abb479cSAndrew Randrianasulu         VMSTATE_UINT8(sr, MPCI2CState),
3227abb479cSAndrew Randrianasulu         VMSTATE_UINT8(dr, MPCI2CState),
3237abb479cSAndrew Randrianasulu         VMSTATE_UINT8(dfssr, MPCI2CState),
3247abb479cSAndrew Randrianasulu         VMSTATE_END_OF_LIST()
3257abb479cSAndrew Randrianasulu     }
3267abb479cSAndrew Randrianasulu };
3277abb479cSAndrew Randrianasulu 
3287abb479cSAndrew Randrianasulu static void mpc_i2c_realize(DeviceState *dev, Error **errp)
3297abb479cSAndrew Randrianasulu {
3307abb479cSAndrew Randrianasulu     MPCI2CState  *i2c = MPC_I2C(dev);
3317abb479cSAndrew Randrianasulu     sysbus_init_irq(SYS_BUS_DEVICE(dev), &i2c->irq);
3327abb479cSAndrew Randrianasulu     memory_region_init_io(&i2c->iomem, OBJECT(i2c), &i2c_ops, i2c,
3337abb479cSAndrew Randrianasulu                           "mpc-i2c", 0x14);
3347abb479cSAndrew Randrianasulu     sysbus_init_mmio(SYS_BUS_DEVICE(dev), &i2c->iomem);
335*8e5c952bSPhilippe Mathieu-Daudé     i2c->bus = i2c_init_bus(dev, "i2c");
3367abb479cSAndrew Randrianasulu }
3377abb479cSAndrew Randrianasulu 
3387abb479cSAndrew Randrianasulu static void mpc_i2c_class_init(ObjectClass *klass, void *data)
3397abb479cSAndrew Randrianasulu {
3407abb479cSAndrew Randrianasulu     DeviceClass *dc = DEVICE_CLASS(klass);
3417abb479cSAndrew Randrianasulu 
3427abb479cSAndrew Randrianasulu     dc->vmsd  = &mpc_i2c_vmstate ;
3437abb479cSAndrew Randrianasulu     dc->reset = mpc_i2c_reset;
3447abb479cSAndrew Randrianasulu     dc->realize = mpc_i2c_realize;
3457abb479cSAndrew Randrianasulu     dc->desc = "MPC I2C Controller";
3467abb479cSAndrew Randrianasulu }
3477abb479cSAndrew Randrianasulu 
3487abb479cSAndrew Randrianasulu static const TypeInfo mpc_i2c_type_info = {
3497abb479cSAndrew Randrianasulu     .name          = TYPE_MPC_I2C,
3507abb479cSAndrew Randrianasulu     .parent        = TYPE_SYS_BUS_DEVICE,
3517abb479cSAndrew Randrianasulu     .instance_size = sizeof(MPCI2CState),
3527abb479cSAndrew Randrianasulu     .class_init    = mpc_i2c_class_init,
3537abb479cSAndrew Randrianasulu };
3547abb479cSAndrew Randrianasulu 
3557abb479cSAndrew Randrianasulu static void mpc_i2c_register_types(void)
3567abb479cSAndrew Randrianasulu {
3577abb479cSAndrew Randrianasulu     type_register_static(&mpc_i2c_type_info);
3587abb479cSAndrew Randrianasulu }
3597abb479cSAndrew Randrianasulu 
3607abb479cSAndrew Randrianasulu type_init(mpc_i2c_register_types)
361