On 3/5/21 4:36 AM, Johan Hovold wrote: oops I should have looked at the previous code determining variants... take 2... #define PL2303_QUIRK_DIVISOR_TA BIT(3) enum pl2303_type { TYPE_01, /* Type 0 and 1 (difference unknown) */ TYPE_HX, /* HX version of the pl2303 chip */ TYPE_HXN, /* HXN version of the pl2303 chip */ TYPE_TA, /* TA version of the pl2303 chip */ TYPE_COUNT }; static const struct pl2303_type_data pl2303_type_data[TYPE_COUNT] = .... [TYPE_TA] = { .max_baud_rate = 6000000, .quirks = PL2303_QUIRK_DIVISOR_TA, }, }; static int pl2303_startup(struct usb_serial *serial) { .... if ( serial->dev->descriptor.bcdDevice == 0x0300 && serial->dev->descriptor.bcdUSB == 0x0200 ) type = TYPE_TA; else if (serial->dev->descriptor.bDeviceClass == 0x02) .... } 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; struct usb_serial *serial = port->serial; struct pl2303_serial_private *spriv = usb_get_serial_data(serial); /* * 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 (spriv->quirks & PL2303_QUIRK_DIVISOR_TA) { while (mantissa >= 2048) { // exponent is three bits (after shifting right) 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; } static void pl2303_encode_baud_rate(struct tty_struct *tty, struct usb_serial_port *port, u8 buf[4]) { .... else baud = pl2303_encode_baud_rate_divisor(port, buf, baud); .... }