diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/codecs/cs42888.c | 7 | ||||
-rw-r--r-- | sound/soc/imx/imx-cs42888.c | 136 | ||||
-rw-r--r-- | sound/soc/imx/imx-esai.c | 2 | ||||
-rw-r--r-- | sound/soc/imx/imx-pcm-dma-mx2.c | 8 | ||||
-rw-r--r-- | sound/soc/imx/imx-pcm.h | 4 |
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 |