diff options
Diffstat (limited to 'firmware/target/arm')
-rw-r--r-- | firmware/target/arm/as3525/usb-drv-as3525.c | 286 |
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 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright © 2009 Rafaël Carré | ||
11 | * | ||
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. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
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 | |||
30 | /* 4 input endpoints */ | ||
31 | #define USB_IEP_CTRL(i) *((volatile unsigned long*) USB_BASE + 0x0000 + (i*0x20)) | ||
32 | #define USB_IEP_STS(i) *((volatile unsigned long*) USB_BASE + 0x0004 + (i*0x20)) | ||
33 | #define USB_IEP_TXFSIZE(i) *((volatile unsigned long*) USB_BASE + 0x0008 + (i*0x20)) | ||
34 | #define USB_IEP_MPS(i) *((volatile unsigned long*) USB_BASE + 0x000C + (i*0x20)) | ||
35 | #define USB_IEP_DESC_PTR(i) *((volatile unsigned long*) USB_BASE + 0x0014 + (i*0x20)) | ||
36 | #define USB_IEP_STS_MASK(i) *((volatile unsigned long*) USB_BASE + 0x0018 + (i*0x20)) | ||
37 | |||
38 | /* 4 output endpoints */ | ||
39 | #define USB_OEP_CTRL(i) *((volatile unsigned long*) USB_BASE + 0x0200 + (i*0x20)) | ||
40 | #define USB_OEP_STS(i) *((volatile unsigned long*) USB_BASE + 0x0204 + (i*0x20)) | ||
41 | #define USB_OEP_RXFR(i) *((volatile unsigned long*) USB_BASE + 0x0208 + (i*0x20)) | ||
42 | #define USB_OEP_MPS(i) *((volatile unsigned long*) USB_BASE + 0x020C + (i*0x20)) | ||
43 | #define USB_OEP_SUP_PTR(i) *((volatile unsigned long*) USB_BASE + 0x0210 + (i*0x20)) | ||
44 | #define USB_OEP_DESC_PTR(i) *((volatile unsigned long*) USB_BASE + 0x0214 + (i*0x20)) | ||
45 | #define USB_OEP_STS_MASK(i) *((volatile unsigned long*) USB_BASE + 0x0218 + (i*0x20)) | ||
46 | |||
47 | #define USB_DEV_CFG *((volatile unsigned long*) USB_BASE + 0x0400) | ||
48 | #define USB_DEV_CTRL *((volatile unsigned long*) USB_BASE + 0x0404) | ||
49 | #define USB_DEV_STS *((volatile unsigned long*) USB_BASE + 0x0408) | ||
50 | #define USB_DEV_INTR *((volatile unsigned long*) USB_BASE + 0x040C) | ||
51 | #define USB_DEV_INTR_MASK *((volatile unsigned long*) USB_BASE + 0x0410) | ||
52 | #define USB_DEV_EP_INTR *((volatile unsigned long*) USB_BASE + 0x0414) | ||
53 | #define USB_DEV_EP_INTR_MASK *((volatile unsigned long*) USB_BASE + 0x0418) | ||
54 | |||
55 | #define USB_PHY_EP0_INFO *((volatile unsigned long*) USB_BASE + 0x0504) | ||
56 | #define USB_PHY_EP1_INFO *((volatile unsigned long*) USB_BASE + 0x0508) | ||
57 | #define USB_PHY_EP2_INFO *((volatile unsigned long*) USB_BASE + 0x050C) | ||
58 | #define USB_PHY_EP3_INFO *((volatile unsigned long*) USB_BASE + 0x0510) | ||
59 | #define USB_PHY_EP4_INFO *((volatile unsigned long*) USB_BASE + 0x0514) | ||
60 | #define USB_PHY_EP5_INFO *((volatile unsigned long*) USB_BASE + 0x0518) | ||
61 | |||
62 | /* 4 channels */ | ||
63 | #define USB_HOST_CH_SPLT(i) *((volatile unsigned long*) USB_BASE + 0x1000 + (i*0x20)) | ||
64 | #define USB_HOST_CH_STS(i) *((volatile unsigned long*) USB_BASE + 0x1004 + (i*0x20)) | ||
65 | #define USB_HOST_CH_TXFSIZE(i) *((volatile unsigned long*) USB_BASE + 0x1008 + (i*0x20)) | ||
66 | #define USB_HOST_CH_REQ(i) *((volatile unsigned long*) USB_BASE + 0x100C + (i*0x20)) | ||
67 | #define USB_HOST_CH_PER_INFO(i) *((volatile unsigned long*) USB_BASE + 0x1010 + (i*0x20)) | ||
68 | #define USB_HOST_CH_DESC_PTR(i) *((volatile unsigned long*) USB_BASE + 0x1014 + (i*0x20)) | ||
69 | #define USB_HOST_CH_STS_MASK(i) *((volatile unsigned long*) USB_BASE + 0x1018 + (i*0x20)) | ||
70 | |||
71 | #define USB_HOST_CFG *((volatile unsigned long*) USB_BASE + 0x1400) | ||
72 | #define USB_HOST_CTRL *((volatile unsigned long*) USB_BASE + 0x1404) | ||
73 | #define USB_HOST_INTR *((volatile unsigned long*) USB_BASE + 0x140C) | ||
74 | #define USB_HOST_INTR_MASK *((volatile unsigned long*) USB_BASE + 0x1410) | ||
75 | #define USB_HOST_CH_INTR *((volatile unsigned long*) USB_BASE + 0x1414) | ||
76 | #define USB_HOST_CH_INTR_MASK *((volatile unsigned long*) USB_BASE + 0x1418) | ||
77 | #define USB_HOST_FRAME_INT *((volatile unsigned long*) USB_BASE + 0x141C) | ||
78 | #define USB_HOST_FRAME_REM *((volatile unsigned long*) USB_BASE + 0x1420) | ||
79 | #define USB_HOST_FRAME_NUM *((volatile unsigned long*) USB_BASE + 0x1424) | ||
80 | |||
81 | #define USB_HOST_PORT0_CTRL_STS *((volatile unsigned long*) USB_BASE + 0x1500) | ||
82 | |||
83 | #define USB_OTG_CSR *((volatile unsigned long*) USB_BASE + 0x2000) | ||
84 | #define USB_I2C_CSR *((volatile unsigned long*) USB_BASE + 0x2004) | ||
85 | #define USB_GPIO_CSR *((volatile unsigned long*) USB_BASE + 0x2008) | ||
86 | #define USB_SNPSID_CSR *((volatile unsigned long*) USB_BASE + 0x200C) | ||
87 | #define USB_USERID_CSR *((volatile unsigned long*) USB_BASE + 0x2010) | ||
88 | #define USB_USER_CONF1 *((volatile unsigned long*) USB_BASE + 0x2014) | ||
89 | #define USB_USER_CONF2 *((volatile unsigned long*) USB_BASE + 0x2018) | ||
90 | #define USB_USER_CONF3 *((volatile unsigned long*) USB_BASE + 0x201C) | ||
91 | #define USB_USER_CONF4 *((volatile unsigned long*) USB_BASE + 0x2020) | ||
92 | #define USB_USER_CONF5 *((volatile unsigned long*) USB_BASE + 0x2024) | ||
93 | |||
94 | struct usb_endpoint | ||
95 | { | ||
96 | void *buf; | ||
97 | unsigned int len; | ||
98 | union | ||
99 | { | ||
100 | unsigned int sent; | ||
101 | unsigned int received; | ||
102 | }; | ||
103 | bool wait; | ||
104 | bool busy; | ||
105 | }; | ||
106 | |||
107 | static struct usb_endpoint endpoints[USB_NUM_ENDPOINTS*2]; | ||
108 | |||
109 | void usb_attach(void) | ||
110 | { | ||
111 | usb_enable(true); | ||
112 | } | ||
113 | |||
114 | void usb_drv_init(void) | ||
115 | { | ||
116 | int i; | ||
117 | for(i = 0; i < USB_NUM_ENDPOINTS * 2; i++) | ||
118 | endpoints[i].busy = false; | ||
119 | |||
120 | ascodec_write(AS3514_CVDD_DCDC3, ascodec_read(AS3514_CVDD_DCDC3) | 1<<2); | ||
121 | ascodec_write(AS3514_USB_UTIL, ascodec_read(AS3514_USB_UTIL) & ~(1<<4)); | ||
122 | |||
123 | USB_GPIO_CSR |= 0x1C00000; //sleep(3) | ||
124 | sleep(1); | ||
125 | USB_GPIO_CSR |= 0x200000; //sleep(10) | ||
126 | sleep(1); | ||
127 | |||
128 | /* PHY part */ | ||
129 | CGU_USB = 1<<5 /* enable */ | ||
130 | | (CLK_DIV(AS3525_PLLA_FREQ, 48000000) / 2) << 2 | ||
131 | | 1; /* source = PLLA */ | ||
132 | |||
133 | /* AHB part */ | ||
134 | CGU_PERI |= CGU_USB_CLOCK_ENABLE; | ||
135 | |||
136 | /* UVDD */ | ||
137 | ascodec_write(AS3514_USB_UTIL, ascodec_read(AS3514_USB_UTIL) | (1<<4)); | ||
138 | |||
139 | sleep(10); | ||
140 | |||
141 | USB_DEV_CFG |= (1<<31); /* soft reset */ | ||
142 | volatile int tmp = USB_DEV_CFG; | ||
143 | (void)tmp; | ||
144 | |||
145 | USB_GPIO_CSR = 0x6180000; | ||
146 | |||
147 | USB_DEV_CFG = (USB_DEV_CFG & ~3) | 1; /* full speed */ | ||
148 | |||
149 | USB_DEV_CTRL |= 0x400; /* soft disconnect */ | ||
150 | |||
151 | |||
152 | USB_GPIO_CSR |= 0x1C00000; //sleep(3) | ||
153 | sleep(1); | ||
154 | USB_GPIO_CSR |= 0x200000; //sleep(10) | ||
155 | sleep(1); | ||
156 | |||
157 | USB_DEV_CTRL |= 0x400; /* soft disconnect */ | ||
158 | |||
159 | USB_GPIO_CSR &= ~0x1C00000; //sleep(3) | ||
160 | sleep(1); | ||
161 | USB_GPIO_CSR &= ~0x200000; //sleep(10) | ||
162 | sleep(1); | ||
163 | USB_DEV_CTRL &= ~0x400; /* soft disconnect */ | ||
164 | |||
165 | GPIOA_DIR |= (1<<6); | ||
166 | GPIOA_PIN(6) = (1<<6); | ||
167 | |||
168 | #if 0 /* linux */ | ||
169 | USB_DEV_CFG |= (1<<17) /* csr programming */ | ||
170 | | (1<<3) /* self powered */ | ||
171 | | (1<<2); /* remote wakeup */ | ||
172 | |||
173 | USB_DEV_CFG &= ~3; /* high speed */ | ||
174 | #endif | ||
175 | |||
176 | USB_IEP_CTRL(0) &= (3 << 4); /* control endpoint */ | ||
177 | USB_IEP_DESC_PTR(0) = 0; | ||
178 | |||
179 | USB_OEP_CTRL(0) &= (3 << 4); /* control endpoint */ | ||
180 | USB_OEP_DESC_PTR(0) = 0; | ||
181 | |||
182 | USB_DEV_INTR_MASK &= ~0xff; /* unmask all flags */ | ||
183 | |||
184 | USB_DEV_EP_INTR_MASK &= ~((1<<0) | (1<<16)); /* ep 0 */ | ||
185 | |||
186 | VIC_INT_ENABLE |= INTERRUPT_USB; | ||
187 | |||
188 | USB_IEP_CTRL(0) |= (1<<7); /* set NAK */ | ||
189 | USB_OEP_CTRL(0) |= (1<<7); /* set NAK */ | ||
190 | } | ||
191 | |||
192 | void usb_drv_exit(void) | ||
193 | { | ||
194 | USB_DEV_CTRL |= (1<<10); /* soft disconnect */ | ||
195 | VIC_INT_EN_CLEAR = INTERRUPT_USB; | ||
196 | CGU_USB &= ~(1<<5); | ||
197 | CGU_PERI &= ~CGU_USB_CLOCK_ENABLE; | ||
198 | ascodec_write(AS3514_USB_UTIL, ascodec_read(AS3514_USB_UTIL) & ~(1<<4)); | ||
199 | } | ||
200 | |||
201 | int usb_drv_port_speed(void) | ||
202 | { | ||
203 | return (USB_DEV_CFG & 3) ? 0 : 1; | ||
204 | } | ||
205 | |||
206 | int usb_drv_request_endpoint(int type, int dir) | ||
207 | { | ||
208 | (void) type; | ||
209 | int i = dir == USB_DIR_IN ? 0 : 1; | ||
210 | |||
211 | for(; i < USB_NUM_ENDPOINTS * 2; i += 2) | ||
212 | if(!endpoints[i].busy) | ||
213 | { | ||
214 | endpoints[i].busy = true; | ||
215 | i >>= 1; | ||
216 | USB_DEV_EP_INTR_MASK &= ~((1<<i) | (1<<(16+i))); | ||
217 | return i | dir; | ||
218 | } | ||
219 | |||
220 | return -1; | ||
221 | } | ||
222 | |||
223 | void usb_drv_release_endpoint(int ep) | ||
224 | { | ||
225 | int i = (ep & 0x7f) * 2; | ||
226 | if(ep & USB_DIR_OUT) | ||
227 | i++; | ||
228 | endpoints[i].busy = false; | ||
229 | USB_DEV_EP_INTR_MASK |= (1<<ep) | (1<<(16+ep)); | ||
230 | } | ||
231 | |||
232 | void usb_drv_cancel_all_transfers(void) | ||
233 | { | ||
234 | } | ||
235 | |||
236 | int usb_drv_recv(int ep, void *ptr, int len) | ||
237 | { | ||
238 | (void)ep;(void)ptr;(void)len; | ||
239 | if(ep >= 2) | ||
240 | return -1; | ||
241 | |||
242 | return -1; | ||
243 | } | ||
244 | |||
245 | int usb_drv_send(int ep, void *ptr, int len) | ||
246 | { | ||
247 | (void)ep;(void)ptr;(void)len; | ||
248 | if(ep >= 2) | ||
249 | return -1; | ||
250 | |||
251 | return -1; | ||
252 | } | ||
253 | |||
254 | int usb_drv_send_nonblocking(int ep, void *ptr, int len) | ||
255 | { | ||
256 | /* TODO */ | ||
257 | return usb_drv_send(ep, ptr, len); | ||
258 | } | ||
259 | |||
260 | /* interrupt service routine */ | ||
261 | void INT_USB(void) | ||
262 | { | ||
263 | } | ||
264 | |||
265 | /* (not essential? , not implemented in usb-tcc.c) */ | ||
266 | void usb_drv_set_test_mode(int mode) | ||
267 | { | ||
268 | (void)mode; | ||
269 | } | ||
270 | |||
271 | void usb_drv_set_address(int address) | ||
272 | { | ||
273 | (void)address; | ||
274 | } | ||
275 | |||
276 | void usb_drv_stall(int ep, bool stall, bool in) | ||
277 | { | ||
278 | (void)ep;(void)stall;(void)in; | ||
279 | } | ||
280 | |||
281 | bool usb_drv_stalled(int ep, bool in) | ||
282 | { | ||
283 | (void)ep;(void)in; | ||
284 | return true; | ||
285 | } | ||
286 | |||