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