On Fri, Nov 01, 2019 at 06:24:10PM +0100, Johan Hovold wrote: > The current ch341 divisor algorithm was known to give inaccurate results > for certain higher line speeds. Jonathan Olds <jontio@xxxxxxxxxxxx> > investigated this, determined the basic equations used to derive the > divisors and confirmed them experimentally [1]. > > The equations Jonathan used could be generalised further to: > > baud = 48000000 / (2^(12 - 3 * ps - fact) * div), where > > 0 <= ps <= 3, > 0 <= fact <= 1, > 2 <= div <= 256 if fact = 0, or > 9 <= div <= 256 if fact = 1 > > which will also give better results for lower rates. > > Notably the error is reduced for the following standard rates: > > 1152000 (4.0% instead of 15% error) > 921600 (0.16% instead of -7.5% error) > 576000 (-0.80% instead of -5.6% error) > 200 (0.16% instead of -0.69% error) > 134 (-0.05% instead of -0.63% error) > 110 (0.03% instead of -0.44% error) > > but also for many non-standard ones. > > The current algorithm also suffered from rounding issues (e.g. 2950000 > was rounded to 2 Mbaud instead of 3 Mbaud resulting in a -32% instead of > 1.7% error). > > The new algorithm was inspired by the current vendor driver even if that > one only handles two higher rates that require fact=1 by hard coding the > corresponding divisors [2]. > > Michael Dreher <michael@xxxxxxxx> also did a similar generalisation of > Jonathan's work and has published his results with a very good summary > that provides further insights into how this device works [3]. > > [1] https://lkml.kernel.org/r/000001d51f34$bad6afd0$30840f70$@co.nz > [2] http://www.wch.cn/download/CH341SER_LINUX_ZIP.html > [3] https://github.com/nospam2000/ch341-baudrate-calculation > > Reported-by: Jonathan Olds <jontio@xxxxxxxxxxxx> > Tested-by: Jonathan Olds <jontio@xxxxxxxxxxxx> > Cc: Michael Dreher <michael@xxxxxxxx> > Signed-off-by: Johan Hovold <johan@xxxxxxxxxx> > --- > drivers/usb/serial/ch341.c | 97 +++++++++++++++++++++++++++++--------- > 1 file changed, 75 insertions(+), 22 deletions(-) I've applied this one for 5.5 now (not 5.4 as I mistakingly said earlier). Johan