diff options
Diffstat (limited to 'arch/arm/plat-omap/usb.c')
-rw-r--r-- | arch/arm/plat-omap/usb.c | 644 |
1 files changed, 16 insertions, 628 deletions
diff --git a/arch/arm/plat-omap/usb.c b/arch/arm/plat-omap/usb.c index d3bf17cd36f3..f3570884883e 100644 --- a/arch/arm/plat-omap/usb.c +++ b/arch/arm/plat-omap/usb.c | |||
@@ -22,524 +22,13 @@ | |||
22 | 22 | ||
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
25 | #include <linux/types.h> | ||
26 | #include <linux/errno.h> | ||
27 | #include <linux/init.h> | 25 | #include <linux/init.h> |
28 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
29 | #include <linux/usb/otg.h> | ||
30 | #include <linux/io.h> | 27 | #include <linux/io.h> |
31 | 28 | ||
32 | #include <asm/irq.h> | ||
33 | #include <asm/system.h> | ||
34 | #include <mach/hardware.h> | ||
35 | |||
36 | #include <plat/control.h> | ||
37 | #include <plat/mux.h> | ||
38 | #include <plat/usb.h> | 29 | #include <plat/usb.h> |
39 | #include <plat/board.h> | 30 | #include <plat/board.h> |
40 | 31 | ||
41 | #ifdef CONFIG_ARCH_OMAP1 | ||
42 | |||
43 | #define INT_USB_IRQ_GEN IH2_BASE + 20 | ||
44 | #define INT_USB_IRQ_NISO IH2_BASE + 30 | ||
45 | #define INT_USB_IRQ_ISO IH2_BASE + 29 | ||
46 | #define INT_USB_IRQ_HGEN INT_USB_HHC_1 | ||
47 | #define INT_USB_IRQ_OTG IH2_BASE + 8 | ||
48 | |||
49 | #else | ||
50 | |||
51 | #define INT_USB_IRQ_GEN INT_24XX_USB_IRQ_GEN | ||
52 | #define INT_USB_IRQ_NISO INT_24XX_USB_IRQ_NISO | ||
53 | #define INT_USB_IRQ_ISO INT_24XX_USB_IRQ_ISO | ||
54 | #define INT_USB_IRQ_HGEN INT_24XX_USB_IRQ_HGEN | ||
55 | #define INT_USB_IRQ_OTG INT_24XX_USB_IRQ_OTG | ||
56 | |||
57 | #endif | ||
58 | |||
59 | |||
60 | /* These routines should handle the standard chip-specific modes | ||
61 | * for usb0/1/2 ports, covering basic mux and transceiver setup. | ||
62 | * | ||
63 | * Some board-*.c files will need to set up additional mux options, | ||
64 | * like for suspend handling, vbus sensing, GPIOs, and the D+ pullup. | ||
65 | */ | ||
66 | |||
67 | /* TESTED ON: | ||
68 | * - 1611B H2 (with usb1 mini-AB) using standard Mini-B or OTG cables | ||
69 | * - 5912 OSK OHCI (with usb0 standard-A), standard A-to-B cables | ||
70 | * - 5912 OSK UDC, with *nonstandard* A-to-A cable | ||
71 | * - 1510 Innovator UDC with bundled usb0 cable | ||
72 | * - 1510 Innovator OHCI with bundled usb1/usb2 cable | ||
73 | * - 1510 Innovator OHCI with custom usb0 cable, feeding 5V VBUS | ||
74 | * - 1710 custom development board using alternate pin group | ||
75 | * - 1710 H3 (with usb1 mini-AB) using standard Mini-B or OTG cables | ||
76 | */ | ||
77 | |||
78 | /*-------------------------------------------------------------------------*/ | ||
79 | |||
80 | #if defined(CONFIG_ARCH_OMAP_OTG) || defined(CONFIG_ARCH_OMAP15XX) | ||
81 | |||
82 | static void omap2_usb_devconf_clear(u8 port, u32 mask) | ||
83 | { | ||
84 | u32 r; | ||
85 | |||
86 | r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); | ||
87 | r &= ~USBTXWRMODEI(port, mask); | ||
88 | omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0); | ||
89 | } | ||
90 | |||
91 | static void omap2_usb_devconf_set(u8 port, u32 mask) | ||
92 | { | ||
93 | u32 r; | ||
94 | |||
95 | r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); | ||
96 | r |= USBTXWRMODEI(port, mask); | ||
97 | omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0); | ||
98 | } | ||
99 | |||
100 | static void omap2_usb2_disable_5pinbitll(void) | ||
101 | { | ||
102 | u32 r; | ||
103 | |||
104 | r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); | ||
105 | r &= ~(USBTXWRMODEI(2, USB_BIDIR_TLL) | USBT2TLL5PI); | ||
106 | omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0); | ||
107 | } | ||
108 | |||
109 | static void omap2_usb2_enable_5pinunitll(void) | ||
110 | { | ||
111 | u32 r; | ||
112 | |||
113 | r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); | ||
114 | r |= USBTXWRMODEI(2, USB_UNIDIR_TLL) | USBT2TLL5PI; | ||
115 | omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0); | ||
116 | } | ||
117 | |||
118 | static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device) | ||
119 | { | ||
120 | u32 syscon1 = 0; | ||
121 | |||
122 | if (cpu_is_omap24xx()) | ||
123 | omap2_usb_devconf_clear(0, USB_BIDIR_TLL); | ||
124 | |||
125 | if (nwires == 0) { | ||
126 | if (cpu_class_is_omap1() && !cpu_is_omap15xx()) { | ||
127 | u32 l; | ||
128 | |||
129 | /* pulldown D+/D- */ | ||
130 | l = omap_readl(USB_TRANSCEIVER_CTRL); | ||
131 | l &= ~(3 << 1); | ||
132 | omap_writel(l, USB_TRANSCEIVER_CTRL); | ||
133 | } | ||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | if (is_device) { | ||
138 | if (cpu_is_omap24xx()) | ||
139 | omap_cfg_reg(J20_24XX_USB0_PUEN); | ||
140 | else if (cpu_is_omap7xx()) { | ||
141 | omap_cfg_reg(AA17_7XX_USB_DM); | ||
142 | omap_cfg_reg(W16_7XX_USB_PU_EN); | ||
143 | omap_cfg_reg(W17_7XX_USB_VBUSI); | ||
144 | omap_cfg_reg(W18_7XX_USB_DMCK_OUT); | ||
145 | omap_cfg_reg(W19_7XX_USB_DCRST); | ||
146 | } else | ||
147 | omap_cfg_reg(W4_USB_PUEN); | ||
148 | } | ||
149 | |||
150 | /* internal transceiver (unavailable on 17xx, 24xx) */ | ||
151 | if (!cpu_class_is_omap2() && nwires == 2) { | ||
152 | u32 l; | ||
153 | |||
154 | // omap_cfg_reg(P9_USB_DP); | ||
155 | // omap_cfg_reg(R8_USB_DM); | ||
156 | |||
157 | if (cpu_is_omap15xx()) { | ||
158 | /* This works on 1510-Innovator */ | ||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | /* NOTES: | ||
163 | * - peripheral should configure VBUS detection! | ||
164 | * - only peripherals may use the internal D+/D- pulldowns | ||
165 | * - OTG support on this port not yet written | ||
166 | */ | ||
167 | |||
168 | /* Don't do this for omap7xx -- it causes USB to not work correctly */ | ||
169 | if (!cpu_is_omap7xx()) { | ||
170 | l = omap_readl(USB_TRANSCEIVER_CTRL); | ||
171 | l &= ~(7 << 4); | ||
172 | if (!is_device) | ||
173 | l |= (3 << 1); | ||
174 | omap_writel(l, USB_TRANSCEIVER_CTRL); | ||
175 | } | ||
176 | |||
177 | return 3 << 16; | ||
178 | } | ||
179 | |||
180 | /* alternate pin config, external transceiver */ | ||
181 | if (cpu_is_omap15xx()) { | ||
182 | printk(KERN_ERR "no usb0 alt pin config on 15xx\n"); | ||
183 | return 0; | ||
184 | } | ||
185 | |||
186 | if (cpu_is_omap24xx()) { | ||
187 | omap_cfg_reg(K18_24XX_USB0_DAT); | ||
188 | omap_cfg_reg(K19_24XX_USB0_TXEN); | ||
189 | omap_cfg_reg(J14_24XX_USB0_SE0); | ||
190 | if (nwires != 3) | ||
191 | omap_cfg_reg(J18_24XX_USB0_RCV); | ||
192 | } else { | ||
193 | omap_cfg_reg(V6_USB0_TXD); | ||
194 | omap_cfg_reg(W9_USB0_TXEN); | ||
195 | omap_cfg_reg(W5_USB0_SE0); | ||
196 | if (nwires != 3) | ||
197 | omap_cfg_reg(Y5_USB0_RCV); | ||
198 | } | ||
199 | |||
200 | /* NOTE: SPEED and SUSP aren't configured here. OTG hosts | ||
201 | * may be able to use I2C requests to set those bits along | ||
202 | * with VBUS switching and overcurrent detection. | ||
203 | */ | ||
204 | |||
205 | if (cpu_class_is_omap1() && nwires != 6) { | ||
206 | u32 l; | ||
207 | |||
208 | l = omap_readl(USB_TRANSCEIVER_CTRL); | ||
209 | l &= ~CONF_USB2_UNI_R; | ||
210 | omap_writel(l, USB_TRANSCEIVER_CTRL); | ||
211 | } | ||
212 | |||
213 | switch (nwires) { | ||
214 | case 3: | ||
215 | syscon1 = 2; | ||
216 | if (cpu_is_omap24xx()) | ||
217 | omap2_usb_devconf_set(0, USB_BIDIR); | ||
218 | break; | ||
219 | case 4: | ||
220 | syscon1 = 1; | ||
221 | if (cpu_is_omap24xx()) | ||
222 | omap2_usb_devconf_set(0, USB_BIDIR); | ||
223 | break; | ||
224 | case 6: | ||
225 | syscon1 = 3; | ||
226 | if (cpu_is_omap24xx()) { | ||
227 | omap_cfg_reg(J19_24XX_USB0_VP); | ||
228 | omap_cfg_reg(K20_24XX_USB0_VM); | ||
229 | omap2_usb_devconf_set(0, USB_UNIDIR); | ||
230 | } else { | ||
231 | u32 l; | ||
232 | |||
233 | omap_cfg_reg(AA9_USB0_VP); | ||
234 | omap_cfg_reg(R9_USB0_VM); | ||
235 | l = omap_readl(USB_TRANSCEIVER_CTRL); | ||
236 | l |= CONF_USB2_UNI_R; | ||
237 | omap_writel(l, USB_TRANSCEIVER_CTRL); | ||
238 | } | ||
239 | break; | ||
240 | default: | ||
241 | printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", | ||
242 | 0, nwires); | ||
243 | } | ||
244 | return syscon1 << 16; | ||
245 | } | ||
246 | |||
247 | static u32 __init omap_usb1_init(unsigned nwires) | ||
248 | { | ||
249 | u32 syscon1 = 0; | ||
250 | |||
251 | if (cpu_class_is_omap1() && !cpu_is_omap15xx() && nwires != 6) { | ||
252 | u32 l; | ||
253 | |||
254 | l = omap_readl(USB_TRANSCEIVER_CTRL); | ||
255 | l &= ~CONF_USB1_UNI_R; | ||
256 | omap_writel(l, USB_TRANSCEIVER_CTRL); | ||
257 | } | ||
258 | if (cpu_is_omap24xx()) | ||
259 | omap2_usb_devconf_clear(1, USB_BIDIR_TLL); | ||
260 | |||
261 | if (nwires == 0) | ||
262 | return 0; | ||
263 | |||
264 | /* external transceiver */ | ||
265 | if (cpu_class_is_omap1()) { | ||
266 | omap_cfg_reg(USB1_TXD); | ||
267 | omap_cfg_reg(USB1_TXEN); | ||
268 | if (nwires != 3) | ||
269 | omap_cfg_reg(USB1_RCV); | ||
270 | } | ||
271 | |||
272 | if (cpu_is_omap15xx()) { | ||
273 | omap_cfg_reg(USB1_SEO); | ||
274 | omap_cfg_reg(USB1_SPEED); | ||
275 | // SUSP | ||
276 | } else if (cpu_is_omap1610() || cpu_is_omap5912()) { | ||
277 | omap_cfg_reg(W13_1610_USB1_SE0); | ||
278 | omap_cfg_reg(R13_1610_USB1_SPEED); | ||
279 | // SUSP | ||
280 | } else if (cpu_is_omap1710()) { | ||
281 | omap_cfg_reg(R13_1710_USB1_SE0); | ||
282 | // SUSP | ||
283 | } else if (cpu_is_omap24xx()) { | ||
284 | /* NOTE: board-specific code must set up pin muxing for usb1, | ||
285 | * since each signal could come out on either of two balls. | ||
286 | */ | ||
287 | } else { | ||
288 | pr_debug("usb%d cpu unrecognized\n", 1); | ||
289 | return 0; | ||
290 | } | ||
291 | |||
292 | switch (nwires) { | ||
293 | case 2: | ||
294 | if (!cpu_is_omap24xx()) | ||
295 | goto bad; | ||
296 | /* NOTE: board-specific code must override this setting if | ||
297 | * this TLL link is not using DP/DM | ||
298 | */ | ||
299 | syscon1 = 1; | ||
300 | omap2_usb_devconf_set(1, USB_BIDIR_TLL); | ||
301 | break; | ||
302 | case 3: | ||
303 | syscon1 = 2; | ||
304 | if (cpu_is_omap24xx()) | ||
305 | omap2_usb_devconf_set(1, USB_BIDIR); | ||
306 | break; | ||
307 | case 4: | ||
308 | syscon1 = 1; | ||
309 | if (cpu_is_omap24xx()) | ||
310 | omap2_usb_devconf_set(1, USB_BIDIR); | ||
311 | break; | ||
312 | case 6: | ||
313 | if (cpu_is_omap24xx()) | ||
314 | goto bad; | ||
315 | syscon1 = 3; | ||
316 | omap_cfg_reg(USB1_VP); | ||
317 | omap_cfg_reg(USB1_VM); | ||
318 | if (!cpu_is_omap15xx()) { | ||
319 | u32 l; | ||
320 | |||
321 | l = omap_readl(USB_TRANSCEIVER_CTRL); | ||
322 | l |= CONF_USB1_UNI_R; | ||
323 | omap_writel(l, USB_TRANSCEIVER_CTRL); | ||
324 | } | ||
325 | break; | ||
326 | default: | ||
327 | bad: | ||
328 | printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", | ||
329 | 1, nwires); | ||
330 | } | ||
331 | return syscon1 << 20; | ||
332 | } | ||
333 | |||
334 | static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup) | ||
335 | { | ||
336 | u32 syscon1 = 0; | ||
337 | |||
338 | if (cpu_is_omap24xx()) { | ||
339 | omap2_usb2_disable_5pinbitll(); | ||
340 | alt_pingroup = 0; | ||
341 | } | ||
342 | |||
343 | /* NOTE omap1 erratum: must leave USB2_UNI_R set if usb0 in use */ | ||
344 | if (alt_pingroup || nwires == 0) | ||
345 | return 0; | ||
346 | |||
347 | if (cpu_class_is_omap1() && !cpu_is_omap15xx() && nwires != 6) { | ||
348 | u32 l; | ||
349 | |||
350 | l = omap_readl(USB_TRANSCEIVER_CTRL); | ||
351 | l &= ~CONF_USB2_UNI_R; | ||
352 | omap_writel(l, USB_TRANSCEIVER_CTRL); | ||
353 | } | ||
354 | |||
355 | /* external transceiver */ | ||
356 | if (cpu_is_omap15xx()) { | ||
357 | omap_cfg_reg(USB2_TXD); | ||
358 | omap_cfg_reg(USB2_TXEN); | ||
359 | omap_cfg_reg(USB2_SEO); | ||
360 | if (nwires != 3) | ||
361 | omap_cfg_reg(USB2_RCV); | ||
362 | /* there is no USB2_SPEED */ | ||
363 | } else if (cpu_is_omap16xx()) { | ||
364 | omap_cfg_reg(V6_USB2_TXD); | ||
365 | omap_cfg_reg(W9_USB2_TXEN); | ||
366 | omap_cfg_reg(W5_USB2_SE0); | ||
367 | if (nwires != 3) | ||
368 | omap_cfg_reg(Y5_USB2_RCV); | ||
369 | // FIXME omap_cfg_reg(USB2_SPEED); | ||
370 | } else if (cpu_is_omap24xx()) { | ||
371 | omap_cfg_reg(Y11_24XX_USB2_DAT); | ||
372 | omap_cfg_reg(AA10_24XX_USB2_SE0); | ||
373 | if (nwires > 2) | ||
374 | omap_cfg_reg(AA12_24XX_USB2_TXEN); | ||
375 | if (nwires > 3) | ||
376 | omap_cfg_reg(AA6_24XX_USB2_RCV); | ||
377 | } else { | ||
378 | pr_debug("usb%d cpu unrecognized\n", 1); | ||
379 | return 0; | ||
380 | } | ||
381 | // if (cpu_class_is_omap1()) omap_cfg_reg(USB2_SUSP); | ||
382 | |||
383 | switch (nwires) { | ||
384 | case 2: | ||
385 | if (!cpu_is_omap24xx()) | ||
386 | goto bad; | ||
387 | /* NOTE: board-specific code must override this setting if | ||
388 | * this TLL link is not using DP/DM | ||
389 | */ | ||
390 | syscon1 = 1; | ||
391 | omap2_usb_devconf_set(2, USB_BIDIR_TLL); | ||
392 | break; | ||
393 | case 3: | ||
394 | syscon1 = 2; | ||
395 | if (cpu_is_omap24xx()) | ||
396 | omap2_usb_devconf_set(2, USB_BIDIR); | ||
397 | break; | ||
398 | case 4: | ||
399 | syscon1 = 1; | ||
400 | if (cpu_is_omap24xx()) | ||
401 | omap2_usb_devconf_set(2, USB_BIDIR); | ||
402 | break; | ||
403 | case 5: | ||
404 | if (!cpu_is_omap24xx()) | ||
405 | goto bad; | ||
406 | omap_cfg_reg(AA4_24XX_USB2_TLLSE0); | ||
407 | /* NOTE: board-specific code must override this setting if | ||
408 | * this TLL link is not using DP/DM. Something must also | ||
409 | * set up OTG_SYSCON2.HMC_TLL{ATTACH,SPEED} | ||
410 | */ | ||
411 | syscon1 = 3; | ||
412 | omap2_usb2_enable_5pinunitll(); | ||
413 | break; | ||
414 | case 6: | ||
415 | if (cpu_is_omap24xx()) | ||
416 | goto bad; | ||
417 | syscon1 = 3; | ||
418 | if (cpu_is_omap15xx()) { | ||
419 | omap_cfg_reg(USB2_VP); | ||
420 | omap_cfg_reg(USB2_VM); | ||
421 | } else { | ||
422 | u32 l; | ||
423 | |||
424 | omap_cfg_reg(AA9_USB2_VP); | ||
425 | omap_cfg_reg(R9_USB2_VM); | ||
426 | l = omap_readl(USB_TRANSCEIVER_CTRL); | ||
427 | l |= CONF_USB2_UNI_R; | ||
428 | omap_writel(l, USB_TRANSCEIVER_CTRL); | ||
429 | } | ||
430 | break; | ||
431 | default: | ||
432 | bad: | ||
433 | printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", | ||
434 | 2, nwires); | ||
435 | } | ||
436 | return syscon1 << 24; | ||
437 | } | ||
438 | |||
439 | #endif | ||
440 | |||
441 | /*-------------------------------------------------------------------------*/ | ||
442 | |||
443 | #ifdef CONFIG_USB_GADGET_OMAP | ||
444 | |||
445 | static struct resource udc_resources[] = { | ||
446 | /* order is significant! */ | ||
447 | { /* registers */ | ||
448 | .start = UDC_BASE, | ||
449 | .end = UDC_BASE + 0xff, | ||
450 | .flags = IORESOURCE_MEM, | ||
451 | }, { /* general IRQ */ | ||
452 | .start = INT_USB_IRQ_GEN, | ||
453 | .flags = IORESOURCE_IRQ, | ||
454 | }, { /* PIO IRQ */ | ||
455 | .start = INT_USB_IRQ_NISO, | ||
456 | .flags = IORESOURCE_IRQ, | ||
457 | }, { /* SOF IRQ */ | ||
458 | .start = INT_USB_IRQ_ISO, | ||
459 | .flags = IORESOURCE_IRQ, | ||
460 | }, | ||
461 | }; | ||
462 | |||
463 | static u64 udc_dmamask = ~(u32)0; | ||
464 | |||
465 | static struct platform_device udc_device = { | ||
466 | .name = "omap_udc", | ||
467 | .id = -1, | ||
468 | .dev = { | ||
469 | .dma_mask = &udc_dmamask, | ||
470 | .coherent_dma_mask = 0xffffffff, | ||
471 | }, | ||
472 | .num_resources = ARRAY_SIZE(udc_resources), | ||
473 | .resource = udc_resources, | ||
474 | }; | ||
475 | |||
476 | #endif | ||
477 | |||
478 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) | ||
479 | |||
480 | /* The dmamask must be set for OHCI to work */ | ||
481 | static u64 ohci_dmamask = ~(u32)0; | ||
482 | |||
483 | static struct resource ohci_resources[] = { | ||
484 | { | ||
485 | .start = OMAP_OHCI_BASE, | ||
486 | .end = OMAP_OHCI_BASE + 0xff, | ||
487 | .flags = IORESOURCE_MEM, | ||
488 | }, | ||
489 | { | ||
490 | .start = INT_USB_IRQ_HGEN, | ||
491 | .flags = IORESOURCE_IRQ, | ||
492 | }, | ||
493 | }; | ||
494 | |||
495 | static struct platform_device ohci_device = { | ||
496 | .name = "ohci", | ||
497 | .id = -1, | ||
498 | .dev = { | ||
499 | .dma_mask = &ohci_dmamask, | ||
500 | .coherent_dma_mask = 0xffffffff, | ||
501 | }, | ||
502 | .num_resources = ARRAY_SIZE(ohci_resources), | ||
503 | .resource = ohci_resources, | ||
504 | }; | ||
505 | |||
506 | #endif | ||
507 | |||
508 | #if defined(CONFIG_USB_OTG) && defined(CONFIG_ARCH_OMAP_OTG) | ||
509 | |||
510 | static struct resource otg_resources[] = { | ||
511 | /* order is significant! */ | ||
512 | { | ||
513 | .start = OTG_BASE, | ||
514 | .end = OTG_BASE + 0xff, | ||
515 | .flags = IORESOURCE_MEM, | ||
516 | }, { | ||
517 | .start = INT_USB_IRQ_OTG, | ||
518 | .flags = IORESOURCE_IRQ, | ||
519 | }, | ||
520 | }; | ||
521 | |||
522 | static struct platform_device otg_device = { | ||
523 | .name = "omap_otg", | ||
524 | .id = -1, | ||
525 | .num_resources = ARRAY_SIZE(otg_resources), | ||
526 | .resource = otg_resources, | ||
527 | }; | ||
528 | |||
529 | #endif | ||
530 | |||
531 | /*-------------------------------------------------------------------------*/ | ||
532 | |||
533 | // FIXME correct answer depends on hmc_mode, | ||
534 | // as does (on omap1) any nonzero value for config->otg port number | ||
535 | #ifdef CONFIG_USB_GADGET_OMAP | ||
536 | #define is_usb0_device(config) 1 | ||
537 | #else | ||
538 | #define is_usb0_device(config) 0 | ||
539 | #endif | ||
540 | |||
541 | /*-------------------------------------------------------------------------*/ | ||
542 | |||
543 | #ifdef CONFIG_ARCH_OMAP_OTG | 32 | #ifdef CONFIG_ARCH_OMAP_OTG |
544 | 33 | ||
545 | void __init | 34 | void __init |
@@ -560,9 +49,9 @@ omap_otg_init(struct omap_usb_config *config) | |||
560 | /* pin muxing and transceiver pinouts */ | 49 | /* pin muxing and transceiver pinouts */ |
561 | if (config->pins[0] > 2) /* alt pingroup 2 */ | 50 | if (config->pins[0] > 2) /* alt pingroup 2 */ |
562 | alt_pingroup = 1; | 51 | alt_pingroup = 1; |
563 | syscon |= omap_usb0_init(config->pins[0], is_usb0_device(config)); | 52 | syscon |= config->usb0_init(config->pins[0], is_usb0_device(config)); |
564 | syscon |= omap_usb1_init(config->pins[1]); | 53 | syscon |= config->usb1_init(config->pins[1]); |
565 | syscon |= omap_usb2_init(config->pins[2], alt_pingroup); | 54 | syscon |= config->usb2_init(config->pins[2], alt_pingroup); |
566 | pr_debug("OTG_SYSCON_1 = %08x\n", omap_readl(OTG_SYSCON_1)); | 55 | pr_debug("OTG_SYSCON_1 = %08x\n", omap_readl(OTG_SYSCON_1)); |
567 | omap_writel(syscon, OTG_SYSCON_1); | 56 | omap_writel(syscon, OTG_SYSCON_1); |
568 | 57 | ||
@@ -610,15 +99,11 @@ omap_otg_init(struct omap_usb_config *config) | |||
610 | 99 | ||
611 | #ifdef CONFIG_USB_GADGET_OMAP | 100 | #ifdef CONFIG_USB_GADGET_OMAP |
612 | if (config->otg || config->register_dev) { | 101 | if (config->otg || config->register_dev) { |
102 | struct platform_device *udc_device = config->udc_device; | ||
103 | |||
613 | syscon &= ~DEV_IDLE_EN; | 104 | syscon &= ~DEV_IDLE_EN; |
614 | udc_device.dev.platform_data = config; | 105 | udc_device->dev.platform_data = config; |
615 | /* IRQ numbers for omap7xx */ | 106 | status = platform_device_register(udc_device); |
616 | if(cpu_is_omap7xx()) { | ||
617 | udc_resources[1].start = INT_7XX_USB_GENI; | ||
618 | udc_resources[2].start = INT_7XX_USB_NON_ISO; | ||
619 | udc_resources[3].start = INT_7XX_USB_ISO; | ||
620 | } | ||
621 | status = platform_device_register(&udc_device); | ||
622 | if (status) | 107 | if (status) |
623 | pr_debug("can't register UDC device, %d\n", status); | 108 | pr_debug("can't register UDC device, %d\n", status); |
624 | } | 109 | } |
@@ -626,11 +111,11 @@ omap_otg_init(struct omap_usb_config *config) | |||
626 | 111 | ||
627 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) | 112 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) |
628 | if (config->otg || config->register_host) { | 113 | if (config->otg || config->register_host) { |
114 | struct platform_device *ohci_device = config->ohci_device; | ||
115 | |||
629 | syscon &= ~HST_IDLE_EN; | 116 | syscon &= ~HST_IDLE_EN; |
630 | ohci_device.dev.platform_data = config; | 117 | ohci_device->dev.platform_data = config; |
631 | if (cpu_is_omap7xx()) | 118 | status = platform_device_register(ohci_device); |
632 | ohci_resources[1].start = INT_7XX_USB_HHC_1; | ||
633 | status = platform_device_register(&ohci_device); | ||
634 | if (status) | 119 | if (status) |
635 | pr_debug("can't register OHCI device, %d\n", status); | 120 | pr_debug("can't register OHCI device, %d\n", status); |
636 | } | 121 | } |
@@ -638,11 +123,11 @@ omap_otg_init(struct omap_usb_config *config) | |||
638 | 123 | ||
639 | #ifdef CONFIG_USB_OTG | 124 | #ifdef CONFIG_USB_OTG |
640 | if (config->otg) { | 125 | if (config->otg) { |
126 | struct platform_device *otg_device = config->otg_device; | ||
127 | |||
641 | syscon &= ~OTG_IDLE_EN; | 128 | syscon &= ~OTG_IDLE_EN; |
642 | otg_device.dev.platform_data = config; | 129 | otg_device->dev.platform_data = config; |
643 | if (cpu_is_omap7xx()) | 130 | status = platform_device_register(otg_device); |
644 | otg_resources[1].start = INT_7XX_USB_OTG; | ||
645 | status = platform_device_register(&otg_device); | ||
646 | if (status) | 131 | if (status) |
647 | pr_debug("can't register OTG device, %d\n", status); | 132 | pr_debug("can't register OTG device, %d\n", status); |
648 | } | 133 | } |
@@ -654,102 +139,5 @@ omap_otg_init(struct omap_usb_config *config) | |||
654 | } | 139 | } |
655 | 140 | ||
656 | #else | 141 | #else |
657 | static inline void omap_otg_init(struct omap_usb_config *config) {} | 142 | void omap_otg_init(struct omap_usb_config *config) {} |
658 | #endif | ||
659 | |||
660 | /*-------------------------------------------------------------------------*/ | ||
661 | |||
662 | #ifdef CONFIG_ARCH_OMAP15XX | ||
663 | |||
664 | /* ULPD_DPLL_CTRL */ | ||
665 | #define DPLL_IOB (1 << 13) | ||
666 | #define DPLL_PLL_ENABLE (1 << 4) | ||
667 | #define DPLL_LOCK (1 << 0) | ||
668 | |||
669 | /* ULPD_APLL_CTRL */ | ||
670 | #define APLL_NDPLL_SWITCH (1 << 0) | ||
671 | |||
672 | |||
673 | static void __init omap_1510_usb_init(struct omap_usb_config *config) | ||
674 | { | ||
675 | unsigned int val; | ||
676 | u16 w; | ||
677 | |||
678 | omap_usb0_init(config->pins[0], is_usb0_device(config)); | ||
679 | omap_usb1_init(config->pins[1]); | ||
680 | omap_usb2_init(config->pins[2], 0); | ||
681 | |||
682 | val = omap_readl(MOD_CONF_CTRL_0) & ~(0x3f << 1); | ||
683 | val |= (config->hmc_mode << 1); | ||
684 | omap_writel(val, MOD_CONF_CTRL_0); | ||
685 | |||
686 | printk("USB: hmc %d", config->hmc_mode); | ||
687 | if (config->pins[0]) | ||
688 | printk(", usb0 %d wires%s", config->pins[0], | ||
689 | is_usb0_device(config) ? " (dev)" : ""); | ||
690 | if (config->pins[1]) | ||
691 | printk(", usb1 %d wires", config->pins[1]); | ||
692 | if (config->pins[2]) | ||
693 | printk(", usb2 %d wires", config->pins[2]); | ||
694 | printk("\n"); | ||
695 | |||
696 | /* use DPLL for 48 MHz function clock */ | ||
697 | pr_debug("APLL %04x DPLL %04x REQ %04x\n", omap_readw(ULPD_APLL_CTRL), | ||
698 | omap_readw(ULPD_DPLL_CTRL), omap_readw(ULPD_SOFT_REQ)); | ||
699 | |||
700 | w = omap_readw(ULPD_APLL_CTRL); | ||
701 | w &= ~APLL_NDPLL_SWITCH; | ||
702 | omap_writew(w, ULPD_APLL_CTRL); | ||
703 | |||
704 | w = omap_readw(ULPD_DPLL_CTRL); | ||
705 | w |= DPLL_IOB | DPLL_PLL_ENABLE; | ||
706 | omap_writew(w, ULPD_DPLL_CTRL); | ||
707 | |||
708 | w = omap_readw(ULPD_SOFT_REQ); | ||
709 | w |= SOFT_UDC_REQ | SOFT_DPLL_REQ; | ||
710 | omap_writew(w, ULPD_SOFT_REQ); | ||
711 | |||
712 | while (!(omap_readw(ULPD_DPLL_CTRL) & DPLL_LOCK)) | ||
713 | cpu_relax(); | ||
714 | |||
715 | #ifdef CONFIG_USB_GADGET_OMAP | ||
716 | if (config->register_dev) { | ||
717 | int status; | ||
718 | |||
719 | udc_device.dev.platform_data = config; | ||
720 | status = platform_device_register(&udc_device); | ||
721 | if (status) | ||
722 | pr_debug("can't register UDC device, %d\n", status); | ||
723 | /* udc driver gates 48MHz by D+ pullup */ | ||
724 | } | ||
725 | #endif | ||
726 | |||
727 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) | ||
728 | if (config->register_host) { | ||
729 | int status; | ||
730 | |||
731 | ohci_device.dev.platform_data = config; | ||
732 | status = platform_device_register(&ohci_device); | ||
733 | if (status) | ||
734 | pr_debug("can't register OHCI device, %d\n", status); | ||
735 | /* hcd explicitly gates 48MHz */ | ||
736 | } | ||
737 | #endif | ||
738 | } | ||
739 | |||
740 | #else | ||
741 | static inline void omap_1510_usb_init(struct omap_usb_config *config) {} | ||
742 | #endif | 143 | #endif |
743 | |||
744 | /*-------------------------------------------------------------------------*/ | ||
745 | |||
746 | void __init omap_usb_init(struct omap_usb_config *pdata) | ||
747 | { | ||
748 | if (cpu_is_omap7xx() || cpu_is_omap16xx() || cpu_is_omap24xx()) | ||
749 | omap_otg_init(pdata); | ||
750 | else if (cpu_is_omap15xx()) | ||
751 | omap_1510_usb_init(pdata); | ||
752 | else | ||
753 | printk(KERN_ERR "USB: No init for your chip yet\n"); | ||
754 | } | ||
755 | |||