1 1.28 chs /* $NetBSD: opmbell.c,v 1.28 2019/11/10 21:16:33 chs Exp $ */ 2 1.1 oki 3 1.1 oki /* 4 1.1 oki * Copyright (c) 1995 MINOURA Makoto, Takuya Harakawa. 5 1.1 oki * All rights reserved. 6 1.1 oki * 7 1.1 oki * Redistribution and use in source and binary forms, with or without 8 1.1 oki * modification, are permitted provided that the following conditions 9 1.1 oki * are met: 10 1.1 oki * 1. Redistributions of source code must retain the above copyright 11 1.1 oki * notice, this list of conditions and the following disclaimer. 12 1.1 oki * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 oki * notice, this list of conditions and the following disclaimer in the 14 1.1 oki * documentation and/or other materials provided with the distribution. 15 1.1 oki * 3. All advertising materials mentioning features or use of this software 16 1.1 oki * must display the following acknowledgement: 17 1.1 oki * This product includes software developed by MINOURA Makoto, 18 1.1 oki * Takuya Harakawa. 19 1.1 oki * 4. Neither the name of the authors may be used to endorse or promote 20 1.1 oki * products derived from this software without specific prior written 21 1.1 oki * permission. 22 1.1 oki * 23 1.1 oki * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 1.1 oki * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 1.1 oki * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 1.1 oki * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 1.1 oki * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 1.1 oki * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 1.1 oki * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 1.1 oki * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 1.1 oki * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 1.1 oki * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 1.1 oki * SUCH DAMAGE. 34 1.1 oki * 35 1.1 oki */ 36 1.1 oki 37 1.1 oki /* 38 1.1 oki * bell device driver 39 1.1 oki */ 40 1.11 lukem 41 1.11 lukem #include <sys/cdefs.h> 42 1.28 chs __KERNEL_RCSID(0, "$NetBSD: opmbell.c,v 1.28 2019/11/10 21:16:33 chs Exp $"); 43 1.1 oki 44 1.1 oki #include "bell.h" 45 1.1 oki #if NBELL > 0 46 1.1 oki 47 1.1 oki #if NBELL > 1 48 1.1 oki #undef NBELL 49 1.1 oki #define NBELL 1 50 1.1 oki #endif 51 1.1 oki 52 1.1 oki #include <sys/param.h> 53 1.1 oki #include <sys/errno.h> 54 1.1 oki #include <sys/uio.h> 55 1.1 oki #include <sys/device.h> 56 1.1 oki #include <sys/malloc.h> 57 1.1 oki #include <sys/file.h> 58 1.1 oki #include <sys/systm.h> 59 1.7 thorpej #include <sys/callout.h> 60 1.5 oki #include <sys/conf.h> 61 1.10 jdolecek #include <sys/event.h> 62 1.18 isaki #include <sys/kernel.h> 63 1.1 oki 64 1.12 minoura #include <machine/opmbellio.h> 65 1.12 minoura 66 1.12 minoura #include <x68k/dev/opmvar.h> 67 1.1 oki 68 1.27 christos #include "ioconf.h" 69 1.26 christos 70 1.6 minoura /* In opm.c. */ 71 1.13 chs void opm_set_volume(int, int); 72 1.13 chs void opm_set_key(int, int); 73 1.13 chs void opm_set_voice(int, struct opm_voice *); 74 1.13 chs void opm_key_on(u_char); 75 1.13 chs void opm_key_off(u_char); 76 1.6 minoura 77 1.13 chs static u_int bell_pitchtokey(u_int); 78 1.13 chs static void bell_timeout(void *); 79 1.1 oki 80 1.1 oki struct bell_softc { 81 1.1 oki int sc_flags; 82 1.1 oki u_char ch; 83 1.1 oki u_char volume; 84 1.1 oki u_int pitch; 85 1.1 oki u_int msec; 86 1.1 oki u_int key; 87 1.1 oki }; 88 1.1 oki 89 1.1 oki struct bell_softc *bell_softc; 90 1.1 oki 91 1.20 ad callout_t bell_ch; 92 1.7 thorpej 93 1.1 oki static struct opm_voice vtab[NBELL]; 94 1.1 oki 95 1.12 minoura static struct opm_voice bell_voice = DEFAULT_BELL_VOICE; 96 1.12 minoura 97 1.1 oki /* sc_flags values */ 98 1.1 oki #define BELLF_READ 0x01 99 1.1 oki #define BELLF_WRITE 0x02 100 1.1 oki #define BELLF_ALIVE 0x04 101 1.1 oki #define BELLF_OPEN 0x08 102 1.1 oki #define BELLF_OUT 0x10 103 1.1 oki #define BELLF_ON 0x20 104 1.1 oki 105 1.1 oki #define UNIT(x) minor(x) 106 1.1 oki 107 1.13 chs void bell_on(struct bell_softc *); 108 1.13 chs void bell_off(struct bell_softc *); 109 1.13 chs void opm_bell(void); 110 1.13 chs void opm_bell_on(void); 111 1.13 chs void opm_bell_off(void); 112 1.13 chs int opm_bell_setup(struct bell_info *); 113 1.13 chs int bellmstohz(int); 114 1.5 oki 115 1.9 gehenna dev_type_open(bellopen); 116 1.9 gehenna dev_type_close(bellclose); 117 1.9 gehenna dev_type_ioctl(bellioctl); 118 1.9 gehenna 119 1.9 gehenna const struct cdevsw bell_cdevsw = { 120 1.24 dholland .d_open = bellopen, 121 1.24 dholland .d_close = bellclose, 122 1.24 dholland .d_read = noread, 123 1.24 dholland .d_write = nowrite, 124 1.24 dholland .d_ioctl = bellioctl, 125 1.24 dholland .d_stop = nostop, 126 1.24 dholland .d_tty = notty, 127 1.24 dholland .d_poll = nopoll, 128 1.24 dholland .d_mmap = nommap, 129 1.24 dholland .d_kqfilter = nokqfilter, 130 1.25 dholland .d_discard = nodiscard, 131 1.24 dholland .d_flag = 0 132 1.9 gehenna }; 133 1.5 oki 134 1.16 isaki void 135 1.13 chs bellattach(int num) 136 1.1 oki { 137 1.13 chs u_long size; 138 1.13 chs struct bell_softc *sc; 139 1.1 oki int unit; 140 1.1 oki 141 1.1 oki if (num <= 0) 142 1.1 oki return; 143 1.20 ad callout_init(&bell_ch, 0); 144 1.1 oki size = num * sizeof(struct bell_softc); 145 1.28 chs bell_softc = malloc(size, M_DEVBUF, M_WAITOK | M_ZERO); 146 1.1 oki for (unit = 0; unit < num; unit++) { 147 1.1 oki sc = &bell_softc[unit]; 148 1.1 oki sc->sc_flags = BELLF_ALIVE; 149 1.1 oki sc->ch = BELL_CHANNEL; 150 1.1 oki sc->volume = BELL_VOLUME; 151 1.1 oki sc->pitch = BELL_PITCH; 152 1.1 oki sc->msec = BELL_DURATION; 153 1.1 oki sc->key = bell_pitchtokey(sc->pitch); 154 1.1 oki 155 1.1 oki /* setup initial voice parameter */ 156 1.8 wiz memcpy(&vtab[unit], &bell_voice, sizeof(bell_voice)); 157 1.1 oki opm_set_voice(sc->ch, &vtab[unit]); 158 1.1 oki 159 1.4 christos printf("bell%d: YM2151 OPM bell emulation.\n", unit); 160 1.1 oki } 161 1.1 oki } 162 1.1 oki 163 1.16 isaki int 164 1.14 christos bellopen(dev_t dev, int flags, int mode, struct lwp *l) 165 1.1 oki { 166 1.13 chs int unit = UNIT(dev); 167 1.13 chs struct bell_softc *sc = &bell_softc[unit]; 168 1.1 oki 169 1.1 oki if (unit >= NBELL || !(sc->sc_flags & BELLF_ALIVE)) 170 1.1 oki return ENXIO; 171 1.1 oki 172 1.1 oki if (sc->sc_flags & BELLF_OPEN) 173 1.1 oki return EBUSY; 174 1.1 oki 175 1.1 oki sc->sc_flags |= BELLF_OPEN; 176 1.1 oki sc->sc_flags |= (flags & (FREAD | FWRITE)); 177 1.1 oki 178 1.1 oki return 0; 179 1.1 oki } 180 1.1 oki 181 1.16 isaki int 182 1.14 christos bellclose(dev_t dev, int flags, int mode, struct lwp *l) 183 1.1 oki { 184 1.1 oki int unit = UNIT(dev); 185 1.1 oki struct bell_softc *sc = &bell_softc[unit]; 186 1.1 oki 187 1.1 oki sc->sc_flags &= ~BELLF_OPEN; 188 1.5 oki return 0; 189 1.1 oki } 190 1.1 oki 191 1.16 isaki int 192 1.15 christos bellioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l) 193 1.1 oki { 194 1.1 oki int unit = UNIT(dev); 195 1.1 oki struct bell_softc *sc = &bell_softc[unit]; 196 1.1 oki 197 1.1 oki switch (cmd) { 198 1.1 oki case BELLIOCGPARAM: 199 1.1 oki { 200 1.17 isaki struct bell_info *bp = (struct bell_info *)addr; 201 1.17 isaki if (!(sc->sc_flags & FREAD)) 202 1.17 isaki return EBADF; 203 1.17 isaki 204 1.17 isaki bp->volume = sc->volume; 205 1.17 isaki bp->pitch = sc->pitch; 206 1.17 isaki bp->msec = sc->msec; 207 1.17 isaki break; 208 1.1 oki } 209 1.1 oki 210 1.1 oki case BELLIOCSPARAM: 211 1.1 oki { 212 1.17 isaki struct bell_info *bp = (struct bell_info *)addr; 213 1.1 oki 214 1.17 isaki if (!(sc->sc_flags & FWRITE)) 215 1.17 isaki return EBADF; 216 1.1 oki 217 1.17 isaki return opm_bell_setup(bp); 218 1.1 oki } 219 1.1 oki 220 1.1 oki case BELLIOCGVOICE: 221 1.17 isaki if (!(sc->sc_flags & FREAD)) 222 1.17 isaki return EBADF; 223 1.1 oki 224 1.17 isaki if (addr == NULL) 225 1.17 isaki return EFAULT; 226 1.1 oki 227 1.17 isaki memcpy(addr, &vtab[unit], sizeof(struct opm_voice)); 228 1.17 isaki break; 229 1.1 oki 230 1.1 oki case BELLIOCSVOICE: 231 1.17 isaki if (!(sc->sc_flags & FWRITE)) 232 1.17 isaki return EBADF; 233 1.1 oki 234 1.17 isaki if (addr == NULL) 235 1.17 isaki return EFAULT; 236 1.1 oki 237 1.17 isaki memcpy(&vtab[unit], addr, sizeof(struct opm_voice)); 238 1.17 isaki opm_set_voice(sc->ch, &vtab[unit]); 239 1.17 isaki break; 240 1.1 oki 241 1.1 oki default: 242 1.17 isaki return EINVAL; 243 1.1 oki } 244 1.1 oki return 0; 245 1.1 oki } 246 1.1 oki 247 1.1 oki /* 248 1.1 oki * The next table is used for calculating KeyCode/KeyFraction pair 249 1.1 oki * from frequency. 250 1.1 oki */ 251 1.1 oki 252 1.1 oki static u_int note[] = { 253 1.13 chs 0x0800, 0x0808, 0x0810, 0x081c, 254 1.13 chs 0x0824, 0x0830, 0x0838, 0x0844, 255 1.13 chs 0x084c, 0x0858, 0x0860, 0x086c, 256 1.13 chs 0x0874, 0x0880, 0x0888, 0x0890, 257 1.13 chs 0x089c, 0x08a4, 0x08b0, 0x08b8, 258 1.13 chs 0x08c4, 0x08cc, 0x08d8, 0x08e0, 259 1.13 chs 0x08ec, 0x08f4, 0x0900, 0x0908, 260 1.13 chs 0x0910, 0x091c, 0x0924, 0x092c, 261 1.13 chs 0x0938, 0x0940, 0x0948, 0x0954, 262 1.13 chs 0x095c, 0x0968, 0x0970, 0x0978, 263 1.13 chs 0x0984, 0x098c, 0x0994, 0x09a0, 264 1.13 chs 0x09a8, 0x09b4, 0x09bc, 0x09c4, 265 1.13 chs 0x09d0, 0x09d8, 0x09e0, 0x09ec, 266 1.13 chs 0x09f4, 0x0a00, 0x0a08, 0x0a10, 267 1.13 chs 0x0a18, 0x0a20, 0x0a28, 0x0a30, 268 1.13 chs 0x0a38, 0x0a44, 0x0a4c, 0x0a54, 269 1.13 chs 0x0a5c, 0x0a64, 0x0a6c, 0x0a74, 270 1.13 chs 0x0a80, 0x0a88, 0x0a90, 0x0a98, 271 1.13 chs 0x0aa0, 0x0aa8, 0x0ab0, 0x0ab8, 272 1.13 chs 0x0ac4, 0x0acc, 0x0ad4, 0x0adc, 273 1.13 chs 0x0ae4, 0x0aec, 0x0af4, 0x0c00, 274 1.13 chs 0x0c08, 0x0c10, 0x0c18, 0x0c20, 275 1.13 chs 0x0c28, 0x0c30, 0x0c38, 0x0c40, 276 1.13 chs 0x0c48, 0x0c50, 0x0c58, 0x0c60, 277 1.13 chs 0x0c68, 0x0c70, 0x0c78, 0x0c84, 278 1.13 chs 0x0c8c, 0x0c94, 0x0c9c, 0x0ca4, 279 1.13 chs 0x0cac, 0x0cb4, 0x0cbc, 0x0cc4, 280 1.13 chs 0x0ccc, 0x0cd4, 0x0cdc, 0x0ce4, 281 1.13 chs 0x0cec, 0x0cf4, 0x0d00, 0x0d04, 282 1.13 chs 0x0d0c, 0x0d14, 0x0d1c, 0x0d24, 283 1.13 chs 0x0d2c, 0x0d34, 0x0d3c, 0x0d44, 284 1.13 chs 0x0d4c, 0x0d54, 0x0d5c, 0x0d64, 285 1.13 chs 0x0d6c, 0x0d74, 0x0d7c, 0x0d80, 286 1.13 chs 0x0d88, 0x0d90, 0x0d98, 0x0da0, 287 1.13 chs 0x0da8, 0x0db0, 0x0db8, 0x0dc0, 288 1.13 chs 0x0dc8, 0x0dd0, 0x0dd8, 0x0de0, 289 1.13 chs 0x0de8, 0x0df0, 0x0df8, 0x0e00, 290 1.13 chs 0x0e04, 0x0e0c, 0x0e14, 0x0e1c, 291 1.13 chs 0x0e24, 0x0e28, 0x0e30, 0x0e38, 292 1.13 chs 0x0e40, 0x0e48, 0x0e50, 0x0e54, 293 1.13 chs 0x0e5c, 0x0e64, 0x0e6c, 0x0e74, 294 1.13 chs 0x0e7c, 0x0e80, 0x0e88, 0x0e90, 295 1.13 chs 0x0e98, 0x0ea0, 0x0ea8, 0x0eac, 296 1.13 chs 0x0eb4, 0x0ebc, 0x0ec4, 0x0ecc, 297 1.13 chs 0x0ed4, 0x0ed8, 0x0ee0, 0x0ee8, 298 1.13 chs 0x0ef0, 0x0ef8, 0x1000, 0x1004, 299 1.13 chs 0x100c, 0x1014, 0x1018, 0x1020, 300 1.13 chs 0x1028, 0x1030, 0x1034, 0x103c, 301 1.13 chs 0x1044, 0x104c, 0x1050, 0x1058, 302 1.13 chs 0x1060, 0x1064, 0x106c, 0x1074, 303 1.13 chs 0x107c, 0x1080, 0x1088, 0x1090, 304 1.13 chs 0x1098, 0x109c, 0x10a4, 0x10ac, 305 1.13 chs 0x10b0, 0x10b8, 0x10c0, 0x10c8, 306 1.13 chs 0x10cc, 0x10d4, 0x10dc, 0x10e4, 307 1.13 chs 0x10e8, 0x10f0, 0x10f8, 0x1100, 308 1.13 chs 0x1104, 0x110c, 0x1110, 0x1118, 309 1.13 chs 0x1120, 0x1124, 0x112c, 0x1134, 310 1.13 chs 0x1138, 0x1140, 0x1148, 0x114c, 311 1.13 chs 0x1154, 0x1158, 0x1160, 0x1168, 312 1.13 chs 0x116c, 0x1174, 0x117c, 0x1180, 313 1.13 chs 0x1188, 0x1190, 0x1194, 0x119c, 314 1.13 chs 0x11a4, 0x11a8, 0x11b0, 0x11b4, 315 1.13 chs 0x11bc, 0x11c4, 0x11c8, 0x11d0, 316 1.13 chs 0x11d8, 0x11dc, 0x11e4, 0x11ec, 317 1.13 chs 0x11f0, 0x11f8, 0x1200, 0x1204, 318 1.13 chs 0x120c, 0x1210, 0x1218, 0x121c, 319 1.13 chs 0x1224, 0x1228, 0x1230, 0x1238, 320 1.13 chs 0x123c, 0x1244, 0x1248, 0x1250, 321 1.13 chs 0x1254, 0x125c, 0x1260, 0x1268, 322 1.13 chs 0x1270, 0x1274, 0x127c, 0x1280, 323 1.13 chs 0x1288, 0x128c, 0x1294, 0x129c, 324 1.13 chs 0x12a0, 0x12a8, 0x12ac, 0x12b4, 325 1.13 chs 0x12b8, 0x12c0, 0x12c4, 0x12cc, 326 1.13 chs 0x12d4, 0x12d8, 0x12e0, 0x12e4, 327 1.13 chs 0x12ec, 0x12f0, 0x12f8, 0x1400, 328 1.13 chs 0x1404, 0x1408, 0x1410, 0x1414, 329 1.13 chs 0x141c, 0x1420, 0x1428, 0x142c, 330 1.13 chs 0x1434, 0x1438, 0x1440, 0x1444, 331 1.13 chs 0x1448, 0x1450, 0x1454, 0x145c, 332 1.13 chs 0x1460, 0x1468, 0x146c, 0x1474, 333 1.13 chs 0x1478, 0x1480, 0x1484, 0x1488, 334 1.13 chs 0x1490, 0x1494, 0x149c, 0x14a0, 335 1.13 chs 0x14a8, 0x14ac, 0x14b4, 0x14b8, 336 1.13 chs 0x14c0, 0x14c4, 0x14c8, 0x14d0, 337 1.13 chs 0x14d4, 0x14dc, 0x14e0, 0x14e8, 338 1.13 chs 0x14ec, 0x14f4, 0x14f8, 0x1500, 339 1.13 chs 0x1504, 0x1508, 0x1510, 0x1514, 340 1.13 chs 0x1518, 0x1520, 0x1524, 0x1528, 341 1.13 chs 0x1530, 0x1534, 0x1538, 0x1540, 342 1.13 chs 0x1544, 0x154c, 0x1550, 0x1554, 343 1.13 chs 0x155c, 0x1560, 0x1564, 0x156c, 344 1.13 chs 0x1570, 0x1574, 0x157c, 0x1580, 345 1.13 chs 0x1588, 0x158c, 0x1590, 0x1598, 346 1.13 chs 0x159c, 0x15a0, 0x15a8, 0x15ac, 347 1.13 chs 0x15b0, 0x15b8, 0x15bc, 0x15c4, 348 1.13 chs 0x15c8, 0x15cc, 0x15d4, 0x15d8, 349 1.13 chs 0x15dc, 0x15e4, 0x15e8, 0x15ec, 350 1.13 chs 0x15f4, 0x15f8, 0x1600, 0x1604, 351 1.13 chs 0x1608, 0x160c, 0x1614, 0x1618, 352 1.13 chs 0x161c, 0x1620, 0x1628, 0x162c, 353 1.13 chs 0x1630, 0x1638, 0x163c, 0x1640, 354 1.13 chs 0x1644, 0x164c, 0x1650, 0x1654, 355 1.13 chs 0x165c, 0x1660, 0x1664, 0x1668, 356 1.13 chs 0x1670, 0x1674, 0x1678, 0x1680, 357 1.13 chs 0x1684, 0x1688, 0x168c, 0x1694, 358 1.13 chs 0x1698, 0x169c, 0x16a0, 0x16a8, 359 1.13 chs 0x16ac, 0x16b0, 0x16b8, 0x16bc, 360 1.13 chs 0x16c0, 0x16c4, 0x16cc, 0x16d0, 361 1.13 chs 0x16d4, 0x16dc, 0x16e0, 0x16e4, 362 1.13 chs 0x16e8, 0x16f0, 0x16f4, 0x16f8, 363 1.1 oki }; 364 1.1 oki 365 1.16 isaki static u_int 366 1.13 chs bell_pitchtokey(u_int pitch) 367 1.1 oki { 368 1.13 chs int i, oct; 369 1.13 chs u_int key; 370 1.1 oki 371 1.13 chs i = 16 * pitch / 440; 372 1.13 chs for (oct = -1; i > 0; i >>= 1, oct++) 373 1.13 chs ; 374 1.1 oki 375 1.13 chs i = (pitch * 16 - (440 * (1 << oct))) / (1 << oct); 376 1.13 chs key = (oct << 12) + note[i]; 377 1.1 oki 378 1.13 chs return key; 379 1.1 oki } 380 1.1 oki 381 1.1 oki /* 382 1.1 oki * The next table is a little trikcy table of volume factors. 383 1.1 oki * Its values have been calculated as table[i] = -15 * log10(i/100) 384 1.1 oki * with an obvious exception for i = 0; This log-table converts a linear 385 1.1 oki * volume-scaling (0...100) to a logarithmic scaling as present in the 386 1.16 isaki * OPM chips. so: Volume 50% = 6 db. 387 1.1 oki */ 388 1.1 oki 389 1.1 oki static u_char vol_table[] = { 390 1.13 chs 0x7f, 0x35, 0x2d, 0x28, 0x25, 0x22, 0x20, 0x1e, 391 1.13 chs 0x1d, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16, 0x15, 392 1.13 chs 0x15, 0x14, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 393 1.13 chs 0x10, 0x10, 0x0f, 0x0f, 0x0e, 0x0e, 0x0d, 0x0d, 394 1.13 chs 0x0d, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0a, 395 1.13 chs 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x08, 0x08, 396 1.13 chs 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06, 397 1.13 chs 0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 398 1.13 chs 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 399 1.13 chs 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 400 1.13 chs 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 401 1.13 chs 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 402 1.13 chs 0x00, 0x00, 0x00, 0x00, 0x00, 403 1.1 oki }; 404 1.1 oki 405 1.16 isaki void 406 1.13 chs bell_on(struct bell_softc *sc) 407 1.1 oki { 408 1.13 chs int sps; 409 1.1 oki 410 1.13 chs sps = spltty(); 411 1.13 chs opm_set_volume(sc->ch, vol_table[sc->volume]); 412 1.13 chs opm_set_key(sc->ch, sc->key); 413 1.13 chs splx(sps); 414 1.1 oki 415 1.13 chs opm_key_on(sc->ch); 416 1.13 chs sc->sc_flags |= BELLF_ON; 417 1.1 oki } 418 1.1 oki 419 1.16 isaki void 420 1.13 chs bell_off(struct bell_softc *sc) 421 1.1 oki { 422 1.13 chs if (sc->sc_flags & BELLF_ON) { 423 1.13 chs opm_key_off(sc->ch); 424 1.13 chs sc->sc_flags &= ~BELLF_ON; 425 1.13 chs } 426 1.1 oki } 427 1.1 oki 428 1.16 isaki void 429 1.13 chs opm_bell(void) 430 1.1 oki { 431 1.13 chs struct bell_softc *sc = &bell_softc[0]; 432 1.13 chs int ticks; 433 1.1 oki 434 1.13 chs if (sc->msec != 0) { 435 1.13 chs if (sc->sc_flags & BELLF_OUT) { 436 1.13 chs bell_timeout(0); 437 1.13 chs } else if (sc->sc_flags & BELLF_ON) 438 1.13 chs return; 439 1.1 oki 440 1.13 chs ticks = bellmstohz(sc->msec); 441 1.1 oki 442 1.13 chs bell_on(sc); 443 1.13 chs sc->sc_flags |= BELLF_OUT; 444 1.1 oki 445 1.13 chs callout_reset(&bell_ch, ticks, bell_timeout, NULL); 446 1.13 chs } 447 1.1 oki } 448 1.1 oki 449 1.16 isaki static void 450 1.13 chs bell_timeout(void *arg) 451 1.1 oki { 452 1.13 chs struct bell_softc *sc = &bell_softc[0]; 453 1.1 oki 454 1.19 isaki sc->sc_flags &= ~BELLF_OUT; 455 1.13 chs bell_off(sc); 456 1.13 chs callout_stop(&bell_ch); 457 1.1 oki } 458 1.1 oki 459 1.16 isaki void 460 1.13 chs opm_bell_on(void) 461 1.1 oki { 462 1.13 chs struct bell_softc *sc = &bell_softc[0]; 463 1.13 chs 464 1.13 chs if (sc->sc_flags & BELLF_OUT) 465 1.13 chs bell_timeout(0); 466 1.13 chs if (sc->sc_flags & BELLF_ON) 467 1.13 chs return; 468 1.1 oki 469 1.13 chs bell_on(sc); 470 1.13 chs } 471 1.1 oki 472 1.16 isaki void 473 1.13 chs opm_bell_off(void) 474 1.13 chs { 475 1.13 chs struct bell_softc *sc = &bell_softc[0]; 476 1.13 chs 477 1.13 chs if (sc->sc_flags & BELLF_ON) 478 1.13 chs bell_off(sc); 479 1.1 oki } 480 1.1 oki 481 1.16 isaki int 482 1.13 chs opm_bell_setup(struct bell_info *data) 483 1.1 oki { 484 1.13 chs struct bell_softc *sc = &bell_softc[0]; 485 1.1 oki 486 1.13 chs /* bounds check */ 487 1.13 chs if (data->pitch > MAXBPITCH || data->pitch < MINBPITCH || 488 1.13 chs data->volume > MAXBVOLUME || data->msec > MAXBTIME) { 489 1.13 chs return EINVAL; 490 1.13 chs } else { 491 1.13 chs sc->volume = data->volume; 492 1.13 chs sc->pitch = data->pitch; 493 1.13 chs sc->msec = data->msec; 494 1.13 chs sc->key = bell_pitchtokey(data->pitch); 495 1.13 chs } 496 1.13 chs return 0; 497 1.1 oki } 498 1.1 oki 499 1.16 isaki int 500 1.13 chs bellmstohz(int m) 501 1.13 chs { 502 1.13 chs int h = m; 503 1.13 chs 504 1.13 chs if (h > 0) { 505 1.13 chs h = h * hz / 1000; 506 1.13 chs if (h == 0) 507 1.13 chs h = 1000 / hz; 508 1.13 chs } 509 1.13 chs return h; 510 1.1 oki } 511 1.1 oki 512 1.1 oki #endif 513