So on more investigation and many hours of trial and error I have determined the correct formua for the non-standard rates with this Prolific 2303. There are four bytes used to send the baud rate. When not using the 'standard' rates, the Linus driver sets byte 3 to 0x80 and bytes 1 and 0 hold the divisor of the clock (12MHz * 32). This divisor is encoded in a special way. The 'exponent' (log 4) and the mantissa. This is calculated by dividing the divisor by 4 until it is less than 512 (the number of times you can do this is the exponent). e then goes in bits 1,2 and 3 of byte 1 with the MSBit of the mantissa in bit 0 of byte 1. Byte 0 holds the lower 8 bits of the mantissa. This does not work on the device I have USB PID/VID/REV is 0673 / 2303/3.00. Instead...the calculation uses 1024 instead of 512 in the method above and the exponent is in byte 1 bits 7,6&5 (the top 2 bits of the mantissa are in bits 0 and 1). I tested this on all baud rates that stty will allow that are not 'standard' and it works. (50, 110 .... 3000000). The changed routine is below. I presume the original driver worked so perhaps this device is a new variant with the same USB VID/PID. Michael static speed_t pl2303_encode_baud_rate_divisor(unsigned char buf[4], speed_t baud) { unsigned int baseline, mantissa, exponent; /* * Apparently the formula is: * baudrate = 12M * 32 / (mantissa * 4^exponent) * where * mantissa = buf[8:0] * exponent = buf[11:9] * * Michael Katzmann: At least versions of the chip VID 0x067b PID 0x2303 bcdDevice 3.00 * uses mantissa = buf[9:0] * exponent = buf[15:13] */ baseline = 12000000 * 32; mantissa = baseline / baud; if (mantissa == 0) mantissa = 1; /* Avoid dividing by zero if baud > 32*12M. */ exponent = 0; #undef ORIGINAL #ifdef ORIGINAL while (mantissa >= 512) { if (exponent < 7) { mantissa >>= 2; /* divide by 4 */ exponent++; } else { /* Exponent is maxed. Trim mantissa and leave. */ mantissa = 511; break; } } buf[3] = 0x80; buf[2] = 0; buf[1] = exponent << 1 | mantissa >> 8; buf[0] = mantissa & 0xff; #else while (mantissa >= 1024) { if (exponent < 7) { mantissa >>= 2; /* divide by 4 */ exponent++; } else { // This is an logical modification of the original code // but I do not know if this an actual limitation /* Exponent is maxed. Trim mantissa and leave. */ mantissa = 1023 ; break; } } buf[3] = 0x80; buf[2] = 0; buf[1] = exponent << 5 | (mantissa >> 8); buf[0] = mantissa & 0xff; #endif /* Calculate and return the exact baud rate. */ baud = (baseline / mantissa) >> (exponent << 1); return baud; } On 2/21/21 10:37 AM, Michael G. Katzmann wrote: > The Linux driver does not seem to produce sensible baud rated for other than the 'supported' rates. > > stty to 110 bd results in ~95,000 bd (that's not a typo but 95 thousand). Other rates like 200 also produce odd speeds although not in a logical manner. > > The data sheets don't describe the formula used for deriving the four bytes used to set the speed. > > I tried adding 110 to the supported rates but this did not produce the correct baud rate so I presume the Windows driver is using a formula different than the one in the Linux driver for 'non standard' baud rates. >