Skip to contentSkip to conversation

drm: Add support for backlight control of eDP panel on ti-sn65dsi86 bridge

PATCH NAK Rajeev Nandan 6 participants 16 messages Apr 26, 2021 – May 25, 2021

Subsystems (5)
lore
Share & tools
lore
#0 lore raw

v3 cover drm: Add support for backlight control of eDP panel on ti-sn65dsi86 bridge

The backlight level of an eDP panel can be controlled through the AUX channel using DPCD registers of the panel.

The capability for the Source device to adjust backlight characteristics within the panel, using the Sink device DPCD registers is indicated by the TCON_BACKLIGHT_ADJUSTMENT_CAPABLE bit in the EDP_GENERAL_CAPABILITY_1 register (DPCD Address 701h, bit0). In this configuration, the eDP TCON receives the backlight level information from the host, through the AUX channel.

Anderson's patch series [1] exposed the DDC bus from ti-sn65dsi86 bridge, that gives an option to move the backlight control out of the bridge and to create a separate backlight driver.

Changes in v2:
- Created a new DisplayPort aux backlight driver and moved the code from drm_dp_aux_backlight.c (v1) to the new driver.
- Removed the changes done in ti-sn65dsi86 bridge. (Rob Herring)

Changes in v3:
- Add missing ';' to fix module compilation (kernel test bot)

[1] https://lore.kernel.org/dri-devel/[email protected]/

Rajeev Nandan (2):
dt-bindings: backlight: add DisplayPort aux backlight
backlight: Add DisplayPort aux backlight driver

 .../bindings/leds/backlight/dp-aux-backlight.yaml  |  49 +++++
 drivers/video/backlight/Kconfig                    |   7 +
 drivers/video/backlight/Makefile                   |   1 +
 drivers/video/backlight/dp_aux_backlight.c         | 245 +++++++++++++++++++++
 4 files changed, 302 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml
 create mode 100644 drivers/video/backlight/dp_aux_backlight.c
Signature · 6 lines
2.7.4

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
#1 lore raw

PATCH v3 1/2 dt-bindings: backlight: add DisplayPort aux backlight

Add bindings for DisplayPort aux backlight driver.

Changes in v2:
- New

---
 .../bindings/leds/backlight/dp-aux-backlight.yaml  | 49 ++++++++++++++++++++++
 1 file changed, 49 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml
Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml new file +49 -0
new file mode 100644
index 00000000..0fa8bf0
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/leds/backlight/dp-aux-backlight.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: DisplayPort aux backlight driver bindings
+
+maintainers:
+  - Rajeev Nandan <[email protected]>
+
+description:
+  Backlight driver to control the brightness over DisplayPort aux channel.
+
+allOf:
+  - $ref: common.yaml#
+
+properties:
+  compatible:
+    const: dp-aux-backlight
+
+  ddc-i2c-bus:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      A phandle to the system I2C controller connected to the DDC bus used
+      for the DisplayPort AUX channel.
+
+  enable-gpios:
+    maxItems: 1
+    description: GPIO specifier for backlight enable pin.
+
+  max-brightness: true
+
+required:
+  - compatible
+  - ddc-i2c-bus
+
+additionalProperties: false
+
+examples:
+  - |
+    backlight {
+        compatible = "dp-aux-backlight";
+        ddc-i2c-bus = <&sn65dsi86_bridge>;
+        enable-gpios = <&tlmm 12 GPIO_ACTIVE_HIGH>;
+        max-brightness = <2047>;
+    };
+
+...
Signature · 6 lines
2.7.4

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
maintainer
#2 lore raw

Re: [v3 1/2] dt-bindings: backlight: add DisplayPort aux backlight

Quoted 11 lines · Rajeev Nandan

Add bindings for DisplayPort aux backlight driver.

Changes in v2:
- New

---
 .../bindings/leds/backlight/dp-aux-backlight.yaml  | 49 ++++++++++++++++++++++
 1 file changed, 49 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check' on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Error: Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.example.dts:22.38-39 syntax error FATAL ERROR: Unable to parse input tree
make[1]: *** [scripts/Makefile.lib:377: Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.example.dt.yaml] Error 1 make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:1414: dt_binding_check] Error 2

See https://patchwork.ozlabs.org/patch/1470203

This check can fail if there are any dependencies. The base for a patch series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above error(s), then make sure 'yamllint' is installed and dt-schema is up to date:

pip3 install dtschema --upgrade

Please check and re-submit.

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel

maintainer
#3 lore raw

Re: [v3 1/2] dt-bindings: backlight: add DisplayPort aux backlight

In reply to Rajeev Nandan
Quoted 52 lines · Rajeev Nandan

Add bindings for DisplayPort aux backlight driver.

Changes in v2:
- New

---
 .../bindings/leds/backlight/dp-aux-backlight.yaml  | 49 ++++++++++++++++++++++
 1 file changed, 49 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml
Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml new file +35 -0
new file mode 100644
index 00000000..0fa8bf0
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/leds/backlight/dp-aux-backlight.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: DisplayPort aux backlight driver bindings
+
+maintainers:
+  - Rajeev Nandan <[email protected]>
+
+description:
+  Backlight driver to control the brightness over DisplayPort aux channel.
+
+allOf:
+  - $ref: common.yaml#
+
+properties:
+  compatible:
+    const: dp-aux-backlight
+
+  ddc-i2c-bus:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      A phandle to the system I2C controller connected to the DDC bus used
+      for the DisplayPort AUX channel.
+
+  enable-gpios:
+    maxItems: 1
+    description: GPIO specifier for backlight enable pin.
+
+  max-brightness: true
+
+required:
+  - compatible

Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml line 45

