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