xref: /openbsd-src/sys/arch/sparc64/dev/beeper.c (revision 91f110e064cd7c194e59e019b83bb7496c1c84d4)
1 /*	$OpenBSD: beeper.c,v 1.10 2005/12/20 16:50:33 martin Exp $	*/
2 
3 /*
4  * Copyright (c) 2001 Jason L. Wright (jason@thought.net)
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
20  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
25  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  *
28  * Effort sponsored in part by the Defense Advanced Research Projects
29  * Agency (DARPA) and Air Force Research Laboratory, Air Force
30  * Materiel Command, USAF, under agreement number F30602-01-2-0537.
31  *
32  */
33 
34 /*
35  * Driver for beeper device on SUNW,Ultra-1-Engine.
36  */
37 
38 #include <sys/types.h>
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/kernel.h>
42 #include <sys/device.h>
43 #include <sys/conf.h>
44 #include <sys/timeout.h>
45 
46 #include <machine/bus.h>
47 #include <machine/autoconf.h>
48 #include <machine/openfirm.h>
49 
50 #include <sparc64/dev/ebusreg.h>
51 #include <sparc64/dev/ebusvar.h>
52 
53 #include "pckbd.h"
54 #if NPCKBD > 0
55 #include <dev/ic/pckbcvar.h>
56 #include <dev/pckbc/pckbdvar.h>
57 #endif
58 
59 struct beeper_softc {
60 	struct device		sc_dev;
61 	bus_space_tag_t		sc_iot;
62 	bus_space_handle_t	sc_ioh;
63 	struct timeout		sc_to;
64 	int 			sc_belltimeout, sc_bellactive;
65 };
66 
67 #define	BEEP_REG	0
68 
69 int	beeper_match(struct device *, void *, void *);
70 void	beeper_attach(struct device *, struct device *, void *);
71 
72 struct cfattach beeper_ca = {
73 	sizeof(struct beeper_softc), beeper_match, beeper_attach
74 };
75 
76 struct cfdriver beeper_cd = {
77 	NULL, "beeper", DV_DULL
78 };
79 
80 #if NPCKBD > 0
81 void beeper_stop(void *);
82 void beeper_bell(void *, u_int, u_int, u_int, int);
83 #endif
84 
85 int
86 beeper_match(parent, match, aux)
87 	struct device *parent;
88 	void *match;
89 	void *aux;
90 {
91 	struct ebus_attach_args *ea = aux;
92 
93 	if (strcmp(ea->ea_name, "beeper") == 0)
94 		return (1);
95 	return (0);
96 }
97 
98 void
99 beeper_attach(parent, self, aux)
100 	struct device *parent, *self;
101 	void *aux;
102 {
103 	struct beeper_softc *sc = (void *)self;
104 	struct ebus_attach_args *ea = aux;
105 
106 	sc->sc_iot = ea->ea_memtag;
107 
108 	/* Use prom address if available, otherwise map it. */
109 	if (ea->ea_nvaddrs) {
110 		if (bus_space_map(sc->sc_iot, ea->ea_vaddrs[0], 0,
111 		    BUS_SPACE_MAP_PROMADDRESS, &sc->sc_ioh)) {
112 			printf(": can't map PROM register space\n");
113 			return;
114 		}
115 	} else if (ebus_bus_map(sc->sc_iot, 0,
116 	    EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), ea->ea_regs[0].size, 0, 0,
117 	    &sc->sc_ioh) != 0) {
118 		printf(": can't map register space\n");
119                 return;
120 	}
121 
122 #if NPCKBD > 0
123 	timeout_set(&sc->sc_to, beeper_stop, sc);
124 	pckbd_hookup_bell(beeper_bell, sc);
125 #endif
126 	printf("\n");
127 }
128 
129 #if NPCKBD > 0
130 void
131 beeper_stop(vsc)
132 	void *vsc;
133 {
134 	struct beeper_softc *sc = vsc;
135 	int s;
136 
137 	s = spltty();
138 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, BEEP_REG, 0);
139 	sc->sc_bellactive = 0;
140 	sc->sc_belltimeout = 0;
141 	splx(s);
142 }
143 
144 void
145 beeper_bell(vsc, pitch, period, volume, poll)
146 	void *vsc;
147 	u_int pitch, period, volume;
148 	int poll;
149 {
150 	struct beeper_softc *sc = vsc;
151 	int s, ticks;
152 
153 	ticks = (period * hz) / 1000;
154 	if (ticks <= 0)
155 		ticks = 1;
156 
157 	s = spltty();
158 	if (sc->sc_bellactive) {
159 		if (sc->sc_belltimeout == 0)
160 			timeout_del(&sc->sc_to);
161 	}
162 	if (pitch == 0 || period == 0) {
163 		beeper_stop(sc);
164 		splx(s);
165 		return;
166 	}
167 	if (!sc->sc_bellactive) {
168 		sc->sc_bellactive = 1;
169 		sc->sc_belltimeout = 1;
170 		bus_space_write_4(sc->sc_iot, sc->sc_ioh, BEEP_REG, 1);
171 		timeout_add(&sc->sc_to, ticks);
172 	}
173 	splx(s);
174 }
175 #endif /* NPCKBD > 0 */
176