Skip to content

Commit

Permalink
USB: gadget: pxa25x: basic transceiver support
Browse files Browse the repository at this point in the history
This adds very basic otg_transceiver support, with vbus_session
and vbus_draw callbacks.

Now VBUS sensing can be handled by an external driver which registers
the otg_transceiver interface. It also allows gadget drivers to configure
the current drawn from VBUS. The UDC driver just passes their requests
along to the transceiver driver.

Signed-off-by: Philipp Zabel <philipp.zabel@gmail.com>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Philipp Zabel authored and Greg Kroah-Hartman committed Sep 23, 2009
1 parent 4c6e897 commit ab26d20
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 4 deletions.
49 changes: 45 additions & 4 deletions drivers/usb/gadget/pxa25x_udc.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@

#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
#include <linux/usb/otg.h>

/*
* This driver is PXA25x only. Grab the right register definitions.
Expand Down Expand Up @@ -1008,15 +1009,27 @@ static int pxa25x_udc_pullup(struct usb_gadget *_gadget, int is_active)
return 0;
}

/* boards may consume current from VBUS, up to 100-500mA based on config.
* the 500uA suspend ceiling means that exclusively vbus-powered PXA designs
* violate USB specs.
*/
static int pxa25x_udc_vbus_draw(struct usb_gadget *_gadget, unsigned mA)
{
struct pxa25x_udc *udc;

udc = container_of(_gadget, struct pxa25x_udc, gadget);

if (udc->transceiver)
return otg_set_power(udc->transceiver, mA);
return -EOPNOTSUPP;
}

static const struct usb_gadget_ops pxa25x_udc_ops = {
.get_frame = pxa25x_udc_get_frame,
.wakeup = pxa25x_udc_wakeup,
.vbus_session = pxa25x_udc_vbus_session,
.pullup = pxa25x_udc_pullup,

// .vbus_draw ... boards may consume current from VBUS, up to
// 100-500mA based on config. the 500uA suspend ceiling means
// that exclusively vbus-powered PXA designs violate USB specs.
.vbus_draw = pxa25x_udc_vbus_draw,
};

/*-------------------------------------------------------------------------*/
Expand Down Expand Up @@ -1303,9 +1316,23 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
* for set_configuration as well as eventual disconnect.
*/
DMSG("registered gadget driver '%s'\n", driver->driver.name);

/* connect to bus through transceiver */
if (dev->transceiver) {
retval = otg_set_peripheral(dev->transceiver, &dev->gadget);
if (retval) {
DMSG("can't bind to transceiver\n");
if (driver->unbind)
driver->unbind(&dev->gadget);
goto bind_fail;
}
}

pullup(dev);
dump_state(dev);
return 0;
bind_fail:
return retval;
}
EXPORT_SYMBOL(usb_gadget_register_driver);

Expand Down Expand Up @@ -1351,6 +1378,9 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
stop_activity(dev, driver);
local_irq_enable();

if (dev->transceiver)
(void) otg_set_peripheral(dev->transceiver, NULL);

driver->unbind(&dev->gadget);
dev->gadget.dev.driver = NULL;
dev->driver = NULL;
Expand Down Expand Up @@ -2162,6 +2192,8 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev)
dev->dev = &pdev->dev;
dev->mach = pdev->dev.platform_data;

dev->transceiver = otg_get_transceiver();

if (gpio_is_valid(dev->mach->gpio_vbus)) {
if ((retval = gpio_request(dev->mach->gpio_vbus,
"pxa25x_udc GPIO VBUS"))) {
Expand Down Expand Up @@ -2264,6 +2296,10 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev)
if (gpio_is_valid(dev->mach->gpio_vbus))
gpio_free(dev->mach->gpio_vbus);
err_gpio_vbus:
if (dev->transceiver) {
otg_put_transceiver(dev->transceiver);
dev->transceiver = NULL;
}
clk_put(dev->clk);
err_clk:
return retval;
Expand Down Expand Up @@ -2305,6 +2341,11 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev)

clk_put(dev->clk);

if (dev->transceiver) {
otg_put_transceiver(dev->transceiver);
dev->transceiver = NULL;
}

platform_set_drvdata(pdev, NULL);
the_controller = NULL;
return 0;
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/gadget/pxa25x_udc.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ struct pxa25x_udc {
struct device *dev;
struct clk *clk;
struct pxa2xx_udc_mach_info *mach;
struct otg_transceiver *transceiver;
u64 dma_mask;
struct pxa25x_ep ep [PXA_UDC_NUM_ENDPOINTS];

Expand Down

0 comments on commit ab26d20

Please sign in to comment.