From c1780af9fcc6b7751b267e4e9577bbb2424a1169 Mon Sep 17 00:00:00 2001 From: Rafaël Carré Date: Mon, 6 Jul 2009 13:54:51 +0000 Subject: 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 --- firmware/SOURCES | 2 + firmware/export/as3525.h | 4 + firmware/export/config-c200v2.h | 16 +- firmware/export/config-clip.h | 9 +- firmware/export/config-e200v2.h | 2 +- firmware/export/config-fuze.h | 2 +- firmware/export/config-m200v4.h | 13 ++ firmware/target/arm/as3525/usb-drv-as3525.c | 286 ++++++++++++++++++++++++++++ 8 files changed, 319 insertions(+), 15 deletions(-) create mode 100644 firmware/target/arm/as3525/usb-drv-as3525.c 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 + +/* 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<= 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; +} + -- cgit v1.2.3