diff options
| author | hauke <hauke@NetBSD.org> | 2008-05-22 19:49:43 +0000 |
|---|---|---|
| committer | hauke <hauke@NetBSD.org> | 2008-05-22 19:49:43 +0000 |
| commit | f5ede5dc2e30f76dd40b9f82eeb4092957f2e30f (patch) | |
| tree | bbcfa0a357e835b5393670e754309f9ea466ae9b /sys | |
| parent | 1f2b983e85485198a6e39185c189883697583598 (diff) | |
Added driver for the Creative Systems Inc. Hurdler CPI parallel printer card.
Timecounter support for the Z8536 counters A + B is not complete, yet.
Reviewed by Martin Husemann.
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/arch/mac68k/conf/GENERIC | 10 | ||||
| -rw-r--r-- | sys/arch/mac68k/conf/files.mac68k | 6 | ||||
| -rw-r--r-- | sys/arch/mac68k/conf/majors.mac68k | 3 | ||||
| -rw-r--r-- | sys/arch/mac68k/nubus/cpi_nubus.c | 770 | ||||
| -rw-r--r-- | sys/arch/mac68k/nubus/cpi_nubusvar.h | 88 | ||||
| -rw-r--r-- | sys/arch/macppc/stand/ofwboot/Makefile | 4 | ||||
| -rw-r--r-- | sys/arch/macppc/stand/ofwboot/ofdev.c | 23 | ||||
| -rw-r--r-- | sys/dev/ic/z8536reg.h | 244 |
8 files changed, 1134 insertions, 14 deletions
diff --git a/sys/arch/mac68k/conf/GENERIC b/sys/arch/mac68k/conf/GENERIC index 7e1b4ae6aa4..45d8772020d 100644 --- a/sys/arch/mac68k/conf/GENERIC +++ b/sys/arch/mac68k/conf/GENERIC @@ -1,4 +1,4 @@ -# $NetBSD: GENERIC,v 1.186 2007/12/31 15:31:58 ad Exp $ +# $NetBSD: GENERIC,v 1.187 2008/05/22 19:49:43 hauke Exp $ # # GENERIC machine description file # @@ -22,7 +22,7 @@ include "arch/mac68k/conf/std.mac68k" options INCLUDE_CONFIG_FILE # embed config file in kernel binary -#ident "GENERIC-$Revision: 1.186 $" +#ident "GENERIC-$Revision: 1.187 $" maxusers 16 # estimated number of users @@ -227,6 +227,12 @@ wskbd* at akbd? console ? wsmouse* at ams? +# Centronics printer port + +# CSI Hurdler Centronics Parallel Interface +cpi* at nubus? + + # Serial Devices # On-board serial interface diff --git a/sys/arch/mac68k/conf/files.mac68k b/sys/arch/mac68k/conf/files.mac68k index e79ae14d6a0..bcd4364c45f 100644 --- a/sys/arch/mac68k/conf/files.mac68k +++ b/sys/arch/mac68k/conf/files.mac68k @@ -1,4 +1,4 @@ -# $NetBSD: files.mac68k,v 1.121 2008/02/20 21:43:34 drochner Exp $ +# $NetBSD: files.mac68k,v 1.122 2008/05/22 19:49:43 hauke Exp $ # mac68k-specific configuration info @@ -131,6 +131,10 @@ include "dev/ata/files.ata" attach wdc at obio with wdc_obio file arch/mac68k/obio/wdc_obio.c wdc_obio +device cpi { } +attach cpi at nubus +file arch/mac68k/nubus/cpi_nubus.c cpi + device zsc { channel = -1 } attach zsc at obio file arch/mac68k/dev/zs.c zsc needs-flag diff --git a/sys/arch/mac68k/conf/majors.mac68k b/sys/arch/mac68k/conf/majors.mac68k index e979f1adb9f..e8804522dca 100644 --- a/sys/arch/mac68k/conf/majors.mac68k +++ b/sys/arch/mac68k/conf/majors.mac68k @@ -1,4 +1,4 @@ -# $NetBSD: majors.mac68k,v 1.19 2007/12/31 15:31:59 ad Exp $ +# $NetBSD: majors.mac68k,v 1.20 2008/05/22 19:49:43 hauke Exp $ # # Device majors for mac68k # @@ -49,6 +49,7 @@ device-major wd char 49 block 22 wd device-major cgd char 51 block 23 cgd device-major ksyms char 52 ksyms device-major wsfont char 53 wsfont +device-major cpi char 54 cpi device-major nsmb char 98 nsmb diff --git a/sys/arch/mac68k/nubus/cpi_nubus.c b/sys/arch/mac68k/nubus/cpi_nubus.c new file mode 100644 index 00000000000..616278d371b --- /dev/null +++ b/sys/arch/mac68k/nubus/cpi_nubus.c @@ -0,0 +1,770 @@ +/* $NetBSD */ + +/*- + * Copyright (c) 2008 Hauke Fath + * + * 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 ``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. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: cpi_nubus.c,v 1.1 2008/05/22 19:49:43 hauke Exp $"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/proc.h> +#include <sys/device.h> +#include <sys/malloc.h> +#include <sys/event.h> +#include <sys/callout.h> +#include <sys/conf.h> +#include <sys/file.h> +#include <sys/uio.h> +#include <sys/ioctl.h> +#include <sys/tty.h> +#include <sys/time.h> +#include <sys/kernel.h> +#include <sys/syslog.h> +#include <sys/errno.h> + +#include <machine/intr.h> +#include <machine/bus.h> +#include <machine/viareg.h> + +#include <dev/ic/z8536reg.h> +#include <mac68k/nubus/nubus.h> +#include <mac68k/nubus/cpi_nubusvar.h> + +#include "ioconf.h" + +#ifdef DEBUG +#define CPI_DEBUG +#endif + +/* + * Stuff taken from Egan/Teixeira ch 8: 'if(TRACE_FOO)' debug output + * statements don't break indentation, and when DEBUG is not defined, + * the compiler code optimizer drops them as dead code. + */ +#ifdef CPI_DEBUG +#define M_TRACE_CONFIG 0x0001 +#define M_TRACE_OPEN 0x0002 +#define M_TRACE_CLOSE 0x0004 +#define M_TRACE_READ 0x0008 +#define M_TRACE_WRITE 0x0010 +#define M_TRACE_IOCTL 0x0020 +#define M_TRACE_STATUS 0x0040 +#define M_TRACE_ALL 0xFFFF +#define M_TRACE_NONE 0x0000 + +#define TRACE_CONFIG (cpi_debug_mask & M_TRACE_CONFIG) +#define TRACE_OPEN (cpi_debug_mask & M_TRACE_OPEN) +#define TRACE_CLOSE (cpi_debug_mask & M_TRACE_CLOSE) +#define TRACE_READ (cpi_debug_mask & M_TRACE_READ) +#define TRACE_WRITE (cpi_debug_mask & M_TRACE_WRITE) +#define TRACE_IOCTL (cpi_debug_mask & M_TRACE_IOCTL) +#define TRACE_STATUS (cpi_debug_mask & M_TRACE_STATUS) +#define TRACE_ALL (cpi_debug_mask & M_TRACE_ALL) +#define TRACE_NONE (cpi_debug_mask & M_TRACE_NONE) + +uint32_t cpi_debug_mask = M_TRACE_NONE /* | M_TRACE_WRITE */ ; + +#else +#define TRACE_CONFIG 0 +#define TRACE_OPEN 0 +#define TRACE_CLOSE 0 +#define TRACE_READ 0 +#define TRACE_WRITE 0 +#define TRACE_IOCTL 0 +#define TRACE_STATUS 0 +#define TRACE_ALL 0 +#define TRACE_NONE 0 +#endif + +#undef USE_CIO_TIMERS /* TBD */ + +/* autoconf interface */ +int cpi_nubus_match(device_t, cfdata_t, void *); +void cpi_nubus_attach(device_t, device_t, void *); +void cpi_nubus_intr(void *); + +CFATTACH_DECL(cpi, sizeof(struct cpi_softc), + cpi_nubus_match, cpi_nubus_attach, NULL, NULL); + +dev_type_open(cpi_open); +dev_type_close(cpi_close); +dev_type_read(cpi_read); +dev_type_write(cpi_write); +dev_type_ioctl(cpi_ioctl); + +const struct cdevsw cpi_cdevsw = { + cpi_open, cpi_close, noread, cpi_write, cpi_ioctl, + nostop, notty, nopoll, nommap, nokqfilter, D_OTHER +}; + +/* prototypes */ +static void cpi_lpreset(struct cpi_softc *); +static int cpi_notready(struct cpi_softc *); +static void cpi_wakeup(void *); +static int cpi_flush(struct cpi_softc *); +static void cpi_intr(void *); + +#ifdef USE_CIO_TIMERS +static void cpi_initclock(struct cpi_softc *); +static u_int cpi_get_timecount(struct timecounter *); +#endif + +static inline void z8536_reg_set(bus_space_tag_t, bus_space_handle_t, + uint8_t, uint8_t); +static inline uint8_t z8536_reg_get(bus_space_tag_t, bus_space_handle_t, + uint8_t); + + +const uint8_t cio_reset[] = { + /* register value */ + Z8536_MICR, 0x00, + Z8536_MICR, MICR_RESET, + Z8536_MICR, 0x00 +}; + +const uint8_t cio_init[] = { + /* register value */ + + /* Interrupt vectors - clear all */ + Z8536_IVRA, 0x00, + Z8536_IVRB, 0x00, + Z8536_IVRCT, 0x20 /* ??? Do we use this? */, + + /* + * Port A specification - bit port, single buffered, + * latched output, pulsed handshake, all bits non-inverting + * non-special I/O + */ + Z8536_PMSRA, PMSR_PTS_OUT | PMSR_LPM, + Z8536_PHSRA, PHSR_HTS_PUL, + Z8536_DPPRA, 0x00, + Z8536_DDRA, 0x00, + Z8536_SIOCRA, 0x00, + + /* + * Port B specification - bit port, transparent output, + * pulsed handshake, all bits non-inverting + * bits 0, 4 output; bits 1-3, 5-8 input, + * non-special I/O + * Pattern matching: Bit 6 (BUSY) matching "1" + * Alternatively: Bit 3 (/ACK) matching "0" + */ + Z8536_PMSRB, PMSR_PMS_OR_PEV, + Z8536_PHSRB, 0x00, + Z8536_DPPRB, 0x00, + Z8536_DDRB, 0xee /*11101110b*/, + Z8536_SIOCRB, 0x00, + Z8536_PPRB, 0x00, + Z8536_PTRB, 0x00, + Z8536_PMRB, 0x40 /*01000000b = PB6 */, + + Z8536_PDRB, 0xFE, /* Assign printer -RESET */ + Z8536_PCSRA, 0x00, /* Clear port A interrupt bits */ + + /* + * Port C specification - bit 3 out, bits 0-2 in, + * all 4 non-inverting, non-special I/O + */ + Z8536_DDRC, 0x07 /*00000111b*/, + Z8536_DPPRC, 0x00, + Z8536_SIOCRC, 0x00, + +#ifdef USE_CIO_TIMERS + /* + * Counter/Timers 1+2 are joined to form a free-running + * 32 bit timecounter + */ + Z8536_CTMSR1, CTMS_CSC, + Z8536_CTTCR1_MSB, 0x00, + Z8536_CTTCR1_LSB, 0x00, + Z8536_CTMSR2, CTMS_CSC, + Z8536_CTTCR2_MSB, 0x00, + Z8536_CTTCR2_LSB, 0x00, +#endif /* USE_CIO_TIMERS */ + + /* + * We need Timer 3 for running port A in strobed mode. + * + * Counter/Timer 3 specification -- clear IP & IUS, trigger + + * gate command bit, one-shot operation + */ + Z8536_CTCSR3, CTCS_CLR_IP_IUS | CTCS_GCB | CTCS_TCB, + Z8536_CTMSR3, CTMS_DCS_ONESHOT, + Z8536_CTTCR3_MSB, 0x00, + Z8536_CTTCR3_LSB, 0x03, + + /* + * Enable ports A+B+C+CT3 + * Set timer 1 to clock timer 2, but not yet enabled. + */ + Z8536_MCCR, MCCR_PAE | MCCR_PBE | MCCR_CT1CT2 | MCCR_PC_CT3E, + /* Master Interrupt Enable, Disable Lower Chain, + * No Vector, port A+B+CT vectors include status */ + Z8536_MICR, MICR_MIE | MICR_DLC | MICR_NV | MICR_PAVIS | + MICR_PBVIS | MICR_CTVIS, + Z8536_PDRB, 0xFE, /* Clear printer -RESET */ +}; + + +/* + * Look for Creative Systems Inc. "Hurdler Centronics Parallel Interface" + */ +int +cpi_nubus_match(device_t parent, cfdata_t cf, void *aux) +{ + struct nubus_attach_args *na; + + na = aux; + if ((na->category == NUBUS_CATEGORY_COMMUNICATIONS) && + (na->type == NUBUS_TYPE_CENTRONICS) && + (na->drsw == NUBUS_DRSW_CPI) && + (na->drhw == NUBUS_DRHW_CPI)) + return 1; + else + return 0; +} + +void +cpi_nubus_attach(device_t parent, device_t self, void *aux) +{ + struct cpi_softc *sc; + struct nubus_attach_args *na; + int err, ii; + + sc = device_private(self); + na = aux; + sc->sc_bst = na->na_tag; + memcpy(&sc->sc_slot, na->fmt, sizeof(nubus_slot)); + sc->sc_basepa = (bus_addr_t)NUBUS_SLOT2PA(na->slot); + + /* + * The CIO sits on the MSB (top byte lane) of the 32 bit + * Nubus, so map 16 byte. + */ + if (TRACE_CONFIG) { + printf("\n"); + printf("\tcpi_nubus_attach() mapping 8536 CIO at 0x%lx.\n", + sc->sc_basepa + CIO_BASE_OFFSET); + } + + err = bus_space_map(sc->sc_bst, sc->sc_basepa + CIO_BASE_OFFSET, + (Z8536_IOSIZE << 4), 0, &sc->sc_bsh); + if (err) { + aprint_normal(": failed to map memory space.\n"); + return; + } + + sc->sc_lpstate = LP_INITIAL; + sc->sc_intcount = 0; + sc->sc_bytestoport = 0; + + if (TRACE_CONFIG) + printf("\tcpi_nubus_attach() about to set up 8536 CIO.\n"); + + for (ii = 0; ii < sizeof(cio_reset); ii += 2) + z8536_reg_set(sc->sc_bst, sc->sc_bsh, cio_reset[ii], + cio_reset[ii + 1]); + + delay(1000); /* Just in case */ + for (ii = 0; ii < sizeof(cio_init); ii += 2) { + z8536_reg_set(sc->sc_bst, sc->sc_bsh, cio_init[ii], + cio_init[ii + 1]); + } + + if (TRACE_CONFIG) + printf("\tcpi_nubus_attach() done with 8536 CIO setup.\n"); + + /* XXX Get the information strings from the card's ROM */ + aprint_normal(": CSI Hurdler II Centronics\n"); + +#ifdef USE_CIO_TIMERS + /* Attach CIO timers as timecounters */ + if (TRACE_CONFIG) + printf("\tcpi_nubus_attach() about to attach timers\n"); + + cpi_initclock(sc); +#endif /* USE_CIO_TIMERS */ + + callout_init(&sc->sc_wakeupchan, 0); /* XXX */ + + /* make sure interrupts are vectored to us */ + add_nubus_intr(na->slot, cpi_nubus_intr, sc); +} + +void +cpi_nubus_intr(void *arg) +{ + struct cpi_softc *sc; + int s; + + sc = (struct cpi_softc *)arg; + + s = spltty(); + + sc->sc_intcount++; + + /* Check for interrupt source, and clear interrupt */ + + /* + * Clear port A interrupt + * Interrupt from register A, clear "pending" + * and set "under service" + */ + z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_PCSRA, PCSR_CLR_IE); + z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_PCSRA, PCSR_CLR_IP); + z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_PCSRA, PCSR_SET_IUS); + + cpi_intr(sc); + + /* Interrupt from register A, mark serviced */ + z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_PCSRA, PCSR_CLR_IUS); + z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_PCSRA, PCSR_SET_IE); + + splx(s); +} + + +/* cpi nuts and bolts */ + +int +cpi_open(dev_t device, int flag, int mode, struct lwp *l) +{ + int lpunit; + int err, ii, s; + struct cpi_softc *sc; + + if (TRACE_OPEN) + printf("\tcpi_open() called...\n"); + + /* Consistency checks: Valid unit number, softc, device state */ + lpunit = CPI_UNIT(device); + if (lpunit >= cpi_cd.cd_ndevs) { + if (TRACE_OPEN) + printf("Tried to cpi_open() invalid unit (%d >= %d)\n", + lpunit, cpi_cd.cd_ndevs); + return ENXIO; + } + sc = device_lookup(&cpi_cd, lpunit); + if (NULL == sc) { + if (TRACE_OPEN) + printf("Tried to cpi_open() with NULL softc\n"); + return ENXIO; + } + if (sc->sc_lpstate != LP_INITIAL) { + if (TRACE_OPEN) + printf("%s not in initial state (%x).\n", + sc->sc_dev.dv_xname, sc->sc_lpstate); + return EBUSY; + } + sc->sc_lpstate = LP_OPENING; + + if (TRACE_OPEN) + printf("\tcpi_open() resetting the printer...\n"); + cpi_lpreset(sc); + + if (TRACE_OPEN) + printf("\tcpi_open() waiting for printer ready...\n"); + + /* Wait max 15 sec for printer to get ready */ + for (ii = 15; cpi_notready(sc); ii--) { + if (0 == ii) { + sc->sc_lpstate = LP_INITIAL; + return EBUSY; + } + /* sleep for a second, unless we get a signal */ + err = ltsleep(sc, PZERO | PCATCH, "cpi_open", hz, NULL); + if (err != EWOULDBLOCK) { + sc->sc_lpstate = LP_INITIAL; + return err; + } + } + if (TRACE_OPEN) + printf("\tcpi_open() allocating printer buffer...\n"); + + /* Allocate the driver's line buffer */ + sc->sc_printbuf = malloc(CPI_BUFSIZE, M_DEVBUF, M_WAITOK); + sc->sc_bufbytes = 0; + sc->sc_lpstate = LP_OPEN; + + /* Statistics */ + sc->sc_intcount = 0; + sc->sc_bytestoport = 0; + + /* Kick off transfer */ + cpi_wakeup(sc); + + /* + * Reset "interrupt {pending, under service}" bits, then + * enable Port A interrupts + */ + s = spltty(); + + z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_PCSRA, PCSR_CLR_IP_IUS); + z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_PCSRA, PCSR_SET_IE); + splx(s); + + if (TRACE_OPEN) + printf("\tcpi_open() done...\n"); + + return 0; +} + +int +cpi_close(dev_t device, int flag, int mode, struct lwp *l) +{ + struct cpi_softc *sc; + int lpunit; + + lpunit = CPI_UNIT(device); + sc = device_lookup(&cpi_cd, lpunit); + + if (TRACE_CLOSE) + printf("\tcpi_close() called (%lu hard, %lu bytes to port)\n", + sc->sc_intcount, sc->sc_bytestoport); + + /* Flush the remaining buffer content, ignoring any errors */ + if (0 < sc->sc_bufbytes) + (void)cpi_flush(sc); + + callout_stop(&sc->sc_wakeupchan); + + /* Disable Port A interrupts */ + z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_PCSRA, PCSR_CLR_IE); + z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_PCSRA, PCSR_CLR_IP_IUS); + + sc->sc_lpstate = LP_INITIAL; + free(sc->sc_printbuf, M_DEVBUF); + + return 0; +} + +int +cpi_write(dev_t device, struct uio *uio, int flags) +{ + int err; + size_t numbytes; + struct cpi_softc *sc; + + err = 0; + + if (TRACE_WRITE) + printf("\tcpi_write() called for %u bytes\n", uio->uio_resid); + + sc = device_lookup(&cpi_cd, CPI_UNIT(device)); + + /* Send data to printer, a line buffer full at a time */ + while (uio->uio_resid > 0) { + numbytes = min(CPI_BUFSIZE, uio->uio_resid); + sc->sc_cp = sc->sc_printbuf; + uiomove(sc->sc_cp, numbytes, uio); + sc->sc_bufbytes = numbytes; + + if (TRACE_WRITE) + printf("\tQueuing %u bytes\n", numbytes); + err = cpi_flush(sc); + if (err) { + /* Failure; adjust residual counter */ + if (TRACE_WRITE) + printf("\tQueuing failed with %d\n", err); + uio->uio_resid += sc->sc_bufbytes; + sc->sc_bufbytes = 0; + break; + } + } + return err; +} + +int +cpi_ioctl(dev_t device, unsigned long cmd, void *data, + int flag, struct lwp *l) +{ + int err; + + err = 0; + + if (TRACE_IOCTL) + printf("\tcpi_ioctl() called with %ld...\n", cmd); + + switch (cmd) { + default: + if (TRACE_IOCTL) + printf("\tcpi_ioctl() unknown ioctl %ld\n", cmd); + err = ENODEV; + break; + } + return err; +} + +/* + * Flush the print buffer that our top half uses to provide data to + * our bottom, interrupt-driven half. + */ +static int +cpi_flush(struct cpi_softc *sc) +{ + int err, s; + + err = 0; + while (0 < sc->sc_bufbytes) { + /* Feed the printer a char, if it's ready */ + if ( !cpi_notready(sc)) { + if (TRACE_WRITE) + printf("\tcpi_flush() writes %u bytes " + "(%lu hard, %lu bytes to port)\n", + sc->sc_bufbytes, sc->sc_intcount, + sc->sc_bytestoport); + s = spltty(); + cpi_intr(sc); + splx(s); + } + /* XXX Sure we want to wait forever for the printer? */ + err = ltsleep((void *)sc, PZERO | PCATCH, + "cpi_flush", (60 * hz), NULL); + } + return err; +} + + +static void +cpi_wakeup(void *param) +{ + struct cpi_softc *sc; + int s; + + sc = param; + + s = spltty(); + cpi_intr(sc); + splx(s); + + callout_reset(&sc->sc_wakeupchan, hz, cpi_wakeup, sc); +} + + +static void +cpi_lpreset(struct cpi_softc *sc) +{ + uint8_t portb; /* Centronics -RESET is on port B, bit 0 */ +#ifdef DIRECT_PORT_ACCESS + int s; + + s = spltty(); + + portb = bus_space_read_1(sc->sc_bst, sc->sc_bsh, CIO_PORTB); + bus_space_write_1(sc->sc_bst, sc->sc_bsh, + CIO_PORTB, portb & ~CPI_RESET); + delay(100); + portb = bus_space_read_1(sc->sc_bst, sc->sc_bsh, CIO_PORTB); + bus_space_write_1(sc->sc_bst, sc->sc_bsh, + CIO_PORTB, portb | CPI_RESET); + + splx(s); +#else + portb = z8536_reg_get(sc->sc_bst, sc->sc_bsh, Z8536_PDRB); + z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_PDRB, portb & ~CPI_RESET); + delay(100); + portb = z8536_reg_get(sc->sc_bst, sc->sc_bsh, Z8536_PDRB); + z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_PDRB, portb | CPI_RESET); +#endif /* DIRECT_PORT_ACCESS */ +} + + +/* + * Centronics BUSY is on port B, bit 6 + * SELECT is on Port B, bit 5 + * /FAULT is on Port B, bit 1 + * PAPER EMPTY is on Port C, bit 1 + */ +static int +cpi_notready(struct cpi_softc *sc) +{ + uint8_t portb, portc; + int is_busy, is_select, is_fault, is_paper_empty; + + if (TRACE_STATUS) + printf("\tcpi_notready() checking printer status...\n"); + + portb = bus_space_read_1(sc->sc_bst, sc->sc_bsh, CIO_PORTB); + if (TRACE_STATUS) + printf("\tPort B has 0x0%X\n", portb); + + is_busy = CPI_BUSY & portb; + if (TRACE_STATUS) + printf("\t\tBUSY = %d\n", is_busy); + + is_select = CPI_SELECT & portb; + if (TRACE_STATUS) + printf("\t\tSELECT = %d\n", is_select); + + is_fault = CPI_FAULT & portb; + if (TRACE_STATUS) + printf("\t\t/FAULT = %d\n", is_fault); + + portc = bus_space_read_1(sc->sc_bst, sc->sc_bsh, CIO_PORTC); + if (TRACE_STATUS) + printf("\tPort C has 0x0%X\n", portc); + + is_paper_empty = CPI_PAPER_EMPTY & portc; + if (TRACE_STATUS) + printf("\t\tPAPER EMPTY = %d\n", is_paper_empty); + + return (is_busy || !is_select || !is_fault || is_paper_empty); +} + +static void +cpi_intr(void *arg) +{ + struct cpi_softc *sc; + + sc = arg; + + /* Printer ready for output? */ + if (cpi_notready(sc)) + return; + + if (0 && TRACE_WRITE) + printf("\tcpi_soft_intr() has %u bytes.\n", sc->sc_bufbytes); + + /* Anything to print? */ + if (sc->sc_bufbytes) { + /* Data byte */ + bus_space_write_1(sc->sc_bst, sc->sc_bsh, + CIO_PORTA, *sc->sc_cp++); + sc->sc_bufbytes--; + sc->sc_bytestoport++; + } + if (0 == sc->sc_bufbytes) + /* line buffer empty, wake up our top half */ + wakeup((void *)sc); +} + +#ifdef USE_CIO_TIMERS +/* + * Z8536 CIO timers 1 + 2 used for timecounter(9) support + */ +static void +cpi_initclock(struct cpi_softc *sc) +{ + static struct timecounter cpi_timecounter = { + .tc_get_timecount = cpi_get_timecount, + .tc_poll_pps = 0, + .tc_counter_mask = 0x0ffffu, + .tc_frequency = CLK_FREQ, + .tc_name = "CPI Z8536 CIO", + .tc_quality = 50, + .tc_priv = NULL, + .tc_next = NULL + }; + + /* + * Set up timers A and B as a single, free-running 32 bit counter + */ + + /* Disable counters A and B */ + reg = z8536_reg_get(sc->sc_bst, sc->sc_bsh, Z8536_MCCR); + z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_MCCR, + reg & ~(MCCR_CT1E | MCCR_CT2E)); + + /* Make sure interrupt enable bits are cleared */ + z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTCSR1, + CTCS_CLR_IE); + z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTCSR2, + CTCS_CLR_IE); + + /* Initialise counter start values, and set to continuous cycle */ + z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTMSR1, CTMS_CSC); + z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTTCR1_MSB, 0x00); + z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTTCR1_LSB, 0x00); + + z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTMSR2, CTMS_CSC); + z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTTCR2_MSB, 0x00); + z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTTCR2_LSB, 0x00); + + /* Re-enable counters A and B */ + reg = z8536_reg_get(sc->sc_bst, sc->sc_bsh, Z8536_MCCR); + z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_MCCR, + reg | MCCR_CT1E | MCCR_CT2E | MCCR_CT1CT2); + + /* Start counters A and B */ + reg = z8536_reg_get(sc->sc_bst, sc->sc_bsh, Z8536_CTCSR1); + z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTCSR1, + reg | CTCS_TCB); + reg = z8536_reg_get(sc->sc_bst, sc->sc_bsh, Z8536_CTCSR2); + z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTCSR2, + reg | CTCS_TCB); + + tc_init(&cpi_timecounter); +} + +static u_int +cpi_get_timecount(struct timecounter *tc) +{ + uint8_t high, high2, low; + int s; + + /* + * Make the timer access atomic + * + * XXX How expensive is this? And is it really necessary? + */ + s = splhigh(); + + /* TBD */ + +} +#endif /* USE_CIO_TIMERS */ + + +/* + * Z8536 CIO nuts and bolts + */ + +static inline void +z8536_reg_set(bus_space_tag_t bspace, bus_space_handle_t bhandle, + uint8_t reg, uint8_t val) +{ + int s; + + s = splhigh(); + bus_space_write_1(bspace, bhandle, CIO_CTRL, reg); + delay(1); + bus_space_write_1(bspace, bhandle, CIO_CTRL, val); + splx(s); +} + +static inline uint8_t +z8536_reg_get(bus_space_tag_t bspace, bus_space_handle_t bhandle, uint8_t reg) +{ + int s; + uint8_t val; + + s = splhigh(); + bus_space_write_1(bspace, bhandle, CIO_CTRL, reg); + delay(1); + val = bus_space_read_1(bspace, bhandle, CIO_CTRL); + splx(s); + + return val; +} diff --git a/sys/arch/mac68k/nubus/cpi_nubusvar.h b/sys/arch/mac68k/nubus/cpi_nubusvar.h new file mode 100644 index 00000000000..cb6670b7d79 --- /dev/null +++ b/sys/arch/mac68k/nubus/cpi_nubusvar.h @@ -0,0 +1,88 @@ +/* $NetBSD */ + +/*- + * Copyright (c) 2008 Hauke Fath + * + * 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 ``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. + */ + +#ifndef CPI_NUBUSVAR_H +#define CPI_NUBUSVAR_H + +/* Where we find the Z8536 CIO in Nubus slot space */ +#define CIO_BASE_OFFSET 0x060010 + +/* Max. length of card name string */ +#define CPI_CARD_NAME_LEN 64 + +/* The CIO lives on the top 8 bit of the 32 bit data bus. */ +enum cio_regs { + CIO_PORTC = 0x03, + CIO_PORTB = 0x07, + CIO_PORTA = 0x0b, + CIO_CTRL = 0x0f +}; + +#define CPI_UNIT(c) (minor(c) & 0x1f) + +enum lp_state { + LP_INITIAL = 0, /* device is closed */ + LP_OPENING, /* device is about to be opened */ + LP_OPEN, /* device is open */ + LP_BUSY, /* busy with data output */ + LP_ASLEEP, /* waiting for output completion */ +}; + +/* Bit masks for Centronics status + handshake lines */ +enum hsk_lines { + CPI_RESET = 0x01, /* PB0 */ + CPI_STROBE = 0x08, /* PC3 */ + CPI_BUSY = 0x40, /* PC0 */ + CPI_SELECT = 0x20, /* PB5 */ + CPI_FAULT = 0x02, /* PB1 */ + CPI_PAPER_EMPTY = 0x02, /* PC1 */ + CPI_ACK = 0x04 /* PC2 */ +}; + +struct cpi_softc { + struct device sc_dev; + + nubus_slot sc_slot; /* Nubus slot number */ + char cardname[CPI_CARD_NAME_LEN]; + + bus_addr_t sc_basepa; /* base physical address */ + bus_space_tag_t sc_bst; + bus_space_handle_t sc_bsh; + + ulong sc_intcount; /* Hard interrupts */ + ulong sc_bytestoport; /* Bytes written to port */ + + struct callout sc_wakeupchan; + +#define CPI_BUFSIZE 0x0800 + char *sc_printbuf; /* Driver's print buffer */ + size_t sc_bufbytes; /* # of bytes in buffer */ + u_char *sc_cp; /* Next byte to send */ + + u_char sc_lpstate; +}; + +#endif /* CPI_NUBUSVAR_H */ diff --git a/sys/arch/macppc/stand/ofwboot/Makefile b/sys/arch/macppc/stand/ofwboot/Makefile index 33def8ab4e9..af49707b081 100644 --- a/sys/arch/macppc/stand/ofwboot/Makefile +++ b/sys/arch/macppc/stand/ofwboot/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.45 2005/12/11 12:18:06 christos Exp $ +# $NetBSD: Makefile,v 1.46 2008/05/22 19:49:43 hauke Exp $ S= ${.CURDIR}/../../../.. @@ -34,7 +34,7 @@ BINMODE= 444 .if !defined(TOOL_MACPPCFIXCOFF) TOOL_MACPPCFIXCOFFDIR!= cd ${.CURDIR}/../fixcoff && ${PRINTOBJDIR} -TOOL_MACPPCFIXCOFF= ${FIXCOFFDIR}/fixcoff +TOOL_MACPPCFIXCOFF= ${TOOL_MACPPCFIXCOFFDIR}/fixcoff .endif .endif diff --git a/sys/arch/macppc/stand/ofwboot/ofdev.c b/sys/arch/macppc/stand/ofwboot/ofdev.c index b6957cd3885..b0df2f4b868 100644 --- a/sys/arch/macppc/stand/ofwboot/ofdev.c +++ b/sys/arch/macppc/stand/ofwboot/ofdev.c @@ -1,4 +1,4 @@ -/* $NetBSD: ofdev.c,v 1.19 2006/05/24 21:24:25 mrg Exp $ */ +/* $NetBSD: ofdev.c,v 1.20 2008/05/22 19:49:43 hauke Exp $ */ /* * Copyright (C) 1995, 1996 Wolfgang Solfrank. @@ -50,6 +50,7 @@ #include <lib/libsa/cd9660.h> #include <lib/libsa/nfs.h> #include <lib/libsa/ufs.h> +#include <lib/libsa/lfs.h> #include <lib/libsa/ustarfs.h> #include "hfs.h" @@ -157,13 +158,16 @@ static struct devsw of_devsw[1] = { }; int ndevs = sizeof of_devsw / sizeof of_devsw[0]; -static struct fs_ops file_system_ufs = FS_OPS(ufs); +static struct fs_ops file_system_ffsv1 = FS_OPS(ffsv1); +static struct fs_ops file_system_ffsv2 = FS_OPS(ffsv2); +static struct fs_ops file_system_lfsv1 = FS_OPS(lfsv1); +static struct fs_ops file_system_lfsv2 = FS_OPS(lfsv2); static struct fs_ops file_system_hfs = FS_OPS(hfs); static struct fs_ops file_system_ustarfs = FS_OPS(ustarfs); static struct fs_ops file_system_cd9660 = FS_OPS(cd9660); static struct fs_ops file_system_nfs = FS_OPS(nfs); -struct fs_ops file_system[4]; +struct fs_ops file_system[8]; int nfsys; static struct of_dev ofdev = { @@ -331,11 +335,14 @@ devopen(struct open_file *of, const char *name, char **file) of->f_dev = of_devsw; of->f_devdata = &ofdev; - file_system[0] = file_system_ufs; - file_system[1] = file_system_ustarfs; - file_system[2] = file_system_cd9660; - file_system[3] = file_system_hfs; - nfsys = 4; + file_system[0] = file_system_ffsv1; + file_system[1] = file_system_ffsv2; + file_system[2] = file_system_lfsv1; + file_system[3] = file_system_lfsv2; + file_system[4] = file_system_ustarfs; + file_system[5] = file_system_cd9660; + file_system[6] = file_system_hfs; + nfsys = 7; return 0; } if (!strcmp(buf, "network")) { diff --git a/sys/dev/ic/z8536reg.h b/sys/dev/ic/z8536reg.h new file mode 100644 index 00000000000..dd783aacb2f --- /dev/null +++ b/sys/dev/ic/z8536reg.h @@ -0,0 +1,244 @@ +/* $NetBSD */ + +/*- + * Copyright (c) 2008 Hauke Fath + * + * 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 ``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. + */ + +/* + * Zilog Z8536 CIO (Counter/Timer and Parallel I/O Unit) + * Register Definitions + * + * The CIO has four registers: One control register, and three data + * registers for ports A/B/C. To set up the CIO through the control + * register, first write the number of the internal register to it, + * then access or set the selected register contents. Once selected, + * an internal register can be polled continuously by reading out the + * control port. + * + * Internal registers are read-writable, except where noted. + */ +#define Z8536_IOSIZE 0x04 + +#define Z8536_MICR 0x00 /* Master Interrupt Control Register */ +#define MICR_RESET 0x01 /* Chip Reset */ +#define MICR_RJA 0x02 /* Only z8036 (ZBUS version) */ +#define MICR_CTVIS 0x04 /* CT vector includes status */ +#define MICR_PBVIS 0x08 /* Port B vector includes status */ +#define MICR_PAVIS 0x10 /* Port A vector includes status */ +#define MICR_NV 0x20 /* No Vector (NV) */ +#define MICR_DLC 0x40 /* Disable Lower Chain (DLC) */ +#define MICR_MIE 0x80 /* Master Interrupt Enable (MIE) */ + +#define Z8536_MCCR 0x01 /* Master Configuration Register */ +#define MCCR_CTINDPT 0x00 /* Counter/Timers Independent */ +#define MCCR_CT1GT2 0x01 /* CT 1 /OUTPUT gates CT 2 */ +#define MCCR_CT1TR2 0x02 /* CT 1 /OUTPUT triggers CT 2 */ +#define MCCR_CT1CT2 0x03 /* CT 1 /OUTPUT is CT 2's COUNT */ +#define MCCR_PAE 0x04 /* Port A Enable */ +#define MCCR_PLC 0x08 /* Port Link Control (A/B) */ +#define MCCR_PC_CT3E 0x10 /* Counter/Timer 3 + Port C Enable */ +#define MCCR_CT2E 0x20 /* Counter/Timer 2 Enable */ +#define MCCR_CT1E 0x40 /* Counter/Timer 1 Enable */ +#define MCCR_PBE 0x80 /* Port B Enable */ + +/* Interrupt Vector Registers */ +#define Z8536_IVRA 0x02 /* Port A Interrupt Vector */ +#define Z8536_IVRB 0x03 /* Port B Interrupt Vector */ +#define Z8536_IVRCT 0x04 /* Counter/Timer Interrupt Vector */ + +/* Port C setup */ +#define Z8536_DPPRC 0x05 /* Port C Data Path Polarity */ +#define Z8536_DDRC 0x06 /* Port C Data Direction */ +#define Z8536_SIOCRC 0x07 /* Port C Special I/O Control */ + +#define Z8536_PCSRA 0x08 /* Port A Command and Status */ +#define Z8536_PCSRB 0x09 /* Port B Command and Status */ + +/* Z8536_PCSRA + Z8536_PCSRB command and status bits */ +#define PCSR_IOE 0x01 /* Interrupt on error */ +#define PCSR_PMF 0x02 /* Pattern match flag (RO) */ +#define PCSR_IRF 0x04 /* Input register full (RO) */ +#define PCSR_ORE 0x08 /* Output register empty (RO) */ +#define PCSR_ERR 0x10 /* Interrupt error */ +#define PCSR_IP 0x20 /* Interrupt pending */ +#define PCSR_IE 0x40 /* Interrupt enable */ +#define PCSR_IUS 0x80 /* Interrupt under service */ +/* PCSR{A,B} interrupt bits: IUS/IE/IP */ +#define PCSR_NULL 0x00 /* Null Code */ +#define PCSR_CLR_IP_IUS 0x20 /* Clear IP and IUS */ +#define PCSR_SET_IUS 0x40 /* Set Interrupt Under Service */ +#define PCSR_CLR_IUS 0x60 /* Clear Interrupt Under Service */ +#define PCSR_SET_IP 0x80 /* Set Interrupt Pending */ +#define PCSR_CLR_IP 0xA0 /* Clear Interrupt Pending */ +#define PCSR_SET_IE 0xC0 /* Set Interrupt Enable */ +#define PCSR_CLR_IE 0xE0 /* Clear Interrupt Enable */ + +/* Counter/Timer 1..3 Command and Status Registers */ +#define Z8536_CTCSR1 0x0A /* CT 1 Command and Status */ +#define Z8536_CTCSR2 0x0B /* CT 2 Command and Status */ +#define Z8536_CTCSR3 0x0C /* CT 3 Command and Status */ + +/* CTCSR setup bits */ +#define CTCS_CIP 0x01 /* Count in Progress (RO) */ +#define CTCS_TCB 0x02 /* Trigger Command Bit (WO) */ +#define CTCS_GCB 0x04 /* Gate Command Bit */ +#define CTCS_RCC 0x08 /* Read Counter Control */ +#define CTCS_ERR 0x10 /* Interrupt Error (RO) */ +#define CTCS_IP 0x20 /* Interrupt Pending */ +#define CTCS_IE 0x40 /* Interrupt Enable */ +#define CTCS_IUS 0x80 /* Interrupt Under Service */ + +/* CTCSR interrupt bits: IUS/IE/IP */ +#define CTCS_NULL 0x00 /* Null Code */ +#define CTCS_CLR_IP_IUS 0x20 /* Clear IP and IUS */ +#define CTCS_SET_IUS 0x40 /* Set Interrupt Under Service */ +#define CTCS_CLR_IUS 0x60 /* Clear Interrupt Under Service */ +#define CTCS_SET_IP 0x80 /* Set Interrupt Pending */ +#define CTCS_CLR_IP 0xA0 /* Clear Interrupt Pending */ +#define CTCS_SET_IE 0xC0 /* Set Interrupt Enable */ +#define CTCS_CLR_IE 0xE0 /* Clear Interrupt Enable */ + +/* The port data registers are directly accessible at their own IO address */ +#define Z8536_PDRA 0x0D /* Port A Data Register */ +#define Z8536_PDRB 0x0E /* Port B Data Register */ +#define Z8536_PDRC 0x0F /* Port C Data Register */ + +/* Bytewise access to current count registers (read-only) */ +#define Z8536_CTCCR1_MSB 0x10 /* CT 1 Current Count MSB */ +#define Z8536_CTCCR1_LSB 0x11 /* CT 1 Current Count LSB */ +#define Z8536_CTCCR2_MSB 0x12 /* CT 2 Current Count MSB */ +#define Z8536_CTCCR2_LSB 0x13 /* CT 2 Current Count LSB */ +#define Z8536_CTCCR3_MSB 0x14 /* CT 3 Current Count MSB */ +#define Z8536_CTCCR3_LSB 0x15 /* CT 3 Current Count LSB */ + +/* Bytewise access to time constant registers */ +#define Z8536_CTTCR1_MSB 0x16 /* CT 1 Time Constant MSB */ +#define Z8536_CTTCR1_LSB 0x17 /* CT 1 Time Constant LSB */ +#define Z8536_CTTCR2_MSB 0x18 /* CT 2 Time Constant MSB */ +#define Z8536_CTTCR2_LSB 0x19 /* CT 2 Time Constant LSB */ +#define Z8536_CTTCR3_MSB 0x1A /* CT 3 Time Constant MSB */ +#define Z8536_CTTCR3_LSB 0x1B /* CT 3 Time Constant LSB */ + +/* Counter/Timer Mode specification */ +#define Z8536_CTMSR1 0x1C /* CT 1 Mode Specification */ +#define Z8536_CTMSR2 0x1D /* CT 2 Mode Specification */ +#define Z8536_CTMSR3 0x1E /* CT 3 Mode Specification */ +#define CTMS_DCS_PULSE 0x00 /* Pulse Output */ +#define CTMS_DCS_ONESHOT 0x01 /* One-Shot Output */ +#define CTMS_DCS_SQUARE 0x02 /* Square Wave Output */ +#define CTMS_REB 0x04 /* Retrigger Enable */ +#define CTMS_EGE 0x08 /* External Gate Enable */ +#define CTMS_ETE 0x10 /* External Trigger Enable */ +#define CTMS_ECE 0x20 /* External Count Enable */ +#define CTMS_EOE 0x40 /* External Output Enable */ +#define CTMS_CSC 0x80 /* Continuous / Single Cycle */ + +#define Z8536_CVR 0x1F /* Current Interrupt Vector (RO) */ + +/* Port A specification registers */ +#define Z8536_PMSRA 0x20 /* Port A Mode Specification */ +#define Z8536_PHSRA 0x21 /* Port A Handshake Specification */ +#define Z8536_DPPRA 0x22 /* Port A Data Path Polarity */ +#define Z8536_DDRA 0x23 /* Port A Data Direction */ +#define Z8536_SIOCRA 0x24 /* Port A Special I/O Control */ +#define Z8536_PPRA 0x25 /* Port A Pattern Polarity */ +#define Z8536_PTRA 0x26 /* Port A Pattern Transition */ +#define Z8536_PMRA 0x27 /* Port A Pattern Mask */ + +/* Port B specification registers */ +#define Z8536_PMSRB 0x28 /* Port B Mode Specification */ +#define Z8536_PHSRB 0x29 /* Port B Handshake Specification */ +#define Z8536_DPPRB 0x2A /* Port B Data Path Polarity */ +#define Z8536_DDRB 0x2B /* Port B Data Direction */ +#define Z8536_SIOCRB 0x2C /* Port B Special I/O Control */ +#define Z8536_PPRB 0x2D /* Port B Pattern Polarity */ +#define Z8536_PTRB 0x2E /* Port B Pattern Transition */ +#define Z8536_PMRB 0x2F /* Port B Pattern Mask */ + +/* Bit definitions, common to ports A and B */ + +/* Z8536_PMSRA + Z8536_PMSRB port mode specification bits */ +#define PMSR_LPM 0x01 /* Bit mode: latched */ +#define PMSR_DTE 0x01 /* Hsk mode: deskew timer enable */ +/* + * PMS1 PMS0 Pattern mode specification + * 0 0 disable pattern match + * 0 1 "and" mode, transition-triggered interrupt + * 1 0 "or" mode, transition-triggered interrupt + * 1 1 "or-priority encoded vector" mode, level- + * triggered interrupt (only transparent LPM mode) + */ +#define PMSR_PMS0 0x02 +#define PMSR_PMS1 0x04 +#define PMSR_PMS_OFF 0x00 /* Disable pattern match */ +#define PMSR_PMS_AND 0x02 /* "and" mode, transition-triggered */ +#define PMSR_PMS_OR 0x04 /* "or" mode, transition-triggered */ +/* + * "or-priority encoded vector" mode, level-triggered interrupt + * (only in transparent LPM mode) + */ +#define PMSR_PMS_OR_PEV 0x06 +#define PMSR_IMO 0x08 /* Interrupt on match only */ +#define PMSR_SB 0x10 /* Single buffered mode */ +#define PMSR_ITB 0x20 /* Interrupt on two bytes */ +/* + * PTS1 PTS0 Port type selects + * 0 0 bit port + * 0 1 input port + * 1 0 output port + * 1 1 bidirectional port + */ +#define PMSR_PTS0 0x40 +#define PMSR_PTS1 0x80 +#define PMSR_PTS_BIT 0x00 +#define PMSR_PTS_IN 0x40 +#define PMSR_PTS_OUT 0x80 +#define PMSR_PTS_BIDI 0xC0 +/* + * Z8536_PHSRA + Z8536_PHSRB port handshake specification bits + * Bits 0-2 set deskew timer for output ports + * + * RWS2 RWS1 RWS0 Status signals on port C + * 0 0 0 REQUEST/-WAIT disabled + * 0 0 1 output -WAIT + * 0 1 1 input -WAIT + * 1 0 0 special REQUEST + * 1 0 1 output REQUEST + * 1 1 1 input REQUEST + */ +#define PHSR_RWS0 0x08 +#define PHSR_RWS1 0x10 +#define PHSR_RWS2 0x20 +/* + * HTS1 HTS0 Handshake type specification + * 0 0 interlocked handshake + * 0 1 strobed handshake + * 1 0 pulsed handshake + * 1 1 three-wire-handshake + */ +#define PHSR_HTS0 0x40 +#define PHSR_HTS1 0x80 +#define PHSR_HTS_INT 0x00 +#define PHSR_HTS_STR 0x40 +#define PHSR_HTS_PUL 0x80 +#define PHSR_HTS_TWI 0xC0 |
