From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MBmsC-0000ZT-Ns for qemu-devel@nongnu.org; Wed, 03 Jun 2009 05:35:04 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MBms7-0000YR-Lo for qemu-devel@nongnu.org; Wed, 03 Jun 2009 05:35:03 -0400 Received: from [199.232.76.173] (port=50554 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MBms7-0000YG-3n for qemu-devel@nongnu.org; Wed, 03 Jun 2009 05:34:59 -0400 Received: from mail-fx0-f219.google.com ([209.85.220.219]:55868) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1MBms6-0001f7-7F for qemu-devel@nongnu.org; Wed, 03 Jun 2009 05:34:58 -0400 Received: by fxm19 with SMTP id 19so7998646fxm.34 for ; Wed, 03 Jun 2009 02:34:57 -0700 (PDT) From: Benoit Canet Date: Wed, 3 Jun 2009 11:34:42 +0200 Message-Id: <1244021682-11125-3-git-send-email-benoit.canet@gmail.com> In-Reply-To: <1244021682-11125-2-git-send-email-benoit.canet@gmail.com> References: <1244021682-11125-1-git-send-email-benoit.canet@gmail.com> <1244021682-11125-2-git-send-email-benoit.canet@gmail.com> Subject: [Qemu-devel] [PATCH 2/2] Add ARM versatile I2C emulation List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Benoit canet From: Benoit canet Signed-off-by: Benoit Canet --- 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 + * + * 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 + * + * 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