Messages in this thread | | | Date | Sun, 25 Apr 1999 02:07:12 -0400 (EDT) | From | Fredrik <> | Subject | fixed bugs in TI16750 serial driver. |
| |
this patch fixes bugs in 16750 detection, as well as enables 16750 AutoFlow (the UART handles CTS/RTS to improve reliability and performance at high speeds)
--alpha
Improve support for TI16750. patch for ftp://tsx-11.mit.edu/pub/linux/ALPHA/serial/serial-4.87.tar.gz, but applies to 2.2.x kernels. hunk #2 may fail, then apply it manually.
you may have to rebuild setserial-2.16.tar.gz (make sure to copy serial.h to /usr/include/linux unless you already have a very recent serial driver installed)
to apply patch:
cd /usr/src/linux patch -p0 <patch.serial-16750
- fredrik.sjoholm <alpha@cupid.suninternet.com>
*** drivers/char/serial.c Sun Mar 7 23:52:45 1999 --- drivers/char/serial.c Sun Apr 25 01:37:23 1999 *************** *** 32,37 **** --- 32,43 ---- * 4/98: Added changes to support the ARM architecture proposed by * Russell King * + * 4/99: Fixed detection of TI16750, and enabled 16750 AutoFlow. + * AutoFlow reduces the number of interrupts since the chip + * does it's own CTS/RTS handling. (tested with the excellent + * 16750 cards available from byterunner.com) - fredrik.sjoholm + * <alpha@hextrade.com> + * * This module exports the following rs232 io functions: * * int rs_init(void); *************** *** 236,246 **** { "16550A", 16, UART_CLEAR_FIFO | UART_USE_FIFO }, { "cirrus", 1, 0 }, /* usurped by cyclades.c */ { "ST16650", 1, UART_CLEAR_FIFO |UART_STARTECH }, ! { "ST16650V2", 32, UART_CLEAR_FIFO | UART_USE_FIFO | ! UART_STARTECH }, ! { "TI16750", 64, UART_CLEAR_FIFO | UART_USE_FIFO}, { "Startech", 1, 0}, /* usurped by cyclades.c */ ! { "TI16750", 128, UART_CLEAR_FIFO | UART_USE_FIFO}, { 0, 0} }; --- 242,251 ---- { "16550A", 16, UART_CLEAR_FIFO | UART_USE_FIFO }, { "cirrus", 1, 0 }, /* usurped by cyclades.c */ { "ST16650", 1, UART_CLEAR_FIFO |UART_STARTECH }, ! { "ST16650V2", 32, UART_CLEAR_FIFO | UART_USE_FIFO | UART_STARTECH }, ! { "TI16750", 64, UART_CLEAR_FIFO | UART_USE_FIFO }, { "Startech", 1, 0}, /* usurped by cyclades.c */ ! { "16C950", 128, UART_CLEAR_FIFO | UART_USE_FIFO}, { 0, 0} }; *************** *** 1380,1387 **** /* disable break condition */ serial_out(info, UART_LCR, serial_inp(info, UART_LCR) & ~UART_LCR_SBC); ! if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS); serial_outp(info, UART_MCR, info->MCR); /* disable FIFO's */ --- 1385,1396 ---- /* disable break condition */ serial_out(info, UART_LCR, serial_inp(info, UART_LCR) & ~UART_LCR_SBC); ! if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) { ! // if we have a 16750, disable autoflow in case it's on: ! if (info->state->type == PORT_16750) info->MCR &= ~UART_MCR_AFE; ! // drop DTR and RTS pins: info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS); + } serial_outp(info, UART_MCR, info->MCR); /* disable FIFO's */ *************** *** 1546,1553 **** if (info->flags & ASYNC_HARDPPS_CD) info->IER |= UART_IER_MSI; if (cflag & CRTSCTS) { ! info->flags |= ASYNC_CTS_FLOW; ! info->IER |= UART_IER_MSI; } else info->flags &= ~ASYNC_CTS_FLOW; if (cflag & CLOCAL) --- 1555,1568 ---- if (info->flags & ASYNC_HARDPPS_CD) info->IER |= UART_IER_MSI; if (cflag & CRTSCTS) { ! if (info->state->type == PORT_16750) { ! // no need for flow ctl interrupts when using 16750 AutoFlow. ! // enable autoflow for CTS and RTS ! info->MCR |= UART_MCR_AFE | UART_MCR_RTS; ! } else { ! info->flags |= ASYNC_CTS_FLOW; ! info->IER |= UART_IER_MSI; ! } } else info->flags &= ~ASYNC_CTS_FLOW; if (cflag & CLOCAL) *************** *** 1800,1806 **** if (I_IXOFF(tty)) rs_send_xchar(tty, STOP_CHAR(tty)); ! if (tty->termios->c_cflag & CRTSCTS) info->MCR &= ~UART_MCR_RTS; save_flags(flags); cli(); --- 1815,1826 ---- if (I_IXOFF(tty)) rs_send_xchar(tty, STOP_CHAR(tty)); ! // if hardware flow is on, drop RTS pin. ! // if we have a 16750 chip, we don't need to do anything, ! // since the autoflow feature will throttle for us when we don't ! // drain the FIFO: ! if (tty->termios->c_cflag & CRTSCTS && ! info->state->type != PORT_16750) info->MCR &= ~UART_MCR_RTS; save_flags(flags); cli(); *************** *** 1937,1942 **** --- 1957,1963 ---- info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) | (info->flags & ASYNC_INTERNAL_FLAGS)); state->custom_divisor = new_serial.custom_divisor; + state->type = new_serial.type; state->close_delay = new_serial.close_delay * HZ/100; state->closing_wait = new_serial.closing_wait * HZ/100; *************** *** 3338,3349 **** if (state->type == PORT_16550A) { /* Check for TI 16750 */ serial_outp(info, UART_LCR, scratch2 | UART_LCR_DLAB); ! serial_outp(info, UART_FCR, ! UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE); scratch = serial_in(info, UART_IIR) >> 5; if (scratch == 7) { ! serial_outp(info, UART_LCR, 0); scratch = serial_in(info, UART_IIR) >> 5; if (scratch == 6) state->type = PORT_16750; } --- 3359,3373 ---- if (state->type == PORT_16550A) { /* Check for TI 16750 */ serial_outp(info, UART_LCR, scratch2 | UART_LCR_DLAB); ! // switch to 64 byte mode: ! serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE); scratch = serial_in(info, UART_IIR) >> 5; + // 64 byte mode worked if (scratch == 7) { ! // test 16 byte mode: ! serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO); scratch = serial_in(info, UART_IIR) >> 5; + // 16 bit mode worked: if (scratch == 6) state->type = PORT_16750; } *** include/linux/serial_reg.h Sat Mar 6 14:26:06 1999 --- include/linux/serial_reg.h Sun Apr 25 01:40:28 1999 *************** *** 114,119 **** --- 114,127 ---- #define UART_MCR_OUT1 0x04 /* Out1 complement */ #define UART_MCR_RTS 0x02 /* RTS complement */ #define UART_MCR_DTR 0x01 /* DTR complement */ + #define UART_MCR_AFE 0x20 /* Enable 16750 autoflow */ + + // TI 16750 Autoflow (http://www.ti.com/sc/docs/products/analog/tl16c750.html) + // UART_MCR_AFE UART_MCR_RTS FLOW CONFIGURATION + // 1 1 Auto-RTS and Auto-CTS enable (autoflow enable) + // 1 0 Auto-CTS only enable + // 0 x Auto-RTS and auto-CTS disable + /* * These are the definitions for the Modem Status Register
| |