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