Commit 76165a3063356ec898159d942ef4d2c69cc26801
Exists in
master
and in
7 other branches
Merge branch 'fix/hda' into for-linus
Showing 2 changed files Side-by-side Diff
sound/pci/hda/patch_conexant.c
... | ... | @@ -3049,6 +3049,7 @@ |
3049 | 3049 | SND_PCI_QUIRK(0x1028, 0x02f5, "Dell", |
3050 | 3050 | CXT5066_DELL_LAPTOP), |
3051 | 3051 | SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), |
3052 | + SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTO), | |
3052 | 3053 | SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTO), |
3053 | 3054 | SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD), |
3054 | 3055 | SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5), |
sound/pci/hda/patch_realtek.c
... | ... | @@ -19030,6 +19030,7 @@ |
19030 | 19030 | /* |
19031 | 19031 | * ALC680 support |
19032 | 19032 | */ |
19033 | +#define ALC680_DIGIN_NID ALC880_DIGIN_NID | |
19033 | 19034 | #define ALC680_DIGOUT_NID ALC880_DIGOUT_NID |
19034 | 19035 | #define alc680_modes alc260_modes |
19035 | 19036 | |
19036 | 19037 | |
19037 | 19038 | |
19038 | 19039 | |
... | ... | @@ -19044,23 +19045,93 @@ |
19044 | 19045 | 0x07, 0x08, 0x09 |
19045 | 19046 | }; |
19046 | 19047 | |
19048 | +/* | |
19049 | + * Analog capture ADC cgange | |
19050 | + */ | |
19051 | +static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | |
19052 | + struct hda_codec *codec, | |
19053 | + unsigned int stream_tag, | |
19054 | + unsigned int format, | |
19055 | + struct snd_pcm_substream *substream) | |
19056 | +{ | |
19057 | + struct alc_spec *spec = codec->spec; | |
19058 | + struct auto_pin_cfg *cfg = &spec->autocfg; | |
19059 | + unsigned int pre_mic, pre_line; | |
19060 | + | |
19061 | + pre_mic = snd_hda_jack_detect(codec, cfg->input_pins[AUTO_PIN_MIC]); | |
19062 | + pre_line = snd_hda_jack_detect(codec, cfg->input_pins[AUTO_PIN_LINE]); | |
19063 | + | |
19064 | + spec->cur_adc_stream_tag = stream_tag; | |
19065 | + spec->cur_adc_format = format; | |
19066 | + | |
19067 | + if (pre_mic || pre_line) { | |
19068 | + if (pre_mic) | |
19069 | + snd_hda_codec_setup_stream(codec, 0x08, stream_tag, 0, | |
19070 | + format); | |
19071 | + else | |
19072 | + snd_hda_codec_setup_stream(codec, 0x09, stream_tag, 0, | |
19073 | + format); | |
19074 | + } else | |
19075 | + snd_hda_codec_setup_stream(codec, 0x07, stream_tag, 0, format); | |
19076 | + return 0; | |
19077 | +} | |
19078 | + | |
19079 | +static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | |
19080 | + struct hda_codec *codec, | |
19081 | + struct snd_pcm_substream *substream) | |
19082 | +{ | |
19083 | + snd_hda_codec_cleanup_stream(codec, 0x07); | |
19084 | + snd_hda_codec_cleanup_stream(codec, 0x08); | |
19085 | + snd_hda_codec_cleanup_stream(codec, 0x09); | |
19086 | + return 0; | |
19087 | +} | |
19088 | + | |
19089 | +static struct hda_pcm_stream alc680_pcm_analog_auto_capture = { | |
19090 | + .substreams = 1, /* can be overridden */ | |
19091 | + .channels_min = 2, | |
19092 | + .channels_max = 2, | |
19093 | + /* NID is set in alc_build_pcms */ | |
19094 | + .ops = { | |
19095 | + .prepare = alc680_capture_pcm_prepare, | |
19096 | + .cleanup = alc680_capture_pcm_cleanup | |
19097 | + }, | |
19098 | +}; | |
19099 | + | |
19047 | 19100 | static struct snd_kcontrol_new alc680_base_mixer[] = { |
19048 | 19101 | /* output mixer control */ |
19049 | 19102 | HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), |
19050 | 19103 | HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), |
19051 | 19104 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT), |
19052 | 19105 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT), |
19106 | + HDA_CODEC_VOLUME("Int Mic Boost", 0x12, 0, HDA_INPUT), | |
19053 | 19107 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), |
19108 | + HDA_CODEC_VOLUME("Line In Boost", 0x19, 0, HDA_INPUT), | |
19054 | 19109 | { } |
19055 | 19110 | }; |
19056 | 19111 | |
19057 | -static struct snd_kcontrol_new alc680_capture_mixer[] = { | |
19058 | - HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), | |
19059 | - HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), | |
19060 | - HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT), | |
19061 | - HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT), | |
19062 | - HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT), | |
19063 | - HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT), | |
19112 | +static struct hda_bind_ctls alc680_bind_cap_vol = { | |
19113 | + .ops = &snd_hda_bind_vol, | |
19114 | + .values = { | |
19115 | + HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT), | |
19116 | + HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), | |
19117 | + HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), | |
19118 | + 0 | |
19119 | + }, | |
19120 | +}; | |
19121 | + | |
19122 | +static struct hda_bind_ctls alc680_bind_cap_switch = { | |
19123 | + .ops = &snd_hda_bind_sw, | |
19124 | + .values = { | |
19125 | + HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT), | |
19126 | + HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), | |
19127 | + HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), | |
19128 | + 0 | |
19129 | + }, | |
19130 | +}; | |
19131 | + | |
19132 | +static struct snd_kcontrol_new alc680_master_capture_mixer[] = { | |
19133 | + HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol), | |
19134 | + HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch), | |
19064 | 19135 | { } /* end */ |
19065 | 19136 | }; |
19066 | 19137 | |
19067 | 19138 | |
19068 | 19139 | |
19069 | 19140 | |
... | ... | @@ -19068,25 +19139,73 @@ |
19068 | 19139 | * generic initialization of ADC, input mixers and output mixers |
19069 | 19140 | */ |
19070 | 19141 | static struct hda_verb alc680_init_verbs[] = { |
19071 | - /* Unmute DAC0-1 and set vol = 0 */ | |
19072 | - {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | |
19073 | - {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | |
19074 | - {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | |
19142 | + {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | |
19143 | + {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | |
19144 | + {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | |
19075 | 19145 | |
19076 | - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, | |
19077 | - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, | |
19078 | - {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, | |
19079 | - {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, | |
19080 | - {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | |
19146 | + {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | |
19147 | + {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | |
19148 | + {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | |
19149 | + {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | |
19150 | + {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | |
19151 | + {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | |
19081 | 19152 | |
19082 | 19153 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, |
19083 | 19154 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, |
19084 | 19155 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, |
19085 | 19156 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, |
19086 | 19157 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, |
19158 | + | |
19159 | + {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, | |
19160 | + {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, | |
19161 | + | |
19087 | 19162 | { } |
19088 | 19163 | }; |
19089 | 19164 | |
19165 | +/* toggle speaker-output according to the hp-jack state */ | |
19166 | +static void alc680_base_setup(struct hda_codec *codec) | |
19167 | +{ | |
19168 | + struct alc_spec *spec = codec->spec; | |
19169 | + | |
19170 | + spec->autocfg.hp_pins[0] = 0x16; | |
19171 | + spec->autocfg.speaker_pins[0] = 0x14; | |
19172 | + spec->autocfg.speaker_pins[1] = 0x15; | |
19173 | + spec->autocfg.input_pins[AUTO_PIN_MIC] = 0x18; | |
19174 | + spec->autocfg.input_pins[AUTO_PIN_LINE] = 0x19; | |
19175 | +} | |
19176 | + | |
19177 | +static void alc680_rec_autoswitch(struct hda_codec *codec) | |
19178 | +{ | |
19179 | + struct alc_spec *spec = codec->spec; | |
19180 | + struct auto_pin_cfg *cfg = &spec->autocfg; | |
19181 | + unsigned int present; | |
19182 | + hda_nid_t new_adc; | |
19183 | + | |
19184 | + present = snd_hda_jack_detect(codec, cfg->input_pins[AUTO_PIN_MIC]); | |
19185 | + | |
19186 | + new_adc = present ? 0x8 : 0x7; | |
19187 | + __snd_hda_codec_cleanup_stream(codec, !present ? 0x8 : 0x7, 1); | |
19188 | + snd_hda_codec_setup_stream(codec, new_adc, | |
19189 | + spec->cur_adc_stream_tag, 0, | |
19190 | + spec->cur_adc_format); | |
19191 | + | |
19192 | +} | |
19193 | + | |
19194 | +static void alc680_unsol_event(struct hda_codec *codec, | |
19195 | + unsigned int res) | |
19196 | +{ | |
19197 | + if ((res >> 26) == ALC880_HP_EVENT) | |
19198 | + alc_automute_amp(codec); | |
19199 | + if ((res >> 26) == ALC880_MIC_EVENT) | |
19200 | + alc680_rec_autoswitch(codec); | |
19201 | +} | |
19202 | + | |
19203 | +static void alc680_inithook(struct hda_codec *codec) | |
19204 | +{ | |
19205 | + alc_automute_amp(codec); | |
19206 | + alc680_rec_autoswitch(codec); | |
19207 | +} | |
19208 | + | |
19090 | 19209 | /* create input playback/capture controls for the given pin */ |
19091 | 19210 | static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid, |
19092 | 19211 | const char *ctlname, int idx) |
19093 | 19212 | |
... | ... | @@ -19197,14 +19316,8 @@ |
19197 | 19316 | #define alc680_pcm_analog_capture alc880_pcm_analog_capture |
19198 | 19317 | #define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture |
19199 | 19318 | #define alc680_pcm_digital_playback alc880_pcm_digital_playback |
19319 | +#define alc680_pcm_digital_capture alc880_pcm_digital_capture | |
19200 | 19320 | |
19201 | -static struct hda_input_mux alc680_capture_source = { | |
19202 | - .num_items = 1, | |
19203 | - .items = { | |
19204 | - { "Mic", 0x0 }, | |
19205 | - }, | |
19206 | -}; | |
19207 | - | |
19208 | 19321 | /* |
19209 | 19322 | * BIOS auto configuration |
19210 | 19323 | */ |
... | ... | @@ -19218,6 +19331,7 @@ |
19218 | 19331 | alc680_ignore); |
19219 | 19332 | if (err < 0) |
19220 | 19333 | return err; |
19334 | + | |
19221 | 19335 | if (!spec->autocfg.line_outs) { |
19222 | 19336 | if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) { |
19223 | 19337 | spec->multiout.max_channels = 2; |
... | ... | @@ -19239,8 +19353,6 @@ |
19239 | 19353 | add_mixer(spec, spec->kctls.list); |
19240 | 19354 | |
19241 | 19355 | add_verb(spec, alc680_init_verbs); |
19242 | - spec->num_mux_defs = 1; | |
19243 | - spec->input_mux = &alc680_capture_source; | |
19244 | 19356 | |
19245 | 19357 | err = alc_auto_add_mic_boost(codec); |
19246 | 19358 | if (err < 0) |
19247 | 19359 | |
19248 | 19360 | |
... | ... | @@ -19279,17 +19391,17 @@ |
19279 | 19391 | static struct alc_config_preset alc680_presets[] = { |
19280 | 19392 | [ALC680_BASE] = { |
19281 | 19393 | .mixers = { alc680_base_mixer }, |
19282 | - .cap_mixer = alc680_capture_mixer, | |
19394 | + .cap_mixer = alc680_master_capture_mixer, | |
19283 | 19395 | .init_verbs = { alc680_init_verbs }, |
19284 | 19396 | .num_dacs = ARRAY_SIZE(alc680_dac_nids), |
19285 | 19397 | .dac_nids = alc680_dac_nids, |
19286 | - .num_adc_nids = ARRAY_SIZE(alc680_adc_nids), | |
19287 | - .adc_nids = alc680_adc_nids, | |
19288 | - .hp_nid = 0x04, | |
19289 | 19398 | .dig_out_nid = ALC680_DIGOUT_NID, |
19290 | 19399 | .num_channel_mode = ARRAY_SIZE(alc680_modes), |
19291 | 19400 | .channel_mode = alc680_modes, |
19292 | - .input_mux = &alc680_capture_source, | |
19401 | + .unsol_event = alc680_unsol_event, | |
19402 | + .setup = alc680_base_setup, | |
19403 | + .init_hook = alc680_inithook, | |
19404 | + | |
19293 | 19405 | }, |
19294 | 19406 | }; |
19295 | 19407 | |
19296 | 19408 | |
... | ... | @@ -19333,9 +19445,9 @@ |
19333 | 19445 | setup_preset(codec, &alc680_presets[board_config]); |
19334 | 19446 | |
19335 | 19447 | spec->stream_analog_playback = &alc680_pcm_analog_playback; |
19336 | - spec->stream_analog_capture = &alc680_pcm_analog_capture; | |
19337 | - spec->stream_analog_alt_capture = &alc680_pcm_analog_alt_capture; | |
19448 | + spec->stream_analog_capture = &alc680_pcm_analog_auto_capture; | |
19338 | 19449 | spec->stream_digital_playback = &alc680_pcm_digital_playback; |
19450 | + spec->stream_digital_capture = &alc680_pcm_digital_capture; | |
19339 | 19451 | |
19340 | 19452 | if (!spec->adc_nids) { |
19341 | 19453 | spec->adc_nids = alc680_adc_nids; |