📄 cp2101.c
字号:
switch(bits & BITS_DATA_MASK) { case BITS_DATA_5: dbg("%s - data bits = 5", __FUNCTION__); cflag |= CS5; break; case BITS_DATA_6: dbg("%s - data bits = 6", __FUNCTION__); cflag |= CS6; break; case BITS_DATA_7: dbg("%s - data bits = 7", __FUNCTION__); cflag |= CS7; break; case BITS_DATA_8: dbg("%s - data bits = 8", __FUNCTION__); cflag |= CS8; break; case BITS_DATA_9: dbg("%s - data bits = 9 (not supported, " "using 8 data bits)", __FUNCTION__); cflag |= CS8; bits &= ~BITS_DATA_MASK; bits |= BITS_DATA_8; cp2101_set_config(port, CP2101_BITS, &bits, 2); break; default: dbg("%s - Unknown number of data bits, " "using 8", __FUNCTION__); cflag |= CS8; bits &= ~BITS_DATA_MASK; bits |= BITS_DATA_8; cp2101_set_config(port, CP2101_BITS, &bits, 2); break; } switch(bits & BITS_PARITY_MASK) { case BITS_PARITY_NONE: dbg("%s - parity = NONE", __FUNCTION__); cflag &= ~PARENB; break; case BITS_PARITY_ODD: dbg("%s - parity = ODD", __FUNCTION__); cflag |= (PARENB|PARODD); break; case BITS_PARITY_EVEN: dbg("%s - parity = EVEN", __FUNCTION__); cflag &= ~PARODD; cflag |= PARENB; break; case BITS_PARITY_MARK: dbg("%s - parity = MARK (not supported, " "disabling parity)", __FUNCTION__); cflag &= ~PARENB; bits &= ~BITS_PARITY_MASK; cp2101_set_config(port, CP2101_BITS, &bits, 2); break; case BITS_PARITY_SPACE: dbg("%s - parity = SPACE (not supported, " "disabling parity)", __FUNCTION__); cflag &= ~PARENB; bits &= ~BITS_PARITY_MASK; cp2101_set_config(port, CP2101_BITS, &bits, 2); break; default: dbg("%s - Unknown parity mode, " "disabling parity", __FUNCTION__); cflag &= ~PARENB; bits &= ~BITS_PARITY_MASK; cp2101_set_config(port, CP2101_BITS, &bits, 2); break; } cflag &= ~CSTOPB; switch(bits & BITS_STOP_MASK) { case BITS_STOP_1: dbg("%s - stop bits = 1", __FUNCTION__); break; case BITS_STOP_1_5: dbg("%s - stop bits = 1.5 (not supported, " "using 1 stop bit)", __FUNCTION__); bits &= ~BITS_STOP_MASK; cp2101_set_config(port, CP2101_BITS, &bits, 2); break; case BITS_STOP_2: dbg("%s - stop bits = 2", __FUNCTION__); cflag |= CSTOPB; break; default: dbg("%s - Unknown number of stop bits, " "using 1 stop bit", __FUNCTION__); bits &= ~BITS_STOP_MASK; cp2101_set_config(port, CP2101_BITS, &bits, 2); break; } cp2101_get_config(port, CP2101_MODEMCTL, modem_ctl, 16); if (modem_ctl[0] & 0x0008) { dbg("%s - flow control = CRTSCTS", __FUNCTION__); cflag |= CRTSCTS; } else { dbg("%s - flow control = NONE", __FUNCTION__); cflag &= ~CRTSCTS; } port->tty->termios->c_cflag = cflag;}static void cp2101_set_termios (struct usb_serial_port *port, struct ktermios *old_termios){ unsigned int cflag, old_cflag; int baud=0, bits; unsigned int modem_ctl[4]; dbg("%s - port %d", __FUNCTION__, port->number); if (!port->tty || !port->tty->termios) { dbg("%s - no tty structures", __FUNCTION__); return; } port->tty->termios->c_cflag &= ~CMSPAR; cflag = port->tty->termios->c_cflag; old_cflag = old_termios->c_cflag; baud = tty_get_baud_rate(port->tty); /* If the baud rate is to be updated*/ if (baud != tty_termios_baud_rate(old_termios)) { switch (baud) { case 0: case 600: case 1200: case 1800: case 2400: case 4800: case 7200: case 9600: case 14400: case 19200: case 28800: case 38400: case 55854: case 57600: case 115200: case 127117: case 230400: case 460800: case 921600: case 3686400: break; default: baud = 9600; break; } if (baud) { dbg("%s - Setting baud rate to %d baud", __FUNCTION__, baud); if (cp2101_set_config_single(port, CP2101_BAUDRATE, (BAUD_RATE_GEN_FREQ / baud))) { dev_err(&port->dev, "Baud rate requested not " "supported by device\n"); baud = tty_termios_baud_rate(old_termios); } } } /* Report back the resulting baud rate */ tty_encode_baud_rate(port->tty, baud, baud); /* If the number of data bits is to be updated */ if ((cflag & CSIZE) != (old_cflag & CSIZE)) { cp2101_get_config(port, CP2101_BITS, &bits, 2); bits &= ~BITS_DATA_MASK; switch (cflag & CSIZE) { case CS5: bits |= BITS_DATA_5; dbg("%s - data bits = 5", __FUNCTION__); break; case CS6: bits |= BITS_DATA_6; dbg("%s - data bits = 6", __FUNCTION__); break; case CS7: bits |= BITS_DATA_7; dbg("%s - data bits = 7", __FUNCTION__); break; case CS8: bits |= BITS_DATA_8; dbg("%s - data bits = 8", __FUNCTION__); break; /*case CS9: bits |= BITS_DATA_9; dbg("%s - data bits = 9", __FUNCTION__); break;*/ default: dev_err(&port->dev, "cp2101 driver does not " "support the number of bits requested," " using 8 bit mode\n"); bits |= BITS_DATA_8; break; } if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) dev_err(&port->dev, "Number of data bits requested " "not supported by device\n"); } if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD))) { cp2101_get_config(port, CP2101_BITS, &bits, 2); bits &= ~BITS_PARITY_MASK; if (cflag & PARENB) { if (cflag & PARODD) { bits |= BITS_PARITY_ODD; dbg("%s - parity = ODD", __FUNCTION__); } else { bits |= BITS_PARITY_EVEN; dbg("%s - parity = EVEN", __FUNCTION__); } } if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) dev_err(&port->dev, "Parity mode not supported " "by device\n"); } if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) { cp2101_get_config(port, CP2101_BITS, &bits, 2); bits &= ~BITS_STOP_MASK; if (cflag & CSTOPB) { bits |= BITS_STOP_2; dbg("%s - stop bits = 2", __FUNCTION__); } else { bits |= BITS_STOP_1; dbg("%s - stop bits = 1", __FUNCTION__); } if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) dev_err(&port->dev, "Number of stop bits requested " "not supported by device\n"); } if ((cflag & CRTSCTS) != (old_cflag & CRTSCTS)) { cp2101_get_config(port, CP2101_MODEMCTL, modem_ctl, 16); dbg("%s - read modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x", __FUNCTION__, modem_ctl[0], modem_ctl[1], modem_ctl[2], modem_ctl[3]); if (cflag & CRTSCTS) { modem_ctl[0] &= ~0x7B; modem_ctl[0] |= 0x09; modem_ctl[1] = 0x80; dbg("%s - flow control = CRTSCTS", __FUNCTION__); } else { modem_ctl[0] &= ~0x7B; modem_ctl[0] |= 0x01; modem_ctl[1] |= 0x40; dbg("%s - flow control = NONE", __FUNCTION__); } dbg("%s - write modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x", __FUNCTION__, modem_ctl[0], modem_ctl[1], modem_ctl[2], modem_ctl[3]); cp2101_set_config(port, CP2101_MODEMCTL, modem_ctl, 16); }}static int cp2101_tiocmset (struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear){ int control = 0; dbg("%s - port %d", __FUNCTION__, port->number); if (set & TIOCM_RTS) { control |= CONTROL_RTS; control |= CONTROL_WRITE_RTS; } if (set & TIOCM_DTR) { control |= CONTROL_DTR; control |= CONTROL_WRITE_DTR; } if (clear & TIOCM_RTS) { control &= ~CONTROL_RTS; control |= CONTROL_WRITE_RTS; } if (clear & TIOCM_DTR) { control &= ~CONTROL_DTR; control |= CONTROL_WRITE_DTR; } dbg("%s - control = 0x%.4x", __FUNCTION__, control); return cp2101_set_config(port, CP2101_CONTROL, &control, 2);}static int cp2101_tiocmget (struct usb_serial_port *port, struct file *file){ int control, result; dbg("%s - port %d", __FUNCTION__, port->number); cp2101_get_config(port, CP2101_CONTROL, &control, 1); result = ((control & CONTROL_DTR) ? TIOCM_DTR : 0) |((control & CONTROL_RTS) ? TIOCM_RTS : 0) |((control & CONTROL_CTS) ? TIOCM_CTS : 0) |((control & CONTROL_DSR) ? TIOCM_DSR : 0) |((control & CONTROL_RING)? TIOCM_RI : 0) |((control & CONTROL_DCD) ? TIOCM_CD : 0); dbg("%s - control = 0x%.2x", __FUNCTION__, control); return result;}static void cp2101_break_ctl (struct usb_serial_port *port, int break_state){ int state; dbg("%s - port %d", __FUNCTION__, port->number); if (break_state == 0) state = BREAK_OFF; else state = BREAK_ON; dbg("%s - turning break %s", __FUNCTION__, state==BREAK_OFF ? "off" : "on"); cp2101_set_config(port, CP2101_BREAK, &state, 2);}static int cp2101_startup (struct usb_serial *serial){ /* CP2101 buffers behave strangely unless device is reset */ usb_reset_device(serial->dev); return 0;}static void cp2101_shutdown (struct usb_serial *serial){ int i; dbg("%s", __FUNCTION__); /* Stop reads and writes on all ports */ for (i=0; i < serial->num_ports; ++i) { cp2101_cleanup(serial->port[i]); }}static int __init cp2101_init (void){ int retval; retval = usb_serial_register(&cp2101_device); if (retval) return retval; /* Failed to register */ retval = usb_register(&cp2101_driver); if (retval) { /* Failed to register */ usb_serial_deregister(&cp2101_device); return retval; } /* Success */ info(DRIVER_DESC " " DRIVER_VERSION); return 0;}static void __exit cp2101_exit (void){ usb_deregister (&cp2101_driver); usb_serial_deregister (&cp2101_device);}module_init(cp2101_init);module_exit(cp2101_exit);MODULE_DESCRIPTION(DRIVER_DESC);MODULE_VERSION(DRIVER_VERSION);MODULE_LICENSE("GPL");module_param(debug, bool, S_IRUGO | S_IWUSR);MODULE_PARM_DESC(debug, "Enable verbose debugging messages");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -