diff mbox series

[2/5] USB: serial: qcserial: add EM7565 (9X50) IDs and configurations

Message ID 20241117083204.57738-2-intelfx@intelfx.name
State New
Headers show
Series None | expand

Commit Message

Ivan Shapovalov Nov. 17, 2024, 8:31 a.m. UTC
This is a port of the corresponding change from the qcserial.c driver
distributed as part of the 9X50 SDK, tested and augmented via
investigation of author's own EM7565 device.

The "MBIM USBIF" configurations correspond to the `AT!USBCOMP=1,1,xxx`
on-device USB composition setting. When activated, the VID:PID resets
to 1199:90b1 ("application" mode) + 1199:90b0 ("boot" mode, i.e. QDL).

The "PCIE USBIF" configurations correspond to the `AT!USBCOMP=1,2,xxx`
on-device USB composition setting. Similarly, when activated, VID:PID
resets to 1199:90c3 ("application" mode) + 1199:90c2 ("boot" mode).

The existing 1199:9091 and 1199:9090 VID:PID pairs correspond to the
"Legacy/Generic" configuration, activated by the `AT!USBCOMP=1,3,xxx`
on-device USB composition setting.

The supported interfaces and their numbers in both these configurations
were confirmed by manual testing. Additional available interfaces
(not claimed by the qcserial driver, such as ADB) found by investigation
were documented in the comments for posterity.

The "MBIM USBIF" and "PCIE USBIF" labels come from on-device help:

---8<---
AT!USBCOMP=?
!USBCOMP:
AT!USBCOMP=<Config Index>,<Config Type>,<Interface bitmask>
  <Config Index>      - configuration index to which the composition applies, should be 1

  <Config Type>       - 1:MBIM USBIF, 2:PCIE USBIF, 3:Legacy-Generic, 4:RNDIS

  <Interface bitmask> - DIAG     - 0x00000001,
                        NMEA     - 0x00000004,
                        MODEM    - 0x00000008,
                        RMNET0   - 0x00000100,
                        MBIM     - 0x00001000,
  e.g.
  10D  - diag, nmea, modem, rmnet interfaces enabled
  1009 - diag, modem, mbim interfaces enabled

  The default configuration is:
  at!usbcomp=1,3,10F

OK
---8<---

Additionally, a fourth PID pair (1199:90c1, 1199:90c0) has been
extracted from on-device help:

---8<---
AT!USBPID=?
APP   BOOT
9091, 9090
90B1, 90B0
90C1, 90C0

OK
---8<---

It is not clear which configuration it corresponds to, but it is
included in the patch for completeness.

Signed-off-by: Ivan Shapovalov <intelfx@intelfx.name>
---
 drivers/usb/serial/qcserial.c | 73 +++++++++++++++++++++++++++++++++++
 1 file changed, 73 insertions(+)
diff mbox series

Patch

diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
index 13c664317a05..c7167242e235 100644
--- a/drivers/usb/serial/qcserial.c
+++ b/drivers/usb/serial/qcserial.c
@@ -26,12 +26,18 @@  enum qcserial_layouts {
 	QCSERIAL_G1K = 1,	/* Gobi 1000 */
 	QCSERIAL_SWI = 2,	/* Sierra Wireless */
 	QCSERIAL_HWI = 3,	/* Huawei */
+	QCSERIAL_SWI_9X50_MBIM = 4, /* Sierra Wireless 9x50 "MBIM USBIF" */
+	QCSERIAL_SWI_9X50_PCIE = 5, /* Sierra Wireless 9x50 "PCIE USBIF" */
 };
 
 #define DEVICE_G1K(v, p) \
 	USB_DEVICE(v, p), .driver_info = QCSERIAL_G1K
 #define DEVICE_SWI(v, p) \
 	USB_DEVICE(v, p), .driver_info = QCSERIAL_SWI
+#define DEVICE_SWI_9X50_PCIE(v, p) \
+	USB_DEVICE(v, p), .driver_info = QCSERIAL_SWI_9X50_PCIE
+#define DEVICE_SWI_9X50_MBIM(v, p) \
+	USB_DEVICE(v, p), .driver_info = QCSERIAL_SWI_9X50_MBIM
 #define DEVICE_HWI(v, p) \
 	USB_DEVICE(v, p), .driver_info = QCSERIAL_HWI
 
