Commit 08861c71 authored by Linus Torvalds's avatar Linus Torvalds

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
parents e82bb314 76934575
...@@ -1070,8 +1070,10 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond, ...@@ -1070,8 +1070,10 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond,
struct snd_pcm_hw_rule *new; struct snd_pcm_hw_rule *new;
unsigned int new_rules = constrs->rules_all + 16; unsigned int new_rules = constrs->rules_all + 16;
new = kcalloc(new_rules, sizeof(*c), GFP_KERNEL); new = kcalloc(new_rules, sizeof(*c), GFP_KERNEL);
if (!new) if (!new) {
va_end(args);
return -ENOMEM; return -ENOMEM;
}
if (constrs->rules) { if (constrs->rules) {
memcpy(new, constrs->rules, memcpy(new, constrs->rules,
constrs->rules_num * sizeof(*c)); constrs->rules_num * sizeof(*c));
...@@ -1087,8 +1089,10 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond, ...@@ -1087,8 +1089,10 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond,
c->private = private; c->private = private;
k = 0; k = 0;
while (1) { while (1) {
if (snd_BUG_ON(k >= ARRAY_SIZE(c->deps))) if (snd_BUG_ON(k >= ARRAY_SIZE(c->deps))) {
va_end(args);
return -EINVAL; return -EINVAL;
}
c->deps[k++] = dep; c->deps[k++] = dep;
if (dep < 0) if (dep < 0)
break; break;
...@@ -1097,7 +1101,7 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond, ...@@ -1097,7 +1101,7 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond,
constrs->rules_num++; constrs->rules_num++;
va_end(args); va_end(args);
return 0; return 0;
} }
EXPORT_SYMBOL(snd_pcm_hw_rule_add); EXPORT_SYMBOL(snd_pcm_hw_rule_add);
......
...@@ -1919,6 +1919,16 @@ struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec, ...@@ -1919,6 +1919,16 @@ struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
} }
EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl); EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl);
static int find_empty_mixer_ctl_idx(struct hda_codec *codec, const char *name)
{
int idx;
for (idx = 0; idx < 16; idx++) { /* 16 ctlrs should be large enough */
if (!_snd_hda_find_mixer_ctl(codec, name, idx))
return idx;
}
return -EBUSY;
}
/** /**
* snd_hda_ctl_add - Add a control element and assign to the codec * snd_hda_ctl_add - Add a control element and assign to the codec
* @codec: HD-audio codec * @codec: HD-audio codec
...@@ -2654,8 +2664,6 @@ static struct snd_kcontrol_new dig_mixes[] = { ...@@ -2654,8 +2664,6 @@ static struct snd_kcontrol_new dig_mixes[] = {
{ } /* end */ { } /* end */
}; };
#define SPDIF_MAX_IDX 4 /* 4 instances should be enough to probe */
/** /**
* snd_hda_create_spdif_out_ctls - create Output SPDIF-related controls * snd_hda_create_spdif_out_ctls - create Output SPDIF-related controls
* @codec: the HDA codec * @codec: the HDA codec
...@@ -2673,12 +2681,8 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid) ...@@ -2673,12 +2681,8 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid)
struct snd_kcontrol_new *dig_mix; struct snd_kcontrol_new *dig_mix;
int idx; int idx;
for (idx = 0; idx < SPDIF_MAX_IDX; idx++) { idx = find_empty_mixer_ctl_idx(codec, "IEC958 Playback Switch");
if (!_snd_hda_find_mixer_ctl(codec, "IEC958 Playback Switch", if (idx < 0) {
idx))
break;
}
if (idx >= SPDIF_MAX_IDX) {
printk(KERN_ERR "hda_codec: too many IEC958 outputs\n"); printk(KERN_ERR "hda_codec: too many IEC958 outputs\n");
return -EBUSY; return -EBUSY;
} }
...@@ -2829,12 +2833,8 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid) ...@@ -2829,12 +2833,8 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
struct snd_kcontrol_new *dig_mix; struct snd_kcontrol_new *dig_mix;
int idx; int idx;
for (idx = 0; idx < SPDIF_MAX_IDX; idx++) { idx = find_empty_mixer_ctl_idx(codec, "IEC958 Capture Switch");
if (!_snd_hda_find_mixer_ctl(codec, "IEC958 Capture Switch", if (idx < 0) {
idx))
break;
}
if (idx >= SPDIF_MAX_IDX) {
printk(KERN_ERR "hda_codec: too many IEC958 inputs\n"); printk(KERN_ERR "hda_codec: too many IEC958 inputs\n");
return -EBUSY; return -EBUSY;
} }
...@@ -3808,21 +3808,32 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) ...@@ -3808,21 +3808,32 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
for (; knew->name; knew++) { for (; knew->name; knew++) {
struct snd_kcontrol *kctl; struct snd_kcontrol *kctl;
int addr = 0, idx = 0;
if (knew->iface == -1) /* skip this codec private value */ if (knew->iface == -1) /* skip this codec private value */
continue; continue;
kctl = snd_ctl_new1(knew, codec); for (;;) {
if (!kctl)
return -ENOMEM;
err = snd_hda_ctl_add(codec, 0, kctl);
if (err < 0) {
if (!codec->addr)
return err;
kctl = snd_ctl_new1(knew, codec); kctl = snd_ctl_new1(knew, codec);
if (!kctl) if (!kctl)
return -ENOMEM; return -ENOMEM;
kctl->id.device = codec->addr; if (addr > 0)
kctl->id.device = addr;
if (idx > 0)
kctl->id.index = idx;
err = snd_hda_ctl_add(codec, 0, kctl); err = snd_hda_ctl_add(codec, 0, kctl);
if (err < 0) if (!err)
break;
/* try first with another device index corresponding to
* the codec addr; if it still fails (or it's the
* primary codec), then try another control index
*/
if (!addr && codec->addr)
addr = codec->addr;
else if (!idx && !knew->index) {
idx = find_empty_mixer_ctl_idx(codec,
knew->name);
if (idx <= 0)
return err;
} else
return err; return err;
} }
} }
......
...@@ -14806,8 +14806,9 @@ static int alc269_resume(struct hda_codec *codec) ...@@ -14806,8 +14806,9 @@ static int alc269_resume(struct hda_codec *codec)
enum { enum {
ALC269_FIXUP_SONY_VAIO, ALC269_FIXUP_SONY_VAIO,
ALC275_FIX_SONY_VAIO_GPIO2,
ALC269_FIXUP_DELL_M101Z, ALC269_FIXUP_DELL_M101Z,
ALC269_FIXUP_LENOVO_EDGE14, ALC269_FIXUP_SKU_IGNORE,
ALC269_FIXUP_ASUS_G73JW, ALC269_FIXUP_ASUS_G73JW,
}; };
...@@ -14818,6 +14819,14 @@ static const struct alc_fixup alc269_fixups[] = { ...@@ -14818,6 +14819,14 @@ static const struct alc_fixup alc269_fixups[] = {
{} {}
} }
}, },
[ALC275_FIX_SONY_VAIO_GPIO2] = {
.verbs = (const struct hda_verb[]) {
{0x01, AC_VERB_SET_GPIO_MASK, 0x04},
{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
{ }
}
},
[ALC269_FIXUP_DELL_M101Z] = { [ALC269_FIXUP_DELL_M101Z] = {
.verbs = (const struct hda_verb[]) { .verbs = (const struct hda_verb[]) {
/* Enables internal speaker */ /* Enables internal speaker */
...@@ -14826,7 +14835,7 @@ static const struct alc_fixup alc269_fixups[] = { ...@@ -14826,7 +14835,7 @@ static const struct alc_fixup alc269_fixups[] = {
{} {}
} }
}, },
[ALC269_FIXUP_LENOVO_EDGE14] = { [ALC269_FIXUP_SKU_IGNORE] = {
.sku = ALC_FIXUP_SKU_IGNORE, .sku = ALC_FIXUP_SKU_IGNORE,
}, },
[ALC269_FIXUP_ASUS_G73JW] = { [ALC269_FIXUP_ASUS_G73JW] = {
...@@ -14838,9 +14847,13 @@ static const struct alc_fixup alc269_fixups[] = { ...@@ -14838,9 +14847,13 @@ static const struct alc_fixup alc269_fixups[] = {
}; };
static struct snd_pci_quirk alc269_fixup_tbl[] = { static struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIX_SONY_VAIO_GPIO2),
SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIX_SONY_VAIO_GPIO2),
SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIX_SONY_VAIO_GPIO2),
SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_LENOVO_EDGE14), SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
{} {}
}; };
...@@ -15091,28 +15104,29 @@ static int patch_alc269(struct hda_codec *codec) ...@@ -15091,28 +15104,29 @@ static int patch_alc269(struct hda_codec *codec)
alc_auto_parse_customize_define(codec); alc_auto_parse_customize_define(codec);
coef = alc_read_coef_idx(codec, 0); if (codec->vendor_id == 0x10ec0269) {
if ((coef & 0x00f0) == 0x0010) { coef = alc_read_coef_idx(codec, 0);
if (codec->bus->pci->subsystem_vendor == 0x1025 && if ((coef & 0x00f0) == 0x0010) {
spec->cdefine.platform_type == 1) { if (codec->bus->pci->subsystem_vendor == 0x1025 &&
alc_codec_rename(codec, "ALC271X"); spec->cdefine.platform_type == 1) {
spec->codec_variant = ALC269_TYPE_ALC271X; alc_codec_rename(codec, "ALC271X");
} else if ((coef & 0xf000) == 0x1000) { spec->codec_variant = ALC269_TYPE_ALC271X;
spec->codec_variant = ALC269_TYPE_ALC270; } else if ((coef & 0xf000) == 0x1000) {
} else if ((coef & 0xf000) == 0x2000) { spec->codec_variant = ALC269_TYPE_ALC270;
alc_codec_rename(codec, "ALC259"); } else if ((coef & 0xf000) == 0x2000) {
spec->codec_variant = ALC269_TYPE_ALC259; alc_codec_rename(codec, "ALC259");
} else if ((coef & 0xf000) == 0x3000) { spec->codec_variant = ALC269_TYPE_ALC259;
alc_codec_rename(codec, "ALC258"); } else if ((coef & 0xf000) == 0x3000) {
spec->codec_variant = ALC269_TYPE_ALC258; alc_codec_rename(codec, "ALC258");
} else { spec->codec_variant = ALC269_TYPE_ALC258;
alc_codec_rename(codec, "ALC269VB"); } else {
spec->codec_variant = ALC269_TYPE_ALC269VB; alc_codec_rename(codec, "ALC269VB");
} spec->codec_variant = ALC269_TYPE_ALC269VB;
} else }
alc_fix_pll_init(codec, 0x20, 0x04, 15); } else
alc_fix_pll_init(codec, 0x20, 0x04, 15);
alc269_fill_coef(codec); alc269_fill_coef(codec);
}
board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
alc269_models, alc269_models,
......
...@@ -3481,6 +3481,8 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, ...@@ -3481,6 +3481,8 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
label = hda_get_input_pin_label(codec, nid, 1); label = hda_get_input_pin_label(codec, nid, 1);
snd_hda_add_imux_item(dimux, label, index, &type_idx); snd_hda_add_imux_item(dimux, label, index, &type_idx);
if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1)
snd_hda_add_imux_item(imux, label, index, &type_idx);
err = create_elem_capture_vol(codec, nid, label, type_idx, err = create_elem_capture_vol(codec, nid, label, type_idx,
HDA_INPUT); HDA_INPUT);
...@@ -3492,9 +3494,6 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, ...@@ -3492,9 +3494,6 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
if (err < 0) if (err < 0)
return err; return err;
} }
if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1)
snd_hda_add_imux_item(imux, label, index, NULL);
} }
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment