blob: 609b330e51109bb95d08bebc5cc03fa8d261cdbb [file] [log] [blame]
Felipe Balbi58a54912009-11-22 10:11:01 -08001/*
Felipe Balbia8480ea2011-03-01 20:08:15 +05302 * usb-host.c - OMAP USB Host
Felipe Balbi58a54912009-11-22 10:11:01 -08003 *
4 * This file will contain the board specific details for the
Felipe Balbia8480ea2011-03-01 20:08:15 +05305 * Synopsys EHCI/OHCI host controller on OMAP3430 and onwards
Felipe Balbi58a54912009-11-22 10:11:01 -08006 *
Felipe Balbia8480ea2011-03-01 20:08:15 +05307 * Copyright (C) 2007-2011 Texas Instruments
Felipe Balbi58a54912009-11-22 10:11:01 -08008 * Author: Vikram Pandita <vikram.pandita@ti.com>
Keshava Munegowda22363962011-03-01 20:08:18 +05309 * Author: Keshava Munegowda <keshava_mgowda@ti.com>
Felipe Balbi58a54912009-11-22 10:11:01 -080010 *
11 * Generalization by:
Felipe Balbia8480ea2011-03-01 20:08:15 +053012 * Felipe Balbi <balbi@ti.com>
Felipe Balbi58a54912009-11-22 10:11:01 -080013 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 */
18
19#include <linux/types.h>
20#include <linux/errno.h>
21#include <linux/delay.h>
22#include <linux/platform_device.h>
Keshava Munegowda22363962011-03-01 20:08:18 +053023#include <linux/slab.h>
Amit Kucheriabfb01192010-06-09 13:53:05 +030024#include <linux/dma-mapping.h>
Roger Quadros5ecd52e2013-03-20 17:44:41 +020025#include <linux/regulator/machine.h>
26#include <linux/regulator/fixed.h>
27#include <linux/string.h>
28#include <linux/io.h>
29#include <linux/gpio.h>
30#include <linux/usb/phy.h>
Roger Quadrose41a5f82013-05-24 16:06:58 +030031#include <linux/usb/nop-usb-xceiv.h>
Felipe Balbi58a54912009-11-22 10:11:01 -080032
Tony Lindgrene4c060d2012-10-05 13:25:59 -070033#include "soc.h"
Tony Lindgren25c7d492012-10-02 17:25:48 -070034#include "omap_device.h"
Tony Lindgren4896e392009-12-11 16:16:32 -080035#include "mux.h"
Tony Lindgren54db6ee2012-10-24 14:26:18 -070036#include "usb.h"
Tony Lindgren4896e392009-12-11 16:16:32 -080037
Keshava Munegowda22363962011-03-01 20:08:18 +053038#ifdef CONFIG_MFD_OMAP_USB_HOST
Felipe Balbi58a54912009-11-22 10:11:01 -080039
Keshava Munegowda50b2a9b2011-10-11 13:21:37 +053040#define OMAP_USBHS_DEVICE "usbhs_omap"
Keshava Munegowda760189b2012-07-16 19:01:10 +053041#define OMAP_USBTLL_DEVICE "usbhs_tll"
Keshava Munegowda50b2a9b2011-10-11 13:21:37 +053042#define USBHS_UHH_HWMODNAME "usb_host_hs"
43#define USBHS_TLL_HWMODNAME "usb_tll_hs"
Felipe Balbi58a54912009-11-22 10:11:01 -080044
45/* MUX settings for EHCI pins */
46/*
47 * setup_ehci_io_mux - initialize IO pad mux for USBHOST
48 */
Igor Grinberg1512f0d2012-03-26 16:51:10 +020049static void __init setup_ehci_io_mux(const enum usbhs_omap_port_mode *port_mode)
Felipe Balbi58a54912009-11-22 10:11:01 -080050{
51 switch (port_mode[0]) {
Keshava Munegowda181b2502011-03-01 20:08:16 +053052 case OMAP_EHCI_PORT_MODE_PHY:
Tony Lindgren4896e392009-12-11 16:16:32 -080053 omap_mux_init_signal("hsusb1_stp", OMAP_PIN_OUTPUT);
54 omap_mux_init_signal("hsusb1_clk", OMAP_PIN_OUTPUT);
55 omap_mux_init_signal("hsusb1_dir", OMAP_PIN_INPUT_PULLDOWN);
56 omap_mux_init_signal("hsusb1_nxt", OMAP_PIN_INPUT_PULLDOWN);
57 omap_mux_init_signal("hsusb1_data0", OMAP_PIN_INPUT_PULLDOWN);
58 omap_mux_init_signal("hsusb1_data1", OMAP_PIN_INPUT_PULLDOWN);
59 omap_mux_init_signal("hsusb1_data2", OMAP_PIN_INPUT_PULLDOWN);
60 omap_mux_init_signal("hsusb1_data3", OMAP_PIN_INPUT_PULLDOWN);
61 omap_mux_init_signal("hsusb1_data4", OMAP_PIN_INPUT_PULLDOWN);
62 omap_mux_init_signal("hsusb1_data5", OMAP_PIN_INPUT_PULLDOWN);
63 omap_mux_init_signal("hsusb1_data6", OMAP_PIN_INPUT_PULLDOWN);
64 omap_mux_init_signal("hsusb1_data7", OMAP_PIN_INPUT_PULLDOWN);
Felipe Balbi58a54912009-11-22 10:11:01 -080065 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +053066 case OMAP_EHCI_PORT_MODE_TLL:
Tony Lindgren4896e392009-12-11 16:16:32 -080067 omap_mux_init_signal("hsusb1_tll_stp",
68 OMAP_PIN_INPUT_PULLUP);
69 omap_mux_init_signal("hsusb1_tll_clk",
70 OMAP_PIN_INPUT_PULLDOWN);
71 omap_mux_init_signal("hsusb1_tll_dir",
72 OMAP_PIN_INPUT_PULLDOWN);
73 omap_mux_init_signal("hsusb1_tll_nxt",
74 OMAP_PIN_INPUT_PULLDOWN);
75 omap_mux_init_signal("hsusb1_tll_data0",
76 OMAP_PIN_INPUT_PULLDOWN);
77 omap_mux_init_signal("hsusb1_tll_data1",
78 OMAP_PIN_INPUT_PULLDOWN);
79 omap_mux_init_signal("hsusb1_tll_data2",
80 OMAP_PIN_INPUT_PULLDOWN);
81 omap_mux_init_signal("hsusb1_tll_data3",
82 OMAP_PIN_INPUT_PULLDOWN);
83 omap_mux_init_signal("hsusb1_tll_data4",
84 OMAP_PIN_INPUT_PULLDOWN);
85 omap_mux_init_signal("hsusb1_tll_data5",
86 OMAP_PIN_INPUT_PULLDOWN);
87 omap_mux_init_signal("hsusb1_tll_data6",
88 OMAP_PIN_INPUT_PULLDOWN);
89 omap_mux_init_signal("hsusb1_tll_data7",
90 OMAP_PIN_INPUT_PULLDOWN);
Felipe Balbi58a54912009-11-22 10:11:01 -080091 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +053092 case OMAP_USBHS_PORT_MODE_UNUSED:
Felipe Balbi58a54912009-11-22 10:11:01 -080093 /* FALLTHROUGH */
94 default:
95 break;
96 }
97
98 switch (port_mode[1]) {
Keshava Munegowda181b2502011-03-01 20:08:16 +053099 case OMAP_EHCI_PORT_MODE_PHY:
Tony Lindgren4896e392009-12-11 16:16:32 -0800100 omap_mux_init_signal("hsusb2_stp", OMAP_PIN_OUTPUT);
101 omap_mux_init_signal("hsusb2_clk", OMAP_PIN_OUTPUT);
102 omap_mux_init_signal("hsusb2_dir", OMAP_PIN_INPUT_PULLDOWN);
103 omap_mux_init_signal("hsusb2_nxt", OMAP_PIN_INPUT_PULLDOWN);
104 omap_mux_init_signal("hsusb2_data0",
105 OMAP_PIN_INPUT_PULLDOWN);
106 omap_mux_init_signal("hsusb2_data1",
107 OMAP_PIN_INPUT_PULLDOWN);
108 omap_mux_init_signal("hsusb2_data2",
109 OMAP_PIN_INPUT_PULLDOWN);
110 omap_mux_init_signal("hsusb2_data3",
111 OMAP_PIN_INPUT_PULLDOWN);
112 omap_mux_init_signal("hsusb2_data4",
113 OMAP_PIN_INPUT_PULLDOWN);
114 omap_mux_init_signal("hsusb2_data5",
115 OMAP_PIN_INPUT_PULLDOWN);
116 omap_mux_init_signal("hsusb2_data6",
117 OMAP_PIN_INPUT_PULLDOWN);
118 omap_mux_init_signal("hsusb2_data7",
119 OMAP_PIN_INPUT_PULLDOWN);
Felipe Balbi58a54912009-11-22 10:11:01 -0800120 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +0530121 case OMAP_EHCI_PORT_MODE_TLL:
Tony Lindgren4896e392009-12-11 16:16:32 -0800122 omap_mux_init_signal("hsusb2_tll_stp",
123 OMAP_PIN_INPUT_PULLUP);
124 omap_mux_init_signal("hsusb2_tll_clk",
125 OMAP_PIN_INPUT_PULLDOWN);
126 omap_mux_init_signal("hsusb2_tll_dir",
127 OMAP_PIN_INPUT_PULLDOWN);
128 omap_mux_init_signal("hsusb2_tll_nxt",
129 OMAP_PIN_INPUT_PULLDOWN);
130 omap_mux_init_signal("hsusb2_tll_data0",
131 OMAP_PIN_INPUT_PULLDOWN);
132 omap_mux_init_signal("hsusb2_tll_data1",
133 OMAP_PIN_INPUT_PULLDOWN);
134 omap_mux_init_signal("hsusb2_tll_data2",
135 OMAP_PIN_INPUT_PULLDOWN);
136 omap_mux_init_signal("hsusb2_tll_data3",
137 OMAP_PIN_INPUT_PULLDOWN);
138 omap_mux_init_signal("hsusb2_tll_data4",
139 OMAP_PIN_INPUT_PULLDOWN);
140 omap_mux_init_signal("hsusb2_tll_data5",
141 OMAP_PIN_INPUT_PULLDOWN);
142 omap_mux_init_signal("hsusb2_tll_data6",
143 OMAP_PIN_INPUT_PULLDOWN);
144 omap_mux_init_signal("hsusb2_tll_data7",
145 OMAP_PIN_INPUT_PULLDOWN);
Felipe Balbi58a54912009-11-22 10:11:01 -0800146 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +0530147 case OMAP_USBHS_PORT_MODE_UNUSED:
Felipe Balbi58a54912009-11-22 10:11:01 -0800148 /* FALLTHROUGH */
149 default:
150 break;
151 }
152
153 switch (port_mode[2]) {
Keshava Munegowda181b2502011-03-01 20:08:16 +0530154 case OMAP_EHCI_PORT_MODE_PHY:
Felipe Balbi58a54912009-11-22 10:11:01 -0800155 printk(KERN_WARNING "Port3 can't be used in PHY mode\n");
156 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +0530157 case OMAP_EHCI_PORT_MODE_TLL:
Tony Lindgren4896e392009-12-11 16:16:32 -0800158 omap_mux_init_signal("hsusb3_tll_stp",
159 OMAP_PIN_INPUT_PULLUP);
160 omap_mux_init_signal("hsusb3_tll_clk",
161 OMAP_PIN_INPUT_PULLDOWN);
162 omap_mux_init_signal("hsusb3_tll_dir",
163 OMAP_PIN_INPUT_PULLDOWN);
164 omap_mux_init_signal("hsusb3_tll_nxt",
165 OMAP_PIN_INPUT_PULLDOWN);
166 omap_mux_init_signal("hsusb3_tll_data0",
167 OMAP_PIN_INPUT_PULLDOWN);
168 omap_mux_init_signal("hsusb3_tll_data1",
169 OMAP_PIN_INPUT_PULLDOWN);
170 omap_mux_init_signal("hsusb3_tll_data2",
171 OMAP_PIN_INPUT_PULLDOWN);
172 omap_mux_init_signal("hsusb3_tll_data3",
173 OMAP_PIN_INPUT_PULLDOWN);
174 omap_mux_init_signal("hsusb3_tll_data4",
175 OMAP_PIN_INPUT_PULLDOWN);
176 omap_mux_init_signal("hsusb3_tll_data5",
177 OMAP_PIN_INPUT_PULLDOWN);
178 omap_mux_init_signal("hsusb3_tll_data6",
179 OMAP_PIN_INPUT_PULLDOWN);
180 omap_mux_init_signal("hsusb3_tll_data7",
181 OMAP_PIN_INPUT_PULLDOWN);
Felipe Balbi58a54912009-11-22 10:11:01 -0800182 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +0530183 case OMAP_USBHS_PORT_MODE_UNUSED:
Felipe Balbi58a54912009-11-22 10:11:01 -0800184 /* FALLTHROUGH */
185 default:
186 break;
187 }
188
189 return;
190}
191
Igor Grinberg1512f0d2012-03-26 16:51:10 +0200192static
193void __init setup_4430ehci_io_mux(const enum usbhs_omap_port_mode *port_mode)
Anand Gadiyarbecf0732010-11-21 23:23:41 +0530194{
195 switch (port_mode[0]) {
Keshava Munegowda181b2502011-03-01 20:08:16 +0530196 case OMAP_EHCI_PORT_MODE_PHY:
Anand Gadiyarbecf0732010-11-21 23:23:41 +0530197 omap_mux_init_signal("usbb1_ulpiphy_stp",
198 OMAP_PIN_OUTPUT);
199 omap_mux_init_signal("usbb1_ulpiphy_clk",
200 OMAP_PIN_INPUT_PULLDOWN);
201 omap_mux_init_signal("usbb1_ulpiphy_dir",
202 OMAP_PIN_INPUT_PULLDOWN);
203 omap_mux_init_signal("usbb1_ulpiphy_nxt",
204 OMAP_PIN_INPUT_PULLDOWN);
205 omap_mux_init_signal("usbb1_ulpiphy_dat0",
206 OMAP_PIN_INPUT_PULLDOWN);
207 omap_mux_init_signal("usbb1_ulpiphy_dat1",
208 OMAP_PIN_INPUT_PULLDOWN);
209 omap_mux_init_signal("usbb1_ulpiphy_dat2",
210 OMAP_PIN_INPUT_PULLDOWN);
211 omap_mux_init_signal("usbb1_ulpiphy_dat3",
212 OMAP_PIN_INPUT_PULLDOWN);
213 omap_mux_init_signal("usbb1_ulpiphy_dat4",
214 OMAP_PIN_INPUT_PULLDOWN);
215 omap_mux_init_signal("usbb1_ulpiphy_dat5",
216 OMAP_PIN_INPUT_PULLDOWN);
217 omap_mux_init_signal("usbb1_ulpiphy_dat6",
218 OMAP_PIN_INPUT_PULLDOWN);
219 omap_mux_init_signal("usbb1_ulpiphy_dat7",
220 OMAP_PIN_INPUT_PULLDOWN);
221 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +0530222 case OMAP_EHCI_PORT_MODE_TLL:
Anand Gadiyarbecf0732010-11-21 23:23:41 +0530223 omap_mux_init_signal("usbb1_ulpitll_stp",
224 OMAP_PIN_INPUT_PULLUP);
225 omap_mux_init_signal("usbb1_ulpitll_clk",
226 OMAP_PIN_INPUT_PULLDOWN);
227 omap_mux_init_signal("usbb1_ulpitll_dir",
228 OMAP_PIN_INPUT_PULLDOWN);
229 omap_mux_init_signal("usbb1_ulpitll_nxt",
230 OMAP_PIN_INPUT_PULLDOWN);
231 omap_mux_init_signal("usbb1_ulpitll_dat0",
232 OMAP_PIN_INPUT_PULLDOWN);
233 omap_mux_init_signal("usbb1_ulpitll_dat1",
234 OMAP_PIN_INPUT_PULLDOWN);
235 omap_mux_init_signal("usbb1_ulpitll_dat2",
236 OMAP_PIN_INPUT_PULLDOWN);
237 omap_mux_init_signal("usbb1_ulpitll_dat3",
238 OMAP_PIN_INPUT_PULLDOWN);
239 omap_mux_init_signal("usbb1_ulpitll_dat4",
240 OMAP_PIN_INPUT_PULLDOWN);
241 omap_mux_init_signal("usbb1_ulpitll_dat5",
242 OMAP_PIN_INPUT_PULLDOWN);
243 omap_mux_init_signal("usbb1_ulpitll_dat6",
244 OMAP_PIN_INPUT_PULLDOWN);
245 omap_mux_init_signal("usbb1_ulpitll_dat7",
246 OMAP_PIN_INPUT_PULLDOWN);
247 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +0530248 case OMAP_USBHS_PORT_MODE_UNUSED:
Anand Gadiyarbecf0732010-11-21 23:23:41 +0530249 default:
250 break;
251 }
252 switch (port_mode[1]) {
Keshava Munegowda181b2502011-03-01 20:08:16 +0530253 case OMAP_EHCI_PORT_MODE_PHY:
Anand Gadiyarbecf0732010-11-21 23:23:41 +0530254 omap_mux_init_signal("usbb2_ulpiphy_stp",
255 OMAP_PIN_OUTPUT);
256 omap_mux_init_signal("usbb2_ulpiphy_clk",
257 OMAP_PIN_INPUT_PULLDOWN);
258 omap_mux_init_signal("usbb2_ulpiphy_dir",
259 OMAP_PIN_INPUT_PULLDOWN);
260 omap_mux_init_signal("usbb2_ulpiphy_nxt",
261 OMAP_PIN_INPUT_PULLDOWN);
262 omap_mux_init_signal("usbb2_ulpiphy_dat0",
263 OMAP_PIN_INPUT_PULLDOWN);
264 omap_mux_init_signal("usbb2_ulpiphy_dat1",
265 OMAP_PIN_INPUT_PULLDOWN);
266 omap_mux_init_signal("usbb2_ulpiphy_dat2",
267 OMAP_PIN_INPUT_PULLDOWN);
268 omap_mux_init_signal("usbb2_ulpiphy_dat3",
269 OMAP_PIN_INPUT_PULLDOWN);
270 omap_mux_init_signal("usbb2_ulpiphy_dat4",
271 OMAP_PIN_INPUT_PULLDOWN);
272 omap_mux_init_signal("usbb2_ulpiphy_dat5",
273 OMAP_PIN_INPUT_PULLDOWN);
274 omap_mux_init_signal("usbb2_ulpiphy_dat6",
275 OMAP_PIN_INPUT_PULLDOWN);
276 omap_mux_init_signal("usbb2_ulpiphy_dat7",
277 OMAP_PIN_INPUT_PULLDOWN);
278 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +0530279 case OMAP_EHCI_PORT_MODE_TLL:
Anand Gadiyarbecf0732010-11-21 23:23:41 +0530280 omap_mux_init_signal("usbb2_ulpitll_stp",
281 OMAP_PIN_INPUT_PULLUP);
282 omap_mux_init_signal("usbb2_ulpitll_clk",
283 OMAP_PIN_INPUT_PULLDOWN);
284 omap_mux_init_signal("usbb2_ulpitll_dir",
285 OMAP_PIN_INPUT_PULLDOWN);
286 omap_mux_init_signal("usbb2_ulpitll_nxt",
287 OMAP_PIN_INPUT_PULLDOWN);
288 omap_mux_init_signal("usbb2_ulpitll_dat0",
289 OMAP_PIN_INPUT_PULLDOWN);
290 omap_mux_init_signal("usbb2_ulpitll_dat1",
291 OMAP_PIN_INPUT_PULLDOWN);
292 omap_mux_init_signal("usbb2_ulpitll_dat2",
293 OMAP_PIN_INPUT_PULLDOWN);
294 omap_mux_init_signal("usbb2_ulpitll_dat3",
295 OMAP_PIN_INPUT_PULLDOWN);
296 omap_mux_init_signal("usbb2_ulpitll_dat4",
297 OMAP_PIN_INPUT_PULLDOWN);
298 omap_mux_init_signal("usbb2_ulpitll_dat5",
299 OMAP_PIN_INPUT_PULLDOWN);
300 omap_mux_init_signal("usbb2_ulpitll_dat6",
301 OMAP_PIN_INPUT_PULLDOWN);
302 omap_mux_init_signal("usbb2_ulpitll_dat7",
303 OMAP_PIN_INPUT_PULLDOWN);
304 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +0530305 case OMAP_USBHS_PORT_MODE_UNUSED:
Anand Gadiyarbecf0732010-11-21 23:23:41 +0530306 default:
307 break;
308 }
309}
310
Igor Grinberg1512f0d2012-03-26 16:51:10 +0200311static void __init setup_ohci_io_mux(const enum usbhs_omap_port_mode *port_mode)
Anand Gadiyar95344fc2010-05-10 21:56:10 +0530312{
313 switch (port_mode[0]) {
314 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
315 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
316 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
317 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
318 omap_mux_init_signal("mm1_rxdp",
319 OMAP_PIN_INPUT_PULLDOWN);
320 omap_mux_init_signal("mm1_rxdm",
321 OMAP_PIN_INPUT_PULLDOWN);
322 /* FALLTHROUGH */
323 case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
324 case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
325 omap_mux_init_signal("mm1_rxrcv",
326 OMAP_PIN_INPUT_PULLDOWN);
327 /* FALLTHROUGH */
328 case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
329 case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
330 omap_mux_init_signal("mm1_txen_n", OMAP_PIN_OUTPUT);
331 /* FALLTHROUGH */
332 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
333 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
334 omap_mux_init_signal("mm1_txse0",
335 OMAP_PIN_INPUT_PULLDOWN);
336 omap_mux_init_signal("mm1_txdat",
337 OMAP_PIN_INPUT_PULLDOWN);
338 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +0530339 case OMAP_USBHS_PORT_MODE_UNUSED:
Anand Gadiyar95344fc2010-05-10 21:56:10 +0530340 /* FALLTHROUGH */
341 default:
342 break;
343 }
344 switch (port_mode[1]) {
345 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
346 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
347 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
348 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
349 omap_mux_init_signal("mm2_rxdp",
350 OMAP_PIN_INPUT_PULLDOWN);
351 omap_mux_init_signal("mm2_rxdm",
352 OMAP_PIN_INPUT_PULLDOWN);
353 /* FALLTHROUGH */
354 case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
355 case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
356 omap_mux_init_signal("mm2_rxrcv",
357 OMAP_PIN_INPUT_PULLDOWN);
358 /* FALLTHROUGH */
359 case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
360 case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
361 omap_mux_init_signal("mm2_txen_n", OMAP_PIN_OUTPUT);
362 /* FALLTHROUGH */
363 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
364 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
365 omap_mux_init_signal("mm2_txse0",
366 OMAP_PIN_INPUT_PULLDOWN);
367 omap_mux_init_signal("mm2_txdat",
368 OMAP_PIN_INPUT_PULLDOWN);
369 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +0530370 case OMAP_USBHS_PORT_MODE_UNUSED:
Anand Gadiyar95344fc2010-05-10 21:56:10 +0530371 /* FALLTHROUGH */
372 default:
373 break;
374 }
375 switch (port_mode[2]) {
376 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
377 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
378 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
379 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
380 omap_mux_init_signal("mm3_rxdp",
381 OMAP_PIN_INPUT_PULLDOWN);
382 omap_mux_init_signal("mm3_rxdm",
383 OMAP_PIN_INPUT_PULLDOWN);
384 /* FALLTHROUGH */
385 case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
386 case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
387 omap_mux_init_signal("mm3_rxrcv",
388 OMAP_PIN_INPUT_PULLDOWN);
389 /* FALLTHROUGH */
390 case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
391 case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
392 omap_mux_init_signal("mm3_txen_n", OMAP_PIN_OUTPUT);
393 /* FALLTHROUGH */
394 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
395 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
396 omap_mux_init_signal("mm3_txse0",
397 OMAP_PIN_INPUT_PULLDOWN);
398 omap_mux_init_signal("mm3_txdat",
399 OMAP_PIN_INPUT_PULLDOWN);
400 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +0530401 case OMAP_USBHS_PORT_MODE_UNUSED:
Anand Gadiyar95344fc2010-05-10 21:56:10 +0530402 /* FALLTHROUGH */
403 default:
404 break;
405 }
406}
407
Igor Grinberg1512f0d2012-03-26 16:51:10 +0200408static
409void __init setup_4430ohci_io_mux(const enum usbhs_omap_port_mode *port_mode)
Keshava Munegowda22363962011-03-01 20:08:18 +0530410{
411 switch (port_mode[0]) {
412 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
413 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
414 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
415 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
416 omap_mux_init_signal("usbb1_mm_rxdp",
417 OMAP_PIN_INPUT_PULLDOWN);
418 omap_mux_init_signal("usbb1_mm_rxdm",
419 OMAP_PIN_INPUT_PULLDOWN);
420
421 case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
422 case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
423 omap_mux_init_signal("usbb1_mm_rxrcv",
424 OMAP_PIN_INPUT_PULLDOWN);
425
426 case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
427 case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
428 omap_mux_init_signal("usbb1_mm_txen",
429 OMAP_PIN_INPUT_PULLDOWN);
430
431
432 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
433 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
434 omap_mux_init_signal("usbb1_mm_txdat",
435 OMAP_PIN_INPUT_PULLDOWN);
436 omap_mux_init_signal("usbb1_mm_txse0",
437 OMAP_PIN_INPUT_PULLDOWN);
438 break;
439
440 case OMAP_USBHS_PORT_MODE_UNUSED:
441 default:
442 break;
443 }
444
445 switch (port_mode[1]) {
446 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
447 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
448 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
449 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
450 omap_mux_init_signal("usbb2_mm_rxdp",
451 OMAP_PIN_INPUT_PULLDOWN);
452 omap_mux_init_signal("usbb2_mm_rxdm",
453 OMAP_PIN_INPUT_PULLDOWN);
454
455 case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
456 case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
457 omap_mux_init_signal("usbb2_mm_rxrcv",
458 OMAP_PIN_INPUT_PULLDOWN);
459
460 case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
461 case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
462 omap_mux_init_signal("usbb2_mm_txen",
463 OMAP_PIN_INPUT_PULLDOWN);
464
465
466 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
467 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
468 omap_mux_init_signal("usbb2_mm_txdat",
469 OMAP_PIN_INPUT_PULLDOWN);
470 omap_mux_init_signal("usbb2_mm_txse0",
471 OMAP_PIN_INPUT_PULLDOWN);
472 break;
473
474 case OMAP_USBHS_PORT_MODE_UNUSED:
475 default:
476 break;
477 }
478}
479
Roger Quadros42973152013-02-14 10:13:48 +0200480void __init usbhs_init(struct usbhs_omap_platform_data *pdata)
Keshava Munegowda22363962011-03-01 20:08:18 +0530481{
Keshava Munegowda760189b2012-07-16 19:01:10 +0530482 struct omap_hwmod *uhh_hwm, *tll_hwm;
Felipe Balbiabe763f2012-02-14 10:54:46 +0200483 struct platform_device *pdev;
Keshava Munegowda50b2a9b2011-10-11 13:21:37 +0530484 int bus_id = -1;
Keshava Munegowda22363962011-03-01 20:08:18 +0530485
486 if (cpu_is_omap34xx()) {
Keshava Munegowda22363962011-03-01 20:08:18 +0530487 setup_ehci_io_mux(pdata->port_mode);
488 setup_ohci_io_mux(pdata->port_mode);
Roger Quadros63b68902012-12-14 09:09:11 -0800489
490 if (omap_rev() <= OMAP3430_REV_ES2_1)
Roger Quadros42973152013-02-14 10:13:48 +0200491 pdata->single_ulpi_bypass = true;
Roger Quadros63b68902012-12-14 09:09:11 -0800492
Keshava Munegowda22363962011-03-01 20:08:18 +0530493 } else if (cpu_is_omap44xx()) {
Keshava Munegowda22363962011-03-01 20:08:18 +0530494 setup_4430ehci_io_mux(pdata->port_mode);
495 setup_4430ohci_io_mux(pdata->port_mode);
496 }
497
Keshava Munegowda760189b2012-07-16 19:01:10 +0530498 uhh_hwm = omap_hwmod_lookup(USBHS_UHH_HWMODNAME);
499 if (!uhh_hwm) {
Keshava Munegowda50b2a9b2011-10-11 13:21:37 +0530500 pr_err("Could not look up %s\n", USBHS_UHH_HWMODNAME);
501 return;
Keshava Munegowda22363962011-03-01 20:08:18 +0530502 }
503
Keshava Munegowda760189b2012-07-16 19:01:10 +0530504 tll_hwm = omap_hwmod_lookup(USBHS_TLL_HWMODNAME);
505 if (!tll_hwm) {
Keshava Munegowda50b2a9b2011-10-11 13:21:37 +0530506 pr_err("Could not look up %s\n", USBHS_TLL_HWMODNAME);
507 return;
508 }
Keshava Munegowda22363962011-03-01 20:08:18 +0530509
Keshava Munegowda760189b2012-07-16 19:01:10 +0530510 pdev = omap_device_build(OMAP_USBTLL_DEVICE, bus_id, tll_hwm,
Arnd Bergmann6e7f7cf2013-02-19 20:54:15 +0100511 pdata, sizeof(*pdata));
Felipe Balbiabe763f2012-02-14 10:54:46 +0200512 if (IS_ERR(pdev)) {
Keshava Munegowda760189b2012-07-16 19:01:10 +0530513 pr_err("Could not build hwmod device %s\n",
514 USBHS_TLL_HWMODNAME);
515 return;
516 }
517
518 pdev = omap_device_build(OMAP_USBHS_DEVICE, bus_id, uhh_hwm,
Arnd Bergmann6e7f7cf2013-02-19 20:54:15 +0100519 pdata, sizeof(*pdata));
Keshava Munegowda760189b2012-07-16 19:01:10 +0530520 if (IS_ERR(pdev)) {
521 pr_err("Could not build hwmod devices %s\n",
522 USBHS_UHH_HWMODNAME);
Keshava Munegowda50b2a9b2011-10-11 13:21:37 +0530523 return;
524 }
Keshava Munegowda22363962011-03-01 20:08:18 +0530525}
526
Anand Gadiyar95344fc2010-05-10 21:56:10 +0530527#else
528
Roger Quadros42973152013-02-14 10:13:48 +0200529void __init usbhs_init(struct usbhs_omap_platform_data *pdata)
Keshava Munegowda22363962011-03-01 20:08:18 +0530530{
531}
532
Keshava Munegowda22363962011-03-01 20:08:18 +0530533#endif
Roger Quadros5ecd52e2013-03-20 17:44:41 +0200534
535/* Template for PHY regulators */
536static struct fixed_voltage_config hsusb_reg_config = {
537 /* .supply_name filled later */
538 .microvolts = 3300000,
539 .gpio = -1, /* updated later */
540 .startup_delay = 70000, /* 70msec */
541 .enable_high = 1, /* updated later */
542 .enabled_at_boot = 0, /* keep in RESET */
543 /* .init_data filled later */
544};
545
546static const char *nop_name = "nop_usb_xceiv"; /* NOP PHY driver */
547static const char *reg_name = "reg-fixed-voltage"; /* Regulator driver */
548
549/**
550 * usbhs_add_regulator - Add a gpio based fixed voltage regulator device
551 * @name: name for the regulator
552 * @dev_id: device id of the device this regulator supplies power to
553 * @dev_supply: supply name that the device expects
554 * @gpio: GPIO number
555 * @polarity: 1 - Active high, 0 - Active low
556 */
557static int usbhs_add_regulator(char *name, char *dev_id, char *dev_supply,
558 int gpio, int polarity)
559{
560 struct regulator_consumer_supply *supplies;
561 struct regulator_init_data *reg_data;
562 struct fixed_voltage_config *config;
563 struct platform_device *pdev;
Roger Quadrose41a5f82013-05-24 16:06:58 +0300564 struct platform_device_info pdevinfo;
565 int ret = -ENOMEM;
Roger Quadros5ecd52e2013-03-20 17:44:41 +0200566
567 supplies = kzalloc(sizeof(*supplies), GFP_KERNEL);
568 if (!supplies)
569 return -ENOMEM;
570
571 supplies->supply = dev_supply;
572 supplies->dev_name = dev_id;
573
574 reg_data = kzalloc(sizeof(*reg_data), GFP_KERNEL);
575 if (!reg_data)
Roger Quadrose41a5f82013-05-24 16:06:58 +0300576 goto err_data;
Roger Quadros5ecd52e2013-03-20 17:44:41 +0200577
578 reg_data->constraints.valid_ops_mask = REGULATOR_CHANGE_STATUS;
579 reg_data->consumer_supplies = supplies;
580 reg_data->num_consumer_supplies = 1;
581
582 config = kmemdup(&hsusb_reg_config, sizeof(hsusb_reg_config),
583 GFP_KERNEL);
584 if (!config)
Roger Quadrose41a5f82013-05-24 16:06:58 +0300585 goto err_config;
Roger Quadros5ecd52e2013-03-20 17:44:41 +0200586
Roger Quadrose41a5f82013-05-24 16:06:58 +0300587 config->supply_name = kstrdup(name, GFP_KERNEL);
588 if (!config->supply_name)
589 goto err_supplyname;
590
Roger Quadros5ecd52e2013-03-20 17:44:41 +0200591 config->gpio = gpio;
592 config->enable_high = polarity;
593 config->init_data = reg_data;
594
595 /* create a regulator device */
Roger Quadrose41a5f82013-05-24 16:06:58 +0300596 memset(&pdevinfo, 0, sizeof(pdevinfo));
597 pdevinfo.name = reg_name;
598 pdevinfo.id = PLATFORM_DEVID_AUTO;
599 pdevinfo.data = config;
600 pdevinfo.size_data = sizeof(*config);
Roger Quadros5ecd52e2013-03-20 17:44:41 +0200601
Roger Quadrose41a5f82013-05-24 16:06:58 +0300602 pdev = platform_device_register_full(&pdevinfo);
603 if (IS_ERR(pdev)) {
604 ret = PTR_ERR(pdev);
605 pr_err("%s: Failed registering regulator %s for %s : %d\n",
606 __func__, name, dev_id, ret);
607 goto err_register;
608 }
Roger Quadros5ecd52e2013-03-20 17:44:41 +0200609
Roger Quadrose41a5f82013-05-24 16:06:58 +0300610 return 0;
Roger Quadros5ecd52e2013-03-20 17:44:41 +0200611
Roger Quadrose41a5f82013-05-24 16:06:58 +0300612err_register:
613 kfree(config->supply_name);
614err_supplyname:
615 kfree(config);
616err_config:
617 kfree(reg_data);
618err_data:
619 kfree(supplies);
Roger Quadros5ecd52e2013-03-20 17:44:41 +0200620 return ret;
621}
622
Roger Quadrose41a5f82013-05-24 16:06:58 +0300623#define MAX_STR 20
624
Roger Quadros5ecd52e2013-03-20 17:44:41 +0200625int usbhs_init_phys(struct usbhs_phy_data *phy, int num_phys)
626{
Roger Quadrose41a5f82013-05-24 16:06:58 +0300627 char rail_name[MAX_STR];
628 int i;
Roger Quadros5ecd52e2013-03-20 17:44:41 +0200629 struct platform_device *pdev;
630 char *phy_id;
Roger Quadrose41a5f82013-05-24 16:06:58 +0300631 struct platform_device_info pdevinfo;
Roger Quadros5ecd52e2013-03-20 17:44:41 +0200632
633 for (i = 0; i < num_phys; i++) {
634
635 if (!phy->port) {
636 pr_err("%s: Invalid port 0. Must start from 1\n",
637 __func__);
638 continue;
639 }
640
641 /* do we need a NOP PHY device ? */
642 if (!gpio_is_valid(phy->reset_gpio) &&
643 !gpio_is_valid(phy->vcc_gpio))
644 continue;
645
Roger Quadrose41a5f82013-05-24 16:06:58 +0300646 phy_id = kmalloc(MAX_STR, GFP_KERNEL);
647 if (!phy_id) {
648 pr_err("%s: kmalloc() failed\n", __func__);
649 return -ENOMEM;
650 }
651
Roger Quadros5ecd52e2013-03-20 17:44:41 +0200652 /* create a NOP PHY device */
Roger Quadrose41a5f82013-05-24 16:06:58 +0300653 memset(&pdevinfo, 0, sizeof(pdevinfo));
654 pdevinfo.name = nop_name;
655 pdevinfo.id = phy->port;
656 pdevinfo.data = phy->platform_data;
657 pdevinfo.size_data = sizeof(struct nop_usb_xceiv_platform_data);
Roger Quadros5ecd52e2013-03-20 17:44:41 +0200658
Roger Quadrose41a5f82013-05-24 16:06:58 +0300659 scnprintf(phy_id, MAX_STR, "nop_usb_xceiv.%d",
660 phy->port);
661 pdev = platform_device_register_full(&pdevinfo);
662 if (IS_ERR(pdev)) {
663 pr_err("%s: Failed to register device %s : %ld\n",
664 __func__, phy_id, PTR_ERR(pdev));
665 kfree(phy_id);
Roger Quadros5ecd52e2013-03-20 17:44:41 +0200666 continue;
667 }
668
669 usb_bind_phy("ehci-omap.0", phy->port - 1, phy_id);
670
671 /* Do we need RESET regulator ? */
672 if (gpio_is_valid(phy->reset_gpio)) {
Roger Quadrose41a5f82013-05-24 16:06:58 +0300673 scnprintf(rail_name, MAX_STR,
674 "hsusb%d_reset", phy->port);
Roger Quadros5ecd52e2013-03-20 17:44:41 +0200675 usbhs_add_regulator(rail_name, phy_id, "reset",
676 phy->reset_gpio, 1);
677 }
678
679 /* Do we need VCC regulator ? */
680 if (gpio_is_valid(phy->vcc_gpio)) {
Roger Quadrose41a5f82013-05-24 16:06:58 +0300681 scnprintf(rail_name, MAX_STR, "hsusb%d_vcc", phy->port);
Roger Quadros5ecd52e2013-03-20 17:44:41 +0200682 usbhs_add_regulator(rail_name, phy_id, "vcc",
683 phy->vcc_gpio, phy->vcc_polarity);
684 }
685
686 phy++;
687 }
688
689 return 0;
690}