aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Jarzmik <robert.jarzmik@free.fr>2009-01-25 02:57:30 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2009-03-24 19:20:27 -0400
commit7fec3c25b773883bd50c4078bcccdd23d3dadeac (patch)
tree42d46e065d2408a34c0a255e8ac1dfcb71c85972
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>
-rw-r--r--drivers/usb/gadget/Kconfig1
-rw-r--r--drivers/usb/gadget/pxa27x_udc.c19
-rw-r--r--drivers/usb/gadget/pxa27x_udc.h3
3 files changed, 22 insertions, 1 deletions
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index e55fef52a5dc..770b3eaa9184 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -254,6 +254,7 @@ config USB_PXA25X_SMALL
254config USB_GADGET_PXA27X 254config USB_GADGET_PXA27X
255 boolean "PXA 27x" 255 boolean "PXA 27x"
256 depends on ARCH_PXA && PXA27x 256 depends on ARCH_PXA && PXA27x
257 select USB_OTG_UTILS
257 help 258 help
258 Intel's PXA 27x series XScale ARM v5TE processors include 259 Intel's PXA 27x series XScale ARM v5TE processors include
259 an integrated full speed USB 1.1 device controller. 260 an integrated full speed USB 1.1 device controller.
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)
1779 dev_dbg(udc->dev, "registered gadget driver '%s'\n", 1779 dev_dbg(udc->dev, "registered gadget driver '%s'\n",
1780 driver->driver.name); 1780 driver->driver.name);
1781 1781
1782 if (udc->transceiver) {
1783 retval = otg_set_peripheral(udc->transceiver, &udc->gadget);
1784 if (retval) {
1785 dev_err(udc->dev, "can't bind to transceiver\n");
1786 goto transceiver_fail;
1787 }
1788 }
1789
1782 if (should_enable_udc(udc)) 1790 if (should_enable_udc(udc))
1783 udc_enable(udc); 1791 udc_enable(udc);
1784 return 0; 1792 return 0;
1785 1793
1794transceiver_fail:
1795 if (driver->unbind)
1796 driver->unbind(&udc->gadget);
1786bind_fail: 1797bind_fail:
1787 device_del(&udc->gadget.dev); 1798 device_del(&udc->gadget.dev);
1788add_fail: 1799add_fail:
@@ -1840,9 +1851,11 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
1840 udc->driver = NULL; 1851 udc->driver = NULL;
1841 1852
1842 device_del(&udc->gadget.dev); 1853 device_del(&udc->gadget.dev);
1843
1844 dev_info(udc->dev, "unregistered gadget driver '%s'\n", 1854 dev_info(udc->dev, "unregistered gadget driver '%s'\n",
1845 driver->driver.name); 1855 driver->driver.name);
1856
1857 if (udc->transceiver)
1858 return otg_set_peripheral(udc->transceiver, NULL);
1846 return 0; 1859 return 0;
1847} 1860}
1848EXPORT_SYMBOL(usb_gadget_unregister_driver); 1861EXPORT_SYMBOL(usb_gadget_unregister_driver);
@@ -2359,6 +2372,7 @@ static int __init pxa_udc_probe(struct platform_device *pdev)
2359 2372
2360 udc->dev = &pdev->dev; 2373 udc->dev = &pdev->dev;
2361 udc->mach = pdev->dev.platform_data; 2374 udc->mach = pdev->dev.platform_data;
2375 udc->transceiver = otg_get_transceiver();
2362 2376
2363 gpio = udc->mach->gpio_pullup; 2377 gpio = udc->mach->gpio_pullup;
2364 if (gpio_is_valid(gpio)) { 2378 if (gpio_is_valid(gpio)) {
@@ -2431,6 +2445,9 @@ static int __exit pxa_udc_remove(struct platform_device *_dev)
2431 if (gpio_is_valid(gpio)) 2445 if (gpio_is_valid(gpio))
2432 gpio_free(gpio); 2446 gpio_free(gpio);
2433 2447
2448 otg_put_transceiver(udc->transceiver);
2449
2450 udc->transceiver = NULL;
2434 platform_set_drvdata(_dev, NULL); 2451 platform_set_drvdata(_dev, NULL);
2435 the_controller = NULL; 2452 the_controller = NULL;
2436 clk_put(udc->clk); 2453 clk_put(udc->clk);
diff --git a/drivers/usb/gadget/pxa27x_udc.h b/drivers/usb/gadget/pxa27x_udc.h
index 64741e199204..db58125331da 100644
--- a/drivers/usb/gadget/pxa27x_udc.h
+++ b/drivers/usb/gadget/pxa27x_udc.h
@@ -26,6 +26,7 @@
26#include <linux/types.h> 26#include <linux/types.h>
27#include <linux/spinlock.h> 27#include <linux/spinlock.h>
28#include <linux/io.h> 28#include <linux/io.h>
29#include <linux/usb/otg.h>
29 30
30/* 31/*
31 * Register definitions 32 * Register definitions
@@ -421,6 +422,7 @@ struct udc_stats {
421 * @driver: bound gadget (zero, g_ether, g_file_storage, ...) 422 * @driver: bound gadget (zero, g_ether, g_file_storage, ...)
422 * @dev: device 423 * @dev: device
423 * @mach: machine info, used to activate specific GPIO 424 * @mach: machine info, used to activate specific GPIO
425 * @transceiver: external transceiver to handle vbus sense and D+ pullup
424 * @ep0state: control endpoint state machine state 426 * @ep0state: control endpoint state machine state
425 * @stats: statistics on udc usage 427 * @stats: statistics on udc usage
426 * @udc_usb_ep: array of usb endpoints offered by the gadget 428 * @udc_usb_ep: array of usb endpoints offered by the gadget
@@ -446,6 +448,7 @@ struct pxa_udc {
446 struct usb_gadget_driver *driver; 448 struct usb_gadget_driver *driver;
447 struct device *dev; 449 struct device *dev;
448 struct pxa2xx_udc_mach_info *mach; 450 struct pxa2xx_udc_mach_info *mach;
451 struct otg_transceiver *transceiver;
449 452
450 enum ep0_state ep0state; 453 enum ep0_state ep0state;
451 struct udc_stats stats; 454 struct udc_stats stats;