aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/zte_ev.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-01 16:23:01 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-01 16:23:01 -0400
commitd9a807461fc8cc0d6ba589ea0730d139122af012 (patch)
tree9d8c7a044659d821748dd40718a22557c04e4299 /drivers/usb/serial/zte_ev.c
parent3498d13b8090c0b0ef911409fbc503a7c4cca6ef (diff)
parent70c048a238c780c226eb4b115ebaa908cb3b34ec (diff)
Merge tag 'usb-3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB changes from Greg Kroah-Hartman: "Here is the big USB pull request for 3.7-rc1 There are lots of gadget driver changes (including copying a bunch of files into the drivers/staging/ccg/ directory so that the other gadget drivers can be fixed up properly without breaking that driver), and we remove the old obsolete ub.c driver from the tree. There are also the usual XHCI set of updates, and other various driver changes and updates. We also are trying hard to remove the old dbg() macro, but the final bits of that removal will be coming in through the networking tree before we can delete it for good. All of these patches have been in the linux-next tree. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>" Fix up several annoying - but fairly mindless - conflicts due to the termios structure having moved into the tty device, and often clashing with dbg -> dev_dbg conversion. * tag 'usb-3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (339 commits) USB: ezusb: move ezusb.c from drivers/usb/serial to drivers/usb/misc USB: uas: fix gcc warning USB: uas: fix locking USB: Fix race condition when removing host controllers USB: uas: add locking USB: uas: fix abort USB: uas: remove aborted field, replace with status bit. USB: uas: fix task management USB: uas: keep track of command urbs xhci: Intel Panther Point BEI quirk. powerpc/usb: remove checking PHY_CLK_VALID for UTMI PHY USB: ftdi_sio: add TIAO USB Multi-Protocol Adapter (TUMPA) support Revert "usb : Add sysfs files to control port power." USB: serial: remove vizzini driver usb: host: xhci: Fix Null pointer dereferencing with 71c731a for non-x86 systems Increase XHCI suspend timeout to 16ms USB: ohci-at91: fix null pointer in ohci_hcd_at91_overcurrent_irq USB: sierra_ms: don't keep unused variable fsl/usb: Add support for USB controller version 2.4 USB: qcaux: add Pantech vendor class match ...
Diffstat (limited to 'drivers/usb/serial/zte_ev.c')
-rw-r--r--drivers/usb/serial/zte_ev.c307
1 files changed, 307 insertions, 0 deletions
diff --git a/drivers/usb/serial/zte_ev.c b/drivers/usb/serial/zte_ev.c
new file mode 100644
index 000000000000..39ee7373b4ee
--- /dev/null
+++ b/drivers/usb/serial/zte_ev.c
@@ -0,0 +1,307 @@
1/*
2 * ZTE_EV USB serial driver
3 *
4 * Copyright (C) 2012 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
5 * Copyright (C) 2012 Linux Foundation
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This driver is based on code found in a ZTE_ENV patch that modified
12 * the usb-serial generic driver. Comments were left in that I think
13 * show the commands used to talk to the device, but I am not sure.
14 */
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/tty.h>
18#include <linux/slab.h>
19#include <linux/module.h>
20#include <linux/usb.h>
21#include <linux/usb/serial.h>
22#include <linux/uaccess.h>
23
24#define MAX_SETUP_DATA_SIZE 32
25
26static void debug_data(struct device *dev, const char *function, int len,
27 const unsigned char *data, int result)
28{
29 dev_dbg(dev, "result = %d\n", result);
30 if (result == len)
31 dev_dbg(dev, "%s - length = %d, data = %*ph\n", function,
32 len, len, data);
33}
34
35static int zte_ev_usb_serial_open(struct tty_struct *tty,
36 struct usb_serial_port *port)
37{
38 struct usb_device *udev = port->serial->dev;
39 struct device *dev = &port->dev;
40 int result = 0;
41 int len;
42 unsigned char *buf;
43
44 if (port->number != 0)
45 return -ENODEV;
46
47 buf = kmalloc(MAX_SETUP_DATA_SIZE, GFP_KERNEL);
48 if (!buf)
49 return -ENOMEM;
50
51 /* send 1st ctl cmd(CTL 21 22 01 00 00 00 00 00) */
52 len = 0;
53 result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
54 0x22, 0x21,
55 0x0001, 0x0000, NULL, len,
56 HZ * USB_CTRL_GET_TIMEOUT);
57 dev_dbg(dev, "result = %d\n", result);
58
59 /* send 2st cmd and recieve data */
60 /*
61 * 16.0 CTL a1 21 00 00 00 00 07 00 CLASS 25.1.0(5)
62 * 16.0 DI 00 96 00 00 00 00 08
63 */
64 len = 0x0007;
65 result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
66 0x21, 0xa1,
67 0x0000, 0x0000, buf, len,
68 HZ * USB_CTRL_GET_TIMEOUT);
69 debug_data(dev, __func__, len, buf, result);
70
71 /* send 3 cmd */
72 /*
73 * 16.0 CTL 21 20 00 00 00 00 07 00 CLASS 30.1.0
74 * 16.0 DO 80 25 00 00 00 00 08 .%..... 30.2.0
75 */
76 len = 0x0007;
77 buf[0] = 0x80;
78 buf[1] = 0x25;
79 buf[2] = 0x00;
80 buf[3] = 0x00;
81 buf[4] = 0x00;
82 buf[5] = 0x00;
83 buf[6] = 0x08;
84 result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
85 0x20, 0x21,
86 0x0000, 0x0000, buf, len,
87 HZ * USB_CTRL_GET_TIMEOUT);
88 debug_data(dev, __func__, len, buf, result);
89
90 /* send 4 cmd */
91 /*
92 * 16.0 CTL 21 22 03 00 00 00 00 00
93 */
94 len = 0;
95 result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
96 0x22, 0x21,
97 0x0003, 0x0000, NULL, len,
98 HZ * USB_CTRL_GET_TIMEOUT);
99 dev_dbg(dev, "result = %d\n", result);
100
101 /* send 5 cmd */
102 /*
103 * 16.0 CTL a1 21 00 00 00 00 07 00 CLASS 33.1.0
104 * 16.0 DI 80 25 00 00 00 00 08
105 */
106 len = 0x0007;
107 result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
108 0x21, 0xa1,
109 0x0000, 0x0000, buf, len,
110 HZ * USB_CTRL_GET_TIMEOUT);
111 debug_data(dev, __func__, len, buf, result);
112
113 /* send 6 cmd */
114 /*
115 * 16.0 CTL 21 20 00 00 00 00 07 00 CLASS 34.1.0
116 * 16.0 DO 80 25 00 00 00 00 08
117 */
118 len = 0x0007;
119 buf[0] = 0x80;
120 buf[1] = 0x25;
121 buf[2] = 0x00;
122 buf[3] = 0x00;
123 buf[4] = 0x00;
124 buf[5] = 0x00;
125 buf[6] = 0x08;
126 result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
127 0x20, 0x21,
128 0x0000, 0x0000, buf, len,
129 HZ * USB_CTRL_GET_TIMEOUT);
130 debug_data(dev, __func__, len, buf, result);
131 kfree(buf);
132
133 return usb_serial_generic_open(tty, port);
134}
135
136/*
137 * CTL 21 22 02 00 00 00 00 00 CLASS 338.1.0
138 *
139 * 16.1 DI a1 20 00 00 00 00 02 00 02 00 . ........ 340.1.0
140 * 16.0 CTL 21 22 03 00 00 00 00 00 CLASS 341.1.0
141 *
142 * 16.0 CTL a1 21 00 00 00 00 07 00 CLASS 346.1.0(3)
143 * 16.0 DI 00 08 07 00 00 00 08 ....... 346.2.0
144 *
145 * 16.0 CTL 21 20 00 00 00 00 07 00 CLASS 349.1.0
146 * 16.0 DO 00 c2 01 00 00 00 08 ....... 349.2.0
147 *
148 * 16.0 CTL 21 22 03 00 00 00 00 00 CLASS 350.1.0(2)
149 *
150 * 16.0 CTL a1 21 00 00 00 00 07 00 CLASS 352.1.0
151 * 16.0 DI 00 c2 01 00 00 00 08 ....... 352.2.0
152 *
153 * 16.1 DI a1 20 00 00 00 00 02 00 02 00 . ........ 353.1.0
154 *
155 * 16.0 CTL 21 20 00 00 00 00 07 00 CLASS 354.1.0
156 * 16.0 DO 00 c2 01 00 00 00 08 ....... 354.2.0
157 *
158 * 16.0 CTL 21 22 03 00 00 00 00 00
159*/
160
161static void zte_ev_usb_serial_close(struct usb_serial_port *port)
162{
163 struct usb_device *udev = port->serial->dev;
164 struct device *dev = &port->dev;
165 int result = 0;
166 int len;
167 unsigned char *buf;
168
169 if (port->number != 0)
170 return;
171
172 buf = kmalloc(MAX_SETUP_DATA_SIZE, GFP_KERNEL);
173 if (!buf)
174 return;
175
176 /* send 1st ctl cmd(CTL 21 22 02 00 00 00 00 00) */
177 len = 0;
178 result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
179 0x22, 0x21,
180 0x0002, 0x0000, NULL, len,
181 HZ * USB_CTRL_GET_TIMEOUT);
182 dev_dbg(dev, "result = %d\n", result);
183
184 /* send 2st ctl cmd(CTL 21 22 03 00 00 00 00 00 ) */
185 len = 0;
186 result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
187 0x22, 0x21,
188 0x0003, 0x0000, NULL, len,
189 HZ * USB_CTRL_GET_TIMEOUT);
190 dev_dbg(dev, "result = %d\n", result);
191
192 /* send 3st cmd and recieve data */
193 /*
194 * 16.0 CTL a1 21 00 00 00 00 07 00 CLASS 25.1.0(5)
195 * 16.0 DI 00 08 07 00 00 00 08
196 */
197 len = 0x0007;
198 result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
199 0x21, 0xa1,
200 0x0000, 0x0000, buf, len,
201 HZ * USB_CTRL_GET_TIMEOUT);
202 debug_data(dev, __func__, len, buf, result);
203
204 /* send 4 cmd */
205 /*
206 * 16.0 CTL 21 20 00 00 00 00 07 00 CLASS 30.1.0
207 * 16.0 DO 00 c2 01 00 00 00 08 .%..... 30.2.0
208 */
209 len = 0x0007;
210 buf[0] = 0x00;
211 buf[1] = 0xc2;
212 buf[2] = 0x01;
213 buf[3] = 0x00;
214 buf[4] = 0x00;
215 buf[5] = 0x00;
216 buf[6] = 0x08;
217 result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
218 0x20, 0x21,
219 0x0000, 0x0000, buf, len,
220 HZ * USB_CTRL_GET_TIMEOUT);
221 debug_data(dev, __func__, len, buf, result);
222
223 /* send 5 cmd */
224 /*
225 * 16.0 CTL 21 22 03 00 00 00 00 00
226 */
227 len = 0;
228 result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
229 0x22, 0x21,
230 0x0003, 0x0000, NULL, len,
231 HZ * USB_CTRL_GET_TIMEOUT);
232 dev_dbg(dev, "result = %d\n", result);
233
234 /* send 6 cmd */
235 /*
236 * 16.0 CTL a1 21 00 00 00 00 07 00 CLASS 33.1.0
237 * 16.0 DI 00 c2 01 00 00 00 08
238 */
239 len = 0x0007;
240 result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
241 0x21, 0xa1,
242 0x0000, 0x0000, buf, len,
243 HZ * USB_CTRL_GET_TIMEOUT);
244 debug_data(dev, __func__, len, buf, result);
245
246 /* send 7 cmd */
247 /*
248 * 16.0 CTL 21 20 00 00 00 00 07 00 CLASS 354.1.0
249 * 16.0 DO 00 c2 01 00 00 00 08 ....... 354.2.0
250 */
251 len = 0x0007;
252 buf[0] = 0x00;
253 buf[1] = 0xc2;
254 buf[2] = 0x01;
255 buf[3] = 0x00;
256 buf[4] = 0x00;
257 buf[5] = 0x00;
258 buf[6] = 0x08;
259 result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
260 0x20, 0x21,
261 0x0000, 0x0000, buf, len,
262 HZ * USB_CTRL_GET_TIMEOUT);
263 debug_data(dev, __func__, len, buf, result);
264
265 /* send 8 cmd */
266 /*
267 * 16.0 CTL 21 22 03 00 00 00 00 00
268 */
269 len = 0;
270 result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
271 0x22, 0x21,
272 0x0003, 0x0000, NULL, len,
273 HZ * USB_CTRL_GET_TIMEOUT);
274 dev_dbg(dev, "result = %d\n", result);
275
276 kfree(buf);
277
278 usb_serial_generic_close(port);
279}
280
281static const struct usb_device_id id_table[] = {
282 { USB_DEVICE(0x19d2, 0xffff) }, /* AC8700 */
283 { USB_DEVICE(0x19d2, 0xfffe) },
284 { USB_DEVICE(0x19d2, 0xfffd) }, /* MG880 */
285 { USB_DEVICE(0x05C6, 0x3197) },
286 { USB_DEVICE(0x05C6, 0x6000) },
287 { },
288};
289MODULE_DEVICE_TABLE(usb, id_table);
290
291static struct usb_serial_driver zio_device = {
292 .driver = {
293 .owner = THIS_MODULE,
294 .name = "zte_ev",
295 },
296 .id_table = id_table,
297 .num_ports = 1,
298 .open = zte_ev_usb_serial_open,
299 .close = zte_ev_usb_serial_close,
300};
301
302static struct usb_serial_driver * const serial_drivers[] = {
303 &zio_device, NULL
304};
305
306module_usb_serial_driver(serial_drivers, id_table);
307MODULE_LICENSE("GPL v2");