^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2009 by Bart Hartgers (bart.hartgers+ark3116@gmail.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Original version:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2006
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Simon Schulz (ark3116_driver <at> auctionant.de)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * ark3116
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * - implements a driver for the arkmicro ark3116 chipset (vendor=0x6547,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * productid=0x0232) (used in a datacable called KQ-U8A)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Supports full modem status lines, break, hardware flow control. Does not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * support software flow control, since I do not know how to enable it in hw.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * This driver is a essentially new implementation. I initially dug
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * into the old ark3116.c driver and suddenly realized the ark3116 is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * a 16450 with a USB interface glued to it. See comments at the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * bottom of this file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/ioctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/tty.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/tty_flip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/usb/serial.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/serial.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/serial_reg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define DRIVER_AUTHOR "Bart Hartgers <bart.hartgers+ark3116@gmail.com>"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define DRIVER_DESC "USB ARK3116 serial/IrDA driver"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define DRIVER_DEV_DESC "ARK3116 RS232/IrDA"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define DRIVER_NAME "ark3116"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /* usb timeout of 1 second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define ARK_TIMEOUT 1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) static const struct usb_device_id id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) { USB_DEVICE(0x6547, 0x0232) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) { USB_DEVICE(0x18ec, 0x3118) }, /* USB to IrDA adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) MODULE_DEVICE_TABLE(usb, id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static int is_irda(struct usb_serial *serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct usb_device *dev = serial->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) if (le16_to_cpu(dev->descriptor.idVendor) == 0x18ec &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) le16_to_cpu(dev->descriptor.idProduct) == 0x3118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct ark3116_private {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) int irda; /* 1 for irda device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /* protects hw register updates */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct mutex hw_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) int quot; /* baudrate divisor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) __u32 lcr; /* line control register value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) __u32 hcr; /* handshake control register (0x8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) __u32 mcr; /* modem control register value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /* protects the status values below */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) spinlock_t status_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) __u32 msr; /* modem status register value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) __u32 lsr; /* line status register value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static int ark3116_write_reg(struct usb_serial *serial,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) unsigned reg, __u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /* 0xfe 0x40 are magic values taken from original driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) result = usb_control_msg(serial->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) usb_sndctrlpipe(serial->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) 0xfe, 0x40, val, reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) NULL, 0, ARK_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) static int ark3116_read_reg(struct usb_serial *serial,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) unsigned reg, unsigned char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /* 0xfe 0xc0 are magic values taken from original driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) result = usb_control_msg(serial->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) usb_rcvctrlpipe(serial->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) 0xfe, 0xc0, 0, reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) buf, 1, ARK_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (result < 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) dev_err(&serial->interface->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) "failed to read register %u: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) reg, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (result >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) result = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static inline int calc_divisor(int bps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) /* Original ark3116 made some exceptions in rounding here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * because windows did the same. Assume that is not really
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * necessary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * Crystal is 12MHz, probably because of USB, but we divide by 4?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return (12000000 + 2*bps) / (4*bps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) static int ark3116_port_probe(struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct usb_serial *serial = port->serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct ark3116_private *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) priv = kzalloc(sizeof(*priv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (!priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) mutex_init(&priv->hw_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) spin_lock_init(&priv->status_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) priv->irda = is_irda(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) usb_set_serial_port_data(port, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /* setup the hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) ark3116_write_reg(serial, UART_IER, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) /* disable DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) ark3116_write_reg(serial, UART_FCR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /* handshake control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) priv->hcr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) ark3116_write_reg(serial, 0x8 , 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) /* modem control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) priv->mcr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) ark3116_write_reg(serial, UART_MCR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) if (!(priv->irda)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) ark3116_write_reg(serial, 0xb , 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) ark3116_write_reg(serial, 0xb , 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) ark3116_write_reg(serial, 0xc , 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) ark3116_write_reg(serial, 0xd , 0x41);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) ark3116_write_reg(serial, 0xa , 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /* setup baudrate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) ark3116_write_reg(serial, UART_LCR, UART_LCR_DLAB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /* setup for 9600 8N1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) priv->quot = calc_divisor(9600);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) ark3116_write_reg(serial, UART_DLL, priv->quot & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) ark3116_write_reg(serial, UART_DLM, (priv->quot>>8) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) priv->lcr = UART_LCR_WLEN8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) ark3116_write_reg(serial, UART_LCR, UART_LCR_WLEN8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) ark3116_write_reg(serial, 0xe, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (priv->irda)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) ark3116_write_reg(serial, 0x9, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) dev_info(&port->dev, "using %s mode\n", priv->irda ? "IrDA" : "RS232");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) static int ark3116_port_remove(struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct ark3116_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) /* device is closed, so URBs and DMA should be down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) mutex_destroy(&priv->hw_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) kfree(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) static void ark3116_set_termios(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) struct usb_serial_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) struct ktermios *old_termios)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) struct usb_serial *serial = port->serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct ark3116_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) struct ktermios *termios = &tty->termios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) unsigned int cflag = termios->c_cflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) int bps = tty_get_baud_rate(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) int quot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) __u8 lcr, hcr, eval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /* set data bit count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) switch (cflag & CSIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) case CS5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) lcr = UART_LCR_WLEN5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) case CS6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) lcr = UART_LCR_WLEN6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) case CS7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) lcr = UART_LCR_WLEN7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) case CS8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) lcr = UART_LCR_WLEN8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if (cflag & CSTOPB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) lcr |= UART_LCR_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) if (cflag & PARENB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) lcr |= UART_LCR_PARITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (!(cflag & PARODD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) lcr |= UART_LCR_EPAR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) #ifdef CMSPAR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (cflag & CMSPAR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) lcr |= UART_LCR_SPAR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) /* handshake control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) hcr = (cflag & CRTSCTS) ? 0x03 : 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /* calc baudrate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) dev_dbg(&port->dev, "%s - setting bps to %d\n", __func__, bps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) eval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) switch (bps) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) quot = calc_divisor(9600);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if ((bps < 75) || (bps > 3000000))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) bps = 9600;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) quot = calc_divisor(bps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) case 460800:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) eval = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) quot = calc_divisor(bps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) case 921600:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) eval = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) quot = calc_divisor(bps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) /* Update state: synchronize */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) mutex_lock(&priv->hw_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) /* keep old LCR_SBC bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) lcr |= (priv->lcr & UART_LCR_SBC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) dev_dbg(&port->dev, "%s - setting hcr:0x%02x,lcr:0x%02x,quot:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) __func__, hcr, lcr, quot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) /* handshake control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (priv->hcr != hcr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) priv->hcr = hcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) ark3116_write_reg(serial, 0x8, hcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) /* baudrate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (priv->quot != quot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) priv->quot = quot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) priv->lcr = lcr; /* need to write lcr anyway */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) /* disable DMA since transmit/receive is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * shadowed by UART_DLL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) ark3116_write_reg(serial, UART_FCR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) ark3116_write_reg(serial, UART_LCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) lcr|UART_LCR_DLAB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) ark3116_write_reg(serial, UART_DLL, quot & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) ark3116_write_reg(serial, UART_DLM, (quot>>8) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) /* restore lcr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) ark3116_write_reg(serial, UART_LCR, lcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) /* magic baudrate thingy: not sure what it does,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) * but windows does this as well.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) ark3116_write_reg(serial, 0xe, eval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) /* enable DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) ark3116_write_reg(serial, UART_FCR, UART_FCR_DMA_SELECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) } else if (priv->lcr != lcr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) priv->lcr = lcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) ark3116_write_reg(serial, UART_LCR, lcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) mutex_unlock(&priv->hw_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) /* check for software flow control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (I_IXOFF(tty) || I_IXON(tty)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) dev_warn(&port->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) "software flow control not implemented\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) /* Don't rewrite B0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (tty_termios_baud_rate(termios))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) tty_termios_encode_baud_rate(termios, bps, bps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) static void ark3116_close(struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) struct usb_serial *serial = port->serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) /* disable DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) ark3116_write_reg(serial, UART_FCR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) /* deactivate interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) ark3116_write_reg(serial, UART_IER, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) usb_serial_generic_close(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) usb_kill_urb(port->interrupt_in_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) struct ark3116_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) struct usb_serial *serial = port->serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) unsigned char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) buf = kmalloc(1, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (buf == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) result = usb_serial_generic_open(tty, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) dev_dbg(&port->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) "%s - usb_serial_generic_open failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) __func__, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) goto err_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) /* remove any data still left: also clears error state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) ark3116_read_reg(serial, UART_RX, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) /* read modem status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) result = ark3116_read_reg(serial, UART_MSR, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) goto err_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) priv->msr = *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) /* read line status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) result = ark3116_read_reg(serial, UART_LSR, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) goto err_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) priv->lsr = *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) if (result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) dev_err(&port->dev, "submit irq_in urb failed %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) goto err_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) /* activate interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) ark3116_write_reg(port->serial, UART_IER, UART_IER_MSI|UART_IER_RLSI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) /* enable DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) ark3116_write_reg(port->serial, UART_FCR, UART_FCR_DMA_SELECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) /* setup termios */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) ark3116_set_termios(tty, port, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) err_close:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) usb_serial_generic_close(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) err_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) static int ark3116_get_serial_info(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) struct serial_struct *ss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) struct usb_serial_port *port = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) ss->type = PORT_16654;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) ss->line = port->minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) ss->port = port->port_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) ss->baud_base = 460800;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) static int ark3116_tiocmget(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) struct usb_serial_port *port = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) struct ark3116_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) __u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) __u32 ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) mutex_lock(&priv->hw_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) ctrl = priv->mcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) mutex_unlock(&priv->hw_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) spin_lock_irqsave(&priv->status_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) status = priv->msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) spin_unlock_irqrestore(&priv->status_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return (status & UART_MSR_DSR ? TIOCM_DSR : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) (status & UART_MSR_CTS ? TIOCM_CTS : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) (status & UART_MSR_RI ? TIOCM_RI : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) (status & UART_MSR_DCD ? TIOCM_CD : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) (ctrl & UART_MCR_DTR ? TIOCM_DTR : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) (ctrl & UART_MCR_RTS ? TIOCM_RTS : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) (ctrl & UART_MCR_OUT1 ? TIOCM_OUT1 : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) (ctrl & UART_MCR_OUT2 ? TIOCM_OUT2 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) static int ark3116_tiocmset(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) unsigned set, unsigned clr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) struct usb_serial_port *port = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) struct ark3116_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) /* we need to take the mutex here, to make sure that the value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) * in priv->mcr is actually the one that is in the hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) mutex_lock(&priv->hw_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (set & TIOCM_RTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) priv->mcr |= UART_MCR_RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (set & TIOCM_DTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) priv->mcr |= UART_MCR_DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (set & TIOCM_OUT1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) priv->mcr |= UART_MCR_OUT1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (set & TIOCM_OUT2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) priv->mcr |= UART_MCR_OUT2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (clr & TIOCM_RTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) priv->mcr &= ~UART_MCR_RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (clr & TIOCM_DTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) priv->mcr &= ~UART_MCR_DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) if (clr & TIOCM_OUT1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) priv->mcr &= ~UART_MCR_OUT1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (clr & TIOCM_OUT2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) priv->mcr &= ~UART_MCR_OUT2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) ark3116_write_reg(port->serial, UART_MCR, priv->mcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) mutex_unlock(&priv->hw_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) static void ark3116_break_ctl(struct tty_struct *tty, int break_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) struct usb_serial_port *port = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) struct ark3116_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) /* LCR is also used for other things: protect access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) mutex_lock(&priv->hw_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) if (break_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) priv->lcr |= UART_LCR_SBC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) priv->lcr &= ~UART_LCR_SBC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) ark3116_write_reg(port->serial, UART_LCR, priv->lcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) mutex_unlock(&priv->hw_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) static void ark3116_update_msr(struct usb_serial_port *port, __u8 msr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) struct ark3116_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) spin_lock_irqsave(&priv->status_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) priv->msr = msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) spin_unlock_irqrestore(&priv->status_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (msr & UART_MSR_ANY_DELTA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) /* update input line counters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (msr & UART_MSR_DCTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) port->icount.cts++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) if (msr & UART_MSR_DDSR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) port->icount.dsr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (msr & UART_MSR_DDCD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) port->icount.dcd++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (msr & UART_MSR_TERI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) port->icount.rng++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) wake_up_interruptible(&port->port.delta_msr_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) static void ark3116_update_lsr(struct usb_serial_port *port, __u8 lsr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) struct ark3116_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) spin_lock_irqsave(&priv->status_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) /* combine bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) priv->lsr |= lsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) spin_unlock_irqrestore(&priv->status_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) if (lsr&UART_LSR_BRK_ERROR_BITS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) if (lsr & UART_LSR_BI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) port->icount.brk++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) if (lsr & UART_LSR_FE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) port->icount.frame++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) if (lsr & UART_LSR_PE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) port->icount.parity++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (lsr & UART_LSR_OE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) port->icount.overrun++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) static void ark3116_read_int_callback(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) struct usb_serial_port *port = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) int status = urb->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) const __u8 *data = urb->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) switch (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) case -ECONNRESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) case -ENOENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) case -ESHUTDOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) /* this urb is terminated, clean up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) dev_dbg(&port->dev, "%s - urb shutting down with status: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) dev_dbg(&port->dev, "%s - nonzero urb status received: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) case 0: /* success */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) /* discovered this by trail and error... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) if ((urb->actual_length == 4) && (data[0] == 0xe8)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) const __u8 id = data[1]&UART_IIR_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) dev_dbg(&port->dev, "%s: iir=%02x\n", __func__, data[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) if (id == UART_IIR_MSI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) dev_dbg(&port->dev, "%s: msr=%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) __func__, data[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) ark3116_update_msr(port, data[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) } else if (id == UART_IIR_RLSI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) dev_dbg(&port->dev, "%s: lsr=%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) __func__, data[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) ark3116_update_lsr(port, data[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) * Not sure what this data meant...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) usb_serial_debug_data(&port->dev, __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) urb->actual_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) urb->transfer_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) result = usb_submit_urb(urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) dev_err(&port->dev, "failed to resubmit interrupt urb: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) /* Data comes in via the bulk (data) URB, errors/interrupts via the int URB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) * This means that we cannot be sure which data byte has an associated error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) * condition, so we report an error for all data in the next bulk read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) * Actually, there might even be a window between the bulk data leaving the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) * ark and reading/resetting the lsr in the read_bulk_callback where an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) * interrupt for the next data block could come in.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) * Without somekind of ordering on the ark, we would have to report the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) * error for the next block of data as well...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) * For now, let's pretend this can't happen.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) static void ark3116_process_read_urb(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) struct usb_serial_port *port = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) struct ark3116_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) unsigned char *data = urb->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) char tty_flag = TTY_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) __u32 lsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) /* update line status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) spin_lock_irqsave(&priv->status_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) lsr = priv->lsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) priv->lsr &= ~UART_LSR_BRK_ERROR_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) spin_unlock_irqrestore(&priv->status_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) if (!urb->actual_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) if (lsr & UART_LSR_BRK_ERROR_BITS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if (lsr & UART_LSR_BI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) tty_flag = TTY_BREAK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) else if (lsr & UART_LSR_PE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) tty_flag = TTY_PARITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) else if (lsr & UART_LSR_FE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) tty_flag = TTY_FRAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) /* overrun is special, not associated with a char */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) if (lsr & UART_LSR_OE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) tty_insert_flip_char(&port->port, 0, TTY_OVERRUN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) tty_insert_flip_string_fixed_flag(&port->port, data, tty_flag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) urb->actual_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) tty_flip_buffer_push(&port->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) static struct usb_serial_driver ark3116_device = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) .name = "ark3116",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) .id_table = id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) .num_ports = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) .num_bulk_in = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) .num_bulk_out = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) .num_interrupt_in = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) .port_probe = ark3116_port_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) .port_remove = ark3116_port_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) .set_termios = ark3116_set_termios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) .get_serial = ark3116_get_serial_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) .tiocmget = ark3116_tiocmget,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) .tiocmset = ark3116_tiocmset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) .tiocmiwait = usb_serial_generic_tiocmiwait,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) .get_icount = usb_serial_generic_get_icount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) .open = ark3116_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) .close = ark3116_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) .break_ctl = ark3116_break_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) .read_int_callback = ark3116_read_int_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) .process_read_urb = ark3116_process_read_urb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) static struct usb_serial_driver * const serial_drivers[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) &ark3116_device, NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) module_usb_serial_driver(serial_drivers, id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) MODULE_AUTHOR(DRIVER_AUTHOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) MODULE_DESCRIPTION(DRIVER_DESC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) * The following describes what I learned from studying the old
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) * ark3116.c driver, disassembling the windows driver, and some lucky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) * guesses. Since I do not have any datasheet or other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) * documentation, inaccuracies are almost guaranteed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) * Some specs for the ARK3116 can be found here:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) * http://web.archive.org/web/20060318000438/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) * www.arkmicro.com/en/products/view.php?id=10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) * On that page, 2 GPIO pins are mentioned: I assume these are the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) * OUT1 and OUT2 pins of the UART, so I added support for those
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) * through the MCR. Since the pins are not available on my hardware,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) * I could not verify this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) * Also, it states there is "on-chip hardware flow control". I have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) * discovered how to enable that. Unfortunately, I do not know how to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) * enable XON/XOFF (software) flow control, which would need support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) * from the chip as well to work. Because of the wording on the web
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) * page there is a real possibility the chip simply does not support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) * software flow control.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) * I got my ark3116 as part of a mobile phone adapter cable. On the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) * PCB, the following numbered contacts are present:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) * 1:- +5V
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) * 2:o DTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) * 3:i RX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) * 4:i DCD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) * 5:o RTS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) * 6:o TX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) * 7:i RI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) * 8:i DSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) * 10:- 0V
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) * 11:i CTS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) * On my chip, all signals seem to be 3.3V, but 5V tolerant. But that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) * may be different for the one you have ;-).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) * The windows driver limits the registers to 0-F, so I assume there
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) * are actually 16 present on the device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) * On an UART interrupt, 4 bytes of data come in on the interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) * endpoint. The bytes are 0xe8 IIR LSR MSR.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) * The baudrate seems to be generated from the 12MHz crystal, using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) * 4-times subsampling. So quot=12e6/(4*baud). Also see description
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) * of register E.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) * Registers 0-7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) * These seem to be the same as for a regular 16450. The FCR is set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) * to UART_FCR_DMA_SELECT (0x8), I guess to enable transfers between
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) * the UART and the USB bridge/DMA engine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) * Register 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) * By trial and error, I found out that bit 0 enables hardware CTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) * stopping TX when CTS is +5V. Bit 1 does the same for RTS, making
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) * RTS +5V when the 3116 cannot transfer the data to the USB bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) * (verified by disabling the reading URB). Note that as far as I can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) * tell, the windows driver does NOT use this, so there might be some
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) * hardware bug or something.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) * According to a patch provided here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) * (http://lkml.org/lkml/2009/7/26/56), the ARK3116 can also be used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) * as an IrDA dongle. Since I do not have such a thing, I could not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) * investigate that aspect. However, I can speculate ;-).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) * - IrDA encodes data differently than RS232. Most likely, one of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) * the bits in registers 9..E enables the IR ENDEC (encoder/decoder).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) * - Depending on the IR transceiver, the input and output need to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) * inverted, so there are probably bits for that as well.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) * - IrDA is half-duplex, so there should be a bit for selecting that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) * This still leaves at least two registers unaccounted for. Perhaps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) * The chip can do XON/XOFF or CRC in HW?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) * Register 9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) * Set to 0x00 for IrDA, when the baudrate is initialised.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) * Register A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) * Set to 0x01 for IrDA, at init.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) * Register B:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) * Set to 0x01 for IrDA, 0x00 for RS232, at init.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) * Register C:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) * Set to 00 for IrDA, at init.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) * Register D:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) * Set to 0x41 for IrDA, at init.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) * Register E:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) * Somekind of baudrate override. The windows driver seems to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) * this to 0x00 for normal baudrates, 0x01 for 460800, 0x02 for 921600.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) * Since 460800 and 921600 cannot be obtained by dividing 3MHz by an integer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) * it could be somekind of subdivisor thingy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) * However,it does not seem to do anything: selecting 921600 (divisor 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) * reg E=2), still gets 1 MHz. I also checked if registers 9, C or F would
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) * work, but they don't.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) * Register F: unknown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) */