ark3116.c 19.0 KB
Newer Older
1
/*
2 3
 * Copyright (C) 2009 by Bart Hartgers (bart.hartgers+ark3116@gmail.com)
 * Original version:
4 5 6
 * Copyright (C) 2006
 *   Simon Schulz (ark3116_driver <at> auctionant.de)
 *
7 8 9 10
 * ark3116
 * - implements a driver for the arkmicro ark3116 chipset (vendor=0x6547,
 *   productid=0x0232) (used in a datacable called KQ-U8A)
 *
11 12
 * Supports full modem status lines, break, hardware flow control. Does not
 * support software flow control, since I do not know how to enable it in hw.
13
 *
14 15 16 17
 * This driver is a essentially new implementation. I initially dug
 * into the old ark3116.c driver and suddenly realized the ark3116 is
 * a 16450 with a USB interface glued to it. See comments at the
 * bottom of this file.
18 19 20 21 22 23 24 25 26
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.
 */

#include <linux/kernel.h>
#include <linux/init.h>
27
#include <linux/ioctl.h>
28
#include <linux/tty.h>
29
#include <linux/tty_flip.h>
30 31
#include <linux/module.h>
#include <linux/usb.h>
32
#include <linux/usb/serial.h>
33
#include <linux/serial.h>
34
#include <linux/serial_reg.h>
A
Alan Cox 已提交
35
#include <linux/uaccess.h>
36 37
#include <linux/mutex.h>
#include <linux/spinlock.h>
38 39

static int debug;
40 41 42 43 44 45 46 47 48 49 50 51
/*
 * Version information
 */

#define DRIVER_VERSION "v0.5"
#define DRIVER_AUTHOR "Bart Hartgers <bart.hartgers+ark3116@gmail.com>"
#define DRIVER_DESC "USB ARK3116 serial/IrDA driver"
#define DRIVER_DEV_DESC "ARK3116 RS232/IrDA"
#define DRIVER_NAME "ark3116"

/* usb timeout of 1 second */
#define ARK_TIMEOUT (1*HZ)
52 53 54

static struct usb_device_id id_table [] = {
	{ USB_DEVICE(0x6547, 0x0232) },
55
	{ USB_DEVICE(0x18ec, 0x3118) },		/* USB to IrDA adapter */
56 57 58 59
	{ },
};
MODULE_DEVICE_TABLE(usb, id_table);

60 61 62 63 64 65 66 67 68
static int is_irda(struct usb_serial *serial)
{
	struct usb_device *dev = serial->dev;
	if (le16_to_cpu(dev->descriptor.idVendor) == 0x18ec &&
			le16_to_cpu(dev->descriptor.idProduct) == 0x3118)
		return 1;
	return 0;
}

69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
struct ark3116_private {
	wait_queue_head_t       delta_msr_wait;
	struct async_icount	icount;
	int			irda;	/* 1 for irda device */

	/* protects hw register updates */
	struct mutex		hw_lock;

	int			quot;	/* baudrate divisor */
	__u32			lcr;	/* line control register value */
	__u32			hcr;	/* handshake control register (0x8)
					 * value */
	__u32			mcr;	/* modem contol register value */

	/* protects the status values below */
	spinlock_t		status_lock;
	__u32			msr;	/* modem status register value */
	__u32			lsr;	/* line status register value */
};

static int ark3116_write_reg(struct usb_serial *serial,
			     unsigned reg, __u8 val)
{
	int result;
	 /* 0xfe 0x40 are magic values taken from original driver */
	result = usb_control_msg(serial->dev,
				 usb_sndctrlpipe(serial->dev, 0),
				 0xfe, 0x40, val, reg,
				 NULL, 0, ARK_TIMEOUT);
	return result;
}

static int ark3116_read_reg(struct usb_serial *serial,
			    unsigned reg, unsigned char *buf)
{
	int result;
	/* 0xfe 0xc0 are magic values taken from original driver */
	result = usb_control_msg(serial->dev,
				 usb_rcvctrlpipe(serial->dev, 0),
				 0xfe, 0xc0, 0, reg,
				 buf, 1, ARK_TIMEOUT);
	if (result < 0)
		return result;
	else
		return buf[0];
}

116 117 118 119 120 121
static inline void ARK3116_SND(struct usb_serial *serial, int seq,
			       __u8 request, __u8 requesttype,
			       __u16 value, __u16 index)
{
	int result;
	result = usb_control_msg(serial->dev,
122
				 usb_sndctrlpipe(serial->dev, 0),
123
				 request, requesttype, value, index,
124 125
				 NULL, 0x00, 1000);
	dbg("%03d > ok", seq);
126 127 128 129 130 131 132 133 134
}

