Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 487d54d1 authored by Neil Zhang's avatar Neil Zhang Committed by Felipe Balbi
Browse files

usb: gadget: mv_udc: add otg relative code



Add otg relative code, make it possible to switch between host and
device.

Signed-off-by: default avatarNeil Zhang <zhangwm@marvell.com>
Signed-off-by: default avatarFelipe Balbi <balbi@ti.com>
parent 9823a525
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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*/
+30 −3
Original line number Diff line number Diff line
@@ -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: