* [PATCH RFC 0/8] Qualcomm 3rd gen fuel gauge support
@ 2025-11-24 21:53 David Heidelberg via B4 Relay
2025-11-24 21:53 ` [PATCH RFC 1/8] dt-bindings: power: supply: Add schema for Qualcomm pmi8998 fuel gauge David Heidelberg via B4 Relay
` (8 more replies)
0 siblings, 9 replies; 24+ messages in thread
From: David Heidelberg via B4 Relay @ 2025-11-24 21:53 UTC (permalink / raw)
To: Sebastian Reichel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Casey Connolly, Casey Connolly, Joel Selvaraj, Yassine Oudjana,
Bjorn Andersson, Konrad Dybcio, Alexander Martinz,
Barnabás Czémán, Richard Acayan,
Alexey Minnekhanov
Cc: linux-pm, devicetree, linux-kernel, linux-arm-msm, phone-devel,
David Heidelberg
This FG (fuel gauge) can be found on Snapdragon 835, 845, 660, 670..
Series enables the FG, which is used on phones as OnePlus 6, 6T, Pixel 3a..
Since many downstream trees (sdm845-mainline, sdm660, sdm670) carring
these patches, after Barnabás dropped older gen support from the driver,
cleaned up the driver, I picked changes and cleaned up device-tree
patches and sending the whole bulk for review.
Note:
Usually I picked the oldest commits authors.
Since there was multiple patches, multiple names and modifications etc.,
if someone from the authors, co-developers, contributors etc. missing,
please let me know and I'll fix this up in the next series.
Currently some authors are unreachable or haven't given Signed-off-by
yet, thus RFC, when this get cleaned up, I'll sent non-RFC or leave it
to the authors to continue upstreaming process in case they want to.
Until merged (or taken over by the original authors), the series is
available at:
https://gitlab.com/sdm845/sdm845-next/-/commits/b4%2Fpmi8998_fuel_gauge
Signed-off-by: David Heidelberg <david@ixit.cz>
---
Changes in v1:
- Clean and read charge full and max voltage from dts. (Joel)
- Dont put battery info on remove. All the battery info data is devm
tracked so it will be freed for us on removal. (Casey)
- Invert charging current. Battery current should be negative for charging
batteries, invert it so it's correct. Fixes upower charging status
reporting. (Casey)
- Expose PROP_STATUS to fix upower not detecting charging status properly.
- Adopt battery info API changes.
- Silence -EPROBE_DEFER error. (Richard)
- Add present sysfs property. Required for battery drivers from
UPower>=1.90.0 onwards to work properly. (Alexander)
- Drop support for older gen from the driver. (Barnabás)
- Rename the driver to pmi8998_fg. (Barnabás)
- Remove unnecessary batt_info. (Barnabás)
- Fix all checkpatch issues in strict mode. (Barnabás)
- Fixed naming, properties sorting, styling issues, few checkpatch
warnings. (David)
- Updated Joel to "Joel Selvaraj <foss@joelselvaraj.com>" everywhere
(patch author, author field inside the driver, dt docs). (David)
- Link to v0:
- https://gitlab.com/msm8998-mainline/linux/ (very old)
- https://gitlab.com/sdm845-mainline/linux/ (multiple branches)
- https://github.com/sdm660-mainline/linux/
- https://gitlab.com/sdm670-mainline/linux-patches/-/tree/main/stable
---
Alexey Minnekhanov (1):
arm64: dts: qcom: sdm660-xiaomi-lavender: Enable support for battery
Casey Connolly (2):
arm64: dts: qcom: pmi8998: Add fuel gauge
arm64: dts: qcom: sdm845-shift-axolotl: Enable fuel gauge
Joel Selvaraj (2):
power: supply: Add driver for Qualcomm PMI8998 fuel gauge
arm64: dts: qcom: sdm845-xiaomi-beryllium: Enable fuel gauge
Richard Acayan (2):
arm64: dts: qcom: pm660: Add fuel gauge
arm64: dts: qcom: sdm670-google-sargo: Enable fuel gauge
Yassine Oudjana (1):
dt-bindings: power: supply: Add schema for Qualcomm pmi8998 fuel gauge
.../bindings/power/supply/qcom,pmi8998-fg.yaml | 77 +++
arch/arm64/boot/dts/qcom/pm660.dtsi | 10 +
arch/arm64/boot/dts/qcom/pmi8998.dtsi | 11 +
.../arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts | 25 +
arch/arm64/boot/dts/qcom/sdm670-google-sargo.dts | 7 +
arch/arm64/boot/dts/qcom/sdm845-shift-axolotl.dts | 7 +
.../dts/qcom/sdm845-xiaomi-beryllium-common.dtsi | 7 +
drivers/power/supply/Kconfig | 8 +
drivers/power/supply/Makefile | 1 +
drivers/power/supply/pmi8998_fg.c | 687 +++++++++++++++++++++
10 files changed, 840 insertions(+)
---
base-commit: 422f3140bbcb657e1b86c484296972ab76f6d1ff
change-id: 20251121-pmi8998_fuel_gauge-cfaf78ed103d
Best regards,
--
David Heidelberg <david@ixit.cz>
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH RFC 1/8] dt-bindings: power: supply: Add schema for Qualcomm pmi8998 fuel gauge
2025-11-24 21:53 [PATCH RFC 0/8] Qualcomm 3rd gen fuel gauge support David Heidelberg via B4 Relay
@ 2025-11-24 21:53 ` David Heidelberg via B4 Relay
2025-11-27 10:32 ` Konrad Dybcio
2025-11-24 21:53 ` [PATCH RFC 2/8] power: supply: Add driver for Qualcomm PMI8998 " David Heidelberg via B4 Relay
` (7 subsequent siblings)
8 siblings, 1 reply; 24+ messages in thread
From: David Heidelberg via B4 Relay @ 2025-11-24 21:53 UTC (permalink / raw)
To: Sebastian Reichel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Casey Connolly, Casey Connolly, Joel Selvaraj, Yassine Oudjana,
Bjorn Andersson, Konrad Dybcio, Alexander Martinz,
Barnabás Czémán, Richard Acayan,
Alexey Minnekhanov
Cc: linux-pm, devicetree, linux-kernel, linux-arm-msm, phone-devel,
David Heidelberg
From: Yassine Oudjana <y.oudjana@protonmail.com>
Add a device-tree schema for Qualcomm PMIC 8998 fuel gauge.
Signed-off-by: Barnabás Czémán <barnabas.czeman@mainlining.org>
Signed-off-by: Yassine Oudjana <y.oudjana@protonmail.com>
---
.../bindings/power/supply/qcom,pmi8998-fg.yaml | 77 ++++++++++++++++++++++
1 file changed, 77 insertions(+)
diff --git a/Documentation/devicetree/bindings/power/supply/qcom,pmi8998-fg.yaml b/Documentation/devicetree/bindings/power/supply/qcom,pmi8998-fg.yaml
new file mode 100644
index 0000000000000..9acc1a7f04cda
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/supply/qcom,pmi8998-fg.yaml
@@ -0,0 +1,77 @@
+# SPDX-License-Identifier: (GPL-2.0-only or BSD-3-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/power/supply/qcom,pmi8998-fg.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm PMI8998 PMIC Fuel Gauge
+
+maintainers:
+ - Casey Connolly <casey@connolly.tech>
+ - Joel Selvaraj <foss@joelselvaraj.com>
+ - Yassine Oudjana <y.oudjana@protonmail.com>
+
+allOf:
+ - $ref: /schemas/power/supply/power-supply.yaml#
+
+properties:
+ compatible:
+ const: qcom,pmi8998-fg
+
+ reg:
+ maxItems: 1
+
+ monitored-battery:
+ description: |
+ phandle of battery characteristics node.
+ The fuel gauge uses the following battery properties:
+ - charge-full-design-microamp-hours
+ - voltage-min-design-microvolt
+ - voltage-max-design-microvolt
+ See Documentation/devicetree/bindings/power/supply/battery.yaml
+
+ interrupts:
+ items:
+ - description: State of charge change interrupt
+
+ interrupt-names:
+ items:
+ - const: soc-delta
+
+ power-supplies: true
+
+required:
+ - compatible
+ - reg
+ - monitored-battery
+ - interrupts
+ - interrupt-names
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ battery: battery {
+ compatible = "simple-battery";
+
+ charge-full-design-microamp-hours = <4070000>;
+ voltage-min-design-microvolt = <3400000>;
+ voltage-max-design-microvolt = <4400000>;
+ };
+
+ pmic {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ fuel-gauge@4000 {
+ compatible = "qcom,pmi8998-fg";
+ reg = <0x4000>;
+
+ interrupts = <0x2 0x40 0x4 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "soc-delta";
+
+ monitored-battery = <&battery>;
+ };
+ };
--
2.51.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH RFC 2/8] power: supply: Add driver for Qualcomm PMI8998 fuel gauge
2025-11-24 21:53 [PATCH RFC 0/8] Qualcomm 3rd gen fuel gauge support David Heidelberg via B4 Relay
2025-11-24 21:53 ` [PATCH RFC 1/8] dt-bindings: power: supply: Add schema for Qualcomm pmi8998 fuel gauge David Heidelberg via B4 Relay
@ 2025-11-24 21:53 ` David Heidelberg via B4 Relay
2025-11-25 23:13 ` Dmitry Baryshkov
2025-11-27 15:28 ` Konrad Dybcio
2025-11-24 21:53 ` [PATCH RFC 3/8] arm64: dts: qcom: pmi8998: Add " David Heidelberg via B4 Relay
` (6 subsequent siblings)
8 siblings, 2 replies; 24+ messages in thread
From: David Heidelberg via B4 Relay @ 2025-11-24 21:53 UTC (permalink / raw)
To: Sebastian Reichel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Casey Connolly, Casey Connolly, Joel Selvaraj, Yassine Oudjana,
Bjorn Andersson, Konrad Dybcio, Alexander Martinz,
Barnabás Czémán, Richard Acayan,
Alexey Minnekhanov
Cc: linux-pm, devicetree, linux-kernel, linux-arm-msm, phone-devel,
David Heidelberg
From: Joel Selvaraj <foss@joelselvaraj.com>
Ths driver supports the fuel gauge hardware available on PMICs known as
3rd generation fuel gauge hardware available on PMI8998.
Co-developed-by: Casey Connolly <casey@connolly.tech>
Co-developed-by: Barnabás Czémán <barnabas.czeman@mainlining.org>
Signed-off-by: Barnabás Czémán <barnabas.czeman@mainlining.org>
Co-developed-by: Yassine Oudjana <y.oudjana@protonmail.com>
Signed-off-by: Yassine Oudjana <y.oudjana@protonmail.com>
Signed-off-by: David Heidelberg <david@ixit.cz>
---
drivers/power/supply/Kconfig | 8 +
drivers/power/supply/Makefile | 1 +
drivers/power/supply/pmi8998_fg.c | 687 ++++++++++++++++++++++++++++++++++++++
3 files changed, 696 insertions(+)
diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
index 92f9f7aae92f2..4024c6fe3fef2 100644
--- a/drivers/power/supply/Kconfig
+++ b/drivers/power/supply/Kconfig
@@ -746,6 +746,14 @@ config CHARGER_PM8916_LBC
To compile this driver as module, choose M here: the
module will be called pm8916_lbc.
+config BATTERY_PMI8998_FG
+ tristate "Qualcomm PMI8998 PMIC fuel gauge driver"
+ depends on MFD_SPMI_PMIC
+ help
+ Say Y here to enable the Qualcomm PMI8998 PMIC Fuel Gauge driver.
+ This adds support for battery fuel gauging and state of charge of
+ battery connected to the fuel gauge.
+
config CHARGER_BQ2415X
tristate "TI BQ2415x battery charger driver"
depends on I2C
diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile
index 4b79d5abc49a7..03584efa2b1b0 100644
--- a/drivers/power/supply/Makefile
+++ b/drivers/power/supply/Makefile
@@ -96,6 +96,7 @@ obj-$(CONFIG_CHARGER_MT6370) += mt6370-charger.o
obj-$(CONFIG_CHARGER_QCOM_SMBB) += qcom_smbb.o
obj-$(CONFIG_BATTERY_PM8916_BMS_VM) += pm8916_bms_vm.o
obj-$(CONFIG_CHARGER_PM8916_LBC) += pm8916_lbc.o
+obj-$(CONFIG_BATTERY_PMI8998_FG) += pmi8998_fg.o
obj-$(CONFIG_CHARGER_BQ2415X) += bq2415x_charger.o
obj-$(CONFIG_CHARGER_BQ24190) += bq24190_charger.o
obj-$(CONFIG_CHARGER_BQ24257) += bq24257_charger.o
diff --git a/drivers/power/supply/pmi8998_fg.c b/drivers/power/supply/pmi8998_fg.c
new file mode 100644
index 0000000000000..d5fccd16a013b
--- /dev/null
+++ b/drivers/power/supply/pmi8998_fg.c
@@ -0,0 +1,687 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2020, The Linux Foundation. All rights reserved. */
+
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/math64.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+#include <linux/regmap.h>
+#include <linux/types.h>
+#include <linux/workqueue.h>
+
+/* SOC */
+#define BATT_MONOTONIC_SOC 0x009
+
+/* BATT */
+#define PARAM_ADDR_BATT_TEMP 0x150
+#define BATT_INFO_JEITA_COLD 0x162
+#define BATT_INFO_JEITA_COOL 0x163
+#define BATT_INFO_JEITA_WARM 0x164
+#define BATT_INFO_JEITA_HOT 0x165
+#define PARAM_ADDR_BATT_VOLTAGE 0x1a0
+#define PARAM_ADDR_BATT_CURRENT 0x1a2
+
+/* MEMIF */
+#define MEM_INTF_IMA_CFG 0x452
+#define MEM_INTF_IMA_EXP_STS 0x455
+#define MEM_INTF_IMA_HW_STS 0x456
+#define MEM_INTF_IMA_ERR_STS 0x45f
+#define MEM_INTF_ADDR_LSB 0x461
+#define MEM_INTF_RD_DATA0 0x467
+#define MEM_INTF_WR_DATA0 0x463
+#define MEM_IF_DMA_STS 0x470
+#define MEM_IF_DMA_CTL 0x471
+
+#define BATT_TEMP_LSB_MASK GENMASK(7, 0)
+#define BATT_TEMP_MSB_MASK GENMASK(2, 0)
+
+struct pmi8998_fg_chip {
+ struct device *dev;
+ unsigned int base;
+ struct regmap *regmap;
+ struct notifier_block nb;
+
+ struct power_supply *batt_psy;
+ struct power_supply *chg_psy;
+ int status;
+ struct delayed_work status_changed_work;
+};
+
+/*
+ * IO functions
+ */
+
+/**
+ * @brief pmi8998_fg_read() - Read multiple registers with regmap_bulk_read
+ *
+ * @param chip Pointer to chip
+ * @param val Pointer to read values into
+ * @param addr Address to read from
+ * @param len Number of registers (bytes) to read
+ * @return int 0 on success, negative errno on error
+ */
+static int pmi8998_fg_read(struct pmi8998_fg_chip *chip, u8 *val, u16 addr, int len)
+{
+ if (((chip->base + addr) & 0xff00) == 0)
+ return -EINVAL;
+
+ dev_vdbg(chip->dev, "%s: Reading 0x%x bytes from 0x%x", __func__, len, addr);
+
+ return regmap_bulk_read(chip->regmap, chip->base + addr, val, len);
+}
+
+/**
+ * @brief pmi8998_fg_write() - Write multiple registers with regmap_bulk_write
+ *
+ * @param chip Pointer to chip
+ * @param val Pointer to write values from
+ * @param addr Address to write to
+ * @param len Number of registers (bytes) to write
+ * @return int 0 on success, negative errno on error
+ */
+static int pmi8998_fg_write(struct pmi8998_fg_chip *chip, u8 *val, u16 addr, int len)
+{
+ bool sec_access = (addr & 0xff) > 0xd0;
+ u8 sec_addr_val = 0xa5;
+ int ret;
+
+ if (((chip->base + addr) & 0xff00) == 0)
+ return -EINVAL;
+
+ dev_vdbg(chip->dev, "%s: Writing 0x%x to 0x%x", __func__, *val, addr);
+
+ if (sec_access) {
+ ret = regmap_bulk_write(chip->regmap,
+ ((chip->base + addr) & 0xff00) | 0xd0,
+ &sec_addr_val, 1);
+ if (ret)
+ return ret;
+ }
+
+ return regmap_bulk_write(chip->regmap, chip->base + addr, val, len);
+}
+
+/**
+ * @brief pmi8998_fg_masked_write() - like pmi8998_fg_write but applies
+ * a mask first.
+ *
+ * @param chip Pointer to chip
+ * @param val Pointer to write values from
+ * @param addr Address to write to
+ * @param len Number of registers (bytes) to write
+ * @return int 0 on success, negative errno on error
+ */
+static int pmi8998_fg_masked_write(struct pmi8998_fg_chip *chip, u16 addr, u8 mask, u8 val)
+{
+ u8 reg;
+ int ret;
+
+ ret = pmi8998_fg_read(chip, ®, addr, 1);
+ if (ret)
+ return ret;
+
+ reg &= ~mask;
+ reg |= val & mask;
+
+ return pmi8998_fg_write(chip, ®, addr, 1);
+}
+
+/*
+ * Battery status
+ */
+
+/**
+ * @brief pmi8998_fg_get_capacity() - Get remaining capacity of battery
+ *
+ * @param chip Pointer to chip
+ * @param val Pointer to store value at
+ * @return int 0 on success, negative errno on error
+ */
+static int pmi8998_fg_get_capacity(struct pmi8998_fg_chip *chip, int *val)
+{
+ u8 cap[2];
+ int ret;
+
+ ret = pmi8998_fg_read(chip, cap, BATT_MONOTONIC_SOC, 2);
+ if (ret) {
+ dev_err(chip->dev, "Failed to read capacity: %d", ret);
+ return ret;
+ }
+
+ if (cap[0] != cap[1])
+ cap[0] = cap[0] < cap[1] ? cap[0] : cap[1];
+
+ *val = DIV_ROUND_CLOSEST((cap[0] - 1) * 98, 0xff - 2) + 1;
+
+ return 0;
+}
+
+/**
+ * @brief pmi8998_fg_get_temperature() - Get temperature of battery
+ *
+ * @param chip Pointer to chip
+ * @param val Pointer to store value at
+ * @return int 0 on success, negative errno on error
+ */
+static int pmi8998_fg_get_temperature(struct pmi8998_fg_chip *chip, int *val)
+{
+ int ret, temp;
+ u8 readval[2];
+
+ ret = pmi8998_fg_read(chip, readval, PARAM_ADDR_BATT_TEMP, 2);
+ if (ret) {
+ dev_err(chip->dev, "Failed to read temperature: %d\n", ret);
+ return ret;
+ }
+
+ temp = ((readval[1] & BATT_TEMP_MSB_MASK) << 8) |
+ (readval[0] & BATT_TEMP_LSB_MASK);
+ temp = DIV_ROUND_CLOSEST(temp * 10, 4);
+
+ *val = temp - 2730;
+
+ return 0;
+}
+
+/**
+ * @brief pmi8998_fg_get_current() - Get current being drawn from battery
+ *
+ * @param chip Pointer to chip
+ * @param val Pointer to store value at
+ * @return int 0 on success, negative errno on error
+ */
+static int pmi8998_fg_get_current(struct pmi8998_fg_chip *chip, int *val)
+{
+ s16 temp;
+ u8 readval[2];
+ int ret;
+
+ ret = pmi8998_fg_read(chip, readval, PARAM_ADDR_BATT_CURRENT, 2);
+ if (ret) {
+ dev_err(chip->dev, "Failed to read current: %d\n", ret);
+ return ret;
+ }
+
+ /* handle rev 1 too */
+ temp = (s16)(readval[1] << 8 | readval[0]);
+ *val = div_s64((s64)temp * 488281, 1000);
+
+ /*
+ * PSY API expects charging batteries to report a positive current, which is inverted
+ * to what the PMIC reports.
+ */
+ *val = -*val;
+
+ return 0;
+}
+
+/**
+ * @brief pmi8998_fg_get_voltage() - Get voltage of battery
+ *
+ * @param chip Pointer to chip
+ * @param val Pointer to store value at
+ * @return int 0 on success, negative errno on error
+ */
+static int pmi8998_fg_get_voltage(struct pmi8998_fg_chip *chip, int *val)
+{
+ int temp;
+ u8 readval[2];
+ int ret;
+
+ ret = pmi8998_fg_read(chip, readval, PARAM_ADDR_BATT_VOLTAGE, 2);
+ if (ret) {
+ dev_err(chip->dev, "Failed to read voltage: %d\n", ret);
+ return ret;
+ }
+
+ /* handle rev 1 too */
+ temp = readval[1] << 8 | readval[0];
+ *val = div_u64((u64)temp * 122070, 1000);
+
+ return 0;
+}
+
+/**
+ * @brief pmi8998_fg_get_temp_threshold() - Get configured temperature thresholds
+ *
+ * @param chip Pointer to chip
+ * @param psp Power supply property of temperature limit
+ * @param val Pointer to store value at
+ * @return int 0 on success, negative errno on error
+ */
+static int pmi8998_fg_get_temp_threshold(struct pmi8998_fg_chip *chip,
+ enum power_supply_property psp, int *val)
+{
+ u8 temp;
+ u16 reg;
+ int ret;
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_TEMP_MIN:
+ reg = BATT_INFO_JEITA_COLD;
+ break;
+ case POWER_SUPPLY_PROP_TEMP_MAX:
+ reg = BATT_INFO_JEITA_HOT;
+ break;
+ case POWER_SUPPLY_PROP_TEMP_ALERT_MIN:
+ reg = BATT_INFO_JEITA_COOL;
+ break;
+ case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
+ reg = BATT_INFO_JEITA_WARM;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ ret = pmi8998_fg_read(chip, &temp, reg, 1);
+ if (ret < 0) {
+ dev_err(chip->dev, "Failed to read JEITA property %d level: %d\n", psp, ret);
+ return ret;
+ }
+
+ /* Resolution is 0.5C. Base is -30C. */
+ *val = (((5 * temp) / 10) - 30) * 10;
+
+ return 0;
+}
+
+/*
+ * Battery power supply
+ */
+
+static enum power_supply_property pmi8998_fg_props[] = {
+ POWER_SUPPLY_PROP_STATUS,
+ POWER_SUPPLY_PROP_TECHNOLOGY,
+ POWER_SUPPLY_PROP_CAPACITY,
+ POWER_SUPPLY_PROP_CURRENT_NOW,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
+ POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_TEMP,
+ POWER_SUPPLY_PROP_TEMP_MIN,
+ POWER_SUPPLY_PROP_TEMP_MAX,
+ POWER_SUPPLY_PROP_TEMP_ALERT_MIN,
+ POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
+};
+
+static int pmi8998_fg_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct pmi8998_fg_chip *chip = power_supply_get_drvdata(psy);
+ int temp, ret = 0;
+
+ dev_dbg(chip->dev, "Getting property: %d", psp);
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_STATUS:
+ /* Get status from charger if available */
+ if (chip->chg_psy &&
+ chip->status != POWER_SUPPLY_STATUS_UNKNOWN) {
+ val->intval = chip->status;
+ } else {
+ /*
+ * Fall back to capacity and current-based
+ * status checking
+ */
+ ret = pmi8998_fg_get_capacity(chip, &temp);
+ if (ret) {
+ val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
+ break;
+ }
+ if (temp == 100) {
+ val->intval = POWER_SUPPLY_STATUS_FULL;
+ break;
+ }
+
+ ret = pmi8998_fg_get_current(chip, &temp);
+ if (ret) {
+ val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
+ break;
+ }
+ if (temp < 0)
+ val->intval = POWER_SUPPLY_STATUS_CHARGING;
+ else if (temp > 0)
+ val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+ else
+ val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ }
+
+ break;
+ case POWER_SUPPLY_PROP_TECHNOLOGY:
+ val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
+ break;
+ case POWER_SUPPLY_PROP_CAPACITY:
+ ret = pmi8998_fg_get_capacity(chip, &val->intval);
+ break;
+ case POWER_SUPPLY_PROP_CURRENT_NOW:
+ ret = pmi8998_fg_get_current(chip, &val->intval);
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ ret = pmi8998_fg_get_voltage(chip, &val->intval);
+ break;
+ case POWER_SUPPLY_PROP_PRESENT:
+ val->intval = 1;
+ break;
+ case POWER_SUPPLY_PROP_TEMP:
+ ret = pmi8998_fg_get_temperature(chip, &val->intval);
+ break;
+ case POWER_SUPPLY_PROP_TEMP_MIN:
+ case POWER_SUPPLY_PROP_TEMP_MAX:
+ case POWER_SUPPLY_PROP_TEMP_ALERT_MIN:
+ case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
+ ret = pmi8998_fg_get_temp_threshold(chip, psp, &val->intval);
+ break;
+ default:
+ dev_err(chip->dev, "invalid property: %d\n", psp);
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static const struct power_supply_desc batt_psy_desc = {
+ .name = "qcom-battery",
+ .type = POWER_SUPPLY_TYPE_BATTERY,
+ .properties = pmi8998_fg_props,
+ .num_properties = ARRAY_SIZE(pmi8998_fg_props),
+ .get_property = pmi8998_fg_get_property,
+};
+
+/*
+ * Init functions
+ */
+
+static int pmi8998_fg_iacs_clear_sequence(struct pmi8998_fg_chip *chip)
+{
+ u8 temp;
+ int ret;
+
+ /* clear the error */
+ ret = pmi8998_fg_masked_write(chip, MEM_INTF_IMA_CFG, BIT(2), BIT(2));
+ if (ret) {
+ dev_err(chip->dev, "Failed to write IMA_CFG: %d\n", ret);
+ return ret;
+ }
+
+ temp = 0x4;
+ ret = pmi8998_fg_write(chip, &temp, MEM_INTF_ADDR_LSB + 1, 1);
+ if (ret) {
+ dev_err(chip->dev, "Failed to write MEM_INTF_ADDR_MSB: %d\n", ret);
+ return ret;
+ }
+
+ temp = 0x0;
+ ret = pmi8998_fg_write(chip, &temp, MEM_INTF_WR_DATA0 + 3, 1);
+ if (ret) {
+ dev_err(chip->dev, "Failed to write WR_DATA3: %d\n", ret);
+ return ret;
+ }
+
+ ret = pmi8998_fg_read(chip, &temp, MEM_INTF_RD_DATA0 + 3, 1);
+ if (ret) {
+ dev_err(chip->dev, "Failed to write RD_DATA3: %d\n", ret);
+ return ret;
+ }
+
+ ret = pmi8998_fg_masked_write(chip, MEM_INTF_IMA_CFG, BIT(2), 0);
+ if (ret) {
+ dev_err(chip->dev, "Failed to write IMA_CFG: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int pmi8998_fg_clear_ima(struct pmi8998_fg_chip *chip, bool check_hw_sts)
+{
+ u8 err_sts, exp_sts, hw_sts;
+ bool run_err_clr_seq = false;
+ int ret;
+
+ ret = pmi8998_fg_read(chip, &err_sts, MEM_INTF_IMA_ERR_STS, 1);
+ if (ret) {
+ dev_err(chip->dev, "Failed to read IMA_ERR_STS: %d\n", ret);
+ return ret;
+ }
+
+ ret = pmi8998_fg_read(chip, &exp_sts,
+ MEM_INTF_IMA_EXP_STS, 1);
+ if (ret) {
+ dev_err(chip->dev, "Failed to read IMA_EXP_STS: %d\n", ret);
+ return ret;
+ }
+
+ if (check_hw_sts) {
+ ret = pmi8998_fg_read(chip, &hw_sts,
+ MEM_INTF_IMA_HW_STS, 1);
+ if (ret) {
+ dev_err(chip->dev, "Failed to read IMA_HW_STS: %d\n", ret);
+ return ret;
+ }
+ /*
+ * Lower nibble should be equal to upper nibble before SRAM
+ * transactions begins from SW side.
+ */
+ if ((hw_sts & 0x0f) != hw_sts >> 4) {
+ dev_dbg(chip->dev, "IMA HW not in correct state, hw_sts=%x\n",
+ hw_sts);
+ run_err_clr_seq = true;
+ }
+ }
+
+ if (exp_sts & (BIT(0) | BIT(1) | BIT(3) |
+ BIT(4) | BIT(5) | BIT(6) |
+ BIT(7))) {
+ dev_dbg(chip->dev, "IMA exception bit set, exp_sts=%x\n", exp_sts);
+ run_err_clr_seq = true;
+ }
+
+ if (run_err_clr_seq) {
+ ret = pmi8998_fg_iacs_clear_sequence(chip);
+ if (!ret)
+ return -EAGAIN;
+ }
+
+ return 0;
+}
+
+static irqreturn_t pmi8998_fg_handle_soc_delta(int irq, void *data)
+{
+ struct pmi8998_fg_chip *chip = data;
+
+ /* Signal change in state of charge */
+ power_supply_changed(chip->batt_psy);
+ dev_dbg(chip->dev, "SOC changed");
+
+ return IRQ_HANDLED;
+}
+
+static void pmi8998_fg_status_changed_worker(struct work_struct *work)
+{
+ struct pmi8998_fg_chip *chip = container_of(work, struct pmi8998_fg_chip,
+ status_changed_work.work);
+
+ power_supply_changed(chip->batt_psy);
+}
+
+static int pmi8998_fg_notifier_call(struct notifier_block *nb, unsigned long val, void *v)
+{
+ struct pmi8998_fg_chip *chip = container_of(nb, struct pmi8998_fg_chip, nb);
+ struct power_supply *psy = v;
+ union power_supply_propval propval;
+ int ret;
+
+ if (psy == chip->chg_psy) {
+ ret = power_supply_get_property(psy,
+ POWER_SUPPLY_PROP_STATUS, &propval);
+ if (ret)
+ chip->status = POWER_SUPPLY_STATUS_UNKNOWN;
+
+ chip->status = propval.intval;
+
+ power_supply_changed(chip->batt_psy);
+
+ if (chip->status == POWER_SUPPLY_STATUS_UNKNOWN) {
+ /*
+ * REVISIT: Find better solution or remove current-based
+ * status checking once checking is properly implemented
+ * in charger drivers
+
+ * Sometimes it take a while for current to stabilize,
+ * so signal property change again later to make sure
+ * current-based status is properly detected.
+ */
+ cancel_delayed_work_sync(&chip->status_changed_work);
+ schedule_delayed_work(&chip->status_changed_work,
+ msecs_to_jiffies(1000));
+ }
+ }
+
+ return NOTIFY_OK;
+}
+
+static int pmi8998_fg_probe(struct platform_device *pdev)
+{
+ struct power_supply_config supply_config = {};
+ struct pmi8998_fg_chip *chip;
+ const __be32 *prop_addr;
+ int irq;
+ u8 dma_status;
+ bool error_present;
+ int ret;
+
+ chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
+ if (!chip)
+ return -ENOMEM;
+
+ chip->dev = &pdev->dev;
+
+ chip->regmap = dev_get_regmap(pdev->dev.parent, NULL);
+ if (!chip->regmap) {
+ dev_err(chip->dev, "Failed to locate the regmap\n");
+ return -ENODEV;
+ }
+
+ /* Get base address */
+ prop_addr = of_get_address(pdev->dev.of_node, 0, NULL, NULL);
+ if (!prop_addr) {
+ dev_err(chip->dev, "Failed to read SOC base address from dt\n");
+ return -EINVAL;
+ }
+ chip->base = be32_to_cpu(*prop_addr);
+
+ /*
+ * Change the FG_MEM_INT interrupt to track IACS_READY
+ * condition instead of end-of-transaction. This makes sure
+ * that the next transaction starts only after the hw is ready.
+ * IACS_INTR_SRC_SLCT is BIT(3)
+ */
+ ret = pmi8998_fg_masked_write(chip, MEM_INTF_IMA_CFG, BIT(3), BIT(3));
+ if (ret) {
+ dev_err(chip->dev,
+ "Failed to configure interrupt sourete: %d\n", ret);
+ return ret;
+ }
+
+ ret = pmi8998_fg_clear_ima(chip, true);
+ if (ret && ret != -EAGAIN) {
+ dev_err(chip->dev, "Failed to clear IMA exception: %d\n", ret);
+ return ret;
+ }
+
+ /* Check and clear DMA errors */
+ ret = pmi8998_fg_read(chip, &dma_status, MEM_IF_DMA_STS, 1);
+ if (ret < 0) {
+ dev_err(chip->dev, "Failed to read dma_status: %d\n", ret);
+ return ret;
+ }
+
+ error_present = dma_status & (BIT(1) | BIT(2));
+ ret = pmi8998_fg_masked_write(chip, MEM_IF_DMA_CTL, BIT(0),
+ error_present ? BIT(0) : 0);
+ if (ret < 0) {
+ dev_err(chip->dev, "Failed to write dma_ctl: %d\n", ret);
+ return ret;
+ }
+
+ supply_config.drv_data = chip;
+ supply_config.fwnode = dev_fwnode(&pdev->dev);
+
+ chip->batt_psy = devm_power_supply_register(chip->dev,
+ &batt_psy_desc, &supply_config);
+ if (IS_ERR(chip->batt_psy)) {
+ if (PTR_ERR(chip->batt_psy) != -EPROBE_DEFER)
+ dev_err(&pdev->dev, "Failed to register battery\n");
+ return PTR_ERR(chip->batt_psy);
+ }
+
+ platform_set_drvdata(pdev, chip);
+
+ /* Get soc-delta IRQ */
+ irq = of_irq_get_byname(pdev->dev.of_node, "soc-delta");
+ if (irq < 0) {
+ dev_err(&pdev->dev, "Failed to get irq soc-delta byname: %d\n",
+ irq);
+ return irq;
+ }
+
+ ret = devm_request_threaded_irq(chip->dev, irq, NULL,
+ pmi8998_fg_handle_soc_delta,
+ IRQF_ONESHOT, "soc-delta", chip);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Failed to request soc-delta IRQ: %d\n", ret);
+ return ret;
+ }
+
+ /* Optional: Get charger power supply for status checking */
+ chip->chg_psy = power_supply_get_by_reference(of_fwnode_handle(chip->dev->of_node),
+ "power-supplies");
+ if (IS_ERR(chip->chg_psy)) {
+ ret = PTR_ERR(chip->chg_psy);
+ dev_warn(chip->dev, "Failed to get charger supply: %d\n", ret);
+ chip->chg_psy = NULL;
+ }
+
+ if (chip->chg_psy) {
+ INIT_DELAYED_WORK(&chip->status_changed_work,
+ pmi8998_fg_status_changed_worker);
+
+ chip->nb.notifier_call = pmi8998_fg_notifier_call;
+ ret = power_supply_reg_notifier(&chip->nb);
+ if (ret) {
+ dev_err(chip->dev,
+ "Failed to register notifier: %d\n", ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static const struct of_device_id fg_match_id_table[] = {
+ { .compatible = "qcom,pmi8998-fg" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, fg_match_id_table);
+
+static struct platform_driver pmi8998_fg_driver = {
+ .probe = pmi8998_fg_probe,
+ .driver = {
+ .name = "pmi8998-fg",
+ .of_match_table = fg_match_id_table,
+ },
+};
+
+module_platform_driver(pmi8998_fg_driver);
+
+MODULE_AUTHOR("Casey Connolly <casey@connolly.tech>");
+MODULE_AUTHOR("Joel Selvaraj <foss@joelselvaraj.com>");
+MODULE_AUTHOR("Yassine Oudjana <y.oudjana@protonmail.com>");
+MODULE_DESCRIPTION("Qualcomm PMI8998 Fuel Gauge Driver");
+MODULE_LICENSE("GPL");
--
2.51.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH RFC 3/8] arm64: dts: qcom: pmi8998: Add fuel gauge
2025-11-24 21:53 [PATCH RFC 0/8] Qualcomm 3rd gen fuel gauge support David Heidelberg via B4 Relay
2025-11-24 21:53 ` [PATCH RFC 1/8] dt-bindings: power: supply: Add schema for Qualcomm pmi8998 fuel gauge David Heidelberg via B4 Relay
2025-11-24 21:53 ` [PATCH RFC 2/8] power: supply: Add driver for Qualcomm PMI8998 " David Heidelberg via B4 Relay
@ 2025-11-24 21:53 ` David Heidelberg via B4 Relay
2025-11-25 23:16 ` Dmitry Baryshkov
2025-11-27 17:53 ` Casey Connolly
2025-11-24 21:53 ` [PATCH RFC 4/8] arm64: dts: qcom: pm660: " David Heidelberg via B4 Relay
` (5 subsequent siblings)
8 siblings, 2 replies; 24+ messages in thread
From: David Heidelberg via B4 Relay @ 2025-11-24 21:53 UTC (permalink / raw)
To: Sebastian Reichel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Casey Connolly, Casey Connolly, Joel Selvaraj, Yassine Oudjana,
Bjorn Andersson, Konrad Dybcio, Alexander Martinz,
Barnabás Czémán, Richard Acayan,
Alexey Minnekhanov
Cc: linux-pm, devicetree, linux-kernel, linux-arm-msm, phone-devel,
David Heidelberg
From: Casey Connolly <casey.connolly@linaro.org>
Introduce the fuel gauge node for pmi8998.
Signed-off-by: David Heidelberg <david@ixit.cz>
---
arch/arm64/boot/dts/qcom/pmi8998.dtsi | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/pmi8998.dtsi b/arch/arm64/boot/dts/qcom/pmi8998.dtsi
index cd3f0790fd420..ab3bc66502657 100644
--- a/arch/arm64/boot/dts/qcom/pmi8998.dtsi
+++ b/arch/arm64/boot/dts/qcom/pmi8998.dtsi
@@ -44,6 +44,17 @@ pmi8998_rradc: adc@4500 {
reg = <0x4500>;
#io-channel-cells = <1>;
};
+
+ pmi8998_fg: fuel-gauge@4000 {
+ compatible = "qcom,pmi8998-fg";
+ reg = <0x4000>;
+
+ interrupts = <0x2 0x40 0x3 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "soc-delta";
+
+ status = "disabled";
+ };
+
};
pmi8998_lsid1: pmic@3 {
--
2.51.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH RFC 4/8] arm64: dts: qcom: pm660: Add fuel gauge
2025-11-24 21:53 [PATCH RFC 0/8] Qualcomm 3rd gen fuel gauge support David Heidelberg via B4 Relay
` (2 preceding siblings ...)
2025-11-24 21:53 ` [PATCH RFC 3/8] arm64: dts: qcom: pmi8998: Add " David Heidelberg via B4 Relay
@ 2025-11-24 21:53 ` David Heidelberg via B4 Relay
2025-11-25 23:17 ` Dmitry Baryshkov
2025-11-24 21:53 ` [PATCH RFC 5/8] arm64: dts: qcom: sdm845-xiaomi-beryllium: Enable " David Heidelberg via B4 Relay
` (4 subsequent siblings)
8 siblings, 1 reply; 24+ messages in thread
From: David Heidelberg via B4 Relay @ 2025-11-24 21:53 UTC (permalink / raw)
To: Sebastian Reichel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Casey Connolly, Casey Connolly, Joel Selvaraj, Yassine Oudjana,
Bjorn Andersson, Konrad Dybcio, Alexander Martinz,
Barnabás Czémán, Richard Acayan,
Alexey Minnekhanov
Cc: linux-pm, devicetree, linux-kernel, linux-arm-msm, phone-devel,
David Heidelberg
From: Richard Acayan <mailingradian@gmail.com>
The PM660 has the same fuel gauge as PMI8998. Add support for
PM660 battery monitoring.
Signed-off-by: Richard Acayan <mailingradian@gmail.com>
Signed-off-by: David Heidelberg <david@ixit.cz>
---
arch/arm64/boot/dts/qcom/pm660.dtsi | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/pm660.dtsi b/arch/arm64/boot/dts/qcom/pm660.dtsi
index 156b2ddff0dcb..ce53f5ddc4bdf 100644
--- a/arch/arm64/boot/dts/qcom/pm660.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm660.dtsi
@@ -197,6 +197,16 @@ channel@85 {
};
};
+ pm660_fg: fuel-gauge@4000 {
+ compatible = "qcom,pmi8998-fg";
+ reg = <0x4000>;
+
+ interrupts = <0x0 0x40 0x3 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "soc-delta";
+
+ status = "disabled";
+ };
+
pm660_rradc: adc@4500 {
compatible = "qcom,pm660-rradc";
reg = <0x4500>;
--
2.51.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH RFC 5/8] arm64: dts: qcom: sdm845-xiaomi-beryllium: Enable fuel gauge
2025-11-24 21:53 [PATCH RFC 0/8] Qualcomm 3rd gen fuel gauge support David Heidelberg via B4 Relay
` (3 preceding siblings ...)
2025-11-24 21:53 ` [PATCH RFC 4/8] arm64: dts: qcom: pm660: " David Heidelberg via B4 Relay
@ 2025-11-24 21:53 ` David Heidelberg via B4 Relay
2025-11-25 23:48 ` Dmitry Baryshkov
2025-11-24 21:53 ` [PATCH RFC 6/8] arm64: dts: qcom: sdm845-shift-axolotl: " David Heidelberg via B4 Relay
` (3 subsequent siblings)
8 siblings, 1 reply; 24+ messages in thread
From: David Heidelberg via B4 Relay @ 2025-11-24 21:53 UTC (permalink / raw)
To: Sebastian Reichel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Casey Connolly, Casey Connolly, Joel Selvaraj, Yassine Oudjana,
Bjorn Andersson, Konrad Dybcio, Alexander Martinz,
Barnabás Czémán, Richard Acayan,
Alexey Minnekhanov
Cc: linux-pm, devicetree, linux-kernel, linux-arm-msm, phone-devel,
David Heidelberg
From: Joel Selvaraj <foss@joelselvaraj.com>
Enable the fuel gauge and configure the associated charger and battery.
Signed-off-by: Joel Selvaraj <foss@joelselvaraj.com>
Signed-off-by: David Heidelberg <david@ixit.cz>
---
arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium-common.dtsi | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium-common.dtsi b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium-common.dtsi
index 785006a15e979..bb6448f4e036b 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium-common.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium-common.dtsi
@@ -377,6 +377,13 @@ led-1 {
};
};
+&pmi8998_fg {
+ power-supplies = <&pmi8998_charger>;
+ monitored-battery = <&battery>;
+
+ status = "okay";
+};
+
&pm8998_resin {
linux,code = <KEY_VOLUMEDOWN>;
status = "okay";
--
2.51.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH RFC 6/8] arm64: dts: qcom: sdm845-shift-axolotl: Enable fuel gauge
2025-11-24 21:53 [PATCH RFC 0/8] Qualcomm 3rd gen fuel gauge support David Heidelberg via B4 Relay
` (4 preceding siblings ...)
2025-11-24 21:53 ` [PATCH RFC 5/8] arm64: dts: qcom: sdm845-xiaomi-beryllium: Enable " David Heidelberg via B4 Relay
@ 2025-11-24 21:53 ` David Heidelberg via B4 Relay
2025-11-25 23:48 ` Dmitry Baryshkov
2025-11-24 21:53 ` [PATCH RFC 7/8] arm64: dts: qcom: sdm660-xiaomi-lavender: Enable support for battery David Heidelberg via B4 Relay
` (2 subsequent siblings)
8 siblings, 1 reply; 24+ messages in thread
From: David Heidelberg via B4 Relay @ 2025-11-24 21:53 UTC (permalink / raw)
To: Sebastian Reichel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Casey Connolly, Casey Connolly, Joel Selvaraj, Yassine Oudjana,
Bjorn Andersson, Konrad Dybcio, Alexander Martinz,
Barnabás Czémán, Richard Acayan,
Alexey Minnekhanov
Cc: linux-pm, devicetree, linux-kernel, linux-arm-msm, phone-devel,
David Heidelberg
From: Casey Connolly <casey.connolly@linaro.org>
Enable the fuel gauge and configure the associated charger and battery.
Signed-off-by: Casey Connolly <casey.connolly@linaro.org>
Signed-off-by: David Heidelberg <david@ixit.cz>
---
arch/arm64/boot/dts/qcom/sdm845-shift-axolotl.dts | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/sdm845-shift-axolotl.dts b/arch/arm64/boot/dts/qcom/sdm845-shift-axolotl.dts
index ddc2b3ca3bc57..f1fea39972e8c 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-shift-axolotl.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-shift-axolotl.dts
@@ -524,6 +524,13 @@ &pmi8998_charger {
status = "okay";
};
+&pmi8998_fg {
+ power-supplies = <&pmi8998_charger>;
+ monitored-battery = <&battery>;
+
+ status = "okay";
+};
+
&pm8998_resin {
linux,code = <KEY_VOLUMEDOWN>;
status = "okay";
--
2.51.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH RFC 7/8] arm64: dts: qcom: sdm660-xiaomi-lavender: Enable support for battery
2025-11-24 21:53 [PATCH RFC 0/8] Qualcomm 3rd gen fuel gauge support David Heidelberg via B4 Relay
` (5 preceding siblings ...)
2025-11-24 21:53 ` [PATCH RFC 6/8] arm64: dts: qcom: sdm845-shift-axolotl: " David Heidelberg via B4 Relay
@ 2025-11-24 21:53 ` David Heidelberg via B4 Relay
2025-11-25 23:50 ` Dmitry Baryshkov
2025-11-24 21:53 ` [PATCH RFC 8/8] arm64: dts: qcom: sdm670-google-sargo: Enable fuel gauge David Heidelberg via B4 Relay
2025-11-25 18:09 ` [PATCH RFC 0/8] Qualcomm 3rd gen fuel gauge support Rob Herring
8 siblings, 1 reply; 24+ messages in thread
From: David Heidelberg via B4 Relay @ 2025-11-24 21:53 UTC (permalink / raw)
To: Sebastian Reichel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Casey Connolly, Casey Connolly, Joel Selvaraj, Yassine Oudjana,
Bjorn Andersson, Konrad Dybcio, Alexander Martinz,
Barnabás Czémán, Richard Acayan,
Alexey Minnekhanov
Cc: linux-pm, devicetree, linux-kernel, linux-arm-msm, phone-devel,
David Heidelberg
From: Alexey Minnekhanov <alexeymin@postmarketos.org>
Add support for battery, fuelgauge and charger.
Signed-off-by: Alexey Minnekhanov <alexeymin@postmarketos.org>
Signed-off-by: David Heidelberg <david@ixit.cz>
---
.../arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts | 25 ++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts b/arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts
index a9926ad6c6f9f..cb89b88d887d1 100644
--- a/arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts
+++ b/arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts
@@ -38,6 +38,14 @@ framebuffer0: framebuffer@9d400000 {
};
};
+ battery: battery {
+ compatible = "simple-battery";
+
+ charge-full-design-microamp-hours = <4000000>;
+ voltage-min-design-microvolt = <3400000>;
+ voltage-max-design-microvolt = <4400000>;
+ };
+
vph_pwr: vph-pwr-regulator {
compatible = "regulator-fixed";
regulator-name = "vph_pwr";
@@ -93,6 +101,23 @@ &blsp1_uart2 {
status = "okay";
};
+&pm660_charger {
+ monitored-battery = <&battery>;
+
+ status = "okay";
+};
+
+&pm660_fg {
+ monitored-battery = <&battery>;
+ power-supplies = <&pm660_charger>;
+
+ status = "okay";
+};
+
+&pm660_rradc {
+ status = "okay";
+};
+
&pon_pwrkey {
status = "okay";
};
--
2.51.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH RFC 8/8] arm64: dts: qcom: sdm670-google-sargo: Enable fuel gauge
2025-11-24 21:53 [PATCH RFC 0/8] Qualcomm 3rd gen fuel gauge support David Heidelberg via B4 Relay
` (6 preceding siblings ...)
2025-11-24 21:53 ` [PATCH RFC 7/8] arm64: dts: qcom: sdm660-xiaomi-lavender: Enable support for battery David Heidelberg via B4 Relay
@ 2025-11-24 21:53 ` David Heidelberg via B4 Relay
2025-11-25 23:50 ` Dmitry Baryshkov
2025-11-25 18:09 ` [PATCH RFC 0/8] Qualcomm 3rd gen fuel gauge support Rob Herring
8 siblings, 1 reply; 24+ messages in thread
From: David Heidelberg via B4 Relay @ 2025-11-24 21:53 UTC (permalink / raw)
To: Sebastian Reichel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Casey Connolly, Casey Connolly, Joel Selvaraj, Yassine Oudjana,
Bjorn Andersson, Konrad Dybcio, Alexander Martinz,
Barnabás Czémán, Richard Acayan,
Alexey Minnekhanov
Cc: linux-pm, devicetree, linux-kernel, linux-arm-msm, phone-devel,
David Heidelberg
From: Richard Acayan <mailingradian@gmail.com>
The PM660 fuel gauge determines the battery charge. Enable it for full
battery support.
Signed-off-by: Richard Acayan <mailingradian@gmail.com>
Signed-off-by: David Heidelberg <david@ixit.cz>
---
arch/arm64/boot/dts/qcom/sdm670-google-sargo.dts | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/sdm670-google-sargo.dts b/arch/arm64/boot/dts/qcom/sdm670-google-sargo.dts
index ed55646ca419d..a8e0e85c42cd2 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-google-sargo.dts
+++ b/arch/arm64/boot/dts/qcom/sdm670-google-sargo.dts
@@ -490,6 +490,13 @@ &pm660_charger {
status = "okay";
};
+&pm660_fg {
+ monitored-battery = <&battery>;
+ power-supplies = <&pm660_charger>;
+
+ status = "okay";
+};
+
&pm660_rradc {
status = "okay";
};
--
2.51.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH RFC 0/8] Qualcomm 3rd gen fuel gauge support
2025-11-24 21:53 [PATCH RFC 0/8] Qualcomm 3rd gen fuel gauge support David Heidelberg via B4 Relay
` (7 preceding siblings ...)
2025-11-24 21:53 ` [PATCH RFC 8/8] arm64: dts: qcom: sdm670-google-sargo: Enable fuel gauge David Heidelberg via B4 Relay
@ 2025-11-25 18:09 ` Rob Herring
8 siblings, 0 replies; 24+ messages in thread
From: Rob Herring @ 2025-11-25 18:09 UTC (permalink / raw)
To: David Heidelberg
Cc: Casey Connolly, Richard Acayan, Sebastian Reichel,
Bjorn Andersson, linux-arm-msm, phone-devel, linux-kernel,
Yassine Oudjana, Krzysztof Kozlowski, Alexander Martinz,
Joel Selvaraj, devicetree, linux-pm, Alexey Minnekhanov,
Conor Dooley, Konrad Dybcio, Casey Connolly,
Barnabás Czémán
On Mon, 24 Nov 2025 22:53:33 +0100, David Heidelberg wrote:
> This FG (fuel gauge) can be found on Snapdragon 835, 845, 660, 670..
>
> Series enables the FG, which is used on phones as OnePlus 6, 6T, Pixel 3a..
>
> Since many downstream trees (sdm845-mainline, sdm660, sdm670) carring
> these patches, after Barnabás dropped older gen support from the driver,
> cleaned up the driver, I picked changes and cleaned up device-tree
> patches and sending the whole bulk for review.
>
> Note:
> Usually I picked the oldest commits authors.
> Since there was multiple patches, multiple names and modifications etc.,
> if someone from the authors, co-developers, contributors etc. missing,
> please let me know and I'll fix this up in the next series.
>
> Currently some authors are unreachable or haven't given Signed-off-by
> yet, thus RFC, when this get cleaned up, I'll sent non-RFC or leave it
> to the authors to continue upstreaming process in case they want to.
>
> Until merged (or taken over by the original authors), the series is
> available at:
> https://gitlab.com/sdm845/sdm845-next/-/commits/b4%2Fpmi8998_fuel_gauge
>
> Signed-off-by: David Heidelberg <david@ixit.cz>
> ---
> Changes in v1:
> - Clean and read charge full and max voltage from dts. (Joel)
> - Dont put battery info on remove. All the battery info data is devm
> tracked so it will be freed for us on removal. (Casey)
> - Invert charging current. Battery current should be negative for charging
> batteries, invert it so it's correct. Fixes upower charging status
> reporting. (Casey)
> - Expose PROP_STATUS to fix upower not detecting charging status properly.
> - Adopt battery info API changes.
> - Silence -EPROBE_DEFER error. (Richard)
> - Add present sysfs property. Required for battery drivers from
> UPower>=1.90.0 onwards to work properly. (Alexander)
> - Drop support for older gen from the driver. (Barnabás)
> - Rename the driver to pmi8998_fg. (Barnabás)
> - Remove unnecessary batt_info. (Barnabás)
> - Fix all checkpatch issues in strict mode. (Barnabás)
> - Fixed naming, properties sorting, styling issues, few checkpatch
> warnings. (David)
> - Updated Joel to "Joel Selvaraj <foss@joelselvaraj.com>" everywhere
> (patch author, author field inside the driver, dt docs). (David)
> - Link to v0:
> - https://gitlab.com/msm8998-mainline/linux/ (very old)
> - https://gitlab.com/sdm845-mainline/linux/ (multiple branches)
> - https://github.com/sdm660-mainline/linux/
> - https://gitlab.com/sdm670-mainline/linux-patches/-/tree/main/stable
>
> ---
> Alexey Minnekhanov (1):
> arm64: dts: qcom: sdm660-xiaomi-lavender: Enable support for battery
>
> Casey Connolly (2):
> arm64: dts: qcom: pmi8998: Add fuel gauge
> arm64: dts: qcom: sdm845-shift-axolotl: Enable fuel gauge
>
> Joel Selvaraj (2):
> power: supply: Add driver for Qualcomm PMI8998 fuel gauge
> arm64: dts: qcom: sdm845-xiaomi-beryllium: Enable fuel gauge
>
> Richard Acayan (2):
> arm64: dts: qcom: pm660: Add fuel gauge
> arm64: dts: qcom: sdm670-google-sargo: Enable fuel gauge
>
> Yassine Oudjana (1):
> dt-bindings: power: supply: Add schema for Qualcomm pmi8998 fuel gauge
>
> .../bindings/power/supply/qcom,pmi8998-fg.yaml | 77 +++
> arch/arm64/boot/dts/qcom/pm660.dtsi | 10 +
> arch/arm64/boot/dts/qcom/pmi8998.dtsi | 11 +
> .../arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts | 25 +
> arch/arm64/boot/dts/qcom/sdm670-google-sargo.dts | 7 +
> arch/arm64/boot/dts/qcom/sdm845-shift-axolotl.dts | 7 +
> .../dts/qcom/sdm845-xiaomi-beryllium-common.dtsi | 7 +
> drivers/power/supply/Kconfig | 8 +
> drivers/power/supply/Makefile | 1 +
> drivers/power/supply/pmi8998_fg.c | 687 +++++++++++++++++++++
> 10 files changed, 840 insertions(+)
> ---
> base-commit: 422f3140bbcb657e1b86c484296972ab76f6d1ff
> change-id: 20251121-pmi8998_fuel_gauge-cfaf78ed103d
>
> Best regards,
> --
> David Heidelberg <david@ixit.cz>
>
>
>
My bot found new DTB warnings on the .dts files added or changed in this
series.
Some warnings may be from an existing SoC .dtsi. Or perhaps the warnings
are fixed by another series. Ultimately, it is up to the platform
maintainer whether these warnings are acceptable or not. No need to reply
unless the platform maintainer has comments.
If you already ran DT checks and didn't see these error(s), then
make sure dt-schema is up to date:
pip3 install dtschema --upgrade
This patch series was applied (using b4) to base:
Base: 422f3140bbcb657e1b86c484296972ab76f6d1ff (use --merge-base to override)
If this is not the correct base, please add 'base-commit' tag
(or use b4 which does this automatically)
New warnings running 'make CHECK_DTBS=y for arch/arm64/boot/dts/qcom/' for 20251124-pmi8998_fuel_gauge-v1-0-dd3791f61478@ixit.cz:
arch/arm64/boot/dts/qcom/msm8998-mtp.dtb: pmic@2 (qcom,pmi8998): 'fuel-gauge@4000' does not match any of the regexes: '(.*)?(wled|leds)@[0-9a-f]+$', '^adc-tm@[0-9a-f]+$', '^adc@[0-9a-f]+$', '^audio-codec@[0-9a-f]+$', '^battery@[0-9a-f]+$', '^charger@[0-9a-f]+$', '^led-controller@[0-9a-f]+$', '^mpps@[0-9a-f]+$', '^nvram@[0-9a-f]+$', '^pbs@[0-9a-f]+$', '^pinctrl-[0-9]+$', '^rtc@[0-9a-f]+$', '^temp-alarm@[0-9a-f]+$', '^typec@[0-9a-f]+$', '^usb-detect@[0-9a-f]+$', '^usb-vbus-regulator@[0-9a-f]+$', '^vibrator@[0-9a-f]+$', 'gpio@[0-9a-f]+$', 'phy@[0-9a-f]+$', 'pon@[0-9a-f]+$'
from schema $id: http://devicetree.org/schemas/mfd/qcom,spmi-pmic.yaml
arch/arm64/boot/dts/qcom/msm8998-fxtec-pro1.dtb: pmic@2 (qcom,pmi8998): 'fuel-gauge@4000' does not match any of the regexes: '(.*)?(wled|leds)@[0-9a-f]+$', '^adc-tm@[0-9a-f]+$', '^adc@[0-9a-f]+$', '^audio-codec@[0-9a-f]+$', '^battery@[0-9a-f]+$', '^charger@[0-9a-f]+$', '^led-controller@[0-9a-f]+$', '^mpps@[0-9a-f]+$', '^nvram@[0-9a-f]+$', '^pbs@[0-9a-f]+$', '^pinctrl-[0-9]+$', '^rtc@[0-9a-f]+$', '^temp-alarm@[0-9a-f]+$', '^typec@[0-9a-f]+$', '^usb-detect@[0-9a-f]+$', '^usb-vbus-regulator@[0-9a-f]+$', '^vibrator@[0-9a-f]+$', 'gpio@[0-9a-f]+$', 'phy@[0-9a-f]+$', 'pon@[0-9a-f]+$'
from schema $id: http://devicetree.org/schemas/mfd/qcom,spmi-pmic.yaml
arch/arm64/boot/dts/qcom/msm8998-sony-xperia-yoshino-maple.dtb: pmic@2 (qcom,pmi8998): 'fuel-gauge@4000' does not match any of the regexes: '(.*)?(wled|leds)@[0-9a-f]+$', '^adc-tm@[0-9a-f]+$', '^adc@[0-9a-f]+$', '^audio-codec@[0-9a-f]+$', '^battery@[0-9a-f]+$', '^charger@[0-9a-f]+$', '^led-controller@[0-9a-f]+$', '^mpps@[0-9a-f]+$', '^nvram@[0-9a-f]+$', '^pbs@[0-9a-f]+$', '^pinctrl-[0-9]+$', '^rtc@[0-9a-f]+$', '^temp-alarm@[0-9a-f]+$', '^typec@[0-9a-f]+$', '^usb-detect@[0-9a-f]+$', '^usb-vbus-regulator@[0-9a-f]+$', '^vibrator@[0-9a-f]+$', 'gpio@[0-9a-f]+$', 'phy@[0-9a-f]+$', 'pon@[0-9a-f]+$'
from schema $id: http://devicetree.org/schemas/mfd/qcom,spmi-pmic.yaml
arch/arm64/boot/dts/qcom/sdm630-sony-xperia-ganges-kirin.dtb: pmic@0 (qcom,pm660): 'fuel-gauge@4000' does not match any of the regexes: '(.*)?(wled|leds)@[0-9a-f]+$', '^adc-tm@[0-9a-f]+$', '^adc@[0-9a-f]+$', '^audio-codec@[0-9a-f]+$', '^battery@[0-9a-f]+$', '^charger@[0-9a-f]+$', '^led-controller@[0-9a-f]+$', '^mpps@[0-9a-f]+$', '^nvram@[0-9a-f]+$', '^pbs@[0-9a-f]+$', '^pinctrl-[0-9]+$', '^rtc@[0-9a-f]+$', '^temp-alarm@[0-9a-f]+$', '^typec@[0-9a-f]+$', '^usb-detect@[0-9a-f]+$', '^usb-vbus-regulator@[0-9a-f]+$', '^vibrator@[0-9a-f]+$', 'gpio@[0-9a-f]+$', 'phy@[0-9a-f]+$', 'pon@[0-9a-f]+$'
from schema $id: http://devicetree.org/schemas/mfd/qcom,spmi-pmic.yaml
arch/arm64/boot/dts/qcom/sdm845-lg-judyp.dtb: pmic@2 (qcom,pmi8998): 'fuel-gauge@4000' does not match any of the regexes: '(.*)?(wled|leds)@[0-9a-f]+$', '^adc-tm@[0-9a-f]+$', '^adc@[0-9a-f]+$', '^audio-codec@[0-9a-f]+$', '^battery@[0-9a-f]+$', '^charger@[0-9a-f]+$', '^led-controller@[0-9a-f]+$', '^mpps@[0-9a-f]+$', '^nvram@[0-9a-f]+$', '^pbs@[0-9a-f]+$', '^pinctrl-[0-9]+$', '^rtc@[0-9a-f]+$', '^temp-alarm@[0-9a-f]+$', '^typec@[0-9a-f]+$', '^usb-detect@[0-9a-f]+$', '^usb-vbus-regulator@[0-9a-f]+$', '^vibrator@[0-9a-f]+$', 'gpio@[0-9a-f]+$', 'phy@[0-9a-f]+$', 'pon@[0-9a-f]+$'
from schema $id: http://devicetree.org/schemas/mfd/qcom,spmi-pmic.yaml
arch/arm64/boot/dts/qcom/sdm630-sony-xperia-nile-discovery.dtb: pmic@0 (qcom,pm660): 'fuel-gauge@4000' does not match any of the regexes: '(.*)?(wled|leds)@[0-9a-f]+$', '^adc-tm@[0-9a-f]+$', '^adc@[0-9a-f]+$', '^audio-codec@[0-9a-f]+$', '^battery@[0-9a-f]+$', '^charger@[0-9a-f]+$', '^led-controller@[0-9a-f]+$', '^mpps@[0-9a-f]+$', '^nvram@[0-9a-f]+$', '^pbs@[0-9a-f]+$', '^pinctrl-[0-9]+$', '^rtc@[0-9a-f]+$', '^temp-alarm@[0-9a-f]+$', '^typec@[0-9a-f]+$', '^usb-detect@[0-9a-f]+$', '^usb-vbus-regulator@[0-9a-f]+$', '^vibrator@[0-9a-f]+$', 'gpio@[0-9a-f]+$', 'phy@[0-9a-f]+$', 'pon@[0-9a-f]+$'
from schema $id: http://devicetree.org/schemas/mfd/qcom,spmi-pmic.yaml
arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dtb: pmic@0 (qcom,pm660): 'fuel-gauge@4000' does not match any of the regexes: '(.*)?(wled|leds)@[0-9a-f]+$', '^adc-tm@[0-9a-f]+$', '^adc@[0-9a-f]+$', '^audio-codec@[0-9a-f]+$', '^battery@[0-9a-f]+$', '^charger@[0-9a-f]+$', '^led-controller@[0-9a-f]+$', '^mpps@[0-9a-f]+$', '^nvram@[0-9a-f]+$', '^pbs@[0-9a-f]+$', '^pinctrl-[0-9]+$', '^rtc@[0-9a-f]+$', '^temp-alarm@[0-9a-f]+$', '^typec@[0-9a-f]+$', '^usb-detect@[0-9a-f]+$', '^usb-vbus-regulator@[0-9a-f]+$', '^vibrator@[0-9a-f]+$', 'gpio@[0-9a-f]+$', 'phy@[0-9a-f]+$', 'pon@[0-9a-f]+$'
from schema $id: http://devicetree.org/schemas/mfd/qcom,spmi-pmic.yaml
arch/arm64/boot/dts/qcom/sdm845-oneplus-fajita.dtb: pmic@2 (qcom,pmi8998): 'fuel-gauge@4000' does not match any of the regexes: '(.*)?(wled|leds)@[0-9a-f]+$', '^adc-tm@[0-9a-f]+$', '^adc@[0-9a-f]+$', '^audio-codec@[0-9a-f]+$', '^battery@[0-9a-f]+$', '^charger@[0-9a-f]+$', '^led-controller@[0-9a-f]+$', '^mpps@[0-9a-f]+$', '^nvram@[0-9a-f]+$', '^pbs@[0-9a-f]+$', '^pinctrl-[0-9]+$', '^rtc@[0-9a-f]+$', '^temp-alarm@[0-9a-f]+$', '^typec@[0-9a-f]+$', '^usb-detect@[0-9a-f]+$', '^usb-vbus-regulator@[0-9a-f]+$', '^vibrator@[0-9a-f]+$', 'gpio@[0-9a-f]+$', 'phy@[0-9a-f]+$', 'pon@[0-9a-f]+$'
from schema $id: http://devicetree.org/schemas/mfd/qcom,spmi-pmic.yaml
arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama-akari.dtb: pmic@2 (qcom,pmi8998): 'fuel-gauge@4000' does not match any of the regexes: '(.*)?(wled|leds)@[0-9a-f]+$', '^adc-tm@[0-9a-f]+$', '^adc@[0-9a-f]+$', '^audio-codec@[0-9a-f]+$', '^battery@[0-9a-f]+$', '^charger@[0-9a-f]+$', '^led-controller@[0-9a-f]+$', '^mpps@[0-9a-f]+$', '^nvram@[0-9a-f]+$', '^pbs@[0-9a-f]+$', '^pinctrl-[0-9]+$', '^rtc@[0-9a-f]+$', '^temp-alarm@[0-9a-f]+$', '^typec@[0-9a-f]+$', '^usb-detect@[0-9a-f]+$', '^usb-vbus-regulator@[0-9a-f]+$', '^vibrator@[0-9a-f]+$', 'gpio@[0-9a-f]+$', 'phy@[0-9a-f]+$', 'pon@[0-9a-f]+$'
from schema $id: http://devicetree.org/schemas/mfd/qcom,spmi-pmic.yaml
arch/arm64/boot/dts/qcom/msm8998-xiaomi-sagit.dtb: pmic@2 (qcom,pmi8998): 'fuel-gauge@4000' does not match any of the regexes: '(.*)?(wled|leds)@[0-9a-f]+$', '^adc-tm@[0-9a-f]+$', '^adc@[0-9a-f]+$', '^audio-codec@[0-9a-f]+$', '^battery@[0-9a-f]+$', '^charger@[0-9a-f]+$', '^led-controller@[0-9a-f]+$', '^mpps@[0-9a-f]+$', '^nvram@[0-9a-f]+$', '^pbs@[0-9a-f]+$', '^pinctrl-[0-9]+$', '^rtc@[0-9a-f]+$', '^temp-alarm@[0-9a-f]+$', '^typec@[0-9a-f]+$', '^usb-detect@[0-9a-f]+$', '^usb-vbus-regulator@[0-9a-f]+$', '^vibrator@[0-9a-f]+$', 'gpio@[0-9a-f]+$', 'phy@[0-9a-f]+$', 'pon@[0-9a-f]+$'
from schema $id: http://devicetree.org/schemas/mfd/qcom,spmi-pmic.yaml
arch/arm64/boot/dts/qcom/sdm670-google-sargo.dtb: pmic@0 (qcom,pm660): 'fuel-gauge@4000' does not match any of the regexes: '(.*)?(wled|leds)@[0-9a-f]+$', '^adc-tm@[0-9a-f]+$', '^adc@[0-9a-f]+$', '^audio-codec@[0-9a-f]+$', '^battery@[0-9a-f]+$', '^charger@[0-9a-f]+$', '^led-controller@[0-9a-f]+$', '^mpps@[0-9a-f]+$', '^nvram@[0-9a-f]+$', '^pbs@[0-9a-f]+$', '^pinctrl-[0-9]+$', '^rtc@[0-9a-f]+$', '^temp-alarm@[0-9a-f]+$', '^typec@[0-9a-f]+$', '^usb-detect@[0-9a-f]+$', '^usb-vbus-regulator@[0-9a-f]+$', '^vibrator@[0-9a-f]+$', 'gpio@[0-9a-f]+$', 'phy@[0-9a-f]+$', 'pon@[0-9a-f]+$'
from schema $id: http://devicetree.org/schemas/mfd/qcom,spmi-pmic.yaml
arch/arm64/boot/dts/qcom/sdm845-lg-judyln.dtb: pmic@2 (qcom,pmi8998): 'fuel-gauge@4000' does not match any of the regexes: '(.*)?(wled|leds)@[0-9a-f]+$', '^adc-tm@[0-9a-f]+$', '^adc@[0-9a-f]+$', '^audio-codec@[0-9a-f]+$', '^battery@[0-9a-f]+$', '^charger@[0-9a-f]+$', '^led-controller@[0-9a-f]+$', '^mpps@[0-9a-f]+$', '^nvram@[0-9a-f]+$', '^pbs@[0-9a-f]+$', '^pinctrl-[0-9]+$', '^rtc@[0-9a-f]+$', '^temp-alarm@[0-9a-f]+$', '^typec@[0-9a-f]+$', '^usb-detect@[0-9a-f]+$', '^usb-vbus-regulator@[0-9a-f]+$', '^vibrator@[0-9a-f]+$', 'gpio@[0-9a-f]+$', 'phy@[0-9a-f]+$', 'pon@[0-9a-f]+$'
from schema $id: http://devicetree.org/schemas/mfd/qcom,spmi-pmic.yaml
arch/arm64/boot/dts/qcom/sdm845-oneplus-enchilada.dtb: pmic@2 (qcom,pmi8998): 'fuel-gauge@4000' does not match any of the regexes: '(.*)?(wled|leds)@[0-9a-f]+$', '^adc-tm@[0-9a-f]+$', '^adc@[0-9a-f]+$', '^audio-codec@[0-9a-f]+$', '^battery@[0-9a-f]+$', '^charger@[0-9a-f]+$', '^led-controller@[0-9a-f]+$', '^mpps@[0-9a-f]+$', '^nvram@[0-9a-f]+$', '^pbs@[0-9a-f]+$', '^pinctrl-[0-9]+$', '^rtc@[0-9a-f]+$', '^temp-alarm@[0-9a-f]+$', '^typec@[0-9a-f]+$', '^usb-detect@[0-9a-f]+$', '^usb-vbus-regulator@[0-9a-f]+$', '^vibrator@[0-9a-f]+$', 'gpio@[0-9a-f]+$', 'phy@[0-9a-f]+$', 'pon@[0-9a-f]+$'
from schema $id: http://devicetree.org/schemas/mfd/qcom,spmi-pmic.yaml
arch/arm64/boot/dts/qcom/sdm630-sony-xperia-nile-pioneer.dtb: pmic@0 (qcom,pm660): 'fuel-gauge@4000' does not match any of the regexes: '(.*)?(wled|leds)@[0-9a-f]+$', '^adc-tm@[0-9a-f]+$', '^adc@[0-9a-f]+$', '^audio-codec@[0-9a-f]+$', '^battery@[0-9a-f]+$', '^charger@[0-9a-f]+$', '^led-controller@[0-9a-f]+$', '^mpps@[0-9a-f]+$', '^nvram@[0-9a-f]+$', '^pbs@[0-9a-f]+$', '^pinctrl-[0-9]+$', '^rtc@[0-9a-f]+$', '^temp-alarm@[0-9a-f]+$', '^typec@[0-9a-f]+$', '^usb-detect@[0-9a-f]+$', '^usb-vbus-regulator@[0-9a-f]+$', '^vibrator@[0-9a-f]+$', 'gpio@[0-9a-f]+$', 'phy@[0-9a-f]+$', 'pon@[0-9a-f]+$'
from schema $id: http://devicetree.org/schemas/mfd/qcom,spmi-pmic.yaml
arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama-apollo.dtb: pmic@2 (qcom,pmi8998): 'fuel-gauge@4000' does not match any of the regexes: '(.*)?(wled|leds)@[0-9a-f]+$', '^adc-tm@[0-9a-f]+$', '^adc@[0-9a-f]+$', '^audio-codec@[0-9a-f]+$', '^battery@[0-9a-f]+$', '^charger@[0-9a-f]+$', '^led-controller@[0-9a-f]+$', '^mpps@[0-9a-f]+$', '^nvram@[0-9a-f]+$', '^pbs@[0-9a-f]+$', '^pinctrl-[0-9]+$', '^rtc@[0-9a-f]+$', '^temp-alarm@[0-9a-f]+$', '^typec@[0-9a-f]+$', '^usb-detect@[0-9a-f]+$', '^usb-vbus-regulator@[0-9a-f]+$', '^vibrator@[0-9a-f]+$', 'gpio@[0-9a-f]+$', 'phy@[0-9a-f]+$', 'pon@[0-9a-f]+$'
from schema $id: http://devicetree.org/schemas/mfd/qcom,spmi-pmic.yaml
arch/arm64/boot/dts/qcom/sdm845-mtp.dtb: pmic@2 (qcom,pmi8998): 'fuel-gauge@4000' does not match any of the regexes: '(.*)?(wled|leds)@[0-9a-f]+$', '^adc-tm@[0-9a-f]+$', '^adc@[0-9a-f]+$', '^audio-codec@[0-9a-f]+$', '^battery@[0-9a-f]+$', '^charger@[0-9a-f]+$', '^led-controller@[0-9a-f]+$', '^mpps@[0-9a-f]+$', '^nvram@[0-9a-f]+$', '^pbs@[0-9a-f]+$', '^pinctrl-[0-9]+$', '^rtc@[0-9a-f]+$', '^temp-alarm@[0-9a-f]+$', '^typec@[0-9a-f]+$', '^usb-detect@[0-9a-f]+$', '^usb-vbus-regulator@[0-9a-f]+$', '^vibrator@[0-9a-f]+$', 'gpio@[0-9a-f]+$', 'phy@[0-9a-f]+$', 'pon@[0-9a-f]+$'
from schema $id: http://devicetree.org/schemas/mfd/qcom,spmi-pmic.yaml
arch/arm64/boot/dts/qcom/msm8998-sony-xperia-yoshino-lilac.dtb: pmic@2 (qcom,pmi8998): 'fuel-gauge@4000' does not match any of the regexes: '(.*)?(wled|leds)@[0-9a-f]+$', '^adc-tm@[0-9a-f]+$', '^adc@[0-9a-f]+$', '^audio-codec@[0-9a-f]+$', '^battery@[0-9a-f]+$', '^charger@[0-9a-f]+$', '^led-controller@[0-9a-f]+$', '^mpps@[0-9a-f]+$', '^nvram@[0-9a-f]+$', '^pbs@[0-9a-f]+$', '^pinctrl-[0-9]+$', '^rtc@[0-9a-f]+$', '^temp-alarm@[0-9a-f]+$', '^typec@[0-9a-f]+$', '^usb-detect@[0-9a-f]+$', '^usb-vbus-regulator@[0-9a-f]+$', '^vibrator@[0-9a-f]+$', 'gpio@[0-9a-f]+$', 'phy@[0-9a-f]+$', 'pon@[0-9a-f]+$'
from schema $id: http://devicetree.org/schemas/mfd/qcom,spmi-pmic.yaml
arch/arm64/boot/dts/qcom/sdm845-shift-axolotl.dtb: pmic@2 (qcom,pmi8998): 'fuel-gauge@4000' does not match any of the regexes: '(.*)?(wled|leds)@[0-9a-f]+$', '^adc-tm@[0-9a-f]+$', '^adc@[0-9a-f]+$', '^audio-codec@[0-9a-f]+$', '^battery@[0-9a-f]+$', '^charger@[0-9a-f]+$', '^led-controller@[0-9a-f]+$', '^mpps@[0-9a-f]+$', '^nvram@[0-9a-f]+$', '^pbs@[0-9a-f]+$', '^pinctrl-[0-9]+$', '^rtc@[0-9a-f]+$', '^temp-alarm@[0-9a-f]+$', '^typec@[0-9a-f]+$', '^usb-detect@[0-9a-f]+$', '^usb-vbus-regulator@[0-9a-f]+$', '^vibrator@[0-9a-f]+$', 'gpio@[0-9a-f]+$', 'phy@[0-9a-f]+$', 'pon@[0-9a-f]+$'
from schema $id: http://devicetree.org/schemas/mfd/qcom,spmi-pmic.yaml
arch/arm64/boot/dts/qcom/sdm630-sony-xperia-nile-voyager.dtb: pmic@0 (qcom,pm660): 'fuel-gauge@4000' does not match any of the regexes: '(.*)?(wled|leds)@[0-9a-f]+$', '^adc-tm@[0-9a-f]+$', '^adc@[0-9a-f]+$', '^audio-codec@[0-9a-f]+$', '^battery@[0-9a-f]+$', '^charger@[0-9a-f]+$', '^led-controller@[0-9a-f]+$', '^mpps@[0-9a-f]+$', '^nvram@[0-9a-f]+$', '^pbs@[0-9a-f]+$', '^pinctrl-[0-9]+$', '^rtc@[0-9a-f]+$', '^temp-alarm@[0-9a-f]+$', '^typec@[0-9a-f]+$', '^usb-detect@[0-9a-f]+$', '^usb-vbus-regulator@[0-9a-f]+$', '^vibrator@[0-9a-f]+$', 'gpio@[0-9a-f]+$', 'phy@[0-9a-f]+$', 'pon@[0-9a-f]+$'
from schema $id: http://devicetree.org/schemas/mfd/qcom,spmi-pmic.yaml
arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama-akatsuki.dtb: pmic@2 (qcom,pmi8998): 'fuel-gauge@4000' does not match any of the regexes: '(.*)?(wled|leds)@[0-9a-f]+$', '^adc-tm@[0-9a-f]+$', '^adc@[0-9a-f]+$', '^audio-codec@[0-9a-f]+$', '^battery@[0-9a-f]+$', '^charger@[0-9a-f]+$', '^led-controller@[0-9a-f]+$', '^mpps@[0-9a-f]+$', '^nvram@[0-9a-f]+$', '^pbs@[0-9a-f]+$', '^pinctrl-[0-9]+$', '^rtc@[0-9a-f]+$', '^temp-alarm@[0-9a-f]+$', '^typec@[0-9a-f]+$', '^usb-detect@[0-9a-f]+$', '^usb-vbus-regulator@[0-9a-f]+$', '^vibrator@[0-9a-f]+$', 'gpio@[0-9a-f]+$', 'phy@[0-9a-f]+$', 'pon@[0-9a-f]+$'
from schema $id: http://devicetree.org/schemas/mfd/qcom,spmi-pmic.yaml
arch/arm64/boot/dts/qcom/msm8998-oneplus-dumpling.dtb: pmic@2 (qcom,pmi8998): 'fuel-gauge@4000' does not match any of the regexes: '(.*)?(wled|leds)@[0-9a-f]+$', '^adc-tm@[0-9a-f]+$', '^adc@[0-9a-f]+$', '^audio-codec@[0-9a-f]+$', '^battery@[0-9a-f]+$', '^charger@[0-9a-f]+$', '^led-controller@[0-9a-f]+$', '^mpps@[0-9a-f]+$', '^nvram@[0-9a-f]+$', '^pbs@[0-9a-f]+$', '^pinctrl-[0-9]+$', '^rtc@[0-9a-f]+$', '^temp-alarm@[0-9a-f]+$', '^typec@[0-9a-f]+$', '^usb-detect@[0-9a-f]+$', '^usb-vbus-regulator@[0-9a-f]+$', '^vibrator@[0-9a-f]+$', 'gpio@[0-9a-f]+$', 'phy@[0-9a-f]+$', 'pon@[0-9a-f]+$'
from schema $id: http://devicetree.org/schemas/mfd/qcom,spmi-pmic.yaml
arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium-ebbg.dtb: pmic@2 (qcom,pmi8998): 'fuel-gauge@4000' does not match any of the regexes: '(.*)?(wled|leds)@[0-9a-f]+$', '^adc-tm@[0-9a-f]+$', '^adc@[0-9a-f]+$', '^audio-codec@[0-9a-f]+$', '^battery@[0-9a-f]+$', '^charger@[0-9a-f]+$', '^led-controller@[0-9a-f]+$', '^mpps@[0-9a-f]+$', '^nvram@[0-9a-f]+$', '^pbs@[0-9a-f]+$', '^pinctrl-[0-9]+$', '^rtc@[0-9a-f]+$', '^temp-alarm@[0-9a-f]+$', '^typec@[0-9a-f]+$', '^usb-detect@[0-9a-f]+$', '^usb-vbus-regulator@[0-9a-f]+$', '^vibrator@[0-9a-f]+$', 'gpio@[0-9a-f]+$', 'phy@[0-9a-f]+$', 'pon@[0-9a-f]+$'
from schema $id: http://devicetree.org/schemas/mfd/qcom,spmi-pmic.yaml
arch/arm64/boot/dts/qcom/sda660-inforce-ifc6560.dtb: pmic@0 (qcom,pm660): 'fuel-gauge@4000' does not match any of the regexes: '(.*)?(wled|leds)@[0-9a-f]+$', '^adc-tm@[0-9a-f]+$', '^adc@[0-9a-f]+$', '^audio-codec@[0-9a-f]+$', '^battery@[0-9a-f]+$', '^charger@[0-9a-f]+$', '^led-controller@[0-9a-f]+$', '^mpps@[0-9a-f]+$', '^nvram@[0-9a-f]+$', '^pbs@[0-9a-f]+$', '^pinctrl-[0-9]+$', '^rtc@[0-9a-f]+$', '^temp-alarm@[0-9a-f]+$', '^typec@[0-9a-f]+$', '^usb-detect@[0-9a-f]+$', '^usb-vbus-regulator@[0-9a-f]+$', '^vibrator@[0-9a-f]+$', 'gpio@[0-9a-f]+$', 'phy@[0-9a-f]+$', 'pon@[0-9a-f]+$'
from schema $id: http://devicetree.org/schemas/mfd/qcom,spmi-pmic.yaml
arch/arm64/boot/dts/qcom/msm8998-sony-xperia-yoshino-poplar.dtb: pmic@2 (qcom,pmi8998): 'fuel-gauge@4000' does not match any of the regexes: '(.*)?(wled|leds)@[0-9a-f]+$', '^adc-tm@[0-9a-f]+$', '^adc@[0-9a-f]+$', '^audio-codec@[0-9a-f]+$', '^battery@[0-9a-f]+$', '^charger@[0-9a-f]+$', '^led-controller@[0-9a-f]+$', '^mpps@[0-9a-f]+$', '^nvram@[0-9a-f]+$', '^pbs@[0-9a-f]+$', '^pinctrl-[0-9]+$', '^rtc@[0-9a-f]+$', '^temp-alarm@[0-9a-f]+$', '^typec@[0-9a-f]+$', '^usb-detect@[0-9a-f]+$', '^usb-vbus-regulator@[0-9a-f]+$', '^vibrator@[0-9a-f]+$', 'gpio@[0-9a-f]+$', 'phy@[0-9a-f]+$', 'pon@[0-9a-f]+$'
from schema $id: http://devicetree.org/schemas/mfd/qcom,spmi-pmic.yaml
arch/arm64/boot/dts/qcom/sdm845-db845c.dtb: pmic@2 (qcom,pmi8998): 'fuel-gauge@4000' does not match any of the regexes: '(.*)?(wled|leds)@[0-9a-f]+$', '^adc-tm@[0-9a-f]+$', '^adc@[0-9a-f]+$', '^audio-codec@[0-9a-f]+$', '^battery@[0-9a-f]+$', '^charger@[0-9a-f]+$', '^led-controller@[0-9a-f]+$', '^mpps@[0-9a-f]+$', '^nvram@[0-9a-f]+$', '^pbs@[0-9a-f]+$', '^pinctrl-[0-9]+$', '^rtc@[0-9a-f]+$', '^temp-alarm@[0-9a-f]+$', '^typec@[0-9a-f]+$', '^usb-detect@[0-9a-f]+$', '^usb-vbus-regulator@[0-9a-f]+$', '^vibrator@[0-9a-f]+$', 'gpio@[0-9a-f]+$', 'phy@[0-9a-f]+$', 'pon@[0-9a-f]+$'
from schema $id: http://devicetree.org/schemas/mfd/qcom,spmi-pmic.yaml
arch/arm64/boot/dts/qcom/msm8998-oneplus-cheeseburger.dtb: pmic@2 (qcom,pmi8998): 'fuel-gauge@4000' does not match any of the regexes: '(.*)?(wled|leds)@[0-9a-f]+$', '^adc-tm@[0-9a-f]+$', '^adc@[0-9a-f]+$', '^audio-codec@[0-9a-f]+$', '^battery@[0-9a-f]+$', '^charger@[0-9a-f]+$', '^led-controller@[0-9a-f]+$', '^mpps@[0-9a-f]+$', '^nvram@[0-9a-f]+$', '^pbs@[0-9a-f]+$', '^pinctrl-[0-9]+$', '^rtc@[0-9a-f]+$', '^temp-alarm@[0-9a-f]+$', '^typec@[0-9a-f]+$', '^usb-detect@[0-9a-f]+$', '^usb-vbus-regulator@[0-9a-f]+$', '^vibrator@[0-9a-f]+$', 'gpio@[0-9a-f]+$', 'phy@[0-9a-f]+$', 'pon@[0-9a-f]+$'
from schema $id: http://devicetree.org/schemas/mfd/qcom,spmi-pmic.yaml
arch/arm64/boot/dts/qcom/sdm636-sony-xperia-ganges-mermaid.dtb: pmic@0 (qcom,pm660): 'fuel-gauge@4000' does not match any of the regexes: '(.*)?(wled|leds)@[0-9a-f]+$', '^adc-tm@[0-9a-f]+$', '^adc@[0-9a-f]+$', '^audio-codec@[0-9a-f]+$', '^battery@[0-9a-f]+$', '^charger@[0-9a-f]+$', '^led-controller@[0-9a-f]+$', '^mpps@[0-9a-f]+$', '^nvram@[0-9a-f]+$', '^pbs@[0-9a-f]+$', '^pinctrl-[0-9]+$', '^rtc@[0-9a-f]+$', '^temp-alarm@[0-9a-f]+$', '^typec@[0-9a-f]+$', '^usb-detect@[0-9a-f]+$', '^usb-vbus-regulator@[0-9a-f]+$', '^vibrator@[0-9a-f]+$', 'gpio@[0-9a-f]+$', 'phy@[0-9a-f]+$', 'pon@[0-9a-f]+$'
from schema $id: http://devicetree.org/schemas/mfd/qcom,spmi-pmic.yaml
arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium-tianma.dtb: pmic@2 (qcom,pmi8998): 'fuel-gauge@4000' does not match any of the regexes: '(.*)?(wled|leds)@[0-9a-f]+$', '^adc-tm@[0-9a-f]+$', '^adc@[0-9a-f]+$', '^audio-codec@[0-9a-f]+$', '^battery@[0-9a-f]+$', '^charger@[0-9a-f]+$', '^led-controller@[0-9a-f]+$', '^mpps@[0-9a-f]+$', '^nvram@[0-9a-f]+$', '^pbs@[0-9a-f]+$', '^pinctrl-[0-9]+$', '^rtc@[0-9a-f]+$', '^temp-alarm@[0-9a-f]+$', '^typec@[0-9a-f]+$', '^usb-detect@[0-9a-f]+$', '^usb-vbus-regulator@[0-9a-f]+$', '^vibrator@[0-9a-f]+$', 'gpio@[0-9a-f]+$', 'phy@[0-9a-f]+$', 'pon@[0-9a-f]+$'
from schema $id: http://devicetree.org/schemas/mfd/qcom,spmi-pmic.yaml
arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dtb: pmic@2 (qcom,pmi8998): 'fuel-gauge@4000' does not match any of the regexes: '(.*)?(wled|leds)@[0-9a-f]+$', '^adc-tm@[0-9a-f]+$', '^adc@[0-9a-f]+$', '^audio-codec@[0-9a-f]+$', '^battery@[0-9a-f]+$', '^charger@[0-9a-f]+$', '^led-controller@[0-9a-f]+$', '^mpps@[0-9a-f]+$', '^nvram@[0-9a-f]+$', '^pbs@[0-9a-f]+$', '^pinctrl-[0-9]+$', '^rtc@[0-9a-f]+$', '^temp-alarm@[0-9a-f]+$', '^typec@[0-9a-f]+$', '^usb-detect@[0-9a-f]+$', '^usb-vbus-regulator@[0-9a-f]+$', '^vibrator@[0-9a-f]+$', 'gpio@[0-9a-f]+$', 'phy@[0-9a-f]+$', 'pon@[0-9a-f]+$'
from schema $id: http://devicetree.org/schemas/mfd/qcom,spmi-pmic.yaml
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH RFC 2/8] power: supply: Add driver for Qualcomm PMI8998 fuel gauge
2025-11-24 21:53 ` [PATCH RFC 2/8] power: supply: Add driver for Qualcomm PMI8998 " David Heidelberg via B4 Relay
@ 2025-11-25 23:13 ` Dmitry Baryshkov
2025-11-26 16:35 ` Joel Selvaraj
2025-11-27 15:28 ` Konrad Dybcio
1 sibling, 1 reply; 24+ messages in thread
From: Dmitry Baryshkov @ 2025-11-25 23:13 UTC (permalink / raw)
To: david
Cc: Sebastian Reichel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Casey Connolly, Casey Connolly, Joel Selvaraj, Yassine Oudjana,
Bjorn Andersson, Konrad Dybcio, Alexander Martinz,
Barnabás Czémán, Richard Acayan,
Alexey Minnekhanov, linux-pm, devicetree, linux-kernel,
linux-arm-msm, phone-devel
On Mon, Nov 24, 2025 at 10:53:35PM +0100, David Heidelberg via B4 Relay wrote:
> From: Joel Selvaraj <foss@joelselvaraj.com>
>
> Ths driver supports the fuel gauge hardware available on PMICs known as
> 3rd generation fuel gauge hardware available on PMI8998.
>
> Co-developed-by: Casey Connolly <casey@connolly.tech>
> Co-developed-by: Barnabás Czémán <barnabas.czeman@mainlining.org>
> Signed-off-by: Barnabás Czémán <barnabas.czeman@mainlining.org>
> Co-developed-by: Yassine Oudjana <y.oudjana@protonmail.com>
> Signed-off-by: Yassine Oudjana <y.oudjana@protonmail.com>
> Signed-off-by: David Heidelberg <david@ixit.cz>
This can't be applied, there is no author's (Joel Selvaraj) SoB.
> ---
> drivers/power/supply/Kconfig | 8 +
> drivers/power/supply/Makefile | 1 +
> drivers/power/supply/pmi8998_fg.c | 687 ++++++++++++++++++++++++++++++++++++++
> 3 files changed, 696 insertions(+)
>
> diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
> index 92f9f7aae92f2..4024c6fe3fef2 100644
> --- a/drivers/power/supply/Kconfig
> +++ b/drivers/power/supply/Kconfig
> @@ -746,6 +746,14 @@ config CHARGER_PM8916_LBC
> To compile this driver as module, choose M here: the
> module will be called pm8916_lbc.
>
> +config BATTERY_PMI8998_FG
> + tristate "Qualcomm PMI8998 PMIC fuel gauge driver"
> + depends on MFD_SPMI_PMIC
> + help
> + Say Y here to enable the Qualcomm PMI8998 PMIC Fuel Gauge driver.
> + This adds support for battery fuel gauging and state of charge of
> + battery connected to the fuel gauge.
> +
> config CHARGER_BQ2415X
> tristate "TI BQ2415x battery charger driver"
> depends on I2C
> diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile
> index 4b79d5abc49a7..03584efa2b1b0 100644
> --- a/drivers/power/supply/Makefile
> +++ b/drivers/power/supply/Makefile
> @@ -96,6 +96,7 @@ obj-$(CONFIG_CHARGER_MT6370) += mt6370-charger.o
> obj-$(CONFIG_CHARGER_QCOM_SMBB) += qcom_smbb.o
> obj-$(CONFIG_BATTERY_PM8916_BMS_VM) += pm8916_bms_vm.o
> obj-$(CONFIG_CHARGER_PM8916_LBC) += pm8916_lbc.o
> +obj-$(CONFIG_BATTERY_PMI8998_FG) += pmi8998_fg.o
> obj-$(CONFIG_CHARGER_BQ2415X) += bq2415x_charger.o
> obj-$(CONFIG_CHARGER_BQ24190) += bq24190_charger.o
> obj-$(CONFIG_CHARGER_BQ24257) += bq24257_charger.o
> diff --git a/drivers/power/supply/pmi8998_fg.c b/drivers/power/supply/pmi8998_fg.c
> new file mode 100644
> index 0000000000000..d5fccd16a013b
> --- /dev/null
> +++ b/drivers/power/supply/pmi8998_fg.c
> @@ -0,0 +1,687 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/* Copyright (c) 2020, The Linux Foundation. All rights reserved. */
> +
> +#include <linux/device.h>
> +#include <linux/interrupt.h>
> +#include <linux/kernel.h>
> +#include <linux/math64.h>
> +#include <linux/module.h>
> +#include <linux/of_address.h>
> +#include <linux/of_device.h>
> +#include <linux/of_irq.h>
> +#include <linux/platform_device.h>
> +#include <linux/power_supply.h>
> +#include <linux/regmap.h>
> +#include <linux/types.h>
> +#include <linux/workqueue.h>
> +
> +/* SOC */
> +#define BATT_MONOTONIC_SOC 0x009
> +
> +/* BATT */
> +#define PARAM_ADDR_BATT_TEMP 0x150
> +#define BATT_INFO_JEITA_COLD 0x162
> +#define BATT_INFO_JEITA_COOL 0x163
> +#define BATT_INFO_JEITA_WARM 0x164
> +#define BATT_INFO_JEITA_HOT 0x165
> +#define PARAM_ADDR_BATT_VOLTAGE 0x1a0
> +#define PARAM_ADDR_BATT_CURRENT 0x1a2
> +
> +/* MEMIF */
> +#define MEM_INTF_IMA_CFG 0x452
> +#define MEM_INTF_IMA_EXP_STS 0x455
> +#define MEM_INTF_IMA_HW_STS 0x456
> +#define MEM_INTF_IMA_ERR_STS 0x45f
> +#define MEM_INTF_ADDR_LSB 0x461
> +#define MEM_INTF_RD_DATA0 0x467
> +#define MEM_INTF_WR_DATA0 0x463
> +#define MEM_IF_DMA_STS 0x470
> +#define MEM_IF_DMA_CTL 0x471
> +
> +#define BATT_TEMP_LSB_MASK GENMASK(7, 0)
> +#define BATT_TEMP_MSB_MASK GENMASK(2, 0)
> +
> +struct pmi8998_fg_chip {
> + struct device *dev;
> + unsigned int base;
> + struct regmap *regmap;
> + struct notifier_block nb;
> +
> + struct power_supply *batt_psy;
> + struct power_supply *chg_psy;
> + int status;
> + struct delayed_work status_changed_work;
> +};
> +
> +/*
> + * IO functions
> + */
> +
> +/**
> + * @brief pmi8998_fg_read() - Read multiple registers with regmap_bulk_read
Please see Documentation/doc-guide and reforman kerneldoc
appropriately.
> + *
> + * @param chip Pointer to chip
> + * @param val Pointer to read values into
> + * @param addr Address to read from
> + * @param len Number of registers (bytes) to read
> + * @return int 0 on success, negative errno on error
> + */
> +static int pmi8998_fg_read(struct pmi8998_fg_chip *chip, u8 *val, u16 addr, int len)
> +{
> + if (((chip->base + addr) & 0xff00) == 0)
> + return -EINVAL;
A comment would be apprciated
> +
> + dev_vdbg(chip->dev, "%s: Reading 0x%x bytes from 0x%x", __func__, len, addr);
No need to, regmap already has debugging / tracing functionality.
> +
> + return regmap_bulk_read(chip->regmap, chip->base + addr, val, len);
> +}
> +
> +/**
> + * @brief pmi8998_fg_write() - Write multiple registers with regmap_bulk_write
> + *
> + * @param chip Pointer to chip
> + * @param val Pointer to write values from
> + * @param addr Address to write to
> + * @param len Number of registers (bytes) to write
> + * @return int 0 on success, negative errno on error
> + */
> +static int pmi8998_fg_write(struct pmi8998_fg_chip *chip, u8 *val, u16 addr, int len)
> +{
> + bool sec_access = (addr & 0xff) > 0xd0;
> + u8 sec_addr_val = 0xa5;
> + int ret;
> +
> + if (((chip->base + addr) & 0xff00) == 0)
> + return -EINVAL;
> +
> + dev_vdbg(chip->dev, "%s: Writing 0x%x to 0x%x", __func__, *val, addr);
> +
> + if (sec_access) {
> + ret = regmap_bulk_write(chip->regmap,
> + ((chip->base + addr) & 0xff00) | 0xd0,
> + &sec_addr_val, 1);
Isn't it required to lock it again?
> + if (ret)
> + return ret;
> + }
> +
> + return regmap_bulk_write(chip->regmap, chip->base + addr, val, len);
> +}
> +
> +/**
> + * @brief pmi8998_fg_masked_write() - like pmi8998_fg_write but applies
> + * a mask first.
> + *
> + * @param chip Pointer to chip
> + * @param val Pointer to write values from
> + * @param addr Address to write to
> + * @param len Number of registers (bytes) to write
> + * @return int 0 on success, negative errno on error
> + */
> +static int pmi8998_fg_masked_write(struct pmi8998_fg_chip *chip, u16 addr, u8 mask, u8 val)
> +{
> + u8 reg;
> + int ret;
> +
> + ret = pmi8998_fg_read(chip, ®, addr, 1);
> + if (ret)
> + return ret;
> +
> + reg &= ~mask;
> + reg |= val & mask;
> +
> + return pmi8998_fg_write(chip, ®, addr, 1);
regmap_update_bits? Or at least a lock around?
> +}
> +
> +/*
> + * Battery status
> + */
> +
> +/**
> + * @brief pmi8998_fg_get_capacity() - Get remaining capacity of battery
> + *
> + * @param chip Pointer to chip
> + * @param val Pointer to store value at
> + * @return int 0 on success, negative errno on error
> + */
> +static int pmi8998_fg_get_capacity(struct pmi8998_fg_chip *chip, int *val)
> +{
> + u8 cap[2];
> + int ret;
> +
> + ret = pmi8998_fg_read(chip, cap, BATT_MONOTONIC_SOC, 2);
> + if (ret) {
> + dev_err(chip->dev, "Failed to read capacity: %d", ret);
> + return ret;
> + }
> +
> + if (cap[0] != cap[1])
> + cap[0] = cap[0] < cap[1] ? cap[0] : cap[1];
> +
> + *val = DIV_ROUND_CLOSEST((cap[0] - 1) * 98, 0xff - 2) + 1;
> +
> + return 0;
> +}
> +
> +/**
> + * @brief pmi8998_fg_get_temperature() - Get temperature of battery
> + *
> + * @param chip Pointer to chip
> + * @param val Pointer to store value at
> + * @return int 0 on success, negative errno on error
> + */
> +static int pmi8998_fg_get_temperature(struct pmi8998_fg_chip *chip, int *val)
> +{
> + int ret, temp;
> + u8 readval[2];
> +
> + ret = pmi8998_fg_read(chip, readval, PARAM_ADDR_BATT_TEMP, 2);
> + if (ret) {
> + dev_err(chip->dev, "Failed to read temperature: %d\n", ret);
> + return ret;
> + }
> +
> + temp = ((readval[1] & BATT_TEMP_MSB_MASK) << 8) |
> + (readval[0] & BATT_TEMP_LSB_MASK);
> + temp = DIV_ROUND_CLOSEST(temp * 10, 4);
> +
> + *val = temp - 2730;
> +
> + return 0;
> +}
> +
> +/**
> + * @brief pmi8998_fg_get_current() - Get current being drawn from battery
> + *
> + * @param chip Pointer to chip
> + * @param val Pointer to store value at
> + * @return int 0 on success, negative errno on error
> + */
> +static int pmi8998_fg_get_current(struct pmi8998_fg_chip *chip, int *val)
> +{
> + s16 temp;
> + u8 readval[2];
> + int ret;
> +
> + ret = pmi8998_fg_read(chip, readval, PARAM_ADDR_BATT_CURRENT, 2);
> + if (ret) {
> + dev_err(chip->dev, "Failed to read current: %d\n", ret);
> + return ret;
> + }
> +
> + /* handle rev 1 too */
> + temp = (s16)(readval[1] << 8 | readval[0]);
> + *val = div_s64((s64)temp * 488281, 1000);
> +
> + /*
> + * PSY API expects charging batteries to report a positive current, which is inverted
> + * to what the PMIC reports.
> + */
> + *val = -*val;
> +
> + return 0;
> +}
> +
> +/**
> + * @brief pmi8998_fg_get_voltage() - Get voltage of battery
> + *
> + * @param chip Pointer to chip
> + * @param val Pointer to store value at
> + * @return int 0 on success, negative errno on error
> + */
> +static int pmi8998_fg_get_voltage(struct pmi8998_fg_chip *chip, int *val)
> +{
> + int temp;
> + u8 readval[2];
> + int ret;
> +
> + ret = pmi8998_fg_read(chip, readval, PARAM_ADDR_BATT_VOLTAGE, 2);
> + if (ret) {
> + dev_err(chip->dev, "Failed to read voltage: %d\n", ret);
> + return ret;
> + }
> +
> + /* handle rev 1 too */
> + temp = readval[1] << 8 | readval[0];
> + *val = div_u64((u64)temp * 122070, 1000);
> +
> + return 0;
> +}
> +
> +/**
> + * @brief pmi8998_fg_get_temp_threshold() - Get configured temperature thresholds
> + *
> + * @param chip Pointer to chip
> + * @param psp Power supply property of temperature limit
> + * @param val Pointer to store value at
> + * @return int 0 on success, negative errno on error
> + */
> +static int pmi8998_fg_get_temp_threshold(struct pmi8998_fg_chip *chip,
> + enum power_supply_property psp, int *val)
> +{
> + u8 temp;
> + u16 reg;
> + int ret;
> +
> + switch (psp) {
> + case POWER_SUPPLY_PROP_TEMP_MIN:
> + reg = BATT_INFO_JEITA_COLD;
> + break;
> + case POWER_SUPPLY_PROP_TEMP_MAX:
> + reg = BATT_INFO_JEITA_HOT;
> + break;
> + case POWER_SUPPLY_PROP_TEMP_ALERT_MIN:
> + reg = BATT_INFO_JEITA_COOL;
> + break;
> + case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
> + reg = BATT_INFO_JEITA_WARM;
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + ret = pmi8998_fg_read(chip, &temp, reg, 1);
> + if (ret < 0) {
> + dev_err(chip->dev, "Failed to read JEITA property %d level: %d\n", psp, ret);
> + return ret;
> + }
> +
> + /* Resolution is 0.5C. Base is -30C. */
> + *val = (((5 * temp) / 10) - 30) * 10;
> +
> + return 0;
> +}
> +
> +/*
> + * Battery power supply
> + */
> +
> +static enum power_supply_property pmi8998_fg_props[] = {
> + POWER_SUPPLY_PROP_STATUS,
> + POWER_SUPPLY_PROP_TECHNOLOGY,
> + POWER_SUPPLY_PROP_CAPACITY,
> + POWER_SUPPLY_PROP_CURRENT_NOW,
> + POWER_SUPPLY_PROP_VOLTAGE_NOW,
> + POWER_SUPPLY_PROP_PRESENT,
> + POWER_SUPPLY_PROP_TEMP,
> + POWER_SUPPLY_PROP_TEMP_MIN,
> + POWER_SUPPLY_PROP_TEMP_MAX,
> + POWER_SUPPLY_PROP_TEMP_ALERT_MIN,
> + POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
> +};
> +
> +static int pmi8998_fg_get_property(struct power_supply *psy,
> + enum power_supply_property psp,
> + union power_supply_propval *val)
> +{
> + struct pmi8998_fg_chip *chip = power_supply_get_drvdata(psy);
> + int temp, ret = 0;
> +
> + dev_dbg(chip->dev, "Getting property: %d", psp);
> +
> + switch (psp) {
> + case POWER_SUPPLY_PROP_STATUS:
> + /* Get status from charger if available */
> + if (chip->chg_psy &&
> + chip->status != POWER_SUPPLY_STATUS_UNKNOWN) {
> + val->intval = chip->status;
return 0;
drop else
> + } else {
> + /*
> + * Fall back to capacity and current-based
> + * status checking
> + */
> + ret = pmi8998_fg_get_capacity(chip, &temp);
> + if (ret) {
> + val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
> + break;
> + }
> + if (temp == 100) {
> + val->intval = POWER_SUPPLY_STATUS_FULL;
> + break;
> + }
> +
> + ret = pmi8998_fg_get_current(chip, &temp);
> + if (ret) {
> + val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
> + break;
> + }
> + if (temp < 0)
> + val->intval = POWER_SUPPLY_STATUS_CHARGING;
> + else if (temp > 0)
> + val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
> + else
> + val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
> + }
> +
> + break;
> + case POWER_SUPPLY_PROP_TECHNOLOGY:
> + val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
> + break;
> + case POWER_SUPPLY_PROP_CAPACITY:
> + ret = pmi8998_fg_get_capacity(chip, &val->intval);
return pmi8998_fg_get_capacity();
etc.
> + break;
> + case POWER_SUPPLY_PROP_CURRENT_NOW:
> + ret = pmi8998_fg_get_current(chip, &val->intval);
> + break;
> + case POWER_SUPPLY_PROP_VOLTAGE_NOW:
> + ret = pmi8998_fg_get_voltage(chip, &val->intval);
> + break;
> + case POWER_SUPPLY_PROP_PRESENT:
> + val->intval = 1;
> + break;
> + case POWER_SUPPLY_PROP_TEMP:
> + ret = pmi8998_fg_get_temperature(chip, &val->intval);
> + break;
> + case POWER_SUPPLY_PROP_TEMP_MIN:
> + case POWER_SUPPLY_PROP_TEMP_MAX:
> + case POWER_SUPPLY_PROP_TEMP_ALERT_MIN:
> + case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
> + ret = pmi8998_fg_get_temp_threshold(chip, psp, &val->intval);
> + break;
> + default:
> + dev_err(chip->dev, "invalid property: %d\n", psp);
> + return -EINVAL;
> + }
> +
> + return ret;
> +}
> +
> +static const struct power_supply_desc batt_psy_desc = {
> + .name = "qcom-battery",
> + .type = POWER_SUPPLY_TYPE_BATTERY,
> + .properties = pmi8998_fg_props,
> + .num_properties = ARRAY_SIZE(pmi8998_fg_props),
> + .get_property = pmi8998_fg_get_property,
> +};
> +
> +/*
> + * Init functions
> + */
> +
> +static int pmi8998_fg_iacs_clear_sequence(struct pmi8998_fg_chip *chip)
> +{
> + u8 temp;
> + int ret;
> +
> + /* clear the error */
> + ret = pmi8998_fg_masked_write(chip, MEM_INTF_IMA_CFG, BIT(2), BIT(2));
> + if (ret) {
> + dev_err(chip->dev, "Failed to write IMA_CFG: %d\n", ret);
> + return ret;
> + }
> +
> + temp = 0x4;
> + ret = pmi8998_fg_write(chip, &temp, MEM_INTF_ADDR_LSB + 1, 1);
> + if (ret) {
> + dev_err(chip->dev, "Failed to write MEM_INTF_ADDR_MSB: %d\n", ret);
> + return ret;
> + }
> +
> + temp = 0x0;
> + ret = pmi8998_fg_write(chip, &temp, MEM_INTF_WR_DATA0 + 3, 1);
> + if (ret) {
> + dev_err(chip->dev, "Failed to write WR_DATA3: %d\n", ret);
> + return ret;
> + }
> +
> + ret = pmi8998_fg_read(chip, &temp, MEM_INTF_RD_DATA0 + 3, 1);
> + if (ret) {
> + dev_err(chip->dev, "Failed to write RD_DATA3: %d\n", ret);
> + return ret;
> + }
> +
> + ret = pmi8998_fg_masked_write(chip, MEM_INTF_IMA_CFG, BIT(2), 0);
> + if (ret) {
> + dev_err(chip->dev, "Failed to write IMA_CFG: %d\n", ret);
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static int pmi8998_fg_clear_ima(struct pmi8998_fg_chip *chip, bool check_hw_sts)
> +{
> + u8 err_sts, exp_sts, hw_sts;
> + bool run_err_clr_seq = false;
> + int ret;
> +
> + ret = pmi8998_fg_read(chip, &err_sts, MEM_INTF_IMA_ERR_STS, 1);
> + if (ret) {
> + dev_err(chip->dev, "Failed to read IMA_ERR_STS: %d\n", ret);
> + return ret;
> + }
> +
> + ret = pmi8998_fg_read(chip, &exp_sts,
> + MEM_INTF_IMA_EXP_STS, 1);
> + if (ret) {
> + dev_err(chip->dev, "Failed to read IMA_EXP_STS: %d\n", ret);
> + return ret;
> + }
> +
> + if (check_hw_sts) {
> + ret = pmi8998_fg_read(chip, &hw_sts,
> + MEM_INTF_IMA_HW_STS, 1);
> + if (ret) {
> + dev_err(chip->dev, "Failed to read IMA_HW_STS: %d\n", ret);
> + return ret;
> + }
> + /*
> + * Lower nibble should be equal to upper nibble before SRAM
> + * transactions begins from SW side.
> + */
> + if ((hw_sts & 0x0f) != hw_sts >> 4) {
> + dev_dbg(chip->dev, "IMA HW not in correct state, hw_sts=%x\n",
> + hw_sts);
> + run_err_clr_seq = true;
> + }
> + }
> +
> + if (exp_sts & (BIT(0) | BIT(1) | BIT(3) |
> + BIT(4) | BIT(5) | BIT(6) |
> + BIT(7))) {
Wrong indentation. Please #define the mask if possible.
> + dev_dbg(chip->dev, "IMA exception bit set, exp_sts=%x\n", exp_sts);
> + run_err_clr_seq = true;
> + }
> +
> + if (run_err_clr_seq) {
> + ret = pmi8998_fg_iacs_clear_sequence(chip);
> + if (!ret)
> + return -EAGAIN;
> + }
> +
> + return 0;
> +}
> +
> +static irqreturn_t pmi8998_fg_handle_soc_delta(int irq, void *data)
> +{
> + struct pmi8998_fg_chip *chip = data;
> +
> + /* Signal change in state of charge */
> + power_supply_changed(chip->batt_psy);
> + dev_dbg(chip->dev, "SOC changed");
> +
> + return IRQ_HANDLED;
> +}
> +
> +static void pmi8998_fg_status_changed_worker(struct work_struct *work)
> +{
> + struct pmi8998_fg_chip *chip = container_of(work, struct pmi8998_fg_chip,
> + status_changed_work.work);
> +
> + power_supply_changed(chip->batt_psy);
> +}
> +
> +static int pmi8998_fg_notifier_call(struct notifier_block *nb, unsigned long val, void *v)
> +{
> + struct pmi8998_fg_chip *chip = container_of(nb, struct pmi8998_fg_chip, nb);
> + struct power_supply *psy = v;
> + union power_supply_propval propval;
> + int ret;
> +
> + if (psy == chip->chg_psy) {
> + ret = power_supply_get_property(psy,
> + POWER_SUPPLY_PROP_STATUS, &propval);
> + if (ret)
> + chip->status = POWER_SUPPLY_STATUS_UNKNOWN;
> +
> + chip->status = propval.intval;
> +
> + power_supply_changed(chip->batt_psy);
> +
> + if (chip->status == POWER_SUPPLY_STATUS_UNKNOWN) {
> + /*
> + * REVISIT: Find better solution or remove current-based
> + * status checking once checking is properly implemented
> + * in charger drivers
> +
> + * Sometimes it take a while for current to stabilize,
> + * so signal property change again later to make sure
> + * current-based status is properly detected.
> + */
> + cancel_delayed_work_sync(&chip->status_changed_work);
> + schedule_delayed_work(&chip->status_changed_work,
> + msecs_to_jiffies(1000));
> + }
> + }
> +
> + return NOTIFY_OK;
> +}
> +
> +static int pmi8998_fg_probe(struct platform_device *pdev)
> +{
> + struct power_supply_config supply_config = {};
> + struct pmi8998_fg_chip *chip;
> + const __be32 *prop_addr;
> + int irq;
> + u8 dma_status;
> + bool error_present;
> + int ret;
> +
> + chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
> + if (!chip)
> + return -ENOMEM;
> +
> + chip->dev = &pdev->dev;
> +
> + chip->regmap = dev_get_regmap(pdev->dev.parent, NULL);
> + if (!chip->regmap) {
> + dev_err(chip->dev, "Failed to locate the regmap\n");
> + return -ENODEV;
> + }
> +
> + /* Get base address */
> + prop_addr = of_get_address(pdev->dev.of_node, 0, NULL, NULL);
> + if (!prop_addr) {
> + dev_err(chip->dev, "Failed to read SOC base address from dt\n");
> + return -EINVAL;
> + }
> + chip->base = be32_to_cpu(*prop_addr);
> +
> + /*
> + * Change the FG_MEM_INT interrupt to track IACS_READY
> + * condition instead of end-of-transaction. This makes sure
> + * that the next transaction starts only after the hw is ready.
> + * IACS_INTR_SRC_SLCT is BIT(3)
> + */
> + ret = pmi8998_fg_masked_write(chip, MEM_INTF_IMA_CFG, BIT(3), BIT(3));
> + if (ret) {
> + dev_err(chip->dev,
> + "Failed to configure interrupt sourete: %d\n", ret);
> + return ret;
> + }
> +
> + ret = pmi8998_fg_clear_ima(chip, true);
> + if (ret && ret != -EAGAIN) {
> + dev_err(chip->dev, "Failed to clear IMA exception: %d\n", ret);
> + return ret;
> + }
> +
> + /* Check and clear DMA errors */
DMA?
> + ret = pmi8998_fg_read(chip, &dma_status, MEM_IF_DMA_STS, 1);
> + if (ret < 0) {
> + dev_err(chip->dev, "Failed to read dma_status: %d\n", ret);
> + return ret;
> + }
> +
> + error_present = dma_status & (BIT(1) | BIT(2));
> + ret = pmi8998_fg_masked_write(chip, MEM_IF_DMA_CTL, BIT(0),
> + error_present ? BIT(0) : 0);
> + if (ret < 0) {
> + dev_err(chip->dev, "Failed to write dma_ctl: %d\n", ret);
> + return ret;
> + }
> +
> + supply_config.drv_data = chip;
> + supply_config.fwnode = dev_fwnode(&pdev->dev);
> +
> + chip->batt_psy = devm_power_supply_register(chip->dev,
> + &batt_psy_desc, &supply_config);
> + if (IS_ERR(chip->batt_psy)) {
> + if (PTR_ERR(chip->batt_psy) != -EPROBE_DEFER)
> + dev_err(&pdev->dev, "Failed to register battery\n");
> + return PTR_ERR(chip->batt_psy);
> + }
> +
> + platform_set_drvdata(pdev, chip);
> +
> + /* Get soc-delta IRQ */
> + irq = of_irq_get_byname(pdev->dev.of_node, "soc-delta");
> + if (irq < 0) {
> + dev_err(&pdev->dev, "Failed to get irq soc-delta byname: %d\n",
> + irq);
> + return irq;
> + }
> +
> + ret = devm_request_threaded_irq(chip->dev, irq, NULL,
> + pmi8998_fg_handle_soc_delta,
> + IRQF_ONESHOT, "soc-delta", chip);
> + if (ret < 0) {
> + dev_err(&pdev->dev, "Failed to request soc-delta IRQ: %d\n", ret);
> + return ret;
> + }
> +
> + /* Optional: Get charger power supply for status checking */
> + chip->chg_psy = power_supply_get_by_reference(of_fwnode_handle(chip->dev->of_node),
> + "power-supplies");
> + if (IS_ERR(chip->chg_psy)) {
> + ret = PTR_ERR(chip->chg_psy);
> + dev_warn(chip->dev, "Failed to get charger supply: %d\n", ret);
> + chip->chg_psy = NULL;
> + }
> +
> + if (chip->chg_psy) {
> + INIT_DELAYED_WORK(&chip->status_changed_work,
> + pmi8998_fg_status_changed_worker);
> +
> + chip->nb.notifier_call = pmi8998_fg_notifier_call;
> + ret = power_supply_reg_notifier(&chip->nb);
> + if (ret) {
> + dev_err(chip->dev,
> + "Failed to register notifier: %d\n", ret);
> + return ret;
> + }
> + }
> +
> + return 0;
> +}
> +
> +static const struct of_device_id fg_match_id_table[] = {
> + { .compatible = "qcom,pmi8998-fg" },
> + { /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, fg_match_id_table);
> +
> +static struct platform_driver pmi8998_fg_driver = {
> + .probe = pmi8998_fg_probe,
> + .driver = {
> + .name = "pmi8998-fg",
> + .of_match_table = fg_match_id_table,
> + },
> +};
> +
> +module_platform_driver(pmi8998_fg_driver);
> +
> +MODULE_AUTHOR("Casey Connolly <casey@connolly.tech>");
> +MODULE_AUTHOR("Joel Selvaraj <foss@joelselvaraj.com>");
> +MODULE_AUTHOR("Yassine Oudjana <y.oudjana@protonmail.com>");
> +MODULE_DESCRIPTION("Qualcomm PMI8998 Fuel Gauge Driver");
> +MODULE_LICENSE("GPL");
>
> --
> 2.51.0
>
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH RFC 3/8] arm64: dts: qcom: pmi8998: Add fuel gauge
2025-11-24 21:53 ` [PATCH RFC 3/8] arm64: dts: qcom: pmi8998: Add " David Heidelberg via B4 Relay
@ 2025-11-25 23:16 ` Dmitry Baryshkov
2025-11-27 17:53 ` Casey Connolly
1 sibling, 0 replies; 24+ messages in thread
From: Dmitry Baryshkov @ 2025-11-25 23:16 UTC (permalink / raw)
To: david
Cc: Sebastian Reichel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Casey Connolly, Casey Connolly, Joel Selvaraj, Yassine Oudjana,
Bjorn Andersson, Konrad Dybcio, Alexander Martinz,
Barnabás Czémán, Richard Acayan,
Alexey Minnekhanov, linux-pm, devicetree, linux-kernel,
linux-arm-msm, phone-devel
On Mon, Nov 24, 2025 at 10:53:36PM +0100, David Heidelberg via B4 Relay wrote:
> From: Casey Connolly <casey.connolly@linaro.org>
>
> Introduce the fuel gauge node for pmi8998.
>
> Signed-off-by: David Heidelberg <david@ixit.cz>
Again, missing author's SoB
> ---
> arch/arm64/boot/dts/qcom/pmi8998.dtsi | 11 +++++++++++
> 1 file changed, 11 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/qcom/pmi8998.dtsi b/arch/arm64/boot/dts/qcom/pmi8998.dtsi
> index cd3f0790fd420..ab3bc66502657 100644
> --- a/arch/arm64/boot/dts/qcom/pmi8998.dtsi
> +++ b/arch/arm64/boot/dts/qcom/pmi8998.dtsi
> @@ -44,6 +44,17 @@ pmi8998_rradc: adc@4500 {
> reg = <0x4500>;
> #io-channel-cells = <1>;
> };
> +
> + pmi8998_fg: fuel-gauge@4000 {
> + compatible = "qcom,pmi8998-fg";
> + reg = <0x4000>;
> +
> + interrupts = <0x2 0x40 0x3 IRQ_TYPE_EDGE_RISING>;
> + interrupt-names = "soc-delta";
> +
> + status = "disabled";
> + };
> +
> };
>
> pmi8998_lsid1: pmic@3 {
>
> --
> 2.51.0
>
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH RFC 4/8] arm64: dts: qcom: pm660: Add fuel gauge
2025-11-24 21:53 ` [PATCH RFC 4/8] arm64: dts: qcom: pm660: " David Heidelberg via B4 Relay
@ 2025-11-25 23:17 ` Dmitry Baryshkov
0 siblings, 0 replies; 24+ messages in thread
From: Dmitry Baryshkov @ 2025-11-25 23:17 UTC (permalink / raw)
To: david
Cc: Sebastian Reichel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Casey Connolly, Casey Connolly, Joel Selvaraj, Yassine Oudjana,
Bjorn Andersson, Konrad Dybcio, Alexander Martinz,
Barnabás Czémán, Richard Acayan,
Alexey Minnekhanov, linux-pm, devicetree, linux-kernel,
linux-arm-msm, phone-devel
On Mon, Nov 24, 2025 at 10:53:37PM +0100, David Heidelberg via B4 Relay wrote:
> From: Richard Acayan <mailingradian@gmail.com>
>
> The PM660 has the same fuel gauge as PMI8998. Add support for
> PM660 battery monitoring.
>
> Signed-off-by: Richard Acayan <mailingradian@gmail.com>
> Signed-off-by: David Heidelberg <david@ixit.cz>
> ---
> arch/arm64/boot/dts/qcom/pm660.dtsi | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/qcom/pm660.dtsi b/arch/arm64/boot/dts/qcom/pm660.dtsi
> index 156b2ddff0dcb..ce53f5ddc4bdf 100644
> --- a/arch/arm64/boot/dts/qcom/pm660.dtsi
> +++ b/arch/arm64/boot/dts/qcom/pm660.dtsi
> @@ -197,6 +197,16 @@ channel@85 {
> };
> };
>
> + pm660_fg: fuel-gauge@4000 {
> + compatible = "qcom,pmi8998-fg";
Please add PMIC-specific compatible, use pmi8998 as a fallback.
> + reg = <0x4000>;
> +
> + interrupts = <0x0 0x40 0x3 IRQ_TYPE_EDGE_RISING>;
> + interrupt-names = "soc-delta";
> +
> + status = "disabled";
> + };
> +
> pm660_rradc: adc@4500 {
> compatible = "qcom,pm660-rradc";
> reg = <0x4500>;
>
> --
> 2.51.0
>
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH RFC 5/8] arm64: dts: qcom: sdm845-xiaomi-beryllium: Enable fuel gauge
2025-11-24 21:53 ` [PATCH RFC 5/8] arm64: dts: qcom: sdm845-xiaomi-beryllium: Enable " David Heidelberg via B4 Relay
@ 2025-11-25 23:48 ` Dmitry Baryshkov
0 siblings, 0 replies; 24+ messages in thread
From: Dmitry Baryshkov @ 2025-11-25 23:48 UTC (permalink / raw)
To: david
Cc: Sebastian Reichel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Casey Connolly, Casey Connolly, Joel Selvaraj, Yassine Oudjana,
Bjorn Andersson, Konrad Dybcio, Alexander Martinz,
Barnabás Czémán, Richard Acayan,
Alexey Minnekhanov, linux-pm, devicetree, linux-kernel,
linux-arm-msm, phone-devel
On Mon, Nov 24, 2025 at 10:53:38PM +0100, David Heidelberg via B4 Relay wrote:
> From: Joel Selvaraj <foss@joelselvaraj.com>
>
> Enable the fuel gauge and configure the associated charger and battery.
>
> Signed-off-by: Joel Selvaraj <foss@joelselvaraj.com>
> Signed-off-by: David Heidelberg <david@ixit.cz>
> ---
> arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium-common.dtsi | 7 +++++++
> 1 file changed, 7 insertions(+)
>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH RFC 6/8] arm64: dts: qcom: sdm845-shift-axolotl: Enable fuel gauge
2025-11-24 21:53 ` [PATCH RFC 6/8] arm64: dts: qcom: sdm845-shift-axolotl: " David Heidelberg via B4 Relay
@ 2025-11-25 23:48 ` Dmitry Baryshkov
0 siblings, 0 replies; 24+ messages in thread
From: Dmitry Baryshkov @ 2025-11-25 23:48 UTC (permalink / raw)
To: david
Cc: Sebastian Reichel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Casey Connolly, Casey Connolly, Joel Selvaraj, Yassine Oudjana,
Bjorn Andersson, Konrad Dybcio, Alexander Martinz,
Barnabás Czémán, Richard Acayan,
Alexey Minnekhanov, linux-pm, devicetree, linux-kernel,
linux-arm-msm, phone-devel
On Mon, Nov 24, 2025 at 10:53:39PM +0100, David Heidelberg via B4 Relay wrote:
> From: Casey Connolly <casey.connolly@linaro.org>
>
> Enable the fuel gauge and configure the associated charger and battery.
>
> Signed-off-by: Casey Connolly <casey.connolly@linaro.org>
> Signed-off-by: David Heidelberg <david@ixit.cz>
> ---
> arch/arm64/boot/dts/qcom/sdm845-shift-axolotl.dts | 7 +++++++
> 1 file changed, 7 insertions(+)
>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH RFC 7/8] arm64: dts: qcom: sdm660-xiaomi-lavender: Enable support for battery
2025-11-24 21:53 ` [PATCH RFC 7/8] arm64: dts: qcom: sdm660-xiaomi-lavender: Enable support for battery David Heidelberg via B4 Relay
@ 2025-11-25 23:50 ` Dmitry Baryshkov
0 siblings, 0 replies; 24+ messages in thread
From: Dmitry Baryshkov @ 2025-11-25 23:50 UTC (permalink / raw)
To: david
Cc: Sebastian Reichel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Casey Connolly, Casey Connolly, Joel Selvaraj, Yassine Oudjana,
Bjorn Andersson, Konrad Dybcio, Alexander Martinz,
Barnabás Czémán, Richard Acayan,
Alexey Minnekhanov, linux-pm, devicetree, linux-kernel,
linux-arm-msm, phone-devel
On Mon, Nov 24, 2025 at 10:53:40PM +0100, David Heidelberg via B4 Relay wrote:
> From: Alexey Minnekhanov <alexeymin@postmarketos.org>
>
> Add support for battery, fuelgauge and charger.
>
> Signed-off-by: Alexey Minnekhanov <alexeymin@postmarketos.org>
> Signed-off-by: David Heidelberg <david@ixit.cz>
> ---
> .../arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts | 25 ++++++++++++++++++++++
> 1 file changed, 25 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts b/arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts
> index a9926ad6c6f9f..cb89b88d887d1 100644
> --- a/arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts
> +++ b/arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts
> @@ -38,6 +38,14 @@ framebuffer0: framebuffer@9d400000 {
> };
> };
>
> + battery: battery {
> + compatible = "simple-battery";
> +
> + charge-full-design-microamp-hours = <4000000>;
> + voltage-min-design-microvolt = <3400000>;
> + voltage-max-design-microvolt = <4400000>;
> + };
> +
> vph_pwr: vph-pwr-regulator {
> compatible = "regulator-fixed";
> regulator-name = "vph_pwr";
> @@ -93,6 +101,23 @@ &blsp1_uart2 {
> status = "okay";
> };
>
> +&pm660_charger {
> + monitored-battery = <&battery>;
> +
> + status = "okay";
> +};
> +
> +&pm660_fg {
> + monitored-battery = <&battery>;
> + power-supplies = <&pm660_charger>;
> +
> + status = "okay";
> +};
> +
> +&pm660_rradc {
> + status = "okay";
> +};
Could you please also add a patch moving &pm660l_wled to a correct
place?
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> +
> &pon_pwrkey {
> status = "okay";
> };
>
> --
> 2.51.0
>
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH RFC 8/8] arm64: dts: qcom: sdm670-google-sargo: Enable fuel gauge
2025-11-24 21:53 ` [PATCH RFC 8/8] arm64: dts: qcom: sdm670-google-sargo: Enable fuel gauge David Heidelberg via B4 Relay
@ 2025-11-25 23:50 ` Dmitry Baryshkov
0 siblings, 0 replies; 24+ messages in thread
From: Dmitry Baryshkov @ 2025-11-25 23:50 UTC (permalink / raw)
To: david
Cc: Sebastian Reichel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Casey Connolly, Casey Connolly, Joel Selvaraj, Yassine Oudjana,
Bjorn Andersson, Konrad Dybcio, Alexander Martinz,
Barnabás Czémán, Richard Acayan,
Alexey Minnekhanov, linux-pm, devicetree, linux-kernel,
linux-arm-msm, phone-devel
On Mon, Nov 24, 2025 at 10:53:41PM +0100, David Heidelberg via B4 Relay wrote:
> From: Richard Acayan <mailingradian@gmail.com>
>
> The PM660 fuel gauge determines the battery charge. Enable it for full
> battery support.
>
> Signed-off-by: Richard Acayan <mailingradian@gmail.com>
> Signed-off-by: David Heidelberg <david@ixit.cz>
> ---
> arch/arm64/boot/dts/qcom/sdm670-google-sargo.dts | 7 +++++++
> 1 file changed, 7 insertions(+)
>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH RFC 2/8] power: supply: Add driver for Qualcomm PMI8998 fuel gauge
2025-11-25 23:13 ` Dmitry Baryshkov
@ 2025-11-26 16:35 ` Joel Selvaraj
2025-11-29 1:36 ` Dmitry Baryshkov
0 siblings, 1 reply; 24+ messages in thread
From: Joel Selvaraj @ 2025-11-26 16:35 UTC (permalink / raw)
To: david
Cc: Sebastian Reichel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Casey Connolly, Casey Connolly, Yassine Oudjana, Dmitry Baryshkov,
Bjorn Andersson, Konrad Dybcio, Alexander Martinz,
Barnabás Czémán, Richard Acayan,
Alexey Minnekhanov, linux-pm, devicetree, linux-kernel,
linux-arm-msm, phone-devel
Hi David,
On 11/25/25 5:13 PM, Dmitry Baryshkov wrote:
> On Mon, Nov 24, 2025 at 10:53:35PM +0100, David Heidelberg via B4 Relay wrote:
>> From: Joel Selvaraj <foss@joelselvaraj.com>
>>
>> Ths driver supports the fuel gauge hardware available on PMICs known as
>> 3rd generation fuel gauge hardware available on PMI8998.
>>
>> Co-developed-by: Casey Connolly <casey@connolly.tech>
>> Co-developed-by: Barnabás Czémán <barnabas.czeman@mainlining.org>
>> Signed-off-by: Barnabás Czémán <barnabas.czeman@mainlining.org>
>> Co-developed-by: Yassine Oudjana <y.oudjana@protonmail.com>
>> Signed-off-by: Yassine Oudjana <y.oudjana@protonmail.com>
>> Signed-off-by: David Heidelberg <david@ixit.cz>
>
> This can't be applied, there is no author's (Joel Selvaraj) SoB.
Here is my signed-off-by. You can include them in future revisions.
Signed-off-by: Joel Selvaraj <foss@joelselvaraj.com>
Regards,
Joel
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH RFC 1/8] dt-bindings: power: supply: Add schema for Qualcomm pmi8998 fuel gauge
2025-11-24 21:53 ` [PATCH RFC 1/8] dt-bindings: power: supply: Add schema for Qualcomm pmi8998 fuel gauge David Heidelberg via B4 Relay
@ 2025-11-27 10:32 ` Konrad Dybcio
0 siblings, 0 replies; 24+ messages in thread
From: Konrad Dybcio @ 2025-11-27 10:32 UTC (permalink / raw)
To: david, Sebastian Reichel, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Casey Connolly, Casey Connolly, Joel Selvaraj,
Yassine Oudjana, Bjorn Andersson, Konrad Dybcio,
Alexander Martinz, Barnabás Czémán, Richard Acayan,
Alexey Minnekhanov
Cc: linux-pm, devicetree, linux-kernel, linux-arm-msm, phone-devel
On 11/24/25 10:53 PM, David Heidelberg via B4 Relay wrote:
> From: Yassine Oudjana <y.oudjana@protonmail.com>
>
> Add a device-tree schema for Qualcomm PMIC 8998 fuel gauge.
>
> Signed-off-by: Barnabás Czémán <barnabas.czeman@mainlining.org>
> Signed-off-by: Yassine Oudjana <y.oudjana@protonmail.com>
> ---
[...]
> + pmic {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + fuel-gauge@4000 {
> + compatible = "qcom,pmi8998-fg";
> + reg = <0x4000>;
> +
> + interrupts = <0x2 0x40 0x4 IRQ_TYPE_EDGE_RISING>;
> + interrupt-names = "soc-delta";
A (much much older but still) similar in functionality, the PM8916
BMS block has 6 interrupts.
pmi8998.dtsi on msm-4.4 defines a total of 16 under the fg-gen3
megadevice. I would assume that at least a majority of them are useful
and/or required for full functionality.
There's 8 under 'fg-batt-soc', 5 under 'fg-batt-info' and 3 under
'fg-memif'
The main node also consumes an IIO channel provided by the RRADC
I'm not asking you to implement all the feature delta in v2, but I
will ask you to assess what the dt-bindings for a complete solution
would look like and to fill in all the resources that will be necessary
down the line, to the best of your knowledge, so that you won't have
to wrestle with bindings updates with every new feature addition
Konrad
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH RFC 2/8] power: supply: Add driver for Qualcomm PMI8998 fuel gauge
2025-11-24 21:53 ` [PATCH RFC 2/8] power: supply: Add driver for Qualcomm PMI8998 " David Heidelberg via B4 Relay
2025-11-25 23:13 ` Dmitry Baryshkov
@ 2025-11-27 15:28 ` Konrad Dybcio
2025-12-12 15:22 ` David Heidelberg
1 sibling, 1 reply; 24+ messages in thread
From: Konrad Dybcio @ 2025-11-27 15:28 UTC (permalink / raw)
To: david, Sebastian Reichel, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Casey Connolly, Casey Connolly, Joel Selvaraj,
Yassine Oudjana, Bjorn Andersson, Konrad Dybcio,
Alexander Martinz, Barnabás Czémán, Richard Acayan,
Alexey Minnekhanov
Cc: linux-pm, devicetree, linux-kernel, linux-arm-msm, phone-devel
On 11/24/25 10:53 PM, David Heidelberg via B4 Relay wrote:
> From: Joel Selvaraj <foss@joelselvaraj.com>
>
> Ths driver supports the fuel gauge hardware available on PMICs known as
> 3rd generation fuel gauge hardware available on PMI8998.
>
> Co-developed-by: Casey Connolly <casey@connolly.tech>
> Co-developed-by: Barnabás Czémán <barnabas.czeman@mainlining.org>
> Signed-off-by: Barnabás Czémán <barnabas.czeman@mainlining.org>
> Co-developed-by: Yassine Oudjana <y.oudjana@protonmail.com>
> Signed-off-by: Yassine Oudjana <y.oudjana@protonmail.com>
> Signed-off-by: David Heidelberg <david@ixit.cz>
> ---
[...]
> +/**
> + * @brief pmi8998_fg_read() - Read multiple registers with regmap_bulk_read
I think this won't pass kerneldoc checks (make W=1)
[...]
> +static int pmi8998_fg_write(struct pmi8998_fg_chip *chip, u8 *val, u16 addr, int len)
> +{
> + bool sec_access = (addr & 0xff) > 0xd0;
Downstream checks if the address is > 0xBA which is what you want
at least for pmi8998
You can de-abbreviate this to 'secure_access' (not to be confused
with 'secondary' or so). There's a locking mechanism which needs a
0xa5 byte written to the base+0xd0 register (applies to all FG
peripherals with the 'last non-secure register' value possibly
varying).
[...]
> + u8 sec_addr_val = 0xa5;
> + int ret;
> +
> + if (((chip->base + addr) & 0xff00) == 0)
The 'fuel gauge' consists of:
FG_BATT_SOC @ 0x4000 (state of charge monitor)
FG_BATT_INFO @ 0x4100 ("general fg minus SoC")
FG_BCL @ 0x4200 (battery current limiter)
FG_LMH @ 0x4300 (limits management hardware)
FG_MEM_IF @ 0x4400 (DMA engine)
RRADC @ 0x4500 (today handled by its own driver)
and a couple other peripherals that Linux doesn't need to worry about
Each one of them should have its own 'reg' entry (which is assumed
to be 0x100-long), which will let you skip such interesting checks
and rely on the regmap framework disallowing address spillover (or
you can just then make the addr argument a u8)
It would be good to keep in mind their relationship and think about how
to model them together. I don't think they must all necessarily be part
of a single big "fg" dt node, particularly the LMH/BCL part seems to be
rather self-contained
[...]
> + return -EINVAL;
> +
> + dev_vdbg(chip->dev, "%s: Writing 0x%x to 0x%x", __func__, *val, addr);
> +
> + if (sec_access) {
> + ret = regmap_bulk_write(chip->regmap,
> + ((chip->base + addr) & 0xff00) | 0xd0,
> + &sec_addr_val, 1);
> + if (ret)
> + return ret;
> + }
> +
> + return regmap_bulk_write(chip->regmap, chip->base + addr, val, len);
> +}
> +
> +/**
> + * @brief pmi8998_fg_masked_write() - like pmi8998_fg_write but applies
> + * a mask first.
> + *
> + * @param chip Pointer to chip
> + * @param val Pointer to write values from
> + * @param addr Address to write to
> + * @param len Number of registers (bytes) to write
> + * @return int 0 on success, negative errno on error
> + */
> +static int pmi8998_fg_masked_write(struct pmi8998_fg_chip *chip, u16 addr, u8 mask, u8 val)
> +{
> + u8 reg;
> + int ret;
> +
> + ret = pmi8998_fg_read(chip, ®, addr, 1);
> + if (ret)
> + return ret;
> +
> + reg &= ~mask;
> + reg |= val & mask;
> +
> + return pmi8998_fg_write(chip, ®, addr, 1);
> +}
> +
> +/*
> + * Battery status
> + */
> +
> +/**
> + * @brief pmi8998_fg_get_capacity() - Get remaining capacity of battery
> + *
> + * @param chip Pointer to chip
> + * @param val Pointer to store value at
> + * @return int 0 on success, negative errno on error
> + */
> +static int pmi8998_fg_get_capacity(struct pmi8998_fg_chip *chip, int *val)
> +{
> + u8 cap[2];
> + int ret;
> +
> + ret = pmi8998_fg_read(chip, cap, BATT_MONOTONIC_SOC, 2);
> + if (ret) {
> + dev_err(chip->dev, "Failed to read capacity: %d", ret);
> + return ret;
> + }
Downstream tries for 5 times to get this (raw) pair of values and fails if
they don't match - 0x400a is a shadow register of 0x4009 and this is very
much intended
> + if (cap[0] != cap[1])
> + cap[0] = cap[0] < cap[1] ? cap[0] : cap[1];
> +
> + *val = DIV_ROUND_CLOSEST((cap[0] - 1) * 98, 0xff - 2) + 1;
98 comes from "FULL_CAPACITY (100) - 2", 0xff denotes "FULL_SOC_RAW", i.e. the
raw value of this register that corresponds to 100% (again not sure where the
minus2 comes from - perhaps some rounding fixups)
> +
> + return 0;
> +}
> +
> +/**
> + * @brief pmi8998_fg_get_temperature() - Get temperature of battery
> + *
> + * @param chip Pointer to chip
> + * @param val Pointer to store value at
> + * @return int 0 on success, negative errno on error
> + */
> +static int pmi8998_fg_get_temperature(struct pmi8998_fg_chip *chip, int *val)
> +{
> + int ret, temp;
> + u8 readval[2];
> +
> + ret = pmi8998_fg_read(chip, readval, PARAM_ADDR_BATT_TEMP, 2);
> + if (ret) {
> + dev_err(chip->dev, "Failed to read temperature: %d\n", ret);
> + return ret;
> + }
> +
> + temp = ((readval[1] & BATT_TEMP_MSB_MASK) << 8) |
> + (readval[0] & BATT_TEMP_LSB_MASK);
> + temp = DIV_ROUND_CLOSEST(temp * 10, 4);
> +
> + *val = temp - 2730;
> +
> + return 0;
> +}
> +
> +/**
> + * @brief pmi8998_fg_get_current() - Get current being drawn from battery
> + *
> + * @param chip Pointer to chip
> + * @param val Pointer to store value at
> + * @return int 0 on success, negative errno on error
> + */
> +static int pmi8998_fg_get_current(struct pmi8998_fg_chip *chip, int *val)
> +{
> + s16 temp;
> + u8 readval[2];
> + int ret;
> +
> + ret = pmi8998_fg_read(chip, readval, PARAM_ADDR_BATT_CURRENT, 2);
> + if (ret) {
> + dev_err(chip->dev, "Failed to read current: %d\n", ret);
> + return ret;
> + }
> +
> + /* handle rev 1 too */
PMI8998v1 has flipped the order of the registers and I would guesstimate
that it wouldn't actually be present in the wild
> + temp = (s16)(readval[1] << 8 | readval[0]);
> + *val = div_s64((s64)temp * 488281, 1000);
This is a funny way to say that this is a 2s complement-encoded
16b value, where 5 bits are reserved for the integer portion
[...]
> + power_supply_changed(chip->batt_psy);
> +
> + if (chip->status == POWER_SUPPLY_STATUS_UNKNOWN) {
> + /*
> + * REVISIT: Find better solution or remove current-based
> + * status checking once checking is properly implemented
> + * in charger drivers
> +
> + * Sometimes it take a while for current to stabilize,
> + * so signal property change again later to make sure
> + * current-based status is properly detected.
> + */
On downstream, it's the charger counterpart that signals PSY_STATUS_(DIS)CHARGING
Konrad
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH RFC 3/8] arm64: dts: qcom: pmi8998: Add fuel gauge
2025-11-24 21:53 ` [PATCH RFC 3/8] arm64: dts: qcom: pmi8998: Add " David Heidelberg via B4 Relay
2025-11-25 23:16 ` Dmitry Baryshkov
@ 2025-11-27 17:53 ` Casey Connolly
2025-11-29 2:09 ` Richard Acayan
1 sibling, 1 reply; 24+ messages in thread
From: Casey Connolly @ 2025-11-27 17:53 UTC (permalink / raw)
To: david, Sebastian Reichel, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Casey Connolly, Joel Selvaraj, Yassine Oudjana,
Bjorn Andersson, Konrad Dybcio, Alexander Martinz,
Barnabás Czémán, Richard Acayan,
Alexey Minnekhanov
Cc: linux-pm, devicetree, linux-kernel, linux-arm-msm, phone-devel
On 24/11/2025 22:53, David Heidelberg via B4 Relay wrote:
> From: Casey Connolly <casey.connolly@linaro.org>
>
> Introduce the fuel gauge node for pmi8998.
>
Signed-off-by: Casey Connolly <casey.connolly@linaro.org>>
Signed-off-by: David Heidelberg <david@ixit.cz>
> ---
> arch/arm64/boot/dts/qcom/pmi8998.dtsi | 11 +++++++++++
> 1 file changed, 11 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/qcom/pmi8998.dtsi b/arch/arm64/boot/dts/qcom/pmi8998.dtsi
> index cd3f0790fd420..ab3bc66502657 100644
> --- a/arch/arm64/boot/dts/qcom/pmi8998.dtsi
> +++ b/arch/arm64/boot/dts/qcom/pmi8998.dtsi
> @@ -44,6 +44,17 @@ pmi8998_rradc: adc@4500 {
> reg = <0x4500>;
> #io-channel-cells = <1>;
> };
> +
> + pmi8998_fg: fuel-gauge@4000 {
> + compatible = "qcom,pmi8998-fg";
> + reg = <0x4000>;
> +
> + interrupts = <0x2 0x40 0x3 IRQ_TYPE_EDGE_RISING>;
> + interrupt-names = "soc-delta";
I think it makes sense to add all the interrupts here, even if thr
driver only uses one of them currently.
interrupts = <0x2 0x40 0x0 IRQ_TYPE_EDGE_BOTH>,
<0x2 0x40 0x1 IRQ_TYPE_EDGE_BOTH>,
<0x2 0x40 0x2 IRQ_TYPE_EDGE_RISING>,
<0x2 0x40 0x3 IRQ_TYPE_EDGE_RISING>,
<0x2 0x40 0x4 IRQ_TYPE_EDGE_BOTH>,
<0x2 0x40 0x5 IRQ_TYPE_EDGE_RISING>,
<0x2 0x40 0x6 IRQ_TYPE_EDGE_BOTH>,
<0x2 0x40 0x7 IRQ_TYPE_EDGE_BOTH>;
interrupt-names = "soc-update",
"soc-ready",
"bsoc-delta",
"msoc-delta",
"msoc-low",
"msoc-empty",
"msoc-high",
"msoc-full";
https://github.com/LineageOS/android_kernel_oneplus_sdm845/blob/lineage-22.2/arch/arm64/boot/dts/qcom/pmi8998.dtsi#L292
Not sure what the difference is between bsoc-delta and msoc-delta, maybe
Richard or Yassine can recall? DT bindings would need updating too.
> +
> + status = "disabled";
> + };
> +
> };
>
> pmi8998_lsid1: pmic@3 {
>
--
// Casey (she/her)
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH RFC 2/8] power: supply: Add driver for Qualcomm PMI8998 fuel gauge
2025-11-26 16:35 ` Joel Selvaraj
@ 2025-11-29 1:36 ` Dmitry Baryshkov
0 siblings, 0 replies; 24+ messages in thread
From: Dmitry Baryshkov @ 2025-11-29 1:36 UTC (permalink / raw)
To: Joel Selvaraj
Cc: david, Sebastian Reichel, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Casey Connolly, Casey Connolly, Yassine Oudjana,
Bjorn Andersson, Konrad Dybcio, Alexander Martinz,
Barnabás Czémán, Richard Acayan,
Alexey Minnekhanov, linux-pm, devicetree, linux-kernel,
linux-arm-msm, phone-devel
On Wed, Nov 26, 2025 at 04:35:09PM +0000, Joel Selvaraj wrote:
> Hi David,
>
> On 11/25/25 5:13 PM, Dmitry Baryshkov wrote:
> > On Mon, Nov 24, 2025 at 10:53:35PM +0100, David Heidelberg via B4 Relay wrote:
> >> From: Joel Selvaraj <foss@joelselvaraj.com>
> >>
> >> Ths driver supports the fuel gauge hardware available on PMICs known as
> >> 3rd generation fuel gauge hardware available on PMI8998.
> >>
> >> Co-developed-by: Casey Connolly <casey@connolly.tech>
> >> Co-developed-by: Barnabás Czémán <barnabas.czeman@mainlining.org>
> >> Signed-off-by: Barnabás Czémán <barnabas.czeman@mainlining.org>
> >> Co-developed-by: Yassine Oudjana <y.oudjana@protonmail.com>
> >> Signed-off-by: Yassine Oudjana <y.oudjana@protonmail.com>
> >> Signed-off-by: David Heidelberg <david@ixit.cz>
> >
> > This can't be applied, there is no author's (Joel Selvaraj) SoB.
>
> Here is my signed-off-by. You can include them in future revisions.
>
> Signed-off-by: Joel Selvaraj <foss@joelselvaraj.com>
Thanks!
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH RFC 3/8] arm64: dts: qcom: pmi8998: Add fuel gauge
2025-11-27 17:53 ` Casey Connolly
@ 2025-11-29 2:09 ` Richard Acayan
0 siblings, 0 replies; 24+ messages in thread
From: Richard Acayan @ 2025-11-29 2:09 UTC (permalink / raw)
To: Casey Connolly
Cc: david, Sebastian Reichel, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Casey Connolly, Joel Selvaraj, Yassine Oudjana,
Bjorn Andersson, Konrad Dybcio, Alexander Martinz,
Barnabás Czémán, Alexey Minnekhanov, linux-pm,
devicetree, linux-kernel, linux-arm-msm, phone-devel
On Thu, Nov 27, 2025 at 06:53:38PM +0100, Casey Connolly wrote:
> On 24/11/2025 22:53, David Heidelberg via B4 Relay wrote:
> > From: Casey Connolly <casey.connolly@linaro.org>
> >
> > Introduce the fuel gauge node for pmi8998.
> >
>
> Signed-off-by: Casey Connolly <casey.connolly@linaro.org>>
> Signed-off-by: David Heidelberg <david@ixit.cz>
> > ---
> > arch/arm64/boot/dts/qcom/pmi8998.dtsi | 11 +++++++++++
> > 1 file changed, 11 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/qcom/pmi8998.dtsi b/arch/arm64/boot/dts/qcom/pmi8998.dtsi
> > index cd3f0790fd420..ab3bc66502657 100644
> > --- a/arch/arm64/boot/dts/qcom/pmi8998.dtsi
> > +++ b/arch/arm64/boot/dts/qcom/pmi8998.dtsi
> > @@ -44,6 +44,17 @@ pmi8998_rradc: adc@4500 {
> > reg = <0x4500>;
> > #io-channel-cells = <1>;
> > };
> > +
> > + pmi8998_fg: fuel-gauge@4000 {
> > + compatible = "qcom,pmi8998-fg";
> > + reg = <0x4000>;
> > +
> > + interrupts = <0x2 0x40 0x3 IRQ_TYPE_EDGE_RISING>;
> > + interrupt-names = "soc-delta";
>
> I think it makes sense to add all the interrupts here, even if thr
> driver only uses one of them currently.
>
> interrupts = <0x2 0x40 0x0 IRQ_TYPE_EDGE_BOTH>,
> <0x2 0x40 0x1 IRQ_TYPE_EDGE_BOTH>,
> <0x2 0x40 0x2 IRQ_TYPE_EDGE_RISING>,
> <0x2 0x40 0x3 IRQ_TYPE_EDGE_RISING>,
> <0x2 0x40 0x4 IRQ_TYPE_EDGE_BOTH>,
> <0x2 0x40 0x5 IRQ_TYPE_EDGE_RISING>,
> <0x2 0x40 0x6 IRQ_TYPE_EDGE_BOTH>,
> <0x2 0x40 0x7 IRQ_TYPE_EDGE_BOTH>;
> interrupt-names = "soc-update",
> "soc-ready",
> "bsoc-delta",
> "msoc-delta",
> "msoc-low",
> "msoc-empty",
> "msoc-high",
> "msoc-full";
>
> https://github.com/LineageOS/android_kernel_oneplus_sdm845/blob/lineage-22.2/arch/arm64/boot/dts/qcom/pmi8998.dtsi#L292
>
> Not sure what the difference is between bsoc-delta and msoc-delta, maybe
> Richard or Yassine can recall? DT bindings would need updating too.
Well I don't remember, but the downstream kernel seems to reference bsoc
as battery SOC and msoc (used for the battery percentage) as
monotonic SOC. Maybe msoc is based on bsoc and scaled based on battery
health, but that's just from skimming the downstream driver.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH RFC 2/8] power: supply: Add driver for Qualcomm PMI8998 fuel gauge
2025-11-27 15:28 ` Konrad Dybcio
@ 2025-12-12 15:22 ` David Heidelberg
0 siblings, 0 replies; 24+ messages in thread
From: David Heidelberg @ 2025-12-12 15:22 UTC (permalink / raw)
To: Konrad Dybcio, Sebastian Reichel, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Casey Connolly, Casey Connolly,
Joel Selvaraj, Yassine Oudjana, Bjorn Andersson, Konrad Dybcio,
Alexander Martinz, Barnabás Czémán, Richard Acayan,
Alexey Minnekhanov
Cc: linux-pm, devicetree, linux-kernel, linux-arm-msm, phone-devel
On 27/11/2025 16:28, Konrad Dybcio wrote:
> On 11/24/25 10:53 PM, David Heidelberg via B4 Relay wrote:
>> From: Joel Selvaraj <foss@joelselvaraj.com>
>>
>> Ths driver supports the fuel gauge hardware available on PMICs known as
>> 3rd generation fuel gauge hardware available on PMI8998.
>>
[...]
> Downstream checks if the address is > 0xBA which is what you want
> at least for pmi8998
My downstream [1] checks this value.
[1]
https://github.com/LineageOS/android_kernel_xiaomi_sdm845/blob/lineage-22.2/drivers/power/supply/qcom/qpnp-fg.c#L760>
> You can de-abbreviate this to 'secure_access' (not to be confused
> with 'secondary' or so). There's a locking mechanism which needs a
> 0xa5 byte written to the base+0xd0 register (applies to all FG
> peripherals with the 'last non-secure register' value possibly
> varying).
>
> [...]
>
>> + u8 sec_addr_val = 0xa5;
>> + int ret;
>> +
>> + if (((chip->base + addr) & 0xff00) == 0)
>
> The 'fuel gauge' consists of:
>
> FG_BATT_SOC @ 0x4000 (state of charge monitor)
> FG_BATT_INFO @ 0x4100 ("general fg minus SoC")
> FG_BCL @ 0x4200 (battery current limiter)
> FG_LMH @ 0x4300 (limits management hardware)
> FG_MEM_IF @ 0x4400 (DMA engine)
> RRADC @ 0x4500 (today handled by its own driver)
>
> and a couple other peripherals that Linux doesn't need to worry about
>
> Each one of them should have its own 'reg' entry (which is assumed
> to be 0x100-long), which will let you skip such interesting checks
> and rely on the regmap framework disallowing address spillover (or
> you can just then make the addr argument a u8)
Sounds good.
>
> It would be good to keep in mind their relationship and think about how
> to model them together. I don't think they must all necessarily be part
> of a single big "fg" dt node, particularly the LMH/BCL part seems to be
> rather self-contained
Would you recommend some readings to prepare for this task?
I see the FG_BATT* + FG_MEM_IF seems to be pretty relying on each other,
so I assume I need to take good care of that relation, when spliting
pieces up.
Thanks
David
[...]
^ permalink raw reply [flat|nested] 24+ messages in thread
end of thread, other threads:[~2025-12-12 15:22 UTC | newest]
Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-24 21:53 [PATCH RFC 0/8] Qualcomm 3rd gen fuel gauge support David Heidelberg via B4 Relay
2025-11-24 21:53 ` [PATCH RFC 1/8] dt-bindings: power: supply: Add schema for Qualcomm pmi8998 fuel gauge David Heidelberg via B4 Relay
2025-11-27 10:32 ` Konrad Dybcio
2025-11-24 21:53 ` [PATCH RFC 2/8] power: supply: Add driver for Qualcomm PMI8998 " David Heidelberg via B4 Relay
2025-11-25 23:13 ` Dmitry Baryshkov
2025-11-26 16:35 ` Joel Selvaraj
2025-11-29 1:36 ` Dmitry Baryshkov
2025-11-27 15:28 ` Konrad Dybcio
2025-12-12 15:22 ` David Heidelberg
2025-11-24 21:53 ` [PATCH RFC 3/8] arm64: dts: qcom: pmi8998: Add " David Heidelberg via B4 Relay
2025-11-25 23:16 ` Dmitry Baryshkov
2025-11-27 17:53 ` Casey Connolly
2025-11-29 2:09 ` Richard Acayan
2025-11-24 21:53 ` [PATCH RFC 4/8] arm64: dts: qcom: pm660: " David Heidelberg via B4 Relay
2025-11-25 23:17 ` Dmitry Baryshkov
2025-11-24 21:53 ` [PATCH RFC 5/8] arm64: dts: qcom: sdm845-xiaomi-beryllium: Enable " David Heidelberg via B4 Relay
2025-11-25 23:48 ` Dmitry Baryshkov
2025-11-24 21:53 ` [PATCH RFC 6/8] arm64: dts: qcom: sdm845-shift-axolotl: " David Heidelberg via B4 Relay
2025-11-25 23:48 ` Dmitry Baryshkov
2025-11-24 21:53 ` [PATCH RFC 7/8] arm64: dts: qcom: sdm660-xiaomi-lavender: Enable support for battery David Heidelberg via B4 Relay
2025-11-25 23:50 ` Dmitry Baryshkov
2025-11-24 21:53 ` [PATCH RFC 8/8] arm64: dts: qcom: sdm670-google-sargo: Enable fuel gauge David Heidelberg via B4 Relay
2025-11-25 23:50 ` Dmitry Baryshkov
2025-11-25 18:09 ` [PATCH RFC 0/8] Qualcomm 3rd gen fuel gauge support Rob Herring
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).