Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
zte_ev.c
Go to the documentation of this file.
1 /*
2  * ZTE_EV USB serial driver
3  *
4  * Copyright (C) 2012 Greg Kroah-Hartman <[email protected]>
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 
26 static 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 
35 static 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 
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 
161 static 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 
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 
279 }
280 
281 static 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 };
289 MODULE_DEVICE_TABLE(usb, id_table);
290 
291 static 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 
302 static struct usb_serial_driver * const serial_drivers[] = {
303  &zio_device, NULL
304 };
305 
306 module_usb_serial_driver(serial_drivers, id_table);
307 MODULE_LICENSE("GPL v2");