You can have a look at the i2c-imx driver. It does exactly that.
You need to use pinctrl_lookup_state
to retrieve the different pinctrl states (one of those being USART Tx and the other one GPIO). Then you can switch between both with pinctrl_select_state
.
To sum it up, you'd have something like that in your uart node:
usart3: serial@fc00c000 {
pinctrl-names = "default","gpio";
pinctrl-0 = <&pinctrl_usart3>;
pinctrl-1 = <&pinctrl_usart3_gpio>;
tx-gpio = <&pioE 4 GPIO_ACTIVE_LOW>;
status = "okay";
};
In the driver code:
pinctrl_pins_default = pinctrl_lookup_state(pinctrl, PINCTRL_STATE_DEFAULT);
pinctrl_pins_gpio = pinctrl_lookup_state(pinctrl, "gpio");
tx_gpio = of_get_named_gpio(pdev->dev.of_node, "tx-gpio", 0);
Then, you can use pinctrl_select_state
to switch back and forth between pinctrl_pins_default
and pinctrl_pins_gpio
. tx_gpio
is your gpio.