sc27xx_fuel_gauge.c (35510B)
1// SPDX-License-Identifier: GPL-2.0 2// Copyright (C) 2018 Spreadtrum Communications Inc. 3 4#include <linux/gpio/consumer.h> 5#include <linux/iio/consumer.h> 6#include <linux/interrupt.h> 7#include <linux/kernel.h> 8#include <linux/math64.h> 9#include <linux/module.h> 10#include <linux/nvmem-consumer.h> 11#include <linux/of.h> 12#include <linux/platform_device.h> 13#include <linux/power_supply.h> 14#include <linux/regmap.h> 15#include <linux/slab.h> 16 17/* PMIC global control registers definition */ 18#define SC27XX_MODULE_EN0 0xc08 19#define SC27XX_CLK_EN0 0xc18 20#define SC27XX_FGU_EN BIT(7) 21#define SC27XX_FGU_RTC_EN BIT(6) 22 23/* FGU registers definition */ 24#define SC27XX_FGU_START 0x0 25#define SC27XX_FGU_CONFIG 0x4 26#define SC27XX_FGU_ADC_CONFIG 0x8 27#define SC27XX_FGU_STATUS 0xc 28#define SC27XX_FGU_INT_EN 0x10 29#define SC27XX_FGU_INT_CLR 0x14 30#define SC27XX_FGU_INT_STS 0x1c 31#define SC27XX_FGU_VOLTAGE 0x20 32#define SC27XX_FGU_OCV 0x24 33#define SC27XX_FGU_POCV 0x28 34#define SC27XX_FGU_CURRENT 0x2c 35#define SC27XX_FGU_LOW_OVERLOAD 0x34 36#define SC27XX_FGU_CLBCNT_SETH 0x50 37#define SC27XX_FGU_CLBCNT_SETL 0x54 38#define SC27XX_FGU_CLBCNT_DELTH 0x58 39#define SC27XX_FGU_CLBCNT_DELTL 0x5c 40#define SC27XX_FGU_CLBCNT_VALH 0x68 41#define SC27XX_FGU_CLBCNT_VALL 0x6c 42#define SC27XX_FGU_CLBCNT_QMAXL 0x74 43#define SC27XX_FGU_USER_AREA_SET 0xa0 44#define SC27XX_FGU_USER_AREA_CLEAR 0xa4 45#define SC27XX_FGU_USER_AREA_STATUS 0xa8 46#define SC27XX_FGU_VOLTAGE_BUF 0xd0 47#define SC27XX_FGU_CURRENT_BUF 0xf0 48 49#define SC27XX_WRITE_SELCLB_EN BIT(0) 50#define SC27XX_FGU_CLBCNT_MASK GENMASK(15, 0) 51#define SC27XX_FGU_CLBCNT_SHIFT 16 52#define SC27XX_FGU_LOW_OVERLOAD_MASK GENMASK(12, 0) 53 54#define SC27XX_FGU_INT_MASK GENMASK(9, 0) 55#define SC27XX_FGU_LOW_OVERLOAD_INT BIT(0) 56#define SC27XX_FGU_CLBCNT_DELTA_INT BIT(2) 57 58#define SC27XX_FGU_MODE_AREA_MASK GENMASK(15, 12) 59#define SC27XX_FGU_CAP_AREA_MASK GENMASK(11, 0) 60#define SC27XX_FGU_MODE_AREA_SHIFT 12 61 62#define SC27XX_FGU_FIRST_POWERTON GENMASK(3, 0) 63#define SC27XX_FGU_DEFAULT_CAP GENMASK(11, 0) 64#define SC27XX_FGU_NORMAIL_POWERTON 0x5 65 66#define SC27XX_FGU_CUR_BASIC_ADC 8192 67#define SC27XX_FGU_SAMPLE_HZ 2 68/* micro Ohms */ 69#define SC27XX_FGU_IDEAL_RESISTANCE 20000 70 71/* 72 * struct sc27xx_fgu_data: describe the FGU device 73 * @regmap: regmap for register access 74 * @dev: platform device 75 * @battery: battery power supply 76 * @base: the base offset for the controller 77 * @lock: protect the structure 78 * @gpiod: GPIO for battery detection 79 * @channel: IIO channel to get battery temperature 80 * @charge_chan: IIO channel to get charge voltage 81 * @internal_resist: the battery internal resistance in mOhm 82 * @total_cap: the total capacity of the battery in mAh 83 * @init_cap: the initial capacity of the battery in mAh 84 * @alarm_cap: the alarm capacity 85 * @init_clbcnt: the initial coulomb counter 86 * @max_volt: the maximum constant input voltage in millivolt 87 * @min_volt: the minimum drained battery voltage in microvolt 88 * @boot_volt: the voltage measured during boot in microvolt 89 * @table_len: the capacity table length 90 * @resist_table_len: the resistance table length 91 * @cur_1000ma_adc: ADC value corresponding to 1000 mA 92 * @vol_1000mv_adc: ADC value corresponding to 1000 mV 93 * @calib_resist: the real resistance of coulomb counter chip in uOhm 94 * @cap_table: capacity table with corresponding ocv 95 * @resist_table: resistance percent table with corresponding temperature 96 */ 97struct sc27xx_fgu_data { 98 struct regmap *regmap; 99 struct device *dev; 100 struct power_supply *battery; 101 u32 base; 102 struct mutex lock; 103 struct gpio_desc *gpiod; 104 struct iio_channel *channel; 105 struct iio_channel *charge_chan; 106 bool bat_present; 107 int internal_resist; 108 int total_cap; 109 int init_cap; 110 int alarm_cap; 111 int init_clbcnt; 112 int max_volt; 113 int min_volt; 114 int boot_volt; 115 int table_len; 116 int resist_table_len; 117 int cur_1000ma_adc; 118 int vol_1000mv_adc; 119 int calib_resist; 120 struct power_supply_battery_ocv_table *cap_table; 121 struct power_supply_resistance_temp_table *resist_table; 122}; 123 124static int sc27xx_fgu_cap_to_clbcnt(struct sc27xx_fgu_data *data, int capacity); 125static void sc27xx_fgu_capacity_calibration(struct sc27xx_fgu_data *data, 126 int cap, bool int_mode); 127static void sc27xx_fgu_adjust_cap(struct sc27xx_fgu_data *data, int cap); 128static int sc27xx_fgu_get_temp(struct sc27xx_fgu_data *data, int *temp); 129 130static const char * const sc27xx_charger_supply_name[] = { 131 "sc2731_charger", 132 "sc2720_charger", 133 "sc2721_charger", 134 "sc2723_charger", 135}; 136 137static int sc27xx_fgu_adc_to_current(struct sc27xx_fgu_data *data, s64 adc) 138{ 139 return DIV_S64_ROUND_CLOSEST(adc * 1000, data->cur_1000ma_adc); 140} 141 142static int sc27xx_fgu_adc_to_voltage(struct sc27xx_fgu_data *data, s64 adc) 143{ 144 return DIV_S64_ROUND_CLOSEST(adc * 1000, data->vol_1000mv_adc); 145} 146 147static int sc27xx_fgu_voltage_to_adc(struct sc27xx_fgu_data *data, int vol) 148{ 149 return DIV_ROUND_CLOSEST(vol * data->vol_1000mv_adc, 1000); 150} 151 152static bool sc27xx_fgu_is_first_poweron(struct sc27xx_fgu_data *data) 153{ 154 int ret, status, cap, mode; 155 156 ret = regmap_read(data->regmap, 157 data->base + SC27XX_FGU_USER_AREA_STATUS, &status); 158 if (ret) 159 return false; 160 161 /* 162 * We use low 4 bits to save the last battery capacity and high 12 bits 163 * to save the system boot mode. 164 */ 165 mode = (status & SC27XX_FGU_MODE_AREA_MASK) >> SC27XX_FGU_MODE_AREA_SHIFT; 166 cap = status & SC27XX_FGU_CAP_AREA_MASK; 167 168 /* 169 * When FGU has been powered down, the user area registers became 170 * default value (0xffff), which can be used to valid if the system is 171 * first power on or not. 172 */ 173 if (mode == SC27XX_FGU_FIRST_POWERTON || cap == SC27XX_FGU_DEFAULT_CAP) 174 return true; 175 176 return false; 177} 178 179static int sc27xx_fgu_save_boot_mode(struct sc27xx_fgu_data *data, 180 int boot_mode) 181{ 182 int ret; 183 184 ret = regmap_update_bits(data->regmap, 185 data->base + SC27XX_FGU_USER_AREA_CLEAR, 186 SC27XX_FGU_MODE_AREA_MASK, 187 SC27XX_FGU_MODE_AREA_MASK); 188 if (ret) 189 return ret; 190 191 /* 192 * Since the user area registers are put on power always-on region, 193 * then these registers changing time will be a little long. Thus 194 * here we should delay 200us to wait until values are updated 195 * successfully according to the datasheet. 196 */ 197 udelay(200); 198 199 ret = regmap_update_bits(data->regmap, 200 data->base + SC27XX_FGU_USER_AREA_SET, 201 SC27XX_FGU_MODE_AREA_MASK, 202 boot_mode << SC27XX_FGU_MODE_AREA_SHIFT); 203 if (ret) 204 return ret; 205 206 /* 207 * Since the user area registers are put on power always-on region, 208 * then these registers changing time will be a little long. Thus 209 * here we should delay 200us to wait until values are updated 210 * successfully according to the datasheet. 211 */ 212 udelay(200); 213 214 /* 215 * According to the datasheet, we should set the USER_AREA_CLEAR to 0 to 216 * make the user area data available, otherwise we can not save the user 217 * area data. 218 */ 219 return regmap_update_bits(data->regmap, 220 data->base + SC27XX_FGU_USER_AREA_CLEAR, 221 SC27XX_FGU_MODE_AREA_MASK, 0); 222} 223 224static int sc27xx_fgu_save_last_cap(struct sc27xx_fgu_data *data, int cap) 225{ 226 int ret; 227 228 ret = regmap_update_bits(data->regmap, 229 data->base + SC27XX_FGU_USER_AREA_CLEAR, 230 SC27XX_FGU_CAP_AREA_MASK, 231 SC27XX_FGU_CAP_AREA_MASK); 232 if (ret) 233 return ret; 234 235 /* 236 * Since the user area registers are put on power always-on region, 237 * then these registers changing time will be a little long. Thus 238 * here we should delay 200us to wait until values are updated 239 * successfully according to the datasheet. 240 */ 241 udelay(200); 242 243 ret = regmap_update_bits(data->regmap, 244 data->base + SC27XX_FGU_USER_AREA_SET, 245 SC27XX_FGU_CAP_AREA_MASK, cap); 246 if (ret) 247 return ret; 248 249 /* 250 * Since the user area registers are put on power always-on region, 251 * then these registers changing time will be a little long. Thus 252 * here we should delay 200us to wait until values are updated 253 * successfully according to the datasheet. 254 */ 255 udelay(200); 256 257 /* 258 * According to the datasheet, we should set the USER_AREA_CLEAR to 0 to 259 * make the user area data available, otherwise we can not save the user 260 * area data. 261 */ 262 return regmap_update_bits(data->regmap, 263 data->base + SC27XX_FGU_USER_AREA_CLEAR, 264 SC27XX_FGU_CAP_AREA_MASK, 0); 265} 266 267static int sc27xx_fgu_read_last_cap(struct sc27xx_fgu_data *data, int *cap) 268{ 269 int ret, value; 270 271 ret = regmap_read(data->regmap, 272 data->base + SC27XX_FGU_USER_AREA_STATUS, &value); 273 if (ret) 274 return ret; 275 276 *cap = value & SC27XX_FGU_CAP_AREA_MASK; 277 return 0; 278} 279 280/* 281 * When system boots on, we can not read battery capacity from coulomb 282 * registers, since now the coulomb registers are invalid. So we should 283 * calculate the battery open circuit voltage, and get current battery 284 * capacity according to the capacity table. 285 */ 286static int sc27xx_fgu_get_boot_capacity(struct sc27xx_fgu_data *data, int *cap) 287{ 288 int volt, cur, oci, ocv, ret; 289 bool is_first_poweron = sc27xx_fgu_is_first_poweron(data); 290 291 /* 292 * If system is not the first power on, we should use the last saved 293 * battery capacity as the initial battery capacity. Otherwise we should 294 * re-calculate the initial battery capacity. 295 */ 296 if (!is_first_poweron) { 297 ret = sc27xx_fgu_read_last_cap(data, cap); 298 if (ret) 299 return ret; 300 301 return sc27xx_fgu_save_boot_mode(data, SC27XX_FGU_NORMAIL_POWERTON); 302 } 303 304 /* 305 * After system booting on, the SC27XX_FGU_CLBCNT_QMAXL register saved 306 * the first sampled open circuit current. 307 */ 308 ret = regmap_read(data->regmap, data->base + SC27XX_FGU_CLBCNT_QMAXL, 309 &cur); 310 if (ret) 311 return ret; 312 313 cur <<= 1; 314 oci = sc27xx_fgu_adc_to_current(data, cur - SC27XX_FGU_CUR_BASIC_ADC); 315 316 /* 317 * Should get the OCV from SC27XX_FGU_POCV register at the system 318 * beginning. It is ADC values reading from registers which need to 319 * convert the corresponding voltage. 320 */ 321 ret = regmap_read(data->regmap, data->base + SC27XX_FGU_POCV, &volt); 322 if (ret) 323 return ret; 324 325 volt = sc27xx_fgu_adc_to_voltage(data, volt); 326 ocv = volt * 1000 - oci * data->internal_resist; 327 data->boot_volt = ocv; 328 329 /* 330 * Parse the capacity table to look up the correct capacity percent 331 * according to current battery's corresponding OCV values. 332 */ 333 *cap = power_supply_ocv2cap_simple(data->cap_table, data->table_len, 334 ocv); 335 336 ret = sc27xx_fgu_save_last_cap(data, *cap); 337 if (ret) 338 return ret; 339 340 return sc27xx_fgu_save_boot_mode(data, SC27XX_FGU_NORMAIL_POWERTON); 341} 342 343static int sc27xx_fgu_set_clbcnt(struct sc27xx_fgu_data *data, int clbcnt) 344{ 345 int ret; 346 347 ret = regmap_update_bits(data->regmap, 348 data->base + SC27XX_FGU_CLBCNT_SETL, 349 SC27XX_FGU_CLBCNT_MASK, clbcnt); 350 if (ret) 351 return ret; 352 353 ret = regmap_update_bits(data->regmap, 354 data->base + SC27XX_FGU_CLBCNT_SETH, 355 SC27XX_FGU_CLBCNT_MASK, 356 clbcnt >> SC27XX_FGU_CLBCNT_SHIFT); 357 if (ret) 358 return ret; 359 360 return regmap_update_bits(data->regmap, data->base + SC27XX_FGU_START, 361 SC27XX_WRITE_SELCLB_EN, 362 SC27XX_WRITE_SELCLB_EN); 363} 364 365static int sc27xx_fgu_get_clbcnt(struct sc27xx_fgu_data *data, int *clb_cnt) 366{ 367 int ccl, cch, ret; 368 369 ret = regmap_read(data->regmap, data->base + SC27XX_FGU_CLBCNT_VALL, 370 &ccl); 371 if (ret) 372 return ret; 373 374 ret = regmap_read(data->regmap, data->base + SC27XX_FGU_CLBCNT_VALH, 375 &cch); 376 if (ret) 377 return ret; 378 379 *clb_cnt = ccl & SC27XX_FGU_CLBCNT_MASK; 380 *clb_cnt |= (cch & SC27XX_FGU_CLBCNT_MASK) << SC27XX_FGU_CLBCNT_SHIFT; 381 382 return 0; 383} 384 385static int sc27xx_fgu_get_vol_now(struct sc27xx_fgu_data *data, int *val) 386{ 387 int ret; 388 u32 vol; 389 390 ret = regmap_read(data->regmap, data->base + SC27XX_FGU_VOLTAGE_BUF, 391 &vol); 392 if (ret) 393 return ret; 394 395 /* 396 * It is ADC values reading from registers which need to convert to 397 * corresponding voltage values. 398 */ 399 *val = sc27xx_fgu_adc_to_voltage(data, vol); 400 401 return 0; 402} 403 404static int sc27xx_fgu_get_cur_now(struct sc27xx_fgu_data *data, int *val) 405{ 406 int ret; 407 u32 cur; 408 409 ret = regmap_read(data->regmap, data->base + SC27XX_FGU_CURRENT_BUF, 410 &cur); 411 if (ret) 412 return ret; 413 414 /* 415 * It is ADC values reading from registers which need to convert to 416 * corresponding current values. 417 */ 418 *val = sc27xx_fgu_adc_to_current(data, cur - SC27XX_FGU_CUR_BASIC_ADC); 419 420 return 0; 421} 422 423static int sc27xx_fgu_get_capacity(struct sc27xx_fgu_data *data, int *cap) 424{ 425 int ret, cur_clbcnt, delta_clbcnt, delta_cap, temp; 426 427 /* Get current coulomb counters firstly */ 428 ret = sc27xx_fgu_get_clbcnt(data, &cur_clbcnt); 429 if (ret) 430 return ret; 431 432 delta_clbcnt = cur_clbcnt - data->init_clbcnt; 433 434 /* 435 * Convert coulomb counter to delta capacity (mAh), and set multiplier 436 * as 10 to improve the precision. 437 */ 438 temp = DIV_ROUND_CLOSEST(delta_clbcnt * 10, 36 * SC27XX_FGU_SAMPLE_HZ); 439 temp = sc27xx_fgu_adc_to_current(data, temp / 1000); 440 441 /* 442 * Convert to capacity percent of the battery total capacity, 443 * and multiplier is 100 too. 444 */ 445 delta_cap = DIV_ROUND_CLOSEST(temp * 100, data->total_cap); 446 *cap = delta_cap + data->init_cap; 447 448 /* Calibrate the battery capacity in a normal range. */ 449 sc27xx_fgu_capacity_calibration(data, *cap, false); 450 451 return 0; 452} 453 454static int sc27xx_fgu_get_vbat_vol(struct sc27xx_fgu_data *data, int *val) 455{ 456 int ret, vol; 457 458 ret = regmap_read(data->regmap, data->base + SC27XX_FGU_VOLTAGE, &vol); 459 if (ret) 460 return ret; 461 462 /* 463 * It is ADC values reading from registers which need to convert to 464 * corresponding voltage values. 465 */ 466 *val = sc27xx_fgu_adc_to_voltage(data, vol); 467 468 return 0; 469} 470 471static int sc27xx_fgu_get_current(struct sc27xx_fgu_data *data, int *val) 472{ 473 int ret, cur; 474 475 ret = regmap_read(data->regmap, data->base + SC27XX_FGU_CURRENT, &cur); 476 if (ret) 477 return ret; 478 479 /* 480 * It is ADC values reading from registers which need to convert to 481 * corresponding current values. 482 */ 483 *val = sc27xx_fgu_adc_to_current(data, cur - SC27XX_FGU_CUR_BASIC_ADC); 484 485 return 0; 486} 487 488static int sc27xx_fgu_get_vbat_ocv(struct sc27xx_fgu_data *data, int *val) 489{ 490 int vol, cur, ret, temp, resistance; 491 492 ret = sc27xx_fgu_get_vbat_vol(data, &vol); 493 if (ret) 494 return ret; 495 496 ret = sc27xx_fgu_get_current(data, &cur); 497 if (ret) 498 return ret; 499 500 resistance = data->internal_resist; 501 if (data->resist_table_len > 0) { 502 ret = sc27xx_fgu_get_temp(data, &temp); 503 if (ret) 504 return ret; 505 506 resistance = power_supply_temp2resist_simple(data->resist_table, 507 data->resist_table_len, temp); 508 resistance = data->internal_resist * resistance / 100; 509 } 510 511 /* Return the battery OCV in micro volts. */ 512 *val = vol * 1000 - cur * resistance; 513 514 return 0; 515} 516 517static int sc27xx_fgu_get_charge_vol(struct sc27xx_fgu_data *data, int *val) 518{ 519 int ret, vol; 520 521 ret = iio_read_channel_processed(data->charge_chan, &vol); 522 if (ret < 0) 523 return ret; 524 525 *val = vol * 1000; 526 return 0; 527} 528 529static int sc27xx_fgu_get_temp(struct sc27xx_fgu_data *data, int *temp) 530{ 531 return iio_read_channel_processed(data->channel, temp); 532} 533 534static int sc27xx_fgu_get_health(struct sc27xx_fgu_data *data, int *health) 535{ 536 int ret, vol; 537 538 ret = sc27xx_fgu_get_vbat_vol(data, &vol); 539 if (ret) 540 return ret; 541 542 if (vol > data->max_volt) 543 *health = POWER_SUPPLY_HEALTH_OVERVOLTAGE; 544 else 545 *health = POWER_SUPPLY_HEALTH_GOOD; 546 547 return 0; 548} 549 550static int sc27xx_fgu_get_status(struct sc27xx_fgu_data *data, int *status) 551{ 552 union power_supply_propval val; 553 struct power_supply *psy; 554 int i, ret = -EINVAL; 555 556 for (i = 0; i < ARRAY_SIZE(sc27xx_charger_supply_name); i++) { 557 psy = power_supply_get_by_name(sc27xx_charger_supply_name[i]); 558 if (!psy) 559 continue; 560 561 ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_STATUS, 562 &val); 563 power_supply_put(psy); 564 if (ret) 565 return ret; 566 567 *status = val.intval; 568 } 569 570 return ret; 571} 572 573static int sc27xx_fgu_get_property(struct power_supply *psy, 574 enum power_supply_property psp, 575 union power_supply_propval *val) 576{ 577 struct sc27xx_fgu_data *data = power_supply_get_drvdata(psy); 578 int ret = 0; 579 int value; 580 581 mutex_lock(&data->lock); 582 583 switch (psp) { 584 case POWER_SUPPLY_PROP_STATUS: 585 ret = sc27xx_fgu_get_status(data, &value); 586 if (ret) 587 goto error; 588 589 val->intval = value; 590 break; 591 592 case POWER_SUPPLY_PROP_HEALTH: 593 ret = sc27xx_fgu_get_health(data, &value); 594 if (ret) 595 goto error; 596 597 val->intval = value; 598 break; 599 600 case POWER_SUPPLY_PROP_PRESENT: 601 val->intval = data->bat_present; 602 break; 603 604 case POWER_SUPPLY_PROP_TEMP: 605 ret = sc27xx_fgu_get_temp(data, &value); 606 if (ret) 607 goto error; 608 609 val->intval = value; 610 break; 611 612 case POWER_SUPPLY_PROP_TECHNOLOGY: 613 val->intval = POWER_SUPPLY_TECHNOLOGY_LION; 614 break; 615 616 case POWER_SUPPLY_PROP_CAPACITY: 617 ret = sc27xx_fgu_get_capacity(data, &value); 618 if (ret) 619 goto error; 620 621 val->intval = value; 622 break; 623 624 case POWER_SUPPLY_PROP_VOLTAGE_AVG: 625 ret = sc27xx_fgu_get_vbat_vol(data, &value); 626 if (ret) 627 goto error; 628 629 val->intval = value * 1000; 630 break; 631 632 case POWER_SUPPLY_PROP_VOLTAGE_OCV: 633 ret = sc27xx_fgu_get_vbat_ocv(data, &value); 634 if (ret) 635 goto error; 636 637 val->intval = value; 638 break; 639 640 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: 641 ret = sc27xx_fgu_get_charge_vol(data, &value); 642 if (ret) 643 goto error; 644 645 val->intval = value; 646 break; 647 648 case POWER_SUPPLY_PROP_CURRENT_AVG: 649 ret = sc27xx_fgu_get_current(data, &value); 650 if (ret) 651 goto error; 652 653 val->intval = value * 1000; 654 break; 655 656 case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN: 657 val->intval = data->total_cap * 1000; 658 break; 659 660 case POWER_SUPPLY_PROP_CHARGE_NOW: 661 ret = sc27xx_fgu_get_clbcnt(data, &value); 662 if (ret) 663 goto error; 664 665 value = DIV_ROUND_CLOSEST(value * 10, 666 36 * SC27XX_FGU_SAMPLE_HZ); 667 val->intval = sc27xx_fgu_adc_to_current(data, value); 668 669 break; 670 671 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 672 ret = sc27xx_fgu_get_vol_now(data, &value); 673 if (ret) 674 goto error; 675 676 val->intval = value * 1000; 677 break; 678 679 case POWER_SUPPLY_PROP_CURRENT_NOW: 680 ret = sc27xx_fgu_get_cur_now(data, &value); 681 if (ret) 682 goto error; 683 684 val->intval = value * 1000; 685 break; 686 687 case POWER_SUPPLY_PROP_VOLTAGE_BOOT: 688 val->intval = data->boot_volt; 689 break; 690 691 default: 692 ret = -EINVAL; 693 break; 694 } 695 696error: 697 mutex_unlock(&data->lock); 698 return ret; 699} 700 701static int sc27xx_fgu_set_property(struct power_supply *psy, 702 enum power_supply_property psp, 703 const union power_supply_propval *val) 704{ 705 struct sc27xx_fgu_data *data = power_supply_get_drvdata(psy); 706 int ret; 707 708 mutex_lock(&data->lock); 709 710 switch (psp) { 711 case POWER_SUPPLY_PROP_CAPACITY: 712 ret = sc27xx_fgu_save_last_cap(data, val->intval); 713 if (ret < 0) 714 dev_err(data->dev, "failed to save battery capacity\n"); 715 break; 716 717 case POWER_SUPPLY_PROP_CALIBRATE: 718 sc27xx_fgu_adjust_cap(data, val->intval); 719 ret = 0; 720 break; 721 722 case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN: 723 data->total_cap = val->intval / 1000; 724 ret = 0; 725 break; 726 727 default: 728 ret = -EINVAL; 729 } 730 731 mutex_unlock(&data->lock); 732 733 return ret; 734} 735 736static void sc27xx_fgu_external_power_changed(struct power_supply *psy) 737{ 738 struct sc27xx_fgu_data *data = power_supply_get_drvdata(psy); 739 740 power_supply_changed(data->battery); 741} 742 743static int sc27xx_fgu_property_is_writeable(struct power_supply *psy, 744 enum power_supply_property psp) 745{ 746 return psp == POWER_SUPPLY_PROP_CAPACITY || 747 psp == POWER_SUPPLY_PROP_CALIBRATE || 748 psp == POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN; 749} 750 751static enum power_supply_property sc27xx_fgu_props[] = { 752 POWER_SUPPLY_PROP_STATUS, 753 POWER_SUPPLY_PROP_HEALTH, 754 POWER_SUPPLY_PROP_PRESENT, 755 POWER_SUPPLY_PROP_TEMP, 756 POWER_SUPPLY_PROP_TECHNOLOGY, 757 POWER_SUPPLY_PROP_CAPACITY, 758 POWER_SUPPLY_PROP_VOLTAGE_NOW, 759 POWER_SUPPLY_PROP_VOLTAGE_OCV, 760 POWER_SUPPLY_PROP_VOLTAGE_AVG, 761 POWER_SUPPLY_PROP_VOLTAGE_BOOT, 762 POWER_SUPPLY_PROP_CURRENT_NOW, 763 POWER_SUPPLY_PROP_CURRENT_AVG, 764 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE, 765 POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, 766 POWER_SUPPLY_PROP_CALIBRATE, 767 POWER_SUPPLY_PROP_CHARGE_NOW 768}; 769 770static const struct power_supply_desc sc27xx_fgu_desc = { 771 .name = "sc27xx-fgu", 772 .type = POWER_SUPPLY_TYPE_BATTERY, 773 .properties = sc27xx_fgu_props, 774 .num_properties = ARRAY_SIZE(sc27xx_fgu_props), 775 .get_property = sc27xx_fgu_get_property, 776 .set_property = sc27xx_fgu_set_property, 777 .external_power_changed = sc27xx_fgu_external_power_changed, 778 .property_is_writeable = sc27xx_fgu_property_is_writeable, 779 .no_thermal = true, 780}; 781 782static void sc27xx_fgu_adjust_cap(struct sc27xx_fgu_data *data, int cap) 783{ 784 int ret; 785 786 data->init_cap = cap; 787 ret = sc27xx_fgu_get_clbcnt(data, &data->init_clbcnt); 788 if (ret) 789 dev_err(data->dev, "failed to get init coulomb counter\n"); 790} 791 792static void sc27xx_fgu_capacity_calibration(struct sc27xx_fgu_data *data, 793 int cap, bool int_mode) 794{ 795 int ret, ocv, chg_sts, adc; 796 797 ret = sc27xx_fgu_get_vbat_ocv(data, &ocv); 798 if (ret) { 799 dev_err(data->dev, "get battery ocv error.\n"); 800 return; 801 } 802 803 ret = sc27xx_fgu_get_status(data, &chg_sts); 804 if (ret) { 805 dev_err(data->dev, "get charger status error.\n"); 806 return; 807 } 808 809 /* 810 * If we are in charging mode, then we do not need to calibrate the 811 * lower capacity. 812 */ 813 if (chg_sts == POWER_SUPPLY_STATUS_CHARGING) 814 return; 815 816 if ((ocv > data->cap_table[0].ocv && cap < 100) || cap > 100) { 817 /* 818 * If current OCV value is larger than the max OCV value in 819 * OCV table, or the current capacity is larger than 100, 820 * we should force the inititial capacity to 100. 821 */ 822 sc27xx_fgu_adjust_cap(data, 100); 823 } else if (ocv <= data->cap_table[data->table_len - 1].ocv) { 824 /* 825 * If current OCV value is leass than the minimum OCV value in 826 * OCV table, we should force the inititial capacity to 0. 827 */ 828 sc27xx_fgu_adjust_cap(data, 0); 829 } else if ((ocv > data->cap_table[data->table_len - 1].ocv && cap <= 0) || 830 (ocv > data->min_volt && cap <= data->alarm_cap)) { 831 /* 832 * If current OCV value is not matchable with current capacity, 833 * we should re-calculate current capacity by looking up the 834 * OCV table. 835 */ 836 int cur_cap = power_supply_ocv2cap_simple(data->cap_table, 837 data->table_len, ocv); 838 839 sc27xx_fgu_adjust_cap(data, cur_cap); 840 } else if (ocv <= data->min_volt) { 841 /* 842 * If current OCV value is less than the low alarm voltage, but 843 * current capacity is larger than the alarm capacity, we should 844 * adjust the inititial capacity to alarm capacity. 845 */ 846 if (cap > data->alarm_cap) { 847 sc27xx_fgu_adjust_cap(data, data->alarm_cap); 848 } else { 849 int cur_cap; 850 851 /* 852 * If current capacity is equal with 0 or less than 0 853 * (some error occurs), we should adjust inititial 854 * capacity to the capacity corresponding to current OCV 855 * value. 856 */ 857 cur_cap = power_supply_ocv2cap_simple(data->cap_table, 858 data->table_len, 859 ocv); 860 sc27xx_fgu_adjust_cap(data, cur_cap); 861 } 862 863 if (!int_mode) 864 return; 865 866 /* 867 * After adjusting the battery capacity, we should set the 868 * lowest alarm voltage instead. 869 */ 870 data->min_volt = data->cap_table[data->table_len - 1].ocv; 871 data->alarm_cap = power_supply_ocv2cap_simple(data->cap_table, 872 data->table_len, 873 data->min_volt); 874 875 adc = sc27xx_fgu_voltage_to_adc(data, data->min_volt / 1000); 876 regmap_update_bits(data->regmap, 877 data->base + SC27XX_FGU_LOW_OVERLOAD, 878 SC27XX_FGU_LOW_OVERLOAD_MASK, adc); 879 } 880} 881 882static irqreturn_t sc27xx_fgu_interrupt(int irq, void *dev_id) 883{ 884 struct sc27xx_fgu_data *data = dev_id; 885 int ret, cap; 886 u32 status; 887 888 mutex_lock(&data->lock); 889 890 ret = regmap_read(data->regmap, data->base + SC27XX_FGU_INT_STS, 891 &status); 892 if (ret) 893 goto out; 894 895 ret = regmap_update_bits(data->regmap, data->base + SC27XX_FGU_INT_CLR, 896 status, status); 897 if (ret) 898 goto out; 899 900 /* 901 * When low overload voltage interrupt happens, we should calibrate the 902 * battery capacity in lower voltage stage. 903 */ 904 if (!(status & SC27XX_FGU_LOW_OVERLOAD_INT)) 905 goto out; 906 907 ret = sc27xx_fgu_get_capacity(data, &cap); 908 if (ret) 909 goto out; 910 911 sc27xx_fgu_capacity_calibration(data, cap, true); 912 913out: 914 mutex_unlock(&data->lock); 915 916 power_supply_changed(data->battery); 917 return IRQ_HANDLED; 918} 919 920static irqreturn_t sc27xx_fgu_bat_detection(int irq, void *dev_id) 921{ 922 struct sc27xx_fgu_data *data = dev_id; 923 int state; 924 925 mutex_lock(&data->lock); 926 927 state = gpiod_get_value_cansleep(data->gpiod); 928 if (state < 0) { 929 dev_err(data->dev, "failed to get gpio state\n"); 930 mutex_unlock(&data->lock); 931 return IRQ_RETVAL(state); 932 } 933 934 data->bat_present = !!state; 935 936 mutex_unlock(&data->lock); 937 938 power_supply_changed(data->battery); 939 return IRQ_HANDLED; 940} 941 942static void sc27xx_fgu_disable(void *_data) 943{ 944 struct sc27xx_fgu_data *data = _data; 945 946 regmap_update_bits(data->regmap, SC27XX_CLK_EN0, SC27XX_FGU_RTC_EN, 0); 947 regmap_update_bits(data->regmap, SC27XX_MODULE_EN0, SC27XX_FGU_EN, 0); 948} 949 950static int sc27xx_fgu_cap_to_clbcnt(struct sc27xx_fgu_data *data, int capacity) 951{ 952 /* 953 * Get current capacity (mAh) = battery total capacity (mAh) * 954 * current capacity percent (capacity / 100). 955 */ 956 int cur_cap = DIV_ROUND_CLOSEST(data->total_cap * capacity, 100); 957 958 /* 959 * Convert current capacity (mAh) to coulomb counter according to the 960 * formula: 1 mAh =3.6 coulomb. 961 */ 962 return DIV_ROUND_CLOSEST(cur_cap * 36 * data->cur_1000ma_adc * SC27XX_FGU_SAMPLE_HZ, 10); 963} 964 965static int sc27xx_fgu_calibration(struct sc27xx_fgu_data *data) 966{ 967 struct nvmem_cell *cell; 968 int calib_data, cal_4200mv; 969 void *buf; 970 size_t len; 971 972 cell = nvmem_cell_get(data->dev, "fgu_calib"); 973 if (IS_ERR(cell)) 974 return PTR_ERR(cell); 975 976 buf = nvmem_cell_read(cell, &len); 977 nvmem_cell_put(cell); 978 979 if (IS_ERR(buf)) 980 return PTR_ERR(buf); 981 982 memcpy(&calib_data, buf, min(len, sizeof(u32))); 983 984 /* 985 * Get the ADC value corresponding to 4200 mV from eFuse controller 986 * according to below formula. Then convert to ADC values corresponding 987 * to 1000 mV and 1000 mA. 988 */ 989 cal_4200mv = (calib_data & 0x1ff) + 6963 - 4096 - 256; 990 data->vol_1000mv_adc = DIV_ROUND_CLOSEST(cal_4200mv * 10, 42); 991 data->cur_1000ma_adc = 992 DIV_ROUND_CLOSEST(data->vol_1000mv_adc * 4 * data->calib_resist, 993 SC27XX_FGU_IDEAL_RESISTANCE); 994 995 kfree(buf); 996 return 0; 997} 998 999static int sc27xx_fgu_hw_init(struct sc27xx_fgu_data *data) 1000{ 1001 struct power_supply_battery_info *info; 1002 struct power_supply_battery_ocv_table *table; 1003 int ret, delta_clbcnt, alarm_adc; 1004 1005 ret = power_supply_get_battery_info(data->battery, &info); 1006 if (ret) { 1007 dev_err(data->dev, "failed to get battery information\n"); 1008 return ret; 1009 } 1010 1011 data->total_cap = info->charge_full_design_uah / 1000; 1012 data->max_volt = info->constant_charge_voltage_max_uv / 1000; 1013 data->internal_resist = info->factory_internal_resistance_uohm / 1000; 1014 data->min_volt = info->voltage_min_design_uv; 1015 1016 /* 1017 * For SC27XX fuel gauge device, we only use one ocv-capacity 1018 * table in normal temperature 20 Celsius. 1019 */ 1020 table = power_supply_find_ocv2cap_table(info, 20, &data->table_len); 1021 if (!table) 1022 return -EINVAL; 1023 1024 data->cap_table = devm_kmemdup(data->dev, table, 1025 data->table_len * sizeof(*table), 1026 GFP_KERNEL); 1027 if (!data->cap_table) { 1028 power_supply_put_battery_info(data->battery, info); 1029 return -ENOMEM; 1030 } 1031 1032 data->alarm_cap = power_supply_ocv2cap_simple(data->cap_table, 1033 data->table_len, 1034 data->min_volt); 1035 if (!data->alarm_cap) 1036 data->alarm_cap += 1; 1037 1038 data->resist_table_len = info->resist_table_size; 1039 if (data->resist_table_len > 0) { 1040 data->resist_table = devm_kmemdup(data->dev, info->resist_table, 1041 data->resist_table_len * 1042 sizeof(struct power_supply_resistance_temp_table), 1043 GFP_KERNEL); 1044 if (!data->resist_table) { 1045 power_supply_put_battery_info(data->battery, info); 1046 return -ENOMEM; 1047 } 1048 } 1049 1050 power_supply_put_battery_info(data->battery, info); 1051 1052 ret = sc27xx_fgu_calibration(data); 1053 if (ret) 1054 return ret; 1055 1056 /* Enable the FGU module */ 1057 ret = regmap_update_bits(data->regmap, SC27XX_MODULE_EN0, 1058 SC27XX_FGU_EN, SC27XX_FGU_EN); 1059 if (ret) { 1060 dev_err(data->dev, "failed to enable fgu\n"); 1061 return ret; 1062 } 1063 1064 /* Enable the FGU RTC clock to make it work */ 1065 ret = regmap_update_bits(data->regmap, SC27XX_CLK_EN0, 1066 SC27XX_FGU_RTC_EN, SC27XX_FGU_RTC_EN); 1067 if (ret) { 1068 dev_err(data->dev, "failed to enable fgu RTC clock\n"); 1069 goto disable_fgu; 1070 } 1071 1072 ret = regmap_update_bits(data->regmap, data->base + SC27XX_FGU_INT_CLR, 1073 SC27XX_FGU_INT_MASK, SC27XX_FGU_INT_MASK); 1074 if (ret) { 1075 dev_err(data->dev, "failed to clear interrupt status\n"); 1076 goto disable_clk; 1077 } 1078 1079 /* 1080 * Set the voltage low overload threshold, which means when the battery 1081 * voltage is lower than this threshold, the controller will generate 1082 * one interrupt to notify. 1083 */ 1084 alarm_adc = sc27xx_fgu_voltage_to_adc(data, data->min_volt / 1000); 1085 ret = regmap_update_bits(data->regmap, data->base + SC27XX_FGU_LOW_OVERLOAD, 1086 SC27XX_FGU_LOW_OVERLOAD_MASK, alarm_adc); 1087 if (ret) { 1088 dev_err(data->dev, "failed to set fgu low overload\n"); 1089 goto disable_clk; 1090 } 1091 1092 /* 1093 * Set the coulomb counter delta threshold, that means when the coulomb 1094 * counter change is multiples of the delta threshold, the controller 1095 * will generate one interrupt to notify the users to update the battery 1096 * capacity. Now we set the delta threshold as a counter value of 1% 1097 * capacity. 1098 */ 1099 delta_clbcnt = sc27xx_fgu_cap_to_clbcnt(data, 1); 1100 1101 ret = regmap_update_bits(data->regmap, data->base + SC27XX_FGU_CLBCNT_DELTL, 1102 SC27XX_FGU_CLBCNT_MASK, delta_clbcnt); 1103 if (ret) { 1104 dev_err(data->dev, "failed to set low delta coulomb counter\n"); 1105 goto disable_clk; 1106 } 1107 1108 ret = regmap_update_bits(data->regmap, data->base + SC27XX_FGU_CLBCNT_DELTH, 1109 SC27XX_FGU_CLBCNT_MASK, 1110 delta_clbcnt >> SC27XX_FGU_CLBCNT_SHIFT); 1111 if (ret) { 1112 dev_err(data->dev, "failed to set high delta coulomb counter\n"); 1113 goto disable_clk; 1114 } 1115 1116 /* 1117 * Get the boot battery capacity when system powers on, which is used to 1118 * initialize the coulomb counter. After that, we can read the coulomb 1119 * counter to measure the battery capacity. 1120 */ 1121 ret = sc27xx_fgu_get_boot_capacity(data, &data->init_cap); 1122 if (ret) { 1123 dev_err(data->dev, "failed to get boot capacity\n"); 1124 goto disable_clk; 1125 } 1126 1127 /* 1128 * Convert battery capacity to the corresponding initial coulomb counter 1129 * and set into coulomb counter registers. 1130 */ 1131 data->init_clbcnt = sc27xx_fgu_cap_to_clbcnt(data, data->init_cap); 1132 ret = sc27xx_fgu_set_clbcnt(data, data->init_clbcnt); 1133 if (ret) { 1134 dev_err(data->dev, "failed to initialize coulomb counter\n"); 1135 goto disable_clk; 1136 } 1137 1138 return 0; 1139 1140disable_clk: 1141 regmap_update_bits(data->regmap, SC27XX_CLK_EN0, SC27XX_FGU_RTC_EN, 0); 1142disable_fgu: 1143 regmap_update_bits(data->regmap, SC27XX_MODULE_EN0, SC27XX_FGU_EN, 0); 1144 1145 return ret; 1146} 1147 1148static int sc27xx_fgu_probe(struct platform_device *pdev) 1149{ 1150 struct device *dev = &pdev->dev; 1151 struct device_node *np = dev->of_node; 1152 struct power_supply_config fgu_cfg = { }; 1153 struct sc27xx_fgu_data *data; 1154 int ret, irq; 1155 1156 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 1157 if (!data) 1158 return -ENOMEM; 1159 1160 data->regmap = dev_get_regmap(dev->parent, NULL); 1161 if (!data->regmap) { 1162 dev_err(dev, "failed to get regmap\n"); 1163 return -ENODEV; 1164 } 1165 1166 ret = device_property_read_u32(dev, "reg", &data->base); 1167 if (ret) { 1168 dev_err(dev, "failed to get fgu address\n"); 1169 return ret; 1170 } 1171 1172 ret = device_property_read_u32(&pdev->dev, 1173 "sprd,calib-resistance-micro-ohms", 1174 &data->calib_resist); 1175 if (ret) { 1176 dev_err(&pdev->dev, 1177 "failed to get fgu calibration resistance\n"); 1178 return ret; 1179 } 1180 1181 data->channel = devm_iio_channel_get(dev, "bat-temp"); 1182 if (IS_ERR(data->channel)) { 1183 dev_err(dev, "failed to get IIO channel\n"); 1184 return PTR_ERR(data->channel); 1185 } 1186 1187 data->charge_chan = devm_iio_channel_get(dev, "charge-vol"); 1188 if (IS_ERR(data->charge_chan)) { 1189 dev_err(dev, "failed to get charge IIO channel\n"); 1190 return PTR_ERR(data->charge_chan); 1191 } 1192 1193 data->gpiod = devm_gpiod_get(dev, "bat-detect", GPIOD_IN); 1194 if (IS_ERR(data->gpiod)) { 1195 dev_err(dev, "failed to get battery detection GPIO\n"); 1196 return PTR_ERR(data->gpiod); 1197 } 1198 1199 ret = gpiod_get_value_cansleep(data->gpiod); 1200 if (ret < 0) { 1201 dev_err(dev, "failed to get gpio state\n"); 1202 return ret; 1203 } 1204 1205 data->bat_present = !!ret; 1206 mutex_init(&data->lock); 1207 data->dev = dev; 1208 platform_set_drvdata(pdev, data); 1209 1210 fgu_cfg.drv_data = data; 1211 fgu_cfg.of_node = np; 1212 data->battery = devm_power_supply_register(dev, &sc27xx_fgu_desc, 1213 &fgu_cfg); 1214 if (IS_ERR(data->battery)) { 1215 dev_err(dev, "failed to register power supply\n"); 1216 return PTR_ERR(data->battery); 1217 } 1218 1219 ret = sc27xx_fgu_hw_init(data); 1220 if (ret) { 1221 dev_err(dev, "failed to initialize fgu hardware\n"); 1222 return ret; 1223 } 1224 1225 ret = devm_add_action_or_reset(dev, sc27xx_fgu_disable, data); 1226 if (ret) { 1227 dev_err(dev, "failed to add fgu disable action\n"); 1228 return ret; 1229 } 1230 1231 irq = platform_get_irq(pdev, 0); 1232 if (irq < 0) 1233 return irq; 1234 1235 ret = devm_request_threaded_irq(data->dev, irq, NULL, 1236 sc27xx_fgu_interrupt, 1237 IRQF_NO_SUSPEND | IRQF_ONESHOT, 1238 pdev->name, data); 1239 if (ret) { 1240 dev_err(data->dev, "failed to request fgu IRQ\n"); 1241 return ret; 1242 } 1243 1244 irq = gpiod_to_irq(data->gpiod); 1245 if (irq < 0) { 1246 dev_err(dev, "failed to translate GPIO to IRQ\n"); 1247 return irq; 1248 } 1249 1250 ret = devm_request_threaded_irq(dev, irq, NULL, 1251 sc27xx_fgu_bat_detection, 1252 IRQF_ONESHOT | IRQF_TRIGGER_RISING | 1253 IRQF_TRIGGER_FALLING, 1254 pdev->name, data); 1255 if (ret) { 1256 dev_err(dev, "failed to request IRQ\n"); 1257 return ret; 1258 } 1259 1260 return 0; 1261} 1262 1263#ifdef CONFIG_PM_SLEEP 1264static int sc27xx_fgu_resume(struct device *dev) 1265{ 1266 struct sc27xx_fgu_data *data = dev_get_drvdata(dev); 1267 int ret; 1268 1269 ret = regmap_update_bits(data->regmap, data->base + SC27XX_FGU_INT_EN, 1270 SC27XX_FGU_LOW_OVERLOAD_INT | 1271 SC27XX_FGU_CLBCNT_DELTA_INT, 0); 1272 if (ret) { 1273 dev_err(data->dev, "failed to disable fgu interrupts\n"); 1274 return ret; 1275 } 1276 1277 return 0; 1278} 1279 1280static int sc27xx_fgu_suspend(struct device *dev) 1281{ 1282 struct sc27xx_fgu_data *data = dev_get_drvdata(dev); 1283 int ret, status, ocv; 1284 1285 ret = sc27xx_fgu_get_status(data, &status); 1286 if (ret) 1287 return ret; 1288 1289 /* 1290 * If we are charging, then no need to enable the FGU interrupts to 1291 * adjust the battery capacity. 1292 */ 1293 if (status != POWER_SUPPLY_STATUS_NOT_CHARGING && 1294 status != POWER_SUPPLY_STATUS_DISCHARGING) 1295 return 0; 1296 1297 ret = regmap_update_bits(data->regmap, data->base + SC27XX_FGU_INT_EN, 1298 SC27XX_FGU_LOW_OVERLOAD_INT, 1299 SC27XX_FGU_LOW_OVERLOAD_INT); 1300 if (ret) { 1301 dev_err(data->dev, "failed to enable low voltage interrupt\n"); 1302 return ret; 1303 } 1304 1305 ret = sc27xx_fgu_get_vbat_ocv(data, &ocv); 1306 if (ret) 1307 goto disable_int; 1308 1309 /* 1310 * If current OCV is less than the minimum voltage, we should enable the 1311 * coulomb counter threshold interrupt to notify events to adjust the 1312 * battery capacity. 1313 */ 1314 if (ocv < data->min_volt) { 1315 ret = regmap_update_bits(data->regmap, 1316 data->base + SC27XX_FGU_INT_EN, 1317 SC27XX_FGU_CLBCNT_DELTA_INT, 1318 SC27XX_FGU_CLBCNT_DELTA_INT); 1319 if (ret) { 1320 dev_err(data->dev, 1321 "failed to enable coulomb threshold int\n"); 1322 goto disable_int; 1323 } 1324 } 1325 1326 return 0; 1327 1328disable_int: 1329 regmap_update_bits(data->regmap, data->base + SC27XX_FGU_INT_EN, 1330 SC27XX_FGU_LOW_OVERLOAD_INT, 0); 1331 return ret; 1332} 1333#endif 1334 1335static const struct dev_pm_ops sc27xx_fgu_pm_ops = { 1336 SET_SYSTEM_SLEEP_PM_OPS(sc27xx_fgu_suspend, sc27xx_fgu_resume) 1337}; 1338 1339static const struct of_device_id sc27xx_fgu_of_match[] = { 1340 { .compatible = "sprd,sc2731-fgu", }, 1341 { } 1342}; 1343MODULE_DEVICE_TABLE(of, sc27xx_fgu_of_match); 1344 1345static struct platform_driver sc27xx_fgu_driver = { 1346 .probe = sc27xx_fgu_probe, 1347 .driver = { 1348 .name = "sc27xx-fgu", 1349 .of_match_table = sc27xx_fgu_of_match, 1350 .pm = &sc27xx_fgu_pm_ops, 1351 } 1352}; 1353 1354module_platform_driver(sc27xx_fgu_driver); 1355 1356MODULE_DESCRIPTION("Spreadtrum SC27XX PMICs Fual Gauge Unit Driver"); 1357MODULE_LICENSE("GPL v2");