summaryrefslogtreecommitdiff
path: root/drivers/usb/gadget/pxa27x_udc.c
diff options
context:
space:
mode:
authorRobert Jarzmik <robert.jarzmik@free.fr>2009-01-24 23:57:30 -0800
committerGreg Kroah-Hartman <gregkh@suse.de>2009-03-24 16:20:27 -0700
commit7fec3c25b773883bd50c4078bcccdd23d3dadeac (patch)
tree42d46e065d2408a34c0a255e8ac1dfcb71c85972 /drivers/usb/gadget/pxa27x_udc.c
parentb799a7eb68082af620b7e37b6f41c98802e831f6 (diff)
USB: pxa27x_udc: add otg transceiver support
When a transceiver driver is used, no automatic udc enable is done. The transceiver (OTG or not) should : - take care of VBus sensing - call usb_gadget_vbus_connect() - call usb_gadget_vbus_disconnect() The pullup should remain within this driver's management, either by gpio_pullup of udc_command() fields. Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr> Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/gadget/pxa27x_udc.c')
-rw-r--r--drivers/usb/gadget/pxa27x_udc.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c
index 0c9307118b54..11510472ee00 100644
--- a/drivers/usb/gadget/pxa27x_udc.c
+++ b/drivers/usb/gadget/pxa27x_udc.c
@@ -1779,10 +1779,21 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
dev_dbg(udc->dev, "registered gadget driver '%s'\n",
driver->driver.name);
+ if (udc->transceiver) {
+ retval = otg_set_peripheral(udc->transceiver, &udc->gadget);
+ if (retval) {
+ dev_err(udc->dev, "can't bind to transceiver\n");
+ goto transceiver_fail;
+ }
+ }
+
if (should_enable_udc(udc))
udc_enable(udc);
return 0;
+transceiver_fail:
+ if (driver->unbind)
+ driver->unbind(&udc->gadget);
bind_fail:
device_del(&udc->gadget.dev);
add_fail:
@@ -1840,9 +1851,11 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
udc->driver = NULL;
device_del(&udc->gadget.dev);
-
dev_info(udc->dev, "unregistered gadget driver '%s'\n",
driver->driver.name);
+
+ if (udc->transceiver)
+ return otg_set_peripheral(udc->transceiver, NULL);
return 0;
}
EXPORT_SYMBOL(usb_gadget_unregister_driver);
@@ -2359,6 +2372,7 @@ static int __init pxa_udc_probe(struct platform_device *pdev)
udc->dev = &pdev->dev;
udc->mach = pdev->dev.platform_data;
+ udc->transceiver = otg_get_transceiver();
gpio = udc->mach->gpio_pullup;
if (gpio_is_valid(gpio)) {
@@ -2431,6 +2445,9 @@ static int __exit pxa_udc_remove(struct platform_device *_dev)
if (gpio_is_valid(gpio))
gpio_free(gpio);
+ otg_put_transceiver(udc->transceiver);
+
+ udc->transceiver = NULL;
platform_set_drvdata(_dev, NULL);
the_controller = NULL;
clk_put(udc->clk);