Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 309693
b: refs/heads/master
c: 9a8422d
h: refs/heads/master
i:
  309691: 47b1082
v: v3
  • Loading branch information
Ramakrishna Pallala authored and Anton Vorontsov committed May 6, 2012
1 parent a7e2f5f commit 710ef32
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 14 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b1f092f6480e0a9d8d5f99d3363e022952d1af83
refs/heads/master: 9a8422d205ea142a27c2573e5ca3d2cc87d75260
5 changes: 3 additions & 2 deletions trunk/drivers/power/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -181,14 +181,15 @@ config BATTERY_MAX17040
to operate with a single lithium cell

config BATTERY_MAX17042
tristate "Maxim MAX17042/8997/8966 Fuel Gauge"
tristate "Maxim MAX17042/17047/17050/8997/8966 Fuel Gauge"
depends on I2C
help
MAX17042 is fuel-gauge systems for lithium-ion (Li+) batteries
in handheld and portable equipment. The MAX17042 is configured
to operate with a single lithium cell. MAX8997 and MAX8966 are
multi-function devices that include fuel gauages that are compatible
with MAX17042.
with MAX17042. This driver also supports max17047/50 chips which are
improved version of max17042.

config BATTERY_Z2
tristate "Z2 battery driver"
Expand Down
69 changes: 58 additions & 11 deletions trunk/drivers/power/max17042_battery.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,13 @@
#define dP_ACC_100 0x1900
#define dP_ACC_200 0x3200

#define MAX17042_IC_VERSION 0x0092
#define MAX17047_IC_VERSION 0x00AC /* same for max17050 */

struct max17042_chip {
struct i2c_client *client;
struct power_supply battery;
enum max170xx_chip_type chip_type;
struct max17042_platform_data *pdata;
struct work_struct work;
int init_complete;
Expand Down Expand Up @@ -152,7 +156,10 @@ static int max17042_get_property(struct power_supply *psy,
val->intval *= 20000; /* Units of LSB = 20mV */
break;
case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
ret = max17042_read_reg(chip->client, MAX17042_V_empty);
if (chip->chip_type == MAX17042)
ret = max17042_read_reg(chip->client, MAX17042_V_empty);
else
ret = max17042_read_reg(chip->client, MAX17047_V_empty);
if (ret < 0)
return ret;

Expand Down Expand Up @@ -389,6 +396,9 @@ static void max17042_write_config_regs(struct max17042_chip *chip)
max17042_write_reg(chip->client, MAX17042_FilterCFG,
config->filter_cfg);
max17042_write_reg(chip->client, MAX17042_RelaxCFG, config->relax_cfg);
if (chip->chip_type == MAX17047)
max17042_write_reg(chip->client, MAX17047_FullSOCThr,
config->full_soc_thresh);
}

static void max17042_write_custom_regs(struct max17042_chip *chip)
Expand All @@ -399,12 +409,23 @@ static void max17042_write_custom_regs(struct max17042_chip *chip)
config->rcomp0);
max17042_write_verify_reg(chip->client, MAX17042_TempCo,
config->tcompc0);
max17042_write_reg(chip->client, MAX17042_EmptyTempCo,
config->empty_tempco);
max17042_write_verify_reg(chip->client, MAX17042_K_empty0,
config->kempty0);
max17042_write_verify_reg(chip->client, MAX17042_ICHGTerm,
config->ichgt_term);
if (chip->chip_type == MAX17042) {
max17042_write_reg(chip->client, MAX17042_EmptyTempCo,
config->empty_tempco);
max17042_write_verify_reg(chip->client, MAX17042_K_empty0,
config->kempty0);
} else {
max17042_write_verify_reg(chip->client, MAX17047_QRTbl00,
config->qrtbl00);
max17042_write_verify_reg(chip->client, MAX17047_QRTbl10,
config->qrtbl10);
max17042_write_verify_reg(chip->client, MAX17047_QRTbl20,
config->qrtbl20);
max17042_write_verify_reg(chip->client, MAX17047_QRTbl30,
config->qrtbl30);
}
}

static void max17042_update_capacity_regs(struct max17042_chip *chip)
Expand Down Expand Up @@ -460,6 +481,8 @@ static void max17042_load_new_capacity_params(struct max17042_chip *chip)
config->design_cap);
max17042_write_verify_reg(chip->client, MAX17042_FullCAPNom,
config->fullcapnom);
/* Update SOC register with new SOC */
max17042_write_reg(chip->client, MAX17042_RepSOC, vfSoc);
}

/*
Expand Down Expand Up @@ -496,20 +519,28 @@ static inline void max17042_override_por_values(struct max17042_chip *chip)

max17042_override_por(client, MAX17042_FullCAP, config->fullcap);
max17042_override_por(client, MAX17042_FullCAPNom, config->fullcapnom);
max17042_override_por(client, MAX17042_SOC_empty, config->socempty);
if (chip->chip_type == MAX17042)
max17042_override_por(client, MAX17042_SOC_empty,
config->socempty);
max17042_override_por(client, MAX17042_LAvg_empty, config->lavg_empty);
max17042_override_por(client, MAX17042_dQacc, config->dqacc);
max17042_override_por(client, MAX17042_dPacc, config->dpacc);

max17042_override_por(client, MAX17042_V_empty, config->vempty);
if (chip->chip_type == MAX17042)
max17042_override_por(client, MAX17042_V_empty, config->vempty);
else
max17042_override_por(client, MAX17047_V_empty, config->vempty);
max17042_override_por(client, MAX17042_TempNom, config->temp_nom);
max17042_override_por(client, MAX17042_TempLim, config->temp_lim);
max17042_override_por(client, MAX17042_FCTC, config->fctc);
max17042_override_por(client, MAX17042_RCOMP0, config->rcomp0);
max17042_override_por(client, MAX17042_TempCo, config->tcompc0);
max17042_override_por(client, MAX17042_EmptyTempCo,
config->empty_tempco);
max17042_override_por(client, MAX17042_K_empty0, config->kempty0);
if (chip->chip_type) {
max17042_override_por(client, MAX17042_EmptyTempCo,
config->empty_tempco);
max17042_override_por(client, MAX17042_K_empty0,
config->kempty0);
}
}

static int max17042_init_chip(struct max17042_chip *chip)
Expand Down Expand Up @@ -666,7 +697,19 @@ static int __devinit max17042_probe(struct i2c_client *client,

i2c_set_clientdata(client, chip);

chip->battery.name = "max17042_battery";
ret = max17042_read_reg(chip->client, MAX17042_DevName);
if (ret == MAX17042_IC_VERSION) {
dev_dbg(&client->dev, "chip type max17042 detected\n");
chip->chip_type = MAX17042;
} else if (ret == MAX17047_IC_VERSION) {
dev_dbg(&client->dev, "chip type max17047/50 detected\n");
chip->chip_type = MAX17047;
} else {
dev_err(&client->dev, "device version mismatch: %x\n", ret);
return -EIO;
}

chip->battery.name = "max170xx_battery";
chip->battery.type = POWER_SUPPLY_TYPE_BATTERY;
chip->battery.get_property = max17042_get_property;
chip->battery.properties = max17042_battery_props;
Expand Down Expand Up @@ -778,13 +821,17 @@ static const struct dev_pm_ops max17042_pm_ops = {
#ifdef CONFIG_OF
static const struct of_device_id max17042_dt_match[] = {
{ .compatible = "maxim,max17042" },
{ .compatible = "maxim,max17047" },
{ .compatible = "maxim,max17050" },
{ },
};
MODULE_DEVICE_TABLE(of, max17042_dt_match);
#endif

static const struct i2c_device_id max17042_id[] = {
{ "max17042", 0 },
{ "max17047", 1 },
{ "max17050", 2 },
{ }
};
MODULE_DEVICE_TABLE(i2c, max17042_id);
Expand Down
17 changes: 17 additions & 0 deletions trunk/include/linux/power/max17042_battery.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,18 @@ enum max17042_register {
MAX17042_VFSOC = 0xFF,
};

/* Registers specific to max17047/50 */
enum max17047_register {
MAX17047_QRTbl00 = 0x12,
MAX17047_FullSOCThr = 0x13,
MAX17047_QRTbl10 = 0x22,
MAX17047_QRTbl20 = 0x32,
MAX17047_V_empty = 0x3A,
MAX17047_QRTbl30 = 0x42,
};

enum max170xx_chip_type {MAX17042, MAX17047};

/*
* used for setting a register to a desired value
* addr : address for a register
Expand Down Expand Up @@ -144,6 +156,7 @@ struct max17042_config_data {
u16 shdntimer; /* 0x03F */

/* App data */
u16 full_soc_thresh; /* 0x13 */
u16 design_cap; /* 0x18 */
u16 ichgt_term; /* 0x1E */

Expand All @@ -162,6 +175,10 @@ struct max17042_config_data {
u16 lavg_empty; /* 0x36 */
u16 dqacc; /* 0x45 */
u16 dpacc; /* 0x46 */
u16 qrtbl00; /* 0x12 */
u16 qrtbl10; /* 0x22 */
u16 qrtbl20; /* 0x32 */
u16 qrtbl30; /* 0x42 */

/* Cell technology from power_supply.h */
u16 cell_technology;
Expand Down

0 comments on commit 710ef32

Please sign in to comment.