1 /* $OpenBSD: beeper.c,v 1.15 2022/10/16 01:22:39 jsg 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/param.h>
39 #include <sys/systm.h>
40 #include <sys/kernel.h>
41 #include <sys/device.h>
42 #include <sys/conf.h>
43 #include <sys/timeout.h>
44
45 #include <machine/bus.h>
46 #include <machine/autoconf.h>
47 #include <machine/openfirm.h>
48
49 #include <sparc64/dev/ebusreg.h>
50 #include <sparc64/dev/ebusvar.h>
51
52 #include "pckbd.h"
53 #if NPCKBD > 0
54 #include <dev/ic/pckbcvar.h>
55 #include <dev/pckbc/pckbdvar.h>
56 #endif
57
58 struct beeper_softc {
59 struct device sc_dev;
60 bus_space_tag_t sc_iot;
61 bus_space_handle_t sc_ioh;
62 struct timeout sc_to;
63 int sc_belltimeout, sc_bellactive;
64 };
65
66 #define BEEP_REG 0
67
68 int beeper_match(struct device *, void *, void *);
69 void beeper_attach(struct device *, struct device *, void *);
70
71 const struct cfattach beeper_ca = {
72 sizeof(struct beeper_softc), beeper_match, beeper_attach
73 };
74
75 struct cfdriver beeper_cd = {
76 NULL, "beeper", DV_DULL
77 };
78
79 #if NPCKBD > 0
80 void beeper_stop(void *);
81 void beeper_bell(void *, u_int, u_int, u_int, int);
82 #endif
83
84 int
beeper_match(struct device * parent,void * match,void * aux)85 beeper_match(struct device *parent, void *match, void *aux)
86 {
87 struct ebus_attach_args *ea = aux;
88
89 if (strcmp(ea->ea_name, "beeper") == 0)
90 return (1);
91 return (0);
92 }
93
94 void
beeper_attach(struct device * parent,struct device * self,void * aux)95 beeper_attach(struct device *parent, struct device *self, void *aux)
96 {
97 struct beeper_softc *sc = (void *)self;
98 struct ebus_attach_args *ea = aux;
99
100 sc->sc_iot = ea->ea_memtag;
101
102 /* Use prom address if available, otherwise map it. */
103 if (ea->ea_nvaddrs) {
104 if (bus_space_map(sc->sc_iot, ea->ea_vaddrs[0], 0,
105 BUS_SPACE_MAP_PROMADDRESS, &sc->sc_ioh)) {
106 printf(": can't map PROM register space\n");
107 return;
108 }
109 } else if (ebus_bus_map(sc->sc_iot, 0,
110 EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), ea->ea_regs[0].size, 0, 0,
111 &sc->sc_ioh) != 0) {
112 printf(": can't map register space\n");
113 return;
114 }
115
116 #if NPCKBD > 0
117 timeout_set(&sc->sc_to, beeper_stop, sc);
118 pckbd_hookup_bell(beeper_bell, sc);
119 #endif
120 printf("\n");
121 }
122
123 #if NPCKBD > 0
124 void
beeper_stop(void * vsc)125 beeper_stop(void *vsc)
126 {
127 struct beeper_softc *sc = vsc;
128 int s;
129
130 s = spltty();
131 bus_space_write_4(sc->sc_iot, sc->sc_ioh, BEEP_REG, 0);
132 sc->sc_bellactive = 0;
133 sc->sc_belltimeout = 0;
134 splx(s);
135 }
136
137 void
beeper_bell(void * vsc,u_int pitch,u_int period,u_int volume,int poll)138 beeper_bell(void *vsc, u_int pitch, u_int period, u_int volume, int poll)
139 {
140 struct beeper_softc *sc = vsc;
141 int s;
142
143 s = spltty();
144 if (sc->sc_bellactive) {
145 if (sc->sc_belltimeout == 0)
146 timeout_del(&sc->sc_to);
147 }
148 if (pitch == 0 || period == 0) {
149 beeper_stop(sc);
150 splx(s);
151 return;
152 }
153 if (!sc->sc_bellactive) {
154 sc->sc_bellactive = 1;
155 sc->sc_belltimeout = 1;
156 bus_space_write_4(sc->sc_iot, sc->sc_ioh, BEEP_REG, 1);
157 timeout_add_msec(&sc->sc_to, period);
158 }
159 splx(s);
160 }
161 #endif /* NPCKBD > 0 */
162