How to Specify Drive Strength via Overlay?

Hi All,

I’ve been enjoying cutting my teeth on the Zero as my first sbc. I’ve a long history as a linux sysadmin and it’s impressive to see what’s possible in this form factor.

I generated my first overlay a week ago but am yet to find comprehensive docs to translate kernel device details into overlay source.

Does anybody know the correct syntax to specify gpio drive strength (ie: current output) via an overlay?

@RadxaYuntian shared this link, which provides some naming specifics:

More precisely, I’m looking to increase GPIOAO_3 drive-strength-microamp from 500 to 2000uA.

Thank you in advance for your thoughts!

I’ve been reading about this for more than a week and have found reference to syntax like:
drive-strength-microamp = <2000>;

The missing piece is what needs to precede and close this statement. After reading the Radxa S905Y2 manual then this pin primer and looking at the example from the above meson pinctrl bindings along with all the overlay source files and dtsi definitions, the mystery is how to refer to the pin group specific to the amlogic,g12a

The kernel source pinctrl driver for the Zero makes reference to MESON_PIN(GPIOAO_3)

So my dts stub is along the lines of:

/dts-v1/;
/plugin/;

/ {
	compatible = "radxa,zero", "amlogic,g12a";

	fragment@0 {
		target = <&GPIOAO_3>; # this is a guess from the driver def
		__overlay__ {
			status = "okay";
			pinctrl-0 = <&GPIOAO_3_pins>;  # this is an extrapolation from the above & other DTSes
			pinctrl-names = "default";
			drive-strength-microamp = <2000>;
		};
	};
};

Any overlay overlords out there with some insights?

drive-strength-microamp is a property for meson-pinctrl which affects all pins, so your target should be ao_pinctrl and you should only keep

this line in that node. After loading that check your sysfs to see if there is such property for pinctrl. That should give you something.

Hi @RadxaYuntian, I greatly appreciate your reply & wisdom!

I’ll give that a go tomorrow and confirm the increased uA is shown via sysfs.

Then the next step will be to have both the onewire and drive-strength overlays in uEnv.txt

Do you anticipate any caveats with including both?

Much appreciated, hope your week is starting off well!

As long as there is no conflict of settings between the dtbo’s they can coexist without issue.

Brilliant, thank you, that was my hope!

Hi @RadxaYuntian,

So testing with:

/dts-v1/;
/plugin/;

    / {
    	compatible = "radxa,zero", "amlogic,g12a";

    	fragment@0 {
    		target = <&ao_pinctrl>;
    		__overlay__ {
    			status = "okay";
    			pinctrl-names = "default";
    			drive-strength-microamp = <2000>;
    		};
    	};
    }; 

Does reveal a new file:
/sys/firmware/devicetree/base/soc/bus@ff800000/sys-ctrl@0/pinctrl@14/drive-strength-microamp

The file is of type ‘data’ so is not human readable and differs from other firmware/devicetree entries for drive-strength-microamp.

Unfortunately the output is still indicated as 500uA in the pinconf-pins file:
/sys/kernel/debug/pinctrl/ff800000.sys-ctrl\:pinctrl@14-pinctrl-meson/pinconf-pins

Reviewing meson-g12-common.dtsi seems to show a mux { } statement prior to setting drive-strength and other overlay source files seem to all indicate the specific pin group based on pinctrl-0 = statements.

Please provide an updated dts including the pin group needed to successfully set the drive strength for ao?

Much appreciated!

Actually it seems like the i2c was set to output 3000uA already. Can you try without the drive strength overlay?

I noticed that but thought there may be a conflict calling two overlays for GPIOAO-3:
meson-g12a-i2c-ao-m0-gpioao-2-gpioao-3
AND
meson-g12a-w1-gpioa-3-high

However looking at the source for the former doesn’t show any calls to GPIOAO-3 since it is instead referencing i2c_ao_sda_pins

Is it okay to call both of these overlays together?

Calling the first overlay does result in the drive strength showing 3000uA from the pinconf-pins output:
pin 2 (GPIOAO_2): input bias disabled, output drive strength (3000 uA)
pin 3 (GPIOAO_3): input bias disabled, output drive strength (3000 uA)

