Linux Audio

Check our new training course

Loading...
v3.1
  1/*
  2 * Copyright (c) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
  3 * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
  4 *
  5 * This program is free software; you can redistribute it and/or modify it
  6 * under the terms of the GNU General Public License as published by the
  7 * Free Software Foundation; either version 2 of the License, or (at your
  8 * option) any later version.
  9 *
 10 * This program is distributed in the hope that it will be useful, but
 11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 12 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 13 * for more details.
 14 *
 15 * You should have received a copy of the GNU General Public License
 16 * along with this program; if not, write to the Free Software Foundation,
 17 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 18 */
 19
 20#include <linux/platform_device.h>
 21#include <linux/clk.h>
 22#include <linux/delay.h>
 23#include <linux/usb/otg.h>
 24#include <linux/usb/ulpi.h>
 25#include <linux/slab.h>
 26
 27#include <mach/hardware.h>
 28#include <mach/mxc_ehci.h>
 29
 30#include <asm/mach-types.h>
 31
 32#define ULPI_VIEWPORT_OFFSET	0x170
 33
 34struct ehci_mxc_priv {
 35	struct clk *usbclk, *ahbclk, *phy1clk;
 36	struct usb_hcd *hcd;
 37};
 38
 39/* called during probe() after chip reset completes */
 40static int ehci_mxc_setup(struct usb_hcd *hcd)
 41{
 42	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
 43	int retval;
 44
 45	dbg_hcs_params(ehci, "reset");
 46	dbg_hcc_params(ehci, "reset");
 47
 48	/* cache this readonly data; minimize chip reads */
 49	ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
 50
 51	hcd->has_tt = 1;
 52
 53	retval = ehci_halt(ehci);
 54	if (retval)
 55		return retval;
 56
 57	/* data structure init */
 58	retval = ehci_init(hcd);
 59	if (retval)
 60		return retval;
 61
 62	ehci->sbrn = 0x20;
 63
 64	ehci_reset(ehci);
 65
 66	ehci_port_power(ehci, 0);
 67	return 0;
 68}
 69
 70static const struct hc_driver ehci_mxc_hc_driver = {
 71	.description = hcd_name,
 72	.product_desc = "Freescale On-Chip EHCI Host Controller",
 73	.hcd_priv_size = sizeof(struct ehci_hcd),
 74
 75	/*
 76	 * generic hardware linkage
 77	 */
 78	.irq = ehci_irq,
 79	.flags = HCD_USB2 | HCD_MEMORY,
 80
 81	/*
 82	 * basic lifecycle operations
 83	 */
 84	.reset = ehci_mxc_setup,
 85	.start = ehci_run,
 86	.stop = ehci_stop,
 87	.shutdown = ehci_shutdown,
 88
 89	/*
 90	 * managing i/o requests and associated device resources
 91	 */
 92	.urb_enqueue = ehci_urb_enqueue,
 93	.urb_dequeue = ehci_urb_dequeue,
 94	.endpoint_disable = ehci_endpoint_disable,
 95	.endpoint_reset = ehci_endpoint_reset,
 96
 97	/*
 98	 * scheduling support
 99	 */
100	.get_frame_number = ehci_get_frame,
101
102	/*
103	 * root hub support
104	 */
105	.hub_status_data = ehci_hub_status_data,
106	.hub_control = ehci_hub_control,
107	.bus_suspend = ehci_bus_suspend,
108	.bus_resume = ehci_bus_resume,
109	.relinquish_port = ehci_relinquish_port,
110	.port_handed_over = ehci_port_handed_over,
111
112	.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
113};
114
115static int ehci_mxc_drv_probe(struct platform_device *pdev)
116{
117	struct mxc_usbh_platform_data *pdata = pdev->dev.platform_data;
118	struct usb_hcd *hcd;
119	struct resource *res;
120	int irq, ret;
121	unsigned int flags;
122	struct ehci_mxc_priv *priv;
123	struct device *dev = &pdev->dev;
124	struct ehci_hcd *ehci;
125
126	dev_info(&pdev->dev, "initializing i.MX USB Controller\n");
127
128	if (!pdata) {
129		dev_err(dev, "No platform data given, bailing out.\n");
130		return -EINVAL;
131	}
132
133	irq = platform_get_irq(pdev, 0);
134
135	hcd = usb_create_hcd(&ehci_mxc_hc_driver, dev, dev_name(dev));
136	if (!hcd)
137		return -ENOMEM;
138
139	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
140	if (!priv) {
141		ret = -ENOMEM;
142		goto err_alloc;
143	}
144
145	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
146	if (!res) {
147		dev_err(dev, "Found HC with no register addr. Check setup!\n");
148		ret = -ENODEV;
149		goto err_get_resource;
150	}
151
152	hcd->rsrc_start = res->start;
153	hcd->rsrc_len = resource_size(res);
154
155	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
156		dev_dbg(dev, "controller already in use\n");
157		ret = -EBUSY;
158		goto err_request_mem;
159	}
160
161	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
162	if (!hcd->regs) {
163		dev_err(dev, "error mapping memory\n");
164		ret = -EFAULT;
165		goto err_ioremap;
166	}
167
168	/* enable clocks */
169	priv->usbclk = clk_get(dev, "usb");
170	if (IS_ERR(priv->usbclk)) {
171		ret = PTR_ERR(priv->usbclk);
172		goto err_clk;
173	}
174	clk_enable(priv->usbclk);
175
176	if (!cpu_is_mx35() && !cpu_is_mx25()) {
177		priv->ahbclk = clk_get(dev, "usb_ahb");
178		if (IS_ERR(priv->ahbclk)) {
179			ret = PTR_ERR(priv->ahbclk);
180			goto err_clk_ahb;
181		}
182		clk_enable(priv->ahbclk);
183	}
 
184
185	/* "dr" device has its own clock on i.MX51 */
186	if (cpu_is_mx51() && (pdev->id == 0)) {
187		priv->phy1clk = clk_get(dev, "usb_phy1");
188		if (IS_ERR(priv->phy1clk)) {
189			ret = PTR_ERR(priv->phy1clk);
190			goto err_clk_phy;
191		}
192		clk_enable(priv->phy1clk);
193	}
194
195
196	/* call platform specific init function */
197	if (pdata->init) {
198		ret = pdata->init(pdev);
199		if (ret) {
200			dev_err(dev, "platform init failed\n");
201			goto err_init;
202		}
203		/* platforms need some time to settle changed IO settings */
204		mdelay(10);
205	}
206
207	ehci = hcd_to_ehci(hcd);
208
209	/* EHCI registers start at offset 0x100 */
210	ehci->caps = hcd->regs + 0x100;
211	ehci->regs = hcd->regs + 0x100 +
212		HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase));
213
214	/* set up the PORTSCx register */
215	ehci_writel(ehci, pdata->portsc, &ehci->regs->port_status[0]);
216
217	/* is this really needed? */
218	msleep(10);
219
220	/* Initialize the transceiver */
221	if (pdata->otg) {
222		pdata->otg->io_priv = hcd->regs + ULPI_VIEWPORT_OFFSET;
223		ret = otg_init(pdata->otg);
224		if (ret) {
225			dev_err(dev, "unable to init transceiver, probably missing\n");
226			ret = -ENODEV;
227			goto err_add;
228		}
229		ret = otg_set_vbus(pdata->otg, 1);
230		if (ret) {
231			dev_err(dev, "unable to enable vbus on transceiver\n");
232			goto err_add;
233		}
234	}
235
236	priv->hcd = hcd;
237	platform_set_drvdata(pdev, priv);
238
239	ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
240	if (ret)
241		goto err_add;
242
243	if (pdata->otg) {
244		/*
245		 * efikamx and efikasb have some hardware bug which is
246		 * preventing usb to work unless CHRGVBUS is set.
247		 * It's in violation of USB specs
248		 */
249		if (machine_is_mx51_efikamx() || machine_is_mx51_efikasb()) {
250			flags = otg_io_read(pdata->otg, ULPI_OTG_CTRL);
 
251			flags |= ULPI_OTG_CTRL_CHRGVBUS;
252			ret = otg_io_write(pdata->otg, flags, ULPI_OTG_CTRL);
 
253			if (ret) {
254				dev_err(dev, "unable to set CHRVBUS\n");
255				goto err_add;
256			}
257		}
258	}
259
260	return 0;
261
262err_add:
263	if (pdata && pdata->exit)
264		pdata->exit(pdev);
265err_init:
266	if (priv->phy1clk) {
267		clk_disable(priv->phy1clk);
268		clk_put(priv->phy1clk);
269	}
270err_clk_phy:
271	if (priv->ahbclk) {
272		clk_disable(priv->ahbclk);
273		clk_put(priv->ahbclk);
274	}
 
 
 
275err_clk_ahb:
276	clk_disable(priv->usbclk);
277	clk_put(priv->usbclk);
278err_clk:
279	iounmap(hcd->regs);
280err_ioremap:
281	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
282err_request_mem:
283err_get_resource:
284	kfree(priv);
285err_alloc:
286	usb_put_hcd(hcd);
287	return ret;
288}
289
290static int __exit ehci_mxc_drv_remove(struct platform_device *pdev)
291{
292	struct mxc_usbh_platform_data *pdata = pdev->dev.platform_data;
293	struct ehci_mxc_priv *priv = platform_get_drvdata(pdev);
294	struct usb_hcd *hcd = priv->hcd;
295
296	if (pdata && pdata->exit)
297		pdata->exit(pdev);
298
299	if (pdata->otg)
300		otg_shutdown(pdata->otg);
301
302	usb_remove_hcd(hcd);
303	iounmap(hcd->regs);
304	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
305	usb_put_hcd(hcd);
306	platform_set_drvdata(pdev, NULL);
307
308	clk_disable(priv->usbclk);
309	clk_put(priv->usbclk);
310	if (priv->ahbclk) {
311		clk_disable(priv->ahbclk);
312		clk_put(priv->ahbclk);
313	}
314	if (priv->phy1clk) {
315		clk_disable(priv->phy1clk);
316		clk_put(priv->phy1clk);
317	}
318
319	kfree(priv);
320
321	return 0;
322}
323
324static void ehci_mxc_drv_shutdown(struct platform_device *pdev)
325{
326	struct ehci_mxc_priv *priv = platform_get_drvdata(pdev);
327	struct usb_hcd *hcd = priv->hcd;
328
329	if (hcd->driver->shutdown)
330		hcd->driver->shutdown(hcd);
331}
332
333MODULE_ALIAS("platform:mxc-ehci");
334
335static struct platform_driver ehci_mxc_driver = {
336	.probe = ehci_mxc_drv_probe,
337	.remove = __exit_p(ehci_mxc_drv_remove),
338	.shutdown = ehci_mxc_drv_shutdown,
339	.driver = {
340		   .name = "mxc-ehci",
341	},
342};
v3.5.6
  1/*
  2 * Copyright (c) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
  3 * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
  4 *
  5 * This program is free software; you can redistribute it and/or modify it
  6 * under the terms of the GNU General Public License as published by the
  7 * Free Software Foundation; either version 2 of the License, or (at your
  8 * option) any later version.
  9 *
 10 * This program is distributed in the hope that it will be useful, but
 11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 12 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 13 * for more details.
 14 *
 15 * You should have received a copy of the GNU General Public License
 16 * along with this program; if not, write to the Free Software Foundation,
 17 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 18 */
 19
 20#include <linux/platform_device.h>
 21#include <linux/clk.h>
 22#include <linux/delay.h>
 23#include <linux/usb/otg.h>
 24#include <linux/usb/ulpi.h>
 25#include <linux/slab.h>
 26
 27#include <mach/hardware.h>
 28#include <mach/mxc_ehci.h>
 29
 30#include <asm/mach-types.h>
 31
 32#define ULPI_VIEWPORT_OFFSET	0x170
 33
 34struct ehci_mxc_priv {
 35	struct clk *usbclk, *ahbclk, *phyclk;
 36	struct usb_hcd *hcd;
 37};
 38
 39/* called during probe() after chip reset completes */
 40static int ehci_mxc_setup(struct usb_hcd *hcd)
 41{
 42	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
 43	int retval;
 44
 45	dbg_hcs_params(ehci, "reset");
 46	dbg_hcc_params(ehci, "reset");
 47
 48	/* cache this readonly data; minimize chip reads */
 49	ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
 50
 51	hcd->has_tt = 1;
 52
 53	retval = ehci_halt(ehci);
 54	if (retval)
 55		return retval;
 56
 57	/* data structure init */
 58	retval = ehci_init(hcd);
 59	if (retval)
 60		return retval;
 61
 62	ehci->sbrn = 0x20;
 63
 64	ehci_reset(ehci);
 65
 66	ehci_port_power(ehci, 0);
 67	return 0;
 68}
 69
 70static const struct hc_driver ehci_mxc_hc_driver = {
 71	.description = hcd_name,
 72	.product_desc = "Freescale On-Chip EHCI Host Controller",
 73	.hcd_priv_size = sizeof(struct ehci_hcd),
 74
 75	/*
 76	 * generic hardware linkage
 77	 */
 78	.irq = ehci_irq,
 79	.flags = HCD_USB2 | HCD_MEMORY,
 80
 81	/*
 82	 * basic lifecycle operations
 83	 */
 84	.reset = ehci_mxc_setup,
 85	.start = ehci_run,
 86	.stop = ehci_stop,
 87	.shutdown = ehci_shutdown,
 88
 89	/*
 90	 * managing i/o requests and associated device resources
 91	 */
 92	.urb_enqueue = ehci_urb_enqueue,
 93	.urb_dequeue = ehci_urb_dequeue,
 94	.endpoint_disable = ehci_endpoint_disable,
 95	.endpoint_reset = ehci_endpoint_reset,
 96
 97	/*
 98	 * scheduling support
 99	 */
100	.get_frame_number = ehci_get_frame,
101
102	/*
103	 * root hub support
104	 */
105	.hub_status_data = ehci_hub_status_data,
106	.hub_control = ehci_hub_control,
107	.bus_suspend = ehci_bus_suspend,
108	.bus_resume = ehci_bus_resume,
109	.relinquish_port = ehci_relinquish_port,
110	.port_handed_over = ehci_port_handed_over,
111
112	.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
113};
114
115static int ehci_mxc_drv_probe(struct platform_device *pdev)
116{
117	struct mxc_usbh_platform_data *pdata = pdev->dev.platform_data;
118	struct usb_hcd *hcd;
119	struct resource *res;
120	int irq, ret;
121	unsigned int flags;
122	struct ehci_mxc_priv *priv;
123	struct device *dev = &pdev->dev;
124	struct ehci_hcd *ehci;
125
126	dev_info(&pdev->dev, "initializing i.MX USB Controller\n");
127
128	if (!pdata) {
129		dev_err(dev, "No platform data given, bailing out.\n");
130		return -EINVAL;
131	}
132
133	irq = platform_get_irq(pdev, 0);
134
135	hcd = usb_create_hcd(&ehci_mxc_hc_driver, dev, dev_name(dev));
136	if (!hcd)
137		return -ENOMEM;
138
139	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
140	if (!priv) {
141		ret = -ENOMEM;
142		goto err_alloc;
143	}
144
145	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
146	if (!res) {
147		dev_err(dev, "Found HC with no register addr. Check setup!\n");
148		ret = -ENODEV;
149		goto err_get_resource;
150	}
151
152	hcd->rsrc_start = res->start;
153	hcd->rsrc_len = resource_size(res);
154
155	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
156		dev_dbg(dev, "controller already in use\n");
157		ret = -EBUSY;
158		goto err_request_mem;
159	}
160
161	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
162	if (!hcd->regs) {
163		dev_err(dev, "error mapping memory\n");
164		ret = -EFAULT;
165		goto err_ioremap;
166	}
167
168	/* enable clocks */
169	priv->usbclk = clk_get(dev, "ipg");
170	if (IS_ERR(priv->usbclk)) {
171		ret = PTR_ERR(priv->usbclk);
172		goto err_clk;
173	}
174	clk_prepare_enable(priv->usbclk);
175
176	priv->ahbclk = clk_get(dev, "ahb");
177	if (IS_ERR(priv->ahbclk)) {
178		ret = PTR_ERR(priv->ahbclk);
179		goto err_clk_ahb;
 
 
 
180	}
181	clk_prepare_enable(priv->ahbclk);
182
183	/* "dr" device has its own clock on i.MX51 */
184	priv->phyclk = clk_get(dev, "phy");
185	if (IS_ERR(priv->phyclk))
186		priv->phyclk = NULL;
187	if (priv->phyclk)
188		clk_prepare_enable(priv->phyclk);
 
 
 
