USB: qcaux: driver for auxiliary serial ports on Qualcomm devices
authorDan Williams <dcbw@redhat.com>
Thu, 25 Feb 2010 18:39:20 +0000 (10:39 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 2 Mar 2010 22:55:19 +0000 (14:55 -0800)
qcaux: add driver for QCDM-capable ports on various devices

Many Qualcomm-based devices provide a CDC-ACM port which accepts
normal AT commands and PPP connections.  But they only provide one
which makes status or signal strength requests impossible while
PPP is active.  They also provide secondary USB interfaces that
talk the Qualcomm Diagnostic Monitor (QCDM) protocol which can be
used for status and strength.  Make those QCDM ports accessible.

Signed-off-by: Dan Williams <dcbw@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/serial/Kconfig
drivers/usb/serial/Makefile
drivers/usb/serial/qcaux.c [new file with mode: 0644]

index d9f289ca2bda37c4203b24c0af64206dc145e6b4..c78b255e3f831ee7cd086c6053f7728915062783 100644 (file)
@@ -472,6 +472,17 @@ config USB_SERIAL_OTI6858
          To compile this driver as a module, choose M here: the
          module will be called oti6858.
 
+config USB_SERIAL_QCAUX
+       tristate "USB Qualcomm Auxiliary Serial Port Driver"
+       ---help---
+         Say Y here if you want to use the auxiliary serial ports provided
+         by many modems based on Qualcomm chipsets.  These ports often use
+         a proprietary protocol called DM and cannot be used for AT- or
+         PPP-based communication.
+
+         To compile this driver as a module, choose M here: the
+         module will be called moto_modem.  If unsure, choose N.
+
 config USB_SERIAL_QUALCOMM
        tristate "USB Qualcomm Serial modem"
        help
index 108c7d8f0c71660fdd6ece18575e0e11e712d768..83c9e431a56805fb3d3c33c812b2cdf5e27c71b2 100644 (file)
@@ -45,6 +45,7 @@ obj-$(CONFIG_USB_SERIAL_OPTICON)              += opticon.o
 obj-$(CONFIG_USB_SERIAL_OPTION)                        += option.o
 obj-$(CONFIG_USB_SERIAL_OTI6858)               += oti6858.o
 obj-$(CONFIG_USB_SERIAL_PL2303)                        += pl2303.o
+obj-$(CONFIG_USB_SERIAL_QCAUX)                 += qcaux.o
 obj-$(CONFIG_USB_SERIAL_QUALCOMM)              += qcserial.o
 obj-$(CONFIG_USB_SERIAL_SAFE)                  += safe_serial.o
 obj-$(CONFIG_USB_SERIAL_SIEMENS_MPI)           += siemens_mpi.o
diff --git a/drivers/usb/serial/qcaux.c b/drivers/usb/serial/qcaux.c
new file mode 100644 (file)
index 0000000..0b93620
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Qualcomm USB Auxiliary Serial Port driver
+ *
+ * Copyright (C) 2008 Greg Kroah-Hartman <greg@kroah.com>
+ * Copyright (C) 2010 Dan Williams <dcbw@redhat.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ * Devices listed here usually provide a CDC ACM port on which normal modem
+ * AT commands and PPP can be used.  But when that port is in-use by PPP it
+ * cannot be used simultaneously for status or signal strength.  Instead, the
+ * ports here can be queried for that information using the Qualcomm DM
+ * protocol.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/tty.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/serial.h>
+
+/* NOTE: for now, only use this driver for devices that provide a CDC-ACM port
+ * for normal AT commands, but also provide secondary USB interfaces for the
+ * QCDM-capable ports.  Devices that do not provide a CDC-ACM port should
+ * probably be driven by option.ko.
+ */
+
+/* UTStarcom/Pantech/Curitel devices */
+#define UTSTARCOM_VENDOR_ID                    0x106c
+#define UTSTARCOM_PRODUCT_PC5740               0x3701
+#define UTSTARCOM_PRODUCT_PC5750               0x3702 /* aka Pantech PX-500 */
+#define UTSTARCOM_PRODUCT_UM150                        0x3711
+#define UTSTARCOM_PRODUCT_UM175_V1             0x3712
+#define UTSTARCOM_PRODUCT_UM175_V2             0x3714
+#define UTSTARCOM_PRODUCT_UM175_ALLTEL         0x3715
+
+/* CMOTECH devices */
+#define CMOTECH_VENDOR_ID                      0x16d8
+#define CMOTECH_PRODUCT_CDU550                 0x5553
+#define CMOTECH_PRODUCT_CDX650                 0x6512
+
+static struct usb_device_id id_table[] = {
+       { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_PC5740, 0xff, 0x00, 0x00) },
+       { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_PC5750, 0xff, 0x00, 0x00) },
+       { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_UM150, 0xff, 0x00, 0x00) },
+       { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_UM175_V1, 0xff, 0x00, 0x00) },
+       { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_UM175_V2, 0xff, 0x00, 0x00) },
+       { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_UM175_ALLTEL, 0xff, 0x00, 0x00) },
+       { USB_DEVICE_AND_INTERFACE_INFO(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CDU550, 0xff, 0xff, 0x00) },
+       { USB_DEVICE_AND_INTERFACE_INFO(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CDX650, 0xff, 0xff, 0x00) },
+       { },
+};
+MODULE_DEVICE_TABLE(usb, id_table);
+
+static struct usb_driver qcaux_driver = {
+       .name =         "qcaux",
+       .probe =        usb_serial_probe,
+       .disconnect =   usb_serial_disconnect,
+       .id_table =     id_table,
+       .no_dynamic_id =        1,
+};
+
+static struct usb_serial_driver qcaux_device = {
+       .driver = {
+               .owner =        THIS_MODULE,
+               .name =         "qcaux",
+       },
+       .id_table =             id_table,
+       .num_ports =            1,
+};
+
+static int __init qcaux_init(void)
+{
+       int retval;
+
+       retval = usb_serial_register(&qcaux_device);
+       if (retval)
+               return retval;
+       retval = usb_register(&qcaux_driver);
+       if (retval)
+               usb_serial_deregister(&qcaux_device);
+       return retval;
+}
+
+static void __exit qcaux_exit(void)
+{
+       usb_deregister(&qcaux_driver);
+       usb_serial_deregister(&qcaux_device);
+}
+
+module_init(qcaux_init);
+module_exit(qcaux_exit);
+MODULE_LICENSE("GPL");