Skip to contentSkip to conversation

Add Anbernic RG Vita-Pro

PATCH Superseded Chris Morgan 2 participants 6 messages Jul 21

Subsystems (3)

v8 of 10 Superseded Latest is v10 →

lore
Share & tools
lore
#0 lore raw

v8 cover Add Anbernic RG Vita-Pro

From: Chris Morgan <[email protected]>

Add support for the Anbernic RG Vita-Pro, based on the Rockchip RK3576 SoC.

Changes Since V1:
- Updated documentation filename to matche compatible string.
- Corrected order of allocating IRQ in charger driver and switched to using devm managed function to allocate work queue.
Changes Since V2:
- Corrected issue with naming of panel binding document and added fallback compatible string.
- Switched to devm helpers in panel driver. Note that devm_drm_panel_add() is currently only in the drm-next branch.
- Optimized setting GPIOs for panel driver.
Changes Since V3:
- Fixed numerous issues identifed by Sashiko bot, mainly relating to unclamped or improperly clamped values from within the charger driver.
- Corrected hard-coded values in the panel driver unprepare routine as well as correcting an improperly checked return condition.
Changes Since V4:
- Fixed errors identified by Sashiko bot on charger driver that could result in an improper value being written to the registers.
- Corrected some error handling in the panel driver.
Changes Since V5:
- Corrected minor errors in documentation and added default values.
- Further corrected clamping behavior in charger driver.
Changes Since V6:
- Additional corrections as suggested by Sashiko bot to fix potential edge cases during probe for sgm41542.
- Corrected an improperly shifted value being written to register for sgm41542.
- Changed a MV value to UV in sgm41542 driver to simplify function.
Changes Since V7:
- Added PM functions to sgm41542 driver per request from Sashiko, which stops the hardware watchdog during suspend.
- Switched from device_init_wakeup() to devm_device_init_wakeup().
- Confirmed a state change in IRQ handler for sgm41542 to ensure we don't update input current limit except when the vbus goes from not okay to okay.
- Removed panel patches, which have already been accepted upstream. Please note that this *may* cause an error about missing bindings. See commit 0fd6ead8270270d859a28d0196a4b47e7d6845b8 in linux-next.

Chris Morgan (4):
dt-bindings: power: supply: sgm41542: document sgm41542
power: supply: sgm41542: Add SG Micro sgm41542 charger
dt-bindings: arm: rockchip: Add Anbernic RG Vita-Pro
arm64: dts: rockchip: Add Anbernic RG Vita-Pro

 .../devicetree/bindings/arm/rockchip.yaml     |    6 +
 .../power/supply/sgmicro,sgm41542.yaml        |   96 ++
 arch/arm64/boot/dts/rockchip/Makefile         |    1 +
 .../rockchip/rk3576-anbernic-rg-vita-pro.dts  | 1327 +++++++++++++++++
 drivers/power/supply/Kconfig                  |    8 +
 drivers/power/supply/Makefile                 |    1 +
 drivers/power/supply/sgm41542_charger.c       | 1111 ++++++++++++++
 7 files changed, 2550 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/power/supply/sgmicro,sgm41542.yaml
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3576-anbernic-rg-vita-pro.dts
 create mode 100644 drivers/power/supply/sgm41542_charger.c
Signature · 1 line
2.43.0
#1 lore raw

PATCH v8 1/4 dt-bindings: power: supply: sgm41542: document sgm41542

From: Chris Morgan <[email protected]>

Document the SG Micro sgm41542 battery charger/boost converter. The parameters of input-current-limit-microamp and input-voltage-limit-microvolt are defined as such since they are in common use among multiple bindings currently.

---
 .../power/supply/sgmicro,sgm41542.yaml        | 96 +++++++++++++++++++
 1 file changed, 96 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/power/supply/sgmicro,sgm41542.yaml
