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); ...@@ -161,6 +161,7 @@ static void option_instat_callback(struct urb *urb);
#define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0x9001 #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0x9001
#define NOVATELWIRELESS_PRODUCT_E362 0x9010 #define NOVATELWIRELESS_PRODUCT_E362 0x9010
#define NOVATELWIRELESS_PRODUCT_E371 0x9011 #define NOVATELWIRELESS_PRODUCT_E371 0x9011
#define NOVATELWIRELESS_PRODUCT_U620L 0x9022
#define NOVATELWIRELESS_PRODUCT_G2 0xA010 #define NOVATELWIRELESS_PRODUCT_G2 0xA010
#define NOVATELWIRELESS_PRODUCT_MC551 0xB001 #define NOVATELWIRELESS_PRODUCT_MC551 0xB001
...@@ -1052,6 +1053,7 @@ static const struct usb_device_id option_ids[] = { ...@@ -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_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_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_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_H01) },
{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) }, { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) },
......
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
#define DRIVER_AUTHOR "Qualcomm Inc" #define DRIVER_AUTHOR "Qualcomm Inc"
#define DRIVER_DESC "Qualcomm USB Serial driver" #define DRIVER_DESC "Qualcomm USB Serial driver"
#define QUECTEL_EC20_PID 0x9215
/* standard device layouts supported by this driver */ /* standard device layouts supported by this driver */
enum qcserial_layouts { enum qcserial_layouts {
QCSERIAL_G2K = 0, /* Gobi 2000 */ QCSERIAL_G2K = 0, /* Gobi 2000 */
...@@ -171,6 +173,38 @@ static const struct usb_device_id id_table[] = { ...@@ -171,6 +173,38 @@ static const struct usb_device_id id_table[] = {
}; };
MODULE_DEVICE_TABLE(usb, 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) static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
{ {
struct usb_host_interface *intf = serial->interface->cur_altsetting; 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) ...@@ -181,6 +215,10 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
int altsetting = -1; int altsetting = -1;
bool sendsetup = false; 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; nintf = serial->dev->actconfig->desc.bNumInterfaces;
dev_dbg(dev, "Num Interfaces = %d\n", nintf); dev_dbg(dev, "Num Interfaces = %d\n", nintf);
ifnum = intf->desc.bInterfaceNumber; ifnum = intf->desc.bInterfaceNumber;
...@@ -240,6 +278,12 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) ...@@ -240,6 +278,12 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
altsetting = -1; altsetting = -1;
break; break;
case QCSERIAL_G2K: 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: * Gobi 2K+ USB layout:
* 0: QMI/net * 0: QMI/net
...@@ -301,29 +345,39 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) ...@@ -301,29 +345,39 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
break; break;
case QCSERIAL_HWI: case QCSERIAL_HWI:
/* /*
* Huawei layout: * Huawei devices map functions by subclass + protocol
* 0: AT-capable modem port * instead of interface numbers. The protocol identify
* 1: DM/DIAG * a specific function, while the subclass indicate a
* 2: AT-capable modem port * specific firmware source
* 3: CCID-compatible PCSC interface *
* 4: QMI/net * This is a blacklist of functions known to be
* 5: NMEA * non-serial. The rest are assumed to be serial and
* will be handled by this driver
*/ */
switch (ifnum) { switch (intf->desc.bInterfaceProtocol) {
case 0: /* QMI combined (qmi_wwan) */
case 2: case 0x07:
dev_dbg(dev, "Modem port found\n"); case 0x37:
break; case 0x67:
case 1: /* QMI data (qmi_wwan) */
dev_dbg(dev, "DM/DIAG interface found\n"); case 0x08:
break; case 0x38:
case 5: case 0x68:
dev_dbg(dev, "NMEA GPS interface found\n"); /* QMI control (qmi_wwan) */
break; case 0x09:
default: case 0x39:
/* don't claim any unsupported interface */ case 0x69:
/* NCM like (huawei_cdc_ncm) */
case 0x16:
case 0x46:
case 0x76:
altsetting = -1; altsetting = -1;
break; break;
default:
dev_dbg(dev, "Huawei type serial port found (%02x/%02x/%02x)\n",
intf->desc.bInterfaceClass,
intf->desc.bInterfaceSubClass,
intf->desc.bInterfaceProtocol);
} }
break; break;
default: default:
......
...@@ -159,6 +159,7 @@ static const struct usb_device_id ti_id_table_3410[] = { ...@@ -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_STEREO_PLUG_ID) },
{ USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STRIP_PORT_ID) }, { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STRIP_PORT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) }, { USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) },
{ USB_DEVICE(HONEYWELL_VENDOR_ID, HONEYWELL_HGI80_PRODUCT_ID) },
{ } /* terminator */ { } /* terminator */
}; };
...@@ -191,6 +192,7 @@ static const struct usb_device_id ti_id_table_combined[] = { ...@@ -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_PRODUCT_ID) },
{ USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STRIP_PORT_ID) }, { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STRIP_PORT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) }, { USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) },
{ USB_DEVICE(HONEYWELL_VENDOR_ID, HONEYWELL_HGI80_PRODUCT_ID) },
{ } /* terminator */ { } /* terminator */
}; };
......
...@@ -56,6 +56,10 @@ ...@@ -56,6 +56,10 @@
#define ABBOTT_PRODUCT_ID ABBOTT_STEREO_PLUG_ID #define ABBOTT_PRODUCT_ID ABBOTT_STEREO_PLUG_ID
#define ABBOTT_STRIP_PORT_ID 0x3420 #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 */ /* Commands */
#define TI_GET_VERSION 0x01 #define TI_GET_VERSION 0x01
#define TI_GET_PORT_STATUS 0x02 #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