static int cp210x_carrier_raised(struct usb_serial_port *p) { unsigned int control; cp210x_get_config(p, CP210X_GET_MDMSTS, &control, 1); if (control & CONTROL_DCD) return 1; return 0; }
static int cp210x_tiocmget (struct tty_struct *tty, struct file *file) { struct usb_serial_port *port = tty->driver_data; unsigned int control; int result; dbg("%s - port %d", __func__, port->number); cp210x_get_config(port, CP210X_GET_MDMSTS, &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", __func__, control); return result; }
/* * cp210x_get_termios_port * This is the heart of cp210x_get_termios which always uses a &usb_serial_port. */ static void cp210x_get_termios_port(struct usb_serial_port *port, unsigned int *cflagp, unsigned int *baudp) { unsigned int cflag, modem_ctl[4]; unsigned int baud; unsigned int bits; dbg("%s - port %d", __func__, port->number); cp210x_get_config(port, CP210X_GET_BAUDDIV, &baud, 2); /* Convert to baudrate */ if (baud) baud = cp210x_quantise_baudrate((BAUD_RATE_GEN_FREQ + baud/2)/ baud); dbg("%s - baud rate = %d", __func__, baud); *baudp = baud; cflag = *cflagp; cp210x_get_config(port, CP210X_GET_LINE_CTL, &bits, 2); cflag &= ~CSIZE; switch (bits & BITS_DATA_MASK) { case BITS_DATA_5: dbg("%s - data bits = 5", __func__); cflag |= CS5; break; case BITS_DATA_6: dbg("%s - data bits = 6", __func__); cflag |= CS6; break; case BITS_DATA_7: dbg("%s - data bits = 7", __func__); cflag |= CS7; break; case BITS_DATA_8: dbg("%s - data bits = 8", __func__); cflag |= CS8; break; case BITS_DATA_9: dbg("%s - data bits = 9 (not supported, using 8 data bits)", __func__); cflag |= CS8; bits &= ~BITS_DATA_MASK; bits |= BITS_DATA_8; cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2); break; default: dbg("%s - Unknown number of data bits, using 8", __func__); cflag |= CS8; bits &= ~BITS_DATA_MASK; bits |= BITS_DATA_8; cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2); break; } switch (bits & BITS_PARITY_MASK) { case BITS_PARITY_NONE: dbg("%s - parity = NONE", __func__); cflag &= ~PARENB; break; case BITS_PARITY_ODD: dbg("%s - parity = ODD", __func__); cflag |= (PARENB|PARODD); break; case BITS_PARITY_EVEN: dbg("%s - parity = EVEN", __func__); cflag &= ~PARODD; cflag |= PARENB; break; case BITS_PARITY_MARK: dbg("%s - parity = MARK (not supported, disabling parity)", __func__); cflag &= ~PARENB; bits &= ~BITS_PARITY_MASK; cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2); break; case BITS_PARITY_SPACE: dbg("%s - parity = SPACE (not supported, disabling parity)", __func__); cflag &= ~PARENB; bits &= ~BITS_PARITY_MASK; cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2); break; default: dbg("%s - Unknown parity mode, disabling parity", __func__); cflag &= ~PARENB; bits &= ~BITS_PARITY_MASK; cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2); break; } cflag &= ~CSTOPB; switch (bits & BITS_STOP_MASK) { case BITS_STOP_1: dbg("%s - stop bits = 1", __func__); break; case BITS_STOP_1_5: dbg("%s - stop bits = 1.5 (not supported, using 1 stop bit)", __func__); bits &= ~BITS_STOP_MASK; cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2); break; case BITS_STOP_2: dbg("%s - stop bits = 2", __func__); cflag |= CSTOPB; break; default: dbg("%s - Unknown number of stop bits, using 1 stop bit", __func__); bits &= ~BITS_STOP_MASK; cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2); break; } cp210x_get_config(port, CP210X_GET_FLOW, modem_ctl, 16); if (modem_ctl[0] & 0x0008) { dbg("%s - flow control = CRTSCTS", __func__); cflag |= CRTSCTS; } else { dbg("%s - flow control = NONE", __func__); cflag &= ~CRTSCTS; } *cflagp = cflag; }
static void cp210x_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old_termios) { unsigned int cflag, old_cflag; unsigned int baud = 0, bits; unsigned int modem_ctl[4]; dbg("%s - port %d", __func__, port->number); if (!tty) return; tty->termios->c_cflag &= ~CMSPAR; cflag = tty->termios->c_cflag; old_cflag = old_termios->c_cflag; baud = cp210x_quantise_baudrate(tty_get_baud_rate(tty)); /* If the baud rate is to be updated*/ if (baud != tty_termios_baud_rate(old_termios) && baud != 0) { dbg("%s - Setting baud rate to %d baud", __func__, baud); if (cp210x_set_config_single(port, CP210X_SET_BAUDDIV, ((BAUD_RATE_GEN_FREQ + baud/2) / baud))) { dbg("Baud rate requested not supported by device"); baud = tty_termios_baud_rate(old_termios); } } /* Report back the resulting baud rate */ tty_encode_baud_rate(tty, baud, baud); /* If the number of data bits is to be updated */ if ((cflag & CSIZE) != (old_cflag & CSIZE)) { cp210x_get_config(port, CP210X_GET_LINE_CTL, &bits, 2); bits &= ~BITS_DATA_MASK; switch (cflag & CSIZE) { case CS5: bits |= BITS_DATA_5; dbg("%s - data bits = 5", __func__); break; case CS6: bits |= BITS_DATA_6; dbg("%s - data bits = 6", __func__); break; case CS7: bits |= BITS_DATA_7; dbg("%s - data bits = 7", __func__); break; case CS8: bits |= BITS_DATA_8; dbg("%s - data bits = 8", __func__); break; /*case CS9: bits |= BITS_DATA_9; dbg("%s - data bits = 9", __func__); break;*/ default: dbg("cp210x driver does not " "support the number of bits requested," " using 8 bit mode\n"); bits |= BITS_DATA_8; break; } if (cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2)) dbg("Number of data bits requested " "not supported by device\n"); } if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD))) { cp210x_get_config(port, CP210X_GET_LINE_CTL, &bits, 2); bits &= ~BITS_PARITY_MASK; if (cflag & PARENB) { if (cflag & PARODD) { bits |= BITS_PARITY_ODD; dbg("%s - parity = ODD", __func__); } else { bits |= BITS_PARITY_EVEN; dbg("%s - parity = EVEN", __func__); } } if (cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2)) dbg("Parity mode not supported " "by device\n"); } if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) { cp210x_get_config(port, CP210X_GET_LINE_CTL, &bits, 2); bits &= ~BITS_STOP_MASK; if (cflag & CSTOPB) { bits |= BITS_STOP_2; dbg("%s - stop bits = 2", __func__); } else { bits |= BITS_STOP_1; dbg("%s - stop bits = 1", __func__); } if (cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2)) dbg("Number of stop bits requested " "not supported by device\n"); } if ((cflag & CRTSCTS) != (old_cflag & CRTSCTS)) { cp210x_get_config(port, CP210X_GET_FLOW, modem_ctl, 16); dbg("%s - read modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x", __func__, 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", __func__); } else { modem_ctl[0] &= ~0x7B; modem_ctl[0] |= 0x01; modem_ctl[1] |= 0x40; dbg("%s - flow control = NONE", __func__); } dbg("%s - write modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x", __func__, modem_ctl[0], modem_ctl[1], modem_ctl[2], modem_ctl[3]); cp210x_set_config(port, CP210X_SET_FLOW, modem_ctl, 16); } }
static void cp210x_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old_termios) { unsigned int cflag, old_cflag; unsigned int bits; unsigned int modem_ctl[4]; dbg("%s - port %d", __func__, port->number); if (!tty) return; tty->termios->c_cflag &= ~CMSPAR; cflag = tty->termios->c_cflag; old_cflag = old_termios->c_cflag; if (tty->termios->c_ospeed != old_termios->c_ospeed) cp210x_change_speed(tty, port, old_termios); /* If the number of data bits is to be updated */ if ((cflag & CSIZE) != (old_cflag & CSIZE)) { cp210x_get_config(port, CP210X_GET_LINE_CTL, &bits, 2); bits &= ~BITS_DATA_MASK; switch (cflag & CSIZE) { case CS5: bits |= BITS_DATA_5; dbg("%s - data bits = 5", __func__); break; case CS6: bits |= BITS_DATA_6; dbg("%s - data bits = 6", __func__); break; case CS7: bits |= BITS_DATA_7; dbg("%s - data bits = 7", __func__); break; case CS8: bits |= BITS_DATA_8; dbg("%s - data bits = 8", __func__); break; /*case CS9: bits |= BITS_DATA_9; dbg("%s - data bits = 9", __func__); break;*/ default: dbg("cp210x driver does not " "support the number of bits requested," " using 8 bit mode\n"); bits |= BITS_DATA_8; break; } if (cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2)) dbg("Number of data bits requested " "not supported by device\n"); } if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD))) { cp210x_get_config(port, CP210X_GET_LINE_CTL, &bits, 2); bits &= ~BITS_PARITY_MASK; if (cflag & PARENB) { if (cflag & PARODD) { bits |= BITS_PARITY_ODD; dbg("%s - parity = ODD", __func__); } else { bits |= BITS_PARITY_EVEN; dbg("%s - parity = EVEN", __func__); } } if (cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2)) dbg("Parity mode not supported " "by device\n"); } if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) { cp210x_get_config(port, CP210X_GET_LINE_CTL, &bits, 2); bits &= ~BITS_STOP_MASK; if (cflag & CSTOPB) { bits |= BITS_STOP_2; dbg("%s - stop bits = 2", __func__); } else { bits |= BITS_STOP_1; dbg("%s - stop bits = 1", __func__); } if (cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2)) dbg("Number of stop bits requested " "not supported by device\n"); } if ((cflag & CRTSCTS) != (old_cflag & CRTSCTS)) { cp210x_get_config(port, CP210X_GET_FLOW, modem_ctl, 16); dbg("%s - read modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x", __func__, 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", __func__); } else { modem_ctl[0] &= ~0x7B; modem_ctl[0] |= 0x01; modem_ctl[1] |= 0x40; dbg("%s - flow control = NONE", __func__); } dbg("%s - write modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x", __func__, modem_ctl[0], modem_ctl[1], modem_ctl[2], modem_ctl[3]); cp210x_set_config(port, CP210X_SET_FLOW, modem_ctl, 16); } }