diff options
Diffstat (limited to 'drivers/usb/gadget/pxa25x_udc.c')
| -rw-r--r-- | drivers/usb/gadget/pxa25x_udc.c | 49 |
1 files changed, 45 insertions, 4 deletions
diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index ed21e263f832..e6fedbd5a654 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c | |||
| @@ -56,6 +56,7 @@ | |||
| 56 | 56 | ||
| 57 | #include <linux/usb/ch9.h> | 57 | #include <linux/usb/ch9.h> |
| 58 | #include <linux/usb/gadget.h> | 58 | #include <linux/usb/gadget.h> |
| 59 | #include <linux/usb/otg.h> | ||
| 59 | 60 | ||
| 60 | /* | 61 | /* |
| 61 | * This driver is PXA25x only. Grab the right register definitions. | 62 | * This driver is PXA25x only. Grab the right register definitions. |
| @@ -1008,15 +1009,27 @@ static int pxa25x_udc_pullup(struct usb_gadget *_gadget, int is_active) | |||
| 1008 | return 0; | 1009 | return 0; |
| 1009 | } | 1010 | } |
| 1010 | 1011 | ||
| 1012 | /* boards may consume current from VBUS, up to 100-500mA based on config. | ||
| 1013 | * the 500uA suspend ceiling means that exclusively vbus-powered PXA designs | ||
| 1014 | * violate USB specs. | ||
| 1015 | */ | ||
| 1016 | static int pxa25x_udc_vbus_draw(struct usb_gadget *_gadget, unsigned mA) | ||
| 1017 | { | ||
| 1018 | struct pxa25x_udc *udc; | ||
| 1019 | |||
| 1020 | udc = container_of(_gadget, struct pxa25x_udc, gadget); | ||
| 1021 | |||
| 1022 | if (udc->transceiver) | ||
| 1023 | return otg_set_power(udc->transceiver, mA); | ||
| 1024 | return -EOPNOTSUPP; | ||
| 1025 | } | ||
| 1026 | |||
| 1011 | static const struct usb_gadget_ops pxa25x_udc_ops = { | 1027 | static const struct usb_gadget_ops pxa25x_udc_ops = { |
| 1012 | .get_frame = pxa25x_udc_get_frame, | 1028 | .get_frame = pxa25x_udc_get_frame, |
| 1013 | .wakeup = pxa25x_udc_wakeup, | 1029 | .wakeup = pxa25x_udc_wakeup, |
| 1014 | .vbus_session = pxa25x_udc_vbus_session, | 1030 | .vbus_session = pxa25x_udc_vbus_session, |
| 1015 | .pullup = pxa25x_udc_pullup, | 1031 | .pullup = pxa25x_udc_pullup, |
| 1016 | 1032 | .vbus_draw = pxa25x_udc_vbus_draw, | |
| 1017 | // .vbus_draw ... boards may consume current from VBUS, up to | ||
| 1018 | // 100-500mA based on config. the 500uA suspend ceiling means | ||
| 1019 | // that exclusively vbus-powered PXA designs violate USB specs. | ||
| 1020 | }; | 1033 | }; |
| 1021 | 1034 | ||
| 1022 | /*-------------------------------------------------------------------------*/ | 1035 | /*-------------------------------------------------------------------------*/ |
| @@ -1303,9 +1316,23 @@ fail: | |||
| 1303 | * for set_configuration as well as eventual disconnect. | 1316 | * for set_configuration as well as eventual disconnect. |
| 1304 | */ | 1317 | */ |
| 1305 | DMSG("registered gadget driver '%s'\n", driver->driver.name); | 1318 | DMSG("registered gadget driver '%s'\n", driver->driver.name); |
| 1319 | |||
| 1320 | /* connect to bus through transceiver */ | ||
| 1321 | if (dev->transceiver) { | ||
| 1322 | retval = otg_set_peripheral(dev->transceiver, &dev->gadget); | ||
| 1323 | if (retval) { | ||
| 1324 | DMSG("can't bind to transceiver\n"); | ||
| 1325 | if (driver->unbind) | ||
| 1326 | driver->unbind(&dev->gadget); | ||
| 1327 | goto bind_fail; | ||
| 1328 | } | ||
| 1329 | } | ||
| 1330 | |||
| 1306 | pullup(dev); | 1331 | pullup(dev); |
| 1307 | dump_state(dev); | 1332 | dump_state(dev); |
| 1308 | return 0; | 1333 | return 0; |
| 1334 | bind_fail: | ||
| 1335 | return retval; | ||
| 1309 | } | 1336 | } |
| 1310 | EXPORT_SYMBOL(usb_gadget_register_driver); | 1337 | EXPORT_SYMBOL(usb_gadget_register_driver); |
| 1311 | 1338 | ||
| @@ -1351,6 +1378,9 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
| 1351 | stop_activity(dev, driver); | 1378 | stop_activity(dev, driver); |
| 1352 | local_irq_enable(); | 1379 | local_irq_enable(); |
| 1353 | 1380 | ||
| 1381 | if (dev->transceiver) | ||
| 1382 | (void) otg_set_peripheral(dev->transceiver, NULL); | ||
| 1383 | |||
| 1354 | driver->unbind(&dev->gadget); | 1384 | driver->unbind(&dev->gadget); |
| 1355 | dev->gadget.dev.driver = NULL; | 1385 | dev->gadget.dev.driver = NULL; |
| 1356 | dev->driver = NULL; | 1386 | dev->driver = NULL; |
| @@ -2162,6 +2192,8 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) | |||
| 2162 | dev->dev = &pdev->dev; | 2192 | dev->dev = &pdev->dev; |
| 2163 | dev->mach = pdev->dev.platform_data; | 2193 | dev->mach = pdev->dev.platform_data; |
| 2164 | 2194 | ||
| 2195 | dev->transceiver = otg_get_transceiver(); | ||
| 2196 | |||
| 2165 | if (gpio_is_valid(dev->mach->gpio_vbus)) { | 2197 | if (gpio_is_valid(dev->mach->gpio_vbus)) { |
| 2166 | if ((retval = gpio_request(dev->mach->gpio_vbus, | 2198 | if ((retval = gpio_request(dev->mach->gpio_vbus, |
| 2167 | "pxa25x_udc GPIO VBUS"))) { | 2199 | "pxa25x_udc GPIO VBUS"))) { |
| @@ -2264,6 +2296,10 @@ lubbock_fail0: | |||
| 2264 | if (gpio_is_valid(dev->mach->gpio_vbus)) | 2296 | if (gpio_is_valid(dev->mach->gpio_vbus)) |
| 2265 | gpio_free(dev->mach->gpio_vbus); | 2297 | gpio_free(dev->mach->gpio_vbus); |
| 2266 | err_gpio_vbus: | 2298 | err_gpio_vbus: |
| 2299 | if (dev->transceiver) { | ||
| 2300 | otg_put_transceiver(dev->transceiver); | ||
| 2301 | dev->transceiver = NULL; | ||
| 2302 | } | ||
| 2267 | clk_put(dev->clk); | 2303 | clk_put(dev->clk); |
| 2268 | err_clk: | 2304 | err_clk: |
| 2269 | return retval; | 2305 | return retval; |
| @@ -2305,6 +2341,11 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev) | |||
| 2305 | 2341 | ||
| 2306 | clk_put(dev->clk); | 2342 | clk_put(dev->clk); |
| 2307 | 2343 | ||
| 2344 | if (dev->transceiver) { | ||
| 2345 | otg_put_transceiver(dev->transceiver); | ||
| 2346 | dev->transceiver = NULL; | ||
| 2347 | } | ||
| 2348 | |||
| 2308 | platform_set_drvdata(pdev, NULL); | 2349 | platform_set_drvdata(pdev, NULL); |
| 2309 | the_controller = NULL; | 2350 | the_controller = NULL; |
| 2310 | return 0; | 2351 | return 0; |
