|
Takashi Iwai |
f6a509 |
From ebd09f1cd417fce9c85de3abcabf51eadf907a2a Mon Sep 17 00:00:00 2001
|
|
Takashi Iwai |
f6a509 |
From: Charles Yeh <charlesyeh522@gmail.com>
|
|
Takashi Iwai |
f6a509 |
Date: Tue, 24 Sep 2019 20:14:00 +0800
|
|
Takashi Iwai |
f6a509 |
Subject: [PATCH] USB: serial: pl2303: add support for PL2303HXN
|
|
Takashi Iwai |
f6a509 |
Git-commit: ebd09f1cd417fce9c85de3abcabf51eadf907a2a
|
|
Takashi Iwai |
f6a509 |
Patch-mainline: v5.5-rc1
|
|
Takashi Iwai |
f6a509 |
References: bsc#1186320
|
|
Takashi Iwai |
f6a509 |
|
|
Takashi Iwai |
f6a509 |
Prolific has developed a new USB to UART chip: PL2303HXN
|
|
Takashi Iwai |
f6a509 |
PL2303HXN : PL2303GC/PL2303GS/PL2303GT/PL2303GL/PL2303GE/PL2303GB
|
|
Takashi Iwai |
f6a509 |
The Vendor request used by the PL2303HXN (TYPE_HXN) is different from
|
|
Takashi Iwai |
f6a509 |
the existing PL2303 series (TYPE_HX & TYPE_01).
|
|
Takashi Iwai |
f6a509 |
Therefore, different Vendor requests are used to issue related commands.
|
|
Takashi Iwai |
f6a509 |
|
|
Takashi Iwai |
f6a509 |
1. Added a new TYPE_HXN type in pl2303_type_data, and then executes
|
|
Takashi Iwai |
f6a509 |
new Vendor request,new flow control and other related instructions
|
|
Takashi Iwai |
f6a509 |
if TYPE_HXN is recognized.
|
|
Takashi Iwai |
f6a509 |
|
|
Takashi Iwai |
f6a509 |
2. Because the new PL2303HXN only accept the new Vendor request,
|
|
Takashi Iwai |
f6a509 |
the old Vendor request cannot be accepted (the error message
|
|
Takashi Iwai |
f6a509 |
will be returned)
|
|
Takashi Iwai |
f6a509 |
So first determine the TYPE_HX or TYPE_HXN through
|
|
Takashi Iwai |
f6a509 |
PL2303_READ_TYPE_HX_STATUS in pl2303_startup.
|
|
Takashi Iwai |
f6a509 |
|
|
Takashi Iwai |
f6a509 |
2.1 If the return message is "1", then the PL2303 is the existing
|
|
Takashi Iwai |
f6a509 |
TYPE_HX/ TYPE_01 series.
|
|
Takashi Iwai |
f6a509 |
The other settings in pl2303_startup are to continue execution.
|
|
Takashi Iwai |
f6a509 |
2.2 If the return message is "not 1", then the PL2303 is the new
|
|
Takashi Iwai |
f6a509 |
TYPE_HXN series.
|
|
Takashi Iwai |
f6a509 |
The other settings in pl2303_startup are ignored.
|
|
Takashi Iwai |
f6a509 |
(PL2303HXN will directly use the default value in the hardware,
|
|
Takashi Iwai |
f6a509 |
no need to add additional settings through the software)
|
|
Takashi Iwai |
f6a509 |
|
|
Takashi Iwai |
f6a509 |
3. In pl2303_open: Because TYPE_HXN is different from the instruction of reset
|
|
Takashi Iwai |
f6a509 |
down/up stream used by TYPE_HX.
|
|
Takashi Iwai |
f6a509 |
Therefore, we will also execute different instructions here.
|
|
Takashi Iwai |
f6a509 |
|
|
Takashi Iwai |
f6a509 |
4. In pl2303_set_termios: The UART flow control instructions used by
|
|
Takashi Iwai |
f6a509 |
TYPE_HXN/TYPE_HX/TYPE_01 are different.
|
|
Takashi Iwai |
f6a509 |
Therefore, we will also execute different instructions here.
|
|
Takashi Iwai |
f6a509 |
|
|
Takashi Iwai |
f6a509 |
5. In pl2303_vendor_read & pl2303_vendor_write, since TYPE_HXN is different
|
|
Takashi Iwai |
f6a509 |
from the vendor request instruction used by TYPE_HX/TYPE_01,
|
|
Takashi Iwai |
f6a509 |
it will also execute different instructions here.
|
|
Takashi Iwai |
f6a509 |
|
|
Takashi Iwai |
f6a509 |
6. In pl2303_update_reg: TYPE_HXN used different register for flow control.
|
|
Takashi Iwai |
f6a509 |
Therefore, we will also execute different instructions here.
|
|
Takashi Iwai |
f6a509 |
|
|
Takashi Iwai |
f6a509 |
Signed-off-by: Charles Yeh <charlesyeh522@gmail.com>
|
|
Takashi Iwai |
f6a509 |
Signed-off-by: Johan Hovold <johan@kernel.org>
|
|
Takashi Iwai |
f6a509 |
Acked-by: Takashi Iwai <tiwai@suse.de>
|
|
Takashi Iwai |
f6a509 |
|
|
Takashi Iwai |
f6a509 |
---
|
|
Takashi Iwai |
f6a509 |
drivers/usb/serial/pl2303.c | 124 +++++++++++++++++++++++++++++-------
|
|
Takashi Iwai |
f6a509 |
drivers/usb/serial/pl2303.h | 6 ++
|
|
Takashi Iwai |
f6a509 |
2 files changed, 107 insertions(+), 23 deletions(-)
|
|
Takashi Iwai |
f6a509 |
|
|
Takashi Iwai |
f6a509 |
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
|
|
Takashi Iwai |
f6a509 |
index 9d27b76c5c6e..aab737e1e7b6 100644
|
|
Takashi Iwai |
f6a509 |
--- a/drivers/usb/serial/pl2303.c
|
|
Takashi Iwai |
f6a509 |
+++ b/drivers/usb/serial/pl2303.c
|
|
Takashi Iwai |
f6a509 |
@@ -47,6 +47,12 @@ static const struct usb_device_id id_table[] = {
|
|
Takashi Iwai |
f6a509 |
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_MOTOROLA) },
|
|
Takashi Iwai |
f6a509 |
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_ZTEK) },
|
|
Takashi Iwai |
f6a509 |
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_TB) },
|
|
Takashi Iwai |
f6a509 |
+ { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_GC) },
|
|
Takashi Iwai |
f6a509 |
+ { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_GB) },
|
|
Takashi Iwai |
f6a509 |
+ { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_GT) },
|
|
Takashi Iwai |
f6a509 |
+ { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_GL) },
|
|
Takashi Iwai |
f6a509 |
+ { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_GE) },
|
|
Takashi Iwai |
f6a509 |
+ { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_GS) },
|
|
Takashi Iwai |
f6a509 |
{ USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) },
|
|
Takashi Iwai |
f6a509 |
{ USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) },
|
|
Takashi Iwai |
f6a509 |
{ USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID),
|
|
Takashi Iwai |
f6a509 |
@@ -130,9 +136,11 @@ MODULE_DEVICE_TABLE(usb, id_table);
|
|
Takashi Iwai |
f6a509 |
|
|
Takashi Iwai |
f6a509 |
#define VENDOR_WRITE_REQUEST_TYPE 0x40
|
|
Takashi Iwai |
f6a509 |
#define VENDOR_WRITE_REQUEST 0x01
|
|
Takashi Iwai |
f6a509 |
+#define VENDOR_WRITE_NREQUEST 0x80
|
|
Takashi Iwai |
f6a509 |
|
|
Takashi Iwai |
f6a509 |
#define VENDOR_READ_REQUEST_TYPE 0xc0
|
|
Takashi Iwai |
f6a509 |
#define VENDOR_READ_REQUEST 0x01
|
|
Takashi Iwai |
f6a509 |
+#define VENDOR_READ_NREQUEST 0x81
|
|
Takashi Iwai |
f6a509 |
|
|
Takashi Iwai |
f6a509 |
#define UART_STATE_INDEX 8
|
|
Takashi Iwai |
f6a509 |
#define UART_STATE_MSR_MASK 0x8b
|
|
Takashi Iwai |
f6a509 |
@@ -148,11 +156,24 @@ MODULE_DEVICE_TABLE(usb, id_table);
|
|
Takashi Iwai |
f6a509 |
|
|
Takashi Iwai |
f6a509 |
#define PL2303_FLOWCTRL_MASK 0xf0
|
|
Takashi Iwai |
f6a509 |
|
|
Takashi Iwai |
f6a509 |
+#define PL2303_READ_TYPE_HX_STATUS 0x8080
|
|
Takashi Iwai |
f6a509 |
+
|
|
Takashi Iwai |
f6a509 |
+#define PL2303_HXN_RESET_REG 0x07
|
|
Takashi Iwai |
f6a509 |
+#define PL2303_HXN_RESET_UPSTREAM_PIPE 0x02
|
|
Takashi Iwai |
f6a509 |
+#define PL2303_HXN_RESET_DOWNSTREAM_PIPE 0x01
|
|
Takashi Iwai |
f6a509 |
+
|
|
Takashi Iwai |
f6a509 |
+#define PL2303_HXN_FLOWCTRL_REG 0x0a
|
|
Takashi Iwai |
f6a509 |
+#define PL2303_HXN_FLOWCTRL_MASK 0x1c
|
|
Takashi Iwai |
f6a509 |
+#define PL2303_HXN_FLOWCTRL_NONE 0x1c
|
|
Takashi Iwai |
f6a509 |
+#define PL2303_HXN_FLOWCTRL_RTS_CTS 0x18
|
|
Takashi Iwai |
f6a509 |
+#define PL2303_HXN_FLOWCTRL_XON_XOFF 0x0c
|
|
Takashi Iwai |
f6a509 |
+
|
|
Takashi Iwai |
f6a509 |
static void pl2303_set_break(struct usb_serial_port *port, bool enable);
|
|
Takashi Iwai |
f6a509 |
|
|
Takashi Iwai |
f6a509 |
enum pl2303_type {
|
|
Takashi Iwai |
f6a509 |
TYPE_01, /* Type 0 and 1 (difference unknown) */
|
|
Takashi Iwai |
f6a509 |
TYPE_HX, /* HX version of the pl2303 chip */
|
|
Takashi Iwai |
f6a509 |
+ TYPE_HXN, /* HXN version of the pl2303 chip */
|
|
Takashi Iwai |
f6a509 |
TYPE_COUNT
|
|
Takashi Iwai |
f6a509 |
};
|
|
Takashi Iwai |
f6a509 |
|
|
Takashi Iwai |
f6a509 |
@@ -184,16 +205,26 @@ static const struct pl2303_type_data pl2303_type_data[TYPE_COUNT] = {
|
|
Takashi Iwai |
f6a509 |
[TYPE_HX] = {
|
|
Takashi Iwai |
f6a509 |
.max_baud_rate = 12000000,
|
|
Takashi Iwai |
f6a509 |
},
|
|
Takashi Iwai |
f6a509 |
+ [TYPE_HXN] = {
|
|
Takashi Iwai |
f6a509 |
+ .max_baud_rate = 12000000,
|
|
Takashi Iwai |
f6a509 |
+ },
|
|
Takashi Iwai |
f6a509 |
};
|
|
Takashi Iwai |
f6a509 |
|
|
Takashi Iwai |
f6a509 |
static int pl2303_vendor_read(struct usb_serial *serial, u16 value,
|
|
Takashi Iwai |
f6a509 |
unsigned char buf[1])
|
|
Takashi Iwai |
f6a509 |
{
|
|
Takashi Iwai |
f6a509 |
+ struct pl2303_serial_private *spriv = usb_get_serial_data(serial);
|
|
Takashi Iwai |
f6a509 |
struct device *dev = &serial->interface->dev;
|
|
Takashi Iwai |
f6a509 |
+ u8 request;
|
|
Takashi Iwai |
f6a509 |
int res;
|
|
Takashi Iwai |
f6a509 |
|
|
Takashi Iwai |
f6a509 |
+ if (spriv->type == &pl2303_type_data[TYPE_HXN])
|
|
Takashi Iwai |
f6a509 |
+ request = VENDOR_READ_NREQUEST;
|
|
Takashi Iwai |
f6a509 |
+ else
|
|
Takashi Iwai |
f6a509 |
+ request = VENDOR_READ_REQUEST;
|
|
Takashi Iwai |
f6a509 |
+
|
|
Takashi Iwai |
f6a509 |
res = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
|
|
Takashi Iwai |
f6a509 |
- VENDOR_READ_REQUEST, VENDOR_READ_REQUEST_TYPE,
|
|
Takashi Iwai |
f6a509 |
+ request, VENDOR_READ_REQUEST_TYPE,
|
|
Takashi Iwai |
f6a509 |
value, 0, buf, 1, 100);
|
|
Takashi Iwai |
f6a509 |
if (res != 1) {
|
|
Takashi Iwai |
f6a509 |
dev_err(dev, "%s - failed to read [%04x]: %d\n", __func__,
|
|
Takashi Iwai |
f6a509 |
@@ -211,13 +242,20 @@ static int pl2303_vendor_read(struct usb_serial *serial, u16 value,
|
|
Takashi Iwai |
f6a509 |
|
|
Takashi Iwai |
f6a509 |
static int pl2303_vendor_write(struct usb_serial *serial, u16 value, u16 index)
|
|
Takashi Iwai |
f6a509 |
{
|
|
Takashi Iwai |
f6a509 |
+ struct pl2303_serial_private *spriv = usb_get_serial_data(serial);
|
|
Takashi Iwai |
f6a509 |
struct device *dev = &serial->interface->dev;
|
|
Takashi Iwai |
f6a509 |
+ u8 request;
|
|
Takashi Iwai |
f6a509 |
int res;
|
|
Takashi Iwai |
f6a509 |
|
|
Takashi Iwai |
f6a509 |
dev_dbg(dev, "%s - [%04x] = %02x\n", __func__, value, index);
|
|
Takashi Iwai |
f6a509 |
|
|
Takashi Iwai |
f6a509 |
+ if (spriv->type == &pl2303_type_data[TYPE_HXN])
|
|
Takashi Iwai |
f6a509 |
+ request = VENDOR_WRITE_NREQUEST;
|
|
Takashi Iwai |
f6a509 |
+ else
|
|
Takashi Iwai |
f6a509 |
+ request = VENDOR_WRITE_REQUEST;
|
|
Takashi Iwai |
f6a509 |
+
|
|
Takashi Iwai |
f6a509 |
res = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
|
|
Takashi Iwai |
f6a509 |
- VENDOR_WRITE_REQUEST, VENDOR_WRITE_REQUEST_TYPE,
|
|
Takashi Iwai |
f6a509 |
+ request, VENDOR_WRITE_REQUEST_TYPE,
|
|
Takashi Iwai |
f6a509 |
value, index, NULL, 0, 100);
|
|
Takashi Iwai |
f6a509 |
if (res) {
|
|
Takashi Iwai |
f6a509 |
dev_err(dev, "%s - failed to write [%04x]: %d\n", __func__,
|
|
Takashi Iwai |
f6a509 |
@@ -230,6 +268,7 @@ static int pl2303_vendor_write(struct usb_serial *serial, u16 value, u16 index)
|
|
Takashi Iwai |
f6a509 |
|
|
Takashi Iwai |
f6a509 |
static int pl2303_update_reg(struct usb_serial *serial, u8 reg, u8 mask, u8 val)
|
|
Takashi Iwai |
f6a509 |
{
|
|
Takashi Iwai |
f6a509 |
+ struct pl2303_serial_private *spriv = usb_get_serial_data(serial);
|
|
Takashi Iwai |
f6a509 |
int ret = 0;
|
|
Takashi Iwai |
f6a509 |
u8 *buf;
|
|
Takashi Iwai |
f6a509 |
|
|
Takashi Iwai |
f6a509 |
@@ -237,7 +276,11 @@ static int pl2303_update_reg(struct usb_serial *serial, u8 reg, u8 mask, u8 val)
|
|
Takashi Iwai |
f6a509 |
if (!buf)
|
|
Takashi Iwai |
f6a509 |
return -ENOMEM;
|
|
Takashi Iwai |
f6a509 |
|
|
Takashi Iwai |
f6a509 |
- ret = pl2303_vendor_read(serial, reg | 0x80, buf);
|
|
Takashi Iwai |
f6a509 |
+ if (spriv->type == &pl2303_type_data[TYPE_HXN])
|
|
Takashi Iwai |
f6a509 |
+ ret = pl2303_vendor_read(serial, reg, buf);
|
|
Takashi Iwai |
f6a509 |
+ else
|
|
Takashi Iwai |
f6a509 |
+ ret = pl2303_vendor_read(serial, reg | 0x80, buf);
|
|
Takashi Iwai |
f6a509 |
+
|
|
Takashi Iwai |
f6a509 |
if (ret)
|
|
Takashi Iwai |
f6a509 |
goto out_free;
|
|
Takashi Iwai |
f6a509 |
|
|
Takashi Iwai |
f6a509 |
@@ -320,6 +363,7 @@ static int pl2303_startup(struct usb_serial *serial)
|
|
Takashi Iwai |
f6a509 |
struct pl2303_serial_private *spriv;
|
|
Takashi Iwai |
f6a509 |
enum pl2303_type type = TYPE_01;
|
|
Takashi Iwai |
f6a509 |
unsigned char *buf;
|
|
Takashi Iwai |
f6a509 |
+ int res;
|
|
Takashi Iwai |
f6a509 |
|
|
Takashi Iwai |
f6a509 |
spriv = kzalloc(sizeof(*spriv), GFP_KERNEL);
|
|
Takashi Iwai |
f6a509 |
if (!spriv)
|
|
Takashi Iwai |
f6a509 |
@@ -341,26 +385,37 @@ static int pl2303_startup(struct usb_serial *serial)
|
|
Takashi Iwai |
f6a509 |
type = TYPE_01; /* type 1 */
|
|
Takashi Iwai |
f6a509 |
dev_dbg(&serial->interface->dev, "device type: %d\n", type);
|
|
Takashi Iwai |
f6a509 |
|
|
Takashi Iwai |
f6a509 |
+ if (type == TYPE_HX) {
|
|
Takashi Iwai |
f6a509 |
+ res = usb_control_msg(serial->dev,
|
|
Takashi Iwai |
f6a509 |
+ usb_rcvctrlpipe(serial->dev, 0),
|
|
Takashi Iwai |
f6a509 |
+ VENDOR_READ_REQUEST, VENDOR_READ_REQUEST_TYPE,
|
|
Takashi Iwai |
f6a509 |
+ PL2303_READ_TYPE_HX_STATUS, 0, buf, 1, 100);
|
|
Takashi Iwai |
f6a509 |
+ if (res != 1)
|
|
Takashi Iwai |
f6a509 |
+ type = TYPE_HXN;
|
|
Takashi Iwai |
f6a509 |
+ }
|
|
Takashi Iwai |
f6a509 |
+
|
|
Takashi Iwai |
f6a509 |
spriv->type = &pl2303_type_data[type];
|
|
Takashi Iwai |
f6a509 |
spriv->quirks = (unsigned long)usb_get_serial_data(serial);
|
|
Takashi Iwai |
f6a509 |
spriv->quirks |= spriv->type->quirks;
|
|
Takashi Iwai |
f6a509 |
|
|
Takashi Iwai |
f6a509 |
usb_set_serial_data(serial, spriv);
|
|
Takashi Iwai |
f6a509 |
|
|
Takashi Iwai |
f6a509 |
- pl2303_vendor_read(serial, 0x8484, buf);
|
|
Takashi Iwai |
f6a509 |
- pl2303_vendor_write(serial, 0x0404, 0);
|
|
Takashi Iwai |
f6a509 |
- pl2303_vendor_read(serial, 0x8484, buf);
|
|
Takashi Iwai |
f6a509 |
- pl2303_vendor_read(serial, 0x8383, buf);
|
|
Takashi Iwai |
f6a509 |
- pl2303_vendor_read(serial, 0x8484, buf);
|
|
Takashi Iwai |
f6a509 |
- pl2303_vendor_write(serial, 0x0404, 1);
|
|
Takashi Iwai |
f6a509 |
- pl2303_vendor_read(serial, 0x8484, buf);
|
|
Takashi Iwai |
f6a509 |
- pl2303_vendor_read(serial, 0x8383, buf);
|
|
Takashi Iwai |
f6a509 |
- pl2303_vendor_write(serial, 0, 1);
|
|
Takashi Iwai |
f6a509 |
- pl2303_vendor_write(serial, 1, 0);
|
|
Takashi Iwai |
f6a509 |
- if (spriv->quirks & PL2303_QUIRK_LEGACY)
|
|
Takashi Iwai |
f6a509 |
- pl2303_vendor_write(serial, 2, 0x24);
|
|
Takashi Iwai |
f6a509 |
- else
|
|
Takashi Iwai |
f6a509 |
- pl2303_vendor_write(serial, 2, 0x44);
|
|
Takashi Iwai |
f6a509 |
+ if (type != TYPE_HXN) {
|
|
Takashi Iwai |
f6a509 |
+ pl2303_vendor_read(serial, 0x8484, buf);
|
|
Takashi Iwai |
f6a509 |
+ pl2303_vendor_write(serial, 0x0404, 0);
|
|
Takashi Iwai |
f6a509 |
+ pl2303_vendor_read(serial, 0x8484, buf);
|
|
Takashi Iwai |
f6a509 |
+ pl2303_vendor_read(serial, 0x8383, buf);
|
|
Takashi Iwai |
f6a509 |
+ pl2303_vendor_read(serial, 0x8484, buf);
|
|
Takashi Iwai |
f6a509 |
+ pl2303_vendor_write(serial, 0x0404, 1);
|
|
Takashi Iwai |
f6a509 |
+ pl2303_vendor_read(serial, 0x8484, buf);
|
|
Takashi Iwai |
f6a509 |
+ pl2303_vendor_read(serial, 0x8383, buf);
|
|
Takashi Iwai |
f6a509 |
+ pl2303_vendor_write(serial, 0, 1);
|
|
Takashi Iwai |
f6a509 |
+ pl2303_vendor_write(serial, 1, 0);
|
|
Takashi Iwai |
f6a509 |
+ if (spriv->quirks & PL2303_QUIRK_LEGACY)
|
|
Takashi Iwai |
f6a509 |
+ pl2303_vendor_write(serial, 2, 0x24);
|
|
Takashi Iwai |
f6a509 |
+ else
|
|
Takashi Iwai |
f6a509 |
+ pl2303_vendor_write(serial, 2, 0x44);
|
|
Takashi Iwai |
f6a509 |
+ }
|
|
Takashi Iwai |
f6a509 |
|
|
Takashi Iwai |
f6a509 |
kfree(buf);
|
|
Takashi Iwai |
f6a509 |
|
|
Takashi Iwai |
f6a509 |
@@ -719,14 +774,31 @@ static void pl2303_set_termios(struct tty_struct *tty,
|
|
Takashi Iwai |
f6a509 |
}
|
|
Takashi Iwai |
f6a509 |
|
|
Takashi Iwai |
f6a509 |
if (C_CRTSCTS(tty)) {
|
|
Takashi Iwai |
f6a509 |
- if (spriv->quirks & PL2303_QUIRK_LEGACY)
|
|
Takashi Iwai |
f6a509 |
+ if (spriv->quirks & PL2303_QUIRK_LEGACY) {
|
|
Takashi Iwai |
f6a509 |
pl2303_update_reg(serial, 0, PL2303_FLOWCTRL_MASK, 0x40);
|
|
Takashi Iwai |
f6a509 |
- else
|
|
Takashi Iwai |
f6a509 |
+ } else if (spriv->type == &pl2303_type_data[TYPE_HXN]) {
|
|
Takashi Iwai |
f6a509 |
+ pl2303_update_reg(serial, PL2303_HXN_FLOWCTRL_REG,
|
|
Takashi Iwai |
f6a509 |
+ PL2303_HXN_FLOWCTRL_MASK,
|
|
Takashi Iwai |
f6a509 |
+ PL2303_HXN_FLOWCTRL_RTS_CTS);
|
|
Takashi Iwai |
f6a509 |
+ } else {
|
|
Takashi Iwai |
f6a509 |
pl2303_update_reg(serial, 0, PL2303_FLOWCTRL_MASK, 0x60);
|
|
Takashi Iwai |
f6a509 |
+ }
|
|
Takashi Iwai |
f6a509 |
} else if (pl2303_enable_xonxoff(tty, spriv->type)) {
|
|
Takashi Iwai |
f6a509 |
- pl2303_update_reg(serial, 0, PL2303_FLOWCTRL_MASK, 0xc0);
|
|
Takashi Iwai |
f6a509 |
+ if (spriv->type == &pl2303_type_data[TYPE_HXN]) {
|
|
Takashi Iwai |
f6a509 |
+ pl2303_update_reg(serial, PL2303_HXN_FLOWCTRL_REG,
|
|
Takashi Iwai |
f6a509 |
+ PL2303_HXN_FLOWCTRL_MASK,
|
|
Takashi Iwai |
f6a509 |
+ PL2303_HXN_FLOWCTRL_XON_XOFF);
|
|
Takashi Iwai |
f6a509 |
+ } else {
|
|
Takashi Iwai |
f6a509 |
+ pl2303_update_reg(serial, 0, PL2303_FLOWCTRL_MASK, 0xc0);
|
|
Takashi Iwai |
f6a509 |
+ }
|
|
Takashi Iwai |
f6a509 |
} else {
|
|
Takashi Iwai |
f6a509 |
- pl2303_update_reg(serial, 0, PL2303_FLOWCTRL_MASK, 0);
|
|
Takashi Iwai |
f6a509 |
+ if (spriv->type == &pl2303_type_data[TYPE_HXN]) {
|
|
Takashi Iwai |
f6a509 |
+ pl2303_update_reg(serial, PL2303_HXN_FLOWCTRL_REG,
|
|
Takashi Iwai |
f6a509 |
+ PL2303_HXN_FLOWCTRL_MASK,
|
|
Takashi Iwai |
f6a509 |
+ PL2303_HXN_FLOWCTRL_NONE);
|
|
Takashi Iwai |
f6a509 |
+ } else {
|
|
Takashi Iwai |
f6a509 |
+ pl2303_update_reg(serial, 0, PL2303_FLOWCTRL_MASK, 0);
|
|
Takashi Iwai |
f6a509 |
+ }
|
|
Takashi Iwai |
f6a509 |
}
|
|
Takashi Iwai |
f6a509 |
|
|
Takashi Iwai |
f6a509 |
kfree(buf);
|
|
Takashi Iwai |
f6a509 |
@@ -767,8 +839,14 @@ static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port)
|
|
Takashi Iwai |
f6a509 |
usb_clear_halt(serial->dev, port->read_urb->pipe);
|
|
Takashi Iwai |
f6a509 |
} else {
|
|
Takashi Iwai |
f6a509 |
/* reset upstream data pipes */
|
|
Takashi Iwai |
f6a509 |
- pl2303_vendor_write(serial, 8, 0);
|
|
Takashi Iwai |
f6a509 |
- pl2303_vendor_write(serial, 9, 0);
|
|
Takashi Iwai |
f6a509 |
+ if (spriv->type == &pl2303_type_data[TYPE_HXN]) {
|
|
Takashi Iwai |
f6a509 |
+ pl2303_vendor_write(serial, PL2303_HXN_RESET_REG,
|
|
Takashi Iwai |
f6a509 |
+ PL2303_HXN_RESET_UPSTREAM_PIPE |
|
|
Takashi Iwai |
f6a509 |
+ PL2303_HXN_RESET_DOWNSTREAM_PIPE);
|
|
Takashi Iwai |
f6a509 |
+ } else {
|
|
Takashi Iwai |
f6a509 |
+ pl2303_vendor_write(serial, 8, 0);
|
|
Takashi Iwai |
f6a509 |
+ pl2303_vendor_write(serial, 9, 0);
|
|
Takashi Iwai |
f6a509 |
+ }
|
|
Takashi Iwai |
f6a509 |
}
|
|
Takashi Iwai |
f6a509 |
|
|
Takashi Iwai |
f6a509 |
/* Setup termios */
|
|
Takashi Iwai |
f6a509 |
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h
|
|
Takashi Iwai |
f6a509 |
index b0175f17d1a2..a019ea7e6e0e 100644
|
|
Takashi Iwai |
f6a509 |
--- a/drivers/usb/serial/pl2303.h
|
|
Takashi Iwai |
f6a509 |
+++ b/drivers/usb/serial/pl2303.h
|
|
Takashi Iwai |
f6a509 |
@@ -9,6 +9,12 @@
|
|
Takashi Iwai |
f6a509 |
#define PL2303_VENDOR_ID 0x067b
|
|
Takashi Iwai |
f6a509 |
#define PL2303_PRODUCT_ID 0x2303
|
|
Takashi Iwai |
f6a509 |
#define PL2303_PRODUCT_ID_TB 0x2304
|
|
Takashi Iwai |
f6a509 |
+#define PL2303_PRODUCT_ID_GC 0x23a3
|
|
Takashi Iwai |
f6a509 |
+#define PL2303_PRODUCT_ID_GB 0x23b3
|
|
Takashi Iwai |
f6a509 |
+#define PL2303_PRODUCT_ID_GT 0x23c3
|
|
Takashi Iwai |
f6a509 |
+#define PL2303_PRODUCT_ID_GL 0x23d3
|
|
Takashi Iwai |
f6a509 |
+#define PL2303_PRODUCT_ID_GE 0x23e3
|
|
Takashi Iwai |
f6a509 |
+#define PL2303_PRODUCT_ID_GS 0x23f3
|
|
Takashi Iwai |
f6a509 |
#define PL2303_PRODUCT_ID_RSAQ2 0x04bb
|
|
Takashi Iwai |
f6a509 |
#define PL2303_PRODUCT_ID_DCU11 0x1234
|
|
Takashi Iwai |
f6a509 |
#define PL2303_PRODUCT_ID_PHAROS 0xaaa0
|
|
Takashi Iwai |
f6a509 |
--
|
|
Takashi Iwai |
f6a509 |
2.26.2
|
|
Takashi Iwai |
f6a509 |
|