1 /* $NetBSD: midi_pcppi.c,v 1.22 2009/04/08 00:12:27 dyoung Exp $ */
4 * Copyright (c) 1998 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Lennart Augustsson (augustss@NetBSD.org).
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: midi_pcppi.c,v 1.22 2009/04/08 00:12:27 dyoung Exp $");
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/kernel.h>
38 #include <sys/errno.h>
39 #include <sys/device.h>
40 #include <sys/malloc.h>
43 #include <sys/select.h>
44 #include <sys/audioio.h>
45 #include <sys/midiio.h>
49 #include <dev/isa/pcppivar.h>
51 #include <dev/audio_if.h>
52 #include <dev/midi_if.h>
53 #include <dev/midivar.h>
54 #include <dev/midisynvar.h>
56 #define MAX_DURATION 30 /* turn off sound automagically after 30 s */
58 struct midi_pcppi_softc
{
59 struct midi_softc sc_mididev
;
63 static int midi_pcppi_match(device_t
, cfdata_t
, void *);
64 static void midi_pcppi_attach(device_t
, device_t
, void *);
65 static int midi_pcppi_detach(device_t
, int);
67 void midi_pcppi_on (midisyn
*, uint_fast16_t, midipitch_t
, int16_t);
68 void midi_pcppi_off (midisyn
*, uint_fast16_t, uint_fast8_t);
69 void midi_pcppi_close(midisyn
*);
70 static void midi_pcppi_repitchv(midisyn
*, uint_fast16_t, midipitch_t
);
72 CFATTACH_DECL3_NEW(midi_pcppi
, sizeof(struct midi_pcppi_softc
),
73 midi_pcppi_match
, midi_pcppi_attach
, midi_pcppi_detach
, NULL
, NULL
, NULL
,
76 struct midisyn_methods midi_pcppi_hw
= {
77 .close
= midi_pcppi_close
,
78 .attackv
= midi_pcppi_on
,
79 .releasev
= midi_pcppi_off
,
80 .repitchv
= midi_pcppi_repitchv
,
83 int midi_pcppi_attached
= 0; /* Not very nice */
86 midi_pcppi_match(device_t parent
, cfdata_t match
, void *aux
)
88 return (!midi_pcppi_attached
);
92 midi_pcppi_attach(device_t parent
, device_t self
, void *aux
)
94 struct midi_pcppi_softc
*sc
= device_private(self
);
95 struct pcppi_attach_args
*pa
= (struct pcppi_attach_args
*)aux
;
98 sc
->sc_mididev
.dev
= self
;
100 ms
->mets
= &midi_pcppi_hw
;
101 strcpy(ms
->name
, "PC speaker");
103 ms
->data
= pa
->pa_cookie
;
105 midi_pcppi_attached
++;
107 midisyn_attach(&sc
->sc_mididev
, ms
);
108 midi_attach(&sc
->sc_mididev
, parent
);
109 if (!device_pmf_is_registered(self
))
110 if (!pmf_device_register(self
, NULL
, NULL
))
111 aprint_error_dev(self
,
112 "couldn't establish power handler\n");
116 midi_pcppi_detach(device_t self
, int flags
)
118 KASSERT(midi_pcppi_attached
> 0);
120 midi_pcppi_attached
--;
121 return mididetach(self
, flags
);
125 midi_pcppi_on(midisyn
*ms
,
126 uint_fast16_t voice
, midipitch_t mp
, int16_t level
)
128 pcppi_tag_t t
= ms
->data
;
131 MIDIHZ18_TO_HZ(MIDIPITCH_TO_HZ18(mp
)),
132 MAX_DURATION
* hz
, 0);
136 midi_pcppi_off(midisyn
*ms
, uint_fast16_t voice
, uint_fast8_t vel
)
138 pcppi_tag_t t
= ms
->data
;
140 /*printf("OFF %p %d\n", t, note >> 16);*/
141 pcppi_bell(t
, 0, 0, 0);
145 midi_pcppi_close(midisyn
*ms
)
147 pcppi_tag_t t
= ms
->data
;
149 /* Make sure we are quiet. */
150 pcppi_bell(t
, 0, 0, 0);
154 midi_pcppi_repitchv(midisyn
*ms
, uint_fast16_t voice
, midipitch_t newpitch
)
156 midi_pcppi_on(ms
, voice
, newpitch
, 64);