aBUGSworstnightmare
Posts: 3635
Joined: Tue Jun 30, 2015 1:35 pm

[Solved] Overlay with PCA9538 and PCA9632

Sun Sep 12, 2021 11:31 am

Fighting my way through device tree overlay again, looking for advice how to initialize/configure a NXP PCA953x - I'm using a PCA9538 in my design - in the proper/correct way.

Below is the source code of my overlay (still work in progress):

Code: Select all

/*
 * vc4-kms-dsi-sn65dsi8x-overlay.dts
 */

/dts-v1/;
/plugin/;
#include <dt-bindings/gpio/gpio.h>

/ {
	compatible = "brcm,bcm2835";

	/* PCA9538 GPIO expander, address 0x73 */
	fragment@0 {
		/*target = <&i2c_csi_dsi>;*/
		target = <&i2c0>;
		__overlay__ {
			#address-cells = <1>;
			#size-cells = <0>;
			status = "okay";

			pca: pca@73 {
				compatible = "nxp,pca9538";
				reg = <0x73>;
				gpio-controller;
				#gpio-cells = <2>;
				gpio-line-names = "UNUSED",
				  "BLEN_1",
				  "AUX1_2",
				  "AUX1-1",
				  "AUX2_2",
				  "AUX2_1",
				  "BLEN_2",
				  "EN_PCA";
				status = "okay";
				
				unused: unused {
					gpio-hog;
					gpios = <0 GPIO_ACTIVE_HIGH>;
					output-low;
				};

				aux12: aux12 {
					gpio-hog;
					gpios = <2 GPIO_ACTIVE_HIGH>;
					output-low;
				};
				
				aux11: aux11 {
					gpio-hog;
					gpios = <3 GPIO_ACTIVE_HIGH>;
					output-high;
				};

				aux22: aux22 {
					gpio-hog;
					gpios = <4 GPIO_ACTIVE_HIGH>;
					output-high;
				};
				
				aux21: aux21 {
					gpio-hog;
					gpios = <5 GPIO_ACTIVE_HIGH>;
					output-low;
				};
			};
		};
	};
	
	/* PWM0 function */
	fragment@1 {
		target = <&gpio>;
		__overlay__ {
			pwm_pins: pwm_pins {
				brcm,pins = <12>;
				brcm,function = <4>; /* Alt1 */
			};
		};
	};

	fragment@2 {
		target = <&pwm>;
		frag1: __overlay__ {
			pinctrl-names = "default";
			pinctrl-0 = <&pwm_pins>;
			assigned-clock-rates = <100000000>;
			status = "okay";
		};
	};

	fragment@3 {
		target-path = "/";
		__overlay__ {
			//#gpio-cells = <2>;
			/* Panel backlight through PWM0 on GPIO 12 */
			backlight_lvds: backlight {
				compatible = "pwm-backlight";
				pwms = <&pwm 0 5000000>; /* Period of 5000000ns means 200Hz */
				brightness-levels = <0  1000>;
				num-interpolated-steps = <1000>;
				default-brightness-level = <800>;
				enable-gpios  = <&pca 6 0>; /* Backlight enable... */
			};

			panel: panel {
				compatible = "chunghwa,claa070wp03xglvds", "simple-panel";
				backlight = <&backlight_lvds>;

				port {
					panel_in_lvds: endpoint {
						remote-endpoint = <&bridge_out>;
					};
				};
			};
		};
	};

	fragment@4 {
		/*target = <&i2c_csi_dsi>;*/
		target = <&i2c0>;
		__overlay__ {
			#gpio-cells = <2>;
			#address-cells = <1>;
			#size-cells = <0>;
			status = "okay";
			
			bridge@2c {
				compatible = "ti,sn65dsi83";
				reg = <0x2c>;
				enable-gpios  = <&pca 7 0>;

				ports {
					#address-cells = <1>;
					#size-cells = <0>;

					port@0 {
						reg = <0>;
						bridge_in: endpoint {
							remote-endpoint = <&dsi_out_port>;
							data-lanes = <0 1 2>;
						};
					};

					port@2 {
						reg = <2>;
						bridge_out: endpoint {
							remote-endpoint = <&panel_in_lvds>;
						};
					};
				};
			};
		};
	};

	fragment@5 {
		target = <&dsi1>;
		__overlay__ {
			#address-cells = <1>;
			#size-cells = <0>;
			status = "okay";
			port {
				dsi_out_port: endpoint {
					remote-endpoint = <&bridge_in>;
					data-lanes = <0 1 2>;
				};
			};
		};
	};

	/*fragment@6 {
		target = <&i2c0if>;
		__overlay__ {
			status = "okay";
		};
	};*/
		
	/*fragment@7 {
		target = <&i2c0mux>;
		__overlay__ {
			status = "okay";
		};
	};*/
};
I've initialized my PCA9538 at address 0x73 like below, with some outputs to be used as configuration signals later.

Code: Select all

			pca: pca@73 {
				compatible = "nxp,pca9538";
				reg = <0x73>;
				gpio-controller;
				#gpio-cells = <2>;
				gpio-line-names = "UNUSED",
				  "BLEN_1",
				  "AUX1_2",
				  "AUX1-1",
				  "AUX2_2",
				  "AUX2_1",
				  "BLEN_2",
				  "EN_PCA";
				status = "okay";
				
				unused: unused {
					gpio-hog;
					gpios = <0 GPIO_ACTIVE_HIGH>;
					output-low;
				};

				aux12: aux12 {
					gpio-hog;
					gpios = <2 GPIO_ACTIVE_HIGH>;
					output-low;
				};
				
				aux11: aux11 {
					gpio-hog;
					gpios = <3 GPIO_ACTIVE_HIGH>;
					output-high;
				};

				aux22: aux22 {
					gpio-hog;
					gpios = <4 GPIO_ACTIVE_HIGH>;
					output-high;
				};
				
				aux21: aux21 {
					gpio-hog;
					gpios = <5 GPIO_ACTIVE_HIGH>;
					output-low;
				};
			};
	
Above signals will have to receive override possibility later, as they are intended to switch/configure LVDS data mapping or display scan direction, without the need for recompiling the overlay.

I have some other outputs which are under kernel control and will be used by certain drivers, i.e. as enable signal for backlights or the SN65DSI8x bridge on my board.
I've decided for a simpler initialization for these signals as below i.e.

