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