USB: qcserial: Enable Diagnostics Monitor and GPS ports on Gobi 2000
authorMatthias G. Eckermann <mge@arcor.de>
Fri, 24 Sep 2010 16:12:01 +0000 (18:12 +0200)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 22 Oct 2010 17:21:49 +0000 (10:21 -0700)
this patch to qcserial.c enables the Diagnostics Monitor
and NMEA GPS ports on Qualcomm Gobi 2000 devices.

A Gobi 2000 device will provide 3 serial ports:
        # /dev/ttyUSB0 -> Diagnostics
        # /dev/ttyUSB1 -> 3G Modem
        # /dev/ttyUSB2 -> NMEA GPS port

* The Diagnostics Monitor uses Qualcomm's DM protocol; I used
  libqcdm (ModemManager) to talk to it, found it working, but at
  least DM commands 12 and 64 are not implemented on my device
  (Gobi 2000 built into Thinkpad x100e).

* Functionality of the 3G Modem port remains unchanged.

* The GPS port and how to enable it has been confirmed now in the
  Gobi 3000 source code at:
https://www.codeaurora.org/patches/quic/gobi/
  Enable/disable GPS via:
        echo "\$GPS_START" > /dev/ttyUSB2
        # use GPS
        echo "\$GPS_STOP"  > /dev/ttyUSB2

Signed-off-by: Matthias G. Eckermann <mge@arcor.de>

drivers/usb/serial/qcserial.c

index 2846ad8..8858201 100644 (file)
@@ -152,7 +152,22 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
        case 3:
        case 4:
                /* Composite mode */
-               if (ifnum == 2) {
+               /* ifnum == 0 is a broadband network adapter */
+               if (ifnum == 1) {
+                       /*
+                        * Diagnostics Monitor (serial line 9600 8N1)
+                        * Qualcomm DM protocol
+                        * use "libqcdm" (ModemManager) for communication
+                        */
+                       dbg("Diagnostics Monitor found");
+                       retval = usb_set_interface(serial->dev, ifnum, 0);
+                       if (retval < 0) {
+                               dev_err(&serial->dev->dev,
+                                       "Could not set interface, error %d\n",
+                                       retval);
+                               retval = -ENODEV;
+                       }
+               } else if (ifnum == 2) {
                        dbg("Modem port found");
                        retval = usb_set_interface(serial->dev, ifnum, 0);
                        if (retval < 0) {
@@ -163,6 +178,20 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
                                kfree(data);
                        }
                        return retval;
+               } else if (ifnum==3) {
+                       /*
+                        * NMEA (serial line 9600 8N1)
+                        * # echo "\$GPS_START" > /dev/ttyUSBx
+                        * # echo "\$GPS_STOP"  > /dev/ttyUSBx
+                        */
+                       dbg("NMEA GPS interface found");
+                       retval = usb_set_interface(serial->dev, ifnum, 0);
+                       if (retval < 0) {
+                               dev_err(&serial->dev->dev,
+                                       "Could not set interface, error %d\n",
+                                       retval);
+                               retval = -ENODEV;
+                       }
                }
                break;