Commit 0a72f2ad authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'usb-serial-4.4-rc2' of...

Merge tag 'usb-serial-4.4-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial into usb-linus

Johan writes:

USB-serial fixes for v4.4-rc2

Here are some new device ids, support for an odd qcserial Gobi interface
layout and a fix for the qcserial Huawei interface layout.
Signed-off-by: default avatarJohan Hovold <johan@kernel.org>
parents dad67d5f 59536da3
......@@ -161,6 +161,7 @@ static void option_instat_callback(struct urb *urb);
#define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0x9001
#define NOVATELWIRELESS_PRODUCT_E362 0x9010
#define NOVATELWIRELESS_PRODUCT_E371 0x9011
#define NOVATELWIRELESS_PRODUCT_U620L 0x9022
#define NOVATELWIRELESS_PRODUCT_G2 0xA010
#define NOVATELWIRELESS_PRODUCT_MC551 0xB001
......@@ -1052,6 +1053,7 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC551, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E362, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E371, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U620L, 0xff, 0x00, 0x00) },
{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) },
{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) },
......
......@@ -22,6 +22,8 @@
#define DRIVER_AUTHOR "Qualcomm Inc"
#define DRIVER_DESC "Qualcomm USB Serial driver"
#define QUECTEL_EC20_PID 0x9215
/* standard device layouts supported by this driver */
enum qcserial_layouts {
QCSERIAL_G2K = 0, /* Gobi 2000 */
......@@ -171,6 +173,38 @@ static const struct usb_device_id id_table[] = {
};
MODULE_DEVICE_TABLE(usb, id_table);
static int handle_quectel_ec20(struct device *dev, int ifnum)
{
int altsetting = 0;
/*
* Quectel EC20 Mini PCIe LTE module layout:
* 0: DM/DIAG (use libqcdm from ModemManager for communication)
* 1: NMEA
* 2: AT-capable modem port
* 3: Modem interface
* 4: NDIS
*/
switch (ifnum) {
case 0:
dev_dbg(dev, "Quectel EC20 DM/DIAG interface found\n");
break;
case 1:
dev_dbg(dev, "Quectel EC20 NMEA GPS interface found\n");
break;
case 2:
case 3:
dev_dbg(dev, "Quectel EC20 Modem port found\n");
break;
case 4:
/* Don't claim the QMI/net interface */
altsetting = -1;
break;
}
return altsetting;
}
static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
{
struct usb_host_interface *intf = serial->interface->cur_altsetting;
......@@ -181,6 +215,10 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
int altsetting = -1;
bool sendsetup = false;
/* we only support vendor specific functions */
if (intf->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
goto done;
nintf = serial->dev->actconfig->desc.bNumInterfaces;
dev_dbg(dev, "Num Interfaces = %d\n", nintf);
ifnum = intf->desc.bInterfaceNumber;
......@@ -240,6 +278,12 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
altsetting = -1;
break;
case QCSERIAL_G2K:
/* handle non-standard layouts */
if (nintf == 5 && id->idProduct == QUECTEL_EC20_PID) {
altsetting = handle_quectel_ec20(dev, ifnum);
goto done;
}
/*
* Gobi 2K+ USB layout:
* 0: QMI/net
......@@ -301,29 +345,39 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
break;
case QCSERIAL_HWI:
/*
* Huawei layout:
* 0: AT-capable modem port
* 1: DM/DIAG
* 2: AT-capable modem port
* 3: CCID-compatible PCSC interface
* 4: QMI/net
* 5: NMEA
* Huawei devices map functions by subclass + protocol
* instead of interface numbers. The protocol identify
* a specific function, while the subclass indicate a
* specific firmware source
*
* This is a blacklist of functions known to be
* non-serial. The rest are assumed to be serial and
* will be handled by this driver
*/
switch (ifnum) {
case 0:
case 2:
dev_dbg(dev, "Modem port found\n");
break;
case 1:
dev_dbg(dev, "DM/DIAG interface found\n");
break;
case 5:
dev_dbg(dev, "NMEA GPS interface found\n");
break;
default:
/* don't claim any unsupported interface */
switch (intf->desc.bInterfaceProtocol) {
/* QMI combined (qmi_wwan) */
case 0x07:
case 0x37:
case 0x67:
/* QMI data (qmi_wwan) */
case 0x08:
case 0x38:
case 0x68:
/* QMI control (qmi_wwan) */
case 0x09:
case 0x39:
case 0x69:
/* NCM like (huawei_cdc_ncm) */
case 0x16:
case 0x46:
case 0x76:
altsetting = -1;
break;
default:
dev_dbg(dev, "Huawei type serial port found (%02x/%02x/%02x)\n",
intf->desc.bInterfaceClass,
intf->desc.bInterfaceSubClass,
intf->desc.bInterfaceProtocol);
}
break;
default:
......
......@@ -159,6 +159,7 @@ static const struct usb_device_id ti_id_table_3410[] = {
{ USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STEREO_PLUG_ID) },
{ USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STRIP_PORT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) },
{ USB_DEVICE(HONEYWELL_VENDOR_ID, HONEYWELL_HGI80_PRODUCT_ID) },
{ } /* terminator */
};
......@@ -191,6 +192,7 @@ static const struct usb_device_id ti_id_table_combined[] = {
{ USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_PRODUCT_ID) },
{ USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STRIP_PORT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) },
{ USB_DEVICE(HONEYWELL_VENDOR_ID, HONEYWELL_HGI80_PRODUCT_ID) },
{ } /* terminator */
};
......
......@@ -56,6 +56,10 @@
#define ABBOTT_PRODUCT_ID ABBOTT_STEREO_PLUG_ID
#define ABBOTT_STRIP_PORT_ID 0x3420
/* Honeywell vendor and product IDs */
#define HONEYWELL_VENDOR_ID 0x10ac
#define HONEYWELL_HGI80_PRODUCT_ID 0x0102 /* Honeywell HGI80 */
/* Commands */
#define TI_GET_VERSION 0x01
#define TI_GET_PORT_STATUS 0x02
......
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