* [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
* 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
* [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", ®); + + 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 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", ®); > + > + 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 an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.