Commit 5e8063d7 authored by Linus Torvalds's avatar Linus Torvalds

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

sound fixes for 3.3-rc6 from Takashi Iwai

This contains again regression fixes for various HD-audio and ASoC
regarding SSI and dapm shutdown path.  In addition, a minor azt3328
fix and the correction of the new jack-notification strings in HD-audio.

* tag 'sound-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: hda - Kill hyphenated names
  ALSA: hda - Add a fake mute feature
  ALSA: hda - Always set HP pin in unsol handler for STAC/IDT codecs
  ALSA: azt3328 - Fix NULL ptr dereference on cards without OPL3
  ALSA: hda/realtek - Fix resume of multiple input sources
  ASoC: i.MX SSI: Fix DSP_A format.
  ASoC: dapm: Check for bias level when powering down
parents 200e9ef7 e49a3434
...@@ -2684,9 +2684,8 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) ...@@ -2684,9 +2684,8 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
err = snd_opl3_hwdep_new(opl3, 0, 1, NULL); err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
if (err < 0) if (err < 0)
goto out_err; goto out_err;
}
opl3->private_data = chip; opl3->private_data = chip;
}
sprintf(card->longname, "%s at 0x%lx, irq %i", sprintf(card->longname, "%s at 0x%lx, irq %i",
card->shortname, chip->ctrl_io, chip->irq); card->shortname, chip->ctrl_io, chip->irq);
......
...@@ -1759,6 +1759,10 @@ static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info, ...@@ -1759,6 +1759,10 @@ static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info,
parm = ch ? AC_AMP_SET_RIGHT : AC_AMP_SET_LEFT; parm = ch ? AC_AMP_SET_RIGHT : AC_AMP_SET_LEFT;
parm |= direction == HDA_OUTPUT ? AC_AMP_SET_OUTPUT : AC_AMP_SET_INPUT; parm |= direction == HDA_OUTPUT ? AC_AMP_SET_OUTPUT : AC_AMP_SET_INPUT;
parm |= index << AC_AMP_SET_INDEX_SHIFT; parm |= index << AC_AMP_SET_INDEX_SHIFT;
if ((val & HDA_AMP_MUTE) && !(info->amp_caps & AC_AMPCAP_MUTE) &&
(info->amp_caps & AC_AMPCAP_MIN_MUTE))
; /* set the zero value as a fake mute */
else
parm |= val; parm |= val;
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, parm); snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, parm);
info->vol[ch] = val; info->vol[ch] = val;
...@@ -2026,7 +2030,7 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, ...@@ -2026,7 +2030,7 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT); val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT);
val1 += ofs; val1 += ofs;
val1 = ((int)val1) * ((int)val2); val1 = ((int)val1) * ((int)val2);
if (min_mute) if (min_mute || (caps & AC_AMPCAP_MIN_MUTE))
val2 |= TLV_DB_SCALE_MUTE; val2 |= TLV_DB_SCALE_MUTE;
if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv)) if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv))
return -EFAULT; return -EFAULT;
...@@ -5114,7 +5118,7 @@ static int fill_audio_out_name(struct hda_codec *codec, hda_nid_t nid, ...@@ -5114,7 +5118,7 @@ static int fill_audio_out_name(struct hda_codec *codec, hda_nid_t nid,
const char *pfx = "", *sfx = ""; const char *pfx = "", *sfx = "";
/* handle as a speaker if it's a fixed line-out */ /* handle as a speaker if it's a fixed line-out */
if (!strcmp(name, "Line-Out") && attr == INPUT_PIN_ATTR_INT) if (!strcmp(name, "Line Out") && attr == INPUT_PIN_ATTR_INT)
name = "Speaker"; name = "Speaker";
/* check the location */ /* check the location */
switch (attr) { switch (attr) {
...@@ -5173,7 +5177,7 @@ int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid, ...@@ -5173,7 +5177,7 @@ int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid,
switch (get_defcfg_device(def_conf)) { switch (get_defcfg_device(def_conf)) {
case AC_JACK_LINE_OUT: case AC_JACK_LINE_OUT:
return fill_audio_out_name(codec, nid, cfg, "Line-Out", return fill_audio_out_name(codec, nid, cfg, "Line Out",
label, maxlen, indexp); label, maxlen, indexp);
case AC_JACK_SPEAKER: case AC_JACK_SPEAKER:
return fill_audio_out_name(codec, nid, cfg, "Speaker", return fill_audio_out_name(codec, nid, cfg, "Speaker",
......
...@@ -298,6 +298,9 @@ enum { ...@@ -298,6 +298,9 @@ enum {
#define AC_AMPCAP_MUTE (1<<31) /* mute capable */ #define AC_AMPCAP_MUTE (1<<31) /* mute capable */
#define AC_AMPCAP_MUTE_SHIFT 31 #define AC_AMPCAP_MUTE_SHIFT 31
/* driver-specific amp-caps: using bits 24-30 */
#define AC_AMPCAP_MIN_MUTE (1 << 30) /* min-volume = mute */
/* Connection list */ /* Connection list */
#define AC_CLIST_LENGTH (0x7f<<0) #define AC_CLIST_LENGTH (0x7f<<0)
#define AC_CLIST_LONG (1<<7) #define AC_CLIST_LONG (1<<7)
......
...@@ -609,7 +609,7 @@ static int add_output(struct hda_codec *codec, hda_nid_t dac, int idx, ...@@ -609,7 +609,7 @@ static int add_output(struct hda_codec *codec, hda_nid_t dac, int idx,
"Front Speaker", "Surround Speaker", "Bass Speaker" "Front Speaker", "Surround Speaker", "Bass Speaker"
}; };
static const char * const line_outs[] = { static const char * const line_outs[] = {
"Front Line-Out", "Surround Line-Out", "Bass Line-Out" "Front Line Out", "Surround Line Out", "Bass Line Out"
}; };
fix_volume_caps(codec, dac); fix_volume_caps(codec, dac);
...@@ -635,7 +635,7 @@ static int add_output(struct hda_codec *codec, hda_nid_t dac, int idx, ...@@ -635,7 +635,7 @@ static int add_output(struct hda_codec *codec, hda_nid_t dac, int idx,
if (num_ctls > 1) if (num_ctls > 1)
name = line_outs[idx]; name = line_outs[idx];
else else
name = "Line-Out"; name = "Line Out";
break; break;
} }
......
...@@ -3482,7 +3482,7 @@ static int cx_automute_mode_info(struct snd_kcontrol *kcontrol, ...@@ -3482,7 +3482,7 @@ static int cx_automute_mode_info(struct snd_kcontrol *kcontrol,
"Disabled", "Enabled" "Disabled", "Enabled"
}; };
static const char * const texts3[] = { static const char * const texts3[] = {
"Disabled", "Speaker Only", "Line-Out+Speaker" "Disabled", "Speaker Only", "Line Out+Speaker"
}; };
const char * const *texts; const char * const *texts;
...@@ -4079,7 +4079,8 @@ static int cx_auto_add_volume_idx(struct hda_codec *codec, const char *basename, ...@@ -4079,7 +4079,8 @@ static int cx_auto_add_volume_idx(struct hda_codec *codec, const char *basename,
err = snd_hda_ctl_add(codec, nid, kctl); err = snd_hda_ctl_add(codec, nid, kctl);
if (err < 0) if (err < 0)
return err; return err;
if (!(query_amp_caps(codec, nid, hda_dir) & AC_AMPCAP_MUTE)) if (!(query_amp_caps(codec, nid, hda_dir) &
(AC_AMPCAP_MUTE | AC_AMPCAP_MIN_MUTE)))
break; break;
} }
return 0; return 0;
...@@ -4379,6 +4380,22 @@ static const struct snd_pci_quirk cxt_fixups[] = { ...@@ -4379,6 +4380,22 @@ static const struct snd_pci_quirk cxt_fixups[] = {
{} {}
}; };
/* add "fake" mute amp-caps to DACs on cx5051 so that mixer mute switches
* can be created (bko#42825)
*/
static void add_cx5051_fake_mutes(struct hda_codec *codec)
{
static hda_nid_t out_nids[] = {
0x10, 0x11, 0
};
hda_nid_t *p;
for (p = out_nids; *p; p++)
snd_hda_override_amp_caps(codec, *p, HDA_OUTPUT,
AC_AMPCAP_MIN_MUTE |
query_amp_caps(codec, *p, HDA_OUTPUT));
}
static int patch_conexant_auto(struct hda_codec *codec) static int patch_conexant_auto(struct hda_codec *codec)
{ {
struct conexant_spec *spec; struct conexant_spec *spec;
...@@ -4397,6 +4414,9 @@ static int patch_conexant_auto(struct hda_codec *codec) ...@@ -4397,6 +4414,9 @@ static int patch_conexant_auto(struct hda_codec *codec)
case 0x14f15045: case 0x14f15045:
spec->single_adc_amp = 1; spec->single_adc_amp = 1;
break; break;
case 0x14f15051:
add_cx5051_fake_mutes(codec);
break;
} }
apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl); apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl);
......
...@@ -802,7 +802,7 @@ static int alc_automute_mode_info(struct snd_kcontrol *kcontrol, ...@@ -802,7 +802,7 @@ static int alc_automute_mode_info(struct snd_kcontrol *kcontrol,
"Disabled", "Enabled" "Disabled", "Enabled"
}; };
static const char * const texts3[] = { static const char * const texts3[] = {
"Disabled", "Speaker Only", "Line-Out+Speaker" "Disabled", "Speaker Only", "Line Out+Speaker"
}; };
const char * const *texts; const char * const *texts;
...@@ -1856,7 +1856,7 @@ static const char * const alc_slave_vols[] = { ...@@ -1856,7 +1856,7 @@ static const char * const alc_slave_vols[] = {
"Headphone Playback Volume", "Headphone Playback Volume",
"Speaker Playback Volume", "Speaker Playback Volume",
"Mono Playback Volume", "Mono Playback Volume",
"Line-Out Playback Volume", "Line Out Playback Volume",
"CLFE Playback Volume", "CLFE Playback Volume",
"Bass Speaker Playback Volume", "Bass Speaker Playback Volume",
"PCM Playback Volume", "PCM Playback Volume",
...@@ -1873,7 +1873,7 @@ static const char * const alc_slave_sws[] = { ...@@ -1873,7 +1873,7 @@ static const char * const alc_slave_sws[] = {
"Speaker Playback Switch", "Speaker Playback Switch",
"Mono Playback Switch", "Mono Playback Switch",
"IEC958 Playback Switch", "IEC958 Playback Switch",
"Line-Out Playback Switch", "Line Out Playback Switch",
"CLFE Playback Switch", "CLFE Playback Switch",
"Bass Speaker Playback Switch", "Bass Speaker Playback Switch",
"PCM Playback Switch", "PCM Playback Switch",
...@@ -3797,7 +3797,7 @@ static void alc_auto_init_input_src(struct hda_codec *codec) ...@@ -3797,7 +3797,7 @@ static void alc_auto_init_input_src(struct hda_codec *codec)
else else
nums = spec->num_adc_nids; nums = spec->num_adc_nids;
for (c = 0; c < nums; c++) for (c = 0; c < nums; c++)
alc_mux_select(codec, 0, spec->cur_mux[c], true); alc_mux_select(codec, c, spec->cur_mux[c], true);
} }
/* add mic boosts if needed */ /* add mic boosts if needed */
......
...@@ -4629,7 +4629,7 @@ static void stac92xx_hp_detect(struct hda_codec *codec) ...@@ -4629,7 +4629,7 @@ static void stac92xx_hp_detect(struct hda_codec *codec)
unsigned int val = AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN; unsigned int val = AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN;
if (no_hp_sensing(spec, i)) if (no_hp_sensing(spec, i))
continue; continue;
if (presence) if (1 /*presence*/)
stac92xx_set_pinctl(codec, cfg->hp_pins[i], val); stac92xx_set_pinctl(codec, cfg->hp_pins[i], val);
#if 0 /* FIXME */ #if 0 /* FIXME */
/* Resetting the pinctl like below may lead to (a sort of) regressions /* Resetting the pinctl like below may lead to (a sort of) regressions
......
...@@ -112,7 +112,7 @@ static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) ...@@ -112,7 +112,7 @@ static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
break; break;
case SND_SOC_DAIFMT_DSP_A: case SND_SOC_DAIFMT_DSP_A:
/* data on rising edge of bclk, frame high 1clk before data */ /* data on rising edge of bclk, frame high 1clk before data */
strcr |= SSI_STCR_TFSL | SSI_STCR_TEFS; strcr |= SSI_STCR_TFSL | SSI_STCR_TXBIT0 | SSI_STCR_TEFS;
break; break;
} }
......
...@@ -3068,9 +3068,13 @@ static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm) ...@@ -3068,9 +3068,13 @@ static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm)
* standby. * standby.
*/ */
if (powerdown) { if (powerdown) {
snd_soc_dapm_set_bias_level(dapm, SND_SOC_BIAS_PREPARE); if (dapm->bias_level == SND_SOC_BIAS_ON)
snd_soc_dapm_set_bias_level(dapm,
SND_SOC_BIAS_PREPARE);
dapm_seq_run(dapm, &down_list, 0, false); dapm_seq_run(dapm, &down_list, 0, false);
snd_soc_dapm_set_bias_level(dapm, SND_SOC_BIAS_STANDBY); if (dapm->bias_level == SND_SOC_BIAS_PREPARE)
snd_soc_dapm_set_bias_level(dapm,
SND_SOC_BIAS_STANDBY);
} }
} }
...@@ -3083,7 +3087,9 @@ void snd_soc_dapm_shutdown(struct snd_soc_card *card) ...@@ -3083,7 +3087,9 @@ void snd_soc_dapm_shutdown(struct snd_soc_card *card)
list_for_each_entry(codec, &card->codec_dev_list, list) { list_for_each_entry(codec, &card->codec_dev_list, list) {
soc_dapm_shutdown_codec(&codec->dapm); soc_dapm_shutdown_codec(&codec->dapm);
snd_soc_dapm_set_bias_level(&codec->dapm, SND_SOC_BIAS_OFF); if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY)
snd_soc_dapm_set_bias_level(&codec->dapm,
SND_SOC_BIAS_OFF);
} }
} }
......
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