static int ad1988_auto_smux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct ad198x_spec *spec = codec->spec; unsigned int val = ucontrol->value.enumerated.item[0]; struct nid_path *path; int num_conns = snd_hda_get_num_conns(codec, 0x0b) + 1; if (val >= num_conns) return -EINVAL; if (spec->cur_smux == val) return 0; mutex_lock(&codec->control_mutex); path = snd_hda_get_path_from_idx(codec, spec->smux_paths[spec->cur_smux]); if (path) snd_hda_activate_path(codec, path, false, true); path = snd_hda_get_path_from_idx(codec, spec->smux_paths[val]); if (path) snd_hda_activate_path(codec, path, true, true); spec->cur_smux = val; mutex_unlock(&codec->control_mutex); return 1; }
static void olpc_xo_update_mic_pins(struct hda_codec *codec) { struct conexant_spec *spec = codec->spec; int cur_input, val; struct nid_path *path; cur_input = spec->gen.input_paths[0][spec->gen.cur_mux[0]]; /* Set up mic pins for port-B, C and F dynamically as the recording * LED is turned on/off by these pin controls */ if (!spec->dc_enable) { /* disable DC bias path and pin for port F */ update_mic_pin(codec, 0x1e, 0); snd_hda_activate_path(codec, spec->dc_mode_path, false, false); /* update port B (ext mic) and C (int mic) */ /* OLPC defers mic widget control until when capture is * started because the microphone LED comes on as soon as * these settings are put in place. if we did this before * recording, it would give the false indication that * recording is happening when it is not. */ update_mic_pin(codec, 0x1a, spec->recording ? snd_hda_codec_get_pin_target(codec, 0x1a) : 0); update_mic_pin(codec, 0x1b, spec->recording ? snd_hda_codec_get_pin_target(codec, 0x1b) : 0); /* enable normal mic path */ path = snd_hda_get_path_from_idx(codec, cur_input); if (path) snd_hda_activate_path(codec, path, true, false); } else { /* disable normal mic path */ path = snd_hda_get_path_from_idx(codec, cur_input); if (path) snd_hda_activate_path(codec, path, false, false); /* Even though port F is the DC input, the bias is controlled * on port B. We also leave that port as an active input (but * unselected) in DC mode just in case that is necessary to * make the bias setting take effect. */ if (spec->recording) val = olpc_xo_dc_bias.items[spec->dc_input_bias].index; else val = 0; update_mic_pin(codec, 0x1a, val); update_mic_pin(codec, 0x1b, 0); /* enable DC bias path and pin */ update_mic_pin(codec, 0x1e, spec->recording ? PIN_IN : 0); snd_hda_activate_path(codec, spec->dc_mode_path, true, false); } }
static int ad1988_auto_init(struct hda_codec *codec) { struct ad198x_spec *spec = codec->spec; int i, err; err = snd_hda_gen_init(codec); if (err < 0) return err; if (!spec->gen.autocfg.dig_outs) return 0; for (i = 0; i < 4; i++) { struct nid_path *path; path = snd_hda_get_path_from_idx(codec, spec->smux_paths[i]); if (path) snd_hda_activate_path(codec, path, path->active, false); } return 0; }