Add Control Bank to HVLED/LVLED muxing support based on the led-sources
defined in the device tree.

Signed-off-by: Svyatoslav Ryhel <[email protected]>
---
 drivers/leds/leds-lm3533.c          | 55 ++++++++++++++++++++++++++++-
 drivers/video/backlight/lm3533_bl.c | 40 ++++++++++++++++++++-
 2 files changed, 93 insertions(+), 2 deletions(-)

diff --git a/drivers/leds/leds-lm3533.c b/drivers/leds/leds-lm3533.c
index f2502daf450d..6db1c1fd2e20 100644
--- a/drivers/leds/leds-lm3533.c
+++ b/drivers/leds/leds-lm3533.c
@@ -7,6 +7,7 @@
  * Author: Johan Hovold <[email protected]>
  */
 
+#include <linux/bits.h>
 #include <linux/module.h>
 #include <linux/leds.h>
 #include <linux/mfd/core.h>
@@ -27,6 +28,12 @@
 #define LM3533_ALS_CHANNEL_LV_MIN      1
 #define LM3533_ALS_CHANNEL_LV_MAX      2
 
+#define LM3533_REG_OUTPUT_CONF1                        0x10
+#define   OUTPUT_CONF1_MASK                    GENMASK(7, 2)
+#define   OUTPUT_CONF1_SHIFT                   2
+#define LM3533_REG_OUTPUT_CONF2                        0x11
+#define   OUTPUT_CONF2_MASK                    GENMASK(3, 0)
+#define   OUTPUT_CONF2_SHIFT                   6
 #define LM3533_REG_CTRLBANK_BCONF_BASE         0x1b
 #define LM3533_REG_PATTERN_ENABLE              0x28
 #define LM3533_REG_PATTERN_LOW_TIME_BASE       0x71
@@ -54,6 +61,9 @@ struct lm3533_led {
 
        u32 max_current;
        u32 pwm;
+
+       int num_leds;
+       u32 leds[LM3533_LVCTRLBANK_MAX];
 };
 
 
@@ -641,7 +651,33 @@ static const struct attribute_group 
*lm3533_led_attribute_groups[] = {
 
 static int lm3533_led_setup(struct lm3533_led *led)
 {
-       int ret;
+       u32 output_cfg_shift = 0;
+       u32 output_cfg_val = 0;
+       int ret, i;
+
+       if (led->num_leds) {
+               for (i = 0; i < led->num_leds; i++) {
+                       if (led->leds[i] >= LM3533_LVCTRLBANK_MAX)
+                               continue;
+
+                       output_cfg_shift = led->leds[i] * 2;
+                       output_cfg_val |= led->id << output_cfg_shift;
+               }
+
+               /* LVLED1, LVLED2 and LVLED3 */
+               ret = regmap_update_bits(led->lm3533->regmap, 
LM3533_REG_OUTPUT_CONF1,
+                                        OUTPUT_CONF1_MASK,
+                                        output_cfg_val << OUTPUT_CONF1_SHIFT);
+               if (ret)
+                       return ret;
+
+               /* LVLED4 and LVLED5 */
+               ret = regmap_update_bits(led->lm3533->regmap, 
LM3533_REG_OUTPUT_CONF2,
+                                        OUTPUT_CONF2_MASK,
+                                        output_cfg_val >> OUTPUT_CONF2_SHIFT);
+               if (ret)
+                       return ret;
+       }
 
        ret = lm3533_ctrlbank_set_max_current(&led->cb, led->max_current);
        if (ret)
@@ -716,6 +752,23 @@ static int lm3533_led_probe(struct platform_device *pdev)
        led->pwm = 0;
        device_property_read_u32(&pdev->dev, "ti,pwm-config-mask", &led->pwm);
 
+       led->num_leds = device_property_count_u32(&pdev->dev, "led-sources");
+
+       /*
+        * If led-sources property is not set then either this Control Bank uses
+        * its default LVLED or is not linked to any LVLED at all.
+        */
+       if (led->num_leds > 0 && led->num_leds <= LM3533_LVCTRLBANK_MAX) {
+               ret = device_property_read_u32_array(&pdev->dev, "led-sources",
+                                                    led->leds, led->num_leds);
+               if (ret) {
+                       dev_err(&pdev->dev, "failed to get led-sources\n");
+                       goto err_deregister;
+               }
+       } else {
+               led->num_leds = 0;
+       }
+
        ret = lm3533_led_setup(led);
        if (ret)
                goto err_deregister;
diff --git a/drivers/video/backlight/lm3533_bl.c 
b/drivers/video/backlight/lm3533_bl.c
index 945625c54fc4..2119433bae45 100644
--- a/drivers/video/backlight/lm3533_bl.c
+++ b/drivers/video/backlight/lm3533_bl.c
@@ -7,6 +7,7 @@
  * Author: Johan Hovold <[email protected]>
  */
 
+#include <linux/bits.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/mod_devicetable.h>
@@ -22,6 +23,8 @@
 #define LM3533_HVCTRLBANK_COUNT                2
 #define LM3533_BL_MAX_BRIGHTNESS       255
 
+#define LM3533_REG_OUTPUT_CONF1                0x10
+#define   OUTPUT_CONF1_MASK            GENMASK(1, 0)
 #define LM3533_REG_CTRLBANK_AB_BCONF   0x1a
 #define   CTRLBANK_AB_BCONF_MODE(n)    BIT(2 * (n) + 1)
 
@@ -35,6 +38,9 @@ struct lm3533_bl {
        u32 max_current;
        u32 pwm;
        bool linear;
+
+       int num_leds;
+       u32 led_strings[LM3533_HVCTRLBANK_COUNT];
 };
 
 
@@ -253,7 +259,8 @@ static struct attribute_group lm3533_bl_attribute_group = {
 static int lm3533_bl_setup(struct lm3533_bl *bl)
 {
        int id = lm3533_bl_get_ctrlbank_id(bl);
-       int ret;
+       u32 output_cfg_val = 0;
+       int ret, i;
 
        ret = regmap_update_bits(bl->lm3533->regmap, 
LM3533_REG_CTRLBANK_AB_BCONF,
                                 CTRLBANK_AB_BCONF_MODE(id),
@@ -261,6 +268,20 @@ static int lm3533_bl_setup(struct lm3533_bl *bl)
        if (ret)
                return ret;
 
+       if (bl->num_leds) {
+               for (i = 0; i < bl->num_leds; i++) {
+                       if (bl->led_strings[i] >= LM3533_HVCTRLBANK_COUNT)
+                               continue;
+
+                       output_cfg_val |= id << bl->led_strings[i];
+               }
+
+               ret = regmap_update_bits(bl->lm3533->regmap, 
LM3533_REG_OUTPUT_CONF1,
+                                        OUTPUT_CONF1_MASK, output_cfg_val);
+               if (ret)
+                       return ret;
+       }
+
        ret = lm3533_ctrlbank_set_max_current(&bl->cb, bl->max_current);
        if (ret)
                return ret;
@@ -336,6 +357,23 @@ static int lm3533_bl_probe(struct platform_device *pdev)
        bl->pwm = 0;
        device_property_read_u32(&pdev->dev, "ti,pwm-config-mask", &bl->pwm);
 
+       bl->num_leds = device_property_count_u32(&pdev->dev, "led-sources");
+
+       /*
+        * If led-sources property is not set then either this Control Bank uses
+        * its default HVLED or is not linked to any HVLED at all.
+        */
+       if (bl->num_leds > 0 && bl->num_leds <= LM3533_HVCTRLBANK_COUNT) {
+               ret = device_property_read_u32_array(&pdev->dev, "led-sources",
+                                                    bl->led_strings,
+                                                    bl->num_leds);
+               if (ret)
+                       return dev_err_probe(&pdev->dev, ret,
+                                            "failed to get led-sources\n");
+       } else {
+               bl->num_leds = 0;
+       }
+
        ret = lm3533_bl_setup(bl);
        if (ret)
                return ret;
-- 
2.51.0

Reply via email to