0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/delay.h>
0014 #include <linux/err.h>
0015 #include <linux/interrupt.h>
0016 #include <linux/kernel.h>
0017 #include <linux/module.h>
0018 #include <linux/of_device.h>
0019 #include <linux/platform_device.h>
0020 #include <linux/power_supply.h>
0021 #include <linux/reboot.h>
0022 #include <linux/regmap.h>
0023 #include <linux/nvmem-consumer.h>
0024 #include <linux/moduleparam.h>
0025
0026 #include <linux/iio/consumer.h>
0027 #include <linux/iio/types.h>
0028 #include <linux/mfd/motorola-cpcap.h>
0029
0030
0031
0032
0033
0034
0035
0036 #define CPCAP_REG_BPEOL_BIT_EOL9 BIT(9)
0037 #define CPCAP_REG_BPEOL_BIT_EOL8 BIT(8)
0038 #define CPCAP_REG_BPEOL_BIT_UNKNOWN7 BIT(7)
0039 #define CPCAP_REG_BPEOL_BIT_UNKNOWN6 BIT(6)
0040 #define CPCAP_REG_BPEOL_BIT_UNKNOWN5 BIT(5)
0041 #define CPCAP_REG_BPEOL_BIT_EOL_MULTI BIT(4)
0042 #define CPCAP_REG_BPEOL_BIT_UNKNOWN3 BIT(3)
0043 #define CPCAP_REG_BPEOL_BIT_UNKNOWN2 BIT(2)
0044 #define CPCAP_REG_BPEOL_BIT_BATTDETEN BIT(1)
0045 #define CPCAP_REG_BPEOL_BIT_EOLSEL BIT(0)
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055 #define CPCAP_REG_CCC1_ACTIVE_MODE1 BIT(4)
0056 #define CPCAP_REG_CCC1_ACTIVE_MODE0 BIT(3)
0057 #define CPCAP_REG_CCC1_AUTOCLEAR BIT(2)
0058 #define CPCAP_REG_CCC1_CAL_EN BIT(1)
0059 #define CPCAP_REG_CCC1_PAUSE BIT(0)
0060 #define CPCAP_REG_CCC1_RESET_MASK (CPCAP_REG_CCC1_AUTOCLEAR | \
0061 CPCAP_REG_CCC1_CAL_EN)
0062
0063 #define CPCAP_REG_CCCC2_RATE1 BIT(5)
0064 #define CPCAP_REG_CCCC2_RATE0 BIT(4)
0065 #define CPCAP_REG_CCCC2_ENABLE BIT(3)
0066
0067 #define CPCAP_BATTERY_CC_SAMPLE_PERIOD_MS 250
0068
0069 #define CPCAP_BATTERY_EB41_HW4X_ID 0x9E
0070 #define CPCAP_BATTERY_BW8X_ID 0x98
0071
0072 enum {
0073 CPCAP_BATTERY_IIO_BATTDET,
0074 CPCAP_BATTERY_IIO_VOLTAGE,
0075 CPCAP_BATTERY_IIO_CHRG_CURRENT,
0076 CPCAP_BATTERY_IIO_BATT_CURRENT,
0077 CPCAP_BATTERY_IIO_NR,
0078 };
0079
0080 enum cpcap_battery_irq_action {
0081 CPCAP_BATTERY_IRQ_ACTION_NONE,
0082 CPCAP_BATTERY_IRQ_ACTION_CC_CAL_DONE,
0083 CPCAP_BATTERY_IRQ_ACTION_BATTERY_LOW,
0084 CPCAP_BATTERY_IRQ_ACTION_POWEROFF,
0085 };
0086
0087 struct cpcap_interrupt_desc {
0088 const char *name;
0089 struct list_head node;
0090 int irq;
0091 enum cpcap_battery_irq_action action;
0092 };
0093
0094 struct cpcap_battery_config {
0095 int cd_factor;
0096 struct power_supply_info info;
0097 struct power_supply_battery_info bat;
0098 };
0099
0100 struct cpcap_coulomb_counter_data {
0101 s32 sample;
0102 s32 accumulator;
0103 s16 offset;
0104 s16 integrator;
0105 };
0106
0107 enum cpcap_battery_state {
0108 CPCAP_BATTERY_STATE_PREVIOUS,
0109 CPCAP_BATTERY_STATE_LATEST,
0110 CPCAP_BATTERY_STATE_EMPTY,
0111 CPCAP_BATTERY_STATE_FULL,
0112 CPCAP_BATTERY_STATE_NR,
0113 };
0114
0115 struct cpcap_battery_state_data {
0116 int voltage;
0117 int current_ua;
0118 int counter_uah;
0119 int temperature;
0120 ktime_t time;
0121 struct cpcap_coulomb_counter_data cc;
0122 };
0123
0124 struct cpcap_battery_ddata {
0125 struct device *dev;
0126 struct regmap *reg;
0127 struct list_head irq_list;
0128 struct iio_channel *channels[CPCAP_BATTERY_IIO_NR];
0129 struct power_supply *psy;
0130 struct cpcap_battery_config config;
0131 struct cpcap_battery_state_data state[CPCAP_BATTERY_STATE_NR];
0132 u32 cc_lsb;
0133 atomic_t active;
0134 int charge_full;
0135 int status;
0136 u16 vendor;
0137 bool check_nvmem;
0138 unsigned int is_full:1;
0139 };
0140
0141 #define CPCAP_NO_BATTERY -400
0142
0143 static bool ignore_temperature_probe;
0144 module_param(ignore_temperature_probe, bool, 0660);
0145
0146 static struct cpcap_battery_state_data *
0147 cpcap_battery_get_state(struct cpcap_battery_ddata *ddata,
0148 enum cpcap_battery_state state)
0149 {
0150 if (state >= CPCAP_BATTERY_STATE_NR)
0151 return NULL;
0152
0153 return &ddata->state[state];
0154 }
0155
0156 static struct cpcap_battery_state_data *
0157 cpcap_battery_latest(struct cpcap_battery_ddata *ddata)
0158 {
0159 return cpcap_battery_get_state(ddata, CPCAP_BATTERY_STATE_LATEST);
0160 }
0161
0162 static struct cpcap_battery_state_data *
0163 cpcap_battery_previous(struct cpcap_battery_ddata *ddata)
0164 {
0165 return cpcap_battery_get_state(ddata, CPCAP_BATTERY_STATE_PREVIOUS);
0166 }
0167
0168 static struct cpcap_battery_state_data *
0169 cpcap_battery_get_empty(struct cpcap_battery_ddata *ddata)
0170 {
0171 return cpcap_battery_get_state(ddata, CPCAP_BATTERY_STATE_EMPTY);
0172 }
0173
0174 static struct cpcap_battery_state_data *
0175 cpcap_battery_get_full(struct cpcap_battery_ddata *ddata)
0176 {
0177 return cpcap_battery_get_state(ddata, CPCAP_BATTERY_STATE_FULL);
0178 }
0179
0180 static int cpcap_charger_battery_temperature(struct cpcap_battery_ddata *ddata,
0181 int *value)
0182 {
0183 struct iio_channel *channel;
0184 int error;
0185
0186 channel = ddata->channels[CPCAP_BATTERY_IIO_BATTDET];
0187 error = iio_read_channel_processed(channel, value);
0188 if (error < 0) {
0189 if (!ignore_temperature_probe)
0190 dev_warn(ddata->dev, "%s failed: %i\n", __func__, error);
0191 *value = CPCAP_NO_BATTERY;
0192
0193 return error;
0194 }
0195
0196 *value /= 100;
0197
0198 return 0;
0199 }
0200
0201 static int cpcap_battery_get_voltage(struct cpcap_battery_ddata *ddata)
0202 {
0203 struct iio_channel *channel;
0204 int error, value = 0;
0205
0206 channel = ddata->channels[CPCAP_BATTERY_IIO_VOLTAGE];
0207 error = iio_read_channel_processed(channel, &value);
0208 if (error < 0) {
0209 dev_warn(ddata->dev, "%s failed: %i\n", __func__, error);
0210
0211 return 0;
0212 }
0213
0214 return value * 1000;
0215 }
0216
0217 static int cpcap_battery_get_current(struct cpcap_battery_ddata *ddata)
0218 {
0219 struct iio_channel *channel;
0220 int error, value = 0;
0221
0222 channel = ddata->channels[CPCAP_BATTERY_IIO_BATT_CURRENT];
0223 error = iio_read_channel_processed(channel, &value);
0224 if (error < 0) {
0225 dev_warn(ddata->dev, "%s failed: %i\n", __func__, error);
0226
0227 return 0;
0228 }
0229
0230 return value * 1000;
0231 }
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254 static int cpcap_battery_cc_raw_div(struct cpcap_battery_ddata *ddata,
0255 s32 sample, s32 accumulator,
0256 s16 offset, u32 divider)
0257 {
0258 s64 acc;
0259
0260 if (!divider)
0261 return 0;
0262
0263 acc = accumulator;
0264 acc -= (s64)sample * offset;
0265 acc *= ddata->cc_lsb;
0266 acc *= -1;
0267 acc = div_s64(acc, divider);
0268
0269 return acc;
0270 }
0271
0272
0273 static int cpcap_battery_cc_to_uah(struct cpcap_battery_ddata *ddata,
0274 s32 sample, s32 accumulator,
0275 s16 offset)
0276 {
0277 return cpcap_battery_cc_raw_div(ddata, sample,
0278 accumulator, offset,
0279 3600000);
0280 }
0281
0282 static int cpcap_battery_cc_to_ua(struct cpcap_battery_ddata *ddata,
0283 s32 sample, s32 accumulator,
0284 s16 offset)
0285 {
0286 return cpcap_battery_cc_raw_div(ddata, sample,
0287 accumulator, offset,
0288 sample *
0289 CPCAP_BATTERY_CC_SAMPLE_PERIOD_MS);
0290 }
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307 static int
0308 cpcap_battery_read_accumulated(struct cpcap_battery_ddata *ddata,
0309 struct cpcap_coulomb_counter_data *ccd)
0310 {
0311 u16 buf[7];
0312 int error;
0313
0314 ccd->sample = 0;
0315 ccd->accumulator = 0;
0316 ccd->offset = 0;
0317 ccd->integrator = 0;
0318
0319
0320 error = regmap_bulk_read(ddata->reg, CPCAP_REG_CCS1,
0321 buf, ARRAY_SIZE(buf));
0322 if (error)
0323 return 0;
0324
0325
0326 ccd->sample = (buf[1] & 0x0fff) << 16;
0327 ccd->sample |= buf[0];
0328 if (ddata->vendor == CPCAP_VENDOR_TI)
0329 ccd->sample = sign_extend32(24, ccd->sample);
0330
0331
0332 ccd->accumulator = ((s16)buf[3]) << 16;
0333 ccd->accumulator |= buf[2];
0334
0335
0336
0337
0338
0339 ccd->offset = buf[4];
0340 ccd->offset = sign_extend32(ccd->offset, 9);
0341
0342
0343 if (ddata->vendor == CPCAP_VENDOR_TI)
0344 ccd->integrator = sign_extend32(buf[6], 13);
0345 else
0346 ccd->integrator = (s16)buf[6];
0347
0348 return cpcap_battery_cc_to_uah(ddata,
0349 ccd->sample,
0350 ccd->accumulator,
0351 ccd->offset);
0352 }
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367 static const struct cpcap_battery_config cpcap_battery_eb41_data = {
0368 .cd_factor = 0x3cc,
0369 .info.technology = POWER_SUPPLY_TECHNOLOGY_LION,
0370 .info.voltage_max_design = 4351000,
0371 .info.voltage_min_design = 3100000,
0372 .info.charge_full_design = 1740000,
0373 .bat.constant_charge_voltage_max_uv = 4200000,
0374 };
0375
0376
0377 static const struct cpcap_battery_config cpcap_battery_bw8x_data = {
0378 .cd_factor = 0x3cc,
0379 .info.technology = POWER_SUPPLY_TECHNOLOGY_LION,
0380 .info.voltage_max_design = 4200000,
0381 .info.voltage_min_design = 3200000,
0382 .info.charge_full_design = 2760000,
0383 .bat.constant_charge_voltage_max_uv = 4200000,
0384 };
0385
0386
0387
0388
0389
0390 static const struct cpcap_battery_config cpcap_battery_unkown_data = {
0391 .cd_factor = 0x3cc,
0392 .info.technology = POWER_SUPPLY_TECHNOLOGY_LION,
0393 .info.voltage_max_design = 4200000,
0394 .info.voltage_min_design = 3200000,
0395 .info.charge_full_design = 3000000,
0396 .bat.constant_charge_voltage_max_uv = 4200000,
0397 };
0398
0399 static int cpcap_battery_match_nvmem(struct device *dev, const void *data)
0400 {
0401 if (strcmp(dev_name(dev), "89-500029ba0f73") == 0)
0402 return 1;
0403 else
0404 return 0;
0405 }
0406
0407 static void cpcap_battery_detect_battery_type(struct cpcap_battery_ddata *ddata)
0408 {
0409 struct nvmem_device *nvmem;
0410 u8 battery_id = 0;
0411
0412 ddata->check_nvmem = false;
0413
0414 nvmem = nvmem_device_find(NULL, &cpcap_battery_match_nvmem);
0415 if (IS_ERR_OR_NULL(nvmem)) {
0416 ddata->check_nvmem = true;
0417 dev_info_once(ddata->dev, "Can not find battery nvmem device. Assuming generic lipo battery\n");
0418 } else if (nvmem_device_read(nvmem, 2, 1, &battery_id) < 0) {
0419 battery_id = 0;
0420 ddata->check_nvmem = true;
0421 dev_warn(ddata->dev, "Can not read battery nvmem device. Assuming generic lipo battery\n");
0422 }
0423
0424 switch (battery_id) {
0425 case CPCAP_BATTERY_EB41_HW4X_ID:
0426 ddata->config = cpcap_battery_eb41_data;
0427 break;
0428 case CPCAP_BATTERY_BW8X_ID:
0429 ddata->config = cpcap_battery_bw8x_data;
0430 break;
0431 default:
0432 ddata->config = cpcap_battery_unkown_data;
0433 }
0434 }
0435
0436
0437
0438
0439
0440 static int cpcap_battery_cc_get_avg_current(struct cpcap_battery_ddata *ddata)
0441 {
0442 int value, acc, error;
0443 s32 sample;
0444 s16 offset;
0445
0446
0447 error = regmap_read(ddata->reg, CPCAP_REG_CCI, &value);
0448 if (error)
0449 return error;
0450
0451 if (ddata->vendor == CPCAP_VENDOR_TI) {
0452 acc = sign_extend32(value, 13);
0453 sample = 1;
0454 } else {
0455 acc = (s16)value;
0456 sample = 4;
0457 }
0458
0459
0460 error = regmap_read(ddata->reg, CPCAP_REG_CCM, &value);
0461 if (error)
0462 return error;
0463
0464 offset = sign_extend32(value, 9);
0465
0466 return cpcap_battery_cc_to_ua(ddata, sample, acc, offset);
0467 }
0468
0469 static int cpcap_battery_get_charger_status(struct cpcap_battery_ddata *ddata,
0470 int *val)
0471 {
0472 union power_supply_propval prop;
0473 struct power_supply *charger;
0474 int error;
0475
0476 charger = power_supply_get_by_name("usb");
0477 if (!charger)
0478 return -ENODEV;
0479
0480 error = power_supply_get_property(charger, POWER_SUPPLY_PROP_STATUS,
0481 &prop);
0482 if (error)
0483 *val = POWER_SUPPLY_STATUS_UNKNOWN;
0484 else
0485 *val = prop.intval;
0486
0487 power_supply_put(charger);
0488
0489 return error;
0490 }
0491
0492 static bool cpcap_battery_full(struct cpcap_battery_ddata *ddata)
0493 {
0494 struct cpcap_battery_state_data *state = cpcap_battery_latest(ddata);
0495 unsigned int vfull;
0496 int error, val;
0497
0498 error = cpcap_battery_get_charger_status(ddata, &val);
0499 if (!error) {
0500 switch (val) {
0501 case POWER_SUPPLY_STATUS_DISCHARGING:
0502 dev_dbg(ddata->dev, "charger disconnected\n");
0503 ddata->is_full = 0;
0504 break;
0505 case POWER_SUPPLY_STATUS_FULL:
0506 dev_dbg(ddata->dev, "charger full status\n");
0507 ddata->is_full = 1;
0508 break;
0509 default:
0510 break;
0511 }
0512 }
0513
0514
0515
0516
0517
0518
0519 vfull = ddata->config.bat.constant_charge_voltage_max_uv - 120000;
0520
0521 if (ddata->is_full && state->voltage < vfull)
0522 ddata->is_full = 0;
0523
0524 return ddata->is_full;
0525 }
0526
0527 static bool cpcap_battery_low(struct cpcap_battery_ddata *ddata)
0528 {
0529 struct cpcap_battery_state_data *state = cpcap_battery_latest(ddata);
0530 static bool is_low;
0531
0532 if (state->current_ua > 0 && (state->voltage <= 3350000 || is_low))
0533 is_low = true;
0534 else
0535 is_low = false;
0536
0537 return is_low;
0538 }
0539
0540 static int cpcap_battery_update_status(struct cpcap_battery_ddata *ddata)
0541 {
0542 struct cpcap_battery_state_data state, *latest, *previous,
0543 *empty, *full;
0544 ktime_t now;
0545 int error;
0546
0547 memset(&state, 0, sizeof(state));
0548 now = ktime_get();
0549
0550 latest = cpcap_battery_latest(ddata);
0551 if (latest) {
0552 s64 delta_ms = ktime_to_ms(ktime_sub(now, latest->time));
0553
0554 if (delta_ms < CPCAP_BATTERY_CC_SAMPLE_PERIOD_MS)
0555 return delta_ms;
0556 }
0557
0558 state.time = now;
0559 state.voltage = cpcap_battery_get_voltage(ddata);
0560 state.current_ua = cpcap_battery_get_current(ddata);
0561 state.counter_uah = cpcap_battery_read_accumulated(ddata, &state.cc);
0562
0563 error = cpcap_charger_battery_temperature(ddata,
0564 &state.temperature);
0565 if (error)
0566 return error;
0567
0568 previous = cpcap_battery_previous(ddata);
0569 memcpy(previous, latest, sizeof(*previous));
0570 memcpy(latest, &state, sizeof(*latest));
0571
0572 if (cpcap_battery_full(ddata)) {
0573 full = cpcap_battery_get_full(ddata);
0574 memcpy(full, latest, sizeof(*full));
0575
0576 empty = cpcap_battery_get_empty(ddata);
0577 if (empty->voltage && empty->voltage != -1) {
0578 empty->voltage = -1;
0579 ddata->charge_full =
0580 empty->counter_uah - full->counter_uah;
0581 } else if (ddata->charge_full) {
0582 empty->voltage = -1;
0583 empty->counter_uah =
0584 full->counter_uah + ddata->charge_full;
0585 }
0586 } else if (cpcap_battery_low(ddata)) {
0587 empty = cpcap_battery_get_empty(ddata);
0588 memcpy(empty, latest, sizeof(*empty));
0589
0590 full = cpcap_battery_get_full(ddata);
0591 if (full->voltage) {
0592 full->voltage = 0;
0593 ddata->charge_full =
0594 empty->counter_uah - full->counter_uah;
0595 }
0596 }
0597
0598 return 0;
0599 }
0600
0601
0602
0603
0604
0605
0606 static void cpcap_battery_external_power_changed(struct power_supply *psy)
0607 {
0608 union power_supply_propval prop;
0609
0610 power_supply_get_property(psy, POWER_SUPPLY_PROP_STATUS, &prop);
0611 }
0612
0613 static enum power_supply_property cpcap_battery_props[] = {
0614 POWER_SUPPLY_PROP_STATUS,
0615 POWER_SUPPLY_PROP_PRESENT,
0616 POWER_SUPPLY_PROP_TECHNOLOGY,
0617 POWER_SUPPLY_PROP_VOLTAGE_NOW,
0618 POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
0619 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
0620 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
0621 POWER_SUPPLY_PROP_CURRENT_AVG,
0622 POWER_SUPPLY_PROP_CURRENT_NOW,
0623 POWER_SUPPLY_PROP_CHARGE_FULL,
0624 POWER_SUPPLY_PROP_CHARGE_NOW,
0625 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
0626 POWER_SUPPLY_PROP_CHARGE_COUNTER,
0627 POWER_SUPPLY_PROP_POWER_NOW,
0628 POWER_SUPPLY_PROP_POWER_AVG,
0629 POWER_SUPPLY_PROP_CAPACITY,
0630 POWER_SUPPLY_PROP_CAPACITY_LEVEL,
0631 POWER_SUPPLY_PROP_SCOPE,
0632 POWER_SUPPLY_PROP_TEMP,
0633 };
0634
0635 static int cpcap_battery_get_property(struct power_supply *psy,
0636 enum power_supply_property psp,
0637 union power_supply_propval *val)
0638 {
0639 struct cpcap_battery_ddata *ddata = power_supply_get_drvdata(psy);
0640 struct cpcap_battery_state_data *latest, *previous, *empty;
0641 u32 sample;
0642 s32 accumulator;
0643 int cached;
0644 s64 tmp;
0645
0646 cached = cpcap_battery_update_status(ddata);
0647 if (cached < 0)
0648 return cached;
0649
0650 latest = cpcap_battery_latest(ddata);
0651 previous = cpcap_battery_previous(ddata);
0652
0653 if (ddata->check_nvmem)
0654 cpcap_battery_detect_battery_type(ddata);
0655
0656 switch (psp) {
0657 case POWER_SUPPLY_PROP_PRESENT:
0658 if (latest->temperature > CPCAP_NO_BATTERY || ignore_temperature_probe)
0659 val->intval = 1;
0660 else
0661 val->intval = 0;
0662 break;
0663 case POWER_SUPPLY_PROP_STATUS:
0664 if (cpcap_battery_full(ddata)) {
0665 val->intval = POWER_SUPPLY_STATUS_FULL;
0666 break;
0667 }
0668 if (cpcap_battery_cc_get_avg_current(ddata) < 0)
0669 val->intval = POWER_SUPPLY_STATUS_CHARGING;
0670 else
0671 val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
0672 break;
0673 case POWER_SUPPLY_PROP_TECHNOLOGY:
0674 val->intval = ddata->config.info.technology;
0675 break;
0676 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
0677 val->intval = cpcap_battery_get_voltage(ddata);
0678 break;
0679 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
0680 val->intval = ddata->config.info.voltage_max_design;
0681 break;
0682 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
0683 val->intval = ddata->config.info.voltage_min_design;
0684 break;
0685 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
0686 val->intval = ddata->config.bat.constant_charge_voltage_max_uv;
0687 break;
0688 case POWER_SUPPLY_PROP_CURRENT_AVG:
0689 sample = latest->cc.sample - previous->cc.sample;
0690 if (!sample) {
0691 val->intval = cpcap_battery_cc_get_avg_current(ddata);
0692 break;
0693 }
0694 accumulator = latest->cc.accumulator - previous->cc.accumulator;
0695 val->intval = cpcap_battery_cc_to_ua(ddata, sample,
0696 accumulator,
0697 latest->cc.offset);
0698 break;
0699 case POWER_SUPPLY_PROP_CURRENT_NOW:
0700 val->intval = latest->current_ua;
0701 break;
0702 case POWER_SUPPLY_PROP_CHARGE_COUNTER:
0703 val->intval = latest->counter_uah;
0704 break;
0705 case POWER_SUPPLY_PROP_POWER_NOW:
0706 tmp = (latest->voltage / 10000) * latest->current_ua;
0707 val->intval = div64_s64(tmp, 100);
0708 break;
0709 case POWER_SUPPLY_PROP_POWER_AVG:
0710 sample = latest->cc.sample - previous->cc.sample;
0711 if (!sample) {
0712 tmp = cpcap_battery_cc_get_avg_current(ddata);
0713 tmp *= (latest->voltage / 10000);
0714 val->intval = div64_s64(tmp, 100);
0715 break;
0716 }
0717 accumulator = latest->cc.accumulator - previous->cc.accumulator;
0718 tmp = cpcap_battery_cc_to_ua(ddata, sample, accumulator,
0719 latest->cc.offset);
0720 tmp *= ((latest->voltage + previous->voltage) / 20000);
0721 val->intval = div64_s64(tmp, 100);
0722 break;
0723 case POWER_SUPPLY_PROP_CAPACITY:
0724 empty = cpcap_battery_get_empty(ddata);
0725 if (!empty->voltage || !ddata->charge_full)
0726 return -ENODATA;
0727
0728 val->intval = empty->counter_uah - latest->counter_uah +
0729 ddata->charge_full / 200;
0730 val->intval = clamp(val->intval, 0, ddata->charge_full);
0731 val->intval = val->intval * 100 / ddata->charge_full;
0732 break;
0733 case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
0734 if (cpcap_battery_full(ddata))
0735 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
0736 else if (latest->voltage >= 3750000)
0737 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_HIGH;
0738 else if (latest->voltage >= 3300000)
0739 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
0740 else if (latest->voltage > 3100000)
0741 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
0742 else if (latest->voltage <= 3100000)
0743 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
0744 else
0745 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN;
0746 break;
0747 case POWER_SUPPLY_PROP_CHARGE_NOW:
0748 empty = cpcap_battery_get_empty(ddata);
0749 if (!empty->voltage)
0750 return -ENODATA;
0751 val->intval = empty->counter_uah - latest->counter_uah;
0752 if (val->intval < 0) {
0753
0754 if (ddata->charge_full && abs(val->intval) > ddata->charge_full/5) {
0755 empty->voltage = 0;
0756 ddata->charge_full = 0;
0757 return -ENODATA;
0758 }
0759 val->intval = 0;
0760 } else if (ddata->charge_full && ddata->charge_full < val->intval) {
0761
0762 if (val->intval > (6*ddata->charge_full)/5) {
0763 empty->voltage = 0;
0764 ddata->charge_full = 0;
0765 return -ENODATA;
0766 }
0767 val->intval = ddata->charge_full;
0768 }
0769 break;
0770 case POWER_SUPPLY_PROP_CHARGE_FULL:
0771 if (!ddata->charge_full)
0772 return -ENODATA;
0773 val->intval = ddata->charge_full;
0774 break;
0775 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
0776 val->intval = ddata->config.info.charge_full_design;
0777 break;
0778 case POWER_SUPPLY_PROP_SCOPE:
0779 val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
0780 break;
0781 case POWER_SUPPLY_PROP_TEMP:
0782 if (ignore_temperature_probe)
0783 return -ENODATA;
0784 val->intval = latest->temperature;
0785 break;
0786 default:
0787 return -EINVAL;
0788 }
0789
0790 return 0;
0791 }
0792
0793 static int cpcap_battery_update_charger(struct cpcap_battery_ddata *ddata,
0794 int const_charge_voltage)
0795 {
0796 union power_supply_propval prop;
0797 union power_supply_propval val;
0798 struct power_supply *charger;
0799 int error;
0800
0801 charger = power_supply_get_by_name("usb");
0802 if (!charger)
0803 return -ENODEV;
0804
0805 error = power_supply_get_property(charger,
0806 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
0807 &prop);
0808 if (error)
0809 goto out_put;
0810
0811
0812 if (const_charge_voltage > prop.intval)
0813 goto out_put;
0814
0815 val.intval = const_charge_voltage;
0816
0817 error = power_supply_set_property(charger,
0818 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
0819 &val);
0820 out_put:
0821 power_supply_put(charger);
0822
0823 return error;
0824 }
0825
0826 static int cpcap_battery_set_property(struct power_supply *psy,
0827 enum power_supply_property psp,
0828 const union power_supply_propval *val)
0829 {
0830 struct cpcap_battery_ddata *ddata = power_supply_get_drvdata(psy);
0831
0832 switch (psp) {
0833 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
0834 if (val->intval < ddata->config.info.voltage_min_design)
0835 return -EINVAL;
0836 if (val->intval > ddata->config.info.voltage_max_design)
0837 return -EINVAL;
0838
0839 ddata->config.bat.constant_charge_voltage_max_uv = val->intval;
0840
0841 return cpcap_battery_update_charger(ddata, val->intval);
0842 case POWER_SUPPLY_PROP_CHARGE_FULL:
0843 if (val->intval < 0)
0844 return -EINVAL;
0845 if (val->intval > (6*ddata->config.info.charge_full_design)/5)
0846 return -EINVAL;
0847
0848 ddata->charge_full = val->intval;
0849
0850 return 0;
0851 default:
0852 return -EINVAL;
0853 }
0854
0855 return 0;
0856 }
0857
0858 static int cpcap_battery_property_is_writeable(struct power_supply *psy,
0859 enum power_supply_property psp)
0860 {
0861 switch (psp) {
0862 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
0863 case POWER_SUPPLY_PROP_CHARGE_FULL:
0864 return 1;
0865 default:
0866 return 0;
0867 }
0868 }
0869
0870 static irqreturn_t cpcap_battery_irq_thread(int irq, void *data)
0871 {
0872 struct cpcap_battery_ddata *ddata = data;
0873 struct cpcap_battery_state_data *latest;
0874 struct cpcap_interrupt_desc *d;
0875
0876 if (!atomic_read(&ddata->active))
0877 return IRQ_NONE;
0878
0879 list_for_each_entry(d, &ddata->irq_list, node) {
0880 if (irq == d->irq)
0881 break;
0882 }
0883
0884 if (list_entry_is_head(d, &ddata->irq_list, node))
0885 return IRQ_NONE;
0886
0887 latest = cpcap_battery_latest(ddata);
0888
0889 switch (d->action) {
0890 case CPCAP_BATTERY_IRQ_ACTION_CC_CAL_DONE:
0891 dev_info(ddata->dev, "Coulomb counter calibration done\n");
0892 break;
0893 case CPCAP_BATTERY_IRQ_ACTION_BATTERY_LOW:
0894 if (latest->current_ua >= 0)
0895 dev_warn(ddata->dev, "Battery low at %imV!\n",
0896 latest->voltage / 1000);
0897 break;
0898 case CPCAP_BATTERY_IRQ_ACTION_POWEROFF:
0899 if (latest->current_ua >= 0 && latest->voltage <= 3200000) {
0900 dev_emerg(ddata->dev,
0901 "Battery empty at %imV, powering off\n",
0902 latest->voltage / 1000);
0903 orderly_poweroff(true);
0904 }
0905 break;
0906 default:
0907 break;
0908 }
0909
0910 power_supply_changed(ddata->psy);
0911
0912 return IRQ_HANDLED;
0913 }
0914
0915 static int cpcap_battery_init_irq(struct platform_device *pdev,
0916 struct cpcap_battery_ddata *ddata,
0917 const char *name)
0918 {
0919 struct cpcap_interrupt_desc *d;
0920 int irq, error;
0921
0922 irq = platform_get_irq_byname(pdev, name);
0923 if (irq < 0)
0924 return irq;
0925
0926 error = devm_request_threaded_irq(ddata->dev, irq, NULL,
0927 cpcap_battery_irq_thread,
0928 IRQF_SHARED | IRQF_ONESHOT,
0929 name, ddata);
0930 if (error) {
0931 dev_err(ddata->dev, "could not get irq %s: %i\n",
0932 name, error);
0933
0934 return error;
0935 }
0936
0937 d = devm_kzalloc(ddata->dev, sizeof(*d), GFP_KERNEL);
0938 if (!d)
0939 return -ENOMEM;
0940
0941 d->name = name;
0942 d->irq = irq;
0943
0944 if (!strncmp(name, "cccal", 5))
0945 d->action = CPCAP_BATTERY_IRQ_ACTION_CC_CAL_DONE;
0946 else if (!strncmp(name, "lowbph", 6))
0947 d->action = CPCAP_BATTERY_IRQ_ACTION_BATTERY_LOW;
0948 else if (!strncmp(name, "lowbpl", 6))
0949 d->action = CPCAP_BATTERY_IRQ_ACTION_POWEROFF;
0950
0951 list_add(&d->node, &ddata->irq_list);
0952
0953 return 0;
0954 }
0955
0956 static int cpcap_battery_init_interrupts(struct platform_device *pdev,
0957 struct cpcap_battery_ddata *ddata)
0958 {
0959 static const char * const cpcap_battery_irqs[] = {
0960 "eol", "lowbph", "lowbpl",
0961 "chrgcurr1", "battdetb"
0962 };
0963 int i, error;
0964
0965 for (i = 0; i < ARRAY_SIZE(cpcap_battery_irqs); i++) {
0966 error = cpcap_battery_init_irq(pdev, ddata,
0967 cpcap_battery_irqs[i]);
0968 if (error)
0969 return error;
0970 }
0971
0972
0973 cpcap_battery_init_irq(pdev, ddata, "cccal");
0974
0975
0976 error = regmap_update_bits(ddata->reg, CPCAP_REG_BPEOL,
0977 0xffff,
0978 CPCAP_REG_BPEOL_BIT_BATTDETEN);
0979 if (error)
0980 return error;
0981
0982 return 0;
0983 }
0984
0985 static int cpcap_battery_init_iio(struct cpcap_battery_ddata *ddata)
0986 {
0987 const char * const names[CPCAP_BATTERY_IIO_NR] = {
0988 "battdetb", "battp", "chg_isense", "batti",
0989 };
0990 int error, i;
0991
0992 for (i = 0; i < CPCAP_BATTERY_IIO_NR; i++) {
0993 ddata->channels[i] = devm_iio_channel_get(ddata->dev,
0994 names[i]);
0995 if (IS_ERR(ddata->channels[i])) {
0996 error = PTR_ERR(ddata->channels[i]);
0997 goto out_err;
0998 }
0999
1000 if (!ddata->channels[i]->indio_dev) {
1001 error = -ENXIO;
1002 goto out_err;
1003 }
1004 }
1005
1006 return 0;
1007
1008 out_err:
1009 return dev_err_probe(ddata->dev, error,
1010 "could not initialize VBUS or ID IIO\n");
1011 }
1012
1013
1014 static int cpcap_battery_calibrate(struct cpcap_battery_ddata *ddata)
1015 {
1016 int error, ccc1, value;
1017 unsigned long timeout;
1018
1019 error = regmap_read(ddata->reg, CPCAP_REG_CCC1, &ccc1);
1020 if (error)
1021 return error;
1022
1023 timeout = jiffies + msecs_to_jiffies(6000);
1024
1025
1026 error = regmap_update_bits(ddata->reg, CPCAP_REG_CCC1,
1027 0xffff,
1028 CPCAP_REG_CCC1_CAL_EN);
1029 if (error)
1030 goto restore;
1031
1032 while (time_before(jiffies, timeout)) {
1033 error = regmap_read(ddata->reg, CPCAP_REG_CCC1, &value);
1034 if (error)
1035 goto restore;
1036
1037 if (!(value & CPCAP_REG_CCC1_CAL_EN))
1038 break;
1039
1040 error = regmap_read(ddata->reg, CPCAP_REG_CCM, &value);
1041 if (error)
1042 goto restore;
1043
1044 msleep(300);
1045 }
1046
1047
1048 error = regmap_read(ddata->reg, CPCAP_REG_CCM, &value);
1049 if (error)
1050 goto restore;
1051
1052 dev_info(ddata->dev, "calibration done: 0x%04x\n", value);
1053
1054 restore:
1055 if (error)
1056 dev_err(ddata->dev, "%s: error %i\n", __func__, error);
1057
1058 error = regmap_update_bits(ddata->reg, CPCAP_REG_CCC1,
1059 0xffff, ccc1);
1060 if (error)
1061 dev_err(ddata->dev, "%s: restore error %i\n",
1062 __func__, error);
1063
1064 return error;
1065 }
1066
1067 #ifdef CONFIG_OF
1068 static const struct of_device_id cpcap_battery_id_table[] = {
1069 {
1070 .compatible = "motorola,cpcap-battery",
1071 },
1072 {},
1073 };
1074 MODULE_DEVICE_TABLE(of, cpcap_battery_id_table);
1075 #endif
1076
1077 static const struct power_supply_desc cpcap_charger_battery_desc = {
1078 .name = "battery",
1079 .type = POWER_SUPPLY_TYPE_BATTERY,
1080 .properties = cpcap_battery_props,
1081 .num_properties = ARRAY_SIZE(cpcap_battery_props),
1082 .get_property = cpcap_battery_get_property,
1083 .set_property = cpcap_battery_set_property,
1084 .property_is_writeable = cpcap_battery_property_is_writeable,
1085 .external_power_changed = cpcap_battery_external_power_changed,
1086 };
1087
1088 static int cpcap_battery_probe(struct platform_device *pdev)
1089 {
1090 struct cpcap_battery_ddata *ddata;
1091 struct power_supply_config psy_cfg = {};
1092 int error;
1093
1094 ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
1095 if (!ddata)
1096 return -ENOMEM;
1097
1098 cpcap_battery_detect_battery_type(ddata);
1099
1100 INIT_LIST_HEAD(&ddata->irq_list);
1101 ddata->dev = &pdev->dev;
1102
1103 ddata->reg = dev_get_regmap(ddata->dev->parent, NULL);
1104 if (!ddata->reg)
1105 return -ENODEV;
1106
1107 error = cpcap_get_vendor(ddata->dev, ddata->reg, &ddata->vendor);
1108 if (error)
1109 return error;
1110
1111 switch (ddata->vendor) {
1112 case CPCAP_VENDOR_ST:
1113 ddata->cc_lsb = 95374;
1114 break;
1115 case CPCAP_VENDOR_TI:
1116 ddata->cc_lsb = 91501;
1117 break;
1118 default:
1119 return -EINVAL;
1120 }
1121 ddata->cc_lsb = (ddata->cc_lsb * ddata->config.cd_factor) / 1000;
1122
1123 platform_set_drvdata(pdev, ddata);
1124
1125 error = cpcap_battery_init_interrupts(pdev, ddata);
1126 if (error)
1127 return error;
1128
1129 error = cpcap_battery_init_iio(ddata);
1130 if (error)
1131 return error;
1132
1133 psy_cfg.of_node = pdev->dev.of_node;
1134 psy_cfg.drv_data = ddata;
1135
1136 ddata->psy = devm_power_supply_register(ddata->dev,
1137 &cpcap_charger_battery_desc,
1138 &psy_cfg);
1139 error = PTR_ERR_OR_ZERO(ddata->psy);
1140 if (error) {
1141 dev_err(ddata->dev, "failed to register power supply\n");
1142 return error;
1143 }
1144
1145 atomic_set(&ddata->active, 1);
1146
1147 error = cpcap_battery_calibrate(ddata);
1148 if (error)
1149 return error;
1150
1151 return 0;
1152 }
1153
1154 static int cpcap_battery_remove(struct platform_device *pdev)
1155 {
1156 struct cpcap_battery_ddata *ddata = platform_get_drvdata(pdev);
1157 int error;
1158
1159 atomic_set(&ddata->active, 0);
1160 error = regmap_update_bits(ddata->reg, CPCAP_REG_BPEOL,
1161 0xffff, 0);
1162 if (error)
1163 dev_err(&pdev->dev, "could not disable: %i\n", error);
1164
1165 return 0;
1166 }
1167
1168 static struct platform_driver cpcap_battery_driver = {
1169 .driver = {
1170 .name = "cpcap_battery",
1171 .of_match_table = of_match_ptr(cpcap_battery_id_table),
1172 },
1173 .probe = cpcap_battery_probe,
1174 .remove = cpcap_battery_remove,
1175 };
1176 module_platform_driver(cpcap_battery_driver);
1177
1178 MODULE_LICENSE("GPL v2");
1179 MODULE_AUTHOR("Tony Lindgren <tony@atomide.com>");
1180 MODULE_DESCRIPTION("CPCAP PMIC Battery Driver");