• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * usb-host.c - OMAP USB Host
3  *
4  * This file will contain the board specific details for the
5  * Synopsys EHCI/OHCI host controller on OMAP3430 and onwards
6  *
7  * Copyright (C) 2007-2011 Texas Instruments
8  * Author: Vikram Pandita <vikram.pandita@ti.com>
9  * Author: Keshava Munegowda <keshava_mgowda@ti.com>
10  *
11  * Generalization by:
12  * Felipe Balbi <balbi@ti.com>
13  *
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>
23 #include <linux/slab.h>
24 #include <linux/dma-mapping.h>
25 #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>
31 #include <linux/usb/usb_phy_generic.h>
32 
33 #include "soc.h"
34 #include "omap_device.h"
35 #include "mux.h"
36 #include "usb.h"
37 
38 #ifdef CONFIG_MFD_OMAP_USB_HOST
39 
40 #define OMAP_USBHS_DEVICE	"usbhs_omap"
41 #define OMAP_USBTLL_DEVICE	"usbhs_tll"
42 #define	USBHS_UHH_HWMODNAME	"usb_host_hs"
43 #define USBHS_TLL_HWMODNAME	"usb_tll_hs"
44 
45 /* MUX settings for EHCI pins */
46 /*
47  * setup_ehci_io_mux - initialize IO pad mux for USBHOST
48  */
setup_ehci_io_mux(const enum usbhs_omap_port_mode * port_mode)49 static void __init setup_ehci_io_mux(const enum usbhs_omap_port_mode *port_mode)
50 {
51 	switch (port_mode[0]) {
52 	case OMAP_EHCI_PORT_MODE_PHY:
53 		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);
65 		break;
66 	case OMAP_EHCI_PORT_MODE_TLL:
67 		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);
91 		break;
92 	case OMAP_USBHS_PORT_MODE_UNUSED:
93 		/* FALLTHROUGH */
94 	default:
95 		break;
96 	}
97 
98 	switch (port_mode[1]) {
99 	case OMAP_EHCI_PORT_MODE_PHY:
100 		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);
120 		break;
121 	case OMAP_EHCI_PORT_MODE_TLL:
122 		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);
146 		break;
147 	case OMAP_USBHS_PORT_MODE_UNUSED:
148 		/* FALLTHROUGH */
149 	default:
150 		break;
151 	}
152 
153 	switch (port_mode[2]) {
154 	case OMAP_EHCI_PORT_MODE_PHY:
155 		printk(KERN_WARNING "Port3 can't be used in PHY mode\n");
156 		break;
157 	case OMAP_EHCI_PORT_MODE_TLL:
158 		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);
182 		break;
183 	case OMAP_USBHS_PORT_MODE_UNUSED:
184 		/* FALLTHROUGH */
185 	default:
186 		break;
187 	}
188 
189 	return;
190 }
191 
setup_ohci_io_mux(const enum usbhs_omap_port_mode * port_mode)192 static void __init setup_ohci_io_mux(const enum usbhs_omap_port_mode *port_mode)
193 {
194 	switch (port_mode[0]) {
195 	case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
196 	case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
197 	case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
198 	case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
199 		omap_mux_init_signal("mm1_rxdp",
200 			OMAP_PIN_INPUT_PULLDOWN);
201 		omap_mux_init_signal("mm1_rxdm",
202 			OMAP_PIN_INPUT_PULLDOWN);
203 		/* FALLTHROUGH */
204 	case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
205 	case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
206 		omap_mux_init_signal("mm1_rxrcv",
207 			OMAP_PIN_INPUT_PULLDOWN);
208 		/* FALLTHROUGH */
209 	case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
210 	case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
211 		omap_mux_init_signal("mm1_txen_n", OMAP_PIN_OUTPUT);
212 		/* FALLTHROUGH */
213 	case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
214 	case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
215 		omap_mux_init_signal("mm1_txse0",
216 			OMAP_PIN_INPUT_PULLDOWN);
217 		omap_mux_init_signal("mm1_txdat",
218 			OMAP_PIN_INPUT_PULLDOWN);
219 		break;
220 	case OMAP_USBHS_PORT_MODE_UNUSED:
221 		/* FALLTHROUGH */
222 	default:
223 		break;
224 	}
225 	switch (port_mode[1]) {
226 	case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
227 	case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
228 	case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
229 	case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
230 		omap_mux_init_signal("mm2_rxdp",
231 			OMAP_PIN_INPUT_PULLDOWN);
232 		omap_mux_init_signal("mm2_rxdm",
233 			OMAP_PIN_INPUT_PULLDOWN);
234 		/* FALLTHROUGH */
235 	case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
236 	case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
237 		omap_mux_init_signal("mm2_rxrcv",
238 			OMAP_PIN_INPUT_PULLDOWN);
239 		/* FALLTHROUGH */
240 	case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
241 	case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
242 		omap_mux_init_signal("mm2_txen_n", OMAP_PIN_OUTPUT);
243 		/* FALLTHROUGH */
244 	case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
245 	case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
246 		omap_mux_init_signal("mm2_txse0",
247 			OMAP_PIN_INPUT_PULLDOWN);
248 		omap_mux_init_signal("mm2_txdat",
249 			OMAP_PIN_INPUT_PULLDOWN);
250 		break;
251 	case OMAP_USBHS_PORT_MODE_UNUSED:
252 		/* FALLTHROUGH */
253 	default:
254 		break;
255 	}
256 	switch (port_mode[2]) {
257 	case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
258 	case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
259 	case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
260 	case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
261 		omap_mux_init_signal("mm3_rxdp",
262 			OMAP_PIN_INPUT_PULLDOWN);
263 		omap_mux_init_signal("mm3_rxdm",
264 			OMAP_PIN_INPUT_PULLDOWN);
265 		/* FALLTHROUGH */
266 	case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
267 	case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
268 		omap_mux_init_signal("mm3_rxrcv",
269 			OMAP_PIN_INPUT_PULLDOWN);
270 		/* FALLTHROUGH */
271 	case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
272 	case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
273 		omap_mux_init_signal("mm3_txen_n", OMAP_PIN_OUTPUT);
274 		/* FALLTHROUGH */
275 	case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
276 	case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
277 		omap_mux_init_signal("mm3_txse0",
278 			OMAP_PIN_INPUT_PULLDOWN);
279 		omap_mux_init_signal("mm3_txdat",
280 			OMAP_PIN_INPUT_PULLDOWN);
281 		break;
282 	case OMAP_USBHS_PORT_MODE_UNUSED:
283 		/* FALLTHROUGH */
284 	default:
285 		break;
286 	}
287 }
288 
usbhs_init(struct usbhs_omap_platform_data * pdata)289 void __init usbhs_init(struct usbhs_omap_platform_data *pdata)
290 {
291 	struct omap_hwmod	*uhh_hwm, *tll_hwm;
292 	struct platform_device	*pdev;
293 	int			bus_id = -1;
294 
295 	if (cpu_is_omap34xx()) {
296 		setup_ehci_io_mux(pdata->port_mode);
297 		setup_ohci_io_mux(pdata->port_mode);
298 
299 		if (omap_rev() <= OMAP3430_REV_ES2_1)
300 			pdata->single_ulpi_bypass = true;
301 
302 	}
303 
304 	uhh_hwm = omap_hwmod_lookup(USBHS_UHH_HWMODNAME);
305 	if (!uhh_hwm) {
306 		pr_err("Could not look up %s\n", USBHS_UHH_HWMODNAME);
307 		return;
308 	}
309 
310 	tll_hwm = omap_hwmod_lookup(USBHS_TLL_HWMODNAME);
311 	if (!tll_hwm) {
312 		pr_err("Could not look up %s\n", USBHS_TLL_HWMODNAME);
313 		return;
314 	}
315 
316 	pdev = omap_device_build(OMAP_USBTLL_DEVICE, bus_id, tll_hwm,
317 				pdata, sizeof(*pdata));
318 	if (IS_ERR(pdev)) {
319 		pr_err("Could not build hwmod device %s\n",
320 		       USBHS_TLL_HWMODNAME);
321 		return;
322 	}
323 
324 	pdev = omap_device_build(OMAP_USBHS_DEVICE, bus_id, uhh_hwm,
325 				pdata, sizeof(*pdata));
326 	if (IS_ERR(pdev)) {
327 		pr_err("Could not build hwmod devices %s\n",
328 		       USBHS_UHH_HWMODNAME);
329 		return;
330 	}
331 }
332 
333 #else
334 
usbhs_init(struct usbhs_omap_platform_data * pdata)335 void __init usbhs_init(struct usbhs_omap_platform_data *pdata)
336 {
337 }
338 
339 #endif
340 
341 /* Template for PHY regulators */
342 static struct fixed_voltage_config hsusb_reg_config = {
343 	/* .supply_name filled later */
344 	.microvolts = 3300000,
345 	.gpio = -1,		/* updated later */
346 	.startup_delay = 70000, /* 70msec */
347 	.enable_high = 1,	/* updated later */
348 	.enabled_at_boot = 0,	/* keep in RESET */
349 	/* .init_data filled later */
350 };
351 
352 static const char *nop_name = "usb_phy_generic"; /* NOP PHY driver */
353 static const char *reg_name = "reg-fixed-voltage"; /* Regulator driver */
354 
355 /**
356  * usbhs_add_regulator - Add a gpio based fixed voltage regulator device
357  * @name: name for the regulator
358  * @dev_id: device id of the device this regulator supplies power to
359  * @dev_supply: supply name that the device expects
360  * @gpio: GPIO number
361  * @polarity: 1 - Active high, 0 - Active low
362  */
usbhs_add_regulator(char * name,char * dev_id,char * dev_supply,int gpio,int polarity)363 static int usbhs_add_regulator(char *name, char *dev_id, char *dev_supply,
364 						int gpio, int polarity)
365 {
366 	struct regulator_consumer_supply *supplies;
367 	struct regulator_init_data *reg_data;
368 	struct fixed_voltage_config *config;
369 	struct platform_device *pdev;
370 	struct platform_device_info pdevinfo;
371 	int ret = -ENOMEM;
372 
373 	supplies = kzalloc(sizeof(*supplies), GFP_KERNEL);
374 	if (!supplies)
375 		return -ENOMEM;
376 
377 	supplies->supply = dev_supply;
378 	supplies->dev_name = dev_id;
379 
380 	reg_data = kzalloc(sizeof(*reg_data), GFP_KERNEL);
381 	if (!reg_data)
382 		goto err_data;
383 
384 	reg_data->constraints.valid_ops_mask = REGULATOR_CHANGE_STATUS;
385 	reg_data->consumer_supplies = supplies;
386 	reg_data->num_consumer_supplies = 1;
387 
388 	config = kmemdup(&hsusb_reg_config, sizeof(hsusb_reg_config),
389 			GFP_KERNEL);
390 	if (!config)
391 		goto err_config;
392 
393 	config->supply_name = kstrdup(name, GFP_KERNEL);
394 	if (!config->supply_name)
395 		goto err_supplyname;
396 
397 	config->gpio = gpio;
398 	config->enable_high = polarity;
399 	config->init_data = reg_data;
400 
401 	/* create a regulator device */
402 	memset(&pdevinfo, 0, sizeof(pdevinfo));
403 	pdevinfo.name = reg_name;
404 	pdevinfo.id = PLATFORM_DEVID_AUTO;
405 	pdevinfo.data = config;
406 	pdevinfo.size_data = sizeof(*config);
407 
408 	pdev = platform_device_register_full(&pdevinfo);
409 	if (IS_ERR(pdev)) {
410 		ret = PTR_ERR(pdev);
411 		pr_err("%s: Failed registering regulator %s for %s : %d\n",
412 				__func__, name, dev_id, ret);
413 		goto err_register;
414 	}
415 
416 	return 0;
417 
418 err_register:
419 	kfree(config->supply_name);
420 err_supplyname:
421 	kfree(config);
422 err_config:
423 	kfree(reg_data);
424 err_data:
425 	kfree(supplies);
426 	return ret;
427 }
428 
429 #define MAX_STR 20
430 
usbhs_init_phys(struct usbhs_phy_data * phy,int num_phys)431 int usbhs_init_phys(struct usbhs_phy_data *phy, int num_phys)
432 {
433 	char rail_name[MAX_STR];
434 	int i;
435 	struct platform_device *pdev;
436 	char *phy_id;
437 	struct platform_device_info pdevinfo;
438 	struct usb_phy_generic_platform_data nop_pdata;
439 
440 	for (i = 0; i < num_phys; i++) {
441 
442 		if (!phy->port) {
443 			pr_err("%s: Invalid port 0. Must start from 1\n",
444 						__func__);
445 			continue;
446 		}
447 
448 		/* do we need a NOP PHY device ? */
449 		if (!gpio_is_valid(phy->reset_gpio) &&
450 			!gpio_is_valid(phy->vcc_gpio))
451 			continue;
452 
453 		phy_id = kmalloc(MAX_STR, GFP_KERNEL);
454 		if (!phy_id) {
455 			pr_err("%s: kmalloc() failed\n", __func__);
456 			return -ENOMEM;
457 		}
458 
459 		/* set platform data */
460 		memset(&nop_pdata, 0, sizeof(nop_pdata));
461 		if (gpio_is_valid(phy->vcc_gpio))
462 			nop_pdata.needs_vcc = true;
463 		nop_pdata.gpio_reset = phy->reset_gpio;
464 		nop_pdata.type = USB_PHY_TYPE_USB2;
465 
466 		/* create a NOP PHY device */
467 		memset(&pdevinfo, 0, sizeof(pdevinfo));
468 		pdevinfo.name = nop_name;
469 		pdevinfo.id = phy->port;
470 		pdevinfo.data = &nop_pdata;
471 		pdevinfo.size_data =
472 			sizeof(struct usb_phy_generic_platform_data);
473 		scnprintf(phy_id, MAX_STR, "usb_phy_generic.%d",
474 					phy->port);
475 		pdev = platform_device_register_full(&pdevinfo);
476 		if (IS_ERR(pdev)) {
477 			pr_err("%s: Failed to register device %s : %ld\n",
478 				__func__,  phy_id, PTR_ERR(pdev));
479 			kfree(phy_id);
480 			continue;
481 		}
482 
483 		usb_bind_phy("ehci-omap.0", phy->port - 1, phy_id);
484 
485 		/* Do we need VCC regulator ? */
486 		if (gpio_is_valid(phy->vcc_gpio)) {
487 			scnprintf(rail_name, MAX_STR, "hsusb%d_vcc", phy->port);
488 			usbhs_add_regulator(rail_name, phy_id, "vcc",
489 					phy->vcc_gpio, phy->vcc_polarity);
490 		}
491 
492 		phy++;
493 	}
494 
495 	return 0;
496 }
497