Commit 822e44b4 authored by Kristian Evensen's avatar Kristian Evensen Committed by David S. Miller

qmi_wwan: Add support for Quectel EG12/EM12

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: default avatarKristian Evensen <kristian.evensen@gmail.com>
Acked-by: default avatarBjørn Mork <bjorn@mork.no>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 95150f29
...@@ -976,6 +976,13 @@ static const struct usb_device_id products[] = { ...@@ -976,6 +976,13 @@ static const struct usb_device_id products[] = {
0xff), 0xff),
.driver_info = (unsigned long)&qmi_wwan_info_quirk_dtr, .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 */ /* 3. Combined interface devices matching on interface number */
{QMI_FIXED_INTF(0x0408, 0xea42, 4)}, /* Yota / Megafon M100-1 */ {QMI_FIXED_INTF(0x0408, 0xea42, 4)}, /* Yota / Megafon M100-1 */
...@@ -1343,17 +1350,20 @@ static bool quectel_ec20_detected(struct usb_interface *intf) ...@@ -1343,17 +1350,20 @@ static bool quectel_ec20_detected(struct usb_interface *intf)
return false; 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_device *dev = interface_to_usbdev(intf);
struct usb_interface_descriptor intf_desc = intf->cur_altsetting->desc; 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 && if (id_vendor != 0x2c7c || intf_desc.bNumEndpoints != 2)
le16_to_cpu(dev->descriptor.idProduct) == 0x0306 && return false;
intf_desc.bNumEndpoints == 2)
return true;
return false; if (id_product == 0x0306 || id_product == 0x0512)
return true;
else
return false;
} }
static int qmi_wwan_probe(struct usb_interface *intf, static int qmi_wwan_probe(struct usb_interface *intf,
...@@ -1390,13 +1400,13 @@ static int qmi_wwan_probe(struct usb_interface *intf, ...@@ -1390,13 +1400,13 @@ static int qmi_wwan_probe(struct usb_interface *intf,
return -ENODEV; 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 * we need to match on class/subclass/protocol. These values are
* identical for the diagnostic- and QMI-interface, but bNumEndpoints is * identical for the diagnostic- and QMI-interface, but bNumEndpoints is
* different. Ignore the current interface if the number of endpoints * different. Ignore the current interface if the number of endpoints
* the number for the diag interface (two). * the number for the diag interface (two).
*/ */
if (quectel_ep06_diag_detected(intf)) if (quectel_diag_detected(intf))
return -ENODEV; return -ENODEV;
return usbnet_probe(intf, id); return usbnet_probe(intf, id);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment