pci1xxxx uart supports rs485 mode of operation in the hardware with
auto-direction control with configurable delay for releasing RTS after
the transmission. This patch adds support for the rs485 mode.
Signed-off-by: Kumaravel Thiagarajan <kumaravel.thiagarajan@microchip.com>
---
Changes in v2:
- move pci1xxxx_rs485_config to a separate patch with
pci1xxxx_rs485_supported.
---
drivers/tty/serial/8250/8250_pci1xxxx.c | 57 +++++++++++++++++++++++++
1 file changed, 57 insertions(+)
diff --git a/drivers/tty/serial/8250/8250_pci1xxxx.c b/drivers/tty/serial/8250/8250_pci1xxxx.c
index 41a4b94f52b4..999e5a284266 100644
--- a/drivers/tty/serial/8250/8250_pci1xxxx.c
+++ b/drivers/tty/serial/8250/8250_pci1xxxx.c
@@ -137,6 +137,61 @@ static void pci1xxxx_set_divisor(struct uart_port *port, unsigned int baud,
writel((quot << 8) | frac, (port->membase + CLK_DIVISOR_REG));
}
+static const struct serial_rs485 pci1xxxx_rs485_supported = {
+ .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | SER_RS485_RTS_AFTER_SEND,
+ .delay_rts_after_send = 1,
+ /* Delay RTS before send is not supported */
+};
+
+static int pci1xxxx_rs485_config(struct uart_port *port,
+ struct ktermios *termios,
+ struct serial_rs485 *rs485)
+{
+ u32 clock_div = readl(port->membase + CLK_DIVISOR_REG);
+ u8 delay_in_baud_periods = 0;
+ u32 baud_period_in_ns = 0;
+ u8 data = 0;
+
+ /* pci1xxxx's uart hardware supports only RTS delay after
+ * Tx and in units of bit times to a maximum of 15
+ */
+
+ rs485->flags &= SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND |
+ SER_RS485_RTS_AFTER_SEND;
+
+ if (rs485->flags & SER_RS485_ENABLED) {
+ memset(rs485->padding, 0, sizeof(rs485->padding));
+
+ data = ADCL_CFG_EN | ADCL_CFG_PIN_SEL;
+
+ if (!(rs485->flags & SER_RS485_RTS_ON_SEND)) {
+ data |= ADCL_CFG_POL_SEL;
+ rs485->flags |= SER_RS485_RTS_AFTER_SEND;
+ } else {
+ rs485->flags &= ~SER_RS485_RTS_AFTER_SEND;
+ }
+
+ if (rs485->delay_rts_after_send) {
+ baud_period_in_ns = ((clock_div >> 8) * 16);
+ delay_in_baud_periods = (rs485->delay_rts_after_send * 1000000) /
+ baud_period_in_ns;
+ if (delay_in_baud_periods > 0xF)
+ delay_in_baud_periods = 0xF;
+ data |= delay_in_baud_periods << 8;
+ rs485->delay_rts_after_send = (baud_period_in_ns * delay_in_baud_periods) /
+ 1000000;
+ rs485->delay_rts_before_send = 0;
+ }
+ } else {
+ memset(rs485, 0, sizeof(*rs485));
+ }
+
+ writeb(data, (port->membase + ADCL_CFG_REG));
+ port->rs485 = *rs485;
+
+ return 0;
+}
+
static int pci1xxxx_get_num_ports(struct pci_dev *dev)
{
int nr_ports = 1;
@@ -217,6 +272,8 @@ static int pci1xxxx_setup(struct pci1xxxx_8250 *priv,
port->port.set_termios = serial8250_do_set_termios;
port->port.get_divisor = pci1xxxx_get_divisor;
port->port.set_divisor = pci1xxxx_set_divisor;
+ port->port.rs485_config = pci1xxxx_rs485_config;
+ port->port.rs485_supported = pci1xxxx_rs485_supported;
ret = pci1xxxx_setup_port(priv, port, offset);
if (ret < 0)
return ret;
--
2.25.1
On Sat, 1 Oct 2022, Kumaravel Thiagarajan wrote:
> pci1xxxx uart supports rs485 mode of operation in the hardware with
> auto-direction control with configurable delay for releasing RTS after
> the transmission. This patch adds support for the rs485 mode.
>
> Signed-off-by: Kumaravel Thiagarajan <kumaravel.thiagarajan@microchip.com>
> ---
> Changes in v2:
> - move pci1xxxx_rs485_config to a separate patch with
> pci1xxxx_rs485_supported.
> ---
> drivers/tty/serial/8250/8250_pci1xxxx.c | 57 +++++++++++++++++++++++++
> 1 file changed, 57 insertions(+)
>
> diff --git a/drivers/tty/serial/8250/8250_pci1xxxx.c b/drivers/tty/serial/8250/8250_pci1xxxx.c
> index 41a4b94f52b4..999e5a284266 100644
> --- a/drivers/tty/serial/8250/8250_pci1xxxx.c
> +++ b/drivers/tty/serial/8250/8250_pci1xxxx.c
> +
> + if (rs485->delay_rts_after_send) {
> + baud_period_in_ns = ((clock_div >> 8) * 16);
Is this 16 perhaps UART_BIT_SAMPLE_CNT?
--
i.
> -----Original Message-----
> From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> Sent: Monday, October 3, 2022 2:51 PM
> To: Kumaravel Thiagarajan - I21417 <Kumaravel.Thiagarajan@microchip.com>
> Subject: Re: [PATCH v2 tty-next 2/3] 8250: microchip: pci1xxxx: Add rs485
> support to quad-uart driver.
>
> On Sat, 1 Oct 2022, Kumaravel Thiagarajan wrote:
>
> > pci1xxxx uart supports rs485 mode of operation in the hardware with
> > auto-direction control with configurable delay for releasing RTS after
> > the transmission. This patch adds support for the rs485 mode.
> >
> > Signed-off-by: Kumaravel Thiagarajan
> > <kumaravel.thiagarajan@microchip.com>
> > ---
> > Changes in v2:
> > - move pci1xxxx_rs485_config to a separate patch with
> > pci1xxxx_rs485_supported.
> > ---
> > drivers/tty/serial/8250/8250_pci1xxxx.c | 57
> > +++++++++++++++++++++++++
> > 1 file changed, 57 insertions(+)
> >
> > diff --git a/drivers/tty/serial/8250/8250_pci1xxxx.c
> > b/drivers/tty/serial/8250/8250_pci1xxxx.c
> > index 41a4b94f52b4..999e5a284266 100644
> > --- a/drivers/tty/serial/8250/8250_pci1xxxx.c
> > +++ b/drivers/tty/serial/8250/8250_pci1xxxx.c
> > +
> > + if (rs485->delay_rts_after_send) {
> > + baud_period_in_ns = ((clock_div >> 8) * 16);
>
> Is this 16 perhaps UART_BIT_SAMPLE_CNT?
Yes. Is there any macro definition for that? I could not find any definition in the above name.
Thank You.
Regards,
Kumar
On Tue, 4 Oct 2022, Kumaravel.Thiagarajan@microchip.com wrote:
> > -----Original Message-----
> > From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> > Sent: Monday, October 3, 2022 2:51 PM
> > To: Kumaravel Thiagarajan - I21417 <Kumaravel.Thiagarajan@microchip.com>
> > Subject: Re: [PATCH v2 tty-next 2/3] 8250: microchip: pci1xxxx: Add rs485
> > support to quad-uart driver.
> >
> > On Sat, 1 Oct 2022, Kumaravel Thiagarajan wrote:
> >
> > > pci1xxxx uart supports rs485 mode of operation in the hardware with
> > > auto-direction control with configurable delay for releasing RTS after
> > > the transmission. This patch adds support for the rs485 mode.
> > >
> > > Signed-off-by: Kumaravel Thiagarajan
> > > <kumaravel.thiagarajan@microchip.com>
> > > ---
> > > Changes in v2:
> > > - move pci1xxxx_rs485_config to a separate patch with
> > > pci1xxxx_rs485_supported.
> > > ---
> > > drivers/tty/serial/8250/8250_pci1xxxx.c | 57
> > > +++++++++++++++++++++++++
> > > 1 file changed, 57 insertions(+)
> > >
> > > diff --git a/drivers/tty/serial/8250/8250_pci1xxxx.c
> > > b/drivers/tty/serial/8250/8250_pci1xxxx.c
> > > index 41a4b94f52b4..999e5a284266 100644
> > > --- a/drivers/tty/serial/8250/8250_pci1xxxx.c
> > > +++ b/drivers/tty/serial/8250/8250_pci1xxxx.c
> > > +
> > > + if (rs485->delay_rts_after_send) {
> > > + baud_period_in_ns = ((clock_div >> 8) * 16);
> >
> > Is this 16 perhaps UART_BIT_SAMPLE_CNT?
> Yes. Is there any macro definition for that? I could not find any
> definition in the above name.
You're adding it in your 1/3 patch :-).
--
i.
On Sat, 1 Oct 2022, Kumaravel Thiagarajan wrote:
> pci1xxxx uart supports rs485 mode of operation in the hardware with
> auto-direction control with configurable delay for releasing RTS after
> the transmission. This patch adds support for the rs485 mode.
>
> Signed-off-by: Kumaravel Thiagarajan <kumaravel.thiagarajan@microchip.com>
> ---
> Changes in v2:
> - move pci1xxxx_rs485_config to a separate patch with
> pci1xxxx_rs485_supported.
> ---
> drivers/tty/serial/8250/8250_pci1xxxx.c | 57 +++++++++++++++++++++++++
> 1 file changed, 57 insertions(+)
>
> diff --git a/drivers/tty/serial/8250/8250_pci1xxxx.c b/drivers/tty/serial/8250/8250_pci1xxxx.c
> index 41a4b94f52b4..999e5a284266 100644
> --- a/drivers/tty/serial/8250/8250_pci1xxxx.c
> +++ b/drivers/tty/serial/8250/8250_pci1xxxx.c
> @@ -137,6 +137,61 @@ static void pci1xxxx_set_divisor(struct uart_port *port, unsigned int baud,
> writel((quot << 8) | frac, (port->membase + CLK_DIVISOR_REG));
> }
>
> +static const struct serial_rs485 pci1xxxx_rs485_supported = {
> + .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | SER_RS485_RTS_AFTER_SEND,
> + .delay_rts_after_send = 1,
> + /* Delay RTS before send is not supported */
> +};
> +
> +static int pci1xxxx_rs485_config(struct uart_port *port,
> + struct ktermios *termios,
> + struct serial_rs485 *rs485)
> +{
> + u32 clock_div = readl(port->membase + CLK_DIVISOR_REG);
> + u8 delay_in_baud_periods = 0;
> + u32 baud_period_in_ns = 0;
> + u8 data = 0;
> +
> + /* pci1xxxx's uart hardware supports only RTS delay after
> + * Tx and in units of bit times to a maximum of 15
> + */
> +
> + rs485->flags &= SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND |
> + SER_RS485_RTS_AFTER_SEND;
Drop this, core handles it for you.
I think I already mentioned to you that there is a lot of stuff that core
handles for you.
> + if (rs485->flags & SER_RS485_ENABLED) {
> + memset(rs485->padding, 0, sizeof(rs485->padding));
Core handles this for you.
> + data = ADCL_CFG_EN | ADCL_CFG_PIN_SEL;
> +
> + if (!(rs485->flags & SER_RS485_RTS_ON_SEND)) {
> + data |= ADCL_CFG_POL_SEL;
> + rs485->flags |= SER_RS485_RTS_AFTER_SEND;
> + } else {
> + rs485->flags &= ~SER_RS485_RTS_AFTER_SEND;
> + }
Core handles that flags sanitization for you.
> + if (rs485->delay_rts_after_send) {
> + baud_period_in_ns = ((clock_div >> 8) * 16);
If that >> 8 is there to take part of the CLK_DIVISOR_REG register's bits,
you want to define a mask and use FIELD_GET().
> + delay_in_baud_periods = (rs485->delay_rts_after_send * 1000000) /
NSEC_PER_MSEC?
> + baud_period_in_ns;
> + if (delay_in_baud_periods > 0xF)
> + delay_in_baud_periods = 0xF;
> + data |= delay_in_baud_periods << 8;
You want to add something along these lines:
#define ADCL_CFG_RTS_DELAY_MASK GENMASK(11, 8)
Then do:
delay_in_baud_periods = min(delay_in_baud_periods,
FIELD_MAX(ADCL_CFG_RTS_DELAY_MASK));
data |= FIELD_PREP(ADCL_CFG_RTS_DELAY_MASK, delay_in_baud_periods);
> + rs485->delay_rts_after_send = (baud_period_in_ns * delay_in_baud_periods) /
> + 1000000;
NSEC_PER_MSEC?
> + rs485->delay_rts_before_send = 0;
> + }
> + } else {
> + memset(rs485, 0, sizeof(*rs485));
Core handles this.
> + }
> +
> + writeb(data, (port->membase + ADCL_CFG_REG));
> + port->rs485 = *rs485;
Core handles this.
> + return 0;
> +}
> +
> static int pci1xxxx_get_num_ports(struct pci_dev *dev)
> {
> int nr_ports = 1;
> @@ -217,6 +272,8 @@ static int pci1xxxx_setup(struct pci1xxxx_8250 *priv,
> port->port.set_termios = serial8250_do_set_termios;
> port->port.get_divisor = pci1xxxx_get_divisor;
> port->port.set_divisor = pci1xxxx_set_divisor;
> + port->port.rs485_config = pci1xxxx_rs485_config;
> + port->port.rs485_supported = pci1xxxx_rs485_supported;
> ret = pci1xxxx_setup_port(priv, port, offset);
> if (ret < 0)
> return ret;
>
--
i.
> From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> Sent: Monday, October 3, 2022 2:34 PM
> To: Kumaravel Thiagarajan - I21417
> <Kumaravel.Thiagarajan@microchip.com>
> Subject: Re: [PATCH v2 tty-next 2/3] 8250: microchip: pci1xxxx: Add rs485
> support to quad-uart driver.
>
> [Some people who received this message don't often get email from
> ilpo.jarvinen@linux.intel.com. Learn why this is important at
> https://aka.ms/LearnAboutSenderIdentification ]
>
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the
> content is safe
>
> > + if (rs485->flags & SER_RS485_ENABLED) {
> > + memset(rs485->padding, 0, sizeof(rs485->padding));
>
> Core handles this for you.
I went through the code and it seems like this is not taken care by the core.
Do you suggest calling 'serial8250_em485_config' inside 'pci1xxxx_rs485_config' callback?
This has not been done since we do not need all the configurations done inside 'serial8250_em485_config'.
> > + if (!(rs485->flags & SER_RS485_RTS_ON_SEND)) {
> > + data |= ADCL_CFG_POL_SEL;
> > + rs485->flags |= SER_RS485_RTS_AFTER_SEND;
> > + } else {
> > + rs485->flags &= ~SER_RS485_RTS_AFTER_SEND;
> > + }
>
> Core handles that flags sanitization for you.
I went through the code and it seems like this is not taken care by the core.
Do you suggest calling 'serial8250_em485_config' inside 'pci1xxxx_rs485_config' callback?
This has not been done since we do not need all the configurations done inside 'serial8250_em485_config'.
> > + } else {
> > + memset(rs485, 0, sizeof(*rs485));
>
> Core handles this.
I went through the code and it seems like this is not taken care by the core.
Do you suggest calling 'serial8250_em485_config' inside 'pci1xxxx_rs485_config' callback?
This has not been done since we do not need all the configurations done inside 'serial8250_em485_config'.
> > + writeb(data, (port->membase + ADCL_CFG_REG));
> > + port->rs485 = *rs485;
>
> Core handles this.
I went through the code and it seems like this is not taken care by the core.
Do you suggest calling 'serial8250_em485_config' inside 'pci1xxxx_rs485_config' callback?
This has not been done since we do not need all the configurations done inside 'serial8250_em485_config'.
Thanks,
Tharun Kumar P
On Tue, 1 Nov 2022, Tharunkumar.Pasumarthi@microchip.com wrote:
> > From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> > Sent: Monday, October 3, 2022 2:34 PM
> > To: Kumaravel Thiagarajan - I21417
> > <Kumaravel.Thiagarajan@microchip.com>
> > Subject: Re: [PATCH v2 tty-next 2/3] 8250: microchip: pci1xxxx: Add rs485
> > support to quad-uart driver.
> >
> > [Some people who received this message don't often get email from
> > ilpo.jarvinen@linux.intel.com. Learn why this is important at
> > https://aka.ms/LearnAboutSenderIdentification ]
> >
> > EXTERNAL EMAIL: Do not click links or open attachments unless you know the
> > content is safe
> >
> > > + if (rs485->flags & SER_RS485_ENABLED) {
> > > + memset(rs485->padding, 0, sizeof(rs485->padding));
> >
> > Core handles this for you.
>
> I went through the code and it seems like this is not taken care by the core.
> Do you suggest calling 'serial8250_em485_config' inside 'pci1xxxx_rs485_config' callback?
> This has not been done since we do not need all the configurations done inside 'serial8250_em485_config'.
>
> > > + if (!(rs485->flags & SER_RS485_RTS_ON_SEND)) {
> > > + data |= ADCL_CFG_POL_SEL;
> > > + rs485->flags |= SER_RS485_RTS_AFTER_SEND;
> > > + } else {
> > > + rs485->flags &= ~SER_RS485_RTS_AFTER_SEND;
> > > + }
> >
> > Core handles that flags sanitization for you.
>
> I went through the code and it seems like this is not taken care by the core.
> Do you suggest calling 'serial8250_em485_config' inside 'pci1xxxx_rs485_config' callback?
> This has not been done since we do not need all the configurations done inside 'serial8250_em485_config'.
>
> > > + } else {
> > > + memset(rs485, 0, sizeof(*rs485));
> >
> > Core handles this.
>
> I went through the code and it seems like this is not taken care by the core.
> Do you suggest calling 'serial8250_em485_config' inside 'pci1xxxx_rs485_config' callback?
> This has not been done since we do not need all the configurations done inside 'serial8250_em485_config'.
>
> > > + writeb(data, (port->membase + ADCL_CFG_REG));
> > > + port->rs485 = *rs485;
> >
> > Core handles this.
>
> I went through the code and it seems like this is not taken care by the core.
> Do you suggest calling 'serial8250_em485_config' inside 'pci1xxxx_rs485_config' callback?
> This has not been done since we do not need all the configurations done inside 'serial8250_em485_config'.
It has nothing to do with serial8250_em485_config.
It is very hard to believe you couldn't find
uart_sanitize_serial_rs485() and uart_set_rs485_config() yourself, the
latter calls your driver specific rs485 handler.
--
i.
On Tue, Nov 1, 2022 at 5:25 PM Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> wrote: > On Tue, 1 Nov 2022, Tharunkumar.Pasumarthi@microchip.com wrote: ... > > I went through the code and it seems like this is not taken care by the core. > > Do you suggest calling 'serial8250_em485_config' inside 'pci1xxxx_rs485_config' callback? > > This has not been done since we do not need all the configurations done inside 'serial8250_em485_config'. > > It has nothing to do with serial8250_em485_config. > > It is very hard to believe you couldn't find > uart_sanitize_serial_rs485() and uart_set_rs485_config() yourself, the > latter calls your driver specific rs485 handler. Which version has this API? If it's v6.1-rc1 and patches are made against v6.0, it's possible to miss something. In any case, the patches to the serial subsystem should always be done against the tty/tty-next branch. -- With Best Regards, Andy Shevchenko
On Tue, 1 Nov 2022, Andy Shevchenko wrote: > On Tue, Nov 1, 2022 at 5:25 PM Ilpo Järvinen > <ilpo.jarvinen@linux.intel.com> wrote: > > On Tue, 1 Nov 2022, Tharunkumar.Pasumarthi@microchip.com wrote: > > ... > > > > I went through the code and it seems like this is not taken care by the core. > > > Do you suggest calling 'serial8250_em485_config' inside 'pci1xxxx_rs485_config' callback? > > > This has not been done since we do not need all the configurations done inside 'serial8250_em485_config'. > > > > It has nothing to do with serial8250_em485_config. > > > > It is very hard to believe you couldn't find > > uart_sanitize_serial_rs485() and uart_set_rs485_config() yourself, the > > latter calls your driver specific rs485 handler. > > Which version has this API? If it's v6.1-rc1 and patches are made > against v6.0, it's possible to miss something. > > In any case, the patches to the serial subsystem should always be done > against the tty/tty-next branch. It has been for multiple stable kernel version already. It was moved to own function by this commit: git describe --contains 2dbd0c14ebe8836eaf890c7f50f3fc5d26d67d95 v6.0-rc1~64^2~129 Originally introduced here: git describe --contains 0ed12afa5655512ee418047fb3546d229df20aa1 v5.19-rc1~47^2~142 There have been perhaps one of those things I pointed out that was added later than the others but it won't explain why nothing was found from the code. -- i.
> From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> > Sent: Tuesday, November 1, 2022 9:20 PM > To: Andy Shevchenko <andy.shevchenko@gmail.com> > Subject: Re: [PATCH v2 tty-next 2/3] 8250: microchip: pci1xxxx: Add rs485 > support to quad-uart driver. > > EXTERNAL EMAIL: Do not click links or open attachments unless you know the > content is safe > > There have been perhaps one of those things I pointed out that was added > later than the others but it won't explain why nothing was found from the > code. Sorry Ilpo. This was a mistake from my side. I was referring to older kernel instead of the one in tty-next branch by mistake. I will make sure not to repeat this going forward. Thanks, Tharun Kumar P
© 2016 - 2026 Red Hat, Inc.