1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Fintek F81232 USB to serial adaptor driver 4 * 5 * Copyright (C) 2012 Greg Kroah-Hartman (gregkh@linuxfoundation.org) 6 * Copyright (C) 2012 Linux Foundation 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License version 2 as published by 10 * the Free Software Foundation. 11 * 12 */ 13 14 #include <linux/kernel.h> 15 #include <linux/errno.h> 16 #include <linux/slab.h> 17 #include <linux/tty.h> 18 #include <linux/tty_driver.h> 19 #include <linux/tty_flip.h> 20 #include <linux/serial.h> 21 #include <linux/module.h> 22 #include <linux/moduleparam.h> 23 #include <linux/mutex.h> 24 #include <linux/uaccess.h> 25 #include <linux/usb.h> 26 #include <linux/usb/serial.h> 27 #include <linux/serial_reg.h> 28 29 static const struct usb_device_id id_table[] = { 30 { USB_DEVICE(0x1934, 0x0706) }, 31 { } /* Terminating entry */ 32 }; 33 MODULE_DEVICE_TABLE(usb, id_table); 34 35 /* Maximum baudrate for F81232 */ 36 #define F81232_MAX_BAUDRATE 115200 37 38 /* USB Control EP parameter */ 39 #define F81232_REGISTER_REQUEST 0xa0 40 #define F81232_GET_REGISTER 0xc0 41 #define F81232_SET_REGISTER 0x40 42 43 #define SERIAL_BASE_ADDRESS 0x0120 44 #define RECEIVE_BUFFER_REGISTER (0x00 + SERIAL_BASE_ADDRESS) 45 #define INTERRUPT_ENABLE_REGISTER (0x01 + SERIAL_BASE_ADDRESS) 46 #define FIFO_CONTROL_REGISTER (0x02 + SERIAL_BASE_ADDRESS) 47 #define LINE_CONTROL_REGISTER (0x03 + SERIAL_BASE_ADDRESS) 48 #define MODEM_CONTROL_REGISTER (0x04 + SERIAL_BASE_ADDRESS) 49 #define MODEM_STATUS_REGISTER (0x06 + SERIAL_BASE_ADDRESS) 50 51 struct f81232_private { 52 struct mutex lock; 53 u8 modem_control; 54 u8 modem_status; 55 struct work_struct interrupt_work; 56 struct usb_serial_port *port; 57 }; 58 59 static int calc_baud_divisor(speed_t baudrate) 60 { 61 return DIV_ROUND_CLOSEST(F81232_MAX_BAUDRATE, baudrate); 62 } 63 64 static int f81232_get_register(struct usb_serial_port *port, u16 reg, u8 *val) 65 { 66 int status; 67 u8 *tmp; 68 struct usb_device *dev = port->serial->dev; 69 70 tmp = kmalloc(sizeof(*val), GFP_KERNEL); 71 if (!tmp) 72 return -ENOMEM; 73 74 status = usb_control_msg(dev, 75 usb_rcvctrlpipe(dev, 0), 76 F81232_REGISTER_REQUEST, 77 F81232_GET_REGISTER, 78 reg, 79 0, 80 tmp, 81 sizeof(*val), 82 USB_CTRL_GET_TIMEOUT); 83 if (status != sizeof(*val)) { 84 dev_err(&port->dev, "%s failed status: %d\n", __func__, status); 85 86 if (status < 0) 87 status = usb_translate_errors(status); 88 else 89 status = -EIO; 90 } else { 91 status = 0; 92 *val = *tmp; 93 } 94 95 kfree(tmp); 96 return status; 97 } 98 99 static int f81232_set_register(struct usb_serial_port *port, u16 reg, u8 val) 100 { 101 int status; 102 u8 *tmp; 103 struct usb_device *dev = port->serial->dev; 104 105 tmp = kmalloc(sizeof(val), GFP_KERNEL); 106 if (!tmp) 107 return -ENOMEM; 108 109 *tmp = val; 110 111 status = usb_control_msg(dev, 112 usb_sndctrlpipe(dev, 0), 113 F81232_REGISTER_REQUEST, 114 F81232_SET_REGISTER, 115 reg, 116 0, 117 tmp, 118 sizeof(val), 119 USB_CTRL_SET_TIMEOUT); 120 if (status != sizeof(val)) { 121 dev_err(&port->dev, "%s failed status: %d\n", __func__, status); 122 123 if (status < 0) 124 status = usb_translate_errors(status); 125 else 126 status = -EIO; 127 } else { 128 status = 0; 129 } 130 131 kfree(tmp); 132 return status; 133 } 134 135 static void f81232_read_msr(struct usb_serial_port *port) 136 { 137 int status; 138 u8 current_msr; 139 struct tty_struct *tty; 140 struct f81232_private *priv = usb_get_serial_port_data(port); 141 142 mutex_lock(&priv->lock); 143 status = f81232_get_register(port, MODEM_STATUS_REGISTER, 144 ¤t_msr); 145 if (status) { 146 dev_err(&port->dev, "%s fail, status: %d\n", __func__, status); 147 mutex_unlock(&priv->lock); 148 return; 149 } 150 151 if (!(current_msr & UART_MSR_ANY_DELTA)) { 152 mutex_unlock(&priv->lock); 153 return; 154 } 155 156 priv->modem_status = current_msr; 157 158 if (current_msr & UART_MSR_DCTS) 159 port->icount.cts++; 160 if (current_msr & UART_MSR_DDSR) 161 port->icount.dsr++; 162 if (current_msr & UART_MSR_TERI) 163 port->icount.rng++; 164 if (current_msr & UART_MSR_DDCD) { 165 port->icount.dcd++; 166 tty = tty_port_tty_get(&port->port); 167 if (tty) { 168 usb_serial_handle_dcd_change(port, tty, 169 current_msr & UART_MSR_DCD); 170 171 tty_kref_put(tty); 172 } 173 } 174 175 wake_up_interruptible(&port->port.delta_msr_wait); 176 mutex_unlock(&priv->lock); 177 } 178 179 static int f81232_set_mctrl(struct usb_serial_port *port, 180 unsigned int set, unsigned int clear) 181 { 182 u8 val; 183 int status; 184 struct f81232_private *priv = usb_get_serial_port_data(port); 185 186 if (((set | clear) & (TIOCM_DTR | TIOCM_RTS)) == 0) 187 return 0; /* no change */ 188 189 /* 'set' takes precedence over 'clear' */ 190 clear &= ~set; 191 192 /* force enable interrupt with OUT2 */ 193 mutex_lock(&priv->lock); 194 val = UART_MCR_OUT2 | priv->modem_control; 195 196 if (clear & TIOCM_DTR) 197 val &= ~UART_MCR_DTR; 198 199 if (clear & TIOCM_RTS) 200 val &= ~UART_MCR_RTS; 201 202 if (set & TIOCM_DTR) 203 val |= UART_MCR_DTR; 204 205 if (set & TIOCM_RTS) 206 val |= UART_MCR_RTS; 207 208 dev_dbg(&port->dev, "%s new:%02x old:%02x\n", __func__, 209 val, priv->modem_control); 210 211 status = f81232_set_register(port, MODEM_CONTROL_REGISTER, val); 212 if (status) { 213 dev_err(&port->dev, "%s set MCR status < 0\n", __func__); 214 mutex_unlock(&priv->lock); 215 return status; 216 } 217 218 priv->modem_control = val; 219 mutex_unlock(&priv->lock); 220 221 return 0; 222 } 223 224 static void f81232_update_line_status(struct usb_serial_port *port, 225 unsigned char *data, 226 size_t actual_length) 227 { 228 struct f81232_private *priv = usb_get_serial_port_data(port); 229 230 if (!actual_length) 231 return; 232 233 switch (data[0] & 0x07) { 234 case 0x00: /* msr change */ 235 dev_dbg(&port->dev, "IIR: MSR Change: %02x\n", data[0]); 236 schedule_work(&priv->interrupt_work); 237 break; 238 case 0x02: /* tx-empty */ 239 break; 240 case 0x04: /* rx data available */ 241 break; 242 case 0x06: /* lsr change */ 243 /* we can forget it. the LSR will read from bulk-in */ 244 dev_dbg(&port->dev, "IIR: LSR Change: %02x\n", data[0]); 245 break; 246 } 247 } 248 249 static void f81232_read_int_callback(struct urb *urb) 250 { 251 struct usb_serial_port *port = urb->context; 252 unsigned char *data = urb->transfer_buffer; 253 unsigned int actual_length = urb->actual_length; 254 int status = urb->status; 255 int retval; 256 257 switch (status) { 258 case 0: 259 /* success */ 260 break; 261 case -ECONNRESET: 262 case -ENOENT: 263 case -ESHUTDOWN: 264 /* this urb is terminated, clean up */ 265 dev_dbg(&port->dev, "%s - urb shutting down with status: %d\n", 266 __func__, status); 267 return; 268 default: 269 dev_dbg(&port->dev, "%s - nonzero urb status received: %d\n", 270 __func__, status); 271 goto exit; 272 } 273 274 usb_serial_debug_data(&port->dev, __func__, 275 urb->actual_length, urb->transfer_buffer); 276 277 f81232_update_line_status(port, data, actual_length); 278 279 exit: 280 retval = usb_submit_urb(urb, GFP_ATOMIC); 281 if (retval) 282 dev_err(&urb->dev->dev, 283 "%s - usb_submit_urb failed with result %d\n", 284 __func__, retval); 285 } 286 287 static void f81232_process_read_urb(struct urb *urb) 288 { 289 struct usb_serial_port *port = urb->context; 290 unsigned char *data = urb->transfer_buffer; 291 char tty_flag; 292 unsigned int i; 293 u8 lsr; 294 295 /* 296 * When opening the port we get a 1-byte packet with the current LSR, 297 * which we discard. 298 */ 299 if ((urb->actual_length < 2) || (urb->actual_length % 2)) 300 return; 301 302 /* bulk-in data: [LSR(1Byte)+DATA(1Byte)][LSR(1Byte)+DATA(1Byte)]... */ 303 304 for (i = 0; i < urb->actual_length; i += 2) { 305 tty_flag = TTY_NORMAL; 306 lsr = data[i]; 307 308 if (lsr & UART_LSR_BRK_ERROR_BITS) { 309 if (lsr & UART_LSR_BI) { 310 tty_flag = TTY_BREAK; 311 port->icount.brk++; 312 usb_serial_handle_break(port); 313 } else if (lsr & UART_LSR_PE) { 314 tty_flag = TTY_PARITY; 315 port->icount.parity++; 316 } else if (lsr & UART_LSR_FE) { 317 tty_flag = TTY_FRAME; 318 port->icount.frame++; 319 } 320 321 if (lsr & UART_LSR_OE) { 322 port->icount.overrun++; 323 tty_insert_flip_char(&port->port, 0, 324 TTY_OVERRUN); 325 } 326 } 327 328 if (port->port.console && port->sysrq) { 329 if (usb_serial_handle_sysrq_char(port, data[i + 1])) 330 continue; 331 } 332 333 tty_insert_flip_char(&port->port, data[i + 1], tty_flag); 334 } 335 336 tty_flip_buffer_push(&port->port); 337 } 338 339 static void f81232_break_ctl(struct tty_struct *tty, int break_state) 340 { 341 /* FIXME - Stubbed out for now */ 342 343 /* 344 * break_state = -1 to turn on break, and 0 to turn off break 345 * see drivers/char/tty_io.c to see it used. 346 * last_set_data_urb_value NEVER has the break bit set in it. 347 */ 348 } 349 350 static void f81232_set_baudrate(struct usb_serial_port *port, speed_t baudrate) 351 { 352 u8 lcr; 353 int divisor; 354 int status = 0; 355 356 divisor = calc_baud_divisor(baudrate); 357 358 status = f81232_get_register(port, LINE_CONTROL_REGISTER, 359 &lcr); /* get LCR */ 360 if (status) { 361 dev_err(&port->dev, "%s failed to get LCR: %d\n", 362 __func__, status); 363 return; 364 } 365 366 status = f81232_set_register(port, LINE_CONTROL_REGISTER, 367 lcr | UART_LCR_DLAB); /* Enable DLAB */ 368 if (status) { 369 dev_err(&port->dev, "%s failed to set DLAB: %d\n", 370 __func__, status); 371 return; 372 } 373 374 status = f81232_set_register(port, RECEIVE_BUFFER_REGISTER, 375 divisor & 0x00ff); /* low */ 376 if (status) { 377 dev_err(&port->dev, "%s failed to set baudrate MSB: %d\n", 378 __func__, status); 379 goto reapply_lcr; 380 } 381 382 status = f81232_set_register(port, INTERRUPT_ENABLE_REGISTER, 383 (divisor & 0xff00) >> 8); /* high */ 384 if (status) { 385 dev_err(&port->dev, "%s failed to set baudrate LSB: %d\n", 386 __func__, status); 387 } 388 389 reapply_lcr: 390 status = f81232_set_register(port, LINE_CONTROL_REGISTER, 391 lcr & ~UART_LCR_DLAB); 392 if (status) { 393 dev_err(&port->dev, "%s failed to set DLAB: %d\n", 394 __func__, status); 395 } 396 } 397 398 static int f81232_port_enable(struct usb_serial_port *port) 399 { 400 u8 val; 401 int status; 402 403 /* fifo on, trigger8, clear TX/RX*/ 404 val = UART_FCR_TRIGGER_8 | UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | 405 UART_FCR_CLEAR_XMIT; 406 407 status = f81232_set_register(port, FIFO_CONTROL_REGISTER, val); 408 if (status) { 409 dev_err(&port->dev, "%s failed to set FCR: %d\n", 410 __func__, status); 411 return status; 412 } 413 414 /* MSR Interrupt only, LSR will read from Bulk-in odd byte */ 415 status = f81232_set_register(port, INTERRUPT_ENABLE_REGISTER, 416 UART_IER_MSI); 417 if (status) { 418 dev_err(&port->dev, "%s failed to set IER: %d\n", 419 __func__, status); 420 return status; 421 } 422 423 return 0; 424 } 425 426 static int f81232_port_disable(struct usb_serial_port *port) 427 { 428 int status; 429 430 status = f81232_set_register(port, INTERRUPT_ENABLE_REGISTER, 0); 431 if (status) { 432 dev_err(&port->dev, "%s failed to set IER: %d\n", 433 __func__, status); 434 return status; 435 } 436 437 return 0; 438 } 439 440 static void f81232_set_termios(struct tty_struct *tty, 441 struct usb_serial_port *port, struct ktermios *old_termios) 442 { 443 u8 new_lcr = 0; 444 int status = 0; 445 speed_t baudrate; 446 447 /* Don't change anything if nothing has changed */ 448 if (old_termios && !tty_termios_hw_change(&tty->termios, old_termios)) 449 return; 450 451 if (C_BAUD(tty) == B0) 452 f81232_set_mctrl(port, 0, TIOCM_DTR | TIOCM_RTS); 453 else if (old_termios && (old_termios->c_cflag & CBAUD) == B0) 454 f81232_set_mctrl(port, TIOCM_DTR | TIOCM_RTS, 0); 455 456 baudrate = tty_get_baud_rate(tty); 457 if (baudrate > 0) { 458 if (baudrate > F81232_MAX_BAUDRATE) { 459 baudrate = F81232_MAX_BAUDRATE; 460 tty_encode_baud_rate(tty, baudrate, baudrate); 461 } 462 f81232_set_baudrate(port, baudrate); 463 } 464 465 if (C_PARENB(tty)) { 466 new_lcr |= UART_LCR_PARITY; 467 468 if (!C_PARODD(tty)) 469 new_lcr |= UART_LCR_EPAR; 470 471 if (C_CMSPAR(tty)) 472 new_lcr |= UART_LCR_SPAR; 473 } 474 475 if (C_CSTOPB(tty)) 476 new_lcr |= UART_LCR_STOP; 477 478 switch (C_CSIZE(tty)) { 479 case CS5: 480 new_lcr |= UART_LCR_WLEN5; 481 break; 482 case CS6: 483 new_lcr |= UART_LCR_WLEN6; 484 break; 485 case CS7: 486 new_lcr |= UART_LCR_WLEN7; 487 break; 488 default: 489 case CS8: 490 new_lcr |= UART_LCR_WLEN8; 491 break; 492 } 493 494 status = f81232_set_register(port, LINE_CONTROL_REGISTER, new_lcr); 495 if (status) { 496 dev_err(&port->dev, "%s failed to set LCR: %d\n", 497 __func__, status); 498 } 499 } 500 501 static int f81232_tiocmget(struct tty_struct *tty) 502 { 503 int r; 504 struct usb_serial_port *port = tty->driver_data; 505 struct f81232_private *port_priv = usb_get_serial_port_data(port); 506 u8 mcr, msr; 507 508 /* force get current MSR changed state */ 509 f81232_read_msr(port); 510 511 mutex_lock(&port_priv->lock); 512 mcr = port_priv->modem_control; 513 msr = port_priv->modem_status; 514 mutex_unlock(&port_priv->lock); 515 516 r = (mcr & UART_MCR_DTR ? TIOCM_DTR : 0) | 517 (mcr & UART_MCR_RTS ? TIOCM_RTS : 0) | 518 (msr & UART_MSR_CTS ? TIOCM_CTS : 0) | 519 (msr & UART_MSR_DCD ? TIOCM_CAR : 0) | 520 (msr & UART_MSR_RI ? TIOCM_RI : 0) | 521 (msr & UART_MSR_DSR ? TIOCM_DSR : 0); 522 523 return r; 524 } 525 526 static int f81232_tiocmset(struct tty_struct *tty, 527 unsigned int set, unsigned int clear) 528 { 529 struct usb_serial_port *port = tty->driver_data; 530 531 return f81232_set_mctrl(port, set, clear); 532 } 533 534 static int f81232_open(struct tty_struct *tty, struct usb_serial_port *port) 535 { 536 int result; 537 538 result = f81232_port_enable(port); 539 if (result) 540 return result; 541 542 /* Setup termios */ 543 if (tty) 544 f81232_set_termios(tty, port, NULL); 545 546 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); 547 if (result) { 548 dev_err(&port->dev, "%s - failed submitting interrupt urb," 549 " error %d\n", __func__, result); 550 return result; 551 } 552 553 result = usb_serial_generic_open(tty, port); 554 if (result) { 555 usb_kill_urb(port->interrupt_in_urb); 556 return result; 557 } 558 559 return 0; 560 } 561 562 static void f81232_close(struct usb_serial_port *port) 563 { 564 f81232_port_disable(port); 565 usb_serial_generic_close(port); 566 usb_kill_urb(port->interrupt_in_urb); 567 } 568 569 static void f81232_dtr_rts(struct usb_serial_port *port, int on) 570 { 571 if (on) 572 f81232_set_mctrl(port, TIOCM_DTR | TIOCM_RTS, 0); 573 else 574 f81232_set_mctrl(port, 0, TIOCM_DTR | TIOCM_RTS); 575 } 576 577 static int f81232_carrier_raised(struct usb_serial_port *port) 578 { 579 u8 msr; 580 struct f81232_private *priv = usb_get_serial_port_data(port); 581 582 mutex_lock(&priv->lock); 583 msr = priv->modem_status; 584 mutex_unlock(&priv->lock); 585 586 if (msr & UART_MSR_DCD) 587 return 1; 588 return 0; 589 } 590 591 static int f81232_get_serial_info(struct usb_serial_port *port, 592 unsigned long arg) 593 { 594 struct serial_struct ser; 595 596 memset(&ser, 0, sizeof(ser)); 597 598 ser.type = PORT_16550A; 599 ser.line = port->minor; 600 ser.port = port->port_number; 601 ser.baud_base = F81232_MAX_BAUDRATE; 602 603 if (copy_to_user((void __user *)arg, &ser, sizeof(ser))) 604 return -EFAULT; 605 606 return 0; 607 } 608 609 static int f81232_ioctl(struct tty_struct *tty, 610 unsigned int cmd, unsigned long arg) 611 { 612 struct usb_serial_port *port = tty->driver_data; 613 614 switch (cmd) { 615 case TIOCGSERIAL: 616 return f81232_get_serial_info(port, arg); 617 default: 618 break; 619 } 620 return -ENOIOCTLCMD; 621 } 622 623 static void f81232_interrupt_work(struct work_struct *work) 624 { 625 struct f81232_private *priv = 626 container_of(work, struct f81232_private, interrupt_work); 627 628 f81232_read_msr(priv->port); 629 } 630 631 static int f81232_port_probe(struct usb_serial_port *port) 632 { 633 struct f81232_private *priv; 634 635 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 636 if (!priv) 637 return -ENOMEM; 638 639 mutex_init(&priv->lock); 640 INIT_WORK(&priv->interrupt_work, f81232_interrupt_work); 641 642 usb_set_serial_port_data(port, priv); 643 644 port->port.drain_delay = 256; 645 priv->port = port; 646 647 return 0; 648 } 649 650 static int f81232_port_remove(struct usb_serial_port *port) 651 { 652 struct f81232_private *priv; 653 654 priv = usb_get_serial_port_data(port); 655 kfree(priv); 656 657 return 0; 658 } 659 660 static struct usb_serial_driver f81232_device = { 661 .driver = { 662 .owner = THIS_MODULE, 663 .name = "f81232", 664 }, 665 .id_table = id_table, 666 .num_ports = 1, 667 .bulk_in_size = 256, 668 .bulk_out_size = 256, 669 .open = f81232_open, 670 .close = f81232_close, 671 .dtr_rts = f81232_dtr_rts, 672 .carrier_raised = f81232_carrier_raised, 673 .ioctl = f81232_ioctl, 674 .break_ctl = f81232_break_ctl, 675 .set_termios = f81232_set_termios, 676 .tiocmget = f81232_tiocmget, 677 .tiocmset = f81232_tiocmset, 678 .tiocmiwait = usb_serial_generic_tiocmiwait, 679 .process_read_urb = f81232_process_read_urb, 680 .read_int_callback = f81232_read_int_callback, 681 .port_probe = f81232_port_probe, 682 .port_remove = f81232_port_remove, 683 }; 684 685 static struct usb_serial_driver * const serial_drivers[] = { 686 &f81232_device, 687 NULL, 688 }; 689 690 module_usb_serial_driver(serial_drivers, id_table); 691 692 MODULE_DESCRIPTION("Fintek F81232 USB to serial adaptor driver"); 693 MODULE_AUTHOR("Greg Kroah-Hartman <gregkh@linuxfoundation.org>"); 694 MODULE_AUTHOR("Peter Hong <peter_hong@fintek.com.tw>"); 695 MODULE_LICENSE("GPL v2"); 696