static inline void ARK3116_RCV(struct usb_serial *serial, int seq,
			       __u8 request, __u8 requesttype,
			       __u16 value, __u16 index, __u8 expected,
			       char *buf)
{
	int result;
	result = usb_control_msg(serial->dev,
135 136 137
				 usb_rcvctrlpipe(serial->dev, 0),
				 request, requesttype, value, index,
				 buf, 0x0000001, 1000);
138
	if (result)
139 140
		dbg("%03d < %d bytes [0x%02X]", seq, result,
		    ((unsigned char *)buf)[0]);
141 142 143 144 145 146 147 148 149
	else
		dbg("%03d < 0 bytes", seq);
}

static inline void ARK3116_RCV_QUIET(struct usb_serial *serial,
				     __u8 request, __u8 requesttype,
				     __u16 value, __u16 index, char *buf)
{
	usb_control_msg(serial->dev,
150
			usb_rcvctrlpipe(serial->dev, 0),
151 152 153 154
			request, requesttype, value, index,
			buf, 0x0000001, 1000);
}

155 156 157 158 159 160 161 162 163 164
static inline int calc_divisor(int bps)
{
	/* Original ark3116 made some exceptions in rounding here
	 * because windows did the same. Assume that is not really
	 * necessary.
	 * Crystal is 12MHz, probably because of USB, but we divide by 4?
	 */
	return (12000000 + 2*bps) / (4*bps);
}

165 166
static int ark3116_attach(struct usb_serial *serial)
{
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
	struct usb_serial_port *port = serial->port[0];
	struct ark3116_private *priv;

	/* make sure we have our end-points */
	if ((serial->num_bulk_in == 0) ||
	    (serial->num_bulk_out == 0) ||
	    (serial->num_interrupt_in == 0)) {
		dev_err(&serial->dev->dev,
			"%s - missing endpoint - "
			"bulk in: %d, bulk out: %d, int in %d\n",
			KBUILD_MODNAME,
			serial->num_bulk_in,
			serial->num_bulk_out,
			serial->num_interrupt_in);
		return -EINVAL;
	}
183

184 185 186
	priv = kzalloc(sizeof(struct ark3116_private),
		       GFP_KERNEL);
	if (!priv)
A
Alan Cox 已提交
187
		return -ENOMEM;
188

189 190 191 192 193 194 195
	init_waitqueue_head(&priv->delta_msr_wait);
	mutex_init(&priv->hw_lock);
	spin_lock_init(&priv->status_lock);

	priv->irda = is_irda(serial);

	usb_set_serial_port_data(port, priv);
196

197 198 199 200 201 202 203 204 205 206
	/* setup the hardware */
	ark3116_write_reg(serial, UART_IER, 0);
	/* disable DMA */
	ark3116_write_reg(serial, UART_FCR, 0);
	/* handshake control */
	priv->hcr = 0;
	ark3116_write_reg(serial, 0x8     , 0);
	/* modem control */
	priv->mcr = 0;
	ark3116_write_reg(serial, UART_MCR, 0);
207

208 209 210 211 212 213 214
	if (!(priv->irda)) {
		ark3116_write_reg(serial, 0xb , 0);
	} else {
		ark3116_write_reg(serial, 0xb , 1);
		ark3116_write_reg(serial, 0xc , 0);
		ark3116_write_reg(serial, 0xd , 0x41);
		ark3116_write_reg(serial, 0xa , 1);
215
	}
216

217 218
	/* setup baudrate */
	ark3116_write_reg(serial, UART_LCR, UART_LCR_DLAB);
219

220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236
	/* setup for 9600 8N1 */
	priv->quot = calc_divisor(9600);
	ark3116_write_reg(serial, UART_DLL, priv->quot & 0xff);
	ark3116_write_reg(serial, UART_DLM, (priv->quot>>8) & 0xff);

	priv->lcr = UART_LCR_WLEN8;
	ark3116_write_reg(serial, UART_LCR, UART_LCR_WLEN8);

	ark3116_write_reg(serial, 0xe, 0);

	if (priv->irda)
		ark3116_write_reg(serial, 0x9, 0);

	dev_info(&serial->dev->dev,
		"%s using %s mode\n",
		KBUILD_MODNAME,
		priv->irda ? "IrDA" : "RS232");
237
	return 0;
A
Alan Cox 已提交
238
}
239

