* [PATCH 0/3] isp1704 changes
@ 2010-11-04 14:31 Heikki Krogerus
2010-11-04 14:31 ` [PATCH 1/4] power_supply: isp1704: correct length for storing model Heikki Krogerus
` (3 more replies)
0 siblings, 4 replies; 7+ messages in thread
From: Heikki Krogerus @ 2010-11-04 14:31 UTC (permalink / raw)
To: cbouatmailru
Cc: dwmw2, linux-kernel, linux-usb, ameya.palande, markus.lehtonen,
heikki.krogerus
These add support for USB Host/HUB chargers and fix a few
issues.
Ameya Palande (1):
power_supply: isp1704: correct length for storing model
Heikki Krogerus (2):
power_supply: isp1704: Detect HUB/Host chargers
power_supply: isp1704: Set isp->dev before anything needs it
drivers/power/isp1704_charger.c | 188 ++++++++++++++++++++++++++++++---------
1 files changed, 146 insertions(+), 42 deletions(-)
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/4] power_supply: isp1704: correct length for storing model
2010-11-04 14:31 [PATCH 0/3] isp1704 changes Heikki Krogerus
@ 2010-11-04 14:31 ` Heikki Krogerus
2010-11-04 14:31 ` [PATCH 2/4] power_supply: isp1704: Detect HUB/Host chargers Heikki Krogerus
` (2 subsequent siblings)
3 siblings, 0 replies; 7+ messages in thread
From: Heikki Krogerus @ 2010-11-04 14:31 UTC (permalink / raw)
To: cbouatmailru
Cc: dwmw2, linux-kernel, linux-usb, ameya.palande, markus.lehtonen,
heikki.krogerus
From: Ameya Palande <ameya.palande@nokia.com>
Model should have room to accommodate the trailing null
byte, "isp170[4|7]\0".
Signed-off-by: Ameya Palande <ameya.palande@nokia.com>
Acked-by: Heikki Krogerus <heikki.krogerus@nokia.com>
---
drivers/power/isp1704_charger.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/power/isp1704_charger.c b/drivers/power/isp1704_charger.c
index 7251218..87252e1 100644
--- a/drivers/power/isp1704_charger.c
+++ b/drivers/power/isp1704_charger.c
@@ -59,7 +59,7 @@ struct isp1704_charger {
struct notifier_block nb;
struct work_struct work;
- char model[7];
+ char model[8];
unsigned present:1;
};
--
1.7.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/4] power_supply: isp1704: Detect HUB/Host chargers
2010-11-04 14:31 [PATCH 0/3] isp1704 changes Heikki Krogerus
2010-11-04 14:31 ` [PATCH 1/4] power_supply: isp1704: correct length for storing model Heikki Krogerus
@ 2010-11-04 14:31 ` Heikki Krogerus
2010-11-04 14:31 ` [PATCH 3/4] power_supply: isp1704: Set isp->dev before anything needs it Heikki Krogerus
2010-11-04 14:31 ` [PATCH 4/4] power_supply: isp1704: Detect charger after probe Heikki Krogerus
3 siblings, 0 replies; 7+ messages in thread
From: Heikki Krogerus @ 2010-11-04 14:31 UTC (permalink / raw)
To: cbouatmailru
Cc: dwmw2, linux-kernel, linux-usb, ameya.palande, markus.lehtonen,
heikki.krogerus
To avoid breaking high speed chirp handshaking with CDP
chargers, no more then 500mA should be drawn. To make sure
of this, utilizing current_max property. After the device
has enumerated, it's safe to draw the maximum 1800mA as
defined in the Battery Charging Specification. This can be
also used with normal USB connection if the controller sends
ENUMERATED notification with the milliamps as data.
>From now on the online property indicates VBUS, present
property if there is a charger and current_max the milliamps
possible to draw from VBUS.
Signed-off-by: Heikki Krogerus <heikki.krogerus@nokia.com>
---
drivers/power/isp1704_charger.c | 180 ++++++++++++++++++++++++++++++--------
1 files changed, 142 insertions(+), 38 deletions(-)
diff --git a/drivers/power/isp1704_charger.c b/drivers/power/isp1704_charger.c
index 87252e1..10c7cc5 100644
--- a/drivers/power/isp1704_charger.c
+++ b/drivers/power/isp1704_charger.c
@@ -59,11 +59,61 @@ struct isp1704_charger {
struct notifier_block nb;
struct work_struct work;
+ /* properties */
char model[8];
unsigned present:1;
+ unsigned online:1;
+ unsigned current_max;
+
+ /* temp storage variables */
+ unsigned long event;
+ unsigned max_power;
};
/*
+ * Determine is the charging port DCP (dedicated charger) or CDP (Host/HUB
+ * chargers).
+ *
+ * REVISIT: The method is defined in Battery Charging Specification and is
+ * applicable to any ULPI transceiver. Nothing isp170x specific here.
+ */
+static inline int isp1704_charger_type(struct isp1704_charger *isp)
+{
+ u8 reg;
+ u8 func_ctrl;
+ u8 otg_ctrl;
+ int type = POWER_SUPPLY_TYPE_USB_DCP;
+
+ func_ctrl = otg_io_read(isp->otg, ULPI_FUNC_CTRL);
+ otg_ctrl = otg_io_read(isp->otg, ULPI_OTG_CTRL);
+
+ /* disable pulldowns */
+ reg = ULPI_OTG_CTRL_DM_PULLDOWN | ULPI_OTG_CTRL_DP_PULLDOWN;
+ otg_io_write(isp->otg, ULPI_CLR(ULPI_OTG_CTRL), reg);
+
+ /* full speed */
+ otg_io_write(isp->otg, ULPI_CLR(ULPI_FUNC_CTRL),
+ ULPI_FUNC_CTRL_XCVRSEL_MASK);
+ otg_io_write(isp->otg, ULPI_SET(ULPI_FUNC_CTRL),
+ ULPI_FUNC_CTRL_FULL_SPEED);
+
+ /* Enable strong pull-up on DP (1.5K) and reset */
+ reg = ULPI_FUNC_CTRL_TERMSELECT | ULPI_FUNC_CTRL_RESET;
+ otg_io_write(isp->otg, ULPI_SET(ULPI_FUNC_CTRL), reg);
+ usleep_range(1000, 2000);
+
+ reg = otg_io_read(isp->otg, ULPI_DEBUG);
+ if ((reg & 3) != 3)
+ type = POWER_SUPPLY_TYPE_USB_CDP;
+
+ /* recover original state */
+ otg_io_write(isp->otg, ULPI_FUNC_CTRL, func_ctrl);
+ otg_io_write(isp->otg, ULPI_OTG_CTRL, otg_ctrl);
+
+ return type;
+}
+
+/*
* ISP1704 detects PS/2 adapters as charger. To make sure the detected charger
* is actually a dedicated charger, the following steps need to be taken.
*/
@@ -127,16 +177,19 @@ static inline int isp1704_charger_verify(struct isp1704_charger *isp)
static inline int isp1704_charger_detect(struct isp1704_charger *isp)
{
unsigned long timeout;
- u8 r;
+ u8 pwr_ctrl;
int ret = 0;
+ pwr_ctrl = otg_io_read(isp->otg, ISP1704_PWR_CTRL);
+
/* set SW control bit in PWR_CTRL register */
otg_io_write(isp->otg, ISP1704_PWR_CTRL,
ISP1704_PWR_CTRL_SWCTRL);
/* enable manual charger detection */
- r = (ISP1704_PWR_CTRL_SWCTRL | ISP1704_PWR_CTRL_DPVSRC_EN);
- otg_io_write(isp->otg, ULPI_SET(ISP1704_PWR_CTRL), r);
+ otg_io_write(isp->otg, ULPI_SET(ISP1704_PWR_CTRL),
+ ISP1704_PWR_CTRL_SWCTRL
+ | ISP1704_PWR_CTRL_DPVSRC_EN);
usleep_range(1000, 2000);
timeout = jiffies + msecs_to_jiffies(300);
@@ -147,7 +200,10 @@ static inline int isp1704_charger_detect(struct isp1704_charger *isp)
ret = isp1704_charger_verify(isp);
break;
}
- } while (!time_after(jiffies, timeout));
+ } while (!time_after(jiffies, timeout) && isp->online);
+
+ /* recover original state */
+ otg_io_write(isp->otg, ISP1704_PWR_CTRL, pwr_ctrl);
return ret;
}
@@ -155,53 +211,93 @@ static inline int isp1704_charger_detect(struct isp1704_charger *isp)
static void isp1704_charger_work(struct work_struct *data)
{
int detect;
+ unsigned long event;
+ unsigned power;
struct isp1704_charger *isp =
container_of(data, struct isp1704_charger, work);
+ static DEFINE_MUTEX(lock);
- /*
- * FIXME Only supporting dedicated chargers even though isp1704 can
- * detect HUB and HOST chargers. If the device has already been
- * enumerated, the detection will break the connection.
- */
- if (isp->otg->state != OTG_STATE_B_IDLE)
- return;
-
- /* disable data pullups */
- if (isp->otg->gadget)
- usb_gadget_disconnect(isp->otg->gadget);
-
- /* detect charger */
- detect = isp1704_charger_detect(isp);
- if (detect) {
- isp->present = detect;
- power_supply_changed(&isp->psy);
- }
+ event = isp->event;
+ power = isp->max_power;
- /* enable data pullups */
- if (isp->otg->gadget)
- usb_gadget_connect(isp->otg->gadget);
-}
-
-static int isp1704_notifier_call(struct notifier_block *nb,
- unsigned long event, void *unused)
-{
- struct isp1704_charger *isp =
- container_of(nb, struct isp1704_charger, nb);
+ mutex_lock(&lock);
switch (event) {
case USB_EVENT_VBUS:
- schedule_work(&isp->work);
+ isp->online = true;
+
+ /* detect charger */
+ detect = isp1704_charger_detect(isp);
+
+ if (detect) {
+ isp->present = detect;
+ isp->psy.type = isp1704_charger_type(isp);
+ }
+
+ switch (isp->psy.type) {
+ case POWER_SUPPLY_TYPE_USB_DCP:
+ isp->current_max = 1800;
+ break;
+ case POWER_SUPPLY_TYPE_USB_CDP:
+ /*
+ * Only 500mA here or high speed chirp
+ * handshaking may break
+ */
+ isp->current_max = 500;
+ /* FALLTHROUGH */
+ case POWER_SUPPLY_TYPE_USB:
+ default:
+ /* enable data pullups */
+ if (isp->otg->gadget)
+ usb_gadget_connect(isp->otg->gadget);
+ }
break;
case USB_EVENT_NONE:
- if (isp->present) {
- isp->present = 0;
- power_supply_changed(&isp->psy);
- }
+ isp->online = false;
+ isp->current_max = 0;
+ isp->present = 0;
+ isp->current_max = 0;
+ isp->psy.type = POWER_SUPPLY_TYPE_USB;
+
+ /*
+ * Disable data pullups. We need to prevent the controller from
+ * enumerating.
+ *
+ * FIXME: This is here to allow charger detection with Host/HUB
+ * chargers. The pullups may be enabled elsewhere, so this can
+ * not be the final solution.
+ */
+ if (isp->otg->gadget)
+ usb_gadget_disconnect(isp->otg->gadget);
+ break;
+ case USB_EVENT_ENUMERATED:
+ if (isp->present)
+ isp->current_max = 1800;
+ else
+ isp->current_max = power;
break;
default:
- return NOTIFY_DONE;
+ goto out;
}
+ power_supply_changed(&isp->psy);
+out:
+ mutex_unlock(&lock);
+}
+
+static int isp1704_notifier_call(struct notifier_block *nb,
+ unsigned long event, void *power)
+{
+ struct isp1704_charger *isp =
+ container_of(nb, struct isp1704_charger, nb);
+
+ isp->event = event;
+
+ if (power)
+ isp->max_power = *((unsigned *)power);
+
+ schedule_work(&isp->work);
+
return NOTIFY_OK;
}
@@ -216,6 +312,12 @@ static int isp1704_charger_get_property(struct power_supply *psy,
case POWER_SUPPLY_PROP_PRESENT:
val->intval = isp->present;
break;
+ case POWER_SUPPLY_PROP_ONLINE:
+ val->intval = isp->online;
+ break;
+ case POWER_SUPPLY_PROP_CURRENT_MAX:
+ val->intval = isp->current_max;
+ break;
case POWER_SUPPLY_PROP_MODEL_NAME:
val->strval = isp->model;
break;
@@ -230,6 +332,8 @@ static int isp1704_charger_get_property(struct power_supply *psy,
static enum power_supply_property power_props[] = {
POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_ONLINE,
+ POWER_SUPPLY_PROP_CURRENT_MAX,
POWER_SUPPLY_PROP_MODEL_NAME,
POWER_SUPPLY_PROP_MANUFACTURER,
};
--
1.7.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 3/4] power_supply: isp1704: Set isp->dev before anything needs it
2010-11-04 14:31 [PATCH 0/3] isp1704 changes Heikki Krogerus
2010-11-04 14:31 ` [PATCH 1/4] power_supply: isp1704: correct length for storing model Heikki Krogerus
2010-11-04 14:31 ` [PATCH 2/4] power_supply: isp1704: Detect HUB/Host chargers Heikki Krogerus
@ 2010-11-04 14:31 ` Heikki Krogerus
2010-11-04 14:31 ` [PATCH 4/4] power_supply: isp1704: Detect charger after probe Heikki Krogerus
3 siblings, 0 replies; 7+ messages in thread
From: Heikki Krogerus @ 2010-11-04 14:31 UTC (permalink / raw)
To: cbouatmailru
Cc: dwmw2, linux-kernel, linux-usb, ameya.palande, markus.lehtonen,
heikki.krogerus
isp1704_test_ulpi() is the first place that needs isp->dev
member, so it must be set before calling the function.
Signed-off-by: Heikki Krogerus <heikki.krogerus@nokia.com>
---
drivers/power/isp1704_charger.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/power/isp1704_charger.c b/drivers/power/isp1704_charger.c
index 10c7cc5..77c11f1 100644
--- a/drivers/power/isp1704_charger.c
+++ b/drivers/power/isp1704_charger.c
@@ -391,13 +391,13 @@ static int __devinit isp1704_charger_probe(struct platform_device *pdev)
if (!isp->otg)
goto fail0;
+ isp->dev = &pdev->dev;
+ platform_set_drvdata(pdev, isp);
+
ret = isp1704_test_ulpi(isp);
if (ret < 0)
goto fail1;
- isp->dev = &pdev->dev;
- platform_set_drvdata(pdev, isp);
-
isp->psy.name = "isp1704";
isp->psy.type = POWER_SUPPLY_TYPE_USB;
isp->psy.properties = power_props;
--
1.7.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 4/4] power_supply: isp1704: Detect charger after probe
2010-11-04 14:31 [PATCH 0/3] isp1704 changes Heikki Krogerus
` (2 preceding siblings ...)
2010-11-04 14:31 ` [PATCH 3/4] power_supply: isp1704: Set isp->dev before anything needs it Heikki Krogerus
@ 2010-11-04 14:31 ` Heikki Krogerus
2010-11-05 15:11 ` Sergei Shtylyov
3 siblings, 1 reply; 7+ messages in thread
From: Heikki Krogerus @ 2010-11-04 14:31 UTC (permalink / raw)
To: cbouatmailru
Cc: dwmw2, linux-kernel, linux-usb, ameya.palande, markus.lehtonen,
heikki.krogerus
If the device is booted up with cable connected, or the
module is loaded after plugging in the cable, the
notification has come and gone, so not relying on it at
probe time. Instead this checks the VBUS level manually
after probe.
Signed-off-by: Heikki Krogerus <heikki.krogerus@nokia.com>
---
drivers/power/isp1704_charger.c | 17 +++++++++++++++++
1 files changed, 17 insertions(+), 0 deletions(-)
diff --git a/drivers/power/isp1704_charger.c b/drivers/power/isp1704_charger.c
index 77c11f1..946e43c 100644
--- a/drivers/power/isp1704_charger.c
+++ b/drivers/power/isp1704_charger.c
@@ -422,6 +422,23 @@ static int __devinit isp1704_charger_probe(struct platform_device *pdev)
dev_info(isp->dev, "registered with product id %s\n", isp->model);
+ /*
+ * Taking over the D+ pullup.
+ *
+ * FIXME: The device will be disconnected if the it was already
+ * enumerated. The charger driver should be always loaded before any
+ * gadget is loaded.
+ */
+ if (isp->otg->gadget)
+ usb_gadget_disconnect(isp->otg->gadget);
+
+ /* Detect charger if VBUS is valid (the cable was already plugged). */
+ ret = otg_io_read(isp->otg, ULPI_USB_INT_STS);
+ if ((ret & ULPI_INT_VBUS_VALID) && !isp->otg->default_a) {
+ isp->event = USB_EVENT_VBUS;
+ schedule_work(&isp->work);
+ }
+
return 0;
fail2:
power_supply_unregister(&isp->psy);
--
1.7.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 4/4] power_supply: isp1704: Detect charger after probe
2010-11-04 14:31 ` [PATCH 4/4] power_supply: isp1704: Detect charger after probe Heikki Krogerus
@ 2010-11-05 15:11 ` Sergei Shtylyov
2010-11-08 10:22 ` Heikki Krogerus
0 siblings, 1 reply; 7+ messages in thread
From: Sergei Shtylyov @ 2010-11-05 15:11 UTC (permalink / raw)
To: Heikki Krogerus
Cc: cbouatmailru, dwmw2, linux-kernel, linux-usb, ameya.palande,
markus.lehtonen
Hello.
On 04-11-2010 17:31, Heikki Krogerus wrote:
> If the device is booted up with cable connected, or the
> module is loaded after plugging in the cable, the
> notification has come and gone, so not relying on it at
> probe time. Instead this checks the VBUS level manually
> after probe.
> Signed-off-by: Heikki Krogerus<heikki.krogerus@nokia.com>
> ---
> drivers/power/isp1704_charger.c | 17 +++++++++++++++++
> 1 files changed, 17 insertions(+), 0 deletions(-)
> diff --git a/drivers/power/isp1704_charger.c b/drivers/power/isp1704_charger.c
> index 77c11f1..946e43c 100644
> --- a/drivers/power/isp1704_charger.c
> +++ b/drivers/power/isp1704_charger.c
> @@ -422,6 +422,23 @@ static int __devinit isp1704_charger_probe(struct platform_device *pdev)
>
> dev_info(isp->dev, "registered with product id %s\n", isp->model);
>
> + /*
> + * Taking over the D+ pullup.
> + *
> + * FIXME: The device will be disconnected if the it was already
^^^
"the" is not needed here.
WBR, Sergei
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 4/4] power_supply: isp1704: Detect charger after probe
2010-11-05 15:11 ` Sergei Shtylyov
@ 2010-11-08 10:22 ` Heikki Krogerus
0 siblings, 0 replies; 7+ messages in thread
From: Heikki Krogerus @ 2010-11-08 10:22 UTC (permalink / raw)
To: Sergei Shtylyov
Cc: cbouatmailru, dwmw2, linux-kernel, linux-usb, ameya.palande,
markus.lehtonen
[-- Attachment #1: Type: text/plain, Size: 532 bytes --]
Hi,
On Fri, Nov 05, 2010 at 04:11:25PM +0100, ext Sergei Shtylyov wrote:
> > @@ -422,6 +422,23 @@ static int __devinit isp1704_charger_probe(struct platform_device *pdev)
> >
> > dev_info(isp->dev, "registered with product id %s\n", isp->model);
> >
> > + /*
> > + * Taking over the D+ pullup.
> > + *
> > + * FIXME: The device will be disconnected if the it was already
> ^^^
> "the" is not needed here.
Here's the fix removing the extra "the". Thanks.
--
heikki
[-- Attachment #2: 0001-power_supply-isp1704-Detect-charger-after-probe.patch --]
[-- Type: text/x-diff, Size: 1578 bytes --]
>From 22adc046938bdb57adca5acf59fd94539d5e0110 Mon Sep 17 00:00:00 2001
From: Heikki Krogerus <heikki.krogerus@nokia.com>
Date: Thu, 4 Nov 2010 16:14:22 +0200
Subject: [PATCH] power_supply: isp1704: Detect charger after probe
If the device is booted up with cable connected, or the
module is loaded after plugging in the cable, the
notification has come and gone, so not relying on it at
probe time. Instead this checks the VBUS level manually
after probe.
Signed-off-by: Heikki Krogerus <heikki.krogerus@nokia.com>
---
drivers/power/isp1704_charger.c | 17 +++++++++++++++++
1 files changed, 17 insertions(+), 0 deletions(-)
diff --git a/drivers/power/isp1704_charger.c b/drivers/power/isp1704_charger.c
index 77c11f1..2ad9b14 100644
--- a/drivers/power/isp1704_charger.c
+++ b/drivers/power/isp1704_charger.c
@@ -422,6 +422,23 @@ static int __devinit isp1704_charger_probe(struct platform_device *pdev)
dev_info(isp->dev, "registered with product id %s\n", isp->model);
+ /*
+ * Taking over the D+ pullup.
+ *
+ * FIXME: The device will be disconnected if it was already
+ * enumerated. The charger driver should be always loaded before any
+ * gadget is loaded.
+ */
+ if (isp->otg->gadget)
+ usb_gadget_disconnect(isp->otg->gadget);
+
+ /* Detect charger if VBUS is valid (the cable was already plugged). */
+ ret = otg_io_read(isp->otg, ULPI_USB_INT_STS);
+ if ((ret & ULPI_INT_VBUS_VALID) && !isp->otg->default_a) {
+ isp->event = USB_EVENT_VBUS;
+ schedule_work(&isp->work);
+ }
+
return 0;
fail2:
power_supply_unregister(&isp->psy);
--
1.7.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2010-11-08 10:23 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-11-04 14:31 [PATCH 0/3] isp1704 changes Heikki Krogerus
2010-11-04 14:31 ` [PATCH 1/4] power_supply: isp1704: correct length for storing model Heikki Krogerus
2010-11-04 14:31 ` [PATCH 2/4] power_supply: isp1704: Detect HUB/Host chargers Heikki Krogerus
2010-11-04 14:31 ` [PATCH 3/4] power_supply: isp1704: Set isp->dev before anything needs it Heikki Krogerus
2010-11-04 14:31 ` [PATCH 4/4] power_supply: isp1704: Detect charger after probe Heikki Krogerus
2010-11-05 15:11 ` Sergei Shtylyov
2010-11-08 10:22 ` Heikki Krogerus
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox