From patchwork Tue Dec 25 14:00:22 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Charles Yeh X-Patchwork-Id: 10742573 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id F33C36C2 for ; Tue, 25 Dec 2018 14:00:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E120E28AC8 for ; Tue, 25 Dec 2018 14:00:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D443A28AF9; Tue, 25 Dec 2018 14:00:40 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1E6FC28AC8 for ; Tue, 25 Dec 2018 14:00:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725897AbeLYOAi (ORCPT ); Tue, 25 Dec 2018 09:00:38 -0500 Received: from mail-pl1-f195.google.com ([209.85.214.195]:43809 "EHLO mail-pl1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725878AbeLYOAi (ORCPT ); Tue, 25 Dec 2018 09:00:38 -0500 Received: by mail-pl1-f195.google.com with SMTP id gn14so6573980plb.10 for ; Tue, 25 Dec 2018 06:00:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=+4mELoJtt0Qz3/w/JMezmJKaDPIAm47XAzXMLxt+flE=; b=dqcBDWRm+f4bF2Rsk7Elx50rw+4M5yW8xMs2fHFz2lyJvyXYQ2bifUu0GXSYyOV6/P eBtsWgx0XBmUPWCqFGnqwAOOLaI43KkPQRuc2LU+B+J1f1R0lf2IyuOq4Ol5YoelJA15 ofz7LqGAyQ20sbs/jY7K3UT8DtR6seRK0wYamuCGBioZT8N/uMGYv+PgUJN1G+Floatg 5Z/KgNXjp1+5OMIxfQJ3SQbPAeeZX5waASubC8IMAOiWzKhUJpn789SKSv8mpeq0kl4p 0ZKFtnhmtXUHX0GB3tRHb0ZYYccHDtzZklhTD0jIkVJ75QFq7/yqf6Q0p/jwyHiknxLk k7Aw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=+4mELoJtt0Qz3/w/JMezmJKaDPIAm47XAzXMLxt+flE=; b=akOjUx0nH+0udqsAplOHtYyKi2TgrZ/6ug8ce46oISFIu1HBZ9p+g2uOlNmak5jJtn 6ermrt+6Oq9PlTjlcIUCyZMIgiPgQcgPztT+e4PHICvOiEu1wfnHKAIwYEu0ZCyfgTB9 JRxLuENjUC2k4Jm76yqUfCRF1ziTEbAZszyX26wtl3gmqbycOofzlWL0iweFYOZDxDTE jFM/KXXUTfvti48u9jh4rMLwlsfhILoYoCthIUULPvOjoxke7A50trML0w2Fi/TKiEZ+ iZpA4BiOKINTq5XU+sVz4mJUxM6Vb+3MUYOjzRzmhD5qrJWcT1Zcnz10b7HMxFOPWNi+ 7yAg== X-Gm-Message-State: AJcUukdvhrR0CQ4vhvDaXmNdlE3uP6XglNghyOzfr6bXc7MYNDJp1lI4 1QFs6e8wyodIJFP+6JmvQkWNaeHPqw8= X-Google-Smtp-Source: ALg8bN488fkl7aFsodZzKB1KtcVF/qA0QX0Q3ym7xFr5/QjGQSbJ7KIDdXInnaSPfq4K3S85M25MzQ== X-Received: by 2002:a17:902:f24:: with SMTP id 33mr16638838ply.65.1545746437323; Tue, 25 Dec 2018 06:00:37 -0800 (PST) Received: from localhost.localdomain (220-141-4-93.dynamic-ip.hinet.net. [220.141.4.93]) by smtp.gmail.com with ESMTPSA id u87sm70050467pfi.2.2018.12.25.06.00.35 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 25 Dec 2018 06:00:36 -0800 (PST) From: Charles Yeh To: gregkh@linuxfoundation.org Cc: johan@kernel.org, linux-usb@vger.kernel.org, Charles Yeh Subject: [PATCH] Add Prolific new chip: PL2303TB & PL2303N(G) Date: Tue, 25 Dec 2018 22:00:22 +0800 Message-Id: <20181225140022.3660-1-charlesyeh522@gmail.com> X-Mailer: git-send-email 2.20.1.windows.1 MIME-Version: 1.0 Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add new PID to support PL2303TB (TYPE_HX) Add new PID to support PL2303(N)GC/GB/GS/GT/GL/GE (TYPE_HXN) Add new flow control to support PL2303(N)GC/GB/GS/GT/GL/GE (TYPE_HXN) Add new Down/Up Stream reset to support PL2303(N)GC/GB/GS/GT/GL/GE (TYPE_HXN) Add new Pull-Up Mode to support PL2303HXD (TYPE_HX) Signed-off-by: Charles Yeh --- drivers/usb/serial/pl2303.c | 116 +++++++++++++++++++++++++++++------- drivers/usb/serial/pl2303.h | 11 ++++ 2 files changed, 106 insertions(+), 21 deletions(-) diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index a4e0d13fc121..dde112f06601 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -46,6 +46,13 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_HCR331) }, { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_MOTOROLA) }, { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_ZTEK) }, + { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_TB) }, + { USB_DEVICE(PL2303_VENDOR_ID, PL2303G_PRODUCT_ID_GC) }, + { USB_DEVICE(PL2303_VENDOR_ID, PL2303G_PRODUCT_ID_GB) }, + { USB_DEVICE(PL2303_VENDOR_ID, PL2303G_PRODUCT_ID_GT) }, + { USB_DEVICE(PL2303_VENDOR_ID, PL2303G_PRODUCT_ID_GL) }, + { USB_DEVICE(PL2303_VENDOR_ID, PL2303G_PRODUCT_ID_GE) }, + { USB_DEVICE(PL2303_VENDOR_ID, PL2303G_PRODUCT_ID_GS) }, { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) }, { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) }, { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID), @@ -123,9 +130,11 @@ MODULE_DEVICE_TABLE(usb, id_table); #define VENDOR_WRITE_REQUEST_TYPE 0x40 #define VENDOR_WRITE_REQUEST 0x01 +#define VENDOR_WRITE_NREQUEST 0x80 #define VENDOR_READ_REQUEST_TYPE 0xc0 #define VENDOR_READ_REQUEST 0x01 +#define VENDOR_READ_NREQUEST 0x81 #define UART_STATE_INDEX 8 #define UART_STATE_MSR_MASK 0x8b @@ -139,11 +148,21 @@ MODULE_DEVICE_TABLE(usb, id_table); #define UART_OVERRUN_ERROR 0x40 #define UART_CTS 0x80 +#define TYPE_HX_READ_OTP_STATUS_REGISTER 0x8484 +#define TYPE_HX_EXTERNAL_PULLUP_MODE 0x08 +#define TYPE_HX_PULLUP_MODE_REG 0x09 +#define TYPE_HXN_UART_FLOWCONTROL 0x0A +#define TYPE_HXN_HARDWAREFLOW 0xFA +#define TYPE_HXN_SOFTWAREFLOW 0xEE +#define TYPE_HXN_NOFLOW 0xFF +#define TYPE_HXN_RESET_DOWN_UPSTREAM 0x07 + static void pl2303_set_break(struct usb_serial_port *port, bool enable); 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_COUNT }; @@ -173,16 +192,26 @@ static const struct pl2303_type_data pl2303_type_data[TYPE_COUNT] = { [TYPE_HX] = { .max_baud_rate = 12000000, }, + [TYPE_HXN] = { + .max_baud_rate = 12000000, + }, }; static int pl2303_vendor_read(struct usb_serial *serial, u16 value, unsigned char buf[1]) { struct device *dev = &serial->interface->dev; + struct pl2303_serial_private *spriv = usb_get_serial_data(serial); int res; + u8 request; + + if (spriv->type == &pl2303_type_data[TYPE_HXN]) + request = VENDOR_READ_NREQUEST; + else + request = VENDOR_READ_REQUEST; res = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), - VENDOR_READ_REQUEST, VENDOR_READ_REQUEST_TYPE, + request, VENDOR_READ_REQUEST_TYPE, value, 0, buf, 1, 100); if (res != 1) { dev_err(dev, "%s - failed to read [%04x]: %d\n", __func__, @@ -201,12 +230,19 @@ static int pl2303_vendor_read(struct usb_serial *serial, u16 value, static int pl2303_vendor_write(struct usb_serial *serial, u16 value, u16 index) { struct device *dev = &serial->interface->dev; + struct pl2303_serial_private *spriv = usb_get_serial_data(serial); int res; + u8 request; dev_dbg(dev, "%s - [%04x] = %02x\n", __func__, value, index); + if (spriv->type == &pl2303_type_data[TYPE_HXN]) + request = VENDOR_WRITE_NREQUEST; + else + request = VENDOR_WRITE_REQUEST; + res = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), - VENDOR_WRITE_REQUEST, VENDOR_WRITE_REQUEST_TYPE, + request, VENDOR_WRITE_REQUEST_TYPE, value, index, NULL, 0, 100); if (res) { dev_err(dev, "%s - failed to write [%04x]: %d\n", __func__, @@ -286,6 +322,7 @@ static int pl2303_startup(struct usb_serial *serial) struct pl2303_serial_private *spriv; enum pl2303_type type = TYPE_01; unsigned char *buf; + int res; spriv = kzalloc(sizeof(*spriv), GFP_KERNEL); if (!spriv) @@ -307,26 +344,36 @@ static int pl2303_startup(struct usb_serial *serial) type = TYPE_01; /* type 1 */ dev_dbg(&serial->interface->dev, "device type: %d\n", type); + if (serial->dev->descriptor.bcdUSB == 0x0200) { + res = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), + VENDOR_READ_REQUEST, VENDOR_READ_REQUEST_TYPE, + TYPE_HX_READ_OTP_STATUS_REGISTER, 0, buf, 1, 100); + if (res != 1) + type = TYPE_HXN; + } + spriv->type = &pl2303_type_data[type]; spriv->quirks = (unsigned long)usb_get_serial_data(serial); spriv->quirks |= spriv->type->quirks; usb_set_serial_data(serial, spriv); - pl2303_vendor_read(serial, 0x8484, buf); - pl2303_vendor_write(serial, 0x0404, 0); - pl2303_vendor_read(serial, 0x8484, buf); - pl2303_vendor_read(serial, 0x8383, buf); - pl2303_vendor_read(serial, 0x8484, buf); - pl2303_vendor_write(serial, 0x0404, 1); - pl2303_vendor_read(serial, 0x8484, buf); - pl2303_vendor_read(serial, 0x8383, buf); - pl2303_vendor_write(serial, 0, 1); - pl2303_vendor_write(serial, 1, 0); - if (spriv->quirks & PL2303_QUIRK_LEGACY) - pl2303_vendor_write(serial, 2, 0x24); - else - pl2303_vendor_write(serial, 2, 0x44); + if (type != TYPE_HXN) { + pl2303_vendor_read(serial, 0x8484, buf); + pl2303_vendor_write(serial, 0x0404, 0); + pl2303_vendor_read(serial, 0x8484, buf); + pl2303_vendor_read(serial, 0x8383, buf); + pl2303_vendor_read(serial, 0x8484, buf); + pl2303_vendor_write(serial, 0x0404, 1); + pl2303_vendor_read(serial, 0x8484, buf); + pl2303_vendor_read(serial, 0x8383, buf); + pl2303_vendor_write(serial, 0, 1); + pl2303_vendor_write(serial, 1, 0); + if (spriv->quirks & PL2303_QUIRK_LEGACY) + pl2303_vendor_write(serial, 2, 0x24); + else + pl2303_vendor_write(serial, 2, 0x44); + } kfree(buf); @@ -671,15 +718,37 @@ static void pl2303_set_termios(struct tty_struct *tty, } if (C_CRTSCTS(tty)) { - if (spriv->quirks & PL2303_QUIRK_LEGACY) + if (spriv->type == &pl2303_type_data[TYPE_01]) pl2303_vendor_write(serial, 0x0, 0x41); + else if (spriv->type == &pl2303_type_data[TYPE_HXN]) + pl2303_vendor_write(serial, TYPE_HXN_UART_FLOWCONTROL, + TYPE_HXN_HARDWAREFLOW); else pl2303_vendor_write(serial, 0x0, 0x61); } else if (I_IXON(tty) && !I_IXANY(tty) && START_CHAR(tty) == 0x11 && STOP_CHAR(tty) == 0x13) { - pl2303_vendor_write(serial, 0x0, 0xc0); + if (spriv->type == &pl2303_type_data[TYPE_HXN]) + pl2303_vendor_write(serial, TYPE_HXN_UART_FLOWCONTROL, + TYPE_HXN_SOFTWAREFLOW); + else + pl2303_vendor_write(serial, 0x0, 0xc0); } else { - pl2303_vendor_write(serial, 0x0, 0x0); + if (spriv->type == &pl2303_type_data[TYPE_HXN]) + pl2303_vendor_write(serial, TYPE_HXN_UART_FLOWCONTROL, + TYPE_HXN_NOFLOW); + else + pl2303_vendor_write(serial, 0x0, 0x0); + } + + if (spriv->type == &pl2303_type_data[TYPE_HX]) { + pl2303_vendor_read(serial, 0x8484, buf); + pl2303_vendor_write(serial, 0x0404, TYPE_HX_PULLUP_MODE_REG); + pl2303_vendor_read(serial, 0x8484, buf); + pl2303_vendor_read(serial, 0x8383, buf); + if ((u16)*buf & TYPE_HX_EXTERNAL_PULLUP_MODE) { + pl2303_vendor_write(serial, 0x0, 0x31); + pl2303_vendor_write(serial, 0x1, 0x01); + } } kfree(buf); @@ -720,8 +789,13 @@ static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port) usb_clear_halt(serial->dev, port->read_urb->pipe); } else { /* reset upstream data pipes */ - pl2303_vendor_write(serial, 8, 0); - pl2303_vendor_write(serial, 9, 0); + if (spriv->type == &pl2303_type_data[TYPE_HXN]) + pl2303_vendor_write(serial, + TYPE_HXN_RESET_DOWN_UPSTREAM, 0); + else { + pl2303_vendor_write(serial, 8, 0); + pl2303_vendor_write(serial, 9, 0); + } } /* Setup termios */ diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index 26965cc23c17..f7c500622f6b 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h @@ -20,6 +20,17 @@ #define PL2303_PRODUCT_ID_MOTOROLA 0x0307 #define PL2303_PRODUCT_ID_ZTEK 0xe1f1 +/* PL2303TB , TYPE_HX */ +#define PL2303_PRODUCT_ID_TB 0x2304 + +/* PL2303HXN , TYPE_HXN */ +#define PL2303G_PRODUCT_ID_GC 0x23A3 +#define PL2303G_PRODUCT_ID_GB 0x23B3 +#define PL2303G_PRODUCT_ID_GT 0x23C3 +#define PL2303G_PRODUCT_ID_GL 0x23D3 +#define PL2303G_PRODUCT_ID_GE 0x23E3 +#define PL2303G_PRODUCT_ID_GS 0x23F3 + #define ATEN_VENDOR_ID 0x0557 #define ATEN_VENDOR_ID2 0x0547 #define ATEN_PRODUCT_ID 0x2008