240 241 242 243 244 245 246 247 248 249 250 251 252 253
static void ark3116_release(struct usb_serial *serial)
{
	struct usb_serial_port *port = serial->port[0];
	struct ark3116_private *priv = usb_get_serial_port_data(port);

	/* device is closed, so URBs and DMA should be down */

	usb_set_serial_port_data(port, NULL);

	mutex_destroy(&priv->hw_lock);

	kfree(priv);
}

A
Alan Cox 已提交
254 255 256 257 258 259 260 261
static void ark3116_init_termios(struct tty_struct *tty)
{
	struct ktermios *termios = tty->termios;
	*termios = tty_std_termios;
	termios->c_cflag = B9600 | CS8
				      | CREAD | HUPCL | CLOCAL;
	termios->c_ispeed = 9600;
	termios->c_ospeed = 9600;
262 263
}

A
Alan Cox 已提交
264 265
static void ark3116_set_termios(struct tty_struct *tty,
				struct usb_serial_port *port,
A
Alan Cox 已提交
266
				struct ktermios *old_termios)
267 268
{
	struct usb_serial *serial = port->serial;
269
	struct ark3116_private *priv = usb_get_serial_port_data(port);
A
Alan Cox 已提交
270
	struct ktermios *termios = tty->termios;
A
Alan Cox 已提交
271
	unsigned int cflag = termios->c_cflag;
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325
	int bps = tty_get_baud_rate(tty);
	int quot;
	__u8 lcr, hcr, eval;

	/* set data bit count */
	switch (cflag & CSIZE) {
	case CS5:
		lcr = UART_LCR_WLEN5;
		break;
	case CS6:
		lcr = UART_LCR_WLEN6;
		break;
	case CS7:
		lcr = UART_LCR_WLEN7;
		break;
	default:
	case CS8:
		lcr = UART_LCR_WLEN8;
		break;
	}
	if (cflag & CSTOPB)
		lcr |= UART_LCR_STOP;
	if (cflag & PARENB)
		lcr |= UART_LCR_PARITY;
	if (!(cflag & PARODD))
		lcr |= UART_LCR_EPAR;
#ifdef CMSPAR
	if (cflag & CMSPAR)
		lcr |= UART_LCR_SPAR;
#endif
	/* handshake control */
	hcr = (cflag & CRTSCTS) ? 0x03 : 0x00;

	/* calc baudrate */
	dbg("%s - setting bps to %d", __func__, bps);
	eval = 0;
	switch (bps) {
	case 0:
		quot = calc_divisor(9600);
		break;
	default:
		if ((bps < 75) || (bps > 3000000))
			bps = 9600;
		quot = calc_divisor(bps);
		break;
	case 460800:
		eval = 1;
		quot = calc_divisor(bps);
		break;
	case 921600:
		eval = 2;
		quot = calc_divisor(bps);
		break;
	}
326

327 328
	/* Update state: synchronize */
	mutex_lock(&priv->hw_lock);
329

330 331
	/* keep old LCR_SBC bit */
	lcr |= (priv->lcr & UART_LCR_SBC);
332

333 334
	dbg("%s - setting hcr:0x%02x,lcr:0x%02x,quot:%d",
	    __func__, hcr, lcr, quot);
335

336 337 338 339
	/* handshake control */
	if (priv->hcr != hcr) {
		priv->hcr = hcr;
		ark3116_write_reg(serial, 0x8, hcr);
340 341
	}

342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368
	/* baudrate */
	if (priv->quot != quot) {
		priv->quot = quot;
		priv->lcr = lcr; /* need to write lcr anyway */

		/* disable DMA since transmit/receive is
		 * shadowed by UART_DLL
		 */
		ark3116_write_reg(serial, UART_FCR, 0);

		ark3116_write_reg(serial, UART_LCR,
				  lcr|UART_LCR_DLAB);
		ark3116_write_reg(serial, UART_DLL, quot & 0xff);
		ark3116_write_reg(serial, UART_DLM, (quot>>8) & 0xff);

		/* restore lcr */
		ark3116_write_reg(serial, UART_LCR, lcr);
		/* magic baudrate thingy: not sure what it does,
		 * but windows does this as well.
		 */
		ark3116_write_reg(serial, 0xe, eval);

		/* enable DMA */
		ark3116_write_reg(serial, UART_FCR, UART_FCR_DMA_SELECT);
	} else if (priv->lcr != lcr) {
		priv->lcr = lcr;
		ark3116_write_reg(serial, UART_LCR, lcr);
369 370
	}

371
	mutex_unlock(&priv->hw_lock);
372

373 374 375 376 377
	/* check for software flow control */
	if (I_IXOFF(tty) || I_IXON(tty)) {
		dev_warn(&serial->dev->dev,
			 "%s: don't know how to do software flow control\n",
			 KBUILD_MODNAME);
378 379
	}

380 381 382 383
	/* Don't rewrite B0 */
	if (tty_termios_baud_rate(termios))
		tty_termios_encode_baud_rate(termios, bps, bps);
}
384

385 386 387
static void ark3116_close(struct usb_serial_port *port)
{
	struct usb_serial *serial = port->serial;
388

389 390 391
	if (serial->dev) {
		/* disable DMA */
		ark3116_write_reg(serial, UART_FCR, 0);
392

393 394
		/* deactivate interrupts */
		ark3116_write_reg(serial, UART_IER, 0);
A
Alan Cox 已提交
395

396 397 398 399 400 401 402 403
		/* shutdown any bulk reads that might be going on */
		if (serial->num_bulk_out)
			usb_kill_urb(port->write_urb);
		if (serial->num_bulk_in)
			usb_kill_urb(port->read_urb);
		if (serial->num_interrupt_in)
			usb_kill_urb(port->interrupt_in_urb);
	}
404 405
}

406
static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port)
407
{
408
	struct ark3116_private *priv = usb_get_serial_port_data(port);
409
	struct usb_serial *serial = port->serial;
410 411
	unsigned char *buf;
	int result;
412 413

	buf = kmalloc(1, GFP_KERNEL);
414
	if (buf == NULL)
415 416
		return -ENOMEM;

417
	result = usb_serial_generic_open(tty, port);
418 419 420
	if (result) {
		dbg("%s - usb_serial_generic_open failed: %d",
		    __func__, result);
O
Oliver Neukum 已提交
421
		goto err_out;
422
	}
423

424 425 426
	/* setup termios */
	if (tty)
		ark3116_set_termios(tty, port, NULL);
427

428 429
	/* remove any data still left: also clears error state */
	ark3116_read_reg(serial, UART_RX, buf);
430

431 432 433 434
	/* read modem status */
	priv->msr = ark3116_read_reg(serial, UART_MSR, buf);
	/* read line status */
	priv->lsr = ark3116_read_reg(serial, UART_LSR, buf);
435

436 437 438 439 440 441 442
	result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
	if (result) {
		dev_err(&port->dev, "submit irq_in urb failed %d\n",
			result);
		ark3116_close(port);
		goto err_out;
	}
443

444 445
	/* activate interrupts */
	ark3116_write_reg(port->serial, UART_IER, UART_IER_MSI|UART_IER_RLSI);
446

447 448
	/* enable DMA */
	ark3116_write_reg(port->serial, UART_FCR, UART_FCR_DMA_SELECT);
449

O
Oliver Neukum 已提交
450
err_out:
451 452 453 454
	kfree(buf);
	return result;
}

