linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v1 0/2] Add OF support for LM3560
@ 2023-03-08  9:52 Svyatoslav Ryhel
  2023-03-08  9:52 ` [PATCH v1 1/2] dt-bindings: media: i2c: add lm3560 binding Svyatoslav Ryhel
  2023-03-08  9:52 ` [PATCH v1 2/2] media: lm3560: convent to OF Svyatoslav Ryhel
  0 siblings, 2 replies; 6+ messages in thread
From: Svyatoslav Ryhel @ 2023-03-08  9:52 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
	Svyatoslav Ryhel, Hans Verkuil, Luca Ceresoli, Jean Delvare,
	Sebastian Reichel, Daniel Jeong, Ldd-Mlp
  Cc: linux-media, devicetree, linux-kernel

Implement device tree support to lm3560 and make some 
minor style adjustmets.

Svyatoslav Ryhel (2):
  dt-bindings: media: i2c: add lm3560 binding
  media: lm3560: convent to OF

 .../bindings/media/i2c/ti,lm3560.yaml         | 130 ++++++++++++++++++
 drivers/media/i2c/lm3560.c                    | 128 ++++++++++++-----
 2 files changed, 223 insertions(+), 35 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/media/i2c/ti,lm3560.yaml

-- 
2.37.2


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

* [PATCH v1 1/2] dt-bindings: media: i2c: add lm3560 binding
  2023-03-08  9:52 [PATCH v1 0/2] Add OF support for LM3560 Svyatoslav Ryhel
@ 2023-03-08  9:52 ` Svyatoslav Ryhel
  2023-03-08 14:06   ` Rob Herring
  2023-03-08 18:21   ` Rob Herring
  2023-03-08  9:52 ` [PATCH v1 2/2] media: lm3560: convent to OF Svyatoslav Ryhel
  1 sibling, 2 replies; 6+ messages in thread
From: Svyatoslav Ryhel @ 2023-03-08  9:52 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
	Svyatoslav Ryhel, Hans Verkuil, Luca Ceresoli, Jean Delvare,
	Sebastian Reichel, Daniel Jeong, Ldd-Mlp
  Cc: linux-media, devicetree, linux-kernel

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

diff --git a/Documentation/devicetree/bindings/media/i2c/ti,lm3560.yaml b/Documentation/devicetree/bindings/media/i2c/ti,lm3560.yaml
new file mode 100644
index 000000000000..b3c2ccb83a30
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/i2c/ti,lm3560.yaml
@@ -0,0 +1,130 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/i2c/ti,lm3560.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: TI LM3560 Synchronous Boost Flash Driver
+
+maintainers:
+  - Daniel Jeong <gshark.jeong@gmail.com>
+  - Ldd-Mlp <ldd-mlp@list.ti.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 highside 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.
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - ti,lm3559
+          - ti,lm3560
+
+  reg:
+    maxItems: 1
+
+  enable-gpios:
+    maxItems: 1
+
+  ti,peak-current:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [0, 0x20, 0x40, 0x60]
+    default: 0x60
+    description: |
+      Peak current can be set to 4 values 1.6A (0x00),
+      2.3A (0x20), 3.0A (0x40) and 3.6A (0x60).
+
+  ti,max-flash-timeout:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 32
+    maximum: 1024
+    default: 1024
+    description: |
+      Maximum flash timeout in ms with step 32ms.
+
+  '#address-cells':
+    const: 1
+
+  '#size-cells':
+    const: 0
+
+required:
+  - compatible
+  - reg
+  - '#address-cells'
+  - '#size-cells'
+
+patternProperties:
+  "^led@[01]$":
+    type: object
+    description: |
+      Properties for a connected LEDs.
+    properties:
+      reg:
+        minimum: 0
+        maximum: 1
+
+      ti,max-flash-current:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        minimum: 62500
+        maximum: 1000000
+        default: 1000000
+        description: |
+          Maximum current in flash mode in uA with step 62500uA.
+
+      ti,max-torch-current:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        minimum: 31250
+        maximum: 250000
+        default: 250000
+        description: |
+          Maximum current in tourch mode in uA with step 31250uA.
+
+    required:
+      - reg
+
+    additionalProperties: false
+
+additionalProperties: false
+
+examples:
+  - |
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        flash-led@53 {
+            compatible = "ti,lm3559";
+            reg = <0x53>;
+
+            enable-gpios = <&gpio 219 GPIO_ACTIVE_HIGH>;
+
+            ti,peak-current = <0>;
+            ti,max-flash-timeout = <1024>;
+
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            led@0 {
+                reg = <0>;
+
+                ti,max-flash-current = <562500>;
+                ti,max-torch-current = <156250>;
+            };
+
+            led@1 {
+                reg = <1>;
+
+                ti,max-flash-current = <562500>;
+                ti,max-torch-current = <156250>;
+            };
+        };
+    };
+...
-- 
2.37.2


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

