hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/power/supply/bq27xxx_battery.c
....@@ -1,48 +1,44 @@
1
+// SPDX-License-Identifier: GPL-2.0
12 /*
23 * BQ27xxx battery driver
34 *
45 * Copyright (C) 2008 Rodolfo Giometti <giometti@linux.it>
56 * Copyright (C) 2008 Eurotech S.p.A. <info@eurotech.it>
67 * Copyright (C) 2010-2011 Lars-Peter Clausen <lars@metafoo.de>
7
- * Copyright (C) 2011 Pali Rohár <pali.rohar@gmail.com>
8
+ * Copyright (C) 2011 Pali Rohár <pali@kernel.org>
89 * Copyright (C) 2017 Liam Breck <kernel@networkimprov.net>
910 *
1011 * Based on a previous work by Copyright (C) 2008 Texas Instruments, Inc.
1112 *
12
- * This package is free software; you can redistribute it and/or modify
13
- * it under the terms of the GNU General Public License version 2 as
14
- * published by the Free Software Foundation.
15
- *
16
- * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19
- *
2013 * Datasheets:
21
- * http://www.ti.com/product/bq27000
22
- * http://www.ti.com/product/bq27200
23
- * http://www.ti.com/product/bq27010
24
- * http://www.ti.com/product/bq27210
25
- * http://www.ti.com/product/bq27500
26
- * http://www.ti.com/product/bq27510-g1
27
- * http://www.ti.com/product/bq27510-g2
28
- * http://www.ti.com/product/bq27510-g3
29
- * http://www.ti.com/product/bq27520-g1
30
- * http://www.ti.com/product/bq27520-g2
31
- * http://www.ti.com/product/bq27520-g3
32
- * http://www.ti.com/product/bq27520-g4
33
- * http://www.ti.com/product/bq27530-g1
34
- * http://www.ti.com/product/bq27531-g1
35
- * http://www.ti.com/product/bq27541-g1
36
- * http://www.ti.com/product/bq27542-g1
37
- * http://www.ti.com/product/bq27546-g1
38
- * http://www.ti.com/product/bq27742-g1
39
- * http://www.ti.com/product/bq27545-g1
40
- * http://www.ti.com/product/bq27421-g1
41
- * http://www.ti.com/product/bq27425-g1
42
- * http://www.ti.com/product/bq27426
43
- * http://www.ti.com/product/bq27411-g1
44
- * http://www.ti.com/product/bq27441-g1
45
- * http://www.ti.com/product/bq27621-g1
14
+ * https://www.ti.com/product/bq27000
15
+ * https://www.ti.com/product/bq27200
16
+ * https://www.ti.com/product/bq27010
17
+ * https://www.ti.com/product/bq27210
18
+ * https://www.ti.com/product/bq27500
19
+ * https://www.ti.com/product/bq27510-g1
20
+ * https://www.ti.com/product/bq27510-g2
21
+ * https://www.ti.com/product/bq27510-g3
22
+ * https://www.ti.com/product/bq27520-g1
23
+ * https://www.ti.com/product/bq27520-g2
24
+ * https://www.ti.com/product/bq27520-g3
25
+ * https://www.ti.com/product/bq27520-g4
26
+ * https://www.ti.com/product/bq27530-g1
27
+ * https://www.ti.com/product/bq27531-g1
28
+ * https://www.ti.com/product/bq27541-g1
29
+ * https://www.ti.com/product/bq27542-g1
30
+ * https://www.ti.com/product/bq27546-g1
31
+ * https://www.ti.com/product/bq27742-g1
32
+ * https://www.ti.com/product/bq27545-g1
33
+ * https://www.ti.com/product/bq27421-g1
34
+ * https://www.ti.com/product/bq27425-g1
35
+ * https://www.ti.com/product/bq27426
36
+ * https://www.ti.com/product/bq27411-g1
37
+ * https://www.ti.com/product/bq27441-g1
38
+ * https://www.ti.com/product/bq27621-g1
39
+ * https://www.ti.com/product/bq27z561
40
+ * https://www.ti.com/product/bq28z610
41
+ * https://www.ti.com/product/bq34z100-g1
4642 */
4743
4844 #include <linux/device.h>
....@@ -78,6 +74,11 @@
7874 #define BQ27000_FLAG_CI BIT(4) /* Capacity Inaccurate flag */
7975 #define BQ27000_FLAG_FC BIT(5)
8076 #define BQ27000_FLAG_CHGS BIT(7) /* Charge state flag */
77
+
78
+/* BQ27Z561 has different layout for Flags register */
79
+#define BQ27Z561_FLAG_FDC BIT(4) /* Battery fully discharged */
80
+#define BQ27Z561_FLAG_FC BIT(5) /* Battery fully charged */
81
+#define BQ27Z561_FLAG_DIS_CH BIT(6) /* Battery is discharging */
8182
8283 /* control register params */
8384 #define BQ27XXX_SEALED 0x20
....@@ -431,11 +432,72 @@
431432 [BQ27XXX_REG_DCAP] = 0x3c,
432433 [BQ27XXX_REG_AP] = 0x18,
433434 BQ27XXX_DM_REG_ROWS,
434
- };
435
+ },
436
+#define bq27411_regs bq27421_regs
435437 #define bq27425_regs bq27421_regs
436438 #define bq27426_regs bq27421_regs
437439 #define bq27441_regs bq27421_regs
438440 #define bq27621_regs bq27421_regs
441
+ bq27z561_regs[BQ27XXX_REG_MAX] = {
442
+ [BQ27XXX_REG_CTRL] = 0x00,
443
+ [BQ27XXX_REG_TEMP] = 0x06,
444
+ [BQ27XXX_REG_INT_TEMP] = INVALID_REG_ADDR,
445
+ [BQ27XXX_REG_VOLT] = 0x08,
446
+ [BQ27XXX_REG_AI] = 0x14,
447
+ [BQ27XXX_REG_FLAGS] = 0x0a,
448
+ [BQ27XXX_REG_TTE] = 0x16,
449
+ [BQ27XXX_REG_TTF] = 0x18,
450
+ [BQ27XXX_REG_TTES] = INVALID_REG_ADDR,
451
+ [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,
452
+ [BQ27XXX_REG_NAC] = INVALID_REG_ADDR,
453
+ [BQ27XXX_REG_FCC] = 0x12,
454
+ [BQ27XXX_REG_CYCT] = 0x2a,
455
+ [BQ27XXX_REG_AE] = 0x22,
456
+ [BQ27XXX_REG_SOC] = 0x2c,
457
+ [BQ27XXX_REG_DCAP] = 0x3c,
458
+ [BQ27XXX_REG_AP] = 0x22,
459
+ BQ27XXX_DM_REG_ROWS,
460
+ },
461
+ bq28z610_regs[BQ27XXX_REG_MAX] = {
462
+ [BQ27XXX_REG_CTRL] = 0x00,
463
+ [BQ27XXX_REG_TEMP] = 0x06,
464
+ [BQ27XXX_REG_INT_TEMP] = INVALID_REG_ADDR,
465
+ [BQ27XXX_REG_VOLT] = 0x08,
466
+ [BQ27XXX_REG_AI] = 0x14,
467
+ [BQ27XXX_REG_FLAGS] = 0x0a,
468
+ [BQ27XXX_REG_TTE] = 0x16,
469
+ [BQ27XXX_REG_TTF] = 0x18,
470
+ [BQ27XXX_REG_TTES] = INVALID_REG_ADDR,
471
+ [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,
472
+ [BQ27XXX_REG_NAC] = INVALID_REG_ADDR,
473
+ [BQ27XXX_REG_FCC] = 0x12,
474
+ [BQ27XXX_REG_CYCT] = 0x2a,
475
+ [BQ27XXX_REG_AE] = 0x22,
476
+ [BQ27XXX_REG_SOC] = 0x2c,
477
+ [BQ27XXX_REG_DCAP] = 0x3c,
478
+ [BQ27XXX_REG_AP] = 0x22,
479
+ BQ27XXX_DM_REG_ROWS,
480
+ },
481
+ bq34z100_regs[BQ27XXX_REG_MAX] = {
482
+ [BQ27XXX_REG_CTRL] = 0x00,
483
+ [BQ27XXX_REG_TEMP] = 0x0c,
484
+ [BQ27XXX_REG_INT_TEMP] = 0x2a,
485
+ [BQ27XXX_REG_VOLT] = 0x08,
486
+ [BQ27XXX_REG_AI] = 0x0a,
487
+ [BQ27XXX_REG_FLAGS] = 0x0e,
488
+ [BQ27XXX_REG_TTE] = 0x18,
489
+ [BQ27XXX_REG_TTF] = 0x1a,
490
+ [BQ27XXX_REG_TTES] = 0x1e,
491
+ [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,
492
+ [BQ27XXX_REG_NAC] = INVALID_REG_ADDR,
493
+ [BQ27XXX_REG_FCC] = 0x06,
494
+ [BQ27XXX_REG_CYCT] = 0x2c,
495
+ [BQ27XXX_REG_AE] = 0x24,
496
+ [BQ27XXX_REG_SOC] = 0x02,
497
+ [BQ27XXX_REG_DCAP] = 0x3c,
498
+ [BQ27XXX_REG_AP] = 0x22,
499
+ BQ27XXX_DM_REG_ROWS,
500
+ };
439501
440502 static enum power_supply_property bq27000_props[] = {
441503 POWER_SUPPLY_PROP_STATUS,
....@@ -665,10 +727,70 @@
665727 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
666728 POWER_SUPPLY_PROP_MANUFACTURER,
667729 };
730
+#define bq27411_props bq27421_props
668731 #define bq27425_props bq27421_props
669732 #define bq27426_props bq27421_props
670733 #define bq27441_props bq27421_props
671734 #define bq27621_props bq27421_props
735
+
736
+static enum power_supply_property bq27z561_props[] = {
737
+ POWER_SUPPLY_PROP_STATUS,
738
+ POWER_SUPPLY_PROP_PRESENT,
739
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
740
+ POWER_SUPPLY_PROP_CURRENT_NOW,
741
+ POWER_SUPPLY_PROP_CAPACITY,
742
+ POWER_SUPPLY_PROP_CAPACITY_LEVEL,
743
+ POWER_SUPPLY_PROP_TEMP,
744
+ POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
745
+ POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
746
+ POWER_SUPPLY_PROP_TECHNOLOGY,
747
+ POWER_SUPPLY_PROP_CHARGE_FULL,
748
+ POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
749
+ POWER_SUPPLY_PROP_CYCLE_COUNT,
750
+ POWER_SUPPLY_PROP_POWER_AVG,
751
+ POWER_SUPPLY_PROP_HEALTH,
752
+ POWER_SUPPLY_PROP_MANUFACTURER,
753
+};
754
+
755
+static enum power_supply_property bq28z610_props[] = {
756
+ POWER_SUPPLY_PROP_STATUS,
757
+ POWER_SUPPLY_PROP_PRESENT,
758
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
759
+ POWER_SUPPLY_PROP_CURRENT_NOW,
760
+ POWER_SUPPLY_PROP_CAPACITY,
761
+ POWER_SUPPLY_PROP_CAPACITY_LEVEL,
762
+ POWER_SUPPLY_PROP_TEMP,
763
+ POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
764
+ POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
765
+ POWER_SUPPLY_PROP_TECHNOLOGY,
766
+ POWER_SUPPLY_PROP_CHARGE_FULL,
767
+ POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
768
+ POWER_SUPPLY_PROP_CYCLE_COUNT,
769
+ POWER_SUPPLY_PROP_POWER_AVG,
770
+ POWER_SUPPLY_PROP_HEALTH,
771
+ POWER_SUPPLY_PROP_MANUFACTURER,
772
+};
773
+
774
+static enum power_supply_property bq34z100_props[] = {
775
+ POWER_SUPPLY_PROP_STATUS,
776
+ POWER_SUPPLY_PROP_PRESENT,
777
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
778
+ POWER_SUPPLY_PROP_CURRENT_NOW,
779
+ POWER_SUPPLY_PROP_CAPACITY,
780
+ POWER_SUPPLY_PROP_CAPACITY_LEVEL,
781
+ POWER_SUPPLY_PROP_TEMP,
782
+ POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
783
+ POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
784
+ POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
785
+ POWER_SUPPLY_PROP_TECHNOLOGY,
786
+ POWER_SUPPLY_PROP_CHARGE_FULL,
787
+ POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
788
+ POWER_SUPPLY_PROP_CYCLE_COUNT,
789
+ POWER_SUPPLY_PROP_ENERGY_NOW,
790
+ POWER_SUPPLY_PROP_POWER_AVG,
791
+ POWER_SUPPLY_PROP_HEALTH,
792
+ POWER_SUPPLY_PROP_MANUFACTURER,
793
+};
672794
673795 struct bq27xxx_dm_reg {
674796 u8 subclass_id;
....@@ -725,6 +847,12 @@
725847 #define bq27545_dm_regs 0
726848 #endif
727849
850
+static struct bq27xxx_dm_reg bq27411_dm_regs[] = {
851
+ [BQ27XXX_DM_DESIGN_CAPACITY] = { 82, 10, 2, 0, 32767 },
852
+ [BQ27XXX_DM_DESIGN_ENERGY] = { 82, 12, 2, 0, 32767 },
853
+ [BQ27XXX_DM_TERMINATE_VOLTAGE] = { 82, 16, 2, 2800, 3700 },
854
+};
855
+
728856 static struct bq27xxx_dm_reg bq27421_dm_regs[] = {
729857 [BQ27XXX_DM_DESIGN_CAPACITY] = { 82, 10, 2, 0, 8000 },
730858 [BQ27XXX_DM_DESIGN_ENERGY] = { 82, 12, 2, 0, 32767 },
....@@ -759,11 +887,19 @@
759887 #define bq27621_dm_regs 0
760888 #endif
761889
762
-#define BQ27XXX_O_ZERO 0x00000001
763
-#define BQ27XXX_O_OTDC 0x00000002 /* has OTC/OTD overtemperature flags */
764
-#define BQ27XXX_O_UTOT 0x00000004 /* has OT overtemperature flag */
765
-#define BQ27XXX_O_CFGUP 0x00000008
766
-#define BQ27XXX_O_RAM 0x00000010
890
+#define bq27z561_dm_regs 0
891
+#define bq28z610_dm_regs 0
892
+#define bq34z100_dm_regs 0
893
+
894
+#define BQ27XXX_O_ZERO BIT(0)
895
+#define BQ27XXX_O_OTDC BIT(1) /* has OTC/OTD overtemperature flags */
896
+#define BQ27XXX_O_UTOT BIT(2) /* has OT overtemperature flag */
897
+#define BQ27XXX_O_CFGUP BIT(3)
898
+#define BQ27XXX_O_RAM BIT(4)
899
+#define BQ27Z561_O_BITS BIT(5)
900
+#define BQ27XXX_O_SOC_SI BIT(6) /* SoC is single register */
901
+#define BQ27XXX_O_HAS_CI BIT(7) /* has Capacity Inaccurate flag */
902
+#define BQ27XXX_O_MUL_CHEM BIT(8) /* multiple chemistries supported */
767903
768904 #define BQ27XXX_DATA(ref, key, opt) { \
769905 .opts = (opt), \
....@@ -781,8 +917,8 @@
781917 enum power_supply_property *props;
782918 size_t props_size;
783919 } bq27xxx_chip_data[] = {
784
- [BQ27000] = BQ27XXX_DATA(bq27000, 0 , BQ27XXX_O_ZERO),
785
- [BQ27010] = BQ27XXX_DATA(bq27010, 0 , BQ27XXX_O_ZERO),
920
+ [BQ27000] = BQ27XXX_DATA(bq27000, 0 , BQ27XXX_O_ZERO | BQ27XXX_O_SOC_SI | BQ27XXX_O_HAS_CI),
921
+ [BQ27010] = BQ27XXX_DATA(bq27010, 0 , BQ27XXX_O_ZERO | BQ27XXX_O_SOC_SI | BQ27XXX_O_HAS_CI),
786922 [BQ2750X] = BQ27XXX_DATA(bq2750x, 0 , BQ27XXX_O_OTDC),
787923 [BQ2751X] = BQ27XXX_DATA(bq2751x, 0 , BQ27XXX_O_OTDC),
788924 [BQ2752X] = BQ27XXX_DATA(bq2752x, 0 , BQ27XXX_O_OTDC),
....@@ -802,11 +938,16 @@
802938 [BQ27546] = BQ27XXX_DATA(bq27546, 0 , BQ27XXX_O_OTDC),
803939 [BQ27742] = BQ27XXX_DATA(bq27742, 0 , BQ27XXX_O_OTDC),
804940 [BQ27545] = BQ27XXX_DATA(bq27545, 0x04143672, BQ27XXX_O_OTDC),
941
+ [BQ27411] = BQ27XXX_DATA(bq27411, 0x80008000, BQ27XXX_O_UTOT | BQ27XXX_O_CFGUP | BQ27XXX_O_RAM),
805942 [BQ27421] = BQ27XXX_DATA(bq27421, 0x80008000, BQ27XXX_O_UTOT | BQ27XXX_O_CFGUP | BQ27XXX_O_RAM),
806943 [BQ27425] = BQ27XXX_DATA(bq27425, 0x04143672, BQ27XXX_O_UTOT | BQ27XXX_O_CFGUP),
807944 [BQ27426] = BQ27XXX_DATA(bq27426, 0x80008000, BQ27XXX_O_UTOT | BQ27XXX_O_CFGUP | BQ27XXX_O_RAM),
808945 [BQ27441] = BQ27XXX_DATA(bq27441, 0x80008000, BQ27XXX_O_UTOT | BQ27XXX_O_CFGUP | BQ27XXX_O_RAM),
809946 [BQ27621] = BQ27XXX_DATA(bq27621, 0x80008000, BQ27XXX_O_UTOT | BQ27XXX_O_CFGUP | BQ27XXX_O_RAM),
947
+ [BQ27Z561] = BQ27XXX_DATA(bq27z561, 0 , BQ27Z561_O_BITS),
948
+ [BQ28Z610] = BQ27XXX_DATA(bq28z610, 0 , BQ27Z561_O_BITS),
949
+ [BQ34Z100] = BQ27XXX_DATA(bq34z100, 0 , BQ27XXX_O_OTDC | BQ27XXX_O_SOC_SI | \
950
+ BQ27XXX_O_HAS_CI | BQ27XXX_O_MUL_CHEM),
810951 };
811952
812953 static DEFINE_MUTEX(bq27xxx_list_lock);
....@@ -877,10 +1018,8 @@
8771018 return ret;
8781019
8791020 mutex_lock(&bq27xxx_list_lock);
880
- list_for_each_entry(di, &bq27xxx_battery_devices, list) {
881
- cancel_delayed_work_sync(&di->work);
882
- schedule_delayed_work(&di->work, 0);
883
- }
1021
+ list_for_each_entry(di, &bq27xxx_battery_devices, list)
1022
+ mod_delayed_work(system_wq, &di->work, 0);
8841023 mutex_unlock(&bq27xxx_list_lock);
8851024
8861025 return ret;
....@@ -1326,7 +1465,7 @@
13261465 {
13271466 int soc;
13281467
1329
- if (di->opts & BQ27XXX_O_ZERO)
1468
+ if (di->opts & BQ27XXX_O_SOC_SI)
13301469 soc = bq27xxx_read(di, BQ27XXX_REG_SOC, true);
13311470 else
13321471 soc = bq27xxx_read(di, BQ27XXX_REG_SOC, false);
....@@ -1366,14 +1505,6 @@
13661505 */
13671506 static inline int bq27xxx_battery_read_nac(struct bq27xxx_device_info *di)
13681507 {
1369
- int flags;
1370
-
1371
- if (di->opts & BQ27XXX_O_ZERO) {
1372
- flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, true);
1373
- if (flags >= 0 && (flags & BQ27000_FLAG_CI))
1374
- return -ENODATA;
1375
- }
1376
-
13771508 return bq27xxx_battery_read_charge(di, BQ27XXX_REG_NAC);
13781509 }
13791510
....@@ -1521,40 +1652,116 @@
15211652 {
15221653 if (di->opts & BQ27XXX_O_ZERO)
15231654 return flags & (BQ27000_FLAG_EDV1 | BQ27000_FLAG_EDVF);
1655
+ else if (di->opts & BQ27Z561_O_BITS)
1656
+ return flags & BQ27Z561_FLAG_FDC;
15241657 else
15251658 return flags & (BQ27XXX_FLAG_SOC1 | BQ27XXX_FLAG_SOCF);
15261659 }
15271660
15281661 /*
1529
- * Read flag register.
1530
- * Return < 0 if something fails.
1662
+ * Returns true if reported battery capacity is inaccurate
15311663 */
1664
+static bool bq27xxx_battery_capacity_inaccurate(struct bq27xxx_device_info *di,
1665
+ u16 flags)
1666
+{
1667
+ if (di->opts & BQ27XXX_O_HAS_CI)
1668
+ return (flags & BQ27000_FLAG_CI);
1669
+ else
1670
+ return false;
1671
+}
1672
+
15321673 static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di)
15331674 {
1534
- int flags;
1535
- bool has_singe_flag = di->opts & BQ27XXX_O_ZERO;
1536
-
1537
- flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, has_singe_flag);
1538
- if (flags < 0) {
1539
- dev_err(di->dev, "error reading flag register:%d\n", flags);
1540
- return flags;
1541
- }
1542
-
15431675 /* Unlikely but important to return first */
1544
- if (unlikely(bq27xxx_battery_overtemp(di, flags)))
1676
+ if (unlikely(bq27xxx_battery_overtemp(di, di->cache.flags)))
15451677 return POWER_SUPPLY_HEALTH_OVERHEAT;
1546
- if (unlikely(bq27xxx_battery_undertemp(di, flags)))
1678
+ if (unlikely(bq27xxx_battery_undertemp(di, di->cache.flags)))
15471679 return POWER_SUPPLY_HEALTH_COLD;
1548
- if (unlikely(bq27xxx_battery_dead(di, flags)))
1680
+ if (unlikely(bq27xxx_battery_dead(di, di->cache.flags)))
15491681 return POWER_SUPPLY_HEALTH_DEAD;
1682
+ if (unlikely(bq27xxx_battery_capacity_inaccurate(di, di->cache.flags)))
1683
+ return POWER_SUPPLY_HEALTH_CALIBRATION_REQUIRED;
15501684
15511685 return POWER_SUPPLY_HEALTH_GOOD;
15521686 }
15531687
1554
-void bq27xxx_battery_update(struct bq27xxx_device_info *di)
1688
+static bool bq27xxx_battery_is_full(struct bq27xxx_device_info *di, int flags)
15551689 {
1690
+ if (di->opts & BQ27XXX_O_ZERO)
1691
+ return (flags & BQ27000_FLAG_FC);
1692
+ else if (di->opts & BQ27Z561_O_BITS)
1693
+ return (flags & BQ27Z561_FLAG_FC);
1694
+ else
1695
+ return (flags & BQ27XXX_FLAG_FC);
1696
+}
1697
+
1698
+/*
1699
+ * Return the battery average current in µA and the status
1700
+ * Note that current can be negative signed as well
1701
+ * Or 0 if something fails.
1702
+ */
1703
+static int bq27xxx_battery_current_and_status(
1704
+ struct bq27xxx_device_info *di,
1705
+ union power_supply_propval *val_curr,
1706
+ union power_supply_propval *val_status,
1707
+ struct bq27xxx_reg_cache *cache)
1708
+{
1709
+ bool single_flags = (di->opts & BQ27XXX_O_ZERO);
1710
+ int curr;
1711
+ int flags;
1712
+
1713
+ curr = bq27xxx_read(di, BQ27XXX_REG_AI, false);
1714
+ if (curr < 0) {
1715
+ dev_err(di->dev, "error reading current\n");
1716
+ return curr;
1717
+ }
1718
+
1719
+ if (cache) {
1720
+ flags = cache->flags;
1721
+ } else {
1722
+ flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, single_flags);
1723
+ if (flags < 0) {
1724
+ dev_err(di->dev, "error reading flags\n");
1725
+ return flags;
1726
+ }
1727
+ }
1728
+
1729
+ if (di->opts & BQ27XXX_O_ZERO) {
1730
+ if (!(flags & BQ27000_FLAG_CHGS)) {
1731
+ dev_dbg(di->dev, "negative current!\n");
1732
+ curr = -curr;
1733
+ }
1734
+
1735
+ curr = curr * BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS;
1736
+ } else {
1737
+ /* Other gauges return signed value */
1738
+ curr = (int)((s16)curr) * 1000;
1739
+ }
1740
+
1741
+ if (val_curr)
1742
+ val_curr->intval = curr;
1743
+
1744
+ if (val_status) {
1745
+ if (curr > 0) {
1746
+ val_status->intval = POWER_SUPPLY_STATUS_CHARGING;
1747
+ } else if (curr < 0) {
1748
+ val_status->intval = POWER_SUPPLY_STATUS_DISCHARGING;
1749
+ } else {
1750
+ if (bq27xxx_battery_is_full(di, flags))
1751
+ val_status->intval = POWER_SUPPLY_STATUS_FULL;
1752
+ else
1753
+ val_status->intval =
1754
+ POWER_SUPPLY_STATUS_NOT_CHARGING;
1755
+ }
1756
+ }
1757
+
1758
+ return 0;
1759
+}
1760
+
1761
+static void bq27xxx_battery_update_unlocked(struct bq27xxx_device_info *di)
1762
+{
1763
+ union power_supply_propval status = di->last_status;
15561764 struct bq27xxx_reg_cache cache = {0, };
1557
- bool has_ci_flag = di->opts & BQ27XXX_O_ZERO;
15581765 bool has_singe_flag = di->opts & BQ27XXX_O_ZERO;
15591766
15601767 cache.flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, has_singe_flag);
....@@ -1562,43 +1769,55 @@
15621769 cache.flags = -1; /* read error */
15631770 if (cache.flags >= 0) {
15641771 cache.temperature = bq27xxx_battery_read_temperature(di);
1565
- if (has_ci_flag && (cache.flags & BQ27000_FLAG_CI)) {
1566
- dev_info_once(di->dev, "battery is not calibrated! ignoring capacity values\n");
1567
- cache.capacity = -ENODATA;
1568
- cache.energy = -ENODATA;
1569
- cache.time_to_empty = -ENODATA;
1570
- cache.time_to_empty_avg = -ENODATA;
1571
- cache.time_to_full = -ENODATA;
1572
- cache.charge_full = -ENODATA;
1573
- cache.health = -ENODATA;
1574
- } else {
1575
- if (di->regs[BQ27XXX_REG_TTE] != INVALID_REG_ADDR)
1576
- cache.time_to_empty = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTE);
1577
- if (di->regs[BQ27XXX_REG_TTECP] != INVALID_REG_ADDR)
1578
- cache.time_to_empty_avg = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTECP);
1579
- if (di->regs[BQ27XXX_REG_TTF] != INVALID_REG_ADDR)
1580
- cache.time_to_full = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTF);
1581
- cache.charge_full = bq27xxx_battery_read_fcc(di);
1582
- cache.capacity = bq27xxx_battery_read_soc(di);
1583
- if (di->regs[BQ27XXX_REG_AE] != INVALID_REG_ADDR)
1584
- cache.energy = bq27xxx_battery_read_energy(di);
1585
- cache.health = bq27xxx_battery_read_health(di);
1586
- }
1772
+ if (di->regs[BQ27XXX_REG_TTE] != INVALID_REG_ADDR)
1773
+ cache.time_to_empty = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTE);
1774
+ if (di->regs[BQ27XXX_REG_TTECP] != INVALID_REG_ADDR)
1775
+ cache.time_to_empty_avg = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTECP);
1776
+ if (di->regs[BQ27XXX_REG_TTF] != INVALID_REG_ADDR)
1777
+ cache.time_to_full = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTF);
1778
+
1779
+ cache.charge_full = bq27xxx_battery_read_fcc(di);
1780
+ cache.capacity = bq27xxx_battery_read_soc(di);
1781
+ if (di->regs[BQ27XXX_REG_AE] != INVALID_REG_ADDR)
1782
+ cache.energy = bq27xxx_battery_read_energy(di);
1783
+ di->cache.flags = cache.flags;
1784
+ cache.health = bq27xxx_battery_read_health(di);
15871785 if (di->regs[BQ27XXX_REG_CYCT] != INVALID_REG_ADDR)
15881786 cache.cycle_count = bq27xxx_battery_read_cyct(di);
1787
+
1788
+ /*
1789
+ * On gauges with signed current reporting the current must be
1790
+ * checked to detect charging <-> discharging status changes.
1791
+ */
1792
+ if (!(di->opts & BQ27XXX_O_ZERO))
1793
+ bq27xxx_battery_current_and_status(di, NULL, &status, &cache);
15891794
15901795 /* We only have to read charge design full once */
15911796 if (di->charge_design_full <= 0)
15921797 di->charge_design_full = bq27xxx_battery_read_dcap(di);
15931798 }
15941799
1595
- if (di->cache.capacity != cache.capacity)
1800
+ if ((di->cache.capacity != cache.capacity) ||
1801
+ (di->cache.flags != cache.flags) ||
1802
+ (di->last_status.intval != status.intval)) {
1803
+ di->last_status.intval = status.intval;
15961804 power_supply_changed(di->bat);
1805
+ }
15971806
15981807 if (memcmp(&di->cache, &cache, sizeof(cache)) != 0)
15991808 di->cache = cache;
16001809
16011810 di->last_update = jiffies;
1811
+
1812
+ if (!di->removed && poll_interval > 0)
1813
+ mod_delayed_work(system_wq, &di->work, poll_interval * HZ);
1814
+}
1815
+
1816
+void bq27xxx_battery_update(struct bq27xxx_device_info *di)
1817
+{
1818
+ mutex_lock(&di->lock);
1819
+ bq27xxx_battery_update_unlocked(di);
1820
+ mutex_unlock(&di->lock);
16021821 }
16031822 EXPORT_SYMBOL_GPL(bq27xxx_battery_update);
16041823
....@@ -1609,42 +1828,6 @@
16091828 work.work);
16101829
16111830 bq27xxx_battery_update(di);
1612
-
1613
- if (poll_interval > 0)
1614
- schedule_delayed_work(&di->work, poll_interval * HZ);
1615
-}
1616
-
1617
-/*
1618
- * Return the battery average current in µA
1619
- * Note that current can be negative signed as well
1620
- * Or 0 if something fails.
1621
- */
1622
-static int bq27xxx_battery_current(struct bq27xxx_device_info *di,
1623
- union power_supply_propval *val)
1624
-{
1625
- int curr;
1626
- int flags;
1627
-
1628
- curr = bq27xxx_read(di, BQ27XXX_REG_AI, false);
1629
- if (curr < 0) {
1630
- dev_err(di->dev, "error reading current\n");
1631
- return curr;
1632
- }
1633
-
1634
- if (di->opts & BQ27XXX_O_ZERO) {
1635
- flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, true);
1636
- if (flags & BQ27000_FLAG_CHGS) {
1637
- dev_dbg(di->dev, "negative current!\n");
1638
- curr = -curr;
1639
- }
1640
-
1641
- val->intval = curr * BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS;
1642
- } else {
1643
- /* Other gauges return signed value */
1644
- val->intval = (int)((s16)curr) * 1000;
1645
- }
1646
-
1647
- return 0;
16481831 }
16491832
16501833 /*
....@@ -1673,36 +1856,6 @@
16731856 return 0;
16741857 }
16751858
1676
-static int bq27xxx_battery_status(struct bq27xxx_device_info *di,
1677
- union power_supply_propval *val)
1678
-{
1679
- int status;
1680
-
1681
- if (di->opts & BQ27XXX_O_ZERO) {
1682
- if (di->cache.flags & BQ27000_FLAG_FC)
1683
- status = POWER_SUPPLY_STATUS_FULL;
1684
- else if (di->cache.flags & BQ27000_FLAG_CHGS)
1685
- status = POWER_SUPPLY_STATUS_CHARGING;
1686
- else
1687
- status = POWER_SUPPLY_STATUS_DISCHARGING;
1688
- } else {
1689
- if (di->cache.flags & BQ27XXX_FLAG_FC)
1690
- status = POWER_SUPPLY_STATUS_FULL;
1691
- else if (di->cache.flags & BQ27XXX_FLAG_DSC)
1692
- status = POWER_SUPPLY_STATUS_DISCHARGING;
1693
- else
1694
- status = POWER_SUPPLY_STATUS_CHARGING;
1695
- }
1696
-
1697
- if ((status == POWER_SUPPLY_STATUS_DISCHARGING) &&
1698
- (power_supply_am_i_supplied(di->bat) > 0))
1699
- status = POWER_SUPPLY_STATUS_NOT_CHARGING;
1700
-
1701
- val->intval = status;
1702
-
1703
- return 0;
1704
-}
1705
-
17061859 static int bq27xxx_battery_capacity_level(struct bq27xxx_device_info *di,
17071860 union power_supply_propval *val)
17081861 {
....@@ -1714,6 +1867,13 @@
17141867 else if (di->cache.flags & BQ27000_FLAG_EDV1)
17151868 level = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
17161869 else if (di->cache.flags & BQ27000_FLAG_EDVF)
1870
+ level = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
1871
+ else
1872
+ level = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
1873
+ } else if (di->opts & BQ27Z561_O_BITS) {
1874
+ if (di->cache.flags & BQ27Z561_FLAG_FC)
1875
+ level = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
1876
+ else if (di->cache.flags & BQ27Z561_FLAG_FDC)
17171877 level = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
17181878 else
17191879 level = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
....@@ -1772,10 +1932,8 @@
17721932 struct bq27xxx_device_info *di = power_supply_get_drvdata(psy);
17731933
17741934 mutex_lock(&di->lock);
1775
- if (time_is_before_jiffies(di->last_update + 5 * HZ)) {
1776
- cancel_delayed_work_sync(&di->work);
1777
- bq27xxx_battery_poll(&di->work.work);
1778
- }
1935
+ if (time_is_before_jiffies(di->last_update + 5 * HZ))
1936
+ bq27xxx_battery_update_unlocked(di);
17791937 mutex_unlock(&di->lock);
17801938
17811939 if (psp != POWER_SUPPLY_PROP_PRESENT && di->cache.flags < 0)
....@@ -1783,7 +1941,7 @@
17831941
17841942 switch (psp) {
17851943 case POWER_SUPPLY_PROP_STATUS:
1786
- ret = bq27xxx_battery_status(di, val);
1944
+ ret = bq27xxx_battery_current_and_status(di, NULL, val, NULL);
17871945 break;
17881946 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
17891947 ret = bq27xxx_battery_voltage(di, val);
....@@ -1792,7 +1950,7 @@
17921950 val->intval = di->cache.flags < 0 ? 0 : 1;
17931951 break;
17941952 case POWER_SUPPLY_PROP_CURRENT_NOW:
1795
- ret = bq27xxx_battery_current(di, val);
1953
+ ret = bq27xxx_battery_current_and_status(di, val, NULL, NULL);
17961954 break;
17971955 case POWER_SUPPLY_PROP_CAPACITY:
17981956 ret = bq27xxx_simple_value(di->cache.capacity, val);
....@@ -1815,7 +1973,10 @@
18151973 ret = bq27xxx_simple_value(di->cache.time_to_full, val);
18161974 break;
18171975 case POWER_SUPPLY_PROP_TECHNOLOGY:
1818
- val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
1976
+ if (di->opts & BQ27XXX_O_MUL_CHEM)
1977
+ val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
1978
+ else
1979
+ val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
18191980 break;
18201981 case POWER_SUPPLY_PROP_CHARGE_NOW:
18211982 ret = bq27xxx_simple_value(bq27xxx_battery_read_nac(di), val);
....@@ -1859,8 +2020,8 @@
18592020 {
18602021 struct bq27xxx_device_info *di = power_supply_get_drvdata(psy);
18612022
1862
- cancel_delayed_work_sync(&di->work);
1863
- schedule_delayed_work(&di->work, 0);
2023
+ /* After charger plug in/out wait 0.5s for things to stabilize */
2024
+ mod_delayed_work(system_wq, &di->work, HZ / 2);
18642025 }
18652026
18662027 int bq27xxx_battery_setup(struct bq27xxx_device_info *di)
....@@ -1891,13 +2052,9 @@
18912052 psy_desc->external_power_changed = bq27xxx_external_power_changed;
18922053
18932054 di->bat = power_supply_register_no_ws(di->dev, psy_desc, &psy_cfg);
1894
- if (IS_ERR(di->bat)) {
1895
- if (PTR_ERR(di->bat) == -EPROBE_DEFER)
1896
- dev_dbg(di->dev, "failed to register battery, deferring probe\n");
1897
- else
1898
- dev_err(di->dev, "failed to register battery\n");
1899
- return PTR_ERR(di->bat);
1900
- }
2055
+ if (IS_ERR(di->bat))
2056
+ return dev_err_probe(di->dev, PTR_ERR(di->bat),
2057
+ "failed to register battery\n");
19012058
19022059 bq27xxx_battery_settings(di);
19032060 bq27xxx_battery_update(di);
....@@ -1912,22 +2069,18 @@
19122069
19132070 void bq27xxx_battery_teardown(struct bq27xxx_device_info *di)
19142071 {
1915
- /*
1916
- * power_supply_unregister call bq27xxx_battery_get_property which
1917
- * call bq27xxx_battery_poll.
1918
- * Make sure that bq27xxx_battery_poll will not call
1919
- * schedule_delayed_work again after unregister (which cause OOPS).
1920
- */
1921
- poll_interval = 0;
1922
-
1923
- cancel_delayed_work_sync(&di->work);
1924
-
1925
- power_supply_unregister(di->bat);
1926
-
19272072 mutex_lock(&bq27xxx_list_lock);
19282073 list_del(&di->list);
19292074 mutex_unlock(&bq27xxx_list_lock);
19302075
2076
+ /* Set removed to avoid bq27xxx_battery_update() re-queuing the work */
2077
+ mutex_lock(&di->lock);
2078
+ di->removed = true;
2079
+ mutex_unlock(&di->lock);
2080
+
2081
+ cancel_delayed_work_sync(&di->work);
2082
+
2083
+ power_supply_unregister(di->bat);
19312084 mutex_destroy(&di->lock);
19322085 }
19332086 EXPORT_SYMBOL_GPL(bq27xxx_battery_teardown);