aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-12-23 19:04:32 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2010-12-23 19:04:32 -0500
commit08861c713c1314d5b7329a290b5d53ad711112c3 (patch)
tree2571a28b8e1d1637273be8a7988d6ab72460af39 /sound
parente82bb314eab2e25a7657f34450665160a5a6cc2b (diff)
parent7693457547b729d9010a6014bbb8572b085f58d4 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6: ALSA: hda - Fix GPIO2-fixup for Sony laptops ALSA: hda - Try to find an empty control index when it's occupied ALSA: hda - Fix conflict of d-mic capture volume controls ALSA: hda - Don't apply ALC269-specific initialization to ALC275 ALSA: hda - Add fix-up for Sony VAIO with ALC275 codecs ALSA: pcm: remember to always call va_end() on stuff that we va_start() ALSA: HDA: Add auto-mute for Thinkpad SL410/SL510
Diffstat (limited to 'sound')
-rw-r--r--sound/core/pcm_lib.c10
-rw-r--r--sound/pci/hda/hda_codec.c57
-rw-r--r--sound/pci/hda/patch_realtek.c64
-rw-r--r--sound/pci/hda/patch_sigmatel.c5
4 files changed, 82 insertions, 54 deletions
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index b75db8e9cc0f..11446a1506da 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -1070,8 +1070,10 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond,
1070 struct snd_pcm_hw_rule *new; 1070 struct snd_pcm_hw_rule *new;
1071 unsigned int new_rules = constrs->rules_all + 16; 1071 unsigned int new_rules = constrs->rules_all + 16;
1072 new = kcalloc(new_rules, sizeof(*c), GFP_KERNEL); 1072 new = kcalloc(new_rules, sizeof(*c), GFP_KERNEL);
1073 if (!new) 1073 if (!new) {
1074 va_end(args);
1074 return -ENOMEM; 1075 return -ENOMEM;
1076 }
1075 if (constrs->rules) { 1077 if (constrs->rules) {
1076 memcpy(new, constrs->rules, 1078 memcpy(new, constrs->rules,
1077 constrs->rules_num * sizeof(*c)); 1079 constrs->rules_num * sizeof(*c));
@@ -1087,8 +1089,10 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond,
1087 c->private = private; 1089 c->private = private;
1088 k = 0; 1090 k = 0;
1089 while (1) { 1091 while (1) {
1090 if (snd_BUG_ON(k >= ARRAY_SIZE(c->deps))) 1092 if (snd_BUG_ON(k >= ARRAY_SIZE(c->deps))) {
1093 va_end(args);
1091 return -EINVAL; 1094 return -EINVAL;
1095 }
1092 c->deps[k++] = dep; 1096 c->deps[k++] = dep;
1093 if (dep < 0) 1097 if (dep < 0)
1094 break; 1098 break;
@@ -1097,7 +1101,7 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond,
1097 constrs->rules_num++; 1101 constrs->rules_num++;
1098 va_end(args); 1102 va_end(args);
1099 return 0; 1103 return 0;
1100} 1104}
1101 1105
1102EXPORT_SYMBOL(snd_pcm_hw_rule_add); 1106EXPORT_SYMBOL(snd_pcm_hw_rule_add);
1103 1107
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}
1920EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl); 1920EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl);
1921 1921
1922static 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 }
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 427da45d7906..552a09e9211f 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -14806,8 +14806,9 @@ static int alc269_resume(struct hda_codec *codec)
14806 14806
14807enum { 14807enum {
14808 ALC269_FIXUP_SONY_VAIO, 14808 ALC269_FIXUP_SONY_VAIO,
14809 ALC275_FIX_SONY_VAIO_GPIO2,
14809 ALC269_FIXUP_DELL_M101Z, 14810 ALC269_FIXUP_DELL_M101Z,
14810 ALC269_FIXUP_LENOVO_EDGE14, 14811 ALC269_FIXUP_SKU_IGNORE,
14811 ALC269_FIXUP_ASUS_G73JW, 14812 ALC269_FIXUP_ASUS_G73JW,
14812}; 14813};
14813 14814
@@ -14818,6 +14819,14 @@ static const struct alc_fixup alc269_fixups[] = {
14818 {} 14819 {}
14819 } 14820 }
14820 }, 14821 },
14822 [ALC275_FIX_SONY_VAIO_GPIO2] = {
14823 .verbs = (const struct hda_verb[]) {
14824 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14825 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14826 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14827 { }
14828 }
14829 },
14821 [ALC269_FIXUP_DELL_M101Z] = { 14830 [ALC269_FIXUP_DELL_M101Z] = {
14822 .verbs = (const struct hda_verb[]) { 14831 .verbs = (const struct hda_verb[]) {
14823 /* Enables internal speaker */ 14832 /* Enables internal speaker */
@@ -14826,7 +14835,7 @@ static const struct alc_fixup alc269_fixups[] = {
14826 {} 14835 {}
14827 } 14836 }
14828 }, 14837 },
14829 [ALC269_FIXUP_LENOVO_EDGE14] = { 14838 [ALC269_FIXUP_SKU_IGNORE] = {
14830 .sku = ALC_FIXUP_SKU_IGNORE, 14839 .sku = ALC_FIXUP_SKU_IGNORE,
14831 }, 14840 },
14832 [ALC269_FIXUP_ASUS_G73JW] = { 14841 [ALC269_FIXUP_ASUS_G73JW] = {
@@ -14838,9 +14847,13 @@ static const struct alc_fixup alc269_fixups[] = {
14838}; 14847};
14839 14848
14840static struct snd_pci_quirk alc269_fixup_tbl[] = { 14849static struct snd_pci_quirk alc269_fixup_tbl[] = {
14850 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIX_SONY_VAIO_GPIO2),
14851 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIX_SONY_VAIO_GPIO2),
14852 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIX_SONY_VAIO_GPIO2),
14841 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), 14853 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
14842 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), 14854 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
14843 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_LENOVO_EDGE14), 14855 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14856 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
14844 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), 14857 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
14845 {} 14858 {}
14846}; 14859};
@@ -15091,28 +15104,29 @@ static int patch_alc269(struct hda_codec *codec)
15091 15104
15092 alc_auto_parse_customize_define(codec); 15105 alc_auto_parse_customize_define(codec);
15093 15106
15094 coef = alc_read_coef_idx(codec, 0); 15107 if (codec->vendor_id == 0x10ec0269) {
15095 if ((coef & 0x00f0) == 0x0010) { 15108 coef = alc_read_coef_idx(codec, 0);
15096 if (codec->bus->pci->subsystem_vendor == 0x1025 && 15109 if ((coef & 0x00f0) == 0x0010) {
15097 spec->cdefine.platform_type == 1) { 15110 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
15098 alc_codec_rename(codec, "ALC271X"); 15111 spec->cdefine.platform_type == 1) {
15099 spec->codec_variant = ALC269_TYPE_ALC271X; 15112 alc_codec_rename(codec, "ALC271X");
15100 } else if ((coef & 0xf000) == 0x1000) { 15113 spec->codec_variant = ALC269_TYPE_ALC271X;
15101 spec->codec_variant = ALC269_TYPE_ALC270; 15114 } else if ((coef & 0xf000) == 0x1000) {
15102 } else if ((coef & 0xf000) == 0x2000) { 15115 spec->codec_variant = ALC269_TYPE_ALC270;
15103 alc_codec_rename(codec, "ALC259"); 15116 } else if ((coef & 0xf000) == 0x2000) {
15104 spec->codec_variant = ALC269_TYPE_ALC259; 15117 alc_codec_rename(codec, "ALC259");
15105 } else if ((coef & 0xf000) == 0x3000) { 15118 spec->codec_variant = ALC269_TYPE_ALC259;
15106 alc_codec_rename(codec, "ALC258"); 15119 } else if ((coef & 0xf000) == 0x3000) {
15107 spec->codec_variant = ALC269_TYPE_ALC258; 15120 alc_codec_rename(codec, "ALC258");
15108 } else { 15121 spec->codec_variant = ALC269_TYPE_ALC258;
15109 alc_codec_rename(codec, "ALC269VB"); 15122 } else {
15110 spec->codec_variant = ALC269_TYPE_ALC269VB; 15123 alc_codec_rename(codec, "ALC269VB");
15111 } 15124 spec->codec_variant = ALC269_TYPE_ALC269VB;
15112 } else 15125 }
15113 alc_fix_pll_init(codec, 0x20, 0x04, 15); 15126 } else
15114 15127 alc_fix_pll_init(codec, 0x20, 0x04, 15);
15115 alc269_fill_coef(codec); 15128 alc269_fill_coef(codec);
15129 }
15116 15130
15117 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, 15131 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
15118 alc269_models, 15132 alc269_models,
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index efa4225f5fd6..f03b2ff90496 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -3481,6 +3481,8 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
3481 3481
3482 label = hda_get_input_pin_label(codec, nid, 1); 3482 label = hda_get_input_pin_label(codec, nid, 1);
3483 snd_hda_add_imux_item(dimux, label, index, &type_idx); 3483 snd_hda_add_imux_item(dimux, label, index, &type_idx);
3484 if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1)
3485 snd_hda_add_imux_item(imux, label, index, &type_idx);
3484 3486
3485 err = create_elem_capture_vol(codec, nid, label, type_idx, 3487 err = create_elem_capture_vol(codec, nid, label, type_idx,
3486 HDA_INPUT); 3488 HDA_INPUT);
@@ -3492,9 +3494,6 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
3492 if (err < 0) 3494 if (err < 0)
3493 return err; 3495 return err;
3494 } 3496 }
3495
3496 if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1)
3497 snd_hda_add_imux_item(imux, label, index, NULL);
3498 } 3497 }
3499 3498
3500 return 0; 3499 return 0;