From nobody Mon Jan 26 22:56:50 2026 Received: from layka.disroot.org (layka.disroot.org [178.21.23.139]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1773D340279; Mon, 26 Jan 2026 15:40:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=178.21.23.139 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769442007; cv=none; b=ah7Wgcl5oDIUqCsmqfU3JE29xwmjgT98rijB6a8BrIc3sQVYglMrPEh+0WZ61q3Xb2LNudC3T6KDqu9G2+papZBuWKE3K1CFfzt69/3mDH4sRrlkLnKC6Yzn2lpALuuOHy/MeQHPdDnolD8sUCTmOFAikVBY+Ex6KL6rw1t1X7g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769442007; c=relaxed/simple; bh=EoFfBo5hPiItUd0YquJyrcSZKrDBJIGSBOCGyATgRkY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=hY4KRax40phdMQPz2r0zfRsrSwERuyxOm3w0OxhiMgpwOAmvv2/bqHXBxNRHWmx6n2dqIOFBWLadBEckKC/IbqC3fsfp88uQELzID5/QDPRGAGMTkRMXde/EReDA0LiI9eNs3v1WLS0QVA7rdREBB25pzLChjGomuwx7eH1C3yo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=disroot.org; spf=pass smtp.mailfrom=disroot.org; dkim=pass (2048-bit key) header.d=disroot.org header.i=@disroot.org header.b=KZhomKBK; arc=none smtp.client-ip=178.21.23.139 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=disroot.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=disroot.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=disroot.org header.i=@disroot.org header.b="KZhomKBK" Received: from [127.0.0.1] (localhost [127.0.0.1]) by disroot.org (Postfix) with ESMTP id B0CD727374; Mon, 26 Jan 2026 16:40:04 +0100 (CET) X-Virus-Scanned: SPAM Filter at disroot.org Received: from layka.disroot.org ([127.0.0.1]) by localhost (disroot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id zgxnwz87wuUc; Mon, 26 Jan 2026 16:40:03 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=disroot.org; s=mail; t=1769442003; bh=EoFfBo5hPiItUd0YquJyrcSZKrDBJIGSBOCGyATgRkY=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=KZhomKBK3cAKj4wHLXXg/+Gp9cMnmK9/f8IzJfyVFrPhsXAVNNw3gb5W2PUHqIy9J WxPbkPkSj/7ueV+tuXiEJvSzGqjh+w4WQiaKJ96l40HftVUBJnsFbzGLLWoKPC4FLy vk5jLXIbM5yubxYlfVWMXmWEBwm+He5UtJmLq59zwJ0bYNPmTMGmAiZ6P0muteh9fx B4xfD30VQEwiiGujlno73xbCA4z3kT0NKLu65hXEoui0yZZ0sSazx/+OOTAlmqWQQG DqnBgACRDLHbyku14iiIEAiTGgnFW03j/Uuu/9D1jQv4MQ/8+OBwD+PaEhVplDJZel wT4PQJAhswiGQ== From: Kaustabh Chakraborty Date: Mon, 26 Jan 2026 21:09:48 +0530 Subject: [PATCH 1/2] dt-bindings: power: supply: document Samsung S2MU005 battery fuel gauge Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260126-s2mu005-fuelgauge-v1-1-68a146ed0819@disroot.org> References: <20260126-s2mu005-fuelgauge-v1-0-68a146ed0819@disroot.org> In-Reply-To: <20260126-s2mu005-fuelgauge-v1-0-68a146ed0819@disroot.org> To: Yassine Oudjana , Sebastian Reichel , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Kaustabh Chakraborty Samsung S2MU005 is a PMIC device which has LED controllers, an MUIC and a battery charger. The battery charger is paired with an independent device connected via I2C which can be used to access various metrics of the battery. Document the device as a schema. Signed-off-by: Kaustabh Chakraborty Acked-by: Conor Dooley --- .../power/supply/samsung,s2mu005-fuel-gauge.yaml | 49 ++++++++++++++++++= ++++ 1 file changed, 49 insertions(+) diff --git a/Documentation/devicetree/bindings/power/supply/samsung,s2mu005= -fuel-gauge.yaml b/Documentation/devicetree/bindings/power/supply/samsung,s= 2mu005-fuel-gauge.yaml new file mode 100644 index 0000000000000..5f945a5369dc8 --- /dev/null +++ b/Documentation/devicetree/bindings/power/supply/samsung,s2mu005-fuel-g= auge.yaml @@ -0,0 +1,49 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/power/supply/samsung,s2mu005-fuel-gauge= .yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Battery Fuel Gauge for Samsung S2M series PMICs + +maintainers: + - Kaustabh Chakraborty + +allOf: + - $ref: power-supply.yaml# + +properties: + compatible: + enum: + - samsung,s2mu005-fuel-gauge + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + +required: + - compatible + - reg + +unevaluatedProperties: false + +examples: + - | + #include + + i2c { + #address-cells =3D <1>; + #size-cells =3D <0>; + + fuelgauge@3b { + compatible =3D "samsung,s2mu005-fuel-gauge"; + reg =3D <0x3b>; + + interrupt-parent =3D <&gpa0>; + interrupts =3D <3 IRQ_TYPE_EDGE_BOTH>; + + monitored-battery =3D <&battery>; + }; + }; --=20 2.52.0 From nobody Mon Jan 26 22:56:50 2026 Received: from layka.disroot.org (layka.disroot.org [178.21.23.139]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 89D8A340275; Mon, 26 Jan 2026 15:40:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=178.21.23.139 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769442013; cv=none; b=FRUQvHAHWivnLJyUPzceSGhGkqoXFsSFSt80ZcM+0jx6iudCtlCVWDTcq2Vyr224v8P9SIzD5aewIkmxFsrjMEwJ4Qpsv5/i8u3USzvPQ9PTGl1Honxq8scQ51oQ6TGKC4KNdySQ8nJHMRZk5QqQOXlOlK5ypaqSqqyoTOhPWqs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769442013; c=relaxed/simple; bh=jjfFByUueOhLF+GJfahp/6Wi2wfOAu+dUSDB+c2Er/s=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ABjvOHef2DfzdB8SP2JsgaFAywsC7wgMwCiYWWeg+G2O3GbaFUZiCsO0/Lg3gthCGe+EV0eJVu6H59MZ09xco0ZjiUjCGpP94OW3GWHpnf0+Q9LfGMhg0ETJso8lsfHQQ496apF3lYkgmkKusWENdida6Wgr7+KexQbGI1VsQhE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=disroot.org; spf=pass smtp.mailfrom=disroot.org; dkim=pass (2048-bit key) header.d=disroot.org header.i=@disroot.org header.b=bwu5xDya; arc=none smtp.client-ip=178.21.23.139 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=disroot.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=disroot.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=disroot.org header.i=@disroot.org header.b="bwu5xDya" Received: from [127.0.0.1] (localhost [127.0.0.1]) by disroot.org (Postfix) with ESMTP id E80BD26426; Mon, 26 Jan 2026 16:40:09 +0100 (CET) X-Virus-Scanned: SPAM Filter at disroot.org Received: from layka.disroot.org ([127.0.0.1]) by localhost (disroot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id 18c95C4GZO2G; Mon, 26 Jan 2026 16:40:07 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=disroot.org; s=mail; t=1769442007; bh=jjfFByUueOhLF+GJfahp/6Wi2wfOAu+dUSDB+c2Er/s=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=bwu5xDyazB59Yq5gcZ+Ixkkhpr3VRzYElQqcgkBiIkbXPJ5KGk7PW+vcg/RXfTna2 rhyBHuxOFzZJkbckNqnJ2MffDWiv5rEBumYWzX0Vgoct9v07S/Ab1syEO+9dMCPJhp ZYK+yxbrXG/adjU0ZHqX3gFH2nUPXK39C81s5kdQl1cfO+WSOL0/9rmeWLww25CaT2 p+FVmSkq8gCsNz8Xpf+v0DERwbLjXsP4IjqmeRdtdfyQnBUdyeuDvIF/rnpxu3u2Fv BI0ruAMqxAniPmv6HkM/cCfjopZEkXTqyEx3nOCBJmMFtP5PJuSPXLxKTQzI+06o/H XSQk3YD0uWadw== From: Kaustabh Chakraborty Date: Mon, 26 Jan 2026 21:09:49 +0530 Subject: [PATCH 2/2] power: supply: add support for S2MU005 battery fuel gauge device Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260126-s2mu005-fuelgauge-v1-2-68a146ed0819@disroot.org> References: <20260126-s2mu005-fuelgauge-v1-0-68a146ed0819@disroot.org> In-Reply-To: <20260126-s2mu005-fuelgauge-v1-0-68a146ed0819@disroot.org> To: Yassine Oudjana , Sebastian Reichel , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Kaustabh Chakraborty From: Yassine Oudjana Samsung's S2MU005 PMIC, which contains battery charger functionality also includes a battery fuel gauge device, which is separate from the PMIC itself, and typically connected to an I2C bus. Add a generic driver to support said device. Signed-off-by: Yassine Oudjana Co-developed-by: Kaustabh Chakraborty Signed-off-by: Kaustabh Chakraborty --- drivers/power/supply/Kconfig | 9 ++ drivers/power/supply/Makefile | 1 + drivers/power/supply/s2mu005-battery.c | 234 +++++++++++++++++++++++++++++= ++++ 3 files changed, 244 insertions(+) diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig index 92f9f7aae92f2..a5777309b1f62 100644 --- a/drivers/power/supply/Kconfig +++ b/drivers/power/supply/Kconfig @@ -229,6 +229,15 @@ config BATTERY_SAMSUNG_SDI Say Y to enable support for Samsung SDI battery data. These batteries are used in Samsung mobile phones. =20 +config BATTERY_S2MU005 + tristate "Samsung S2MU005 PMIC fuel gauge driver" + help + Say Y to enable support for the Samsung S2MU005 PMIC integrated + fuel gauge, which works indepenently of the PMIC battery charger + counterpart, and reports battery metrics. + + This driver, if built as a module, will be called s2mu005-fuel-gauge. + config BATTERY_COLLIE tristate "Sharp SL-5500 (collie) battery" depends on SA1100_COLLIE && MCP_UCB1200 diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile index 4b79d5abc49a7..cd061887c1727 100644 --- a/drivers/power/supply/Makefile +++ b/drivers/power/supply/Makefile @@ -40,6 +40,7 @@ obj-$(CONFIG_BATTERY_PMU) +=3D pmu_battery.o obj-$(CONFIG_BATTERY_QCOM_BATTMGR) +=3D qcom_battmgr.o obj-$(CONFIG_BATTERY_OLPC) +=3D olpc_battery.o obj-$(CONFIG_BATTERY_SAMSUNG_SDI) +=3D samsung-sdi-battery.o +obj-$(CONFIG_BATTERY_S2MU005) +=3D s2mu005-battery.o obj-$(CONFIG_BATTERY_COLLIE) +=3D collie_battery.o obj-$(CONFIG_BATTERY_INGENIC) +=3D ingenic-battery.o obj-$(CONFIG_BATTERY_INTEL_DC_TI) +=3D intel_dc_ti_battery.o diff --git a/drivers/power/supply/s2mu005-battery.c b/drivers/power/supply/= s2mu005-battery.c new file mode 100644 index 0000000000000..914308e82683b --- /dev/null +++ b/drivers/power/supply/s2mu005-battery.c @@ -0,0 +1,234 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Battery Fuel Gauge Driver for Samsung S2MU005 PMIC. + * + * Copyright (C) 2015 Samsung Electronics + * Copyright (C) 2023 Yassine Oudjana + * Copyright (C) 2025 Kaustabh Chakraborty + */ + +#include +#include +#include +#include +#include +#include +#include + +#define S2MU005_FG_REG_STATUS 0x00 +#define S2MU005_FG_REG_IRQ 0x02 +#define S2MU005_FG_REG_RVBAT 0x04 +#define S2MU005_FG_REG_RCUR_CC 0x06 +#define S2MU005_FG_REG_RSOC 0x08 +#define S2MU005_FG_REG_MONOUT 0x0a +#define S2MU005_FG_REG_MONOUT_SEL 0x0c +#define S2MU005_FG_REG_RBATCAP 0x0e +#define S2MU005_FG_REG_RZADJ 0x12 +#define S2MU005_FG_REG_RBATZ0 0x16 +#define S2MU005_FG_REG_RBATZ1 0x18 +#define S2MU005_FG_REG_IRQ_LVL 0x1a +#define S2MU005_FG_REG_START 0x1e + +struct s2mu005_fg { + struct device *dev; + struct regmap *regmap; + struct power_supply *psy; +}; + +static const struct regmap_config s2mu005_fg_regmap_config =3D { + .reg_bits =3D 8, + .val_bits =3D 8, +}; + +static irqreturn_t s2mu005_handle_irq(int irq, void *data) +{ + struct s2mu005_fg *priv =3D data; + + msleep(100); + power_supply_changed(priv->psy); + + return IRQ_HANDLED; +} + +static int s2mu005_fg_get_voltage_now(struct s2mu005_fg *priv, int *value) +{ + struct regmap *regmap =3D priv->regmap; + u16 reg; + int ret; + + ret =3D regmap_raw_read(regmap, S2MU005_FG_REG_RVBAT, ®, sizeof(reg)); + if (ret < 0) { + dev_err(priv->dev, "failed to read voltage register (%d)\n", ret); + return ret; + } + + *value =3D ((unsigned long)reg * 1000000) >> 13; /* uV */ + + return 0; +} + +static int s2mu005_fg_get_current_now(struct s2mu005_fg *priv, int *value) +{ + struct regmap *regmap =3D priv->regmap; + s16 reg; + int ret; + + ret =3D regmap_raw_read(regmap, S2MU005_FG_REG_RCUR_CC, ®, sizeof(reg)= ); + if (ret < 0) { + dev_err(priv->dev, "failed to read current register (%d)\n", ret); + return ret; + } + + *value =3D -((long)reg * 1000000) >> 12; /* uA */ + + return 0; +} + +static int s2mu005_fg_get_capacity(struct s2mu005_fg *priv, int *value) +{ + struct regmap *regmap =3D priv->regmap; + s16 reg; + int ret; + + ret =3D regmap_raw_read(regmap, S2MU005_FG_REG_RSOC, ®, sizeof(reg)); + if (ret < 0) { + dev_err(priv->dev, "failed to read capacity register (%d)\n", ret); + return ret; + } + + *value =3D (reg * 100) >> 14; /* percentage */ + + return 0; +} + +static int s2mu005_fg_get_status(struct s2mu005_fg *priv, int *value) +{ + int current_now; + int capacity; + int ret; + + ret =3D s2mu005_fg_get_current_now(priv, ¤t_now); + if (ret) + return ret; + + if (current_now <=3D 0) { + *value =3D POWER_SUPPLY_STATUS_DISCHARGING; + return 0; + } + + ret =3D s2mu005_fg_get_capacity(priv, &capacity); + if (ret) + return ret; + + if (capacity < 90) + *value =3D POWER_SUPPLY_STATUS_CHARGING; + else + *value =3D POWER_SUPPLY_STATUS_FULL; + + return 0; +} + +static const enum power_supply_property s2mu005_fg_properties[] =3D { + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_CURRENT_NOW, + POWER_SUPPLY_PROP_CAPACITY, + POWER_SUPPLY_PROP_STATUS, +}; + +static int s2mu005_fg_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct s2mu005_fg *priv =3D power_supply_get_drvdata(psy); + int ret =3D 0; + + switch (psp) { + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + ret =3D s2mu005_fg_get_voltage_now(priv, &val->intval); + break; + case POWER_SUPPLY_PROP_CURRENT_NOW: + ret =3D s2mu005_fg_get_current_now(priv, &val->intval); + break; + case POWER_SUPPLY_PROP_CAPACITY: + ret =3D s2mu005_fg_get_capacity(priv, &val->intval); + break; + case POWER_SUPPLY_PROP_STATUS: + ret =3D s2mu005_fg_get_status(priv, &val->intval); + break; + default: + return -EINVAL; + } + + return ret; +} + +static const struct power_supply_desc s2mu005_fg_desc =3D { + .name =3D "s2mu005-fuel-gauge", + .type =3D POWER_SUPPLY_TYPE_BATTERY, + .properties =3D s2mu005_fg_properties, + .num_properties =3D ARRAY_SIZE(s2mu005_fg_properties), + .get_property =3D s2mu005_fg_get_property, +}; + +static int s2mu005_fg_i2c_probe(struct i2c_client *client) +{ + struct device *dev =3D &client->dev; + struct s2mu005_fg *priv; + struct power_supply_config psy_cfg =3D {}; + const struct power_supply_desc *psy_desc; + int flags; + int ret; + + priv =3D devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return dev_err_probe(dev, -ENOMEM, + "failed to allocate driver private\n"); + + dev_set_drvdata(dev, priv); + priv->dev =3D dev; + + priv->regmap =3D devm_regmap_init_i2c(client, &s2mu005_fg_regmap_config); + if (IS_ERR(priv->regmap)) + return dev_err_probe(dev, PTR_ERR(priv->regmap), + "failed to initialize regmap\n"); + + psy_desc =3D device_get_match_data(dev); + + psy_cfg.drv_data =3D priv; + priv->psy =3D devm_power_supply_register(priv->dev, psy_desc, &psy_cfg); + if (IS_ERR(priv->psy)) + return dev_err_probe(dev, PTR_ERR(priv->psy), + "failed to register power supply subsystem\n"); + + flags =3D irq_get_trigger_type(client->irq); + + ret =3D devm_request_threaded_irq(priv->dev, client->irq, NULL, + s2mu005_handle_irq, IRQF_ONESHOT | flags, + psy_desc->name, priv); + if (ret) + dev_err_probe(dev, ret, "failed to request IRQ\n"); + + return 0; +} + +static const struct of_device_id s2mu005_fg_of_match_table[] =3D { + { + .compatible =3D "samsung,s2mu005-fuel-gauge", + .data =3D &s2mu005_fg_desc, + }, { }, +}; +MODULE_DEVICE_TABLE(of, s2mu005_fg_of_match_table); + +static struct i2c_driver s2mu005_fg_i2c_driver =3D { + .probe =3D s2mu005_fg_i2c_probe, + .driver =3D { + .name =3D "s2mu005-fuel-gauge", + .of_match_table =3D of_match_ptr(s2mu005_fg_of_match_table), + }, +}; +module_i2c_driver(s2mu005_fg_i2c_driver); + +MODULE_DESCRIPTION("Samsung S2MU005 PMIC Battery Fuel Gauge Driver"); +MODULE_AUTHOR("Yassine Oudjana "); +MODULE_AUTHOR("Kaustabh Chakraborty "); +MODULE_LICENSE("GPL"); --=20 2.52.0