summaryrefslogtreecommitdiff
path: root/sound/soc
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/fsl/fsl_asrc.c4
-rw-r--r--sound/soc/fsl/fsl_asrc.h4
-rw-r--r--sound/soc/fsl/fsl_asrc_m2m.c18
3 files changed, 24 insertions, 2 deletions
diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
index 5d32c26659d1..31dbca05c6d6 100644
--- a/sound/soc/fsl/fsl_asrc.c
+++ b/sound/soc/fsl/fsl_asrc.c
@@ -1144,24 +1144,28 @@ static int fsl_asrc_probe(struct platform_device *pdev)
sizeof(asrc_priv->name) - 1);
asrc_priv->clk_map[IN] = input_clk_map_imx35;
asrc_priv->clk_map[OUT] = output_clk_map_imx35;
+ asrc_priv->dma_type = DMA_SDMA;
} else if (of_device_is_compatible(np, "fsl,imx53-asrc")) {
asrc_priv->channel_bits = 4;
strncpy(asrc_priv->name, "mxc_asrc",
sizeof(asrc_priv->name) - 1);
asrc_priv->clk_map[IN] = input_clk_map_imx53;
asrc_priv->clk_map[OUT] = output_clk_map_imx53;
+ asrc_priv->dma_type = DMA_SDMA;
} else if (of_device_is_compatible(np, "fsl,imx8qm-asrc0")) {
asrc_priv->channel_bits = 4;
strncpy(asrc_priv->name, "mxc_asrc",
sizeof(asrc_priv->name) - 1);
asrc_priv->clk_map[IN] = input_clk_map_imx8_0;
asrc_priv->clk_map[OUT] = output_clk_map_imx8_0;
+ asrc_priv->dma_type = DMA_EDMA;
} else if (of_device_is_compatible(np, "fsl,imx8qm-asrc1")) {
asrc_priv->channel_bits = 4;
strncpy(asrc_priv->name, "mxc_asrc1",
sizeof(asrc_priv->name) - 1);
asrc_priv->clk_map[IN] = input_clk_map_imx8_1;
asrc_priv->clk_map[OUT] = output_clk_map_imx8_1;
+ asrc_priv->dma_type = DMA_EDMA;
}
ret = fsl_asrc_init(asrc_priv);
diff --git a/sound/soc/fsl/fsl_asrc.h b/sound/soc/fsl/fsl_asrc.h
index 028c18fa324e..38394a4fe7df 100644
--- a/sound/soc/fsl/fsl_asrc.h
+++ b/sound/soc/fsl/fsl_asrc.h
@@ -371,11 +371,15 @@ struct fsl_asrc {
int asrc_rate;
int asrc_width;
+ int dma_type; /* 0 is sdma, 1 is edma */
u32 regcache_cfg;
char name[20];
};
+#define DMA_SDMA 0
+#define DMA_EDMA 1
+
extern struct snd_soc_platform_driver fsl_asrc_platform;
struct dma_chan *fsl_asrc_get_dma_channel(struct fsl_asrc_pair *pair, bool dir);
int fsl_asrc_request_pair(int channels, struct fsl_asrc_pair *pair);
diff --git a/sound/soc/fsl/fsl_asrc_m2m.c b/sound/soc/fsl/fsl_asrc_m2m.c
index 9f0314970cbb..2684518d26ee 100644
--- a/sound/soc/fsl/fsl_asrc_m2m.c
+++ b/sound/soc/fsl/fsl_asrc_m2m.c
@@ -174,8 +174,11 @@ static int fsl_asrc_dmaconfig(struct fsl_asrc_pair *pair, struct dma_chan *chan,
slave_config.direction = DMA_MEM_TO_DEV;
slave_config.dst_addr = dma_addr;
slave_config.dst_addr_width = buswidth;
- slave_config.dst_maxburst =
- m2m->watermark[IN] * pair->channels;
+ if (asrc_priv->dma_type == DMA_SDMA)
+ slave_config.dst_maxburst =
+ m2m->watermark[IN] * pair->channels;
+ else
+ slave_config.dst_maxburst = 1;
} else {
slave_config.direction = DMA_DEV_TO_MEM;
slave_config.src_addr = dma_addr;
@@ -283,6 +286,9 @@ static int fsl_asrc_prepare_io_buffer(struct fsl_asrc_pair *pair,
*dma_len -= last_period_size * word_size * pair->channels;
*dma_len = *dma_len / (word_size * pair->channels) *
(word_size * pair->channels);
+ if (asrc_priv->dma_type == DMA_EDMA)
+ *dma_len = *dma_len / (word_size * pair->channels * m2m->watermark[OUT])
+ * (word_size * pair->channels * m2m->watermark[OUT]);
}
*sg_nodes = *dma_len / ASRC_MAX_BUFFER_SIZE + 1;
@@ -625,11 +631,13 @@ static long fsl_asrc_calc_last_period_size(struct fsl_asrc_pair *pair,
struct asrc_convert_buffer *pbuf)
{
struct fsl_asrc_m2m *m2m = pair->private;
+ struct fsl_asrc *asrc_priv = pair->asrc_priv;
unsigned int out_length;
unsigned int in_width, out_width;
unsigned int channels = pair->channels;
unsigned int in_samples, out_samples;
unsigned int last_period_size;
+ unsigned int remain;
switch (m2m->word_width[IN]) {
case ASRC_WIDTH_24_BIT:
@@ -672,6 +680,12 @@ static long fsl_asrc_calc_last_period_size(struct fsl_asrc_pair *pair,
m2m->last_period_size = last_period_size + 1 + ASRC_OUTPUT_LAST_SAMPLE;
+ if (asrc_priv->dma_type == DMA_EDMA) {
+ remain = pbuf->output_buffer_length % (out_width * channels * m2m->watermark[OUT]);
+ if (remain)
+ m2m->last_period_size += remain / (out_width * channels);
+ }
+
return 0;
}