Merge tag 'for-v4.12-2' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply

Pull more power-supply updates from Sebastian Reichel:
"The power-supply subsystem has a few more changes for the v4.12 merge
window:

- New battery driver for AXP20X and AXP22X PMICs

- Improve max17042_battery for usage on x86

- Misc small cleanups & fixes"

* tag 'for-v4.12-2' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply: (34 commits)
power: supply: cpcap-charger: Keep trickle charger bits disabled
power: supply: cpcap-charger: Fix enable for 3.8V charge setting
power: supply: cpcap-charger: Fix charge voltage configuration
power: supply: cpcap-charger: Fix charger name
power: supply: twl4030-charger: make twl4030_bci_property_is_writeable static
power: supply: sbs-battery: Add alert callback
mailmap: add Sebastian Reichel
power: supply: avoid unused twl4030-madc.h
power: supply: sbs-battery: Correct supply status with current draw
power: supply: sbs-battery: Don't ignore the first external power change
power: supply: pda_power: move from timer to delayed_work
power: supply: max17042_battery: Add support for the SCOPE property
power: supply: max17042_battery: Add support for the CHARGE_NOW property
power: supply: max17042_battery: Add support for the CHARGE_FULL_DESIGN property
power: supply: max17042_battery: mAh readings depend on r_sns value
power: supply: max17042_battery: Add support for the VOLT_MIN property
power: supply: max17042_battery: Add support for the TECHNOLOGY attribute
power: supply: max17042_battery: Add external_power_changed callback
power: supply: max17042_battery: Add support for the STATUS property
power: supply: max17042_battery: Add default platform_data fallback data
...

