Commit f07c11ea authored by Pali Rohár's avatar Pali Rohár Committed by Anton Vorontsov

isp1704_charger: Fix driver to work with changes introduced in v3.5

* omap musb driver does not report USB_EVENT_ENUMERATED event anymore
* omap musb driver reporting USB_EVENT_VBUS when charger is connected
* read last event from phy->last_event (instead from ulpi register)
* do not call wall charger detection more times
Signed-off-by: default avatarPali Rohár <pali.rohar@gmail.com>
Signed-off-by: default avatarAnton Vorontsov <anton@enomsg.org>
parent 61e6cfa8
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
* ISP1704 USB Charger Detection driver * ISP1704 USB Charger Detection driver
* *
* Copyright (C) 2010 Nokia Corporation * Copyright (C) 2010 Nokia Corporation
* Copyright (C) 2012 - 2013 Pali Rohár <pali.rohar@gmail.com>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
...@@ -65,10 +66,6 @@ struct isp1704_charger { ...@@ -65,10 +66,6 @@ struct isp1704_charger {
unsigned present:1; unsigned present:1;
unsigned online:1; unsigned online:1;
unsigned current_max; unsigned current_max;
/* temp storage variables */
unsigned long event;
unsigned max_power;
}; };
static inline int isp1704_read(struct isp1704_charger *isp, u32 reg) static inline int isp1704_read(struct isp1704_charger *isp, u32 reg)
...@@ -231,56 +228,59 @@ static inline int isp1704_charger_detect(struct isp1704_charger *isp) ...@@ -231,56 +228,59 @@ static inline int isp1704_charger_detect(struct isp1704_charger *isp)
return ret; return ret;
} }
static inline int isp1704_charger_detect_dcp(struct isp1704_charger *isp)
{
if (isp1704_charger_detect(isp) &&
isp1704_charger_type(isp) == POWER_SUPPLY_TYPE_USB_DCP)
return true;
else
return false;
}
static void isp1704_charger_work(struct work_struct *data) static void isp1704_charger_work(struct work_struct *data)
{ {
int detect;
unsigned long event;
unsigned power;
struct isp1704_charger *isp = struct isp1704_charger *isp =
container_of(data, struct isp1704_charger, work); container_of(data, struct isp1704_charger, work);
static DEFINE_MUTEX(lock); static DEFINE_MUTEX(lock);
event = isp->event;
power = isp->max_power;
mutex_lock(&lock); mutex_lock(&lock);
if (event != USB_EVENT_NONE) switch (isp->phy->last_event) {
isp1704_charger_set_power(isp, 1);
switch (event) {
case USB_EVENT_VBUS: case USB_EVENT_VBUS:
isp->online = true; /* do not call wall charger detection more times */
if (!isp->present) {
isp->online = true;
isp->present = 1;
isp1704_charger_set_power(isp, 1);
/* detect wall charger */
if (isp1704_charger_detect_dcp(isp)) {
isp->psy.type = POWER_SUPPLY_TYPE_USB_DCP;
isp->current_max = 1800;
} else {
isp->psy.type = POWER_SUPPLY_TYPE_USB;
isp->current_max = 500;
}
/* detect charger */ /* enable data pullups */
detect = isp1704_charger_detect(isp); if (isp->phy->otg->gadget)
usb_gadget_connect(isp->phy->otg->gadget);
if (detect) {
isp->present = detect;
isp->psy.type = isp1704_charger_type(isp);
} }
switch (isp->psy.type) { if (isp->psy.type != POWER_SUPPLY_TYPE_USB_DCP) {
case POWER_SUPPLY_TYPE_USB_DCP:
isp->current_max = 1800;
break;
case POWER_SUPPLY_TYPE_USB_CDP:
/* /*
* Only 500mA here or high speed chirp * Only 500mA here or high speed chirp
* handshaking may break * handshaking may break
*/ */
isp->current_max = 500; if (isp->current_max > 500)
/* FALLTHROUGH */ isp->current_max = 500;
case POWER_SUPPLY_TYPE_USB:
default: if (isp->current_max > 100)
/* enable data pullups */ isp->psy.type = POWER_SUPPLY_TYPE_USB_CDP;
if (isp->phy->otg->gadget)
usb_gadget_connect(isp->phy->otg->gadget);
} }
break; break;
case USB_EVENT_NONE: case USB_EVENT_NONE:
isp->online = false; isp->online = false;
isp->current_max = 0;
isp->present = 0; isp->present = 0;
isp->current_max = 0; isp->current_max = 0;
isp->psy.type = POWER_SUPPLY_TYPE_USB; isp->psy.type = POWER_SUPPLY_TYPE_USB;
...@@ -298,12 +298,6 @@ static void isp1704_charger_work(struct work_struct *data) ...@@ -298,12 +298,6 @@ static void isp1704_charger_work(struct work_struct *data)
isp1704_charger_set_power(isp, 0); isp1704_charger_set_power(isp, 0);
break; break;
case USB_EVENT_ENUMERATED:
if (isp->present)
isp->current_max = 1800;
else
isp->current_max = power;
break;
default: default:
goto out; goto out;
} }
...@@ -314,16 +308,11 @@ static void isp1704_charger_work(struct work_struct *data) ...@@ -314,16 +308,11 @@ static void isp1704_charger_work(struct work_struct *data)
} }
static int isp1704_notifier_call(struct notifier_block *nb, static int isp1704_notifier_call(struct notifier_block *nb,
unsigned long event, void *power) unsigned long val, void *v)
{ {
struct isp1704_charger *isp = struct isp1704_charger *isp =
container_of(nb, struct isp1704_charger, nb); container_of(nb, struct isp1704_charger, nb);
isp->event = event;
if (power)
isp->max_power = *((unsigned *)power);
schedule_work(&isp->work); schedule_work(&isp->work);
return NOTIFY_OK; return NOTIFY_OK;
...@@ -462,13 +451,13 @@ static int isp1704_charger_probe(struct platform_device *pdev) ...@@ -462,13 +451,13 @@ static int isp1704_charger_probe(struct platform_device *pdev)
if (isp->phy->otg->gadget) if (isp->phy->otg->gadget)
usb_gadget_disconnect(isp->phy->otg->gadget); usb_gadget_disconnect(isp->phy->otg->gadget);
if (isp->phy->last_event == USB_EVENT_NONE)
isp1704_charger_set_power(isp, 0);
/* Detect charger if VBUS is valid (the cable was already plugged). */ /* Detect charger if VBUS is valid (the cable was already plugged). */
ret = isp1704_read(isp, ULPI_USB_INT_STS); if (isp->phy->last_event == USB_EVENT_VBUS &&
isp1704_charger_set_power(isp, 0); !isp->phy->otg->default_a)
if ((ret & ULPI_INT_VBUS_VALID) && !isp->phy->otg->default_a) {
isp->event = USB_EVENT_VBUS;
schedule_work(&isp->work); schedule_work(&isp->work);
}
return 0; return 0;
fail2: fail2:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment