summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/cs42888.c7
-rw-r--r--sound/soc/imx/imx-cs42888.c136
-rw-r--r--sound/soc/imx/imx-esai.c2
-rw-r--r--sound/soc/imx/imx-pcm-dma-mx2.c8
-rw-r--r--sound/soc/imx/imx-pcm.h4
5 files changed, 48 insertions, 109 deletions
diff --git a/sound/soc/codecs/cs42888.c b/sound/soc/codecs/cs42888.c
index cc802e0e71c2..73571dafa9a4 100644
--- a/sound/soc/codecs/cs42888.c
+++ b/sound/soc/codecs/cs42888.c
@@ -34,6 +34,7 @@
#include <asm/div64.h>
#include "cs42888.h"
+#include "../imx/imx-pcm.h"
#define CS42888_NUM_SUPPLIES 4
static const char *cs42888_supply_names[CS42888_NUM_SUPPLIES] = {
"VA",
@@ -664,6 +665,7 @@ static int cs42888_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct imx_pcm_runtime_data *iprtd = substream->runtime->private_data;
struct snd_soc_codec *codec = rtd->codec;
struct cs42888_private *cs42888 = snd_soc_codec_get_drvdata(codec);
int ret;
@@ -672,7 +674,10 @@ static int cs42888_hw_params(struct snd_pcm_substream *substream,
unsigned int ratio;
u32 val;
- rate = params_rate(params); /* Sampling rate, in Hz */
+ if (iprtd->asrc_enable)
+ rate = iprtd->p2p->p2p_rate;
+ else
+ rate = params_rate(params); /* Sampling rate, in Hz */
ratio = cs42888->mclk / rate; /* MCLK/LRCK ratio */
for (i = 0; i < NUM_MCLK_RATIOS; i++) {
if (cs42888_mode_ratios[i].ratio == ratio)
diff --git a/sound/soc/imx/imx-cs42888.c b/sound/soc/imx/imx-cs42888.c
index 7f4f2840db7b..5fc128a4aacb 100644
--- a/sound/soc/imx/imx-cs42888.c
+++ b/sound/soc/imx/imx-cs42888.c
@@ -39,61 +39,6 @@
#include "imx-pcm.h"
#if defined(CONFIG_MXC_ASRC) || defined(CONFIG_IMX_HAVE_PLATFORM_IMX_ASRC)
-static unsigned int asrc_rates[] = {
- 0,
- 24000,
- 32000,
- 44100,
- 48000,
- 64000,
- 88200,
- 96000,
- 176400,
- 192000,
-};
-struct asrc_esai {
- unsigned int cpu_dai_rates;
- unsigned int codec_dai_rates;
- enum asrc_pair_index asrc_index;
- unsigned int input_sample_rate;
-};
-static struct asrc_esai asrc_esai_data;
-static bool asrc_support = 1;
-static int asrc_func;
-enum asrc_word_width asrcp2p_output_bit = ASRC_WIDTH_24_BIT;
-
-static const char *asrc_function[] = {
- "disable", "24KHz", "32KHz", "44.1KHz",
- "48KHz", "64KHz", "88.2KHz", "96KHz", "176.4KHz", "192KHz"
-};
-
-static const struct soc_enum asrc_enum[] = {
- SOC_ENUM_SINGLE_EXT(9, asrc_function),
-};
-
-static int asrc_get_rate(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.enumerated.item[0] = asrc_func;
- return 0;
-}
-
-static int asrc_set_rate(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- if (asrc_func == ucontrol->value.enumerated.item[0])
- return 0;
-
- asrc_func = ucontrol->value.enumerated.item[0];
- asrc_esai_data.input_sample_rate = asrc_rates[asrc_func];
-
- return 1;
-}
-
-static const struct snd_kcontrol_new asrc_controls[] = {
- SOC_ENUM_EXT("ASRC", asrc_enum[0], asrc_get_rate,
- asrc_set_rate),
-};
static enum asrc_word_width get_asrc_input_width(
struct snd_pcm_hw_params *params)
@@ -129,61 +74,51 @@ static int config_asrc(struct snd_pcm_substream *substream,
{
unsigned int rate = params_rate(params);
unsigned int channel = params_channels(params);
- struct imx_pcm_runtime_data *pcm_data =
+ struct imx_pcm_runtime_data *iprtd =
substream->runtime->private_data;
struct asrc_config config = {0};
int ret = 0;
- if ((rate == asrc_esai_data.input_sample_rate)
- || !asrc_func)
- return -EINVAL;
-
if ((channel != 2) && (channel != 4) && (channel != 6))
return -EINVAL;
- ret = asrc_req_pair(channel, &asrc_esai_data.asrc_index);
+ ret = asrc_req_pair(channel, &iprtd->asrc_index);
if (ret < 0) {
pr_err("Fail to request asrc pair\n");
- asrc_release_pair(asrc_esai_data.asrc_index);
- asrc_finish_conv(asrc_esai_data.asrc_index);
+ asrc_release_pair(iprtd->asrc_index);
+ asrc_finish_conv(iprtd->asrc_index);
return -EINVAL;
}
config.input_word_width = get_asrc_input_width(params);
- config.output_word_width = asrcp2p_output_bit;
- config.pair = asrc_esai_data.asrc_index;
+ config.output_word_width = iprtd->p2p->p2p_width;
+ config.pair = iprtd->asrc_index;
config.channel_num = channel;
- config.input_sample_rate = asrc_esai_data.input_sample_rate;
- config.output_sample_rate = rate;
- config.inclk = OUTCLK_ASRCK1_CLK;
+ config.input_sample_rate = rate;
+ config.output_sample_rate = iprtd->p2p->p2p_rate;
+ config.inclk = INCLK_ASRCK1_CLK;
config.outclk = OUTCLK_ESAI_TX;
ret = asrc_config_pair(&config);
if (ret < 0) {
pr_err("Fail to config asrc\n");
- asrc_release_pair(asrc_esai_data.asrc_index);
- asrc_finish_conv(asrc_esai_data.asrc_index);
+ asrc_release_pair(iprtd->asrc_index);
+ asrc_finish_conv(iprtd->asrc_index);
return ret;
}
- /*now our asrc driver only support 24bit output*/
- pcm_data->output_bit = asrcp2p_output_bit;
- pcm_data->asrc_index = asrc_esai_data.asrc_index;
- pcm_data->asrc_enable = 1;
return 0;
}
-#else
-static bool asrc_support;
#endif
struct imx_priv_state {
int hw;
};
+static struct asrc_p2p_params *esai_asrc;
static struct imx_priv_state hw_state;
unsigned int mclk_freq;
-
static int imx_3stack_startup(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -193,14 +128,6 @@ static int imx_3stack_startup(struct snd_pcm_substream *substream)
hw_state.hw = 0;
}
- if (asrc_support) {
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- asrc_esai_data.cpu_dai_rates =
- cpu_dai->driver->playback.rates;
- asrc_esai_data.codec_dai_rates =
- codec_dai->driver->playback.rates;
- }
-
return 0;
}
@@ -208,24 +135,14 @@ static void imx_3stack_shutdown(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct imx_pcm_runtime_data *iprtd = substream->runtime->private_data;
- if (asrc_support) {
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct imx_pcm_runtime_data *pcm_data =
- substream->runtime->private_data;
- if (pcm_data->asrc_enable) {
- asrc_release_pair(asrc_esai_data.asrc_index);
- asrc_finish_conv(asrc_esai_data.asrc_index);
+ if (iprtd->asrc_enable) {
+ if (iprtd->asrc_index != -1) {
+ asrc_release_pair(iprtd->asrc_index);
+ asrc_finish_conv(iprtd->asrc_index);
}
- pcm_data->asrc_enable = 0;
- asrc_esai_data.asrc_index = -1;
-
- codec_dai->driver->playback.rates =
- asrc_esai_data.codec_dai_rates;
- cpu_dai->driver->playback.rates =
- asrc_esai_data.cpu_dai_rates;
- asrc_func = 0;
- asrc_esai_data.input_sample_rate = asrc_rates[asrc_func];
+ iprtd->asrc_index = -1;
}
if (!cpu_dai->active)
@@ -238,17 +155,22 @@ static int imx_3stack_surround_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct imx_pcm_runtime_data *iprtd = substream->runtime->private_data;
unsigned int rate = params_rate(params);
u32 dai_format;
unsigned int lrclk_ratio = 0;
+ int err = 0;
if (hw_state.hw)
return 0;
hw_state.hw = 1;
- if (asrc_support && (substream->stream == SNDRV_PCM_STREAM_PLAYBACK))
- config_asrc(substream, params);
-
+ if (iprtd->asrc_enable) {
+ err = config_asrc(substream, params);
+ if (err < 0)
+ return err;
+ rate = iprtd->p2p->p2p_rate;
+ }
if (cpu_is_mx53() || machine_is_mx6q_sabreauto()) {
switch (rate) {
case 32000:
@@ -393,6 +315,8 @@ static int imx_3stack_cs42888_init(struct snd_soc_pcm_runtime *rtd)
}
static int imx_asrc_cs42888_init(struct snd_soc_pcm_runtime *rtd)
{
+
+ snd_soc_pcm_set_drvdata(rtd, (void *)esai_asrc);
return 0;
}
@@ -451,11 +375,15 @@ static int __devinit imx_3stack_cs42888_probe(struct platform_device *pdev)
imx_3stack_dai[0].codec_name = plat_data->codec_name;
imx_3stack_dai[1].codec_name = plat_data->codec_name;
}
+ esai_asrc = kzalloc(sizeof(struct asrc_p2p_params), GFP_KERNEL);
+ memcpy(esai_asrc, plat_data->priv, sizeof(struct asrc_p2p_params));
return 0;
}
static int __devexit imx_3stack_cs42888_remove(struct platform_device *pdev)
{
+ if (esai_asrc)
+ kfree(esai_asrc);
return 0;
}
diff --git a/sound/soc/imx/imx-esai.c b/sound/soc/imx/imx-esai.c
index f11757b0e7cc..b3cba9ea53c4 100644
--- a/sound/soc/imx/imx-esai.c
+++ b/sound/soc/imx/imx-esai.c
@@ -319,7 +319,7 @@ static int imx_esai_hw_tx_params(struct snd_pcm_substream *substream,
tcr &= ESAI_TCR_TSWS_MASK;
if (iprtd->asrc_enable) {
- switch (iprtd->output_bit) {
+ switch (iprtd->p2p->p2p_width) {
case ASRC_WIDTH_16_BIT:
tfcr |= ESAI_WORD_LEN_16;
tcr |= ESAI_TCR_TSHFD_MSB | ESAI_TCR_TSWS_STL32_WDL16;
diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c
index 9c6dcd2a0e40..712bf7d49522 100644
--- a/sound/soc/imx/imx-pcm-dma-mx2.c
+++ b/sound/soc/imx/imx-pcm-dma-mx2.c
@@ -134,7 +134,7 @@ static int imx_ssi_asrc_dma_alloc(struct snd_pcm_substream *substream,
if (!iprtd->asrc_p2p_dma_chan)
goto error;
- switch (iprtd->output_bit) {
+ switch (iprtd->p2p->p2p_width) {
case ASRC_WIDTH_16_BIT:
buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
break;
@@ -415,12 +415,18 @@ static struct snd_pcm_hardware snd_imx_hardware = {
static int snd_imx_open(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct imx_pcm_runtime_data *iprtd;
int ret;
iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL);
if (iprtd == NULL)
return -ENOMEM;
+ if (!strcmp(rtd->dai_link->name, "HiFi_ASRC")) {
+ iprtd->asrc_enable = true;
+ iprtd->p2p =
+ (struct asrc_p2p_params *)snd_soc_pcm_get_drvdata(rtd);
+ }
runtime->private_data = iprtd;
diff --git a/sound/soc/imx/imx-pcm.h b/sound/soc/imx/imx-pcm.h
index 86d6e36dab94..c6126216a9cd 100644
--- a/sound/soc/imx/imx-pcm.h
+++ b/sound/soc/imx/imx-pcm.h
@@ -57,14 +57,14 @@ struct imx_pcm_runtime_data {
int asrc_enable;
#if defined(CONFIG_MXC_ASRC) || defined(CONFIG_IMX_HAVE_PLATFORM_IMX_ASRC)
- int asrc_index;
+ enum asrc_pair_index asrc_index;
struct dma_async_tx_descriptor *asrc_desc;
struct dma_chan *asrc_dma_chan;
struct imx_dma_data asrc_dma_data;
struct dma_async_tx_descriptor *asrc_p2p_desc;
struct dma_chan *asrc_p2p_dma_chan;
struct imx_dma_data asrc_p2p_dma_data;
- enum asrc_word_width output_bit;
+ struct asrc_p2p_params *p2p;
#endif
};
#endif