From a7a8bb9829d60851104495c2affbf12c60357b46 Mon Sep 17 00:00:00 2001 From: Lionel Xu Date: Thu, 15 Sep 2011 15:44:26 +0800 Subject: ENGR00156813 MX53 ALSA: Recording no sound There is no sound in the recorded wav, to enable recording, the VAG should be powered up, and the mic bias resistor should be setup with proper value. Signed-off-by: Lionel Xu --- sound/soc/codecs/sgtl5000.c | 17 +++++++++++++---- sound/soc/codecs/sgtl5000.h | 2 +- 2 files changed, 14 insertions(+), 5 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index 20cc36f268ad..485a9d1cd472 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c @@ -103,7 +103,11 @@ static int mic_bias_event(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMU: /* change mic bias resistor to 4Kohm */ snd_soc_update_bits(w->codec, SGTL5000_CHIP_MIC_CTRL, - SGTL5000_BIAS_R_4k, SGTL5000_BIAS_R_4k); + SGTL5000_BIAS_R_MASK, + SGTL5000_BIAS_R_4k << SGTL5000_BIAS_R_SHIFT); + + snd_soc_update_bits(w->codec, SGTL5000_CHIP_ANA_POWER, + SGTL5000_VAG_POWERUP, SGTL5000_VAG_POWERUP); break; case SND_SOC_DAPM_PRE_PMD: @@ -112,7 +116,11 @@ static int mic_bias_event(struct snd_soc_dapm_widget *w, * of mic bias and output impedance */ snd_soc_update_bits(w->codec, SGTL5000_CHIP_MIC_CTRL, - SGTL5000_BIAS_R_8k, 0); + SGTL5000_BIAS_R_MASK, + SGTL5000_BIAS_R_off << SGTL5000_BIAS_R_SHIFT); + + snd_soc_update_bits(w->codec, SGTL5000_CHIP_ANA_POWER, + SGTL5000_VAG_POWERUP, 0); break; } return 0; @@ -240,7 +248,7 @@ static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = { 0, SGTL5000_CHIP_DIG_POWER, 1, 0), - SND_SOC_DAPM_MICBIAS_E("Mic Bias", SGTL5000_CHIP_MIC_CTRL, 8, 0, + SND_SOC_DAPM_MICBIAS_E("Mic Bias", SND_SOC_NOPM, 0, 0, mic_bias_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), @@ -271,7 +279,8 @@ static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = { /* routes for sgtl5000 */ static const struct snd_soc_dapm_route audio_map[] = { {"Capture Mux", "LINE_IN", "LINE_IN"}, /* line_in --> adc_mux */ - {"Capture Mux", "MIC_IN", "MIC_IN"}, /* mic_in --> adc_mux */ + {"Mic Bias", NULL, "MIC_IN"}, /* mic_in --> mic bias */ + {"Capture Mux", "MIC_IN", "Mic Bias"}, /* mic bias --> adc_mux */ {"ADC", NULL, "Capture Mux"}, /* adc_mux --> adc */ diff --git a/sound/soc/codecs/sgtl5000.h b/sound/soc/codecs/sgtl5000.h index eec3ab368f39..8a9f43534b79 100644 --- a/sound/soc/codecs/sgtl5000.h +++ b/sound/soc/codecs/sgtl5000.h @@ -280,7 +280,7 @@ /* * SGTL5000_CHIP_MIC_CTRL */ -#define SGTL5000_BIAS_R_MASK 0x0200 +#define SGTL5000_BIAS_R_MASK 0x0300 #define SGTL5000_BIAS_R_SHIFT 8 #define SGTL5000_BIAS_R_WIDTH 2 #define SGTL5000_BIAS_R_off 0x0 -- cgit v1.2.3 From 9f7399813f5d0c743ee15f656dde82dec4f21d7a Mon Sep 17 00:00:00 2001 From: Lionel Xu Date: Mon, 26 Sep 2011 16:46:00 +0800 Subject: ENGR00158176 SGTL5000: I/O Error appeared when recording mono wav through HW When recording mono wav, SSI's network mode should be closed, or it will influence the internal freq config, making recording fail. Signed-off-by: Lionel Xu --- sound/soc/imx/imx-ssi.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'sound') diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c index 44edf2951542..9dfbd2087e2c 100644 --- a/sound/soc/imx/imx-ssi.c +++ b/sound/soc/imx/imx-ssi.c @@ -89,14 +89,13 @@ static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai); u32 strcr = 0, scr; - scr = readl(ssi->base + SSI_SCR) & ~(SSI_SCR_SYN | SSI_SCR_NET); + scr = readl(ssi->base + SSI_SCR) & ~SSI_SCR_SYN; /* DAI mode */ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: /* data on rising edge of bclk, frame low 1clk before data */ strcr |= SSI_STCR_TFSI | SSI_STCR_TEFS | SSI_STCR_TXBIT0; - scr |= SSI_SCR_NET; if (ssi->flags & IMX_SSI_USE_I2S_SLAVE) { scr &= ~SSI_I2S_MODE_MASK; scr |= SSI_SCR_I2S_MODE_SLAVE; @@ -145,8 +144,6 @@ static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) strcr |= SSI_STCR_TFEN0; - if (ssi->flags & IMX_SSI_NET) - scr |= SSI_SCR_NET; if (ssi->flags & IMX_SSI_SYN) scr |= SSI_SCR_SYN; @@ -243,7 +240,8 @@ static int imx_ssi_hw_params(struct snd_pcm_substream *substream, { struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai); struct imx_pcm_dma_params *dma_data; - u32 reg, sccr; + u32 reg, sccr, scr; + unsigned int channels = params_channels(params); /* Tx/Rx config */ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { @@ -276,6 +274,14 @@ static int imx_ssi_hw_params(struct snd_pcm_substream *substream, writel(sccr, ssi->base + reg); + scr = readl(ssi->base + SSI_SCR); + + if (channels == 1) + scr &= ~SSI_SCR_NET; + else + scr |= SSI_SCR_NET; + + writel(scr, ssi->base + SSI_SCR); return 0; } -- cgit v1.2.3 From d97b9e4c876fb07828b96a6624cd8cc84193c0d8 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Mon, 26 Sep 2011 10:46:27 +0800 Subject: SAUCE: set correct rates before registering SPDIF codec DAI BugLink: http://bugs.launchpad.net/bugs/855281 Playback/capture rates should be configured before the SPDIF codec DAI is registered, according to the parameters that passed in by the platform data. And this caused pulseaudio not working with the SPDIF sound card. Signed-off-by: Eric Miao --- sound/soc/codecs/mxc_spdif.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/mxc_spdif.c b/sound/soc/codecs/mxc_spdif.c index 6774ed954269..fbcd75494209 100644 --- a/sound/soc/codecs/mxc_spdif.c +++ b/sound/soc/codecs/mxc_spdif.c @@ -1152,7 +1152,13 @@ static int __devinit mxc_spdif_probe(struct platform_device *pdev) mxc_spdif_codec_dai.playback.stream_name = "Playback"; mxc_spdif_codec_dai.playback.channels_min = 2; mxc_spdif_codec_dai.playback.channels_max = 2; - mxc_spdif_codec_dai.playback.rates = MXC_SPDIF_RATES_PLAYBACK; + + if (plat_data->spdif_clk_44100 >= 0) + mxc_spdif_codec_dai.playback.rates |= SNDRV_PCM_RATE_44100; + if (plat_data->spdif_clk_48000 >= 0) + mxc_spdif_codec_dai.playback.rates |= SNDRV_PCM_RATE_32000 | + SNDRV_PCM_RATE_48000; + mxc_spdif_codec_dai.playback.formats = MXC_SPDIF_FORMATS_PLAYBACK; } @@ -1160,7 +1166,13 @@ static int __devinit mxc_spdif_probe(struct platform_device *pdev) mxc_spdif_codec_dai.capture.stream_name = "Capture"; mxc_spdif_codec_dai.capture.channels_min = 2; mxc_spdif_codec_dai.capture.channels_max = 2; - mxc_spdif_codec_dai.capture.rates = MXC_SPDIF_RATES_CAPTURE; + + if (plat_data->spdif_clk_44100 >= 0) + mxc_spdif_codec_dai.capture.rates |= SNDRV_PCM_RATE_44100; + if (plat_data->spdif_clk_48000 >= 0) + mxc_spdif_codec_dai.capture.rates |= SNDRV_PCM_RATE_32000 | + SNDRV_PCM_RATE_48000; + mxc_spdif_codec_dai.capture.formats = MXC_SPDIF_FORMATS_CAPTURE; } -- cgit v1.2.3 From a6706b3ccf4e31462c8beaa3ed231a187c61784c Mon Sep 17 00:00:00 2001 From: Lionel Xu Date: Fri, 30 Sep 2011 14:47:31 +0800 Subject: ENGR00156745 MX6Q ESAI: Playback and record can't start up concurrently Proper flag setting and placement should be used to avoid function hw_param called multiple times when playback and record startup concurrently. Signed-off-by: Lionel Xu --- sound/soc/codecs/cs42888.c | 1 - sound/soc/imx/imx-cs42888.c | 20 ++++++++++++++------ sound/soc/imx/imx-esai.c | 29 ++++++++++++++++++++--------- sound/soc/imx/imx-esai.h | 5 +++++ 4 files changed, 39 insertions(+), 16 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/cs42888.c b/sound/soc/codecs/cs42888.c index c810333b3284..f2480cc1490f 100644 --- a/sound/soc/codecs/cs42888.c +++ b/sound/soc/codecs/cs42888.c @@ -784,7 +784,6 @@ struct snd_soc_dai_driver cs42888_dai = { .formats = CS42888_FORMATS, }, .ops = &cs42888_dai_ops, - .symmetric_rates = 1, }; /** diff --git a/sound/soc/imx/imx-cs42888.c b/sound/soc/imx/imx-cs42888.c index e9f6633f1b74..d34be0a0e8f9 100644 --- a/sound/soc/imx/imx-cs42888.c +++ b/sound/soc/imx/imx-cs42888.c @@ -34,23 +34,29 @@ #include "../codecs/cs42888.h" -struct imx_3stack_pcm_state { - int lr_clk_active; +struct imx_priv_state { + int hw; }; -static struct imx_3stack_pcm_state clk_state; +static struct imx_priv_state hw_state; unsigned int mclk_freq; static int imx_3stack_startup(struct snd_pcm_substream *substream) { - clk_state.lr_clk_active++; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + if (!cpu_dai->active) + hw_state.hw = 0; return 0; } static void imx_3stack_shutdown(struct snd_pcm_substream *substream) { - clk_state.lr_clk_active--; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + if (!cpu_dai->active) + hw_state.hw = 0; } static int imx_3stack_surround_hw_params(struct snd_pcm_substream *substream, @@ -62,8 +68,10 @@ static int imx_3stack_surround_hw_params(struct snd_pcm_substream *substream, unsigned int rate = params_rate(params); u32 dai_format; unsigned int lrclk_ratio = 0; - if (clk_state.lr_clk_active > 1) + + if (hw_state.hw) return 0; + hw_state.hw = 1; if (cpu_is_mx53()) { switch (rate) { case 32000: diff --git a/sound/soc/imx/imx-esai.c b/sound/soc/imx/imx-esai.c index ebd45ffa6ecf..a3c5c44983e7 100644 --- a/sound/soc/imx/imx-esai.c +++ b/sound/soc/imx/imx-esai.c @@ -277,18 +277,23 @@ static int imx_esai_startup(struct snd_pcm_substream *substream, { struct imx_esai *esai = snd_soc_dai_get_drvdata(cpu_dai); - clk_enable(esai->clk); + if (!(local_esai->imx_esai_txrx_state & IMX_DAI_ESAI_TXRX)) { + clk_enable(esai->clk); - writel(ESAI_ECR_ERST, esai->base + ESAI_ECR); - writel(ESAI_ECR_ESAIEN, esai->base + ESAI_ECR); + writel(ESAI_ECR_ERST, esai->base + ESAI_ECR); + writel(ESAI_ECR_ESAIEN, esai->base + ESAI_ECR); - writel(ESAI_GPIO_ESAI, esai->base + ESAI_PRRC); - writel(ESAI_GPIO_ESAI, esai->base + ESAI_PCRC); + writel(ESAI_GPIO_ESAI, esai->base + ESAI_PRRC); + writel(ESAI_GPIO_ESAI, esai->base + ESAI_PCRC); + } - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + local_esai->imx_esai_txrx_state |= IMX_DAI_ESAI_TX; writel(ESAI_TCR_TPR, esai->base + ESAI_TCR); - else + } else { + local_esai->imx_esai_txrx_state |= IMX_DAI_ESAI_RX; writel(ESAI_RCR_RPR, esai->base + ESAI_RCR); + } ESAI_DUMP(); return 0; @@ -422,9 +427,14 @@ static void imx_esai_shutdown(struct snd_pcm_substream *substream, { struct imx_esai *esai = snd_soc_dai_get_drvdata(cpu_dai); - /* close easi clock */ - clk_disable(esai->clk); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + local_esai->imx_esai_txrx_state &= ~IMX_DAI_ESAI_TX; + else + local_esai->imx_esai_txrx_state &= ~IMX_DAI_ESAI_RX; + if (!(local_esai->imx_esai_txrx_state & IMX_DAI_ESAI_TXRX)) + /* close easi clock */ + clk_disable(esai->clk); } static int imx_esai_trigger(struct snd_pcm_substream *substream, int cmd, @@ -532,6 +542,7 @@ static struct snd_soc_dai_ops imx_esai_dai_ops = { static int imx_esai_dai_probe(struct snd_soc_dai *dai) { struct imx_esai *esai = dev_get_drvdata(dai->dev); + local_esai->imx_esai_txrx_state = 0; snd_soc_dai_set_drvdata(dai, esai); return 0; } diff --git a/sound/soc/imx/imx-esai.h b/sound/soc/imx/imx-esai.h index e8f2a71a6e71..97cf1c44c004 100644 --- a/sound/soc/imx/imx-esai.h +++ b/sound/soc/imx/imx-esai.h @@ -304,6 +304,10 @@ #include #include +#define IMX_DAI_ESAI_TX 0x04 +#define IMX_DAI_ESAI_RX 0x08 +#define IMX_DAI_ESAI_TXRX (IMX_DAI_ESAI_TX | IMX_DAI_ESAI_RX) + struct imx_esai { struct platform_device *ac97_dev; struct snd_soc_dai *imx_ac97; @@ -322,6 +326,7 @@ struct imx_esai { struct imx_pcm_dma_params dma_params_tx; int enabled; + int imx_esai_txrx_state; struct platform_device *soc_platform_pdev; struct platform_device *soc_platform_pdev_fiq; -- cgit v1.2.3