xref: /openbmc/qemu/hw/i2c/mpc_i2c.c (revision 63dc36944383f70f1c7a20f6104966d8560300fa)
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 "hw/sysbus.h"
24d6454270SMarkus Armbruster #include "migration/vmstate.h"
25db1015e9SEduardo Habkost #include "qom/object.h"
261d97f16eSBernhard Beschow #include "trace.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"
398063396bSEduardo Habkost OBJECT_DECLARE_SIMPLE_TYPE(MPCI2CState, MPC_I2C)
407abb479cSAndrew Randrianasulu 
417abb479cSAndrew Randrianasulu #define MPC_I2C_ADR   0x00
427abb479cSAndrew Randrianasulu #define MPC_I2C_FDR   0x04
437abb479cSAndrew Randrianasulu #define MPC_I2C_CR    0x08
447abb479cSAndrew Randrianasulu #define MPC_I2C_SR    0x0c
457abb479cSAndrew Randrianasulu #define MPC_I2C_DR    0x10
467abb479cSAndrew Randrianasulu #define MPC_I2C_DFSRR 0x14
477abb479cSAndrew Randrianasulu 
487abb479cSAndrew Randrianasulu #define CCR_MEN  (1 << 7)
497abb479cSAndrew Randrianasulu #define CCR_MIEN (1 << 6)
507abb479cSAndrew Randrianasulu #define CCR_MSTA (1 << 5)
517abb479cSAndrew Randrianasulu #define CCR_MTX  (1 << 4)
527abb479cSAndrew Randrianasulu #define CCR_TXAK (1 << 3)
537abb479cSAndrew Randrianasulu #define CCR_RSTA (1 << 2)
547abb479cSAndrew Randrianasulu #define CCR_BCST (1 << 0)
557abb479cSAndrew Randrianasulu 
567abb479cSAndrew Randrianasulu #define CSR_MCF  (1 << 7)
577abb479cSAndrew Randrianasulu #define CSR_MAAS (1 << 6)
587abb479cSAndrew Randrianasulu #define CSR_MBB  (1 << 5)
597abb479cSAndrew Randrianasulu #define CSR_MAL  (1 << 4)
607abb479cSAndrew Randrianasulu #define CSR_SRW  (1 << 2)
617abb479cSAndrew Randrianasulu #define CSR_MIF  (1 << 1)
627abb479cSAndrew Randrianasulu #define CSR_RXAK (1 << 0)
637abb479cSAndrew Randrianasulu 
647abb479cSAndrew Randrianasulu #define CADR_MASK 0xFE
657abb479cSAndrew Randrianasulu #define CFDR_MASK 0x3F
667abb479cSAndrew Randrianasulu #define CCR_MASK  0xFC
677abb479cSAndrew Randrianasulu #define CSR_MASK  0xED
687abb479cSAndrew Randrianasulu #define CDR_MASK  0xFF
697abb479cSAndrew Randrianasulu 
707abb479cSAndrew Randrianasulu #define CYCLE_RESET 0xFF
717abb479cSAndrew Randrianasulu 
72db1015e9SEduardo Habkost struct MPCI2CState {
737abb479cSAndrew Randrianasulu     SysBusDevice parent_obj;
747abb479cSAndrew Randrianasulu 
757abb479cSAndrew Randrianasulu     I2CBus *bus;
767abb479cSAndrew Randrianasulu     qemu_irq irq;
777abb479cSAndrew Randrianasulu     MemoryRegion iomem;
787abb479cSAndrew Randrianasulu 
797abb479cSAndrew Randrianasulu     uint8_t address;
807abb479cSAndrew Randrianasulu     uint8_t adr;
817abb479cSAndrew Randrianasulu     uint8_t fdr;
827abb479cSAndrew Randrianasulu     uint8_t cr;
837abb479cSAndrew Randrianasulu     uint8_t sr;
847abb479cSAndrew Randrianasulu     uint8_t dr;
8553858a6aSBALATON Zoltan     uint8_t dfsrr;
86db1015e9SEduardo Habkost };
877abb479cSAndrew Randrianasulu 
mpc_i2c_is_enabled(MPCI2CState * s)887abb479cSAndrew Randrianasulu static bool mpc_i2c_is_enabled(MPCI2CState *s)
897abb479cSAndrew Randrianasulu {
907abb479cSAndrew Randrianasulu     return s->cr & CCR_MEN;
917abb479cSAndrew Randrianasulu }
927abb479cSAndrew Randrianasulu 
mpc_i2c_is_master(MPCI2CState * s)937abb479cSAndrew Randrianasulu static bool mpc_i2c_is_master(MPCI2CState *s)
947abb479cSAndrew Randrianasulu {
957abb479cSAndrew Randrianasulu     return s->cr & CCR_MSTA;
967abb479cSAndrew Randrianasulu }
977abb479cSAndrew Randrianasulu 
mpc_i2c_direction_is_tx(MPCI2CState * s)987abb479cSAndrew Randrianasulu static bool mpc_i2c_direction_is_tx(MPCI2CState *s)
997abb479cSAndrew Randrianasulu {
1007abb479cSAndrew Randrianasulu     return s->cr & CCR_MTX;
1017abb479cSAndrew Randrianasulu }
1027abb479cSAndrew Randrianasulu 
mpc_i2c_irq_pending(MPCI2CState * s)1037abb479cSAndrew Randrianasulu static bool mpc_i2c_irq_pending(MPCI2CState *s)
1047abb479cSAndrew Randrianasulu {
1057abb479cSAndrew Randrianasulu     return s->sr & CSR_MIF;
1067abb479cSAndrew Randrianasulu }
1077abb479cSAndrew Randrianasulu 
mpc_i2c_irq_is_enabled(MPCI2CState * s)1087abb479cSAndrew Randrianasulu static bool mpc_i2c_irq_is_enabled(MPCI2CState *s)
1097abb479cSAndrew Randrianasulu {
1107abb479cSAndrew Randrianasulu     return s->cr & CCR_MIEN;
1117abb479cSAndrew Randrianasulu }
1127abb479cSAndrew Randrianasulu 
mpc_i2c_reset(DeviceState * dev)1137abb479cSAndrew Randrianasulu static void mpc_i2c_reset(DeviceState *dev)
1147abb479cSAndrew Randrianasulu {
1157abb479cSAndrew Randrianasulu     MPCI2CState *i2c = MPC_I2C(dev);
1167abb479cSAndrew Randrianasulu 
1177abb479cSAndrew Randrianasulu     i2c->address = 0xFF;
1187abb479cSAndrew Randrianasulu     i2c->adr = 0x00;
1197abb479cSAndrew Randrianasulu     i2c->fdr = 0x00;
1207abb479cSAndrew Randrianasulu     i2c->cr =  0x00;
1217abb479cSAndrew Randrianasulu     i2c->sr =  0x81;
1227abb479cSAndrew Randrianasulu     i2c->dr =  0x00;
1237abb479cSAndrew Randrianasulu }
1247abb479cSAndrew Randrianasulu 
mpc_i2c_irq(MPCI2CState * s)1257abb479cSAndrew Randrianasulu static void mpc_i2c_irq(MPCI2CState *s)
1267abb479cSAndrew Randrianasulu {
1277abb479cSAndrew Randrianasulu     bool irq_active = false;
1287abb479cSAndrew Randrianasulu 
1297abb479cSAndrew Randrianasulu     if (mpc_i2c_is_enabled(s) && mpc_i2c_irq_is_enabled(s)
1307abb479cSAndrew Randrianasulu                               && mpc_i2c_irq_pending(s)) {
1317abb479cSAndrew Randrianasulu         irq_active = true;
1327abb479cSAndrew Randrianasulu     }
1337abb479cSAndrew Randrianasulu 
1347abb479cSAndrew Randrianasulu     if (irq_active) {
1357abb479cSAndrew Randrianasulu         qemu_irq_raise(s->irq);
1367abb479cSAndrew Randrianasulu     } else {
1377abb479cSAndrew Randrianasulu         qemu_irq_lower(s->irq);
1387abb479cSAndrew Randrianasulu     }
1397abb479cSAndrew Randrianasulu }
1407abb479cSAndrew Randrianasulu 
mpc_i2c_soft_reset(MPCI2CState * s)1417abb479cSAndrew Randrianasulu static void mpc_i2c_soft_reset(MPCI2CState *s)
1427abb479cSAndrew Randrianasulu {
1437abb479cSAndrew Randrianasulu     /* This is a soft reset. ADR is preserved during soft resets */
1447abb479cSAndrew Randrianasulu     uint8_t adr = s->adr;
1457abb479cSAndrew Randrianasulu     mpc_i2c_reset(DEVICE(s));
1467abb479cSAndrew Randrianasulu     s->adr = adr;
1477abb479cSAndrew Randrianasulu }
1487abb479cSAndrew Randrianasulu 
mpc_i2c_address_send(MPCI2CState * s)1497abb479cSAndrew Randrianasulu static void  mpc_i2c_address_send(MPCI2CState *s)
1507abb479cSAndrew Randrianasulu {
1517abb479cSAndrew Randrianasulu     /* if returns non zero slave address is not right */
1527abb479cSAndrew Randrianasulu     if (i2c_start_transfer(s->bus, s->dr >> 1, s->dr & (0x01))) {
1537abb479cSAndrew Randrianasulu         s->sr |= CSR_RXAK;
1547abb479cSAndrew Randrianasulu     } else {
1557abb479cSAndrew Randrianasulu         s->address = s->dr;
1567abb479cSAndrew Randrianasulu         s->sr &= ~CSR_RXAK;
1577abb479cSAndrew Randrianasulu         s->sr |=  CSR_MCF; /* Set after Byte Transfer is completed */
1587abb479cSAndrew Randrianasulu         s->sr |=  CSR_MIF; /* Set after Byte Transfer is completed */
1597abb479cSAndrew Randrianasulu         mpc_i2c_irq(s);
1607abb479cSAndrew Randrianasulu     }
1617abb479cSAndrew Randrianasulu }
1627abb479cSAndrew Randrianasulu 
mpc_i2c_data_send(MPCI2CState * s)1637abb479cSAndrew Randrianasulu static void  mpc_i2c_data_send(MPCI2CState *s)
1647abb479cSAndrew Randrianasulu {
1657abb479cSAndrew Randrianasulu     if (i2c_send(s->bus, s->dr)) {
1667abb479cSAndrew Randrianasulu         /* End of transfer */
1677abb479cSAndrew Randrianasulu         s->sr |= CSR_RXAK;
1687abb479cSAndrew Randrianasulu         i2c_end_transfer(s->bus);
1697abb479cSAndrew Randrianasulu     } else {
1707abb479cSAndrew Randrianasulu         s->sr &= ~CSR_RXAK;
1717abb479cSAndrew Randrianasulu         s->sr |=  CSR_MCF; /* Set after Byte Transfer is completed */
1727abb479cSAndrew Randrianasulu         s->sr |=  CSR_MIF; /* Set after Byte Transfer is completed */
1737abb479cSAndrew Randrianasulu         mpc_i2c_irq(s);
1747abb479cSAndrew Randrianasulu     }
1757abb479cSAndrew Randrianasulu }
1767abb479cSAndrew Randrianasulu 
mpc_i2c_data_recive(MPCI2CState * s)1777abb479cSAndrew Randrianasulu static void  mpc_i2c_data_recive(MPCI2CState *s)
1787abb479cSAndrew Randrianasulu {
1797abb479cSAndrew Randrianasulu     int ret;
1807abb479cSAndrew Randrianasulu     /* get the next byte */
1817abb479cSAndrew Randrianasulu     ret = i2c_recv(s->bus);
1827abb479cSAndrew Randrianasulu     if (ret >= 0) {
1837abb479cSAndrew Randrianasulu         s->sr |= CSR_MCF; /* Set after Byte Transfer is completed */
1847abb479cSAndrew Randrianasulu         s->sr |= CSR_MIF; /* Set after Byte Transfer is completed */
1857abb479cSAndrew Randrianasulu         mpc_i2c_irq(s);
1867abb479cSAndrew Randrianasulu     } else {
1877abb479cSAndrew Randrianasulu         DPRINTF("read failed for device");
1887abb479cSAndrew Randrianasulu         ret = 0xff;
1897abb479cSAndrew Randrianasulu     }
1907abb479cSAndrew Randrianasulu     s->dr = ret;
1917abb479cSAndrew Randrianasulu }
1927abb479cSAndrew Randrianasulu 
mpc_i2c_read(void * opaque,hwaddr addr,unsigned size)1937abb479cSAndrew Randrianasulu static uint64_t mpc_i2c_read(void *opaque, hwaddr addr, unsigned size)
1947abb479cSAndrew Randrianasulu {
1957abb479cSAndrew Randrianasulu     MPCI2CState *s = opaque;
1967abb479cSAndrew Randrianasulu     uint8_t value;
1977abb479cSAndrew Randrianasulu 
1987abb479cSAndrew Randrianasulu     switch (addr) {
1997abb479cSAndrew Randrianasulu     case MPC_I2C_ADR:
2007abb479cSAndrew Randrianasulu         value = s->adr;
2017abb479cSAndrew Randrianasulu         break;
2027abb479cSAndrew Randrianasulu     case MPC_I2C_FDR:
2037abb479cSAndrew Randrianasulu         value = s->fdr;
2047abb479cSAndrew Randrianasulu         break;
2057abb479cSAndrew Randrianasulu     case MPC_I2C_CR:
2067abb479cSAndrew Randrianasulu         value = s->cr;
2077abb479cSAndrew Randrianasulu         break;
2087abb479cSAndrew Randrianasulu     case MPC_I2C_SR:
2097abb479cSAndrew Randrianasulu         value = s->sr;
2107abb479cSAndrew Randrianasulu         break;
2117abb479cSAndrew Randrianasulu     case MPC_I2C_DR:
2127abb479cSAndrew Randrianasulu         value = s->dr;
2137abb479cSAndrew Randrianasulu         if (mpc_i2c_is_master(s)) { /* master mode */
2147abb479cSAndrew Randrianasulu             if (mpc_i2c_direction_is_tx(s)) {
2157abb479cSAndrew Randrianasulu                 DPRINTF("MTX is set not in recv mode\n");
2167abb479cSAndrew Randrianasulu             } else {
2177abb479cSAndrew Randrianasulu                 mpc_i2c_data_recive(s);
2187abb479cSAndrew Randrianasulu             }
2197abb479cSAndrew Randrianasulu         }
2207abb479cSAndrew Randrianasulu         break;
2217abb479cSAndrew Randrianasulu     default:
2227abb479cSAndrew Randrianasulu         value = 0;
2237abb479cSAndrew Randrianasulu         DPRINTF("ERROR: Bad read addr 0x%x\n", (unsigned int)addr);
2247abb479cSAndrew Randrianasulu         break;
2257abb479cSAndrew Randrianasulu     }
2267abb479cSAndrew Randrianasulu 
2271d97f16eSBernhard Beschow     trace_mpc_i2c_read(addr, value);
2281d97f16eSBernhard Beschow 
2297abb479cSAndrew Randrianasulu     return (uint64_t)value;
2307abb479cSAndrew Randrianasulu }
2317abb479cSAndrew Randrianasulu 
mpc_i2c_write(void * opaque,hwaddr addr,uint64_t value,unsigned size)2327abb479cSAndrew Randrianasulu static void mpc_i2c_write(void *opaque, hwaddr addr,
2337abb479cSAndrew Randrianasulu                             uint64_t value, unsigned size)
2347abb479cSAndrew Randrianasulu {
2357abb479cSAndrew Randrianasulu     MPCI2CState *s = opaque;
2367abb479cSAndrew Randrianasulu 
2371d97f16eSBernhard Beschow     trace_mpc_i2c_write(addr, value);
2381d97f16eSBernhard Beschow 
2397abb479cSAndrew Randrianasulu     switch (addr) {
2407abb479cSAndrew Randrianasulu     case MPC_I2C_ADR:
2417abb479cSAndrew Randrianasulu         s->adr = value & CADR_MASK;
2427abb479cSAndrew Randrianasulu         break;
2437abb479cSAndrew Randrianasulu     case MPC_I2C_FDR:
2447abb479cSAndrew Randrianasulu         s->fdr = value & CFDR_MASK;
2457abb479cSAndrew Randrianasulu         break;
2467abb479cSAndrew Randrianasulu     case MPC_I2C_CR:
2477abb479cSAndrew Randrianasulu         if (mpc_i2c_is_enabled(s) && ((value & CCR_MEN) == 0)) {
2487abb479cSAndrew Randrianasulu             mpc_i2c_soft_reset(s);
2497abb479cSAndrew Randrianasulu             break;
2507abb479cSAndrew Randrianasulu         }
2517abb479cSAndrew Randrianasulu         /* normal write */
2527abb479cSAndrew Randrianasulu         s->cr = value & CCR_MASK;
2537abb479cSAndrew Randrianasulu         if (mpc_i2c_is_master(s)) { /* master mode */
2547abb479cSAndrew Randrianasulu             /* set the bus to busy after master is set as per RM */
2557abb479cSAndrew Randrianasulu             s->sr |= CSR_MBB;
2567abb479cSAndrew Randrianasulu         } else {
2577abb479cSAndrew Randrianasulu             /* bus is not busy anymore */
2587abb479cSAndrew Randrianasulu             s->sr &= ~CSR_MBB;
2597abb479cSAndrew Randrianasulu             /* Reset the address for fresh write/read cycle */
2607abb479cSAndrew Randrianasulu         if (s->address != CYCLE_RESET) {
2617abb479cSAndrew Randrianasulu             i2c_end_transfer(s->bus);
2627abb479cSAndrew Randrianasulu             s->address = CYCLE_RESET;
2637abb479cSAndrew Randrianasulu             }
2647abb479cSAndrew Randrianasulu         }
2657abb479cSAndrew Randrianasulu         /* For restart end the onging transfer */
2667abb479cSAndrew Randrianasulu         if (s->cr & CCR_RSTA) {
2677abb479cSAndrew Randrianasulu             if (s->address != CYCLE_RESET) {
2687abb479cSAndrew Randrianasulu                 s->address = CYCLE_RESET;
2697abb479cSAndrew Randrianasulu                 i2c_end_transfer(s->bus);
2707abb479cSAndrew Randrianasulu                 s->cr &= ~CCR_RSTA;
2717abb479cSAndrew Randrianasulu             }
2727abb479cSAndrew Randrianasulu         }
2737abb479cSAndrew Randrianasulu         break;
2747abb479cSAndrew Randrianasulu     case MPC_I2C_SR:
2757abb479cSAndrew Randrianasulu         s->sr = value & CSR_MASK;
2767abb479cSAndrew Randrianasulu         /* Lower the interrupt */
2777abb479cSAndrew Randrianasulu         if (!(s->sr & CSR_MIF) || !(s->sr & CSR_MAL)) {
2787abb479cSAndrew Randrianasulu             mpc_i2c_irq(s);
2797abb479cSAndrew Randrianasulu         }
2807abb479cSAndrew Randrianasulu         break;
2817abb479cSAndrew Randrianasulu     case MPC_I2C_DR:
2827abb479cSAndrew Randrianasulu         /* if the device is not enabled, nothing to do */
2837abb479cSAndrew Randrianasulu         if (!mpc_i2c_is_enabled(s)) {
2847abb479cSAndrew Randrianasulu             break;
2857abb479cSAndrew Randrianasulu         }
2867abb479cSAndrew Randrianasulu         s->dr = value & CDR_MASK;
2877abb479cSAndrew Randrianasulu         if (mpc_i2c_is_master(s)) { /* master mode */
2887abb479cSAndrew Randrianasulu             if (s->address == CYCLE_RESET) {
2897abb479cSAndrew Randrianasulu                 mpc_i2c_address_send(s);
2907abb479cSAndrew Randrianasulu             } else {
2917abb479cSAndrew Randrianasulu                 mpc_i2c_data_send(s);
2927abb479cSAndrew Randrianasulu             }
2937abb479cSAndrew Randrianasulu         }
2947abb479cSAndrew Randrianasulu         break;
2957abb479cSAndrew Randrianasulu     case MPC_I2C_DFSRR:
29653858a6aSBALATON Zoltan         s->dfsrr = value;
2977abb479cSAndrew Randrianasulu         break;
2987abb479cSAndrew Randrianasulu     default:
2997abb479cSAndrew Randrianasulu         DPRINTF("ERROR: Bad write addr 0x%x\n", (unsigned int)addr);
3007abb479cSAndrew Randrianasulu         break;
3017abb479cSAndrew Randrianasulu     }
3027abb479cSAndrew Randrianasulu }
3037abb479cSAndrew Randrianasulu 
3047abb479cSAndrew Randrianasulu static const MemoryRegionOps i2c_ops = {
3057abb479cSAndrew Randrianasulu     .read =  mpc_i2c_read,
3067abb479cSAndrew Randrianasulu     .write =  mpc_i2c_write,
3077abb479cSAndrew Randrianasulu     .valid.max_access_size = 1,
3087abb479cSAndrew Randrianasulu     .endianness = DEVICE_NATIVE_ENDIAN,
3097abb479cSAndrew Randrianasulu };
3107abb479cSAndrew Randrianasulu 
3117abb479cSAndrew Randrianasulu static const VMStateDescription mpc_i2c_vmstate = {
3127abb479cSAndrew Randrianasulu     .name = TYPE_MPC_I2C,
3137abb479cSAndrew Randrianasulu     .version_id = 1,
3147abb479cSAndrew Randrianasulu     .minimum_version_id = 1,
31501d9442aSRichard Henderson     .fields = (const VMStateField[]) {
3167abb479cSAndrew Randrianasulu         VMSTATE_UINT8(address, MPCI2CState),
3177abb479cSAndrew Randrianasulu         VMSTATE_UINT8(adr, MPCI2CState),
3187abb479cSAndrew Randrianasulu         VMSTATE_UINT8(fdr, MPCI2CState),
3197abb479cSAndrew Randrianasulu         VMSTATE_UINT8(cr, MPCI2CState),
3207abb479cSAndrew Randrianasulu         VMSTATE_UINT8(sr, MPCI2CState),
3217abb479cSAndrew Randrianasulu         VMSTATE_UINT8(dr, MPCI2CState),
32253858a6aSBALATON Zoltan         VMSTATE_UINT8(dfsrr, MPCI2CState),
3237abb479cSAndrew Randrianasulu         VMSTATE_END_OF_LIST()
3247abb479cSAndrew Randrianasulu     }
3257abb479cSAndrew Randrianasulu };
3267abb479cSAndrew Randrianasulu 
mpc_i2c_realize(DeviceState * dev,Error ** errp)3277abb479cSAndrew Randrianasulu static void mpc_i2c_realize(DeviceState *dev, Error **errp)
3287abb479cSAndrew Randrianasulu {
3297abb479cSAndrew Randrianasulu     MPCI2CState  *i2c = MPC_I2C(dev);
3307abb479cSAndrew Randrianasulu     sysbus_init_irq(SYS_BUS_DEVICE(dev), &i2c->irq);
3317abb479cSAndrew Randrianasulu     memory_region_init_io(&i2c->iomem, OBJECT(i2c), &i2c_ops, i2c,
33253858a6aSBALATON Zoltan                           "mpc-i2c", 0x15);
3337abb479cSAndrew Randrianasulu     sysbus_init_mmio(SYS_BUS_DEVICE(dev), &i2c->iomem);
3348e5c952bSPhilippe Mathieu-Daudé     i2c->bus = i2c_init_bus(dev, "i2c");
3357abb479cSAndrew Randrianasulu }
3367abb479cSAndrew Randrianasulu 
mpc_i2c_class_init(ObjectClass * klass,void * data)3377abb479cSAndrew Randrianasulu static void mpc_i2c_class_init(ObjectClass *klass, void *data)
3387abb479cSAndrew Randrianasulu {
3397abb479cSAndrew Randrianasulu     DeviceClass *dc = DEVICE_CLASS(klass);
3407abb479cSAndrew Randrianasulu 
3417abb479cSAndrew Randrianasulu     dc->vmsd  = &mpc_i2c_vmstate ;
342e3d08143SPeter Maydell     device_class_set_legacy_reset(dc, mpc_i2c_reset);
3437abb479cSAndrew Randrianasulu     dc->realize = mpc_i2c_realize;
3447abb479cSAndrew Randrianasulu     dc->desc = "MPC I2C Controller";
3457abb479cSAndrew Randrianasulu }
3467abb479cSAndrew Randrianasulu 
347*21b1ee76SBernhard Beschow static const TypeInfo mpc_i2c_types[] = {
348*21b1ee76SBernhard Beschow     {
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,
353*21b1ee76SBernhard Beschow     },
3547abb479cSAndrew Randrianasulu };
3557abb479cSAndrew Randrianasulu 
356*21b1ee76SBernhard Beschow DEFINE_TYPES(mpc_i2c_types)
357