@@ -165,6 +171,12 @@  static const struct usb_device_id id_table[] = {
 	{DEVICE_SWI(0x1199, 0x907b)},	/* Sierra Wireless EM74xx */
 	{DEVICE_SWI(0x1199, 0x9090)},	/* Sierra Wireless EM7565 QDL */
 	{DEVICE_SWI(0x1199, 0x9091)},	/* Sierra Wireless EM7565 */
+	{DEVICE_SWI(0x1199, 0x90B0)},	/* Sierra Wireless EM7565 QDL */
+	{DEVICE_SWI_9X50_MBIM(0x1199, 0x90B1)},	/* Sierra Wireless EM7565 "MBIM USBIF" */
+	{DEVICE_SWI(0x1199, 0x90c0)},	/* Sierra Wireless EM7565 QDL */
+	{DEVICE_SWI_9X50_PCIE(0x1199, 0x90c1)},	/* Sierra Wireless EM7565 (unknown configuration, found in on-device AT command help) */
+	{DEVICE_SWI(0x1199, 0x90c2)},	/* Sierra Wireless EM7565 QDL */
+	{DEVICE_SWI_9X50_PCIE(0x1199, 0x90c3)},	/* Sierra Wireless EM7565 "PCIE USBIF" */
 	{DEVICE_SWI(0x1199, 0x90d2)},	/* Sierra Wireless EM9191 QDL */
 	{DEVICE_SWI(0x1199, 0x90e4)},	/* Sierra Wireless EM86xx QDL*/
 	{DEVICE_SWI(0x1199, 0x90e5)},	/* Sierra Wireless EM86xx */
@@ -345,9 +357,11 @@  static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
 		/*
 		 * Sierra Wireless layout:
 		 * 0: DM/DIAG (use libqcdm from ModemManager for communication)
+		 * 1: ADB
 		 * 2: NMEA
 		 * 3: AT-capable modem port
 		 * 8: QMI/net
+		 * 12, 13: MBIM
 		 */
 		switch (ifnum) {
 		case 0:
@@ -403,6 +417,65 @@  static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
 				intf->desc.bInterfaceProtocol);
 		}
 		break;
+	case QCSERIAL_SWI_9X50_MBIM:
+		/*
+		 * Sierra Wireless 9X50 "MBIM USBIF" layout:
+		 * 0, 1: MBIM
+		 * 2: AT-capable modem port
+		 * 3: NMEA
+		 * 4: DM
+		 * 7: ADB
+		 */
+		switch (ifnum) {
+		case 2:
+			dev_dbg(dev, "Modem port found\n");
+			sendsetup = true;
+			break;
+		case 3:
+			dev_dbg(dev, "NMEA GPS interface found\n");
+			sendsetup = true;
+			break;
+		case 4:
+			dev_dbg(dev, "DM/DIAG interface found\n");
+			break;
+		default:
+			/* don't claim any unsupported interface */
+			altsetting = -1;
+			break;
+		}
+		break;
+	case QCSERIAL_SWI_9X50_PCIE:
+		/*
+		 * Sierra Wireless 9X50 "PCIE USBIF" layout:
+		 * 0: AT-capable modem port
+		 * 1: NMEA
+		 * 2: DM
+		 * 5: ADB
+		 * No other interfaces possible, presumably this configuration
+		 * means that data exchange is happening via PCIe (but we are
+		 * not making this an error).
+		 */
+		switch (ifnum) {
+		case 0:
+			dev_dbg(dev, "Modem port found\n");
+			sendsetup = true;
+			break;
+		case 1:
+			dev_dbg(dev, "NMEA GPS interface found\n");
+			sendsetup = true;
+			break;
+		case 2:
+			dev_dbg(dev, "DM/DIAG interface found\n");
+			break;
+		default:
+			dev_err(dev,
+			        "unexpected interface for PCIE-USBIF layout type: %u\n",
+			        (unsigned)ifnum);
+			/* don't claim any unsupported interface */
+			altsetting = -1;
+			break;
+		}
+		break;
 	default:
 		dev_err(dev, "unsupported device layout type: %lu\n",
 			id->driver_info);