2022-05-09 03:37:37

by Marijn Suijten

[permalink] [raw]
Subject: [PATCH 1/4] dt-bindings: leds: qcom-lpg: Add compatible for PM660L LPG block

Document the availability of an LPG configuration for the PM660L PMIC in
the Qualcomm Light Pulse Generator driver.

Signed-off-by: Marijn Suijten <[email protected]>
Acked-by: Rob Herring <[email protected]>
---
Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml | 1 +
1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml b/Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml
index 409a4c7298e1..cd02811583ec 100644
--- a/Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml
+++ b/Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml
@@ -17,6 +17,7 @@ description: >
properties:
compatible:
enum:
+ - qcom,pm660l-lpg
- qcom,pm8150b-lpg
- qcom,pm8150l-lpg
- qcom,pm8350c-pwm
--
2.36.0



2022-05-09 05:08:04

by Marijn Suijten

[permalink] [raw]
Subject: [PATCH 4/4] arm64: dts: qcom: sdm630-nile: Add RGB status LED on the PM660L LPG

The entire Sony Nile and Ganges lineup utilize the first three channels
(the triled channels) of the LPG block for an RGB (battery) status and
notification indicator.

Signed-off-by: Marijn Suijten <[email protected]>
---
.../dts/qcom/sdm630-sony-xperia-nile.dtsi | 33 +++++++++++++++++++
1 file changed, 33 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sdm630-sony-xperia-nile.dtsi b/arch/arm64/boot/dts/qcom/sdm630-sony-xperia-nile.dtsi
index 42af1fade461..f42304671520 100644
--- a/arch/arm64/boot/dts/qcom/sdm630-sony-xperia-nile.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm630-sony-xperia-nile.dtsi
@@ -10,6 +10,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/input/gpio-keys.h>
+#include <dt-bindings/leds/common.h>

/ {
/* required for bootloader to select correct board */
@@ -214,6 +215,38 @@ &blsp2_uart1 {
/* HCI Bluetooth */
};

+&pm660l_lpg {
+ status = "okay";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,power-source = <1>;
+
+ multi-led {
+ color = <LED_COLOR_ID_RGB>;
+ function = LED_FUNCTION_STATUS;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_BLUE>;
+ };
+
+ led@2 {
+ reg = <2>;
+ color = <LED_COLOR_ID_GREEN>;
+ };
+
+ led@3 {
+ reg = <3>;
+ color = <LED_COLOR_ID_RED>;
+ };
+ };
+};
+
&pon_pwrkey {
status = "okay";
};
--
2.36.0


2022-05-09 05:34:16

by Marijn Suijten

[permalink] [raw]
Subject: [PATCH 2/4] leds: qcom-lpg: Add PM660L configuration and compatible

Inherit PM660L PMIC LPG/triled block configuration from downstream
drivers and DT sources, consisting of a triled block with automatic
trickle charge control and source selection, three colored led channels
belonging to the synchronized triled block and one loose PWM channel.

Signed-off-by: Marijn Suijten <[email protected]>
---
drivers/leds/rgb/leds-qcom-lpg.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)

diff --git a/drivers/leds/rgb/leds-qcom-lpg.c b/drivers/leds/rgb/leds-qcom-lpg.c
index cfa3362b2457..30c12ac8eed4 100644
--- a/drivers/leds/rgb/leds-qcom-lpg.c
+++ b/drivers/leds/rgb/leds-qcom-lpg.c
@@ -1271,6 +1271,23 @@ static int lpg_remove(struct platform_device *pdev)
return 0;
}

+static const struct lpg_data pm660l_lpg_data = {
+ .lut_base = 0xb000,
+ .lut_size = 0x100,
+
+ .triled_base = 0xd000,
+ .triled_has_atc_ctl = true,
+ .triled_has_src_sel = true,
+
+ .num_channels = 4,
+ .channels = (struct lpg_channel_data[]) {
+ { .base = 0xb100, .triled_mask = BIT(5) },
+ { .base = 0xb200, .triled_mask = BIT(6) },
+ { .base = 0xb300, .triled_mask = BIT(7) },
+ { .base = 0xb400 },
+ },
+};
+
static const struct lpg_data pm8916_pwm_data = {
.num_channels = 1,
.channels = (const struct lpg_channel_data[]) {
@@ -1391,6 +1408,7 @@ static const struct lpg_data pm8350c_pwm_data = {
};

static const struct of_device_id lpg_of_table[] = {
+ { .compatible = "qcom,pm660l-lpg", .data = &pm660l_lpg_data },
{ .compatible = "qcom,pm8150b-lpg", .data = &pm8150b_lpg_data },
{ .compatible = "qcom,pm8150l-lpg", .data = &pm8150l_lpg_data },
{ .compatible = "qcom,pm8350c-pwm", .data = &pm8350c_pwm_data },
--
2.36.0


2022-05-09 08:54:06

by Marijn Suijten

[permalink] [raw]
Subject: [PATCH 3/4] arm64: dts: qcom: pm660l: Add LPG node

The Light Pulse Generator describes a hardware block responsible for
displaying colors and patterns on an RGB LED (usually used for [battery]
status and notifications), and drive PWM signals for general-purpose
(ie. backlight) LEDs. The availability and usage of the individual
channels differ per board and is hence left for individual platform DTs
to configure.

Signed-off-by: Marijn Suijten <[email protected]>
---
arch/arm64/boot/dts/qcom/pm660l.dtsi | 9 +++++++++
1 file changed, 9 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/pm660l.dtsi b/arch/arm64/boot/dts/qcom/pm660l.dtsi
index cfef42353611..636b8d398d96 100644
--- a/arch/arm64/boot/dts/qcom/pm660l.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm660l.dtsi
@@ -65,6 +65,15 @@ pmic@3 {
#address-cells = <1>;
#size-cells = <0>;

+ pm660l_lpg: lpg@b100 {
+ compatible = "qcom,pm660l-lpg";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+ };
+
pm660l_wled: leds@d800 {
compatible = "qcom,pm660l-wled";
reg = <0xd800 0xd900>;
--
2.36.0


2022-05-11 06:46:26

by Bjorn Andersson

[permalink] [raw]
Subject: Re: [PATCH 2/4] leds: qcom-lpg: Add PM660L configuration and compatible

On Sat 07 May 17:11 CDT 2022, Marijn Suijten wrote:

> Inherit PM660L PMIC LPG/triled block configuration from downstream
> drivers and DT sources, consisting of a triled block with automatic
> trickle charge control and source selection, three colored led channels
> belonging to the synchronized triled block and one loose PWM channel.
>
> Signed-off-by: Marijn Suijten <[email protected]>
> ---
> drivers/leds/rgb/leds-qcom-lpg.c | 18 ++++++++++++++++++
> 1 file changed, 18 insertions(+)
>
> diff --git a/drivers/leds/rgb/leds-qcom-lpg.c b/drivers/leds/rgb/leds-qcom-lpg.c
> index cfa3362b2457..30c12ac8eed4 100644
> --- a/drivers/leds/rgb/leds-qcom-lpg.c
> +++ b/drivers/leds/rgb/leds-qcom-lpg.c
> @@ -1271,6 +1271,23 @@ static int lpg_remove(struct platform_device *pdev)
> return 0;
> }
>
> +static const struct lpg_data pm660l_lpg_data = {
> + .lut_base = 0xb000,
> + .lut_size = 0x100,

The documentation tells me that you have 49 entries of LUT on the
PM660L.

> +
> + .triled_base = 0xd000,
> + .triled_has_atc_ctl = true,
> + .triled_has_src_sel = true,
> +
> + .num_channels = 4,
> + .channels = (struct lpg_channel_data[]) {

This can be const

Regards,
Bjorn

> + { .base = 0xb100, .triled_mask = BIT(5) },
> + { .base = 0xb200, .triled_mask = BIT(6) },
> + { .base = 0xb300, .triled_mask = BIT(7) },
> + { .base = 0xb400 },
> + },
> +};
> +
> static const struct lpg_data pm8916_pwm_data = {
> .num_channels = 1,
> .channels = (const struct lpg_channel_data[]) {
> @@ -1391,6 +1408,7 @@ static const struct lpg_data pm8350c_pwm_data = {
> };
>
> static const struct of_device_id lpg_of_table[] = {
> + { .compatible = "qcom,pm660l-lpg", .data = &pm660l_lpg_data },
> { .compatible = "qcom,pm8150b-lpg", .data = &pm8150b_lpg_data },
> { .compatible = "qcom,pm8150l-lpg", .data = &pm8150l_lpg_data },
> { .compatible = "qcom,pm8350c-pwm", .data = &pm8350c_pwm_data },
> --
> 2.36.0
>

2022-05-11 09:54:56

by Marijn Suijten

[permalink] [raw]
Subject: Re: [PATCH 2/4] leds: qcom-lpg: Add PM660L configuration and compatible

On 2022-05-10 22:54:07, Bjorn Andersson wrote:
> On Sat 07 May 17:11 CDT 2022, Marijn Suijten wrote:
>
> > Inherit PM660L PMIC LPG/triled block configuration from downstream
> > drivers and DT sources, consisting of a triled block with automatic
> > trickle charge control and source selection, three colored led channels
> > belonging to the synchronized triled block and one loose PWM channel.
> >
> > Signed-off-by: Marijn Suijten <[email protected]>
> > ---
> > drivers/leds/rgb/leds-qcom-lpg.c | 18 ++++++++++++++++++
> > 1 file changed, 18 insertions(+)
> >
> > diff --git a/drivers/leds/rgb/leds-qcom-lpg.c b/drivers/leds/rgb/leds-qcom-lpg.c
> > index cfa3362b2457..30c12ac8eed4 100644
> > --- a/drivers/leds/rgb/leds-qcom-lpg.c
> > +++ b/drivers/leds/rgb/leds-qcom-lpg.c
> > @@ -1271,6 +1271,23 @@ static int lpg_remove(struct platform_device *pdev)
> > return 0;
> > }
> >
> > +static const struct lpg_data pm660l_lpg_data = {
> > + .lut_base = 0xb000,
> > + .lut_size = 0x100,
>
> The documentation tells me that you have 49 entries of LUT on the
> PM660L.

Downstream DT sources report the full 0x100 range starting at 0xb000 is
used, before the first channel starts at 0xb100:

https://git.codelinaro.org/clo/la/kernel/msm-4.14/-/blob/LA.UM.8.2.1.r1-06200-sdm660.0/arch/arm64/boot/dts/qcom/pm660l.dtsi#L84-85

However, every LUT entry appears to be two bytes in size so this should
at least be halved.

The driver does seem to add another 0x42 on top of this base address:

https://git.codelinaro.org/clo/la/kernel/msm-4.14/-/blob/LA.UM.8.2.1.r1-06200-sdm660.0/drivers/pwm/pwm-qti-lpg.c#L104

(Your LPG driver adds 0x40 - I've seen both used in our downstream
driver) yet that leaves (0x100-0x42) / 2 = 95 spots.

This is still significantly higher than 49. Is part of this register
range used for something else, inaccesible for LUT-value readings or is
the counter hardware in the LPG limiting this?

The driver codes in a max length of 47:

https://git.codelinaro.org/clo/la/kernel/msm-4.14/-/blob/LA.UM.8.2.1.r1-06200-sdm660.0/drivers/pwm/pwm-qti-lpg.c#L108

If you're confident about this I'll bump it down to 49 or try validating
what happens if higher registers are used.

> > +
> > + .triled_base = 0xd000,
> > + .triled_has_atc_ctl = true,
> > + .triled_has_src_sel = true,
> > +
> > + .num_channels = 4,
> > + .channels = (struct lpg_channel_data[]) {
>
> This can be const

Thanks for spotting!

- Marijn

>
> Regards,
> Bjorn
>
> > + { .base = 0xb100, .triled_mask = BIT(5) },
> > + { .base = 0xb200, .triled_mask = BIT(6) },
> > + { .base = 0xb300, .triled_mask = BIT(7) },
> > + { .base = 0xb400 },
> > + },
> > +};
> > +
> > static const struct lpg_data pm8916_pwm_data = {
> > .num_channels = 1,
> > .channels = (const struct lpg_channel_data[]) {
> > @@ -1391,6 +1408,7 @@ static const struct lpg_data pm8350c_pwm_data = {
> > };
> >
> > static const struct of_device_id lpg_of_table[] = {
> > + { .compatible = "qcom,pm660l-lpg", .data = &pm660l_lpg_data },
> > { .compatible = "qcom,pm8150b-lpg", .data = &pm8150b_lpg_data },
> > { .compatible = "qcom,pm8150l-lpg", .data = &pm8150l_lpg_data },
> > { .compatible = "qcom,pm8350c-pwm", .data = &pm8350c_pwm_data },
> > --
> > 2.36.0
> >