2023-04-26 20:09:14

by Corey Minyard

[permalink] [raw]
Subject: Break doesn't work on a CP2105

I have a development board with a CP2105 on it, and I was trying to send
a break to it to do a sysrq. And it wasn't working.

I have verified that the target driver works by setting a really slow
baud rate and sending something with a lot of zero bits. It got breaks
just fine.

If I use TCSBRK, it seems to just send a short time with zeros, not
even a full character's worth. It receives a valid character with the
top few bits set. If I use TCSBRKP with a longer time, like 2.5
seconds, it waits the whole time, then at the very end it gets the
character as with the shorter break.

I can't find a programming manual for the chip, and I'm not sure what's
going on.

-corey


2023-04-26 23:43:20

by Corey Minyard

[permalink] [raw]
Subject: [PATCH] USB: serial: cp210x: work around silicon bug setting break

From: Corey Minyard <[email protected]>

At least on the CP2105, sending this once doesn't work, you have to send
it twice to make it happen. If you only send it once, you will get a
really short time (a few bits) where the break is sent, right when the
break is turned off, thus it isn't recognised as a break. Sending it
twice won't hurt anything, so just do it all the time.

Signed-off-by: Corey Minyard <[email protected]>
---
I played with this a bit, and found this change fixes the issue. It's
not ideal, I suppose, but it works.

drivers/usb/serial/cp210x.c | 9 +++++++++
1 file changed, 9 insertions(+)

diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index cdea1bff3b70..e410a749325b 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -1446,6 +1446,15 @@ static void cp210x_break_ctl(struct tty_struct *tty, int break_state)
dev_dbg(&port->dev, "%s - turning break %s\n", __func__,
state == BREAK_OFF ? "off" : "on");
cp210x_write_u16_reg(port, CP210X_SET_BREAK, state);
+ /*
+ * At least on the CP2105, sending this once doesn't work, you
+ * have to send it twice to make it happen. If you only send
+ * it once, you will get a really short time (a few bits) where
+ * the break is sent, right when the break is turned off, thus
+ * it isn't recognised as a break. Sending it twice won't hurt
+ * anything, so just do it all the time.
+ */
+ cp210x_write_u16_reg(port, CP210X_SET_BREAK, state);
}

#ifdef CONFIG_GPIOLIB
--
2.35.7

2023-05-22 12:13:45

by Johan Hovold

[permalink] [raw]
Subject: Re: Break doesn't work on a CP2105

Hi Corey,

and sorry about the late reply on this.

On Wed, Apr 26, 2023 at 03:04:03PM -0500, Corey Minyard wrote:
> I have a development board with a CP2105 on it, and I was trying to send
> a break to it to do a sysrq. And it wasn't working.
>
> I have verified that the target driver works by setting a really slow
> baud rate and sending something with a lot of zero bits. It got breaks
> just fine.
>
> If I use TCSBRK, it seems to just send a short time with zeros, not
> even a full character's worth. It receives a valid character with the
> top few bits set. If I use TCSBRKP with a longer time, like 2.5
> seconds, it waits the whole time, then at the very end it gets the
> character as with the shorter break.
>
> I can't find a programming manual for the chip, and I'm not sure what's
> going on.

I just verified that break works on the first port of my cp2105 but not
on the second one (I seem to receive the last characters sent instead).

Apparently this is expected as the datasheet (AN571) says the following
about the SET_BREAK command:

This command is not supported on the second CP2105 interface.

Which port are you seeing this behaviour with?

Johan

2023-05-22 13:26:47

by Corey Minyard

[permalink] [raw]
Subject: Re: Break doesn't work on a CP2105

On Mon, May 22, 2023 at 01:59:36PM +0200, Johan Hovold wrote:
> Hi Corey,
>
> and sorry about the late reply on this.

Not a problem, thanks for replying.

