xref: /openbmc/qemu/hw/i2c/exynos4210_i2c.c (revision 28ae3179fc52d2e4d870b635c4a412aab99759e7)
153ed424eSPaolo Bonzini /*
253ed424eSPaolo Bonzini  *  Exynos4210 I2C Bus Serial Interface Emulation
353ed424eSPaolo Bonzini  *
453ed424eSPaolo Bonzini  *  Copyright (C) 2012 Samsung Electronics Co Ltd.
553ed424eSPaolo Bonzini  *    Maksim Kozlov, <m.kozlov@samsung.com>
653ed424eSPaolo Bonzini  *    Igor Mitsyanko, <i.mitsyanko@samsung.com>
753ed424eSPaolo Bonzini  *
853ed424eSPaolo Bonzini  *  This program is free software; you can redistribute it and/or modify it
953ed424eSPaolo Bonzini  *  under the terms of the GNU General Public License as published by the
1053ed424eSPaolo Bonzini  *  Free Software Foundation; either version 2 of the License, or
1153ed424eSPaolo Bonzini  *  (at your option) any later version.
1253ed424eSPaolo Bonzini  *
1353ed424eSPaolo Bonzini  *  This program is distributed in the hope that it will be useful, but WITHOUT
1453ed424eSPaolo Bonzini  *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1553ed424eSPaolo Bonzini  *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1653ed424eSPaolo Bonzini  *  for more details.
1753ed424eSPaolo Bonzini  *
1853ed424eSPaolo Bonzini  *  You should have received a copy of the GNU General Public License along
1953ed424eSPaolo Bonzini  *  with this program; if not, see <http://www.gnu.org/licenses/>.
2053ed424eSPaolo Bonzini  *
2153ed424eSPaolo Bonzini  */
2253ed424eSPaolo Bonzini 
238ef94f0bSPeter Maydell #include "qemu/osdep.h"
240b8fa32fSMarkus Armbruster #include "qemu/module.h"
2553ed424eSPaolo Bonzini #include "qemu/timer.h"
2653ed424eSPaolo Bonzini #include "hw/sysbus.h"
27d6454270SMarkus Armbruster #include "migration/vmstate.h"
2853ed424eSPaolo Bonzini #include "hw/i2c/i2c.h"
2964552b6bSMarkus Armbruster #include "hw/irq.h"
30db1015e9SEduardo Habkost #include "qom/object.h"
3153ed424eSPaolo Bonzini 
3253ed424eSPaolo Bonzini #ifndef EXYNOS4_I2C_DEBUG
3353ed424eSPaolo Bonzini #define EXYNOS4_I2C_DEBUG                 0
3453ed424eSPaolo Bonzini #endif
3553ed424eSPaolo Bonzini 
3653ed424eSPaolo Bonzini #define TYPE_EXYNOS4_I2C                  "exynos4210.i2c"
OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210I2CState,EXYNOS4_I2C)378063396bSEduardo Habkost OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210I2CState, EXYNOS4_I2C)
3853ed424eSPaolo Bonzini 
3953ed424eSPaolo Bonzini /* Exynos4210 I2C memory map */
4053ed424eSPaolo Bonzini #define EXYNOS4_I2C_MEM_SIZE              0x14
4153ed424eSPaolo Bonzini #define I2CCON_ADDR                       0x00  /* control register */
4253ed424eSPaolo Bonzini #define I2CSTAT_ADDR                      0x04  /* control/status register */
4353ed424eSPaolo Bonzini #define I2CADD_ADDR                       0x08  /* address register */
4453ed424eSPaolo Bonzini #define I2CDS_ADDR                        0x0c  /* data shift register */
4553ed424eSPaolo Bonzini #define I2CLC_ADDR                        0x10  /* line control register */
4653ed424eSPaolo Bonzini 
4753ed424eSPaolo Bonzini #define I2CCON_ACK_GEN                    (1 << 7)
4853ed424eSPaolo Bonzini #define I2CCON_INTRS_EN                   (1 << 5)
4953ed424eSPaolo Bonzini #define I2CCON_INT_PEND                   (1 << 4)
5053ed424eSPaolo Bonzini 
5153ed424eSPaolo Bonzini #define EXYNOS4_I2C_MODE(reg)             (((reg) >> 6) & 3)
5253ed424eSPaolo Bonzini #define I2C_IN_MASTER_MODE(reg)           (((reg) >> 6) & 2)
5353ed424eSPaolo Bonzini #define I2CMODE_MASTER_Rx                 0x2
5453ed424eSPaolo Bonzini #define I2CMODE_MASTER_Tx                 0x3
5553ed424eSPaolo Bonzini #define I2CSTAT_LAST_BIT                  (1 << 0)
5653ed424eSPaolo Bonzini #define I2CSTAT_OUTPUT_EN                 (1 << 4)
5753ed424eSPaolo Bonzini #define I2CSTAT_START_BUSY                (1 << 5)
5853ed424eSPaolo Bonzini 
5953ed424eSPaolo Bonzini 
6053ed424eSPaolo Bonzini #if EXYNOS4_I2C_DEBUG
6153ed424eSPaolo Bonzini #define DPRINT(fmt, args...)              \
6253ed424eSPaolo Bonzini     do { fprintf(stderr, "QEMU I2C: "fmt, ## args); } while (0)
6353ed424eSPaolo Bonzini 
6453ed424eSPaolo Bonzini static const char *exynos4_i2c_get_regname(unsigned offset)
6553ed424eSPaolo Bonzini {
6653ed424eSPaolo Bonzini     switch (offset) {
6753ed424eSPaolo Bonzini     case I2CCON_ADDR:
6853ed424eSPaolo Bonzini         return "I2CCON";
6953ed424eSPaolo Bonzini     case I2CSTAT_ADDR:
7053ed424eSPaolo Bonzini         return "I2CSTAT";
7153ed424eSPaolo Bonzini     case I2CADD_ADDR:
7253ed424eSPaolo Bonzini         return "I2CADD";
7353ed424eSPaolo Bonzini     case I2CDS_ADDR:
7453ed424eSPaolo Bonzini         return "I2CDS";
7553ed424eSPaolo Bonzini     case I2CLC_ADDR:
7653ed424eSPaolo Bonzini         return "I2CLC";
7753ed424eSPaolo Bonzini     default:
7853ed424eSPaolo Bonzini         return "[?]";
7953ed424eSPaolo Bonzini     }
8053ed424eSPaolo Bonzini }
8153ed424eSPaolo Bonzini 
8253ed424eSPaolo Bonzini #else
8353ed424eSPaolo Bonzini #define DPRINT(fmt, args...)              do { } while (0)
8453ed424eSPaolo Bonzini #endif
8553ed424eSPaolo Bonzini 
86db1015e9SEduardo Habkost struct Exynos4210I2CState {
8743603329SAndreas Färber     SysBusDevice parent_obj;
8843603329SAndreas Färber 
8953ed424eSPaolo Bonzini     MemoryRegion iomem;
90a5c82852SAndreas Färber     I2CBus *bus;
9153ed424eSPaolo Bonzini     qemu_irq irq;
9253ed424eSPaolo Bonzini 
9353ed424eSPaolo Bonzini     uint8_t i2ccon;
9453ed424eSPaolo Bonzini     uint8_t i2cstat;
9553ed424eSPaolo Bonzini     uint8_t i2cadd;
9653ed424eSPaolo Bonzini     uint8_t i2cds;
9753ed424eSPaolo Bonzini     uint8_t i2clc;
9853ed424eSPaolo Bonzini     bool scl_free;
99db1015e9SEduardo Habkost };
10053ed424eSPaolo Bonzini 
exynos4210_i2c_raise_interrupt(Exynos4210I2CState * s)10153ed424eSPaolo Bonzini static inline void exynos4210_i2c_raise_interrupt(Exynos4210I2CState *s)
10253ed424eSPaolo Bonzini {
10353ed424eSPaolo Bonzini     if (s->i2ccon & I2CCON_INTRS_EN) {
10453ed424eSPaolo Bonzini         s->i2ccon |= I2CCON_INT_PEND;
10553ed424eSPaolo Bonzini         qemu_irq_raise(s->irq);
10653ed424eSPaolo Bonzini     }
10753ed424eSPaolo Bonzini }
10853ed424eSPaolo Bonzini 
exynos4210_i2c_data_receive(void * opaque)10953ed424eSPaolo Bonzini static void exynos4210_i2c_data_receive(void *opaque)
11053ed424eSPaolo Bonzini {
11153ed424eSPaolo Bonzini     Exynos4210I2CState *s = (Exynos4210I2CState *)opaque;
11253ed424eSPaolo Bonzini 
11353ed424eSPaolo Bonzini     s->i2cstat &= ~I2CSTAT_LAST_BIT;
11453ed424eSPaolo Bonzini     s->scl_free = false;
115bc15cde0SCorey Minyard     s->i2cds = i2c_recv(s->bus);
11653ed424eSPaolo Bonzini     exynos4210_i2c_raise_interrupt(s);
11753ed424eSPaolo Bonzini }
11853ed424eSPaolo Bonzini 
exynos4210_i2c_data_send(void * opaque)11953ed424eSPaolo Bonzini static void exynos4210_i2c_data_send(void *opaque)
12053ed424eSPaolo Bonzini {
12153ed424eSPaolo Bonzini     Exynos4210I2CState *s = (Exynos4210I2CState *)opaque;
12253ed424eSPaolo Bonzini 
12353ed424eSPaolo Bonzini     s->i2cstat &= ~I2CSTAT_LAST_BIT;
12453ed424eSPaolo Bonzini     s->scl_free = false;
12553ed424eSPaolo Bonzini     if (i2c_send(s->bus, s->i2cds) < 0 && (s->i2ccon & I2CCON_ACK_GEN)) {
12653ed424eSPaolo Bonzini         s->i2cstat |= I2CSTAT_LAST_BIT;
12753ed424eSPaolo Bonzini     }
12853ed424eSPaolo Bonzini     exynos4210_i2c_raise_interrupt(s);
12953ed424eSPaolo Bonzini }
13053ed424eSPaolo Bonzini 
exynos4210_i2c_read(void * opaque,hwaddr offset,unsigned size)13153ed424eSPaolo Bonzini static uint64_t exynos4210_i2c_read(void *opaque, hwaddr offset,
13253ed424eSPaolo Bonzini                                  unsigned size)
13353ed424eSPaolo Bonzini {
13453ed424eSPaolo Bonzini     Exynos4210I2CState *s = (Exynos4210I2CState *)opaque;
13553ed424eSPaolo Bonzini     uint8_t value;
13653ed424eSPaolo Bonzini 
13753ed424eSPaolo Bonzini     switch (offset) {
13853ed424eSPaolo Bonzini     case I2CCON_ADDR:
13953ed424eSPaolo Bonzini         value = s->i2ccon;
14053ed424eSPaolo Bonzini         break;
14153ed424eSPaolo Bonzini     case I2CSTAT_ADDR:
14253ed424eSPaolo Bonzini         value = s->i2cstat;
14353ed424eSPaolo Bonzini         break;
14453ed424eSPaolo Bonzini     case I2CADD_ADDR:
14553ed424eSPaolo Bonzini         value = s->i2cadd;
14653ed424eSPaolo Bonzini         break;
14753ed424eSPaolo Bonzini     case I2CDS_ADDR:
14853ed424eSPaolo Bonzini         value = s->i2cds;
14953ed424eSPaolo Bonzini         s->scl_free = true;
15053ed424eSPaolo Bonzini         if (EXYNOS4_I2C_MODE(s->i2cstat) == I2CMODE_MASTER_Rx &&
15153ed424eSPaolo Bonzini                (s->i2cstat & I2CSTAT_START_BUSY) &&
15253ed424eSPaolo Bonzini                !(s->i2ccon & I2CCON_INT_PEND)) {
15353ed424eSPaolo Bonzini             exynos4210_i2c_data_receive(s);
15453ed424eSPaolo Bonzini         }
15553ed424eSPaolo Bonzini         break;
15653ed424eSPaolo Bonzini     case I2CLC_ADDR:
15753ed424eSPaolo Bonzini         value = s->i2clc;
15853ed424eSPaolo Bonzini         break;
15953ed424eSPaolo Bonzini     default:
16053ed424eSPaolo Bonzini         value = 0;
16153ed424eSPaolo Bonzini         DPRINT("ERROR: Bad read offset 0x%x\n", (unsigned int)offset);
16253ed424eSPaolo Bonzini         break;
16353ed424eSPaolo Bonzini     }
16453ed424eSPaolo Bonzini 
16553ed424eSPaolo Bonzini     DPRINT("read %s [0x%02x] -> 0x%02x\n", exynos4_i2c_get_regname(offset),
16653ed424eSPaolo Bonzini             (unsigned int)offset, value);
16753ed424eSPaolo Bonzini     return value;
16853ed424eSPaolo Bonzini }
16953ed424eSPaolo Bonzini 
exynos4210_i2c_write(void * opaque,hwaddr offset,uint64_t value,unsigned size)17053ed424eSPaolo Bonzini static void exynos4210_i2c_write(void *opaque, hwaddr offset,
17153ed424eSPaolo Bonzini                               uint64_t value, unsigned size)
17253ed424eSPaolo Bonzini {
17353ed424eSPaolo Bonzini     Exynos4210I2CState *s = (Exynos4210I2CState *)opaque;
17453ed424eSPaolo Bonzini     uint8_t v = value & 0xff;
17553ed424eSPaolo Bonzini 
17653ed424eSPaolo Bonzini     DPRINT("write %s [0x%02x] <- 0x%02x\n", exynos4_i2c_get_regname(offset),
17753ed424eSPaolo Bonzini             (unsigned int)offset, v);
17853ed424eSPaolo Bonzini 
17953ed424eSPaolo Bonzini     switch (offset) {
18053ed424eSPaolo Bonzini     case I2CCON_ADDR:
18153ed424eSPaolo Bonzini         s->i2ccon = (v & ~I2CCON_INT_PEND) | (s->i2ccon & I2CCON_INT_PEND);
18253ed424eSPaolo Bonzini         if ((s->i2ccon & I2CCON_INT_PEND) && !(v & I2CCON_INT_PEND)) {
18353ed424eSPaolo Bonzini             s->i2ccon &= ~I2CCON_INT_PEND;
18453ed424eSPaolo Bonzini             qemu_irq_lower(s->irq);
18553ed424eSPaolo Bonzini             if (!(s->i2ccon & I2CCON_INTRS_EN)) {
18653ed424eSPaolo Bonzini                 s->i2cstat &= ~I2CSTAT_START_BUSY;
18753ed424eSPaolo Bonzini             }
18853ed424eSPaolo Bonzini 
18953ed424eSPaolo Bonzini             if (s->i2cstat & I2CSTAT_START_BUSY) {
19053ed424eSPaolo Bonzini                 if (s->scl_free) {
19153ed424eSPaolo Bonzini                     if (EXYNOS4_I2C_MODE(s->i2cstat) == I2CMODE_MASTER_Tx) {
19253ed424eSPaolo Bonzini                         exynos4210_i2c_data_send(s);
19353ed424eSPaolo Bonzini                     } else if (EXYNOS4_I2C_MODE(s->i2cstat) ==
19453ed424eSPaolo Bonzini                             I2CMODE_MASTER_Rx) {
19553ed424eSPaolo Bonzini                         exynos4210_i2c_data_receive(s);
19653ed424eSPaolo Bonzini                     }
19753ed424eSPaolo Bonzini                 } else {
19853ed424eSPaolo Bonzini                     s->i2ccon |= I2CCON_INT_PEND;
19953ed424eSPaolo Bonzini                     qemu_irq_raise(s->irq);
20053ed424eSPaolo Bonzini                 }
20153ed424eSPaolo Bonzini             }
20253ed424eSPaolo Bonzini         }
20353ed424eSPaolo Bonzini         break;
20453ed424eSPaolo Bonzini     case I2CSTAT_ADDR:
20553ed424eSPaolo Bonzini         s->i2cstat =
20653ed424eSPaolo Bonzini                 (s->i2cstat & I2CSTAT_START_BUSY) | (v & ~I2CSTAT_START_BUSY);
20753ed424eSPaolo Bonzini 
20853ed424eSPaolo Bonzini         if (!(s->i2cstat & I2CSTAT_OUTPUT_EN)) {
20953ed424eSPaolo Bonzini             s->i2cstat &= ~I2CSTAT_START_BUSY;
21053ed424eSPaolo Bonzini             s->scl_free = true;
21153ed424eSPaolo Bonzini             qemu_irq_lower(s->irq);
21253ed424eSPaolo Bonzini             break;
21353ed424eSPaolo Bonzini         }
21453ed424eSPaolo Bonzini 
21553ed424eSPaolo Bonzini         /* Nothing to do if in i2c slave mode */
21653ed424eSPaolo Bonzini         if (!I2C_IN_MASTER_MODE(s->i2cstat)) {
21753ed424eSPaolo Bonzini             break;
21853ed424eSPaolo Bonzini         }
21953ed424eSPaolo Bonzini 
22053ed424eSPaolo Bonzini         if (v & I2CSTAT_START_BUSY) {
22153ed424eSPaolo Bonzini             s->i2cstat &= ~I2CSTAT_LAST_BIT;
22253ed424eSPaolo Bonzini             s->i2cstat |= I2CSTAT_START_BUSY;    /* Line is busy */
22353ed424eSPaolo Bonzini             s->scl_free = false;
22453ed424eSPaolo Bonzini 
22553ed424eSPaolo Bonzini             /* Generate start bit and send slave address */
22653ed424eSPaolo Bonzini             if (i2c_start_transfer(s->bus, s->i2cds >> 1, s->i2cds & 0x1) &&
22753ed424eSPaolo Bonzini                     (s->i2ccon & I2CCON_ACK_GEN)) {
22853ed424eSPaolo Bonzini                 s->i2cstat |= I2CSTAT_LAST_BIT;
22953ed424eSPaolo Bonzini             } else if (EXYNOS4_I2C_MODE(s->i2cstat) == I2CMODE_MASTER_Rx) {
23053ed424eSPaolo Bonzini                 exynos4210_i2c_data_receive(s);
23153ed424eSPaolo Bonzini             }
23253ed424eSPaolo Bonzini             exynos4210_i2c_raise_interrupt(s);
23353ed424eSPaolo Bonzini         } else {
23453ed424eSPaolo Bonzini             i2c_end_transfer(s->bus);
23553ed424eSPaolo Bonzini             if (!(s->i2ccon & I2CCON_INT_PEND)) {
23653ed424eSPaolo Bonzini                 s->i2cstat &= ~I2CSTAT_START_BUSY;
23753ed424eSPaolo Bonzini             }
23853ed424eSPaolo Bonzini             s->scl_free = true;
23953ed424eSPaolo Bonzini         }
24053ed424eSPaolo Bonzini         break;
24153ed424eSPaolo Bonzini     case I2CADD_ADDR:
24253ed424eSPaolo Bonzini         if ((s->i2cstat & I2CSTAT_OUTPUT_EN) == 0) {
24353ed424eSPaolo Bonzini             s->i2cadd = v;
24453ed424eSPaolo Bonzini         }
24553ed424eSPaolo Bonzini         break;
24653ed424eSPaolo Bonzini     case I2CDS_ADDR:
24753ed424eSPaolo Bonzini         if (s->i2cstat & I2CSTAT_OUTPUT_EN) {
24853ed424eSPaolo Bonzini             s->i2cds = v;
24953ed424eSPaolo Bonzini             s->scl_free = true;
25053ed424eSPaolo Bonzini             if (EXYNOS4_I2C_MODE(s->i2cstat) == I2CMODE_MASTER_Tx &&
25153ed424eSPaolo Bonzini                     (s->i2cstat & I2CSTAT_START_BUSY) &&
25253ed424eSPaolo Bonzini                     !(s->i2ccon & I2CCON_INT_PEND)) {
25353ed424eSPaolo Bonzini                 exynos4210_i2c_data_send(s);
25453ed424eSPaolo Bonzini             }
25553ed424eSPaolo Bonzini         }
25653ed424eSPaolo Bonzini         break;
25753ed424eSPaolo Bonzini     case I2CLC_ADDR:
25853ed424eSPaolo Bonzini         s->i2clc = v;
25953ed424eSPaolo Bonzini         break;
26053ed424eSPaolo Bonzini     default:
26153ed424eSPaolo Bonzini         DPRINT("ERROR: Bad write offset 0x%x\n", (unsigned int)offset);
26253ed424eSPaolo Bonzini         break;
26353ed424eSPaolo Bonzini     }
26453ed424eSPaolo Bonzini }
26553ed424eSPaolo Bonzini 
26653ed424eSPaolo Bonzini static const MemoryRegionOps exynos4210_i2c_ops = {
26753ed424eSPaolo Bonzini     .read = exynos4210_i2c_read,
26853ed424eSPaolo Bonzini     .write = exynos4210_i2c_write,
26953ed424eSPaolo Bonzini     .endianness = DEVICE_NATIVE_ENDIAN,
27053ed424eSPaolo Bonzini };
27153ed424eSPaolo Bonzini 
27253ed424eSPaolo Bonzini static const VMStateDescription exynos4210_i2c_vmstate = {
2736783ecf1SPeter Maydell     .name = "exynos4210.i2c",
27453ed424eSPaolo Bonzini     .version_id = 1,
27553ed424eSPaolo Bonzini     .minimum_version_id = 1,
27601d9442aSRichard Henderson     .fields = (const VMStateField[]) {
27753ed424eSPaolo Bonzini         VMSTATE_UINT8(i2ccon, Exynos4210I2CState),
27853ed424eSPaolo Bonzini         VMSTATE_UINT8(i2cstat, Exynos4210I2CState),
27953ed424eSPaolo Bonzini         VMSTATE_UINT8(i2cds, Exynos4210I2CState),
28053ed424eSPaolo Bonzini         VMSTATE_UINT8(i2cadd, Exynos4210I2CState),
28153ed424eSPaolo Bonzini         VMSTATE_UINT8(i2clc, Exynos4210I2CState),
28253ed424eSPaolo Bonzini         VMSTATE_BOOL(scl_free, Exynos4210I2CState),
28353ed424eSPaolo Bonzini         VMSTATE_END_OF_LIST()
28453ed424eSPaolo Bonzini     }
28553ed424eSPaolo Bonzini };
28653ed424eSPaolo Bonzini 
exynos4210_i2c_reset(DeviceState * d)28753ed424eSPaolo Bonzini static void exynos4210_i2c_reset(DeviceState *d)
28853ed424eSPaolo Bonzini {
28953ed424eSPaolo Bonzini     Exynos4210I2CState *s = EXYNOS4_I2C(d);
29053ed424eSPaolo Bonzini 
29153ed424eSPaolo Bonzini     s->i2ccon  = 0x00;
29253ed424eSPaolo Bonzini     s->i2cstat = 0x00;
29353ed424eSPaolo Bonzini     s->i2cds   = 0xFF;
29453ed424eSPaolo Bonzini     s->i2clc   = 0x00;
29553ed424eSPaolo Bonzini     s->i2cadd  = 0xFF;
29653ed424eSPaolo Bonzini     s->scl_free = true;
29753ed424eSPaolo Bonzini }
29853ed424eSPaolo Bonzini 
exynos4210_i2c_init(Object * obj)29993d6599fSxiaoqiang zhao static void exynos4210_i2c_init(Object *obj)
30053ed424eSPaolo Bonzini {
30193d6599fSxiaoqiang zhao     DeviceState *dev = DEVICE(obj);
30293d6599fSxiaoqiang zhao     Exynos4210I2CState *s = EXYNOS4_I2C(obj);
30393d6599fSxiaoqiang zhao     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
30453ed424eSPaolo Bonzini 
30593d6599fSxiaoqiang zhao     memory_region_init_io(&s->iomem, obj, &exynos4210_i2c_ops, s,
3061437c94bSPaolo Bonzini                           TYPE_EXYNOS4_I2C, EXYNOS4_I2C_MEM_SIZE);
30743603329SAndreas Färber     sysbus_init_mmio(sbd, &s->iomem);
30843603329SAndreas Färber     sysbus_init_irq(sbd, &s->irq);
30943603329SAndreas Färber     s->bus = i2c_init_bus(dev, "i2c");
31053ed424eSPaolo Bonzini }
31153ed424eSPaolo Bonzini 
exynos4210_i2c_class_init(ObjectClass * klass,void * data)31253ed424eSPaolo Bonzini static void exynos4210_i2c_class_init(ObjectClass *klass, void *data)
31353ed424eSPaolo Bonzini {
31453ed424eSPaolo Bonzini     DeviceClass *dc = DEVICE_CLASS(klass);
31553ed424eSPaolo Bonzini 
31653ed424eSPaolo Bonzini     dc->vmsd = &exynos4210_i2c_vmstate;
317*e3d08143SPeter Maydell     device_class_set_legacy_reset(dc, exynos4210_i2c_reset);
31853ed424eSPaolo Bonzini }
31953ed424eSPaolo Bonzini 
32053ed424eSPaolo Bonzini static const TypeInfo exynos4210_i2c_type_info = {
32153ed424eSPaolo Bonzini     .name = TYPE_EXYNOS4_I2C,
32253ed424eSPaolo Bonzini     .parent = TYPE_SYS_BUS_DEVICE,
32353ed424eSPaolo Bonzini     .instance_size = sizeof(Exynos4210I2CState),
32493d6599fSxiaoqiang zhao     .instance_init = exynos4210_i2c_init,
32553ed424eSPaolo Bonzini     .class_init = exynos4210_i2c_class_init,
32653ed424eSPaolo Bonzini };
32753ed424eSPaolo Bonzini 
exynos4210_i2c_register_types(void)32853ed424eSPaolo Bonzini static void exynos4210_i2c_register_types(void)
32953ed424eSPaolo Bonzini {
33053ed424eSPaolo Bonzini     type_register_static(&exynos4210_i2c_type_info);
33153ed424eSPaolo Bonzini }
33253ed424eSPaolo Bonzini 
33353ed424eSPaolo Bonzini type_init(exynos4210_i2c_register_types)
334