diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-08-17 09:09:51 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-08-17 09:09:51 -0700 |
commit | 02dc2723f2b0b94bb3e47c08e1543b84b1836086 (patch) | |
tree | 189cb06a65d9e940ca92d4e0b94162a287263aba /drivers/usb/serial/pl2303.c | |
parent | 17248569499eae54b314fb05c4ff19fd47c9e99b (diff) | |
parent | 26c78daade0fbeef7f20bae3c5508a7c571078cd (diff) | |
download | blackbird-op-linux-02dc2723f2b0b94bb3e47c08e1543b84b1836086.tar.gz blackbird-op-linux-02dc2723f2b0b94bb3e47c08e1543b84b1836086.zip |
Merge tag 'usb-serial-4.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial into usb-next
Johan writes:
USB-serial updates for v4.3-rc1
Here's a fix for a long-standing issue with the pl2303 divisor
calculations that affects some non-standard baudrates that were enabled
in v3.18.
Adding support for newer Edgeport devices and firmware required changes
to the io_ti driver and also exposed some issues with the driver's
current firmware handling.
Included is also a URL comment-typo fix.
Signed-off-by: Johan Hovold <johan@kernel.org>
Diffstat (limited to 'drivers/usb/serial/pl2303.c')
-rw-r--r-- | drivers/usb/serial/pl2303.c | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index f5257af33ecf..ae682e4eeaef 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -362,21 +362,38 @@ static speed_t pl2303_encode_baud_rate_direct(unsigned char buf[4], static speed_t pl2303_encode_baud_rate_divisor(unsigned char buf[4], speed_t baud) { - unsigned int tmp; + unsigned int baseline, mantissa, exponent; /* * Apparently the formula is: - * baudrate = 12M * 32 / (2^buf[1]) / buf[0] + * baudrate = 12M * 32 / (mantissa * 4^exponent) + * where + * mantissa = buf[8:0] + * exponent = buf[11:9] */ - tmp = 12000000 * 32 / baud; + baseline = 12000000 * 32; + mantissa = baseline / baud; + if (mantissa == 0) + mantissa = 1; /* Avoid dividing by zero if baud > 32*12M. */ + exponent = 0; + while (mantissa >= 512) { + if (exponent < 7) { + mantissa >>= 2; /* divide by 4 */ + exponent++; + } else { + /* Exponent is maxed. Trim mantissa and leave. */ + mantissa = 511; + break; + } + } + buf[3] = 0x80; buf[2] = 0; - buf[1] = (tmp >= 256); - while (tmp >= 256) { - tmp >>= 2; - buf[1] <<= 1; - } - buf[0] = tmp; + buf[1] = exponent << 1 | mantissa >> 8; + buf[0] = mantissa & 0xff; + + /* Calculate and return the exact baud rate. */ + baud = (baseline / mantissa) >> (exponent << 1); return baud; } |