From patchwork Tue Mar 16 12:06:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: michaelk@IEEE.org X-Patchwork-Id: 402213 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D83F9C433E0 for ; Tue, 16 Mar 2021 12:07:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8C1186504E for ; Tue, 16 Mar 2021 12:07:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237599AbhCPMHG (ORCPT ); Tue, 16 Mar 2021 08:07:06 -0400 Received: from beige.elm.relay.mailchannels.net ([23.83.212.16]:62544 "EHLO beige.elm.relay.mailchannels.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237610AbhCPMG5 (ORCPT ); Tue, 16 Mar 2021 08:06:57 -0400 X-Sender-Id: dreamhost|x-authsender|smtp@contentfirst.com Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id BCF9F1E269C; Tue, 16 Mar 2021 12:06:51 +0000 (UTC) Received: from pdx1-sub0-mail-a96.g.dreamhost.com (100-96-27-131.trex.outbound.svc.cluster.local [100.96.27.131]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id E5EFF1E23FD; Tue, 16 Mar 2021 12:06:50 +0000 (UTC) X-Sender-Id: dreamhost|x-authsender|smtp@contentfirst.com Received: from pdx1-sub0-mail-a96.g.dreamhost.com (pop.dreamhost.com [64.90.62.162]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384) by 100.96.27.131 (trex/6.1.1); Tue, 16 Mar 2021 12:06:51 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|smtp@contentfirst.com X-MailChannels-Auth-Id: dreamhost X-Lyrical-Cold: 354702871536d84c_1615896411214_3961716016 X-MC-Loop-Signature: 1615896411214:855673715 X-MC-Ingress-Time: 1615896411213 Received: from pdx1-sub0-mail-a96.g.dreamhost.com (localhost [127.0.0.1]) by pdx1-sub0-mail-a96.g.dreamhost.com (Postfix) with ESMTP id 9A19E86C49; Tue, 16 Mar 2021 05:06:50 -0700 (PDT) Received: from industrynumbers.com (pool-100-15-209-187.washdc.fios.verizon.net [100.15.209.187]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: smtp@contentfirst.com) by pdx1-sub0-mail-a96.g.dreamhost.com (Postfix) with ESMTPSA id 58D107E391; Tue, 16 Mar 2021 05:06:49 -0700 (PDT) Received: by industrynumbers.com (Postfix, from userid 1000) id 8AA56282ABB; Tue, 16 Mar 2021 08:06:48 -0400 (EDT) X-DH-BACKEND: pdx1-sub0-mail-a96 From: michaelk@IEEE.org To: michaelk@IEEE.org Cc: linux-usb@vger.kernel.org Subject: [PATCH 1/1] USB: serial: pl2303: TA & TB alternate divider Date: Tue, 16 Mar 2021 08:06:20 -0400 Message-Id: <20210316120620.888110-1-michaelk@IEEE.org> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org From: Michael Katzmann 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 --- 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);