Commit a709bd58 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-v3.13' of git://git.infradead.org/battery-2.6

Pull battery updates from Anton Vorontsov:
 "Highlights:
   - A new driver for TI BQ24735 Battery Chargers, courtesy of NVidia.
   - Device tree bindings for TWL4030 chips.
   - Random fixes and cleanups"

* tag 'for-v3.13' of git://git.infradead.org/battery-2.6:
  pm2301-charger: Remove unneeded NULL checks
  twl4030_charger: Add devicetree support
  power_supply: Fix documentation for TEMP_*ALERT* properties
  max17042_battery: Support regmap to access device's registers
  max17042_battery: Use SIMPLE_DEV_PM_OPS
  charger-manager : Replace kzalloc to devm_kzalloc and remove uneccessary code
  bq2415x_charger: Fix max battery regulation voltage
  tps65090-charger: Use "IS_ENABLED(CONFIG_OF)" for DT code
  tps65090-charger: Drop devm_free_irq of devm_ allocated irq
  power_supply: Add support for bq24735 charger
  pm2301-charger: Staticize pm2xxx_charger_die_therm_mngt
  pm2301-charger: Check return value of regulator_enable
  ab8500-charger: Remove redundant break
  ab8500-charger: Check return value of regulator_enable
  isp1704_charger: Fix driver to work with changes introduced in v3.5
