Re: [PATCH v1] usb: phy: generic: add vbus support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun, Nov 09, 2014 at 03:58:14PM +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.jarzmik@xxxxxxx>
> ---
>  drivers/usb/phy/phy-generic.c       | 90 ++++++++++++++++++++++++++++++++++++-
>  drivers/usb/phy/phy-generic.h       |  6 +++
>  include/linux/usb/usb_phy_generic.h |  2 +
>  3 files changed, 97 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c
> index 71e061d..2f383a1 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;

do you really need this flag here ? How about:

	if (regulator_is_enabled(vbus_draw))
		foo();

> +		}
> +	} 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);

right, we need to take into considering the Battery Charging
specification here, though. We might need to setup a timer for the
amount of time we can draw 100mA before device enumerates. If the times
expires we're only allowed to draw 8mA or 2mA, or something like that.

The time gets cancelled as soon as we get enumerated.

Another possibility would be to move this policy into userland, then
kernel only provides the interfaces.

-- 
balbi

Attachment: signature.asc
Description: Digital signature


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux