power: pm8921-charger: support dc charging while in usb host mode

The current code disables charging when the usb is operating in host
mode. This unnecessarily stops charging from the DC path. The board
layout (the ovp fet and otg path) is assumed to support host mode and
charging from dc path.

Also make the usb driver change the power supply framework's scope
property instead of calling 8921 charger apis directly.

CRs-Fixed: 373365
Change-Id: I2a9fb32de22cbe68e26078b97a7d83c40272a370
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
This commit is contained in:
Abhijeet Dharmapurikar 2012-06-26 11:21:03 -07:00 committed by Stephen Boyd
parent 811c5d6e11
commit 5a0002ab37
2 changed files with 88 additions and 2 deletions

View file

@ -265,6 +265,7 @@ struct pm8921_chg_chip {
enum pm8921_chg_hot_thr hot_thr;
int rconn_mohm;
enum pm8921_chg_led_src_config led_src_config;
bool host_mode;
};
/* user space parameter to limit usb current */
@ -1141,6 +1142,7 @@ static enum power_supply_property pm_power_props_usb[] = {
POWER_SUPPLY_PROP_PRESENT,
POWER_SUPPLY_PROP_ONLINE,
POWER_SUPPLY_PROP_CURRENT_MAX,
POWER_SUPPLY_PROP_SCOPE,
};
static enum power_supply_property pm_power_props_mains[] = {
@ -1196,6 +1198,67 @@ static int pm_power_get_property_mains(struct power_supply *psy,
return 0;
}
static int switch_usb_to_charge_mode(struct pm8921_chg_chip *chip)
{
int rc;
if (!chip->host_mode)
return 0;
/* enable usbin valid comparator and remove force usb ovp fet off */
rc = pm8xxx_writeb(chip->dev->parent, USB_OVP_TEST, 0xB2);
if (rc < 0) {
pr_err("Failed to write 0xB2 to USB_OVP_TEST rc = %d\n", rc);
return rc;
}
chip->host_mode = 0;
return 0;
}
static int switch_usb_to_host_mode(struct pm8921_chg_chip *chip)
{
int rc;
if (chip->host_mode)
return 0;
/* disable usbin valid comparator and force usb ovp fet off */
rc = pm8xxx_writeb(chip->dev->parent, USB_OVP_TEST, 0xB3);
if (rc < 0) {
pr_err("Failed to write 0xB3 to USB_OVP_TEST rc = %d\n", rc);
return rc;
}
chip->host_mode = 1;
return 0;
}
static int pm_power_set_property_usb(struct power_supply *psy,
enum power_supply_property psp,
const union power_supply_propval *val)
{
/* Check if called before init */
if (!the_chip)
return -EINVAL;
switch (psp) {
case POWER_SUPPLY_PROP_SCOPE:
if (val->intval == POWER_SUPPLY_SCOPE_SYSTEM)
return switch_usb_to_host_mode(the_chip);
if (val->intval == POWER_SUPPLY_SCOPE_DEVICE)
return switch_usb_to_charge_mode(the_chip);
else
return -EINVAL;
break;
default:
return -EINVAL;
}
return 0;
}
static int pm_power_get_property_usb(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
@ -1234,6 +1297,13 @@ static int pm_power_get_property_usb(struct power_supply *psy,
else
return 0;
break;
case POWER_SUPPLY_PROP_SCOPE:
if (the_chip->host_mode)
val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
else
val->intval = POWER_SUPPLY_SCOPE_DEVICE;
break;
default:
return -EINVAL;
}
@ -3851,6 +3921,7 @@ static int __devinit pm8921_charger_probe(struct platform_device *pdev)
chip->usb_psy.properties = pm_power_props_usb,
chip->usb_psy.num_properties = ARRAY_SIZE(pm_power_props_usb),
chip->usb_psy.get_property = pm_power_get_property_usb,
chip->usb_psy.set_property = pm_power_set_property_usb,
chip->dc_psy.name = "pm8921-dc",
chip->dc_psy.type = POWER_SUPPLY_TYPE_MAINS,

View file

@ -972,6 +972,21 @@ skip_phy_resume:
}
#endif
static int msm_otg_notify_host_mode(struct msm_otg *motg, bool host_mode)
{
if (!psy)
goto psy_not_supported;
if (host_mode)
power_supply_set_scope(psy, POWER_SUPPLY_SCOPE_SYSTEM);
else
power_supply_set_scope(psy, POWER_SUPPLY_SCOPE_DEVICE);
psy_not_supported:
dev_dbg(motg->phy.dev, "Power Supply doesn't support USB charger\n");
return -ENXIO;
}
static int msm_otg_notify_chg_type(struct msm_otg *motg)
{
static int charger_type;
@ -1220,7 +1235,7 @@ static void msm_hsusb_vbus_power(struct msm_otg *motg, bool on)
* current from the source.
*/
if (on) {
pm8921_disable_source_current(on);
msm_otg_notify_host_mode(motg, on);
ret = regulator_enable(vbus_otg);
if (ret) {
pr_err("unable to enable vbus_otg\n");
@ -1233,7 +1248,7 @@ static void msm_hsusb_vbus_power(struct msm_otg *motg, bool on)
pr_err("unable to disable vbus_otg\n");
return;
}
pm8921_disable_source_current(on);
msm_otg_notify_host_mode(motg, on);
vbus_is_on = false;
}
}