189
190
191	/* call platform specific init function */
192	if (pdata->init) {
193		ret = pdata->init(pdev);
194		if (ret) {
195			dev_err(dev, "platform init failed\n");
196			goto err_init;
197		}
198		/* platforms need some time to settle changed IO settings */
199		mdelay(10);
200	}
201
202	ehci = hcd_to_ehci(hcd);
203
204	/* EHCI registers start at offset 0x100 */
205	ehci->caps = hcd->regs + 0x100;
206	ehci->regs = hcd->regs + 0x100 +
207		HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase));
208
209	/* set up the PORTSCx register */
210	ehci_writel(ehci, pdata->portsc, &ehci->regs->port_status[0]);
211
212	/* is this really needed? */
213	msleep(10);
214
215	/* Initialize the transceiver */
216	if (pdata->otg) {
217		pdata->otg->io_priv = hcd->regs + ULPI_VIEWPORT_OFFSET;
218		ret = usb_phy_init(pdata->otg);
219		if (ret) {
220			dev_err(dev, "unable to init transceiver, probably missing\n");
221			ret = -ENODEV;
222			goto err_add;
223		}
224		ret = otg_set_vbus(pdata->otg->otg, 1);
225		if (ret) {
226			dev_err(dev, "unable to enable vbus on transceiver\n");
227			goto err_add;
228		}
229	}
230
231	priv->hcd = hcd;
232	platform_set_drvdata(pdev, priv);
233
234	ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
235	if (ret)
236		goto err_add;
237
238	if (pdata->otg) {
239		/*
240		 * efikamx and efikasb have some hardware bug which is
241		 * preventing usb to work unless CHRGVBUS is set.
242		 * It's in violation of USB specs
243		 */
244		if (machine_is_mx51_efikamx() || machine_is_mx51_efikasb()) {
245			flags = usb_phy_io_read(pdata->otg,
246							ULPI_OTG_CTRL);
247			flags |= ULPI_OTG_CTRL_CHRGVBUS;
248			ret = usb_phy_io_write(pdata->otg, flags,
249							ULPI_OTG_CTRL);
250			if (ret) {
251				dev_err(dev, "unable to set CHRVBUS\n");
252				goto err_add;
253			}
254		}
255	}
256
257	return 0;
258
259err_add:
260	if (pdata && pdata->exit)
261		pdata->exit(pdev);
262err_init:
263	if (priv->phyclk) {
264		clk_disable_unprepare(priv->phyclk);
265		clk_put(priv->phyclk);
 
 
 
 
 
266	}
267
268	clk_disable_unprepare(priv->ahbclk);
269	clk_put(priv->ahbclk);
270err_clk_ahb:
271	clk_disable_unprepare(priv->usbclk);
272	clk_put(priv->usbclk);
273err_clk:
274	iounmap(hcd->regs);
275err_ioremap:
276	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
277err_request_mem:
278err_get_resource:
279	kfree(priv);
280err_alloc:
281	usb_put_hcd(hcd);
282	return ret;
283}
284
285static int __exit ehci_mxc_drv_remove(struct platform_device *pdev)
286{
287	struct mxc_usbh_platform_data *pdata = pdev->dev.platform_data;
288	struct ehci_mxc_priv *priv = platform_get_drvdata(pdev);
289	struct usb_hcd *hcd = priv->hcd;
290
291	if (pdata && pdata->exit)
292		pdata->exit(pdev);
293
294	if (pdata->otg)
295		usb_phy_shutdown(pdata->otg);
296
297	usb_remove_hcd(hcd);
298	iounmap(hcd->regs);
299	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
300	usb_put_hcd(hcd);
301	platform_set_drvdata(pdev, NULL);
302
303	clk_disable_unprepare(priv->usbclk);
304	clk_put(priv->usbclk);
305	clk_disable_unprepare(priv->ahbclk);
306	clk_put(priv->ahbclk);
307
308	if (priv->phyclk) {
309		clk_disable_unprepare(priv->phyclk);
310		clk_put(priv->phyclk);
 
311	}
312
313	kfree(priv);
314
315	return 0;
316}
317
318static void ehci_mxc_drv_shutdown(struct platform_device *pdev)
319{
320	struct ehci_mxc_priv *priv = platform_get_drvdata(pdev);
321	struct usb_hcd *hcd = priv->hcd;
322
323	if (hcd->driver->shutdown)
324		hcd->driver->shutdown(hcd);
325}
326
327MODULE_ALIAS("platform:mxc-ehci");
328
329static struct platform_driver ehci_mxc_driver = {
330	.probe = ehci_mxc_drv_probe,
331	.remove = __exit_p(ehci_mxc_drv_remove),
332	.shutdown = ehci_mxc_drv_shutdown,
333	.driver = {
334		   .name = "mxc-ehci",
335	},
336};