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 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 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 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 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