EC200&UC200 需要用到2个驱动,这2个驱动都是内核自带的。
需要使能的内核选项如下
USB_SERIAL=y
USB_SERIAL_WWAN=y
USB_SERIAL_OPTION=y
需要使能的内核选项如下
USB_USBNET=y
USB_NET_CDCETHER=y #用ECM 使能此项
USB_NET_RNDIS_HOST=y #用RNDIS 使能此项
内核配置项截图如下
UC200&EC200和其他高通模块,都是用usb-serial-option驱动,但是USB interface的顺序不同. 所以如果客户之前移植过EC20/EC25的代码,会导致UC200&EC200的PPP口识别不到。所以建议客户先还原drivers/usb/serial/option.c的修改,重新按照 EC200_UC200_usb_serial_option.patch移植。这个修改方法同时UC200&EC200和其他高通平台模块。
[17738.104336] usb 1-1.4: new high-speed USB device number 5 using ehci-pci
[17738.215240] usb 1-1.4: New USB device found, idVendor=2c7c, idProduct=6026
[17738.215243] usb 1-1.4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[17738.215246] usb 1-1.4: Product: EC26
[17738.215248] usb 1-1.4: Manufacturer: Quectel
[17738.215250] usb 1-1.4: SerialNumber: 200806006809080000
[17738.217710] rndis_host 1-1.4:1.0 eth0: register 'rndis_host' at usb-0000:00:1a.0-1.4, RNDIS device, ac:af:fc:d4:e0:61
[17738.218236] option 1-1.4:1.2: GSM modem (1-port) converter detected
[17738.218485] usb 1-1.4: GSM modem (1-port) converter now attached to ttyUSB0
[17738.218729] option 1-1.4:1.3: GSM modem (1-port) converter detected
[17738.218843] usb 1-1.4: GSM modem (1-port) converter now attached to ttyUSB1
[17738.219089] option 1-1.4:1.4: GSM modem (1-port) converter detected
[17738.219186] usb 1-1.4: GSM modem (1-port) converter now attached to ttyUSB2
/dev/ttyUSB0 is DM Port
/dev/ttyUSB1 is AT Port
/dev/ttyUSB2 is PPP port
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index b6320e3..8ca8dbe 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -687,6 +687,22 @@ static const struct option_blacklist_info yuga_clm920_nc5_blacklist = {
};
static const struct usb_device_id option_ids[] = {
+#if 1 //Added by Quectel
+ { USB_DEVICE(0x05C6, 0x9090) }, /* Quectel UC15 */
+ { USB_DEVICE(0x05C6, 0x9003) }, /* Quectel UC20 */
+ { USB_DEVICE(0x2C7C, 0x0125) }, /* Quectel EC25 */
+ { USB_DEVICE(0x2C7C, 0x0121) }, /* Quectel EC21 */
+ { USB_DEVICE(0x05C6, 0x9215) }, /* Quectel EC20 */
+ { USB_DEVICE(0x2C7C, 0x0191) }, /* Quectel EG91 */
+ { USB_DEVICE(0x2C7C, 0x0195) }, /* Quectel EG95 */
+ { USB_DEVICE(0x2C7C, 0x0306) }, /* Quectel EG06/EP06/EM06 */
+ { USB_DEVICE(0x2C7C, 0x0296) }, /* Quectel BG96 */
+ { USB_DEVICE(0x2C7C, 0x0435) }, /* Quectel AG35 */
+ { USB_DEVICE(0x2C7C, 0x0512) }, /* Quectel EG12/EG18 */
+ { USB_DEVICE(0x2C7C, 0x6026) }, /* Quectel EC200 */
+ { USB_DEVICE(0x2C7C, 0x6120) }, /* Quectel UC200 */
+ { USB_DEVICE(0x2C7C, 0x6000) }, /* Quectel EC200/UC200 */
+#endif
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_LIGHT) },
@@ -2088,6 +2104,9 @@ static struct usb_serial_driver option_1port_device = {
#ifdef CONFIG_PM
.suspend = usb_wwan_suspend,
.resume = usb_wwan_resume,
+#if 1 //add by Quectel
+ .reset_resume = usb_wwan_resume,
+#endif
#endif
};
@@ -2105,6 +2124,31 @@ static int option_probe(struct usb_serial *serial,
struct usb_device_descriptor *dev_desc = &serial->dev->descriptor;
const struct option_blacklist_info *blacklist;
+#if 1 //Added by Quectel
+ //Quectel UC20's interface 4 can be used as USB Network device
+ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) && serial->dev->descriptor.idProduct == cpu_to_le16(0x9003)
+ && serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4)
+ return -ENODEV;
+
+ //Quectel EC20's interface 4 can be used as USB Network device
+ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) && serial->dev->descriptor.idProduct == cpu_to_le16(0x9215)
+ && serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4)
+ return -ENODEV;
+
+ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C)) {
+ __u16 idProduct = le16_to_cpu(serial->dev->descriptor.idProduct);
+
+ //Quectel EC200&UC200's interface 0 can be used as USB Network device (ecm, rndis)
+ if (serial->interface->cur_altsetting->desc.bInterfaceClass != 0xFF)
+ return -ENODEV;
+
+ //Quectel EC25&EC21&EG91&EG95&EG06&EP06&EM06&BG96&AG35&EG12&EG18's interface 4 can be used as USB network device (qmi,ecm,mbim)
+ if ((idProduct != 0x6026 && idProduct != 0x6126)
+ && serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4)
+ return -ENODEV;
+ }
+#endif
+
/* Never bind to the CD-Rom emulation interface */
if (iface_desc->bInterfaceClass == 0x08)
return -ENODEV;
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
index 613f91a..4a06a2a 100644
--- a/drivers/usb/serial/qcserial.c
+++ b/drivers/usb/serial/qcserial.c
@@ -63,7 +63,7 @@ static const struct usb_device_id id_table[] = {
{DEVICE_G1K(0x05c6, 0x9202)}, /* Generic Gobi Modem device */
{DEVICE_G1K(0x05c6, 0x9203)}, /* Generic Gobi Modem device */
{DEVICE_G1K(0x05c6, 0x9222)}, /* Generic Gobi Modem device */
- {DEVICE_G1K(0x05c6, 0x9008)}, /* Generic Gobi QDL device */
+ //{DEVICE_G1K(0x05c6, 0x9008)}, /* Generic Gobi QDL device */
{DEVICE_G1K(0x05c6, 0x9009)}, /* Generic Gobi Modem device */
{DEVICE_G1K(0x05c6, 0x9201)}, /* Generic Gobi QDL device */
{DEVICE_G1K(0x05c6, 0x9221)}, /* Generic Gobi QDL device */
@@ -88,7 +88,7 @@ static const struct usb_device_id id_table[] = {
{USB_DEVICE(0x03f0, 0x241d)}, /* HP Gobi 2000 QDL device (VP412) */
{USB_DEVICE(0x03f0, 0x251d)}, /* HP Gobi 2000 Modem device (VP412) */
{USB_DEVICE(0x05c6, 0x9214)}, /* Acer Gobi 2000 QDL device (VP413) */
- {USB_DEVICE(0x05c6, 0x9215)}, /* Acer Gobi 2000 Modem device (VP413) */
+ //{USB_DEVICE(0x05c6, 0x9215)}, /* Acer Gobi 2000 Modem device (VP413) */
{USB_DEVICE(0x05c6, 0x9264)}, /* Asus Gobi 2000 QDL device (VR305) */
{USB_DEVICE(0x05c6, 0x9265)}, /* Asus Gobi 2000 Modem device (VR305) */
{USB_DEVICE(0x05c6, 0x9234)}, /* Top Global Gobi 2000 QDL device (VR306) */
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c
index 107e64c..ee0190c 100644
--- a/drivers/usb/serial/usb_wwan.c
+++ b/drivers/usb/serial/usb_wwan.c
@@ -499,6 +499,20 @@ static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port,
usb_sndbulkpipe(serial->dev, endpoint) | dir,
buf, len, callback, ctx);
+#if 1 //Added by Quectel for Zero Packet
+ if (dir == USB_DIR_OUT) {
+ struct usb_device_descriptor *desc = &serial->dev->descriptor;
+ if (desc->idVendor == cpu_to_le16(0x05C6) && desc->idProduct == cpu_to_le16(0x9090))
+ urb->transfer_flags |= URB_ZERO_PACKET;
+ if (desc->idVendor == cpu_to_le16(0x05C6) && desc->idProduct == cpu_to_le16(0x9003))
+ urb->transfer_flags |= URB_ZERO_PACKET;
+ if (desc->idVendor == cpu_to_le16(0x05C6) && desc->idProduct == cpu_to_le16(0x9215))
+ urb->transfer_flags |= URB_ZERO_PACKET;
+ if (desc->idVendor == cpu_to_le16(0x2C7C))
+ urb->transfer_flags |= URB_ZERO_PACKET;
+ }
+#endif
+
return urb;
}