summaryrefslogtreecommitdiff
path: root/firmware/target/arm/usb-fw-pp502x.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/usb-fw-pp502x.c')
-rw-r--r--firmware/target/arm/usb-fw-pp502x.c215
1 files changed, 137 insertions, 78 deletions
diff --git a/firmware/target/arm/usb-fw-pp502x.c b/firmware/target/arm/usb-fw-pp502x.c
index 8a6d78675f..883ca1e8e2 100644
--- a/firmware/target/arm/usb-fw-pp502x.c
+++ b/firmware/target/arm/usb-fw-pp502x.c
@@ -33,6 +33,60 @@
33#include "usb_core.h" 33#include "usb_core.h"
34#include "usb_drv.h" 34#include "usb_drv.h"
35 35
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
42
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
48
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
54
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
60
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
66
67#elif defined(PHILIPS_SA9200)
68 /* GPIO F bit 7 (low) is usb detect */
69#define USB_GPIO GPIOF
70#define USB_GPIO_MASK 0x80
71#define USB_GPIO_VAL 0x00
72
73#elif defined(PHILIPS_HDD1630)
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
78#else
79#error No USB GPIO config specified
80#endif
81
82#define USB_GPIO_ENABLE GPIO_ENABLE(USB_GPIO)
83#define USB_GPIO_OUTPUT_EN GPIO_OUTPUT_EN(USB_GPIO)
84#define USB_GPIO_INPUT_VAL GPIO_INPUT_VAL(USB_GPIO)
85#define USB_GPIO_INT_EN GPIO_INT_EN(USB_GPIO)
86#define USB_GPIO_INT_LEV GPIO_INT_LEV(USB_GPIO)
87#define USB_GPIO_INT_CLR GPIO_INT_CLR(USB_GPIO)
88#define USB_GPIO_HI_INT_MASK GPIO_HI_INT_MASK(USB_GPIO)
89
36void usb_init_device(void) 90void usb_init_device(void)
37{ 91{
38 /* enable usb module */ 92 /* enable usb module */
@@ -52,7 +106,10 @@ void usb_init_device(void)
52 while ((inl(0x70000028) & 0x80) == 0); 106 while ((inl(0x70000028) & 0x80) == 0);
53 outl(inl(0x70000028) | 0x2, 0x70000028); 107 outl(inl(0x70000028) | 0x2, 0x70000028);
54 udelay(100000); 108 udelay(100000);
55 109
110 /* Do one-time inits */
111 usb_drv_startup();
112
56 /* disable USB-devices until USB is detected via GPIO */ 113 /* disable USB-devices until USB is detected via GPIO */
57#ifndef BOOTLOADER 114#ifndef BOOTLOADER
58 /* Disabling USB0 in the bootloader makes the OF not load, 115 /* Disabling USB0 in the bootloader makes the OF not load,
@@ -63,17 +120,38 @@ void usb_init_device(void)
63 DEV_INIT2 &= ~INIT_USB; 120 DEV_INIT2 &= ~INIT_USB;
64#endif 121#endif
65 122
66#if defined(IPOD_COLOR) || defined(IPOD_4G) \ 123 /* These set INV_LEV to the inserted level so it will fire if already
67 || defined(IPOD_MINI) || defined(IPOD_MINI2G) 124 * inserted at the time they are enabled. */
125#ifdef USB_STATUS_BY_EVENT
126 GPIO_CLEAR_BITWISE(USB_GPIO_INT_EN, USB_GPIO_MASK);
127 GPIO_CLEAR_BITWISE(USB_GPIO_OUTPUT_EN, USB_GPIO_MASK);
128 GPIO_SET_BITWISE(USB_GPIO_ENABLE, USB_GPIO_MASK);
129 GPIO_WRITE_BITWISE(USB_GPIO_INT_LEV, USB_GPIO_VAL, USB_GPIO_MASK);
130 USB_GPIO_INT_CLR = USB_GPIO_MASK;
131 GPIO_SET_BITWISE(USB_GPIO_INT_EN, USB_GPIO_MASK);
132 CPU_HI_INT_EN = USB_GPIO_HI_INT_MASK;
133
134#ifdef USB_FIREWIRE_HANDLING
68 /* GPIO C bit 1 is firewire detect */ 135 /* GPIO C bit 1 is firewire detect */
69 GPIOC_ENABLE |= 0x02; 136 GPIO_CLEAR_BITWISE(GPIOC_INT_EN, 0x02);
70 GPIOC_OUTPUT_EN &= ~0x02; 137 GPIO_CLEAR_BITWISE(GPIOC_OUTPUT_EN, 0x02);
138 GPIO_SET_BITWISE(GPIOC_ENABLE, 0x02);
139 GPIO_WRITE_BITWISE(GPIOC_INT_LEV, 0x00, 0x02);
140 GPIOC_INT_CLR = 0x02;
141 GPIO_SET_BITWISE(GPIOC_INT_EN, 0x02);
142 CPU_HI_INT_EN = GPIO0_MASK;
71#endif 143#endif
72 144 CPU_INT_EN = HI_MASK;
73#ifdef HAVE_USBSTACK 145#else
74 /* Do one-time inits */ 146 /* No interrupt - setup pin read only (BOOTLOADER) */
75 usb_drv_startup(); 147 GPIO_CLEAR_BITWISE(USB_GPIO_OUTPUT_EN, USB_GPIO_MASK);
148 GPIO_SET_BITWISE(USB_GPIO_ENABLE, USB_GPIO_MASK);
149#ifdef USB_FIREWIRE_HANDLING
150 /* GPIO C bit 1 is firewire detect */
151 GPIO_CLEAR_BITWISE(GPIOC_OUTPUT_EN, 0x02);
152 GPIO_SET_BITWISE(GPIOC_ENABLE, 0x02);
76#endif 153#endif
154#endif /* USB_STATUS_BY_EVENT */
77} 155}
78 156
79void usb_enable(bool on) 157void usb_enable(bool on)
@@ -96,21 +174,27 @@ void usb_enable(bool on)
96 174
97void usb_attach(void) 175void usb_attach(void)
98{ 176{
99#ifdef USB_DETECT_BY_DRV
100 usb_drv_attach(); 177 usb_drv_attach();
101#else
102 usb_enable(true);
103#endif
104} 178}
105 179
106#ifdef USB_DETECT_BY_DRV 180#ifdef USB_STATUS_BY_EVENT
107/* Cannot tell charger pin from USB pin */ 181/* Cannot always tell power pin from USB pin */
108static int usb_status = USB_EXTRACTED; 182static int usb_status = USB_EXTRACTED;
109 183
110void usb_connect_event(bool inserted) 184static int usb_timeout_event(struct timeout *tmo)
185{
186 usb_status_event(tmo->data == USB_GPIO_VAL ? USB_POWERED : USB_UNPOWERED);
187 return 0;
188}
189
190void usb_insert_int(void)
111{ 191{
112 usb_status = inserted ? USB_INSERTED : USB_EXTRACTED; 192 static struct timeout usb_oneshot;
113 usb_status_event(inserted ? USB_POWERED : USB_UNPOWERED); 193 unsigned long val = USB_GPIO_INPUT_VAL & USB_GPIO_MASK;
194 usb_status = (val == USB_GPIO_VAL) ? USB_INSERTED : USB_EXTRACTED;
195 GPIO_WRITE_BITWISE(USB_GPIO_INT_LEV, val ^ USB_GPIO_MASK, USB_GPIO_MASK);
196 USB_GPIO_INT_CLR = USB_GPIO_MASK;
197 timeout_register(&usb_oneshot, usb_timeout_event, HZ/5, val);
114} 198}
115 199
116/* Called during the bus reset interrupt when in detect mode */ 200/* Called during the bus reset interrupt when in detect mode */
@@ -118,51 +202,7 @@ void usb_drv_usb_detect_event(void)
118{ 202{
119 usb_status_event(USB_INSERTED); 203 usb_status_event(USB_INSERTED);
120} 204}
121#else /* !USB_DETECT_BY_DRV */ 205#endif /* USB_STATUS_BY_EVENT */
122static bool usb_pin_detect(void)
123{
124 bool retval = false;
125
126#if defined(IPOD_4G) || defined(IPOD_COLOR) \
127 || defined(IPOD_MINI) || defined(IPOD_MINI2G)
128 /* GPIO D bit 3 is usb detect */
129 if (GPIOD_INPUT_VAL & 0x08)
130 retval = true;
131
132#elif defined(IPOD_NANO) || defined(IPOD_VIDEO)
133 /* GPIO L bit 4 is usb detect */
134 if (GPIOL_INPUT_VAL & 0x10)
135 retval = true;
136
137#elif defined(SANSA_C200)
138 /* GPIO H bit 1 is usb/charger detect */
139 if (GPIOH_INPUT_VAL & 0x02)
140 retval = true;
141
142#elif defined(SANSA_E200)
143 /* GPIO B bit 4 is usb/charger detect */
144 if (GPIOB_INPUT_VAL & 0x10)
145 retval = true;
146
147#elif defined(IRIVER_H10) || defined(IRIVER_H10_5GB) || defined(MROBE_100)
148 /* GPIO L bit 2 is usb detect */
149 if (GPIOL_INPUT_VAL & 0x4)
150 retval = true;
151
152#elif defined(PHILIPS_SA9200)
153 /* GPIO F bit 7 is usb detect */
154 if (!(GPIOF_INPUT_VAL & 0x80))
155 retval = true;
156
157#elif defined(PHILIPS_HDD1630)
158 /* GPIO E bit 2 is usb detect */
159 if (GPIOE_INPUT_VAL & 0x4)
160 retval = true;
161#endif
162
163 return retval;
164}
165#endif /* USB_DETECT_BY_DRV */
166 206
167void usb_drv_int_enable(bool enable) 207void usb_drv_int_enable(bool enable)
168{ 208{
@@ -178,27 +218,46 @@ void usb_drv_int_enable(bool enable)
178/* detect host or charger (INSERTED or EXTRACTED) */ 218/* detect host or charger (INSERTED or EXTRACTED) */
179int usb_detect(void) 219int usb_detect(void)
180{ 220{
181#ifdef USB_DETECT_BY_DRV 221#ifdef USB_STATUS_BY_EVENT
182 return usb_status; 222 return usb_status;
183#else 223#else
184 if(usb_pin_detect()) { 224 return ((USB_GPIO_INPUT_VAL & USB_GPIO_MASK) == USB_GPIO_VAL) ?
185 return USB_INSERTED; 225 USB_INSERTED : USB_EXTRACTED;
186 }
187 else {
188 return USB_EXTRACTED;
189 }
190#endif 226#endif
191} 227}
192 228
193#if defined(IPOD_COLOR) || defined(IPOD_4G) \ 229#ifdef USB_FIREWIRE_HANDLING
194 || defined(IPOD_MINI) || defined(IPOD_MINI2G) 230#ifdef USB_STATUS_BY_EVENT
231static bool firewire_status = false;
232#endif
233
195bool firewire_detect(void) 234bool firewire_detect(void)
196{ 235{
236#ifdef USB_STATUS_BY_EVENT
237 return firewire_status;
238#else
197 /* GPIO C bit 1 is firewire detect */ 239 /* GPIO C bit 1 is firewire detect */
198 if (!(GPIOC_INPUT_VAL & 0x02)) 240 /* no charger detection needed for firewire */
199 /* no charger detection needed for firewire */ 241 return (GPIOC_INPUT_VAL & 0x02) == 0x00;
200 return true;
201 else
202 return false;
203}
204#endif 242#endif
243}
244
245#ifdef USB_STATUS_BY_EVENT
246static int firewire_timeout_event(struct timeout *tmo)
247{
248 if (tmo->data == 0x00)
249 usb_firewire_connect_event();
250 return 0;
251}
252
253void firewire_insert_int(void)
254{
255 static struct timeout firewire_oneshot;
256 unsigned long val = GPIOC_INPUT_VAL & 0x02;
257 firewire_status = val == 0x00;
258 GPIO_WRITE_BITWISE(GPIOC_INT_LEV, val ^ 0x02, 0x02);
259 GPIOC_INT_CLR = 0x02;
260 timeout_register(&firewire_oneshot, firewire_timeout_event, HZ/5, val);
261}
262#endif /* USB_STATUS_BY_EVENT */
263#endif /* USB_FIREWIRE_HANDLING */