1 /* $NetBSD: ms_zs.c,v 1.18 2008/04/20 15:44:01 tsutsui Exp $ */
4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved.
7 * This software was developed by the Computer Systems Engineering group
8 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
9 * contributed to Berkeley.
11 * All advertising materials mentioning features or use of this software
12 * must display the following acknowledgement:
13 * This product includes software developed by the University of
14 * California, Lawrence Berkeley Laboratory.
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 * 3. Neither the name of the University nor the names of its contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 * @(#)ms.c 8.1 (Berkeley) 6/11/93
44 * Mouse driver (/dev/mouse)
48 * Zilog Z8530 Dual UART driver (mouse interface)
50 * This is the "slave" driver that will be attached to
51 * the "zsc" driver for a Sun mouse.
54 #include <sys/cdefs.h>
55 __KERNEL_RCSID(0, "$NetBSD: ms_zs.c,v 1.18 2008/04/20 15:44:01 tsutsui Exp $");
57 #include <sys/param.h>
58 #include <sys/systm.h>
60 #include <sys/device.h>
61 #include <sys/ioctl.h>
62 #include <sys/kernel.h>
64 #include <sys/signal.h>
65 #include <sys/signalvar.h>
67 #include <sys/select.h>
68 #include <sys/syslog.h>
70 #include <machine/vuid_event.h>
72 #include <dev/ic/z8530reg.h>
73 #include <machine/z8530var.h>
74 #include <dev/sun/event_var.h>
75 #include <dev/sun/msvar.h>
77 static void ms_zs_rxint(struct zs_chanstate
*);
78 static void ms_zs_stint(struct zs_chanstate
*, int);
79 static void ms_zs_txint(struct zs_chanstate
*);
80 static void ms_zs_softint(struct zs_chanstate
*);
82 struct zsops zsops_ms
= {
83 ms_zs_rxint
, /* receive char available */
84 ms_zs_stint
, /* external/status */
85 ms_zs_txint
, /* xmit buffer empty */
86 ms_zs_softint
, /* process software interrupt */
89 /* Fall-back baud rate */
91 int ms_zs_bps
= SUN_MS_BPS
;
93 int ms_zs_bps
= MS_DEFAULT_BPS
;
96 static int ms_zs_match(device_t
, cfdata_t
, void *);
97 static void ms_zs_attach(device_t
, device_t
, void *);
99 CFATTACH_DECL_NEW(ms_zs
, sizeof(struct ms_softc
),
100 ms_zs_match
, ms_zs_attach
, NULL
, NULL
);
103 * ms_match: how is this zs channel configured?
106 ms_zs_match(device_t parent
, cfdata_t cf
, void *aux
)
108 struct zsc_attach_args
*args
= aux
;
113 /* Exact match required for keyboard. */
114 if (cf
->cf_loc
[ZSCCF_CHANNEL
] == args
->channel
)
121 ms_zs_attach(device_t parent
, device_t self
, void *aux
)
124 struct zsc_softc
*zsc
= device_private(parent
);
125 struct ms_softc
*ms
= device_private(self
);
126 struct zsc_attach_args
*args
= aux
;
127 struct zs_chanstate
*cs
;
129 int channel
, ms_unit
;
134 cf
= device_cfdata(self
);
135 ms_unit
= device_unit(self
);
136 channel
= args
->channel
;
137 cs
= zsc
->zsc_cs
[channel
];
139 cs
->cs_ops
= &zsops_ms
;
141 /* Allow kernel option SUN_MS_BPS to hard-code baud rate */
143 if ((bps
= cs
->cs_defspeed
) == 0)
147 aprint_normal(": baud rate %d\n", bps
);
149 /* Initialize the speed, etc. */
151 /* May need reset... */
152 reset
= (channel
== 0) ?
153 ZSWR9_A_RESET
: ZSWR9_B_RESET
;
154 zs_write_reg(cs
, 9, reset
);
155 /* These are OK as set by zscc: WR3, WR4, WR5 */
156 /* We don't care about status or tx interrupts. */
157 cs
->cs_preg
[1] = ZSWR1_RIE
;
158 (void)zs_set_speed(cs
, bps
);
159 zs_loadchannelregs(cs
);
162 /* Initialize translator. */
166 /****************************************************************
167 * Interface to the lower layer (zscc)
168 ****************************************************************/
171 ms_zs_rxint(struct zs_chanstate
*cs
)
181 * First read the status, because reading the received char
182 * destroys the status of this char.
184 rr1
= zs_read_reg(cs
, 1);
185 c
= zs_read_data(cs
);
187 if (rr1
& (ZSRR1_FE
| ZSRR1_DO
| ZSRR1_PE
)) {
188 /* Clear the receive error. */
189 zs_write_csr(cs
, ZSWR0_RESET_ERRORS
);
192 ms
->ms_rbuf
[put
] = (c
<< 8) | rr1
;
193 put_next
= (put
+ 1) & MS_RX_RING_MASK
;
195 /* Would overrun if increment makes (put==get). */
196 if (put_next
== ms
->ms_rbget
) {
197 ms
->ms_intr_flags
|= INTR_RX_OVERRUN
;
199 /* OK, really increment. */
206 /* Ask for softint() call. */
211 ms_zs_txint(struct zs_chanstate
*cs
)
216 zs_write_csr(cs
, ZSWR0_RESET_TXINT
);
217 ms
->ms_intr_flags
|= INTR_TX_EMPTY
;
218 /* Ask for softint() call. */
223 ms_zs_stint(struct zs_chanstate
*cs
, int force
)
230 rr0
= zs_read_csr(cs
);
231 zs_write_csr(cs
, ZSWR0_RESET_STATUS
);
234 * We have to accumulate status line changes here.
235 * Otherwise, if we get multiple status interrupts
236 * before the softint runs, we could fail to notice
237 * some status line changes in the softint routine.
238 * Fix from Bill Studenmund, October 1996.
240 cs
->cs_rr0_delta
|= (cs
->cs_rr0
^ rr0
);
242 ms
->ms_intr_flags
|= INTR_ST_CHECK
;
244 /* Ask for softint() call. */
249 ms_zs_softint(struct zs_chanstate
*cs
)
258 /* Atomically get and clear flags. */
260 intr_flags
= ms
->ms_intr_flags
;
261 ms
->ms_intr_flags
= 0;
263 /* Now lower to spltty for the rest. */
267 * Copy data from the receive ring to the event layer.
270 while (get
!= ms
->ms_rbput
) {
271 ring_data
= ms
->ms_rbuf
[get
];
272 get
= (get
+ 1) & MS_RX_RING_MASK
;
274 /* low byte of ring_data is rr1 */
275 c
= (ring_data
>> 8) & 0xff;
277 if (ring_data
& ZSRR1_DO
)
278 intr_flags
|= INTR_RX_OVERRUN
;
279 if (ring_data
& (ZSRR1_FE
| ZSRR1_PE
)) {
280 log(LOG_ERR
, "%s: input error (0x%x)\n",
281 device_xname(ms
->ms_dev
), ring_data
);
282 c
= -1; /* signal input error */
285 /* Pass this up to the "middle" layer. */
288 if (intr_flags
& INTR_RX_OVERRUN
) {
289 log(LOG_ERR
, "%s: input overrun\n",
290 device_xname(ms
->ms_dev
));
294 if (intr_flags
& INTR_TX_EMPTY
) {
296 * Transmit done. (Not expected.)
298 log(LOG_ERR
, "%s: transmit interrupt?\n",
299 device_xname(ms
->ms_dev
));
302 if (intr_flags
& INTR_ST_CHECK
) {
304 * Status line change. (Not expected.)
306 log(LOG_ERR
, "%s: status interrupt?\n",
307 device_xname(ms
->ms_dev
));
308 cs
->cs_rr0_delta
= 0;