]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.25/patches.drivers/usb-serial-add-qualcomm-wireless-modem-driver.patch
Reenabled linux-xen and xen-image build
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.drivers / usb-serial-add-qualcomm-wireless-modem-driver.patch
CommitLineData
00e5a55c
BS
1From foo@baz Tue Feb 17 22:39:56 PST 2009
2Date: Tue, 17 Feb 2009 22:39:56 -0800
3To: Greg KH <greg@kroah.com>
4From: Greg Kroah-Hartman <gregkh@suse.de>
5Subject: USB: serial: add qualcomm wireless modem driver
6
7Driver originally written by Qualcomm, but rewritten by me due to the
8totally different coding style. Cleaned up the probe logic to make a
9bit more sense, this is one wierd device. They could have prevented all
10of this by just writing sane firmware for the modem.
11
12Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
13
14---
15 drivers/usb/serial/Kconfig | 9 ++
16 drivers/usb/serial/Makefile | 1
17 drivers/usb/serial/qcserial.c | 152 ++++++++++++++++++++++++++++++++++++++++++
18 3 files changed, 162 insertions(+)
19
20--- a/drivers/usb/serial/Kconfig
21+++ b/drivers/usb/serial/Kconfig
22@@ -472,6 +472,15 @@ config USB_SERIAL_OTI6858
23 To compile this driver as a module, choose M here: the
24 module will be called oti6858.
25
26+config USB_SERIAL_QUALCOMM
27+ tristate "USB Qualcomm Serial modem"
28+ help
29+ Say Y here if you have a Qualcomm USB modem device. These are
30+ usually wireless cellular modems.
31+
32+ To compile this driver as a module, choose M here: the
33+ module will be called qcserial.
34+
35 config USB_SERIAL_SPCP8X5
36 tristate "USB SPCP8x5 USB To Serial Driver"
37 help
38--- a/drivers/usb/serial/Makefile
39+++ b/drivers/usb/serial/Makefile
40@@ -44,6 +44,7 @@ obj-$(CONFIG_USB_SERIAL_OMNINET) += omn
41 obj-$(CONFIG_USB_SERIAL_OPTION) += option.o
42 obj-$(CONFIG_USB_SERIAL_OTI6858) += oti6858.o
43 obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o
44+obj-$(CONFIG_USB_SERIAL_QUALCOMM) += qcserial.o
45 obj-$(CONFIG_USB_SERIAL_SAFE) += safe_serial.o
46 obj-$(CONFIG_USB_SERIAL_SIERRAWIRELESS) += sierra.o
47 obj-$(CONFIG_USB_SERIAL_SPCP8X5) += spcp8x5.o
48--- /dev/null
49+++ b/drivers/usb/serial/qcserial.c
50@@ -0,0 +1,152 @@
51+/*
52+ * Qualcomm Serial USB driver
53+ *
54+ * Copyright (c) 2008 QUALCOMM Incorporated.
55+ * Copyright (c) 2009 Greg Kroah-Hartman <gregkh@suse.de>
56+ * Copyright (c) 2009 Novell Inc.
57+ *
58+ * This program is free software; you can redistribute it and/or
59+ * modify it under the terms of the GNU General Public License version
60+ * 2 as published by the Free Software Foundation.
61+ *
62+ */
63+
64+#include <linux/tty.h>
65+#include <linux/tty_flip.h>
66+#include <linux/usb.h>
67+#include <linux/usb/serial.h>
68+
69+#define DRIVER_VERSION "v0.4"
70+#define DRIVER_AUTHOR "Qualcomm Inc"
71+#define DRIVER_DESC "Qualcomm USB Serial driver"
72+
73+#define NUM_BULK_EPS 1
74+#define MAX_BULK_EPS 6
75+
76+static int debug;
77+
78+static struct usb_device_id id_table[] = {
79+ {USB_DEVICE(0x05c6, 0x9211)}, /* Acer Gobi QDL device */
80+ {USB_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */
81+ { } /* Terminating entry */
82+};
83+MODULE_DEVICE_TABLE(usb, id_table);
84+
85+static struct usb_driver qcdriver = {
86+ .name = "qcserial",
87+ .probe = usb_serial_probe,
88+ .disconnect = usb_serial_disconnect,
89+ .id_table = id_table,
90+ .suspend = usb_serial_suspend,
91+ .resume = usb_serial_resume,
92+ .supports_autosuspend = true,
93+};
94+
95+static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
96+{
97+ int retval = -ENODEV;
98+ __u8 nintf;
99+ __u8 ifnum;
100+
101+ dbg("%s", __func__);
102+
103+ nintf = serial->dev->actconfig->desc.bNumInterfaces;
104+ dbg("Num Interfaces = %d", nintf);
105+ ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber;
106+ dbg("This Interface = %d", ifnum);
107+
108+ switch (nintf) {
109+ case 1:
110+ /* QDL mode */
111+ if (serial->interface->num_altsetting == 2) {
112+ struct usb_host_interface *intf;
113+
114+ intf = &serial->interface->altsetting[1];
115+ if (intf->desc.bNumEndpoints == 2) {
116+ if (usb_endpoint_is_bulk_in(&intf->endpoint[0].desc) &&
117+ usb_endpoint_is_bulk_out(&intf->endpoint[1].desc)) {
118+ dbg("QDL port found");
119+ retval = usb_set_interface(serial->dev, ifnum, 1);
120+ if (retval < 0) {
121+ dev_err(&serial->dev->dev,
122+ "Could not set interface, error %d\n",
123+ retval);
124+ retval = -ENODEV;
125+ }
126+ return retval;
127+ }
128+ }
129+ }
130+ break;
131+
132+ case 4:
133+ /* Composite mode */
134+ if (ifnum == 2) {
135+ dbg("Modem port found");
136+ retval = usb_set_interface(serial->dev, ifnum, 0);
137+ if (retval < 0) {
138+ dev_err(&serial->dev->dev,
139+ "Could not set interface, error %d\n",
140+ retval);
141+ retval = -ENODEV;
142+ }
143+ return retval;
144+ }
145+ break;
146+
147+ default:
148+ dev_err(&serial->dev->dev,
149+ "unknown number of interfaces: %d\n", nintf);
150+ return -ENODEV;
151+ }
152+
153+ return retval;
154+}
155+
156+static struct usb_serial_driver qcdevice = {
157+ .driver = {
158+ .owner = THIS_MODULE,
159+ .name = "qcserial",
160+ },
161+ .description = "Qualcomm USB modem",
162+ .id_table = id_table,
163+ .usb_driver = &qcdriver,
164+ .num_ports = 1,
165+ .probe = qcprobe,
166+};
167+
168+static int __init qcinit(void)
169+{
170+ int retval;
171+
172+ retval = usb_serial_register(&qcdevice);
173+ if (retval)
174+ return retval;
175+
176+ retval = usb_register(&qcdriver);
177+ if (retval) {
178+ usb_serial_deregister(&qcdevice);
179+ return retval;
180+ }
181+
182+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION "\n");
183+
184+ return 0;
185+}
186+
187+static void __exit qcexit(void)
188+{
189+ usb_deregister(&qcdriver);
190+ usb_serial_deregister(&qcdevice);
191+}
192+
193+module_init(qcinit);
194+module_exit(qcexit);
195+
196+MODULE_AUTHOR(DRIVER_AUTHOR);
197+MODULE_DESCRIPTION(DRIVER_DESC);
198+MODULE_LICENSE("GPL v2");
199+MODULE_VERSION(DRIVER_VERSION);
200+
201+module_param(debug, bool, S_IRUGO | S_IWUSR);
202+MODULE_PARM_DESC(debug, "Debug enabled or not");