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