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 Original line Diff line number Diff line
@@ -216,6 +216,8 @@ struct mv_udc {
	struct work_struct	vbus_work;
	struct work_struct	vbus_work;
	struct workqueue_struct *qwork;
	struct workqueue_struct *qwork;


	struct otg_transceiver	*transceiver;

	struct mv_usb_platform_data     *pdata;
	struct mv_usb_platform_data     *pdata;


	/* some SOC has mutiple clock sources for USB*/
	/* some SOC has mutiple clock sources for USB*/
+30 −3
Original line number Original line Diff line number Diff line
@@ -1407,6 +1407,20 @@ static int mv_udc_start(struct usb_gadget_driver *driver,
		return retval;
		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 */
	/* pullup is always on */
	mv_udc_pullup(&udc->gadget, 1);
	mv_udc_pullup(&udc->gadget, 1);


@@ -2109,7 +2123,12 @@ static int __devexit mv_udc_remove(struct platform_device *dev)
		destroy_workqueue(udc->qwork);
		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_irq(udc->pdata->vbus->irq, &dev->dev);


	/* free memory allocated in probe */
	/* free memory allocated in probe */
@@ -2182,6 +2201,11 @@ static int __devinit mv_udc_probe(struct platform_device *dev)


	udc->dev = 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;
	udc->clknum = pdata->clknum;
	for (clk_i = 0; clk_i < udc->clknum; clk_i++) {
	for (clk_i = 0; clk_i < udc->clknum; clk_i++) {
		udc->clk[clk_i] = clk_get(&dev->dev, pdata->clkname[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);
	eps_init(udc);


	/* VBUS detect: we can disable/enable clock on demand.*/
	/* 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;
		udc->clock_gating = 1;
		retval = request_threaded_irq(pdata->vbus->irq, NULL,
		retval = request_threaded_irq(pdata->vbus->irq, NULL,
				mv_udc_vbus_irq, IRQF_ONESHOT, "vbus", udc);
				mv_udc_vbus_irq, IRQF_ONESHOT, "vbus", udc);
@@ -2371,7 +2397,8 @@ static int __devinit mv_udc_probe(struct platform_device *dev)
	return 0;
	return 0;


err_unregister:
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);
		free_irq(pdata->vbus->irq, &dev->dev);
	device_unregister(&udc->gadget.dev);
	device_unregister(&udc->gadget.dev);
err_free_irq:
err_free_irq: