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          | 58 ++++++++++++++++++++++++++++-
 drivers/video/backlight/lm3533_bl.c | 43 ++++++++++++++++++++-
 2 files changed, 99 insertions(+), 2 deletions(-)

diff --git a/drivers/leds/leds-lm3533.c b/drivers/leds/leds-lm3533.c
index a661aedcdc60..fe3e01b265e1 100644
--- a/drivers/leds/leds-lm3533.c
+++ b/drivers/leds/leds-lm3533.c
@@ -27,6 +27,11 @@
 #define LM3533_ALS_CHANNEL_LV_MIN      1
 #define LM3533_ALS_CHANNEL_LV_MAX      2
 
+#define LM3533_REG_OUTPUT_CONF1                        0x10
+#define   OUTPUT_CONF1_SHIFT                   2
+#define   OUTPUT_LVLED_MASK                    0x3
+#define LM3533_REG_OUTPUT_CONF2                        0x11
+#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
@@ -55,6 +60,9 @@ struct lm3533_led {
        u32 max_current;
        u32 pwm;
 
+       int num_leds;
+       u32 leds[LM3533_LVCTRLBANK_MAX];
+
        bool have_als;
 };
 
@@ -623,7 +631,35 @@ 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;
+       u32 output_cfg_mask = 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;
+                       output_cfg_mask |= OUTPUT_LVLED_MASK << 
output_cfg_shift;
+               }
+
+               /* LVLED1, LVLED2 and LVLED3 */
+               ret = regmap_update_bits(led->regmap, LM3533_REG_OUTPUT_CONF1,
+                                        output_cfg_mask << OUTPUT_CONF1_SHIFT,
+                                        output_cfg_val << OUTPUT_CONF1_SHIFT);
+               if (ret)
+                       return ret;
+
+               /* LVLED4 and LVLED5 */
+               ret = regmap_update_bits(led->regmap, LM3533_REG_OUTPUT_CONF2,
+                                        output_cfg_mask >> OUTPUT_CONF2_SHIFT,
+                                        output_cfg_val >> OUTPUT_CONF2_SHIFT);
+               if (ret)
+                       return ret;
+       }
 
        ret = lm3533_ctrlbank_set_max_current(&led->cb, led->max_current);
        if (ret)
@@ -700,6 +736,26 @@ 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->num_leds > LM3533_LVCTRLBANK_MAX) {
+               dev_err(&pdev->dev, "num of LED sources exceeds max %d: %d\n",
+                       LM3533_LVCTRLBANK_MAX, led->num_leds);
+               goto err_deregister;
+       }
+
+       /*
+        * 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) {
+               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;
+               }
+       }
+
        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 2aa4b86042ff..ed358fb3c759 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,7 @@
 #define LM3533_HVCTRLBANK_COUNT                2
 #define LM3533_BL_MAX_BRIGHTNESS       255
 
+#define LM3533_REG_OUTPUT_CONF1                0x10
 #define LM3533_REG_CTRLBANK_AB_BCONF   0x1a
 #define   CTRLBANK_AB_BCONF_ALS(n)     BIT(2 * (n))
 #define   CTRLBANK_AB_BCONF_MODE(n)    BIT(2 * (n) + 1)
@@ -36,6 +38,9 @@ struct lm3533_bl {
        u32 max_current;
        u32 pwm;
 
+       int num_leds;
+       u32 led_strings[LM3533_HVCTRLBANK_COUNT];
+
        bool have_als;
        bool linear;
 };
@@ -232,13 +237,30 @@ static struct attribute_group lm3533_bl_attribute_group = 
{
 static int lm3533_bl_setup(struct lm3533_bl *bl)
 {
        int ctrlbank = lm3533_bl_get_ctrlbank_id(bl);
-       int ret;
+       u32 output_cfg_val = 0;
+       u32 output_cfg_mask = 0;
+       int ret, i;
 
        ret = regmap_assign_bits(bl->regmap, LM3533_REG_CTRLBANK_AB_BCONF,
                                 CTRLBANK_AB_BCONF_MODE(ctrlbank), bl->linear);
        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 |= ctrlbank << bl->led_strings[i];
+                       output_cfg_mask |= BIT(bl->led_strings[i]);
+               }
+
+               ret = regmap_update_bits(bl->regmap, LM3533_REG_OUTPUT_CONF1,
+                                        output_cfg_mask, output_cfg_val);
+               if (ret)
+                       return ret;
+       }
+
        ret = lm3533_ctrlbank_set_max_current(&bl->cb, bl->max_current);
        if (ret)
                return ret;
@@ -316,6 +338,25 @@ static int lm3533_bl_probe(struct platform_device *pdev)
 
        device_property_read_u32(&pdev->dev, "ti,pwm-config-mask", &bl->pwm);
 
+       bl->num_leds = device_property_count_u32(&pdev->dev, "led-sources");
+       if (bl->num_leds > LM3533_HVCTRLBANK_COUNT)
+               return dev_err_probe(&pdev->dev, bl->num_leds,
+                                    "num of LED sources exceeds max %d\n",
+                                    LM3533_HVCTRLBANK_COUNT);
+
+       /*
+        * 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) {
+               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");
+       }
+
        ret = lm3533_bl_setup(bl);
        if (ret)
                return ret;
-- 
2.53.0

Reply via email to