qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 2/2] Add ARM versatile I2C emulation


From: Benoit Canet
Subject: [Qemu-devel] [PATCH 2/2] Add ARM versatile I2C emulation
Date: Wed, 3 Jun 2009 11:34:42 +0200

From: Benoit canet <address@hidden>


Signed-off-by: Benoit Canet <address@hidden>
---
 Makefile.target    |    1 +
 hw/versatile_i2c.c |   88 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/versatile_i2c.h |   15 +++++++++
 hw/versatilepb.c   |    5 +++
 4 files changed, 109 insertions(+), 0 deletions(-)
 create mode 100644 hw/versatile_i2c.c
 create mode 100644 hw/versatile_i2c.h

diff --git a/Makefile.target b/Makefile.target
index d049a73..fa7efed 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -657,6 +657,7 @@ ifeq ($(TARGET_BASE_ARCH), arm)
 OBJS+= integratorcp.o versatilepb.o smc91c111.o arm_pic.o arm_timer.o
 OBJS+= arm_boot.o pl011.o pl031.o pl050.o pl080.o pl110.o pl181.o pl190.o
 OBJS+= versatile_pci.o
+OBJS+= versatile_i2c.o
 OBJS+= realview_gic.o realview.o arm_sysctl.o mpcore.o
 OBJS+= armv7m.o armv7m_nvic.o stellaris.o pl022.o stellaris_enet.o
 OBJS+= pl061.o
diff --git a/hw/versatile_i2c.c b/hw/versatile_i2c.c
new file mode 100644
index 0000000..c905562
--- /dev/null
+++ b/hw/versatile_i2c.c
@@ -0,0 +1,88 @@
+/*
+ * Arm versatile i2c interface
+ *
+ * Copyright (c) 2009 Benoît Canet
+ *      Benoît Canet <address@hidden>
+ *
+ * This code is licenced under the GPL.
+ */
+#include "hw.h"
+#include "smbus.h"
+#include "i2c.h"
+#include "bitbang_i2c.h"
+#include "versatile_i2c.h"
+
+#define I2C_CONTROL   0x0
+#define I2C_CONTROLS  0x0
+#define I2C_CONTROLC  0x4
+
+#define DATA    1<<1
+#define CLOCK   1
+
+static uint32_t versatile_i2c_read(void *opaque, target_phys_addr_t offset)
+{
+    bitbang_i2c_interface *i2c = (bitbang_i2c_interface *) opaque;
+
+    switch (offset) {
+    case I2C_CONTROL:
+        return (bitbang_i2c_get_data(i2c) << 1) | i2c->last_clock;
+    default:
+        hw_error("versatile_i2c_read: Bad offset %x\n", (int)offset);
+        return 0;
+    }
+}
+
+static void versatile_i2c_write(void *opaque, target_phys_addr_t offset,
+                        uint32_t value)
+{
+    bitbang_i2c_interface *i2c = (bitbang_i2c_interface *) opaque;
+    int data  = i2c->last_data;
+    int clock = i2c->last_clock;
+
+    switch (offset) {
+    case I2C_CONTROLS:
+        if (value & DATA)
+            data = 1;
+        if (value & CLOCK)
+            clock = 1;
+        break;
+    case I2C_CONTROLC:
+        if (value & DATA)
+            data = 0;
+        if (value & CLOCK)
+            clock = 0;
+        break;
+    default:
+        hw_error("versatile_i2c_write: Bad offset %x\n", (int)offset);
+    }
+
+    bitbang_i2c_state_update(i2c, data, clock);
+}
+
+static CPUReadMemoryFunc *versatile_i2c_readfn[] = {
+   versatile_i2c_read,
+   versatile_i2c_read,
+   versatile_i2c_read
+};
+
+static CPUWriteMemoryFunc *versatile_i2c_writefn[] = {
+   versatile_i2c_write,
+   versatile_i2c_write,
+   versatile_i2c_write
+};
+
+i2c_bus *versatile_i2c_init(uint32_t base)
+{
+    int iomemtype;
+    bitbang_i2c_interface *i2c;
+
+    i2c = qemu_mallocz(sizeof(bitbang_i2c_interface));
+    i2c->bus = i2c_init_bus(NULL, "i2c");
+    i2c->current_addr = -1;
+
+    iomemtype = cpu_register_io_memory(0, versatile_i2c_readfn,
+                                       versatile_i2c_writefn, i2c);
+    cpu_register_physical_memory(base, 0x00001000, iomemtype);
+
+    return i2c->bus;
+}
diff --git a/hw/versatile_i2c.h b/hw/versatile_i2c.h
new file mode 100644
index 0000000..41f8a01
--- /dev/null
+++ b/hw/versatile_i2c.h
@@ -0,0 +1,15 @@
+/*
+ * Arm versatile i2c interface
+ *
+ * Copyright (c) 2009 Benoît Canet
+ *      Benoît Canet <address@hidden>
+ *
+ * This code is licenced under the GPL.
+ */
+#ifndef I2C_VERSATILE_H
+#define I2C_VERSATILE_H
+#include "i2c.h"
+
+i2c_bus *versatile_i2c_init(uint32_t base);
+
+#endif
diff --git a/hw/versatilepb.c b/hw/versatilepb.c
index 03cf4d8..4f924be 100644
--- a/hw/versatilepb.c
+++ b/hw/versatilepb.c
@@ -9,6 +9,8 @@
 
 #include "sysbus.h"
 #include "arm-misc.h"
+#include "i2c.h"
+#include "versatile_i2c.h"
 #include "primecell.h"
 #include "devices.h"
 #include "net.h"
@@ -170,6 +172,7 @@ static void versatile_init(ram_addr_t ram_size,
     NICInfo *nd;
     int n;
     int done_smc = 0;
+    i2c_bus *i2c;
 
     if (!cpu_model)
         cpu_model = "arm926";
@@ -224,6 +227,8 @@ static void versatile_init(ram_addr_t ram_size,
         n--;
     }
 
+    i2c = versatile_i2c_init(0x10002000);
+
     sysbus_create_simple("pl011", 0x101f1000, pic[12]);
     sysbus_create_simple("pl011", 0x101f2000, pic[13]);
     sysbus_create_simple("pl011", 0x101f3000, pic[14]);
-- 
1.5.6.3





reply via email to

[Prev in Thread] Current Thread [Next in Thread]