Thu Aug 29 13:01:07 2019 UTC ()
Fix lock assertion on async I/O mode.
psignal() must be called without any spin locks.
Thanks maxv@!


(isaki)
diff -r1.29 -r1.30 src/sys/dev/audio/audio.c
diff -r1.4 -r1.5 src/sys/dev/audio/audiovar.h

cvs diff -r1.29 -r1.30 src/sys/dev/audio/audio.c (switch to unified diff)

--- src/sys/dev/audio/audio.c 2019/08/23 09:41:26 1.29
+++ src/sys/dev/audio/audio.c 2019/08/29 13:01:07 1.30
@@ -1,1144 +1,1144 @@ @@ -1,1144 +1,1144 @@
1/* $NetBSD: audio.c,v 1.29 2019/08/23 09:41:26 maxv Exp $ */ 1/* $NetBSD: audio.c,v 1.30 2019/08/29 13:01:07 isaki Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran. 8 * by Andrew Doran.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 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 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 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 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 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * Copyright (c) 1991-1993 Regents of the University of California. 33 * Copyright (c) 1991-1993 Regents of the University of California.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions 37 * modification, are permitted provided that the following conditions
38 * are met: 38 * are met:
39 * 1. Redistributions of source code must retain the above copyright 39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer. 40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright 41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the 42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution. 43 * documentation and/or other materials provided with the distribution.
44 * 3. All advertising materials mentioning features or use of this software 44 * 3. All advertising materials mentioning features or use of this software
45 * must display the following acknowledgement: 45 * must display the following acknowledgement:
46 * This product includes software developed by the Computer Systems 46 * This product includes software developed by the Computer Systems
47 * Engineering Group at Lawrence Berkeley Laboratory. 47 * Engineering Group at Lawrence Berkeley Laboratory.
48 * 4. Neither the name of the University nor of the Laboratory may be used 48 * 4. Neither the name of the University nor of the Laboratory may be used
49 * to endorse or promote products derived from this software without 49 * to endorse or promote products derived from this software without
50 * specific prior written permission. 50 * specific prior written permission.
51 * 51 *
52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62 * SUCH DAMAGE. 62 * SUCH DAMAGE.
63 */ 63 */
64 64
65/* 65/*
66 * Locking: there are three locks per device. 66 * Locking: there are three locks per device.
67 * 67 *
68 * - sc_lock, provided by the underlying driver. This is an adaptive lock, 68 * - sc_lock, provided by the underlying driver. This is an adaptive lock,
69 * returned in the second parameter to hw_if->get_locks(). It is known 69 * returned in the second parameter to hw_if->get_locks(). It is known
70 * as the "thread lock". 70 * as the "thread lock".
71 * 71 *
72 * It serializes access to state in all places except the 72 * It serializes access to state in all places except the
73 * driver's interrupt service routine. This lock is taken from process 73 * driver's interrupt service routine. This lock is taken from process
74 * context (example: access to /dev/audio). It is also taken from soft 74 * context (example: access to /dev/audio). It is also taken from soft
75 * interrupt handlers in this module, primarily to serialize delivery of 75 * interrupt handlers in this module, primarily to serialize delivery of
76 * wakeups. This lock may be used/provided by modules external to the 76 * wakeups. This lock may be used/provided by modules external to the
77 * audio subsystem, so take care not to introduce a lock order problem. 77 * audio subsystem, so take care not to introduce a lock order problem.
78 * LONG TERM SLEEPS MUST NOT OCCUR WITH THIS LOCK HELD. 78 * LONG TERM SLEEPS MUST NOT OCCUR WITH THIS LOCK HELD.
79 * 79 *
80 * - sc_intr_lock, provided by the underlying driver. This may be either a 80 * - sc_intr_lock, provided by the underlying driver. This may be either a
81 * spinlock (at IPL_SCHED or IPL_VM) or an adaptive lock (IPL_NONE or 81 * spinlock (at IPL_SCHED or IPL_VM) or an adaptive lock (IPL_NONE or
82 * IPL_SOFT*), returned in the first parameter to hw_if->get_locks(). It 82 * IPL_SOFT*), returned in the first parameter to hw_if->get_locks(). It
83 * is known as the "interrupt lock". 83 * is known as the "interrupt lock".
84 * 84 *
85 * It provides atomic access to the device's hardware state, and to audio 85 * It provides atomic access to the device's hardware state, and to audio
86 * channel data that may be accessed by the hardware driver's ISR. 86 * channel data that may be accessed by the hardware driver's ISR.
87 * In all places outside the ISR, sc_lock must be held before taking 87 * In all places outside the ISR, sc_lock must be held before taking
88 * sc_intr_lock. This is to ensure that groups of hardware operations are 88 * sc_intr_lock. This is to ensure that groups of hardware operations are
89 * made atomically. SLEEPS CANNOT OCCUR WITH THIS LOCK HELD. 89 * made atomically. SLEEPS CANNOT OCCUR WITH THIS LOCK HELD.
90 * 90 *
91 * - sc_exlock, private to this module. This is a variable protected by 91 * - sc_exlock, private to this module. This is a variable protected by
92 * sc_lock. It is known as the "critical section". 92 * sc_lock. It is known as the "critical section".
93 * Some operations release sc_lock in order to allocate memory, to wait 93 * Some operations release sc_lock in order to allocate memory, to wait
94 * for in-flight I/O to complete, to copy to/from user context, etc. 94 * for in-flight I/O to complete, to copy to/from user context, etc.
95 * sc_exlock provides a critical section even under the circumstance. 95 * sc_exlock provides a critical section even under the circumstance.
96 * "+" in following list indicates the interfaces which necessary to be 96 * "+" in following list indicates the interfaces which necessary to be
97 * protected by sc_exlock. 97 * protected by sc_exlock.
98 * 98 *
99 * List of hardware interface methods, and which locks are held when each 99 * List of hardware interface methods, and which locks are held when each
100 * is called by this module: 100 * is called by this module:
101 * 101 *
102 * METHOD INTR THREAD NOTES 102 * METHOD INTR THREAD NOTES
103 * ----------------------- ------- ------- ------------------------- 103 * ----------------------- ------- ------- -------------------------
104 * open x x + 104 * open x x +
105 * close x x + 105 * close x x +
106 * query_format - x 106 * query_format - x
107 * set_format - x 107 * set_format - x
108 * round_blocksize - x 108 * round_blocksize - x
109 * commit_settings - x 109 * commit_settings - x
110 * init_output x x 110 * init_output x x
111 * init_input x x 111 * init_input x x
112 * start_output x x + 112 * start_output x x +
113 * start_input x x + 113 * start_input x x +
114 * halt_output x x + 114 * halt_output x x +
115 * halt_input x x + 115 * halt_input x x +
116 * speaker_ctl x x 116 * speaker_ctl x x
117 * getdev - x 117 * getdev - x
118 * set_port - x + 118 * set_port - x +
119 * get_port - x + 119 * get_port - x +
120 * query_devinfo - x 120 * query_devinfo - x
121 * allocm - - + (*1) 121 * allocm - - + (*1)
122 * freem - - + (*1) 122 * freem - - + (*1)
123 * round_buffersize - x 123 * round_buffersize - x
124 * get_props - x Called at attach time 124 * get_props - x Called at attach time
125 * trigger_output x x + 125 * trigger_output x x +
126 * trigger_input x x + 126 * trigger_input x x +
127 * dev_ioctl - x 127 * dev_ioctl - x
128 * get_locks - - Called at attach time 128 * get_locks - - Called at attach time
129 * 129 *
130 * *1 Note: Before 8.0, since these have been called only at attach time, 130 * *1 Note: Before 8.0, since these have been called only at attach time,
131 * neither lock were necessary. Currently, on the other hand, since 131 * neither lock were necessary. Currently, on the other hand, since
132 * these may be also called after attach, the thread lock is required. 132 * these may be also called after attach, the thread lock is required.
133 * 133 *
134 * In addition, there is an additional lock. 134 * In addition, there is an additional lock.
135 * 135 *
136 * - track->lock. This is an atomic variable and is similar to the 136 * - track->lock. This is an atomic variable and is similar to the
137 * "interrupt lock". This is one for each track. If any thread context 137 * "interrupt lock". This is one for each track. If any thread context
138 * (and software interrupt context) and hardware interrupt context who 138 * (and software interrupt context) and hardware interrupt context who
139 * want to access some variables on this track, they must acquire this 139 * want to access some variables on this track, they must acquire this
140 * lock before. It protects track's consistency between hardware 140 * lock before. It protects track's consistency between hardware
141 * interrupt context and others. 141 * interrupt context and others.
142 */ 142 */
143 143
144#include <sys/cdefs.h> 144#include <sys/cdefs.h>
145__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.29 2019/08/23 09:41:26 maxv Exp $"); 145__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.30 2019/08/29 13:01:07 isaki Exp $");
146 146
147#ifdef _KERNEL_OPT 147#ifdef _KERNEL_OPT
148#include "audio.h" 148#include "audio.h"
149#include "midi.h" 149#include "midi.h"
150#endif 150#endif
151 151
152#if NAUDIO > 0 152#if NAUDIO > 0
153 153
154#ifdef _KERNEL 154#ifdef _KERNEL
155 155
156#include <sys/types.h> 156#include <sys/types.h>
157#include <sys/param.h> 157#include <sys/param.h>
158#include <sys/atomic.h> 158#include <sys/atomic.h>
159#include <sys/audioio.h> 159#include <sys/audioio.h>
160#include <sys/conf.h> 160#include <sys/conf.h>
161#include <sys/cpu.h> 161#include <sys/cpu.h>
162#include <sys/device.h> 162#include <sys/device.h>
163#include <sys/fcntl.h> 163#include <sys/fcntl.h>
164#include <sys/file.h> 164#include <sys/file.h>
165#include <sys/filedesc.h> 165#include <sys/filedesc.h>
166#include <sys/intr.h> 166#include <sys/intr.h>
167#include <sys/ioctl.h> 167#include <sys/ioctl.h>
168#include <sys/kauth.h> 168#include <sys/kauth.h>
169#include <sys/kernel.h> 169#include <sys/kernel.h>
170#include <sys/kmem.h> 170#include <sys/kmem.h>
171#include <sys/malloc.h> 171#include <sys/malloc.h>
172#include <sys/mman.h> 172#include <sys/mman.h>
173#include <sys/module.h> 173#include <sys/module.h>
174#include <sys/poll.h> 174#include <sys/poll.h>
175#include <sys/proc.h> 175#include <sys/proc.h>
176#include <sys/queue.h> 176#include <sys/queue.h>
177#include <sys/select.h> 177#include <sys/select.h>
178#include <sys/signalvar.h> 178#include <sys/signalvar.h>
179#include <sys/stat.h> 179#include <sys/stat.h>
180#include <sys/sysctl.h> 180#include <sys/sysctl.h>
181#include <sys/systm.h> 181#include <sys/systm.h>
182#include <sys/syslog.h> 182#include <sys/syslog.h>
183#include <sys/vnode.h> 183#include <sys/vnode.h>
184 184
185#include <dev/audio/audio_if.h> 185#include <dev/audio/audio_if.h>
186#include <dev/audio/audiovar.h> 186#include <dev/audio/audiovar.h>
187#include <dev/audio/audiodef.h> 187#include <dev/audio/audiodef.h>
188#include <dev/audio/linear.h> 188#include <dev/audio/linear.h>
189#include <dev/audio/mulaw.h> 189#include <dev/audio/mulaw.h>
190 190
191#include <machine/endian.h> 191#include <machine/endian.h>
192 192
193#include <uvm/uvm.h> 193#include <uvm/uvm.h>
194 194
195#include "ioconf.h" 195#include "ioconf.h"
196#endif /* _KERNEL */ 196#endif /* _KERNEL */
197 197
198/* 198/*
199 * 0: No debug logs 199 * 0: No debug logs
200 * 1: action changes like open/close/set_format... 200 * 1: action changes like open/close/set_format...
201 * 2: + normal operations like read/write/ioctl... 201 * 2: + normal operations like read/write/ioctl...
202 * 3: + TRACEs except interrupt 202 * 3: + TRACEs except interrupt
203 * 4: + TRACEs including interrupt 203 * 4: + TRACEs including interrupt
204 */ 204 */
205//#define AUDIO_DEBUG 1 205//#define AUDIO_DEBUG 1
206 206
207#if defined(AUDIO_DEBUG) 207#if defined(AUDIO_DEBUG)
208 208
209int audiodebug = AUDIO_DEBUG; 209int audiodebug = AUDIO_DEBUG;
210static void audio_vtrace(struct audio_softc *sc, const char *, const char *, 210static void audio_vtrace(struct audio_softc *sc, const char *, const char *,
211 const char *, va_list); 211 const char *, va_list);
212static void audio_trace(struct audio_softc *sc, const char *, const char *, ...) 212static void audio_trace(struct audio_softc *sc, const char *, const char *, ...)
213 __printflike(3, 4); 213 __printflike(3, 4);
214static void audio_tracet(const char *, audio_track_t *, const char *, ...) 214static void audio_tracet(const char *, audio_track_t *, const char *, ...)
215 __printflike(3, 4); 215 __printflike(3, 4);
216static void audio_tracef(const char *, audio_file_t *, const char *, ...) 216static void audio_tracef(const char *, audio_file_t *, const char *, ...)
217 __printflike(3, 4); 217 __printflike(3, 4);
218 218
219/* XXX sloppy memory logger */ 219/* XXX sloppy memory logger */
220static void audio_mlog_init(void); 220static void audio_mlog_init(void);
221static void audio_mlog_free(void); 221static void audio_mlog_free(void);
222static void audio_mlog_softintr(void *); 222static void audio_mlog_softintr(void *);
223extern void audio_mlog_flush(void); 223extern void audio_mlog_flush(void);
224extern void audio_mlog_printf(const char *, ...); 224extern void audio_mlog_printf(const char *, ...);
225 225
226static int mlog_refs; /* reference counter */ 226static int mlog_refs; /* reference counter */
227static char *mlog_buf[2]; /* double buffer */ 227static char *mlog_buf[2]; /* double buffer */
228static int mlog_buflen; /* buffer length */ 228static int mlog_buflen; /* buffer length */
229static int mlog_used; /* used length */ 229static int mlog_used; /* used length */
230static int mlog_full; /* number of dropped lines by buffer full */ 230static int mlog_full; /* number of dropped lines by buffer full */
231static int mlog_drop; /* number of dropped lines by busy */ 231static int mlog_drop; /* number of dropped lines by busy */
232static volatile uint32_t mlog_inuse; /* in-use */ 232static volatile uint32_t mlog_inuse; /* in-use */
233static int mlog_wpage; /* active page */ 233static int mlog_wpage; /* active page */
234static void *mlog_sih; /* softint handle */ 234static void *mlog_sih; /* softint handle */
235 235
236static void 236static void
237audio_mlog_init(void) 237audio_mlog_init(void)
238{ 238{
239 mlog_refs++; 239 mlog_refs++;
240 if (mlog_refs > 1) 240 if (mlog_refs > 1)
241 return; 241 return;
242 mlog_buflen = 4096; 242 mlog_buflen = 4096;
243 mlog_buf[0] = kmem_zalloc(mlog_buflen, KM_SLEEP); 243 mlog_buf[0] = kmem_zalloc(mlog_buflen, KM_SLEEP);
244 mlog_buf[1] = kmem_zalloc(mlog_buflen, KM_SLEEP); 244 mlog_buf[1] = kmem_zalloc(mlog_buflen, KM_SLEEP);
245 mlog_used = 0; 245 mlog_used = 0;
246 mlog_full = 0; 246 mlog_full = 0;
247 mlog_drop = 0; 247 mlog_drop = 0;
248 mlog_inuse = 0; 248 mlog_inuse = 0;
249 mlog_wpage = 0; 249 mlog_wpage = 0;
250 mlog_sih = softint_establish(SOFTINT_SERIAL, audio_mlog_softintr, NULL); 250 mlog_sih = softint_establish(SOFTINT_SERIAL, audio_mlog_softintr, NULL);
251 if (mlog_sih == NULL) 251 if (mlog_sih == NULL)
252 printf("%s: softint_establish failed\n", __func__); 252 printf("%s: softint_establish failed\n", __func__);
253} 253}
254 254
255static void 255static void
256audio_mlog_free(void) 256audio_mlog_free(void)
257{ 257{
258 mlog_refs--; 258 mlog_refs--;
259 if (mlog_refs > 0) 259 if (mlog_refs > 0)
260 return; 260 return;
261 261
262 audio_mlog_flush(); 262 audio_mlog_flush();
263 if (mlog_sih) 263 if (mlog_sih)
264 softint_disestablish(mlog_sih); 264 softint_disestablish(mlog_sih);
265 kmem_free(mlog_buf[0], mlog_buflen); 265 kmem_free(mlog_buf[0], mlog_buflen);
266 kmem_free(mlog_buf[1], mlog_buflen); 266 kmem_free(mlog_buf[1], mlog_buflen);
267} 267}
268 268
269/* 269/*
270 * Flush memory buffer. 270 * Flush memory buffer.
271 * It must not be called from hardware interrupt context. 271 * It must not be called from hardware interrupt context.
272 */ 272 */
273void 273void
274audio_mlog_flush(void) 274audio_mlog_flush(void)
275{ 275{
276 if (mlog_refs == 0) 276 if (mlog_refs == 0)
277 return; 277 return;
278 278
279 /* Nothing to do if already in use ? */ 279 /* Nothing to do if already in use ? */
280 if (atomic_swap_32(&mlog_inuse, 1) == 1) 280 if (atomic_swap_32(&mlog_inuse, 1) == 1)
281 return; 281 return;
282 282
283 int rpage = mlog_wpage; 283 int rpage = mlog_wpage;
284 mlog_wpage ^= 1; 284 mlog_wpage ^= 1;
285 mlog_buf[mlog_wpage][0] = '\0'; 285 mlog_buf[mlog_wpage][0] = '\0';
286 mlog_used = 0; 286 mlog_used = 0;
287 287
288 atomic_swap_32(&mlog_inuse, 0); 288 atomic_swap_32(&mlog_inuse, 0);
289 289
290 if (mlog_buf[rpage][0] != '\0') { 290 if (mlog_buf[rpage][0] != '\0') {
291 printf("%s", mlog_buf[rpage]); 291 printf("%s", mlog_buf[rpage]);
292 if (mlog_drop > 0) 292 if (mlog_drop > 0)
293 printf("mlog_drop %d\n", mlog_drop); 293 printf("mlog_drop %d\n", mlog_drop);
294 if (mlog_full > 0) 294 if (mlog_full > 0)
295 printf("mlog_full %d\n", mlog_full); 295 printf("mlog_full %d\n", mlog_full);
296 } 296 }
297 mlog_full = 0; 297 mlog_full = 0;
298 mlog_drop = 0; 298 mlog_drop = 0;
299} 299}
300 300
301static void 301static void
302audio_mlog_softintr(void *cookie) 302audio_mlog_softintr(void *cookie)
303{ 303{
304 audio_mlog_flush(); 304 audio_mlog_flush();
305} 305}
306 306
307void 307void
308audio_mlog_printf(const char *fmt, ...) 308audio_mlog_printf(const char *fmt, ...)
309{ 309{
310 int len; 310 int len;
311 va_list ap; 311 va_list ap;
312 312
313 if (atomic_swap_32(&mlog_inuse, 1) == 1) { 313 if (atomic_swap_32(&mlog_inuse, 1) == 1) {
314 /* already inuse */ 314 /* already inuse */
315 mlog_drop++; 315 mlog_drop++;
316 return; 316 return;
317 } 317 }
318 318
319 va_start(ap, fmt); 319 va_start(ap, fmt);
320 len = vsnprintf( 320 len = vsnprintf(
321 mlog_buf[mlog_wpage] + mlog_used, 321 mlog_buf[mlog_wpage] + mlog_used,
322 mlog_buflen - mlog_used, 322 mlog_buflen - mlog_used,
323 fmt, ap); 323 fmt, ap);
324 va_end(ap); 324 va_end(ap);
325 325
326 mlog_used += len; 326 mlog_used += len;
327 if (mlog_buflen - mlog_used <= 1) { 327 if (mlog_buflen - mlog_used <= 1) {
328 mlog_full++; 328 mlog_full++;
329 } 329 }
330 330
331 atomic_swap_32(&mlog_inuse, 0); 331 atomic_swap_32(&mlog_inuse, 0);
332 332
333 if (mlog_sih) 333 if (mlog_sih)
334 softint_schedule(mlog_sih); 334 softint_schedule(mlog_sih);
335} 335}
336 336
337/* trace functions */ 337/* trace functions */
338static void 338static void
339audio_vtrace(struct audio_softc *sc, const char *funcname, const char *header, 339audio_vtrace(struct audio_softc *sc, const char *funcname, const char *header,
340 const char *fmt, va_list ap) 340 const char *fmt, va_list ap)
341{ 341{
342 char buf[256]; 342 char buf[256];
343 int n; 343 int n;
344 344
345 n = 0; 345 n = 0;
346 buf[0] = '\0'; 346 buf[0] = '\0';
347 n += snprintf(buf + n, sizeof(buf) - n, "%s@%d %s", 347 n += snprintf(buf + n, sizeof(buf) - n, "%s@%d %s",
348 funcname, device_unit(sc->sc_dev), header); 348 funcname, device_unit(sc->sc_dev), header);
349 n += vsnprintf(buf + n, sizeof(buf) - n, fmt, ap); 349 n += vsnprintf(buf + n, sizeof(buf) - n, fmt, ap);
350 350
351 if (cpu_intr_p()) { 351 if (cpu_intr_p()) {
352 audio_mlog_printf("%s\n", buf); 352 audio_mlog_printf("%s\n", buf);
353 } else { 353 } else {
354 audio_mlog_flush(); 354 audio_mlog_flush();
355 printf("%s\n", buf); 355 printf("%s\n", buf);
356 } 356 }
357} 357}
358 358
359static void 359static void
360audio_trace(struct audio_softc *sc, const char *funcname, const char *fmt, ...) 360audio_trace(struct audio_softc *sc, const char *funcname, const char *fmt, ...)
361{ 361{
362 va_list ap; 362 va_list ap;
363 363
364 va_start(ap, fmt); 364 va_start(ap, fmt);
365 audio_vtrace(sc, funcname, "", fmt, ap); 365 audio_vtrace(sc, funcname, "", fmt, ap);
366 va_end(ap); 366 va_end(ap);
367} 367}
368 368
369static void 369static void
370audio_tracet(const char *funcname, audio_track_t *track, const char *fmt, ...) 370audio_tracet(const char *funcname, audio_track_t *track, const char *fmt, ...)
371{ 371{
372 char hdr[16]; 372 char hdr[16];
373 va_list ap; 373 va_list ap;
374 374
375 snprintf(hdr, sizeof(hdr), "#%d ", track->id); 375 snprintf(hdr, sizeof(hdr), "#%d ", track->id);
376 va_start(ap, fmt); 376 va_start(ap, fmt);
377 audio_vtrace(track->mixer->sc, funcname, hdr, fmt, ap); 377 audio_vtrace(track->mixer->sc, funcname, hdr, fmt, ap);
378 va_end(ap); 378 va_end(ap);
379} 379}
380 380
381static void 381static void
382audio_tracef(const char *funcname, audio_file_t *file, const char *fmt, ...) 382audio_tracef(const char *funcname, audio_file_t *file, const char *fmt, ...)
383{ 383{
384 char hdr[32]; 384 char hdr[32];
385 char phdr[16], rhdr[16]; 385 char phdr[16], rhdr[16];
386 va_list ap; 386 va_list ap;
387 387
388 phdr[0] = '\0'; 388 phdr[0] = '\0';
389 rhdr[0] = '\0'; 389 rhdr[0] = '\0';
390 if (file->ptrack) 390 if (file->ptrack)
391 snprintf(phdr, sizeof(phdr), "#%d", file->ptrack->id); 391 snprintf(phdr, sizeof(phdr), "#%d", file->ptrack->id);
392 if (file->rtrack) 392 if (file->rtrack)
393 snprintf(rhdr, sizeof(rhdr), "#%d", file->rtrack->id); 393 snprintf(rhdr, sizeof(rhdr), "#%d", file->rtrack->id);
394 snprintf(hdr, sizeof(hdr), "{%s,%s} ", phdr, rhdr); 394 snprintf(hdr, sizeof(hdr), "{%s,%s} ", phdr, rhdr);
395 395
396 va_start(ap, fmt); 396 va_start(ap, fmt);
397 audio_vtrace(file->sc, funcname, hdr, fmt, ap); 397 audio_vtrace(file->sc, funcname, hdr, fmt, ap);
398 va_end(ap); 398 va_end(ap);
399} 399}
400 400
401#define DPRINTF(n, fmt...) do { \ 401#define DPRINTF(n, fmt...) do { \
402 if (audiodebug >= (n)) { \ 402 if (audiodebug >= (n)) { \
403 audio_mlog_flush(); \ 403 audio_mlog_flush(); \
404 printf(fmt); \ 404 printf(fmt); \
405 } \ 405 } \
406} while (0) 406} while (0)
407#define TRACE(n, fmt...) do { \ 407#define TRACE(n, fmt...) do { \
408 if (audiodebug >= (n)) audio_trace(sc, __func__, fmt); \ 408 if (audiodebug >= (n)) audio_trace(sc, __func__, fmt); \
409} while (0) 409} while (0)
410#define TRACET(n, t, fmt...) do { \ 410#define TRACET(n, t, fmt...) do { \
411 if (audiodebug >= (n)) audio_tracet(__func__, t, fmt); \ 411 if (audiodebug >= (n)) audio_tracet(__func__, t, fmt); \
412} while (0) 412} while (0)
413#define TRACEF(n, f, fmt...) do { \ 413#define TRACEF(n, f, fmt...) do { \
414 if (audiodebug >= (n)) audio_tracef(__func__, f, fmt); \ 414 if (audiodebug >= (n)) audio_tracef(__func__, f, fmt); \
415} while (0) 415} while (0)
416 416
417struct audio_track_debugbuf { 417struct audio_track_debugbuf {
418 char usrbuf[32]; 418 char usrbuf[32];
419 char codec[32]; 419 char codec[32];
420 char chvol[32]; 420 char chvol[32];
421 char chmix[32]; 421 char chmix[32];
422 char freq[32]; 422 char freq[32];
423 char outbuf[32]; 423 char outbuf[32];
424}; 424};
425 425
426static void 426static void
427audio_track_bufstat(audio_track_t *track, struct audio_track_debugbuf *buf) 427audio_track_bufstat(audio_track_t *track, struct audio_track_debugbuf *buf)
428{ 428{
429 429
430 memset(buf, 0, sizeof(*buf)); 430 memset(buf, 0, sizeof(*buf));
431 431
432 snprintf(buf->outbuf, sizeof(buf->outbuf), " out=%d/%d/%d", 432 snprintf(buf->outbuf, sizeof(buf->outbuf), " out=%d/%d/%d",
433 track->outbuf.head, track->outbuf.used, track->outbuf.capacity); 433 track->outbuf.head, track->outbuf.used, track->outbuf.capacity);
434 if (track->freq.filter) 434 if (track->freq.filter)
435 snprintf(buf->freq, sizeof(buf->freq), " f=%d/%d/%d", 435 snprintf(buf->freq, sizeof(buf->freq), " f=%d/%d/%d",
436 track->freq.srcbuf.head, 436 track->freq.srcbuf.head,
437 track->freq.srcbuf.used, 437 track->freq.srcbuf.used,
438 track->freq.srcbuf.capacity); 438 track->freq.srcbuf.capacity);
439 if (track->chmix.filter) 439 if (track->chmix.filter)
440 snprintf(buf->chmix, sizeof(buf->chmix), " m=%d", 440 snprintf(buf->chmix, sizeof(buf->chmix), " m=%d",
441 track->chmix.srcbuf.used); 441 track->chmix.srcbuf.used);
442 if (track->chvol.filter) 442 if (track->chvol.filter)
443 snprintf(buf->chvol, sizeof(buf->chvol), " v=%d", 443 snprintf(buf->chvol, sizeof(buf->chvol), " v=%d",
444 track->chvol.srcbuf.used); 444 track->chvol.srcbuf.used);
445 if (track->codec.filter) 445 if (track->codec.filter)
446 snprintf(buf->codec, sizeof(buf->codec), " e=%d", 446 snprintf(buf->codec, sizeof(buf->codec), " e=%d",
447 track->codec.srcbuf.used); 447 track->codec.srcbuf.used);
448 snprintf(buf->usrbuf, sizeof(buf->usrbuf), " usr=%d/%d/H%d", 448 snprintf(buf->usrbuf, sizeof(buf->usrbuf), " usr=%d/%d/H%d",
449 track->usrbuf.head, track->usrbuf.used, track->usrbuf_usedhigh); 449 track->usrbuf.head, track->usrbuf.used, track->usrbuf_usedhigh);
450} 450}
451#else 451#else
452#define DPRINTF(n, fmt...) do { } while (0) 452#define DPRINTF(n, fmt...) do { } while (0)
453#define TRACE(n, fmt, ...) do { } while (0) 453#define TRACE(n, fmt, ...) do { } while (0)
454#define TRACET(n, t, fmt, ...) do { } while (0) 454#define TRACET(n, t, fmt, ...) do { } while (0)
455#define TRACEF(n, f, fmt, ...) do { } while (0) 455#define TRACEF(n, f, fmt, ...) do { } while (0)
456#endif 456#endif
457 457
458#define SPECIFIED(x) ((x) != ~0) 458#define SPECIFIED(x) ((x) != ~0)
459#define SPECIFIED_CH(x) ((x) != (u_char)~0) 459#define SPECIFIED_CH(x) ((x) != (u_char)~0)
460 460
461/* Device timeout in msec */ 461/* Device timeout in msec */
462#define AUDIO_TIMEOUT (3000) 462#define AUDIO_TIMEOUT (3000)
463 463
464/* #define AUDIO_PM_IDLE */ 464/* #define AUDIO_PM_IDLE */
465#ifdef AUDIO_PM_IDLE 465#ifdef AUDIO_PM_IDLE
466int audio_idle_timeout = 30; 466int audio_idle_timeout = 30;
467#endif 467#endif
468 468
469struct portname { 469struct portname {
470 const char *name; 470 const char *name;
471 int mask; 471 int mask;
472}; 472};
473 473
474static int audiomatch(device_t, cfdata_t, void *); 474static int audiomatch(device_t, cfdata_t, void *);
475static void audioattach(device_t, device_t, void *); 475static void audioattach(device_t, device_t, void *);
476static int audiodetach(device_t, int); 476static int audiodetach(device_t, int);
477static int audioactivate(device_t, enum devact); 477static int audioactivate(device_t, enum devact);
478static void audiochilddet(device_t, device_t); 478static void audiochilddet(device_t, device_t);
479static int audiorescan(device_t, const char *, const int *); 479static int audiorescan(device_t, const char *, const int *);
480 480
481static int audio_modcmd(modcmd_t, void *); 481static int audio_modcmd(modcmd_t, void *);
482 482
483#ifdef AUDIO_PM_IDLE 483#ifdef AUDIO_PM_IDLE
484static void audio_idle(void *); 484static void audio_idle(void *);
485static void audio_activity(device_t, devactive_t); 485static void audio_activity(device_t, devactive_t);
486#endif 486#endif
487 487
488static bool audio_suspend(device_t dv, const pmf_qual_t *); 488static bool audio_suspend(device_t dv, const pmf_qual_t *);
489static bool audio_resume(device_t dv, const pmf_qual_t *); 489static bool audio_resume(device_t dv, const pmf_qual_t *);
490static void audio_volume_down(device_t); 490static void audio_volume_down(device_t);
491static void audio_volume_up(device_t); 491static void audio_volume_up(device_t);
492static void audio_volume_toggle(device_t); 492static void audio_volume_toggle(device_t);
493 493
494static void audio_mixer_capture(struct audio_softc *); 494static void audio_mixer_capture(struct audio_softc *);
495static void audio_mixer_restore(struct audio_softc *); 495static void audio_mixer_restore(struct audio_softc *);
496 496
497static void audio_softintr_rd(void *); 497static void audio_softintr_rd(void *);
498static void audio_softintr_wr(void *); 498static void audio_softintr_wr(void *);
499 499
500static int audio_enter_exclusive(struct audio_softc *); 500static int audio_enter_exclusive(struct audio_softc *);
501static void audio_exit_exclusive(struct audio_softc *); 501static void audio_exit_exclusive(struct audio_softc *);
502static int audio_track_waitio(struct audio_softc *, audio_track_t *); 502static int audio_track_waitio(struct audio_softc *, audio_track_t *);
503 503
504static int audioclose(struct file *); 504static int audioclose(struct file *);
505static int audioread(struct file *, off_t *, struct uio *, kauth_cred_t, int); 505static int audioread(struct file *, off_t *, struct uio *, kauth_cred_t, int);
506static int audiowrite(struct file *, off_t *, struct uio *, kauth_cred_t, int); 506static int audiowrite(struct file *, off_t *, struct uio *, kauth_cred_t, int);
507static int audioioctl(struct file *, u_long, void *); 507static int audioioctl(struct file *, u_long, void *);
508static int audiopoll(struct file *, int); 508static int audiopoll(struct file *, int);
509static int audiokqfilter(struct file *, struct knote *); 509static int audiokqfilter(struct file *, struct knote *);
510static int audiommap(struct file *, off_t *, size_t, int, int *, int *, 510static int audiommap(struct file *, off_t *, size_t, int, int *, int *,
511 struct uvm_object **, int *); 511 struct uvm_object **, int *);
512static int audiostat(struct file *, struct stat *); 512static int audiostat(struct file *, struct stat *);
513 513
514static void filt_audiowrite_detach(struct knote *); 514static void filt_audiowrite_detach(struct knote *);
515static int filt_audiowrite_event(struct knote *, long); 515static int filt_audiowrite_event(struct knote *, long);
516static void filt_audioread_detach(struct knote *); 516static void filt_audioread_detach(struct knote *);
517static int filt_audioread_event(struct knote *, long); 517static int filt_audioread_event(struct knote *, long);
518 518
519static int audio_open(dev_t, struct audio_softc *, int, int, struct lwp *, 519static int audio_open(dev_t, struct audio_softc *, int, int, struct lwp *,
520 audio_file_t **); 520 audio_file_t **);
521static int audio_close(struct audio_softc *, audio_file_t *); 521static int audio_close(struct audio_softc *, audio_file_t *);
522static int audio_read(struct audio_softc *, struct uio *, int, audio_file_t *); 522static int audio_read(struct audio_softc *, struct uio *, int, audio_file_t *);
523static int audio_write(struct audio_softc *, struct uio *, int, audio_file_t *); 523static int audio_write(struct audio_softc *, struct uio *, int, audio_file_t *);
524static void audio_file_clear(struct audio_softc *, audio_file_t *); 524static void audio_file_clear(struct audio_softc *, audio_file_t *);
525static int audio_ioctl(dev_t, struct audio_softc *, u_long, void *, int, 525static int audio_ioctl(dev_t, struct audio_softc *, u_long, void *, int,
526 struct lwp *, audio_file_t *); 526 struct lwp *, audio_file_t *);
527static int audio_poll(struct audio_softc *, int, struct lwp *, audio_file_t *); 527static int audio_poll(struct audio_softc *, int, struct lwp *, audio_file_t *);
528static int audio_kqfilter(struct audio_softc *, audio_file_t *, struct knote *); 528static int audio_kqfilter(struct audio_softc *, audio_file_t *, struct knote *);
529static int audio_mmap(struct audio_softc *, off_t *, size_t, int, int *, int *, 529static int audio_mmap(struct audio_softc *, off_t *, size_t, int, int *, int *,
530 struct uvm_object **, int *, audio_file_t *); 530 struct uvm_object **, int *, audio_file_t *);
531 531
532static int audioctl_open(dev_t, struct audio_softc *, int, int, struct lwp *); 532static int audioctl_open(dev_t, struct audio_softc *, int, int, struct lwp *);
533 533
534static void audio_pintr(void *); 534static void audio_pintr(void *);
535static void audio_rintr(void *); 535static void audio_rintr(void *);
536 536
537static int audio_query_devinfo(struct audio_softc *, mixer_devinfo_t *); 537static int audio_query_devinfo(struct audio_softc *, mixer_devinfo_t *);
538 538
539static __inline int audio_track_readablebytes(const audio_track_t *); 539static __inline int audio_track_readablebytes(const audio_track_t *);
540static int audio_file_setinfo(struct audio_softc *, audio_file_t *, 540static int audio_file_setinfo(struct audio_softc *, audio_file_t *,
541 const struct audio_info *); 541 const struct audio_info *);
542static int audio_track_setinfo_check(audio_format2_t *, 542static int audio_track_setinfo_check(audio_format2_t *,
543 const struct audio_prinfo *); 543 const struct audio_prinfo *);
544static void audio_track_setinfo_water(audio_track_t *, 544static void audio_track_setinfo_water(audio_track_t *,
545 const struct audio_info *); 545 const struct audio_info *);
546static int audio_hw_setinfo(struct audio_softc *, const struct audio_info *, 546static int audio_hw_setinfo(struct audio_softc *, const struct audio_info *,
547 struct audio_info *); 547 struct audio_info *);
548static int audio_hw_set_format(struct audio_softc *, int, 548static int audio_hw_set_format(struct audio_softc *, int,
549 audio_format2_t *, audio_format2_t *, 549 audio_format2_t *, audio_format2_t *,
550 audio_filter_reg_t *, audio_filter_reg_t *); 550 audio_filter_reg_t *, audio_filter_reg_t *);
551static int audiogetinfo(struct audio_softc *, struct audio_info *, int, 551static int audiogetinfo(struct audio_softc *, struct audio_info *, int,
552 audio_file_t *); 552 audio_file_t *);
553static bool audio_can_playback(struct audio_softc *); 553static bool audio_can_playback(struct audio_softc *);
554static bool audio_can_capture(struct audio_softc *); 554static bool audio_can_capture(struct audio_softc *);
555static int audio_check_params(audio_format2_t *); 555static int audio_check_params(audio_format2_t *);
556static int audio_mixers_init(struct audio_softc *sc, int, 556static int audio_mixers_init(struct audio_softc *sc, int,
557 const audio_format2_t *, const audio_format2_t *, 557 const audio_format2_t *, const audio_format2_t *,
558 const audio_filter_reg_t *, const audio_filter_reg_t *); 558 const audio_filter_reg_t *, const audio_filter_reg_t *);
559static int audio_select_freq(const struct audio_format *); 559static int audio_select_freq(const struct audio_format *);
560static int audio_hw_probe(struct audio_softc *, int, int *, 560static int audio_hw_probe(struct audio_softc *, int, int *,
561 audio_format2_t *, audio_format2_t *); 561 audio_format2_t *, audio_format2_t *);
562static int audio_hw_probe_fmt(struct audio_softc *, audio_format2_t *, int); 562static int audio_hw_probe_fmt(struct audio_softc *, audio_format2_t *, int);
563static int audio_hw_validate_format(struct audio_softc *, int, 563static int audio_hw_validate_format(struct audio_softc *, int,
564 const audio_format2_t *); 564 const audio_format2_t *);
565static int audio_mixers_set_format(struct audio_softc *, 565static int audio_mixers_set_format(struct audio_softc *,
566 const struct audio_info *); 566 const struct audio_info *);
567static void audio_mixers_get_format(struct audio_softc *, struct audio_info *); 567static void audio_mixers_get_format(struct audio_softc *, struct audio_info *);
568static int audio_sysctl_blk_ms(SYSCTLFN_PROTO); 568static int audio_sysctl_blk_ms(SYSCTLFN_PROTO);
569static int audio_sysctl_multiuser(SYSCTLFN_PROTO); 569static int audio_sysctl_multiuser(SYSCTLFN_PROTO);
570#if defined(AUDIO_DEBUG) 570#if defined(AUDIO_DEBUG)
571static int audio_sysctl_debug(SYSCTLFN_PROTO); 571static int audio_sysctl_debug(SYSCTLFN_PROTO);
572static void audio_format2_tostr(char *, size_t, const audio_format2_t *); 572static void audio_format2_tostr(char *, size_t, const audio_format2_t *);
573static void audio_print_format2(const char *, const audio_format2_t *) __unused; 573static void audio_print_format2(const char *, const audio_format2_t *) __unused;
574#endif 574#endif
575 575
576static void *audio_realloc(void *, size_t); 576static void *audio_realloc(void *, size_t);
577static int audio_realloc_usrbuf(audio_track_t *, int); 577static int audio_realloc_usrbuf(audio_track_t *, int);
578static void audio_free_usrbuf(audio_track_t *); 578static void audio_free_usrbuf(audio_track_t *);
579 579
580static audio_track_t *audio_track_create(struct audio_softc *, 580static audio_track_t *audio_track_create(struct audio_softc *,
581 audio_trackmixer_t *); 581 audio_trackmixer_t *);
582static void audio_track_destroy(audio_track_t *); 582static void audio_track_destroy(audio_track_t *);
583static audio_filter_t audio_track_get_codec(audio_track_t *, 583static audio_filter_t audio_track_get_codec(audio_track_t *,
584 const audio_format2_t *, const audio_format2_t *); 584 const audio_format2_t *, const audio_format2_t *);
585static int audio_track_set_format(audio_track_t *, audio_format2_t *); 585static int audio_track_set_format(audio_track_t *, audio_format2_t *);
586static void audio_track_play(audio_track_t *); 586static void audio_track_play(audio_track_t *);
587static int audio_track_drain(struct audio_softc *, audio_track_t *); 587static int audio_track_drain(struct audio_softc *, audio_track_t *);
588static void audio_track_record(audio_track_t *); 588static void audio_track_record(audio_track_t *);
589static void audio_track_clear(struct audio_softc *, audio_track_t *); 589static void audio_track_clear(struct audio_softc *, audio_track_t *);
590 590
591static int audio_mixer_init(struct audio_softc *, int, 591static int audio_mixer_init(struct audio_softc *, int,
592 const audio_format2_t *, const audio_filter_reg_t *); 592 const audio_format2_t *, const audio_filter_reg_t *);
593static void audio_mixer_destroy(struct audio_softc *, audio_trackmixer_t *); 593static void audio_mixer_destroy(struct audio_softc *, audio_trackmixer_t *);
594static void audio_pmixer_start(struct audio_softc *, bool); 594static void audio_pmixer_start(struct audio_softc *, bool);
595static void audio_pmixer_process(struct audio_softc *); 595static void audio_pmixer_process(struct audio_softc *);
596static void audio_pmixer_agc(audio_trackmixer_t *, int); 596static void audio_pmixer_agc(audio_trackmixer_t *, int);
597static int audio_pmixer_mix_track(audio_trackmixer_t *, audio_track_t *, int); 597static int audio_pmixer_mix_track(audio_trackmixer_t *, audio_track_t *, int);
598static void audio_pmixer_output(struct audio_softc *); 598static void audio_pmixer_output(struct audio_softc *);
599static int audio_pmixer_halt(struct audio_softc *); 599static int audio_pmixer_halt(struct audio_softc *);
600static void audio_rmixer_start(struct audio_softc *); 600static void audio_rmixer_start(struct audio_softc *);
601static void audio_rmixer_process(struct audio_softc *); 601static void audio_rmixer_process(struct audio_softc *);
602static void audio_rmixer_input(struct audio_softc *); 602static void audio_rmixer_input(struct audio_softc *);
603static int audio_rmixer_halt(struct audio_softc *); 603static int audio_rmixer_halt(struct audio_softc *);
604 604
605static void mixer_init(struct audio_softc *); 605static void mixer_init(struct audio_softc *);
606static int mixer_open(dev_t, struct audio_softc *, int, int, struct lwp *); 606static int mixer_open(dev_t, struct audio_softc *, int, int, struct lwp *);
607static int mixer_close(struct audio_softc *, audio_file_t *); 607static int mixer_close(struct audio_softc *, audio_file_t *);
608static int mixer_ioctl(struct audio_softc *, u_long, void *, int, struct lwp *); 608static int mixer_ioctl(struct audio_softc *, u_long, void *, int, struct lwp *);
609static void mixer_remove(struct audio_softc *); 609static void mixer_remove(struct audio_softc *);
610static void mixer_signal(struct audio_softc *); 610static void mixer_signal(struct audio_softc *);
611 611
612static int au_portof(struct audio_softc *, char *, int); 612static int au_portof(struct audio_softc *, char *, int);
613 613
614static void au_setup_ports(struct audio_softc *, struct au_mixer_ports *, 614static void au_setup_ports(struct audio_softc *, struct au_mixer_ports *,
615 mixer_devinfo_t *, const struct portname *); 615 mixer_devinfo_t *, const struct portname *);
616static int au_set_lr_value(struct audio_softc *, mixer_ctrl_t *, int, int); 616static int au_set_lr_value(struct audio_softc *, mixer_ctrl_t *, int, int);
617static int au_get_lr_value(struct audio_softc *, mixer_ctrl_t *, int *, int *); 617static int au_get_lr_value(struct audio_softc *, mixer_ctrl_t *, int *, int *);
618static int au_set_gain(struct audio_softc *, struct au_mixer_ports *, int, int); 618static int au_set_gain(struct audio_softc *, struct au_mixer_ports *, int, int);
619static void au_get_gain(struct audio_softc *, struct au_mixer_ports *, 619static void au_get_gain(struct audio_softc *, struct au_mixer_ports *,
620 u_int *, u_char *); 620 u_int *, u_char *);
621static int au_set_port(struct audio_softc *, struct au_mixer_ports *, u_int); 621static int au_set_port(struct audio_softc *, struct au_mixer_ports *, u_int);
622static int au_get_port(struct audio_softc *, struct au_mixer_ports *); 622static int au_get_port(struct audio_softc *, struct au_mixer_ports *);
623static int au_set_monitor_gain(struct audio_softc *, int); 623static int au_set_monitor_gain(struct audio_softc *, int);
624static int au_get_monitor_gain(struct audio_softc *); 624static int au_get_monitor_gain(struct audio_softc *);
625static int audio_get_port(struct audio_softc *, mixer_ctrl_t *); 625static int audio_get_port(struct audio_softc *, mixer_ctrl_t *);
626static int audio_set_port(struct audio_softc *, mixer_ctrl_t *); 626static int audio_set_port(struct audio_softc *, mixer_ctrl_t *);
627 627
628static __inline struct audio_params 628static __inline struct audio_params
629format2_to_params(const audio_format2_t *f2) 629format2_to_params(const audio_format2_t *f2)
630{ 630{
631 audio_params_t p; 631 audio_params_t p;
632 632
633 /* validbits/precision <-> precision/stride */ 633 /* validbits/precision <-> precision/stride */
634 p.sample_rate = f2->sample_rate; 634 p.sample_rate = f2->sample_rate;
635 p.channels = f2->channels; 635 p.channels = f2->channels;
636 p.encoding = f2->encoding; 636 p.encoding = f2->encoding;
637 p.validbits = f2->precision; 637 p.validbits = f2->precision;
638 p.precision = f2->stride; 638 p.precision = f2->stride;
639 return p; 639 return p;
640} 640}
641 641
642static __inline audio_format2_t 642static __inline audio_format2_t
643params_to_format2(const struct audio_params *p) 643params_to_format2(const struct audio_params *p)
644{ 644{
645 audio_format2_t f2; 645 audio_format2_t f2;
646 646
647 /* precision/stride <-> validbits/precision */ 647 /* precision/stride <-> validbits/precision */
648 f2.sample_rate = p->sample_rate; 648 f2.sample_rate = p->sample_rate;
649 f2.channels = p->channels; 649 f2.channels = p->channels;
650 f2.encoding = p->encoding; 650 f2.encoding = p->encoding;
651 f2.precision = p->validbits; 651 f2.precision = p->validbits;
652 f2.stride = p->precision; 652 f2.stride = p->precision;
653 return f2; 653 return f2;
654} 654}
655 655
656/* Return true if this track is a playback track. */ 656/* Return true if this track is a playback track. */
657static __inline bool 657static __inline bool
658audio_track_is_playback(const audio_track_t *track) 658audio_track_is_playback(const audio_track_t *track)
659{ 659{
660 660
661 return ((track->mode & AUMODE_PLAY) != 0); 661 return ((track->mode & AUMODE_PLAY) != 0);
662} 662}
663 663
664/* Return true if this track is a recording track. */ 664/* Return true if this track is a recording track. */
665static __inline bool 665static __inline bool
666audio_track_is_record(const audio_track_t *track) 666audio_track_is_record(const audio_track_t *track)
667{ 667{
668 668
669 return ((track->mode & AUMODE_RECORD) != 0); 669 return ((track->mode & AUMODE_RECORD) != 0);
670} 670}
671 671
672#if 0 /* XXX Not used yet */ 672#if 0 /* XXX Not used yet */
673/* 673/*
674 * Convert 0..255 volume used in userland to internal presentation 0..256. 674 * Convert 0..255 volume used in userland to internal presentation 0..256.
675 */ 675 */
676static __inline u_int 676static __inline u_int
677audio_volume_to_inner(u_int v) 677audio_volume_to_inner(u_int v)
678{ 678{
679 679
680 return v < 127 ? v : v + 1; 680 return v < 127 ? v : v + 1;
681} 681}
682 682
683/* 683/*
684 * Convert 0..256 internal presentation to 0..255 volume used in userland. 684 * Convert 0..256 internal presentation to 0..255 volume used in userland.
685 */ 685 */
686static __inline u_int 686static __inline u_int
687audio_volume_to_outer(u_int v) 687audio_volume_to_outer(u_int v)
688{ 688{
689 689
690 return v < 127 ? v : v - 1; 690 return v < 127 ? v : v - 1;
691} 691}
692#endif /* 0 */ 692#endif /* 0 */
693 693
694static dev_type_open(audioopen); 694static dev_type_open(audioopen);
695/* XXXMRG use more dev_type_xxx */ 695/* XXXMRG use more dev_type_xxx */
696 696
697const struct cdevsw audio_cdevsw = { 697const struct cdevsw audio_cdevsw = {
698 .d_open = audioopen, 698 .d_open = audioopen,
699 .d_close = noclose, 699 .d_close = noclose,
700 .d_read = noread, 700 .d_read = noread,
701 .d_write = nowrite, 701 .d_write = nowrite,
702 .d_ioctl = noioctl, 702 .d_ioctl = noioctl,
703 .d_stop = nostop, 703 .d_stop = nostop,
704 .d_tty = notty, 704 .d_tty = notty,
705 .d_poll = nopoll, 705 .d_poll = nopoll,
706 .d_mmap = nommap, 706 .d_mmap = nommap,
707 .d_kqfilter = nokqfilter, 707 .d_kqfilter = nokqfilter,
708 .d_discard = nodiscard, 708 .d_discard = nodiscard,
709 .d_flag = D_OTHER | D_MPSAFE 709 .d_flag = D_OTHER | D_MPSAFE
710}; 710};
711 711
712const struct fileops audio_fileops = { 712const struct fileops audio_fileops = {
713 .fo_name = "audio", 713 .fo_name = "audio",
714 .fo_read = audioread, 714 .fo_read = audioread,
715 .fo_write = audiowrite, 715 .fo_write = audiowrite,
716 .fo_ioctl = audioioctl, 716 .fo_ioctl = audioioctl,
717 .fo_fcntl = fnullop_fcntl, 717 .fo_fcntl = fnullop_fcntl,
718 .fo_stat = audiostat, 718 .fo_stat = audiostat,
719 .fo_poll = audiopoll, 719 .fo_poll = audiopoll,
720 .fo_close = audioclose, 720 .fo_close = audioclose,
721 .fo_mmap = audiommap, 721 .fo_mmap = audiommap,
722 .fo_kqfilter = audiokqfilter, 722 .fo_kqfilter = audiokqfilter,
723 .fo_restart = fnullop_restart 723 .fo_restart = fnullop_restart
724}; 724};
725 725
726/* The default audio mode: 8 kHz mono mu-law */ 726/* The default audio mode: 8 kHz mono mu-law */
727static const struct audio_params audio_default = { 727static const struct audio_params audio_default = {
728 .sample_rate = 8000, 728 .sample_rate = 8000,
729 .encoding = AUDIO_ENCODING_ULAW, 729 .encoding = AUDIO_ENCODING_ULAW,
730 .precision = 8, 730 .precision = 8,
731 .validbits = 8, 731 .validbits = 8,
732 .channels = 1, 732 .channels = 1,
733}; 733};
734 734
735static const char *encoding_names[] = { 735static const char *encoding_names[] = {
736 "none", 736 "none",
737 AudioEmulaw, 737 AudioEmulaw,
738 AudioEalaw, 738 AudioEalaw,
739 "pcm16", 739 "pcm16",
740 "pcm8", 740 "pcm8",
741 AudioEadpcm, 741 AudioEadpcm,
742 AudioEslinear_le, 742 AudioEslinear_le,
743 AudioEslinear_be, 743 AudioEslinear_be,
744 AudioEulinear_le, 744 AudioEulinear_le,
745 AudioEulinear_be, 745 AudioEulinear_be,
746 AudioEslinear, 746 AudioEslinear,
747 AudioEulinear, 747 AudioEulinear,
748 AudioEmpeg_l1_stream, 748 AudioEmpeg_l1_stream,
749 AudioEmpeg_l1_packets, 749 AudioEmpeg_l1_packets,
750 AudioEmpeg_l1_system, 750 AudioEmpeg_l1_system,
751 AudioEmpeg_l2_stream, 751 AudioEmpeg_l2_stream,
752 AudioEmpeg_l2_packets, 752 AudioEmpeg_l2_packets,
753 AudioEmpeg_l2_system, 753 AudioEmpeg_l2_system,
754 AudioEac3, 754 AudioEac3,
755}; 755};
756 756
757/* 757/*
758 * Returns encoding name corresponding to AUDIO_ENCODING_*. 758 * Returns encoding name corresponding to AUDIO_ENCODING_*.
759 * Note that it may return a local buffer because it is mainly for debugging. 759 * Note that it may return a local buffer because it is mainly for debugging.
760 */ 760 */
761const char * 761const char *
762audio_encoding_name(int encoding) 762audio_encoding_name(int encoding)
763{ 763{
764 static char buf[16]; 764 static char buf[16];
765 765
766 if (0 <= encoding && encoding < __arraycount(encoding_names)) { 766 if (0 <= encoding && encoding < __arraycount(encoding_names)) {
767 return encoding_names[encoding]; 767 return encoding_names[encoding];
768 } else { 768 } else {
769 snprintf(buf, sizeof(buf), "enc=%d", encoding); 769 snprintf(buf, sizeof(buf), "enc=%d", encoding);
770 return buf; 770 return buf;
771 } 771 }
772} 772}
773 773
774/* 774/*
775 * Supported encodings used by AUDIO_GETENC. 775 * Supported encodings used by AUDIO_GETENC.
776 * index and flags are set by code. 776 * index and flags are set by code.
777 * XXX is there any needs for SLINEAR_OE:>=16/ULINEAR_OE:>=16 ? 777 * XXX is there any needs for SLINEAR_OE:>=16/ULINEAR_OE:>=16 ?
778 */ 778 */
779static const audio_encoding_t audio_encodings[] = { 779static const audio_encoding_t audio_encodings[] = {
780 { 0, AudioEmulaw, AUDIO_ENCODING_ULAW, 8, 0 }, 780 { 0, AudioEmulaw, AUDIO_ENCODING_ULAW, 8, 0 },
781 { 0, AudioEalaw, AUDIO_ENCODING_ALAW, 8, 0 }, 781 { 0, AudioEalaw, AUDIO_ENCODING_ALAW, 8, 0 },
782 { 0, AudioEslinear, AUDIO_ENCODING_SLINEAR, 8, 0 }, 782 { 0, AudioEslinear, AUDIO_ENCODING_SLINEAR, 8, 0 },
783 { 0, AudioEulinear, AUDIO_ENCODING_ULINEAR, 8, 0 }, 783 { 0, AudioEulinear, AUDIO_ENCODING_ULINEAR, 8, 0 },
784 { 0, AudioEslinear_le, AUDIO_ENCODING_SLINEAR_LE, 16, 0 }, 784 { 0, AudioEslinear_le, AUDIO_ENCODING_SLINEAR_LE, 16, 0 },
785 { 0, AudioEulinear_le, AUDIO_ENCODING_ULINEAR_LE, 16, 0 }, 785 { 0, AudioEulinear_le, AUDIO_ENCODING_ULINEAR_LE, 16, 0 },
786 { 0, AudioEslinear_be, AUDIO_ENCODING_SLINEAR_BE, 16, 0 }, 786 { 0, AudioEslinear_be, AUDIO_ENCODING_SLINEAR_BE, 16, 0 },
787 { 0, AudioEulinear_be, AUDIO_ENCODING_ULINEAR_BE, 16, 0 }, 787 { 0, AudioEulinear_be, AUDIO_ENCODING_ULINEAR_BE, 16, 0 },
788#if defined(AUDIO_SUPPORT_LINEAR24) 788#if defined(AUDIO_SUPPORT_LINEAR24)
789 { 0, AudioEslinear_le, AUDIO_ENCODING_SLINEAR_LE, 24, 0 }, 789 { 0, AudioEslinear_le, AUDIO_ENCODING_SLINEAR_LE, 24, 0 },
790 { 0, AudioEulinear_le, AUDIO_ENCODING_ULINEAR_LE, 24, 0 }, 790 { 0, AudioEulinear_le, AUDIO_ENCODING_ULINEAR_LE, 24, 0 },
791 { 0, AudioEslinear_be, AUDIO_ENCODING_SLINEAR_BE, 24, 0 }, 791 { 0, AudioEslinear_be, AUDIO_ENCODING_SLINEAR_BE, 24, 0 },
792 { 0, AudioEulinear_be, AUDIO_ENCODING_ULINEAR_BE, 24, 0 }, 792 { 0, AudioEulinear_be, AUDIO_ENCODING_ULINEAR_BE, 24, 0 },
793#endif 793#endif
794 { 0, AudioEslinear_le, AUDIO_ENCODING_SLINEAR_LE, 32, 0 }, 794 { 0, AudioEslinear_le, AUDIO_ENCODING_SLINEAR_LE, 32, 0 },
795 { 0, AudioEulinear_le, AUDIO_ENCODING_ULINEAR_LE, 32, 0 }, 795 { 0, AudioEulinear_le, AUDIO_ENCODING_ULINEAR_LE, 32, 0 },
796 { 0, AudioEslinear_be, AUDIO_ENCODING_SLINEAR_BE, 32, 0 }, 796 { 0, AudioEslinear_be, AUDIO_ENCODING_SLINEAR_BE, 32, 0 },
797 { 0, AudioEulinear_be, AUDIO_ENCODING_ULINEAR_BE, 32, 0 }, 797 { 0, AudioEulinear_be, AUDIO_ENCODING_ULINEAR_BE, 32, 0 },
798}; 798};
799 799
800static const struct portname itable[] = { 800static const struct portname itable[] = {
801 { AudioNmicrophone, AUDIO_MICROPHONE }, 801 { AudioNmicrophone, AUDIO_MICROPHONE },
802 { AudioNline, AUDIO_LINE_IN }, 802 { AudioNline, AUDIO_LINE_IN },
803 { AudioNcd, AUDIO_CD }, 803 { AudioNcd, AUDIO_CD },
804 { 0, 0 } 804 { 0, 0 }
805}; 805};
806static const struct portname otable[] = { 806static const struct portname otable[] = {
807 { AudioNspeaker, AUDIO_SPEAKER }, 807 { AudioNspeaker, AUDIO_SPEAKER },
808 { AudioNheadphone, AUDIO_HEADPHONE }, 808 { AudioNheadphone, AUDIO_HEADPHONE },
809 { AudioNline, AUDIO_LINE_OUT }, 809 { AudioNline, AUDIO_LINE_OUT },
810 { 0, 0 } 810 { 0, 0 }
811}; 811};
812 812
813CFATTACH_DECL3_NEW(audio, sizeof(struct audio_softc), 813CFATTACH_DECL3_NEW(audio, sizeof(struct audio_softc),
814 audiomatch, audioattach, audiodetach, audioactivate, audiorescan, 814 audiomatch, audioattach, audiodetach, audioactivate, audiorescan,
815 audiochilddet, DVF_DETACH_SHUTDOWN); 815 audiochilddet, DVF_DETACH_SHUTDOWN);
816 816
817static int 817static int
818audiomatch(device_t parent, cfdata_t match, void *aux) 818audiomatch(device_t parent, cfdata_t match, void *aux)
819{ 819{
820 struct audio_attach_args *sa; 820 struct audio_attach_args *sa;
821 821
822 sa = aux; 822 sa = aux;
823 DPRINTF(1, "%s: type=%d sa=%p hw=%p\n", 823 DPRINTF(1, "%s: type=%d sa=%p hw=%p\n",
824 __func__, sa->type, sa, sa->hwif); 824 __func__, sa->type, sa, sa->hwif);
825 return (sa->type == AUDIODEV_TYPE_AUDIO) ? 1 : 0; 825 return (sa->type == AUDIODEV_TYPE_AUDIO) ? 1 : 0;
826} 826}
827 827
828static void 828static void
829audioattach(device_t parent, device_t self, void *aux) 829audioattach(device_t parent, device_t self, void *aux)
830{ 830{
831 struct audio_softc *sc; 831 struct audio_softc *sc;
832 struct audio_attach_args *sa; 832 struct audio_attach_args *sa;
833 const struct audio_hw_if *hw_if; 833 const struct audio_hw_if *hw_if;
834 audio_format2_t phwfmt; 834 audio_format2_t phwfmt;
835 audio_format2_t rhwfmt; 835 audio_format2_t rhwfmt;
836 audio_filter_reg_t pfil; 836 audio_filter_reg_t pfil;
837 audio_filter_reg_t rfil; 837 audio_filter_reg_t rfil;
838 const struct sysctlnode *node; 838 const struct sysctlnode *node;
839 void *hdlp; 839 void *hdlp;
840 bool has_playback; 840 bool has_playback;
841 bool has_capture; 841 bool has_capture;
842 bool has_indep; 842 bool has_indep;
843 bool has_fulldup; 843 bool has_fulldup;
844 int mode; 844 int mode;
845 int error; 845 int error;
846 846
847 sc = device_private(self); 847 sc = device_private(self);
848 sc->sc_dev = self; 848 sc->sc_dev = self;
849 sa = (struct audio_attach_args *)aux; 849 sa = (struct audio_attach_args *)aux;
850 hw_if = sa->hwif; 850 hw_if = sa->hwif;
851 hdlp = sa->hdl; 851 hdlp = sa->hdl;
852 852
853 if (hw_if == NULL || hw_if->get_locks == NULL) { 853 if (hw_if == NULL || hw_if->get_locks == NULL) {
854 panic("audioattach: missing hw_if method"); 854 panic("audioattach: missing hw_if method");
855 } 855 }
856 856
857 hw_if->get_locks(hdlp, &sc->sc_intr_lock, &sc->sc_lock); 857 hw_if->get_locks(hdlp, &sc->sc_intr_lock, &sc->sc_lock);
858 858
859#ifdef DIAGNOSTIC 859#ifdef DIAGNOSTIC
860 if (hw_if->query_format == NULL || 860 if (hw_if->query_format == NULL ||
861 hw_if->set_format == NULL || 861 hw_if->set_format == NULL ||
862 (hw_if->start_output == NULL && hw_if->trigger_output == NULL) || 862 (hw_if->start_output == NULL && hw_if->trigger_output == NULL) ||
863 (hw_if->start_input == NULL && hw_if->trigger_input == NULL) || 863 (hw_if->start_input == NULL && hw_if->trigger_input == NULL) ||
864 hw_if->halt_output == NULL || 864 hw_if->halt_output == NULL ||
865 hw_if->halt_input == NULL || 865 hw_if->halt_input == NULL ||
866 hw_if->getdev == NULL || 866 hw_if->getdev == NULL ||
867 hw_if->set_port == NULL || 867 hw_if->set_port == NULL ||
868 hw_if->get_port == NULL || 868 hw_if->get_port == NULL ||
869 hw_if->query_devinfo == NULL || 869 hw_if->query_devinfo == NULL ||
870 hw_if->get_props == NULL) { 870 hw_if->get_props == NULL) {
871 aprint_error(": missing method\n"); 871 aprint_error(": missing method\n");
872 return; 872 return;
873 } 873 }
874#endif 874#endif
875 875
876 sc->hw_if = hw_if; 876 sc->hw_if = hw_if;
877 sc->hw_hdl = hdlp; 877 sc->hw_hdl = hdlp;
878 sc->hw_dev = parent; 878 sc->hw_dev = parent;
879 879
880 sc->sc_blk_ms = AUDIO_BLK_MS; 880 sc->sc_blk_ms = AUDIO_BLK_MS;
881 SLIST_INIT(&sc->sc_files); 881 SLIST_INIT(&sc->sc_files);
882 cv_init(&sc->sc_exlockcv, "audiolk"); 882 cv_init(&sc->sc_exlockcv, "audiolk");
883 883
884 mutex_enter(sc->sc_lock); 884 mutex_enter(sc->sc_lock);
885 sc->sc_props = hw_if->get_props(sc->hw_hdl); 885 sc->sc_props = hw_if->get_props(sc->hw_hdl);
886 mutex_exit(sc->sc_lock); 886 mutex_exit(sc->sc_lock);
887 887
888 /* MMAP is now supported by upper layer. */ 888 /* MMAP is now supported by upper layer. */
889 sc->sc_props |= AUDIO_PROP_MMAP; 889 sc->sc_props |= AUDIO_PROP_MMAP;
890 890
891 has_playback = (sc->sc_props & AUDIO_PROP_PLAYBACK); 891 has_playback = (sc->sc_props & AUDIO_PROP_PLAYBACK);
892 has_capture = (sc->sc_props & AUDIO_PROP_CAPTURE); 892 has_capture = (sc->sc_props & AUDIO_PROP_CAPTURE);
893 has_indep = (sc->sc_props & AUDIO_PROP_INDEPENDENT); 893 has_indep = (sc->sc_props & AUDIO_PROP_INDEPENDENT);
894 has_fulldup = (sc->sc_props & AUDIO_PROP_FULLDUPLEX); 894 has_fulldup = (sc->sc_props & AUDIO_PROP_FULLDUPLEX);
895 895
896 KASSERT(has_playback || has_capture); 896 KASSERT(has_playback || has_capture);
897 /* Unidirectional device must have neither FULLDUP nor INDEPENDENT. */ 897 /* Unidirectional device must have neither FULLDUP nor INDEPENDENT. */
898 if (!has_playback || !has_capture) { 898 if (!has_playback || !has_capture) {
899 KASSERT(!has_indep); 899 KASSERT(!has_indep);
900 KASSERT(!has_fulldup); 900 KASSERT(!has_fulldup);
901 } 901 }
902 902
903 mode = 0; 903 mode = 0;
904 if (has_playback) { 904 if (has_playback) {
905 aprint_normal(": playback"); 905 aprint_normal(": playback");
906 mode |= AUMODE_PLAY; 906 mode |= AUMODE_PLAY;
907 } 907 }
908 if (has_capture) { 908 if (has_capture) {
909 aprint_normal("%c capture", has_playback ? ',' : ':'); 909 aprint_normal("%c capture", has_playback ? ',' : ':');
910 mode |= AUMODE_RECORD; 910 mode |= AUMODE_RECORD;
911 } 911 }
912 if (has_playback && has_capture) { 912 if (has_playback && has_capture) {
913 if (has_fulldup) 913 if (has_fulldup)
914 aprint_normal(", full duplex"); 914 aprint_normal(", full duplex");
915 else 915 else
916 aprint_normal(", half duplex"); 916 aprint_normal(", half duplex");
917 917
918 if (has_indep) 918 if (has_indep)
919 aprint_normal(", independent"); 919 aprint_normal(", independent");
920 } 920 }
921 921
922 aprint_naive("\n"); 922 aprint_naive("\n");
923 aprint_normal("\n"); 923 aprint_normal("\n");
924 924
925 /* probe hw params */ 925 /* probe hw params */
926 memset(&phwfmt, 0, sizeof(phwfmt)); 926 memset(&phwfmt, 0, sizeof(phwfmt));
927 memset(&rhwfmt, 0, sizeof(rhwfmt)); 927 memset(&rhwfmt, 0, sizeof(rhwfmt));
928 memset(&pfil, 0, sizeof(pfil)); 928 memset(&pfil, 0, sizeof(pfil));
929 memset(&rfil, 0, sizeof(rfil)); 929 memset(&rfil, 0, sizeof(rfil));
930 mutex_enter(sc->sc_lock); 930 mutex_enter(sc->sc_lock);
931 error = audio_hw_probe(sc, has_indep, &mode, &phwfmt, &rhwfmt); 931 error = audio_hw_probe(sc, has_indep, &mode, &phwfmt, &rhwfmt);
932 if (error) { 932 if (error) {
933 mutex_exit(sc->sc_lock); 933 mutex_exit(sc->sc_lock);
934 aprint_error_dev(self, "audio_hw_probe failed, " 934 aprint_error_dev(self, "audio_hw_probe failed, "
935 "error = %d\n", error); 935 "error = %d\n", error);
936 goto bad; 936 goto bad;
937 } 937 }
938 if (mode == 0) { 938 if (mode == 0) {
939 mutex_exit(sc->sc_lock); 939 mutex_exit(sc->sc_lock);
940 aprint_error_dev(self, "audio_hw_probe failed, no mode\n"); 940 aprint_error_dev(self, "audio_hw_probe failed, no mode\n");
941 goto bad; 941 goto bad;
942 } 942 }
943 /* Init hardware. */ 943 /* Init hardware. */
944 /* hw_probe() also validates [pr]hwfmt. */ 944 /* hw_probe() also validates [pr]hwfmt. */
945 error = audio_hw_set_format(sc, mode, &phwfmt, &rhwfmt, &pfil, &rfil); 945 error = audio_hw_set_format(sc, mode, &phwfmt, &rhwfmt, &pfil, &rfil);
946 if (error) { 946 if (error) {
947 mutex_exit(sc->sc_lock); 947 mutex_exit(sc->sc_lock);
948 aprint_error_dev(self, "audio_hw_set_format failed, " 948 aprint_error_dev(self, "audio_hw_set_format failed, "
949 "error = %d\n", error); 949 "error = %d\n", error);
950 goto bad; 950 goto bad;
951 } 951 }
952 952
953 /* 953 /*
954 * Init track mixers. If at least one direction is available on 954 * Init track mixers. If at least one direction is available on
955 * attach time, we assume a success. 955 * attach time, we assume a success.
956 */ 956 */
957 error = audio_mixers_init(sc, mode, &phwfmt, &rhwfmt, &pfil, &rfil); 957 error = audio_mixers_init(sc, mode, &phwfmt, &rhwfmt, &pfil, &rfil);
958 mutex_exit(sc->sc_lock); 958 mutex_exit(sc->sc_lock);
959 if (sc->sc_pmixer == NULL && sc->sc_rmixer == NULL) { 959 if (sc->sc_pmixer == NULL && sc->sc_rmixer == NULL) {
960 aprint_error_dev(self, "audio_mixers_init failed, " 960 aprint_error_dev(self, "audio_mixers_init failed, "
961 "error = %d\n", error); 961 "error = %d\n", error);
962 goto bad; 962 goto bad;
963 } 963 }
964 964
965 selinit(&sc->sc_wsel); 965 selinit(&sc->sc_wsel);
966 selinit(&sc->sc_rsel); 966 selinit(&sc->sc_rsel);
967 967
968 /* Initial parameter of /dev/sound */ 968 /* Initial parameter of /dev/sound */
969 sc->sc_sound_pparams = params_to_format2(&audio_default); 969 sc->sc_sound_pparams = params_to_format2(&audio_default);
970 sc->sc_sound_rparams = params_to_format2(&audio_default); 970 sc->sc_sound_rparams = params_to_format2(&audio_default);
971 sc->sc_sound_ppause = false; 971 sc->sc_sound_ppause = false;
972 sc->sc_sound_rpause = false; 972 sc->sc_sound_rpause = false;
973 973
974 /* XXX TODO: consider about sc_ai */ 974 /* XXX TODO: consider about sc_ai */
975 975
976 mixer_init(sc); 976 mixer_init(sc);
977 TRACE(2, "inputs ports=0x%x, input master=%d, " 977 TRACE(2, "inputs ports=0x%x, input master=%d, "
978 "output ports=0x%x, output master=%d", 978 "output ports=0x%x, output master=%d",
979 sc->sc_inports.allports, sc->sc_inports.master, 979 sc->sc_inports.allports, sc->sc_inports.master,
980 sc->sc_outports.allports, sc->sc_outports.master); 980 sc->sc_outports.allports, sc->sc_outports.master);
981 981
982 sysctl_createv(&sc->sc_log, 0, NULL, &node, 982 sysctl_createv(&sc->sc_log, 0, NULL, &node,
983 0, 983 0,
984 CTLTYPE_NODE, device_xname(sc->sc_dev), 984 CTLTYPE_NODE, device_xname(sc->sc_dev),
985 SYSCTL_DESCR("audio test"), 985 SYSCTL_DESCR("audio test"),
986 NULL, 0, 986 NULL, 0,
987 NULL, 0, 987 NULL, 0,
988 CTL_HW, 988 CTL_HW,
989 CTL_CREATE, CTL_EOL); 989 CTL_CREATE, CTL_EOL);
990 990
991 if (node != NULL) { 991 if (node != NULL) {
992 sysctl_createv(&sc->sc_log, 0, NULL, NULL, 992 sysctl_createv(&sc->sc_log, 0, NULL, NULL,
993 CTLFLAG_READWRITE, 993 CTLFLAG_READWRITE,
994 CTLTYPE_INT, "blk_ms", 994 CTLTYPE_INT, "blk_ms",
995 SYSCTL_DESCR("blocksize in msec"), 995 SYSCTL_DESCR("blocksize in msec"),
996 audio_sysctl_blk_ms, 0, (void *)sc, 0, 996 audio_sysctl_blk_ms, 0, (void *)sc, 0,
997 CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL); 997 CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL);
998 998
999 sysctl_createv(&sc->sc_log, 0, NULL, NULL, 999 sysctl_createv(&sc->sc_log, 0, NULL, NULL,
1000 CTLFLAG_READWRITE, 1000 CTLFLAG_READWRITE,
1001 CTLTYPE_BOOL, "multiuser", 1001 CTLTYPE_BOOL, "multiuser",
1002 SYSCTL_DESCR("allow multiple user access"), 1002 SYSCTL_DESCR("allow multiple user access"),
1003 audio_sysctl_multiuser, 0, (void *)sc, 0, 1003 audio_sysctl_multiuser, 0, (void *)sc, 0,
1004 CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL); 1004 CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL);
1005 1005
1006#if defined(AUDIO_DEBUG) 1006#if defined(AUDIO_DEBUG)
1007 sysctl_createv(&sc->sc_log, 0, NULL, NULL, 1007 sysctl_createv(&sc->sc_log, 0, NULL, NULL,
1008 CTLFLAG_READWRITE, 1008 CTLFLAG_READWRITE,
1009 CTLTYPE_INT, "debug", 1009 CTLTYPE_INT, "debug",
1010 SYSCTL_DESCR("debug level (0..4)"), 1010 SYSCTL_DESCR("debug level (0..4)"),
1011 audio_sysctl_debug, 0, (void *)sc, 0, 1011 audio_sysctl_debug, 0, (void *)sc, 0,
1012 CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL); 1012 CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL);
1013#endif 1013#endif
1014 } 1014 }
1015 1015
1016#ifdef AUDIO_PM_IDLE 1016#ifdef AUDIO_PM_IDLE
1017 callout_init(&sc->sc_idle_counter, 0); 1017 callout_init(&sc->sc_idle_counter, 0);
1018 callout_setfunc(&sc->sc_idle_counter, audio_idle, self); 1018 callout_setfunc(&sc->sc_idle_counter, audio_idle, self);
1019#endif 1019#endif
1020 1020
1021 if (!pmf_device_register(self, audio_suspend, audio_resume)) 1021 if (!pmf_device_register(self, audio_suspend, audio_resume))
1022 aprint_error_dev(self, "couldn't establish power handler\n"); 1022 aprint_error_dev(self, "couldn't establish power handler\n");
1023#ifdef AUDIO_PM_IDLE 1023#ifdef AUDIO_PM_IDLE
1024 if (!device_active_register(self, audio_activity)) 1024 if (!device_active_register(self, audio_activity))
1025 aprint_error_dev(self, "couldn't register activity handler\n"); 1025 aprint_error_dev(self, "couldn't register activity handler\n");
1026#endif 1026#endif
1027 1027
1028 if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_DOWN, 1028 if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_DOWN,
1029 audio_volume_down, true)) 1029 audio_volume_down, true))
1030 aprint_error_dev(self, "couldn't add volume down handler\n"); 1030 aprint_error_dev(self, "couldn't add volume down handler\n");
1031 if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_UP, 1031 if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_UP,
1032 audio_volume_up, true)) 1032 audio_volume_up, true))
1033 aprint_error_dev(self, "couldn't add volume up handler\n"); 1033 aprint_error_dev(self, "couldn't add volume up handler\n");
1034 if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_TOGGLE, 1034 if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_TOGGLE,
1035 audio_volume_toggle, true)) 1035 audio_volume_toggle, true))
1036 aprint_error_dev(self, "couldn't add volume toggle handler\n"); 1036 aprint_error_dev(self, "couldn't add volume toggle handler\n");
1037 1037
1038#ifdef AUDIO_PM_IDLE 1038#ifdef AUDIO_PM_IDLE
1039 callout_schedule(&sc->sc_idle_counter, audio_idle_timeout * hz); 1039 callout_schedule(&sc->sc_idle_counter, audio_idle_timeout * hz);
1040#endif 1040#endif
1041 1041
1042#if defined(AUDIO_DEBUG) 1042#if defined(AUDIO_DEBUG)
1043 audio_mlog_init(); 1043 audio_mlog_init();
1044#endif 1044#endif
1045 1045
1046 audiorescan(self, "audio", NULL); 1046 audiorescan(self, "audio", NULL);
1047 return; 1047 return;
1048 1048
1049bad: 1049bad:
1050 /* Clearing hw_if means that device is attached but disabled. */ 1050 /* Clearing hw_if means that device is attached but disabled. */
1051 sc->hw_if = NULL; 1051 sc->hw_if = NULL;
1052 aprint_error_dev(sc->sc_dev, "disabled\n"); 1052 aprint_error_dev(sc->sc_dev, "disabled\n");
1053 return; 1053 return;
1054} 1054}
1055 1055
1056/* 1056/*
1057 * Initialize hardware mixer. 1057 * Initialize hardware mixer.
1058 * This function is called from audioattach(). 1058 * This function is called from audioattach().
1059 */ 1059 */
1060static void 1060static void
1061mixer_init(struct audio_softc *sc) 1061mixer_init(struct audio_softc *sc)
1062{ 1062{
1063 mixer_devinfo_t mi; 1063 mixer_devinfo_t mi;
1064 int iclass, mclass, oclass, rclass; 1064 int iclass, mclass, oclass, rclass;
1065 int record_master_found, record_source_found; 1065 int record_master_found, record_source_found;
1066 1066
1067 iclass = mclass = oclass = rclass = -1; 1067 iclass = mclass = oclass = rclass = -1;
1068 sc->sc_inports.index = -1; 1068 sc->sc_inports.index = -1;
1069 sc->sc_inports.master = -1; 1069 sc->sc_inports.master = -1;
1070 sc->sc_inports.nports = 0; 1070 sc->sc_inports.nports = 0;
1071 sc->sc_inports.isenum = false; 1071 sc->sc_inports.isenum = false;
1072 sc->sc_inports.allports = 0; 1072 sc->sc_inports.allports = 0;
1073 sc->sc_inports.isdual = false; 1073 sc->sc_inports.isdual = false;
1074 sc->sc_inports.mixerout = -1; 1074 sc->sc_inports.mixerout = -1;
1075 sc->sc_inports.cur_port = -1; 1075 sc->sc_inports.cur_port = -1;
1076 sc->sc_outports.index = -1; 1076 sc->sc_outports.index = -1;
1077 sc->sc_outports.master = -1; 1077 sc->sc_outports.master = -1;
1078 sc->sc_outports.nports = 0; 1078 sc->sc_outports.nports = 0;
1079 sc->sc_outports.isenum = false; 1079 sc->sc_outports.isenum = false;
1080 sc->sc_outports.allports = 0; 1080 sc->sc_outports.allports = 0;
1081 sc->sc_outports.isdual = false; 1081 sc->sc_outports.isdual = false;
1082 sc->sc_outports.mixerout = -1; 1082 sc->sc_outports.mixerout = -1;
1083 sc->sc_outports.cur_port = -1; 1083 sc->sc_outports.cur_port = -1;
1084 sc->sc_monitor_port = -1; 1084 sc->sc_monitor_port = -1;
1085 /* 1085 /*
1086 * Read through the underlying driver's list, picking out the class 1086 * Read through the underlying driver's list, picking out the class
1087 * names from the mixer descriptions. We'll need them to decode the 1087 * names from the mixer descriptions. We'll need them to decode the
1088 * mixer descriptions on the next pass through the loop. 1088 * mixer descriptions on the next pass through the loop.
1089 */ 1089 */
1090 mutex_enter(sc->sc_lock); 1090 mutex_enter(sc->sc_lock);
1091 for(mi.index = 0; ; mi.index++) { 1091 for(mi.index = 0; ; mi.index++) {
1092 if (audio_query_devinfo(sc, &mi) != 0) 1092 if (audio_query_devinfo(sc, &mi) != 0)
1093 break; 1093 break;
1094 /* 1094 /*
1095 * The type of AUDIO_MIXER_CLASS merely introduces a class. 1095 * The type of AUDIO_MIXER_CLASS merely introduces a class.
1096 * All the other types describe an actual mixer. 1096 * All the other types describe an actual mixer.
1097 */ 1097 */
1098 if (mi.type == AUDIO_MIXER_CLASS) { 1098 if (mi.type == AUDIO_MIXER_CLASS) {
1099 if (strcmp(mi.label.name, AudioCinputs) == 0) 1099 if (strcmp(mi.label.name, AudioCinputs) == 0)
1100 iclass = mi.mixer_class; 1100 iclass = mi.mixer_class;
1101 if (strcmp(mi.label.name, AudioCmonitor) == 0) 1101 if (strcmp(mi.label.name, AudioCmonitor) == 0)
1102 mclass = mi.mixer_class; 1102 mclass = mi.mixer_class;
1103 if (strcmp(mi.label.name, AudioCoutputs) == 0) 1103 if (strcmp(mi.label.name, AudioCoutputs) == 0)
1104 oclass = mi.mixer_class; 1104 oclass = mi.mixer_class;
1105 if (strcmp(mi.label.name, AudioCrecord) == 0) 1105 if (strcmp(mi.label.name, AudioCrecord) == 0)
1106 rclass = mi.mixer_class; 1106 rclass = mi.mixer_class;
1107 } 1107 }
1108 } 1108 }
1109 mutex_exit(sc->sc_lock); 1109 mutex_exit(sc->sc_lock);
1110 1110
1111 /* Allocate save area. Ensure non-zero allocation. */ 1111 /* Allocate save area. Ensure non-zero allocation. */
1112 sc->sc_nmixer_states = mi.index; 1112 sc->sc_nmixer_states = mi.index;
1113 sc->sc_mixer_state = kmem_zalloc(sizeof(mixer_ctrl_t) * 1113 sc->sc_mixer_state = kmem_zalloc(sizeof(mixer_ctrl_t) *
1114 (sc->sc_nmixer_states + 1), KM_SLEEP); 1114 (sc->sc_nmixer_states + 1), KM_SLEEP);
1115 1115
1116 /* 1116 /*
1117 * This is where we assign each control in the "audio" model, to the 1117 * This is where we assign each control in the "audio" model, to the
1118 * underlying "mixer" control. We walk through the whole list once, 1118 * underlying "mixer" control. We walk through the whole list once,
1119 * assigning likely candidates as we come across them. 1119 * assigning likely candidates as we come across them.
1120 */ 1120 */
1121 record_master_found = 0; 1121 record_master_found = 0;
1122 record_source_found = 0; 1122 record_source_found = 0;
1123 mutex_enter(sc->sc_lock); 1123 mutex_enter(sc->sc_lock);
1124 for(mi.index = 0; ; mi.index++) { 1124 for(mi.index = 0; ; mi.index++) {
1125 if (audio_query_devinfo(sc, &mi) != 0) 1125 if (audio_query_devinfo(sc, &mi) != 0)
1126 break; 1126 break;
1127 KASSERT(mi.index < sc->sc_nmixer_states); 1127 KASSERT(mi.index < sc->sc_nmixer_states);
1128 if (mi.type == AUDIO_MIXER_CLASS) 1128 if (mi.type == AUDIO_MIXER_CLASS)
1129 continue; 1129 continue;
1130 if (mi.mixer_class == iclass) { 1130 if (mi.mixer_class == iclass) {
1131 /* 1131 /*
1132 * AudioCinputs is only a fallback, when we don't 1132 * AudioCinputs is only a fallback, when we don't
1133 * find what we're looking for in AudioCrecord, so 1133 * find what we're looking for in AudioCrecord, so
1134 * check the flags before accepting one of these. 1134 * check the flags before accepting one of these.
1135 */ 1135 */
1136 if (strcmp(mi.label.name, AudioNmaster) == 0 1136 if (strcmp(mi.label.name, AudioNmaster) == 0
1137 && record_master_found == 0) 1137 && record_master_found == 0)
1138 sc->sc_inports.master = mi.index; 1138 sc->sc_inports.master = mi.index;
1139 if (strcmp(mi.label.name, AudioNsource) == 0 1139 if (strcmp(mi.label.name, AudioNsource) == 0
1140 && record_source_found == 0) { 1140 && record_source_found == 0) {
1141 if (mi.type == AUDIO_MIXER_ENUM) { 1141 if (mi.type == AUDIO_MIXER_ENUM) {
1142 int i; 1142 int i;
1143 for(i = 0; i < mi.un.e.num_mem; i++) 1143 for(i = 0; i < mi.un.e.num_mem; i++)
1144 if (strcmp(mi.un.e.member[i].label.name, 1144 if (strcmp(mi.un.e.member[i].label.name,
@@ -4734,2102 +4734,2126 @@ audio_mixer_init(struct audio_softc *sc, @@ -4734,2102 +4734,2126 @@ audio_mixer_init(struct audio_softc *sc,
4734 __func__, len); 4734 __func__, len);
4735 error = ENOMEM; 4735 error = ENOMEM;
4736 goto abort; 4736 goto abort;
4737 } 4737 }
4738 } else { 4738 } else {
4739 /* No mixing buffer for recording */ 4739 /* No mixing buffer for recording */
4740 } 4740 }
4741 4741
4742 if (reg->codec) { 4742 if (reg->codec) {
4743 mixer->codec = reg->codec; 4743 mixer->codec = reg->codec;
4744 mixer->codecarg.context = reg->context; 4744 mixer->codecarg.context = reg->context;
4745 if (mode == AUMODE_PLAY) { 4745 if (mode == AUMODE_PLAY) {
4746 mixer->codecarg.srcfmt = &mixer->track_fmt; 4746 mixer->codecarg.srcfmt = &mixer->track_fmt;
4747 mixer->codecarg.dstfmt = &mixer->hwbuf.fmt; 4747 mixer->codecarg.dstfmt = &mixer->hwbuf.fmt;
4748 } else { 4748 } else {
4749 mixer->codecarg.srcfmt = &mixer->hwbuf.fmt; 4749 mixer->codecarg.srcfmt = &mixer->hwbuf.fmt;
4750 mixer->codecarg.dstfmt = &mixer->track_fmt; 4750 mixer->codecarg.dstfmt = &mixer->track_fmt;
4751 } 4751 }
4752 mixer->codecbuf.fmt = mixer->track_fmt; 4752 mixer->codecbuf.fmt = mixer->track_fmt;
4753 mixer->codecbuf.capacity = mixer->frames_per_block; 4753 mixer->codecbuf.capacity = mixer->frames_per_block;
4754 len = auring_bytelen(&mixer->codecbuf); 4754 len = auring_bytelen(&mixer->codecbuf);
4755 mixer->codecbuf.mem = audio_realloc(mixer->codecbuf.mem, len); 4755 mixer->codecbuf.mem = audio_realloc(mixer->codecbuf.mem, len);
4756 if (mixer->codecbuf.mem == NULL) { 4756 if (mixer->codecbuf.mem == NULL) {
4757 device_printf(sc->sc_dev, 4757 device_printf(sc->sc_dev,
4758 "%s: malloc codecbuf(%d) failed\n", 4758 "%s: malloc codecbuf(%d) failed\n",
4759 __func__, len); 4759 __func__, len);
4760 error = ENOMEM; 4760 error = ENOMEM;
4761 goto abort; 4761 goto abort;
4762 } 4762 }
4763 } 4763 }
4764 4764
4765 /* Succeeded so display it. */ 4765 /* Succeeded so display it. */
4766 codecbuf[0] = '\0'; 4766 codecbuf[0] = '\0';
4767 if (mixer->codec || mixer->swap_endian) { 4767 if (mixer->codec || mixer->swap_endian) {
4768 snprintf(codecbuf, sizeof(codecbuf), " %s %s:%d", 4768 snprintf(codecbuf, sizeof(codecbuf), " %s %s:%d",
4769 (mode == AUMODE_PLAY) ? "->" : "<-", 4769 (mode == AUMODE_PLAY) ? "->" : "<-",
4770 audio_encoding_name(mixer->hwbuf.fmt.encoding), 4770 audio_encoding_name(mixer->hwbuf.fmt.encoding),
4771 mixer->hwbuf.fmt.precision); 4771 mixer->hwbuf.fmt.precision);
4772 } 4772 }
4773 blkms = mixer->blktime_n * 1000 / mixer->blktime_d; 4773 blkms = mixer->blktime_n * 1000 / mixer->blktime_d;
4774 aprint_normal_dev(sc->sc_dev, "%s:%d%s %dch %dHz, blk %dms for %s\n", 4774 aprint_normal_dev(sc->sc_dev, "%s:%d%s %dch %dHz, blk %dms for %s\n",
4775 audio_encoding_name(mixer->track_fmt.encoding), 4775 audio_encoding_name(mixer->track_fmt.encoding),
4776 mixer->track_fmt.precision, 4776 mixer->track_fmt.precision,
4777 codecbuf, 4777 codecbuf,
4778 mixer->track_fmt.channels, 4778 mixer->track_fmt.channels,
4779 mixer->track_fmt.sample_rate, 4779 mixer->track_fmt.sample_rate,
4780 blkms, 4780 blkms,
4781 (mode == AUMODE_PLAY) ? "playback" : "recording"); 4781 (mode == AUMODE_PLAY) ? "playback" : "recording");
4782 4782
4783 return 0; 4783 return 0;
4784 4784
4785abort: 4785abort:
4786 audio_mixer_destroy(sc, mixer); 4786 audio_mixer_destroy(sc, mixer);
4787 return error; 4787 return error;
4788} 4788}
4789 4789
4790/* 4790/*
4791 * Releases all resources of 'mixer'. 4791 * Releases all resources of 'mixer'.
4792 * Note that it does not release the memory area of 'mixer' itself. 4792 * Note that it does not release the memory area of 'mixer' itself.
4793 * Must be called with sc_lock held. 4793 * Must be called with sc_lock held.
4794 */ 4794 */
4795static void 4795static void
4796audio_mixer_destroy(struct audio_softc *sc, audio_trackmixer_t *mixer) 4796audio_mixer_destroy(struct audio_softc *sc, audio_trackmixer_t *mixer)
4797{ 4797{
4798 int bufsize; 4798 int bufsize;
4799 4799
4800 KASSERT(mutex_owned(sc->sc_lock)); 4800 KASSERT(mutex_owned(sc->sc_lock));
4801 4801
4802 bufsize = frametobyte(&mixer->hwbuf.fmt, mixer->hwbuf.capacity); 4802 bufsize = frametobyte(&mixer->hwbuf.fmt, mixer->hwbuf.capacity);
4803 4803
4804 if (mixer->hwbuf.mem != NULL) { 4804 if (mixer->hwbuf.mem != NULL) {
4805 if (sc->hw_if->freem) { 4805 if (sc->hw_if->freem) {
4806 sc->hw_if->freem(sc->hw_hdl, mixer->hwbuf.mem, bufsize); 4806 sc->hw_if->freem(sc->hw_hdl, mixer->hwbuf.mem, bufsize);
4807 } else { 4807 } else {
4808 kmem_free(mixer->hwbuf.mem, bufsize); 4808 kmem_free(mixer->hwbuf.mem, bufsize);
4809 } 4809 }
4810 mixer->hwbuf.mem = NULL; 4810 mixer->hwbuf.mem = NULL;
4811 } 4811 }
4812 4812
4813 audio_free(mixer->codecbuf.mem); 4813 audio_free(mixer->codecbuf.mem);
4814 audio_free(mixer->mixsample); 4814 audio_free(mixer->mixsample);
4815 4815
4816 cv_destroy(&mixer->outcv); 4816 cv_destroy(&mixer->outcv);
4817 4817
4818 if (mixer->sih) { 4818 if (mixer->sih) {
4819 softint_disestablish(mixer->sih); 4819 softint_disestablish(mixer->sih);
4820 mixer->sih = NULL; 4820 mixer->sih = NULL;
4821 } 4821 }
4822} 4822}
4823 4823
4824/* 4824/*
4825 * Starts playback mixer. 4825 * Starts playback mixer.
4826 * Must be called only if sc_pbusy is false. 4826 * Must be called only if sc_pbusy is false.
4827 * Must be called with sc_lock held. 4827 * Must be called with sc_lock held.
4828 * Must not be called from the interrupt context. 4828 * Must not be called from the interrupt context.
4829 */ 4829 */
4830static void 4830static void
4831audio_pmixer_start(struct audio_softc *sc, bool force) 4831audio_pmixer_start(struct audio_softc *sc, bool force)
4832{ 4832{
4833 audio_trackmixer_t *mixer; 4833 audio_trackmixer_t *mixer;
4834 int minimum; 4834 int minimum;
4835 4835
4836 KASSERT(mutex_owned(sc->sc_lock)); 4836 KASSERT(mutex_owned(sc->sc_lock));
4837 KASSERT(sc->sc_pbusy == false); 4837 KASSERT(sc->sc_pbusy == false);
4838 4838
4839 mutex_enter(sc->sc_intr_lock); 4839 mutex_enter(sc->sc_intr_lock);
4840 4840
4841 mixer = sc->sc_pmixer; 4841 mixer = sc->sc_pmixer;
4842 TRACE(2, "%smixseq=%d hwseq=%d hwbuf=%d/%d/%d%s", 4842 TRACE(2, "%smixseq=%d hwseq=%d hwbuf=%d/%d/%d%s",
4843 (audiodebug >= 3) ? "begin " : "", 4843 (audiodebug >= 3) ? "begin " : "",
4844 (int)mixer->mixseq, (int)mixer->hwseq, 4844 (int)mixer->mixseq, (int)mixer->hwseq,
4845 mixer->hwbuf.head, mixer->hwbuf.used, mixer->hwbuf.capacity, 4845 mixer->hwbuf.head, mixer->hwbuf.used, mixer->hwbuf.capacity,
4846 force ? " force" : ""); 4846 force ? " force" : "");
4847 4847
4848 /* Need two blocks to start normally. */ 4848 /* Need two blocks to start normally. */
4849 minimum = (force) ? 1 : 2; 4849 minimum = (force) ? 1 : 2;
4850 while (mixer->hwbuf.used < mixer->frames_per_block * minimum) { 4850 while (mixer->hwbuf.used < mixer->frames_per_block * minimum) {
4851 audio_pmixer_process(sc); 4851 audio_pmixer_process(sc);
4852 } 4852 }
4853 4853
4854 /* Start output */ 4854 /* Start output */
4855 audio_pmixer_output(sc); 4855 audio_pmixer_output(sc);
4856 sc->sc_pbusy = true; 4856 sc->sc_pbusy = true;
4857 4857
4858 TRACE(3, "end mixseq=%d hwseq=%d hwbuf=%d/%d/%d", 4858 TRACE(3, "end mixseq=%d hwseq=%d hwbuf=%d/%d/%d",
4859 (int)mixer->mixseq, (int)mixer->hwseq, 4859 (int)mixer->mixseq, (int)mixer->hwseq,
4860 mixer->hwbuf.head, mixer->hwbuf.used, mixer->hwbuf.capacity); 4860 mixer->hwbuf.head, mixer->hwbuf.used, mixer->hwbuf.capacity);
4861 4861
4862 mutex_exit(sc->sc_intr_lock); 4862 mutex_exit(sc->sc_intr_lock);
4863} 4863}
4864 4864
4865/* 4865/*
4866 * When playing back with MD filter: 4866 * When playing back with MD filter:
4867 * 4867 *
4868 * track track ... 4868 * track track ...
4869 * v v 4869 * v v
4870 * + mix (with aint2_t) 4870 * + mix (with aint2_t)
4871 * | master volume (with aint2_t) 4871 * | master volume (with aint2_t)
4872 * v 4872 * v
4873 * mixsample [::::] wide-int 1 block (ring) buffer 4873 * mixsample [::::] wide-int 1 block (ring) buffer
4874 * | 4874 * |
4875 * | convert aint2_t -> aint_t 4875 * | convert aint2_t -> aint_t
4876 * v 4876 * v
4877 * codecbuf [....] 1 block (ring) buffer 4877 * codecbuf [....] 1 block (ring) buffer
4878 * | 4878 * |
4879 * | convert to hw format 4879 * | convert to hw format
4880 * v 4880 * v
4881 * hwbuf [............] NBLKHW blocks ring buffer 4881 * hwbuf [............] NBLKHW blocks ring buffer
4882 * 4882 *
4883 * When playing back without MD filter: 4883 * When playing back without MD filter:
4884 * 4884 *
4885 * mixsample [::::] wide-int 1 block (ring) buffer 4885 * mixsample [::::] wide-int 1 block (ring) buffer
4886 * | 4886 * |
4887 * | convert aint2_t -> aint_t 4887 * | convert aint2_t -> aint_t
4888 * | (with byte swap if necessary) 4888 * | (with byte swap if necessary)
4889 * v 4889 * v
4890 * hwbuf [............] NBLKHW blocks ring buffer 4890 * hwbuf [............] NBLKHW blocks ring buffer
4891 * 4891 *
4892 * mixsample: slinear_NE, wide internal precision, HW ch, HW freq. 4892 * mixsample: slinear_NE, wide internal precision, HW ch, HW freq.
4893 * codecbuf: slinear_NE, internal precision, HW ch, HW freq. 4893 * codecbuf: slinear_NE, internal precision, HW ch, HW freq.
4894 * hwbuf: HW encoding, HW precision, HW ch, HW freq. 4894 * hwbuf: HW encoding, HW precision, HW ch, HW freq.
4895 */ 4895 */
4896 4896
4897/* 4897/*
4898 * Performs track mixing and converts it to hwbuf. 4898 * Performs track mixing and converts it to hwbuf.
4899 * Note that this function doesn't transfer hwbuf to hardware. 4899 * Note that this function doesn't transfer hwbuf to hardware.
4900 * Must be called with sc_intr_lock held. 4900 * Must be called with sc_intr_lock held.
4901 */ 4901 */
4902static void 4902static void
4903audio_pmixer_process(struct audio_softc *sc) 4903audio_pmixer_process(struct audio_softc *sc)
4904{ 4904{
4905 audio_trackmixer_t *mixer; 4905 audio_trackmixer_t *mixer;
4906 audio_file_t *f; 4906 audio_file_t *f;
4907 int frame_count; 4907 int frame_count;
4908 int sample_count; 4908 int sample_count;
4909 int mixed; 4909 int mixed;
4910 int i; 4910 int i;
4911 aint2_t *m; 4911 aint2_t *m;
4912 aint_t *h; 4912 aint_t *h;
4913 4913
4914 mixer = sc->sc_pmixer; 4914 mixer = sc->sc_pmixer;
4915 4915
4916 frame_count = mixer->frames_per_block; 4916 frame_count = mixer->frames_per_block;
4917 KASSERT(auring_get_contig_free(&mixer->hwbuf) >= frame_count); 4917 KASSERT(auring_get_contig_free(&mixer->hwbuf) >= frame_count);
4918 sample_count = frame_count * mixer->mixfmt.channels; 4918 sample_count = frame_count * mixer->mixfmt.channels;
4919 4919
4920 mixer->mixseq++; 4920 mixer->mixseq++;
4921 4921
4922 /* Mix all tracks */ 4922 /* Mix all tracks */
4923 mixed = 0; 4923 mixed = 0;
4924 SLIST_FOREACH(f, &sc->sc_files, entry) { 4924 SLIST_FOREACH(f, &sc->sc_files, entry) {
4925 audio_track_t *track = f->ptrack; 4925 audio_track_t *track = f->ptrack;
4926 4926
4927 if (track == NULL) 4927 if (track == NULL)
4928 continue; 4928 continue;
4929 4929
4930 if (track->is_pause) { 4930 if (track->is_pause) {
4931 TRACET(4, track, "skip; paused"); 4931 TRACET(4, track, "skip; paused");
4932 continue; 4932 continue;
4933 } 4933 }
4934 4934
4935 /* Skip if the track is used by process context. */ 4935 /* Skip if the track is used by process context. */
4936 if (audio_track_lock_tryenter(track) == false) { 4936 if (audio_track_lock_tryenter(track) == false) {
4937 TRACET(4, track, "skip; in use"); 4937 TRACET(4, track, "skip; in use");
4938 continue; 4938 continue;
4939 } 4939 }
4940 4940
4941 /* Emulate mmap'ped track */ 4941 /* Emulate mmap'ped track */
4942 if (track->mmapped) { 4942 if (track->mmapped) {
4943 auring_push(&track->usrbuf, track->usrbuf_blksize); 4943 auring_push(&track->usrbuf, track->usrbuf_blksize);
4944 TRACET(4, track, "mmap; usr=%d/%d/C%d", 4944 TRACET(4, track, "mmap; usr=%d/%d/C%d",
4945 track->usrbuf.head, 4945 track->usrbuf.head,
4946 track->usrbuf.used, 4946 track->usrbuf.used,
4947 track->usrbuf.capacity); 4947 track->usrbuf.capacity);
4948 } 4948 }
4949 4949
4950 if (track->outbuf.used < mixer->frames_per_block && 4950 if (track->outbuf.used < mixer->frames_per_block &&
4951 track->usrbuf.used > 0) { 4951 track->usrbuf.used > 0) {
4952 TRACET(4, track, "process"); 4952 TRACET(4, track, "process");
4953 audio_track_play(track); 4953 audio_track_play(track);
4954 } 4954 }
4955 4955
4956 if (track->outbuf.used > 0) { 4956 if (track->outbuf.used > 0) {
4957 mixed = audio_pmixer_mix_track(mixer, track, mixed); 4957 mixed = audio_pmixer_mix_track(mixer, track, mixed);
4958 } else { 4958 } else {
4959 TRACET(4, track, "skip; empty"); 4959 TRACET(4, track, "skip; empty");
4960 } 4960 }
4961 4961
4962 audio_track_lock_exit(track); 4962 audio_track_lock_exit(track);
4963 } 4963 }
4964 4964
4965 if (mixed == 0) { 4965 if (mixed == 0) {
4966 /* Silence */ 4966 /* Silence */
4967 memset(mixer->mixsample, 0, 4967 memset(mixer->mixsample, 0,
4968 frametobyte(&mixer->mixfmt, frame_count)); 4968 frametobyte(&mixer->mixfmt, frame_count));
4969 } else { 4969 } else {
4970 if (mixed > 1) { 4970 if (mixed > 1) {
4971 /* If there are multiple tracks, do auto gain control */ 4971 /* If there are multiple tracks, do auto gain control */
4972 audio_pmixer_agc(mixer, sample_count); 4972 audio_pmixer_agc(mixer, sample_count);
4973 } 4973 }
4974 4974
4975 /* Apply master volume */ 4975 /* Apply master volume */
4976 if (mixer->volume < 256) { 4976 if (mixer->volume < 256) {
4977 m = mixer->mixsample; 4977 m = mixer->mixsample;
4978 for (i = 0; i < sample_count; i++) { 4978 for (i = 0; i < sample_count; i++) {
4979 *m = AUDIO_SCALEDOWN(*m * mixer->volume, 8); 4979 *m = AUDIO_SCALEDOWN(*m * mixer->volume, 8);
4980 m++; 4980 m++;
4981 } 4981 }
4982 4982
4983 /* 4983 /*
4984 * Recover the volume gradually at the pace of 4984 * Recover the volume gradually at the pace of
4985 * several times per second. If it's too fast, you 4985 * several times per second. If it's too fast, you
4986 * can recognize that the volume changes up and down 4986 * can recognize that the volume changes up and down
4987 * quickly and it's not so comfortable. 4987 * quickly and it's not so comfortable.
4988 */ 4988 */
4989 mixer->voltimer += mixer->blktime_n; 4989 mixer->voltimer += mixer->blktime_n;
4990 if (mixer->voltimer * 4 >= mixer->blktime_d) { 4990 if (mixer->voltimer * 4 >= mixer->blktime_d) {
4991 mixer->volume++; 4991 mixer->volume++;
4992 mixer->voltimer = 0; 4992 mixer->voltimer = 0;
4993#if defined(AUDIO_DEBUG_AGC) 4993#if defined(AUDIO_DEBUG_AGC)
4994 TRACE(1, "volume recover: %d", mixer->volume); 4994 TRACE(1, "volume recover: %d", mixer->volume);
4995#endif 4995#endif
4996 } 4996 }
4997 } 4997 }
4998 } 4998 }
4999 4999
5000 /* 5000 /*
5001 * The rest is the hardware part. 5001 * The rest is the hardware part.
5002 */ 5002 */
5003 5003
5004 if (mixer->codec) { 5004 if (mixer->codec) {
5005 h = auring_tailptr_aint(&mixer->codecbuf); 5005 h = auring_tailptr_aint(&mixer->codecbuf);
5006 } else { 5006 } else {
5007 h = auring_tailptr_aint(&mixer->hwbuf); 5007 h = auring_tailptr_aint(&mixer->hwbuf);
5008 } 5008 }
5009 5009
5010 m = mixer->mixsample; 5010 m = mixer->mixsample;
5011 if (mixer->swap_endian) { 5011 if (mixer->swap_endian) {
5012 for (i = 0; i < sample_count; i++) { 5012 for (i = 0; i < sample_count; i++) {
5013 *h++ = bswap16(*m++); 5013 *h++ = bswap16(*m++);
5014 } 5014 }
5015 } else { 5015 } else {
5016 for (i = 0; i < sample_count; i++) { 5016 for (i = 0; i < sample_count; i++) {
5017 *h++ = *m++; 5017 *h++ = *m++;
5018 } 5018 }
5019 } 5019 }
5020 5020
5021 /* Hardware driver's codec */ 5021 /* Hardware driver's codec */
5022 if (mixer->codec) { 5022 if (mixer->codec) {
5023 auring_push(&mixer->codecbuf, frame_count); 5023 auring_push(&mixer->codecbuf, frame_count);
5024 mixer->codecarg.src = auring_headptr(&mixer->codecbuf); 5024 mixer->codecarg.src = auring_headptr(&mixer->codecbuf);
5025 mixer->codecarg.dst = auring_tailptr(&mixer->hwbuf); 5025 mixer->codecarg.dst = auring_tailptr(&mixer->hwbuf);
5026 mixer->codecarg.count = frame_count; 5026 mixer->codecarg.count = frame_count;
5027 mixer->codec(&mixer->codecarg); 5027 mixer->codec(&mixer->codecarg);
5028 auring_take(&mixer->codecbuf, mixer->codecarg.count); 5028 auring_take(&mixer->codecbuf, mixer->codecarg.count);
5029 } 5029 }
5030 5030
5031 auring_push(&mixer->hwbuf, frame_count); 5031 auring_push(&mixer->hwbuf, frame_count);
5032 5032
5033 TRACE(4, "done mixseq=%d hwbuf=%d/%d/%d%s", 5033 TRACE(4, "done mixseq=%d hwbuf=%d/%d/%d%s",
5034 (int)mixer->mixseq, 5034 (int)mixer->mixseq,
5035 mixer->hwbuf.head, mixer->hwbuf.used, mixer->hwbuf.capacity, 5035 mixer->hwbuf.head, mixer->hwbuf.used, mixer->hwbuf.capacity,
5036 (mixed == 0) ? " silent" : ""); 5036 (mixed == 0) ? " silent" : "");
5037} 5037}
5038 5038
5039/* 5039/*
5040 * Do auto gain control. 5040 * Do auto gain control.
5041 * Must be called sc_intr_lock held. 5041 * Must be called sc_intr_lock held.
5042 */ 5042 */
5043static void 5043static void
5044audio_pmixer_agc(audio_trackmixer_t *mixer, int sample_count) 5044audio_pmixer_agc(audio_trackmixer_t *mixer, int sample_count)
5045{ 5045{
5046 struct audio_softc *sc __unused; 5046 struct audio_softc *sc __unused;
5047 aint2_t val; 5047 aint2_t val;
5048 aint2_t maxval; 5048 aint2_t maxval;
5049 aint2_t minval; 5049 aint2_t minval;
5050 aint2_t over_plus; 5050 aint2_t over_plus;
5051 aint2_t over_minus; 5051 aint2_t over_minus;
5052 aint2_t *m; 5052 aint2_t *m;
5053 int newvol; 5053 int newvol;
5054 int i; 5054 int i;
5055 5055
5056 sc = mixer->sc; 5056 sc = mixer->sc;
5057 5057
5058 /* Overflow detection */ 5058 /* Overflow detection */
5059 maxval = AINT_T_MAX; 5059 maxval = AINT_T_MAX;
5060 minval = AINT_T_MIN; 5060 minval = AINT_T_MIN;
5061 m = mixer->mixsample; 5061 m = mixer->mixsample;
5062 for (i = 0; i < sample_count; i++) { 5062 for (i = 0; i < sample_count; i++) {
5063 val = *m++; 5063 val = *m++;
5064 if (val > maxval) 5064 if (val > maxval)
5065 maxval = val; 5065 maxval = val;
5066 else if (val < minval) 5066 else if (val < minval)
5067 minval = val; 5067 minval = val;
5068 } 5068 }
5069 5069
5070 /* Absolute value of overflowed amount */ 5070 /* Absolute value of overflowed amount */
5071 over_plus = maxval - AINT_T_MAX; 5071 over_plus = maxval - AINT_T_MAX;
5072 over_minus = AINT_T_MIN - minval; 5072 over_minus = AINT_T_MIN - minval;
5073 5073
5074 if (over_plus > 0 || over_minus > 0) { 5074 if (over_plus > 0 || over_minus > 0) {
5075 if (over_plus > over_minus) { 5075 if (over_plus > over_minus) {
5076 newvol = (int)((aint2_t)AINT_T_MAX * 256 / maxval); 5076 newvol = (int)((aint2_t)AINT_T_MAX * 256 / maxval);
5077 } else { 5077 } else {
5078 newvol = (int)((aint2_t)AINT_T_MIN * 256 / minval); 5078 newvol = (int)((aint2_t)AINT_T_MIN * 256 / minval);
5079 } 5079 }
5080 5080
5081 /* 5081 /*
5082 * Change the volume only if new one is smaller. 5082 * Change the volume only if new one is smaller.
5083 * Reset the timer even if the volume isn't changed. 5083 * Reset the timer even if the volume isn't changed.
5084 */ 5084 */
5085 if (newvol <= mixer->volume) { 5085 if (newvol <= mixer->volume) {
5086 mixer->volume = newvol; 5086 mixer->volume = newvol;
5087 mixer->voltimer = 0; 5087 mixer->voltimer = 0;
5088#if defined(AUDIO_DEBUG_AGC) 5088#if defined(AUDIO_DEBUG_AGC)
5089 TRACE(1, "auto volume adjust: %d", mixer->volume); 5089 TRACE(1, "auto volume adjust: %d", mixer->volume);
5090#endif 5090#endif
5091 } 5091 }
5092 } 5092 }
5093} 5093}
5094 5094
5095/* 5095/*
5096 * Mix one track. 5096 * Mix one track.
5097 * 'mixed' specifies the number of tracks mixed so far. 5097 * 'mixed' specifies the number of tracks mixed so far.
5098 * It returns the number of tracks mixed. In other words, it returns 5098 * It returns the number of tracks mixed. In other words, it returns
5099 * mixed + 1 if this track is mixed. 5099 * mixed + 1 if this track is mixed.
5100 */ 5100 */
5101static int 5101static int
5102audio_pmixer_mix_track(audio_trackmixer_t *mixer, audio_track_t *track, 5102audio_pmixer_mix_track(audio_trackmixer_t *mixer, audio_track_t *track,
5103 int mixed) 5103 int mixed)
5104{ 5104{
5105 int count; 5105 int count;
5106 int sample_count; 5106 int sample_count;
5107 int remain; 5107 int remain;
5108 int i; 5108 int i;
5109 const aint_t *s; 5109 const aint_t *s;
5110 aint2_t *d; 5110 aint2_t *d;
5111 5111
5112 /* XXX TODO: Is this necessary for now? */ 5112 /* XXX TODO: Is this necessary for now? */
5113 if (mixer->mixseq < track->seq) 5113 if (mixer->mixseq < track->seq)
5114 return mixed; 5114 return mixed;
5115 5115
5116 count = auring_get_contig_used(&track->outbuf); 5116 count = auring_get_contig_used(&track->outbuf);
5117 count = uimin(count, mixer->frames_per_block); 5117 count = uimin(count, mixer->frames_per_block);
5118 5118
5119 s = auring_headptr_aint(&track->outbuf); 5119 s = auring_headptr_aint(&track->outbuf);
5120 d = mixer->mixsample; 5120 d = mixer->mixsample;
5121 5121
5122 /* 5122 /*
5123 * Apply track volume with double-sized integer and perform 5123 * Apply track volume with double-sized integer and perform
5124 * additive synthesis. 5124 * additive synthesis.
5125 * 5125 *
5126 * XXX If you limit the track volume to 1.0 or less (<= 256), 5126 * XXX If you limit the track volume to 1.0 or less (<= 256),
5127 * it would be better to do this in the track conversion stage 5127 * it would be better to do this in the track conversion stage
5128 * rather than here. However, if you accept the volume to 5128 * rather than here. However, if you accept the volume to
5129 * be greater than 1.0 (> 256), it's better to do it here. 5129 * be greater than 1.0 (> 256), it's better to do it here.
5130 * Because the operation here is done by double-sized integer. 5130 * Because the operation here is done by double-sized integer.
5131 */ 5131 */
5132 sample_count = count * mixer->mixfmt.channels; 5132 sample_count = count * mixer->mixfmt.channels;
5133 if (mixed == 0) { 5133 if (mixed == 0) {
5134 /* If this is the first track, assignment can be used. */ 5134 /* If this is the first track, assignment can be used. */
5135#if defined(AUDIO_SUPPORT_TRACK_VOLUME) 5135#if defined(AUDIO_SUPPORT_TRACK_VOLUME)
5136 if (track->volume != 256) { 5136 if (track->volume != 256) {
5137 for (i = 0; i < sample_count; i++) { 5137 for (i = 0; i < sample_count; i++) {
5138 aint2_t v; 5138 aint2_t v;
5139 v = *s++; 5139 v = *s++;
5140 *d++ = AUDIO_SCALEDOWN(v * track->volume, 8) 5140 *d++ = AUDIO_SCALEDOWN(v * track->volume, 8)
5141 } 5141 }
5142 } else 5142 } else
5143#endif 5143#endif
5144 { 5144 {
5145 for (i = 0; i < sample_count; i++) { 5145 for (i = 0; i < sample_count; i++) {
5146 *d++ = ((aint2_t)*s++); 5146 *d++ = ((aint2_t)*s++);
5147 } 5147 }
5148 } 5148 }
5149 /* Fill silence if the first track is not filled. */ 5149 /* Fill silence if the first track is not filled. */
5150 for (; i < mixer->frames_per_block * mixer->mixfmt.channels; i++) 5150 for (; i < mixer->frames_per_block * mixer->mixfmt.channels; i++)
5151 *d++ = 0; 5151 *d++ = 0;
5152 } else { 5152 } else {
5153 /* If this is the second or later, add it. */ 5153 /* If this is the second or later, add it. */
5154#if defined(AUDIO_SUPPORT_TRACK_VOLUME) 5154#if defined(AUDIO_SUPPORT_TRACK_VOLUME)
5155 if (track->volume != 256) { 5155 if (track->volume != 256) {
5156 for (i = 0; i < sample_count; i++) { 5156 for (i = 0; i < sample_count; i++) {
5157 aint2_t v; 5157 aint2_t v;
5158 v = *s++; 5158 v = *s++;
5159 *d++ += AUDIO_SCALEDOWN(v * track->volume, 8); 5159 *d++ += AUDIO_SCALEDOWN(v * track->volume, 8);
5160 } 5160 }
5161 } else 5161 } else
5162#endif 5162#endif
5163 { 5163 {
5164 for (i = 0; i < sample_count; i++) { 5164 for (i = 0; i < sample_count; i++) {
5165 *d++ += ((aint2_t)*s++); 5165 *d++ += ((aint2_t)*s++);
5166 } 5166 }
5167 } 5167 }
5168 } 5168 }
5169 5169
5170 auring_take(&track->outbuf, count); 5170 auring_take(&track->outbuf, count);
5171 /* 5171 /*
5172 * The counters have to align block even if outbuf is less than 5172 * The counters have to align block even if outbuf is less than
5173 * one block. XXX Is this still necessary? 5173 * one block. XXX Is this still necessary?
5174 */ 5174 */
5175 remain = mixer->frames_per_block - count; 5175 remain = mixer->frames_per_block - count;
5176 if (__predict_false(remain != 0)) { 5176 if (__predict_false(remain != 0)) {
5177 auring_push(&track->outbuf, remain); 5177 auring_push(&track->outbuf, remain);
5178 auring_take(&track->outbuf, remain); 5178 auring_take(&track->outbuf, remain);
5179 } 5179 }
5180 5180
5181 /* 5181 /*
5182 * Update track sequence. 5182 * Update track sequence.
5183 * mixseq has previous value yet at this point. 5183 * mixseq has previous value yet at this point.
5184 */ 5184 */
5185 track->seq = mixer->mixseq + 1; 5185 track->seq = mixer->mixseq + 1;
5186 5186
5187 return mixed + 1; 5187 return mixed + 1;
5188} 5188}
5189 5189
5190/* 5190/*
5191 * Output one block from hwbuf to HW. 5191 * Output one block from hwbuf to HW.
5192 * Must be called with sc_intr_lock held. 5192 * Must be called with sc_intr_lock held.
5193 */ 5193 */
5194static void 5194static void
5195audio_pmixer_output(struct audio_softc *sc) 5195audio_pmixer_output(struct audio_softc *sc)
5196{ 5196{
5197 audio_trackmixer_t *mixer; 5197 audio_trackmixer_t *mixer;
5198 audio_params_t params; 5198 audio_params_t params;
5199 void *start; 5199 void *start;
5200 void *end; 5200 void *end;
5201 int blksize; 5201 int blksize;
5202 int error; 5202 int error;
5203 5203
5204 mixer = sc->sc_pmixer; 5204 mixer = sc->sc_pmixer;
5205 TRACE(4, "pbusy=%d hwbuf=%d/%d/%d", 5205 TRACE(4, "pbusy=%d hwbuf=%d/%d/%d",
5206 sc->sc_pbusy, 5206 sc->sc_pbusy,
5207 mixer->hwbuf.head, mixer->hwbuf.used, mixer->hwbuf.capacity); 5207 mixer->hwbuf.head, mixer->hwbuf.used, mixer->hwbuf.capacity);
5208 KASSERT(mixer->hwbuf.used >= mixer->frames_per_block); 5208 KASSERT(mixer->hwbuf.used >= mixer->frames_per_block);
5209 5209
5210 blksize = frametobyte(&mixer->hwbuf.fmt, mixer->frames_per_block); 5210 blksize = frametobyte(&mixer->hwbuf.fmt, mixer->frames_per_block);
5211 5211
5212 if (sc->hw_if->trigger_output) { 5212 if (sc->hw_if->trigger_output) {
5213 /* trigger (at once) */ 5213 /* trigger (at once) */
5214 if (!sc->sc_pbusy) { 5214 if (!sc->sc_pbusy) {
5215 start = mixer->hwbuf.mem; 5215 start = mixer->hwbuf.mem;
5216 end = (uint8_t *)start + auring_bytelen(&mixer->hwbuf); 5216 end = (uint8_t *)start + auring_bytelen(&mixer->hwbuf);
5217 params = format2_to_params(&mixer->hwbuf.fmt); 5217 params = format2_to_params(&mixer->hwbuf.fmt);
5218 5218
5219 error = sc->hw_if->trigger_output(sc->hw_hdl, 5219 error = sc->hw_if->trigger_output(sc->hw_hdl,
5220 start, end, blksize, audio_pintr, sc, &params); 5220 start, end, blksize, audio_pintr, sc, &params);
5221 if (error) { 5221 if (error) {
5222 device_printf(sc->sc_dev, 5222 device_printf(sc->sc_dev,
5223 "trigger_output failed with %d\n", error); 5223 "trigger_output failed with %d\n", error);
5224 return; 5224 return;
5225 } 5225 }
5226 } 5226 }
5227 } else { 5227 } else {
5228 /* start (everytime) */ 5228 /* start (everytime) */
5229 start = auring_headptr(&mixer->hwbuf); 5229 start = auring_headptr(&mixer->hwbuf);
5230 5230
5231 error = sc->hw_if->start_output(sc->hw_hdl, 5231 error = sc->hw_if->start_output(sc->hw_hdl,
5232 start, blksize, audio_pintr, sc); 5232 start, blksize, audio_pintr, sc);
5233 if (error) { 5233 if (error) {
5234 device_printf(sc->sc_dev, 5234 device_printf(sc->sc_dev,
5235 "start_output failed with %d\n", error); 5235 "start_output failed with %d\n", error);
5236 return; 5236 return;
5237 } 5237 }
5238 } 5238 }
5239} 5239}
5240 5240
5241/* 5241/*
5242 * This is an interrupt handler for playback. 5242 * This is an interrupt handler for playback.
5243 * It is called with sc_intr_lock held. 5243 * It is called with sc_intr_lock held.
5244 * 5244 *
5245 * It is usually called from hardware interrupt. However, note that 5245 * It is usually called from hardware interrupt. However, note that
5246 * for some drivers (e.g. uaudio) it is called from software interrupt. 5246 * for some drivers (e.g. uaudio) it is called from software interrupt.
5247 */ 5247 */
5248static void 5248static void
5249audio_pintr(void *arg) 5249audio_pintr(void *arg)
5250{ 5250{
5251 struct audio_softc *sc; 5251 struct audio_softc *sc;
5252 audio_trackmixer_t *mixer; 5252 audio_trackmixer_t *mixer;
5253 5253
5254 sc = arg; 5254 sc = arg;
5255 KASSERT(mutex_owned(sc->sc_intr_lock)); 5255 KASSERT(mutex_owned(sc->sc_intr_lock));
5256 5256
5257 if (sc->sc_dying) 5257 if (sc->sc_dying)
5258 return; 5258 return;
5259#if defined(DIAGNOSTIC) 5259#if defined(DIAGNOSTIC)
5260 if (sc->sc_pbusy == false) { 5260 if (sc->sc_pbusy == false) {
5261 device_printf(sc->sc_dev, "stray interrupt\n"); 5261 device_printf(sc->sc_dev, "stray interrupt\n");
5262 return; 5262 return;
5263 } 5263 }
5264#endif 5264#endif
5265 5265
5266 mixer = sc->sc_pmixer; 5266 mixer = sc->sc_pmixer;
5267 mixer->hw_complete_counter += mixer->frames_per_block; 5267 mixer->hw_complete_counter += mixer->frames_per_block;
5268 mixer->hwseq++; 5268 mixer->hwseq++;
5269 5269
5270 auring_take(&mixer->hwbuf, mixer->frames_per_block); 5270 auring_take(&mixer->hwbuf, mixer->frames_per_block);
5271 5271
5272 TRACE(4, 5272 TRACE(4,
5273 "HW_INT ++hwseq=%" PRIu64 " cmplcnt=%" PRIu64 " hwbuf=%d/%d/%d", 5273 "HW_INT ++hwseq=%" PRIu64 " cmplcnt=%" PRIu64 " hwbuf=%d/%d/%d",
5274 mixer->hwseq, mixer->hw_complete_counter, 5274 mixer->hwseq, mixer->hw_complete_counter,
5275 mixer->hwbuf.head, mixer->hwbuf.used, mixer->hwbuf.capacity); 5275 mixer->hwbuf.head, mixer->hwbuf.used, mixer->hwbuf.capacity);
5276 5276
5277#if !defined(_KERNEL) 5277#if !defined(_KERNEL)
5278 /* This is a debug code for userland test. */ 5278 /* This is a debug code for userland test. */
5279 return; 5279 return;
5280#endif 5280#endif
5281 5281
5282#if defined(AUDIO_HW_SINGLE_BUFFER) 5282#if defined(AUDIO_HW_SINGLE_BUFFER)
5283 /* 5283 /*
5284 * Create a new block here and output it immediately. 5284 * Create a new block here and output it immediately.
5285 * It makes a latency lower but needs machine power. 5285 * It makes a latency lower but needs machine power.
5286 */ 5286 */
5287 audio_pmixer_process(sc); 5287 audio_pmixer_process(sc);
5288 audio_pmixer_output(sc); 5288 audio_pmixer_output(sc);
5289#else 5289#else
5290 /* 5290 /*
5291 * It is called when block N output is done. 5291 * It is called when block N output is done.
5292 * Output immediately block N+1 created by the last interrupt. 5292 * Output immediately block N+1 created by the last interrupt.
5293 * And then create block N+2 for the next interrupt. 5293 * And then create block N+2 for the next interrupt.
5294 * This method makes playback robust even on slower machines. 5294 * This method makes playback robust even on slower machines.
5295 * Instead the latency is increased by one block. 5295 * Instead the latency is increased by one block.
5296 */ 5296 */
5297 5297
5298 /* At first, output ready block. */ 5298 /* At first, output ready block. */
5299 if (mixer->hwbuf.used >= mixer->frames_per_block) { 5299 if (mixer->hwbuf.used >= mixer->frames_per_block) {
5300 audio_pmixer_output(sc); 5300 audio_pmixer_output(sc);
5301 } 5301 }
5302 5302
5303 bool later = false; 5303 bool later = false;
5304 5304
5305 if (mixer->hwbuf.used < mixer->frames_per_block) { 5305 if (mixer->hwbuf.used < mixer->frames_per_block) {
5306 later = true; 5306 later = true;
5307 } 5307 }
5308 5308
5309 /* Then, process next block. */ 5309 /* Then, process next block. */
5310 audio_pmixer_process(sc); 5310 audio_pmixer_process(sc);
5311 5311
5312 if (later) { 5312 if (later) {
5313 audio_pmixer_output(sc); 5313 audio_pmixer_output(sc);
5314 } 5314 }
5315#endif 5315#endif
5316 5316
5317 /* 5317 /*
5318 * When this interrupt is the real hardware interrupt, disabling 5318 * When this interrupt is the real hardware interrupt, disabling
5319 * preemption here is not necessary. But some drivers (e.g. uaudio) 5319 * preemption here is not necessary. But some drivers (e.g. uaudio)
5320 * emulate it by software interrupt, so kpreempt_disable is necessary. 5320 * emulate it by software interrupt, so kpreempt_disable is necessary.
5321 */ 5321 */
5322 kpreempt_disable(); 5322 kpreempt_disable();
5323 softint_schedule(mixer->sih); 5323 softint_schedule(mixer->sih);
5324 kpreempt_enable(); 5324 kpreempt_enable();
5325} 5325}
5326 5326
5327/* 5327/*
5328 * Starts record mixer. 5328 * Starts record mixer.
5329 * Must be called only if sc_rbusy is false. 5329 * Must be called only if sc_rbusy is false.
5330 * Must be called with sc_lock held. 5330 * Must be called with sc_lock held.
5331 * Must not be called from the interrupt context. 5331 * Must not be called from the interrupt context.
5332 */ 5332 */
5333static void 5333static void
5334audio_rmixer_start(struct audio_softc *sc) 5334audio_rmixer_start(struct audio_softc *sc)
5335{ 5335{
5336 5336
5337 KASSERT(mutex_owned(sc->sc_lock)); 5337 KASSERT(mutex_owned(sc->sc_lock));
5338 KASSERT(sc->sc_rbusy == false); 5338 KASSERT(sc->sc_rbusy == false);
5339 5339
5340 mutex_enter(sc->sc_intr_lock); 5340 mutex_enter(sc->sc_intr_lock);
5341 5341
5342 TRACE(2, "%s", (audiodebug >= 3) ? "begin" : ""); 5342 TRACE(2, "%s", (audiodebug >= 3) ? "begin" : "");
5343 audio_rmixer_input(sc); 5343 audio_rmixer_input(sc);
5344 sc->sc_rbusy = true; 5344 sc->sc_rbusy = true;
5345 TRACE(3, "end"); 5345 TRACE(3, "end");
5346 5346
5347 mutex_exit(sc->sc_intr_lock); 5347 mutex_exit(sc->sc_intr_lock);
5348} 5348}
5349 5349
5350/* 5350/*
5351 * When recording with MD filter: 5351 * When recording with MD filter:
5352 * 5352 *
5353 * hwbuf [............] NBLKHW blocks ring buffer 5353 * hwbuf [............] NBLKHW blocks ring buffer
5354 * | 5354 * |
5355 * | convert from hw format 5355 * | convert from hw format
5356 * v 5356 * v
5357 * codecbuf [....] 1 block (ring) buffer 5357 * codecbuf [....] 1 block (ring) buffer
5358 * | | 5358 * | |
5359 * v v 5359 * v v
5360 * track track ... 5360 * track track ...
5361 * 5361 *
5362 * When recording without MD filter: 5362 * When recording without MD filter:
5363 * 5363 *
5364 * hwbuf [............] NBLKHW blocks ring buffer 5364 * hwbuf [............] NBLKHW blocks ring buffer
5365 * | | 5365 * | |
5366 * v v 5366 * v v
5367 * track track ... 5367 * track track ...
5368 * 5368 *
5369 * hwbuf: HW encoding, HW precision, HW ch, HW freq. 5369 * hwbuf: HW encoding, HW precision, HW ch, HW freq.
5370 * codecbuf: slinear_NE, internal precision, HW ch, HW freq. 5370 * codecbuf: slinear_NE, internal precision, HW ch, HW freq.
5371 */ 5371 */
5372 5372
5373/* 5373/*
5374 * Distribute a recorded block to all recording tracks. 5374 * Distribute a recorded block to all recording tracks.
5375 */ 5375 */
5376static void 5376static void
5377audio_rmixer_process(struct audio_softc *sc) 5377audio_rmixer_process(struct audio_softc *sc)
5378{ 5378{
5379 audio_trackmixer_t *mixer; 5379 audio_trackmixer_t *mixer;
5380 audio_ring_t *mixersrc; 5380 audio_ring_t *mixersrc;
5381 audio_file_t *f; 5381 audio_file_t *f;
5382 aint_t *p; 5382 aint_t *p;
5383 int count; 5383 int count;
5384 int bytes; 5384 int bytes;
5385 int i; 5385 int i;
5386 5386
5387 mixer = sc->sc_rmixer; 5387 mixer = sc->sc_rmixer;
5388 5388
5389 /* 5389 /*
5390 * count is the number of frames to be retrieved this time. 5390 * count is the number of frames to be retrieved this time.
5391 * count should be one block. 5391 * count should be one block.
5392 */ 5392 */
5393 count = auring_get_contig_used(&mixer->hwbuf); 5393 count = auring_get_contig_used(&mixer->hwbuf);
5394 count = uimin(count, mixer->frames_per_block); 5394 count = uimin(count, mixer->frames_per_block);
5395 if (count <= 0) { 5395 if (count <= 0) {
5396 TRACE(4, "count %d: too short", count); 5396 TRACE(4, "count %d: too short", count);
5397 return; 5397 return;
5398 } 5398 }
5399 bytes = frametobyte(&mixer->track_fmt, count); 5399 bytes = frametobyte(&mixer->track_fmt, count);
5400 5400
5401 /* Hardware driver's codec */ 5401 /* Hardware driver's codec */
5402 if (mixer->codec) { 5402 if (mixer->codec) {
5403 mixer->codecarg.src = auring_headptr(&mixer->hwbuf); 5403 mixer->codecarg.src = auring_headptr(&mixer->hwbuf);
5404 mixer->codecarg.dst = auring_tailptr(&mixer->codecbuf); 5404 mixer->codecarg.dst = auring_tailptr(&mixer->codecbuf);
5405 mixer->codecarg.count = count; 5405 mixer->codecarg.count = count;
5406 mixer->codec(&mixer->codecarg); 5406 mixer->codec(&mixer->codecarg);
5407 auring_take(&mixer->hwbuf, mixer->codecarg.count); 5407 auring_take(&mixer->hwbuf, mixer->codecarg.count);
5408 auring_push(&mixer->codecbuf, mixer->codecarg.count); 5408 auring_push(&mixer->codecbuf, mixer->codecarg.count);
5409 mixersrc = &mixer->codecbuf; 5409 mixersrc = &mixer->codecbuf;
5410 } else { 5410 } else {
5411 mixersrc = &mixer->hwbuf; 5411 mixersrc = &mixer->hwbuf;
5412 } 5412 }
5413 5413
5414 if (mixer->swap_endian) { 5414 if (mixer->swap_endian) {
5415 /* inplace conversion */ 5415 /* inplace conversion */
5416 p = auring_headptr_aint(mixersrc); 5416 p = auring_headptr_aint(mixersrc);
5417 for (i = 0; i < count * mixer->track_fmt.channels; i++, p++) { 5417 for (i = 0; i < count * mixer->track_fmt.channels; i++, p++) {
5418 *p = bswap16(*p); 5418 *p = bswap16(*p);
5419 } 5419 }
5420 } 5420 }
5421 5421
5422 /* Distribute to all tracks. */ 5422 /* Distribute to all tracks. */
5423 SLIST_FOREACH(f, &sc->sc_files, entry) { 5423 SLIST_FOREACH(f, &sc->sc_files, entry) {
5424 audio_track_t *track = f->rtrack; 5424 audio_track_t *track = f->rtrack;
5425 audio_ring_t *input; 5425 audio_ring_t *input;
5426 5426
5427 if (track == NULL) 5427 if (track == NULL)
5428 continue; 5428 continue;
5429 5429
5430 if (track->is_pause) { 5430 if (track->is_pause) {
5431 TRACET(4, track, "skip; paused"); 5431 TRACET(4, track, "skip; paused");
5432 continue; 5432 continue;
5433 } 5433 }
5434 5434
5435 if (audio_track_lock_tryenter(track) == false) { 5435 if (audio_track_lock_tryenter(track) == false) {
5436 TRACET(4, track, "skip; in use"); 5436 TRACET(4, track, "skip; in use");
5437 continue; 5437 continue;
5438 } 5438 }
5439 5439
5440 /* If the track buffer is full, discard the oldest one? */ 5440 /* If the track buffer is full, discard the oldest one? */
5441 input = track->input; 5441 input = track->input;
5442 if (input->capacity - input->used < mixer->frames_per_block) { 5442 if (input->capacity - input->used < mixer->frames_per_block) {
5443 int drops = mixer->frames_per_block - 5443 int drops = mixer->frames_per_block -
5444 (input->capacity - input->used); 5444 (input->capacity - input->used);
5445 track->dropframes += drops; 5445 track->dropframes += drops;
5446 TRACET(4, track, "drop %d frames: inp=%d/%d/%d", 5446 TRACET(4, track, "drop %d frames: inp=%d/%d/%d",
5447 drops, 5447 drops,
5448 input->head, input->used, input->capacity); 5448 input->head, input->used, input->capacity);
5449 auring_take(input, drops); 5449 auring_take(input, drops);
5450 } 5450 }
5451 KASSERT(input->used % mixer->frames_per_block == 0); 5451 KASSERT(input->used % mixer->frames_per_block == 0);
5452 5452
5453 memcpy(auring_tailptr_aint(input), 5453 memcpy(auring_tailptr_aint(input),
5454 auring_headptr_aint(mixersrc), 5454 auring_headptr_aint(mixersrc),
5455 bytes); 5455 bytes);
5456 auring_push(input, count); 5456 auring_push(input, count);
5457 5457
5458 /* XXX sequence counter? */ 5458 /* XXX sequence counter? */
5459 5459
5460 audio_track_lock_exit(track); 5460 audio_track_lock_exit(track);
5461 } 5461 }
5462 5462
5463 auring_take(mixersrc, count); 5463 auring_take(mixersrc, count);
5464} 5464}
5465 5465
5466/* 5466/*
5467 * Input one block from HW to hwbuf. 5467 * Input one block from HW to hwbuf.
5468 * Must be called with sc_intr_lock held. 5468 * Must be called with sc_intr_lock held.
5469 */ 5469 */
5470static void 5470static void
5471audio_rmixer_input(struct audio_softc *sc) 5471audio_rmixer_input(struct audio_softc *sc)
5472{ 5472{
5473 audio_trackmixer_t *mixer; 5473 audio_trackmixer_t *mixer;
5474 audio_params_t params; 5474 audio_params_t params;
5475 void *start; 5475 void *start;
5476 void *end; 5476 void *end;
5477 int blksize; 5477 int blksize;
5478 int error; 5478 int error;
5479 5479
5480 mixer = sc->sc_rmixer; 5480 mixer = sc->sc_rmixer;
5481 blksize = frametobyte(&mixer->hwbuf.fmt, mixer->frames_per_block); 5481 blksize = frametobyte(&mixer->hwbuf.fmt, mixer->frames_per_block);
5482 5482
5483 if (sc->hw_if->trigger_input) { 5483 if (sc->hw_if->trigger_input) {
5484 /* trigger (at once) */ 5484 /* trigger (at once) */
5485 if (!sc->sc_rbusy) { 5485 if (!sc->sc_rbusy) {
5486 start = mixer->hwbuf.mem; 5486 start = mixer->hwbuf.mem;
5487 end = (uint8_t *)start + auring_bytelen(&mixer->hwbuf); 5487 end = (uint8_t *)start + auring_bytelen(&mixer->hwbuf);
5488 params = format2_to_params(&mixer->hwbuf.fmt); 5488 params = format2_to_params(&mixer->hwbuf.fmt);
5489 5489
5490 error = sc->hw_if->trigger_input(sc->hw_hdl, 5490 error = sc->hw_if->trigger_input(sc->hw_hdl,
5491 start, end, blksize, audio_rintr, sc, &params); 5491 start, end, blksize, audio_rintr, sc, &params);
5492 if (error) { 5492 if (error) {
5493 device_printf(sc->sc_dev, 5493 device_printf(sc->sc_dev,
5494 "trigger_input failed with %d\n", error); 5494 "trigger_input failed with %d\n", error);
5495 return; 5495 return;
5496 } 5496 }
5497 } 5497 }
5498 } else { 5498 } else {
5499 /* start (everytime) */ 5499 /* start (everytime) */
5500 start = auring_tailptr(&mixer->hwbuf); 5500 start = auring_tailptr(&mixer->hwbuf);
5501 5501
5502 error = sc->hw_if->start_input(sc->hw_hdl, 5502 error = sc->hw_if->start_input(sc->hw_hdl,
5503 start, blksize, audio_rintr, sc); 5503 start, blksize, audio_rintr, sc);
5504 if (error) { 5504 if (error) {
5505 device_printf(sc->sc_dev, 5505 device_printf(sc->sc_dev,
5506 "start_input failed with %d\n", error); 5506 "start_input failed with %d\n", error);
5507 return; 5507 return;
5508 } 5508 }
5509 } 5509 }
5510} 5510}
5511 5511
5512/* 5512/*
5513 * This is an interrupt handler for recording. 5513 * This is an interrupt handler for recording.
5514 * It is called with sc_intr_lock. 5514 * It is called with sc_intr_lock.
5515 * 5515 *
5516 * It is usually called from hardware interrupt. However, note that 5516 * It is usually called from hardware interrupt. However, note that
5517 * for some drivers (e.g. uaudio) it is called from software interrupt. 5517 * for some drivers (e.g. uaudio) it is called from software interrupt.
5518 */ 5518 */
5519static void 5519static void
5520audio_rintr(void *arg) 5520audio_rintr(void *arg)
5521{ 5521{
5522 struct audio_softc *sc; 5522 struct audio_softc *sc;
5523 audio_trackmixer_t *mixer; 5523 audio_trackmixer_t *mixer;
5524 5524
5525 sc = arg; 5525 sc = arg;
5526 KASSERT(mutex_owned(sc->sc_intr_lock)); 5526 KASSERT(mutex_owned(sc->sc_intr_lock));
5527 5527
5528 if (sc->sc_dying) 5528 if (sc->sc_dying)
5529 return; 5529 return;
5530#if defined(DIAGNOSTIC) 5530#if defined(DIAGNOSTIC)
5531 if (sc->sc_rbusy == false) { 5531 if (sc->sc_rbusy == false) {
5532 device_printf(sc->sc_dev, "stray interrupt\n"); 5532 device_printf(sc->sc_dev, "stray interrupt\n");
5533 return; 5533 return;
5534 } 5534 }
5535#endif 5535#endif
5536 5536
5537 mixer = sc->sc_rmixer; 5537 mixer = sc->sc_rmixer;
5538 mixer->hw_complete_counter += mixer->frames_per_block; 5538 mixer->hw_complete_counter += mixer->frames_per_block;
5539 mixer->hwseq++; 5539 mixer->hwseq++;
5540 5540
5541 auring_push(&mixer->hwbuf, mixer->frames_per_block); 5541 auring_push(&mixer->hwbuf, mixer->frames_per_block);
5542 5542
5543 TRACE(4, 5543 TRACE(4,
5544 "HW_INT ++hwseq=%" PRIu64 " cmplcnt=%" PRIu64 " hwbuf=%d/%d/%d", 5544 "HW_INT ++hwseq=%" PRIu64 " cmplcnt=%" PRIu64 " hwbuf=%d/%d/%d",
5545 mixer->hwseq, mixer->hw_complete_counter, 5545 mixer->hwseq, mixer->hw_complete_counter,
5546 mixer->hwbuf.head, mixer->hwbuf.used, mixer->hwbuf.capacity); 5546 mixer->hwbuf.head, mixer->hwbuf.used, mixer->hwbuf.capacity);
5547 5547
5548 /* Distrubute recorded block */ 5548 /* Distrubute recorded block */
5549 audio_rmixer_process(sc); 5549 audio_rmixer_process(sc);
5550 5550
5551 /* Request next block */ 5551 /* Request next block */
5552 audio_rmixer_input(sc); 5552 audio_rmixer_input(sc);
5553 5553
5554 /* 5554 /*
5555 * When this interrupt is the real hardware interrupt, disabling 5555 * When this interrupt is the real hardware interrupt, disabling
5556 * preemption here is not necessary. But some drivers (e.g. uaudio) 5556 * preemption here is not necessary. But some drivers (e.g. uaudio)
5557 * emulate it by software interrupt, so kpreempt_disable is necessary. 5557 * emulate it by software interrupt, so kpreempt_disable is necessary.
5558 */ 5558 */
5559 kpreempt_disable(); 5559 kpreempt_disable();
5560 softint_schedule(mixer->sih); 5560 softint_schedule(mixer->sih);
5561 kpreempt_enable(); 5561 kpreempt_enable();
5562} 5562}
5563 5563
5564/* 5564/*
5565 * Halts playback mixer. 5565 * Halts playback mixer.
5566 * This function also clears related parameters, so call this function 5566 * This function also clears related parameters, so call this function
5567 * instead of calling halt_output directly. 5567 * instead of calling halt_output directly.
5568 * Must be called only if sc_pbusy is true. 5568 * Must be called only if sc_pbusy is true.
5569 * Must be called with sc_lock && sc_exlock held. 5569 * Must be called with sc_lock && sc_exlock held.
5570 */ 5570 */
5571static int 5571static int
5572audio_pmixer_halt(struct audio_softc *sc) 5572audio_pmixer_halt(struct audio_softc *sc)
5573{ 5573{
5574 int error; 5574 int error;
5575 5575
5576 TRACE(2, ""); 5576 TRACE(2, "");
5577 KASSERT(mutex_owned(sc->sc_lock)); 5577 KASSERT(mutex_owned(sc->sc_lock));
5578 KASSERT(sc->sc_exlock); 5578 KASSERT(sc->sc_exlock);
5579 5579
5580 mutex_enter(sc->sc_intr_lock); 5580 mutex_enter(sc->sc_intr_lock);
5581 error = sc->hw_if->halt_output(sc->hw_hdl); 5581 error = sc->hw_if->halt_output(sc->hw_hdl);
5582 mutex_exit(sc->sc_intr_lock); 5582 mutex_exit(sc->sc_intr_lock);
5583 5583
5584 /* Halts anyway even if some error has occurred. */ 5584 /* Halts anyway even if some error has occurred. */
5585 sc->sc_pbusy = false; 5585 sc->sc_pbusy = false;
5586 sc->sc_pmixer->hwbuf.head = 0; 5586 sc->sc_pmixer->hwbuf.head = 0;
5587 sc->sc_pmixer->hwbuf.used = 0; 5587 sc->sc_pmixer->hwbuf.used = 0;
5588 sc->sc_pmixer->mixseq = 0; 5588 sc->sc_pmixer->mixseq = 0;
5589 sc->sc_pmixer->hwseq = 0; 5589 sc->sc_pmixer->hwseq = 0;
5590 5590
5591 return error; 5591 return error;
5592} 5592}
5593 5593
5594/* 5594/*
5595 * Halts recording mixer. 5595 * Halts recording mixer.
5596 * This function also clears related parameters, so call this function 5596 * This function also clears related parameters, so call this function
5597 * instead of calling halt_input directly. 5597 * instead of calling halt_input directly.
5598 * Must be called only if sc_rbusy is true. 5598 * Must be called only if sc_rbusy is true.
5599 * Must be called with sc_lock && sc_exlock held. 5599 * Must be called with sc_lock && sc_exlock held.
5600 */ 5600 */
5601static int 5601static int
5602audio_rmixer_halt(struct audio_softc *sc) 5602audio_rmixer_halt(struct audio_softc *sc)
5603{ 5603{
5604 int error; 5604 int error;
5605 5605
5606 TRACE(2, ""); 5606 TRACE(2, "");
5607 KASSERT(mutex_owned(sc->sc_lock)); 5607 KASSERT(mutex_owned(sc->sc_lock));
5608 KASSERT(sc->sc_exlock); 5608 KASSERT(sc->sc_exlock);
5609 5609
5610 mutex_enter(sc->sc_intr_lock); 5610 mutex_enter(sc->sc_intr_lock);
5611 error = sc->hw_if->halt_input(sc->hw_hdl); 5611 error = sc->hw_if->halt_input(sc->hw_hdl);
5612 mutex_exit(sc->sc_intr_lock); 5612 mutex_exit(sc->sc_intr_lock);
5613 5613
5614 /* Halts anyway even if some error has occurred. */ 5614 /* Halts anyway even if some error has occurred. */
5615 sc->sc_rbusy = false; 5615 sc->sc_rbusy = false;
5616 sc->sc_rmixer->hwbuf.head = 0; 5616 sc->sc_rmixer->hwbuf.head = 0;
5617 sc->sc_rmixer->hwbuf.used = 0; 5617 sc->sc_rmixer->hwbuf.used = 0;
5618 sc->sc_rmixer->mixseq = 0; 5618 sc->sc_rmixer->mixseq = 0;
5619 sc->sc_rmixer->hwseq = 0; 5619 sc->sc_rmixer->hwseq = 0;
5620 5620
5621 return error; 5621 return error;
5622} 5622}
5623 5623
5624/* 5624/*
5625 * Flush this track. 5625 * Flush this track.
5626 * Halts all operations, clears all buffers, reset error counters. 5626 * Halts all operations, clears all buffers, reset error counters.
5627 * XXX I'm not sure... 5627 * XXX I'm not sure...
5628 */ 5628 */
5629static void 5629static void
5630audio_track_clear(struct audio_softc *sc, audio_track_t *track) 5630audio_track_clear(struct audio_softc *sc, audio_track_t *track)
5631{ 5631{
5632 5632
5633 KASSERT(track); 5633 KASSERT(track);
5634 TRACET(3, track, "clear"); 5634 TRACET(3, track, "clear");
5635 5635
5636 audio_track_lock_enter(track); 5636 audio_track_lock_enter(track);
5637 5637
5638 track->usrbuf.used = 0; 5638 track->usrbuf.used = 0;
5639 /* Clear all internal parameters. */ 5639 /* Clear all internal parameters. */
5640 if (track->codec.filter) { 5640 if (track->codec.filter) {
5641 track->codec.srcbuf.used = 0; 5641 track->codec.srcbuf.used = 0;
5642 track->codec.srcbuf.head = 0; 5642 track->codec.srcbuf.head = 0;
5643 } 5643 }
5644 if (track->chvol.filter) { 5644 if (track->chvol.filter) {
5645 track->chvol.srcbuf.used = 0; 5645 track->chvol.srcbuf.used = 0;
5646 track->chvol.srcbuf.head = 0; 5646 track->chvol.srcbuf.head = 0;
5647 } 5647 }
5648 if (track->chmix.filter) { 5648 if (track->chmix.filter) {
5649 track->chmix.srcbuf.used = 0; 5649 track->chmix.srcbuf.used = 0;
5650 track->chmix.srcbuf.head = 0; 5650 track->chmix.srcbuf.head = 0;
5651 } 5651 }
5652 if (track->freq.filter) { 5652 if (track->freq.filter) {
5653 track->freq.srcbuf.used = 0; 5653 track->freq.srcbuf.used = 0;
5654 track->freq.srcbuf.head = 0; 5654 track->freq.srcbuf.head = 0;
5655 if (track->freq_step < 65536) 5655 if (track->freq_step < 65536)
5656 track->freq_current = 65536; 5656 track->freq_current = 65536;
5657 else 5657 else
5658 track->freq_current = 0; 5658 track->freq_current = 0;
5659 memset(track->freq_prev, 0, sizeof(track->freq_prev)); 5659 memset(track->freq_prev, 0, sizeof(track->freq_prev));
5660 memset(track->freq_curr, 0, sizeof(track->freq_curr)); 5660 memset(track->freq_curr, 0, sizeof(track->freq_curr));
5661 } 5661 }
5662 /* Clear buffer, then operation halts naturally. */ 5662 /* Clear buffer, then operation halts naturally. */
5663 track->outbuf.used = 0; 5663 track->outbuf.used = 0;
5664 5664
5665 /* Clear counters. */ 5665 /* Clear counters. */
5666 track->dropframes = 0; 5666 track->dropframes = 0;
5667 5667
5668 audio_track_lock_exit(track); 5668 audio_track_lock_exit(track);
5669} 5669}
5670 5670
5671/* 5671/*
5672 * Drain the track. 5672 * Drain the track.
5673 * track must be present and for playback. 5673 * track must be present and for playback.
5674 * If successful, it returns 0. Otherwise returns errno. 5674 * If successful, it returns 0. Otherwise returns errno.
5675 * Must be called with sc_lock held. 5675 * Must be called with sc_lock held.
5676 */ 5676 */
5677static int 5677static int
5678audio_track_drain(struct audio_softc *sc, audio_track_t *track) 5678audio_track_drain(struct audio_softc *sc, audio_track_t *track)
5679{ 5679{
5680 audio_trackmixer_t *mixer; 5680 audio_trackmixer_t *mixer;
5681 int done; 5681 int done;
5682 int error; 5682 int error;
5683 5683
5684 KASSERT(track); 5684 KASSERT(track);
5685 TRACET(3, track, "start"); 5685 TRACET(3, track, "start");
5686 mixer = track->mixer; 5686 mixer = track->mixer;
5687 KASSERT(mutex_owned(sc->sc_lock)); 5687 KASSERT(mutex_owned(sc->sc_lock));
5688 5688
5689 /* Ignore them if pause. */ 5689 /* Ignore them if pause. */
5690 if (track->is_pause) { 5690 if (track->is_pause) {
5691 TRACET(3, track, "pause -> clear"); 5691 TRACET(3, track, "pause -> clear");
5692 track->pstate = AUDIO_STATE_CLEAR; 5692 track->pstate = AUDIO_STATE_CLEAR;
5693 } 5693 }
5694 /* Terminate early here if there is no data in the track. */ 5694 /* Terminate early here if there is no data in the track. */
5695 if (track->pstate == AUDIO_STATE_CLEAR) { 5695 if (track->pstate == AUDIO_STATE_CLEAR) {
5696 TRACET(3, track, "no need to drain"); 5696 TRACET(3, track, "no need to drain");
5697 return 0; 5697 return 0;
5698 } 5698 }
5699 track->pstate = AUDIO_STATE_DRAINING; 5699 track->pstate = AUDIO_STATE_DRAINING;
5700 5700
5701 for (;;) { 5701 for (;;) {
5702 /* I want to display it before condition evaluation. */ 5702 /* I want to display it before condition evaluation. */
5703 TRACET(3, track, "pid=%d.%d trkseq=%d hwseq=%d out=%d/%d/%d", 5703 TRACET(3, track, "pid=%d.%d trkseq=%d hwseq=%d out=%d/%d/%d",
5704 (int)curproc->p_pid, (int)curlwp->l_lid, 5704 (int)curproc->p_pid, (int)curlwp->l_lid,
5705 (int)track->seq, (int)mixer->hwseq, 5705 (int)track->seq, (int)mixer->hwseq,
5706 track->outbuf.head, track->outbuf.used, 5706 track->outbuf.head, track->outbuf.used,
5707 track->outbuf.capacity); 5707 track->outbuf.capacity);
5708 5708
5709 /* Condition to terminate */ 5709 /* Condition to terminate */
5710 audio_track_lock_enter(track); 5710 audio_track_lock_enter(track);
5711 done = (track->usrbuf.used < frametobyte(&track->inputfmt, 1) && 5711 done = (track->usrbuf.used < frametobyte(&track->inputfmt, 1) &&
5712 track->outbuf.used == 0 && 5712 track->outbuf.used == 0 &&
5713 track->seq <= mixer->hwseq); 5713 track->seq <= mixer->hwseq);
5714 audio_track_lock_exit(track); 5714 audio_track_lock_exit(track);
5715 if (done) 5715 if (done)
5716 break; 5716 break;
5717 5717
5718 TRACET(3, track, "sleep"); 5718 TRACET(3, track, "sleep");
5719 error = audio_track_waitio(sc, track); 5719 error = audio_track_waitio(sc, track);
5720 if (error) 5720 if (error)
5721 return error; 5721 return error;
5722 5722
5723 /* XXX call audio_track_play here ? */ 5723 /* XXX call audio_track_play here ? */
5724 } 5724 }
5725 5725
5726 track->pstate = AUDIO_STATE_CLEAR; 5726 track->pstate = AUDIO_STATE_CLEAR;
5727 TRACET(3, track, "done trk_inp=%d trk_out=%d", 5727 TRACET(3, track, "done trk_inp=%d trk_out=%d",
5728 (int)track->inputcounter, (int)track->outputcounter); 5728 (int)track->inputcounter, (int)track->outputcounter);
5729 return 0; 5729 return 0;
5730} 5730}
5731 5731
5732/* 5732/*
 5733 * Send signal to process.
 5734 * This is intended to be called only from audio_softintr_{rd,wr}.
 5735 * Must be called with sc_lock && sc_intr_lock held.
 5736 */
 5737static inline void
 5738audio_psignal(struct audio_softc *sc, pid_t pid, int signum)
 5739{
 5740 proc_t *p;
 5741
 5742 KASSERT(mutex_owned(sc->sc_lock));
 5743 KASSERT(mutex_owned(sc->sc_intr_lock));
 5744 KASSERT(pid != 0);
 5745
 5746 /*
 5747 * psignal() must be called without spin lock held.
 5748 * So leave intr_lock temporarily here.
 5749 */
 5750 mutex_exit(sc->sc_intr_lock);
 5751
 5752 mutex_enter(proc_lock);
 5753 p = proc_find(pid);
 5754 if (p)
 5755 psignal(p, signum);
 5756 mutex_exit(proc_lock);
 5757
 5758 /* Enter intr_lock again */
 5759 mutex_enter(sc->sc_intr_lock);
 5760}
 5761
 5762/*
5733 * This is software interrupt handler for record. 5763 * This is software interrupt handler for record.
5734 * It is called from recording hardware interrupt everytime. 5764 * It is called from recording hardware interrupt everytime.
5735 * It does: 5765 * It does:
5736 * - Deliver SIGIO for all async processes. 5766 * - Deliver SIGIO for all async processes.
5737 * - Notify to audio_read() that data has arrived. 5767 * - Notify to audio_read() that data has arrived.
5738 * - selnotify() for select/poll-ing processes. 5768 * - selnotify() for select/poll-ing processes.
5739 */ 5769 */
5740/* 5770/*
5741 * XXX If a process issues FIOASYNC between hardware interrupt and 5771 * XXX If a process issues FIOASYNC between hardware interrupt and
5742 * software interrupt, (stray) SIGIO will be sent to the process 5772 * software interrupt, (stray) SIGIO will be sent to the process
5743 * despite the fact that it has not receive recorded data yet. 5773 * despite the fact that it has not receive recorded data yet.
5744 */ 5774 */
5745static void 5775static void
5746audio_softintr_rd(void *cookie) 5776audio_softintr_rd(void *cookie)
5747{ 5777{
5748 struct audio_softc *sc = cookie; 5778 struct audio_softc *sc = cookie;
5749 audio_file_t *f; 5779 audio_file_t *f;
5750 proc_t *p; 
5751 pid_t pid; 5780 pid_t pid;
5752 5781
5753 mutex_enter(sc->sc_lock); 5782 mutex_enter(sc->sc_lock);
5754 mutex_enter(sc->sc_intr_lock); 5783 mutex_enter(sc->sc_intr_lock);
5755 5784
5756 SLIST_FOREACH(f, &sc->sc_files, entry) { 5785 SLIST_FOREACH(f, &sc->sc_files, entry) {
5757 audio_track_t *track = f->rtrack; 5786 audio_track_t *track = f->rtrack;
5758 5787
5759 if (track == NULL) 5788 if (track == NULL)
5760 continue; 5789 continue;
5761 5790
5762 TRACET(4, track, "broadcast; inp=%d/%d/%d", 5791 TRACET(4, track, "broadcast; inp=%d/%d/%d",
5763 track->input->head, 5792 track->input->head,
5764 track->input->used, 5793 track->input->used,
5765 track->input->capacity); 5794 track->input->capacity);
5766 5795
5767 pid = f->async_audio; 5796 pid = f->async_audio;
5768 if (pid != 0) { 5797 if (pid != 0) {
5769 TRACEF(4, f, "sending SIGIO %d", pid); 5798 TRACEF(4, f, "sending SIGIO %d", pid);
5770 mutex_enter(proc_lock); 5799 audio_psignal(sc, pid, SIGIO);
5771 if ((p = proc_find(pid)) != NULL) 
5772 psignal(p, SIGIO); 
5773 mutex_exit(proc_lock); 
5774 } 5800 }
5775 } 5801 }
5776 mutex_exit(sc->sc_intr_lock); 5802 mutex_exit(sc->sc_intr_lock);
5777 5803
5778 /* Notify that data has arrived. */ 5804 /* Notify that data has arrived. */
5779 selnotify(&sc->sc_rsel, 0, NOTE_SUBMIT); 5805 selnotify(&sc->sc_rsel, 0, NOTE_SUBMIT);
5780 KNOTE(&sc->sc_rsel.sel_klist, 0); 5806 KNOTE(&sc->sc_rsel.sel_klist, 0);
5781 cv_broadcast(&sc->sc_rmixer->outcv); 5807 cv_broadcast(&sc->sc_rmixer->outcv);
5782 5808
5783 mutex_exit(sc->sc_lock); 5809 mutex_exit(sc->sc_lock);
5784} 5810}
5785 5811
5786/* 5812/*
5787 * This is software interrupt handler for playback. 5813 * This is software interrupt handler for playback.
5788 * It is called from playback hardware interrupt everytime. 5814 * It is called from playback hardware interrupt everytime.
5789 * It does: 5815 * It does:
5790 * - Deliver SIGIO for all async and writable (used < lowat) processes. 5816 * - Deliver SIGIO for all async and writable (used < lowat) processes.
5791 * - Notify to audio_write() that outbuf block available. 5817 * - Notify to audio_write() that outbuf block available.
5792 * - selnotify() for select/poll-ing processes if there are any writable 5818 * - selnotify() for select/poll-ing processes if there are any writable
5793 * (used < lowat) processes. Checking each descriptor will be done by 5819 * (used < lowat) processes. Checking each descriptor will be done by
5794 * filt_audiowrite_event(). 5820 * filt_audiowrite_event().
5795 */ 5821 */
5796static void 5822static void
5797audio_softintr_wr(void *cookie) 5823audio_softintr_wr(void *cookie)
5798{ 5824{
5799 struct audio_softc *sc = cookie; 5825 struct audio_softc *sc = cookie;
5800 audio_file_t *f; 5826 audio_file_t *f;
5801 bool found; 5827 bool found;
5802 proc_t *p; 
5803 pid_t pid; 5828 pid_t pid;
5804 5829
5805 TRACE(4, "called"); 5830 TRACE(4, "called");
5806 found = false; 5831 found = false;
5807 5832
5808 mutex_enter(sc->sc_lock); 5833 mutex_enter(sc->sc_lock);
5809 mutex_enter(sc->sc_intr_lock); 5834 mutex_enter(sc->sc_intr_lock);
5810 5835
5811 SLIST_FOREACH(f, &sc->sc_files, entry) { 5836 SLIST_FOREACH(f, &sc->sc_files, entry) {
5812 audio_track_t *track = f->ptrack; 5837 audio_track_t *track = f->ptrack;
5813 5838
5814 if (track == NULL) 5839 if (track == NULL)
5815 continue; 5840 continue;
5816 5841
5817 TRACET(4, track, "broadcast; trseq=%d out=%d/%d/%d", 5842 TRACET(4, track, "broadcast; trseq=%d out=%d/%d/%d",
5818 (int)track->seq, 5843 (int)track->seq,
5819 track->outbuf.head, 5844 track->outbuf.head,
5820 track->outbuf.used, 5845 track->outbuf.used,
5821 track->outbuf.capacity); 5846 track->outbuf.capacity);
5822 5847
5823 /* 5848 /*
5824 * Send a signal if the process is async mode and 5849 * Send a signal if the process is async mode and
5825 * used is lower than lowat. 5850 * used is lower than lowat.
5826 */ 5851 */
5827 if (track->usrbuf.used <= track->usrbuf_usedlow && 5852 if (track->usrbuf.used <= track->usrbuf_usedlow &&
5828 !track->is_pause) { 5853 !track->is_pause) {
 5854 /* For selnotify */
5829 found = true; 5855 found = true;
 5856 /* For SIGIO */
5830 pid = f->async_audio; 5857 pid = f->async_audio;
5831 if (pid != 0) { 5858 if (pid != 0) {
5832 TRACEF(4, f, "sending SIGIO %d", pid); 5859 TRACEF(4, f, "sending SIGIO %d", pid);
5833 mutex_enter(proc_lock); 5860 audio_psignal(sc, pid, SIGIO);
5834 if ((p = proc_find(pid)) != NULL) 
5835 psignal(p, SIGIO); 
5836 mutex_exit(proc_lock); 
5837 } 5861 }
5838 } 5862 }
5839 } 5863 }
5840 mutex_exit(sc->sc_intr_lock); 5864 mutex_exit(sc->sc_intr_lock);
5841 5865
5842 /* 5866 /*
5843 * Notify for select/poll when someone become writable. 5867 * Notify for select/poll when someone become writable.
5844 * It needs sc_lock (and not sc_intr_lock). 5868 * It needs sc_lock (and not sc_intr_lock).
5845 */ 5869 */
5846 if (found) { 5870 if (found) {
5847 TRACE(4, "selnotify"); 5871 TRACE(4, "selnotify");
5848 selnotify(&sc->sc_wsel, 0, NOTE_SUBMIT); 5872 selnotify(&sc->sc_wsel, 0, NOTE_SUBMIT);
5849 KNOTE(&sc->sc_wsel.sel_klist, 0); 5873 KNOTE(&sc->sc_wsel.sel_klist, 0);
5850 } 5874 }
5851 5875
5852 /* Notify to audio_write() that outbuf available. */ 5876 /* Notify to audio_write() that outbuf available. */
5853 cv_broadcast(&sc->sc_pmixer->outcv); 5877 cv_broadcast(&sc->sc_pmixer->outcv);
5854 5878
5855 mutex_exit(sc->sc_lock); 5879 mutex_exit(sc->sc_lock);
5856} 5880}
5857 5881
5858/* 5882/*
5859 * Check (and convert) the format *p came from userland. 5883 * Check (and convert) the format *p came from userland.
5860 * If successful, it writes back the converted format to *p if necessary 5884 * If successful, it writes back the converted format to *p if necessary
5861 * and returns 0. Otherwise returns errno (*p may change even this case). 5885 * and returns 0. Otherwise returns errno (*p may change even this case).
5862 */ 5886 */
5863static int 5887static int
5864audio_check_params(audio_format2_t *p) 5888audio_check_params(audio_format2_t *p)
5865{ 5889{
5866 5890
5867 /* Convert obsoleted AUDIO_ENCODING_PCM* */ 5891 /* Convert obsoleted AUDIO_ENCODING_PCM* */
5868 /* XXX Is this conversion right? */ 5892 /* XXX Is this conversion right? */
5869 if (p->encoding == AUDIO_ENCODING_PCM16) { 5893 if (p->encoding == AUDIO_ENCODING_PCM16) {
5870 if (p->precision == 8) 5894 if (p->precision == 8)
5871 p->encoding = AUDIO_ENCODING_ULINEAR; 5895 p->encoding = AUDIO_ENCODING_ULINEAR;
5872 else 5896 else
5873 p->encoding = AUDIO_ENCODING_SLINEAR; 5897 p->encoding = AUDIO_ENCODING_SLINEAR;
5874 } else if (p->encoding == AUDIO_ENCODING_PCM8) { 5898 } else if (p->encoding == AUDIO_ENCODING_PCM8) {
5875 if (p->precision == 8) 5899 if (p->precision == 8)
5876 p->encoding = AUDIO_ENCODING_ULINEAR; 5900 p->encoding = AUDIO_ENCODING_ULINEAR;
5877 else 5901 else
5878 return EINVAL; 5902 return EINVAL;
5879 } 5903 }
5880 5904
5881 /* 5905 /*
5882 * Convert obsoleted AUDIO_ENCODING_[SU]LINEAR without endianness 5906 * Convert obsoleted AUDIO_ENCODING_[SU]LINEAR without endianness
5883 * suffix. 5907 * suffix.
5884 */ 5908 */
5885 if (p->encoding == AUDIO_ENCODING_SLINEAR) 5909 if (p->encoding == AUDIO_ENCODING_SLINEAR)
5886 p->encoding = AUDIO_ENCODING_SLINEAR_NE; 5910 p->encoding = AUDIO_ENCODING_SLINEAR_NE;
5887 if (p->encoding == AUDIO_ENCODING_ULINEAR) 5911 if (p->encoding == AUDIO_ENCODING_ULINEAR)
5888 p->encoding = AUDIO_ENCODING_ULINEAR_NE; 5912 p->encoding = AUDIO_ENCODING_ULINEAR_NE;
5889 5913
5890 switch (p->encoding) { 5914 switch (p->encoding) {
5891 case AUDIO_ENCODING_ULAW: 5915 case AUDIO_ENCODING_ULAW:
5892 case AUDIO_ENCODING_ALAW: 5916 case AUDIO_ENCODING_ALAW:
5893 if (p->precision != 8) 5917 if (p->precision != 8)
5894 return EINVAL; 5918 return EINVAL;
5895 break; 5919 break;
5896 case AUDIO_ENCODING_ADPCM: 5920 case AUDIO_ENCODING_ADPCM:
5897 if (p->precision != 4 && p->precision != 8) 5921 if (p->precision != 4 && p->precision != 8)
5898 return EINVAL; 5922 return EINVAL;
5899 break; 5923 break;
5900 case AUDIO_ENCODING_SLINEAR_LE: 5924 case AUDIO_ENCODING_SLINEAR_LE:
5901 case AUDIO_ENCODING_SLINEAR_BE: 5925 case AUDIO_ENCODING_SLINEAR_BE:
5902 case AUDIO_ENCODING_ULINEAR_LE: 5926 case AUDIO_ENCODING_ULINEAR_LE:
5903 case AUDIO_ENCODING_ULINEAR_BE: 5927 case AUDIO_ENCODING_ULINEAR_BE:
5904 if (p->precision != 8 && p->precision != 16 && 5928 if (p->precision != 8 && p->precision != 16 &&
5905 p->precision != 24 && p->precision != 32) 5929 p->precision != 24 && p->precision != 32)
5906 return EINVAL; 5930 return EINVAL;
5907 5931
5908 /* 8bit format does not have endianness. */ 5932 /* 8bit format does not have endianness. */
5909 if (p->precision == 8) { 5933 if (p->precision == 8) {
5910 if (p->encoding == AUDIO_ENCODING_SLINEAR_OE) 5934 if (p->encoding == AUDIO_ENCODING_SLINEAR_OE)
5911 p->encoding = AUDIO_ENCODING_SLINEAR_NE; 5935 p->encoding = AUDIO_ENCODING_SLINEAR_NE;
5912 if (p->encoding == AUDIO_ENCODING_ULINEAR_OE) 5936 if (p->encoding == AUDIO_ENCODING_ULINEAR_OE)
5913 p->encoding = AUDIO_ENCODING_ULINEAR_NE; 5937 p->encoding = AUDIO_ENCODING_ULINEAR_NE;
5914 } 5938 }
5915 5939
5916 if (p->precision > p->stride) 5940 if (p->precision > p->stride)
5917 return EINVAL; 5941 return EINVAL;
5918 break; 5942 break;
5919 case AUDIO_ENCODING_MPEG_L1_STREAM: 5943 case AUDIO_ENCODING_MPEG_L1_STREAM:
5920 case AUDIO_ENCODING_MPEG_L1_PACKETS: 5944 case AUDIO_ENCODING_MPEG_L1_PACKETS:
5921 case AUDIO_ENCODING_MPEG_L1_SYSTEM: 5945 case AUDIO_ENCODING_MPEG_L1_SYSTEM:
5922 case AUDIO_ENCODING_MPEG_L2_STREAM: 5946 case AUDIO_ENCODING_MPEG_L2_STREAM:
5923 case AUDIO_ENCODING_MPEG_L2_PACKETS: 5947 case AUDIO_ENCODING_MPEG_L2_PACKETS:
5924 case AUDIO_ENCODING_MPEG_L2_SYSTEM: 5948 case AUDIO_ENCODING_MPEG_L2_SYSTEM:
5925 case AUDIO_ENCODING_AC3: 5949 case AUDIO_ENCODING_AC3:
5926 break; 5950 break;
5927 default: 5951 default:
5928 return EINVAL; 5952 return EINVAL;
5929 } 5953 }
5930 5954
5931 /* sanity check # of channels*/ 5955 /* sanity check # of channels*/
5932 if (p->channels < 1 || p->channels > AUDIO_MAX_CHANNELS) 5956 if (p->channels < 1 || p->channels > AUDIO_MAX_CHANNELS)
5933 return EINVAL; 5957 return EINVAL;
5934 5958
5935 return 0; 5959 return 0;
5936} 5960}
5937 5961
5938/* 5962/*
5939 * Initialize playback and record mixers. 5963 * Initialize playback and record mixers.
5940 * mode (AUMODE_{PLAY,RECORD}) indicates the mixer to be initalized. 5964 * mode (AUMODE_{PLAY,RECORD}) indicates the mixer to be initalized.
5941 * phwfmt and rhwfmt indicate the hardware format. pfil and rfil indicate 5965 * phwfmt and rhwfmt indicate the hardware format. pfil and rfil indicate
5942 * the filter registration information. These four must not be NULL. 5966 * the filter registration information. These four must not be NULL.
5943 * If successful returns 0. Otherwise returns errno. 5967 * If successful returns 0. Otherwise returns errno.
5944 * Must be called with sc_lock held. 5968 * Must be called with sc_lock held.
5945 * Must not be called if there are any tracks. 5969 * Must not be called if there are any tracks.
5946 * Caller should check that the initialization succeed by whether 5970 * Caller should check that the initialization succeed by whether
5947 * sc_[pr]mixer is not NULL. 5971 * sc_[pr]mixer is not NULL.
5948 */ 5972 */
5949static int 5973static int
5950audio_mixers_init(struct audio_softc *sc, int mode, 5974audio_mixers_init(struct audio_softc *sc, int mode,
5951 const audio_format2_t *phwfmt, const audio_format2_t *rhwfmt, 5975 const audio_format2_t *phwfmt, const audio_format2_t *rhwfmt,
5952 const audio_filter_reg_t *pfil, const audio_filter_reg_t *rfil) 5976 const audio_filter_reg_t *pfil, const audio_filter_reg_t *rfil)
5953{ 5977{
5954 int error; 5978 int error;
5955 5979
5956 KASSERT(phwfmt != NULL); 5980 KASSERT(phwfmt != NULL);
5957 KASSERT(rhwfmt != NULL); 5981 KASSERT(rhwfmt != NULL);
5958 KASSERT(pfil != NULL); 5982 KASSERT(pfil != NULL);
5959 KASSERT(rfil != NULL); 5983 KASSERT(rfil != NULL);
5960 KASSERT(mutex_owned(sc->sc_lock)); 5984 KASSERT(mutex_owned(sc->sc_lock));
5961 5985
5962 if ((mode & AUMODE_PLAY)) { 5986 if ((mode & AUMODE_PLAY)) {
5963 if (sc->sc_pmixer == NULL) { 5987 if (sc->sc_pmixer == NULL) {
5964 sc->sc_pmixer = kmem_zalloc(sizeof(*sc->sc_pmixer), 5988 sc->sc_pmixer = kmem_zalloc(sizeof(*sc->sc_pmixer),
5965 KM_SLEEP); 5989 KM_SLEEP);
5966 } else { 5990 } else {
5967 /* destroy() doesn't free memory. */ 5991 /* destroy() doesn't free memory. */
5968 audio_mixer_destroy(sc, sc->sc_pmixer); 5992 audio_mixer_destroy(sc, sc->sc_pmixer);
5969 memset(sc->sc_pmixer, 0, sizeof(*sc->sc_pmixer)); 5993 memset(sc->sc_pmixer, 0, sizeof(*sc->sc_pmixer));
5970 } 5994 }
5971 error = audio_mixer_init(sc, AUMODE_PLAY, phwfmt, pfil); 5995 error = audio_mixer_init(sc, AUMODE_PLAY, phwfmt, pfil);
5972 if (error) { 5996 if (error) {
5973 aprint_error_dev(sc->sc_dev, 5997 aprint_error_dev(sc->sc_dev,
5974 "configuring playback mode failed\n"); 5998 "configuring playback mode failed\n");
5975 kmem_free(sc->sc_pmixer, sizeof(*sc->sc_pmixer)); 5999 kmem_free(sc->sc_pmixer, sizeof(*sc->sc_pmixer));
5976 sc->sc_pmixer = NULL; 6000 sc->sc_pmixer = NULL;
5977 return error; 6001 return error;
5978 } 6002 }
5979 } 6003 }
5980 if ((mode & AUMODE_RECORD)) { 6004 if ((mode & AUMODE_RECORD)) {
5981 if (sc->sc_rmixer == NULL) { 6005 if (sc->sc_rmixer == NULL) {
5982 sc->sc_rmixer = kmem_zalloc(sizeof(*sc->sc_rmixer), 6006 sc->sc_rmixer = kmem_zalloc(sizeof(*sc->sc_rmixer),
5983 KM_SLEEP); 6007 KM_SLEEP);
5984 } else { 6008 } else {
5985 /* destroy() doesn't free memory. */ 6009 /* destroy() doesn't free memory. */
5986 audio_mixer_destroy(sc, sc->sc_rmixer); 6010 audio_mixer_destroy(sc, sc->sc_rmixer);
5987 memset(sc->sc_rmixer, 0, sizeof(*sc->sc_rmixer)); 6011 memset(sc->sc_rmixer, 0, sizeof(*sc->sc_rmixer));
5988 } 6012 }
5989 error = audio_mixer_init(sc, AUMODE_RECORD, rhwfmt, rfil); 6013 error = audio_mixer_init(sc, AUMODE_RECORD, rhwfmt, rfil);
5990 if (error) { 6014 if (error) {
5991 aprint_error_dev(sc->sc_dev, 6015 aprint_error_dev(sc->sc_dev,
5992 "configuring record mode failed\n"); 6016 "configuring record mode failed\n");
5993 kmem_free(sc->sc_rmixer, sizeof(*sc->sc_rmixer)); 6017 kmem_free(sc->sc_rmixer, sizeof(*sc->sc_rmixer));
5994 sc->sc_rmixer = NULL; 6018 sc->sc_rmixer = NULL;
5995 return error; 6019 return error;
5996 } 6020 }
5997 } 6021 }
5998 6022
5999 return 0; 6023 return 0;
6000} 6024}
6001 6025
6002/* 6026/*
6003 * Select a frequency. 6027 * Select a frequency.
6004 * Prioritize 48kHz and 44.1kHz. Otherwise choose the highest one. 6028 * Prioritize 48kHz and 44.1kHz. Otherwise choose the highest one.
6005 * XXX Better algorithm? 6029 * XXX Better algorithm?
6006 */ 6030 */
6007static int 6031static int
6008audio_select_freq(const struct audio_format *fmt) 6032audio_select_freq(const struct audio_format *fmt)
6009{ 6033{
6010 int freq; 6034 int freq;
6011 int high; 6035 int high;
6012 int low; 6036 int low;
6013 int j; 6037 int j;
6014 6038
6015 if (fmt->frequency_type == 0) { 6039 if (fmt->frequency_type == 0) {
6016 low = fmt->frequency[0]; 6040 low = fmt->frequency[0];
6017 high = fmt->frequency[1]; 6041 high = fmt->frequency[1];
6018 freq = 48000; 6042 freq = 48000;
6019 if (low <= freq && freq <= high) { 6043 if (low <= freq && freq <= high) {
6020 return freq; 6044 return freq;
6021 } 6045 }
6022 freq = 44100; 6046 freq = 44100;
6023 if (low <= freq && freq <= high) { 6047 if (low <= freq && freq <= high) {
6024 return freq; 6048 return freq;
6025 } 6049 }
6026 return high; 6050 return high;
6027 } else { 6051 } else {
6028 for (j = 0; j < fmt->frequency_type; j++) { 6052 for (j = 0; j < fmt->frequency_type; j++) {
6029 if (fmt->frequency[j] == 48000) { 6053 if (fmt->frequency[j] == 48000) {
6030 return fmt->frequency[j]; 6054 return fmt->frequency[j];
6031 } 6055 }
6032 } 6056 }
6033 high = 0; 6057 high = 0;
6034 for (j = 0; j < fmt->frequency_type; j++) { 6058 for (j = 0; j < fmt->frequency_type; j++) {
6035 if (fmt->frequency[j] == 44100) { 6059 if (fmt->frequency[j] == 44100) {
6036 return fmt->frequency[j]; 6060 return fmt->frequency[j];
6037 } 6061 }
6038 if (fmt->frequency[j] > high) { 6062 if (fmt->frequency[j] > high) {
6039 high = fmt->frequency[j]; 6063 high = fmt->frequency[j];
6040 } 6064 }
6041 } 6065 }
6042 return high; 6066 return high;
6043 } 6067 }
6044} 6068}
6045 6069
6046/* 6070/*
6047 * Probe playback and/or recording format (depending on *modep). 6071 * Probe playback and/or recording format (depending on *modep).
6048 * *modep is an in-out parameter. It indicates the direction to configure 6072 * *modep is an in-out parameter. It indicates the direction to configure
6049 * as an argument, and the direction configured is written back as out 6073 * as an argument, and the direction configured is written back as out
6050 * parameter. 6074 * parameter.
6051 * If successful, probed hardware format is stored into *phwfmt, *rhwfmt 6075 * If successful, probed hardware format is stored into *phwfmt, *rhwfmt
6052 * depending on *modep, and return 0. Otherwise it returns errno. 6076 * depending on *modep, and return 0. Otherwise it returns errno.
6053 * Must be called with sc_lock held. 6077 * Must be called with sc_lock held.
6054 */ 6078 */
6055static int 6079static int
6056audio_hw_probe(struct audio_softc *sc, int is_indep, int *modep, 6080audio_hw_probe(struct audio_softc *sc, int is_indep, int *modep,
6057 audio_format2_t *phwfmt, audio_format2_t *rhwfmt) 6081 audio_format2_t *phwfmt, audio_format2_t *rhwfmt)
6058{ 6082{
6059 audio_format2_t fmt; 6083 audio_format2_t fmt;
6060 int mode; 6084 int mode;
6061 int error = 0; 6085 int error = 0;
6062 6086
6063 KASSERT(mutex_owned(sc->sc_lock)); 6087 KASSERT(mutex_owned(sc->sc_lock));
6064 6088
6065 mode = *modep; 6089 mode = *modep;
6066 KASSERTMSG((mode & (AUMODE_PLAY | AUMODE_RECORD)) != 0, 6090 KASSERTMSG((mode & (AUMODE_PLAY | AUMODE_RECORD)) != 0,
6067 "invalid mode = %x", mode); 6091 "invalid mode = %x", mode);
6068 6092
6069 if (is_indep) { 6093 if (is_indep) {
6070 int errorp = 0, errorr = 0; 6094 int errorp = 0, errorr = 0;
6071 6095
6072 /* On independent devices, probe separately. */ 6096 /* On independent devices, probe separately. */
6073 if ((mode & AUMODE_PLAY) != 0) { 6097 if ((mode & AUMODE_PLAY) != 0) {
6074 errorp = audio_hw_probe_fmt(sc, phwfmt, AUMODE_PLAY); 6098 errorp = audio_hw_probe_fmt(sc, phwfmt, AUMODE_PLAY);
6075 if (errorp) 6099 if (errorp)
6076 mode &= ~AUMODE_PLAY; 6100 mode &= ~AUMODE_PLAY;
6077 } 6101 }
6078 if ((mode & AUMODE_RECORD) != 0) { 6102 if ((mode & AUMODE_RECORD) != 0) {
6079 errorr = audio_hw_probe_fmt(sc, rhwfmt, AUMODE_RECORD); 6103 errorr = audio_hw_probe_fmt(sc, rhwfmt, AUMODE_RECORD);
6080 if (errorr) 6104 if (errorr)
6081 mode &= ~AUMODE_RECORD; 6105 mode &= ~AUMODE_RECORD;
6082 } 6106 }
6083 6107
6084 /* Return error if both play and record probes failed. */ 6108 /* Return error if both play and record probes failed. */
6085 if (errorp && errorr) 6109 if (errorp && errorr)
6086 error = errorp; 6110 error = errorp;
6087 } else { 6111 } else {
6088 /* On non independent devices, probe simultaneously. */ 6112 /* On non independent devices, probe simultaneously. */
6089 error = audio_hw_probe_fmt(sc, &fmt, mode); 6113 error = audio_hw_probe_fmt(sc, &fmt, mode);
6090 if (error) { 6114 if (error) {
6091 mode = 0; 6115 mode = 0;
6092 } else { 6116 } else {
6093 *phwfmt = fmt; 6117 *phwfmt = fmt;
6094 *rhwfmt = fmt; 6118 *rhwfmt = fmt;
6095 } 6119 }
6096 } 6120 }
6097 6121
6098 *modep = mode; 6122 *modep = mode;
6099 return error; 6123 return error;
6100} 6124}
6101 6125
6102/* 6126/*
6103 * Choose the most preferred hardware format. 6127 * Choose the most preferred hardware format.
6104 * If successful, it will store the chosen format into *cand and return 0. 6128 * If successful, it will store the chosen format into *cand and return 0.
6105 * Otherwise, return errno. 6129 * Otherwise, return errno.
6106 * Must be called with sc_lock held. 6130 * Must be called with sc_lock held.
6107 */ 6131 */
6108static int 6132static int
6109audio_hw_probe_fmt(struct audio_softc *sc, audio_format2_t *cand, int mode) 6133audio_hw_probe_fmt(struct audio_softc *sc, audio_format2_t *cand, int mode)
6110{ 6134{
6111 audio_format_query_t query; 6135 audio_format_query_t query;
6112 int cand_score; 6136 int cand_score;
6113 int score; 6137 int score;
6114 int i; 6138 int i;
6115 int error; 6139 int error;
6116 6140
6117 KASSERT(mutex_owned(sc->sc_lock)); 6141 KASSERT(mutex_owned(sc->sc_lock));
6118 6142
6119 /* 6143 /*
6120 * Score each formats and choose the highest one. 6144 * Score each formats and choose the highest one.
6121 * 6145 *
6122 * +---- priority(0-3) 6146 * +---- priority(0-3)
6123 * |+--- encoding/precision 6147 * |+--- encoding/precision
6124 * ||+-- channels 6148 * ||+-- channels
6125 * score = 0x000000PEC 6149 * score = 0x000000PEC
6126 */ 6150 */
6127 6151
6128 cand_score = 0; 6152 cand_score = 0;
6129 for (i = 0; ; i++) { 6153 for (i = 0; ; i++) {
6130 memset(&query, 0, sizeof(query)); 6154 memset(&query, 0, sizeof(query));
6131 query.index = i; 6155 query.index = i;
6132 6156
6133 error = sc->hw_if->query_format(sc->hw_hdl, &query); 6157 error = sc->hw_if->query_format(sc->hw_hdl, &query);
6134 if (error == EINVAL) 6158 if (error == EINVAL)
6135 break; 6159 break;
6136 if (error) 6160 if (error)
6137 return error; 6161 return error;
6138 6162
6139#if defined(AUDIO_DEBUG) 6163#if defined(AUDIO_DEBUG)
6140 DPRINTF(1, "fmt[%d] %c%c pri=%d %s,%d/%dbit,%dch,", i, 6164 DPRINTF(1, "fmt[%d] %c%c pri=%d %s,%d/%dbit,%dch,", i,
6141 (query.fmt.mode & AUMODE_PLAY) ? 'P' : '-', 6165 (query.fmt.mode & AUMODE_PLAY) ? 'P' : '-',
6142 (query.fmt.mode & AUMODE_RECORD) ? 'R' : '-', 6166 (query.fmt.mode & AUMODE_RECORD) ? 'R' : '-',
6143 query.fmt.priority, 6167 query.fmt.priority,
6144 audio_encoding_name(query.fmt.encoding), 6168 audio_encoding_name(query.fmt.encoding),
6145 query.fmt.validbits, 6169 query.fmt.validbits,
6146 query.fmt.precision, 6170 query.fmt.precision,
6147 query.fmt.channels); 6171 query.fmt.channels);
6148 if (query.fmt.frequency_type == 0) { 6172 if (query.fmt.frequency_type == 0) {
6149 DPRINTF(1, "{%d-%d", 6173 DPRINTF(1, "{%d-%d",
6150 query.fmt.frequency[0], query.fmt.frequency[1]); 6174 query.fmt.frequency[0], query.fmt.frequency[1]);
6151 } else { 6175 } else {
6152 int j; 6176 int j;
6153 for (j = 0; j < query.fmt.frequency_type; j++) { 6177 for (j = 0; j < query.fmt.frequency_type; j++) {
6154 DPRINTF(1, "%c%d", 6178 DPRINTF(1, "%c%d",
6155 (j == 0) ? '{' : ',', 6179 (j == 0) ? '{' : ',',
6156 query.fmt.frequency[j]); 6180 query.fmt.frequency[j]);
6157 } 6181 }
6158 } 6182 }
6159 DPRINTF(1, "}\n"); 6183 DPRINTF(1, "}\n");
6160#endif 6184#endif
6161 6185
6162 if ((query.fmt.mode & mode) == 0) { 6186 if ((query.fmt.mode & mode) == 0) {
6163 DPRINTF(1, "fmt[%d] skip; mode not match %d\n", i, 6187 DPRINTF(1, "fmt[%d] skip; mode not match %d\n", i,
6164 mode); 6188 mode);
6165 continue; 6189 continue;
6166 } 6190 }
6167 6191
6168 if (query.fmt.priority < 0) { 6192 if (query.fmt.priority < 0) {
6169 DPRINTF(1, "fmt[%d] skip; unsupported encoding\n", i); 6193 DPRINTF(1, "fmt[%d] skip; unsupported encoding\n", i);
6170 continue; 6194 continue;
6171 } 6195 }
6172 6196
6173 /* Score */ 6197 /* Score */
6174 score = (query.fmt.priority & 3) * 0x100; 6198 score = (query.fmt.priority & 3) * 0x100;
6175 if (query.fmt.encoding == AUDIO_ENCODING_SLINEAR_NE && 6199 if (query.fmt.encoding == AUDIO_ENCODING_SLINEAR_NE &&
6176 query.fmt.validbits == AUDIO_INTERNAL_BITS && 6200 query.fmt.validbits == AUDIO_INTERNAL_BITS &&
6177 query.fmt.precision == AUDIO_INTERNAL_BITS) { 6201 query.fmt.precision == AUDIO_INTERNAL_BITS) {
6178 score += 0x20; 6202 score += 0x20;
6179 } else if (query.fmt.encoding == AUDIO_ENCODING_SLINEAR_OE && 6203 } else if (query.fmt.encoding == AUDIO_ENCODING_SLINEAR_OE &&
6180 query.fmt.validbits == AUDIO_INTERNAL_BITS && 6204 query.fmt.validbits == AUDIO_INTERNAL_BITS &&
6181 query.fmt.precision == AUDIO_INTERNAL_BITS) { 6205 query.fmt.precision == AUDIO_INTERNAL_BITS) {
6182 score += 0x10; 6206 score += 0x10;
6183 } 6207 }
6184 score += query.fmt.channels; 6208 score += query.fmt.channels;
6185 6209
6186 if (score < cand_score) { 6210 if (score < cand_score) {
6187 DPRINTF(1, "fmt[%d] skip; score 0x%x < 0x%x\n", i, 6211 DPRINTF(1, "fmt[%d] skip; score 0x%x < 0x%x\n", i,
6188 score, cand_score); 6212 score, cand_score);
6189 continue; 6213 continue;
6190 } 6214 }
6191 6215
6192 /* Update candidate */ 6216 /* Update candidate */
6193 cand_score = score; 6217 cand_score = score;
6194 cand->encoding = query.fmt.encoding; 6218 cand->encoding = query.fmt.encoding;
6195 cand->precision = query.fmt.validbits; 6219 cand->precision = query.fmt.validbits;
6196 cand->stride = query.fmt.precision; 6220 cand->stride = query.fmt.precision;
6197 cand->channels = query.fmt.channels; 6221 cand->channels = query.fmt.channels;
6198 cand->sample_rate = audio_select_freq(&query.fmt); 6222 cand->sample_rate = audio_select_freq(&query.fmt);
6199 DPRINTF(1, "fmt[%d] candidate (score=0x%x)" 6223 DPRINTF(1, "fmt[%d] candidate (score=0x%x)"
6200 " pri=%d %s,%d/%d,%dch,%dHz\n", i, 6224 " pri=%d %s,%d/%d,%dch,%dHz\n", i,
6201 cand_score, query.fmt.priority, 6225 cand_score, query.fmt.priority,
6202 audio_encoding_name(query.fmt.encoding), 6226 audio_encoding_name(query.fmt.encoding),
6203 cand->precision, cand->stride, 6227 cand->precision, cand->stride,
6204 cand->channels, cand->sample_rate); 6228 cand->channels, cand->sample_rate);
6205 } 6229 }
6206 6230
6207 if (cand_score == 0) { 6231 if (cand_score == 0) {
6208 DPRINTF(1, "%s no fmt\n", __func__); 6232 DPRINTF(1, "%s no fmt\n", __func__);
6209 return ENXIO; 6233 return ENXIO;
6210 } 6234 }
6211 DPRINTF(1, "%s selected: %s,%d/%d,%dch,%dHz\n", __func__, 6235 DPRINTF(1, "%s selected: %s,%d/%d,%dch,%dHz\n", __func__,
6212 audio_encoding_name(cand->encoding), 6236 audio_encoding_name(cand->encoding),
6213 cand->precision, cand->stride, cand->channels, cand->sample_rate); 6237 cand->precision, cand->stride, cand->channels, cand->sample_rate);
6214 return 0; 6238 return 0;
6215} 6239}
6216 6240
6217/* 6241/*
6218 * Validate fmt with query_format. 6242 * Validate fmt with query_format.
6219 * If fmt is included in the result of query_format, returns 0. 6243 * If fmt is included in the result of query_format, returns 0.
6220 * Otherwise returns EINVAL. 6244 * Otherwise returns EINVAL.
6221 * Must be called with sc_lock held. 6245 * Must be called with sc_lock held.
6222 */  6246 */
6223static int 6247static int
6224audio_hw_validate_format(struct audio_softc *sc, int mode, 6248audio_hw_validate_format(struct audio_softc *sc, int mode,
6225 const audio_format2_t *fmt) 6249 const audio_format2_t *fmt)
6226{ 6250{
6227 audio_format_query_t query; 6251 audio_format_query_t query;
6228 struct audio_format *q; 6252 struct audio_format *q;
6229 int index; 6253 int index;
6230 int error; 6254 int error;
6231 int j; 6255 int j;
6232 6256
6233 KASSERT(mutex_owned(sc->sc_lock)); 6257 KASSERT(mutex_owned(sc->sc_lock));
6234 6258
6235 /* 6259 /*
6236 * If query_format is not supported by hardware driver, 6260 * If query_format is not supported by hardware driver,
6237 * a rough check instead will be performed. 6261 * a rough check instead will be performed.
6238 * XXX This will gone in the future. 6262 * XXX This will gone in the future.
6239 */ 6263 */
6240 if (sc->hw_if->query_format == NULL) { 6264 if (sc->hw_if->query_format == NULL) {
6241 if (fmt->encoding != AUDIO_ENCODING_SLINEAR_NE) 6265 if (fmt->encoding != AUDIO_ENCODING_SLINEAR_NE)
6242 return EINVAL; 6266 return EINVAL;
6243 if (fmt->precision != AUDIO_INTERNAL_BITS) 6267 if (fmt->precision != AUDIO_INTERNAL_BITS)
6244 return EINVAL; 6268 return EINVAL;
6245 if (fmt->stride != AUDIO_INTERNAL_BITS) 6269 if (fmt->stride != AUDIO_INTERNAL_BITS)
6246 return EINVAL; 6270 return EINVAL;
6247 return 0; 6271 return 0;
6248 } 6272 }
6249 6273
6250 for (index = 0; ; index++) { 6274 for (index = 0; ; index++) {
6251 query.index = index; 6275 query.index = index;
6252 error = sc->hw_if->query_format(sc->hw_hdl, &query); 6276 error = sc->hw_if->query_format(sc->hw_hdl, &query);
6253 if (error == EINVAL) 6277 if (error == EINVAL)
6254 break; 6278 break;
6255 if (error) 6279 if (error)
6256 return error; 6280 return error;
6257 6281
6258 q = &query.fmt; 6282 q = &query.fmt;
6259 /* 6283 /*
6260 * Note that fmt is audio_format2_t (precision/stride) but 6284 * Note that fmt is audio_format2_t (precision/stride) but
6261 * q is audio_format_t (validbits/precision). 6285 * q is audio_format_t (validbits/precision).
6262 */ 6286 */
6263 if ((q->mode & mode) == 0) { 6287 if ((q->mode & mode) == 0) {
6264 continue; 6288 continue;
6265 } 6289 }
6266 if (fmt->encoding != q->encoding) { 6290 if (fmt->encoding != q->encoding) {
6267 continue; 6291 continue;
6268 } 6292 }
6269 if (fmt->precision != q->validbits) { 6293 if (fmt->precision != q->validbits) {
6270 continue; 6294 continue;
6271 } 6295 }
6272 if (fmt->stride != q->precision) { 6296 if (fmt->stride != q->precision) {
6273 continue; 6297 continue;
6274 } 6298 }
6275 if (fmt->channels != q->channels) { 6299 if (fmt->channels != q->channels) {
6276 continue; 6300 continue;
6277 } 6301 }
6278 if (q->frequency_type == 0) { 6302 if (q->frequency_type == 0) {
6279 if (fmt->sample_rate < q->frequency[0] || 6303 if (fmt->sample_rate < q->frequency[0] ||
6280 fmt->sample_rate > q->frequency[1]) { 6304 fmt->sample_rate > q->frequency[1]) {
6281 continue; 6305 continue;
6282 } 6306 }
6283 } else { 6307 } else {
6284 for (j = 0; j < q->frequency_type; j++) { 6308 for (j = 0; j < q->frequency_type; j++) {
6285 if (fmt->sample_rate == q->frequency[j]) 6309 if (fmt->sample_rate == q->frequency[j])
6286 break; 6310 break;
6287 } 6311 }
6288 if (j == query.fmt.frequency_type) { 6312 if (j == query.fmt.frequency_type) {
6289 continue; 6313 continue;
6290 } 6314 }
6291 } 6315 }
6292 6316
6293 /* Matched. */ 6317 /* Matched. */
6294 return 0; 6318 return 0;
6295 } 6319 }
6296 6320
6297 return EINVAL; 6321 return EINVAL;
6298} 6322}
6299 6323
6300/* 6324/*
6301 * Set track mixer's format depending on ai->mode. 6325 * Set track mixer's format depending on ai->mode.
6302 * If AUMODE_PLAY is set in ai->mode, it set up the playback mixer 6326 * If AUMODE_PLAY is set in ai->mode, it set up the playback mixer
6303 * with ai.play.{channels, sample_rate}. 6327 * with ai.play.{channels, sample_rate}.
6304 * If AUMODE_RECORD is set in ai->mode, it set up the recording mixer 6328 * If AUMODE_RECORD is set in ai->mode, it set up the recording mixer
6305 * with ai.record.{channels, sample_rate}. 6329 * with ai.record.{channels, sample_rate}.
6306 * All other fields in ai are ignored. 6330 * All other fields in ai are ignored.
6307 * If successful returns 0. Otherwise returns errno. 6331 * If successful returns 0. Otherwise returns errno.
6308 * This function does not roll back even if it fails. 6332 * This function does not roll back even if it fails.
6309 * Must be called with sc_lock held. 6333 * Must be called with sc_lock held.
6310 */ 6334 */
6311static int 6335static int
6312audio_mixers_set_format(struct audio_softc *sc, const struct audio_info *ai) 6336audio_mixers_set_format(struct audio_softc *sc, const struct audio_info *ai)
6313{ 6337{
6314 audio_format2_t phwfmt; 6338 audio_format2_t phwfmt;
6315 audio_format2_t rhwfmt; 6339 audio_format2_t rhwfmt;
6316 audio_filter_reg_t pfil; 6340 audio_filter_reg_t pfil;
6317 audio_filter_reg_t rfil; 6341 audio_filter_reg_t rfil;
6318 int mode; 6342 int mode;
6319 int error; 6343 int error;
6320 6344
6321 KASSERT(mutex_owned(sc->sc_lock)); 6345 KASSERT(mutex_owned(sc->sc_lock));
6322 6346
6323 /* 6347 /*
6324 * Even when setting either one of playback and recording, 6348 * Even when setting either one of playback and recording,
6325 * both must be halted. 6349 * both must be halted.
6326 */ 6350 */
6327 if (sc->sc_popens + sc->sc_ropens > 0) 6351 if (sc->sc_popens + sc->sc_ropens > 0)
6328 return EBUSY; 6352 return EBUSY;
6329 6353
6330 if (!SPECIFIED(ai->mode) || ai->mode == 0) 6354 if (!SPECIFIED(ai->mode) || ai->mode == 0)
6331 return ENOTTY; 6355 return ENOTTY;
6332 6356
6333 /* Only channels and sample_rate are changeable. */ 6357 /* Only channels and sample_rate are changeable. */
6334 mode = ai->mode; 6358 mode = ai->mode;
6335 if ((mode & AUMODE_PLAY)) { 6359 if ((mode & AUMODE_PLAY)) {
6336 phwfmt.encoding = ai->play.encoding; 6360 phwfmt.encoding = ai->play.encoding;
6337 phwfmt.precision = ai->play.precision; 6361 phwfmt.precision = ai->play.precision;
6338 phwfmt.stride = ai->play.precision; 6362 phwfmt.stride = ai->play.precision;
6339 phwfmt.channels = ai->play.channels; 6363 phwfmt.channels = ai->play.channels;
6340 phwfmt.sample_rate = ai->play.sample_rate; 6364 phwfmt.sample_rate = ai->play.sample_rate;
6341 } 6365 }
6342 if ((mode & AUMODE_RECORD)) { 6366 if ((mode & AUMODE_RECORD)) {
6343 rhwfmt.encoding = ai->record.encoding; 6367 rhwfmt.encoding = ai->record.encoding;
6344 rhwfmt.precision = ai->record.precision; 6368 rhwfmt.precision = ai->record.precision;
6345 rhwfmt.stride = ai->record.precision; 6369 rhwfmt.stride = ai->record.precision;
6346 rhwfmt.channels = ai->record.channels; 6370 rhwfmt.channels = ai->record.channels;
6347 rhwfmt.sample_rate = ai->record.sample_rate; 6371 rhwfmt.sample_rate = ai->record.sample_rate;
6348 } 6372 }
6349 6373
6350 /* On non-independent devices, use the same format for both. */ 6374 /* On non-independent devices, use the same format for both. */
6351 if ((sc->sc_props & AUDIO_PROP_INDEPENDENT) == 0) { 6375 if ((sc->sc_props & AUDIO_PROP_INDEPENDENT) == 0) {
6352 if (mode == AUMODE_RECORD) { 6376 if (mode == AUMODE_RECORD) {
6353 phwfmt = rhwfmt; 6377 phwfmt = rhwfmt;
6354 } else { 6378 } else {
6355 rhwfmt = phwfmt; 6379 rhwfmt = phwfmt;
6356 } 6380 }
6357 mode = AUMODE_PLAY | AUMODE_RECORD; 6381 mode = AUMODE_PLAY | AUMODE_RECORD;
6358 } 6382 }
6359 6383
6360 /* Then, unset the direction not exist on the hardware. */ 6384 /* Then, unset the direction not exist on the hardware. */
6361 if ((sc->sc_props & AUDIO_PROP_PLAYBACK) == 0) 6385 if ((sc->sc_props & AUDIO_PROP_PLAYBACK) == 0)
6362 mode &= ~AUMODE_PLAY; 6386 mode &= ~AUMODE_PLAY;
6363 if ((sc->sc_props & AUDIO_PROP_CAPTURE) == 0) 6387 if ((sc->sc_props & AUDIO_PROP_CAPTURE) == 0)
6364 mode &= ~AUMODE_RECORD; 6388 mode &= ~AUMODE_RECORD;
6365 6389
6366 /* debug */ 6390 /* debug */
6367 if ((mode & AUMODE_PLAY)) { 6391 if ((mode & AUMODE_PLAY)) {
6368 TRACE(1, "play=%s/%d/%d/%dch/%dHz", 6392 TRACE(1, "play=%s/%d/%d/%dch/%dHz",
6369 audio_encoding_name(phwfmt.encoding), 6393 audio_encoding_name(phwfmt.encoding),
6370 phwfmt.precision, 6394 phwfmt.precision,
6371 phwfmt.stride, 6395 phwfmt.stride,
6372 phwfmt.channels, 6396 phwfmt.channels,
6373 phwfmt.sample_rate); 6397 phwfmt.sample_rate);
6374 } 6398 }
6375 if ((mode & AUMODE_RECORD)) { 6399 if ((mode & AUMODE_RECORD)) {
6376 TRACE(1, "rec =%s/%d/%d/%dch/%dHz", 6400 TRACE(1, "rec =%s/%d/%d/%dch/%dHz",
6377 audio_encoding_name(rhwfmt.encoding), 6401 audio_encoding_name(rhwfmt.encoding),
6378 rhwfmt.precision, 6402 rhwfmt.precision,
6379 rhwfmt.stride, 6403 rhwfmt.stride,
6380 rhwfmt.channels, 6404 rhwfmt.channels,
6381 rhwfmt.sample_rate); 6405 rhwfmt.sample_rate);
6382 } 6406 }
6383 6407
6384 /* Check the format */ 6408 /* Check the format */
6385 if ((mode & AUMODE_PLAY)) { 6409 if ((mode & AUMODE_PLAY)) {
6386 if (audio_hw_validate_format(sc, AUMODE_PLAY, &phwfmt)) { 6410 if (audio_hw_validate_format(sc, AUMODE_PLAY, &phwfmt)) {
6387 TRACE(1, "invalid format"); 6411 TRACE(1, "invalid format");
6388 return EINVAL; 6412 return EINVAL;
6389 } 6413 }
6390 } 6414 }
6391 if ((mode & AUMODE_RECORD)) { 6415 if ((mode & AUMODE_RECORD)) {
6392 if (audio_hw_validate_format(sc, AUMODE_RECORD, &rhwfmt)) { 6416 if (audio_hw_validate_format(sc, AUMODE_RECORD, &rhwfmt)) {
6393 TRACE(1, "invalid format"); 6417 TRACE(1, "invalid format");
6394 return EINVAL; 6418 return EINVAL;
6395 } 6419 }
6396 } 6420 }
6397 6421
6398 /* Configure the mixers. */ 6422 /* Configure the mixers. */
6399 memset(&pfil, 0, sizeof(pfil)); 6423 memset(&pfil, 0, sizeof(pfil));
6400 memset(&rfil, 0, sizeof(rfil)); 6424 memset(&rfil, 0, sizeof(rfil));
6401 error = audio_hw_set_format(sc, mode, &phwfmt, &rhwfmt, &pfil, &rfil); 6425 error = audio_hw_set_format(sc, mode, &phwfmt, &rhwfmt, &pfil, &rfil);
6402 if (error) 6426 if (error)
6403 return error; 6427 return error;
6404 6428
6405 error = audio_mixers_init(sc, mode, &phwfmt, &rhwfmt, &pfil, &rfil); 6429 error = audio_mixers_init(sc, mode, &phwfmt, &rhwfmt, &pfil, &rfil);
6406 if (error) 6430 if (error)
6407 return error; 6431 return error;
6408 6432
6409 return 0; 6433 return 0;
6410} 6434}
6411 6435
6412/* 6436/*
6413 * Store current mixers format into *ai. 6437 * Store current mixers format into *ai.
6414 */ 6438 */
6415static void 6439static void
6416audio_mixers_get_format(struct audio_softc *sc, struct audio_info *ai) 6440audio_mixers_get_format(struct audio_softc *sc, struct audio_info *ai)
6417{ 6441{
6418 /* 6442 /*
6419 * There is no stride information in audio_info but it doesn't matter. 6443 * There is no stride information in audio_info but it doesn't matter.
6420 * trackmixer always treats stride and precision as the same. 6444 * trackmixer always treats stride and precision as the same.
6421 */ 6445 */
6422 AUDIO_INITINFO(ai); 6446 AUDIO_INITINFO(ai);
6423 ai->mode = 0; 6447 ai->mode = 0;
6424 if (sc->sc_pmixer) { 6448 if (sc->sc_pmixer) {
6425 audio_format2_t *fmt = &sc->sc_pmixer->track_fmt; 6449 audio_format2_t *fmt = &sc->sc_pmixer->track_fmt;
6426 ai->play.encoding = fmt->encoding; 6450 ai->play.encoding = fmt->encoding;
6427 ai->play.precision = fmt->precision; 6451 ai->play.precision = fmt->precision;
6428 ai->play.channels = fmt->channels; 6452 ai->play.channels = fmt->channels;
6429 ai->play.sample_rate = fmt->sample_rate; 6453 ai->play.sample_rate = fmt->sample_rate;
6430 ai->mode |= AUMODE_PLAY; 6454 ai->mode |= AUMODE_PLAY;
6431 } 6455 }
6432 if (sc->sc_rmixer) { 6456 if (sc->sc_rmixer) {
6433 audio_format2_t *fmt = &sc->sc_rmixer->track_fmt; 6457 audio_format2_t *fmt = &sc->sc_rmixer->track_fmt;
6434 ai->record.encoding = fmt->encoding; 6458 ai->record.encoding = fmt->encoding;
6435 ai->record.precision = fmt->precision; 6459 ai->record.precision = fmt->precision;
6436 ai->record.channels = fmt->channels; 6460 ai->record.channels = fmt->channels;
6437 ai->record.sample_rate = fmt->sample_rate; 6461 ai->record.sample_rate = fmt->sample_rate;
6438 ai->mode |= AUMODE_RECORD; 6462 ai->mode |= AUMODE_RECORD;
6439 } 6463 }
6440} 6464}
6441 6465
6442/* 6466/*
6443 * audio_info details: 6467 * audio_info details:
6444 * 6468 *
6445 * ai.{play,record}.sample_rate (R/W) 6469 * ai.{play,record}.sample_rate (R/W)
6446 * ai.{play,record}.encoding (R/W) 6470 * ai.{play,record}.encoding (R/W)
6447 * ai.{play,record}.precision (R/W) 6471 * ai.{play,record}.precision (R/W)
6448 * ai.{play,record}.channels (R/W) 6472 * ai.{play,record}.channels (R/W)
6449 * These specify the playback or recording format. 6473 * These specify the playback or recording format.
6450 * Ignore members within an inactive track. 6474 * Ignore members within an inactive track.
6451 * 6475 *
6452 * ai.mode (R/W) 6476 * ai.mode (R/W)
6453 * It specifies the playback or recording mode, AUMODE_*. 6477 * It specifies the playback or recording mode, AUMODE_*.
6454 * Currently, a mode change operation by ai.mode after opening is 6478 * Currently, a mode change operation by ai.mode after opening is
6455 * prohibited. In addition, AUMODE_PLAY_ALL no longer makes sense. 6479 * prohibited. In addition, AUMODE_PLAY_ALL no longer makes sense.
6456 * However, it's possible to get or to set for backward compatibility. 6480 * However, it's possible to get or to set for backward compatibility.
6457 * 6481 *
6458 * ai.{hiwat,lowat} (R/W) 6482 * ai.{hiwat,lowat} (R/W)
6459 * These specify the high water mark and low water mark for playback 6483 * These specify the high water mark and low water mark for playback
6460 * track. The unit is block. 6484 * track. The unit is block.
6461 * 6485 *
6462 * ai.{play,record}.gain (R/W) 6486 * ai.{play,record}.gain (R/W)
6463 * It specifies the HW mixer volume in 0-255. 6487 * It specifies the HW mixer volume in 0-255.
6464 * It is historical reason that the gain is connected to HW mixer. 6488 * It is historical reason that the gain is connected to HW mixer.
6465 * 6489 *
6466 * ai.{play,record}.balance (R/W) 6490 * ai.{play,record}.balance (R/W)
6467 * It specifies the left-right balance of HW mixer in 0-64. 6491 * It specifies the left-right balance of HW mixer in 0-64.
6468 * 32 means the center. 6492 * 32 means the center.
6469 * It is historical reason that the balance is connected to HW mixer. 6493 * It is historical reason that the balance is connected to HW mixer.
6470 * 6494 *
6471 * ai.{play,record}.port (R/W) 6495 * ai.{play,record}.port (R/W)
6472 * It specifies the input/output port of HW mixer. 6496 * It specifies the input/output port of HW mixer.
6473 * 6497 *
6474 * ai.monitor_gain (R/W) 6498 * ai.monitor_gain (R/W)
6475 * It specifies the recording monitor gain(?) of HW mixer. 6499 * It specifies the recording monitor gain(?) of HW mixer.
6476 * 6500 *
6477 * ai.{play,record}.pause (R/W) 6501 * ai.{play,record}.pause (R/W)
6478 * Non-zero means the track is paused. 6502 * Non-zero means the track is paused.
6479 * 6503 *
6480 * ai.play.seek (R/-) 6504 * ai.play.seek (R/-)
6481 * It indicates the number of bytes written but not processed. 6505 * It indicates the number of bytes written but not processed.
6482 * ai.record.seek (R/-) 6506 * ai.record.seek (R/-)
6483 * It indicates the number of bytes to be able to read. 6507 * It indicates the number of bytes to be able to read.
6484 * 6508 *
6485 * ai.{play,record}.avail_ports (R/-) 6509 * ai.{play,record}.avail_ports (R/-)
6486 * Mixer info. 6510 * Mixer info.
6487 * 6511 *
6488 * ai.{play,record}.buffer_size (R/-) 6512 * ai.{play,record}.buffer_size (R/-)
6489 * It indicates the buffer size in bytes. Internally it means usrbuf. 6513 * It indicates the buffer size in bytes. Internally it means usrbuf.
6490 * 6514 *
6491 * ai.{play,record}.samples (R/-) 6515 * ai.{play,record}.samples (R/-)
6492 * It indicates the total number of bytes played or recorded. 6516 * It indicates the total number of bytes played or recorded.
6493 * 6517 *
6494 * ai.{play,record}.eof (R/-) 6518 * ai.{play,record}.eof (R/-)
6495 * It indicates the number of times reached EOF(?). 6519 * It indicates the number of times reached EOF(?).
6496 * 6520 *
6497 * ai.{play,record}.error (R/-) 6521 * ai.{play,record}.error (R/-)
6498 * Non-zero indicates overflow/underflow has occured. 6522 * Non-zero indicates overflow/underflow has occured.
6499 * 6523 *
6500 * ai.{play,record}.waiting (R/-) 6524 * ai.{play,record}.waiting (R/-)
6501 * Non-zero indicates that other process waits to open. 6525 * Non-zero indicates that other process waits to open.
6502 * It will never happen anymore. 6526 * It will never happen anymore.
6503 * 6527 *
6504 * ai.{play,record}.open (R/-) 6528 * ai.{play,record}.open (R/-)
6505 * Non-zero indicates the direction is opened by this process(?). 6529 * Non-zero indicates the direction is opened by this process(?).
6506 * XXX Is this better to indicate that "the device is opened by 6530 * XXX Is this better to indicate that "the device is opened by
6507 * at least one process"? 6531 * at least one process"?
6508 * 6532 *
6509 * ai.{play,record}.active (R/-) 6533 * ai.{play,record}.active (R/-)
6510 * Non-zero indicates that I/O is currently active. 6534 * Non-zero indicates that I/O is currently active.
6511 * 6535 *
6512 * ai.blocksize (R/-) 6536 * ai.blocksize (R/-)
6513 * It indicates the block size in bytes. 6537 * It indicates the block size in bytes.
6514 * XXX The blocksize of playback and recording may be different. 6538 * XXX The blocksize of playback and recording may be different.
6515 */ 6539 */
6516 6540
6517/* 6541/*
6518 * Pause consideration: 6542 * Pause consideration:
6519 * 6543 *
6520 * The introduction of these two behavior makes pause/unpause operation 6544 * The introduction of these two behavior makes pause/unpause operation
6521 * simple. 6545 * simple.
6522 * 1. The first read/write access of the first track makes mixer start. 6546 * 1. The first read/write access of the first track makes mixer start.
6523 * 2. A pause of the last track doesn't make mixer stop. 6547 * 2. A pause of the last track doesn't make mixer stop.
6524 */ 6548 */
6525 6549
6526/* 6550/*
6527 * Set both track's parameters within a file depending on ai. 6551 * Set both track's parameters within a file depending on ai.
6528 * Update sc_sound_[pr]* if set. 6552 * Update sc_sound_[pr]* if set.
6529 * Must be called with sc_lock and sc_exlock held. 6553 * Must be called with sc_lock and sc_exlock held.
6530 */ 6554 */
6531static int 6555static int
6532audio_file_setinfo(struct audio_softc *sc, audio_file_t *file, 6556audio_file_setinfo(struct audio_softc *sc, audio_file_t *file,
6533 const struct audio_info *ai) 6557 const struct audio_info *ai)
6534{ 6558{
6535 const struct audio_prinfo *pi; 6559 const struct audio_prinfo *pi;
6536 const struct audio_prinfo *ri; 6560 const struct audio_prinfo *ri;
6537 audio_track_t *ptrack; 6561 audio_track_t *ptrack;
6538 audio_track_t *rtrack; 6562 audio_track_t *rtrack;
6539 audio_format2_t pfmt; 6563 audio_format2_t pfmt;
6540 audio_format2_t rfmt; 6564 audio_format2_t rfmt;
6541 int pchanges; 6565 int pchanges;
6542 int rchanges; 6566 int rchanges;
6543 int mode; 6567 int mode;
6544 struct audio_info saved_ai; 6568 struct audio_info saved_ai;
6545 audio_format2_t saved_pfmt; 6569 audio_format2_t saved_pfmt;
6546 audio_format2_t saved_rfmt; 6570 audio_format2_t saved_rfmt;
6547 int error; 6571 int error;
6548 6572
6549 KASSERT(mutex_owned(sc->sc_lock)); 6573 KASSERT(mutex_owned(sc->sc_lock));
6550 KASSERT(sc->sc_exlock); 6574 KASSERT(sc->sc_exlock);
6551 6575
6552 pi = &ai->play; 6576 pi = &ai->play;
6553 ri = &ai->record; 6577 ri = &ai->record;
6554 pchanges = 0; 6578 pchanges = 0;
6555 rchanges = 0; 6579 rchanges = 0;
6556 6580
6557 ptrack = file->ptrack; 6581 ptrack = file->ptrack;
6558 rtrack = file->rtrack; 6582 rtrack = file->rtrack;
6559 6583
6560#if defined(AUDIO_DEBUG) 6584#if defined(AUDIO_DEBUG)
6561 if (audiodebug >= 2) { 6585 if (audiodebug >= 2) {
6562 char buf[256]; 6586 char buf[256];
6563 char p[64]; 6587 char p[64];
6564 int buflen; 6588 int buflen;
6565 int plen; 6589 int plen;
6566#define SPRINTF(var, fmt...) do { \ 6590#define SPRINTF(var, fmt...) do { \
6567 var##len += snprintf(var + var##len, sizeof(var) - var##len, fmt); \ 6591 var##len += snprintf(var + var##len, sizeof(var) - var##len, fmt); \
6568} while (0) 6592} while (0)
6569 6593
6570 buflen = 0; 6594 buflen = 0;
6571 plen = 0; 6595 plen = 0;
6572 if (SPECIFIED(pi->encoding)) 6596 if (SPECIFIED(pi->encoding))
6573 SPRINTF(p, "/%s", audio_encoding_name(pi->encoding)); 6597 SPRINTF(p, "/%s", audio_encoding_name(pi->encoding));
6574 if (SPECIFIED(pi->precision)) 6598 if (SPECIFIED(pi->precision))
6575 SPRINTF(p, "/%dbit", pi->precision); 6599 SPRINTF(p, "/%dbit", pi->precision);
6576 if (SPECIFIED(pi->channels)) 6600 if (SPECIFIED(pi->channels))
6577 SPRINTF(p, "/%dch", pi->channels); 6601 SPRINTF(p, "/%dch", pi->channels);
6578 if (SPECIFIED(pi->sample_rate)) 6602 if (SPECIFIED(pi->sample_rate))
6579 SPRINTF(p, "/%dHz", pi->sample_rate); 6603 SPRINTF(p, "/%dHz", pi->sample_rate);
6580 if (plen > 0) 6604 if (plen > 0)
6581 SPRINTF(buf, ",play.param=%s", p + 1); 6605 SPRINTF(buf, ",play.param=%s", p + 1);
6582 6606
6583 plen = 0; 6607 plen = 0;
6584 if (SPECIFIED(ri->encoding)) 6608 if (SPECIFIED(ri->encoding))
6585 SPRINTF(p, "/%s", audio_encoding_name(ri->encoding)); 6609 SPRINTF(p, "/%s", audio_encoding_name(ri->encoding));
6586 if (SPECIFIED(ri->precision)) 6610 if (SPECIFIED(ri->precision))
6587 SPRINTF(p, "/%dbit", ri->precision); 6611 SPRINTF(p, "/%dbit", ri->precision);
6588 if (SPECIFIED(ri->channels)) 6612 if (SPECIFIED(ri->channels))
6589 SPRINTF(p, "/%dch", ri->channels); 6613 SPRINTF(p, "/%dch", ri->channels);
6590 if (SPECIFIED(ri->sample_rate)) 6614 if (SPECIFIED(ri->sample_rate))
6591 SPRINTF(p, "/%dHz", ri->sample_rate); 6615 SPRINTF(p, "/%dHz", ri->sample_rate);
6592 if (plen > 0) 6616 if (plen > 0)
6593 SPRINTF(buf, ",record.param=%s", p + 1); 6617 SPRINTF(buf, ",record.param=%s", p + 1);
6594 6618
6595 if (SPECIFIED(ai->mode)) 6619 if (SPECIFIED(ai->mode))
6596 SPRINTF(buf, ",mode=%d", ai->mode); 6620 SPRINTF(buf, ",mode=%d", ai->mode);
6597 if (SPECIFIED(ai->hiwat)) 6621 if (SPECIFIED(ai->hiwat))
6598 SPRINTF(buf, ",hiwat=%d", ai->hiwat); 6622 SPRINTF(buf, ",hiwat=%d", ai->hiwat);
6599 if (SPECIFIED(ai->lowat)) 6623 if (SPECIFIED(ai->lowat))
6600 SPRINTF(buf, ",lowat=%d", ai->lowat); 6624 SPRINTF(buf, ",lowat=%d", ai->lowat);
6601 if (SPECIFIED(ai->play.gain)) 6625 if (SPECIFIED(ai->play.gain))
6602 SPRINTF(buf, ",play.gain=%d", ai->play.gain); 6626 SPRINTF(buf, ",play.gain=%d", ai->play.gain);
6603 if (SPECIFIED(ai->record.gain)) 6627 if (SPECIFIED(ai->record.gain))
6604 SPRINTF(buf, ",record.gain=%d", ai->record.gain); 6628 SPRINTF(buf, ",record.gain=%d", ai->record.gain);
6605 if (SPECIFIED_CH(ai->play.balance)) 6629 if (SPECIFIED_CH(ai->play.balance))
6606 SPRINTF(buf, ",play.balance=%d", ai->play.balance); 6630 SPRINTF(buf, ",play.balance=%d", ai->play.balance);
6607 if (SPECIFIED_CH(ai->record.balance)) 6631 if (SPECIFIED_CH(ai->record.balance))
6608 SPRINTF(buf, ",record.balance=%d", ai->record.balance); 6632 SPRINTF(buf, ",record.balance=%d", ai->record.balance);
6609 if (SPECIFIED(ai->play.port)) 6633 if (SPECIFIED(ai->play.port))
6610 SPRINTF(buf, ",play.port=%d", ai->play.port); 6634 SPRINTF(buf, ",play.port=%d", ai->play.port);
6611 if (SPECIFIED(ai->record.port)) 6635 if (SPECIFIED(ai->record.port))
6612 SPRINTF(buf, ",record.port=%d", ai->record.port); 6636 SPRINTF(buf, ",record.port=%d", ai->record.port);
6613 if (SPECIFIED(ai->monitor_gain)) 6637 if (SPECIFIED(ai->monitor_gain))
6614 SPRINTF(buf, ",monitor_gain=%d", ai->monitor_gain); 6638 SPRINTF(buf, ",monitor_gain=%d", ai->monitor_gain);
6615 if (SPECIFIED_CH(ai->play.pause)) 6639 if (SPECIFIED_CH(ai->play.pause))
6616 SPRINTF(buf, ",play.pause=%d", ai->play.pause); 6640 SPRINTF(buf, ",play.pause=%d", ai->play.pause);
6617 if (SPECIFIED_CH(ai->record.pause)) 6641 if (SPECIFIED_CH(ai->record.pause))
6618 SPRINTF(buf, ",record.pause=%d", ai->record.pause); 6642 SPRINTF(buf, ",record.pause=%d", ai->record.pause);
6619 6643
6620 if (buflen > 0) 6644 if (buflen > 0)
6621 TRACE(2, "specified %s", buf + 1); 6645 TRACE(2, "specified %s", buf + 1);
6622 } 6646 }
6623#endif 6647#endif
6624 6648
6625 AUDIO_INITINFO(&saved_ai); 6649 AUDIO_INITINFO(&saved_ai);
6626 /* XXX shut up gcc */ 6650 /* XXX shut up gcc */
6627 memset(&saved_pfmt, 0, sizeof(saved_pfmt)); 6651 memset(&saved_pfmt, 0, sizeof(saved_pfmt));
6628 memset(&saved_rfmt, 0, sizeof(saved_rfmt)); 6652 memset(&saved_rfmt, 0, sizeof(saved_rfmt));
6629 6653
6630 /* Set default value and save current parameters */ 6654 /* Set default value and save current parameters */
6631 if (ptrack) { 6655 if (ptrack) {
6632 pfmt = ptrack->usrbuf.fmt; 6656 pfmt = ptrack->usrbuf.fmt;
6633 saved_pfmt = ptrack->usrbuf.fmt; 6657 saved_pfmt = ptrack->usrbuf.fmt;
6634 saved_ai.play.pause = ptrack->is_pause; 6658 saved_ai.play.pause = ptrack->is_pause;
6635 } 6659 }
6636 if (rtrack) { 6660 if (rtrack) {
6637 rfmt = rtrack->usrbuf.fmt; 6661 rfmt = rtrack->usrbuf.fmt;
6638 saved_rfmt = rtrack->usrbuf.fmt; 6662 saved_rfmt = rtrack->usrbuf.fmt;
6639 saved_ai.record.pause = rtrack->is_pause; 6663 saved_ai.record.pause = rtrack->is_pause;
6640 } 6664 }
6641 saved_ai.mode = file->mode; 6665 saved_ai.mode = file->mode;
6642 6666
6643 /* Overwrite if specified */ 6667 /* Overwrite if specified */
6644 mode = file->mode; 6668 mode = file->mode;
6645 if (SPECIFIED(ai->mode)) { 6669 if (SPECIFIED(ai->mode)) {
6646 /* 6670 /*
6647 * Setting ai->mode no longer does anything because it's 6671 * Setting ai->mode no longer does anything because it's
6648 * prohibited to change playback/recording mode after open 6672 * prohibited to change playback/recording mode after open
6649 * and AUMODE_PLAY_ALL is obsoleted. However, it still 6673 * and AUMODE_PLAY_ALL is obsoleted. However, it still
6650 * keeps the state of AUMODE_PLAY_ALL itself for backward 6674 * keeps the state of AUMODE_PLAY_ALL itself for backward
6651 * compatibility. 6675 * compatibility.
6652 * In the internal, only file->mode has the state of 6676 * In the internal, only file->mode has the state of
6653 * AUMODE_PLAY_ALL flag and track->mode in both track does 6677 * AUMODE_PLAY_ALL flag and track->mode in both track does
6654 * not have. 6678 * not have.
6655 */ 6679 */
6656 if ((file->mode & AUMODE_PLAY)) { 6680 if ((file->mode & AUMODE_PLAY)) {
6657 mode = (file->mode & (AUMODE_PLAY | AUMODE_RECORD)) 6681 mode = (file->mode & (AUMODE_PLAY | AUMODE_RECORD))
6658 | (ai->mode & AUMODE_PLAY_ALL); 6682 | (ai->mode & AUMODE_PLAY_ALL);
6659 } 6683 }
6660 } 6684 }
6661 6685
6662 if (ptrack) { 6686 if (ptrack) {
6663 pchanges = audio_track_setinfo_check(&pfmt, pi); 6687 pchanges = audio_track_setinfo_check(&pfmt, pi);
6664 if (pchanges == -1) { 6688 if (pchanges == -1) {
6665#if defined(AUDIO_DEBUG) 6689#if defined(AUDIO_DEBUG)
6666 char fmtbuf[64]; 6690 char fmtbuf[64];
6667 audio_format2_tostr(fmtbuf, sizeof(fmtbuf), &pfmt); 6691 audio_format2_tostr(fmtbuf, sizeof(fmtbuf), &pfmt);
6668 TRACET(1, ptrack, "check play.params failed: %s", 6692 TRACET(1, ptrack, "check play.params failed: %s",
6669 fmtbuf); 6693 fmtbuf);
6670#endif 6694#endif
6671 return EINVAL; 6695 return EINVAL;
6672 } 6696 }
6673 if (SPECIFIED(ai->mode)) 6697 if (SPECIFIED(ai->mode))
6674 pchanges = 1; 6698 pchanges = 1;
6675 } 6699 }
6676 if (rtrack) { 6700 if (rtrack) {
6677 rchanges = audio_track_setinfo_check(&rfmt, ri); 6701 rchanges = audio_track_setinfo_check(&rfmt, ri);
6678 if (rchanges == -1) { 6702 if (rchanges == -1) {
6679#if defined(AUDIO_DEBUG) 6703#if defined(AUDIO_DEBUG)
6680 char fmtbuf[64]; 6704 char fmtbuf[64];
6681 audio_format2_tostr(fmtbuf, sizeof(fmtbuf), &rfmt); 6705 audio_format2_tostr(fmtbuf, sizeof(fmtbuf), &rfmt);
6682 TRACET(1, rtrack, "check record.params failed: %s", 6706 TRACET(1, rtrack, "check record.params failed: %s",
6683 fmtbuf); 6707 fmtbuf);
6684#endif 6708#endif
6685 return EINVAL; 6709 return EINVAL;
6686 } 6710 }
6687 if (SPECIFIED(ai->mode)) 6711 if (SPECIFIED(ai->mode))
6688 rchanges = 1; 6712 rchanges = 1;
6689 } 6713 }
6690 6714
6691 /* 6715 /*
6692 * Even when setting either one of playback and recording, 6716 * Even when setting either one of playback and recording,
6693 * both track must be halted. 6717 * both track must be halted.
6694 */ 6718 */
6695 if (pchanges || rchanges) { 6719 if (pchanges || rchanges) {
6696 audio_file_clear(sc, file); 6720 audio_file_clear(sc, file);
6697#if defined(AUDIO_DEBUG) 6721#if defined(AUDIO_DEBUG)
6698 char fmtbuf[64]; 6722 char fmtbuf[64];
6699 if (pchanges) { 6723 if (pchanges) {
6700 audio_format2_tostr(fmtbuf, sizeof(fmtbuf), &pfmt); 6724 audio_format2_tostr(fmtbuf, sizeof(fmtbuf), &pfmt);
6701 DPRINTF(1, "audio track#%d play mode: %s\n", 6725 DPRINTF(1, "audio track#%d play mode: %s\n",
6702 ptrack->id, fmtbuf); 6726 ptrack->id, fmtbuf);
6703 } 6727 }
6704 if (rchanges) { 6728 if (rchanges) {
6705 audio_format2_tostr(fmtbuf, sizeof(fmtbuf), &rfmt); 6729 audio_format2_tostr(fmtbuf, sizeof(fmtbuf), &rfmt);
6706 DPRINTF(1, "audio track#%d rec mode: %s\n", 6730 DPRINTF(1, "audio track#%d rec mode: %s\n",
6707 rtrack->id, fmtbuf); 6731 rtrack->id, fmtbuf);
6708 } 6732 }
6709#endif 6733#endif
6710 } 6734 }
6711 6735
6712 /* Set mixer parameters */ 6736 /* Set mixer parameters */
6713 error = audio_hw_setinfo(sc, ai, &saved_ai); 6737 error = audio_hw_setinfo(sc, ai, &saved_ai);
6714 if (error) 6738 if (error)
6715 goto abort1; 6739 goto abort1;
6716 6740
6717 /* Set to track and update sticky parameters */ 6741 /* Set to track and update sticky parameters */
6718 error = 0; 6742 error = 0;
6719 file->mode = mode; 6743 file->mode = mode;
6720 if (ptrack) { 6744 if (ptrack) {
6721 if (SPECIFIED_CH(pi->pause)) { 6745 if (SPECIFIED_CH(pi->pause)) {
6722 ptrack->is_pause = pi->pause; 6746 ptrack->is_pause = pi->pause;
6723 sc->sc_sound_ppause = pi->pause; 6747 sc->sc_sound_ppause = pi->pause;
6724 } 6748 }
6725 if (pchanges) { 6749 if (pchanges) {
6726 audio_track_lock_enter(ptrack); 6750 audio_track_lock_enter(ptrack);
6727 error = audio_track_set_format(ptrack, &pfmt); 6751 error = audio_track_set_format(ptrack, &pfmt);
6728 audio_track_lock_exit(ptrack); 6752 audio_track_lock_exit(ptrack);
6729 if (error) { 6753 if (error) {
6730 TRACET(1, ptrack, "set play.params failed"); 6754 TRACET(1, ptrack, "set play.params failed");
6731 goto abort2; 6755 goto abort2;
6732 } 6756 }
6733 sc->sc_sound_pparams = pfmt; 6757 sc->sc_sound_pparams = pfmt;
6734 } 6758 }
6735 /* Change water marks after initializing the buffers. */ 6759 /* Change water marks after initializing the buffers. */
6736 if (SPECIFIED(ai->hiwat) || SPECIFIED(ai->lowat)) 6760 if (SPECIFIED(ai->hiwat) || SPECIFIED(ai->lowat))
6737 audio_track_setinfo_water(ptrack, ai); 6761 audio_track_setinfo_water(ptrack, ai);
6738 } 6762 }
6739 if (rtrack) { 6763 if (rtrack) {
6740 if (SPECIFIED_CH(ri->pause)) { 6764 if (SPECIFIED_CH(ri->pause)) {
6741 rtrack->is_pause = ri->pause; 6765 rtrack->is_pause = ri->pause;
6742 sc->sc_sound_rpause = ri->pause; 6766 sc->sc_sound_rpause = ri->pause;
6743 } 6767 }
6744 if (rchanges) { 6768 if (rchanges) {
6745 audio_track_lock_enter(rtrack); 6769 audio_track_lock_enter(rtrack);
6746 error = audio_track_set_format(rtrack, &rfmt); 6770 error = audio_track_set_format(rtrack, &rfmt);
6747 audio_track_lock_exit(rtrack); 6771 audio_track_lock_exit(rtrack);
6748 if (error) { 6772 if (error) {
6749 TRACET(1, rtrack, "set record.params failed"); 6773 TRACET(1, rtrack, "set record.params failed");
6750 goto abort3; 6774 goto abort3;
6751 } 6775 }
6752 sc->sc_sound_rparams = rfmt; 6776 sc->sc_sound_rparams = rfmt;
6753 } 6777 }
6754 } 6778 }
6755 6779
6756 return 0; 6780 return 0;
6757 6781
6758 /* Rollback */ 6782 /* Rollback */
6759abort3: 6783abort3:
6760 if (error != ENOMEM) { 6784 if (error != ENOMEM) {
6761 rtrack->is_pause = saved_ai.record.pause; 6785 rtrack->is_pause = saved_ai.record.pause;
6762 audio_track_lock_enter(rtrack); 6786 audio_track_lock_enter(rtrack);
6763 audio_track_set_format(rtrack, &saved_rfmt); 6787 audio_track_set_format(rtrack, &saved_rfmt);
6764 audio_track_lock_exit(rtrack); 6788 audio_track_lock_exit(rtrack);
6765 } 6789 }
6766abort2: 6790abort2:
6767 if (ptrack && error != ENOMEM) { 6791 if (ptrack && error != ENOMEM) {
6768 ptrack->is_pause = saved_ai.play.pause; 6792 ptrack->is_pause = saved_ai.play.pause;
6769 audio_track_lock_enter(ptrack); 6793 audio_track_lock_enter(ptrack);
6770 audio_track_set_format(ptrack, &saved_pfmt); 6794 audio_track_set_format(ptrack, &saved_pfmt);
6771 audio_track_lock_exit(ptrack); 6795 audio_track_lock_exit(ptrack);
6772 sc->sc_sound_pparams = saved_pfmt; 6796 sc->sc_sound_pparams = saved_pfmt;
6773 sc->sc_sound_ppause = saved_ai.play.pause; 6797 sc->sc_sound_ppause = saved_ai.play.pause;
6774 } 6798 }
6775 file->mode = saved_ai.mode; 6799 file->mode = saved_ai.mode;
6776abort1: 6800abort1:
6777 audio_hw_setinfo(sc, &saved_ai, NULL); 6801 audio_hw_setinfo(sc, &saved_ai, NULL);
6778 6802
6779 return error; 6803 return error;
6780} 6804}
6781 6805
6782/* 6806/*
6783 * Write SPECIFIED() parameters within info back to fmt. 6807 * Write SPECIFIED() parameters within info back to fmt.
6784 * Return value of 1 indicates that fmt is modified. 6808 * Return value of 1 indicates that fmt is modified.
6785 * Return value of 0 indicates that fmt is not modified. 6809 * Return value of 0 indicates that fmt is not modified.
6786 * Return value of -1 indicates that error EINVAL has occurred. 6810 * Return value of -1 indicates that error EINVAL has occurred.
6787 */ 6811 */
6788static int 6812static int
6789audio_track_setinfo_check(audio_format2_t *fmt, const struct audio_prinfo *info) 6813audio_track_setinfo_check(audio_format2_t *fmt, const struct audio_prinfo *info)
6790{ 6814{
6791 int changes; 6815 int changes;
6792 6816
6793 changes = 0; 6817 changes = 0;
6794 if (SPECIFIED(info->sample_rate)) { 6818 if (SPECIFIED(info->sample_rate)) {
6795 if (info->sample_rate < AUDIO_MIN_FREQUENCY) 6819 if (info->sample_rate < AUDIO_MIN_FREQUENCY)
6796 return -1; 6820 return -1;
6797 if (info->sample_rate > AUDIO_MAX_FREQUENCY) 6821 if (info->sample_rate > AUDIO_MAX_FREQUENCY)
6798 return -1; 6822 return -1;
6799 fmt->sample_rate = info->sample_rate; 6823 fmt->sample_rate = info->sample_rate;
6800 changes = 1; 6824 changes = 1;
6801 } 6825 }
6802 if (SPECIFIED(info->encoding)) { 6826 if (SPECIFIED(info->encoding)) {
6803 fmt->encoding = info->encoding; 6827 fmt->encoding = info->encoding;
6804 changes = 1; 6828 changes = 1;
6805 } 6829 }
6806 if (SPECIFIED(info->precision)) { 6830 if (SPECIFIED(info->precision)) {
6807 fmt->precision = info->precision; 6831 fmt->precision = info->precision;
6808 /* we don't have API to specify stride */ 6832 /* we don't have API to specify stride */
6809 fmt->stride = info->precision; 6833 fmt->stride = info->precision;
6810 changes = 1; 6834 changes = 1;
6811 } 6835 }
6812 if (SPECIFIED(info->channels)) { 6836 if (SPECIFIED(info->channels)) {
6813 fmt->channels = info->channels; 6837 fmt->channels = info->channels;
6814 changes = 1; 6838 changes = 1;
6815 } 6839 }
6816 6840
6817 if (changes) { 6841 if (changes) {
6818 if (audio_check_params(fmt) != 0) 6842 if (audio_check_params(fmt) != 0)
6819 return -1; 6843 return -1;
6820 } 6844 }
6821 6845
6822 return changes; 6846 return changes;
6823} 6847}
6824 6848
6825/* 6849/*
6826 * Change water marks for playback track if specfied. 6850 * Change water marks for playback track if specfied.
6827 */ 6851 */
6828static void 6852static void
6829audio_track_setinfo_water(audio_track_t *track, const struct audio_info *ai) 6853audio_track_setinfo_water(audio_track_t *track, const struct audio_info *ai)
6830{ 6854{
6831 u_int blks; 6855 u_int blks;
6832 u_int maxblks; 6856 u_int maxblks;
6833 u_int blksize; 6857 u_int blksize;
6834 6858
6835 KASSERT(audio_track_is_playback(track)); 6859 KASSERT(audio_track_is_playback(track));

cvs diff -r1.4 -r1.5 src/sys/dev/audio/audiovar.h (switch to unified diff)

--- src/sys/dev/audio/audiovar.h 2019/06/26 06:57:45 1.4
+++ src/sys/dev/audio/audiovar.h 2019/08/29 13:01:07 1.5
@@ -1,326 +1,327 @@ @@ -1,326 +1,327 @@
1/* $NetBSD: audiovar.h,v 1.4 2019/06/26 06:57:45 isaki Exp $ */ 1/* $NetBSD: audiovar.h,v 1.5 2019/08/29 13:01:07 isaki Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2002 The NetBSD Foundation, Inc. 4 * Copyright (c) 2002 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by TAMURA Kent 8 * by TAMURA Kent
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 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 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 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 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 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * Copyright (c) 1991-1993 Regents of the University of California. 33 * Copyright (c) 1991-1993 Regents of the University of California.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions 37 * modification, are permitted provided that the following conditions
38 * are met: 38 * are met:
39 * 1. Redistributions of source code must retain the above copyright 39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer. 40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright 41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the 42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution. 43 * documentation and/or other materials provided with the distribution.
44 * 3. All advertising materials mentioning features or use of this software 44 * 3. All advertising materials mentioning features or use of this software
45 * must display the following acknowledgement: 45 * must display the following acknowledgement:
46 * This product includes software developed by the Computer Systems 46 * This product includes software developed by the Computer Systems
47 * Engineering Group at Lawrence Berkeley Laboratory. 47 * Engineering Group at Lawrence Berkeley Laboratory.
48 * 4. Neither the name of the University nor of the Laboratory may be used 48 * 4. Neither the name of the University nor of the Laboratory may be used
49 * to endorse or promote products derived from this software without 49 * to endorse or promote products derived from this software without
50 * specific prior written permission. 50 * specific prior written permission.
51 * 51 *
52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62 * SUCH DAMAGE. 62 * SUCH DAMAGE.
63 * 63 *
64 * From: Header: audiovar.h,v 1.3 93/07/18 14:07:25 mccanne Exp (LBL) 64 * From: Header: audiovar.h,v 1.3 93/07/18 14:07:25 mccanne Exp (LBL)
65 */ 65 */
66 66
67#ifndef _SYS_DEV_AUDIO_AUDIOVAR_H_ 67#ifndef _SYS_DEV_AUDIO_AUDIOVAR_H_
68#define _SYS_DEV_AUDIO_AUDIOVAR_H_ 68#define _SYS_DEV_AUDIO_AUDIOVAR_H_
69 69
70#if defined(_KERNEL) 70#if defined(_KERNEL)
71#include <sys/condvar.h> 71#include <sys/condvar.h>
72#include <sys/proc.h> 72#include <sys/proc.h>
73#include <sys/queue.h> 73#include <sys/queue.h>
74 74
75#include <dev/audio/audio_if.h> 75#include <dev/audio/audio_if.h>
76#include <dev/audio/audiofil.h> 76#include <dev/audio/audiofil.h>
77#else 77#else
78#include <stdint.h> 78#include <stdint.h>
79#include <stdbool.h> 79#include <stdbool.h>
80#include "compat.h" 80#include "compat.h"
81#include "userland.h" 81#include "userland.h"
82#include "audiofil.h" 82#include "audiofil.h"
83#endif /* _KERNEL */ 83#endif /* _KERNEL */
84 84
85/* 85/*
86 * Whether supports [US]LINEAR24/24 as userland format. 86 * Whether supports [US]LINEAR24/24 as userland format.
87 */ 87 */
88/* #define AUDIO_SUPPORT_LINEAR24 */ 88/* #define AUDIO_SUPPORT_LINEAR24 */
89 89
90/* 90/*
91 * Frequency range. 91 * Frequency range.
92 * For lower limit, there are some antique machines who supports under 92 * For lower limit, there are some antique machines who supports under
93 * 4000Hz, so that we accept 1000Hz as lower limit, regardless of 93 * 4000Hz, so that we accept 1000Hz as lower limit, regardless of
94 * practicality(?). 94 * practicality(?).
95 * For upper limit, there are some devices who supports 384000Hz, but 95 * For upper limit, there are some devices who supports 384000Hz, but
96 * I don't have them. :-) 96 * I don't have them. :-)
97 */ 97 */
98#define AUDIO_MIN_FREQUENCY (1000) 98#define AUDIO_MIN_FREQUENCY (1000)
99#define AUDIO_MAX_FREQUENCY (192000) 99#define AUDIO_MAX_FREQUENCY (192000)
100 100
101typedef struct audio_file audio_file_t; 101typedef struct audio_file audio_file_t;
102typedef struct audio_trackmixer audio_trackmixer_t; 102typedef struct audio_trackmixer audio_trackmixer_t;
103 103
104/* ring buffer */ 104/* ring buffer */
105typedef struct { 105typedef struct {
106 audio_format2_t fmt; /* format */ 106 audio_format2_t fmt; /* format */
107 int capacity; /* capacity by frame */ 107 int capacity; /* capacity by frame */
108 int head; /* head position in frame */ 108 int head; /* head position in frame */
109 int used; /* used frame count */ 109 int used; /* used frame count */
110 void *mem; /* sample ptr */ 110 void *mem; /* sample ptr */
111} audio_ring_t; 111} audio_ring_t;
112 112
113#define AUDIO_N_PORTS 4 113#define AUDIO_N_PORTS 4
114 114
115struct au_mixer_ports { 115struct au_mixer_ports {
116 int index; /* index of port-selector mixerctl */ 116 int index; /* index of port-selector mixerctl */
117 int master; /* index of master mixerctl */ 117 int master; /* index of master mixerctl */
118 int nports; /* number of selectable ports */ 118 int nports; /* number of selectable ports */
119 bool isenum; /* selector is enum type */ 119 bool isenum; /* selector is enum type */
120 u_int allports; /* all aumasks or'd */ 120 u_int allports; /* all aumasks or'd */
121 u_int aumask[AUDIO_N_PORTS]; /* exposed value of "ports" */ 121 u_int aumask[AUDIO_N_PORTS]; /* exposed value of "ports" */
122 int misel [AUDIO_N_PORTS]; /* ord of port, for selector */ 122 int misel [AUDIO_N_PORTS]; /* ord of port, for selector */
123 int miport[AUDIO_N_PORTS]; /* index of port's mixerctl */ 123 int miport[AUDIO_N_PORTS]; /* index of port's mixerctl */
124 bool isdual; /* has working mixerout */ 124 bool isdual; /* has working mixerout */
125 int mixerout; /* ord of mixerout, for dual case */ 125 int mixerout; /* ord of mixerout, for dual case */
126 int cur_port; /* the port that gain actually controls when 126 int cur_port; /* the port that gain actually controls when
127 mixerout is selected, for dual case */ 127 mixerout is selected, for dual case */
128}; 128};
129 129
130struct audio_softc { 130struct audio_softc {
131 /* Myself (e.g.; audio0, audio1, ...) */ 131 /* Myself (e.g.; audio0, audio1, ...) */
132 device_t sc_dev; 132 device_t sc_dev;
133 133
134 /* Hardware device struct (e.g.; sb0, hdafg0, ...) */ 134 /* Hardware device struct (e.g.; sb0, hdafg0, ...) */
135 device_t hw_dev; 135 device_t hw_dev;
136 136
137 /* 137 /*
138 * Hardware interface and driver handle. 138 * Hardware interface and driver handle.
139 * hw_if == NULL means that the device is (attached but) disabled. 139 * hw_if == NULL means that the device is (attached but) disabled.
140 */ 140 */
141 const struct audio_hw_if *hw_if; 141 const struct audio_hw_if *hw_if;
142 void *hw_hdl; 142 void *hw_hdl;
143 143
144 /* 144 /*
145 * Properties obtained by get_props(). 145 * Properties obtained by get_props().
146 * No need any locks to read this variable. 146 * No need any locks to read this variable.
147 */ 147 */
148 int sc_props; 148 int sc_props;
149 149
150 /* 150 /*
151 * List of opened descriptors. 151 * List of opened descriptors.
152 * Must be protected by sc_intr_lock. 152 * Must be protected by sc_lock || sc_intr_lock for traversal(FOREACH).
 153 * Must be protected by sc_lock && sc_intr_lock for insertion/removal.
153 */ 154 */
154 SLIST_HEAD(, audio_file) sc_files; 155 SLIST_HEAD(, audio_file) sc_files;
155 156
156 /* 157 /*
157 * Blocksize in msec. 158 * Blocksize in msec.
158 * Must be protected by sc_lock. 159 * Must be protected by sc_lock.
159 */ 160 */
160 int sc_blk_ms; 161 int sc_blk_ms;
161 162
162 /* 163 /*
163 * Track mixer for playback and recording. 164 * Track mixer for playback and recording.
164 * If null, the mixer is disabled. 165 * If null, the mixer is disabled.
165 */ 166 */
166 audio_trackmixer_t *sc_pmixer; 167 audio_trackmixer_t *sc_pmixer;
167 audio_trackmixer_t *sc_rmixer; 168 audio_trackmixer_t *sc_rmixer;
168 169
169 /* 170 /*
170 * Opening track counter. 171 * Opening track counter.
171 * Must be protected by sc_lock. 172 * Must be protected by sc_lock.
172 */ 173 */
173 int sc_popens; 174 int sc_popens;
174 int sc_ropens; 175 int sc_ropens;
175 176
176 /* 177 /*
177 * true if the track mixer is running. 178 * true if the track mixer is running.
178 * Must be protected by sc_lock. 179 * Must be protected by sc_lock.
179 */ 180 */
180 bool sc_pbusy; 181 bool sc_pbusy;
181 bool sc_rbusy; 182 bool sc_rbusy;
182 183
183 /* 184 /*
184 * These four are the parameters sustained with /dev/sound. 185 * These four are the parameters sustained with /dev/sound.
185 * Must be protected by sc_lock. 186 * Must be protected by sc_lock.
186 */ 187 */
187 audio_format2_t sc_sound_pparams; 188 audio_format2_t sc_sound_pparams;
188 audio_format2_t sc_sound_rparams; 189 audio_format2_t sc_sound_rparams;
189 bool sc_sound_ppause; 190 bool sc_sound_ppause;
190 bool sc_sound_rpause; 191 bool sc_sound_rpause;
191 192
192 /* recent info for /dev/sound */ 193 /* recent info for /dev/sound */
193 /* XXX TODO */ 194 /* XXX TODO */
194 struct audio_info sc_ai; 195 struct audio_info sc_ai;
195 196
196 /* 197 /*
197 * Playback(write)/Recording(read) selector. 198 * Playback(write)/Recording(read) selector.
198 * Must be protected by sc_lock. 199 * Must be protected by sc_lock.
199 */ 200 */
200 struct selinfo sc_wsel; 201 struct selinfo sc_wsel;
201 struct selinfo sc_rsel; 202 struct selinfo sc_rsel;
202 203
203 /* 204 /*
204 * processes who want mixer SIGIO. 205 * processes who want mixer SIGIO.
205 * Must be protected by sc_lock. 206 * Must be protected by sc_lock.
206 */ 207 */
207 struct mixer_asyncs { 208 struct mixer_asyncs {
208 struct mixer_asyncs *next; 209 struct mixer_asyncs *next;
209 pid_t pid; 210 pid_t pid;
210 } *sc_async_mixer; 211 } *sc_async_mixer;
211 212
212 /* 213 /*
213 * Thread lock and interrupt lock obtained by get_locks(). 214 * Thread lock and interrupt lock obtained by get_locks().
214 */ 215 */
215 kmutex_t *sc_lock; 216 kmutex_t *sc_lock;
216 kmutex_t *sc_intr_lock; 217 kmutex_t *sc_intr_lock;
217 218
218 /* 219 /*
219 * Critical section. 220 * Critical section.
220 * Must be protected by sc_lock. 221 * Must be protected by sc_lock.
221 */ 222 */
222 int sc_exlock; 223 int sc_exlock;
223 kcondvar_t sc_exlockcv; 224 kcondvar_t sc_exlockcv;
224 225
225 /* 226 /*
226 * Must be protected by sc_lock (?) 227 * Must be protected by sc_lock (?)
227 */ 228 */
228 bool sc_dying; 229 bool sc_dying;
229 230
230 /* 231 /*
231 * If multiuser is false, other users who have different euid 232 * If multiuser is false, other users who have different euid
232 * than the first user cannot open this device. 233 * than the first user cannot open this device.
233 * Must be protected by sc_lock. 234 * Must be protected by sc_lock.
234 */ 235 */
235 bool sc_multiuser; 236 bool sc_multiuser;
236 kauth_cred_t sc_cred; 237 kauth_cred_t sc_cred;
237 238
238 struct sysctllog *sc_log; 239 struct sysctllog *sc_log;
239 240
240 mixer_ctrl_t *sc_mixer_state; 241 mixer_ctrl_t *sc_mixer_state;
241 int sc_nmixer_states; 242 int sc_nmixer_states;
242 struct au_mixer_ports sc_inports; 243 struct au_mixer_ports sc_inports;
243 struct au_mixer_ports sc_outports; 244 struct au_mixer_ports sc_outports;
244 int sc_monitor_port; 245 int sc_monitor_port;
245 u_int sc_lastgain; 246 u_int sc_lastgain;
246}; 247};
247 248
248#ifdef DIAGNOSTIC 249#ifdef DIAGNOSTIC
249#define DIAGNOSTIC_filter_arg(arg) audio_diagnostic_filter_arg(__func__, (arg)) 250#define DIAGNOSTIC_filter_arg(arg) audio_diagnostic_filter_arg(__func__, (arg))
250#define DIAGNOSTIC_format2(fmt) audio_diagnostic_format2(__func__, (fmt)) 251#define DIAGNOSTIC_format2(fmt) audio_diagnostic_format2(__func__, (fmt))
251extern void audio_diagnostic_filter_arg(const char *, 252extern void audio_diagnostic_filter_arg(const char *,
252 const audio_filter_arg_t *); 253 const audio_filter_arg_t *);
253extern void audio_diagnostic_format2(const char *, const audio_format2_t *); 254extern void audio_diagnostic_format2(const char *, const audio_format2_t *);
254#else 255#else
255#define DIAGNOSTIC_filter_arg(arg) 256#define DIAGNOSTIC_filter_arg(arg)
256#define DIAGNOSTIC_format2(fmt) 257#define DIAGNOSTIC_format2(fmt)
257#endif 258#endif
258 259
259/* 260/*
260 * Return true if 'fmt' is the internal format. 261 * Return true if 'fmt' is the internal format.
261 * It does not check for frequency and number of channels. 262 * It does not check for frequency and number of channels.
262 */ 263 */
263static __inline bool 264static __inline bool
264audio_format2_is_internal(const audio_format2_t *fmt) 265audio_format2_is_internal(const audio_format2_t *fmt)
265{ 266{
266 267
267 if (fmt->encoding != AUDIO_ENCODING_SLINEAR_NE) 268 if (fmt->encoding != AUDIO_ENCODING_SLINEAR_NE)
268 return false; 269 return false;
269 if (fmt->precision != AUDIO_INTERNAL_BITS) 270 if (fmt->precision != AUDIO_INTERNAL_BITS)
270 return false; 271 return false;
271 if (fmt->stride != AUDIO_INTERNAL_BITS) 272 if (fmt->stride != AUDIO_INTERNAL_BITS)
272 return false; 273 return false;
273 return true; 274 return true;
274} 275}
275 276
276/* 277/*
277 * Return true if fmt's encoding is one of LINEAR. 278 * Return true if fmt's encoding is one of LINEAR.
278 */ 279 */
279static __inline bool 280static __inline bool
280audio_format2_is_linear(const audio_format2_t *fmt) 281audio_format2_is_linear(const audio_format2_t *fmt)
281{ 282{
282 return (fmt->encoding == AUDIO_ENCODING_SLINEAR_LE) 283 return (fmt->encoding == AUDIO_ENCODING_SLINEAR_LE)
283 || (fmt->encoding == AUDIO_ENCODING_SLINEAR_BE) 284 || (fmt->encoding == AUDIO_ENCODING_SLINEAR_BE)
284 || (fmt->encoding == AUDIO_ENCODING_ULINEAR_LE) 285 || (fmt->encoding == AUDIO_ENCODING_ULINEAR_LE)
285 || (fmt->encoding == AUDIO_ENCODING_ULINEAR_BE); 286 || (fmt->encoding == AUDIO_ENCODING_ULINEAR_BE);
286} 287}
287 288
288/* 289/*
289 * Return true if fmt's encoding is one of SLINEAR. 290 * Return true if fmt's encoding is one of SLINEAR.
290 */ 291 */
291static __inline bool 292static __inline bool
292audio_format2_is_signed(const audio_format2_t *fmt) 293audio_format2_is_signed(const audio_format2_t *fmt)
293{ 294{
294 return (fmt->encoding == AUDIO_ENCODING_SLINEAR_LE) 295 return (fmt->encoding == AUDIO_ENCODING_SLINEAR_LE)
295 || (fmt->encoding == AUDIO_ENCODING_SLINEAR_BE); 296 || (fmt->encoding == AUDIO_ENCODING_SLINEAR_BE);
296} 297}
297 298
298/* 299/*
299 * Return fmt's endian as LITTLE_ENDIAN or BIG_ENDIAN. 300 * Return fmt's endian as LITTLE_ENDIAN or BIG_ENDIAN.
300 */ 301 */
301static __inline int 302static __inline int
302audio_format2_endian(const audio_format2_t *fmt) 303audio_format2_endian(const audio_format2_t *fmt)
303{ 304{
304 if (fmt->stride == 8) { 305 if (fmt->stride == 8) {
305 /* HOST ENDIAN */ 306 /* HOST ENDIAN */
306 return BYTE_ORDER; 307 return BYTE_ORDER;
307 } 308 }
308 309
309 if (fmt->encoding == AUDIO_ENCODING_SLINEAR_LE || 310 if (fmt->encoding == AUDIO_ENCODING_SLINEAR_LE ||
310 fmt->encoding == AUDIO_ENCODING_ULINEAR_LE) { 311 fmt->encoding == AUDIO_ENCODING_ULINEAR_LE) {
311 return LITTLE_ENDIAN; 312 return LITTLE_ENDIAN;
312 } 313 }
313 if (fmt->encoding == AUDIO_ENCODING_SLINEAR_BE || 314 if (fmt->encoding == AUDIO_ENCODING_SLINEAR_BE ||
314 fmt->encoding == AUDIO_ENCODING_ULINEAR_BE) { 315 fmt->encoding == AUDIO_ENCODING_ULINEAR_BE) {
315 return BIG_ENDIAN; 316 return BIG_ENDIAN;
316 } 317 }
317 return BYTE_ORDER; 318 return BYTE_ORDER;
318} 319}
319 320
320/* Interfaces for audiobell. */ 321/* Interfaces for audiobell. */
321int audiobellopen(dev_t, audio_file_t **); 322int audiobellopen(dev_t, audio_file_t **);
322int audiobellsetrate(audio_file_t *, u_int); 323int audiobellsetrate(audio_file_t *, u_int);
323int audiobellclose(audio_file_t *); 324int audiobellclose(audio_file_t *);
324int audiobellwrite(audio_file_t *, struct uio *); 325int audiobellwrite(audio_file_t *, struct uio *);
325 326
326#endif /* !_SYS_DEV_AUDIO_AUDIOVAR_H_ */ 327#endif /* !_SYS_DEV_AUDIO_AUDIOVAR_H_ */