On 3/5/21 4:36 AM, Johan Hovold wrote: > On Fri, Mar 05, 2021 at 05:32:23PM +0800, Charles Yeh wrote: >> 110 bps is not the standard Baud rate, >> PL2303TA don't work with the current Linux driver (d5 0e 00 80), It >> needs to "a8 a6 01 80" > > Ok, thanks for confirming. Then we should be able to fix this up based > on Michael's findings. > >> Johan Hovold <johan@xxxxxxxxxx> 於 2021年2月25日 週四 上午1:00寫道: >> >>> But can you confirm that your PL2303TA works with the current Linux >>> driver at 110 Bd (and doesn't need the alternate divisor encoding)? > > Johan > How about... altering the call to pl2303_encode_baud_rate_divisor (adding 'port') baud = pl2303_encode_baud_rate_divisor(port, buf, baud); and checking for model and altering algorithm as below. I've tested this on the TA version. Michael static speed_t pl2303_encode_baud_rate_divisor(struct usb_serial_port *port, unsigned char buf[4], speed_t baud) { unsigned int baseline, mantissa, exponent; unsigned int bcdDevice = port->serial->dev->descriptor.bcdDevice; unsigned int bcdUSB = port->serial->dev->descriptor.bcdUSB; enum model { eUNKNOWN, eHXD, eHXA, eTA } model; if ( bcdUSB == 0x0110 ) { if( bcdDevice == 0x0400 ) model = eHXD; else if ( bcdDevice == 0x0300 ) model = eHXA; // PL2303HX(A)/XA ( EOL : PHASED OUT SINCE 2012 ) else model = eUNKNOWN; } else if( bcdUSB == 0x200 && bcdDevice == 0x0300 ) { model = eTA; } /* * Apparently the formula is: * baudrate = 12M * 32 / (mantissa * 4^exponent) * where * mantissa = buf[8:0] * exponent = buf[11:9] * * TA version has more precision * uses mantissa = buf[bits 10:0 ] * exponent = buf[bits 15:13] * and x2 prescaler enable by buf[bit 16] */ baseline = 12000000 * 32; mantissa = baseline / baud; if (mantissa == 0) mantissa = 1; /* Avoid dividing by zero if baud > 32*12M. */ exponent = 0; if ( model == eTA ) { while (mantissa >= 2048) { // n.b. below is speculative for the TA chip and is based on original code if (exponent < 15) { // we are going to divide this by 2 later mantissa >>= 1; // divide by 2 exponent++; // currently log2 ... will become log4 } else { /* Exponent is maxed. Trim mantissa and leave. */ mantissa = 2047 ; break; } } buf[2] = exponent & 0x01; // activate x2 prescaler if needed exponent >>= 1; // now log base 4 (losing LSB) buf[1] = (exponent << 5) | (mantissa >> 8); } else { while (mantissa >= 512) { if (exponent < 7) { mantissa >>= 2; /* divide by 4 */ exponent++; } else { /* Exponent is maxed. Trim mantissa and leave. */ mantissa = 511; break; } } buf[2] = 0; buf[1] = exponent << 1 | mantissa >> 8; } buf[3] = 0x80; buf[0] = mantissa & 0xff; /* Calculate and return the exact baud rate. */ baud = (baseline / mantissa / (buf[2] == 0x01 ? 2:1)) >> (exponent << 1); return baud; }