public inbox for linux-leds@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/5] media: lm3560: convert to use OF bindings
@ 2026-04-19  9:34 Svyatoslav Ryhel
  2026-04-19  9:34 ` [PATCH v2 1/5] dt-bindings: leds: Document TI LM3560 Synchronous Boost Flash Driver Svyatoslav Ryhel
                   ` (4 more replies)
  0 siblings, 5 replies; 12+ messages in thread
From: Svyatoslav Ryhel @ 2026-04-19  9:34 UTC (permalink / raw)
  To: Lee Jones, Pavel Machek, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Sakari Ailus, Mauro Carvalho Chehab,
	Svyatoslav Ryhel
  Cc: linux-leds, devicetree, linux-kernel, linux-media

Add missing HWEN input pin and IN supply. Fix v4l2 subdev registration.
Remove platform data and switch to OF device tree bindings.

---
Changes in v2:
- vendor properties swapped with generic LED properties
- added mutex lock usage optimization
- power supply and enable gpio commits squashed into PM
  configuration since they are both required in making
  proper on/off sequence.
---

Svyatoslav Ryhel (5):
  dt-bindings: leds: Document TI LM3560 Synchronous Boost Flash Driver
  media: i2c: lm3560: Fix v4l2 subdev registration
  media: i2c: lm3560: Optimize mutex lock usage
  media: i2c: lm3560: Convert to use OF bindings
  media: i2c: lm3560: Add support for PM features

 .../devicetree/bindings/leds/ti,lm3560.yaml   | 131 +++++++++
 drivers/media/i2c/lm3560.c                    | 262 ++++++++++++++----
 include/media/i2c/lm3560.h                    |  15 -
 3 files changed, 340 insertions(+), 68 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/leds/ti,lm3560.yaml

-- 
2.51.0


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

* [PATCH v2 1/5] dt-bindings: leds: Document TI LM3560 Synchronous Boost Flash Driver
  2026-04-19  9:34 [PATCH v2 0/5] media: lm3560: convert to use OF bindings Svyatoslav Ryhel
@ 2026-04-19  9:34 ` Svyatoslav Ryhel
  2026-04-20 16:20   ` Conor Dooley
  2026-04-19  9:34 ` [PATCH v2 2/5] media: i2c: lm3560: Fix v4l2 subdev registration Svyatoslav Ryhel
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 12+ messages in thread
From: Svyatoslav Ryhel @ 2026-04-19  9:34 UTC (permalink / raw)
  To: Lee Jones, Pavel Machek, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Sakari Ailus, Mauro Carvalho Chehab,
	Svyatoslav Ryhel
  Cc: linux-leds, devicetree, linux-kernel, linux-media

Document TI LM3560 Synchronous Boost Flash Driver used for camera flash
LEDs.

Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
---
 .../devicetree/bindings/leds/ti,lm3560.yaml   | 131 ++++++++++++++++++
 1 file changed, 131 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/ti,lm3560.yaml

diff --git a/Documentation/devicetree/bindings/leds/ti,lm3560.yaml b/Documentation/devicetree/bindings/leds/ti,lm3560.yaml
new file mode 100644
index 000000000000..c6c553ad23f9
--- /dev/null
+++ b/Documentation/devicetree/bindings/leds/ti,lm3560.yaml
@@ -0,0 +1,131 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/leds/ti,lm3560.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: TI LM3560 Synchronous Boost Flash Driver
+
+maintainers:
+  - Svyatoslav Ryhel <clamor95@gmail.com>
+
+description:
+  The LM3560 is a 2-MHz fixed frequency synchronous boost converter with two
+  1000-mA constant current drivers for high-current white LEDs. The dual high-
+  side current sources allow for grounded cathode LED operation and can be
+  tied together for providing flash currents at up to 2 A through a single LED.
+  An adaptive regulation method ensures the current for each LED remains in
+  regulation and maximizes efficiency.
+
+allOf:
+  - $ref: /schemas/leds/common.yaml
+
+properties:
+  compatible:
+    enum:
+      - ti,lm3559
+      - ti,lm3560
+
+  reg:
+    maxItems: 1
+
+  '#address-cells':
+    const: 1
+
+  '#size-cells':
+    const: 0
+
+  enable-gpios:
+    description: GPIO connected to the HWEN pin.
+    maxItems: 1
+
+  vin-supply:
+    description: Supply connected to the IN line.
+
+  flash-max-timeout-us:
+    minimum: 32000
+    maximum: 1024000
+    default: 32000
+
+  ti,peak-current-microamp:
+    description:
+      The LM3560 features 4 selectable current limits 1.6A, 2.3A, 3A, and 3.6A.
+      When the current limit is reached, the LM3560 stops switching for the
+      remainder of the switching cycle.
+    enum: [16000000, 23000000, 30000000, 36000000]
+    default: 16000000
+
+patternProperties:
+  '^led@[01]$':
+    description: LED control bank nodes.
+    $ref: /schemas/leds/common.yaml#
+    unevaluatedProperties: false
+
+    properties:
+      reg:
+        description: Control bank selection (0 = bank A, 1 = bank B).
+        maximum: 1
+
+      flash-max-microamp:
+        minimum: 62500
+        maximum: 1000000
+
+      led-max-microamp:
+        minimum: 31250
+        maximum: 250000
+
+    required:
+      - reg
+      - flash-max-microamp
+      - led-max-microamp
+
+required:
+  - compatible
+  - reg
+  - '#address-cells'
+  - '#size-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        led-controller@53 {
+            compatible = "ti,lm3560";
+            reg = <0x53>;
+
+            enable-gpios = <&gpio 28 GPIO_ACTIVE_HIGH>;
+            vin-supply = <&vdd_3v3_sys>;
+
+            flash-max-timeout-us = <1024000>;
+            ti,peak-current-microamp = <16000000>;
+
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            led@0 {
+                reg = <0>;
+
+                label = "white::flash";
+                linux,default-trigger = "flash";
+
+                flash-max-microamp = <562500>;
+                led-max-microamp = <156250>;
+            };
+
+            led@1 {
+                reg = <1>;
+
+                label = "yellow::flash";
+                linux,default-trigger = "flash";
+
+                flash-max-microamp = <562500>;
+                led-max-microamp = <156250>;
+            };
+        };
+    };
-- 
2.51.0


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

* [PATCH v2 2/5] media: i2c: lm3560: Fix v4l2 subdev registration
  2026-04-19  9:34 [PATCH v2 0/5] media: lm3560: convert to use OF bindings Svyatoslav Ryhel
  2026-04-19  9:34 ` [PATCH v2 1/5] dt-bindings: leds: Document TI LM3560 Synchronous Boost Flash Driver Svyatoslav Ryhel
@ 2026-04-19  9:34 ` Svyatoslav Ryhel
  2026-04-19  9:34 ` [PATCH v2 3/5] media: i2c: lm3560: Optimize mutex lock usage Svyatoslav Ryhel
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 12+ messages in thread
From: Svyatoslav Ryhel @ 2026-04-19  9:34 UTC (permalink / raw)
  To: Lee Jones, Pavel Machek, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Sakari Ailus, Mauro Carvalho Chehab,
	Svyatoslav Ryhel
  Cc: linux-leds, devicetree, linux-kernel, linux-media

The existing driver does not call media subdev registration, making it
invisible to the media framework. Since the LM3560 supports two
independent LEDs, register each LED as a separate media entity.

Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
---
 drivers/media/i2c/lm3560.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/media/i2c/lm3560.c b/drivers/media/i2c/lm3560.c
