qmi_wwan: Add support for Quectel EG12/EM12
authorKristian Evensen <kristian.evensen@gmail.com>
Sat, 2 Mar 2019 12:32:26 +0000 (13:32 +0100)
committerDavid S. Miller <davem@davemloft.net>
Mon, 4 Mar 2019 05:39:50 +0000 (21:39 -0800)
Quectel EG12 (module)/EM12 (M.2 card) is a Cat. 12 LTE modem. The modem
behaves in the same way as the EP06, so the "set DTR"-quirk must be
applied and the diagnostic-interface check performed. Since the
diagnostic-check now applies to more modems, I have renamed the function
from quectel_ep06_diag_detected() to quectel_diag_detected().

Signed-off-by: Kristian Evensen <kristian.evensen@gmail.com>
Acked-by: Bjørn Mork <bjorn@mork.no>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/usb/qmi_wwan.c

index 18af2f8eee96a87418dd93005600e661a93a818a..74bebbdb4b158791135410d00591e84eb9da7073 100644 (file)
@@ -976,6 +976,13 @@ static const struct usb_device_id products[] = {
                                              0xff),
                .driver_info        = (unsigned long)&qmi_wwan_info_quirk_dtr,
        },
+       {       /* Quectel EG12/EM12 */
+               USB_DEVICE_AND_INTERFACE_INFO(0x2c7c, 0x0512,
+                                             USB_CLASS_VENDOR_SPEC,
+                                             USB_SUBCLASS_VENDOR_SPEC,
+                                             0xff),
+               .driver_info        = (unsigned long)&qmi_wwan_info_quirk_dtr,
+       },
 
        /* 3. Combined interface devices matching on interface number */
        {QMI_FIXED_INTF(0x0408, 0xea42, 4)},    /* Yota / Megafon M100-1 */
@@ -1343,17 +1350,20 @@ static bool quectel_ec20_detected(struct usb_interface *intf)
        return false;
 }
 
-static bool quectel_ep06_diag_detected(struct usb_interface *intf)
+static bool quectel_diag_detected(struct usb_interface *intf)
 {
        struct usb_device *dev = interface_to_usbdev(intf);
        struct usb_interface_descriptor intf_desc = intf->cur_altsetting->desc;
+       u16 id_vendor = le16_to_cpu(dev->descriptor.idVendor);
+       u16 id_product = le16_to_cpu(dev->descriptor.idProduct);
 
-       if (le16_to_cpu(dev->descriptor.idVendor) == 0x2c7c &&
-           le16_to_cpu(dev->descriptor.idProduct) == 0x0306 &&
-           intf_desc.bNumEndpoints == 2)
-               return true;
+       if (id_vendor != 0x2c7c || intf_desc.bNumEndpoints != 2)
+               return false;
 
-       return false;
+       if (id_product == 0x0306 || id_product == 0x0512)
+               return true;
+       else
+               return false;
 }
 
 static int qmi_wwan_probe(struct usb_interface *intf,
@@ -1390,13 +1400,13 @@ static int qmi_wwan_probe(struct usb_interface *intf,
                return -ENODEV;
        }
 
-       /* Quectel EP06/EM06/EG06 supports dynamic interface configuration, so
+       /* Several Quectel modems supports dynamic interface configuration, so
         * we need to match on class/subclass/protocol. These values are
         * identical for the diagnostic- and QMI-interface, but bNumEndpoints is
         * different. Ignore the current interface if the number of endpoints
         * the number for the diag interface (two).
         */
-       if (quectel_ep06_diag_detected(intf))
+       if (quectel_diag_detected(intf))
                return -ENODEV;
 
        return usbnet_probe(intf, id);