Quoted 10 lines
Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml new file +10 -0
+  - ddc-i2c-bus
+
+additionalProperties: false
+
+examples:
+  - |
+    backlight {
+        compatible = "dp-aux-backlight";
+        ddc-i2c-bus = <&sn65dsi86_bridge>;
+        enable-gpios = <&tlmm 12 GPIO_ACTIVE_HIGH>;

So the DDC bus is connected to a backlight and also a panel? This binding is not reflecting the h/w, but rather what you want for some driver.

There's only one thing here and that's an eDP panel which supports backlight control via DP aux channel. You can figure all that out from the panel's compatible and/or reading the EDID.

You might also be interested in this thread:

https://lore.kernel.org/lkml/[email protected]/

Rob

#4 lore raw

Re: [v3 1/2] dt-bindings: backlight: add DisplayPort aux backlight

Hi,

Quoted 69 lines · Rob Herring
Quoted 52 lines · Rajeev Nandan

Add bindings for DisplayPort aux backlight driver.

Changes in v2:
- New

---
 .../bindings/leds/backlight/dp-aux-backlight.yaml  | 49 ++++++++++++++++++++++
 1 file changed, 49 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml
Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml new file +35 -0
new file mode 100644
index 00000000..0fa8bf0
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/leds/backlight/dp-aux-backlight.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: DisplayPort aux backlight driver bindings
+
+maintainers:
+  - Rajeev Nandan <[email protected]>
+
+description:
+  Backlight driver to control the brightness over DisplayPort aux channel.
+
+allOf:
+  - $ref: common.yaml#
+
+properties:
+  compatible:
+    const: dp-aux-backlight
+
+  ddc-i2c-bus:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      A phandle to the system I2C controller connected to the DDC bus used
+      for the DisplayPort AUX channel.
+
+  enable-gpios:
+    maxItems: 1
+    description: GPIO specifier for backlight enable pin.
+
+  max-brightness: true
+
+required:
+  - compatible

Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml line 45

Quoted 10 lines
Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml new file +10 -0
+  - ddc-i2c-bus
+
+additionalProperties: false
+
+examples:
+  - |
+    backlight {
+        compatible = "dp-aux-backlight";
+        ddc-i2c-bus = <&sn65dsi86_bridge>;
+        enable-gpios = <&tlmm 12 GPIO_ACTIVE_HIGH>;

So the DDC bus is connected to a backlight and also a panel? This binding is not reflecting the h/w, but rather what you want for some driver.

Quoted 7 lines

There's only one thing here and that's an eDP panel which supports backlight control via DP aux channel. You can figure all that out from the panel's compatible and/or reading the EDID.

You might also be interested in this thread:

https://lore.kernel.org/lkml/[email protected]/

I think Rajeev needs to rework everything anyway as per:

https://lore.kernel.org/r/[email protected]

...but you're right that it makes sense not to model the backlight as a separate node in the device tree. The panel driver can handle setting up the backlight.

-Doug
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel

#5 lore raw

Re: [v3 1/2] dt-bindings: backlight: add DisplayPort aux backlight

Quoted 82 lines · Doug Anderson

Hi,

Quoted 69 lines · Rob Herring
Quoted 52 lines · Rajeev Nandan

Add bindings for DisplayPort aux backlight driver.

Changes in v2:
- New

---
 .../bindings/leds/backlight/dp-aux-backlight.yaml  | 49 ++++++++++++++++++++++
 1 file changed, 49 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml
Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml new file +35 -0
new file mode 100644
index 00000000..0fa8bf0
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/leds/backlight/dp-aux-backlight.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: DisplayPort aux backlight driver bindings
+
+maintainers:
+  - Rajeev Nandan <[email protected]>
+
+description:
+  Backlight driver to control the brightness over DisplayPort aux channel.
+
+allOf:
+  - $ref: common.yaml#
+
+properties:
+  compatible:
+    const: dp-aux-backlight
+
+  ddc-i2c-bus:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      A phandle to the system I2C controller connected to the DDC bus used
+      for the DisplayPort AUX channel.
+
+  enable-gpios:
+    maxItems: 1
+    description: GPIO specifier for backlight enable pin.
+
+  max-brightness: true
+
+required:
+  - compatible

Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml line 45

Quoted 10 lines
Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml new file +10 -0
+  - ddc-i2c-bus
+
+additionalProperties: false
+
+examples:
+  - |
+    backlight {
+        compatible = "dp-aux-backlight";
+        ddc-i2c-bus = <&sn65dsi86_bridge>;
+        enable-gpios = <&tlmm 12 GPIO_ACTIVE_HIGH>;

So the DDC bus is connected to a backlight and also a panel? This binding is not reflecting the h/w, but rather what you want for some driver.

Quoted 7 lines

There's only one thing here and that's an eDP panel which supports backlight control via DP aux channel. You can figure all that out from the panel's compatible and/or reading the EDID.

You might also be interested in this thread:

https://lore.kernel.org/lkml/[email protected]/

I think Rajeev needs to rework everything anyway as per:

Quoted 7 lines

https://lore.kernel.org/r/[email protected]

...but you're right that it makes sense not to model the backlight as a separate node in the device tree. The panel driver can handle setting up the backlight.

-Doug

It was not a good idea to create a separate backlight driver and use ddc-i2c-bus to get access to DP aux. I am working to move the code to the panel driver and to utilize the new DRM helper functions (drm_edp_backlight_*) Lyude has added [1].

To use these helper functions, the panel driver should have access to the "struct drm_dp_aux *". The simple-panel has a "ddc-i2c-bus" property to give the panel access to the DDC bus and is currently being used to get the EDID from the panel. Can I use the same ddc bus i2c_adapter to get the "struct drm_dp_aux *"?

As per the suggestion [2], I get the "struct drm_dp_aux *" from the i2c_adapter of ddc bus (maybe I didn't understand the suggestion correctly), and, it turned out, the way I have implemented is not the right way [3]. So, I am afraid to use the same method in the panel driver.

[1] https://lore.kernel.org/dri-devel/[email protected]/
[2] https://www.spinics.net/lists/dri-devel/msg295429.html
[3] https://lore.kernel.org/dri-devel/[email protected]/

Thanks,
Rajeev

#6 lore raw

Re: [v3 1/2] dt-bindings: backlight: add DisplayPort aux backlight

Hi,

Quoted 112 lines · On Fri, Apr 30, 2021 at 8:10 AM <[email protected]> wrote:
Quoted 82 lines · Doug Anderson

Hi,

Quoted 69 lines · Rob Herring
Quoted 52 lines · Rajeev Nandan

Add bindings for DisplayPort aux backlight driver.

Changes in v2:
- New

---
 .../bindings/leds/backlight/dp-aux-backlight.yaml  | 49 ++++++++++++++++++++++
 1 file changed, 49 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml
Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml new file +35 -0
new file mode 100644
index 00000000..0fa8bf0
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/leds/backlight/dp-aux-backlight.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: DisplayPort aux backlight driver bindings
+
+maintainers:
+  - Rajeev Nandan <[email protected]>
+
+description:
+  Backlight driver to control the brightness over DisplayPort aux channel.
+
+allOf:
+  - $ref: common.yaml#
+
+properties:
+  compatible:
+    const: dp-aux-backlight
+
+  ddc-i2c-bus:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      A phandle to the system I2C controller connected to the DDC bus used
+      for the DisplayPort AUX channel.
+
+  enable-gpios:
+    maxItems: 1
+    description: GPIO specifier for backlight enable pin.
+
+  max-brightness: true
+
+required:
+  - compatible

Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml line 45

Quoted 10 lines
Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml new file +10 -0
+  - ddc-i2c-bus
+
+additionalProperties: false
+
+examples:
+  - |
+    backlight {
+        compatible = "dp-aux-backlight";
+        ddc-i2c-bus = <&sn65dsi86_bridge>;
+        enable-gpios = <&tlmm 12 GPIO_ACTIVE_HIGH>;

So the DDC bus is connected to a backlight and also a panel? This binding is not reflecting the h/w, but rather what you want for some driver.

Quoted 7 lines

There's only one thing here and that's an eDP panel which supports backlight control via DP aux channel. You can figure all that out from the panel's compatible and/or reading the EDID.

You might also be interested in this thread:

https://lore.kernel.org/lkml/[email protected]/

I think Rajeev needs to rework everything anyway as per:

Quoted 7 lines

https://lore.kernel.org/r/[email protected]

...but you're right that it makes sense not to model the backlight as a separate node in the device tree. The panel driver can handle setting up the backlight.

-Doug

It was not a good idea to create a separate backlight driver and use ddc-i2c-bus to get access to DP aux. I am working to move the code to the panel driver and to utilize the new DRM helper functions (drm_edp_backlight_*) Lyude has added [1].

To use these helper functions, the panel driver should have access to the
"struct drm_dp_aux *". The simple-panel has a "ddc-i2c-bus" property to give the panel access to the DDC bus and is currently being used to get the EDID from the panel. Can I use the same ddc bus i2c_adapter to get
the "struct drm_dp_aux *"?

As per the suggestion [2], I get the "struct drm_dp_aux *" from the i2c_adapter of ddc bus (maybe I didn't understand the suggestion correctly),
and, it turned out, the way I have implemented is not the right way [3]. So, I am afraid to use the same method in the panel driver.

Quoted 4 lines

[1] https://lore.kernel.org/dri-devel/[email protected]/
[2] https://www.spinics.net/lists/dri-devel/msg295429.html
[3]
https://lore.kernel.org/dri-devel/[email protected]/

So it's definitely up to maintainers, not me. ...but I guess I would have expected something like a new property called "ddc-aux-bus". Then you'd have to create a new API call called something like "of_find_ddc_aux_adapter_by_node()" that would allow you to find it.

I guess an alternate way to solve this (I'm not totally sure whether it's better or worse) would be to add a function that would walk up the chain of parent bridges and ask them for a pointer to the aux bus. I definitely haven't thought it all the way through, but I'd imagine something like drm_bridge_chain_get_ddc_aux(). This is _probably_ better than adding the "ddc-aux-bus" property but it assumes that the aux bus is provided by one of our parents. Hrm, looking at this briefly, though, I'm not sure how to do it. It doesn't seem possible to get the parent bridges from the panel structure. Even if you assume that your parent is wrapping you with a panel_bridge it still doesn't seem possible?

This probably needs more drm-expertise.

-Doug
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel

#7 lore raw

Re: [v3 1/2] dt-bindings: backlight: add DisplayPort aux backlight

Quoted 120 lines · Doug Anderson

Hi,

Quoted 112 lines · On Fri, Apr 30, 2021 at 8:10 AM <[email protected]> wrote:
Quoted 82 lines · Doug Anderson

Hi,

Quoted 69 lines · Rob Herring
Quoted 52 lines · Rajeev Nandan

Add bindings for DisplayPort aux backlight driver.

Changes in v2:
- New

---
 .../bindings/leds/backlight/dp-aux-backlight.yaml  | 49 ++++++++++++++++++++++
 1 file changed, 49 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml
Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml new file +35 -0
new file mode 100644
index 00000000..0fa8bf0
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/leds/backlight/dp-aux-backlight.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: DisplayPort aux backlight driver bindings
+
+maintainers:
+  - Rajeev Nandan <[email protected]>
+
+description:
+  Backlight driver to control the brightness over DisplayPort aux channel.
+
+allOf:
+  - $ref: common.yaml#
+
+properties:
+  compatible:
+    const: dp-aux-backlight
+
+  ddc-i2c-bus:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      A phandle to the system I2C controller connected to the DDC bus used
+      for the DisplayPort AUX channel.
+
+  enable-gpios:
+    maxItems: 1
+    description: GPIO specifier for backlight enable pin.
+
+  max-brightness: true
+
+required:
+  - compatible

Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml line 45

Quoted 10 lines
Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml new file +10 -0
+  - ddc-i2c-bus
+
+additionalProperties: false
+
+examples:
+  - |
+    backlight {
+        compatible = "dp-aux-backlight";
+        ddc-i2c-bus = <&sn65dsi86_bridge>;
+        enable-gpios = <&tlmm 12 GPIO_ACTIVE_HIGH>;

So the DDC bus is connected to a backlight and also a panel? This binding is not reflecting the h/w, but rather what you want for some driver.

Quoted 7 lines

There's only one thing here and that's an eDP panel which supports backlight control via DP aux channel. You can figure all that out from the panel's compatible and/or reading the EDID.

You might also be interested in this thread:

https://lore.kernel.org/lkml/[email protected]/

I think Rajeev needs to rework everything anyway as per:

Quoted 7 lines

https://lore.kernel.org/r/[email protected]

...but you're right that it makes sense not to model the backlight as a separate node in the device tree. The panel driver can handle setting up the backlight.

-Doug

It was not a good idea to create a separate backlight driver and use ddc-i2c-bus to get access to DP aux. I am working to move the code to the panel driver and to utilize the new DRM helper functions (drm_edp_backlight_*) Lyude has added [1].

To use these helper functions, the panel driver should have access to the
"struct drm_dp_aux *". The simple-panel has a "ddc-i2c-bus" property to give the panel access to the DDC bus and is currently being used to get the EDID from the panel. Can I use the same ddc bus i2c_adapter to get
the "struct drm_dp_aux *"?

As per the suggestion [2], I get the "struct drm_dp_aux *" from the i2c_adapter of ddc bus (maybe I didn't understand the suggestion correctly),
and, it turned out, the way I have implemented is not the right way [3]. So, I am afraid to use the same method in the panel driver.

Quoted 4 lines

[1] https://lore.kernel.org/dri-devel/[email protected]/
[2] https://www.spinics.net/lists/dri-devel/msg295429.html
[3]
https://lore.kernel.org/dri-devel/[email protected]/

Quoted 5 lines

So it's definitely up to maintainers, not me. ...but I guess I would have expected something like a new property called "ddc-aux-bus". Then you'd have to create a new API call called something like "of_find_ddc_aux_adapter_by_node()" that would allow you to find it.

To implement the first suggestion, I can think of the following way to get the "struct drm_dp_aux" in the panel_simple_probe function:

- Create a new panel-simple DT property "ddc-aux-bus", a phandle to the platform device that implements the AUX channel.

- Create a global list of drm_dp_aux in drm_dp_helper.c. Initialize list head in drm_dp_aux_init(), add the drm_dp_aux onto the list in drm_dp_aux_register(). Similarly, remove the drm_dp_aux from list in drm_dp_aux_unregister().

- Create a new function of_drm_find_dp_aux_by_node() to get the expected drm_dp_aux from this global list.

Please let me know your views on this implementation.

Below is the summary of the changes in drm dp helper:

---

// drm_dp_helper.h

struct drm_dp_aux {
	...
	struct list_head list;
	...
}

// drm_dp_helper.c

static DEFINE_MUTEX(dp_aux_lock);
static LIST_HEAD(dp_aux_list);

static void drm_dp_aux_add(struct drm_dp_aux *aux)

{
    mutex_lock(&dp_aux_lock);
    list_add_tail(&aux->list, &dp_aux_list);
    mutex_unlock(&dp_aux_lock);
}

static void drm_dp_aux_remove(struct drm_dp_aux *aux)

{
    mutex_lock(&dp_aux_lock);
    list_del_init(&aux->list);
    mutex_unlock(&dp_aux_lock);
}

#ifdef CONFIG_OF
struct drm_dp_aux *of_drm_find_dp_aux_by_node(struct device_node *np)

{
    struct drm_dp_aux *aux;
    mutex_lock(&dp_aux_lock);

    list_for_each_entry(aux, &dp_aux_list, list) {
        if (aux->dev->of_node == np) {
            mutex_unlock(&dp_aux_lock);
            return aux;
        }
    }

    mutex_unlock(&dp_aux_lock);
    return NULL;
}

EXPORT_SYMBOL(of_drm_find_dp_aux_by_node);
#endif

int drm_dp_aux_init(struct drm_dp_aux *aux)

{
    INIT_LIST_HEAD(&aux->list);
    ...
}

int drm_dp_aux_register(struct drm_dp_aux *aux)

{
    ...
    drm_dp_aux_add(aux);

    return 0;
}

void drm_dp_aux_unregister(struct drm_dp_aux *aux)

{
    drm_dp_aux_remove(aux);
    ...
}

---

Thanks,
Rajeev

Quoted 15 lines

I guess an alternate way to solve this (I'm not totally sure whether it's better or worse) would be to add a function that would walk up the chain of parent bridges and ask them for a pointer to the aux bus. I definitely haven't thought it all the way through, but I'd imagine something like drm_bridge_chain_get_ddc_aux(). This is _probably_ better than adding the "ddc-aux-bus" property but it assumes that the aux bus is provided by one of our parents. Hrm, looking at this briefly, though, I'm not sure how to do it. It doesn't seem possible to get the parent bridges from the panel structure. Even if you assume that your parent is wrapping you with a panel_bridge it still doesn't seem possible?

This probably needs more drm-expertise.

-Doug

#8 lore raw

Re: [v3 1/2] dt-bindings: backlight: add DisplayPort aux backlight

Hi Rajeevny,

Quoted 197 lines · On Tue, May 11, 2021 at 11:41:57PM +0530, [email protected] wrote:
Quoted 109 lines · Doug Anderson
Quoted 103 lines · On Fri, Apr 30, 2021 at 8:10 AM <[email protected]> wrote:
Quoted 77 lines · Doug Anderson
Quoted 68 lines · Rob Herring
Quoted 52 lines · Rajeev Nandan

Add bindings for DisplayPort aux backlight driver.

Changes in v2:
- New

---
 .../bindings/leds/backlight/dp-aux-backlight.yaml  | 49 ++++++++++++++++++++++
 1 file changed, 49 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml
Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml new file +35 -0
new file mode 100644
index 00000000..0fa8bf0
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/leds/backlight/dp-aux-backlight.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: DisplayPort aux backlight driver bindings
+
+maintainers:
+  - Rajeev Nandan <[email protected]>
+
+description:
+  Backlight driver to control the brightness over DisplayPort aux channel.
+
+allOf:
+  - $ref: common.yaml#
+
+properties:
+  compatible:
+    const: dp-aux-backlight
+
+  ddc-i2c-bus:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      A phandle to the system I2C controller connected to the DDC bus used
+      for the DisplayPort AUX channel.
+
+  enable-gpios:
+    maxItems: 1
+    description: GPIO specifier for backlight enable pin.
+
+  max-brightness: true
+
+required:
+  - compatible

Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml line 45

Quoted 10 lines
Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml new file +10 -0
+  - ddc-i2c-bus
+
+additionalProperties: false
+
+examples:
+  - |
+    backlight {
+        compatible = "dp-aux-backlight";
+        ddc-i2c-bus = <&sn65dsi86_bridge>;
+        enable-gpios = <&tlmm 12 GPIO_ACTIVE_HIGH>;

So the DDC bus is connected to a backlight and also a panel? This binding is not reflecting the h/w, but rather what you want for some driver.

Quoted 7 lines

There's only one thing here and that's an eDP panel which supports backlight control via DP aux channel. You can figure all that out from the panel's compatible and/or reading the EDID.

You might also be interested in this thread:

https://lore.kernel.org/lkml/[email protected]/

Quoted 7 lines

I think Rajeev needs to rework everything anyway as per:

https://lore.kernel.org/r/[email protected]

...but you're right that it makes sense not to model the backlight as a separate node in the device tree. The panel driver can handle setting up the backlight.

It was not a good idea to create a separate backlight driver and use ddc-i2c-bus to get access to DP aux. I am working to move the code to the panel driver and to utilize the new DRM helper functions (drm_edp_backlight_*) Lyude has added [1].

To use these helper functions, the panel driver should have access to the "struct drm_dp_aux *". The simple-panel has a "ddc-i2c-bus" property to give the panel access to the DDC bus and is currently being used to get the EDID from the panel. Can I use the same ddc bus i2c_adapter to get the "struct drm_dp_aux *"?

As per the suggestion [2], I get the "struct drm_dp_aux *" from the i2c_adapter of ddc bus (maybe I didn't understand the suggestion correctly), and, it turned out, the way I have implemented is not the right way [3]. So, I am afraid to use the same method in the panel driver.

Quoted 4 lines

[1] https://lore.kernel.org/dri-devel/[email protected]/
[2] https://www.spinics.net/lists/dri-devel/msg295429.html
[3]
https://lore.kernel.org/dri-devel/[email protected]/

Quoted 4 lines

So it's definitely up to maintainers, not me. ...but I guess I would have expected something like a new property called "ddc-aux-bus". Then you'd have to create a new API call called something like "of_find_ddc_aux_adapter_by_node()" that would allow you to find it.

To implement the first suggestion, I can think of the following way to get the "struct drm_dp_aux" in the panel_simple_probe function:

- Create a new panel-simple DT property "ddc-aux-bus", a phandle to the platform device that implements the AUX channel.

- Create a global list of drm_dp_aux in drm_dp_helper.c. Initialize list head
in drm_dp_aux_init(), add the drm_dp_aux onto the list in drm_dp_aux_register().
Similarly, remove the drm_dp_aux from list in drm_dp_aux_unregister().

- Create a new function of_drm_find_dp_aux_by_node() to get the expected drm_dp_aux from this global list.

Please let me know your views on this implementation.

Below is the summary of the changes in drm dp helper:

---

// drm_dp_helper.h

struct drm_dp_aux {
	...
	struct list_head list;
	...
}

// drm_dp_helper.c

static DEFINE_MUTEX(dp_aux_lock);
static LIST_HEAD(dp_aux_list);

static void drm_dp_aux_add(struct drm_dp_aux *aux)

{
     mutex_lock(&dp_aux_lock);
     list_add_tail(&aux->list, &dp_aux_list);
     mutex_unlock(&dp_aux_lock);
}

static void drm_dp_aux_remove(struct drm_dp_aux *aux)

{
     mutex_lock(&dp_aux_lock);
     list_del_init(&aux->list);
     mutex_unlock(&dp_aux_lock);
}

#ifdef CONFIG_OF
struct drm_dp_aux *of_drm_find_dp_aux_by_node(struct device_node *np)

{
     struct drm_dp_aux *aux;
     mutex_lock(&dp_aux_lock);

     list_for_each_entry(aux, &dp_aux_list, list) {
         if (aux->dev->of_node == np) {
             mutex_unlock(&dp_aux_lock);
             return aux;
         }
     }

     mutex_unlock(&dp_aux_lock);
     return NULL;
}

EXPORT_SYMBOL(of_drm_find_dp_aux_by_node);
#endif

int drm_dp_aux_init(struct drm_dp_aux *aux)

{
     INIT_LIST_HEAD(&aux->list);
     ...
}

int drm_dp_aux_register(struct drm_dp_aux *aux)

{
     ...
     drm_dp_aux_add(aux);

     return 0;
}
Quoted 5 lines

void drm_dp_aux_unregister(struct drm_dp_aux *aux)

{
     drm_dp_aux_remove(aux);
     ...
}

Overall this seems like a good approach, but there's one unanswered
question: what happens if drm_dp_aux_unregister() is called while a panel holds a reference to it ? The drm_dp_aux instances likely need to be reference-counted.

Quoted 13 lines
Quoted 13 lines

I guess an alternate way to solve this (I'm not totally sure whether it's better or worse) would be to add a function that would walk up the chain of parent bridges and ask them for a pointer to the aux bus. I definitely haven't thought it all the way through, but I'd imagine something like drm_bridge_chain_get_ddc_aux(). This is _probably_ better than adding the "ddc-aux-bus" property but it assumes that the aux bus is provided by one of our parents. Hrm, looking at this briefly, though, I'm not sure how to do it. It doesn't seem possible to get the parent bridges from the panel structure. Even if you assume that your parent is wrapping you with a panel_bridge it still doesn't seem possible?

This probably needs more drm-expertise.

Signature · 3 lines
Regards,

Laurent Pinchart
#9 lore raw

Re: [v3 1/2] dt-bindings: backlight: add DisplayPort aux backlight

In reply to [email protected]

Hi,

Quoted 141 lines · On Tue, May 11, 2021 at 11:12 AM <[email protected]> wrote:
Quoted 121 lines · Doug Anderson

Hi,

Quoted 113 lines · On Fri, Apr 30, 2021 at 8:10 AM <[email protected]> wrote:
Quoted 82 lines · Doug Anderson

Hi,

Quoted 69 lines · Rob Herring
Quoted 52 lines · Rajeev Nandan

Add bindings for DisplayPort aux backlight driver.

Changes in v2:
- New

---
 .../bindings/leds/backlight/dp-aux-backlight.yaml  | 49 ++++++++++++++++++++++
 1 file changed, 49 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml
Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml new file +35 -0
new file mode 100644
index 00000000..0fa8bf0
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/leds/backlight/dp-aux-backlight.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: DisplayPort aux backlight driver bindings
+
+maintainers:
+  - Rajeev Nandan <[email protected]>
+
+description:
+  Backlight driver to control the brightness over DisplayPort aux channel.
+
+allOf:
+  - $ref: common.yaml#
+
+properties:
+  compatible:
+    const: dp-aux-backlight
+
+  ddc-i2c-bus:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      A phandle to the system I2C controller connected to the DDC bus used
+      for the DisplayPort AUX channel.
+
+  enable-gpios:
+    maxItems: 1
+    description: GPIO specifier for backlight enable pin.
+
+  max-brightness: true
+
+required:
+  - compatible

Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml line 45

Quoted 10 lines
Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml new file +10 -0
+  - ddc-i2c-bus
+
+additionalProperties: false
+
+examples:
+  - |
+    backlight {
+        compatible = "dp-aux-backlight";
+        ddc-i2c-bus = <&sn65dsi86_bridge>;
+        enable-gpios = <&tlmm 12 GPIO_ACTIVE_HIGH>;

So the DDC bus is connected to a backlight and also a panel? This binding is not reflecting the h/w, but rather what you want for some driver.

Quoted 7 lines

There's only one thing here and that's an eDP panel which supports backlight control via DP aux channel. You can figure all that out from the panel's compatible and/or reading the EDID.

You might also be interested in this thread:

https://lore.kernel.org/lkml/[email protected]/

I think Rajeev needs to rework everything anyway as per:

Quoted 7 lines

https://lore.kernel.org/r/[email protected]

...but you're right that it makes sense not to model the backlight as a separate node in the device tree. The panel driver can handle setting up the backlight.

-Doug

It was not a good idea to create a separate backlight driver and use ddc-i2c-bus to get access to DP aux. I am working to move the code to the panel driver and to utilize the new DRM helper functions (drm_edp_backlight_*) Lyude has added [1].

To use these helper functions, the panel driver should have access to the
"struct drm_dp_aux *". The simple-panel has a "ddc-i2c-bus" property to give the panel access to the DDC bus and is currently being used to get the EDID from the panel. Can I use the same ddc bus i2c_adapter to get
the "struct drm_dp_aux *"?

As per the suggestion [2], I get the "struct drm_dp_aux *" from the i2c_adapter of ddc bus (maybe I didn't understand the suggestion correctly),
and, it turned out, the way I have implemented is not the right way [3].
So, I am afraid to use the same method in the panel driver.

Quoted 4 lines

[1] https://lore.kernel.org/dri-devel/[email protected]/
[2] https://www.spinics.net/lists/dri-devel/msg295429.html
[3]
https://lore.kernel.org/dri-devel/[email protected]/

Quoted 5 lines

So it's definitely up to maintainers, not me. ...but I guess I would have expected something like a new property called "ddc-aux-bus". Then you'd have to create a new API call called something like "of_find_ddc_aux_adapter_by_node()" that would allow you to find it.

To implement the first suggestion, I can think of the following way to get the "struct drm_dp_aux" in the panel_simple_probe function:

- Create a new panel-simple DT property "ddc-aux-bus", a phandle to the platform device that implements the AUX channel.

- Create a global list of drm_dp_aux in drm_dp_helper.c. Initialize list head
in drm_dp_aux_init(), add the drm_dp_aux onto the list in drm_dp_aux_register().
Similarly, remove the drm_dp_aux from list in drm_dp_aux_unregister().

Quoted 4 lines

- Create a new function of_drm_find_dp_aux_by_node() to get the expected drm_dp_aux from this global list.

Please let me know your views on this implementation.

BTW: a bunch of discussion today on IRC:

https://people.freedesktop.org/~cbrill/dri-log/?channel=dri-devel&highlight_names=&date=2021-05-11&show_html=true

-Doug

#10 lore raw

Re: [v3 1/2] dt-bindings: backlight: add DisplayPort aux backlight

Hi,

Quoted 145 lines · Doug Anderson

Hi,

Quoted 141 lines · On Tue, May 11, 2021 at 11:12 AM <[email protected]> wrote:
Quoted 121 lines · Doug Anderson

Hi,

Quoted 113 lines · On Fri, Apr 30, 2021 at 8:10 AM <[email protected]> wrote:
Quoted 82 lines · Doug Anderson

Hi,

Quoted 69 lines · Rob Herring
Quoted 52 lines · Rajeev Nandan

Add bindings for DisplayPort aux backlight driver.

Changes in v2:
- New

---
 .../bindings/leds/backlight/dp-aux-backlight.yaml  | 49 ++++++++++++++++++++++
 1 file changed, 49 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml
Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml new file +35 -0
new file mode 100644
index 00000000..0fa8bf0
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/leds/backlight/dp-aux-backlight.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: DisplayPort aux backlight driver bindings
+
+maintainers:
+  - Rajeev Nandan <[email protected]>
+
+description:
+  Backlight driver to control the brightness over DisplayPort aux channel.
+
+allOf:
+  - $ref: common.yaml#
+
+properties:
+  compatible:
+    const: dp-aux-backlight
+
+  ddc-i2c-bus:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      A phandle to the system I2C controller connected to the DDC bus used
+      for the DisplayPort AUX channel.
+
+  enable-gpios:
+    maxItems: 1
+    description: GPIO specifier for backlight enable pin.
+
+  max-brightness: true
+
+required:
+  - compatible

Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml line 45

Quoted 10 lines
Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml new file +10 -0
+  - ddc-i2c-bus
+
+additionalProperties: false
+
+examples:
+  - |
+    backlight {
+        compatible = "dp-aux-backlight";
+        ddc-i2c-bus = <&sn65dsi86_bridge>;
+        enable-gpios = <&tlmm 12 GPIO_ACTIVE_HIGH>;

So the DDC bus is connected to a backlight and also a panel? This binding is not reflecting the h/w, but rather what you want for some driver.

Quoted 7 lines

There's only one thing here and that's an eDP panel which supports backlight control via DP aux channel. You can figure all that out from the panel's compatible and/or reading the EDID.

You might also be interested in this thread:

https://lore.kernel.org/lkml/[email protected]/

I think Rajeev needs to rework everything anyway as per:

Quoted 7 lines

https://lore.kernel.org/r/[email protected]

...but you're right that it makes sense not to model the backlight as a separate node in the device tree. The panel driver can handle setting up the backlight.

-Doug

It was not a good idea to create a separate backlight driver and use ddc-i2c-bus to get access to DP aux. I am working to move the code to the panel driver and to utilize the new DRM helper functions (drm_edp_backlight_*) Lyude has added [1].

To use these helper functions, the panel driver should have access to the
"struct drm_dp_aux *". The simple-panel has a "ddc-i2c-bus" property to give the panel access to the DDC bus and is currently being used to get the EDID from the panel. Can I use the same ddc bus i2c_adapter to get
the "struct drm_dp_aux *"?

As per the suggestion [2], I get the "struct drm_dp_aux *" from the i2c_adapter of ddc bus (maybe I didn't understand the suggestion correctly),
and, it turned out, the way I have implemented is not the right way [3].
So, I am afraid to use the same method in the panel driver.

Quoted 4 lines

[1] https://lore.kernel.org/dri-devel/[email protected]/
[2] https://www.spinics.net/lists/dri-devel/msg295429.html
[3]
https://lore.kernel.org/dri-devel/[email protected]/

Quoted 5 lines

So it's definitely up to maintainers, not me. ...but I guess I would have expected something like a new property called "ddc-aux-bus". Then you'd have to create a new API call called something like "of_find_ddc_aux_adapter_by_node()" that would allow you to find it.

To implement the first suggestion, I can think of the following way to get the "struct drm_dp_aux" in the panel_simple_probe function:

- Create a new panel-simple DT property "ddc-aux-bus", a phandle to the platform device that implements the AUX channel.

- Create a global list of drm_dp_aux in drm_dp_helper.c. Initialize list head
in drm_dp_aux_init(), add the drm_dp_aux onto the list in drm_dp_aux_register().
Similarly, remove the drm_dp_aux from list in drm_dp_aux_unregister().

Quoted 8 lines
Quoted 4 lines

- Create a new function of_drm_find_dp_aux_by_node() to get the expected drm_dp_aux from this global list.

Please let me know your views on this implementation.

BTW: a bunch of discussion today on IRC:

https://people.freedesktop.org/~cbrill/dri-log/?channel=dri-devel&highlight_names=&date=2021-05-11&show_html=true

To finish adding breadcrumbs to those playing at home, v7 of my patch series should get the AUX channel to the panel device:

https://lore.kernel.org/r/[email protected]/

Assuming that people don't hate that solution it may be a good things for you to build your patches atop. :-)

-Doug

#11 lore raw

Re: [v3 1/2] dt-bindings: backlight: add DisplayPort aux backlight

Hi,

Quoted 160 lines · Doug Anderson

Hi,

Quoted 145 lines · Doug Anderson

Hi,

Quoted 141 lines · On Tue, May 11, 2021 at 11:12 AM <[email protected]> wrote:
Quoted 121 lines · Doug Anderson

Hi,

Quoted 113 lines · On Fri, Apr 30, 2021 at 8:10 AM <[email protected]> wrote:
Quoted 82 lines · Doug Anderson

Hi,

Quoted 69 lines · Rob Herring
Quoted 52 lines · Rajeev Nandan

Add bindings for DisplayPort aux backlight driver.

Changes in v2:
- New

---
 .../bindings/leds/backlight/dp-aux-backlight.yaml  | 49 ++++++++++++++++++++++
 1 file changed, 49 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml
Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml new file +35 -0
new file mode 100644
index 00000000..0fa8bf0
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/leds/backlight/dp-aux-backlight.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: DisplayPort aux backlight driver bindings
+
+maintainers:
+  - Rajeev Nandan <[email protected]>
+
+description:
+  Backlight driver to control the brightness over DisplayPort aux channel.
+
+allOf:
+  - $ref: common.yaml#
+
+properties:
+  compatible:
+    const: dp-aux-backlight
+
+  ddc-i2c-bus:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      A phandle to the system I2C controller connected to the DDC bus used
+      for the DisplayPort AUX channel.
+
+  enable-gpios:
+    maxItems: 1
+    description: GPIO specifier for backlight enable pin.
+
+  max-brightness: true
+
+required:
+  - compatible

Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml line 45

Quoted 10 lines
Documentation/devicetree/bindings/leds/backlight/dp-aux-backlight.yaml new file +10 -0
+  - ddc-i2c-bus
+
+additionalProperties: false
+
+examples:
+  - |
+    backlight {
+        compatible = "dp-aux-backlight";
+        ddc-i2c-bus = <&sn65dsi86_bridge>;
+        enable-gpios = <&tlmm 12 GPIO_ACTIVE_HIGH>;

So the DDC bus is connected to a backlight and also a panel? This binding is not reflecting the h/w, but rather what you want for some driver.

Quoted 7 lines

There's only one thing here and that's an eDP panel which supports backlight control via DP aux channel. You can figure all that out from the panel's compatible and/or reading the EDID.

You might also be interested in this thread:

https://lore.kernel.org/lkml/[email protected]/

I think Rajeev needs to rework everything anyway as per:

Quoted 7 lines

https://lore.kernel.org/r/[email protected]

...but you're right that it makes sense not to model the backlight as a separate node in the device tree. The panel driver can handle setting up the backlight.

-Doug

It was not a good idea to create a separate backlight driver and use ddc-i2c-bus to get access to DP aux. I am working to move the code to the panel driver and to utilize the new DRM helper functions (drm_edp_backlight_*) Lyude has added [1].

To use these helper functions, the panel driver should have access to the
"struct drm_dp_aux *". The simple-panel has a "ddc-i2c-bus" property to give the panel access to the DDC bus and is currently being used to get the EDID from the panel. Can I use the same ddc bus i2c_adapter to get
the "struct drm_dp_aux *"?

As per the suggestion [2], I get the "struct drm_dp_aux *" from the i2c_adapter of ddc bus (maybe I didn't understand the suggestion correctly),
and, it turned out, the way I have implemented is not the right way [3].
So, I am afraid to use the same method in the panel driver.

Quoted 4 lines

[1] https://lore.kernel.org/dri-devel/[email protected]/
[2] https://www.spinics.net/lists/dri-devel/msg295429.html
[3]
https://lore.kernel.org/dri-devel/[email protected]/

Quoted 5 lines

So it's definitely up to maintainers, not me. ...but I guess I would have expected something like a new property called "ddc-aux-bus". Then you'd have to create a new API call called something like "of_find_ddc_aux_adapter_by_node()" that would allow you to find it.

To implement the first suggestion, I can think of the following way to get the "struct drm_dp_aux" in the panel_simple_probe function:

- Create a new panel-simple DT property "ddc-aux-bus", a phandle to the platform device that implements the AUX channel.

- Create a global list of drm_dp_aux in drm_dp_helper.c. Initialize list head
in drm_dp_aux_init(), add the drm_dp_aux onto the list in drm_dp_aux_register().
Similarly, remove the drm_dp_aux from list in drm_dp_aux_unregister().

Quoted 8 lines
Quoted 4 lines

- Create a new function of_drm_find_dp_aux_by_node() to get the expected drm_dp_aux from this global list.

Please let me know your views on this implementation.

BTW: a bunch of discussion today on IRC:

https://people.freedesktop.org/~cbrill/dri-log/?channel=dri-devel&highlight_names=&date=2021-05-11&show_html=true

To finish adding breadcrumbs to those playing at home, v7 of my patch series should get the AUX channel to the panel device:

Quoted 6 lines

https://lore.kernel.org/r/[email protected]/

Assuming that people don't hate that solution it may be a good things for you to build your patches atop. :-)

-Doug

Thank you, for all your suggestions.

I have posted the new patch series (v4) on top of the above series. Please check:
https://lore.kernel.org/dri-devel/[email protected]/

Thanks,
Rajeev

#12 lore raw

PATCH v3 2/2 backlight: Add DisplayPort aux backlight driver

In reply to Rajeev Nandan

Add backlight driver for the panels supporting backlight control using DPCD registers on the DisplayPort aux channel.

Changes in v2:
- New (most of the code reused from drm_dp_aux_backlight.c of v1)

Changes in v3:
- Add missing ';' to fix module compilation (kernel test bot)

---
 drivers/video/backlight/Kconfig            |   7 +
 drivers/video/backlight/Makefile           |   1 +
 drivers/video/backlight/dp_aux_backlight.c | 245 +++++++++++++++++++++++++++++
 3 files changed, 253 insertions(+)
 create mode 100644 drivers/video/backlight/dp_aux_backlight.c
drivers/video/backlight/Kconfig +7 -0
index d83c87b..82c88f0 100644
@@ -456,6 +456,13 @@ config BACKLIGHT_LED
 	  If you have a LCD backlight adjustable by LED class driver, say Y
 	  to enable this driver.
 
+config BACKLIGHT_DP_AUX
+       tristate "DisplayPort aux backlight driver"
+       depends on DRM && DRM_KMS_HELPER
+       help
+         If you have a panel backlight controlled by DPCD registers
+         on the DisplayPort aux channel, say Y to enable this driver.
+
 endif # BACKLIGHT_CLASS_DEVICE
 
 endmenu
drivers/video/backlight/Makefile +1 -0
index 685f3f1..ba23c7c 100644
@@ -57,3 +57,4 @@ obj-$(CONFIG_BACKLIGHT_WM831X)		+= wm831x_bl.o
 obj-$(CONFIG_BACKLIGHT_ARCXCNN) 	+= arcxcnn_bl.o
 obj-$(CONFIG_BACKLIGHT_RAVE_SP)		+= rave-sp-backlight.o
 obj-$(CONFIG_BACKLIGHT_LED)		+= led_bl.o
+obj-$(CONFIG_BACKLIGHT_DP_AUX)		+= dp_aux_backlight.o
drivers/video/backlight/dp_aux_backlight.c new file +245 -0

245 lines not on this page · raw message

Signature · 6 lines
2.7.4

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
#13 lore raw

Re: [v3 2/2] backlight: Add DisplayPort aux backlight driver

Quoted 2 lines · Rajeev Nandan

Add backlight driver for the panels supporting backlight control using DPCD registers on the DisplayPort aux channel.

No, please don't do this.

I wrote you last week in reply to v1 why I thought merging this would not be a good idea [1]. Why have you sent two versions since then without replying to me, or Cc'ing me or Lyude?

I think it's an even worse idea to merge this to drivers/video/backlight. With DP AUX backlight you can't pretend it's just an independent aux interface for backlight without everything else around it. It's not independent of eDP, and exposing it as a direct backlight sysfs interface bypasses the encoder.

And it still remains that there is existing DP AUX backlight code in use, in the tree, with more features than this, with plans and previously submitted patches to lift from one driver to drm core, and with patches to add support to another driver.

I don't say this lightly, or very often at all, but,

NAK.

BR,
Jani.

[1] https://lore.kernel.org/dri-devel/[email protected]/

Quoted 293 lines

Changes in v2:
- New (most of the code reused from drm_dp_aux_backlight.c of v1)

Changes in v3:
- Add missing ';' to fix module compilation (kernel test bot)

---
 drivers/video/backlight/Kconfig            |   7 +
 drivers/video/backlight/Makefile           |   1 +
 drivers/video/backlight/dp_aux_backlight.c | 245 +++++++++++++++++++++++++++++
 3 files changed, 253 insertions(+)
 create mode 100644 drivers/video/backlight/dp_aux_backlight.c
drivers/video/backlight/Kconfig +7 -0
index d83c87b..82c88f0 100644
@@ -456,6 +456,13 @@ config BACKLIGHT_LED
 	  If you have a LCD backlight adjustable by LED class driver, say Y
 	  to enable this driver.
 
+config BACKLIGHT_DP_AUX
+       tristate "DisplayPort aux backlight driver"
+       depends on DRM && DRM_KMS_HELPER
+       help
+         If you have a panel backlight controlled by DPCD registers
+         on the DisplayPort aux channel, say Y to enable this driver.
+
 endif # BACKLIGHT_CLASS_DEVICE
 
 endmenu
drivers/video/backlight/Makefile +1 -0
index 685f3f1..ba23c7c 100644
@@ -57,3 +57,4 @@ obj-$(CONFIG_BACKLIGHT_WM831X)		+= wm831x_bl.o
 obj-$(CONFIG_BACKLIGHT_ARCXCNN) 	+= arcxcnn_bl.o
 obj-$(CONFIG_BACKLIGHT_RAVE_SP)		+= rave-sp-backlight.o
 obj-$(CONFIG_BACKLIGHT_LED)		+= led_bl.o
+obj-$(CONFIG_BACKLIGHT_DP_AUX)		+= dp_aux_backlight.o
drivers/video/backlight/dp_aux_backlight.c new file +245 -0
new file mode 100644
index 00000000..3398383
@@ -0,0 +1,245 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Backlight driver to control the brightness over DisplayPort aux channel.
+ */
+
+#include <linux/backlight.h>
+#include <linux/err.h>
+#include <linux/gpio/consumer.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <drm/drm_dp_helper.h>
+
+#define DP_AUX_MAX_BRIGHTNESS		0xffff
+
+/**
+ * struct dp_aux_backlight - DisplayPort aux backlight data
+ * @dev: pointer to our device.
+ * @aux: the DisplayPort aux channel.
+ * @enable_gpio: the backlight enable gpio.
+ * @enabled: true if backlight is enabled else false.
+ */
+struct dp_aux_backlight {
+	struct device *dev;
+	struct drm_dp_aux *aux;
+	struct gpio_desc *enable_gpio;
+	bool enabled;
+};
+
+static struct drm_dp_aux *i2c_to_aux(struct i2c_adapter *i2c)
+{
+	return container_of(i2c, struct drm_dp_aux, ddc);
+}
+
+static int dp_aux_backlight_enable(struct dp_aux_backlight *aux_bl)
+{
+	u8 val = 0;
+	int ret;
+
+	if (aux_bl->enabled)
+		return 0;
+
+	/* Set backlight control mode */
+	ret = drm_dp_dpcd_readb(aux_bl->aux, DP_EDP_BACKLIGHT_MODE_SET_REGISTER,
+				&val);
+	if (ret < 0)
+		return ret;
+
+	val &= ~DP_EDP_BACKLIGHT_CONTROL_MODE_MASK;
+	val |= DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD;
+	ret = drm_dp_dpcd_writeb(aux_bl->aux, DP_EDP_BACKLIGHT_MODE_SET_REGISTER,
+				 val);
+	if (ret < 0)
+		return ret;
+
+	/* Enable backlight */
+	ret = drm_dp_dpcd_readb(aux_bl->aux, DP_EDP_DISPLAY_CONTROL_REGISTER,
+				&val);
+	if (ret < 0)
+		return ret;
+
+	val |= DP_EDP_BACKLIGHT_ENABLE;
+	ret = drm_dp_dpcd_writeb(aux_bl->aux, DP_EDP_DISPLAY_CONTROL_REGISTER,
+				 val);
+	if (ret < 0)
+		return ret;
+
+	if (aux_bl->enable_gpio)
+		gpiod_set_value(aux_bl->enable_gpio, 1);
+
+	aux_bl->enabled = true;
+
+	return 0;
+}
+
+static int dp_aux_backlight_disable(struct dp_aux_backlight *aux_bl)
+{
+	u8 val = 0;
+	int ret;
+
+	if (!aux_bl->enabled)
+		return 0;
+
+	if (aux_bl->enable_gpio)
+		gpiod_set_value(aux_bl->enable_gpio, 0);
+
+	ret = drm_dp_dpcd_readb(aux_bl->aux, DP_EDP_DISPLAY_CONTROL_REGISTER,
+				&val);
+	if (ret < 0)
+		return ret;
+
+	val &= ~DP_EDP_BACKLIGHT_ENABLE;
+	ret = drm_dp_dpcd_writeb(aux_bl->aux, DP_EDP_DISPLAY_CONTROL_REGISTER,
+				 val);
+	if (ret < 0)
+		return ret;
+
+	aux_bl->enabled = false;
+
+	return 0;
+}
+
+static int dp_aux_backlight_update_status(struct backlight_device *bd)
+{
+	struct dp_aux_backlight *aux_bl = bl_get_data(bd);
+	u16 brightness = backlight_get_brightness(bd);
+	u8 val[2] = { 0x0 };
+	int ret = 0;
+
+	if (brightness > 0) {
+		val[0] = brightness >> 8;
+		val[1] = brightness & 0xff;
+		ret = drm_dp_dpcd_write(aux_bl->aux, DP_EDP_BACKLIGHT_BRIGHTNESS_MSB,
+					val, sizeof(val));
+		if (ret < 0)
+			return ret;
+
+		dp_aux_backlight_enable(aux_bl);
+	} else {
+		dp_aux_backlight_disable(aux_bl);
+	}
+
+	return 0;
+}
+
+static int dp_aux_backlight_get_brightness(struct backlight_device *bd)
+{
+	struct dp_aux_backlight *aux_bl = bl_get_data(bd);
+	u8 val[2] = { 0x0 };
+	int ret = 0;
+
+	if (backlight_is_blank(bd))
+		return 0;
+
+	ret = drm_dp_dpcd_read(aux_bl->aux, DP_EDP_BACKLIGHT_BRIGHTNESS_MSB,
+			       &val, sizeof(val));
+	if (ret < 0)
+		return ret;
+
+	return (val[0] << 8 | val[1]);
+}
+
+static const struct backlight_ops aux_bl_ops = {
+	.update_status = dp_aux_backlight_update_status,
+	.get_brightness = dp_aux_backlight_get_brightness,
+};
+
+
+static int dp_aux_backlight_probe(struct platform_device *pdev)
+{
+	struct dp_aux_backlight *aux_bl;
+	struct backlight_device *bd;
+	struct backlight_properties bl_props = { 0 };
+	struct device_node *np;
+	struct i2c_adapter *ddc;
+	int ret = 0;
+	u32 val;
+
+	aux_bl = devm_kzalloc(&pdev->dev, sizeof(*aux_bl), GFP_KERNEL);
+	if (!aux_bl)
+		return -ENOMEM;
+
+	aux_bl->dev = &pdev->dev;
+
+	np = of_parse_phandle(pdev->dev.of_node, "ddc-i2c-bus", 0);
+	if (!np) {
+		dev_err(&pdev->dev, "failed to get aux ddc I2C bus\n");
+		return -ENODEV;
+	}
+
+	ddc = of_find_i2c_adapter_by_node(np);
+	of_node_put(np);
+	if (!ddc)
+		return -EPROBE_DEFER;
+
+	aux_bl->aux = i2c_to_aux(ddc);
+	dev_dbg(&pdev->dev, "using dp aux %s\n", aux_bl->aux->name);
+
+	aux_bl->enable_gpio = devm_gpiod_get_optional(&pdev->dev, "enable",
+					     GPIOD_OUT_LOW);
+	if (IS_ERR(aux_bl->enable_gpio)) {
+		ret = PTR_ERR(aux_bl->enable_gpio);
+		goto free_ddc;
+	}
+
+	val = DP_AUX_MAX_BRIGHTNESS;
+	of_property_read_u32(pdev->dev.of_node, "max-brightness", &val);
+	if (val > DP_AUX_MAX_BRIGHTNESS)
+		val = DP_AUX_MAX_BRIGHTNESS;
+
+	bl_props.max_brightness = val;
+	bl_props.brightness = val;
+	bl_props.type = BACKLIGHT_RAW;
+	bd = devm_backlight_device_register(&pdev->dev, dev_name(&pdev->dev),
+					    &pdev->dev, aux_bl,
+					    &aux_bl_ops, &bl_props);
+	if (IS_ERR(bd)) {
+		ret = PTR_ERR(bd);
+		dev_err(&pdev->dev,
+			      "failed to register backlight (%d)\n", ret);
+		goto free_ddc;
+	}
+
+	platform_set_drvdata(pdev, bd);
+
+	return 0;
+
+free_ddc:
+	if (ddc)
+		put_device(&ddc->dev);
+
+	return ret;
+}
+
+static int dp_aux_backlight_remove(struct platform_device *pdev)
+{
+	struct backlight_device *bd = platform_get_drvdata(pdev);
+	struct dp_aux_backlight *aux_bl = bl_get_data(bd);
+	struct i2c_adapter *ddc = &aux_bl->aux->ddc;
+
+	if (ddc)
+		put_device(&ddc->dev);
+
+	return 0;
+}
+
+static const struct of_device_id dp_aux_bl_of_match_table[] = {
+	{ .compatible = "dp-aux-backlight"},
+	{},
+};
+MODULE_DEVICE_TABLE(of, dp_aux_bl_of_match_table);
+
+static struct platform_driver dp_aux_backlight_driver = {
+	.driver = {
+		.name = "dp-aux-backlight",
+		.of_match_table = dp_aux_bl_of_match_table,
+	},
+	.probe = dp_aux_backlight_probe,
+	.remove = dp_aux_backlight_remove,
+
+};
+module_platform_driver(dp_aux_backlight_driver);
+
+MODULE_DESCRIPTION("DisplayPort aux backlight driver");
+MODULE_LICENSE("GPL v2");
Signature · 1 line
Jani Nikula, Intel Open Source Graphics Center
#14 lore raw

Re: [v3 2/2] backlight: Add DisplayPort aux backlight driver

Quoted 23 lines · Jani Nikula
Quoted 2 lines · Rajeev Nandan

Add backlight driver for the panels supporting backlight control using DPCD registers on the DisplayPort aux channel.

No, please don't do this.

I wrote you last week in reply to v1 why I thought merging this would not be a good idea [1]. Why have you sent two versions since then without replying to me, or Cc'ing me or Lyude?

I think it's an even worse idea to merge this to drivers/video/backlight. With DP AUX backlight you can't pretend it's just an independent aux interface for backlight without everything else around it. It's not independent of eDP, and exposing it as a direct backlight sysfs interface bypasses the encoder.

And it still remains that there is existing DP AUX backlight code in use, in the tree, with more features than this, with plans and previously submitted patches to lift from one driver to drm core, and with patches to add support to another driver.

I don't say this lightly, or very often at all, but,

Quoted 9 lines

NAK.

BR,
Jani.

[1] https://lore.kernel.org/dri-devel/[email protected]/

Hi Jani,

Apologies for not acknowledging your comment on v1.
I was looking here [1] for all the comments I would be receiving on my patches. I was not aware that the comments on the cover letter don't appear on this page. Also, I completely missed your mail.
I will ensure such omissions don't happen again.

Keeping your comments in mind, I will look into Lyude's series and work upon my code.

[1] https://patchwork.freedesktop.org/series/89085/

Yours sincerely,
Rajeev

Quoted 297 lines
Quoted 297 lines

Changes in v2:
- New (most of the code reused from drm_dp_aux_backlight.c of v1)

Changes in v3:
- Add missing ';' to fix module compilation (kernel test bot)

---
 drivers/video/backlight/Kconfig            |   7 +
 drivers/video/backlight/Makefile           |   1 +
 drivers/video/backlight/dp_aux_backlight.c | 245 
+++++++++++++++++++++++++++++
 3 files changed, 253 insertions(+)
 create mode 100644 drivers/video/backlight/dp_aux_backlight.c
drivers/video/backlight/Kconfig +7 -0
index d83c87b..82c88f0 100644
@@ -456,6 +456,13 @@ config BACKLIGHT_LED
 	  If you have a LCD backlight adjustable by LED class driver, say Y
 	  to enable this driver.
 
+config BACKLIGHT_DP_AUX
+       tristate "DisplayPort aux backlight driver"
+       depends on DRM && DRM_KMS_HELPER
+       help
+         If you have a panel backlight controlled by DPCD registers
+         on the DisplayPort aux channel, say Y to enable this driver.
+
 endif # BACKLIGHT_CLASS_DEVICE
 
 endmenu
drivers/video/backlight/Makefile +1 -0
index 685f3f1..ba23c7c 100644
@@ -57,3 +57,4 @@ obj-$(CONFIG_BACKLIGHT_WM831X)		+= wm831x_bl.o
 obj-$(CONFIG_BACKLIGHT_ARCXCNN) 	+= arcxcnn_bl.o
 obj-$(CONFIG_BACKLIGHT_RAVE_SP)		+= rave-sp-backlight.o
 obj-$(CONFIG_BACKLIGHT_LED)		+= led_bl.o
+obj-$(CONFIG_BACKLIGHT_DP_AUX)		+= dp_aux_backlight.o
drivers/video/backlight/dp_aux_backlight.c new file +3 -0
new file mode 100644
index 00000000..3398383
@@ -0,0 +1,245 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Backlight driver to control the brightness over DisplayPort aux 

channel.
+ */

drivers/video/backlight/dp_aux_backlight.c new file +40 -0
+
+#include <linux/backlight.h>
+#include <linux/err.h>
+#include <linux/gpio/consumer.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <drm/drm_dp_helper.h>
+
+#define DP_AUX_MAX_BRIGHTNESS		0xffff
+
+/**
+ * struct dp_aux_backlight - DisplayPort aux backlight data
+ * @dev: pointer to our device.
+ * @aux: the DisplayPort aux channel.
+ * @enable_gpio: the backlight enable gpio.
+ * @enabled: true if backlight is enabled else false.
+ */
+struct dp_aux_backlight {
+	struct device *dev;
+	struct drm_dp_aux *aux;
+	struct gpio_desc *enable_gpio;
+	bool enabled;
+};
+
+static struct drm_dp_aux *i2c_to_aux(struct i2c_adapter *i2c)
+{
+	return container_of(i2c, struct drm_dp_aux, ddc);
+}
+
+static int dp_aux_backlight_enable(struct dp_aux_backlight *aux_bl)
+{
+	u8 val = 0;
+	int ret;
+
+	if (aux_bl->enabled)
+		return 0;
+
+	/* Set backlight control mode */
+	ret = drm_dp_dpcd_readb(aux_bl->aux, 

DP_EDP_BACKLIGHT_MODE_SET_REGISTER,

drivers/video/backlight/dp_aux_backlight.c new file +7 -0
+				&val);
+	if (ret < 0)
+		return ret;
+
+	val &= ~DP_EDP_BACKLIGHT_CONTROL_MODE_MASK;
+	val |= DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD;
+	ret = drm_dp_dpcd_writeb(aux_bl->aux, 

DP_EDP_BACKLIGHT_MODE_SET_REGISTER,

drivers/video/backlight/dp_aux_backlight.c new file +6 -0
+				 val);
+	if (ret < 0)
+		return ret;
+
+	/* Enable backlight */
+	ret = drm_dp_dpcd_readb(aux_bl->aux, 

DP_EDP_DISPLAY_CONTROL_REGISTER,

drivers/video/backlight/dp_aux_backlight.c new file +6 -0
+				&val);
+	if (ret < 0)
+		return ret;
+
+	val |= DP_EDP_BACKLIGHT_ENABLE;
+	ret = drm_dp_dpcd_writeb(aux_bl->aux, 

DP_EDP_DISPLAY_CONTROL_REGISTER,

drivers/video/backlight/dp_aux_backlight.c new file +24 -0
+				 val);
+	if (ret < 0)
+		return ret;
+
+	if (aux_bl->enable_gpio)
+		gpiod_set_value(aux_bl->enable_gpio, 1);
+
+	aux_bl->enabled = true;
+
+	return 0;
+}
+
+static int dp_aux_backlight_disable(struct dp_aux_backlight *aux_bl)
+{
+	u8 val = 0;
+	int ret;
+
+	if (!aux_bl->enabled)
+		return 0;
+
+	if (aux_bl->enable_gpio)
+		gpiod_set_value(aux_bl->enable_gpio, 0);
+
+	ret = drm_dp_dpcd_readb(aux_bl->aux, 

DP_EDP_DISPLAY_CONTROL_REGISTER,

drivers/video/backlight/dp_aux_backlight.c new file +6 -0
+				&val);
+	if (ret < 0)
+		return ret;
+
+	val &= ~DP_EDP_BACKLIGHT_ENABLE;
+	ret = drm_dp_dpcd_writeb(aux_bl->aux, 

DP_EDP_DISPLAY_CONTROL_REGISTER,

drivers/video/backlight/dp_aux_backlight.c new file +10 -0
+				 val);
+	if (ret < 0)
+		return ret;
+
+	aux_bl->enabled = false;
+
+	return 0;
+}
+
+static int dp_aux_backlight_update_status(struct backlight_device 

*bd)

drivers/video/backlight/dp_aux_backlight.c new file +10 -0
+{
+	struct dp_aux_backlight *aux_bl = bl_get_data(bd);
+	u16 brightness = backlight_get_brightness(bd);
+	u8 val[2] = { 0x0 };
+	int ret = 0;
+
+	if (brightness > 0) {
+		val[0] = brightness >> 8;
+		val[1] = brightness & 0xff;
+		ret = drm_dp_dpcd_write(aux_bl->aux, 

DP_EDP_BACKLIGHT_BRIGHTNESS_MSB,

drivers/video/backlight/dp_aux_backlight.c new file +13 -0
+					val, sizeof(val));
+		if (ret < 0)
+			return ret;
+
+		dp_aux_backlight_enable(aux_bl);
+	} else {
+		dp_aux_backlight_disable(aux_bl);
+	}
+
+	return 0;
+}
+
+static int dp_aux_backlight_get_brightness(struct backlight_device 

*bd)

drivers/video/backlight/dp_aux_backlight.c new file +68 -0
+{
+	struct dp_aux_backlight *aux_bl = bl_get_data(bd);
+	u8 val[2] = { 0x0 };
+	int ret = 0;
+
+	if (backlight_is_blank(bd))
+		return 0;
+
+	ret = drm_dp_dpcd_read(aux_bl->aux, DP_EDP_BACKLIGHT_BRIGHTNESS_MSB,
+			       &val, sizeof(val));
+	if (ret < 0)
+		return ret;
+
+	return (val[0] << 8 | val[1]);
+}
+
+static const struct backlight_ops aux_bl_ops = {
+	.update_status = dp_aux_backlight_update_status,
+	.get_brightness = dp_aux_backlight_get_brightness,
+};
+
+
+static int dp_aux_backlight_probe(struct platform_device *pdev)
+{
+	struct dp_aux_backlight *aux_bl;
+	struct backlight_device *bd;
+	struct backlight_properties bl_props = { 0 };
+	struct device_node *np;
+	struct i2c_adapter *ddc;
+	int ret = 0;
+	u32 val;
+
+	aux_bl = devm_kzalloc(&pdev->dev, sizeof(*aux_bl), GFP_KERNEL);
+	if (!aux_bl)
+		return -ENOMEM;
+
+	aux_bl->dev = &pdev->dev;
+
+	np = of_parse_phandle(pdev->dev.of_node, "ddc-i2c-bus", 0);
+	if (!np) {
+		dev_err(&pdev->dev, "failed to get aux ddc I2C bus\n");
+		return -ENODEV;
+	}
+
+	ddc = of_find_i2c_adapter_by_node(np);
+	of_node_put(np);
+	if (!ddc)
+		return -EPROBE_DEFER;
+
+	aux_bl->aux = i2c_to_aux(ddc);
+	dev_dbg(&pdev->dev, "using dp aux %s\n", aux_bl->aux->name);
+
+	aux_bl->enable_gpio = devm_gpiod_get_optional(&pdev->dev, "enable",
+					     GPIOD_OUT_LOW);
+	if (IS_ERR(aux_bl->enable_gpio)) {
+		ret = PTR_ERR(aux_bl->enable_gpio);
+		goto free_ddc;
+	}
+
+	val = DP_AUX_MAX_BRIGHTNESS;
+	of_property_read_u32(pdev->dev.of_node, "max-brightness", &val);
+	if (val > DP_AUX_MAX_BRIGHTNESS)
+		val = DP_AUX_MAX_BRIGHTNESS;
+
+	bl_props.max_brightness = val;
+	bl_props.brightness = val;
+	bl_props.type = BACKLIGHT_RAW;
+	bd = devm_backlight_device_register(&pdev->dev, 

dev_name(&pdev->dev),

drivers/video/backlight/dp_aux_backlight.c new file +43 -0
+					    &pdev->dev, aux_bl,
+					    &aux_bl_ops, &bl_props);
+	if (IS_ERR(bd)) {
+		ret = PTR_ERR(bd);
+		dev_err(&pdev->dev,
+			      "failed to register backlight (%d)\n", ret);
+		goto free_ddc;
+	}
+
+	platform_set_drvdata(pdev, bd);
+
+	return 0;
+
+free_ddc:
+	if (ddc)
+		put_device(&ddc->dev);
+
+	return ret;
+}
+
+static int dp_aux_backlight_remove(struct platform_device *pdev)
+{
+	struct backlight_device *bd = platform_get_drvdata(pdev);
+	struct dp_aux_backlight *aux_bl = bl_get_data(bd);
+	struct i2c_adapter *ddc = &aux_bl->aux->ddc;
+
+	if (ddc)
+		put_device(&ddc->dev);
+
+	return 0;
+}
+
+static const struct of_device_id dp_aux_bl_of_match_table[] = {
+	{ .compatible = "dp-aux-backlight"},
+	{},
+};
+MODULE_DEVICE_TABLE(of, dp_aux_bl_of_match_table);
+
+static struct platform_driver dp_aux_backlight_driver = {
+	.driver = {
+		.name = "dp-aux-backlight",
+		.of_match_table = dp_aux_bl_of_match_table,
+	},
Quoted 8 lines

drivers/video/backlight/dp_aux_backlight.c line 245

Quoted 8 lines
drivers/video/backlight/dp_aux_backlight.c new file +8 -0
+	.probe = dp_aux_backlight_probe,
+	.remove = dp_aux_backlight_remove,
+
+};
+module_platform_driver(dp_aux_backlight_driver);
+
+MODULE_DESCRIPTION("DisplayPort aux backlight driver");
+MODULE_LICENSE("GPL v2");

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel

#15 lore raw

Re: [v3 2/2] backlight: Add DisplayPort aux backlight driver

In reply to Jani Nikula

JFYI for anyone who is interested, I will be respinning my patches for adding backlight helpers very soon since we've got pretty much all of the prep work for it upstream now

Quoted 343 lines · Jani Nikula
Quoted 2 lines · Rajeev Nandan

Add backlight driver for the panels supporting backlight control using DPCD registers on the DisplayPort aux channel.

No, please don't do this.

I wrote you last week in reply to v1 why I thought merging this would not be a good idea [1]. Why have you sent two versions since then without replying to me, or Cc'ing me or Lyude?

I think it's an even worse idea to merge this to drivers/video/backlight. With DP AUX backlight you can't pretend it's just an independent aux interface for backlight without everything else around it. It's not independent of eDP, and exposing it as a direct backlight sysfs interface bypasses the encoder.

And it still remains that there is existing DP AUX backlight code in use, in the tree, with more features than this, with plans and previously submitted patches to lift from one driver to drm core, and with patches to add support to another driver.

I don't say this lightly, or very often at all, but,

NAK.

BR,
Jani.

[1] https://lore.kernel.org/dri-devel/[email protected]/

Quoted 310 lines

Changes in v2:
- New (most of the code reused from drm_dp_aux_backlight.c of v1)

Changes in v3:
- Add missing ';' to fix module compilation (kernel test bot)

---
 drivers/video/backlight/Kconfig            |   7 + drivers/video/backlight/Makefile           |   1 + drivers/video/backlight/dp_aux_backlight.c | 245
+++++++++++++++++++++++++++++

 3 files changed, 253 insertions(+)

 create mode 100644 drivers/video/backlight/dp_aux_backlight.c

drivers/video/backlight/Kconfig +0 -0
index d83c87b..82c88f0 100644
@@ -456,6 +456,13 @@ config BACKLIGHT_LED

          If you have a LCD backlight adjustable by LED class driver, say Y
          to enable this driver.

drivers/video/backlight/Kconfig +7 -0
+config BACKLIGHT_DP_AUX
+       tristate "DisplayPort aux backlight driver"
+       depends on DRM && DRM_KMS_HELPER
+       help
+         If you have a panel backlight controlled by DPCD registers
+         on the DisplayPort aux channel, say Y to enable this driver.
+

 endif # BACKLIGHT_CLASS_DEVICE

 endmenu

drivers/video/backlight/Makefile +0 -0
index 685f3f1..ba23c7c 100644
@@ -57,3 +57,4 @@ obj-$(CONFIG_BACKLIGHT_WM831X)                +=

wm831x_bl.o
 obj-$(CONFIG_BACKLIGHT_ARCXCNN)        += arcxcnn_bl.o obj-$(CONFIG_BACKLIGHT_RAVE_SP)                += rave-sp-backlight.o obj-$(CONFIG_BACKLIGHT_LED)            += led_bl.o

drivers/video/backlight/Makefile +1 -0
+obj-$(CONFIG_BACKLIGHT_DP_AUX)         += dp_aux_backlight.o
drivers/video/backlight/dp_aux_backlight.c new file +3 -0
new file mode 100644
index 00000000..3398383
@@ -0,0 +1,245 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Backlight driver to control the brightness over DisplayPort aux

channel.
+ */

drivers/video/backlight/dp_aux_backlight.c new file +40 -0
+
+#include <linux/backlight.h>
+#include <linux/err.h>
+#include <linux/gpio/consumer.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <drm/drm_dp_helper.h>
+
+#define DP_AUX_MAX_BRIGHTNESS          0xffff
+
+/**
+ * struct dp_aux_backlight - DisplayPort aux backlight data
+ * @dev: pointer to our device.
+ * @aux: the DisplayPort aux channel.
+ * @enable_gpio: the backlight enable gpio.
+ * @enabled: true if backlight is enabled else false.
+ */
+struct dp_aux_backlight {
+       struct device *dev;
+       struct drm_dp_aux *aux;
+       struct gpio_desc *enable_gpio;
+       bool enabled;
+};
+
+static struct drm_dp_aux *i2c_to_aux(struct i2c_adapter *i2c)
+{
+       return container_of(i2c, struct drm_dp_aux, ddc);
+}
+
+static int dp_aux_backlight_enable(struct dp_aux_backlight *aux_bl)
+{
+       u8 val = 0;
+       int ret;
+
+       if (aux_bl->enabled)
+               return 0;
+
+       /* Set backlight control mode */
+       ret = drm_dp_dpcd_readb(aux_bl->aux,

DP_EDP_BACKLIGHT_MODE_SET_REGISTER,
+                               &val);
+       if (ret < 0)
+               return ret;
+
+       val &= ~DP_EDP_BACKLIGHT_CONTROL_MODE_MASK; +       val |= DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD; +       ret = drm_dp_dpcd_writeb(aux_bl->aux, DP_EDP_BACKLIGHT_MODE_SET_REGISTER,
+                                val);
+       if (ret < 0)
+               return ret;
+
+       /* Enable backlight */
+       ret = drm_dp_dpcd_readb(aux_bl->aux, DP_EDP_DISPLAY_CONTROL_REGISTER,
+                               &val);
+       if (ret < 0)
+               return ret;
+
+       val |= DP_EDP_BACKLIGHT_ENABLE;
+       ret = drm_dp_dpcd_writeb(aux_bl->aux, DP_EDP_DISPLAY_CONTROL_REGISTER,
+                                val);
+       if (ret < 0)
+               return ret;

drivers/video/backlight/dp_aux_backlight.c new file +21 -0
+
+       if (aux_bl->enable_gpio)
+               gpiod_set_value(aux_bl->enable_gpio, 1);
+
+       aux_bl->enabled = true;
+
+       return 0;
+}
+
+static int dp_aux_backlight_disable(struct dp_aux_backlight *aux_bl)
+{
+       u8 val = 0;
+       int ret;
+
+       if (!aux_bl->enabled)
+               return 0;
+
+       if (aux_bl->enable_gpio)
+               gpiod_set_value(aux_bl->enable_gpio, 0);
+
+       ret = drm_dp_dpcd_readb(aux_bl->aux,

DP_EDP_DISPLAY_CONTROL_REGISTER,
+                               &val);
+       if (ret < 0)
+               return ret;
+
+       val &= ~DP_EDP_BACKLIGHT_ENABLE;
+       ret = drm_dp_dpcd_writeb(aux_bl->aux,
DP_EDP_DISPLAY_CONTROL_REGISTER,
+                                val);
+       if (ret < 0)
+               return ret;

drivers/video/backlight/dp_aux_backlight.c new file +17 -0
+
+       aux_bl->enabled = false;
+
+       return 0;
+}
+
+static int dp_aux_backlight_update_status(struct backlight_device *bd)
+{
+       struct dp_aux_backlight *aux_bl = bl_get_data(bd);
+       u16 brightness = backlight_get_brightness(bd);
+       u8 val[2] = { 0x0 };
+       int ret = 0;
+
+       if (brightness > 0) {
+               val[0] = brightness >> 8;
+               val[1] = brightness & 0xff;
+               ret = drm_dp_dpcd_write(aux_bl->aux,

DP_EDP_BACKLIGHT_BRIGHTNESS_MSB,
+                                       val, sizeof(val)); +               if (ret < 0)
+                       return ret;

drivers/video/backlight/dp_aux_backlight.c new file +19 -0
+
+               dp_aux_backlight_enable(aux_bl);
+       } else {
+               dp_aux_backlight_disable(aux_bl);
+       }
+
+       return 0;
+}
+
+static int dp_aux_backlight_get_brightness(struct backlight_device *bd)
+{
+       struct dp_aux_backlight *aux_bl = bl_get_data(bd);
+       u8 val[2] = { 0x0 };
+       int ret = 0;
+
+       if (backlight_is_blank(bd))
+               return 0;
+
+       ret = drm_dp_dpcd_read(aux_bl->aux,

DP_EDP_BACKLIGHT_BRIGHTNESS_MSB,
+                              &val, sizeof(val)); +       if (ret < 0)
+               return ret;

drivers/video/backlight/dp_aux_backlight.c new file +41 -0
+
+       return (val[0] << 8 | val[1]);
+}
+
+static const struct backlight_ops aux_bl_ops = {
+       .update_status = dp_aux_backlight_update_status,
+       .get_brightness = dp_aux_backlight_get_brightness,
+};
+
+
+static int dp_aux_backlight_probe(struct platform_device *pdev)
+{
+       struct dp_aux_backlight *aux_bl;
+       struct backlight_device *bd;
+       struct backlight_properties bl_props = { 0 };
+       struct device_node *np;
+       struct i2c_adapter *ddc;
+       int ret = 0;
+       u32 val;
+
+       aux_bl = devm_kzalloc(&pdev->dev, sizeof(*aux_bl), GFP_KERNEL);
+       if (!aux_bl)
+               return -ENOMEM;
+
+       aux_bl->dev = &pdev->dev;
+
+       np = of_parse_phandle(pdev->dev.of_node, "ddc-i2c-bus", 0);
+       if (!np) {
+               dev_err(&pdev->dev, "failed to get aux ddc I2C bus\n");
+               return -ENODEV;
+       }
+
+       ddc = of_find_i2c_adapter_by_node(np);
+       of_node_put(np);
+       if (!ddc)
+               return -EPROBE_DEFER;
+
+       aux_bl->aux = i2c_to_aux(ddc);
+       dev_dbg(&pdev->dev, "using dp aux %s\n", aux_bl->aux->name);
+
+       aux_bl->enable_gpio = devm_gpiod_get_optional(&pdev->dev,

"enable",
+                                            GPIOD_OUT_LOW); +       if (IS_ERR(aux_bl->enable_gpio)) {
+               ret = PTR_ERR(aux_bl->enable_gpio); +               goto free_ddc;
+       }

drivers/video/backlight/dp_aux_backlight.c new file +10 -0
+
+       val = DP_AUX_MAX_BRIGHTNESS;
+       of_property_read_u32(pdev->dev.of_node, "max-brightness", &val);
+       if (val > DP_AUX_MAX_BRIGHTNESS)
+               val = DP_AUX_MAX_BRIGHTNESS;
+
+       bl_props.max_brightness = val;
+       bl_props.brightness = val;
+       bl_props.type = BACKLIGHT_RAW;
+       bd = devm_backlight_device_register(&pdev->dev, dev_name(&pdev-
Quoted 1 line

dev),

+                                           &pdev->dev, aux_bl, +                                           &aux_bl_ops, &bl_props); +       if (IS_ERR(bd)) {
+               ret = PTR_ERR(bd);
+               dev_err(&pdev->dev,
+                             "failed to register backlight (%d)\n", ret); +               goto free_ddc;
+       }

drivers/video/backlight/dp_aux_backlight.c new file +43 -0
+
+       platform_set_drvdata(pdev, bd);
+
+       return 0;
+
+free_ddc:
+       if (ddc)
+               put_device(&ddc->dev);
+
+       return ret;
+}
+
+static int dp_aux_backlight_remove(struct platform_device *pdev)
+{
+       struct backlight_device *bd = platform_get_drvdata(pdev);
+       struct dp_aux_backlight *aux_bl = bl_get_data(bd);
+       struct i2c_adapter *ddc = &aux_bl->aux->ddc;
+
+       if (ddc)
+               put_device(&ddc->dev);
+
+       return 0;
+}
+
+static const struct of_device_id dp_aux_bl_of_match_table[] = {
+       { .compatible = "dp-aux-backlight"},
+       {},
+};
+MODULE_DEVICE_TABLE(of, dp_aux_bl_of_match_table);
+
+static struct platform_driver dp_aux_backlight_driver = {
+       .driver = {
+               .name = "dp-aux-backlight",
+               .of_match_table = dp_aux_bl_of_match_table,
+       },
+       .probe = dp_aux_backlight_probe,
+       .remove = dp_aux_backlight_remove,
+
+};
+module_platform_driver(dp_aux_backlight_driver);
+
+MODULE_DESCRIPTION("DisplayPort aux backlight driver");
+MODULE_LICENSE("GPL v2");
Signature · 3 lines
Cheers,
 Lyude Paul (she/her)
 Software Engineer at Red Hat