Commit e9d99a1d authored by Linus Torvalds's avatar Linus Torvalds

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

Pull sound fixes from Takashi Iwai:
 "A bunch of ASoC fixes with a few HD-audio fixes in this pull request.

  All fairly small, boring and device-specific fixes, in addition to
  MAINTAINERS update for better reviewing"

* tag 'sound-3.17-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: hda/hdmi - apply Valleyview fix-ups to Cherryview display codec
  ALSA: hda/hdmi - set depop_delay for haswell plus
  ALSA: hda - restore the gpio led after resume
  ALSA: hda/realtek - Avoid setting wrong COEF on ALC269 & co
  ASoC: pxa-ssp: drop SNDRV_PCM_FMTBIT_S24_LE
  ASoC: fsl-esai: Revert .xlate_tdm_slot_mask() support
  ASoC: mcasp: Fix implicit BLCK divider setting
  ASoC: arizona: Fix TDM slot length handling in arizona_hw_params
  ASoC: pcm512x: Correct Digital Playback control names
  ASoC: dapm: Fix uninitialized variable in snd_soc_dapm_get_enum_double()
  ASoC: Intel: Restore Baytrail ADSP streams only when ADSP was in reset
  ASoC: Intel: Wait Baytrail ADSP boot at resume_early stage
  ASoC: Intel: Merge Baytrail ADSP suspend_noirq into suspend_late
  MAINTAINERS: Add i.MX maintainers and paths to Freescale ASoC entry
  ASoC: Intel: Update Baytrail ADSP firmware name