Code: Select all

			...
			bridge@2c {
				compatible = "ti,sn65dsi83";
				reg = <0x2c>;
				enable-gpios  = <&pca 7 0>;
				...
On first view everything seems to work, but I would like to understand:
- what is the best way for configuring the PCA I/O?
- what is the difference and/or benefit/disadvantage of my approach?
- how will the 'gpio-line-names' be used by the kernel (if at all)?

Bellow is some output for reference:

Code: Select all

pi@raspberrypi:~ $ sudo i2cdetect -y 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          03 -- -- -- -- -- -- -- -- 0c -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- UU -- -- 2f 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- 51 -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- 62 -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: 70 -- -- UU -- -- -- --                         
pi@raspberrypi:~ $ ls /sys/bus/i2c/drivers
dummy  pca953x  sn65dsi83  stmpe-i2c
pi@raspberrypi:~ $ i2cdump -f -y 0 0x73
No size specified (using byte-data access)
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: d8 da 00 02 XX XX XX XX XX XX XX XX XX XX XX XX    ??.?XXXXXXXXXXXX
..
pi@raspberrypi:~ $ 
As one can see:
1) I2C address 0x73 = PCA9538 is claimed by the kernel.
2) The driver for pca953x is loaded. Would also like to know what is responsible for the 'dummy' and the 'stmpe-i2c' driver.
3) PCA9538 register 0x03 is configuration register, 0x02 means only IO1 is configure as input (0=output, 1=input) which is fully correct, as it is not configured by the overlay yet.
Register 0x01 is the output port register, reflecting outgoing logic level. It's value is 0xda = 0b11011010 which is also in-line with my expectations (IO0/IO2/IO5=zero '0' as per initialization; IO1 =1 as it's unconfigured, IO6/IO7 should be one as used by the drivers (and configured to 1=active high).

So, on first view everything seems to work.
But, still looking for advice if I'm on the right track for this. Also would like to know how I need to specify the '__overrides__ {.. }' section in the overlay for Aux1-1 to Aux2-2.

Looking forward to your replays.
Last edited by aBUGSworstnightmare on Thu Sep 16, 2021 11:04 am, edited 1 time in total.

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 4132
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: Overlay with PCA9538 - looking for advice how to initialize/configure I/O

Mon Sep 13, 2021 8:08 am

- what is the best way for configuring the PCA I/O?
If by this you mean the pins that you've assigned gpio-hogs to, that would be the recommended way if they are meant to have fixed values for the lifetime of the kernel. If the values may need to be changed at runtime. and if the drive strength is not a problem, then you may get away with configuring them as inputs with pulls in the appropriate direction.
- what is the difference and/or benefit/disadvantage of my approach?
I've partially covered this already, in that pins with gpio-hogs cannot be changed except by going behind the kernel's back. The syntax is also a bit verbose, but that is the modern GPIO DT style.
- how will the 'gpio-line-names' be used by the kernel (if at all)?
I think it's mainly to add some annotations to the output of gpioinfo (from the "gpiod" apt package), but you can use "gpiofind" to look up a name, and the output is suitable for use in gpioset/get commands:

Code: Select all

gpioset --mode=wait `gpiofind "BLEN_2"`=1
Note that the effects of gpioset are not guaranteed to persist after they exit - the value is supposed to return to the default.

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 4132
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: Overlay with PCA9538 - looking for advice how to initialize/configure I/O

Mon Sep 13, 2021 8:27 am

Also would like to know how I need to specify the '__overrides__ {.. }' section in the overlay for Aux1-1 to Aux2-2.
This isn't so simple because the options ("output-high" and "output-low") are boolean properties - true if present, false if absent, and there is no way to delete a property from an overlay.

Fortunately you are adding new booleans rather than trying to overwrite existing ones, and the overlay parameter mechanism allows fragments to be enabled and disabled. To avoid unnecessary duplication I would extract the output state from the declarations and add two additional fragments containing the values - one enabled and one disabled:

Code: Select all

				aux12: aux12 {
					gpio-hog;
					gpios = <2 GPIO_ACTIVE_HIGH>;
				};
...

	fragment@10 {
		target = <&aux12>;
		__overlay__ {
			output-low;
		};
	};

	fragment@11 {
		target = <&aux12>;
		__dormant__ {
			output-high;
		};
	};

	__overrides__ {
		aux12_low = <0>,"+10-11";
		aux12_high = <0>,"-10+11";
		...
	};
};
Fragments 10 and 11 modify the main gpio fragment (they are "intra-overlay fragments"), and that modification has to happen before the target fragment gets merged into the base DTB. The overlay applications works in two passes, merging intra- fragments before fragments that target the base, but the way to avoid any merge order problems is to write the fragments in the order in which they should be applied (references to labels further down the overlay are allowed).

aBUGSworstnightmare
Posts: 3635
Joined: Tue Jun 30, 2015 1:35 pm

Re: Overlay with PCA9538 - looking for advice how to initialize/configure I/O

Mon Sep 13, 2021 11:27 am

PhilE wrote:
Mon Sep 13, 2021 8:27 am
Also would like to know how I need to specify the '__overrides__ {.. }' section in the overlay for Aux1-1 to Aux2-2.
This isn't so simple because the options ("output-high" and "output-low") are boolean properties - true if present, false if absent, and there is no way to delete a property from an overlay.

Fortunately you are adding new booleans rather than trying to overwrite existing ones, and the overlay parameter mechanism allows fragments to be enabled and disabled. To avoid unnecessary duplication I would extract the output state from the declarations and add two additional fragments containing the values - one enabled and one disabled:

Code: Select all

				aux12: aux12 {
					gpio-hog;
					gpios = <2 GPIO_ACTIVE_HIGH>;
				};
...

	fragment@10 {
		target = <&aux12>;
		__overlay__ {
			output-low;
		};
	};

	fragment@11 {
		target = <&aux12>;
		__dormant__ {
			output-high;
		};
	};

	__overrides__ {
		aux12_low = <0>,"+10-11";
		aux12_high = <0>,"-10+11";
		...
	};
};
Fragments 10 and 11 modify the main gpio fragment (they are "intra-overlay fragments"), and that modification has to happen before the target fragment gets merged into the base DTB. The overlay applications works in two passes, merging intra- fragments before fragments that target the base, but the way to avoid any merge order problems is to write the fragments in the order in which they should be applied (references to labels further down the overlay are allowed).
Thank PhilE, I think I get the point.
Amended the overlay like below, keeping the initialization for the unused (NC) pin and adding new fragments for the auxx-x control signals.

