root/drivers/usb/serial/f81232.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. calc_baud_divisor
  2. f81232_get_register
  3. f81232_set_register
  4. f81232_set_mask_register
  5. f81232_read_msr
  6. f81232_set_mctrl
  7. f81232_update_line_status
  8. f81232_read_int_callback
  9. f81232_process_read_urb
  10. f81232_break_ctl
  11. f81232_find_clk
  12. f81232_set_baudrate
  13. f81232_port_enable
  14. f81232_port_disable
  15. f81232_set_termios
  16. f81232_tiocmget
  17. f81232_tiocmset
  18. f81232_open
  19. f81232_close
  20. f81232_dtr_rts
  21. f81232_carrier_raised
  22. f81232_get_serial_info
  23. f81232_interrupt_work
  24. f81232_lsr_worker
  25. f81232_port_probe
  26. f81232_port_remove
  27. f81232_suspend
  28. f81232_resume

   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             1500000
  32 #define F81232_DEF_BAUDRATE             9600
  33 
  34 /* USB Control EP parameter */
  35 #define F81232_REGISTER_REQUEST         0xa0
  36 #define F81232_GET_REGISTER             0xc0
  37 #define F81232_SET_REGISTER             0x40
  38 
  39 #define SERIAL_BASE_ADDRESS             0x0120
  40 #define RECEIVE_BUFFER_REGISTER         (0x00 + SERIAL_BASE_ADDRESS)
  41 #define INTERRUPT_ENABLE_REGISTER       (0x01 + SERIAL_BASE_ADDRESS)
  42 #define FIFO_CONTROL_REGISTER           (0x02 + SERIAL_BASE_ADDRESS)
  43 #define LINE_CONTROL_REGISTER           (0x03 + SERIAL_BASE_ADDRESS)
  44 #define MODEM_CONTROL_REGISTER          (0x04 + SERIAL_BASE_ADDRESS)
  45 #define LINE_STATUS_REGISTER            (0x05 + SERIAL_BASE_ADDRESS)
  46 #define MODEM_STATUS_REGISTER           (0x06 + SERIAL_BASE_ADDRESS)
  47 
  48 /*
  49  * F81232 Clock registers (106h)
  50  *
  51  * Bit1-0:      Clock source selector
  52  *                      00: 1.846MHz.
  53  *                      01: 18.46MHz.
  54  *                      10: 24MHz.
  55  *                      11: 14.77MHz.
  56  */
  57 #define F81232_CLK_REGISTER             0x106
  58 #define F81232_CLK_1_846_MHZ            0
  59 #define F81232_CLK_18_46_MHZ            BIT(0)
  60 #define F81232_CLK_24_MHZ               BIT(1)
  61 #define F81232_CLK_14_77_MHZ            (BIT(1) | BIT(0))
  62 #define F81232_CLK_MASK                 GENMASK(1, 0)
  63 
  64 struct f81232_private {
  65         struct mutex lock;
  66         u8 modem_control;
  67         u8 modem_status;
  68         u8 shadow_lcr;
  69         speed_t baud_base;
  70         struct work_struct lsr_work;
  71         struct work_struct interrupt_work;
  72         struct usb_serial_port *port;
  73 };
  74 
  75 static u32 const baudrate_table[] = { 115200, 921600, 1152000, 1500000 };
  76 static u8 const clock_table[] = { F81232_CLK_1_846_MHZ, F81232_CLK_14_77_MHZ,
  77                                 F81232_CLK_18_46_MHZ, F81232_CLK_24_MHZ };
  78 
  79 static int calc_baud_divisor(speed_t baudrate, speed_t clockrate)
  80 {
  81         if (!baudrate)
  82                 return 0;
  83 
  84         return DIV_ROUND_CLOSEST(clockrate, baudrate);
  85 }
  86 
  87 static int f81232_get_register(struct usb_serial_port *port, u16 reg, u8 *val)
  88 {
  89         int status;
  90         u8 *tmp;
  91         struct usb_device *dev = port->serial->dev;
  92 
  93         tmp = kmalloc(sizeof(*val), GFP_KERNEL);
  94         if (!tmp)
  95                 return -ENOMEM;
  96 
  97         status = usb_control_msg(dev,
  98                                 usb_rcvctrlpipe(dev, 0),
  99                                 F81232_REGISTER_REQUEST,
 100                                 F81232_GET_REGISTER,
 101                                 reg,
 102                                 0,
 103                                 tmp,
 104                                 sizeof(*val),
 105                                 USB_CTRL_GET_TIMEOUT);
 106         if (status != sizeof(*val)) {
 107                 dev_err(&port->dev, "%s failed status: %d\n", __func__, status);
 108 
 109                 if (status < 0)
 110                         status = usb_translate_errors(status);
 111                 else
 112                         status = -EIO;
 113         } else {
 114                 status = 0;
 115                 *val = *tmp;
 116         }
 117 
 118         kfree(tmp);
 119         return status;
 120 }
 121 
 122 static int f81232_set_register(struct usb_serial_port *port, u16 reg, u8 val)
 123 {
 124         int status;
 125         u8 *tmp;
 126         struct usb_device *dev = port->serial->dev;
 127 
 128         tmp = kmalloc(sizeof(val), GFP_KERNEL);
 129         if (!tmp)
 130                 return -ENOMEM;
 131 
 132         *tmp = val;
 133 
 134         status = usb_control_msg(dev,
 135                                 usb_sndctrlpipe(dev, 0),
 136                                 F81232_REGISTER_REQUEST,
 137                                 F81232_SET_REGISTER,
 138                                 reg,
 139                                 0,
 140                                 tmp,
 141                                 sizeof(val),
 142                                 USB_CTRL_SET_TIMEOUT);
 143         if (status != sizeof(val)) {
 144                 dev_err(&port->dev, "%s failed status: %d\n", __func__, status);
 145 
 146                 if (status < 0)
 147                         status = usb_translate_errors(status);
 148                 else
 149                         status = -EIO;
 150         } else {
 151                 status = 0;
 152         }
 153 
 154         kfree(tmp);
 155         return status;
 156 }
 157 
 158 static int f81232_set_mask_register(struct usb_serial_port *port, u16 reg,
 159                                         u8 mask, u8 val)
 160 {
 161         int status;
 162         u8 tmp;
 163 
 164         status = f81232_get_register(port, reg, &tmp);
 165         if (status)
 166                 return status;
 167 
 168         tmp = (tmp & ~mask) | (val & mask);
 169 
 170         return f81232_set_register(port, reg, tmp);
 171 }
 172 
 173 static void f81232_read_msr(struct usb_serial_port *port)
 174 {
 175         int status;
 176         u8 current_msr;
 177         struct tty_struct *tty;
 178         struct f81232_private *priv = usb_get_serial_port_data(port);
 179 
 180         mutex_lock(&priv->lock);
 181         status = f81232_get_register(port, MODEM_STATUS_REGISTER,
 182                         &current_msr);
 183         if (status) {
 184                 dev_err(&port->dev, "%s fail, status: %d\n", __func__, status);
 185                 mutex_unlock(&priv->lock);
 186                 return;
 187         }
 188 
 189         if (!(current_msr & UART_MSR_ANY_DELTA)) {
 190                 mutex_unlock(&priv->lock);
 191                 return;
 192         }
 193 
 194         priv->modem_status = current_msr;
 195 
 196         if (current_msr & UART_MSR_DCTS)
 197                 port->icount.cts++;
 198         if (current_msr & UART_MSR_DDSR)
 199                 port->icount.dsr++;
 200         if (current_msr & UART_MSR_TERI)
 201                 port->icount.rng++;
 202         if (current_msr & UART_MSR_DDCD) {
 203                 port->icount.dcd++;
 204                 tty = tty_port_tty_get(&port->port);
 205                 if (tty) {
 206                         usb_serial_handle_dcd_change(port, tty,
 207                                         current_msr & UART_MSR_DCD);
 208 
 209                         tty_kref_put(tty);
 210                 }
 211         }
 212 
 213         wake_up_interruptible(&port->port.delta_msr_wait);
 214         mutex_unlock(&priv->lock);
 215 }
 216 
 217 static int f81232_set_mctrl(struct usb_serial_port *port,
 218                                            unsigned int set, unsigned int clear)
 219 {
 220         u8 val;
 221         int status;
 222         struct f81232_private *priv = usb_get_serial_port_data(port);
 223 
 224         if (((set | clear) & (TIOCM_DTR | TIOCM_RTS)) == 0)
 225                 return 0;       /* no change */
 226 
 227         /* 'set' takes precedence over 'clear' */
 228         clear &= ~set;
 229 
 230         /* force enable interrupt with OUT2 */
 231         mutex_lock(&priv->lock);
 232         val = UART_MCR_OUT2 | priv->modem_control;
 233 
 234         if (clear & TIOCM_DTR)
 235                 val &= ~UART_MCR_DTR;
 236 
 237         if (clear & TIOCM_RTS)
 238                 val &= ~UART_MCR_RTS;
 239 
 240         if (set & TIOCM_DTR)
 241                 val |= UART_MCR_DTR;
 242 
 243         if (set & TIOCM_RTS)
 244                 val |= UART_MCR_RTS;
 245 
 246         dev_dbg(&port->dev, "%s new:%02x old:%02x\n", __func__,
 247                         val, priv->modem_control);
 248 
 249         status = f81232_set_register(port, MODEM_CONTROL_REGISTER, val);
 250         if (status) {
 251                 dev_err(&port->dev, "%s set MCR status < 0\n", __func__);
 252                 mutex_unlock(&priv->lock);
 253                 return status;
 254         }
 255 
 256         priv->modem_control = val;
 257         mutex_unlock(&priv->lock);
 258 
 259         return 0;
 260 }
 261 
 262 static void f81232_update_line_status(struct usb_serial_port *port,
 263                                       unsigned char *data,
 264                                       size_t actual_length)
 265 {
 266         struct f81232_private *priv = usb_get_serial_port_data(port);
 267 
 268         if (!actual_length)
 269                 return;
 270 
 271         switch (data[0] & 0x07) {
 272         case 0x00: /* msr change */
 273                 dev_dbg(&port->dev, "IIR: MSR Change: %02x\n", data[0]);
 274                 schedule_work(&priv->interrupt_work);
 275                 break;
 276         case 0x02: /* tx-empty */
 277                 break;
 278         case 0x04: /* rx data available */
 279                 break;
 280         case 0x06: /* lsr change */
 281                 /* we can forget it. the LSR will read from bulk-in */
 282                 dev_dbg(&port->dev, "IIR: LSR Change: %02x\n", data[0]);
 283                 break;
 284         }
 285 }
 286 
 287 static void f81232_read_int_callback(struct urb *urb)
 288 {
 289         struct usb_serial_port *port =  urb->context;
 290         unsigned char *data = urb->transfer_buffer;
 291         unsigned int actual_length = urb->actual_length;
 292         int status = urb->status;
 293         int retval;
 294 
 295         switch (status) {
 296         case 0:
 297                 /* success */
 298                 break;
 299         case -ECONNRESET:
 300         case -ENOENT:
 301         case -ESHUTDOWN:
 302                 /* this urb is terminated, clean up */
 303                 dev_dbg(&port->dev, "%s - urb shutting down with status: %d\n",
 304                         __func__, status);
 305                 return;
 306         default:
 307                 dev_dbg(&port->dev, "%s - nonzero urb status received: %d\n",
 308                         __func__, status);
 309                 goto exit;
 310         }
 311 
 312         usb_serial_debug_data(&port->dev, __func__,
 313                               urb->actual_length, urb->transfer_buffer);
 314 
 315         f81232_update_line_status(port, data, actual_length);
 316 
 317 exit:
 318         retval = usb_submit_urb(urb, GFP_ATOMIC);
 319         if (retval)
 320                 dev_err(&urb->dev->dev,
 321                         "%s - usb_submit_urb failed with result %d\n",
 322                         __func__, retval);
 323 }
 324 
 325 static void f81232_process_read_urb(struct urb *urb)
 326 {
 327         struct usb_serial_port *port = urb->context;
 328         struct f81232_private *priv = usb_get_serial_port_data(port);
 329         unsigned char *data = urb->transfer_buffer;
 330         char tty_flag;
 331         unsigned int i;
 332         u8 lsr;
 333 
 334         /*
 335          * When opening the port we get a 1-byte packet with the current LSR,
 336          * which we discard.
 337          */
 338         if ((urb->actual_length < 2) || (urb->actual_length % 2))
 339                 return;
 340 
 341         /* bulk-in data: [LSR(1Byte)+DATA(1Byte)][LSR(1Byte)+DATA(1Byte)]... */
 342 
 343         for (i = 0; i < urb->actual_length; i += 2) {
 344                 tty_flag = TTY_NORMAL;
 345                 lsr = data[i];
 346 
 347                 if (lsr & UART_LSR_BRK_ERROR_BITS) {
 348                         if (lsr & UART_LSR_BI) {
 349                                 tty_flag = TTY_BREAK;
 350                                 port->icount.brk++;
 351                                 usb_serial_handle_break(port);
 352                         } else if (lsr & UART_LSR_PE) {
 353                                 tty_flag = TTY_PARITY;
 354                                 port->icount.parity++;
 355                         } else if (lsr & UART_LSR_FE) {
 356                                 tty_flag = TTY_FRAME;
 357                                 port->icount.frame++;
 358                         }
 359 
 360                         if (lsr & UART_LSR_OE) {
 361                                 port->icount.overrun++;
 362                                 schedule_work(&priv->lsr_work);
 363                                 tty_insert_flip_char(&port->port, 0,
 364                                                 TTY_OVERRUN);
 365                         }
 366                 }
 367 
 368                 if (port->port.console && port->sysrq) {
 369                         if (usb_serial_handle_sysrq_char(port, data[i + 1]))
 370                                 continue;
 371                 }
 372 
 373                 tty_insert_flip_char(&port->port, data[i + 1], tty_flag);
 374         }
 375 
 376         tty_flip_buffer_push(&port->port);
 377 }
 378 
 379 static void f81232_break_ctl(struct tty_struct *tty, int break_state)
 380 {
 381         struct usb_serial_port *port = tty->driver_data;
 382         struct f81232_private *priv = usb_get_serial_port_data(port);
 383         int status;
 384 
 385         mutex_lock(&priv->lock);
 386 
 387         if (break_state)
 388                 priv->shadow_lcr |= UART_LCR_SBC;
 389         else
 390                 priv->shadow_lcr &= ~UART_LCR_SBC;
 391 
 392         status = f81232_set_register(port, LINE_CONTROL_REGISTER,
 393                                         priv->shadow_lcr);
 394         if (status)
 395                 dev_err(&port->dev, "set break failed: %d\n", status);
 396 
 397         mutex_unlock(&priv->lock);
 398 }
 399 
 400 static int f81232_find_clk(speed_t baudrate)
 401 {
 402         int idx;
 403 
 404         for (idx = 0; idx < ARRAY_SIZE(baudrate_table); ++idx) {
 405                 if (baudrate <= baudrate_table[idx] &&
 406                                 baudrate_table[idx] % baudrate == 0)
 407                         return idx;
 408         }
 409 
 410         return -EINVAL;
 411 }
 412 
 413 static void f81232_set_baudrate(struct tty_struct *tty,
 414                                 struct usb_serial_port *port, speed_t baudrate,
 415                                 speed_t old_baudrate)
 416 {
 417         struct f81232_private *priv = usb_get_serial_port_data(port);
 418         u8 lcr;
 419         int divisor;
 420         int status = 0;
 421         int i;
 422         int idx;
 423         speed_t baud_list[] = { baudrate, old_baudrate, F81232_DEF_BAUDRATE };
 424 
 425         for (i = 0; i < ARRAY_SIZE(baud_list); ++i) {
 426                 idx = f81232_find_clk(baud_list[i]);
 427                 if (idx >= 0) {
 428                         baudrate = baud_list[i];
 429                         tty_encode_baud_rate(tty, baudrate, baudrate);
 430                         break;
 431                 }
 432         }
 433 
 434         if (idx < 0)
 435                 return;
 436 
 437         priv->baud_base = baudrate_table[idx];
 438         divisor = calc_baud_divisor(baudrate, priv->baud_base);
 439 
 440         status = f81232_set_mask_register(port, F81232_CLK_REGISTER,
 441                         F81232_CLK_MASK, clock_table[idx]);
 442         if (status) {
 443                 dev_err(&port->dev, "%s failed to set CLK_REG: %d\n",
 444                         __func__, status);
 445                 return;
 446         }
 447 
 448         status = f81232_get_register(port, LINE_CONTROL_REGISTER,
 449                          &lcr); /* get LCR */
 450         if (status) {
 451                 dev_err(&port->dev, "%s failed to get LCR: %d\n",
 452                         __func__, status);
 453                 return;
 454         }
 455 
 456         status = f81232_set_register(port, LINE_CONTROL_REGISTER,
 457                          lcr | UART_LCR_DLAB); /* Enable DLAB */
 458         if (status) {
 459                 dev_err(&port->dev, "%s failed to set DLAB: %d\n",
 460                         __func__, status);
 461                 return;
 462         }
 463 
 464         status = f81232_set_register(port, RECEIVE_BUFFER_REGISTER,
 465                          divisor & 0x00ff); /* low */
 466         if (status) {
 467                 dev_err(&port->dev, "%s failed to set baudrate MSB: %d\n",
 468                         __func__, status);
 469                 goto reapply_lcr;
 470         }
 471 
 472         status = f81232_set_register(port, INTERRUPT_ENABLE_REGISTER,
 473                          (divisor & 0xff00) >> 8); /* high */
 474         if (status) {
 475                 dev_err(&port->dev, "%s failed to set baudrate LSB: %d\n",
 476                         __func__, status);
 477         }
 478 
 479 reapply_lcr:
 480         status = f81232_set_register(port, LINE_CONTROL_REGISTER,
 481                         lcr & ~UART_LCR_DLAB);
 482         if (status) {
 483                 dev_err(&port->dev, "%s failed to set DLAB: %d\n",
 484                         __func__, status);
 485         }
 486 }
 487 
 488 static int f81232_port_enable(struct usb_serial_port *port)
 489 {
 490         u8 val;
 491         int status;
 492 
 493         /* fifo on, trigger8, clear TX/RX*/
 494         val = UART_FCR_TRIGGER_8 | UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR |
 495                         UART_FCR_CLEAR_XMIT;
 496 
 497         status = f81232_set_register(port, FIFO_CONTROL_REGISTER, val);
 498         if (status) {
 499                 dev_err(&port->dev, "%s failed to set FCR: %d\n",
 500                         __func__, status);
 501                 return status;
 502         }
 503 
 504         /* MSR Interrupt only, LSR will read from Bulk-in odd byte */
 505         status = f81232_set_register(port, INTERRUPT_ENABLE_REGISTER,
 506                         UART_IER_MSI);
 507         if (status) {
 508                 dev_err(&port->dev, "%s failed to set IER: %d\n",
 509                         __func__, status);
 510                 return status;
 511         }
 512 
 513         return 0;
 514 }
 515 
 516 static int f81232_port_disable(struct usb_serial_port *port)
 517 {
 518         int status;
 519 
 520         status = f81232_set_register(port, INTERRUPT_ENABLE_REGISTER, 0);
 521         if (status) {
 522                 dev_err(&port->dev, "%s failed to set IER: %d\n",
 523                         __func__, status);
 524                 return status;
 525         }
 526 
 527         return 0;
 528 }
 529 
 530 static void f81232_set_termios(struct tty_struct *tty,
 531                 struct usb_serial_port *port, struct ktermios *old_termios)
 532 {
 533         struct f81232_private *priv = usb_get_serial_port_data(port);
 534         u8 new_lcr = 0;
 535         int status = 0;
 536         speed_t baudrate;
 537         speed_t old_baud;
 538 
 539         /* Don't change anything if nothing has changed */
 540         if (old_termios && !tty_termios_hw_change(&tty->termios, old_termios))
 541                 return;
 542 
 543         if (C_BAUD(tty) == B0)
 544                 f81232_set_mctrl(port, 0, TIOCM_DTR | TIOCM_RTS);
 545         else if (old_termios && (old_termios->c_cflag & CBAUD) == B0)
 546                 f81232_set_mctrl(port, TIOCM_DTR | TIOCM_RTS, 0);
 547 
 548         baudrate = tty_get_baud_rate(tty);
 549         if (baudrate > 0) {
 550                 if (old_termios)
 551                         old_baud = tty_termios_baud_rate(old_termios);
 552                 else
 553                         old_baud = F81232_DEF_BAUDRATE;
 554 
 555                 f81232_set_baudrate(tty, port, baudrate, old_baud);
 556         }
 557 
 558         if (C_PARENB(tty)) {
 559                 new_lcr |= UART_LCR_PARITY;
 560 
 561                 if (!C_PARODD(tty))
 562                         new_lcr |= UART_LCR_EPAR;
 563 
 564                 if (C_CMSPAR(tty))
 565                         new_lcr |= UART_LCR_SPAR;
 566         }
 567 
 568         if (C_CSTOPB(tty))
 569                 new_lcr |= UART_LCR_STOP;
 570 
 571         switch (C_CSIZE(tty)) {
 572         case CS5:
 573                 new_lcr |= UART_LCR_WLEN5;
 574                 break;
 575         case CS6:
 576                 new_lcr |= UART_LCR_WLEN6;
 577                 break;
 578         case CS7:
 579                 new_lcr |= UART_LCR_WLEN7;
 580                 break;
 581         default:
 582         case CS8:
 583                 new_lcr |= UART_LCR_WLEN8;
 584                 break;
 585         }
 586 
 587         mutex_lock(&priv->lock);
 588 
 589         new_lcr |= (priv->shadow_lcr & UART_LCR_SBC);
 590         status = f81232_set_register(port, LINE_CONTROL_REGISTER, new_lcr);
 591         if (status) {
 592                 dev_err(&port->dev, "%s failed to set LCR: %d\n",
 593                         __func__, status);
 594         }
 595 
 596         priv->shadow_lcr = new_lcr;
 597 
 598         mutex_unlock(&priv->lock);
 599 }
 600 
 601 static int f81232_tiocmget(struct tty_struct *tty)
 602 {
 603         int r;
 604         struct usb_serial_port *port = tty->driver_data;
 605         struct f81232_private *port_priv = usb_get_serial_port_data(port);
 606         u8 mcr, msr;
 607 
 608         /* force get current MSR changed state */
 609         f81232_read_msr(port);
 610 
 611         mutex_lock(&port_priv->lock);
 612         mcr = port_priv->modem_control;
 613         msr = port_priv->modem_status;
 614         mutex_unlock(&port_priv->lock);
 615 
 616         r = (mcr & UART_MCR_DTR ? TIOCM_DTR : 0) |
 617                 (mcr & UART_MCR_RTS ? TIOCM_RTS : 0) |
 618                 (msr & UART_MSR_CTS ? TIOCM_CTS : 0) |
 619                 (msr & UART_MSR_DCD ? TIOCM_CAR : 0) |
 620                 (msr & UART_MSR_RI ? TIOCM_RI : 0) |
 621                 (msr & UART_MSR_DSR ? TIOCM_DSR : 0);
 622 
 623         return r;
 624 }
 625 
 626 static int f81232_tiocmset(struct tty_struct *tty,
 627                         unsigned int set, unsigned int clear)
 628 {
 629         struct usb_serial_port *port = tty->driver_data;
 630 
 631         return f81232_set_mctrl(port, set, clear);
 632 }
 633 
 634 static int f81232_open(struct tty_struct *tty, struct usb_serial_port *port)
 635 {
 636         int result;
 637 
 638         result = f81232_port_enable(port);
 639         if (result)
 640                 return result;
 641 
 642         /* Setup termios */
 643         if (tty)
 644                 f81232_set_termios(tty, port, NULL);
 645 
 646         result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
 647         if (result) {
 648                 dev_err(&port->dev, "%s - failed submitting interrupt urb,"
 649                         " error %d\n", __func__, result);
 650                 return result;
 651         }
 652 
 653         result = usb_serial_generic_open(tty, port);
 654         if (result) {
 655                 usb_kill_urb(port->interrupt_in_urb);
 656                 return result;
 657         }
 658 
 659         return 0;
 660 }
 661 
 662 static void f81232_close(struct usb_serial_port *port)
 663 {
 664         struct f81232_private *port_priv = usb_get_serial_port_data(port);
 665 
 666         f81232_port_disable(port);
 667         usb_serial_generic_close(port);
 668         usb_kill_urb(port->interrupt_in_urb);
 669         flush_work(&port_priv->interrupt_work);
 670         flush_work(&port_priv->lsr_work);
 671 }
 672 
 673 static void f81232_dtr_rts(struct usb_serial_port *port, int on)
 674 {
 675         if (on)
 676                 f81232_set_mctrl(port, TIOCM_DTR | TIOCM_RTS, 0);
 677         else
 678                 f81232_set_mctrl(port, 0, TIOCM_DTR | TIOCM_RTS);
 679 }
 680 
 681 static int f81232_carrier_raised(struct usb_serial_port *port)
 682 {
 683         u8 msr;
 684         struct f81232_private *priv = usb_get_serial_port_data(port);
 685 
 686         mutex_lock(&priv->lock);
 687         msr = priv->modem_status;
 688         mutex_unlock(&priv->lock);
 689 
 690         if (msr & UART_MSR_DCD)
 691                 return 1;
 692         return 0;
 693 }
 694 
 695 static int f81232_get_serial_info(struct tty_struct *tty,
 696                 struct serial_struct *ss)
 697 {
 698         struct usb_serial_port *port = tty->driver_data;
 699         struct f81232_private *priv = usb_get_serial_port_data(port);
 700 
 701         ss->type = PORT_16550A;
 702         ss->line = port->minor;
 703         ss->port = port->port_number;
 704         ss->baud_base = priv->baud_base;
 705         return 0;
 706 }
 707 
 708 static void  f81232_interrupt_work(struct work_struct *work)
 709 {
 710         struct f81232_private *priv =
 711                 container_of(work, struct f81232_private, interrupt_work);
 712 
 713         f81232_read_msr(priv->port);
 714 }
 715 
 716 static void f81232_lsr_worker(struct work_struct *work)
 717 {
 718         struct f81232_private *priv;
 719         struct usb_serial_port *port;
 720         int status;
 721         u8 tmp;
 722 
 723         priv = container_of(work, struct f81232_private, lsr_work);
 724         port = priv->port;
 725 
 726         status = f81232_get_register(port, LINE_STATUS_REGISTER, &tmp);
 727         if (status)
 728                 dev_warn(&port->dev, "read LSR failed: %d\n", status);
 729 }
 730 
 731 static int f81232_port_probe(struct usb_serial_port *port)
 732 {
 733         struct f81232_private *priv;
 734 
 735         priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 736         if (!priv)
 737                 return -ENOMEM;
 738 
 739         mutex_init(&priv->lock);
 740         INIT_WORK(&priv->interrupt_work,  f81232_interrupt_work);
 741         INIT_WORK(&priv->lsr_work, f81232_lsr_worker);
 742 
 743         usb_set_serial_port_data(port, priv);
 744 
 745         port->port.drain_delay = 256;
 746         priv->port = port;
 747 
 748         return 0;
 749 }
 750 
 751 static int f81232_port_remove(struct usb_serial_port *port)
 752 {
 753         struct f81232_private *priv;
 754 
 755         priv = usb_get_serial_port_data(port);
 756         kfree(priv);
 757 
 758         return 0;
 759 }
 760 
 761 static int f81232_suspend(struct usb_serial *serial, pm_message_t message)
 762 {
 763         struct usb_serial_port *port = serial->port[0];
 764         struct f81232_private *port_priv = usb_get_serial_port_data(port);
 765         int i;
 766 
 767         for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i)
 768                 usb_kill_urb(port->read_urbs[i]);
 769 
 770         usb_kill_urb(port->interrupt_in_urb);
 771 
 772         if (port_priv) {
 773                 flush_work(&port_priv->interrupt_work);
 774                 flush_work(&port_priv->lsr_work);
 775         }
 776 
 777         return 0;
 778 }
 779 
 780 static int f81232_resume(struct usb_serial *serial)
 781 {
 782         struct usb_serial_port *port = serial->port[0];
 783         int result;
 784 
 785         if (tty_port_initialized(&port->port)) {
 786                 result = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO);
 787                 if (result) {
 788                         dev_err(&port->dev, "submit interrupt urb failed: %d\n",
 789                                         result);
 790                         return result;
 791                 }
 792         }
 793 
 794         return usb_serial_generic_resume(serial);
 795 }
 796 
 797 static struct usb_serial_driver f81232_device = {
 798         .driver = {
 799                 .owner =        THIS_MODULE,
 800                 .name =         "f81232",
 801         },
 802         .id_table =             id_table,
 803         .num_ports =            1,
 804         .bulk_in_size =         256,
 805         .bulk_out_size =        256,
 806         .open =                 f81232_open,
 807         .close =                f81232_close,
 808         .dtr_rts =              f81232_dtr_rts,
 809         .carrier_raised =       f81232_carrier_raised,
 810         .get_serial =           f81232_get_serial_info,
 811         .break_ctl =            f81232_break_ctl,
 812         .set_termios =          f81232_set_termios,
 813         .tiocmget =             f81232_tiocmget,
 814         .tiocmset =             f81232_tiocmset,
 815         .tiocmiwait =           usb_serial_generic_tiocmiwait,
 816         .process_read_urb =     f81232_process_read_urb,
 817         .read_int_callback =    f81232_read_int_callback,
 818         .port_probe =           f81232_port_probe,
 819         .port_remove =          f81232_port_remove,
 820         .suspend =              f81232_suspend,
 821         .resume =               f81232_resume,
 822 };
 823 
 824 static struct usb_serial_driver * const serial_drivers[] = {
 825         &f81232_device,
 826         NULL,
 827 };
 828 
 829 module_usb_serial_driver(serial_drivers, id_table);
 830 
 831 MODULE_DESCRIPTION("Fintek F81232 USB to serial adaptor driver");
 832 MODULE_AUTHOR("Greg Kroah-Hartman <gregkh@linuxfoundation.org>");
 833 MODULE_AUTHOR("Peter Hong <peter_hong@fintek.com.tw>");
 834 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */