• Johan Hovold's avatar
    USB: serial: ch341: reimplement line-speed handling · 35714565
    Johan Hovold authored
    The current ch341 divisor algorithm was known to give inaccurate results
    for certain higher line speeds. Jonathan Olds <jontio@i4free.co.nz>
    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:
    
    	baudrate = 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.
    requesting 2950000 Bd resulted in a rate of 2 MBd instead of 3 MBd and
    thus 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@5dot1.de> 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-calculationReported-by: default avatarJonathan Olds <jontio@i4free.co.nz>
    Tested-by: default avatarJonathan Olds <jontio@i4free.co.nz>
    Cc: Michael Dreher <michael@5dot1.de>
    Signed-off-by: default avatarJohan Hovold <johan@kernel.org>
    35714565
ch341.c 17.1 KB