linux-usb.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/1] USB: serial: pl2303: TA & TB alternate divider
@ 2021-03-16  1:42 michaelk
  2021-03-16  7:19 ` Greg KH
  0 siblings, 1 reply; 5+ messages in thread
From: michaelk @ 2021-03-16  1:42 UTC (permalink / raw)
  To: linux-usb; +Cc: Michael Katzmann

From: Michael Katzmann <michaelk@IEEE.org>

Use an alternate clock divider algorithm and bit ordering for the TA and
TB versions of the pl2303. It was discovered that these variants do not
produce the correct baud rates with the existing scheme.

see https://marc.info/?t=161392209800002&r=1&w=2

Signed-off-by: Michael G. Katzmann <michaelk@IEEE.org>
---
 drivers/usb/serial/pl2303.c | 45 +++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 7208966891d0..bf5828579918 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -188,6 +188,7 @@ struct pl2303_type_data {
 	unsigned long quirks;
 	unsigned int no_autoxonxoff:1;
 	unsigned int no_divisors:1;
+	unsigned int alt_divisors:1;
 };
 
 struct pl2303_serial_private {
@@ -217,10 +218,12 @@ static const struct pl2303_type_data pl2303_type_data[TYPE_COUNT] = {
 	[TYPE_TA] = {
 		.name			= "TA",
 		.max_baud_rate		= 6000000,
+		.alt_divisors		= true,
 	},
 	[TYPE_TB] = {
 		.name			= "TB",
 		.max_baud_rate		= 12000000,
+		.alt_divisors		= true,
 	},
 	[TYPE_HXD] = {
 		.name			= "HXD",
@@ -618,6 +621,46 @@ static speed_t pl2303_encode_baud_rate_divisor(unsigned char buf[4],
 	return baud;
 }
 
+static speed_t pl2303_encode_baud_rate_divisor_alt(unsigned char buf[4],
+                                                                speed_t baud)
+{
+        unsigned int baseline, mantissa, exponent;
+
+        /*
+         * Apparently, for the TA version the formula is:
+         *   baudrate = 12M * 32 / (mantissa * 2^exponent)
+         * where
+         *   mantissa = buf[10:0]
+         *   exponent = buf[15:13 16]
+         */
+        baseline = 12000000 * 32;
+        mantissa = baseline / baud;
+        if (mantissa == 0)
+                mantissa = 1;   /* Avoid dividing by zero if baud > 32*12M. */
+        exponent = 0;
+        while (mantissa >= 2048) {
+                if (exponent < 15) {
+                        mantissa >>= 1; /* divide by 2 */
+                        exponent++;
+                } else {
+                        /* Exponent is maxed. Trim mantissa and leave. */
+                        mantissa = 2047;
+                        break;
+                }
+        }
+
+        buf[3] = 0x80;
+        buf[2] = exponent & 0x01;
+        buf[1] = (exponent & ~0x01) << 4 | mantissa >> 8;
+        buf[0] = mantissa & 0xff;
+
+        /* Calculate and return the exact baud rate. */
+        baud = (baseline / mantissa) >> exponent;
+
+        return baud;
+}
+
+
 static void pl2303_encode_baud_rate(struct tty_struct *tty,
 					struct usb_serial_port *port,
 					u8 buf[4])
@@ -645,6 +688,8 @@ static void pl2303_encode_baud_rate(struct tty_struct *tty,
 
 	if (baud == baud_sup)
 		baud = pl2303_encode_baud_rate_direct(buf, baud);
+	else if (spriv->type->alt_divisors) 
+                baud = pl2303_encode_baud_rate_divisor_alt(buf, baud);
 	else
 		baud = pl2303_encode_baud_rate_divisor(buf, baud);
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/1] USB: serial: pl2303: TA & TB alternate divider
  2021-03-16  1:42 [PATCH 1/1] USB: serial: pl2303: TA & TB alternate divider michaelk
@ 2021-03-16  7:19 ` Greg KH
  2021-03-16  9:19   ` Johan Hovold
  0 siblings, 1 reply; 5+ messages in thread
From: Greg KH @ 2021-03-16  7:19 UTC (permalink / raw)
  To: michaelk; +Cc: linux-usb

On Mon, Mar 15, 2021 at 09:42:05PM -0400, michaelk@IEEE.org wrote:
> From: Michael Katzmann <michaelk@IEEE.org>
> 
> Use an alternate clock divider algorithm and bit ordering for the TA and
> TB versions of the pl2303. It was discovered that these variants do not
> produce the correct baud rates with the existing scheme.
> 
> see https://marc.info/?t=161392209800002&r=1&w=2

Can you point to a lore.kernel.org thread instead?  We (kernel developer
community) have control over lore, but not over marc.info or any other
archive, so we never know if it will be around or not over time :)

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/1] USB: serial: pl2303: TA & TB alternate divider
  2021-03-16  7:19 ` Greg KH