A
Alan Cox 已提交
455
static int ark3116_ioctl(struct tty_struct *tty, struct file *file,
456 457
			 unsigned int cmd, unsigned long arg)
{
A
Alan Cox 已提交
458
	struct usb_serial_port *port = tty->driver_data;
459
	struct ark3116_private *priv = usb_get_serial_port_data(port);
460 461 462 463 464 465
	struct serial_struct serstruct;
	void __user *user_arg = (void __user *)arg;

	switch (cmd) {
	case TIOCGSERIAL:
		/* XXX: Some of these values are probably wrong. */
A
Alan Cox 已提交
466
		memset(&serstruct, 0, sizeof(serstruct));
467 468 469 470 471 472
		serstruct.type = PORT_16654;
		serstruct.line = port->serial->minor;
		serstruct.port = port->number;
		serstruct.custom_divisor = 0;
		serstruct.baud_base = 460800;

A
Alan Cox 已提交
473
		if (copy_to_user(user_arg, &serstruct, sizeof(serstruct)))
474 475 476 477
			return -EFAULT;

		return 0;
	case TIOCSSERIAL:
A
Alan Cox 已提交
478
		if (copy_from_user(&serstruct, user_arg, sizeof(serstruct)))
479 480
			return -EFAULT;
		return 0;
481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502
	case TIOCMIWAIT:
		for (;;) {
			struct async_icount prev = priv->icount;
			interruptible_sleep_on(&priv->delta_msr_wait);
			/* see if a signal did it */
			if (signal_pending(current))
				return -ERESTARTSYS;
			if ((prev.rng == priv->icount.rng) &&
			    (prev.dsr == priv->icount.dsr) &&
			    (prev.dcd == priv->icount.dcd) &&
			    (prev.cts == priv->icount.cts))
				return -EIO;
			if ((arg & TIOCM_RNG &&
			     (prev.rng != priv->icount.rng)) ||
			    (arg & TIOCM_DSR &&
			     (prev.dsr != priv->icount.dsr)) ||
			    (arg & TIOCM_CD  &&
			     (prev.dcd != priv->icount.dcd)) ||
			    (arg & TIOCM_CTS &&
			     (prev.cts != priv->icount.cts)))
				return 0;
		}
503
		break;
504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522
	case TIOCGICOUNT: {
		struct serial_icounter_struct icount;
		struct async_icount cnow = priv->icount;
		memset(&icount, 0, sizeof(icount));
		icount.cts = cnow.cts;
		icount.dsr = cnow.dsr;
		icount.rng = cnow.rng;
		icount.dcd = cnow.dcd;
		icount.rx = cnow.rx;
		icount.tx = cnow.tx;
		icount.frame = cnow.frame;
		icount.overrun = cnow.overrun;
		icount.parity = cnow.parity;
		icount.brk = cnow.brk;
		icount.buf_overrun = cnow.buf_overrun;
		if (copy_to_user(user_arg, &icount, sizeof(icount)))
			return -EFAULT;
		return 0;
	}
523 524
	}

525 526 527
	return -ENOIOCTLCMD;
}

A
Alan Cox 已提交
528
static int ark3116_tiocmget(struct tty_struct *tty, struct file *file)
529
{
A
Alan Cox 已提交
530
	struct usb_serial_port *port = tty->driver_data;
531 532 533 534
	struct usb_serial *serial = port->serial;
	char *buf;
	char temp;

535
	/* seems like serial port status info (RTS, CTS, ...) is stored
536 537 538 539 540 541 542 543 544 545 546
	 * in reg(?) 0x0006
	 * pcb connection point 11 = GND -> sets bit4 of response
	 * pcb connection point  7 = GND -> sets bit6 of response
	 */

	buf = kmalloc(1, GFP_KERNEL);
	if (!buf) {
		dbg("error kmalloc");
		return -ENOMEM;
	}

547 548
	/* read register */
	ARK3116_RCV_QUIET(serial, 0xFE, 0xC0, 0x0000, 0x0006, buf);
549 550 551
	temp = buf[0];
	kfree(buf);

552 553
	/* i do not really know if bit4=CTS and bit6=DSR... just a
	 * quick guess!
554
	 */
555 556
	return (temp & (1<<4) ? TIOCM_CTS : 0)
	       | (temp & (1<<6) ? TIOCM_DSR : 0);
557 558 559 560 561 562 563
}

static struct usb_driver ark3116_driver = {
	.name =		"ark3116",
	.probe =	usb_serial_probe,
	.disconnect =	usb_serial_disconnect,
	.id_table =	id_table,
564
	.no_dynamic_id =	1,
565 566 567 568 569 570 571 572
};

static struct usb_serial_driver ark3116_device = {
	.driver = {
		.owner =	THIS_MODULE,
		.name =		"ark3116",
	},
	.id_table =		id_table,
573
	.usb_driver =		&ark3116_driver,
574 575
	.num_ports =		1,
	.attach =		ark3116_attach,
576
	.release =		ark3116_release,
577
	.set_termios =		ark3116_set_termios,
A
Alan Cox 已提交
578
	.init_termios =		ark3116_init_termios,
579 580 581
	.ioctl =		ark3116_ioctl,
	.tiocmget =		ark3116_tiocmget,
	.open =			ark3116_open,
582
	.close =		ark3116_close,
583 584 585 586 587 588 589 590 591 592
};

static int __init ark3116_init(void)
{
	int retval;

	retval = usb_serial_register(&ark3116_device);
	if (retval)
		return retval;
	retval = usb_register(&ark3116_driver);
593 594 595 596 597 598
	if (retval == 0) {
		printk(KERN_INFO "%s:"
		       DRIVER_VERSION ":"
		       DRIVER_DESC "\n",
		       KBUILD_MODNAME);
	} else
599 600 601 602 603 604 605 606 607 608 609 610 611 612
		usb_serial_deregister(&ark3116_device);
	return retval;
}

