Unimplemented set_config Function: GPIO Pin Configuration Loss on i.MX8MP

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

Unimplemented set_config Function: GPIO Pin Configuration Loss on i.MX8MP

跳至解决方案
219 次查看
alexandreMarquis
Contributor II

Hi everyone,

I'm currently working with the i.MX8MP platform and encountered an issue while configuring a GPIO pin in input/pull-up mode. Here's the scenario:

In one of my drivers, the pin is used in output mode during the probe phase and then switched back to input mode. However, after this process, I found that the pin loses its configuration and is no longer in pull-up mode.

here is the dtb:

gt928@5d {
[...]
pincrtl-0 = <&pinctrl_ts>;
gt928,irq-gpios = <&gpio1 6 GPIO_PULL_UP>;
};

pinctrl_ts: tsgrp {
fsl,pins = <
MX8MP_IOMUXC_GPIO1_IO06__GPIO1_IO06 0x146 /* 0x146 == pull up, drive strength = 6 */
MX8MP_IOMUXC_SD1_DATA4__GPIO2_IO06 0xd6
>;
};

Here's the call stack for reference:

[ 14.630895] gpio_do_set_config+0x24/0x74
[ 14.630905] gpio_set_config_with_argument+0x38/0x44
[ 14.630911] gpio_set_bias+0x84/0xa4
[ 14.643448] gpiod_direction_input+0x198/0x1ac
[ 14.647892] goodix_irq_direction_input+0x40/0xa4 [goodix]
[ 14.653388] goodix_ts_probe+0x3fc/0x5c8 [goodix]

Upon further investigation, I noticed that the set_config function is not implemented (gpiolib.c do the following check):

