usb: gadget: mv_udc: add otg relative code
Add otg relative code, make it possible to switch between host and device. Signed-off-by: Neil Zhang <zhangwm@marvell.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
This commit is contained in:
parent
9823a52539
commit
487d54d172
@ -216,6 +216,8 @@ struct mv_udc {
|
||||
struct work_struct vbus_work;
|
||||
struct workqueue_struct *qwork;
|
||||
|
||||
struct otg_transceiver *transceiver;
|
||||
|
||||
struct mv_usb_platform_data *pdata;
|
||||
|
||||
/* some SOC has mutiple clock sources for USB*/
|
||||
|
@ -1407,6 +1407,20 @@ static int mv_udc_start(struct usb_gadget_driver *driver,
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (udc->transceiver) {
|
||||
retval = otg_set_peripheral(udc->transceiver, &udc->gadget);
|
||||
if (retval) {
|
||||
dev_err(&udc->dev->dev,
|
||||
"unable to register peripheral to otg\n");
|
||||
if (driver->unbind) {
|
||||
driver->unbind(&udc->gadget);
|
||||
udc->gadget.dev.driver = NULL;
|
||||
udc->driver = NULL;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
/* pullup is always on */
|
||||
mv_udc_pullup(&udc->gadget, 1);
|
||||
|
||||
@ -2109,7 +2123,12 @@ static int __devexit mv_udc_remove(struct platform_device *dev)
|
||||
destroy_workqueue(udc->qwork);
|
||||
}
|
||||
|
||||
if (udc->pdata && udc->pdata->vbus && udc->clock_gating)
|
||||
/*
|
||||
* If we have transceiver inited,
|
||||
* then vbus irq will not be requested in udc driver.
|
||||
*/
|
||||
if (udc->pdata && udc->pdata->vbus
|
||||
&& udc->clock_gating && udc->transceiver == NULL)
|
||||
free_irq(udc->pdata->vbus->irq, &dev->dev);
|
||||
|
||||
/* free memory allocated in probe */
|
||||
@ -2182,6 +2201,11 @@ static int __devinit mv_udc_probe(struct platform_device *dev)
|
||||
|
||||
udc->dev = dev;
|
||||
|
||||
#ifdef CONFIG_USB_OTG_UTILS
|
||||
if (pdata->mode == MV_USB_MODE_OTG)
|
||||
udc->transceiver = otg_get_transceiver();
|
||||
#endif
|
||||
|
||||
udc->clknum = pdata->clknum;
|
||||
for (clk_i = 0; clk_i < udc->clknum; clk_i++) {
|
||||
udc->clk[clk_i] = clk_get(&dev->dev, pdata->clkname[clk_i]);
|
||||
@ -2328,7 +2352,9 @@ static int __devinit mv_udc_probe(struct platform_device *dev)
|
||||
eps_init(udc);
|
||||
|
||||
/* VBUS detect: we can disable/enable clock on demand.*/
|
||||
if (pdata->vbus) {
|
||||
if (udc->transceiver)
|
||||
udc->clock_gating = 1;
|
||||
else if (pdata->vbus) {
|
||||
udc->clock_gating = 1;
|
||||
retval = request_threaded_irq(pdata->vbus->irq, NULL,
|
||||
mv_udc_vbus_irq, IRQF_ONESHOT, "vbus", udc);
|
||||
@ -2371,7 +2397,8 @@ static int __devinit mv_udc_probe(struct platform_device *dev)
|
||||
return 0;
|
||||
|
||||
err_unregister:
|
||||
if (udc->pdata && udc->pdata->vbus && udc->clock_gating)
|
||||
if (udc->pdata && udc->pdata->vbus
|
||||
&& udc->clock_gating && udc->transceiver == NULL)
|
||||
free_irq(pdata->vbus->irq, &dev->dev);
|
||||
device_unregister(&udc->gadget.dev);
|
||||
err_free_irq:
|
||||
|
Loading…
Reference in New Issue
Block a user