On Wed May 6 09:48:47 2026 +0300, Svyatoslav Ryhel wrote:
> The LM3559 is very similar to the LM3560, but it operates at much lower
> currents. This may result in incorrect current selection if LM3560 ranges
> are applied to the LM3559. Implement driver data matching to use
> device-specific current configurations.
> 
> Since the driver no longer supports platform data and device configuration
> is performed more granularly, move the remaining enums from the header
> into the driver file and remove the header.
> 
> Signed-off-by: Svyatoslav Ryhel <[email protected]>
> Signed-off-by: Sakari Ailus <[email protected]>

Patch committed.

Thanks,
Sakari Ailus

 drivers/media/i2c/lm3560.c | 120 +++++++++++++++++++++++++++++++++++++--------
 include/media/i2c/lm3560.h |  69 --------------------------
 2 files changed, 100 insertions(+), 89 deletions(-)

---

diff --git a/drivers/media/i2c/lm3560.c b/drivers/media/i2c/lm3560.c
index 49030bc0f441..46d316a26e50 100644
--- a/drivers/media/i2c/lm3560.c
+++ b/drivers/media/i2c/lm3560.c
@@ -22,9 +22,9 @@
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/videodev2.h>
-#include <media/i2c/lm3560.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
 
 /* registers definitions */
 #define REG_ENABLE             0x10
@@ -39,12 +39,44 @@
 #define FAULT_OVERTEMP (1<<1)
 #define FAULT_SHORT_CIRCUIT    (1<<2)
 
+#define LM3560_FLASH_TOUT_MIN                  32
+#define LM3560_FLASH_TOUT_STEP                 32
+#define LM3560_FLASH_TOUT_MAX                  1024
+#define LM3560_FLASH_TOUT_ms_TO_REG(a)         \
+       ((a) < LM3560_FLASH_TOUT_MIN ? 0 :      \
+        (((a) - LM3560_FLASH_TOUT_MIN) / LM3560_FLASH_TOUT_STEP))
+#define LM3560_FLASH_TOUT_REG_TO_ms(a)         \
+       ((a) * LM3560_FLASH_TOUT_STEP + LM3560_FLASH_TOUT_MIN)
+
+enum lm3560_led_id {
+       LM3560_LED0 = 0,
+       LM3560_LED1,
+       LM3560_LED_MAX
+};
+
+enum lm3560_peak_current {
+       LM3560_PEAK_1600mA = 0x00,
+       LM3560_PEAK_2300mA = 0x20,
+       LM3560_PEAK_3000mA = 0x40,
+       LM3560_PEAK_3600mA = 0x60
+};
+
 enum led_enable {
        MODE_SHDN = 0x0,
        MODE_TORCH = 0x2,
        MODE_FLASH = 0x3,
 };
 
+struct lm3560_flash_config {
+       u32 flash_brt_min_ua;
+       u32 flash_brt_max_ua;
+       u32 flash_brt_step_ua;
+
+       u32 torch_brt_min_ua;
+       u32 torch_brt_max_ua;
+       u32 torch_brt_step_ua;
+};
+
 /**
  * struct lm3560_flash
  *
@@ -61,6 +93,7 @@ enum led_enable {
  * @max_flash_timeout: flash timeout
  * @max_flash_brt: flash mode led brightness
  * @max_torch_brt: torch mode led brightness
+ * @config: device specific current configuration
  */
 struct lm3560_flash {
        struct device *dev;
@@ -81,6 +114,8 @@ struct lm3560_flash {
 
        u32 max_flash_brt[LM3560_LED_MAX];
        u32 max_torch_brt[LM3560_LED_MAX];
+
+       const struct lm3560_flash_config *config;
 };
 
 #define to_lm3560_flash(_ctrl, _no)    \
@@ -136,15 +171,20 @@ static int lm3560_enable_ctrl(struct lm3560_flash *flash,
 static int lm3560_torch_brt_ctrl(struct lm3560_flash *flash,
                                 enum lm3560_led_id led_no, unsigned int brt)
 {
+       const struct lm3560_flash_config *config = flash->config;
        int rval;
-       u8 br_bits;
+       u32 br_bits;
 
-       if (brt < LM3560_TORCH_BRT_MIN)
+       if (brt < config->torch_brt_min_ua)
                return lm3560_enable_ctrl(flash, led_no, false);
        else
                rval = lm3560_enable_ctrl(flash, led_no, true);
 
-       br_bits = LM3560_TORCH_BRT_uA_TO_REG(brt);
+       br_bits = clamp(brt, config->torch_brt_min_ua,
+                       config->torch_brt_max_ua);
+       br_bits = (br_bits - config->torch_brt_min_ua) /
+                 config->torch_brt_step_ua;
+
        if (led_no == LM3560_LED0)
                rval = regmap_update_bits(flash->regmap,
                                          REG_TORCH_BR, 0x07, br_bits);
@@ -159,15 +199,20 @@ static int lm3560_torch_brt_ctrl(struct lm3560_flash 
*flash,
 static int lm3560_flash_brt_ctrl(struct lm3560_flash *flash,
                                 enum lm3560_led_id led_no, unsigned int brt)
 {
+       const struct lm3560_flash_config *config = flash->config;
        int rval;
-       u8 br_bits;
+       u32 br_bits;
 
-       if (brt < LM3560_FLASH_BRT_MIN)
+       if (brt < config->flash_brt_min_ua)
                return lm3560_enable_ctrl(flash, led_no, false);
        else
                rval = lm3560_enable_ctrl(flash, led_no, true);
 
-       br_bits = LM3560_FLASH_BRT_uA_TO_REG(brt);
+       br_bits = clamp(brt, config->flash_brt_min_ua,
+                       config->flash_brt_max_ua);
+       br_bits = (br_bits - config->flash_brt_min_ua) /
+                 config->flash_brt_step_ua;
+
        if (led_no == LM3560_LED0)
                rval = regmap_update_bits(flash->regmap,
                                          REG_FLASH_BR, 0x0f, br_bits);
@@ -307,6 +352,7 @@ static int lm3560_init_controls(struct lm3560_flash *flash,
        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];
+       const struct lm3560_flash_config *config = flash->config;
 
        v4l2_ctrl_handler_init(hdl, 8);
 
@@ -335,13 +381,13 @@ static int lm3560_init_controls(struct lm3560_flash 
*flash,
 
        /* flash brt */
        v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_INTENSITY,
-                         LM3560_FLASH_BRT_MIN, max_flash_brt,
-                         LM3560_FLASH_BRT_STEP, max_flash_brt);
+                         config->flash_brt_min_ua, max_flash_brt,
+                         config->flash_brt_step_ua, max_flash_brt);
 
        /* torch brt */
        v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_TORCH_INTENSITY,
-                         LM3560_TORCH_BRT_MIN, max_torch_brt,
-                         LM3560_TORCH_BRT_STEP, max_torch_brt);
+                         config->torch_brt_min_ua, max_torch_brt,
+                         config->torch_brt_step_ua, max_torch_brt);
 
        /* fault */
        fault = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_FAULT, 0,
@@ -481,6 +527,10 @@ static int lm3560_probe(struct i2c_client *client)
        if (flash == NULL)
                return -ENOMEM;
 
+       flash->config = device_get_match_data(&client->dev);
+       if (!flash->config)
+               return -ENODEV;
+
        flash->regmap = devm_regmap_init_i2c(client, &lm3560_regmap);
        if (IS_ERR(flash->regmap)) {
                rval = PTR_ERR(flash->regmap);
@@ -507,16 +557,26 @@ static int lm3560_probe(struct i2c_client *client)
        rval = device_property_read_u32(flash->dev,
                                        "ti,peak-current-microamp", &peak_ua);
        if (!rval) {
+               /*
+                * LM3559 has lower peak current limit, but
+                * bit configuration matches LM3560.
+                * Correct current restrictions are enforced
+                * by the LM3560 schema.
+                */
                switch (peak_ua) {
+               case 1400000:
                case 1600000:
                        flash->peak = LM3560_PEAK_1600mA;
                        break;
+               case 2100000:
                case 2300000:
                        flash->peak = LM3560_PEAK_2300mA;
                        break;
+               case 2700000:
                case 3000000:
                        flash->peak = LM3560_PEAK_3000mA;
                        break;
+               case 3200000:
                case 3600000:
                        flash->peak = LM3560_PEAK_3600mA;
                        break;
@@ -545,6 +605,7 @@ static int lm3560_probe(struct i2c_client *client)
        pm_runtime_enable(flash->dev);
 
        device_for_each_child_node_scoped(flash->dev, node) {
+               const struct lm3560_flash_config *config = flash->config;
                u32 reg;
 
                rval = fwnode_property_read_u32(node, "reg", &reg);
@@ -553,11 +614,11 @@ static int lm3560_probe(struct i2c_client *client)
                        continue;
 
                if (reg == LM3560_LED0 || reg == LM3560_LED1) {
-                       flash->max_flash_brt[reg] = LM3560_FLASH_BRT_MIN;
+                       flash->max_flash_brt[reg] = config->flash_brt_min_ua;
                        fwnode_property_read_u32(node, "flash-max-microamp",
                                                 &flash->max_flash_brt[reg]);
 
-                       flash->max_torch_brt[reg] = LM3560_TORCH_BRT_MIN;
+                       flash->max_torch_brt[reg] = config->torch_brt_min_ua;
                        fwnode_property_read_u32(node, "led-max-microamp",
                                                 &flash->max_torch_brt[reg]);
 
@@ -615,24 +676,43 @@ static const struct dev_pm_ops lm3560_pm_ops = {
        SET_RUNTIME_PM_OPS(lm3560_power_off, lm3560_power_on, NULL)
 };
 
+static const struct lm3560_flash_config lm3559_config = {
+       .flash_brt_min_ua = 56250,
+       .flash_brt_max_ua = 900000,
+       .flash_brt_step_ua = 56250,
+
+       .torch_brt_min_ua = 28125,
+       .torch_brt_max_ua = 225000,
+       .torch_brt_step_ua = 28125,
+};
+
+static const struct lm3560_flash_config lm3560_config = {
+       .flash_brt_min_ua = 62500,
+       .flash_brt_max_ua = 1000000,
+       .flash_brt_step_ua = 62500,
+
+       .torch_brt_min_ua = 31250,
+       .torch_brt_max_ua = 250000,
+       .torch_brt_step_ua = 31250,
+};
+
 static const struct of_device_id lm3560_of_match[] = {
-       { .compatible = "ti,lm3559" },
-       { .compatible = "ti,lm3560" },
+       { .compatible = "ti,lm3559", .data = &lm3559_config },
+       { .compatible = "ti,lm3560", .data = &lm3560_config },
        { }
 };
 MODULE_DEVICE_TABLE(of, lm3560_of_match);
 
 static const struct i2c_device_id lm3560_id_table[] = {
-       { LM3559_NAME },
-       { LM3560_NAME },
-       {}
+       { "lm3559", (kernel_ulong_t)&lm3559_config },
+       { "lm3560", (kernel_ulong_t)&lm3560_config },
+       { }
 };
-
 MODULE_DEVICE_TABLE(i2c, lm3560_id_table);
 
 static struct i2c_driver lm3560_i2c_driver = {
        .driver = {
-                  .name = LM3560_NAME,
+                  .name = "lm3560",
                   .pm = pm_ptr(&lm3560_pm_ops),
                   .of_match_table = lm3560_of_match,
                   },
diff --git a/include/media/i2c/lm3560.h b/include/media/i2c/lm3560.h
deleted file mode 100644
index b56c1ff8fd49..000000000000
--- a/include/media/i2c/lm3560.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * include/media/i2c/lm3560.h
- *
- * Copyright (C) 2013 Texas Instruments
- *
- * Contact: Daniel Jeong <[email protected]>
- *                     Ldd-Mlp <[email protected]>
- */
-
-#ifndef __LM3560_H__
-#define __LM3560_H__
-
-#include <media/v4l2-subdev.h>
-
-#define LM3559_NAME    "lm3559"
-#define LM3560_NAME    "lm3560"
-#define LM3560_I2C_ADDR        (0x53)
-
-/*  FLASH Brightness
- *     min 62500uA, step 62500uA, max 1000000uA
- */
-#define LM3560_FLASH_BRT_MIN 62500
-#define LM3560_FLASH_BRT_STEP 62500
-#define LM3560_FLASH_BRT_MAX 1000000
-#define LM3560_FLASH_BRT_uA_TO_REG(a)  \
-       ((a) < LM3560_FLASH_BRT_MIN ? 0 :       \
-        (((a) - LM3560_FLASH_BRT_MIN) / LM3560_FLASH_BRT_STEP))
-#define LM3560_FLASH_BRT_REG_TO_uA(a)          \
-       ((a) * LM3560_FLASH_BRT_STEP + LM3560_FLASH_BRT_MIN)
-
-/*  FLASH TIMEOUT DURATION
- *     min 32ms, step 32ms, max 1024ms
- */
-#define LM3560_FLASH_TOUT_MIN 32
-#define LM3560_FLASH_TOUT_STEP 32
-#define LM3560_FLASH_TOUT_MAX 1024
-#define LM3560_FLASH_TOUT_ms_TO_REG(a) \
-       ((a) < LM3560_FLASH_TOUT_MIN ? 0 :      \
-        (((a) - LM3560_FLASH_TOUT_MIN) / LM3560_FLASH_TOUT_STEP))
-#define LM3560_FLASH_TOUT_REG_TO_ms(a)         \
-       ((a) * LM3560_FLASH_TOUT_STEP + LM3560_FLASH_TOUT_MIN)
-
-/*  TORCH BRT
- *     min 31250uA, step 31250uA, max 250000uA
- */
-#define LM3560_TORCH_BRT_MIN 31250
-#define LM3560_TORCH_BRT_STEP 31250
-#define LM3560_TORCH_BRT_MAX 250000
-#define LM3560_TORCH_BRT_uA_TO_REG(a)  \
-       ((a) < LM3560_TORCH_BRT_MIN ? 0 :       \
-        (((a) - LM3560_TORCH_BRT_MIN) / LM3560_TORCH_BRT_STEP))
-#define LM3560_TORCH_BRT_REG_TO_uA(a)          \
-       ((a) * LM3560_TORCH_BRT_STEP + LM3560_TORCH_BRT_MIN)
-
-enum lm3560_led_id {
-       LM3560_LED0 = 0,
-       LM3560_LED1,
-       LM3560_LED_MAX
-};
-
-enum lm3560_peak_current {
-       LM3560_PEAK_1600mA = 0x00,
-       LM3560_PEAK_2300mA = 0x20,
-       LM3560_PEAK_3000mA = 0x40,
-       LM3560_PEAK_3600mA = 0x60
-};
-
-#endif /* __LM3560_H__ */
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to