MachCtl-SVN | 25 Mar 09:18
Favicon

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 *);

Gmane