On Thu, Nov 22, 2018 at 09:27:46PM +0100, Nikolaj Fogh wrote: > 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 for 961200 is significantly > improved for some rates, 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@xxxxxxxxx> > > --- > 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 609198d9594c..0edbd3427548 100644 > --- a/drivers/usb/serial/ftdi_sio.c > +++ b/drivers/usb/serial/ftdi_sio.c > @@ -1130,7 +1130,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; This version turned out to be white-space damaged by gmail (?) with tabs replaced by spaces. I fixed it up manually, but next time try sending the patch to yourself and make sure can apply it (and/or run checkpatch on the result). I also shortened the summary further and edited the commit message very slightly. The result can be seen here (soon): https://git.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial.git/commit/?h=usb-next&id=6abd837104a3a8e1cda64fc4d7675f6c3ece9d8b Again, thanks for fixing this. Johan