The udc has three supplies: vdda (3.3V), vddi (1.2V) and vddosc (1.8-3.3V). When CONFIG_REGULATOR is active use these to turn udc power on and off on start and stop calls. Signed-off-by: Heiko Stuebner <heiko@xxxxxxxxx> --- drivers/usb/gadget/s3c-hsudc.c | 51 ++++++++++++++++++++++++++++++++++++++++ 1 files changed, 51 insertions(+), 0 deletions(-) diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/s3c-hsudc.c index 74be824..6872dee 100644 --- a/drivers/usb/gadget/s3c-hsudc.c +++ b/drivers/usb/gadget/s3c-hsudc.c @@ -29,6 +29,10 @@ #include <linux/usb/otg.h> #include <linux/prefetch.h> +#ifdef CONFIG_REGULATOR +#include <linux/regulator/consumer.h> +#endif + #include <mach/regs-s3c2443-clock.h> #include <plat/udc.h> @@ -87,6 +91,14 @@ #define DATA_STATE_XMIT (1) #define DATA_STATE_RECV (2) +#ifdef CONFIG_REGULATOR +static const char *s3c_hsudc_supply_names[] = { + "vdda", /* analog phy supply, 3.3V */ + "vddi", /* digital phy supply, 1.2V */ + "vddosc" /* oscillator supply, 1.8V - 3.3V */ +}; +#endif + /** * struct s3c_hsudc_ep - Endpoint representation used by driver. * @ep: USB gadget layer representation of device endpoint. @@ -139,6 +151,9 @@ struct s3c_hsudc { struct device *dev; struct s3c24xx_hsudc_platdata *pd; struct otg_transceiver *transceiver; +#ifdef CONFIG_REGULATOR + struct regulator_bulk_data supplies[ARRAY_SIZE(s3c_hsudc_supply_names)]; +#endif spinlock_t lock; void __iomem *regs; struct resource *mem_rsrc; @@ -1162,6 +1177,15 @@ static int s3c_hsudc_start(struct usb_gadget_driver *driver, return ret; } +#ifdef CONFIG_REGULATOR + ret = regulator_bulk_enable(ARRAY_SIZE(hsudc->supplies), + hsudc->supplies); + if (ret != 0) { + dev_err(hsudc->dev, "failed to enable supplies: %d\n", ret); + goto err_supplies; + } +#endif + ret = bind(&hsudc->gadget); if (ret) { dev_err(hsudc->dev, "%s: bind failed\n", hsudc->gadget.name); @@ -1190,6 +1214,10 @@ static int s3c_hsudc_start(struct usb_gadget_driver *driver, err_otg: driver->unbind(&hsudc->gadget); err_bind: +#ifdef CONFIG_REGULATOR + regulator_bulk_disable(ARRAY_SIZE(hsudc->supplies), hsudc->supplies); +err_supplies: +#endif device_del(&hsudc->gadget.dev); hsudc->driver = NULL; @@ -1223,6 +1251,10 @@ static int s3c_hsudc_stop(struct usb_gadget_driver *driver) device_del(&hsudc->gadget.dev); disable_irq(hsudc->irq); +#ifdef CONFIG_REGULATOR + regulator_bulk_disable(ARRAY_SIZE(hsudc->supplies), hsudc->supplies); +#endif + dev_info(hsudc->dev, "unregistered gadget driver '%s'\n", driver->driver.name); return 0; @@ -1265,6 +1297,9 @@ static int s3c_hsudc_probe(struct platform_device *pdev) struct s3c_hsudc *hsudc; struct s3c24xx_hsudc_platdata *pd = pdev->dev.platform_data; int ret; +#ifdef CONFIG_REGULATOR + int i; +#endif hsudc = kzalloc(sizeof(struct s3c_hsudc) + sizeof(struct s3c_hsudc_ep) * pd->epnum, @@ -1281,6 +1316,18 @@ static int s3c_hsudc_probe(struct platform_device *pdev) hsudc->transceiver = otg_get_transceiver(); +#ifdef CONFIG_REGULATOR + for (i = 0; i < ARRAY_SIZE(hsudc->supplies); i++) + hsudc->supplies[i].supply = s3c_hsudc_supply_names[i]; + + ret = regulator_bulk_get(dev, ARRAY_SIZE(hsudc->supplies), + hsudc->supplies); + if (ret != 0) { + dev_err(dev, "failed to request supplies: %d\n", ret); + goto err_supplies; + } +#endif + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(dev, "unable to obtain driver resource data\n"); @@ -1364,6 +1411,10 @@ err_remap: kfree(hsudc->mem_rsrc); err_res: +#ifdef CONFIG_REGULATOR + regulator_bulk_free(ARRAY_SIZE(hsudc->supplies), hsudc->supplies); +err_supplies: +#endif kfree(hsudc); return ret; } -- 1.7.2.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html