aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/power/Kconfig5
-rw-r--r--drivers/power/max17042_battery.c69
-rw-r--r--include/linux/power/max17042_battery.h17
3 files changed, 78 insertions, 13 deletions
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index b711795c6664..e3a3b4956f08 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -181,14 +181,15 @@ config BATTERY_MAX17040
181 to operate with a single lithium cell 181 to operate with a single lithium cell
182 182
183config BATTERY_MAX17042 183config BATTERY_MAX17042
184 tristate "Maxim MAX17042/8997/8966 Fuel Gauge" 184 tristate "Maxim MAX17042/17047/17050/8997/8966 Fuel Gauge"
185 depends on I2C 185 depends on I2C
186 help 186 help
187 MAX17042 is fuel-gauge systems for lithium-ion (Li+) batteries 187 MAX17042 is fuel-gauge systems for lithium-ion (Li+) batteries
188 in handheld and portable equipment. The MAX17042 is configured 188 in handheld and portable equipment. The MAX17042 is configured
189 to operate with a single lithium cell. MAX8997 and MAX8966 are 189 to operate with a single lithium cell. MAX8997 and MAX8966 are
190 multi-function devices that include fuel gauages that are compatible 190 multi-function devices that include fuel gauages that are compatible
191 with MAX17042. 191 with MAX17042. This driver also supports max17047/50 chips which are
192 improved version of max17042.
192 193
193config BATTERY_Z2 194config BATTERY_Z2
194 tristate "Z2 battery driver" 195 tristate "Z2 battery driver"
diff --git a/drivers/power/max17042_battery.c b/drivers/power/max17042_battery.c
index 8d28006322e9..140788b309f8 100644
--- a/drivers/power/max17042_battery.c
+++ b/drivers/power/max17042_battery.c
@@ -62,9 +62,13 @@
62#define dP_ACC_100 0x1900 62#define dP_ACC_100 0x1900
63#define dP_ACC_200 0x3200 63#define dP_ACC_200 0x3200
64 64
65#define MAX17042_IC_VERSION 0x0092
66#define MAX17047_IC_VERSION 0x00AC /* same for max17050 */
67
65struct max17042_chip { 68struct max17042_chip {
66 struct i2c_client *client; 69 struct i2c_client *client;
67 struct power_supply battery; 70 struct power_supply battery;
71 enum max170xx_chip_type chip_type;
68 struct max17042_platform_data *pdata; 72 struct max17042_platform_data *pdata;
69 struct work_struct work; 73 struct work_struct work;
70 int init_complete; 74 int init_complete;
@@ -152,7 +156,10 @@ static int max17042_get_property(struct power_supply *psy,
152 val->intval *= 20000; /* Units of LSB = 20mV */ 156 val->intval *= 20000; /* Units of LSB = 20mV */
153 break; 157 break;
154 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: 158 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
155 ret = max17042_read_reg(chip->client, MAX17042_V_empty); 159 if (chip->chip_type == MAX17042)
160 ret = max17042_read_reg(chip->client, MAX17042_V_empty);
161 else
162 ret = max17042_read_reg(chip->client, MAX17047_V_empty);
156 if (ret < 0) 163 if (ret < 0)
157 return ret; 164 return ret;
158 165
@@ -389,6 +396,9 @@ static void max17042_write_config_regs(struct max17042_chip *chip)
389 max17042_write_reg(chip->client, MAX17042_FilterCFG, 396 max17042_write_reg(chip->client, MAX17042_FilterCFG,
390 config->filter_cfg); 397 config->filter_cfg);
391 max17042_write_reg(chip->client, MAX17042_RelaxCFG, config->relax_cfg); 398 max17042_write_reg(chip->client, MAX17042_RelaxCFG, config->relax_cfg);
399 if (chip->chip_type == MAX17047)
400 max17042_write_reg(chip->client, MAX17047_FullSOCThr,
401 config->full_soc_thresh);
392} 402}
393 403
394static void max17042_write_custom_regs(struct max17042_chip *chip) 404static void max17042_write_custom_regs(struct max17042_chip *chip)
@@ -399,12 +409,23 @@ static void max17042_write_custom_regs(struct max17042_chip *chip)
399 config->rcomp0); 409 config->rcomp0);
400 max17042_write_verify_reg(chip->client, MAX17042_TempCo, 410 max17042_write_verify_reg(chip->client, MAX17042_TempCo,
401 config->tcompc0); 411 config->tcompc0);
402 max17042_write_reg(chip->client, MAX17042_EmptyTempCo,
403 config->empty_tempco);
404 max17042_write_verify_reg(chip->client, MAX17042_K_empty0,
405 config->kempty0);
406 max17042_write_verify_reg(chip->client, MAX17042_ICHGTerm, 412 max17042_write_verify_reg(chip->client, MAX17042_ICHGTerm,
407 config->ichgt_term); 413 config->ichgt_term);
414 if (chip->chip_type == MAX17042) {
415 max17042_write_reg(chip->client, MAX17042_EmptyTempCo,
416 config->empty_tempco);
417 max17042_write_verify_reg(chip->client, MAX17042_K_empty0,
418 config->kempty0);
419 } else {
420 max17042_write_verify_reg(chip->client, MAX17047_QRTbl00,
421 config->qrtbl00);
422 max17042_write_verify_reg(chip->client, MAX17047_QRTbl10,
423 config->qrtbl10);
424 max17042_write_verify_reg(chip->client, MAX17047_QRTbl20,
425 config->qrtbl20);
426 max17042_write_verify_reg(chip->client, MAX17047_QRTbl30,
427 config->qrtbl30);
428 }
408} 429}
409 430
410static void max17042_update_capacity_regs(struct max17042_chip *chip) 431static void max17042_update_capacity_regs(struct max17042_chip *chip)
@@ -460,6 +481,8 @@ static void max17042_load_new_capacity_params(struct max17042_chip *chip)
460 config->design_cap); 481 config->design_cap);
461 max17042_write_verify_reg(chip->client, MAX17042_FullCAPNom, 482 max17042_write_verify_reg(chip->client, MAX17042_FullCAPNom,
462 config->fullcapnom); 483 config->fullcapnom);
484 /* Update SOC register with new SOC */
485 max17042_write_reg(chip->client, MAX17042_RepSOC, vfSoc);
463} 486}
464 487
465/* 488/*
@@ -496,20 +519,28 @@ static inline void max17042_override_por_values(struct max17042_chip *chip)
496 519
497 max17042_override_por(client, MAX17042_FullCAP, config->fullcap); 520 max17042_override_por(client, MAX17042_FullCAP, config->fullcap);
498 max17042_override_por(client, MAX17042_FullCAPNom, config->fullcapnom); 521 max17042_override_por(client, MAX17042_FullCAPNom, config->fullcapnom);
499 max17042_override_por(client, MAX17042_SOC_empty, config->socempty); 522 if (chip->chip_type == MAX17042)
523 max17042_override_por(client, MAX17042_SOC_empty,
524 config->socempty);
500 max17042_override_por(client, MAX17042_LAvg_empty, config->lavg_empty); 525 max17042_override_por(client, MAX17042_LAvg_empty, config->lavg_empty);
501 max17042_override_por(client, MAX17042_dQacc, config->dqacc); 526 max17042_override_por(client, MAX17042_dQacc, config->dqacc);
502 max17042_override_por(client, MAX17042_dPacc, config->dpacc); 527 max17042_override_por(client, MAX17042_dPacc, config->dpacc);
503 528
504 max17042_override_por(client, MAX17042_V_empty, config->vempty); 529 if (chip->chip_type == MAX17042)
530 max17042_override_por(client, MAX17042_V_empty, config->vempty);
531 else
532 max17042_override_por(client, MAX17047_V_empty, config->vempty);
505 max17042_override_por(client, MAX17042_TempNom, config->temp_nom); 533 max17042_override_por(client, MAX17042_TempNom, config->temp_nom);
506 max17042_override_por(client, MAX17042_TempLim, config->temp_lim); 534 max17042_override_por(client, MAX17042_TempLim, config->temp_lim);
507 max17042_override_por(client, MAX17042_FCTC, config->fctc); 535 max17042_override_por(client, MAX17042_FCTC, config->fctc);
508 max17042_override_por(client, MAX17042_RCOMP0, config->rcomp0); 536 max17042_override_por(client, MAX17042_RCOMP0, config->rcomp0);
509 max17042_override_por(client, MAX17042_TempCo, config->tcompc0); 537 max17042_override_por(client, MAX17042_TempCo, config->tcompc0);
510 max17042_override_por(client, MAX17042_EmptyTempCo, 538 if (chip->chip_type) {
511 config->empty_tempco); 539 max17042_override_por(client, MAX17042_EmptyTempCo,
512 max17042_override_por(client, MAX17042_K_empty0, config->kempty0); 540 config->empty_tempco);
541 max17042_override_por(client, MAX17042_K_empty0,
542 config->kempty0);
543 }
513} 544}
514 545
515static int max17042_init_chip(struct max17042_chip *chip) 546static int max17042_init_chip(struct max17042_chip *chip)
@@ -666,7 +697,19 @@ static int __devinit max17042_probe(struct i2c_client *client,
666 697
667 i2c_set_clientdata(client, chip); 698 i2c_set_clientdata(client, chip);
668 699
669 chip->battery.name = "max17042_battery"; 700 ret = max17042_read_reg(chip->client, MAX17042_DevName);
701 if (ret == MAX17042_IC_VERSION) {
702 dev_dbg(&client->dev, "chip type max17042 detected\n");
703 chip->chip_type = MAX17042;
704 } else if (ret == MAX17047_IC_VERSION) {
705 dev_dbg(&client->dev, "chip type max17047/50 detected\n");
706 chip->chip_type = MAX17047;
707 } else {
708 dev_err(&client->dev, "device version mismatch: %x\n", ret);
709 return -EIO;
710 }
711
712 chip->battery.name = "max170xx_battery";
670 chip->battery.type = POWER_SUPPLY_TYPE_BATTERY; 713 chip->battery.type = POWER_SUPPLY_TYPE_BATTERY;
671 chip->battery.get_property = max17042_get_property; 714 chip->battery.get_property = max17042_get_property;
672 chip->battery.properties = max17042_battery_props; 715 chip->battery.properties = max17042_battery_props;
@@ -778,6 +821,8 @@ static const struct dev_pm_ops max17042_pm_ops = {
778#ifdef CONFIG_OF 821#ifdef CONFIG_OF
779static const struct of_device_id max17042_dt_match[] = { 822static const struct of_device_id max17042_dt_match[] = {
780 { .compatible = "maxim,max17042" }, 823 { .compatible = "maxim,max17042" },
824 { .compatible = "maxim,max17047" },
825 { .compatible = "maxim,max17050" },
781 { }, 826 { },
782}; 827};
783MODULE_DEVICE_TABLE(of, max17042_dt_match); 828MODULE_DEVICE_TABLE(of, max17042_dt_match);
@@ -785,6 +830,8 @@ MODULE_DEVICE_TABLE(of, max17042_dt_match);
785 830
786static const struct i2c_device_id max17042_id[] = { 831static const struct i2c_device_id max17042_id[] = {
787 { "max17042", 0 }, 832 { "max17042", 0 },
833 { "max17047", 1 },
834 { "max17050", 2 },
788 { } 835 { }
789}; 836};
790MODULE_DEVICE_TABLE(i2c, max17042_id); 837MODULE_DEVICE_TABLE(i2c, max17042_id);
diff --git a/include/linux/power/max17042_battery.h b/include/linux/power/max17042_battery.h
index e01b167e66f0..89dd84f47c6e 100644
--- a/include/linux/power/max17042_battery.h
+++ b/include/linux/power/max17042_battery.h
@@ -116,6 +116,18 @@ enum max17042_register {
116 MAX17042_VFSOC = 0xFF, 116 MAX17042_VFSOC = 0xFF,
117}; 117};
118 118
119/* Registers specific to max17047/50 */
120enum max17047_register {
121 MAX17047_QRTbl00 = 0x12,
122 MAX17047_FullSOCThr = 0x13,
123 MAX17047_QRTbl10 = 0x22,
124 MAX17047_QRTbl20 = 0x32,
125 MAX17047_V_empty = 0x3A,
126 MAX17047_QRTbl30 = 0x42,
127};
128
129enum max170xx_chip_type {MAX17042, MAX17047};
130
119/* 131/*
120 * used for setting a register to a desired value 132 * used for setting a register to a desired value
121 * addr : address for a register 133 * addr : address for a register
@@ -144,6 +156,7 @@ struct max17042_config_data {
144 u16 shdntimer; /* 0x03F */ 156 u16 shdntimer; /* 0x03F */
145 157
146 /* App data */ 158 /* App data */
159 u16 full_soc_thresh; /* 0x13 */
147 u16 design_cap; /* 0x18 */ 160 u16 design_cap; /* 0x18 */
148 u16 ichgt_term; /* 0x1E */ 161 u16 ichgt_term; /* 0x1E */
149 162
@@ -162,6 +175,10 @@ struct max17042_config_data {
162 u16 lavg_empty; /* 0x36 */ 175 u16 lavg_empty; /* 0x36 */
163 u16 dqacc; /* 0x45 */ 176 u16 dqacc; /* 0x45 */
164 u16 dpacc; /* 0x46 */ 177 u16 dpacc; /* 0x46 */
178 u16 qrtbl00; /* 0x12 */
179 u16 qrtbl10; /* 0x22 */
180 u16 qrtbl20; /* 0x32 */
181 u16 qrtbl30; /* 0x42 */
165 182
166 /* Cell technology from power_supply.h */ 183 /* Cell technology from power_supply.h */
167 u16 cell_technology; 184 u16 cell_technology;