496d434c6e79c0a52b3475151ada51e9921eb19e
[kugel-rb.git] / firmware / target / arm / as3525 / usb-drv-as3525.c
blob496d434c6e79c0a52b3475151ada51e9921eb19e
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright © 2009 Rafaël Carré
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include "usb.h"
23 #include "usb_drv.h"
24 #include "as3525.h"
25 #include "clock-target.h"
26 #include "ascodec.h"
27 #include "as3514.h"
28 #include <stdbool.h>
29 #include "panic.h"
30 /*#define LOGF_ENABLE*/
31 #include "logf.h"
34 /* 4 input endpoints */
35 #define USB_IEP_CTRL(i) *((volatile unsigned long*) USB_BASE + 0x0000 + (i*0x20))
36 #define USB_IEP_STS(i) *((volatile unsigned long*) USB_BASE + 0x0004 + (i*0x20))
37 #define USB_IEP_TXFSIZE(i) *((volatile unsigned long*) USB_BASE + 0x0008 + (i*0x20))
38 #define USB_IEP_MPS(i) *((volatile unsigned long*) USB_BASE + 0x000C + (i*0x20))
39 #define USB_IEP_DESC_PTR(i) *((volatile unsigned long*) USB_BASE + 0x0014 + (i*0x20))
40 #define USB_IEP_STS_MASK(i) *((volatile unsigned long*) USB_BASE + 0x0018 + (i*0x20))
42 /* 4 output endpoints */
43 #define USB_OEP_CTRL(i) *((volatile unsigned long*) USB_BASE + 0x0200 + (i*0x20))
44 #define USB_OEP_STS(i) *((volatile unsigned long*) USB_BASE + 0x0204 + (i*0x20))
45 #define USB_OEP_RXFR(i) *((volatile unsigned long*) USB_BASE + 0x0208 + (i*0x20))
46 #define USB_OEP_MPS(i) *((volatile unsigned long*) USB_BASE + 0x020C + (i*0x20))
47 #define USB_OEP_SUP_PTR(i) *((volatile unsigned long*) USB_BASE + 0x0210 + (i*0x20))
48 #define USB_OEP_DESC_PTR(i) *((volatile unsigned long*) USB_BASE + 0x0214 + (i*0x20))
49 #define USB_OEP_STS_MASK(i) *((volatile unsigned long*) USB_BASE + 0x0218 + (i*0x20))
51 #define USB_DEV_CFG *((volatile unsigned long*) USB_BASE + 0x0400)
52 #define USB_DEV_CTRL *((volatile unsigned long*) USB_BASE + 0x0404)
53 #define USB_DEV_STS *((volatile unsigned long*) USB_BASE + 0x0408)
54 #define USB_DEV_INTR *((volatile unsigned long*) USB_BASE + 0x040C)
55 #define USB_DEV_INTR_MASK *((volatile unsigned long*) USB_BASE + 0x0410)
56 #define USB_DEV_EP_INTR *((volatile unsigned long*) USB_BASE + 0x0414)
57 #define USB_DEV_EP_INTR_MASK *((volatile unsigned long*) USB_BASE + 0x0418)
59 #define USB_PHY_EP0_INFO *((volatile unsigned long*) USB_BASE + 0x0504)
60 #define USB_PHY_EP1_INFO *((volatile unsigned long*) USB_BASE + 0x0508)
61 #define USB_PHY_EP2_INFO *((volatile unsigned long*) USB_BASE + 0x050C)
62 #define USB_PHY_EP3_INFO *((volatile unsigned long*) USB_BASE + 0x0510)
63 #define USB_PHY_EP4_INFO *((volatile unsigned long*) USB_BASE + 0x0514)
64 #define USB_PHY_EP5_INFO *((volatile unsigned long*) USB_BASE + 0x0518)
66 /* 4 channels */
67 #define USB_HOST_CH_SPLT(i) *((volatile unsigned long*) USB_BASE + 0x1000 + (i*0x20))
68 #define USB_HOST_CH_STS(i) *((volatile unsigned long*) USB_BASE + 0x1004 + (i*0x20))
69 #define USB_HOST_CH_TXFSIZE(i) *((volatile unsigned long*) USB_BASE + 0x1008 + (i*0x20))
70 #define USB_HOST_CH_REQ(i) *((volatile unsigned long*) USB_BASE + 0x100C + (i*0x20))
71 #define USB_HOST_CH_PER_INFO(i) *((volatile unsigned long*) USB_BASE + 0x1010 + (i*0x20))
72 #define USB_HOST_CH_DESC_PTR(i) *((volatile unsigned long*) USB_BASE + 0x1014 + (i*0x20))
73 #define USB_HOST_CH_STS_MASK(i) *((volatile unsigned long*) USB_BASE + 0x1018 + (i*0x20))
75 #define USB_HOST_CFG *((volatile unsigned long*) USB_BASE + 0x1400)
76 #define USB_HOST_CTRL *((volatile unsigned long*) USB_BASE + 0x1404)
77 #define USB_HOST_INTR *((volatile unsigned long*) USB_BASE + 0x140C)
78 #define USB_HOST_INTR_MASK *((volatile unsigned long*) USB_BASE + 0x1410)
79 #define USB_HOST_CH_INTR *((volatile unsigned long*) USB_BASE + 0x1414)
80 #define USB_HOST_CH_INTR_MASK *((volatile unsigned long*) USB_BASE + 0x1418)
81 #define USB_HOST_FRAME_INT *((volatile unsigned long*) USB_BASE + 0x141C)
82 #define USB_HOST_FRAME_REM *((volatile unsigned long*) USB_BASE + 0x1420)
83 #define USB_HOST_FRAME_NUM *((volatile unsigned long*) USB_BASE + 0x1424)
85 #define USB_HOST_PORT0_CTRL_STS *((volatile unsigned long*) USB_BASE + 0x1500)
87 #define USB_OTG_CSR *((volatile unsigned long*) USB_BASE + 0x2000)
88 #define USB_I2C_CSR *((volatile unsigned long*) USB_BASE + 0x2004)
89 #define USB_GPIO_CSR *((volatile unsigned long*) USB_BASE + 0x2008)
90 #define USB_SNPSID_CSR *((volatile unsigned long*) USB_BASE + 0x200C)
91 #define USB_USERID_CSR *((volatile unsigned long*) USB_BASE + 0x2010)
92 #define USB_USER_CONF1 *((volatile unsigned long*) USB_BASE + 0x2014)
93 #define USB_USER_CONF2 *((volatile unsigned long*) USB_BASE + 0x2018)
94 #define USB_USER_CONF3 *((volatile unsigned long*) USB_BASE + 0x201C)
95 #define USB_USER_CONF4 *((volatile unsigned long*) USB_BASE + 0x2020)
96 #define USB_USER_CONF5 *((volatile unsigned long*) USB_BASE + 0x2024)
98 struct usb_endpoint
100 void *buf;
101 unsigned int len;
102 union
104 unsigned int sent;
105 unsigned int received;
107 bool wait;
108 bool busy;
111 static struct usb_endpoint endpoints[USB_NUM_ENDPOINTS*2];
113 void usb_attach(void)
115 usb_enable(true);
118 void usb_drv_init(void)
120 int i;
121 for(i = 0; i < USB_NUM_ENDPOINTS * 2; i++)
122 endpoints[i].busy = false;
124 ascodec_write(AS3514_CVDD_DCDC3, ascodec_read(AS3514_CVDD_DCDC3) | 1<<2);
125 ascodec_write(AS3517_USB_UTIL, ascodec_read(AS3517_USB_UTIL) & ~(1<<4));
127 /* PHY part */
128 CGU_USB = 1<<5 /* enable */
129 | (CLK_DIV(AS3525_PLLA_FREQ, 48000000) / 2) << 2
130 | 1; /* source = PLLA */
132 /* AHB part */
133 CGU_PERI |= CGU_USB_CLOCK_ENABLE;
135 USB_GPIO_CSR = 0x6180000;
136 USB_DEV_CFG = (USB_DEV_CFG & ~3) | 1; /* full speed */
137 USB_DEV_CTRL |= 0x400; /* soft disconnect */
139 /* UVDD */
140 ascodec_write(AS3517_USB_UTIL, ascodec_read(AS3517_USB_UTIL) | (1<<4));
141 sleep(10); //msleep(100)
143 USB_GPIO_CSR = 0x6180000;
145 USB_GPIO_CSR |= 0x1C00000;
146 sleep(1); //msleep(3)
147 USB_GPIO_CSR |= 0x200000;
148 sleep(1); //msleep(10)
150 USB_DEV_CTRL |= 0x400; /* soft disconnect */
152 USB_GPIO_CSR &= ~0x1C00000;
153 sleep(1); //msleep(3)
154 USB_GPIO_CSR &= ~0x200000;
155 sleep(1); //msleep(10)
156 USB_DEV_CTRL &= ~0x400; /* clear soft disconnect */
158 #if defined(SANSA_CLIP)
159 GPIOA_DIR |= (1<<6);
160 GPIOA_PIN(6) = (1<<6);
161 GPIOA_DIR &= ~(1<<6); /* restore direction for usb_detect() */
162 #elif defined(SANSA_FUZE) || defined(SANSA_E200V2)
163 GPIOA_DIR |= (1<<3);
164 GPIOA_PIN(3) = (1<<3);
165 GPIOA_DIR &= ~(1<<3); /* restore direction for usb_detect() */
166 #elif defined(SANSA_C200V2)
167 GPIOA_DIR |= (1<<1);
168 GPIOA_PIN(1) = (1<<1);
169 GPIOA_DIR &= ~(1<<1); /* restore direction for usb_detect() */
170 #endif
172 #if 0 /* linux */
173 USB_DEV_CFG |= (1<<17) /* csr programming */
174 | (1<<3) /* self powered */
175 | (1<<2); /* remote wakeup */
177 USB_DEV_CFG &= ~3; /* high speed */
178 #endif
180 USB_IEP_CTRL(0) &= (3 << 4); /* control endpoint */
181 USB_IEP_DESC_PTR(0) = 0;
183 USB_OEP_CTRL(0) &= (3 << 4); /* control endpoint */
184 USB_OEP_DESC_PTR(0) = 0;
186 USB_DEV_INTR_MASK &= ~0xff; /* unmask all flags */
188 USB_DEV_EP_INTR_MASK &= ~((1<<0) | (1<<16)); /* ep 0 */
190 VIC_INT_ENABLE = INTERRUPT_USB;
192 USB_IEP_CTRL(0) |= (1<<7); /* set NAK */
193 USB_OEP_CTRL(0) |= (1<<7); /* set NAK */
196 void usb_drv_exit(void)
198 USB_DEV_CTRL |= (1<<10); /* soft disconnect */
199 VIC_INT_EN_CLEAR = INTERRUPT_USB;
200 CGU_USB &= ~(1<<5);
201 CGU_PERI &= ~CGU_USB_CLOCK_ENABLE;
202 ascodec_write(AS3517_USB_UTIL, ascodec_read(AS3517_USB_UTIL) & ~(1<<4));
205 int usb_drv_port_speed(void)
207 return (USB_DEV_CFG & 3) ? 0 : 1;
210 int usb_drv_request_endpoint(int type, int dir)
212 (void) type;
213 int i = dir == USB_DIR_IN ? 0 : 1;
215 for(; i < USB_NUM_ENDPOINTS * 2; i += 2)
216 if(!endpoints[i].busy)
218 endpoints[i].busy = true;
219 i >>= 1;
220 USB_DEV_EP_INTR_MASK &= ~((1<<i) | (1<<(16+i)));
221 return i | dir;
224 return -1;
227 void usb_drv_release_endpoint(int ep)
229 int i = (ep & 0x7f) * 2;
230 if(ep & USB_DIR_OUT)
231 i++;
232 endpoints[i].busy = false;
233 USB_DEV_EP_INTR_MASK |= (1<<ep) | (1<<(16+ep));
236 void usb_drv_cancel_all_transfers(void)
240 int usb_drv_recv(int ep, void *ptr, int len)
242 (void)ep;(void)ptr;(void)len;
243 if(ep >= 2)
244 return -1;
246 return -1;
249 int usb_drv_send(int ep, void *ptr, int len)
251 (void)ep;(void)ptr;(void)len;
252 if(ep >= 2)
253 return -1;
255 return -1;
258 int usb_drv_send_nonblocking(int ep, void *ptr, int len)
260 /* TODO */
261 return usb_drv_send(ep, ptr, len);
264 /* interrupt service routine */
265 void INT_USB(void)
267 panicf("USB interrupt !");
270 /* (not essential? , not implemented in usb-tcc.c) */
271 void usb_drv_set_test_mode(int mode)
273 (void)mode;
276 void usb_drv_set_address(int address)
278 (void)address;
281 void usb_drv_stall(int ep, bool stall, bool in)
283 (void)ep;(void)stall;(void)in;
286 bool usb_drv_stalled(int ep, bool in)
288 (void)ep;(void)in;
289 return true;