summaryrefslogtreecommitdiffstats
path: root/qemu/hw/i2c
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/hw/i2c')
-rw-r--r--qemu/hw/i2c/Makefile.objs8
-rw-r--r--qemu/hw/i2c/bitbang_i2c.c253
-rw-r--r--qemu/hw/i2c/bitbang_i2c.h14
-rw-r--r--qemu/hw/i2c/core.c246
-rw-r--r--qemu/hw/i2c/exynos4210_i2c.c337
-rw-r--r--qemu/hw/i2c/imx_i2c.c337
-rw-r--r--qemu/hw/i2c/omap_i2c.c509
-rw-r--r--qemu/hw/i2c/pm_smbus.c228
-rw-r--r--qemu/hw/i2c/smbus.c362
-rw-r--r--qemu/hw/i2c/smbus_eeprom.c159
-rw-r--r--qemu/hw/i2c/smbus_ich9.c130
-rw-r--r--qemu/hw/i2c/versatile_i2c.c114
12 files changed, 0 insertions, 2697 deletions
diff --git a/qemu/hw/i2c/Makefile.objs b/qemu/hw/i2c/Makefile.objs
deleted file mode 100644
index aeb8f38d7..000000000
--- a/qemu/hw/i2c/Makefile.objs
+++ /dev/null
@@ -1,8 +0,0 @@
-common-obj-y += core.o smbus.o smbus_eeprom.o
-common-obj-$(CONFIG_VERSATILE_I2C) += versatile_i2c.o
-common-obj-$(CONFIG_ACPI_X86) += smbus_ich9.o
-common-obj-$(CONFIG_APM) += pm_smbus.o
-common-obj-$(CONFIG_BITBANG_I2C) += bitbang_i2c.o
-common-obj-$(CONFIG_EXYNOS4) += exynos4210_i2c.o
-common-obj-$(CONFIG_IMX_I2C) += imx_i2c.o
-obj-$(CONFIG_OMAP) += omap_i2c.o
diff --git a/qemu/hw/i2c/bitbang_i2c.c b/qemu/hw/i2c/bitbang_i2c.c
deleted file mode 100644
index 6ed206020..000000000
--- a/qemu/hw/i2c/bitbang_i2c.c
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Bit-Bang i2c emulation extracted from
- * Marvell MV88W8618 / Freecom MusicPal emulation.
- *
- * Copyright (c) 2008 Jan Kiszka
- *
- * This code is licensed under the GNU GPL v2.
- *
- * Contributions after 2012-01-13 are licensed under the terms of the
- * GNU GPL, version 2 or (at your option) any later version.
- */
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "bitbang_i2c.h"
-#include "hw/sysbus.h"
-
-//#define DEBUG_BITBANG_I2C
-
-#ifdef DEBUG_BITBANG_I2C
-#define DPRINTF(fmt, ...) \
-do { printf("bitbang_i2c: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define DPRINTF(fmt, ...) do {} while(0)
-#endif
-
-typedef enum bitbang_i2c_state {
- STOPPED = 0,
- SENDING_BIT7,
- SENDING_BIT6,
- SENDING_BIT5,
- SENDING_BIT4,
- SENDING_BIT3,
- SENDING_BIT2,
- SENDING_BIT1,
- SENDING_BIT0,
- WAITING_FOR_ACK,
- RECEIVING_BIT7,
- RECEIVING_BIT6,
- RECEIVING_BIT5,
- RECEIVING_BIT4,
- RECEIVING_BIT3,
- RECEIVING_BIT2,
- RECEIVING_BIT1,
- RECEIVING_BIT0,
- SENDING_ACK,
- SENT_NACK
-} bitbang_i2c_state;
-
-struct bitbang_i2c_interface {
- I2CBus *bus;
- bitbang_i2c_state state;
- int last_data;
- int last_clock;
- int device_out;
- uint8_t buffer;
- int current_addr;
-};
-
-static void bitbang_i2c_enter_stop(bitbang_i2c_interface *i2c)
-{
- DPRINTF("STOP\n");
- if (i2c->current_addr >= 0)
- i2c_end_transfer(i2c->bus);
- i2c->current_addr = -1;
- i2c->state = STOPPED;
-}
-
-/* Set device data pin. */
-static int bitbang_i2c_ret(bitbang_i2c_interface *i2c, int level)
-{
- i2c->device_out = level;
- //DPRINTF("%d %d %d\n", i2c->last_clock, i2c->last_data, i2c->device_out);
- return level & i2c->last_data;
-}
-
-/* Leave device data pin unodified. */
-static int bitbang_i2c_nop(bitbang_i2c_interface *i2c)
-{
- return bitbang_i2c_ret(i2c, i2c->device_out);
-}
-
-/* Returns data line level. */
-int bitbang_i2c_set(bitbang_i2c_interface *i2c, int line, int level)
-{
- int data;
-
- if (level != 0 && level != 1) {
- abort();
- }
-
- if (line == BITBANG_I2C_SDA) {
- if (level == i2c->last_data) {
- return bitbang_i2c_nop(i2c);
- }
- i2c->last_data = level;
- if (i2c->last_clock == 0) {
- return bitbang_i2c_nop(i2c);
- }
- if (level == 0) {
- DPRINTF("START\n");
- /* START condition. */
- i2c->state = SENDING_BIT7;
- i2c->current_addr = -1;
- } else {
- /* STOP condition. */
- bitbang_i2c_enter_stop(i2c);
- }
- return bitbang_i2c_ret(i2c, 1);
- }
-
- data = i2c->last_data;
- if (i2c->last_clock == level) {
- return bitbang_i2c_nop(i2c);
- }
- i2c->last_clock = level;
- if (level == 0) {
- /* State is set/read at the start of the clock pulse.
- release the data line at the end. */
- return bitbang_i2c_ret(i2c, 1);
- }
- switch (i2c->state) {
- case STOPPED:
- case SENT_NACK:
- return bitbang_i2c_ret(i2c, 1);
-
- case SENDING_BIT7 ... SENDING_BIT0:
- i2c->buffer = (i2c->buffer << 1) | data;
- /* will end up in WAITING_FOR_ACK */
- i2c->state++;
- return bitbang_i2c_ret(i2c, 1);
-
- case WAITING_FOR_ACK:
- if (i2c->current_addr < 0) {
- i2c->current_addr = i2c->buffer;
- DPRINTF("Address 0x%02x\n", i2c->current_addr);
- i2c_start_transfer(i2c->bus, i2c->current_addr >> 1,
- i2c->current_addr & 1);
- } else {
- DPRINTF("Sent 0x%02x\n", i2c->buffer);
- i2c_send(i2c->bus, i2c->buffer);
- }
- if (i2c->current_addr & 1) {
- i2c->state = RECEIVING_BIT7;
- } else {
- i2c->state = SENDING_BIT7;
- }
- return bitbang_i2c_ret(i2c, 0);
-
- case RECEIVING_BIT7:
- i2c->buffer = i2c_recv(i2c->bus);
- DPRINTF("RX byte 0x%02x\n", i2c->buffer);
- /* Fall through... */
- case RECEIVING_BIT6 ... RECEIVING_BIT0:
- data = i2c->buffer >> 7;
- /* will end up in SENDING_ACK */
- i2c->state++;
- i2c->buffer <<= 1;
- return bitbang_i2c_ret(i2c, data);
-
- case SENDING_ACK:
- i2c->state = RECEIVING_BIT7;
- if (data != 0) {
- DPRINTF("NACKED\n");
- i2c->state = SENT_NACK;
- i2c_nack(i2c->bus);
- } else {
- DPRINTF("ACKED\n");
- }
- return bitbang_i2c_ret(i2c, 1);
- }
- abort();
-}
-
-bitbang_i2c_interface *bitbang_i2c_init(I2CBus *bus)
-{
- bitbang_i2c_interface *s;
-
- s = g_malloc0(sizeof(bitbang_i2c_interface));
-
- s->bus = bus;
- s->last_data = 1;
- s->last_clock = 1;
- s->device_out = 1;
-
- return s;
-}
-
-/* GPIO interface. */
-
-#define TYPE_GPIO_I2C "gpio_i2c"
-#define GPIO_I2C(obj) OBJECT_CHECK(GPIOI2CState, (obj), TYPE_GPIO_I2C)
-
-typedef struct GPIOI2CState {
- SysBusDevice parent_obj;
-
- MemoryRegion dummy_iomem;
- bitbang_i2c_interface *bitbang;
- int last_level;
- qemu_irq out;
-} GPIOI2CState;
-
-static void bitbang_i2c_gpio_set(void *opaque, int irq, int level)
-{
- GPIOI2CState *s = opaque;
-
- level = bitbang_i2c_set(s->bitbang, irq, level);
- if (level != s->last_level) {
- s->last_level = level;
- qemu_set_irq(s->out, level);
- }
-}
-
-static int gpio_i2c_init(SysBusDevice *sbd)
-{
- DeviceState *dev = DEVICE(sbd);
- GPIOI2CState *s = GPIO_I2C(dev);
- I2CBus *bus;
-
- memory_region_init(&s->dummy_iomem, OBJECT(s), "gpio_i2c", 0);
- sysbus_init_mmio(sbd, &s->dummy_iomem);
-
- bus = i2c_init_bus(dev, "i2c");
- s->bitbang = bitbang_i2c_init(bus);
-
- qdev_init_gpio_in(dev, bitbang_i2c_gpio_set, 2);
- qdev_init_gpio_out(dev, &s->out, 1);
-
- return 0;
-}
-
-static void gpio_i2c_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
- k->init = gpio_i2c_init;
- set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
- dc->desc = "Virtual GPIO to I2C bridge";
-}
-
-static const TypeInfo gpio_i2c_info = {
- .name = TYPE_GPIO_I2C,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(GPIOI2CState),
- .class_init = gpio_i2c_class_init,
-};
-
-static void bitbang_i2c_register_types(void)
-{
- type_register_static(&gpio_i2c_info);
-}
-
-type_init(bitbang_i2c_register_types)
diff --git a/qemu/hw/i2c/bitbang_i2c.h b/qemu/hw/i2c/bitbang_i2c.h
deleted file mode 100644
index 3a7126d5d..000000000
--- a/qemu/hw/i2c/bitbang_i2c.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef BITBANG_I2C_H
-#define BITBANG_I2C_H
-
-#include "hw/i2c/i2c.h"
-
-typedef struct bitbang_i2c_interface bitbang_i2c_interface;
-
-#define BITBANG_I2C_SDA 0
-#define BITBANG_I2C_SCL 1
-
-bitbang_i2c_interface *bitbang_i2c_init(I2CBus *bus);
-int bitbang_i2c_set(bitbang_i2c_interface *i2c, int line, int level);
-
-#endif
diff --git a/qemu/hw/i2c/core.c b/qemu/hw/i2c/core.c
deleted file mode 100644
index ba22104af..000000000
--- a/qemu/hw/i2c/core.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * QEMU I2C bus interface.
- *
- * Copyright (c) 2007 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licensed under the LGPL.
- */
-
-#include "qemu/osdep.h"
-#include "hw/i2c/i2c.h"
-
-struct I2CBus
-{
- BusState qbus;
- I2CSlave *current_dev;
- I2CSlave *dev;
- uint8_t saved_address;
-};
-
-static Property i2c_props[] = {
- DEFINE_PROP_UINT8("address", struct I2CSlave, address, 0),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-#define TYPE_I2C_BUS "i2c-bus"
-#define I2C_BUS(obj) OBJECT_CHECK(I2CBus, (obj), TYPE_I2C_BUS)
-
-static const TypeInfo i2c_bus_info = {
- .name = TYPE_I2C_BUS,
- .parent = TYPE_BUS,
- .instance_size = sizeof(I2CBus),
-};
-
-static void i2c_bus_pre_save(void *opaque)
-{
- I2CBus *bus = opaque;
-
- bus->saved_address = bus->current_dev ? bus->current_dev->address : -1;
-}
-
-static int i2c_bus_post_load(void *opaque, int version_id)
-{
- I2CBus *bus = opaque;
-
- /* The bus is loaded before attached devices, so load and save the
- current device id. Devices will check themselves as loaded. */
- bus->current_dev = NULL;
- return 0;
-}
-
-static const VMStateDescription vmstate_i2c_bus = {
- .name = "i2c_bus",
- .version_id = 1,
- .minimum_version_id = 1,
- .pre_save = i2c_bus_pre_save,
- .post_load = i2c_bus_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_UINT8(saved_address, I2CBus),
- VMSTATE_END_OF_LIST()
- }
-};
-
-/* Create a new I2C bus. */
-I2CBus *i2c_init_bus(DeviceState *parent, const char *name)
-{
- I2CBus *bus;
-
- bus = I2C_BUS(qbus_create(TYPE_I2C_BUS, parent, name));
- vmstate_register(NULL, -1, &vmstate_i2c_bus, bus);
- return bus;
-}
-
-void i2c_set_slave_address(I2CSlave *dev, uint8_t address)
-{
- dev->address = address;
-}
-
-/* Return nonzero if bus is busy. */
-int i2c_bus_busy(I2CBus *bus)
-{
- return bus->current_dev != NULL;
-}
-
-/* Returns non-zero if the address is not valid. */
-/* TODO: Make this handle multiple masters. */
-int i2c_start_transfer(I2CBus *bus, uint8_t address, int recv)
-{
- BusChild *kid;
- I2CSlave *slave = NULL;
- I2CSlaveClass *sc;
-
- QTAILQ_FOREACH(kid, &bus->qbus.children, sibling) {
- DeviceState *qdev = kid->child;
- I2CSlave *candidate = I2C_SLAVE(qdev);
- if (candidate->address == address) {
- slave = candidate;
- break;
- }
- }
-
- if (!slave) {
- return 1;
- }
-
- sc = I2C_SLAVE_GET_CLASS(slave);
- /* If the bus is already busy, assume this is a repeated
- start condition. */
- bus->current_dev = slave;
- if (sc->event) {
- sc->event(slave, recv ? I2C_START_RECV : I2C_START_SEND);
- }
- return 0;
-}
-
-void i2c_end_transfer(I2CBus *bus)
-{
- I2CSlave *dev = bus->current_dev;
- I2CSlaveClass *sc;
-
- if (!dev) {
- return;
- }
-
- sc = I2C_SLAVE_GET_CLASS(dev);
- if (sc->event) {
- sc->event(dev, I2C_FINISH);
- }
-
- bus->current_dev = NULL;
-}
-
-int i2c_send(I2CBus *bus, uint8_t data)
-{
- I2CSlave *dev = bus->current_dev;
- I2CSlaveClass *sc;
-
- if (!dev) {
- return -1;
- }
-
- sc = I2C_SLAVE_GET_CLASS(dev);
- if (sc->send) {
- return sc->send(dev, data);
- }
-
- return -1;
-}
-
-int i2c_recv(I2CBus *bus)
-{
- I2CSlave *dev = bus->current_dev;
- I2CSlaveClass *sc;
-
- if (!dev) {
- return -1;
- }
-
- sc = I2C_SLAVE_GET_CLASS(dev);
- if (sc->recv) {
- return sc->recv(dev);
- }
-
- return -1;
-}
-
-void i2c_nack(I2CBus *bus)
-{
- I2CSlave *dev = bus->current_dev;
- I2CSlaveClass *sc;
-
- if (!dev) {
- return;
- }
-
- sc = I2C_SLAVE_GET_CLASS(dev);
- if (sc->event) {
- sc->event(dev, I2C_NACK);
- }
-}
-
-static int i2c_slave_post_load(void *opaque, int version_id)
-{
- I2CSlave *dev = opaque;
- I2CBus *bus;
- bus = I2C_BUS(qdev_get_parent_bus(DEVICE(dev)));
- if (bus->saved_address == dev->address) {
- bus->current_dev = dev;
- }
- return 0;
-}
-
-const VMStateDescription vmstate_i2c_slave = {
- .name = "I2CSlave",
- .version_id = 1,
- .minimum_version_id = 1,
- .post_load = i2c_slave_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_UINT8(address, I2CSlave),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static int i2c_slave_qdev_init(DeviceState *dev)
-{
- I2CSlave *s = I2C_SLAVE(dev);
- I2CSlaveClass *sc = I2C_SLAVE_GET_CLASS(s);
-
- return sc->init(s);
-}
-
-DeviceState *i2c_create_slave(I2CBus *bus, const char *name, uint8_t addr)
-{
- DeviceState *dev;
-
- dev = qdev_create(&bus->qbus, name);
- qdev_prop_set_uint8(dev, "address", addr);
- qdev_init_nofail(dev);
- return dev;
-}
-
-static void i2c_slave_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *k = DEVICE_CLASS(klass);
- k->init = i2c_slave_qdev_init;
- set_bit(DEVICE_CATEGORY_MISC, k->categories);
- k->bus_type = TYPE_I2C_BUS;
- k->props = i2c_props;
-}
-
-static const TypeInfo i2c_slave_type_info = {
- .name = TYPE_I2C_SLAVE,
- .parent = TYPE_DEVICE,
- .instance_size = sizeof(I2CSlave),
- .abstract = true,
- .class_size = sizeof(I2CSlaveClass),
- .class_init = i2c_slave_class_init,
-};
-
-static void i2c_slave_register_types(void)
-{
- type_register_static(&i2c_bus_info);
- type_register_static(&i2c_slave_type_info);
-}
-
-type_init(i2c_slave_register_types)
diff --git a/qemu/hw/i2c/exynos4210_i2c.c b/qemu/hw/i2c/exynos4210_i2c.c
deleted file mode 100644
index 8c2a2c163..000000000
--- a/qemu/hw/i2c/exynos4210_i2c.c
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * Exynos4210 I2C Bus Serial Interface Emulation
- *
- * Copyright (C) 2012 Samsung Electronics Co Ltd.
- * Maksim Kozlov, <m.kozlov@samsung.com>
- * Igor Mitsyanko, <i.mitsyanko@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "qemu/osdep.h"
-#include "qemu/timer.h"
-#include "hw/sysbus.h"
-#include "hw/i2c/i2c.h"
-
-#ifndef EXYNOS4_I2C_DEBUG
-#define EXYNOS4_I2C_DEBUG 0
-#endif
-
-#define TYPE_EXYNOS4_I2C "exynos4210.i2c"
-#define EXYNOS4_I2C(obj) \
- OBJECT_CHECK(Exynos4210I2CState, (obj), TYPE_EXYNOS4_I2C)
-
-/* Exynos4210 I2C memory map */
-#define EXYNOS4_I2C_MEM_SIZE 0x14
-#define I2CCON_ADDR 0x00 /* control register */
-#define I2CSTAT_ADDR 0x04 /* control/status register */
-#define I2CADD_ADDR 0x08 /* address register */
-#define I2CDS_ADDR 0x0c /* data shift register */
-#define I2CLC_ADDR 0x10 /* line control register */
-
-#define I2CCON_ACK_GEN (1 << 7)
-#define I2CCON_INTRS_EN (1 << 5)
-#define I2CCON_INT_PEND (1 << 4)
-
-#define EXYNOS4_I2C_MODE(reg) (((reg) >> 6) & 3)
-#define I2C_IN_MASTER_MODE(reg) (((reg) >> 6) & 2)
-#define I2CMODE_MASTER_Rx 0x2
-#define I2CMODE_MASTER_Tx 0x3
-#define I2CSTAT_LAST_BIT (1 << 0)
-#define I2CSTAT_OUTPUT_EN (1 << 4)
-#define I2CSTAT_START_BUSY (1 << 5)
-
-
-#if EXYNOS4_I2C_DEBUG
-#define DPRINT(fmt, args...) \
- do { fprintf(stderr, "QEMU I2C: "fmt, ## args); } while (0)
-
-static const char *exynos4_i2c_get_regname(unsigned offset)
-{
- switch (offset) {
- case I2CCON_ADDR:
- return "I2CCON";
- case I2CSTAT_ADDR:
- return "I2CSTAT";
- case I2CADD_ADDR:
- return "I2CADD";
- case I2CDS_ADDR:
- return "I2CDS";
- case I2CLC_ADDR:
- return "I2CLC";
- default:
- return "[?]";
- }
-}
-
-#else
-#define DPRINT(fmt, args...) do { } while (0)
-#endif
-
-typedef struct Exynos4210I2CState {
- SysBusDevice parent_obj;
-
- MemoryRegion iomem;
- I2CBus *bus;
- qemu_irq irq;
-
- uint8_t i2ccon;
- uint8_t i2cstat;
- uint8_t i2cadd;
- uint8_t i2cds;
- uint8_t i2clc;
- bool scl_free;
-} Exynos4210I2CState;
-
-static inline void exynos4210_i2c_raise_interrupt(Exynos4210I2CState *s)
-{
- if (s->i2ccon & I2CCON_INTRS_EN) {
- s->i2ccon |= I2CCON_INT_PEND;
- qemu_irq_raise(s->irq);
- }
-}
-
-static void exynos4210_i2c_data_receive(void *opaque)
-{
- Exynos4210I2CState *s = (Exynos4210I2CState *)opaque;
- int ret;
-
- s->i2cstat &= ~I2CSTAT_LAST_BIT;
- s->scl_free = false;
- ret = i2c_recv(s->bus);
- if (ret < 0 && (s->i2ccon & I2CCON_ACK_GEN)) {
- s->i2cstat |= I2CSTAT_LAST_BIT; /* Data is not acknowledged */
- } else {
- s->i2cds = ret;
- }
- exynos4210_i2c_raise_interrupt(s);
-}
-
-static void exynos4210_i2c_data_send(void *opaque)
-{
- Exynos4210I2CState *s = (Exynos4210I2CState *)opaque;
-
- s->i2cstat &= ~I2CSTAT_LAST_BIT;
- s->scl_free = false;
- if (i2c_send(s->bus, s->i2cds) < 0 && (s->i2ccon & I2CCON_ACK_GEN)) {
- s->i2cstat |= I2CSTAT_LAST_BIT;
- }
- exynos4210_i2c_raise_interrupt(s);
-}
-
-static uint64_t exynos4210_i2c_read(void *opaque, hwaddr offset,
- unsigned size)
-{
- Exynos4210I2CState *s = (Exynos4210I2CState *)opaque;
- uint8_t value;
-
- switch (offset) {
- case I2CCON_ADDR:
- value = s->i2ccon;
- break;
- case I2CSTAT_ADDR:
- value = s->i2cstat;
- break;
- case I2CADD_ADDR:
- value = s->i2cadd;
- break;
- case I2CDS_ADDR:
- value = s->i2cds;
- s->scl_free = true;
- if (EXYNOS4_I2C_MODE(s->i2cstat) == I2CMODE_MASTER_Rx &&
- (s->i2cstat & I2CSTAT_START_BUSY) &&
- !(s->i2ccon & I2CCON_INT_PEND)) {
- exynos4210_i2c_data_receive(s);
- }
- break;
- case I2CLC_ADDR:
- value = s->i2clc;
- break;
- default:
- value = 0;
- DPRINT("ERROR: Bad read offset 0x%x\n", (unsigned int)offset);
- break;
- }
-
- DPRINT("read %s [0x%02x] -> 0x%02x\n", exynos4_i2c_get_regname(offset),
- (unsigned int)offset, value);
- return value;
-}
-
-static void exynos4210_i2c_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
-{
- Exynos4210I2CState *s = (Exynos4210I2CState *)opaque;
- uint8_t v = value & 0xff;
-
- DPRINT("write %s [0x%02x] <- 0x%02x\n", exynos4_i2c_get_regname(offset),
- (unsigned int)offset, v);
-
- switch (offset) {
- case I2CCON_ADDR:
- s->i2ccon = (v & ~I2CCON_INT_PEND) | (s->i2ccon & I2CCON_INT_PEND);
- if ((s->i2ccon & I2CCON_INT_PEND) && !(v & I2CCON_INT_PEND)) {
- s->i2ccon &= ~I2CCON_INT_PEND;
- qemu_irq_lower(s->irq);
- if (!(s->i2ccon & I2CCON_INTRS_EN)) {
- s->i2cstat &= ~I2CSTAT_START_BUSY;
- }
-
- if (s->i2cstat & I2CSTAT_START_BUSY) {
- if (s->scl_free) {
- if (EXYNOS4_I2C_MODE(s->i2cstat) == I2CMODE_MASTER_Tx) {
- exynos4210_i2c_data_send(s);
- } else if (EXYNOS4_I2C_MODE(s->i2cstat) ==
- I2CMODE_MASTER_Rx) {
- exynos4210_i2c_data_receive(s);
- }
- } else {
- s->i2ccon |= I2CCON_INT_PEND;
- qemu_irq_raise(s->irq);
- }
- }
- }
- break;
- case I2CSTAT_ADDR:
- s->i2cstat =
- (s->i2cstat & I2CSTAT_START_BUSY) | (v & ~I2CSTAT_START_BUSY);
-
- if (!(s->i2cstat & I2CSTAT_OUTPUT_EN)) {
- s->i2cstat &= ~I2CSTAT_START_BUSY;
- s->scl_free = true;
- qemu_irq_lower(s->irq);
- break;
- }
-
- /* Nothing to do if in i2c slave mode */
- if (!I2C_IN_MASTER_MODE(s->i2cstat)) {
- break;
- }
-
- if (v & I2CSTAT_START_BUSY) {
- s->i2cstat &= ~I2CSTAT_LAST_BIT;
- s->i2cstat |= I2CSTAT_START_BUSY; /* Line is busy */
- s->scl_free = false;
-
- /* Generate start bit and send slave address */
- if (i2c_start_transfer(s->bus, s->i2cds >> 1, s->i2cds & 0x1) &&
- (s->i2ccon & I2CCON_ACK_GEN)) {
- s->i2cstat |= I2CSTAT_LAST_BIT;
- } else if (EXYNOS4_I2C_MODE(s->i2cstat) == I2CMODE_MASTER_Rx) {
- exynos4210_i2c_data_receive(s);
- }
- exynos4210_i2c_raise_interrupt(s);
- } else {
- i2c_end_transfer(s->bus);
- if (!(s->i2ccon & I2CCON_INT_PEND)) {
- s->i2cstat &= ~I2CSTAT_START_BUSY;
- }
- s->scl_free = true;
- }
- break;
- case I2CADD_ADDR:
- if ((s->i2cstat & I2CSTAT_OUTPUT_EN) == 0) {
- s->i2cadd = v;
- }
- break;
- case I2CDS_ADDR:
- if (s->i2cstat & I2CSTAT_OUTPUT_EN) {
- s->i2cds = v;
- s->scl_free = true;
- if (EXYNOS4_I2C_MODE(s->i2cstat) == I2CMODE_MASTER_Tx &&
- (s->i2cstat & I2CSTAT_START_BUSY) &&
- !(s->i2ccon & I2CCON_INT_PEND)) {
- exynos4210_i2c_data_send(s);
- }
- }
- break;
- case I2CLC_ADDR:
- s->i2clc = v;
- break;
- default:
- DPRINT("ERROR: Bad write offset 0x%x\n", (unsigned int)offset);
- break;
- }
-}
-
-static const MemoryRegionOps exynos4210_i2c_ops = {
- .read = exynos4210_i2c_read,
- .write = exynos4210_i2c_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static const VMStateDescription exynos4210_i2c_vmstate = {
- .name = "exynos4210.i2c",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT8(i2ccon, Exynos4210I2CState),
- VMSTATE_UINT8(i2cstat, Exynos4210I2CState),
- VMSTATE_UINT8(i2cds, Exynos4210I2CState),
- VMSTATE_UINT8(i2cadd, Exynos4210I2CState),
- VMSTATE_UINT8(i2clc, Exynos4210I2CState),
- VMSTATE_BOOL(scl_free, Exynos4210I2CState),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static void exynos4210_i2c_reset(DeviceState *d)
-{
- Exynos4210I2CState *s = EXYNOS4_I2C(d);
-
- s->i2ccon = 0x00;
- s->i2cstat = 0x00;
- s->i2cds = 0xFF;
- s->i2clc = 0x00;
- s->i2cadd = 0xFF;
- s->scl_free = true;
-}
-
-static int exynos4210_i2c_realize(SysBusDevice *sbd)
-{
- DeviceState *dev = DEVICE(sbd);
- Exynos4210I2CState *s = EXYNOS4_I2C(dev);
-
- memory_region_init_io(&s->iomem, OBJECT(s), &exynos4210_i2c_ops, s,
- TYPE_EXYNOS4_I2C, EXYNOS4_I2C_MEM_SIZE);
- sysbus_init_mmio(sbd, &s->iomem);
- sysbus_init_irq(sbd, &s->irq);
- s->bus = i2c_init_bus(dev, "i2c");
- return 0;
-}
-
-static void exynos4210_i2c_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *sbdc = SYS_BUS_DEVICE_CLASS(klass);
-
- dc->vmsd = &exynos4210_i2c_vmstate;
- dc->reset = exynos4210_i2c_reset;
- sbdc->init = exynos4210_i2c_realize;
-}
-
-static const TypeInfo exynos4210_i2c_type_info = {
- .name = TYPE_EXYNOS4_I2C,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(Exynos4210I2CState),
- .class_init = exynos4210_i2c_class_init,
-};
-
-static void exynos4210_i2c_register_types(void)
-{
- type_register_static(&exynos4210_i2c_type_info);
-}
-
-type_init(exynos4210_i2c_register_types)
diff --git a/qemu/hw/i2c/imx_i2c.c b/qemu/hw/i2c/imx_i2c.c
deleted file mode 100644
index a01e43ebe..000000000
--- a/qemu/hw/i2c/imx_i2c.c
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * i.MX I2C Bus Serial Interface Emulation
- *
- * Copyright (C) 2013 Jean-Christophe Dubois. <jcd@tribudubois.net>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "qemu/osdep.h"
-#include "hw/i2c/imx_i2c.h"
-#include "hw/i2c/i2c.h"
-
-#ifndef DEBUG_IMX_I2C
-#define DEBUG_IMX_I2C 0
-#endif
-
-#define DPRINTF(fmt, args...) \
- do { \
- if (DEBUG_IMX_I2C) { \
- fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX_I2C, \
- __func__, ##args); \
- } \
- } while (0)
-
-static const char *imx_i2c_get_regname(unsigned offset)
-{
- switch (offset) {
- case IADR_ADDR:
- return "IADR";
- case IFDR_ADDR:
- return "IFDR";
- case I2CR_ADDR:
- return "I2CR";
- case I2SR_ADDR:
- return "I2SR";
- case I2DR_ADDR:
- return "I2DR";
- default:
- return "[?]";
- }
-}
-
-static inline bool imx_i2c_is_enabled(IMXI2CState *s)
-{
- return s->i2cr & I2CR_IEN;
-}
-
-static inline bool imx_i2c_interrupt_is_enabled(IMXI2CState *s)
-{
- return s->i2cr & I2CR_IIEN;
-}
-
-static inline bool imx_i2c_is_master(IMXI2CState *s)
-{
- return s->i2cr & I2CR_MSTA;
-}
-
-static void imx_i2c_reset(DeviceState *dev)
-{
- IMXI2CState *s = IMX_I2C(dev);
-
- if (s->address != ADDR_RESET) {
- i2c_end_transfer(s->bus);
- }
-
- s->address = ADDR_RESET;
- s->iadr = IADR_RESET;
- s->ifdr = IFDR_RESET;
- s->i2cr = I2CR_RESET;
- s->i2sr = I2SR_RESET;
- s->i2dr_read = I2DR_RESET;
- s->i2dr_write = I2DR_RESET;
-}
-
-static inline void imx_i2c_raise_interrupt(IMXI2CState *s)
-{
- /*
- * raise an interrupt if the device is enabled and it is configured
- * to generate some interrupts.
- */
- if (imx_i2c_is_enabled(s) && imx_i2c_interrupt_is_enabled(s)) {
- s->i2sr |= I2SR_IIF;
- qemu_irq_raise(s->irq);
- }
-}
-
-static uint64_t imx_i2c_read(void *opaque, hwaddr offset,
- unsigned size)
-{
- uint16_t value;
- IMXI2CState *s = IMX_I2C(opaque);
-
- switch (offset) {
- case IADR_ADDR:
- value = s->iadr;
- break;
- case IFDR_ADDR:
- value = s->ifdr;
- break;
- case I2CR_ADDR:
- value = s->i2cr;
- break;
- case I2SR_ADDR:
- value = s->i2sr;
- break;
- case I2DR_ADDR:
- value = s->i2dr_read;
-
- if (imx_i2c_is_master(s)) {
- int ret = 0xff;
-
- if (s->address == ADDR_RESET) {
- /* something is wrong as the address is not set */
- qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Trying to read "
- "without specifying the slave address\n",
- TYPE_IMX_I2C, __func__);
- } else if (s->i2cr & I2CR_MTX) {
- qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Trying to read "
- "but MTX is set\n", TYPE_IMX_I2C, __func__);
- } else {
- /* get the next byte */
- ret = i2c_recv(s->bus);
-
- if (ret >= 0) {
- imx_i2c_raise_interrupt(s);
- } else {
- qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: read failed "
- "for device 0x%02x\n", TYPE_IMX_I2C,
- __func__, s->address);
- ret = 0xff;
- }
- }
-
- s->i2dr_read = ret;
- } else {
- qemu_log_mask(LOG_UNIMP, "[%s]%s: slave mode not implemented\n",
- TYPE_IMX_I2C, __func__);
- }
- break;
- default:
- qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad address at offset 0x%"
- HWADDR_PRIx "\n", TYPE_IMX_I2C, __func__, offset);
- value = 0;
- break;
- }
-
- DPRINTF("read %s [0x%" HWADDR_PRIx "] -> 0x%02x\n",
- imx_i2c_get_regname(offset), offset, value);
-
- return (uint64_t)value;
-}
-
-static void imx_i2c_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
-{
- IMXI2CState *s = IMX_I2C(opaque);
-
- DPRINTF("write %s [0x%" HWADDR_PRIx "] <- 0x%02x\n",
- imx_i2c_get_regname(offset), offset, (int)value);
-
- value &= 0xff;
-
- switch (offset) {
- case IADR_ADDR:
- s->iadr = value & IADR_MASK;
- /* i2c_set_slave_address(s->bus, (uint8_t)s->iadr); */
- break;
- case IFDR_ADDR:
- s->ifdr = value & IFDR_MASK;
- break;
- case I2CR_ADDR:
- if (imx_i2c_is_enabled(s) && ((value & I2CR_IEN) == 0)) {
- /* This is a soft reset. IADR is preserved during soft resets */
- uint16_t iadr = s->iadr;
- imx_i2c_reset(DEVICE(s));
- s->iadr = iadr;
- } else { /* normal write */
- s->i2cr = value & I2CR_MASK;
-
- if (imx_i2c_is_master(s)) {
- /* set the bus to busy */
- s->i2sr |= I2SR_IBB;
- } else { /* slave mode */
- /* bus is not busy anymore */
- s->i2sr &= ~I2SR_IBB;
-
- /*
- * if we unset the master mode then it ends the ongoing
- * transfer if any
- */
- if (s->address != ADDR_RESET) {
- i2c_end_transfer(s->bus);
- s->address = ADDR_RESET;
- }
- }
-
- if (s->i2cr & I2CR_RSTA) { /* Restart */
- /* if this is a restart then it ends the ongoing transfer */
- if (s->address != ADDR_RESET) {
- i2c_end_transfer(s->bus);
- s->address = ADDR_RESET;
- s->i2cr &= ~I2CR_RSTA;
- }
- }
- }
- break;
- case I2SR_ADDR:
- /*
- * if the user writes 0 to IIF then lower the interrupt and
- * reset the bit
- */
- if ((s->i2sr & I2SR_IIF) && !(value & I2SR_IIF)) {
- s->i2sr &= ~I2SR_IIF;
- qemu_irq_lower(s->irq);
- }
-
- /*
- * if the user writes 0 to IAL, reset the bit
- */
- if ((s->i2sr & I2SR_IAL) && !(value & I2SR_IAL)) {
- s->i2sr &= ~I2SR_IAL;
- }
-
- break;
- case I2DR_ADDR:
- /* if the device is not enabled, nothing to do */
- if (!imx_i2c_is_enabled(s)) {
- break;
- }
-
- s->i2dr_write = value & I2DR_MASK;
-
- if (imx_i2c_is_master(s)) {
- /* If this is the first write cycle then it is the slave addr */
- if (s->address == ADDR_RESET) {
- if (i2c_start_transfer(s->bus, extract32(s->i2dr_write, 1, 7),
- extract32(s->i2dr_write, 0, 1))) {
- /* if non zero is returned, the adress is not valid */
- s->i2sr |= I2SR_RXAK;
- } else {
- s->address = s->i2dr_write;
- s->i2sr &= ~I2SR_RXAK;
- imx_i2c_raise_interrupt(s);
- }
- } else { /* This is a normal data write */
- if (i2c_send(s->bus, s->i2dr_write)) {
- /* if the target return non zero then end the transfer */
- s->i2sr |= I2SR_RXAK;
- s->address = ADDR_RESET;
- i2c_end_transfer(s->bus);
- } else {
- s->i2sr &= ~I2SR_RXAK;
- imx_i2c_raise_interrupt(s);
- }
- }
- } else {
- qemu_log_mask(LOG_UNIMP, "[%s]%s: slave mode not implemented\n",
- TYPE_IMX_I2C, __func__);
- }
- break;
- default:
- qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad address at offset 0x%"
- HWADDR_PRIx "\n", TYPE_IMX_I2C, __func__, offset);
- break;
- }
-}
-
-static const MemoryRegionOps imx_i2c_ops = {
- .read = imx_i2c_read,
- .write = imx_i2c_write,
- .valid.min_access_size = 1,
- .valid.max_access_size = 2,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static const VMStateDescription imx_i2c_vmstate = {
- .name = TYPE_IMX_I2C,
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT16(address, IMXI2CState),
- VMSTATE_UINT16(iadr, IMXI2CState),
- VMSTATE_UINT16(ifdr, IMXI2CState),
- VMSTATE_UINT16(i2cr, IMXI2CState),
- VMSTATE_UINT16(i2sr, IMXI2CState),
- VMSTATE_UINT16(i2dr_read, IMXI2CState),
- VMSTATE_UINT16(i2dr_write, IMXI2CState),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static void imx_i2c_realize(DeviceState *dev, Error **errp)
-{
- IMXI2CState *s = IMX_I2C(dev);
-
- memory_region_init_io(&s->iomem, OBJECT(s), &imx_i2c_ops, s, TYPE_IMX_I2C,
- IMX_I2C_MEM_SIZE);
- sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
- sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
- s->bus = i2c_init_bus(DEVICE(dev), "i2c");
-}
-
-static void imx_i2c_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
-
- dc->vmsd = &imx_i2c_vmstate;
- dc->reset = imx_i2c_reset;
- dc->realize = imx_i2c_realize;
- dc->desc = "i.MX I2C Controller";
-}
-
-static const TypeInfo imx_i2c_type_info = {
- .name = TYPE_IMX_I2C,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(IMXI2CState),
- .class_init = imx_i2c_class_init,
-};
-
-static void imx_i2c_register_types(void)
-{
- type_register_static(&imx_i2c_type_info);
-}
-
-type_init(imx_i2c_register_types)
diff --git a/qemu/hw/i2c/omap_i2c.c b/qemu/hw/i2c/omap_i2c.c
deleted file mode 100644
index 67fbbff8e..000000000
--- a/qemu/hw/i2c/omap_i2c.c
+++ /dev/null
@@ -1,509 +0,0 @@
-/*
- * TI OMAP on-chip I2C controller. Only "new I2C" mode supported.
- *
- * Copyright (C) 2007 Andrzej Zaborowski <balrog@zabor.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "hw/i2c/i2c.h"
-#include "hw/arm/omap.h"
-#include "hw/sysbus.h"
-#include "qemu/error-report.h"
-
-#define TYPE_OMAP_I2C "omap_i2c"
-#define OMAP_I2C(obj) OBJECT_CHECK(OMAPI2CState, (obj), TYPE_OMAP_I2C)
-
-typedef struct OMAPI2CState {
- SysBusDevice parent_obj;
-
- MemoryRegion iomem;
- qemu_irq irq;
- qemu_irq drq[2];
- I2CBus *bus;
-
- uint8_t revision;
- void *iclk;
- void *fclk;
-
- uint8_t mask;
- uint16_t stat;
- uint16_t dma;
- uint16_t count;
- int count_cur;
- uint32_t fifo;
- int rxlen;
- int txlen;
- uint16_t control;
- uint16_t addr[2];
- uint8_t divider;
- uint8_t times[2];
- uint16_t test;
-} OMAPI2CState;
-
-#define OMAP2_INTR_REV 0x34
-#define OMAP2_GC_REV 0x34
-
-static void omap_i2c_interrupts_update(OMAPI2CState *s)
-{
- qemu_set_irq(s->irq, s->stat & s->mask);
- if ((s->dma >> 15) & 1) /* RDMA_EN */
- qemu_set_irq(s->drq[0], (s->stat >> 3) & 1); /* RRDY */
- if ((s->dma >> 7) & 1) /* XDMA_EN */
- qemu_set_irq(s->drq[1], (s->stat >> 4) & 1); /* XRDY */
-}
-
-static void omap_i2c_fifo_run(OMAPI2CState *s)
-{
- int ack = 1;
-
- if (!i2c_bus_busy(s->bus))
- return;
-
- if ((s->control >> 2) & 1) { /* RM */
- if ((s->control >> 1) & 1) { /* STP */
- i2c_end_transfer(s->bus);
- s->control &= ~(1 << 1); /* STP */
- s->count_cur = s->count;
- s->txlen = 0;
- } else if ((s->control >> 9) & 1) { /* TRX */
- while (ack && s->txlen)
- ack = (i2c_send(s->bus,
- (s->fifo >> ((-- s->txlen) << 3)) &
- 0xff) >= 0);
- s->stat |= 1 << 4; /* XRDY */
- } else {
- while (s->rxlen < 4)
- s->fifo |= i2c_recv(s->bus) << ((s->rxlen ++) << 3);
- s->stat |= 1 << 3; /* RRDY */
- }
- } else {
- if ((s->control >> 9) & 1) { /* TRX */
- while (ack && s->count_cur && s->txlen) {
- ack = (i2c_send(s->bus,
- (s->fifo >> ((-- s->txlen) << 3)) &
- 0xff) >= 0);
- s->count_cur --;
- }
- if (ack && s->count_cur)
- s->stat |= 1 << 4; /* XRDY */
- else
- s->stat &= ~(1 << 4); /* XRDY */
- if (!s->count_cur) {
- s->stat |= 1 << 2; /* ARDY */
- s->control &= ~(1 << 10); /* MST */
- }
- } else {
- while (s->count_cur && s->rxlen < 4) {
- s->fifo |= i2c_recv(s->bus) << ((s->rxlen ++) << 3);
- s->count_cur --;
- }
- if (s->rxlen)
- s->stat |= 1 << 3; /* RRDY */
- else
- s->stat &= ~(1 << 3); /* RRDY */
- }
- if (!s->count_cur) {
- if ((s->control >> 1) & 1) { /* STP */
- i2c_end_transfer(s->bus);
- s->control &= ~(1 << 1); /* STP */
- s->count_cur = s->count;
- s->txlen = 0;
- } else {
- s->stat |= 1 << 2; /* ARDY */
- s->control &= ~(1 << 10); /* MST */
- }
- }
- }
-
- s->stat |= (!ack) << 1; /* NACK */
- if (!ack)
- s->control &= ~(1 << 1); /* STP */
-}
-
-static void omap_i2c_reset(DeviceState *dev)
-{
- OMAPI2CState *s = OMAP_I2C(dev);
-
- s->mask = 0;
- s->stat = 0;
- s->dma = 0;
- s->count = 0;
- s->count_cur = 0;
- s->fifo = 0;
- s->rxlen = 0;
- s->txlen = 0;
- s->control = 0;
- s->addr[0] = 0;
- s->addr[1] = 0;
- s->divider = 0;
- s->times[0] = 0;
- s->times[1] = 0;
- s->test = 0;
-}
-
-static uint32_t omap_i2c_read(void *opaque, hwaddr addr)
-{
- OMAPI2CState *s = opaque;
- int offset = addr & OMAP_MPUI_REG_MASK;
- uint16_t ret;
-
- switch (offset) {
- case 0x00: /* I2C_REV */
- return s->revision; /* REV */
-
- case 0x04: /* I2C_IE */
- return s->mask;
-
- case 0x08: /* I2C_STAT */
- return s->stat | (i2c_bus_busy(s->bus) << 12);
-
- case 0x0c: /* I2C_IV */
- if (s->revision >= OMAP2_INTR_REV)
- break;
- ret = ctz32(s->stat & s->mask);
- if (ret != 32) {
- s->stat ^= 1 << ret;
- ret++;
- } else {
- ret = 0;
- }
- omap_i2c_interrupts_update(s);
- return ret;
-
- case 0x10: /* I2C_SYSS */
- return (s->control >> 15) & 1; /* I2C_EN */
-
- case 0x14: /* I2C_BUF */
- return s->dma;
-
- case 0x18: /* I2C_CNT */
- return s->count_cur; /* DCOUNT */
-
- case 0x1c: /* I2C_DATA */
- ret = 0;
- if (s->control & (1 << 14)) { /* BE */
- ret |= ((s->fifo >> 0) & 0xff) << 8;
- ret |= ((s->fifo >> 8) & 0xff) << 0;
- } else {
- ret |= ((s->fifo >> 8) & 0xff) << 8;
- ret |= ((s->fifo >> 0) & 0xff) << 0;
- }
- if (s->rxlen == 1) {
- s->stat |= 1 << 15; /* SBD */
- s->rxlen = 0;
- } else if (s->rxlen > 1) {
- if (s->rxlen > 2)
- s->fifo >>= 16;
- s->rxlen -= 2;
- } else {
- /* XXX: remote access (qualifier) error - what's that? */
- }
- if (!s->rxlen) {
- s->stat &= ~(1 << 3); /* RRDY */
- if (((s->control >> 10) & 1) && /* MST */
- ((~s->control >> 9) & 1)) { /* TRX */
- s->stat |= 1 << 2; /* ARDY */
- s->control &= ~(1 << 10); /* MST */
- }
- }
- s->stat &= ~(1 << 11); /* ROVR */
- omap_i2c_fifo_run(s);
- omap_i2c_interrupts_update(s);
- return ret;
-
- case 0x20: /* I2C_SYSC */
- return 0;
-
- case 0x24: /* I2C_CON */
- return s->control;
-
- case 0x28: /* I2C_OA */
- return s->addr[0];
-
- case 0x2c: /* I2C_SA */
- return s->addr[1];
-
- case 0x30: /* I2C_PSC */
- return s->divider;
-
- case 0x34: /* I2C_SCLL */
- return s->times[0];
-
- case 0x38: /* I2C_SCLH */
- return s->times[1];
-
- case 0x3c: /* I2C_SYSTEST */
- if (s->test & (1 << 15)) { /* ST_EN */
- s->test ^= 0xa;
- return s->test;
- } else
- return s->test & ~0x300f;
- }
-
- OMAP_BAD_REG(addr);
- return 0;
-}
-
-static void omap_i2c_write(void *opaque, hwaddr addr,
- uint32_t value)
-{
- OMAPI2CState *s = opaque;
- int offset = addr & OMAP_MPUI_REG_MASK;
- int nack;
-
- switch (offset) {
- case 0x00: /* I2C_REV */
- case 0x0c: /* I2C_IV */
- case 0x10: /* I2C_SYSS */
- OMAP_RO_REG(addr);
- return;
-
- case 0x04: /* I2C_IE */
- s->mask = value & (s->revision < OMAP2_GC_REV ? 0x1f : 0x3f);
- break;
-
- case 0x08: /* I2C_STAT */
- if (s->revision < OMAP2_INTR_REV) {
- OMAP_RO_REG(addr);
- return;
- }
-
- /* RRDY and XRDY are reset by hardware. (in all versions???) */
- s->stat &= ~(value & 0x27);
- omap_i2c_interrupts_update(s);
- break;
-
- case 0x14: /* I2C_BUF */
- s->dma = value & 0x8080;
- if (value & (1 << 15)) /* RDMA_EN */
- s->mask &= ~(1 << 3); /* RRDY_IE */
- if (value & (1 << 7)) /* XDMA_EN */
- s->mask &= ~(1 << 4); /* XRDY_IE */
- break;
-
- case 0x18: /* I2C_CNT */
- s->count = value; /* DCOUNT */
- break;
-
- case 0x1c: /* I2C_DATA */
- if (s->txlen > 2) {
- /* XXX: remote access (qualifier) error - what's that? */
- break;
- }
- s->fifo <<= 16;
- s->txlen += 2;
- if (s->control & (1 << 14)) { /* BE */
- s->fifo |= ((value >> 8) & 0xff) << 8;
- s->fifo |= ((value >> 0) & 0xff) << 0;
- } else {
- s->fifo |= ((value >> 0) & 0xff) << 8;
- s->fifo |= ((value >> 8) & 0xff) << 0;
- }
- s->stat &= ~(1 << 10); /* XUDF */
- if (s->txlen > 2)
- s->stat &= ~(1 << 4); /* XRDY */
- omap_i2c_fifo_run(s);
- omap_i2c_interrupts_update(s);
- break;
-
- case 0x20: /* I2C_SYSC */
- if (s->revision < OMAP2_INTR_REV) {
- OMAP_BAD_REG(addr);
- return;
- }
-
- if (value & 2) {
- omap_i2c_reset(DEVICE(s));
- }
- break;
-
- case 0x24: /* I2C_CON */
- s->control = value & 0xcf87;
- if (~value & (1 << 15)) { /* I2C_EN */
- if (s->revision < OMAP2_INTR_REV) {
- omap_i2c_reset(DEVICE(s));
- }
- break;
- }
- if ((value & (1 << 15)) && !(value & (1 << 10))) { /* MST */
- fprintf(stderr, "%s: I^2C slave mode not supported\n",
- __FUNCTION__);
- break;
- }
- if ((value & (1 << 15)) && value & (1 << 8)) { /* XA */
- fprintf(stderr, "%s: 10-bit addressing mode not supported\n",
- __FUNCTION__);
- break;
- }
- if ((value & (1 << 15)) && value & (1 << 0)) { /* STT */
- nack = !!i2c_start_transfer(s->bus, s->addr[1], /* SA */
- (~value >> 9) & 1); /* TRX */
- s->stat |= nack << 1; /* NACK */
- s->control &= ~(1 << 0); /* STT */
- s->fifo = 0;
- if (nack)
- s->control &= ~(1 << 1); /* STP */
- else {
- s->count_cur = s->count;
- omap_i2c_fifo_run(s);
- }
- omap_i2c_interrupts_update(s);
- }
- break;
-
- case 0x28: /* I2C_OA */
- s->addr[0] = value & 0x3ff;
- break;
-
- case 0x2c: /* I2C_SA */
- s->addr[1] = value & 0x3ff;
- break;
-
- case 0x30: /* I2C_PSC */
- s->divider = value;
- break;
-
- case 0x34: /* I2C_SCLL */
- s->times[0] = value;
- break;
-
- case 0x38: /* I2C_SCLH */
- s->times[1] = value;
- break;
-
- case 0x3c: /* I2C_SYSTEST */
- s->test = value & 0xf80f;
- if (value & (1 << 11)) /* SBB */
- if (s->revision >= OMAP2_INTR_REV) {
- s->stat |= 0x3f;
- omap_i2c_interrupts_update(s);
- }
- if (value & (1 << 15)) /* ST_EN */
- fprintf(stderr, "%s: System Test not supported\n", __FUNCTION__);
- break;
-
- default:
- OMAP_BAD_REG(addr);
- return;
- }
-}
-
-static void omap_i2c_writeb(void *opaque, hwaddr addr,
- uint32_t value)
-{
- OMAPI2CState *s = opaque;
- int offset = addr & OMAP_MPUI_REG_MASK;
-
- switch (offset) {
- case 0x1c: /* I2C_DATA */
- if (s->txlen > 2) {
- /* XXX: remote access (qualifier) error - what's that? */
- break;
- }
- s->fifo <<= 8;
- s->txlen += 1;
- s->fifo |= value & 0xff;
- s->stat &= ~(1 << 10); /* XUDF */
- if (s->txlen > 2)
- s->stat &= ~(1 << 4); /* XRDY */
- omap_i2c_fifo_run(s);
- omap_i2c_interrupts_update(s);
- break;
-
- default:
- OMAP_BAD_REG(addr);
- return;
- }
-}
-
-static const MemoryRegionOps omap_i2c_ops = {
- .old_mmio = {
- .read = {
- omap_badwidth_read16,
- omap_i2c_read,
- omap_badwidth_read16,
- },
- .write = {
- omap_i2c_writeb, /* Only the last fifo write can be 8 bit. */
- omap_i2c_write,
- omap_badwidth_write16,
- },
- },
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static int omap_i2c_init(SysBusDevice *sbd)
-{
- DeviceState *dev = DEVICE(sbd);
- OMAPI2CState *s = OMAP_I2C(dev);
-
- if (!s->fclk) {
- error_report("omap_i2c: fclk not connected");
- return -1;
- }
- if (s->revision >= OMAP2_INTR_REV && !s->iclk) {
- /* Note that OMAP1 doesn't have a separate interface clock */
- error_report("omap_i2c: iclk not connected");
- return -1;
- }
-
- sysbus_init_irq(sbd, &s->irq);
- sysbus_init_irq(sbd, &s->drq[0]);
- sysbus_init_irq(sbd, &s->drq[1]);
- memory_region_init_io(&s->iomem, OBJECT(s), &omap_i2c_ops, s, "omap.i2c",
- (s->revision < OMAP2_INTR_REV) ? 0x800 : 0x1000);
- sysbus_init_mmio(sbd, &s->iomem);
- s->bus = i2c_init_bus(dev, NULL);
- return 0;
-}
-
-static Property omap_i2c_properties[] = {
- DEFINE_PROP_UINT8("revision", OMAPI2CState, revision, 0),
- DEFINE_PROP_PTR("iclk", OMAPI2CState, iclk),
- DEFINE_PROP_PTR("fclk", OMAPI2CState, fclk),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void omap_i2c_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
- k->init = omap_i2c_init;
- dc->props = omap_i2c_properties;
- dc->reset = omap_i2c_reset;
- /* Reason: pointer properties "iclk", "fclk" */
- dc->cannot_instantiate_with_device_add_yet = true;
-}
-
-static const TypeInfo omap_i2c_info = {
- .name = TYPE_OMAP_I2C,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(OMAPI2CState),
- .class_init = omap_i2c_class_init,
-};
-
-static void omap_i2c_register_types(void)
-{
- type_register_static(&omap_i2c_info);
-}
-
-I2CBus *omap_i2c_bus(DeviceState *omap_i2c)
-{
- OMAPI2CState *s = OMAP_I2C(omap_i2c);
- return s->bus;
-}
-
-type_init(omap_i2c_register_types)
diff --git a/qemu/hw/i2c/pm_smbus.c b/qemu/hw/i2c/pm_smbus.c
deleted file mode 100644
index 6fc3923f5..000000000
--- a/qemu/hw/i2c/pm_smbus.c
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * PC SMBus implementation
- * splitted from acpi.c
- *
- * Copyright (c) 2006 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2 as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see
- * <http://www.gnu.org/licenses/>.
- */
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "hw/i386/pc.h"
-#include "hw/i2c/pm_smbus.h"
-#include "hw/i2c/smbus.h"
-
-/* no save/load? */
-
-#define SMBHSTSTS 0x00
-#define SMBHSTCNT 0x02
-#define SMBHSTCMD 0x03
-#define SMBHSTADD 0x04
-#define SMBHSTDAT0 0x05
-#define SMBHSTDAT1 0x06
-#define SMBBLKDAT 0x07
-
-#define STS_HOST_BUSY (1)
-#define STS_INTR (1<<1)
-#define STS_DEV_ERR (1<<2)
-#define STS_BUS_ERR (1<<3)
-#define STS_FAILED (1<<4)
-#define STS_SMBALERT (1<<5)
-#define STS_INUSE_STS (1<<6)
-#define STS_BYTE_DONE (1<<7)
-/* Signs of successfully transaction end :
-* ByteDoneStatus = 1 (STS_BYTE_DONE) and INTR = 1 (STS_INTR )
-*/
-
-//#define DEBUG
-
-#ifdef DEBUG
-# define SMBUS_DPRINTF(format, ...) printf(format, ## __VA_ARGS__)
-#else
-# define SMBUS_DPRINTF(format, ...) do { } while (0)
-#endif
-
-
-static void smb_transaction(PMSMBus *s)
-{
- uint8_t prot = (s->smb_ctl >> 2) & 0x07;
- uint8_t read = s->smb_addr & 0x01;
- uint8_t cmd = s->smb_cmd;
- uint8_t addr = s->smb_addr >> 1;
- I2CBus *bus = s->smbus;
- int ret;
-
- SMBUS_DPRINTF("SMBus trans addr=0x%02x prot=0x%02x\n", addr, prot);
- /* Transaction isn't exec if STS_DEV_ERR bit set */
- if ((s->smb_stat & STS_DEV_ERR) != 0) {
- goto error;
- }
- switch(prot) {
- case 0x0:
- ret = smbus_quick_command(bus, addr, read);
- goto done;
- case 0x1:
- if (read) {
- ret = smbus_receive_byte(bus, addr);
- goto data8;
- } else {
- ret = smbus_send_byte(bus, addr, cmd);
- goto done;
- }
- case 0x2:
- if (read) {
- ret = smbus_read_byte(bus, addr, cmd);
- goto data8;
- } else {
- ret = smbus_write_byte(bus, addr, cmd, s->smb_data0);
- goto done;
- }
- break;
- case 0x3:
- if (read) {
- ret = smbus_read_word(bus, addr, cmd);
- goto data16;
- } else {
- ret = smbus_write_word(bus, addr, cmd, (s->smb_data1 << 8) | s->smb_data0);
- goto done;
- }
- break;
- case 0x5:
- if (read) {
- ret = smbus_read_block(bus, addr, cmd, s->smb_data);
- goto data8;
- } else {
- ret = smbus_write_block(bus, addr, cmd, s->smb_data, s->smb_data0);
- goto done;
- }
- break;
- default:
- goto error;
- }
- abort();
-
-data16:
- if (ret < 0) {
- goto error;
- }
- s->smb_data1 = ret >> 8;
-data8:
- if (ret < 0) {
- goto error;
- }
- s->smb_data0 = ret;
-done:
- if (ret < 0) {
- goto error;
- }
- s->smb_stat |= STS_BYTE_DONE | STS_INTR;
- return;
-
-error:
- s->smb_stat |= STS_DEV_ERR;
- return;
-
-}
-
-static void smb_ioport_writeb(void *opaque, hwaddr addr, uint64_t val,
- unsigned width)
-{
- PMSMBus *s = opaque;
-
- SMBUS_DPRINTF("SMB writeb port=0x%04" HWADDR_PRIx
- " val=0x%02" PRIx64 "\n", addr, val);
- switch(addr) {
- case SMBHSTSTS:
- s->smb_stat = (~(val & 0xff)) & s->smb_stat;
- s->smb_index = 0;
- break;
- case SMBHSTCNT:
- s->smb_ctl = val;
- if (val & 0x40)
- smb_transaction(s);
- break;
- case SMBHSTCMD:
- s->smb_cmd = val;
- break;
- case SMBHSTADD:
- s->smb_addr = val;
- break;
- case SMBHSTDAT0:
- s->smb_data0 = val;
- break;
- case SMBHSTDAT1:
- s->smb_data1 = val;
- break;
- case SMBBLKDAT:
- s->smb_data[s->smb_index++] = val;
- if (s->smb_index > 31)
- s->smb_index = 0;
- break;
- default:
- break;
- }
-}
-
-static uint64_t smb_ioport_readb(void *opaque, hwaddr addr, unsigned width)
-{
- PMSMBus *s = opaque;
- uint32_t val;
-
- switch(addr) {
- case SMBHSTSTS:
- val = s->smb_stat;
- break;
- case SMBHSTCNT:
- s->smb_index = 0;
- val = s->smb_ctl & 0x1f;
- break;
- case SMBHSTCMD:
- val = s->smb_cmd;
- break;
- case SMBHSTADD:
- val = s->smb_addr;
- break;
- case SMBHSTDAT0:
- val = s->smb_data0;
- break;
- case SMBHSTDAT1:
- val = s->smb_data1;
- break;
- case SMBBLKDAT:
- val = s->smb_data[s->smb_index++];
- if (s->smb_index > 31)
- s->smb_index = 0;
- break;
- default:
- val = 0;
- break;
- }
- SMBUS_DPRINTF("SMB readb port=0x%04" HWADDR_PRIx " val=0x%02x\n", addr, val);
- return val;
-}
-
-static const MemoryRegionOps pm_smbus_ops = {
- .read = smb_ioport_readb,
- .write = smb_ioport_writeb,
- .valid.min_access_size = 1,
- .valid.max_access_size = 1,
- .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
-void pm_smbus_init(DeviceState *parent, PMSMBus *smb)
-{
- smb->smbus = i2c_init_bus(parent, "i2c");
- memory_region_init_io(&smb->io, OBJECT(parent), &pm_smbus_ops, smb,
- "pm-smbus", 64);
-}
diff --git a/qemu/hw/i2c/smbus.c b/qemu/hw/i2c/smbus.c
deleted file mode 100644
index 3979b3dad..000000000
--- a/qemu/hw/i2c/smbus.c
+++ /dev/null
@@ -1,362 +0,0 @@
-/*
- * QEMU SMBus device emulation.
- *
- * Copyright (c) 2007 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licensed under the LGPL.
- */
-
-/* TODO: Implement PEC. */
-
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "hw/i2c/i2c.h"
-#include "hw/i2c/smbus.h"
-
-//#define DEBUG_SMBUS 1
-
-#ifdef DEBUG_SMBUS
-#define DPRINTF(fmt, ...) \
-do { printf("smbus(%02x): " fmt , dev->i2c.address, ## __VA_ARGS__); } while (0)
-#define BADF(fmt, ...) \
-do { fprintf(stderr, "smbus: error: " fmt , ## __VA_ARGS__); exit(1);} while (0)
-#else
-#define DPRINTF(fmt, ...) do {} while(0)
-#define BADF(fmt, ...) \
-do { fprintf(stderr, "smbus: error: " fmt , ## __VA_ARGS__);} while (0)
-#endif
-
-enum {
- SMBUS_IDLE,
- SMBUS_WRITE_DATA,
- SMBUS_RECV_BYTE,
- SMBUS_READ_DATA,
- SMBUS_DONE,
- SMBUS_CONFUSED = -1
-};
-
-static void smbus_do_quick_cmd(SMBusDevice *dev, int recv)
-{
- SMBusDeviceClass *sc = SMBUS_DEVICE_GET_CLASS(dev);
-
- DPRINTF("Quick Command %d\n", recv);
- if (sc->quick_cmd) {
- sc->quick_cmd(dev, recv);
- }
-}
-
-static void smbus_do_write(SMBusDevice *dev)
-{
- SMBusDeviceClass *sc = SMBUS_DEVICE_GET_CLASS(dev);
-
- if (dev->data_len == 0) {
- smbus_do_quick_cmd(dev, 0);
- } else if (dev->data_len == 1) {
- DPRINTF("Send Byte\n");
- if (sc->send_byte) {
- sc->send_byte(dev, dev->data_buf[0]);
- }
- } else {
- dev->command = dev->data_buf[0];
- DPRINTF("Command %d len %d\n", dev->command, dev->data_len - 1);
- if (sc->write_data) {
- sc->write_data(dev, dev->command, dev->data_buf + 1,
- dev->data_len - 1);
- }
- }
-}
-
-static void smbus_i2c_event(I2CSlave *s, enum i2c_event event)
-{
- SMBusDevice *dev = SMBUS_DEVICE(s);
-
- switch (event) {
- case I2C_START_SEND:
- switch (dev->mode) {
- case SMBUS_IDLE:
- DPRINTF("Incoming data\n");
- dev->mode = SMBUS_WRITE_DATA;
- break;
- default:
- BADF("Unexpected send start condition in state %d\n", dev->mode);
- dev->mode = SMBUS_CONFUSED;
- break;
- }
- break;
-
- case I2C_START_RECV:
- switch (dev->mode) {
- case SMBUS_IDLE:
- DPRINTF("Read mode\n");
- dev->mode = SMBUS_RECV_BYTE;
- break;
- case SMBUS_WRITE_DATA:
- if (dev->data_len == 0) {
- BADF("Read after write with no data\n");
- dev->mode = SMBUS_CONFUSED;
- } else {
- if (dev->data_len > 1) {
- smbus_do_write(dev);
- } else {
- dev->command = dev->data_buf[0];
- DPRINTF("%02x: Command %d\n", dev->i2c.address,
- dev->command);
- }
- DPRINTF("Read mode\n");
- dev->data_len = 0;
- dev->mode = SMBUS_READ_DATA;
- }
- break;
- default:
- BADF("Unexpected recv start condition in state %d\n", dev->mode);
- dev->mode = SMBUS_CONFUSED;
- break;
- }
- break;
-
- case I2C_FINISH:
- switch (dev->mode) {
- case SMBUS_WRITE_DATA:
- smbus_do_write(dev);
- break;
- case SMBUS_RECV_BYTE:
- smbus_do_quick_cmd(dev, 1);
- break;
- case SMBUS_READ_DATA:
- BADF("Unexpected stop during receive\n");
- break;
- default:
- /* Nothing to do. */
- break;
- }
- dev->mode = SMBUS_IDLE;
- dev->data_len = 0;
- break;
-
- case I2C_NACK:
- switch (dev->mode) {
- case SMBUS_DONE:
- /* Nothing to do. */
- break;
- case SMBUS_READ_DATA:
- dev->mode = SMBUS_DONE;
- break;
- default:
- BADF("Unexpected NACK in state %d\n", dev->mode);
- dev->mode = SMBUS_CONFUSED;
- break;
- }
- }
-}
-
-static int smbus_i2c_recv(I2CSlave *s)
-{
- SMBusDevice *dev = SMBUS_DEVICE(s);
- SMBusDeviceClass *sc = SMBUS_DEVICE_GET_CLASS(dev);
- int ret;
-
- switch (dev->mode) {
- case SMBUS_RECV_BYTE:
- if (sc->receive_byte) {
- ret = sc->receive_byte(dev);
- } else {
- ret = 0;
- }
- DPRINTF("Receive Byte %02x\n", ret);
- dev->mode = SMBUS_DONE;
- break;
- case SMBUS_READ_DATA:
- if (sc->read_data) {
- ret = sc->read_data(dev, dev->command, dev->data_len);
- dev->data_len++;
- } else {
- ret = 0;
- }
- DPRINTF("Read data %02x\n", ret);
- break;
- default:
- BADF("Unexpected read in state %d\n", dev->mode);
- dev->mode = SMBUS_CONFUSED;
- ret = 0;
- break;
- }
- return ret;
-}
-
-static int smbus_i2c_send(I2CSlave *s, uint8_t data)
-{
- SMBusDevice *dev = SMBUS_DEVICE(s);
-
- switch (dev->mode) {
- case SMBUS_WRITE_DATA:
- DPRINTF("Write data %02x\n", data);
- dev->data_buf[dev->data_len++] = data;
- break;
- default:
- BADF("Unexpected write in state %d\n", dev->mode);
- break;
- }
- return 0;
-}
-
-static int smbus_device_init(I2CSlave *i2c)
-{
- SMBusDevice *dev = SMBUS_DEVICE(i2c);
- SMBusDeviceClass *sc = SMBUS_DEVICE_GET_CLASS(dev);
-
- return sc->init(dev);
-}
-
-/* Master device commands. */
-int smbus_quick_command(I2CBus *bus, uint8_t addr, int read)
-{
- if (i2c_start_transfer(bus, addr, read)) {
- return -1;
- }
- i2c_end_transfer(bus);
- return 0;
-}
-
-int smbus_receive_byte(I2CBus *bus, uint8_t addr)
-{
- uint8_t data;
-
- if (i2c_start_transfer(bus, addr, 1)) {
- return -1;
- }
- data = i2c_recv(bus);
- i2c_nack(bus);
- i2c_end_transfer(bus);
- return data;
-}
-
-int smbus_send_byte(I2CBus *bus, uint8_t addr, uint8_t data)
-{
- if (i2c_start_transfer(bus, addr, 0)) {
- return -1;
- }
- i2c_send(bus, data);
- i2c_end_transfer(bus);
- return 0;
-}
-
-int smbus_read_byte(I2CBus *bus, uint8_t addr, uint8_t command)
-{
- uint8_t data;
- if (i2c_start_transfer(bus, addr, 0)) {
- return -1;
- }
- i2c_send(bus, command);
- i2c_start_transfer(bus, addr, 1);
- data = i2c_recv(bus);
- i2c_nack(bus);
- i2c_end_transfer(bus);
- return data;
-}
-
-int smbus_write_byte(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t data)
-{
- if (i2c_start_transfer(bus, addr, 0)) {
- return -1;
- }
- i2c_send(bus, command);
- i2c_send(bus, data);
- i2c_end_transfer(bus);
- return 0;
-}
-
-int smbus_read_word(I2CBus *bus, uint8_t addr, uint8_t command)
-{
- uint16_t data;
- if (i2c_start_transfer(bus, addr, 0)) {
- return -1;
- }
- i2c_send(bus, command);
- i2c_start_transfer(bus, addr, 1);
- data = i2c_recv(bus);
- data |= i2c_recv(bus) << 8;
- i2c_nack(bus);
- i2c_end_transfer(bus);
- return data;
-}
-
-int smbus_write_word(I2CBus *bus, uint8_t addr, uint8_t command, uint16_t data)
-{
- if (i2c_start_transfer(bus, addr, 0)) {
- return -1;
- }
- i2c_send(bus, command);
- i2c_send(bus, data & 0xff);
- i2c_send(bus, data >> 8);
- i2c_end_transfer(bus);
- return 0;
-}
-
-int smbus_read_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data)
-{
- int len;
- int i;
-
- if (i2c_start_transfer(bus, addr, 0)) {
- return -1;
- }
- i2c_send(bus, command);
- i2c_start_transfer(bus, addr, 1);
- len = i2c_recv(bus);
- if (len > 32) {
- len = 0;
- }
- for (i = 0; i < len; i++) {
- data[i] = i2c_recv(bus);
- }
- i2c_nack(bus);
- i2c_end_transfer(bus);
- return len;
-}
-
-int smbus_write_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data,
- int len)
-{
- int i;
-
- if (len > 32)
- len = 32;
-
- if (i2c_start_transfer(bus, addr, 0)) {
- return -1;
- }
- i2c_send(bus, command);
- i2c_send(bus, len);
- for (i = 0; i < len; i++) {
- i2c_send(bus, data[i]);
- }
- i2c_end_transfer(bus);
- return 0;
-}
-
-static void smbus_device_class_init(ObjectClass *klass, void *data)
-{
- I2CSlaveClass *sc = I2C_SLAVE_CLASS(klass);
-
- sc->init = smbus_device_init;
- sc->event = smbus_i2c_event;
- sc->recv = smbus_i2c_recv;
- sc->send = smbus_i2c_send;
-}
-
-static const TypeInfo smbus_device_type_info = {
- .name = TYPE_SMBUS_DEVICE,
- .parent = TYPE_I2C_SLAVE,
- .instance_size = sizeof(SMBusDevice),
- .abstract = true,
- .class_size = sizeof(SMBusDeviceClass),
- .class_init = smbus_device_class_init,
-};
-
-static void smbus_device_register_types(void)
-{
- type_register_static(&smbus_device_type_info);
-}
-
-type_init(smbus_device_register_types)
diff --git a/qemu/hw/i2c/smbus_eeprom.c b/qemu/hw/i2c/smbus_eeprom.c
deleted file mode 100644
index 5b7bd891b..000000000
--- a/qemu/hw/i2c/smbus_eeprom.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * QEMU SMBus EEPROM device
- *
- * Copyright (c) 2007 Arastra, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "hw/i2c/i2c.h"
-#include "hw/i2c/smbus.h"
-
-//#define DEBUG
-
-typedef struct SMBusEEPROMDevice {
- SMBusDevice smbusdev;
- void *data;
- uint8_t offset;
-} SMBusEEPROMDevice;
-
-static void eeprom_quick_cmd(SMBusDevice *dev, uint8_t read)
-{
-#ifdef DEBUG
- printf("eeprom_quick_cmd: addr=0x%02x read=%d\n", dev->i2c.address, read);
-#endif
-}
-
-static void eeprom_send_byte(SMBusDevice *dev, uint8_t val)
-{
- SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *) dev;
-#ifdef DEBUG
- printf("eeprom_send_byte: addr=0x%02x val=0x%02x\n",
- dev->i2c.address, val);
-#endif
- eeprom->offset = val;
-}
-
-static uint8_t eeprom_receive_byte(SMBusDevice *dev)
-{
- SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *) dev;
- uint8_t *data = eeprom->data;
- uint8_t val = data[eeprom->offset++];
-#ifdef DEBUG
- printf("eeprom_receive_byte: addr=0x%02x val=0x%02x\n",
- dev->i2c.address, val);
-#endif
- return val;
-}
-
-static void eeprom_write_data(SMBusDevice *dev, uint8_t cmd, uint8_t *buf, int len)
-{
- SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *) dev;
- int n;
-#ifdef DEBUG
- printf("eeprom_write_byte: addr=0x%02x cmd=0x%02x val=0x%02x\n",
- dev->i2c.address, cmd, buf[0]);
-#endif
- /* A page write operation is not a valid SMBus command.
- It is a block write without a length byte. Fortunately we
- get the full block anyway. */
- /* TODO: Should this set the current location? */
- if (cmd + len > 256)
- n = 256 - cmd;
- else
- n = len;
- memcpy(eeprom->data + cmd, buf, n);
- len -= n;
- if (len)
- memcpy(eeprom->data, buf + n, len);
-}
-
-static uint8_t eeprom_read_data(SMBusDevice *dev, uint8_t cmd, int n)
-{
- SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *) dev;
- /* If this is the first byte then set the current position. */
- if (n == 0)
- eeprom->offset = cmd;
- /* As with writes, we implement block reads without the
- SMBus length byte. */
- return eeprom_receive_byte(dev);
-}
-
-static int smbus_eeprom_initfn(SMBusDevice *dev)
-{
- SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *)dev;
-
- eeprom->offset = 0;
- return 0;
-}
-
-static Property smbus_eeprom_properties[] = {
- DEFINE_PROP_PTR("data", SMBusEEPROMDevice, data),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void smbus_eeprom_class_initfn(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SMBusDeviceClass *sc = SMBUS_DEVICE_CLASS(klass);
-
- sc->init = smbus_eeprom_initfn;
- sc->quick_cmd = eeprom_quick_cmd;
- sc->send_byte = eeprom_send_byte;
- sc->receive_byte = eeprom_receive_byte;
- sc->write_data = eeprom_write_data;
- sc->read_data = eeprom_read_data;
- dc->props = smbus_eeprom_properties;
- /* Reason: pointer property "data" */
- dc->cannot_instantiate_with_device_add_yet = true;
-}
-
-static const TypeInfo smbus_eeprom_info = {
- .name = "smbus-eeprom",
- .parent = TYPE_SMBUS_DEVICE,
- .instance_size = sizeof(SMBusEEPROMDevice),
- .class_init = smbus_eeprom_class_initfn,
-};
-
-static void smbus_eeprom_register_types(void)
-{
- type_register_static(&smbus_eeprom_info);
-}
-
-type_init(smbus_eeprom_register_types)
-
-void smbus_eeprom_init(I2CBus *smbus, int nb_eeprom,
- const uint8_t *eeprom_spd, int eeprom_spd_size)
-{
- int i;
- uint8_t *eeprom_buf = g_malloc0(8 * 256); /* XXX: make this persistent */
- if (eeprom_spd_size > 0) {
- memcpy(eeprom_buf, eeprom_spd, eeprom_spd_size);
- }
-
- for (i = 0; i < nb_eeprom; i++) {
- DeviceState *eeprom;
- eeprom = qdev_create((BusState *)smbus, "smbus-eeprom");
- qdev_prop_set_uint8(eeprom, "address", 0x50 + i);
- qdev_prop_set_ptr(eeprom, "data", eeprom_buf + (i * 256));
- qdev_init_nofail(eeprom);
- }
-}
diff --git a/qemu/hw/i2c/smbus_ich9.c b/qemu/hw/i2c/smbus_ich9.c
deleted file mode 100644
index 498f03e83..000000000
--- a/qemu/hw/i2c/smbus_ich9.c
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * ACPI implementation
- *
- * Copyright (c) 2006 Fabrice Bellard
- * Copyright (c) 2009 Isaku Yamahata <yamahata at valinux co jp>
- * VA Linux Systems Japan K.K.
- * Copyright (C) 2012 Jason Baron <jbaron@redhat.com>
- *
- * This is based on acpi.c, but heavily rewritten.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2 as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>
- *
- * Contributions after 2012-01-13 are licensed under the terms of the
- * GNU GPL, version 2 or (at your option) any later version.
- *
- */
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "hw/i386/pc.h"
-#include "hw/i2c/pm_smbus.h"
-#include "hw/pci/pci.h"
-#include "sysemu/sysemu.h"
-#include "hw/i2c/i2c.h"
-#include "hw/i2c/smbus.h"
-
-#include "hw/i386/ich9.h"
-
-#define TYPE_ICH9_SMB_DEVICE "ICH9 SMB"
-#define ICH9_SMB_DEVICE(obj) \
- OBJECT_CHECK(ICH9SMBState, (obj), TYPE_ICH9_SMB_DEVICE)
-
-typedef struct ICH9SMBState {
- PCIDevice dev;
-
- PMSMBus smb;
-} ICH9SMBState;
-
-static const VMStateDescription vmstate_ich9_smbus = {
- .name = "ich9_smb",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_PCI_DEVICE(dev, struct ICH9SMBState),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static void ich9_smbus_write_config(PCIDevice *d, uint32_t address,
- uint32_t val, int len)
-{
- ICH9SMBState *s = ICH9_SMB_DEVICE(d);
-
- pci_default_write_config(d, address, val, len);
- if (range_covers_byte(address, len, ICH9_SMB_HOSTC)) {
- uint8_t hostc = s->dev.config[ICH9_SMB_HOSTC];
- if ((hostc & ICH9_SMB_HOSTC_HST_EN) &&
- !(hostc & ICH9_SMB_HOSTC_I2C_EN)) {
- memory_region_set_enabled(&s->smb.io, true);
- } else {
- memory_region_set_enabled(&s->smb.io, false);
- }
- }
-}
-
-static void ich9_smbus_realize(PCIDevice *d, Error **errp)
-{
- ICH9SMBState *s = ICH9_SMB_DEVICE(d);
-
- /* TODO? D31IP.SMIP in chipset configuration space */
- pci_config_set_interrupt_pin(d->config, 0x01); /* interrupt pin 1 */
-
- pci_set_byte(d->config + ICH9_SMB_HOSTC, 0);
- /* TODO bar0, bar1: 64bit BAR support*/
-
- pm_smbus_init(&d->qdev, &s->smb);
- pci_register_bar(d, ICH9_SMB_SMB_BASE_BAR, PCI_BASE_ADDRESS_SPACE_IO,
- &s->smb.io);
-}
-
-static void ich9_smb_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-
- k->vendor_id = PCI_VENDOR_ID_INTEL;
- k->device_id = PCI_DEVICE_ID_INTEL_ICH9_6;
- k->revision = ICH9_A2_SMB_REVISION;
- k->class_id = PCI_CLASS_SERIAL_SMBUS;
- dc->vmsd = &vmstate_ich9_smbus;
- dc->desc = "ICH9 SMBUS Bridge";
- k->realize = ich9_smbus_realize;
- k->config_write = ich9_smbus_write_config;
- /*
- * Reason: part of ICH9 southbridge, needs to be wired up by
- * pc_q35_init()
- */
- dc->cannot_instantiate_with_device_add_yet = true;
-}
-
-I2CBus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base)
-{
- PCIDevice *d =
- pci_create_simple_multifunction(bus, devfn, true, TYPE_ICH9_SMB_DEVICE);
- ICH9SMBState *s = ICH9_SMB_DEVICE(d);
- return s->smb.smbus;
-}
-
-static const TypeInfo ich9_smb_info = {
- .name = TYPE_ICH9_SMB_DEVICE,
- .parent = TYPE_PCI_DEVICE,
- .instance_size = sizeof(ICH9SMBState),
- .class_init = ich9_smb_class_init,
-};
-
-static void ich9_smb_register(void)
-{
- type_register_static(&ich9_smb_info);
-}
-
-type_init(ich9_smb_register);
diff --git a/qemu/hw/i2c/versatile_i2c.c b/qemu/hw/i2c/versatile_i2c.c
deleted file mode 100644
index fee3bc761..000000000
--- a/qemu/hw/i2c/versatile_i2c.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * ARM Versatile I2C controller
- *
- * Copyright (c) 2006-2007 CodeSourcery.
- * Copyright (c) 2012 Oskar Andero <oskar.andero@gmail.com>
- *
- * This file is derived from hw/realview.c by Paul Brook
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "qemu/osdep.h"
-#include "hw/sysbus.h"
-#include "bitbang_i2c.h"
-
-#define TYPE_VERSATILE_I2C "versatile_i2c"
-#define VERSATILE_I2C(obj) \
- OBJECT_CHECK(VersatileI2CState, (obj), TYPE_VERSATILE_I2C)
-
-typedef struct VersatileI2CState {
- SysBusDevice parent_obj;
-
- MemoryRegion iomem;
- bitbang_i2c_interface *bitbang;
- int out;
- int in;
-} VersatileI2CState;
-
-static uint64_t versatile_i2c_read(void *opaque, hwaddr offset,
- unsigned size)
-{
- VersatileI2CState *s = (VersatileI2CState *)opaque;
-
- if (offset == 0) {
- return (s->out & 1) | (s->in << 1);
- } else {
- qemu_log_mask(LOG_GUEST_ERROR,
- "%s: Bad offset 0x%x\n", __func__, (int)offset);
- return -1;
- }
-}
-
-static void versatile_i2c_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
-{
- VersatileI2CState *s = (VersatileI2CState *)opaque;
-
- switch (offset) {
- case 0:
- s->out |= value & 3;
- break;
- case 4:
- s->out &= ~value;
- break;
- default:
- qemu_log_mask(LOG_GUEST_ERROR,
- "%s: Bad offset 0x%x\n", __func__, (int)offset);
- }
- bitbang_i2c_set(s->bitbang, BITBANG_I2C_SCL, (s->out & 1) != 0);
- s->in = bitbang_i2c_set(s->bitbang, BITBANG_I2C_SDA, (s->out & 2) != 0);
-}
-
-static const MemoryRegionOps versatile_i2c_ops = {
- .read = versatile_i2c_read,
- .write = versatile_i2c_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static int versatile_i2c_init(SysBusDevice *sbd)
-{
- DeviceState *dev = DEVICE(sbd);
- VersatileI2CState *s = VERSATILE_I2C(dev);
- I2CBus *bus;
-
- bus = i2c_init_bus(dev, "i2c");
- s->bitbang = bitbang_i2c_init(bus);
- memory_region_init_io(&s->iomem, OBJECT(s), &versatile_i2c_ops, s,
- "versatile_i2c", 0x1000);
- sysbus_init_mmio(sbd, &s->iomem);
- return 0;
-}
-
-static void versatile_i2c_class_init(ObjectClass *klass, void *data)
-{
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
- k->init = versatile_i2c_init;
-}
-
-static const TypeInfo versatile_i2c_info = {
- .name = TYPE_VERSATILE_I2C,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(VersatileI2CState),
- .class_init = versatile_i2c_class_init,
-};
-
-static void versatile_i2c_register_types(void)
-{
- type_register_static(&versatile_i2c_info);
-}
-
-type_init(versatile_i2c_register_types)