Merge git://git.infradead.org/battery-2.6
* git://git.infradead.org/battery-2.6: gpio-charger: Fix checking return value of request_any_context_irq power_supply: MAX17042: Support additional properties max8903_charger: Allow platform data to be __initdata power_supply: Add charger driver for MAX8998/LP3974 power_supply: Add charger driver for MAX8997/8966 max17042_battery: Remove obsolete cleanup for clientdata twl4030_charger: Fix warnings wm831x_power: Support multiple instances wm831x_backup: Support multiple instances apm_power: Fix style error in macros s3c_adc_battery: Fix annotation for s3c_adc_battery_probe() bq20z75: Enable detection after registering bq20z75: Add support for external notification
This commit is contained in:
commit
f0d15c96d4
@ -39,6 +39,8 @@ static struct mfd_cell max8998_devs[] = {
|
||||
.name = "max8998-pmic",
|
||||
}, {
|
||||
.name = "max8998-rtc",
|
||||
}, {
|
||||
.name = "max8998-battery",
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -235,4 +235,18 @@ config CHARGER_GPIO
|
||||
This driver can be build as a module. If so, the module will be
|
||||
called gpio-charger.
|
||||
|
||||
config CHARGER_MAX8997
|
||||
tristate "Maxim MAX8997/MAX8966 PMIC battery charger driver"
|
||||
depends on MFD_MAX8997 && REGULATOR_MAX8997
|
||||
help
|
||||
Say Y to enable support for the battery charger control sysfs and
|
||||
platform data of MAX8997/LP3974 PMICs.
|
||||
|
||||
config CHARGER_MAX8998
|
||||
tristate "Maxim MAX8998/LP3974 PMIC battery charger driver"
|
||||
depends on MFD_MAX8998 && REGULATOR_MAX8998
|
||||
help
|
||||
Say Y to enable support for the battery charger control sysfs and
|
||||
platform data of MAX8998/LP3974 PMICs.
|
||||
|
||||
endif # POWER_SUPPLY
|
||||
|
@ -36,3 +36,5 @@ obj-$(CONFIG_CHARGER_ISP1704) += isp1704_charger.o
|
||||
obj-$(CONFIG_CHARGER_MAX8903) += max8903_charger.o
|
||||
obj-$(CONFIG_CHARGER_TWL4030) += twl4030_charger.o
|
||||
obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o
|
||||
obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o
|
||||
obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o
|
||||
|
@ -14,11 +14,11 @@
|
||||
#include <linux/apm-emulation.h>
|
||||
|
||||
|
||||
#define PSY_PROP(psy, prop, val) psy->get_property(psy, \
|
||||
POWER_SUPPLY_PROP_##prop, val)
|
||||
#define PSY_PROP(psy, prop, val) (psy->get_property(psy, \
|
||||
POWER_SUPPLY_PROP_##prop, val))
|
||||
|
||||
#define _MPSY_PROP(prop, val) main_battery->get_property(main_battery, \
|
||||
prop, val)
|
||||
#define _MPSY_PROP(prop, val) (main_battery->get_property(main_battery, \
|
||||
prop, val))
|
||||
|
||||
#define MPSY_PROP(prop, val) _MPSY_PROP(POWER_SUPPLY_PROP_##prop, val)
|
||||
|
||||
|
@ -152,6 +152,10 @@ struct bq20z75_info {
|
||||
bool gpio_detect;
|
||||
bool enable_detection;
|
||||
int irq;
|
||||
int last_state;
|
||||
int poll_time;
|
||||
struct delayed_work work;
|
||||
int ignore_changes;
|
||||
};
|
||||
|
||||
static int bq20z75_read_word_data(struct i2c_client *client, u8 address)
|
||||
@ -279,6 +283,7 @@ static int bq20z75_get_battery_property(struct i2c_client *client,
|
||||
int reg_offset, enum power_supply_property psp,
|
||||
union power_supply_propval *val)
|
||||
{
|
||||
struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client);
|
||||
s32 ret;
|
||||
|
||||
ret = bq20z75_read_word_data(client,
|
||||
@ -293,15 +298,24 @@ static int bq20z75_get_battery_property(struct i2c_client *client,
|
||||
if (ret >= bq20z75_data[reg_offset].min_value &&
|
||||
ret <= bq20z75_data[reg_offset].max_value) {
|
||||
val->intval = ret;
|
||||
if (psp == POWER_SUPPLY_PROP_STATUS) {
|
||||
if (ret & BATTERY_FULL_CHARGED)
|
||||
val->intval = POWER_SUPPLY_STATUS_FULL;
|
||||
else if (ret & BATTERY_FULL_DISCHARGED)
|
||||
val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
|
||||
else if (ret & BATTERY_DISCHARGING)
|
||||
val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
|
||||
else
|
||||
val->intval = POWER_SUPPLY_STATUS_CHARGING;
|
||||
if (psp != POWER_SUPPLY_PROP_STATUS)
|
||||
return 0;
|
||||
|
||||
if (ret & BATTERY_FULL_CHARGED)
|
||||
val->intval = POWER_SUPPLY_STATUS_FULL;
|
||||
else if (ret & BATTERY_FULL_DISCHARGED)
|
||||
val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
|
||||
else if (ret & BATTERY_DISCHARGING)
|
||||
val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
|
||||
else
|
||||
val->intval = POWER_SUPPLY_STATUS_CHARGING;
|
||||
|
||||
if (bq20z75_device->poll_time == 0)
|
||||
bq20z75_device->last_state = val->intval;
|
||||
else if (bq20z75_device->last_state != val->intval) {
|
||||
cancel_delayed_work_sync(&bq20z75_device->work);
|
||||
power_supply_changed(&bq20z75_device->power_supply);
|
||||
bq20z75_device->poll_time = 0;
|
||||
}
|
||||
} else {
|
||||
if (psp == POWER_SUPPLY_PROP_STATUS)
|
||||
@ -545,6 +559,60 @@ static irqreturn_t bq20z75_irq(int irq, void *devid)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void bq20z75_external_power_changed(struct power_supply *psy)
|
||||
{
|
||||
struct bq20z75_info *bq20z75_device;
|
||||
|
||||
bq20z75_device = container_of(psy, struct bq20z75_info, power_supply);
|
||||
|
||||
if (bq20z75_device->ignore_changes > 0) {
|
||||
bq20z75_device->ignore_changes--;
|
||||
return;
|
||||
}
|
||||
|
||||
/* cancel outstanding work */
|
||||
cancel_delayed_work_sync(&bq20z75_device->work);
|
||||
|
||||
schedule_delayed_work(&bq20z75_device->work, HZ);
|
||||
bq20z75_device->poll_time = bq20z75_device->pdata->poll_retry_count;
|
||||
}
|
||||
|
||||
static void bq20z75_delayed_work(struct work_struct *work)
|
||||
{
|
||||
struct bq20z75_info *bq20z75_device;
|
||||
s32 ret;
|
||||
|
||||
bq20z75_device = container_of(work, struct bq20z75_info, work.work);
|
||||
|
||||
ret = bq20z75_read_word_data(bq20z75_device->client,
|
||||
bq20z75_data[REG_STATUS].addr);
|
||||
/* if the read failed, give up on this work */
|
||||
if (ret < 0) {
|
||||
bq20z75_device->poll_time = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ret & BATTERY_FULL_CHARGED)
|
||||
ret = POWER_SUPPLY_STATUS_FULL;
|
||||
else if (ret & BATTERY_FULL_DISCHARGED)
|
||||
ret = POWER_SUPPLY_STATUS_NOT_CHARGING;
|
||||
else if (ret & BATTERY_DISCHARGING)
|
||||
ret = POWER_SUPPLY_STATUS_DISCHARGING;
|
||||
else
|
||||
ret = POWER_SUPPLY_STATUS_CHARGING;
|
||||
|
||||
if (bq20z75_device->last_state != ret) {
|
||||
bq20z75_device->poll_time = 0;
|
||||
power_supply_changed(&bq20z75_device->power_supply);
|
||||
return;
|
||||
}
|
||||
if (bq20z75_device->poll_time > 0) {
|
||||
schedule_delayed_work(&bq20z75_device->work, HZ);
|
||||
bq20z75_device->poll_time--;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static int __devinit bq20z75_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
@ -566,6 +634,13 @@ static int __devinit bq20z75_probe(struct i2c_client *client,
|
||||
bq20z75_device->power_supply.num_properties =
|
||||
ARRAY_SIZE(bq20z75_properties);
|
||||
bq20z75_device->power_supply.get_property = bq20z75_get_property;
|
||||
/* ignore first notification of external change, it is generated
|
||||
* from the power_supply_register call back
|
||||
*/
|
||||
bq20z75_device->ignore_changes = 1;
|
||||
bq20z75_device->last_state = POWER_SUPPLY_STATUS_UNKNOWN;
|
||||
bq20z75_device->power_supply.external_power_changed =
|
||||
bq20z75_external_power_changed;
|
||||
|
||||
if (pdata) {
|
||||
bq20z75_device->gpio_detect =
|
||||
@ -625,6 +700,10 @@ skip_gpio:
|
||||
dev_info(&client->dev,
|
||||
"%s: battery gas gauge device registered\n", client->name);
|
||||
|
||||
INIT_DELAYED_WORK(&bq20z75_device->work, bq20z75_delayed_work);
|
||||
|
||||
bq20z75_device->enable_detection = true;
|
||||
|
||||
return 0;
|
||||
|
||||
exit_psupply:
|
||||
@ -648,6 +727,9 @@ static int __devexit bq20z75_remove(struct i2c_client *client)
|
||||
gpio_free(bq20z75_device->pdata->battery_detect);
|
||||
|
||||
power_supply_unregister(&bq20z75_device->power_supply);
|
||||
|
||||
cancel_delayed_work_sync(&bq20z75_device->work);
|
||||
|
||||
kfree(bq20z75_device);
|
||||
bq20z75_device = NULL;
|
||||
|
||||
@ -661,6 +743,9 @@ static int bq20z75_suspend(struct i2c_client *client,
|
||||
struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client);
|
||||
s32 ret;
|
||||
|
||||
if (bq20z75_device->poll_time > 0)
|
||||
cancel_delayed_work_sync(&bq20z75_device->work);
|
||||
|
||||
/* write to manufacturer access with sleep command */
|
||||
ret = bq20z75_write_word_data(client,
|
||||
bq20z75_data[REG_MANUFACTURER_DATA].addr,
|
||||
|
@ -127,7 +127,7 @@ static int __devinit gpio_charger_probe(struct platform_device *pdev)
|
||||
ret = request_any_context_irq(irq, gpio_charger_irq,
|
||||
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
|
||||
dev_name(&pdev->dev), charger);
|
||||
if (ret)
|
||||
if (ret < 0)
|
||||
dev_warn(&pdev->dev, "Failed to request irq: %d\n", ret);
|
||||
else
|
||||
gpio_charger->irq = irq;
|
||||
|
@ -29,74 +29,6 @@
|
||||
#include <linux/power_supply.h>
|
||||
#include <linux/power/max17042_battery.h>
|
||||
|
||||
enum max17042_register {
|
||||
MAX17042_STATUS = 0x00,
|
||||
MAX17042_VALRT_Th = 0x01,
|
||||
MAX17042_TALRT_Th = 0x02,
|
||||
MAX17042_SALRT_Th = 0x03,
|
||||
MAX17042_AtRate = 0x04,
|
||||
MAX17042_RepCap = 0x05,
|
||||
MAX17042_RepSOC = 0x06,
|
||||
MAX17042_Age = 0x07,
|
||||
MAX17042_TEMP = 0x08,
|
||||
MAX17042_VCELL = 0x09,
|
||||
MAX17042_Current = 0x0A,
|
||||
MAX17042_AvgCurrent = 0x0B,
|
||||
MAX17042_Qresidual = 0x0C,
|
||||
MAX17042_SOC = 0x0D,
|
||||
MAX17042_AvSOC = 0x0E,
|
||||
MAX17042_RemCap = 0x0F,
|
||||
MAX17402_FullCAP = 0x10,
|
||||
MAX17042_TTE = 0x11,
|
||||
MAX17042_V_empty = 0x12,
|
||||
|
||||
MAX17042_RSLOW = 0x14,
|
||||
|
||||
MAX17042_AvgTA = 0x16,
|
||||
MAX17042_Cycles = 0x17,
|
||||
MAX17042_DesignCap = 0x18,
|
||||
MAX17042_AvgVCELL = 0x19,
|
||||
MAX17042_MinMaxTemp = 0x1A,
|
||||
MAX17042_MinMaxVolt = 0x1B,
|
||||
MAX17042_MinMaxCurr = 0x1C,
|
||||
MAX17042_CONFIG = 0x1D,
|
||||
MAX17042_ICHGTerm = 0x1E,
|
||||
MAX17042_AvCap = 0x1F,
|
||||
MAX17042_ManName = 0x20,
|
||||
MAX17042_DevName = 0x21,
|
||||
MAX17042_DevChem = 0x22,
|
||||
|
||||
MAX17042_TempNom = 0x24,
|
||||
MAX17042_TempCold = 0x25,
|
||||
MAX17042_TempHot = 0x26,
|
||||
MAX17042_AIN = 0x27,
|
||||
MAX17042_LearnCFG = 0x28,
|
||||
MAX17042_SHFTCFG = 0x29,
|
||||
MAX17042_RelaxCFG = 0x2A,
|
||||
MAX17042_MiscCFG = 0x2B,
|
||||
MAX17042_TGAIN = 0x2C,
|
||||
MAx17042_TOFF = 0x2D,
|
||||
MAX17042_CGAIN = 0x2E,
|
||||
MAX17042_COFF = 0x2F,
|
||||
|
||||
MAX17042_Q_empty = 0x33,
|
||||
MAX17042_T_empty = 0x34,
|
||||
|
||||
MAX17042_RCOMP0 = 0x38,
|
||||
MAX17042_TempCo = 0x39,
|
||||
MAX17042_Rx = 0x3A,
|
||||
MAX17042_T_empty0 = 0x3B,
|
||||
MAX17042_TaskPeriod = 0x3C,
|
||||
MAX17042_FSTAT = 0x3D,
|
||||
|
||||
MAX17042_SHDNTIMER = 0x3F,
|
||||
|
||||
MAX17042_VFRemCap = 0x4A,
|
||||
|
||||
MAX17042_QH = 0x4D,
|
||||
MAX17042_QL = 0x4E,
|
||||
};
|
||||
|
||||
struct max17042_chip {
|
||||
struct i2c_client *client;
|
||||
struct power_supply battery;
|
||||
@ -123,10 +55,27 @@ static int max17042_read_reg(struct i2c_client *client, u8 reg)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void max17042_set_reg(struct i2c_client *client,
|
||||
struct max17042_reg_data *data, int size)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
max17042_write_reg(client, data[i].addr, data[i].data);
|
||||
}
|
||||
|
||||
static enum power_supply_property max17042_battery_props[] = {
|
||||
POWER_SUPPLY_PROP_PRESENT,
|
||||
POWER_SUPPLY_PROP_CYCLE_COUNT,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_MAX,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_NOW,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_AVG,
|
||||
POWER_SUPPLY_PROP_CAPACITY,
|
||||
POWER_SUPPLY_PROP_CHARGE_FULL,
|
||||
POWER_SUPPLY_PROP_TEMP,
|
||||
POWER_SUPPLY_PROP_CURRENT_NOW,
|
||||
POWER_SUPPLY_PROP_CURRENT_AVG,
|
||||
};
|
||||
|
||||
static int max17042_get_property(struct power_supply *psy,
|
||||
@ -137,6 +86,30 @@ static int max17042_get_property(struct power_supply *psy,
|
||||
struct max17042_chip, battery);
|
||||
|
||||
switch (psp) {
|
||||
case POWER_SUPPLY_PROP_PRESENT:
|
||||
val->intval = max17042_read_reg(chip->client,
|
||||
MAX17042_STATUS);
|
||||
if (val->intval & MAX17042_STATUS_BattAbsent)
|
||||
val->intval = 0;
|
||||
else
|
||||
val->intval = 1;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_CYCLE_COUNT:
|
||||
val->intval = max17042_read_reg(chip->client,
|
||||
MAX17042_Cycles);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_VOLTAGE_MAX:
|
||||
val->intval = max17042_read_reg(chip->client,
|
||||
MAX17042_MinMaxVolt);
|
||||
val->intval >>= 8;
|
||||
val->intval *= 20000; /* Units of LSB = 20mV */
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
|
||||
val->intval = max17042_read_reg(chip->client,
|
||||
MAX17042_V_empty);
|
||||
val->intval >>= 7;
|
||||
val->intval *= 10000; /* Units of LSB = 10mV */
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
|
||||
val->intval = max17042_read_reg(chip->client,
|
||||
MAX17042_VCELL) * 83; /* 1000 / 12 = 83 */
|
||||
@ -149,6 +122,57 @@ static int max17042_get_property(struct power_supply *psy,
|
||||
val->intval = max17042_read_reg(chip->client,
|
||||
MAX17042_SOC) / 256;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_CHARGE_FULL:
|
||||
val->intval = max17042_read_reg(chip->client,
|
||||
MAX17042_RepSOC);
|
||||
if ((val->intval / 256) >= MAX17042_BATTERY_FULL)
|
||||
val->intval = 1;
|
||||
else if (val->intval >= 0)
|
||||
val->intval = 0;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_TEMP:
|
||||
val->intval = max17042_read_reg(chip->client,
|
||||
MAX17042_TEMP);
|
||||
/* The value is signed. */
|
||||
if (val->intval & 0x8000) {
|
||||
val->intval = (0x7fff & ~val->intval) + 1;
|
||||
val->intval *= -1;
|
||||
}
|
||||
/* The value is converted into deci-centigrade scale */
|
||||
/* Units of LSB = 1 / 256 degree Celsius */
|
||||
val->intval = val->intval * 10 / 256;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_CURRENT_NOW:
|
||||
if (chip->pdata->enable_current_sense) {
|
||||
val->intval = max17042_read_reg(chip->client,
|
||||
MAX17042_Current);
|
||||
if (val->intval & 0x8000) {
|
||||
/* Negative */
|
||||
val->intval = ~val->intval & 0x7fff;
|
||||
val->intval++;
|
||||
val->intval *= -1;
|
||||
}
|
||||
val->intval >>= 4;
|
||||
val->intval *= 1000000 * 25 / chip->pdata->r_sns;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_CURRENT_AVG:
|
||||
if (chip->pdata->enable_current_sense) {
|
||||
val->intval = max17042_read_reg(chip->client,
|
||||
MAX17042_AvgCurrent);
|
||||
if (val->intval & 0x8000) {
|
||||
/* Negative */
|
||||
val->intval = ~val->intval & 0x7fff;
|
||||
val->intval++;
|
||||
val->intval *= -1;
|
||||
}
|
||||
val->intval *= 1562500 / chip->pdata->r_sns;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -180,18 +204,30 @@ static int __devinit max17042_probe(struct i2c_client *client,
|
||||
chip->battery.properties = max17042_battery_props;
|
||||
chip->battery.num_properties = ARRAY_SIZE(max17042_battery_props);
|
||||
|
||||
/* When current is not measured,
|
||||
* CURRENT_NOW and CURRENT_AVG properties should be invisible. */
|
||||
if (!chip->pdata->enable_current_sense)
|
||||
chip->battery.num_properties -= 2;
|
||||
|
||||
ret = power_supply_register(&client->dev, &chip->battery);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed: power supply register\n");
|
||||
i2c_set_clientdata(client, NULL);
|
||||
kfree(chip);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Initialize registers according to values from the platform data */
|
||||
if (chip->pdata->init_data)
|
||||
max17042_set_reg(client, chip->pdata->init_data,
|
||||
chip->pdata->num_init_data);
|
||||
|
||||
if (!chip->pdata->enable_current_sense) {
|
||||
max17042_write_reg(client, MAX17042_CGAIN, 0x0000);
|
||||
max17042_write_reg(client, MAX17042_MiscCFG, 0x0003);
|
||||
max17042_write_reg(client, MAX17042_LearnCFG, 0x0007);
|
||||
} else {
|
||||
if (chip->pdata->r_sns == 0)
|
||||
chip->pdata->r_sns = MAX17042_DEFAULT_SNS_RESISTOR;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -202,7 +238,6 @@ static int __devexit max17042_remove(struct i2c_client *client)
|
||||
struct max17042_chip *chip = i2c_get_clientdata(client);
|
||||
|
||||
power_supply_unregister(&chip->battery);
|
||||
i2c_set_clientdata(client, NULL);
|
||||
kfree(chip);
|
||||
return 0;
|
||||
}
|
||||
|
@ -28,7 +28,7 @@
|
||||
#include <linux/power/max8903_charger.h>
|
||||
|
||||
struct max8903_data {
|
||||
struct max8903_pdata *pdata;
|
||||
struct max8903_pdata pdata;
|
||||
struct device *dev;
|
||||
struct power_supply psy;
|
||||
bool fault;
|
||||
@ -52,8 +52,8 @@ static int max8903_get_property(struct power_supply *psy,
|
||||
switch (psp) {
|
||||
case POWER_SUPPLY_PROP_STATUS:
|
||||
val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
|
||||
if (data->pdata->chg) {
|
||||
if (gpio_get_value(data->pdata->chg) == 0)
|
||||
if (data->pdata.chg) {
|
||||
if (gpio_get_value(data->pdata.chg) == 0)
|
||||
val->intval = POWER_SUPPLY_STATUS_CHARGING;
|
||||
else if (data->usb_in || data->ta_in)
|
||||
val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
|
||||
@ -80,7 +80,7 @@ static int max8903_get_property(struct power_supply *psy,
|
||||
static irqreturn_t max8903_dcin(int irq, void *_data)
|
||||
{
|
||||
struct max8903_data *data = _data;
|
||||
struct max8903_pdata *pdata = data->pdata;
|
||||
struct max8903_pdata *pdata = &data->pdata;
|
||||
bool ta_in;
|
||||
enum power_supply_type old_type;
|
||||
|
||||
@ -121,7 +121,7 @@ static irqreturn_t max8903_dcin(int irq, void *_data)
|
||||
static irqreturn_t max8903_usbin(int irq, void *_data)
|
||||
{
|
||||
struct max8903_data *data = _data;
|
||||
struct max8903_pdata *pdata = data->pdata;
|
||||
struct max8903_pdata *pdata = &data->pdata;
|
||||
bool usb_in;
|
||||
enum power_supply_type old_type;
|
||||
|
||||
@ -160,7 +160,7 @@ static irqreturn_t max8903_usbin(int irq, void *_data)
|
||||
static irqreturn_t max8903_fault(int irq, void *_data)
|
||||
{
|
||||
struct max8903_data *data = _data;
|
||||
struct max8903_pdata *pdata = data->pdata;
|
||||
struct max8903_pdata *pdata = &data->pdata;
|
||||
bool fault;
|
||||
|
||||
fault = gpio_get_value(pdata->flt) ? false : true;
|
||||
@ -193,7 +193,7 @@ static __devinit int max8903_probe(struct platform_device *pdev)
|
||||
dev_err(dev, "Cannot allocate memory.\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
data->pdata = pdata;
|
||||
memcpy(&data->pdata, pdata, sizeof(struct max8903_pdata));
|
||||
data->dev = dev;
|
||||
platform_set_drvdata(pdev, data);
|
||||
|
||||
@ -349,7 +349,7 @@ static __devexit int max8903_remove(struct platform_device *pdev)
|
||||
struct max8903_data *data = platform_get_drvdata(pdev);
|
||||
|
||||
if (data) {
|
||||
struct max8903_pdata *pdata = data->pdata;
|
||||
struct max8903_pdata *pdata = &data->pdata;
|
||||
|
||||
if (pdata->flt)
|
||||
free_irq(gpio_to_irq(pdata->flt), data);
|
||||
|
206
drivers/power/max8997_charger.c
Normal file
206
drivers/power/max8997_charger.c
Normal file
@ -0,0 +1,206 @@
|
||||
/*
|
||||
* max8997_charger.c - Power supply consumer driver for the Maxim 8997/8966
|
||||
*
|
||||
* Copyright (C) 2011 Samsung Electronics
|
||||
* MyungJoo Ham <myungjoo.ham@samsung.com>
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/power_supply.h>
|
||||
#include <linux/mfd/max8997.h>
|
||||
#include <linux/mfd/max8997-private.h>
|
||||
|
||||
struct charger_data {
|
||||
struct device *dev;
|
||||
struct max8997_dev *iodev;
|
||||
struct power_supply battery;
|
||||
};
|
||||
|
||||
static enum power_supply_property max8997_battery_props[] = {
|
||||
POWER_SUPPLY_PROP_STATUS, /* "FULL" or "NOT FULL" only. */
|
||||
POWER_SUPPLY_PROP_PRESENT, /* the presence of battery */
|
||||
POWER_SUPPLY_PROP_ONLINE, /* charger is active or not */
|
||||
};
|
||||
|
||||
/* Note that the charger control is done by a current regulator "CHARGER" */
|
||||
static int max8997_battery_get_property(struct power_supply *psy,
|
||||
enum power_supply_property psp,
|
||||
union power_supply_propval *val)
|
||||
{
|
||||
struct charger_data *charger = container_of(psy,
|
||||
struct charger_data, battery);
|
||||
struct i2c_client *i2c = charger->iodev->i2c;
|
||||
int ret;
|
||||
u8 reg;
|
||||
|
||||
switch (psp) {
|
||||
case POWER_SUPPLY_PROP_STATUS:
|
||||
val->intval = 0;
|
||||
ret = max8997_read_reg(i2c, MAX8997_REG_STATUS4, ®);
|
||||
if (ret)
|
||||
return ret;
|
||||
if ((reg & (1 << 0)) == 0x1)
|
||||
val->intval = POWER_SUPPLY_STATUS_FULL;
|
||||
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_PRESENT:
|
||||
val->intval = 0;
|
||||
ret = max8997_read_reg(i2c, MAX8997_REG_STATUS4, ®);
|
||||
if (ret)
|
||||
return ret;
|
||||
if ((reg & (1 << 2)) == 0x0)
|
||||
val->intval = 1;
|
||||
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_ONLINE:
|
||||
val->intval = 0;
|
||||
ret = max8997_read_reg(i2c, MAX8997_REG_STATUS4, ®);
|
||||
if (ret)
|
||||
return ret;
|
||||
/* DCINOK */
|
||||
if (reg & (1 << 1))
|
||||
val->intval = 1;
|
||||
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __devinit int max8997_battery_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret = 0;
|
||||
struct charger_data *charger;
|
||||
struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent);
|
||||
struct max8997_platform_data *pdata = dev_get_platdata(iodev->dev);
|
||||
|
||||
if (!pdata)
|
||||
return -EINVAL;
|
||||
|
||||
if (pdata->eoc_mA) {
|
||||
u8 val = (pdata->eoc_mA - 50) / 10;
|
||||
if (val < 0)
|
||||
val = 0;
|
||||
if (val > 0xf)
|
||||
val = 0xf;
|
||||
|
||||
ret = max8997_update_reg(iodev->i2c,
|
||||
MAX8997_REG_MBCCTRL5, val, 0xf);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Cannot use i2c bus.\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
switch (pdata->timeout) {
|
||||
case 5:
|
||||
ret = max8997_update_reg(iodev->i2c, MAX8997_REG_MBCCTRL1,
|
||||
0x2 << 4, 0x7 << 4);
|
||||
break;
|
||||
case 6:
|
||||
ret = max8997_update_reg(iodev->i2c, MAX8997_REG_MBCCTRL1,
|
||||
0x3 << 4, 0x7 << 4);
|
||||
break;
|
||||
case 7:
|
||||
ret = max8997_update_reg(iodev->i2c, MAX8997_REG_MBCCTRL1,
|
||||
0x4 << 4, 0x7 << 4);
|
||||
break;
|
||||
case 0:
|
||||
ret = max8997_update_reg(iodev->i2c, MAX8997_REG_MBCCTRL1,
|
||||
0x7 << 4, 0x7 << 4);
|
||||
break;
|
||||
default:
|
||||
dev_err(&pdev->dev, "incorrect timeout value (%d)\n",
|
||||
pdata->timeout);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Cannot use i2c bus.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
charger = kzalloc(sizeof(struct charger_data), GFP_KERNEL);
|
||||
if (charger == NULL) {
|
||||
dev_err(&pdev->dev, "Cannot allocate memory.\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, charger);
|
||||
|
||||
charger->battery.name = "max8997_pmic";
|
||||
charger->battery.type = POWER_SUPPLY_TYPE_BATTERY;
|
||||
charger->battery.get_property = max8997_battery_get_property;
|
||||
charger->battery.properties = max8997_battery_props;
|
||||
charger->battery.num_properties = ARRAY_SIZE(max8997_battery_props);
|
||||
|
||||
charger->dev = &pdev->dev;
|
||||
charger->iodev = iodev;
|
||||
|
||||
ret = power_supply_register(&pdev->dev, &charger->battery);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed: power supply register\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err:
|
||||
kfree(charger);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __devexit max8997_battery_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct charger_data *charger = platform_get_drvdata(pdev);
|
||||
|
||||
power_supply_unregister(&charger->battery);
|
||||
kfree(charger);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct platform_device_id max8997_battery_id[] = {
|
||||
{ "max8997-battery", 0 },
|
||||
};
|
||||
|
||||
static struct platform_driver max8997_battery_driver = {
|
||||
.driver = {
|
||||
.name = "max8997-battery",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = max8997_battery_probe,
|
||||
.remove = __devexit_p(max8997_battery_remove),
|
||||
.id_table = max8997_battery_id,
|
||||
};
|
||||
|
||||
static int __init max8997_battery_init(void)
|
||||
{
|
||||
return platform_driver_register(&max8997_battery_driver);
|
||||
}
|
||||
subsys_initcall(max8997_battery_init);
|
||||
|
||||
static void __exit max8997_battery_cleanup(void)
|
||||
{
|
||||
platform_driver_unregister(&max8997_battery_driver);
|
||||
}
|
||||
module_exit(max8997_battery_cleanup);
|
||||
|
||||
MODULE_DESCRIPTION("MAXIM 8997/8966 battery control driver");
|
||||
MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
|
||||
MODULE_LICENSE("GPL");
|
218
drivers/power/max8998_charger.c
Normal file
218
drivers/power/max8998_charger.c
Normal file
@ -0,0 +1,218 @@
|
||||
/*
|
||||
* max8998_charger.c - Power supply consumer driver for the Maxim 8998/LP3974
|
||||
*
|
||||
* Copyright (C) 2009-2010 Samsung Electronics
|
||||
* MyungJoo Ham <myungjoo.ham@samsung.com>
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/power_supply.h>
|
||||
#include <linux/mfd/max8998.h>
|
||||
#include <linux/mfd/max8998-private.h>
|
||||
|
||||
struct max8998_battery_data {
|
||||
struct device *dev;
|
||||
struct max8998_dev *iodev;
|
||||
struct power_supply battery;
|
||||
};
|
||||
|
||||
static enum power_supply_property max8998_battery_props[] = {
|
||||
POWER_SUPPLY_PROP_PRESENT, /* the presence of battery */
|
||||
POWER_SUPPLY_PROP_ONLINE, /* charger is active or not */
|
||||
};
|
||||
|
||||
/* Note that the charger control is done by a current regulator "CHARGER" */
|
||||
static int max8998_battery_get_property(struct power_supply *psy,
|
||||
enum power_supply_property psp,
|
||||
union power_supply_propval *val)
|
||||
{
|
||||
struct max8998_battery_data *max8998 = container_of(psy,
|
||||
struct max8998_battery_data, battery);
|
||||
struct i2c_client *i2c = max8998->iodev->i2c;
|
||||
int ret;
|
||||
u8 reg;
|
||||
|
||||
switch (psp) {
|
||||
case POWER_SUPPLY_PROP_PRESENT:
|
||||
ret = max8998_read_reg(i2c, MAX8998_REG_STATUS2, ®);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (reg & (1 << 4))
|
||||
val->intval = 0;
|
||||
else
|
||||
val->intval = 1;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_ONLINE:
|
||||
ret = max8998_read_reg(i2c, MAX8998_REG_STATUS2, ®);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (reg & (1 << 3))
|
||||
val->intval = 0;
|
||||
else
|
||||
val->intval = 1;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __devinit int max8998_battery_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct max8998_dev *iodev = dev_get_drvdata(pdev->dev.parent);
|
||||
struct max8998_platform_data *pdata = dev_get_platdata(iodev->dev);
|
||||
struct max8998_battery_data *max8998;
|
||||
struct i2c_client *i2c;
|
||||
int ret = 0;
|
||||
|
||||
if (!pdata) {
|
||||
dev_err(pdev->dev.parent, "No platform init data supplied\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
max8998 = kzalloc(sizeof(struct max8998_battery_data), GFP_KERNEL);
|
||||
if (!max8998)
|
||||
return -ENOMEM;
|
||||
|
||||
max8998->dev = &pdev->dev;
|
||||
max8998->iodev = iodev;
|
||||
platform_set_drvdata(pdev, max8998);
|
||||
i2c = max8998->iodev->i2c;
|
||||
|
||||
/* Setup "End of Charge" */
|
||||
/* If EOC value equals 0,
|
||||
* remain value set from bootloader or default value */
|
||||
if (pdata->eoc >= 10 && pdata->eoc <= 45) {
|
||||
max8998_update_reg(i2c, MAX8998_REG_CHGR1,
|
||||
(pdata->eoc / 5 - 2) << 5, 0x7 << 5);
|
||||
} else if (pdata->eoc == 0) {
|
||||
dev_dbg(max8998->dev,
|
||||
"EOC value not set: leave it unchanged.\n");
|
||||
} else {
|
||||
dev_err(max8998->dev, "Invalid EOC value\n");
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Setup Charge Restart Level */
|
||||
switch (pdata->restart) {
|
||||
case 100:
|
||||
max8998_update_reg(i2c, MAX8998_REG_CHGR1, 0x1 << 3, 0x3 << 3);
|
||||
break;
|
||||
case 150:
|
||||
max8998_update_reg(i2c, MAX8998_REG_CHGR1, 0x0 << 3, 0x3 << 3);
|
||||
break;
|
||||
case 200:
|
||||
max8998_update_reg(i2c, MAX8998_REG_CHGR1, 0x2 << 3, 0x3 << 3);
|
||||
break;
|
||||
case -1:
|
||||
max8998_update_reg(i2c, MAX8998_REG_CHGR1, 0x3 << 3, 0x3 << 3);
|
||||
break;
|
||||
case 0:
|
||||
dev_dbg(max8998->dev,
|
||||
"Restart Level not set: leave it unchanged.\n");
|
||||
break;
|
||||
default:
|
||||
dev_err(max8998->dev, "Invalid Restart Level\n");
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Setup Charge Full Timeout */
|
||||
switch (pdata->timeout) {
|
||||
case 5:
|
||||
max8998_update_reg(i2c, MAX8998_REG_CHGR2, 0x0 << 4, 0x3 << 4);
|
||||
break;
|
||||
case 6:
|
||||
max8998_update_reg(i2c, MAX8998_REG_CHGR2, 0x1 << 4, 0x3 << 4);
|
||||
break;
|
||||
case 7:
|
||||
max8998_update_reg(i2c, MAX8998_REG_CHGR2, 0x2 << 4, 0x3 << 4);
|
||||
break;
|
||||
case -1:
|
||||
max8998_update_reg(i2c, MAX8998_REG_CHGR2, 0x3 << 4, 0x3 << 4);
|
||||
break;
|
||||
case 0:
|
||||
dev_dbg(max8998->dev,
|
||||
"Full Timeout not set: leave it unchanged.\n");
|
||||
default:
|
||||
dev_err(max8998->dev, "Invalid Full Timeout value\n");
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
max8998->battery.name = "max8998_pmic";
|
||||
max8998->battery.type = POWER_SUPPLY_TYPE_BATTERY;
|
||||
max8998->battery.get_property = max8998_battery_get_property;
|
||||
max8998->battery.properties = max8998_battery_props;
|
||||
max8998->battery.num_properties = ARRAY_SIZE(max8998_battery_props);
|
||||
|
||||
ret = power_supply_register(max8998->dev, &max8998->battery);
|
||||
if (ret) {
|
||||
dev_err(max8998->dev, "failed: power supply register\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err:
|
||||
kfree(max8998);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __devexit max8998_battery_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct max8998_battery_data *max8998 = platform_get_drvdata(pdev);
|
||||
|
||||
power_supply_unregister(&max8998->battery);
|
||||
kfree(max8998);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct platform_device_id max8998_battery_id[] = {
|
||||
{ "max8998-battery", TYPE_MAX8998 },
|
||||
};
|
||||
|
||||
static struct platform_driver max8998_battery_driver = {
|
||||
.driver = {
|
||||
.name = "max8998-battery",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = max8998_battery_probe,
|
||||
.remove = __devexit_p(max8998_battery_remove),
|
||||
.id_table = max8998_battery_id,
|
||||
};
|
||||
|
||||
static int __init max8998_battery_init(void)
|
||||
{
|
||||
return platform_driver_register(&max8998_battery_driver);
|
||||
}
|
||||
module_init(max8998_battery_init);
|
||||
|
||||
static void __exit max8998_battery_cleanup(void)
|
||||
{
|
||||
platform_driver_unregister(&max8998_battery_driver);
|
||||
}
|
||||
module_exit(max8998_battery_cleanup);
|
||||
|
||||
MODULE_DESCRIPTION("MAXIM 8998 battery control driver");
|
||||
MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:max8998-battery");
|
@ -266,7 +266,7 @@ static irqreturn_t s3c_adc_bat_charged(int irq, void *dev_id)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int __init s3c_adc_bat_probe(struct platform_device *pdev)
|
||||
static int __devinit s3c_adc_bat_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct s3c_adc_client *client;
|
||||
struct s3c_adc_bat_pdata *pdata = pdev->dev.platform_data;
|
||||
|
@ -62,7 +62,7 @@
|
||||
#define TWL4030_MSTATEC_COMPLETE4 0x0e
|
||||
|
||||
static bool allow_usb;
|
||||
module_param(allow_usb, bool, 1);
|
||||
module_param(allow_usb, bool, 0644);
|
||||
MODULE_PARM_DESC(allow_usb, "Allow USB charge drawing default current");
|
||||
|
||||
struct twl4030_bci {
|
||||
@ -425,7 +425,7 @@ static int __init twl4030_bci_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct twl4030_bci *bci;
|
||||
int ret;
|
||||
int reg;
|
||||
u32 reg;
|
||||
|
||||
bci = kzalloc(sizeof(*bci), GFP_KERNEL);
|
||||
if (bci == NULL)
|
||||
@ -486,7 +486,7 @@ static int __init twl4030_bci_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
/* Enable interrupts now. */
|
||||
reg = ~(TWL4030_ICHGLOW | TWL4030_ICHGEOC | TWL4030_TBATOR2 |
|
||||
reg = ~(u32)(TWL4030_ICHGLOW | TWL4030_ICHGEOC | TWL4030_TBATOR2 |
|
||||
TWL4030_TBATOR1 | TWL4030_BATSTS);
|
||||
ret = twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, reg,
|
||||
TWL4030_INTERRUPTS_BCIIMR1A);
|
||||
@ -495,7 +495,7 @@ static int __init twl4030_bci_probe(struct platform_device *pdev)
|
||||
goto fail_unmask_interrupts;
|
||||
}
|
||||
|
||||
reg = ~(TWL4030_VBATOV | TWL4030_VBUSOV | TWL4030_ACCHGOV);
|
||||
reg = ~(u32)(TWL4030_VBATOV | TWL4030_VBUSOV | TWL4030_ACCHGOV);
|
||||
ret = twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, reg,
|
||||
TWL4030_INTERRUPTS_BCIIMR2A);
|
||||
if (ret < 0)
|
||||
@ -572,7 +572,7 @@ static void __exit twl4030_bci_exit(void)
|
||||
}
|
||||
module_exit(twl4030_bci_exit);
|
||||
|
||||
MODULE_AUTHOR("Gražydas Ignotas");
|
||||
MODULE_AUTHOR("Gražvydas Ignotas");
|
||||
MODULE_DESCRIPTION("TWL4030 Battery Charger Interface driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:twl4030_bci");
|
||||
|
@ -22,6 +22,7 @@
|
||||
struct wm831x_backup {
|
||||
struct wm831x *wm831x;
|
||||
struct power_supply backup;
|
||||
char name[20];
|
||||
};
|
||||
|
||||
static int wm831x_backup_read_voltage(struct wm831x *wm831x,
|
||||
@ -163,6 +164,7 @@ static enum power_supply_property wm831x_backup_props[] = {
|
||||
static __devinit int wm831x_backup_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
|
||||
struct wm831x_pdata *wm831x_pdata = wm831x->dev->platform_data;
|
||||
struct wm831x_backup *devdata;
|
||||
struct power_supply *backup;
|
||||
int ret;
|
||||
@ -182,7 +184,14 @@ static __devinit int wm831x_backup_probe(struct platform_device *pdev)
|
||||
*/
|
||||
wm831x_config_backup(wm831x);
|
||||
|
||||
backup->name = "wm831x-backup";
|
||||
if (wm831x_pdata && wm831x_pdata->wm831x_num)
|
||||
snprintf(devdata->name, sizeof(devdata->name),
|
||||
"wm831x-backup.%d", wm831x_pdata->wm831x_num);
|
||||
else
|
||||
snprintf(devdata->name, sizeof(devdata->name),
|
||||
"wm831x-backup");
|
||||
|
||||
backup->name = devdata->name;
|
||||
backup->type = POWER_SUPPLY_TYPE_BATTERY;
|
||||
backup->properties = wm831x_backup_props;
|
||||
backup->num_properties = ARRAY_SIZE(wm831x_backup_props);
|
||||
@ -203,6 +212,7 @@ static __devexit int wm831x_backup_remove(struct platform_device *pdev)
|
||||
struct wm831x_backup *devdata = platform_get_drvdata(pdev);
|
||||
|
||||
power_supply_unregister(&devdata->backup);
|
||||
kfree(devdata->backup.name);
|
||||
kfree(devdata);
|
||||
|
||||
return 0;
|
||||
|
@ -24,6 +24,9 @@ struct wm831x_power {
|
||||
struct power_supply wall;
|
||||
struct power_supply usb;
|
||||
struct power_supply battery;
|
||||
char wall_name[20];
|
||||
char usb_name[20];
|
||||
char battery_name[20];
|
||||
};
|
||||
|
||||
static int wm831x_power_check_online(struct wm831x *wm831x, int supply,
|
||||
@ -486,6 +489,7 @@ static irqreturn_t wm831x_pwr_src_irq(int irq, void *data)
|
||||
static __devinit int wm831x_power_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
|
||||
struct wm831x_pdata *wm831x_pdata = wm831x->dev->platform_data;
|
||||
struct wm831x_power *power;
|
||||
struct power_supply *usb;
|
||||
struct power_supply *battery;
|
||||
@ -503,12 +507,28 @@ static __devinit int wm831x_power_probe(struct platform_device *pdev)
|
||||
battery = &power->battery;
|
||||
wall = &power->wall;
|
||||
|
||||
if (wm831x_pdata && wm831x_pdata->wm831x_num) {
|
||||
snprintf(power->wall_name, sizeof(power->wall_name),
|
||||
"wm831x-wall.%d", wm831x_pdata->wm831x_num);
|
||||
snprintf(power->battery_name, sizeof(power->wall_name),
|
||||
"wm831x-battery.%d", wm831x_pdata->wm831x_num);
|
||||
snprintf(power->usb_name, sizeof(power->wall_name),
|
||||
"wm831x-usb.%d", wm831x_pdata->wm831x_num);
|
||||
} else {
|
||||
snprintf(power->wall_name, sizeof(power->wall_name),
|
||||
"wm831x-wall");
|
||||
snprintf(power->battery_name, sizeof(power->wall_name),
|
||||
"wm831x-battery");
|
||||
snprintf(power->usb_name, sizeof(power->wall_name),
|
||||
"wm831x-usb");
|
||||
}
|
||||
|
||||
/* We ignore configuration failures since we can still read back
|
||||
* the status without enabling the charger.
|
||||
*/
|
||||
wm831x_config_battery(wm831x);
|
||||
|
||||
wall->name = "wm831x-wall";
|
||||
wall->name = power->wall_name;
|
||||
wall->type = POWER_SUPPLY_TYPE_MAINS;
|
||||
wall->properties = wm831x_wall_props;
|
||||
wall->num_properties = ARRAY_SIZE(wm831x_wall_props);
|
||||
@ -517,7 +537,7 @@ static __devinit int wm831x_power_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
goto err_kmalloc;
|
||||
|
||||
battery->name = "wm831x-battery";
|
||||
battery->name = power->battery_name;
|
||||
battery->properties = wm831x_bat_props;
|
||||
battery->num_properties = ARRAY_SIZE(wm831x_bat_props);
|
||||
battery->get_property = wm831x_bat_get_prop;
|
||||
@ -526,7 +546,7 @@ static __devinit int wm831x_power_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
goto err_wall;
|
||||
|
||||
usb->name = "wm831x-usb",
|
||||
usb->name = power->usb_name,
|
||||
usb->type = POWER_SUPPLY_TYPE_USB;
|
||||
usb->properties = wm831x_usb_props;
|
||||
usb->num_properties = ARRAY_SIZE(wm831x_usb_props);
|
||||
|
@ -107,11 +107,16 @@ struct max8997_platform_data {
|
||||
unsigned int buck5_voltage[8];
|
||||
bool buck5_gpiodvs;
|
||||
|
||||
/* ---- Charger control ---- */
|
||||
/* eoc stands for 'end of charge' */
|
||||
int eoc_mA; /* 50 ~ 200mA by 10mA step */
|
||||
/* charge Full Timeout */
|
||||
int timeout; /* 0 (no timeout), 5, 6, 7 hours */
|
||||
|
||||
/* MUIC: Not implemented */
|
||||
/* HAPTIC: Not implemented */
|
||||
/* RTC: Not implemented */
|
||||
/* Flash: Not implemented */
|
||||
/* Charger control: Not implemented */
|
||||
};
|
||||
|
||||
#endif /* __LINUX_MFD_MAX8998_H */
|
||||
|
@ -87,6 +87,15 @@ struct max8998_regulator_data {
|
||||
* @wakeup: Allow to wake up from suspend
|
||||
* @rtc_delay: LP3974 RTC chip bug that requires delay after a register
|
||||
* write before reading it.
|
||||
* @eoc: End of Charge Level in percent: 10% ~ 45% by 5% step
|
||||
* If it equals 0, leave it unchanged.
|
||||
* Otherwise, it is a invalid value.
|
||||
* @restart: Restart Level in mV: 100, 150, 200, and -1 for disable.
|
||||
* If it equals 0, leave it unchanged.
|
||||
* Otherwise, it is a invalid value.
|
||||
* @timeout: Full Timeout in hours: 5, 6, 7, and -1 for disable.
|
||||
* If it equals 0, leave it unchanged.
|
||||
* Otherwise, leave it unchanged.
|
||||
*/
|
||||
struct max8998_platform_data {
|
||||
struct max8998_regulator_data *regulators;
|
||||
@ -107,6 +116,9 @@ struct max8998_platform_data {
|
||||
int buck2_default_idx;
|
||||
bool wakeup;
|
||||
bool rtc_delay;
|
||||
int eoc;
|
||||
int restart;
|
||||
int timeout;
|
||||
};
|
||||
|
||||
#endif /* __LINUX_MFD_MAX8998_H */
|
||||
|
@ -29,11 +29,14 @@
|
||||
* @battery_detect: GPIO which is used to detect battery presence
|
||||
* @battery_detect_present: gpio state when battery is present (0 / 1)
|
||||
* @i2c_retry_count: # of times to retry on i2c IO failure
|
||||
* @poll_retry_count: # of times to retry looking for new status after
|
||||
* external change notification
|
||||
*/
|
||||
struct bq20z75_platform_data {
|
||||
int battery_detect;
|
||||
int battery_detect_present;
|
||||
int i2c_retry_count;
|
||||
int poll_retry_count;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -23,8 +23,99 @@
|
||||
#ifndef __MAX17042_BATTERY_H_
|
||||
#define __MAX17042_BATTERY_H_
|
||||
|
||||
#define MAX17042_STATUS_BattAbsent (1 << 3)
|
||||
#define MAX17042_BATTERY_FULL (100)
|
||||
#define MAX17042_DEFAULT_SNS_RESISTOR (10000)
|
||||
|
||||
enum max17042_register {
|
||||
MAX17042_STATUS = 0x00,
|
||||
MAX17042_VALRT_Th = 0x01,
|
||||
MAX17042_TALRT_Th = 0x02,
|
||||
MAX17042_SALRT_Th = 0x03,
|
||||
MAX17042_AtRate = 0x04,
|
||||
MAX17042_RepCap = 0x05,
|
||||
MAX17042_RepSOC = 0x06,
|
||||
MAX17042_Age = 0x07,
|
||||
MAX17042_TEMP = 0x08,
|
||||
MAX17042_VCELL = 0x09,
|
||||
MAX17042_Current = 0x0A,
|
||||
MAX17042_AvgCurrent = 0x0B,
|
||||
MAX17042_Qresidual = 0x0C,
|
||||
MAX17042_SOC = 0x0D,
|
||||
MAX17042_AvSOC = 0x0E,
|
||||
MAX17042_RemCap = 0x0F,
|
||||
MAX17402_FullCAP = 0x10,
|
||||
MAX17042_TTE = 0x11,
|
||||
MAX17042_V_empty = 0x12,
|
||||
|
||||
MAX17042_RSLOW = 0x14,
|
||||
|
||||
MAX17042_AvgTA = 0x16,
|
||||
MAX17042_Cycles = 0x17,
|
||||
MAX17042_DesignCap = 0x18,
|
||||
MAX17042_AvgVCELL = 0x19,
|
||||
MAX17042_MinMaxTemp = 0x1A,
|
||||
MAX17042_MinMaxVolt = 0x1B,
|
||||
MAX17042_MinMaxCurr = 0x1C,
|
||||
MAX17042_CONFIG = 0x1D,
|
||||
MAX17042_ICHGTerm = 0x1E,
|
||||
MAX17042_AvCap = 0x1F,
|
||||
MAX17042_ManName = 0x20,
|
||||
MAX17042_DevName = 0x21,
|
||||
MAX17042_DevChem = 0x22,
|
||||
|
||||
MAX17042_TempNom = 0x24,
|
||||
MAX17042_TempCold = 0x25,
|
||||
MAX17042_TempHot = 0x26,
|
||||
MAX17042_AIN = 0x27,
|
||||
MAX17042_LearnCFG = 0x28,
|
||||
MAX17042_SHFTCFG = 0x29,
|
||||
MAX17042_RelaxCFG = 0x2A,
|
||||
MAX17042_MiscCFG = 0x2B,
|
||||
MAX17042_TGAIN = 0x2C,
|
||||
MAx17042_TOFF = 0x2D,
|
||||
MAX17042_CGAIN = 0x2E,
|
||||
MAX17042_COFF = 0x2F,
|
||||
|
||||
MAX17042_Q_empty = 0x33,
|
||||
MAX17042_T_empty = 0x34,
|
||||
|
||||
MAX17042_RCOMP0 = 0x38,
|
||||
MAX17042_TempCo = 0x39,
|
||||
MAX17042_Rx = 0x3A,
|
||||
MAX17042_T_empty0 = 0x3B,
|
||||
MAX17042_TaskPeriod = 0x3C,
|
||||
MAX17042_FSTAT = 0x3D,
|
||||
|
||||
MAX17042_SHDNTIMER = 0x3F,
|
||||
|
||||
MAX17042_VFRemCap = 0x4A,
|
||||
|
||||
MAX17042_QH = 0x4D,
|
||||
MAX17042_QL = 0x4E,
|
||||
};
|
||||
|
||||
/*
|
||||
* used for setting a register to a desired value
|
||||
* addr : address for a register
|
||||
* data : setting value for the register
|
||||
*/
|
||||
struct max17042_reg_data {
|
||||
u8 addr;
|
||||
u16 data;
|
||||
};
|
||||
|
||||
struct max17042_platform_data {
|
||||
struct max17042_reg_data *init_data;
|
||||
int num_init_data; /* Number of enties in init_data array */
|
||||
bool enable_current_sense;
|
||||
|
||||
/*
|
||||
* R_sns in micro-ohms.
|
||||
* default 10000 (if r_sns = 0) as it is the recommended value by
|
||||
* the datasheet although it can be changed by board designers.
|
||||
*/
|
||||
unsigned int r_sns;
|
||||
};
|
||||
|
||||
#endif /* __MAX17042_BATTERY_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user