Re: Modem control lines for RTSCTS hardware flow control via rts-gpio and cts-gpio with IMX

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Jan 6, 2022 at 3:55 PM Tim Harvey <tharvey@xxxxxxxxxxxxx> wrote:
>
> Greetings,
>
> I have long used modem control lines via GPIO with the IMX driver for
> RS485 via rts-gpios in the scenario where an RS485 transceiver
> transmit enable is connected to a GPIO representing RTS.
>
> Therefore I 'thought' that one could use rts-gpios and cts-gpios for
> hardware flow control on an IMX UART but it appears I may be wrong as
> when I define those along with 'uart-has-rtscts' UART communication
> ceases between the IMX and a device using hardware flow control.
>
> As an example take the following which describes a UART with RTSCTS
> flow control connected to a broadcom Bluetooth HCI radio:
>
> The following works:
> &uart4 {
>         pinctrl-names = "default";
>         pinctrl-0 = <&pinctrl_uart4>,<&pinctrl_bten>;
>         uart-has-rtscts;
>         status = "okay";
>
>         bluetooth {
>                 compatible = "brcm,bcm4330-bt";
>                 shutdown-gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
>         };
> };
>
> &iomuxc {
>         pinctrl_bten: btengrp {
>                 fsl,pins = <
>                         MX6QDL_PAD_GPIO_2__GPIO1_IO02           0x1b0b1
>                 >;
>         };
>
>         pinctrl_uart4: uart4grp {
>                 fsl,pins = <
>                         MX6QDL_PAD_CSI0_DAT12__UART4_TX_DATA    0x1b0b1
>                         MX6QDL_PAD_CSI0_DAT13__UART4_RX_DATA    0x1b0b1
>                         MX6QDL_PAD_CSI0_DAT16__UART4_RTS_B      0x1b0b1
>                         MX6QDL_PAD_CSI0_DAT17__UART4_CTS_B      0x1b0b1
>                 >;
>         };
> };
>
> The following where I've replaced the RTS/CTS with gpio does not work:
> &uart4 {
>         pinctrl-names = "default";
>         pinctrl-0 = <&pinctrl_uart4>,<&pinctrl_bten>;
>         rts-gpios = <&gpio6 2 GPIO_ACTIVE_LOW>;
>         cts-gpios = <&gpio6 3 GPIO_ACTIVE_LOW>;
>         uart-has-rtscts;
>         status = "okay";
>
>         bluetooth {
>                 compatible = "brcm,bcm4330-bt";
>                 shutdown-gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
>         };
> };
>
> &iomuxc {
>         pinctrl_bten: btengrp {
>                 fsl,pins = <
>                         MX6QDL_PAD_GPIO_2__GPIO1_IO02           0x1b0b1
>                 >;
>         };
>
>         pinctrl_uart4: uart4grp {
>                 fsl,pins = <
>                         MX6QDL_PAD_CSI0_DAT12__UART4_TX_DATA    0x1b0b1
>                         MX6QDL_PAD_CSI0_DAT13__UART4_RX_DATA    0x1b0b1
>                         MX6QDL_PAD_CSI0_DAT16__GPIO6_IO02       0x1b0b1
>                         MX6QDL_PAD_CSI0_DAT17__GPIO6_IO03       0x1b0b1
>                 >;
>         };
> };
>
> In the above example of course I could simply use the version that
> works but the reason I want to use rts-gpios and cts-gpios is that I
> have cases where I don't have access to the RTS/CTS pinmux options and
> thus can only use gpio's.
>
> I'm hoping perhaps I just have something misconfigured or that perhaps
> something simple is missing from drivers/tty/serial/imx.c in order to
> use gpio's as hardware flow control. I've tried flipping the rts/cts
> gpios and polarity in case I had something simply backwards but that
> still did not work.
>
> Any ideas or suggestions?
>
> Best regards,
>
> Tim

Adding some previous main committers to imx uart driver and mctrl feature to cc.

>From looking over drivers/tty/serial/imx.c, serial_core.c, and
serial_mctrl_gpio.c I see that rts-gpios is the 'output' from the IMX
so I need to flip my gpios as:
         cts-gpios = <&gpio6 2 GPIO_ACTIVE_LOW>; // input to IMX from
BT_UART_RTS_L output on brcm chip
         rts-gpios = <&gpio6 3 GPIO_ACTIVE_LOW>; // output from IMX to
BT_UART_CTS_L input on brcm chip

I see the following happening when the brcm bluetooth uart driver initializes:
mctrl_gpio_init registers irq handler for cts gpio (gpio6 2)
mctrl_gpio_init configures output for rts gpio (gpio6 3)
uart_change_speed is called and sets CRTSCTS enabled and calls stop_tx
(imx_uart_stop_tx)
mctrl_gpio_irq_handle is called and it sees CTS=1 then calls
uart_handle_cts_change which calls start_tx

So I believe the CTS input is handled correctly but I see nothing that
asserts the RTS  output. The imx.c driver has imx_uart_rts_active and
imx_uart_rts_inactive which call mctrl_gpio_set to manipulate the RTS
output yet this is only done when the UART is configured for RS485
mode to handle the case where RTS is used as an output to enable the
RS485 transmit enable.

So I believe in order to support using gpios for rts/cts in the imx
uart driver I must find the right place to call imx_uart_rts_active
and imx_uart_rts_inactive when the FIFO is not full and full
respectively. I'm not that familiar with the Linux uart driver
framework - am I on the right track and if so any ideas where this is
best done?

Best Regards,

Tim



[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux PPP]     [Linux FS]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Linmodem]     [Device Mapper]     [Linux Kernel for ARM]

  Powered by Linux