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>

+14 -8
+14 -8
sound/pci/hda/patch_realtek.c
··· 4996 */ 4997 4998 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid, 4999 - const char *pfx) 5000 { 5001 hda_nid_t nid_vol; 5002 unsigned long vol_val, sw_val; ··· 5018 } else 5019 return 0; /* N/A */ 5020 5021 - snprintf(name, sizeof(name), "%s Playback Volume", pfx); 5022 - err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val); 5023 - if (err < 0) 5024 - return err; 5025 snprintf(name, sizeof(name), "%s Playback Switch", pfx); 5026 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val); 5027 if (err < 0) ··· 5039 { 5040 hda_nid_t nid; 5041 int err; 5042 5043 spec->multiout.num_dacs = 1; 5044 spec->multiout.dac_nids = spec->private_dac_nids; ··· 5047 5048 nid = cfg->line_out_pins[0]; 5049 if (nid) { 5050 - err = alc260_add_playback_controls(spec, nid, "Front"); 5051 if (err < 0) 5052 return err; 5053 } 5054 5055 nid = cfg->speaker_pins[0]; 5056 if (nid) { 5057 - err = alc260_add_playback_controls(spec, nid, "Speaker"); 5058 if (err < 0) 5059 return err; 5060 } 5061 5062 nid = cfg->hp_pins[0]; 5063 if (nid) { 5064 - err = alc260_add_playback_controls(spec, nid, "Headphone"); 5065 if (err < 0) 5066 return err; 5067 }
··· 4996 */ 4997 4998 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid, 4999 + const char *pfx, int *vol_bits) 5000 { 5001 hda_nid_t nid_vol; 5002 unsigned long vol_val, sw_val; ··· 5018 } else 5019 return 0; /* N/A */ 5020 5021 + if (!(*vol_bits & (1 << nid_vol))) { 5022 + /* first control for the volume widget */ 5023 + snprintf(name, sizeof(name), "%s Playback Volume", pfx); 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 + } 5029 snprintf(name, sizeof(name), "%s Playback Switch", pfx); 5030 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val); 5031 if (err < 0) ··· 5035 { 5036 hda_nid_t nid; 5037 int err; 5038 + int vols = 0; 5039 5040 spec->multiout.num_dacs = 1; 5041 spec->multiout.dac_nids = spec->private_dac_nids; ··· 5042 5043 nid = cfg->line_out_pins[0]; 5044 if (nid) { 5045 + err = alc260_add_playback_controls(spec, nid, "Front", &vols); 5046 if (err < 0) 5047 return err; 5048 } 5049 5050 nid = cfg->speaker_pins[0]; 5051 if (nid) { 5052 + err = alc260_add_playback_controls(spec, nid, "Speaker", &vols); 5053 if (err < 0) 5054 return err; 5055 } 5056 5057 nid = cfg->hp_pins[0]; 5058 if (nid) { 5059 + err = alc260_add_playback_controls(spec, nid, "Headphone", 5060 + &vols); 5061 if (err < 0) 5062 return err; 5063 }