Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.15-rc7 317 lines 8.8 kB view raw
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 25static 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 34static 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 157static 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 274static 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}; 299MODULE_DEVICE_TABLE(usb, id_table); 300 301static 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 312static struct usb_serial_driver * const serial_drivers[] = { 313 &zio_device, NULL 314}; 315 316module_usb_serial_driver(serial_drivers, id_table); 317MODULE_LICENSE("GPL v2");