Skip to content

Commit

Permalink
Merge git://git.infradead.org/battery-2.6
Browse files Browse the repository at this point in the history
* git://git.infradead.org/battery-2.6:
  da9030_battery: Fix race between event handler and monitor
  Add MAX17040 Fuel Gauge driver
  w1: ds2760_battery: add support for sleep mode feature
  w1: ds2760: add support for EEPROM read and write
  ds2760_battery: cleanups in ds2760_battery_probe()
  • Loading branch information
Linus Torvalds committed Jun 24, 2009
2 parents c622304 + a35d01a commit f27884a
Show file tree
Hide file tree
Showing 8 changed files with 420 additions and 17 deletions.
8 changes: 8 additions & 0 deletions drivers/power/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ config BATTERY_DA9030
Say Y here to enable support for batteries charger integrated into
DA9030 PMIC.

config BATTERY_MAX17040
tristate "Maxim MAX17040 Fuel Gauge"
depends on I2C
help
MAX17040 is fuel-gauge systems for lithium-ion (Li+) batteries
in handheld and portable equipment. The MAX17040 is configured
to operate with a single lithium cell

config CHARGER_PCF50633
tristate "NXP PCF50633 MBC"
depends on MFD_PCF50633
Expand Down
3 changes: 2 additions & 1 deletion drivers/power/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@ obj-$(CONFIG_BATTERY_TOSA) += tosa_battery.o
obj-$(CONFIG_BATTERY_WM97XX) += wm97xx_battery.o
obj-$(CONFIG_BATTERY_BQ27x00) += bq27x00_battery.o
obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o
obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o
obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o
obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o
19 changes: 12 additions & 7 deletions drivers/power/da9030_battery.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@
#include <linux/debugfs.h>
#include <linux/seq_file.h>

#define DA9030_STATUS_CHDET (1 << 3)

#define DA9030_FAULT_LOG 0x0a
#define DA9030_FAULT_LOG_OVER_TEMP (1 << 7)
#define DA9030_FAULT_LOG_VBAT_OVER (1 << 4)
Expand Down Expand Up @@ -244,6 +242,8 @@ static void da9030_set_charge(struct da9030_charger *charger, int on)
}

da903x_write(charger->master, DA9030_CHARGE_CONTROL, val);

power_supply_changed(&charger->psy);
}

static void da9030_charger_check_state(struct da9030_charger *charger)
Expand All @@ -258,6 +258,12 @@ static void da9030_charger_check_state(struct da9030_charger *charger)
da9030_set_charge(charger, 1);
}
} else {
/* Charger has been pulled out */
if (!charger->chdet) {
da9030_set_charge(charger, 0);
return;
}

if (charger->adc.vbat_res >=
charger->thresholds.vbat_charge_stop) {
da9030_set_charge(charger, 0);
Expand Down Expand Up @@ -395,13 +401,11 @@ static int da9030_battery_event(struct notifier_block *nb, unsigned long event,
{
struct da9030_charger *charger =
container_of(nb, struct da9030_charger, nb);
int status;

switch (event) {
case DA9030_EVENT_CHDET:
status = da903x_query_status(charger->master,
DA9030_STATUS_CHDET);
da9030_set_charge(charger, status);
cancel_delayed_work_sync(&charger->work);
schedule_work(&charger->work.work);
break;
case DA9030_EVENT_VBATMON:
da9030_battery_vbat_event(charger);
Expand Down Expand Up @@ -565,7 +569,8 @@ static int da9030_battery_remove(struct platform_device *dev)
da903x_unregister_notifier(charger->master, &charger->nb,
DA9030_EVENT_CHDET | DA9030_EVENT_VBATMON |
DA9030_EVENT_CHIOVER | DA9030_EVENT_TBAT);
cancel_delayed_work(&charger->work);
cancel_delayed_work_sync(&charger->work);
da9030_set_charge(charger, 0);
power_supply_unregister(&charger->psy);

kfree(charger);
Expand Down
42 changes: 33 additions & 9 deletions drivers/power/ds2760_battery.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ static unsigned int cache_time = 1000;
module_param(cache_time, uint, 0644);
MODULE_PARM_DESC(cache_time, "cache time in milliseconds");

static unsigned int pmod_enabled;
module_param(pmod_enabled, bool, 0644);
MODULE_PARM_DESC(pmod_enabled, "PMOD enable bit");

/* Some batteries have their rated capacity stored a N * 10 mAh, while
* others use an index into this table. */
static int rated_capacities[] = {
Expand Down Expand Up @@ -259,6 +263,17 @@ static void ds2760_battery_update_status(struct ds2760_device_info *di)
power_supply_changed(&di->bat);
}

static void ds2760_battery_write_status(struct ds2760_device_info *di,
char status)
{
if (status == di->raw[DS2760_STATUS_REG])
return;

w1_ds2760_write(di->w1_dev, &status, DS2760_STATUS_WRITE_REG, 1);
w1_ds2760_store_eeprom(di->w1_dev, DS2760_EEPROM_BLOCK1);
w1_ds2760_recall_eeprom(di->w1_dev, DS2760_EEPROM_BLOCK1);
}

static void ds2760_battery_work(struct work_struct *work)
{
struct ds2760_device_info *di = container_of(work,
Expand Down Expand Up @@ -342,9 +357,9 @@ static enum power_supply_property ds2760_battery_props[] = {

static int ds2760_battery_probe(struct platform_device *pdev)
{
char status;
int retval = 0;
struct ds2760_device_info *di;
struct ds2760_platform_data *pdata;

di = kzalloc(sizeof(*di), GFP_KERNEL);
if (!di) {
Expand All @@ -354,14 +369,13 @@ static int ds2760_battery_probe(struct platform_device *pdev)

platform_set_drvdata(pdev, di);

pdata = pdev->dev.platform_data;
di->dev = &pdev->dev;
di->w1_dev = pdev->dev.parent;
di->bat.name = dev_name(&pdev->dev);
di->bat.type = POWER_SUPPLY_TYPE_BATTERY;
di->bat.properties = ds2760_battery_props;
di->bat.num_properties = ARRAY_SIZE(ds2760_battery_props);
di->bat.get_property = ds2760_battery_get_property;
di->dev = &pdev->dev;
di->w1_dev = pdev->dev.parent;
di->bat.name = dev_name(&pdev->dev);
di->bat.type = POWER_SUPPLY_TYPE_BATTERY;
di->bat.properties = ds2760_battery_props;
di->bat.num_properties = ARRAY_SIZE(ds2760_battery_props);
di->bat.get_property = ds2760_battery_get_property;
di->bat.external_power_changed =
ds2760_battery_external_power_changed;

Expand All @@ -373,6 +387,16 @@ static int ds2760_battery_probe(struct platform_device *pdev)
goto batt_failed;
}

/* enable sleep mode feature */
ds2760_battery_read_status(di);
status = di->raw[DS2760_STATUS_REG];
if (pmod_enabled)
status |= DS2760_STATUS_PMOD;
else
status &= ~DS2760_STATUS_PMOD;

ds2760_battery_write_status(di, status);

INIT_DELAYED_WORK(&di->monitor_work, ds2760_battery_work);
di->monitor_wqueue = create_singlethread_workqueue(dev_name(&pdev->dev));
if (!di->monitor_wqueue) {
Expand Down
Loading

0 comments on commit f27884a

Please sign in to comment.