From patchwork Wed Dec 26 12:28:10 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Charles Yeh X-Patchwork-Id: 10743011 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 0CC9D13B5 for ; Wed, 26 Dec 2018 12:30:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E1DFA285A8 for ; Wed, 26 Dec 2018 12:30:02 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D56542897E; Wed, 26 Dec 2018 12:30:02 +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 1A759285A8 for ; Wed, 26 Dec 2018 12:30:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726770AbeLZMaA (ORCPT ); Wed, 26 Dec 2018 07:30:00 -0500 Received: from mail-pl1-f195.google.com ([209.85.214.195]:37598 "EHLO mail-pl1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726720AbeLZM37 (ORCPT ); Wed, 26 Dec 2018 07:29:59 -0500 Received: by mail-pl1-f195.google.com with SMTP id b5so7510762plr.4 for ; Wed, 26 Dec 2018 04:29:58 -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=rBFIQ/XzYRRRJQ/t5p9W6pzJyHyEHXMwjoyKG6F7+uc=; b=lQeuMdAOoVXiHsowXMtOpLS4HI2DHKfKkzf3KAbvcV07crMtyyBYOaWMyBgpu5ZUNf V8fs8rQsT4VNfPDoE5/fWKCsQmCusZXJp0OPIbf8082AzvYl6G7+g/j9QOVrV3XLLoXx 5+72m4piVjwBekoLY837FopdHOG6qRt4j/JRBpI9kMib33+mUr4xQeK6wmo4HJ/nlHD1 VcWvKx6nWvtAjzZLYFEpjUIFkQJTiNepSFBFA6x/ZhQ9PmGt0EI9hpSTN0bEtmDYw59U AuHvCoxqyOSnxqeU4go02c/1S/+3Vb0x+GyPi6ikMNp1VJITHHzcNGP+xioGX2utbeb+ lbRA== 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=rBFIQ/XzYRRRJQ/t5p9W6pzJyHyEHXMwjoyKG6F7+uc=; b=ueLNnxy/C3qhpZToAXWForQhjoImKyI3xqDNdHRf9YWfpLYyT+vjb4EUeqU7L14lqs pUaIL9LG48JJr1xx38TW/kAEkSrfjNTfXC3LgeC/3DLHGYLvWR1rENDfTKSZYek8AaCs p3Oz2XiTFNrzqK6Qq3D/TAuuFiLj6M74UIDPp8bMA21R0kWyifYhC5usXl/6Lmir1MZ2 IdwxYwMNmk02YNMn4keCR0e3sDrNR49mYwyCw66awFN24clqRwnrX1UVDsyT3vNxwJaL t7m3k17CPylwtbOX3OhOsi/deahpwDranKg6n2RojAX8PBXarz1W43U/XuFveFAlR41y cR1w== X-Gm-Message-State: AJcUukfkE9OKThRo4Wx2oaoGn6BDxuW+STWhmqHw9F50IvO/uqyNxHqw anHwbffr8BzlbGjf0bpJpLM= X-Google-Smtp-Source: ALg8bN7y9WOniIxWSqYRmxvyHOzoTDA2bPQNzUwK/2fHGEV8giHavQlTXg7Qenq3w4D/4YqfLJOTeA== X-Received: by 2002:a17:902:b118:: with SMTP id q24mr19838376plr.209.1545827397707; Wed, 26 Dec 2018 04:29:57 -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 c7sm68101313pfh.18.2018.12.26.04.29.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 26 Dec 2018 04:29:56 -0800 (PST) From: Charles Yeh To: lkp@intel.com Cc: kbuild-all@01.org, gregkh@linuxfoundation.org, johan@kernel.org, linux-usb@vger.kernel.org, charles-yeh@prolific.com.tw, Charles Yeh Subject: [PATCH] Add Proliic new chip: PL2303TB & PL2303N(G) Date: Wed, 26 Dec 2018 20:28:10 +0800 Message-Id: <20181226122810.1716-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 Pull-Up Mode to support PL2303HXD (TYPE_HX) Fixed warning:restricted__le16 degrades to integer 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..8c71612e1811 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 (type == TYPE_HX) { + 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