Code: Select all

/*
 * vc4-kms-dsi-sn65dsi8x-overlay.dts
 */

/dts-v1/;
/plugin/;
#include <dt-bindings/gpio/gpio.h>

/ {
	compatible = "brcm,bcm2835";

	/* PCA9538 GPIO expander, address 0x73 */
	fragment@0 {
		/*target = <&i2c_csi_dsi>;*/
		target = <&i2c0>;
		__overlay__ {
			#address-cells = <1>;
			#size-cells = <0>;
			status = "okay";

			pca: pca@73 {
				compatible = "nxp,pca9538";
				reg = <0x73>;
				gpio-controller;
				#gpio-cells = <2>;
				gpio-line-names = "UNUSED",
				  "BLEN_1",
				  "AUX1_2",
				  "AUX1-1",
				  "AUX2_2",
				  "AUX2_1",
				  "BLEN_2",
				  "EN_PCA";
				status = "okay";
				
				unused: unused {
					gpio-hog;
					gpios = <0 GPIO_ACTIVE_HIGH>;
					output-low;
				};

				aux12: aux12 {
					gpio-hog;
					gpios = <2 GPIO_ACTIVE_HIGH>;
				};
				
				aux11: aux11 {
					gpio-hog;
					gpios = <3 GPIO_ACTIVE_HIGH>;
				};

				aux22: aux22 {
					gpio-hog;
					gpios = <4 GPIO_ACTIVE_HIGH>;
				};
				
				aux21: aux21 {
					gpio-hog;
					gpios = <5 GPIO_ACTIVE_HIGH>;
				};
			};
		};
	};
	
	/* PWM0 function */
	fragment@1 {
		target = <&gpio>;
		__overlay__ {
			pwm_pins: pwm_pins {
				brcm,pins = <12>;
				brcm,function = <4>; /* Alt1 */
			};
		};
	};

	fragment@2 {
		target = <&pwm>;
		frag1: __overlay__ {
			pinctrl-names = "default";
			pinctrl-0 = <&pwm_pins>;
			assigned-clock-rates = <100000000>;
			status = "okay";
		};
	};

	fragment@3 {
		target-path = "/";
		__overlay__ {
			//#gpio-cells = <2>;
			/* Panel backlight through PWM0 on GPIO 12 */
			backlight_lvds: backlight {
				compatible = "pwm-backlight";
				pwms = <&pwm 0 5000000>; /* Period of 5000000ns means 200Hz */
				brightness-levels = <0  1000>;
				num-interpolated-steps = <1000>;
				default-brightness-level = <800>;
				enable-gpios  = <&pca 6 0>; /* Backlight enable... */
			};

			panel: panel {
				compatible = "chunghwa,claa070wp03xglvds", "simple-panel";
				backlight = <&backlight_lvds>;

				port {
					panel_in_lvds: endpoint {
						remote-endpoint = <&bridge_out>;
					};
				};
			};
		};
	};

	fragment@4 {
		/*target = <&i2c_csi_dsi>;*/
		target = <&i2c0>;
		__overlay__ {
			#gpio-cells = <2>;
			#address-cells = <1>;
			#size-cells = <0>;
			status = "okay";
			
			bridge@2c {
				compatible = "ti,sn65dsi83";
				reg = <0x2c>;
				enable-gpios  = <&pca 7 0>;

				ports {
					#address-cells = <1>;
					#size-cells = <0>;

					port@0 {
						reg = <0>;
						bridge_in: endpoint {
							remote-endpoint = <&dsi_out_port>;
							data-lanes = <0 1 2>;
						};
					};

					port@2 {
						reg = <2>;
						bridge_out: endpoint {
							remote-endpoint = <&panel_in_lvds>;
						};
					};
				};
			};
		};
	};

	fragment@5 {
		target = <&dsi1>;
		__overlay__ {
			#address-cells = <1>;
			#size-cells = <0>;
			status = "okay";
			port {
				dsi_out_port: endpoint {
					remote-endpoint = <&bridge_in>;
					data-lanes = <0 1 2>;
				};
			};
		};
	};

	/*fragment@6 {
		target = <&i2c0if>;
		__overlay__ {
			status = "okay";
		};
	};*/
		
	/*fragment@7 {
		target = <&i2c0mux>;
		__overlay__ {
			status = "okay";
		};
	};*/	
	
	fragment@10 {
		target = <&aux11>;
		__overlay__ {
			output-low;
		};
	};

	fragment@11 {
		target = <&aux11>;
		__dormant__ {
			output-high;
		};
	};
	
	fragment@12 {
		target = <&aux12>;
		__overlay__ {
			output-low;
		};
	};

	fragment@13 {
		target = <&aux12>;
		__dormant__ {
			output-high;
		};
	};
	
	fragment@14 {
		target = <&aux21>;
		__overlay__ {
			output-low;
		};
	};

	fragment@15 {
		target = <&aux21>;
		__dormant__ {
			output-high;
		};
	};
	
	fragment@16 {
		target = <&aux22>;
		__overlay__ {
			output-low;
		};
	};

	fragment@17 {
		target = <&aux22>;
		__dormant__ {
			output-high;
		};
	};
			
	__overrides__ {
		aux11_low = <0>,"+10-11";
		aux11_high = <0>,"-10+11";
		aux12_low = <0>,"+12-13";
		aux12_high = <0>,"-12+13";
		aux21_low = <0>,"+14-15";
		aux21_high = <0>,"-14+15";
		aux22_low = <0>,"+16-17";
		aux22_high = <0>,"-16+17";				
	};	


};
The overlay will now onfigure the AUXx-x signals to LOW (default) when no parameter is added to the command in config.txt.
Using the overlay like in the example below should invoke fragment 11 and disable fragment 10 --> aux1-1 will be initialized to HIGH, correct?

Code: Select all

dtoverlay=vc4-kms-dsi-ti-sn65dsi83,aux11_high=1
At least this it what I get:

Code: Select all

pi@raspberrypi:~ $ i2cdump -f -y 0 0x73
No size specified (using byte-data access)
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: c8 ca 00 02 XX XX XX XX XX XX XX XX XX XX XX XX    ??.?XXXXXXXXXXXX
..
Output register 0x03 shows all IO configured to output (except IO1, 'cause it's untouched atm)
Output port register becomes 0xca = 0b1100 1010 --> IO3 = aux1-1 is HIGH --> that's what is should be! So, looks like a success!