Documentation/devicetree/bindings/power/supply/sgmicro,sgm41542.yaml new file +96 -0
new file mode 100644
index 000000000000..af80fe528505
@@ -0,0 +1,96 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/power/supply/sgmicro,sgm41542.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SGM41542 Battery Charger
+
+description:
+  The SGMicro SGM41542 is a single cell battery charger/boost controller.
+
+maintainers:
+  - Chris Morgan <[email protected]>
+  - Xu Shengfei <[email protected]>
+
+allOf:
+  - $ref: power-supply.yaml#
+
+properties:
+  compatible:
+    const: sgmicro,sgm41542
+
+  input-current-limit-microamp:
+    default: 2400000
+    minimum: 100000
+    maximum: 3800000
+
+  input-voltage-limit-microvolt:
+    default: 4500000
+    minimum: 3900000
+    maximum: 12000000
+
+  interrupts:
+    maxItems: 1
+
+  monitored-battery:
+    description: |
+        The charger uses the following battery properties
+        constant-charge-current-max-microamp (default 2040000)
+        constant-charge-voltage-max-microvolt (default 4208000)
+        charge-term-current-microamp (default 180000)
+        precharge-current-microamp (default 180000)
+
+  reg:
+    maxItems: 1
+
+  regulators:
+    type: object
+    properties:
+      otg-vbus:
+        type: object
+        description: OTG boost regulator
+        $ref: /schemas/regulator/regulator.yaml
+        unevaluatedProperties: false
+    additionalProperties: false
+
+required:
+  - compatible
+  - reg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    battery: battery {
+      compatible = "simple-battery";
+      constant-charge-current-max-microamp = <10000000>;
+      constant-charge-voltage-max-microvolt = <4350000>;
+      precharge-current-microamp = <180000>;
+      charge-term-current-microamp = <300000>;
+    };
+
+    i2c {
+      #address-cells = <1>;
+      #size-cells = <0>;
+
+      charger@3b {
+        compatible = "sgmicro,sgm41542";
+        reg = <0x3b>;
+        input-current-limit-microamp = <3000000>;
+        input-voltage-limit-microvolt = <4500000>;
+        interrupt-parent = <&gpio0>;
+        interrupts = <26 IRQ_TYPE_EDGE_FALLING>;
+        monitored-battery = <&battery>;
+
+        regulators {
+          otg-vbus {
+            regulator-max-microvolt = <5000000>;
+            regulator-min-microvolt = <5000000>;
+          };
+        };
+      };
+    };
Signature · 1 line
2.43.0
#2 lore raw

PATCH v8 2/4 power: supply: sgm41542: Add SG Micro sgm41542 charger

In reply to Chris Morgan

From: Chris Morgan <[email protected]>

Add support for the SG Micro SGM41542 charger/boost converter. Driver was adapted from Rockchip BSP driver [1] and confirmed with vendor datasheet [2].

[1] https://github.com/rockchip-linux/kernel/blob/develop-6.6/drivers/power/supply/sgm41542_charger.c
[2] https://www.sg-micro.de/rect/assets/1e8de70b-657e-4156-be68-a64fdbe8e418/SGM41541_SGM41542.pdf

---
 drivers/power/supply/Kconfig            |    8 +
 drivers/power/supply/Makefile           |    1 +
 drivers/power/supply/sgm41542_charger.c | 1111 +++++++++++++++++++++++
 3 files changed, 1120 insertions(+)
 create mode 100644 drivers/power/supply/sgm41542_charger.c
drivers/power/supply/Kconfig +8 -0
index f0ede1cecb6a..dadda6b78a03 100644
@@ -866,6 +866,14 @@ config CHARGER_S2M
 	  devices provide USB power supply information and also required
 	  for USB OTG role switching.
 
