static int add_vmaster(struct hda_codec *codec, hda_nid_t dac) { if(!codec) return -1; struct cs_spec *spec = codec->spec; if(!spec) return -1; unsigned int tlv[4]; int err; spec->vmaster_sw = snd_ctl_make_virtual_master("Master Playback Switch", NULL); if(!spec->vmaster_sw) return -1; err = snd_hda_ctl_add(codec, dac, spec->vmaster_sw); if (err < 0) return err; snd_hda_set_vmaster_tlv(codec, dac, HDA_OUTPUT, tlv); spec->vmaster_vol = snd_ctl_make_virtual_master("Master Playback Volume", tlv); if(!spec->vmaster_vol) return -1; err = snd_hda_ctl_add(codec, dac, spec->vmaster_vol); if (err < 0) return err; return 0; }
static int build_input(struct hda_codec *codec) { struct cs_spec *spec = codec->spec; int i, err; if (!spec->num_inputs) return 0; /* make bind-capture */ spec->capture_bind[0] = make_bind_capture(codec, &snd_hda_bind_sw); spec->capture_bind[1] = make_bind_capture(codec, &snd_hda_bind_vol); for (i = 0; i < 2; i++) { struct snd_kcontrol *kctl; if (!spec->capture_bind[i]) return -ENOMEM; kctl = snd_ctl_new1(&cs_capture_ctls[i], codec); if (!kctl) return -ENOMEM; kctl->private_value = (long)spec->capture_bind[i]; err = snd_hda_ctl_add(codec, kctl); if (err < 0) return err; } if (spec->num_inputs > 1 && !spec->mic_detect) { err = snd_hda_ctl_add(codec, snd_ctl_new1(&cs_capture_source, codec)); if (err < 0) return err; } return 0; }
static int build_input(struct hda_codec *codec) { struct cs_spec *spec = codec->spec; int i, err; if (!spec->num_inputs) return 0; /* make bind-capture */ spec->capture_bind[0] = make_bind_capture(codec, &snd_hda_bind_sw); spec->capture_bind[1] = make_bind_capture(codec, &snd_hda_bind_vol); for (i = 0; i < 2; i++) { struct snd_kcontrol *kctl; int n; if (!spec->capture_bind[i]) return -ENOMEM; kctl = snd_ctl_new1(&cs_capture_ctls[i], codec); if (!kctl) return -ENOMEM; kctl->private_value = (long)spec->capture_bind[i]; err = snd_hda_ctl_add(codec, 0, kctl); if (err < 0) return err; for (n = 0; n < AUTO_PIN_LAST; n++) { if (!spec->adc_nid[n]) continue; err = snd_hda_add_nid(codec, kctl, 0, spec->adc_nid[n]); if (err < 0) return err; } } if (spec->num_inputs > 1 && !spec->mic_detect) { struct snd_kcontrol *SND_CTL = snd_ctl_new1(&cs_capture_source, codec); if(!SND_CTL) return -1; err = snd_hda_ctl_add(codec, 0, SND_CTL); if (err < 0) return err; } for (i = 0; i < spec->num_inputs; i++) { err = add_input_volume_control(codec, &spec->autocfg, i); if (err < 0) return err; } return 0; }
/** * snd_hda_jack_add_kctl - Add a kctl for the given pin * * This assigns a jack-detection kctl to the given pin. The kcontrol * will have the given name and index. */ int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, const char *name, int idx) { struct hda_jack_tbl *jack; struct snd_kcontrol *kctl; int err, state; jack = snd_hda_jack_tbl_new(codec, nid); if (!jack) return 0; if (jack->kctl) return 0; /* already created */ kctl = snd_kctl_jack_new(name, idx, codec); if (!kctl) return -ENOMEM; err = snd_hda_ctl_add(codec, nid, kctl); if (err < 0) return err; jack->kctl = kctl; state = snd_hda_jack_detect(codec, nid); snd_kctl_jack_report(codec->bus->card, kctl, state); #ifdef CONFIG_SND_HDA_INPUT_JACK jack->type = get_input_jack_type(codec, nid); err = snd_jack_new(codec->bus->card, name, jack->type, &jack->jack); if (err < 0) return err; jack->jack->private_data = jack; jack->jack->private_free = hda_free_jack_priv; snd_jack_report(jack->jack, state ? jack->type : 0); #endif return 0; }
static int _add_volume(struct hda_codec *codec, hda_nid_t nid, const char *pfx, int chan, int dir) { char namestr[44]; int type = dir ? HDA_INPUT : HDA_OUTPUT; struct snd_kcontrol_new knew = HDA_CODEC_VOLUME_MONO(namestr, nid, chan, 0, type); sprintf(namestr, "%s %s Volume", pfx, dirstr[dir]); return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec)); }
static int add_mute(struct hda_codec *codec, const char *name, int index, unsigned int pval, int dir, struct snd_kcontrol **kctlp) { char tmp[44]; struct snd_kcontrol_new knew = HDA_CODEC_MUTE_IDX(tmp, index, 0, 0, HDA_OUTPUT); knew.private_value = pval; snprintf(tmp, sizeof(tmp), "%s %s Switch", name, dir_sfx[dir]); *kctlp = snd_ctl_new1(&knew, codec); return snd_hda_ctl_add(codec, *kctlp); }
static int add_volume(struct hda_codec *codec, const char *name, int index, unsigned int pval, int dir, struct snd_kcontrol **kctlp) { char tmp[32]; struct snd_kcontrol_new knew = HDA_CODEC_VOLUME_IDX(tmp, index, 0, 0, HDA_OUTPUT); knew.private_value = pval; snprintf(tmp, sizeof(tmp), "%s %s Volume", name, dir_sfx[dir]); *kctlp = snd_ctl_new1(&knew, codec); (*kctlp)->id.subdevice = HDA_SUBDEV_AMP_FLAG; return snd_hda_ctl_add(codec, 0, *kctlp); }
static int _add_volume(struct hda_codec *codec, hda_nid_t nid, const char *pfx, int chan, int dir) { char namestr[44]; int type = dir ? HDA_INPUT : HDA_OUTPUT; struct snd_kcontrol_new knew = HDA_CODEC_VOLUME_MONO(namestr, nid, chan, 0, type); if ((query_amp_caps(codec, nid, type) & AC_AMPCAP_NUM_STEPS) == 0) { snd_printdd("Skipping '%s %s Volume' (no amp on node 0x%x)\n", pfx, dirstr[dir], nid); return 0; } sprintf(namestr, "%s %s Volume", pfx, dirstr[dir]); return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec)); }
static int cs421x_build_controls(struct hda_codec *codec) { struct cs_spec *spec = codec->spec; int err; err = snd_hda_gen_build_controls(codec); if (err < 0) return err; if (spec->gen.autocfg.speaker_outs && spec->vendor_nid == CS4210_VENDOR_NID) { err = snd_hda_ctl_add(codec, 0, snd_ctl_new1(&cs421x_speaker_boost_ctl, codec)); if (err < 0) return err; } return 0; }
/* create beep controls if needed */ static int add_beep_ctls(struct hda_codec *codec) { struct conexant_spec *spec = codec->spec; int err; if (spec->beep_amp) { const struct snd_kcontrol_new *knew; for (knew = cxt_beep_mixer; knew->name; knew++) { struct snd_kcontrol *kctl; kctl = snd_ctl_new1(knew, codec); if (!kctl) return -ENOMEM; kctl->private_value = spec->beep_amp; err = snd_hda_ctl_add(codec, 0, kctl); if (err < 0) return err; } } return 0; }
static int create_beep_ctls(struct hda_codec *codec) { struct ad198x_spec *spec = codec->spec; const struct snd_kcontrol_new *knew; if (!spec->beep_amp) return 0; for (knew = ad_beep_mixer ; knew->name; knew++) { int err; struct snd_kcontrol *kctl; kctl = snd_ctl_new1(knew, codec); if (!kctl) return -ENOMEM; kctl->private_value = spec->beep_amp; err = snd_hda_ctl_add(codec, 0, kctl); if (err < 0) return err; } return 0; }
static int ad198x_build_controls(struct hda_codec *codec) { struct ad198x_spec *spec = codec->spec; struct snd_kcontrol *kctl; unsigned int i; int err; for (i = 0; i < spec->num_mixers; i++) { err = snd_hda_add_new_ctls(codec, spec->mixers[i]); if (err < 0) return err; } if (spec->multiout.dig_out_nid) { err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); if (err < 0) return err; err = snd_hda_create_spdif_share_sw(codec, &spec->multiout); if (err < 0) return err; spec->multiout.share_spdif = 1; } if (spec->dig_in_nid) { err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); if (err < 0) return err; } /* create beep controls if needed */ #ifdef CONFIG_SND_HDA_INPUT_BEEP if (spec->beep_amp) { struct snd_kcontrol_new *knew; knew = spec->analog_beep ? ad_beep2_mixer : ad_beep_mixer; for ( ; knew->name; knew++) { struct snd_kcontrol *kctl; kctl = snd_ctl_new1(knew, codec); if (!kctl) return -ENOMEM; kctl->private_value = spec->beep_amp; err = snd_hda_ctl_add(codec, 0, kctl); if (err < 0) return err; } } #endif /* if we have no master control, let's create it */ if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { unsigned int vmaster_tlv[4]; snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, HDA_OUTPUT, vmaster_tlv); err = snd_hda_add_vmaster(codec, "Master Playback Volume", vmaster_tlv, (spec->slave_vols ? spec->slave_vols : ad_slave_vols)); if (err < 0) return err; } if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { err = snd_hda_add_vmaster(codec, "Master Playback Switch", NULL, (spec->slave_sws ? spec->slave_sws : ad_slave_sws)); if (err < 0) return err; } ad198x_free_kctls(codec); /* no longer needed */ /* assign Capture Source enums to NID */ kctl = snd_hda_find_mixer_ctl(codec, "Capture Source"); if (!kctl) kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); for (i = 0; kctl && i < kctl->count; i++) { err = snd_hda_add_nid(codec, kctl, i, spec->capsrc_nids[i]); if (err < 0) return err; } /* assign IEC958 enums to NID */ kctl = snd_hda_find_mixer_ctl(codec, SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source"); if (kctl) { err = snd_hda_add_nid(codec, kctl, 0, spec->multiout.dig_out_nid); if (err < 0) return err; } return 0; }