+static int cx_auto_mux_enum_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct conexant_spec *spec = codec->spec;
+
+ return snd_hda_input_mux_info(&spec->private_imux, uinfo);
+}
+
+static int cx_auto_mux_enum_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct conexant_spec *spec = codec->spec;
+
+ ucontrol->value.enumerated.item[0] = spec->cur_mux[0];
+ return 0;
+}
+
+static int cx_auto_mux_enum_update(struct hda_codec *codec,
+ const struct hda_input_mux *imux,
+ unsigned int idx)
+{
+ struct conexant_spec *spec = codec->spec;
+ hda_nid_t adc;
+
+ if (!imux->num_items)
+ return 0;
+ if (idx >= imux->num_items)
+ idx = imux->num_items - 1;
+ if (spec->cur_mux[0] == idx)
+ return 0;
+ adc = spec->imux_adcs[idx];
+ if (has_multi_connection(codec, adc))
+ snd_hda_codec_write(codec, adc, 0,
+ AC_VERB_SET_CONNECT_SEL,
+ imux->items[idx].index);
+ if (spec->cur_adc && spec->cur_adc != adc) {
+ /* stream is running, let's swap the current ADC */
+ __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
+ spec->cur_adc = adc;
+ snd_hda_codec_setup_stream(codec, adc,
+ spec->cur_adc_stream_tag, 0,
+ spec->cur_adc_format);
+ }
+ spec->cur_mux[0] = idx;
+ return 1;
+}
+
+static int cx_auto_mux_enum_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct conexant_spec *spec = codec->spec;
+
+ return cx_auto_mux_enum_update(codec, &spec->private_imux,
+ ucontrol->value.enumerated.item[0]);
+}
+
+static const struct snd_kcontrol_new cx_auto_capture_mixers[] = {
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Capture Source",
+ .info = cx_auto_mux_enum_info,
+ .get = cx_auto_mux_enum_get,
+ .put = cx_auto_mux_enum_put
+ },
+ {}
+};
+