1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Power supply driver for the RICOH RN5T618 power management chip family 4 * 5 * Copyright (C) 2020 Andreas Kemnade 6 */ 7 8 #include <linux/kernel.h> 9 #include <linux/device.h> 10 #include <linux/bitops.h> 11 #include <linux/errno.h> 12 #include <linux/init.h> 13 #include <linux/interrupt.h> 14 #include <linux/module.h> 15 #include <linux/mfd/rn5t618.h> 16 #include <linux/platform_device.h> 17 #include <linux/power_supply.h> 18 #include <linux/regmap.h> 19 #include <linux/slab.h> 20 21 #define CHG_STATE_ADP_INPUT 0x40 22 #define CHG_STATE_USB_INPUT 0x80 23 #define CHG_STATE_MASK 0x1f 24 #define CHG_STATE_CHG_OFF 0 25 #define CHG_STATE_CHG_READY_VADP 1 26 #define CHG_STATE_CHG_TRICKLE 2 27 #define CHG_STATE_CHG_RAPID 3 28 #define CHG_STATE_CHG_COMPLETE 4 29 #define CHG_STATE_SUSPEND 5 30 #define CHG_STATE_VCHG_OVER_VOL 6 31 #define CHG_STATE_BAT_ERROR 7 32 #define CHG_STATE_NO_BAT 8 33 #define CHG_STATE_BAT_OVER_VOL 9 34 #define CHG_STATE_BAT_TEMP_ERR 10 35 #define CHG_STATE_DIE_ERR 11 36 #define CHG_STATE_DIE_SHUTDOWN 12 37 #define CHG_STATE_NO_BAT2 13 38 #define CHG_STATE_CHG_READY_VUSB 14 39 40 #define GCHGDET_TYPE_MASK 0x30 41 #define GCHGDET_TYPE_SDP 0x00 42 #define GCHGDET_TYPE_CDP 0x10 43 #define GCHGDET_TYPE_DCP 0x20 44 45 #define FG_ENABLE 1 46 47 /* 48 * Formula seems accurate for battery current, but for USB current around 70mA 49 * per step was seen on Kobo Clara HD but all sources show the same formula 50 * also fur USB current. To avoid accidentially unwanted high currents we stick 51 * to that formula 52 */ 53 #define TO_CUR_REG(x) ((x) / 100000 - 1) 54 #define FROM_CUR_REG(x) ((((x) & 0x1f) + 1) * 100000) 55 #define CHG_MIN_CUR 100000 56 #define CHG_MAX_CUR 1800000 57 #define ADP_MAX_CUR 2500000 58 #define USB_MAX_CUR 1400000 59 60 61 struct rn5t618_power_info { 62 struct rn5t618 *rn5t618; 63 struct platform_device *pdev; 64 struct power_supply *battery; 65 struct power_supply *usb; 66 struct power_supply *adp; 67 int irq; 68 }; 69 70 static enum power_supply_usb_type rn5t618_usb_types[] = { 71 POWER_SUPPLY_USB_TYPE_SDP, 72 POWER_SUPPLY_USB_TYPE_DCP, 73 POWER_SUPPLY_USB_TYPE_CDP, 74 POWER_SUPPLY_USB_TYPE_UNKNOWN 75 }; 76 77 static enum power_supply_property rn5t618_usb_props[] = { 78 /* input current limit is not very accurate */ 79 POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, 80 POWER_SUPPLY_PROP_STATUS, 81 POWER_SUPPLY_PROP_USB_TYPE, 82 POWER_SUPPLY_PROP_ONLINE, 83 }; 84 85 static enum power_supply_property rn5t618_adp_props[] = { 86 /* input current limit is not very accurate */ 87 POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, 88 POWER_SUPPLY_PROP_STATUS, 89 POWER_SUPPLY_PROP_ONLINE, 90 }; 91 92 93 static enum power_supply_property rn5t618_battery_props[] = { 94 POWER_SUPPLY_PROP_STATUS, 95 POWER_SUPPLY_PROP_PRESENT, 96 POWER_SUPPLY_PROP_VOLTAGE_NOW, 97 POWER_SUPPLY_PROP_CURRENT_NOW, 98 POWER_SUPPLY_PROP_CAPACITY, 99 POWER_SUPPLY_PROP_TEMP, 100 POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW, 101 POWER_SUPPLY_PROP_TIME_TO_FULL_NOW, 102 POWER_SUPPLY_PROP_TECHNOLOGY, 103 POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT, 104 POWER_SUPPLY_PROP_CHARGE_FULL, 105 POWER_SUPPLY_PROP_CHARGE_NOW, 106 }; 107 108 static int rn5t618_battery_read_doublereg(struct rn5t618_power_info *info, 109 u8 reg, u16 *result) 110 { 111 int ret, i; 112 u8 data[2]; 113 u16 old, new; 114 115 old = 0; 116 /* Prevent races when registers are changing. */ 117 for (i = 0; i < 3; i++) { 118 ret = regmap_bulk_read(info->rn5t618->regmap, 119 reg, data, sizeof(data)); 120 if (ret) 121 return ret; 122 123 new = data[0] << 8; 124 new |= data[1]; 125 if (new == old) 126 break; 127 128 old = new; 129 } 130 131 *result = new; 132 133 return 0; 134 } 135 136 static int rn5t618_decode_status(unsigned int status) 137 { 138 switch (status & CHG_STATE_MASK) { 139 case CHG_STATE_CHG_OFF: 140 case CHG_STATE_SUSPEND: 141 case CHG_STATE_VCHG_OVER_VOL: 142 case CHG_STATE_DIE_SHUTDOWN: 143 return POWER_SUPPLY_STATUS_DISCHARGING; 144 145 case CHG_STATE_CHG_TRICKLE: 146 case CHG_STATE_CHG_RAPID: 147 return POWER_SUPPLY_STATUS_CHARGING; 148 149 case CHG_STATE_CHG_COMPLETE: 150 return POWER_SUPPLY_STATUS_FULL; 151 152 default: 153 return POWER_SUPPLY_STATUS_NOT_CHARGING; 154 } 155 } 156 157 static int rn5t618_battery_status(struct rn5t618_power_info *info, 158 union power_supply_propval *val) 159 { 160 unsigned int v; 161 int ret; 162 163 ret = regmap_read(info->rn5t618->regmap, RN5T618_CHGSTATE, &v); 164 if (ret) 165 return ret; 166 167 val->intval = POWER_SUPPLY_STATUS_UNKNOWN; 168 169 if (v & 0xc0) { /* USB or ADP plugged */ 170 val->intval = rn5t618_decode_status(v); 171 } else 172 val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 173 174 return ret; 175 } 176 177 static int rn5t618_battery_present(struct rn5t618_power_info *info, 178 union power_supply_propval *val) 179 { 180 unsigned int v; 181 int ret; 182 183 ret = regmap_read(info->rn5t618->regmap, RN5T618_CHGSTATE, &v); 184 if (ret) 185 return ret; 186 187 v &= CHG_STATE_MASK; 188 if ((v == CHG_STATE_NO_BAT) || (v == CHG_STATE_NO_BAT2)) 189 val->intval = 0; 190 else 191 val->intval = 1; 192 193 return ret; 194 } 195 196 static int rn5t618_battery_voltage_now(struct rn5t618_power_info *info, 197 union power_supply_propval *val) 198 { 199 u16 res; 200 int ret; 201 202 ret = rn5t618_battery_read_doublereg(info, RN5T618_VOLTAGE_1, &res); 203 if (ret) 204 return ret; 205 206 val->intval = res * 2 * 2500 / 4095 * 1000; 207 208 return 0; 209 } 210 211 static int rn5t618_battery_current_now(struct rn5t618_power_info *info, 212 union power_supply_propval *val) 213 { 214 u16 res; 215 int ret; 216 217 ret = rn5t618_battery_read_doublereg(info, RN5T618_CC_AVEREG1, &res); 218 if (ret) 219 return ret; 220 221 /* current is negative when discharging */ 222 val->intval = sign_extend32(res, 13) * 1000; 223 224 return 0; 225 } 226 227 static int rn5t618_battery_capacity(struct rn5t618_power_info *info, 228 union power_supply_propval *val) 229 { 230 unsigned int v; 231 int ret; 232 233 ret = regmap_read(info->rn5t618->regmap, RN5T618_SOC, &v); 234 if (ret) 235 return ret; 236 237 val->intval = v; 238 239 return 0; 240 } 241 242 static int rn5t618_battery_temp(struct rn5t618_power_info *info, 243 union power_supply_propval *val) 244 { 245 u16 res; 246 int ret; 247 248 ret = rn5t618_battery_read_doublereg(info, RN5T618_TEMP_1, &res); 249 if (ret) 250 return ret; 251 252 val->intval = sign_extend32(res, 11) * 10 / 16; 253 254 return 0; 255 } 256 257 static int rn5t618_battery_tte(struct rn5t618_power_info *info, 258 union power_supply_propval *val) 259 { 260 u16 res; 261 int ret; 262 263 ret = rn5t618_battery_read_doublereg(info, RN5T618_TT_EMPTY_H, &res); 264 if (ret) 265 return ret; 266 267 if (res == 65535) 268 return -ENODATA; 269 270 val->intval = res * 60; 271 272 return 0; 273 } 274 275 static int rn5t618_battery_ttf(struct rn5t618_power_info *info, 276 union power_supply_propval *val) 277 { 278 u16 res; 279 int ret; 280 281 ret = rn5t618_battery_read_doublereg(info, RN5T618_TT_FULL_H, &res); 282 if (ret) 283 return ret; 284 285 if (res == 65535) 286 return -ENODATA; 287 288 val->intval = res * 60; 289 290 return 0; 291 } 292 293 static int rn5t618_battery_set_current_limit(struct rn5t618_power_info *info, 294 const union power_supply_propval *val) 295 { 296 if (val->intval < CHG_MIN_CUR) 297 return -EINVAL; 298 299 if (val->intval >= CHG_MAX_CUR) 300 return -EINVAL; 301 302 return regmap_update_bits(info->rn5t618->regmap, 303 RN5T618_CHGISET, 304 0x1F, TO_CUR_REG(val->intval)); 305 } 306 307 static int rn5t618_battery_get_current_limit(struct rn5t618_power_info *info, 308 union power_supply_propval *val) 309 { 310 unsigned int regval; 311 int ret; 312 313 ret = regmap_read(info->rn5t618->regmap, RN5T618_CHGISET, 314 ®val); 315 if (ret < 0) 316 return ret; 317 318 val->intval = FROM_CUR_REG(regval); 319 320 return 0; 321 } 322 323 static int rn5t618_battery_charge_full(struct rn5t618_power_info *info, 324 union power_supply_propval *val) 325 { 326 u16 res; 327 int ret; 328 329 ret = rn5t618_battery_read_doublereg(info, RN5T618_FA_CAP_H, &res); 330 if (ret) 331 return ret; 332 333 val->intval = res * 1000; 334 335 return 0; 336 } 337 338 static int rn5t618_battery_charge_now(struct rn5t618_power_info *info, 339 union power_supply_propval *val) 340 { 341 u16 res; 342 int ret; 343 344 ret = rn5t618_battery_read_doublereg(info, RN5T618_RE_CAP_H, &res); 345 if (ret) 346 return ret; 347 348 val->intval = res * 1000; 349 350 return 0; 351 } 352 353 static int rn5t618_battery_get_property(struct power_supply *psy, 354 enum power_supply_property psp, 355 union power_supply_propval *val) 356 { 357 int ret = 0; 358 struct rn5t618_power_info *info = power_supply_get_drvdata(psy); 359 360 switch (psp) { 361 case POWER_SUPPLY_PROP_STATUS: 362 ret = rn5t618_battery_status(info, val); 363 break; 364 case POWER_SUPPLY_PROP_PRESENT: 365 ret = rn5t618_battery_present(info, val); 366 break; 367 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 368 ret = rn5t618_battery_voltage_now(info, val); 369 break; 370 case POWER_SUPPLY_PROP_CURRENT_NOW: 371 ret = rn5t618_battery_current_now(info, val); 372 break; 373 case POWER_SUPPLY_PROP_CAPACITY: 374 ret = rn5t618_battery_capacity(info, val); 375 break; 376 case POWER_SUPPLY_PROP_TEMP: 377 ret = rn5t618_battery_temp(info, val); 378 break; 379 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW: 380 ret = rn5t618_battery_tte(info, val); 381 break; 382 case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW: 383 ret = rn5t618_battery_ttf(info, val); 384 break; 385 case POWER_SUPPLY_PROP_TECHNOLOGY: 386 val->intval = POWER_SUPPLY_TECHNOLOGY_LION; 387 break; 388 case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT: 389 ret = rn5t618_battery_get_current_limit(info, val); 390 break; 391 case POWER_SUPPLY_PROP_CHARGE_FULL: 392 ret = rn5t618_battery_charge_full(info, val); 393 break; 394 case POWER_SUPPLY_PROP_CHARGE_NOW: 395 ret = rn5t618_battery_charge_now(info, val); 396 break; 397 default: 398 return -EINVAL; 399 } 400 401 return ret; 402 } 403 404 static int rn5t618_battery_set_property(struct power_supply *psy, 405 enum power_supply_property psp, 406 const union power_supply_propval *val) 407 { 408 struct rn5t618_power_info *info = power_supply_get_drvdata(psy); 409 410 switch (psp) { 411 case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT: 412 return rn5t618_battery_set_current_limit(info, val); 413 default: 414 return -EINVAL; 415 } 416 } 417 418 static int rn5t618_battery_property_is_writeable(struct power_supply *psy, 419 enum power_supply_property psp) 420 { 421 switch (psp) { 422 case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT: 423 return true; 424 default: 425 return false; 426 } 427 } 428 429 static int rn5t618_adp_get_property(struct power_supply *psy, 430 enum power_supply_property psp, 431 union power_supply_propval *val) 432 { 433 struct rn5t618_power_info *info = power_supply_get_drvdata(psy); 434 unsigned int chgstate; 435 unsigned int regval; 436 bool online; 437 int ret; 438 439 ret = regmap_read(info->rn5t618->regmap, RN5T618_CHGSTATE, &chgstate); 440 if (ret) 441 return ret; 442 443 online = !!(chgstate & CHG_STATE_ADP_INPUT); 444 445 switch (psp) { 446 case POWER_SUPPLY_PROP_ONLINE: 447 val->intval = online; 448 break; 449 case POWER_SUPPLY_PROP_STATUS: 450 if (!online) { 451 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; 452 break; 453 } 454 val->intval = rn5t618_decode_status(chgstate); 455 if (val->intval != POWER_SUPPLY_STATUS_CHARGING) 456 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; 457 458 break; 459 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 460 ret = regmap_read(info->rn5t618->regmap, 461 RN5T618_REGISET1, ®val); 462 if (ret < 0) 463 return ret; 464 465 val->intval = FROM_CUR_REG(regval); 466 break; 467 default: 468 return -EINVAL; 469 } 470 471 return 0; 472 } 473 474 static int rn5t618_adp_set_property(struct power_supply *psy, 475 enum power_supply_property psp, 476 const union power_supply_propval *val) 477 { 478 struct rn5t618_power_info *info = power_supply_get_drvdata(psy); 479 int ret; 480 481 switch (psp) { 482 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 483 if (val->intval > ADP_MAX_CUR) 484 return -EINVAL; 485 486 if (val->intval < CHG_MIN_CUR) 487 return -EINVAL; 488 489 ret = regmap_write(info->rn5t618->regmap, RN5T618_REGISET1, 490 TO_CUR_REG(val->intval)); 491 if (ret < 0) 492 return ret; 493 494 break; 495 default: 496 return -EINVAL; 497 } 498 499 return 0; 500 } 501 502 static int rn5t618_adp_property_is_writeable(struct power_supply *psy, 503 enum power_supply_property psp) 504 { 505 switch (psp) { 506 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 507 return true; 508 default: 509 return false; 510 } 511 } 512 513 static int rc5t619_usb_get_type(struct rn5t618_power_info *info, 514 union power_supply_propval *val) 515 { 516 unsigned int regval; 517 int ret; 518 519 ret = regmap_read(info->rn5t618->regmap, RN5T618_GCHGDET, ®val); 520 if (ret < 0) 521 return ret; 522 523 switch (regval & GCHGDET_TYPE_MASK) { 524 case GCHGDET_TYPE_SDP: 525 val->intval = POWER_SUPPLY_USB_TYPE_SDP; 526 break; 527 case GCHGDET_TYPE_CDP: 528 val->intval = POWER_SUPPLY_USB_TYPE_CDP; 529 break; 530 case GCHGDET_TYPE_DCP: 531 val->intval = POWER_SUPPLY_USB_TYPE_DCP; 532 break; 533 default: 534 val->intval = POWER_SUPPLY_USB_TYPE_UNKNOWN; 535 } 536 537 return 0; 538 } 539 540 static int rn5t618_usb_get_property(struct power_supply *psy, 541 enum power_supply_property psp, 542 union power_supply_propval *val) 543 { 544 struct rn5t618_power_info *info = power_supply_get_drvdata(psy); 545 unsigned int chgstate; 546 unsigned int regval; 547 bool online; 548 int ret; 549 550 ret = regmap_read(info->rn5t618->regmap, RN5T618_CHGSTATE, &chgstate); 551 if (ret) 552 return ret; 553 554 online = !!(chgstate & CHG_STATE_USB_INPUT); 555 556 switch (psp) { 557 case POWER_SUPPLY_PROP_ONLINE: 558 val->intval = online; 559 break; 560 case POWER_SUPPLY_PROP_STATUS: 561 if (!online) { 562 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; 563 break; 564 } 565 val->intval = rn5t618_decode_status(chgstate); 566 if (val->intval != POWER_SUPPLY_STATUS_CHARGING) 567 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; 568 569 break; 570 case POWER_SUPPLY_PROP_USB_TYPE: 571 if (!online || (info->rn5t618->variant != RC5T619)) 572 return -ENODATA; 573 574 return rc5t619_usb_get_type(info, val); 575 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 576 ret = regmap_read(info->rn5t618->regmap, RN5T618_CHGCTL1, 577 ®val); 578 if (ret < 0) 579 return ret; 580 581 val->intval = 0; 582 if (regval & 2) { 583 ret = regmap_read(info->rn5t618->regmap, 584 RN5T618_REGISET2, 585 ®val); 586 if (ret < 0) 587 return ret; 588 589 val->intval = FROM_CUR_REG(regval); 590 } 591 break; 592 default: 593 return -EINVAL; 594 } 595 596 return 0; 597 } 598 599 static int rn5t618_usb_set_property(struct power_supply *psy, 600 enum power_supply_property psp, 601 const union power_supply_propval *val) 602 { 603 struct rn5t618_power_info *info = power_supply_get_drvdata(psy); 604 int ret; 605 606 switch (psp) { 607 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 608 if (val->intval > USB_MAX_CUR) 609 return -EINVAL; 610 611 if (val->intval < CHG_MIN_CUR) 612 return -EINVAL; 613 614 ret = regmap_write(info->rn5t618->regmap, RN5T618_REGISET2, 615 0xE0 | TO_CUR_REG(val->intval)); 616 if (ret < 0) 617 return ret; 618 619 break; 620 default: 621 return -EINVAL; 622 } 623 624 return 0; 625 } 626 627 static int rn5t618_usb_property_is_writeable(struct power_supply *psy, 628 enum power_supply_property psp) 629 { 630 switch (psp) { 631 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 632 return true; 633 default: 634 return false; 635 } 636 } 637 638 static const struct power_supply_desc rn5t618_battery_desc = { 639 .name = "rn5t618-battery", 640 .type = POWER_SUPPLY_TYPE_BATTERY, 641 .properties = rn5t618_battery_props, 642 .num_properties = ARRAY_SIZE(rn5t618_battery_props), 643 .get_property = rn5t618_battery_get_property, 644 .set_property = rn5t618_battery_set_property, 645 .property_is_writeable = rn5t618_battery_property_is_writeable, 646 }; 647 648 static const struct power_supply_desc rn5t618_adp_desc = { 649 .name = "rn5t618-adp", 650 .type = POWER_SUPPLY_TYPE_MAINS, 651 .properties = rn5t618_adp_props, 652 .num_properties = ARRAY_SIZE(rn5t618_adp_props), 653 .get_property = rn5t618_adp_get_property, 654 .set_property = rn5t618_adp_set_property, 655 .property_is_writeable = rn5t618_adp_property_is_writeable, 656 }; 657 658 static const struct power_supply_desc rn5t618_usb_desc = { 659 .name = "rn5t618-usb", 660 .type = POWER_SUPPLY_TYPE_USB, 661 .usb_types = rn5t618_usb_types, 662 .num_usb_types = ARRAY_SIZE(rn5t618_usb_types), 663 .properties = rn5t618_usb_props, 664 .num_properties = ARRAY_SIZE(rn5t618_usb_props), 665 .get_property = rn5t618_usb_get_property, 666 .set_property = rn5t618_usb_set_property, 667 .property_is_writeable = rn5t618_usb_property_is_writeable, 668 }; 669 670 static irqreturn_t rn5t618_charger_irq(int irq, void *data) 671 { 672 struct device *dev = data; 673 struct rn5t618_power_info *info = dev_get_drvdata(dev); 674 675 unsigned int ctrl, stat1, stat2, err; 676 677 regmap_read(info->rn5t618->regmap, RN5T618_CHGERR_IRR, &err); 678 regmap_read(info->rn5t618->regmap, RN5T618_CHGCTRL_IRR, &ctrl); 679 regmap_read(info->rn5t618->regmap, RN5T618_CHGSTAT_IRR1, &stat1); 680 regmap_read(info->rn5t618->regmap, RN5T618_CHGSTAT_IRR2, &stat2); 681 682 regmap_write(info->rn5t618->regmap, RN5T618_CHGERR_IRR, 0); 683 regmap_write(info->rn5t618->regmap, RN5T618_CHGCTRL_IRR, 0); 684 regmap_write(info->rn5t618->regmap, RN5T618_CHGSTAT_IRR1, 0); 685 regmap_write(info->rn5t618->regmap, RN5T618_CHGSTAT_IRR2, 0); 686 687 dev_dbg(dev, "chgerr: %x chgctrl: %x chgstat: %x chgstat2: %x\n", 688 err, ctrl, stat1, stat2); 689 690 power_supply_changed(info->usb); 691 power_supply_changed(info->adp); 692 power_supply_changed(info->battery); 693 694 return IRQ_HANDLED; 695 } 696 697 static int rn5t618_power_probe(struct platform_device *pdev) 698 { 699 int ret = 0; 700 unsigned int v; 701 struct power_supply_config psy_cfg = {}; 702 struct rn5t618_power_info *info; 703 704 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); 705 if (!info) 706 return -ENOMEM; 707 708 info->pdev = pdev; 709 info->rn5t618 = dev_get_drvdata(pdev->dev.parent); 710 info->irq = -1; 711 712 platform_set_drvdata(pdev, info); 713 714 ret = regmap_read(info->rn5t618->regmap, RN5T618_CONTROL, &v); 715 if (ret) 716 return ret; 717 718 if (!(v & FG_ENABLE)) { 719 /* E.g. the vendor kernels of various Kobo and Tolino Ebook 720 * readers disable the fuel gauge on shutdown. If a kernel 721 * without fuel gauge support is booted after that, the fuel 722 * gauge will get decalibrated. 723 */ 724 dev_info(&pdev->dev, "Fuel gauge not enabled, enabling now\n"); 725 dev_info(&pdev->dev, "Expect imprecise results\n"); 726 regmap_update_bits(info->rn5t618->regmap, RN5T618_CONTROL, 727 FG_ENABLE, FG_ENABLE); 728 } 729 730 psy_cfg.drv_data = info; 731 info->battery = devm_power_supply_register(&pdev->dev, 732 &rn5t618_battery_desc, 733 &psy_cfg); 734 if (IS_ERR(info->battery)) { 735 ret = PTR_ERR(info->battery); 736 dev_err(&pdev->dev, "failed to register battery: %d\n", ret); 737 return ret; 738 } 739 740 info->adp = devm_power_supply_register(&pdev->dev, 741 &rn5t618_adp_desc, 742 &psy_cfg); 743 if (IS_ERR(info->adp)) { 744 ret = PTR_ERR(info->adp); 745 dev_err(&pdev->dev, "failed to register adp: %d\n", ret); 746 return ret; 747 } 748 749 info->usb = devm_power_supply_register(&pdev->dev, 750 &rn5t618_usb_desc, 751 &psy_cfg); 752 if (IS_ERR(info->usb)) { 753 ret = PTR_ERR(info->usb); 754 dev_err(&pdev->dev, "failed to register usb: %d\n", ret); 755 return ret; 756 } 757 758 if (info->rn5t618->irq_data) 759 info->irq = regmap_irq_get_virq(info->rn5t618->irq_data, 760 RN5T618_IRQ_CHG); 761 762 if (info->irq < 0) 763 info->irq = -1; 764 else { 765 ret = devm_request_threaded_irq(&pdev->dev, info->irq, NULL, 766 rn5t618_charger_irq, 767 IRQF_ONESHOT, 768 "rn5t618_power", 769 &pdev->dev); 770 771 if (ret < 0) { 772 dev_err(&pdev->dev, "request IRQ:%d fail\n", 773 info->irq); 774 info->irq = -1; 775 } 776 } 777 778 return 0; 779 } 780 781 static struct platform_driver rn5t618_power_driver = { 782 .driver = { 783 .name = "rn5t618-power", 784 }, 785 .probe = rn5t618_power_probe, 786 }; 787 788 module_platform_driver(rn5t618_power_driver); 789 MODULE_ALIAS("platform:rn5t618-power"); 790 MODULE_DESCRIPTION("Power supply driver for RICOH RN5T618"); 791 MODULE_LICENSE("GPL"); 792