qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH 2/2] usb-ehci: add Faraday FUSBH200 support


From: Kuo-Jung Su
Subject: [Qemu-devel] [PATCH 2/2] usb-ehci: add Faraday FUSBH200 support
Date: Tue, 29 Jan 2013 13:43:54 +0800

From: Kuo-Jung Su <address@hidden>

Add Faraday FUSBH200 support, which is slightly different from EHCI spec.
(Or maybe simply a bad/wrong implementation...)

Signed-off-by: Kuo-Jung Su <address@hidden>
Cc: Gerd Hoffmann <address@hidden>
Cc: Andreas <address@hidden>
Cc: Peter Crosthwaite <address@hidden>
---
 hw/usb/hcd-ehci-sysbus.c |   66 ++++++++++++++++++++++++++++++++++++++++++++++
 hw/usb/hcd-ehci.h        |    5 ++++
 2 files changed, 71 insertions(+)

diff --git a/hw/usb/hcd-ehci-sysbus.c b/hw/usb/hcd-ehci-sysbus.c
index ae2db1a..404a227 100644
--- a/hw/usb/hcd-ehci-sysbus.c
+++ b/hw/usb/hcd-ehci-sysbus.c
@@ -17,6 +17,49 @@
 
 #include "hw/usb/hcd-ehci.h"
 
+/*
+ * Faraday FUSBH200 USB 2.0 EHCI
+ */
+
+static uint64_t
+ehci_fusbh200_read(void *ptr, hwaddr addr, unsigned size)
+{
+    hwaddr off = 0x34 + addr;
+
+    switch (off) {
+    case 0x34:  /* fusbh200: EOF/Async. Sleep Timer Register */
+        return 0x00000041;
+    case 0x40:  /* fusbh200: Bus Monitor Control/Status Register */
+        /* High-Speed, VBUS valid, interrupt level-high active */
+        return (2 << 9) | (1 << 8) | (1 << 3);
+    }
+
+    return 0;
+}
+
+static void
+ehci_fusbh200_write(void *ptr, hwaddr addr, uint64_t val, unsigned size)
+{
+}
+
+static const MemoryRegionOps ehci_mmio_fusbh200_ops = {
+    .read = ehci_fusbh200_read,
+    .write = ehci_fusbh200_write,
+    .valid.min_access_size = 4,
+    .valid.max_access_size = 4,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static void
+usb_ehci_fusbh200_initfn(EHCIState *s, DeviceState *dev)
+{
+    memory_region_init_io(&s->mem_vendor, &ehci_mmio_fusbh200_ops, s,
+                          "fusbh200", 0x4c);
+    memory_region_add_subregion(&s->mem,
+                                s->opregbase + s->portscbase + 4 * s->portnr,
+                                &s->mem_vendor);
+}
+
 static const VMStateDescription vmstate_ehci_sysbus = {
     .name        = "ehci-sysbus",
     .version_id  = 2,
@@ -46,6 +89,9 @@ static void usb_ehci_sysbus_realizefn(DeviceState *dev, Error 
**errp)
     s->dma = &dma_context_memory;
 
     usb_ehci_initfn(s, dev);
+    if (sec->vendor_init) {
+        sec->vendor_init(s, DEVICE(dev));
+    }
     sysbus_init_irq(d, &s->irq);
     sysbus_init_mmio(d, &s->mem);
 }
@@ -76,6 +122,7 @@ static void ehci_xlnx_class_init(ObjectClass *oc, void *data)
     sec->opregbase = 0x140;
     sec->portscbase = 0x44;
     sec->portnr = NB_PORTS;
+    sec->vendor_init = NULL;
 }
 
 static const TypeInfo ehci_xlnx_type_info = {
@@ -92,6 +139,7 @@ static void ehci_exynos4210_class_init(ObjectClass *oc, void 
*data)
     sec->opregbase = 0x10;
     sec->portscbase = 0x44;
     sec->portnr = NB_PORTS;
+    sec->vendor_init = NULL;
 }
 
 static const TypeInfo ehci_exynos4210_type_info = {
@@ -100,11 +148,29 @@ static const TypeInfo ehci_exynos4210_type_info = {
     .class_init    = ehci_exynos4210_class_init,
 };
 
+static void ehci_fusbh200_class_init(ObjectClass *oc, void *data)
+{
+    SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(oc);
+
+    sec->capsbase = 0x0;
+    sec->opregbase = 0x10;
+    sec->portscbase = 0x20;
+    sec->portnr = 1;
+    sec->vendor_init = usb_ehci_fusbh200_initfn;
+}
+
+static const TypeInfo ehci_fusbh200_type_info = {
+    .name          = TYPE_FUSBH200_EHCI,
+    .parent        = TYPE_SYS_BUS_EHCI,
+    .class_init    = ehci_fusbh200_class_init,
+};
+
 static void ehci_sysbus_register_types(void)
 {
     type_register_static(&ehci_type_info);
     type_register_static(&ehci_xlnx_type_info);
     type_register_static(&ehci_exynos4210_type_info);
+    type_register_static(&ehci_fusbh200_type_info);
 }
 
 type_init(ehci_sysbus_register_types)
diff --git a/hw/usb/hcd-ehci.h b/hw/usb/hcd-ehci.h
index e587b67..3ca9c8f 100644
--- a/hw/usb/hcd-ehci.h
+++ b/hw/usb/hcd-ehci.h
@@ -261,6 +261,7 @@ struct EHCIState {
     MemoryRegion mem_caps;
     MemoryRegion mem_opreg;
     MemoryRegion mem_ports;
+    MemoryRegion mem_vendor;
     int companion_count;
     uint16_t capsbase;
     uint16_t opregbase;
@@ -336,6 +337,7 @@ typedef struct EHCIPCIState {
 
 #define TYPE_SYS_BUS_EHCI "sysbus-ehci-usb"
 #define TYPE_EXYNOS4210_EHCI "exynos4210-ehci-usb"
+#define TYPE_FUSBH200_EHCI "fusbh200-ehci-usb"
 
 #define SYS_BUS_EHCI(obj) \
     OBJECT_CHECK(EHCISysBusState, (obj), TYPE_SYS_BUS_EHCI)
@@ -361,6 +363,9 @@ typedef struct SysBusEHCIClass {
     uint16_t opregbase;
     uint16_t portscbase;
     uint16_t portnr;
+
+    /* vendor specific init function */
+    void (*vendor_init)(EHCIState *s, DeviceState *dev);
 } SysBusEHCIClass;
 
 #endif
-- 
1.7.9.5




reply via email to

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