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