25 Mar 09:18
machctl: r21 - sys
Author: vedge Date: 2009-03-25 05:18:53 -0300 (Wed, 25 Mar 2009) New Revision: 21 Added: sys/cnc_lcd.c sys/cnc_lcd_isa.c sys/cnc_lcdvar.h Log: driver for LCDs via RS-232 interface; unlike the standard com driver we do not use interrupts so it is suitable for displaying real-time program status. Added: sys/cnc_lcd.c =================================================================== --- sys/cnc_lcd.c (rev 0) +++ sys/cnc_lcd.c 2009-03-25 08:18:53 UTC (rev 21) @@ -0,0 +1,545 @@ +/* + * Copyright (c) 2009 Hypertriton, Inc. <http://www.hypertriton.com/> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * Copyright (c) 1997 - 1999, Jason Downs. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +/*- + * Copyright (c) 1993, 1994, 1995, 1996 + * Charles M. Hannum. All rights reserved. + * Copyright (c) 1991 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)com.c 7.5 (Berkeley) 5/16/91 + */ + +/* + * 16450/16550 UART driver modified for text-based LCD output and polled-mode + * operation. This allows a standard serial link to be used in interfacing + * with common serial LCD control ICs such as the EDE700 or EDE702. + * + * Polled-mode operation is useful for debugging, and is the cnc(4) subsystem's + * only way of displaying information during program execution in real time. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/conf.h> +#include <sys/kernel.h> +#include <sys/device.h> +#include <sys/cnc.h> + +#include <machine/bus.h> + +#include <dev/ic/comreg.h> +#include <dev/ic/ns16550reg.h> +#define com_lcr com_cfcr + +#include <dev/cnc/cncvar.h> +#include <dev/cnc/cnc_devicevar.h> +#include <dev/cnc/cnc_lcdvar.h> + +struct cfdriver cnclcd_cd = { + NULL, "cnclcd", DV_DULL +}; + +void cnclcd_attach_fifo(struct cnclcd_softc *); + +void +cnclcd_attach(struct cnclcd_softc *sc) +{ + bus_space_tag_t iot = sc->sc_iot; + bus_space_handle_t ioh = sc->sc_ioh; + + /* Generic CNC device initialization. */ + if (cnc_device_attach(sc, CNC_DEVICE_LCD) == -1) + return; + + sc->sc_open = 0; + sc->sc_flags = 0; + + /* Disable interrupts */ + bus_space_write_1(iot, ioh, com_ier, 0); + + /* + * Probe for all known forms of UART. + */ + bus_space_write_1(iot, ioh, com_lcr, LCR_EFR); + bus_space_write_1(iot, ioh, com_efr, 0); + bus_space_write_1(iot, ioh, com_lcr, 0); + bus_space_write_1(iot, ioh, com_fifo, FIFO_ENABLE); + delay(100); + + /* + * Skip specific probes if attachment code knows it already. + */ + switch (bus_space_read_1(iot, ioh, com_iir) >> 6) { + case 0: + sc->sc_uarttype = COM_UART_16450; + break; + case 2: + sc->sc_uarttype = COM_UART_16550; + break; + case 3: + sc->sc_uarttype = COM_UART_16550A; + break; + default: + sc->sc_uarttype = COM_UART_UNKNOWN; + break; + } + + /* Read the LCR */ + sc->sc_lcr = bus_space_read_1(iot, ioh, com_lcr); + + if (sc->sc_uarttype == COM_UART_16550A) { /* Probe for ST16650s */ + bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr|LCR_DLAB); + if (bus_space_read_1(iot, ioh, com_efr) == 0) { + sc->sc_uarttype = COM_UART_ST16650; + } else { + bus_space_write_1(iot, ioh, com_lcr, LCR_EFR); + if (bus_space_read_1(iot, ioh, com_efr) == 0) + sc->sc_uarttype = COM_UART_ST16650V2; + } + } + if (sc->sc_uarttype == COM_UART_16550A) { /* Probe for TI16750s */ + bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr|LCR_DLAB); + bus_space_write_1(iot, ioh, com_fifo, + FIFO_ENABLE | FIFO_ENABLE_64BYTE); + if ((bus_space_read_1(iot, ioh, com_iir) >> 5) == 7) { +#if 0 + bus_space_write_1(iot, ioh, com_lcr, 0); + if ((bus_space_read_1(iot, ioh, com_iir) >> 5) == 6) +#endif + sc->sc_uarttype = COM_UART_TI16750; + } + bus_space_write_1(iot, ioh, com_fifo, FIFO_ENABLE); + } + + /* Reset the LCR (latch access is probably enabled). */ + bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr); + + if (sc->sc_uarttype == COM_UART_16450) { /* Probe for 8250 */ + u_int8_t scr0, scr1, scr2; + + scr0 = bus_space_read_1(iot, ioh, com_scratch); + bus_space_write_1(iot, ioh, com_scratch, 0xa5); + scr1 = bus_space_read_1(iot, ioh, com_scratch); + bus_space_write_1(iot, ioh, com_scratch, 0x5a); + scr2 = bus_space_read_1(iot, ioh, com_scratch); + bus_space_write_1(iot, ioh, com_scratch, scr0); + + if ((scr1 != 0xa5) || (scr2 != 0x5a)) + sc->sc_uarttype = COM_UART_8250; + } + + /* + * Print UART type and initialize ourself. + */ + sc->sc_fifolen = 0; + switch (sc->sc_uarttype) { + case COM_UART_UNKNOWN: + printf(": unknown uart\n"); + break; + case COM_UART_8250: + printf(": ns8250, no fifo\n"); + break; + case COM_UART_16450: + printf(": ns16450, no fifo\n"); + break; + case COM_UART_16550: + printf(": ns16550, no working fifo\n"); + break; + case COM_UART_16550A: + sc->sc_fifolen = 16; + printf(": ns16550a, %d byte fifo\n", sc->sc_fifolen); + SET(sc->sc_hwflags, COM_HW_FIFO); + break; + case COM_UART_ST16650: + printf(": st16650, no working fifo\n"); + break; + case COM_UART_ST16650V2: + sc->sc_fifolen = 32; + printf(": st16650, %d byte fifo\n", sc->sc_fifolen); + SET(sc->sc_hwflags, COM_HW_FIFO); + break; + case COM_UART_ST16C654: + printf(": st16c654, 64 byte fifo\n"); + SET(sc->sc_hwflags, COM_HW_FIFO); + sc->sc_fifolen = 64; + break; + case COM_UART_TI16750: + printf(": ti16750, 64 byte fifo\n"); + SET(sc->sc_hwflags, COM_HW_FIFO); + sc->sc_fifolen = 64; + break; + default: + panic("cnclcd_attach: bad fifo type"); + } + + if (ISSET(sc->sc_hwflags, COM_HW_FIFO)) { + cnclcd_attach_fifo(sc); + } + if (sc->sc_fifolen == 0) { + CLR(sc->sc_hwflags, COM_HW_FIFO); + sc->sc_fifolen = 1; + } + + /* clear and disable fifo */ + bus_space_write_1(iot, ioh, com_fifo, FIFO_RCV_RST | FIFO_XMT_RST); + (void)bus_space_read_1(iot, ioh, com_data); + bus_space_write_1(iot, ioh, com_fifo, 0); + + sc->sc_msr = 0; + sc->sc_mcr = bus_space_read_1(iot, ioh, com_mcr); +} + +void +cnclcd_attach_fifo(struct cnclcd_softc *sc) +{ + bus_space_handle_t ioh = sc->sc_ioh; + bus_space_tag_t iot = sc->sc_iot; + u_int8_t fifo; + int timo, len; + + bus_space_write_1(iot, ioh, com_ier, 0); + bus_space_write_1(iot, ioh, com_lcr, LCR_DLAB); + bus_space_write_1(iot, ioh, com_dlbl, 3); + bus_space_write_1(iot, ioh, com_dlbh, 0); + bus_space_write_1(iot, ioh, com_lcr, LCR_PNONE | LCR_8BITS); + bus_space_write_1(iot, ioh, com_mcr, MCR_LOOPBACK); + + fifo = FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST; + if (sc->sc_uarttype == COM_UART_TI16750) + fifo |= FIFO_ENABLE_64BYTE; + + bus_space_write_1(iot, ioh, com_fifo, fifo); + + for (len = 0; len < 256; len++) { + bus_space_write_1(iot, ioh, com_data, (len + 1)); + timo = 2000; + while (!ISSET(bus_space_read_1(iot, ioh, com_lsr), + LSR_TXRDY) && --timo) + delay(1); + if (!timo) + break; + } + + delay(100); + + for (len = 0; len < 256; len++) { + timo = 2000; + while (!ISSET(bus_space_read_1(iot,ioh,com_lsr),LSR_RXRDY) && + --timo) { + delay(1); + } + if (!timo || bus_space_read_1(iot, ioh, com_data) != (len + 1)) + break; + } + + /* For safety, always use the smaller value. */ + if (sc->sc_fifolen > len) { + sc->sc_fifolen = len; + } + printf("%s: probed fifo depth: %d bytes\n", + ((struct device *)sc)->dv_xname, len); +} + +int +cnclcd_speed(long freq, long speed) +{ +#define divrnd(n, q) (((n)*2/(q)+1)/2) /* divide and round off */ + + int x, err; + + if (speed == 0) { return (0); } + if (speed < 0) { return (-1); } + x = divrnd((freq / 16), speed); + if (x <= 0) { return (-1); } + err = divrnd((quad_t)freq * 1000 / 16, speed * x) - 1000; + if (err < 0) { err = -err; } + if (err > COM_TOLERANCE) { return (-1); } + return (x); +#undef divrnd +} + +int +cnclcd_open(struct cnclcd_softc *sc, int speed, int bits, + enum cnclcd_parity parity, int stopbits) +{ + bus_space_tag_t iot = sc->sc_iot; + bus_space_handle_t ioh = sc->sc_ioh; + int s, rate; + + if (sc->sc_open) + return (-1); + + s = spltty(); + sc->sc_speed = speed; + + /* Clear DTR */ + CLR(sc->sc_mcr, MCR_DTR); + bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr); + + /* Configure bits */ + CLR(sc->sc_lcr, LCR_5BITS); + CLR(sc->sc_lcr, LCR_6BITS); + CLR(sc->sc_lcr, LCR_7BITS); + CLR(sc->sc_lcr, LCR_8BITS); + switch (bits) { + case 5: SET(sc->sc_lcr, LCR_5BITS); break; + case 6: SET(sc->sc_lcr, LCR_6BITS); break; + case 7: SET(sc->sc_lcr, LCR_7BITS); break; + case 8: SET(sc->sc_lcr, LCR_8BITS); break; + default: break; + } + + /* Configure parity and stop bits */ + if (parity != CNCLCD_PNONE) { + SET(sc->sc_lcr, LCR_PENAB); + switch (parity) { + case CNCLCD_PZERO: SET(sc->sc_lcr, LCR_PZERO); break; + case CNCLCD_PONE: SET(sc->sc_lcr, LCR_PONE); break; + case CNCLCD_PEVEN: SET(sc->sc_lcr, LCR_PEVEN); break; + case CNCLCD_PODD: SET(sc->sc_lcr, LCR_PODD); break; + default: panic("cnclcd_open: parity"); + } + } else { + CLR(sc->sc_lcr, LCR_PENAB); + CLR(sc->sc_lcr, LCR_PZERO); + CLR(sc->sc_lcr, LCR_PONE); + CLR(sc->sc_lcr, LCR_PEVEN); + CLR(sc->sc_lcr, LCR_PODD); + } + if (stopbits == 2) { + SET(sc->sc_lcr, LCR_STOPB); + } else { + CLR(sc->sc_lcr, LCR_STOPB); + } + bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr); + + /* Configure speed */ + bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr|LCR_DLAB); + rate = cnclcd_speed(COM_FREQ, sc->sc_speed); + bus_space_write_1(iot, ioh, com_dlbl, rate); + bus_space_write_1(iot, ioh, com_dlbh, rate >> 8); + bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr); + + /* Set the FIFO threshold based on the speed. */ + if (ISSET(sc->sc_hwflags, COM_HW_FIFO)) { + if (sc->sc_uarttype == COM_UART_TI16750) { + bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr|LCR_DLAB); + bus_space_write_1(iot, ioh, com_fifo, + FIFO_ENABLE | FIFO_ENABLE_64BYTE | + (sc->sc_speed <= 1200 ? FIFO_TRIGGER_1 : FIFO_TRIGGER_8)); + bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr); + } else { + bus_space_write_1(iot, ioh, com_fifo, + FIFO_ENABLE | + (sc->sc_speed <= 1200 ? FIFO_TRIGGER_1 : FIFO_TRIGGER_8)); + } + } else { + bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr); + } + + /* + * Wake up the sleepy heads. + */ + switch (sc->sc_uarttype) { + case COM_UART_ST16650: + case COM_UART_ST16650V2: + bus_space_write_1(iot, ioh, com_lcr, LCR_EFR); + bus_space_write_1(iot, ioh, com_efr, EFR_ECB); + bus_space_write_1(iot, ioh, com_ier, 0); + bus_space_write_1(iot, ioh, com_efr, 0); + bus_space_write_1(iot, ioh, com_lcr, 0); + break; + case COM_UART_TI16750: + bus_space_write_1(iot, ioh, com_ier, 0); + break; + } + + if (ISSET(sc->sc_hwflags, COM_HW_FIFO)) { + u_int8_t fifo = FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST; + + if (sc->sc_speed <= 1200) { + fifo |= FIFO_TRIGGER_1; + } else { + fifo |= FIFO_TRIGGER_8; + } + if (sc->sc_uarttype == COM_UART_TI16750) { + fifo |= FIFO_ENABLE_64BYTE; + bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr|LCR_DLAB); + } + + /* + * (Re)enable and drain FIFOs. + * + * Certain SMC chips cause problems if the FIFOs are + * enabled while input is ready. Turn off the FIFO + * if necessary to clear the input. Test the input + * ready bit after enabling the FIFOs to handle races + * between enabling and fresh input. + * + * Set the FIFO threshold based on the receive speed. + */ + for (;;) { + bus_space_write_1(iot, ioh, com_fifo, 0); + delay(100); + (void)bus_space_read_1(iot, ioh, com_data); + bus_space_write_1(iot, ioh, com_fifo, + fifo | FIFO_RCV_RST | FIFO_XMT_RST); + delay(100); + if (!ISSET(bus_space_read_1(iot,ioh,com_lsr),LSR_RXRDY)) + break; + } + if (sc->sc_uarttype == COM_UART_TI16750) + bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr); + } + + /* Flush any pending I/O. */ + while (ISSET(bus_space_read_1(iot, ioh, com_lsr), LSR_RXRDY)) + (void)bus_space_read_1(iot, ioh, com_data); + + /* Set DTR|RTS */ + SET(sc->sc_mcr, MCR_DTR|MCR_RTS); + bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_mcr, sc->sc_mcr); + + /* Read initial MSR */ + sc->sc_msr = bus_space_read_1(iot, ioh, com_msr); + + sc->sc_open = 1; + splx(s); + return (0); +} + +int +cnclcd_close(struct cnclcd_softc *sc) +{ + int s; + + s = spltty(); + if (sc->sc_open) { + CLR(sc->sc_mcr, MCR_DTR|MCR_RTS); + bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_mcr, sc->sc_mcr); + sc->sc_open = 0; + } + splx(s); + return (0); +} + +void +cnclcd_puts(struct cnclcd_softc *sc, const char *s) +{ + const char *c; + + for (c = &s[0]; *c != '\0'; c++) + cnclcd_putc(sc, *c); +} + +void +cnclcd_putc(struct cnclcd_softc *sc, int c) +{ + bus_space_tag_t iot = sc->sc_iot; + bus_space_handle_t ioh = sc->sc_ioh; + int timo; + + /* Wait for any pending transmission to finish. */ + timo = 2000; + while (!ISSET(bus_space_read_1(iot,ioh,com_lsr),LSR_TXRDY) && --timo) + delay(1); + + bus_space_write_1(iot, ioh, com_data, (u_int8_t)(c & 0xff)); + bus_space_barrier(iot, ioh, 0, COM_NPORTS, + (BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE)); + + /* Wait for this transmission to complete. */ + timo = 2000; + while (!ISSET(bus_space_read_1(iot,ioh,com_lsr),LSR_TXRDY) && --timo) + delay(1); +} + +#if 0 +void +cnclcd_init(bus_space_tag_t iot, bus_space_handle_t ioh, int rate, int frequency) +{ + int s; + + s = splhigh(); + bus_space_write_1(iot, ioh, com_lcr, LCR_DLAB); + rate = cnclcd_speed(frequency, rate); /* XXX not cnclcd_default_rate? */ + bus_space_write_1(iot, ioh, com_dlbl, rate); + bus_space_write_1(iot, ioh, com_dlbh, rate >> 8); + bus_space_write_1(iot, ioh, com_lcr, LCR_8BITS); + bus_space_write_1(iot, ioh, com_mcr, MCR_DTR | MCR_RTS); + bus_space_write_1(iot, ioh, com_ier, 0); /* Make sure they are off */ + bus_space_write_1(iot, ioh, com_fifo, + FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_1); + splx(s); +} +#endif Added: sys/cnc_lcd_isa.c =================================================================== --- sys/cnc_lcd_isa.c (rev 0) +++ sys/cnc_lcd_isa.c 2009-03-25 08:18:53 UTC (rev 21) @@ -0,0 +1,160 @@ +/* + * Copyright (c) 1997 - 1999, Jason Downs. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name(s) of the author(s) nor the name OpenBSD + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +/*- + * Copyright (c) 1993, 1994, 1995, 1996 + * Charles M. Hannum. All rights reserved. + * Copyright (c) 1991 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)com.c 7.5 (Berkeley) 5/16/91 + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/device.h> +#include <sys/cnc.h> + +#include <machine/bus.h> + +#include <dev/cnc/cncvar.h> +#include <dev/cnc/cnc_devicevar.h> +#include <dev/cnc/cnc_lcdvar.h> + +#include <dev/isa/isavar.h> + +#include <dev/ic/comreg.h> +#include <dev/ic/ns16550reg.h> +#define com_lcr com_cfcr + +int cnclcd_isa_match(struct device *, void *, void *); +void cnclcd_isa_attach(struct device *, struct device *, void *); +int cnclcd_isa_detach(struct device *, int); +int cnclcd_isa_activate(struct device *, enum devact); + +struct cfattach cnclcd_isa_ca = { + sizeof(struct cnclcd_softc), + cnclcd_isa_match, + cnclcd_isa_attach, + cnclcd_isa_detach, + cnclcd_isa_activate +}; + +int +cnclcd_isa_match(struct device *parent, void *match, void *aux) +{ + struct isa_attach_args *ia = aux; + bus_space_handle_t ioh; + bus_space_tag_t iot; + int iobase; + int i, k; + + iot = ia->ia_iot; + iobase = ia->ia_iobase; + + if (bus_space_map(iot, iobase, COM_NPORTS, 0, &ioh)) + return (0); + + /* Force access to id register. */ + bus_space_write_1(iot, ioh, com_lcr, 0); + bus_space_write_1(iot, ioh, com_iir, 0); + for (i = 0; i < 32; i++) { + k = bus_space_read_1(iot, ioh, com_iir); + if (k & 0x38) { + bus_space_read_1(iot, ioh, com_data); /* cleanup */ + } else { + break; + } + } + bus_space_unmap(iot, ioh, COM_NPORTS); + if (i >= 32) { + return (0); + } + ia->ia_iosize = COM_NPORTS; + ia->ia_msize = 0; + return (1); +} + +void +cnclcd_isa_attach(struct device *parent, struct device *self, void *aux) +{ + struct cnclcd_softc *sc = (struct cnclcd_softc *)self; + struct isa_attach_args *ia = aux; + bus_space_handle_t ioh; + bus_space_tag_t iot; + int iobase; + + sc->sc_hwflags = 0; + + iobase = ia->ia_iobase; + iot = ia->ia_iot; + + if (bus_space_map(iot, iobase, COM_NPORTS, 0, &ioh)) + panic("cnclcd_isa_attach: mapping failed"); + + sc->sc_iot = iot; + sc->sc_ioh = ioh; + sc->sc_iobase = iobase; + + cnclcd_attach(sc); +} + +int +cnclcd_isa_detach(struct device *self, int flags) +{ + return cnc_device_detach(self); +} + +int +cnclcd_isa_activate(struct device *self, enum devact act) +{ + return cnc_device_activate(self); +} Added: sys/cnc_lcdvar.h =================================================================== --- sys/cnc_lcdvar.h (rev 0) +++ sys/cnc_lcdvar.h 2009-03-25 08:18:53 UTC (rev 21) @@ -0,0 +1,112 @@ +/* + * Copyright (c) 1997 - 1998, Jason Downs. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +/* + * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Christopher G. Demetriou + * for the NetBSD Project. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +enum cnclcd_parity { + CNCLCD_PZERO, /* Space */ + CNCLCD_PONE, /* Mark */ + CNCLCD_PEVEN, /* Even */ + CNCLCD_PODD, /* Odd */ + CNCLCD_PNONE /* No parity */ +}; + +#define CNC_LCD_IBUFSIZE (2 * 512) +#define CNC_LCD_IHIGHWATER ((3 * CNC_LCD_IBUFSIZE) / 4) + +struct cnclcd_softc { + struct cnc_device sc_cdev; + bus_space_tag_t sc_iot; + bus_space_handle_t sc_ioh; + bus_addr_t sc_iobase; /* For bus-specific layer */ + + u_char sc_flags; +#define CNCLCD_USE_CRTSCTS 0x01 /* Use CRTSCTS */ + + int sc_open; /* UART is initialized */ + int sc_speed; /* Baud rate */ + + u_char sc_uarttype; +#define COM_UART_UNKNOWN 0x00 /* unknown */ +#define COM_UART_8250 0x01 /* no fifo */ +#define COM_UART_16450 0x02 /* no fifo */ +#define COM_UART_16550 0x03 /* no working fifo */ +#define COM_UART_16550A 0x04 /* 16 byte fifo */ +#define COM_UART_ST16650 0x05 /* no working fifo */ +#define COM_UART_ST16650V2 0x06 /* 32 byte fifo */ +#define COM_UART_TI16750 0x07 /* 64 byte fifo */ +#define COM_UART_ST16C654 0x08 /* 64 bytes fifo */ +#define COM_UART_XR16850 0x10 /* 128 byte fifo */ +#define COM_UART_PXA2X0 0x11 /* 16 byte fifo */ +#define COM_UART_OX16C950 0x12 /* 128 byte fifo */ + + u_char sc_hwflags; +#define COM_HW_FIFO 0x02 +#define COM_HW_SIR 0x20 + + int sc_fifolen; /* FIFO length in bytes */ + u_char sc_msr; /* MODEM Status Register */ + u_char sc_mcr; /* MODEM Control Register */ + u_char sc_lcr; /* Line Control Register */ +}; + +void cnclcd_attach(struct cnclcd_softc *); +int cnclcd_activate(struct device *, enum devact); + +int cnclcd_speed(long, long); +void cnclcd_start(struct cnclcd_softc *); +void cnclcd_puts(struct cnclcd_softc *, const char *); +void cnclcd_putc(struct cnclcd_softc *, int); +void cnclcd_set_dtr_rts(void *, int); + +int cnclcd_open(struct cnclcd_softc *, int, int, enum cnclcd_parity, int); +int cnclcd_close(struct cnclcd_softc *);
RSS Feed