+config CHARGER_SGM41542
+	tristate "SGM41542 charger driver"
+	depends on I2C
+	depends on GPIOLIB || COMPILE_TEST
+	select REGMAP_I2C
+	help
+	  Say Y to enable support for the SGM41542 battery charger.
+
 config CHARGER_SMB347
 	tristate "Summit Microelectronics SMB3XX Battery Charger"
 	depends on I2C
drivers/power/supply/Makefile +1 -0
index 31fe4a145929..25d23ea3fcbd 100644
@@ -108,6 +108,7 @@ obj-$(CONFIG_CHARGER_BQ25980)	+= bq25980_charger.o
 obj-$(CONFIG_CHARGER_BQ256XX)	+= bq256xx_charger.o
 obj-$(CONFIG_CHARGER_RK817)	+= rk817_charger.o
 obj-$(CONFIG_CHARGER_S2M)	+= s2m-charger.o
+obj-$(CONFIG_CHARGER_SGM41542)	+= sgm41542_charger.o
 obj-$(CONFIG_CHARGER_SMB347)	+= smb347-charger.o
 obj-$(CONFIG_CHARGER_TPS65090)	+= tps65090-charger.o
 obj-$(CONFIG_CHARGER_TPS65217)	+= tps65217_charger.o
drivers/power/supply/sgm41542_charger.c new file +1111 -0

1,111 lines not on this page · raw message

Signature · 1 line
2.43.0
#3 lore raw

Re: [PATCH V8 2/4] power: supply: sgm41542: Add SG Micro sgm41542 charger

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider: - [High] Lockless update of cached device state in `get_property` causes lost IRQ edge detection and data…

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] Lockless update of cached device state in get_property causes lost IRQ edge detection and data tearing.
- [High] The hardware charger watchdog is permanently disabled after the first system suspend/resume cycle.
- [Medium] The power supply is registered and exposed to userspace before its initialization data is populated, causing a race condition on sysfs property accesses.
- [Low] Missing dependency on REGULATOR in Kconfig causes build failures.
--

--- Patch [2]: [PATCH V8 2/4] power: supply: sgm41542: Add SG Micro sgm41542 charger --- commit 3abcd77069baeaee08cbb10755bbd687ee39d41c

Author: Chris Morgan <[email protected]>
Date:   Tue Jul 21 17:09:05 2026 +0000

power: supply: sgm41542: Add SG Micro sgm41542 charger

Add support for the SG Micro SGM41542 charger/boost converter. Driver was adapted from Rockchip BSP driver and confirmed with vendor datasheet.

[1] https://github.com/rockchip-linux/kernel/blob/develop-6.6/drivers/power/supply/sgm41542_charger.c
[2] https://www.sg-micro.de/rect/assets/1e8de70b-657e-4156-be68-a64fdbe8e418/SGM41541_SGM41542.pdf

drivers/power/supply/Kconfig config CHARGER_S2M · line 873

Quoted 12 lines
drivers/power/supply/Kconfig +5 -0
@@ -866,6 +866,14 @@ config CHARGER_S2M
 	  devices provide USB power supply information and also required
 	  for USB OTG role switching.
 
+config CHARGER_SGM41542
+	tristate "SGM41542 charger driver"
+	depends on I2C
+	depends on GPIOLIB || COMPILE_TEST
+	select REGMAP_I2C

[Severity: Low]
Since this driver provides a regulator via devm_regulator_register(), should this also depend on REGULATOR to prevent build failures when the regulator subsystem is disabled?

[ ... ]

Quoted 4 lines
drivers/power/supply/sgm41542_charger.c new file +0 -0
new file mode 100644

[ ... ]

