[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH] versatilepb: add i2c support
From: |
Oskar Andero |
Subject: |
[Qemu-devel] [PATCH] versatilepb: add i2c support |
Date: |
Mon, 2 Apr 2012 22:17:17 +0200 |
Signed-off-by: Oskar Andero <address@hidden>
---
hw/versatilepb.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 80 insertions(+), 0 deletions(-)
diff --git a/hw/versatilepb.c b/hw/versatilepb.c
index 25afb1e..014621a 100644
--- a/hw/versatilepb.c
+++ b/hw/versatilepb.c
@@ -16,9 +16,18 @@
#include "boards.h"
#include "blockdev.h"
#include "exec-memory.h"
+#include "bitbang_i2c.h"
/* Primary interrupt controller. */
+typedef struct {
+ SysBusDevice busdev;
+ MemoryRegion iomem;
+ bitbang_i2c_interface *bitbang;
+ int out;
+ int in;
+} vpb_i2c_state;
+
typedef struct vpb_sic_state
{
SysBusDevice busdev;
@@ -153,6 +162,64 @@ static int vpb_sic_init(SysBusDevice *dev)
return 0;
}
+static uint64_t vpb_i2c_read(void *opaque, target_phys_addr_t offset,
+ unsigned size)
+{
+ vpb_i2c_state *s = (vpb_i2c_state *)opaque;
+
+ if (offset == 0) {
+ return (s->out & 1) | (s->in << 1);
+ } else {
+ hw_error("%s: Bad offset 0x%x\n", __func__, (int)offset);
+ return -1;
+ }
+}
+
+static void vpb_i2c_write(void *opaque, target_phys_addr_t offset,
+ uint64_t value, unsigned size)
+{
+ vpb_i2c_state *s = (vpb_i2c_state *)opaque;
+
+ switch (offset) {
+ case 0:
+ s->out |= value & 3;
+ break;
+ case 4:
+ s->out &= ~value;
+ break;
+ default:
+ hw_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 vpb_i2c_ops = {
+ .read = vpb_i2c_read,
+ .write = vpb_i2c_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static int vpb_i2c_init(SysBusDevice *dev)
+{
+ vpb_i2c_state *s = FROM_SYSBUS(vpb_i2c_state, dev);
+ i2c_bus *bus;
+
+ bus = i2c_init_bus(&dev->qdev, "i2c");
+ s->bitbang = bitbang_i2c_init(bus);
+ memory_region_init_io(&s->iomem, &vpb_i2c_ops, s,
+ "vpb-i2c", 0x1000);
+ sysbus_init_mmio(dev, &s->iomem);
+ return 0;
+}
+
+static void vpb_i2c_class_init(ObjectClass *klass, void *data)
+{
+ SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+ k->init = vpb_i2c_init;
+}
+
/* Board init. */
/* The AB and PB boards both use the same core, just with different
@@ -177,6 +244,7 @@ static void versatile_init(ram_addr_t ram_size,
SysBusDevice *busdev;
DeviceState *pl041;
PCIBus *pci_bus;
+ i2c_bus *i2c;
NICInfo *nd;
int n;
int done_smc = 0;
@@ -268,6 +336,10 @@ static void versatile_init(ram_addr_t ram_size,
/* Add PL031 Real Time Clock. */
sysbus_create_simple("pl031", 0x101e8000, pic[10]);
+ dev = sysbus_create_simple("vpb_i2c", 0x10002000, NULL);
+ i2c = (i2c_bus *)qdev_get_child_bus(dev, "i2c");
+ i2c_create_slave(i2c, "ds1338", 0x68);
+
/* Add PL041 AACI Interface to the LM4549 codec */
pl041 = qdev_create(NULL, "pl041");
qdev_prop_set_uint32(pl041, "nc_fifo_depth", 512);
@@ -380,9 +452,17 @@ static TypeInfo vpb_sic_info = {
.class_init = vpb_sic_class_init,
};
+static TypeInfo vpb_i2c_info = {
+ .name = "vpb_i2c",
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(vpb_i2c_state),
+ .class_init = vpb_i2c_class_init,
+};
+
static void versatilepb_register_types(void)
{
type_register_static(&vpb_sic_info);
+ type_register_static(&vpb_i2c_info);
}
type_init(versatilepb_register_types)
--
1.7.3.4
- [Qemu-devel] [PATCH] versatilepb: add i2c support,
Oskar Andero <=