* [PATCH v1 2/2] media: lm3560: convent to OF
  2023-03-08  9:52 [PATCH v1 0/2] Add OF support for LM3560 Svyatoslav Ryhel
  2023-03-08  9:52 ` [PATCH v1 1/2] dt-bindings: media: i2c: add lm3560 binding Svyatoslav Ryhel
@ 2023-03-08  9:52 ` Svyatoslav Ryhel
  2023-03-14 11:00   ` Sakari Ailus
  1 sibling, 1 reply; 6+ messages in thread
From: Svyatoslav Ryhel @ 2023-03-08  9:52 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
	Svyatoslav Ryhel, Hans Verkuil, Luca Ceresoli, Jean Delvare,
	Sebastian Reichel, Daniel Jeong, Ldd-Mlp
  Cc: linux-media, devicetree, linux-kernel

If no pdata is available, try to read from device tree.

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

diff --git a/drivers/media/i2c/lm3560.c b/drivers/media/i2c/lm3560.c
index 5ef613604be7..5541051616b7 100644
--- a/drivers/media/i2c/lm3560.c
+++ b/drivers/media/i2c/lm3560.c
@@ -11,6 +11,7 @@
 
 #include <linux/delay.h>
 #include <linux/module.h>
+#include <linux/gpio.h>
 #include <linux/i2c.h>
 #include <linux/slab.h>
 #include <linux/mutex.h>
@@ -22,16 +23,16 @@
 
 /* registers definitions */
 #define REG_ENABLE		0x10
-#define REG_TORCH_BR	0xa0
-#define REG_FLASH_BR	0xb0
-#define REG_FLASH_TOUT	0xc0
+#define REG_TORCH_BR		0xa0
+#define REG_FLASH_BR		0xb0
+#define REG_FLASH_TOUT		0xc0
 #define REG_FLAG		0xd0
 #define REG_CONFIG1		0xe0
 
 /* fault mask */
-#define FAULT_TIMEOUT	(1<<0)
-#define FAULT_OVERTEMP	(1<<1)
-#define FAULT_SHORT_CIRCUIT	(1<<2)
+#define FAULT_TIMEOUT		BIT(0)
+#define FAULT_OVERTEMP		BIT(1)
+#define FAULT_SHORT_CIRCUIT	BIT(2)
 
 enum led_enable {
 	MODE_SHDN = 0x0,
@@ -54,6 +55,7 @@ struct lm3560_flash {
 	struct device *dev;
 	struct lm3560_platform_data *pdata;
 	struct regmap *regmap;
+	struct gpio_desc *hwen_gpio;
 	struct mutex lock;
 
 	enum v4l2_flash_led_mode led_mode;
@@ -356,12 +358,19 @@ static int lm3560_subdev_init(struct lm3560_flash *flash,
 	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));
+
 	rval = lm3560_init_controls(flash, led_no);
-	if (rval)
+	if (rval) {
+		dev_err(flash->dev, "failed to init controls: %d\n", rval);
 		goto err_out;
+	}
+
 	rval = media_entity_pads_init(&flash->subdev_led[led_no].entity, 0, NULL);
-	if (rval < 0)
+	if (rval < 0) {
+		dev_err(flash->dev, "failed to init media entity pads: %d\n", rval);
 		goto err_out;
+	}
+
 	flash->subdev_led[led_no].entity.function = MEDIA_ENT_F_FLASH;
 
 	return rval;
@@ -391,6 +400,49 @@ static int lm3560_init_device(struct lm3560_flash *flash)
 	return rval;
 }
 
+static int lm3560_of_probe(struct lm3560_flash *flash)
+{
+	struct lm3560_platform_data *pdata;
+	struct fwnode_handle *node;
+	int ret, reg;
+
+	pdata = devm_kzalloc(flash->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return -ENODEV;
+
+	ret = device_property_read_u32(flash->dev,
+				       "ti,peak-current", &pdata->peak);
+	if (ret)
+		pdata->peak = LM3560_PEAK_3600mA;
+
+	ret = device_property_read_u32(flash->dev,
+				       "ti,max-flash-timeout",
+				       &pdata->max_flash_timeout);
+	if (ret)
+		pdata->max_flash_timeout = LM3560_FLASH_TOUT_MAX;
+
+	device_for_each_child_node(flash->dev, node) {
+		fwnode_property_read_u32(node, "reg", &reg);
+
+		if (reg == LM3560_LED0 || reg == LM3560_LED1) {
+			ret = device_property_read_u32(flash->dev,
+						       "ti,max-flash-current",
+						       &pdata->max_flash_brt[reg]);
+			if (ret)
+				pdata->max_flash_brt[reg] = LM3560_FLASH_TOUT_MAX;
+
+			ret = device_property_read_u32(flash->dev,
+						       "ti,max-torch-current",
+						       &pdata->max_torch_brt[reg]);
+			if (ret)
+				pdata->max_torch_brt[reg] = LM3560_TORCH_BRT_MAX;
+		}
+	}
+	flash->pdata = pdata;
+
+	return 0;
+}
+
 static int lm3560_probe(struct i2c_client *client)
 {
 	struct lm3560_flash *flash;
@@ -398,44 +450,41 @@ static int lm3560_probe(struct i2c_client *client)
 	int rval;
 
 	flash = devm_kzalloc(&client->dev, sizeof(*flash), GFP_KERNEL);
-	if (flash == NULL)
+	if (!flash)
 		return -ENOMEM;
 
 	flash->regmap = devm_regmap_init_i2c(client, &lm3560_regmap);
-	if (IS_ERR(flash->regmap)) {
-		rval = PTR_ERR(flash->regmap);
-		return rval;
-	}
+	if (IS_ERR(flash->regmap))
+		return dev_err_probe(&client->dev, PTR_ERR(flash->regmap),
+				     "failed to init regmap\n");
 
-	/* 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);
 
+	/* if there is no platform data, try to read from device tree */
+	if (!pdata)
+		lm3560_of_probe(flash);
+
+	flash->hwen_gpio = devm_gpiod_get_optional(flash->dev, "enable",
+						   GPIOD_OUT_HIGH);
+	if (IS_ERR(flash->hwen_gpio))
+		return dev_err_probe(&client->dev, PTR_ERR(flash->hwen_gpio),
+				     "failed to get hwen gpio\n");
+
 	rval = lm3560_subdev_init(flash, LM3560_LED0, "lm3560-led0");
 	if (rval < 0)
-		return rval;
+		return dev_err_probe(&client->dev, rval,
+				     "failed to init led0 subdev\n");
 
 	rval = lm3560_subdev_init(flash, LM3560_LED1, "lm3560-led1");
 	if (rval < 0)
-		return rval;
+		return dev_err_probe(&client->dev, rval,
+				     "failed to init led1 subdev\n");
 
 	rval = lm3560_init_device(flash);
 	if (rval < 0)
-		return rval;
+		return dev_err_probe(&client->dev, rval,
+				     "failed to init device\n");
 
 	i2c_set_clientdata(client, flash);
 
@@ -452,21 +501,30 @@ static void lm3560_remove(struct i2c_client *client)
 		v4l2_ctrl_handler_free(&flash->ctrls_led[i]);
 		media_entity_cleanup(&flash->subdev_led[i].entity);
 	}
+
+	gpiod_set_value_cansleep(flash->hwen_gpio, 0);
 }
 
+static const struct of_device_id lm3560_match[] = {
+	{ .compatible = "ti,lm3559" },
+	{ .compatible = "ti,lm3560" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, lm3560_match);
+
 static const struct i2c_device_id lm3560_id_table[] = {
 	{LM3559_NAME, 0},
 	{LM3560_NAME, 0},
 	{}
 };
-
 MODULE_DEVICE_TABLE(i2c, lm3560_id_table);
 
 static struct i2c_driver lm3560_i2c_driver = {
 	.driver = {
-		   .name = LM3560_NAME,
-		   .pm = NULL,
-		   },
+		.name = LM3560_NAME,
+		.pm = NULL,
+		.of_match_table = lm3560_match,
+	},
 	.probe_new = lm3560_probe,
 	.remove = lm3560_remove,
 	.id_table = lm3560_id_table,
-- 
2.37.2


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

* Re: [PATCH v1 1/2] dt-bindings: media: i2c: add lm3560 binding
  2023-03-08  9:52 ` [PATCH v1 1/2] dt-bindings: media: i2c: add lm3560 binding Svyatoslav Ryhel
@ 2023-03-08 14:06   ` Rob Herring
  2023-03-08 18:21   ` Rob Herring
  1 sibling, 0 replies; 6+ messages in thread
From: Rob Herring @ 2023-03-08 14:06 UTC (permalink / raw)
  To: Svyatoslav Ryhel
  Cc: linux-media, Rob Herring, Hans Verkuil, Mauro Carvalho Chehab,
	Krzysztof Kozlowski, Ldd-Mlp, Daniel Jeong, Jean Delvare,
	devicetree, linux-kernel, Luca Ceresoli, Sebastian Reichel


On Wed, 08 Mar 2023 11:52:08 +0200, Svyatoslav Ryhel wrote:
> Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
> ---
>  .../bindings/media/i2c/ti,lm3560.yaml         | 130 ++++++++++++++++++
>  1 file changed, 130 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/i2c/ti,lm3560.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Error: Documentation/devicetree/bindings/media/i2c/ti,lm3560.example.dts:26.43-44 syntax error
FATAL ERROR: Unable to parse input tree
make[1]: *** [scripts/Makefile.lib:419: Documentation/devicetree/bindings/media/i2c/ti,lm3560.example.dtb] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:1512: dt_binding_check] Error 2

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20230308095209.14700-2-clamor95@gmail.com

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.


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

* Re: [PATCH v1 1/2] dt-bindings: media: i2c: add lm3560 binding
  2023-03-08  9:52 ` [PATCH v1 1/2] dt-bindings: media: i2c: add lm3560 binding Svyatoslav Ryhel
  2023-03-08 14:06   ` Rob Herring
@ 2023-03-08 18:21   ` Rob Herring
  1 sibling, 0 replies; 6+ messages in thread
From: Rob Herring @ 2023-03-08 18:21 UTC (permalink / raw)
  To: Svyatoslav Ryhel
  Cc: Mauro Carvalho Chehab, Krzysztof Kozlowski, Hans Verkuil,
	Luca Ceresoli, Jean Delvare, Sebastian Reichel, Daniel Jeong,
	Ldd-Mlp, linux-media, devicetree, linux-kernel

On Wed, Mar 08, 2023 at 11:52:08AM +0200, Svyatoslav Ryhel wrote:
> Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
> ---
>  .../bindings/media/i2c/ti,lm3560.yaml         | 130 ++++++++++++++++++
>  1 file changed, 130 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/i2c/ti,lm3560.yaml
> 
> diff --git a/Documentation/devicetree/bindings/media/i2c/ti,lm3560.yaml b/Documentation/devicetree/bindings/media/i2c/ti,lm3560.yaml
> new file mode 100644
> index 000000000000..b3c2ccb83a30
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/i2c/ti,lm3560.yaml
> @@ -0,0 +1,130 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/media/i2c/ti,lm3560.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: TI LM3560 Synchronous Boost Flash Driver
> +
> +maintainers:
> +  - Daniel Jeong <gshark.jeong@gmail.com>
> +  - Ldd-Mlp <ldd-mlp@list.ti.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 highside 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.
> +
> +properties:
> +  compatible:
> +    items:
> +      - enum:
> +          - ti,lm3559
> +          - ti,lm3560
> +
> +  reg:
> +    maxItems: 1
> +
> +  enable-gpios:
> +    maxItems: 1
> +
> +  ti,peak-current:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    enum: [0, 0x20, 0x40, 0x60]
> +    default: 0x60
> +    description: |
> +      Peak current can be set to 4 values 1.6A (0x00),
> +      2.3A (0x20), 3.0A (0x40) and 3.6A (0x60).

Pretty sure we have common properties for this.

> +
> +  ti,max-flash-timeout:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    minimum: 32
> +    maximum: 1024
> +    default: 1024
> +    description: |
> +      Maximum flash timeout in ms with step 32ms.

And this too.

> +
> +  '#address-cells':
> +    const: 1
> +
> +  '#size-cells':
> +    const: 0
> +
> +required:
> +  - compatible
> +  - reg
> +  - '#address-cells'
> +  - '#size-cells'
> +
> +patternProperties:
> +  "^led@[01]$":
> +    type: object
> +    description: |
> +      Properties for a connected LEDs.
> +    properties:
> +      reg:
> +        minimum: 0
> +        maximum: 1
> +
> +      ti,max-flash-current:
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +        minimum: 62500
> +        maximum: 1000000
> +        default: 1000000
> +        description: |
> +          Maximum current in flash mode in uA with step 62500uA.

Or maybe it's these per LED settings that are common.

BTW, anything with units, should have a standard unit suffix.

> +
> +      ti,max-torch-current:
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +        minimum: 31250
> +        maximum: 250000
> +        default: 250000
> +        description: |
> +          Maximum current in tourch mode in uA with step 31250uA.
> +
> +    required:
> +      - reg
> +
> +    additionalProperties: false
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    i2c {
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        flash-led@53 {

led-controller@53

> +            compatible = "ti,lm3559";
> +            reg = <0x53>;
> +
> +            enable-gpios = <&gpio 219 GPIO_ACTIVE_HIGH>;
> +
> +            ti,peak-current = <0>;
> +            ti,max-flash-timeout = <1024>;
> +
> +            #address-cells = <1>;
> +            #size-cells = <0>;
> +
> +            led@0 {
> +                reg = <0>;
> +
> +                ti,max-flash-current = <562500>;
> +                ti,max-torch-current = <156250>;
> +            };
> +
> +            led@1 {
> +                reg = <1>;
> +
> +                ti,max-flash-current = <562500>;
> +                ti,max-torch-current = <156250>;
> +            };
> +        };
> +    };
> +...
> -- 
> 2.37.2
> 

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

* Re: [PATCH v1 2/2] media: lm3560: convent to OF
  2023-03-08  9:52 ` [PATCH v1 2/2] media: lm3560: convent to OF Svyatoslav Ryhel
