aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2008-10-21 11:01:47 -0400
committerTakashi Iwai <tiwai@suse.de>2008-10-21 11:01:47 -0400
commit863b45180ef541a1990e4986d30fb7a93022a733 (patch)
tree7929285c861f5e9ee635f5a2a0a53756c5a0951e
parentec4e86ba0662ed85f3b3a38fb220dc51d951da84 (diff)
ALSA: hda - Fix conflicting volume controls on ALC260
ALC260 auto-parsing mode may create multiple controls for the same volume widget (0x08 and 0x09) depending on the pin. For example, Front and Headphone volumes may control the same volume, just the latter one wins. This patch adds a proper check of the existing of the volume control and avoid the doulbed creation of the same volume controls. Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/pci/hda/patch_realtek.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index e72707cb60a3..ef4955c73c88 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -4996,7 +4996,7 @@ static struct hda_verb alc260_test_init_verbs[] = {
4996 */ 4996 */
4997 4997
4998static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid, 4998static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4999 const char *pfx) 4999 const char *pfx, int *vol_bits)
5000{ 5000{
5001 hda_nid_t nid_vol; 5001 hda_nid_t nid_vol;
5002 unsigned long vol_val, sw_val; 5002 unsigned long vol_val, sw_val;
@@ -5018,10 +5018,14 @@ static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
5018 } else 5018 } else
5019 return 0; /* N/A */ 5019 return 0; /* N/A */
5020 5020
5021 snprintf(name, sizeof(name), "%s Playback Volume", pfx); 5021 if (!(*vol_bits & (1 << nid_vol))) {
5022 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val); 5022 /* first control for the volume widget */
5023 if (err < 0) 5023 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
5024 return err; 5024 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
5025 if (err < 0)
5026 return err;
5027 *vol_bits |= (1 << nid_vol);
5028 }
5025 snprintf(name, sizeof(name), "%s Playback Switch", pfx); 5029 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
5026 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val); 5030 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
5027 if (err < 0) 5031 if (err < 0)
@@ -5035,6 +5039,7 @@ static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
5035{ 5039{
5036 hda_nid_t nid; 5040 hda_nid_t nid;
5037 int err; 5041 int err;
5042 int vols = 0;
5038 5043
5039 spec->multiout.num_dacs = 1; 5044 spec->multiout.num_dacs = 1;
5040 spec->multiout.dac_nids = spec->private_dac_nids; 5045 spec->multiout.dac_nids = spec->private_dac_nids;
@@ -5042,21 +5047,22 @@ static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
5042 5047
5043 nid = cfg->line_out_pins[0]; 5048 nid = cfg->line_out_pins[0];
5044 if (nid) { 5049 if (nid) {
5045 err = alc260_add_playback_controls(spec, nid, "Front"); 5050 err = alc260_add_playback_controls(spec, nid, "Front", &vols);
5046 if (err < 0) 5051 if (err < 0)
5047 return err; 5052 return err;
5048 } 5053 }
5049 5054
5050 nid = cfg->speaker_pins[0]; 5055 nid = cfg->speaker_pins[0];
5051 if (nid) { 5056 if (nid) {
5052 err = alc260_add_playback_controls(spec, nid, "Speaker"); 5057 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
5053 if (err < 0) 5058 if (err < 0)
5054 return err; 5059 return err;
5055 } 5060 }
5056 5061
5057 nid = cfg->hp_pins[0]; 5062 nid = cfg->hp_pins[0];
5058 if (nid) { 5063 if (nid) {
5059 err = alc260_add_playback_controls(spec, nid, "Headphone"); 5064 err = alc260_add_playback_controls(spec, nid, "Headphone",
5065 &vols);
5060 if (err < 0) 5066 if (err < 0)
5061 return err; 5067 return err;
5062 } 5068 }