1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Battery driver for CPCAP PMIC
4 *
5 * Copyright (C) 2017 Tony Lindgren <tony@atomide.com>
6 *
7 * Some parts of the code based on earlier Motorola mapphone Linux kernel
8 * drivers:
9 *
10 * Copyright (C) 2009-2010 Motorola, Inc.
11 */
12
13#include <linux/delay.h>
14#include <linux/err.h>
15#include <linux/interrupt.h>
16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/of.h>
19#include <linux/platform_device.h>
20#include <linux/power_supply.h>
21#include <linux/reboot.h>
22#include <linux/regmap.h>
23#include <linux/nvmem-consumer.h>
24#include <linux/moduleparam.h>
25
26#include <linux/iio/consumer.h>
27#include <linux/iio/types.h>
28#include <linux/mfd/motorola-cpcap.h>
29
30/*
31 * Register bit defines for CPCAP_REG_BPEOL. Some of these seem to
32 * map to MC13783UG.pdf "Table 5-19. Register 13, Power Control 0"
33 * to enable BATTDETEN, LOBAT and EOL features. We currently use
34 * LOBAT interrupts instead of EOL.
35 */
36#define CPCAP_REG_BPEOL_BIT_EOL9 BIT(9) /* Set for EOL irq */
37#define CPCAP_REG_BPEOL_BIT_EOL8 BIT(8) /* Set for EOL irq */
38#define CPCAP_REG_BPEOL_BIT_UNKNOWN7 BIT(7)
39#define CPCAP_REG_BPEOL_BIT_UNKNOWN6 BIT(6)
40#define CPCAP_REG_BPEOL_BIT_UNKNOWN5 BIT(5)
41#define CPCAP_REG_BPEOL_BIT_EOL_MULTI BIT(4) /* Set for multiple EOL irqs */
42#define CPCAP_REG_BPEOL_BIT_UNKNOWN3 BIT(3)
43#define CPCAP_REG_BPEOL_BIT_UNKNOWN2 BIT(2)
44#define CPCAP_REG_BPEOL_BIT_BATTDETEN BIT(1) /* Enable battery detect */
45#define CPCAP_REG_BPEOL_BIT_EOLSEL BIT(0) /* BPDET = 0, EOL = 1 */
46
47/*
48 * Register bit defines for CPCAP_REG_CCC1. These seem similar to the twl6030
49 * coulomb counter registers rather than the mc13892 registers. Both twl6030
50 * and mc13892 set bits 2 and 1 to reset and clear registers. But mc13892
51 * sets bit 0 to start the coulomb counter while twl6030 sets bit 0 to stop
52 * the coulomb counter like cpcap does. So for now, we use the twl6030 style
53 * naming for the registers.
54 */
55#define CPCAP_REG_CCC1_ACTIVE_MODE1 BIT(4) /* Update rate */
56#define CPCAP_REG_CCC1_ACTIVE_MODE0 BIT(3) /* Update rate */
57#define CPCAP_REG_CCC1_AUTOCLEAR BIT(2) /* Resets sample registers */
58#define CPCAP_REG_CCC1_CAL_EN BIT(1) /* Clears after write in 1s */
59#define CPCAP_REG_CCC1_PAUSE BIT(0) /* Stop counters, allow write */
60#define CPCAP_REG_CCC1_RESET_MASK (CPCAP_REG_CCC1_AUTOCLEAR | \
61 CPCAP_REG_CCC1_CAL_EN)
62
63#define CPCAP_REG_CCCC2_RATE1 BIT(5)
64#define CPCAP_REG_CCCC2_RATE0 BIT(4)
65#define CPCAP_REG_CCCC2_ENABLE BIT(3)
66
67#define CPCAP_BATTERY_CC_SAMPLE_PERIOD_MS 250
68
69#define CPCAP_BATTERY_EB41_HW4X_ID 0x9E
70#define CPCAP_BATTERY_BW8X_ID 0x98
71
72enum {
73 CPCAP_BATTERY_IIO_BATTDET,
74 CPCAP_BATTERY_IIO_VOLTAGE,
75 CPCAP_BATTERY_IIO_CHRG_CURRENT,
76 CPCAP_BATTERY_IIO_BATT_CURRENT,
77 CPCAP_BATTERY_IIO_NR,
78};
79
80enum cpcap_battery_irq_action {
81 CPCAP_BATTERY_IRQ_ACTION_NONE,
82 CPCAP_BATTERY_IRQ_ACTION_CC_CAL_DONE,
83 CPCAP_BATTERY_IRQ_ACTION_BATTERY_LOW,
84 CPCAP_BATTERY_IRQ_ACTION_POWEROFF,
85};
86
87struct cpcap_interrupt_desc {
88 const char *name;
89 struct list_head node;
90 int irq;
91 enum cpcap_battery_irq_action action;
92};
93
94struct cpcap_battery_config {
95 int cd_factor;
96 struct power_supply_info info;
97 struct power_supply_battery_info bat;
98};
99
100struct cpcap_coulomb_counter_data {
101 s32 sample; /* 24 or 32 bits */
102 s32 accumulator;
103 s16 offset; /* 9 bits */
104 s16 integrator; /* 13 or 16 bits */
105};
106
107enum cpcap_battery_state {
108 CPCAP_BATTERY_STATE_PREVIOUS,
109 CPCAP_BATTERY_STATE_LATEST,
110 CPCAP_BATTERY_STATE_EMPTY,
111 CPCAP_BATTERY_STATE_FULL,
112 CPCAP_BATTERY_STATE_NR,
113};
114
115struct cpcap_battery_state_data {
116 int voltage;
117 int current_ua;
118 int counter_uah;
119 int temperature;
120 ktime_t time;
121 struct cpcap_coulomb_counter_data cc;
122};
123
124struct cpcap_battery_ddata {
125 struct device *dev;
126 struct regmap *reg;
127 struct list_head irq_list;
128 struct iio_channel *channels[CPCAP_BATTERY_IIO_NR];
129 struct power_supply *psy;
130 struct cpcap_battery_config config;
131 struct cpcap_battery_state_data state[CPCAP_BATTERY_STATE_NR];
132 u32 cc_lsb; /* μAms per LSB */
133 atomic_t active;
134 int charge_full;
135 int status;
136 u16 vendor;
137 bool check_nvmem;
138 unsigned int is_full:1;
139};
140
141#define CPCAP_NO_BATTERY -400
142
143static bool ignore_temperature_probe;
144module_param(ignore_temperature_probe, bool, 0660);
145
146static struct cpcap_battery_state_data *
147cpcap_battery_get_state(struct cpcap_battery_ddata *ddata,
148 enum cpcap_battery_state state)
149{
150 if (state >= CPCAP_BATTERY_STATE_NR)
151 return NULL;
152
153 return &ddata->state[state];
154}
155
156static struct cpcap_battery_state_data *
157cpcap_battery_latest(struct cpcap_battery_ddata *ddata)
158{
159 return cpcap_battery_get_state(ddata, state: CPCAP_BATTERY_STATE_LATEST);
160}
161
162static struct cpcap_battery_state_data *
163cpcap_battery_previous(struct cpcap_battery_ddata *ddata)
164{
165 return cpcap_battery_get_state(ddata, state: CPCAP_BATTERY_STATE_PREVIOUS);
166}
167
168static struct cpcap_battery_state_data *
169cpcap_battery_get_empty(struct cpcap_battery_ddata *ddata)
170{
171 return cpcap_battery_get_state(ddata, state: CPCAP_BATTERY_STATE_EMPTY);
172}
173
174static struct cpcap_battery_state_data *
175cpcap_battery_get_full(struct cpcap_battery_ddata *ddata)
176{
177 return cpcap_battery_get_state(ddata, state: CPCAP_BATTERY_STATE_FULL);
178}
179
180static int cpcap_charger_battery_temperature(struct cpcap_battery_ddata *ddata,
181 int *value)
182{
183 struct iio_channel *channel;
184 int error;
185
186 channel = ddata->channels[CPCAP_BATTERY_IIO_BATTDET];
187 error = iio_read_channel_processed(chan: channel, val: value);
188 if (error < 0) {
189 if (!ignore_temperature_probe)
190 dev_warn(ddata->dev, "%s failed: %i\n", __func__, error);
191 *value = CPCAP_NO_BATTERY;
192
193 return error;
194 }
195
196 *value /= 100;
197
198 return 0;
199}
200
201static int cpcap_battery_get_voltage(struct cpcap_battery_ddata *ddata)
202{
203 struct iio_channel *channel;
204 int error, value = 0;
205
206 channel = ddata->channels[CPCAP_BATTERY_IIO_VOLTAGE];
207 error = iio_read_channel_processed(chan: channel, val: &value);
208 if (error < 0) {
209 dev_warn(ddata->dev, "%s failed: %i\n", __func__, error);
210
211 return 0;
212 }
213
214 return value * 1000;
215}
216
217static int cpcap_battery_get_current(struct cpcap_battery_ddata *ddata)
218{
219 struct iio_channel *channel;
220 int error, value = 0;
221
222 channel = ddata->channels[CPCAP_BATTERY_IIO_BATT_CURRENT];
223 error = iio_read_channel_processed(chan: channel, val: &value);
224 if (error < 0) {
225 dev_warn(ddata->dev, "%s failed: %i\n", __func__, error);
226
227 return 0;
228 }
229
230 return value * 1000;
231}
232
233/**
234 * cpcap_battery_cc_raw_div - calculate and divide coulomb counter μAms values
235 * @ddata: device driver data
236 * @sample: coulomb counter sample value
237 * @accumulator: coulomb counter integrator value
238 * @offset: coulomb counter offset value
239 * @divider: conversion divider
240 *
241 * Note that cc_lsb and cc_dur values are from Motorola Linux kernel
242 * function data_get_avg_curr_ua() and seem to be based on measured test
243 * results. It also has the following comment:
244 *
245 * Adjustment factors are applied here as a temp solution per the test
246 * results. Need to work out a formal solution for this adjustment.
247 *
248 * A coulomb counter for similar hardware seems to be documented in
249 * "TWL6030 Gas Gauging Basics (Rev. A)" swca095a.pdf in chapter
250 * "10 Calculating Accumulated Current". We however follow what the
251 * Motorola mapphone Linux kernel is doing as there may be either a
252 * TI or ST coulomb counter in the PMIC.
253 */
254static int cpcap_battery_cc_raw_div(struct cpcap_battery_ddata *ddata,
255 s32 sample, s32 accumulator,
256 s16 offset, u32 divider)
257{
258 s64 acc;
259
260 if (!divider)
261 return 0;
262
263 acc = accumulator;
264 acc -= (s64)sample * offset;
265 acc *= ddata->cc_lsb;
266 acc *= -1;
267 acc = div_s64(dividend: acc, divisor: divider);
268
269 return acc;
270}
271
272/* 3600000μAms = 1μAh */
273static int cpcap_battery_cc_to_uah(struct cpcap_battery_ddata *ddata,
274 s32 sample, s32 accumulator,
275 s16 offset)
276{
277 return cpcap_battery_cc_raw_div(ddata, sample,
278 accumulator, offset,
279 divider: 3600000);
280}
281
282static int cpcap_battery_cc_to_ua(struct cpcap_battery_ddata *ddata,
283 s32 sample, s32 accumulator,
284 s16 offset)
285{
286 return cpcap_battery_cc_raw_div(ddata, sample,
287 accumulator, offset,
288 divider: sample *
289 CPCAP_BATTERY_CC_SAMPLE_PERIOD_MS);
290}
291
292/**
293 * cpcap_battery_read_accumulated - reads cpcap coulomb counter
294 * @ddata: device driver data
295 * @ccd: coulomb counter values
296 *
297 * Based on Motorola mapphone kernel function data_read_regs().
298 * Looking at the registers, the coulomb counter seems similar to
299 * the coulomb counter in TWL6030. See "TWL6030 Gas Gauging Basics
300 * (Rev. A) swca095a.pdf for "10 Calculating Accumulated Current".
301 *
302 * Note that swca095a.pdf instructs to stop the coulomb counter
303 * before reading to avoid values changing. Motorola mapphone
304 * Linux kernel does not do it, so let's assume they've verified
305 * the data produced is correct.
306 */
307static int
308cpcap_battery_read_accumulated(struct cpcap_battery_ddata *ddata,
309 struct cpcap_coulomb_counter_data *ccd)
310{
311 u16 buf[7]; /* CPCAP_REG_CCS1 to CCI */
312 int error;
313
314 ccd->sample = 0;
315 ccd->accumulator = 0;
316 ccd->offset = 0;
317 ccd->integrator = 0;
318
319 /* Read coulomb counter register range */
320 error = regmap_bulk_read(map: ddata->reg, CPCAP_REG_CCS1,
321 val: buf, ARRAY_SIZE(buf));
322 if (error)
323 return 0;
324
325 /* Sample value CPCAP_REG_CCS1 & 2 */
326 ccd->sample = (buf[1] & 0x0fff) << 16;
327 ccd->sample |= buf[0];
328 if (ddata->vendor == CPCAP_VENDOR_TI)
329 ccd->sample = sign_extend32(value: 24, index: ccd->sample);
330
331 /* Accumulator value CPCAP_REG_CCA1 & 2 */
332 ccd->accumulator = ((s16)buf[3]) << 16;
333 ccd->accumulator |= buf[2];
334
335 /*
336 * Coulomb counter calibration offset is CPCAP_REG_CCM,
337 * REG_CCO seems unused
338 */
339 ccd->offset = buf[4];
340 ccd->offset = sign_extend32(value: ccd->offset, index: 9);
341
342 /* Integrator register CPCAP_REG_CCI */
343 if (ddata->vendor == CPCAP_VENDOR_TI)
344 ccd->integrator = sign_extend32(value: buf[6], index: 13);
345 else
346 ccd->integrator = (s16)buf[6];
347
348 return cpcap_battery_cc_to_uah(ddata,
349 sample: ccd->sample,
350 accumulator: ccd->accumulator,
351 offset: ccd->offset);
352}
353
354
355/*
356 * Based on the values from Motorola mapphone Linux kernel for the
357 * stock Droid 4 battery eb41. In the Motorola mapphone Linux
358 * kernel tree the value for pm_cd_factor is passed to the kernel
359 * via device tree. If it turns out to be something device specific
360 * we can consider that too later. These values are also fine for
361 * Bionic's hw4x.
362 *
363 * And looking at the battery full and shutdown values for the stock
364 * kernel on droid 4, full is 4351000 and software initiates shutdown
365 * at 3078000. The device will die around 2743000.
366 */
367static const struct cpcap_battery_config cpcap_battery_eb41_data = {
368 .cd_factor = 0x3cc,
369 .info.technology = POWER_SUPPLY_TECHNOLOGY_LION,
370 .info.voltage_max_design = 4351000,
371 .info.voltage_min_design = 3100000,
372 .info.charge_full_design = 1740000,
373 .bat.constant_charge_voltage_max_uv = 4200000,
374};
375
376/* Values for the extended Droid Bionic battery bw8x. */
377static const struct cpcap_battery_config cpcap_battery_bw8x_data = {
378 .cd_factor = 0x3cc,
379 .info.technology = POWER_SUPPLY_TECHNOLOGY_LION,
380 .info.voltage_max_design = 4200000,
381 .info.voltage_min_design = 3200000,
382 .info.charge_full_design = 2760000,
383 .bat.constant_charge_voltage_max_uv = 4200000,
384};
385
386/*
387 * Safe values for any lipo battery likely to fit into a mapphone
388 * battery bay.
389 */
390static const struct cpcap_battery_config cpcap_battery_unkown_data = {
391 .cd_factor = 0x3cc,
392 .info.technology = POWER_SUPPLY_TECHNOLOGY_LION,
393 .info.voltage_max_design = 4200000,
394 .info.voltage_min_design = 3200000,
395 .info.charge_full_design = 3000000,
396 .bat.constant_charge_voltage_max_uv = 4200000,
397};
398
399static int cpcap_battery_match_nvmem(struct device *dev, const void *data)
400{
401 if (strcmp(dev_name(dev), "89-500029ba0f73") == 0)
402 return 1;
403 else
404 return 0;
405}
406
407static void cpcap_battery_detect_battery_type(struct cpcap_battery_ddata *ddata)
408{
409 struct nvmem_device *nvmem;
410 u8 battery_id = 0;
411
412 ddata->check_nvmem = false;
413
414 nvmem = nvmem_device_find(NULL, match: &cpcap_battery_match_nvmem);
415 if (IS_ERR_OR_NULL(ptr: nvmem)) {
416 ddata->check_nvmem = true;
417 dev_info_once(ddata->dev, "Can not find battery nvmem device. Assuming generic lipo battery\n");
418 } else if (nvmem_device_read(nvmem, offset: 2, bytes: 1, buf: &battery_id) < 0) {
419 battery_id = 0;
420 ddata->check_nvmem = true;
421 dev_warn(ddata->dev, "Can not read battery nvmem device. Assuming generic lipo battery\n");
422 }
423
424 switch (battery_id) {
425 case CPCAP_BATTERY_EB41_HW4X_ID:
426 ddata->config = cpcap_battery_eb41_data;
427 break;
428 case CPCAP_BATTERY_BW8X_ID:
429 ddata->config = cpcap_battery_bw8x_data;
430 break;
431 default:
432 ddata->config = cpcap_battery_unkown_data;
433 }
434}
435
436/**
437 * cpcap_battery_cc_get_avg_current - read cpcap coulumb counter
438 * @ddata: cpcap battery driver device data
439 */
440static int cpcap_battery_cc_get_avg_current(struct cpcap_battery_ddata *ddata)
441{
442 int value, acc, error;
443 s32 sample;
444 s16 offset;
445
446 /* Coulomb counter integrator */
447 error = regmap_read(map: ddata->reg, CPCAP_REG_CCI, val: &value);
448 if (error)
449 return error;
450
451 if (ddata->vendor == CPCAP_VENDOR_TI) {
452 acc = sign_extend32(value, index: 13);
453 sample = 1;
454 } else {
455 acc = (s16)value;
456 sample = 4;
457 }
458
459 /* Coulomb counter calibration offset */
460 error = regmap_read(map: ddata->reg, CPCAP_REG_CCM, val: &value);
461 if (error)
462 return error;
463
464 offset = sign_extend32(value, index: 9);
465
466 return cpcap_battery_cc_to_ua(ddata, sample, accumulator: acc, offset);
467}
468
469static int cpcap_battery_get_charger_status(struct cpcap_battery_ddata *ddata,
470 int *val)
471{
472 union power_supply_propval prop;
473 struct power_supply *charger;
474 int error;
475
476 charger = power_supply_get_by_name(name: "usb");
477 if (!charger)
478 return -ENODEV;
479
480 error = power_supply_get_property(psy: charger, psp: POWER_SUPPLY_PROP_STATUS,
481 val: &prop);
482 if (error)
483 *val = POWER_SUPPLY_STATUS_UNKNOWN;
484 else
485 *val = prop.intval;
486
487 power_supply_put(psy: charger);
488
489 return error;
490}
491
492static bool cpcap_battery_full(struct cpcap_battery_ddata *ddata)
493{
494 struct cpcap_battery_state_data *state = cpcap_battery_latest(ddata);
495 unsigned int vfull;
496 int error, val;
497
498 error = cpcap_battery_get_charger_status(ddata, val: &val);
499 if (!error) {
500 switch (val) {
501 case POWER_SUPPLY_STATUS_DISCHARGING:
502 dev_dbg(ddata->dev, "charger disconnected\n");
503 ddata->is_full = 0;
504 break;
505 case POWER_SUPPLY_STATUS_FULL:
506 dev_dbg(ddata->dev, "charger full status\n");
507 ddata->is_full = 1;
508 break;
509 default:
510 break;
511 }
512 }
513
514 /*
515 * The full battery voltage here can be inaccurate, it's used just to
516 * filter out any trickle charging events. We clear the is_full status
517 * on charger disconnect above anyways.
518 */
519 vfull = ddata->config.bat.constant_charge_voltage_max_uv - 120000;
520
521 if (ddata->is_full && state->voltage < vfull)
522 ddata->is_full = 0;
523
524 return ddata->is_full;
525}
526
527static bool cpcap_battery_low(struct cpcap_battery_ddata *ddata)
528{
529 struct cpcap_battery_state_data *state = cpcap_battery_latest(ddata);
530 static bool is_low;
531
532 if (state->current_ua > 0 && (state->voltage <= 3350000 || is_low))
533 is_low = true;
534 else
535 is_low = false;
536
537 return is_low;
538}
539
540static int cpcap_battery_update_status(struct cpcap_battery_ddata *ddata)
541{
542 struct cpcap_battery_state_data state, *latest, *previous,
543 *empty, *full;
544 ktime_t now;
545 int error;
546
547 memset(&state, 0, sizeof(state));
548 now = ktime_get();
549
550 latest = cpcap_battery_latest(ddata);
551 if (latest) {
552 s64 delta_ms = ktime_to_ms(ktime_sub(now, latest->time));
553
554 if (delta_ms < CPCAP_BATTERY_CC_SAMPLE_PERIOD_MS)
555 return delta_ms;
556 }
557
558 state.time = now;
559 state.voltage = cpcap_battery_get_voltage(ddata);
560 state.current_ua = cpcap_battery_get_current(ddata);
561 state.counter_uah = cpcap_battery_read_accumulated(ddata, ccd: &state.cc);
562
563 error = cpcap_charger_battery_temperature(ddata,
564 value: &state.temperature);
565 if (error)
566 return error;
567
568 previous = cpcap_battery_previous(ddata);
569 memcpy(previous, latest, sizeof(*previous));
570 memcpy(latest, &state, sizeof(*latest));
571
572 if (cpcap_battery_full(ddata)) {
573 full = cpcap_battery_get_full(ddata);
574 memcpy(full, latest, sizeof(*full));
575
576 empty = cpcap_battery_get_empty(ddata);
577 if (empty->voltage && empty->voltage != -1) {
578 empty->voltage = -1;
579 ddata->charge_full =
580 empty->counter_uah - full->counter_uah;
581 } else if (ddata->charge_full) {
582 empty->voltage = -1;
583 empty->counter_uah =
584 full->counter_uah + ddata->charge_full;
585 }
586 } else if (cpcap_battery_low(ddata)) {
587 empty = cpcap_battery_get_empty(ddata);
588 memcpy(empty, latest, sizeof(*empty));
589
590 full = cpcap_battery_get_full(ddata);
591 if (full->voltage) {
592 full->voltage = 0;
593 ddata->charge_full =
594 empty->counter_uah - full->counter_uah;
595 }
596 }
597
598 return 0;
599}
600
601/*
602 * Update battery status when cpcap-charger calls power_supply_changed().
603 * This allows us to detect battery full condition before the charger
604 * disconnects.
605 */
606static void cpcap_battery_external_power_changed(struct power_supply *psy)
607{
608 union power_supply_propval prop;
609
610 power_supply_get_property(psy, psp: POWER_SUPPLY_PROP_STATUS, val: &prop);
611}
612
613static enum power_supply_property cpcap_battery_props[] = {
614 POWER_SUPPLY_PROP_STATUS,
615 POWER_SUPPLY_PROP_PRESENT,
616 POWER_SUPPLY_PROP_TECHNOLOGY,
617 POWER_SUPPLY_PROP_VOLTAGE_NOW,
618 POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
619 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
620 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
621 POWER_SUPPLY_PROP_CURRENT_AVG,
622 POWER_SUPPLY_PROP_CURRENT_NOW,
623 POWER_SUPPLY_PROP_CHARGE_FULL,
624 POWER_SUPPLY_PROP_CHARGE_NOW,
625 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
626 POWER_SUPPLY_PROP_CHARGE_COUNTER,
627 POWER_SUPPLY_PROP_POWER_NOW,
628 POWER_SUPPLY_PROP_POWER_AVG,
629 POWER_SUPPLY_PROP_CAPACITY,
630 POWER_SUPPLY_PROP_CAPACITY_LEVEL,
631 POWER_SUPPLY_PROP_SCOPE,
632 POWER_SUPPLY_PROP_TEMP,
633};
634
635static int cpcap_battery_get_property(struct power_supply *psy,
636 enum power_supply_property psp,
637 union power_supply_propval *val)
638{
639 struct cpcap_battery_ddata *ddata = power_supply_get_drvdata(psy);
640 struct cpcap_battery_state_data *latest, *previous, *empty;
641 u32 sample;
642 s32 accumulator;
643 int cached;
644 s64 tmp;
645
646 cached = cpcap_battery_update_status(ddata);
647 if (cached < 0)
648 return cached;
649
650 latest = cpcap_battery_latest(ddata);
651 previous = cpcap_battery_previous(ddata);
652
653 if (ddata->check_nvmem)
654 cpcap_battery_detect_battery_type(ddata);
655
656 switch (psp) {
657 case POWER_SUPPLY_PROP_PRESENT:
658 if (latest->temperature > CPCAP_NO_BATTERY || ignore_temperature_probe)
659 val->intval = 1;
660 else
661 val->intval = 0;
662 break;
663 case POWER_SUPPLY_PROP_STATUS:
664 if (cpcap_battery_full(ddata)) {
665 val->intval = POWER_SUPPLY_STATUS_FULL;
666 break;
667 }
668 if (cpcap_battery_cc_get_avg_current(ddata) < 0)
669 val->intval = POWER_SUPPLY_STATUS_CHARGING;
670 else
671 val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
672 break;
673 case POWER_SUPPLY_PROP_TECHNOLOGY:
674 val->intval = ddata->config.info.technology;
675 break;
676 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
677 val->intval = cpcap_battery_get_voltage(ddata);
678 break;
679 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
680 val->intval = ddata->config.info.voltage_max_design;
681 break;
682 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
683 val->intval = ddata->config.info.voltage_min_design;
684 break;
685 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
686 val->intval = ddata->config.bat.constant_charge_voltage_max_uv;
687 break;
688 case POWER_SUPPLY_PROP_CURRENT_AVG:
689 sample = latest->cc.sample - previous->cc.sample;
690 if (!sample) {
691 val->intval = cpcap_battery_cc_get_avg_current(ddata);
692 break;
693 }
694 accumulator = latest->cc.accumulator - previous->cc.accumulator;
695 val->intval = cpcap_battery_cc_to_ua(ddata, sample,
696 accumulator,
697 offset: latest->cc.offset);
698 break;
699 case POWER_SUPPLY_PROP_CURRENT_NOW:
700 val->intval = latest->current_ua;
701 break;
702 case POWER_SUPPLY_PROP_CHARGE_COUNTER:
703 val->intval = latest->counter_uah;
704 break;
705 case POWER_SUPPLY_PROP_POWER_NOW:
706 tmp = (latest->voltage / 10000) * latest->current_ua;
707 val->intval = div64_s64(dividend: tmp, divisor: 100);
708 break;
709 case POWER_SUPPLY_PROP_POWER_AVG:
710 sample = latest->cc.sample - previous->cc.sample;
711 if (!sample) {
712 tmp = cpcap_battery_cc_get_avg_current(ddata);
713 tmp *= (latest->voltage / 10000);
714 val->intval = div64_s64(dividend: tmp, divisor: 100);
715 break;
716 }
717 accumulator = latest->cc.accumulator - previous->cc.accumulator;
718 tmp = cpcap_battery_cc_to_ua(ddata, sample, accumulator,
719 offset: latest->cc.offset);
720 tmp *= ((latest->voltage + previous->voltage) / 20000);
721 val->intval = div64_s64(dividend: tmp, divisor: 100);
722 break;
723 case POWER_SUPPLY_PROP_CAPACITY:
724 empty = cpcap_battery_get_empty(ddata);
725 if (!empty->voltage || !ddata->charge_full)
726 return -ENODATA;
727 /* (ddata->charge_full / 200) is needed for rounding */
728 val->intval = empty->counter_uah - latest->counter_uah +
729 ddata->charge_full / 200;
730 val->intval = clamp(val->intval, 0, ddata->charge_full);
731 val->intval = val->intval * 100 / ddata->charge_full;
732 break;
733 case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
734 if (cpcap_battery_full(ddata))
735 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
736 else if (latest->voltage >= 3750000)
737 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_HIGH;
738 else if (latest->voltage >= 3300000)
739 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
740 else if (latest->voltage > 3100000)
741 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
742 else if (latest->voltage <= 3100000)
743 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
744 else
745 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN;
746 break;
747 case POWER_SUPPLY_PROP_CHARGE_NOW:
748 empty = cpcap_battery_get_empty(ddata);
749 if (!empty->voltage)
750 return -ENODATA;
751 val->intval = empty->counter_uah - latest->counter_uah;
752 if (val->intval < 0) {
753 /* Assume invalid config if CHARGE_NOW is -20% */
754 if (ddata->charge_full && abs(val->intval) > ddata->charge_full/5) {
755 empty->voltage = 0;
756 ddata->charge_full = 0;
757 return -ENODATA;
758 }
759 val->intval = 0;
760 } else if (ddata->charge_full && ddata->charge_full < val->intval) {
761 /* Assume invalid config if CHARGE_NOW exceeds CHARGE_FULL by 20% */
762 if (val->intval > (6*ddata->charge_full)/5) {
763 empty->voltage = 0;
764 ddata->charge_full = 0;
765 return -ENODATA;
766 }
767 val->intval = ddata->charge_full;
768 }
769 break;
770 case POWER_SUPPLY_PROP_CHARGE_FULL:
771 if (!ddata->charge_full)
772 return -ENODATA;
773 val->intval = ddata->charge_full;
774 break;
775 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
776 val->intval = ddata->config.info.charge_full_design;
777 break;
778 case POWER_SUPPLY_PROP_SCOPE:
779 val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
780 break;
781 case POWER_SUPPLY_PROP_TEMP:
782 if (ignore_temperature_probe)
783 return -ENODATA;
784 val->intval = latest->temperature;
785 break;
786 default:
787 return -EINVAL;
788 }
789
790 return 0;
791}
792
793static int cpcap_battery_update_charger(struct cpcap_battery_ddata *ddata,
794 int const_charge_voltage)
795{
796 union power_supply_propval prop;
797 union power_supply_propval val;
798 struct power_supply *charger;
799 int error;
800
801 charger = power_supply_get_by_name(name: "usb");
802 if (!charger)
803 return -ENODEV;
804
805 error = power_supply_get_property(psy: charger,
806 psp: POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
807 val: &prop);
808 if (error)
809 goto out_put;
810
811 /* Allow charger const voltage lower than battery const voltage */
812 if (const_charge_voltage > prop.intval)
813 goto out_put;
814
815 val.intval = const_charge_voltage;
816
817 error = power_supply_set_property(psy: charger,
818 psp: POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
819 val: &val);
820out_put:
821 power_supply_put(psy: charger);
822
823 return error;
824}
825
826static int cpcap_battery_set_property(struct power_supply *psy,
827 enum power_supply_property psp,
828 const union power_supply_propval *val)
829{
830 struct cpcap_battery_ddata *ddata = power_supply_get_drvdata(psy);
831
832 switch (psp) {
833 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
834 if (val->intval < ddata->config.info.voltage_min_design)
835 return -EINVAL;
836 if (val->intval > ddata->config.info.voltage_max_design)
837 return -EINVAL;
838
839 ddata->config.bat.constant_charge_voltage_max_uv = val->intval;
840
841 return cpcap_battery_update_charger(ddata, const_charge_voltage: val->intval);
842 case POWER_SUPPLY_PROP_CHARGE_FULL:
843 if (val->intval < 0)
844 return -EINVAL;
845 if (val->intval > (6*ddata->config.info.charge_full_design)/5)
846 return -EINVAL;
847
848 ddata->charge_full = val->intval;
849
850 return 0;
851 default:
852 return -EINVAL;
853 }
854
855 return 0;
856}
857
858static int cpcap_battery_property_is_writeable(struct power_supply *psy,
859 enum power_supply_property psp)
860{
861 switch (psp) {
862 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
863 case POWER_SUPPLY_PROP_CHARGE_FULL:
864 return 1;
865 default:
866 return 0;
867 }
868}
869
870static irqreturn_t cpcap_battery_irq_thread(int irq, void *data)
871{
872 struct cpcap_battery_ddata *ddata = data;
873 struct cpcap_battery_state_data *latest;
874 struct cpcap_interrupt_desc *d;
875
876 if (!atomic_read(v: &ddata->active))
877 return IRQ_NONE;
878
879 list_for_each_entry(d, &ddata->irq_list, node) {
880 if (irq == d->irq)
881 break;
882 }
883
884 if (list_entry_is_head(d, &ddata->irq_list, node))
885 return IRQ_NONE;
886
887 latest = cpcap_battery_latest(ddata);
888
889 switch (d->action) {
890 case CPCAP_BATTERY_IRQ_ACTION_CC_CAL_DONE:
891 dev_info(ddata->dev, "Coulomb counter calibration done\n");
892 break;
893 case CPCAP_BATTERY_IRQ_ACTION_BATTERY_LOW:
894 if (latest->current_ua >= 0)
895 dev_warn(ddata->dev, "Battery low at %imV!\n",
896 latest->voltage / 1000);
897 break;
898 case CPCAP_BATTERY_IRQ_ACTION_POWEROFF:
899 if (latest->current_ua >= 0 && latest->voltage <= 3200000) {
900 dev_emerg(ddata->dev,
901 "Battery empty at %imV, powering off\n",
902 latest->voltage / 1000);
903 orderly_poweroff(force: true);
904 }
905 break;
906 default:
907 break;
908 }
909
910 power_supply_changed(psy: ddata->psy);
911
912 return IRQ_HANDLED;
913}
914
915static int cpcap_battery_init_irq(struct platform_device *pdev,
916 struct cpcap_battery_ddata *ddata,
917 const char *name)
918{
919 struct cpcap_interrupt_desc *d;
920 int irq, error;
921
922 irq = platform_get_irq_byname(pdev, name);
923 if (irq < 0)
924 return irq;
925
926 error = devm_request_threaded_irq(dev: ddata->dev, irq, NULL,
927 thread_fn: cpcap_battery_irq_thread,
928 IRQF_SHARED | IRQF_ONESHOT,
929 devname: name, dev_id: ddata);
930 if (error) {
931 dev_err(ddata->dev, "could not get irq %s: %i\n",
932 name, error);
933
934 return error;
935 }
936
937 d = devm_kzalloc(dev: ddata->dev, size: sizeof(*d), GFP_KERNEL);
938 if (!d)
939 return -ENOMEM;
940
941 d->name = name;
942 d->irq = irq;
943
944 if (!strncmp(name, "cccal", 5))
945 d->action = CPCAP_BATTERY_IRQ_ACTION_CC_CAL_DONE;
946 else if (!strncmp(name, "lowbph", 6))
947 d->action = CPCAP_BATTERY_IRQ_ACTION_BATTERY_LOW;
948 else if (!strncmp(name, "lowbpl", 6))
949 d->action = CPCAP_BATTERY_IRQ_ACTION_POWEROFF;
950
951 list_add(new: &d->node, head: &ddata->irq_list);
952
953 return 0;
954}
955
956static int cpcap_battery_init_interrupts(struct platform_device *pdev,
957 struct cpcap_battery_ddata *ddata)
958{
959 static const char * const cpcap_battery_irqs[] = {
960 "eol", "lowbph", "lowbpl",
961 "chrgcurr1", "battdetb"
962 };
963 int i, error;
964
965 for (i = 0; i < ARRAY_SIZE(cpcap_battery_irqs); i++) {
966 error = cpcap_battery_init_irq(pdev, ddata,
967 name: cpcap_battery_irqs[i]);
968 if (error)
969 return error;
970 }
971
972 /* Enable calibration interrupt if already available in dts */
973 cpcap_battery_init_irq(pdev, ddata, name: "cccal");
974
975 /* Enable low battery interrupts for 3.3V high and 3.1V low */
976 error = regmap_update_bits(map: ddata->reg, CPCAP_REG_BPEOL,
977 mask: 0xffff,
978 CPCAP_REG_BPEOL_BIT_BATTDETEN);
979 if (error)
980 return error;
981
982 return 0;
983}
984
985static int cpcap_battery_init_iio(struct cpcap_battery_ddata *ddata)
986{
987 const char * const names[CPCAP_BATTERY_IIO_NR] = {
988 "battdetb", "battp", "chg_isense", "batti",
989 };
990 int error, i;
991
992 for (i = 0; i < CPCAP_BATTERY_IIO_NR; i++) {
993 ddata->channels[i] = devm_iio_channel_get(dev: ddata->dev,
994 consumer_channel: names[i]);
995 if (IS_ERR(ptr: ddata->channels[i])) {
996 error = PTR_ERR(ptr: ddata->channels[i]);
997 goto out_err;
998 }
999
1000 if (!ddata->channels[i]->indio_dev) {
1001 error = -ENXIO;
1002 goto out_err;
1003 }
1004 }
1005
1006 return 0;
1007
1008out_err:
1009 return dev_err_probe(dev: ddata->dev, err: error,
1010 fmt: "could not initialize VBUS or ID IIO\n");
1011}
1012
1013/* Calibrate coulomb counter */
1014static int cpcap_battery_calibrate(struct cpcap_battery_ddata *ddata)
1015{
1016 int error, ccc1, value;
1017 unsigned long timeout;
1018
1019 error = regmap_read(map: ddata->reg, CPCAP_REG_CCC1, val: &ccc1);
1020 if (error)
1021 return error;
1022
1023 timeout = jiffies + msecs_to_jiffies(m: 6000);
1024
1025 /* Start calibration */
1026 error = regmap_update_bits(map: ddata->reg, CPCAP_REG_CCC1,
1027 mask: 0xffff,
1028 CPCAP_REG_CCC1_CAL_EN);
1029 if (error)
1030 goto restore;
1031
1032 while (time_before(jiffies, timeout)) {
1033 error = regmap_read(map: ddata->reg, CPCAP_REG_CCC1, val: &value);
1034 if (error)
1035 goto restore;
1036
1037 if (!(value & CPCAP_REG_CCC1_CAL_EN))
1038 break;
1039
1040 error = regmap_read(map: ddata->reg, CPCAP_REG_CCM, val: &value);
1041 if (error)
1042 goto restore;
1043
1044 msleep(msecs: 300);
1045 }
1046
1047 /* Read calibration offset from CCM */
1048 error = regmap_read(map: ddata->reg, CPCAP_REG_CCM, val: &value);
1049 if (error)
1050 goto restore;
1051
1052 dev_info(ddata->dev, "calibration done: 0x%04x\n", value);
1053
1054restore:
1055 if (error)
1056 dev_err(ddata->dev, "%s: error %i\n", __func__, error);
1057
1058 error = regmap_update_bits(map: ddata->reg, CPCAP_REG_CCC1,
1059 mask: 0xffff, val: 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
1068static const struct of_device_id cpcap_battery_id_table[] = {
1069 {
1070 .compatible = "motorola,cpcap-battery",
1071 },
1072 {},
1073};
1074MODULE_DEVICE_TABLE(of, cpcap_battery_id_table);
1075#endif
1076
1077static 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
1088static 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(dev: &pdev->dev, size: sizeof(*ddata), GFP_KERNEL);
1095 if (!ddata)
1096 return -ENOMEM;
1097
1098 cpcap_battery_detect_battery_type(ddata);
1099
1100 INIT_LIST_HEAD(list: &ddata->irq_list);
1101 ddata->dev = &pdev->dev;
1102
1103 ddata->reg = dev_get_regmap(dev: ddata->dev->parent, NULL);
1104 if (!ddata->reg)
1105 return -ENODEV;
1106
1107 error = cpcap_get_vendor(dev: ddata->dev, regmap: ddata->reg, vendor: &ddata->vendor);
1108 if (error)
1109 return error;
1110
1111 switch (ddata->vendor) {
1112 case CPCAP_VENDOR_ST:
1113 ddata->cc_lsb = 95374; /* μAms per LSB */
1114 break;
1115 case CPCAP_VENDOR_TI:
1116 ddata->cc_lsb = 91501; /* μAms per LSB */
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, data: 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(parent: ddata->dev,
1137 desc: &cpcap_charger_battery_desc,
1138 cfg: &psy_cfg);
1139 error = PTR_ERR_OR_ZERO(ptr: ddata->psy);
1140 if (error) {
1141 dev_err(ddata->dev, "failed to register power supply\n");
1142 return error;
1143 }
1144
1145 atomic_set(v: &ddata->active, i: 1);
1146
1147 error = cpcap_battery_calibrate(ddata);
1148 if (error)
1149 return error;
1150
1151 return 0;
1152}
1153
1154static void 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(v: &ddata->active, i: 0);
1160 error = regmap_update_bits(map: ddata->reg, CPCAP_REG_BPEOL,
1161 mask: 0xffff, val: 0);
1162 if (error)
1163 dev_err(&pdev->dev, "could not disable: %i\n", error);
1164}
1165
1166static struct platform_driver cpcap_battery_driver = {
1167 .driver = {
1168 .name = "cpcap_battery",
1169 .of_match_table = of_match_ptr(cpcap_battery_id_table),
1170 },
1171 .probe = cpcap_battery_probe,
1172 .remove_new = cpcap_battery_remove,
1173};
1174module_platform_driver(cpcap_battery_driver);
1175
1176MODULE_LICENSE("GPL v2");
1177MODULE_AUTHOR("Tony Lindgren <tony@atomide.com>");
1178MODULE_DESCRIPTION("CPCAP PMIC Battery Driver");
1179

source code of linux/drivers/power/supply/cpcap-battery.c