^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) * KLSI KL5KUSB105 chip RS232 converter driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2010 Johan Hovold <jhovold@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2001 Utz-Uwe Haus <haus@uuhaus.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * All information about the device was acquired using SniffUSB ans snoopUSB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * on Windows98.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * It was written out of frustration with the PalmConnect USB Serial adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * sold by Palm Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Neither Palm, nor their contractor (MCCI) or their supplier (KLSI) provided
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * information that was not already available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * It seems that KLSI bought some silicon-design information from ScanLogic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * whose SL11R processor is at the core of the KL5KUSB chipset from KLSI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * KLSI has firmware available for their devices; it is probable that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * firmware differs from that used by KLSI in their products. If you have an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * original KLSI device and can provide some information on it, I would be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * most interested in adding support for it here. If you have any information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * on the protocol used (or find errors in my reverse-engineered stuff), please
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * let me know.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * The code was only tested with a PalmConnect USB adapter; if you
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * are adventurous, try it with any KLSI-based device and let me know how it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * breaks so that I can fix it!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /* TODO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * check modem line signals
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * implement handshaking or decide that we do not support it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/tty.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/tty_driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/tty_flip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <asm/unaligned.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/usb/serial.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include "kl5kusb105.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define DRIVER_AUTHOR "Utz-Uwe Haus <haus@uuhaus.de>, Johan Hovold <jhovold@gmail.com>"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define DRIVER_DESC "KLSI KL5KUSB105 chipset USB->Serial Converter driver"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * Function prototypes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static int klsi_105_port_probe(struct usb_serial_port *port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static int klsi_105_port_remove(struct usb_serial_port *port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static void klsi_105_close(struct usb_serial_port *port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static void klsi_105_set_termios(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct usb_serial_port *port, struct ktermios *old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static int klsi_105_tiocmget(struct tty_struct *tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static void klsi_105_process_read_urb(struct urb *urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static int klsi_105_prepare_write_buffer(struct usb_serial_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) void *dest, size_t size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * All of the device info needed for the KLSI converters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static const struct usb_device_id id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) { USB_DEVICE(PALMCONNECT_VID, PALMCONNECT_PID) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) { } /* Terminating entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) MODULE_DEVICE_TABLE(usb, id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) static struct usb_serial_driver kl5kusb105d_device = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) .name = "kl5kusb105d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) .description = "KL5KUSB105D / PalmConnect",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) .id_table = id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) .num_ports = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) .bulk_out_size = 64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) .open = klsi_105_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) .close = klsi_105_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) .set_termios = klsi_105_set_termios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) .tiocmget = klsi_105_tiocmget,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) .port_probe = klsi_105_port_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) .port_remove = klsi_105_port_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) .throttle = usb_serial_generic_throttle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) .unthrottle = usb_serial_generic_unthrottle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) .process_read_urb = klsi_105_process_read_urb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) .prepare_write_buffer = klsi_105_prepare_write_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static struct usb_serial_driver * const serial_drivers[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) &kl5kusb105d_device, NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct klsi_105_port_settings {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) u8 pktlen; /* always 5, it seems */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) u8 baudrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) u8 databits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) u8 unknown1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) u8 unknown2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct klsi_105_private {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct klsi_105_port_settings cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) unsigned long line_state; /* modem line settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) spinlock_t lock;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * Handle vendor specific USB requests
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define KLSI_TIMEOUT 5000 /* default urb timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static int klsi_105_chg_port_settings(struct usb_serial_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct klsi_105_port_settings *settings)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) rc = usb_control_msg(port->serial->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) usb_sndctrlpipe(port->serial->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) KL5KUSB105A_SIO_SET_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_INTERFACE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 0, /* value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 0, /* index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) settings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) sizeof(struct klsi_105_port_settings),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) KLSI_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) dev_err(&port->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) "Change port settings failed (error = %d)\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) dev_dbg(&port->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) "pktlen %u, baudrate 0x%02x, databits %u, u1 %u, u2 %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) settings->pktlen, settings->baudrate, settings->databits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) settings->unknown1, settings->unknown2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) /* translate a 16-bit status value from the device to linux's TIO bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) static unsigned long klsi_105_status2linestate(const __u16 status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) unsigned long res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) res = ((status & KL5KUSB105A_DSR) ? TIOCM_DSR : 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) | ((status & KL5KUSB105A_CTS) ? TIOCM_CTS : 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return res;
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * Read line control via vendor command and return result through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) * *line_state_p
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /* It seems that the status buffer has always only 2 bytes length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define KLSI_STATUSBUF_LEN 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) static int klsi_105_get_line_state(struct usb_serial_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) unsigned long *line_state_p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) u8 *status_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) __u16 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) status_buf = kmalloc(KLSI_STATUSBUF_LEN, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (!status_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) status_buf[0] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) status_buf[1] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) rc = usb_control_msg(port->serial->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) usb_rcvctrlpipe(port->serial->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) KL5KUSB105A_SIO_POLL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) USB_TYPE_VENDOR | USB_DIR_IN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 0, /* value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 0, /* index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) status_buf, KLSI_STATUSBUF_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 10000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (rc != KLSI_STATUSBUF_LEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) dev_err(&port->dev, "reading line status failed: %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (rc >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) status = get_unaligned_le16(status_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) dev_dbg(&port->dev, "read status %02x %02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) status_buf[0], status_buf[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) *line_state_p = klsi_105_status2linestate(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) kfree(status_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * Driver's tty interface functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) static int klsi_105_port_probe(struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) struct klsi_105_private *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) priv = kmalloc(sizeof(*priv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (!priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) /* set initial values for control structures */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) priv->cfg.pktlen = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) priv->cfg.baudrate = kl5kusb105a_sio_b9600;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) priv->cfg.databits = kl5kusb105a_dtb_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) priv->cfg.unknown1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) priv->cfg.unknown2 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) priv->line_state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) spin_lock_init(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) usb_set_serial_port_data(port, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) static int klsi_105_port_remove(struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) struct klsi_105_private *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) kfree(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) struct klsi_105_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) unsigned long line_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) struct klsi_105_port_settings *cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) /* Do a defined restart:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * Set up sane default baud rate and send the 'READ_ON'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * vendor command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * FIXME: set modem line control (how?)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * Then read the modem line control and store values in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * priv->line_state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) cfg = kmalloc(sizeof(*cfg), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (!cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) cfg->pktlen = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) cfg->baudrate = kl5kusb105a_sio_b9600;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) cfg->databits = kl5kusb105a_dtb_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) cfg->unknown1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) cfg->unknown2 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) klsi_105_chg_port_settings(port, cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) priv->cfg.pktlen = cfg->pktlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) priv->cfg.baudrate = cfg->baudrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) priv->cfg.databits = cfg->databits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) priv->cfg.unknown1 = cfg->unknown1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) priv->cfg.unknown2 = cfg->unknown2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) kfree(cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /* READ_ON and urb submission */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) rc = usb_serial_generic_open(tty, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) rc = usb_control_msg(port->serial->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) usb_sndctrlpipe(port->serial->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) KL5KUSB105A_SIO_CONFIGURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) USB_TYPE_VENDOR|USB_DIR_OUT|USB_RECIP_INTERFACE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) KL5KUSB105A_SIO_CONFIGURE_READ_ON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 0, /* index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) KLSI_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) dev_err(&port->dev, "Enabling read failed (error = %d)\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) retval = rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) goto err_generic_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) dev_dbg(&port->dev, "%s - enabled reading\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) rc = klsi_105_get_line_state(port, &line_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) retval = rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) goto err_disable_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) priv->line_state = line_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) dev_dbg(&port->dev, "%s - read line state 0x%lx\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) line_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) err_disable_read:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) usb_control_msg(port->serial->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) usb_sndctrlpipe(port->serial->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) KL5KUSB105A_SIO_CONFIGURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) USB_TYPE_VENDOR | USB_DIR_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) KL5KUSB105A_SIO_CONFIGURE_READ_OFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 0, /* index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) KLSI_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) err_generic_close:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) usb_serial_generic_close(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) static void klsi_105_close(struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) /* send READ_OFF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) rc = usb_control_msg(port->serial->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) usb_sndctrlpipe(port->serial->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) KL5KUSB105A_SIO_CONFIGURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) USB_TYPE_VENDOR | USB_DIR_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) KL5KUSB105A_SIO_CONFIGURE_READ_OFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 0, /* index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) KLSI_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) dev_err(&port->dev, "failed to disable read: %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) /* shutdown our bulk reads and writes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) usb_serial_generic_close(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) /* We need to write a complete 64-byte data block and encode the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) * number actually sent in the first double-byte, LSB-order. That
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) * leaves at most 62 bytes of payload.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) #define KLSI_HDR_LEN 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) static int klsi_105_prepare_write_buffer(struct usb_serial_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) void *dest, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) unsigned char *buf = dest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) count = kfifo_out_locked(&port->write_fifo, buf + KLSI_HDR_LEN, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) &port->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) put_unaligned_le16(count, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) return count + KLSI_HDR_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) /* The data received is preceded by a length double-byte in LSB-first order.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) static void klsi_105_process_read_urb(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) struct usb_serial_port *port = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) unsigned char *data = urb->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) unsigned len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) /* empty urbs seem to happen, we ignore them */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (!urb->actual_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (urb->actual_length <= KLSI_HDR_LEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) dev_dbg(&port->dev, "%s - malformed packet\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) len = get_unaligned_le16(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if (len > urb->actual_length - KLSI_HDR_LEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) dev_dbg(&port->dev, "%s - packet length mismatch\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) len = urb->actual_length - KLSI_HDR_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) tty_insert_flip_string(&port->port, data + KLSI_HDR_LEN, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) tty_flip_buffer_push(&port->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) static void klsi_105_set_termios(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) struct usb_serial_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) struct ktermios *old_termios)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) struct klsi_105_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) struct device *dev = &port->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) unsigned int iflag = tty->termios.c_iflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) unsigned int old_iflag = old_termios->c_iflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) unsigned int cflag = tty->termios.c_cflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) unsigned int old_cflag = old_termios->c_cflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) struct klsi_105_port_settings *cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) speed_t baud;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) cfg = kmalloc(sizeof(*cfg), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (!cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) /* lock while we are modifying the settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) * Update baud rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) baud = tty_get_baud_rate(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) switch (baud) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) case 0: /* handled below */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) case 1200:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) priv->cfg.baudrate = kl5kusb105a_sio_b1200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) case 2400:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) priv->cfg.baudrate = kl5kusb105a_sio_b2400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) case 4800:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) priv->cfg.baudrate = kl5kusb105a_sio_b4800;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) case 9600:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) priv->cfg.baudrate = kl5kusb105a_sio_b9600;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) case 19200:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) priv->cfg.baudrate = kl5kusb105a_sio_b19200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) case 38400:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) priv->cfg.baudrate = kl5kusb105a_sio_b38400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) case 57600:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) priv->cfg.baudrate = kl5kusb105a_sio_b57600;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) case 115200:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) priv->cfg.baudrate = kl5kusb105a_sio_b115200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) dev_dbg(dev, "unsupported baudrate, using 9600\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) priv->cfg.baudrate = kl5kusb105a_sio_b9600;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) baud = 9600;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) * FIXME: implement B0 handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) * Maybe this should be simulated by sending read disable and read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) * enable messages?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) tty_encode_baud_rate(tty, baud, baud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if ((cflag & CSIZE) != (old_cflag & CSIZE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) /* set the number of data bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) switch (cflag & CSIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) case CS5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) dev_dbg(dev, "%s - 5 bits/byte not supported\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) case CS6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) dev_dbg(dev, "%s - 6 bits/byte not supported\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) case CS7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) priv->cfg.databits = kl5kusb105a_dtb_7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) case CS8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) priv->cfg.databits = kl5kusb105a_dtb_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) dev_err(dev, "CSIZE was not CS5-CS8, using default of 8\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) priv->cfg.databits = kl5kusb105a_dtb_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) * Update line control register (LCR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) || (cflag & CSTOPB) != (old_cflag & CSTOPB)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) /* Not currently supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) tty->termios.c_cflag &= ~(PARENB|PARODD|CSTOPB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) * Set flow control: well, I do not really now how to handle DTR/RTS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) * Just do what we have seen with SniffUSB on Win98.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if ((iflag & IXOFF) != (old_iflag & IXOFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) || (iflag & IXON) != (old_iflag & IXON)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) || (cflag & CRTSCTS) != (old_cflag & CRTSCTS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) /* Not currently supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) tty->termios.c_cflag &= ~CRTSCTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) memcpy(cfg, &priv->cfg, sizeof(*cfg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) /* now commit changes to device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) klsi_105_chg_port_settings(port, cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) kfree(cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) static int klsi_105_tiocmget(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) struct usb_serial_port *port = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) struct klsi_105_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) unsigned long line_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) rc = klsi_105_get_line_state(port, &line_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) dev_err(&port->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) "Reading line control failed (error = %d)\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) /* better return value? EAGAIN? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) priv->line_state = line_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) dev_dbg(&port->dev, "%s - read line state 0x%lx\n", __func__, line_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) return (int)line_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) module_usb_serial_driver(serial_drivers, id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) MODULE_AUTHOR(DRIVER_AUTHOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) MODULE_DESCRIPTION(DRIVER_DESC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) MODULE_LICENSE("GPL");