blob: aa27d7f5cbb7a760596337903fd0e61ac22e647b [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>
Felipe Balbi58a54912009-11-22 10:11:01 -080031
Tony Lindgrene4c060d2012-10-05 13:25:59 -070032#include "soc.h"
Tony Lindgren25c7d492012-10-02 17:25:48 -070033#include "omap_device.h"
Tony Lindgren4896e392009-12-11 16:16:32 -080034#include "mux.h"
Tony Lindgren54db6ee2012-10-24 14:26:18 -070035#include "usb.h"
Tony Lindgren4896e392009-12-11 16:16:32 -080036
Keshava Munegowda22363962011-03-01 20:08:18 +053037#ifdef CONFIG_MFD_OMAP_USB_HOST
Felipe Balbi58a54912009-11-22 10:11:01 -080038
Keshava Munegowda50b2a9b2011-10-11 13:21:37 +053039#define OMAP_USBHS_DEVICE "usbhs_omap"
Keshava Munegowda760189b2012-07-16 19:01:10 +053040#define OMAP_USBTLL_DEVICE "usbhs_tll"
Keshava Munegowda50b2a9b2011-10-11 13:21:37 +053041#define USBHS_UHH_HWMODNAME "usb_host_hs"
42#define USBHS_TLL_HWMODNAME "usb_tll_hs"
Felipe Balbi58a54912009-11-22 10:11:01 -080043
44/* MUX settings for EHCI pins */
45/*
46 * setup_ehci_io_mux - initialize IO pad mux for USBHOST
47 */
Igor Grinberg1512f0d2012-03-26 16:51:10 +020048static void __init setup_ehci_io_mux(const enum usbhs_omap_port_mode *port_mode)
Felipe Balbi58a54912009-11-22 10:11:01 -080049{
50 switch (port_mode[0]) {
Keshava Munegowda181b2502011-03-01 20:08:16 +053051 case OMAP_EHCI_PORT_MODE_PHY:
Tony Lindgren4896e392009-12-11 16:16:32 -080052 omap_mux_init_signal("hsusb1_stp", OMAP_PIN_OUTPUT);
53 omap_mux_init_signal("hsusb1_clk", OMAP_PIN_OUTPUT);
54 omap_mux_init_signal("hsusb1_dir", OMAP_PIN_INPUT_PULLDOWN);
55 omap_mux_init_signal("hsusb1_nxt", OMAP_PIN_INPUT_PULLDOWN);
56 omap_mux_init_signal("hsusb1_data0", OMAP_PIN_INPUT_PULLDOWN);
57 omap_mux_init_signal("hsusb1_data1", OMAP_PIN_INPUT_PULLDOWN);
58 omap_mux_init_signal("hsusb1_data2", OMAP_PIN_INPUT_PULLDOWN);
59 omap_mux_init_signal("hsusb1_data3", OMAP_PIN_INPUT_PULLDOWN);
60 omap_mux_init_signal("hsusb1_data4", OMAP_PIN_INPUT_PULLDOWN);
61 omap_mux_init_signal("hsusb1_data5", OMAP_PIN_INPUT_PULLDOWN);
62 omap_mux_init_signal("hsusb1_data6", OMAP_PIN_INPUT_PULLDOWN);
63 omap_mux_init_signal("hsusb1_data7", OMAP_PIN_INPUT_PULLDOWN);
Felipe Balbi58a54912009-11-22 10:11:01 -080064 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +053065 case OMAP_EHCI_PORT_MODE_TLL:
Tony Lindgren4896e392009-12-11 16:16:32 -080066 omap_mux_init_signal("hsusb1_tll_stp",
67 OMAP_PIN_INPUT_PULLUP);
68 omap_mux_init_signal("hsusb1_tll_clk",
69 OMAP_PIN_INPUT_PULLDOWN);
70 omap_mux_init_signal("hsusb1_tll_dir",
71 OMAP_PIN_INPUT_PULLDOWN);
72 omap_mux_init_signal("hsusb1_tll_nxt",
73 OMAP_PIN_INPUT_PULLDOWN);
74 omap_mux_init_signal("hsusb1_tll_data0",
75 OMAP_PIN_INPUT_PULLDOWN);
76 omap_mux_init_signal("hsusb1_tll_data1",
77 OMAP_PIN_INPUT_PULLDOWN);
78 omap_mux_init_signal("hsusb1_tll_data2",
79 OMAP_PIN_INPUT_PULLDOWN);
80 omap_mux_init_signal("hsusb1_tll_data3",
81 OMAP_PIN_INPUT_PULLDOWN);
82 omap_mux_init_signal("hsusb1_tll_data4",
83 OMAP_PIN_INPUT_PULLDOWN);
84 omap_mux_init_signal("hsusb1_tll_data5",
85 OMAP_PIN_INPUT_PULLDOWN);
86 omap_mux_init_signal("hsusb1_tll_data6",
87 OMAP_PIN_INPUT_PULLDOWN);
88 omap_mux_init_signal("hsusb1_tll_data7",
89 OMAP_PIN_INPUT_PULLDOWN);
Felipe Balbi58a54912009-11-22 10:11:01 -080090 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +053091 case OMAP_USBHS_PORT_MODE_UNUSED:
Felipe Balbi58a54912009-11-22 10:11:01 -080092 /* FALLTHROUGH */
93 default:
94 break;
95 }
96
97 switch (port_mode[1]) {
Keshava Munegowda181b2502011-03-01 20:08:16 +053098 case OMAP_EHCI_PORT_MODE_PHY:
Tony Lindgren4896e392009-12-11 16:16:32 -080099 omap_mux_init_signal("hsusb2_stp", OMAP_PIN_OUTPUT);
100 omap_mux_init_signal("hsusb2_clk", OMAP_PIN_OUTPUT);
101 omap_mux_init_signal("hsusb2_dir", OMAP_PIN_INPUT_PULLDOWN);
102 omap_mux_init_signal("hsusb2_nxt", OMAP_PIN_INPUT_PULLDOWN);
103 omap_mux_init_signal("hsusb2_data0",
104 OMAP_PIN_INPUT_PULLDOWN);
105 omap_mux_init_signal("hsusb2_data1",
106 OMAP_PIN_INPUT_PULLDOWN);
107 omap_mux_init_signal("hsusb2_data2",
108 OMAP_PIN_INPUT_PULLDOWN);
109 omap_mux_init_signal("hsusb2_data3",
110 OMAP_PIN_INPUT_PULLDOWN);
111 omap_mux_init_signal("hsusb2_data4",
112 OMAP_PIN_INPUT_PULLDOWN);
113 omap_mux_init_signal("hsusb2_data5",
114 OMAP_PIN_INPUT_PULLDOWN);
115 omap_mux_init_signal("hsusb2_data6",
116 OMAP_PIN_INPUT_PULLDOWN);
117 omap_mux_init_signal("hsusb2_data7",
118 OMAP_PIN_INPUT_PULLDOWN);
Felipe Balbi58a54912009-11-22 10:11:01 -0800119 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +0530120 case OMAP_EHCI_PORT_MODE_TLL:
Tony Lindgren4896e392009-12-11 16:16:32 -0800121 omap_mux_init_signal("hsusb2_tll_stp",
122 OMAP_PIN_INPUT_PULLUP);
123 omap_mux_init_signal("hsusb2_tll_clk",
124 OMAP_PIN_INPUT_PULLDOWN);
125 omap_mux_init_signal("hsusb2_tll_dir",
126 OMAP_PIN_INPUT_PULLDOWN);
127 omap_mux_init_signal("hsusb2_tll_nxt",
128 OMAP_PIN_INPUT_PULLDOWN);
129 omap_mux_init_signal("hsusb2_tll_data0",
130 OMAP_PIN_INPUT_PULLDOWN);
131 omap_mux_init_signal("hsusb2_tll_data1",
132 OMAP_PIN_INPUT_PULLDOWN);
133 omap_mux_init_signal("hsusb2_tll_data2",
134 OMAP_PIN_INPUT_PULLDOWN);
135 omap_mux_init_signal("hsusb2_tll_data3",
136 OMAP_PIN_INPUT_PULLDOWN);
137 omap_mux_init_signal("hsusb2_tll_data4",
138 OMAP_PIN_INPUT_PULLDOWN);
139 omap_mux_init_signal("hsusb2_tll_data5",
140 OMAP_PIN_INPUT_PULLDOWN);
141 omap_mux_init_signal("hsusb2_tll_data6",
142 OMAP_PIN_INPUT_PULLDOWN);
143 omap_mux_init_signal("hsusb2_tll_data7",
144 OMAP_PIN_INPUT_PULLDOWN);
Felipe Balbi58a54912009-11-22 10:11:01 -0800145 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +0530146 case OMAP_USBHS_PORT_MODE_UNUSED:
Felipe Balbi58a54912009-11-22 10:11:01 -0800147 /* FALLTHROUGH */
148 default:
149 break;
150 }
151
152 switch (port_mode[2]) {
Keshava Munegowda181b2502011-03-01 20:08:16 +0530153 case OMAP_EHCI_PORT_MODE_PHY:
Felipe Balbi58a54912009-11-22 10:11:01 -0800154 printk(KERN_WARNING "Port3 can't be used in PHY mode\n");
155 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +0530156 case OMAP_EHCI_PORT_MODE_TLL:
Tony Lindgren4896e392009-12-11 16:16:32 -0800157 omap_mux_init_signal("hsusb3_tll_stp",
158 OMAP_PIN_INPUT_PULLUP);
159 omap_mux_init_signal("hsusb3_tll_clk",
160 OMAP_PIN_INPUT_PULLDOWN);
161 omap_mux_init_signal("hsusb3_tll_dir",
162 OMAP_PIN_INPUT_PULLDOWN);
163 omap_mux_init_signal("hsusb3_tll_nxt",
164 OMAP_PIN_INPUT_PULLDOWN);
165 omap_mux_init_signal("hsusb3_tll_data0",
166 OMAP_PIN_INPUT_PULLDOWN);
167 omap_mux_init_signal("hsusb3_tll_data1",
168 OMAP_PIN_INPUT_PULLDOWN);
169 omap_mux_init_signal("hsusb3_tll_data2",
170 OMAP_PIN_INPUT_PULLDOWN);
171 omap_mux_init_signal("hsusb3_tll_data3",
172 OMAP_PIN_INPUT_PULLDOWN);
173 omap_mux_init_signal("hsusb3_tll_data4",
174 OMAP_PIN_INPUT_PULLDOWN);
175 omap_mux_init_signal("hsusb3_tll_data5",
176 OMAP_PIN_INPUT_PULLDOWN);
177 omap_mux_init_signal("hsusb3_tll_data6",
178 OMAP_PIN_INPUT_PULLDOWN);
179 omap_mux_init_signal("hsusb3_tll_data7",
180 OMAP_PIN_INPUT_PULLDOWN);
Felipe Balbi58a54912009-11-22 10:11:01 -0800181 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +0530182 case OMAP_USBHS_PORT_MODE_UNUSED:
Felipe Balbi58a54912009-11-22 10:11:01 -0800183 /* FALLTHROUGH */
184 default:
185 break;
186 }
187
188 return;
189}
190
Igor Grinberg1512f0d2012-03-26 16:51:10 +0200191static
192void __init setup_4430ehci_io_mux(const enum usbhs_omap_port_mode *port_mode)
Anand Gadiyarbecf0732010-11-21 23:23:41 +0530193{
194 switch (port_mode[0]) {
Keshava Munegowda181b2502011-03-01 20:08:16 +0530195 case OMAP_EHCI_PORT_MODE_PHY:
Anand Gadiyarbecf0732010-11-21 23:23:41 +0530196 omap_mux_init_signal("usbb1_ulpiphy_stp",
197 OMAP_PIN_OUTPUT);
198 omap_mux_init_signal("usbb1_ulpiphy_clk",
199 OMAP_PIN_INPUT_PULLDOWN);
200 omap_mux_init_signal("usbb1_ulpiphy_dir",
201 OMAP_PIN_INPUT_PULLDOWN);
202 omap_mux_init_signal("usbb1_ulpiphy_nxt",
203 OMAP_PIN_INPUT_PULLDOWN);
204 omap_mux_init_signal("usbb1_ulpiphy_dat0",
205 OMAP_PIN_INPUT_PULLDOWN);
206 omap_mux_init_signal("usbb1_ulpiphy_dat1",
207 OMAP_PIN_INPUT_PULLDOWN);
208 omap_mux_init_signal("usbb1_ulpiphy_dat2",
209 OMAP_PIN_INPUT_PULLDOWN);
210 omap_mux_init_signal("usbb1_ulpiphy_dat3",
211 OMAP_PIN_INPUT_PULLDOWN);
212 omap_mux_init_signal("usbb1_ulpiphy_dat4",
213 OMAP_PIN_INPUT_PULLDOWN);
214 omap_mux_init_signal("usbb1_ulpiphy_dat5",
215 OMAP_PIN_INPUT_PULLDOWN);
216 omap_mux_init_signal("usbb1_ulpiphy_dat6",
217 OMAP_PIN_INPUT_PULLDOWN);
218 omap_mux_init_signal("usbb1_ulpiphy_dat7",
219 OMAP_PIN_INPUT_PULLDOWN);
220 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +0530221 case OMAP_EHCI_PORT_MODE_TLL:
Anand Gadiyarbecf0732010-11-21 23:23:41 +0530222 omap_mux_init_signal("usbb1_ulpitll_stp",
223 OMAP_PIN_INPUT_PULLUP);
224 omap_mux_init_signal("usbb1_ulpitll_clk",
225 OMAP_PIN_INPUT_PULLDOWN);
226 omap_mux_init_signal("usbb1_ulpitll_dir",
227 OMAP_PIN_INPUT_PULLDOWN);
228 omap_mux_init_signal("usbb1_ulpitll_nxt",
229 OMAP_PIN_INPUT_PULLDOWN);
230 omap_mux_init_signal("usbb1_ulpitll_dat0",
231 OMAP_PIN_INPUT_PULLDOWN);
232 omap_mux_init_signal("usbb1_ulpitll_dat1",
233 OMAP_PIN_INPUT_PULLDOWN);
234 omap_mux_init_signal("usbb1_ulpitll_dat2",
235 OMAP_PIN_INPUT_PULLDOWN);
236 omap_mux_init_signal("usbb1_ulpitll_dat3",
237 OMAP_PIN_INPUT_PULLDOWN);
238 omap_mux_init_signal("usbb1_ulpitll_dat4",
239 OMAP_PIN_INPUT_PULLDOWN);
240 omap_mux_init_signal("usbb1_ulpitll_dat5",
241 OMAP_PIN_INPUT_PULLDOWN);
242 omap_mux_init_signal("usbb1_ulpitll_dat6",
243 OMAP_PIN_INPUT_PULLDOWN);
244 omap_mux_init_signal("usbb1_ulpitll_dat7",
245 OMAP_PIN_INPUT_PULLDOWN);
246 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +0530247 case OMAP_USBHS_PORT_MODE_UNUSED:
Anand Gadiyarbecf0732010-11-21 23:23:41 +0530248 default:
249 break;
250 }
251 switch (port_mode[1]) {
Keshava Munegowda181b2502011-03-01 20:08:16 +0530252 case OMAP_EHCI_PORT_MODE_PHY:
Anand Gadiyarbecf0732010-11-21 23:23:41 +0530253 omap_mux_init_signal("usbb2_ulpiphy_stp",
254 OMAP_PIN_OUTPUT);
255 omap_mux_init_signal("usbb2_ulpiphy_clk",
256 OMAP_PIN_INPUT_PULLDOWN);
257 omap_mux_init_signal("usbb2_ulpiphy_dir",
258 OMAP_PIN_INPUT_PULLDOWN);
259 omap_mux_init_signal("usbb2_ulpiphy_nxt",
260 OMAP_PIN_INPUT_PULLDOWN);
261 omap_mux_init_signal("usbb2_ulpiphy_dat0",
262 OMAP_PIN_INPUT_PULLDOWN);
263 omap_mux_init_signal("usbb2_ulpiphy_dat1",
264 OMAP_PIN_INPUT_PULLDOWN);
265 omap_mux_init_signal("usbb2_ulpiphy_dat2",
266 OMAP_PIN_INPUT_PULLDOWN);
267 omap_mux_init_signal("usbb2_ulpiphy_dat3",
268 OMAP_PIN_INPUT_PULLDOWN);
269 omap_mux_init_signal("usbb2_ulpiphy_dat4",
270 OMAP_PIN_INPUT_PULLDOWN);
271 omap_mux_init_signal("usbb2_ulpiphy_dat5",
272 OMAP_PIN_INPUT_PULLDOWN);
273 omap_mux_init_signal("usbb2_ulpiphy_dat6",
274 OMAP_PIN_INPUT_PULLDOWN);
275 omap_mux_init_signal("usbb2_ulpiphy_dat7",
276 OMAP_PIN_INPUT_PULLDOWN);
277 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +0530278 case OMAP_EHCI_PORT_MODE_TLL:
Anand Gadiyarbecf0732010-11-21 23:23:41 +0530279 omap_mux_init_signal("usbb2_ulpitll_stp",
280 OMAP_PIN_INPUT_PULLUP);
281 omap_mux_init_signal("usbb2_ulpitll_clk",
282 OMAP_PIN_INPUT_PULLDOWN);
283 omap_mux_init_signal("usbb2_ulpitll_dir",
284 OMAP_PIN_INPUT_PULLDOWN);
285 omap_mux_init_signal("usbb2_ulpitll_nxt",
286 OMAP_PIN_INPUT_PULLDOWN);
287 omap_mux_init_signal("usbb2_ulpitll_dat0",
288 OMAP_PIN_INPUT_PULLDOWN);
289 omap_mux_init_signal("usbb2_ulpitll_dat1",
290 OMAP_PIN_INPUT_PULLDOWN);
291 omap_mux_init_signal("usbb2_ulpitll_dat2",
292 OMAP_PIN_INPUT_PULLDOWN);
293 omap_mux_init_signal("usbb2_ulpitll_dat3",
294 OMAP_PIN_INPUT_PULLDOWN);
295 omap_mux_init_signal("usbb2_ulpitll_dat4",
296 OMAP_PIN_INPUT_PULLDOWN);
297 omap_mux_init_signal("usbb2_ulpitll_dat5",
298 OMAP_PIN_INPUT_PULLDOWN);
299 omap_mux_init_signal("usbb2_ulpitll_dat6",
300 OMAP_PIN_INPUT_PULLDOWN);
301 omap_mux_init_signal("usbb2_ulpitll_dat7",
302 OMAP_PIN_INPUT_PULLDOWN);
303 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +0530304 case OMAP_USBHS_PORT_MODE_UNUSED:
Anand Gadiyarbecf0732010-11-21 23:23:41 +0530305 default:
306 break;
307 }
308}
309
Igor Grinberg1512f0d2012-03-26 16:51:10 +0200310static void __init setup_ohci_io_mux(const enum usbhs_omap_port_mode *port_mode)
Anand Gadiyar95344fc2010-05-10 21:56:10 +0530311{
312 switch (port_mode[0]) {
313 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
314 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
315 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
316 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
317 omap_mux_init_signal("mm1_rxdp",
318 OMAP_PIN_INPUT_PULLDOWN);
319 omap_mux_init_signal("mm1_rxdm",
320 OMAP_PIN_INPUT_PULLDOWN);
321 /* FALLTHROUGH */
322 case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
323 case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
324 omap_mux_init_signal("mm1_rxrcv",
325 OMAP_PIN_INPUT_PULLDOWN);
326 /* FALLTHROUGH */
327 case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
328 case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
329 omap_mux_init_signal("mm1_txen_n", OMAP_PIN_OUTPUT);
330 /* FALLTHROUGH */
331 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
332 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
333 omap_mux_init_signal("mm1_txse0",
334 OMAP_PIN_INPUT_PULLDOWN);
335 omap_mux_init_signal("mm1_txdat",
336 OMAP_PIN_INPUT_PULLDOWN);
337 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +0530338 case OMAP_USBHS_PORT_MODE_UNUSED:
Anand Gadiyar95344fc2010-05-10 21:56:10 +0530339 /* FALLTHROUGH */
340 default:
341 break;
342 }
343 switch (port_mode[1]) {
344 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
345 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
346 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
347 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
348 omap_mux_init_signal("mm2_rxdp",
349 OMAP_PIN_INPUT_PULLDOWN);
350 omap_mux_init_signal("mm2_rxdm",
351 OMAP_PIN_INPUT_PULLDOWN);
352 /* FALLTHROUGH */
353 case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
354 case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
355 omap_mux_init_signal("mm2_rxrcv",
356 OMAP_PIN_INPUT_PULLDOWN);
357 /* FALLTHROUGH */
358 case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
359 case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
360 omap_mux_init_signal("mm2_txen_n", OMAP_PIN_OUTPUT);
361 /* FALLTHROUGH */
362 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
363 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
364 omap_mux_init_signal("mm2_txse0",
365 OMAP_PIN_INPUT_PULLDOWN);
366 omap_mux_init_signal("mm2_txdat",
367 OMAP_PIN_INPUT_PULLDOWN);
368 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +0530369 case OMAP_USBHS_PORT_MODE_UNUSED:
Anand Gadiyar95344fc2010-05-10 21:56:10 +0530370 /* FALLTHROUGH */
371 default:
372 break;
373 }
374 switch (port_mode[2]) {
375 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
376 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
377 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
378 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
379 omap_mux_init_signal("mm3_rxdp",
380 OMAP_PIN_INPUT_PULLDOWN);
381 omap_mux_init_signal("mm3_rxdm",
382 OMAP_PIN_INPUT_PULLDOWN);
383 /* FALLTHROUGH */
384 case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
385 case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
386 omap_mux_init_signal("mm3_rxrcv",
387 OMAP_PIN_INPUT_PULLDOWN);
388 /* FALLTHROUGH */
389 case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
390 case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
391 omap_mux_init_signal("mm3_txen_n", OMAP_PIN_OUTPUT);
392 /* FALLTHROUGH */
393 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
394 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
395 omap_mux_init_signal("mm3_txse0",
396 OMAP_PIN_INPUT_PULLDOWN);
397 omap_mux_init_signal("mm3_txdat",
398 OMAP_PIN_INPUT_PULLDOWN);
399 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +0530400 case OMAP_USBHS_PORT_MODE_UNUSED:
Anand Gadiyar95344fc2010-05-10 21:56:10 +0530401 /* FALLTHROUGH */
402 default:
403 break;
404 }
405}
406
Igor Grinberg1512f0d2012-03-26 16:51:10 +0200407static
408void __init setup_4430ohci_io_mux(const enum usbhs_omap_port_mode *port_mode)
Keshava Munegowda22363962011-03-01 20:08:18 +0530409{
410 switch (port_mode[0]) {
411 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
412 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
413 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
414 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
415 omap_mux_init_signal("usbb1_mm_rxdp",
416 OMAP_PIN_INPUT_PULLDOWN);
417 omap_mux_init_signal("usbb1_mm_rxdm",
418 OMAP_PIN_INPUT_PULLDOWN);
419
420 case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
421 case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
422 omap_mux_init_signal("usbb1_mm_rxrcv",
423 OMAP_PIN_INPUT_PULLDOWN);
424
425 case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
426 case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
427 omap_mux_init_signal("usbb1_mm_txen",
428 OMAP_PIN_INPUT_PULLDOWN);
429
430
431 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
432 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
433 omap_mux_init_signal("usbb1_mm_txdat",
434 OMAP_PIN_INPUT_PULLDOWN);
435 omap_mux_init_signal("usbb1_mm_txse0",
436 OMAP_PIN_INPUT_PULLDOWN);
437 break;
438
439 case OMAP_USBHS_PORT_MODE_UNUSED:
440 default:
441 break;
442 }
443
444 switch (port_mode[1]) {
445 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
446 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
447 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
448 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
449 omap_mux_init_signal("usbb2_mm_rxdp",
450 OMAP_PIN_INPUT_PULLDOWN);
451 omap_mux_init_signal("usbb2_mm_rxdm",
452 OMAP_PIN_INPUT_PULLDOWN);
453
454 case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
455 case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
456 omap_mux_init_signal("usbb2_mm_rxrcv",
457 OMAP_PIN_INPUT_PULLDOWN);
458
459 case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
460 case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
461 omap_mux_init_signal("usbb2_mm_txen",
462 OMAP_PIN_INPUT_PULLDOWN);
463
464
465 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
466 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
467 omap_mux_init_signal("usbb2_mm_txdat",
468 OMAP_PIN_INPUT_PULLDOWN);
469 omap_mux_init_signal("usbb2_mm_txse0",
470 OMAP_PIN_INPUT_PULLDOWN);
471 break;
472
473 case OMAP_USBHS_PORT_MODE_UNUSED:
474 default:
475 break;
476 }
477}
478
Roger Quadros42973152013-02-14 10:13:48 +0200479void __init usbhs_init(struct usbhs_omap_platform_data *pdata)
Keshava Munegowda22363962011-03-01 20:08:18 +0530480{
Keshava Munegowda760189b2012-07-16 19:01:10 +0530481 struct omap_hwmod *uhh_hwm, *tll_hwm;
Felipe Balbiabe763f2012-02-14 10:54:46 +0200482 struct platform_device *pdev;
Keshava Munegowda50b2a9b2011-10-11 13:21:37 +0530483 int bus_id = -1;
Keshava Munegowda22363962011-03-01 20:08:18 +0530484
485 if (cpu_is_omap34xx()) {
Keshava Munegowda22363962011-03-01 20:08:18 +0530486 setup_ehci_io_mux(pdata->port_mode);
487 setup_ohci_io_mux(pdata->port_mode);
Roger Quadros63b68902012-12-14 09:09:11 -0800488
489 if (omap_rev() <= OMAP3430_REV_ES2_1)
Roger Quadros42973152013-02-14 10:13:48 +0200490 pdata->single_ulpi_bypass = true;
Roger Quadros63b68902012-12-14 09:09:11 -0800491
Keshava Munegowda22363962011-03-01 20:08:18 +0530492 } else if (cpu_is_omap44xx()) {
Keshava Munegowda22363962011-03-01 20:08:18 +0530493 setup_4430ehci_io_mux(pdata->port_mode);
494 setup_4430ohci_io_mux(pdata->port_mode);
495 }
496
Keshava Munegowda760189b2012-07-16 19:01:10 +0530497 uhh_hwm = omap_hwmod_lookup(USBHS_UHH_HWMODNAME);
498 if (!uhh_hwm) {
Keshava Munegowda50b2a9b2011-10-11 13:21:37 +0530499 pr_err("Could not look up %s\n", USBHS_UHH_HWMODNAME);
500 return;
Keshava Munegowda22363962011-03-01 20:08:18 +0530501 }
502
Keshava Munegowda760189b2012-07-16 19:01:10 +0530503 tll_hwm = omap_hwmod_lookup(USBHS_TLL_HWMODNAME);
504 if (!tll_hwm) {
Keshava Munegowda50b2a9b2011-10-11 13:21:37 +0530505 pr_err("Could not look up %s\n", USBHS_TLL_HWMODNAME);
506 return;
507 }
Keshava Munegowda22363962011-03-01 20:08:18 +0530508
Keshava Munegowda760189b2012-07-16 19:01:10 +0530509 pdev = omap_device_build(OMAP_USBTLL_DEVICE, bus_id, tll_hwm,
Arnd Bergmann6e7f7cf2013-02-19 20:54:15 +0100510 pdata, sizeof(*pdata));
Felipe Balbiabe763f2012-02-14 10:54:46 +0200511 if (IS_ERR(pdev)) {
Keshava Munegowda760189b2012-07-16 19:01:10 +0530512 pr_err("Could not build hwmod device %s\n",
513 USBHS_TLL_HWMODNAME);
514 return;
515 }
516
517 pdev = omap_device_build(OMAP_USBHS_DEVICE, bus_id, uhh_hwm,
Arnd Bergmann6e7f7cf2013-02-19 20:54:15 +0100518 pdata, sizeof(*pdata));
Keshava Munegowda760189b2012-07-16 19:01:10 +0530519 if (IS_ERR(pdev)) {
520 pr_err("Could not build hwmod devices %s\n",
521 USBHS_UHH_HWMODNAME);
Keshava Munegowda50b2a9b2011-10-11 13:21:37 +0530522 return;
523 }
Keshava Munegowda22363962011-03-01 20:08:18 +0530524}
525
Anand Gadiyar95344fc2010-05-10 21:56:10 +0530526#else
527
Roger Quadros42973152013-02-14 10:13:48 +0200528void __init usbhs_init(struct usbhs_omap_platform_data *pdata)
Keshava Munegowda22363962011-03-01 20:08:18 +0530529{
530}
531
Keshava Munegowda22363962011-03-01 20:08:18 +0530532#endif
Roger Quadros5ecd52e2013-03-20 17:44:41 +0200533
534/* Template for PHY regulators */
535static struct fixed_voltage_config hsusb_reg_config = {
536 /* .supply_name filled later */
537 .microvolts = 3300000,
538 .gpio = -1, /* updated later */
539 .startup_delay = 70000, /* 70msec */
540 .enable_high = 1, /* updated later */
541 .enabled_at_boot = 0, /* keep in RESET */
542 /* .init_data filled later */
543};
544
545static const char *nop_name = "nop_usb_xceiv"; /* NOP PHY driver */
546static const char *reg_name = "reg-fixed-voltage"; /* Regulator driver */
547
548/**
549 * usbhs_add_regulator - Add a gpio based fixed voltage regulator device
550 * @name: name for the regulator
551 * @dev_id: device id of the device this regulator supplies power to
552 * @dev_supply: supply name that the device expects
553 * @gpio: GPIO number
554 * @polarity: 1 - Active high, 0 - Active low
555 */
556static int usbhs_add_regulator(char *name, char *dev_id, char *dev_supply,
557 int gpio, int polarity)
558{
559 struct regulator_consumer_supply *supplies;
560 struct regulator_init_data *reg_data;
561 struct fixed_voltage_config *config;
562 struct platform_device *pdev;
563 int ret;
564
565 supplies = kzalloc(sizeof(*supplies), GFP_KERNEL);
566 if (!supplies)
567 return -ENOMEM;
568
569 supplies->supply = dev_supply;
570 supplies->dev_name = dev_id;
571
572 reg_data = kzalloc(sizeof(*reg_data), GFP_KERNEL);
573 if (!reg_data)
574 return -ENOMEM;
575
576 reg_data->constraints.valid_ops_mask = REGULATOR_CHANGE_STATUS;
577 reg_data->consumer_supplies = supplies;
578 reg_data->num_consumer_supplies = 1;
579
580 config = kmemdup(&hsusb_reg_config, sizeof(hsusb_reg_config),
581 GFP_KERNEL);
582 if (!config)
583 return -ENOMEM;
584
585 config->supply_name = name;
586 config->gpio = gpio;
587 config->enable_high = polarity;
588 config->init_data = reg_data;
589
590 /* create a regulator device */
591 pdev = kzalloc(sizeof(*pdev), GFP_KERNEL);
592 if (!pdev)
593 return -ENOMEM;
594
595 pdev->id = PLATFORM_DEVID_AUTO;
596 pdev->name = reg_name;
597 pdev->dev.platform_data = config;
598
599 ret = platform_device_register(pdev);
600 if (ret)
601 pr_err("%s: Failed registering regulator %s for %s\n",
602 __func__, name, dev_id);
603
604 return ret;
605}
606
607int usbhs_init_phys(struct usbhs_phy_data *phy, int num_phys)
608{
609 char *rail_name;
610 int i, len;
611 struct platform_device *pdev;
612 char *phy_id;
613
614 /* the phy_id will be something like "nop_usb_xceiv.1" */
615 len = strlen(nop_name) + 3; /* 3 -> ".1" and NULL terminator */
616
617 for (i = 0; i < num_phys; i++) {
618
619 if (!phy->port) {
620 pr_err("%s: Invalid port 0. Must start from 1\n",
621 __func__);
622 continue;
623 }
624
625 /* do we need a NOP PHY device ? */
626 if (!gpio_is_valid(phy->reset_gpio) &&
627 !gpio_is_valid(phy->vcc_gpio))
628 continue;
629
630 /* create a NOP PHY device */
631 pdev = kzalloc(sizeof(*pdev), GFP_KERNEL);
632 if (!pdev)
633 return -ENOMEM;
634
635 pdev->id = phy->port;
636 pdev->name = nop_name;
637 pdev->dev.platform_data = phy->platform_data;
638
639 phy_id = kmalloc(len, GFP_KERNEL);
640 if (!phy_id)
641 return -ENOMEM;
642
643 scnprintf(phy_id, len, "nop_usb_xceiv.%d\n",
644 pdev->id);
645
646 if (platform_device_register(pdev)) {
647 pr_err("%s: Failed to register device %s\n",
648 __func__, phy_id);
649 continue;
650 }
651
652 usb_bind_phy("ehci-omap.0", phy->port - 1, phy_id);
653
654 /* Do we need RESET regulator ? */
655 if (gpio_is_valid(phy->reset_gpio)) {
656
657 rail_name = kmalloc(13, GFP_KERNEL);
658 if (!rail_name)
659 return -ENOMEM;
660
661 scnprintf(rail_name, 13, "hsusb%d_reset", phy->port);
662
663 usbhs_add_regulator(rail_name, phy_id, "reset",
664 phy->reset_gpio, 1);
665 }
666
667 /* Do we need VCC regulator ? */
668 if (gpio_is_valid(phy->vcc_gpio)) {
669
670 rail_name = kmalloc(13, GFP_KERNEL);
671 if (!rail_name)
672 return -ENOMEM;
673
674 scnprintf(rail_name, 13, "hsusb%d_vcc", phy->port);
675
676 usbhs_add_regulator(rail_name, phy_id, "vcc",
677 phy->vcc_gpio, phy->vcc_polarity);
678 }
679
680 phy++;
681 }
682
683 return 0;
684}