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