1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Battery charger driver for Dialog Semiconductor DA9030 4 * 5 * Copyright (C) 2008 Compulab, Ltd. 6 * Mike Rapoport <mike@compulab.co.il> 7 */ 8 9 #include <linux/kernel.h> 10 #include <linux/slab.h> 11 #include <linux/init.h> 12 #include <linux/types.h> 13 #include <linux/device.h> 14 #include <linux/workqueue.h> 15 #include <linux/module.h> 16 #include <linux/platform_device.h> 17 #include <linux/power_supply.h> 18 #include <linux/string_choices.h> 19 #include <linux/mfd/da903x.h> 20 21 #include <linux/debugfs.h> 22 #include <linux/seq_file.h> 23 #include <linux/notifier.h> 24 25 #define DA9030_FAULT_LOG 0x0a 26 #define DA9030_FAULT_LOG_OVER_TEMP (1 << 7) 27 #define DA9030_FAULT_LOG_VBAT_OVER (1 << 4) 28 29 #define DA9030_CHARGE_CONTROL 0x28 30 #define DA9030_CHRG_CHARGER_ENABLE (1 << 7) 31 32 #define DA9030_ADC_MAN_CONTROL 0x30 33 #define DA9030_ADC_TBATREF_ENABLE (1 << 5) 34 #define DA9030_ADC_LDO_INT_ENABLE (1 << 4) 35 36 #define DA9030_ADC_AUTO_CONTROL 0x31 37 #define DA9030_ADC_TBAT_ENABLE (1 << 5) 38 #define DA9030_ADC_VBAT_IN_TXON (1 << 4) 39 #define DA9030_ADC_VCH_ENABLE (1 << 3) 40 #define DA9030_ADC_ICH_ENABLE (1 << 2) 41 #define DA9030_ADC_VBAT_ENABLE (1 << 1) 42 #define DA9030_ADC_AUTO_SLEEP_ENABLE (1 << 0) 43 44 #define DA9030_VBATMON 0x32 45 #define DA9030_VBATMONTXON 0x33 46 #define DA9030_TBATHIGHP 0x34 47 #define DA9030_TBATHIGHN 0x35 48 #define DA9030_TBATLOW 0x36 49 50 #define DA9030_VBAT_RES 0x41 51 #define DA9030_VBATMIN_RES 0x42 52 #define DA9030_VBATMINTXON_RES 0x43 53 #define DA9030_ICHMAX_RES 0x44 54 #define DA9030_ICHMIN_RES 0x45 55 #define DA9030_ICHAVERAGE_RES 0x46 56 #define DA9030_VCHMAX_RES 0x47 57 #define DA9030_VCHMIN_RES 0x48 58 #define DA9030_TBAT_RES 0x49 59 60 struct da9030_adc_res { 61 uint8_t vbat_res; 62 uint8_t vbatmin_res; 63 uint8_t vbatmintxon; 64 uint8_t ichmax_res; 65 uint8_t ichmin_res; 66 uint8_t ichaverage_res; 67 uint8_t vchmax_res; 68 uint8_t vchmin_res; 69 uint8_t tbat_res; 70 uint8_t adc_in4_res; 71 uint8_t adc_in5_res; 72 }; 73 74 struct da9030_battery_thresholds { 75 int tbat_low; 76 int tbat_high; 77 int tbat_restart; 78 79 int vbat_low; 80 int vbat_crit; 81 int vbat_charge_start; 82 int vbat_charge_stop; 83 int vbat_charge_restart; 84 85 int vcharge_min; 86 int vcharge_max; 87 }; 88 89 struct da9030_charger { 90 struct power_supply *psy; 91 struct power_supply_desc psy_desc; 92 93 struct device *master; 94 95 struct da9030_adc_res adc; 96 struct delayed_work work; 97 unsigned int interval; 98 99 struct power_supply_info *battery_info; 100 101 struct da9030_battery_thresholds thresholds; 102 103 unsigned int charge_milliamp; 104 unsigned int charge_millivolt; 105 106 /* charger status */ 107 bool chdet; 108 uint8_t fault; 109 int mA; 110 int mV; 111 bool is_on; 112 113 struct notifier_block nb; 114 115 /* platform callbacks for battery low and critical events */ 116 void (*battery_low)(void); 117 void (*battery_critical)(void); 118 119 struct dentry *debug_file; 120 }; 121 122 static inline int da9030_reg_to_mV(int reg) 123 { 124 return ((reg * 2650) >> 8) + 2650; 125 } 126 127 static inline int da9030_millivolt_to_reg(int mV) 128 { 129 return ((mV - 2650) << 8) / 2650; 130 } 131 132 static inline int da9030_reg_to_mA(int reg) 133 { 134 return ((reg * 24000) >> 8) / 15; 135 } 136 137 #ifdef CONFIG_DEBUG_FS 138 static int bat_debug_show(struct seq_file *s, void *data) 139 { 140 struct da9030_charger *charger = s->private; 141 142 seq_printf(s, "charger is %s\n", str_on_off(charger->is_on)); 143 if (charger->chdet) { 144 seq_printf(s, "iset = %dmA, vset = %dmV\n", 145 charger->mA, charger->mV); 146 } 147 148 seq_printf(s, "vbat_res = %d (%dmV)\n", 149 charger->adc.vbat_res, 150 da9030_reg_to_mV(charger->adc.vbat_res)); 151 seq_printf(s, "vbatmin_res = %d (%dmV)\n", 152 charger->adc.vbatmin_res, 153 da9030_reg_to_mV(charger->adc.vbatmin_res)); 154 seq_printf(s, "vbatmintxon = %d (%dmV)\n", 155 charger->adc.vbatmintxon, 156 da9030_reg_to_mV(charger->adc.vbatmintxon)); 157 seq_printf(s, "ichmax_res = %d (%dmA)\n", 158 charger->adc.ichmax_res, 159 da9030_reg_to_mV(charger->adc.ichmax_res)); 160 seq_printf(s, "ichmin_res = %d (%dmA)\n", 161 charger->adc.ichmin_res, 162 da9030_reg_to_mA(charger->adc.ichmin_res)); 163 seq_printf(s, "ichaverage_res = %d (%dmA)\n", 164 charger->adc.ichaverage_res, 165 da9030_reg_to_mA(charger->adc.ichaverage_res)); 166 seq_printf(s, "vchmax_res = %d (%dmV)\n", 167 charger->adc.vchmax_res, 168 da9030_reg_to_mA(charger->adc.vchmax_res)); 169 seq_printf(s, "vchmin_res = %d (%dmV)\n", 170 charger->adc.vchmin_res, 171 da9030_reg_to_mV(charger->adc.vchmin_res)); 172 173 return 0; 174 } 175 176 DEFINE_SHOW_ATTRIBUTE(bat_debug); 177 178 static struct dentry *da9030_bat_create_debugfs(struct da9030_charger *charger) 179 { 180 charger->debug_file = debugfs_create_file("charger", 0666, NULL, 181 charger, &bat_debug_fops); 182 return charger->debug_file; 183 } 184 185 static void da9030_bat_remove_debugfs(struct da9030_charger *charger) 186 { 187 debugfs_remove(charger->debug_file); 188 } 189 #else 190 static inline struct dentry *da9030_bat_create_debugfs(struct da9030_charger *charger) 191 { 192 return NULL; 193 } 194 static inline void da9030_bat_remove_debugfs(struct da9030_charger *charger) 195 { 196 } 197 #endif 198 199 static inline void da9030_read_adc(struct da9030_charger *charger, 200 struct da9030_adc_res *adc) 201 { 202 da903x_reads(charger->master, DA9030_VBAT_RES, 203 sizeof(*adc), (uint8_t *)adc); 204 } 205 206 static void da9030_charger_update_state(struct da9030_charger *charger) 207 { 208 uint8_t val; 209 210 da903x_read(charger->master, DA9030_CHARGE_CONTROL, &val); 211 charger->is_on = (val & DA9030_CHRG_CHARGER_ENABLE) ? 1 : 0; 212 charger->mA = ((val >> 3) & 0xf) * 100; 213 charger->mV = (val & 0x7) * 50 + 4000; 214 215 da9030_read_adc(charger, &charger->adc); 216 da903x_read(charger->master, DA9030_FAULT_LOG, &charger->fault); 217 charger->chdet = da903x_query_status(charger->master, 218 DA9030_STATUS_CHDET); 219 } 220 221 static void da9030_set_charge(struct da9030_charger *charger, int on) 222 { 223 uint8_t val; 224 225 if (on) { 226 val = DA9030_CHRG_CHARGER_ENABLE; 227 val |= (charger->charge_milliamp / 100) << 3; 228 val |= (charger->charge_millivolt - 4000) / 50; 229 charger->is_on = 1; 230 } else { 231 val = 0; 232 charger->is_on = 0; 233 } 234 235 da903x_write(charger->master, DA9030_CHARGE_CONTROL, val); 236 237 power_supply_changed(charger->psy); 238 } 239 240 static void da9030_charger_check_state(struct da9030_charger *charger) 241 { 242 da9030_charger_update_state(charger); 243 244 /* we wake or boot with external power on */ 245 if (!charger->is_on) { 246 if ((charger->chdet) && 247 (charger->adc.vbat_res < 248 charger->thresholds.vbat_charge_start)) { 249 da9030_set_charge(charger, 1); 250 } 251 } else { 252 /* Charger has been pulled out */ 253 if (!charger->chdet) { 254 da9030_set_charge(charger, 0); 255 return; 256 } 257 258 if (charger->adc.vbat_res >= 259 charger->thresholds.vbat_charge_stop) { 260 da9030_set_charge(charger, 0); 261 da903x_write(charger->master, DA9030_VBATMON, 262 charger->thresholds.vbat_charge_restart); 263 } else if (charger->adc.vbat_res > 264 charger->thresholds.vbat_low) { 265 /* we are charging and passed LOW_THRESH, 266 so upate DA9030 VBAT threshold 267 */ 268 da903x_write(charger->master, DA9030_VBATMON, 269 charger->thresholds.vbat_low); 270 } 271 if (charger->adc.vchmax_res > charger->thresholds.vcharge_max || 272 charger->adc.vchmin_res < charger->thresholds.vcharge_min || 273 /* Temperature readings are negative */ 274 charger->adc.tbat_res < charger->thresholds.tbat_high || 275 charger->adc.tbat_res > charger->thresholds.tbat_low) { 276 /* disable charger */ 277 da9030_set_charge(charger, 0); 278 } 279 } 280 } 281 282 static void da9030_charging_monitor(struct work_struct *work) 283 { 284 struct da9030_charger *charger; 285 286 charger = container_of(work, struct da9030_charger, work.work); 287 288 da9030_charger_check_state(charger); 289 290 /* reschedule for the next time */ 291 schedule_delayed_work(&charger->work, charger->interval); 292 } 293 294 static enum power_supply_property da9030_battery_props[] = { 295 POWER_SUPPLY_PROP_MODEL_NAME, 296 POWER_SUPPLY_PROP_STATUS, 297 POWER_SUPPLY_PROP_HEALTH, 298 POWER_SUPPLY_PROP_TECHNOLOGY, 299 POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, 300 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, 301 POWER_SUPPLY_PROP_VOLTAGE_NOW, 302 POWER_SUPPLY_PROP_CURRENT_AVG, 303 }; 304 305 static void da9030_battery_check_status(struct da9030_charger *charger, 306 union power_supply_propval *val) 307 { 308 if (charger->chdet) { 309 if (charger->is_on) 310 val->intval = POWER_SUPPLY_STATUS_CHARGING; 311 else 312 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; 313 } else { 314 val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 315 } 316 } 317 318 static void da9030_battery_check_health(struct da9030_charger *charger, 319 union power_supply_propval *val) 320 { 321 if (charger->fault & DA9030_FAULT_LOG_OVER_TEMP) 322 val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; 323 else if (charger->fault & DA9030_FAULT_LOG_VBAT_OVER) 324 val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE; 325 else 326 val->intval = POWER_SUPPLY_HEALTH_GOOD; 327 } 328 329 static int da9030_battery_get_property(struct power_supply *psy, 330 enum power_supply_property psp, 331 union power_supply_propval *val) 332 { 333 struct da9030_charger *charger = power_supply_get_drvdata(psy); 334 335 switch (psp) { 336 case POWER_SUPPLY_PROP_STATUS: 337 da9030_battery_check_status(charger, val); 338 break; 339 case POWER_SUPPLY_PROP_HEALTH: 340 da9030_battery_check_health(charger, val); 341 break; 342 case POWER_SUPPLY_PROP_TECHNOLOGY: 343 val->intval = charger->battery_info->technology; 344 break; 345 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: 346 val->intval = charger->battery_info->voltage_max_design; 347 break; 348 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: 349 val->intval = charger->battery_info->voltage_min_design; 350 break; 351 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 352 val->intval = da9030_reg_to_mV(charger->adc.vbat_res) * 1000; 353 break; 354 case POWER_SUPPLY_PROP_CURRENT_AVG: 355 val->intval = 356 da9030_reg_to_mA(charger->adc.ichaverage_res) * 1000; 357 break; 358 case POWER_SUPPLY_PROP_MODEL_NAME: 359 val->strval = charger->battery_info->name; 360 break; 361 default: 362 break; 363 } 364 365 return 0; 366 } 367 368 static void da9030_battery_vbat_event(struct da9030_charger *charger) 369 { 370 da9030_read_adc(charger, &charger->adc); 371 372 if (charger->is_on) 373 return; 374 375 if (charger->adc.vbat_res < charger->thresholds.vbat_low) { 376 /* set VBAT threshold for critical */ 377 da903x_write(charger->master, DA9030_VBATMON, 378 charger->thresholds.vbat_crit); 379 if (charger->battery_low) 380 charger->battery_low(); 381 } else if (charger->adc.vbat_res < 382 charger->thresholds.vbat_crit) { 383 /* notify the system of battery critical */ 384 if (charger->battery_critical) 385 charger->battery_critical(); 386 } 387 } 388 389 static int da9030_battery_event(struct notifier_block *nb, unsigned long event, 390 void *data) 391 { 392 struct da9030_charger *charger = 393 container_of(nb, struct da9030_charger, nb); 394 395 switch (event) { 396 case DA9030_EVENT_CHDET: 397 cancel_delayed_work_sync(&charger->work); 398 schedule_work(&charger->work.work); 399 break; 400 case DA9030_EVENT_VBATMON: 401 da9030_battery_vbat_event(charger); 402 break; 403 case DA9030_EVENT_CHIOVER: 404 case DA9030_EVENT_TBAT: 405 da9030_set_charge(charger, 0); 406 break; 407 } 408 409 return 0; 410 } 411 412 static void da9030_battery_convert_thresholds(struct da9030_charger *charger, 413 struct da9030_battery_info *pdata) 414 { 415 charger->thresholds.tbat_low = pdata->tbat_low; 416 charger->thresholds.tbat_high = pdata->tbat_high; 417 charger->thresholds.tbat_restart = pdata->tbat_restart; 418 419 charger->thresholds.vbat_low = 420 da9030_millivolt_to_reg(pdata->vbat_low); 421 charger->thresholds.vbat_crit = 422 da9030_millivolt_to_reg(pdata->vbat_crit); 423 charger->thresholds.vbat_charge_start = 424 da9030_millivolt_to_reg(pdata->vbat_charge_start); 425 charger->thresholds.vbat_charge_stop = 426 da9030_millivolt_to_reg(pdata->vbat_charge_stop); 427 charger->thresholds.vbat_charge_restart = 428 da9030_millivolt_to_reg(pdata->vbat_charge_restart); 429 430 charger->thresholds.vcharge_min = 431 da9030_millivolt_to_reg(pdata->vcharge_min); 432 charger->thresholds.vcharge_max = 433 da9030_millivolt_to_reg(pdata->vcharge_max); 434 } 435 436 static void da9030_battery_setup_psy(struct da9030_charger *charger) 437 { 438 struct power_supply_desc *psy_desc = &charger->psy_desc; 439 struct power_supply_info *info = charger->battery_info; 440 441 psy_desc->name = info->name; 442 psy_desc->use_for_apm = info->use_for_apm; 443 psy_desc->type = POWER_SUPPLY_TYPE_BATTERY; 444 psy_desc->get_property = da9030_battery_get_property; 445 446 psy_desc->properties = da9030_battery_props; 447 psy_desc->num_properties = ARRAY_SIZE(da9030_battery_props); 448 }; 449 450 static int da9030_battery_charger_init(struct da9030_charger *charger) 451 { 452 char v[5]; 453 int ret; 454 455 v[0] = v[1] = charger->thresholds.vbat_low; 456 v[2] = charger->thresholds.tbat_high; 457 v[3] = charger->thresholds.tbat_restart; 458 v[4] = charger->thresholds.tbat_low; 459 460 ret = da903x_writes(charger->master, DA9030_VBATMON, 5, v); 461 if (ret) 462 return ret; 463 464 /* 465 * Enable reference voltage supply for ADC from the LDO_INTERNAL 466 * regulator. Must be set before ADC measurements can be made. 467 */ 468 ret = da903x_write(charger->master, DA9030_ADC_MAN_CONTROL, 469 DA9030_ADC_LDO_INT_ENABLE | 470 DA9030_ADC_TBATREF_ENABLE); 471 if (ret) 472 return ret; 473 474 /* enable auto ADC measurements */ 475 return da903x_write(charger->master, DA9030_ADC_AUTO_CONTROL, 476 DA9030_ADC_TBAT_ENABLE | DA9030_ADC_VBAT_IN_TXON | 477 DA9030_ADC_VCH_ENABLE | DA9030_ADC_ICH_ENABLE | 478 DA9030_ADC_VBAT_ENABLE | 479 DA9030_ADC_AUTO_SLEEP_ENABLE); 480 } 481 482 static int da9030_battery_probe(struct platform_device *pdev) 483 { 484 struct da9030_charger *charger; 485 struct power_supply_config psy_cfg = {}; 486 struct da9030_battery_info *pdata = pdev->dev.platform_data; 487 int ret; 488 489 if (pdata == NULL) 490 return -EINVAL; 491 492 if (pdata->charge_milliamp >= 1500 || 493 pdata->charge_millivolt < 4000 || 494 pdata->charge_millivolt > 4350) 495 return -EINVAL; 496 497 charger = devm_kzalloc(&pdev->dev, sizeof(*charger), GFP_KERNEL); 498 if (charger == NULL) 499 return -ENOMEM; 500 501 charger->master = pdev->dev.parent; 502 503 /* 10 seconds between monitor runs unless platform defines other 504 interval */ 505 charger->interval = secs_to_jiffies(pdata->batmon_interval ? : 10); 506 507 charger->charge_milliamp = pdata->charge_milliamp; 508 charger->charge_millivolt = pdata->charge_millivolt; 509 charger->battery_info = pdata->battery_info; 510 charger->battery_low = pdata->battery_low; 511 charger->battery_critical = pdata->battery_critical; 512 513 da9030_battery_convert_thresholds(charger, pdata); 514 515 ret = da9030_battery_charger_init(charger); 516 if (ret) 517 goto err_charger_init; 518 519 INIT_DELAYED_WORK(&charger->work, da9030_charging_monitor); 520 schedule_delayed_work(&charger->work, charger->interval); 521 522 charger->nb.notifier_call = da9030_battery_event; 523 ret = da903x_register_notifier(charger->master, &charger->nb, 524 DA9030_EVENT_CHDET | 525 DA9030_EVENT_VBATMON | 526 DA9030_EVENT_CHIOVER | 527 DA9030_EVENT_TBAT); 528 if (ret) 529 goto err_notifier; 530 531 da9030_battery_setup_psy(charger); 532 psy_cfg.drv_data = charger; 533 charger->psy = devm_power_supply_register(&pdev->dev, 534 &charger->psy_desc, 535 &psy_cfg); 536 if (IS_ERR(charger->psy)) { 537 ret = PTR_ERR(charger->psy); 538 goto err_ps_register; 539 } 540 541 charger->debug_file = da9030_bat_create_debugfs(charger); 542 platform_set_drvdata(pdev, charger); 543 return 0; 544 545 err_ps_register: 546 da903x_unregister_notifier(charger->master, &charger->nb, 547 DA9030_EVENT_CHDET | DA9030_EVENT_VBATMON | 548 DA9030_EVENT_CHIOVER | DA9030_EVENT_TBAT); 549 err_notifier: 550 cancel_delayed_work(&charger->work); 551 552 err_charger_init: 553 return ret; 554 } 555 556 static void da9030_battery_remove(struct platform_device *dev) 557 { 558 struct da9030_charger *charger = platform_get_drvdata(dev); 559 560 da9030_bat_remove_debugfs(charger); 561 562 da903x_unregister_notifier(charger->master, &charger->nb, 563 DA9030_EVENT_CHDET | DA9030_EVENT_VBATMON | 564 DA9030_EVENT_CHIOVER | DA9030_EVENT_TBAT); 565 cancel_delayed_work_sync(&charger->work); 566 da9030_set_charge(charger, 0); 567 } 568 569 static struct platform_driver da903x_battery_driver = { 570 .driver = { 571 .name = "da903x-battery", 572 }, 573 .probe = da9030_battery_probe, 574 .remove = da9030_battery_remove, 575 }; 576 577 module_platform_driver(da903x_battery_driver); 578 579 MODULE_DESCRIPTION("DA9030 battery charger driver"); 580 MODULE_AUTHOR("Mike Rapoport, CompuLab"); 581 MODULE_LICENSE("GPL"); 582