diff options
Diffstat (limited to 'firmware/target/arm/pp/usb-fw-pp502x.c')
-rw-r--r-- | firmware/target/arm/pp/usb-fw-pp502x.c | 308 |
1 files changed, 308 insertions, 0 deletions
diff --git a/firmware/target/arm/pp/usb-fw-pp502x.c b/firmware/target/arm/pp/usb-fw-pp502x.c new file mode 100644 index 0000000000..5272102fad --- /dev/null +++ b/firmware/target/arm/pp/usb-fw-pp502x.c | |||
@@ -0,0 +1,308 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Linus Nielsen Feltzing | ||
11 | * | ||
12 | * iPod driver based on code from the ipodlinux project - http://ipodlinux.org | ||
13 | * Adapted for Rockbox in January 2006 | ||
14 | * Original file: podzilla/usb.c | ||
15 | * Copyright (C) 2005 Adam Johnston | ||
16 | * | ||
17 | * This program is free software; you can redistribute it and/or | ||
18 | * modify it under the terms of the GNU General Public License | ||
19 | * as published by the Free Software Foundation; either version 2 | ||
20 | * of the License, or (at your option) any later version. | ||
21 | * | ||
22 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
23 | * KIND, either express or implied. | ||
24 | * | ||
25 | ****************************************************************************/ | ||
26 | #include "config.h" | ||
27 | #include "system.h" | ||
28 | #include "usb.h" | ||
29 | #include "button.h" | ||
30 | #include "ata.h" | ||
31 | #include "string.h" | ||
32 | #include "usb_core.h" | ||
33 | #include "usb_drv.h" | ||
34 | |||
35 | #if defined(IPOD_4G) || defined(IPOD_COLOR) \ | ||
36 | || defined(IPOD_MINI) || defined(IPOD_MINI2G) | ||
37 | /* GPIO D bit 3 is usb detect */ | ||
38 | #define USB_GPIO GPIOD | ||
39 | #define USB_GPIO_MASK 0x08 | ||
40 | #define USB_GPIO_VAL 0x08 | ||
41 | |||
42 | #elif defined(IPOD_NANO) || defined(IPOD_VIDEO) | ||
43 | /* GPIO L bit 4 is usb detect */ | ||
44 | #define USB_GPIO GPIOL | ||
45 | #define USB_GPIO_MASK 0x10 | ||
46 | #define USB_GPIO_VAL 0x10 | ||
47 | |||
48 | #elif defined(SANSA_C200) | ||
49 | /* GPIO H bit 1 is usb/charger detect */ | ||
50 | #define USB_GPIO GPIOH | ||
51 | #define USB_GPIO_MASK 0x02 | ||
52 | #define USB_GPIO_VAL 0x02 | ||
53 | |||
54 | #elif defined(SANSA_E200) | ||
55 | /* GPIO B bit 4 is usb/charger detect */ | ||
56 | #define USB_GPIO GPIOB | ||
57 | #define USB_GPIO_MASK 0x10 | ||
58 | #define USB_GPIO_VAL 0x10 | ||
59 | |||
60 | #elif defined(IRIVER_H10) || defined(IRIVER_H10_5GB) || defined(MROBE_100) | ||
61 | /* GPIO L bit 2 is usb detect */ | ||
62 | #define USB_GPIO GPIOL | ||
63 | #define USB_GPIO_MASK 0x04 | ||
64 | #define USB_GPIO_VAL 0x04 | ||
65 | |||
66 | #elif defined(PHILIPS_SA9200) | ||
67 | /* GPIO B bit 6 (high) is usb bus power detect */ | ||
68 | #define USB_GPIO GPIOB | ||
69 | #define USB_GPIO_MASK 0x40 | ||
70 | #define USB_GPIO_VAL 0x40 | ||
71 | |||
72 | #elif defined(PHILIPS_HDD1630) || defined(PHILIPS_HDD6330) | ||
73 | /* GPIO E bit 2 is usb detect */ | ||
74 | #define USB_GPIO GPIOE | ||
75 | #define USB_GPIO_MASK 0x04 | ||
76 | #define USB_GPIO_VAL 0x04 | ||
77 | |||
78 | #elif defined(SAMSUNG_YH820) || defined(SAMSUNG_YH920) || defined(SAMSUNG_YH925) | ||
79 | /* GPIO D bit 4 is usb detect */ | ||
80 | #define USB_GPIO GPIOD | ||
81 | #define USB_GPIO_MASK 0x10 | ||
82 | #define USB_GPIO_VAL 0x10 | ||
83 | |||
84 | #elif defined(TATUNG_TPJ1022) | ||
85 | /* GPIO ? bit ? is usb detect (dummy value)*/ | ||
86 | #define USB_GPIO GPIOD | ||
87 | #define USB_GPIO_MASK 0x10 | ||
88 | #define USB_GPIO_VAL 0x10 | ||
89 | |||
90 | #elif defined(PBELL_VIBE500) | ||
91 | /* GPIO L bit 3 is usb detect */ | ||
92 | #define USB_GPIO GPIOL | ||
93 | #define USB_GPIO_MASK 0x04 | ||
94 | #define USB_GPIO_VAL 0x04 | ||
95 | |||
96 | #else | ||
97 | #error No USB GPIO config specified | ||
98 | #endif | ||
99 | |||
100 | #define USB_GPIO_ENABLE GPIO_ENABLE(USB_GPIO) | ||
101 | #define USB_GPIO_OUTPUT_EN GPIO_OUTPUT_EN(USB_GPIO) | ||
102 | #define USB_GPIO_INPUT_VAL GPIO_INPUT_VAL(USB_GPIO) | ||
103 | #define USB_GPIO_INT_EN GPIO_INT_EN(USB_GPIO) | ||
104 | #define USB_GPIO_INT_LEV GPIO_INT_LEV(USB_GPIO) | ||
105 | #define USB_GPIO_INT_CLR GPIO_INT_CLR(USB_GPIO) | ||
106 | #define USB_GPIO_HI_INT_MASK GPIO_HI_INT_MASK(USB_GPIO) | ||
107 | |||
108 | static void usb_reset_controller(void) | ||
109 | { | ||
110 | /* enable usb module */ | ||
111 | outl(inl(0x7000002C) | 0x3000000, 0x7000002C); | ||
112 | |||
113 | DEV_EN |= DEV_USB0; | ||
114 | DEV_EN |= DEV_USB1; | ||
115 | |||
116 | /* reset both USBs */ | ||
117 | DEV_RS |= DEV_USB0; | ||
118 | DEV_RS &=~DEV_USB0; | ||
119 | DEV_RS |= DEV_USB1; | ||
120 | DEV_RS &=~DEV_USB1; | ||
121 | |||
122 | DEV_INIT2 |= INIT_USB; | ||
123 | |||
124 | while ((inl(0x70000028) & 0x80) == 0); | ||
125 | outl(inl(0x70000028) | 0x2, 0x70000028); | ||
126 | udelay(100000); | ||
127 | XMB_RAM_CFG |= 0x47A; | ||
128 | |||
129 | /* disable USB-devices until USB is detected via GPIO */ | ||
130 | #ifndef BOOTLOADER | ||
131 | /* Disabling USB0 in the bootloader makes the OF not load, | ||
132 | Also something here breaks usb pin detect in bootloader. | ||
133 | leave it all enabled untill rockbox main loads */ | ||
134 | DEV_EN &= ~DEV_USB0; | ||
135 | DEV_EN &= ~DEV_USB1; | ||
136 | DEV_INIT2 &= ~INIT_USB; | ||
137 | #endif | ||
138 | } | ||
139 | |||
140 | /* Enable raw status pin read only - not interrupt */ | ||
141 | void usb_pin_init(void) | ||
142 | { | ||
143 | GPIO_CLEAR_BITWISE(USB_GPIO_OUTPUT_EN, USB_GPIO_MASK); | ||
144 | GPIO_SET_BITWISE(USB_GPIO_ENABLE, USB_GPIO_MASK); | ||
145 | #ifdef USB_FIREWIRE_HANDLING | ||
146 | /* GPIO C bit 1 is firewire detect */ | ||
147 | GPIO_CLEAR_BITWISE(GPIOC_OUTPUT_EN, 0x02); | ||
148 | GPIO_SET_BITWISE(GPIOC_ENABLE, 0x02); | ||
149 | #endif | ||
150 | } | ||
151 | |||
152 | void usb_init_device(void) | ||
153 | { | ||
154 | usb_reset_controller(); | ||
155 | |||
156 | /* Do one-time inits (no dependency on controller) */ | ||
157 | usb_drv_startup(); | ||
158 | |||
159 | usb_pin_init(); | ||
160 | |||
161 | /* These set INT_LEV to the inserted level so it will fire if already | ||
162 | * inserted at the time they are enabled. */ | ||
163 | #ifdef USB_STATUS_BY_EVENT | ||
164 | GPIO_CLEAR_BITWISE(USB_GPIO_INT_EN, USB_GPIO_MASK); | ||
165 | GPIO_WRITE_BITWISE(USB_GPIO_INT_LEV, USB_GPIO_VAL, USB_GPIO_MASK); | ||
166 | USB_GPIO_INT_CLR = USB_GPIO_MASK; | ||
167 | GPIO_SET_BITWISE(USB_GPIO_INT_EN, USB_GPIO_MASK); | ||
168 | CPU_HI_INT_EN = USB_GPIO_HI_INT_MASK; | ||
169 | |||
170 | #ifdef USB_FIREWIRE_HANDLING | ||
171 | /* GPIO C bit 1 is firewire detect */ | ||
172 | GPIO_CLEAR_BITWISE(GPIOC_INT_EN, 0x02); | ||
173 | GPIO_WRITE_BITWISE(GPIOC_INT_LEV, 0x00, 0x02); | ||
174 | GPIOC_INT_CLR = 0x02; | ||
175 | GPIO_SET_BITWISE(GPIOC_INT_EN, 0x02); | ||
176 | CPU_HI_INT_EN = GPIO0_MASK; | ||
177 | #endif | ||
178 | CPU_INT_EN = HI_MASK; | ||
179 | #endif /* USB_STATUS_BY_EVENT */ | ||
180 | } | ||
181 | |||
182 | void usb_enable(bool on) | ||
183 | { | ||
184 | if (on) { | ||
185 | /* if USB is detected, re-enable the USB-devices, otherwise make sure it's disabled */ | ||
186 | DEV_EN |= DEV_USB0; | ||
187 | DEV_EN |= DEV_USB1; | ||
188 | DEV_INIT2 |= INIT_USB; | ||
189 | usb_core_init(); | ||
190 | } | ||
191 | else { | ||
192 | usb_core_exit(); | ||
193 | /* Disable USB devices */ | ||
194 | usb_reset_controller(); | ||
195 | } | ||
196 | } | ||
197 | |||
198 | void usb_attach(void) | ||
199 | { | ||
200 | usb_drv_attach(); | ||
201 | } | ||
202 | |||
203 | bool usb_plugged(void) | ||
204 | { | ||
205 | return (USB_GPIO_INPUT_VAL & USB_GPIO_MASK) == USB_GPIO_VAL; | ||
206 | } | ||
207 | |||
208 | #ifdef USB_STATUS_BY_EVENT | ||
209 | /* Cannot always tell power pin from USB pin */ | ||
210 | static int usb_status = USB_EXTRACTED; | ||
211 | |||
212 | static int usb_timeout_event(struct timeout *tmo) | ||
213 | { | ||
214 | usb_status_event(tmo->data == USB_GPIO_VAL ? USB_INSERTED : USB_EXTRACTED); | ||
215 | return 0; | ||
216 | } | ||
217 | |||
218 | void usb_insert_int(void) | ||
219 | { | ||
220 | static struct timeout usb_oneshot; | ||
221 | unsigned long val = USB_GPIO_INPUT_VAL & USB_GPIO_MASK; | ||
222 | usb_status = (val == USB_GPIO_VAL) ? USB_INSERTED : USB_EXTRACTED; | ||
223 | GPIO_WRITE_BITWISE(USB_GPIO_INT_LEV, val ^ USB_GPIO_MASK, USB_GPIO_MASK); | ||
224 | USB_GPIO_INT_CLR = USB_GPIO_MASK; | ||
225 | timeout_register(&usb_oneshot, usb_timeout_event, HZ/5, val); | ||
226 | } | ||
227 | |||
228 | /* USB_DETECT_BY_CORE: Called when device descriptor is requested */ | ||
229 | void usb_drv_usb_detect_event(void) | ||
230 | { | ||
231 | /* Filter for invalid bus reset when unplugging by checking the pin state. */ | ||
232 | if(usb_plugged()) { | ||
233 | usb_status_event(USB_HOSTED); | ||
234 | } | ||
235 | } | ||
236 | #endif /* USB_STATUS_BY_EVENT */ | ||
237 | |||
238 | #ifdef HAVE_BOOTLOADER_USB_MODE | ||
239 | /* Replacement function that returns all unused memory after the bootloader | ||
240 | * because the storage driver uses the audio buffer */ | ||
241 | extern unsigned char freebuffer[]; | ||
242 | extern unsigned char freebufferend[]; | ||
243 | unsigned char *audio_get_buffer(bool talk_buf, size_t *buffer_size) | ||
244 | { | ||
245 | if (buffer_size) | ||
246 | *buffer_size = freebufferend - freebuffer + 1; | ||
247 | |||
248 | return freebuffer; | ||
249 | (void)talk_buf; | ||
250 | } | ||
251 | #endif /* HAVE_BOOTLOADER_USB_MODE */ | ||
252 | |||
253 | void usb_drv_int_enable(bool enable) | ||
254 | { | ||
255 | /* enable/disable USB IRQ in CPU */ | ||
256 | if(enable) { | ||
257 | CPU_INT_EN = USB_MASK; | ||
258 | } | ||
259 | else { | ||
260 | CPU_INT_DIS = USB_MASK; | ||
261 | } | ||
262 | } | ||
263 | |||
264 | /* detect host or charger (INSERTED or EXTRACTED) */ | ||
265 | int usb_detect(void) | ||
266 | { | ||
267 | #ifdef USB_STATUS_BY_EVENT | ||
268 | return usb_status; | ||
269 | #else | ||
270 | return usb_plugged() ? USB_INSERTED : USB_EXTRACTED; | ||
271 | #endif | ||
272 | } | ||
273 | |||
274 | #ifdef USB_FIREWIRE_HANDLING | ||
275 | #ifdef USB_STATUS_BY_EVENT | ||
276 | static bool firewire_status = false; | ||
277 | #endif | ||
278 | |||
279 | bool firewire_detect(void) | ||
280 | { | ||
281 | #ifdef USB_STATUS_BY_EVENT | ||
282 | return firewire_status; | ||
283 | #else | ||
284 | /* GPIO C bit 1 is firewire detect */ | ||
285 | /* no charger detection needed for firewire */ | ||
286 | return (GPIOC_INPUT_VAL & 0x02) == 0x00; | ||
287 | #endif | ||
288 | } | ||
289 | |||
290 | #ifdef USB_STATUS_BY_EVENT | ||
291 | static int firewire_timeout_event(struct timeout *tmo) | ||
292 | { | ||
293 | if (tmo->data == 0x00) | ||
294 | usb_firewire_connect_event(); | ||
295 | return 0; | ||
296 | } | ||
297 | |||
298 | void firewire_insert_int(void) | ||
299 | { | ||
300 | static struct timeout firewire_oneshot; | ||
301 | unsigned long val = GPIOC_INPUT_VAL & 0x02; | ||
302 | firewire_status = val == 0x00; | ||
303 | GPIO_WRITE_BITWISE(GPIOC_INT_LEV, val ^ 0x02, 0x02); | ||
304 | GPIOC_INT_CLR = 0x02; | ||
305 | timeout_register(&firewire_oneshot, firewire_timeout_event, HZ/5, val); | ||
306 | } | ||
307 | #endif /* USB_STATUS_BY_EVENT */ | ||
308 | #endif /* USB_FIREWIRE_HANDLING */ | ||