xref: /illumos-gate/usr/src/uts/common/sys/audio/audio_driver.h (revision 2dd5848fa9da42f374782814f362e0afda124ecd)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright (C) 4Front Technologies 1996-2008.
23  *
24  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
25  * Use is subject to license terms.
26  */
27 
28 #ifndef	_SYS_AUDIO_AUDIO_DRIVER_H
29 #define	_SYS_AUDIO_AUDIO_DRIVER_H
30 
31 #include <sys/types.h>
32 #include <sys/list.h>
33 #include <sys/ddi.h>
34 #include <sys/sunddi.h>
35 #include <sys/audio/audio_common.h>
36 
37 
38 #ifdef	__cplusplus
39 extern "C" {
40 #endif
41 
42 #ifdef	_KERNEL
43 
44 struct audio_engine_ops {
45 	int	audio_engine_version;
46 #define	AUDIO_ENGINE_VERSION	2
47 
48 	/*
49 	 * Initialize engine, including buffer allocation.  Arguments
50 	 * that are pointers are hints.  On return, they are updated with
51 	 * the actual values configured by the driver.
52 	 */
53 	int	(*audio_engine_open)(void *, int, uint_t *, caddr_t *);
54 	void	(*audio_engine_close)(void *);
55 
56 	/*
57 	 * Start and stop are used to actually get the hardware running
58 	 * or stop the hardware.  Until this is kicked off, the engine
59 	 * will not actually transfer data.  These are not destructive to
60 	 * ring positions, etc.  (Think of it like pause/play).
61 	 */
62 	int	(*audio_engine_start)(void *);
63 	void	(*audio_engine_stop)(void *);
64 
65 	/*
66 	 * Obtain the engine offset.  Offsets start at zero at engine_open,
67 	 * and keep counting upwards.  Count is returned in frames.
68 	 */
69 	uint64_t	(*audio_engine_count)(void *);
70 
71 	/*
72 	 * The following entry points return the currently configured
73 	 * status of the engine.  It is assumed that the engine's
74 	 * configuration is relatively fixed, and does not change
75 	 * while open, or in response to open.
76 	 *
77 	 * However, in the future we might like to allow for the
78 	 * device to change the settings while it is not open, which
79 	 * could allow for mixerctl to change the configured channels,
80 	 * for example.  In order to synchronize this properly, we'll
81 	 * need the engine to perform a notification/request.  That
82 	 * will be added later.
83 	 *
84 	 * AC3: We will have to figure out how to support dynamically
85 	 * selecting different sampling frequencies for AC3, since
86 	 * it needs to be able to support 32, 44.1, and 48 kHz.
87 	 * Perhaps special flags used during open() would do the trick.
88 	 */
89 	int	(*audio_engine_format)(void *);
90 	int	(*audio_engine_channels)(void *);
91 	int	(*audio_engine_rate)(void *);
92 
93 	/*
94 	 * DMA cache synchronization.  The framework does this on
95 	 * behalf of the driver for both input and output.  The driver
96 	 * is responsible for tracking the direction (based on the
97 	 * flags passed to ae_open()), and dealing with any partial
98 	 * synchronization if any is needed.
99 	 */
100 	void	(*audio_engine_sync)(void *, uint_t);
101 
102 	/*
103 	 * The framework may like to know how deep the device queues data.
104 	 * This can be used to provide a more accurate latency calculation.
105 	 */
106 	uint_t	(*audio_engine_qlen)(void *);
107 
108 	/*
109 	 * If the driver doesn't use simple interleaving, then we need to
110 	 * know more about the offsets of channels within the buffer.
111 	 * We obtain both the starting offset within the buffer, and the
112 	 * increment for each new sample.  As usual, these are given in
113 	 * samples.  If this entry point is NULL, the framework assumes
114 	 * that simple interlevaing is used instead.
115 	 */
116 	void	(*audio_engine_chinfo)(void *, int chan, uint_t *offset,
117 	    uint_t *incr);
118 
119 	/*
120 	 * The following entry point is used to determine the play ahead
121 	 * desired by the engine.  Engines with less consistent scheduling,
122 	 * or with a need for deeper queuing, implement this.  If not
123 	 * implemented, the framework assumes 1.5 * fragfr.
124 	 */
125 	uint_t	(*audio_engine_playahead)(void *);
126 };
127 
128 /*
129  * Drivers call these.
130  */
131 void audio_init_ops(struct dev_ops *, const char *);
132 void audio_fini_ops(struct dev_ops *);
133 
134 audio_dev_t *audio_dev_alloc(dev_info_t *, int);
135 void audio_dev_free(audio_dev_t *);
136 
137 void audio_dev_set_description(audio_dev_t *, const char *);
138 void audio_dev_set_version(audio_dev_t *, const char *);
139 void audio_dev_add_info(audio_dev_t *, const char *);
140 
141 audio_engine_t *audio_engine_alloc(audio_engine_ops_t *, uint_t);
142 void audio_engine_set_private(audio_engine_t *, void *);
143 void *audio_engine_get_private(audio_engine_t *);
144 void audio_engine_free(audio_engine_t *);
145 
146 void audio_dev_add_engine(audio_dev_t *, audio_engine_t *);
147 void audio_dev_remove_engine(audio_dev_t *, audio_engine_t *);
148 int audio_dev_register(audio_dev_t *);
149 int audio_dev_unregister(audio_dev_t *);
150 void audio_dev_suspend(audio_dev_t *);
151 void audio_dev_resume(audio_dev_t *);
152 void audio_dev_warn(audio_dev_t *, const char *, ...);
153 
154 /* DEBUG ONLY */
155 void audio_dump_bytes(const uint8_t *w, int dcount);
156 void audio_dump_words(const uint16_t *w, int dcount);
157 void audio_dump_dwords(const uint32_t *w, int dcount);
158 
159 
160 /* Engine flags */
161 #define	ENGINE_OUTPUT_CAP	(1U << 2)
162 #define	ENGINE_INPUT_CAP	(1U << 3)
163 #define	ENGINE_CAPS		(ENGINE_OUTPUT_CAP | ENGINE_INPUT_CAP)
164 #define	ENGINE_DRIVER_FLAGS	(0xffff)	/* flags usable by driver */
165 
166 #define	ENGINE_OUTPUT		(1U << 16)	/* fields not for driver use */
167 #define	ENGINE_INPUT		(1U << 17)
168 #define	ENGINE_OPEN		(1U << 18)
169 #define	ENGINE_RUNNING		(1U << 19)
170 #define	ENGINE_EXCLUSIVE	(1U << 20)	/* exclusive use, e.g. AC3 */
171 #define	ENGINE_NDELAY		(1U << 21)	/* non-blocking open */
172 
173 /*
174  * entry points used by legacy SADA drivers
175  */
176 int audio_legacy_open(queue_t *, dev_t *, int, int, cred_t *);
177 int audio_legacy_close(queue_t *, int, cred_t *);
178 int audio_legacy_wput(queue_t *, mblk_t *);
179 int audio_legacy_wsrv(queue_t *);
180 
181 
182 
183 /*
184  * Audio device controls
185  */
186 
187 /*
188  * Control read or write driver function type.
189  *
190  * Returns zero on success, errno on failure.
191  */
192 typedef int (*audio_ctrl_wr_t)(void *, uint64_t);
193 typedef int (*audio_ctrl_rd_t)(void *, uint64_t *);
194 
195 
196 /*
197  * This will allocate and register a control for my audio device.
198  *
199  * On success this will return a control structure else NULL.
200  */
201 audio_ctrl_t *audio_dev_add_control(audio_dev_t *,
202     audio_ctrl_desc_t *, audio_ctrl_rd_t, audio_ctrl_wr_t, void *);
203 
204 /*
205  * Add a synthetic PCM volume control.  This should only be used by
206  * devices which have no physical PCM volume controls.  The control
207  * implements a simple attenuator on the PCM data; unlike AC'97 there
208  * is no "gain", so using this instead of a hardware control may
209  * result in loss range.  The control is implemented using
210  * AUDIO_CTRL_ID_VOLUME.
211  */
212 int audio_dev_add_soft_volume(audio_dev_t *);
213 
214 /*
215  * This will remove a control from an audio device.
216  */
217 void audio_dev_del_control(audio_ctrl_t *);
218 
219 /*
220  * This will tell the framework that controls have changed
221  * and it should update its values.
222  */
223 void audio_dev_update_controls(audio_dev_t *);
224 
225 /*
226  * This is used to read the current value of a control.
227  * Note, this will cause a callback into the driver to get the value.
228  *
229  * On return zero is returned on success else errno is returned.
230  */
231 int audio_control_read(audio_ctrl_t *, uint64_t *);
232 
233 /*
234  * This is used to write a value to a control.
235  * Note, this will cause a callback into the driver to write the value.
236  *
237  * On return zero is returned on success else errno is returned.
238  */
239 int audio_control_write(audio_ctrl_t *, uint64_t);
240 
241 #endif	/* _KERNEL */
242 
243 #ifdef	__cplusplus
244 }
245 #endif
246 
247 #endif	/* _SYS_AUDIO_AUDIO_DRIVER_H */
248