Thanks for the moment!

Btw .. reason why IO1 is still untouched is the fact that I need to work on the DSI8x driver first to allow for dual DSI output from the Pi. IO1 will be used as backlight enable later. I'm pulling my new HW out of the swamps atm ..
IMG_20210913_132018.jpg
MIPI2LVDS EVO - will hopefully allow for dual DSI output from the CM4.
Does not require ANY GPIO pin thanks to the PCA9538 IO-expander
IMG_20210913_132018.jpg (124.55 KiB) Viewed 1299 times

aBUGSworstnightmare
Posts: 3635
Joined: Tue Jun 30, 2015 1:35 pm

How to use PCA9632 for backlight control

Mon Sep 13, 2021 1:32 pm

Thanks to PhilE I could make some progress in the overlay. After adding the next device to it - a NXP PCA9632 4-channel LED controller - I've hit a wall again, struggling to figure out how to replace the GPIO PWM backlight control with 'bl1pwm' (channel0 PWM from PCA9632).

My latest overlay source is:

Code: Select all

/*
 * vc4-kms-dsi-sn65dsi8x-overlay.dts
 */

/dts-v1/;
/plugin/;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/leds/leds-pca9532.h>

/ {
	compatible = "brcm,bcm2835";

	/* PCA9538 GPIO expander, address 0x73 */
	fragment@0 {
		/*target = <&i2c_csi_dsi>;*/
		target = <&i2c0>;
		__overlay__ {
			#address-cells = <1>;
			#size-cells = <0>;
			status = "okay";

			pca: pca@73 {
				compatible = "nxp,pca9538";
				reg = <0x73>;
				gpio-controller;
				#gpio-cells = <2>;
				gpio-line-names = "UNUSED",
				  "BLEN_1",
				  "AUX1_2",
				  "AUX1-1",
				  "AUX2_2",
				  "AUX2_1",
				  "BLEN_2",
				  "EN_PCA";
				status = "okay";
				
				unused: unused {
					gpio-hog;
					gpios = <0 GPIO_ACTIVE_HIGH>;
					output-low;
				};

				aux12: aux12 {
					gpio-hog;
					gpios = <2 GPIO_ACTIVE_HIGH>;
				};
				
				aux11: aux11 {
					gpio-hog;
					gpios = <3 GPIO_ACTIVE_HIGH>;
				};

				aux22: aux22 {
					gpio-hog;
					gpios = <4 GPIO_ACTIVE_HIGH>;
				};
				
				aux21: aux21 {
					gpio-hog;
					gpios = <5 GPIO_ACTIVE_HIGH>;
				};
			};
		};
	};

	/* PCA9632 LED driver, address 0x62 */
	fragment@1 {
		/*target = <&i2c_csi_dsi>;*/
		target = <&i2c0>;
		__overlay__ {
			#address-cells = <1>;
			#size-cells = <0>;
			status = "okay";

			pca9632: pca9632@62 {
				compatible = "nxp,pca9632";
				#address-cells = <1>;
				#size-cells = <0>;
				#pwm-cells = <2>;
				reg = <0x62>;

				bl1pwm@0 {
					label = "bl1pwm";
					reg = <0>;
					type = <PCA9532_TYPE_LED>;
					linux,default-trigger = "backlight";
				};
				bl2pwm@1 {
					label = "bl2pwm";
					reg = <1>;
					type = <PCA9532_TYPE_LED>;
					linux,default-trigger = "backlight";
				};
				unused2@2 {
					label = "unused2";
					reg = <2>;
					type = <PCA9532_TYPE_NONE>;
					linux,default-trigger = "none";
				};
				unused3@3 {
					label = "unused3";
					reg = <3>;
					type = <PCA9532_TYPE_NONE>;
					linux,default-trigger = "none";
				};
			};
		};
	};

	/* PWM0 function */
	fragment@2 {
		target = <&gpio>;
		__overlay__ {
			pwm_pins: pwm_pins {
				brcm,pins = <12>;
				brcm,function = <4>;
			};
		};
	};

	fragment@3 {
		target = <&pwm>;
		frag1: __overlay__ {
			pinctrl-names = "default";
			pinctrl-0 = <&pwm_pins>;
			assigned-clock-rates = <100000000>;
			status = "okay";
		};
	};

	fragment@4 {
		target-path = "/";
		__overlay__ {
			//#gpio-cells = <2>;
			/* Panel backlight through PWM0 on GPIO 12 */
			backlight_lvds: backlight {
				compatible = "pwm-backlight";
				pwms = <&pwm 0 5000000>; /* Period of 5000000ns means 200Hz */
				brightness-levels = <0  1000>;
				num-interpolated-steps = <1000>;
				 default-brightness-level = <800>;

				enable-gpios  = <&pca 6 0>; /* Backlight enable... */
			};

			panel: panel {
				compatible = "chunghwa,claa070wp03xglvds", "simple-panel";
				backlight = <&backlight_lvds>;

				port {
					panel_in_lvds: endpoint {
						remote-endpoint = <&bridge_out>;
					};
				};
			};
		};
	};

	fragment@5 {
		/*target = <&i2c_csi_dsi>;*/
		target = <&i2c0>;
		__overlay__ {
			#gpio-cells = <2>;
			#address-cells = <1>;
			#size-cells = <0>;
			status = "okay";
			
			bridge@2c {
				compatible = "ti,sn65dsi83";
				reg = <0x2c>;
				enable-gpios  = <&pca 7 0>;

				ports {
					#address-cells = <1>;
					#size-cells = <0>;

					port@0 {
						reg = <0>;
						bridge_in: endpoint {
							remote-endpoint = <&dsi_out_port>;
							data-lanes = <0 1 2>;
						};
					};

					port@2 {
						reg = <2>;
						bridge_out: endpoint {
							remote-endpoint = <&panel_in_lvds>;
						};
					};
				};
			};
		};
	};

	fragment@6 {
		target = <&dsi1>;
		__overlay__ {
			#address-cells = <1>;
			#size-cells = <0>;
			status = "okay";
			port {
				dsi_out_port: endpoint {
					remote-endpoint = <&bridge_in>;
					data-lanes = <0 1 2>;
				};
			};
		};
	};

	/*fragment@7 {
		target = <&i2c0if>;
		__overlay__ {
			status = "okay";
		};
	};*/
		
	/*fragment@8 {
		target = <&i2c0mux>;
		__overlay__ {
			status = "okay";
		};
	};*/	
	
	fragment@10 {
		target = <&aux11>;
		__overlay__ {
			output-low;
		};
	};

	fragment@11 {
		target = <&aux11>;
		__dormant__ {
			output-high;
		};
	};
	
	fragment@12 {
		target = <&aux12>;
		__overlay__ {
			output-low;
		};
	};

	fragment@13 {
		target = <&aux12>;
		__dormant__ {
			output-high;
		};
	};
	
	fragment@14 {
		target = <&aux21>;
		__overlay__ {
			output-low;
		};
	};

	fragment@15 {
		target = <&aux21>;
		__dormant__ {
			output-high;
		};
	};
	
	fragment@16 {
		target = <&aux22>;
		__overlay__ {
			output-low;
		};
	};

	fragment@17 {
		target = <&aux22>;
		__dormant__ {
			output-high;
		};
	};
			
	__overrides__ {
		aux11_low = <0>,"+10-11";
		aux11_high = <0>,"-10+11";
		aux12_low = <0>,"+12-13";
		aux12_high = <0>,"-12+13";
		aux21_low = <0>,"+14-15";
		aux21_high = <0>,"-14+15";
		aux22_low = <0>,"+16-17";
		aux22_high = <0>,"-16+17";				
	};	


};
The PCA9632 is at address 0x62, claimed by the kernel. The related driver is loaded, and the overlay looks like it gets applied correctly.