@ 2023-03-14 11:00   ` Sakari Ailus
  0 siblings, 0 replies; 6+ messages in thread
From: Sakari Ailus @ 2023-03-14 11:00 UTC (permalink / raw)
  To: Svyatoslav Ryhel
  Cc: Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
	Hans Verkuil, Luca Ceresoli, Jean Delvare, Sebastian Reichel,
	Daniel Jeong, Ldd-Mlp, linux-media, devicetree, linux-kernel

Hi Svyatoslav,

Thanks for the patch.

On Wed, Mar 08, 2023 at 11:52:09AM +0200, Svyatoslav Ryhel wrote:
> If no pdata is available, try to read from device tree.

I think platform data support could be even dropped these days. But it
should probably be a separate patch. I think either before or after this
one would be fine.

> 
> Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
> ---
>  drivers/media/i2c/lm3560.c | 128 +++++++++++++++++++++++++++----------
>  1 file changed, 93 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/media/i2c/lm3560.c b/drivers/media/i2c/lm3560.c
> index 5ef613604be7..5541051616b7 100644
> --- a/drivers/media/i2c/lm3560.c
> +++ b/drivers/media/i2c/lm3560.c
> @@ -11,6 +11,7 @@
>  
>  #include <linux/delay.h>
>  #include <linux/module.h>
> +#include <linux/gpio.h>
>  #include <linux/i2c.h>
>  #include <linux/slab.h>
>  #include <linux/mutex.h>
> @@ -22,16 +23,16 @@
>  
>  /* registers definitions */
>  #define REG_ENABLE		0x10
> -#define REG_TORCH_BR	0xa0
> -#define REG_FLASH_BR	0xb0
> -#define REG_FLASH_TOUT	0xc0
> +#define REG_TORCH_BR		0xa0
> +#define REG_FLASH_BR		0xb0
> +#define REG_FLASH_TOUT		0xc0
>  #define REG_FLAG		0xd0
>  #define REG_CONFIG1		0xe0
>  
>  /* fault mask */
> -#define FAULT_TIMEOUT	(1<<0)
> -#define FAULT_OVERTEMP	(1<<1)
> -#define FAULT_SHORT_CIRCUIT	(1<<2)
> +#define FAULT_TIMEOUT		BIT(0)
> +#define FAULT_OVERTEMP		BIT(1)
> +#define FAULT_SHORT_CIRCUIT	BIT(2)
>  
>  enum led_enable {
>  	MODE_SHDN = 0x0,
> @@ -54,6 +55,7 @@ struct lm3560_flash {
>  	struct device *dev;
>  	struct lm3560_platform_data *pdata;
>  	struct regmap *regmap;
> +	struct gpio_desc *hwen_gpio;
>  	struct mutex lock;
>  
>  	enum v4l2_flash_led_mode led_mode;
> @@ -356,12 +358,19 @@ static int lm3560_subdev_init(struct lm3560_flash *flash,
>  	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));
> +
>  	rval = lm3560_init_controls(flash, led_no);
> -	if (rval)
> +	if (rval) {
> +		dev_err(flash->dev, "failed to init controls: %d\n", rval);
>  		goto err_out;
> +	}
> +
>  	rval = media_entity_pads_init(&flash->subdev_led[led_no].entity, 0, NULL);
> -	if (rval < 0)
> +	if (rval < 0) {
> +		dev_err(flash->dev, "failed to init media entity pads: %d\n", rval);
>  		goto err_out;
> +	}
> +
>  	flash->subdev_led[led_no].entity.function = MEDIA_ENT_F_FLASH;
>  
>  	return rval;
> @@ -391,6 +400,49 @@ static int lm3560_init_device(struct lm3560_flash *flash)
>  	return rval;
>  }
>  
> +static int lm3560_of_probe(struct lm3560_flash *flash)
> +{
> +	struct lm3560_platform_data *pdata;
> +	struct fwnode_handle *node;
> +	int ret, reg;
> +
> +	pdata = devm_kzalloc(flash->dev, sizeof(*pdata), GFP_KERNEL);
> +	if (!pdata)
> +		return -ENODEV;
> +
> +	ret = device_property_read_u32(flash->dev,
> +				       "ti,peak-current", &pdata->peak);
> +	if (ret)
> +		pdata->peak = LM3560_PEAK_3600mA;
> +
> +	ret = device_property_read_u32(flash->dev,
> +				       "ti,max-flash-timeout",
> +				       &pdata->max_flash_timeout);
> +	if (ret)
> +		pdata->max_flash_timeout = LM3560_FLASH_TOUT_MAX;
> +
> +	device_for_each_child_node(flash->dev, node) {
> +		fwnode_property_read_u32(node, "reg", &reg);
> +
> +		if (reg == LM3560_LED0 || reg == LM3560_LED1) {
> +			ret = device_property_read_u32(flash->dev,
> +						       "ti,max-flash-current",
> +						       &pdata->max_flash_brt[reg]);
> +			if (ret)
> +				pdata->max_flash_brt[reg] = LM3560_FLASH_TOUT_MAX;
> +
> +			ret = device_property_read_u32(flash->dev,
> +						       "ti,max-torch-current",
> +						       &pdata->max_torch_brt[reg]);
> +			if (ret)
> +				pdata->max_torch_brt[reg] = LM3560_TORCH_BRT_MAX;
> +		}
> +	}
> +	flash->pdata = pdata;
> +
> +	return 0;
> +}
> +
>  static int lm3560_probe(struct i2c_client *client)
>  {
>  	struct lm3560_flash *flash;
> @@ -398,44 +450,41 @@ static int lm3560_probe(struct i2c_client *client)
>  	int rval;
>  
>  	flash = devm_kzalloc(&client->dev, sizeof(*flash), GFP_KERNEL);
> -	if (flash == NULL)
> +	if (!flash)
>  		return -ENOMEM;
>  
>  	flash->regmap = devm_regmap_init_i2c(client, &lm3560_regmap);
> -	if (IS_ERR(flash->regmap)) {
> -		rval = PTR_ERR(flash->regmap);
> -		return rval;
> -	}
> +	if (IS_ERR(flash->regmap))
> +		return dev_err_probe(&client->dev, PTR_ERR(flash->regmap),
> +				     "failed to init regmap\n");
>  
> -	/* 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);
>  
> +	/* if there is no platform data, try to read from device tree */
> +	if (!pdata)
> +		lm3560_of_probe(flash);
> +
> +	flash->hwen_gpio = devm_gpiod_get_optional(flash->dev, "enable",
> +						   GPIOD_OUT_HIGH);
> +	if (IS_ERR(flash->hwen_gpio))
> +		return dev_err_probe(&client->dev, PTR_ERR(flash->hwen_gpio),
> +				     "failed to get hwen gpio\n");
> +
>  	rval = lm3560_subdev_init(flash, LM3560_LED0, "lm3560-led0");
>  	if (rval < 0)
> -		return rval;
> +		return dev_err_probe(&client->dev, rval,
> +				     "failed to init led0 subdev\n");
>  
>  	rval = lm3560_subdev_init(flash, LM3560_LED1, "lm3560-led1");
>  	if (rval < 0)
> -		return rval;
> +		return dev_err_probe(&client->dev, rval,
> +				     "failed to init led1 subdev\n");
>  
>  	rval = lm3560_init_device(flash);
>  	if (rval < 0)
> -		return rval;
> +		return dev_err_probe(&client->dev, rval,
> +				     "failed to init device\n");
>  
>  	i2c_set_clientdata(client, flash);
>  
> @@ -452,21 +501,30 @@ static void lm3560_remove(struct i2c_client *client)
>  		v4l2_ctrl_handler_free(&flash->ctrls_led[i]);
>  		media_entity_cleanup(&flash->subdev_led[i].entity);
>  	}
> +
> +	gpiod_set_value_cansleep(flash->hwen_gpio, 0);
>  }
>  
> +static const struct of_device_id lm3560_match[] = {
> +	{ .compatible = "ti,lm3559" },
> +	{ .compatible = "ti,lm3560" },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, lm3560_match);
> +
>  static const struct i2c_device_id lm3560_id_table[] = {
>  	{LM3559_NAME, 0},
>  	{LM3560_NAME, 0},
>  	{}
>  };
> -
>  MODULE_DEVICE_TABLE(i2c, lm3560_id_table);
>  
>  static struct i2c_driver lm3560_i2c_driver = {
>  	.driver = {
> -		   .name = LM3560_NAME,
> -		   .pm = NULL,
> -		   },
> +		.name = LM3560_NAME,
> +		.pm = NULL,
> +		.of_match_table = lm3560_match,
> +	},
>  	.probe_new = lm3560_probe,
>  	.remove = lm3560_remove,
>  	.id_table = lm3560_id_table,

-- 
Kind regards,

Sakari Ailus

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

end of thread, other threads:[~2023-03-14 11:01 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-08  9:52 [PATCH v1 0/2] Add OF support for LM3560 Svyatoslav Ryhel
2023-03-08  9:52 ` [PATCH v1 1/2] dt-bindings: media: i2c: add lm3560 binding Svyatoslav Ryhel
2023-03-08 14:06   ` Rob Herring
2023-03-08 18:21   ` Rob Herring
2023-03-08  9:52 ` [PATCH v1 2/2] media: lm3560: convent to OF Svyatoslav Ryhel
2023-03-14 11:00   ` Sakari Ailus

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).