1 /* $OpenBSD: beeper.c,v 1.13 2019/06/22 20:30:42 kn 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 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 85 beeper_match(parent, match, aux) 86 struct device *parent; 87 void *match; 88 void *aux; 89 { 90 struct ebus_attach_args *ea = aux; 91 92 if (strcmp(ea->ea_name, "beeper") == 0) 93 return (1); 94 return (0); 95 } 96 97 void 98 beeper_attach(parent, self, aux) 99 struct device *parent, *self; 100 void *aux; 101 { 102 struct beeper_softc *sc = (void *)self; 103 struct ebus_attach_args *ea = aux; 104 105 sc->sc_iot = ea->ea_memtag; 106 107 /* Use prom address if available, otherwise map it. */ 108 if (ea->ea_nvaddrs) { 109 if (bus_space_map(sc->sc_iot, ea->ea_vaddrs[0], 0, 110 BUS_SPACE_MAP_PROMADDRESS, &sc->sc_ioh)) { 111 printf(": can't map PROM register space\n"); 112 return; 113 } 114 } else if (ebus_bus_map(sc->sc_iot, 0, 115 EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), ea->ea_regs[0].size, 0, 0, 116 &sc->sc_ioh) != 0) { 117 printf(": can't map register space\n"); 118 return; 119 } 120 121 #if NPCKBD > 0 122 timeout_set(&sc->sc_to, beeper_stop, sc); 123 pckbd_hookup_bell(beeper_bell, sc); 124 #endif 125 printf("\n"); 126 } 127 128 #if NPCKBD > 0 129 void 130 beeper_stop(vsc) 131 void *vsc; 132 { 133 struct beeper_softc *sc = vsc; 134 int s; 135 136 s = spltty(); 137 bus_space_write_4(sc->sc_iot, sc->sc_ioh, BEEP_REG, 0); 138 sc->sc_bellactive = 0; 139 sc->sc_belltimeout = 0; 140 splx(s); 141 } 142 143 void 144 beeper_bell(vsc, pitch, period, volume, poll) 145 void *vsc; 146 u_int pitch, period, volume; 147 int poll; 148 { 149 struct beeper_softc *sc = vsc; 150 int s; 151 152 s = spltty(); 153 if (sc->sc_bellactive) { 154 if (sc->sc_belltimeout == 0) 155 timeout_del(&sc->sc_to); 156 } 157 if (pitch == 0 || period == 0) { 158 beeper_stop(sc); 159 splx(s); 160 return; 161 } 162 if (!sc->sc_bellactive) { 163 sc->sc_bellactive = 1; 164 sc->sc_belltimeout = 1; 165 bus_space_write_4(sc->sc_iot, sc->sc_ioh, BEEP_REG, 1); 166 timeout_add_msec(&sc->sc_to, period); 167 } 168 splx(s); 169 } 170 #endif /* NPCKBD > 0 */ 171