| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: spkr.c,v 1.31 2010/07/27 14:34:34 jakllsch Exp $ */ | | 1 | /* $NetBSD: spkr.c,v 1.32 2012/02/01 02:01:28 matt Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1990 Eric S. Raymond (esr@snark.thyrsus.com) | | 4 | * Copyright (c) 1990 Eric S. Raymond (esr@snark.thyrsus.com) |
5 | * Copyright (c) 1990 Andrew A. Chernov (ache@astral.msk.su) | | 5 | * Copyright (c) 1990 Andrew A. Chernov (ache@astral.msk.su) |
6 | * Copyright (c) 1990 Lennart Augustsson (lennart@augustsson.net) | | 6 | * Copyright (c) 1990 Lennart Augustsson (lennart@augustsson.net) |
7 | * All rights reserved. | | 7 | * All rights reserved. |
8 | * | | 8 | * |
9 | * Redistribution and use in source and binary forms, with or without | | 9 | * Redistribution and use in source and binary forms, with or without |
10 | * modification, are permitted provided that the following conditions | | 10 | * modification, are permitted provided that the following conditions |
11 | * are met: | | 11 | * are met: |
12 | * 1. Redistributions of source code must retain the above copyright | | 12 | * 1. Redistributions of source code must retain the above copyright |
13 | * notice, this list of conditions and the following disclaimer. | | 13 | * notice, this list of conditions and the following disclaimer. |
14 | * 2. Redistributions in binary form must reproduce the above copyright | | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| @@ -33,27 +33,27 @@ | | | @@ -33,27 +33,27 @@ |
33 | * POSSIBILITY OF SUCH DAMAGE. | | 33 | * POSSIBILITY OF SUCH DAMAGE. |
34 | */ | | 34 | */ |
35 | | | 35 | |
36 | /* | | 36 | /* |
37 | * spkr.c -- device driver for console speaker on 80386 | | 37 | * spkr.c -- device driver for console speaker on 80386 |
38 | * | | 38 | * |
39 | * v1.1 by Eric S. Raymond (esr@snark.thyrsus.com) Feb 1990 | | 39 | * v1.1 by Eric S. Raymond (esr@snark.thyrsus.com) Feb 1990 |
40 | * modified for 386bsd by Andrew A. Chernov <ache@astral.msk.su> | | 40 | * modified for 386bsd by Andrew A. Chernov <ache@astral.msk.su> |
41 | * 386bsd only clean version, all SYSV stuff removed | | 41 | * 386bsd only clean version, all SYSV stuff removed |
42 | * use hz value from param.c | | 42 | * use hz value from param.c |
43 | */ | | 43 | */ |
44 | | | 44 | |
45 | #include <sys/cdefs.h> | | 45 | #include <sys/cdefs.h> |
46 | __KERNEL_RCSID(0, "$NetBSD: spkr.c,v 1.31 2010/07/27 14:34:34 jakllsch Exp $"); | | 46 | __KERNEL_RCSID(0, "$NetBSD: spkr.c,v 1.32 2012/02/01 02:01:28 matt Exp $"); |
47 | | | 47 | |
48 | #include <sys/param.h> | | 48 | #include <sys/param.h> |
49 | #include <sys/systm.h> | | 49 | #include <sys/systm.h> |
50 | #include <sys/kernel.h> | | 50 | #include <sys/kernel.h> |
51 | #include <sys/errno.h> | | 51 | #include <sys/errno.h> |
52 | #include <sys/device.h> | | 52 | #include <sys/device.h> |
53 | #include <sys/malloc.h> | | 53 | #include <sys/malloc.h> |
54 | #include <sys/uio.h> | | 54 | #include <sys/uio.h> |
55 | #include <sys/proc.h> | | 55 | #include <sys/proc.h> |
56 | #include <sys/ioctl.h> | | 56 | #include <sys/ioctl.h> |
57 | #include <sys/conf.h> | | 57 | #include <sys/conf.h> |
58 | | | 58 | |
59 | #include <sys/bus.h> | | 59 | #include <sys/bus.h> |
| @@ -78,38 +78,36 @@ const struct cdevsw spkr_cdevsw = { | | | @@ -78,38 +78,36 @@ const struct cdevsw spkr_cdevsw = { |
78 | nostop, notty, nopoll, nommap, nokqfilter, D_OTHER, | | 78 | nostop, notty, nopoll, nommap, nokqfilter, D_OTHER, |
79 | }; | | 79 | }; |
80 | | | 80 | |
81 | static pcppi_tag_t ppicookie; | | 81 | static pcppi_tag_t ppicookie; |
82 | | | 82 | |
83 | #define SPKRPRI (PZERO - 1) | | 83 | #define SPKRPRI (PZERO - 1) |
84 | | | 84 | |
85 | static void tone(u_int, u_int); | | 85 | static void tone(u_int, u_int); |
86 | static void rest(int); | | 86 | static void rest(int); |
87 | static void playinit(void); | | 87 | static void playinit(void); |
88 | static void playtone(int, int, int); | | 88 | static void playtone(int, int, int); |
89 | static void playstring(char *, int); | | 89 | static void playstring(char *, int); |
90 | | | 90 | |
91 | static | | 91 | static void |
92 | void tone(xhz, ticks) | | 92 | tone(u_int xhz, u_int ticks) |
93 | /* emit tone of frequency hz for given number of ticks */ | | 93 | /* emit tone of frequency hz for given number of ticks */ |
94 | u_int xhz, ticks; | | | |
95 | { | | 94 | { |
96 | pcppi_bell(ppicookie, xhz, ticks, PCPPI_BELL_SLEEP); | | 95 | pcppi_bell(ppicookie, xhz, ticks, PCPPI_BELL_SLEEP); |
97 | } | | 96 | } |
98 | | | 97 | |
99 | static void | | 98 | static void |
100 | rest(ticks) | | 99 | rest(int ticks) |
101 | /* rest for given number of ticks */ | | 100 | /* rest for given number of ticks */ |
102 | int ticks; | | | |
103 | { | | 101 | { |
104 | /* | | 102 | /* |
105 | * Set timeout to endrest function, then give up the timeslice. | | 103 | * Set timeout to endrest function, then give up the timeslice. |
106 | * This is so other processes can execute while the rest is being | | 104 | * This is so other processes can execute while the rest is being |
107 | * waited out. | | 105 | * waited out. |
108 | */ | | 106 | */ |
109 | #ifdef SPKRDEBUG | | 107 | #ifdef SPKRDEBUG |
110 | printf("rest: %d\n", ticks); | | 108 | printf("rest: %d\n", ticks); |
111 | #endif /* SPKRDEBUG */ | | 109 | #endif /* SPKRDEBUG */ |
112 | if (ticks > 0) | | 110 | if (ticks > 0) |
113 | tsleep(rest, SPKRPRI | PCATCH, "rest", ticks); | | 111 | tsleep(rest, SPKRPRI | PCATCH, "rest", ticks); |
114 | } | | 112 | } |
115 | | | 113 | |
| @@ -172,29 +170,28 @@ static const int pitchtab[] = | | | @@ -172,29 +170,28 @@ static const int pitchtab[] = |
172 | | | 170 | |
173 | static void | | 171 | static void |
174 | playinit(void) | | 172 | playinit(void) |
175 | { | | 173 | { |
176 | octave = DFLT_OCTAVE; | | 174 | octave = DFLT_OCTAVE; |
177 | whole = (hz * SECS_PER_MIN * WHOLE_NOTE) / DFLT_TEMPO; | | 175 | whole = (hz * SECS_PER_MIN * WHOLE_NOTE) / DFLT_TEMPO; |
178 | fill = NORMAL; | | 176 | fill = NORMAL; |
179 | value = DFLT_VALUE; | | 177 | value = DFLT_VALUE; |
180 | octtrack = false; | | 178 | octtrack = false; |
181 | octprefix = true; /* act as though there was an initial O(n) */ | | 179 | octprefix = true; /* act as though there was an initial O(n) */ |
182 | } | | 180 | } |
183 | | | 181 | |
184 | static void | | 182 | static void |
185 | playtone(pitch, val, sustain) | | 183 | playtone(int pitch, int val, int sustain) |
186 | /* play tone of proper duration for current rhythm signature */ | | 184 | /* play tone of proper duration for current rhythm signature */ |
187 | int pitch, val, sustain; | | | |
188 | { | | 185 | { |
189 | int sound, silence, snum = 1, sdenom = 1; | | 186 | int sound, silence, snum = 1, sdenom = 1; |
190 | | | 187 | |
191 | /* this weirdness avoids floating-point arithmetic */ | | 188 | /* this weirdness avoids floating-point arithmetic */ |
192 | for (; sustain; sustain--) | | 189 | for (; sustain; sustain--) |
193 | { | | 190 | { |
194 | snum *= NUM_MULT; | | 191 | snum *= NUM_MULT; |
195 | sdenom *= DENOM_MULT; | | 192 | sdenom *= DENOM_MULT; |
196 | } | | 193 | } |
197 | | | 194 | |
198 | if (pitch == -1) | | 195 | if (pitch == -1) |
199 | rest(whole * snum / (val * sdenom)); | | 196 | rest(whole * snum / (val * sdenom)); |
200 | else | | 197 | else |
| @@ -205,30 +202,28 @@ playtone(pitch, val, sustain) | | | @@ -205,30 +202,28 @@ playtone(pitch, val, sustain) |
205 | | | 202 | |
206 | #ifdef SPKRDEBUG | | 203 | #ifdef SPKRDEBUG |
207 | printf("playtone: pitch %d for %d ticks, rest for %d ticks\n", | | 204 | printf("playtone: pitch %d for %d ticks, rest for %d ticks\n", |
208 | pitch, sound, silence); | | 205 | pitch, sound, silence); |
209 | #endif /* SPKRDEBUG */ | | 206 | #endif /* SPKRDEBUG */ |
210 | | | 207 | |
211 | tone(pitchtab[pitch], sound); | | 208 | tone(pitchtab[pitch], sound); |
212 | if (fill != LEGATO) | | 209 | if (fill != LEGATO) |
213 | rest(silence); | | 210 | rest(silence); |
214 | } | | 211 | } |
215 | } | | 212 | } |
216 | | | 213 | |
217 | static void | | 214 | static void |
218 | playstring(cp, slen) | | 215 | playstring(char *cp, int slen) |
219 | /* interpret and play an item from a notation string */ | | 216 | /* interpret and play an item from a notation string */ |
220 | char *cp; | | | |
221 | int slen; | | | |
222 | { | | 217 | { |
223 | int pitch, lastpitch = OCTAVE_NOTES * DFLT_OCTAVE; | | 218 | int pitch, lastpitch = OCTAVE_NOTES * DFLT_OCTAVE; |
224 | | | 219 | |
225 | #define GETNUM(cp, v) for(v=0; slen > 0 && isdigit(cp[1]); ) \ | | 220 | #define GETNUM(cp, v) for(v=0; slen > 0 && isdigit(cp[1]); ) \ |
226 | {v = v * 10 + (*++cp - '0'); slen--;} | | 221 | {v = v * 10 + (*++cp - '0'); slen--;} |
227 | for (; slen--; cp++) | | 222 | for (; slen--; cp++) |
228 | { | | 223 | { |
229 | int sustain, timeval, tempo; | | 224 | int sustain, timeval, tempo; |
230 | char c = toupper(*cp); | | 225 | char c = toupper(*cp); |
231 | | | 226 | |
232 | #ifdef SPKRDEBUG | | 227 | #ifdef SPKRDEBUG |
233 | printf("playstring: %c (%x)\n", c, c); | | 228 | printf("playstring: %c (%x)\n", c, c); |
234 | #endif /* SPKRDEBUG */ | | 229 | #endif /* SPKRDEBUG */ |
| @@ -404,30 +399,29 @@ static int spkr_attached = 0; | | | @@ -404,30 +399,29 @@ static int spkr_attached = 0; |
404 | | | 399 | |
405 | int | | 400 | int |
406 | spkrprobe(device_t parent, cfdata_t match, void *aux) | | 401 | spkrprobe(device_t parent, cfdata_t match, void *aux) |
407 | { | | 402 | { |
408 | return (!spkr_attached); | | 403 | return (!spkr_attached); |
409 | } | | 404 | } |
410 | | | 405 | |
411 | void | | 406 | void |
412 | spkrattach(device_t parent, device_t self, void *aux) | | 407 | spkrattach(device_t parent, device_t self, void *aux) |
413 | { | | 408 | { |
414 | printf("\n"); | | 409 | printf("\n"); |
415 | ppicookie = ((struct pcppi_attach_args *)aux)->pa_cookie; | | 410 | ppicookie = ((struct pcppi_attach_args *)aux)->pa_cookie; |
416 | spkr_attached = 1; | | 411 | spkr_attached = 1; |
417 | if (!device_pmf_is_registered(self)) | | 412 | if (!device_pmf_is_registered(self) |
418 | if (!pmf_device_register(self, NULL, NULL)) | | 413 | && !pmf_device_register(self, NULL, NULL)) |
419 | aprint_error_dev(self, | | 414 | aprint_error_dev(self, "couldn't establish power handler\n"); |
420 | "couldn't establish power handler\n"); | | | |
421 | | | 415 | |
422 | } | | 416 | } |
423 | | | 417 | |
424 | int | | 418 | int |
425 | spkropen(dev_t dev, int flags, int mode, struct lwp *l) | | 419 | spkropen(dev_t dev, int flags, int mode, struct lwp *l) |
426 | { | | 420 | { |
427 | #ifdef SPKRDEBUG | | 421 | #ifdef SPKRDEBUG |
428 | printf("spkropen: entering with dev = %"PRIx64"\n", dev); | | 422 | printf("spkropen: entering with dev = %"PRIx64"\n", dev); |
429 | #endif /* SPKRDEBUG */ | | 423 | #endif /* SPKRDEBUG */ |
430 | | | 424 | |
431 | if (minor(dev) != 0 || !spkr_attached) | | 425 | if (minor(dev) != 0 || !spkr_attached) |
432 | return(ENXIO); | | 426 | return(ENXIO); |
433 | else if (spkr_active) | | 427 | else if (spkr_active) |
| @@ -453,46 +447,46 @@ spkrwrite(dev_t dev, struct uio *uio, in | | | @@ -453,46 +447,46 @@ spkrwrite(dev_t dev, struct uio *uio, in |
453 | | | 447 | |
454 | if (minor(dev) != 0) | | 448 | if (minor(dev) != 0) |
455 | return(ENXIO); | | 449 | return(ENXIO); |
456 | else | | 450 | else |
457 | { | | 451 | { |
458 | n = min(DEV_BSIZE, uio->uio_resid); | | 452 | n = min(DEV_BSIZE, uio->uio_resid); |
459 | error = uiomove(spkr_inbuf, n, uio); | | 453 | error = uiomove(spkr_inbuf, n, uio); |
460 | if (!error) | | 454 | if (!error) |
461 | playstring((char *)spkr_inbuf, n); | | 455 | playstring((char *)spkr_inbuf, n); |
462 | return(error); | | 456 | return(error); |
463 | } | | 457 | } |
464 | } | | 458 | } |
465 | | | 459 | |
466 | int spkrclose(dev_t dev, int flags, int mode, | | 460 | int |
467 | struct lwp *l) | | 461 | spkrclose(dev_t dev, int flags, int mode, struct lwp *l) |
468 | { | | 462 | { |
469 | #ifdef SPKRDEBUG | | 463 | #ifdef SPKRDEBUG |
470 | printf("spkrclose: entering with dev = %"PRIx64"\n", dev); | | 464 | printf("spkrclose: entering with dev = %"PRIx64"\n", dev); |
471 | #endif /* SPKRDEBUG */ | | 465 | #endif /* SPKRDEBUG */ |
472 | | | 466 | |
473 | if (minor(dev) != 0) | | 467 | if (minor(dev) != 0) |
474 | return(ENXIO); | | 468 | return(ENXIO); |
475 | else | | 469 | else |
476 | { | | 470 | { |
477 | tone(0, 0); | | 471 | tone(0, 0); |
478 | free(spkr_inbuf, M_DEVBUF); | | 472 | free(spkr_inbuf, M_DEVBUF); |
479 | spkr_active = 0; | | 473 | spkr_active = 0; |
480 | } | | 474 | } |
481 | return(0); | | 475 | return(0); |
482 | } | | 476 | } |
483 | | | 477 | |
484 | int spkrioctl(dev_t dev, u_long cmd, void *data, int flag, | | 478 | int |
485 | struct lwp *l) | | 479 | spkrioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) |
486 | { | | 480 | { |
487 | #ifdef SPKRDEBUG | | 481 | #ifdef SPKRDEBUG |
488 | printf("spkrioctl: entering with dev = %"PRIx64", cmd = %lx\n", dev, cmd); | | 482 | printf("spkrioctl: entering with dev = %"PRIx64", cmd = %lx\n", dev, cmd); |
489 | #endif /* SPKRDEBUG */ | | 483 | #endif /* SPKRDEBUG */ |
490 | | | 484 | |
491 | if (minor(dev) != 0) | | 485 | if (minor(dev) != 0) |
492 | return(ENXIO); | | 486 | return(ENXIO); |
493 | else if (cmd == SPKRTONE) | | 487 | else if (cmd == SPKRTONE) |
494 | { | | 488 | { |
495 | tone_t *tp = (tone_t *)data; | | 489 | tone_t *tp = (tone_t *)data; |
496 | | | 490 | |
497 | if (tp->frequency == 0) | | 491 | if (tp->frequency == 0) |
498 | rest(tp->duration); | | 492 | rest(tp->duration); |