📄 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 termios *old_termios){ unsigned int cflag, old_cflag=0; 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; } cflag = port->tty->termios->c_cflag; /* Check that they really want us to change something */ if (old_termios) { if ((cflag == old_termios->c_cflag) && (RELEVANT_IFLAG(port->tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) { dbg("%s - nothing to change...", __FUNCTION__); return; } old_cflag = old_termios->c_cflag; } /* If the baud rate is to be updated*/ if ((cflag & CBAUD) != (old_cflag & CBAUD)) { switch (cflag & CBAUD) { /* * The baud rates which are commented out below * appear to be supported by the device * but are non-standard */ case B0: baud = 0; break; case B600: baud = 600; break; case B1200: baud = 1200; break; case B1800: baud = 1800; break; case B2400: baud = 2400; break; case B4800: baud = 4800; break; /*case B7200: baud = 7200; break;*/ case B9600: baud = 9600; break; /*ase B14400: baud = 14400; break;*/ case B19200: baud = 19200; break; /*case B28800: baud = 28800; break;*/ case B38400: baud = 38400; break; /*case B55854: baud = 55054; break;*/ case B57600: baud = 57600; break; case B115200: baud = 115200; break; /*case B127117: baud = 127117; break;*/ case B230400: baud = 230400; break; case B460800: baud = 460800; break; case B921600: baud = 921600; break; /*case B3686400: baud = 3686400; break;*/ default: dev_err(&port->dev, "cp2101 driver does not " "support the baudrate requested\n"); 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"); } } /* 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 + -