Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

charger: max14577: Configure battery-dependent settings from DTS and sysfs

Remove hard-coded values for:
- Fast Charge current,
- End Of Charge current,
- Fast Charge timer,
- Overvoltage Protection Threshold,
- Battery Constant Voltage,
and use DTS or sysfs to configure them. This allows using the max14577 charger
driver with different batteries.

Now the charger driver requires valid configuration data from DTS. In
case of wrong configuration data it fails during probe.

The fast charge timer is configured through sysfs entry.

Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Acked-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Lee Jones <lee.jones@linaro.org>

authored by

Krzysztof Kozlowski and committed by
Lee Jones
e30110e9 b8f139f6

+311 -29
+1
drivers/power/Kconfig
··· 327 327 config CHARGER_MAX14577 328 328 tristate "Maxim MAX14577/77836 battery charger driver" 329 329 depends on MFD_MAX14577 330 + select SYSFS 330 331 help 331 332 Say Y to enable support for the battery charger control sysfs and 332 333 platform data of MAX14577/77836 MUICs.
+284 -29
drivers/power/max14577_charger.c
··· 19 19 #include <linux/platform_device.h> 20 20 #include <linux/power_supply.h> 21 21 #include <linux/mfd/max14577-private.h> 22 + #include <linux/mfd/max14577.h> 22 23 23 24 struct max14577_charger { 24 25 struct device *dev; ··· 28 27 29 28 unsigned int charging_state; 30 29 unsigned int battery_state; 30 + 31 + struct max14577_charger_platform_data *pdata; 31 32 }; 32 33 33 34 /* ··· 181 178 return 1; 182 179 } 183 180 181 + static int max14577_set_fast_charge_timer(struct max14577_charger *chg, 182 + unsigned long hours) 183 + { 184 + u8 reg_data; 185 + 186 + switch (hours) { 187 + case 5 ... 7: 188 + reg_data = hours - 3; 189 + break; 190 + case 0: 191 + /* Disable */ 192 + reg_data = 0x7; 193 + break; 194 + default: 195 + dev_err(chg->dev, "Wrong value for Fast-Charge Timer: %lu\n", 196 + hours); 197 + return -EINVAL; 198 + } 199 + reg_data <<= CHGCTRL1_TCHW_SHIFT; 200 + 201 + return max14577_update_reg(chg->max14577->regmap, 202 + MAX14577_REG_CHGCTRL1, CHGCTRL1_TCHW_MASK, reg_data); 203 + } 204 + 205 + static int max14577_init_constant_voltage(struct max14577_charger *chg, 206 + unsigned int uvolt) 207 + { 208 + u8 reg_data; 209 + 210 + if (uvolt < MAXIM_CHARGER_CONSTANT_VOLTAGE_MIN || 211 + uvolt > MAXIM_CHARGER_CONSTANT_VOLTAGE_MAX) 212 + return -EINVAL; 213 + 214 + if (uvolt == 4200000) 215 + reg_data = 0x0; 216 + else if (uvolt == MAXIM_CHARGER_CONSTANT_VOLTAGE_MAX) 217 + reg_data = 0x1f; 218 + else if (uvolt <= 4280000) { 219 + unsigned int val = uvolt; 220 + 221 + val -= MAXIM_CHARGER_CONSTANT_VOLTAGE_MIN; 222 + val /= MAXIM_CHARGER_CONSTANT_VOLTAGE_STEP; 223 + if (uvolt <= 4180000) 224 + reg_data = 0x1 + val; 225 + else 226 + reg_data = val; /* Fix for gap between 4.18V and 4.22V */ 227 + } else 228 + return -EINVAL; 229 + 230 + reg_data <<= CHGCTRL3_MBCCVWRC_SHIFT; 231 + 232 + return max14577_write_reg(chg->max14577->regmap, 233 + MAX14577_CHG_REG_CHG_CTRL3, reg_data); 234 + } 235 + 236 + static int max14577_init_eoc(struct max14577_charger *chg, 237 + unsigned int uamp) 238 + { 239 + unsigned int current_bits = 0xf; 240 + u8 reg_data; 241 + 242 + switch (chg->max14577->dev_type) { 243 + case MAXIM_DEVICE_TYPE_MAX77836: 244 + if (uamp < 5000) 245 + return -EINVAL; /* Requested current is too low */ 246 + 247 + if (uamp >= 7500 && uamp < 10000) 248 + current_bits = 0x0; 249 + else if (uamp <= 50000) { 250 + /* <5000, 7499> and <10000, 50000> */ 251 + current_bits = uamp / 5000; 252 + } else { 253 + uamp = min(uamp, 100000U) - 50000U; 254 + current_bits = 0xa + uamp / 10000; 255 + } 256 + break; 257 + 258 + case MAXIM_DEVICE_TYPE_MAX14577: 259 + default: 260 + if (uamp < MAX14577_CHARGER_EOC_CURRENT_LIMIT_MIN) 261 + return -EINVAL; /* Requested current is too low */ 262 + 263 + uamp = min(uamp, MAX14577_CHARGER_EOC_CURRENT_LIMIT_MAX); 264 + uamp -= MAX14577_CHARGER_EOC_CURRENT_LIMIT_MIN; 265 + current_bits = uamp / MAX14577_CHARGER_EOC_CURRENT_LIMIT_STEP; 266 + break; 267 + } 268 + 269 + reg_data = current_bits << CHGCTRL5_EOCS_SHIFT; 270 + 271 + return max14577_update_reg(chg->max14577->regmap, 272 + MAX14577_CHG_REG_CHG_CTRL5, CHGCTRL5_EOCS_MASK, 273 + reg_data); 274 + } 275 + 276 + static int max14577_init_fast_charge(struct max14577_charger *chg, 277 + unsigned int uamp) 278 + { 279 + u8 reg_data; 280 + int ret; 281 + const struct maxim_charger_current *limits = 282 + &maxim_charger_currents[chg->max14577->dev_type]; 283 + 284 + ret = maxim_charger_calc_reg_current(limits, uamp, uamp, &reg_data); 285 + if (ret) { 286 + dev_err(chg->dev, "Wrong value for fast charge: %u\n", uamp); 287 + return ret; 288 + } 289 + 290 + return max14577_update_reg(chg->max14577->regmap, 291 + MAX14577_CHG_REG_CHG_CTRL4, 292 + CHGCTRL4_MBCICHWRCL_MASK | CHGCTRL4_MBCICHWRCH_MASK, 293 + reg_data); 294 + } 295 + 184 296 /* 185 297 * Sets charger registers to proper and safe default values. 186 298 * Some of these values are equal to defaults in MAX14577E 187 299 * data sheet but there are minor differences. 188 300 */ 189 - static void max14577_charger_reg_init(struct max14577_charger *chg) 301 + static int max14577_charger_reg_init(struct max14577_charger *chg) 190 302 { 191 303 struct regmap *rmap = chg->max14577->regmap; 192 304 u8 reg_data; 305 + int ret; 193 306 194 307 /* 195 308 * Charger-Type Manual Detection, default off (set CHGTYPMAN to 0) ··· 317 198 CDETCTRL1_CHGDETEN_MASK | CDETCTRL1_CHGTYPMAN_MASK, 318 199 reg_data); 319 200 320 - /* Battery Fast-Charge Timer, set to: 6hrs */ 321 - reg_data = 0x3 << CHGCTRL1_TCHW_SHIFT; 322 - max14577_write_reg(rmap, MAX14577_REG_CHGCTRL1, reg_data); 323 - 324 201 /* 325 202 * Wall-Adapter Rapid Charge, default on 326 203 * Battery-Charger, default on ··· 325 210 reg_data |= 0x1 << CHGCTRL2_MBCHOSTEN_SHIFT; 326 211 max14577_write_reg(rmap, MAX14577_REG_CHGCTRL2, reg_data); 327 212 328 - /* Battery-Charger Constant Voltage (CV) Mode, set to: 4.35V */ 329 - reg_data = 0xf << CHGCTRL3_MBCCVWRC_SHIFT; 330 - max14577_write_reg(rmap, MAX14577_REG_CHGCTRL3, reg_data); 331 - 332 - /* 333 - * Fast Battery-Charge Current Low, 334 - * default 200-950mA (max14577) / 100-475mA (max77836) 335 - * 336 - * Fast Battery-Charge Current High, 337 - * set to 450mA (max14577) / 225mA (max77836) 338 - */ 339 - reg_data = 0x1 << CHGCTRL4_MBCICHWRCL_SHIFT; 340 - reg_data |= 0x5 << CHGCTRL4_MBCICHWRCH_SHIFT; 341 - max14577_write_reg(rmap, MAX14577_REG_CHGCTRL4, reg_data); 342 - 343 - /* End-of-Charge Current, set to 50mA (max14577) / 7.5mA (max77836) */ 344 - reg_data = 0x0 << CHGCTRL5_EOCS_SHIFT; 345 - max14577_write_reg(rmap, MAX14577_REG_CHGCTRL5, reg_data); 346 - 347 213 /* Auto Charging Stop, default off */ 348 214 reg_data = 0x0 << CHGCTRL6_AUTOSTOP_SHIFT; 349 215 max14577_write_reg(rmap, MAX14577_REG_CHGCTRL6, reg_data); 350 216 351 - /* Overvoltage-Protection Threshold, set to 6.5V */ 352 - reg_data = 0x2 << CHGCTRL7_OTPCGHCVS_SHIFT; 217 + ret = max14577_init_constant_voltage(chg, chg->pdata->constant_uvolt); 218 + if (ret) 219 + return ret; 220 + 221 + ret = max14577_init_eoc(chg, chg->pdata->eoc_uamp); 222 + if (ret) 223 + return ret; 224 + 225 + ret = max14577_init_fast_charge(chg, chg->pdata->fast_charge_uamp); 226 + if (ret) 227 + return ret; 228 + 229 + ret = max14577_set_fast_charge_timer(chg, 230 + MAXIM_CHARGER_FAST_CHARGE_TIMER_DEFAULT); 231 + if (ret) 232 + return ret; 233 + 234 + /* Initialize Overvoltage-Protection Threshold */ 235 + switch (chg->pdata->ovp_uvolt) { 236 + case 7500000: 237 + reg_data = 0x0; 238 + break; 239 + case 6000000: 240 + case 6500000: 241 + case 7000000: 242 + reg_data = 0x1 + (chg->pdata->ovp_uvolt - 6000000) / 500000; 243 + break; 244 + default: 245 + dev_err(chg->dev, "Wrong value for OVP: %u\n", 246 + chg->pdata->ovp_uvolt); 247 + return -EINVAL; 248 + } 249 + reg_data <<= CHGCTRL7_OTPCGHCVS_SHIFT; 353 250 max14577_write_reg(rmap, MAX14577_REG_CHGCTRL7, reg_data); 251 + 252 + return 0; 354 253 } 355 254 356 255 /* Support property from charger */ ··· 424 295 return ret; 425 296 } 426 297 298 + #ifdef CONFIG_OF 299 + static struct max14577_charger_platform_data *max14577_charger_dt_init( 300 + struct platform_device *pdev) 301 + { 302 + struct max14577_charger_platform_data *pdata; 303 + struct device_node *np = pdev->dev.of_node; 304 + int ret; 305 + 306 + if (!np) { 307 + dev_err(&pdev->dev, "No charger OF node\n"); 308 + return ERR_PTR(-EINVAL); 309 + } 310 + 311 + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 312 + if (!pdata) 313 + return ERR_PTR(-ENOMEM); 314 + 315 + ret = of_property_read_u32(np, "maxim,constant-uvolt", 316 + &pdata->constant_uvolt); 317 + if (ret) { 318 + dev_err(&pdev->dev, "Cannot parse maxim,constant-uvolt field from DT\n"); 319 + return ERR_PTR(ret); 320 + } 321 + 322 + ret = of_property_read_u32(np, "maxim,fast-charge-uamp", 323 + &pdata->fast_charge_uamp); 324 + if (ret) { 325 + dev_err(&pdev->dev, "Cannot parse maxim,fast-charge-uamp field from DT\n"); 326 + return ERR_PTR(ret); 327 + } 328 + 329 + ret = of_property_read_u32(np, "maxim,eoc-uamp", &pdata->eoc_uamp); 330 + if (ret) { 331 + dev_err(&pdev->dev, "Cannot parse maxim,eoc-uamp field from DT\n"); 332 + return ERR_PTR(ret); 333 + } 334 + 335 + ret = of_property_read_u32(np, "maxim,ovp-uvolt", &pdata->ovp_uvolt); 336 + if (ret) { 337 + dev_err(&pdev->dev, "Cannot parse maxim,ovp-uvolt field from DT\n"); 338 + return ERR_PTR(ret); 339 + } 340 + 341 + return pdata; 342 + } 343 + #else /* CONFIG_OF */ 344 + static struct max14577_charger_platform_data *max14577_charger_dt_init( 345 + struct platform_device *pdev) 346 + { 347 + return NULL; 348 + } 349 + #endif /* CONFIG_OF */ 350 + 351 + static ssize_t show_fast_charge_timer(struct device *dev, 352 + struct device_attribute *attr, char *buf) 353 + { 354 + struct max14577_charger *chg = dev_get_drvdata(dev); 355 + u8 reg_data; 356 + int ret; 357 + unsigned int val; 358 + 359 + ret = max14577_read_reg(chg->max14577->regmap, MAX14577_REG_CHGCTRL1, 360 + &reg_data); 361 + if (ret) 362 + return ret; 363 + 364 + reg_data &= CHGCTRL1_TCHW_MASK; 365 + reg_data >>= CHGCTRL1_TCHW_SHIFT; 366 + switch (reg_data) { 367 + case 0x2 ... 0x4: 368 + val = reg_data + 3; 369 + break; 370 + case 0x7: 371 + val = 0; 372 + break; 373 + default: 374 + val = 5; 375 + break; 376 + } 377 + 378 + return scnprintf(buf, PAGE_SIZE, "%u\n", val); 379 + } 380 + 381 + static ssize_t store_fast_charge_timer(struct device *dev, 382 + struct device_attribute *attr, const char *buf, size_t count) 383 + { 384 + struct max14577_charger *chg = dev_get_drvdata(dev); 385 + unsigned long val; 386 + int ret; 387 + 388 + ret = kstrtoul(buf, 10, &val); 389 + if (ret) 390 + return ret; 391 + 392 + ret = max14577_set_fast_charge_timer(chg, val); 393 + if (ret) 394 + return ret; 395 + 396 + return count; 397 + } 398 + 399 + static DEVICE_ATTR(fast_charge_timer, S_IRUGO | S_IWUSR, 400 + show_fast_charge_timer, store_fast_charge_timer); 401 + 427 402 static int max14577_charger_probe(struct platform_device *pdev) 428 403 { 429 404 struct max14577_charger *chg; ··· 542 309 chg->dev = &pdev->dev; 543 310 chg->max14577 = max14577; 544 311 545 - max14577_charger_reg_init(chg); 312 + chg->pdata = max14577_charger_dt_init(pdev); 313 + if (IS_ERR_OR_NULL(chg->pdata)) 314 + return PTR_ERR(chg->pdata); 315 + 316 + ret = max14577_charger_reg_init(chg); 317 + if (ret) 318 + return ret; 546 319 547 320 chg->charger.name = "max14577-charger", 548 321 chg->charger.type = POWER_SUPPLY_TYPE_BATTERY, ··· 556 317 chg->charger.num_properties = ARRAY_SIZE(max14577_charger_props), 557 318 chg->charger.get_property = max14577_charger_get_property, 558 319 559 - ret = power_supply_register(&pdev->dev, &chg->charger); 320 + ret = device_create_file(&pdev->dev, &dev_attr_fast_charge_timer); 560 321 if (ret) { 561 - dev_err(&pdev->dev, "failed: power supply register\n"); 322 + dev_err(&pdev->dev, "failed: create sysfs entry\n"); 562 323 return ret; 563 324 } 564 325 326 + ret = power_supply_register(&pdev->dev, &chg->charger); 327 + if (ret) { 328 + dev_err(&pdev->dev, "failed: power supply register\n"); 329 + goto err; 330 + } 331 + 332 + /* Check for valid values for charger */ 333 + BUILD_BUG_ON(MAX14577_CHARGER_EOC_CURRENT_LIMIT_MIN + 334 + MAX14577_CHARGER_EOC_CURRENT_LIMIT_STEP * 0xf != 335 + MAX14577_CHARGER_EOC_CURRENT_LIMIT_MAX); 565 336 return 0; 337 + 338 + err: 339 + device_remove_file(&pdev->dev, &dev_attr_fast_charge_timer); 340 + 341 + return ret; 566 342 } 567 343 568 344 static int max14577_charger_remove(struct platform_device *pdev) 569 345 { 570 346 struct max14577_charger *chg = platform_get_drvdata(pdev); 571 347 348 + device_remove_file(&pdev->dev, &dev_attr_fast_charge_timer); 572 349 power_supply_unregister(&chg->charger); 573 350 574 351 return 0;
+19
include/linux/mfd/max14577-private.h
··· 293 293 #define MAX77836_CHARGER_CURRENT_LIMIT_HIGH_STEP 25000U 294 294 #define MAX77836_CHARGER_CURRENT_LIMIT_MAX 475000U 295 295 296 + /* 297 + * MAX14577 charger End-Of-Charge current limits 298 + * (as in CHGCTRL5 register), uA 299 + */ 300 + #define MAX14577_CHARGER_EOC_CURRENT_LIMIT_MIN 50000U 301 + #define MAX14577_CHARGER_EOC_CURRENT_LIMIT_STEP 10000U 302 + #define MAX14577_CHARGER_EOC_CURRENT_LIMIT_MAX 200000U 303 + 304 + /* 305 + * MAX14577/MAX77836 Battery Constant Voltage 306 + * (as in CHGCTRL3 register), uV 307 + */ 308 + #define MAXIM_CHARGER_CONSTANT_VOLTAGE_MIN 4000000U 309 + #define MAXIM_CHARGER_CONSTANT_VOLTAGE_STEP 20000U 310 + #define MAXIM_CHARGER_CONSTANT_VOLTAGE_MAX 4350000U 311 + 312 + /* Default value for fast charge timer, in hours */ 313 + #define MAXIM_CHARGER_FAST_CHARGE_TIMER_DEFAULT 5 314 + 296 315 /* MAX14577 regulator SFOUT LDO voltage, fixed, uV */ 297 316 #define MAX14577_REGULATOR_SAFEOUT_VOLTAGE 4900000 298 317
+7
include/linux/mfd/max14577.h
··· 54 54 struct device_node *of_node; 55 55 }; 56 56 57 + struct max14577_charger_platform_data { 58 + u32 constant_uvolt; 59 + u32 fast_charge_uamp; 60 + u32 eoc_uamp; 61 + u32 ovp_uvolt; 62 + }; 63 + 57 64 /* 58 65 * MAX14577 MFD platform data 59 66 */