gpio_do_set_config(struct gpio_chip *gc, unsigned int offset, unsigned long config) {
{
if (!gc->set_config)
return -ENOTSUPP;
[...]
}
I'm curious as to why set_config hasn't been implemented.
I've seen that other have done it :
 

 

​gc->set_config = pca953x_gpio_set_config;
or
gc->set_config = ep93xx_gpio_set_config;

 

 

 
Any insights or suggestions on how to address this issue would be greatly appreciated.

Thank you in advance for your help!

Best regards,
Alexandre

0 项奖励
1 解答
68 次查看
alexandreMarquis
Contributor II

This is how I resolved my problem.
Based on my findings, placing <&pinctrl_ts> under the touchscreen node doesn't apply the pin function correctly.

 

&i2c3 {
	clock-frequency = <400000>;
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_i2c3>,<&pinctrl_ts>;
	status = "okay";

	ov5640_0: ov5640_mipi@3c {
		status = "disabled";
	};

	gt928@5d {
		compatible = "goodix,gt928";
		reg = <0x5d>;
		pincrtl-names = "default";
		pincrtl-0 = <&pinctrl_ts>;
		interrupt-parent = <&gpio1>;
		interrupts = <6 IRQ_TYPE_LEVEL_LOW>;
		gt928,irq-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
		gt928,reset-gpios = <&gpio2 6 GPIO_ACTIVE_HIGH>;
		touchscreen-inverted-x; 
		status = "okay";
	};
};

[...]

&iomuxc {
	pinctrl_ts: tsgrp {
		fsl,pins = <
			MX8MP_IOMUXC_GPIO1_IO06__GPIO1_IO06		0x146 /* 0x146 == pull up, drive strength = 6 */
			MX8MP_IOMUXC_SD1_DATA4__GPIO2_IO06		0xd6
		>;
	};
};

 


However, when I move it to the &i2c3 node, the pins are configured properly.

Thank you for your time!

在原帖中查看解决方案

0 项奖励
4 回复数
69 次查看
alexandreMarquis
Contributor II

This is how I resolved my problem.
Based on my findings, placing <&pinctrl_ts> under the touchscreen node doesn't apply the pin function correctly.

 

&i2c3 {
	clock-frequency = <400000>;
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_i2c3>,<&pinctrl_ts>;
	status = "okay";

	ov5640_0: ov5640_mipi@3c {
		status = "disabled";
	};

	gt928@5d {
		compatible = "goodix,gt928";
		reg = <0x5d>;
		pincrtl-names = "default";
		pincrtl-0 = <&pinctrl_ts>;
		interrupt-parent = <&gpio1>;
		interrupts = <6 IRQ_TYPE_LEVEL_LOW>;
		gt928,irq-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
		gt928,reset-gpios = <&gpio2 6 GPIO_ACTIVE_HIGH>;
		touchscreen-inverted-x; 
		status = "okay";
	};
};

[...]

&iomuxc {
	pinctrl_ts: tsgrp {
		fsl,pins = <
			MX8MP_IOMUXC_GPIO1_IO06__GPIO1_IO06		0x146 /* 0x146 == pull up, drive strength = 6 */
			MX8MP_IOMUXC_SD1_DATA4__GPIO2_IO06		0xd6
		>;
	};
};

 


However, when I move it to the &i2c3 node, the pins are configured properly.

Thank you for your time!

0 项奖励
178 次查看
Zhiming_Liu
NXP TechSupport
NXP TechSupport

Hi @alexandreMarquis 

The gpio iomux value has been written with imx_pmx_set before gpio driver probe, so there is no need to use set_config function in gpio driver. The imx_pinctrl_probe

For gpio io expander driver, this function is need, because there is no another driver setting pull up/down.

 

Best Regards

Zhiming

0 项奖励
162 次查看
alexandreMarquis
Contributor II
I see, but then my question would be, why do i lose the pin configuration from the device-tree when I change my pin direction?

Scenario:



My pin is configure with a pull-up.
My driver load, set the pin in output. There is no more pull-up.
Put it back in input

expectation : the pin is set input, pull-up
current behaviour: the pin is set in input but the is no more pull-up on it.



From what i can see, when we call
gpiod_direction_input()


the function set the pin in input and then call the function
gpio_set_bias(struct gpio_desc *desc)


Which seem to try to restore the pull/pull down state of the pin, but as mention earlier, the no function seem to be implemented to reapply the device tree flag.

0 项奖励
131 次查看
Zhiming_Liu
NXP TechSupport
NXP TechSupport

Hi @alexandreMarquis 

I test such behavior on GPIO3_IO16(gpio-80). The iomux value in device tree will not be covered. There is no such issue using sysfs to control gpio.

NXP i.MX Release Distro 6.6-nanbield imx8mp-lpddr4-evk ttymxc1

imx8mp-lpddr4-evk login: [   14.532349] fec 30be0000.ethernet eth0: Link is Up - 1Gbps/Full - flow control off

imx8mp-lpddr4-evk login: root
root@imx8mp-lpddr4-evk:~# echo 80 > /sys/class/gpio/export
root@imx8mp-lpddr4-evk:~# cat /sys/kernel/debug/gpio
gpiochip0: GPIOs 0-31, parent: platform/30200000.gpio, 30200000.gpio:
 gpio-10  (                    |reset               ) out hi ACTIVE LOW
 gpio-14  (                    |regulator-vbus      ) out hi

gpiochip1: GPIOs 32-63, parent: platform/30210000.gpio, 30210000.gpio:
 gpio-38  (                    |regulator-pcie      ) out hi
 gpio-39  (                    |PCIe reset          ) out hi
 gpio-44  (                    |cd                  ) in  hi ACTIVE LOW
 gpio-51  (                    |regulator-usdhc2    ) out lo

gpiochip2: GPIOs 64-95, parent: platform/30220000.gpio, 30220000.gpio:
 gpio-80  (                    |sysfs               ) out hi

gpiochip3: GPIOs 96-127, parent: platform/30230000.gpio, 30230000.gpio:
 gpio-98  (                    |PHY reset           ) out hi ACTIVE LOW
 gpio-116 (                    |switch              ) out hi ACTIVE LOW
 gpio-118 (                    |PHY reset           ) out hi ACTIVE LOW
 gpio-123 (                    |regulator-can2-stby ) out lo
 gpio-124 (                    |Headphone detection ) in  lo
 gpio-125 (                    |regulator-audio-pwr ) out hi

gpiochip4: GPIOs 128-159, parent: platform/30240000.gpio, 30240000.gpio:
 gpio-133 (                    |regulator-can1-stby ) out lo
 gpio-141 (                    |spi1 CS0            ) out hi ACTIVE LOW
 gpio-149 (                    |host-wake           ) in  hi ACTIVE LOW

gpiochip5: GPIOs 512-527, parent: i2c/2-0020, 2-0020, can sleep:
 gpio-512 (EXT_PWREN1          )
 gpio-513 (EXT_PWREN2          )
 gpio-514 (CAN1/I2C5_SEL       )
 gpio-515 (PDM/CAN2_SEL        )
 gpio-516 (FAN_EN              )
 gpio-517 (PWR_MEAS_IO1        )
 gpio-518 (PWR_MEAS_IO2        )
 gpio-519 (EXP_P0_7            )
 gpio-520 (EXP_P1_0            )
 gpio-521 (EXP_P1_1            )
 gpio-522 (EXP_P1_2            )
 gpio-523 (EXP_P1_3            )
 gpio-524 (EXP_P1_4            )
 gpio-525 (EXP_P1_5            )
 gpio-526 (EXP_P1_6            )
 gpio-527 (EXP_P1_7            )
root@imx8mp-lpddr4-evk:~# memtool -32 30330380 1
E
Reading 0x1 count starting at address 0x30330380

0x30330380:  00000140

root@imx8mp-lpddr4-evk:~# echo in > /sys/class/gpio/gpio80/direction
root@imx8mp-lpddr4-evk:~# memtool -32 30330380 1
E
Reading 0x1 count starting at address 0x30330380

0x30330380:  00000140

root@imx8mp-lpddr4-evk:~# cat /sys/kernel/debug/gpio
gpiochip0: GPIOs 0-31, parent: platform/30200000.gpio, 30200000.gpio:
 gpio-10  (                    |reset               ) out hi ACTIVE LOW
 gpio-14  (                    |regulator-vbus      ) out hi

gpiochip1: GPIOs 32-63, parent: platform/30210000.gpio, 30210000.gpio:
 gpio-38  (                    |regulator-pcie      ) out hi
 gpio-39  (                    |PCIe reset          ) out hi
 gpio-44  (                    |cd                  ) in  hi ACTIVE LOW
 gpio-51  (                    |regulator-usdhc2    ) out lo

gpiochip2: GPIOs 64-95, parent: platform/30220000.gpio, 30220000.gpio:
 gpio-80  (                    |sysfs               ) in  hi

gpiochip3: GPIOs 96-127, parent: platform/30230000.gpio, 30230000.gpio:
 gpio-98  (                    |PHY reset           ) out hi ACTIVE LOW
 gpio-116 (                    |switch              ) out hi ACTIVE LOW
 gpio-118 (                    |PHY reset           ) out hi ACTIVE LOW
 gpio-123 (                    |regulator-can2-stby ) out lo
 gpio-124 (                    |Headphone detection ) in  lo
 gpio-125 (                    |regulator-audio-pwr ) out hi

gpiochip4: GPIOs 128-159, parent: platform/30240000.gpio, 30240000.gpio:
 gpio-133 (                    |regulator-can1-stby ) out lo
 gpio-141 (                    |spi1 CS0            ) out hi ACTIVE LOW
 gpio-149 (                    |host-wake           ) in  hi ACTIVE LOW

gpiochip5: GPIOs 512-527, parent: i2c/2-0020, 2-0020, can sleep:
 gpio-512 (EXT_PWREN1          )
 gpio-513 (EXT_PWREN2          )
 gpio-514 (CAN1/I2C5_SEL       )
 gpio-515 (PDM/CAN2_SEL        )
 gpio-516 (FAN_EN              )
 gpio-517 (PWR_MEAS_IO1        )
 gpio-518 (PWR_MEAS_IO2        )
 gpio-519 (EXP_P0_7            )
 gpio-520 (EXP_P1_0            )
 gpio-521 (EXP_P1_1            )
 gpio-522 (EXP_P1_2            )
 gpio-523 (EXP_P1_3            )
 gpio-524 (EXP_P1_4            )
 gpio-525 (EXP_P1_5            )
 gpio-526 (EXP_P1_6            )
 gpio-527 (EXP_P1_7            )

 

I think maybe you miss some code in your driver, you can refer the sysfs code, have you add mutex during your operation?

Zhiming_Liu_0-1715147008336.png

 

0 项奖励