summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorChen Liangjun <b36089@freescale.com>2012-06-11 15:08:18 +0800
committerJason Liu <r64343@freescale.com>2012-07-20 13:38:50 +0800
commitd85b9d666cc6d6a6fdbfe7567cce4a7a9d08780f (patch)
tree99dbf64c601376227b716125001b4861819e1c8e /sound
parent9531edc94a94124d1ca119300f7c2d8b267de094 (diff)
ENGR00212318 ASRC:update to in/out width config
The origin ASRC driver did not support input and output wordwidth config but an total wordwidth config instead. And the input wordwith and output wordwidth are all fixed to 24 bit. In this path, we do things below: 1 Update to use input wordwidth and output wordwidth config seperately instead of an total wordwidth config. 2 Set corresponding DMA(input/output) buswidth according ASRC's input and output wordwidth config. 3 Support 16/24 bit input wordwidth and 24 bit output wordwidth. Signed-off-by: Chen Liangjun <b36089@freescale.com>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/imx/imx-cs42888.c30
-rw-r--r--sound/soc/imx/imx-pcm-dma-mx2.c12
-rw-r--r--sound/soc/imx/imx-pcm.h3
3 files changed, 27 insertions, 18 deletions
diff --git a/sound/soc/imx/imx-cs42888.c b/sound/soc/imx/imx-cs42888.c
index 3fc420cbf59e..5a22939b8cc0 100644
--- a/sound/soc/imx/imx-cs42888.c
+++ b/sound/soc/imx/imx-cs42888.c
@@ -60,6 +60,7 @@ struct asrc_esai {
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",
@@ -94,16 +95,14 @@ static const struct snd_kcontrol_new asrc_controls[] = {
asrc_set_rate),
};
-static int get_format_width(struct snd_pcm_hw_params *params)
+static enum asrc_word_width get_asrc_input_width(
+ struct snd_pcm_hw_params *params)
{
switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S8:
- case SNDRV_PCM_FORMAT_U8:
- return 8;
case SNDRV_PCM_FORMAT_U16:
case SNDRV_PCM_FORMAT_S16_LE:
case SNDRV_PCM_FORMAT_S16_BE:
- return 16;
+ return ASRC_WIDTH_16_BIT;
case SNDRV_PCM_FORMAT_S20_3LE:
case SNDRV_PCM_FORMAT_S20_3BE:
case SNDRV_PCM_FORMAT_S24_3LE:
@@ -114,12 +113,13 @@ static int get_format_width(struct snd_pcm_hw_params *params)
case SNDRV_PCM_FORMAT_U24_LE:
case SNDRV_PCM_FORMAT_U24_3BE:
case SNDRV_PCM_FORMAT_U24_3LE:
- return 24;
+ return ASRC_WIDTH_24_BIT;
+ case SNDRV_PCM_FORMAT_S8:
+ case SNDRV_PCM_FORMAT_U8:
case SNDRV_PCM_FORMAT_S32:
case SNDRV_PCM_FORMAT_U32:
- return 32;
default:
- pr_err("Format is not support!\r\n");
+ pr_err("Format is not support!\n");
return -EINVAL;
}
}
@@ -129,21 +129,18 @@ static int config_asrc(struct snd_pcm_substream *substream,
{
unsigned int rate = params_rate(params);
unsigned int channel = params_channels(params);
- unsigned int wordwidth = get_format_width(params);
struct imx_pcm_runtime_data *pcm_data =
substream->runtime->private_data;
struct asrc_config config = {0};
int ret = 0;
- if ((rate == asrc_esai_data.input_sample_rate) || (asrc_func == 0))
+ if ((rate == asrc_esai_data.input_sample_rate)
+ || !asrc_func)
return -EINVAL;
if (channel != 2)
return -EINVAL;
- if (wordwidth != 24)
- return -EINVAL;
-
ret = asrc_req_pair(channel, &asrc_esai_data.asrc_index);
if (ret < 0) {
pr_err("Fail to request asrc pair\n");
@@ -152,12 +149,13 @@ static int config_asrc(struct snd_pcm_substream *substream,
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.channel_num = channel;
config.input_sample_rate = asrc_esai_data.input_sample_rate;
config.output_sample_rate = rate;
config.inclk = OUTCLK_ASRCK1_CLK;
- config.word_width = wordwidth;
config.outclk = OUTCLK_ESAI_TX;
ret = asrc_config_pair(&config);
@@ -167,8 +165,8 @@ static int config_asrc(struct snd_pcm_substream *substream,
asrc_finish_conv(asrc_esai_data.asrc_index);
return ret;
}
- /*now our asrc driver support 24bit output*/
- pcm_data->output_bit = 24;
+ /*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;
diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c
index 2547d2bb8fdb..9c6dcd2a0e40 100644
--- a/sound/soc/imx/imx-pcm-dma-mx2.c
+++ b/sound/soc/imx/imx-pcm-dma-mx2.c
@@ -134,7 +134,16 @@ static int imx_ssi_asrc_dma_alloc(struct snd_pcm_substream *substream,
if (!iprtd->asrc_p2p_dma_chan)
goto error;
- buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ switch (iprtd->output_bit) {
+ case ASRC_WIDTH_16_BIT:
+ buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
+ break;
+ case ASRC_WIDTH_24_BIT:
+ buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ break;
+ default:
+ return -EINVAL;
+ }
slave_config.direction = DMA_DEV_TO_DEV;
slave_config.src_addr = asrc_get_per_addr(iprtd->asrc_index, 0);
@@ -412,6 +421,7 @@ static int snd_imx_open(struct snd_pcm_substream *substream)
iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL);
if (iprtd == NULL)
return -ENOMEM;
+
runtime->private_data = iprtd;
ret = snd_pcm_hw_constraint_integer(substream->runtime,
diff --git a/sound/soc/imx/imx-pcm.h b/sound/soc/imx/imx-pcm.h
index ede1382a2e04..86d6e36dab94 100644
--- a/sound/soc/imx/imx-pcm.h
+++ b/sound/soc/imx/imx-pcm.h
@@ -33,6 +33,7 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/dmaengine.h>
+#include <linux/mxc_asrc.h>
#include <sound/core.h>
#include <sound/initval.h>
@@ -63,7 +64,7 @@ struct imx_pcm_runtime_data {
struct dma_async_tx_descriptor *asrc_p2p_desc;
struct dma_chan *asrc_p2p_dma_chan;
struct imx_dma_data asrc_p2p_dma_data;
- unsigned int output_bit;
+ enum asrc_word_width output_bit;
#endif
};
#endif