Break doesn't work on a CP2105
Subsystems (2)
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
PATCH 1/1 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.
---
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(+)
drivers/usb/serial/cp210x.c +9 -0
@@ -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
Signature · 1 line
2.35.7
Johan Hovold
maintainerHi Corey,
and sorry about the late reply on this.
Quoted 7 lines · Corey Minyard
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.
Quoted 8 lines
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
Quoted 3 lines · Johan Hovold
Hi Corey,
and sorry about the late reply on this.
Not a problem, thanks for replying.
Quoted 21 lines · Corey Minyard
Quoted 7 lines
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.
Quoted 8 lines
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).
Quoted 6 lines
Apparently this is expected as the datasheet (AN571) says the following about the
SET_BREAKcommand: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
Johan Hovold
maintainerQuoted 8 lines · Corey Minyard
Quoted 6 lines · Johan Hovold
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_BREAKcommand:
Quoted 7 lines
Quoted 3 lines
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_ECIpin, 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.
Quoted 2 lines
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
Quoted 26 lines · Johan Hovold
Quoted 8 lines · Corey Minyard
Quoted 6 lines · Johan Hovold
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_BREAKcommand:Quoted 7 lines
Quoted 3 lines
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_ECIpin, 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.
Quoted 2 lines
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.
Quoted 8 lines
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
Quoted 2 lines
Johan
Johan Hovold
maintainerQuoted 11 lines · Corey Minyard
Quoted 9 lines · Johan Hovold
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.
Quoted 7 lines
Quoted 3 lines
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.
Quoted 8 lines
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
Quoted 37 lines · Johan Hovold
Quoted 11 lines · Corey Minyard
Quoted 9 lines · Johan Hovold
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.
Quoted 7 lines
Quoted 3 lines
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.
Quoted 8 lines
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 -> ../../ttyUSB1Ok, 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.
Quoted 8 lines
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
Johan Hovold
maintainerQuoted 10 lines · Corey Minyard
Quoted 7 lines · Johan Hovold
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?
Quoted 12 lines
[ 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.
Quoted 2 lines
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
Quoted 24 lines · Johan Hovold
Quoted 10 lines · Corey Minyard
Quoted 7 lines · Johan Hovold
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?
Quoted 12 lines
[ 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
Quoted 8 lines
So we have the same firmware revision.
Quoted 2 lines
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
Quoted 6 lines
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