1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * BQ257XX Battery Charger Driver 4 * Copyright (C) 2025 Chris Morgan <macromorgan@hotmail.com> 5 */ 6 7 #include <linux/bitfield.h> 8 #include <linux/i2c.h> 9 #include <linux/interrupt.h> 10 #include <linux/mfd/bq257xx.h> 11 #include <linux/platform_device.h> 12 #include <linux/power_supply.h> 13 #include <linux/property.h> 14 #include <linux/regmap.h> 15 16 /* Forward declaration of driver data. */ 17 struct bq257xx_chg; 18 19 /** 20 * struct bq257xx_chip_info - chip specific routines 21 * @bq257xx_hw_init: init function for hw 22 * @bq257xx_hw_shutdown: shutdown function for hw 23 * @bq257xx_get_state: get and update state of hardware 24 * @bq257xx_set_ichg: set maximum charge current (in uA) 25 * @bq257xx_set_vbatreg: set maximum charge voltage (in uV) 26 * @bq257xx_set_iindpm: set maximum input current (in uA) 27 */ 28 struct bq257xx_chip_info { 29 int (*bq257xx_hw_init)(struct bq257xx_chg *pdata); 30 void (*bq257xx_hw_shutdown)(struct bq257xx_chg *pdata); 31 int (*bq257xx_get_state)(struct bq257xx_chg *pdata); 32 int (*bq257xx_set_ichg)(struct bq257xx_chg *pdata, int ichg); 33 int (*bq257xx_set_vbatreg)(struct bq257xx_chg *pdata, int vbatreg); 34 int (*bq257xx_set_iindpm)(struct bq257xx_chg *pdata, int iindpm); 35 }; 36 37 /** 38 * struct bq257xx_chg - driver data for charger 39 * @chip: hw specific functions 40 * @bq: parent MFD device 41 * @charger: power supply device 42 * @online: charger input is present 43 * @fast_charge: charger is in fast charge mode 44 * @pre_charge: charger is in pre-charge mode 45 * @ov_fault: charger reports over voltage fault 46 * @batoc_fault: charger reports battery over current fault 47 * @oc_fault: charger reports over current fault 48 * @usb_type: USB type reported from parent power supply 49 * @supplied: Status of parent power supply 50 * @iindpm_max: maximum input current limit (uA) 51 * @vbat_max: maximum charge voltage (uV) 52 * @ichg_max: maximum charge current (uA) 53 * @vsys_min: minimum system voltage (uV) 54 */ 55 struct bq257xx_chg { 56 const struct bq257xx_chip_info *chip; 57 struct bq257xx_device *bq; 58 struct power_supply *charger; 59 bool online; 60 bool fast_charge; 61 bool pre_charge; 62 bool ov_fault; 63 bool batoc_fault; 64 bool oc_fault; 65 int usb_type; 66 int supplied; 67 u32 iindpm_max; 68 u32 vbat_max; 69 u32 ichg_max; 70 u32 vsys_min; 71 }; 72 73 /** 74 * bq25703_get_state() - Get the current state of the device 75 * @pdata: driver platform data 76 * 77 * Get the current state of the charger. Check if the charger is 78 * powered, what kind of charge state (if any) the device is in, 79 * and if there are any active faults. 80 * 81 * Return: Returns 0 on success, or error on failure to read device. 82 */ 83 static int bq25703_get_state(struct bq257xx_chg *pdata) 84 { 85 unsigned int reg; 86 int ret; 87 88 ret = regmap_read(pdata->bq->regmap, BQ25703_CHARGER_STATUS, ®); 89 if (ret) 90 return ret; 91 92 pdata->online = reg & BQ25703_STS_AC_STAT; 93 pdata->fast_charge = reg & BQ25703_STS_IN_FCHRG; 94 pdata->pre_charge = reg & BQ25703_STS_IN_PCHRG; 95 pdata->ov_fault = reg & BQ25703_STS_FAULT_ACOV; 96 pdata->batoc_fault = reg & BQ25703_STS_FAULT_BATOC; 97 pdata->oc_fault = reg & BQ25703_STS_FAULT_ACOC; 98 99 return 0; 100 } 101 102 /** 103 * bq25703_get_min_vsys() - Get the minimum system voltage 104 * @pdata: driver platform data 105 * @intval: value for minimum voltage 106 * 107 * Return: Returns 0 on success or error on failure to read. 108 */ 109 static int bq25703_get_min_vsys(struct bq257xx_chg *pdata, int *intval) 110 { 111 unsigned int reg; 112 int ret; 113 114 ret = regmap_read(pdata->bq->regmap, BQ25703_MIN_VSYS, 115 ®); 116 if (ret) 117 return ret; 118 119 reg = FIELD_GET(BQ25703_MINVSYS_MASK, reg); 120 *intval = (reg * BQ25703_MINVSYS_STEP_UV) + BQ25703_MINVSYS_MIN_UV; 121 122 return ret; 123 } 124 125 /** 126 * bq25703_set_min_vsys() - Set the minimum system voltage 127 * @pdata: driver platform data 128 * @vsys: voltage value to set in uV. 129 * 130 * This function takes a requested minimum system voltage value, clamps 131 * it between the minimum supported value by the charger and a user 132 * defined minimum system value, and then writes the value to the 133 * appropriate register. 134 * 135 * Return: Returns 0 on success or error if an error occurs. 136 */ 137 static int bq25703_set_min_vsys(struct bq257xx_chg *pdata, int vsys) 138 { 139 unsigned int reg; 140 int vsys_min = pdata->vsys_min; 141 142 vsys = clamp(vsys, BQ25703_MINVSYS_MIN_UV, vsys_min); 143 reg = ((vsys - BQ25703_MINVSYS_MIN_UV) / BQ25703_MINVSYS_STEP_UV); 144 reg = FIELD_PREP(BQ25703_MINVSYS_MASK, reg); 145 146 return regmap_write(pdata->bq->regmap, BQ25703_MIN_VSYS, 147 reg); 148 } 149 150 /** 151 * bq25703_get_cur() - Get the reported current from the battery 152 * @pdata: driver platform data 153 * @intval: value of reported battery current 154 * 155 * Read the reported current from the battery. Since value is always 156 * positive set sign to negative if discharging. 157 * 158 * Return: Returns 0 on success or error if unable to read value. 159 */ 160 static int bq25703_get_cur(struct bq257xx_chg *pdata, int *intval) 161 { 162 unsigned int reg; 163 int ret; 164 165 ret = regmap_read(pdata->bq->regmap, BQ25703_ADCIBAT_CHG, ®); 166 if (ret < 0) 167 return ret; 168 169 if (pdata->online) 170 *intval = FIELD_GET(BQ25703_ADCIBAT_CHG_MASK, reg) * 171 BQ25703_ADCIBAT_CHG_STEP_UA; 172 else 173 *intval = -(FIELD_GET(BQ25703_ADCIBAT_DISCHG_MASK, reg) * 174 BQ25703_ADCIBAT_DIS_STEP_UA); 175 176 return ret; 177 } 178 179 /** 180 * bq25703_get_ichg_cur() - Get the maximum reported charge current 181 * @pdata: driver platform data 182 * @intval: value of maximum reported charge current 183 * 184 * Get the maximum reported charge current from the battery. 185 * 186 * Return: Returns 0 on success or error if unable to read value. 187 */ 188 static int bq25703_get_ichg_cur(struct bq257xx_chg *pdata, int *intval) 189 { 190 unsigned int reg; 191 int ret; 192 193 ret = regmap_read(pdata->bq->regmap, BQ25703_CHARGE_CURRENT, ®); 194 if (ret) 195 return ret; 196 197 *intval = FIELD_GET(BQ25703_ICHG_MASK, reg) * BQ25703_ICHG_STEP_UA; 198 199 return ret; 200 } 201 202 /** 203 * bq25703_set_ichg_cur() - Set the maximum charge current 204 * @pdata: driver platform data 205 * @ichg: current value to set in uA. 206 * 207 * This function takes a requested maximum charge current value, clamps 208 * it between the minimum supported value by the charger and a user 209 * defined maximum charging value, and then writes the value to the 210 * appropriate register. 211 * 212 * Return: Returns 0 on success or error if an error occurs. 213 */ 214 static int bq25703_set_ichg_cur(struct bq257xx_chg *pdata, int ichg) 215 { 216 unsigned int reg; 217 int ichg_max = pdata->ichg_max; 218 219 ichg = clamp(ichg, BQ25703_ICHG_MIN_UA, ichg_max); 220 reg = FIELD_PREP(BQ25703_ICHG_MASK, (ichg / BQ25703_ICHG_STEP_UA)); 221 222 return regmap_write(pdata->bq->regmap, BQ25703_CHARGE_CURRENT, 223 reg); 224 } 225 226 /** 227 * bq25703_get_chrg_volt() - Get the maximum set charge voltage 228 * @pdata: driver platform data 229 * @intval: maximum charge voltage value 230 * 231 * Return: Returns 0 on success or error if unable to read value. 232 */ 233 static int bq25703_get_chrg_volt(struct bq257xx_chg *pdata, int *intval) 234 { 235 unsigned int reg; 236 int ret; 237 238 ret = regmap_read(pdata->bq->regmap, BQ25703_MAX_CHARGE_VOLT, 239 ®); 240 if (ret) 241 return ret; 242 243 *intval = FIELD_GET(BQ25703_MAX_CHARGE_VOLT_MASK, reg) * 244 BQ25703_VBATREG_STEP_UV; 245 246 return ret; 247 } 248 249 /** 250 * bq25703_set_chrg_volt() - Set the maximum charge voltage 251 * @pdata: driver platform data 252 * @vbat: voltage value to set in uV. 253 * 254 * This function takes a requested maximum charge voltage value, clamps 255 * it between the minimum supported value by the charger and a user 256 * defined maximum charging value, and then writes the value to the 257 * appropriate register. 258 * 259 * Return: Returns 0 on success or error if an error occurs. 260 */ 261 static int bq25703_set_chrg_volt(struct bq257xx_chg *pdata, int vbat) 262 { 263 unsigned int reg; 264 int vbat_max = pdata->vbat_max; 265 266 vbat = clamp(vbat, BQ25703_VBATREG_MIN_UV, vbat_max); 267 268 reg = FIELD_PREP(BQ25703_MAX_CHARGE_VOLT_MASK, 269 (vbat / BQ25703_VBATREG_STEP_UV)); 270 271 return regmap_write(pdata->bq->regmap, BQ25703_MAX_CHARGE_VOLT, 272 reg); 273 } 274 275 /** 276 * bq25703_get_iindpm() - Get the maximum set input current 277 * @pdata: driver platform data 278 * @intval: maximum input current value 279 * 280 * Read the actual input current limit from the device into intval. 281 * This can differ from the value programmed due to some autonomous 282 * functions that may be enabled (but are not currently). This is why 283 * there is a different register used. 284 * 285 * Return: Returns 0 on success or error if unable to read register 286 * value. 287 */ 288 static int bq25703_get_iindpm(struct bq257xx_chg *pdata, int *intval) 289 { 290 unsigned int reg; 291 int ret; 292 293 ret = regmap_read(pdata->bq->regmap, BQ25703_IIN_DPM, ®); 294 if (ret) 295 return ret; 296 297 reg = FIELD_GET(BQ25703_IINDPM_MASK, reg); 298 *intval = (reg * BQ25703_IINDPM_STEP_UA) + BQ25703_IINDPM_OFFSET_UA; 299 300 return ret; 301 } 302 303 /** 304 * bq25703_set_iindpm() - Set the maximum input current 305 * @pdata: driver platform data 306 * @iindpm: current value in uA. 307 * 308 * This function takes a requested maximum input current value, clamps 309 * it between the minimum supported value by the charger and a user 310 * defined maximum input value, and then writes the value to the 311 * appropriate register. 312 * 313 * Return: Returns 0 on success or error if an error occurs. 314 */ 315 static int bq25703_set_iindpm(struct bq257xx_chg *pdata, int iindpm) 316 { 317 unsigned int reg; 318 int iindpm_max = pdata->iindpm_max; 319 320 iindpm = clamp(iindpm, BQ25703_IINDPM_MIN_UA, iindpm_max); 321 322 reg = ((iindpm - BQ25703_IINDPM_OFFSET_UA) / BQ25703_IINDPM_STEP_UA); 323 324 return regmap_write(pdata->bq->regmap, BQ25703_IIN_HOST, 325 FIELD_PREP(BQ25703_IINDPM_MASK, reg)); 326 } 327 328 /** 329 * bq25703_get_vbat() - Get the reported voltage from the battery 330 * @pdata: driver platform data 331 * @intval: value of reported battery voltage 332 * 333 * Read value of battery voltage into intval. 334 * 335 * Return: Returns 0 on success or error if unable to read value. 336 */ 337 static int bq25703_get_vbat(struct bq257xx_chg *pdata, int *intval) 338 { 339 unsigned int reg; 340 int ret; 341 342 ret = regmap_read(pdata->bq->regmap, BQ25703_ADCVSYSVBAT, ®); 343 if (ret) 344 return ret; 345 346 reg = FIELD_GET(BQ25703_ADCVBAT_MASK, reg); 347 *intval = (reg * BQ25703_ADCVSYSVBAT_STEP) + BQ25703_ADCVSYSVBAT_OFFSET_UV; 348 349 return ret; 350 } 351 352 /** 353 * bq25703_hw_init() - Set all the required registers to init the charger 354 * @pdata: driver platform data 355 * 356 * Initialize the BQ25703 by first disabling the watchdog timer (which 357 * shuts off the charger in the absence of periodic writes). Then, set 358 * the charge current, charge voltage, minimum system voltage, and 359 * input current limit. Disable low power mode to allow ADCs and 360 * interrupts. Enable the ADC, start the ADC, set the ADC scale to 361 * full, and enable each individual ADC channel. 362 * 363 * Return: Returns 0 on success or error code on error. 364 */ 365 static int bq25703_hw_init(struct bq257xx_chg *pdata) 366 { 367 struct regmap *regmap = pdata->bq->regmap; 368 int ret = 0; 369 370 regmap_update_bits(regmap, BQ25703_CHARGE_OPTION_0, 371 BQ25703_WDTMR_ADJ_MASK, 372 FIELD_PREP(BQ25703_WDTMR_ADJ_MASK, 373 BQ25703_WDTMR_DISABLE)); 374 375 ret = pdata->chip->bq257xx_set_ichg(pdata, pdata->ichg_max); 376 if (ret) 377 return ret; 378 379 ret = pdata->chip->bq257xx_set_vbatreg(pdata, pdata->vbat_max); 380 if (ret) 381 return ret; 382 383 ret = bq25703_set_min_vsys(pdata, pdata->vsys_min); 384 if (ret) 385 return ret; 386 387 ret = pdata->chip->bq257xx_set_iindpm(pdata, pdata->iindpm_max); 388 if (ret) 389 return ret; 390 391 /* Disable low power mode by writing 0 to the register. */ 392 regmap_update_bits(regmap, BQ25703_CHARGE_OPTION_0, 393 BQ25703_EN_LWPWR, 0); 394 395 /* Enable the ADC. */ 396 regmap_update_bits(regmap, BQ25703_ADC_OPTION, 397 BQ25703_ADC_CONV_EN, BQ25703_ADC_CONV_EN); 398 399 /* Start the ADC. */ 400 regmap_update_bits(regmap, BQ25703_ADC_OPTION, 401 BQ25703_ADC_START, BQ25703_ADC_START); 402 403 /* Set the scale of the ADC. */ 404 regmap_update_bits(regmap, BQ25703_ADC_OPTION, 405 BQ25703_ADC_FULL_SCALE, BQ25703_ADC_FULL_SCALE); 406 407 /* Enable each of the ADC channels available. */ 408 regmap_update_bits(regmap, BQ25703_ADC_OPTION, 409 BQ25703_ADC_CH_MASK, 410 (BQ25703_ADC_CMPIN_EN | BQ25703_ADC_VBUS_EN | 411 BQ25703_ADC_PSYS_EN | BQ25703_ADC_IIN_EN | 412 BQ25703_ADC_IDCHG_EN | BQ25703_ADC_ICHG_EN | 413 BQ25703_ADC_VSYS_EN | BQ25703_ADC_VBAT_EN)); 414 415 return ret; 416 } 417 418 /** 419 * bq25703_hw_shutdown() - Set registers for shutdown 420 * @pdata: driver platform data 421 * 422 * Enable low power mode for the device while in shutdown. 423 */ 424 static void bq25703_hw_shutdown(struct bq257xx_chg *pdata) 425 { 426 regmap_update_bits(pdata->bq->regmap, BQ25703_CHARGE_OPTION_0, 427 BQ25703_EN_LWPWR, BQ25703_EN_LWPWR); 428 } 429 430 static int bq257xx_set_charger_property(struct power_supply *psy, 431 enum power_supply_property prop, 432 const union power_supply_propval *val) 433 { 434 struct bq257xx_chg *pdata = power_supply_get_drvdata(psy); 435 436 switch (prop) { 437 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 438 return pdata->chip->bq257xx_set_iindpm(pdata, val->intval); 439 440 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX: 441 return pdata->chip->bq257xx_set_vbatreg(pdata, val->intval); 442 443 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: 444 return pdata->chip->bq257xx_set_ichg(pdata, val->intval); 445 446 default: 447 break; 448 } 449 450 return -EINVAL; 451 } 452 453 static int bq257xx_get_charger_property(struct power_supply *psy, 454 enum power_supply_property psp, 455 union power_supply_propval *val) 456 { 457 struct bq257xx_chg *pdata = power_supply_get_drvdata(psy); 458 int ret = 0; 459 460 ret = pdata->chip->bq257xx_get_state(pdata); 461 if (ret) 462 return ret; 463 464 switch (psp) { 465 case POWER_SUPPLY_PROP_STATUS: 466 if (!pdata->online) 467 val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 468 else if (pdata->fast_charge || pdata->pre_charge) 469 val->intval = POWER_SUPPLY_STATUS_CHARGING; 470 else 471 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; 472 break; 473 474 case POWER_SUPPLY_PROP_HEALTH: 475 if (pdata->ov_fault || pdata->batoc_fault) 476 val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE; 477 else if (pdata->oc_fault) 478 val->intval = POWER_SUPPLY_HEALTH_OVERCURRENT; 479 else 480 val->intval = POWER_SUPPLY_HEALTH_GOOD; 481 break; 482 483 case POWER_SUPPLY_PROP_MANUFACTURER: 484 val->strval = "Texas Instruments"; 485 break; 486 487 case POWER_SUPPLY_PROP_ONLINE: 488 val->intval = pdata->online; 489 break; 490 491 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 492 return bq25703_get_iindpm(pdata, &val->intval); 493 494 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX: 495 return bq25703_get_chrg_volt(pdata, &val->intval); 496 497 case POWER_SUPPLY_PROP_CURRENT_NOW: 498 return bq25703_get_cur(pdata, &val->intval); 499 500 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 501 return bq25703_get_vbat(pdata, &val->intval); 502 503 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: 504 return bq25703_get_ichg_cur(pdata, &val->intval); 505 506 case POWER_SUPPLY_PROP_VOLTAGE_MIN: 507 return bq25703_get_min_vsys(pdata, &val->intval); 508 509 case POWER_SUPPLY_PROP_USB_TYPE: 510 val->intval = pdata->usb_type; 511 break; 512 513 default: 514 return -EINVAL; 515 } 516 517 return ret; 518 } 519 520 static enum power_supply_property bq257xx_power_supply_props[] = { 521 POWER_SUPPLY_PROP_MANUFACTURER, 522 POWER_SUPPLY_PROP_STATUS, 523 POWER_SUPPLY_PROP_ONLINE, 524 POWER_SUPPLY_PROP_HEALTH, 525 POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, 526 POWER_SUPPLY_PROP_CURRENT_NOW, 527 POWER_SUPPLY_PROP_VOLTAGE_NOW, 528 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX, 529 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, 530 POWER_SUPPLY_PROP_VOLTAGE_MIN, 531 POWER_SUPPLY_PROP_USB_TYPE, 532 }; 533 534 static int bq257xx_property_is_writeable(struct power_supply *psy, 535 enum power_supply_property prop) 536 { 537 switch (prop) { 538 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: 539 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX: 540 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 541 return true; 542 default: 543 return false; 544 } 545 } 546 547 /** 548 * bq257xx_external_power_changed() - Handler for external power change 549 * @psy: Power supply data 550 * 551 * When the external power into the charger is changed, check the USB 552 * type so that it can be reported. Additionally, update the max input 553 * current and max charging current to the value reported if it is a 554 * USB PD charger, otherwise use the default value. Note that each time 555 * a charger is removed the max charge current register is erased, so 556 * it must be set again each time the input changes or the device will 557 * not charge. 558 */ 559 static void bq257xx_external_power_changed(struct power_supply *psy) 560 { 561 struct bq257xx_chg *pdata = power_supply_get_drvdata(psy); 562 union power_supply_propval val; 563 int ret; 564 int imax = pdata->iindpm_max; 565 566 pdata->chip->bq257xx_get_state(pdata); 567 568 pdata->supplied = power_supply_am_i_supplied(pdata->charger); 569 if (pdata->supplied < 0) 570 return; 571 572 if (pdata->supplied == 0) 573 goto out; 574 575 ret = power_supply_get_property_from_supplier(psy, 576 POWER_SUPPLY_PROP_USB_TYPE, 577 &val); 578 if (ret) 579 return; 580 581 pdata->usb_type = val.intval; 582 583 if ((pdata->usb_type == POWER_SUPPLY_USB_TYPE_PD) || 584 (pdata->usb_type == POWER_SUPPLY_USB_TYPE_PD_DRP) || 585 (pdata->usb_type == POWER_SUPPLY_USB_TYPE_PD_PPS)) { 586 ret = power_supply_get_property_from_supplier(psy, 587 POWER_SUPPLY_PROP_CURRENT_MAX, 588 &val); 589 if (ret) 590 return; 591 592 if (val.intval) 593 imax = val.intval; 594 } 595 596 if (pdata->supplied) { 597 pdata->chip->bq257xx_set_ichg(pdata, pdata->ichg_max); 598 pdata->chip->bq257xx_set_iindpm(pdata, imax); 599 pdata->chip->bq257xx_set_vbatreg(pdata, pdata->vbat_max); 600 } 601 602 out: 603 power_supply_changed(psy); 604 } 605 606 static irqreturn_t bq257xx_irq_handler_thread(int irq, void *private) 607 { 608 struct bq257xx_chg *pdata = private; 609 610 bq257xx_external_power_changed(pdata->charger); 611 return IRQ_HANDLED; 612 } 613 614 static const struct power_supply_desc bq257xx_power_supply_desc = { 615 .name = "bq257xx-charger", 616 .type = POWER_SUPPLY_TYPE_USB, 617 .usb_types = BIT(POWER_SUPPLY_USB_TYPE_C) | 618 BIT(POWER_SUPPLY_USB_TYPE_PD) | 619 BIT(POWER_SUPPLY_USB_TYPE_PD_DRP) | 620 BIT(POWER_SUPPLY_USB_TYPE_PD_PPS) | 621 BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN), 622 .properties = bq257xx_power_supply_props, 623 .num_properties = ARRAY_SIZE(bq257xx_power_supply_props), 624 .get_property = bq257xx_get_charger_property, 625 .set_property = bq257xx_set_charger_property, 626 .property_is_writeable = bq257xx_property_is_writeable, 627 .external_power_changed = bq257xx_external_power_changed, 628 }; 629 630 static const struct bq257xx_chip_info bq25703_chip_info = { 631 .bq257xx_hw_init = &bq25703_hw_init, 632 .bq257xx_hw_shutdown = &bq25703_hw_shutdown, 633 .bq257xx_get_state = &bq25703_get_state, 634 .bq257xx_set_ichg = &bq25703_set_ichg_cur, 635 .bq257xx_set_vbatreg = &bq25703_set_chrg_volt, 636 .bq257xx_set_iindpm = &bq25703_set_iindpm, 637 }; 638 639 /** 640 * bq257xx_parse_dt() - Parse the device tree for required properties 641 * @pdata: driver platform data 642 * @psy_cfg: power supply config data 643 * @dev: device struct 644 * 645 * Read the device tree to identify the minimum system voltage, the 646 * maximum charge current, the maximum charge voltage, and the maximum 647 * input current. 648 * 649 * Return: Returns 0 on success or error code on error. 650 */ 651 static int bq257xx_parse_dt(struct bq257xx_chg *pdata, 652 struct power_supply_config *psy_cfg, struct device *dev) 653 { 654 struct power_supply_battery_info *bat_info; 655 int ret; 656 657 ret = power_supply_get_battery_info(pdata->charger, 658 &bat_info); 659 if (ret) 660 return dev_err_probe(dev, ret, 661 "Unable to get battery info\n"); 662 663 if ((bat_info->voltage_min_design_uv <= 0) || 664 (bat_info->constant_charge_voltage_max_uv <= 0) || 665 (bat_info->constant_charge_current_max_ua <= 0)) 666 return dev_err_probe(dev, -EINVAL, 667 "Required bat info missing or invalid\n"); 668 669 pdata->vsys_min = bat_info->voltage_min_design_uv; 670 pdata->vbat_max = bat_info->constant_charge_voltage_max_uv; 671 pdata->ichg_max = bat_info->constant_charge_current_max_ua; 672 673 power_supply_put_battery_info(pdata->charger, bat_info); 674 675 ret = device_property_read_u32(dev, 676 "input-current-limit-microamp", 677 &pdata->iindpm_max); 678 if (ret) 679 pdata->iindpm_max = BQ25703_IINDPM_DEFAULT_UA; 680 681 return 0; 682 } 683 684 static int bq257xx_charger_probe(struct platform_device *pdev) 685 { 686 struct device *dev = &pdev->dev; 687 struct bq257xx_device *bq = dev_get_drvdata(pdev->dev.parent); 688 struct bq257xx_chg *pdata; 689 struct power_supply_config psy_cfg = { }; 690 int ret; 691 692 device_set_of_node_from_dev(dev, pdev->dev.parent); 693 694 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 695 if (!pdata) 696 return -ENOMEM; 697 698 pdata->bq = bq; 699 pdata->chip = &bq25703_chip_info; 700 701 platform_set_drvdata(pdev, pdata); 702 703 psy_cfg.drv_data = pdata; 704 psy_cfg.fwnode = dev_fwnode(dev); 705 706 pdata->charger = devm_power_supply_register(dev, 707 &bq257xx_power_supply_desc, 708 &psy_cfg); 709 if (IS_ERR(pdata->charger)) 710 return dev_err_probe(dev, PTR_ERR(pdata->charger), 711 "Power supply register charger failed\n"); 712 713 ret = bq257xx_parse_dt(pdata, &psy_cfg, dev); 714 if (ret) 715 return ret; 716 717 ret = pdata->chip->bq257xx_hw_init(pdata); 718 if (ret) 719 return dev_err_probe(dev, ret, "Cannot initialize the charger\n"); 720 721 platform_set_drvdata(pdev, pdata); 722 723 if (bq->client->irq) { 724 ret = devm_request_threaded_irq(dev, bq->client->irq, NULL, 725 bq257xx_irq_handler_thread, 726 IRQF_TRIGGER_RISING | 727 IRQF_TRIGGER_FALLING | 728 IRQF_ONESHOT, 729 dev_name(&bq->client->dev), pdata); 730 if (ret < 0) 731 dev_err_probe(dev, ret, "Charger get irq failed\n"); 732 } 733 734 return ret; 735 } 736 737 static void bq257xx_charger_shutdown(struct platform_device *pdev) 738 { 739 struct bq257xx_chg *pdata = platform_get_drvdata(pdev); 740 741 pdata->chip->bq257xx_hw_shutdown(pdata); 742 } 743 744 static struct platform_driver bq257xx_chg_driver = { 745 .driver = { 746 .name = "bq257xx-charger", 747 }, 748 .probe = bq257xx_charger_probe, 749 .shutdown = bq257xx_charger_shutdown, 750 }; 751 module_platform_driver(bq257xx_chg_driver); 752 753 MODULE_DESCRIPTION("bq257xx charger driver"); 754 MODULE_AUTHOR("Chris Morgan <macromorgan@hotmail.com>"); 755 MODULE_LICENSE("GPL"); 756