On Sat, Dec 06, 2014 at 10:05:15PM +0100, Robert Jarzmik wrote:
> Add support for vbus detection and power supply. This code is more or
> less stolen from phy-gpio-vbus-usb.c, and aims at providing a detection
> mechanism for VBus (ie. usb cable plug) based on a GPIO line, and a
> power supply activation which draws current from the VBus.
> 
> Signed-off-by: Robert Jarzmik <robert.jarz...@free.fr>
> ---
> Since v1: changed vbus-gpios to vbus-detect-gpio
> ---
>  drivers/usb/phy/phy-generic.c       | 91 
> ++++++++++++++++++++++++++++++++++++-
>  drivers/usb/phy/phy-generic.h       |  6 +++
>  include/linux/usb/usb_phy_generic.h |  2 +
>  3 files changed, 98 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c
> index 71e061d..f56a47b 100644
> --- a/drivers/usb/phy/phy-generic.c
> +++ b/drivers/usb/phy/phy-generic.c
> @@ -29,6 +29,7 @@
>  #include <linux/module.h>
>  #include <linux/platform_device.h>
>  #include <linux/dma-mapping.h>
> +#include <linux/usb/gadget.h>
>  #include <linux/usb/otg.h>
>  #include <linux/usb/usb_phy_generic.h>
>  #include <linux/slab.h>
> @@ -41,6 +42,9 @@
>  
>  #include "phy-generic.h"
>  
> +#define VBUS_IRQ_FLAGS \
> +     (IRQF_SHARED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)
> +
>  struct platform_device *usb_phy_generic_register(void)
>  {
>       return platform_device_register_simple("usb_phy_generic",
> @@ -68,6 +72,73 @@ static void nop_reset_set(struct usb_phy_generic *nop, int 
> asserted)
>               usleep_range(10000, 20000);
>  }
>  
> +/* interface to regulator framework */
> +static void nop_set_vbus_draw(struct usb_phy_generic *nop, unsigned mA)
> +{
> +     struct regulator *vbus_draw = nop->vbus_draw;
> +     int enabled;
> +     int ret;
> +
> +     if (!vbus_draw)
> +             return;
> +
> +     enabled = nop->vbus_draw_enabled;
> +     if (mA) {
> +             regulator_set_current_limit(vbus_draw, 0, 1000 * mA);
> +             if (!enabled) {
> +                     ret = regulator_enable(vbus_draw);
> +                     if (ret < 0)
> +                             return;
> +                     nop->vbus_draw_enabled = 1;
> +             }
> +     } else {
> +             if (enabled) {
> +                     ret = regulator_disable(vbus_draw);
> +                     if (ret < 0)
> +                             return;
> +                     nop->vbus_draw_enabled = 0;
> +             }
> +     }
> +     nop->mA = mA;
> +}
> +
> +
> +static irqreturn_t nop_gpio_vbus_thread(int irq, void *data)
> +{
> +     struct usb_phy_generic *nop = data;
> +     struct usb_otg *otg = nop->phy.otg;
> +     int vbus, status;
> +
> +     vbus = gpiod_get_value(nop->gpiod_vbus);
> +     if ((vbus ^ nop->vbus) == 0)
> +             return IRQ_HANDLED;
> +     nop->vbus = vbus;
> +
> +     if (vbus) {
> +             status = USB_EVENT_VBUS;
> +             nop->phy.state = OTG_STATE_B_PERIPHERAL;
> +             nop->phy.last_event = status;
> +             usb_gadget_vbus_connect(otg->gadget);
> +
> +             /* drawing a "unit load" is *always* OK, except for OTG */
> +             nop_set_vbus_draw(nop, 100);
> +
> +             atomic_notifier_call_chain(&nop->phy.notifier, status,
> +                                        otg->gadget);
> +     } else {
> +             nop_set_vbus_draw(nop, 0);
> +
> +             usb_gadget_vbus_disconnect(otg->gadget);
> +             status = USB_EVENT_NONE;
> +             nop->phy.state = OTG_STATE_B_IDLE;

broke build :-( I'll see if I can fix it myself this time as this was
probably caused by something that went in during the merge window.

cheers

-- 
balbi

Attachment: signature.asc
Description: Digital signature

Reply via email to