Quoted 4 lines
drivers/power/supply/sgm41542_charger.c new file +4 -0
+static int sgm4154x_charger_get_property(struct power_supply *psy,
+					 enum power_supply_property psp,
+					 union power_supply_propval *val)
+{

drivers/power/supply/sgm41542_charger.c line 641

Quoted 10 lines
drivers/power/supply/sgm41542_charger.c new file +10 -0
+	struct sgm4154x_device *sgm = power_supply_get_drvdata(psy);
+	struct sgm4154x_state state;
+	int ret;
+
+	ret = sgm4154x_get_state(sgm, &state);
+	if (ret) {
+		dev_err(sgm->dev, "get state error!\n");
+		return ret;
+	}
+	sgm->state = state;

[Severity: High]
Could this lockless update of sgm->state interfere with the edge detection in the IRQ handler?

If a sysfs read calls this function concurrently with an interrupt, it updates sgm->state before the IRQ handler can read the old state:

sysfs read thread:

    sgm4154x_get_state(sgm, &state);
    sgm->state = state; // updated to the new state

IRQ thread (sgm4154x_irq_handler_thread):

    struct sgm4154x_state oldstate = sgm4154x->state; // reads newly updated state
    ...
    if (state.vbus_gd && !oldstate.vbus_gd) { // fails because oldstate already has vbus_gd

This could cause the driver to miss edge transitions, like failing to apply the input current limit on cable insertion. Additionally, since the state struct is multi-byte, can this assignment cause data tearing if readers are accessing it concurrently?

[ ... ]

Quoted 5 lines
drivers/power/supply/sgm41542_charger.c new file +5 -0
+static int sgm4154x_probe(struct i2c_client *client)
+{
+	struct device *dev = &client->dev;
+	struct sgm4154x_device *sgm;
+	int ret;

[ ... ]

Quoted 7 lines
drivers/power/supply/sgm41542_charger.c new file +7 -0
+	sgm->sgm_monitor_wq = devm_alloc_ordered_workqueue(dev, "sgm-monitor-wq",
+			WQ_MEM_RECLAIM | WQ_FREEZABLE);
+	if (!sgm->sgm_monitor_wq)
+		return -EINVAL;
+
+	ret = devm_delayed_work_autocancel(dev, &sgm->sgm_delay_work,
+					   sgm_charger_work);

drivers/power/supply/sgm41542_charger.c line 1030

Quoted 10 lines
drivers/power/supply/sgm41542_charger.c new file +10 -0
+	if (ret)
+		return dev_err_probe(dev, ret, "Unable to register delayed work\n");
+
+	ret = sgm4154x_power_supply_init(sgm, dev);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to register power supply\n");
+
+	ret = sgm4154x_hw_init(sgm);
+	if (ret)
+		return dev_err_probe(dev, ret, "Cannot initialize the chip.\n");

[Severity: Medium]
Is there a race condition here if userspace accesses sysfs properties immediately after power supply registration?

devm_power_supply_register() (called via sgm4154x_power_supply_init) exposes the device before sgm4154x_hw_init() populates the safety limits in sgm->init_data.

If a udev rule or userspace polling attempts to configure charge limits during this window, could it bypass the intended hardware bounds because the limit variables are still zeroed?

[ ... ]

Quoted 14 lines
drivers/power/supply/sgm41542_charger.c new file +14 -0
+static int __maybe_unused sgm4154x_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct sgm4154x_device *sgm = i2c_get_clientdata(client);
+
+	/*
+	 * Disable watchdog during suspend and stop delayed work. When
+	 * delayed work is restarted after resume watchdog will be
+	 * re-enabled if it was previously enabled.
+	 */
+	sgm4154x_set_watchdog_timer(sgm, SGM4154X_WDT_TIMER_DISABLE);
+	cancel_delayed_work_sync(&sgm->sgm_delay_work);
+	return 0;
+}

drivers/power/supply/sgm41542_charger.c line 1081

Quoted 10 lines
drivers/power/supply/sgm41542_charger.c new file +10 -0
+
+static int __maybe_unused sgm4154x_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct sgm4154x_device *sgm = i2c_get_clientdata(client);
+
+	queue_delayed_work(sgm->sgm_monitor_wq,
+			   &sgm->sgm_delay_work, 0);
+	return 0;
+}

[Severity: High]
Will the charger watchdog be permanently disabled after the first suspend and resume cycle?

When sgm4154x_suspend() calls sgm4154x_set_watchdog_timer() with SGM4154X_WDT_TIMER_DISABLE, it destructively clears sgm->watchdog_enable to false.

On resume, queue_delayed_work() schedules the monitor work, but sgm_charger_work() checks this flag:

static void sgm_charger_work(struct work_struct *work)

{
    ...
    if (sgm->watchdog_enable)
        queue_delayed_work(...)
}

Because the flag was wiped during suspend, the timer is never requeued or re-enabled, potentially leaving the hardware unprotected against overcharging if the system were to crash later.

Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=2
#4 lore raw

PATCH v8 3/4 dt-bindings: arm: rockchip: Add Anbernic RG Vita-Pro

In reply to Chris Morgan

From: Chris Morgan <[email protected]>

Add compatible string for the Anbernic RG Vita-Pro.

---
 Documentation/devicetree/bindings/arm/rockchip.yaml | 6 ++++++
 1 file changed, 6 insertions(+)
Documentation/devicetree/bindings/arm/rockchip.yaml +6 -0
index 1a9dde18626d..b8babe9d3a26 100644
@@ -66,6 +66,12 @@ properties:
               - anbernic,rg-ds
           - const: rockchip,rk3568
 
+      - description: Anbernic RK3576 Handheld Gaming Console
+        items:
+          - enum:
+              - anbernic,rg-vita-pro
+          - const: rockchip,rk3576
+
       - description: Ariaboard Photonicat
         items:
           - const: ariaboard,photonicat
Signature · 1 line
2.43.0
#5 lore raw

PATCH v8 4/4 arm64: dts: rockchip: Add Anbernic RG Vita-Pro

In reply to Chris Morgan

From: Chris Morgan <[email protected]>

Add device tree for the Anbernic RG Vita-Pro, based on the Rockchip RK3576. All hardware is currently working except for the accelerometer, the touchscreen, the battery monitor, and DisplayPort over USB-C. PWM is also missing currently, and as a result the LEDs and panel backlight are currently controlled via GPIO but will be changed to PWM once supported.

The Anbernic RG Vita-Pro includes the following hardware:
- A 1080x1920 DSI display with touch.
- 21 buttons.
- 3 LEDs.
- 64GB eMMC, 2 SDMMC slots.
- RTL8852BE WiFi (with Bluetooth via UART)
- 1 USB 3.0 USB-C port in OTG mode.
- 3.5mm headphone jack with play button support.
- 5000mAH battery

The following hardware has incomplete driver support and is not yet working:
- An Invensense icm42607p accelerometer.
- A Cellwise cw221x battery monitor.
- A Synaptics i2c touchscreen.
- DisplayPort over USB-C alt-mode.
- PWM controller.
- 2 Analog joysticks with LED controllers.

---
 arch/arm64/boot/dts/rockchip/Makefile         |    1 +
 .../rockchip/rk3576-anbernic-rg-vita-pro.dts  | 1327 +++++++++++++++++
 2 files changed, 1328 insertions(+)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3576-anbernic-rg-vita-pro.dts
arch/arm64/boot/dts/rockchip/Makefile +1 -0
index 761d82b4f4f2..7b003bc45dea 100644
@@ -165,6 +165,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-wolfvision-pf5.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-wolfvision-pf5-display-vz.dtbo
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-wolfvision-pf5-io-expander.dtbo
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-100ask-dshanpi-a1.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-anbernic-rg-vita-pro.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-armsom-sige5.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-armsom-sige5-v1.2-wifibt.dtbo
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-evb1-v10.dtb
arch/arm64/boot/dts/rockchip/rk3576-anbernic-rg-vita-pro.dts new file +1327 -0

1,327 lines not on this page · raw message

Signature · 1 line
2.43.0