2012-12-19 15:52:06 +04:00
/*
* Generic BIOS auto - parser helper functions for HD - audio
*
* Copyright ( c ) 2012 Takashi Iwai < tiwai @ suse . de >
*
* This driver is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*/
# ifndef __SOUND_HDA_GENERIC_H
# define __SOUND_HDA_GENERIC_H
/* unsol event tags */
enum {
2012-12-20 17:46:57 +04:00
HDA_GEN_HP_EVENT = 1 , HDA_GEN_FRONT_EVENT , HDA_GEN_MIC_EVENT ,
2012-12-19 15:52:06 +04:00
HDA_GEN_LAST_EVENT = HDA_GEN_MIC_EVENT
} ;
/* table entry for multi-io paths */
struct hda_multi_io {
hda_nid_t pin ; /* multi-io widget pin NID */
hda_nid_t dac ; /* DAC to be connected */
unsigned int ctl_in ; /* cached input-pin control value */
} ;
/* Widget connection path
*
* For output , stored in the order of DAC - > . . . - > pin ,
* for input , pin - > . . . - > ADC .
*
* idx [ i ] contains the source index number to select on of the widget path [ i ] ;
* e . g . idx [ 1 ] is the index of the DAC ( path [ 0 ] ) selected by path [ 1 ] widget
* multi [ ] indicates whether it ' s a selector widget with multi - connectors
* ( i . e . the connection selection is mandatory )
* vol_ctl and mute_ctl contains the NIDs for the assigned mixers
*/
2012-12-20 17:42:42 +04:00
# define MAX_NID_PATH_DEPTH 10
2012-12-19 15:52:06 +04:00
enum {
NID_PATH_VOL_CTL ,
NID_PATH_MUTE_CTL ,
NID_PATH_BOOST_CTL ,
NID_PATH_NUM_CTLS
} ;
struct nid_path {
int depth ;
hda_nid_t path [ MAX_NID_PATH_DEPTH ] ;
unsigned char idx [ MAX_NID_PATH_DEPTH ] ;
unsigned char multi [ MAX_NID_PATH_DEPTH ] ;
unsigned int ctls [ NID_PATH_NUM_CTLS ] ; /* NID_PATH_XXX_CTL */
bool active ;
} ;
/* mic/line-in auto switching entry */
# define MAX_AUTO_MIC_PINS 3
struct automic_entry {
hda_nid_t pin ; /* pin */
int idx ; /* imux index, -1 = invalid */
unsigned int attr ; /* pin attribute (INPUT_PIN_ATTR_*) */
} ;
2012-12-21 17:09:42 +04:00
/* active stream id */
enum { STREAM_MULTI_OUT , STREAM_INDEP_HP } ;
2013-01-07 14:54:34 +04:00
/* PCM hook action */
enum {
HDA_GEN_PCM_ACT_OPEN ,
HDA_GEN_PCM_ACT_PREPARE ,
HDA_GEN_PCM_ACT_CLEANUP ,
HDA_GEN_PCM_ACT_CLOSE ,
} ;
2013-03-22 17:53:50 +04:00
/* DAC assignment badness table */
struct badness_table {
int no_primary_dac ; /* no primary DAC */
int no_dac ; /* no secondary DACs */
int shared_primary ; /* primary DAC is shared with main output */
int shared_surr ; /* secondary DAC shared with main or primary */
int shared_clfe ; /* third DAC shared with main or primary */
int shared_surr_main ; /* secondary DAC sahred with main/DAC0 */
} ;
extern const struct badness_table hda_main_out_badness ;
extern const struct badness_table hda_extra_out_badness ;
2012-12-19 15:52:06 +04:00
struct hda_gen_spec {
char stream_name_analog [ 32 ] ; /* analog PCM stream */
const struct hda_pcm_stream * stream_analog_playback ;
const struct hda_pcm_stream * stream_analog_capture ;
2013-01-21 19:50:09 +04:00
char stream_name_alt_analog [ 32 ] ; /* alternative analog PCM stream */
2012-12-19 15:52:06 +04:00
const struct hda_pcm_stream * stream_analog_alt_playback ;
const struct hda_pcm_stream * stream_analog_alt_capture ;
char stream_name_digital [ 32 ] ; /* digital PCM stream */
const struct hda_pcm_stream * stream_digital_playback ;
const struct hda_pcm_stream * stream_digital_capture ;
2012-12-21 17:09:42 +04:00
/* PCM */
unsigned int active_streams ;
struct mutex pcm_mutex ;
2012-12-19 15:52:06 +04:00
/* playback */
struct hda_multi_out multiout ; /* playback set-up
* max_channels , dacs must be set
* dig_out_nid and hp_nid are optional
*/
hda_nid_t alt_dac_nid ;
hda_nid_t slave_dig_outs [ 3 ] ; /* optional - for auto-parsing */
int dig_out_type ;
/* capture */
unsigned int num_adc_nids ;
2013-01-18 19:38:08 +04:00
hda_nid_t adc_nids [ AUTO_CFG_MAX_INS ] ;
2012-12-19 15:52:06 +04:00
hda_nid_t dig_in_nid ; /* digital-in NID; optional */
hda_nid_t mixer_nid ; /* analog-mixer NID */
2013-01-23 20:00:31 +04:00
hda_nid_t mixer_merge_nid ; /* aamix merge-point NID (optional) */
2013-01-18 19:38:08 +04:00
const char * input_labels [ HDA_MAX_NUM_INPUTS ] ;
int input_label_idxs [ HDA_MAX_NUM_INPUTS ] ;
2012-12-19 15:52:06 +04:00
/* capture setup for dynamic dual-adc switch */
hda_nid_t cur_adc ;
unsigned int cur_adc_stream_tag ;
unsigned int cur_adc_format ;
/* capture source */
struct hda_input_mux input_mux ;
unsigned int cur_mux [ 3 ] ;
/* channel model */
2013-01-07 19:44:06 +04:00
/* min_channel_count contains the minimum channel count for primary
* outputs . When multi_ios is set , the channels can be configured
* between min_channel_count and ( min_channel_count + multi_ios * 2 ) .
*
* ext_channel_count contains the current channel count of the primary
* out . This varies in the range above .
*
* Meanwhile , const_channel_count is the channel count for all outputs
* including headphone and speakers . It ' s a constant value , and the
* PCM is set up as max ( ext_channel_count , const_channel_count ) .
*/
int min_channel_count ; /* min. channel count for primary out */
int ext_channel_count ; /* current channel count for primary */
int const_channel_count ; /* channel count for all */
2012-12-19 15:52:06 +04:00
/* PCM information */
struct hda_pcm pcm_rec [ 3 ] ; /* used in build_pcms() */
/* dynamic controls, init_verbs and input_mux */
struct auto_pin_cfg autocfg ;
struct snd_array kctls ;
hda_nid_t private_dac_nids [ AUTO_CFG_MAX_OUTS ] ;
hda_nid_t imux_pins [ HDA_MAX_NUM_INPUTS ] ;
unsigned int dyn_adc_idx [ HDA_MAX_NUM_INPUTS ] ;
2013-02-19 20:12:42 +04:00
/* shared hp/mic */
2012-12-19 15:52:06 +04:00
hda_nid_t shared_mic_vref_pin ;
2013-02-19 20:12:42 +04:00
hda_nid_t hp_mic_pin ;
int hp_mic_mux_idx ;
2012-12-19 15:52:06 +04:00
2013-01-17 18:53:29 +04:00
/* DAC/ADC lists */
2012-12-19 15:52:06 +04:00
int num_all_dacs ;
hda_nid_t all_dacs [ 16 ] ;
2013-01-17 18:53:29 +04:00
int num_all_adcs ;
2013-01-18 19:38:08 +04:00
hda_nid_t all_adcs [ AUTO_CFG_MAX_INS ] ;
2012-12-19 15:52:06 +04:00
/* path list */
struct snd_array paths ;
2013-01-04 18:01:40 +04:00
/* path indices */
int out_paths [ AUTO_CFG_MAX_OUTS ] ;
int hp_paths [ AUTO_CFG_MAX_OUTS ] ;
int speaker_paths [ AUTO_CFG_MAX_OUTS ] ;
2013-01-04 19:42:48 +04:00
int aamix_out_paths [ 3 ] ;
2013-01-04 18:01:40 +04:00
int digout_paths [ AUTO_CFG_MAX_OUTS ] ;
2013-01-18 18:43:01 +04:00
int input_paths [ HDA_MAX_NUM_INPUTS ] [ AUTO_CFG_MAX_INS ] ;
2013-01-04 18:01:40 +04:00
int loopback_paths [ HDA_MAX_NUM_INPUTS ] ;
2013-01-23 20:00:31 +04:00
int loopback_merge_path ;
2013-01-04 18:09:42 +04:00
int digin_path ;
2013-01-04 18:01:40 +04:00
2012-12-19 15:52:06 +04:00
/* auto-mic stuff */
int am_num_entries ;
struct automic_entry am_entry [ MAX_AUTO_MIC_PINS ] ;
/* for pin sensing */
2013-01-16 21:28:38 +04:00
/* current status; set in hda_geneic.c */
2012-12-19 15:52:06 +04:00
unsigned int hp_jack_present : 1 ;
unsigned int line_jack_present : 1 ;
2013-01-16 21:28:38 +04:00
unsigned int speaker_muted : 1 ; /* current status of speaker mute */
unsigned int line_out_muted : 1 ; /* current status of LO mute */
/* internal states of automute / autoswitch behavior */
2012-12-19 15:52:06 +04:00
unsigned int auto_mic : 1 ;
unsigned int automute_speaker : 1 ; /* automute speaker outputs */
unsigned int automute_lo : 1 ; /* automute LO outputs */
2013-01-16 21:28:38 +04:00
/* capabilities detected by parser */
2012-12-19 15:52:06 +04:00
unsigned int detect_hp : 1 ; /* Headphone detection enabled */
unsigned int detect_lo : 1 ; /* Line-out detection enabled */
unsigned int automute_speaker_possible : 1 ; /* there are speakers and either LO or HP */
unsigned int automute_lo_possible : 1 ; /* there are line outs and HP */
2013-01-16 21:28:38 +04:00
/* additional parameters set by codec drivers */
unsigned int master_mute : 1 ; /* master mute over all */
2012-12-19 15:52:06 +04:00
unsigned int keep_vref_in_automute : 1 ; /* Don't clear VREF in automute */
2013-01-16 21:28:38 +04:00
unsigned int line_in_auto_switch : 1 ; /* allow line-in auto switch */
/* parser behavior flags; set before snd_hda_gen_parse_auto_config() */
2013-01-16 21:20:07 +04:00
unsigned int suppress_auto_mute : 1 ; /* suppress input jack auto mute */
2013-01-07 19:32:11 +04:00
unsigned int suppress_auto_mic : 1 ; /* suppress input jack auto switch */
2012-12-19 15:52:06 +04:00
2013-01-16 21:28:38 +04:00
/* other parse behavior flags */
2012-12-19 15:52:06 +04:00
unsigned int need_dac_fix : 1 ; /* need to limit DACs for multi channels */
2013-02-19 20:12:42 +04:00
unsigned int hp_mic : 1 ; /* Allow HP as a mic-in */
unsigned int suppress_hp_mic_detect : 1 ; /* Don't detect HP/mic */
2012-12-19 15:52:06 +04:00
unsigned int no_primary_hp : 1 ; /* Don't prefer HP pins to speaker pins */
unsigned int multi_cap_vol : 1 ; /* allow multiple capture xxx volumes */
unsigned int inv_dmic_split : 1 ; /* inverted dmic w/a for conexant */
2012-12-19 16:01:54 +04:00
unsigned int own_eapd_ctl : 1 ; /* set EAPD by own function */
2012-12-20 17:57:18 +04:00
unsigned int vmaster_mute_enum : 1 ; /* add vmaster mute mode enum */
2012-12-21 17:09:42 +04:00
unsigned int indep_hp : 1 ; /* independent HP supported */
2013-01-15 21:45:53 +04:00
unsigned int prefer_hp_amp : 1 ; /* enable HP amp for speaker if any */
2013-01-09 12:14:23 +04:00
unsigned int add_stereo_mix_input : 1 ; /* add aamix as a capture src */
2013-03-07 21:32:59 +04:00
unsigned int add_jack_modes : 1 ; /* add i/o jack mode enum ctls */
2013-01-24 20:32:56 +04:00
unsigned int power_down_unused : 1 ; /* power down unused widgets */
2012-12-19 15:52:06 +04:00
2013-01-16 21:28:38 +04:00
/* other internal flags */
unsigned int no_analog : 1 ; /* digital I/O only */
unsigned int dyn_adc_switch : 1 ; /* switch ADCs (for ALC275) */
unsigned int indep_hp_enabled : 1 ; /* independent HP enabled */
2013-01-21 18:11:25 +04:00
unsigned int have_aamix_ctl : 1 ;
2013-03-07 21:40:58 +04:00
unsigned int hp_mic_jack_modes : 1 ;
2013-01-16 21:28:38 +04:00
2013-03-22 17:53:50 +04:00
/* badness tables for output path evaluations */
const struct badness_table * main_out_badness ;
const struct badness_table * extra_out_badness ;
2013-01-04 19:42:48 +04:00
/* loopback mixing mode */
bool aamix_mode ;
2013-03-18 14:25:51 +04:00
/* digital beep */
hda_nid_t beep_nid ;
2012-12-19 15:52:06 +04:00
/* for virtual master */
hda_nid_t vmaster_nid ;
2013-01-17 13:25:15 +04:00
unsigned int vmaster_tlv [ 4 ] ;
2012-12-19 15:52:06 +04:00
struct hda_vmaster_mute_hook vmaster_mute ;
2013-02-07 12:58:11 +04:00
2012-12-19 15:52:06 +04:00
struct hda_loopback_check loopback ;
2013-02-07 13:45:11 +04:00
struct snd_array loopback_list ;
2012-12-19 15:52:06 +04:00
/* multi-io */
int multi_ios ;
struct hda_multi_io multi_io [ 4 ] ;
/* hooks */
void ( * init_hook ) ( struct hda_codec * codec ) ;
void ( * automute_hook ) ( struct hda_codec * codec ) ;
2013-01-18 17:10:00 +04:00
void ( * cap_sync_hook ) ( struct hda_codec * codec ,
struct snd_ctl_elem_value * ucontrol ) ;
2013-01-03 18:55:06 +04:00
2013-01-17 18:57:10 +04:00
/* PCM hooks */
2013-01-07 14:54:34 +04:00
void ( * pcm_playback_hook ) ( struct hda_pcm_stream * hinfo ,
struct hda_codec * codec ,
struct snd_pcm_substream * substream ,
int action ) ;
2013-01-17 18:57:10 +04:00
void ( * pcm_capture_hook ) ( struct hda_pcm_stream * hinfo ,
struct hda_codec * codec ,
struct snd_pcm_substream * substream ,
int action ) ;
2013-01-07 14:54:34 +04:00
2013-01-03 18:55:06 +04:00
/* automute / autoswitch hooks */
void ( * hp_automute_hook ) ( struct hda_codec * codec ,
struct hda_jack_tbl * tbl ) ;
void ( * line_automute_hook ) ( struct hda_codec * codec ,
struct hda_jack_tbl * tbl ) ;
void ( * mic_autoswitch_hook ) ( struct hda_codec * codec ,
struct hda_jack_tbl * tbl ) ;
2012-12-19 15:52:06 +04:00
} ;
int snd_hda_gen_spec_init ( struct hda_gen_spec * spec ) ;
void snd_hda_gen_spec_free ( struct hda_gen_spec * spec ) ;
int snd_hda_gen_init ( struct hda_codec * codec ) ;
2013-01-07 15:42:48 +04:00
void snd_hda_gen_free ( struct hda_codec * codec ) ;
2012-12-19 15:52:06 +04:00
struct nid_path * snd_hda_get_nid_path ( struct hda_codec * codec ,
hda_nid_t from_nid , hda_nid_t to_nid ) ;
2013-01-04 18:01:40 +04:00
int snd_hda_get_path_idx ( struct hda_codec * codec , struct nid_path * path ) ;
struct nid_path * snd_hda_get_path_from_idx ( struct hda_codec * codec , int idx ) ;
2012-12-19 15:52:06 +04:00
bool snd_hda_parse_nid_path ( struct hda_codec * codec , hda_nid_t from_nid ,
2013-01-07 20:25:08 +04:00
hda_nid_t to_nid , int anchor_nid ,
2012-12-19 15:52:06 +04:00
struct nid_path * path ) ;
struct nid_path *
snd_hda_add_new_path ( struct hda_codec * codec , hda_nid_t from_nid ,
2013-01-07 20:25:08 +04:00
hda_nid_t to_nid , int anchor_nid ) ;
2012-12-19 15:52:06 +04:00
void snd_hda_activate_path ( struct hda_codec * codec , struct nid_path * path ,
bool enable , bool add_aamix ) ;
2012-12-19 17:38:33 +04:00
struct snd_kcontrol_new *
snd_hda_gen_add_kctl ( struct hda_gen_spec * spec , const char * name ,
const struct snd_kcontrol_new * temp ) ;
2012-12-19 15:52:06 +04:00
int snd_hda_gen_parse_auto_config ( struct hda_codec * codec ,
2012-12-19 17:41:21 +04:00
struct auto_pin_cfg * cfg ) ;
2012-12-19 15:52:06 +04:00
int snd_hda_gen_build_controls ( struct hda_codec * codec ) ;
int snd_hda_gen_build_pcms ( struct hda_codec * codec ) ;
2012-12-19 18:16:44 +04:00
/* standard jack event callbacks */
void snd_hda_gen_hp_automute ( struct hda_codec * codec ,
struct hda_jack_tbl * jack ) ;
void snd_hda_gen_line_automute ( struct hda_codec * codec ,
struct hda_jack_tbl * jack ) ;
void snd_hda_gen_mic_autoswitch ( struct hda_codec * codec ,
struct hda_jack_tbl * jack ) ;
void snd_hda_gen_update_outputs ( struct hda_codec * codec ) ;
2013-01-07 15:42:48 +04:00
# ifdef CONFIG_PM
int snd_hda_gen_check_power_status ( struct hda_codec * codec , hda_nid_t nid ) ;
# endif
2012-12-19 15:52:06 +04:00
# endif /* __SOUND_HDA_GENERIC_H */