1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * DA9150 Fuel-Gauge Driver
5 * Copyright (c) 2015 Dialog Semiconductor
7 * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/platform_device.h>
14 #include <linux/of_platform.h>
15 #include <linux/slab.h>
16 #include <linux/interrupt.h>
17 #include <linux/delay.h>
18 #include <linux/power_supply.h>
19 #include <linux/list.h>
20 #include <asm/div64.h>
21 #include <linux/mfd/da9150/core.h>
22 #include <linux/mfd/da9150/registers.h>
25 #define DA9150_QIF_READ (0x0 << 7)
26 #define DA9150_QIF_WRITE (0x1 << 7)
27 #define DA9150_QIF_CODE_MASK 0x7F
29 #define DA9150_QIF_BYTE_SIZE 8
30 #define DA9150_QIF_BYTE_MASK 0xFF
31 #define DA9150_QIF_SHORT_SIZE 2
32 #define DA9150_QIF_LONG_SIZE 4
35 #define DA9150_QIF_UAVG 6
36 #define DA9150_QIF_UAVG_SIZE DA9150_QIF_LONG_SIZE
37 #define DA9150_QIF_IAVG 8
38 #define DA9150_QIF_IAVG_SIZE DA9150_QIF_LONG_SIZE
39 #define DA9150_QIF_NTCAVG 12
40 #define DA9150_QIF_NTCAVG_SIZE DA9150_QIF_LONG_SIZE
41 #define DA9150_QIF_SHUNT_VAL 36
42 #define DA9150_QIF_SHUNT_VAL_SIZE DA9150_QIF_SHORT_SIZE
43 #define DA9150_QIF_SD_GAIN 38
44 #define DA9150_QIF_SD_GAIN_SIZE DA9150_QIF_LONG_SIZE
45 #define DA9150_QIF_FCC_MAH 40
46 #define DA9150_QIF_FCC_MAH_SIZE DA9150_QIF_SHORT_SIZE
47 #define DA9150_QIF_SOC_PCT 43
48 #define DA9150_QIF_SOC_PCT_SIZE DA9150_QIF_SHORT_SIZE
49 #define DA9150_QIF_CHARGE_LIMIT 44
50 #define DA9150_QIF_CHARGE_LIMIT_SIZE DA9150_QIF_SHORT_SIZE
51 #define DA9150_QIF_DISCHARGE_LIMIT 45
52 #define DA9150_QIF_DISCHARGE_LIMIT_SIZE DA9150_QIF_SHORT_SIZE
53 #define DA9150_QIF_FW_MAIN_VER 118
54 #define DA9150_QIF_FW_MAIN_VER_SIZE DA9150_QIF_SHORT_SIZE
55 #define DA9150_QIF_E_FG_STATUS 126
56 #define DA9150_QIF_E_FG_STATUS_SIZE DA9150_QIF_SHORT_SIZE
57 #define DA9150_QIF_SYNC 127
58 #define DA9150_QIF_SYNC_SIZE DA9150_QIF_SHORT_SIZE
59 #define DA9150_QIF_MAX_CODES 128
61 /* QIF Sync Timeout */
62 #define DA9150_QIF_SYNC_TIMEOUT 1000
63 #define DA9150_QIF_SYNC_RETRIES 10
66 #define DA9150_FG_IRQ_LOW_SOC_MASK (1 << 0)
67 #define DA9150_FG_IRQ_HIGH_SOC_MASK (1 << 1)
68 #define DA9150_FG_IRQ_SOC_MASK \
69 (DA9150_FG_IRQ_LOW_SOC_MASK | DA9150_FG_IRQ_HIGH_SOC_MASK)
73 struct da9150
*da9150
;
78 struct power_supply
*battery
;
79 struct delayed_work work
;
87 /* Battery Properties */
88 static u32
da9150_fg_read_attr(struct da9150_fg
*fg
, u8 code
, u8 size
)
91 u8 buf
[DA9150_QIF_LONG_SIZE
];
96 /* Set QIF code (READ mode) */
97 read_addr
= (code
& DA9150_QIF_CODE_MASK
) | DA9150_QIF_READ
;
99 da9150_read_qif(fg
->da9150
, read_addr
, size
, buf
);
100 for (i
= 0; i
< size
; ++i
)
101 res
|= (buf
[i
] << (i
* DA9150_QIF_BYTE_SIZE
));
106 static void da9150_fg_write_attr(struct da9150_fg
*fg
, u8 code
, u8 size
,
110 u8 buf
[DA9150_QIF_LONG_SIZE
];
114 /* Set QIF code (WRITE mode) */
115 write_addr
= (code
& DA9150_QIF_CODE_MASK
) | DA9150_QIF_WRITE
;
117 for (i
= 0; i
< size
; ++i
) {
118 buf
[i
] = (val
>> (i
* DA9150_QIF_BYTE_SIZE
)) &
119 DA9150_QIF_BYTE_MASK
;
121 da9150_write_qif(fg
->da9150
, write_addr
, size
, buf
);
124 /* Trigger QIF Sync to update QIF readable data */
125 static void da9150_fg_read_sync_start(struct da9150_fg
*fg
)
130 mutex_lock(&fg
->io_lock
);
132 /* Check if QIF sync already requested, and write to sync if not */
133 res
= da9150_fg_read_attr(fg
, DA9150_QIF_SYNC
,
134 DA9150_QIF_SYNC_SIZE
);
136 da9150_fg_write_attr(fg
, DA9150_QIF_SYNC
,
137 DA9150_QIF_SYNC_SIZE
, 0);
139 /* Wait for sync to complete */
141 while ((res
== 0) && (i
++ < DA9150_QIF_SYNC_RETRIES
)) {
142 usleep_range(DA9150_QIF_SYNC_TIMEOUT
,
143 DA9150_QIF_SYNC_TIMEOUT
* 2);
144 res
= da9150_fg_read_attr(fg
, DA9150_QIF_SYNC
,
145 DA9150_QIF_SYNC_SIZE
);
148 /* Check if sync completed */
150 dev_err(fg
->dev
, "Failed to perform QIF read sync!\n");
154 * Should always be called after QIF sync read has been performed, and all
155 * attributes required have been accessed.
157 static inline void da9150_fg_read_sync_end(struct da9150_fg
*fg
)
159 mutex_unlock(&fg
->io_lock
);
162 /* Sync read of single QIF attribute */
163 static u32
da9150_fg_read_attr_sync(struct da9150_fg
*fg
, u8 code
, u8 size
)
167 da9150_fg_read_sync_start(fg
);
168 val
= da9150_fg_read_attr(fg
, code
, size
);
169 da9150_fg_read_sync_end(fg
);
174 /* Wait for QIF Sync, write QIF data and wait for ack */
175 static void da9150_fg_write_attr_sync(struct da9150_fg
*fg
, u8 code
, u8 size
,
179 u32 res
= 0, sync_val
;
181 mutex_lock(&fg
->io_lock
);
183 /* Check if QIF sync already requested */
184 res
= da9150_fg_read_attr(fg
, DA9150_QIF_SYNC
,
185 DA9150_QIF_SYNC_SIZE
);
187 /* Wait for an existing sync to complete */
188 while ((res
== 0) && (i
++ < DA9150_QIF_SYNC_RETRIES
)) {
189 usleep_range(DA9150_QIF_SYNC_TIMEOUT
,
190 DA9150_QIF_SYNC_TIMEOUT
* 2);
191 res
= da9150_fg_read_attr(fg
, DA9150_QIF_SYNC
,
192 DA9150_QIF_SYNC_SIZE
);
196 dev_err(fg
->dev
, "Timeout waiting for existing QIF sync!\n");
197 mutex_unlock(&fg
->io_lock
);
201 /* Write value for QIF code */
202 da9150_fg_write_attr(fg
, code
, size
, val
);
204 /* Wait for write acknowledgment */
207 while ((res
== sync_val
) && (i
++ < DA9150_QIF_SYNC_RETRIES
)) {
208 usleep_range(DA9150_QIF_SYNC_TIMEOUT
,
209 DA9150_QIF_SYNC_TIMEOUT
* 2);
210 res
= da9150_fg_read_attr(fg
, DA9150_QIF_SYNC
,
211 DA9150_QIF_SYNC_SIZE
);
214 mutex_unlock(&fg
->io_lock
);
216 /* Check write was actually successful */
217 if (res
!= (sync_val
+ 1))
218 dev_err(fg
->dev
, "Error performing QIF sync write for code %d\n",
222 /* Power Supply attributes */
223 static int da9150_fg_capacity(struct da9150_fg
*fg
,
224 union power_supply_propval
*val
)
226 val
->intval
= da9150_fg_read_attr_sync(fg
, DA9150_QIF_SOC_PCT
,
227 DA9150_QIF_SOC_PCT_SIZE
);
229 if (val
->intval
> 100)
235 static int da9150_fg_current_avg(struct da9150_fg
*fg
,
236 union power_supply_propval
*val
)
238 u32 iavg
, sd_gain
, shunt_val
;
241 da9150_fg_read_sync_start(fg
);
242 iavg
= da9150_fg_read_attr(fg
, DA9150_QIF_IAVG
,
243 DA9150_QIF_IAVG_SIZE
);
244 shunt_val
= da9150_fg_read_attr(fg
, DA9150_QIF_SHUNT_VAL
,
245 DA9150_QIF_SHUNT_VAL_SIZE
);
246 sd_gain
= da9150_fg_read_attr(fg
, DA9150_QIF_SD_GAIN
,
247 DA9150_QIF_SD_GAIN_SIZE
);
248 da9150_fg_read_sync_end(fg
);
250 div
= (u64
) (sd_gain
* shunt_val
* 65536ULL);
251 do_div(div
, 1000000);
252 res
= (u64
) (iavg
* 1000000ULL);
255 val
->intval
= (int) res
;
260 static int da9150_fg_voltage_avg(struct da9150_fg
*fg
,
261 union power_supply_propval
*val
)
265 val
->intval
= da9150_fg_read_attr_sync(fg
, DA9150_QIF_UAVG
,
266 DA9150_QIF_UAVG_SIZE
);
268 res
= (u64
) (val
->intval
* 186ULL);
270 val
->intval
= (int) res
;
275 static int da9150_fg_charge_full(struct da9150_fg
*fg
,
276 union power_supply_propval
*val
)
278 val
->intval
= da9150_fg_read_attr_sync(fg
, DA9150_QIF_FCC_MAH
,
279 DA9150_QIF_FCC_MAH_SIZE
);
281 val
->intval
= val
->intval
* 1000;
287 * Temperature reading from device is only valid if battery/system provides
288 * valid NTC to associated pin of DA9150 chip.
290 static int da9150_fg_temp(struct da9150_fg
*fg
,
291 union power_supply_propval
*val
)
293 val
->intval
= da9150_fg_read_attr_sync(fg
, DA9150_QIF_NTCAVG
,
294 DA9150_QIF_NTCAVG_SIZE
);
296 val
->intval
= (val
->intval
* 10) / 1048576;
301 static enum power_supply_property da9150_fg_props
[] = {
302 POWER_SUPPLY_PROP_CAPACITY
,
303 POWER_SUPPLY_PROP_CURRENT_AVG
,
304 POWER_SUPPLY_PROP_VOLTAGE_AVG
,
305 POWER_SUPPLY_PROP_CHARGE_FULL
,
306 POWER_SUPPLY_PROP_TEMP
,
309 static int da9150_fg_get_prop(struct power_supply
*psy
,
310 enum power_supply_property psp
,
311 union power_supply_propval
*val
)
313 struct da9150_fg
*fg
= dev_get_drvdata(psy
->dev
.parent
);
317 case POWER_SUPPLY_PROP_CAPACITY
:
318 ret
= da9150_fg_capacity(fg
, val
);
320 case POWER_SUPPLY_PROP_CURRENT_AVG
:
321 ret
= da9150_fg_current_avg(fg
, val
);
323 case POWER_SUPPLY_PROP_VOLTAGE_AVG
:
324 ret
= da9150_fg_voltage_avg(fg
, val
);
326 case POWER_SUPPLY_PROP_CHARGE_FULL
:
327 ret
= da9150_fg_charge_full(fg
, val
);
329 case POWER_SUPPLY_PROP_TEMP
:
330 ret
= da9150_fg_temp(fg
, val
);
340 /* Repeated SOC check */
341 static bool da9150_fg_soc_changed(struct da9150_fg
*fg
)
343 union power_supply_propval val
;
345 da9150_fg_capacity(fg
, &val
);
346 if (val
.intval
!= fg
->soc
) {
347 fg
->soc
= val
.intval
;
354 static void da9150_fg_work(struct work_struct
*work
)
356 struct da9150_fg
*fg
= container_of(work
, struct da9150_fg
, work
.work
);
358 /* Report if SOC has changed */
359 if (da9150_fg_soc_changed(fg
))
360 power_supply_changed(fg
->battery
);
362 schedule_delayed_work(&fg
->work
, msecs_to_jiffies(fg
->interval
));
365 /* SOC level event configuration */
366 static void da9150_fg_soc_event_config(struct da9150_fg
*fg
)
370 soc
= da9150_fg_read_attr_sync(fg
, DA9150_QIF_SOC_PCT
,
371 DA9150_QIF_SOC_PCT_SIZE
);
373 if (soc
> fg
->warn_soc
) {
374 /* If SOC > warn level, set discharge warn level event */
375 da9150_fg_write_attr_sync(fg
, DA9150_QIF_DISCHARGE_LIMIT
,
376 DA9150_QIF_DISCHARGE_LIMIT_SIZE
,
378 } else if ((soc
<= fg
->warn_soc
) && (soc
> fg
->crit_soc
)) {
380 * If SOC <= warn level, set discharge crit level event,
381 * and set charge warn level event.
383 da9150_fg_write_attr_sync(fg
, DA9150_QIF_DISCHARGE_LIMIT
,
384 DA9150_QIF_DISCHARGE_LIMIT_SIZE
,
387 da9150_fg_write_attr_sync(fg
, DA9150_QIF_CHARGE_LIMIT
,
388 DA9150_QIF_CHARGE_LIMIT_SIZE
,
390 } else if (soc
<= fg
->crit_soc
) {
391 /* If SOC <= crit level, set charge crit level event */
392 da9150_fg_write_attr_sync(fg
, DA9150_QIF_CHARGE_LIMIT
,
393 DA9150_QIF_CHARGE_LIMIT_SIZE
,
398 static irqreturn_t
da9150_fg_irq(int irq
, void *data
)
400 struct da9150_fg
*fg
= data
;
403 /* Read FG IRQ status info */
404 e_fg_status
= da9150_fg_read_attr(fg
, DA9150_QIF_E_FG_STATUS
,
405 DA9150_QIF_E_FG_STATUS_SIZE
);
407 /* Handle warning/critical threhold events */
408 if (e_fg_status
& DA9150_FG_IRQ_SOC_MASK
)
409 da9150_fg_soc_event_config(fg
);
411 /* Clear any FG IRQs */
412 da9150_fg_write_attr(fg
, DA9150_QIF_E_FG_STATUS
,
413 DA9150_QIF_E_FG_STATUS_SIZE
, e_fg_status
);
418 static struct da9150_fg_pdata
*da9150_fg_dt_pdata(struct device
*dev
)
420 struct device_node
*fg_node
= dev
->of_node
;
421 struct da9150_fg_pdata
*pdata
;
423 pdata
= devm_kzalloc(dev
, sizeof(struct da9150_fg_pdata
), GFP_KERNEL
);
427 of_property_read_u32(fg_node
, "dlg,update-interval",
428 &pdata
->update_interval
);
429 of_property_read_u8(fg_node
, "dlg,warn-soc-level",
430 &pdata
->warn_soc_lvl
);
431 of_property_read_u8(fg_node
, "dlg,crit-soc-level",
432 &pdata
->crit_soc_lvl
);
437 static const struct power_supply_desc fg_desc
= {
439 .type
= POWER_SUPPLY_TYPE_BATTERY
,
440 .properties
= da9150_fg_props
,
441 .num_properties
= ARRAY_SIZE(da9150_fg_props
),
442 .get_property
= da9150_fg_get_prop
,
445 static int da9150_fg_probe(struct platform_device
*pdev
)
447 struct device
*dev
= &pdev
->dev
;
448 struct da9150
*da9150
= dev_get_drvdata(dev
->parent
);
449 struct da9150_fg_pdata
*fg_pdata
= dev_get_platdata(dev
);
450 struct da9150_fg
*fg
;
451 int ver
, irq
, ret
= 0;
453 fg
= devm_kzalloc(dev
, sizeof(*fg
), GFP_KERNEL
);
457 platform_set_drvdata(pdev
, fg
);
461 mutex_init(&fg
->io_lock
);
464 da9150_set_bits(da9150
, DA9150_CORE2WIRE_CTRL_A
, DA9150_FG_QIF_EN_MASK
,
465 DA9150_FG_QIF_EN_MASK
);
467 fg
->battery
= devm_power_supply_register(dev
, &fg_desc
, NULL
);
468 if (IS_ERR(fg
->battery
)) {
469 ret
= PTR_ERR(fg
->battery
);
473 ver
= da9150_fg_read_attr(fg
, DA9150_QIF_FW_MAIN_VER
,
474 DA9150_QIF_FW_MAIN_VER_SIZE
);
475 dev_info(dev
, "Version: 0x%x\n", ver
);
477 /* Handle DT data if provided */
479 fg_pdata
= da9150_fg_dt_pdata(dev
);
480 dev
->platform_data
= fg_pdata
;
483 /* Handle any pdata provided */
485 fg
->interval
= fg_pdata
->update_interval
;
487 if (fg_pdata
->warn_soc_lvl
> 100)
488 dev_warn(dev
, "Invalid SOC warning level provided, Ignoring");
490 fg
->warn_soc
= fg_pdata
->warn_soc_lvl
;
492 if ((fg_pdata
->crit_soc_lvl
> 100) ||
493 (fg_pdata
->crit_soc_lvl
>= fg_pdata
->warn_soc_lvl
))
494 dev_warn(dev
, "Invalid SOC critical level provided, Ignoring");
496 fg
->crit_soc
= fg_pdata
->crit_soc_lvl
;
501 /* Configure initial SOC level events */
502 da9150_fg_soc_event_config(fg
);
505 * If an interval period has been provided then setup repeating
506 * work for reporting data updates.
509 INIT_DELAYED_WORK(&fg
->work
, da9150_fg_work
);
510 schedule_delayed_work(&fg
->work
,
511 msecs_to_jiffies(fg
->interval
));
515 irq
= platform_get_irq_byname(pdev
, "FG");
517 dev_err(dev
, "Failed to get IRQ FG: %d\n", irq
);
522 ret
= devm_request_threaded_irq(dev
, irq
, NULL
, da9150_fg_irq
,
523 IRQF_ONESHOT
, "FG", fg
);
525 dev_err(dev
, "Failed to request IRQ %d: %d\n", irq
, ret
);
533 cancel_delayed_work(&fg
->work
);
538 static int da9150_fg_remove(struct platform_device
*pdev
)
540 struct da9150_fg
*fg
= platform_get_drvdata(pdev
);
543 cancel_delayed_work(&fg
->work
);
548 static int da9150_fg_resume(struct platform_device
*pdev
)
550 struct da9150_fg
*fg
= platform_get_drvdata(pdev
);
553 * Trigger SOC check to happen now so as to indicate any value change
554 * since last check before suspend.
557 flush_delayed_work(&fg
->work
);
562 static struct platform_driver da9150_fg_driver
= {
564 .name
= "da9150-fuel-gauge",
566 .probe
= da9150_fg_probe
,
567 .remove
= da9150_fg_remove
,
568 .resume
= da9150_fg_resume
,
571 module_platform_driver(da9150_fg_driver
);
573 MODULE_DESCRIPTION("Fuel-Gauge Driver for DA9150");
574 MODULE_AUTHOR("Adam Thomson <Adam.Thomson.Opensource@diasemi.com>");
575 MODULE_LICENSE("GPL");