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" 230b8fa32fSMarkus Armbruster #include "qemu/module.h" 247abb479cSAndrew Randrianasulu #include "hw/sysbus.h" 25d6454270SMarkus Armbruster #include "migration/vmstate.h" 26db1015e9SEduardo Habkost #include "qom/object.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; 85*53858a6aSBALATON Zoltan uint8_t dfsrr; 86db1015e9SEduardo Habkost }; 877abb479cSAndrew Randrianasulu 887abb479cSAndrew Randrianasulu static bool mpc_i2c_is_enabled(MPCI2CState *s) 897abb479cSAndrew Randrianasulu { 907abb479cSAndrew Randrianasulu return s->cr & CCR_MEN; 917abb479cSAndrew Randrianasulu } 927abb479cSAndrew Randrianasulu 937abb479cSAndrew Randrianasulu static bool mpc_i2c_is_master(MPCI2CState *s) 947abb479cSAndrew Randrianasulu { 957abb479cSAndrew Randrianasulu return s->cr & CCR_MSTA; 967abb479cSAndrew Randrianasulu } 977abb479cSAndrew Randrianasulu 987abb479cSAndrew Randrianasulu static bool mpc_i2c_direction_is_tx(MPCI2CState *s) 997abb479cSAndrew Randrianasulu { 1007abb479cSAndrew Randrianasulu return s->cr & CCR_MTX; 1017abb479cSAndrew Randrianasulu } 1027abb479cSAndrew Randrianasulu 1037abb479cSAndrew Randrianasulu static bool mpc_i2c_irq_pending(MPCI2CState *s) 1047abb479cSAndrew Randrianasulu { 1057abb479cSAndrew Randrianasulu return s->sr & CSR_MIF; 1067abb479cSAndrew Randrianasulu } 1077abb479cSAndrew Randrianasulu 1087abb479cSAndrew Randrianasulu static bool mpc_i2c_irq_is_enabled(MPCI2CState *s) 1097abb479cSAndrew Randrianasulu { 1107abb479cSAndrew Randrianasulu return s->cr & CCR_MIEN; 1117abb479cSAndrew Randrianasulu } 1127abb479cSAndrew Randrianasulu 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 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 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 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 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 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 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 227883f2c59SPhilippe Mathieu-Daudé DPRINTF("%s: addr " HWADDR_FMT_plx " %02" PRIx32 "\n", __func__, 2287abb479cSAndrew Randrianasulu addr, value); 2297abb479cSAndrew Randrianasulu return (uint64_t)value; 2307abb479cSAndrew Randrianasulu } 2317abb479cSAndrew Randrianasulu 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 237883f2c59SPhilippe Mathieu-Daudé DPRINTF("%s: addr " HWADDR_FMT_plx " val %08" PRIx64 "\n", __func__, 2387abb479cSAndrew Randrianasulu addr, value); 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: 296*53858a6aSBALATON 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), 322*53858a6aSBALATON Zoltan VMSTATE_UINT8(dfsrr, MPCI2CState), 3237abb479cSAndrew Randrianasulu VMSTATE_END_OF_LIST() 3247abb479cSAndrew Randrianasulu } 3257abb479cSAndrew Randrianasulu }; 3267abb479cSAndrew Randrianasulu 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, 332*53858a6aSBALATON 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 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 ; 3427abb479cSAndrew Randrianasulu dc->reset = mpc_i2c_reset; 3437abb479cSAndrew Randrianasulu dc->realize = mpc_i2c_realize; 3447abb479cSAndrew Randrianasulu dc->desc = "MPC I2C Controller"; 3457abb479cSAndrew Randrianasulu } 3467abb479cSAndrew Randrianasulu 3477abb479cSAndrew Randrianasulu static const TypeInfo mpc_i2c_type_info = { 3487abb479cSAndrew Randrianasulu .name = TYPE_MPC_I2C, 3497abb479cSAndrew Randrianasulu .parent = TYPE_SYS_BUS_DEVICE, 3507abb479cSAndrew Randrianasulu .instance_size = sizeof(MPCI2CState), 3517abb479cSAndrew Randrianasulu .class_init = mpc_i2c_class_init, 3527abb479cSAndrew Randrianasulu }; 3537abb479cSAndrew Randrianasulu 3547abb479cSAndrew Randrianasulu static void mpc_i2c_register_types(void) 3557abb479cSAndrew Randrianasulu { 3567abb479cSAndrew Randrianasulu type_register_static(&mpc_i2c_type_info); 3577abb479cSAndrew Randrianasulu } 3587abb479cSAndrew Randrianasulu 3597abb479cSAndrew Randrianasulu type_init(mpc_i2c_register_types) 360