audio_driver.h revision 12165:e481916a5729
1192886Sedwin/*
2192886Sedwin * CDDL HEADER START
364499Swollman *
4273719Sedwin * The contents of this file are subject to the terms of the
52742Swollman * Common Development and Distribution License (the "License").
6273719Sedwin * You may not use this file except in compliance with the License.
7273719Sedwin *
82742Swollman * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9325322Sgordon * or http://www.opensolaris.org/os/licensing.
10274563Sedwin * See the License for the specific language governing permissions
11274563Sedwin * and limitations under the License.
12158421Swollman *
13158421Swollman * When distributing Covered Code, include this CDDL HEADER in each
14274563Sedwin * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
152742Swollman * If applicable, add the following below this CDDL HEADER, with the
16325322Sgordon * fields enclosed by brackets "[]" replaced with your own identifying
17325322Sgordon * information: Portions Copyright [yyyy] [name of copyright owner]
1820094Swollman *
1920094Swollman * CDDL HEADER END
20274563Sedwin */
21274563Sedwin/*
2220094Swollman * Copyright (C) 4Front Technologies 1996-2008.
23274563Sedwin *
24274563Sedwin * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
25325322Sgordon */
2620094Swollman
27325322Sgordon#ifndef	_SYS_AUDIO_AUDIO_DRIVER_H
28330568Sgordon#define	_SYS_AUDIO_AUDIO_DRIVER_H
29325322Sgordon
30325322Sgordon#include <sys/types.h>
312742Swollman#include <sys/list.h>
322742Swollman#include <sys/ddi.h>
332742Swollman#include <sys/sunddi.h>
342742Swollman#include <sys/audio/audio_common.h>
352742Swollman
362742Swollman
372742Swollman#ifdef	__cplusplus
3819878Swollmanextern "C" {
392742Swollman#endif
402742Swollman
412742Swollman#ifdef	_KERNEL
42270817Spluknet
432742Swollmanstruct audio_engine_ops {
442742Swollman	int	audio_engine_version;
45149514Swollman#define	AUDIO_ENGINE_VERSION	2
4621217Swollman
479908Swollman	/*
489908Swollman	 * Initialize engine, including buffer allocation.  Arguments
492742Swollman	 * that are pointers are hints.  On return, they are updated with
50331986Sgordon	 * the actual values configured by the driver.
5119878Swollman	 */
52331986Sgordon	int	(*audio_engine_open)(void *, int, uint_t *, caddr_t *);
5319878Swollman	void	(*audio_engine_close)(void *);
54331986Sgordon
55331986Sgordon	/*
5619878Swollman	 * Start and stop are used to actually get the hardware running
57331986Sgordon	 * or stop the hardware.  Until this is kicked off, the engine
5819878Swollman	 * will not actually transfer data.  These are not destructive to
59331986Sgordon	 * ring positions, etc.  (Think of it like pause/play).
6019878Swollman	 */
61331986Sgordon	int	(*audio_engine_start)(void *);
6219878Swollman	void	(*audio_engine_stop)(void *);
63331986Sgordon
6419878Swollman	/*
65331986Sgordon	 * Obtain the engine offset.  Offsets start at zero at engine_open,
6693799Swollman	 * and keep counting upwards.  Count is returned in frames.
67331986Sgordon	 */
6858787Sru	uint64_t	(*audio_engine_count)(void *);
69331986Sgordon
7019878Swollman	/*
71331986Sgordon	 * The following entry points return the currently configured
729908Swollman	 * status of the engine.  It is assumed that the engine's
73149514Swollman	 * configuration is relatively fixed, and does not change
749908Swollman	 * while open, or in response to open.
759908Swollman	 *
76270817Spluknet	 * However, in the future we might like to allow for the
7721217Swollman	 * device to change the settings while it is not open, which
7819878Swollman	 * could allow for mixerctl to change the configured channels,
79331986Sgordon	 * for example.  In order to synchronize this properly, we'll
809908Swollman	 * need the engine to perform a notification/request.  That
81149514Swollman	 * will be added later.
829908Swollman	 *
839908Swollman	 * AC3: We will have to figure out how to support dynamically
849908Swollman	 * selecting different sampling frequencies for AC3, since
859908Swollman	 * it needs to be able to support 32, 44.1, and 48 kHz.
8658787Sru	 * Perhaps special flags used during open() would do the trick.
8758787Sru	 */
8858787Sru	int	(*audio_engine_format)(void *);
8964499Swollman	int	(*audio_engine_channels)(void *);
90331986Sgordon	int	(*audio_engine_rate)(void *);
91175034Sedwin
92175034Sedwin	/*
93175034Sedwin	 * DMA cache synchronization.  The framework does this on
94175034Sedwin	 * behalf of the driver for both input and output.  The driver
95175034Sedwin	 * is responsible for tracking the direction (based on the
9658787Sru	 * flags passed to ae_open()), and dealing with any partial
9758787Sru	 * synchronization if any is needed.
98270817Spluknet	 */
9958787Sru	void	(*audio_engine_sync)(void *, uint_t);
10058787Sru
10158787Sru	/*
102270817Spluknet	 * The framework may like to know how deep the device queues data.
10364499Swollman	 * This can be used to provide a more accurate latency calculation.
104270817Spluknet	 */
10564499Swollman	uint_t	(*audio_engine_qlen)(void *);
10664499Swollman
10786222Swollman	/*
10886222Swollman	 * If the driver doesn't use simple interleaving, then we need to
10986222Swollman	 * know more about the offsets of channels within the buffer.
11086222Swollman	 * We obtain both the starting offset within the buffer, and the
11186222Swollman	 * increment for each new sample.  As usual, these are given in
112286751Sedwin	 * samples.  If this entry point is NULL, the framework assumes
11386222Swollman	 * that simple interlevaing is used instead.
11486222Swollman	 */
11586222Swollman	void	(*audio_engine_chinfo)(void *, int chan, uint_t *offset,
11686222Swollman	    uint_t *incr);
11786222Swollman
11886222Swollman	/*
11986222Swollman	 * The following entry point is used to determine the play ahead
12086222Swollman	 * desired by the engine.  Engines with less consistent scheduling,
12186222Swollman	 * or with a need for deeper queuing, implement this.  If not
12286222Swollman	 * implemented, the framework assumes 1.5 * fragfr.
12386222Swollman	 */
12486222Swollman	uint_t	(*audio_engine_playahead)(void *);
12586222Swollman};
12686222Swollman
12786222Swollman/*
12886222Swollman * Drivers call these.
12986222Swollman */
130175034Sedwinvoid audio_init_ops(struct dev_ops *, const char *);
131175034Sedwinvoid audio_fini_ops(struct dev_ops *);
132175034Sedwin
133175034Sedwinaudio_dev_t *audio_dev_alloc(dev_info_t *, int);
134175034Sedwinvoid audio_dev_free(audio_dev_t *);
135175034Sedwin
136175034Sedwinvoid audio_dev_set_description(audio_dev_t *, const char *);
137270817Spluknetvoid audio_dev_set_version(audio_dev_t *, const char *);
138175034Sedwinvoid audio_dev_add_info(audio_dev_t *, const char *);
139270817Spluknet
140175034Sedwinaudio_engine_t *audio_engine_alloc(audio_engine_ops_t *, uint_t);
141175034Sedwinvoid audio_engine_set_private(audio_engine_t *, void *);
142175034Sedwinvoid *audio_engine_get_private(audio_engine_t *);
143175034Sedwinvoid audio_engine_free(audio_engine_t *);
144175034Sedwin
145175034Sedwinvoid audio_dev_add_engine(audio_dev_t *, audio_engine_t *);
146175034Sedwinvoid audio_dev_remove_engine(audio_dev_t *, audio_engine_t *);
147175034Sedwinint audio_dev_register(audio_dev_t *);
148183066Sedwinint audio_dev_unregister(audio_dev_t *);
149183066Sedwinvoid audio_dev_suspend(audio_dev_t *);
150183066Sedwinvoid audio_dev_resume(audio_dev_t *);
151183066Sedwinvoid audio_dev_warn(audio_dev_t *, const char *, ...);
152183066Sedwin
153183066Sedwin/* DEBUG ONLY */
154183066Sedwinvoid audio_dump_bytes(const uint8_t *w, int dcount);
155183066Sedwinvoid audio_dump_words(const uint16_t *w, int dcount);
156286751Sedwinvoid audio_dump_dwords(const uint32_t *w, int dcount);
157286751Sedwin
158286751Sedwin
159183864Sedwin/* Engine flags */
160286751Sedwin#define	ENGINE_OUTPUT_CAP	(1U << 2)
161183864Sedwin#define	ENGINE_INPUT_CAP	(1U << 3)
162183864Sedwin#define	ENGINE_CAPS		(ENGINE_OUTPUT_CAP | ENGINE_INPUT_CAP)
163183864Sedwin#define	ENGINE_DRIVER_FLAGS	(0xffff)	/* flags usable by driver */
164184406Sedwin
165273719Sedwin#define	ENGINE_OUTPUT		(1U << 16)	/* fields not for driver use */
166273719Sedwin#define	ENGINE_INPUT		(1U << 17)
167184406Sedwin#define	ENGINE_EXCLUSIVE	(1U << 20)	/* exclusive use, e.g. AC3 */
168184406Sedwin#define	ENGINE_NDELAY		(1U << 21)	/* non-blocking open */
169270817Spluknet
170270817Spluknet/*
171270817Spluknet * entry points used by legacy SADA drivers
172270817Spluknet */
173184406Sedwinint audio_legacy_open(queue_t *, dev_t *, int, int, cred_t *);
174184406Sedwinint audio_legacy_close(queue_t *, int, cred_t *);
175273719Sedwinint audio_legacy_wput(queue_t *, mblk_t *);
176273719Sedwinint audio_legacy_wsrv(queue_t *);
177273719Sedwin
178184406Sedwin
179184406Sedwin
180198515Sedwin/*
181198515Sedwin * Audio device controls
182198515Sedwin */
183273719Sedwin
184273719Sedwin/*
185198515Sedwin * Control read or write driver function type.
186270817Spluknet *
187270817Spluknet * Returns zero on success, errno on failure.
188270817Spluknet */
189270817Spluknettypedef int (*audio_ctrl_wr_t)(void *, uint64_t);
190270817Spluknettypedef int (*audio_ctrl_rd_t)(void *, uint64_t *);
191270817Spluknet
192198515Sedwin
193331986Sgordon/*
194198515Sedwin * This will allocate and register a control for my audio device.
195331986Sgordon *
196240457Sedwin * On success this will return a control structure else NULL.
197136638Swollman */
198136638Swollmanaudio_ctrl_t *audio_dev_add_control(audio_dev_t *,
199136638Swollman    audio_ctrl_desc_t *, audio_ctrl_rd_t, audio_ctrl_wr_t, void *);
200136638Swollman
201136638Swollman/*
202136638Swollman * Add a synthetic PCM volume control.  This should only be used by
203136638Swollman * devices which have no physical PCM volume controls.  The control
20493799Swollman * implements a simple attenuator on the PCM data; unlike AC'97 there
205331986Sgordon * is no "gain", so using this instead of a hardware control may
206273719Sedwin * result in loss range.  The control is implemented using
207273719Sedwin * AUDIO_CTRL_ID_VOLUME.
208270817Spluknet */
20993799Swollmanvoid audio_dev_add_soft_volume(audio_dev_t *);
210331986Sgordon
211331986Sgordon/*
212331986Sgordon * This will remove a control from an audio device.
213136638Swollman */
214136638Swollmanvoid audio_dev_del_control(audio_ctrl_t *);
215136638Swollman
216136638Swollman/*
217136638Swollman * This will tell the framework that controls have changed
218136638Swollman * and it should update its values.
219136638Swollman */
220136638Swollmanvoid audio_dev_update_controls(audio_dev_t *);
221136638Swollman
222136638Swollman/*
223136638Swollman * This is used to read the current value of a control.
224136638Swollman * Note, this will cause a callback into the driver to get the value.
225270817Spluknet *
226136638Swollman * On return zero is returned on success else errno is returned.
227136638Swollman */
228270817Spluknetint audio_control_read(audio_ctrl_t *, uint64_t *);
229136638Swollman
230136638Swollman/*
231136638Swollman * This is used to write a value to a control.
232136638Swollman * Note, this will cause a callback into the driver to write the value.
233136638Swollman *
234136638Swollman * On return zero is returned on success else errno is returned.
235136638Swollman */
236136638Swollmanint audio_control_write(audio_ctrl_t *, uint64_t);
237136638Swollman
238136638Swollman#endif	/* _KERNEL */
239136638Swollman
240136638Swollman#ifdef	__cplusplus
241136638Swollman}
242136638Swollman#endif
243136638Swollman
244136638Swollman#endif	/* _SYS_AUDIO_AUDIO_DRIVER_H */
245136638Swollman