summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--firmware/SOURCES2
-rw-r--r--firmware/export/as3525.h4
-rw-r--r--firmware/export/config-c200v2.h16
-rw-r--r--firmware/export/config-clip.h9
-rw-r--r--firmware/export/config-e200v2.h2
-rw-r--r--firmware/export/config-fuze.h2
-rw-r--r--firmware/export/config-m200v4.h13
-rw-r--r--firmware/target/arm/as3525/usb-drv-as3525.c286
8 files changed, 319 insertions, 15 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES
index 6f932d1887..7c1a17ff7f 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -279,6 +279,8 @@ usbstack/usb_hid.c
drivers/m66591.c
#elif CONFIG_USBOTG == USBOTG_ARC
target/arm/usb-drv-arc.c
+#elif CONFIG_USBOTG == USBOTG_AS3525
+target/arm/as3525/usb-drv-as3525.c
#elif CONFIG_USBOTG == USBOTG_ISP1583
drivers/isp1583.c
#endif
diff --git a/firmware/export/as3525.h b/firmware/export/as3525.h
index 39e0706637..b7da19320d 100644
--- a/firmware/export/as3525.h
+++ b/firmware/export/as3525.h
@@ -500,4 +500,8 @@ interface */
/* Timer frequency */
#define TIMER_FREQ (24000000 / 16)
+/* USB : TODO */
+#define USB_NUM_ENDPOINTS 4
+#define USB_DEVBSS_ATTR IBSS_ATTR
+
#endif /*__AS3525_H__*/
diff --git a/firmware/export/config-c200v2.h b/firmware/export/config-c200v2.h
index ae2cd04c0b..cde5e9b0e5 100644
--- a/firmware/export/config-c200v2.h
+++ b/firmware/export/config-c200v2.h
@@ -168,17 +168,21 @@
/* Type of LCD : Samsung S6B33B2 */
#define CONFIG_LCD LCD_C200
-#define USB_HANDLED_BY_OF
-
#ifndef BOOTLOADER
#define HAVE_MULTIVOLUME
#define HAVE_HOTSWAP
-#endif
+
+#define USB_HANDLED_BY_OF
+
+#define CONFIG_USB USBOTG_AS3525
/* enable these for the experimental usb stack */
-//#define HAVE_USBSTACK
-//#define USB_VENDOR_ID 0x0781
-//#define USB_PRODUCT_ID 0x7452
+#define HAVE_USBSTACK
+#define USB_VENDOR_ID 0x0781
+#define USB_PRODUCT_ID 0x7452
+
+#endif /* BOOTLOADER */
+
/* Virtual LED (icon) */
#define CONFIG_LED LED_VIRTUAL
diff --git a/firmware/export/config-clip.h b/firmware/export/config-clip.h
index 37b1a3185a..45b0a607c0 100644
--- a/firmware/export/config-clip.h
+++ b/firmware/export/config-clip.h
@@ -175,19 +175,14 @@
#define USB_HANDLED_BY_OF
-#if 0 /* disabled since there is no USB driver */
-
-/* USB On-the-go */
-#define CONFIG_USBOTG USBOTG_ARC
+#define CONFIG_USB USBOTG_AS3525
/* enable these for the experimental usb stack */
#define HAVE_USBSTACK
#define USB_VENDOR_ID 0x0781
#define USB_PRODUCT_ID 0x7433
-#endif /* BOOTLOADER */
-
-#endif
+#endif /* BOOTLOADER */
/* Virtual LED (icon) */
#define CONFIG_LED LED_VIRTUAL
diff --git a/firmware/export/config-e200v2.h b/firmware/export/config-e200v2.h
index cc66b73249..a1c41fbe7d 100644
--- a/firmware/export/config-e200v2.h
+++ b/firmware/export/config-e200v2.h
@@ -190,7 +190,7 @@
#define CONFIG_USBOTG USBOTG_AS3525
/* enable these for the experimental usb stack */
-//#define HAVE_USBSTACK
+#define HAVE_USBSTACK
#define USB_VENDOR_ID 0x0781
#define USB_PRODUCT_ID 0x7423
diff --git a/firmware/export/config-fuze.h b/firmware/export/config-fuze.h
index c8fae9aca9..b9c5acb9b1 100644
--- a/firmware/export/config-fuze.h
+++ b/firmware/export/config-fuze.h
@@ -188,7 +188,7 @@
#define CONFIG_USBOTG USBOTG_AS3525
/* enable these for the experimental usb stack */
-//#define HAVE_USBSTACK
+#define HAVE_USBSTACK
#define USB_VENDOR_ID 0x0781
#define USB_PRODUCT_ID 0x7423
diff --git a/firmware/export/config-m200v4.h b/firmware/export/config-m200v4.h
index 16b704cea4..e23f3eb0e2 100644
--- a/firmware/export/config-m200v4.h
+++ b/firmware/export/config-m200v4.h
@@ -139,6 +139,19 @@
/* Offset ( in the firmware file's header ) to the real data */
#define FIRMWARE_OFFSET_FILE_DATA 8
+#ifndef BOOTLOADER
+
+#define USB_HANDLED_BY_OF
+
+#define CONFIG_USB USBOTG_AS3525
+
+/* enable these for the experimental usb stack */
+#define HAVE_USBSTACK
+#define USB_VENDOR_ID 0x0781
+#define USB_PRODUCT_ID 0x7431
+
+#endif /* BOOTLOADER */
+
/* Software controlled LED */
#define CONFIG_LED LED_VIRTUAL
diff --git a/firmware/target/arm/as3525/usb-drv-as3525.c b/firmware/target/arm/as3525/usb-drv-as3525.c
new file mode 100644
index 0000000000..bac5f6776b
--- /dev/null
+++ b/firmware/target/arm/as3525/usb-drv-as3525.c
@@ -0,0 +1,286 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright © 2009 Rafaël Carré
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "usb.h"
+#include "usb_drv.h"
+#include "as3525.h"
+#include "clock-target.h"
+#include "ascodec.h"
+#include "as3514.h"
+#include <stdbool.h>
+
+/* 4 input endpoints */
+#define USB_IEP_CTRL(i) *((volatile unsigned long*) USB_BASE + 0x0000 + (i*0x20))
+#define USB_IEP_STS(i) *((volatile unsigned long*) USB_BASE + 0x0004 + (i*0x20))
+#define USB_IEP_TXFSIZE(i) *((volatile unsigned long*) USB_BASE + 0x0008 + (i*0x20))
+#define USB_IEP_MPS(i) *((volatile unsigned long*) USB_BASE + 0x000C + (i*0x20))
+#define USB_IEP_DESC_PTR(i) *((volatile unsigned long*) USB_BASE + 0x0014 + (i*0x20))
+#define USB_IEP_STS_MASK(i) *((volatile unsigned long*) USB_BASE + 0x0018 + (i*0x20))
+
+/* 4 output endpoints */
+#define USB_OEP_CTRL(i) *((volatile unsigned long*) USB_BASE + 0x0200 + (i*0x20))
+#define USB_OEP_STS(i) *((volatile unsigned long*) USB_BASE + 0x0204 + (i*0x20))
+#define USB_OEP_RXFR(i) *((volatile unsigned long*) USB_BASE + 0x0208 + (i*0x20))
+#define USB_OEP_MPS(i) *((volatile unsigned long*) USB_BASE + 0x020C + (i*0x20))
+#define USB_OEP_SUP_PTR(i) *((volatile unsigned long*) USB_BASE + 0x0210 + (i*0x20))
+#define USB_OEP_DESC_PTR(i) *((volatile unsigned long*) USB_BASE + 0x0214 + (i*0x20))
+#define USB_OEP_STS_MASK(i) *((volatile unsigned long*) USB_BASE + 0x0218 + (i*0x20))
+
+#define USB_DEV_CFG *((volatile unsigned long*) USB_BASE + 0x0400)
+#define USB_DEV_CTRL *((volatile unsigned long*) USB_BASE + 0x0404)
+#define USB_DEV_STS *((volatile unsigned long*) USB_BASE + 0x0408)
+#define USB_DEV_INTR *((volatile unsigned long*) USB_BASE + 0x040C)
+#define USB_DEV_INTR_MASK *((volatile unsigned long*) USB_BASE + 0x0410)
+#define USB_DEV_EP_INTR *((volatile unsigned long*) USB_BASE + 0x0414)
+#define USB_DEV_EP_INTR_MASK *((volatile unsigned long*) USB_BASE + 0x0418)
+
+#define USB_PHY_EP0_INFO *((volatile unsigned long*) USB_BASE + 0x0504)
+#define USB_PHY_EP1_INFO *((volatile unsigned long*) USB_BASE + 0x0508)
+#define USB_PHY_EP2_INFO *((volatile unsigned long*) USB_BASE + 0x050C)
+#define USB_PHY_EP3_INFO *((volatile unsigned long*) USB_BASE + 0x0510)
+#define USB_PHY_EP4_INFO *((volatile unsigned long*) USB_BASE + 0x0514)
+#define USB_PHY_EP5_INFO *((volatile unsigned long*) USB_BASE + 0x0518)
+
+/* 4 channels */
+#define USB_HOST_CH_SPLT(i) *((volatile unsigned long*) USB_BASE + 0x1000 + (i*0x20))
+#define USB_HOST_CH_STS(i) *((volatile unsigned long*) USB_BASE + 0x1004 + (i*0x20))
+#define USB_HOST_CH_TXFSIZE(i) *((volatile unsigned long*) USB_BASE + 0x1008 + (i*0x20))
+#define USB_HOST_CH_REQ(i) *((volatile unsigned long*) USB_BASE + 0x100C + (i*0x20))
+#define USB_HOST_CH_PER_INFO(i) *((volatile unsigned long*) USB_BASE + 0x1010 + (i*0x20))
+#define USB_HOST_CH_DESC_PTR(i) *((volatile unsigned long*) USB_BASE + 0x1014 + (i*0x20))
+#define USB_HOST_CH_STS_MASK(i) *((volatile unsigned long*) USB_BASE + 0x1018 + (i*0x20))
+
+#define USB_HOST_CFG *((volatile unsigned long*) USB_BASE + 0x1400)
+#define USB_HOST_CTRL *((volatile unsigned long*) USB_BASE + 0x1404)
+#define USB_HOST_INTR *((volatile unsigned long*) USB_BASE + 0x140C)
+#define USB_HOST_INTR_MASK *((volatile unsigned long*) USB_BASE + 0x1410)
+#define USB_HOST_CH_INTR *((volatile unsigned long*) USB_BASE + 0x1414)
+#define USB_HOST_CH_INTR_MASK *((volatile unsigned long*) USB_BASE + 0x1418)
+#define USB_HOST_FRAME_INT *((volatile unsigned long*) USB_BASE + 0x141C)
+#define USB_HOST_FRAME_REM *((volatile unsigned long*) USB_BASE + 0x1420)
+#define USB_HOST_FRAME_NUM *((volatile unsigned long*) USB_BASE + 0x1424)
+
+#define USB_HOST_PORT0_CTRL_STS *((volatile unsigned long*) USB_BASE + 0x1500)
+
+#define USB_OTG_CSR *((volatile unsigned long*) USB_BASE + 0x2000)
+#define USB_I2C_CSR *((volatile unsigned long*) USB_BASE + 0x2004)
+#define USB_GPIO_CSR *((volatile unsigned long*) USB_BASE + 0x2008)
+#define USB_SNPSID_CSR *((volatile unsigned long*) USB_BASE + 0x200C)
+#define USB_USERID_CSR *((volatile unsigned long*) USB_BASE + 0x2010)
+#define USB_USER_CONF1 *((volatile unsigned long*) USB_BASE + 0x2014)
+#define USB_USER_CONF2 *((volatile unsigned long*) USB_BASE + 0x2018)
+#define USB_USER_CONF3 *((volatile unsigned long*) USB_BASE + 0x201C)
+#define USB_USER_CONF4 *((volatile unsigned long*) USB_BASE + 0x2020)
+#define USB_USER_CONF5 *((volatile unsigned long*) USB_BASE + 0x2024)
+
+struct usb_endpoint
+{
+ void *buf;
+ unsigned int len;
+ union
+ {
+ unsigned int sent;
+ unsigned int received;
+ };
+ bool wait;
+ bool busy;
+};
+
+static struct usb_endpoint endpoints[USB_NUM_ENDPOINTS*2];
+
+void usb_attach(void)
+{
+ usb_enable(true);
+}
+
+void usb_drv_init(void)
+{
+ int i;
+ for(i = 0; i < USB_NUM_ENDPOINTS * 2; i++)
+ endpoints[i].busy = false;
+
+ ascodec_write(AS3514_CVDD_DCDC3, ascodec_read(AS3514_CVDD_DCDC3) | 1<<2);
+ ascodec_write(AS3514_USB_UTIL, ascodec_read(AS3514_USB_UTIL) & ~(1<<4));
+
+ USB_GPIO_CSR |= 0x1C00000; //sleep(3)
+ sleep(1);
+ USB_GPIO_CSR |= 0x200000; //sleep(10)
+ sleep(1);
+
+ /* PHY part */
+ CGU_USB = 1<<5 /* enable */
+ | (CLK_DIV(AS3525_PLLA_FREQ, 48000000) / 2) << 2
+ | 1; /* source = PLLA */
+
+ /* AHB part */
+ CGU_PERI |= CGU_USB_CLOCK_ENABLE;
+
+ /* UVDD */
+ ascodec_write(AS3514_USB_UTIL, ascodec_read(AS3514_USB_UTIL) | (1<<4));
+
+ sleep(10);
+
+ USB_DEV_CFG |= (1<<31); /* soft reset */
+ volatile int tmp = USB_DEV_CFG;
+ (void)tmp;
+
+ USB_GPIO_CSR = 0x6180000;
+
+ USB_DEV_CFG = (USB_DEV_CFG & ~3) | 1; /* full speed */
+
+ USB_DEV_CTRL |= 0x400; /* soft disconnect */
+
+
+ USB_GPIO_CSR |= 0x1C00000; //sleep(3)
+ sleep(1);
+ USB_GPIO_CSR |= 0x200000; //sleep(10)
+ sleep(1);
+
+ USB_DEV_CTRL |= 0x400; /* soft disconnect */
+
+ USB_GPIO_CSR &= ~0x1C00000; //sleep(3)
+ sleep(1);
+ USB_GPIO_CSR &= ~0x200000; //sleep(10)
+ sleep(1);
+ USB_DEV_CTRL &= ~0x400; /* soft disconnect */
+
+ GPIOA_DIR |= (1<<6);
+ GPIOA_PIN(6) = (1<<6);
+
+#if 0 /* linux */
+ USB_DEV_CFG |= (1<<17) /* csr programming */
+ | (1<<3) /* self powered */
+ | (1<<2); /* remote wakeup */
+
+ USB_DEV_CFG &= ~3; /* high speed */
+#endif
+
+ USB_IEP_CTRL(0) &= (3 << 4); /* control endpoint */
+ USB_IEP_DESC_PTR(0) = 0;
+
+ USB_OEP_CTRL(0) &= (3 << 4); /* control endpoint */
+ USB_OEP_DESC_PTR(0) = 0;
+
+ USB_DEV_INTR_MASK &= ~0xff; /* unmask all flags */
+
+ USB_DEV_EP_INTR_MASK &= ~((1<<0) | (1<<16)); /* ep 0 */
+
+ VIC_INT_ENABLE |= INTERRUPT_USB;
+
+ USB_IEP_CTRL(0) |= (1<<7); /* set NAK */
+ USB_OEP_CTRL(0) |= (1<<7); /* set NAK */
+}
+
+void usb_drv_exit(void)
+{
+ USB_DEV_CTRL |= (1<<10); /* soft disconnect */
+ VIC_INT_EN_CLEAR = INTERRUPT_USB;
+ CGU_USB &= ~(1<<5);
+ CGU_PERI &= ~CGU_USB_CLOCK_ENABLE;
+ ascodec_write(AS3514_USB_UTIL, ascodec_read(AS3514_USB_UTIL) & ~(1<<4));
+}
+
+int usb_drv_port_speed(void)
+{
+ return (USB_DEV_CFG & 3) ? 0 : 1;
+}
+
+int usb_drv_request_endpoint(int type, int dir)
+{
+ (void) type;
+ int i = dir == USB_DIR_IN ? 0 : 1;
+
+ for(; i < USB_NUM_ENDPOINTS * 2; i += 2)
+ if(!endpoints[i].busy)
+ {
+ endpoints[i].busy = true;
+ i >>= 1;
+ USB_DEV_EP_INTR_MASK &= ~((1<<i) | (1<<(16+i)));
+ return i | dir;
+ }
+
+ return -1;
+}
+
+void usb_drv_release_endpoint(int ep)
+{
+ int i = (ep & 0x7f) * 2;
+ if(ep & USB_DIR_OUT)
+ i++;
+ endpoints[i].busy = false;
+ USB_DEV_EP_INTR_MASK |= (1<<ep) | (1<<(16+ep));
+}
+
+void usb_drv_cancel_all_transfers(void)
+{
+}
+
+int usb_drv_recv(int ep, void *ptr, int len)
+{
+ (void)ep;(void)ptr;(void)len;
+ if(ep >= 2)
+ return -1;
+
+ return -1;
+}
+
+int usb_drv_send(int ep, void *ptr, int len)
+{
+ (void)ep;(void)ptr;(void)len;
+ if(ep >= 2)
+ return -1;
+
+ return -1;
+}
+
+int usb_drv_send_nonblocking(int ep, void *ptr, int len)
+{
+ /* TODO */
+ return usb_drv_send(ep, ptr, len);
+}
+
+/* interrupt service routine */
+void INT_USB(void)
+{
+}
+
+/* (not essential? , not implemented in usb-tcc.c) */
+void usb_drv_set_test_mode(int mode)
+{
+ (void)mode;
+}
+
+void usb_drv_set_address(int address)
+{
+ (void)address;
+}
+
+void usb_drv_stall(int ep, bool stall, bool in)
+{
+ (void)ep;(void)stall;(void)in;
+}
+
+bool usb_drv_stalled(int ep, bool in)
+{
+ (void)ep;(void)in;
+ return true;
+}
+