diff options
Diffstat (limited to 'arch/arm/plat-omap/usb.c')
-rw-r--r-- | arch/arm/plat-omap/usb.c | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/arch/arm/plat-omap/usb.c b/arch/arm/plat-omap/usb.c new file mode 100644 index 00000000000..f3570884883 --- /dev/null +++ b/arch/arm/plat-omap/usb.c | |||
@@ -0,0 +1,143 @@ | |||
1 | /* | ||
2 | * arch/arm/plat-omap/usb.c -- platform level USB initialization | ||
3 | * | ||
4 | * Copyright (C) 2004 Texas Instruments, Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #undef DEBUG | ||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/platform_device.h> | ||
27 | #include <linux/io.h> | ||
28 | |||
29 | #include <plat/usb.h> | ||
30 | #include <plat/board.h> | ||
31 | |||
32 | #ifdef CONFIG_ARCH_OMAP_OTG | ||
33 | |||
34 | void __init | ||
35 | omap_otg_init(struct omap_usb_config *config) | ||
36 | { | ||
37 | u32 syscon; | ||
38 | int status; | ||
39 | int alt_pingroup = 0; | ||
40 | |||
41 | /* NOTE: no bus or clock setup (yet?) */ | ||
42 | |||
43 | syscon = omap_readl(OTG_SYSCON_1) & 0xffff; | ||
44 | if (!(syscon & OTG_RESET_DONE)) | ||
45 | pr_debug("USB resets not complete?\n"); | ||
46 | |||
47 | //omap_writew(0, OTG_IRQ_EN); | ||
48 | |||
49 | /* pin muxing and transceiver pinouts */ | ||
50 | if (config->pins[0] > 2) /* alt pingroup 2 */ | ||
51 | alt_pingroup = 1; | ||
52 | syscon |= config->usb0_init(config->pins[0], is_usb0_device(config)); | ||
53 | syscon |= config->usb1_init(config->pins[1]); | ||
54 | syscon |= config->usb2_init(config->pins[2], alt_pingroup); | ||
55 | pr_debug("OTG_SYSCON_1 = %08x\n", omap_readl(OTG_SYSCON_1)); | ||
56 | omap_writel(syscon, OTG_SYSCON_1); | ||
57 | |||
58 | syscon = config->hmc_mode; | ||
59 | syscon |= USBX_SYNCHRO | (4 << 16) /* B_ASE0_BRST */; | ||
60 | #ifdef CONFIG_USB_OTG | ||
61 | if (config->otg) | ||
62 | syscon |= OTG_EN; | ||
63 | #endif | ||
64 | if (cpu_class_is_omap1()) | ||
65 | pr_debug("USB_TRANSCEIVER_CTRL = %03x\n", | ||
66 | omap_readl(USB_TRANSCEIVER_CTRL)); | ||
67 | pr_debug("OTG_SYSCON_2 = %08x\n", omap_readl(OTG_SYSCON_2)); | ||
68 | omap_writel(syscon, OTG_SYSCON_2); | ||
69 | |||
70 | printk("USB: hmc %d", config->hmc_mode); | ||
71 | if (!alt_pingroup) | ||
72 | printk(", usb2 alt %d wires", config->pins[2]); | ||
73 | else if (config->pins[0]) | ||
74 | printk(", usb0 %d wires%s", config->pins[0], | ||
75 | is_usb0_device(config) ? " (dev)" : ""); | ||
76 | if (config->pins[1]) | ||
77 | printk(", usb1 %d wires", config->pins[1]); | ||
78 | if (!alt_pingroup && config->pins[2]) | ||
79 | printk(", usb2 %d wires", config->pins[2]); | ||
80 | if (config->otg) | ||
81 | printk(", Mini-AB on usb%d", config->otg - 1); | ||
82 | printk("\n"); | ||
83 | |||
84 | if (cpu_class_is_omap1()) { | ||
85 | u16 w; | ||
86 | |||
87 | /* leave USB clocks/controllers off until needed */ | ||
88 | w = omap_readw(ULPD_SOFT_REQ); | ||
89 | w &= ~SOFT_USB_CLK_REQ; | ||
90 | omap_writew(w, ULPD_SOFT_REQ); | ||
91 | |||
92 | w = omap_readw(ULPD_CLOCK_CTRL); | ||
93 | w &= ~USB_MCLK_EN; | ||
94 | w |= DIS_USB_PVCI_CLK; | ||
95 | omap_writew(w, ULPD_CLOCK_CTRL); | ||
96 | } | ||
97 | syscon = omap_readl(OTG_SYSCON_1); | ||
98 | syscon |= HST_IDLE_EN|DEV_IDLE_EN|OTG_IDLE_EN; | ||
99 | |||
100 | #ifdef CONFIG_USB_GADGET_OMAP | ||
101 | if (config->otg || config->register_dev) { | ||
102 | struct platform_device *udc_device = config->udc_device; | ||
103 | |||
104 | syscon &= ~DEV_IDLE_EN; | ||
105 | udc_device->dev.platform_data = config; | ||
106 | status = platform_device_register(udc_device); | ||
107 | if (status) | ||
108 | pr_debug("can't register UDC device, %d\n", status); | ||
109 | } | ||
110 | #endif | ||
111 | |||
112 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) | ||
113 | if (config->otg || config->register_host) { | ||
114 | struct platform_device *ohci_device = config->ohci_device; | ||
115 | |||
116 | syscon &= ~HST_IDLE_EN; | ||
117 | ohci_device->dev.platform_data = config; | ||
118 | status = platform_device_register(ohci_device); | ||
119 | if (status) | ||
120 | pr_debug("can't register OHCI device, %d\n", status); | ||
121 | } | ||
122 | #endif | ||
123 | |||
124 | #ifdef CONFIG_USB_OTG | ||
125 | if (config->otg) { | ||
126 | struct platform_device *otg_device = config->otg_device; | ||
127 | |||
128 | syscon &= ~OTG_IDLE_EN; | ||
129 | otg_device->dev.platform_data = config; | ||
130 | status = platform_device_register(otg_device); | ||
131 | if (status) | ||
132 | pr_debug("can't register OTG device, %d\n", status); | ||
133 | } | ||
134 | #endif | ||
135 | pr_debug("OTG_SYSCON_1 = %08x\n", omap_readl(OTG_SYSCON_1)); | ||
136 | omap_writel(syscon, OTG_SYSCON_1); | ||
137 | |||
138 | status = 0; | ||
139 | } | ||
140 | |||
141 | #else | ||
142 | void omap_otg_init(struct omap_usb_config *config) {} | ||
143 | #endif | ||