mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v2 0/7] leds: aw2013: Add AW2027 support
@ 2026-10-06  3:46 Paul Sajna
  2026-10-06  3:46 ` [PATCH v2 1/7] dt-bindings: leds: aw2013: Add awinic,aw2027 compatible Paul Sajna
                   ` (6 more replies)
  0 siblings, 7 replies; 11+ messages in thread
From: Paul Sajna @ 2026-10-06  3:46 UTC (permalink / raw)
  To: Lee Jones, Pavel Machek, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Nikita Travkin, Alexey Min
  Cc: linux-leds, devicetree, linux-kernel, phone-devel,
	~postmarketos/upstreaming, Paul Sajna

Refer to PATCH 3 for a full description of the similarities and
differences between AW2013 and AW2027.

Several pre-existing bugs were also caught by Sashiko Review
and fixed in this patch-series. The joys of LLM-inflicted bikeshedding.

This PATCH resulted out of discussions pertaining to
sdm660-mainline/linux, a close-to-mainline fork for Qualcomm Snapdragon 660
devices, specifically for the BlackBerry KEY2 Keyboard Backlight,
in the following GitHub PR: https://github.com/sdm660-mainline/linux/pull/218

Signed-off-by: Paul Sajna <sajattack@postmarketos.org>
---
Changes in v2:
- Reduce renames to internal driver scope, to prevent breaking compat
- Address Sashiko Review Comments
- Split renames into a separate commit to make the actual changes easier
to identify
- Change from RFC to PATCH
- Link to v1: https://lore.kernel.org/r/20260907-aw2013-aw20xx-rename-v1-0-c9a7df12a701@postmarketos.org

---
Paul Sajna (7):
      dt-bindings: leds: aw2013: Add awinic,aw2027 compatible
      leds: aw2013: Rename internal APIs from aw2013 to aw20xx
      leds: aw2013: Add AW2027 support
      leds: aw2013: use dev_err_probe
      leds: aw2013: Move assignment of chip->num_leds
      leds: aw2013: Prevent writes to unpowered chip
      leds: aw2013: move reset from probe_dt to chip_init

 .../devicetree/bindings/leds/leds-aw2013.yaml      |   6 +-
 drivers/leds/leds-aw2013.c                         | 351 +++++++++++++--------
 2 files changed, 229 insertions(+), 128 deletions(-)
---
base-commit: 944a035ecca915ae947905dcfb03f2b9dc6d032c
change-id: 20260907-aw2013-aw20xx-rename-df233c5921c6

Best regards,
-- 
Paul Sajna <sajattack@postmarketos.org>


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 1/7] dt-bindings: leds: aw2013: Add awinic,aw2027 compatible
  2026-10-06  3:46 [PATCH v2 0/7] leds: aw2013: Add AW2027 support Paul Sajna
@ 2026-10-06  3:46 ` Paul Sajna
  2026-10-06  3:46 ` [PATCH v2 2/7] leds: aw2013: Rename internal APIs from aw2013 to aw20xx Paul Sajna
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Paul Sajna @ 2026-10-06  3:46 UTC (permalink / raw)
  To: Lee Jones, Pavel Machek, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Nikita Travkin, Alexey Min
  Cc: linux-leds, devicetree, linux-kernel, phone-devel,
	~postmarketos/upstreaming, Paul Sajna

Very similar chip from the same family to be added

Signed-off-by: Paul Sajna <sajattack@postmarketos.org>
---
 Documentation/devicetree/bindings/leds/leds-aw2013.yaml | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/leds/leds-aw2013.yaml b/Documentation/devicetree/bindings/leds/leds-aw2013.yaml
index 26238446f2bd..1ad165cfe34a 100644
--- a/Documentation/devicetree/bindings/leds/leds-aw2013.yaml
+++ b/Documentation/devicetree/bindings/leds/leds-aw2013.yaml
@@ -4,7 +4,7 @@
 $id: http://devicetree.org/schemas/leds/leds-aw2013.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: AWINIC AW2013 3-channel LED Driver
+title: AWINIC AW2013/AW2027 3-channel LED Driver
 
 maintainers:
   - Nikita Travkin <nikitos.tr@gmail.com>
@@ -15,7 +15,9 @@ description: |
 
 properties:
   compatible:
-    const: awinic,aw2013
+    enum:
+      - awinic,aw2013
+      - awinic,aw2027
 
   reg:
     maxItems: 1

-- 
2.55.0


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 2/7] leds: aw2013: Rename internal APIs from aw2013 to aw20xx
  2026-10-06  3:46 [PATCH v2 0/7] leds: aw2013: Add AW2027 support Paul Sajna
  2026-10-06  3:46 ` [PATCH v2 1/7] dt-bindings: leds: aw2013: Add awinic,aw2027 compatible Paul Sajna
@ 2026-10-06  3:46 ` Paul Sajna
  2026-10-06 10:45   ` Griffin Kroah-Hartman
  2026-10-06  3:46 ` [PATCH v2 3/7] leds: aw2013: Add AW2027 support Paul Sajna
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 11+ messages in thread
From: Paul Sajna @ 2026-10-06  3:46 UTC (permalink / raw)
  To: Lee Jones, Pavel Machek, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Nikita Travkin, Alexey Min
  Cc: linux-leds, devicetree, linux-kernel, phone-devel,
	~postmarketos/upstreaming, Paul Sajna

We don't want to break external compatibility, but it's better
if the things shared between aw2013 and aw2027 have generic names.

Split into a separate commit to reduce noise in the upcoming commits

Signed-off-by: Paul Sajna <sajattack@postmarketos.org>
---
 drivers/leds/leds-aw2013.c | 182 ++++++++++++++++++++++-----------------------
 1 file changed, 91 insertions(+), 91 deletions(-)

diff --git a/drivers/leds/leds-aw2013.c b/drivers/leds/leds-aw2013.c
index 216755d6010f..ae3c8131efb4 100644
--- a/drivers/leds/leds-aw2013.c
+++ b/drivers/leds/leds-aw2013.c
@@ -9,72 +9,72 @@
 #include <linux/of.h>
 #include <linux/regmap.h>
 
-#define AW2013_MAX_LEDS 3
+#define AW20XX_MAX_LEDS 3
 
 /* Reset and ID register */
-#define AW2013_RSTR 0x00
-#define AW2013_RSTR_RESET 0x55
-#define AW2013_RSTR_CHIP_ID 0x33
+#define AW20XX_RSTR 0x00
+#define AW20XX_RSTR_RESET 0x55
 
 /* Global control register */
