[PATCH V5 1/2] backlight: qcom-wled: Fix FSC update issue for WLED5

2021-03-18 Thread Kiran Gunda
Currently, for WLED5, the FSC (Full scale current) setting is not
updated properly due to driver toggling the wrong register after
an FSC update.

On WLED5 we should only toggle the MOD_SYNC bit after a brightness
update. For an FSC update we need to toggle the SYNC bits instead.

Fix it by adopting the common wled3_sync_toggle() for WLED5 and
introducing new code to the brightness update path to compensate.

Signed-off-by: Kiran Gunda 
Reviewed-by: Daniel Thompson 
---
 drivers/video/backlight/qcom-wled.c | 25 +++--
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index fc8b443..e9fbe24 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -348,7 +348,7 @@ static int wled3_sync_toggle(struct wled *wled)
return rc;
 }
 
-static int wled5_sync_toggle(struct wled *wled)
+static int wled5_mod_sync_toggle(struct wled *wled)
 {
int rc;
u8 val;
@@ -445,10 +445,23 @@ static int wled_update_status(struct backlight_device *bl)
goto unlock_mutex;
}
 
-   rc = wled->wled_sync_toggle(wled);
-   if (rc < 0) {
-   dev_err(wled->dev, "wled sync failed rc:%d\n", rc);
-   goto unlock_mutex;
+   if (wled->version < 5) {
+   rc = wled->wled_sync_toggle(wled);
+   if (rc < 0) {
+   dev_err(wled->dev, "wled sync failed rc:%d\n", 
rc);
+   goto unlock_mutex;
+   }
+   } else {
+   /*
+* For WLED5 toggling the MOD_SYNC_BIT updates the
+* brightness
+*/
+   rc = wled5_mod_sync_toggle(wled);
+   if (rc < 0) {
+   dev_err(wled->dev, "wled mod sync failed 
rc:%d\n",
+   rc);
+   goto unlock_mutex;
+   }
}
}
 
@@ -1459,7 +1472,7 @@ static int wled_configure(struct wled *wled)
size = ARRAY_SIZE(wled5_opts);
*cfg = wled5_config_defaults;
wled->wled_set_brightness = wled5_set_brightness;
-   wled->wled_sync_toggle = wled5_sync_toggle;
+   wled->wled_sync_toggle = wled3_sync_toggle;
wled->wled_cabc_config = wled5_cabc_config;
wled->wled_ovp_delay = wled5_ovp_delay;
wled->wled_auto_detection_required =
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH V5 0/2] Fix WLED FSC Sync and brightness Sync settings

2021-03-18 Thread Kiran Gunda
This patch series has the following two WLED fixes
 1. As per the current implementation, for WLED5, after
the FSC (Full Scale Current) update the driver is incorrectly
toggling the MOD_SYNC register instead of toggling the SYNC register.
The patch 1/2 fixes this by toggling the SYNC register after
FSC update.

 2. Currently, the sync bits are set-then-cleared after FSC and brightness
update. As per hardware team recommendation the FSC and brightness sync
takes place from clear-then-set transition of the sync bits.
The patch 2/2 fies this issue.

changes from V4:
  1. Rebased this patch series on the below patch.
 "backlight-qcom-wled-Use-sink_addr-for-sync-toggle.patch".

Changes from V3:
  1. Updated the patch description as per Daneil's suggestion.
  2. Added Daniel's "Reviewed-by" tag for patch 2/2.
  3. Updated the cover letter to use "set" and "clear" properly.
 
Changes from V2:
  1. Added Daniel's "Reviewed-by" tag for patch 1/2.
  2. Updated the patch 2/2 description with "set" and "clear"
 terminology instead of "1" and "0".
  3. Updated the cover letter with "set" and "clear" terminology
 instead of "1" and "0".

Changes from V1:
  1. Updated the cover letter.
  2. Updated the description of the patches as per Daniel's suggestion.

Kiran Gunda (2):
  backlight: qcom-wled: Fix FSC update issue for WLED5
  backlight: qcom-wled: Correct the sync_toggle sequence

 drivers/video/backlight/qcom-wled.c | 37 +
 1 file changed, 25 insertions(+), 12 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH V5 2/2] backlight: qcom-wled: Correct the sync_toggle sequence

2021-03-18 Thread Kiran Gunda
As per the current implementation, after FSC (Full Scale Current)
and brightness update the sync bits are set-then-cleared.
But, the FSC and brightness sync takes place when the sync bits are
set (e.g. on a rising edge). So the hardware team recommends a
clear-then-set approach in order to guarantee such a transition
regardless of the previous register state.

Signed-off-by: Kiran Gunda 
Reviewed-by: Daniel Thompson 
---
 drivers/video/backlight/qcom-wled.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index e9fbe24..7c02f87 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -337,13 +337,13 @@ static int wled3_sync_toggle(struct wled *wled)
 
rc = regmap_update_bits(wled->regmap,
wled->sink_addr + WLED3_SINK_REG_SYNC,
-   mask, mask);
+   mask, WLED3_SINK_REG_SYNC_CLEAR);
if (rc < 0)
return rc;
 
rc = regmap_update_bits(wled->regmap,
wled->sink_addr + WLED3_SINK_REG_SYNC,
-   mask, WLED3_SINK_REG_SYNC_CLEAR);
+   mask, mask);
 
return rc;
 }
@@ -353,17 +353,17 @@ static int wled5_mod_sync_toggle(struct wled *wled)
int rc;
u8 val;
 
-   val = (wled->cfg.mod_sel == MOD_A) ? WLED5_SINK_REG_SYNC_MOD_A_BIT :
-WLED5_SINK_REG_SYNC_MOD_B_BIT;
rc = regmap_update_bits(wled->regmap,
wled->sink_addr + WLED5_SINK_REG_MOD_SYNC_BIT,
-   WLED5_SINK_REG_SYNC_MASK, val);
+   WLED5_SINK_REG_SYNC_MASK, 0);
if (rc < 0)
return rc;
 
+   val = (wled->cfg.mod_sel == MOD_A) ? WLED5_SINK_REG_SYNC_MOD_A_BIT :
+WLED5_SINK_REG_SYNC_MOD_B_BIT;
return regmap_update_bits(wled->regmap,
  wled->sink_addr + WLED5_SINK_REG_MOD_SYNC_BIT,
- WLED5_SINK_REG_SYNC_MASK, 0);
+ WLED5_SINK_REG_SYNC_MASK, val);
 }
 
 static int wled_ovp_fault_status(struct wled *wled, bool *fault_set)
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH V4 2/2] backlight: qcom-wled: Correct the sync_toggle sequence

2021-03-01 Thread Kiran Gunda
As per the current implementation, after FSC (Full Scale Current)
and brightness update the sync bits are set-then-cleared.
But, the FSC and brightness sync takes place when the sync bits are
set (e.g. on a rising edge). So the hardware team recommends a
clear-then-set approach in order to guarantee such a transition
regardless of the previous register state.

Signed-off-by: Kiran Gunda 
Reviewed-by: Daniel Thompson 
---
 drivers/video/backlight/qcom-wled.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index aef52b9..19f83ac 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -337,13 +337,13 @@ static int wled3_sync_toggle(struct wled *wled)
 
rc = regmap_update_bits(wled->regmap,
wled->ctrl_addr + WLED3_SINK_REG_SYNC,
-   mask, mask);
+   mask, WLED3_SINK_REG_SYNC_CLEAR);
if (rc < 0)
return rc;
 
rc = regmap_update_bits(wled->regmap,
wled->ctrl_addr + WLED3_SINK_REG_SYNC,
-   mask, WLED3_SINK_REG_SYNC_CLEAR);
+   mask, mask);
 
return rc;
 }
@@ -353,17 +353,17 @@ static int wled5_mod_sync_toggle(struct wled *wled)
int rc;
u8 val;
 
-   val = (wled->cfg.mod_sel == MOD_A) ? WLED5_SINK_REG_SYNC_MOD_A_BIT :
-WLED5_SINK_REG_SYNC_MOD_B_BIT;
rc = regmap_update_bits(wled->regmap,
wled->sink_addr + WLED5_SINK_REG_MOD_SYNC_BIT,
-   WLED5_SINK_REG_SYNC_MASK, val);
+   WLED5_SINK_REG_SYNC_MASK, 0);
if (rc < 0)
return rc;
 
+   val = (wled->cfg.mod_sel == MOD_A) ? WLED5_SINK_REG_SYNC_MOD_A_BIT :
+WLED5_SINK_REG_SYNC_MOD_B_BIT;
return regmap_update_bits(wled->regmap,
  wled->sink_addr + WLED5_SINK_REG_MOD_SYNC_BIT,
- WLED5_SINK_REG_SYNC_MASK, 0);
+ WLED5_SINK_REG_SYNC_MASK, val);
 }
 
 static int wled_ovp_fault_status(struct wled *wled, bool *fault_set)
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH V4 1/2] backlight: qcom-wled: Fix FSC update issue for WLED5

2021-03-01 Thread Kiran Gunda
Currently, for WLED5, the FSC (Full scale current) setting is not
updated properly due to driver toggling the wrong register after
an FSC update.

On WLED5 we should only toggle the MOD_SYNC bit after a brightness
update. For an FSC update we need to toggle the SYNC bits instead.

Fix it by adopting the common wled3_sync_toggle() for WLED5 and
introducing new code to the brightness update path to compensate.

Signed-off-by: Kiran Gunda 
Reviewed-by: Daniel Thompson 
---
 drivers/video/backlight/qcom-wled.c | 25 +++--
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 3bc7800..aef52b9 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -348,7 +348,7 @@ static int wled3_sync_toggle(struct wled *wled)
return rc;
 }
 
-static int wled5_sync_toggle(struct wled *wled)
+static int wled5_mod_sync_toggle(struct wled *wled)
 {
int rc;
u8 val;
@@ -445,10 +445,23 @@ static int wled_update_status(struct backlight_device *bl)
goto unlock_mutex;
}
 
-   rc = wled->wled_sync_toggle(wled);
-   if (rc < 0) {
-   dev_err(wled->dev, "wled sync failed rc:%d\n", rc);
-   goto unlock_mutex;
+   if (wled->version < 5) {
+   rc = wled->wled_sync_toggle(wled);
+   if (rc < 0) {
+   dev_err(wled->dev, "wled sync failed rc:%d\n", 
rc);
+   goto unlock_mutex;
+   }
+   } else {
+   /*
+* For WLED5 toggling the MOD_SYNC_BIT updates the
+* brightness
+*/
+   rc = wled5_mod_sync_toggle(wled);
+   if (rc < 0) {
+   dev_err(wled->dev, "wled mod sync failed 
rc:%d\n",
+   rc);
+   goto unlock_mutex;
+   }
}
}
 
@@ -1459,7 +1472,7 @@ static int wled_configure(struct wled *wled)
size = ARRAY_SIZE(wled5_opts);
*cfg = wled5_config_defaults;
wled->wled_set_brightness = wled5_set_brightness;
-   wled->wled_sync_toggle = wled5_sync_toggle;
+   wled->wled_sync_toggle = wled3_sync_toggle;
wled->wled_cabc_config = wled5_cabc_config;
wled->wled_ovp_delay = wled5_ovp_delay;
wled->wled_auto_detection_required =
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH V4 0/2] Fix WLED FSC Sync and brightness Sync settings

2021-03-01 Thread Kiran Gunda
This patch series has the following two WLED fixes
 1. As per the current implementation, for WLED5, after
the FSC (Full Scale Current) update the driver is incorrectly
toggling the MOD_SYNC register instead of toggling the SYNC register.
The patch 1/2 fixes this by toggling the SYNC register after
FSC update.

 2. Currently, the sync bits are set-then-cleared after FSC and brightness
update. As per hardware team recommendation the FSC and brightness sync
takes place from clear-then-set transition of the sync bits.
The patch 2/2 fies this issue.

Changes from V3:
  1. Updated the patch description as per Daneil's suggestion.
  2. Added Daniel's "Reviewed-by" tag for patch 2/2.
  3. Updated the cover letter to use "set" and "clear" properly.
 
Changes from V2:
  1. Added Daniel's "Reviewed-by" tag for patch 1/2.
  2. Updated the patch 2/2 description with "set" and "clear"
 terminology instead of "1" and "0".
  3. Updated the cover letter with "set" and "clear" terminology
 instead of "1" and "0".

Changes from V1:
  1. Updated the cover letter.
  2. Updated the description of the patches as per Daniel's suggestion.

Kiran Gunda (2):
  backlight: qcom-wled: Fix FSC update issue for WLED5
  backlight: qcom-wled: Correct the sync_toggle sequence

 drivers/video/backlight/qcom-wled.c | 37 +
 1 file changed, 25 insertions(+), 12 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH V3 1/2] backlight: qcom-wled: Fix FSC update issue for WLED5

2021-03-01 Thread Kiran Gunda
Currently, for WLED5, the FSC (Full scale current) setting is not
updated properly due to driver toggling the wrong register after
an FSC update.

On WLED5 we should only toggle the MOD_SYNC bit after a brightness
update. For an FSC update we need to toggle the SYNC bits instead.

Fix it by adopting the common wled3_sync_toggle() for WLED5 and
introducing new code to the brightness update path to compensate.

Signed-off-by: Kiran Gunda 
Reviewed-by: Daniel Thompson 
---
 drivers/video/backlight/qcom-wled.c | 25 +++--
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 3bc7800..aef52b9 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -348,7 +348,7 @@ static int wled3_sync_toggle(struct wled *wled)
return rc;
 }
 
-static int wled5_sync_toggle(struct wled *wled)
+static int wled5_mod_sync_toggle(struct wled *wled)
 {
int rc;
u8 val;
@@ -445,10 +445,23 @@ static int wled_update_status(struct backlight_device *bl)
goto unlock_mutex;
}
 
-   rc = wled->wled_sync_toggle(wled);
-   if (rc < 0) {
-   dev_err(wled->dev, "wled sync failed rc:%d\n", rc);
-   goto unlock_mutex;
+   if (wled->version < 5) {
+   rc = wled->wled_sync_toggle(wled);
+   if (rc < 0) {
+   dev_err(wled->dev, "wled sync failed rc:%d\n", 
rc);
+   goto unlock_mutex;
+   }
+   } else {
+   /*
+* For WLED5 toggling the MOD_SYNC_BIT updates the
+* brightness
+*/
+   rc = wled5_mod_sync_toggle(wled);
+   if (rc < 0) {
+   dev_err(wled->dev, "wled mod sync failed 
rc:%d\n",
+   rc);
+   goto unlock_mutex;
+   }
}
}
 
@@ -1459,7 +1472,7 @@ static int wled_configure(struct wled *wled)
size = ARRAY_SIZE(wled5_opts);
*cfg = wled5_config_defaults;
wled->wled_set_brightness = wled5_set_brightness;
-   wled->wled_sync_toggle = wled5_sync_toggle;
+   wled->wled_sync_toggle = wled3_sync_toggle;
wled->wled_cabc_config = wled5_cabc_config;
wled->wled_ovp_delay = wled5_ovp_delay;
wled->wled_auto_detection_required =
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH V3 2/2] backlight: qcom-wled: Correct the sync_toggle sequence

2021-03-01 Thread Kiran Gunda
As per the current implementation, after FSC (Full Scale Current)
and brightness update the sync bits are transitioned from set-then-clear.
But, the FSC and brightness sync takes place during a clear-then-set
transition of the sync bits. So the hardware team recommends a
clear-then-set approach in order to guarantee such a transition
regardless of the previous register state.

Signed-off-by: Kiran Gunda 
---
 drivers/video/backlight/qcom-wled.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index aef52b9..19f83ac 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -337,13 +337,13 @@ static int wled3_sync_toggle(struct wled *wled)
 
rc = regmap_update_bits(wled->regmap,
wled->ctrl_addr + WLED3_SINK_REG_SYNC,
-   mask, mask);
+   mask, WLED3_SINK_REG_SYNC_CLEAR);
if (rc < 0)
return rc;
 
rc = regmap_update_bits(wled->regmap,
wled->ctrl_addr + WLED3_SINK_REG_SYNC,
-   mask, WLED3_SINK_REG_SYNC_CLEAR);
+   mask, mask);
 
return rc;
 }
@@ -353,17 +353,17 @@ static int wled5_mod_sync_toggle(struct wled *wled)
int rc;
u8 val;
 
-   val = (wled->cfg.mod_sel == MOD_A) ? WLED5_SINK_REG_SYNC_MOD_A_BIT :
-WLED5_SINK_REG_SYNC_MOD_B_BIT;
rc = regmap_update_bits(wled->regmap,
wled->sink_addr + WLED5_SINK_REG_MOD_SYNC_BIT,
-   WLED5_SINK_REG_SYNC_MASK, val);
+   WLED5_SINK_REG_SYNC_MASK, 0);
if (rc < 0)
return rc;
 
+   val = (wled->cfg.mod_sel == MOD_A) ? WLED5_SINK_REG_SYNC_MOD_A_BIT :
+WLED5_SINK_REG_SYNC_MOD_B_BIT;
return regmap_update_bits(wled->regmap,
  wled->sink_addr + WLED5_SINK_REG_MOD_SYNC_BIT,
- WLED5_SINK_REG_SYNC_MASK, 0);
+ WLED5_SINK_REG_SYNC_MASK, val);
 }
 
 static int wled_ovp_fault_status(struct wled *wled, bool *fault_set)
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH V3 0/2] Fix WLED FSC Sync and brightness Sync settings

2021-03-01 Thread Kiran Gunda
This patch series has the following two WLED fixes
 1. As per the current implementation, for WLED5, after
the FSC (Full Scale Current) update the driver is incorrectly
toggling the MOD_SYNC register instead of toggling the SYNC register.
The patch 1/2 fixes this by toggling the SYNC register after
FSC update.

 2. Currently, the sync bits are transitioned from set-then-clear
after FSC and brightness update. As per hardware team recommendation
the FSC and brightness sync takes place from clear-then-set transition
of the sync bits. The patch 2/2 fies this issue.


Changes from V2:
  1. Added Daniel's "Reviewed-by" tag for patch 1/2.
  2. Updated the patch 2/2 description with "set" and "clear"
 terminology instead of "1" and "0".
  3. Updated the cover letter with "set" and "clear" terminology
 instead of "1" and "0".

Changes from V1:
   1. Updated the cover letter.
   2. Updated the description of the patches as per Daniel's suggestion.


Kiran Gunda (2):
  backlight: qcom-wled: Fix FSC update issue for WLED5
  backlight: qcom-wled: Correct the sync_toggle sequence

 drivers/video/backlight/qcom-wled.c | 37 +
 1 file changed, 25 insertions(+), 12 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH V2 2/2] backlight: qcom-wled: Correct the sync_toggle sequence

2021-02-26 Thread Kiran Gunda
As per the current implementation, after FSC (Full Scale Current)
and brightness update the sync bits are transitioned from 1 to 0.
But, the FSC and brightness sync takes place during a 0 to 1
transition of the sync bits. So the hardware team recommends a
clear-then-set approach in order to guarantee such a transition
regardless of the previous register state.

Signed-off-by: Kiran Gunda 
---
 drivers/video/backlight/qcom-wled.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index aef52b9..19f83ac 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -337,13 +337,13 @@ static int wled3_sync_toggle(struct wled *wled)
 
rc = regmap_update_bits(wled->regmap,
wled->ctrl_addr + WLED3_SINK_REG_SYNC,
-   mask, mask);
+   mask, WLED3_SINK_REG_SYNC_CLEAR);
if (rc < 0)
return rc;
 
rc = regmap_update_bits(wled->regmap,
wled->ctrl_addr + WLED3_SINK_REG_SYNC,
-   mask, WLED3_SINK_REG_SYNC_CLEAR);
+   mask, mask);
 
return rc;
 }
@@ -353,17 +353,17 @@ static int wled5_mod_sync_toggle(struct wled *wled)
int rc;
u8 val;
 
-   val = (wled->cfg.mod_sel == MOD_A) ? WLED5_SINK_REG_SYNC_MOD_A_BIT :
-WLED5_SINK_REG_SYNC_MOD_B_BIT;
rc = regmap_update_bits(wled->regmap,
wled->sink_addr + WLED5_SINK_REG_MOD_SYNC_BIT,
-   WLED5_SINK_REG_SYNC_MASK, val);
+   WLED5_SINK_REG_SYNC_MASK, 0);
if (rc < 0)
return rc;
 
+   val = (wled->cfg.mod_sel == MOD_A) ? WLED5_SINK_REG_SYNC_MOD_A_BIT :
+WLED5_SINK_REG_SYNC_MOD_B_BIT;
return regmap_update_bits(wled->regmap,
  wled->sink_addr + WLED5_SINK_REG_MOD_SYNC_BIT,
- WLED5_SINK_REG_SYNC_MASK, 0);
+ WLED5_SINK_REG_SYNC_MASK, val);
 }
 
 static int wled_ovp_fault_status(struct wled *wled, bool *fault_set)
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH V2 1/2] backlight: qcom-wled: Fix FSC update issue for WLED5

2021-02-26 Thread Kiran Gunda
Currently, for WLED5, the FSC (Full scale current) setting is not
updated properly due to driver toggling the wrong register after
an FSC update.

On WLED5 we should only toggle the MOD_SYNC bit after a brightness
update. For an FSC update we need to toggle the SYNC bits instead.

Fix it by adopting the common wled3_sync_toggle() for WLED5 and
introducing new code to the brightness update path to compensate.

Signed-off-by: Kiran Gunda 
---
 drivers/video/backlight/qcom-wled.c | 25 +++--
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 3bc7800..aef52b9 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -348,7 +348,7 @@ static int wled3_sync_toggle(struct wled *wled)
return rc;
 }
 
-static int wled5_sync_toggle(struct wled *wled)
+static int wled5_mod_sync_toggle(struct wled *wled)
 {
int rc;
u8 val;
@@ -445,10 +445,23 @@ static int wled_update_status(struct backlight_device *bl)
goto unlock_mutex;
}
 
-   rc = wled->wled_sync_toggle(wled);
-   if (rc < 0) {
-   dev_err(wled->dev, "wled sync failed rc:%d\n", rc);
-   goto unlock_mutex;
+   if (wled->version < 5) {
+   rc = wled->wled_sync_toggle(wled);
+   if (rc < 0) {
+   dev_err(wled->dev, "wled sync failed rc:%d\n", 
rc);
+   goto unlock_mutex;
+   }
+   } else {
+   /*
+* For WLED5 toggling the MOD_SYNC_BIT updates the
+* brightness
+*/
+   rc = wled5_mod_sync_toggle(wled);
+   if (rc < 0) {
+   dev_err(wled->dev, "wled mod sync failed 
rc:%d\n",
+   rc);
+   goto unlock_mutex;
+   }
}
}
 
@@ -1459,7 +1472,7 @@ static int wled_configure(struct wled *wled)
size = ARRAY_SIZE(wled5_opts);
*cfg = wled5_config_defaults;
wled->wled_set_brightness = wled5_set_brightness;
-   wled->wled_sync_toggle = wled5_sync_toggle;
+   wled->wled_sync_toggle = wled3_sync_toggle;
wled->wled_cabc_config = wled5_cabc_config;
wled->wled_ovp_delay = wled5_ovp_delay;
wled->wled_auto_detection_required =
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH V2 0/2] Fix WLED FSC Sync and brightness Sync settings

2021-02-26 Thread Kiran Gunda
This patch series has the following two WLED fixes
 1. As per the current implementation, for WLED5, after
the FSC (Full Scale Current) update the driver is incorrectly
toggling the MOD_SYNC register instead of toggling the SYNC register.
The patch 1/2 fixes this by toggling the SYNC register after
FSC update.

 2. Currently, the sync bits are transitioned from 1 to 0
after FSC and brightness update. As per hardware team recommendation
the FSC and brightness sync takes place from 0 to 1 transition.
The patch 2/2 fies this issue.


Changes from V1:
   1. Updated the cover letter.
   2. Updated the description of the patches as per Daniel's suggestion.


Kiran Gunda (2):
  backlight: qcom-wled: Fix FSC update issue for WLED5
  backlight: qcom-wled: Correct the sync_toggle sequence

 drivers/video/backlight/qcom-wled.c | 37 +
 1 file changed, 25 insertions(+), 12 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH V1 1/2] backlight: qcom-wled: Fix FSC update issue for WLED5

2021-02-23 Thread Kiran Gunda
Currently, for WLED5, after FSC register update MOD_SYNC_BIT
is toggled instead of SYNC_BIT. MOD_SYNC_BIT has to be toggled
after the brightness update and SYNC_BIT has to be toggled after
FSC update for WLED5. Fix it.

Signed-off-by: Kiran Gunda 
---
 drivers/video/backlight/qcom-wled.c | 25 +++--
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 3bc7800..aef52b9 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -348,7 +348,7 @@ static int wled3_sync_toggle(struct wled *wled)
return rc;
 }
 
-static int wled5_sync_toggle(struct wled *wled)
+static int wled5_mod_sync_toggle(struct wled *wled)
 {
int rc;
u8 val;
@@ -445,10 +445,23 @@ static int wled_update_status(struct backlight_device *bl)
goto unlock_mutex;
}
 
-   rc = wled->wled_sync_toggle(wled);
-   if (rc < 0) {
-   dev_err(wled->dev, "wled sync failed rc:%d\n", rc);
-   goto unlock_mutex;
+   if (wled->version < 5) {
+   rc = wled->wled_sync_toggle(wled);
+   if (rc < 0) {
+   dev_err(wled->dev, "wled sync failed rc:%d\n", 
rc);
+   goto unlock_mutex;
+   }
+   } else {
+   /*
+* For WLED5 toggling the MOD_SYNC_BIT updates the
+* brightness
+*/
+   rc = wled5_mod_sync_toggle(wled);
+   if (rc < 0) {
+   dev_err(wled->dev, "wled mod sync failed 
rc:%d\n",
+   rc);
+   goto unlock_mutex;
+   }
}
}
 
@@ -1459,7 +1472,7 @@ static int wled_configure(struct wled *wled)
size = ARRAY_SIZE(wled5_opts);
*cfg = wled5_config_defaults;
wled->wled_set_brightness = wled5_set_brightness;
-   wled->wled_sync_toggle = wled5_sync_toggle;
+   wled->wled_sync_toggle = wled3_sync_toggle;
wled->wled_cabc_config = wled5_cabc_config;
wled->wled_ovp_delay = wled5_ovp_delay;
wled->wled_auto_detection_required =
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH V1 2/2] backlight: qcom-wled: Correct the sync_toggle sequence

2021-02-23 Thread Kiran Gunda
Currently the FSC SYNC_BIT and MOD_SYNC_BIT are toggled
from 1 to 0 to update the FSC and brightenss settings.
Change this sequence form 0 to 1 as per the hardware team
recommendation to update the FSC and brightness correctly.

Signed-off-by: Kiran Gunda 
---
 drivers/video/backlight/qcom-wled.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index aef52b9..19f83ac 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -337,13 +337,13 @@ static int wled3_sync_toggle(struct wled *wled)
 
rc = regmap_update_bits(wled->regmap,
wled->ctrl_addr + WLED3_SINK_REG_SYNC,
-   mask, mask);
+   mask, WLED3_SINK_REG_SYNC_CLEAR);
if (rc < 0)
return rc;
 
rc = regmap_update_bits(wled->regmap,
wled->ctrl_addr + WLED3_SINK_REG_SYNC,
-   mask, WLED3_SINK_REG_SYNC_CLEAR);
+   mask, mask);
 
return rc;
 }
@@ -353,17 +353,17 @@ static int wled5_mod_sync_toggle(struct wled *wled)
int rc;
u8 val;
 
-   val = (wled->cfg.mod_sel == MOD_A) ? WLED5_SINK_REG_SYNC_MOD_A_BIT :
-WLED5_SINK_REG_SYNC_MOD_B_BIT;
rc = regmap_update_bits(wled->regmap,
wled->sink_addr + WLED5_SINK_REG_MOD_SYNC_BIT,
-   WLED5_SINK_REG_SYNC_MASK, val);
+   WLED5_SINK_REG_SYNC_MASK, 0);
if (rc < 0)
return rc;
 
+   val = (wled->cfg.mod_sel == MOD_A) ? WLED5_SINK_REG_SYNC_MOD_A_BIT :
+WLED5_SINK_REG_SYNC_MOD_B_BIT;
return regmap_update_bits(wled->regmap,
  wled->sink_addr + WLED5_SINK_REG_MOD_SYNC_BIT,
- WLED5_SINK_REG_SYNC_MASK, 0);
+ WLED5_SINK_REG_SYNC_MASK, val);
 }
 
 static int wled_ovp_fault_status(struct wled *wled, bool *fault_set)
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH V1 0/2] Fix WLED FSC Sync and brightness Sync settings

2021-02-23 Thread Kiran Gunda
The FSC (Full scale current) setting is not updated properly due to the
wrong register toggling for WLED5. Also the ILED_SYNC toggle and MOD_SYNC
toggle sequence is updated as per the hardware team recommendation to fix
the FSC update and brightness update issue.

Kiran Gunda (2):
  backlight: qcom-wled: Fix FSC update issue for WLED5
  backlight: qcom-wled: Correct the sync_toggle sequence

 drivers/video/backlight/qcom-wled.c | 37 +
 1 file changed, 25 insertions(+), 12 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH V1 1/2] backlight: qcom-wled: Fix FSC update issue for WLED5

2021-02-19 Thread Kiran Gunda
Currently, for WLED5, after FSC register update MOD_SYNC_BIT
is toggled instead of SYNC_BIT. MOD_SYNC_BIT has to be toggled
after the brightness update and SYNC_BIT has to be toggled after
FSC update for WLED5. Fix it.

Signed-off-by: Kiran Gunda 
---
 drivers/video/backlight/qcom-wled.c | 25 +++--
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 3bc7800..aef52b9 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -348,7 +348,7 @@ static int wled3_sync_toggle(struct wled *wled)
return rc;
 }
 
-static int wled5_sync_toggle(struct wled *wled)
+static int wled5_mod_sync_toggle(struct wled *wled)
 {
int rc;
u8 val;
@@ -445,10 +445,23 @@ static int wled_update_status(struct backlight_device *bl)
goto unlock_mutex;
}
 
-   rc = wled->wled_sync_toggle(wled);
-   if (rc < 0) {
-   dev_err(wled->dev, "wled sync failed rc:%d\n", rc);
-   goto unlock_mutex;
+   if (wled->version < 5) {
+   rc = wled->wled_sync_toggle(wled);
+   if (rc < 0) {
+   dev_err(wled->dev, "wled sync failed rc:%d\n", 
rc);
+   goto unlock_mutex;
+   }
+   } else {
+   /*
+* For WLED5 toggling the MOD_SYNC_BIT updates the
+* brightness
+*/
+   rc = wled5_mod_sync_toggle(wled);
+   if (rc < 0) {
+   dev_err(wled->dev, "wled mod sync failed 
rc:%d\n",
+   rc);
+   goto unlock_mutex;
+   }
}
}
 
@@ -1459,7 +1472,7 @@ static int wled_configure(struct wled *wled)
size = ARRAY_SIZE(wled5_opts);
*cfg = wled5_config_defaults;
wled->wled_set_brightness = wled5_set_brightness;
-   wled->wled_sync_toggle = wled5_sync_toggle;
+   wled->wled_sync_toggle = wled3_sync_toggle;
wled->wled_cabc_config = wled5_cabc_config;
wled->wled_ovp_delay = wled5_ovp_delay;
wled->wled_auto_detection_required =
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH V1 0/2] Fix WLED FSC Sync and brightness Sync settings

2021-02-19 Thread Kiran Gunda
The FSC (Full scale current) setting is not updated properly due to the
wrong register toggling for WLED5. Also the ILED_SYNC toggle and MOD_SYNC
toggle sequence is updated as per the hardware team recommendation to fix
the FSC update and brightness update issue.

Kiran Gunda (2):
  backlight: qcom-wled: Fix FSC update issue for WLED5
  backlight: qcom-wled: Correct the sync_toggle sequence

 drivers/video/backlight/qcom-wled.c | 37 +
 1 file changed, 25 insertions(+), 12 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH V1 2/2] backlight: qcom-wled: Correct the sync_toggle sequence

2021-02-19 Thread Kiran Gunda
Currently the FSC SYNC_BIT and MOD_SYNC_BIT are toggled
from 1 to 0 to update the FSC and brightenss settings.
Change this sequence form 0 to 1 as per the hardware team
recommendation to update the FSC and brightness correctly.

Signed-off-by: Kiran Gunda 
---
 drivers/video/backlight/qcom-wled.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index aef52b9..19f83ac 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -337,13 +337,13 @@ static int wled3_sync_toggle(struct wled *wled)
 
rc = regmap_update_bits(wled->regmap,
wled->ctrl_addr + WLED3_SINK_REG_SYNC,
-   mask, mask);
+   mask, WLED3_SINK_REG_SYNC_CLEAR);
if (rc < 0)
return rc;
 
rc = regmap_update_bits(wled->regmap,
wled->ctrl_addr + WLED3_SINK_REG_SYNC,
-   mask, WLED3_SINK_REG_SYNC_CLEAR);
+   mask, mask);
 
return rc;
 }
@@ -353,17 +353,17 @@ static int wled5_mod_sync_toggle(struct wled *wled)
int rc;
u8 val;
 
-   val = (wled->cfg.mod_sel == MOD_A) ? WLED5_SINK_REG_SYNC_MOD_A_BIT :
-WLED5_SINK_REG_SYNC_MOD_B_BIT;
rc = regmap_update_bits(wled->regmap,
wled->sink_addr + WLED5_SINK_REG_MOD_SYNC_BIT,
-   WLED5_SINK_REG_SYNC_MASK, val);
+   WLED5_SINK_REG_SYNC_MASK, 0);
if (rc < 0)
return rc;
 
+   val = (wled->cfg.mod_sel == MOD_A) ? WLED5_SINK_REG_SYNC_MOD_A_BIT :
+WLED5_SINK_REG_SYNC_MOD_B_BIT;
return regmap_update_bits(wled->regmap,
  wled->sink_addr + WLED5_SINK_REG_MOD_SYNC_BIT,
- WLED5_SINK_REG_SYNC_MASK, 0);
+ WLED5_SINK_REG_SYNC_MASK, val);
 }
 
 static int wled_ovp_fault_status(struct wled *wled, bool *fault_set)
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH V6 0/4] Add support for WLED5

2020-04-23 Thread Kiran Gunda
Currently, WLED driver supports only WLED4 peripherals that is present
on pmi8998 and pm660L. This patch series  converts the existing WLED4
bindings from .txt to .yaml format and adds the support for WLED5 peripheral
that is present on PM8150L.

PM8150L WLED supports the following.
- Two modulators and each sink can use any of the modulator
- Multiple CABC selection options
- Multiple brightness width selection (12 bits to 15 bits)

Changes from V1:
- Rebased on top of the below commit.
  backlight: qcom-wled: Fix unsigned comparison to zero

Changes from V2:
- Addressed Bjorn's comments by splitting the WLED4 changes
  in a seperate patch.
- Added WLED5 auto calibration support

Changes from V3:
- Addressed comments from Daniel Thompson and Rob Herring
- Seperated the WLED5 bindings from the driver changes
 - Squashed wled5 auto string detection and wled5 basic changes
  to avoid the NULL callback function pointer issue.

Changes from V4:
- Addressed the yaml formatting comments from Rob Herring.
- Addressed the comments from Daniel Thompson on the below patch
  "backlight: qcom-wled: Add callback functions"

Changes from V5:
- This series depends on the below patch.
  https://lore.kernel.org/patchwork/patch/1226258/
- Addressed yaml formatting comments from Rob Herring.
- Removed the "wled_ovp_fault_status" callback as per Daniel Thomson
  suggestion from patch #2.
- Addressed comments from Daniel Thomson on patch #4.

Kiran Gunda (3):
  backlight: qcom-wled: convert the wled bindings to .yaml format
  backlight: qcom-wled: Add callback functions
  backlight: qcom-wled: Add WLED5 bindings

Subbaraman Narayanamurthy (1):
  backlight: qcom-wled: Add support for WLED5 peripheral that is present
on PM8150L PMICs

 .../bindings/leds/backlight/qcom-wled.txt  | 154 --
 .../bindings/leds/backlight/qcom-wled.yaml | 261 +
 drivers/video/backlight/qcom-wled.c| 589 ++---
 3 files changed, 777 insertions(+), 227 deletions(-)
 delete mode 100644 
Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
 create mode 100644 
Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH V6 4/4] backlight: qcom-wled: Add support for WLED5 peripheral that is present on PM8150L PMICs

2020-04-23 Thread Kiran Gunda
From: Subbaraman Narayanamurthy 

PM8150L WLED supports the following:
- Two modulators and each sink can use any of the modulator
- Multiple CABC selection options from which one can be selected/enabled
- Multiple brightness width selection (12 bits to 15 bits)

Signed-off-by: Subbaraman Narayanamurthy 
Signed-off-by: Kiran Gunda 
---
 drivers/video/backlight/qcom-wled.c | 378 +++-
 1 file changed, 376 insertions(+), 2 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 7b0095e..c25c311 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -15,16 +15,21 @@
 
 /* From DT binding */
 #define WLED_MAX_STRINGS   4
+#define MOD_A  0
+#define MOD_B  1
 
 #define WLED_DEFAULT_BRIGHTNESS2048
 #define WLED_SOFT_START_DLY_US 1
 #define WLED3_SINK_REG_BRIGHT_MAX  0xFFF
+#define WLED5_SINK_REG_BRIGHT_MAX_12B  0xFFF
+#define WLED5_SINK_REG_BRIGHT_MAX_15B  0x7FFF
 
 /* WLED3/WLED4 control registers */
 #define WLED3_CTRL_REG_FAULT_STATUS0x08
 #define  WLED3_CTRL_REG_ILIM_FAULT_BIT BIT(0)
 #define  WLED3_CTRL_REG_OVP_FAULT_BIT  BIT(1)
 #define  WLED4_CTRL_REG_SC_FAULT_BIT   BIT(2)
+#define  WLED5_CTRL_REG_OVP_PRE_ALARM_BIT  BIT(4)
 
 #define WLED3_CTRL_REG_INT_RT_STS  0x10
 #define  WLED3_CTRL_REG_OVP_FAULT_STATUS   BIT(1)
@@ -40,6 +45,7 @@
 
 #define WLED3_CTRL_REG_OVP 0x4d
 #define  WLED3_CTRL_REG_OVP_MASK   GENMASK(1, 0)
+#define  WLED5_CTRL_REG_OVP_MASK   GENMASK(3, 0)
 
 #define WLED3_CTRL_REG_ILIMIT  0x4e
 #define  WLED3_CTRL_REG_ILIMIT_MASKGENMASK(2, 0)
@@ -101,6 +107,44 @@
 
 #define WLED4_SINK_REG_BRIGHT(n)   (0x57 + (n * 0x10))
 
+/* WLED5 specific control registers */
+#define WLED5_CTRL_REG_OVP_INT_CTL 0x5f
+#define  WLED5_CTRL_REG_OVP_INT_TIMER_MASK GENMASK(2, 0)
+
+/* WLED5 specific sink registers */
+#define WLED5_SINK_REG_MOD_A_EN0x50
+#define WLED5_SINK_REG_MOD_B_EN0x60
+#define  WLED5_SINK_REG_MOD_EN_MASKBIT(7)
+
+#define WLED5_SINK_REG_MOD_A_SRC_SEL   0x51
+#define WLED5_SINK_REG_MOD_B_SRC_SEL   0x61
+#define  WLED5_SINK_REG_MOD_SRC_SEL_HIGH   0
+#define  WLED5_SINK_REG_MOD_SRC_SEL_EXT0x03
+#define  WLED5_SINK_REG_MOD_SRC_SEL_MASK   GENMASK(1, 0)
+
+#define WLED5_SINK_REG_MOD_A_BRIGHTNESS_WIDTH_SEL  0x52
+#define WLED5_SINK_REG_MOD_B_BRIGHTNESS_WIDTH_SEL  0x62
+#define  WLED5_SINK_REG_BRIGHTNESS_WIDTH_12B   0
+#define  WLED5_SINK_REG_BRIGHTNESS_WIDTH_15B   1
+
+#define WLED5_SINK_REG_MOD_A_BRIGHTNESS_LSB0x53
+#define WLED5_SINK_REG_MOD_A_BRIGHTNESS_MSB0x54
+#define WLED5_SINK_REG_MOD_B_BRIGHTNESS_LSB0x63
+#define WLED5_SINK_REG_MOD_B_BRIGHTNESS_MSB0x64
+
+#define WLED5_SINK_REG_MOD_SYNC_BIT0x65
+#define  WLED5_SINK_REG_SYNC_MOD_A_BIT BIT(0)
+#define  WLED5_SINK_REG_SYNC_MOD_B_BIT BIT(1)
+#define  WLED5_SINK_REG_SYNC_MASK  GENMASK(1, 0)
+
+/* WLED5 specific per-'string' registers below */
+#define WLED5_SINK_REG_STR_FULL_SCALE_CURR(n)  (0x72 + (n * 0x10))
+
+#define WLED5_SINK_REG_STR_SRC_SEL(n)  (0x73 + (n * 0x10))
+#define  WLED5_SINK_REG_SRC_SEL_MOD_A  0
+#define  WLED5_SINK_REG_SRC_SEL_MOD_B  1
+#define  WLED5_SINK_REG_SRC_SEL_MASK   GENMASK(1, 0)
+
 struct wled_var_cfg {
const u32 *values;
u32 (*fn)(u32);
@@ -125,6 +169,8 @@ struct wled_config {
u32 num_strings;
u32 string_i_limit;
u32 enabled_strings[WLED_MAX_STRINGS];
+   u32 mod_sel;
+   u32 cabc_sel;
bool cs_out_en;
bool ext_gen;
bool cabc;
@@ -150,6 +196,7 @@ struct wled {
u32 version;
bool disabled_by_short;
bool has_short_detect;
+   bool cabc_disabled;
int short_irq;
int ovp_irq;
 
@@ -222,6 +269,28 @@ static int wled4_set_brightness(struct wled *wled, u16 
brightness)
return 0;
 }
 
+static int wled5_set_brightness(struct wled *wled, u16 brightness)
+{
+   int rc, offset;
+   u16 low_limit = wled->max_brightness * 1 / 1000;
+   u8 v[2];
+
+   /* WLED5's lower limit is 0.1% */
+   if (brightness < low_limit)
+   brightness = low_limit;
+
+   v[0] = brightness & 0xff;
+

[PATCH V6 3/4] backlight: qcom-wled: Add WLED5 bindings

2020-04-23 Thread Kiran Gunda
Add WLED5 specific bindings.

Signed-off-by: Kiran Gunda 
Signed-off-by: Subbaraman Narayanamurthy 
Acked-by: Daniel Thompson 
---
 .../bindings/leds/backlight/qcom-wled.yaml | 59 --
 1 file changed, 56 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml 
b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml
index b835443b..01c7d93 100644
--- a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml
+++ b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml
@@ -21,6 +21,7 @@ properties:
   - qcom,pm8941-wled
   - qcom,pmi8998-wled
   - qcom,pm660l-wled
+  - qcom,pm8150l-wled
 
   reg:
 maxItems: 1
@@ -28,12 +29,13 @@ properties:
   default-brightness:
 description: |
   brightness value on boot.
-minimum: 0
-maximum: 4095
-default: 2048
 
   label: true
 
+  max-brightness:
+description: |
+  Maximum brightness level.
+
   qcom,cs-out:
 description: |
   enable current sink output.
@@ -141,6 +143,31 @@ properties:
   - const: ovp
   - const: short
 
+  qcom,modulator-sel:
+description: |
+  Selects the modulator used for brightness modulation.
+  Allowed values are,
+   0 - Modulator A
+   1 - Modulator B
+  This property is applicable only to WLED5 peripheral.
+allOf:
+  - $ref: /schemas/types.yaml#/definitions/uint32
+  - enum: [ 0, 1 ]
+  - default: 0
+
+  qcom,cabc-sel:
+description: |
+  Selects the CABC pin signal used for brightness modulation.
+  Allowed values are,
+   0 - CABC disabled
+   1 - CABC 1
+   2 - CABC 2
+   3 - External signal (e.g. LPG) is used for dimming
+  This property is applicable only to WLED5 peripheral.
+allOf:
+  - $ref: /schemas/types.yaml#/definitions/uint32
+  - enum: [ 0, 1, 2, 3 ]
+
 allOf:
   - if:
   properties:
@@ -183,6 +210,32 @@ allOf:
 
 interrupt-names:
   minItems: 2
+  - if:
+  properties:
+compatible:
+  contains:
+enum:
+  - qcom,pm8150l-wled
+
+then:
+  properties:
+default-brightness:
+  minimum: 0
+  maximum: 32767
+
+max-brightness:
+  minimum: 0
+  maximum: 32767
+
+else:
+  properties:
+default-brightness:
+  minimum: 0
+  maximum: 4095
+
+max-brightness:
+  minimum: 0
+  maximum: 4095
 
 required:
   - compatible
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH V6 1/4] backlight: qcom-wled: convert the wled bindings to .yaml format

2020-04-23 Thread Kiran Gunda
Convert the qcom-wled bindings from .txt to .yaml format.
Also replace PM8941 to WLED3 and PMI8998 to WLED4.

Signed-off-by: Kiran Gunda 
Signed-off-by: Subbaraman Narayanamurthy 
Acked-by: Daniel Thompson 
---
 .../bindings/leds/backlight/qcom-wled.txt  | 154 ---
 .../bindings/leds/backlight/qcom-wled.yaml | 208 +
 2 files changed, 208 insertions(+), 154 deletions(-)
 delete mode 100644 
Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
 create mode 100644 
Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml

diff --git a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt 
b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
deleted file mode 100644
index c06863b..000
--- a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
+++ /dev/null
@@ -1,154 +0,0 @@
-Binding for Qualcomm Technologies, Inc. WLED driver
-
-WLED (White Light Emitting Diode) driver is used for controlling display
-backlight that is part of PMIC on Qualcomm Technologies, Inc. reference
-platforms. The PMIC is connected to the host processor via SPMI bus.
-
-- compatible
-   Usage:required
-   Value type:   
-   Definition:   should be one of:
-   "qcom,pm8941-wled"
-   "qcom,pmi8998-wled"
-   "qcom,pm660l-wled"
-
-- reg
-   Usage:required
-   Value type:   
-   Definition:   Base address of the WLED modules.
-
-- default-brightness
-   Usage:optional
-   Value type:   
-   Definition:   brightness value on boot, value from: 0-4095.
- Default: 2048
-
-- label
-   Usage:required
-   Value type:   
-   Definition:   The name of the backlight device
-
-- qcom,cs-out
-   Usage:optional
-   Value type:   
-   Definition:   enable current sink output.
- This property is supported only for PM8941.
-
-- qcom,cabc
-   Usage:optional
-   Value type:   
-   Definition:   enable content adaptive backlight control.
-
-- qcom,ext-gen
-   Usage:optional
-   Value type:   
-   Definition:   use externally generated modulator signal to dim.
- This property is supported only for PM8941.
-
-- qcom,current-limit
-   Usage:optional
-   Value type:   
-   Definition:   mA; per-string current limit; value from 0 to 25 with
- 1 mA step. Default 20 mA.
- This property is supported only for pm8941.
-
-- qcom,current-limit-microamp
-   Usage:optional
-   Value type:   
-   Definition:   uA; per-string current limit; value from 0 to 3 with
- 2500 uA step. Default 25 mA.
-
-- qcom,current-boost-limit
-   Usage:optional
-   Value type:   
-   Definition:   mA; boost current limit.
- For pm8941: one of: 105, 385, 525, 805, 980, 1260, 1400,
- 1680. Default: 805 mA.
- For pmi8998: one of: 105, 280, 450, 620, 970, 1150, 1300,
- 1500. Default: 970 mA.
-
-- qcom,switching-freq
-   Usage:optional
-   Value type:   
-Definition:   kHz; switching frequency; one of: 600, 640, 685, 738,
-  800, 872, 960, 1066, 1200, 1371, 1600, 1920, 2400, 3200,
-  4800, 9600.
-  Default: for pm8941: 1600 kHz
-   for pmi8998: 800 kHz
-
-- qcom,ovp
-   Usage:optional
-   Value type:   
-   Definition:   V; Over-voltage protection limit; one of:
- 27, 29, 32, 35. Default: 29V
- This property is supported only for PM8941.
-
-- qcom,ovp-millivolt
-   Usage:optional
-   Value type:   
-   Definition:   mV; Over-voltage protection limit;
- For pmi8998: one of 18100, 19600, 29600, 31100.
- Default 29600 mV.
- If this property is not specified for PM8941, it
- falls back to "qcom,ovp" property.
-
-- qcom,num-strings
-   Usage:optional
-   Value type:   
-   Definition:   #; number of led strings attached;
- value: For PM8941 from 1 to 3. Default: 2
-For PMI8998 from 1 to 4.
-
-- interrupts
-   Usage:optional
-   Value type:   
-   Definition:   Interrupts associated with WLED. This should be
- "short" and "ovp" interrupts. Interrupts can be
- specified as per the encoding listed under
- Documentation/devicetree/bindings/spmi/
- qcom,spmi-pmic-arb.txt.
-
-- interrupt-names
-   Usage:optional
-   Value type:   
-   

[PATCH V6 2/4] backlight: qcom-wled: Add callback functions

2020-04-23 Thread Kiran Gunda
Add wled_cabc_config, wled_sync_toggle, wled_ovp_fault_status
and wled_ovp_delay and wled_auto_detection_required callback
functions to prepare the driver for adding WLED5 support.

Signed-off-by: Kiran Gunda 
Signed-off-by: Subbaraman Narayanamurthy 
Reviewed-by: Daniel Thompson 
---
 drivers/video/backlight/qcom-wled.c | 213 
 1 file changed, 141 insertions(+), 72 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index df53fbd..7b0095e 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -147,6 +147,7 @@ struct wled {
u32 max_brightness;
u32 short_count;
u32 auto_detect_count;
+   u32 version;
bool disabled_by_short;
bool has_short_detect;
int short_irq;
@@ -154,7 +155,30 @@ struct wled {
 
struct wled_config cfg;
struct delayed_work ovp_work;
+
+   /* Configures the brightness. Applicable for wled3, wled4 and wled5 */
int (*wled_set_brightness)(struct wled *wled, u16 brightness);
+
+   /* Configures the cabc register. Applicable for wled4 and wled5 */
+   int (*wled_cabc_config)(struct wled *wled, bool enable);
+
+   /*
+* Toggles the sync bit for the brightness update to take place.
+* Applicable for WLED3, WLED4 and WLED5.
+*/
+   int (*wled_sync_toggle)(struct wled *wled);
+
+   /*
+* Time to wait before checking the OVP status after wled module enable.
+* Applicable for WLED4 and WLED5.
+*/
+   int (*wled_ovp_delay)(struct wled *wled);
+
+   /*
+* Determines if the auto string detection is required.
+* Applicable for WLED4 and WLED5
+*/
+   bool (*wled_auto_detection_required)(struct wled *wled);
 };
 
 static int wled3_set_brightness(struct wled *wled, u16 brightness)
@@ -237,7 +261,7 @@ static int wled_module_enable(struct wled *wled, int val)
return 0;
 }
 
-static int wled_sync_toggle(struct wled *wled)
+static int wled3_sync_toggle(struct wled *wled)
 {
int rc;
unsigned int mask = GENMASK(wled->max_string_count - 1, 0);
@@ -255,6 +279,46 @@ static int wled_sync_toggle(struct wled *wled)
return rc;
 }
 
+static int wled_ovp_fault_status(struct wled *wled, bool *fault_set)
+{
+   int rc;
+   u32 int_rt_sts, fault_sts;
+
+   *fault_set = false;
+   rc = regmap_read(wled->regmap,
+   wled->ctrl_addr + WLED3_CTRL_REG_INT_RT_STS,
+   _rt_sts);
+   if (rc < 0) {
+   dev_err(wled->dev, "Failed to read INT_RT_STS rc=%d\n", rc);
+   return rc;
+   }
+
+   rc = regmap_read(wled->regmap,
+   wled->ctrl_addr + WLED3_CTRL_REG_FAULT_STATUS,
+   _sts);
+   if (rc < 0) {
+   dev_err(wled->dev, "Failed to read FAULT_STATUS rc=%d\n", rc);
+   return rc;
+   }
+
+   if (int_rt_sts & WLED3_CTRL_REG_OVP_FAULT_STATUS)
+   *fault_set = true;
+
+   if (fault_sts & WLED3_CTRL_REG_OVP_FAULT_BIT)
+   *fault_set = true;
+
+   if (*fault_set)
+   dev_dbg(wled->dev, "WLED OVP fault detected, int_rt_sts=0x%x 
fault_sts=0x%x\n",
+   int_rt_sts, fault_sts);
+
+   return rc;
+}
+
+static int wled4_ovp_delay(struct wled *wled)
+{
+   return WLED_SOFT_START_DLY_US;
+}
+
 static int wled_update_status(struct backlight_device *bl)
 {
struct wled *wled = bl_get_data(bl);
@@ -275,7 +339,7 @@ static int wled_update_status(struct backlight_device *bl)
goto unlock_mutex;
}
 
-   rc = wled_sync_toggle(wled);
+   rc = wled->wled_sync_toggle(wled);
if (rc < 0) {
dev_err(wled->dev, "wled sync failed rc:%d\n", rc);
goto unlock_mutex;
@@ -298,6 +362,25 @@ static int wled_update_status(struct backlight_device *bl)
return rc;
 }
 
+static int wled4_cabc_config(struct wled *wled, bool enable)
+{
+   int i, j, rc;
+   u8 val;
+
+   for (i = 0; i < wled->cfg.num_strings; i++) {
+   j = wled->cfg.enabled_strings[i];
+
+   val = enable ? WLED4_SINK_REG_STR_CABC_MASK : 0;
+   rc = regmap_update_bits(wled->regmap, wled->sink_addr +
+   WLED4_SINK_REG_STR_CABC(j),
+   WLED4_SINK_REG_STR_CABC_MASK, val);
+   if (rc < 0)
+   return rc;
+   }
+
+   return 0;
+}
+
 #define WLED_SHORT_DLY_MS  20
 #define WLED_SHORT_CNT_MAX 5
 #define WLED_SHORT_RESET_CNT_DLY_USUSEC_PER_SEC
@@ -345,9 +428,10 @@ static irqreturn_t wled_short_irq_hand

[PATCH V5 4/4] backlight: qcom-wled: Add support for WLED5 peripheral that is present on PM8150L PMICs

2020-04-08 Thread Kiran Gunda
From: Subbaraman Narayanamurthy 

PM8150L WLED supports the following:
- Two modulators and each sink can use any of the modulator
- Multiple CABC selection options from which one can be selected/enabled
- Multiple brightness width selection (12 bits to 15 bits)

Signed-off-by: Subbaraman Narayanamurthy 
Signed-off-by: Kiran Gunda 
---
 drivers/video/backlight/qcom-wled.c | 443 +++-
 1 file changed, 442 insertions(+), 1 deletion(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index a6ddaa9..3a57011 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -19,12 +19,15 @@
 #define WLED_DEFAULT_BRIGHTNESS2048
 #define WLED_SOFT_START_DLY_US 1
 #define WLED3_SINK_REG_BRIGHT_MAX  0xFFF
+#define WLED5_SINK_REG_BRIGHT_MAX_12B  0xFFF
+#define WLED5_SINK_REG_BRIGHT_MAX_15B  0x7FFF
 
 /* WLED3/WLED4 control registers */
 #define WLED3_CTRL_REG_FAULT_STATUS0x08
 #define  WLED3_CTRL_REG_ILIM_FAULT_BIT BIT(0)
 #define  WLED3_CTRL_REG_OVP_FAULT_BIT  BIT(1)
 #define  WLED4_CTRL_REG_SC_FAULT_BIT   BIT(2)
+#define  WLED5_CTRL_REG_OVP_PRE_ALARM_BIT  BIT(4)
 
 #define WLED3_CTRL_REG_INT_RT_STS  0x10
 #define  WLED3_CTRL_REG_OVP_FAULT_STATUS   BIT(1)
@@ -40,6 +43,7 @@
 
 #define WLED3_CTRL_REG_OVP 0x4d
 #define  WLED3_CTRL_REG_OVP_MASK   GENMASK(1, 0)
+#define  WLED5_CTRL_REG_OVP_MASK   GENMASK(3, 0)
 
 #define WLED3_CTRL_REG_ILIMIT  0x4e
 #define  WLED3_CTRL_REG_ILIMIT_MASKGENMASK(2, 0)
@@ -101,6 +105,44 @@
 
 #define WLED4_SINK_REG_BRIGHT(n)   (0x57 + (n * 0x10))
 
+/* WLED5 specific control registers */
+#define WLED5_CTRL_REG_OVP_INT_CTL 0x5f
+#define  WLED5_CTRL_REG_OVP_INT_TIMER_MASK GENMASK(2, 0)
+
+/* WLED5 specific sink registers */
+#define WLED5_SINK_REG_MOD_A_EN0x50
+#define WLED5_SINK_REG_MOD_B_EN0x60
+#define  WLED5_SINK_REG_MOD_EN_MASKBIT(7)
+
+#define WLED5_SINK_REG_MOD_A_SRC_SEL   0x51
+#define WLED5_SINK_REG_MOD_B_SRC_SEL   0x61
+#define  WLED5_SINK_REG_MOD_SRC_SEL_HIGH   0
+#define  WLED5_SINK_REG_MOD_SRC_SEL_EXT0x03
+#define  WLED5_SINK_REG_MOD_SRC_SEL_MASK   GENMASK(1, 0)
+
+#define WLED5_SINK_REG_MOD_A_BRIGHTNESS_WIDTH_SEL  0x52
+#define WLED5_SINK_REG_MOD_B_BRIGHTNESS_WIDTH_SEL  0x62
+#define  WLED5_SINK_REG_BRIGHTNESS_WIDTH_12B   0
+#define  WLED5_SINK_REG_BRIGHTNESS_WIDTH_15B   1
+
+#define WLED5_SINK_REG_MOD_A_BRIGHTNESS_LSB0x53
+#define WLED5_SINK_REG_MOD_A_BRIGHTNESS_MSB0x54
+#define WLED5_SINK_REG_MOD_B_BRIGHTNESS_LSB0x63
+#define WLED5_SINK_REG_MOD_B_BRIGHTNESS_MSB0x64
+
+#define WLED5_SINK_REG_MOD_SYNC_BIT0x65
+#define  WLED5_SINK_REG_SYNC_MOD_A_BIT BIT(0)
+#define  WLED5_SINK_REG_SYNC_MOD_B_BIT BIT(1)
+#define  WLED5_SINK_REG_SYNC_MASK  GENMASK(1, 0)
+
+/* WLED5 specific per-'string' registers below */
+#define WLED5_SINK_REG_STR_FULL_SCALE_CURR(n)  (0x72 + (n * 0x10))
+
+#define WLED5_SINK_REG_STR_SRC_SEL(n)  (0x73 + (n * 0x10))
+#define  WLED5_SINK_REG_SRC_SEL_MOD_A  0
+#define  WLED5_SINK_REG_SRC_SEL_MOD_B  1
+#define  WLED5_SINK_REG_SRC_SEL_MASK   GENMASK(1, 0)
+
 struct wled_var_cfg {
const u32 *values;
u32 (*fn)(u32);
@@ -125,6 +167,8 @@ struct wled_config {
u32 num_strings;
u32 string_i_limit;
u32 enabled_strings[WLED_MAX_STRINGS];
+   u32 mod_sel;
+   u32 cabc_sel;
bool cs_out_en;
bool ext_gen;
bool cabc;
@@ -150,6 +194,7 @@ struct wled {
u32 version;
bool disabled_by_short;
bool has_short_detect;
+   bool cabc_disabled;
int short_irq;
int ovp_irq;
 
@@ -184,6 +229,27 @@ struct wled {
bool (*wled_auto_detection_required)(struct wled *wled);
 };
 
+enum wled5_mod_sel {
+   MOD_A,
+   MOD_B,
+   MOD_MAX,
+};
+
+static const u8 wled5_brightness_reg[MOD_MAX] = {
+   [MOD_A] = WLED5_SINK_REG_MOD_A_BRIGHTNESS_LSB,
+   [MOD_B] = WLED5_SINK_REG_MOD_B_BRIGHTNESS_LSB,
+};
+
+static const u8 wled5_src_sel_reg[MOD_MAX] = {
+   [MOD_A] = WLED5_SINK_REG_MOD_A_SRC_SEL,
+   [MOD_B] = WLED5_SINK_REG_MOD_B_SRC_SEL,
+};
+
+static const u8 wled5_brt_wid_sel_reg[MOD_MAX] = {
+   [MOD_A] = WLED5_SINK_REG_MOD_A_BRIGHTNESS_WIDTH_SEL,
+   [MOD_B

[PATCH V5 0/4] Add support for WLED5

2020-04-08 Thread Kiran Gunda
Currently, WLED driver supports only WLED4 peripherals that is present
on pmi8998 and pm660L. This patch series  converts the existing WLED4
bindings from .txt to .yaml format and adds the support for WLED5 peripheral
that is present on PM8150L.

PM8150L WLED supports the following.
- Two modulators and each sink can use any of the modulator
- Multiple CABC selection options
- Multiple brightness width selection (12 bits to 15 bits)

Changes from V1:
- Rebased on top of the below commit.
  backlight: qcom-wled: Fix unsigned comparison to zero

Changes from V2:
- Addressed Bjorn's comments by splitting the WLED4 changes
  in a seperate patch.
- Added WLED5 auto calibration support

Changes from V3:
- Addressed comments from Daniel Thompson and Rob Herring
- Seperated the WLED5 bindings from the driver changes
- Squashed wled5 auto string detection and wled5 basic changes
  to avoid the NULL callback function pointer issue.

Changes from V4:
- Addressed the yaml formatting comments from Rob Herring.
- Addressed the comments from Daniel Thompson on the below patch
  "backlight: qcom-wled: Add callback functions"

Kiran Gunda (3):
  backlight: qcom-wled: convert the wled bindings to .yaml format
  backlight: qcom-wled: Add callback functions
  backlight: qcom-wled: Add WLED5 bindings

Subbaraman Narayanamurthy (1):
  backlight: qcom-wled: Add support for WLED5 peripheral that is present
on PM8150L PMICs

 .../bindings/leds/backlight/qcom-wled.txt  | 154 -
 .../bindings/leds/backlight/qcom-wled.yaml | 255 
 drivers/video/backlight/qcom-wled.c| 659 ++---
 3 files changed, 841 insertions(+), 227 deletions(-)
 delete mode 100644 
Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
 create mode 100644 
Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH V5 3/4] backlight: qcom-wled: Add WLED5 bindings

2020-04-08 Thread Kiran Gunda
Add WLED5 specific bindings.

Signed-off-by: Kiran Gunda 
Signed-off-by: Subbaraman Narayanamurthy 
---
 .../bindings/leds/backlight/qcom-wled.yaml | 60 --
 1 file changed, 57 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml 
b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml
index 770e780..5714631 100644
--- a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml
+++ b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml
@@ -21,6 +21,7 @@ properties:
   - qcom,pm8941-wled
   - qcom,pmi8998-wled
   - qcom,pm660l-wled
+  - qcom,pm8150l-wled
 
   reg:
 maxItems: 1
@@ -28,12 +29,13 @@ properties:
   default-brightness:
 description:
   brightness value on boot.
-minimum: 0
-maximum: 4095
-default: 2048
 
   label: true
 
+  max-brightness:
+description:
+  Maximum brightness level.
+
   qcom,cs-out:
 description:
   enable current sink output.
@@ -130,6 +132,31 @@ properties:
   This feature is not supported for WLED3.
 type: boolean
 
+  qcom,modulator-sel:
+description:
+  Selects the modulator used for brightness modulation.
+  Allowed values are,
+   0 - Modulator A
+   1 - Modulator B
+  This property is applicable only to WLED5 peripheral.
+allOf:
+  - $ref: /schemas/types.yaml#/definitions/uint32
+  - enum: [ 0, 1 ]
+  - default: 0
+
+  qcom,cabc-sel:
+description:
+  Selects the CABC pin signal used for brightness modulation.
+  Allowed values are,
+   0 - CABC disabled
+   1 - CABC 1
+   2 - CABC 2
+   3 - External signal (e.g. LPG) is used for dimming
+  This property is applicable only to WLED5 peripheral.
+allOf:
+  - $ref: /schemas/types.yaml#/definitions/uint32
+  - enum: [ 0, 1, 2, 3 ]
+
 allOf:
   - if:
   properties:
@@ -179,6 +206,33 @@ allOf:
 - const: ovp
 - const: short
 
+  - if:
+  properties:
+compatible:
+  contains:
+enum:
+  - qcom,pm8150l-wled
+
+then:
+  properties:
+default-brightness:
+  minimum: 0
+  maximum: 32767
+
+max-brightness:
+  minimum: 0
+  maximum: 32767
+
+else:
+  properties:
+default-brightness:
+minimum: 0
+maximum: 4095
+
+max-brightness:
+  minimum: 0
+  maximum: 4095
+
 required:
   - compatible
   - reg
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH V5 2/4] backlight: qcom-wled: Add callback functions

2020-04-08 Thread Kiran Gunda
Add wled_cabc_config, wled_sync_toggle, wled_ovp_fault_status
and wled_ovp_delay and wled_auto_detection_required callback
functions to prepare the driver for adding WLED5 support.

Signed-off-by: Kiran Gunda 
Signed-off-by: Subbaraman Narayanamurthy 
---
 drivers/video/backlight/qcom-wled.c | 216 
 1 file changed, 144 insertions(+), 72 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 3d276b3..a6ddaa9 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -147,6 +147,7 @@ struct wled {
u32 max_brightness;
u32 short_count;
u32 auto_detect_count;
+   u32 version;
bool disabled_by_short;
bool has_short_detect;
int short_irq;
@@ -154,7 +155,33 @@ struct wled {
 
struct wled_config cfg;
struct delayed_work ovp_work;
+
+   /* Configures the brightness. Applicable for wled3, wled4 and wled5 */
int (*wled_set_brightness)(struct wled *wled, u16 brightness);
+
+   /* Configures the cabc register. Applicable for wled4 and wled5 */
+   int (*wled_cabc_config)(struct wled *wled, bool enable);
+
+   /*
+* Toggles the sync bit for the brightness update to take place.
+* Applicable for WLED3, WLED4 and WLED5.
+*/
+   int (*wled_sync_toggle)(struct wled *wled);
+
+   /* Determines OVP fault status. Applicable for WLED4 and WLED5 */
+   int (*wled_ovp_fault_status)(struct wled *wled, bool *fault_set);
+
+   /*
+* Time to wait before checking the OVP status after wled module enable.
+* Applicable for WLED4 and WLED5.
+*/
+   int (*wled_ovp_delay)(struct wled *wled);
+
+   /*
+* Determines if the auto string detection is required.
+* Applicable for WLED4 and WLED5
+*/
+   bool (*wled_auto_detection_required)(struct wled *wled);
 };
 
 static int wled3_set_brightness(struct wled *wled, u16 brightness)
@@ -237,7 +264,7 @@ static int wled_module_enable(struct wled *wled, int val)
return 0;
 }
 
-static int wled_sync_toggle(struct wled *wled)
+static int wled3_sync_toggle(struct wled *wled)
 {
int rc;
unsigned int mask = GENMASK(wled->max_string_count - 1, 0);
@@ -255,6 +282,46 @@ static int wled_sync_toggle(struct wled *wled)
return rc;
 }
 
+static int wled4_ovp_fault_status(struct wled *wled, bool *fault_set)
+{
+   int rc;
+   u32 int_rt_sts, fault_sts;
+
+   *fault_set = false;
+   rc = regmap_read(wled->regmap,
+   wled->ctrl_addr + WLED3_CTRL_REG_INT_RT_STS,
+   _rt_sts);
+   if (rc < 0) {
+   dev_err(wled->dev, "Failed to read INT_RT_STS rc=%d\n", rc);
+   return rc;
+   }
+
+   rc = regmap_read(wled->regmap,
+   wled->ctrl_addr + WLED3_CTRL_REG_FAULT_STATUS,
+   _sts);
+   if (rc < 0) {
+   dev_err(wled->dev, "Failed to read FAULT_STATUS rc=%d\n", rc);
+   return rc;
+   }
+
+   if (int_rt_sts & WLED3_CTRL_REG_OVP_FAULT_STATUS)
+   *fault_set = true;
+
+   if (fault_sts & WLED3_CTRL_REG_OVP_FAULT_BIT)
+   *fault_set = true;
+
+   if (*fault_set)
+   dev_dbg(wled->dev, "WLED OVP fault detected, int_rt_sts=0x%x 
fault_sts=0x%x\n",
+   int_rt_sts, fault_sts);
+
+   return rc;
+}
+
+static int wled4_ovp_delay(struct wled *wled)
+{
+   return WLED_SOFT_START_DLY_US;
+}
+
 static int wled_update_status(struct backlight_device *bl)
 {
struct wled *wled = bl_get_data(bl);
@@ -275,7 +342,7 @@ static int wled_update_status(struct backlight_device *bl)
goto unlock_mutex;
}
 
-   rc = wled_sync_toggle(wled);
+   rc = wled->wled_sync_toggle(wled);
if (rc < 0) {
dev_err(wled->dev, "wled sync failed rc:%d\n", rc);
goto unlock_mutex;
@@ -298,6 +365,25 @@ static int wled_update_status(struct backlight_device *bl)
return rc;
 }
 
+static int wled4_cabc_config(struct wled *wled, bool enable)
+{
+   int i, j, rc;
+   u8 val;
+
+   for (i = 0; i < wled->cfg.num_strings; i++) {
+   j = wled->cfg.enabled_strings[i];
+
+   val = enable ? WLED4_SINK_REG_STR_CABC_MASK : 0;
+   rc = regmap_update_bits(wled->regmap, wled->sink_addr +
+   WLED4_SINK_REG_STR_CABC(j),
+   WLED4_SINK_REG_STR_CABC_MASK, val);
+   if (rc < 0)
+   return rc;
+   }
+
+   return 0;
+}
+
 #define WLED_SHORT_DLY_MS  20
 #define WLED_SHORT_CNT_MAX  

[PATCH V5 1/4] backlight: qcom-wled: convert the wled bindings to .yaml format

2020-04-08 Thread Kiran Gunda
Convert the qcom-wled bindings from .txt to .yaml format.
Also replace PM8941 to WLED3 and PMI8998 to WLED4.

Signed-off-by: Kiran Gunda 
Signed-off-by: Subbaraman Narayanamurthy 
Acked-by: Daniel Thompson 
---
 .../bindings/leds/backlight/qcom-wled.txt  | 154 
 .../bindings/leds/backlight/qcom-wled.yaml | 201 +
 2 files changed, 201 insertions(+), 154 deletions(-)
 delete mode 100644 
Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
 create mode 100644 
Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml

diff --git a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt 
b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
deleted file mode 100644
index c06863b..000
--- a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
+++ /dev/null
@@ -1,154 +0,0 @@
-Binding for Qualcomm Technologies, Inc. WLED driver
-
-WLED (White Light Emitting Diode) driver is used for controlling display
-backlight that is part of PMIC on Qualcomm Technologies, Inc. reference
-platforms. The PMIC is connected to the host processor via SPMI bus.
-
-- compatible
-   Usage:required
-   Value type:   
-   Definition:   should be one of:
-   "qcom,pm8941-wled"
-   "qcom,pmi8998-wled"
-   "qcom,pm660l-wled"
-
-- reg
-   Usage:required
-   Value type:   
-   Definition:   Base address of the WLED modules.
-
-- default-brightness
-   Usage:optional
-   Value type:   
-   Definition:   brightness value on boot, value from: 0-4095.
- Default: 2048
-
-- label
-   Usage:required
-   Value type:   
-   Definition:   The name of the backlight device
-
-- qcom,cs-out
-   Usage:optional
-   Value type:   
-   Definition:   enable current sink output.
- This property is supported only for PM8941.
-
-- qcom,cabc
-   Usage:optional
-   Value type:   
-   Definition:   enable content adaptive backlight control.
-
-- qcom,ext-gen
-   Usage:optional
-   Value type:   
-   Definition:   use externally generated modulator signal to dim.
- This property is supported only for PM8941.
-
-- qcom,current-limit
-   Usage:optional
-   Value type:   
-   Definition:   mA; per-string current limit; value from 0 to 25 with
- 1 mA step. Default 20 mA.
- This property is supported only for pm8941.
-
-- qcom,current-limit-microamp
-   Usage:optional
-   Value type:   
-   Definition:   uA; per-string current limit; value from 0 to 3 with
- 2500 uA step. Default 25 mA.
-
-- qcom,current-boost-limit
-   Usage:optional
-   Value type:   
-   Definition:   mA; boost current limit.
- For pm8941: one of: 105, 385, 525, 805, 980, 1260, 1400,
- 1680. Default: 805 mA.
- For pmi8998: one of: 105, 280, 450, 620, 970, 1150, 1300,
- 1500. Default: 970 mA.
-
-- qcom,switching-freq
-   Usage:optional
-   Value type:   
-Definition:   kHz; switching frequency; one of: 600, 640, 685, 738,
-  800, 872, 960, 1066, 1200, 1371, 1600, 1920, 2400, 3200,
-  4800, 9600.
-  Default: for pm8941: 1600 kHz
-   for pmi8998: 800 kHz
-
-- qcom,ovp
-   Usage:optional
-   Value type:   
-   Definition:   V; Over-voltage protection limit; one of:
- 27, 29, 32, 35. Default: 29V
- This property is supported only for PM8941.
-
-- qcom,ovp-millivolt
-   Usage:optional
-   Value type:   
-   Definition:   mV; Over-voltage protection limit;
- For pmi8998: one of 18100, 19600, 29600, 31100.
- Default 29600 mV.
- If this property is not specified for PM8941, it
- falls back to "qcom,ovp" property.
-
-- qcom,num-strings
-   Usage:optional
-   Value type:   
-   Definition:   #; number of led strings attached;
- value: For PM8941 from 1 to 3. Default: 2
-For PMI8998 from 1 to 4.
-
-- interrupts
-   Usage:optional
-   Value type:   
-   Definition:   Interrupts associated with WLED. This should be
- "short" and "ovp" interrupts. Interrupts can be
- specified as per the encoding listed under
- Documentation/devicetree/bindings/spmi/
- qcom,spmi-pmic-arb.txt.
-
-- interrupt-names
-   Usage:optional
-   Value type:   
-   

[PATCH V4 0/4] Add support for WLED5

2020-03-24 Thread Kiran Gunda
Currently, WLED driver supports only WLED4 peripherals that is present
on pmi8998 and pm660L. This patch series  converts the existing WLED4
bindings from .txt to .yaml format and adds the support for WLED5 peripheral
that is present on PM8150L.

PM8150L WLED supports the following.
- Two modulators and each sink can use any of the modulator
- Multiple CABC selection options
- Multiple brightness width selection (12 bits to 15 bits)

Changes from V1:
- Rebased on top of the below commit.
  backlight: qcom-wled: Fix unsigned comparison to zero

Changes from V2:
- Addressed Bjorn's comments by splitting the WLED4 changes
  in a seperate patch.
- Added WLED5 auto calibration support

Changes from V3:
- Addressed comments from Daniel Thompson and Rob Herring
- Seperated the WLED5 bindings from the driver changes
- Squashed wled5 auto string detection and wled5 basic changes
  to avoid the NULL callback function pointer issue.

Kiran Gunda (3):
  backlight: qcom-wled: convert the wled bindings to .yaml format
  backlight: qcom-wled: Add callback functions
  backlight: qcom-wled: Add WLED5 bindings

Subbaraman Narayanamurthy (1):
  backlight: qcom-wled: Add support for WLED5 peripheral in PM8150L

 .../bindings/leds/backlight/qcom-wled.txt  | 154 --
 .../bindings/leds/backlight/qcom-wled.yaml | 223 
 drivers/video/backlight/qcom-wled.c| 613 ++---
 3 files changed, 764 insertions(+), 226 deletions(-)
 delete mode 100644 
Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
 create mode 100644 
Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH V4 3/4] backlight: qcom-wled: Add WLED5 bindings

2020-03-24 Thread Kiran Gunda
Add WLED5 specific bindings.

Signed-off-by: Kiran Gunda 
Signed-off-by: Subbaraman Narayanamurthy 
---
 .../bindings/leds/backlight/qcom-wled.yaml | 39 ++
 1 file changed, 39 insertions(+)

diff --git a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml 
b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml
index 8a388bf..159115f 100644
--- a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml
+++ b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml
@@ -20,6 +20,7 @@ properties:
- qcom,pm8941-wled
- qcom,pmi8998-wled
- qcom,pm660l-wled
+   - qcom,pm8150l-wled
 
   reg:
 maxItems: 1
@@ -28,10 +29,23 @@ properties:
 maxItems: 1
 description:
   brightness value on boot, value from 0-4095.
+  For pm8150l this value vary from 0-4095 or 0-32767
+  depending on the brightness control mode. If CABC is
+  enabled 0-4095 range is used.
 allOf:
   - $ref: /schemas/types.yaml#/definitions/uint32
 default: 2048
 
+  max-brightness:
+maxItems: 1
+description:
+  Maximum brightness level. Allowed values are,
+  for pmi8998 it is  0-4095.
+  For pm8150l, this can be either 4095 or 32767.
+  If CABC is enabled, this is capped to 4095.
+allOf:
+  - $ref: /schemas/types.yaml#/definitions/uint32
+
   label:
 maxItems: 1
 description:
@@ -124,6 +138,31 @@ properties:
   value for PM8941 from 1 to 3. Default 2
   For PMI8998 from 1 to 4.
 
+  qcom,modulator-sel:
+maxItems: 1
+allOf:
+  - $ref: /schemas/types.yaml#/definitions/uint32
+description:
+  Selects the modulator used for brightness modulation.
+  Allowed values are,
+   0 - Modulator A
+   1 - Modulator B
+  If not specified, then modulator A will be used by default.
+  This property is applicable only to WLED5 peripheral.
+
+  qcom,cabc-sel:
+maxItems: 1
+allOf:
+  - $ref: /schemas/types.yaml#/definitions/uint32
+description:
+  Selects the CABC pin signal used for brightness modulation.
+  Allowed values are,
+  0 - CABC disabled
+  1 - CABC 1
+  2 - CABC 2
+  3 - External signal (e.g. LPG) is used for dimming
+  This property is applicable only to WLED5 peripheral.
+
   interrupts:
 maxItems: 2
 description:
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH V4 2/4] backlight: qcom-wled: Add callback functions

2020-03-24 Thread Kiran Gunda
Add wled_cabc_config, wled_sync_toggle, wled_ovp_fault_status
and wled_ovp_delay callback functions to prepare the driver for
adding WLED5 support.

wled_cabc_config() ===> Used to configure the cabc register.
 It is applicable for wled4 and wled5.

wled_sync_toggle() ===> used to toggle the Sync register bit for the
brightness update to take place.
It is applicable for WLED3, WLED4 and WLED5.

wled_ovp_fault_status() ===> Used to determine if the OVP fault is triggered.
 It is applicable for WLED4 and WLED5.

wled_ovp_delay() ===> Provides the time to wait before checking the OVP status
after wled module enable.
It is applicable for WLED4 and WLED5.

Signed-off-by: Kiran Gunda 
---
 drivers/video/backlight/qcom-wled.c | 188 ++--
 1 file changed, 118 insertions(+), 70 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 3d276b3..a3daf9e 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -147,6 +147,7 @@ struct wled {
u32 max_brightness;
u32 short_count;
u32 auto_detect_count;
+   u32 version;
bool disabled_by_short;
bool has_short_detect;
int short_irq;
@@ -155,6 +156,10 @@ struct wled {
struct wled_config cfg;
struct delayed_work ovp_work;
int (*wled_set_brightness)(struct wled *wled, u16 brightness);
+   int (*wled_cabc_config)(struct wled *wled, bool enable);
+   int (*wled_sync_toggle)(struct wled *wled);
+   int (*wled_ovp_fault_status)(struct wled *wled, bool *fault_set);
+   int (*wled_ovp_delay)(struct wled *wled);
 };
 
 static int wled3_set_brightness(struct wled *wled, u16 brightness)
@@ -237,7 +242,7 @@ static int wled_module_enable(struct wled *wled, int val)
return 0;
 }
 
-static int wled_sync_toggle(struct wled *wled)
+static int wled3_sync_toggle(struct wled *wled)
 {
int rc;
unsigned int mask = GENMASK(wled->max_string_count - 1, 0);
@@ -255,6 +260,46 @@ static int wled_sync_toggle(struct wled *wled)
return rc;
 }
 
+static int wled4_ovp_fault_status(struct wled *wled, bool *fault_set)
+{
+   int rc;
+   u32 int_rt_sts, fault_sts;
+
+   *fault_set = false;
+   rc = regmap_read(wled->regmap,
+   wled->ctrl_addr + WLED3_CTRL_REG_INT_RT_STS,
+   _rt_sts);
+   if (rc < 0) {
+   dev_err(wled->dev, "Failed to read INT_RT_STS rc=%d\n", rc);
+   return rc;
+   }
+
+   rc = regmap_read(wled->regmap,
+   wled->ctrl_addr + WLED3_CTRL_REG_FAULT_STATUS,
+   _sts);
+   if (rc < 0) {
+   dev_err(wled->dev, "Failed to read FAULT_STATUS rc=%d\n", rc);
+   return rc;
+   }
+
+   if (int_rt_sts & WLED3_CTRL_REG_OVP_FAULT_STATUS)
+   *fault_set = true;
+
+   if (fault_sts & WLED3_CTRL_REG_OVP_FAULT_BIT)
+   *fault_set = true;
+
+   if (*fault_set)
+   dev_dbg(wled->dev, "WLED OVP fault detected, int_rt_sts=0x%x 
fault_sts=0x%x\n",
+   int_rt_sts, fault_sts);
+
+   return rc;
+}
+
+static int wled4_ovp_delay(struct wled *wled)
+{
+   return WLED_SOFT_START_DLY_US;
+}
+
 static int wled_update_status(struct backlight_device *bl)
 {
struct wled *wled = bl_get_data(bl);
@@ -275,7 +320,7 @@ static int wled_update_status(struct backlight_device *bl)
goto unlock_mutex;
}
 
-   rc = wled_sync_toggle(wled);
+   rc = wled->wled_sync_toggle(wled);
if (rc < 0) {
dev_err(wled->dev, "wled sync failed rc:%d\n", rc);
goto unlock_mutex;
@@ -298,6 +343,25 @@ static int wled_update_status(struct backlight_device *bl)
return rc;
 }
 
+static int wled4_cabc_config(struct wled *wled, bool enable)
+{
+   int i, j, rc;
+   u8 val;
+
+   for (i = 0; i < wled->cfg.num_strings; i++) {
+   j = wled->cfg.enabled_strings[i];
+
+   val = enable ? WLED4_SINK_REG_STR_CABC_MASK : 0;
+   rc = regmap_update_bits(wled->regmap, wled->sink_addr +
+   WLED4_SINK_REG_STR_CABC(j),
+   WLED4_SINK_REG_STR_CABC_MASK, val);
+   if (rc < 0)
+   return rc;
+   }
+
+   return 0;
+}
+
 #define WLED_SHORT_DLY_MS  20
 #define WLED_SHORT_CNT_MAX 5
 #define WLED_SHORT_RESET_CNT_DLY_USUSEC_PER_SEC
@@ -345,9 +409,10 @@ static irqreturn_t wled_short_irq_handler(int 

[PATCH V4 4/4] backlight: qcom-wled: Add support for WLED5 peripheral in PM8150L

2020-03-24 Thread Kiran Gunda
From: Subbaraman Narayanamurthy 

Add support for WLED5 peripheral that is present on PM8150L PMICs.

PM8150L WLED supports the following:
- Two modulators and each sink can use any of the modulator
- Multiple CABC selection options from which one can be selected/enabled
- Multiple brightness width selection (12 bits to 15 bits)

Signed-off-by: Subbaraman Narayanamurthy 
Signed-off-by: Kiran Gunda 
---
 drivers/video/backlight/qcom-wled.c | 427 +++-
 1 file changed, 424 insertions(+), 3 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index a3daf9e..5a347ef 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -19,12 +19,15 @@
 #define WLED_DEFAULT_BRIGHTNESS2048
 #define WLED_SOFT_START_DLY_US 1
 #define WLED3_SINK_REG_BRIGHT_MAX  0xFFF
+#define WLED5_SINK_REG_BRIGHT_MAX_12B  0xFFF
+#define WLED5_SINK_REG_BRIGHT_MAX_15B  0x7FFF
 
 /* WLED3/WLED4 control registers */
 #define WLED3_CTRL_REG_FAULT_STATUS0x08
 #define  WLED3_CTRL_REG_ILIM_FAULT_BIT BIT(0)
 #define  WLED3_CTRL_REG_OVP_FAULT_BIT  BIT(1)
 #define  WLED4_CTRL_REG_SC_FAULT_BIT   BIT(2)
+#define  WLED5_CTRL_REG_OVP_PRE_ALARM_BIT  BIT(4)
 
 #define WLED3_CTRL_REG_INT_RT_STS  0x10
 #define  WLED3_CTRL_REG_OVP_FAULT_STATUS   BIT(1)
@@ -40,6 +43,7 @@
 
 #define WLED3_CTRL_REG_OVP 0x4d
 #define  WLED3_CTRL_REG_OVP_MASK   GENMASK(1, 0)
+#define  WLED5_CTRL_REG_OVP_MASK   GENMASK(3, 0)
 
 #define WLED3_CTRL_REG_ILIMIT  0x4e
 #define  WLED3_CTRL_REG_ILIMIT_MASKGENMASK(2, 0)
@@ -101,6 +105,44 @@
 
 #define WLED4_SINK_REG_BRIGHT(n)   (0x57 + (n * 0x10))
 
+/* WLED5 specific control registers */
+#define WLED5_CTRL_REG_OVP_INT_CTL 0x5f
+#define  WLED5_CTRL_REG_OVP_INT_TIMER_MASK GENMASK(2, 0)
+
+/* WLED5 specific sink registers */
+#define WLED5_SINK_REG_MOD_A_EN0x50
+#define WLED5_SINK_REG_MOD_B_EN0x60
+#define  WLED5_SINK_REG_MOD_EN_MASKBIT(7)
+
+#define WLED5_SINK_REG_MOD_A_SRC_SEL   0x51
+#define WLED5_SINK_REG_MOD_B_SRC_SEL   0x61
+#define  WLED5_SINK_REG_MOD_SRC_SEL_HIGH   0
+#define  WLED5_SINK_REG_MOD_SRC_SEL_EXT0x03
+#define  WLED5_SINK_REG_MOD_SRC_SEL_MASK   GENMASK(1, 0)
+
+#define WLED5_SINK_REG_MOD_A_BRIGHTNESS_WIDTH_SEL  0x52
+#define WLED5_SINK_REG_MOD_B_BRIGHTNESS_WIDTH_SEL  0x62
+#define  WLED5_SINK_REG_BRIGHTNESS_WIDTH_12B   0
+#define  WLED5_SINK_REG_BRIGHTNESS_WIDTH_15B   1
+
+#define WLED5_SINK_REG_MOD_A_BRIGHTNESS_LSB0x53
+#define WLED5_SINK_REG_MOD_A_BRIGHTNESS_MSB0x54
+#define WLED5_SINK_REG_MOD_B_BRIGHTNESS_LSB0x63
+#define WLED5_SINK_REG_MOD_B_BRIGHTNESS_MSB0x64
+
+#define WLED5_SINK_REG_MOD_SYNC_BIT0x65
+#define  WLED5_SINK_REG_SYNC_MOD_A_BIT BIT(0)
+#define  WLED5_SINK_REG_SYNC_MOD_B_BIT BIT(1)
+#define  WLED5_SINK_REG_SYNC_MASK  GENMASK(1, 0)
+
+/* WLED5 specific per-'string' registers below */
+#define WLED5_SINK_REG_STR_FULL_SCALE_CURR(n)  (0x72 + (n * 0x10))
+
+#define WLED5_SINK_REG_STR_SRC_SEL(n)  (0x73 + (n * 0x10))
+#define  WLED5_SINK_REG_SRC_SEL_MOD_A  0
+#define  WLED5_SINK_REG_SRC_SEL_MOD_B  1
+#define  WLED5_SINK_REG_SRC_SEL_MASK   GENMASK(1, 0)
+
 struct wled_var_cfg {
const u32 *values;
u32 (*fn)(u32);
@@ -125,6 +167,8 @@ struct wled_config {
u32 num_strings;
u32 string_i_limit;
u32 enabled_strings[WLED_MAX_STRINGS];
+   u32 mod_sel;
+   u32 cabc_sel;
bool cs_out_en;
bool ext_gen;
bool cabc;
@@ -150,6 +194,7 @@ struct wled {
u32 version;
bool disabled_by_short;
bool has_short_detect;
+   bool cabc_disabled;
int short_irq;
int ovp_irq;
 
@@ -162,6 +207,27 @@ struct wled {
int (*wled_ovp_delay)(struct wled *wled);
 };
 
+enum wled5_mod_sel {
+   MOD_A,
+   MOD_B,
+   MOD_MAX,
+};
+
+static const u8 wled5_brightness_reg[MOD_MAX] = {
+   [MOD_A] = WLED5_SINK_REG_MOD_A_BRIGHTNESS_LSB,
+   [MOD_B] = WLED5_SINK_REG_MOD_B_BRIGHTNESS_LSB,
+};
+
+static const u8 wled5_src_sel_reg[MOD_MAX] = {
+   [MOD_A] = WLED5_SINK_REG_MOD_A_SRC_SEL,
+   [MOD_B] = WLED5_SINK_REG_MOD_B_SRC_SEL,
+};
+
+static const u8 wled5_brt_wid_sel_reg[MOD_MAX] = {
+   [MOD_A

[PATCH V4 1/4] backlight: qcom-wled: convert the wled bindings to .yaml format

2020-03-24 Thread Kiran Gunda
Convert the qcom-wled bindings from .txt to .yaml format.

Signed-off-by: Kiran Gunda 
Signed-off-by: Subbaraman Narayanamurthy 
Acked-by: Daniel Thompson 
---
 .../bindings/leds/backlight/qcom-wled.txt  | 154 -
 .../bindings/leds/backlight/qcom-wled.yaml | 184 +
 2 files changed, 184 insertions(+), 154 deletions(-)
 delete mode 100644 
Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
 create mode 100644 
Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml

diff --git a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt 
b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
deleted file mode 100644
index c06863b..000
--- a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
+++ /dev/null
@@ -1,154 +0,0 @@
-Binding for Qualcomm Technologies, Inc. WLED driver
-
-WLED (White Light Emitting Diode) driver is used for controlling display
-backlight that is part of PMIC on Qualcomm Technologies, Inc. reference
-platforms. The PMIC is connected to the host processor via SPMI bus.
-
-- compatible
-   Usage:required
-   Value type:   
-   Definition:   should be one of:
-   "qcom,pm8941-wled"
-   "qcom,pmi8998-wled"
-   "qcom,pm660l-wled"
-
-- reg
-   Usage:required
-   Value type:   
-   Definition:   Base address of the WLED modules.
-
-- default-brightness
-   Usage:optional
-   Value type:   
-   Definition:   brightness value on boot, value from: 0-4095.
- Default: 2048
-
-- label
-   Usage:required
-   Value type:   
-   Definition:   The name of the backlight device
-
-- qcom,cs-out
-   Usage:optional
-   Value type:   
-   Definition:   enable current sink output.
- This property is supported only for PM8941.
-
-- qcom,cabc
-   Usage:optional
-   Value type:   
-   Definition:   enable content adaptive backlight control.
-
-- qcom,ext-gen
-   Usage:optional
-   Value type:   
-   Definition:   use externally generated modulator signal to dim.
- This property is supported only for PM8941.
-
-- qcom,current-limit
-   Usage:optional
-   Value type:   
-   Definition:   mA; per-string current limit; value from 0 to 25 with
- 1 mA step. Default 20 mA.
- This property is supported only for pm8941.
-
-- qcom,current-limit-microamp
-   Usage:optional
-   Value type:   
-   Definition:   uA; per-string current limit; value from 0 to 3 with
- 2500 uA step. Default 25 mA.
-
-- qcom,current-boost-limit
-   Usage:optional
-   Value type:   
-   Definition:   mA; boost current limit.
- For pm8941: one of: 105, 385, 525, 805, 980, 1260, 1400,
- 1680. Default: 805 mA.
- For pmi8998: one of: 105, 280, 450, 620, 970, 1150, 1300,
- 1500. Default: 970 mA.
-
-- qcom,switching-freq
-   Usage:optional
-   Value type:   
-Definition:   kHz; switching frequency; one of: 600, 640, 685, 738,
-  800, 872, 960, 1066, 1200, 1371, 1600, 1920, 2400, 3200,
-  4800, 9600.
-  Default: for pm8941: 1600 kHz
-   for pmi8998: 800 kHz
-
-- qcom,ovp
-   Usage:optional
-   Value type:   
-   Definition:   V; Over-voltage protection limit; one of:
- 27, 29, 32, 35. Default: 29V
- This property is supported only for PM8941.
-
-- qcom,ovp-millivolt
-   Usage:optional
-   Value type:   
-   Definition:   mV; Over-voltage protection limit;
- For pmi8998: one of 18100, 19600, 29600, 31100.
- Default 29600 mV.
- If this property is not specified for PM8941, it
- falls back to "qcom,ovp" property.
-
-- qcom,num-strings
-   Usage:optional
-   Value type:   
-   Definition:   #; number of led strings attached;
- value: For PM8941 from 1 to 3. Default: 2
-For PMI8998 from 1 to 4.
-
-- interrupts
-   Usage:optional
-   Value type:   
-   Definition:   Interrupts associated with WLED. This should be
- "short" and "ovp" interrupts. Interrupts can be
- specified as per the encoding listed under
- Documentation/devicetree/bindings/spmi/
- qcom,spmi-pmic-arb.txt.
-
-- interrupt-names
-   Usage:optional
-   Value type:   
-   Definition:   Interrupt names associated with the interrupts

[PATCH V3 0/4] Add support for WLED5

2020-03-10 Thread Kiran Gunda


Currently, WLED driver supports only WLED4 peripherals that is present
on pmi8998 and pm660L. This patch series  converts the existing WLED4
bindings from .txt to .yaml format and adds the support for WLED5 peripheral
that is present on PM8150L.

PM8150L WLED supports the following.
- Two modulators and each sink can use any of the modulator
- Multiple CABC selection options
- Multiple brightness width selection (12 bits to 15 bits)

Changes from V1:
- Rebased on top of the below commit.
  backlight: qcom-wled: Fix unsigned comparison to zero

Changes from V2:
- Addressed Bjorn's comments by splitting the WLED4 changes
  in a seperate patch.
- Added WLED5 auto calibration support

Kiran Gunda (4):
  backlight: qcom-wled: convert the wled bindings to .yaml format
  backlight: qcom-wled: Add callbacks functions
  backlight: qcom-wled: Add support for WLED5 peripheral in PM8150L
  backlight: qcom-wled: Update auto calibration support for WLED5

 .../bindings/leds/backlight/qcom-wled.txt  | 154 -
 .../bindings/leds/backlight/qcom-wled.yaml | 223 
 drivers/video/backlight/qcom-wled.c| 622 ++---
 3 files changed, 772 insertions(+), 227 deletions(-)
 delete mode 100644 
Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
 create mode 100644 
Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH V3 4/4] backlight: qcom-wled: Update auto calibration support for WLED5

2020-03-10 Thread Kiran Gunda
Currently, auto calibration logic checks only for OVP_FAULT bit
to be set in FAULT_STATUS register to detect OVP fault. This works
well for WLED4 type. However, WLED5 type has OVP_PRE_ALARM bit
which can indicate a potential OVP fault. Use that as well for
detecting OVP fault and run auto calibration to fix the sink
configuration.

Signed-off-by: Kiran Gunda 
---
 drivers/video/backlight/qcom-wled.c | 90 -
 1 file changed, 88 insertions(+), 2 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index edbbcb2..5079f1f 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -27,6 +27,7 @@
 #define  WLED3_CTRL_REG_ILIM_FAULT_BIT BIT(0)
 #define  WLED3_CTRL_REG_OVP_FAULT_BIT  BIT(1)
 #define  WLED4_CTRL_REG_SC_FAULT_BIT   BIT(2)
+#define  WLED5_CTRL_REG_OVP_PRE_ALARM_BIT  BIT(4)
 
 #define WLED3_CTRL_REG_INT_RT_STS  0x10
 #define  WLED3_CTRL_REG_OVP_FAULT_STATUS   BIT(1)
@@ -104,6 +105,10 @@
 
 #define WLED4_SINK_REG_BRIGHT(n)   (0x57 + (n * 0x10))
 
+/* WLED5 specific control registers */
+#define WLED5_CTRL_REG_OVP_INT_CTL 0x5f
+#define  WLED5_CTRL_REG_OVP_INT_TIMER_MASK GENMASK(2, 0)
+
 /* WLED5 specific sink registers */
 #define WLED5_SINK_REG_MOD_A_EN0x50
 #define WLED5_SINK_REG_MOD_B_EN0x60
@@ -394,11 +399,67 @@ static int wled4_ovp_fault_status(struct wled *wled, bool 
*fault_set)
return rc;
 }
 
+static int wled5_ovp_fault_status(struct wled *wled, bool *fault_set)
+{
+   int rc;
+   u32 int_rt_sts, fault_sts;
+
+   *fault_set = false;
+   rc = regmap_read(wled->regmap,
+   wled->ctrl_addr + WLED3_CTRL_REG_INT_RT_STS,
+   _rt_sts);
+   if (rc < 0) {
+   dev_err(wled->dev, "Failed to read INT_RT_STS rc=%d\n", rc);
+   return rc;
+   }
+
+   rc = regmap_read(wled->regmap,
+   wled->ctrl_addr + WLED3_CTRL_REG_FAULT_STATUS,
+   _sts);
+   if (rc < 0) {
+   dev_err(wled->dev, "Failed to read FAULT_STATUS rc=%d\n", rc);
+   return rc;
+   }
+
+   if (int_rt_sts & WLED3_CTRL_REG_OVP_FAULT_STATUS)
+   *fault_set = true;
+
+   if (fault_sts & (WLED3_CTRL_REG_OVP_FAULT_BIT |
+  WLED5_CTRL_REG_OVP_PRE_ALARM_BIT))
+   *fault_set = true;
+
+   if (*fault_set)
+   dev_dbg(wled->dev, "WLED OVP fault detected, int_rt_sts=0x%x 
fault_sts=0x%x\n",
+   int_rt_sts, fault_sts);
+
+   return rc;
+}
+
 static int wled4_ovp_delay(struct wled *wled)
 {
return WLED_SOFT_START_DLY_US;
 }
 
+static int wled5_ovp_delay(struct wled *wled)
+{
+   int rc, delay_us;
+   u32 val;
+   u8 ovp_timer_ms[8] = {1, 2, 4, 8, 12, 16, 20, 24};
+
+   /* For WLED5, get the delay based on OVP timer */
+   rc = regmap_read(wled->regmap, wled->ctrl_addr +
+WLED5_CTRL_REG_OVP_INT_CTL, );
+   if (rc < 0)
+   delay_us =
+   ovp_timer_ms[val & WLED5_CTRL_REG_OVP_INT_TIMER_MASK] * 1000;
+   else
+   delay_us = 2 * WLED_SOFT_START_DLY_US;
+
+   dev_dbg(wled->dev, "delay_time_us: %d\n", *delay_us);
+
+   return delay_us;
+}
+
 static int wled_update_status(struct backlight_device *bl)
 {
struct wled *wled = bl_get_data(bl);
@@ -736,9 +797,32 @@ static bool wled_auto_detection_required(struct wled *wled)
if (!wled->auto_detection_ovp_count) {
wled->start_ovp_fault_time = ktime_get();
wled->auto_detection_ovp_count++;
-   } else {
+   return false;
+   }
+
+   if (wled->version == 5) {
+   /*
+* WLED5 has OVP fault density interrupt configuration i.e. to
+* count the number of OVP alarms for a certain duration before
+* triggering OVP fault interrupt. By default, number of OVP
+* fault events counted before an interrupt is fired is 32 and
+* the time interval is 12 ms. If we see more than one OVP fault
+* interrupt, then that should qualify for a real OVP fault
+* condition to run auto calibration algorithm.
+*/
+
+   if (wled->auto_detection_ovp_count > 1) {
+   elapsed_time_us = ktime_us_delta(ktime_get(),
+   wled->start_ovp_fault_time);
+   wled->auto_detection_ovp_count = 0;
+   dev_dbg(wled->

[PATCH V3 1/4] backlight: qcom-wled: convert the wled bindings to .yaml format

2020-03-10 Thread Kiran Gunda
Convert the qcom-wled bindings from .txt to .yaml format.

Signed-off-by: Kiran Gunda 
---
 .../bindings/leds/backlight/qcom-wled.txt  | 154 -
 .../bindings/leds/backlight/qcom-wled.yaml | 184 +
 2 files changed, 184 insertions(+), 154 deletions(-)
 delete mode 100644 
Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
 create mode 100644 
Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml

diff --git a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt 
b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
deleted file mode 100644
index c06863b..000
--- a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
+++ /dev/null
@@ -1,154 +0,0 @@
-Binding for Qualcomm Technologies, Inc. WLED driver
-
-WLED (White Light Emitting Diode) driver is used for controlling display
-backlight that is part of PMIC on Qualcomm Technologies, Inc. reference
-platforms. The PMIC is connected to the host processor via SPMI bus.
-
-- compatible
-   Usage:required
-   Value type:   
-   Definition:   should be one of:
-   "qcom,pm8941-wled"
-   "qcom,pmi8998-wled"
-   "qcom,pm660l-wled"
-
-- reg
-   Usage:required
-   Value type:   
-   Definition:   Base address of the WLED modules.
-
-- default-brightness
-   Usage:optional
-   Value type:   
-   Definition:   brightness value on boot, value from: 0-4095.
- Default: 2048
-
-- label
-   Usage:required
-   Value type:   
-   Definition:   The name of the backlight device
-
-- qcom,cs-out
-   Usage:optional
-   Value type:   
-   Definition:   enable current sink output.
- This property is supported only for PM8941.
-
-- qcom,cabc
-   Usage:optional
-   Value type:   
-   Definition:   enable content adaptive backlight control.
-
-- qcom,ext-gen
-   Usage:optional
-   Value type:   
-   Definition:   use externally generated modulator signal to dim.
- This property is supported only for PM8941.
-
-- qcom,current-limit
-   Usage:optional
-   Value type:   
-   Definition:   mA; per-string current limit; value from 0 to 25 with
- 1 mA step. Default 20 mA.
- This property is supported only for pm8941.
-
-- qcom,current-limit-microamp
-   Usage:optional
-   Value type:   
-   Definition:   uA; per-string current limit; value from 0 to 3 with
- 2500 uA step. Default 25 mA.
-
-- qcom,current-boost-limit
-   Usage:optional
-   Value type:   
-   Definition:   mA; boost current limit.
- For pm8941: one of: 105, 385, 525, 805, 980, 1260, 1400,
- 1680. Default: 805 mA.
- For pmi8998: one of: 105, 280, 450, 620, 970, 1150, 1300,
- 1500. Default: 970 mA.
-
-- qcom,switching-freq
-   Usage:optional
-   Value type:   
-Definition:   kHz; switching frequency; one of: 600, 640, 685, 738,
-  800, 872, 960, 1066, 1200, 1371, 1600, 1920, 2400, 3200,
-  4800, 9600.
-  Default: for pm8941: 1600 kHz
-   for pmi8998: 800 kHz
-
-- qcom,ovp
-   Usage:optional
-   Value type:   
-   Definition:   V; Over-voltage protection limit; one of:
- 27, 29, 32, 35. Default: 29V
- This property is supported only for PM8941.
-
-- qcom,ovp-millivolt
-   Usage:optional
-   Value type:   
-   Definition:   mV; Over-voltage protection limit;
- For pmi8998: one of 18100, 19600, 29600, 31100.
- Default 29600 mV.
- If this property is not specified for PM8941, it
- falls back to "qcom,ovp" property.
-
-- qcom,num-strings
-   Usage:optional
-   Value type:   
-   Definition:   #; number of led strings attached;
- value: For PM8941 from 1 to 3. Default: 2
-For PMI8998 from 1 to 4.
-
-- interrupts
-   Usage:optional
-   Value type:   
-   Definition:   Interrupts associated with WLED. This should be
- "short" and "ovp" interrupts. Interrupts can be
- specified as per the encoding listed under
- Documentation/devicetree/bindings/spmi/
- qcom,spmi-pmic-arb.txt.
-
-- interrupt-names
-   Usage:optional
-   Value type:   
-   Definition:   Interrupt names associated with the interrupts.
- Must be "short" and "ovp"

[PATCH V3 3/4] backlight: qcom-wled: Add support for WLED5 peripheral in PM8150L

2020-03-10 Thread Kiran Gunda
Add support for WLED5 peripheral that is present on PM8150L PMICs.

PM8150L WLED supports the following:
- Two modulators and each sink can use any of the modulator
- Multiple CABC selection options
- Multiple brightness width selection (12 bits to 15 bits)

Signed-off-by: Kiran Gunda 
---
 .../bindings/leds/backlight/qcom-wled.yaml |  39 +++
 drivers/video/backlight/qcom-wled.c| 336 -
 2 files changed, 374 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml 
b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml
index d334f81..e0dadc4 100644
--- a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml
+++ b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml
@@ -20,6 +20,7 @@ properties:
- qcom,pm8941-wled
- qcom,pmi8998-wled
- qcom,pm660l-wled
+   - qcom,pm8150l-wled
 
   reg:
 maxItems: 1
@@ -28,10 +29,23 @@ properties:
 maxItems: 1
 description:
   brightness value on boot, value from 0-4095.
+  For pm8150l this value vary from 0-4095 or 0-32767
+  depending on the brightness control mode. If CABC is
+  enabled 0-4095 range is used.
 allOf:
   - $ref: /schemas/types.yaml#/definitions/uint32
 default: 2048
 
+  max-brightness:
+maxItems: 1
+description:
+  Maximum brightness level. Allowed values are,
+  for pmi8998 it is  0-4095.
+  For pm8150l, this can be either 4095 or 32767.
+  If CABC is enabled, this is capped to 4095.
+allOf:
+  - $ref: /schemas/types.yaml#/definitions/uint32
+
   label:
 maxItems: 1
 description:
@@ -124,6 +138,31 @@ properties:
   value for PM8941 from 1 to 3. Default 2
   For PMI8998 from 1 to 4.
 
+  qcom,modulator-sel:
+maxItems: 1
+allOf:
+  - $ref: /schemas/types.yaml#/definitions/uint32
+description:
+  Selects the modulator used for brightness modulation.
+  Allowed values are,
+   0 - Modulator A
+   1 - Modulator B
+  If not specified, then modulator A will be used by default.
+  This property is applicable only to WLED5 peripheral.
+
+  qcom,cabc-sel:
+maxItems: 1
+allOf:
+  - $ref: /schemas/types.yaml#/definitions/uint32
+description:
+  Selects the CABC pin signal used for brightness modulation.
+  Allowed values are,
+  0 - CABC disabled
+  1 - CABC 1
+  2 - CABC 2
+  3 - External signal (e.g. LPG) is used for dimming
+  This property is applicable only to WLED5 peripheral.
+
   interrupts:
 maxItems: 2
 description:
diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index b73f273..edbbcb2 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -19,6 +19,8 @@
 #define WLED_DEFAULT_BRIGHTNESS2048
 #define WLED_SOFT_START_DLY_US 1
 #define WLED3_SINK_REG_BRIGHT_MAX  0xFFF
+#define WLED5_SINK_REG_BRIGHT_MAX_12B  0xFFF
+#define WLED5_SINK_REG_BRIGHT_MAX_15B  0x7FFF
 
 /* WLED3/WLED4 control registers */
 #define WLED3_CTRL_REG_FAULT_STATUS0x08
@@ -40,6 +42,7 @@
 
 #define WLED3_CTRL_REG_OVP 0x4d
 #define  WLED3_CTRL_REG_OVP_MASK   GENMASK(1, 0)
+#define  WLED5_CTRL_REG_OVP_MASK   GENMASK(3, 0)
 
 #define WLED3_CTRL_REG_ILIMIT  0x4e
 #define  WLED3_CTRL_REG_ILIMIT_MASKGENMASK(2, 0)
@@ -101,6 +104,40 @@
 
 #define WLED4_SINK_REG_BRIGHT(n)   (0x57 + (n * 0x10))
 
+/* WLED5 specific sink registers */
+#define WLED5_SINK_REG_MOD_A_EN0x50
+#define WLED5_SINK_REG_MOD_B_EN0x60
+#define  WLED5_SINK_REG_MOD_EN_MASKBIT(7)
+
+#define WLED5_SINK_REG_MOD_A_SRC_SEL   0x51
+#define WLED5_SINK_REG_MOD_B_SRC_SEL   0x61
+#define  WLED5_SINK_REG_MOD_SRC_SEL_HIGH   0
+#define  WLED5_SINK_REG_MOD_SRC_SEL_EXT0x03
+#define  WLED5_SINK_REG_MOD_SRC_SEL_MASK   GENMASK(1, 0)
+
+#define WLED5_SINK_REG_MOD_A_BRIGHTNESS_WIDTH_SEL  0x52
+#define WLED5_SINK_REG_MOD_B_BRIGHTNESS_WIDTH_SEL  0x62
+#define  WLED5_SINK_REG_BRIGHTNESS_WIDTH_12B   0
+#define  WLED5_SINK_REG_BRIGHTNESS_WIDTH_15B   1
+
+#define WLED5_SINK_REG_MOD_A_BRIGHTNESS_LSB0x53
+#define WLED5_SINK_REG_MOD_A_BRIGHTNESS_MSB0x54
+#define WLED5_SINK_REG_MOD_B_BRIGHTNESS_LSB0x63
+#define WLED5_SINK_REG_MOD_B_BRIGHTNESS_MSB0x64
+
+#define WLED5_SINK_REG_MOD_SYNC_BIT0x65
+#define  WLED5_SINK_REG_SYNC_MOD_A_BIT BIT(0)
+#define

[PATCH V3 2/4] backlight: qcom-wled: Add callback functions

2020-03-10 Thread Kiran Gunda
Add cabc_config, sync_toggle, wled_ovp_fault_status and wled_ovp_delay
callback functions to prepare the driver for adding WLED5 support.

Signed-off-by: Kiran Gunda 
---
 drivers/video/backlight/qcom-wled.c | 196 +++-
 1 file changed, 126 insertions(+), 70 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 3d276b3..b73f273 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -128,6 +128,7 @@ struct wled_config {
bool cs_out_en;
bool ext_gen;
bool cabc;
+   bool en_cabc;
bool external_pfet;
bool auto_detection_enabled;
 };
@@ -147,14 +148,20 @@ struct wled {
u32 max_brightness;
u32 short_count;
u32 auto_detect_count;
+   u32 version;
bool disabled_by_short;
bool has_short_detect;
+   bool cabc_disabled;
int short_irq;
int ovp_irq;
 
struct wled_config cfg;
struct delayed_work ovp_work;
int (*wled_set_brightness)(struct wled *wled, u16 brightness);
+   int (*cabc_config)(struct wled *wled, bool enable);
+   int (*wled_sync_toggle)(struct wled *wled);
+   int (*wled_ovp_fault_status)(struct wled *wled, bool *fault_set);
+   int (*wled_ovp_delay)(struct wled *wled);
 };
 
 static int wled3_set_brightness(struct wled *wled, u16 brightness)
@@ -237,7 +244,7 @@ static int wled_module_enable(struct wled *wled, int val)
return 0;
 }
 
-static int wled_sync_toggle(struct wled *wled)
+static int wled3_sync_toggle(struct wled *wled)
 {
int rc;
unsigned int mask = GENMASK(wled->max_string_count - 1, 0);
@@ -255,6 +262,46 @@ static int wled_sync_toggle(struct wled *wled)
return rc;
 }
 
+static int wled4_ovp_fault_status(struct wled *wled, bool *fault_set)
+{
+   int rc;
+   u32 int_rt_sts, fault_sts;
+
+   *fault_set = false;
+   rc = regmap_read(wled->regmap,
+   wled->ctrl_addr + WLED3_CTRL_REG_INT_RT_STS,
+   _rt_sts);
+   if (rc < 0) {
+   dev_err(wled->dev, "Failed to read INT_RT_STS rc=%d\n", rc);
+   return rc;
+   }
+
+   rc = regmap_read(wled->regmap,
+   wled->ctrl_addr + WLED3_CTRL_REG_FAULT_STATUS,
+   _sts);
+   if (rc < 0) {
+   dev_err(wled->dev, "Failed to read FAULT_STATUS rc=%d\n", rc);
+   return rc;
+   }
+
+   if (int_rt_sts & WLED3_CTRL_REG_OVP_FAULT_STATUS)
+   *fault_set = true;
+
+   if (fault_sts & WLED3_CTRL_REG_OVP_FAULT_BIT)
+   *fault_set = true;
+
+   if (*fault_set)
+   dev_dbg(wled->dev, "WLED OVP fault detected, int_rt_sts=0x%x 
fault_sts=0x%x\n",
+   int_rt_sts, fault_sts);
+
+   return rc;
+}
+
+static int wled4_ovp_delay(struct wled *wled)
+{
+   return WLED_SOFT_START_DLY_US;
+}
+
 static int wled_update_status(struct backlight_device *bl)
 {
struct wled *wled = bl_get_data(bl);
@@ -275,7 +322,7 @@ static int wled_update_status(struct backlight_device *bl)
goto unlock_mutex;
}
 
-   rc = wled_sync_toggle(wled);
+   rc = wled->wled_sync_toggle(wled);
if (rc < 0) {
dev_err(wled->dev, "wled sync failed rc:%d\n", rc);
goto unlock_mutex;
@@ -298,6 +345,31 @@ static int wled_update_status(struct backlight_device *bl)
return rc;
 }
 
+static int wled4_cabc_config(struct wled *wled, bool enable)
+{
+   int i, j, rc;
+   u8 val;
+
+   if (wled->cabc_disabled)
+   return 0;
+
+   for (i = 0; i < wled->cfg.num_strings; i++) {
+   j = wled->cfg.enabled_strings[i];
+
+   val = enable ? WLED4_SINK_REG_STR_CABC_MASK : 0;
+   rc = regmap_update_bits(wled->regmap, wled->sink_addr +
+   WLED4_SINK_REG_STR_CABC(j),
+   WLED4_SINK_REG_STR_CABC_MASK, val);
+   if (rc < 0)
+   return rc;
+   }
+
+   if (!wled->cfg.en_cabc)
+   wled->cabc_disabled = true;
+
+   return 0;
+}
+
 #define WLED_SHORT_DLY_MS  20
 #define WLED_SHORT_CNT_MAX 5
 #define WLED_SHORT_RESET_CNT_DLY_USUSEC_PER_SEC
@@ -345,9 +417,10 @@ static irqreturn_t wled_short_irq_handler(int irq, void 
*_wled)
 
 static void wled_auto_string_detection(struct wled *wled)
 {
-   int rc = 0, i;
-   u32 sink_config = 0, int_sts;
+   int rc = 0, i, delay_time_us;
+   u32 sink_config = 0;
u8 sink_test = 0, sink_valid = 0, val;
+   bool fault_set;
 
/* Read configur

[PATCH V2 1/2] backlight: qcom-wled: convert the wled bindings to .yaml format

2020-03-05 Thread Kiran Gunda
Convert the qcom-wled bindings from .txt to .yaml format.

Signed-off-by: Kiran Gunda 
---
 .../bindings/leds/backlight/qcom-wled.txt  | 154 -
 .../bindings/leds/backlight/qcom-wled.yaml | 184 +
 2 files changed, 184 insertions(+), 154 deletions(-)
 delete mode 100644 
Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
 create mode 100644 
Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml

diff --git a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt 
b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
deleted file mode 100644
index c06863b..000
--- a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
+++ /dev/null
@@ -1,154 +0,0 @@
-Binding for Qualcomm Technologies, Inc. WLED driver
-
-WLED (White Light Emitting Diode) driver is used for controlling display
-backlight that is part of PMIC on Qualcomm Technologies, Inc. reference
-platforms. The PMIC is connected to the host processor via SPMI bus.
-
-- compatible
-   Usage:required
-   Value type:   
-   Definition:   should be one of:
-   "qcom,pm8941-wled"
-   "qcom,pmi8998-wled"
-   "qcom,pm660l-wled"
-
-- reg
-   Usage:required
-   Value type:   
-   Definition:   Base address of the WLED modules.
-
-- default-brightness
-   Usage:optional
-   Value type:   
-   Definition:   brightness value on boot, value from: 0-4095.
- Default: 2048
-
-- label
-   Usage:required
-   Value type:   
-   Definition:   The name of the backlight device
-
-- qcom,cs-out
-   Usage:optional
-   Value type:   
-   Definition:   enable current sink output.
- This property is supported only for PM8941.
-
-- qcom,cabc
-   Usage:optional
-   Value type:   
-   Definition:   enable content adaptive backlight control.
-
-- qcom,ext-gen
-   Usage:optional
-   Value type:   
-   Definition:   use externally generated modulator signal to dim.
- This property is supported only for PM8941.
-
-- qcom,current-limit
-   Usage:optional
-   Value type:   
-   Definition:   mA; per-string current limit; value from 0 to 25 with
- 1 mA step. Default 20 mA.
- This property is supported only for pm8941.
-
-- qcom,current-limit-microamp
-   Usage:optional
-   Value type:   
-   Definition:   uA; per-string current limit; value from 0 to 3 with
- 2500 uA step. Default 25 mA.
-
-- qcom,current-boost-limit
-   Usage:optional
-   Value type:   
-   Definition:   mA; boost current limit.
- For pm8941: one of: 105, 385, 525, 805, 980, 1260, 1400,
- 1680. Default: 805 mA.
- For pmi8998: one of: 105, 280, 450, 620, 970, 1150, 1300,
- 1500. Default: 970 mA.
-
-- qcom,switching-freq
-   Usage:optional
-   Value type:   
-Definition:   kHz; switching frequency; one of: 600, 640, 685, 738,
-  800, 872, 960, 1066, 1200, 1371, 1600, 1920, 2400, 3200,
-  4800, 9600.
-  Default: for pm8941: 1600 kHz
-   for pmi8998: 800 kHz
-
-- qcom,ovp
-   Usage:optional
-   Value type:   
-   Definition:   V; Over-voltage protection limit; one of:
- 27, 29, 32, 35. Default: 29V
- This property is supported only for PM8941.
-
-- qcom,ovp-millivolt
-   Usage:optional
-   Value type:   
-   Definition:   mV; Over-voltage protection limit;
- For pmi8998: one of 18100, 19600, 29600, 31100.
- Default 29600 mV.
- If this property is not specified for PM8941, it
- falls back to "qcom,ovp" property.
-
-- qcom,num-strings
-   Usage:optional
-   Value type:   
-   Definition:   #; number of led strings attached;
- value: For PM8941 from 1 to 3. Default: 2
-For PMI8998 from 1 to 4.
-
-- interrupts
-   Usage:optional
-   Value type:   
-   Definition:   Interrupts associated with WLED. This should be
- "short" and "ovp" interrupts. Interrupts can be
- specified as per the encoding listed under
- Documentation/devicetree/bindings/spmi/
- qcom,spmi-pmic-arb.txt.
-
-- interrupt-names
-   Usage:optional
-   Value type:   
-   Definition:   Interrupt names associated with the interrupts.
- Must be "short" and "ovp"

[PATCH V2 0/2] Add support for WLED5

2020-03-05 Thread Kiran Gunda
Currently, WLED driver supports only WLED4 peripherals that is present
on pmi8998 and pm660L. This patch series  converts the existing WLED4
bindings from .txt to .yaml format and adds the support for WLED5 peripheral
that is present on PM8150L.

PM8150L WLED supports the following.
- Two modulators and each sink can use any of the modulator
- Multiple CABC selection options
- Multiple brightness width selection (12 bits to 15 bits)

Changes from V1:
- Rebased on top of the below commit.
  backlight: qcom-wled: Fix unsigned comparison to zero

Kiran Gunda (2):
  backlight: qcom-wled: convert the wled bindings to .yaml format
  backlight: qcom-wled: Add support for WLED5 peripheral in PM8150L

 .../bindings/leds/backlight/qcom-wled.txt  | 154 ---
 .../bindings/leds/backlight/qcom-wled.yaml | 223 ++
 drivers/video/backlight/qcom-wled.c| 459 ++---
 3 files changed, 634 insertions(+), 202 deletions(-)
 delete mode 100644 
Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
 create mode 100644 
Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH V2 2/2] backlight: qcom-wled: Add support for WLED5 peripheral in PM8150L

2020-03-05 Thread Kiran Gunda
Add support for WLED5 peripheral that is present on PM8150L PMICs.

PM8150L WLED supports the following.
- Two modulators and each sink can use any of the modulator
- Multiple CABC selection options
- Multiple brightness width selection (12 bits to 15 bits)

Signed-off-by: Kiran Gunda 
---
 .../bindings/leds/backlight/qcom-wled.yaml |  39 ++
 drivers/video/backlight/qcom-wled.c| 459 ++---
 2 files changed, 450 insertions(+), 48 deletions(-)

diff --git a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml 
b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml
index d334f81..e0dadc4 100644
--- a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml
+++ b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml
@@ -20,6 +20,7 @@ properties:
- qcom,pm8941-wled
- qcom,pmi8998-wled
- qcom,pm660l-wled
+   - qcom,pm8150l-wled
 
   reg:
 maxItems: 1
@@ -28,10 +29,23 @@ properties:
 maxItems: 1
 description:
   brightness value on boot, value from 0-4095.
+  For pm8150l this value vary from 0-4095 or 0-32767
+  depending on the brightness control mode. If CABC is
+  enabled 0-4095 range is used.
 allOf:
   - $ref: /schemas/types.yaml#/definitions/uint32
 default: 2048
 
+  max-brightness:
+maxItems: 1
+description:
+  Maximum brightness level. Allowed values are,
+  for pmi8998 it is  0-4095.
+  For pm8150l, this can be either 4095 or 32767.
+  If CABC is enabled, this is capped to 4095.
+allOf:
+  - $ref: /schemas/types.yaml#/definitions/uint32
+
   label:
 maxItems: 1
 description:
@@ -124,6 +138,31 @@ properties:
   value for PM8941 from 1 to 3. Default 2
   For PMI8998 from 1 to 4.
 
+  qcom,modulator-sel:
+maxItems: 1
+allOf:
+  - $ref: /schemas/types.yaml#/definitions/uint32
+description:
+  Selects the modulator used for brightness modulation.
+  Allowed values are,
+   0 - Modulator A
+   1 - Modulator B
+  If not specified, then modulator A will be used by default.
+  This property is applicable only to WLED5 peripheral.
+
+  qcom,cabc-sel:
+maxItems: 1
+allOf:
+  - $ref: /schemas/types.yaml#/definitions/uint32
+description:
+  Selects the CABC pin signal used for brightness modulation.
+  Allowed values are,
+  0 - CABC disabled
+  1 - CABC 1
+  2 - CABC 2
+  3 - External signal (e.g. LPG) is used for dimming
+  This property is applicable only to WLED5 peripheral.
+
   interrupts:
 maxItems: 2
 description:
diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 3d276b3..8aa56ab 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -19,6 +19,8 @@
 #define WLED_DEFAULT_BRIGHTNESS2048
 #define WLED_SOFT_START_DLY_US 1
 #define WLED3_SINK_REG_BRIGHT_MAX  0xFFF
+#define WLED5_SINK_REG_BRIGHT_MAX_12B  0xFFF
+#define WLED5_SINK_REG_BRIGHT_MAX_15B  0x7FFF
 
 /* WLED3/WLED4 control registers */
 #define WLED3_CTRL_REG_FAULT_STATUS0x08
@@ -40,6 +42,7 @@
 
 #define WLED3_CTRL_REG_OVP 0x4d
 #define  WLED3_CTRL_REG_OVP_MASK   GENMASK(1, 0)
+#define  WLED5_CTRL_REG_OVP_MASK   GENMASK(3, 0)
 
 #define WLED3_CTRL_REG_ILIMIT  0x4e
 #define  WLED3_CTRL_REG_ILIMIT_MASKGENMASK(2, 0)
@@ -101,6 +104,40 @@
 
 #define WLED4_SINK_REG_BRIGHT(n)   (0x57 + (n * 0x10))
 
+/* WLED5 specific sink registers */
+#define WLED5_SINK_REG_MOD_A_EN0x50
+#define WLED5_SINK_REG_MOD_B_EN0x60
+#define  WLED5_SINK_REG_MOD_EN_MASKBIT(7)
+
+#define WLED5_SINK_REG_MOD_A_SRC_SEL   0x51
+#define WLED5_SINK_REG_MOD_B_SRC_SEL   0x61
+#define  WLED5_SINK_REG_MOD_SRC_SEL_HIGH   0
+#define  WLED5_SINK_REG_MOD_SRC_SEL_EXT0x03
+#define  WLED5_SINK_REG_MOD_SRC_SEL_MASK   GENMASK(1, 0)
+
+#define WLED5_SINK_REG_MOD_A_BRIGHTNESS_WIDTH_SEL  0x52
+#define WLED5_SINK_REG_MOD_B_BRIGHTNESS_WIDTH_SEL  0x62
+#define  WLED5_SINK_REG_BRIGHTNESS_WIDTH_12B   0
+#define  WLED5_SINK_REG_BRIGHTNESS_WIDTH_15B   1
+
+#define WLED5_SINK_REG_MOD_A_BRIGHTNESS_LSB0x53
+#define WLED5_SINK_REG_MOD_A_BRIGHTNESS_MSB0x54
+#define WLED5_SINK_REG_MOD_B_BRIGHTNESS_LSB0x63
+#define WLED5_SINK_REG_MOD_B_BRIGHTNESS_MSB0x64
+
+#define WLED5_SINK_REG_MOD_SYNC_BIT0x65
+#define  WLED5_SINK_REG_SYNC_MOD_A_BIT BIT(0)
+#define

[PATCH V1 1/2] backlight: qcom-wled: convert the wled bindings to .yaml format

2020-03-03 Thread Kiran Gunda
Convert the qcom-wled bindings from .txt to .yaml format.

Signed-off-by: Kiran Gunda 
---
 .../bindings/leds/backlight/qcom-wled.txt  | 154 -
 .../bindings/leds/backlight/qcom-wled.yaml | 184 +
 2 files changed, 184 insertions(+), 154 deletions(-)
 delete mode 100644 
Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
 create mode 100644 
Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml

diff --git a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt 
b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
deleted file mode 100644
index c06863b..000
--- a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
+++ /dev/null
@@ -1,154 +0,0 @@
-Binding for Qualcomm Technologies, Inc. WLED driver
-
-WLED (White Light Emitting Diode) driver is used for controlling display
-backlight that is part of PMIC on Qualcomm Technologies, Inc. reference
-platforms. The PMIC is connected to the host processor via SPMI bus.
-
-- compatible
-   Usage:required
-   Value type:   
-   Definition:   should be one of:
-   "qcom,pm8941-wled"
-   "qcom,pmi8998-wled"
-   "qcom,pm660l-wled"
-
-- reg
-   Usage:required
-   Value type:   
-   Definition:   Base address of the WLED modules.
-
-- default-brightness
-   Usage:optional
-   Value type:   
-   Definition:   brightness value on boot, value from: 0-4095.
- Default: 2048
-
-- label
-   Usage:required
-   Value type:   
-   Definition:   The name of the backlight device
-
-- qcom,cs-out
-   Usage:optional
-   Value type:   
-   Definition:   enable current sink output.
- This property is supported only for PM8941.
-
-- qcom,cabc
-   Usage:optional
-   Value type:   
-   Definition:   enable content adaptive backlight control.
-
-- qcom,ext-gen
-   Usage:optional
-   Value type:   
-   Definition:   use externally generated modulator signal to dim.
- This property is supported only for PM8941.
-
-- qcom,current-limit
-   Usage:optional
-   Value type:   
-   Definition:   mA; per-string current limit; value from 0 to 25 with
- 1 mA step. Default 20 mA.
- This property is supported only for pm8941.
-
-- qcom,current-limit-microamp
-   Usage:optional
-   Value type:   
-   Definition:   uA; per-string current limit; value from 0 to 3 with
- 2500 uA step. Default 25 mA.
-
-- qcom,current-boost-limit
-   Usage:optional
-   Value type:   
-   Definition:   mA; boost current limit.
- For pm8941: one of: 105, 385, 525, 805, 980, 1260, 1400,
- 1680. Default: 805 mA.
- For pmi8998: one of: 105, 280, 450, 620, 970, 1150, 1300,
- 1500. Default: 970 mA.
-
-- qcom,switching-freq
-   Usage:optional
-   Value type:   
-Definition:   kHz; switching frequency; one of: 600, 640, 685, 738,
-  800, 872, 960, 1066, 1200, 1371, 1600, 1920, 2400, 3200,
-  4800, 9600.
-  Default: for pm8941: 1600 kHz
-   for pmi8998: 800 kHz
-
-- qcom,ovp
-   Usage:optional
-   Value type:   
-   Definition:   V; Over-voltage protection limit; one of:
- 27, 29, 32, 35. Default: 29V
- This property is supported only for PM8941.
-
-- qcom,ovp-millivolt
-   Usage:optional
-   Value type:   
-   Definition:   mV; Over-voltage protection limit;
- For pmi8998: one of 18100, 19600, 29600, 31100.
- Default 29600 mV.
- If this property is not specified for PM8941, it
- falls back to "qcom,ovp" property.
-
-- qcom,num-strings
-   Usage:optional
-   Value type:   
-   Definition:   #; number of led strings attached;
- value: For PM8941 from 1 to 3. Default: 2
-For PMI8998 from 1 to 4.
-
-- interrupts
-   Usage:optional
-   Value type:   
-   Definition:   Interrupts associated with WLED. This should be
- "short" and "ovp" interrupts. Interrupts can be
- specified as per the encoding listed under
- Documentation/devicetree/bindings/spmi/
- qcom,spmi-pmic-arb.txt.
-
-- interrupt-names
-   Usage:optional
-   Value type:   
-   Definition:   Interrupt names associated with the interrupts.
- Must be "short" and "ovp"

[PATCH V1 0/2] Add support for WLED5

2020-03-03 Thread Kiran Gunda
Currently, WLED driver supports only WLED4 peripherals that is present
on pmi8998 and pm660L. This patch series  converts the existing WLED4
bindings from .txt to .yaml format and adds the support for WLED5 peripheral
that is present on PM8150L.

PM8150L WLED supports the following.
- Two modulators and each sink can use any of the modulator
- Multiple CABC selection options
- Multiple brightness width selection (12 bits to 15 bits)

Kiran Gunda (2):
  backlight: qcom-wled: convert the wled bindings to .yaml format
  backlight: qcom-wled: Add support for WLED5 peripheral in PM8150L

 .../bindings/leds/backlight/qcom-wled.txt  | 154 ---
 .../bindings/leds/backlight/qcom-wled.yaml | 223 ++
 drivers/video/backlight/qcom-wled.c| 463 ++---
 3 files changed, 636 insertions(+), 204 deletions(-)
 delete mode 100644 
Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
 create mode 100644 
Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH V1 2/2] backlight: qcom-wled: Add support for WLED5 peripheral in PM8150L

2020-03-03 Thread Kiran Gunda
Add support for WLED5 peripheral that is present on PM8150L PMICs.

PM8150L WLED supports the following.
- Two modulators and each sink can use any of the modulator
- Multiple CABC selection options
- Multiple brightness width selection (12 bits to 15 bits)

Signed-off-by: Kiran Gunda 
---
 .../bindings/leds/backlight/qcom-wled.yaml |  39 ++
 drivers/video/backlight/qcom-wled.c| 463 ++---
 2 files changed, 452 insertions(+), 50 deletions(-)

diff --git a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml 
b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml
index d334f81..e0dadc4 100644
--- a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml
+++ b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml
@@ -20,6 +20,7 @@ properties:
- qcom,pm8941-wled
- qcom,pmi8998-wled
- qcom,pm660l-wled
+   - qcom,pm8150l-wled
 
   reg:
 maxItems: 1
@@ -28,10 +29,23 @@ properties:
 maxItems: 1
 description:
   brightness value on boot, value from 0-4095.
+  For pm8150l this value vary from 0-4095 or 0-32767
+  depending on the brightness control mode. If CABC is
+  enabled 0-4095 range is used.
 allOf:
   - $ref: /schemas/types.yaml#/definitions/uint32
 default: 2048
 
+  max-brightness:
+maxItems: 1
+description:
+  Maximum brightness level. Allowed values are,
+  for pmi8998 it is  0-4095.
+  For pm8150l, this can be either 4095 or 32767.
+  If CABC is enabled, this is capped to 4095.
+allOf:
+  - $ref: /schemas/types.yaml#/definitions/uint32
+
   label:
 maxItems: 1
 description:
@@ -124,6 +138,31 @@ properties:
   value for PM8941 from 1 to 3. Default 2
   For PMI8998 from 1 to 4.
 
+  qcom,modulator-sel:
+maxItems: 1
+allOf:
+  - $ref: /schemas/types.yaml#/definitions/uint32
+description:
+  Selects the modulator used for brightness modulation.
+  Allowed values are,
+   0 - Modulator A
+   1 - Modulator B
+  If not specified, then modulator A will be used by default.
+  This property is applicable only to WLED5 peripheral.
+
+  qcom,cabc-sel:
+maxItems: 1
+allOf:
+  - $ref: /schemas/types.yaml#/definitions/uint32
+description:
+  Selects the CABC pin signal used for brightness modulation.
+  Allowed values are,
+  0 - CABC disabled
+  1 - CABC 1
+  2 - CABC 2
+  3 - External signal (e.g. LPG) is used for dimming
+  This property is applicable only to WLED5 peripheral.
+
   interrupts:
 maxItems: 2
 description:
diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 3d276b3..ebec649 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -19,6 +19,8 @@
 #define WLED_DEFAULT_BRIGHTNESS2048
 #define WLED_SOFT_START_DLY_US 1
 #define WLED3_SINK_REG_BRIGHT_MAX  0xFFF
+#define WLED5_SINK_REG_BRIGHT_MAX_12B  0xFFF
+#define WLED5_SINK_REG_BRIGHT_MAX_15B  0x7FFF
 
 /* WLED3/WLED4 control registers */
 #define WLED3_CTRL_REG_FAULT_STATUS0x08
@@ -40,6 +42,7 @@
 
 #define WLED3_CTRL_REG_OVP 0x4d
 #define  WLED3_CTRL_REG_OVP_MASK   GENMASK(1, 0)
+#define  WLED5_CTRL_REG_OVP_MASK   GENMASK(3, 0)
 
 #define WLED3_CTRL_REG_ILIMIT  0x4e
 #define  WLED3_CTRL_REG_ILIMIT_MASKGENMASK(2, 0)
@@ -101,6 +104,40 @@
 
 #define WLED4_SINK_REG_BRIGHT(n)   (0x57 + (n * 0x10))
 
+/* WLED5 specific sink registers */
+#define WLED5_SINK_REG_MOD_A_EN0x50
+#define WLED5_SINK_REG_MOD_B_EN0x60
+#define  WLED5_SINK_REG_MOD_EN_MASKBIT(7)
+
+#define WLED5_SINK_REG_MOD_A_SRC_SEL   0x51
+#define WLED5_SINK_REG_MOD_B_SRC_SEL   0x61
+#define  WLED5_SINK_REG_MOD_SRC_SEL_HIGH   0
+#define  WLED5_SINK_REG_MOD_SRC_SEL_EXT0x03
+#define  WLED5_SINK_REG_MOD_SRC_SEL_MASK   GENMASK(1, 0)
+
+#define WLED5_SINK_REG_MOD_A_BRIGHTNESS_WIDTH_SEL  0x52
+#define WLED5_SINK_REG_MOD_B_BRIGHTNESS_WIDTH_SEL  0x62
+#define  WLED5_SINK_REG_BRIGHTNESS_WIDTH_12B   0
+#define  WLED5_SINK_REG_BRIGHTNESS_WIDTH_15B   1
+
+#define WLED5_SINK_REG_MOD_A_BRIGHTNESS_LSB0x53
+#define WLED5_SINK_REG_MOD_A_BRIGHTNESS_MSB0x54
+#define WLED5_SINK_REG_MOD_B_BRIGHTNESS_LSB0x63
+#define WLED5_SINK_REG_MOD_B_BRIGHTNESS_MSB0x64
+
+#define WLED5_SINK_REG_MOD_SYNC_BIT0x65
+#define  WLED5_SINK_REG_SYNC_MOD_A_BIT BIT(0)
+#define

[PATCH V10 3/8] backlight: qcom-wled: Add new properties for PMI8998.

2019-11-01 Thread Kiran Gunda
Update the bindings with the new properties used for
PMI8998.

Signed-off-by: Kiran Gunda 
Reviewed-by: Bjorn Andersson 
Reviewed-by: Rob Herring 
Acked-by: Daniel Thompson 
---
 .../bindings/leds/backlight/qcom-wled.txt  | 74 ++
 1 file changed, 63 insertions(+), 11 deletions(-)

diff --git a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt 
b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
index 14f28f2..c06863b 100644
--- a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
+++ b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
@@ -20,7 +20,7 @@ platforms. The PMIC is connected to the host processor via 
SPMI bus.
 - default-brightness
Usage:optional
Value type:   
-   Definition:   brightness value on boot, value from: 0-4095
+   Definition:   brightness value on boot, value from: 0-4095.
  Default: 2048
 
 - label
@@ -48,20 +48,24 @@ platforms. The PMIC is connected to the host processor via 
SPMI bus.
 - qcom,current-limit
Usage:optional
Value type:   
-   Definition:   mA; per-string current limit
- value: For pm8941: from 0 to 25 with 5 mA step
-Default 20 mA.
-For pmi8998: from 0 to 30 with 5 mA step
-Default 25 mA.
+   Definition:   mA; per-string current limit; value from 0 to 25 with
+ 1 mA step. Default 20 mA.
+ This property is supported only for pm8941.
+
+- qcom,current-limit-microamp
+   Usage:optional
+   Value type:   
+   Definition:   uA; per-string current limit; value from 0 to 3 with
+ 2500 uA step. Default 25 mA.
 
 - qcom,current-boost-limit
Usage:optional
Value type:   
Definition:   mA; boost current limit.
  For pm8941: one of: 105, 385, 525, 805, 980, 1260, 1400,
- 1680. Default: 805 mA
+ 1680. Default: 805 mA.
  For pmi8998: one of: 105, 280, 450, 620, 970, 1150, 1300,
- 1500. Default: 970 mA
+ 1500. Default: 970 mA.
 
 - qcom,switching-freq
Usage:optional
@@ -76,15 +80,62 @@ platforms. The PMIC is connected to the host processor via 
SPMI bus.
Usage:optional
Value type:   
Definition:   V; Over-voltage protection limit; one of:
- 27, 29, 32, 35. default: 29V
+ 27, 29, 32, 35. Default: 29V
  This property is supported only for PM8941.
 
+- qcom,ovp-millivolt
+   Usage:optional
+   Value type:   
+   Definition:   mV; Over-voltage protection limit;
+ For pmi8998: one of 18100, 19600, 29600, 31100.
+ Default 29600 mV.
+ If this property is not specified for PM8941, it
+ falls back to "qcom,ovp" property.
+
 - qcom,num-strings
Usage:optional
Value type:   
Definition:   #; number of led strings attached;
- value from 1 to 3. default: 2
- This property is supported only for PM8941.
+ value: For PM8941 from 1 to 3. Default: 2
+For PMI8998 from 1 to 4.
+
+- interrupts
+   Usage:optional
+   Value type:   
+   Definition:   Interrupts associated with WLED. This should be
+ "short" and "ovp" interrupts. Interrupts can be
+ specified as per the encoding listed under
+ Documentation/devicetree/bindings/spmi/
+ qcom,spmi-pmic-arb.txt.
+
+- interrupt-names
+   Usage:optional
+   Value type:   
+   Definition:   Interrupt names associated with the interrupts.
+ Must be "short" and "ovp". The short circuit detection
+ is not supported for PM8941.
+
+- qcom,enabled-strings
+   Usage:optional
+   Value tyoe:   
+   Definition:   Array of the WLED strings numbered from 0 to 3. Each
+ string of leds are operated individually. Specify the
+ list of strings used by the device. Any combination of
+ led strings can be used.
+
+- qcom,external-pfet
+   Usage:optional
+   Value type:   
+   Definition:   Specify if external PFET control for short circuit
+ protection is used. This property is supported only
+ for PMI8998.
+
+- qcom,auto-string-detection
+   Usage:optional
+   Value type:   
+   Definition:   Enables auto-detection of the WLED string configuration.
+ This feature is not sup

[PATCH V10 4/8] backlight: qcom-wled: Rename PM8941* to WLED3

2019-11-01 Thread Kiran Gunda
Rename the PM8941* references as WLED3 to make the driver
generic and have WLED support for other PMICs. Also rename
"i_boost_limit" and "i_limit" variables to "boost_i_limit"
and "string_i_limit" respectively to resemble the corresponding
register names.

Signed-off-by: Kiran Gunda 
Reviewed-by: Daniel Thompson 
Reviewed-by: Bjorn Andersson 
Acked-by: Pavel Machek 
---
 drivers/video/backlight/qcom-wled.c | 248 ++--
 1 file changed, 125 insertions(+), 123 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 82b8572..f191242 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -10,77 +10,79 @@
 #include 
 
 /* From DT binding */
-#define PM8941_WLED_DEFAULT_BRIGHTNESS 2048
+#define WLED_DEFAULT_BRIGHTNESS2048
 
-#define PM8941_WLED_REG_VAL_BASE   0x40
-#define  PM8941_WLED_REG_VAL_MAX   0xFFF
+#define WLED3_SINK_REG_BRIGHT_MAX  0xFFF
+#define WLED3_CTRL_REG_VAL_BASE0x40
 
-#define PM8941_WLED_REG_MOD_EN 0x46
-#define  PM8941_WLED_REG_MOD_EN_BITBIT(7)
-#define  PM8941_WLED_REG_MOD_EN_MASK   BIT(7)
+/* WLED3 control registers */
+#define WLED3_CTRL_REG_MOD_EN  0x46
+#define  WLED3_CTRL_REG_MOD_EN_BIT BIT(7)
+#define  WLED3_CTRL_REG_MOD_EN_MASKBIT(7)
 
-#define PM8941_WLED_REG_SYNC   0x47
-#define  PM8941_WLED_REG_SYNC_MASK 0x07
-#define  PM8941_WLED_REG_SYNC_LED1 BIT(0)
-#define  PM8941_WLED_REG_SYNC_LED2 BIT(1)
-#define  PM8941_WLED_REG_SYNC_LED3 BIT(2)
-#define  PM8941_WLED_REG_SYNC_ALL  0x07
-#define  PM8941_WLED_REG_SYNC_CLEAR0x00
+#define WLED3_CTRL_REG_FREQ0x4c
+#define  WLED3_CTRL_REG_FREQ_MASK  0x0f
 
-#define PM8941_WLED_REG_FREQ   0x4c
-#define  PM8941_WLED_REG_FREQ_MASK 0x0f
+#define WLED3_CTRL_REG_OVP 0x4d
+#define  WLED3_CTRL_REG_OVP_MASK   0x03
 
-#define PM8941_WLED_REG_OVP0x4d
-#define  PM8941_WLED_REG_OVP_MASK  0x03
+#define WLED3_CTRL_REG_ILIMIT  0x4e
+#define  WLED3_CTRL_REG_ILIMIT_MASK0x07
 
-#define PM8941_WLED_REG_BOOST  0x4e
-#define  PM8941_WLED_REG_BOOST_MASK0x07
+/* WLED3 sink registers */
+#define WLED3_SINK_REG_SYNC0x47
+#define  WLED3_SINK_REG_SYNC_MASK  0x07
+#define  WLED3_SINK_REG_SYNC_LED1  BIT(0)
+#define  WLED3_SINK_REG_SYNC_LED2  BIT(1)
+#define  WLED3_SINK_REG_SYNC_LED3  BIT(2)
+#define  WLED3_SINK_REG_SYNC_ALL   0x07
+#define  WLED3_SINK_REG_SYNC_CLEAR 0x00
 
-#define PM8941_WLED_REG_SINK   0x4f
-#define  PM8941_WLED_REG_SINK_MASK 0xe0
-#define  PM8941_WLED_REG_SINK_SHFT 0x05
+#define WLED3_SINK_REG_CURR_SINK   0x4f
+#define  WLED3_SINK_REG_CURR_SINK_MASK 0xe0
+#define  WLED3_SINK_REG_CURR_SINK_SHFT 0x05
 
-/* Per-'string' registers below */
-#define PM8941_WLED_REG_STR_OFFSET 0x10
+/* WLED3 per-'string' registers below */
+#define WLED3_SINK_REG_STR_OFFSET  0x10
 
-#define PM8941_WLED_REG_STR_MOD_EN_BASE0x60
-#define  PM8941_WLED_REG_STR_MOD_MASK  BIT(7)
-#define  PM8941_WLED_REG_STR_MOD_ENBIT(7)
+#define WLED3_SINK_REG_STR_MOD_EN_BASE 0x60
+#define  WLED3_SINK_REG_STR_MOD_MASK   BIT(7)
+#define  WLED3_SINK_REG_STR_MOD_EN BIT(7)
 
-#define PM8941_WLED_REG_STR_SCALE_BASE 0x62
-#define  PM8941_WLED_REG_STR_SCALE_MASK0x1f
+#define WLED3_SINK_REG_STR_FULL_SCALE_CURR 0x62
+#define  WLED3_SINK_REG_STR_FULL_SCALE_CURR_MASK   0x1f
 
-#define PM8941_WLED_REG_STR_MOD_SRC_BASE   0x63
-#define  PM8941_WLED_REG_STR_MOD_SRC_MASK  0x01
-#define  PM8941_WLED_REG_STR_MOD_SRC_INT   0x00
-#define  PM8941_WLED_REG_STR_MOD_SRC_EXT   0x01
+#define WLED3_SINK_REG_STR_MOD_SRC_BASE0x63
+#define  WLED3_SINK_REG_STR_MOD_SRC_MASK   0x01
+#define  WLED3_SINK_REG_STR_MOD_SRC_INT0x00
+#define  WLED3_SINK_REG_STR_MOD_SRC_EXT0x01
 
-#define PM8941_WLED_REG_STR_CABC_BASE  0x66
-#define  PM8941_WLED_REG_STR_CABC_MASK BIT(7)
-#define  PM8941_WLED_REG_STR_CABC_EN   BIT(7)
+#define WLED3_SINK_REG_STR_CABC_BASE   0x66
+#define  WLED3_SINK_REG_STR_CABC_MASK  BIT

[PATCH V10 1/8] backlight: qcom-wled: Rename pm8941-wled.c to qcom-wled.c

2019-11-01 Thread Kiran Gunda
pm8941-wled.c driver is supporting the WLED peripheral
on pm8941. Rename it to qcom-wled.c so that it can support
WLED on multiple PMICs.

Signed-off-by: Kiran Gunda 
Reviewed-by: Bjorn Andersson 
Acked-by: Rob Herring 
Acked-by: Daniel Thompson 
Acked-by: Pavel Machek 
---
 .../bindings/leds/backlight/{pm8941-wled.txt => qcom-wled.txt}| 2 +-
 drivers/video/backlight/Kconfig   | 8 
 drivers/video/backlight/Makefile  | 2 +-
 drivers/video/backlight/{pm8941-wled.c => qcom-wled.c}| 0
 4 files changed, 6 insertions(+), 6 deletions(-)
 rename Documentation/devicetree/bindings/leds/backlight/{pm8941-wled.txt => 
qcom-wled.txt} (95%)
 rename drivers/video/backlight/{pm8941-wled.c => qcom-wled.c} (100%)

diff --git a/Documentation/devicetree/bindings/leds/backlight/pm8941-wled.txt 
b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
similarity index 95%
rename from Documentation/devicetree/bindings/leds/backlight/pm8941-wled.txt
rename to Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
index e5b294d..fb39e32 100644
--- a/Documentation/devicetree/bindings/leds/backlight/pm8941-wled.txt
+++ b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
@@ -1,4 +1,4 @@
-Binding for Qualcomm PM8941 WLED driver
+Binding for Qualcomm Technologies, Inc. WLED driver
 
 Required properties:
 - compatible: should be "qcom,pm8941-wled"
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 40676be..73442bdf 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -282,12 +282,12 @@ config BACKLIGHT_TOSA
  If you have an Sharp SL-6000 Zaurus say Y to enable a driver
  for its backlight
 
-config BACKLIGHT_PM8941_WLED
-   tristate "Qualcomm PM8941 WLED Driver"
+config BACKLIGHT_QCOM_WLED
+   tristate "Qualcomm PMIC WLED Driver"
select REGMAP
help
- If you have the Qualcomm PM8941, say Y to enable a driver for the
- WLED block.
+ If you have the Qualcomm PMIC, say Y to enable a driver for the
+ WLED block. Currently it supports PM8941 and PMI8998.
 
 config BACKLIGHT_SAHARA
tristate "Tabletkiosk Sahara Touch-iT Backlight Driver"
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 63c507c..6f87770 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -48,8 +48,8 @@ obj-$(CONFIG_BACKLIGHT_OMAP1) += omap1_bl.o
 obj-$(CONFIG_BACKLIGHT_OT200)  += ot200_bl.o
 obj-$(CONFIG_BACKLIGHT_PANDORA)+= pandora_bl.o
 obj-$(CONFIG_BACKLIGHT_PCF50633)   += pcf50633-backlight.o
-obj-$(CONFIG_BACKLIGHT_PM8941_WLED)+= pm8941-wled.o
 obj-$(CONFIG_BACKLIGHT_PWM)+= pwm_bl.o
+obj-$(CONFIG_BACKLIGHT_QCOM_WLED)  += qcom-wled.o
 obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o
 obj-$(CONFIG_BACKLIGHT_SKY81452)   += sky81452-backlight.o
 obj-$(CONFIG_BACKLIGHT_TOSA)   += tosa_bl.o
diff --git a/drivers/video/backlight/pm8941-wled.c 
b/drivers/video/backlight/qcom-wled.c
similarity index 100%
rename from drivers/video/backlight/pm8941-wled.c
rename to drivers/video/backlight/qcom-wled.c
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH V10 0/8] backlight: qcom-wled: Support for QCOM wled driver

2019-11-01 Thread Kiran Gunda
This patch series renames the pm8941-wled.c driver to qcom-wled.c to add
the support for multiple PMICs supported by qualcomm. This patch series
supports both PM8941 and PMI8998 WLED. The PMI8998 WLED has the support
to handle the OVP (over voltage protection) and the SC (short circuit
protection)
interrupts. It also has the auto string detection algorithm support to
configure the right strings if the user specified string configuration
is in-correct. These three features are added in this series for PMI8998.

changes from v1:
   - Fixed the commit message for
   - backlight: qcom-wled: Rename pm8941-wled.c to qcom-wled.c

Changes from v2:
   - Fixed bjorn and other reviewer's comments
   - Seperated the device tree bindings
   - Splitted out the WLED4 changes in seperate patch
   - Merged OVP and auto string detection patch

Changes from v3:
  - Added Reviewed-by/Acked-by tags
  - Fixed comments from Bjorn/Vinod/Rob
  - Splitting the "backlight: qcom-wled: Add support for WLED4 peripheral" patch
to seperate the WLED3 specific restructure.

Changes from v4:
  - Added reviewed-by/Acked-by tags
  - Fixed comments from Bjorn/Daniel/Pavel

Changes from v5:
  - Fixed comments from Bjorn/Pavel

Changes from v5/v6:
  - Fixed comments from Bjorn/Pavel on V5 series, which were missed in V6 series
  - Patch 1 and 2, mentioned below, from V6 series are picked by Pavel In next.
Hence, dropped them in this series.
https://lore.kernel.org/patchwork/patch/1132467/
https://lore.kernel.org/patchwork/patch/1132468/

Changes from v7:
  - Addressed comments from Daniel Thompson/Lee Jones
  - Patch 1 and 2, mentioned below, from V6 series are picked by Pavel In next.
Hence, dropped them in this series.
https://lore.kernel.org/patchwork/patch/1132467/
https://lore.kernel.org/patchwork/patch/1132468/

Changes from v8:
 - Addressed a comment from Daniel Thompson on patch 6
 - Added Reviewed-by tag of Daniel Thompson on patch 4
 - Patch 1 and 2, mentioned below, from V6 series are picked by Pavel In next.
Hence, dropped them in this series.
https://lore.kernel.org/patchwork/patch/1132467/
https://lore.kernel.org/patchwork/patch/1132468/

Changes from v9:
 - Added back the below dropped out patches to this series.
https://lore.kernel.org/patchwork/patch/1132467/
https://lore.kernel.org/patchwork/patch/1132468/
 - Added Reviewed-by tag of Daniel Thompson on patch 8

Kiran Gunda (8):
  backlight: qcom-wled: Rename pm8941-wled.c to qcom-wled.c
  backlight: qcom-wled: restructure the qcom-wled bindings.
  backlight: qcom-wled: Add new properties for PMI8998.
  backlight: qcom-wled: Rename PM8941* to WLED3
  backlight: qcom-wled: Restructure the driver for WLED3.
  backlight: qcom-wled: Add support for WLED4 peripheral.
  backlight: qcom-wled: add support for short circuit handling.
  backlight: qcom-wled: Add auto string detection logic

 .../bindings/leds/backlight/pm8941-wled.txt|   42 -
 .../bindings/leds/backlight/qcom-wled.txt  |  154 +++
 drivers/video/backlight/Kconfig|8 +-
 drivers/video/backlight/Makefile   |2 +-
 drivers/video/backlight/pm8941-wled.c  |  424 ---
 drivers/video/backlight/qcom-wled.c| 1296 
 6 files changed, 1455 insertions(+), 471 deletions(-)
 delete mode 100644 
Documentation/devicetree/bindings/leds/backlight/pm8941-wled.txt
 create mode 100644 
Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
 delete mode 100644 drivers/video/backlight/pm8941-wled.c
 create mode 100644 drivers/video/backlight/qcom-wled.c

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH V10 2/8] backlight: qcom-wled: restructure the qcom-wled bindings.

2019-11-01 Thread Kiran Gunda
Restructure the qcom-wled bindings for the better readability.

Signed-off-by: Kiran Gunda 
Reviewed-by: Bjorn Andersson 
Reviewed-by: Rob Herring 
Acked-by: Daniel Thompson 
Acked-by: Pavel Machek 
---
 .../bindings/leds/backlight/qcom-wled.txt  | 110 -
 1 file changed, 85 insertions(+), 25 deletions(-)

diff --git a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt 
b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
index fb39e32..14f28f2 100644
--- a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
+++ b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
@@ -1,30 +1,90 @@
 Binding for Qualcomm Technologies, Inc. WLED driver
 
-Required properties:
-- compatible: should be "qcom,pm8941-wled"
-- reg: slave address
-
-Optional properties:
-- default-brightness: brightness value on boot, value from: 0-4095
-   default: 2048
-- label: The name of the backlight device
-- qcom,cs-out: bool; enable current sink output
-- qcom,cabc: bool; enable content adaptive backlight control
-- qcom,ext-gen: bool; use externally generated modulator signal to dim
-- qcom,current-limit: mA; per-string current limit; value from 0 to 25
-   default: 20mA
-- qcom,current-boost-limit: mA; boost current limit; one of:
-   105, 385, 525, 805, 980, 1260, 1400, 1680
-   default: 805mA
-- qcom,switching-freq: kHz; switching frequency; one of:
-   600, 640, 685, 738, 800, 872, 960, 1066, 1200, 1371,
-   1600, 1920, 2400, 3200, 4800, 9600,
-   default: 1600kHz
-- qcom,ovp: V; Over-voltage protection limit; one of:
-   27, 29, 32, 35
-   default: 29V
-- qcom,num-strings: #; number of led strings attached; value from 1 to 3
-   default: 2
+WLED (White Light Emitting Diode) driver is used for controlling display
+backlight that is part of PMIC on Qualcomm Technologies, Inc. reference
+platforms. The PMIC is connected to the host processor via SPMI bus.
+
+- compatible
+   Usage:required
+   Value type:   
+   Definition:   should be one of:
+   "qcom,pm8941-wled"
+   "qcom,pmi8998-wled"
+   "qcom,pm660l-wled"
+
+- reg
+   Usage:required
+   Value type:   
+   Definition:   Base address of the WLED modules.
+
+- default-brightness
+   Usage:optional
+   Value type:   
+   Definition:   brightness value on boot, value from: 0-4095
+ Default: 2048
+
+- label
+   Usage:required
+   Value type:   
+   Definition:   The name of the backlight device
+
+- qcom,cs-out
+   Usage:optional
+   Value type:   
+   Definition:   enable current sink output.
+ This property is supported only for PM8941.
+
+- qcom,cabc
+   Usage:optional
+   Value type:   
+   Definition:   enable content adaptive backlight control.
+
+- qcom,ext-gen
+   Usage:optional
+   Value type:   
+   Definition:   use externally generated modulator signal to dim.
+ This property is supported only for PM8941.
+
+- qcom,current-limit
+   Usage:optional
+   Value type:   
+   Definition:   mA; per-string current limit
+ value: For pm8941: from 0 to 25 with 5 mA step
+Default 20 mA.
+For pmi8998: from 0 to 30 with 5 mA step
+Default 25 mA.
+
+- qcom,current-boost-limit
+   Usage:optional
+   Value type:   
+   Definition:   mA; boost current limit.
+ For pm8941: one of: 105, 385, 525, 805, 980, 1260, 1400,
+ 1680. Default: 805 mA
+ For pmi8998: one of: 105, 280, 450, 620, 970, 1150, 1300,
+ 1500. Default: 970 mA
+
+- qcom,switching-freq
+   Usage:optional
+   Value type:   
+Definition:   kHz; switching frequency; one of: 600, 640, 685, 738,
+  800, 872, 960, 1066, 1200, 1371, 1600, 1920, 2400, 3200,
+  4800, 9600.
+  Default: for pm8941: 1600 kHz
+   for pmi8998: 800 kHz
+
+- qcom,ovp
+   Usage:optional
+   Value type:   
+   Definition:   V; Over-voltage protection limit; one of:
+ 27, 29, 32, 35. default: 29V
+ This property is supported only for PM8941.
+
+- qcom,num-strings
+   Usage:optional
+   Value type:   
+   Definition:   #; number of led strings attached;
+ value from 1 to 3. default: 2
+ This property is supported only for PM8941.
 
 Example:
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project


[PATCH V10 6/8] backlight: qcom-wled: Add support for WLED4 peripheral.

2019-11-01 Thread Kiran Gunda
WLED4 peripheral is present on some PMICs like pmi8998 and
pm660l. It has a different register map and configurations
are also different. Add support for it.

Signed-off-by: Kiran Gunda 
Reviewed-by: Bjorn Andersson 
Reviewed-by: Daniel Thompson 
---
 drivers/video/backlight/qcom-wled.c | 255 +++-
 1 file changed, 253 insertions(+), 2 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 45eeda4..5386ca9 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -17,7 +17,7 @@
 
 #define WLED3_SINK_REG_BRIGHT_MAX  0xFFF
 
-/* WLED3 control registers */
+/* WLED3/WLED4 control registers */
 #define WLED3_CTRL_REG_MOD_EN  0x46
 #define  WLED3_CTRL_REG_MOD_EN_MASKBIT(7)
 #define  WLED3_CTRL_REG_MOD_EN_SHIFT   7
@@ -31,7 +31,7 @@
 #define WLED3_CTRL_REG_ILIMIT  0x4e
 #define  WLED3_CTRL_REG_ILIMIT_MASKGENMASK(2, 0)
 
-/* WLED3 sink registers */
+/* WLED3/WLED4 sink registers */
 #define WLED3_SINK_REG_SYNC0x47
 #define  WLED3_SINK_REG_SYNC_CLEAR 0x00
 
@@ -56,6 +56,28 @@
 #define WLED3_SINK_REG_STR_CABC(n) (0x66 + (n * 0x10))
 #define  WLED3_SINK_REG_STR_CABC_MASK  BIT(7)
 
+/* WLED4 specific sink registers */
+#define WLED4_SINK_REG_CURR_SINK   0x46
+#define  WLED4_SINK_REG_CURR_SINK_MASK GENMASK(7, 4)
+#define  WLED4_SINK_REG_CURR_SINK_SHFT 4
+
+/* WLED4 specific per-'string' registers below */
+#define WLED4_SINK_REG_STR_MOD_EN(n)   (0x50 + (n * 0x10))
+#define  WLED4_SINK_REG_STR_MOD_MASK   BIT(7)
+
+#define WLED4_SINK_REG_STR_FULL_SCALE_CURR(n)  (0x52 + (n * 0x10))
+#define  WLED4_SINK_REG_STR_FULL_SCALE_CURR_MASK   GENMASK(3, 0)
+
+#define WLED4_SINK_REG_STR_MOD_SRC(n)  (0x53 + (n * 0x10))
+#define  WLED4_SINK_REG_STR_MOD_SRC_MASK   BIT(0)
+#define  WLED4_SINK_REG_STR_MOD_SRC_INT0x00
+#define  WLED4_SINK_REG_STR_MOD_SRC_EXT0x01
+
+#define WLED4_SINK_REG_STR_CABC(n) (0x56 + (n * 0x10))
+#define  WLED4_SINK_REG_STR_CABC_MASK  BIT(7)
+
+#define WLED4_SINK_REG_BRIGHT(n)   (0x57 + (n * 0x10))
+
 struct wled_var_cfg {
const u32 *values;
u32 (*fn)(u32);
@@ -90,6 +112,7 @@ struct wled {
struct device *dev;
struct regmap *regmap;
u16 ctrl_addr;
+   u16 sink_addr;
u16 max_string_count;
u32 brightness;
u32 max_brightness;
@@ -116,6 +139,29 @@ static int wled3_set_brightness(struct wled *wled, u16 
brightness)
return 0;
 }
 
+static int wled4_set_brightness(struct wled *wled, u16 brightness)
+{
+   int rc, i;
+   u16 low_limit = wled->max_brightness * 4 / 1000;
+   u8 v[2];
+
+   /* WLED4's lower limit of operation is 0.4% */
+   if (brightness > 0 && brightness < low_limit)
+   brightness = low_limit;
+
+   v[0] = brightness & 0xff;
+   v[1] = (brightness >> 8) & 0xf;
+
+   for (i = 0;  i < wled->cfg.num_strings; ++i) {
+   rc = regmap_bulk_write(wled->regmap, wled->sink_addr +
+  WLED4_SINK_REG_BRIGHT(i), v, 2);
+   if (rc < 0)
+   return rc;
+   }
+
+   return 0;
+}
+
 static int wled_module_enable(struct wled *wled, int val)
 {
int rc;
@@ -267,6 +313,120 @@ static int wled3_setup(struct wled *wled)
.enabled_strings = {0, 1, 2, 3},
 };
 
+static int wled4_setup(struct wled *wled)
+{
+   int rc, temp, i, j;
+   u16 addr;
+   u8 sink_en = 0;
+   u32 sink_cfg = 0;
+
+   rc = regmap_update_bits(wled->regmap,
+   wled->ctrl_addr + WLED3_CTRL_REG_OVP,
+   WLED3_CTRL_REG_OVP_MASK, wled->cfg.ovp);
+   if (rc < 0)
+   return rc;
+
+   rc = regmap_update_bits(wled->regmap,
+   wled->ctrl_addr + WLED3_CTRL_REG_ILIMIT,
+   WLED3_CTRL_REG_ILIMIT_MASK,
+   wled->cfg.boost_i_limit);
+   if (rc < 0)
+   return rc;
+
+   rc = regmap_update_bits(wled->regmap,
+   wled->ctrl_addr + WLED3_CTRL_REG_FREQ,
+   WLED3_CTRL_REG_FREQ_MASK,
+   wled->cfg.switch_freq);
+   if (rc < 0)
+   return rc;
+
+   rc = regmap_read(wled->regmap, wled->sink_addr +
+WLED4_SINK_REG_CURR_SINK, _cfg);
+   if (rc < 0)
+   return rc;
+
+   fo

[PATCH V10 8/8] backlight: qcom-wled: Add auto string detection logic

2019-11-01 Thread Kiran Gunda
The auto string detection algorithm checks if the current WLED
sink configuration is valid. It tries enabling every sink and
checks if the OVP fault is observed. Based on this information
it detects and enables the valid sink configuration.
Auto calibration will be triggered when the OVP fault interrupts
are seen frequently thereby it tries to fix the sink configuration.

The auto-detection also kicks in when the connected LED string
of the display-backlight malfunctions (because of damage) and
requires the damaged string to be turned off to prevent the
complete panel and/or board from being damaged.

Signed-off-by: Kiran Gunda 
Reviewed-by: Daniel Thompson 
---
 drivers/video/backlight/qcom-wled.c | 400 +++-
 1 file changed, 394 insertions(+), 6 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 658b1e0..33b6007 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -17,19 +17,29 @@
 #define WLED_MAX_STRINGS   4
 
 #define WLED_DEFAULT_BRIGHTNESS2048
-
+#define WLED_SOFT_START_DLY_US 1
 #define WLED3_SINK_REG_BRIGHT_MAX  0xFFF
 
 /* WLED3/WLED4 control registers */
+#define WLED3_CTRL_REG_FAULT_STATUS0x08
+#define  WLED3_CTRL_REG_ILIM_FAULT_BIT BIT(0)
+#define  WLED3_CTRL_REG_OVP_FAULT_BIT  BIT(1)
+#define  WLED4_CTRL_REG_SC_FAULT_BIT   BIT(2)
+
+#define WLED3_CTRL_REG_INT_RT_STS  0x10
+#define  WLED3_CTRL_REG_OVP_FAULT_STATUS   BIT(1)
+
 #define WLED3_CTRL_REG_MOD_EN  0x46
 #define  WLED3_CTRL_REG_MOD_EN_MASKBIT(7)
 #define  WLED3_CTRL_REG_MOD_EN_SHIFT   7
 
+#define WLED3_CTRL_REG_FEEDBACK_CONTROL0x48
+
 #define WLED3_CTRL_REG_FREQ0x4c
 #define  WLED3_CTRL_REG_FREQ_MASK  GENMASK(3, 0)
 
 #define WLED3_CTRL_REG_OVP 0x4d
-#define  WLED3_CTRL_REG_OVP_MASK   GENMASK(1, 0)
+#define  WLED3_CTRL_REG_OVP_MASK   GENMASK(1, 0)
 
 #define WLED3_CTRL_REG_ILIMIT  0x4e
 #define  WLED3_CTRL_REG_ILIMIT_MASKGENMASK(2, 0)
@@ -119,6 +129,7 @@ struct wled_config {
bool ext_gen;
bool cabc;
bool external_pfet;
+   bool auto_detection_enabled;
 };
 
 struct wled {
@@ -127,17 +138,22 @@ struct wled {
struct regmap *regmap;
struct mutex lock;  /* Lock to avoid race from thread irq handler */
ktime_t last_short_event;
+   ktime_t start_ovp_fault_time;
u16 ctrl_addr;
u16 sink_addr;
u16 max_string_count;
+   u16 auto_detection_ovp_count;
u32 brightness;
u32 max_brightness;
u32 short_count;
+   u32 auto_detect_count;
bool disabled_by_short;
bool has_short_detect;
int short_irq;
+   int ovp_irq;
 
struct wled_config cfg;
+   struct delayed_work ovp_work;
int (*wled_set_brightness)(struct wled *wled, u16 brightness);
 };
 
@@ -182,6 +198,13 @@ static int wled4_set_brightness(struct wled *wled, u16 
brightness)
return 0;
 }
 
+static void wled_ovp_work(struct work_struct *work)
+{
+   struct wled *wled = container_of(work,
+struct wled, ovp_work.work);
+   enable_irq(wled->ovp_irq);
+}
+
 static int wled_module_enable(struct wled *wled, int val)
 {
int rc;
@@ -193,7 +216,25 @@ static int wled_module_enable(struct wled *wled, int val)
WLED3_CTRL_REG_MOD_EN,
WLED3_CTRL_REG_MOD_EN_MASK,
val << WLED3_CTRL_REG_MOD_EN_SHIFT);
-   return rc;
+   if (rc < 0)
+   return rc;
+
+   if (wled->ovp_irq > 0) {
+   if (val) {
+   /*
+* The hardware generates a storm of spurious OVP
+* interrupts during soft start operations. So defer
+* enabling the IRQ for 10ms to ensure that the
+* soft start is complete.
+*/
+   schedule_delayed_work(>ovp_work, HZ / 100);
+   } else {
+   if (!cancel_delayed_work_sync(>ovp_work))
+   disable_irq(wled->ovp_irq);
+   }
+   }
+
+   return 0;
 }
 
 static int wled_sync_toggle(struct wled *wled)
@@ -300,6 +341,304 @@ static irqreturn_t wled_short_irq_handler(int irq, void 
*_wled)
return IRQ_HANDLED;
 }
 
+#define AUTO_DETECT_BRIGHTNESS 200
+
+static void wled_auto_string_detection(struct wled *wled)
+{
+  

[PATCH V10 5/8] backlight: qcom-wled: Restructure the driver for WLED3.

2019-11-01 Thread Kiran Gunda
Restructure the driver to add the support for new WLED
peripherals.

Signed-off-by: Kiran Gunda 
Acked-by: Daniel Thompson 
---
 drivers/video/backlight/qcom-wled.c | 373 ++--
 1 file changed, 234 insertions(+), 139 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index f191242..45eeda4 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -7,59 +7,71 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 /* From DT binding */
+#define WLED_MAX_STRINGS   4
+
 #define WLED_DEFAULT_BRIGHTNESS2048
 
 #define WLED3_SINK_REG_BRIGHT_MAX  0xFFF
-#define WLED3_CTRL_REG_VAL_BASE0x40
 
 /* WLED3 control registers */
 #define WLED3_CTRL_REG_MOD_EN  0x46
-#define  WLED3_CTRL_REG_MOD_EN_BIT BIT(7)
 #define  WLED3_CTRL_REG_MOD_EN_MASKBIT(7)
+#define  WLED3_CTRL_REG_MOD_EN_SHIFT   7
 
 #define WLED3_CTRL_REG_FREQ0x4c
-#define  WLED3_CTRL_REG_FREQ_MASK  0x0f
+#define  WLED3_CTRL_REG_FREQ_MASK  GENMASK(3, 0)
 
 #define WLED3_CTRL_REG_OVP 0x4d
-#define  WLED3_CTRL_REG_OVP_MASK   0x03
+#define  WLED3_CTRL_REG_OVP_MASK   GENMASK(1, 0)
 
 #define WLED3_CTRL_REG_ILIMIT  0x4e
-#define  WLED3_CTRL_REG_ILIMIT_MASK0x07
+#define  WLED3_CTRL_REG_ILIMIT_MASKGENMASK(2, 0)
 
 /* WLED3 sink registers */
 #define WLED3_SINK_REG_SYNC0x47
-#define  WLED3_SINK_REG_SYNC_MASK  0x07
-#define  WLED3_SINK_REG_SYNC_LED1  BIT(0)
-#define  WLED3_SINK_REG_SYNC_LED2  BIT(1)
-#define  WLED3_SINK_REG_SYNC_LED3  BIT(2)
-#define  WLED3_SINK_REG_SYNC_ALL   0x07
 #define  WLED3_SINK_REG_SYNC_CLEAR 0x00
 
 #define WLED3_SINK_REG_CURR_SINK   0x4f
-#define  WLED3_SINK_REG_CURR_SINK_MASK 0xe0
-#define  WLED3_SINK_REG_CURR_SINK_SHFT 0x05
+#define  WLED3_SINK_REG_CURR_SINK_MASK GENMASK(7, 5)
+#define  WLED3_SINK_REG_CURR_SINK_SHFT 5
 
-/* WLED3 per-'string' registers below */
-#define WLED3_SINK_REG_STR_OFFSET  0x10
+/* WLED3 specific per-'string' registers below */
+#define WLED3_SINK_REG_BRIGHT(n)   (0x40 + n)
 
-#define WLED3_SINK_REG_STR_MOD_EN_BASE 0x60
+#define WLED3_SINK_REG_STR_MOD_EN(n)   (0x60 + (n * 0x10))
 #define  WLED3_SINK_REG_STR_MOD_MASK   BIT(7)
-#define  WLED3_SINK_REG_STR_MOD_EN BIT(7)
 
-#define WLED3_SINK_REG_STR_FULL_SCALE_CURR 0x62
-#define  WLED3_SINK_REG_STR_FULL_SCALE_CURR_MASK   0x1f
+#define WLED3_SINK_REG_STR_FULL_SCALE_CURR(n)  (0x62 + (n * 0x10))
+#define  WLED3_SINK_REG_STR_FULL_SCALE_CURR_MASK   GENMASK(4, 0)
 
-#define WLED3_SINK_REG_STR_MOD_SRC_BASE0x63
-#define  WLED3_SINK_REG_STR_MOD_SRC_MASK   0x01
+#define WLED3_SINK_REG_STR_MOD_SRC(n)  (0x63 + (n * 0x10))
+#define  WLED3_SINK_REG_STR_MOD_SRC_MASK   BIT(0)
 #define  WLED3_SINK_REG_STR_MOD_SRC_INT0x00
 #define  WLED3_SINK_REG_STR_MOD_SRC_EXT0x01
 
-#define WLED3_SINK_REG_STR_CABC_BASE   0x66
+#define WLED3_SINK_REG_STR_CABC(n) (0x66 + (n * 0x10))
 #define  WLED3_SINK_REG_STR_CABC_MASK  BIT(7)
-#define  WLED3_SINK_REG_STR_CABC_ENBIT(7)
+
+struct wled_var_cfg {
+   const u32 *values;
+   u32 (*fn)(u32);
+   int size;
+};
+
+struct wled_u32_opts {
+   const char *name;
+   u32 *val_ptr;
+   const struct wled_var_cfg *cfg;
+};
+
+struct wled_bool_opts {
+   const char *name;
+   bool *val_ptr;
+};
 
 struct wled_config {
u32 boost_i_limit;
@@ -67,132 +79,179 @@ struct wled_config {
u32 switch_freq;
u32 num_strings;
u32 string_i_limit;
+   u32 enabled_strings[WLED_MAX_STRINGS];
bool cs_out_en;
bool ext_gen;
-   bool cabc_en;
+   bool cabc;
 };
 
 struct wled {
const char *name;
+   struct device *dev;
struct regmap *regmap;
-   u16 addr;
+   u16 ctrl_addr;
+   u16 max_string_count;
+   u32 brightness;
+   u32 max_brightness;
 
struct wled_config cfg;
+   int (*wled_set_brightness)(struct wled *wled, u16 brightness);
 };
 
+static int wled3_set_brightness(struct wled *wled, u16 brightness)
+{
+   int rc, i;
+   u8 v[2];
+
+   v[0] = brightness & 0xff;
+  

[PATCH V10 7/8] backlight: qcom-wled: add support for short circuit handling.

2019-11-01 Thread Kiran Gunda
Handle the short circuit interrupt and check if the short circuit
interrupt is valid. Re-enable the module to check if it goes
away. Disable the module altogether if the short circuit event
persists.

Signed-off-by: Kiran Gunda 
Reviewed-by: Bjorn Andersson 
Reviewed-by: Daniel Thompson 
---
 drivers/video/backlight/qcom-wled.c | 144 +++-
 1 file changed, 140 insertions(+), 4 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 5386ca9..658b1e0 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -2,6 +2,9 @@
 /* Copyright (c) 2015, Sony Mobile Communications, AB.
  */
 
+#include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -56,6 +59,16 @@
 #define WLED3_SINK_REG_STR_CABC(n) (0x66 + (n * 0x10))
 #define  WLED3_SINK_REG_STR_CABC_MASK  BIT(7)
 
+/* WLED4 specific control registers */
+#define WLED4_CTRL_REG_SHORT_PROTECT   0x5e
+#define  WLED4_CTRL_REG_SHORT_EN_MASK  BIT(7)
+
+#define WLED4_CTRL_REG_SEC_ACCESS  0xd0
+#define  WLED4_CTRL_REG_SEC_UNLOCK 0xa5
+
+#define WLED4_CTRL_REG_TEST1   0xe2
+#define  WLED4_CTRL_REG_TEST1_EXT_FET_DTEST2   0x09
+
 /* WLED4 specific sink registers */
 #define WLED4_SINK_REG_CURR_SINK   0x46
 #define  WLED4_SINK_REG_CURR_SINK_MASK GENMASK(7, 4)
@@ -105,17 +118,24 @@ struct wled_config {
bool cs_out_en;
bool ext_gen;
bool cabc;
+   bool external_pfet;
 };
 
 struct wled {
const char *name;
struct device *dev;
struct regmap *regmap;
+   struct mutex lock;  /* Lock to avoid race from thread irq handler */
+   ktime_t last_short_event;
u16 ctrl_addr;
u16 sink_addr;
u16 max_string_count;
u32 brightness;
u32 max_brightness;
+   u32 short_count;
+   bool disabled_by_short;
+   bool has_short_detect;
+   int short_irq;
 
struct wled_config cfg;
int (*wled_set_brightness)(struct wled *wled, u16 brightness);
@@ -166,6 +186,9 @@ static int wled_module_enable(struct wled *wled, int val)
 {
int rc;
 
+   if (wled->disabled_by_short)
+   return -ENXIO;
+
rc = regmap_update_bits(wled->regmap, wled->ctrl_addr +
WLED3_CTRL_REG_MOD_EN,
WLED3_CTRL_REG_MOD_EN_MASK,
@@ -202,18 +225,19 @@ static int wled_update_status(struct backlight_device *bl)
bl->props.state & BL_CORE_FBBLANK)
brightness = 0;
 
+   mutex_lock(>lock);
if (brightness) {
rc = wled->wled_set_brightness(wled, brightness);
if (rc < 0) {
dev_err(wled->dev, "wled failed to set brightness 
rc:%d\n",
rc);
-   return rc;
+   goto unlock_mutex;
}
 
rc = wled_sync_toggle(wled);
if (rc < 0) {
dev_err(wled->dev, "wled sync failed rc:%d\n", rc);
-   return rc;
+   goto unlock_mutex;
}
}
 
@@ -221,15 +245,61 @@ static int wled_update_status(struct backlight_device *bl)
rc = wled_module_enable(wled, !!brightness);
if (rc < 0) {
dev_err(wled->dev, "wled enable failed rc:%d\n", rc);
-   return rc;
+   goto unlock_mutex;
}
}
 
wled->brightness = brightness;
 
+unlock_mutex:
+   mutex_unlock(>lock);
+
return rc;
 }
 
+#define WLED_SHORT_DLY_MS  20
+#define WLED_SHORT_CNT_MAX 5
+#define WLED_SHORT_RESET_CNT_DLY_USUSEC_PER_SEC
+
+static irqreturn_t wled_short_irq_handler(int irq, void *_wled)
+{
+   struct wled *wled = _wled;
+   int rc;
+   s64 elapsed_time;
+
+   wled->short_count++;
+   mutex_lock(>lock);
+   rc = wled_module_enable(wled, false);
+   if (rc < 0) {
+   dev_err(wled->dev, "wled disable failed rc:%d\n", rc);
+   goto unlock_mutex;
+   }
+
+   elapsed_time = ktime_us_delta(ktime_get(),
+ wled->last_short_event);
+   if (elapsed_time > WLED_SHORT_RESET_CNT_DLY_US)
+   wled->short_count = 1;
+
+   if (wled->short_count > WLED_SHORT_CNT_MAX) {
+   dev_err(wled->dev, "Short trigged %d times, disabling WLED 
forever!\n",
+   wled->short_count);
+   wled->disabled_by_short = true;
+   goto unlock_mutex;
+

[PATCH V9 6/6] backlight: qcom-wled: Add auto string detection logic

2019-10-23 Thread Kiran Gunda
The auto string detection algorithm checks if the current WLED
sink configuration is valid. It tries enabling every sink and
checks if the OVP fault is observed. Based on this information
it detects and enables the valid sink configuration.
Auto calibration will be triggered when the OVP fault interrupts
are seen frequently thereby it tries to fix the sink configuration.

The auto-detection also kicks in when the connected LED string
of the display-backlight malfunctions (because of damage) and
requires the damaged string to be turned off to prevent the
complete panel and/or board from being damaged.

Signed-off-by: Kiran Gunda 
---
 drivers/video/backlight/qcom-wled.c | 400 +++-
 1 file changed, 394 insertions(+), 6 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 658b1e0..33b6007 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -17,19 +17,29 @@
 #define WLED_MAX_STRINGS   4
 
 #define WLED_DEFAULT_BRIGHTNESS2048
-
+#define WLED_SOFT_START_DLY_US 1
 #define WLED3_SINK_REG_BRIGHT_MAX  0xFFF
 
 /* WLED3/WLED4 control registers */
+#define WLED3_CTRL_REG_FAULT_STATUS0x08
+#define  WLED3_CTRL_REG_ILIM_FAULT_BIT BIT(0)
+#define  WLED3_CTRL_REG_OVP_FAULT_BIT  BIT(1)
+#define  WLED4_CTRL_REG_SC_FAULT_BIT   BIT(2)
+
+#define WLED3_CTRL_REG_INT_RT_STS  0x10
+#define  WLED3_CTRL_REG_OVP_FAULT_STATUS   BIT(1)
+
 #define WLED3_CTRL_REG_MOD_EN  0x46
 #define  WLED3_CTRL_REG_MOD_EN_MASKBIT(7)
 #define  WLED3_CTRL_REG_MOD_EN_SHIFT   7
 
+#define WLED3_CTRL_REG_FEEDBACK_CONTROL0x48
+
 #define WLED3_CTRL_REG_FREQ0x4c
 #define  WLED3_CTRL_REG_FREQ_MASK  GENMASK(3, 0)
 
 #define WLED3_CTRL_REG_OVP 0x4d
-#define  WLED3_CTRL_REG_OVP_MASK   GENMASK(1, 0)
+#define  WLED3_CTRL_REG_OVP_MASK   GENMASK(1, 0)
 
 #define WLED3_CTRL_REG_ILIMIT  0x4e
 #define  WLED3_CTRL_REG_ILIMIT_MASKGENMASK(2, 0)
@@ -119,6 +129,7 @@ struct wled_config {
bool ext_gen;
bool cabc;
bool external_pfet;
+   bool auto_detection_enabled;
 };
 
 struct wled {
@@ -127,17 +138,22 @@ struct wled {
struct regmap *regmap;
struct mutex lock;  /* Lock to avoid race from thread irq handler */
ktime_t last_short_event;
+   ktime_t start_ovp_fault_time;
u16 ctrl_addr;
u16 sink_addr;
u16 max_string_count;
+   u16 auto_detection_ovp_count;
u32 brightness;
u32 max_brightness;
u32 short_count;
+   u32 auto_detect_count;
bool disabled_by_short;
bool has_short_detect;
int short_irq;
+   int ovp_irq;
 
struct wled_config cfg;
+   struct delayed_work ovp_work;
int (*wled_set_brightness)(struct wled *wled, u16 brightness);
 };
 
@@ -182,6 +198,13 @@ static int wled4_set_brightness(struct wled *wled, u16 
brightness)
return 0;
 }
 
+static void wled_ovp_work(struct work_struct *work)
+{
+   struct wled *wled = container_of(work,
+struct wled, ovp_work.work);
+   enable_irq(wled->ovp_irq);
+}
+
 static int wled_module_enable(struct wled *wled, int val)
 {
int rc;
@@ -193,7 +216,25 @@ static int wled_module_enable(struct wled *wled, int val)
WLED3_CTRL_REG_MOD_EN,
WLED3_CTRL_REG_MOD_EN_MASK,
val << WLED3_CTRL_REG_MOD_EN_SHIFT);
-   return rc;
+   if (rc < 0)
+   return rc;
+
+   if (wled->ovp_irq > 0) {
+   if (val) {
+   /*
+* The hardware generates a storm of spurious OVP
+* interrupts during soft start operations. So defer
+* enabling the IRQ for 10ms to ensure that the
+* soft start is complete.
+*/
+   schedule_delayed_work(>ovp_work, HZ / 100);
+   } else {
+   if (!cancel_delayed_work_sync(>ovp_work))
+   disable_irq(wled->ovp_irq);
+   }
+   }
+
+   return 0;
 }
 
 static int wled_sync_toggle(struct wled *wled)
@@ -300,6 +341,304 @@ static irqreturn_t wled_short_irq_handler(int irq, void 
*_wled)
return IRQ_HANDLED;
 }
 
+#define AUTO_DETECT_BRIGHTNESS 200
+
+static void wled_auto_string_detection(struct wled *wled)
+{
+   int rc = 0, i;
+   u

[PATCH V9 0/6] backlight: qcom-wled: Support for QCOM wled driver

2019-10-23 Thread Kiran Gunda
This patch series renames the pm8941-wled.c driver to qcom-wled.c to add
the support for multiple PMICs supported by qualcomm. This patch series
supports both PM8941 and PMI8998 WLED. The PMI8998 WLED has the support
to handle the OVP (over voltage protection) and the SC (short circuit
protection)
interrupts. It also has the auto string detection algorithm support to
configure the right strings if the user specified string configuration
is in-correct. These three features are added in this series for PMI8998.

changes from v1:
   - Fixed the commit message for
   - backlight: qcom-wled: Rename pm8941-wled.c to qcom-wled.c

Changes from v2:
   - Fixed bjorn and other reviewer's comments
   - Seperated the device tree bindings
   - Splitted out the WLED4 changes in seperate patch
   - Merged OVP and auto string detection patch

Changes from v3:
  - Added Reviewed-by/Acked-by tags
  - Fixed comments from Bjorn/Vinod/Rob
  - Splitting the "backlight: qcom-wled: Add support for WLED4 peripheral" patch
to seperate the WLED3 specific restructure.

Changes from v4:
  - Added reviewed-by/Acked-by tags
  - Fixed comments from Bjorn/Daniel/Pavel

Changes from v5:
  - Fixed comments from Bjorn/Pavel

Changes from v5/v6:
  - Fixed comments from Bjorn/Pavel on V5 series, which were missed in V6 series
  - Patch 1 and 2, mentioned below, from V6 series are picked by Pavel In next.
Hence, dropped them in this series.
https://lore.kernel.org/patchwork/patch/1132467/
https://lore.kernel.org/patchwork/patch/1132468/

Changes from v7:
  - Addressed comments from Daniel Thompson/Lee Jones
  - Patch 1 and 2, mentioned below, from V6 series are picked by Pavel In next.
Hence, dropped them in this series.
https://lore.kernel.org/patchwork/patch/1132467/
https://lore.kernel.org/patchwork/patch/1132468/

Changes from v8:
 - Addressed a comment from Daniel Thompson on patch 6
 - Added Reviewed-by tag of Daniel Thompson on patch 4
 - Patch 1 and 2, mentioned below, from V6 series are picked by Pavel In next.
Hence, dropped them in this series.
https://lore.kernel.org/patchwork/patch/1132467/
https://lore.kernel.org/patchwork/patch/1132468/

Kiran Gunda (6):
  backlight: qcom-wled: Add new properties for PMI8998.
  backlight: qcom-wled: Rename PM8941* to WLED3
  backlight: qcom-wled: Restructure the driver for WLED3.
  backlight: qcom-wled: Add support for WLED4 peripheral.
  backlight: qcom-wled: add support for short circuit handling.
  backlight: qcom-wled: Add auto string detection logic

 .../bindings/leds/backlight/qcom-wled.txt  |   74 +-
 drivers/video/backlight/qcom-wled.c| 1256 +---
 2 files changed, 1127 insertions(+), 203 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project



[PATCH V9 4/6] backlight: qcom-wled: Add support for WLED4 peripheral.

2019-10-23 Thread Kiran Gunda
WLED4 peripheral is present on some PMICs like pmi8998 and
pm660l. It has a different register map and configurations
are also different. Add support for it.

Signed-off-by: Kiran Gunda 
Reviewed-by: Bjorn Andersson 
Reviewed-by: Daniel Thompson 
---
 drivers/video/backlight/qcom-wled.c | 255 +++-
 1 file changed, 253 insertions(+), 2 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 45eeda4..5386ca9 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -17,7 +17,7 @@
 
 #define WLED3_SINK_REG_BRIGHT_MAX  0xFFF
 
-/* WLED3 control registers */
+/* WLED3/WLED4 control registers */
 #define WLED3_CTRL_REG_MOD_EN  0x46
 #define  WLED3_CTRL_REG_MOD_EN_MASKBIT(7)
 #define  WLED3_CTRL_REG_MOD_EN_SHIFT   7
@@ -31,7 +31,7 @@
 #define WLED3_CTRL_REG_ILIMIT  0x4e
 #define  WLED3_CTRL_REG_ILIMIT_MASKGENMASK(2, 0)
 
-/* WLED3 sink registers */
+/* WLED3/WLED4 sink registers */
 #define WLED3_SINK_REG_SYNC0x47
 #define  WLED3_SINK_REG_SYNC_CLEAR 0x00
 
@@ -56,6 +56,28 @@
 #define WLED3_SINK_REG_STR_CABC(n) (0x66 + (n * 0x10))
 #define  WLED3_SINK_REG_STR_CABC_MASK  BIT(7)
 
+/* WLED4 specific sink registers */
+#define WLED4_SINK_REG_CURR_SINK   0x46
+#define  WLED4_SINK_REG_CURR_SINK_MASK GENMASK(7, 4)
+#define  WLED4_SINK_REG_CURR_SINK_SHFT 4
+
+/* WLED4 specific per-'string' registers below */
+#define WLED4_SINK_REG_STR_MOD_EN(n)   (0x50 + (n * 0x10))
+#define  WLED4_SINK_REG_STR_MOD_MASK   BIT(7)
+
+#define WLED4_SINK_REG_STR_FULL_SCALE_CURR(n)  (0x52 + (n * 0x10))
+#define  WLED4_SINK_REG_STR_FULL_SCALE_CURR_MASK   GENMASK(3, 0)
+
+#define WLED4_SINK_REG_STR_MOD_SRC(n)  (0x53 + (n * 0x10))
+#define  WLED4_SINK_REG_STR_MOD_SRC_MASK   BIT(0)
+#define  WLED4_SINK_REG_STR_MOD_SRC_INT0x00
+#define  WLED4_SINK_REG_STR_MOD_SRC_EXT0x01
+
+#define WLED4_SINK_REG_STR_CABC(n) (0x56 + (n * 0x10))
+#define  WLED4_SINK_REG_STR_CABC_MASK  BIT(7)
+
+#define WLED4_SINK_REG_BRIGHT(n)   (0x57 + (n * 0x10))
+
 struct wled_var_cfg {
const u32 *values;
u32 (*fn)(u32);
@@ -90,6 +112,7 @@ struct wled {
struct device *dev;
struct regmap *regmap;
u16 ctrl_addr;
+   u16 sink_addr;
u16 max_string_count;
u32 brightness;
u32 max_brightness;
@@ -116,6 +139,29 @@ static int wled3_set_brightness(struct wled *wled, u16 
brightness)
return 0;
 }
 
+static int wled4_set_brightness(struct wled *wled, u16 brightness)
+{
+   int rc, i;
+   u16 low_limit = wled->max_brightness * 4 / 1000;
+   u8 v[2];
+
+   /* WLED4's lower limit of operation is 0.4% */
+   if (brightness > 0 && brightness < low_limit)
+   brightness = low_limit;
+
+   v[0] = brightness & 0xff;
+   v[1] = (brightness >> 8) & 0xf;
+
+   for (i = 0;  i < wled->cfg.num_strings; ++i) {
+   rc = regmap_bulk_write(wled->regmap, wled->sink_addr +
+  WLED4_SINK_REG_BRIGHT(i), v, 2);
+   if (rc < 0)
+   return rc;
+   }
+
+   return 0;
+}
+
 static int wled_module_enable(struct wled *wled, int val)
 {
int rc;
@@ -267,6 +313,120 @@ static int wled3_setup(struct wled *wled)
.enabled_strings = {0, 1, 2, 3},
 };
 
+static int wled4_setup(struct wled *wled)
+{
+   int rc, temp, i, j;
+   u16 addr;
+   u8 sink_en = 0;
+   u32 sink_cfg = 0;
+
+   rc = regmap_update_bits(wled->regmap,
+   wled->ctrl_addr + WLED3_CTRL_REG_OVP,
+   WLED3_CTRL_REG_OVP_MASK, wled->cfg.ovp);
+   if (rc < 0)
+   return rc;
+
+   rc = regmap_update_bits(wled->regmap,
+   wled->ctrl_addr + WLED3_CTRL_REG_ILIMIT,
+   WLED3_CTRL_REG_ILIMIT_MASK,
+   wled->cfg.boost_i_limit);
+   if (rc < 0)
+   return rc;
+
+   rc = regmap_update_bits(wled->regmap,
+   wled->ctrl_addr + WLED3_CTRL_REG_FREQ,
+   WLED3_CTRL_REG_FREQ_MASK,
+   wled->cfg.switch_freq);
+   if (rc < 0)
+   return rc;
+
+   rc = regmap_read(wled->regmap, wled->sink_addr +
+WLED4_SINK_REG_CURR_SINK, _cfg);
+   if (rc < 0)
+   return rc;
+
+   fo

[PATCH V9 3/6] backlight: qcom-wled: Restructure the driver for WLED3.

2019-10-23 Thread Kiran Gunda
Restructure the driver to add the support for new WLED
peripherals.

Signed-off-by: Kiran Gunda 
Acked-by: Daniel Thompson 
---
 drivers/video/backlight/qcom-wled.c | 373 ++--
 1 file changed, 234 insertions(+), 139 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index f191242..45eeda4 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -7,59 +7,71 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 /* From DT binding */
+#define WLED_MAX_STRINGS   4
+
 #define WLED_DEFAULT_BRIGHTNESS2048
 
 #define WLED3_SINK_REG_BRIGHT_MAX  0xFFF
-#define WLED3_CTRL_REG_VAL_BASE0x40
 
 /* WLED3 control registers */
 #define WLED3_CTRL_REG_MOD_EN  0x46
-#define  WLED3_CTRL_REG_MOD_EN_BIT BIT(7)
 #define  WLED3_CTRL_REG_MOD_EN_MASKBIT(7)
+#define  WLED3_CTRL_REG_MOD_EN_SHIFT   7
 
 #define WLED3_CTRL_REG_FREQ0x4c
-#define  WLED3_CTRL_REG_FREQ_MASK  0x0f
+#define  WLED3_CTRL_REG_FREQ_MASK  GENMASK(3, 0)
 
 #define WLED3_CTRL_REG_OVP 0x4d
-#define  WLED3_CTRL_REG_OVP_MASK   0x03
+#define  WLED3_CTRL_REG_OVP_MASK   GENMASK(1, 0)
 
 #define WLED3_CTRL_REG_ILIMIT  0x4e
-#define  WLED3_CTRL_REG_ILIMIT_MASK0x07
+#define  WLED3_CTRL_REG_ILIMIT_MASKGENMASK(2, 0)
 
 /* WLED3 sink registers */
 #define WLED3_SINK_REG_SYNC0x47
-#define  WLED3_SINK_REG_SYNC_MASK  0x07
-#define  WLED3_SINK_REG_SYNC_LED1  BIT(0)
-#define  WLED3_SINK_REG_SYNC_LED2  BIT(1)
-#define  WLED3_SINK_REG_SYNC_LED3  BIT(2)
-#define  WLED3_SINK_REG_SYNC_ALL   0x07
 #define  WLED3_SINK_REG_SYNC_CLEAR 0x00
 
 #define WLED3_SINK_REG_CURR_SINK   0x4f
-#define  WLED3_SINK_REG_CURR_SINK_MASK 0xe0
-#define  WLED3_SINK_REG_CURR_SINK_SHFT 0x05
+#define  WLED3_SINK_REG_CURR_SINK_MASK GENMASK(7, 5)
+#define  WLED3_SINK_REG_CURR_SINK_SHFT 5
 
-/* WLED3 per-'string' registers below */
-#define WLED3_SINK_REG_STR_OFFSET  0x10
+/* WLED3 specific per-'string' registers below */
+#define WLED3_SINK_REG_BRIGHT(n)   (0x40 + n)
 
-#define WLED3_SINK_REG_STR_MOD_EN_BASE 0x60
+#define WLED3_SINK_REG_STR_MOD_EN(n)   (0x60 + (n * 0x10))
 #define  WLED3_SINK_REG_STR_MOD_MASK   BIT(7)
-#define  WLED3_SINK_REG_STR_MOD_EN BIT(7)
 
-#define WLED3_SINK_REG_STR_FULL_SCALE_CURR 0x62
-#define  WLED3_SINK_REG_STR_FULL_SCALE_CURR_MASK   0x1f
+#define WLED3_SINK_REG_STR_FULL_SCALE_CURR(n)  (0x62 + (n * 0x10))
+#define  WLED3_SINK_REG_STR_FULL_SCALE_CURR_MASK   GENMASK(4, 0)
 
-#define WLED3_SINK_REG_STR_MOD_SRC_BASE0x63
-#define  WLED3_SINK_REG_STR_MOD_SRC_MASK   0x01
+#define WLED3_SINK_REG_STR_MOD_SRC(n)  (0x63 + (n * 0x10))
+#define  WLED3_SINK_REG_STR_MOD_SRC_MASK   BIT(0)
 #define  WLED3_SINK_REG_STR_MOD_SRC_INT0x00
 #define  WLED3_SINK_REG_STR_MOD_SRC_EXT0x01
 
-#define WLED3_SINK_REG_STR_CABC_BASE   0x66
+#define WLED3_SINK_REG_STR_CABC(n) (0x66 + (n * 0x10))
 #define  WLED3_SINK_REG_STR_CABC_MASK  BIT(7)
-#define  WLED3_SINK_REG_STR_CABC_ENBIT(7)
+
+struct wled_var_cfg {
+   const u32 *values;
+   u32 (*fn)(u32);
+   int size;
+};
+
+struct wled_u32_opts {
+   const char *name;
+   u32 *val_ptr;
+   const struct wled_var_cfg *cfg;
+};
+
+struct wled_bool_opts {
+   const char *name;
+   bool *val_ptr;
+};
 
 struct wled_config {
u32 boost_i_limit;
@@ -67,132 +79,179 @@ struct wled_config {
u32 switch_freq;
u32 num_strings;
u32 string_i_limit;
+   u32 enabled_strings[WLED_MAX_STRINGS];
bool cs_out_en;
bool ext_gen;
-   bool cabc_en;
+   bool cabc;
 };
 
 struct wled {
const char *name;
+   struct device *dev;
struct regmap *regmap;
-   u16 addr;
+   u16 ctrl_addr;
+   u16 max_string_count;
+   u32 brightness;
+   u32 max_brightness;
 
struct wled_config cfg;
+   int (*wled_set_brightness)(struct wled *wled, u16 brightness);
 };
 
+static int wled3_set_brightness(struct wled *wled, u16 brightness)
+{
+   int rc, i;
+   u8 v[2];
+
+   v[0] = brightness & 0xff;
+  

[PATCH V9 5/6] backlight: qcom-wled: add support for short circuit handling.

2019-10-23 Thread Kiran Gunda
Handle the short circuit interrupt and check if the short circuit
interrupt is valid. Re-enable the module to check if it goes
away. Disable the module altogether if the short circuit event
persists.

Signed-off-by: Kiran Gunda 
Reviewed-by: Bjorn Andersson 
Reviewed-by: Daniel Thompson 
---
 drivers/video/backlight/qcom-wled.c | 144 +++-
 1 file changed, 140 insertions(+), 4 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 5386ca9..658b1e0 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -2,6 +2,9 @@
 /* Copyright (c) 2015, Sony Mobile Communications, AB.
  */
 
+#include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -56,6 +59,16 @@
 #define WLED3_SINK_REG_STR_CABC(n) (0x66 + (n * 0x10))
 #define  WLED3_SINK_REG_STR_CABC_MASK  BIT(7)
 
+/* WLED4 specific control registers */
+#define WLED4_CTRL_REG_SHORT_PROTECT   0x5e
+#define  WLED4_CTRL_REG_SHORT_EN_MASK  BIT(7)
+
+#define WLED4_CTRL_REG_SEC_ACCESS  0xd0
+#define  WLED4_CTRL_REG_SEC_UNLOCK 0xa5
+
+#define WLED4_CTRL_REG_TEST1   0xe2
+#define  WLED4_CTRL_REG_TEST1_EXT_FET_DTEST2   0x09
+
 /* WLED4 specific sink registers */
 #define WLED4_SINK_REG_CURR_SINK   0x46
 #define  WLED4_SINK_REG_CURR_SINK_MASK GENMASK(7, 4)
@@ -105,17 +118,24 @@ struct wled_config {
bool cs_out_en;
bool ext_gen;
bool cabc;
+   bool external_pfet;
 };
 
 struct wled {
const char *name;
struct device *dev;
struct regmap *regmap;
+   struct mutex lock;  /* Lock to avoid race from thread irq handler */
+   ktime_t last_short_event;
u16 ctrl_addr;
u16 sink_addr;
u16 max_string_count;
u32 brightness;
u32 max_brightness;
+   u32 short_count;
+   bool disabled_by_short;
+   bool has_short_detect;
+   int short_irq;
 
struct wled_config cfg;
int (*wled_set_brightness)(struct wled *wled, u16 brightness);
@@ -166,6 +186,9 @@ static int wled_module_enable(struct wled *wled, int val)
 {
int rc;
 
+   if (wled->disabled_by_short)
+   return -ENXIO;
+
rc = regmap_update_bits(wled->regmap, wled->ctrl_addr +
WLED3_CTRL_REG_MOD_EN,
WLED3_CTRL_REG_MOD_EN_MASK,
@@ -202,18 +225,19 @@ static int wled_update_status(struct backlight_device *bl)
bl->props.state & BL_CORE_FBBLANK)
brightness = 0;
 
+   mutex_lock(>lock);
if (brightness) {
rc = wled->wled_set_brightness(wled, brightness);
if (rc < 0) {
dev_err(wled->dev, "wled failed to set brightness 
rc:%d\n",
rc);
-   return rc;
+   goto unlock_mutex;
}
 
rc = wled_sync_toggle(wled);
if (rc < 0) {
dev_err(wled->dev, "wled sync failed rc:%d\n", rc);
-   return rc;
+   goto unlock_mutex;
}
}
 
@@ -221,15 +245,61 @@ static int wled_update_status(struct backlight_device *bl)
rc = wled_module_enable(wled, !!brightness);
if (rc < 0) {
dev_err(wled->dev, "wled enable failed rc:%d\n", rc);
-   return rc;
+   goto unlock_mutex;
}
}
 
wled->brightness = brightness;
 
+unlock_mutex:
+   mutex_unlock(>lock);
+
return rc;
 }
 
+#define WLED_SHORT_DLY_MS  20
+#define WLED_SHORT_CNT_MAX 5
+#define WLED_SHORT_RESET_CNT_DLY_USUSEC_PER_SEC
+
+static irqreturn_t wled_short_irq_handler(int irq, void *_wled)
+{
+   struct wled *wled = _wled;
+   int rc;
+   s64 elapsed_time;
+
+   wled->short_count++;
+   mutex_lock(>lock);
+   rc = wled_module_enable(wled, false);
+   if (rc < 0) {
+   dev_err(wled->dev, "wled disable failed rc:%d\n", rc);
+   goto unlock_mutex;
+   }
+
+   elapsed_time = ktime_us_delta(ktime_get(),
+ wled->last_short_event);
+   if (elapsed_time > WLED_SHORT_RESET_CNT_DLY_US)
+   wled->short_count = 1;
+
+   if (wled->short_count > WLED_SHORT_CNT_MAX) {
+   dev_err(wled->dev, "Short trigged %d times, disabling WLED 
forever!\n",
+   wled->short_count);
+   wled->disabled_by_short = true;
+   goto unlock_mutex;
+

[PATCH V9 2/6] backlight: qcom-wled: Rename PM8941* to WLED3

2019-10-23 Thread Kiran Gunda
Rename the PM8941* references as WLED3 to make the driver
generic and have WLED support for other PMICs. Also rename
"i_boost_limit" and "i_limit" variables to "boost_i_limit"
and "string_i_limit" respectively to resemble the corresponding
register names.

Signed-off-by: Kiran Gunda 
Reviewed-by: Daniel Thompson 
Reviewed-by: Bjorn Andersson 
Acked-by: Pavel Machek 
---
 drivers/video/backlight/qcom-wled.c | 248 ++--
 1 file changed, 125 insertions(+), 123 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 82b8572..f191242 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -10,77 +10,79 @@
 #include 
 
 /* From DT binding */
-#define PM8941_WLED_DEFAULT_BRIGHTNESS 2048
+#define WLED_DEFAULT_BRIGHTNESS2048
 
-#define PM8941_WLED_REG_VAL_BASE   0x40
-#define  PM8941_WLED_REG_VAL_MAX   0xFFF
+#define WLED3_SINK_REG_BRIGHT_MAX  0xFFF
+#define WLED3_CTRL_REG_VAL_BASE0x40
 
-#define PM8941_WLED_REG_MOD_EN 0x46
-#define  PM8941_WLED_REG_MOD_EN_BITBIT(7)
-#define  PM8941_WLED_REG_MOD_EN_MASK   BIT(7)
+/* WLED3 control registers */
+#define WLED3_CTRL_REG_MOD_EN  0x46
+#define  WLED3_CTRL_REG_MOD_EN_BIT BIT(7)
+#define  WLED3_CTRL_REG_MOD_EN_MASKBIT(7)
 
-#define PM8941_WLED_REG_SYNC   0x47
-#define  PM8941_WLED_REG_SYNC_MASK 0x07
-#define  PM8941_WLED_REG_SYNC_LED1 BIT(0)
-#define  PM8941_WLED_REG_SYNC_LED2 BIT(1)
-#define  PM8941_WLED_REG_SYNC_LED3 BIT(2)
-#define  PM8941_WLED_REG_SYNC_ALL  0x07
-#define  PM8941_WLED_REG_SYNC_CLEAR0x00
+#define WLED3_CTRL_REG_FREQ0x4c
+#define  WLED3_CTRL_REG_FREQ_MASK  0x0f
 
-#define PM8941_WLED_REG_FREQ   0x4c
-#define  PM8941_WLED_REG_FREQ_MASK 0x0f
+#define WLED3_CTRL_REG_OVP 0x4d
+#define  WLED3_CTRL_REG_OVP_MASK   0x03
 
-#define PM8941_WLED_REG_OVP0x4d
-#define  PM8941_WLED_REG_OVP_MASK  0x03
+#define WLED3_CTRL_REG_ILIMIT  0x4e
+#define  WLED3_CTRL_REG_ILIMIT_MASK0x07
 
-#define PM8941_WLED_REG_BOOST  0x4e
-#define  PM8941_WLED_REG_BOOST_MASK0x07
+/* WLED3 sink registers */
+#define WLED3_SINK_REG_SYNC0x47
+#define  WLED3_SINK_REG_SYNC_MASK  0x07
+#define  WLED3_SINK_REG_SYNC_LED1  BIT(0)
+#define  WLED3_SINK_REG_SYNC_LED2  BIT(1)
+#define  WLED3_SINK_REG_SYNC_LED3  BIT(2)
+#define  WLED3_SINK_REG_SYNC_ALL   0x07
+#define  WLED3_SINK_REG_SYNC_CLEAR 0x00
 
-#define PM8941_WLED_REG_SINK   0x4f
-#define  PM8941_WLED_REG_SINK_MASK 0xe0
-#define  PM8941_WLED_REG_SINK_SHFT 0x05
+#define WLED3_SINK_REG_CURR_SINK   0x4f
+#define  WLED3_SINK_REG_CURR_SINK_MASK 0xe0
+#define  WLED3_SINK_REG_CURR_SINK_SHFT 0x05
 
-/* Per-'string' registers below */
-#define PM8941_WLED_REG_STR_OFFSET 0x10
+/* WLED3 per-'string' registers below */
+#define WLED3_SINK_REG_STR_OFFSET  0x10
 
-#define PM8941_WLED_REG_STR_MOD_EN_BASE0x60
-#define  PM8941_WLED_REG_STR_MOD_MASK  BIT(7)
-#define  PM8941_WLED_REG_STR_MOD_ENBIT(7)
+#define WLED3_SINK_REG_STR_MOD_EN_BASE 0x60
+#define  WLED3_SINK_REG_STR_MOD_MASK   BIT(7)
+#define  WLED3_SINK_REG_STR_MOD_EN BIT(7)
 
-#define PM8941_WLED_REG_STR_SCALE_BASE 0x62
-#define  PM8941_WLED_REG_STR_SCALE_MASK0x1f
+#define WLED3_SINK_REG_STR_FULL_SCALE_CURR 0x62
+#define  WLED3_SINK_REG_STR_FULL_SCALE_CURR_MASK   0x1f
 
-#define PM8941_WLED_REG_STR_MOD_SRC_BASE   0x63
-#define  PM8941_WLED_REG_STR_MOD_SRC_MASK  0x01
-#define  PM8941_WLED_REG_STR_MOD_SRC_INT   0x00
-#define  PM8941_WLED_REG_STR_MOD_SRC_EXT   0x01
+#define WLED3_SINK_REG_STR_MOD_SRC_BASE0x63
+#define  WLED3_SINK_REG_STR_MOD_SRC_MASK   0x01
+#define  WLED3_SINK_REG_STR_MOD_SRC_INT0x00
+#define  WLED3_SINK_REG_STR_MOD_SRC_EXT0x01
 
-#define PM8941_WLED_REG_STR_CABC_BASE  0x66
-#define  PM8941_WLED_REG_STR_CABC_MASK BIT(7)
-#define  PM8941_WLED_REG_STR_CABC_EN   BIT(7)
+#define WLED3_SINK_REG_STR_CABC_BASE   0x66
+#define  WLED3_SINK_REG_STR_CABC_MASK  BIT

[PATCH V9 1/6] backlight: qcom-wled: Add new properties for PMI8998.

2019-10-23 Thread Kiran Gunda
Update the bindings with the new properties used for
PMI8998.

Signed-off-by: Kiran Gunda 
Reviewed-by: Bjorn Andersson 
Reviewed-by: Rob Herring 
Acked-by: Daniel Thompson 
---
 .../bindings/leds/backlight/qcom-wled.txt  | 74 ++
 1 file changed, 63 insertions(+), 11 deletions(-)

diff --git a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt 
b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
index 14f28f2..c06863b 100644
--- a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
+++ b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
@@ -20,7 +20,7 @@ platforms. The PMIC is connected to the host processor via 
SPMI bus.
 - default-brightness
Usage:optional
Value type:   
-   Definition:   brightness value on boot, value from: 0-4095
+   Definition:   brightness value on boot, value from: 0-4095.
  Default: 2048
 
 - label
@@ -48,20 +48,24 @@ platforms. The PMIC is connected to the host processor via 
SPMI bus.
 - qcom,current-limit
Usage:optional
Value type:   
-   Definition:   mA; per-string current limit
- value: For pm8941: from 0 to 25 with 5 mA step
-Default 20 mA.
-For pmi8998: from 0 to 30 with 5 mA step
-Default 25 mA.
+   Definition:   mA; per-string current limit; value from 0 to 25 with
+ 1 mA step. Default 20 mA.
+ This property is supported only for pm8941.
+
+- qcom,current-limit-microamp
+   Usage:optional
+   Value type:   
+   Definition:   uA; per-string current limit; value from 0 to 3 with
+ 2500 uA step. Default 25 mA.
 
 - qcom,current-boost-limit
Usage:optional
Value type:   
Definition:   mA; boost current limit.
  For pm8941: one of: 105, 385, 525, 805, 980, 1260, 1400,
- 1680. Default: 805 mA
+ 1680. Default: 805 mA.
  For pmi8998: one of: 105, 280, 450, 620, 970, 1150, 1300,
- 1500. Default: 970 mA
+ 1500. Default: 970 mA.
 
 - qcom,switching-freq
Usage:optional
@@ -76,15 +80,62 @@ platforms. The PMIC is connected to the host processor via 
SPMI bus.
Usage:optional
Value type:   
Definition:   V; Over-voltage protection limit; one of:
- 27, 29, 32, 35. default: 29V
+ 27, 29, 32, 35. Default: 29V
  This property is supported only for PM8941.
 
+- qcom,ovp-millivolt
+   Usage:optional
+   Value type:   
+   Definition:   mV; Over-voltage protection limit;
+ For pmi8998: one of 18100, 19600, 29600, 31100.
+ Default 29600 mV.
+ If this property is not specified for PM8941, it
+ falls back to "qcom,ovp" property.
+
 - qcom,num-strings
Usage:optional
Value type:   
Definition:   #; number of led strings attached;
- value from 1 to 3. default: 2
- This property is supported only for PM8941.
+ value: For PM8941 from 1 to 3. Default: 2
+For PMI8998 from 1 to 4.
+
+- interrupts
+   Usage:optional
+   Value type:   
+   Definition:   Interrupts associated with WLED. This should be
+ "short" and "ovp" interrupts. Interrupts can be
+ specified as per the encoding listed under
+ Documentation/devicetree/bindings/spmi/
+ qcom,spmi-pmic-arb.txt.
+
+- interrupt-names
+   Usage:optional
+   Value type:   
+   Definition:   Interrupt names associated with the interrupts.
+ Must be "short" and "ovp". The short circuit detection
+ is not supported for PM8941.
+
+- qcom,enabled-strings
+   Usage:optional
+   Value tyoe:   
+   Definition:   Array of the WLED strings numbered from 0 to 3. Each
+ string of leds are operated individually. Specify the
+ list of strings used by the device. Any combination of
+ led strings can be used.
+
+- qcom,external-pfet
+   Usage:optional
+   Value type:   
+   Definition:   Specify if external PFET control for short circuit
+ protection is used. This property is supported only
+ for PMI8998.
+
+- qcom,auto-string-detection
+   Usage:optional
+   Value type:   
+   Definition:   Enables auto-detection of the WLED string configuration.
+ This feature is not sup

[PATCH V7 4/6] backlight: qcom-wled: Add support for WLED4 peripheral.

2019-10-18 Thread Kiran Gunda
WLED4 peripheral is present on some PMICs like pmi8998 and
pm660l. It has a different register map and configurations
are also different. Add support for it.

Signed-off-by: Kiran Gunda 
Reviewed-by: Bjorn Andersson 
---
 drivers/video/backlight/qcom-wled.c | 263 +++-
 1 file changed, 257 insertions(+), 6 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 45eeda4..2807b4b 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -17,7 +17,7 @@
 
 #define WLED3_SINK_REG_BRIGHT_MAX  0xFFF
 
-/* WLED3 control registers */
+/* WLED3/WLED4 control registers */
 #define WLED3_CTRL_REG_MOD_EN  0x46
 #define  WLED3_CTRL_REG_MOD_EN_MASKBIT(7)
 #define  WLED3_CTRL_REG_MOD_EN_SHIFT   7
@@ -31,7 +31,7 @@
 #define WLED3_CTRL_REG_ILIMIT  0x4e
 #define  WLED3_CTRL_REG_ILIMIT_MASKGENMASK(2, 0)
 
-/* WLED3 sink registers */
+/* WLED3/WLED4 sink registers */
 #define WLED3_SINK_REG_SYNC0x47
 #define  WLED3_SINK_REG_SYNC_CLEAR 0x00
 
@@ -56,6 +56,28 @@
 #define WLED3_SINK_REG_STR_CABC(n) (0x66 + (n * 0x10))
 #define  WLED3_SINK_REG_STR_CABC_MASK  BIT(7)
 
+/* WLED4 specific sink registers */
+#define WLED4_SINK_REG_CURR_SINK   0x46
+#define  WLED4_SINK_REG_CURR_SINK_MASK GENMASK(7, 4)
+#define  WLED4_SINK_REG_CURR_SINK_SHFT 4
+
+/* WLED4 specific per-'string' registers below */
+#define WLED4_SINK_REG_STR_MOD_EN(n)   (0x50 + (n * 0x10))
+#define  WLED4_SINK_REG_STR_MOD_MASK   BIT(7)
+
+#define WLED4_SINK_REG_STR_FULL_SCALE_CURR(n)  (0x52 + (n * 0x10))
+#define  WLED4_SINK_REG_STR_FULL_SCALE_CURR_MASK   GENMASK(3, 0)
+
+#define WLED4_SINK_REG_STR_MOD_SRC(n)  (0x53 + (n * 0x10))
+#define  WLED4_SINK_REG_STR_MOD_SRC_MASK   BIT(0)
+#define  WLED4_SINK_REG_STR_MOD_SRC_INT0x00
+#define  WLED4_SINK_REG_STR_MOD_SRC_EXT0x01
+
+#define WLED4_SINK_REG_STR_CABC(n) (0x56 + (n * 0x10))
+#define  WLED4_SINK_REG_STR_CABC_MASK  BIT(7)
+
+#define WLED4_SINK_REG_BRIGHT(n)   (0x57 + (n * 0x10))
+
 struct wled_var_cfg {
const u32 *values;
u32 (*fn)(u32);
@@ -90,6 +112,7 @@ struct wled {
struct device *dev;
struct regmap *regmap;
u16 ctrl_addr;
+   u16 sink_addr;
u16 max_string_count;
u32 brightness;
u32 max_brightness;
@@ -116,6 +139,29 @@ static int wled3_set_brightness(struct wled *wled, u16 
brightness)
return 0;
 }
 
+static int wled4_set_brightness(struct wled *wled, u16 brightness)
+{
+   int rc, i;
+   u16 low_limit = wled->max_brightness * 4 / 1000;
+   u8 v[2];
+
+   /* WLED4's lower limit of operation is 0.4% */
+   if (brightness > 0 && brightness < low_limit)
+   brightness = low_limit;
+
+   v[0] = brightness & 0xff;
+   v[1] = (brightness >> 8) & 0xf;
+
+   for (i = 0;  i < wled->cfg.num_strings; ++i) {
+   rc = regmap_bulk_write(wled->regmap, wled->sink_addr +
+  WLED4_SINK_REG_BRIGHT(i), v, 2);
+   if (rc < 0)
+   return rc;
+   }
+
+   return 0;
+}
+
 static int wled_module_enable(struct wled *wled, int val)
 {
int rc;
@@ -267,6 +313,120 @@ static int wled3_setup(struct wled *wled)
.enabled_strings = {0, 1, 2, 3},
 };
 
+static int wled4_setup(struct wled *wled)
+{
+   int rc, temp, i, j;
+   u16 addr;
+   u8 sink_en = 0;
+   u32 sink_cfg = 0;
+
+   rc = regmap_update_bits(wled->regmap,
+   wled->ctrl_addr + WLED3_CTRL_REG_OVP,
+   WLED3_CTRL_REG_OVP_MASK, wled->cfg.ovp);
+   if (rc < 0)
+   return rc;
+
+   rc = regmap_update_bits(wled->regmap,
+   wled->ctrl_addr + WLED3_CTRL_REG_ILIMIT,
+   WLED3_CTRL_REG_ILIMIT_MASK,
+   wled->cfg.boost_i_limit);
+   if (rc < 0)
+   return rc;
+
+   rc = regmap_update_bits(wled->regmap,
+   wled->ctrl_addr + WLED3_CTRL_REG_FREQ,
+   WLED3_CTRL_REG_FREQ_MASK,
+   wled->cfg.switch_freq);
+   if (rc < 0)
+   return rc;
+
+   rc = regmap_read(wled->regmap, wled->sink_addr +
+WLED4_SINK_REG_CURR_SINK, _cfg);
+   if (rc < 0)
+   return rc;
+
+   for (i = 0; i < wled->c

[PATCH V8 1/6] backlight: qcom-wled: Add new properties for PMI8998.

2019-10-18 Thread Kiran Gunda
Update the bindings with the new properties used for
PMI8998.

Signed-off-by: Kiran Gunda 
Reviewed-by: Bjorn Andersson 
Reviewed-by: Rob Herring 
Acked-by: Daniel Thompson 
---
 .../bindings/leds/backlight/qcom-wled.txt  | 74 ++
 1 file changed, 63 insertions(+), 11 deletions(-)

diff --git a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt 
b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
index 14f28f2..c06863b 100644
--- a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
+++ b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
@@ -20,7 +20,7 @@ platforms. The PMIC is connected to the host processor via 
SPMI bus.
 - default-brightness
Usage:optional
Value type:   
-   Definition:   brightness value on boot, value from: 0-4095
+   Definition:   brightness value on boot, value from: 0-4095.
  Default: 2048
 
 - label
@@ -48,20 +48,24 @@ platforms. The PMIC is connected to the host processor via 
SPMI bus.
 - qcom,current-limit
Usage:optional
Value type:   
-   Definition:   mA; per-string current limit
- value: For pm8941: from 0 to 25 with 5 mA step
-Default 20 mA.
-For pmi8998: from 0 to 30 with 5 mA step
-Default 25 mA.
+   Definition:   mA; per-string current limit; value from 0 to 25 with
+ 1 mA step. Default 20 mA.
+ This property is supported only for pm8941.
+
+- qcom,current-limit-microamp
+   Usage:optional
+   Value type:   
+   Definition:   uA; per-string current limit; value from 0 to 3 with
+ 2500 uA step. Default 25 mA.
 
 - qcom,current-boost-limit
Usage:optional
Value type:   
Definition:   mA; boost current limit.
  For pm8941: one of: 105, 385, 525, 805, 980, 1260, 1400,
- 1680. Default: 805 mA
+ 1680. Default: 805 mA.
  For pmi8998: one of: 105, 280, 450, 620, 970, 1150, 1300,
- 1500. Default: 970 mA
+ 1500. Default: 970 mA.
 
 - qcom,switching-freq
Usage:optional
@@ -76,15 +80,62 @@ platforms. The PMIC is connected to the host processor via 
SPMI bus.
Usage:optional
Value type:   
Definition:   V; Over-voltage protection limit; one of:
- 27, 29, 32, 35. default: 29V
+ 27, 29, 32, 35. Default: 29V
  This property is supported only for PM8941.
 
+- qcom,ovp-millivolt
+   Usage:optional
+   Value type:   
+   Definition:   mV; Over-voltage protection limit;
+ For pmi8998: one of 18100, 19600, 29600, 31100.
+ Default 29600 mV.
+ If this property is not specified for PM8941, it
+ falls back to "qcom,ovp" property.
+
 - qcom,num-strings
Usage:optional
Value type:   
Definition:   #; number of led strings attached;
- value from 1 to 3. default: 2
- This property is supported only for PM8941.
+ value: For PM8941 from 1 to 3. Default: 2
+For PMI8998 from 1 to 4.
+
+- interrupts
+   Usage:optional
+   Value type:   
+   Definition:   Interrupts associated with WLED. This should be
+ "short" and "ovp" interrupts. Interrupts can be
+ specified as per the encoding listed under
+ Documentation/devicetree/bindings/spmi/
+ qcom,spmi-pmic-arb.txt.
+
+- interrupt-names
+   Usage:optional
+   Value type:   
+   Definition:   Interrupt names associated with the interrupts.
+ Must be "short" and "ovp". The short circuit detection
+ is not supported for PM8941.
+
+- qcom,enabled-strings
+   Usage:optional
+   Value tyoe:   
+   Definition:   Array of the WLED strings numbered from 0 to 3. Each
+ string of leds are operated individually. Specify the
+ list of strings used by the device. Any combination of
+ led strings can be used.
+
+- qcom,external-pfet
+   Usage:optional
+   Value type:   
+   Definition:   Specify if external PFET control for short circuit
+ protection is used. This property is supported only
+ for PMI8998.
+
+- qcom,auto-string-detection
+   Usage:optional
+   Value type:   
+   Definition:   Enables auto-detection of the WLED string configuration.
+ This feature is not sup

[PATCH V8 2/6] backlight: qcom-wled: Rename PM8941* to WLED3

2019-10-18 Thread Kiran Gunda
Rename the PM8941* references as WLED3 to make the driver
generic and have WLED support for other PMICs. Also rename
"i_boost_limit" and "i_limit" variables to "boost_i_limit"
and "string_i_limit" respectively to resemble the corresponding
register names.

Signed-off-by: Kiran Gunda 
Reviewed-by: Daniel Thompson 
Reviewed-by: Bjorn Andersson 
Acked-by: Pavel Machek 
---
 drivers/video/backlight/qcom-wled.c | 248 ++--
 1 file changed, 125 insertions(+), 123 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 82b8572..f191242 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -10,77 +10,79 @@
 #include 
 
 /* From DT binding */
-#define PM8941_WLED_DEFAULT_BRIGHTNESS 2048
+#define WLED_DEFAULT_BRIGHTNESS2048
 
-#define PM8941_WLED_REG_VAL_BASE   0x40
-#define  PM8941_WLED_REG_VAL_MAX   0xFFF
+#define WLED3_SINK_REG_BRIGHT_MAX  0xFFF
+#define WLED3_CTRL_REG_VAL_BASE0x40
 
-#define PM8941_WLED_REG_MOD_EN 0x46
-#define  PM8941_WLED_REG_MOD_EN_BITBIT(7)
-#define  PM8941_WLED_REG_MOD_EN_MASK   BIT(7)
+/* WLED3 control registers */
+#define WLED3_CTRL_REG_MOD_EN  0x46
+#define  WLED3_CTRL_REG_MOD_EN_BIT BIT(7)
+#define  WLED3_CTRL_REG_MOD_EN_MASKBIT(7)
 
-#define PM8941_WLED_REG_SYNC   0x47
-#define  PM8941_WLED_REG_SYNC_MASK 0x07
-#define  PM8941_WLED_REG_SYNC_LED1 BIT(0)
-#define  PM8941_WLED_REG_SYNC_LED2 BIT(1)
-#define  PM8941_WLED_REG_SYNC_LED3 BIT(2)
-#define  PM8941_WLED_REG_SYNC_ALL  0x07
-#define  PM8941_WLED_REG_SYNC_CLEAR0x00
+#define WLED3_CTRL_REG_FREQ0x4c
+#define  WLED3_CTRL_REG_FREQ_MASK  0x0f
 
-#define PM8941_WLED_REG_FREQ   0x4c
-#define  PM8941_WLED_REG_FREQ_MASK 0x0f
+#define WLED3_CTRL_REG_OVP 0x4d
+#define  WLED3_CTRL_REG_OVP_MASK   0x03
 
-#define PM8941_WLED_REG_OVP0x4d
-#define  PM8941_WLED_REG_OVP_MASK  0x03
+#define WLED3_CTRL_REG_ILIMIT  0x4e
+#define  WLED3_CTRL_REG_ILIMIT_MASK0x07
 
-#define PM8941_WLED_REG_BOOST  0x4e
-#define  PM8941_WLED_REG_BOOST_MASK0x07
+/* WLED3 sink registers */
+#define WLED3_SINK_REG_SYNC0x47
+#define  WLED3_SINK_REG_SYNC_MASK  0x07
+#define  WLED3_SINK_REG_SYNC_LED1  BIT(0)
+#define  WLED3_SINK_REG_SYNC_LED2  BIT(1)
+#define  WLED3_SINK_REG_SYNC_LED3  BIT(2)
+#define  WLED3_SINK_REG_SYNC_ALL   0x07
+#define  WLED3_SINK_REG_SYNC_CLEAR 0x00
 
-#define PM8941_WLED_REG_SINK   0x4f
-#define  PM8941_WLED_REG_SINK_MASK 0xe0
-#define  PM8941_WLED_REG_SINK_SHFT 0x05
+#define WLED3_SINK_REG_CURR_SINK   0x4f
+#define  WLED3_SINK_REG_CURR_SINK_MASK 0xe0
+#define  WLED3_SINK_REG_CURR_SINK_SHFT 0x05
 
-/* Per-'string' registers below */
-#define PM8941_WLED_REG_STR_OFFSET 0x10
+/* WLED3 per-'string' registers below */
+#define WLED3_SINK_REG_STR_OFFSET  0x10
 
-#define PM8941_WLED_REG_STR_MOD_EN_BASE0x60
-#define  PM8941_WLED_REG_STR_MOD_MASK  BIT(7)
-#define  PM8941_WLED_REG_STR_MOD_ENBIT(7)
+#define WLED3_SINK_REG_STR_MOD_EN_BASE 0x60
+#define  WLED3_SINK_REG_STR_MOD_MASK   BIT(7)
+#define  WLED3_SINK_REG_STR_MOD_EN BIT(7)
 
-#define PM8941_WLED_REG_STR_SCALE_BASE 0x62
-#define  PM8941_WLED_REG_STR_SCALE_MASK0x1f
+#define WLED3_SINK_REG_STR_FULL_SCALE_CURR 0x62
+#define  WLED3_SINK_REG_STR_FULL_SCALE_CURR_MASK   0x1f
 
-#define PM8941_WLED_REG_STR_MOD_SRC_BASE   0x63
-#define  PM8941_WLED_REG_STR_MOD_SRC_MASK  0x01
-#define  PM8941_WLED_REG_STR_MOD_SRC_INT   0x00
-#define  PM8941_WLED_REG_STR_MOD_SRC_EXT   0x01
+#define WLED3_SINK_REG_STR_MOD_SRC_BASE0x63
+#define  WLED3_SINK_REG_STR_MOD_SRC_MASK   0x01
+#define  WLED3_SINK_REG_STR_MOD_SRC_INT0x00
+#define  WLED3_SINK_REG_STR_MOD_SRC_EXT0x01
 
-#define PM8941_WLED_REG_STR_CABC_BASE  0x66
-#define  PM8941_WLED_REG_STR_CABC_MASK BIT(7)
-#define  PM8941_WLED_REG_STR_CABC_EN   BIT(7)
+#define WLED3_SINK_REG_STR_CABC_BASE   0x66
+#define  WLED3_SINK_REG_STR_CABC_MASK  BIT

[PATCH V8 4/6] backlight: qcom-wled: Add support for WLED4 peripheral.

2019-10-18 Thread Kiran Gunda
WLED4 peripheral is present on some PMICs like pmi8998 and
pm660l. It has a different register map and configurations
are also different. Add support for it.

Signed-off-by: Kiran Gunda 
Reviewed-by: Bjorn Andersson 
---
 drivers/video/backlight/qcom-wled.c | 255 +++-
 1 file changed, 253 insertions(+), 2 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 45eeda4..5386ca9 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -17,7 +17,7 @@
 
 #define WLED3_SINK_REG_BRIGHT_MAX  0xFFF
 
-/* WLED3 control registers */
+/* WLED3/WLED4 control registers */
 #define WLED3_CTRL_REG_MOD_EN  0x46
 #define  WLED3_CTRL_REG_MOD_EN_MASKBIT(7)
 #define  WLED3_CTRL_REG_MOD_EN_SHIFT   7
@@ -31,7 +31,7 @@
 #define WLED3_CTRL_REG_ILIMIT  0x4e
 #define  WLED3_CTRL_REG_ILIMIT_MASKGENMASK(2, 0)
 
-/* WLED3 sink registers */
+/* WLED3/WLED4 sink registers */
 #define WLED3_SINK_REG_SYNC0x47
 #define  WLED3_SINK_REG_SYNC_CLEAR 0x00
 
@@ -56,6 +56,28 @@
 #define WLED3_SINK_REG_STR_CABC(n) (0x66 + (n * 0x10))
 #define  WLED3_SINK_REG_STR_CABC_MASK  BIT(7)
 
+/* WLED4 specific sink registers */
+#define WLED4_SINK_REG_CURR_SINK   0x46
+#define  WLED4_SINK_REG_CURR_SINK_MASK GENMASK(7, 4)
+#define  WLED4_SINK_REG_CURR_SINK_SHFT 4
+
+/* WLED4 specific per-'string' registers below */
+#define WLED4_SINK_REG_STR_MOD_EN(n)   (0x50 + (n * 0x10))
+#define  WLED4_SINK_REG_STR_MOD_MASK   BIT(7)
+
+#define WLED4_SINK_REG_STR_FULL_SCALE_CURR(n)  (0x52 + (n * 0x10))
+#define  WLED4_SINK_REG_STR_FULL_SCALE_CURR_MASK   GENMASK(3, 0)
+
+#define WLED4_SINK_REG_STR_MOD_SRC(n)  (0x53 + (n * 0x10))
+#define  WLED4_SINK_REG_STR_MOD_SRC_MASK   BIT(0)
+#define  WLED4_SINK_REG_STR_MOD_SRC_INT0x00
+#define  WLED4_SINK_REG_STR_MOD_SRC_EXT0x01
+
+#define WLED4_SINK_REG_STR_CABC(n) (0x56 + (n * 0x10))
+#define  WLED4_SINK_REG_STR_CABC_MASK  BIT(7)
+
+#define WLED4_SINK_REG_BRIGHT(n)   (0x57 + (n * 0x10))
+
 struct wled_var_cfg {
const u32 *values;
u32 (*fn)(u32);
@@ -90,6 +112,7 @@ struct wled {
struct device *dev;
struct regmap *regmap;
u16 ctrl_addr;
+   u16 sink_addr;
u16 max_string_count;
u32 brightness;
u32 max_brightness;
@@ -116,6 +139,29 @@ static int wled3_set_brightness(struct wled *wled, u16 
brightness)
return 0;
 }
 
+static int wled4_set_brightness(struct wled *wled, u16 brightness)
+{
+   int rc, i;
+   u16 low_limit = wled->max_brightness * 4 / 1000;
+   u8 v[2];
+
+   /* WLED4's lower limit of operation is 0.4% */
+   if (brightness > 0 && brightness < low_limit)
+   brightness = low_limit;
+
+   v[0] = brightness & 0xff;
+   v[1] = (brightness >> 8) & 0xf;
+
+   for (i = 0;  i < wled->cfg.num_strings; ++i) {
+   rc = regmap_bulk_write(wled->regmap, wled->sink_addr +
+  WLED4_SINK_REG_BRIGHT(i), v, 2);
+   if (rc < 0)
+   return rc;
+   }
+
+   return 0;
+}
+
 static int wled_module_enable(struct wled *wled, int val)
 {
int rc;
@@ -267,6 +313,120 @@ static int wled3_setup(struct wled *wled)
.enabled_strings = {0, 1, 2, 3},
 };
 
+static int wled4_setup(struct wled *wled)
+{
+   int rc, temp, i, j;
+   u16 addr;
+   u8 sink_en = 0;
+   u32 sink_cfg = 0;
+
+   rc = regmap_update_bits(wled->regmap,
+   wled->ctrl_addr + WLED3_CTRL_REG_OVP,
+   WLED3_CTRL_REG_OVP_MASK, wled->cfg.ovp);
+   if (rc < 0)
+   return rc;
+
+   rc = regmap_update_bits(wled->regmap,
+   wled->ctrl_addr + WLED3_CTRL_REG_ILIMIT,
+   WLED3_CTRL_REG_ILIMIT_MASK,
+   wled->cfg.boost_i_limit);
+   if (rc < 0)
+   return rc;
+
+   rc = regmap_update_bits(wled->regmap,
+   wled->ctrl_addr + WLED3_CTRL_REG_FREQ,
+   WLED3_CTRL_REG_FREQ_MASK,
+   wled->cfg.switch_freq);
+   if (rc < 0)
+   return rc;
+
+   rc = regmap_read(wled->regmap, wled->sink_addr +
+WLED4_SINK_REG_CURR_SINK, _cfg);
+   if (rc < 0)
+   return rc;
+
+   for (i = 0; i < wled->c

[PATCH V8 6/6] backlight: qcom-wled: Add auto string detection logic

2019-10-18 Thread Kiran Gunda
The auto string detection algorithm checks if the current WLED
sink configuration is valid. It tries enabling every sink and
checks if the OVP fault is observed. Based on this information
it detects and enables the valid sink configuration.
Auto calibration will be triggered when the OVP fault interrupts
are seen frequently thereby it tries to fix the sink configuration.

The auto-detection also kicks in when the connected LED string
of the display-backlight malfunctions (because of damage) and
requires the damaged string to be turned off to prevent the
complete panel and/or board from being damaged.

Signed-off-by: Kiran Gunda 
---
 drivers/video/backlight/qcom-wled.c | 398 +++-
 1 file changed, 392 insertions(+), 6 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 658b1e0..b2e6754 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -17,19 +17,29 @@
 #define WLED_MAX_STRINGS   4
 
 #define WLED_DEFAULT_BRIGHTNESS2048
-
+#define WLED_SOFT_START_DLY_US 1
 #define WLED3_SINK_REG_BRIGHT_MAX  0xFFF
 
 /* WLED3/WLED4 control registers */
+#define WLED3_CTRL_REG_FAULT_STATUS0x08
+#define  WLED3_CTRL_REG_ILIM_FAULT_BIT BIT(0)
+#define  WLED3_CTRL_REG_OVP_FAULT_BIT  BIT(1)
+#define  WLED4_CTRL_REG_SC_FAULT_BIT   BIT(2)
+
+#define WLED3_CTRL_REG_INT_RT_STS  0x10
+#define  WLED3_CTRL_REG_OVP_FAULT_STATUS   BIT(1)
+
 #define WLED3_CTRL_REG_MOD_EN  0x46
 #define  WLED3_CTRL_REG_MOD_EN_MASKBIT(7)
 #define  WLED3_CTRL_REG_MOD_EN_SHIFT   7
 
+#define WLED3_CTRL_REG_FEEDBACK_CONTROL0x48
+
 #define WLED3_CTRL_REG_FREQ0x4c
 #define  WLED3_CTRL_REG_FREQ_MASK  GENMASK(3, 0)
 
 #define WLED3_CTRL_REG_OVP 0x4d
-#define  WLED3_CTRL_REG_OVP_MASK   GENMASK(1, 0)
+#define  WLED3_CTRL_REG_OVP_MASK   GENMASK(1, 0)
 
 #define WLED3_CTRL_REG_ILIMIT  0x4e
 #define  WLED3_CTRL_REG_ILIMIT_MASKGENMASK(2, 0)
@@ -119,6 +129,7 @@ struct wled_config {
bool ext_gen;
bool cabc;
bool external_pfet;
+   bool auto_detection_enabled;
 };
 
 struct wled {
@@ -127,17 +138,22 @@ struct wled {
struct regmap *regmap;
struct mutex lock;  /* Lock to avoid race from thread irq handler */
ktime_t last_short_event;
+   ktime_t start_ovp_fault_time;
u16 ctrl_addr;
u16 sink_addr;
u16 max_string_count;
+   u16 auto_detection_ovp_count;
u32 brightness;
u32 max_brightness;
u32 short_count;
+   u32 auto_detect_count;
bool disabled_by_short;
bool has_short_detect;
int short_irq;
+   int ovp_irq;
 
struct wled_config cfg;
+   struct delayed_work ovp_work;
int (*wled_set_brightness)(struct wled *wled, u16 brightness);
 };
 
@@ -182,6 +198,13 @@ static int wled4_set_brightness(struct wled *wled, u16 
brightness)
return 0;
 }
 
+static void wled_ovp_work(struct work_struct *work)
+{
+   struct wled *wled = container_of(work,
+struct wled, ovp_work.work);
+   enable_irq(wled->ovp_irq);
+}
+
 static int wled_module_enable(struct wled *wled, int val)
 {
int rc;
@@ -193,7 +216,23 @@ static int wled_module_enable(struct wled *wled, int val)
WLED3_CTRL_REG_MOD_EN,
WLED3_CTRL_REG_MOD_EN_MASK,
val << WLED3_CTRL_REG_MOD_EN_SHIFT);
-   return rc;
+   if (rc < 0)
+   return rc;
+
+   if (wled->ovp_irq > 0) {
+   if (val) {
+   /*
+* Wait for at least 10ms before enabling OVP interrupt
+* after module enable so that soft start is completed.
+*/
+   schedule_delayed_work(>ovp_work, HZ / 100);
+   } else {
+   if (!cancel_delayed_work_sync(>ovp_work))
+   disable_irq(wled->ovp_irq);
+   }
+   }
+
+   return 0;
 }
 
 static int wled_sync_toggle(struct wled *wled)
@@ -300,6 +339,304 @@ static irqreturn_t wled_short_irq_handler(int irq, void 
*_wled)
return IRQ_HANDLED;
 }
 
+#define AUTO_DETECT_BRIGHTNESS 200
+
+static void wled_auto_string_detection(struct wled *wled)
+{
+   int rc = 0, i;
+   u32 sink_config = 0, int_sts;
+   u8 sink_test = 0, sink_valid = 0, val;
+
+   /* Read configured sink 

[PATCH V8 5/6] backlight: qcom-wled: add support for short circuit handling.

2019-10-18 Thread Kiran Gunda
Handle the short circuit interrupt and check if the short circuit
interrupt is valid. Re-enable the module to check if it goes
away. Disable the module altogether if the short circuit event
persists.

Signed-off-by: Kiran Gunda 
Reviewed-by: Bjorn Andersson 
Reviewed-by: Daniel Thompson 
---
 drivers/video/backlight/qcom-wled.c | 144 +++-
 1 file changed, 140 insertions(+), 4 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 5386ca9..658b1e0 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -2,6 +2,9 @@
 /* Copyright (c) 2015, Sony Mobile Communications, AB.
  */
 
+#include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -56,6 +59,16 @@
 #define WLED3_SINK_REG_STR_CABC(n) (0x66 + (n * 0x10))
 #define  WLED3_SINK_REG_STR_CABC_MASK  BIT(7)
 
+/* WLED4 specific control registers */
+#define WLED4_CTRL_REG_SHORT_PROTECT   0x5e
+#define  WLED4_CTRL_REG_SHORT_EN_MASK  BIT(7)
+
+#define WLED4_CTRL_REG_SEC_ACCESS  0xd0
+#define  WLED4_CTRL_REG_SEC_UNLOCK 0xa5
+
+#define WLED4_CTRL_REG_TEST1   0xe2
+#define  WLED4_CTRL_REG_TEST1_EXT_FET_DTEST2   0x09
+
 /* WLED4 specific sink registers */
 #define WLED4_SINK_REG_CURR_SINK   0x46
 #define  WLED4_SINK_REG_CURR_SINK_MASK GENMASK(7, 4)
@@ -105,17 +118,24 @@ struct wled_config {
bool cs_out_en;
bool ext_gen;
bool cabc;
+   bool external_pfet;
 };
 
 struct wled {
const char *name;
struct device *dev;
struct regmap *regmap;
+   struct mutex lock;  /* Lock to avoid race from thread irq handler */
+   ktime_t last_short_event;
u16 ctrl_addr;
u16 sink_addr;
u16 max_string_count;
u32 brightness;
u32 max_brightness;
+   u32 short_count;
+   bool disabled_by_short;
+   bool has_short_detect;
+   int short_irq;
 
struct wled_config cfg;
int (*wled_set_brightness)(struct wled *wled, u16 brightness);
@@ -166,6 +186,9 @@ static int wled_module_enable(struct wled *wled, int val)
 {
int rc;
 
+   if (wled->disabled_by_short)
+   return -ENXIO;
+
rc = regmap_update_bits(wled->regmap, wled->ctrl_addr +
WLED3_CTRL_REG_MOD_EN,
WLED3_CTRL_REG_MOD_EN_MASK,
@@ -202,18 +225,19 @@ static int wled_update_status(struct backlight_device *bl)
bl->props.state & BL_CORE_FBBLANK)
brightness = 0;
 
+   mutex_lock(>lock);
if (brightness) {
rc = wled->wled_set_brightness(wled, brightness);
if (rc < 0) {
dev_err(wled->dev, "wled failed to set brightness 
rc:%d\n",
rc);
-   return rc;
+   goto unlock_mutex;
}
 
rc = wled_sync_toggle(wled);
if (rc < 0) {
dev_err(wled->dev, "wled sync failed rc:%d\n", rc);
-   return rc;
+   goto unlock_mutex;
}
}
 
@@ -221,15 +245,61 @@ static int wled_update_status(struct backlight_device *bl)
rc = wled_module_enable(wled, !!brightness);
if (rc < 0) {
dev_err(wled->dev, "wled enable failed rc:%d\n", rc);
-   return rc;
+   goto unlock_mutex;
}
}
 
wled->brightness = brightness;
 
+unlock_mutex:
+   mutex_unlock(>lock);
+
return rc;
 }
 
+#define WLED_SHORT_DLY_MS  20
+#define WLED_SHORT_CNT_MAX 5
+#define WLED_SHORT_RESET_CNT_DLY_USUSEC_PER_SEC
+
+static irqreturn_t wled_short_irq_handler(int irq, void *_wled)
+{
+   struct wled *wled = _wled;
+   int rc;
+   s64 elapsed_time;
+
+   wled->short_count++;
+   mutex_lock(>lock);
+   rc = wled_module_enable(wled, false);
+   if (rc < 0) {
+   dev_err(wled->dev, "wled disable failed rc:%d\n", rc);
+   goto unlock_mutex;
+   }
+
+   elapsed_time = ktime_us_delta(ktime_get(),
+ wled->last_short_event);
+   if (elapsed_time > WLED_SHORT_RESET_CNT_DLY_US)
+   wled->short_count = 1;
+
+   if (wled->short_count > WLED_SHORT_CNT_MAX) {
+   dev_err(wled->dev, "Short trigged %d times, disabling WLED 
forever!\n",
+   wled->short_count);
+   wled->disabled_by_short = true;
+   goto unlock_mutex;
+

[PATCH V8 3/6] backlight: qcom-wled: Restructure the driver for WLED3.

2019-10-18 Thread Kiran Gunda
Restructure the driver to add the support for new WLED
peripherals.

Signed-off-by: Kiran Gunda 
Acked-by: Daniel Thompson 
---
 drivers/video/backlight/qcom-wled.c | 373 ++--
 1 file changed, 234 insertions(+), 139 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index f191242..45eeda4 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -7,59 +7,71 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 /* From DT binding */
+#define WLED_MAX_STRINGS   4
+
 #define WLED_DEFAULT_BRIGHTNESS2048
 
 #define WLED3_SINK_REG_BRIGHT_MAX  0xFFF
-#define WLED3_CTRL_REG_VAL_BASE0x40
 
 /* WLED3 control registers */
 #define WLED3_CTRL_REG_MOD_EN  0x46
-#define  WLED3_CTRL_REG_MOD_EN_BIT BIT(7)
 #define  WLED3_CTRL_REG_MOD_EN_MASKBIT(7)
+#define  WLED3_CTRL_REG_MOD_EN_SHIFT   7
 
 #define WLED3_CTRL_REG_FREQ0x4c
-#define  WLED3_CTRL_REG_FREQ_MASK  0x0f
+#define  WLED3_CTRL_REG_FREQ_MASK  GENMASK(3, 0)
 
 #define WLED3_CTRL_REG_OVP 0x4d
-#define  WLED3_CTRL_REG_OVP_MASK   0x03
+#define  WLED3_CTRL_REG_OVP_MASK   GENMASK(1, 0)
 
 #define WLED3_CTRL_REG_ILIMIT  0x4e
-#define  WLED3_CTRL_REG_ILIMIT_MASK0x07
+#define  WLED3_CTRL_REG_ILIMIT_MASKGENMASK(2, 0)
 
 /* WLED3 sink registers */
 #define WLED3_SINK_REG_SYNC0x47
-#define  WLED3_SINK_REG_SYNC_MASK  0x07
-#define  WLED3_SINK_REG_SYNC_LED1  BIT(0)
-#define  WLED3_SINK_REG_SYNC_LED2  BIT(1)
-#define  WLED3_SINK_REG_SYNC_LED3  BIT(2)
-#define  WLED3_SINK_REG_SYNC_ALL   0x07
 #define  WLED3_SINK_REG_SYNC_CLEAR 0x00
 
 #define WLED3_SINK_REG_CURR_SINK   0x4f
-#define  WLED3_SINK_REG_CURR_SINK_MASK 0xe0
-#define  WLED3_SINK_REG_CURR_SINK_SHFT 0x05
+#define  WLED3_SINK_REG_CURR_SINK_MASK GENMASK(7, 5)
+#define  WLED3_SINK_REG_CURR_SINK_SHFT 5
 
-/* WLED3 per-'string' registers below */
-#define WLED3_SINK_REG_STR_OFFSET  0x10
+/* WLED3 specific per-'string' registers below */
+#define WLED3_SINK_REG_BRIGHT(n)   (0x40 + n)
 
-#define WLED3_SINK_REG_STR_MOD_EN_BASE 0x60
+#define WLED3_SINK_REG_STR_MOD_EN(n)   (0x60 + (n * 0x10))
 #define  WLED3_SINK_REG_STR_MOD_MASK   BIT(7)
-#define  WLED3_SINK_REG_STR_MOD_EN BIT(7)
 
-#define WLED3_SINK_REG_STR_FULL_SCALE_CURR 0x62
-#define  WLED3_SINK_REG_STR_FULL_SCALE_CURR_MASK   0x1f
+#define WLED3_SINK_REG_STR_FULL_SCALE_CURR(n)  (0x62 + (n * 0x10))
+#define  WLED3_SINK_REG_STR_FULL_SCALE_CURR_MASK   GENMASK(4, 0)
 
-#define WLED3_SINK_REG_STR_MOD_SRC_BASE0x63
-#define  WLED3_SINK_REG_STR_MOD_SRC_MASK   0x01
+#define WLED3_SINK_REG_STR_MOD_SRC(n)  (0x63 + (n * 0x10))
+#define  WLED3_SINK_REG_STR_MOD_SRC_MASK   BIT(0)
 #define  WLED3_SINK_REG_STR_MOD_SRC_INT0x00
 #define  WLED3_SINK_REG_STR_MOD_SRC_EXT0x01
 
-#define WLED3_SINK_REG_STR_CABC_BASE   0x66
+#define WLED3_SINK_REG_STR_CABC(n) (0x66 + (n * 0x10))
 #define  WLED3_SINK_REG_STR_CABC_MASK  BIT(7)
-#define  WLED3_SINK_REG_STR_CABC_ENBIT(7)
+
+struct wled_var_cfg {
+   const u32 *values;
+   u32 (*fn)(u32);
+   int size;
+};
+
+struct wled_u32_opts {
+   const char *name;
+   u32 *val_ptr;
+   const struct wled_var_cfg *cfg;
+};
+
+struct wled_bool_opts {
+   const char *name;
+   bool *val_ptr;
+};
 
 struct wled_config {
u32 boost_i_limit;
@@ -67,132 +79,179 @@ struct wled_config {
u32 switch_freq;
u32 num_strings;
u32 string_i_limit;
+   u32 enabled_strings[WLED_MAX_STRINGS];
bool cs_out_en;
bool ext_gen;
-   bool cabc_en;
+   bool cabc;
 };
 
 struct wled {
const char *name;
+   struct device *dev;
struct regmap *regmap;
-   u16 addr;
+   u16 ctrl_addr;
+   u16 max_string_count;
+   u32 brightness;
+   u32 max_brightness;
 
struct wled_config cfg;
+   int (*wled_set_brightness)(struct wled *wled, u16 brightness);
 };
 
+static int wled3_set_brightness(struct wled *wled, u16 brightness)
+{
+   int rc, i;
+   u8 v[2];
+
+   v[0] = brightness & 0xff;
+  

[PATCH V8 0/6] backlight: qcom-wled: Support for QCOM wled driver

2019-10-18 Thread Kiran Gunda
This patch series renames the pm8941-wled.c driver to qcom-wled.c to add
the support for multiple PMICs supported by qualcomm. This patch series
supports both PM8941 and PMI8998 WLED. The PMI8998 WLED has the support
to handle the OVP (over voltage protection) and the SC (short circuit
protection)
interrupts. It also has the auto string detection algorithm support to
configure the right strings if the user specified string configuration
is in-correct. These three features are added in this series for PMI8998.

changes from v1:
   - Fixed the commit message for
   - backlight: qcom-wled: Rename pm8941-wled.c to qcom-wled.c

Changes from v2:
   - Fixed bjorn and other reviewer's comments
   - Seperated the device tree bindings
   - Splitted out the WLED4 changes in seperate patch
   - Merged OVP and auto string detection patch

Changes from v3:
  - Added Reviewed-by/Acked-by tags
  - Fixed comments from Bjorn/Vinod/Rob
  - Splitting the "backlight: qcom-wled: Add support for WLED4 peripheral" patch
to seperate the WLED3 specific restructure.

Changes from v4:
  - Added reviewed-by/Acked-by tags
  - Fixed comments from Bjorn/Daniel/Pavel

Changes from v5:
  - Fixed comments from Bjorn/Pavel

Changes from v5/v6:
  - Fixed comments from Bjorn/Pavel on V5 series, which were missed in V6 series
  - Patch 1 and 2, mentioned below, from V6 series are picked by Pavel In next.
Hence, dropped them in this series.
https://lore.kernel.org/patchwork/patch/1132467/
https://lore.kernel.org/patchwork/patch/1132468/

Changes from v7:
  - Addressed comments from Daniel Thompson/Lee Jones
  - Patch 1 and 2, mentioned below, from V6 series are picked by Pavel In next.
Hence, dropped them in this series.
https://lore.kernel.org/patchwork/patch/1132467/
https://lore.kernel.org/patchwork/patch/1132468/

Kiran Gunda (6):
  backlight: qcom-wled: Add new properties for PMI8998.
  backlight: qcom-wled: Rename PM8941* to WLED3
  backlight: qcom-wled: Restructure the driver for WLED3.
  backlight: qcom-wled: Add support for WLED4 peripheral.
  backlight: qcom-wled: add support for short circuit handling.
  backlight: qcom-wled: Add auto string detection logic

 .../bindings/leds/backlight/qcom-wled.txt  |   74 +-
 drivers/video/backlight/qcom-wled.c| 1254 +---
 2 files changed, 1125 insertions(+), 203 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project



[PATCH V7 3/6] backlight: qcom-wled: Restructure the driver for WLED3

2019-10-16 Thread Kiran Gunda
Restructure the driver to add the support for new WLED
peripherals.

Signed-off-by: Kiran Gunda 
Acked-by: Daniel Thompson 
---
 drivers/video/backlight/qcom-wled.c | 373 ++--
 1 file changed, 234 insertions(+), 139 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index f191242..45eeda4 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -7,59 +7,71 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 /* From DT binding */
+#define WLED_MAX_STRINGS   4
+
 #define WLED_DEFAULT_BRIGHTNESS2048
 
 #define WLED3_SINK_REG_BRIGHT_MAX  0xFFF
-#define WLED3_CTRL_REG_VAL_BASE0x40
 
 /* WLED3 control registers */
 #define WLED3_CTRL_REG_MOD_EN  0x46
-#define  WLED3_CTRL_REG_MOD_EN_BIT BIT(7)
 #define  WLED3_CTRL_REG_MOD_EN_MASKBIT(7)
+#define  WLED3_CTRL_REG_MOD_EN_SHIFT   7
 
 #define WLED3_CTRL_REG_FREQ0x4c
-#define  WLED3_CTRL_REG_FREQ_MASK  0x0f
+#define  WLED3_CTRL_REG_FREQ_MASK  GENMASK(3, 0)
 
 #define WLED3_CTRL_REG_OVP 0x4d
-#define  WLED3_CTRL_REG_OVP_MASK   0x03
+#define  WLED3_CTRL_REG_OVP_MASK   GENMASK(1, 0)
 
 #define WLED3_CTRL_REG_ILIMIT  0x4e
-#define  WLED3_CTRL_REG_ILIMIT_MASK0x07
+#define  WLED3_CTRL_REG_ILIMIT_MASKGENMASK(2, 0)
 
 /* WLED3 sink registers */
 #define WLED3_SINK_REG_SYNC0x47
-#define  WLED3_SINK_REG_SYNC_MASK  0x07
-#define  WLED3_SINK_REG_SYNC_LED1  BIT(0)
-#define  WLED3_SINK_REG_SYNC_LED2  BIT(1)
-#define  WLED3_SINK_REG_SYNC_LED3  BIT(2)
-#define  WLED3_SINK_REG_SYNC_ALL   0x07
 #define  WLED3_SINK_REG_SYNC_CLEAR 0x00
 
 #define WLED3_SINK_REG_CURR_SINK   0x4f
-#define  WLED3_SINK_REG_CURR_SINK_MASK 0xe0
-#define  WLED3_SINK_REG_CURR_SINK_SHFT 0x05
+#define  WLED3_SINK_REG_CURR_SINK_MASK GENMASK(7, 5)
+#define  WLED3_SINK_REG_CURR_SINK_SHFT 5
 
-/* WLED3 per-'string' registers below */
-#define WLED3_SINK_REG_STR_OFFSET  0x10
+/* WLED3 specific per-'string' registers below */
+#define WLED3_SINK_REG_BRIGHT(n)   (0x40 + n)
 
-#define WLED3_SINK_REG_STR_MOD_EN_BASE 0x60
+#define WLED3_SINK_REG_STR_MOD_EN(n)   (0x60 + (n * 0x10))
 #define  WLED3_SINK_REG_STR_MOD_MASK   BIT(7)
-#define  WLED3_SINK_REG_STR_MOD_EN BIT(7)
 
-#define WLED3_SINK_REG_STR_FULL_SCALE_CURR 0x62
-#define  WLED3_SINK_REG_STR_FULL_SCALE_CURR_MASK   0x1f
+#define WLED3_SINK_REG_STR_FULL_SCALE_CURR(n)  (0x62 + (n * 0x10))
+#define  WLED3_SINK_REG_STR_FULL_SCALE_CURR_MASK   GENMASK(4, 0)
 
-#define WLED3_SINK_REG_STR_MOD_SRC_BASE0x63
-#define  WLED3_SINK_REG_STR_MOD_SRC_MASK   0x01
+#define WLED3_SINK_REG_STR_MOD_SRC(n)  (0x63 + (n * 0x10))
+#define  WLED3_SINK_REG_STR_MOD_SRC_MASK   BIT(0)
 #define  WLED3_SINK_REG_STR_MOD_SRC_INT0x00
 #define  WLED3_SINK_REG_STR_MOD_SRC_EXT0x01
 
-#define WLED3_SINK_REG_STR_CABC_BASE   0x66
+#define WLED3_SINK_REG_STR_CABC(n) (0x66 + (n * 0x10))
 #define  WLED3_SINK_REG_STR_CABC_MASK  BIT(7)
-#define  WLED3_SINK_REG_STR_CABC_ENBIT(7)
+
+struct wled_var_cfg {
+   const u32 *values;
+   u32 (*fn)(u32);
+   int size;
+};
+
+struct wled_u32_opts {
+   const char *name;
+   u32 *val_ptr;
+   const struct wled_var_cfg *cfg;
+};
+
+struct wled_bool_opts {
+   const char *name;
+   bool *val_ptr;
+};
 
 struct wled_config {
u32 boost_i_limit;
@@ -67,132 +79,179 @@ struct wled_config {
u32 switch_freq;
u32 num_strings;
u32 string_i_limit;
+   u32 enabled_strings[WLED_MAX_STRINGS];
bool cs_out_en;
bool ext_gen;
-   bool cabc_en;
+   bool cabc;
 };
 
 struct wled {
const char *name;
+   struct device *dev;
struct regmap *regmap;
-   u16 addr;
+   u16 ctrl_addr;
+   u16 max_string_count;
+   u32 brightness;
+   u32 max_brightness;
 
struct wled_config cfg;
+   int (*wled_set_brightness)(struct wled *wled, u16 brightness);
 };
 
+static int wled3_set_brightness(struct wled *wled, u16 brightness)
+{
+   int rc, i;
+   u8 v[2];
+
+   v[0] = brightness & 0xff;
+  

[PATCH V7 6/6] backlight: qcom-wled: Add auto string detection logic

2019-10-16 Thread Kiran Gunda
The auto string detection algorithm checks if the current WLED
sink configuration is valid. It tries enabling every sink and
checks if the OVP fault is observed. Based on this information
it detects and enables the valid sink configuration.
Auto calibration will be triggered when the OVP fault interrupts
are seen frequently thereby it tries to fix the sink configuration.

The auto-detection also kicks in when the connected LED string
of the display-backlight malfunctions (because of damage) and
requires the damaged string to be turned off to prevent the
complete panel and/or board from being damaged.

Signed-off-by: Kiran Gunda 
---
 drivers/video/backlight/qcom-wled.c | 410 +++-
 1 file changed, 404 insertions(+), 6 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index b5b125c..ff7c409 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -17,19 +17,29 @@
 #define WLED_MAX_STRINGS   4
 
 #define WLED_DEFAULT_BRIGHTNESS2048
-
+#define WLED_SOFT_START_DLY_US 1
 #define WLED3_SINK_REG_BRIGHT_MAX  0xFFF
 
 /* WLED3/WLED4 control registers */
+#define WLED3_CTRL_REG_FAULT_STATUS0x08
+#define  WLED3_CTRL_REG_ILIM_FAULT_BIT BIT(0)
+#define  WLED3_CTRL_REG_OVP_FAULT_BIT  BIT(1)
+#define  WLED4_CTRL_REG_SC_FAULT_BIT   BIT(2)
+
+#define WLED3_CTRL_REG_INT_RT_STS  0x10
+#define  WLED3_CTRL_REG_OVP_FAULT_STATUS   BIT(1)
+
 #define WLED3_CTRL_REG_MOD_EN  0x46
 #define  WLED3_CTRL_REG_MOD_EN_MASKBIT(7)
 #define  WLED3_CTRL_REG_MOD_EN_SHIFT   7
 
+#define WLED3_CTRL_REG_FEEDBACK_CONTROL0x48
+
 #define WLED3_CTRL_REG_FREQ0x4c
 #define  WLED3_CTRL_REG_FREQ_MASK  GENMASK(3, 0)
 
 #define WLED3_CTRL_REG_OVP 0x4d
-#define  WLED3_CTRL_REG_OVP_MASK   GENMASK(1, 0)
+#define  WLED3_CTRL_REG_OVP_MASK   GENMASK(1, 0)
 
 #define WLED3_CTRL_REG_ILIMIT  0x4e
 #define  WLED3_CTRL_REG_ILIMIT_MASKGENMASK(2, 0)
@@ -119,6 +129,7 @@ struct wled_config {
bool ext_gen;
bool cabc;
bool external_pfet;
+   bool auto_detection_enabled;
 };
 
 struct wled {
@@ -127,16 +138,21 @@ struct wled {
struct regmap *regmap;
struct mutex lock;  /* Lock to avoid race from thread irq handler */
ktime_t last_short_event;
+   ktime_t start_ovp_fault_time;
u16 ctrl_addr;
u16 sink_addr;
u16 max_string_count;
+   u16 auto_detection_ovp_count;
u32 brightness;
u32 max_brightness;
u32 short_count;
+   u32 auto_detect_count;
bool disabled_by_short;
bool has_short_detect;
+   int ovp_irq;
 
struct wled_config cfg;
+   struct delayed_work ovp_work;
int (*wled_set_brightness)(struct wled *wled, u16 brightness);
 };
 
@@ -181,6 +197,13 @@ static int wled4_set_brightness(struct wled *wled, u16 
brightness)
return 0;
 }
 
+static void wled_ovp_work(struct work_struct *work)
+{
+   struct wled *wled = container_of(work,
+struct wled, ovp_work.work);
+   enable_irq(wled->ovp_irq);
+}
+
 static int wled_module_enable(struct wled *wled, int val)
 {
int rc;
@@ -192,7 +215,19 @@ static int wled_module_enable(struct wled *wled, int val)
WLED3_CTRL_REG_MOD_EN,
WLED3_CTRL_REG_MOD_EN_MASK,
val << WLED3_CTRL_REG_MOD_EN_SHIFT);
-   return rc;
+   if (rc < 0)
+   return rc;
+
+   if (wled->ovp_irq > 0) {
+   if (val) {
+   schedule_delayed_work(>ovp_work, HZ / 100);
+   } else {
+   if (!cancel_delayed_work_sync(>ovp_work))
+   disable_irq(wled->ovp_irq);
+   }
+   }
+
+   return 0;
 }
 
 static int wled_sync_toggle(struct wled *wled)
@@ -299,6 +334,311 @@ static irqreturn_t wled_short_irq_handler(int irq, void 
*_wled)
return IRQ_HANDLED;
 }
 
+#define AUTO_DETECT_BRIGHTNESS 200
+
+static void wled_auto_string_detection(struct wled *wled)
+{
+   int rc = 0, i;
+   u32 sink_config = 0, int_sts;
+   u8 sink_test = 0, sink_valid = 0, val;
+
+   /* read configured sink configuration */
+   rc = regmap_read(wled->regmap, wled->sink_addr +
+WLED4_SINK_REG_CURR_SINK, _config);
+   if (rc < 0) {
+   dev_err(wled->dev, "Failed to read SINK config

[PATCH V7 5/6] backlight: qcom-wled: add support for short circuit handling.

2019-10-16 Thread Kiran Gunda
Handle the short circuit interrupt and check if the short circuit
interrupt is valid. Re-enable the module to check if it goes
away. Disable the module altogether if the short circuit event
persists.

Signed-off-by: Kiran Gunda 
Reviewed-by: Bjorn Andersson 
---
 drivers/video/backlight/qcom-wled.c | 132 ++--
 1 file changed, 128 insertions(+), 4 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 2807b4b..b5b125c 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -2,6 +2,9 @@
 /* Copyright (c) 2015, Sony Mobile Communications, AB.
  */
 
+#include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -56,6 +59,16 @@
 #define WLED3_SINK_REG_STR_CABC(n) (0x66 + (n * 0x10))
 #define  WLED3_SINK_REG_STR_CABC_MASK  BIT(7)
 
+/* WLED4 specific control registers */
+#define WLED4_CTRL_REG_SHORT_PROTECT   0x5e
+#define  WLED4_CTRL_REG_SHORT_EN_MASK  BIT(7)
+
+#define WLED4_CTRL_REG_SEC_ACCESS  0xd0
+#define  WLED4_CTRL_REG_SEC_UNLOCK 0xa5
+
+#define WLED4_CTRL_REG_TEST1   0xe2
+#define  WLED4_CTRL_REG_TEST1_EXT_FET_DTEST2   0x09
+
 /* WLED4 specific sink registers */
 #define WLED4_SINK_REG_CURR_SINK   0x46
 #define  WLED4_SINK_REG_CURR_SINK_MASK GENMASK(7, 4)
@@ -105,17 +118,23 @@ struct wled_config {
bool cs_out_en;
bool ext_gen;
bool cabc;
+   bool external_pfet;
 };
 
 struct wled {
const char *name;
struct device *dev;
struct regmap *regmap;
+   struct mutex lock;  /* Lock to avoid race from thread irq handler */
+   ktime_t last_short_event;
u16 ctrl_addr;
u16 sink_addr;
u16 max_string_count;
u32 brightness;
u32 max_brightness;
+   u32 short_count;
+   bool disabled_by_short;
+   bool has_short_detect;
 
struct wled_config cfg;
int (*wled_set_brightness)(struct wled *wled, u16 brightness);
@@ -166,6 +185,9 @@ static int wled_module_enable(struct wled *wled, int val)
 {
int rc;
 
+   if (wled->disabled_by_short)
+   return -ENXIO;
+
rc = regmap_update_bits(wled->regmap, wled->ctrl_addr +
WLED3_CTRL_REG_MOD_EN,
WLED3_CTRL_REG_MOD_EN_MASK,
@@ -202,18 +224,19 @@ static int wled_update_status(struct backlight_device *bl)
bl->props.state & BL_CORE_FBBLANK)
brightness = 0;
 
+   mutex_lock(>lock);
if (brightness) {
rc = wled->wled_set_brightness(wled, brightness);
if (rc < 0) {
dev_err(wled->dev, "wled failed to set brightness 
rc:%d\n",
rc);
-   return rc;
+   goto unlock_mutex;
}
 
rc = wled_sync_toggle(wled);
if (rc < 0) {
dev_err(wled->dev, "wled sync failed rc:%d\n", rc);
-   return rc;
+   goto unlock_mutex;
}
}
 
@@ -221,15 +244,61 @@ static int wled_update_status(struct backlight_device *bl)
rc = wled_module_enable(wled, !!brightness);
if (rc < 0) {
dev_err(wled->dev, "wled enable failed rc:%d\n", rc);
-   return rc;
+   goto unlock_mutex;
}
}
 
wled->brightness = brightness;
 
+unlock_mutex:
+   mutex_unlock(>lock);
+
return rc;
 }
 
+#define WLED_SHORT_DLY_MS  20
+#define WLED_SHORT_CNT_MAX 5
+#define WLED_SHORT_RESET_CNT_DLY_USUSEC_PER_SEC
+
+static irqreturn_t wled_short_irq_handler(int irq, void *_wled)
+{
+   struct wled *wled = _wled;
+   int rc;
+   s64 elapsed_time;
+
+   wled->short_count++;
+   mutex_lock(>lock);
+   rc = wled_module_enable(wled, false);
+   if (rc < 0) {
+   dev_err(wled->dev, "wled disable failed rc:%d\n", rc);
+   goto unlock_mutex;
+   }
+
+   elapsed_time = ktime_us_delta(ktime_get(),
+ wled->last_short_event);
+   if (elapsed_time > WLED_SHORT_RESET_CNT_DLY_US)
+   wled->short_count = 1;
+
+   if (wled->short_count > WLED_SHORT_CNT_MAX) {
+   dev_err(wled->dev, "Short trigged %d times, disabling WLED 
forever!\n",
+   wled->short_count);
+   wled->disabled_by_short = true;
+   goto unlock_mutex;
+   }
+
+   wled->last_short_event = ktime_get();

[PATCH V7 1/6] backlight: qcom-wled: Add new properties for PMI8998

2019-10-16 Thread Kiran Gunda
Update the bindings with the new properties used for
PMI8998.

Signed-off-by: Kiran Gunda 
Reviewed-by: Bjorn Andersson 
Reviewed-by: Rob Herring 
Acked-by: Daniel Thompson 
---
 .../bindings/leds/backlight/qcom-wled.txt  | 74 ++
 1 file changed, 63 insertions(+), 11 deletions(-)

diff --git a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt 
b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
index 14f28f2..c06863b 100644
--- a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
+++ b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
@@ -20,7 +20,7 @@ platforms. The PMIC is connected to the host processor via 
SPMI bus.
 - default-brightness
Usage:optional
Value type:   
-   Definition:   brightness value on boot, value from: 0-4095
+   Definition:   brightness value on boot, value from: 0-4095.
  Default: 2048
 
 - label
@@ -48,20 +48,24 @@ platforms. The PMIC is connected to the host processor via 
SPMI bus.
 - qcom,current-limit
Usage:optional
Value type:   
-   Definition:   mA; per-string current limit
- value: For pm8941: from 0 to 25 with 5 mA step
-Default 20 mA.
-For pmi8998: from 0 to 30 with 5 mA step
-Default 25 mA.
+   Definition:   mA; per-string current limit; value from 0 to 25 with
+ 1 mA step. Default 20 mA.
+ This property is supported only for pm8941.
+
+- qcom,current-limit-microamp
+   Usage:optional
+   Value type:   
+   Definition:   uA; per-string current limit; value from 0 to 3 with
+ 2500 uA step. Default 25 mA.
 
 - qcom,current-boost-limit
Usage:optional
Value type:   
Definition:   mA; boost current limit.
  For pm8941: one of: 105, 385, 525, 805, 980, 1260, 1400,
- 1680. Default: 805 mA
+ 1680. Default: 805 mA.
  For pmi8998: one of: 105, 280, 450, 620, 970, 1150, 1300,
- 1500. Default: 970 mA
+ 1500. Default: 970 mA.
 
 - qcom,switching-freq
Usage:optional
@@ -76,15 +80,62 @@ platforms. The PMIC is connected to the host processor via 
SPMI bus.
Usage:optional
Value type:   
Definition:   V; Over-voltage protection limit; one of:
- 27, 29, 32, 35. default: 29V
+ 27, 29, 32, 35. Default: 29V
  This property is supported only for PM8941.
 
+- qcom,ovp-millivolt
+   Usage:optional
+   Value type:   
+   Definition:   mV; Over-voltage protection limit;
+ For pmi8998: one of 18100, 19600, 29600, 31100.
+ Default 29600 mV.
+ If this property is not specified for PM8941, it
+ falls back to "qcom,ovp" property.
+
 - qcom,num-strings
Usage:optional
Value type:   
Definition:   #; number of led strings attached;
- value from 1 to 3. default: 2
- This property is supported only for PM8941.
+ value: For PM8941 from 1 to 3. Default: 2
+For PMI8998 from 1 to 4.
+
+- interrupts
+   Usage:optional
+   Value type:   
+   Definition:   Interrupts associated with WLED. This should be
+ "short" and "ovp" interrupts. Interrupts can be
+ specified as per the encoding listed under
+ Documentation/devicetree/bindings/spmi/
+ qcom,spmi-pmic-arb.txt.
+
+- interrupt-names
+   Usage:optional
+   Value type:   
+   Definition:   Interrupt names associated with the interrupts.
+ Must be "short" and "ovp". The short circuit detection
+ is not supported for PM8941.
+
+- qcom,enabled-strings
+   Usage:optional
+   Value tyoe:   
+   Definition:   Array of the WLED strings numbered from 0 to 3. Each
+ string of leds are operated individually. Specify the
+ list of strings used by the device. Any combination of
+ led strings can be used.
+
+- qcom,external-pfet
+   Usage:optional
+   Value type:   
+   Definition:   Specify if external PFET control for short circuit
+ protection is used. This property is supported only
+ for PMI8998.
+
+- qcom,auto-string-detection
+   Usage:optional
+   Value type:   
+   Definition:   Enables auto-detection of the WLED string configuration.
+ This feature is not sup

[PATCH V7 2/6] backlight: qcom-wled: Rename PM8941* to WLED3.

2019-10-16 Thread Kiran Gunda
Rename the PM8941* references as WLED3 to make the driver
generic and have WLED support for other PMICs. Also rename
"i_boost_limit" and "i_limit" variables to "boost_i_limit"
and "string_i_limit" respectively to resemble the corresponding
register names.

Signed-off-by: Kiran Gunda 
Reviewed-by: Daniel Thompson 
Reviewed-by: Bjorn Andersson 
Acked-by: Pavel Machek 
---
 drivers/video/backlight/qcom-wled.c | 248 ++--
 1 file changed, 125 insertions(+), 123 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 82b8572..f191242 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -10,77 +10,79 @@
 #include 
 
 /* From DT binding */
-#define PM8941_WLED_DEFAULT_BRIGHTNESS 2048
+#define WLED_DEFAULT_BRIGHTNESS2048
 
-#define PM8941_WLED_REG_VAL_BASE   0x40
-#define  PM8941_WLED_REG_VAL_MAX   0xFFF
+#define WLED3_SINK_REG_BRIGHT_MAX  0xFFF
+#define WLED3_CTRL_REG_VAL_BASE0x40
 
-#define PM8941_WLED_REG_MOD_EN 0x46
-#define  PM8941_WLED_REG_MOD_EN_BITBIT(7)
-#define  PM8941_WLED_REG_MOD_EN_MASK   BIT(7)
+/* WLED3 control registers */
+#define WLED3_CTRL_REG_MOD_EN  0x46
+#define  WLED3_CTRL_REG_MOD_EN_BIT BIT(7)
+#define  WLED3_CTRL_REG_MOD_EN_MASKBIT(7)
 
-#define PM8941_WLED_REG_SYNC   0x47
-#define  PM8941_WLED_REG_SYNC_MASK 0x07
-#define  PM8941_WLED_REG_SYNC_LED1 BIT(0)
-#define  PM8941_WLED_REG_SYNC_LED2 BIT(1)
-#define  PM8941_WLED_REG_SYNC_LED3 BIT(2)
-#define  PM8941_WLED_REG_SYNC_ALL  0x07
-#define  PM8941_WLED_REG_SYNC_CLEAR0x00
+#define WLED3_CTRL_REG_FREQ0x4c
+#define  WLED3_CTRL_REG_FREQ_MASK  0x0f
 
-#define PM8941_WLED_REG_FREQ   0x4c
-#define  PM8941_WLED_REG_FREQ_MASK 0x0f
+#define WLED3_CTRL_REG_OVP 0x4d
+#define  WLED3_CTRL_REG_OVP_MASK   0x03
 
-#define PM8941_WLED_REG_OVP0x4d
-#define  PM8941_WLED_REG_OVP_MASK  0x03
+#define WLED3_CTRL_REG_ILIMIT  0x4e
+#define  WLED3_CTRL_REG_ILIMIT_MASK0x07
 
-#define PM8941_WLED_REG_BOOST  0x4e
-#define  PM8941_WLED_REG_BOOST_MASK0x07
+/* WLED3 sink registers */
+#define WLED3_SINK_REG_SYNC0x47
+#define  WLED3_SINK_REG_SYNC_MASK  0x07
+#define  WLED3_SINK_REG_SYNC_LED1  BIT(0)
+#define  WLED3_SINK_REG_SYNC_LED2  BIT(1)
+#define  WLED3_SINK_REG_SYNC_LED3  BIT(2)
+#define  WLED3_SINK_REG_SYNC_ALL   0x07
+#define  WLED3_SINK_REG_SYNC_CLEAR 0x00
 
-#define PM8941_WLED_REG_SINK   0x4f
-#define  PM8941_WLED_REG_SINK_MASK 0xe0
-#define  PM8941_WLED_REG_SINK_SHFT 0x05
+#define WLED3_SINK_REG_CURR_SINK   0x4f
+#define  WLED3_SINK_REG_CURR_SINK_MASK 0xe0
+#define  WLED3_SINK_REG_CURR_SINK_SHFT 0x05
 
-/* Per-'string' registers below */
-#define PM8941_WLED_REG_STR_OFFSET 0x10
+/* WLED3 per-'string' registers below */
+#define WLED3_SINK_REG_STR_OFFSET  0x10
 
-#define PM8941_WLED_REG_STR_MOD_EN_BASE0x60
-#define  PM8941_WLED_REG_STR_MOD_MASK  BIT(7)
-#define  PM8941_WLED_REG_STR_MOD_ENBIT(7)
+#define WLED3_SINK_REG_STR_MOD_EN_BASE 0x60
+#define  WLED3_SINK_REG_STR_MOD_MASK   BIT(7)
+#define  WLED3_SINK_REG_STR_MOD_EN BIT(7)
 
-#define PM8941_WLED_REG_STR_SCALE_BASE 0x62
-#define  PM8941_WLED_REG_STR_SCALE_MASK0x1f
+#define WLED3_SINK_REG_STR_FULL_SCALE_CURR 0x62
+#define  WLED3_SINK_REG_STR_FULL_SCALE_CURR_MASK   0x1f
 
-#define PM8941_WLED_REG_STR_MOD_SRC_BASE   0x63
-#define  PM8941_WLED_REG_STR_MOD_SRC_MASK  0x01
-#define  PM8941_WLED_REG_STR_MOD_SRC_INT   0x00
-#define  PM8941_WLED_REG_STR_MOD_SRC_EXT   0x01
+#define WLED3_SINK_REG_STR_MOD_SRC_BASE0x63
+#define  WLED3_SINK_REG_STR_MOD_SRC_MASK   0x01
+#define  WLED3_SINK_REG_STR_MOD_SRC_INT0x00
+#define  WLED3_SINK_REG_STR_MOD_SRC_EXT0x01
 
-#define PM8941_WLED_REG_STR_CABC_BASE  0x66
-#define  PM8941_WLED_REG_STR_CABC_MASK BIT(7)
-#define  PM8941_WLED_REG_STR_CABC_EN   BIT(7)
+#define WLED3_SINK_REG_STR_CABC_BASE   0x66
+#define  WLED3_SINK_REG_STR_CABC_MASK  BIT

[PATCH V7 0/6] backlight: qcom-wled: Support for QCOM wled driver

2019-10-16 Thread Kiran Gunda
This patch series renames the pm8941-wled.c driver to qcom-wled.c to add
the support for multiple PMICs supported by qualcomm. This patch series
supports both PM8941 and PMI8998 WLED. The PMI8998 WLED has the support
to handle the OVP (over voltage protection) and the SC (short circuit
protection)
interrupts. It also has the auto string detection algorithm support to
configure the right strings if the user specified string configuration
is in-correct. These three features are added in this series for PMI8998.

changes from v1:
   - Fixed the commit message for
   - backlight: qcom-wled: Rename pm8941-wled.c to qcom-wled.c

Changes from v2:
   - Fixed bjorn and other reviewer's comments
   - Seperated the device tree bindings
   - Splitted out the WLED4 changes in seperate patch
   - Merged OVP and auto string detection patch

Changes from v3:
  - Added Reviewed-by/Acked-by tags
  - Fixed comments from Bjorn/Vinod/Rob
  - Splitting the "backlight: qcom-wled: Add support for WLED4 peripheral" patch
to seperate the WLED3 specific restructure.

Changes from v4:
  - Added reviewed-by/Acked-by tags
  - Fixed comments from Bjorn/Daniel/Pavel

Changes from v5:
  - Fixed comments from Bjorn/Pavel

Changes from v5/v6:
  - Fixed comments from Bjorn/Pavel on V5 series, which were missed in V6 series
  - Patch 1 and 2, mentioned below, from V6 series are picked by Pavel In next.
Hence, dropped them in this series.
https://lore.kernel.org/patchwork/patch/1132467/
https://lore.kernel.org/patchwork/patch/1132468/

Kiran Gunda (6):
  backlight: qcom-wled: Add new properties for PMI8998
  backlight: qcom-wled: Rename PM8941* to WLED3.
  backlight: qcom-wled: Restructure the driver for WLED3
  backlight: qcom-wled: Add support for WLED4 peripheral.
  backlight: qcom-wled: add support for short circuit handling.
  backlight: qcom-wled: Add auto string detection logic

 .../bindings/leds/backlight/qcom-wled.txt  |   74 +-
 drivers/video/backlight/qcom-wled.c| 1256 +---
 2 files changed, 1126 insertions(+), 204 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project



[PATCH V6 8/8] backlight: qcom-wled: Add auto string detection logic

2019-09-30 Thread Kiran Gunda
The auto string detection algorithm checks if the current WLED
sink configuration is valid. It tries enabling every sink and
checks if the OVP fault is observed. Based on this information
it detects and enables the valid sink configuration.
Auto calibration will be triggered when the OVP fault interrupts
are seen frequently thereby it tries to fix the sink configuration.

The auto-detection also kicks in when the connected LED string
of the display-backlight malfunctions (because of damage) and
requires the damaged string to be turned off to prevent the
complete panel and/or board from being damaged.

Signed-off-by: Kiran Gunda 
---
 drivers/video/backlight/qcom-wled.c | 402 +++-
 1 file changed, 397 insertions(+), 5 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 556c734..7a1d3ae 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -17,10 +17,18 @@
 #define WLED_MAX_STRINGS   4
 
 #define WLED_DEFAULT_BRIGHTNESS2048
-
+#define WLED_SOFT_START_DLY_US 1
 #define WLED_SINK_REG_BRIGHT_MAX   0xFFF
 
 /* WLED control registers */
+#define WLED_CTRL_REG_FAULT_STATUS 0x08
+#define  WLED_CTRL_REG_ILIM_FAULT_BIT  BIT(0)
+#define  WLED_CTRL_REG_OVP_FAULT_BIT   BIT(1)
+#define  WLED4_CTRL_REG_SC_FAULT_BIT   BIT(2)
+
+#define WLED_CTRL_REG_INT_RT_STS   0x10
+#define  WLED_CTRL_REG_OVP_FAULT_STATUSBIT(1)
+
 #define WLED_CTRL_REG_MOD_EN   0x46
 #define  WLED_CTRL_REG_MOD_EN_MASK BIT(7)
 #define  WLED_CTRL_REG_MOD_EN_SHIFT7
@@ -28,6 +36,8 @@
 #define WLED_CTRL_REG_FREQ 0x4c
 #define  WLED_CTRL_REG_FREQ_MASK   GENMASK(3, 0)
 
+#define WLED_CTRL_REG_FEEDBACK_CONTROL 0x48
+
 #define WLED_CTRL_REG_OVP  0x4d
 #define  WLED_CTRL_REG_OVP_MASKGENMASK(1, 0)
 
@@ -119,6 +129,7 @@ struct wled_config {
bool ext_gen;
bool cabc;
bool external_pfet;
+   bool auto_detection_enabled;
 };
 
 struct wled {
@@ -127,16 +138,22 @@ struct wled {
struct regmap *regmap;
struct mutex lock;  /* Lock to avoid race from thread irq handler */
ktime_t last_short_event;
+   ktime_t start_ovp_fault_time;
u16 ctrl_addr;
u16 sink_addr;
u16 max_string_count;
+   u16 auto_detection_ovp_count;
u32 brightness;
u32 max_brightness;
u32 short_count;
+   u32 auto_detect_count;
bool disabled_by_short;
bool has_short_detect;
+   int ovp_irq;
+   bool ovp_irq_disabled;
 
struct wled_config cfg;
+   struct delayed_work ovp_work;
int (*wled_set_brightness)(struct wled *wled, u16 brightness);
 };
 
@@ -181,6 +198,15 @@ static int wled4_set_brightness(struct wled *wled, u16 
brightness)
return 0;
 }
 
+static void wled_ovp_work(struct work_struct *work)
+{
+   struct wled *wled = container_of(work,
+struct wled, ovp_work.work);
+
+   if (wled->ovp_irq > 0)
+   enable_irq(wled->ovp_irq);
+}
+
 static int wled_module_enable(struct wled *wled, int val)
 {
int rc;
@@ -192,7 +218,18 @@ static int wled_module_enable(struct wled *wled, int val)
WLED_CTRL_REG_MOD_EN,
WLED_CTRL_REG_MOD_EN_MASK,
val << WLED_CTRL_REG_MOD_EN_SHIFT);
-   return rc;
+   if (rc < 0)
+   return rc;
+
+   if (val) {
+   schedule_delayed_work(>ovp_work, HZ / 100);
+   } else {
+   if (!cancel_delayed_work_sync(>ovp_work) &&
+   wled->ovp_irq > 0)
+   disable_irq(wled->ovp_irq);
+   }
+
+   return 0;
 }
 
 static int wled_sync_toggle(struct wled *wled)
@@ -299,6 +336,312 @@ static irqreturn_t wled_short_irq_handler(int irq, void 
*_wled)
return IRQ_HANDLED;
 }
 
+#define AUTO_DETECT_BRIGHTNESS 200
+
+static void wled_auto_string_detection(struct wled *wled)
+{
+   int rc = 0, i;
+   u32 sink_config = 0, int_sts;
+   u8 sink_test = 0, sink_valid = 0, val;
+
+   /* read configured sink configuration */
+   rc = regmap_read(wled->regmap, wled->sink_addr +
+WLED4_SINK_REG_CURR_SINK, _config);
+   if (rc < 0) {
+   dev_err(wled->dev, "Failed to read SINK configuration rc=%d\n",
+   rc);
+   goto failed_detect;
+   }
+
+   /* disable the module before sta

[PATCH V6 7/8] backlight: qcom-wled: add support for short circuit handling.

2019-09-30 Thread Kiran Gunda
Handle the short circuit interrupt and check if the short circuit
interrupt is valid. Re-enable the module to check if it goes
away. Disable the module altogether if the short circuit event
persists.

Change-Id: Ia3f5272e1a50927467611bef4a0d2218dbeb95e6
Signed-off-by: Kiran Gunda 
Reviewed-by: Bjorn Andersson 
---
 drivers/video/backlight/qcom-wled.c | 132 ++--
 1 file changed, 128 insertions(+), 4 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index b012a2a..556c734 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -2,6 +2,9 @@
 /* Copyright (c) 2015, Sony Mobile Communications, AB.
  */
 
+#include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -56,6 +59,16 @@
 #define WLED3_SINK_REG_STR_CABC(n) (0x66 + (n * 0x10))
 #define  WLED3_SINK_REG_STR_CABC_MASK  BIT(7)
 
+/* WLED4 specific control registers */
+#define WLED4_CTRL_REG_SHORT_PROTECT   0x5e
+#define  WLED4_CTRL_REG_SHORT_EN_MASK  BIT(7)
+
+#define WLED4_CTRL_REG_SEC_ACCESS  0xd0
+#define  WLED4_CTRL_REG_SEC_UNLOCK 0xa5
+
+#define WLED4_CTRL_REG_TEST1   0xe2
+#define  WLED4_CTRL_REG_TEST1_EXT_FET_DTEST2   0x09
+
 /* WLED4 specific sink registers */
 #define WLED4_SINK_REG_CURR_SINK   0x46
 #define  WLED4_SINK_REG_CURR_SINK_MASK GENMASK(7, 4)
@@ -105,17 +118,23 @@ struct wled_config {
bool cs_out_en;
bool ext_gen;
bool cabc;
+   bool external_pfet;
 };
 
 struct wled {
const char *name;
struct device *dev;
struct regmap *regmap;
+   struct mutex lock;  /* Lock to avoid race from thread irq handler */
+   ktime_t last_short_event;
u16 ctrl_addr;
u16 sink_addr;
u16 max_string_count;
u32 brightness;
u32 max_brightness;
+   u32 short_count;
+   bool disabled_by_short;
+   bool has_short_detect;
 
struct wled_config cfg;
int (*wled_set_brightness)(struct wled *wled, u16 brightness);
@@ -166,6 +185,9 @@ static int wled_module_enable(struct wled *wled, int val)
 {
int rc;
 
+   if (wled->disabled_by_short)
+   return -ENXIO;
+
rc = regmap_update_bits(wled->regmap, wled->ctrl_addr +
WLED_CTRL_REG_MOD_EN,
WLED_CTRL_REG_MOD_EN_MASK,
@@ -202,18 +224,19 @@ static int wled_update_status(struct backlight_device *bl)
bl->props.state & BL_CORE_FBBLANK)
brightness = 0;
 
+   mutex_lock(>lock);
if (brightness) {
rc = wled->wled_set_brightness(wled, brightness);
if (rc < 0) {
dev_err(wled->dev, "wled failed to set brightness 
rc:%d\n",
rc);
-   return rc;
+   goto unlock_mutex;
}
 
rc = wled_sync_toggle(wled);
if (rc < 0) {
dev_err(wled->dev, "wled sync failed rc:%d\n", rc);
-   return rc;
+   goto unlock_mutex;
}
}
 
@@ -221,15 +244,61 @@ static int wled_update_status(struct backlight_device *bl)
rc = wled_module_enable(wled, !!brightness);
if (rc < 0) {
dev_err(wled->dev, "wled enable failed rc:%d\n", rc);
-   return rc;
+   goto unlock_mutex;
}
}
 
wled->brightness = brightness;
 
+unlock_mutex:
+   mutex_unlock(>lock);
+
return rc;
 }
 
+#define WLED_SHORT_DLY_MS  20
+#define WLED_SHORT_CNT_MAX 5
+#define WLED_SHORT_RESET_CNT_DLY_USUSEC_PER_SEC
+
+static irqreturn_t wled_short_irq_handler(int irq, void *_wled)
+{
+   struct wled *wled = _wled;
+   int rc;
+   s64 elapsed_time;
+
+   wled->short_count++;
+   mutex_lock(>lock);
+   rc = wled_module_enable(wled, false);
+   if (rc < 0) {
+   dev_err(wled->dev, "wled disable failed rc:%d\n", rc);
+   goto unlock_mutex;
+   }
+
+   elapsed_time = ktime_us_delta(ktime_get(),
+ wled->last_short_event);
+   if (elapsed_time > WLED_SHORT_RESET_CNT_DLY_US)
+   wled->short_count = 1;
+
+   if (wled->short_count > WLED_SHORT_CNT_MAX) {
+   dev_err(wled->dev, "Short trigged %d times, disabling WLED 
forever!\n",
+   wled->short_count);
+   wled->disabled_by_short = true;
+   goto unlock_mutex;
+

[PATCH V6 5/8] backlight: qcom-wled: Restructure the driver for WLED3

2019-09-30 Thread Kiran Gunda
Restructure the driver to add the support for new WLED
peripherals.

Signed-off-by: Kiran Gunda 
Acked-by: Daniel Thompson 
---
 drivers/video/backlight/qcom-wled.c | 395 ++--
 1 file changed, 245 insertions(+), 150 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index f191242..740f1b6 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -7,59 +7,71 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 /* From DT binding */
+#define WLED_MAX_STRINGS   4
+
 #define WLED_DEFAULT_BRIGHTNESS2048
 
-#define WLED3_SINK_REG_BRIGHT_MAX  0xFFF
-#define WLED3_CTRL_REG_VAL_BASE0x40
+#define WLED_SINK_REG_BRIGHT_MAX   0xFFF
 
-/* WLED3 control registers */
-#define WLED3_CTRL_REG_MOD_EN  0x46
-#define  WLED3_CTRL_REG_MOD_EN_BIT BIT(7)
-#define  WLED3_CTRL_REG_MOD_EN_MASKBIT(7)
+/* WLED control registers */
+#define WLED_CTRL_REG_MOD_EN   0x46
+#define  WLED_CTRL_REG_MOD_EN_MASK BIT(7)
+#define  WLED_CTRL_REG_MOD_EN_SHIFT7
 
-#define WLED3_CTRL_REG_FREQ0x4c
-#define  WLED3_CTRL_REG_FREQ_MASK  0x0f
+#define WLED_CTRL_REG_FREQ 0x4c
+#define  WLED_CTRL_REG_FREQ_MASK   GENMASK(3, 0)
 
-#define WLED3_CTRL_REG_OVP 0x4d
-#define  WLED3_CTRL_REG_OVP_MASK   0x03
+#define WLED_CTRL_REG_OVP  0x4d
+#define  WLED_CTRL_REG_OVP_MASKGENMASK(1, 0)
 
-#define WLED3_CTRL_REG_ILIMIT  0x4e
-#define  WLED3_CTRL_REG_ILIMIT_MASK0x07
+#define WLED_CTRL_REG_ILIMIT   0x4e
+#define  WLED_CTRL_REG_ILIMIT_MASK GENMASK(2, 0)
 
-/* WLED3 sink registers */
-#define WLED3_SINK_REG_SYNC0x47
-#define  WLED3_SINK_REG_SYNC_MASK  0x07
-#define  WLED3_SINK_REG_SYNC_LED1  BIT(0)
-#define  WLED3_SINK_REG_SYNC_LED2  BIT(1)
-#define  WLED3_SINK_REG_SYNC_LED3  BIT(2)
-#define  WLED3_SINK_REG_SYNC_ALL   0x07
-#define  WLED3_SINK_REG_SYNC_CLEAR 0x00
+/* WLED sink registers */
+#define WLED_SINK_REG_SYNC 0x47
+#define  WLED_SINK_REG_SYNC_CLEAR  0x00
 
 #define WLED3_SINK_REG_CURR_SINK   0x4f
-#define  WLED3_SINK_REG_CURR_SINK_MASK 0xe0
-#define  WLED3_SINK_REG_CURR_SINK_SHFT 0x05
+#define  WLED3_SINK_REG_CURR_SINK_MASK GENMASK(7, 5)
+#define  WLED3_SINK_REG_CURR_SINK_SHFT 5
 
-/* WLED3 per-'string' registers below */
-#define WLED3_SINK_REG_STR_OFFSET  0x10
+/* WLED3 specific per-'string' registers below */
+#define WLED3_SINK_REG_BRIGHT(n)   (0x40 + n)
 
-#define WLED3_SINK_REG_STR_MOD_EN_BASE 0x60
+#define WLED3_SINK_REG_STR_MOD_EN(n)   (0x60 + (n * 0x10))
 #define  WLED3_SINK_REG_STR_MOD_MASK   BIT(7)
-#define  WLED3_SINK_REG_STR_MOD_EN BIT(7)
 
-#define WLED3_SINK_REG_STR_FULL_SCALE_CURR 0x62
-#define  WLED3_SINK_REG_STR_FULL_SCALE_CURR_MASK   0x1f
+#define WLED3_SINK_REG_STR_FULL_SCALE_CURR(n)  (0x62 + (n * 0x10))
+#define  WLED3_SINK_REG_STR_FULL_SCALE_CURR_MASK   GENMASK(4, 0)
 
-#define WLED3_SINK_REG_STR_MOD_SRC_BASE0x63
-#define  WLED3_SINK_REG_STR_MOD_SRC_MASK   0x01
+#define WLED3_SINK_REG_STR_MOD_SRC(n)  (0x63 + (n * 0x10))
+#define  WLED3_SINK_REG_STR_MOD_SRC_MASK   BIT(0)
 #define  WLED3_SINK_REG_STR_MOD_SRC_INT0x00
 #define  WLED3_SINK_REG_STR_MOD_SRC_EXT0x01
 
-#define WLED3_SINK_REG_STR_CABC_BASE   0x66
+#define WLED3_SINK_REG_STR_CABC(n) (0x66 + (n * 0x10))
 #define  WLED3_SINK_REG_STR_CABC_MASK  BIT(7)
-#define  WLED3_SINK_REG_STR_CABC_ENBIT(7)
+
+struct wled_var_cfg {
+   const u32 *values;
+   u32 (*fn)(u32);
+   int size;
+};
+
+struct wled_u32_opts {
+   const char *name;
+   u32 *val_ptr;
+   const struct wled_var_cfg *cfg;
+};
+
+struct wled_bool_opts {
+   const char *name;
+   bool *val_ptr;
+};
 
 struct wled_config {
u32 boost_i_limit;
@@ -67,132 +79,179 @@ struct wled_config {
u32 switch_freq;
u32 num_strings;
u32 string_i_limit;
+   u32 enabled_strings[WLED_MAX_STRINGS];
bool cs_out_en

[PATCH V6 6/8] backlight: qcom-wled: Add support for WLED4 peripheral

2019-09-30 Thread Kiran Gunda
WLED4 peripheral is present on some PMICs like pmi8998 and
pm660l. It has a different register map and configurations
are also different. Add support for it.

Signed-off-by: Kiran Gunda 
Reviewed-by: Bjorn Andersson 
---
 drivers/video/backlight/qcom-wled.c | 263 +++-
 1 file changed, 257 insertions(+), 6 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 740f1b6..b012a2a 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -56,6 +56,28 @@
 #define WLED3_SINK_REG_STR_CABC(n) (0x66 + (n * 0x10))
 #define  WLED3_SINK_REG_STR_CABC_MASK  BIT(7)
 
+/* WLED4 specific sink registers */
+#define WLED4_SINK_REG_CURR_SINK   0x46
+#define  WLED4_SINK_REG_CURR_SINK_MASK GENMASK(7, 4)
+#define  WLED4_SINK_REG_CURR_SINK_SHFT 4
+
+/* WLED4 specific per-'string' registers below */
+#define WLED4_SINK_REG_STR_MOD_EN(n)   (0x50 + (n * 0x10))
+#define  WLED4_SINK_REG_STR_MOD_MASK   BIT(7)
+
+#define WLED4_SINK_REG_STR_FULL_SCALE_CURR(n)  (0x52 + (n * 0x10))
+#define  WLED4_SINK_REG_STR_FULL_SCALE_CURR_MASK   GENMASK(3, 0)
+
+#define WLED4_SINK_REG_STR_MOD_SRC(n)  (0x53 + (n * 0x10))
+#define  WLED4_SINK_REG_STR_MOD_SRC_MASK   BIT(0)
+#define  WLED4_SINK_REG_STR_MOD_SRC_INT0x00
+#define  WLED4_SINK_REG_STR_MOD_SRC_EXT0x01
+
+#define WLED4_SINK_REG_STR_CABC(n) (0x56 + (n * 0x10))
+#define  WLED4_SINK_REG_STR_CABC_MASK  BIT(7)
+
+#define WLED4_SINK_REG_BRIGHT(n)   (0x57 + (n * 0x10))
+
 struct wled_var_cfg {
const u32 *values;
u32 (*fn)(u32);
@@ -90,6 +112,7 @@ struct wled {
struct device *dev;
struct regmap *regmap;
u16 ctrl_addr;
+   u16 sink_addr;
u16 max_string_count;
u32 brightness;
u32 max_brightness;
@@ -116,6 +139,29 @@ static int wled3_set_brightness(struct wled *wled, u16 
brightness)
return 0;
 }
 
+static int wled4_set_brightness(struct wled *wled, u16 brightness)
+{
+   int rc, i;
+   u16 low_limit = wled->max_brightness * 4 / 1000;
+   u8 v[2];
+
+   /* WLED4's lower limit of operation is 0.4% */
+   if (brightness > 0 && brightness < low_limit)
+   brightness = low_limit;
+
+   v[0] = brightness & 0xff;
+   v[1] = (brightness >> 8) & 0xf;
+
+   for (i = 0;  i < wled->cfg.num_strings; ++i) {
+   rc = regmap_bulk_write(wled->regmap, wled->sink_addr +
+  WLED4_SINK_REG_BRIGHT(i), v, 2);
+   if (rc < 0)
+   return rc;
+   }
+
+   return 0;
+}
+
 static int wled_module_enable(struct wled *wled, int val)
 {
int rc;
@@ -133,13 +179,13 @@ static int wled_sync_toggle(struct wled *wled)
unsigned int mask = GENMASK(wled->max_string_count - 1, 0);
 
rc = regmap_update_bits(wled->regmap,
-   wled->ctrl_addr + WLED_SINK_REG_SYNC,
+   wled->sink_addr + WLED_SINK_REG_SYNC,
mask, mask);
if (rc < 0)
return rc;
 
rc = regmap_update_bits(wled->regmap,
-   wled->ctrl_addr + WLED_SINK_REG_SYNC,
+   wled->sink_addr + WLED_SINK_REG_SYNC,
mask, WLED_SINK_REG_SYNC_CLEAR);
 
return rc;
@@ -267,6 +313,120 @@ static int wled3_setup(struct wled *wled)
.enabled_strings = {0, 1, 2, 3},
 };
 
+static int wled4_setup(struct wled *wled)
+{
+   int rc, temp, i, j;
+   u16 addr;
+   u8 sink_en = 0;
+   u32 sink_cfg = 0;
+
+   rc = regmap_update_bits(wled->regmap,
+   wled->ctrl_addr + WLED_CTRL_REG_OVP,
+   WLED_CTRL_REG_OVP_MASK, wled->cfg.ovp);
+   if (rc < 0)
+   return rc;
+
+   rc = regmap_update_bits(wled->regmap,
+   wled->ctrl_addr + WLED_CTRL_REG_ILIMIT,
+   WLED_CTRL_REG_ILIMIT_MASK,
+   wled->cfg.boost_i_limit);
+   if (rc < 0)
+   return rc;
+
+   rc = regmap_update_bits(wled->regmap,
+   wled->ctrl_addr + WLED_CTRL_REG_FREQ,
+   WLED_CTRL_REG_FREQ_MASK,
+   wled->cfg.switch_freq);
+   if (rc < 0)
+   return rc;
+
+   rc = regmap_read(wled->regmap, wled->sink_addr +
+WLED4_SINK_REG_CURR_SINK, _cfg);
+   if (rc < 0)
+   return rc;
+
+   for (

[PATCH V6 4/8] backlight: qcom-wled: Rename PM8941* to WLED3

2019-09-30 Thread Kiran Gunda
Rename the PM8941* references as WLED3 to make the driver
generic and have WLED support for other PMICs. Also rename
"i_boost_limit" and "i_limit" variables to "boost_i_limit"
and "string_i_limit" respectively to resemble the corresponding
register names.

Signed-off-by: Kiran Gunda 
Reviewed-by: Daniel Thompson 
Reviewed-by: Bjorn Andersson 
Acked-by: Pavel Machek 
---
 drivers/video/backlight/qcom-wled.c | 248 ++--
 1 file changed, 125 insertions(+), 123 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 82b8572..f191242 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -10,77 +10,79 @@
 #include 
 
 /* From DT binding */
-#define PM8941_WLED_DEFAULT_BRIGHTNESS 2048
+#define WLED_DEFAULT_BRIGHTNESS2048
 
-#define PM8941_WLED_REG_VAL_BASE   0x40
-#define  PM8941_WLED_REG_VAL_MAX   0xFFF
+#define WLED3_SINK_REG_BRIGHT_MAX  0xFFF
+#define WLED3_CTRL_REG_VAL_BASE0x40
 
-#define PM8941_WLED_REG_MOD_EN 0x46
-#define  PM8941_WLED_REG_MOD_EN_BITBIT(7)
-#define  PM8941_WLED_REG_MOD_EN_MASK   BIT(7)
+/* WLED3 control registers */
+#define WLED3_CTRL_REG_MOD_EN  0x46
+#define  WLED3_CTRL_REG_MOD_EN_BIT BIT(7)
+#define  WLED3_CTRL_REG_MOD_EN_MASKBIT(7)
 
-#define PM8941_WLED_REG_SYNC   0x47
-#define  PM8941_WLED_REG_SYNC_MASK 0x07
-#define  PM8941_WLED_REG_SYNC_LED1 BIT(0)
-#define  PM8941_WLED_REG_SYNC_LED2 BIT(1)
-#define  PM8941_WLED_REG_SYNC_LED3 BIT(2)
-#define  PM8941_WLED_REG_SYNC_ALL  0x07
-#define  PM8941_WLED_REG_SYNC_CLEAR0x00
+#define WLED3_CTRL_REG_FREQ0x4c
+#define  WLED3_CTRL_REG_FREQ_MASK  0x0f
 
-#define PM8941_WLED_REG_FREQ   0x4c
-#define  PM8941_WLED_REG_FREQ_MASK 0x0f
+#define WLED3_CTRL_REG_OVP 0x4d
+#define  WLED3_CTRL_REG_OVP_MASK   0x03
 
-#define PM8941_WLED_REG_OVP0x4d
-#define  PM8941_WLED_REG_OVP_MASK  0x03
+#define WLED3_CTRL_REG_ILIMIT  0x4e
+#define  WLED3_CTRL_REG_ILIMIT_MASK0x07
 
-#define PM8941_WLED_REG_BOOST  0x4e
-#define  PM8941_WLED_REG_BOOST_MASK0x07
+/* WLED3 sink registers */
+#define WLED3_SINK_REG_SYNC0x47
+#define  WLED3_SINK_REG_SYNC_MASK  0x07
+#define  WLED3_SINK_REG_SYNC_LED1  BIT(0)
+#define  WLED3_SINK_REG_SYNC_LED2  BIT(1)
+#define  WLED3_SINK_REG_SYNC_LED3  BIT(2)
+#define  WLED3_SINK_REG_SYNC_ALL   0x07
+#define  WLED3_SINK_REG_SYNC_CLEAR 0x00
 
-#define PM8941_WLED_REG_SINK   0x4f
-#define  PM8941_WLED_REG_SINK_MASK 0xe0
-#define  PM8941_WLED_REG_SINK_SHFT 0x05
+#define WLED3_SINK_REG_CURR_SINK   0x4f
+#define  WLED3_SINK_REG_CURR_SINK_MASK 0xe0
+#define  WLED3_SINK_REG_CURR_SINK_SHFT 0x05
 
-/* Per-'string' registers below */
-#define PM8941_WLED_REG_STR_OFFSET 0x10
+/* WLED3 per-'string' registers below */
+#define WLED3_SINK_REG_STR_OFFSET  0x10
 
-#define PM8941_WLED_REG_STR_MOD_EN_BASE0x60
-#define  PM8941_WLED_REG_STR_MOD_MASK  BIT(7)
-#define  PM8941_WLED_REG_STR_MOD_ENBIT(7)
+#define WLED3_SINK_REG_STR_MOD_EN_BASE 0x60
+#define  WLED3_SINK_REG_STR_MOD_MASK   BIT(7)
+#define  WLED3_SINK_REG_STR_MOD_EN BIT(7)
 
-#define PM8941_WLED_REG_STR_SCALE_BASE 0x62
-#define  PM8941_WLED_REG_STR_SCALE_MASK0x1f
+#define WLED3_SINK_REG_STR_FULL_SCALE_CURR 0x62
+#define  WLED3_SINK_REG_STR_FULL_SCALE_CURR_MASK   0x1f
 
-#define PM8941_WLED_REG_STR_MOD_SRC_BASE   0x63
-#define  PM8941_WLED_REG_STR_MOD_SRC_MASK  0x01
-#define  PM8941_WLED_REG_STR_MOD_SRC_INT   0x00
-#define  PM8941_WLED_REG_STR_MOD_SRC_EXT   0x01
+#define WLED3_SINK_REG_STR_MOD_SRC_BASE0x63
+#define  WLED3_SINK_REG_STR_MOD_SRC_MASK   0x01
+#define  WLED3_SINK_REG_STR_MOD_SRC_INT0x00
+#define  WLED3_SINK_REG_STR_MOD_SRC_EXT0x01
 
-#define PM8941_WLED_REG_STR_CABC_BASE  0x66
-#define  PM8941_WLED_REG_STR_CABC_MASK BIT(7)
-#define  PM8941_WLED_REG_STR_CABC_EN   BIT(7)
+#define WLED3_SINK_REG_STR_CABC_BASE   0x66
+#define  WLED3_SINK_REG_STR_CABC_MASK  BIT

[PATCH V6 3/8] backlight: qcom-wled: Add new properties for PMI8998

2019-09-30 Thread Kiran Gunda
Update the bindings with the new properties used for
PMI8998.

Signed-off-by: Kiran Gunda 
Reviewed-by: Bjorn Andersson 
Reviewed-by: Rob Herring 
Acked-by: Daniel Thompson 
---
 .../bindings/leds/backlight/qcom-wled.txt  | 76 ++
 1 file changed, 62 insertions(+), 14 deletions(-)

diff --git a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt 
b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
index 14f28f2..9d840d5 100644
--- a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
+++ b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
@@ -20,8 +20,7 @@ platforms. The PMIC is connected to the host processor via 
SPMI bus.
 - default-brightness
Usage:optional
Value type:   
-   Definition:   brightness value on boot, value from: 0-4095
- Default: 2048
+   Definition:   brightness value on boot, value from: 0-4095.
 
 - label
Usage:required
@@ -48,20 +47,24 @@ platforms. The PMIC is connected to the host processor via 
SPMI bus.
 - qcom,current-limit
Usage:optional
Value type:   
-   Definition:   mA; per-string current limit
- value: For pm8941: from 0 to 25 with 5 mA step
-Default 20 mA.
-For pmi8998: from 0 to 30 with 5 mA step
-Default 25 mA.
+   Definition:   mA; per-string current limit; value from 0 to 25 with
+ 1 mA step.
+ This property is supported only for pm8941.
+
+- qcom,current-limit-microamp
+   Usage:optional
+   Value type:   
+   Definition:   uA; per-string current limit; value from 0 to 3 with
+ 2500 uA step.
 
 - qcom,current-boost-limit
Usage:optional
Value type:   
Definition:   mA; boost current limit.
  For pm8941: one of: 105, 385, 525, 805, 980, 1260, 1400,
- 1680. Default: 805 mA
+ 1680.
  For pmi8998: one of: 105, 280, 450, 620, 970, 1150, 1300,
- 1500. Default: 970 mA
+ 1500.
 
 - qcom,switching-freq
Usage:optional
@@ -69,22 +72,66 @@ platforms. The PMIC is connected to the host processor via 
SPMI bus.
 Definition:   kHz; switching frequency; one of: 600, 640, 685, 738,
   800, 872, 960, 1066, 1200, 1371, 1600, 1920, 2400, 3200,
   4800, 9600.
-  Default: for pm8941: 1600 kHz
-   for pmi8998: 800 kHz
 
 - qcom,ovp
Usage:optional
Value type:   
Definition:   V; Over-voltage protection limit; one of:
- 27, 29, 32, 35. default: 29V
+ 27, 29, 32, 35.
  This property is supported only for PM8941.
 
+- qcom,ovp-millivolt
+   Usage:optional
+   Value type:   
+   Definition:   mV; Over-voltage protection limit;
+ For pmi8998: one of 18100, 19600, 29600, 31100
+ If this property is not specified for PM8941, it
+ falls back to "qcom,ovp" property.
+
 - qcom,num-strings
Usage:optional
Value type:   
Definition:   #; number of led strings attached;
- value from 1 to 3. default: 2
- This property is supported only for PM8941.
+ value: For PM8941 from 1 to 3.
+For PMI8998 from 1 to 4.
+
+- interrupts
+   Usage:optional
+   Value type:   
+   Definition:   Interrupts associated with WLED. This should be
+ "short" and "ovp" interrupts. Interrupts can be
+ specified as per the encoding listed under
+ Documentation/devicetree/bindings/spmi/
+ qcom,spmi-pmic-arb.txt.
+
+- interrupt-names
+   Usage:optional
+   Value type:   
+   Definition:   Interrupt names associated with the interrupts.
+ Must be "short" and "ovp". The short circuit detection
+ is not supported for PM8941.
+
+- qcom,enabled-strings
+   Usage:optional
+   Value tyoe:   
+   Definition:   Array of the WLED strings numbered from 0 to 3. Each
+ string of leds are operated individually. Specify the
+ list of strings used by the device. Any combination of
+ led strings can be used.
+
+- qcom,external-pfet
+   Usage:optional
+   Value type:   
+   Definition:   Specify if external PFET control for short circuit
+ protection is used. This property is supported only
+ for PMI8

[PATCH V6 2/8] backlight: qcom-wled: restructure the qcom-wled bindings

2019-09-30 Thread Kiran Gunda
Restructure the qcom-wled bindings for the better readability.

Signed-off-by: Kiran Gunda 
Reviewed-by: Bjorn Andersson 
Reviewed-by: Rob Herring 
Acked-by: Daniel Thompson 
Acked-by: Pavel Machek 
---
 .../bindings/leds/backlight/qcom-wled.txt  | 110 -
 1 file changed, 85 insertions(+), 25 deletions(-)

diff --git a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt 
b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
index fb39e32..14f28f2 100644
--- a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
+++ b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
@@ -1,30 +1,90 @@
 Binding for Qualcomm Technologies, Inc. WLED driver
 
-Required properties:
-- compatible: should be "qcom,pm8941-wled"
-- reg: slave address
-
-Optional properties:
-- default-brightness: brightness value on boot, value from: 0-4095
-   default: 2048
-- label: The name of the backlight device
-- qcom,cs-out: bool; enable current sink output
-- qcom,cabc: bool; enable content adaptive backlight control
-- qcom,ext-gen: bool; use externally generated modulator signal to dim
-- qcom,current-limit: mA; per-string current limit; value from 0 to 25
-   default: 20mA
-- qcom,current-boost-limit: mA; boost current limit; one of:
-   105, 385, 525, 805, 980, 1260, 1400, 1680
-   default: 805mA
-- qcom,switching-freq: kHz; switching frequency; one of:
-   600, 640, 685, 738, 800, 872, 960, 1066, 1200, 1371,
-   1600, 1920, 2400, 3200, 4800, 9600,
-   default: 1600kHz
-- qcom,ovp: V; Over-voltage protection limit; one of:
-   27, 29, 32, 35
-   default: 29V
-- qcom,num-strings: #; number of led strings attached; value from 1 to 3
-   default: 2
+WLED (White Light Emitting Diode) driver is used for controlling display
+backlight that is part of PMIC on Qualcomm Technologies, Inc. reference
+platforms. The PMIC is connected to the host processor via SPMI bus.
+
+- compatible
+   Usage:required
+   Value type:   
+   Definition:   should be one of:
+   "qcom,pm8941-wled"
+   "qcom,pmi8998-wled"
+   "qcom,pm660l-wled"
+
+- reg
+   Usage:required
+   Value type:   
+   Definition:   Base address of the WLED modules.
+
+- default-brightness
+   Usage:optional
+   Value type:   
+   Definition:   brightness value on boot, value from: 0-4095
+ Default: 2048
+
+- label
+   Usage:required
+   Value type:   
+   Definition:   The name of the backlight device
+
+- qcom,cs-out
+   Usage:optional
+   Value type:   
+   Definition:   enable current sink output.
+ This property is supported only for PM8941.
+
+- qcom,cabc
+   Usage:optional
+   Value type:   
+   Definition:   enable content adaptive backlight control.
+
+- qcom,ext-gen
+   Usage:optional
+   Value type:   
+   Definition:   use externally generated modulator signal to dim.
+ This property is supported only for PM8941.
+
+- qcom,current-limit
+   Usage:optional
+   Value type:   
+   Definition:   mA; per-string current limit
+ value: For pm8941: from 0 to 25 with 5 mA step
+Default 20 mA.
+For pmi8998: from 0 to 30 with 5 mA step
+Default 25 mA.
+
+- qcom,current-boost-limit
+   Usage:optional
+   Value type:   
+   Definition:   mA; boost current limit.
+ For pm8941: one of: 105, 385, 525, 805, 980, 1260, 1400,
+ 1680. Default: 805 mA
+ For pmi8998: one of: 105, 280, 450, 620, 970, 1150, 1300,
+ 1500. Default: 970 mA
+
+- qcom,switching-freq
+   Usage:optional
+   Value type:   
+Definition:   kHz; switching frequency; one of: 600, 640, 685, 738,
+  800, 872, 960, 1066, 1200, 1371, 1600, 1920, 2400, 3200,
+  4800, 9600.
+  Default: for pm8941: 1600 kHz
+   for pmi8998: 800 kHz
+
+- qcom,ovp
+   Usage:optional
+   Value type:   
+   Definition:   V; Over-voltage protection limit; one of:
+ 27, 29, 32, 35. default: 29V
+ This property is supported only for PM8941.
+
+- qcom,num-strings
+   Usage:optional
+   Value type:   
+   Definition:   #; number of led strings attached;
+ value from 1 to 3. default: 2
+ This property is supported only for PM8941.
 
 Example:
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project



[PATCH V6 1/8] backlight: qcom-wled: Rename pm8941-wled.c to qcom-wled.c

2019-09-30 Thread Kiran Gunda
pm8941-wled.c driver is supporting the WLED peripheral
on pm8941. Rename it to qcom-wled.c so that it can support
WLED on multiple PMICs.

Signed-off-by: Kiran Gunda 
Reviewed-by: Bjorn Andersson 
Acked-by: Rob Herring 
Acked-by: Daniel Thompson 
Acked-by: Pavel Machek 
---
 .../bindings/leds/backlight/{pm8941-wled.txt => qcom-wled.txt}| 2 +-
 drivers/video/backlight/Kconfig   | 8 
 drivers/video/backlight/Makefile  | 2 +-
 drivers/video/backlight/{pm8941-wled.c => qcom-wled.c}| 0
 4 files changed, 6 insertions(+), 6 deletions(-)
 rename Documentation/devicetree/bindings/leds/backlight/{pm8941-wled.txt => 
qcom-wled.txt} (95%)
 rename drivers/video/backlight/{pm8941-wled.c => qcom-wled.c} (100%)

diff --git a/Documentation/devicetree/bindings/leds/backlight/pm8941-wled.txt 
b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
similarity index 95%
rename from Documentation/devicetree/bindings/leds/backlight/pm8941-wled.txt
rename to Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
index e5b294d..fb39e32 100644
--- a/Documentation/devicetree/bindings/leds/backlight/pm8941-wled.txt
+++ b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
@@ -1,4 +1,4 @@
-Binding for Qualcomm PM8941 WLED driver
+Binding for Qualcomm Technologies, Inc. WLED driver
 
 Required properties:
 - compatible: should be "qcom,pm8941-wled"
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 8b081d6..6ff3176 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -284,12 +284,12 @@ config BACKLIGHT_TOSA
  If you have an Sharp SL-6000 Zaurus say Y to enable a driver
  for its backlight
 
-config BACKLIGHT_PM8941_WLED
-   tristate "Qualcomm PM8941 WLED Driver"
+config BACKLIGHT_QCOM_WLED
+   tristate "Qualcomm PMIC WLED Driver"
select REGMAP
help
- If you have the Qualcomm PM8941, say Y to enable a driver for the
- WLED block.
+ If you have the Qualcomm PMIC, say Y to enable a driver for the
+ WLED block. Currently it supports PM8941 and PMI8998.
 
 config BACKLIGHT_SAHARA
tristate "Tabletkiosk Sahara Touch-iT Backlight Driver"
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 63c507c..6f87770 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -48,8 +48,8 @@ obj-$(CONFIG_BACKLIGHT_OMAP1) += omap1_bl.o
 obj-$(CONFIG_BACKLIGHT_OT200)  += ot200_bl.o
 obj-$(CONFIG_BACKLIGHT_PANDORA)+= pandora_bl.o
 obj-$(CONFIG_BACKLIGHT_PCF50633)   += pcf50633-backlight.o
-obj-$(CONFIG_BACKLIGHT_PM8941_WLED)+= pm8941-wled.o
 obj-$(CONFIG_BACKLIGHT_PWM)+= pwm_bl.o
+obj-$(CONFIG_BACKLIGHT_QCOM_WLED)  += qcom-wled.o
 obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o
 obj-$(CONFIG_BACKLIGHT_SKY81452)   += sky81452-backlight.o
 obj-$(CONFIG_BACKLIGHT_TOSA)   += tosa_bl.o
diff --git a/drivers/video/backlight/pm8941-wled.c 
b/drivers/video/backlight/qcom-wled.c
similarity index 100%
rename from drivers/video/backlight/pm8941-wled.c
rename to drivers/video/backlight/qcom-wled.c
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project



[PATCH V6 0/8] backlight: qcom-wled: Support for QCOM wled driver

2019-09-30 Thread Kiran Gunda
This patch series renames the pm8941-wled.c driver to qcom-wled.c to add
the support for multiple PMICs supported by qualcomm. This patch series
supports both PM8941 and PMI8998 WLED. The PMI8998 WLED has the support
to handle the OVP (over voltage protection) and the SC (short circuit
protection)
interrupts. It also has the auto string detection algorithm support to
configure the right strings if the user specified string configuration
is in-correct. These three features are added in this series for PMI8998.

changes from v1:
   - Fixed the commit message for
   - backlight: qcom-wled: Rename pm8941-wled.c to qcom-wled.c

Changes from v2:
   - Fixed bjorn and other reviewer's comments
   - Seperated the device tree bindings
   - Splitted out the WLED4 changes in seperate patch
   - Merged OVP and auto string detection patch

Changes from v3:
  - Added Reviewed-by/Acked-by tags
  - Fixed comments from Bjorn/Vinod/Rob
  - Splitting the "backlight: qcom-wled: Add support for WLED4 peripheral" patch
to seperate the WLED3 specific restructure.

Changes from v4:
  - Added reviewed-by/Acked-by tags
  - Fixed comments from Bjorn/Daniel/Pavel

Changes from v5:
  - Fixed comments from Bjorn/Pavel

Kiran Gunda (8):
  backlight: qcom-wled: Rename pm8941-wled.c to qcom-wled.c
  backlight: qcom-wled: restructure the qcom-wled bindings
  backlight: qcom-wled: Add new properties for PMI8998
  backlight: qcom-wled: Rename PM8941* to WLED3
  backlight: qcom-wled: Restructure the driver for WLED3
  backlight: qcom-wled: Add support for WLED4 peripheral
  backlight: qcom-wled: add support for short circuit handling.
  backlight: qcom-wled: Add auto string detection logic

 .../bindings/leds/backlight/pm8941-wled.txt|   42 -
 .../bindings/leds/backlight/qcom-wled.txt  |  150 +++
 drivers/video/backlight/Kconfig|8 +-
 drivers/video/backlight/Makefile   |2 +-
 drivers/video/backlight/pm8941-wled.c  |  424 ---
 drivers/video/backlight/qcom-wled.c| 1288 
 6 files changed, 1443 insertions(+), 471 deletions(-)
 delete mode 100644 
Documentation/devicetree/bindings/leds/backlight/pm8941-wled.txt
 create mode 100644 
Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
 delete mode 100644 drivers/video/backlight/pm8941-wled.c
 create mode 100644 drivers/video/backlight/qcom-wled.c

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project



[PATCH V5 8/8] backlight: qcom-wled: Add auto string detection logic

2018-08-27 Thread Kiran Gunda
The auto string detection algorithm checks if the current WLED
sink configuration is valid. It tries enabling every sink and
checks if the OVP fault is observed. Based on this information
it detects and enables the valid sink configuration.
Auto calibration will be triggered when the OVP fault interrupts
are seen frequently thereby it tries to fix the sink configuration.

The auto-detection also kicks in when the connected LED string
of the display-backlight malfunctions (because of damage) and
requires the damaged string to be turned off to prevent the
complete panel and/or board from being damaged.

Signed-off-by: Kiran Gunda 
---
Changes from V3:
- Optimized the wled_ovp_work
- pr_err/pr_dbg to dev_err/dev_dbg
- removed un-necessary variable initializations
- Addressed few other comments from Bjorn 

Changes from V4:
- Passing jiffies to schedule_delayed_work
- Checking the return value of the cancel_delayed_work_sync 

 drivers/video/backlight/qcom-wled.c | 402 +++-
 1 file changed, 397 insertions(+), 5 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index d891067..3778acd 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -25,10 +25,18 @@
 #define WLED_MAX_STRINGS   4
 
 #define WLED_DEFAULT_BRIGHTNESS2048
-
+#define WLED_SOFT_START_DLY_US 1
 #define WLED_SINK_REG_BRIGHT_MAX   0xFFF
 
 /* WLED control registers */
+#define WLED_CTRL_REG_FAULT_STATUS 0x08
+#define  WLED_CTRL_REG_ILIM_FAULT_BIT  BIT(0)
+#define  WLED_CTRL_REG_OVP_FAULT_BIT   BIT(1)
+#define  WLED4_CTRL_REG_SC_FAULT_BIT   BIT(2)
+
+#define WLED_CTRL_REG_INT_RT_STS   0x10
+#define  WLED_CTRL_REG_OVP_FAULT_STATUSBIT(1)
+
 #define WLED_CTRL_REG_MOD_EN   0x46
 #define  WLED_CTRL_REG_MOD_EN_MASK BIT(7)
 #define  WLED_CTRL_REG_MOD_EN_SHIFT7
@@ -36,6 +44,8 @@
 #define WLED_CTRL_REG_FREQ 0x4c
 #define  WLED_CTRL_REG_FREQ_MASK   GENMASK(3, 0)
 
+#define WLED_CTRL_REG_FEEDBACK_CONTROL 0x48
+
 #define WLED_CTRL_REG_OVP  0x4d
 #define  WLED_CTRL_REG_OVP_MASKGENMASK(1, 0)
 
@@ -127,6 +137,7 @@ struct wled_config {
bool ext_gen;
bool cabc;
bool external_pfet;
+   bool auto_detection_enabled;
 };
 
 struct wled {
@@ -135,16 +146,22 @@ struct wled {
struct regmap *regmap;
struct mutex lock;  /* Lock to avoid race from thread irq handler */
ktime_t last_short_event;
+   ktime_t start_ovp_fault_time;
u16 ctrl_addr;
u16 sink_addr;
u16 max_string_count;
+   u16 auto_detection_ovp_count;
u32 brightness;
u32 max_brightness;
u32 short_count;
+   u32 auto_detect_count;
bool disabled_by_short;
bool has_short_detect;
+   int ovp_irq;
+   bool ovp_irq_disabled;
 
struct wled_config cfg;
+   struct delayed_work ovp_work;
int (*wled_set_brightness)(struct wled *wled, u16 brightness);
 };
 
@@ -189,6 +206,15 @@ static int wled4_set_brightness(struct wled *wled, u16 
brightness)
return 0;
 }
 
+static void wled_ovp_work(struct work_struct *work)
+{
+   struct wled *wled = container_of(work,
+struct wled, ovp_work.work);
+
+   if (wled->ovp_irq > 0)
+   enable_irq(wled->ovp_irq);
+}
+
 static int wled_module_enable(struct wled *wled, int val)
 {
int rc;
@@ -200,7 +226,18 @@ static int wled_module_enable(struct wled *wled, int val)
WLED_CTRL_REG_MOD_EN,
WLED_CTRL_REG_MOD_EN_MASK,
val << WLED_CTRL_REG_MOD_EN_SHIFT);
-   return rc;
+   if (rc < 0)
+   return rc;
+
+   if (val) {
+   schedule_delayed_work(>ovp_work, HZ / 100);
+   } else {
+   if (!cancel_delayed_work_sync(>ovp_work) &&
+   wled->ovp_irq > 0)
+   disable_irq(wled->ovp_irq);
+   }
+
+   return 0;
 }
 
 static int wled_sync_toggle(struct wled *wled)
@@ -307,6 +344,312 @@ static irqreturn_t wled_short_irq_handler(int irq, void 
*_wled)
return IRQ_HANDLED;
 }
 
+#define AUTO_DETECT_BRIGHTNESS 200
+
+static void wled_auto_string_detection(struct wled *wled)
+{
+   int rc = 0, i;
+   u32 sink_config = 0, int_sts;
+   u8 sink_test = 0, sink_valid = 0, val;
+
+   /* read configured sink configuration */
+   rc = regmap_read(wled->regmap, wled->sink_addr +
+ 

[PATCH V5 0/8] backlight: qcom-wled: Support for QCOM wled driver

2018-08-27 Thread Kiran Gunda
This patch series renames the pm8941-wled.c driver to qcom-wled.c to add
the support for multiple PMICs supported by qualcomm. This patch series
supports both PM8941 and PMI8998 WLED. The PMI8998 WLED has the support
to handle the OVP (over voltage protection) and the SC (short circuit
protection)
interrupts. It also has the auto string detection algorithm support to
configure the right strings if the user specified string configuration
is in-correct. These three features are added in this series for PMI8998.

changes from v1:
   - Fixed the commit message for
   - backlight: qcom-wled: Rename pm8941-wled.c to qcom-wled.c

Changes from v2:
   - Fixed bjorn and other reviewer's comments
   - Seperated the device tree bindings
   - Splitted out the WLED4 changes in seperate patch
   - Merged OVP and auto string detection patch

Changes from v3:
  - Added Reviewed-by/Acked-by tags
  - Fixed comments from Bjorn/Vinod/Rob
  - Splitting the "backlight: qcom-wled: Add support for WLED4 peripheral" patch
to seperate the WLED3 specific restructure.

Changes from v4:
  - Added reviewed-by/Acked-by tags
  - Fixed comments from Bjorn/Daniel/Pavel

Kiran Gunda (8):
  backlight: qcom-wled: Rename pm8941-wled.c to qcom-wled.c
  backlight: qcom-wled: restructure the qcom-wled bindings
  backlight: qcom-wled: Add new properties for PMI8998
  backlight: qcom-wled: Rename PM8941* to WLED3
  backlight: qcom-wled: Restructure the driver for WLED3
  backlight: qcom-wled: Add support for WLED4 peripheral
  backlight: qcom-wled: add support for short circuit handling
  backlight: qcom-wled: Add auto string detection logic

 .../bindings/leds/backlight/pm8941-wled.txt|   42 -
 .../bindings/leds/backlight/qcom-wled.txt  |  150 +++
 drivers/video/backlight/Kconfig|8 +-
 drivers/video/backlight/Makefile   |2 +-
 drivers/video/backlight/pm8941-wled.c  |  432 ---
 drivers/video/backlight/qcom-wled.c| 1296 
 6 files changed, 1451 insertions(+), 479 deletions(-)
 delete mode 100644 
Documentation/devicetree/bindings/leds/backlight/pm8941-wled.txt
 create mode 100644 
Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
 delete mode 100644 drivers/video/backlight/pm8941-wled.c
 create mode 100644 drivers/video/backlight/qcom-wled.c

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH V5 2/8] backlight: qcom-wled: restructure the qcom-wled bindings

2018-08-27 Thread Kiran Gunda
Restructure the qcom-wled bindings for the better readability.

Signed-off-by: Kiran Gunda 
Reviewed-by: Bjorn Andersson 
Reviewed-by: Rob Herring 
Acked-by: Daniel Thompson 
---
Changes from V3:
Added Reviewed-by and Acked-by tags.

Changes from V4:
None

 .../bindings/leds/backlight/qcom-wled.txt  | 110 -
 1 file changed, 85 insertions(+), 25 deletions(-)

diff --git a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt 
b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
index fb39e32..14f28f2 100644
--- a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
+++ b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
@@ -1,30 +1,90 @@
 Binding for Qualcomm Technologies, Inc. WLED driver
 
-Required properties:
-- compatible: should be "qcom,pm8941-wled"
-- reg: slave address
-
-Optional properties:
-- default-brightness: brightness value on boot, value from: 0-4095
-   default: 2048
-- label: The name of the backlight device
-- qcom,cs-out: bool; enable current sink output
-- qcom,cabc: bool; enable content adaptive backlight control
-- qcom,ext-gen: bool; use externally generated modulator signal to dim
-- qcom,current-limit: mA; per-string current limit; value from 0 to 25
-   default: 20mA
-- qcom,current-boost-limit: mA; boost current limit; one of:
-   105, 385, 525, 805, 980, 1260, 1400, 1680
-   default: 805mA
-- qcom,switching-freq: kHz; switching frequency; one of:
-   600, 640, 685, 738, 800, 872, 960, 1066, 1200, 1371,
-   1600, 1920, 2400, 3200, 4800, 9600,
-   default: 1600kHz
-- qcom,ovp: V; Over-voltage protection limit; one of:
-   27, 29, 32, 35
-   default: 29V
-- qcom,num-strings: #; number of led strings attached; value from 1 to 3
-   default: 2
+WLED (White Light Emitting Diode) driver is used for controlling display
+backlight that is part of PMIC on Qualcomm Technologies, Inc. reference
+platforms. The PMIC is connected to the host processor via SPMI bus.
+
+- compatible
+   Usage:required
+   Value type:   
+   Definition:   should be one of:
+   "qcom,pm8941-wled"
+   "qcom,pmi8998-wled"
+   "qcom,pm660l-wled"
+
+- reg
+   Usage:required
+   Value type:   
+   Definition:   Base address of the WLED modules.
+
+- default-brightness
+   Usage:optional
+   Value type:   
+   Definition:   brightness value on boot, value from: 0-4095
+ Default: 2048
+
+- label
+   Usage:required
+   Value type:   
+   Definition:   The name of the backlight device
+
+- qcom,cs-out
+   Usage:optional
+   Value type:   
+   Definition:   enable current sink output.
+ This property is supported only for PM8941.
+
+- qcom,cabc
+   Usage:optional
+   Value type:   
+   Definition:   enable content adaptive backlight control.
+
+- qcom,ext-gen
+   Usage:optional
+   Value type:   
+   Definition:   use externally generated modulator signal to dim.
+ This property is supported only for PM8941.
+
+- qcom,current-limit
+   Usage:optional
+   Value type:   
+   Definition:   mA; per-string current limit
+ value: For pm8941: from 0 to 25 with 5 mA step
+Default 20 mA.
+For pmi8998: from 0 to 30 with 5 mA step
+Default 25 mA.
+
+- qcom,current-boost-limit
+   Usage:optional
+   Value type:   
+   Definition:   mA; boost current limit.
+ For pm8941: one of: 105, 385, 525, 805, 980, 1260, 1400,
+ 1680. Default: 805 mA
+ For pmi8998: one of: 105, 280, 450, 620, 970, 1150, 1300,
+ 1500. Default: 970 mA
+
+- qcom,switching-freq
+   Usage:optional
+   Value type:   
+Definition:   kHz; switching frequency; one of: 600, 640, 685, 738,
+  800, 872, 960, 1066, 1200, 1371, 1600, 1920, 2400, 3200,
+  4800, 9600.
+  Default: for pm8941: 1600 kHz
+   for pmi8998: 800 kHz
+
+- qcom,ovp
+   Usage:optional
+   Value type:   
+   Definition:   V; Over-voltage protection limit; one of:
+ 27, 29, 32, 35. default: 29V
+ This property is supported only for PM8941.
+
+- qcom,num-strings
+   Usage:optional
+   Value type:   
+   Definition:   #; number of led strings attached;
+ value from 1 to 3. default: 2
+ This property is supported only for PM8941.
 
 Example:
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 

[PATCH V5 3/8] backlight: qcom-wled: Add new properties for PMI8998

2018-08-27 Thread Kiran Gunda
Update the bindings with the new properties used for
PMI8998.

Signed-off-by: Kiran Gunda 
Reviewed-by: Bjorn Andersson 
Reviewed-by: Rob Herring 
Acked-by: Daniel Thompson 
---
Changes from V3:
- Removed the default values.
- Removed pmi8998 example.

Changes from V4:
- modified qcom,enabled-strings property with decimal numbers.

 .../bindings/leds/backlight/qcom-wled.txt  | 76 ++
 1 file changed, 62 insertions(+), 14 deletions(-)

diff --git a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt 
b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
index 14f28f2..9d840d5 100644
--- a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
+++ b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
@@ -20,8 +20,7 @@ platforms. The PMIC is connected to the host processor via 
SPMI bus.
 - default-brightness
Usage:optional
Value type:   
-   Definition:   brightness value on boot, value from: 0-4095
- Default: 2048
+   Definition:   brightness value on boot, value from: 0-4095.
 
 - label
Usage:required
@@ -48,20 +47,24 @@ platforms. The PMIC is connected to the host processor via 
SPMI bus.
 - qcom,current-limit
Usage:optional
Value type:   
-   Definition:   mA; per-string current limit
- value: For pm8941: from 0 to 25 with 5 mA step
-Default 20 mA.
-For pmi8998: from 0 to 30 with 5 mA step
-Default 25 mA.
+   Definition:   mA; per-string current limit; value from 0 to 25 with
+ 1 mA step.
+ This property is supported only for pm8941.
+
+- qcom,current-limit-microamp
+   Usage:optional
+   Value type:   
+   Definition:   uA; per-string current limit; value from 0 to 3 with
+ 2500 uA step.
 
 - qcom,current-boost-limit
Usage:optional
Value type:   
Definition:   mA; boost current limit.
  For pm8941: one of: 105, 385, 525, 805, 980, 1260, 1400,
- 1680. Default: 805 mA
+ 1680.
  For pmi8998: one of: 105, 280, 450, 620, 970, 1150, 1300,
- 1500. Default: 970 mA
+ 1500.
 
 - qcom,switching-freq
Usage:optional
@@ -69,22 +72,66 @@ platforms. The PMIC is connected to the host processor via 
SPMI bus.
 Definition:   kHz; switching frequency; one of: 600, 640, 685, 738,
   800, 872, 960, 1066, 1200, 1371, 1600, 1920, 2400, 3200,
   4800, 9600.
-  Default: for pm8941: 1600 kHz
-   for pmi8998: 800 kHz
 
 - qcom,ovp
Usage:optional
Value type:   
Definition:   V; Over-voltage protection limit; one of:
- 27, 29, 32, 35. default: 29V
+ 27, 29, 32, 35.
  This property is supported only for PM8941.
 
+- qcom,ovp-millivolt
+   Usage:optional
+   Value type:   
+   Definition:   mV; Over-voltage protection limit;
+ For pmi8998: one of 18100, 19600, 29600, 31100
+ If this property is not specified for PM8941, it
+ falls back to "qcom,ovp" property.
+
 - qcom,num-strings
Usage:optional
Value type:   
Definition:   #; number of led strings attached;
- value from 1 to 3. default: 2
- This property is supported only for PM8941.
+ value: For PM8941 from 1 to 3.
+For PMI8998 from 1 to 4.
+
+- interrupts
+   Usage:optional
+   Value type:   
+   Definition:   Interrupts associated with WLED. This should be
+ "short" and "ovp" interrupts. Interrupts can be
+ specified as per the encoding listed under
+ Documentation/devicetree/bindings/spmi/
+ qcom,spmi-pmic-arb.txt.
+
+- interrupt-names
+   Usage:optional
+   Value type:   
+   Definition:   Interrupt names associated with the interrupts.
+ Must be "short" and "ovp". The short circuit detection
+ is not supported for PM8941.
+
+- qcom,enabled-strings
+   Usage:optional
+   Value tyoe:   
+   Definition:   Array of the WLED strings numbered from 0 to 3. Each
+ string of leds are operated individually. Specify the
+ list of strings used by the device. Any combination of
+ led strings can be used.
+
+- qcom,external-pfet
+   Usage:optional
+   Value type:   
+   Defini

[PATCH V5 5/8] backlight: qcom-wled: Restructure the driver for WLED3

2018-08-27 Thread Kiran Gunda
Restructure the driver to add the support for new WLED
peripherals.

Signed-off-by: Kiran Gunda 
Acked-by: Daniel Thompson 
---
Changes from V3:
- This is the new patch after splitting the 
  "backlight: qcom-wled: Add support for WLED4 peripheral" patch
  to seperate the WLED3 specific restructure.

Changes from V4:
- Initialize wled->cfg.enabled_strings to 0,1,2,3.
- Replaced the WLED3 macro with 3.

 drivers/video/backlight/qcom-wled.c | 395 ++--
 1 file changed, 245 insertions(+), 150 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 3cd6e75..a746bec 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -15,59 +15,71 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 /* From DT binding */
+#define WLED_MAX_STRINGS   4
+
 #define WLED_DEFAULT_BRIGHTNESS2048
 
-#define WLED3_SINK_REG_BRIGHT_MAX  0xFFF
-#define WLED3_CTRL_REG_VAL_BASE0x40
+#define WLED_SINK_REG_BRIGHT_MAX   0xFFF
 
-/* WLED3 control registers */
-#define WLED3_CTRL_REG_MOD_EN  0x46
-#define  WLED3_CTRL_REG_MOD_EN_BIT BIT(7)
-#define  WLED3_CTRL_REG_MOD_EN_MASKBIT(7)
+/* WLED control registers */
+#define WLED_CTRL_REG_MOD_EN   0x46
+#define  WLED_CTRL_REG_MOD_EN_MASK BIT(7)
+#define  WLED_CTRL_REG_MOD_EN_SHIFT7
 
-#define WLED3_CTRL_REG_FREQ0x4c
-#define  WLED3_CTRL_REG_FREQ_MASK  0x0f
+#define WLED_CTRL_REG_FREQ 0x4c
+#define  WLED_CTRL_REG_FREQ_MASK   GENMASK(3, 0)
 
-#define WLED3_CTRL_REG_OVP 0x4d
-#define  WLED3_CTRL_REG_OVP_MASK   0x03
+#define WLED_CTRL_REG_OVP  0x4d
+#define  WLED_CTRL_REG_OVP_MASKGENMASK(1, 0)
 
-#define WLED3_CTRL_REG_ILIMIT  0x4e
-#define  WLED3_CTRL_REG_ILIMIT_MASK0x07
+#define WLED_CTRL_REG_ILIMIT   0x4e
+#define  WLED_CTRL_REG_ILIMIT_MASK GENMASK(2, 0)
 
-/* WLED3 sink registers */
-#define WLED3_SINK_REG_SYNC0x47
-#define  WLED3_SINK_REG_SYNC_MASK  0x07
-#define  WLED3_SINK_REG_SYNC_LED1  BIT(0)
-#define  WLED3_SINK_REG_SYNC_LED2  BIT(1)
-#define  WLED3_SINK_REG_SYNC_LED3  BIT(2)
-#define  WLED3_SINK_REG_SYNC_ALL   0x07
-#define  WLED3_SINK_REG_SYNC_CLEAR 0x00
+/* WLED sink registers */
+#define WLED_SINK_REG_SYNC 0x47
+#define  WLED_SINK_REG_SYNC_CLEAR  0x00
 
 #define WLED3_SINK_REG_CURR_SINK   0x4f
-#define  WLED3_SINK_REG_CURR_SINK_MASK 0xe0
-#define  WLED3_SINK_REG_CURR_SINK_SHFT 0x05
+#define  WLED3_SINK_REG_CURR_SINK_MASK GENMASK(7, 5)
+#define  WLED3_SINK_REG_CURR_SINK_SHFT 5
 
-/* WLED3 per-'string' registers below */
-#define WLED3_SINK_REG_STR_OFFSET  0x10
+/* WLED3 specific per-'string' registers below */
+#define WLED3_SINK_REG_BRIGHT(n)   (0x40 + n)
 
-#define WLED3_SINK_REG_STR_MOD_EN_BASE 0x60
+#define WLED3_SINK_REG_STR_MOD_EN(n)   (0x60 + (n * 0x10))
 #define  WLED3_SINK_REG_STR_MOD_MASK   BIT(7)
-#define  WLED3_SINK_REG_STR_MOD_EN BIT(7)
 
-#define WLED3_SINK_REG_STR_FULL_SCALE_CURR 0x62
-#define  WLED3_SINK_REG_STR_FULL_SCALE_CURR_MASK   0x1f
+#define WLED3_SINK_REG_STR_FULL_SCALE_CURR(n)  (0x62 + (n * 0x10))
+#define  WLED3_SINK_REG_STR_FULL_SCALE_CURR_MASK   GENMASK(4, 0)
 
-#define WLED3_SINK_REG_STR_MOD_SRC_BASE0x63
-#define  WLED3_SINK_REG_STR_MOD_SRC_MASK   0x01
+#define WLED3_SINK_REG_STR_MOD_SRC(n)  (0x63 + (n * 0x10))
+#define  WLED3_SINK_REG_STR_MOD_SRC_MASK   BIT(0)
 #define  WLED3_SINK_REG_STR_MOD_SRC_INT0x00
 #define  WLED3_SINK_REG_STR_MOD_SRC_EXT0x01
 
-#define WLED3_SINK_REG_STR_CABC_BASE   0x66
+#define WLED3_SINK_REG_STR_CABC(n) (0x66 + (n * 0x10))
 #define  WLED3_SINK_REG_STR_CABC_MASK  BIT(7)
-#define  WLED3_SINK_REG_STR_CABC_ENBIT(7)
+
+struct wled_var_cfg {
+   const u32 *values;
+   u32 (*fn)(u32);
+   int size;
+};
+
+struct wled_u32_opts {
+   const char *name;
+   u32 *val_ptr;
+   const struct wled_var_cfg *cfg;
+};
+
+struct w

[PATCH V5 1/8] backlight: qcom-wled: Rename pm8941-wled.c to qcom-wled.c

2018-08-27 Thread Kiran Gunda
pm8941-wled.c driver is supporting the WLED peripheral
on pm8941. Rename it to qcom-wled.c so that it can support
WLED on multiple PMICs.

Signed-off-by: Kiran Gunda 
Reviewed-by: Bjorn Andersson 
Acked-by: Rob Herring 
Acked-by: Daniel Thompson 
---
changes from V3:
Added Reviewed-by and Acked-by tags.

changes from V4:
None

 .../bindings/leds/backlight/{pm8941-wled.txt => qcom-wled.txt}| 2 +-
 drivers/video/backlight/Kconfig   | 8 
 drivers/video/backlight/Makefile  | 2 +-
 drivers/video/backlight/{pm8941-wled.c => qcom-wled.c}| 0
 4 files changed, 6 insertions(+), 6 deletions(-)
 rename Documentation/devicetree/bindings/leds/backlight/{pm8941-wled.txt => 
qcom-wled.txt} (95%)
 rename drivers/video/backlight/{pm8941-wled.c => qcom-wled.c} (100%)

diff --git a/Documentation/devicetree/bindings/leds/backlight/pm8941-wled.txt 
b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
similarity index 95%
rename from Documentation/devicetree/bindings/leds/backlight/pm8941-wled.txt
rename to Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
index e5b294d..fb39e32 100644
--- a/Documentation/devicetree/bindings/leds/backlight/pm8941-wled.txt
+++ b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
@@ -1,4 +1,4 @@
-Binding for Qualcomm PM8941 WLED driver
+Binding for Qualcomm Technologies, Inc. WLED driver
 
 Required properties:
 - compatible: should be "qcom,pm8941-wled"
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 2919e23..2c29180 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -306,12 +306,12 @@ config BACKLIGHT_TOSA
  If you have an Sharp SL-6000 Zaurus say Y to enable a driver
  for its backlight
 
-config BACKLIGHT_PM8941_WLED
-   tristate "Qualcomm PM8941 WLED Driver"
+config BACKLIGHT_QCOM_WLED
+   tristate "Qualcomm PMIC WLED Driver"
select REGMAP
help
- If you have the Qualcomm PM8941, say Y to enable a driver for the
- WLED block.
+ If you have the Qualcomm PMIC, say Y to enable a driver for the
+ WLED block. Currently it supports PM8941 and PMI8998.
 
 config BACKLIGHT_SAHARA
tristate "Tabletkiosk Sahara Touch-iT Backlight Driver"
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 0dcc2c7..741ab36 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -50,8 +50,8 @@ obj-$(CONFIG_BACKLIGHT_OMAP1) += omap1_bl.o
 obj-$(CONFIG_BACKLIGHT_OT200)  += ot200_bl.o
 obj-$(CONFIG_BACKLIGHT_PANDORA)+= pandora_bl.o
 obj-$(CONFIG_BACKLIGHT_PCF50633)   += pcf50633-backlight.o
-obj-$(CONFIG_BACKLIGHT_PM8941_WLED)+= pm8941-wled.o
 obj-$(CONFIG_BACKLIGHT_PWM)+= pwm_bl.o
+obj-$(CONFIG_BACKLIGHT_QCOM_WLED)  += qcom-wled.o
 obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o
 obj-$(CONFIG_BACKLIGHT_SKY81452)   += sky81452-backlight.o
 obj-$(CONFIG_BACKLIGHT_TOSA)   += tosa_bl.o
diff --git a/drivers/video/backlight/pm8941-wled.c 
b/drivers/video/backlight/qcom-wled.c
similarity index 100%
rename from drivers/video/backlight/pm8941-wled.c
rename to drivers/video/backlight/qcom-wled.c
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH V5 6/8] backlight: qcom-wled: Add support for WLED4 peripheral

2018-08-27 Thread Kiran Gunda
WLED4 peripheral is present on some PMICs like pmi8998 and
pm660l. It has a different register map and configurations
are also different. Add support for it.

Signed-off-by: Kiran Gunda 
Reviewed-by: Bjorn Andersson 
---
Changes from V3:
- The WLED3 specific changes are splitted out
- Merged the wled3_sync_toggle and wled4_syn_toggle functions
- Modified the compatible .data
- Moved from if/else to switch/case to select the version specific data
- Addressed few more minor comments from Bjorn

Changes from V4:
- replaced the WLED4 macro with 4.

 drivers/video/backlight/qcom-wled.c | 263 +++-
 1 file changed, 257 insertions(+), 6 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index a746bec..49fdd23 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -64,6 +64,28 @@
 #define WLED3_SINK_REG_STR_CABC(n) (0x66 + (n * 0x10))
 #define  WLED3_SINK_REG_STR_CABC_MASK  BIT(7)
 
+/* WLED4 specific sink registers */
+#define WLED4_SINK_REG_CURR_SINK   0x46
+#define  WLED4_SINK_REG_CURR_SINK_MASK GENMASK(7, 4)
+#define  WLED4_SINK_REG_CURR_SINK_SHFT 4
+
+/* WLED4 specific per-'string' registers below */
+#define WLED4_SINK_REG_STR_MOD_EN(n)   (0x50 + (n * 0x10))
+#define  WLED4_SINK_REG_STR_MOD_MASK   BIT(7)
+
+#define WLED4_SINK_REG_STR_FULL_SCALE_CURR(n)  (0x52 + (n * 0x10))
+#define  WLED4_SINK_REG_STR_FULL_SCALE_CURR_MASK   GENMASK(3, 0)
+
+#define WLED4_SINK_REG_STR_MOD_SRC(n)  (0x53 + (n * 0x10))
+#define  WLED4_SINK_REG_STR_MOD_SRC_MASK   BIT(0)
+#define  WLED4_SINK_REG_STR_MOD_SRC_INT0x00
+#define  WLED4_SINK_REG_STR_MOD_SRC_EXT0x01
+
+#define WLED4_SINK_REG_STR_CABC(n) (0x56 + (n * 0x10))
+#define  WLED4_SINK_REG_STR_CABC_MASK  BIT(7)
+
+#define WLED4_SINK_REG_BRIGHT(n)   (0x57 + (n * 0x10))
+
 struct wled_var_cfg {
const u32 *values;
u32 (*fn)(u32);
@@ -98,6 +120,7 @@ struct wled {
struct device *dev;
struct regmap *regmap;
u16 ctrl_addr;
+   u16 sink_addr;
u16 max_string_count;
u32 brightness;
u32 max_brightness;
@@ -124,6 +147,29 @@ static int wled3_set_brightness(struct wled *wled, u16 
brightness)
return 0;
 }
 
+static int wled4_set_brightness(struct wled *wled, u16 brightness)
+{
+   int rc, i;
+   u16 low_limit = wled->max_brightness * 4 / 1000;
+   u8 v[2];
+
+   /* WLED4's lower limit of operation is 0.4% */
+   if (brightness > 0 && brightness < low_limit)
+   brightness = low_limit;
+
+   v[0] = brightness & 0xff;
+   v[1] = (brightness >> 8) & 0xf;
+
+   for (i = 0;  i < wled->cfg.num_strings; ++i) {
+   rc = regmap_bulk_write(wled->regmap, wled->sink_addr +
+  WLED4_SINK_REG_BRIGHT(i), v, 2);
+   if (rc < 0)
+   return rc;
+   }
+
+   return 0;
+}
+
 static int wled_module_enable(struct wled *wled, int val)
 {
int rc;
@@ -141,13 +187,13 @@ static int wled_sync_toggle(struct wled *wled)
unsigned int mask = GENMASK(wled->max_string_count - 1, 0);
 
rc = regmap_update_bits(wled->regmap,
-   wled->ctrl_addr + WLED_SINK_REG_SYNC,
+   wled->sink_addr + WLED_SINK_REG_SYNC,
mask, mask);
if (rc < 0)
return rc;
 
rc = regmap_update_bits(wled->regmap,
-   wled->ctrl_addr + WLED_SINK_REG_SYNC,
+   wled->sink_addr + WLED_SINK_REG_SYNC,
mask, WLED_SINK_REG_SYNC_CLEAR);
 
return rc;
@@ -275,6 +321,120 @@ static int wled3_setup(struct wled *wled)
.enabled_strings = {0, 1, 2, 3},
 };
 
+static int wled4_setup(struct wled *wled)
+{
+   int rc, temp, i, j;
+   u16 addr;
+   u8 sink_en = 0;
+   u32 sink_cfg = 0;
+
+   rc = regmap_update_bits(wled->regmap,
+   wled->ctrl_addr + WLED_CTRL_REG_OVP,
+   WLED_CTRL_REG_OVP_MASK, wled->cfg.ovp);
+   if (rc < 0)
+   return rc;
+
+   rc = regmap_update_bits(wled->regmap,
+   wled->ctrl_addr + WLED_CTRL_REG_ILIMIT,
+   WLED_CTRL_REG_ILIMIT_MASK,
+   wled->cfg.boost_i_limit);
+   if (rc < 0)
+   return rc;
+
+   rc = regmap_update_bits(wled->regmap,
+   wled->ctrl_addr + WLED_CTRL_REG

[PATCH V5 4/8] backlight: qcom-wled: Rename PM8941* to WLED3

2018-08-27 Thread Kiran Gunda
Rename the PM8941* references as WLED3 to make the driver
generic and have WLED support for other PMICs. Also rename
"i_boost_limit" and "i_limit" variables to "boost_i_limit"
and "string_i_limit" respectively to resemble the corresponding
register names.

Signed-off-by: Kiran Gunda 
Reviewed-by: Daniel Thompson 
Reviewed-by: Bjorn Andersson 
---
Changes from V3:
- Changed the MODULE_DESCRIPTION

Changes from V4:
- Updated the commit message.

 drivers/video/backlight/qcom-wled.c | 248 ++--
 1 file changed, 125 insertions(+), 123 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 0b6d219..3cd6e75 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -18,77 +18,79 @@
 #include 
 
 /* From DT binding */
-#define PM8941_WLED_DEFAULT_BRIGHTNESS 2048
+#define WLED_DEFAULT_BRIGHTNESS2048
 
-#define PM8941_WLED_REG_VAL_BASE   0x40
-#define  PM8941_WLED_REG_VAL_MAX   0xFFF
+#define WLED3_SINK_REG_BRIGHT_MAX  0xFFF
+#define WLED3_CTRL_REG_VAL_BASE0x40
 
-#define PM8941_WLED_REG_MOD_EN 0x46
-#define  PM8941_WLED_REG_MOD_EN_BITBIT(7)
-#define  PM8941_WLED_REG_MOD_EN_MASK   BIT(7)
+/* WLED3 control registers */
+#define WLED3_CTRL_REG_MOD_EN  0x46
+#define  WLED3_CTRL_REG_MOD_EN_BIT BIT(7)
+#define  WLED3_CTRL_REG_MOD_EN_MASKBIT(7)
 
-#define PM8941_WLED_REG_SYNC   0x47
-#define  PM8941_WLED_REG_SYNC_MASK 0x07
-#define  PM8941_WLED_REG_SYNC_LED1 BIT(0)
-#define  PM8941_WLED_REG_SYNC_LED2 BIT(1)
-#define  PM8941_WLED_REG_SYNC_LED3 BIT(2)
-#define  PM8941_WLED_REG_SYNC_ALL  0x07
-#define  PM8941_WLED_REG_SYNC_CLEAR0x00
+#define WLED3_CTRL_REG_FREQ0x4c
+#define  WLED3_CTRL_REG_FREQ_MASK  0x0f
 
-#define PM8941_WLED_REG_FREQ   0x4c
-#define  PM8941_WLED_REG_FREQ_MASK 0x0f
+#define WLED3_CTRL_REG_OVP 0x4d
+#define  WLED3_CTRL_REG_OVP_MASK   0x03
 
-#define PM8941_WLED_REG_OVP0x4d
-#define  PM8941_WLED_REG_OVP_MASK  0x03
+#define WLED3_CTRL_REG_ILIMIT  0x4e
+#define  WLED3_CTRL_REG_ILIMIT_MASK0x07
 
-#define PM8941_WLED_REG_BOOST  0x4e
-#define  PM8941_WLED_REG_BOOST_MASK0x07
+/* WLED3 sink registers */
+#define WLED3_SINK_REG_SYNC0x47
+#define  WLED3_SINK_REG_SYNC_MASK  0x07
+#define  WLED3_SINK_REG_SYNC_LED1  BIT(0)
+#define  WLED3_SINK_REG_SYNC_LED2  BIT(1)
+#define  WLED3_SINK_REG_SYNC_LED3  BIT(2)
+#define  WLED3_SINK_REG_SYNC_ALL   0x07
+#define  WLED3_SINK_REG_SYNC_CLEAR 0x00
 
-#define PM8941_WLED_REG_SINK   0x4f
-#define  PM8941_WLED_REG_SINK_MASK 0xe0
-#define  PM8941_WLED_REG_SINK_SHFT 0x05
+#define WLED3_SINK_REG_CURR_SINK   0x4f
+#define  WLED3_SINK_REG_CURR_SINK_MASK 0xe0
+#define  WLED3_SINK_REG_CURR_SINK_SHFT 0x05
 
-/* Per-'string' registers below */
-#define PM8941_WLED_REG_STR_OFFSET 0x10
+/* WLED3 per-'string' registers below */
+#define WLED3_SINK_REG_STR_OFFSET  0x10
 
-#define PM8941_WLED_REG_STR_MOD_EN_BASE0x60
-#define  PM8941_WLED_REG_STR_MOD_MASK  BIT(7)
-#define  PM8941_WLED_REG_STR_MOD_ENBIT(7)
+#define WLED3_SINK_REG_STR_MOD_EN_BASE 0x60
+#define  WLED3_SINK_REG_STR_MOD_MASK   BIT(7)
+#define  WLED3_SINK_REG_STR_MOD_EN BIT(7)
 
-#define PM8941_WLED_REG_STR_SCALE_BASE 0x62
-#define  PM8941_WLED_REG_STR_SCALE_MASK0x1f
+#define WLED3_SINK_REG_STR_FULL_SCALE_CURR 0x62
+#define  WLED3_SINK_REG_STR_FULL_SCALE_CURR_MASK   0x1f
 
-#define PM8941_WLED_REG_STR_MOD_SRC_BASE   0x63
-#define  PM8941_WLED_REG_STR_MOD_SRC_MASK  0x01
-#define  PM8941_WLED_REG_STR_MOD_SRC_INT   0x00
-#define  PM8941_WLED_REG_STR_MOD_SRC_EXT   0x01
+#define WLED3_SINK_REG_STR_MOD_SRC_BASE0x63
+#define  WLED3_SINK_REG_STR_MOD_SRC_MASK   0x01
+#define  WLED3_SINK_REG_STR_MOD_SRC_INT0x00
+#define  WLED3_SINK_REG_STR_MOD_SRC_EXT0x01
 
-#define PM8941_WLED_REG_STR_CABC_BASE  0x66
-#define  PM8941_WLED_REG_STR_CABC_MASK BIT(7)
-#define  PM8941_WLED_REG_STR_CABC_EN   BIT(7)
+#define WLED3_SINK_REG_STR_C

[PATCH V5 7/8] backlight: qcom-wled: add support for short circuit handling

2018-08-27 Thread Kiran Gunda
Handle the short circuit interrupt and check if the short circuit
interrupt is valid. Re-enable the module to check if it goes
away. Disable the module altogether if the short circuit event
persists.

Signed-off-by: Kiran Gunda 
Reviewed-by: Bjorn Andersson 
---
Changes from V3:
- Added Reviewed by tag.
- Addressed minor comments from Vinod

Changes from V4:
- Changed the return value from -EINVAL to -ENXIO
- Re-initializing the short_count from 0 to 1.

 drivers/video/backlight/qcom-wled.c | 132 ++--
 1 file changed, 128 insertions(+), 4 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 49fdd23..d891067 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -10,6 +10,9 @@
  * GNU General Public License for more details.
  */
 
+#include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -64,6 +67,16 @@
 #define WLED3_SINK_REG_STR_CABC(n) (0x66 + (n * 0x10))
 #define  WLED3_SINK_REG_STR_CABC_MASK  BIT(7)
 
+/* WLED4 specific control registers */
+#define WLED4_CTRL_REG_SHORT_PROTECT   0x5e
+#define  WLED4_CTRL_REG_SHORT_EN_MASK  BIT(7)
+
+#define WLED4_CTRL_REG_SEC_ACCESS  0xd0
+#define  WLED4_CTRL_REG_SEC_UNLOCK 0xa5
+
+#define WLED4_CTRL_REG_TEST1   0xe2
+#define  WLED4_CTRL_REG_TEST1_EXT_FET_DTEST2   0x09
+
 /* WLED4 specific sink registers */
 #define WLED4_SINK_REG_CURR_SINK   0x46
 #define  WLED4_SINK_REG_CURR_SINK_MASK GENMASK(7, 4)
@@ -113,17 +126,23 @@ struct wled_config {
bool cs_out_en;
bool ext_gen;
bool cabc;
+   bool external_pfet;
 };
 
 struct wled {
const char *name;
struct device *dev;
struct regmap *regmap;
+   struct mutex lock;  /* Lock to avoid race from thread irq handler */
+   ktime_t last_short_event;
u16 ctrl_addr;
u16 sink_addr;
u16 max_string_count;
u32 brightness;
u32 max_brightness;
+   u32 short_count;
+   bool disabled_by_short;
+   bool has_short_detect;
 
struct wled_config cfg;
int (*wled_set_brightness)(struct wled *wled, u16 brightness);
@@ -174,6 +193,9 @@ static int wled_module_enable(struct wled *wled, int val)
 {
int rc;
 
+   if (wled->disabled_by_short)
+   return -ENXIO;
+
rc = regmap_update_bits(wled->regmap, wled->ctrl_addr +
WLED_CTRL_REG_MOD_EN,
WLED_CTRL_REG_MOD_EN_MASK,
@@ -210,18 +232,19 @@ static int wled_update_status(struct backlight_device *bl)
bl->props.state & BL_CORE_FBBLANK)
brightness = 0;
 
+   mutex_lock(>lock);
if (brightness) {
rc = wled->wled_set_brightness(wled, brightness);
if (rc < 0) {
dev_err(wled->dev, "wled failed to set brightness 
rc:%d\n",
rc);
-   return rc;
+   goto unlock_mutex;
}
 
rc = wled_sync_toggle(wled);
if (rc < 0) {
dev_err(wled->dev, "wled sync failed rc:%d\n", rc);
-   return rc;
+   goto unlock_mutex;
}
}
 
@@ -229,15 +252,61 @@ static int wled_update_status(struct backlight_device *bl)
rc = wled_module_enable(wled, !!brightness);
if (rc < 0) {
dev_err(wled->dev, "wled enable failed rc:%d\n", rc);
-   return rc;
+   goto unlock_mutex;
}
}
 
wled->brightness = brightness;
 
+unlock_mutex:
+   mutex_unlock(>lock);
+
return rc;
 }
 
+#define WLED_SHORT_DLY_MS  20
+#define WLED_SHORT_CNT_MAX 5
+#define WLED_SHORT_RESET_CNT_DLY_USUSEC_PER_SEC
+
+static irqreturn_t wled_short_irq_handler(int irq, void *_wled)
+{
+   struct wled *wled = _wled;
+   int rc;
+   s64 elapsed_time;
+
+   wled->short_count++;
+   mutex_lock(>lock);
+   rc = wled_module_enable(wled, false);
+   if (rc < 0) {
+   dev_err(wled->dev, "wled disable failed rc:%d\n", rc);
+   goto unlock_mutex;
+   }
+
+   elapsed_time = ktime_us_delta(ktime_get(),
+ wled->last_short_event);
+   if (elapsed_time > WLED_SHORT_RESET_CNT_DLY_US)
+   wled->short_count = 1;
+
+   if (wled->short_count > WLED_SHORT_CNT_MAX) {
+   dev_err(wled->dev, "Short trigged %d times, disabling WLED 
fore

[PATCH V4 8/8] backlight: qcom-wled: Add auto string detection logic

2018-07-10 Thread Kiran Gunda
The auto string detection algorithm checks if the current WLED
sink configuration is valid. It tries enabling every sink and
checks if the OVP fault is observed. Based on this information
it detects and enables the valid sink configuration.
Auto calibration will be triggered when the OVP fault interrupts
are seen frequently thereby it tries to fix the sink configuration.

The auto-detection also kicks in when the connected LED string
of the display-backlight malfunctions (because of damage) and
requires the damaged string to be turned off to prevent the
complete panel and/or board from being damaged.

Signed-off-by: Kiran Gunda 
---
Changes from V3:
- Optimized the wled_ovp_work
- pr_err/pr_dbg to dev_err/dev_dbg
- removed un-necessary variable initializations
- Addressed few other comments from Bjorn 

 drivers/video/backlight/qcom-wled.c | 402 +++-
 1 file changed, 397 insertions(+), 5 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index a14f1a6..b7d4fae 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -25,10 +25,18 @@
 #define WLED_MAX_STRINGS   4
 
 #define WLED_DEFAULT_BRIGHTNESS2048
-
+#define WLED_SOFT_START_DLY_US 1
 #define WLED_SINK_REG_BRIGHT_MAX   0xFFF
 
 /* WLED control registers */
+#define WLED_CTRL_REG_FAULT_STATUS 0x08
+#define  WLED_CTRL_REG_ILIM_FAULT_BIT  BIT(0)
+#define  WLED_CTRL_REG_OVP_FAULT_BIT   BIT(1)
+#define  WLED4_CTRL_REG_SC_FAULT_BIT   BIT(2)
+
+#define WLED_CTRL_REG_INT_RT_STS   0x10
+#define  WLED_CTRL_REG_OVP_FAULT_STATUSBIT(1)
+
 #define WLED_CTRL_REG_MOD_EN   0x46
 #define  WLED_CTRL_REG_MOD_EN_MASK BIT(7)
 #define  WLED_CTRL_REG_MOD_EN_SHIFT7
@@ -36,6 +44,8 @@
 #define WLED_CTRL_REG_FREQ 0x4c
 #define  WLED_CTRL_REG_FREQ_MASK   GENMASK(3, 0)
 
+#define WLED_CTRL_REG_FEEDBACK_CONTROL 0x48
+
 #define WLED_CTRL_REG_OVP  0x4d
 #define  WLED_CTRL_REG_OVP_MASKGENMASK(1, 0)
 
@@ -127,6 +137,7 @@ struct wled_config {
bool ext_gen;
bool cabc;
bool external_pfet;
+   bool auto_detection_enabled;
 };
 
 struct wled {
@@ -135,16 +146,22 @@ struct wled {
struct regmap *regmap;
struct mutex lock;  /* Lock to avoid race from thread irq handler */
ktime_t last_short_event;
+   ktime_t start_ovp_fault_time;
u16 ctrl_addr;
u16 sink_addr;
u16 max_string_count;
+   u16 auto_detection_ovp_count;
u32 brightness;
u32 max_brightness;
u32 short_count;
+   u32 auto_detect_count;
bool disabled_by_short;
bool has_short_detect;
+   int ovp_irq;
+   bool ovp_irq_disabled;
 
struct wled_config cfg;
+   struct delayed_work ovp_work;
int (*wled_set_brightness)(struct wled *wled, u16 brightness);
 };
 
@@ -189,6 +206,15 @@ static int wled4_set_brightness(struct wled *wled, u16 
brightness)
return 0;
 }
 
+static void wled_ovp_work(struct work_struct *work)
+{
+   struct wled *wled = container_of(work,
+struct wled, ovp_work.work);
+
+   if (wled->ovp_irq > 0)
+   enable_irq(wled->ovp_irq);
+}
+
 static int wled_module_enable(struct wled *wled, int val)
 {
int rc;
@@ -200,7 +226,18 @@ static int wled_module_enable(struct wled *wled, int val)
WLED_CTRL_REG_MOD_EN,
WLED_CTRL_REG_MOD_EN_MASK,
val << WLED_CTRL_REG_MOD_EN_SHIFT);
-   return rc;
+   if (rc < 0)
+   return rc;
+
+   if (val) {
+   schedule_delayed_work(>ovp_work, WLED_SOFT_START_DLY_US);
+   } else {
+   cancel_delayed_work_sync(>ovp_work);
+   if (wled->ovp_irq > 0)
+   disable_irq(wled->ovp_irq);
+   }
+
+   return 0;
 }
 
 static int wled_sync_toggle(struct wled *wled)
@@ -307,6 +344,312 @@ static irqreturn_t wled_short_irq_handler(int irq, void 
*_wled)
return IRQ_HANDLED;
 }
 
+#define AUTO_DETECT_BRIGHTNESS 200
+
+static void wled_auto_string_detection(struct wled *wled)
+{
+   int rc = 0, i;
+   u32 sink_config = 0, int_sts;
+   u8 sink_test = 0, sink_valid = 0, val;
+
+   /* read configured sink configuration */
+   rc = regmap_read(wled->regmap, wled->sink_addr +
+WLED4_SINK_REG_CURR_SINK, _config);
+   if (rc < 0) {
+   dev_err(wled->de

[PATCH V4 6/8] backlight: qcom-wled: Add support for WLED4 peripheral

2018-07-10 Thread Kiran Gunda
WLED4 peripheral is present on some PMICs like pmi8998 and
pm660l. It has a different register map and configurations
are also different. Add support for it.

Signed-off-by: Kiran Gunda 
---
Changes from V3:
- The WLED3 specific changes are splitted out
- Merged the wled3_sync_toggle and wled4_syn_toggle functions
- Modified the compatible .data
- Moved from if/else to switch/case to select the version specific data
- Addressed few more minor comments from Bjorn

 drivers/video/backlight/qcom-wled.c | 264 +++-
 1 file changed, 258 insertions(+), 6 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 87fc1d0..362d254 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -64,6 +64,28 @@
 #define WLED3_SINK_REG_STR_CABC(n) (0x66 + (n * 0x10))
 #define  WLED3_SINK_REG_STR_CABC_MASK  BIT(7)
 
+/* WLED4 specific sink registers */
+#define WLED4_SINK_REG_CURR_SINK   0x46
+#define  WLED4_SINK_REG_CURR_SINK_MASK GENMASK(7, 4)
+#define  WLED4_SINK_REG_CURR_SINK_SHFT 4
+
+/* WLED4 specific per-'string' registers below */
+#define WLED4_SINK_REG_STR_MOD_EN(n)   (0x50 + (n * 0x10))
+#define  WLED4_SINK_REG_STR_MOD_MASK   BIT(7)
+
+#define WLED4_SINK_REG_STR_FULL_SCALE_CURR(n)  (0x52 + (n * 0x10))
+#define  WLED4_SINK_REG_STR_FULL_SCALE_CURR_MASK   GENMASK(3, 0)
+
+#define WLED4_SINK_REG_STR_MOD_SRC(n)  (0x53 + (n * 0x10))
+#define  WLED4_SINK_REG_STR_MOD_SRC_MASK   BIT(0)
+#define  WLED4_SINK_REG_STR_MOD_SRC_INT0x00
+#define  WLED4_SINK_REG_STR_MOD_SRC_EXT0x01
+
+#define WLED4_SINK_REG_STR_CABC(n) (0x56 + (n * 0x10))
+#define  WLED4_SINK_REG_STR_CABC_MASK  BIT(7)
+
+#define WLED4_SINK_REG_BRIGHT(n)   (0x57 + (n * 0x10))
+
 struct wled_var_cfg {
const u32 *values;
u32 (*fn)(u32);
@@ -98,6 +120,7 @@ struct wled {
struct device *dev;
struct regmap *regmap;
u16 ctrl_addr;
+   u16 sink_addr;
u16 max_string_count;
u32 brightness;
u32 max_brightness;
@@ -124,6 +147,29 @@ static int wled3_set_brightness(struct wled *wled, u16 
brightness)
return 0;
 }
 
+static int wled4_set_brightness(struct wled *wled, u16 brightness)
+{
+   int rc, i;
+   u16 low_limit = wled->max_brightness * 4 / 1000;
+   u8 v[2];
+
+   /* WLED4's lower limit of operation is 0.4% */
+   if (brightness > 0 && brightness < low_limit)
+   brightness = low_limit;
+
+   v[0] = brightness & 0xff;
+   v[1] = (brightness >> 8) & 0xf;
+
+   for (i = 0;  i < wled->cfg.num_strings; ++i) {
+   rc = regmap_bulk_write(wled->regmap, wled->sink_addr +
+  WLED4_SINK_REG_BRIGHT(i), v, 2);
+   if (rc < 0)
+   return rc;
+   }
+
+   return 0;
+}
+
 static int wled_module_enable(struct wled *wled, int val)
 {
int rc;
@@ -141,13 +187,13 @@ static int wled_sync_toggle(struct wled *wled)
unsigned int mask = GENMASK(wled->max_string_count - 1, 0);
 
rc = regmap_update_bits(wled->regmap,
-   wled->ctrl_addr + WLED_SINK_REG_SYNC,
+   wled->sink_addr + WLED_SINK_REG_SYNC,
mask, mask);
if (rc < 0)
return rc;
 
rc = regmap_update_bits(wled->regmap,
-   wled->ctrl_addr + WLED_SINK_REG_SYNC,
+   wled->sink_addr + WLED_SINK_REG_SYNC,
mask, WLED_SINK_REG_SYNC_CLEAR);
 
return rc;
@@ -274,6 +320,120 @@ static int wled3_setup(struct wled *wled)
.cabc = false,
 };
 
+static int wled4_setup(struct wled *wled)
+{
+   int rc, temp, i, j;
+   u16 addr;
+   u8 sink_en = 0;
+   u32 sink_cfg = 0;
+
+   rc = regmap_update_bits(wled->regmap,
+   wled->ctrl_addr + WLED_CTRL_REG_OVP,
+   WLED_CTRL_REG_OVP_MASK, wled->cfg.ovp);
+   if (rc < 0)
+   return rc;
+
+   rc = regmap_update_bits(wled->regmap,
+   wled->ctrl_addr + WLED_CTRL_REG_ILIMIT,
+   WLED_CTRL_REG_ILIMIT_MASK,
+   wled->cfg.boost_i_limit);
+   if (rc < 0)
+   return rc;
+
+   rc = regmap_update_bits(wled->regmap,
+   wled->ctrl_addr + WLED_CTRL_REG_FREQ,
+   WLED_CTRL_REG_FREQ_MASK,
+   wl

[PATCH V4 2/8] backlight: qcom-wled: restructure the qcom-wled bindings

2018-07-10 Thread Kiran Gunda
Restructure the qcom-wled bindings for the better readability.

Signed-off-by: Kiran Gunda 
Reviewed-by: Bjorn Andersson 
Reviewed-by: Rob Herring 
Acked-by: Daniel Thompson 
---
Changes from V3:
Added Reviewed-by and Acked-by tags.

 .../bindings/leds/backlight/qcom-wled.txt  | 110 -
 1 file changed, 85 insertions(+), 25 deletions(-)

diff --git a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt 
b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
index fb39e32..14f28f2 100644
--- a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
+++ b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
@@ -1,30 +1,90 @@
 Binding for Qualcomm Technologies, Inc. WLED driver
 
-Required properties:
-- compatible: should be "qcom,pm8941-wled"
-- reg: slave address
-
-Optional properties:
-- default-brightness: brightness value on boot, value from: 0-4095
-   default: 2048
-- label: The name of the backlight device
-- qcom,cs-out: bool; enable current sink output
-- qcom,cabc: bool; enable content adaptive backlight control
-- qcom,ext-gen: bool; use externally generated modulator signal to dim
-- qcom,current-limit: mA; per-string current limit; value from 0 to 25
-   default: 20mA
-- qcom,current-boost-limit: mA; boost current limit; one of:
-   105, 385, 525, 805, 980, 1260, 1400, 1680
-   default: 805mA
-- qcom,switching-freq: kHz; switching frequency; one of:
-   600, 640, 685, 738, 800, 872, 960, 1066, 1200, 1371,
-   1600, 1920, 2400, 3200, 4800, 9600,
-   default: 1600kHz
-- qcom,ovp: V; Over-voltage protection limit; one of:
-   27, 29, 32, 35
-   default: 29V
-- qcom,num-strings: #; number of led strings attached; value from 1 to 3
-   default: 2
+WLED (White Light Emitting Diode) driver is used for controlling display
+backlight that is part of PMIC on Qualcomm Technologies, Inc. reference
+platforms. The PMIC is connected to the host processor via SPMI bus.
+
+- compatible
+   Usage:required
+   Value type:   
+   Definition:   should be one of:
+   "qcom,pm8941-wled"
+   "qcom,pmi8998-wled"
+   "qcom,pm660l-wled"
+
+- reg
+   Usage:required
+   Value type:   
+   Definition:   Base address of the WLED modules.
+
+- default-brightness
+   Usage:optional
+   Value type:   
+   Definition:   brightness value on boot, value from: 0-4095
+ Default: 2048
+
+- label
+   Usage:required
+   Value type:   
+   Definition:   The name of the backlight device
+
+- qcom,cs-out
+   Usage:optional
+   Value type:   
+   Definition:   enable current sink output.
+ This property is supported only for PM8941.
+
+- qcom,cabc
+   Usage:optional
+   Value type:   
+   Definition:   enable content adaptive backlight control.
+
+- qcom,ext-gen
+   Usage:optional
+   Value type:   
+   Definition:   use externally generated modulator signal to dim.
+ This property is supported only for PM8941.
+
+- qcom,current-limit
+   Usage:optional
+   Value type:   
+   Definition:   mA; per-string current limit
+ value: For pm8941: from 0 to 25 with 5 mA step
+Default 20 mA.
+For pmi8998: from 0 to 30 with 5 mA step
+Default 25 mA.
+
+- qcom,current-boost-limit
+   Usage:optional
+   Value type:   
+   Definition:   mA; boost current limit.
+ For pm8941: one of: 105, 385, 525, 805, 980, 1260, 1400,
+ 1680. Default: 805 mA
+ For pmi8998: one of: 105, 280, 450, 620, 970, 1150, 1300,
+ 1500. Default: 970 mA
+
+- qcom,switching-freq
+   Usage:optional
+   Value type:   
+Definition:   kHz; switching frequency; one of: 600, 640, 685, 738,
+  800, 872, 960, 1066, 1200, 1371, 1600, 1920, 2400, 3200,
+  4800, 9600.
+  Default: for pm8941: 1600 kHz
+   for pmi8998: 800 kHz
+
+- qcom,ovp
+   Usage:optional
+   Value type:   
+   Definition:   V; Over-voltage protection limit; one of:
+ 27, 29, 32, 35. default: 29V
+ This property is supported only for PM8941.
+
+- qcom,num-strings
+   Usage:optional
+   Value type:   
+   Definition:   #; number of led strings attached;
+ value from 1 to 3. default: 2
+ This property is supported only for PM8941.
 
 Example:
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 

[PATCH V4 1/8] backlight: qcom-wled: Rename pm8941-wled.c to qcom-wled.c

2018-07-10 Thread Kiran Gunda
pm8941-wled.c driver is supporting the WLED peripheral
on pm8941. Rename it to qcom-wled.c so that it can support
WLED on multiple PMICs.

Signed-off-by: Kiran Gunda 
Reviewed-by: Bjorn Andersson 
Acked-by: Rob Herring 
Acked-by: Daniel Thompson 
---
changes from V3:
Added Reviewed-by and Acked-by tags.

 .../bindings/leds/backlight/{pm8941-wled.txt => qcom-wled.txt}| 2 +-
 drivers/video/backlight/Kconfig   | 8 
 drivers/video/backlight/Makefile  | 2 +-
 drivers/video/backlight/{pm8941-wled.c => qcom-wled.c}| 0
 4 files changed, 6 insertions(+), 6 deletions(-)
 rename Documentation/devicetree/bindings/leds/backlight/{pm8941-wled.txt => 
qcom-wled.txt} (95%)
 rename drivers/video/backlight/{pm8941-wled.c => qcom-wled.c} (100%)

diff --git a/Documentation/devicetree/bindings/leds/backlight/pm8941-wled.txt 
b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
similarity index 95%
rename from Documentation/devicetree/bindings/leds/backlight/pm8941-wled.txt
rename to Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
index e5b294d..fb39e32 100644
--- a/Documentation/devicetree/bindings/leds/backlight/pm8941-wled.txt
+++ b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
@@ -1,4 +1,4 @@
-Binding for Qualcomm PM8941 WLED driver
+Binding for Qualcomm Technologies, Inc. WLED driver
 
 Required properties:
 - compatible: should be "qcom,pm8941-wled"
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 2919e23..2c29180 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -306,12 +306,12 @@ config BACKLIGHT_TOSA
  If you have an Sharp SL-6000 Zaurus say Y to enable a driver
  for its backlight
 
-config BACKLIGHT_PM8941_WLED
-   tristate "Qualcomm PM8941 WLED Driver"
+config BACKLIGHT_QCOM_WLED
+   tristate "Qualcomm PMIC WLED Driver"
select REGMAP
help
- If you have the Qualcomm PM8941, say Y to enable a driver for the
- WLED block.
+ If you have the Qualcomm PMIC, say Y to enable a driver for the
+ WLED block. Currently it supports PM8941 and PMI8998.
 
 config BACKLIGHT_SAHARA
tristate "Tabletkiosk Sahara Touch-iT Backlight Driver"
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 0dcc2c7..741ab36 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -50,8 +50,8 @@ obj-$(CONFIG_BACKLIGHT_OMAP1) += omap1_bl.o
 obj-$(CONFIG_BACKLIGHT_OT200)  += ot200_bl.o
 obj-$(CONFIG_BACKLIGHT_PANDORA)+= pandora_bl.o
 obj-$(CONFIG_BACKLIGHT_PCF50633)   += pcf50633-backlight.o
-obj-$(CONFIG_BACKLIGHT_PM8941_WLED)+= pm8941-wled.o
 obj-$(CONFIG_BACKLIGHT_PWM)+= pwm_bl.o
+obj-$(CONFIG_BACKLIGHT_QCOM_WLED)  += qcom-wled.o
 obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o
 obj-$(CONFIG_BACKLIGHT_SKY81452)   += sky81452-backlight.o
 obj-$(CONFIG_BACKLIGHT_TOSA)   += tosa_bl.o
diff --git a/drivers/video/backlight/pm8941-wled.c 
b/drivers/video/backlight/qcom-wled.c
similarity index 100%
rename from drivers/video/backlight/pm8941-wled.c
rename to drivers/video/backlight/qcom-wled.c
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH V4 3/8] backlight: qcom-wled: Add new properties for PMI8998

2018-07-10 Thread Kiran Gunda
Update the bindings with the new properties used for
PMI8998.

Signed-off-by: Kiran Gunda 
---
Changes from V3:
- Removed the default values.
- Removed pmi8998 example.

 .../bindings/leds/backlight/qcom-wled.txt  | 76 ++
 1 file changed, 62 insertions(+), 14 deletions(-)

diff --git a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt 
b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
index 14f28f2..3f22ced 100644
--- a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
+++ b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
@@ -20,8 +20,7 @@ platforms. The PMIC is connected to the host processor via 
SPMI bus.
 - default-brightness
Usage:optional
Value type:   
-   Definition:   brightness value on boot, value from: 0-4095
- Default: 2048
+   Definition:   brightness value on boot, value from: 0-4095.
 
 - label
Usage:required
@@ -48,20 +47,24 @@ platforms. The PMIC is connected to the host processor via 
SPMI bus.
 - qcom,current-limit
Usage:optional
Value type:   
-   Definition:   mA; per-string current limit
- value: For pm8941: from 0 to 25 with 5 mA step
-Default 20 mA.
-For pmi8998: from 0 to 30 with 5 mA step
-Default 25 mA.
+   Definition:   mA; per-string current limit; value from 0 to 25 with
+ 1 mA step.
+ This property is supported only for pm8941.
+
+- qcom,current-limit-microamp
+   Usage:optional
+   Value type:   
+   Definition:   uA; per-string current limit; value from 0 to 3 with
+ 2500 uA step.
 
 - qcom,current-boost-limit
Usage:optional
Value type:   
Definition:   mA; boost current limit.
  For pm8941: one of: 105, 385, 525, 805, 980, 1260, 1400,
- 1680. Default: 805 mA
+ 1680.
  For pmi8998: one of: 105, 280, 450, 620, 970, 1150, 1300,
- 1500. Default: 970 mA
+ 1500.
 
 - qcom,switching-freq
Usage:optional
@@ -69,22 +72,66 @@ platforms. The PMIC is connected to the host processor via 
SPMI bus.
 Definition:   kHz; switching frequency; one of: 600, 640, 685, 738,
   800, 872, 960, 1066, 1200, 1371, 1600, 1920, 2400, 3200,
   4800, 9600.
-  Default: for pm8941: 1600 kHz
-   for pmi8998: 800 kHz
 
 - qcom,ovp
Usage:optional
Value type:   
Definition:   V; Over-voltage protection limit; one of:
- 27, 29, 32, 35. default: 29V
+ 27, 29, 32, 35.
  This property is supported only for PM8941.
 
+- qcom,ovp-millivolt
+   Usage:optional
+   Value type:   
+   Definition:   mV; Over-voltage protection limit;
+ For pmi8998: one of 18100, 19600, 29600, 31100
+ If this property is not specified for PM8941, it
+ falls back to "qcom,ovp" property.
+
 - qcom,num-strings
Usage:optional
Value type:   
Definition:   #; number of led strings attached;
- value from 1 to 3. default: 2
- This property is supported only for PM8941.
+ value: For PM8941 from 1 to 3.
+For PMI8998 from 1 to 4.
+
+- interrupts
+   Usage:optional
+   Value type:   
+   Definition:   Interrupts associated with WLED. This should be
+ "short" and "ovp" interrupts. Interrupts can be
+ specified as per the encoding listed under
+ Documentation/devicetree/bindings/spmi/
+ qcom,spmi-pmic-arb.txt.
+
+- interrupt-names
+   Usage:optional
+   Value type:   
+   Definition:   Interrupt names associated with the interrupts.
+ Must be "short" and "ovp". The short circuit detection
+ is not supported for PM8941.
+
+- qcom,enabled-strings
+   Usage:optional
+   Value tyoe:   
+   Definition:   Array of the WLED strings numbered from 0 to 3. Each
+ string of leds are operated individually. Specify the
+ list of strings used by the device. Any combination of
+ led strings can be used.
+
+- qcom,external-pfet
+   Usage:optional
+   Value type:   
+   Definition:   Specify if external PFET control for short circuit
+ protection is used. This property is supported only
+ for PMI8

[PATCH V4 0/8] backlight: qcom-wled: Support for QCOM wled driver

2018-07-10 Thread Kiran Gunda
This patch series renames the pm8941-wled.c driver to qcom-wled.c to add
the support for multiple PMICs supported by qualcomm. This patch series
supports both PM8941 and PMI8998 WLED. The PMI8998 WLED has the support
to handle the OVP (over voltage protection) and the SC (short circuit 
protection)
interrupts. It also has the auto string detection algorithm support to
configure the right strings if the user specified string configuration
is in-correct. These three features are added in this series for PMI8998.

changes from v1:
   - Fixed the commit message for
   - backlight: qcom-wled: Rename pm8941-wled.c to qcom-wled.c

Changes from v2:
   - Fixed bjorn and other reviewer's comments
   - Seperated the device tree bindings
   - Splitted out the WLED4 changes in seperate patch
   - Merged OVP and auto string detection patch

Changes from v3:
  - Added Reviewed-by/Acked-by tags
  - Fixed comments from Bjorn/Vinod/Rob
  - Splitting the "backlight: qcom-wled: Add support for WLED4 peripheral" patch
to seperate the WLED3 specific restructure.

Kiran Gunda (8):
  backlight: qcom-wled: Rename pm8941-wled.c to qcom-wled.c
  backlight: qcom-wled: restructure the qcom-wled bindings
  backlight: qcom-wled: Add new properties for PMI8998
  backlight: qcom-wled: Rename PM8941* to WLED3
  backlight: qcom-wled: Restructure the driver for WLED3
  backlight: qcom-wled: Add support for WLED4 peripheral
  backlight: qcom-wled: add support for short circuit handling
  backlight: qcom-wled: Add auto string detection logic

 .../bindings/leds/backlight/pm8941-wled.txt|   42 -
 .../bindings/leds/backlight/qcom-wled.txt  |  150 +++
 drivers/video/backlight/Kconfig|8 +-
 drivers/video/backlight/Makefile   |2 +-
 drivers/video/backlight/pm8941-wled.c  |  432 ---
 drivers/video/backlight/qcom-wled.c| 1298 
 6 files changed, 1453 insertions(+), 479 deletions(-)
 delete mode 100644 
Documentation/devicetree/bindings/leds/backlight/pm8941-wled.txt
 create mode 100644 
Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
 delete mode 100644 drivers/video/backlight/pm8941-wled.c
 create mode 100644 drivers/video/backlight/qcom-wled.c

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
 a Linux Foundation Collaborative Project

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH V4 4/8] backlight: qcom-wled: Rename PM8941* to WLED3

2018-07-10 Thread Kiran Gunda
Rename the PM8941* references as WLED3 to make the
driver generic and have WLED support for other PMICs.

Signed-off-by: Kiran Gunda 
---
Changes from V3:
- Changed the MODULE_DESCRIPTION

 drivers/video/backlight/qcom-wled.c | 248 ++--
 1 file changed, 125 insertions(+), 123 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 0b6d219..3cd6e75 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -18,77 +18,79 @@
 #include 
 
 /* From DT binding */
-#define PM8941_WLED_DEFAULT_BRIGHTNESS 2048
+#define WLED_DEFAULT_BRIGHTNESS2048
 
-#define PM8941_WLED_REG_VAL_BASE   0x40
-#define  PM8941_WLED_REG_VAL_MAX   0xFFF
+#define WLED3_SINK_REG_BRIGHT_MAX  0xFFF
+#define WLED3_CTRL_REG_VAL_BASE0x40
 
-#define PM8941_WLED_REG_MOD_EN 0x46
-#define  PM8941_WLED_REG_MOD_EN_BITBIT(7)
-#define  PM8941_WLED_REG_MOD_EN_MASK   BIT(7)
+/* WLED3 control registers */
+#define WLED3_CTRL_REG_MOD_EN  0x46
+#define  WLED3_CTRL_REG_MOD_EN_BIT BIT(7)
+#define  WLED3_CTRL_REG_MOD_EN_MASKBIT(7)
 
-#define PM8941_WLED_REG_SYNC   0x47
-#define  PM8941_WLED_REG_SYNC_MASK 0x07
-#define  PM8941_WLED_REG_SYNC_LED1 BIT(0)
-#define  PM8941_WLED_REG_SYNC_LED2 BIT(1)
-#define  PM8941_WLED_REG_SYNC_LED3 BIT(2)
-#define  PM8941_WLED_REG_SYNC_ALL  0x07
-#define  PM8941_WLED_REG_SYNC_CLEAR0x00
+#define WLED3_CTRL_REG_FREQ0x4c
+#define  WLED3_CTRL_REG_FREQ_MASK  0x0f
 
-#define PM8941_WLED_REG_FREQ   0x4c
-#define  PM8941_WLED_REG_FREQ_MASK 0x0f
+#define WLED3_CTRL_REG_OVP 0x4d
+#define  WLED3_CTRL_REG_OVP_MASK   0x03
 
-#define PM8941_WLED_REG_OVP0x4d
-#define  PM8941_WLED_REG_OVP_MASK  0x03
+#define WLED3_CTRL_REG_ILIMIT  0x4e
+#define  WLED3_CTRL_REG_ILIMIT_MASK0x07
 
-#define PM8941_WLED_REG_BOOST  0x4e
-#define  PM8941_WLED_REG_BOOST_MASK0x07
+/* WLED3 sink registers */
+#define WLED3_SINK_REG_SYNC0x47
+#define  WLED3_SINK_REG_SYNC_MASK  0x07
+#define  WLED3_SINK_REG_SYNC_LED1  BIT(0)
+#define  WLED3_SINK_REG_SYNC_LED2  BIT(1)
+#define  WLED3_SINK_REG_SYNC_LED3  BIT(2)
+#define  WLED3_SINK_REG_SYNC_ALL   0x07
+#define  WLED3_SINK_REG_SYNC_CLEAR 0x00
 
-#define PM8941_WLED_REG_SINK   0x4f
-#define  PM8941_WLED_REG_SINK_MASK 0xe0
-#define  PM8941_WLED_REG_SINK_SHFT 0x05
+#define WLED3_SINK_REG_CURR_SINK   0x4f
+#define  WLED3_SINK_REG_CURR_SINK_MASK 0xe0
+#define  WLED3_SINK_REG_CURR_SINK_SHFT 0x05
 
-/* Per-'string' registers below */
-#define PM8941_WLED_REG_STR_OFFSET 0x10
+/* WLED3 per-'string' registers below */
+#define WLED3_SINK_REG_STR_OFFSET  0x10
 
-#define PM8941_WLED_REG_STR_MOD_EN_BASE0x60
-#define  PM8941_WLED_REG_STR_MOD_MASK  BIT(7)
-#define  PM8941_WLED_REG_STR_MOD_ENBIT(7)
+#define WLED3_SINK_REG_STR_MOD_EN_BASE 0x60
+#define  WLED3_SINK_REG_STR_MOD_MASK   BIT(7)
+#define  WLED3_SINK_REG_STR_MOD_EN BIT(7)
 
-#define PM8941_WLED_REG_STR_SCALE_BASE 0x62
-#define  PM8941_WLED_REG_STR_SCALE_MASK0x1f
+#define WLED3_SINK_REG_STR_FULL_SCALE_CURR 0x62
+#define  WLED3_SINK_REG_STR_FULL_SCALE_CURR_MASK   0x1f
 
-#define PM8941_WLED_REG_STR_MOD_SRC_BASE   0x63
-#define  PM8941_WLED_REG_STR_MOD_SRC_MASK  0x01
-#define  PM8941_WLED_REG_STR_MOD_SRC_INT   0x00
-#define  PM8941_WLED_REG_STR_MOD_SRC_EXT   0x01
+#define WLED3_SINK_REG_STR_MOD_SRC_BASE0x63
+#define  WLED3_SINK_REG_STR_MOD_SRC_MASK   0x01
+#define  WLED3_SINK_REG_STR_MOD_SRC_INT0x00
+#define  WLED3_SINK_REG_STR_MOD_SRC_EXT0x01
 
-#define PM8941_WLED_REG_STR_CABC_BASE  0x66
-#define  PM8941_WLED_REG_STR_CABC_MASK BIT(7)
-#define  PM8941_WLED_REG_STR_CABC_EN   BIT(7)
+#define WLED3_SINK_REG_STR_CABC_BASE   0x66
+#define  WLED3_SINK_REG_STR_CABC_MASK  BIT(7)
+#define  WLED3_SINK_REG_STR_CABC_ENBIT(7)
 
-struct pm8941_wled_config {
-   u32 i_boost_limit;
+struct wled_config {
+   u32 boost_i_limit;
u32 ovp;
u32 switch_freq

[PATCH V4 5/8] backlight: qcom-wled: Restructure the driver for WLED3

2018-07-10 Thread Kiran Gunda
Restructure the driver to add the support for new WLED
peripherals.

Signed-off-by: Kiran Gunda 
---
Changes from V3:
- This is the new patch after splitting the 
  "backlight: qcom-wled: Add support for WLED4 peripheral" patch
  to seperate the WLED3 specific restructure.

 drivers/video/backlight/qcom-wled.c | 396 ++--
 1 file changed, 246 insertions(+), 150 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 3cd6e75..87fc1d0 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -15,59 +15,71 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 /* From DT binding */
+#define WLED_MAX_STRINGS   4
+
 #define WLED_DEFAULT_BRIGHTNESS2048
 
-#define WLED3_SINK_REG_BRIGHT_MAX  0xFFF
-#define WLED3_CTRL_REG_VAL_BASE0x40
+#define WLED_SINK_REG_BRIGHT_MAX   0xFFF
 
-/* WLED3 control registers */
-#define WLED3_CTRL_REG_MOD_EN  0x46
-#define  WLED3_CTRL_REG_MOD_EN_BIT BIT(7)
-#define  WLED3_CTRL_REG_MOD_EN_MASKBIT(7)
+/* WLED control registers */
+#define WLED_CTRL_REG_MOD_EN   0x46
+#define  WLED_CTRL_REG_MOD_EN_MASK BIT(7)
+#define  WLED_CTRL_REG_MOD_EN_SHIFT7
 
-#define WLED3_CTRL_REG_FREQ0x4c
-#define  WLED3_CTRL_REG_FREQ_MASK  0x0f
+#define WLED_CTRL_REG_FREQ 0x4c
+#define  WLED_CTRL_REG_FREQ_MASK   GENMASK(3, 0)
 
-#define WLED3_CTRL_REG_OVP 0x4d
-#define  WLED3_CTRL_REG_OVP_MASK   0x03
+#define WLED_CTRL_REG_OVP  0x4d
+#define  WLED_CTRL_REG_OVP_MASKGENMASK(1, 0)
 
-#define WLED3_CTRL_REG_ILIMIT  0x4e
-#define  WLED3_CTRL_REG_ILIMIT_MASK0x07
+#define WLED_CTRL_REG_ILIMIT   0x4e
+#define  WLED_CTRL_REG_ILIMIT_MASK GENMASK(2, 0)
 
-/* WLED3 sink registers */
-#define WLED3_SINK_REG_SYNC0x47
-#define  WLED3_SINK_REG_SYNC_MASK  0x07
-#define  WLED3_SINK_REG_SYNC_LED1  BIT(0)
-#define  WLED3_SINK_REG_SYNC_LED2  BIT(1)
-#define  WLED3_SINK_REG_SYNC_LED3  BIT(2)
-#define  WLED3_SINK_REG_SYNC_ALL   0x07
-#define  WLED3_SINK_REG_SYNC_CLEAR 0x00
+/* WLED sink registers */
+#define WLED_SINK_REG_SYNC 0x47
+#define  WLED_SINK_REG_SYNC_CLEAR  0x00
 
 #define WLED3_SINK_REG_CURR_SINK   0x4f
-#define  WLED3_SINK_REG_CURR_SINK_MASK 0xe0
-#define  WLED3_SINK_REG_CURR_SINK_SHFT 0x05
+#define  WLED3_SINK_REG_CURR_SINK_MASK GENMASK(7, 5)
+#define  WLED3_SINK_REG_CURR_SINK_SHFT 5
 
-/* WLED3 per-'string' registers below */
-#define WLED3_SINK_REG_STR_OFFSET  0x10
+/* WLED3 specific per-'string' registers below */
+#define WLED3_SINK_REG_BRIGHT(n)   (0x40 + n)
 
-#define WLED3_SINK_REG_STR_MOD_EN_BASE 0x60
+#define WLED3_SINK_REG_STR_MOD_EN(n)   (0x60 + (n * 0x10))
 #define  WLED3_SINK_REG_STR_MOD_MASK   BIT(7)
-#define  WLED3_SINK_REG_STR_MOD_EN BIT(7)
 
-#define WLED3_SINK_REG_STR_FULL_SCALE_CURR 0x62
-#define  WLED3_SINK_REG_STR_FULL_SCALE_CURR_MASK   0x1f
+#define WLED3_SINK_REG_STR_FULL_SCALE_CURR(n)  (0x62 + (n * 0x10))
+#define  WLED3_SINK_REG_STR_FULL_SCALE_CURR_MASK   GENMASK(4, 0)
 
-#define WLED3_SINK_REG_STR_MOD_SRC_BASE0x63
-#define  WLED3_SINK_REG_STR_MOD_SRC_MASK   0x01
+#define WLED3_SINK_REG_STR_MOD_SRC(n)  (0x63 + (n * 0x10))
+#define  WLED3_SINK_REG_STR_MOD_SRC_MASK   BIT(0)
 #define  WLED3_SINK_REG_STR_MOD_SRC_INT0x00
 #define  WLED3_SINK_REG_STR_MOD_SRC_EXT0x01
 
-#define WLED3_SINK_REG_STR_CABC_BASE   0x66
+#define WLED3_SINK_REG_STR_CABC(n) (0x66 + (n * 0x10))
 #define  WLED3_SINK_REG_STR_CABC_MASK  BIT(7)
-#define  WLED3_SINK_REG_STR_CABC_ENBIT(7)
+
+struct wled_var_cfg {
+   const u32 *values;
+   u32 (*fn)(u32);
+   int size;
+};
+
+struct wled_u32_opts {
+   const char *name;
+   u32 *val_ptr;
+   const struct wled_var_cfg *cfg;
+};
+
+struct wled_bool_opts {
+   const char *name;
+   bool *val_ptr;
+};
 
 struct wled_config {
u32 boost_i_limit;

  1   2   >