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