summaryrefslogtreecommitdiff
path: root/sound/soc
diff options
context:
space:
mode:
authorViorel Suman <viorel.suman@nxp.com>2017-04-30 18:11:00 +0300
committerDong Aisheng <aisheng.dong@nxp.com>2019-11-25 15:48:26 +0800
commiteb267cdcaa7d36a7816f3274be065853e8f4ced7 (patch)
tree65e8b22ec9c52bfbae24e64b83268f825b641bf0 /sound/soc
parent096ff09cc5d9665f72ec77ab127338ef8c5a951a (diff)
ASoC: fsl: refine the asrc driver for imx8qm
The clock source of ASRC in imx8qm is changed. Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/fsl/fsl_asrc.c44
-rw-r--r--sound/soc/fsl/fsl_asrc.h1
-rw-r--r--sound/soc/fsl/fsl_asrc_dma.c50
-rw-r--r--sound/soc/fsl/fsl_asrc_m2m.c17
4 files changed, 89 insertions, 23 deletions
diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
index c41f491cb62f..c6203c81a2b6 100644
--- a/sound/soc/fsl/fsl_asrc.c
+++ b/sound/soc/fsl/fsl_asrc.c
@@ -49,23 +49,55 @@ static struct snd_pcm_hw_constraint_list fsl_asrc_rate_constraints = {
*/
static unsigned char input_clk_map_imx35[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
};
static unsigned char output_clk_map_imx35[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
};
/* i.MX53 uses the same map for input and output */
static unsigned char input_clk_map_imx53[] = {
/* 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf */
0x0, 0x1, 0x2, 0x7, 0x4, 0x5, 0x6, 0x3, 0x8, 0x9, 0xa, 0xb, 0xc, 0xf, 0xe, 0xd,
+ 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
+ 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
};
static unsigned char output_clk_map_imx53[] = {
/* 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf */
0x8, 0x9, 0xa, 0x7, 0xc, 0x5, 0x6, 0xb, 0x0, 0x1, 0x2, 0x3, 0x4, 0xf, 0xe, 0xd,
+ 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
+ 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
};
+/* i.MX8 uses the same map for input and output */
+static unsigned char input_clk_map_imx8_0[] = {
+ 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0x0,
+ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
+ 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
+};
+
+static unsigned char output_clk_map_imx8_0[] = {
+ 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0x0,
+ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
+ 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
+};
+
+static unsigned char input_clk_map_imx8_1[] = {
+ 0xf, 0xf, 0xf, 0xf, 0xf, 0x7, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0x0,
+ 0x0, 0x1, 0x2, 0x3, 0xb, 0xc, 0xf, 0xf, 0xd, 0xe, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
+ 0x4, 0x5, 0x6, 0xf, 0x8, 0x9, 0xa, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
+};
+
+static unsigned char output_clk_map_imx8_1[] = {
+ 0xf, 0xf, 0xf, 0xf, 0xf, 0x7, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0x0,
+ 0x0, 0x1, 0x2, 0x3, 0xb, 0xc, 0xf, 0xf, 0xd, 0xe, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
+ 0x4, 0x5, 0x6, 0xf, 0x8, 0x9, 0xa, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
+};
static unsigned char *clk_map[2];
/**
@@ -963,10 +995,18 @@ static int fsl_asrc_probe(struct platform_device *pdev)
asrc_priv->channel_bits = 3;
clk_map[IN] = input_clk_map_imx35;
clk_map[OUT] = output_clk_map_imx35;
- } else {
+ } else if (of_device_is_compatible(np, "fsl,imx53-asrc")) {
asrc_priv->channel_bits = 4;
clk_map[IN] = input_clk_map_imx53;
clk_map[OUT] = output_clk_map_imx53;
+ } else if (of_device_is_compatible(np, "fsl,imx8qm-asrc0")) {
+ asrc_priv->channel_bits = 4;
+ clk_map[IN] = input_clk_map_imx8_0;
+ clk_map[OUT] = output_clk_map_imx8_0;
+ } else if (of_device_is_compatible(np, "fsl,imx8qm-asrc1")) {
+ asrc_priv->channel_bits = 4;
+ clk_map[IN] = input_clk_map_imx8_1;
+ clk_map[OUT] = output_clk_map_imx8_1;
}
ret = fsl_asrc_init(asrc_priv);
@@ -1119,6 +1159,8 @@ static const struct dev_pm_ops fsl_asrc_pm = {
static const struct of_device_id fsl_asrc_ids[] = {
{ .compatible = "fsl,imx35-asrc", },
{ .compatible = "fsl,imx53-asrc", },
+ { .compatible = "fsl,imx8qm-asrc0", },
+ { .compatible = "fsl,imx8qm-asrc1", },
{}
};
MODULE_DEVICE_TABLE(of, fsl_asrc_ids);
diff --git a/sound/soc/fsl/fsl_asrc.h b/sound/soc/fsl/fsl_asrc.h
index 034d10dc11e9..8acc68af90c4 100644
--- a/sound/soc/fsl/fsl_asrc.h
+++ b/sound/soc/fsl/fsl_asrc.h
@@ -290,7 +290,6 @@
struct dma_block {
- dma_addr_t dma_paddr;
void *dma_vaddr;
unsigned int length;
};
diff --git a/sound/soc/fsl/fsl_asrc_dma.c b/sound/soc/fsl/fsl_asrc_dma.c
index 03471afa0f99..2682af55927e 100644
--- a/sound/soc/fsl/fsl_asrc_dma.c
+++ b/sound/soc/fsl/fsl_asrc_dma.c
@@ -202,25 +202,43 @@ static int fsl_asrc_dma_hw_params(struct snd_pcm_substream *substream,
/* Get DMA request of Back-End */
tmp_chan = dma_request_slave_channel(dev_be, tx ? "tx" : "rx");
- tmp_data = tmp_chan->private;
- pair->dma_data.dma_request = tmp_data->dma_request;
- be_peripheral_type = tmp_data->peripheral_type;
- dma_release_channel(tmp_chan);
+ if (tmp_chan) {
+ tmp_data = tmp_chan->private;
+ if (tmp_data) {
+ pair->dma_data.dma_request = tmp_data->dma_request;
+ be_peripheral_type = tmp_data->peripheral_type;
+ if (tx && be_peripheral_type == IMX_DMATYPE_SSI_DUAL)
+ pair->dma_data.dst_dualfifo = true;
+ if (!tx && be_peripheral_type == IMX_DMATYPE_SSI_DUAL)
+ pair->dma_data.src_dualfifo = true;
+ }
+ dma_release_channel(tmp_chan);
+ }
/* Get DMA request of Front-End */
tmp_chan = fsl_asrc_get_dma_channel(pair, dir);
- tmp_data = tmp_chan->private;
- pair->dma_data.dma_request2 = tmp_data->dma_request;
- pair->dma_data.peripheral_type = tmp_data->peripheral_type;
- pair->dma_data.priority = tmp_data->priority;
- dma_release_channel(tmp_chan);
-
- if (tx && be_peripheral_type == IMX_DMATYPE_SSI_DUAL)
- pair->dma_data.dst_dualfifo = true;
- if (!tx && be_peripheral_type == IMX_DMATYPE_SSI_DUAL)
- pair->dma_data.src_dualfifo = true;
-
- pair->dma_chan[dir] = dma_request_channel(mask, filter, &pair->dma_data);
+ if (tmp_chan) {
+ tmp_data = tmp_chan->private;
+ if (tmp_data) {
+ pair->dma_data.dma_request2 = tmp_data->dma_request;
+ pair->dma_data.peripheral_type =
+ tmp_data->peripheral_type;
+ pair->dma_data.priority = tmp_data->priority;
+ }
+ dma_release_channel(tmp_chan);
+ }
+
+ /* For sdma DEV_TO_DEV, there is two dma request
+ * But for emda DEV_TO_DEV, there is only one dma request, which is
+ * from the BE.
+ */
+ if (pair->dma_data.dma_request2 != pair->dma_data.dma_request)
+ pair->dma_chan[dir] =
+ dma_request_channel(mask, filter, &pair->dma_data);
+ else
+ pair->dma_chan[dir] =
+ dma_request_slave_channel(dev_be, tx ? "tx" : "rx");
+
if (!pair->dma_chan[dir]) {
dev_err(dev, "failed to request DMA channel for Back-End\n");
return -EINVAL;
diff --git a/sound/soc/fsl/fsl_asrc_m2m.c b/sound/soc/fsl/fsl_asrc_m2m.c
index 7363dc003aa6..f0b335697445 100644
--- a/sound/soc/fsl/fsl_asrc_m2m.c
+++ b/sound/soc/fsl/fsl_asrc_m2m.c
@@ -134,14 +134,12 @@ static int fsl_allocate_dma_buf(struct fsl_asrc_pair *pair)
pair_err("failed to allocate input DMA buffer\n");
return -ENOMEM;
}
- input->dma_paddr = virt_to_dma(NULL, input->dma_vaddr);
output->dma_vaddr = kzalloc(output->length, GFP_KERNEL);
if (!output->dma_vaddr) {
pair_err("failed to allocate output DMA buffer\n");
goto exit;
}
- output->dma_paddr = virt_to_dma(NULL, output->dma_vaddr);
return 0;
@@ -812,6 +810,7 @@ static int fsl_asrc_open(struct inode *inode, struct file *file)
struct fsl_asrc_pair *pair;
struct fsl_asrc_m2m *m2m;
int ret;
+ int i;
ret = signal_pending(current);
if (ret) {
@@ -839,7 +838,11 @@ static int fsl_asrc_open(struct inode *inode, struct file *file)
file->private_data = pair;
- pm_runtime_get_sync(dev);
+ clk_prepare_enable(asrc_priv->mem_clk);
+ clk_prepare_enable(asrc_priv->ipg_clk);
+ clk_prepare_enable(asrc_priv->spba_clk);
+ for (i = 0; i < ASRC_CLK_MAX_NUM; i++)
+ clk_prepare_enable(asrc_priv->asrck_clk[i]);
return 0;
out:
@@ -853,8 +856,8 @@ static int fsl_asrc_close(struct inode *inode, struct file *file)
struct fsl_asrc_pair *pair = file->private_data;
struct fsl_asrc_m2m *m2m = pair->private;
struct fsl_asrc *asrc_priv = pair->asrc_priv;
- struct device *dev = &asrc_priv->pdev->dev;
unsigned long lock_flags;
+ int i;
if (m2m->asrc_active) {
m2m->asrc_active = 0;
@@ -890,7 +893,11 @@ static int fsl_asrc_close(struct inode *inode, struct file *file)
spin_unlock_irqrestore(&asrc_priv->lock, lock_flags);
file->private_data = NULL;
- pm_runtime_put_sync(dev);
+ for (i = 0; i < ASRC_CLK_MAX_NUM; i++)
+ clk_disable_unprepare(asrc_priv->asrck_clk[i]);
+ clk_disable_unprepare(asrc_priv->spba_clk);
+ clk_disable_unprepare(asrc_priv->ipg_clk);
+ clk_disable_unprepare(asrc_priv->mem_clk);
return 0;
}