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