Code: Select all

pi@raspberrypi:~ $ sudo i2cdetect -y 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          03 -- -- -- -- -- -- -- -- 0c -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- UU -- -- 2f 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- 51 -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- UU -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- UU -- -- -- --                         
pi@raspberrypi:~ $ ls /sys/bus/i2c/drivers
dummy  leds-pca963x  pca953x  sn65dsi83  stmpe-i2c
pi@raspberrypi:~ $ cd /sys/class/leds
pi@raspberrypi:/sys/class/leds $ tree
.
├── default-on -> ../../devices/virtual/leds/default-on
├── led0 -> ../../devices/platform/leds/leds/led0
├── led1 -> ../../devices/platform/leds/leds/led1
├── mmc0 -> ../../devices/virtual/leds/mmc0
├── mmc0:: -> ../../devices/platform/emmc2bus/fe340000.emmc2/leds/mmc0::
├── pca963x:bl1pwm -> ../../devices/platform/soc/fe205000.i2c/i2c-0/0-0062/leds/pca963x:bl1pwm
├── pca963x:bl2pwm -> ../../devices/platform/soc/fe205000.i2c/i2c-0/0-0062/leds/pca963x:bl2pwm
├── pca963x:unused2 -> ../../devices/platform/soc/fe205000.i2c/i2c-0/0-0062/leds/pca963x:unused2
└── pca963x:unused3 -> ../../devices/platform/soc/fe205000.i2c/i2c-0/0-0062/leds/pca963x:unused3

9 directories, 0 files
pi@raspberrypi:/sys/class/leds $ 
so, my question is, how to change below portion of the overlay to make use of PCA9632 channel0?
Fragment2 will be dropped for sure (as no RPI GPIO will be needed any longer), but what about fragment3 and 'backlight_lvds' related setting form fragment4?

Code: Select all

