0001
0002
0003
0004 #include <linux/gpio/consumer.h>
0005 #include <linux/iio/consumer.h>
0006 #include <linux/interrupt.h>
0007 #include <linux/kernel.h>
0008 #include <linux/math64.h>
0009 #include <linux/module.h>
0010 #include <linux/nvmem-consumer.h>
0011 #include <linux/of.h>
0012 #include <linux/platform_device.h>
0013 #include <linux/power_supply.h>
0014 #include <linux/regmap.h>
0015 #include <linux/slab.h>
0016
0017
0018 #define SC27XX_MODULE_EN0 0xc08
0019 #define SC27XX_CLK_EN0 0xc18
0020 #define SC27XX_FGU_EN BIT(7)
0021 #define SC27XX_FGU_RTC_EN BIT(6)
0022
0023
0024 #define SC27XX_FGU_START 0x0
0025 #define SC27XX_FGU_CONFIG 0x4
0026 #define SC27XX_FGU_ADC_CONFIG 0x8
0027 #define SC27XX_FGU_STATUS 0xc
0028 #define SC27XX_FGU_INT_EN 0x10
0029 #define SC27XX_FGU_INT_CLR 0x14
0030 #define SC27XX_FGU_INT_STS 0x1c
0031 #define SC27XX_FGU_VOLTAGE 0x20
0032 #define SC27XX_FGU_OCV 0x24
0033 #define SC27XX_FGU_POCV 0x28
0034 #define SC27XX_FGU_CURRENT 0x2c
0035 #define SC27XX_FGU_LOW_OVERLOAD 0x34
0036 #define SC27XX_FGU_CLBCNT_SETH 0x50
0037 #define SC27XX_FGU_CLBCNT_SETL 0x54
0038 #define SC27XX_FGU_CLBCNT_DELTH 0x58
0039 #define SC27XX_FGU_CLBCNT_DELTL 0x5c
0040 #define SC27XX_FGU_CLBCNT_VALH 0x68
0041 #define SC27XX_FGU_CLBCNT_VALL 0x6c
0042 #define SC27XX_FGU_CLBCNT_QMAXL 0x74
0043 #define SC27XX_FGU_USER_AREA_SET 0xa0
0044 #define SC27XX_FGU_USER_AREA_CLEAR 0xa4
0045 #define SC27XX_FGU_USER_AREA_STATUS 0xa8
0046 #define SC27XX_FGU_VOLTAGE_BUF 0xd0
0047 #define SC27XX_FGU_CURRENT_BUF 0xf0
0048
0049 #define SC27XX_WRITE_SELCLB_EN BIT(0)
0050 #define SC27XX_FGU_CLBCNT_MASK GENMASK(15, 0)
0051 #define SC27XX_FGU_CLBCNT_SHIFT 16
0052 #define SC27XX_FGU_LOW_OVERLOAD_MASK GENMASK(12, 0)
0053
0054 #define SC27XX_FGU_INT_MASK GENMASK(9, 0)
0055 #define SC27XX_FGU_LOW_OVERLOAD_INT BIT(0)
0056 #define SC27XX_FGU_CLBCNT_DELTA_INT BIT(2)
0057
0058 #define SC27XX_FGU_MODE_AREA_MASK GENMASK(15, 12)
0059 #define SC27XX_FGU_CAP_AREA_MASK GENMASK(11, 0)
0060 #define SC27XX_FGU_MODE_AREA_SHIFT 12
0061
0062 #define SC27XX_FGU_FIRST_POWERTON GENMASK(3, 0)
0063 #define SC27XX_FGU_DEFAULT_CAP GENMASK(11, 0)
0064 #define SC27XX_FGU_NORMAIL_POWERTON 0x5
0065
0066 #define SC27XX_FGU_CUR_BASIC_ADC 8192
0067 #define SC27XX_FGU_SAMPLE_HZ 2
0068
0069 #define SC27XX_FGU_IDEAL_RESISTANCE 20000
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097 struct sc27xx_fgu_data {
0098 struct regmap *regmap;
0099 struct device *dev;
0100 struct power_supply *battery;
0101 u32 base;
0102 struct mutex lock;
0103 struct gpio_desc *gpiod;
0104 struct iio_channel *channel;
0105 struct iio_channel *charge_chan;
0106 bool bat_present;
0107 int internal_resist;
0108 int total_cap;
0109 int init_cap;
0110 int alarm_cap;
0111 int init_clbcnt;
0112 int max_volt;
0113 int min_volt;
0114 int boot_volt;
0115 int table_len;
0116 int resist_table_len;
0117 int cur_1000ma_adc;
0118 int vol_1000mv_adc;
0119 int calib_resist;
0120 struct power_supply_battery_ocv_table *cap_table;
0121 struct power_supply_resistance_temp_table *resist_table;
0122 };
0123
0124 static int sc27xx_fgu_cap_to_clbcnt(struct sc27xx_fgu_data *data, int capacity);
0125 static void sc27xx_fgu_capacity_calibration(struct sc27xx_fgu_data *data,
0126 int cap, bool int_mode);
0127 static void sc27xx_fgu_adjust_cap(struct sc27xx_fgu_data *data, int cap);
0128 static int sc27xx_fgu_get_temp(struct sc27xx_fgu_data *data, int *temp);
0129
0130 static const char * const sc27xx_charger_supply_name[] = {
0131 "sc2731_charger",
0132 "sc2720_charger",
0133 "sc2721_charger",
0134 "sc2723_charger",
0135 };
0136
0137 static int sc27xx_fgu_adc_to_current(struct sc27xx_fgu_data *data, s64 adc)
0138 {
0139 return DIV_S64_ROUND_CLOSEST(adc * 1000, data->cur_1000ma_adc);
0140 }
0141
0142 static int sc27xx_fgu_adc_to_voltage(struct sc27xx_fgu_data *data, s64 adc)
0143 {
0144 return DIV_S64_ROUND_CLOSEST(adc * 1000, data->vol_1000mv_adc);
0145 }
0146
0147 static int sc27xx_fgu_voltage_to_adc(struct sc27xx_fgu_data *data, int vol)
0148 {
0149 return DIV_ROUND_CLOSEST(vol * data->vol_1000mv_adc, 1000);
0150 }
0151
0152 static bool sc27xx_fgu_is_first_poweron(struct sc27xx_fgu_data *data)
0153 {
0154 int ret, status, cap, mode;
0155
0156 ret = regmap_read(data->regmap,
0157 data->base + SC27XX_FGU_USER_AREA_STATUS, &status);
0158 if (ret)
0159 return false;
0160
0161
0162
0163
0164
0165 mode = (status & SC27XX_FGU_MODE_AREA_MASK) >> SC27XX_FGU_MODE_AREA_SHIFT;
0166 cap = status & SC27XX_FGU_CAP_AREA_MASK;
0167
0168
0169
0170
0171
0172
0173 if (mode == SC27XX_FGU_FIRST_POWERTON || cap == SC27XX_FGU_DEFAULT_CAP)
0174 return true;
0175
0176 return false;
0177 }
0178
0179 static int sc27xx_fgu_save_boot_mode(struct sc27xx_fgu_data *data,
0180 int boot_mode)
0181 {
0182 int ret;
0183
0184 ret = regmap_update_bits(data->regmap,
0185 data->base + SC27XX_FGU_USER_AREA_CLEAR,
0186 SC27XX_FGU_MODE_AREA_MASK,
0187 SC27XX_FGU_MODE_AREA_MASK);
0188 if (ret)
0189 return ret;
0190
0191
0192
0193
0194
0195
0196
0197 udelay(200);
0198
0199 ret = regmap_update_bits(data->regmap,
0200 data->base + SC27XX_FGU_USER_AREA_SET,
0201 SC27XX_FGU_MODE_AREA_MASK,
0202 boot_mode << SC27XX_FGU_MODE_AREA_SHIFT);
0203 if (ret)
0204 return ret;
0205
0206
0207
0208
0209
0210
0211
0212 udelay(200);
0213
0214
0215
0216
0217
0218
0219 return regmap_update_bits(data->regmap,
0220 data->base + SC27XX_FGU_USER_AREA_CLEAR,
0221 SC27XX_FGU_MODE_AREA_MASK, 0);
0222 }
0223
0224 static int sc27xx_fgu_save_last_cap(struct sc27xx_fgu_data *data, int cap)
0225 {
0226 int ret;
0227
0228 ret = regmap_update_bits(data->regmap,
0229 data->base + SC27XX_FGU_USER_AREA_CLEAR,
0230 SC27XX_FGU_CAP_AREA_MASK,
0231 SC27XX_FGU_CAP_AREA_MASK);
0232 if (ret)
0233 return ret;
0234
0235
0236
0237
0238
0239
0240
0241 udelay(200);
0242
0243 ret = regmap_update_bits(data->regmap,
0244 data->base + SC27XX_FGU_USER_AREA_SET,
0245 SC27XX_FGU_CAP_AREA_MASK, cap);
0246 if (ret)
0247 return ret;
0248
0249
0250
0251
0252
0253
0254
0255 udelay(200);
0256
0257
0258
0259
0260
0261
0262 return regmap_update_bits(data->regmap,
0263 data->base + SC27XX_FGU_USER_AREA_CLEAR,
0264 SC27XX_FGU_CAP_AREA_MASK, 0);
0265 }
0266
0267 static int sc27xx_fgu_read_last_cap(struct sc27xx_fgu_data *data, int *cap)
0268 {
0269 int ret, value;
0270
0271 ret = regmap_read(data->regmap,
0272 data->base + SC27XX_FGU_USER_AREA_STATUS, &value);
0273 if (ret)
0274 return ret;
0275
0276 *cap = value & SC27XX_FGU_CAP_AREA_MASK;
0277 return 0;
0278 }
0279
0280
0281
0282
0283
0284
0285
0286 static int sc27xx_fgu_get_boot_capacity(struct sc27xx_fgu_data *data, int *cap)
0287 {
0288 int volt, cur, oci, ocv, ret;
0289 bool is_first_poweron = sc27xx_fgu_is_first_poweron(data);
0290
0291
0292
0293
0294
0295
0296 if (!is_first_poweron) {
0297 ret = sc27xx_fgu_read_last_cap(data, cap);
0298 if (ret)
0299 return ret;
0300
0301 return sc27xx_fgu_save_boot_mode(data, SC27XX_FGU_NORMAIL_POWERTON);
0302 }
0303
0304
0305
0306
0307
0308 ret = regmap_read(data->regmap, data->base + SC27XX_FGU_CLBCNT_QMAXL,
0309 &cur);
0310 if (ret)
0311 return ret;
0312
0313 cur <<= 1;
0314 oci = sc27xx_fgu_adc_to_current(data, cur - SC27XX_FGU_CUR_BASIC_ADC);
0315
0316
0317
0318
0319
0320
0321 ret = regmap_read(data->regmap, data->base + SC27XX_FGU_POCV, &volt);
0322 if (ret)
0323 return ret;
0324
0325 volt = sc27xx_fgu_adc_to_voltage(data, volt);
0326 ocv = volt * 1000 - oci * data->internal_resist;
0327 data->boot_volt = ocv;
0328
0329
0330
0331
0332
0333 *cap = power_supply_ocv2cap_simple(data->cap_table, data->table_len,
0334 ocv);
0335
0336 ret = sc27xx_fgu_save_last_cap(data, *cap);
0337 if (ret)
0338 return ret;
0339
0340 return sc27xx_fgu_save_boot_mode(data, SC27XX_FGU_NORMAIL_POWERTON);
0341 }
0342
0343 static int sc27xx_fgu_set_clbcnt(struct sc27xx_fgu_data *data, int clbcnt)
0344 {
0345 int ret;
0346
0347 ret = regmap_update_bits(data->regmap,
0348 data->base + SC27XX_FGU_CLBCNT_SETL,
0349 SC27XX_FGU_CLBCNT_MASK, clbcnt);
0350 if (ret)
0351 return ret;
0352
0353 ret = regmap_update_bits(data->regmap,
0354 data->base + SC27XX_FGU_CLBCNT_SETH,
0355 SC27XX_FGU_CLBCNT_MASK,
0356 clbcnt >> SC27XX_FGU_CLBCNT_SHIFT);
0357 if (ret)
0358 return ret;
0359
0360 return regmap_update_bits(data->regmap, data->base + SC27XX_FGU_START,
0361 SC27XX_WRITE_SELCLB_EN,
0362 SC27XX_WRITE_SELCLB_EN);
0363 }
0364
0365 static int sc27xx_fgu_get_clbcnt(struct sc27xx_fgu_data *data, int *clb_cnt)
0366 {
0367 int ccl, cch, ret;
0368
0369 ret = regmap_read(data->regmap, data->base + SC27XX_FGU_CLBCNT_VALL,
0370 &ccl);
0371 if (ret)
0372 return ret;
0373
0374 ret = regmap_read(data->regmap, data->base + SC27XX_FGU_CLBCNT_VALH,
0375 &cch);
0376 if (ret)
0377 return ret;
0378
0379 *clb_cnt = ccl & SC27XX_FGU_CLBCNT_MASK;
0380 *clb_cnt |= (cch & SC27XX_FGU_CLBCNT_MASK) << SC27XX_FGU_CLBCNT_SHIFT;
0381
0382 return 0;
0383 }
0384
0385 static int sc27xx_fgu_get_vol_now(struct sc27xx_fgu_data *data, int *val)
0386 {
0387 int ret;
0388 u32 vol;
0389
0390 ret = regmap_read(data->regmap, data->base + SC27XX_FGU_VOLTAGE_BUF,
0391 &vol);
0392 if (ret)
0393 return ret;
0394
0395
0396
0397
0398
0399 *val = sc27xx_fgu_adc_to_voltage(data, vol);
0400
0401 return 0;
0402 }
0403
0404 static int sc27xx_fgu_get_cur_now(struct sc27xx_fgu_data *data, int *val)
0405 {
0406 int ret;
0407 u32 cur;
0408
0409 ret = regmap_read(data->regmap, data->base + SC27XX_FGU_CURRENT_BUF,
0410 &cur);
0411 if (ret)
0412 return ret;
0413
0414
0415
0416
0417
0418 *val = sc27xx_fgu_adc_to_current(data, cur - SC27XX_FGU_CUR_BASIC_ADC);
0419
0420 return 0;
0421 }
0422
0423 static int sc27xx_fgu_get_capacity(struct sc27xx_fgu_data *data, int *cap)
0424 {
0425 int ret, cur_clbcnt, delta_clbcnt, delta_cap, temp;
0426
0427
0428 ret = sc27xx_fgu_get_clbcnt(data, &cur_clbcnt);
0429 if (ret)
0430 return ret;
0431
0432 delta_clbcnt = cur_clbcnt - data->init_clbcnt;
0433
0434
0435
0436
0437
0438 temp = DIV_ROUND_CLOSEST(delta_clbcnt * 10, 36 * SC27XX_FGU_SAMPLE_HZ);
0439 temp = sc27xx_fgu_adc_to_current(data, temp / 1000);
0440
0441
0442
0443
0444
0445 delta_cap = DIV_ROUND_CLOSEST(temp * 100, data->total_cap);
0446 *cap = delta_cap + data->init_cap;
0447
0448
0449 sc27xx_fgu_capacity_calibration(data, *cap, false);
0450
0451 return 0;
0452 }
0453
0454 static int sc27xx_fgu_get_vbat_vol(struct sc27xx_fgu_data *data, int *val)
0455 {
0456 int ret, vol;
0457
0458 ret = regmap_read(data->regmap, data->base + SC27XX_FGU_VOLTAGE, &vol);
0459 if (ret)
0460 return ret;
0461
0462
0463
0464
0465
0466 *val = sc27xx_fgu_adc_to_voltage(data, vol);
0467
0468 return 0;
0469 }
0470
0471 static int sc27xx_fgu_get_current(struct sc27xx_fgu_data *data, int *val)
0472 {
0473 int ret, cur;
0474
0475 ret = regmap_read(data->regmap, data->base + SC27XX_FGU_CURRENT, &cur);
0476 if (ret)
0477 return ret;
0478
0479
0480
0481
0482
0483 *val = sc27xx_fgu_adc_to_current(data, cur - SC27XX_FGU_CUR_BASIC_ADC);
0484
0485 return 0;
0486 }
0487
0488 static int sc27xx_fgu_get_vbat_ocv(struct sc27xx_fgu_data *data, int *val)
0489 {
0490 int vol, cur, ret, temp, resistance;
0491
0492 ret = sc27xx_fgu_get_vbat_vol(data, &vol);
0493 if (ret)
0494 return ret;
0495
0496 ret = sc27xx_fgu_get_current(data, &cur);
0497 if (ret)
0498 return ret;
0499
0500 resistance = data->internal_resist;
0501 if (data->resist_table_len > 0) {
0502 ret = sc27xx_fgu_get_temp(data, &temp);
0503 if (ret)
0504 return ret;
0505
0506 resistance = power_supply_temp2resist_simple(data->resist_table,
0507 data->resist_table_len, temp);
0508 resistance = data->internal_resist * resistance / 100;
0509 }
0510
0511
0512 *val = vol * 1000 - cur * resistance;
0513
0514 return 0;
0515 }
0516
0517 static int sc27xx_fgu_get_charge_vol(struct sc27xx_fgu_data *data, int *val)
0518 {
0519 int ret, vol;
0520
0521 ret = iio_read_channel_processed(data->charge_chan, &vol);
0522 if (ret < 0)
0523 return ret;
0524
0525 *val = vol * 1000;
0526 return 0;
0527 }
0528
0529 static int sc27xx_fgu_get_temp(struct sc27xx_fgu_data *data, int *temp)
0530 {
0531 return iio_read_channel_processed(data->channel, temp);
0532 }
0533
0534 static int sc27xx_fgu_get_health(struct sc27xx_fgu_data *data, int *health)
0535 {
0536 int ret, vol;
0537
0538 ret = sc27xx_fgu_get_vbat_vol(data, &vol);
0539 if (ret)
0540 return ret;
0541
0542 if (vol > data->max_volt)
0543 *health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
0544 else
0545 *health = POWER_SUPPLY_HEALTH_GOOD;
0546
0547 return 0;
0548 }
0549
0550 static int sc27xx_fgu_get_status(struct sc27xx_fgu_data *data, int *status)
0551 {
0552 union power_supply_propval val;
0553 struct power_supply *psy;
0554 int i, ret = -EINVAL;
0555
0556 for (i = 0; i < ARRAY_SIZE(sc27xx_charger_supply_name); i++) {
0557 psy = power_supply_get_by_name(sc27xx_charger_supply_name[i]);
0558 if (!psy)
0559 continue;
0560
0561 ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_STATUS,
0562 &val);
0563 power_supply_put(psy);
0564 if (ret)
0565 return ret;
0566
0567 *status = val.intval;
0568 }
0569
0570 return ret;
0571 }
0572
0573 static int sc27xx_fgu_get_property(struct power_supply *psy,
0574 enum power_supply_property psp,
0575 union power_supply_propval *val)
0576 {
0577 struct sc27xx_fgu_data *data = power_supply_get_drvdata(psy);
0578 int ret = 0;
0579 int value;
0580
0581 mutex_lock(&data->lock);
0582
0583 switch (psp) {
0584 case POWER_SUPPLY_PROP_STATUS:
0585 ret = sc27xx_fgu_get_status(data, &value);
0586 if (ret)
0587 goto error;
0588
0589 val->intval = value;
0590 break;
0591
0592 case POWER_SUPPLY_PROP_HEALTH:
0593 ret = sc27xx_fgu_get_health(data, &value);
0594 if (ret)
0595 goto error;
0596
0597 val->intval = value;
0598 break;
0599
0600 case POWER_SUPPLY_PROP_PRESENT:
0601 val->intval = data->bat_present;
0602 break;
0603
0604 case POWER_SUPPLY_PROP_TEMP:
0605 ret = sc27xx_fgu_get_temp(data, &value);
0606 if (ret)
0607 goto error;
0608
0609 val->intval = value;
0610 break;
0611
0612 case POWER_SUPPLY_PROP_TECHNOLOGY:
0613 val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
0614 break;
0615
0616 case POWER_SUPPLY_PROP_CAPACITY:
0617 ret = sc27xx_fgu_get_capacity(data, &value);
0618 if (ret)
0619 goto error;
0620
0621 val->intval = value;
0622 break;
0623
0624 case POWER_SUPPLY_PROP_VOLTAGE_AVG:
0625 ret = sc27xx_fgu_get_vbat_vol(data, &value);
0626 if (ret)
0627 goto error;
0628
0629 val->intval = value * 1000;
0630 break;
0631
0632 case POWER_SUPPLY_PROP_VOLTAGE_OCV:
0633 ret = sc27xx_fgu_get_vbat_ocv(data, &value);
0634 if (ret)
0635 goto error;
0636
0637 val->intval = value;
0638 break;
0639
0640 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
0641 ret = sc27xx_fgu_get_charge_vol(data, &value);
0642 if (ret)
0643 goto error;
0644
0645 val->intval = value;
0646 break;
0647
0648 case POWER_SUPPLY_PROP_CURRENT_AVG:
0649 ret = sc27xx_fgu_get_current(data, &value);
0650 if (ret)
0651 goto error;
0652
0653 val->intval = value * 1000;
0654 break;
0655
0656 case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
0657 val->intval = data->total_cap * 1000;
0658 break;
0659
0660 case POWER_SUPPLY_PROP_CHARGE_NOW:
0661 ret = sc27xx_fgu_get_clbcnt(data, &value);
0662 if (ret)
0663 goto error;
0664
0665 value = DIV_ROUND_CLOSEST(value * 10,
0666 36 * SC27XX_FGU_SAMPLE_HZ);
0667 val->intval = sc27xx_fgu_adc_to_current(data, value);
0668
0669 break;
0670
0671 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
0672 ret = sc27xx_fgu_get_vol_now(data, &value);
0673 if (ret)
0674 goto error;
0675
0676 val->intval = value * 1000;
0677 break;
0678
0679 case POWER_SUPPLY_PROP_CURRENT_NOW:
0680 ret = sc27xx_fgu_get_cur_now(data, &value);
0681 if (ret)
0682 goto error;
0683
0684 val->intval = value * 1000;
0685 break;
0686
0687 case POWER_SUPPLY_PROP_VOLTAGE_BOOT:
0688 val->intval = data->boot_volt;
0689 break;
0690
0691 default:
0692 ret = -EINVAL;
0693 break;
0694 }
0695
0696 error:
0697 mutex_unlock(&data->lock);
0698 return ret;
0699 }
0700
0701 static int sc27xx_fgu_set_property(struct power_supply *psy,
0702 enum power_supply_property psp,
0703 const union power_supply_propval *val)
0704 {
0705 struct sc27xx_fgu_data *data = power_supply_get_drvdata(psy);
0706 int ret;
0707
0708 mutex_lock(&data->lock);
0709
0710 switch (psp) {
0711 case POWER_SUPPLY_PROP_CAPACITY:
0712 ret = sc27xx_fgu_save_last_cap(data, val->intval);
0713 if (ret < 0)
0714 dev_err(data->dev, "failed to save battery capacity\n");
0715 break;
0716
0717 case POWER_SUPPLY_PROP_CALIBRATE:
0718 sc27xx_fgu_adjust_cap(data, val->intval);
0719 ret = 0;
0720 break;
0721
0722 case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
0723 data->total_cap = val->intval / 1000;
0724 ret = 0;
0725 break;
0726
0727 default:
0728 ret = -EINVAL;
0729 }
0730
0731 mutex_unlock(&data->lock);
0732
0733 return ret;
0734 }
0735
0736 static void sc27xx_fgu_external_power_changed(struct power_supply *psy)
0737 {
0738 struct sc27xx_fgu_data *data = power_supply_get_drvdata(psy);
0739
0740 power_supply_changed(data->battery);
0741 }
0742
0743 static int sc27xx_fgu_property_is_writeable(struct power_supply *psy,
0744 enum power_supply_property psp)
0745 {
0746 return psp == POWER_SUPPLY_PROP_CAPACITY ||
0747 psp == POWER_SUPPLY_PROP_CALIBRATE ||
0748 psp == POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN;
0749 }
0750
0751 static enum power_supply_property sc27xx_fgu_props[] = {
0752 POWER_SUPPLY_PROP_STATUS,
0753 POWER_SUPPLY_PROP_HEALTH,
0754 POWER_SUPPLY_PROP_PRESENT,
0755 POWER_SUPPLY_PROP_TEMP,
0756 POWER_SUPPLY_PROP_TECHNOLOGY,
0757 POWER_SUPPLY_PROP_CAPACITY,
0758 POWER_SUPPLY_PROP_VOLTAGE_NOW,
0759 POWER_SUPPLY_PROP_VOLTAGE_OCV,
0760 POWER_SUPPLY_PROP_VOLTAGE_AVG,
0761 POWER_SUPPLY_PROP_VOLTAGE_BOOT,
0762 POWER_SUPPLY_PROP_CURRENT_NOW,
0763 POWER_SUPPLY_PROP_CURRENT_AVG,
0764 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
0765 POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
0766 POWER_SUPPLY_PROP_CALIBRATE,
0767 POWER_SUPPLY_PROP_CHARGE_NOW
0768 };
0769
0770 static const struct power_supply_desc sc27xx_fgu_desc = {
0771 .name = "sc27xx-fgu",
0772 .type = POWER_SUPPLY_TYPE_BATTERY,
0773 .properties = sc27xx_fgu_props,
0774 .num_properties = ARRAY_SIZE(sc27xx_fgu_props),
0775 .get_property = sc27xx_fgu_get_property,
0776 .set_property = sc27xx_fgu_set_property,
0777 .external_power_changed = sc27xx_fgu_external_power_changed,
0778 .property_is_writeable = sc27xx_fgu_property_is_writeable,
0779 .no_thermal = true,
0780 };
0781
0782 static void sc27xx_fgu_adjust_cap(struct sc27xx_fgu_data *data, int cap)
0783 {
0784 int ret;
0785
0786 data->init_cap = cap;
0787 ret = sc27xx_fgu_get_clbcnt(data, &data->init_clbcnt);
0788 if (ret)
0789 dev_err(data->dev, "failed to get init coulomb counter\n");
0790 }
0791
0792 static void sc27xx_fgu_capacity_calibration(struct sc27xx_fgu_data *data,
0793 int cap, bool int_mode)
0794 {
0795 int ret, ocv, chg_sts, adc;
0796
0797 ret = sc27xx_fgu_get_vbat_ocv(data, &ocv);
0798 if (ret) {
0799 dev_err(data->dev, "get battery ocv error.\n");
0800 return;
0801 }
0802
0803 ret = sc27xx_fgu_get_status(data, &chg_sts);
0804 if (ret) {
0805 dev_err(data->dev, "get charger status error.\n");
0806 return;
0807 }
0808
0809
0810
0811
0812
0813 if (chg_sts == POWER_SUPPLY_STATUS_CHARGING)
0814 return;
0815
0816 if ((ocv > data->cap_table[0].ocv && cap < 100) || cap > 100) {
0817
0818
0819
0820
0821
0822 sc27xx_fgu_adjust_cap(data, 100);
0823 } else if (ocv <= data->cap_table[data->table_len - 1].ocv) {
0824
0825
0826
0827
0828 sc27xx_fgu_adjust_cap(data, 0);
0829 } else if ((ocv > data->cap_table[data->table_len - 1].ocv && cap <= 0) ||
0830 (ocv > data->min_volt && cap <= data->alarm_cap)) {
0831
0832
0833
0834
0835
0836 int cur_cap = power_supply_ocv2cap_simple(data->cap_table,
0837 data->table_len, ocv);
0838
0839 sc27xx_fgu_adjust_cap(data, cur_cap);
0840 } else if (ocv <= data->min_volt) {
0841
0842
0843
0844
0845
0846 if (cap > data->alarm_cap) {
0847 sc27xx_fgu_adjust_cap(data, data->alarm_cap);
0848 } else {
0849 int cur_cap;
0850
0851
0852
0853
0854
0855
0856
0857 cur_cap = power_supply_ocv2cap_simple(data->cap_table,
0858 data->table_len,
0859 ocv);
0860 sc27xx_fgu_adjust_cap(data, cur_cap);
0861 }
0862
0863 if (!int_mode)
0864 return;
0865
0866
0867
0868
0869
0870 data->min_volt = data->cap_table[data->table_len - 1].ocv;
0871 data->alarm_cap = power_supply_ocv2cap_simple(data->cap_table,
0872 data->table_len,
0873 data->min_volt);
0874
0875 adc = sc27xx_fgu_voltage_to_adc(data, data->min_volt / 1000);
0876 regmap_update_bits(data->regmap,
0877 data->base + SC27XX_FGU_LOW_OVERLOAD,
0878 SC27XX_FGU_LOW_OVERLOAD_MASK, adc);
0879 }
0880 }
0881
0882 static irqreturn_t sc27xx_fgu_interrupt(int irq, void *dev_id)
0883 {
0884 struct sc27xx_fgu_data *data = dev_id;
0885 int ret, cap;
0886 u32 status;
0887
0888 mutex_lock(&data->lock);
0889
0890 ret = regmap_read(data->regmap, data->base + SC27XX_FGU_INT_STS,
0891 &status);
0892 if (ret)
0893 goto out;
0894
0895 ret = regmap_update_bits(data->regmap, data->base + SC27XX_FGU_INT_CLR,
0896 status, status);
0897 if (ret)
0898 goto out;
0899
0900
0901
0902
0903
0904 if (!(status & SC27XX_FGU_LOW_OVERLOAD_INT))
0905 goto out;
0906
0907 ret = sc27xx_fgu_get_capacity(data, &cap);
0908 if (ret)
0909 goto out;
0910
0911 sc27xx_fgu_capacity_calibration(data, cap, true);
0912
0913 out:
0914 mutex_unlock(&data->lock);
0915
0916 power_supply_changed(data->battery);
0917 return IRQ_HANDLED;
0918 }
0919
0920 static irqreturn_t sc27xx_fgu_bat_detection(int irq, void *dev_id)
0921 {
0922 struct sc27xx_fgu_data *data = dev_id;
0923 int state;
0924
0925 mutex_lock(&data->lock);
0926
0927 state = gpiod_get_value_cansleep(data->gpiod);
0928 if (state < 0) {
0929 dev_err(data->dev, "failed to get gpio state\n");
0930 mutex_unlock(&data->lock);
0931 return IRQ_RETVAL(state);
0932 }
0933
0934 data->bat_present = !!state;
0935
0936 mutex_unlock(&data->lock);
0937
0938 power_supply_changed(data->battery);
0939 return IRQ_HANDLED;
0940 }
0941
0942 static void sc27xx_fgu_disable(void *_data)
0943 {
0944 struct sc27xx_fgu_data *data = _data;
0945
0946 regmap_update_bits(data->regmap, SC27XX_CLK_EN0, SC27XX_FGU_RTC_EN, 0);
0947 regmap_update_bits(data->regmap, SC27XX_MODULE_EN0, SC27XX_FGU_EN, 0);
0948 }
0949
0950 static int sc27xx_fgu_cap_to_clbcnt(struct sc27xx_fgu_data *data, int capacity)
0951 {
0952
0953
0954
0955
0956 int cur_cap = DIV_ROUND_CLOSEST(data->total_cap * capacity, 100);
0957
0958
0959
0960
0961
0962 return DIV_ROUND_CLOSEST(cur_cap * 36 * data->cur_1000ma_adc * SC27XX_FGU_SAMPLE_HZ, 10);
0963 }
0964
0965 static int sc27xx_fgu_calibration(struct sc27xx_fgu_data *data)
0966 {
0967 struct nvmem_cell *cell;
0968 int calib_data, cal_4200mv;
0969 void *buf;
0970 size_t len;
0971
0972 cell = nvmem_cell_get(data->dev, "fgu_calib");
0973 if (IS_ERR(cell))
0974 return PTR_ERR(cell);
0975
0976 buf = nvmem_cell_read(cell, &len);
0977 nvmem_cell_put(cell);
0978
0979 if (IS_ERR(buf))
0980 return PTR_ERR(buf);
0981
0982 memcpy(&calib_data, buf, min(len, sizeof(u32)));
0983
0984
0985
0986
0987
0988
0989 cal_4200mv = (calib_data & 0x1ff) + 6963 - 4096 - 256;
0990 data->vol_1000mv_adc = DIV_ROUND_CLOSEST(cal_4200mv * 10, 42);
0991 data->cur_1000ma_adc =
0992 DIV_ROUND_CLOSEST(data->vol_1000mv_adc * 4 * data->calib_resist,
0993 SC27XX_FGU_IDEAL_RESISTANCE);
0994
0995 kfree(buf);
0996 return 0;
0997 }
0998
0999 static 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
1018
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
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
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
1081
1082
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
1094
1095
1096
1097
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
1118
1119
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
1129
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
1140 disable_clk:
1141 regmap_update_bits(data->regmap, SC27XX_CLK_EN0, SC27XX_FGU_RTC_EN, 0);
1142 disable_fgu:
1143 regmap_update_bits(data->regmap, SC27XX_MODULE_EN0, SC27XX_FGU_EN, 0);
1144
1145 return ret;
1146 }
1147
1148 static 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
1264 static 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
1280 static 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
1291
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
1311
1312
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
1328 disable_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
1335 static const struct dev_pm_ops sc27xx_fgu_pm_ops = {
1336 SET_SYSTEM_SLEEP_PM_OPS(sc27xx_fgu_suspend, sc27xx_fgu_resume)
1337 };
1338
1339 static const struct of_device_id sc27xx_fgu_of_match[] = {
1340 { .compatible = "sprd,sc2731-fgu", },
1341 { }
1342 };
1343 MODULE_DEVICE_TABLE(of, sc27xx_fgu_of_match);
1344
1345 static 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
1354 module_platform_driver(sc27xx_fgu_driver);
1355
1356 MODULE_DESCRIPTION("Spreadtrum SC27XX PMICs Fual Gauge Unit Driver");
1357 MODULE_LICENSE("GPL v2");