static void __exit ark3116_exit(void)
{
	usb_deregister(&ark3116_driver);
	usb_serial_deregister(&ark3116_device);
}

module_init(ark3116_init);
module_exit(ark3116_exit);
MODULE_LICENSE("GPL");

613 614 615
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);

616
module_param(debug, bool, S_IRUGO | S_IWUSR);
617
MODULE_PARM_DESC(debug, "Enable debug");
618

619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718
/*
 * The following describes what I learned from studying the old
 * ark3116.c driver, disassembling the windows driver, and some lucky
 * guesses. Since I do not have any datasheet or other
 * documentation, inaccuracies are almost guaranteed.
 *
 * Some specs for the ARK3116 can be found here:
 * http://web.archive.org/web/20060318000438/
 *   www.arkmicro.com/en/products/view.php?id=10
 * On that page, 2 GPIO pins are mentioned: I assume these are the
 * OUT1 and OUT2 pins of the UART, so I added support for those
 * through the MCR. Since the pins are not available on my hardware,
 * I could not verify this.
 * Also, it states there is "on-chip hardware flow control". I have
 * discovered how to enable that. Unfortunately, I do not know how to
 * enable XON/XOFF (software) flow control, which would need support
 * from the chip as well to work. Because of the wording on the web
 * page there is a real possibility the chip simply does not support
 * software flow control.
 *
 * I got my ark3116 as part of a mobile phone adapter cable. On the
 * PCB, the following numbered contacts are present:
 *
 *  1:- +5V
 *  2:o DTR
 *  3:i RX
 *  4:i DCD
 *  5:o RTS
 *  6:o TX
 *  7:i RI
 *  8:i DSR
 * 10:- 0V
 * 11:i CTS
 *
 * On my chip, all signals seem to be 3.3V, but 5V tolerant. But that
 * may be different for the one you have ;-).
 *
 * The windows driver limits the registers to 0-F, so I assume there
 * are actually 16 present on the device.
 *
 * On an UART interrupt, 4 bytes of data come in on the interrupt
 * endpoint. The bytes are 0xe8 IIR LSR MSR.
 *
 * The baudrate seems to be generated from the 12MHz crystal, using
 * 4-times subsampling. So quot=12e6/(4*baud). Also see description
 * of register E.
 *
 * Registers 0-7:
 * These seem to be the same as for a regular 16450. The FCR is set
 * to UART_FCR_DMA_SELECT (0x8), I guess to enable transfers between
 * the UART and the USB bridge/DMA engine.
 *
 * Register 8:
 * By trial and error, I found out that bit 0 enables hardware CTS,
 * stopping TX when CTS is +5V. Bit 1 does the same for RTS, making
 * RTS +5V when the 3116 cannot transfer the data to the USB bus
 * (verified by disabling the reading URB). Note that as far as I can
 * tell, the windows driver does NOT use this, so there might be some
 * hardware bug or something.
 *
 * According to a patch provided here
 * (http://lkml.org/lkml/2009/7/26/56), the ARK3116 can also be used
 * as an IrDA dongle. Since I do not have such a thing, I could not
 * investigate that aspect. However, I can speculate ;-).
 *
 * - IrDA encodes data differently than RS232. Most likely, one of
 *   the bits in registers 9..E enables the IR ENDEC (encoder/decoder).
 * - Depending on the IR transceiver, the input and output need to be
 *   inverted, so there are probably bits for that as well.
 * - IrDA is half-duplex, so there should be a bit for selecting that.
 *
 * This still leaves at least two registers unaccounted for. Perhaps
 * The chip can do XON/XOFF or CRC in HW?
 *
 * Register 9:
 * Set to 0x00 for IrDA, when the baudrate is initialised.
 *
 * Register A:
 * Set to 0x01 for IrDA, at init.
 *
 * Register B:
 * Set to 0x01 for IrDA, 0x00 for RS232, at init.
 *
 * Register C:
 * Set to 00 for IrDA, at init.
 *
 * Register D:
 * Set to 0x41 for IrDA, at init.
 *
 * Register E:
 * Somekind of baudrate override. The windows driver seems to set
 * this to 0x00 for normal baudrates, 0x01 for 460800, 0x02 for 921600.
 * Since 460800 and 921600 cannot be obtained by dividing 3MHz by an integer,
 * it could be somekind of subdivisor thingy.
 * However,it does not seem to do anything: selecting 921600 (divisor 3,
 * reg E=2), still gets 1 MHz. I also checked if registers 9, C or F would
 * work, but they don't.
 *
 * Register F: unknown
 */