aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-11-19 17:08:37 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-11-19 17:08:37 -0500
commit0a72f2ad84cc9dde5e4c7ab905a2f89593ddc0b6 (patch)
tree36838e38f3ae12403ab6dd24571e3308a64ed63e
parentdad67d5f3d0efe01d38c6cebcb6698280e51927b (diff)
parent59536da34513c594af2a6fd35ba65ea45b6960a1 (diff)
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: Johan Hovold <johan@kernel.org>
-rw-r--r--drivers/usb/serial/option.c2
-rw-r--r--drivers/usb/serial/qcserial.c94
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.c2
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.h4
4 files changed, 82 insertions, 20 deletions
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 685fef71d3d1..2ab2a33e00c4 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -161,6 +161,7 @@ static void option_instat_callback(struct urb *urb);
161#define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0x9001 161#define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0x9001
162#define NOVATELWIRELESS_PRODUCT_E362 0x9010 162#define NOVATELWIRELESS_PRODUCT_E362 0x9010
163#define NOVATELWIRELESS_PRODUCT_E371 0x9011 163#define NOVATELWIRELESS_PRODUCT_E371 0x9011
164#define NOVATELWIRELESS_PRODUCT_U620L 0x9022
164#define NOVATELWIRELESS_PRODUCT_G2 0xA010 165#define NOVATELWIRELESS_PRODUCT_G2 0xA010
165#define NOVATELWIRELESS_PRODUCT_MC551 0xB001 166#define NOVATELWIRELESS_PRODUCT_MC551 0xB001
166 167
@@ -1052,6 +1053,7 @@ static const struct usb_device_id option_ids[] = {
1052 { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC551, 0xff, 0xff, 0xff) }, 1053 { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC551, 0xff, 0xff, 0xff) },
1053 { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E362, 0xff, 0xff, 0xff) }, 1054 { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E362, 0xff, 0xff, 0xff) },
1054 { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E371, 0xff, 0xff, 0xff) }, 1055 { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E371, 0xff, 0xff, 0xff) },
1056 { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U620L, 0xff, 0x00, 0x00) },
1055 1057
1056 { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) }, 1058 { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) },
1057 { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) }, 1059 { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) },
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
index 5022fcfa0260..9919d2a9faf2 100644
--- a/drivers/usb/serial/qcserial.c
+++ b/drivers/usb/serial/qcserial.c
@@ -22,6 +22,8 @@
22#define DRIVER_AUTHOR "Qualcomm Inc" 22#define DRIVER_AUTHOR "Qualcomm Inc"
23#define DRIVER_DESC "Qualcomm USB Serial driver" 23#define DRIVER_DESC "Qualcomm USB Serial driver"
24 24
25#define QUECTEL_EC20_PID 0x9215
26
25/* standard device layouts supported by this driver */ 27/* standard device layouts supported by this driver */
26enum qcserial_layouts { 28enum qcserial_layouts {
27 QCSERIAL_G2K = 0, /* Gobi 2000 */ 29 QCSERIAL_G2K = 0, /* Gobi 2000 */
@@ -171,6 +173,38 @@ static const struct usb_device_id id_table[] = {
171}; 173};
172MODULE_DEVICE_TABLE(usb, id_table); 174MODULE_DEVICE_TABLE(usb, id_table);
173 175
176static int handle_quectel_ec20(struct device *dev, int ifnum)
177{
178 int altsetting = 0;
179
180 /*
181 * Quectel EC20 Mini PCIe LTE module layout:
182 * 0: DM/DIAG (use libqcdm from ModemManager for communication)
183 * 1: NMEA
184 * 2: AT-capable modem port
185 * 3: Modem interface
186 * 4: NDIS
187 */
188 switch (ifnum) {
189 case 0:
190 dev_dbg(dev, "Quectel EC20 DM/DIAG interface found\n");
191 break;
192 case 1:
193 dev_dbg(dev, "Quectel EC20 NMEA GPS interface found\n");
194 break;
195 case 2:
196 case 3:
197 dev_dbg(dev, "Quectel EC20 Modem port found\n");
198 break;
199 case 4:
200 /* Don't claim the QMI/net interface */
201 altsetting = -1;
202 break;
203 }
204
205 return altsetting;
206}
207
174static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) 208static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
175{ 209{
176 struct usb_host_interface *intf = serial->interface->cur_altsetting; 210 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 int altsetting = -1; 215 int altsetting = -1;
182 bool sendsetup = false; 216 bool sendsetup = false;
183 217
218 /* we only support vendor specific functions */
219 if (intf->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
220 goto done;
221
184 nintf = serial->dev->actconfig->desc.bNumInterfaces; 222 nintf = serial->dev->actconfig->desc.bNumInterfaces;
185 dev_dbg(dev, "Num Interfaces = %d\n", nintf); 223 dev_dbg(dev, "Num Interfaces = %d\n", nintf);
186 ifnum = intf->desc.bInterfaceNumber; 224 ifnum = intf->desc.bInterfaceNumber;
@@ -240,6 +278,12 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
240 altsetting = -1; 278 altsetting = -1;
241 break; 279 break;
242 case QCSERIAL_G2K: 280 case QCSERIAL_G2K:
281 /* handle non-standard layouts */
282 if (nintf == 5 && id->idProduct == QUECTEL_EC20_PID) {
283 altsetting = handle_quectel_ec20(dev, ifnum);
284 goto done;
285 }
286
243 /* 287 /*
244 * Gobi 2K+ USB layout: 288 * Gobi 2K+ USB layout:
245 * 0: QMI/net 289 * 0: QMI/net
@@ -301,29 +345,39 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
301 break; 345 break;
302 case QCSERIAL_HWI: 346 case QCSERIAL_HWI:
303 /* 347 /*
304 * Huawei layout: 348 * Huawei devices map functions by subclass + protocol
305 * 0: AT-capable modem port 349 * instead of interface numbers. The protocol identify
306 * 1: DM/DIAG 350 * a specific function, while the subclass indicate a
307 * 2: AT-capable modem port 351 * specific firmware source
308 * 3: CCID-compatible PCSC interface 352 *
309 * 4: QMI/net 353 * This is a blacklist of functions known to be
310 * 5: NMEA 354 * non-serial. The rest are assumed to be serial and
355 * will be handled by this driver
311 */ 356 */
312 switch (ifnum) { 357 switch (intf->desc.bInterfaceProtocol) {
313 case 0: 358 /* QMI combined (qmi_wwan) */
314 case 2: 359 case 0x07:
315 dev_dbg(dev, "Modem port found\n"); 360 case 0x37:
316 break; 361 case 0x67:
317 case 1: 362 /* QMI data (qmi_wwan) */
318 dev_dbg(dev, "DM/DIAG interface found\n"); 363 case 0x08:
319 break; 364 case 0x38:
320 case 5: 365 case 0x68:
321 dev_dbg(dev, "NMEA GPS interface found\n"); 366 /* QMI control (qmi_wwan) */
322 break; 367 case 0x09:
323 default: 368 case 0x39:
324 /* don't claim any unsupported interface */ 369 case 0x69:
370 /* NCM like (huawei_cdc_ncm) */
371 case 0x16:
372 case 0x46:
373 case 0x76:
325 altsetting = -1; 374 altsetting = -1;
326 break; 375 break;
376 default:
377 dev_dbg(dev, "Huawei type serial port found (%02x/%02x/%02x)\n",
378 intf->desc.bInterfaceClass,
379 intf->desc.bInterfaceSubClass,
380 intf->desc.bInterfaceProtocol);
327 } 381 }
328 break; 382 break;
329 default: 383 default:
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index e9da41d9fe7f..2694df2f4559 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -159,6 +159,7 @@ static const struct usb_device_id ti_id_table_3410[] = {
159 { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STEREO_PLUG_ID) }, 159 { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STEREO_PLUG_ID) },
160 { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STRIP_PORT_ID) }, 160 { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STRIP_PORT_ID) },
161 { USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) }, 161 { USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) },
162 { USB_DEVICE(HONEYWELL_VENDOR_ID, HONEYWELL_HGI80_PRODUCT_ID) },
162 { } /* terminator */ 163 { } /* terminator */
163}; 164};
164 165
@@ -191,6 +192,7 @@ static const struct usb_device_id ti_id_table_combined[] = {
191 { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_PRODUCT_ID) }, 192 { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_PRODUCT_ID) },
192 { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STRIP_PORT_ID) }, 193 { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STRIP_PORT_ID) },
193 { USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) }, 194 { USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) },
195 { USB_DEVICE(HONEYWELL_VENDOR_ID, HONEYWELL_HGI80_PRODUCT_ID) },
194 { } /* terminator */ 196 { } /* terminator */
195}; 197};
196 198
diff --git a/drivers/usb/serial/ti_usb_3410_5052.h b/drivers/usb/serial/ti_usb_3410_5052.h
index 4a2423e84d55..98f35c656c02 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.h
+++ b/drivers/usb/serial/ti_usb_3410_5052.h
@@ -56,6 +56,10 @@
56#define ABBOTT_PRODUCT_ID ABBOTT_STEREO_PLUG_ID 56#define ABBOTT_PRODUCT_ID ABBOTT_STEREO_PLUG_ID
57#define ABBOTT_STRIP_PORT_ID 0x3420 57#define ABBOTT_STRIP_PORT_ID 0x3420
58 58
59/* Honeywell vendor and product IDs */
60#define HONEYWELL_VENDOR_ID 0x10ac
61#define HONEYWELL_HGI80_PRODUCT_ID 0x0102 /* Honeywell HGI80 */
62
59/* Commands */ 63/* Commands */
60#define TI_GET_VERSION 0x01 64#define TI_GET_VERSION 0x01
61#define TI_GET_PORT_STATUS 0x02 65#define TI_GET_PORT_STATUS 0x02