>
> On Wed, Apr 26, 2023 at 03:04:03PM -0500, Corey Minyard wrote:
> > I have a development board with a CP2105 on it, and I was trying to send
> > a break to it to do a sysrq. And it wasn't working.
> >
> > I have verified that the target driver works by setting a really slow
> > baud rate and sending something with a lot of zero bits. It got breaks
> > just fine.
> >
> > If I use TCSBRK, it seems to just send a short time with zeros, not
> > even a full character's worth. It receives a valid character with the
> > top few bits set. If I use TCSBRKP with a longer time, like 2.5
> > seconds, it waits the whole time, then at the very end it gets the
> > character as with the shorter break.
> >
> > I can't find a programming manual for the chip, and I'm not sure what's
> > going on.
>
> I just verified that break works on the first port of my cp2105 but not
> on the second one (I seem to receive the last characters sent instead).
>
> Apparently this is expected as the datasheet (AN571) says the following
> about the SET_BREAK command:
>
> This command is not supported on the second CP2105 interface.
>
> Which port are you seeing this behaviour with?

I'm guessing this is it. From the schematic I think this is the
TXD_ECI pin, though I'm not 100% sure. I'd have to dig through the
device tree and SOC manual to be sure which port is which.

Would it be possible to return an error in this situation instead of it
silently not working? Just to avoid others having the same issue.

Thank you,

-corey

2023-06-02 13:11:24

by Johan Hovold

[permalink] [raw]
Subject: Re: Break doesn't work on a CP2105

On Mon, May 22, 2023 at 07:52:45AM -0500, Corey Minyard wrote:
> On Mon, May 22, 2023 at 01:59:36PM +0200, Johan Hovold wrote:

> > I just verified that break works on the first port of my cp2105 but not
> > on the second one (I seem to receive the last characters sent instead).
> >
> > Apparently this is expected as the datasheet (AN571) says the following
> > about the SET_BREAK command:
> >
> > This command is not supported on the second CP2105 interface.
> >
> > Which port are you seeing this behaviour with?
>
> I'm guessing this is it. From the schematic I think this is the
> TXD_ECI pin, though I'm not 100% sure. I'd have to dig through the
> device tree and SOC manual to be sure which port is which.

It should be the second SCI interface which do not support break.

> Would it be possible to return an error in this situation instead of it
> silently not working? Just to avoid others having the same issue.

I just posted a patch series which does that. The USB serial drivers do
not currently return any errors related to break signalling even though
this has been possible since 2008.

The same mechanism can be used to report that break signalling is not
supported by a device or driver, but the USB serial drivers would be the
first tty drivers that actually do this. If it turns out to cause any
trouble we can still use this series to avoid the unnecessary wait.

Care to give the series a try?

https://lore.kernel.org/lkml/[email protected]

Johan

2023-06-02 17:32:23

by Corey Minyard

[permalink] [raw]
Subject: Re: Break doesn't work on a CP2105

On Fri, Jun 02, 2023 at 02:53:31PM +0200, Johan Hovold wrote:
> On Mon, May 22, 2023 at 07:52:45AM -0500, Corey Minyard wrote:
> > On Mon, May 22, 2023 at 01:59:36PM +0200, Johan Hovold wrote:
>
> > > I just verified that break works on the first port of my cp2105 but not
> > > on the second one (I seem to receive the last characters sent instead).
> > >
> > > Apparently this is expected as the datasheet (AN571) says the following
> > > about the SET_BREAK command:
> > >
> > > This command is not supported on the second CP2105 interface.
> > >
> > > Which port are you seeing this behaviour with?
> >
> > I'm guessing this is it. From the schematic I think this is the
> > TXD_ECI pin, though I'm not 100% sure. I'd have to dig through the
> > device tree and SOC manual to be sure which port is which.
>
> It should be the second SCI interface which do not support break.
>
> > Would it be possible to return an error in this situation instead of it
> > silently not working? Just to avoid others having the same issue.
>
> I just posted a patch series which does that. The USB serial drivers do
> not currently return any errors related to break signalling even though
> this has been possible since 2008.
>
> The same mechanism can be used to report that break signalling is not
> supported by a device or driver, but the USB serial drivers would be the
> first tty drivers that actually do this. If it turns out to cause any
> trouble we can still use this series to avoid the unnecessary wait.
>
> Care to give the series a try?
>
> https://lore.kernel.org/lkml/[email protected]