parents 29fdd5ba ca2e7224
...@@ -3843,10 +3843,13 @@ F: drivers/tty/serial/ucc_uart.c ...@@ -3843,10 +3843,13 @@ F: drivers/tty/serial/ucc_uart.c
FREESCALE SOC SOUND DRIVERS FREESCALE SOC SOUND DRIVERS
M: Timur Tabi <timur@tabi.org> M: Timur Tabi <timur@tabi.org>
M: Nicolin Chen <nicoleotsuka@gmail.com>
M: Xiubo Li <Li.Xiubo@freescale.com>
L: alsa-devel@alsa-project.org (moderated for non-subscribers) L: alsa-devel@alsa-project.org (moderated for non-subscribers)
L: linuxppc-dev@lists.ozlabs.org L: linuxppc-dev@lists.ozlabs.org
S: Maintained S: Maintained
F: sound/soc/fsl/fsl* F: sound/soc/fsl/fsl*
F: sound/soc/fsl/imx*
F: sound/soc/fsl/mpc8610_hpcd.c F: sound/soc/fsl/mpc8610_hpcd.c
FREEVXFS FILESYSTEM FREEVXFS FILESYSTEM
......
...@@ -50,6 +50,8 @@ MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info"); ...@@ -50,6 +50,8 @@ MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info");
#define is_haswell_plus(codec) (is_haswell(codec) || is_broadwell(codec)) #define is_haswell_plus(codec) (is_haswell(codec) || is_broadwell(codec))
#define is_valleyview(codec) ((codec)->vendor_id == 0x80862882) #define is_valleyview(codec) ((codec)->vendor_id == 0x80862882)
#define is_cherryview(codec) ((codec)->vendor_id == 0x80862883)
#define is_valleyview_plus(codec) (is_valleyview(codec) || is_cherryview(codec))
struct hdmi_spec_per_cvt { struct hdmi_spec_per_cvt {
hda_nid_t cvt_nid; hda_nid_t cvt_nid;
...@@ -1459,7 +1461,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, ...@@ -1459,7 +1461,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
mux_idx); mux_idx);
/* configure unused pins to choose other converters */ /* configure unused pins to choose other converters */
if (is_haswell_plus(codec) || is_valleyview(codec)) if (is_haswell_plus(codec) || is_valleyview_plus(codec))
intel_not_share_assigned_cvt(codec, per_pin->pin_nid, mux_idx); intel_not_share_assigned_cvt(codec, per_pin->pin_nid, mux_idx);
snd_hda_spdif_ctls_assign(codec, pin_idx, per_cvt->cvt_nid); snd_hda_spdif_ctls_assign(codec, pin_idx, per_cvt->cvt_nid);
...@@ -1598,7 +1600,8 @@ static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) ...@@ -1598,7 +1600,8 @@ static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
* and this can make HW reset converter selection on a pin. * and this can make HW reset converter selection on a pin.
*/ */
if (eld->eld_valid && !old_eld_valid && per_pin->setup) { if (eld->eld_valid && !old_eld_valid && per_pin->setup) {
if (is_haswell_plus(codec) || is_valleyview(codec)) { if (is_haswell_plus(codec) ||
is_valleyview_plus(codec)) {
intel_verify_pin_cvt_connect(codec, per_pin); intel_verify_pin_cvt_connect(codec, per_pin);
intel_not_share_assigned_cvt(codec, pin_nid, intel_not_share_assigned_cvt(codec, pin_nid,
per_pin->mux_idx); per_pin->mux_idx);
...@@ -1779,7 +1782,7 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, ...@@ -1779,7 +1782,7 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
bool non_pcm; bool non_pcm;
int pinctl; int pinctl;
if (is_haswell_plus(codec) || is_valleyview(codec)) { if (is_haswell_plus(codec) || is_valleyview_plus(codec)) {
/* Verify pin:cvt selections to avoid silent audio after S3. /* Verify pin:cvt selections to avoid silent audio after S3.
* After S3, the audio driver restores pin:cvt selections * After S3, the audio driver restores pin:cvt selections
* but this can happen before gfx is ready and such selection * but this can happen before gfx is ready and such selection
...@@ -2330,9 +2333,8 @@ static int patch_generic_hdmi(struct hda_codec *codec) ...@@ -2330,9 +2333,8 @@ static int patch_generic_hdmi(struct hda_codec *codec)
intel_haswell_fixup_enable_dp12(codec); intel_haswell_fixup_enable_dp12(codec);
} }
if (is_haswell(codec) || is_valleyview(codec)) { if (is_haswell_plus(codec) || is_valleyview_plus(codec))
codec->depop_delay = 0; codec->depop_delay = 0;
}
if (hdmi_parse_codec(codec) < 0) { if (hdmi_parse_codec(codec) < 0) {
codec->spec = NULL; codec->spec = NULL;
......
...@@ -181,6 +181,8 @@ static void alc_fix_pll(struct hda_codec *codec) ...@@ -181,6 +181,8 @@ static void alc_fix_pll(struct hda_codec *codec)
spec->pll_coef_idx); spec->pll_coef_idx);
val = snd_hda_codec_read(codec, spec->pll_nid, 0, val = snd_hda_codec_read(codec, spec->pll_nid, 0,
AC_VERB_GET_PROC_COEF, 0); AC_VERB_GET_PROC_COEF, 0);
if (val == -1)
return;
snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
spec->pll_coef_idx); spec->pll_coef_idx);
snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF, snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
...@@ -2806,6 +2808,8 @@ static void alc286_shutup(struct hda_codec *codec) ...@@ -2806,6 +2808,8 @@ static void alc286_shutup(struct hda_codec *codec)
static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up) static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up)
{ {
int val = alc_read_coef_idx(codec, 0x04); int val = alc_read_coef_idx(codec, 0x04);
if (val == -1)
return;
if (power_up) if (power_up)
val |= 1 << 11; val |= 1 << 11;
else else
...@@ -3264,6 +3268,15 @@ static int alc269_resume(struct hda_codec *codec) ...@@ -3264,6 +3268,15 @@ static int alc269_resume(struct hda_codec *codec)
snd_hda_codec_resume_cache(codec); snd_hda_codec_resume_cache(codec);
alc_inv_dmic_sync(codec, true); alc_inv_dmic_sync(codec, true);
hda_call_check_power_status(codec, 0x01); hda_call_check_power_status(codec, 0x01);
/* on some machine, the BIOS will clear the codec gpio data when enter
* suspend, and won't restore the data after resume, so we restore it
* in the driver.
*/
if (spec->gpio_led)
snd_hda_codec_write(codec, codec->afg, 0, AC_VERB_SET_GPIO_DATA,
spec->gpio_led);
if (spec->has_alc5505_dsp) if (spec->has_alc5505_dsp)
alc5505_dsp_resume(codec); alc5505_dsp_resume(codec);
...@@ -5311,27 +5324,30 @@ static void alc269_fill_coef(struct hda_codec *codec) ...@@ -5311,27 +5324,30 @@ static void alc269_fill_coef(struct hda_codec *codec)
if ((alc_get_coef0(codec) & 0x00ff) == 0x017) { if ((alc_get_coef0(codec) & 0x00ff) == 0x017) {
val = alc_read_coef_idx(codec, 0x04); val = alc_read_coef_idx(codec, 0x04);
/* Power up output pin */ /* Power up output pin */
alc_write_coef_idx(codec, 0x04, val | (1<<11)); if (val != -1)
alc_write_coef_idx(codec, 0x04, val | (1<<11));
} }
if ((alc_get_coef0(codec) & 0x00ff) == 0x018) { if ((alc_get_coef0(codec) & 0x00ff) == 0x018) {
val = alc_read_coef_idx(codec, 0xd); val = alc_read_coef_idx(codec, 0xd);
if ((val & 0x0c00) >> 10 != 0x1) { if (val != -1 && (val & 0x0c00) >> 10 != 0x1) {
/* Capless ramp up clock control */ /* Capless ramp up clock control */
alc_write_coef_idx(codec, 0xd, val | (1<<10)); alc_write_coef_idx(codec, 0xd, val | (1<<10));
} }
val = alc_read_coef_idx(codec, 0x17); val = alc_read_coef_idx(codec, 0x17);
if ((val & 0x01c0) >> 6 != 0x4) { if (val != -1 && (val & 0x01c0) >> 6 != 0x4) {
/* Class D power on reset */ /* Class D power on reset */
alc_write_coef_idx(codec, 0x17, val | (1<<7)); alc_write_coef_idx(codec, 0x17, val | (1<<7));
} }
} }
val = alc_read_coef_idx(codec, 0xd); /* Class D */ val = alc_read_coef_idx(codec, 0xd); /* Class D */
alc_write_coef_idx(codec, 0xd, val | (1<<14)); if (val != -1)
alc_write_coef_idx(codec, 0xd, val | (1<<14));
val = alc_read_coef_idx(codec, 0x4); /* HP */ val = alc_read_coef_idx(codec, 0x4); /* HP */
alc_write_coef_idx(codec, 0x4, val | (1<<11)); if (val != -1)
alc_write_coef_idx(codec, 0x4, val | (1<<11));
} }
/* /*
......
...@@ -1278,6 +1278,8 @@ static int arizona_hw_params(struct snd_pcm_substream *substream, ...@@ -1278,6 +1278,8 @@ static int arizona_hw_params(struct snd_pcm_substream *substream,
else else
rates = &arizona_48k_bclk_rates[0]; rates = &arizona_48k_bclk_rates[0];
wl = snd_pcm_format_width(params_format(params));
if (tdm_slots) { if (tdm_slots) {
arizona_aif_dbg(dai, "Configuring for %d %d bit TDM slots\n", arizona_aif_dbg(dai, "Configuring for %d %d bit TDM slots\n",
tdm_slots, tdm_width); tdm_slots, tdm_width);
...@@ -1285,6 +1287,7 @@ static int arizona_hw_params(struct snd_pcm_substream *substream, ...@@ -1285,6 +1287,7 @@ static int arizona_hw_params(struct snd_pcm_substream *substream,
channels = tdm_slots; channels = tdm_slots;
} else { } else {
bclk_target = snd_soc_params_to_bclk(params); bclk_target = snd_soc_params_to_bclk(params);
tdm_width = wl;
} }
if (chan_limit && chan_limit < channels) { if (chan_limit && chan_limit < channels) {
...@@ -1319,8 +1322,7 @@ static int arizona_hw_params(struct snd_pcm_substream *substream, ...@@ -1319,8 +1322,7 @@ static int arizona_hw_params(struct snd_pcm_substream *substream,
arizona_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n", arizona_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n",
rates[bclk], rates[bclk] / lrclk); rates[bclk], rates[bclk] / lrclk);
wl = snd_pcm_format_width(params_format(params)); frame = wl << ARIZONA_AIF1TX_WL_SHIFT | tdm_width;
frame = wl << ARIZONA_AIF1TX_WL_SHIFT | wl;
reconfig = arizona_aif_cfg_changed(codec, base, bclk, lrclk, frame); reconfig = arizona_aif_cfg_changed(codec, base, bclk, lrclk, frame);
......
...@@ -259,13 +259,13 @@ static const struct soc_enum pcm512x_veds = ...@@ -259,13 +259,13 @@ static const struct soc_enum pcm512x_veds =
pcm512x_ramp_step_text); pcm512x_ramp_step_text);
static const struct snd_kcontrol_new pcm512x_controls[] = { static const struct snd_kcontrol_new pcm512x_controls[] = {
SOC_DOUBLE_R_TLV("Playback Digital Volume", PCM512x_DIGITAL_VOLUME_2, SOC_DOUBLE_R_TLV("Digital Playback Volume", PCM512x_DIGITAL_VOLUME_2,
PCM512x_DIGITAL_VOLUME_3, 0, 255, 1, digital_tlv), PCM512x_DIGITAL_VOLUME_3, 0, 255, 1, digital_tlv),
SOC_DOUBLE_TLV("Playback Volume", PCM512x_ANALOG_GAIN_CTRL, SOC_DOUBLE_TLV("Playback Volume", PCM512x_ANALOG_GAIN_CTRL,
PCM512x_LAGN_SHIFT, PCM512x_RAGN_SHIFT, 1, 1, analog_tlv), PCM512x_LAGN_SHIFT, PCM512x_RAGN_SHIFT, 1, 1, analog_tlv),
SOC_DOUBLE_TLV("Playback Boost Volume", PCM512x_ANALOG_GAIN_BOOST, SOC_DOUBLE_TLV("Playback Boost Volume", PCM512x_ANALOG_GAIN_BOOST,
PCM512x_AGBL_SHIFT, PCM512x_AGBR_SHIFT, 1, 0, boost_tlv), PCM512x_AGBL_SHIFT, PCM512x_AGBR_SHIFT, 1, 0, boost_tlv),
SOC_DOUBLE("Playback Digital Switch", PCM512x_MUTE, PCM512x_RQML_SHIFT, SOC_DOUBLE("Digital Playback Switch", PCM512x_MUTE, PCM512x_RQML_SHIFT,
PCM512x_RQMR_SHIFT, 1, 1), PCM512x_RQMR_SHIFT, 1, 1),
SOC_SINGLE("Deemphasis Switch", PCM512x_DSP, PCM512x_DEMP_SHIFT, 1, 1), SOC_SINGLE("Deemphasis Switch", PCM512x_DSP, PCM512x_DEMP_SHIFT, 1, 1),
......
...@@ -403,7 +403,8 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, ...@@ -403,7 +403,8 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
return ret; return ret;
} }
static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div) static int __davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id,
int div, bool explicit)
{ {
struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
...@@ -420,7 +421,8 @@ static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div ...@@ -420,7 +421,8 @@ static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div
ACLKXDIV(div - 1), ACLKXDIV_MASK); ACLKXDIV(div - 1), ACLKXDIV_MASK);
mcasp_mod_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, mcasp_mod_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG,
ACLKRDIV(div - 1), ACLKRDIV_MASK); ACLKRDIV(div - 1), ACLKRDIV_MASK);
mcasp->bclk_div = div; if (explicit)
mcasp->bclk_div = div;
break; break;
case 2: /* BCLK/LRCLK ratio */ case 2: /* BCLK/LRCLK ratio */
...@@ -434,6 +436,12 @@ static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div ...@@ -434,6 +436,12 @@ static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div
return 0; return 0;
} }
static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id,
int div)
{
return __davinci_mcasp_set_clkdiv(dai, div_id, div, 1);
}
static int davinci_mcasp_set_sysclk(struct snd_soc_dai *dai, int clk_id, static int davinci_mcasp_set_sysclk(struct snd_soc_dai *dai, int clk_id,
unsigned int freq, int dir) unsigned int freq, int dir)
{ {
...@@ -738,7 +746,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, ...@@ -738,7 +746,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
"Inaccurate BCLK: %u Hz / %u != %u Hz\n", "Inaccurate BCLK: %u Hz / %u != %u Hz\n",
mcasp->sysclk_freq, div, bclk_freq); mcasp->sysclk_freq, div, bclk_freq);
} }
davinci_mcasp_set_clkdiv(cpu_dai, 1, div); __davinci_mcasp_set_clkdiv(cpu_dai, 1, div, 0);
} }
ret = mcasp_common_hw_param(mcasp, substream->stream, ret = mcasp_common_hw_param(mcasp, substream->stream,
......
...@@ -49,7 +49,6 @@ config SND_SOC_FSL_ESAI ...@@ -49,7 +49,6 @@ config SND_SOC_FSL_ESAI
tristate "Enhanced Serial Audio Interface (ESAI) module support" tristate "Enhanced Serial Audio Interface (ESAI) module support"
select REGMAP_MMIO select REGMAP_MMIO
select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n
select SND_SOC_FSL_UTILS
help help
Say Y if you want to add Enhanced Synchronous Audio Interface Say Y if you want to add Enhanced Synchronous Audio Interface
(ESAI) support for the Freescale CPUs. (ESAI) support for the Freescale CPUs.
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
#include "fsl_esai.h" #include "fsl_esai.h"
#include "imx-pcm.h" #include "imx-pcm.h"
#include "fsl_utils.h"
#define FSL_ESAI_RATES SNDRV_PCM_RATE_8000_192000 #define FSL_ESAI_RATES SNDRV_PCM_RATE_8000_192000
#define FSL_ESAI_FORMATS (SNDRV_PCM_FMTBIT_S8 | \ #define FSL_ESAI_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
...@@ -607,7 +606,6 @@ static struct snd_soc_dai_ops fsl_esai_dai_ops = { ...@@ -607,7 +606,6 @@ static struct snd_soc_dai_ops fsl_esai_dai_ops = {
.hw_params = fsl_esai_hw_params, .hw_params = fsl_esai_hw_params,
.set_sysclk = fsl_esai_set_dai_sysclk, .set_sysclk = fsl_esai_set_dai_sysclk,
.set_fmt = fsl_esai_set_dai_fmt, .set_fmt = fsl_esai_set_dai_fmt,
.xlate_tdm_slot_mask = fsl_asoc_xlate_tdm_slot_mask,
.set_tdm_slot = fsl_esai_set_dai_tdm_slot, .set_tdm_slot = fsl_esai_set_dai_tdm_slot,
}; };
......
...@@ -246,8 +246,8 @@ static struct sst_acpi_desc sst_acpi_broadwell_desc = { ...@@ -246,8 +246,8 @@ static struct sst_acpi_desc sst_acpi_broadwell_desc = {
}; };
static struct sst_acpi_mach baytrail_machines[] = { static struct sst_acpi_mach baytrail_machines[] = {
{ "10EC5640", "byt-rt5640", "intel/fw_sst_0f28.bin-i2s_master" }, { "10EC5640", "byt-rt5640", "intel/fw_sst_0f28.bin-48kHz_i2s_master" },
{ "193C9890", "byt-max98090", "intel/fw_sst_0f28.bin-i2s_master" }, { "193C9890", "byt-max98090", "intel/fw_sst_0f28.bin-48kHz_i2s_master" },
{} {}
}; };
......
...@@ -817,7 +817,7 @@ static struct sst_dsp_device byt_dev = { ...@@ -817,7 +817,7 @@ static struct sst_dsp_device byt_dev = {
.ops = &sst_byt_ops, .ops = &sst_byt_ops,
}; };
int sst_byt_dsp_suspend_noirq(struct device *dev, struct sst_pdata *pdata) int sst_byt_dsp_suspend_late(struct device *dev, struct sst_pdata *pdata)
{ {
struct sst_byt *byt = pdata->dsp; struct sst_byt *byt = pdata->dsp;
...@@ -826,14 +826,6 @@ int sst_byt_dsp_suspend_noirq(struct device *dev, struct sst_pdata *pdata) ...@@ -826,14 +826,6 @@ int sst_byt_dsp_suspend_noirq(struct device *dev, struct sst_pdata *pdata)
sst_byt_drop_all(byt); sst_byt_drop_all(byt);
dev_dbg(byt->dev, "dsp in reset\n"); dev_dbg(byt->dev, "dsp in reset\n");
return 0;
}
EXPORT_SYMBOL_GPL(sst_byt_dsp_suspend_noirq);
int sst_byt_dsp_suspend_late(struct device *dev, struct sst_pdata *pdata)
{
struct sst_byt *byt = pdata->dsp;
dev_dbg(byt->dev, "free all blocks and unload fw\n"); dev_dbg(byt->dev, "free all blocks and unload fw\n");
sst_fw_unload(byt->fw); sst_fw_unload(byt->fw);
......
...@@ -66,7 +66,6 @@ int sst_byt_get_dsp_position(struct sst_byt *byt, ...@@ -66,7 +66,6 @@ int sst_byt_get_dsp_position(struct sst_byt *byt,
int sst_byt_dsp_init(struct device *dev, struct sst_pdata *pdata); int sst_byt_dsp_init(struct device *dev, struct sst_pdata *pdata);
void sst_byt_dsp_free(struct device *dev, struct sst_pdata *pdata); void sst_byt_dsp_free(struct device *dev, struct sst_pdata *pdata);
struct sst_dsp *sst_byt_get_dsp(struct sst_byt *byt); struct sst_dsp *sst_byt_get_dsp(struct sst_byt *byt);
int sst_byt_dsp_suspend_noirq(struct device *dev, struct sst_pdata *pdata);
int sst_byt_dsp_suspend_late(struct device *dev, struct sst_pdata *pdata); int sst_byt_dsp_suspend_late(struct device *dev, struct sst_pdata *pdata);
int sst_byt_dsp_boot(struct device *dev, struct sst_pdata *pdata); int sst_byt_dsp_boot(struct device *dev, struct sst_pdata *pdata);
int sst_byt_dsp_wait_for_ready(struct device *dev, struct sst_pdata *pdata); int sst_byt_dsp_wait_for_ready(struct device *dev, struct sst_pdata *pdata);
......
...@@ -59,6 +59,9 @@ struct sst_byt_priv_data { ...@@ -59,6 +59,9 @@ struct sst_byt_priv_data {
/* DAI data */ /* DAI data */
struct sst_byt_pcm_data pcm[BYT_PCM_COUNT]; struct sst_byt_pcm_data pcm[BYT_PCM_COUNT];
/* flag indicating is stream context restore needed after suspend */
bool restore_stream;
}; };
/* this may get called several times by oss emulation */ /* this may get called several times by oss emulation */
...@@ -184,7 +187,10 @@ static int sst_byt_pcm_trigger(struct snd_pcm_substream *substream, int cmd) ...@@ -184,7 +187,10 @@ static int sst_byt_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
sst_byt_stream_start(byt, pcm_data->stream, 0); sst_byt_stream_start(byt, pcm_data->stream, 0);
break; break;
case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_RESUME:
schedule_work(&pcm_data->work); if (pdata->restore_stream == true)
schedule_work(&pcm_data->work);
else
sst_byt_stream_resume(byt, pcm_data->stream);
break; break;
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
sst_byt_stream_resume(byt, pcm_data->stream); sst_byt_stream_resume(byt, pcm_data->stream);
...@@ -193,6 +199,7 @@ static int sst_byt_pcm_trigger(struct snd_pcm_substream *substream, int cmd) ...@@ -193,6 +199,7 @@ static int sst_byt_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
sst_byt_stream_stop(byt, pcm_data->stream); sst_byt_stream_stop(byt, pcm_data->stream);
break; break;
case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_SUSPEND:
pdata->restore_stream = false;
case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
sst_byt_stream_pause(byt, pcm_data->stream); sst_byt_stream_pause(byt, pcm_data->stream);
break; break;
...@@ -404,26 +411,10 @@ static const struct snd_soc_component_driver byt_dai_component = { ...@@ -404,26 +411,10 @@ static const struct snd_soc_component_driver byt_dai_component = {
}; };
#ifdef CONFIG_PM #ifdef CONFIG_PM
static int sst_byt_pcm_dev_suspend_noirq(struct device *dev)
{
struct sst_pdata *sst_pdata = dev_get_platdata(dev);
int ret;
dev_dbg(dev, "suspending noirq\n");
/* at this point all streams will be stopped and context saved */
ret = sst_byt_dsp_suspend_noirq(dev, sst_pdata);
if (ret < 0) {
dev_err(dev, "failed to suspend %d\n", ret);
return ret;
}
return ret;
}
static int sst_byt_pcm_dev_suspend_late(struct device *dev) static int sst_byt_pcm_dev_suspend_late(struct device *dev)
{ {
struct sst_pdata *sst_pdata = dev_get_platdata(dev); struct sst_pdata *sst_pdata = dev_get_platdata(dev);
struct sst_byt_priv_data *priv_data = dev_get_drvdata(dev);
int ret; int ret;
dev_dbg(dev, "suspending late\n"); dev_dbg(dev, "suspending late\n");
...@@ -434,34 +425,30 @@ static int sst_byt_pcm_dev_suspend_late(struct device *dev) ...@@ -434,34 +425,30 @@ static int sst_byt_pcm_dev_suspend_late(struct device *dev)
return ret; return ret;
} }
priv_data->restore_stream = true;
return ret; return ret;
} }
static int sst_byt_pcm_dev_resume_early(struct device *dev) static int sst_byt_pcm_dev_resume_early(struct device *dev)
{ {
struct sst_pdata *sst_pdata = dev_get_platdata(dev); struct sst_pdata *sst_pdata = dev_get_platdata(dev);
int ret;
dev_dbg(dev, "resume early\n"); dev_dbg(dev, "resume early\n");
/* load fw and boot DSP */ /* load fw and boot DSP */
return sst_byt_dsp_boot(dev, sst_pdata); ret = sst_byt_dsp_boot(dev, sst_pdata);
} if (ret)
return ret;
static int sst_byt_pcm_dev_resume(struct device *dev)
{
struct sst_pdata *sst_pdata = dev_get_platdata(dev);
dev_dbg(dev, "resume\n");
/* wait for FW to finish booting */ /* wait for FW to finish booting */
return sst_byt_dsp_wait_for_ready(dev, sst_pdata); return sst_byt_dsp_wait_for_ready(dev, sst_pdata);
} }
static const struct dev_pm_ops sst_byt_pm_ops = { static const struct dev_pm_ops sst_byt_pm_ops = {
.suspend_noirq = sst_byt_pcm_dev_suspend_noirq,
.suspend_late = sst_byt_pcm_dev_suspend_late, .suspend_late = sst_byt_pcm_dev_suspend_late,
.resume_early = sst_byt_pcm_dev_resume_early, .resume_early = sst_byt_pcm_dev_resume_early,
.resume = sst_byt_pcm_dev_resume,
}; };
#define SST_BYT_PM_OPS (&sst_byt_pm_ops) #define SST_BYT_PM_OPS (&sst_byt_pm_ops)
......
...@@ -765,9 +765,7 @@ static int pxa_ssp_remove(struct snd_soc_dai *dai) ...@@ -765,9 +765,7 @@ static int pxa_ssp_remove(struct snd_soc_dai *dai)
SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | \ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | \
SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
#define PXA_SSP_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ #define PXA_SSP_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
SNDRV_PCM_FMTBIT_S24_LE | \
SNDRV_PCM_FMTBIT_S32_LE)
static const struct snd_soc_dai_ops pxa_ssp_dai_ops = { static const struct snd_soc_dai_ops pxa_ssp_dai_ops = {
.startup = pxa_ssp_startup, .startup = pxa_ssp_startup,
......
...@@ -2860,12 +2860,14 @@ int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol, ...@@ -2860,12 +2860,14 @@ int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol,
struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
unsigned int reg_val, val; unsigned int reg_val, val;
int ret = 0;
if (e->reg != SND_SOC_NOPM) if (e->reg != SND_SOC_NOPM) {
ret = soc_dapm_read(dapm, e->reg, &reg_val); int ret = soc_dapm_read(dapm, e->reg, &reg_val);
else if (ret)
return ret;
} else {
reg_val = dapm_kcontrol_get_value(kcontrol); reg_val = dapm_kcontrol_get_value(kcontrol);
}
val = (reg_val >> e->shift_l) & e->mask; val = (reg_val >> e->shift_l) & e->mask;
ucontrol->value.enumerated.item[0] = snd_soc_enum_val_to_item(e, val); ucontrol->value.enumerated.item[0] = snd_soc_enum_val_to_item(e, val);
...@@ -2875,7 +2877,7 @@ int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol, ...@@ -2875,7 +2877,7 @@ int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol,
ucontrol->value.enumerated.item[1] = val; ucontrol->value.enumerated.item[1] = val;
} }
return ret; return 0;
} }
EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_double); EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_double);
......
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