summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorXinyu Chen <b03824@freescale.com>2011-10-11 16:26:02 +0800
committerXinyu Chen <b03824@freescale.com>2011-10-11 16:26:02 +0800
commit5b2d450d495ecfda84d817ee92407340e8455e4d (patch)
tree066dc1e926f58755782cdfad3e0f6d1995a97ef4 /sound
parent949ce411ed8db6ca2146e1bbb35f23f095ddb010 (diff)
parent1def97410f512f43681660f5a9eeb5662c453380 (diff)
Merge remote branch 'fsl-linux-sdk/imx_2.6.38' into imx_2.6.38_android
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/cs42888.c1
-rw-r--r--sound/soc/codecs/mxc_spdif.c16
-rw-r--r--sound/soc/codecs/sgtl5000.c17
-rw-r--r--sound/soc/codecs/sgtl5000.h2
-rw-r--r--sound/soc/imx/imx-cs42888.c20
-rw-r--r--sound/soc/imx/imx-esai.c29
-rw-r--r--sound/soc/imx/imx-esai.h5
-rw-r--r--sound/soc/imx/imx-ssi.c16
8 files changed, 78 insertions, 28 deletions
diff --git a/sound/soc/codecs/cs42888.c b/sound/soc/codecs/cs42888.c
index b17930a91c4a..e1dfcf8a5c38 100644
--- a/sound/soc/codecs/cs42888.c
+++ b/sound/soc/codecs/cs42888.c
@@ -785,7 +785,6 @@ struct snd_soc_dai_driver cs42888_dai = {
.formats = CS42888_FORMATS,
},
.ops = &cs42888_dai_ops,
- .symmetric_rates = 1,
};
/**
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;
}
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
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 <linux/dmaengine.h>
#include <mach/dma.h>
+#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;
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;
}