Module Name: src
Committed By: christos
Date: Tue Dec 13 20:20:34 UTC 2016
Modified Files:
src/sys/conf: files
src/sys/dev: files.audio spkr.c spkr_synth.c spkrvar.h
src/sys/dev/isa: spkr_pcppi.c
Log Message:
Restructure speaker devices so that there can be multiple of them, and have
proper softc's.
To generate a diff of this commit:
cvs rdiff -u -r1.1166 -r1.1167 src/sys/conf/files
cvs rdiff -u -r1.7 -r1.8 src/sys/dev/files.audio
cvs rdiff -u -r1.3 -r1.4 src/sys/dev/spkr.c src/sys/dev/spkrvar.h
cvs rdiff -u -r1.6 -r1.7 src/sys/dev/spkr_synth.c
cvs rdiff -u -r1.4 -r1.5 src/sys/dev/isa/spkr_pcppi.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/conf/files
diff -u src/sys/conf/files:1.1166 src/sys/conf/files:1.1167
--- src/sys/conf/files:1.1166 Tue Nov 1 20:11:59 2016
+++ src/sys/conf/files Tue Dec 13 15:20:34 2016
@@ -1,4 +1,4 @@
-# $NetBSD: files,v 1.1166 2016/11/02 00:11:59 pgoyette Exp $
+# $NetBSD: files,v 1.1167 2016/12/13 20:20:34 christos Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
version 20150846
@@ -331,6 +331,10 @@ define pckbport {[slot = -1]}
define pckbport_machdep_cnattach
define firmload
+# speaker devices, attaches to audio or pcppi drivers
+device spkr
+file dev/spkr.c spkr
+
include "dev/files.audio"
# High definition audio
Index: src/sys/dev/files.audio
diff -u src/sys/dev/files.audio:1.7 src/sys/dev/files.audio:1.8
--- src/sys/dev/files.audio:1.7 Sun Dec 11 01:30:11 2016
+++ src/sys/dev/files.audio Tue Dec 13 15:20:34 2016
@@ -1,4 +1,4 @@
-# $NetBSD: files.audio,v 1.7 2016/12/11 06:30:11 christos Exp $
+# $NetBSD: files.audio,v 1.8 2016/12/13 20:20:34 christos Exp $
define audiobus { }
define midibus { }
@@ -17,8 +17,7 @@ device audio {}: audiodev, auconv, aurat
attach audio at audiobus
device midi: audio
attach midi at midibus
-device spkr: audiobell
-attach spkr at audio with spkr_synth
+attach spkr at audio with spkr_synth
# console bell via audio device
#
@@ -26,12 +25,11 @@ define audiobell
file dev/auconv.c auconv
file dev/audio.c audio needs-flag
-file dev/audiobell.c audiobell needs-flag
+file dev/audiobell.c spkr_synth needs-flag
file dev/aurateconv.c aurateconv needs-flag
file dev/auvolconv.c auvolconv
file dev/midi.c midi needs-flag
file dev/midictl.c midisyn
file dev/midisyn.c midisyn
file dev/mulaw.c mulaw needs-flag
-file dev/spkr.c spkr needs-flag
file dev/spkr_synth.c spkr_synth needs-flag
Index: src/sys/dev/spkr.c
diff -u src/sys/dev/spkr.c:1.3 src/sys/dev/spkr.c:1.4
--- src/sys/dev/spkr.c:1.3 Fri Dec 9 00:17:03 2016
+++ src/sys/dev/spkr.c Tue Dec 13 15:20:34 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: spkr.c,v 1.3 2016/12/09 05:17:03 christos Exp $ */
+/* $NetBSD: spkr.c,v 1.4 2016/12/13 20:20:34 christos Exp $ */
/*
* Copyright (c) 1990 Eric S. Raymond ([email protected])
@@ -43,7 +43,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: spkr.c,v 1.3 2016/12/09 05:17:03 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: spkr.c,v 1.4 2016/12/13 20:20:34 christos Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -82,9 +82,9 @@ const struct cdevsw spkr_cdevsw = {
.d_flag = D_OTHER
};
-static void playinit(void);
-static void playtone(int, int, int);
-static void playstring(char *, int);
+static void playinit(struct spkr_softc *);
+static void playtone(struct spkr_softc *, int, int, int);
+static void playstring(struct spkr_softc *, const char *, size_t);
/**************** PLAY STRING INTERPRETER BEGINS HERE **********************
*
@@ -96,13 +96,6 @@ static void playstring(char *, int);
#define dtoi(c) ((c) - '0')
-static int octave; /* currently selected octave */
-static int whole; /* whole-note time at current tempo, in ticks */
-static int value; /* whole divisor for note time, quarter note = 1 */
-static int fill; /* controls spacing of notes */
-static bool octtrack; /* octave-tracking on? */
-static bool octprefix; /* override current octave-tracking state? */
-
/*
* Magic number avoidance...
*/
@@ -144,221 +137,211 @@ static const int pitchtab[] =
#define NOCTAVES (int)(__arraycount(pitchtab) / OCTAVE_NOTES)
static void
-playinit(void)
+playinit(struct spkr_softc *sc)
{
- octave = DFLT_OCTAVE;
- whole = (hz * SECS_PER_MIN * WHOLE_NOTE) / DFLT_TEMPO;
- fill = NORMAL;
- value = DFLT_VALUE;
- octtrack = false;
- octprefix = true; /* act as though there was an initial O(n) */
+ sc->sc_octave = DFLT_OCTAVE;
+ sc->sc_whole = (hz * SECS_PER_MIN * WHOLE_NOTE) / DFLT_TEMPO;
+ sc->sc_fill = NORMAL;
+ sc->sc_value = DFLT_VALUE;
+ sc->sc_octtrack = false;
+ sc->sc_octprefix = true;/* act as though there was an initial O(n) */
}
-static void
-playtone(int pitch, int val, int sustain)
/* play tone of proper duration for current rhythm signature */
+static void
+playtone(struct spkr_softc *sc, int pitch, int val, int sustain)
{
- int sound, silence, snum = 1, sdenom = 1;
+ int sound, silence, snum = 1, sdenom = 1;
- /* this weirdness avoids floating-point arithmetic */
- for (; sustain; sustain--)
- {
- snum *= NUM_MULT;
- sdenom *= DENOM_MULT;
- }
+ /* this weirdness avoids floating-point arithmetic */
+ for (; sustain; sustain--) {
+ snum *= NUM_MULT;
+ sdenom *= DENOM_MULT;
+ }
- if (pitch == -1)
- spkr_rest(whole * snum / (val * sdenom));
- else
- {
- sound = (whole * snum) / (val * sdenom)
- - (whole * (FILLTIME - fill)) / (val * FILLTIME);
- silence = whole * (FILLTIME-fill) * snum / (FILLTIME * val * sdenom);
+ if (pitch == -1) {
+ (*sc->sc_rest)(sc->sc_dev, sc->sc_whole
+ * snum / (val * sdenom));
+ return;
+ }
+
+ int fac = sc->sc_whole * (FILLTIME - sc->sc_fill);
+ int fval = FILLTIME * val;
+ sound = (sc->sc_whole * snum) / (val * sdenom) - fac / fval;
+ silence = fac * snum / (fval * sdenom);
#ifdef SPKRDEBUG
- printf("playtone: pitch %d for %d ticks, rest for %d ticks\n",
+ aprint_debug_dev(sc->sc_dev,
+ "%s: pitch %d for %d ticks, rest for %d ticks\n", __func__,
pitch, sound, silence);
#endif /* SPKRDEBUG */
- spkr_tone(pitchtab[pitch], sound);
- if (fill != LEGATO)
- spkr_rest(silence);
- }
+ (*sc->sc_tone)(sc->sc_dev, pitchtab[pitch], sound);
+ if (sc->sc_fill != LEGATO)
+ (*sc->sc_rest)(sc->sc_dev, silence);
}
-static void
-playstring(char *cp, int slen)
/* interpret and play an item from a notation string */
+static void
+playstring(struct spkr_softc *sc, const char *cp, size_t slen)
{
- int pitch, lastpitch = OCTAVE_NOTES * DFLT_OCTAVE;
+ int pitch, lastpitch = OCTAVE_NOTES * DFLT_OCTAVE;
+
+#define GETNUM(cp, v) \
+ for (v = 0; slen > 0 && isdigit((unsigned char)cp[1]); ) { \
+ v = v * 10 + (*++cp - '0'); \
+ slen--; \
+ }
-#define GETNUM(cp, v) for(v=0; slen > 0 && isdigit(cp[1]); ) \
- {v = v * 10 + (*++cp - '0'); slen--;}
- for (; slen--; cp++)
- {
- int sustain, timeval, tempo;
- char c = toupper(*cp);
+ for (; slen--; cp++) {
+ int sustain, timeval, tempo;
+ char c = toupper((unsigned char)*cp);
#ifdef SPKRDEBUG
- printf("playstring: %c (%x)\n", c, c);
+ aprint_debug_dev(sc->sc_dev, "%s: %c (%x)\n", __func__, c, c);
#endif /* SPKRDEBUG */
- switch (c)
- {
- case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G':
-
- /* compute pitch */
- pitch = notetab[c - 'A'] + octave * OCTAVE_NOTES;
-
- /* this may be followed by an accidental sign */
- if (slen > 0 && (cp[1] == '#' || cp[1] == '+'))
- {
- ++pitch;
- ++cp;
- slen--;
- }
- else if (slen > 0 && cp[1] == '-')
- {
- --pitch;
- ++cp;
- slen--;
- }
-
- /*
- * If octave-tracking mode is on, and there has been no octave-
- * setting prefix, find the version of the current letter note
- * closest to the last regardless of octave.
- */
- if (octtrack && !octprefix)
- {
- if (abs(pitch-lastpitch) > abs(pitch+OCTAVE_NOTES-lastpitch))
- {
- if (octave < NOCTAVES - 1) {
- ++octave;
- pitch += OCTAVE_NOTES;
- }
- }
+ switch (c) {
+ case 'A': case 'B': case 'C': case 'D':
+ case 'E': case 'F': case 'G':
+ /* compute pitch */
+ pitch = notetab[c - 'A'] + sc->sc_octave * OCTAVE_NOTES;
+
+ /* this may be followed by an accidental sign */
+ if (slen > 0 && (cp[1] == '#' || cp[1] == '+')) {
+ ++pitch;
+ ++cp;
+ slen--;
+ } else if (slen > 0 && cp[1] == '-') {
+ --pitch;
+ ++cp;
+ slen--;
+ }
+
+ /*
+ * If octave-tracking mode is on, and there has been no
+ * octave- setting prefix, find the version of the
+ * current letter note * closest to the last
+ * regardless of octave.
+ */
+ if (sc->sc_octtrack && !sc->sc_octprefix) {
+ int d = abs(pitch - lastpitch);
+ if (d > abs(pitch + OCTAVE_NOTES - lastpitch)) {
+ if (sc->sc_octave < NOCTAVES - 1) {
+ ++sc->sc_octave;
+ pitch += OCTAVE_NOTES;
+ }
+ }
+
+ if (d > abs(pitch - OCTAVE_NOTES - lastpitch)) {
+ if (sc->sc_octave > 0) {
+ --sc->sc_octave;
+ pitch -= OCTAVE_NOTES;
+ }
+ }
+ }
+ sc->sc_octprefix = false;
+ lastpitch = pitch;
+
+ /*
+ * ...which may in turn be followed by an override
+ * time value
+ */
+ GETNUM(cp, timeval);
+ if (timeval <= 0 || timeval > MIN_VALUE)
+ timeval = sc->sc_value;
+
+ /* ...and/or sustain dots */
+ for (sustain = 0; slen > 0 && cp[1] == '.'; cp++) {
+ slen--;
+ sustain++;
+ }
+
+ /* time to emit the actual tone */
+ playtone(sc, pitch, timeval, sustain);
+ break;
+
+ case 'O':
+ if (slen > 0 && (cp[1] == 'N' || cp[1] == 'n')) {
+ sc->sc_octprefix = sc->sc_octtrack = false;
+ ++cp;
+ slen--;
+ } else if (slen > 0 && (cp[1] == 'L' || cp[1] == 'l')) {
+ sc->sc_octtrack = true;
+ ++cp;
+ slen--;
+ } else {
+ GETNUM(cp, sc->sc_octave);
+ if (sc->sc_octave >= NOCTAVES)
+ sc->sc_octave = DFLT_OCTAVE;
+ sc->sc_octprefix = true;
+ }
+ break;
+
+ case '>':
+ if (sc->sc_octave < NOCTAVES - 1)
+ sc->sc_octave++;
+ sc->sc_octprefix = true;
+ break;
+
+ case '<':
+ if (sc->sc_octave > 0)
+ sc->sc_octave--;
+ sc->sc_octprefix = true;
+ break;
+
+ case 'N':
+ GETNUM(cp, pitch);
+ for (sustain = 0; slen > 0 && cp[1] == '.'; cp++) {
+ slen--;
+ sustain++;
+ }
+ playtone(sc, pitch - 1, sc->sc_value, sustain);
+ break;
+
+ case 'L':
+ GETNUM(cp, sc->sc_value);
+ if (sc->sc_value <= 0 || sc->sc_value > MIN_VALUE)
+ sc->sc_value = DFLT_VALUE;
+ break;
+
+ case 'P':
+ case '~':
+ /* this may be followed by an override time value */
+ GETNUM(cp, timeval);
+ if (timeval <= 0 || timeval > MIN_VALUE)
+ timeval = sc->sc_value;
+ for (sustain = 0; slen > 0 && cp[1] == '.'; cp++) {
+ slen--;
+ sustain++;
+ }
+ playtone(sc, -1, timeval, sustain);
+ break;
- if (abs(pitch-lastpitch) > abs((pitch-OCTAVE_NOTES)-lastpitch))
- {
- if (octave > 0) {
- --octave;
- pitch -= OCTAVE_NOTES;
- }
+ case 'T':
+ GETNUM(cp, tempo);
+ if (tempo < MIN_TEMPO || tempo > MAX_TEMPO)
+ tempo = DFLT_TEMPO;
+ sc->sc_whole = (hz * SECS_PER_MIN * WHOLE_NOTE) / tempo;
+ break;
+
+ case 'M':
+ if (slen > 0 && (cp[1] == 'N' || cp[1] == 'n')) {
+ sc->sc_fill = NORMAL;
+ ++cp;
+ slen--;
+ } else if (slen > 0 && (cp[1] == 'L' || cp[1] == 'l')) {
+ sc->sc_fill = LEGATO;
+ ++cp;
+ slen--;
+ } else if (slen > 0 && (cp[1] == 'S' || cp[1] == 's')) {
+ sc->sc_fill = STACCATO;
+ ++cp;
+ slen--;
+ }
+ break;
}
- }
- octprefix = false;
- lastpitch = pitch;
-
- /* ...which may in turn be followed by an override time value */
- GETNUM(cp, timeval);
- if (timeval <= 0 || timeval > MIN_VALUE)
- timeval = value;
-
- /* ...and/or sustain dots */
- for (sustain = 0; slen > 0 && cp[1] == '.'; cp++)
- {
- slen--;
- sustain++;
- }
-
- /* time to emit the actual tone */
- playtone(pitch, timeval, sustain);
- break;
-
- case 'O':
- if (slen > 0 && (cp[1] == 'N' || cp[1] == 'n'))
- {
- octprefix = octtrack = false;
- ++cp;
- slen--;
- }
- else if (slen > 0 && (cp[1] == 'L' || cp[1] == 'l'))
- {
- octtrack = true;
- ++cp;
- slen--;
- }
- else
- {
- GETNUM(cp, octave);
- if (octave >= NOCTAVES)
- octave = DFLT_OCTAVE;
- octprefix = true;
- }
- break;
-
- case '>':
- if (octave < NOCTAVES - 1)
- octave++;
- octprefix = true;
- break;
-
- case '<':
- if (octave > 0)
- octave--;
- octprefix = true;
- break;
-
- case 'N':
- GETNUM(cp, pitch);
- for (sustain = 0; slen > 0 && cp[1] == '.'; cp++)
- {
- slen--;
- sustain++;
- }
- playtone(pitch - 1, value, sustain);
- break;
-
- case 'L':
- GETNUM(cp, value);
- if (value <= 0 || value > MIN_VALUE)
- value = DFLT_VALUE;
- break;
-
- case 'P':
- case '~':
- /* this may be followed by an override time value */
- GETNUM(cp, timeval);
- if (timeval <= 0 || timeval > MIN_VALUE)
- timeval = value;
- for (sustain = 0; slen > 0 && cp[1] == '.'; cp++)
- {
- slen--;
- sustain++;
- }
- playtone(-1, timeval, sustain);
- break;
-
- case 'T':
- GETNUM(cp, tempo);
- if (tempo < MIN_TEMPO || tempo > MAX_TEMPO)
- tempo = DFLT_TEMPO;
- whole = (hz * SECS_PER_MIN * WHOLE_NOTE) / tempo;
- break;
-
- case 'M':
- if (slen > 0 && (cp[1] == 'N' || cp[1] == 'n'))
- {
- fill = NORMAL;
- ++cp;
- slen--;
- }
- else if (slen > 0 && (cp[1] == 'L' || cp[1] == 'l'))
- {
- fill = LEGATO;
- ++cp;
- slen--;
- }
- else if (slen > 0 && (cp[1] == 'S' || cp[1] == 's'))
- {
- fill = STACCATO;
- ++cp;
- slen--;
- }
- break;
}
- }
}
/******************* UNIX DRIVER HOOKS BEGIN HERE **************************
@@ -366,116 +349,125 @@ playstring(char *cp, int slen)
* This section implements driver hooks to run playstring() and the spkr_tone()
* and spkr_rest() functions defined above.
*/
+extern struct cfdriver spkr_cd;
+#define spkrenter(d) device_lookup_private(&spkr_cd, d)
-static int spkr_active; /* exclusion flag */
-int spkr_attached;
-static void *spkr_inbuf;
-
-int
-spkr_probe(device_t parent, cfdata_t match, void *aux)
+void
+spkr_attach(device_t self, void (*tone)(device_t, u_int, u_int),
+ void (*rest)(device_t, int))
{
- return (!spkr_attached);
+ struct spkr_softc *sc = device_private(self);
+
+ sc->sc_dev = self;
+ sc->sc_tone = tone;
+ sc->sc_rest = rest;
+ sc->sc_inbuf = NULL;
}
int
spkropen(dev_t dev, int flags, int mode, struct lwp *l)
{
#ifdef SPKRDEBUG
- printf("spkropen: entering with dev = %"PRIx64"\n", dev);
+ aprint_debug("%s: entering with dev = %"PRIx64"\n", __func__, dev);
#endif /* SPKRDEBUG */
+ struct spkr_softc *sc = spkrenter(minor(dev));
- if (minor(dev) != 0 || !spkr_attached)
- return(ENXIO);
- else if (spkr_active)
- return(EBUSY);
- else
- {
- playinit();
- spkr_inbuf = malloc(DEV_BSIZE, M_DEVBUF, M_WAITOK);
- spkr_active = 1;
- }
- return(0);
+ if (sc == NULL)
+ return ENXIO;
+ if (sc->sc_inbuf)
+ return EBUSY;
+
+ sc->sc_inbuf = malloc(DEV_BSIZE, M_DEVBUF, M_WAITOK);
+ playinit(sc);
+ return 0;
}
int
spkrwrite(dev_t dev, struct uio *uio, int flags)
{
- int n;
- int error;
#ifdef SPKRDEBUG
- printf("spkrwrite: entering with dev = %"PRIx64", count = %zu\n",
- dev, uio->uio_resid);
+ aprint_debug("%s: entering with dev = %"PRIx64", count = %zu\n",
+ __func__, dev, uio->uio_resid);
#endif /* SPKRDEBUG */
+ struct spkr_softc *sc = spkrenter(minor(dev));
- if (minor(dev) != 0)
- return(ENXIO);
- else
- {
- n = min(DEV_BSIZE, uio->uio_resid);
- error = uiomove(spkr_inbuf, n, uio);
- if (!error)
- playstring((char *)spkr_inbuf, n);
- return(error);
- }
+ if (sc == NULL)
+ return ENXIO;
+ if (!sc->sc_inbuf)
+ return EINVAL;
+
+ size_t n = min(DEV_BSIZE, uio->uio_resid);
+ int error = uiomove(sc->sc_inbuf, n, uio);
+ if (error)
+ return error;
+ playstring(sc, sc->sc_inbuf, n);
+ return 0;
}
int
spkrclose(dev_t dev, int flags, int mode, struct lwp *l)
{
#ifdef SPKRDEBUG
- printf("spkrclose: entering with dev = %"PRIx64"\n", dev);
+ aprint_debug("%s: entering with dev = %"PRIx64"\n", __func__, dev);
#endif /* SPKRDEBUG */
+ struct spkr_softc *sc = spkrenter(minor(dev));
+
+ if (sc == NULL)
+ return ENXIO;
+ if (!sc->sc_inbuf)
+ return EINVAL;
+
+ sc->sc_tone(sc->sc_dev, 0, 0);
+ free(sc->sc_inbuf, M_DEVBUF);
+ sc->sc_inbuf = NULL;
- if (minor(dev) != 0)
- return(ENXIO);
+ return 0;
+}
+
+static void
+playonetone(struct spkr_softc *sc, tone_t *tp)
+{
+ if (tp->frequency == 0)
+ (*sc->sc_rest)(sc->sc_dev, tp->duration);
else
- {
- spkr_tone(0, 0);
- free(spkr_inbuf, M_DEVBUF);
- spkr_active = 0;
- }
- return(0);
+ (*sc->sc_tone)(sc->sc_dev, tp->frequency, tp->duration);
}
int
spkrioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
{
+ tone_t *tp;
+ tone_t ttp;
+ int error;
#ifdef SPKRDEBUG
- printf("spkrioctl: entering with dev = %"PRIx64", cmd = %lx\n", dev, cmd);
+ aprint_debug("%s: entering with dev = %"PRIx64", cmd = %lx\n",
+ __func__, dev, cmd);
#endif /* SPKRDEBUG */
- if (minor(dev) != 0)
- return(ENXIO);
- else if (cmd == SPKRTONE)
- {
- tone_t *tp = (tone_t *)data;
-
- if (tp->frequency == 0)
- spkr_rest(tp->duration);
- else
- spkr_tone(tp->frequency, tp->duration);
- }
- else if (cmd == SPKRTUNE)
- {
- tone_t *tp = (tone_t *)(*(void **)data);
- tone_t ttp;
- int error;
+ struct spkr_softc *sc = spkrenter(minor(dev));
- for (; ; tp++) {
- error = copyin(tp, &ttp, sizeof(tone_t));
- if (error)
- return(error);
- if (ttp.duration == 0)
- break;
- if (ttp.frequency == 0)
- spkr_rest(ttp.duration);
- else
- spkr_tone(ttp.frequency, ttp.duration);
+ if (sc == NULL)
+ return ENXIO;
+ if (!sc->sc_inbuf)
+ return EINVAL;
+
+ switch (cmd) {
+ case SPKRTONE:
+ playonetone(sc, data);
+ return 0;
+ case SPKRTUNE:
+ for (tp = *(void **)data;; tp++) {
+ error = copyin(tp, &ttp, sizeof(tone_t));
+ if (error)
+ return(error);
+ if (ttp.duration == 0)
+ break;
+ playonetone(sc, &ttp);
+ }
+ return 0;
+ default:
+ return ENOTTY;
}
- }
- else
- return(EINVAL);
- return(0);
}
#ifdef _MODULE
@@ -506,12 +498,13 @@ spkr__modcmd(modcmd_t cmd, void *arg)
break;
case MODULE_CMD_FINI:
- if (spkr_active)
- return EBUSY;
+ return EBUSY;
+#ifdef notyet
error = config_fini_component(cfdriver_ioconf_spkr,
cfattach_ioconf_spkr, cfdata_ioconf_spkr);
devsw_detach(NULL, &spkr_cdevsw);
break;
+#endif
default:
error = ENOTTY;
break;
Index: src/sys/dev/spkrvar.h
diff -u src/sys/dev/spkrvar.h:1.3 src/sys/dev/spkrvar.h:1.4
--- src/sys/dev/spkrvar.h:1.3 Fri Dec 9 00:45:20 2016
+++ src/sys/dev/spkrvar.h Tue Dec 13 15:20:34 2016
@@ -1,18 +1,27 @@
-/* $NetBSD: spkrvar.h,v 1.3 2016/12/09 05:45:20 christos Exp $ */
+/* $NetBSD: spkrvar.h,v 1.4 2016/12/13 20:20:34 christos Exp $ */
#ifndef _SYS_DEV_SPKRVAR_H
#define _SYS_DEV_SPKRVAR_H
#include <sys/module.h>
-device_t speakerattach_mi(device_t);
-void speaker_play(u_int, u_int, u_int);
+struct spkr_softc {
+ device_t sc_dev;
+ int sc_octave; /* currently selected octave */
+ int sc_whole; /* whole-note time at current tempo, in ticks */
+ int sc_value; /* whole divisor for note time, quarter note = 1 */
+ int sc_fill; /* controls spacing of notes */
+ bool sc_octtrack; /* octave-tracking on? */
+ bool sc_octprefix; /* override current octave-tracking state? */
+ char *sc_inbuf;
+
+ /* attachment-specific hooks */
+ void (*sc_tone)(device_t, u_int, u_int);
+ void (*sc_rest)(device_t, int);
+};
-// XXX:
-void spkr_tone(u_int, u_int);
-void spkr_rest(int);
int spkr__modcmd(modcmd_t, void *);
-int spkr_probe(device_t, cfdata_t, void *);
-extern int spkr_attached;
+void spkr_attach(device_t,
+ void (*)(device_t, u_int, u_int), void (*)(device_t, int));
#endif /* _SYS_DEV_SPKRVAR_H */
Index: src/sys/dev/spkr_synth.c
diff -u src/sys/dev/spkr_synth.c:1.6 src/sys/dev/spkr_synth.c:1.7
--- src/sys/dev/spkr_synth.c:1.6 Mon Dec 12 05:46:39 2016
+++ src/sys/dev/spkr_synth.c Tue Dec 13 15:20:34 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: spkr_synth.c,v 1.6 2016/12/12 10:46:39 joerg Exp $ */
+/* $NetBSD: spkr_synth.c,v 1.7 2016/12/13 20:20:34 christos Exp $ */
/*-
* Copyright (c) 2016 Nathanial Sloss <[email protected]>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: spkr_synth.c,v 1.6 2016/12/12 10:46:39 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: spkr_synth.c,v 1.7 2016/12/13 20:20:34 christos Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -48,7 +48,6 @@ __KERNEL_RCSID(0, "$NetBSD: spkr_synth.c
#include <dev/audiovar.h>
struct vbell_args {
- device_t *cookie;
u_int pitch;
u_int period;
u_int volume;
@@ -56,18 +55,27 @@ struct vbell_args {
};
static void bell_thread(void *) __dead;
-static int beep_sysctl_device(SYSCTLFN_PROTO);
#include <dev/audiobellvar.h>
#include <dev/spkrvar.h>
#include <dev/spkrio.h>
-static void spkrattach(device_t, device_t, void *);
-static int spkrdetach(device_t, int);
-device_t speakerattach_mi(device_t);
+static int spkr_synth_probe(device_t, cfdata_t, void *);
+static void spkr_synth_attach(device_t, device_t, void *);
+static int spkr_synth_detach(device_t, int);
+
+struct spkr_synth_softc {
+ struct spkr_softc sc_spkr;
+ lwp_t *sc_bellthread;
+ kmutex_t sc_bellock;
+ kcondvar_t sc_bellcv;
+ device_t sc_audiodev;
+ struct vbell_args sc_bell_args;
+};
-#include "ioconf.h"
+CFATTACH_DECL_NEW(spkr_synth, sizeof(struct spkr_synth_softc),
+ spkr_synth_probe, spkr_synth_attach, spkr_synth_detach, NULL);
MODULE(MODULE_CLASS_DRIVER, spkr, NULL /* "audio" */);
@@ -77,173 +85,116 @@ spkr_modcmd(modcmd_t cmd, void *arg)
return spkr__modcmd(cmd, arg);
}
-CFATTACH_DECL3_NEW(spkr_synth, 0,
- spkr_probe, spkrattach, spkrdetach, NULL, NULL, NULL, DVF_DETACH_SHUTDOWN);
-
-extern struct cfdriver audio_cd;
-
-static struct sysctllog *spkr_sc_log; /* sysctl log */
-static int beep_unit = 0;
-
-struct vbell_args sc_bell_args;
-lwp_t *sc_bellthread;
-kmutex_t sc_bellock;
-kcondvar_t sc_bellcv;
-
-struct spkr_attach_args {
- device_t dev;
-};
-
-void
-spkr_tone(u_int xhz, u_int ticks)
+static void
+spkr_synth_tone(device_t self, u_int xhz, u_int ticks)
{
- audiobell(&beep_unit, xhz, ticks * (1000 / hz), 80, 0);
+ struct spkr_synth_softc *sc = device_private(self);
+
+#ifdef SPKRDEBUG
+ aprint_debug_dev(self, "%s: %u %d\n", __func__, xhz, ticks);
+#endif /* SPKRDEBUG */
+ audiobell(sc->sc_audiodev, xhz, ticks * (1000 / hz), 80, 0);
}
-void
-spkr_rest(int ticks)
+static void
+spkr_synth_rest(device_t self, int ticks)
{
+ struct spkr_synth_softc *sc = device_private(self);
+
#ifdef SPKRDEBUG
- printf("%s: %d\n", __func__, ticks);
+ aprint_debug_dev(self, "%s: %d\n", __func__, ticks);
#endif /* SPKRDEBUG */
- if (ticks > 0)
- audiobell(&beep_unit, 0, ticks * (1000 / hz), 80, 0);
+ if (ticks > 0)
+ audiobell(sc->sc_audiodev, 0, ticks * (1000 / hz), 80, 0);
+}
+
+#ifdef notyet
+static void
+spkr_synth_play(device_t self, u_int pitch, u_int period, u_int volume)
+{
+ struct spkr_synth_softc *sc = device_private(self);
+
+ mutex_enter(&sc->sc_bellock);
+ sc->sc_bell_args.dying = false;
+ sc->sc_bell_args.pitch = pitch;
+ sc->sc_bell_args.period = period;
+ sc->sc_bell_args.volume = volume;
+
+ cv_broadcast(&sc->sc_bellcv);
+ mutex_exit(&sc->sc_bellock);
}
+#endif
-device_t
-speakerattach_mi(device_t dev)
+static int
+spkr_synth_probe(device_t parent, cfdata_t cf, void *aux)
{
- struct spkr_attach_args sa;
- sa.dev = dev;
- return config_found(dev, &sa, NULL);
+
+ return 1;
}
static void
-spkrattach(device_t parent, device_t self, void *aux)
+spkr_synth_attach(device_t parent, device_t self, void *aux)
{
- const struct sysctlnode *node;
+ struct spkr_synth_softc *sc = device_private(self);
+
+ aprint_normal("\n");
- printf("\n");
- beep_unit = 0;
- spkr_attached = 1;
+ sc->sc_audiodev = parent;
if (!pmf_device_register(self, NULL, NULL))
aprint_error_dev(self, "couldn't establish power handler\n");
- mutex_init(&sc_bellock, MUTEX_DEFAULT, IPL_SCHED);
- cv_init(&sc_bellcv, "bellcv");
-
- /* sysctl set-up for default audio device */
- sysctl_createv(&spkr_sc_log, 0, NULL, &node,
- 0,
- CTLTYPE_NODE, "beep",
- SYSCTL_DESCR("synthesized beeper information"),
- NULL, 0,
- NULL, 0,
- CTL_HW,
- CTL_CREATE, CTL_EOL);
-
- if (node != NULL) {
- sysctl_createv(&spkr_sc_log, 0, NULL, NULL,
- CTLFLAG_READWRITE,
- CTLTYPE_INT, "device",
- SYSCTL_DESCR("default device"),
- beep_sysctl_device, 0,
- NULL, 0,
- CTL_HW, node->sysctl_num,
- CTL_CREATE, CTL_EOL);
- }
+ mutex_init(&sc->sc_bellock, MUTEX_DEFAULT, IPL_SCHED);
+ cv_init(&sc->sc_bellcv, "bellcv");
kthread_create(PRI_BIO, KTHREAD_MPSAFE | KTHREAD_MUSTJOIN, NULL,
- bell_thread, &sc_bell_args, &sc_bellthread, "vbell");
+ bell_thread, sc, &sc->sc_bellthread, device_xname(self));
+
+ spkr_attach(self, spkr_synth_tone, spkr_synth_rest);
}
static int
-spkrdetach(device_t self, int flags)
+spkr_synth_detach(device_t self, int flags)
{
+ struct spkr_synth_softc *sc = device_private(self);
pmf_device_deregister(self);
- mutex_enter(&sc_bellock);
- sc_bell_args.dying = true;
+ mutex_enter(&sc->sc_bellock);
+ sc->sc_bell_args.dying = true;
- cv_broadcast(&sc_bellcv);
- mutex_exit(&sc_bellock);
+ cv_broadcast(&sc->sc_bellcv);
+ mutex_exit(&sc->sc_bellock);
- kthread_join(sc_bellthread);
- cv_destroy(&sc_bellcv);
- mutex_destroy(&sc_bellock);
+ kthread_join(sc->sc_bellthread);
+ cv_destroy(&sc->sc_bellcv);
+ mutex_destroy(&sc->sc_bellock);
- /* delete sysctl nodes */
- sysctl_teardown(&spkr_sc_log);
-
- spkr_attached = 0;
return 0;
}
-void
+static void
bell_thread(void *arg)
{
- struct vbell_args *vb = arg;
+ struct spkr_synth_softc *sc = arg;
+ struct vbell_args *vb = &sc->sc_bell_args;
u_int bpitch;
u_int bperiod;
u_int bvolume;
for (;;) {
- mutex_enter(&sc_bellock);
- cv_wait_sig(&sc_bellcv, &sc_bellock);
+ mutex_enter(&sc->sc_bellock);
+ cv_wait_sig(&sc->sc_bellcv, &sc->sc_bellock);
if (vb->dying == true) {
- mutex_exit(&sc_bellock);
+ mutex_exit(&sc->sc_bellock);
kthread_exit(0);
}
bpitch = vb->pitch;
bperiod = vb->period;
bvolume = vb->volume;
- mutex_exit(&sc_bellock);
- audiobell(&beep_unit, bpitch, bperiod, bvolume, 0);
+ mutex_exit(&sc->sc_bellock);
+ audiobell(sc->sc_audiodev, bpitch, bperiod, bvolume, 0);
}
}
-
-void
-speaker_play(u_int pitch, u_int period, u_int volume)
-{
- if (spkr_attached == 0 || beep_unit == -1)
- return;
-
- mutex_enter(&sc_bellock);
- sc_bell_args.dying = false;
- sc_bell_args.pitch = pitch;
- sc_bell_args.period = period;
- sc_bell_args.volume = volume;
-
- cv_broadcast(&sc_bellcv);
- mutex_exit(&sc_bellock);
-}
-
-/* sysctl helper to set common audio channels */
-static int
-beep_sysctl_device(SYSCTLFN_ARGS)
-{
- struct sysctlnode node;
- struct audio_softc *ac;
- int t, error;
-
- node = *rnode;
-
- t = beep_unit;
- node.sysctl_data = &t;
- error = sysctl_lookup(SYSCTLFN_CALL(&node));
- if (error || newp == NULL)
- return error;
-
-
- if (t < -1 || (t != -1 && (ac = device_lookup_private(&audio_cd, t)) ==
- NULL))
- return EINVAL;
-
- beep_unit = t;
-
- return error;
-}
Index: src/sys/dev/isa/spkr_pcppi.c
diff -u src/sys/dev/isa/spkr_pcppi.c:1.4 src/sys/dev/isa/spkr_pcppi.c:1.5
--- src/sys/dev/isa/spkr_pcppi.c:1.4 Fri Dec 9 00:17:03 2016
+++ src/sys/dev/isa/spkr_pcppi.c Tue Dec 13 15:20:34 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: spkr_pcppi.c,v 1.4 2016/12/09 05:17:03 christos Exp $ */
+/* $NetBSD: spkr_pcppi.c,v 1.5 2016/12/13 20:20:34 christos Exp $ */
/*
* Copyright (c) 1990 Eric S. Raymond ([email protected])
@@ -43,7 +43,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: spkr_pcppi.c,v 1.4 2016/12/09 05:17:03 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: spkr_pcppi.c,v 1.5 2016/12/13 20:20:34 christos Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -64,11 +64,18 @@ __KERNEL_RCSID(0, "$NetBSD: spkr_pcppi.c
#include <dev/spkrvar.h>
#include <dev/spkrio.h>
-extern int spkr_attached;
-static void spkrattach(device_t, device_t, void *);
-static int spkrdetach(device_t, int);
+struct spkr_pcppi_softc {
+ device_t sc_dev;
+ device_t sc_spkr_dev;
+ pcppi_tag_t sc_pcppicookie;
+};
+
+static int spkr_pcppi_probe(device_t, cfdata_t, void *);
+static void spkr_pcppi_attach(device_t, device_t, void *);
+static int spkr_pcppi_detach(device_t, int);
-#include "ioconf.h"
+CFATTACH_DECL_NEW(spkr_pcppi, sizeof(struct spkr_pcppi_softc),
+ spkr_pcppi_probe, spkr_pcppi_attach, spkr_pcppi_detach, NULL);
MODULE(MODULE_CLASS_DRIVER, spkr, NULL /* "pcppi" */);
@@ -78,53 +85,62 @@ spkr_modcmd(modcmd_t cmd, void *arg)
return spkr__modcmd(cmd, arg);
}
-CFATTACH_DECL_NEW(spkr_pcppi, 0, spkr_probe, spkrattach, spkrdetach, NULL);
-
-static pcppi_tag_t ppicookie;
-
#define SPKRPRI (PZERO - 1)
-void
-spkr_tone(u_int xhz, u_int ticks)
/* emit tone of frequency hz for given number of ticks */
+static void
+spkr_pcppi_tone(device_t self, u_int xhz, u_int ticks)
{
- pcppi_bell(ppicookie, xhz, ticks, PCPPI_BELL_SLEEP);
+#ifdef SPKRDEBUG
+ aprint_debug_dev(self, "%s: %u %u\n", __func__, xhz, ticks);
+#endif /* SPKRDEBUG */
+ struct spkr_pcppi_softc *sc = device_private(self);
+ pcppi_bell(sc->sc_pcppicookie, xhz, ticks, PCPPI_BELL_SLEEP);
}
-void
-spkr_rest(int ticks)
/* rest for given number of ticks */
+static void
+spkr_pcppi_rest(device_t self, int ticks)
{
- /*
- * Set timeout to endrest function, then give up the timeslice.
- * This is so other processes can execute while the rest is being
- * waited out.
- */
+ /*
+ * Set timeout to endrest function, then give up the timeslice.
+ * This is so other processes can execute while the rest is being
+ * waited out.
+ */
#ifdef SPKRDEBUG
- printf("%s: %d\n", __func__, ticks);
+ aprint_debug_dev(self, "%s: %d\n", __func__, ticks);
#endif /* SPKRDEBUG */
- if (ticks > 0)
- tsleep(spkr_rest, SPKRPRI | PCATCH, "rest", ticks);
+ if (ticks > 0)
+ tsleep(self, SPKRPRI | PCATCH, device_xname(self), ticks);
+}
+
+static int
+spkr_pcppi_probe(device_t parent, cfdata_t cf, void *aux)
+{
+ return 1;
}
static void
-spkrattach(device_t parent, device_t self, void *aux)
+spkr_pcppi_attach(device_t parent, device_t self, void *aux)
{
+ struct pcppi_attach_args *pa = aux;
+ struct spkr_pcppi_softc *sc = device_private(self);
+
aprint_naive("\n");
aprint_normal("\n");
- ppicookie = ((struct pcppi_attach_args *)aux)->pa_cookie;
- spkr_attached = 1;
+
+ sc->sc_pcppicookie = pa->pa_cookie;
+ spkr_attach(self, spkr_pcppi_tone, spkr_pcppi_rest);
if (!pmf_device_register(self, NULL, NULL))
aprint_error_dev(self, "couldn't establish power handler\n");
}
static int
-spkrdetach(device_t self, int flags)
+spkr_pcppi_detach(device_t self, int flags)
{
+ struct spkr_pcppi_softc *sc = device_private(self);
+ sc->sc_pcppicookie = NULL;
pmf_device_deregister(self);
- spkr_attached = 0;
- ppicookie = NULL;
-
return 0;
}