No empty .Rs/.Re
[netbsd-mini2440.git] / sys / arch / mvme68k / dev / lpt_pcc.c
blob29f8e360b7d9f7c4bf57281d99ae5a8ddd74b35a
1 /* $NetBSD: lpt_pcc.c,v 1.11 2008/03/07 17:15:51 cube Exp $ */
3 /*-
4 * Copyright (c) 1999 The NetBSD Foundation, Inc.
5 * All rights reserved.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Steve C. Woodford.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 * Device Driver back-end for the MVME147's parallel printer port
36 #include <sys/cdefs.h>
37 __KERNEL_RCSID(0, "$NetBSD: lpt_pcc.c,v 1.11 2008/03/07 17:15:51 cube Exp $");
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/kernel.h>
42 #include <sys/device.h>
43 #include <sys/syslog.h>
45 #include <machine/bus.h>
47 #include <dev/mvme/lptvar.h>
49 #include <mvme68k/dev/lpt_pccreg.h>
50 #include <mvme68k/dev/pccreg.h>
51 #include <mvme68k/dev/pccvar.h>
53 #include "ioconf.h"
56 static int lpt_pcc_intr(void *);
57 static void lpt_pcc_open(struct lpt_softc *, int);
58 static void lpt_pcc_close(struct lpt_softc *);
59 static void lpt_pcc_iprime(struct lpt_softc *);
60 static void lpt_pcc_speed(struct lpt_softc *, int);
61 static int lpt_pcc_notrdy(struct lpt_softc *, int);
62 static void lpt_pcc_wr_data(struct lpt_softc *, u_char);
64 struct lpt_funcs lpt_pcc_funcs = {
65 lpt_pcc_open,
66 lpt_pcc_close,
67 lpt_pcc_iprime,
68 lpt_pcc_speed,
69 lpt_pcc_notrdy,
70 lpt_pcc_wr_data
74 * Autoconfig stuff
76 static int lpt_pcc_match(device_t, cfdata_t , void *);
77 static void lpt_pcc_attach(device_t, device_t, void *);
79 CFATTACH_DECL_NEW(lpt_pcc, sizeof(struct lpt_softc),
80 lpt_pcc_match, lpt_pcc_attach, NULL, NULL);
83 /*ARGSUSED*/
84 static int
85 lpt_pcc_match(device_t parent, cfdata_t cf, void *args)
87 struct pcc_attach_args *pa;
89 pa = args;
91 if (strcmp(pa->pa_name, lpt_cd.cd_name))
92 return 0;
94 pa->pa_ipl = cf->pcccf_ipl;
95 return 1;
98 /*ARGSUSED*/
99 static void
100 lpt_pcc_attach(device_t parent, device_t self, void *args)
102 struct lpt_softc *sc;
103 struct pcc_attach_args *pa;
105 sc = device_private(self);
106 sc->sc_dev = self;
107 pa = args;
109 sc->sc_bust = pa->pa_bust;
110 bus_space_map(pa->pa_bust, pa->pa_offset, LPREG_SIZE, 0, &sc->sc_bush);
112 sc->sc_ipl = pa->pa_ipl & PCC_IMASK;
113 sc->sc_funcs = &lpt_pcc_funcs;
114 sc->sc_laststatus = 0;
116 aprint_normal(": PCC Parallel Printer\n");
119 * Disable interrupts until device is opened
121 pcc_reg_write(sys_pcc, PCCREG_PRNT_INTR_CTRL, 0);
124 * Main attachment code
126 lpt_attach_subr(sc);
128 /* Register the event counter */
129 evcnt_attach_dynamic(&sc->sc_evcnt, EVCNT_TYPE_INTR,
130 pccintr_evcnt(sc->sc_ipl), "printer", device_xname(sc->sc_dev));
133 * Hook into the printer interrupt
135 pccintr_establish(PCCV_PRINTER, lpt_pcc_intr, sc->sc_ipl, sc,
136 &sc->sc_evcnt);
140 * Handle printer interrupts which occur when the printer is ready to accept
141 * another char.
144 lpt_pcc_intr(void *arg)
146 struct lpt_softc *sc;
147 int i;
149 sc = arg;
151 /* is printer online and ready for output */
152 if (lpt_pcc_notrdy(sc, 0) && lpt_pcc_notrdy(sc, 1))
153 return 0;
155 i = lpt_intr(sc);
157 if (pcc_reg_read(sys_pcc, PCCREG_PRNT_INTR_CTRL) & LPI_ACKINT) {
158 pcc_reg_write(sys_pcc, PCCREG_PRNT_INTR_CTRL,
159 sc->sc_icr | LPI_ACKINT);
162 return i;
166 static void
167 lpt_pcc_open(struct lpt_softc *sc, int int_ena)
169 int sps;
171 pcc_reg_write(sys_pcc, PCCREG_PRNT_INTR_CTRL,
172 LPI_ACKINT | LPI_FAULTINT);
174 if (int_ena == 0) {
175 sps = splhigh();
176 sc->sc_icr = sc->sc_ipl | LPI_ENABLE;
177 pcc_reg_write(sys_pcc, PCCREG_PRNT_INTR_CTRL, sc->sc_icr);
178 splx(sps);
182 static void
183 lpt_pcc_close(struct lpt_softc *sc)
186 pcc_reg_write(sys_pcc, PCCREG_PRNT_INTR_CTRL, 0);
187 sc->sc_icr = sc->sc_ipl;
188 pcc_reg_write(sys_pcc, PCCREG_PRNT_INTR_CTRL, sc->sc_icr);
191 /* ARGSUSED */
192 static void
193 lpt_pcc_iprime(struct lpt_softc *sc)
196 lpt_control_write(LPC_INPUT_PRIME);
197 delay(100);
200 /* ARGSUSED */
201 static void
202 lpt_pcc_speed(struct lpt_softc *sc, int speed)
205 if (speed == LPT_STROBE_FAST)
206 lpt_control_write(LPC_FAST_STROBE);
207 else
208 lpt_control_write(0);
211 static int
212 lpt_pcc_notrdy(struct lpt_softc *sc, int err)
214 u_char status;
215 u_char new;
217 #define LPS_INVERT (LPS_SELECT)
218 #define LPS_MASK (LPS_SELECT|LPS_FAULT|LPS_BUSY|LPS_PAPER_EMPTY)
220 status = (lpt_status_read(sc) ^ LPS_INVERT) & LPS_MASK;
222 if (err) {
223 new = status & ~sc->sc_laststatus;
224 sc->sc_laststatus = status;
226 if (new & LPS_SELECT)
227 log(LOG_NOTICE, "%s: offline\n",
228 device_xname(sc->sc_dev));
229 else if (new & LPS_PAPER_EMPTY)
230 log(LOG_NOTICE, "%s: out of paper\n",
231 device_xname(sc->sc_dev));
232 else if (new & LPS_FAULT)
233 log(LOG_NOTICE, "%s: output error\n",
234 device_xname(sc->sc_dev));
237 pcc_reg_write(sys_pcc, PCCREG_PRNT_INTR_CTRL,
238 sc->sc_icr | LPI_FAULTINT);
240 return status;
243 static void
244 lpt_pcc_wr_data(struct lpt_softc *sc, u_char data)
247 lpt_data_write(sc, data);