...
	/* PWM0 function */
	fragment@2 {
		target = <&gpio>;
		__overlay__ {
			pwm_pins: pwm_pins {
				brcm,pins = <12>;
				brcm,function = <4>;
			};
		};
	};

	fragment@3 {
		target = <&pwm>;
		frag1: __overlay__ {
			pinctrl-names = "default";
			pinctrl-0 = <&pwm_pins>;
			assigned-clock-rates = <100000000>;
			status = "okay";
		};
	};

	fragment@4 {
		target-path = "/";
		__overlay__ {
			//#gpio-cells = <2>;
			/* Panel backlight through PWM0 on GPIO 12 */
			backlight_lvds: backlight {
				compatible = "pwm-backlight";
				pwms = <&pwm 0 5000000>; /* Period of 5000000ns means 200Hz */
				brightness-levels = <0  1000>;
				num-interpolated-steps = <1000>;
				 default-brightness-level = <800>;

				enable-gpios  = <&pca 6 0>; /* Backlight enable... */
			};
			...
Thanks in advance for your inputs!

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 4132
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: Overlay with PCA9538 - looking for advice how to initialize/configure I/O

Mon Sep 13, 2021 1:48 pm

Anything related to the node with the label pwm is no longer needed - this means fragments 2 and 3. The existing reference to pwm in fragment 4 has to be replaced with the new PWM provider - pca9632. Where the original PWM was index 0 from "pwm", the new one is index 0 from "pca9632", which should leave you with:

Code: Select all

			backlight_lvds: backlight {
				compatible = "pwm-backlight";
				pwms = <&pca9632 0 5000000>; /* Period of 5000000ns means 200Hz */
				brightness-levels = <0  1000>;
				num-interpolated-steps = <1000>;
				default-brightness-level = <800>;

				enable-gpios  = <&pca 6 0>; /* Backlight enable... */
			};

aBUGSworstnightmare
Posts: 3635
Joined: Tue Jun 30, 2015 1:35 pm

Re: Overlay with PCA9538 - looking for advice how to initialize/configure I/O

Tue Sep 14, 2021 3:27 pm

PhilE wrote:
Mon Sep 13, 2021 1:48 pm
Anything related to the node with the label pwm is no longer needed - this means fragments 2 and 3. The existing reference to pwm in fragment 4 has to be replaced with the new PWM provider - pca9632. Where the original PWM was index 0 from "pwm", the new one is index 0 from "pca9632", which should leave you with:

Code: Select all

			backlight_lvds: backlight {
				compatible = "pwm-backlight";
				pwms = <&pca9632 0 5000000>; /* Period of 5000000ns means 200Hz */
				brightness-levels = <0  1000>;
				num-interpolated-steps = <1000>;
				default-brightness-level = <800>;

				enable-gpios  = <&pca 6 0>; /* Backlight enable... */
			};
That was my first idea as well, but doing as such crashes the overlay. DSI is not started any longer; SSH access by WiFi is lost (connection refused).

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 4132
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: Overlay with PCA9538 - looking for advice how to initialize/configure I/O

Tue Sep 14, 2021 3:37 pm

Hmmm - the pca9632 driver is a leds driver, not a pwm driver and not even a GPIO driver. As such, what you are trying to do appears to be impossible without rewriting the driver.

aBUGSworstnightmare
Posts: 3635
Joined: Tue Jun 30, 2015 1:35 pm

Re: Overlay with PCA9538 - looking for advice how to initialize/configure I/O

Tue Sep 14, 2021 5:04 pm

PhilE wrote:
Tue Sep 14, 2021 3:37 pm
Hmmm - the pca9632 driver is a leds driver, not a pwm driver and not even a GPIO driver. As such, what you are trying to do appears to be impossible without rewriting the driver.
How would you do this in case of an LED, when the default_trigger is 'backlight'?
Why is a backlight - which is an array of LED - different from a single LED? Both were using a PWM for dimming.

Maybe I simply need to change it into "led-backlight" (https://github.com/raspberrypi/linux/bl ... light.yaml)

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 4132
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: Overlay with PCA9538 - looking for advice how to initialize/configure I/O

Wed Sep 15, 2021 7:43 am

That ought to work.

aBUGSworstnightmare
Posts: 3635
Joined: Tue Jun 30, 2015 1:35 pm

Re: Overlay with PCA9538 - looking for advice how to initialize/configure I/O

Wed Sep 15, 2021 11:32 am

still unable to get it to work.. think I'm messed up with the labels an/or don't know how to do it properly.

Here is my current overlay

Code: Select all

/*
 * vc4-kms-dsi-sn65dsi8x-overlay.dts
 */

/dts-v1/;
/plugin/;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/leds/common.h>

/ {
	compatible = "brcm,bcm2835";

	/* PCA9538 GPIO expander, address 0x73 */
	fragment@0 {
		/*target = <&i2c_csi_dsi>;*/
		target = <&i2c0>;
		__overlay__ {
			#address-cells = <1>;
			#size-cells = <0>;
			status = "okay";

			pca: pca@73 {
				compatible = "nxp,pca9538";
				reg = <0x73>;
				gpio-controller;
				#gpio-cells = <2>;
				gpio-line-names = "UNUSED",
				  "BLEN_1",
				  "AUX1_2",
				  "AUX1-1",
				  "AUX2_2",
				  "AUX2_1",
				  "BLEN_2",
				  "EN_PCA";
				status = "okay";
				
				unused: unused {
					gpio-hog;
					gpios = <0 GPIO_ACTIVE_HIGH>;
					output-low;
				};

				aux12: aux12 {
					gpio-hog;
					gpios = <2 GPIO_ACTIVE_HIGH>;
				};
				
				aux11: aux11 {
					gpio-hog;
					gpios = <3 GPIO_ACTIVE_HIGH>;
				};

				aux22: aux22 {
					gpio-hog;
					gpios = <4 GPIO_ACTIVE_HIGH>;
				};
				
				aux21: aux21 {
					gpio-hog;
					gpios = <5 GPIO_ACTIVE_HIGH>;
				};
			};
		};
	};

	/* PCA9632 LED driver, address 0x62 */
	fragment@1 {
		/*target = <&i2c_csi_dsi>;*/
		target = <&i2c0>;
		__overlay__ {
			#address-cells = <1>;
			#size-cells = <0>;
			status = "okay";

			pca9632: pca9632@62 {
				compatible = "nxp,pca9632";
				#address-cells = <1>;
				#size-cells = <0>;
				reg = <0x62>;

				bl1@0 {
					reg = <0>;
					function = LED_FUNCTION_BACKLIGHT;
					color = <LED_COLOR_ID_WHITE>;
					linux,default-trigger = "backlight";
					label = "bl1";
				};
				bl2@1 {
					reg = <1>;
					function = LED_FUNCTION_BACKLIGHT;
					color = <LED_COLOR_ID_WHITE>;
					linux,default-trigger = "backlight";
					label = "bl2";
				};
				led@2 {
					reg = <2>;
					linux,default-trigger = "none";
				};
				led@3 {
					reg = <3>;
					linux,default-trigger = "none";
				};
			};
		};
	};

	fragment@4 {
		target-path = "/";
		__overlay__ {
			/* Panel backlight through PCA9632 channel0 */
			backlight_lvds: backlight {
				compatible = "led-backlight";
				leds = <&bl1>;
				brightness-levels = <0 4 8 16 32 64 128 255>;
				default-brightness-level = <6>;
				
				/* enable through PCA9538 IO6 */
				enable-gpios  = <&pca 6 0>; /* Backlight enable... */
			};

			panel: panel {
				compatible = "chunghwa,claa070wp03xglvds", "simple-panel";
				backlight = <&backlight_lvds>;

				port {
					panel_in_lvds: endpoint {
						remote-endpoint = <&bridge_out>;
					};
				};
			};
		};
	};

	fragment@5 {
		/*target = <&i2c_csi_dsi>;*/
		target = <&i2c0>;
		__overlay__ {
			#gpio-cells = <2>;
			#address-cells = <1>;
			#size-cells = <0>;
			status = "okay";
			
			bridge@2c {
				compatible = "ti,sn65dsi83";
				reg = <0x2c>;
				enable-gpios  = <&pca 7 0>;

				ports {
					#address-cells = <1>;
					#size-cells = <0>;

					port@0 {
						reg = <0>;
						bridge_in: endpoint {
							remote-endpoint = <&dsi_out_port>;
							data-lanes = <0 1 2>;
						};
					};

					port@2 {
						reg = <2>;
						bridge_out: endpoint {
							remote-endpoint = <&panel_in_lvds>;
						};
					};
				};
			};
		};
	};

	fragment@6 {
		target = <&dsi1>;
		__overlay__ {
			#address-cells = <1>;
			#size-cells = <0>;
			status = "okay";
			port {
				dsi_out_port: endpoint {
					remote-endpoint = <&bridge_in>;
					data-lanes = <0 1 2>;
				};
			};
		};
	};

	/*fragment@7 {
		target = <&i2c0if>;
		__overlay__ {
			status = "okay";
		};
	};*/
		
	/*fragment@8 {
		target = <&i2c0mux>;
		__overlay__ {
			status = "okay";
		};
	};*/	
	
	fragment@10 {
		target = <&aux11>;
		__overlay__ {
			output-low;
		};
	};

	fragment@11 {
		target = <&aux11>;
		__dormant__ {
			output-high;
		};
	};
	
	fragment@12 {
		target = <&aux12>;
		__overlay__ {
			output-low;
		};
	};

	fragment@13 {
		target = <&aux12>;
		__dormant__ {
			output-high;
		};
	};
	
	fragment@14 {
		target = <&aux21>;
		__overlay__ {
			output-low;
		};
	};

	fragment@15 {
		target = <&aux21>;
		__dormant__ {
			output-high;
		};
	};
	
	fragment@16 {
		target = <&aux22>;
		__overlay__ {
			output-low;
		};
	};

	fragment@17 {
		target = <&aux22>;
		__dormant__ {
			output-high;
		};
	};
			
	__overrides__ {
		aux11_low = <0>,"+10-11";
		aux11_high = <0>,"-10+11";
		aux12_low = <0>,"+12-13";
		aux12_high = <0>,"-12+13";
		aux21_low = <0>,"+14-15";
		aux21_high = <0>,"-14+15";
		aux22_low = <0>,"+16-17";
		aux22_high = <0>,"-16+17";				
	};	


};
compiles fine, but trying to use it failed because of an unresolved label.

Code: Select all

pi@raspberrypi:~ $ sudo vcdbg log msg
...
006924.444: brfs: File read: 1785 bytes
006941.207: dtdebug: Opened overlay file 'overlays/vc4-kms-dsi-ti-sn65dsi83.dtbo'
006942.569: brfs: File read: /mfs/sd/overlays/vc4-kms-dsi-ti-sn65dsi83.dtbo
006950.771: dterror: can't find symbol 'bl1'
006950.782: Failed to resolve overlay 'vc4-kms-dsi-ti-sn65dsi83'
006959.285: brfs: File read: 5241 bytes...
What am I missing here?

6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 11850
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Re: Overlay with PCA9538 - looking for advice how to initialize/configure I/O

Wed Sep 15, 2021 12:23 pm

You have no symbol called <bl1>

Code: Select all

				bl1: bl1@0 { <<<<<<<
					reg = <0>;
					function = LED_FUNCTION_BACKLIGHT;
					color = <LED_COLOR_ID_WHITE>;
					linux,default-trigger = "backlight";
					label = "bl1";
				};
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

aBUGSworstnightmare
Posts: 3635
Joined: Tue Jun 30, 2015 1:35 pm

Re: Overlay with PCA9538 - looking for advice how to initialize/configure I/O

Wed Sep 15, 2021 12:54 pm

6by9 wrote:
Wed Sep 15, 2021 12:23 pm
You have no symbol called <bl1>

Code: Select all

				bl1: bl1@0 { <<<<<<<
					reg = <0>;
					function = LED_FUNCTION_BACKLIGHT;
					color = <LED_COLOR_ID_WHITE>;
					linux,default-trigger = "backlight";
					label = "bl1";
				};
Thanks! That solves the issue as the overlay now gets applied correctly.
Will grab a scope and see what comes out of PCA9632 channel 0 after init and when I try to change duty.

aBUGSworstnightmare
Posts: 3635
Joined: Tue Jun 30, 2015 1:35 pm

Re: Overlay with PCA9538 - looking for advice how to initialize/configure I/O

Wed Sep 15, 2021 1:56 pm

O.k. I see the PWM and changing duty (only 8 possible settings for starting with) is working.

Code: Select all

pi@raspberrypi:~ $ sudo -i

SSH is enabled and the default password for the 'pi' user has not been changed.
This is a security risk - please login as the 'pi' user and type 'passwd' to set a new password.

root@raspberrypi:~# echo 0  > /sys/class/backlight/backlight/brightness
root@raspberrypi:~# echo 1  > /sys/class/backlight/backlight/brightness
root@raspberrypi:~# echo 2  > /sys/class/backlight/backlight/brightness
root@raspberrypi:~# echo 3  > /sys/class/backlight/backlight/brightness
root@raspberrypi:~# echo 4  > /sys/class/backlight/backlight/brightness
root@raspberrypi:~# echo 5  > /sys/class/backlight/backlight/brightness
root@raspberrypi:~# echo 6  > /sys/class/backlight/backlight/brightness
root@raspberrypi:~# echo 7  > /sys/class/backlight/backlight/brightness
root@raspberrypi:~# echo 8  > /sys/class/backlight/backlight/brightness
-bash: echo: write error: Invalid argument
root@raspberrypi:~# 
Now I need to figure out how to invert the PWM polarity as '0' gives me FULL-ON and '7' is OFF.

Edit: there is a dt-property 'nxp,inverted-out: invert the polarity of the generated PWM' but where to place it? Will it be possible to apply this to individual channels or just global?
Last edited by aBUGSworstnightmare on Thu Sep 16, 2021 6:20 am, edited 1 time in total.

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 4132
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: Overlay with PCA9538 - looking for advice how to initialize/configure I/O

Wed Sep 15, 2021 2:12 pm

"nxp,inverted-out" just sets the INVRT bit of the MODE2 register, so it is a device-wide setting.

aBUGSworstnightmare
Posts: 3635
Joined: Tue Jun 30, 2015 1:35 pm

[Solved] Overlay with PCA9538 and PCA9632

Thu Sep 16, 2021 10:38 am

Overlay is working as expected so let me summarize this thread as below:

- PCA9538 - https://www.nxp.com/docs/en/data-sheet/PCA9538.pdf - is used as GPIO expansion. Some of the IO were under kernel control, others will be used as configuration signals for the connected display modules. Use the override parameters for selecting the output level (HIGH or LOW).

- PCA9632 - https://www.nxp.com/docs/en/data-sheet/PCA9632.pdf - is used as 'LED driver'. Well, not fully valid as it is miss-used to generate PWM's for LED backlight control. PCA9632 outputs are defaulting to open-drain, adding a 100k ohms pull-up gives you a PWM signal. Below is a example scope shot; not the nicest signal, but working (as one can see from the pictures).
Please note that dt-parameter 'nxp,inverted-out;' was added to overlay as the PWM needs to be inverted (pulling up the open-drain output)
pwm_50pct.jpg
PWM signal is not really nice, but working as expected.
pwm_50pct.jpg (73.65 KiB) Viewed 934 times
IMG_20210916_121641.jpg
resulting brightness from index 1 = 8
IMG_20210916_121641.jpg (116.74 KiB) Viewed 934 times
IMG_20210916_121609.jpg
Resulting brightness from index 10 = 160
IMG_20210916_121609.jpg (113.34 KiB) Viewed 934 times
The final overlay is here for reference/as a template for others who want to use PCA9538 and/or PCA9632

Code: Select all

/*
 * vc4-kms-dsi-sn65dsi8x-overlay.dts
 */

/dts-v1/;
/plugin/;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/leds/common.h>

/ {
	compatible = "brcm,bcm2835";

	/* PCA9538 GPIO expander, address 0x73 */
	fragment@0 {
		/*target = <&i2c_csi_dsi>;*/
		target = <&i2c0>;
		__overlay__ {
			#address-cells = <1>;
			#size-cells = <0>;
			status = "okay";

			pca: pca@73 {
				compatible = "nxp,pca9538";
				reg = <0x73>;
				gpio-controller;
				#gpio-cells = <2>;
				gpio-line-names = "UNUSED",
				  "BLEN_1",
				  "AUX1_2",
				  "AUX1-1",
				  "AUX2_2",
				  "AUX2_1",
				  "BLEN_2",
				  "EN_PCA";
				status = "okay";
				
				unused: unused {
					gpio-hog;
					gpios = <0 GPIO_ACTIVE_HIGH>;
					output-low;
				};

				aux12: aux12 {
					gpio-hog;
					gpios = <2 GPIO_ACTIVE_HIGH>;
				};
				
				aux11: aux11 {
					gpio-hog;
					gpios = <3 GPIO_ACTIVE_HIGH>;
				};

				aux22: aux22 {
					gpio-hog;
					gpios = <4 GPIO_ACTIVE_HIGH>;
				};
				
				aux21: aux21 {
					gpio-hog;
					gpios = <5 GPIO_ACTIVE_HIGH>;
				};
			};
		};
	};

	/* PCA9632 LED driver, address 0x62 */
	fragment@1 {
		/*target = <&i2c_csi_dsi>;*/
		target = <&i2c0>;
		__overlay__ {
			#address-cells = <1>;
			#size-cells = <0>;
			status = "okay";

			pca9632: pca9632@62 {
				compatible = "nxp,pca9632";
				#address-cells = <1>;
				#size-cells = <0>;
				reg = <0x62>;
				
				/*	PCA9632 defaults to open-drain output
					pull-ups were added, hence PWM needs to
					be inverted */
				nxp,inverted-out;

				bl1: bl1@0 {
					reg = <0>;
					function = LED_FUNCTION_BACKLIGHT;
					color = <LED_COLOR_ID_WHITE>;
					linux,default-trigger = "backlight";
					label = "bl1";
				};
				bl2: bl2@1 {
					reg = <1>;
					function = LED_FUNCTION_BACKLIGHT;
					color = <LED_COLOR_ID_WHITE>;
					linux,default-trigger = "backlight";
					label = "bl2";
				};
				unused2: unused2@2 {
					reg = <2>;
					linux,default-trigger = "none";
				};
				unused3: unused3@3 {
					reg = <3>;
					linux,default-trigger = "none";
				};
			};
		};
	};

	fragment@4 {
		target-path = "/";
		__overlay__ {
			/* Panel backlight through PCA9632 channel0 */
			backlight_lvds: backlight {
				compatible = "led-backlight";
				leds = <&bl1>;
				
				brightness-levels = <0 8 16 32 64 80 96 112 128 144 
								160 176 192 208 216 224 232 240 248
								255>;
				default-brightness-level = <16>;
				
				/* enable through PCA9538 IO6 */
				enable-gpios  = <&pca 6 0>; /* Backlight enable... */
			};

			panel: panel {
				compatible = "chunghwa,claa070wp03xglvds", "simple-panel";
				backlight = <&backlight_lvds>;

				port {
					panel_in_lvds: endpoint {
						remote-endpoint = <&bridge_out>;
					};
				};
			};
		};
	};

	fragment@5 {
		/*target = <&i2c_csi_dsi>;*/
		target = <&i2c0>;
		__overlay__ {
			#gpio-cells = <2>;
			#address-cells = <1>;
			#size-cells = <0>;
			status = "okay";
			
			bridge@2c {
				compatible = "ti,sn65dsi83";
				reg = <0x2c>;
				enable-gpios  = <&pca 7 0>;

				ports {
					#address-cells = <1>;
					#size-cells = <0>;

					port@0 {
						reg = <0>;
						bridge_in: endpoint {
							remote-endpoint = <&dsi_out_port>;
							data-lanes = <0 1 2>;
						};
					};

					port@2 {
						reg = <2>;
						bridge_out: endpoint {
							remote-endpoint = <&panel_in_lvds>;
						};
					};
				};
			};
		};
	};

	fragment@6 {
		target = <&dsi1>;
		__overlay__ {
			#address-cells = <1>;
			#size-cells = <0>;
			status = "okay";
			port {
				dsi_out_port: endpoint {
					remote-endpoint = <&bridge_in>;
					data-lanes = <0 1 2>;
				};
			};
		};
	};

	/*fragment@7 {
		target = <&i2c0if>;
		__overlay__ {
			status = "okay";
		};
	};*/
		
	/*fragment@8 {
		target = <&i2c0mux>;
		__overlay__ {
			status = "okay";
		};
	};*/	
	
	fragment@10 {
		target = <&aux11>;
		__overlay__ {
			output-low;
		};
	};

	fragment@11 {
		target = <&aux11>;
		__dormant__ {
			output-high;
		};
	};
	
	fragment@12 {
		target = <&aux12>;
		__overlay__ {
			output-low;
		};
	};

	fragment@13 {
		target = <&aux12>;
		__dormant__ {
			output-high;
		};
	};
	
	fragment@14 {
		target = <&aux21>;
		__overlay__ {
			output-low;
		};
	};

	fragment@15 {
		target = <&aux21>;
		__dormant__ {
			output-high;
		};
	};
	
	fragment@16 {
		target = <&aux22>;
		__overlay__ {
			output-low;
		};
	};

	fragment@17 {
		target = <&aux22>;
		__dormant__ {
			output-high;
		};
	};
			
	__overrides__ {
		aux11_low = <0>,"+10-11";
		aux11_high = <0>,"-10+11";
		aux12_low = <0>,"+12-13";
		aux12_high = <0>,"-12+13";
		aux21_low = <0>,"+14-15";
		aux21_high = <0>,"-14+15";
		aux22_low = <0>,"+16-17";
		aux22_high = <0>,"-16+17";				
	};	
};

Return to “Device Tree”