ch341.c revision 6ce76104781a10554129791dc62c3104424f6d48
1/* 2 * Copyright 2007, Frank A Kingswood <frank@kingswood-consulting.co.uk> 3 * 4 * ch341.c implements a serial port driver for the Winchiphead CH341. 5 * 6 * The CH341 device can be used to implement an RS232 asynchronous 7 * serial port, an IEEE-1284 parallel printer port or a memory-like 8 * interface. In all cases the CH341 supports an I2C interface as well. 9 * This driver only supports the asynchronous serial interface. 10 * 11 * This program is free software; you can redistribute it and/or 12 * modify it under the terms of the GNU General Public License version 13 * 2 as published by the Free Software Foundation. 14 */ 15 16#include <linux/kernel.h> 17#include <linux/init.h> 18#include <linux/tty.h> 19#include <linux/module.h> 20#include <linux/usb.h> 21#include <linux/usb/serial.h> 22#include <linux/serial.h> 23 24#define DEFAULT_BAUD_RATE 2400 25#define DEFAULT_TIMEOUT 1000 26 27static int debug; 28 29static struct usb_device_id id_table [] = { 30 { USB_DEVICE(0x4348, 0x5523) }, 31 { }, 32}; 33MODULE_DEVICE_TABLE(usb, id_table); 34 35struct ch341_private { 36 unsigned baud_rate; 37 u8 dtr; 38 u8 rts; 39}; 40 41static int ch341_control_out(struct usb_device *dev, u8 request, 42 u16 value, u16 index) 43{ 44 int r; 45 dbg("ch341_control_out(%02x,%02x,%04x,%04x)", USB_DIR_OUT|0x40, 46 (int)request, (int)value, (int)index); 47 48 r = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), request, 49 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, 50 value, index, NULL, 0, DEFAULT_TIMEOUT); 51 52 return r; 53} 54 55static int ch341_control_in(struct usb_device *dev, 56 u8 request, u16 value, u16 index, 57 char *buf, unsigned bufsize) 58{ 59 int r; 60 dbg("ch341_control_in(%02x,%02x,%04x,%04x,%p,%u)", USB_DIR_IN|0x40, 61 (int)request, (int)value, (int)index, buf, (int)bufsize); 62 63 r = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), request, 64 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 65 value, index, buf, bufsize, DEFAULT_TIMEOUT); 66 return r; 67} 68 69int ch341_set_baudrate(struct usb_device *dev, struct ch341_private *priv) 70{ 71 short a, b; 72 int r; 73 74 dbg("ch341_set_baudrate(%d)", priv->baud_rate); 75 switch (priv->baud_rate) { 76 case 2400: 77 a = 0xd901; 78 b = 0x0038; 79 break; 80 case 4800: 81 a = 0x6402; 82 b = 0x001f; 83 break; 84 case 9600: 85 a = 0xb202; 86 b = 0x0013; 87 break; 88 case 19200: 89 a = 0xd902; 90 b = 0x000d; 91 break; 92 case 38400: 93 a = 0x6403; 94 b = 0x000a; 95 break; 96 case 115200: 97 a = 0xcc03; 98 b = 0x0008; 99 break; 100 default: 101 return -EINVAL; 102 } 103 104 r = ch341_control_out(dev, 0x9a, 0x1312, a); 105 if (!r) 106 r = ch341_control_out(dev, 0x9a, 0x0f2c, b); 107 108 return r; 109} 110 111int ch341_set_handshake(struct usb_device *dev, struct ch341_private *priv) 112{ 113 dbg("ch341_set_handshake(%d,%d)", priv->dtr, priv->rts); 114 return ch341_control_out(dev, 0xa4, 115 ~((priv->dtr?1<<5:0)|(priv->rts?1<<6:0)), 0); 116} 117 118int ch341_get_status(struct usb_device *dev) 119{ 120 char *buffer; 121 int r; 122 const unsigned size = 8; 123 124 dbg("ch341_get_status()"); 125 126 buffer = kmalloc(size, GFP_KERNEL); 127 if (!buffer) 128 return -ENOMEM; 129 130 r = ch341_control_in(dev, 0x95, 0x0706, 0, buffer, size); 131 if ( r < 0) 132 goto out; 133 134 /* Not having the datasheet for the CH341, we ignore the bytes returned 135 * from the device. Return error if the device did not respond in time. 136 */ 137 r = 0; 138 139out: kfree(buffer); 140 return r; 141} 142 143/* -------------------------------------------------------------------------- */ 144 145int ch341_configure(struct usb_device *dev, struct ch341_private *priv) 146{ 147 char *buffer; 148 int r; 149 const unsigned size = 8; 150 151 dbg("ch341_configure()"); 152 153 buffer = kmalloc(size, GFP_KERNEL); 154 if (!buffer) 155 return -ENOMEM; 156 157 /* expect two bytes 0x27 0x00 */ 158 r = ch341_control_in(dev, 0x5f, 0, 0, buffer, size); 159 if (r < 0) 160 goto out; 161 162 r = ch341_control_out(dev, 0xa1, 0, 0); 163 if (r < 0) 164 goto out; 165 166 r = ch341_set_baudrate(dev, priv); 167 if (r < 0) 168 goto out; 169 170 /* expect two bytes 0x56 0x00 */ 171 r = ch341_control_in(dev, 0x95, 0x2518, 0, buffer, size); 172 if (r < 0) 173 goto out; 174 175 r = ch341_control_out(dev, 0x9a, 0x2518, 0x0050); 176 if (r < 0) 177 goto out; 178 179 /* expect 0xff 0xee */ 180 r = ch341_get_status(dev); 181 if (r < 0) 182 goto out; 183 184 r = ch341_control_out(dev, 0xa1, 0x501f, 0xd90a); 185 if (r < 0) 186 goto out; 187 188 r = ch341_set_baudrate(dev, priv); 189 if (r < 0) 190 goto out; 191 192 r = ch341_set_handshake(dev, priv); 193 if (r < 0) 194 goto out; 195 196 /* expect 0x9f 0xee */ 197 r = ch341_get_status(dev); 198 199out: kfree(buffer); 200 return r; 201} 202 203/* allocate private data */ 204static int ch341_attach(struct usb_serial *serial) 205{ 206 struct ch341_private *priv; 207 int r; 208 209 dbg("ch341_attach()"); 210 211 /* private data */ 212 priv = kzalloc(sizeof(struct ch341_private), GFP_KERNEL); 213 if (!priv) 214 return -ENOMEM; 215 216 priv->baud_rate = DEFAULT_BAUD_RATE; 217 priv->dtr = 1; 218 priv->rts = 1; 219 220 r = ch341_configure(serial->dev, priv); 221 if (r < 0) 222 goto error; 223 224 usb_set_serial_port_data(serial->port[0], priv); 225 return 0; 226 227error: kfree(priv); 228 return r; 229} 230 231/* open this device, set default parameters */ 232static int ch341_open(struct usb_serial_port *port, struct file *filp) 233{ 234 struct usb_serial *serial = port->serial; 235 struct ch341_private *priv = usb_get_serial_port_data(serial->port[0]); 236 int r; 237 238 dbg("ch341_open()"); 239 240 priv->baud_rate = DEFAULT_BAUD_RATE; 241 priv->dtr = 1; 242 priv->rts = 1; 243 244 r = ch341_configure(serial->dev, priv); 245 if (r) 246 goto out; 247 248 r = ch341_set_handshake(serial->dev, priv); 249 if (r) 250 goto out; 251 252 r = ch341_set_baudrate(serial->dev, priv); 253 if (r) 254 goto out; 255 256 r = usb_serial_generic_open(port, filp); 257 258out: return r; 259} 260 261/* Old_termios contains the original termios settings and 262 * tty->termios contains the new setting to be used. 263 */ 264static void ch341_set_termios(struct usb_serial_port *port, 265 struct ktermios *old_termios) 266{ 267 struct ch341_private *priv = usb_get_serial_port_data(port); 268 struct tty_struct *tty = port->tty; 269 unsigned baud_rate; 270 271 dbg("ch341_set_termios()"); 272 273 if (!tty || !tty->termios) 274 return; 275 276 baud_rate = tty_get_baud_rate(tty); 277 278 switch (baud_rate) { 279 case 2400: 280 case 4800: 281 case 9600: 282 case 19200: 283 case 38400: 284 case 115200: 285 priv->baud_rate = baud_rate; 286 break; 287 default: 288 dbg("Rate %d not supported, using %d", 289 baud_rate, DEFAULT_BAUD_RATE); 290 priv->baud_rate = DEFAULT_BAUD_RATE; 291 } 292 293 ch341_set_baudrate(port->serial->dev, priv); 294 295 /* Unimplemented: 296 * (cflag & CSIZE) : data bits [5, 8] 297 * (cflag & PARENB) : parity {NONE, EVEN, ODD} 298 * (cflag & CSTOPB) : stop bits [1, 2] 299 */ 300} 301 302static struct usb_driver ch341_driver = { 303 .name = "ch341", 304 .probe = usb_serial_probe, 305 .disconnect = usb_serial_disconnect, 306 .id_table = id_table, 307 .no_dynamic_id = 1, 308}; 309 310static struct usb_serial_driver ch341_device = { 311 .driver = { 312 .owner = THIS_MODULE, 313 .name = "ch341-uart", 314 }, 315 .id_table = id_table, 316 .usb_driver = &ch341_driver, 317 .num_interrupt_in = NUM_DONT_CARE, 318 .num_bulk_in = 1, 319 .num_bulk_out = 1, 320 .num_ports = 1, 321 .open = ch341_open, 322 .set_termios = ch341_set_termios, 323 .attach = ch341_attach, 324}; 325 326static int __init ch341_init(void) 327{ 328 int retval; 329 330 retval = usb_serial_register(&ch341_device); 331 if (retval) 332 return retval; 333 retval = usb_register(&ch341_driver); 334 if (retval) 335 usb_serial_deregister(&ch341_device); 336 return retval; 337} 338 339static void __exit ch341_exit(void) 340{ 341 usb_deregister(&ch341_driver); 342 usb_serial_deregister(&ch341_device); 343} 344 345module_init(ch341_init); 346module_exit(ch341_exit); 347MODULE_LICENSE("GPL"); 348 349module_param(debug, bool, S_IRUGO | S_IWUSR); 350MODULE_PARM_DESC(debug, "Debug enabled or not"); 351 352/* EOF ch341.c */ 353