188447a05SGarrett D'Amore /*
288447a05SGarrett D'Amore  * CDDL HEADER START
388447a05SGarrett D'Amore  *
488447a05SGarrett D'Amore  * The contents of this file are subject to the terms of the
588447a05SGarrett D'Amore  * Common Development and Distribution License (the "License").
688447a05SGarrett D'Amore  * You may not use this file except in compliance with the License.
788447a05SGarrett D'Amore  *
888447a05SGarrett D'Amore  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
988447a05SGarrett D'Amore  * or http://www.opensolaris.org/os/licensing.
1088447a05SGarrett D'Amore  * See the License for the specific language governing permissions
1188447a05SGarrett D'Amore  * and limitations under the License.
1288447a05SGarrett D'Amore  *
1388447a05SGarrett D'Amore  * When distributing Covered Code, include this CDDL HEADER in each
1488447a05SGarrett D'Amore  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1588447a05SGarrett D'Amore  * If applicable, add the following below this CDDL HEADER, with the
1688447a05SGarrett D'Amore  * fields enclosed by brackets "[]" replaced with your own identifying
1788447a05SGarrett D'Amore  * information: Portions Copyright [yyyy] [name of copyright owner]
1888447a05SGarrett D'Amore  *
1988447a05SGarrett D'Amore  * CDDL HEADER END
2088447a05SGarrett D'Amore  */
2188447a05SGarrett D'Amore /*
2288447a05SGarrett D'Amore  * Copyright (C) 4Front Technologies 1996-2008.
2388447a05SGarrett D'Amore  *
24*2c30fa45SGarrett D'Amore  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
2588447a05SGarrett D'Amore  */
2688447a05SGarrett D'Amore 
2788447a05SGarrett D'Amore #ifndef	_AUDIO_IMPL_H
2888447a05SGarrett D'Amore #define	_AUDIO_IMPL_H
2988447a05SGarrett D'Amore 
3088447a05SGarrett D'Amore #include <sys/types.h>
3188447a05SGarrett D'Amore #include <sys/list.h>
3288447a05SGarrett D'Amore #include <sys/poll.h>
3388447a05SGarrett D'Amore 
3488447a05SGarrett D'Amore #include <sys/audio/audio_driver.h>
3588447a05SGarrett D'Amore #include "audio_client.h"
3688447a05SGarrett D'Amore 
3788447a05SGarrett D'Amore #define	AUDIO_MAX_OPENS		256
3888447a05SGarrett D'Amore #define	AUDIO_MAX_CHANNELS	16
3988447a05SGarrett D'Amore #define	AUDIO_UNIT_EXPAND	1024
4088447a05SGarrett D'Amore #define	AUDIO_CHBUFS		2048	/* samples for mixing */
4188447a05SGarrett D'Amore #define	AUDIO_VOL_SCALE		256
4288447a05SGarrett D'Amore #define	AUDIO_DB_SIZE		50
4388447a05SGarrett D'Amore 
4468c47f65SGarrett D'Amore #define	AUDIO_INTRHZ		100
4568c47f65SGarrett D'Amore #define	AUDIO_INTRHZ_MIN	50	/* 20 msec max */
4668c47f65SGarrett D'Amore #define	AUDIO_INTRHZ_MAX	500
4768c47f65SGarrett D'Amore 
4888447a05SGarrett D'Amore struct audio_parms {
4988447a05SGarrett D'Amore 	int		p_format;
5088447a05SGarrett D'Amore 	int		p_rate;
5188447a05SGarrett D'Amore 	int		p_nchan;
5288447a05SGarrett D'Amore };
5388447a05SGarrett D'Amore 
5488447a05SGarrett D'Amore typedef int (*audio_cnv_func_t)(audio_stream_t *, int);
5588447a05SGarrett D'Amore 
5688447a05SGarrett D'Amore struct audio_buffer {
5788447a05SGarrett D'Amore 	caddr_t			b_data;
5888447a05SGarrett D'Amore 	uint64_t		b_head;
5988447a05SGarrett D'Amore 	uint64_t		b_tail;
6068c47f65SGarrett D'Amore 	uint_t			b_hidx;		/* head % nframes */
6168c47f65SGarrett D'Amore 	uint_t			b_tidx;		/* tail % nframes */
6268c47f65SGarrett D'Amore 	uint_t			b_nframes;	/* total frames */
6368c47f65SGarrett D'Amore 	uint_t			b_framesz;	/* bytes per frame  */
6488447a05SGarrett D'Amore };
6588447a05SGarrett D'Amore 
6688447a05SGarrett D'Amore /*
6788447a05SGarrett D'Amore  * struct audio_stream: This structure represents a virtual stream exposed
6888447a05SGarrett D'Amore  * to a single client.  Each client will have at most two of these (one for
6988447a05SGarrett D'Amore  * record, one for playback.)
7088447a05SGarrett D'Amore  */
7188447a05SGarrett D'Amore struct audio_stream {
7288447a05SGarrett D'Amore 	audio_buffer_t		s_buf;
7388447a05SGarrett D'Amore #define	s_data			s_buf.b_data
7488447a05SGarrett D'Amore #define	s_bufsz			s_buf.b_size
7588447a05SGarrett D'Amore #define	s_head			s_buf.b_head
7688447a05SGarrett D'Amore #define	s_tail			s_buf.b_tail
7788447a05SGarrett D'Amore #define	s_framesz		s_buf.b_framesz
7888447a05SGarrett D'Amore #define	s_nframes		s_buf.b_nframes
7988447a05SGarrett D'Amore #define	s_tidx			s_buf.b_tidx
8088447a05SGarrett D'Amore #define	s_hidx			s_buf.b_hidx
8168c47f65SGarrett D'Amore 	uint_t			s_nfrags;
8268c47f65SGarrett D'Amore 	uint_t			s_fragfr;
8368c47f65SGarrett D'Amore 	uint_t			s_nbytes;
8468c47f65SGarrett D'Amore 	uint_t			s_fragbytes;
8588447a05SGarrett D'Amore 	ddi_umem_cookie_t	s_cookie;
86a702341cSGarrett D'Amore 	uint32_t		s_allocsz;
87a702341cSGarrett D'Amore 	uint32_t		s_hintsz;	/* latency hints */
88a702341cSGarrett D'Amore 	uint16_t		s_hintfrags;
8988447a05SGarrett D'Amore 
9088447a05SGarrett D'Amore 	/*
9188447a05SGarrett D'Amore 	 * Various counters.
9288447a05SGarrett D'Amore 	 */
9388447a05SGarrett D'Amore 	uint64_t		s_samples;
9488447a05SGarrett D'Amore 	uint64_t		s_errors;	/* underrun or overrun count */
9588447a05SGarrett D'Amore 
9688447a05SGarrett D'Amore 	boolean_t		s_running;
9788447a05SGarrett D'Amore 	boolean_t		s_paused;	/* stream paused */
9888447a05SGarrett D'Amore 	boolean_t		s_draining;	/* stream draining */
9988447a05SGarrett D'Amore 
10088447a05SGarrett D'Amore 	/*
10188447a05SGarrett D'Amore 	 * Sample rate conversion (SRC) and format conversion details.
10288447a05SGarrett D'Amore 	 */
10388447a05SGarrett D'Amore 	struct grc3state	*s_src_state[AUDIO_MAX_CHANNELS];
10468c47f65SGarrett D'Amore 	uint_t			s_src_quality;
10588447a05SGarrett D'Amore 	int			s_cnv_max;
10688447a05SGarrett D'Amore 	audio_cnv_func_t	s_converter;
10788447a05SGarrett D'Amore 	uint32_t		*s_cnv_buf0;
10888447a05SGarrett D'Amore 	uint32_t		*s_cnv_buf1;
10988447a05SGarrett D'Amore 	void			*s_cnv_src;
11088447a05SGarrett D'Amore 	void			*s_cnv_dst;
11188447a05SGarrett D'Amore 	audio_parms_t		s_cnv_src_parms;
11288447a05SGarrett D'Amore #define	s_cnv_src_nchan		s_cnv_src_parms.p_nchan
11388447a05SGarrett D'Amore #define	s_cnv_src_rate		s_cnv_src_parms.p_rate
11488447a05SGarrett D'Amore #define	s_cnv_src_format	s_cnv_src_parms.p_format
11588447a05SGarrett D'Amore 
11688447a05SGarrett D'Amore 	audio_parms_t		s_cnv_dst_parms;
11788447a05SGarrett D'Amore #define	s_cnv_dst_nchan		s_cnv_dst_parms.p_nchan
11888447a05SGarrett D'Amore #define	s_cnv_dst_rate		s_cnv_dst_parms.p_rate
11988447a05SGarrett D'Amore #define	s_cnv_dst_format	s_cnv_dst_parms.p_format
12088447a05SGarrett D'Amore 
12188447a05SGarrett D'Amore 	size_t			s_cnv_cnt;
12288447a05SGarrett D'Amore 	int32_t			*s_cnv_ptr;
12388447a05SGarrett D'Amore 
12488447a05SGarrett D'Amore 	audio_parms_t		*s_user_parms;
12588447a05SGarrett D'Amore 	audio_parms_t		*s_phys_parms;
12688447a05SGarrett D'Amore 
12788447a05SGarrett D'Amore 	/*
12888447a05SGarrett D'Amore 	 * Volume.
12988447a05SGarrett D'Amore 	 */
13088447a05SGarrett D'Amore 	uint8_t			s_gain_master;
13188447a05SGarrett D'Amore 	uint8_t			s_gain_pct;
13288447a05SGarrett D'Amore 	uint16_t		s_gain_scaled;
13388447a05SGarrett D'Amore 	uint16_t		s_gain_eff;
13488447a05SGarrett D'Amore 	boolean_t		s_muted;
13588447a05SGarrett D'Amore 
13688447a05SGarrett D'Amore 	/*
13788447a05SGarrett D'Amore 	 * Callbacks.
13888447a05SGarrett D'Amore 	 */
13988447a05SGarrett D'Amore 	uint64_t		s_drain_idx;	/* engine index */
14088447a05SGarrett D'Amore 
14188447a05SGarrett D'Amore 	/*
14288447a05SGarrett D'Amore 	 * Other per stream details, e.g. channel offset, etc.
14388447a05SGarrett D'Amore 	 */
14488447a05SGarrett D'Amore 	kmutex_t		s_lock;
14588447a05SGarrett D'Amore 	kcondvar_t		s_cv;
14688447a05SGarrett D'Amore 	list_node_t		s_eng_linkage;	/*  place on engine list */
14788447a05SGarrett D'Amore 	audio_client_t		*s_client;
14888447a05SGarrett D'Amore 	audio_engine_t		*s_engine;
14988447a05SGarrett D'Amore 	int			s_choffs;
15088447a05SGarrett D'Amore 
15188447a05SGarrett D'Amore 	/*
15288447a05SGarrett D'Amore 	 * Other bits.
15388447a05SGarrett D'Amore 	 */
15468c47f65SGarrett D'Amore 	uint_t			s_engcap;	/* ENGINE_xxx_CAP */
15588447a05SGarrett D'Amore };
15688447a05SGarrett D'Amore 
15788447a05SGarrett D'Amore /*
15888447a05SGarrett D'Amore  * struct audio_client: This structure represents a logical port,
15988447a05SGarrett D'Amore  * associated with an open file, etc.  These are the entities that are
16088447a05SGarrett D'Amore  * mixed.
16188447a05SGarrett D'Amore  */
16288447a05SGarrett D'Amore struct audio_client {
16388447a05SGarrett D'Amore 	audio_stream_t		c_istream;
16488447a05SGarrett D'Amore 	audio_stream_t		c_ostream;
16588447a05SGarrett D'Amore 	void			*c_private;
16688447a05SGarrett D'Amore 
16768c47f65SGarrett D'Amore 	/*
16868c47f65SGarrett D'Amore 	 * We can keep a linked list of clients to "notify" so that
16968c47f65SGarrett D'Amore 	 * we can do this outside of locked context.
17068c47f65SGarrett D'Amore 	 */
17168c47f65SGarrett D'Amore 	audio_client_t		*c_next_input;
17268c47f65SGarrett D'Amore 	audio_client_t		*c_next_output;
17368c47f65SGarrett D'Amore 	audio_client_t		*c_next_drain;
17468c47f65SGarrett D'Amore 
17588447a05SGarrett D'Amore 	/*
17688447a05SGarrett D'Amore 	 * DDI support.
17788447a05SGarrett D'Amore 	 */
17888447a05SGarrett D'Amore 	major_t			c_major;
17988447a05SGarrett D'Amore 	minor_t			c_minor;
18088447a05SGarrett D'Amore 	minor_t			c_origminor;
181a19bb1faSGarrett D'Amore 	queue_t			*c_rq;
182a19bb1faSGarrett D'Amore 	queue_t			*c_wq;
18388447a05SGarrett D'Amore 
18488447a05SGarrett D'Amore 	/*
18588447a05SGarrett D'Amore 	 * Linkage for per-device list of clients.
18688447a05SGarrett D'Amore 	 */
18788447a05SGarrett D'Amore 	list_node_t		c_global_linkage;
18888447a05SGarrett D'Amore 	list_node_t		c_dev_linkage;
18988447a05SGarrett D'Amore 	int			c_refcnt;
19068c47f65SGarrett D'Amore 	boolean_t		c_serialize;
19188447a05SGarrett D'Amore 
19288447a05SGarrett D'Amore 	kmutex_t		c_lock;
19388447a05SGarrett D'Amore 	kcondvar_t		c_cv;
19453a539a7SGarrett D'Amore 	boolean_t		c_is_active;
19588447a05SGarrett D'Amore 
19688447a05SGarrett D'Amore 	/*
19788447a05SGarrett D'Amore 	 * Client wide settings... e.g. ops vector, etc.
19888447a05SGarrett D'Amore 	 */
19968c47f65SGarrett D'Amore 	uint_t			c_omode;	/* open mode */
20088447a05SGarrett D'Amore 	pid_t			c_pid;		/* opening process id */
20188447a05SGarrett D'Amore 	audio_dev_t		*c_dev;
20288447a05SGarrett D'Amore 	cred_t			*c_cred;
20388447a05SGarrett D'Amore 	audio_client_ops_t	c_ops;
20488447a05SGarrett D'Amore #define	c_open			c_ops.aco_open
20588447a05SGarrett D'Amore #define	c_close			c_ops.aco_close
20688447a05SGarrett D'Amore #define	c_read			c_ops.aco_read
20788447a05SGarrett D'Amore #define	c_write			c_ops.aco_write
20888447a05SGarrett D'Amore #define	c_ioctl			c_ops.aco_ioctl
20988447a05SGarrett D'Amore #define	c_chpoll		c_ops.aco_chpoll
21088447a05SGarrett D'Amore #define	c_output		c_ops.aco_output
21188447a05SGarrett D'Amore #define	c_input			c_ops.aco_input
21288447a05SGarrett D'Amore #define	c_notify		c_ops.aco_notify
21388447a05SGarrett D'Amore #define	c_drain			c_ops.aco_drain
214a19bb1faSGarrett D'Amore #define	c_wput			c_ops.aco_wput
215a19bb1faSGarrett D'Amore #define	c_wsrv			c_ops.aco_wsrv
216682cb104SGarrett D'Amore #define	c_rsrv			c_ops.aco_rsrv
21788447a05SGarrett D'Amore 
21888447a05SGarrett D'Amore 	struct pollhead		c_pollhead;
21988447a05SGarrett D'Amore 
22088447a05SGarrett D'Amore };
22188447a05SGarrett D'Amore 
22288447a05SGarrett D'Amore struct audio_infostr {
22388447a05SGarrett D'Amore 	char			i_line[100];
22488447a05SGarrett D'Amore 	list_node_t		i_linkage;
22588447a05SGarrett D'Amore };
22688447a05SGarrett D'Amore 
22788447a05SGarrett D'Amore struct audio_stats {
22888447a05SGarrett D'Amore 	kstat_named_t		st_head;
22988447a05SGarrett D'Amore 	kstat_named_t		st_tail;
23088447a05SGarrett D'Amore 	kstat_named_t		st_flags;
23188447a05SGarrett D'Amore 	kstat_named_t		st_nfrags;
23288447a05SGarrett D'Amore 	kstat_named_t		st_framesz;
23388447a05SGarrett D'Amore 	kstat_named_t		st_nbytes;
23488447a05SGarrett D'Amore 	kstat_named_t		st_hidx;
23588447a05SGarrett D'Amore 	kstat_named_t		st_tidx;
23688447a05SGarrett D'Amore 	kstat_named_t		st_format;
23788447a05SGarrett D'Amore 	kstat_named_t		st_nchan;
23888447a05SGarrett D'Amore 	kstat_named_t		st_rate;
23988447a05SGarrett D'Amore 	kstat_named_t		st_errors;
240a19bb1faSGarrett D'Amore 	kstat_named_t		st_engine_underruns;
241a19bb1faSGarrett D'Amore 	kstat_named_t		st_engine_overruns;
242a19bb1faSGarrett D'Amore 	kstat_named_t		st_stream_underruns;
243a19bb1faSGarrett D'Amore 	kstat_named_t		st_stream_overruns;
24468c47f65SGarrett D'Amore 	kstat_named_t		st_playahead;
24588447a05SGarrett D'Amore 	kstat_named_t		st_suspended;
24668c47f65SGarrett D'Amore 	kstat_named_t		st_failed;
24788447a05SGarrett D'Amore };
24888447a05SGarrett D'Amore 
24968c47f65SGarrett D'Amore typedef void (*audio_import_fn_t)(audio_engine_t *, uint_t, audio_stream_t *);
25068c47f65SGarrett D'Amore typedef void (*audio_export_fn_t)(audio_engine_t *, uint_t, uint_t);
25168c47f65SGarrett D'Amore 
25288447a05SGarrett D'Amore /*
25388447a05SGarrett D'Amore  * An audio engine corresponds to a single DMA transfer channel.  It can
25488447a05SGarrett D'Amore  * represent either record or playback, but not both at the same time.
25588447a05SGarrett D'Amore  * A device that supports simultaneous record and playback will register
25688447a05SGarrett D'Amore  * separate channels.
25788447a05SGarrett D'Amore  */
25888447a05SGarrett D'Amore struct audio_engine {
25988447a05SGarrett D'Amore 	audio_engine_ops_t	e_ops;
26088447a05SGarrett D'Amore 	void			*e_private;
26168c47f65SGarrett D'Amore 	uint_t			e_flags;
26288447a05SGarrett D'Amore 
26388447a05SGarrett D'Amore 	/*
26488447a05SGarrett D'Amore 	 * Mixing related fields.
26588447a05SGarrett D'Amore 	 */
26668c47f65SGarrett D'Amore 	uint_t			e_limiter_state;
26788447a05SGarrett D'Amore 	int32_t			*e_chbufs[AUDIO_MAX_CHANNELS];
26868c47f65SGarrett D'Amore 	uint_t			e_choffs[AUDIO_MAX_CHANNELS];
26968c47f65SGarrett D'Amore 	uint_t			e_chincr[AUDIO_MAX_CHANNELS];
27068c47f65SGarrett D'Amore 	audio_export_fn_t	e_export;
27168c47f65SGarrett D'Amore 	audio_import_fn_t	e_import;
27288447a05SGarrett D'Amore 
27388447a05SGarrett D'Amore 	/*
27488447a05SGarrett D'Amore 	 * Underlying physical buffer shared with device driver.
27588447a05SGarrett D'Amore 	 */
27688447a05SGarrett D'Amore 	audio_buffer_t		e_buf;
27788447a05SGarrett D'Amore #define	e_head			e_buf.b_head
27888447a05SGarrett D'Amore #define	e_tail			e_buf.b_tail
27988447a05SGarrett D'Amore #define	e_data			e_buf.b_data
28088447a05SGarrett D'Amore #define	e_framesz		e_buf.b_framesz
28188447a05SGarrett D'Amore #define	e_nframes		e_buf.b_nframes
28288447a05SGarrett D'Amore #define	e_hidx			e_buf.b_hidx
28388447a05SGarrett D'Amore #define	e_tidx			e_buf.b_tidx
28468c47f65SGarrett D'Amore 	uint_t			e_fragfr;
28568c47f65SGarrett D'Amore 	uint_t			e_playahead;
286f9ead4a5SGarrett D'Amore 
28788447a05SGarrett D'Amore 	int			e_errors;
288a19bb1faSGarrett D'Amore 	int			e_overruns;
289a19bb1faSGarrett D'Amore 	int			e_underruns;
290a19bb1faSGarrett D'Amore 	int			e_stream_overruns;
291a19bb1faSGarrett D'Amore 	int			e_stream_underruns;
29288447a05SGarrett D'Amore 
29388447a05SGarrett D'Amore 	audio_parms_t		e_parms;
29488447a05SGarrett D'Amore #define	e_format		e_parms.p_format
29588447a05SGarrett D'Amore #define	e_nchan			e_parms.p_nchan
29688447a05SGarrett D'Amore #define	e_rate			e_parms.p_rate
29788447a05SGarrett D'Amore 
29888447a05SGarrett D'Amore 	/*
29988447a05SGarrett D'Amore 	 * Statistics.
30088447a05SGarrett D'Amore 	 */
30188447a05SGarrett D'Amore 	kstat_t			*e_ksp;
30288447a05SGarrett D'Amore 	struct audio_stats	e_stats;
30388447a05SGarrett D'Amore 
30488447a05SGarrett D'Amore 
30588447a05SGarrett D'Amore 	/*
30688447a05SGarrett D'Amore 	 * Synchronization.
30788447a05SGarrett D'Amore 	 */
30888447a05SGarrett D'Amore 	kmutex_t		e_lock;
30968c47f65SGarrett D'Amore 	kcondvar_t		e_cv;
31068c47f65SGarrett D'Amore 	ddi_periodic_t		e_periodic;
31188447a05SGarrett D'Amore 
31288447a05SGarrett D'Amore 	/*
31388447a05SGarrett D'Amore 	 * Linkage for per-device list.
31488447a05SGarrett D'Amore 	 */
31588447a05SGarrett D'Amore 	list_node_t		e_dev_linkage;
31688447a05SGarrett D'Amore 	audio_dev_t		*e_dev;
31788447a05SGarrett D'Amore 	int			e_num;	/* arbitrary engine number */
31888447a05SGarrett D'Amore 
31988447a05SGarrett D'Amore 	/*
32088447a05SGarrett D'Amore 	 * List of of streams attached to this engine.
32188447a05SGarrett D'Amore 	 */
32288447a05SGarrett D'Amore 	list_t			e_streams;
323*2c30fa45SGarrett D'Amore 	boolean_t		e_suspended;
32468c47f65SGarrett D'Amore 	boolean_t		e_failed;
32568c47f65SGarrett D'Amore 
32668c47f65SGarrett D'Amore 	boolean_t		e_need_start;
32788447a05SGarrett D'Amore };
32888447a05SGarrett D'Amore 
32988447a05SGarrett D'Amore struct audio_dev {
33088447a05SGarrett D'Amore 	dev_info_t		*d_dip;
33188447a05SGarrett D'Amore 	major_t			d_major;
33288447a05SGarrett D'Amore 	int			d_instance;
33388447a05SGarrett D'Amore 
33488447a05SGarrett D'Amore 	uint32_t		d_flags;
33588447a05SGarrett D'Amore #define	DEV_OUTPUT_CAP		(1U << 0)
33688447a05SGarrett D'Amore #define	DEV_INPUT_CAP		(1U << 1)
33788447a05SGarrett D'Amore #define	DEV_DUPLEX_CAP		(1U << 2)
33888447a05SGarrett D'Amore #define	DEV_SNDSTAT_CAP		(1U << 3)
33926025630SGarrett D'Amore #define	DEV_OPAQUE_CAP		(1U << 4)	/* AC3 are not mixable */
34088447a05SGarrett D'Amore 
34188447a05SGarrett D'Amore 	char			d_name[128];	/* generic description */
34288447a05SGarrett D'Amore 	char			d_desc[128];	/* detailed config descr */
34388447a05SGarrett D'Amore 	char			d_vers[128];	/* detailed version descr */
34488447a05SGarrett D'Amore 	int			d_number;	/* global /dev/audioXX # */
34588447a05SGarrett D'Amore 	int			d_index;	/* master device index */
34688447a05SGarrett D'Amore 	int			d_engno;	/* engine counter */
34788447a05SGarrett D'Amore 
34888447a05SGarrett D'Amore 	list_t			d_hwinfo;	/* strings of hw info */
34988447a05SGarrett D'Amore 
35088447a05SGarrett D'Amore 	/*
35188447a05SGarrett D'Amore 	 * Synchronization.
35288447a05SGarrett D'Amore 	 */
35388447a05SGarrett D'Amore 	kmutex_t		d_lock;
35488447a05SGarrett D'Amore 	kcondvar_t		d_cv;
35568c47f65SGarrett D'Amore 	kmutex_t		d_ctrl_lock;	/* leaf lock */
35668c47f65SGarrett D'Amore 	kcondvar_t		d_ctrl_cv;
35788447a05SGarrett D'Amore 	krwlock_t		d_clnt_lock;
35868c47f65SGarrett D'Amore 	uint_t			d_refcnt;
35968c47f65SGarrett D'Amore 	int			d_suspended;
36068c47f65SGarrett D'Amore 	boolean_t		d_failed;
36188447a05SGarrett D'Amore 
36288447a05SGarrett D'Amore 	/*
36388447a05SGarrett D'Amore 	 * Lists of virtual clients, controls and engines.  Protected by
36488447a05SGarrett D'Amore 	 * the d_lock field above.
36588447a05SGarrett D'Amore 	 */
36688447a05SGarrett D'Amore 	list_t			d_clients;
36788447a05SGarrett D'Amore 	list_t			d_engines;
36888447a05SGarrett D'Amore 	list_t			d_controls;
36988447a05SGarrett D'Amore 	audio_ctrl_t		*d_pcmvol_ctrl;
37088447a05SGarrett D'Amore 	uint64_t		d_pcmvol;
37188447a05SGarrett D'Amore 
37268c47f65SGarrett D'Amore 	volatile uint_t		d_serial;
373682cb104SGarrett D'Amore 
37488447a05SGarrett D'Amore 	/*
37588447a05SGarrett D'Amore 	 * Linkage onto global list of devices.
37688447a05SGarrett D'Amore 	 */
37788447a05SGarrett D'Amore 	list_node_t		d_by_index;
37888447a05SGarrett D'Amore 	list_node_t		d_by_number;
37988447a05SGarrett D'Amore 
38088447a05SGarrett D'Amore 	/*
38188447a05SGarrett D'Amore 	 * Personality specific data.
38288447a05SGarrett D'Amore 	 */
38388447a05SGarrett D'Amore 	void			*d_minor_data[1 << AUDIO_MN_TYPE_NBITS];
38488447a05SGarrett D'Amore };
38588447a05SGarrett D'Amore 
38688447a05SGarrett D'Amore /*
38788447a05SGarrett D'Amore  * Each audio_dev optionally can have controls attached to it.
38888447a05SGarrett D'Amore  * Controls are separate from audio engines. They are methods of
38988447a05SGarrett D'Amore  * adjusting pharameters or reading metrics that usually relate to
39088447a05SGarrett D'Amore  * hardware on devices engine by the driver. They can be things like
39188447a05SGarrett D'Amore  * master volume for example.
39288447a05SGarrett D'Amore  *
39388447a05SGarrett D'Amore  * If the driver does not support controls then it must insure
39488447a05SGarrett D'Amore  * that any hardware controls are initialized to a usable state.
39588447a05SGarrett D'Amore  *
39688447a05SGarrett D'Amore  * For the framework/user-apps to be able to change controls
39788447a05SGarrett D'Amore  * the driver must create, enable and configure controls with
39888447a05SGarrett D'Amore  * control API's.
39988447a05SGarrett D'Amore  *
40088447a05SGarrett D'Amore  * There are a number of common controls (well-known) that most
40188447a05SGarrett D'Amore  * hardware supports. These have known names and known ctrl numbers.
40288447a05SGarrett D'Amore  * In addition a driver can have any number of extention
40388447a05SGarrett D'Amore  * controls (device-private). These can have any name and any ctrl
40488447a05SGarrett D'Amore  * number other then the ones, defined as well-knonw ones.
40588447a05SGarrett D'Amore  *
40688447a05SGarrett D'Amore  * Only controls created through control API's will be available,
40788447a05SGarrett D'Amore  * well-known or device-private.
40888447a05SGarrett D'Amore  */
40988447a05SGarrett D'Amore struct	audio_ctrl {
41088447a05SGarrett D'Amore 	audio_ctrl_desc_t	ctrl_des;
41188447a05SGarrett D'Amore #define	ctrl_name		ctrl_des.acd_name
41288447a05SGarrett D'Amore #define	ctrl_type		ctrl_des.acd_type
41388447a05SGarrett D'Amore #define	ctrl_enum		ctrl_des.acd_enum
41488447a05SGarrett D'Amore #define	ctrl_flags		ctrl_des.acd_flags
41588447a05SGarrett D'Amore 	audio_dev_t		*ctrl_dev;
41688447a05SGarrett D'Amore 	audio_ctrl_rd_t		ctrl_read_fn;
41788447a05SGarrett D'Amore 	audio_ctrl_wr_t		ctrl_write_fn;
41888447a05SGarrett D'Amore 	list_node_t		ctrl_linkage;
41988447a05SGarrett D'Amore 	void			*ctrl_arg;
42068c47f65SGarrett D'Amore 	uint64_t		ctrl_saved;	/* the saved value */
42168c47f65SGarrett D'Amore 	boolean_t		ctrl_saved_ok;
42288447a05SGarrett D'Amore };
42388447a05SGarrett D'Amore 
42488447a05SGarrett D'Amore 
42588447a05SGarrett D'Amore /*
42688447a05SGarrett D'Amore  * Prototypes.
42788447a05SGarrett D'Amore  */
42888447a05SGarrett D'Amore 
42988447a05SGarrett D'Amore /* audio_format.c */
43088447a05SGarrett D'Amore int auimpl_format_alloc(audio_stream_t *);
43188447a05SGarrett D'Amore void auimpl_format_free(audio_stream_t *);
432*2c30fa45SGarrett D'Amore int auimpl_format_setup(audio_stream_t *, audio_parms_t *, uint_t);
433*2c30fa45SGarrett D'Amore #define	FORMAT_MSK_NONE		(0x0)
434*2c30fa45SGarrett D'Amore #define	FORMAT_MSK_FMT		(0x1)
435*2c30fa45SGarrett D'Amore #define	FORMAT_MSK_RATE		(0x2)
436*2c30fa45SGarrett D'Amore #define	FORMAT_MSK_CHAN		(0x4)
437*2c30fa45SGarrett D'Amore #define	FOMMAT_MSK_ALL		(0x7)
43888447a05SGarrett D'Amore 
43988447a05SGarrett D'Amore /* audio_output.c */
44068c47f65SGarrett D'Amore void auimpl_export_16ne(audio_engine_t *, uint_t, uint_t);
44168c47f65SGarrett D'Amore void auimpl_export_16oe(audio_engine_t *, uint_t, uint_t);
44268c47f65SGarrett D'Amore void auimpl_export_24ne(audio_engine_t *, uint_t, uint_t);
44368c47f65SGarrett D'Amore void auimpl_export_24oe(audio_engine_t *, uint_t, uint_t);
44468c47f65SGarrett D'Amore void auimpl_export_32ne(audio_engine_t *, uint_t, uint_t);
44568c47f65SGarrett D'Amore void auimpl_export_32oe(audio_engine_t *, uint_t, uint_t);
44668c47f65SGarrett D'Amore void auimpl_output_callback(void *);
44768c47f65SGarrett D'Amore void auimpl_output_preload(audio_engine_t *);
44888447a05SGarrett D'Amore 
44988447a05SGarrett D'Amore /* audio_input.c */
45068c47f65SGarrett D'Amore void auimpl_import_16ne(audio_engine_t *, uint_t, audio_stream_t *);
45168c47f65SGarrett D'Amore void auimpl_import_16oe(audio_engine_t *, uint_t, audio_stream_t *);
45268c47f65SGarrett D'Amore void auimpl_import_24ne(audio_engine_t *, uint_t, audio_stream_t *);
45368c47f65SGarrett D'Amore void auimpl_import_24oe(audio_engine_t *, uint_t, audio_stream_t *);
45468c47f65SGarrett D'Amore void auimpl_import_32ne(audio_engine_t *, uint_t, audio_stream_t *);
45568c47f65SGarrett D'Amore void auimpl_import_32oe(audio_engine_t *, uint_t, audio_stream_t *);
45668c47f65SGarrett D'Amore void auimpl_input_callback(void *);
45788447a05SGarrett D'Amore int auimpl_input_drain(audio_stream_t *);
45888447a05SGarrett D'Amore 
45988447a05SGarrett D'Amore /* audio_client.c */
46088447a05SGarrett D'Amore void auimpl_client_init(void);
46188447a05SGarrett D'Amore void auimpl_client_fini(void);
46288447a05SGarrett D'Amore audio_client_t *auimpl_client_create(dev_t);
46388447a05SGarrett D'Amore void auimpl_client_destroy(audio_client_t *);
46453a539a7SGarrett D'Amore void auimpl_client_activate(audio_client_t *);
46553a539a7SGarrett D'Amore void auimpl_client_deactivate(audio_client_t *);
46688447a05SGarrett D'Amore int auimpl_create_minors(audio_dev_t *);
46788447a05SGarrett D'Amore void auimpl_remove_minors(audio_dev_t *);
46853a539a7SGarrett D'Amore int auimpl_set_pcmvol(void *, uint64_t);
46953a539a7SGarrett D'Amore int auimpl_get_pcmvol(void *, uint64_t *);
47088447a05SGarrett D'Amore 
47168c47f65SGarrett D'Amore /* audio_ctrl.c */
47268c47f65SGarrett D'Amore int auimpl_save_controls(audio_dev_t *);
47368c47f65SGarrett D'Amore int auimpl_restore_controls(audio_dev_t *);
47468c47f65SGarrett D'Amore 
47588447a05SGarrett D'Amore /* audio_engine.c */
47668c47f65SGarrett D'Amore extern int audio_priority;
47788447a05SGarrett D'Amore void auimpl_dev_init(void);
47888447a05SGarrett D'Amore void auimpl_dev_fini(void);
47988447a05SGarrett D'Amore void auimpl_dev_hold(audio_dev_t *);
48088447a05SGarrett D'Amore audio_dev_t *auimpl_dev_hold_by_devt(dev_t);
48188447a05SGarrett D'Amore audio_dev_t *auimpl_dev_hold_by_index(int);
48288447a05SGarrett D'Amore void auimpl_dev_release(audio_dev_t *);
48388447a05SGarrett D'Amore int auimpl_choose_format(int);
48488447a05SGarrett D'Amore 
485*2c30fa45SGarrett D'Amore int auimpl_engine_open(audio_stream_t *, int);
486*2c30fa45SGarrett D'Amore int auimpl_engine_setup(audio_stream_t *, int, audio_parms_t *, uint_t);
48788447a05SGarrett D'Amore void auimpl_engine_close(audio_stream_t *);
48888447a05SGarrett D'Amore 
48988447a05SGarrett D'Amore void auimpl_dev_walk_engines(audio_dev_t *,
49088447a05SGarrett D'Amore     int (*)(audio_engine_t *, void *), void *);
49188447a05SGarrett D'Amore 
49288447a05SGarrett D'Amore void auimpl_dev_vwarn(audio_dev_t *, const char *, va_list);
49388447a05SGarrett D'Amore 
49488447a05SGarrett D'Amore /* engine operations */
49588447a05SGarrett D'Amore #define	E_OP(e, entry)		((e)->e_ops.audio_engine_##entry)
49688447a05SGarrett D'Amore #define	E_PRV(e)		((e)->e_private)
49788447a05SGarrett D'Amore #define	ENG_FORMAT(e)		E_OP(e, format)(E_PRV(e))
49888447a05SGarrett D'Amore #define	ENG_RATE(e)		E_OP(e, rate)(E_PRV(e))
49988447a05SGarrett D'Amore #define	ENG_CHANNELS(e)		E_OP(e, channels)(E_PRV(e))
50088447a05SGarrett D'Amore #define	ENG_SYNC(e, num)	E_OP(e, sync)(E_PRV(e), num)
50188447a05SGarrett D'Amore #define	ENG_START(e)		E_OP(e, start)(E_PRV(e))
50288447a05SGarrett D'Amore #define	ENG_STOP(e)		E_OP(e, stop)(E_PRV(e))
50388447a05SGarrett D'Amore #define	ENG_COUNT(e)		E_OP(e, count)(E_PRV(e))
50488447a05SGarrett D'Amore #define	ENG_QLEN(e)		E_OP(e, qlen)(E_PRV(e))
505f9ead4a5SGarrett D'Amore #define	ENG_PLAYAHEAD(e)	E_OP(e, playahead)(E_PRV(e))
50688447a05SGarrett D'Amore #define	ENG_CLOSE(e)		E_OP(e, close)(E_PRV(e))
507*2c30fa45SGarrett D'Amore #define	ENG_OPEN(e, flg, nf, d) E_OP(e, open)(E_PRV(e), flg, nf, d)
50888447a05SGarrett D'Amore #define	ENG_CHINFO(e, c, o, i)	E_OP(e, chinfo(E_PRV(e), c, o, i))
50988447a05SGarrett D'Amore 
51088447a05SGarrett D'Amore /* audio_sun.c */
51188447a05SGarrett D'Amore void auimpl_sun_init(void);
51288447a05SGarrett D'Amore 
51388447a05SGarrett D'Amore /* audio_oss.c */
51488447a05SGarrett D'Amore void auimpl_oss_init(void);
51588447a05SGarrett D'Amore 
51688447a05SGarrett D'Amore #endif	/* _AUDIO_IMPL_H */
517