Patchwork [v1,6/6] xilinx_zynq: Add i2c components

login
register
mail settings
Submitter Peter Crosthwaite
Date Feb. 20, 2013, 5:29 a.m.
Message ID <e51bc13f345f2186772a8f6574bcb5a0ef2e5b9c.1361337686.git.peter.crosthwaite@xilinx.com>
Download mbox | patch
Permalink /patch/221953/
State New
Headers show

Comments

Peter Crosthwaite - Feb. 20, 2013, 5:29 a.m.
Add the I2C controllers/switches and EEPROMs attached to Zynq boards.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
---

 hw/xilinx_zynq.c |   30 ++++++++++++++++++++++++++++++
 1 files changed, 30 insertions(+), 0 deletions(-)

Patch

diff --git a/hw/xilinx_zynq.c b/hw/xilinx_zynq.c
index 311f791..2608015 100644
--- a/hw/xilinx_zynq.c
+++ b/hw/xilinx_zynq.c
@@ -25,6 +25,7 @@ 
 #include "sysemu/blockdev.h"
 #include "loader.h"
 #include "ssi.h"
+#include "i2c.h"
 
 #define NUM_SPI_FLASHES 4
 #define NUM_QSPI_FLASHES 2
@@ -33,6 +34,8 @@ 
 #define FLASH_SIZE (64 * 1024 * 1024)
 #define FLASH_SECTOR_SIZE (128 * 1024)
 
+#define NUM_I2C_EEPROMS 2
+
 #define IRQ_OFFSET 32 /* pic interrupts start from index 32 */
 
 static struct arm_boot_info zynq_binfo = {};
@@ -93,6 +96,30 @@  static inline void zynq_init_spi_flashes(uint32_t base_addr, qemu_irq irq,
 
 }
 
+static inline void zynq_init_zc70x_i2c(uint32_t base_addr, qemu_irq irq)
+{
+    DeviceState *dev = sysbus_create_simple("cadence.i2c", base_addr, irq);
+    i2c_bus *i2c = (i2c_bus *)qdev_get_child_bus(dev, "i2c");
+    int i, bus;
+
+    dev = i2c_create_slave(i2c, "pca9548", 0);
+    for (bus = 2; bus <= 3; bus++) {
+        char bus_name[16];
+
+        snprintf(bus_name, sizeof(bus_name), "i2c%d", bus);
+        i2c = (i2c_bus *)qdev_get_child_bus(dev, bus_name);
+        assert(i2c);
+
+        assert(NUM_I2C_EEPROMS <= 2); /* not enough address space for anymore */
+        for (i = 0; i < NUM_I2C_EEPROMS; ++i) {
+            DeviceState *eeprom_dev = i2c_create_slave_no_init(i2c, "m24cxx",
+                                                               0x50 + 0x4 * i);
+            qdev_prop_set_uint16(eeprom_dev, "size", 1024); /* M24C08 */
+            qdev_init_nofail(eeprom_dev);
+        }
+    }
+}
+
 static void zynq_init(QEMUMachineInitArgs *args)
 {
     ram_addr_t ram_size = args->ram_size;
@@ -163,6 +190,9 @@  static void zynq_init(QEMUMachineInitArgs *args)
         pic[n] = qdev_get_gpio_in(dev, n);
     }
 
+    zynq_init_zc70x_i2c(0xE0004000, pic[57-IRQ_OFFSET]);
+    zynq_init_zc70x_i2c(0xE0005000, pic[80-IRQ_OFFSET]);
+
     zynq_init_spi_flashes(0xE0006000, pic[58-IRQ_OFFSET], false);
     zynq_init_spi_flashes(0xE0007000, pic[81-IRQ_OFFSET], false);
     zynq_init_spi_flashes(0xE000D000, pic[51-IRQ_OFFSET], true);