+975 -173
+2
.mailmap
··· 146 146 Santosh Shilimkar <santosh.shilimkar@oracle.org> 147 147 Sascha Hauer <s.hauer@pengutronix.de> 148 148 S.Çağlar Onur <caglar@pardus.org.tr> 149 + Sebastian Reichel <sre@kernel.org> <sre@debian.org> 150 + Sebastian Reichel <sre@kernel.org> <sebastian.reichel@collabora.co.uk> 149 151 Shiraz Hashim <shiraz.linux.kernel@gmail.com> <shiraz.hashim@st.com> 150 152 Shuah Khan <shuah@kernel.org> <shuahkhan@gmail.com> 151 153 Shuah Khan <shuah@kernel.org> <shuah.khan@hp.com>
+20
Documentation/devicetree/bindings/power/supply/axp20x_battery.txt
··· 1 + AXP20x and AXP22x battery power supply 2 + 3 + Required Properties: 4 + - compatible, one of: 5 + "x-powers,axp209-battery-power-supply" 6 + "x-powers,axp221-battery-power-supply" 7 + 8 + This node is a subnode of the axp20x/axp22x PMIC. 9 + 10 + The AXP20X and AXP22X can read the battery voltage, charge and discharge 11 + currents of the battery by reading ADC channels from the AXP20X/AXP22X 12 + ADC. 13 + 14 + Example: 15 + 16 + &axp209 { 17 + battery_power_supply: battery-power-supply { 18 + compatible = "x-powers,axp209-battery-power-supply"; 19 + } 20 + };
+20 -7
drivers/power/supply/Kconfig
··· 238 238 This driver can also be built as a module. If so, the module will be 239 239 called axp20x_ac_power. 240 240 241 + config BATTERY_AXP20X 242 + tristate "X-Powers AXP20X battery driver" 243 + depends on MFD_AXP20X 244 + depends on AXP20X_ADC 245 + depends on IIO 246 + help 247 + Say Y here to enable support for X-Powers AXP20X PMICs' battery power 248 + supply. 249 + 250 + This driver can also be built as a module. If so, the module will be 251 + called axp20x_battery. 252 + 253 + config AXP20X_POWER 254 + tristate "AXP20x power supply driver" 255 + depends on MFD_AXP20X 256 + depends on IIO 257 + help 258 + This driver provides support for the power supply features of 259 + AXP20x PMIC. 260 + 241 261 config AXP288_CHARGER 242 262 tristate "X-Powers AXP288 Charger" 243 263 depends on MFD_AXP20X && EXTCON_AXP288 ··· 560 540 select REGMAP_I2C 561 541 help 562 542 Say Y to enable support for Richtek RT9455 battery charger. 563 - 564 - config AXP20X_POWER 565 - tristate "AXP20x power supply driver" 566 - depends on MFD_AXP20X 567 - help 568 - This driver provides support for the power supply features of 569 - AXP20x PMIC. 570 543 571 544 endif # POWER_SUPPLY
+1
drivers/power/supply/Makefile
··· 18 18 19 19 obj-$(CONFIG_BATTERY_88PM860X) += 88pm860x_battery.o 20 20 obj-$(CONFIG_BATTERY_ACT8945A) += act8945a_charger.o 21 + obj-$(CONFIG_BATTERY_AXP20X) += axp20x_battery.o 21 22 obj-$(CONFIG_CHARGER_AXP20X) += axp20x_ac_power.o 22 23 obj-$(CONFIG_BATTERY_DS2760) += ds2760_battery.o 23 24 obj-$(CONFIG_BATTERY_DS2780) += ds2780_battery.o
+1 -1
drivers/power/supply/ab8500_charger.c
··· 3238 3238 BUS_PP_PRECHG_CURRENT_MASK, 0); 3239 3239 if (ret) { 3240 3240 dev_err(di->dev, 3241 - "failed to setup usb power path prechage current\n"); 3241 + "failed to setup usb power path precharge current\n"); 3242 3242 goto out; 3243 3243 } 3244 3244 }
+502
drivers/power/supply/axp20x_battery.c
··· 1 + /* 2 + * Battery power supply driver for X-Powers AXP20X and AXP22X PMICs 3 + * 4 + * Copyright 2016 Free Electrons NextThing Co. 5 + * Quentin Schulz <quentin.schulz@free-electrons.com> 6 + * 7 + * This driver is based on a previous upstreaming attempt by: 8 + * Bruno Prémont <bonbons@linux-vserver.org> 9 + * 10 + * This file is subject to the terms and conditions of the GNU General 11 + * Public License. See the file "COPYING" in the main directory of this 12 + * archive for more details. 13 + * 14 + * This program is distributed in the hope that it will be useful, 15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 + * GNU General Public License for more details. 18 + */ 19 + 20 + #include <linux/err.h> 21 + #include <linux/interrupt.h> 22 + #include <linux/irq.h> 23 + #include <linux/module.h> 24 + #include <linux/of.h> 25 + #include <linux/of_device.h> 26 + #include <linux/platform_device.h> 27 + #include <linux/power_supply.h> 28 + #include <linux/regmap.h> 29 + #include <linux/slab.h> 30 + #include <linux/time.h> 31 + #include <linux/iio/iio.h> 32 + #include <linux/iio/consumer.h> 33 + #include <linux/mfd/axp20x.h> 34 + 35 + #define AXP20X_PWR_STATUS_BAT_CHARGING BIT(2) 36 + 37 + #define AXP20X_PWR_OP_BATT_PRESENT BIT(5) 38 + #define AXP20X_PWR_OP_BATT_ACTIVATED BIT(3) 39 + 40 + #define AXP209_FG_PERCENT GENMASK(6, 0) 41 + #define AXP22X_FG_VALID BIT(7) 42 + 43 + #define AXP20X_CHRG_CTRL1_TGT_VOLT GENMASK(6, 5) 44 + #define AXP20X_CHRG_CTRL1_TGT_4_1V (0 << 5) 45 + #define AXP20X_CHRG_CTRL1_TGT_4_15V (1 << 5) 46 + #define AXP20X_CHRG_CTRL1_TGT_4_2V (2 << 5) 47 + #define AXP20X_CHRG_CTRL1_TGT_4_36V (3 << 5) 48 + 49 + #define AXP22X_CHRG_CTRL1_TGT_4_22V (1 << 5) 50 + #define AXP22X_CHRG_CTRL1_TGT_4_24V (3 << 5) 51 + 52 + #define AXP20X_CHRG_CTRL1_TGT_CURR GENMASK(3, 0) 53 + 54 + #define AXP20X_V_OFF_MASK GENMASK(2, 0) 55 + 56 + struct axp20x_batt_ps { 57 + struct regmap *regmap; 58 + struct power_supply *batt; 59 + struct device *dev; 60 + struct iio_channel *batt_chrg_i; 61 + struct iio_channel *batt_dischrg_i; 62 + struct iio_channel *batt_v; 63 + u8 axp_id; 64 + }; 65 + 66 + static int axp20x_battery_get_max_voltage(struct axp20x_batt_ps *axp20x_batt, 67 + int *val) 68 + { 69 + int ret, reg; 70 + 71 + ret = regmap_read(axp20x_batt->regmap, AXP20X_CHRG_CTRL1, &reg); 72 + if (ret) 73 + return ret; 74 + 75 + switch (reg & AXP20X_CHRG_CTRL1_TGT_VOLT) { 76 + case AXP20X_CHRG_CTRL1_TGT_4_1V: 77 + *val = 4100000; 78 + break; 79 + case AXP20X_CHRG_CTRL1_TGT_4_15V: 80 + *val = 4150000; 81 + break; 82 + case AXP20X_CHRG_CTRL1_TGT_4_2V: 83 + *val = 4200000; 84 + break; 85 + case AXP20X_CHRG_CTRL1_TGT_4_36V: 86 + *val = 4360000; 87 + break; 88 + default: 89 + return -EINVAL; 90 + } 91 + 92 + return 0; 93 + } 94 + 95 + static int axp22x_battery_get_max_voltage(struct axp20x_batt_ps *axp20x_batt, 96 + int *val) 97 + { 98 + int ret, reg; 99 + 100 + ret = regmap_read(axp20x_batt->regmap, AXP20X_CHRG_CTRL1, &reg); 101 + if (ret) 102 + return ret; 103 + 104 + switch (reg & AXP20X_CHRG_CTRL1_TGT_VOLT) { 105 + case AXP20X_CHRG_CTRL1_TGT_4_1V: 106 + *val = 4100000; 107 + break; 108 + case AXP20X_CHRG_CTRL1_TGT_4_2V: 109 + *val = 4200000; 110 + break; 111 + case AXP22X_CHRG_CTRL1_TGT_4_22V: 112 + *val = 4220000; 113 + break; 114 + case AXP22X_CHRG_CTRL1_TGT_4_24V: 115 + *val = 4240000; 116 + break; 117 + default: 118 + return -EINVAL; 119 + } 120 + 121 + return 0; 122 + } 123 + 124 + static void raw_to_constant_charge_current(struct axp20x_batt_ps *axp, int *val) 125 + { 126 + if (axp->axp_id == AXP209_ID) 127 + *val = *val * 100000 + 300000; 128 + else 129 + *val = *val * 150000 + 300000; 130 + } 131 + 132 + static int axp20x_get_constant_charge_current(struct axp20x_batt_ps *axp, 133 + int *val) 134 + { 135 + int ret; 136 + 137 + ret = regmap_read(axp->regmap, AXP20X_CHRG_CTRL1, val); 138 + if (ret) 139 + return ret; 140 + 141 + *val &= AXP20X_CHRG_CTRL1_TGT_CURR; 142 + 143 + raw_to_constant_charge_current(axp, val); 144 + 145 + return 0; 146 + } 147 + 148 + static int axp20x_battery_get_prop(struct power_supply *psy, 149 + enum power_supply_property psp, 150 + union power_supply_propval *val) 151 + { 152 + struct axp20x_batt_ps *axp20x_batt = power_supply_get_drvdata(psy); 153 + struct iio_channel *chan; 154 + int ret = 0, reg, val1; 155 + 156 + switch (psp) { 157 + case POWER_SUPPLY_PROP_PRESENT: 158 + case POWER_SUPPLY_PROP_ONLINE: 159 + ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_OP_MODE, 160 + &reg); 161 + if (ret) 162 + return ret; 163 + 164 + val->intval = !!(reg & AXP20X_PWR_OP_BATT_PRESENT); 165 + break; 166 + 167 + case POWER_SUPPLY_PROP_STATUS: 168 + ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_INPUT_STATUS, 169 + &reg); 170 + if (ret) 171 + return ret; 172 + 173 + if (reg & AXP20X_PWR_STATUS_BAT_CHARGING) { 174 + val->intval = POWER_SUPPLY_STATUS_CHARGING; 175 + return 0; 176 + } 177 + 178 + ret = iio_read_channel_processed(axp20x_batt->batt_dischrg_i, 179 + &val1); 180 + if (ret) 181 + return ret; 182 + 183 + if (val1) { 184 + val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 185 + return 0; 186 + } 187 + 188 + ret = regmap_read(axp20x_batt->regmap, AXP20X_FG_RES, &val1); 189 + if (ret) 190 + return ret; 191 + 192 + /* 193 + * Fuel Gauge data takes 7 bits but the stored value seems to be 194 + * directly the raw percentage without any scaling to 7 bits. 195 + */ 196 + if ((val1 & AXP209_FG_PERCENT) == 100) 197 + val->intval = POWER_SUPPLY_STATUS_FULL; 198 + else 199 + val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; 200 + break; 201 + 202 + case POWER_SUPPLY_PROP_HEALTH: 203 + ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_OP_MODE, 204 + &val1); 205 + if (ret) 206 + return ret; 207 + 208 + if (val1 & AXP20X_PWR_OP_BATT_ACTIVATED) { 209 + val->intval = POWER_SUPPLY_HEALTH_DEAD; 210 + return 0; 211 + } 212 + 213 + val->intval = POWER_SUPPLY_HEALTH_GOOD; 214 + break; 215 + 216 + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: 217 + ret = axp20x_get_constant_charge_current(axp20x_batt, 218 + &val->intval); 219 + if (ret) 220 + return ret; 221 + break; 222 + 223 + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: 224 + val->intval = AXP20X_CHRG_CTRL1_TGT_CURR; 225 + raw_to_constant_charge_current(axp20x_batt, &val->intval); 226 + 227 + break; 228 + 229 + case POWER_SUPPLY_PROP_CURRENT_NOW: 230 + ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_INPUT_STATUS, 231 + &reg); 232 + if (ret) 233 + return ret; 234 + 235 + if (reg & AXP20X_PWR_STATUS_BAT_CHARGING) 236 + chan = axp20x_batt->batt_chrg_i; 237 + else 238 + chan = axp20x_batt->batt_dischrg_i; 239 + 240 + ret = iio_read_channel_processed(chan, &val->intval); 241 + if (ret) 242 + return ret; 243 + 244 + /* IIO framework gives mA but Power Supply framework gives uA */ 245 + val->intval *= 1000; 246 + break; 247 + 248 + case POWER_SUPPLY_PROP_CAPACITY: 249 + /* When no battery is present, return capacity is 100% */ 250 + ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_OP_MODE, 251 + &reg); 252 + if (ret) 253 + return ret; 254 + 255 + if (!(reg & AXP20X_PWR_OP_BATT_PRESENT)) { 256 + val->intval = 100; 257 + return 0; 258 + } 259 + 260 + ret = regmap_read(axp20x_batt->regmap, AXP20X_FG_RES, &reg); 261 + if (ret) 262 + return ret; 263 + 264 + if (axp20x_batt->axp_id == AXP221_ID && 265 + !(reg & AXP22X_FG_VALID)) 266 + return -EINVAL; 267 + 268 + /* 269 + * Fuel Gauge data takes 7 bits but the stored value seems to be 270 + * directly the raw percentage without any scaling to 7 bits. 271 + */ 272 + val->intval = reg & AXP209_FG_PERCENT; 273 + break; 274 + 275 + case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: 276 + if (axp20x_batt->axp_id == AXP209_ID) 277 + return axp20x_battery_get_max_voltage(axp20x_batt, 278 + &val->intval); 279 + return axp22x_battery_get_max_voltage(axp20x_batt, 280 + &val->intval); 281 + 282 + case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: 283 + ret = regmap_read(axp20x_batt->regmap, AXP20X_V_OFF, &reg); 284 + if (ret) 285 + return ret; 286 + 287 + val->intval = 2600000 + 100000 * (reg & AXP20X_V_OFF_MASK); 288 + break; 289 + 290 + case POWER_SUPPLY_PROP_VOLTAGE_NOW: 291 + ret = iio_read_channel_processed(axp20x_batt->batt_v, 292 + &val->intval); 293 + if (ret) 294 + return ret; 295 + 296 + /* IIO framework gives mV but Power Supply framework gives uV */ 297 + val->intval *= 1000; 298 + break; 299 + 300 + default: 301 + return -EINVAL; 302 + } 303 + 304 + return 0; 305 + } 306 + 307 + static int axp20x_battery_set_max_voltage(struct axp20x_batt_ps *axp20x_batt, 308 + int val) 309 + { 310 + switch (val) { 311 + case 4100000: 312 + val = AXP20X_CHRG_CTRL1_TGT_4_1V; 313 + break; 314 + 315 + case 4150000: 316 + if (axp20x_batt->axp_id == AXP221_ID) 317 + return -EINVAL; 318 + 319 + val = AXP20X_CHRG_CTRL1_TGT_4_15V; 320 + break; 321 + 322 + case 4200000: 323 + val = AXP20X_CHRG_CTRL1_TGT_4_2V; 324 + break; 325 + 326 + default: 327 + /* 328 + * AXP20x max voltage can be set to 4.36V and AXP22X max voltage 329 + * can be set to 4.22V and 4.24V, but these voltages are too 330 + * high for Lithium based batteries (AXP PMICs are supposed to 331 + * be used with these kinds of battery). 332 + */ 333 + return -EINVAL; 334 + } 335 + 336 + return regmap_update_bits(axp20x_batt->regmap, AXP20X_CHRG_CTRL1, 337 + AXP20X_CHRG_CTRL1_TGT_VOLT, val); 338 + } 339 + 340 + static int axp20x_set_constant_charge_current(struct axp20x_batt_ps *axp_batt, 341 + int charge_current) 342 + { 343 + if (axp_batt->axp_id == AXP209_ID) 344 + charge_current = (charge_current - 300000) / 100000; 345 + else 346 + charge_current = (charge_current - 300000) / 150000; 347 + 348 + if (charge_current > AXP20X_CHRG_CTRL1_TGT_CURR || charge_current < 0) 349 + return -EINVAL; 350 + 351 + return regmap_update_bits(axp_batt->regmap, AXP20X_CHRG_CTRL1, 352 + AXP20X_CHRG_CTRL1_TGT_CURR, charge_current); 353 + } 354 + 355 + static int axp20x_set_voltage_min_design(struct axp20x_batt_ps *axp_batt, 356 + int min_voltage) 357 + { 358 + int val1 = (min_voltage - 2600000) / 100000; 359 + 360 + if (val1 < 0 || val1 > AXP20X_V_OFF_MASK) 361 + return -EINVAL; 362 + 363 + return regmap_update_bits(axp_batt->regmap, AXP20X_V_OFF, 364 + AXP20X_V_OFF_MASK, val1); 365 + } 366 + 367 + static int axp20x_battery_set_prop(struct power_supply *psy, 368 + enum power_supply_property psp, 369 + const union power_supply_propval *val) 370 + { 371 + struct axp20x_batt_ps *axp20x_batt = power_supply_get_drvdata(psy); 372 + 373 + switch (psp) { 374 + case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: 375 + return axp20x_set_voltage_min_design(axp20x_batt, val->intval); 376 + 377 + case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: 378 + return axp20x_battery_set_max_voltage(axp20x_batt, val->intval); 379 + 380 + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: 381 + return axp20x_set_constant_charge_current(axp20x_batt, 382 + val->intval); 383 + 384 + default: 385 + return -EINVAL; 386 + } 387 + } 388 + 389 + static enum power_supply_property axp20x_battery_props[] = { 390 + POWER_SUPPLY_PROP_PRESENT, 391 + POWER_SUPPLY_PROP_ONLINE, 392 + POWER_SUPPLY_PROP_STATUS, 393 + POWER_SUPPLY_PROP_VOLTAGE_NOW, 394 + POWER_SUPPLY_PROP_CURRENT_NOW, 395 + POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, 396 + POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, 397 + POWER_SUPPLY_PROP_HEALTH, 398 + POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, 399 + POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, 400 + POWER_SUPPLY_PROP_CAPACITY, 401 + }; 402 + 403 + static int axp20x_battery_prop_writeable(struct power_supply *psy, 404 + enum power_supply_property psp) 405 + { 406 + return psp == POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN || 407 + psp == POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN || 408 + psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT; 409 + } 410 + 411 + static const struct power_supply_desc axp20x_batt_ps_desc = { 412 + .name = "axp20x-battery", 413 + .type = POWER_SUPPLY_TYPE_BATTERY, 414 + .properties = axp20x_battery_props, 415 + .num_properties = ARRAY_SIZE(axp20x_battery_props), 416 + .property_is_writeable = axp20x_battery_prop_writeable, 417 + .get_property = axp20x_battery_get_prop, 418 + .set_property = axp20x_battery_set_prop, 419 + }; 420 + 421 + static const struct of_device_id axp20x_battery_ps_id[] = { 422 + { 423 + .compatible = "x-powers,axp209-battery-power-supply", 424 + .data = (void *)AXP209_ID, 425 + }, { 426 + .compatible = "x-powers,axp221-battery-power-supply", 427 + .data = (void *)AXP221_ID, 428 + }, { /* sentinel */ }, 429 + }; 430 + MODULE_DEVICE_TABLE(of, axp20x_battery_ps_id); 431 + 432 + static int axp20x_power_probe(struct platform_device *pdev) 433 + { 434 + struct axp20x_batt_ps *axp20x_batt; 435 + struct power_supply_config psy_cfg = {}; 436 + 437 + if (!of_device_is_available(pdev->dev.of_node)) 438 + return -ENODEV; 439 + 440 + axp20x_batt = devm_kzalloc(&pdev->dev, sizeof(*axp20x_batt), 441 + GFP_KERNEL); 442 + if (!axp20x_batt) 443 + return -ENOMEM; 444 + 445 + axp20x_batt->dev = &pdev->dev; 446 + 447 + axp20x_batt->batt_v = devm_iio_channel_get(&pdev->dev, "batt_v"); 448 + if (IS_ERR(axp20x_batt->batt_v)) { 449 + if (PTR_ERR(axp20x_batt->batt_v) == -ENODEV) 450 + return -EPROBE_DEFER; 451 + return PTR_ERR(axp20x_batt->batt_v); 452 + } 453 + 454 + axp20x_batt->batt_chrg_i = devm_iio_channel_get(&pdev->dev, 455 + "batt_chrg_i"); 456 + if (IS_ERR(axp20x_batt->batt_chrg_i)) { 457 + if (PTR_ERR(axp20x_batt->batt_chrg_i) == -ENODEV) 458 + return -EPROBE_DEFER; 459 + return PTR_ERR(axp20x_batt->batt_chrg_i); 460 + } 461 + 462 + axp20x_batt->batt_dischrg_i = devm_iio_channel_get(&pdev->dev, 463 + "batt_dischrg_i"); 464 + if (IS_ERR(axp20x_batt->batt_dischrg_i)) { 465 + if (PTR_ERR(axp20x_batt->batt_dischrg_i) == -ENODEV) 466 + return -EPROBE_DEFER; 467 + return PTR_ERR(axp20x_batt->batt_dischrg_i); 468 + } 469 + 470 + axp20x_batt->regmap = dev_get_regmap(pdev->dev.parent, NULL); 471 + platform_set_drvdata(pdev, axp20x_batt); 472 + 473 + psy_cfg.drv_data = axp20x_batt; 474 + psy_cfg.of_node = pdev->dev.of_node; 475 + 476 + axp20x_batt->axp_id = (uintptr_t)of_device_get_match_data(&pdev->dev); 477 + 478 + axp20x_batt->batt = devm_power_supply_register(&pdev->dev, 479 + &axp20x_batt_ps_desc, 480 + &psy_cfg); 481 + if (IS_ERR(axp20x_batt->batt)) { 482 + dev_err(&pdev->dev, "failed to register power supply: %ld\n", 483 + PTR_ERR(axp20x_batt->batt)); 484 + return PTR_ERR(axp20x_batt->batt); 485 + } 486 + 487 + return 0; 488 + } 489 + 490 + static struct platform_driver axp20x_batt_driver = { 491 + .probe = axp20x_power_probe, 492 + .driver = { 493 + .name = "axp20x-battery-power-supply", 494 + .of_match_table = axp20x_battery_ps_id, 495 + }, 496 + }; 497 + 498 + module_platform_driver(axp20x_batt_driver); 499 + 500 + MODULE_DESCRIPTION("Battery power supply driver for AXP20X and AXP22X PMICs"); 501 + MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>"); 502 + MODULE_LICENSE("GPL");
+114 -35
drivers/power/supply/bq24190_charger.c
··· 533 533 int ret, limit = 100; 534 534 u8 v; 535 535 536 + if (device_property_read_bool(bdi->dev, "disable-reset")) 537 + return 0; 538 + 536 539 /* Reset the registers */ 537 540 ret = bq24190_write_mask(bdi, BQ24190_REG_POC, 538 541 BQ24190_REG_POC_RESET_MASK, ··· 662 659 v = bdi->f_reg; 663 660 mutex_unlock(&bdi->f_reg_lock); 664 661 665 - if (v & BQ24190_REG_F_BOOST_FAULT_MASK) { 666 - /* 667 - * This could be over-current or over-voltage but there's 668 - * no way to tell which. Return 'OVERVOLTAGE' since there 669 - * isn't an 'OVERCURRENT' value defined that we can return 670 - * even if it was over-current. 671 - */ 672 - health = POWER_SUPPLY_HEALTH_OVERVOLTAGE; 673 - } else { 674 - v &= BQ24190_REG_F_CHRG_FAULT_MASK; 675 - v >>= BQ24190_REG_F_CHRG_FAULT_SHIFT; 676 - 677 - switch (v) { 678 - case 0x0: /* Normal */ 679 - health = POWER_SUPPLY_HEALTH_GOOD; 662 + if (v & BQ24190_REG_F_NTC_FAULT_MASK) { 663 + switch (v >> BQ24190_REG_F_NTC_FAULT_SHIFT & 0x7) { 664 + case 0x1: /* TS1 Cold */ 665 + case 0x3: /* TS2 Cold */ 666 + case 0x5: /* Both Cold */ 667 + health = POWER_SUPPLY_HEALTH_COLD; 680 668 break; 669 + case 0x2: /* TS1 Hot */ 670 + case 0x4: /* TS2 Hot */ 671 + case 0x6: /* Both Hot */ 672 + health = POWER_SUPPLY_HEALTH_OVERHEAT; 673 + break; 674 + default: 675 + health = POWER_SUPPLY_HEALTH_UNKNOWN; 676 + } 677 + } else if (v & BQ24190_REG_F_BAT_FAULT_MASK) { 678 + health = POWER_SUPPLY_HEALTH_OVERVOLTAGE; 679 + } else if (v & BQ24190_REG_F_CHRG_FAULT_MASK) { 680 + switch (v >> BQ24190_REG_F_CHRG_FAULT_SHIFT & 0x3) { 681 681 case 0x1: /* Input Fault (VBUS OVP or VBAT<VBUS<3.8V) */ 682 682 /* 683 683 * This could be over-voltage or under-voltage ··· 697 691 case 0x3: /* Charge Safety Timer Expiration */ 698 692 health = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE; 699 693 break; 700 - default: 701 - health = POWER_SUPPLY_HEALTH_UNKNOWN; 694 + default: /* prevent compiler warning */ 695 + health = -1; 702 696 } 697 + } else if (v & BQ24190_REG_F_BOOST_FAULT_MASK) { 698 + /* 699 + * This could be over-current or over-voltage but there's 700 + * no way to tell which. Return 'OVERVOLTAGE' since there 701 + * isn't an 'OVERCURRENT' value defined that we can return 702 + * even if it was over-current. 703 + */ 704 + health = POWER_SUPPLY_HEALTH_OVERVOLTAGE; 705 + } else { 706 + health = POWER_SUPPLY_HEALTH_GOOD; 703 707 } 704 708 705 709 val->intval = health; ··· 720 704 static int bq24190_charger_get_online(struct bq24190_dev_info *bdi, 721 705 union power_supply_propval *val) 722 706 { 723 - u8 v; 707 + u8 pg_stat, batfet_disable; 724 708 int ret; 725 709 726 710 ret = bq24190_read_mask(bdi, BQ24190_REG_SS, 727 711 BQ24190_REG_SS_PG_STAT_MASK, 728 - BQ24190_REG_SS_PG_STAT_SHIFT, &v); 712 + BQ24190_REG_SS_PG_STAT_SHIFT, &pg_stat); 729 713 if (ret < 0) 730 714 return ret; 731 715 732 - val->intval = v; 716 + ret = bq24190_read_mask(bdi, BQ24190_REG_MOC, 717 + BQ24190_REG_MOC_BATFET_DISABLE_MASK, 718 + BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, &batfet_disable); 719 + if (ret < 0) 720 + return ret; 721 + 722 + val->intval = pg_stat && !batfet_disable; 723 + 733 724 return 0; 725 + } 726 + 727 + static int bq24190_battery_set_online(struct bq24190_dev_info *bdi, 728 + const union power_supply_propval *val); 729 + static int bq24190_battery_get_status(struct bq24190_dev_info *bdi, 730 + union power_supply_propval *val); 731 + static int bq24190_battery_get_temp_alert_max(struct bq24190_dev_info *bdi, 732 + union power_supply_propval *val); 733 + static int bq24190_battery_set_temp_alert_max(struct bq24190_dev_info *bdi, 734 + const union power_supply_propval *val); 735 + 736 + static int bq24190_charger_set_online(struct bq24190_dev_info *bdi, 737 + const union power_supply_propval *val) 738 + { 739 + return bq24190_battery_set_online(bdi, val); 740 + } 741 + 742 + static int bq24190_charger_get_status(struct bq24190_dev_info *bdi, 743 + union power_supply_propval *val) 744 + { 745 + return bq24190_battery_get_status(bdi, val); 746 + } 747 + 748 + static int bq24190_charger_get_temp_alert_max(struct bq24190_dev_info *bdi, 749 + union power_supply_propval *val) 750 + { 751 + return bq24190_battery_get_temp_alert_max(bdi, val); 752 + } 753 + 754 + static int bq24190_charger_set_temp_alert_max(struct bq24190_dev_info *bdi, 755 + const union power_supply_propval *val) 756 + { 757 + return bq24190_battery_set_temp_alert_max(bdi, val); 734 758 } 735 759 736 760 static int bq24190_charger_get_current(struct bq24190_dev_info *bdi, ··· 887 831 case POWER_SUPPLY_PROP_ONLINE: 888 832 ret = bq24190_charger_get_online(bdi, val); 889 833 break; 834 + case POWER_SUPPLY_PROP_STATUS: 835 + ret = bq24190_charger_get_status(bdi, val); 836 + break; 837 + case POWER_SUPPLY_PROP_TEMP_ALERT_MAX: 838 + ret = bq24190_charger_get_temp_alert_max(bdi, val); 839 + break; 890 840 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: 891 841 ret = bq24190_charger_get_current(bdi, val); 892 842 break; ··· 941 879 return ret; 942 880 943 881 switch (psp) { 882 + case POWER_SUPPLY_PROP_ONLINE: 883 + ret = bq24190_charger_set_online(bdi, val); 884 + break; 885 + case POWER_SUPPLY_PROP_TEMP_ALERT_MAX: 886 + ret = bq24190_charger_set_temp_alert_max(bdi, val); 887 + break; 944 888 case POWER_SUPPLY_PROP_CHARGE_TYPE: 945 889 ret = bq24190_charger_set_charge_type(bdi, val); 946 890 break; ··· 972 904 int ret; 973 905 974 906 switch (psp) { 907 + case POWER_SUPPLY_PROP_ONLINE: 908 + case POWER_SUPPLY_PROP_TEMP_ALERT_MAX: 975 909 case POWER_SUPPLY_PROP_CHARGE_TYPE: 976 910 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: 977 911 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: ··· 990 920 POWER_SUPPLY_PROP_CHARGE_TYPE, 991 921 POWER_SUPPLY_PROP_HEALTH, 992 922 POWER_SUPPLY_PROP_ONLINE, 923 + POWER_SUPPLY_PROP_STATUS, 924 + POWER_SUPPLY_PROP_TEMP_ALERT_MAX, 993 925 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, 994 926 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, 995 927 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE, ··· 1165 1093 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy); 1166 1094 int ret; 1167 1095 1096 + dev_warn(bdi->dev, "warning: /sys/class/power_supply/bq24190-battery is deprecated\n"); 1168 1097 dev_dbg(bdi->dev, "prop: %d\n", psp); 1169 1098 1170 1099 ret = pm_runtime_get_sync(bdi->dev); ··· 1211 1138 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy); 1212 1139 int ret; 1213 1140 1141 + dev_warn(bdi->dev, "warning: /sys/class/power_supply/bq24190-battery is deprecated\n"); 1214 1142 dev_dbg(bdi->dev, "prop: %d\n", psp); 1215 1143 1216 1144 ret = pm_runtime_get_sync(bdi->dev); ··· 1340 1266 bdi->ss_reg = ss_reg; 1341 1267 } 1342 1268 1343 - if (alert_charger) 1269 + if (alert_charger || alert_battery) 1344 1270 power_supply_changed(bdi->charger); 1345 - if (alert_battery) 1271 + if (alert_battery && bdi->battery) 1346 1272 power_supply_changed(bdi->battery); 1347 1273 1348 1274 dev_dbg(bdi->dev, "ss_reg: 0x%02x, f_reg: 0x%02x\n", ss_reg, f_reg); ··· 1547 1473 goto out_pmrt; 1548 1474 } 1549 1475 1550 - battery_cfg.drv_data = bdi; 1551 - bdi->battery = power_supply_register(dev, &bq24190_battery_desc, 1552 - &battery_cfg); 1553 - if (IS_ERR(bdi->battery)) { 1554 - dev_err(dev, "Can't register battery\n"); 1555 - ret = PTR_ERR(bdi->battery); 1556 - goto out_charger; 1476 + /* the battery class is deprecated and will be removed. */ 1477 + /* in the interim, this property hides it. */ 1478 + if (!device_property_read_bool(dev, "omit-battery-class")) { 1479 + battery_cfg.drv_data = bdi; 1480 + bdi->battery = power_supply_register(dev, &bq24190_battery_desc, 1481 + &battery_cfg); 1482 + if (IS_ERR(bdi->battery)) { 1483 + dev_err(dev, "Can't register battery\n"); 1484 + ret = PTR_ERR(bdi->battery); 1485 + goto out_charger; 1486 + } 1557 1487 } 1558 1488 1559 1489 ret = bq24190_sysfs_create_group(bdi); 1560 1490 if (ret) { 1561 1491 dev_err(dev, "Can't create sysfs entries\n"); 1562 - goto out_battery; 1492 + goto out_charger; 1563 1493 } 1564 1494 1565 1495 bdi->initialized = true; ··· 1601 1523 out_sysfs: 1602 1524 bq24190_sysfs_remove_group(bdi); 1603 1525 1604 - out_battery: 1605 - power_supply_unregister(bdi->battery); 1606 - 1607 1526 out_charger: 1527 + if (!IS_ERR_OR_NULL(bdi->battery)) 1528 + power_supply_unregister(bdi->battery); 1608 1529 power_supply_unregister(bdi->charger); 1609 1530 1610 1531 out_pmrt: ··· 1626 1549 1627 1550 bq24190_register_reset(bdi); 1628 1551 bq24190_sysfs_remove_group(bdi); 1629 - power_supply_unregister(bdi->battery); 1552 + if (bdi->battery) 1553 + power_supply_unregister(bdi->battery); 1630 1554 power_supply_unregister(bdi->charger); 1631 1555 if (error >= 0) 1632 1556 pm_runtime_put_sync(bdi->dev); ··· 1714 1636 1715 1637 /* Things may have changed while suspended so alert upper layer */ 1716 1638 power_supply_changed(bdi->charger); 1717 - power_supply_changed(bdi->battery); 1639 + if (bdi->battery) 1640 + power_supply_changed(bdi->battery); 1718 1641 1719 1642 return 0; 1720 1643 }
+5 -6
drivers/power/supply/cpcap-charger.c
··· 76 76 #define CPCAP_REG_CRM_VCHRG_4V30 CPCAP_REG_CRM_VCHRG(0x8) 77 77 #define CPCAP_REG_CRM_VCHRG_4V32 CPCAP_REG_CRM_VCHRG(0x9) 78 78 #define CPCAP_REG_CRM_VCHRG_4V34 CPCAP_REG_CRM_VCHRG(0xa) 79 - #define CPCAP_REG_CRM_VCHRG_4V36 CPCAP_REG_CRM_VCHRG(0xb) 79 + #define CPCAP_REG_CRM_VCHRG_4V35 CPCAP_REG_CRM_VCHRG(0xb) 80 80 #define CPCAP_REG_CRM_VCHRG_4V38 CPCAP_REG_CRM_VCHRG(0xc) 81 81 #define CPCAP_REG_CRM_VCHRG_4V40 CPCAP_REG_CRM_VCHRG(0xd) 82 82 #define CPCAP_REG_CRM_VCHRG_4V42 CPCAP_REG_CRM_VCHRG(0xe) ··· 262 262 bool enable; 263 263 int error; 264 264 265 - enable = max_voltage && (charge_current || trickle_current); 265 + enable = (charge_current || trickle_current); 266 266 dev_dbg(ddata->dev, "%s enable: %i\n", __func__, enable); 267 267 268 268 if (!enable) { ··· 433 433 max_current = CPCAP_REG_CRM_ICHRG_0A528; 434 434 435 435 error = cpcap_charger_set_state(ddata, 436 - CPCAP_REG_CRM_VCHRG_4V20, 437 - max_current, 438 - CPCAP_REG_CRM_TR_0A72); 436 + CPCAP_REG_CRM_VCHRG_4V35, 437 + max_current, 0); 439 438 if (error) 440 439 goto out_err; 441 440 } else { ··· 565 566 } 566 567 567 568 static const struct power_supply_desc cpcap_charger_usb_desc = { 568 - .name = "cpcap_usb", 569 + .name = "usb", 569 570 .type = POWER_SUPPLY_TYPE_USB, 570 571 .properties = cpcap_charger_props, 571 572 .num_properties = ARRAY_SIZE(cpcap_charger_props),
+4 -13
drivers/power/supply/generic-adc-battery.c
··· 383 383 return 0; 384 384 } 385 385 386 - #ifdef CONFIG_PM 387 - static int gab_suspend(struct device *dev) 386 + static int __maybe_unused gab_suspend(struct device *dev) 388 387 { 389 388 struct gab *adc_bat = dev_get_drvdata(dev); 390 389 ··· 392 393 return 0; 393 394 } 394 395 395 - static int gab_resume(struct device *dev) 396 + static int __maybe_unused gab_resume(struct device *dev) 396 397 { 397 398 struct gab *adc_bat = dev_get_drvdata(dev); 398 399 struct gab_platform_data *pdata = adc_bat->pdata; ··· 406 407 return 0; 407 408 } 408 409 409 - static const struct dev_pm_ops gab_pm_ops = { 410 - .suspend = gab_suspend, 411 - .resume = gab_resume, 412 - }; 413 - 414 - #define GAB_PM_OPS (&gab_pm_ops) 415 - #else 416 - #define GAB_PM_OPS (NULL) 417 - #endif 410 + static SIMPLE_DEV_PM_OPS(gab_pm_ops, gab_suspend, gab_resume); 418 411 419 412 static struct platform_driver gab_driver = { 420 413 .driver = { 421 414 .name = "generic-adc-battery", 422 - .pm = GAB_PM_OPS 415 + .pm = &gab_pm_ops, 423 416 }, 424 417 .probe = gab_probe, 425 418 .remove = gab_remove,
+4
drivers/power/supply/isp1704_charger.c
··· 418 418 419 419 pdata = devm_kzalloc(&pdev->dev, 420 420 sizeof(struct isp1704_charger_data), GFP_KERNEL); 421 + if (!pdata) { 422 + ret = -ENOMEM; 423 + goto fail0; 424 + } 421 425 pdata->enable_gpio = gpio; 422 426 423 427 dev_info(&pdev->dev, "init gpio %d\n", pdata->enable_gpio);
+150 -31
drivers/power/supply/max17042_battery.c
··· 76 76 }; 77 77 78 78 static enum power_supply_property max17042_battery_props[] = { 79 + POWER_SUPPLY_PROP_STATUS, 79 80 POWER_SUPPLY_PROP_PRESENT, 81 + POWER_SUPPLY_PROP_TECHNOLOGY, 80 82 POWER_SUPPLY_PROP_CYCLE_COUNT, 81 83 POWER_SUPPLY_PROP_VOLTAGE_MAX, 84 + POWER_SUPPLY_PROP_VOLTAGE_MIN, 82 85 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, 83 86 POWER_SUPPLY_PROP_VOLTAGE_NOW, 84 87 POWER_SUPPLY_PROP_VOLTAGE_AVG, 85 88 POWER_SUPPLY_PROP_VOLTAGE_OCV, 86 89 POWER_SUPPLY_PROP_CAPACITY, 90 + POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, 87 91 POWER_SUPPLY_PROP_CHARGE_FULL, 92 + POWER_SUPPLY_PROP_CHARGE_NOW, 88 93 POWER_SUPPLY_PROP_CHARGE_COUNTER, 89 94 POWER_SUPPLY_PROP_TEMP, 90 95 POWER_SUPPLY_PROP_TEMP_ALERT_MIN, ··· 97 92 POWER_SUPPLY_PROP_TEMP_MIN, 98 93 POWER_SUPPLY_PROP_TEMP_MAX, 99 94 POWER_SUPPLY_PROP_HEALTH, 95 + POWER_SUPPLY_PROP_SCOPE, 100 96 POWER_SUPPLY_PROP_CURRENT_NOW, 101 97 POWER_SUPPLY_PROP_CURRENT_AVG, 102 98 }; ··· 112 106 if (ret < 0) 113 107 return ret; 114 108 115 - *temp = data; 116 - /* The value is signed. */ 117 - if (*temp & 0x8000) { 118 - *temp = (0x7fff & ~*temp) + 1; 119 - *temp *= -1; 120 - } 121 - 109 + *temp = sign_extend32(data, 15); 122 110 /* The value is converted into deci-centigrade scale */ 123 111 /* Units of LSB = 1 / 256 degree Celsius */ 124 112 *temp = *temp * 10 / 256; 113 + return 0; 114 + } 115 + 116 + static int max17042_get_status(struct max17042_chip *chip, int *status) 117 + { 118 + int ret, charge_full, charge_now; 119 + 120 + ret = power_supply_am_i_supplied(chip->battery); 121 + if (ret < 0) { 122 + *status = POWER_SUPPLY_STATUS_UNKNOWN; 123 + return 0; 124 + } 125 + if (ret == 0) { 126 + *status = POWER_SUPPLY_STATUS_DISCHARGING; 127 + return 0; 128 + } 129 + 130 + /* 131 + * The MAX170xx has builtin end-of-charge detection and will update 132 + * FullCAP to match RepCap when it detects end of charging. 133 + * 134 + * When this cycle the battery gets charged to a higher (calculated) 135 + * capacity then the previous cycle then FullCAP will get updated 136 + * contineously once end-of-charge detection kicks in, so allow the 137 + * 2 to differ a bit. 138 + */ 139 + 140 + ret = regmap_read(chip->regmap, MAX17042_FullCAP, &charge_full); 141 + if (ret < 0) 142 + return ret; 143 + 144 + ret = regmap_read(chip->regmap, MAX17042_RepCap, &charge_now); 145 + if (ret < 0) 146 + return ret; 147 + 148 + if ((charge_full - charge_now) <= MAX17042_FULL_THRESHOLD) 149 + *status = POWER_SUPPLY_STATUS_FULL; 150 + else 151 + *status = POWER_SUPPLY_STATUS_CHARGING; 152 + 125 153 return 0; 126 154 } 127 155 ··· 196 156 if (ret < 0) 197 157 goto health_error; 198 158 199 - if (temp <= chip->pdata->temp_min) { 159 + if (temp < chip->pdata->temp_min) { 200 160 *health = POWER_SUPPLY_HEALTH_COLD; 201 161 goto out; 202 162 } 203 163 204 - if (temp >= chip->pdata->temp_max) { 164 + if (temp > chip->pdata->temp_max) { 205 165 *health = POWER_SUPPLY_HEALTH_OVERHEAT; 206 166 goto out; 207 167 } ··· 223 183 struct regmap *map = chip->regmap; 224 184 int ret; 225 185 u32 data; 186 + u64 data64; 226 187 227 188 if (!chip->init_complete) 228 189 return -EAGAIN; 229 190 230 191 switch (psp) { 192 + case POWER_SUPPLY_PROP_STATUS: 193 + ret = max17042_get_status(chip, &val->intval); 194 + if (ret < 0) 195 + return ret; 196 + break; 231 197 case POWER_SUPPLY_PROP_PRESENT: 232 198 ret = regmap_read(map, MAX17042_STATUS, &data); 233 199 if (ret < 0) ··· 243 197 val->intval = 0; 244 198 else 245 199 val->intval = 1; 200 + break; 201 + case POWER_SUPPLY_PROP_TECHNOLOGY: 202 + val->intval = POWER_SUPPLY_TECHNOLOGY_LION; 246 203 break; 247 204 case POWER_SUPPLY_PROP_CYCLE_COUNT: 248 205 ret = regmap_read(map, MAX17042_Cycles, &data); ··· 261 212 262 213 val->intval = data >> 8; 263 214 val->intval *= 20000; /* Units of LSB = 20mV */ 215 + break; 216 + case POWER_SUPPLY_PROP_VOLTAGE_MIN: 217 + ret = regmap_read(map, MAX17042_MinMaxVolt, &data); 218 + if (ret < 0) 219 + return ret; 220 + 221 + val->intval = (data & 0xff) * 20000; /* Units of 20mV */ 264 222 break; 265 223 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: 266 224 if (chip->chip_type == MAXIM_DEVICE_TYPE_MAX17042) ··· 308 252 309 253 val->intval = data >> 8; 310 254 break; 255 + case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: 256 + ret = regmap_read(map, MAX17042_DesignCap, &data); 257 + if (ret < 0) 258 + return ret; 259 + 260 + data64 = data * 5000000ll; 261 + do_div(data64, chip->pdata->r_sns); 262 + val->intval = data64; 263 + break; 311 264 case POWER_SUPPLY_PROP_CHARGE_FULL: 312 265 ret = regmap_read(map, MAX17042_FullCAP, &data); 313 266 if (ret < 0) 314 267 return ret; 315 268 316 - val->intval = data * 1000 / 2; 269 + data64 = data * 5000000ll; 270 + do_div(data64, chip->pdata->r_sns); 271 + val->intval = data64; 272 + break; 273 + case POWER_SUPPLY_PROP_CHARGE_NOW: 274 + ret = regmap_read(map, MAX17042_RepCap, &data); 275 + if (ret < 0) 276 + return ret; 277 + 278 + data64 = data * 5000000ll; 279 + do_div(data64, chip->pdata->r_sns); 280 + val->intval = data64; 317 281 break; 318 282 case POWER_SUPPLY_PROP_CHARGE_COUNTER: 319 283 ret = regmap_read(map, MAX17042_QH, &data); ··· 352 276 if (ret < 0) 353 277 return ret; 354 278 /* LSB is Alert Minimum. In deci-centigrade */ 355 - val->intval = (data & 0xff) * 10; 279 + val->intval = sign_extend32(data & 0xff, 7) * 10; 356 280 break; 357 281 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX: 358 282 ret = regmap_read(map, MAX17042_TALRT_Th, &data); 359 283 if (ret < 0) 360 284 return ret; 361 285 /* MSB is Alert Maximum. In deci-centigrade */ 362 - val->intval = (data >> 8) * 10; 286 + val->intval = sign_extend32(data >> 8, 7) * 10; 363 287 break; 364 288 case POWER_SUPPLY_PROP_TEMP_MIN: 365 289 val->intval = chip->pdata->temp_min; ··· 372 296 if (ret < 0) 373 297 return ret; 374 298 break; 299 + case POWER_SUPPLY_PROP_SCOPE: 300 + val->intval = POWER_SUPPLY_SCOPE_SYSTEM; 301 + break; 375 302 case POWER_SUPPLY_PROP_CURRENT_NOW: 376 303 if (chip->pdata->enable_current_sense) { 377 304 ret = regmap_read(map, MAX17042_Current, &data); 378 305 if (ret < 0) 379 306 return ret; 380 307 381 - val->intval = data; 382 - if (val->intval & 0x8000) { 383 - /* Negative */ 384 - val->intval = ~val->intval & 0x7fff; 385 - val->intval++; 386 - val->intval *= -1; 387 - } 308 + val->intval = sign_extend32(data, 15); 388 309 val->intval *= 1562500 / chip->pdata->r_sns; 389 310 } else { 390 311 return -EINVAL; ··· 393 320 if (ret < 0) 394 321 return ret; 395 322 396 - val->intval = data; 397 - if (val->intval & 0x8000) { 398 - /* Negative */ 399 - val->intval = ~val->intval & 0x7fff; 400 - val->intval++; 401 - val->intval *= -1; 402 - } 323 + val->intval = sign_extend32(data, 15); 403 324 val->intval *= 1562500 / chip->pdata->r_sns; 404 325 } else { 405 326 return -EINVAL; ··· 466 399 } 467 400 468 401 return ret; 402 + } 403 + 404 + static void max17042_external_power_changed(struct power_supply *psy) 405 + { 406 + power_supply_changed(psy); 469 407 } 470 408 471 409 static int max17042_write_verify_reg(struct regmap *map, u8 reg, u32 value) ··· 862 790 863 791 #ifdef CONFIG_OF 864 792 static struct max17042_platform_data * 865 - max17042_get_pdata(struct device *dev) 793 + max17042_get_pdata(struct max17042_chip *chip) 866 794 { 795 + struct device *dev = &chip->client->dev; 867 796 struct device_node *np = dev->of_node; 868 797 u32 prop; 869 798 struct max17042_platform_data *pdata; ··· 897 824 return pdata; 898 825 } 899 826 #else 827 + static struct max17042_reg_data max17047_default_pdata_init_regs[] = { 828 + /* 829 + * Some firmwares do not set FullSOCThr, Enable End-of-Charge Detection 830 + * when the voltage FG reports 95%, as recommended in the datasheet. 831 + */ 832 + { MAX17047_FullSOCThr, MAX17042_BATTERY_FULL << 8 }, 833 + }; 834 + 900 835 static struct max17042_platform_data * 901 - max17042_get_pdata(struct device *dev) 836 + max17042_get_pdata(struct max17042_chip *chip) 902 837 { 903 - return dev->platform_data; 838 + struct device *dev = &chip->client->dev; 839 + struct max17042_platform_data *pdata; 840 + int ret, misc_cfg; 841 + 842 + if (dev->platform_data) 843 + return dev->platform_data; 844 + 845 + /* 846 + * The MAX17047 gets used on x86 where we might not have pdata, assume 847 + * the firmware will already have initialized the fuel-gauge and provide 848 + * default values for the non init bits to make things work. 849 + */ 850 + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); 851 + if (!pdata) 852 + return pdata; 853 + 854 + if (chip->chip_type != MAXIM_DEVICE_TYPE_MAX17042) { 855 + pdata->init_data = max17047_default_pdata_init_regs; 856 + pdata->num_init_data = 857 + ARRAY_SIZE(max17047_default_pdata_init_regs); 858 + } 859 + 860 + ret = regmap_read(chip->regmap, MAX17042_MiscCFG, &misc_cfg); 861 + if (ret < 0) 862 + return NULL; 863 + 864 + /* If bits 0-1 are set to 3 then only Voltage readings are used */ 865 + if ((misc_cfg & 0x3) == 0x3) 866 + pdata->enable_current_sense = false; 867 + else 868 + pdata->enable_current_sense = true; 869 + 870 + pdata->vmin = MAX17042_DEFAULT_VMIN; 871 + pdata->vmax = MAX17042_DEFAULT_VMAX; 872 + pdata->temp_min = MAX17042_DEFAULT_TEMP_MIN; 873 + pdata->temp_max = MAX17042_DEFAULT_TEMP_MAX; 874 + 875 + return pdata; 904 876 } 905 877 #endif 906 878 ··· 961 843 .get_property = max17042_get_property, 962 844 .set_property = max17042_set_property, 963 845 .property_is_writeable = max17042_property_is_writeable, 846 + .external_power_changed = max17042_external_power_changed, 964 847 .properties = max17042_battery_props, 965 848 .num_properties = ARRAY_SIZE(max17042_battery_props), 966 849 }; ··· 995 876 return -ENOMEM; 996 877 997 878 chip->client = client; 879 + chip->chip_type = id->driver_data; 998 880 chip->regmap = devm_regmap_init_i2c(client, &max17042_regmap_config); 999 881 if (IS_ERR(chip->regmap)) { 1000 882 dev_err(&client->dev, "Failed to initialize regmap\n"); 1001 883 return -EINVAL; 1002 884 } 1003 885 1004 - chip->pdata = max17042_get_pdata(&client->dev); 886 + chip->pdata = max17042_get_pdata(chip); 1005 887 if (!chip->pdata) { 1006 888 dev_err(&client->dev, "no platform data provided\n"); 1007 889 return -EINVAL; 1008 890 } 1009 891 1010 892 i2c_set_clientdata(client, chip); 1011 - chip->chip_type = id->driver_data; 1012 893 psy_cfg.drv_data = chip; 1013 894 1014 895 /* When current is not measured,
+27 -22
drivers/power/supply/pda_power.c
··· 30 30 static struct device *dev; 31 31 static struct pda_power_pdata *pdata; 32 32 static struct resource *ac_irq, *usb_irq; 33 - static struct timer_list charger_timer; 34 - static struct timer_list supply_timer; 35 - static struct timer_list polling_timer; 33 + static struct delayed_work charger_work; 34 + static struct delayed_work polling_work; 35 + static struct delayed_work supply_work; 36 36 static int polling; 37 37 static struct power_supply *pda_psy_ac, *pda_psy_usb; 38 38 ··· 140 140 } 141 141 } 142 142 143 - static void supply_timer_func(unsigned long unused) 143 + static void supply_work_func(struct work_struct *work) 144 144 { 145 145 if (ac_status == PDA_PSY_TO_CHANGE) { 146 146 ac_status = new_ac_status; ··· 161 161 * Okay, charger set. Now wait a bit before notifying supplicants, 162 162 * charge power should stabilize. 163 163 */ 164 - mod_timer(&supply_timer, 165 - jiffies + msecs_to_jiffies(pdata->wait_for_charger)); 164 + cancel_delayed_work(&supply_work); 165 + schedule_delayed_work(&supply_work, 166 + msecs_to_jiffies(pdata->wait_for_charger)); 166 167 } 167 168 168 - static void charger_timer_func(unsigned long unused) 169 + static void charger_work_func(struct work_struct *work) 169 170 { 170 171 update_status(); 171 172 psy_changed(); ··· 185 184 * Wait a bit before reading ac/usb line status and setting charger, 186 185 * because ac/usb status readings may lag from irq. 187 186 */ 188 - mod_timer(&charger_timer, 189 - jiffies + msecs_to_jiffies(pdata->wait_for_status)); 187 + cancel_delayed_work(&charger_work); 188 + schedule_delayed_work(&charger_work, 189 + msecs_to_jiffies(pdata->wait_for_status)); 190 190 191 191 return IRQ_HANDLED; 192 192 } 193 193 194 - static void polling_timer_func(unsigned long unused) 194 + static void polling_work_func(struct work_struct *work) 195 195 { 196 196 int changed = 0; 197 197 ··· 213 211 if (changed) 214 212 psy_changed(); 215 213 216 - mod_timer(&polling_timer, 217 - jiffies + msecs_to_jiffies(pdata->polling_interval)); 214 + cancel_delayed_work(&polling_work); 215 + schedule_delayed_work(&polling_work, 216 + msecs_to_jiffies(pdata->polling_interval)); 218 217 } 219 218 220 219 #if IS_ENABLED(CONFIG_USB_PHY) ··· 253 250 * Wait a bit before reading ac/usb line status and setting charger, 254 251 * because ac/usb status readings may lag from irq. 255 252 */ 256 - mod_timer(&charger_timer, 257 - jiffies + msecs_to_jiffies(pdata->wait_for_status)); 253 + cancel_delayed_work(&charger_work); 254 + schedule_delayed_work(&charger_work, 255 + msecs_to_jiffies(pdata->wait_for_status)); 258 256 259 257 return NOTIFY_OK; 260 258 } ··· 304 300 if (!pdata->ac_max_uA) 305 301 pdata->ac_max_uA = 500000; 306 302 307 - setup_timer(&charger_timer, charger_timer_func, 0); 308 - setup_timer(&supply_timer, supply_timer_func, 0); 303 + INIT_DELAYED_WORK(&charger_work, charger_work_func); 304 + INIT_DELAYED_WORK(&supply_work, supply_work_func); 309 305 310 306 ac_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ac"); 311 307 usb_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "usb"); ··· 389 385 390 386 if (polling) { 391 387 dev_dbg(dev, "will poll for status\n"); 392 - setup_timer(&polling_timer, polling_timer_func, 0); 393 - mod_timer(&polling_timer, 394 - jiffies + msecs_to_jiffies(pdata->polling_interval)); 388 + INIT_DELAYED_WORK(&polling_work, polling_work_func); 389 + cancel_delayed_work(&polling_work); 390 + schedule_delayed_work(&polling_work, 391 + msecs_to_jiffies(pdata->polling_interval)); 395 392 } 396 393 397 394 if (ac_irq || usb_irq) ··· 438 433 free_irq(ac_irq->start, pda_psy_ac); 439 434 440 435 if (polling) 441 - del_timer_sync(&polling_timer); 442 - del_timer_sync(&charger_timer); 443 - del_timer_sync(&supply_timer); 436 + cancel_delayed_work_sync(&polling_work); 437 + cancel_delayed_work_sync(&charger_work); 438 + cancel_delayed_work_sync(&supply_work); 444 439 445 440 if (pdata->is_usb_online) 446 441 power_supply_unregister(pda_psy_usb);
+15 -5
drivers/power/supply/power_supply_core.c
··· 280 280 } 281 281 #endif 282 282 283 - static int __power_supply_am_i_supplied(struct device *dev, void *data) 283 + struct psy_am_i_supplied_data { 284 + struct power_supply *psy; 285 + unsigned int count; 286 + }; 287 + 288 + static int __power_supply_am_i_supplied(struct device *dev, void *_data) 284 289 { 285 290 union power_supply_propval ret = {0,}; 286 - struct power_supply *psy = data; 287 291 struct power_supply *epsy = dev_get_drvdata(dev); 292 + struct psy_am_i_supplied_data *data = _data; 288 293 289 - if (__power_supply_is_supplied_by(epsy, psy)) 294 + data->count++; 295 + if (__power_supply_is_supplied_by(epsy, data->psy)) 290 296 if (!epsy->desc->get_property(epsy, POWER_SUPPLY_PROP_ONLINE, 291 297 &ret)) 292 298 return ret.intval; ··· 302 296 303 297 int power_supply_am_i_supplied(struct power_supply *psy) 304 298 { 299 + struct psy_am_i_supplied_data data = { psy, 0 }; 305 300 int error; 306 301 307 - error = class_for_each_device(power_supply_class, NULL, psy, 302 + error = class_for_each_device(power_supply_class, NULL, &data, 308 303 __power_supply_am_i_supplied); 309 304 310 - dev_dbg(&psy->dev, "%s %d\n", __func__, error); 305 + dev_dbg(&psy->dev, "%s count %u err %d\n", __func__, data.count, error); 306 + 307 + if (data.count == 0) 308 + return -ENODEV; 311 309 312 310 return error; 313 311 }
-1
drivers/power/supply/rx51_battery.c
··· 23 23 #include <linux/platform_device.h> 24 24 #include <linux/power_supply.h> 25 25 #include <linux/slab.h> 26 - #include <linux/i2c/twl4030-madc.h> 27 26 #include <linux/iio/consumer.h> 28 27 #include <linux/of.h> 29 28
+43 -14
drivers/power/supply/sbs-battery.c
··· 171 171 u32 i2c_retry_count; 172 172 u32 poll_retry_count; 173 173 struct delayed_work work; 174 - int ignore_changes; 175 174 }; 176 175 177 176 static char model_name[I2C_SMBUS_BLOCK_MAX + 1]; ··· 295 296 return 0; 296 297 } 297 298 299 + static int sbs_status_correct(struct i2c_client *client, int *intval) 300 + { 301 + int ret; 302 + 303 + ret = sbs_read_word_data(client, sbs_data[REG_CURRENT].addr); 304 + if (ret < 0) 305 + return ret; 306 + 307 + ret = (s16)ret; 308 + 309 + /* Not drawing current means full (cannot be not charging) */ 310 + if (ret == 0) 311 + *intval = POWER_SUPPLY_STATUS_FULL; 312 + 313 + if (*intval == POWER_SUPPLY_STATUS_FULL) { 314 + /* Drawing or providing current when full */ 315 + if (ret > 0) 316 + *intval = POWER_SUPPLY_STATUS_CHARGING; 317 + else if (ret < 0) 318 + *intval = POWER_SUPPLY_STATUS_DISCHARGING; 319 + } 320 + 321 + return 0; 322 + } 323 + 298 324 static int sbs_get_battery_presence_and_health( 299 325 struct i2c_client *client, enum power_supply_property psp, 300 326 union power_supply_propval *val) ··· 425 401 val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 426 402 else 427 403 val->intval = POWER_SUPPLY_STATUS_CHARGING; 404 + 405 + sbs_status_correct(client, &val->intval); 428 406 429 407 if (chip->poll_time == 0) 430 408 chip->last_state = val->intval; ··· 701 675 return 0; 702 676 } 703 677 704 - static irqreturn_t sbs_irq(int irq, void *devid) 678 + static void sbs_supply_changed(struct sbs_info *chip) 705 679 { 706 - struct sbs_info *chip = devid; 707 680 struct power_supply *battery = chip->power_supply; 708 681 int ret; 709 682 710 683 ret = gpiod_get_value_cansleep(chip->gpio_detect); 711 684 if (ret < 0) 712 - return ret; 685 + return; 713 686 chip->is_present = ret; 714 687 power_supply_changed(battery); 688 + } 715 689 690 + static irqreturn_t sbs_irq(int irq, void *devid) 691 + { 692 + sbs_supply_changed(devid); 716 693 return IRQ_HANDLED; 694 + } 695 + 696 + static void sbs_alert(struct i2c_client *client, enum i2c_alert_protocol prot, 697 + unsigned int data) 698 + { 699 + sbs_supply_changed(i2c_get_clientdata(client)); 717 700 } 718 701 719 702 static void sbs_external_power_changed(struct power_supply *psy) 720 703 { 721 704 struct sbs_info *chip = power_supply_get_drvdata(psy); 722 - 723 - if (chip->ignore_changes > 0) { 724 - chip->ignore_changes--; 725 - return; 726 - } 727 705 728 706 /* cancel outstanding work */ 729 707 cancel_delayed_work_sync(&chip->work); ··· 756 726 ret = POWER_SUPPLY_STATUS_DISCHARGING; 757 727 else 758 728 ret = POWER_SUPPLY_STATUS_CHARGING; 729 + 730 + sbs_status_correct(chip->client, &ret); 759 731 760 732 if (chip->last_state != ret) { 761 733 chip->poll_time = 0; ··· 807 775 chip->enable_detection = false; 808 776 psy_cfg.of_node = client->dev.of_node; 809 777 psy_cfg.drv_data = chip; 810 - /* ignore first notification of external change, it is generated 811 - * from the power_supply_register call back 812 - */ 813 - chip->ignore_changes = 1; 814 778 chip->last_state = POWER_SUPPLY_STATUS_UNKNOWN; 815 779 816 780 /* use pdata if available, fall back to DT properties, ··· 848 820 } 849 821 850 822 rc = devm_request_threaded_irq(&client->dev, irq, NULL, sbs_irq, 851 - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 823 + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 852 824 dev_name(&client->dev), chip); 853 825 if (rc) { 854 826 dev_warn(&client->dev, "Failed to request irq: %d\n", rc); ··· 945 917 static struct i2c_driver sbs_battery_driver = { 946 918 .probe = sbs_probe, 947 919 .remove = sbs_remove, 920 + .alert = sbs_alert, 948 921 .id_table = sbs_id, 949 922 .driver = { 950 923 .name = "sbs-battery",
+59 -36
drivers/power/supply/twl4030_charger.c
··· 206 206 } 207 207 208 208 /* 209 - * Check if Battery Pack was present 210 - */ 211 - static int twl4030_is_battery_present(struct twl4030_bci *bci) 212 - { 213 - int ret; 214 - u8 val = 0; 215 - 216 - /* Battery presence in Main charge? */ 217 - ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE, &val, TWL4030_BCIMFSTS3); 218 - if (ret) 219 - return ret; 220 - if (val & TWL4030_BATSTSMCHG) 221 - return 0; 222 - 223 - /* 224 - * OK, It could be that bootloader did not enable main charger, 225 - * pre-charge is h/w auto. So, Battery presence in Pre-charge? 226 - */ 227 - ret = twl_i2c_read_u8(TWL4030_MODULE_PRECHARGE, &val, 228 - TWL4030_BCIMFSTS1); 229 - if (ret) 230 - return ret; 231 - if (val & TWL4030_BATSTSPCHG) 232 - return 0; 233 - 234 - return -ENODEV; 235 - } 236 - 237 - /* 238 209 * TI provided formulas: 239 210 * CGAIN == 0: ICHG = (BCIICHG * 1.7) / (2^10 - 1) - 0.85 240 211 * CGAIN == 1: ICHG = (BCIICHG * 3.4) / (2^10 - 1) - 1.7 ··· 893 922 twl4030_bci_state_to_status(state) != 894 923 POWER_SUPPLY_STATUS_NOT_CHARGING; 895 924 break; 925 + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 926 + val->intval = -1; 927 + if (psy->desc->type != POWER_SUPPLY_TYPE_USB) { 928 + if (!bci->ac_is_active) 929 + val->intval = bci->ac_cur; 930 + } else { 931 + if (bci->ac_is_active) 932 + val->intval = bci->usb_cur_target; 933 + } 934 + if (val->intval < 0) { 935 + u8 bcictl1; 936 + 937 + val->intval = twl4030bci_read_adc_val(TWL4030_BCIIREF1); 938 + if (val->intval < 0) 939 + return val->intval; 940 + ret = twl4030_bci_read(TWL4030_BCICTL1, &bcictl1); 941 + if (ret < 0) 942 + return ret; 943 + val->intval = regval2ua(val->intval, bcictl1 & 944 + TWL4030_CGAIN); 945 + } 946 + break; 896 947 default: 897 948 return -EINVAL; 898 949 } ··· 922 929 return 0; 923 930 } 924 931 932 + static int twl4030_bci_set_property(struct power_supply *psy, 933 + enum power_supply_property psp, 934 + const union power_supply_propval *val) 935 + { 936 + struct twl4030_bci *bci = dev_get_drvdata(psy->dev.parent); 937 + 938 + switch (psp) { 939 + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 940 + if (psy->desc->type == POWER_SUPPLY_TYPE_USB) 941 + bci->usb_cur_target = val->intval; 942 + else 943 + bci->ac_cur = val->intval; 944 + twl4030_charger_update_current(bci); 945 + break; 946 + default: 947 + return -EINVAL; 948 + } 949 + 950 + return 0; 951 + } 952 + 953 + static int twl4030_bci_property_is_writeable(struct power_supply *psy, 954 + enum power_supply_property psp) 955 + { 956 + switch (psp) { 957 + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 958 + return true; 959 + default: 960 + return false; 961 + } 962 + } 963 + 925 964 static enum power_supply_property twl4030_charger_props[] = { 926 965 POWER_SUPPLY_PROP_STATUS, 927 966 POWER_SUPPLY_PROP_ONLINE, 928 967 POWER_SUPPLY_PROP_VOLTAGE_NOW, 929 968 POWER_SUPPLY_PROP_CURRENT_NOW, 969 + POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, 930 970 }; 931 971 932 972 #ifdef CONFIG_OF ··· 996 970 .properties = twl4030_charger_props, 997 971 .num_properties = ARRAY_SIZE(twl4030_charger_props), 998 972 .get_property = twl4030_bci_get_property, 973 + .set_property = twl4030_bci_set_property, 974 + .property_is_writeable = twl4030_bci_property_is_writeable, 999 975 }; 1000 976 1001 977 static const struct power_supply_desc twl4030_bci_usb_desc = { ··· 1006 978 .properties = twl4030_charger_props, 1007 979 .num_properties = ARRAY_SIZE(twl4030_charger_props), 1008 980 .get_property = twl4030_bci_get_property, 981 + .set_property = twl4030_bci_set_property, 982 + .property_is_writeable = twl4030_bci_property_is_writeable, 1009 983 }; 1010 984 1011 985 static int twl4030_bci_probe(struct platform_device *pdev) ··· 1038 1008 bci->dev = &pdev->dev; 1039 1009 bci->irq_chg = platform_get_irq(pdev, 0); 1040 1010 bci->irq_bci = platform_get_irq(pdev, 1); 1041 - 1042 - /* Only proceed further *IF* battery is physically present */ 1043 - ret = twl4030_is_battery_present(bci); 1044 - if (ret) { 1045 - dev_crit(&pdev->dev, "Battery was not detected:%d\n", ret); 1046 - return ret; 1047 - } 1048 1011 1049 1012 platform_set_drvdata(pdev, bci); 1050 1013
-1
drivers/power/supply/twl4030_madc_battery.c
··· 17 17 #include <linux/power_supply.h> 18 18 #include <linux/slab.h> 19 19 #include <linux/sort.h> 20 - #include <linux/i2c/twl4030-madc.h> 21 20 #include <linux/power/twl4030_madc_battery.h> 22 21 #include <linux/iio/consumer.h> 23 22
+8 -1
include/linux/power/max17042_battery.h
··· 24 24 #define __MAX17042_BATTERY_H_ 25 25 26 26 #define MAX17042_STATUS_BattAbsent (1 << 3) 27 - #define MAX17042_BATTERY_FULL (100) 27 + #define MAX17042_BATTERY_FULL (95) /* Recommend. FullSOCThr value */ 28 28 #define MAX17042_DEFAULT_SNS_RESISTOR (10000) 29 + #define MAX17042_DEFAULT_VMIN (3000) 30 + #define MAX17042_DEFAULT_VMAX (4500) /* LiHV cell max */ 31 + #define MAX17042_DEFAULT_TEMP_MIN (0) /* For sys without temp sensor */ 32 + #define MAX17042_DEFAULT_TEMP_MAX (700) /* 70 degrees Celcius */ 33 + 34 + /* Consider RepCap which is less then 10 units below FullCAP full */ 35 + #define MAX17042_FULL_THRESHOLD 10 29 36 30 37 #define MAX17042_CHARACTERIZATION_DATA_SIZE 48 31 38