Good thinking!

I lost track of your issue and thought you were using i2c. The way you use overlays might give you issue since 2 functions are defined on the same pin.

If that’s the case you probably need to find a way to incorporate this section into your w1 overlay. You can keep the group line since that name is just a label, but for function line I think you need to specify gpio_aobus. That should be the proper way to handle this.

Thank you for your latest insights.

So would running the onewire overlay as it is then also calling another overlay with source:
/dts-v1/;
/plugin/;

/ {
	compatible = "radxa,zero", "amlogic,g12a";

	fragment@0 {
		target = <&ao_pinctrl>;
		__overlay__ {
			status = "okay";
			pinctrl-0 = <&i2c_ao_sda_pins>;
			pinctrl-names = "default";
			drive-strength-microamp = <3000>;
		};
	};
};

Suffice to reach the goals of onewire with a higher drive strength?

If not will you please provide a dts with the combined attributes including function gpio_aobus ?

Probably add the below in your 1w overlay:

	fragment@1 {
		target = <&ao_pinctrl>;
		__overlay__ {
			w1_ao3_pins: w1-ao3 {
						mux {
							groups = "GPIOAO_3";
							function = "gpio_aobus";
							bias-disable;
							drive-strength-microamp = <3000>;
						};
					};
		};
	};

You can also have it standalone but logically they should be kept in the same file.

Thanks @RadxaYuntian, I tested today both as a standalone overlay (fragment@0) and combined with the onewire source as:

/dts-v1/;
/plugin/;

#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/gpio/meson-g12a-gpio.h>

/ {
	compatible = "radxa,zero", "amlogic,g12a";

	fragment@0 {
		target-path = "/";
		__overlay__ {
			w1: onewire {
				compatible = "w1-gpio";
				gpios = <&gpio_ao GPIOAO_3 GPIO_ACTIVE_HIGH>;
				status = "okay";
			};
		};
	};

	fragment@1 {
		target = <&ao_pinctrl>;
		__overlay__ {
			w1_ao3_pins: w1-ao3 {
				mux {
					groups = "GPIOAO_3";
					function = "gpio_aobus";
					bias-disable;
					drive-strength-microamp = <3000>;
				};
			};
		};
	};
}; 

Unfortunately, neither changed the drive strength reported in:
/sys/kernel/debug/pinctrl/ff800000.sys-ctrl\:pinctrl@14-pinctrl-meson/pinconf-pins

Are there any additional includes required for the second fragment?

Or perhaps an alternate pin group needs to be specified which includes GPIOAO_3 and also the pad it is on?

As I work in a factory, the industrial applications for supporting parasitic power for onewire sensors is huge. The Zero serving as the building heat controller is the first proof of concept.

Look forward to your thoughts and hope your week is going well!

Hi @RadxaYuntian, how’s your week going?

I’m checking back on the above findings. Please advise?

Much appreciated!

/dts-v1/;
/plugin/;

#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/gpio/meson-g12a-gpio.h>

/ {
	compatible = "radxa,zero", "amlogic,g12a";

	fragment@0 {
		target-path = "/";
		__overlay__ {
			w1: onewire {
				compatible = "w1-gpio";
				gpios = <&gpio_ao GPIOAO_3 GPIO_ACTIVE_HIGH>;
				status = "okay";
			};
		};
	};

	fragment@1 {
		target = <&GPIOAO_3>;
		__overlay__ {
				mux {
					groups = "GPIOAO_3";
					function = "gpio_aobus";
					bias-disable;
					drive-strength-microamp = <3000>;
				};
		};
	};
}; 

Maybe something like this.

Thank you @RadxaYuntian, I tested the second stub on its own as a fragment@0 overlay and unfortunately still didn’t see any change in the reported pinctrl drive strength.

At this point I need to finalize this project, so I may either directly connect the DS18B20 sensors to an ESP32 over onewire or drive them from a spare Shelly 1 with a temp sensor connector.

I really appreciate your guidance in getting onewire working on the Zero and with attempting to modify the GPIO drive strength.

The Zero will likely continue to serve as the HomeAssistant server, which will allow additional integrations down the line.

I’ll be sure to share my BoM and results once everything’s set.

Here’s to your April!