aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKrzysztof Kozlowski <k.kozlowski@samsung.com>2014-09-12 02:53:57 -0400
committerLee Jones <lee.jones@linaro.org>2014-09-24 10:25:49 -0400
commite30110e9c96f48aea01abc3e6dfadb369cbafec3 (patch)
treeb0fffcc4dd9de5c4efad8dda1682d06acde65239
parentb8f139f68f2099b7f8b4ef470a1e53210e3aa025 (diff)
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>
-rw-r--r--drivers/power/Kconfig1
-rw-r--r--drivers/power/max14577_charger.c311
-rw-r--r--include/linux/mfd/max14577-private.h19
-rw-r--r--include/linux/mfd/max14577.h7
4 files changed, 310 insertions, 28 deletions
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 69fa8a9ef7a6..04e1d2fe2201 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -327,6 +327,7 @@ config CHARGER_MANAGER
327config CHARGER_MAX14577 327config CHARGER_MAX14577
328 tristate "Maxim MAX14577/77836 battery charger driver" 328 tristate "Maxim MAX14577/77836 battery charger driver"
329 depends on MFD_MAX14577 329 depends on MFD_MAX14577
330 select SYSFS
330 help 331 help
331 Say Y to enable support for the battery charger control sysfs and 332 Say Y to enable support for the battery charger control sysfs and
332 platform data of MAX14577/77836 MUICs. 333 platform data of MAX14577/77836 MUICs.
diff --git a/drivers/power/max14577_charger.c b/drivers/power/max14577_charger.c
index 193530549b1f..0a2bc7277026 100644
--- a/drivers/power/max14577_charger.c
+++ b/drivers/power/max14577_charger.c
@@ -19,6 +19,7 @@
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/power_supply.h> 20#include <linux/power_supply.h>
21#include <linux/mfd/max14577-private.h> 21#include <linux/mfd/max14577-private.h>
22#include <linux/mfd/max14577.h>
22 23
23struct max14577_charger { 24struct max14577_charger {
24 struct device *dev; 25 struct device *dev;
@@ -27,6 +28,8 @@ struct max14577_charger {
27 28
28 unsigned int charging_state; 29 unsigned int charging_state;
29 unsigned int battery_state; 30 unsigned int battery_state;
31
32 struct max14577_charger_platform_data *pdata;
30}; 33};
31 34
32/* 35/*
@@ -178,15 +181,131 @@ static int max14577_get_present(struct max14577_charger *chg)
178 return 1; 181 return 1;
179} 182}
180 183
184static int max14577_set_fast_charge_timer(struct max14577_charger *chg,
185 unsigned long hours)
186{
187 u8 reg_data;
188
189 switch (hours) {
190 case 5 ... 7:
191 reg_data = hours - 3;
192 break;
193 case 0:
194 /* Disable */
195 reg_data = 0x7;
196 break;
197 default:
198 dev_err(chg->dev, "Wrong value for Fast-Charge Timer: %lu\n",
199 hours);
200 return -EINVAL;
201 }
202 reg_data <<= CHGCTRL1_TCHW_SHIFT;
203
204 return max14577_update_reg(chg->max14577->regmap,
205 MAX14577_REG_CHGCTRL1, CHGCTRL1_TCHW_MASK, reg_data);
206}
207
208static int max14577_init_constant_voltage(struct max14577_charger *chg,
209 unsigned int uvolt)
210{
211 u8 reg_data;
212
213 if (uvolt < MAXIM_CHARGER_CONSTANT_VOLTAGE_MIN ||
214 uvolt > MAXIM_CHARGER_CONSTANT_VOLTAGE_MAX)
215 return -EINVAL;
216
217 if (uvolt == 4200000)
218 reg_data = 0x0;
219 else if (uvolt == MAXIM_CHARGER_CONSTANT_VOLTAGE_MAX)
220 reg_data = 0x1f;
221 else if (uvolt <= 4280000) {
222 unsigned int val = uvolt;
223
224 val -= MAXIM_CHARGER_CONSTANT_VOLTAGE_MIN;
225 val /= MAXIM_CHARGER_CONSTANT_VOLTAGE_STEP;
226 if (uvolt <= 4180000)
227 reg_data = 0x1 + val;
228 else
229 reg_data = val; /* Fix for gap between 4.18V and 4.22V */
230 } else
231 return -EINVAL;
232
233 reg_data <<= CHGCTRL3_MBCCVWRC_SHIFT;
234
235 return max14577_write_reg(chg->max14577->regmap,
236 MAX14577_CHG_REG_CHG_CTRL3, reg_data);
237}
238
239static int max14577_init_eoc(struct max14577_charger *chg,
240 unsigned int uamp)
241{
242 unsigned int current_bits = 0xf;
243 u8 reg_data;
244
245 switch (chg->max14577->dev_type) {
246 case MAXIM_DEVICE_TYPE_MAX77836:
247 if (uamp < 5000)
248 return -EINVAL; /* Requested current is too low */
249
250 if (uamp >= 7500 && uamp < 10000)
251 current_bits = 0x0;
252 else if (uamp <= 50000) {
253 /* <5000, 7499> and <10000, 50000> */
254 current_bits = uamp / 5000;
255 } else {
256 uamp = min(uamp, 100000U) - 50000U;
257 current_bits = 0xa + uamp / 10000;
258 }
259 break;
260
261 case MAXIM_DEVICE_TYPE_MAX14577:
262 default:
263 if (uamp < MAX14577_CHARGER_EOC_CURRENT_LIMIT_MIN)
264 return -EINVAL; /* Requested current is too low */
265
266 uamp = min(uamp, MAX14577_CHARGER_EOC_CURRENT_LIMIT_MAX);
267 uamp -= MAX14577_CHARGER_EOC_CURRENT_LIMIT_MIN;
268 current_bits = uamp / MAX14577_CHARGER_EOC_CURRENT_LIMIT_STEP;
269 break;
270 }
271
272 reg_data = current_bits << CHGCTRL5_EOCS_SHIFT;
273
274 return max14577_update_reg(chg->max14577->regmap,
275 MAX14577_CHG_REG_CHG_CTRL5, CHGCTRL5_EOCS_MASK,
276 reg_data);
277}
278
279static int max14577_init_fast_charge(struct max14577_charger *chg,
280 unsigned int uamp)
281{
282 u8 reg_data;
283 int ret;
284 const struct maxim_charger_current *limits =
285 &maxim_charger_currents[chg->max14577->dev_type];
286
287 ret = maxim_charger_calc_reg_current(limits, uamp, uamp, &reg_data);
288 if (ret) {
289 dev_err(chg->dev, "Wrong value for fast charge: %u\n", uamp);
290 return ret;
291 }
292
293 return max14577_update_reg(chg->max14577->regmap,
294 MAX14577_CHG_REG_CHG_CTRL4,
295 CHGCTRL4_MBCICHWRCL_MASK | CHGCTRL4_MBCICHWRCH_MASK,
296 reg_data);
297}
298
181/* 299/*
182 * Sets charger registers to proper and safe default values. 300 * Sets charger registers to proper and safe default values.
183 * Some of these values are equal to defaults in MAX14577E 301 * Some of these values are equal to defaults in MAX14577E
184 * data sheet but there are minor differences. 302 * data sheet but there are minor differences.
185 */ 303 */
186static void max14577_charger_reg_init(struct max14577_charger *chg) 304static int max14577_charger_reg_init(struct max14577_charger *chg)
187{ 305{
188 struct regmap *rmap = chg->max14577->regmap; 306 struct regmap *rmap = chg->max14577->regmap;
189 u8 reg_data; 307 u8 reg_data;
308 int ret;
190 309
191 /* 310 /*
192 * Charger-Type Manual Detection, default off (set CHGTYPMAN to 0) 311 * Charger-Type Manual Detection, default off (set CHGTYPMAN to 0)
@@ -198,10 +317,6 @@ static void max14577_charger_reg_init(struct max14577_charger *chg)
198 CDETCTRL1_CHGDETEN_MASK | CDETCTRL1_CHGTYPMAN_MASK, 317 CDETCTRL1_CHGDETEN_MASK | CDETCTRL1_CHGTYPMAN_MASK,
199 reg_data); 318 reg_data);
200 319
201 /* Battery Fast-Charge Timer, set to: 6hrs */
202 reg_data = 0x3 << CHGCTRL1_TCHW_SHIFT;
203 max14577_write_reg(rmap, MAX14577_REG_CHGCTRL1, reg_data);
204
205 /* 320 /*
206 * Wall-Adapter Rapid Charge, default on 321 * Wall-Adapter Rapid Charge, default on
207 * Battery-Charger, default on 322 * Battery-Charger, default on
@@ -210,32 +325,46 @@ static void max14577_charger_reg_init(struct max14577_charger *chg)
210 reg_data |= 0x1 << CHGCTRL2_MBCHOSTEN_SHIFT; 325 reg_data |= 0x1 << CHGCTRL2_MBCHOSTEN_SHIFT;
211 max14577_write_reg(rmap, MAX14577_REG_CHGCTRL2, reg_data); 326 max14577_write_reg(rmap, MAX14577_REG_CHGCTRL2, reg_data);
212 327
213 /* Battery-Charger Constant Voltage (CV) Mode, set to: 4.35V */
214 reg_data = 0xf << CHGCTRL3_MBCCVWRC_SHIFT;
215 max14577_write_reg(rmap, MAX14577_REG_CHGCTRL3, reg_data);
216
217 /*
218 * Fast Battery-Charge Current Low,
219 * default 200-950mA (max14577) / 100-475mA (max77836)
220 *
221 * Fast Battery-Charge Current High,
222 * set to 450mA (max14577) / 225mA (max77836)
223 */
224 reg_data = 0x1 << CHGCTRL4_MBCICHWRCL_SHIFT;
225 reg_data |= 0x5 << CHGCTRL4_MBCICHWRCH_SHIFT;
226 max14577_write_reg(rmap, MAX14577_REG_CHGCTRL4, reg_data);
227
228 /* End-of-Charge Current, set to 50mA (max14577) / 7.5mA (max77836) */
229 reg_data = 0x0 << CHGCTRL5_EOCS_SHIFT;
230 max14577_write_reg(rmap, MAX14577_REG_CHGCTRL5, reg_data);
231
232 /* Auto Charging Stop, default off */ 328 /* Auto Charging Stop, default off */
233 reg_data = 0x0 << CHGCTRL6_AUTOSTOP_SHIFT; 329 reg_data = 0x0 << CHGCTRL6_AUTOSTOP_SHIFT;
234 max14577_write_reg(rmap, MAX14577_REG_CHGCTRL6, reg_data); 330 max14577_write_reg(rmap, MAX14577_REG_CHGCTRL6, reg_data);
235 331
236 /* Overvoltage-Protection Threshold, set to 6.5V */ 332 ret = max14577_init_constant_voltage(chg, chg->pdata->constant_uvolt);
237 reg_data = 0x2 << CHGCTRL7_OTPCGHCVS_SHIFT; 333 if (ret)
334 return ret;
335
336 ret = max14577_init_eoc(chg, chg->pdata->eoc_uamp);
337 if (ret)
338 return ret;
339
340 ret = max14577_init_fast_charge(chg, chg->pdata->fast_charge_uamp);
341 if (ret)
342 return ret;
343
344 ret = max14577_set_fast_charge_timer(chg,
345 MAXIM_CHARGER_FAST_CHARGE_TIMER_DEFAULT);
346 if (ret)
347 return ret;
348
349 /* Initialize Overvoltage-Protection Threshold */
350 switch (chg->pdata->ovp_uvolt) {
351 case 7500000:
352 reg_data = 0x0;
353 break;
354 case 6000000:
355 case 6500000:
356 case 7000000:
357 reg_data = 0x1 + (chg->pdata->ovp_uvolt - 6000000) / 500000;
358 break;
359 default:
360 dev_err(chg->dev, "Wrong value for OVP: %u\n",
361 chg->pdata->ovp_uvolt);
362 return -EINVAL;
363 }
364 reg_data <<= CHGCTRL7_OTPCGHCVS_SHIFT;
238 max14577_write_reg(rmap, MAX14577_REG_CHGCTRL7, reg_data); 365 max14577_write_reg(rmap, MAX14577_REG_CHGCTRL7, reg_data);
366
367 return 0;
239} 368}
240 369
241/* Support property from charger */ 370/* Support property from charger */
@@ -295,6 +424,110 @@ static int max14577_charger_get_property(struct power_supply *psy,
295 return ret; 424 return ret;
296} 425}
297 426
427#ifdef CONFIG_OF
428static struct max14577_charger_platform_data *max14577_charger_dt_init(
429 struct platform_device *pdev)
430{
431 struct max14577_charger_platform_data *pdata;
432 struct device_node *np = pdev->dev.of_node;
433 int ret;
434
435 if (!np) {
436 dev_err(&pdev->dev, "No charger OF node\n");
437 return ERR_PTR(-EINVAL);
438 }
439
440 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
441 if (!pdata)
442 return ERR_PTR(-ENOMEM);
443
444 ret = of_property_read_u32(np, "maxim,constant-uvolt",
445 &pdata->constant_uvolt);
446 if (ret) {
447 dev_err(&pdev->dev, "Cannot parse maxim,constant-uvolt field from DT\n");
448 return ERR_PTR(ret);
449 }
450
451 ret = of_property_read_u32(np, "maxim,fast-charge-uamp",
452 &pdata->fast_charge_uamp);
453 if (ret) {
454 dev_err(&pdev->dev, "Cannot parse maxim,fast-charge-uamp field from DT\n");
455 return ERR_PTR(ret);
456 }
457
458 ret = of_property_read_u32(np, "maxim,eoc-uamp", &pdata->eoc_uamp);
459 if (ret) {
460 dev_err(&pdev->dev, "Cannot parse maxim,eoc-uamp field from DT\n");
461 return ERR_PTR(ret);
462 }
463
464 ret = of_property_read_u32(np, "maxim,ovp-uvolt", &pdata->ovp_uvolt);
465 if (ret) {
466 dev_err(&pdev->dev, "Cannot parse maxim,ovp-uvolt field from DT\n");
467 return ERR_PTR(ret);
468 }
469
470 return pdata;
471}
472#else /* CONFIG_OF */
473static struct max14577_charger_platform_data *max14577_charger_dt_init(
474 struct platform_device *pdev)
475{
476 return NULL;
477}
478#endif /* CONFIG_OF */
479
480static ssize_t show_fast_charge_timer(struct device *dev,
481 struct device_attribute *attr, char *buf)
482{
483 struct max14577_charger *chg = dev_get_drvdata(dev);
484 u8 reg_data;
485 int ret;
486 unsigned int val;
487
488 ret = max14577_read_reg(chg->max14577->regmap, MAX14577_REG_CHGCTRL1,
489 &reg_data);
490 if (ret)
491 return ret;
492
493 reg_data &= CHGCTRL1_TCHW_MASK;
494 reg_data >>= CHGCTRL1_TCHW_SHIFT;
495 switch (reg_data) {
496 case 0x2 ... 0x4:
497 val = reg_data + 3;
498 break;
499 case 0x7:
500 val = 0;
501 break;
502 default:
503 val = 5;
504 break;
505 }
506
507 return scnprintf(buf, PAGE_SIZE, "%u\n", val);
508}
509
510static ssize_t store_fast_charge_timer(struct device *dev,
511 struct device_attribute *attr, const char *buf, size_t count)
512{
513 struct max14577_charger *chg = dev_get_drvdata(dev);
514 unsigned long val;
515 int ret;
516
517 ret = kstrtoul(buf, 10, &val);
518 if (ret)
519 return ret;
520
521 ret = max14577_set_fast_charge_timer(chg, val);
522 if (ret)
523 return ret;
524
525 return count;
526}
527
528static DEVICE_ATTR(fast_charge_timer, S_IRUGO | S_IWUSR,
529 show_fast_charge_timer, store_fast_charge_timer);
530
298static int max14577_charger_probe(struct platform_device *pdev) 531static int max14577_charger_probe(struct platform_device *pdev)
299{ 532{
300 struct max14577_charger *chg; 533 struct max14577_charger *chg;
@@ -309,7 +542,13 @@ static int max14577_charger_probe(struct platform_device *pdev)
309 chg->dev = &pdev->dev; 542 chg->dev = &pdev->dev;
310 chg->max14577 = max14577; 543 chg->max14577 = max14577;
311 544
312 max14577_charger_reg_init(chg); 545 chg->pdata = max14577_charger_dt_init(pdev);
546 if (IS_ERR_OR_NULL(chg->pdata))
547 return PTR_ERR(chg->pdata);
548
549 ret = max14577_charger_reg_init(chg);
550 if (ret)
551 return ret;
313 552
314 chg->charger.name = "max14577-charger", 553 chg->charger.name = "max14577-charger",
315 chg->charger.type = POWER_SUPPLY_TYPE_BATTERY, 554 chg->charger.type = POWER_SUPPLY_TYPE_BATTERY,
@@ -317,19 +556,35 @@ static int max14577_charger_probe(struct platform_device *pdev)
317 chg->charger.num_properties = ARRAY_SIZE(max14577_charger_props), 556 chg->charger.num_properties = ARRAY_SIZE(max14577_charger_props),
318 chg->charger.get_property = max14577_charger_get_property, 557 chg->charger.get_property = max14577_charger_get_property,
319 558
559 ret = device_create_file(&pdev->dev, &dev_attr_fast_charge_timer);
560 if (ret) {
561 dev_err(&pdev->dev, "failed: create sysfs entry\n");
562 return ret;
563 }
564
320 ret = power_supply_register(&pdev->dev, &chg->charger); 565 ret = power_supply_register(&pdev->dev, &chg->charger);
321 if (ret) { 566 if (ret) {
322 dev_err(&pdev->dev, "failed: power supply register\n"); 567 dev_err(&pdev->dev, "failed: power supply register\n");
323 return ret; 568 goto err;
324 } 569 }
325 570
571 /* Check for valid values for charger */
572 BUILD_BUG_ON(MAX14577_CHARGER_EOC_CURRENT_LIMIT_MIN +
573 MAX14577_CHARGER_EOC_CURRENT_LIMIT_STEP * 0xf !=
574 MAX14577_CHARGER_EOC_CURRENT_LIMIT_MAX);
326 return 0; 575 return 0;
576
577err:
578 device_remove_file(&pdev->dev, &dev_attr_fast_charge_timer);
579
580 return ret;
327} 581}
328 582
329static int max14577_charger_remove(struct platform_device *pdev) 583static int max14577_charger_remove(struct platform_device *pdev)
330{ 584{
331 struct max14577_charger *chg = platform_get_drvdata(pdev); 585 struct max14577_charger *chg = platform_get_drvdata(pdev);
332 586
587 device_remove_file(&pdev->dev, &dev_attr_fast_charge_timer);
333 power_supply_unregister(&chg->charger); 588 power_supply_unregister(&chg->charger);
334 589
335 return 0; 590 return 0;
diff --git a/include/linux/mfd/max14577-private.h b/include/linux/mfd/max14577-private.h
index 7d514839c764..f01c1fae4d84 100644
--- a/include/linux/mfd/max14577-private.h
+++ b/include/linux/mfd/max14577-private.h
@@ -293,6 +293,25 @@ enum max14577_charger_reg {
293#define MAX77836_CHARGER_CURRENT_LIMIT_HIGH_STEP 25000U 293#define MAX77836_CHARGER_CURRENT_LIMIT_HIGH_STEP 25000U
294#define MAX77836_CHARGER_CURRENT_LIMIT_MAX 475000U 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/* MAX14577 regulator SFOUT LDO voltage, fixed, uV */ 315/* MAX14577 regulator SFOUT LDO voltage, fixed, uV */
297#define MAX14577_REGULATOR_SAFEOUT_VOLTAGE 4900000 316#define MAX14577_REGULATOR_SAFEOUT_VOLTAGE 4900000
298 317
diff --git a/include/linux/mfd/max14577.h b/include/linux/mfd/max14577.h
index 3c098d57b1d1..ccfaf952c31b 100644
--- a/include/linux/mfd/max14577.h
+++ b/include/linux/mfd/max14577.h
@@ -54,6 +54,13 @@ struct max14577_regulator_platform_data {
54 struct device_node *of_node; 54 struct device_node *of_node;
55}; 55};
56 56
57struct 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 * MAX14577 MFD platform data 65 * MAX14577 MFD platform data
59 */ 66 */