PP502x USB: It seems r29087 introduced additional parasitic current consumption after...
[kugel-rb.git] / firmware / target / arm / usb-fw-pp502x.c
blob19f21e12ed64afadb8286a9bf73fe173a84349d1
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
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
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.
22 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
23 * KIND, either express or implied.
25 ****************************************************************************/
26 #include "config.h"
27 #include "system.h"
28 #include "usb-target.h"
29 #include "usb.h"
30 #include "button.h"
31 #include "ata.h"
32 #include "string.h"
33 #include "usb_core.h"
34 #include "usb_drv.h"
36 #if defined(IPOD_4G) || defined(IPOD_COLOR) \
37 || defined(IPOD_MINI) || defined(IPOD_MINI2G)
38 /* GPIO D bit 3 is usb detect */
39 #define USB_GPIO GPIOD
40 #define USB_GPIO_MASK 0x08
41 #define USB_GPIO_VAL 0x08
43 #elif defined(IPOD_NANO) || defined(IPOD_VIDEO)
44 /* GPIO L bit 4 is usb detect */
45 #define USB_GPIO GPIOL
46 #define USB_GPIO_MASK 0x10
47 #define USB_GPIO_VAL 0x10
49 #elif defined(SANSA_C200)
50 /* GPIO H bit 1 is usb/charger detect */
51 #define USB_GPIO GPIOH
52 #define USB_GPIO_MASK 0x02
53 #define USB_GPIO_VAL 0x02
55 #elif defined(SANSA_E200)
56 /* GPIO B bit 4 is usb/charger detect */
57 #define USB_GPIO GPIOB
58 #define USB_GPIO_MASK 0x10
59 #define USB_GPIO_VAL 0x10
61 #elif defined(IRIVER_H10) || defined(IRIVER_H10_5GB) || defined(MROBE_100)
62 /* GPIO L bit 2 is usb detect */
63 #define USB_GPIO GPIOL
64 #define USB_GPIO_MASK 0x04
65 #define USB_GPIO_VAL 0x04
67 #elif defined(PHILIPS_SA9200)
68 /* GPIO B bit 6 (high) is usb bus power detect */
69 #define USB_GPIO GPIOB
70 #define USB_GPIO_MASK 0x40
71 #define USB_GPIO_VAL 0x40
73 #elif defined(PHILIPS_HDD1630) || defined(PHILIPS_HDD6330)
74 /* GPIO E bit 2 is usb detect */
75 #define USB_GPIO GPIOE
76 #define USB_GPIO_MASK 0x04
77 #define USB_GPIO_VAL 0x04
79 #elif defined(SAMSUNG_YH820) || defined(SAMSUNG_YH920) || defined(SAMSUNG_YH925)
80 /* GPIO D bit 4 is usb detect */
81 #define USB_GPIO GPIOD
82 #define USB_GPIO_MASK 0x10
83 #define USB_GPIO_VAL 0x10
85 #elif defined(TATUNG_TPJ1022)
86 /* GPIO ? bit ? is usb detect (dummy value)*/
87 #define USB_GPIO GPIOD
88 #define USB_GPIO_MASK 0x10
89 #define USB_GPIO_VAL 0x10
91 #elif defined(PBELL_VIBE500)
92 /* GPIO L bit 3 is usb detect */
93 #define USB_GPIO GPIOL
94 #define USB_GPIO_MASK 0x04
95 #define USB_GPIO_VAL 0x04
97 #else
98 #error No USB GPIO config specified
99 #endif
101 #define USB_GPIO_ENABLE GPIO_ENABLE(USB_GPIO)
102 #define USB_GPIO_OUTPUT_EN GPIO_OUTPUT_EN(USB_GPIO)
103 #define USB_GPIO_INPUT_VAL GPIO_INPUT_VAL(USB_GPIO)
104 #define USB_GPIO_INT_EN GPIO_INT_EN(USB_GPIO)
105 #define USB_GPIO_INT_LEV GPIO_INT_LEV(USB_GPIO)
106 #define USB_GPIO_INT_CLR GPIO_INT_CLR(USB_GPIO)
107 #define USB_GPIO_HI_INT_MASK GPIO_HI_INT_MASK(USB_GPIO)
109 static void usb_reset_controller(void)
111 /* enable usb module */
112 outl(inl(0x7000002C) | 0x3000000, 0x7000002C);
114 DEV_EN |= DEV_USB0;
115 DEV_EN |= DEV_USB1;
117 /* reset both USBs */
118 DEV_RS |= DEV_USB0;
119 DEV_RS &=~DEV_USB0;
120 DEV_RS |= DEV_USB1;
121 DEV_RS &=~DEV_USB1;
123 DEV_INIT2 |= INIT_USB;
125 while ((inl(0x70000028) & 0x80) == 0);
126 outl(inl(0x70000028) | 0x2, 0x70000028);
127 udelay(100000);
128 XMB_RAM_CFG |= 0x47A;
130 /* disable USB-devices until USB is detected via GPIO */
131 #ifndef BOOTLOADER
132 /* Disabling USB0 in the bootloader makes the OF not load,
133 Also something here breaks usb pin detect in bootloader.
134 leave it all enabled untill rockbox main loads */
135 DEV_EN &= ~DEV_USB0;
136 DEV_EN &= ~DEV_USB1;
137 DEV_INIT2 &= ~INIT_USB;
138 #endif
141 /* Enable raw status pin read only - not interrupt */
142 void usb_pin_init(void)
144 GPIO_CLEAR_BITWISE(USB_GPIO_OUTPUT_EN, USB_GPIO_MASK);
145 GPIO_SET_BITWISE(USB_GPIO_ENABLE, USB_GPIO_MASK);
146 #ifdef USB_FIREWIRE_HANDLING
147 /* GPIO C bit 1 is firewire detect */
148 GPIO_CLEAR_BITWISE(GPIOC_OUTPUT_EN, 0x02);
149 GPIO_SET_BITWISE(GPIOC_ENABLE, 0x02);
150 #endif
153 void usb_init_device(void)
155 usb_reset_controller();
157 /* Do one-time inits (no dependency on controller) */
158 usb_drv_startup();
160 usb_pin_init();
162 /* These set INT_LEV to the inserted level so it will fire if already
163 * inserted at the time they are enabled. */
164 #ifdef USB_STATUS_BY_EVENT
165 GPIO_CLEAR_BITWISE(USB_GPIO_INT_EN, USB_GPIO_MASK);
166 GPIO_WRITE_BITWISE(USB_GPIO_INT_LEV, USB_GPIO_VAL, USB_GPIO_MASK);
167 USB_GPIO_INT_CLR = USB_GPIO_MASK;
168 GPIO_SET_BITWISE(USB_GPIO_INT_EN, USB_GPIO_MASK);
169 CPU_HI_INT_EN = USB_GPIO_HI_INT_MASK;
171 #ifdef USB_FIREWIRE_HANDLING
172 /* GPIO C bit 1 is firewire detect */
173 GPIO_CLEAR_BITWISE(GPIOC_INT_EN, 0x02);
174 GPIO_WRITE_BITWISE(GPIOC_INT_LEV, 0x00, 0x02);
175 GPIOC_INT_CLR = 0x02;
176 GPIO_SET_BITWISE(GPIOC_INT_EN, 0x02);
177 CPU_HI_INT_EN = GPIO0_MASK;
178 #endif
179 CPU_INT_EN = HI_MASK;
180 #endif /* USB_STATUS_BY_EVENT */
183 void usb_enable(bool on)
185 if (on) {
186 /* if USB is detected, re-enable the USB-devices, otherwise make sure it's disabled */
187 DEV_EN |= DEV_USB0;
188 DEV_EN |= DEV_USB1;
189 DEV_INIT2 |= INIT_USB;
190 usb_core_init();
192 else {
193 usb_core_exit();
194 /* Disable USB devices */
195 usb_reset_controller();
199 void usb_attach(void)
201 usb_drv_attach();
204 bool usb_plugged(void)
206 return (USB_GPIO_INPUT_VAL & USB_GPIO_MASK) == USB_GPIO_VAL;
209 #ifdef USB_STATUS_BY_EVENT
210 /* Cannot always tell power pin from USB pin */
211 static int usb_status = USB_EXTRACTED;
213 static int usb_timeout_event(struct timeout *tmo)
215 usb_status_event(tmo->data == USB_GPIO_VAL ? USB_POWERED : USB_UNPOWERED);
216 return 0;
219 void usb_insert_int(void)
221 static struct timeout usb_oneshot;
222 unsigned long val = USB_GPIO_INPUT_VAL & USB_GPIO_MASK;
223 usb_status = (val == USB_GPIO_VAL) ? USB_INSERTED : USB_EXTRACTED;
224 GPIO_WRITE_BITWISE(USB_GPIO_INT_LEV, val ^ USB_GPIO_MASK, USB_GPIO_MASK);
225 USB_GPIO_INT_CLR = USB_GPIO_MASK;
226 timeout_register(&usb_oneshot, usb_timeout_event, HZ/5, val);
229 /* USB_DETECT_BY_DRV: Called during the bus reset interrupt when in detect mode
230 * USB_DETECT_BY_CORE: Called when device descriptor is requested
232 void usb_drv_usb_detect_event(void)
234 /* Filter for invalid bus reset when unplugging by checking the pin state. */
235 if(usb_plugged()) {
236 usb_status_event(USB_INSERTED);
239 #endif /* USB_STATUS_BY_EVENT */
241 #ifdef HAVE_BOOTLOADER_USB_MODE
242 /* Replacement function that returns all unused memory after the bootloader
243 * because the storage driver uses the audio buffer */
244 extern unsigned char freebuffer[];
245 extern unsigned char freebufferend[];
246 unsigned char *audio_get_buffer(bool talk_buf, size_t *buffer_size)
248 if (buffer_size)
249 *buffer_size = freebufferend - freebuffer + 1;
251 return freebuffer;
252 (void)talk_buf;
254 #endif /* HAVE_BOOTLOADER_USB_MODE */
256 void usb_drv_int_enable(bool enable)
258 /* enable/disable USB IRQ in CPU */
259 if(enable) {
260 CPU_INT_EN = USB_MASK;
262 else {
263 CPU_INT_DIS = USB_MASK;
267 /* detect host or charger (INSERTED or EXTRACTED) */
268 int usb_detect(void)
270 #ifdef USB_STATUS_BY_EVENT
271 return usb_status;
272 #else
273 return usb_plugged() ? USB_INSERTED : USB_EXTRACTED;
274 #endif
277 #ifdef USB_FIREWIRE_HANDLING
278 #ifdef USB_STATUS_BY_EVENT
279 static bool firewire_status = false;
280 #endif
282 bool firewire_detect(void)
284 #ifdef USB_STATUS_BY_EVENT
285 return firewire_status;
286 #else
287 /* GPIO C bit 1 is firewire detect */
288 /* no charger detection needed for firewire */
289 return (GPIOC_INPUT_VAL & 0x02) == 0x00;
290 #endif
293 #ifdef USB_STATUS_BY_EVENT
294 static int firewire_timeout_event(struct timeout *tmo)
296 if (tmo->data == 0x00)
297 usb_firewire_connect_event();
298 return 0;
301 void firewire_insert_int(void)
303 static struct timeout firewire_oneshot;
304 unsigned long val = GPIOC_INPUT_VAL & 0x02;
305 firewire_status = val == 0x00;
306 GPIO_WRITE_BITWISE(GPIOC_INT_LEV, val ^ 0x02, 0x02);
307 GPIOC_INT_CLR = 0x02;
308 timeout_register(&firewire_oneshot, firewire_timeout_event, HZ/5, val);
310 #endif /* USB_STATUS_BY_EVENT */
311 #endif /* USB_FIREWIRE_HANDLING */