From 5b0cb1d850c26893b1468b3a519433a1b7a176be Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Tue, 8 Dec 2009 16:13:32 +0100 Subject: ALSA: hda - add more NID->Control mapping This set of changes add missing NID values to some static control elemenents. Also, it handles all "Capture Source" or "Input Source" controls. Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 120 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 118 insertions(+), 2 deletions(-) (limited to 'sound/pci/hda/patch_realtek.c') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 888b6313eec..6b0b8728f6b 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -627,6 +627,7 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, #define ALC_PIN_MODE(xname, nid, dir) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ + .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ .info = alc_pin_mode_info, \ .get = alc_pin_mode_get, \ .put = alc_pin_mode_put, \ @@ -678,6 +679,7 @@ static int alc_gpio_data_put(struct snd_kcontrol *kcontrol, } #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ + .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ .info = alc_gpio_data_info, \ .get = alc_gpio_data_get, \ .put = alc_gpio_data_put, \ @@ -732,6 +734,7 @@ static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol, } #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ + .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ .info = alc_spdif_ctrl_info, \ .get = alc_spdif_ctrl_get, \ .put = alc_spdif_ctrl_put, \ @@ -785,6 +788,7 @@ static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol, #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ + .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ .info = alc_eapd_ctrl_info, \ .get = alc_eapd_ctrl_get, \ .put = alc_eapd_ctrl_put, \ @@ -2410,6 +2414,15 @@ static const char *alc_slave_sws[] = { * build control elements */ +#define NID_MAPPING (-1) + +#define SUBDEV_SPEAKER_ (0 << 6) +#define SUBDEV_HP_ (1 << 6) +#define SUBDEV_LINE_ (2 << 6) +#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f)) +#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f)) +#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f)) + static void alc_free_kctls(struct hda_codec *codec); #ifdef CONFIG_SND_HDA_INPUT_BEEP @@ -2424,8 +2437,11 @@ static struct snd_kcontrol_new alc_beep_mixer[] = { static int alc_build_controls(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - int err; - int i; + struct snd_kcontrol *kctl; + struct snd_kcontrol_new *knew; + int i, j, err; + unsigned int u; + hda_nid_t nid; for (i = 0; i < spec->num_mixers; i++) { err = snd_hda_add_new_ctls(codec, spec->mixers[i]); @@ -2494,6 +2510,73 @@ static int alc_build_controls(struct hda_codec *codec) } alc_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_nids(codec, kctl, i, spec->capsrc_nids, + spec->input_mux->num_items); + if (err < 0) + return err; + } + if (spec->cap_mixer) { + const char *kname = kctl ? kctl->id.name : NULL; + for (knew = spec->cap_mixer; knew->name; knew++) { + if (kname && strcmp(knew->name, kname) == 0) + continue; + kctl = snd_hda_find_mixer_ctl(codec, knew->name); + for (i = 0; kctl && i < kctl->count; i++) { + err = snd_hda_add_nid(codec, kctl, i, + spec->adc_nids[i]); + if (err < 0) + return err; + } + } + } + + /* other nid->control mapping */ + for (i = 0; i < spec->num_mixers; i++) { + for (knew = spec->mixers[i]; knew->name; knew++) { + if (knew->iface != NID_MAPPING) + continue; + kctl = snd_hda_find_mixer_ctl(codec, knew->name); + if (kctl == NULL) + continue; + u = knew->subdevice; + for (j = 0; j < 4; j++, u >>= 8) { + nid = u & 0x3f; + if (nid == 0) + continue; + switch (u & 0xc0) { + case SUBDEV_SPEAKER_: + nid = spec->autocfg.speaker_pins[nid]; + break; + case SUBDEV_LINE_: + nid = spec->autocfg.line_out_pins[nid]; + break; + case SUBDEV_HP_: + nid = spec->autocfg.hp_pins[nid]; + break; + default: + continue; + } + err = snd_hda_add_nid(codec, kctl, 0, nid); + if (err < 0) + return err; + } + u = knew->private_value; + for (j = 0; j < 4; j++, u >>= 8) { + nid = u & 0xff; + if (nid == 0) + continue; + err = snd_hda_add_nid(codec, kctl, 0, nid); + if (err < 0) + return err; + } + } + } return 0; } @@ -3781,6 +3864,7 @@ static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol, #define PIN_CTL_TEST(xname,nid) { \ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ + .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ .info = alc_test_pin_ctl_info, \ .get = alc_test_pin_ctl_get, \ .put = alc_test_pin_ctl_put, \ @@ -3790,6 +3874,7 @@ static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol, #define PIN_SRC_TEST(xname,nid) { \ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ + .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ .info = alc_test_pin_src_info, \ .get = alc_test_pin_src_get, \ .put = alc_test_pin_src_put, \ @@ -5080,6 +5165,7 @@ static struct snd_kcontrol_new alc260_hp_output_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", + .subdevice = HDA_SUBDEV_NID_FLAG | 0x11, .info = snd_ctl_boolean_mono_info, .get = alc260_hp_master_sw_get, .put = alc260_hp_master_sw_put, @@ -5118,6 +5204,7 @@ static struct snd_kcontrol_new alc260_hp_3013_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", + .subdevice = HDA_SUBDEV_NID_FLAG | 0x11, .info = snd_ctl_boolean_mono_info, .get = alc260_hp_master_sw_get, .put = alc260_hp_master_sw_put, @@ -10188,8 +10275,14 @@ static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol, .info = snd_ctl_boolean_mono_info, \ .get = alc262_hp_master_sw_get, \ .put = alc262_hp_master_sw_put, \ + }, \ + { \ + .iface = NID_MAPPING, \ + .name = "Master Playback Switch", \ + .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \ } + static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { ALC262_HP_MASTER_SWITCH, HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), @@ -10347,6 +10440,12 @@ static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol, .info = snd_ctl_boolean_mono_info, \ .get = alc262_hippo_master_sw_get, \ .put = alc262_hippo_master_sw_put, \ + }, \ + { \ + .iface = NID_MAPPING, \ + .name = "Master Playback Switch", \ + .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \ + (SUBDEV_SPEAKER(0) << 16), \ } static struct snd_kcontrol_new alc262_hippo_mixer[] = { @@ -10820,11 +10919,17 @@ static struct snd_kcontrol_new alc262_fujitsu_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", + .subdevice = HDA_SUBDEV_NID_FLAG | 0x14, .info = snd_hda_mixer_amp_switch_info, .get = snd_hda_mixer_amp_switch_get, .put = alc262_fujitsu_master_sw_put, .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), }, + { + .iface = NID_MAPPING, + .name = "Master Playback Switch", + .private_value = 0x1b, + }, HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), @@ -10855,6 +10960,7 @@ static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", + .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b, .info = snd_hda_mixer_amp_switch_info, .get = snd_hda_mixer_amp_switch_get, .put = alc262_lenovo_3000_master_sw_put, @@ -11009,6 +11115,11 @@ static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = { .get = alc_mux_enum_get, .put = alc262_ultra_mux_enum_put, }, + { + .iface = NID_MAPPING, + .name = "Capture Source", + .private_value = 0x15, + }, { } /* end */ }; @@ -12026,6 +12137,7 @@ static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", + .subdevice = HDA_SUBDEV_NID_FLAG | 0x14, .info = snd_hda_mixer_amp_switch_info, .get = snd_hda_mixer_amp_switch_get, .put = alc268_acer_master_sw_put, @@ -12041,6 +12153,7 @@ static struct snd_kcontrol_new alc268_acer_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", + .subdevice = HDA_SUBDEV_NID_FLAG | 0x14, .info = snd_hda_mixer_amp_switch_info, .get = snd_hda_mixer_amp_switch_get, .put = alc268_acer_master_sw_put, @@ -12058,6 +12171,7 @@ static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", + .subdevice = HDA_SUBDEV_NID_FLAG | 0x14, .info = snd_hda_mixer_amp_switch_info, .get = snd_hda_mixer_amp_switch_get, .put = alc268_acer_master_sw_put, @@ -13010,6 +13124,7 @@ static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", + .subdevice = HDA_SUBDEV_NID_FLAG | 0x14, .info = snd_hda_mixer_amp_switch_info, .get = snd_hda_mixer_amp_switch_get, .put = alc268_acer_master_sw_put, @@ -13030,6 +13145,7 @@ static struct snd_kcontrol_new alc269_lifebook_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", + .subdevice = HDA_SUBDEV_NID_FLAG | 0x14, .info = snd_hda_mixer_amp_switch_info, .get = snd_hda_mixer_amp_switch_get, .put = alc268_acer_master_sw_put, -- cgit v1.2.3-70-g09d2 From 9e3fd8719f624a43575b56a4777b1552399a8be8 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Tue, 8 Dec 2009 17:45:25 +0100 Subject: ALSA: hda - introduce HDA_SUBDEV_AMP_FLAG (ControlAmp in proc) The purpose of this changeset is to show information about amplifier setting in the codec proc file. Something like: Control: name="Front Playback Volume", index=0, device=0 ControlAmp: chs=3, dir=Out, idx=0, ofs=0 Control: name="Front Playback Switch", index=0, device=0 ControlAmp: chs=3, dir=In, idx=2, ofs=0 Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_codec.c | 14 +++++++++----- sound/pci/hda/hda_local.h | 11 ++++++++--- sound/pci/hda/hda_proc.c | 8 ++++++++ sound/pci/hda/patch_analog.c | 12 +++++++----- sound/pci/hda/patch_cirrus.c | 2 ++ sound/pci/hda/patch_conexant.c | 1 + sound/pci/hda/patch_realtek.c | 18 ++++++++++-------- sound/pci/hda/patch_sigmatel.c | 3 ++- sound/pci/hda/patch_via.c | 4 +++- 9 files changed, 50 insertions(+), 23 deletions(-) (limited to 'sound/pci/hda/patch_realtek.c') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 20100b1548e..c9af15ed7f1 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1723,19 +1723,22 @@ EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl); * * snd_hda_ctl_add() checks the control subdev id field whether * #HDA_SUBDEV_NID_FLAG bit is set. If set (and @nid is zero), the lower - * bits value is taken as the NID to assign. + * bits value is taken as the NID to assign. The #HDA_NID_ITEM_AMP bit + * specifies if kctl->private_value is a HDA amplifier value. */ int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid, struct snd_kcontrol *kctl) { int err; + unsigned short flags = 0; struct hda_nid_item *item; - if (kctl->id.subdevice & HDA_SUBDEV_NID_FLAG) { - if (nid == 0) - nid = kctl->id.subdevice & 0xffff; + if (kctl->id.subdevice & HDA_SUBDEV_AMP_FLAG) + flags |= HDA_NID_ITEM_AMP; + if ((kctl->id.subdevice & HDA_SUBDEV_NID_FLAG) != 0 && nid == 0) + nid = kctl->id.subdevice & 0xffff; + if (kctl->id.subdevice & 0xf0000000) kctl->id.subdevice = 0; - } err = snd_ctl_add(codec->bus->card, kctl); if (err < 0) return err; @@ -1744,6 +1747,7 @@ int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid, return -ENOMEM; item->kctl = kctl; item->nid = nid; + item->flags = flags; return 0; } EXPORT_SYMBOL_HDA(snd_hda_ctl_add); diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 98cf3f4f375..0a256471f81 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h @@ -31,6 +31,7 @@ * in snd_hda_ctl_add(), so that this value won't appear in the outside. */ #define HDA_SUBDEV_NID_FLAG (1U << 31) +#define HDA_SUBDEV_AMP_FLAG (1U << 30) /* * for mixer controls @@ -42,7 +43,7 @@ /* mono volume with index (index=0,1,...) (channel=1,2) */ #define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ - .subdevice = HDA_SUBDEV_NID_FLAG | (nid), \ + .subdevice = HDA_SUBDEV_NID_FLAG | HDA_SUBDEV_AMP_FLAG | (nid), \ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \ @@ -63,7 +64,7 @@ /* mono mute switch with index (index=0,1,...) (channel=1,2) */ #define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ - .subdevice = HDA_SUBDEV_NID_FLAG | (nid), \ + .subdevice = HDA_SUBDEV_NID_FLAG | HDA_SUBDEV_AMP_FLAG | (nid), \ .info = snd_hda_mixer_amp_switch_info, \ .get = snd_hda_mixer_amp_switch_get, \ .put = snd_hda_mixer_amp_switch_put, \ @@ -81,7 +82,7 @@ /* special beep mono mute switch with index (index=0,1,...) (channel=1,2) */ #define HDA_CODEC_MUTE_BEEP_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ - .subdevice = HDA_SUBDEV_NID_FLAG | (nid), \ + .subdevice = HDA_SUBDEV_NID_FLAG | HDA_SUBDEV_AMP_FLAG | (nid), \ .info = snd_hda_mixer_amp_switch_info, \ .get = snd_hda_mixer_amp_switch_get, \ .put = snd_hda_mixer_amp_switch_put_beep, \ @@ -466,10 +467,14 @@ u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid); u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid); int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); +/* flags for hda_nid_item */ +#define HDA_NID_ITEM_AMP (1<<0) + struct hda_nid_item { struct snd_kcontrol *kctl; unsigned int index; hda_nid_t nid; + unsigned short flags; }; int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid, diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c index 2e27d6a8b44..f97d35de66c 100644 --- a/sound/pci/hda/hda_proc.c +++ b/sound/pci/hda/hda_proc.c @@ -76,6 +76,14 @@ static void print_nid_array(struct snd_info_buffer *buffer, " Control: name=\"%s\", index=%i, device=%i\n", kctl->id.name, kctl->id.index + item->index, kctl->id.device); + if (item->flags & HDA_NID_ITEM_AMP) + snd_iprintf(buffer, + " ControlAmp: chs=%lu, dir=%s, " + "idx=%lu, ofs=%lu\n", + get_amp_channels(kctl), + get_amp_direction(kctl) ? "Out" : "In", + get_amp_index(kctl), + get_amp_offset(kctl)); } } } diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index d418842373f..5e2bb181a14 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -832,7 +832,7 @@ static struct snd_kcontrol_new ad1986a_automute_master_mixers[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", - .subdevice = HDA_SUBDEV_NID_FLAG | 0x1a, + .subdevice = HDA_SUBDEV_NID_FLAG | HDA_SUBDEV_AMP_FLAG | 0x1a, .info = snd_hda_mixer_amp_switch_info, .get = snd_hda_mixer_amp_switch_get, .put = ad1986a_hp_master_sw_put, @@ -2602,7 +2602,9 @@ static int add_control(struct ad198x_spec *spec, int type, const char *name, if (! knew->name) return -ENOMEM; if (get_amp_nid_(val)) - knew->subdevice = HDA_SUBDEV_NID_FLAG | get_amp_nid_(val); + knew->subdevice = HDA_SUBDEV_NID_FLAG | + HDA_SUBDEV_AMP_FLAG | + get_amp_nid_(val); knew->private_value = val; return 0; } @@ -3756,7 +3758,7 @@ static struct snd_kcontrol_new ad1884a_laptop_mixers[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", - .subdevice = HDA_SUBDEV_NID_FLAG | 0x21, + .subdevice = HDA_SUBDEV_NID_FLAG | HDA_SUBDEV_AMP_FLAG | 0x21, .info = snd_hda_mixer_amp_switch_info, .get = snd_hda_mixer_amp_switch_get, .put = ad1884a_mobile_master_sw_put, @@ -3785,7 +3787,7 @@ static struct snd_kcontrol_new ad1884a_mobile_mixers[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", - .subdevice = HDA_SUBDEV_NID_FLAG | 0x21, + .subdevice = HDA_SUBDEV_NID_FLAG | HDA_SUBDEV_AMP_FLAG | 0x21, .info = snd_hda_mixer_amp_switch_info, .get = snd_hda_mixer_amp_switch_get, .put = ad1884a_mobile_master_sw_put, @@ -4127,7 +4129,7 @@ static struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = { /* HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .subdevice = HDA_SUBDEV_NID_FLAG | 0x21, + .subdevice = HDA_SUBDEV_NID_FLAG | HDA_SUBDEV_AMP_FLAG | 0x21, .name = "Master Playback Switch", .info = snd_hda_mixer_amp_switch_info, .get = snd_hda_mixer_amp_switch_get, diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index d0b8c6dc732..e51f6658aa2 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c @@ -500,6 +500,7 @@ static int add_mute(struct hda_codec *codec, const char *name, int index, knew.private_value = pval; snprintf(tmp, sizeof(tmp), "%s %s Switch", name, dir_sfx[dir]); *kctlp = snd_ctl_new1(&knew, codec); + (*kctlp)->id.subdevice = HDA_SUBDEV_AMP_FLAG; return snd_hda_ctl_add(codec, get_amp_nid_(pval), *kctlp); } @@ -513,6 +514,7 @@ static int add_volume(struct hda_codec *codec, const char *name, 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, get_amp_nid_(pval), *kctlp); } diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index a09c03c3f62..b68650af40a 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -2178,6 +2178,7 @@ static struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = { .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, + .subdevice = HDA_SUBDEV_NID_FLAG | HDA_SUBDEV_AMP_FLAG | 0x10, .info = snd_hda_mixer_amp_volume_info, .get = snd_hda_mixer_amp_volume_get, .put = snd_hda_mixer_amp_volume_put, diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 6b0b8728f6b..87bf7bd6292 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -4414,7 +4414,9 @@ static int add_control(struct alc_spec *spec, int type, const char *name, if (!knew->name) return -ENOMEM; if (get_amp_nid_(val)) - knew->subdevice = HDA_SUBDEV_NID_FLAG | get_amp_nid_(val); + knew->subdevice = HDA_SUBDEV_NID_FLAG | + HDA_SUBDEV_AMP_FLAG | + get_amp_nid_(val); knew->private_value = val; return 0; } @@ -10919,7 +10921,7 @@ static struct snd_kcontrol_new alc262_fujitsu_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", - .subdevice = HDA_SUBDEV_NID_FLAG | 0x14, + .subdevice = HDA_SUBDEV_NID_FLAG | HDA_SUBDEV_AMP_FLAG | 0x14, .info = snd_hda_mixer_amp_switch_info, .get = snd_hda_mixer_amp_switch_get, .put = alc262_fujitsu_master_sw_put, @@ -10960,7 +10962,7 @@ static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", - .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b, + .subdevice = HDA_SUBDEV_NID_FLAG | HDA_SUBDEV_AMP_FLAG | 0x1b, .info = snd_hda_mixer_amp_switch_info, .get = snd_hda_mixer_amp_switch_get, .put = alc262_lenovo_3000_master_sw_put, @@ -12137,7 +12139,7 @@ static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", - .subdevice = HDA_SUBDEV_NID_FLAG | 0x14, + .subdevice = HDA_SUBDEV_NID_FLAG | HDA_SUBDEV_AMP_FLAG | 0x14, .info = snd_hda_mixer_amp_switch_info, .get = snd_hda_mixer_amp_switch_get, .put = alc268_acer_master_sw_put, @@ -12153,7 +12155,7 @@ static struct snd_kcontrol_new alc268_acer_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", - .subdevice = HDA_SUBDEV_NID_FLAG | 0x14, + .subdevice = HDA_SUBDEV_NID_FLAG | HDA_SUBDEV_AMP_FLAG | 0x14, .info = snd_hda_mixer_amp_switch_info, .get = snd_hda_mixer_amp_switch_get, .put = alc268_acer_master_sw_put, @@ -12171,7 +12173,7 @@ static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", - .subdevice = HDA_SUBDEV_NID_FLAG | 0x14, + .subdevice = HDA_SUBDEV_NID_FLAG | HDA_SUBDEV_AMP_FLAG | 0x14, .info = snd_hda_mixer_amp_switch_info, .get = snd_hda_mixer_amp_switch_get, .put = alc268_acer_master_sw_put, @@ -13124,7 +13126,7 @@ static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", - .subdevice = HDA_SUBDEV_NID_FLAG | 0x14, + .subdevice = HDA_SUBDEV_NID_FLAG | HDA_SUBDEV_AMP_FLAG | 0x14, .info = snd_hda_mixer_amp_switch_info, .get = snd_hda_mixer_amp_switch_get, .put = alc268_acer_master_sw_put, @@ -13145,7 +13147,7 @@ static struct snd_kcontrol_new alc269_lifebook_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", - .subdevice = HDA_SUBDEV_NID_FLAG | 0x14, + .subdevice = HDA_SUBDEV_NID_FLAG | HDA_SUBDEV_AMP_FLAG | 0x14, .info = snd_hda_mixer_amp_switch_info, .get = snd_hda_mixer_amp_switch_get, .put = alc268_acer_master_sw_put, diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 3d59f832584..1ee586b65b6 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -2702,7 +2702,8 @@ stac_control_new(struct sigmatel_spec *spec, return NULL; } if (nid) - knew->subdevice = HDA_SUBDEV_NID_FLAG | nid; + knew->subdevice = HDA_SUBDEV_NID_FLAG | + HDA_SUBDEV_AMP_FLAG | nid; return knew; } diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 64995e8e3a7..b94cdee5eb5 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -458,7 +458,9 @@ static int via_add_control(struct via_spec *spec, int type, const char *name, if (!knew->name) return -ENOMEM; if (get_amp_nid_(val)) - knew->subdevice = HDA_SUBDEV_NID_FLAG | get_amp_nid_(val); + knew->subdevice = HDA_SUBDEV_NID_FLAG | + HDA_SUBDEV_AMP_FLAG | + get_amp_nid_(val); knew->private_value = val; return 0; } -- cgit v1.2.3-70-g09d2 From 5e26dfd0615868872cb44842f1e1428c7b414ab0 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Thu, 10 Dec 2009 13:57:01 +0100 Subject: ALSA: hda - simplify usage of HDA_SUBDEV_AMP_FLAG The HDA_SUBDEV_NID_FLAG is duplicate for amplifier control elements. Move get_amp_nid_() call to the snd_hda_ctl_add() function. Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_codec.c | 7 +++++-- sound/pci/hda/hda_local.h | 6 +++--- sound/pci/hda/patch_analog.c | 16 ++++++---------- sound/pci/hda/patch_cirrus.c | 4 ++-- sound/pci/hda/patch_conexant.c | 2 +- sound/pci/hda/patch_realtek.c | 21 +++++++++------------ sound/pci/hda/patch_sigmatel.c | 8 +++----- sound/pci/hda/patch_via.c | 4 +--- 8 files changed, 30 insertions(+), 38 deletions(-) (limited to 'sound/pci/hda/patch_realtek.c') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index c9af15ed7f1..c848ec0f085 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1733,11 +1733,14 @@ int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid, unsigned short flags = 0; struct hda_nid_item *item; - if (kctl->id.subdevice & HDA_SUBDEV_AMP_FLAG) + if (kctl->id.subdevice & HDA_SUBDEV_AMP_FLAG) { flags |= HDA_NID_ITEM_AMP; + if (nid == 0) + nid = get_amp_nid_(kctl->private_value); + } if ((kctl->id.subdevice & HDA_SUBDEV_NID_FLAG) != 0 && nid == 0) nid = kctl->id.subdevice & 0xffff; - if (kctl->id.subdevice & 0xf0000000) + if (kctl->id.subdevice & (HDA_SUBDEV_NID_FLAG|HDA_SUBDEV_AMP_FLAG)) kctl->id.subdevice = 0; err = snd_ctl_add(codec->bus->card, kctl); if (err < 0) diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 0a256471f81..d505d052972 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h @@ -43,7 +43,7 @@ /* mono volume with index (index=0,1,...) (channel=1,2) */ #define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ - .subdevice = HDA_SUBDEV_NID_FLAG | HDA_SUBDEV_AMP_FLAG | (nid), \ + .subdevice = HDA_SUBDEV_AMP_FLAG, \ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \ @@ -64,7 +64,7 @@ /* mono mute switch with index (index=0,1,...) (channel=1,2) */ #define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ - .subdevice = HDA_SUBDEV_NID_FLAG | HDA_SUBDEV_AMP_FLAG | (nid), \ + .subdevice = HDA_SUBDEV_AMP_FLAG, \ .info = snd_hda_mixer_amp_switch_info, \ .get = snd_hda_mixer_amp_switch_get, \ .put = snd_hda_mixer_amp_switch_put, \ @@ -82,7 +82,7 @@ /* special beep mono mute switch with index (index=0,1,...) (channel=1,2) */ #define HDA_CODEC_MUTE_BEEP_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ - .subdevice = HDA_SUBDEV_NID_FLAG | HDA_SUBDEV_AMP_FLAG | (nid), \ + .subdevice = HDA_SUBDEV_AMP_FLAG, \ .info = snd_hda_mixer_amp_switch_info, \ .get = snd_hda_mixer_amp_switch_get, \ .put = snd_hda_mixer_amp_switch_put_beep, \ diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 5e2bb181a14..e75b5e5a1d5 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -209,9 +209,7 @@ static int ad198x_build_controls(struct hda_codec *codec) if (!kctl) return -ENOMEM; kctl->private_value = spec->beep_amp; - err = snd_hda_ctl_add(codec, - get_amp_nid_(spec->beep_amp), - kctl); + err = snd_hda_ctl_add(codec, 0, kctl); if (err < 0) return err; } @@ -832,7 +830,7 @@ static struct snd_kcontrol_new ad1986a_automute_master_mixers[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", - .subdevice = HDA_SUBDEV_NID_FLAG | HDA_SUBDEV_AMP_FLAG | 0x1a, + .subdevice = HDA_SUBDEV_AMP_FLAG, .info = snd_hda_mixer_amp_switch_info, .get = snd_hda_mixer_amp_switch_get, .put = ad1986a_hp_master_sw_put, @@ -2602,9 +2600,7 @@ static int add_control(struct ad198x_spec *spec, int type, const char *name, if (! knew->name) return -ENOMEM; if (get_amp_nid_(val)) - knew->subdevice = HDA_SUBDEV_NID_FLAG | - HDA_SUBDEV_AMP_FLAG | - get_amp_nid_(val); + knew->subdevice = HDA_SUBDEV_AMP_FLAG; knew->private_value = val; return 0; } @@ -3758,7 +3754,7 @@ static struct snd_kcontrol_new ad1884a_laptop_mixers[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", - .subdevice = HDA_SUBDEV_NID_FLAG | HDA_SUBDEV_AMP_FLAG | 0x21, + .subdevice = HDA_SUBDEV_AMP_FLAG, .info = snd_hda_mixer_amp_switch_info, .get = snd_hda_mixer_amp_switch_get, .put = ad1884a_mobile_master_sw_put, @@ -3787,7 +3783,7 @@ static struct snd_kcontrol_new ad1884a_mobile_mixers[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", - .subdevice = HDA_SUBDEV_NID_FLAG | HDA_SUBDEV_AMP_FLAG | 0x21, + .subdevice = HDA_SUBDEV_AMP_FLAG, .info = snd_hda_mixer_amp_switch_info, .get = snd_hda_mixer_amp_switch_get, .put = ad1884a_mobile_master_sw_put, @@ -4129,7 +4125,7 @@ static struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = { /* HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .subdevice = HDA_SUBDEV_NID_FLAG | HDA_SUBDEV_AMP_FLAG | 0x21, + .subdevice = HDA_SUBDEV_AMP_FLAG, .name = "Master Playback Switch", .info = snd_hda_mixer_amp_switch_info, .get = snd_hda_mixer_amp_switch_get, diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index e51f6658aa2..eeb91f6a06c 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c @@ -501,7 +501,7 @@ static int add_mute(struct hda_codec *codec, const char *name, int index, snprintf(tmp, sizeof(tmp), "%s %s Switch", name, dir_sfx[dir]); *kctlp = snd_ctl_new1(&knew, codec); (*kctlp)->id.subdevice = HDA_SUBDEV_AMP_FLAG; - return snd_hda_ctl_add(codec, get_amp_nid_(pval), *kctlp); + return snd_hda_ctl_add(codec, 0, *kctlp); } static int add_volume(struct hda_codec *codec, const char *name, @@ -515,7 +515,7 @@ static int add_volume(struct hda_codec *codec, const char *name, 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, get_amp_nid_(pval), *kctlp); + return snd_hda_ctl_add(codec, 0, *kctlp); } static void fix_volume_caps(struct hda_codec *codec, hda_nid_t dac) diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index b68650af40a..1ab2958a290 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -2178,7 +2178,7 @@ static struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = { .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, - .subdevice = HDA_SUBDEV_NID_FLAG | HDA_SUBDEV_AMP_FLAG | 0x10, + .subdevice = HDA_SUBDEV_AMP_FLAG, .info = snd_hda_mixer_amp_volume_info, .get = snd_hda_mixer_amp_volume_get, .put = snd_hda_mixer_amp_volume_put, diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 87bf7bd6292..cb7679551bd 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -2482,8 +2482,7 @@ static int alc_build_controls(struct hda_codec *codec) if (!kctl) return -ENOMEM; kctl->private_value = spec->beep_amp; - err = snd_hda_ctl_add(codec, - get_amp_nid_(spec->beep_amp), kctl); + err = snd_hda_ctl_add(codec, 0, kctl); if (err < 0) return err; } @@ -4414,9 +4413,7 @@ static int add_control(struct alc_spec *spec, int type, const char *name, if (!knew->name) return -ENOMEM; if (get_amp_nid_(val)) - knew->subdevice = HDA_SUBDEV_NID_FLAG | - HDA_SUBDEV_AMP_FLAG | - get_amp_nid_(val); + knew->subdevice = HDA_SUBDEV_AMP_FLAG; knew->private_value = val; return 0; } @@ -10921,7 +10918,7 @@ static struct snd_kcontrol_new alc262_fujitsu_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", - .subdevice = HDA_SUBDEV_NID_FLAG | HDA_SUBDEV_AMP_FLAG | 0x14, + .subdevice = HDA_SUBDEV_AMP_FLAG, .info = snd_hda_mixer_amp_switch_info, .get = snd_hda_mixer_amp_switch_get, .put = alc262_fujitsu_master_sw_put, @@ -10962,7 +10959,7 @@ static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", - .subdevice = HDA_SUBDEV_NID_FLAG | HDA_SUBDEV_AMP_FLAG | 0x1b, + .subdevice = HDA_SUBDEV_AMP_FLAG, .info = snd_hda_mixer_amp_switch_info, .get = snd_hda_mixer_amp_switch_get, .put = alc262_lenovo_3000_master_sw_put, @@ -12139,7 +12136,7 @@ static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", - .subdevice = HDA_SUBDEV_NID_FLAG | HDA_SUBDEV_AMP_FLAG | 0x14, + .subdevice = HDA_SUBDEV_AMP_FLAG, .info = snd_hda_mixer_amp_switch_info, .get = snd_hda_mixer_amp_switch_get, .put = alc268_acer_master_sw_put, @@ -12155,7 +12152,7 @@ static struct snd_kcontrol_new alc268_acer_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", - .subdevice = HDA_SUBDEV_NID_FLAG | HDA_SUBDEV_AMP_FLAG | 0x14, + .subdevice = HDA_SUBDEV_AMP_FLAG, .info = snd_hda_mixer_amp_switch_info, .get = snd_hda_mixer_amp_switch_get, .put = alc268_acer_master_sw_put, @@ -12173,7 +12170,7 @@ static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", - .subdevice = HDA_SUBDEV_NID_FLAG | HDA_SUBDEV_AMP_FLAG | 0x14, + .subdevice = HDA_SUBDEV_AMP_FLAG, .info = snd_hda_mixer_amp_switch_info, .get = snd_hda_mixer_amp_switch_get, .put = alc268_acer_master_sw_put, @@ -13126,7 +13123,7 @@ static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", - .subdevice = HDA_SUBDEV_NID_FLAG | HDA_SUBDEV_AMP_FLAG | 0x14, + .subdevice = HDA_SUBDEV_AMP_FLAG, .info = snd_hda_mixer_amp_switch_info, .get = snd_hda_mixer_amp_switch_get, .put = alc268_acer_master_sw_put, @@ -13147,7 +13144,7 @@ static struct snd_kcontrol_new alc269_lifebook_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", - .subdevice = HDA_SUBDEV_NID_FLAG | HDA_SUBDEV_AMP_FLAG | 0x14, + .subdevice = HDA_SUBDEV_AMP_FLAG, .info = snd_hda_mixer_amp_switch_info, .get = snd_hda_mixer_amp_switch_get, .put = alc268_acer_master_sw_put, diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 1ee586b65b6..0bafea9d510 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -2685,7 +2685,7 @@ static struct snd_kcontrol_new * stac_control_new(struct sigmatel_spec *spec, struct snd_kcontrol_new *ktemp, const char *name, - hda_nid_t nid) + unsigned int subdev) { struct snd_kcontrol_new *knew; @@ -2701,9 +2701,7 @@ stac_control_new(struct sigmatel_spec *spec, spec->kctls.alloced--; return NULL; } - if (nid) - knew->subdevice = HDA_SUBDEV_NID_FLAG | - HDA_SUBDEV_AMP_FLAG | nid; + knew->subdevice = subdev; return knew; } @@ -2713,7 +2711,7 @@ static int stac92xx_add_control_temp(struct sigmatel_spec *spec, unsigned long val) { struct snd_kcontrol_new *knew = stac_control_new(spec, ktemp, name, - get_amp_nid_(val)); + HDA_SUBDEV_AMP_FLAG); if (!knew) return -ENOMEM; knew->index = idx; diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index b94cdee5eb5..de4839e4676 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -458,9 +458,7 @@ static int via_add_control(struct via_spec *spec, int type, const char *name, if (!knew->name) return -ENOMEM; if (get_amp_nid_(val)) - knew->subdevice = HDA_SUBDEV_NID_FLAG | - HDA_SUBDEV_AMP_FLAG | - get_amp_nid_(val); + knew->subdevice = HDA_SUBDEV_AMP_FLAG; knew->private_value = val; return 0; } -- cgit v1.2.3-70-g09d2 From d1409ae4cecb4af260759bdfdf88fafca23a9940 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 17 Dec 2009 15:01:31 +0100 Subject: ALSA: hda - Fix NULL dereference in kctl-NID mapping in patch_realtek.c capsrc_nids can be NULL, and adc_nids should be taken as fallback. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'sound/pci/hda/patch_realtek.c') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 36556b10357..012435212e5 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -2517,7 +2517,10 @@ static int alc_build_controls(struct hda_codec *codec) if (!kctl) kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); for (i = 0; kctl && i < kctl->count; i++) { - err = snd_hda_add_nids(codec, kctl, i, spec->capsrc_nids, + hda_nid_t *nids = spec->capsrc_nids; + if (!nids) + nids = spec->adc_nids; + err = snd_hda_add_nids(codec, kctl, i, nids, spec->input_mux->num_items); if (err < 0) return err; -- cgit v1.2.3-70-g09d2 From 21949f00a022e090a7e8bc9a01dfca88273c6146 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 23 Dec 2009 08:31:59 +0100 Subject: ALSA: hda - Fix NID association for capture mixers Fix the wrong implementation of NID <-> kctl mapping for capture mixers introduced by the ocmmit 5b0cb1d850c26893b1468b3a519433a1b7a176be. So far, the driver returns an error at probe. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 26 -------------------------- sound/pci/hda/hda_local.h | 2 -- sound/pci/hda/patch_analog.c | 3 +-- sound/pci/hda/patch_cirrus.c | 12 ++++++++---- sound/pci/hda/patch_cmedia.c | 3 +-- sound/pci/hda/patch_realtek.c | 3 +-- sound/pci/hda/patch_via.c | 3 +-- 7 files changed, 12 insertions(+), 40 deletions(-) (limited to 'sound/pci/hda/patch_realtek.c') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index c848ec0f085..29c90d748c9 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -3537,32 +3537,6 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) } EXPORT_SYMBOL_HDA(snd_hda_add_new_ctls); -/** - * snd_hda_add_nids - assign nids to controls from the array - * @codec: the HDA codec - * @kctl: struct snd_kcontrol - * @index: index to kctl - * @nids: the array of hda_nid_t - * @size: count of hda_nid_t items - * - * This helper function assigns NIDs in the given array to a control element. - * - * Returns 0 if successful, or a negative error code. - */ -int snd_hda_add_nids(struct hda_codec *codec, struct snd_kcontrol *kctl, - unsigned int index, hda_nid_t *nids, unsigned int size) -{ - int err; - - for ( ; size > 0; size--, nids++) { - err = snd_hda_add_nid(codec, kctl, index, *nids); - if (err < 0) - return err; - } - return 0; -} -EXPORT_SYMBOL_HDA(snd_hda_add_nids); - #ifdef CONFIG_SND_HDA_POWER_SAVE static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, unsigned int power_state); diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index d505d052972..7cee364976f 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h @@ -343,8 +343,6 @@ int snd_hda_check_board_codec_sid_config(struct hda_codec *codec, const struct snd_pci_quirk *tbl); int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew); -int snd_hda_add_nids(struct hda_codec *codec, struct snd_kcontrol *kctl, - unsigned int index, hda_nid_t *nids, unsigned int size); /* * unsolicited event handler diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 92b72d4f398..45ee352df32 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -244,8 +244,7 @@ static int ad198x_build_controls(struct hda_codec *codec) if (!kctl) kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); for (i = 0; kctl && i < kctl->count; i++) { - err = snd_hda_add_nids(codec, kctl, i, spec->capsrc_nids, - spec->input_mux->num_items); + err = snd_hda_add_nid(codec, kctl, i, spec->capsrc_nids[i]); if (err < 0) return err; } diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index 093cfbb55e9..7de782a5b8f 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c @@ -753,6 +753,7 @@ static int build_input(struct hda_codec *codec) 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); @@ -762,10 +763,13 @@ static int build_input(struct hda_codec *codec) err = snd_hda_ctl_add(codec, 0, kctl); if (err < 0) return err; - err = snd_hda_add_nids(codec, kctl, 0, spec->adc_nid, - spec->num_inputs); - 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[i]); + if (err < 0) + return err; + } } if (spec->num_inputs > 1 && !spec->mic_detect) { diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c index cc1c22370a6..ff60908f455 100644 --- a/sound/pci/hda/patch_cmedia.c +++ b/sound/pci/hda/patch_cmedia.c @@ -345,8 +345,7 @@ static int cmi9880_build_controls(struct hda_codec *codec) /* assign Capture Source enums to NID */ kctl = snd_hda_find_mixer_ctl(codec, "Capture Source"); for (i = 0; kctl && i < kctl->count; i++) { - err = snd_hda_add_nids(codec, kctl, i, spec->adc_nids, - spec->input_mux->num_items); + err = snd_hda_add_nid(codec, kctl, i, spec->adc_nids[i]); if (err < 0) return err; } diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index e7cdc6a7d61..a4519901498 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -2551,8 +2551,7 @@ static int alc_build_controls(struct hda_codec *codec) hda_nid_t *nids = spec->capsrc_nids; if (!nids) nids = spec->adc_nids; - err = snd_hda_add_nids(codec, kctl, i, nids, - spec->input_mux->num_items); + err = snd_hda_add_nid(codec, kctl, i, nids[i]); if (err < 0) return err; } diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index de4839e4676..9ddc37300f6 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -1907,8 +1907,7 @@ static int via_build_controls(struct hda_codec *codec) /* assign Capture Source enums to NID */ kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); for (i = 0; kctl && i < kctl->count; i++) { - err = snd_hda_add_nids(codec, kctl, i, spec->mux_nids, - spec->input_mux->num_items); + err = snd_hda_add_nid(codec, kctl, i, spec->mux_nids[i]); if (err < 0) return err; } -- cgit v1.2.3-70-g09d2 From a4e09aa3cf592d9f084ff4ceb216be40c4c265dc Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sun, 27 Dec 2009 11:22:24 +0100 Subject: ALSA: hda - Fix click noises at suspend/free with Realtek codecs Call snd_hda_shutup_pins() at suspend and free for avoiding click noises. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'sound/pci/hda/patch_realtek.c') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 6361e6b3c9c..cd6d139b4fd 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -3693,6 +3693,11 @@ static int alc_build_pcms(struct hda_codec *codec) return 0; } +static inline void alc_shutup(struct hda_codec *codec) +{ + snd_hda_shutup_pins(codec); +} + static void alc_free_kctls(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; @@ -3713,6 +3718,7 @@ static void alc_free(struct hda_codec *codec) if (!spec) return; + alc_shutup(codec); alc_free_kctls(codec); kfree(spec); snd_hda_detach_beep_device(codec); @@ -3722,6 +3728,7 @@ static void alc_free(struct hda_codec *codec) static int alc_suspend(struct hda_codec *codec, pm_message_t state) { struct alc_spec *spec = codec->spec; + alc_shutup(codec); if (spec && spec->power_hook) spec->power_hook(codec, 0); return 0; -- cgit v1.2.3-70-g09d2 From c97259df3f2e163c72f4d0685c61fb2e026dc989 Mon Sep 17 00:00:00 2001 From: Daniel T Chen Date: Sun, 27 Dec 2009 18:52:08 -0500 Subject: ALSA: hda: Refactor powerdown for Realtek HDA codecs This patch converts the alc889 Aspire-specific powerdown to a generic one. Like the previous effort, it currently only handles Front and PCM but can be easily extended to cover other nids. The existing hook for alc889 Aspire-specific remains enabled. Upon further testing, I've added its use for ALC861_AUTO as well. Following patches will enable them for other quirks. Tested-by: Dr. David Alan Gilbert Signed-off-by: Daniel T Chen Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 60 +++++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 22 deletions(-) (limited to 'sound/pci/hda/patch_realtek.c') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index cd6d139b4fd..141ff446104 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -338,7 +338,7 @@ struct alc_spec { void (*init_hook)(struct hda_codec *codec); void (*unsol_event)(struct hda_codec *codec, unsigned int res); #ifdef CONFIG_SND_HDA_POWER_SAVE - void (*power_hook)(struct hda_codec *codec, int power); + void (*power_hook)(struct hda_codec *codec); #endif /* for pin sensing */ @@ -391,7 +391,7 @@ struct alc_config_preset { void (*init_hook)(struct hda_codec *); #ifdef CONFIG_SND_HDA_POWER_SAVE struct hda_amp_list *loopbacks; - void (*power_hook)(struct hda_codec *codec, int power); + void (*power_hook)(struct hda_codec *codec); #endif }; @@ -1835,16 +1835,6 @@ static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec) spec->autocfg.speaker_pins[2] = 0x1b; } -#ifdef CONFIG_SND_HDA_POWER_SAVE -static void alc889_power_eapd(struct hda_codec *codec, int power) -{ - snd_hda_codec_write(codec, 0x14, 0, - AC_VERB_SET_EAPD_BTLENABLE, power ? 2 : 0); - snd_hda_codec_write(codec, 0x15, 0, - AC_VERB_SET_EAPD_BTLENABLE, power ? 2 : 0); -} -#endif - /* * ALC880 3-stack model * @@ -3725,12 +3715,40 @@ static void alc_free(struct hda_codec *codec) } #ifdef CONFIG_SND_HDA_POWER_SAVE +static void alc_power_eapd(struct hda_codec *codec) +{ + /* We currently only handle front, HP */ + switch (codec->vendor_id) { + case 0x10ec0260: + snd_hda_codec_write(codec, 0x0f, 0, + AC_VERB_SET_EAPD_BTLENABLE, 0x00); + snd_hda_codec_write(codec, 0x10, 0, + AC_VERB_SET_EAPD_BTLENABLE, 0x00); + break; + case 0x10ec0262: + case 0x10ec0267: + case 0x10ec0268: + case 0x10ec0269: + case 0x10ec0272: + case 0x10ec0660: + case 0x10ec0662: + case 0x10ec0663: + case 0x10ec0862: + case 0x10ec0889: + snd_hda_codec_write(codec, 0x14, 0, + AC_VERB_SET_EAPD_BTLENABLE, 0x00); + snd_hda_codec_write(codec, 0x15, 0, + AC_VERB_SET_EAPD_BTLENABLE, 0x00); + break; + } +} + static int alc_suspend(struct hda_codec *codec, pm_message_t state) { struct alc_spec *spec = codec->spec; alc_shutup(codec); if (spec && spec->power_hook) - spec->power_hook(codec, 0); + spec->power_hook(codec); return 0; } #endif @@ -3738,16 +3756,9 @@ static int alc_suspend(struct hda_codec *codec, pm_message_t state) #ifdef SND_HDA_NEEDS_RESUME static int alc_resume(struct hda_codec *codec) { -#ifdef CONFIG_SND_HDA_POWER_SAVE - struct alc_spec *spec = codec->spec; -#endif codec->patch_ops.init(codec); snd_hda_codec_resume_amp(codec); snd_hda_codec_resume_cache(codec); -#ifdef CONFIG_SND_HDA_POWER_SAVE - if (spec && spec->power_hook) - spec->power_hook(codec, 1); -#endif return 0; } #endif @@ -3767,6 +3778,7 @@ static struct hda_codec_ops alc_patch_ops = { .suspend = alc_suspend, .check_power_status = alc_check_power_status, #endif + .reboot_notify = alc_shutup, }; @@ -9547,7 +9559,7 @@ static struct alc_config_preset alc882_presets[] = { .setup = alc889_acer_aspire_8930g_setup, .init_hook = alc_automute_amp, #ifdef CONFIG_SND_HDA_POWER_SAVE - .power_hook = alc889_power_eapd, + .power_hook = alc_power_eapd, #endif }, [ALC888_ACER_ASPIRE_7730G] = { @@ -14984,8 +14996,12 @@ static int patch_alc861(struct hda_codec *codec) spec->vmaster_nid = 0x03; codec->patch_ops = alc_patch_ops; - if (board_config == ALC861_AUTO) + if (board_config == ALC861_AUTO) { spec->init_hook = alc861_auto_init; +#ifdef CONFIG_SND_HDA_POWER_SAVE + spec->power_hook = alc_power_eapd; +#endif + } #ifdef CONFIG_SND_HDA_POWER_SAVE if (!spec->loopback.amplist) spec->loopback.amplist = alc861_loopbacks; -- cgit v1.2.3-70-g09d2