1352f7f91STakashi Iwai /* 2352f7f91STakashi Iwai * Generic BIOS auto-parser helper functions for HD-audio 3352f7f91STakashi Iwai * 4352f7f91STakashi Iwai * Copyright (c) 2012 Takashi Iwai <tiwai@suse.de> 5352f7f91STakashi Iwai * 6352f7f91STakashi Iwai * This driver is free software; you can redistribute it and/or modify 7352f7f91STakashi Iwai * it under the terms of the GNU General Public License as published by 8352f7f91STakashi Iwai * the Free Software Foundation; either version 2 of the License, or 9352f7f91STakashi Iwai * (at your option) any later version. 10352f7f91STakashi Iwai */ 11352f7f91STakashi Iwai 12352f7f91STakashi Iwai #ifndef __SOUND_HDA_GENERIC_H 13352f7f91STakashi Iwai #define __SOUND_HDA_GENERIC_H 14352f7f91STakashi Iwai 15352f7f91STakashi Iwai /* unsol event tags */ 16352f7f91STakashi Iwai enum { 17352f7f91STakashi Iwai HDA_GEN_HP_EVENT, HDA_GEN_FRONT_EVENT, HDA_GEN_MIC_EVENT, 18352f7f91STakashi Iwai HDA_GEN_LAST_EVENT = HDA_GEN_MIC_EVENT 19352f7f91STakashi Iwai }; 20352f7f91STakashi Iwai 21352f7f91STakashi Iwai /* table entry for multi-io paths */ 22352f7f91STakashi Iwai struct hda_multi_io { 23352f7f91STakashi Iwai hda_nid_t pin; /* multi-io widget pin NID */ 24352f7f91STakashi Iwai hda_nid_t dac; /* DAC to be connected */ 25352f7f91STakashi Iwai unsigned int ctl_in; /* cached input-pin control value */ 26352f7f91STakashi Iwai }; 27352f7f91STakashi Iwai 28352f7f91STakashi Iwai /* Widget connection path 29352f7f91STakashi Iwai * 30352f7f91STakashi Iwai * For output, stored in the order of DAC -> ... -> pin, 31352f7f91STakashi Iwai * for input, pin -> ... -> ADC. 32352f7f91STakashi Iwai * 33352f7f91STakashi Iwai * idx[i] contains the source index number to select on of the widget path[i]; 34352f7f91STakashi Iwai * e.g. idx[1] is the index of the DAC (path[0]) selected by path[1] widget 35352f7f91STakashi Iwai * multi[] indicates whether it's a selector widget with multi-connectors 36352f7f91STakashi Iwai * (i.e. the connection selection is mandatory) 37352f7f91STakashi Iwai * vol_ctl and mute_ctl contains the NIDs for the assigned mixers 38352f7f91STakashi Iwai */ 39352f7f91STakashi Iwai 40352f7f91STakashi Iwai #define MAX_NID_PATH_DEPTH 5 41352f7f91STakashi Iwai 42352f7f91STakashi Iwai enum { 43352f7f91STakashi Iwai NID_PATH_VOL_CTL, 44352f7f91STakashi Iwai NID_PATH_MUTE_CTL, 45352f7f91STakashi Iwai NID_PATH_BOOST_CTL, 46352f7f91STakashi Iwai NID_PATH_NUM_CTLS 47352f7f91STakashi Iwai }; 48352f7f91STakashi Iwai 49352f7f91STakashi Iwai struct nid_path { 50352f7f91STakashi Iwai int depth; 51352f7f91STakashi Iwai hda_nid_t path[MAX_NID_PATH_DEPTH]; 52352f7f91STakashi Iwai unsigned char idx[MAX_NID_PATH_DEPTH]; 53352f7f91STakashi Iwai unsigned char multi[MAX_NID_PATH_DEPTH]; 54352f7f91STakashi Iwai unsigned int ctls[NID_PATH_NUM_CTLS]; /* NID_PATH_XXX_CTL */ 55352f7f91STakashi Iwai bool active; 56352f7f91STakashi Iwai }; 57352f7f91STakashi Iwai 58352f7f91STakashi Iwai /* mic/line-in auto switching entry */ 59352f7f91STakashi Iwai 60352f7f91STakashi Iwai #define MAX_AUTO_MIC_PINS 3 61352f7f91STakashi Iwai 62352f7f91STakashi Iwai struct automic_entry { 63352f7f91STakashi Iwai hda_nid_t pin; /* pin */ 64352f7f91STakashi Iwai int idx; /* imux index, -1 = invalid */ 65352f7f91STakashi Iwai unsigned int attr; /* pin attribute (INPUT_PIN_ATTR_*) */ 66352f7f91STakashi Iwai }; 67352f7f91STakashi Iwai 68352f7f91STakashi Iwai struct hda_gen_spec { 69352f7f91STakashi Iwai char stream_name_analog[32]; /* analog PCM stream */ 70352f7f91STakashi Iwai const struct hda_pcm_stream *stream_analog_playback; 71352f7f91STakashi Iwai const struct hda_pcm_stream *stream_analog_capture; 72352f7f91STakashi Iwai const struct hda_pcm_stream *stream_analog_alt_playback; 73352f7f91STakashi Iwai const struct hda_pcm_stream *stream_analog_alt_capture; 74352f7f91STakashi Iwai 75352f7f91STakashi Iwai char stream_name_digital[32]; /* digital PCM stream */ 76352f7f91STakashi Iwai const struct hda_pcm_stream *stream_digital_playback; 77352f7f91STakashi Iwai const struct hda_pcm_stream *stream_digital_capture; 78352f7f91STakashi Iwai 79352f7f91STakashi Iwai /* playback */ 80352f7f91STakashi Iwai struct hda_multi_out multiout; /* playback set-up 81352f7f91STakashi Iwai * max_channels, dacs must be set 82352f7f91STakashi Iwai * dig_out_nid and hp_nid are optional 83352f7f91STakashi Iwai */ 84352f7f91STakashi Iwai hda_nid_t alt_dac_nid; 85352f7f91STakashi Iwai hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */ 86352f7f91STakashi Iwai int dig_out_type; 87352f7f91STakashi Iwai 88352f7f91STakashi Iwai /* capture */ 89352f7f91STakashi Iwai unsigned int num_adc_nids; 90352f7f91STakashi Iwai hda_nid_t adc_nids[AUTO_CFG_MAX_OUTS]; 91352f7f91STakashi Iwai hda_nid_t dig_in_nid; /* digital-in NID; optional */ 92352f7f91STakashi Iwai hda_nid_t mixer_nid; /* analog-mixer NID */ 93352f7f91STakashi Iwai 94352f7f91STakashi Iwai /* capture setup for dynamic dual-adc switch */ 95352f7f91STakashi Iwai hda_nid_t cur_adc; 96352f7f91STakashi Iwai unsigned int cur_adc_stream_tag; 97352f7f91STakashi Iwai unsigned int cur_adc_format; 98352f7f91STakashi Iwai 99352f7f91STakashi Iwai /* capture source */ 100352f7f91STakashi Iwai struct hda_input_mux input_mux; 101352f7f91STakashi Iwai unsigned int cur_mux[3]; 102352f7f91STakashi Iwai 103352f7f91STakashi Iwai /* channel model */ 104352f7f91STakashi Iwai const struct hda_channel_mode *channel_mode; 105352f7f91STakashi Iwai int num_channel_mode; 106352f7f91STakashi Iwai int const_channel_count; /* min. channel count (for speakers) */ 107352f7f91STakashi Iwai int ext_channel_count; /* current channel count for multi-io */ 108352f7f91STakashi Iwai 109352f7f91STakashi Iwai /* PCM information */ 110352f7f91STakashi Iwai struct hda_pcm pcm_rec[3]; /* used in build_pcms() */ 111352f7f91STakashi Iwai 112352f7f91STakashi Iwai /* dynamic controls, init_verbs and input_mux */ 113352f7f91STakashi Iwai struct auto_pin_cfg autocfg; 114352f7f91STakashi Iwai struct snd_array kctls; 115352f7f91STakashi Iwai hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 116352f7f91STakashi Iwai hda_nid_t imux_pins[HDA_MAX_NUM_INPUTS]; 117352f7f91STakashi Iwai unsigned int dyn_adc_idx[HDA_MAX_NUM_INPUTS]; 118352f7f91STakashi Iwai hda_nid_t shared_mic_vref_pin; 119352f7f91STakashi Iwai 120352f7f91STakashi Iwai /* DAC list */ 121352f7f91STakashi Iwai int num_all_dacs; 122352f7f91STakashi Iwai hda_nid_t all_dacs[16]; 123352f7f91STakashi Iwai 124352f7f91STakashi Iwai /* path list */ 125352f7f91STakashi Iwai struct snd_array paths; 126352f7f91STakashi Iwai 127352f7f91STakashi Iwai /* auto-mic stuff */ 128352f7f91STakashi Iwai int am_num_entries; 129352f7f91STakashi Iwai struct automic_entry am_entry[MAX_AUTO_MIC_PINS]; 130352f7f91STakashi Iwai 131352f7f91STakashi Iwai /* for pin sensing */ 132352f7f91STakashi Iwai unsigned int hp_jack_present:1; 133352f7f91STakashi Iwai unsigned int line_jack_present:1; 134352f7f91STakashi Iwai unsigned int master_mute:1; 135352f7f91STakashi Iwai unsigned int auto_mic:1; 136352f7f91STakashi Iwai unsigned int automute_speaker:1; /* automute speaker outputs */ 137352f7f91STakashi Iwai unsigned int automute_lo:1; /* automute LO outputs */ 138352f7f91STakashi Iwai unsigned int detect_hp:1; /* Headphone detection enabled */ 139352f7f91STakashi Iwai unsigned int detect_lo:1; /* Line-out detection enabled */ 140352f7f91STakashi Iwai unsigned int automute_speaker_possible:1; /* there are speakers and either LO or HP */ 141352f7f91STakashi Iwai unsigned int automute_lo_possible:1; /* there are line outs and HP */ 142352f7f91STakashi Iwai unsigned int keep_vref_in_automute:1; /* Don't clear VREF in automute */ 143352f7f91STakashi Iwai unsigned int line_in_auto_switch:1; /* allow line-in auto switch */ 144352f7f91STakashi Iwai 145352f7f91STakashi Iwai /* other flags */ 146352f7f91STakashi Iwai unsigned int need_dac_fix:1; /* need to limit DACs for multi channels */ 147352f7f91STakashi Iwai unsigned int no_analog:1; /* digital I/O only */ 148352f7f91STakashi Iwai unsigned int dyn_adc_switch:1; /* switch ADCs (for ALC275) */ 149352f7f91STakashi Iwai unsigned int shared_mic_hp:1; /* HP/Mic-in sharing */ 150352f7f91STakashi Iwai unsigned int no_primary_hp:1; /* Don't prefer HP pins to speaker pins */ 151352f7f91STakashi Iwai unsigned int multi_cap_vol:1; /* allow multiple capture xxx volumes */ 152352f7f91STakashi Iwai unsigned int inv_dmic_split:1; /* inverted dmic w/a for conexant */ 153*731dc301STakashi Iwai unsigned int own_eapd_ctl:1; /* set EAPD by own function */ 154352f7f91STakashi Iwai 155352f7f91STakashi Iwai unsigned int parse_flags; /* passed to snd_hda_parse_pin_defcfg() */ 156352f7f91STakashi Iwai 157352f7f91STakashi Iwai /* for virtual master */ 158352f7f91STakashi Iwai hda_nid_t vmaster_nid; 159352f7f91STakashi Iwai struct hda_vmaster_mute_hook vmaster_mute; 160352f7f91STakashi Iwai #ifdef CONFIG_PM 161352f7f91STakashi Iwai struct hda_loopback_check loopback; 162352f7f91STakashi Iwai int num_loopbacks; 163352f7f91STakashi Iwai struct hda_amp_list loopback_list[8]; 164352f7f91STakashi Iwai #endif 165352f7f91STakashi Iwai 166352f7f91STakashi Iwai /* multi-io */ 167352f7f91STakashi Iwai int multi_ios; 168352f7f91STakashi Iwai struct hda_multi_io multi_io[4]; 169352f7f91STakashi Iwai 170352f7f91STakashi Iwai /* bind volumes */ 171352f7f91STakashi Iwai struct snd_array bind_ctls; 172352f7f91STakashi Iwai 173352f7f91STakashi Iwai /* hooks */ 174352f7f91STakashi Iwai void (*init_hook)(struct hda_codec *codec); 175352f7f91STakashi Iwai void (*automute_hook)(struct hda_codec *codec); 176352f7f91STakashi Iwai void (*cap_sync_hook)(struct hda_codec *codec); 177352f7f91STakashi Iwai }; 178352f7f91STakashi Iwai 179352f7f91STakashi Iwai int snd_hda_gen_spec_init(struct hda_gen_spec *spec); 180352f7f91STakashi Iwai void snd_hda_gen_spec_free(struct hda_gen_spec *spec); 181352f7f91STakashi Iwai 182352f7f91STakashi Iwai int snd_hda_gen_init(struct hda_codec *codec); 183352f7f91STakashi Iwai 184352f7f91STakashi Iwai struct nid_path *snd_hda_get_nid_path(struct hda_codec *codec, 185352f7f91STakashi Iwai hda_nid_t from_nid, hda_nid_t to_nid); 186352f7f91STakashi Iwai bool snd_hda_parse_nid_path(struct hda_codec *codec, hda_nid_t from_nid, 187352f7f91STakashi Iwai hda_nid_t to_nid, int with_aa_mix, 188352f7f91STakashi Iwai struct nid_path *path); 189352f7f91STakashi Iwai struct nid_path * 190352f7f91STakashi Iwai snd_hda_add_new_path(struct hda_codec *codec, hda_nid_t from_nid, 191352f7f91STakashi Iwai hda_nid_t to_nid, int with_aa_mix); 192352f7f91STakashi Iwai void snd_hda_activate_path(struct hda_codec *codec, struct nid_path *path, 193352f7f91STakashi Iwai bool enable, bool add_aamix); 194352f7f91STakashi Iwai 195352f7f91STakashi Iwai int snd_hda_gen_parse_auto_config(struct hda_codec *codec, 196352f7f91STakashi Iwai const hda_nid_t *ignore_nids); 197352f7f91STakashi Iwai int snd_hda_gen_build_controls(struct hda_codec *codec); 198352f7f91STakashi Iwai int snd_hda_gen_build_pcms(struct hda_codec *codec); 199352f7f91STakashi Iwai 200352f7f91STakashi Iwai #endif /* __SOUND_HDA_GENERIC_H */ 201