diff mbox

[4/4] usb: phy: twl4030: test ID resistance to see if charger is present.

Message ID 20150224034037.31400.48003.stgit@notabene.brown (mailing list archive)
State New, archived
Headers show

Commit Message

NeilBrown Feb. 24, 2015, 3:40 a.m. UTC
If an 'A' plug is inserted, ID should be pulled to ground.
If a 'B' plug, then ID should be floating.

If an Accessory Charger Adapter is inserted, then ID will
be neither grounded nor floating.  In this case tell the
USB subsystem that it is an A plug, and the battery
charging subsystem that it is a charger.

Fortunately, this will treat the Openmoko charger (and
other similar chargers) as a charger.

Signed-off-by: NeilBrown <neilb@suse.de>
---
 drivers/phy/phy-twl4030-usb.c |   28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)



--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Pavel Machek March 2, 2015, 9:04 p.m. UTC | #1
On Tue 2015-02-24 14:40:37, NeilBrown wrote:
> If an 'A' plug is inserted, ID should be pulled to ground.
> If a 'B' plug, then ID should be floating.
> 
> If an Accessory Charger Adapter is inserted, then ID will
> be neither grounded nor floating.  In this case tell the
> USB subsystem that it is an A plug, and the battery
> charging subsystem that it is a charger.

> Fortunately, this will treat the Openmoko charger (and
> other similar chargers) as a charger.
> 
> Signed-off-by: NeilBrown <neilb@suse.de>

I guess signed-off-by should be "real name", so I'd add a space..

Acked-by: Pavel Machek <pavel@ucw.cz>

> --- a/drivers/phy/phy-twl4030-usb.c
> +++ b/drivers/phy/phy-twl4030-usb.c
> @@ -596,9 +596,31 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
>  	struct twl4030_usb *twl = _twl;
>  	enum omap_musb_vbus_id_status status;
>  	bool status_changed = false;
> +	bool found_charger = false;
>  
>  	status = twl4030_usb_linkstat(twl);
>  
> +	if (status == OMAP_MUSB_ID_GROUND ||
> +	    status == OMAP_MUSB_VBUS_VALID) {
> +		/* We should check the resistance on the ID pin.
> +		 * If not a Ground or Floating, then this is
> +		 * likely a charger

"charger.", and I guess kernel comments should have /* on separate line.

So it will draw .5A from the charger? 1A? 2A?

									Pavel
NeilBrown March 4, 2015, 6:40 a.m. UTC | #2
On Mon, 2 Mar 2015 22:04:44 +0100 Pavel Machek <pavel@ucw.cz> wrote:

> On Tue 2015-02-24 14:40:37, NeilBrown wrote:
> > If an 'A' plug is inserted, ID should be pulled to ground.
> > If a 'B' plug, then ID should be floating.
> > 
> > If an Accessory Charger Adapter is inserted, then ID will
> > be neither grounded nor floating.  In this case tell the
> > USB subsystem that it is an A plug, and the battery
> > charging subsystem that it is a charger.
> 
> > Fortunately, this will treat the Openmoko charger (and
> > other similar chargers) as a charger.
> > 
> > Signed-off-by: NeilBrown <neilb@suse.de>
> 
> I guess signed-off-by should be "real name", so I'd add a space..

This is how I always sign-off my name (2858 times in "git log") so I don't
think I'll change it now.

> 
> Acked-by: Pavel Machek <pavel@ucw.cz>

Thanks.

> 
> > --- a/drivers/phy/phy-twl4030-usb.c
> > +++ b/drivers/phy/phy-twl4030-usb.c
> > @@ -596,9 +596,31 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
> >  	struct twl4030_usb *twl = _twl;
> >  	enum omap_musb_vbus_id_status status;
> >  	bool status_changed = false;
> > +	bool found_charger = false;
> >  
> >  	status = twl4030_usb_linkstat(twl);
> >  
> > +	if (status == OMAP_MUSB_ID_GROUND ||
> > +	    status == OMAP_MUSB_VBUS_VALID) {
> > +		/* We should check the resistance on the ID pin.
> > +		 * If not a Ground or Floating, then this is
> > +		 * likely a charger
> 
> "charger.", and I guess kernel comments should have /* on separate line.

Yep.

> 
> So it will draw .5A from the charger? 1A? 2A?
> 
> 									Pavel

That is up to the charger driver.  The phy just detects what is there, it
doesn't decide what to do with it.

Thanks,
NeilBrown
diff mbox

Patch

diff --git a/drivers/phy/phy-twl4030-usb.c b/drivers/phy/phy-twl4030-usb.c
index 759950898df9..8a43080cdbd7 100644
--- a/drivers/phy/phy-twl4030-usb.c
+++ b/drivers/phy/phy-twl4030-usb.c
@@ -596,9 +596,31 @@  static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
 	struct twl4030_usb *twl = _twl;
 	enum omap_musb_vbus_id_status status;
 	bool status_changed = false;
+	bool found_charger = false;
 
 	status = twl4030_usb_linkstat(twl);
 
+	if (status == OMAP_MUSB_ID_GROUND ||
+	    status == OMAP_MUSB_VBUS_VALID) {
+		/* We should check the resistance on the ID pin.
+		 * If not a Ground or Floating, then this is
+		 * likely a charger
+		 */
+		enum twl4030_id_status sts = twl4030_get_id(twl);
+		if (sts > TWL4030_GROUND &&
+		    sts < TWL4030_FLOATING) {
+			/*
+			 * This might be a charger, or an
+			 * Accessory Charger Adapter.
+			 * In either case we can charge, and it
+			 * makes sense to tell the USB system
+			 * that we might be acting as a HOST.
+			 */
+			status = OMAP_MUSB_ID_GROUND;
+			found_charger = true;
+		}
+	}
+
 	mutex_lock(&twl->lock);
 	if (status >= 0 && status != twl->linkstat) {
 		status_changed =
@@ -627,6 +649,12 @@  static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
 		}
 		omap_musb_mailbox(status);
 	}
+	if (found_charger && twl->phy.last_event != USB_EVENT_CHARGER) {
+		twl->phy.last_event = USB_EVENT_CHARGER;
+		atomic_notifier_call_chain(&twl->phy.notifier,
+					   USB_EVENT_CHARGER,
+					   NULL);
+	}
 
 	/* don't schedule during sleep - irq works right then */
 	if (status == OMAP_MUSB_ID_GROUND && pm_runtime_active(twl->dev)) {