lkml.org 
[lkml]   [2019]   [Jan]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 4.9 08/36] USB: serial: ftdi_sio: use rounding when calculating baud rate divisors
    Date
    From: Nikolaj Fogh <nikolajfogh@gmail.com>

    [ Upstream commit 6abd837104a3a8e1cda64fc4d7675f6c3ece9d8b ]

    Improve baud-rate generation by using rounding-to-closest instead of
    truncation in divisor calculation.

    Results have been verified by logic analyzer on an FT232RT (232BM) chip.
    The following table shows the wanted baud rate, the baud rate obtained
    with the old method (truncation), with the new method (rounding) and the
    baud rate generated by the windows 10 driver. The numbers in parentheses
    is the error.

    +- Wanted --+------ Old -------+------ New -------+------ Win -------+
    |   9600  |   9600 (0.00%)  |   9604 (0.05%)  |   9605 (0.05%)  |
    |   19200   |   19200 (0.00%)  |   19199 (0.01%)  |   19198 (0.01%)  |
    |   38400   |   38395 (0.01%)  |   38431 (0.08%)  |   38394 (0.02%)  |
    |   57600   |   57725 (0.22%)  |   57540 (0.10%)  |   57673 (0.13%)  |
    |  115200   |  115307 (0.09%)  |  115330 (0.11%)  |  115320 (0.10%)  |
    |  921600   |  919963 (0.18%)  |  920386 (0.13%)  |  920810 (0.09%)  |
    |  961200   |  996512 (3.67%)  |  956480 (0.49%)  |  956937 (0.44%)  |
    +-----------+------------------+------------------+------------------+

    The error due to noise in the measurements is in the order of a few
    tenths of a %. As can be seen, the baud rate is significantly improved
    for some rates (e.g. 961200), and corresponds to the output given by the
    windows driver.

    The theoretical baud rate has been calculated for all baud rates from 1
    to 3M, and as expected, the error is centered around 0, with a triangle
    shape instead of a sawtooth, so the maximum error is decreased to half.

    Signed-off-by: Nikolaj Fogh <nikolajfogh@gmail.com>
    [ johan: edit commit message slightly ]
    Signed-off-by: Johan Hovold <johan@kernel.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/usb/serial/ftdi_sio.c | 6 +++---
    1 file changed, 3 insertions(+), 3 deletions(-)

    diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
    index 2e2f736384ab..48efc6c7e86b 100644
    --- a/drivers/usb/serial/ftdi_sio.c
    +++ b/drivers/usb/serial/ftdi_sio.c
    @@ -1119,7 +1119,7 @@ static unsigned short int ftdi_232am_baud_base_to_divisor(int baud, int base)
    {
    unsigned short int divisor;
    /* divisor shifted 3 bits to the left */
    - int divisor3 = base / 2 / baud;
    + int divisor3 = DIV_ROUND_CLOSEST(base, 2 * baud);
    if ((divisor3 & 0x7) == 7)
    divisor3++; /* round x.7/8 up to x+1 */
    divisor = divisor3 >> 3;
    @@ -1145,7 +1145,7 @@ static __u32 ftdi_232bm_baud_base_to_divisor(int baud, int base)
    static const unsigned char divfrac[8] = { 0, 3, 2, 4, 1, 5, 6, 7 };
    __u32 divisor;
    /* divisor shifted 3 bits to the left */
    - int divisor3 = base / 2 / baud;
    + int divisor3 = DIV_ROUND_CLOSEST(base, 2 * baud);
    divisor = divisor3 >> 3;
    divisor |= (__u32)divfrac[divisor3 & 0x7] << 14;
    /* Deal with special cases for highest baud rates. */
    @@ -1168,7 +1168,7 @@ static __u32 ftdi_2232h_baud_base_to_divisor(int baud, int base)
    int divisor3;

    /* hi-speed baud rate is 10-bit sampling instead of 16-bit */
    - divisor3 = base * 8 / (baud * 10);
    + divisor3 = DIV_ROUND_CLOSEST(8 * base, 10 * baud);

    divisor = divisor3 >> 3;
    divisor |= (__u32)divfrac[divisor3 & 0x7] << 14;
    --
    2.19.1
    \
     
     \ /
      Last update: 2019-01-08 20:43    [W:2.295 / U:0.020 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site