开发平台基本信息
芯片: 高通SDM450 版本: Android 9.0 kernel: msm-4.9
问题描述
原本设备都通过试产,正常出货销售了,后来采购说换了USB-HUB芯片之后,NFC功能就不能用了,查了下,原因是原生的PL2303G驱动太久,需要升级新的驱动才能正常使用。
解决方法
PL2303G驱动修改
PL2303G驱动是厂商提供的,找到对应的kernel版本,替换修改即可;我的是在kernel/msm-4.9目录下。
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index c7ab480..ceee459 100755
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -48,6 +48,12 @@ 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, 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) },
@@ -119,9 +125,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
@@ -140,6 +148,7 @@ static void pl2303_set_break(struct usb_serial_port *port, bool enable);
enum pl2303_type {
TYPE_01,
TYPE_HX,
+ TYPE_HXN,
TYPE_COUNT
};
@@ -169,16 +178,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__,
@@ -197,12 +216,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__,
@@ -227,6 +253,7 @@ static int pl2303_startup(struct usb_serial *serial)
unsigned char num_ports = serial->num_ports;
enum pl2303_type type = TYPE_01;
unsigned char *buf;
+ int res;
if (serial->num_bulk_in < num_ports ||
serial->num_bulk_out < num_ports ||
@@ -255,12 +282,23 @@ static int pl2303_startup(struct usb_serial *serial)
type = TYPE_01;
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,
+ 0x8080, 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);
+ if (type != TYPE_HXN) {
+
pl2303_vendor_read(serial, 0x8484, buf);
pl2303_vendor_write(serial, 0x0404, 0);
pl2303_vendor_read(serial, 0x8484, buf);
@@ -276,6 +314,8 @@ static int pl2303_startup(struct usb_serial *serial)
else
pl2303_vendor_write(serial, 2, 0x44);
+ }
+
kfree(buf);
return 0;
@@ -612,12 +652,17 @@ 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, 0x0A, 0xFA);
else
pl2303_vendor_write(serial, 0x0, 0x61);
} else {
- pl2303_vendor_write(serial, 0x0, 0x0);
+ if (spriv->type == &pl2303_type_data[TYPE_HXN])
+ pl2303_vendor_write(serial, 0x0A, 0xFF);
+ else
+ pl2303_vendor_write(serial, 0x0, 0x0);
}
kfree(buf);
@@ -658,8 +703,12 @@ static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port)
usb_clear_halt(serial->dev, port->read_urb->pipe);
} else {
- pl2303_vendor_write(serial, 8, 0);
- pl2303_vendor_write(serial, 9, 0);
+ if (spriv->type == &pl2303_type_data[TYPE_HXN])
+ pl2303_vendor_write(serial, 7, 0x07);
+ else {
+ pl2303_vendor_write(serial, 8, 0);
+ pl2303_vendor_write(serial, 9, 0);
+ }
}
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h
index ad32dd5..7a43266 100755
--- a/drivers/usb/serial/pl2303.h
+++ b/drivers/usb/serial/pl2303.h
@@ -27,6 +27,14 @@
#define PL2303_PRODUCT_ID_MOTOROLA 0x0307
#define PL2303_PRODUCT_ID_ZTEK 0xe1f1
+
+#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
PL2303G最新驱动下载地址
https://download.csdn.net/download/Hebin320320/85056027
|