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