Bug 42586

Summary: CP2104 Device doesn't respond to baudrate change request
Product: Drivers Reporter: Preston Fick (preston.fick)
Component: USBAssignee: Greg Kroah-Hartman (greg)
Status: RESOLVED CODE_FIX    
Severity: normal CC: florian, ronnie.king
Priority: P1    
Hardware: All   
OS: Linux   
Kernel Version: 3.2.0 Subsystem:
Regression: No Bisected commit-id:
Attachments: [PATCH 3.2.0] cp210x: Bug fix for CP2104 baudrate usage
[PATCH 3.2.0] cp210x: Bug fix for CP2104 baudrate usage

Description Preston Fick 2012-01-16 03:01:59 UTC
Problem: When using a Silicon Labs CP2104 device it does not respond properly to a baudrate change request. The USB request is not STALLd or failed, so it appears that the baudrate changes successfully. However, the firmware doesn't actually change the baud rate and it will "stick" at the original rate

Specs:
OS/Kernel Version: GNU/Linux, 3.2.0 (Mainline)
Machine/Processor: i686
Hardware Platform: i386

Steps to reproduce:
- Plug in a CP2104 device via USB to a Linux host and ensure cp210x.ko loads properly and a ttyUSBx device appears in /dev/.
- Connect the other end of the CP2104 device via RS232 to another terminal application.
- Open the ttyUSBx device on the Linux machine using minicom, with baudrate of 115200
- Open the RS232 end of the connection in the other terminal application at the same baud rate (115200)
- Ensure that communication works in both directions
- In minicom, change the baudrate to something other than 115200
- In the other terminal application (on RS232 side) change baudrate to match the new baudrate
- Ensure that data transmission does not occur
- Change the baudrate in the other terminal application (on RS232 side) back to 115200 and confirm data does indeed transfer (confirming that the baudrate on the minicom side never changed)

Proposed solution:
Find the specification for the CP210x here:
http://www.silabs.com/pages/DownloadDoc.aspx?FILEURL=Support%20Documents/TechnicalDocs/AN571.pdf&src=DocumentationWebPart

The specification for the CP210x device proposes two ways to set a baudrate on the device:
- Using a divisor (section 5.3/5.4)
- Using the actual baudrate (section 5.5/5.6)

CP2101/2/3 devices support both the divisor and actual baudrate method, where the CP2104 device uses only the actual baud rate method. The cp210x.ko driver in the Linux Kernel only uses the divisor method. If this is changed to use the actual baud rate method it will fix this bug for the CP2104 while keeping support for the CP2101/2/3 devices.
Comment 1 Preston Fick 2012-01-16 03:55:22 UTC
Created attachment 72081 [details]
[PATCH 3.2.0] cp210x: Bug fix for CP2104 baudrate usage

From: Preston Fick <preston.fick@silabs.com>

This is a patch for the cp210x.ko driver with regards to the following bug report:
CP2104 Device doesn't respond to baudrate change request Bug Report: #42586 in bugzilla.kernel.org: https://bugzilla.kernel.org/show_bug.cgi?id=42586

OS/Kernel version: GNU/Linux 3.2.0 (Mainline)

Description:
This fix changes the way baudrates are set on the CP210x devices from Silicon Labs. The CP2101/2/3 will respond to both a GET/SET_BAUDDIV command, and GET/SET_BAUDRATE command, while CP2104 and higher devices only respond to GET/SET_BAUDRATE. The current cp210x.ko driver in kernel version 3.2.0 only implements the GET/SET_BAUDDIV command.

This patch implements the two new codes for the GET/SET_BAUDRATE commands. Then there is a change in the way that the baudrate is assigned or retrieved. This is done according to the CP210x USB specification in AN571. This document can be found here: http://www.silabs.com/pages/DownloadDoc.aspx?FILEURL=Support%20Documents/TechnicalDocs/AN571.pdf&src=DocumentationWebPart

Sections 5.3/5.4 describe the USB packets for the old baudrate method. Sections 5.5/5.6 describe the USB packets for the new method. This patch also implements the new request scheme, and eliminates the unnecessary baudrate calculations since it uses the "actual baudrate" method.

This patch solves the problem reported for the CP2104 in bug 42586, and also keeps support for all other devices (CP2101/2/3).

This patchfile is also attached to the bug report on bugzilla.kernel.org. This patch has been developed and test on the 3.2.0 mainline kernel version under Ubuntu 10.11.

Signed-off-by: Preston Fick <preston.fick@silabs.com>
Comment 2 Preston Fick 2012-01-17 00:20:33 UTC
Created attachment 72091 [details]
[PATCH 3.2.0] cp210x: Bug fix for CP2104 baudrate usage

Submitting corrected patch as of 1/16/2012.

From: Preston Fick <preston.fick@silabs.com>

This is an updated patch for the cp210x.ko driver with regards to the following bug report:
CP2104 Device doesn't respond to baudrate change request Bug Report: #42586 in
bugzilla.kernel.org: https://bugzilla.kernel.org/show_bug.cgi?id=42586

OS/Kernel version: GNU/Linux 3.2.0 (Mainline)

Description:
This fix changes the way baudrates are set on the CP210x devices from Silicon
Labs. The CP2101/2/3 will respond to both a GET/SET_BAUDDIV command, and
GET/SET_BAUDRATE command, while CP2104 and higher devices only respond to
GET/SET_BAUDRATE. The current cp210x.ko driver in kernel version 3.2.0 only
implements the GET/SET_BAUDDIV command.

This patch implements the two new codes for the GET/SET_BAUDRATE commands. Then
there is a change in the way that the baudrate is assigned or retrieved. This
is done according to the CP210x USB specification in AN571. This document can
be found here:
http://www.silabs.com/pages/DownloadDoc.aspx?FILEURL=Support%20Documents/TechnicalDocs/AN571.pdf&src=DocumentationWebPart

Sections 5.3/5.4 describe the USB packets for the old baudrate method. Sections
5.5/5.6 describe the USB packets for the new method. This patch also implements
the new request scheme, and eliminates the unnecessary baudrate calculations
since it uses the "actual baudrate" method.

This patch solves the problem reported for the CP2104 in bug 42586, and also
keeps support for all other devices (CP2101/2/3).

This patchfile is also attached to the bug report on bugzilla.kernel.org. This
patch has been developed and test on the 3.2.0 mainline kernel version under
Ubuntu 10.11.

Signed-off-by: Preston Fick <preston.fick@silabs.com>
Comment 3 Florian Mickler 2012-02-01 21:05:53 UTC
A patch referencing this bug report has been merged in Linux v3.3-rc2:

commit 7f482fc88ac47662228d6b1f05759797c8936a30
Author: Preston Fick <preston.fick@silabs.com>
Date:   Mon Jan 16 18:14:09 2012 -0600

    USB: cp210x: fix CP2104 baudrate usage