I have tested this series. I can verify that one of the CP2105 ports
(ttyUSB0) does not return an error on sending the break, and the other
(ttyUSB1) does. This is the only USB serial device on the system.

However, the device hooked to the remote console (ttyUSB0), the one not
returning an error on sending a break, still doesn't send a break. So
my problem isn't fixed :-(.

# ls -l /dev/serial/by-path
total 0
lrwxrwxrwx 1 root root 13 Jun 2 15:28 pci-0000:00:1d.0-usb-0:1.1:1.0-port0 -> ../../ttyUSB0
lrwxrwxrwx 1 root root 13 Jun 2 15:28 pci-0000:00:1d.0-usb-0:1.1:1.1-port0 -> ../../ttyUSB1

-corey

>
> Johan

2023-06-04 12:21:39

by Johan Hovold

[permalink] [raw]
Subject: Re: Break doesn't work on a CP2105

On Fri, Jun 02, 2023 at 11:46:56AM -0500, Corey Minyard wrote:
> On Fri, Jun 02, 2023 at 02:53:31PM +0200, Johan Hovold wrote:

> > I just posted a patch series which does that. The USB serial drivers do
> > not currently return any errors related to break signalling even though
> > this has been possible since 2008.
> >
> > The same mechanism can be used to report that break signalling is not
> > supported by a device or driver, but the USB serial drivers would be the
> > first tty drivers that actually do this. If it turns out to cause any
> > trouble we can still use this series to avoid the unnecessary wait.
> >
> > Care to give the series a try?
> >
> > https://lore.kernel.org/lkml/[email protected]
>
> I have tested this series. I can verify that one of the CP2105 ports
> (ttyUSB0) does not return an error on sending the break, and the other
> (ttyUSB1) does. This is the only USB serial device on the system.

Thanks for testing.

> However, the device hooked to the remote console (ttyUSB0), the one not
> returning an error on sending a break, still doesn't send a break. So
> my problem isn't fixed :-(.
>
> # ls -l /dev/serial/by-path
> total 0
> lrwxrwxrwx 1 root root 13 Jun 2 15:28 pci-0000:00:1d.0-usb-0:1.1:1.0-port0 -> ../../ttyUSB0
> lrwxrwxrwx 1 root root 13 Jun 2 15:28 pci-0000:00:1d.0-usb-0:1.1:1.1-port0 -> ../../ttyUSB1

Ok, at least that matches what you found in schematics about this being
the ECI (and thus first) port.

I just verified break signalling on the first port of my CP2105 using a
logic analyser and everything seems to work as expected.

There's also no mention of any issue with break in the errata.

Could you check which firmware revision you have by enabling debugging
and reconnecting the device?

For example:

echo func cp210x_get_fw_version +p > /sys/kernel/debug/dynamic_debug/control

Johan

2023-06-04 20:36:06

by Corey Minyard

[permalink] [raw]
Subject: Re: Break doesn't work on a CP2105

