1 1.13 msaitoh /* $NetBSD: lpt_pioc.c,v 1.13 2019/12/27 09:28:41 msaitoh Exp $ */ 2 1.1 reinoud 3 1.1 reinoud /* 4 1.1 reinoud * Copyright (c) 1997 Mark Brinicombe 5 1.1 reinoud * Copyright (c) 1997 Causality Limited 6 1.1 reinoud * All rights reserved. 7 1.1 reinoud * 8 1.1 reinoud * Redistribution and use in source and binary forms, with or without 9 1.1 reinoud * modification, are permitted provided that the following conditions 10 1.1 reinoud * are met: 11 1.1 reinoud * 1. Redistributions of source code must retain the above copyright 12 1.1 reinoud * notice, this list of conditions and the following disclaimer. 13 1.1 reinoud * 2. Redistributions in binary form must reproduce the above copyright 14 1.1 reinoud * notice, this list of conditions and the following disclaimer in the 15 1.1 reinoud * documentation and/or other materials provided with the distribution. 16 1.1 reinoud * 3. The name of the company nor the name of the author may be used to 17 1.1 reinoud * endorse or promote products derived from this software without specific 18 1.1 reinoud * prior written permission. 19 1.1 reinoud * 20 1.1 reinoud * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 21 1.1 reinoud * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 22 1.1 reinoud * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 1.1 reinoud * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTERS BE LIABLE FOR ANY DIRECT, 24 1.1 reinoud * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 1.1 reinoud * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 1.1 reinoud * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 1.1 reinoud * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 1.1 reinoud * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 1.1 reinoud * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 1.1 reinoud * SUCH DAMAGE. 31 1.1 reinoud */ 32 1.1 reinoud 33 1.1 reinoud /* 34 1.1 reinoud * Device Driver for AT parallel printer port 35 1.1 reinoud */ 36 1.1 reinoud 37 1.1 reinoud #include <sys/param.h> 38 1.4 bjh21 39 1.13 msaitoh __KERNEL_RCSID(0, "$NetBSD: lpt_pioc.c,v 1.13 2019/12/27 09:28:41 msaitoh Exp $"); 40 1.4 bjh21 41 1.1 reinoud #include <sys/systm.h> 42 1.1 reinoud #include <sys/kernel.h> 43 1.1 reinoud #include <sys/device.h> 44 1.12 dyoung #include <sys/bus.h> 45 1.2 thorpej #include <machine/intr.h> 46 1.1 reinoud #include <acorn32/mainbus/piocvar.h> 47 1.1 reinoud #include <dev/ic/lptreg.h> 48 1.1 reinoud #include <dev/ic/lptvar.h> 49 1.1 reinoud 50 1.1 reinoud #include "locators.h" 51 1.1 reinoud 52 1.1 reinoud /* Prototypes for functions */ 53 1.1 reinoud 54 1.9 cube static int lpt_port_test (bus_space_tag_t, bus_space_handle_t, bus_addr_t, 55 1.9 cube bus_size_t, u_char, u_char); 56 1.9 cube static int lptprobe (bus_space_tag_t, u_int); 57 1.9 cube static int lpt_pioc_probe (device_t, cfdata_t , void *); 58 1.9 cube static void lpt_pioc_attach (device_t, device_t, void *); 59 1.1 reinoud 60 1.1 reinoud /* device attach structure */ 61 1.1 reinoud 62 1.9 cube CFATTACH_DECL_NEW(lpt_pioc, sizeof(struct lpt_softc), 63 1.8 thorpej lpt_pioc_probe, lpt_pioc_attach, NULL, NULL); 64 1.1 reinoud 65 1.1 reinoud /* 66 1.1 reinoud * Internal routine to lptprobe to do port tests of one byte value. 67 1.1 reinoud */ 68 1.1 reinoud static int 69 1.9 cube lpt_port_test(bus_space_tag_t iot, bus_space_handle_t ioh, 70 1.9 cube bus_addr_t base, bus_size_t off, u_char data, u_char mask) 71 1.1 reinoud { 72 1.1 reinoud int timeout; 73 1.1 reinoud u_char temp; 74 1.1 reinoud 75 1.1 reinoud data &= mask; 76 1.1 reinoud bus_space_write_1(iot, ioh, off, data); 77 1.1 reinoud timeout = 1000; 78 1.1 reinoud do { 79 1.1 reinoud delay(10); 80 1.1 reinoud temp = bus_space_read_1(iot, ioh, off) & mask; 81 1.1 reinoud } while (temp != data && --timeout); 82 1.1 reinoud return (temp == data); 83 1.1 reinoud } 84 1.1 reinoud 85 1.1 reinoud /* 86 1.1 reinoud * Logic: 87 1.1 reinoud * 1) You should be able to write to and read back the same value 88 1.1 reinoud * to the data port. Do an alternating zeros, alternating ones, 89 1.1 reinoud * walking zero, and walking one test to check for stuck bits. 90 1.1 reinoud * 91 1.1 reinoud * 2) You should be able to write to and read back the same value 92 1.1 reinoud * to the control port lower 5 bits, the upper 3 bits are reserved 93 1.13 msaitoh * per the IBM PC technical reference manuals and different boards 94 1.1 reinoud * do different things with them. Do an alternating zeros, alternating 95 1.1 reinoud * ones, walking zero, and walking one test to check for stuck bits. 96 1.1 reinoud * 97 1.1 reinoud * Some printers drag the strobe line down when the are powered off 98 1.1 reinoud * so this bit has been masked out of the control port test. 99 1.1 reinoud * 100 1.1 reinoud * XXX Some printers may not like a fast pulse on init or strobe, I 101 1.1 reinoud * don't know at this point, if that becomes a problem these bits 102 1.1 reinoud * should be turned off in the mask byte for the control port test. 103 1.1 reinoud * 104 1.1 reinoud * 3) Set the data and control ports to a value of 0 105 1.1 reinoud */ 106 1.1 reinoud static int 107 1.9 cube lptprobe(bus_space_tag_t iot, u_int iobase) 108 1.1 reinoud { 109 1.1 reinoud bus_space_handle_t ioh; 110 1.1 reinoud u_char mask, data; 111 1.1 reinoud int i, rv; 112 1.1 reinoud #ifdef DEBUG 113 1.1 reinoud #define ABORT do {printf("lptprobe: mask %x data %x failed\n", mask, data); \ 114 1.1 reinoud goto out;} while (0) 115 1.1 reinoud #else 116 1.1 reinoud #define ABORT goto out 117 1.1 reinoud #endif 118 1.1 reinoud 119 1.1 reinoud if (bus_space_map(iot, iobase, LPT_NPORTS, 0, &ioh)) 120 1.1 reinoud return 0; 121 1.1 reinoud rv = 0; 122 1.1 reinoud mask = 0xff; 123 1.1 reinoud 124 1.1 reinoud data = 0x55; /* Alternating zeros */ 125 1.1 reinoud if (!lpt_port_test(iot, ioh, iobase, lpt_data, data, mask)) 126 1.1 reinoud ABORT; 127 1.1 reinoud 128 1.1 reinoud data = 0xaa; /* Alternating ones */ 129 1.1 reinoud if (!lpt_port_test(iot, ioh, iobase, lpt_data, data, mask)) 130 1.1 reinoud ABORT; 131 1.1 reinoud 132 1.1 reinoud for (i = 0; i < CHAR_BIT; i++) { /* Walking zero */ 133 1.1 reinoud data = ~(1 << i); 134 1.1 reinoud if (!lpt_port_test(iot, ioh, iobase, lpt_data, data, mask)) 135 1.1 reinoud ABORT; 136 1.1 reinoud } 137 1.1 reinoud 138 1.1 reinoud for (i = 0; i < CHAR_BIT; i++) { /* Walking one */ 139 1.1 reinoud data = (1 << i); 140 1.1 reinoud if (!lpt_port_test(iot, ioh, iobase, lpt_data, data, mask)) 141 1.1 reinoud ABORT; 142 1.1 reinoud } 143 1.1 reinoud 144 1.1 reinoud bus_space_write_1(iot, ioh, lpt_data, 0); 145 1.1 reinoud bus_space_write_1(iot, ioh, lpt_control, 0); 146 1.1 reinoud 147 1.1 reinoud rv = LPT_NPORTS; 148 1.1 reinoud 149 1.1 reinoud out: 150 1.1 reinoud bus_space_unmap(iot, ioh, LPT_NPORTS); 151 1.1 reinoud return rv; 152 1.1 reinoud } 153 1.1 reinoud 154 1.1 reinoud /* 155 1.11 matt * int lpt_pioc_probe(device_t parent, cfdata_t cf, void *aux) 156 1.1 reinoud * 157 1.1 reinoud * Make sure we are trying to attach a lpt device and then 158 1.1 reinoud * probe for one. 159 1.1 reinoud */ 160 1.1 reinoud 161 1.1 reinoud static int 162 1.9 cube lpt_pioc_probe(device_t parent, cfdata_t match, void *aux) 163 1.1 reinoud { 164 1.1 reinoud struct pioc_attach_args *pa = aux; 165 1.1 reinoud int rv; 166 1.1 reinoud 167 1.1 reinoud if (pa->pa_name && strcmp(pa->pa_name, "lpt") != 0) 168 1.1 reinoud return(0); 169 1.1 reinoud 170 1.1 reinoud /* We need an offset */ 171 1.1 reinoud if (pa->pa_offset == PIOCCF_OFFSET_DEFAULT) 172 1.1 reinoud return(0); 173 1.1 reinoud 174 1.1 reinoud rv = lptprobe(pa->pa_iot, pa->pa_iobase + pa->pa_offset); 175 1.1 reinoud 176 1.1 reinoud if (rv) { 177 1.1 reinoud pa->pa_iosize = rv; 178 1.1 reinoud return(1); 179 1.1 reinoud } 180 1.1 reinoud return(0); 181 1.1 reinoud } 182 1.1 reinoud 183 1.1 reinoud /* 184 1.11 matt * void lpt_pioc_attach(device_t parent, device_t self, void *aux) 185 1.1 reinoud * 186 1.1 reinoud * attach the lpt device 187 1.1 reinoud */ 188 1.1 reinoud 189 1.1 reinoud static void 190 1.9 cube lpt_pioc_attach(device_t parent, device_t self, void *aux) 191 1.1 reinoud { 192 1.10 chris struct lpt_softc *sc = device_private(self); 193 1.1 reinoud struct pioc_attach_args *pa = aux; 194 1.1 reinoud bus_space_tag_t iot; 195 1.1 reinoud bus_space_handle_t ioh; 196 1.1 reinoud u_int iobase; 197 1.1 reinoud 198 1.9 cube sc->sc_dev = self; 199 1.1 reinoud if (pa->pa_irq != MAINBUSCF_IRQ_DEFAULT) 200 1.9 cube aprint_normal("\n"); 201 1.1 reinoud else 202 1.9 cube aprint_normal(": polled\n"); 203 1.1 reinoud 204 1.1 reinoud iobase = pa->pa_iobase + pa->pa_offset; 205 1.1 reinoud 206 1.1 reinoud iot = sc->sc_iot = pa->pa_iot; 207 1.9 cube if (bus_space_map(iot, iobase, LPT_NPORTS, 0, &ioh)) { 208 1.9 cube aprint_error_dev(self, "couldn't map I/O ports"); 209 1.9 cube return; 210 1.9 cube } 211 1.1 reinoud sc->sc_ioh = ioh; 212 1.1 reinoud 213 1.1 reinoud lpt_attach_subr(sc); 214 1.1 reinoud 215 1.1 reinoud if (pa->pa_irq != MAINBUSCF_IRQ_DEFAULT) 216 1.1 reinoud sc->sc_ih = intr_claim(pa->pa_irq, IPL_TTY, "lpt", 217 1.1 reinoud lptintr, sc); 218 1.1 reinoud } 219 1.1 reinoud 220 1.1 reinoud /* End of lpt_pioc.c */ 221