index f4cc844f4e3c..085a0ef70e39 100644
--- a/drivers/media/i2c/lm3560.c
+++ b/drivers/media/i2c/lm3560.c
@@ -364,8 +364,15 @@ static int lm3560_subdev_init(struct lm3560_flash *flash,
 		goto err_out;
 	flash->subdev_led[led_no].entity.function = MEDIA_ENT_F_FLASH;
 
-	return rval;
+	rval = v4l2_async_register_subdev(&flash->subdev_led[led_no]);
+	if (rval < 0) {
+		dev_err(flash->dev, "failed to register V4L2 subdev");
+		goto error_out_media;
+	}
 
+	return rval;
+error_out_media:
+	media_entity_cleanup(&flash->subdev_led[led_no].entity);
 err_out:
 	v4l2_ctrl_handler_free(&flash->ctrls_led[led_no]);
 	return rval;
-- 
2.51.0


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

* [PATCH v2 3/5] media: i2c: lm3560: Optimize mutex lock usage
  2026-04-19  9:34 [PATCH v2 0/5] media: lm3560: convert to use OF bindings Svyatoslav Ryhel
  2026-04-19  9:34 ` [PATCH v2 1/5] dt-bindings: leds: Document TI LM3560 Synchronous Boost Flash Driver Svyatoslav Ryhel
  2026-04-19  9:34 ` [PATCH v2 2/5] media: i2c: lm3560: Fix v4l2 subdev registration Svyatoslav Ryhel
@ 2026-04-19  9:34 ` Svyatoslav Ryhel
  2026-04-19  9:34 ` [PATCH v2 4/5] media: i2c: lm3560: Convert to use OF bindings Svyatoslav Ryhel
  2026-04-19  9:34 ` [PATCH v2 5/5] media: i2c: lm3560: Add support for PM features Svyatoslav Ryhel
  4 siblings, 0 replies; 12+ messages in thread
From: Svyatoslav Ryhel @ 2026-04-19  9:34 UTC (permalink / raw)
  To: Lee Jones, Pavel Machek, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Sakari Ailus, Mauro Carvalho Chehab,
	Svyatoslav Ryhel
  Cc: linux-leds, devicetree, linux-kernel, linux-media

Pass the device's own mutex lock to the control handler so that the media
framework can handle control access instead of managing it manually. The
lock must be common to both sub-devices, so the individual sub-device
locks will not work here.

Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
---
 drivers/media/i2c/lm3560.c | 18 +++++-------------
 1 file changed, 5 insertions(+), 13 deletions(-)

diff --git a/drivers/media/i2c/lm3560.c b/drivers/media/i2c/lm3560.c
index 085a0ef70e39..5cd22c2fbb64 100644
--- a/drivers/media/i2c/lm3560.c
+++ b/drivers/media/i2c/lm3560.c
@@ -162,14 +162,12 @@ static int lm3560_get_ctrl(struct v4l2_ctrl *ctrl, enum lm3560_led_id led_no)
 	struct lm3560_flash *flash = to_lm3560_flash(ctrl, led_no);
 	int rval = -EINVAL;
 
-	mutex_lock(&flash->lock);
-
 	if (ctrl->id == V4L2_CID_FLASH_FAULT) {
 		s32 fault = 0;
 		unsigned int reg_val;
 		rval = regmap_read(flash->regmap, REG_FLAG, &reg_val);
 		if (rval < 0)
-			goto out;
+			return rval;
 		if (reg_val & FAULT_SHORT_CIRCUIT)
 			fault |= V4L2_FLASH_FAULT_SHORT_CIRCUIT;
 		if (reg_val & FAULT_OVERTEMP)
@@ -179,8 +177,6 @@ static int lm3560_get_ctrl(struct v4l2_ctrl *ctrl, enum lm3560_led_id led_no)
 		ctrl->cur.val = fault;
 	}
 
-out:
-	mutex_unlock(&flash->lock);
 	return rval;
 }
 
@@ -190,8 +186,6 @@ static int lm3560_set_ctrl(struct v4l2_ctrl *ctrl, enum lm3560_led_id led_no)
 	u8 tout_bits;
 	int rval = -EINVAL;
 
-	mutex_lock(&flash->lock);
-
 	switch (ctrl->id) {
 	case V4L2_CID_FLASH_LED_MODE:
 		flash->led_mode = ctrl->val;
@@ -202,14 +196,12 @@ static int lm3560_set_ctrl(struct v4l2_ctrl *ctrl, enum lm3560_led_id led_no)
 	case V4L2_CID_FLASH_STROBE_SOURCE:
 		rval = regmap_update_bits(flash->regmap,
 					  REG_CONFIG1, 0x04, (ctrl->val) << 2);
-		if (rval < 0)
-			goto err_out;
 		break;
 
 	case V4L2_CID_FLASH_STROBE:
 		if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH) {
 			rval = -EBUSY;
-			goto err_out;
+			break;
 		}
 		flash->led_mode = V4L2_FLASH_LED_MODE_FLASH;
 		rval = lm3560_mode_ctrl(flash);
@@ -218,7 +210,7 @@ static int lm3560_set_ctrl(struct v4l2_ctrl *ctrl, enum lm3560_led_id led_no)
 	case V4L2_CID_FLASH_STROBE_STOP:
 		if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH) {
 			rval = -EBUSY;
-			goto err_out;
+			break;
 		}
 		flash->led_mode = V4L2_FLASH_LED_MODE_NONE;
 		rval = lm3560_mode_ctrl(flash);
@@ -239,8 +231,6 @@ static int lm3560_set_ctrl(struct v4l2_ctrl *ctrl, enum lm3560_led_id led_no)
 		break;
 	}
 
-err_out:
-	mutex_unlock(&flash->lock);
 	return rval;
 }
 
@@ -332,6 +322,8 @@ static int lm3560_init_controls(struct lm3560_flash *flash,
 		return hdl->error;
 
 	flash->subdev_led[led_no].ctrl_handler = hdl;
+	flash->subdev_led[led_no].ctrl_handler->lock = &flash->lock;
+
 	return 0;
 }
 
-- 
2.51.0


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

* [PATCH v2 4/5] media: i2c: lm3560: Convert to use OF bindings
  2026-04-19  9:34 [PATCH v2 0/5] media: lm3560: convert to use OF bindings Svyatoslav Ryhel
                   ` (2 preceding siblings ...)
  2026-04-19  9:34 ` [PATCH v2 3/5] media: i2c: lm3560: Optimize mutex lock usage Svyatoslav Ryhel
@ 2026-04-19  9:34 ` Svyatoslav Ryhel
  2026-04-19  9:34 ` [PATCH v2 5/5] media: i2c: lm3560: Add support for PM features Svyatoslav Ryhel
  4 siblings, 0 replies; 12+ messages in thread
From: Svyatoslav Ryhel @ 2026-04-19  9:34 UTC (permalink / raw)
  To: Lee Jones, Pavel Machek, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Sakari Ailus, Mauro Carvalho Chehab,
	Svyatoslav Ryhel
  Cc: linux-leds, devicetree, linux-kernel, linux-media

Since there are no users of this driver via platform data, remove platform
data and switch to using device tree bindings.

Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
---
 drivers/media/i2c/lm3560.c | 112 ++++++++++++++++++++++++++-----------
 include/media/i2c/lm3560.h |  15 -----
 2 files changed, 79 insertions(+), 48 deletions(-)

diff --git a/drivers/media/i2c/lm3560.c b/drivers/media/i2c/lm3560.c
index 5cd22c2fbb64..022a6a76befb 100644
--- a/drivers/media/i2c/lm3560.c
+++ b/drivers/media/i2c/lm3560.c
@@ -13,7 +13,9 @@
 #include <linux/module.h>
 #include <linux/i2c.h>
 #include <linux/slab.h>
+#include <linux/mod_devicetable.h>
 #include <linux/mutex.h>
+#include <linux/property.h>
 #include <linux/regmap.h>
 #include <linux/videodev2.h>
 #include <media/i2c/lm3560.h>
@@ -43,22 +45,30 @@ enum led_enable {
  * struct lm3560_flash
  *
  * @dev: pointer to &struct device
- * @pdata: platform data
  * @regmap: reg. map for i2c
  * @lock: muxtex for serial access.
  * @led_mode: V4L2 LED mode
  * @ctrls_led: V4L2 controls
  * @subdev_led: V4L2 subdev
+ * @peak: peak current
+ * @max_flash_timeout: flash timeout
+ * @max_flash_brt: flash mode led brightness
+ * @max_torch_brt: torch mode led brightness
  */
 struct lm3560_flash {
 	struct device *dev;
-	struct lm3560_platform_data *pdata;
 	struct regmap *regmap;
 	struct mutex lock;
 
 	enum v4l2_flash_led_mode led_mode;
 	struct v4l2_ctrl_handler ctrls_led[LM3560_LED_MAX];
 	struct v4l2_subdev subdev_led[LM3560_LED_MAX];
+
+	enum lm3560_peak_current peak;
+	u32 max_flash_timeout;
+
+	u32 max_flash_brt[LM3560_LED_MAX];
+	u32 max_torch_brt[LM3560_LED_MAX];
 };
 
 #define to_lm3560_flash(_ctrl, _no)	\
@@ -269,8 +279,8 @@ static int lm3560_init_controls(struct lm3560_flash *flash,
 				enum lm3560_led_id led_no)
 {
 	struct v4l2_ctrl *fault;
-	u32 max_flash_brt = flash->pdata->max_flash_brt[led_no];
-	u32 max_torch_brt = flash->pdata->max_torch_brt[led_no];
+	u32 max_flash_brt = flash->max_flash_brt[led_no];
+	u32 max_torch_brt = flash->max_torch_brt[led_no];
 	struct v4l2_ctrl_handler *hdl = &flash->ctrls_led[led_no];
 	const struct v4l2_ctrl_ops *ops = &lm3560_led_ctrl_ops[led_no];
 
@@ -295,9 +305,9 @@ static int lm3560_init_controls(struct lm3560_flash *flash,
 	/* flash strobe timeout */
 	v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_TIMEOUT,
 			  LM3560_FLASH_TOUT_MIN,
-			  flash->pdata->max_flash_timeout,
+			  flash->max_flash_timeout,
 			  LM3560_FLASH_TOUT_STEP,
-			  flash->pdata->max_flash_timeout);
+			  flash->max_flash_timeout);
 
 	/* flash brt */
 	v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_INTENSITY,
@@ -339,15 +349,18 @@ static const struct regmap_config lm3560_regmap = {
 };
 
 static int lm3560_subdev_init(struct lm3560_flash *flash,
-			      enum lm3560_led_id led_no, char *led_name)
+			      enum lm3560_led_id led_no,
+			      struct fwnode_handle *fwnode)
 {
 	struct i2c_client *client = to_i2c_client(flash->dev);
 	int rval;
 
 	v4l2_i2c_subdev_init(&flash->subdev_led[led_no], client, &lm3560_ops);
 	flash->subdev_led[led_no].flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-	strscpy(flash->subdev_led[led_no].name, led_name,
-		sizeof(flash->subdev_led[led_no].name));
+	snprintf(flash->subdev_led[led_no].name,
+		 sizeof(flash->subdev_led[led_no].name),
+		 "lm3560-led%d", led_no);
+	flash->subdev_led[led_no].fwnode = fwnode;
 	rval = lm3560_init_controls(flash, led_no);
 	if (rval)
 		goto err_out;
@@ -377,7 +390,7 @@ static int lm3560_init_device(struct lm3560_flash *flash)
 
 	/* set peak current */
 	rval = regmap_update_bits(flash->regmap,
-				  REG_FLASH_TOUT, 0x60, flash->pdata->peak);
+				  REG_FLASH_TOUT, 0x60, flash->peak);
 	if (rval < 0)
 		return rval;
 	/* output disable */
@@ -393,8 +406,9 @@ static int lm3560_init_device(struct lm3560_flash *flash)
 static int lm3560_probe(struct i2c_client *client)
 {
 	struct lm3560_flash *flash;
-	struct lm3560_platform_data *pdata = dev_get_platdata(&client->dev);
-	int rval;
+	struct fwnode_handle *node;
+	u32 peak_ua;
+	int rval, reg;
 
 	flash = devm_kzalloc(&client->dev, sizeof(*flash), GFP_KERNEL);
 	if (flash == NULL)
@@ -406,36 +420,60 @@ static int lm3560_probe(struct i2c_client *client)
 		return rval;
 	}
 
-	/* if there is no platform data, use chip default value */
-	if (pdata == NULL) {
-		pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
-		if (pdata == NULL)
-			return -ENODEV;
-		pdata->peak = LM3560_PEAK_3600mA;
-		pdata->max_flash_timeout = LM3560_FLASH_TOUT_MAX;
-		/* led 1 */
-		pdata->max_flash_brt[LM3560_LED0] = LM3560_FLASH_BRT_MAX;
-		pdata->max_torch_brt[LM3560_LED0] = LM3560_TORCH_BRT_MAX;
-		/* led 2 */
-		pdata->max_flash_brt[LM3560_LED1] = LM3560_FLASH_BRT_MAX;
-		pdata->max_torch_brt[LM3560_LED1] = LM3560_TORCH_BRT_MAX;
-	}
-	flash->pdata = pdata;
 	flash->dev = &client->dev;
 	mutex_init(&flash->lock);
 
-	rval = lm3560_subdev_init(flash, LM3560_LED0, "lm3560-led0");
-	if (rval < 0)
-		return rval;
+	flash->peak = LM3560_PEAK_1600mA;
+	rval = device_property_read_u32(flash->dev,
+					"ti,peak-current-microamp", &peak_ua);
+	if (!rval) {
+		switch (peak_ua) {
+		case 16000000:
+			flash->peak = LM3560_PEAK_1600mA;
+			break;
+		case 23000000:
+			flash->peak = LM3560_PEAK_2300mA;
+			break;
+		case 30000000:
+			flash->peak = LM3560_PEAK_3000mA;
+			break;
+		case 36000000:
+			flash->peak = LM3560_PEAK_3600mA;
+			break;
+		default:
+			return -EINVAL;
+		}
+	}
 
-	rval = lm3560_subdev_init(flash, LM3560_LED1, "lm3560-led1");
-	if (rval < 0)
-		return rval;
+	flash->max_flash_timeout = LM3560_FLASH_TOUT_MIN * 1000;
+	device_property_read_u32(flash->dev, "flash-max-timeout-us",
+				 &flash->max_flash_timeout);
+	flash->max_flash_timeout /= 1000;
 
 	rval = lm3560_init_device(flash);
 	if (rval < 0)
 		return rval;
 
+	device_for_each_child_node(flash->dev, node) {
+		fwnode_property_read_u32(node, "reg", &reg);
+
+		if (reg == LM3560_LED0 || reg == LM3560_LED1) {
+			flash->max_flash_brt[reg] = LM3560_FLASH_BRT_MIN;
+			fwnode_property_read_u32(node, "flash-max-microamp",
+						 &flash->max_flash_brt[reg]);
+
+			flash->max_torch_brt[reg] = LM3560_TORCH_BRT_MIN;
+			fwnode_property_read_u32(node, "led-max-microamp",
+						 &flash->max_torch_brt[reg]);
+
+			rval = lm3560_subdev_init(flash, reg, node);
+			if (rval < 0)
+				return dev_err_probe(flash->dev, rval,
+						    "failed to register led%d\n",
+						    reg);
+		}
+	}
+
 	i2c_set_clientdata(client, flash);
 
 	return 0;
@@ -453,6 +491,13 @@ static void lm3560_remove(struct i2c_client *client)
 	}
 }
 
+static const struct of_device_id lm3560_of_match[] = {
+	{ .compatible = "ti,lm3559" },
+	{ .compatible = "ti,lm3560" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, lm3560_of_match);
+
 static const struct i2c_device_id lm3560_id_table[] = {
 	{ LM3559_NAME },
 	{ LM3560_NAME },
@@ -465,6 +510,7 @@ static struct i2c_driver lm3560_i2c_driver = {
 	.driver = {
 		   .name = LM3560_NAME,
 		   .pm = NULL,
+		   .of_match_table = lm3560_of_match,
 		   },
 	.probe = lm3560_probe,
 	.remove = lm3560_remove,
diff --git a/include/media/i2c/lm3560.h b/include/media/i2c/lm3560.h
index 770d8c72c94a..b56c1ff8fd49 100644
--- a/include/media/i2c/lm3560.h
+++ b/include/media/i2c/lm3560.h
@@ -66,19 +66,4 @@ enum lm3560_peak_current {
 	LM3560_PEAK_3600mA = 0x60
 };
 
-/* struct lm3560_platform_data
- *
- * @peak :  peak current
- * @max_flash_timeout: flash timeout
- * @max_flash_brt: flash mode led brightness
- * @max_torch_brt: torch mode led brightness
- */
-struct lm3560_platform_data {
-	enum lm3560_peak_current peak;
-
-	u32 max_flash_timeout;
-	u32 max_flash_brt[LM3560_LED_MAX];
-	u32 max_torch_brt[LM3560_LED_MAX];
-};
-
 #endif /* __LM3560_H__ */
-- 
2.51.0


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

* [PATCH v2 5/5] media: i2c: lm3560: Add support for PM features
  2026-04-19  9:34 [PATCH v2 0/5] media: lm3560: convert to use OF bindings Svyatoslav Ryhel
                   ` (3 preceding siblings ...)
  2026-04-19  9:34 ` [PATCH v2 4/5] media: i2c: lm3560: Convert to use OF bindings Svyatoslav Ryhel
@ 2026-04-19  9:34 ` Svyatoslav Ryhel
  2026-04-21 16:44   ` Sakari Ailus
  4 siblings, 1 reply; 12+ messages in thread
From: Svyatoslav Ryhel @ 2026-04-19  9:34 UTC (permalink / raw)
  To: Lee Jones, Pavel Machek, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Sakari Ailus, Mauro Carvalho Chehab,
	Svyatoslav Ryhel
  Cc: linux-leds, devicetree, linux-kernel, linux-media

Add support for power management features to better control the LM3560
within the media framework. To achieve the desired PM support, the HWEN
GPIO and VIN power supply were added and configured into power on/off
sequences. Media device deregistration helpers were grouped into a
separate function to simplify the probe/remove process. Added PM
operations along with the PM configuration setup.

Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
---
 drivers/media/i2c/lm3560.c | 135 +++++++++++++++++++++++++++++++++----
 1 file changed, 123 insertions(+), 12 deletions(-)

diff --git a/drivers/media/i2c/lm3560.c b/drivers/media/i2c/lm3560.c
index 022a6a76befb..8f5156a80a99 100644
--- a/drivers/media/i2c/lm3560.c
+++ b/drivers/media/i2c/lm3560.c
@@ -11,12 +11,15 @@
 
 #include <linux/delay.h>
 #include <linux/module.h>
+#include <linux/gpio/consumer.h>
 #include <linux/i2c.h>
 #include <linux/slab.h>
 #include <linux/mod_devicetable.h>
 #include <linux/mutex.h>
+#include <linux/pm_runtime.h>
 #include <linux/property.h>
 #include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
 #include <linux/videodev2.h>
 #include <media/i2c/lm3560.h>
 #include <media/v4l2-ctrls.h>
@@ -47,6 +50,8 @@ enum led_enable {
  * @dev: pointer to &struct device
  * @regmap: reg. map for i2c
  * @lock: muxtex for serial access.
+ * @hwen_gpio: line connected to HWEN pin
+ * @vin_supply: line connected to IN supply (2.5V - 5.5V)
  * @led_mode: V4L2 LED mode
  * @ctrls_led: V4L2 controls
  * @subdev_led: V4L2 subdev
@@ -60,6 +65,9 @@ struct lm3560_flash {
 	struct regmap *regmap;
 	struct mutex lock;
 
+	struct gpio_desc *hwen_gpio;
+	struct regulator *vin_supply;
+
 	enum v4l2_flash_led_mode led_mode;
 	struct v4l2_ctrl_handler ctrls_led[LM3560_LED_MAX];
 	struct v4l2_subdev subdev_led[LM3560_LED_MAX];
@@ -172,12 +180,17 @@ static int lm3560_get_ctrl(struct v4l2_ctrl *ctrl, enum lm3560_led_id led_no)
 	struct lm3560_flash *flash = to_lm3560_flash(ctrl, led_no);
 	int rval = -EINVAL;
 
+	if (!pm_runtime_get_if_in_use(flash->dev))
+		return 0;
+
 	if (ctrl->id == V4L2_CID_FLASH_FAULT) {
 		s32 fault = 0;
 		unsigned int reg_val;
 		rval = regmap_read(flash->regmap, REG_FLAG, &reg_val);
-		if (rval < 0)
+		if (rval < 0) {
+			pm_runtime_put(flash->dev);
 			return rval;
+		}
 		if (reg_val & FAULT_SHORT_CIRCUIT)
 			fault |= V4L2_FLASH_FAULT_SHORT_CIRCUIT;
 		if (reg_val & FAULT_OVERTEMP)
@@ -187,6 +200,8 @@ static int lm3560_get_ctrl(struct v4l2_ctrl *ctrl, enum lm3560_led_id led_no)
 		ctrl->cur.val = fault;
 	}
 
+	pm_runtime_put(flash->dev);
+
 	return rval;
 }
 
@@ -196,6 +211,9 @@ static int lm3560_set_ctrl(struct v4l2_ctrl *ctrl, enum lm3560_led_id led_no)
 	u8 tout_bits;
 	int rval = -EINVAL;
 
+	if (!pm_runtime_get_if_in_use(flash->dev))
+		return 0;
+
 	switch (ctrl->id) {
 	case V4L2_CID_FLASH_LED_MODE:
 		flash->led_mode = ctrl->val;
@@ -241,6 +259,8 @@ static int lm3560_set_ctrl(struct v4l2_ctrl *ctrl, enum lm3560_led_id led_no)
 		break;
 	}
 
+	pm_runtime_put(flash->dev);
+
 	return rval;
 }
 
@@ -403,6 +423,60 @@ static int lm3560_init_device(struct lm3560_flash *flash)
 	return rval;
 }
 
+static void lm3560_power_off(struct lm3560_flash *flash)
+{
+	gpiod_set_value_cansleep(flash->hwen_gpio, 0);
+	regulator_disable(flash->vin_supply);
+}
+
+static int lm3560_power_on(struct lm3560_flash *flash)
+{
+	int rval;
+
+	rval = regulator_enable(flash->vin_supply);
+	if (rval < 0) {
+		dev_err(flash->dev, "failed to enable vin power supply\n");
+		return rval;
+	}
+
+	gpiod_set_value_cansleep(flash->hwen_gpio, 1);
+
+	rval = lm3560_init_device(flash);
+	if (rval < 0) {
+		lm3560_power_off(flash);
+		return rval;
+	}
+
+	return 0;
+}
+
+static int __maybe_unused lm3560_pm_runtime_resume(struct device *dev)
+{
+	struct lm3560_flash *flash = dev_get_drvdata(dev);
+
+	return lm3560_power_on(flash);
+}
+
+static int __maybe_unused lm3560_pm_runtime_suspend(struct device *dev)
+{
+	struct lm3560_flash *flash = dev_get_drvdata(dev);
+
+	lm3560_power_off(flash);
+
+	return 0;
+}
+
+static void lm3560_subdev_cleanup(struct lm3560_flash *flash)
+{
+	unsigned int i;
+
+	for (i = LM3560_LED0; i < LM3560_LED_MAX; i++) {
+		v4l2_device_unregister_subdev(&flash->subdev_led[i]);
+		v4l2_ctrl_handler_free(&flash->ctrls_led[i]);
+		media_entity_cleanup(&flash->subdev_led[i].entity);
+	}
+}
+
 static int lm3560_probe(struct i2c_client *client)
 {
 	struct lm3560_flash *flash;
@@ -423,6 +497,17 @@ static int lm3560_probe(struct i2c_client *client)
 	flash->dev = &client->dev;
 	mutex_init(&flash->lock);
 
+	flash->hwen_gpio = devm_gpiod_get_optional(&client->dev, "enable",
+						   GPIOD_OUT_LOW);
+	if (IS_ERR(flash->hwen_gpio))
+		return dev_err_probe(&client->dev, PTR_ERR(flash->hwen_gpio),
+				     "failed to get hwen gpio\n");
+
+	flash->vin_supply = devm_regulator_get(&client->dev, "vin");
+	if (IS_ERR(flash->vin_supply))
+		return dev_err_probe(&client->dev, PTR_ERR(flash->vin_supply),
+				     "failed to get vin-supply\n");
+
 	flash->peak = LM3560_PEAK_1600mA;
 	rval = device_property_read_u32(flash->dev,
 					"ti,peak-current-microamp", &peak_ua);
@@ -450,10 +535,13 @@ static int lm3560_probe(struct i2c_client *client)
 				 &flash->max_flash_timeout);
 	flash->max_flash_timeout /= 1000;
 
-	rval = lm3560_init_device(flash);
+	rval = lm3560_power_on(flash);
 	if (rval < 0)
 		return rval;
 
+	pm_runtime_set_active(flash->dev);
+	pm_runtime_enable(flash->dev);
+
 	device_for_each_child_node(flash->dev, node) {
 		fwnode_property_read_u32(node, "reg", &reg);
 
@@ -467,30 +555,53 @@ static int lm3560_probe(struct i2c_client *client)
 						 &flash->max_torch_brt[reg]);
 
 			rval = lm3560_subdev_init(flash, reg, node);
-			if (rval < 0)
-				return dev_err_probe(flash->dev, rval,
-						    "failed to register led%d\n",
-						    reg);
+			if (rval < 0) {
+				dev_err(flash->dev,
+					"failed to register led%d\n", reg);
+				goto error_clean;
+			}
 		}
 	}
 
 	i2c_set_clientdata(client, flash);
 
+	pm_runtime_set_autosuspend_delay(flash->dev, 1000);
+	pm_runtime_use_autosuspend(flash->dev);
+	pm_runtime_idle(flash->dev);
+
 	return 0;
+
+error_clean:
+	pm_runtime_disable(flash->dev);
+	pm_runtime_set_suspended(flash->dev);
+	lm3560_subdev_cleanup(flash);
+	lm3560_power_off(flash);
+
+	return rval;
 }
 
 static void lm3560_remove(struct i2c_client *client)
 {
 	struct lm3560_flash *flash = i2c_get_clientdata(client);
-	unsigned int i;
 
-	for (i = LM3560_LED0; i < LM3560_LED_MAX; i++) {
-		v4l2_device_unregister_subdev(&flash->subdev_led[i]);
-		v4l2_ctrl_handler_free(&flash->ctrls_led[i]);
-		media_entity_cleanup(&flash->subdev_led[i].entity);
+	lm3560_subdev_cleanup(flash);
+
+	/*
+	 * Disable runtime PM. In case runtime PM is disabled in the kernel,
+	 * make sure to turn power off manually.
+	 */
+	pm_runtime_disable(&client->dev);
+	if (!pm_runtime_status_suspended(&client->dev)) {
+		lm3560_power_off(flash);
+		pm_runtime_set_suspended(&client->dev);
 	}
 }
 
+static const struct dev_pm_ops lm3560_pm_ops = {
+	SET_RUNTIME_PM_OPS(lm3560_pm_runtime_suspend,
+			   lm3560_pm_runtime_resume, NULL)
+};
+
 static const struct of_device_id lm3560_of_match[] = {
 	{ .compatible = "ti,lm3559" },
 	{ .compatible = "ti,lm3560" },
@@ -509,7 +620,7 @@ MODULE_DEVICE_TABLE(i2c, lm3560_id_table);
 static struct i2c_driver lm3560_i2c_driver = {
 	.driver = {
 		   .name = LM3560_NAME,
-		   .pm = NULL,
+		   .pm = &lm3560_pm_ops,
 		   .of_match_table = lm3560_of_match,
 		   },
 	.probe = lm3560_probe,
-- 
2.51.0


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

* Re: [PATCH v2 1/5] dt-bindings: leds: Document TI LM3560 Synchronous Boost Flash Driver
  2026-04-19  9:34 ` [PATCH v2 1/5] dt-bindings: leds: Document TI LM3560 Synchronous Boost Flash Driver Svyatoslav Ryhel
@ 2026-04-20 16:20   ` Conor Dooley
  2026-04-20 16:35     ` Svyatoslav Ryhel
  2026-04-20 16:38     ` Sakari Ailus
  0 siblings, 2 replies; 12+ messages in thread
From: Conor Dooley @ 2026-04-20 16:20 UTC (permalink / raw)
  To: Svyatoslav Ryhel
  Cc: Lee Jones, Pavel Machek, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Sakari Ailus, Mauro Carvalho Chehab, linux-leds,
	devicetree, linux-kernel, linux-media

[-- Attachment #1: Type: text/plain, Size: 4422 bytes --]

On Sun, Apr 19, 2026 at 12:34:08PM +0300, Svyatoslav Ryhel wrote:
> Document TI LM3560 Synchronous Boost Flash Driver used for camera flash
> LEDs.
> 
> Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
> ---
>  .../devicetree/bindings/leds/ti,lm3560.yaml   | 131 ++++++++++++++++++
>  1 file changed, 131 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/leds/ti,lm3560.yaml
> 
> diff --git a/Documentation/devicetree/bindings/leds/ti,lm3560.yaml b/Documentation/devicetree/bindings/leds/ti,lm3560.yaml
> new file mode 100644
> index 000000000000..c6c553ad23f9
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/leds/ti,lm3560.yaml
> @@ -0,0 +1,131 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/leds/ti,lm3560.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: TI LM3560 Synchronous Boost Flash Driver
> +
> +maintainers:
> +  - Svyatoslav Ryhel <clamor95@gmail.com>
> +
> +description:
> +  The LM3560 is a 2-MHz fixed frequency synchronous boost converter with two
> +  1000-mA constant current drivers for high-current white LEDs. The dual high-
> +  side current sources allow for grounded cathode LED operation and can be
> +  tied together for providing flash currents at up to 2 A through a single LED.
> +  An adaptive regulation method ensures the current for each LED remains in
> +  regulation and maximizes efficiency.
> +
> +allOf:
> +  - $ref: /schemas/leds/common.yaml
> +
> +properties:
> +  compatible:
> +    enum:
> +      - ti,lm3559
> +      - ti,lm3560

What differentiates these devices to the point that fallback compatibles
are not suitable?

Cheers,
Conor.

> +
> +  reg:
> +    maxItems: 1
> +
> +  '#address-cells':
> +    const: 1
> +
> +  '#size-cells':
> +    const: 0
> +
> +  enable-gpios:
> +    description: GPIO connected to the HWEN pin.
> +    maxItems: 1
> +
> +  vin-supply:
> +    description: Supply connected to the IN line.
> +
> +  flash-max-timeout-us:
> +    minimum: 32000
> +    maximum: 1024000
> +    default: 32000
> +
> +  ti,peak-current-microamp:
> +    description:
> +      The LM3560 features 4 selectable current limits 1.6A, 2.3A, 3A, and 3.6A.
> +      When the current limit is reached, the LM3560 stops switching for the
> +      remainder of the switching cycle.
> +    enum: [16000000, 23000000, 30000000, 36000000]
> +    default: 16000000
> +
> +patternProperties:
> +  '^led@[01]$':
> +    description: LED control bank nodes.
> +    $ref: /schemas/leds/common.yaml#
> +    unevaluatedProperties: false
> +
> +    properties:
> +      reg:
> +        description: Control bank selection (0 = bank A, 1 = bank B).
> +        maximum: 1
> +
> +      flash-max-microamp:
> +        minimum: 62500
> +        maximum: 1000000
> +
> +      led-max-microamp:
> +        minimum: 31250
> +        maximum: 250000
> +
> +    required:
> +      - reg
> +      - flash-max-microamp
> +      - led-max-microamp
> +
> +required:
> +  - compatible
> +  - reg
> +  - '#address-cells'
> +  - '#size-cells'
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/gpio/gpio.h>
> +
> +    i2c {
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        led-controller@53 {
> +            compatible = "ti,lm3560";
> +            reg = <0x53>;
> +
> +            enable-gpios = <&gpio 28 GPIO_ACTIVE_HIGH>;
> +            vin-supply = <&vdd_3v3_sys>;
> +
> +            flash-max-timeout-us = <1024000>;
> +            ti,peak-current-microamp = <16000000>;
> +
> +            #address-cells = <1>;
> +            #size-cells = <0>;
> +
> +            led@0 {
> +                reg = <0>;
> +
> +                label = "white::flash";
> +                linux,default-trigger = "flash";
> +
> +                flash-max-microamp = <562500>;
> +                led-max-microamp = <156250>;
> +            };
> +
> +            led@1 {
> +                reg = <1>;
> +
> +                label = "yellow::flash";
> +                linux,default-trigger = "flash";
> +
> +                flash-max-microamp = <562500>;
> +                led-max-microamp = <156250>;
> +            };
> +        };
> +    };
> -- 
> 2.51.0
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

* Re: [PATCH v2 1/5] dt-bindings: leds: Document TI LM3560 Synchronous Boost Flash Driver
  2026-04-20 16:20   ` Conor Dooley
@ 2026-04-20 16:35     ` Svyatoslav Ryhel
  2026-04-20 16:38     ` Sakari Ailus
  1 sibling, 0 replies; 12+ messages in thread
From: Svyatoslav Ryhel @ 2026-04-20 16:35 UTC (permalink / raw)
  To: Conor Dooley
  Cc: Lee Jones, Pavel Machek, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Sakari Ailus, Mauro Carvalho Chehab, linux-leds,
	devicetree, linux-kernel, linux-media

пн, 20 квіт. 2026 р. о 19:20 Conor Dooley <conor@kernel.org> пише:
>
> On Sun, Apr 19, 2026 at 12:34:08PM +0300, Svyatoslav Ryhel wrote:
> > Document TI LM3560 Synchronous Boost Flash Driver used for camera flash
> > LEDs.
> >
> > Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
> > ---
> >  .../devicetree/bindings/leds/ti,lm3560.yaml   | 131 ++++++++++++++++++
> >  1 file changed, 131 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/leds/ti,lm3560.yaml
> >
> > diff --git a/Documentation/devicetree/bindings/leds/ti,lm3560.yaml b/Documentation/devicetree/bindings/leds/ti,lm3560.yaml
> > new file mode 100644
> > index 000000000000..c6c553ad23f9
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/leds/ti,lm3560.yaml
> > @@ -0,0 +1,131 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/leds/ti,lm3560.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: TI LM3560 Synchronous Boost Flash Driver
> > +
> > +maintainers:
> > +  - Svyatoslav Ryhel <clamor95@gmail.com>
> > +
> > +description:
> > +  The LM3560 is a 2-MHz fixed frequency synchronous boost converter with two
> > +  1000-mA constant current drivers for high-current white LEDs. The dual high-
> > +  side current sources allow for grounded cathode LED operation and can be
> > +  tied together for providing flash currents at up to 2 A through a single LED.
> > +  An adaptive regulation method ensures the current for each LED remains in
> > +  regulation and maximizes efficiency.
> > +
> > +allOf:
> > +  - $ref: /schemas/leds/common.yaml
> > +
> > +properties:
> > +  compatible:
> > +    enum:
> > +      - ti,lm3559
> > +      - ti,lm3560
>
> What differentiates these devices to the point that fallback compatibles
> are not suitable?
>

noted

> Cheers,
> Conor.
>
> > +
> > +  reg:
> > +    maxItems: 1
> > +
> > +  '#address-cells':
> > +    const: 1
> > +
> > +  '#size-cells':
> > +    const: 0
> > +
> > +  enable-gpios:
> > +    description: GPIO connected to the HWEN pin.
> > +    maxItems: 1
> > +
> > +  vin-supply:
> > +    description: Supply connected to the IN line.
> > +
> > +  flash-max-timeout-us:
> > +    minimum: 32000
> > +    maximum: 1024000
> > +    default: 32000
> > +
> > +  ti,peak-current-microamp:
> > +    description:
> > +      The LM3560 features 4 selectable current limits 1.6A, 2.3A, 3A, and 3.6A.
> > +      When the current limit is reached, the LM3560 stops switching for the
> > +      remainder of the switching cycle.
> > +    enum: [16000000, 23000000, 30000000, 36000000]
> > +    default: 16000000
> > +
> > +patternProperties:
> > +  '^led@[01]$':
> > +    description: LED control bank nodes.
> > +    $ref: /schemas/leds/common.yaml#
> > +    unevaluatedProperties: false
> > +
> > +    properties:
> > +      reg:
> > +        description: Control bank selection (0 = bank A, 1 = bank B).
> > +        maximum: 1
> > +
> > +      flash-max-microamp:
> > +        minimum: 62500
> > +        maximum: 1000000
> > +
> > +      led-max-microamp:
> > +        minimum: 31250
> > +        maximum: 250000
> > +
> > +    required:
> > +      - reg
> > +      - flash-max-microamp
> > +      - led-max-microamp
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - '#address-cells'
> > +  - '#size-cells'
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/gpio/gpio.h>
> > +
> > +    i2c {
> > +        #address-cells = <1>;
> > +        #size-cells = <0>;
> > +
> > +        led-controller@53 {
> > +            compatible = "ti,lm3560";
> > +            reg = <0x53>;
> > +
> > +            enable-gpios = <&gpio 28 GPIO_ACTIVE_HIGH>;
> > +            vin-supply = <&vdd_3v3_sys>;
> > +
> > +            flash-max-timeout-us = <1024000>;
> > +            ti,peak-current-microamp = <16000000>;
> > +
> > +            #address-cells = <1>;
> > +            #size-cells = <0>;
> > +
> > +            led@0 {
> > +                reg = <0>;
> > +
> > +                label = "white::flash";
> > +                linux,default-trigger = "flash";
> > +
> > +                flash-max-microamp = <562500>;
> > +                led-max-microamp = <156250>;
> > +            };
> > +
> > +            led@1 {
> > +                reg = <1>;
> > +
> > +                label = "yellow::flash";
> > +                linux,default-trigger = "flash";
> > +
> > +                flash-max-microamp = <562500>;
> > +                led-max-microamp = <156250>;
> > +            };
> > +        };
> > +    };
> > --
> > 2.51.0
> >

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

* Re: [PATCH v2 1/5] dt-bindings: leds: Document TI LM3560 Synchronous Boost Flash Driver
  2026-04-20 16:20   ` Conor Dooley
  2026-04-20 16:35     ` Svyatoslav Ryhel
@ 2026-04-20 16:38     ` Sakari Ailus
  1 sibling, 0 replies; 12+ messages in thread
From: Sakari Ailus @ 2026-04-20 16:38 UTC (permalink / raw)
  To: Conor Dooley
  Cc: Svyatoslav Ryhel, Lee Jones, Pavel Machek, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Mauro Carvalho Chehab,
	linux-leds, devicetree, linux-kernel, linux-media

Hi Conor,

On Mon, Apr 20, 2026 at 05:20:28PM +0100, Conor Dooley wrote:
> > +properties:
> > +  compatible:
> > +    enum:
> > +      - ti,lm3559
> > +      - ti,lm3560
> 
> What differentiates these devices to the point that fallback compatibles
> are not suitable?

Good question.

It seems the currents are different albeit the register values themselves
are the same. The driver doesn't seem to handle that properly right now, so
it's a driver bug.

I'd keep the compatibles as-is as the current limit applied should be as
specified in DT.

-- 
Kind regards,

Sakari Ailus

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

* Re: [PATCH v2 5/5] media: i2c: lm3560: Add support for PM features
  2026-04-19  9:34 ` [PATCH v2 5/5] media: i2c: lm3560: Add support for PM features Svyatoslav Ryhel
@ 2026-04-21 16:44   ` Sakari Ailus
  2026-04-21 17:32     ` Svyatoslav Ryhel
  0 siblings, 1 reply; 12+ messages in thread
From: Sakari Ailus @ 2026-04-21 16:44 UTC (permalink / raw)
  To: Svyatoslav Ryhel
  Cc: Lee Jones, Pavel Machek, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Mauro Carvalho Chehab, linux-leds, devicetree,
	linux-kernel, linux-media

Hi Shyvatoslav,

On Sun, Apr 19, 2026 at 12:34:12PM +0300, Svyatoslav Ryhel wrote:
> @@ -403,6 +423,60 @@ static int lm3560_init_device(struct lm3560_flash *flash)
>  	return rval;
>  }
>  
> +static void lm3560_power_off(struct lm3560_flash *flash)
> +{
> +	gpiod_set_value_cansleep(flash->hwen_gpio, 0);
> +	regulator_disable(flash->vin_supply);
> +}
> +
> +static int lm3560_power_on(struct lm3560_flash *flash)
> +{
> +	int rval;
> +
> +	rval = regulator_enable(flash->vin_supply);
> +	if (rval < 0) {
> +		dev_err(flash->dev, "failed to enable vin power supply\n");
> +		return rval;
> +	}
> +
> +	gpiod_set_value_cansleep(flash->hwen_gpio, 1);
> +
> +	rval = lm3560_init_device(flash);
> +	if (rval < 0) {
> +		lm3560_power_off(flash);
> +		return rval;
> +	}
> +
> +	return 0;
> +}
> +
> +static int __maybe_unused lm3560_pm_runtime_resume(struct device *dev)
> +{
> +	struct lm3560_flash *flash = dev_get_drvdata(dev);
> +
> +	return lm3560_power_on(flash);
> +}
> +
> +static int __maybe_unused lm3560_pm_runtime_suspend(struct device *dev)