parents 3ea369ee c8024234
TWL BCI (Battery Charger Interface)
Required properties:
- compatible:
- "ti,twl4030-bci"
- interrupts: two interrupt lines from the TWL SIH (secondary
interrupt handler) - interrupts 9 and 2.
Optional properties:
- ti,bb-uvolt: microvolts for charging the backup battery.
- ti,bb-uamp: microamps for charging the backup battery.
Examples:
bci {
compatible = "ti,twl4030-bci";
interrupts = <9>, <2>;
ti,bb-uvolt = <3200000>;
ti,bb-uamp = <150>;
};
TI BQ24735 Charge Controller
~~~~~~~~~~
Required properties :
- compatible : "ti,bq24735"
Optional properties :
- interrupts : Specify the interrupt to be used to trigger when the AC
adapter is either plugged in or removed.
- ti,ac-detect-gpios : This GPIO is optionally used to read the AC adapter
presence. This is a Host GPIO that is configured as an input and
connected to the bq24735.
- ti,charge-current : Used to control and set the charging current. This value
must be between 128mA and 8.128A with a 64mA step resolution. The POR value
is 0x0000h. This number is in mA (e.g. 8192), see spec for more information
about the ChargeCurrent (0x14h) register.
- ti,charge-voltage : Used to control and set the charging voltage. This value
must be between 1.024V and 19.2V with a 16mV step resolution. The POR value
is 0x0000h. This number is in mV (e.g. 19200), see spec for more information
about the ChargeVoltage (0x15h) register.
- ti,input-current : Used to control and set the charger input current. This
value must be between 128mA and 8.064A with a 128mA step resolution. The
POR value is 0x1000h. This number is in mA (e.g. 8064), see the spec for
more information about the InputCurrent (0x3fh) register.
Example:
bq24735@9 {
compatible = "ti,bq24735";
reg = <0x9>;
ti,ac-detect-gpios = <&gpio 72 0x1>;
}
...@@ -135,11 +135,11 @@ CAPACITY_LEVEL - capacity level. This corresponds to ...@@ -135,11 +135,11 @@ CAPACITY_LEVEL - capacity level. This corresponds to
POWER_SUPPLY_CAPACITY_LEVEL_*. POWER_SUPPLY_CAPACITY_LEVEL_*.
TEMP - temperature of the power supply. TEMP - temperature of the power supply.
TEMP_ALERT_MIN - minimum battery temperature alert value in milli centigrade. TEMP_ALERT_MIN - minimum battery temperature alert.
TEMP_ALERT_MAX - maximum battery temperature alert value in milli centigrade. TEMP_ALERT_MAX - maximum battery temperature alert.
TEMP_AMBIENT - ambient temperature. TEMP_AMBIENT - ambient temperature.
TEMP_AMBIENT_ALERT_MIN - minimum ambient temperature alert value in milli centigrade. TEMP_AMBIENT_ALERT_MIN - minimum ambient temperature alert.
TEMP_AMBIENT_ALERT_MAX - maximum ambient temperature alert value in milli centigrade. TEMP_AMBIENT_ALERT_MAX - maximum ambient temperature alert.
TIME_TO_EMPTY - seconds left for battery to be considered empty (i.e. TIME_TO_EMPTY - seconds left for battery to be considered empty (i.e.
while battery powers a load) while battery powers a load)
......
...@@ -19,6 +19,12 @@ rtc { ...@@ -19,6 +19,12 @@ rtc {
interrupts = <11>; interrupts = <11>;
}; };
charger: bci {
compatible = "ti,twl4030-bci";
interrupts = <9>, <2>;
bci3v1-supply = <&vusb3v1>;
};
watchdog { watchdog {
compatible = "ti,twl4030-wdt"; compatible = "ti,twl4030-wdt";
}; };
......
...@@ -346,6 +346,12 @@ config CHARGER_BQ24190 ...@@ -346,6 +346,12 @@ config CHARGER_BQ24190
help help
Say Y to enable support for the TI BQ24190 battery charger. Say Y to enable support for the TI BQ24190 battery charger.
config CHARGER_BQ24735
tristate "TI BQ24735 battery charger support"
depends on I2C && GPIOLIB
help
Say Y to enable support for the TI BQ24735 battery charger.
config CHARGER_SMB347 config CHARGER_SMB347
tristate "Summit Microelectronics SMB347 Battery Charger" tristate "Summit Microelectronics SMB347 Battery Charger"
depends on I2C depends on I2C
......
...@@ -52,6 +52,7 @@ obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o ...@@ -52,6 +52,7 @@ obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o
obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o
obj-$(CONFIG_CHARGER_BQ2415X) += bq2415x_charger.o obj-$(CONFIG_CHARGER_BQ2415X) += bq2415x_charger.o
obj-$(CONFIG_CHARGER_BQ24190) += bq24190_charger.o obj-$(CONFIG_CHARGER_BQ24190) += bq24190_charger.o
obj-$(CONFIG_CHARGER_BQ24735) += bq24735-charger.o
obj-$(CONFIG_POWER_AVS) += avs/ obj-$(CONFIG_POWER_AVS) += avs/
obj-$(CONFIG_CHARGER_SMB347) += smb347-charger.o obj-$(CONFIG_CHARGER_SMB347) += smb347-charger.o
obj-$(CONFIG_CHARGER_TPS65090) += tps65090-charger.o obj-$(CONFIG_CHARGER_TPS65090) += tps65090-charger.o
......
...@@ -766,7 +766,6 @@ static int ab8500_charger_max_usb_curr(struct ab8500_charger *di, ...@@ -766,7 +766,6 @@ static int ab8500_charger_max_usb_curr(struct ab8500_charger *di,
ret = -ENXIO; ret = -ENXIO;
break; break;
} }
break;
case USB_STAT_CARKIT_1: case USB_STAT_CARKIT_1:
case USB_STAT_CARKIT_2: case USB_STAT_CARKIT_2:
case USB_STAT_ACA_DOCK_CHARGER: case USB_STAT_ACA_DOCK_CHARGER:
...@@ -1387,7 +1386,11 @@ static int ab8500_charger_ac_en(struct ux500_charger *charger, ...@@ -1387,7 +1386,11 @@ static int ab8500_charger_ac_en(struct ux500_charger *charger,
* the GPADC module independant of the AB8500 chargers * the GPADC module independant of the AB8500 chargers
*/ */
if (!di->vddadc_en_ac) { if (!di->vddadc_en_ac) {
regulator_enable(di->regu); ret = regulator_enable(di->regu);
if (ret)
dev_warn(di->dev,
"Failed to enable regulator\n");
else
di->vddadc_en_ac = true; di->vddadc_en_ac = true;
} }
...@@ -1556,7 +1559,11 @@ static int ab8500_charger_usb_en(struct ux500_charger *charger, ...@@ -1556,7 +1559,11 @@ static int ab8500_charger_usb_en(struct ux500_charger *charger,
* the GPADC module independant of the AB8500 chargers * the GPADC module independant of the AB8500 chargers
*/ */
if (!di->vddadc_en_usb) { if (!di->vddadc_en_usb) {
regulator_enable(di->regu); ret = regulator_enable(di->regu);
if (ret)
dev_warn(di->dev,
"Failed to enable regulator\n");
else
di->vddadc_en_usb = true; di->vddadc_en_usb = true;
} }
......
...@@ -605,9 +605,13 @@ static int bq2415x_set_battery_regulation_voltage(struct bq2415x_device *bq, ...@@ -605,9 +605,13 @@ static int bq2415x_set_battery_regulation_voltage(struct bq2415x_device *bq,
{ {
int val = (mV/10 - 350) / 2; int val = (mV/10 - 350) / 2;
/*
* According to datasheet, maximum battery regulation voltage is
* 4440mV which is b101111 = 47.
*/
if (val < 0) if (val < 0)
val = 0; val = 0;
else if (val > 94) /* FIXME: Max is 94 or 122 ? Set max value ? */ else if (val > 47)
return -EINVAL; return -EINVAL;
return bq2415x_i2c_write_mask(bq, BQ2415X_REG_VOLTAGE, val, return bq2415x_i2c_write_mask(bq, BQ2415X_REG_VOLTAGE, val,
......
This diff is collapsed.
...@@ -1378,7 +1378,8 @@ static int charger_manager_register_sysfs(struct charger_manager *cm) ...@@ -1378,7 +1378,8 @@ static int charger_manager_register_sysfs(struct charger_manager *cm)
charger = &desc->charger_regulators[i]; charger = &desc->charger_regulators[i];
snprintf(buf, 10, "charger.%d", i); snprintf(buf, 10, "charger.%d", i);
str = kzalloc(sizeof(char) * (strlen(buf) + 1), GFP_KERNEL); str = devm_kzalloc(cm->dev,
sizeof(char) * (strlen(buf) + 1), GFP_KERNEL);
if (!str) { if (!str) {
ret = -ENOMEM; ret = -ENOMEM;
goto err; goto err;
...@@ -1452,30 +1453,23 @@ static int charger_manager_probe(struct platform_device *pdev) ...@@ -1452,30 +1453,23 @@ static int charger_manager_probe(struct platform_device *pdev)
rtc_dev = NULL; rtc_dev = NULL;
dev_err(&pdev->dev, "Cannot get RTC %s\n", dev_err(&pdev->dev, "Cannot get RTC %s\n",
g_desc->rtc_name); g_desc->rtc_name);
ret = -ENODEV; return -ENODEV;
goto err_alloc;
} }
} }
if (!desc) { if (!desc) {
dev_err(&pdev->dev, "No platform data (desc) found\n"); dev_err(&pdev->dev, "No platform data (desc) found\n");
ret = -ENODEV; return -ENODEV;
goto err_alloc;
} }
cm = kzalloc(sizeof(struct charger_manager), GFP_KERNEL); cm = devm_kzalloc(&pdev->dev,
if (!cm) { sizeof(struct charger_manager), GFP_KERNEL);
ret = -ENOMEM; if (!cm)
goto err_alloc; return -ENOMEM;
}
/* Basic Values. Unspecified are Null or 0 */ /* Basic Values. Unspecified are Null or 0 */
cm->dev = &pdev->dev; cm->dev = &pdev->dev;
cm->desc = kmemdup(desc, sizeof(struct charger_desc), GFP_KERNEL); cm->desc = desc;
if (!cm->desc) {
ret = -ENOMEM;
goto err_alloc_desc;
}
cm->last_temp_mC = INT_MIN; /* denotes "unmeasured, yet" */ cm->last_temp_mC = INT_MIN; /* denotes "unmeasured, yet" */
/* /*
...@@ -1498,27 +1492,23 @@ static int charger_manager_probe(struct platform_device *pdev) ...@@ -1498,27 +1492,23 @@ static int charger_manager_probe(struct platform_device *pdev)
} }
if (!desc->charger_regulators || desc->num_charger_regulators < 1) { if (!desc->charger_regulators || desc->num_charger_regulators < 1) {
ret = -EINVAL;
dev_err(&pdev->dev, "charger_regulators undefined\n"); dev_err(&pdev->dev, "charger_regulators undefined\n");
goto err_no_charger; return -EINVAL;
} }
if (!desc->psy_charger_stat || !desc->psy_charger_stat[0]) { if (!desc->psy_charger_stat || !desc->psy_charger_stat[0]) {
dev_err(&pdev->dev, "No power supply defined\n"); dev_err(&pdev->dev, "No power supply defined\n");
ret = -EINVAL; return -EINVAL;
goto err_no_charger_stat;
} }
/* Counting index only */ /* Counting index only */
while (desc->psy_charger_stat[i]) while (desc->psy_charger_stat[i])
i++; i++;
cm->charger_stat = kzalloc(sizeof(struct power_supply *) * (i + 1), cm->charger_stat = devm_kzalloc(&pdev->dev,
GFP_KERNEL); sizeof(struct power_supply *) * i, GFP_KERNEL);
if (!cm->charger_stat) { if (!cm->charger_stat)
ret = -ENOMEM; return -ENOMEM;
goto err_no_charger_stat;
}
for (i = 0; desc->psy_charger_stat[i]; i++) { for (i = 0; desc->psy_charger_stat[i]; i++) {
cm->charger_stat[i] = power_supply_get_by_name( cm->charger_stat[i] = power_supply_get_by_name(
...@@ -1526,8 +1516,7 @@ static int charger_manager_probe(struct platform_device *pdev) ...@@ -1526,8 +1516,7 @@ static int charger_manager_probe(struct platform_device *pdev)
if (!cm->charger_stat[i]) { if (!cm->charger_stat[i]) {
dev_err(&pdev->dev, "Cannot find power supply \"%s\"\n", dev_err(&pdev->dev, "Cannot find power supply \"%s\"\n",
desc->psy_charger_stat[i]); desc->psy_charger_stat[i]);
ret = -ENODEV; return -ENODEV;
goto err_chg_stat;
} }
} }
...@@ -1535,21 +1524,18 @@ static int charger_manager_probe(struct platform_device *pdev) ...@@ -1535,21 +1524,18 @@ static int charger_manager_probe(struct platform_device *pdev)
if (!cm->fuel_gauge) { if (!cm->fuel_gauge) {
dev_err(&pdev->dev, "Cannot find power supply \"%s\"\n", dev_err(&pdev->dev, "Cannot find power supply \"%s\"\n",
desc->psy_fuel_gauge); desc->psy_fuel_gauge);
ret = -ENODEV; return -ENODEV;
goto err_chg_stat;
} }
if (desc->polling_interval_ms == 0 || if (desc->polling_interval_ms == 0 ||
msecs_to_jiffies(desc->polling_interval_ms) <= CM_JIFFIES_SMALL) { msecs_to_jiffies(desc->polling_interval_ms) <= CM_JIFFIES_SMALL) {
dev_err(&pdev->dev, "polling_interval_ms is too small\n"); dev_err(&pdev->dev, "polling_interval_ms is too small\n");
ret = -EINVAL; return -EINVAL;
goto err_chg_stat;
} }
if (!desc->temperature_out_of_range) { if (!desc->temperature_out_of_range) {
dev_err(&pdev->dev, "there is no temperature_out_of_range\n"); dev_err(&pdev->dev, "there is no temperature_out_of_range\n");
ret = -EINVAL; return -EINVAL;
goto err_chg_stat;
} }
if (!desc->charging_max_duration_ms || if (!desc->charging_max_duration_ms ||
...@@ -1570,14 +1556,13 @@ static int charger_manager_probe(struct platform_device *pdev) ...@@ -1570,14 +1556,13 @@ static int charger_manager_probe(struct platform_device *pdev)
cm->charger_psy.name = cm->psy_name_buf; cm->charger_psy.name = cm->psy_name_buf;
/* Allocate for psy properties because they may vary */ /* Allocate for psy properties because they may vary */
cm->charger_psy.properties = kzalloc(sizeof(enum power_supply_property) cm->charger_psy.properties = devm_kzalloc(&pdev->dev,
sizeof(enum power_supply_property)
* (ARRAY_SIZE(default_charger_props) + * (ARRAY_SIZE(default_charger_props) +
NUM_CHARGER_PSY_OPTIONAL), NUM_CHARGER_PSY_OPTIONAL), GFP_KERNEL);
GFP_KERNEL); if (!cm->charger_psy.properties)
if (!cm->charger_psy.properties) { return -ENOMEM;
ret = -ENOMEM;
goto err_chg_stat;
}
memcpy(cm->charger_psy.properties, default_charger_props, memcpy(cm->charger_psy.properties, default_charger_props,
sizeof(enum power_supply_property) * sizeof(enum power_supply_property) *
ARRAY_SIZE(default_charger_props)); ARRAY_SIZE(default_charger_props));
...@@ -1614,7 +1599,7 @@ static int charger_manager_probe(struct platform_device *pdev) ...@@ -1614,7 +1599,7 @@ static int charger_manager_probe(struct platform_device *pdev)
if (ret) { if (ret) {
dev_err(&pdev->dev, "Cannot register charger-manager with name \"%s\"\n", dev_err(&pdev->dev, "Cannot register charger-manager with name \"%s\"\n",
cm->charger_psy.name); cm->charger_psy.name);
goto err_register; return ret;
} }
/* Register extcon device for charger cable */ /* Register extcon device for charger cable */
...@@ -1655,8 +1640,6 @@ static int charger_manager_probe(struct platform_device *pdev) ...@@ -1655,8 +1640,6 @@ static int charger_manager_probe(struct platform_device *pdev)
charger = &desc->charger_regulators[i]; charger = &desc->charger_regulators[i];
sysfs_remove_group(&cm->charger_psy.dev->kobj, sysfs_remove_group(&cm->charger_psy.dev->kobj,
&charger->attr_g); &charger->attr_g);
kfree(charger->attr_g.name);
} }
err_reg_extcon: err_reg_extcon:
for (i = 0; i < desc->num_charger_regulators; i++) { for (i = 0; i < desc->num_charger_regulators; i++) {
...@@ -1674,16 +1657,7 @@ static int charger_manager_probe(struct platform_device *pdev) ...@@ -1674,16 +1657,7 @@ static int charger_manager_probe(struct platform_device *pdev)
} }
power_supply_unregister(&cm->charger_psy); power_supply_unregister(&cm->charger_psy);
err_register:
kfree(cm->charger_psy.properties);
err_chg_stat:
kfree(cm->charger_stat);
err_no_charger_stat:
err_no_charger:
kfree(cm->desc);
err_alloc_desc:
kfree(cm);
err_alloc:
return ret; return ret;
} }
...@@ -1718,11 +1692,6 @@ static int charger_manager_remove(struct platform_device *pdev) ...@@ -1718,11 +1692,6 @@ static int charger_manager_remove(struct platform_device *pdev)
try_charger_enable(cm, false); try_charger_enable(cm, false);
kfree(cm->charger_psy.properties);
kfree(cm->charger_stat);
kfree(cm->desc);
kfree(cm);
return 0; return 0;
} }
......
...@@ -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:
/* do not call wall charger detection more times */
if (!isp->present) {
isp->online = true; isp->online = true;
isp->present = 1;
isp1704_charger_set_power(isp, 1);
/* detect charger */ /* detect wall charger */
detect = isp1704_charger_detect(isp); 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;
}
if (detect) { /* enable data pullups */
isp->present = detect; if (isp->phy->otg->gadget)
isp->psy.type = isp1704_charger_type(isp); usb_gadget_connect(isp->phy->otg->gadget);
} }
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
*/ */
if (isp->current_max > 500)
isp->current_max = 500; isp->current_max = 500;
/* FALLTHROUGH */
case POWER_SUPPLY_TYPE_USB: if (isp->current_max > 100)
default: isp->psy.type = POWER_SUPPLY_TYPE_USB_CDP;
/* enable data pullups */
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);
/* Detect charger if VBUS is valid (the cable was already plugged). */ if (isp->phy->last_event == USB_EVENT_NONE)
ret = isp1704_read(isp, ULPI_USB_INT_STS);
isp1704_charger_set_power(isp, 0); isp1704_charger_set_power(isp, 0);
if ((ret & ULPI_INT_VBUS_VALID) && !isp->phy->otg->default_a) {
isp->event = USB_EVENT_VBUS; /* Detect charger if VBUS is valid (the cable was already plugged). */
if (isp->phy->last_event == USB_EVENT_VBUS &&
!isp->phy->otg->default_a)
schedule_work(&isp->work); schedule_work(&isp->work);
}
return 0; return 0;
fail2: fail2:
......
This diff is collapsed.
...@@ -205,7 +205,7 @@ static int pm2xxx_charger_batt_therm_mngt(struct pm2xxx_charger *pm2, int val) ...@@ -205,7 +205,7 @@ static int pm2xxx_charger_batt_therm_mngt(struct pm2xxx_charger *pm2, int val)
} }
int pm2xxx_charger_die_therm_mngt(struct pm2xxx_charger *pm2, int val) static int pm2xxx_charger_die_therm_mngt(struct pm2xxx_charger *pm2, int val)
{ {
queue_work(pm2->charger_wq, &pm2->check_main_thermal_prot_work); queue_work(pm2->charger_wq, &pm2->check_main_thermal_prot_work);
...@@ -722,7 +722,11 @@ static int pm2xxx_charger_ac_en(struct ux500_charger *charger, ...@@ -722,7 +722,11 @@ static int pm2xxx_charger_ac_en(struct ux500_charger *charger,
dev_dbg(pm2->dev, "Enable AC: %dmV %dmA\n", vset, iset); dev_dbg(pm2->dev, "Enable AC: %dmV %dmA\n", vset, iset);
if (!pm2->vddadc_en_ac) { if (!pm2->vddadc_en_ac) {
regulator_enable(pm2->regu); ret = regulator_enable(pm2->regu);
if (ret)
dev_warn(pm2->dev,
"Failed to enable vddadc regulator\n");
else
pm2->vddadc_en_ac = true; pm2->vddadc_en_ac = true;
} }
...@@ -953,37 +957,24 @@ static int pm2xxx_runtime_suspend(struct device *dev) ...@@ -953,37 +957,24 @@ static int pm2xxx_runtime_suspend(struct device *dev)
{ {
struct i2c_client *pm2xxx_i2c_client = to_i2c_client(dev); struct i2c_client *pm2xxx_i2c_client = to_i2c_client(dev);
struct pm2xxx_charger *pm2; struct pm2xxx_charger *pm2;
int ret = 0;
pm2 = (struct pm2xxx_charger *)i2c_get_clientdata(pm2xxx_i2c_client); pm2 = (struct pm2xxx_charger *)i2c_get_clientdata(pm2xxx_i2c_client);
if (!pm2) {
dev_err(pm2->dev, "no pm2xxx_charger data supplied\n");
ret = -EINVAL;
return ret;
}
clear_lpn_pin(pm2); clear_lpn_pin(pm2);
return ret; return 0;
} }
static int pm2xxx_runtime_resume(struct device *dev) static int pm2xxx_runtime_resume(struct device *dev)
{ {
struct i2c_client *pm2xxx_i2c_client = to_i2c_client(dev); struct i2c_client *pm2xxx_i2c_client = to_i2c_client(dev);
struct pm2xxx_charger *pm2; struct pm2xxx_charger *pm2;
int ret = 0;
pm2 = (struct pm2xxx_charger *)i2c_get_clientdata(pm2xxx_i2c_client); pm2 = (struct pm2xxx_charger *)i2c_get_clientdata(pm2xxx_i2c_client);
if (!pm2) {
dev_err(pm2->dev, "no pm2xxx_charger data supplied\n");
ret = -EINVAL;
return ret;
}
if (gpio_is_valid(pm2->lpn_pin) && gpio_get_value(pm2->lpn_pin) == 0) if (gpio_is_valid(pm2->lpn_pin) && gpio_get_value(pm2->lpn_pin) == 0)
set_lpn_pin(pm2); set_lpn_pin(pm2);
return ret; return 0;
} }
#endif #endif
......
...@@ -15,15 +15,17 @@ ...@@ -15,15 +15,17 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <linux/delay.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/slab.h> #include <linux/of_device.h>
#include <linux/delay.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/power_supply.h> #include <linux/power_supply.h>
#include <linux/slab.h>
#include <linux/mfd/tps65090.h> #include <linux/mfd/tps65090.h>
#define TPS65090_REG_INTR_STS 0x00 #define TPS65090_REG_INTR_STS 0x00
...@@ -185,10 +187,6 @@ static irqreturn_t tps65090_charger_isr(int irq, void *dev_id) ...@@ -185,10 +187,6 @@ static irqreturn_t tps65090_charger_isr(int irq, void *dev_id)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
#if defined(CONFIG_OF)
#include <linux/of_device.h>
static struct tps65090_platform_data * static struct tps65090_platform_data *
tps65090_parse_dt_charger_data(struct platform_device *pdev) tps65090_parse_dt_charger_data(struct platform_device *pdev)
{ {
...@@ -210,13 +208,6 @@ static struct tps65090_platform_data * ...@@ -210,13 +208,6 @@ static struct tps65090_platform_data *
return pdata; return pdata;
} }
#else
static struct tps65090_platform_data *
tps65090_parse_dt_charger_data(struct platform_device *pdev)
{
return NULL;
}
#endif
static int tps65090_charger_probe(struct platform_device *pdev) static int tps65090_charger_probe(struct platform_device *pdev)
{ {
...@@ -228,7 +219,7 @@ static int tps65090_charger_probe(struct platform_device *pdev) ...@@ -228,7 +219,7 @@ static int tps65090_charger_probe(struct platform_device *pdev)
pdata = dev_get_platdata(pdev->dev.parent); pdata = dev_get_platdata(pdev->dev.parent);
if (!pdata && pdev->dev.of_node) if (IS_ENABLED(CONFIG_OF) && !pdata && pdev->dev.of_node)
pdata = tps65090_parse_dt_charger_data(pdev); pdata = tps65090_parse_dt_charger_data(pdev);
if (!pdata) { if (!pdata) {
...@@ -277,13 +268,13 @@ static int tps65090_charger_probe(struct platform_device *pdev) ...@@ -277,13 +268,13 @@ static int tps65090_charger_probe(struct platform_device *pdev)
if (ret) { if (ret) {
dev_err(cdata->dev, "Unable to register irq %d err %d\n", irq, dev_err(cdata->dev, "Unable to register irq %d err %d\n", irq,
ret); ret);
goto fail_free_irq; goto fail_unregister_supply;
} }
ret = tps65090_config_charger(cdata); ret = tps65090_config_charger(cdata);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, "charger config failed, err %d\n", ret); dev_err(&pdev->dev, "charger config failed, err %d\n", ret);
goto fail_free_irq; goto fail_unregister_supply;
} }
/* Check for charger presence */ /* Check for charger presence */
...@@ -292,14 +283,14 @@ static int tps65090_charger_probe(struct platform_device *pdev) ...@@ -292,14 +283,14 @@ static int tps65090_charger_probe(struct platform_device *pdev)
if (ret < 0) { if (ret < 0) {
dev_err(cdata->dev, "%s(): Error in reading reg 0x%x", __func__, dev_err(cdata->dev, "%s(): Error in reading reg 0x%x", __func__,
TPS65090_REG_CG_STATUS1); TPS65090_REG_CG_STATUS1);
goto fail_free_irq; goto fail_unregister_supply;
} }
if (status1 != 0) { if (status1 != 0) {
ret = tps65090_enable_charging(cdata); ret = tps65090_enable_charging(cdata);
if (ret < 0) { if (ret < 0) {
dev_err(cdata->dev, "error enabling charger\n"); dev_err(cdata->dev, "error enabling charger\n");
goto fail_free_irq; goto fail_unregister_supply;
} }
cdata->ac_online = 1; cdata->ac_online = 1;
power_supply_changed(&cdata->ac); power_supply_changed(&cdata->ac);
...@@ -307,8 +298,6 @@ static int tps65090_charger_probe(struct platform_device *pdev) ...@@ -307,8 +298,6 @@ static int tps65090_charger_probe(struct platform_device *pdev)
return 0; return 0;
fail_free_irq:
devm_free_irq(cdata->dev, irq, cdata);
fail_unregister_supply: fail_unregister_supply:
power_supply_unregister(&cdata->ac); power_supply_unregister(&cdata->ac);
...@@ -319,7 +308,6 @@ static int tps65090_charger_remove(struct platform_device *pdev) ...@@ -319,7 +308,6 @@ static int tps65090_charger_remove(struct platform_device *pdev)
{ {
struct tps65090_charger *cdata = platform_get_drvdata(pdev); struct tps65090_charger *cdata = platform_get_drvdata(pdev);
devm_free_irq(cdata->dev, cdata->irq, cdata);
power_supply_unregister(&cdata->ac); power_supply_unregister(&cdata->ac);
return 0; return 0;
......
...@@ -495,10 +495,38 @@ static enum power_supply_property twl4030_charger_props[] = { ...@@ -495,10 +495,38 @@ static enum power_supply_property twl4030_charger_props[] = {
POWER_SUPPLY_PROP_CURRENT_NOW, POWER_SUPPLY_PROP_CURRENT_NOW,
}; };
#ifdef CONFIG_OF
static const struct twl4030_bci_platform_data *
twl4030_bci_parse_dt(struct device *dev)
{
struct device_node *np = dev->of_node;
struct twl4030_bci_platform_data *pdata;
u32 num;
if (!np)
return NULL;
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return pdata;
if (of_property_read_u32(np, "ti,bb-uvolt", &num) == 0)
pdata->bb_uvolt = num;
if (of_property_read_u32(np, "ti,bb-uamp", &num) == 0)
pdata->bb_uamp = num;
return pdata;
}
#else
static inline const struct twl4030_bci_platform_data *
twl4030_bci_parse_dt(struct device *dev)
{
return NULL;
}
#endif
static int __init twl4030_bci_probe(struct platform_device *pdev) static int __init twl4030_bci_probe(struct platform_device *pdev)
{ {
struct twl4030_bci *bci; struct twl4030_bci *bci;
struct twl4030_bci_platform_data *pdata = pdev->dev.platform_data; const struct twl4030_bci_platform_data *pdata = pdev->dev.platform_data;
int ret; int ret;
u32 reg; u32 reg;
...@@ -506,6 +534,9 @@ static int __init twl4030_bci_probe(struct platform_device *pdev) ...@@ -506,6 +534,9 @@ static int __init twl4030_bci_probe(struct platform_device *pdev)
if (bci == NULL) if (bci == NULL)
return -ENOMEM; return -ENOMEM;
if (!pdata)
pdata = twl4030_bci_parse_dt(&pdev->dev);
bci->dev = &pdev->dev; bci->dev = &pdev->dev;
bci->irq_chg = platform_get_irq(pdev, 0); bci->irq_chg = platform_get_irq(pdev, 0);
bci->irq_bci = platform_get_irq(pdev, 1); bci->irq_bci = platform_get_irq(pdev, 1);
...@@ -581,8 +612,11 @@ static int __init twl4030_bci_probe(struct platform_device *pdev) ...@@ -581,8 +612,11 @@ static int __init twl4030_bci_probe(struct platform_device *pdev)
twl4030_charger_enable_ac(true); twl4030_charger_enable_ac(true);
twl4030_charger_enable_usb(bci, true); twl4030_charger_enable_usb(bci, true);
if (pdata)
twl4030_charger_enable_backup(pdata->bb_uvolt, twl4030_charger_enable_backup(pdata->bb_uvolt,
pdata->bb_uamp); pdata->bb_uamp);
else
twl4030_charger_enable_backup(0, 0);
return 0; return 0;
...@@ -631,10 +665,17 @@ static int __exit twl4030_bci_remove(struct platform_device *pdev) ...@@ -631,10 +665,17 @@ static int __exit twl4030_bci_remove(struct platform_device *pdev)
return 0; return 0;
} }
static const struct of_device_id twl_bci_of_match[] = {
{.compatible = "ti,twl4030-bci", },
{ }
};
MODULE_DEVICE_TABLE(of, twl_bci_of_match);
static struct platform_driver twl4030_bci_driver = { static struct platform_driver twl4030_bci_driver = {
.driver = { .driver = {
.name = "twl4030_bci", .name = "twl4030_bci",
.owner = THIS_MODULE, .owner = THIS_MODULE,
.of_match_table = of_match_ptr(twl_bci_of_match),
}, },
.remove = __exit_p(twl4030_bci_remove), .remove = __exit_p(twl4030_bci_remove),
}; };
......
/*
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __CHARGER_BQ24735_H_
#define __CHARGER_BQ24735_H_
#include <linux/types.h>
#include <linux/power_supply.h>
struct bq24735_platform {
uint32_t charge_current;
uint32_t charge_voltage;
uint32_t input_current;
const char *name;
int status_gpio;
int status_gpio_active_low;
bool status_gpio_valid;
char **supplied_to;
size_t num_supplicants;
};
#endif /* __CHARGER_BQ24735_H_ */
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