提交 e862f2e4 编写于 作者: L Linus Torvalds

Merge tag 'sound-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound

sound fixes #2 for 3.3-rc3

A collection of small fixes, mostly for regressions.
In addition, a few ASoC wm8994 updates are included, too.

* tag 'sound-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ASoC: wm8994: Disable line output discharge prior to ramping VMID
  ASoC: wm8994: Fix typo in VMID ramp setting
  ALSA: oxygen, virtuoso: fix exchanged L/R volumes of aux and CD inputs
  ALSA: usb-audio: add Edirol UM-3G support
  ALSA: hda - add support for Uniwill ECS M31EI notebook
  ALSA: hda - Fix error handling in patch_ca0132.c
  ASoC: wm8994: Enabling VMID should take a runtime PM reference
  ALSA: hda/realtek - Fix a wrong condition
  ALSA: emu8000: Remove duplicate linux/moduleparam.h include from emu8000_patch.c
  ALSA: hda/realtek - Add missing Bass and CLFE as vmaster slaves
  ASoC: wm_hubs: Correct line input to line output 2 paths
  ASoC: cs42l73: Fix Output [X|A|V]SP_SCLK Sourcing Mode setting for master mode
  ASoC: wm8962: Fix word length configuration
  ASoC: core: Better support for idle_bias_off suspend ignores
  ASoC: wm8994: Remove ASoC level register cache sync
  ASoC: wm_hubs: Fix routing of input PGAs to line output mixer
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#include "emu8000_local.h" #include "emu8000_local.h"
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/moduleparam.h>
static int emu8000_reset_addr; static int emu8000_reset_addr;
module_param(emu8000_reset_addr, int, 0444); module_param(emu8000_reset_addr, int, 0444);
......
...@@ -728,18 +728,19 @@ static int ca0132_hp_switch_put(struct snd_kcontrol *kcontrol, ...@@ -728,18 +728,19 @@ static int ca0132_hp_switch_put(struct snd_kcontrol *kcontrol,
err = chipio_read(codec, REG_CODEC_MUTE, &data); err = chipio_read(codec, REG_CODEC_MUTE, &data);
if (err < 0) if (err < 0)
return err; goto exit;
/* *valp 0 is mute, 1 is unmute */ /* *valp 0 is mute, 1 is unmute */
data = (data & 0x7f) | (*valp ? 0 : 0x80); data = (data & 0x7f) | (*valp ? 0 : 0x80);
chipio_write(codec, REG_CODEC_MUTE, data); err = chipio_write(codec, REG_CODEC_MUTE, data);
if (err < 0) if (err < 0)
return err; goto exit;
spec->curr_hp_switch = *valp; spec->curr_hp_switch = *valp;
exit:
snd_hda_power_down(codec); snd_hda_power_down(codec);
return 1; return err < 0 ? err : 1;
} }
static int ca0132_speaker_switch_get(struct snd_kcontrol *kcontrol, static int ca0132_speaker_switch_get(struct snd_kcontrol *kcontrol,
...@@ -770,18 +771,19 @@ static int ca0132_speaker_switch_put(struct snd_kcontrol *kcontrol, ...@@ -770,18 +771,19 @@ static int ca0132_speaker_switch_put(struct snd_kcontrol *kcontrol,
err = chipio_read(codec, REG_CODEC_MUTE, &data); err = chipio_read(codec, REG_CODEC_MUTE, &data);
if (err < 0) if (err < 0)
return err; goto exit;
/* *valp 0 is mute, 1 is unmute */ /* *valp 0 is mute, 1 is unmute */
data = (data & 0xef) | (*valp ? 0 : 0x10); data = (data & 0xef) | (*valp ? 0 : 0x10);
chipio_write(codec, REG_CODEC_MUTE, data); err = chipio_write(codec, REG_CODEC_MUTE, data);
if (err < 0) if (err < 0)
return err; goto exit;
spec->curr_speaker_switch = *valp; spec->curr_speaker_switch = *valp;
exit:
snd_hda_power_down(codec); snd_hda_power_down(codec);
return 1; return err < 0 ? err : 1;
} }
static int ca0132_hp_volume_get(struct snd_kcontrol *kcontrol, static int ca0132_hp_volume_get(struct snd_kcontrol *kcontrol,
...@@ -819,25 +821,26 @@ static int ca0132_hp_volume_put(struct snd_kcontrol *kcontrol, ...@@ -819,25 +821,26 @@ static int ca0132_hp_volume_put(struct snd_kcontrol *kcontrol,
err = chipio_read(codec, REG_CODEC_HP_VOL_L, &data); err = chipio_read(codec, REG_CODEC_HP_VOL_L, &data);
if (err < 0) if (err < 0)
return err; goto exit;
val = 31 - left_vol; val = 31 - left_vol;
data = (data & 0xe0) | val; data = (data & 0xe0) | val;
chipio_write(codec, REG_CODEC_HP_VOL_L, data); err = chipio_write(codec, REG_CODEC_HP_VOL_L, data);
if (err < 0) if (err < 0)
return err; goto exit;
val = 31 - right_vol; val = 31 - right_vol;
data = (data & 0xe0) | val; data = (data & 0xe0) | val;
chipio_write(codec, REG_CODEC_HP_VOL_R, data); err = chipio_write(codec, REG_CODEC_HP_VOL_R, data);
if (err < 0) if (err < 0)
return err; goto exit;
spec->curr_hp_volume[0] = left_vol; spec->curr_hp_volume[0] = left_vol;
spec->curr_hp_volume[1] = right_vol; spec->curr_hp_volume[1] = right_vol;
exit:
snd_hda_power_down(codec); snd_hda_power_down(codec);
return 1; return err < 0 ? err : 1;
} }
static int add_hp_switch(struct hda_codec *codec, hda_nid_t nid) static int add_hp_switch(struct hda_codec *codec, hda_nid_t nid)
...@@ -936,6 +939,8 @@ static int ca0132_build_controls(struct hda_codec *codec) ...@@ -936,6 +939,8 @@ static int ca0132_build_controls(struct hda_codec *codec)
if (err < 0) if (err < 0)
return err; return err;
err = add_in_volume(codec, spec->dig_in, "IEC958"); err = add_in_volume(codec, spec->dig_in, "IEC958");
if (err < 0)
return err;
} }
return 0; return 0;
} }
......
...@@ -1855,6 +1855,8 @@ static const char * const alc_slave_vols[] = { ...@@ -1855,6 +1855,8 @@ static const char * const alc_slave_vols[] = {
"Speaker Playback Volume", "Speaker Playback Volume",
"Mono Playback Volume", "Mono Playback Volume",
"Line-Out Playback Volume", "Line-Out Playback Volume",
"CLFE Playback Volume",
"Bass Speaker Playback Volume",
"PCM Playback Volume", "PCM Playback Volume",
NULL, NULL,
}; };
...@@ -1870,6 +1872,8 @@ static const char * const alc_slave_sws[] = { ...@@ -1870,6 +1872,8 @@ static const char * const alc_slave_sws[] = {
"Mono Playback Switch", "Mono Playback Switch",
"IEC958 Playback Switch", "IEC958 Playback Switch",
"Line-Out Playback Switch", "Line-Out Playback Switch",
"CLFE Playback Switch",
"Bass Speaker Playback Switch",
"PCM Playback Switch", "PCM Playback Switch",
NULL, NULL,
}; };
...@@ -2318,7 +2322,7 @@ static int alc_build_pcms(struct hda_codec *codec) ...@@ -2318,7 +2322,7 @@ static int alc_build_pcms(struct hda_codec *codec)
"%s Analog", codec->chip_name); "%s Analog", codec->chip_name);
info->name = spec->stream_name_analog; info->name = spec->stream_name_analog;
if (spec->multiout.dac_nids > 0) { if (spec->multiout.num_dacs > 0) {
p = spec->stream_analog_playback; p = spec->stream_analog_playback;
if (!p) if (!p)
p = &alc_pcm_analog_playback; p = &alc_pcm_analog_playback;
...@@ -5623,6 +5627,7 @@ static const struct alc_fixup alc861_fixups[] = { ...@@ -5623,6 +5627,7 @@ static const struct alc_fixup alc861_fixups[] = {
static const struct snd_pci_quirk alc861_fixup_tbl[] = { static const struct snd_pci_quirk alc861_fixup_tbl[] = {
SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", PINFIX_ASUS_A6RP), SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", PINFIX_ASUS_A6RP),
SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", PINFIX_ASUS_A6RP),
SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", PINFIX_ASUS_A6RP), SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", PINFIX_ASUS_A6RP),
SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505), SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
{} {}
......
...@@ -618,9 +618,12 @@ static int ac97_volume_get(struct snd_kcontrol *ctl, ...@@ -618,9 +618,12 @@ static int ac97_volume_get(struct snd_kcontrol *ctl,
mutex_lock(&chip->mutex); mutex_lock(&chip->mutex);
reg = oxygen_read_ac97(chip, codec, index); reg = oxygen_read_ac97(chip, codec, index);
mutex_unlock(&chip->mutex); mutex_unlock(&chip->mutex);
value->value.integer.value[0] = 31 - (reg & 0x1f); if (!stereo) {
if (stereo) value->value.integer.value[0] = 31 - (reg & 0x1f);
value->value.integer.value[1] = 31 - ((reg >> 8) & 0x1f); } else {
value->value.integer.value[0] = 31 - ((reg >> 8) & 0x1f);
value->value.integer.value[1] = 31 - (reg & 0x1f);
}
return 0; return 0;
} }
...@@ -636,14 +639,14 @@ static int ac97_volume_put(struct snd_kcontrol *ctl, ...@@ -636,14 +639,14 @@ static int ac97_volume_put(struct snd_kcontrol *ctl,
mutex_lock(&chip->mutex); mutex_lock(&chip->mutex);
oldreg = oxygen_read_ac97(chip, codec, index); oldreg = oxygen_read_ac97(chip, codec, index);
newreg = oldreg; if (!stereo) {
newreg = (newreg & ~0x1f) | newreg = oldreg & ~0x1f;
(31 - (value->value.integer.value[0] & 0x1f)); newreg |= 31 - (value->value.integer.value[0] & 0x1f);
if (stereo) } else {
newreg = (newreg & ~0x1f00) | newreg = oldreg & ~0x1f1f;
((31 - (value->value.integer.value[1] & 0x1f)) << 8); newreg |= (31 - (value->value.integer.value[0] & 0x1f)) << 8;
else newreg |= 31 - (value->value.integer.value[1] & 0x1f);
newreg = (newreg & ~0x1f00) | ((newreg & 0x1f) << 8); }
change = newreg != oldreg; change = newreg != oldreg;
if (change) if (change)
oxygen_write_ac97(chip, codec, index, newreg); oxygen_write_ac97(chip, codec, index, newreg);
......
...@@ -1113,7 +1113,7 @@ static int cs42l73_pcm_hw_params(struct snd_pcm_substream *substream, ...@@ -1113,7 +1113,7 @@ static int cs42l73_pcm_hw_params(struct snd_pcm_substream *substream,
priv->config[id].mmcc &= 0xC0; priv->config[id].mmcc &= 0xC0;
priv->config[id].mmcc |= cs42l73_mclk_coeffs[mclk_coeff].mmcc; priv->config[id].mmcc |= cs42l73_mclk_coeffs[mclk_coeff].mmcc;
priv->config[id].spc &= 0xFC; priv->config[id].spc &= 0xFC;
priv->config[id].spc &= MCK_SCLK_64FS; priv->config[id].spc |= MCK_SCLK_MCLK;
} else { } else {
/* CS42L73 Slave */ /* CS42L73 Slave */
priv->config[id].spc &= 0xFC; priv->config[id].spc &= 0xFC;
......
...@@ -3159,13 +3159,13 @@ static int wm8962_hw_params(struct snd_pcm_substream *substream, ...@@ -3159,13 +3159,13 @@ static int wm8962_hw_params(struct snd_pcm_substream *substream,
case SNDRV_PCM_FORMAT_S16_LE: case SNDRV_PCM_FORMAT_S16_LE:
break; break;
case SNDRV_PCM_FORMAT_S20_3LE: case SNDRV_PCM_FORMAT_S20_3LE:
aif0 |= 0x40; aif0 |= 0x4;
break; break;
case SNDRV_PCM_FORMAT_S24_LE: case SNDRV_PCM_FORMAT_S24_LE:
aif0 |= 0x80; aif0 |= 0x8;
break; break;
case SNDRV_PCM_FORMAT_S32_LE: case SNDRV_PCM_FORMAT_S32_LE:
aif0 |= 0xc0; aif0 |= 0xc;
break; break;
default: default:
return -EINVAL; return -EINVAL;
......
...@@ -770,6 +770,8 @@ static void vmid_reference(struct snd_soc_codec *codec) ...@@ -770,6 +770,8 @@ static void vmid_reference(struct snd_soc_codec *codec)
{ {
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
pm_runtime_get_sync(codec->dev);
wm8994->vmid_refcount++; wm8994->vmid_refcount++;
dev_dbg(codec->dev, "Referencing VMID, refcount is now %d\n", dev_dbg(codec->dev, "Referencing VMID, refcount is now %d\n",
...@@ -783,7 +785,12 @@ static void vmid_reference(struct snd_soc_codec *codec) ...@@ -783,7 +785,12 @@ static void vmid_reference(struct snd_soc_codec *codec)
WM8994_VMID_RAMP_MASK, WM8994_VMID_RAMP_MASK,
WM8994_STARTUP_BIAS_ENA | WM8994_STARTUP_BIAS_ENA |
WM8994_VMID_BUF_ENA | WM8994_VMID_BUF_ENA |
(0x11 << WM8994_VMID_RAMP_SHIFT)); (0x3 << WM8994_VMID_RAMP_SHIFT));
/* Remove discharge for line out */
snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
WM8994_LINEOUT1_DISCH |
WM8994_LINEOUT2_DISCH, 0);
/* Main bias enable, VMID=2x40k */ /* Main bias enable, VMID=2x40k */
snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
...@@ -837,6 +844,8 @@ static void vmid_dereference(struct snd_soc_codec *codec) ...@@ -837,6 +844,8 @@ static void vmid_dereference(struct snd_soc_codec *codec)
WM8994_VMID_BUF_ENA | WM8994_VMID_BUF_ENA |
WM8994_VMID_RAMP_MASK, 0); WM8994_VMID_RAMP_MASK, 0);
} }
pm_runtime_put(codec->dev);
} }
static int vmid_event(struct snd_soc_dapm_widget *w, static int vmid_event(struct snd_soc_dapm_widget *w,
...@@ -2753,11 +2762,6 @@ static int wm8994_resume(struct snd_soc_codec *codec) ...@@ -2753,11 +2762,6 @@ static int wm8994_resume(struct snd_soc_codec *codec)
codec->cache_only = 0; codec->cache_only = 0;
} }
/* Restore the registers */
ret = snd_soc_cache_sync(codec);
if (ret != 0)
dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY); wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) { for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
......
...@@ -586,8 +586,8 @@ SOC_DAPM_SINGLE("Left Output Switch", WM8993_LINE_MIXER1, 0, 1, 0), ...@@ -586,8 +586,8 @@ SOC_DAPM_SINGLE("Left Output Switch", WM8993_LINE_MIXER1, 0, 1, 0),
}; };
static const struct snd_kcontrol_new line2_mix[] = { static const struct snd_kcontrol_new line2_mix[] = {
SOC_DAPM_SINGLE("IN2R Switch", WM8993_LINE_MIXER2, 2, 1, 0), SOC_DAPM_SINGLE("IN1L Switch", WM8993_LINE_MIXER2, 2, 1, 0),
SOC_DAPM_SINGLE("IN2L Switch", WM8993_LINE_MIXER2, 1, 1, 0), SOC_DAPM_SINGLE("IN1R Switch", WM8993_LINE_MIXER2, 1, 1, 0),
SOC_DAPM_SINGLE("Output Switch", WM8993_LINE_MIXER2, 0, 1, 0), SOC_DAPM_SINGLE("Output Switch", WM8993_LINE_MIXER2, 0, 1, 0),
}; };
...@@ -848,8 +848,8 @@ static const struct snd_soc_dapm_route lineout1_se_routes[] = { ...@@ -848,8 +848,8 @@ static const struct snd_soc_dapm_route lineout1_se_routes[] = {
}; };
static const struct snd_soc_dapm_route lineout2_diff_routes[] = { static const struct snd_soc_dapm_route lineout2_diff_routes[] = {
{ "LINEOUT2 Mixer", "IN2L Switch", "IN2L PGA" }, { "LINEOUT2 Mixer", "IN1L Switch", "IN1L PGA" },
{ "LINEOUT2 Mixer", "IN2R Switch", "IN2R PGA" }, { "LINEOUT2 Mixer", "IN1R Switch", "IN1R PGA" },
{ "LINEOUT2 Mixer", "Output Switch", "Right Output PGA" }, { "LINEOUT2 Mixer", "Output Switch", "Right Output PGA" },
{ "LINEOUT2N Driver", NULL, "LINEOUT2 Mixer" }, { "LINEOUT2N Driver", NULL, "LINEOUT2 Mixer" },
......
...@@ -567,6 +567,17 @@ int snd_soc_suspend(struct device *dev) ...@@ -567,6 +567,17 @@ int snd_soc_suspend(struct device *dev)
if (!codec->suspended && codec->driver->suspend) { if (!codec->suspended && codec->driver->suspend) {
switch (codec->dapm.bias_level) { switch (codec->dapm.bias_level) {
case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_STANDBY:
/*
* If the CODEC is capable of idle
* bias off then being in STANDBY
* means it's doing something,
* otherwise fall through.
*/
if (codec->dapm.idle_bias_off) {
dev_dbg(codec->dev,
"idle_bias_off CODEC on over suspend\n");
break;
}
case SND_SOC_BIAS_OFF: case SND_SOC_BIAS_OFF:
codec->driver->suspend(codec); codec->driver->suspend(codec);
codec->suspended = 1; codec->suspended = 1;
......
...@@ -1617,6 +1617,14 @@ YAMAHA_DEVICE(0x7010, "UB99"), ...@@ -1617,6 +1617,14 @@ YAMAHA_DEVICE(0x7010, "UB99"),
} }
} }
}, },
{
/* Edirol UM-3G */
USB_DEVICE_VENDOR_SPEC(0x0582, 0x0108),
.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
.ifnum = 0,
.type = QUIRK_MIDI_STANDARD_INTERFACE
}
},
{ {
/* Boss JS-8 Jam Station */ /* Boss JS-8 Jam Station */
USB_DEVICE(0x0582, 0x0109), USB_DEVICE(0x0582, 0x0109),
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册