ARM: 8130/1: cpuidle/cpuidle-big_little: fix reading cpu id part number
[cascardo/linux.git] / drivers / usb / serial / zte_ev.c
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/tty.h>
17 #include <linux/slab.h>
18 #include <linux/module.h>
19 #include <linux/usb.h>
20 #include <linux/usb/serial.h>
21 #include <linux/uaccess.h>
22
23 #define  MAX_SETUP_DATA_SIZE    32
24
25 static void debug_data(struct device *dev, const char *function, int len,
26                        const unsigned char *data, int result)
27 {
28         dev_dbg(dev, "result = %d\n", result);
29         if (result == len)
30                 dev_dbg(dev, "%s - length = %d, data = %*ph\n", function,
31                         len, len, data);
32 }
33
34 static int zte_ev_usb_serial_open(struct tty_struct *tty,
35                                   struct usb_serial_port *port)
36 {
37         struct usb_device *udev = port->serial->dev;
38         struct device *dev = &port->dev;
39         int result = 0;
40         int len;
41         unsigned char *buf;
42
43         buf = kmalloc(MAX_SETUP_DATA_SIZE, GFP_KERNEL);
44         if (!buf)
45                 return -ENOMEM;
46
47         /* send 1st ctl cmd(CTL    21 22 01 00  00 00 00 00) */
48         len = 0;
49         result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
50                                  0x22, 0x21,
51                                  0x0001, 0x0000, NULL, len,
52                                  USB_CTRL_GET_TIMEOUT);
53         dev_dbg(dev, "result = %d\n", result);
54
55         /* send 2st cmd and receive data */
56         /*
57          * 16.0  CTL    a1 21 00 00  00 00 07 00   CLASS              25.1.0(5)
58          * 16.0  DI     00 96 00 00  00 00 08
59          */
60         len = 0x0007;
61         result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
62                                  0x21, 0xa1,
63                                  0x0000, 0x0000, buf, len,
64                                  USB_CTRL_GET_TIMEOUT);
65         debug_data(dev, __func__, len, buf, result);
66
67         /* send 3rd cmd */
68         /*
69          * 16.0 CTL    21 20 00 00  00 00 07 00    CLASS                30.1.0
70          * 16.0 DO     80 25 00 00  00 00 08       .%.....              30.2.0
71          */
72         len = 0x0007;
73         buf[0] = 0x80;
74         buf[1] = 0x25;
75         buf[2] = 0x00;
76         buf[3] = 0x00;
77         buf[4] = 0x00;
78         buf[5] = 0x00;
79         buf[6] = 0x08;
80         result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
81                                  0x20, 0x21,
82                                  0x0000, 0x0000, buf, len,
83                                  USB_CTRL_GET_TIMEOUT);
84         debug_data(dev, __func__, len, buf, result);
85
86         /* send 4th cmd */
87         /*
88          * 16.0 CTL    21 22 03 00  00 00 00 00
89          */
90         len = 0;
91         result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
92                                  0x22, 0x21,
93                                  0x0003, 0x0000, NULL, len,
94                                  USB_CTRL_GET_TIMEOUT);
95         dev_dbg(dev, "result = %d\n", result);
96
97         /* send 5th cmd */
98         /*
99          * 16.0  CTL    a1 21 00 00  00 00 07 00   CLASS               33.1.0
100          * 16.0  DI     80 25 00 00  00 00 08
101          */
102         len = 0x0007;
103         result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
104                                  0x21, 0xa1,
105                                  0x0000, 0x0000, buf, len,
106                                  USB_CTRL_GET_TIMEOUT);
107         debug_data(dev, __func__, len, buf, result);
108
109         /* send 6th cmd */
110         /*
111          * 16.0  CTL    21 20 00 00  00 00 07 00    CLASS               34.1.0
112          * 16.0  DO     80 25 00 00  00 00 08
113          */
114         len = 0x0007;
115         buf[0] = 0x80;
116         buf[1] = 0x25;
117         buf[2] = 0x00;
118         buf[3] = 0x00;
119         buf[4] = 0x00;
120         buf[5] = 0x00;
121         buf[6] = 0x08;
122         result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
123                                  0x20, 0x21,
124                                  0x0000, 0x0000, buf, len,
125                                  USB_CTRL_GET_TIMEOUT);
126         debug_data(dev, __func__, len, buf, result);
127         kfree(buf);
128
129         return usb_serial_generic_open(tty, port);
130 }
131
132 /*
133  *       CTL    21 22 02 00  00 00 00 00         CLASS               338.1.0
134  *
135  * 16.1  DI     a1 20 00 00  00 00 02 00  02 00  . ........          340.1.0
136  * 16.0  CTL    21 22 03 00  00 00 00 00         CLASS               341.1.0
137  *
138  * 16.0  CTL    a1 21 00 00  00 00 07 00         CLASS               346.1.0(3)
139  * 16.0  DI     00 08 07 00  00 00 08            .......             346.2.0
140  *
141  * 16.0  CTL    21 20 00 00  00 00 07 00         CLASS               349.1.0
142  * 16.0  DO     00 c2 01 00  00 00 08            .......             349.2.0
143  *
144  * 16.0  CTL    21 22 03 00  00 00 00 00         CLASS               350.1.0(2)
145  *
146  * 16.0  CTL    a1 21 00 00  00 00 07 00         CLASS               352.1.0
147  * 16.0  DI     00 c2 01 00  00 00 08            .......             352.2.0
148  *
149  * 16.1  DI     a1 20 00 00  00 00 02 00  02 00  . ........          353.1.0
150  *
151  * 16.0  CTL    21 20 00 00  00 00 07 00         CLASS               354.1.0
152  * 16.0  DO     00 c2 01 00  00 00 08            .......             354.2.0
153  *
154  * 16.0  CTL    21 22 03 00  00 00 00 00
155 */
156
157 static void zte_ev_usb_serial_close(struct usb_serial_port *port)
158 {
159         struct usb_device *udev = port->serial->dev;
160         struct device *dev = &port->dev;
161         int result = 0;
162         int len;
163         unsigned char *buf;
164
165         buf = kmalloc(MAX_SETUP_DATA_SIZE, GFP_KERNEL);
166         if (!buf)
167                 return;
168
169         /* send 1st ctl cmd(CTL    21 22 02 00  00 00 00 00) */
170         len = 0;
171         result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
172                                  0x22, 0x21,
173                                  0x0002, 0x0000, NULL, len,
174                                  USB_CTRL_GET_TIMEOUT);
175         dev_dbg(dev, "result = %d\n", result);
176
177         /* send 2st ctl cmd(CTL    21 22 03 00  00 00 00 00 ) */
178         len = 0;
179         result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
180                                  0x22, 0x21,
181                                  0x0003, 0x0000, NULL, len,
182                                  USB_CTRL_GET_TIMEOUT);
183         dev_dbg(dev, "result = %d\n", result);
184
185         /* send  3st cmd and recieve data */
186         /*
187          * 16.0  CTL    a1 21 00 00  00 00 07 00      CLASS         25.1.0(5)
188          * 16.0  DI     00 08 07 00  00 00 08
189          */
190         len = 0x0007;
191         result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
192                                  0x21, 0xa1,
193                                  0x0000, 0x0000, buf, len,
194                                  USB_CTRL_GET_TIMEOUT);
195         debug_data(dev, __func__, len, buf, result);
196
197         /* send 4th cmd */
198         /*
199          * 16.0 CTL    21 20 00 00  00 00 07 00      CLASS            30.1.0
200          * 16.0  DO    00 c2 01 00  00 00 08         .%.....          30.2.0
201          */
202         len = 0x0007;
203         buf[0] = 0x00;
204         buf[1] = 0xc2;
205         buf[2] = 0x01;
206         buf[3] = 0x00;
207         buf[4] = 0x00;
208         buf[5] = 0x00;
209         buf[6] = 0x08;
210         result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
211                                  0x20, 0x21,
212                                  0x0000, 0x0000, buf, len,
213                                  USB_CTRL_GET_TIMEOUT);
214         debug_data(dev, __func__, len, buf, result);
215
216         /* send 5th cmd */
217         /*
218          * 16.0 CTL    21 22 03 00  00 00 00 00
219          */
220         len = 0;
221         result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
222                                  0x22, 0x21,
223                                  0x0003, 0x0000, NULL, len,
224                                  USB_CTRL_GET_TIMEOUT);
225         dev_dbg(dev, "result = %d\n", result);
226
227         /* send 6th cmd */
228         /*
229          * 16.0  CTL    a1 21 00 00  00 00 07 00        CLASS          33.1.0
230          * 16.0  DI     00 c2 01 00  00 00 08
231          */
232         len = 0x0007;
233         result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
234                                  0x21, 0xa1,
235                                  0x0000, 0x0000, buf, len,
236                                  USB_CTRL_GET_TIMEOUT);
237         debug_data(dev, __func__, len, buf, result);
238
239         /* send 7th cmd */
240         /*
241          * 16.0  CTL    21 20 00 00  00 00 07 00  CLASS               354.1.0
242          * 16.0  DO     00 c2 01 00  00 00 08     .......             354.2.0
243          */
244         len = 0x0007;
245         buf[0] = 0x00;
246         buf[1] = 0xc2;
247         buf[2] = 0x01;
248         buf[3] = 0x00;
249         buf[4] = 0x00;
250         buf[5] = 0x00;
251         buf[6] = 0x08;
252         result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
253                                  0x20, 0x21,
254                                  0x0000, 0x0000, buf, len,
255                                  USB_CTRL_GET_TIMEOUT);
256         debug_data(dev, __func__, len, buf, result);
257
258         /* send 8th cmd */
259         /*
260          * 16.0 CTL    21 22 03 00  00 00 00 00
261          */
262         len = 0;
263         result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
264                                  0x22, 0x21,
265                                  0x0003, 0x0000, NULL, len,
266                                  USB_CTRL_GET_TIMEOUT);
267         dev_dbg(dev, "result = %d\n", result);
268
269         kfree(buf);
270
271         usb_serial_generic_close(port);
272 }
273
274 static const struct usb_device_id id_table[] = {
275         /* AC8710, AC8710T */
276         { USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xffff, 0xff, 0xff, 0xff) },
277          /* AC8700 */
278         { USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xfffe, 0xff, 0xff, 0xff) },
279         /* MG880 */
280         { USB_DEVICE(0x19d2, 0xfffd) },
281         { USB_DEVICE(0x19d2, 0xfffc) },
282         { USB_DEVICE(0x19d2, 0xfffb) },
283         /* AC8710_V3 */
284         { USB_DEVICE(0x19d2, 0xfff6) },
285         { USB_DEVICE(0x19d2, 0xfff7) },
286         { USB_DEVICE(0x19d2, 0xfff8) },
287         { USB_DEVICE(0x19d2, 0xfff9) },
288         { USB_DEVICE(0x19d2, 0xffee) },
289         /* AC2716, MC2716 */
290         { USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xffed, 0xff, 0xff, 0xff) },
291         /* AD3812 */
292         { USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xffeb, 0xff, 0xff, 0xff) },
293         { USB_DEVICE(0x19d2, 0xffec) },
294         { USB_DEVICE(0x05C6, 0x3197) },
295         { USB_DEVICE(0x05C6, 0x6000) },
296         { USB_DEVICE(0x05C6, 0x9008) },
297         { },
298 };
299 MODULE_DEVICE_TABLE(usb, id_table);
300
301 static struct usb_serial_driver zio_device = {
302         .driver = {
303                 .owner =        THIS_MODULE,
304                 .name =         "zte_ev",
305         },
306         .id_table =             id_table,
307         .num_ports =            1,
308         .open =                 zte_ev_usb_serial_open,
309         .close =                zte_ev_usb_serial_close,
310 };
311
312 static struct usb_serial_driver * const serial_drivers[] = {
313         &zio_device, NULL
314 };
315
316 module_usb_serial_driver(serial_drivers, id_table);
317 MODULE_LICENSE("GPL v2");