Could you change lm3560_power_o{n,ff}() take struct device pointer as the
argument?

> +{
> +	struct lm3560_flash *flash = dev_get_drvdata(dev);
> +
> +	lm3560_power_off(flash);
> +
> +	return 0;
> +}
> +
> +static void lm3560_subdev_cleanup(struct lm3560_flash *flash)
> +{
> +	unsigned int i;
> +
> +	for (i = LM3560_LED0; i < LM3560_LED_MAX; i++) {

You could define i here.

> +		v4l2_device_unregister_subdev(&flash->subdev_led[i]);
> +		v4l2_ctrl_handler_free(&flash->ctrls_led[i]);
> +		media_entity_cleanup(&flash->subdev_led[i].entity);
> +	}
> +}
> +
>  static int lm3560_probe(struct i2c_client *client)
>  {
>  	struct lm3560_flash *flash;

-- 
Kind regards,

Sakari Ailus

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

* Re: [PATCH v2 5/5] media: i2c: lm3560: Add support for PM features
  2026-04-21 16:44   ` Sakari Ailus
@ 2026-04-21 17:32     ` Svyatoslav Ryhel
  2026-04-21 19:59       ` Sakari Ailus
  0 siblings, 1 reply; 12+ messages in thread
From: Svyatoslav Ryhel @ 2026-04-21 17:32 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: Lee Jones, Pavel Machek, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Mauro Carvalho Chehab, linux-leds, devicetree,
	linux-kernel, linux-media

вт, 21 квіт. 2026 р. о 19:44 Sakari Ailus <sakari.ailus@linux.intel.com> пише:
>
> Hi Shyvatoslav,
>
> On Sun, Apr 19, 2026 at 12:34:12PM +0300, Svyatoslav Ryhel wrote:
> > @@ -403,6 +423,60 @@ static int lm3560_init_device(struct lm3560_flash *flash)
> >       return rval;
> >  }
> >
> > +static void lm3560_power_off(struct lm3560_flash *flash)
> > +{
> > +     gpiod_set_value_cansleep(flash->hwen_gpio, 0);
> > +     regulator_disable(flash->vin_supply);
> > +}
> > +
> > +static int lm3560_power_on(struct lm3560_flash *flash)
> > +{
> > +     int rval;
> > +
> > +     rval = regulator_enable(flash->vin_supply);
> > +     if (rval < 0) {
> > +             dev_err(flash->dev, "failed to enable vin power supply\n");
> > +             return rval;
> > +     }
> > +
> > +     gpiod_set_value_cansleep(flash->hwen_gpio, 1);
> > +
> > +     rval = lm3560_init_device(flash);
> > +     if (rval < 0) {
> > +             lm3560_power_off(flash);
> > +             return rval;
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +static int __maybe_unused lm3560_pm_runtime_resume(struct device *dev)
> > +{
> > +     struct lm3560_flash *flash = dev_get_drvdata(dev);
> > +
> > +     return lm3560_power_on(flash);
> > +}
> > +
> > +static int __maybe_unused lm3560_pm_runtime_suspend(struct device *dev)
>
> Could you change lm3560_power_o{n,ff}() take struct device pointer as the
> argument?
>

What benefit it will bring? Unless you propose to use on/off functions
in pm directly, I don't see any benefit in this change.

> > +{
> > +     struct lm3560_flash *flash = dev_get_drvdata(dev);
> > +
> > +     lm3560_power_off(flash);
> > +
> > +     return 0;
> > +}
> > +
> > +static void lm3560_subdev_cleanup(struct lm3560_flash *flash)
> > +{
> > +     unsigned int i;
> > +
> > +     for (i = LM3560_LED0; i < LM3560_LED_MAX; i++) {
>
> You could define i here.
>

You mean:
 for (unsigned int i = LM3560_LED0; i < LM3560_LED_MAX; i++)?

If yes, I would like to keep it as is, it looks cleaner to me, and
this part was transferred from remove as is.

> > +             v4l2_device_unregister_subdev(&flash->subdev_led[i]);
> > +             v4l2_ctrl_handler_free(&flash->ctrls_led[i]);
> > +             media_entity_cleanup(&flash->subdev_led[i].entity);
> > +     }
> > +}
> > +
> >  static int lm3560_probe(struct i2c_client *client)
> >  {
> >       struct lm3560_flash *flash;
>
> --
> Kind regards,
>
> Sakari Ailus

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

* Re: [PATCH v2 5/5] media: i2c: lm3560: Add support for PM features
  2026-04-21 17:32     ` Svyatoslav Ryhel
@ 2026-04-21 19:59       ` Sakari Ailus
  0 siblings, 0 replies; 12+ messages in thread
From: Sakari Ailus @ 2026-04-21 19:59 UTC (permalink / raw)
  To: Svyatoslav Ryhel
  Cc: Lee Jones, Pavel Machek, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Mauro Carvalho Chehab, linux-leds, devicetree,
	linux-kernel, linux-media

Hi Svyatoslav,

On Tue, Apr 21, 2026 at 08:32:16PM +0300, Svyatoslav Ryhel wrote:
> вт, 21 квіт. 2026 р. о 19:44 Sakari Ailus <sakari.ailus@linux.intel.com> пише:
> >
> > Hi Shyvatoslav,
> >
> > On Sun, Apr 19, 2026 at 12:34:12PM +0300, Svyatoslav Ryhel wrote:
> > > @@ -403,6 +423,60 @@ static int lm3560_init_device(struct lm3560_flash *flash)
> > >       return rval;
> > >  }
> > >
> > > +static void lm3560_power_off(struct lm3560_flash *flash)
> > > +{
> > > +     gpiod_set_value_cansleep(flash->hwen_gpio, 0);
> > > +     regulator_disable(flash->vin_supply);
> > > +}
> > > +
> > > +static int lm3560_power_on(struct lm3560_flash *flash)
> > > +{
> > > +     int rval;
> > > +
> > > +     rval = regulator_enable(flash->vin_supply);
> > > +     if (rval < 0) {
> > > +             dev_err(flash->dev, "failed to enable vin power supply\n");
> > > +             return rval;
> > > +     }
> > > +
> > > +     gpiod_set_value_cansleep(flash->hwen_gpio, 1);
> > > +
> > > +     rval = lm3560_init_device(flash);
> > > +     if (rval < 0) {
> > > +             lm3560_power_off(flash);
> > > +             return rval;
> > > +     }
> > > +
> > > +     return 0;
> > > +}
> > > +
> > > +static int __maybe_unused lm3560_pm_runtime_resume(struct device *dev)
> > > +{
> > > +     struct lm3560_flash *flash = dev_get_drvdata(dev);
> > > +
> > > +     return lm3560_power_on(flash);
> > > +}
> > > +
> > > +static int __maybe_unused lm3560_pm_runtime_suspend(struct device *dev)
> >
> > Could you change lm3560_power_o{n,ff}() take struct device pointer as the
> > argument?
> >
> 
> What benefit it will bring? Unless you propose to use on/off functions
> in pm directly, I don't see any benefit in this change.

You get rid of two redundant wrappers.

> 
> > > +{
> > > +     struct lm3560_flash *flash = dev_get_drvdata(dev);
> > > +
> > > +     lm3560_power_off(flash);
> > > +
> > > +     return 0;
> > > +}
> > > +
> > > +static void lm3560_subdev_cleanup(struct lm3560_flash *flash)
> > > +{
> > > +     unsigned int i;
> > > +
> > > +     for (i = LM3560_LED0; i < LM3560_LED_MAX; i++) {
> >
> > You could define i here.
> >
> 
> You mean:
>  for (unsigned int i = LM3560_LED0; i < LM3560_LED_MAX; i++)?
> 
> If yes, I would like to keep it as is, it looks cleaner to me, and
> this part was transferred from remove as is.

Works for me.

-- 
Regards,

Sakari Ailus

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

end of thread, other threads:[~2026-04-21 19:59 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-19  9:34 [PATCH v2 0/5] media: lm3560: convert to use OF bindings Svyatoslav Ryhel
2026-04-19  9:34 ` [PATCH v2 1/5] dt-bindings: leds: Document TI LM3560 Synchronous Boost Flash Driver Svyatoslav Ryhel
2026-04-20 16:20   ` Conor Dooley
2026-04-20 16:35     ` Svyatoslav Ryhel
2026-04-20 16:38     ` Sakari Ailus
2026-04-19  9:34 ` [PATCH v2 2/5] media: i2c: lm3560: Fix v4l2 subdev registration Svyatoslav Ryhel
2026-04-19  9:34 ` [PATCH v2 3/5] media: i2c: lm3560: Optimize mutex lock usage Svyatoslav Ryhel
2026-04-19  9:34 ` [PATCH v2 4/5] media: i2c: lm3560: Convert to use OF bindings Svyatoslav Ryhel
2026-04-19  9:34 ` [PATCH v2 5/5] media: i2c: lm3560: Add support for PM features Svyatoslav Ryhel
2026-04-21 16:44   ` Sakari Ailus
2026-04-21 17:32     ` Svyatoslav Ryhel
2026-04-21 19:59       ` Sakari Ailus

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