summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2011-01-10 10:49:13 +0100
committerTakashi Iwai <tiwai@suse.de>2011-01-10 10:49:13 +0100
commit70c673a48072ff73425b82800479e66f918b8718 (patch)
treeb8a98710f97ff69c51fa5ba158f403059fd30632 /sound
parent10528020d7323778b60c2de04754a2615a88d002 (diff)
parente03fa055bc126e536c7f65862e08a9b143138ea9 (diff)
downloadlinux-70c673a48072ff73425b82800479e66f918b8718.tar.gz
linux-70c673a48072ff73425b82800479e66f918b8718.tar.xz
Merge branch 'fix/hda' into topic/hda
Diffstat (limited to 'sound')
-rw-r--r--sound/core/pcm_lib.c10
-rw-r--r--sound/oss/soundcard.c4
-rw-r--r--sound/pci/hda/hda_codec.c57
-rw-r--r--sound/pci/hda/hda_intel.c1
-rw-r--r--sound/pci/hda/patch_realtek.c57
-rw-r--r--sound/pci/hda/patch_sigmatel.c5
-rw-r--r--sound/soc/codecs/wm8580.c2
-rw-r--r--sound/soc/codecs/wm8904.c3
-rw-r--r--sound/soc/codecs/wm8955.c3
-rw-r--r--sound/soc/codecs/wm8960.c3
-rw-r--r--sound/soc/soc-dapm.c3
11 files changed, 91 insertions, 57 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,
struct snd_pcm_hw_rule *new;
unsigned int new_rules = constrs->rules_all + 16;
new = kcalloc(new_rules, sizeof(*c), GFP_KERNEL);
- if (!new)
+ if (!new) {
+ va_end(args);
return -ENOMEM;
+ }
if (constrs->rules) {
memcpy(new, constrs->rules,
constrs->rules_num * sizeof(*c));
@@ -1087,8 +1089,10 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond,
c->private = private;
k = 0;
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;
+ }
c->deps[k++] = dep;
if (dep < 0)
break;
@@ -1097,7 +1101,7 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond,
constrs->rules_num++;
va_end(args);
return 0;
-}
+}
EXPORT_SYMBOL(snd_pcm_hw_rule_add);
diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c
index 46c0d03dbecc..fcb14a099822 100644
--- a/sound/oss/soundcard.c
+++ b/sound/oss/soundcard.c
@@ -87,7 +87,7 @@ int *load_mixer_volumes(char *name, int *levels, int present)
int i, n;
for (i = 0; i < num_mixer_volumes; i++) {
- if (strcmp(name, mixer_vols[i].name) == 0) {
+ if (strncmp(name, mixer_vols[i].name, 32) == 0) {
if (present)
mixer_vols[i].num = i;
return mixer_vols[i].levels;
@@ -99,7 +99,7 @@ int *load_mixer_volumes(char *name, int *levels, int present)
}
n = num_mixer_volumes++;
- strcpy(mixer_vols[n].name, name);
+ strncpy(mixer_vols[n].name, name, 32);
if (present)
mixer_vols[n].num = n;
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,
}
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
* @codec: HD-audio codec
@@ -2654,8 +2664,6 @@ static struct snd_kcontrol_new dig_mixes[] = {
{ } /* end */
};
-#define SPDIF_MAX_IDX 4 /* 4 instances should be enough to probe */
-
/**
* snd_hda_create_spdif_out_ctls - create Output SPDIF-related controls
* @codec: the HDA codec
@@ -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;
int idx;
- for (idx = 0; idx < SPDIF_MAX_IDX; idx++) {
- if (!_snd_hda_find_mixer_ctl(codec, "IEC958 Playback Switch",
- idx))
- break;
- }
- if (idx >= SPDIF_MAX_IDX) {
+ idx = find_empty_mixer_ctl_idx(codec, "IEC958 Playback Switch");
+ if (idx < 0) {
printk(KERN_ERR "hda_codec: too many IEC958 outputs\n");
return -EBUSY;
}
@@ -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;
int idx;
- for (idx = 0; idx < SPDIF_MAX_IDX; idx++) {
- if (!_snd_hda_find_mixer_ctl(codec, "IEC958 Capture Switch",
- idx))
- break;
- }
- if (idx >= SPDIF_MAX_IDX) {
+ idx = find_empty_mixer_ctl_idx(codec, "IEC958 Capture Switch");
+ if (idx < 0) {
printk(KERN_ERR "hda_codec: too many IEC958 inputs\n");
return -EBUSY;
}
@@ -3808,21 +3808,32 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
for (; knew->name; knew++) {
struct snd_kcontrol *kctl;
+ int addr = 0, idx = 0;
if (knew->iface == -1) /* skip this codec private value */
continue;
- kctl = snd_ctl_new1(knew, codec);
- if (!kctl)
- return -ENOMEM;
- err = snd_hda_ctl_add(codec, 0, kctl);
- if (err < 0) {
- if (!codec->addr)
- return err;
+ for (;;) {
kctl = snd_ctl_new1(knew, codec);
if (!kctl)
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);
- 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;
}
}
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index b030c8eba21f..a1c4008af891 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -2300,6 +2300,7 @@ static struct snd_pci_quirk position_fix_list[] __devinitdata = {
SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB),
+ SND_PCI_QUIRK(0x1028, 0x0470, "Dell Inspiron 1120", POS_FIX_LPIB),
SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB),
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index cad88f476acc..f39efa440c0f 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -14795,6 +14795,7 @@ static int alc269_resume(struct hda_codec *codec)
enum {
ALC269_FIXUP_SONY_VAIO,
+ ALC275_FIX_SONY_VAIO_GPIO2,
ALC269_FIXUP_DELL_M101Z,
ALC269_FIXUP_SKU_IGNORE,
ALC269_FIXUP_ASUS_G73JW,
@@ -14807,6 +14808,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] = {
.verbs = (const struct hda_verb[]) {
/* Enables internal speaker */
@@ -14827,6 +14836,9 @@ static const struct alc_fixup alc269_fixups[] = {
};
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(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
@@ -15081,28 +15093,29 @@ static int patch_alc269(struct hda_codec *codec)
alc_auto_parse_customize_define(codec);
- coef = alc_read_coef_idx(codec, 0);
- if ((coef & 0x00f0) == 0x0010) {
- if (codec->bus->pci->subsystem_vendor == 0x1025 &&
- spec->cdefine.platform_type == 1) {
- alc_codec_rename(codec, "ALC271X");
- spec->codec_variant = ALC269_TYPE_ALC271X;
- } else if ((coef & 0xf000) == 0x1000) {
- spec->codec_variant = ALC269_TYPE_ALC270;
- } else if ((coef & 0xf000) == 0x2000) {
- alc_codec_rename(codec, "ALC259");
- spec->codec_variant = ALC269_TYPE_ALC259;
- } else if ((coef & 0xf000) == 0x3000) {
- alc_codec_rename(codec, "ALC258");
- spec->codec_variant = ALC269_TYPE_ALC258;
- } else {
- alc_codec_rename(codec, "ALC269VB");
- spec->codec_variant = ALC269_TYPE_ALC269VB;
- }
- } else
- alc_fix_pll_init(codec, 0x20, 0x04, 15);
-
- alc269_fill_coef(codec);
+ if (codec->vendor_id == 0x10ec0269) {
+ coef = alc_read_coef_idx(codec, 0);
+ if ((coef & 0x00f0) == 0x0010) {
+ if (codec->bus->pci->subsystem_vendor == 0x1025 &&
+ spec->cdefine.platform_type == 1) {
+ alc_codec_rename(codec, "ALC271X");
+ spec->codec_variant = ALC269_TYPE_ALC271X;
+ } else if ((coef & 0xf000) == 0x1000) {
+ spec->codec_variant = ALC269_TYPE_ALC270;
+ } else if ((coef & 0xf000) == 0x2000) {
+ alc_codec_rename(codec, "ALC259");
+ spec->codec_variant = ALC269_TYPE_ALC259;
+ } else if ((coef & 0xf000) == 0x3000) {
+ alc_codec_rename(codec, "ALC258");
+ spec->codec_variant = ALC269_TYPE_ALC258;
+ } else {
+ alc_codec_rename(codec, "ALC269VB");
+ spec->codec_variant = ALC269_TYPE_ALC269VB;
+ }
+ } else
+ alc_fix_pll_init(codec, 0x20, 0x04, 15);
+ alc269_fill_coef(codec);
+ }
board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
alc269_models,
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 8e2bb0aad0ae..6131a92f0898 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,
label = hda_get_input_pin_label(codec, nid, 1);
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,
HDA_INPUT);
@@ -3492,9 +3494,6 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
if (err < 0)
return err;
}
-
- if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1)
- snd_hda_add_imux_item(imux, label, index, NULL);
}
return 0;
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index 879dff2714dd..8725d4e75431 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -161,7 +161,7 @@
static const u16 wm8580_reg[] = {
0x0121, 0x017e, 0x007d, 0x0014, /*R3*/
0x0121, 0x017e, 0x007d, 0x0194, /*R7*/
- 0x001c, 0x0002, 0x0002, 0x00c2, /*R11*/
+ 0x0010, 0x0002, 0x0002, 0x00c2, /*R11*/
0x0182, 0x0082, 0x000a, 0x0024, /*R15*/
0x0009, 0x0000, 0x00ff, 0x0000, /*R19*/
0x00ff, 0x00ff, 0x00ff, 0x00ff, /*R23*/
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index fca60a0b57b8..9001cc48ba13 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -818,7 +818,8 @@ static int wm8904_get_deemph(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
- return wm8904->deemph;
+ ucontrol->value.enumerated.item[0] = wm8904->deemph;
+ return 0;
}
static int wm8904_put_deemph(struct snd_kcontrol *kcontrol,
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
index f89ad6c9a80b..9cbab8e1de01 100644
--- a/sound/soc/codecs/wm8955.c
+++ b/sound/soc/codecs/wm8955.c
@@ -380,7 +380,8 @@ static int wm8955_get_deemph(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
- return wm8955->deemph;
+ ucontrol->value.enumerated.item[0] = wm8955->deemph;
+ return 0;
}
static int wm8955_put_deemph(struct snd_kcontrol *kcontrol,
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index 8d5efb333c33..21986c42272f 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -138,7 +138,8 @@ static int wm8960_get_deemph(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
- return wm8960->deemph;
+ ucontrol->value.enumerated.item[0] = wm8960->deemph;
+ return 0;
}
static int wm8960_put_deemph(struct snd_kcontrol *kcontrol,
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 75ed6491222d..c721502833bc 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -944,6 +944,9 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
case SND_SOC_DAPM_STREAM_RESUME:
sys_power = 1;
break;
+ case SND_SOC_DAPM_STREAM_STOP:
+ sys_power = !!codec->active;
+ break;
case SND_SOC_DAPM_STREAM_SUSPEND:
sys_power = 0;
break;