ALSA: hda - Try to find an empty control index when it's occupied

When a mixer control element was already created with the given name,
try to find another index for avoiding conflicts, instead of breaking
with an error. This makes the driver more robust.

Signed-off-by: Takashi Iwai <tiwai@suse.de>

+34 -23
+34 -23
sound/pci/hda/hda_codec.c
··· 1919 1919 } 1920 1920 EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl); 1921 1921 1922 + static int find_empty_mixer_ctl_idx(struct hda_codec *codec, const char *name) 1923 + { 1924 + int idx; 1925 + for (idx = 0; idx < 16; idx++) { /* 16 ctlrs should be large enough */ 1926 + if (!_snd_hda_find_mixer_ctl(codec, name, idx)) 1927 + return idx; 1928 + } 1929 + return -EBUSY; 1930 + } 1931 + 1922 1932 /** 1923 1933 * snd_hda_ctl_add - Add a control element and assign to the codec 1924 1934 * @codec: HD-audio codec ··· 2664 2654 { } /* end */ 2665 2655 }; 2666 2656 2667 - #define SPDIF_MAX_IDX 4 /* 4 instances should be enough to probe */ 2668 - 2669 2657 /** 2670 2658 * snd_hda_create_spdif_out_ctls - create Output SPDIF-related controls 2671 2659 * @codec: the HDA codec ··· 2681 2673 struct snd_kcontrol_new *dig_mix; 2682 2674 int idx; 2683 2675 2684 - for (idx = 0; idx < SPDIF_MAX_IDX; idx++) { 2685 - if (!_snd_hda_find_mixer_ctl(codec, "IEC958 Playback Switch", 2686 - idx)) 2687 - break; 2688 - } 2689 - if (idx >= SPDIF_MAX_IDX) { 2676 + idx = find_empty_mixer_ctl_idx(codec, "IEC958 Playback Switch"); 2677 + if (idx < 0) { 2690 2678 printk(KERN_ERR "hda_codec: too many IEC958 outputs\n"); 2691 2679 return -EBUSY; 2692 2680 } ··· 2833 2829 struct snd_kcontrol_new *dig_mix; 2834 2830 int idx; 2835 2831 2836 - for (idx = 0; idx < SPDIF_MAX_IDX; idx++) { 2837 - if (!_snd_hda_find_mixer_ctl(codec, "IEC958 Capture Switch", 2838 - idx)) 2839 - break; 2840 - } 2841 - if (idx >= SPDIF_MAX_IDX) { 2832 + idx = find_empty_mixer_ctl_idx(codec, "IEC958 Capture Switch"); 2833 + if (idx < 0) { 2842 2834 printk(KERN_ERR "hda_codec: too many IEC958 inputs\n"); 2843 2835 return -EBUSY; 2844 2836 } ··· 3808 3808 3809 3809 for (; knew->name; knew++) { 3810 3810 struct snd_kcontrol *kctl; 3811 + int addr = 0, idx = 0; 3811 3812 if (knew->iface == -1) /* skip this codec private value */ 3812 3813 continue; 3813 - kctl = snd_ctl_new1(knew, codec); 3814 - if (!kctl) 3815 - return -ENOMEM; 3816 - err = snd_hda_ctl_add(codec, 0, kctl); 3817 - if (err < 0) { 3818 - if (!codec->addr) 3819 - return err; 3814 + for (;;) { 3820 3815 kctl = snd_ctl_new1(knew, codec); 3821 3816 if (!kctl) 3822 3817 return -ENOMEM; 3823 - kctl->id.device = codec->addr; 3818 + if (addr > 0) 3819 + kctl->id.device = addr; 3820 + if (idx > 0) 3821 + kctl->id.index = idx; 3824 3822 err = snd_hda_ctl_add(codec, 0, kctl); 3825 - if (err < 0) 3823 + if (!err) 3824 + break; 3825 + /* try first with another device index corresponding to 3826 + * the codec addr; if it still fails (or it's the 3827 + * primary codec), then try another control index 3828 + */ 3829 + if (!addr && codec->addr) 3830 + addr = codec->addr; 3831 + else if (!idx && !knew->index) { 3832 + idx = find_empty_mixer_ctl_idx(codec, 3833 + knew->name); 3834 + if (idx <= 0) 3835 + return err; 3836 + } else 3826 3837 return err; 3827 3838 } 3828 3839 }