-#define AW2013_GCR 0x01
-#define AW2013_GCR_ENABLE BIT(0)
+#define AW20XX_GCR 0x01
+#define AW20XX_GCR_ENABLE BIT(0)
 
 /* LED channel enable register */
-#define AW2013_LCTR 0x30
-#define AW2013_LCTR_LE(x) BIT((x))
+#define AW20XX_LCTR 0x30
+#define AW20XX_LCTR_LE(x) BIT((x))
 
 /* LED channel control registers */
-#define AW2013_LCFG(x) (0x31 + (x))
-#define AW2013_LCFG_IMAX_MASK (BIT(0) | BIT(1)) // Should be 0-3
-#define AW2013_LCFG_MD BIT(4)
-#define AW2013_LCFG_FI BIT(5)
-#define AW2013_LCFG_FO BIT(6)
+#define AW20XX_LCFG(x) (0x31 + (x))
+#define AW20XX_LCFG_IMAX_MASK (BIT(0) | BIT(1)) // Should be 0-3
+#define AW20XX_LCFG_MD BIT(4)
+#define AW20XX_LCFG_FI BIT(5)
+#define AW20XX_LCFG_FO BIT(6)
 
 /* LED channel PWM registers */
-#define AW2013_REG_PWM(x) (0x34 + (x))
+#define AW20XX_REG_PWM(x) (0x34 + (x))
 
 /* LED channel timing registers */
-#define AW2013_LEDT0(x) (0x37 + (x) * 3)
-#define AW2013_LEDT0_T1(x) ((x) << 4) // Should be 0-7
-#define AW2013_LEDT0_T2(x) (x) // Should be 0-5
+#define AW20XX_LEDT0(x) (0x37 + (x) * 3)
+#define AW20XX_LEDT0_T1(x) ((x) << 4) // Should be 0-7
+#define AW20XX_LEDT0_T2(x) (x) // Should be 0-5
 
-#define AW2013_LEDT1(x) (0x38 + (x) * 3)
-#define AW2013_LEDT1_T3(x) ((x) << 4) // Should be 0-7
-#define AW2013_LEDT1_T4(x) (x) // Should be 0-7
+#define AW20XX_LEDT1(x) (0x38 + (x) * 3)
+#define AW20XX_LEDT1_T3(x) ((x) << 4) // Should be 0-7
+#define AW20XX_LEDT1_T4(x) (x) // Should be 0-7
 
-#define AW2013_LEDT2(x) (0x39 + (x) * 3)
-#define AW2013_LEDT2_T0(x) ((x) << 4) // Should be 0-8
-#define AW2013_LEDT2_REPEAT(x) (x) // Should be 0-15
+#define AW20XX_LEDT2(x) (0x39 + (x) * 3)
+#define AW20XX_LEDT2_T0(x) ((x) << 4) // Should be 0-8
+#define AW20XX_LEDT2_REPEAT(x) (x) // Should be 0-15
 
-#define AW2013_REG_MAX 0x77
+#define AW20XX_TIME_STEP 130 /* ms */
 
-#define AW2013_TIME_STEP 130 /* ms */
+#define AW2013_RSTR_CHIP_ID 0x33
+#define AW2013_REG_MAX 0x77
 
-struct aw2013;
+struct aw20xx;
 
-struct aw2013_led {
-	struct aw2013 *chip;
+struct aw20xx_led {
+	struct aw20xx *chip;
 	struct led_classdev cdev;
 	u32 num;
 	unsigned int imax;
 };
 
-struct aw2013 {
+struct aw20xx {
 	struct mutex mutex; /* held when writing to registers */
 	struct regulator_bulk_data regulators[2];
 	struct i2c_client *client;
-	struct aw2013_led leds[AW2013_MAX_LEDS];
+	struct aw20xx_led leds[AW20XX_MAX_LEDS];
 	struct regmap *regmap;
 	int num_leds;
 	bool enabled;
 };
 
-static int aw2013_chip_init(struct aw2013 *chip)
+static int aw20xx_chip_init(struct aw20xx *chip)
 {
 	int i, ret;
 
-	ret = regmap_write(chip->regmap, AW2013_GCR, AW2013_GCR_ENABLE);
+	ret = regmap_write(chip->regmap, AW20XX_GCR, AW20XX_GCR_ENABLE);
 	if (ret) {
 		dev_err(&chip->client->dev, "Failed to enable the chip: %d\n",
 			ret);
@@ -83,8 +83,8 @@ static int aw2013_chip_init(struct aw2013 *chip)
 
 	for (i = 0; i < chip->num_leds; i++) {
 		ret = regmap_update_bits(chip->regmap,
-					 AW2013_LCFG(chip->leds[i].num),
-					 AW2013_LCFG_IMAX_MASK,
+					 AW20XX_LCFG(chip->leds[i].num),
+					 AW20XX_LCFG_IMAX_MASK,
 					 chip->leds[i].imax);
 		if (ret) {
 			dev_err(&chip->client->dev,
@@ -97,14 +97,14 @@ static int aw2013_chip_init(struct aw2013 *chip)
 	return ret;
 }
 
-static void aw2013_chip_disable(struct aw2013 *chip)
+static void aw20xx_chip_disable(struct aw20xx *chip)
 {
 	int ret;
 
 	if (!chip->enabled)
 		return;
 
-	regmap_write(chip->regmap, AW2013_GCR, 0);
+	regmap_write(chip->regmap, AW20XX_GCR, 0);
 
 	ret = regulator_bulk_disable(ARRAY_SIZE(chip->regulators),
 				     chip->regulators);
@@ -117,7 +117,7 @@ static void aw2013_chip_disable(struct aw2013 *chip)
 	chip->enabled = false;
 }
 
-static int aw2013_chip_enable(struct aw2013 *chip)
+static int aw20xx_chip_enable(struct aw20xx *chip)
 {
 	int ret;
 
@@ -133,14 +133,14 @@ static int aw2013_chip_enable(struct aw2013 *chip)
 	}
 	chip->enabled = true;
 
-	ret = aw2013_chip_init(chip);
+	ret = aw20xx_chip_init(chip);
 	if (ret)
-		aw2013_chip_disable(chip);
+		aw20xx_chip_disable(chip);
 
 	return ret;
 }
 
-static bool aw2013_chip_in_use(struct aw2013 *chip)
+static bool aw20xx_chip_in_use(struct aw20xx *chip)
 {
 	int i;
 
@@ -151,42 +151,42 @@ static bool aw2013_chip_in_use(struct aw2013 *chip)
 	return false;
 }
 
-static int aw2013_brightness_set(struct led_classdev *cdev,
+static int aw20xx_brightness_set(struct led_classdev *cdev,
 				 enum led_brightness brightness)
 {
-	struct aw2013_led *led = container_of(cdev, struct aw2013_led, cdev);
+	struct aw20xx_led *led = container_of(cdev, struct aw20xx_led, cdev);
 	int ret, num;
 
 	mutex_lock(&led->chip->mutex);
 
-	if (aw2013_chip_in_use(led->chip)) {
-		ret = aw2013_chip_enable(led->chip);
+	if (aw20xx_chip_in_use(led->chip)) {
+		ret = aw20xx_chip_enable(led->chip);
 		if (ret)
 			goto error;
 	}
 
 	num = led->num;
 
-	ret = regmap_write(led->chip->regmap, AW2013_REG_PWM(num), brightness);
+	ret = regmap_write(led->chip->regmap, AW20XX_REG_PWM(num), brightness);
 	if (ret)
 		goto error;
 
 	if (brightness) {
-		ret = regmap_update_bits(led->chip->regmap, AW2013_LCTR,
-					 AW2013_LCTR_LE(num), 0xFF);
+		ret = regmap_update_bits(led->chip->regmap, AW20XX_LCTR,
+					 AW20XX_LCTR_LE(num), 0xFF);
 	} else {
-		ret = regmap_update_bits(led->chip->regmap, AW2013_LCTR,
-					 AW2013_LCTR_LE(num), 0);
+		ret = regmap_update_bits(led->chip->regmap, AW20XX_LCTR,
+					 AW20XX_LCTR_LE(num), 0);
 		if (ret)
 			goto error;
-		ret = regmap_update_bits(led->chip->regmap, AW2013_LCFG(num),
-					 AW2013_LCFG_MD, 0);
+		ret = regmap_update_bits(led->chip->regmap, AW20XX_LCFG(num),
+					 AW20XX_LCFG_MD, 0);
 	}
 	if (ret)
 		goto error;
 
-	if (!aw2013_chip_in_use(led->chip))
-		aw2013_chip_disable(led->chip);
+	if (!aw20xx_chip_in_use(led->chip))
+		aw20xx_chip_disable(led->chip);
 
 error:
 	mutex_unlock(&led->chip->mutex);
@@ -194,10 +194,10 @@ static int aw2013_brightness_set(struct led_classdev *cdev,
 	return ret;
 }
 
-static int aw2013_blink_set(struct led_classdev *cdev,
+static int aw20xx_blink_set(struct led_classdev *cdev,
 			    unsigned long *delay_on, unsigned long *delay_off)
 {
-	struct aw2013_led *led = container_of(cdev, struct aw2013_led, cdev);
+	struct aw20xx_led *led = container_of(cdev, struct aw20xx_led, cdev);
 	int ret, num = led->num;
 	unsigned long off = 0, on = 0;
 
@@ -209,7 +209,7 @@ static int aw2013_blink_set(struct led_classdev *cdev,
 
 	if (!led->cdev.brightness) {
 		led->cdev.brightness = LED_FULL;
-		ret = aw2013_brightness_set(&led->cdev, led->cdev.brightness);
+		ret = aw20xx_brightness_set(&led->cdev, led->cdev.brightness);
 		if (ret)
 			return ret;
 	}
@@ -217,43 +217,43 @@ static int aw2013_blink_set(struct led_classdev *cdev,
 	/* Never on - just set to off */
 	if (!*delay_on) {
 		led->cdev.brightness = LED_OFF;
-		return aw2013_brightness_set(&led->cdev, LED_OFF);
+		return aw20xx_brightness_set(&led->cdev, LED_OFF);
 	}
 
 	mutex_lock(&led->chip->mutex);
 
 	/* Never off - brightness is already set, disable blinking */
 	if (!*delay_off) {
-		ret = regmap_update_bits(led->chip->regmap, AW2013_LCFG(num),
-					 AW2013_LCFG_MD, 0);
+		ret = regmap_update_bits(led->chip->regmap, AW20XX_LCFG(num),
+					 AW20XX_LCFG_MD, 0);
 		goto out;
 	}
 
 	/* Convert into values the HW will understand. */
-	off = min(5, ilog2((*delay_off - 1) / AW2013_TIME_STEP) + 1);
-	on = min(7, ilog2((*delay_on - 1) / AW2013_TIME_STEP) + 1);
+	off = min(5, ilog2((*delay_off - 1) / AW20XX_TIME_STEP) + 1);
+	on = min(7, ilog2((*delay_on - 1) / AW20XX_TIME_STEP) + 1);
 
-	*delay_off = BIT(off) * AW2013_TIME_STEP;
-	*delay_on = BIT(on) * AW2013_TIME_STEP;
+	*delay_off = BIT(off) * AW20XX_TIME_STEP;
+	*delay_on = BIT(on) * AW20XX_TIME_STEP;
 
 	/* Set timings */
 	ret = regmap_write(led->chip->regmap,
-			   AW2013_LEDT0(num), AW2013_LEDT0_T2(on));
+			   AW20XX_LEDT0(num), AW20XX_LEDT0_T2(on));
 	if (ret)
 		goto out;
 	ret = regmap_write(led->chip->regmap,
-			   AW2013_LEDT1(num), AW2013_LEDT1_T4(off));
+			   AW20XX_LEDT1(num), AW20XX_LEDT1_T4(off));
 	if (ret)
 		goto out;
 
 	/* Finally, enable the LED */
-	ret = regmap_update_bits(led->chip->regmap, AW2013_LCFG(num),
-				 AW2013_LCFG_MD, 0xFF);
+	ret = regmap_update_bits(led->chip->regmap, AW20XX_LCFG(num),
+				 AW20XX_LCFG_MD, 0xFF);
 	if (ret)
 		goto out;
 
-	ret = regmap_update_bits(led->chip->regmap, AW2013_LCTR,
-				 AW2013_LCTR_LE(num), 0xFF);
+	ret = regmap_update_bits(led->chip->regmap, AW20XX_LCTR,
+				 AW20XX_LCTR_LE(num), 0xFF);
 
 out:
 	mutex_unlock(&led->chip->mutex);
@@ -261,17 +261,17 @@ static int aw2013_blink_set(struct led_classdev *cdev,
 	return ret;
 }
 
-static int aw2013_probe_dt(struct aw2013 *chip)
+static int aw20xx_probe_dt(struct aw20xx *chip)
 {
 	struct device_node *np = dev_of_node(&chip->client->dev);
 	int count, ret = 0, i = 0;
-	struct aw2013_led *led;
+	struct aw20xx_led *led;
 
 	count = of_get_available_child_count(np);
-	if (!count || count > AW2013_MAX_LEDS)
+	if (!count || count > AW20XX_MAX_LEDS)
 		return -EINVAL;
 
-	regmap_write(chip->regmap, AW2013_RSTR, AW2013_RSTR_RESET);
+	regmap_write(chip->regmap, AW20XX_RSTR, AW20XX_RSTR_RESET);
 
 	for_each_available_child_of_node_scoped(np, child) {
 		struct led_init_data init_data = {};
@@ -279,7 +279,7 @@ static int aw2013_probe_dt(struct aw2013 *chip)
 		u32 imax;
 
 		ret = of_property_read_u32(child, "reg", &source);
-		if (ret != 0 || source >= AW2013_MAX_LEDS) {
+		if (ret != 0 || source >= AW20XX_MAX_LEDS) {
 			dev_err(&chip->client->dev,
 				"Couldn't read LED address: %d\n", ret);
 			count--;
@@ -299,8 +299,8 @@ static int aw2013_probe_dt(struct aw2013 *chip)
 				 "DT property led-max-microamp is missing\n");
 		}
 
-		led->cdev.brightness_set_blocking = aw2013_brightness_set;
-		led->cdev.blink_set = aw2013_blink_set;
+		led->cdev.brightness_set_blocking = aw20xx_brightness_set;
+		led->cdev.blink_set = aw20xx_blink_set;
 
 		ret = devm_led_classdev_register_ext(&chip->client->dev,
 						     &led->cdev, &init_data);
@@ -318,20 +318,20 @@ static int aw2013_probe_dt(struct aw2013 *chip)
 	return 0;
 }
 
-static void aw2013_chip_disable_action(void *data)
+static void aw20xx_chip_disable_action(void *data)
 {
-	aw2013_chip_disable(data);
+	aw20xx_chip_disable(data);
 }
 
-static const struct regmap_config aw2013_regmap_config = {
+static const struct regmap_config aw20xx_regmap_config = {
 	.reg_bits = 8,
 	.val_bits = 8,
 	.max_register = AW2013_REG_MAX,
 };
 
-static int aw2013_probe(struct i2c_client *client)
+static int aw20xx_probe(struct i2c_client *client)
 {
-	struct aw2013 *chip;
+	struct aw20xx *chip;
 	int ret;
 	unsigned int chipid;
 
@@ -348,7 +348,7 @@ static int aw2013_probe(struct i2c_client *client)
 	chip->client = client;
 	i2c_set_clientdata(client, chip);
 
-	chip->regmap = devm_regmap_init_i2c(client, &aw2013_regmap_config);
+	chip->regmap = devm_regmap_init_i2c(client, &aw20xx_regmap_config);
 	if (IS_ERR(chip->regmap)) {
 		ret = PTR_ERR(chip->regmap);
 		dev_err(&client->dev, "Failed to allocate register map: %d\n",
@@ -376,7 +376,7 @@ static int aw2013_probe(struct i2c_client *client)
 		goto error;
 	}
 
-	ret = regmap_read(chip->regmap, AW2013_RSTR, &chipid);
+	ret = regmap_read(chip->regmap, AW20XX_RSTR, &chipid);
 	if (ret) {
 		dev_err(&client->dev, "Failed to read chip ID: %d\n",
 			ret);
@@ -390,11 +390,11 @@ static int aw2013_probe(struct i2c_client *client)
 		goto error_reg;
 	}
 
-	ret = devm_add_action(&client->dev, aw2013_chip_disable_action, chip);
+	ret = devm_add_action(&client->dev, aw20xx_chip_disable_action, chip);
 	if (ret)
 		goto error_reg;
 
-	ret = aw2013_probe_dt(chip);
+	ret = aw20xx_probe_dt(chip);
 	if (ret < 0)
 		goto error_reg;
 
@@ -419,22 +419,22 @@ static int aw2013_probe(struct i2c_client *client)
 	return ret;
 }
 
-static const struct of_device_id aw2013_match_table[] = {
+static const struct of_device_id aw20xx_match_table[] = {
 	{ .compatible = "awinic,aw2013", },
 	{ /* sentinel */ },
 };
 
-MODULE_DEVICE_TABLE(of, aw2013_match_table);
+MODULE_DEVICE_TABLE(of, aw20xx_match_table);
 
-static struct i2c_driver aw2013_driver = {
+static struct i2c_driver aw20xx_driver = {
 	.driver = {
 		.name = "leds-aw2013",
-		.of_match_table = aw2013_match_table,
+		.of_match_table = aw20xx_match_table,
 	},
-	.probe = aw2013_probe,
+	.probe = aw20xx_probe,
 };
 
-module_i2c_driver(aw2013_driver);
+module_i2c_driver(aw20xx_driver);
 
 MODULE_AUTHOR("Nikita Travkin <nikitos.tr@gmail.com>");
 MODULE_DESCRIPTION("AW2013 LED driver");

-- 
2.55.0


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 3/7] leds: aw2013: Add AW2027 support
  2026-10-06  3:46 [PATCH v2 0/7] leds: aw2013: Add AW2027 support Paul Sajna
  2026-10-06  3:46 ` [PATCH v2 1/7] dt-bindings: leds: aw2013: Add awinic,aw2027 compatible Paul Sajna
  2026-10-06  3:46 ` [PATCH v2 2/7] leds: aw2013: Rename internal APIs from aw2013 to aw20xx Paul Sajna
@ 2026-10-06  3:46 ` Paul Sajna
  2026-10-06  3:46 ` [PATCH v2 4/7] leds: aw2013: use dev_err_probe Paul Sajna
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Paul Sajna @ 2026-10-06  3:46 UTC (permalink / raw)
  To: Lee Jones, Pavel Machek, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Nikita Travkin, Alexey Min
  Cc: linux-leds, devicetree, linux-kernel, phone-devel,
	~postmarketos/upstreaming, Paul Sajna

The AW2027 is basically the same as the AW2013.

It differs in:
- the max current (30mA rather than 15)
- the number of current levels for colour-mixing (16 rather than 4)
- the supply voltage max
- the charge indicator (unsupported by our driver at this time)

The max current register (imax) also moves from LCFG to GCR2, and the
selectable current levels for colour-mixing (LCFG_CUR) take their place.

The current driver implementation provided here sets the global imax to
it's maximum, and scales each led to the closest value using the local
imax. It's the best result achievable short of adding custom sysfs
entries and mucking up the linux interfaces.

Comparison of all AW20XX chips https://www.awinic.com/en/productCompareList?id=47&ids=1022,74,96,75,72,71,928,927,73,76,578
AW2027 datasheet: https://doc.awinic.com/doc/202507/77b87097-27bf-48cd-af9b-9b615064c1e1.pdf
Vendor driver: https://www.awinic.com/en/driver/AW2027DNR/454

Signed-off-by: Paul Sajna <sajattack@postmarketos.org>
---
 drivers/leds/leds-aw2013.c | 142 ++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 120 insertions(+), 22 deletions(-)

diff --git a/drivers/leds/leds-aw2013.c b/drivers/leds/leds-aw2013.c
index ae3c8131efb4..340eefdda04f 100644
--- a/drivers/leds/leds-aw2013.c
+++ b/drivers/leds/leds-aw2013.c
@@ -1,5 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0+
-// Driver for Awinic AW2013 3-channel LED driver
+// Driver for Awinic AW2013/AW2027 3-channel LED drivers
 
 #include <linux/i2c.h>
 #include <linux/leds.h>
@@ -19,16 +19,19 @@
 #define AW20XX_GCR 0x01
 #define AW20XX_GCR_ENABLE BIT(0)
 
+#define AW20XX_GCR2 0x04
+#define AW20XX_IMAX_MASK (BIT(0) | BIT(1)) // Should be 0-3
+
 /* LED channel enable register */
 #define AW20XX_LCTR 0x30
 #define AW20XX_LCTR_LE(x) BIT((x))
 
 /* LED channel control registers */
 #define AW20XX_LCFG(x) (0x31 + (x))
-#define AW20XX_LCFG_IMAX_MASK (BIT(0) | BIT(1)) // Should be 0-3
 #define AW20XX_LCFG_MD BIT(4)
 #define AW20XX_LCFG_FI BIT(5)
 #define AW20XX_LCFG_FO BIT(6)
+#define AW20XX_LCFG_CUR_MASK GENMASK(3, 0)
 
 /* LED channel PWM registers */
 #define AW20XX_REG_PWM(x) (0x34 + (x))
@@ -51,6 +54,14 @@
 #define AW2013_RSTR_CHIP_ID 0x33
 #define AW2013_REG_MAX 0x77
 
+#define AW2027_RSTR_CHIP_ID 0x09
+#define AW2027_REG_MAX 0x7F /* copied from vendor driver, but only up to 0x3F is documented */
+
+#define AW2027_IMAX_15MA (0)
+#define AW2027_IMAX_30MA (1)
+#define AW2027_IMAX_5MA  (2)
+#define AW2027_IMAX_10MA (3)
+
 struct aw20xx;
 
 struct aw20xx_led {
@@ -60,16 +71,70 @@ struct aw20xx_led {
 	unsigned int imax;
 };
 
+struct aw20xx_chipdef {
+	u8 chip_id;
+	const struct regmap_config *regmap_cfg;
+	u32 default_imax;
+	bool gcr2_imax;
+	unsigned int current_levels;
+	unsigned int current_max;
+};
+
 struct aw20xx {
 	struct mutex mutex; /* held when writing to registers */
 	struct regulator_bulk_data regulators[2];
+	struct regmap *regmap;
 	struct i2c_client *client;
 	struct aw20xx_led leds[AW20XX_MAX_LEDS];
-	struct regmap *regmap;
+	const struct aw20xx_chipdef *cdef;
 	int num_leds;
 	bool enabled;
 };
 
+static const struct regmap_config aw2013_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = AW2013_REG_MAX,
+};
+
+static const struct regmap_config aw2027_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = AW2027_REG_MAX,
+};
+
+static const struct aw20xx_chipdef aw2013_chipdef = {
+	.chip_id = AW2013_RSTR_CHIP_ID,
+	.regmap_cfg = &aw2013_regmap_config,
+	.default_imax = 1, // 5mA
+	.gcr2_imax = false,
+	.current_levels = 4,
+	.current_max = 15000,
+};
+
+static const struct aw20xx_chipdef aw2027_chipdef = {
+	.chip_id = AW2027_RSTR_CHIP_ID,
+	.regmap_cfg = &aw2027_regmap_config,
+	.default_imax = 3, // 6mA
+	.gcr2_imax = true,
+	.current_levels = 16,
+	.current_max = 30000,
+};
+
+/**
+ * aw20xx_microamp_to_imax() - Finds the closest current step to the given microamp
+ * @microamp: Desired current in microamps
+ * @cdef: Chip definition
+ *
+ * Return: The closest current-step to the given microamp
+ */
+static inline u32 aw20xx_microamp_to_imax(u32 microamp, const struct aw20xx_chipdef *cdef)
+{
+	return min_t(u32, (microamp * (cdef->current_levels - 1))
+			  / cdef->current_max,
+		     cdef->current_levels - 1);
+}
+
 static int aw20xx_chip_init(struct aw20xx *chip)
 {
 	int i, ret;
@@ -81,17 +146,50 @@ static int aw20xx_chip_init(struct aw20xx *chip)
 		return ret;
 	}
 
-	for (i = 0; i < chip->num_leds; i++) {
+	if (chip->cdef->gcr2_imax) {
+		/*
+		 * AW2027 supports 4-step global imax, and also a 16-step control for limiting
+		 * individual current per LED. This doesn't map to the single value the
+		 * devicetree provides super well, so set global imax to maximum, and
+		 * local imax to whatever gets us closest to the value in the devicetree.
+		 */
 		ret = regmap_update_bits(chip->regmap,
-					 AW20XX_LCFG(chip->leds[i].num),
-					 AW20XX_LCFG_IMAX_MASK,
-					 chip->leds[i].imax);
+				AW20XX_GCR2,
+				AW20XX_IMAX_MASK,
+				AW2027_IMAX_30MA);
 		if (ret) {
 			dev_err(&chip->client->dev,
-				"Failed to set maximum current for led %d: %d\n",
-				chip->leds[i].num, ret);
+				"Failed to set maximum global current: %d\n",
+				ret);
 			return ret;
 		}
+
+		for (i = 0; i < chip->num_leds; i++) {
+			ret = regmap_update_bits(chip->regmap,
+						 AW20XX_LCFG(chip->leds[i].num),
+						 AW20XX_LCFG_CUR_MASK,
+						 chip->leds[i].imax);
+			if (ret) {
+				dev_err(&chip->client->dev,
+					"Failed to set maximum current for led %d: %d\n",
+					chip->leds[i].num, ret);
+				return ret;
+			}
+		}
+	} else {
+		/* AW2013 only supports 4-step individual current per LED */
+		for (i = 0; i < chip->num_leds; i++) {
+			ret = regmap_update_bits(chip->regmap,
+						 AW20XX_LCFG(chip->leds[i].num),
+						 AW20XX_IMAX_MASK,
+						 chip->leds[i].imax);
+			if (ret) {
+				dev_err(&chip->client->dev,
+					"Failed to set maximum current for led %d: %d\n",
+					chip->leds[i].num, ret);
+				return ret;
+			}
+		}
 	}
 
 	return ret;
@@ -292,9 +390,9 @@ static int aw20xx_probe_dt(struct aw20xx *chip)
 		init_data.fwnode = of_fwnode_handle(child);
 
 		if (!of_property_read_u32(child, "led-max-microamp", &imax)) {
-			led->imax = min_t(u32, imax / 5000, 3);
+			led->imax = aw20xx_microamp_to_imax(imax, chip->cdef);
 		} else {
-			led->imax = 1; // 5mA
+			led->imax = chip->cdef->default_imax;
 			dev_info(&chip->client->dev,
 				 "DT property led-max-microamp is missing\n");
 		}
@@ -323,18 +421,17 @@ static void aw20xx_chip_disable_action(void *data)
 	aw20xx_chip_disable(data);
 }
 
-static const struct regmap_config aw20xx_regmap_config = {
-	.reg_bits = 8,
-	.val_bits = 8,
-	.max_register = AW2013_REG_MAX,
-};
-
 static int aw20xx_probe(struct i2c_client *client)
 {
 	struct aw20xx *chip;
+	const struct aw20xx_chipdef *cdef;
 	int ret;
 	unsigned int chipid;
 
+	cdef = device_get_match_data(&client->dev);
+	if (!cdef)
+		return -ENODEV;
+
 	chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
 	if (!chip)
 		return -ENOMEM;
@@ -346,9 +443,10 @@ static int aw20xx_probe(struct i2c_client *client)
 	mutex_lock(&chip->mutex);
 
 	chip->client = client;
+	chip->cdef = cdef;
 	i2c_set_clientdata(client, chip);
 
-	chip->regmap = devm_regmap_init_i2c(client, &aw20xx_regmap_config);
+	chip->regmap = devm_regmap_init_i2c(client, chip->cdef->regmap_cfg);
 	if (IS_ERR(chip->regmap)) {
 		ret = PTR_ERR(chip->regmap);
 		dev_err(&client->dev, "Failed to allocate register map: %d\n",
@@ -382,8 +480,7 @@ static int aw20xx_probe(struct i2c_client *client)
 			ret);
 		goto error_reg;
 	}
-
-	if (chipid != AW2013_RSTR_CHIP_ID) {
+	if (chipid != chip->cdef->chip_id) {
 		dev_err(&client->dev, "Chip reported wrong ID: %x\n",
 			chipid);
 		ret = -ENODEV;
@@ -420,7 +517,8 @@ static int aw20xx_probe(struct i2c_client *client)
 }
 
 static const struct of_device_id aw20xx_match_table[] = {
-	{ .compatible = "awinic,aw2013", },
+	{ .compatible = "awinic,aw2013", .data = &aw2013_chipdef },
+	{ .compatible = "awinic,aw2027", .data = &aw2027_chipdef },
 	{ /* sentinel */ },
 };
 
@@ -437,5 +535,5 @@ static struct i2c_driver aw20xx_driver = {
 module_i2c_driver(aw20xx_driver);
 
 MODULE_AUTHOR("Nikita Travkin <nikitos.tr@gmail.com>");
-MODULE_DESCRIPTION("AW2013 LED driver");
+MODULE_DESCRIPTION("AW2013/AW2027 LED driver");
 MODULE_LICENSE("GPL v2");

-- 
2.55.0


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 4/7] leds: aw2013: use dev_err_probe
  2026-10-06  3:46 [PATCH v2 0/7] leds: aw2013: Add AW2027 support Paul Sajna
                   ` (2 preceding siblings ...)
  2026-10-06  3:46 ` [PATCH v2 3/7] leds: aw2013: Add AW2027 support Paul Sajna
@ 2026-10-06  3:46 ` Paul Sajna
  2026-10-06 19:52   ` Griffin Kroah-Hartman
  2026-10-06  3:46 ` [PATCH v2 5/7] leds: aw2013: Move assignment of chip->num_leds Paul Sajna
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 11+ messages in thread
From: Paul Sajna @ 2026-10-06  3:46 UTC (permalink / raw)
  To: Lee Jones, Pavel Machek, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Nikita Travkin, Alexey Min
  Cc: linux-leds, devicetree, linux-kernel, phone-devel,
	~postmarketos/upstreaming, Paul Sajna

Failure to use dev_err_probe() for regulator requests violates
LED subsystem guidelines.

The original driver didn't use it, but it's worth cleaning up
while I'm here.

Signed-off-by: Paul Sajna <sajattack@postmarketos.org>
---
 drivers/leds/leds-aw2013.c | 28 +++++++++++++---------------
 1 file changed, 13 insertions(+), 15 deletions(-)

diff --git a/drivers/leds/leds-aw2013.c b/drivers/leds/leds-aw2013.c
index 340eefdda04f..705de95c6eac 100644
--- a/drivers/leds/leds-aw2013.c
+++ b/drivers/leds/leds-aw2013.c
@@ -448,9 +448,8 @@ static int aw20xx_probe(struct i2c_client *client)
 
 	chip->regmap = devm_regmap_init_i2c(client, chip->cdef->regmap_cfg);
 	if (IS_ERR(chip->regmap)) {
-		ret = PTR_ERR(chip->regmap);
-		dev_err(&client->dev, "Failed to allocate register map: %d\n",
-			ret);
+		ret = dev_err_probe(&client->dev, PTR_ERR(chip->regmap),
+				    "Failed to allocate register map\n");
 		goto error;
 	}
 
@@ -460,30 +459,30 @@ static int aw20xx_probe(struct i2c_client *client)
 				      ARRAY_SIZE(chip->regulators),
 				      chip->regulators);
 	if (ret < 0) {
-		if (ret != -EPROBE_DEFER)
-			dev_err(&client->dev,
-				"Failed to request regulators: %d\n", ret);
+		ret = dev_err_probe(&client->dev, ret,
+				     "Failed to request regulators\n");
 		goto error;
 	}
 
 	ret = regulator_bulk_enable(ARRAY_SIZE(chip->regulators),
 				    chip->regulators);
 	if (ret) {
-		dev_err(&client->dev,
-			"Failed to enable regulators: %d\n", ret);
+		ret = dev_err_probe(&client->dev, ret,
+				     "Failed to enable regulators\n");
 		goto error;
 	}
 
 	ret = regmap_read(chip->regmap, AW20XX_RSTR, &chipid);
 	if (ret) {
-		dev_err(&client->dev, "Failed to read chip ID: %d\n",
-			ret);
+		ret = dev_err_probe(&client->dev, ret,
+				     "Failed to read chip ID\n");
 		goto error_reg;
 	}
 	if (chipid != chip->cdef->chip_id) {
-		dev_err(&client->dev, "Chip reported wrong ID: %x\n",
-			chipid);
 		ret = -ENODEV;
+		ret = dev_err_probe(&client->dev, ret,
+				     "Chip reported wrong ID: %x\n",
+				     chipid);
 		goto error_reg;
 	}
 
@@ -498,13 +497,12 @@ static int aw20xx_probe(struct i2c_client *client)
 	ret = regulator_bulk_disable(ARRAY_SIZE(chip->regulators),
 				     chip->regulators);
 	if (ret) {
-		dev_err(&client->dev,
-			"Failed to disable regulators: %d\n", ret);
+		ret = dev_err_probe(&client->dev, ret,
+				     "Failed to disable regulators\n");
 		goto error;
 	}
 
 	mutex_unlock(&chip->mutex);
-
 	return 0;
 
 error_reg:

-- 
2.55.0


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 5/7] leds: aw2013: Move assignment of chip->num_leds
  2026-10-06  3:46 [PATCH v2 0/7] leds: aw2013: Add AW2027 support Paul Sajna
                   ` (3 preceding siblings ...)
  2026-10-06  3:46 ` [PATCH v2 4/7] leds: aw2013: use dev_err_probe Paul Sajna
@ 2026-10-06  3:46 ` Paul Sajna
  2026-10-06  3:46 ` [PATCH v2 6/7] leds: aw2013: Prevent writes to unpowered chip Paul Sajna
  2026-10-06  3:46 ` [PATCH v2 7/7] leds: aw2013: move reset from probe_dt to chip_init Paul Sajna
  6 siblings, 0 replies; 11+ messages in thread
From: Paul Sajna @ 2026-10-06  3:46 UTC (permalink / raw)
  To: Lee Jones, Pavel Machek, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Nikita Travkin, Alexey Min
  Cc: linux-leds, devicetree, linux-kernel, phone-devel,
	~postmarketos/upstreaming, Paul Sajna

devm_led_classdev_register_ext() executes default triggers
synchronously, which call aw20xx_brightness_set().
aw20xx_chip_in_use() silently returns false, skipping chip enablement and
causing unbalanced regulator disables while probe is still running.

Increment chip->num_leds inside the loop, so that each call gets the
correct value for it's default trigger.

Signed-off-by: Paul Sajna <sajattack@postmarketos.org>
---
 drivers/leds/leds-aw2013.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/leds/leds-aw2013.c b/drivers/leds/leds-aw2013.c
index 705de95c6eac..5d242e2bab60 100644
--- a/drivers/leds/leds-aw2013.c
+++ b/drivers/leds/leds-aw2013.c
@@ -399,7 +399,7 @@ static int aw20xx_probe_dt(struct aw20xx *chip)
 
 		led->cdev.brightness_set_blocking = aw20xx_brightness_set;
 		led->cdev.blink_set = aw20xx_blink_set;
-
+		chip->num_leds = i + 1;
 		ret = devm_led_classdev_register_ext(&chip->client->dev,
 						     &led->cdev, &init_data);
 		if (ret < 0)
@@ -411,8 +411,6 @@ static int aw20xx_probe_dt(struct aw20xx *chip)
 	if (!count)
 		return -EINVAL;
 
-	chip->num_leds = i;
-
 	return 0;
 }
 

-- 
2.55.0


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 6/7] leds: aw2013: Prevent writes to unpowered chip
  2026-10-06  3:46 [PATCH v2 0/7] leds: aw2013: Add AW2027 support Paul Sajna
                   ` (4 preceding siblings ...)
  2026-10-06  3:46 ` [PATCH v2 5/7] leds: aw2013: Move assignment of chip->num_leds Paul Sajna
@ 2026-10-06  3:46 ` Paul Sajna
  2026-10-06  3:46 ` [PATCH v2 7/7] leds: aw2013: move reset from probe_dt to chip_init Paul Sajna
  6 siblings, 0 replies; 11+ messages in thread
From: Paul Sajna @ 2026-10-06  3:46 UTC (permalink / raw)
  To: Lee Jones, Pavel Machek, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Nikita Travkin, Alexey Min
  Cc: linux-leds, devicetree, linux-kernel, phone-devel,
	~postmarketos/upstreaming, Paul Sajna

Replace chip_in_use check with chip->enabled boolean in
aw20xx_brightness_set

During teardown, probe, or unregistration, the LED core initializes
cdev->brightness to 0 and queues a work to set the brightness to 0.
This canalso be triggered by unprivileged user space via sysfs by
writing 0 to the brightness file when already 0.

When this occurs, aw2013_chip_in_use() evaluates to false and skips
enabling the regulators:

Because aw2013_chip_enable() is skipped, the driver then unconditionally
calls regmap_write() and regmap_update_bits(), which perform I2C
transactions to the unpowered chip.

Signed-off-by: Paul Sajna <sajattack@postmarketos.org>
---
 drivers/leds/leds-aw2013.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/leds/leds-aw2013.c b/drivers/leds/leds-aw2013.c
index 5d242e2bab60..2a133657d9b6 100644
--- a/drivers/leds/leds-aw2013.c
+++ b/drivers/leds/leds-aw2013.c
@@ -257,7 +257,7 @@ static int aw20xx_brightness_set(struct led_classdev *cdev,
 
 	mutex_lock(&led->chip->mutex);
 
-	if (aw20xx_chip_in_use(led->chip)) {
+	if (!led->chip->enabled) {
 		ret = aw20xx_chip_enable(led->chip);
 		if (ret)
 			goto error;

-- 
2.55.0


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 7/7] leds: aw2013: move reset from probe_dt to chip_init
  2026-10-06  3:46 [PATCH v2 0/7] leds: aw2013: Add AW2027 support Paul Sajna
                   ` (5 preceding siblings ...)
  2026-10-06  3:46 ` [PATCH v2 6/7] leds: aw2013: Prevent writes to unpowered chip Paul Sajna
@ 2026-10-06  3:46 ` Paul Sajna
  6 siblings, 0 replies; 11+ messages in thread
From: Paul Sajna @ 2026-10-06  3:46 UTC (permalink / raw)
  To: Lee Jones, Pavel Machek, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Nikita Travkin, Alexey Min
  Cc: linux-leds, devicetree, linux-kernel, phone-devel,
	~postmarketos/upstreaming, Paul Sajna

It has no reason to be in probe_dt, and putting it there complicates
the mutex requirements

Signed-off-by: Paul Sajna <sajattack@postmarketos.org>
---
 drivers/leds/leds-aw2013.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/leds/leds-aw2013.c b/drivers/leds/leds-aw2013.c
index 2a133657d9b6..7bc0415375c6 100644
--- a/drivers/leds/leds-aw2013.c
+++ b/drivers/leds/leds-aw2013.c
@@ -139,6 +139,13 @@ static int aw20xx_chip_init(struct aw20xx *chip)
 {
 	int i, ret;
 
+	ret = regmap_write(chip->regmap, AW20XX_RSTR, AW20XX_RSTR_RESET);
+	if (ret) {
+		dev_err(&chip->client->dev, "Failed to reset the chip: %d\n",
+			ret);
+		return ret;
+	}
+
 	ret = regmap_write(chip->regmap, AW20XX_GCR, AW20XX_GCR_ENABLE);
 	if (ret) {
 		dev_err(&chip->client->dev, "Failed to enable the chip: %d\n",
@@ -369,8 +376,6 @@ static int aw20xx_probe_dt(struct aw20xx *chip)
 	if (!count || count > AW20XX_MAX_LEDS)
 		return -EINVAL;
 
-	regmap_write(chip->regmap, AW20XX_RSTR, AW20XX_RSTR_RESET);
-
 	for_each_available_child_of_node_scoped(np, child) {
 		struct led_init_data init_data = {};
 		u32 source;

-- 
2.55.0


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 2/7] leds: aw2013: Rename internal APIs from aw2013 to aw20xx
  2026-10-06  3:46 ` [PATCH v2 2/7] leds: aw2013: Rename internal APIs from aw2013 to aw20xx Paul Sajna
@ 2026-10-06 10:45   ` Griffin Kroah-Hartman
  2026-10-06 18:54     ` Paul Sajna
  0 siblings, 1 reply; 11+ messages in thread
From: Griffin Kroah-Hartman @ 2026-10-06 10:45 UTC (permalink / raw)
  To: Paul Sajna
  Cc: Lee Jones, Pavel Machek, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Nikita Travkin, Alexey Min, linux-leds, devicetree,
	linux-kernel, phone-devel, ~postmarketos/upstreaming

On Mon, 05 Oct 2026 20:46:03 -0700, Paul Sajna <sajattack@postmarketos.org> wrote:
> We don't want to break external compatibility, but it's better
> if the things shared between aw2013 and aw2027 have generic names.
> 

I understand the impulse, but the preferred way to handle this situation
is just to rename the properties unique to your new driver, otherwise
this code wouldn't make sense to be in the aw2013.c file anymore :)

Thanks,
Griffin

-- 
 


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 2/7] leds: aw2013: Rename internal APIs from aw2013 to aw20xx
  2026-10-06 10:45   ` Griffin Kroah-Hartman
@ 2026-10-06 18:54     ` Paul Sajna
  0 siblings, 0 replies; 11+ messages in thread
From: Paul Sajna @ 2026-10-06 18:54 UTC (permalink / raw)
  To: Griffin Kroah-Hartman
  Cc: Lee Jones, Pavel Machek, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Nikita Travkin, Alexey Min, linux-leds, devicetree,
	linux-kernel, phone-devel, ~postmarketos/upstreaming

October 6, 2026 at 3:45 AM, "Griffin Kroah-Hartman" <griffin@kroah.com mailto:griffin@kroah.com?to=%22Griffin%20Kroah-Hartman%22%20%3Cgriffin%40kroah.com%3E > wrote:

> I understand the impulse, but the preferred way to handle this situation
> is just to rename the properties unique to your new driver, otherwise
> this code wouldn't make sense to be in the aw2013.c file anymore :)
> 
> Thanks,
> Griffin
> 
> --
>

Thanks. This is the sort of feedback I was looking for in the RFC, but never got directly. 

I'll walk back the renames some more, and look at the fresh batch of Sashiko nits before sending v3.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 4/7] leds: aw2013: use dev_err_probe
  2026-10-06  3:46 ` [PATCH v2 4/7] leds: aw2013: use dev_err_probe Paul Sajna
@ 2026-10-06 19:52   ` Griffin Kroah-Hartman
  0 siblings, 0 replies; 11+ messages in thread
From: Griffin Kroah-Hartman @ 2026-10-06 19:52 UTC (permalink / raw)
  To: Paul Sajna
  Cc: Lee Jones, Pavel Machek, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Nikita Travkin, Alexey Min, linux-leds, devicetree,
	linux-kernel, phone-devel, ~postmarketos/upstreaming

On Mon, 05 Oct 2026 20:46:05 -0700, Paul Sajna <sajattack@postmarketos.org> wrote:
> Failure to use dev_err_probe() for regulator requests violates
> LED subsystem guidelines.
> 
> The original driver didn't use it, but it's worth cleaning up
> while I'm here.
> 
> 
> [...]

Reviewed-by: Griffin Kroah-Hartman <griffin@kroah.com>

-- 
 


^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2026-10-06 19:53 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-06  3:46 [PATCH v2 0/7] leds: aw2013: Add AW2027 support Paul Sajna
2026-10-06  3:46 ` [PATCH v2 1/7] dt-bindings: leds: aw2013: Add awinic,aw2027 compatible Paul Sajna
2026-10-06  3:46 ` [PATCH v2 2/7] leds: aw2013: Rename internal APIs from aw2013 to aw20xx Paul Sajna
2026-10-06 10:45   ` Griffin Kroah-Hartman
2026-10-06 18:54     ` Paul Sajna
2026-10-06  3:46 ` [PATCH v2 3/7] leds: aw2013: Add AW2027 support Paul Sajna
2026-10-06  3:46 ` [PATCH v2 4/7] leds: aw2013: use dev_err_probe Paul Sajna
2026-10-06 19:52   ` Griffin Kroah-Hartman
2026-10-06  3:46 ` [PATCH v2 5/7] leds: aw2013: Move assignment of chip->num_leds Paul Sajna
2026-10-06  3:46 ` [PATCH v2 6/7] leds: aw2013: Prevent writes to unpowered chip Paul Sajna
2026-10-06  3:46 ` [PATCH v2 7/7] leds: aw2013: move reset from probe_dt to chip_init Paul Sajna

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®