summaryrefslogtreecommitdiffstats
path: root/firmware/target/arm
diff options
context:
space:
mode:
authorRafaël Carré <rafael.carre@gmail.com>2009-07-06 13:54:51 +0000
committerRafaël Carré <rafael.carre@gmail.com>2009-07-06 13:54:51 +0000
commitc1780af9fcc6b7751b267e4e9577bbb2424a1169 (patch)
tree8644c22091bc7ed6c6ada18c484efed26fb13d84 /firmware/target/arm
parenta63a116086ac8c4d876c89b1bb2566b4d168a75f (diff)
downloadrockbox-c1780af9fcc6b7751b267e4e9577bbb2424a1169.tar.gz
rockbox-c1780af9fcc6b7751b267e4e9577bbb2424a1169.tar.bz2
rockbox-c1780af9fcc6b7751b267e4e9577bbb2424a1169.zip
Samsa AMS: start of an USB driver (nothing working atm)
Work based on AMD 5536 linux driver and AMD Geode CS5536 datasheet Rockbox still doesn't reboot on USB insert git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21689 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm')
-rw-r--r--firmware/target/arm/as3525/usb-drv-as3525.c286
1 files changed, 286 insertions, 0 deletions
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;
+}
+