On Sun, Jun 04, 2023 at 02:17:16PM +0200, Johan Hovold wrote:
> On Fri, Jun 02, 2023 at 11:46:56AM -0500, Corey Minyard wrote:
> > On Fri, Jun 02, 2023 at 02:53:31PM +0200, Johan Hovold wrote:
>
> > > I just posted a patch series which does that. The USB serial drivers do
> > > not currently return any errors related to break signalling even though
> > > this has been possible since 2008.
> > >
> > > The same mechanism can be used to report that break signalling is not
> > > supported by a device or driver, but the USB serial drivers would be the
> > > first tty drivers that actually do this. If it turns out to cause any
> > > trouble we can still use this series to avoid the unnecessary wait.
> > >
> > > Care to give the series a try?
> > >
> > > https://lore.kernel.org/lkml/[email protected]
> >
> > I have tested this series. I can verify that one of the CP2105 ports
> > (ttyUSB0) does not return an error on sending the break, and the other
> > (ttyUSB1) does. This is the only USB serial device on the system.
>
> Thanks for testing.
>
> > However, the device hooked to the remote console (ttyUSB0), the one not
> > returning an error on sending a break, still doesn't send a break. So
> > my problem isn't fixed :-(.
> >
> > # ls -l /dev/serial/by-path
> > total 0
> > lrwxrwxrwx 1 root root 13 Jun 2 15:28 pci-0000:00:1d.0-usb-0:1.1:1.0-port0 -> ../../ttyUSB0
> > lrwxrwxrwx 1 root root 13 Jun 2 15:28 pci-0000:00:1d.0-usb-0:1.1:1.1-port0 -> ../../ttyUSB1
>
> Ok, at least that matches what you found in schematics about this being
> the ECI (and thus first) port.
>
> I just verified break signalling on the first port of my CP2105 using a
> logic analyser and everything seems to work as expected.
>
> There's also no mention of any issue with break in the errata.
>
> Could you check which firmware revision you have by enabling debugging
> and reconnecting the device?
>
> For example:
>
> echo func cp210x_get_fw_version +p > /sys/kernel/debug/dynamic_debug/control

I couldn't get that to work (didn't try too hard), so I just stuck in a dev_info():

[ 4.253869] usb 2-1.2: new full-speed USB device number 3 using ehci-pci
[ 4.342570] usb 2-1.2: New USB device found, idVendor=10c4, idProduct=ea70, bcdDevice= 1.00
[ 4.350939] usb 2-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=5
[ 4.358259] usb 2-1.2: Product: CP2105 Dual USB to UART Bridge Controller
[ 4.365052] usb 2-1.2: Manufacturer: Silicon Labs
[ 4.369765] usb 2-1.2: SerialNumber: 01070456
[ 4.374925] cp210x 2-1.2:1.0: cp210x converter detected
[ 4.381086] cp210x 2-1.2:1.0: cp210x_get_fw_version - 1.18.1
[ 4.386915] usb 2-1.2: cp210x converter now attached to ttyUSB0
[ 4.393529] cp210x 2-1.2:1.1: cp210x converter detected
[ 4.399835] cp210x 2-1.2:1.1: cp210x_get_fw_version - 1.18.1
[ 4.405657] usb 2-1.2: cp210x converter now attached to ttyUSB1

This is an embedded reference board, I guess there is some probability
that this is just broken on this board, though I'm not quite sure how.

Thanks for working on this.

-corey

2023-06-05 07:21:11

by Johan Hovold

[permalink] [raw]
Subject: Re: Break doesn't work on a CP2105

On Sun, Jun 04, 2023 at 03:11:43PM -0500, Corey Minyard wrote:
> On Sun, Jun 04, 2023 at 02:17:16PM +0200, Johan Hovold wrote:

> > I just verified break signalling on the first port of my CP2105 using a
> > logic analyser and everything seems to work as expected.
> >
> > There's also no mention of any issue with break in the errata.
> >
> > Could you check which firmware revision you have by enabling debugging
> > and reconnecting the device?

> [ 4.253869] usb 2-1.2: new full-speed USB device number 3 using ehci-pci
> [ 4.342570] usb 2-1.2: New USB device found, idVendor=10c4, idProduct=ea70, bcdDevice= 1.00
> [ 4.350939] usb 2-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=5
> [ 4.358259] usb 2-1.2: Product: CP2105 Dual USB to UART Bridge Controller
> [ 4.365052] usb 2-1.2: Manufacturer: Silicon Labs
> [ 4.369765] usb 2-1.2: SerialNumber: 01070456
> [ 4.374925] cp210x 2-1.2:1.0: cp210x converter detected
> [ 4.381086] cp210x 2-1.2:1.0: cp210x_get_fw_version - 1.18.1
> [ 4.386915] usb 2-1.2: cp210x converter now attached to ttyUSB0
> [ 4.393529] cp210x 2-1.2:1.1: cp210x converter detected
> [ 4.399835] cp210x 2-1.2:1.1: cp210x_get_fw_version - 1.18.1
> [ 4.405657] usb 2-1.2: cp210x converter now attached to ttyUSB1

So we have the same firmware revision.

> This is an embedded reference board, I guess there is some probability
> that this is just broken on this board, though I'm not quite sure how.

Is the port accessible somehow so that you could hook up a scope or
logic analyser? Or is that what you did already when you mentioned
seeing garbage sent after 2.5 seconds?

That last bit seems to match the behaviour I see with the second, SCI
port, where the last character sent is resent when trying to signal a
break.

Johan

2023-06-05 12:30:19

by Corey Minyard

[permalink] [raw]
Subject: Re: Break doesn't work on a CP2105

On Mon, Jun 05, 2023 at 09:15:28AM +0200, Johan Hovold wrote:
> On Sun, Jun 04, 2023 at 03:11:43PM -0500, Corey Minyard wrote:
> > On Sun, Jun 04, 2023 at 02:17:16PM +0200, Johan Hovold wrote:
>
> > > I just verified break signalling on the first port of my CP2105 using a
> > > logic analyser and everything seems to work as expected.
> > >
> > > There's also no mention of any issue with break in the errata.
> > >
> > > Could you check which firmware revision you have by enabling debugging
> > > and reconnecting the device?
>
> > [ 4.253869] usb 2-1.2: new full-speed USB device number 3 using ehci-pci
> > [ 4.342570] usb 2-1.2: New USB device found, idVendor=10c4, idProduct=ea70, bcdDevice= 1.00
> > [ 4.350939] usb 2-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=5
> > [ 4.358259] usb 2-1.2: Product: CP2105 Dual USB to UART Bridge Controller
> > [ 4.365052] usb 2-1.2: Manufacturer: Silicon Labs
> > [ 4.369765] usb 2-1.2: SerialNumber: 01070456
> > [ 4.374925] cp210x 2-1.2:1.0: cp210x converter detected
> > [ 4.381086] cp210x 2-1.2:1.0: cp210x_get_fw_version - 1.18.1
> > [ 4.386915] usb 2-1.2: cp210x converter now attached to ttyUSB0
> > [ 4.393529] cp210x 2-1.2:1.1: cp210x converter detected
> > [ 4.399835] cp210x 2-1.2:1.1: cp210x_get_fw_version - 1.18.1
> > [ 4.405657] usb 2-1.2: cp210x converter now attached to ttyUSB1
>
> So we have the same firmware revision.
>
> > This is an embedded reference board, I guess there is some probability
> > that this is just broken on this board, though I'm not quite sure how.
>
> Is the port accessible somehow so that you could hook up a scope or
> logic analyser? Or is that what you did already when you mentioned
> seeing garbage sent after 2.5 seconds?

I didn't hook up a scope, but I did set the baud to a really low rate
and send a character that was all zeros and got a break on the other
end. It wasn't garbage I was seeing after 2.5 seconds, it was basically
a small number of 0 bits, it appeared.

I have a scope that I can capture with, but this is all embedded onto a
board. I looked at the schematic and there are some resistors that I
could hook to, perhaps. I'll see what I can do, but I don't have
surface mount stuff to be able to attach easily.

Thank you,

-corey

>
> That last bit seems to match the behaviour I see with the second, SCI
> port, where the last character sent is resent when trying to signal a
> break.
>
> Johan