diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-11-19 17:08:37 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-11-19 17:08:37 -0500 |
commit | 0a72f2ad84cc9dde5e4c7ab905a2f89593ddc0b6 (patch) | |
tree | 36838e38f3ae12403ab6dd24571e3308a64ed63e | |
parent | dad67d5f3d0efe01d38c6cebcb6698280e51927b (diff) | |
parent | 59536da34513c594af2a6fd35ba65ea45b6960a1 (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.c | 2 | ||||
-rw-r--r-- | drivers/usb/serial/qcserial.c | 94 | ||||
-rw-r--r-- | drivers/usb/serial/ti_usb_3410_5052.c | 2 | ||||
-rw-r--r-- | drivers/usb/serial/ti_usb_3410_5052.h | 4 |
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 */ |
26 | enum qcserial_layouts { | 28 | enum 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 | }; |
172 | MODULE_DEVICE_TABLE(usb, id_table); | 174 | MODULE_DEVICE_TABLE(usb, id_table); |
173 | 175 | ||
176 | static 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 | |||
174 | static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) | 208 | static 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 |