diff options
Diffstat (limited to 'sound/pci/hda/hda_codec.c')
-rw-r--r-- | sound/pci/hda/hda_codec.c | 57 |
1 files changed, 34 insertions, 23 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 644e3f14f8ca..98b6d02a36c9 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -1919,6 +1919,16 @@ struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec, | |||
1919 | } | 1919 | } |
1920 | EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl); | 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 | * snd_hda_ctl_add - Add a control element and assign to the codec | 1933 | * snd_hda_ctl_add - Add a control element and assign to the codec |
1924 | * @codec: HD-audio codec | 1934 | * @codec: HD-audio codec |
@@ -2654,8 +2664,6 @@ static struct snd_kcontrol_new dig_mixes[] = { | |||
2654 | { } /* end */ | 2664 | { } /* end */ |
2655 | }; | 2665 | }; |
2656 | 2666 | ||
2657 | #define SPDIF_MAX_IDX 4 /* 4 instances should be enough to probe */ | ||
2658 | |||
2659 | /** | 2667 | /** |
2660 | * snd_hda_create_spdif_out_ctls - create Output SPDIF-related controls | 2668 | * snd_hda_create_spdif_out_ctls - create Output SPDIF-related controls |
2661 | * @codec: the HDA codec | 2669 | * @codec: the HDA codec |
@@ -2673,12 +2681,8 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid) | |||
2673 | struct snd_kcontrol_new *dig_mix; | 2681 | struct snd_kcontrol_new *dig_mix; |
2674 | int idx; | 2682 | int idx; |
2675 | 2683 | ||
2676 | for (idx = 0; idx < SPDIF_MAX_IDX; idx++) { | 2684 | idx = find_empty_mixer_ctl_idx(codec, "IEC958 Playback Switch"); |
2677 | if (!_snd_hda_find_mixer_ctl(codec, "IEC958 Playback Switch", | 2685 | if (idx < 0) { |
2678 | idx)) | ||
2679 | break; | ||
2680 | } | ||
2681 | if (idx >= SPDIF_MAX_IDX) { | ||
2682 | printk(KERN_ERR "hda_codec: too many IEC958 outputs\n"); | 2686 | printk(KERN_ERR "hda_codec: too many IEC958 outputs\n"); |
2683 | return -EBUSY; | 2687 | return -EBUSY; |
2684 | } | 2688 | } |
@@ -2829,12 +2833,8 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid) | |||
2829 | struct snd_kcontrol_new *dig_mix; | 2833 | struct snd_kcontrol_new *dig_mix; |
2830 | int idx; | 2834 | int idx; |
2831 | 2835 | ||
2832 | for (idx = 0; idx < SPDIF_MAX_IDX; idx++) { | 2836 | idx = find_empty_mixer_ctl_idx(codec, "IEC958 Capture Switch"); |
2833 | if (!_snd_hda_find_mixer_ctl(codec, "IEC958 Capture Switch", | 2837 | if (idx < 0) { |
2834 | idx)) | ||
2835 | break; | ||
2836 | } | ||
2837 | if (idx >= SPDIF_MAX_IDX) { | ||
2838 | printk(KERN_ERR "hda_codec: too many IEC958 inputs\n"); | 2838 | printk(KERN_ERR "hda_codec: too many IEC958 inputs\n"); |
2839 | return -EBUSY; | 2839 | return -EBUSY; |
2840 | } | 2840 | } |
@@ -3808,21 +3808,32 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) | |||
3808 | 3808 | ||
3809 | for (; knew->name; knew++) { | 3809 | for (; knew->name; knew++) { |
3810 | struct snd_kcontrol *kctl; | 3810 | struct snd_kcontrol *kctl; |
3811 | int addr = 0, idx = 0; | ||
3811 | if (knew->iface == -1) /* skip this codec private value */ | 3812 | if (knew->iface == -1) /* skip this codec private value */ |
3812 | continue; | 3813 | continue; |
3813 | kctl = snd_ctl_new1(knew, codec); | 3814 | for (;;) { |
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; | ||
3820 | kctl = snd_ctl_new1(knew, codec); | 3815 | kctl = snd_ctl_new1(knew, codec); |
3821 | if (!kctl) | 3816 | if (!kctl) |
3822 | return -ENOMEM; | 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 | err = snd_hda_ctl_add(codec, 0, kctl); | 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 | return err; | 3837 | return err; |
3827 | } | 3838 | } |
3828 | } | 3839 | } |