@ 2021-03-16  9:19   ` Johan Hovold
  0 siblings, 0 replies; 5+ messages in thread
From: Johan Hovold @ 2021-03-16  9:19 UTC (permalink / raw)
  To: Greg KH; +Cc: michaelk, linux-usb

On Tue, Mar 16, 2021 at 08:19:57AM +0100, Greg Kroah-Hartman wrote:
> On Mon, Mar 15, 2021 at 09:42:05PM -0400, michaelk@IEEE.org wrote:
> > From: Michael Katzmann <michaelk@IEEE.org>
> > 
> > Use an alternate clock divider algorithm and bit ordering for the TA and
> > TB versions of the pl2303. It was discovered that these variants do not
> > produce the correct baud rates with the existing scheme.
> > 
> > see https://marc.info/?t=161392209800002&r=1&w=2
> 
> Can you point to a lore.kernel.org thread instead?  We (kernel developer
> community) have control over lore, but not over marc.info or any other
> archive, so we never know if it will be around or not over time :)

I was gonna say that I could fix that up when applying, but turns out
there are some formatting issues with the patch.

Michael, it looks like you've used tabs instead of spaces for
indentation in some places. Try running scripts/checkpatch.pl on the
patch before submitting (which would have caught this).

Care to send a v2?

And the lore link would be:

	https://lore.kernel.org/r/3aee5708-7961-f464-8c5f-6685d96920d6@IEEE.org

Johan

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/1] USB: serial: pl2303: TA & TB alternate divider
@ 2021-03-16 12:06 michaelk
  2021-03-16 15:55 ` Johan Hovold
  0 siblings, 1 reply; 5+ messages in thread
From: michaelk @ 2021-03-16 12:06 UTC (permalink / raw)
  To: michaelk; +Cc: linux-usb

From: Michael Katzmann <michaelk@IEEE.org>

Use an alternate clock divider algorithm and bit ordering for the TA and
TB versions of the pl2303. It was discovered that these variants do not
produce the correct baud rates with the existing scheme.

see https://lore.kernel.org/r/3aee5708-7961-f464-8c5f-6685d96920d6@IEEE.org

Signed-off-by: Michael G. Katzmann <michaelk@IEEE.org>
---
 drivers/usb/serial/pl2303.c | 45 +++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 7208966891d0..bf5828579918 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -188,6 +188,7 @@ struct pl2303_type_data {
 	unsigned long quirks;
 	unsigned int no_autoxonxoff:1;
 	unsigned int no_divisors:1;
+	unsigned int alt_divisors:1;
 };
 
 struct pl2303_serial_private {
@@ -217,10 +218,12 @@ static const struct pl2303_type_data pl2303_type_data[TYPE_COUNT] = {
 	[TYPE_TA] = {
 		.name			= "TA",
 		.max_baud_rate		= 6000000,
+		.alt_divisors		= true,
 	},
 	[TYPE_TB] = {
 		.name			= "TB",
 		.max_baud_rate		= 12000000,
+		.alt_divisors		= true,
 	},
 	[TYPE_HXD] = {
 		.name			= "HXD",
@@ -618,6 +621,46 @@ static speed_t pl2303_encode_baud_rate_divisor(unsigned char buf[4],
 	return baud;
 }
 
+static speed_t pl2303_encode_baud_rate_divisor_alt(unsigned char buf[4],
+                                                                speed_t baud)
+{
+        unsigned int baseline, mantissa, exponent;
+
+        /*
+         * Apparently, for the TA version the formula is:
+         *   baudrate = 12M * 32 / (mantissa * 2^exponent)
+         * where
+         *   mantissa = buf[10:0]
+         *   exponent = buf[15:13 16]
+         */
+        baseline = 12000000 * 32;
+        mantissa = baseline / baud;
+        if (mantissa == 0)
+                mantissa = 1;   /* Avoid dividing by zero if baud > 32*12M. */
+        exponent = 0;
+        while (mantissa >= 2048) {
+                if (exponent < 15) {
+                        mantissa >>= 1; /* divide by 2 */
+                        exponent++;
+                } else {
+                        /* Exponent is maxed. Trim mantissa and leave. */
+                        mantissa = 2047;
+                        break;
+                }
+        }
+
+        buf[3] = 0x80;
+        buf[2] = exponent & 0x01;
+        buf[1] = (exponent & ~0x01) << 4 | mantissa >> 8;
+        buf[0] = mantissa & 0xff;
+
+        /* Calculate and return the exact baud rate. */
+        baud = (baseline / mantissa) >> exponent;
+
+        return baud;
+}
+
+
 static void pl2303_encode_baud_rate(struct tty_struct *tty,
 					struct usb_serial_port *port,
 					u8 buf[4])
@@ -645,6 +688,8 @@ static void pl2303_encode_baud_rate(struct tty_struct *tty,
 
 	if (baud == baud_sup)
 		baud = pl2303_encode_baud_rate_direct(buf, baud);
+	else if (spriv->type->alt_divisors) 
+                baud = pl2303_encode_baud_rate_divisor_alt(buf, baud);
 	else
 		baud = pl2303_encode_baud_rate_divisor(buf, baud);
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/1] USB: serial: pl2303: TA & TB alternate divider
  2021-03-16 12:06 michaelk
@ 2021-03-16 15:55 ` Johan Hovold
  0 siblings, 0 replies; 5+ messages in thread
From: Johan Hovold @ 2021-03-16 15:55 UTC (permalink / raw)
  To: michaelk; +Cc: linux-usb

On Tue, Mar 16, 2021 at 08:06:20AM -0400, michaelk@IEEE.org wrote:
> From: Michael Katzmann <michaelk@IEEE.org>
> 
> Use an alternate clock divider algorithm and bit ordering for the TA and
> TB versions of the pl2303. It was discovered that these variants do not
> produce the correct baud rates with the existing scheme.
> 
> see https://lore.kernel.org/r/3aee5708-7961-f464-8c5f-6685d96920d6@IEEE.org
> 
> Signed-off-by: Michael G. Katzmann <michaelk@IEEE.org>
> ---
>  drivers/usb/serial/pl2303.c | 45 +++++++++++++++++++++++++++++++++++++
>  1 file changed, 45 insertions(+)
 
> +static speed_t pl2303_encode_baud_rate_divisor_alt(unsigned char buf[4],
> +                                                                speed_t baud)
> +{
> +        unsigned int baseline, mantissa, exponent;
> +
> +        /*
> +         * Apparently, for the TA version the formula is:
> +         *   baudrate = 12M * 32 / (mantissa * 2^exponent)
> +         * where
> +         *   mantissa = buf[10:0]
> +         *   exponent = buf[15:13 16]
> +         */
> +        baseline = 12000000 * 32;
> +        mantissa = baseline / baud;
> +        if (mantissa == 0)
> +                mantissa = 1;   /* Avoid dividing by zero if baud > 32*12M. */
> +        exponent = 0;
> +        while (mantissa >= 2048) {
> +                if (exponent < 15) {
> +                        mantissa >>= 1; /* divide by 2 */
> +                        exponent++;
> +                } else {
> +                        /* Exponent is maxed. Trim mantissa and leave. */
> +                        mantissa = 2047;
> +                        break;
> +                }
> +        }
> +
> +        buf[3] = 0x80;
> +        buf[2] = exponent & 0x01;
> +        buf[1] = (exponent & ~0x01) << 4 | mantissa >> 8;
> +        buf[0] = mantissa & 0xff;
> +
> +        /* Calculate and return the exact baud rate. */
> +        baud = (baseline / mantissa) >> exponent;
> +
> +        return baud;
> +}

The code above is still indented using spaces rather than tabs.

> +
> +
>  static void pl2303_encode_baud_rate(struct tty_struct *tty,
>  					struct usb_serial_port *port,
>  					u8 buf[4])
> @@ -645,6 +688,8 @@ static void pl2303_encode_baud_rate(struct tty_struct *tty,
>  
>  	if (baud == baud_sup)
>  		baud = pl2303_encode_baud_rate_direct(buf, baud);
> +	else if (spriv->type->alt_divisors) 
> +                baud = pl2303_encode_baud_rate_divisor_alt(buf, baud);

Same here.

>  	else
>  		baud = pl2303_encode_baud_rate_divisor(buf, baud);

Please include a revision in the subject prefix when resending (e.g.
this would be "[PATCH v2]: USB: ...", generally there should be a
matching short changelog below the '---' cut-off line as well).

Johan

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-03-16 15:56 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-03-16  1:42 [PATCH 1/1] USB: serial: pl2303: TA & TB alternate divider michaelk
2021-03-16  7:19 ` Greg KH
2021-03-16  9:19   ` Johan Hovold
  -- strict thread matches above, loose matches on Subject: below --
2021-03-16 12:06 michaelk
2021-03-16 15:55 ` Johan Hovold

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).