ACP3x has a i2s controller block for playback and capture.
This patch adds ACP3x i2s DAI operations.
Signed-off-by: Maruthi Bayyavarapu <[email protected]>
Tested-by: Ravulapati Vishnu vardhan Rao <[email protected]>
Signed-off-by: Vijendar Mukunda <[email protected]>
---
sound/soc/amd/raven/acp3x-pcm-dma.c | 89 +++++++++++++++++++++++++++++++++++--
1 file changed, 86 insertions(+), 3 deletions(-)
diff --git a/sound/soc/amd/raven/acp3x-pcm-dma.c b/sound/soc/amd/raven/acp3x-pcm-dma.c
index 06c1985..ed2c163 100644
--- a/sound/soc/amd/raven/acp3x-pcm-dma.c
+++ b/sound/soc/amd/raven/acp3x-pcm-dma.c
@@ -423,10 +423,93 @@ static struct snd_pcm_ops acp3x_dma_ops = {
.mmap = acp3x_dma_mmap,
};
+static int acp3x_dai_i2s_hwparams(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ u32 val = 0;
+ struct i2s_stream_instance *rtd = substream->runtime->private_data;
+
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_U8:
+ case SNDRV_PCM_FORMAT_S8:
+ rtd->xfer_resolution = 0x0;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ rtd->xfer_resolution = 0x02;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ rtd->xfer_resolution = 0x04;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ rtd->xfer_resolution = 0x05;
+ break;
+ default:
+ return -EINVAL;
+ }
+ val = rv_readl(rtd->acp3x_base + mmACP_BTTDM_ITER);
+ val = val | (rtd->xfer_resolution << 3);
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_ITER);
+ else
+ rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_IRER);
+
+ return 0;
+}
+
+static int acp3x_dai_i2s_trigger(struct snd_pcm_substream *substream,
+ int cmd, struct snd_soc_dai *dai)
+{
+ int ret = 0;
+ struct i2s_stream_instance *rtd = substream->runtime->private_data;
+ u32 val, period_bytes;
+
+ period_bytes = frames_to_bytes(substream->runtime,
+ substream->runtime->period_size);
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ rv_writel(period_bytes, rtd->acp3x_base +
+ mmACP_BT_TX_INTR_WATERMARK_SIZE);
+ val = rv_readl(rtd->acp3x_base + mmACP_BTTDM_ITER);
+ val = val | BIT(0);
+ rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_ITER);
+ } else {
+ rv_writel(period_bytes, rtd->acp3x_base +
+ mmACP_BT_RX_INTR_WATERMARK_SIZE);
+ val = rv_readl(rtd->acp3x_base + mmACP_BTTDM_IRER);
+ val = val | BIT(0);
+ rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_IRER);
+ }
+ rv_writel(1, rtd->acp3x_base + mmACP_BTTDM_IER);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ val = rv_readl(rtd->acp3x_base + mmACP_BTTDM_ITER);
+ val = val & ~BIT(0);
+ rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_ITER);
+ } else {
+ val = rv_readl(rtd->acp3x_base + mmACP_BTTDM_IRER);
+ val = val & ~BIT(0);
+ rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_IRER);
+ }
+ rv_writel(0, rtd->acp3x_base + mmACP_BTTDM_IER);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
struct snd_soc_dai_ops acp3x_dai_i2s_ops = {
- .hw_params = NULL,
- .trigger = NULL,
- .set_fmt = NULL,
+ .hw_params = acp3x_dai_i2s_hwparams,
+ .trigger = acp3x_dai_i2s_trigger,
};
static struct snd_soc_dai_driver acp3x_i2s_dai_driver = {
--
2.7.4
The patch
ASoC: amd: add acp3x i2s ops
has been applied to the asoc tree at
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
From 2b5f290e10266037338631c03ab6bea51f0a7ebf Mon Sep 17 00:00:00 2001
From: Vijendar Mukunda <[email protected]>
Date: Mon, 12 Nov 2018 11:04:58 +0530
Subject: [PATCH] ASoC: amd: add acp3x i2s ops
ACP3x has a i2s controller block for playback and capture.
This patch adds ACP3x i2s DAI operations.
Signed-off-by: Maruthi Bayyavarapu <[email protected]>
Tested-by: Ravulapati Vishnu vardhan Rao <[email protected]>
Signed-off-by: Vijendar Mukunda <[email protected]>
Signed-off-by: Mark Brown <[email protected]>
---
sound/soc/amd/raven/acp3x-pcm-dma.c | 89 ++++++++++++++++++++++++++++-
1 file changed, 86 insertions(+), 3 deletions(-)
diff --git a/sound/soc/amd/raven/acp3x-pcm-dma.c b/sound/soc/amd/raven/acp3x-pcm-dma.c
index 06c1985c4d56..ed2c16379d2c 100644
--- a/sound/soc/amd/raven/acp3x-pcm-dma.c
+++ b/sound/soc/amd/raven/acp3x-pcm-dma.c
@@ -423,10 +423,93 @@ static struct snd_pcm_ops acp3x_dma_ops = {
.mmap = acp3x_dma_mmap,
};
+static int acp3x_dai_i2s_hwparams(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ u32 val = 0;
+ struct i2s_stream_instance *rtd = substream->runtime->private_data;
+
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_U8:
+ case SNDRV_PCM_FORMAT_S8:
+ rtd->xfer_resolution = 0x0;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ rtd->xfer_resolution = 0x02;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ rtd->xfer_resolution = 0x04;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ rtd->xfer_resolution = 0x05;
+ break;
+ default:
+ return -EINVAL;
+ }
+ val = rv_readl(rtd->acp3x_base + mmACP_BTTDM_ITER);
+ val = val | (rtd->xfer_resolution << 3);
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_ITER);
+ else
+ rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_IRER);
+
+ return 0;
+}
+
+static int acp3x_dai_i2s_trigger(struct snd_pcm_substream *substream,
+ int cmd, struct snd_soc_dai *dai)
+{
+ int ret = 0;
+ struct i2s_stream_instance *rtd = substream->runtime->private_data;
+ u32 val, period_bytes;
+
+ period_bytes = frames_to_bytes(substream->runtime,
+ substream->runtime->period_size);
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ rv_writel(period_bytes, rtd->acp3x_base +
+ mmACP_BT_TX_INTR_WATERMARK_SIZE);
+ val = rv_readl(rtd->acp3x_base + mmACP_BTTDM_ITER);
+ val = val | BIT(0);
+ rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_ITER);
+ } else {
+ rv_writel(period_bytes, rtd->acp3x_base +
+ mmACP_BT_RX_INTR_WATERMARK_SIZE);
+ val = rv_readl(rtd->acp3x_base + mmACP_BTTDM_IRER);
+ val = val | BIT(0);
+ rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_IRER);
+ }
+ rv_writel(1, rtd->acp3x_base + mmACP_BTTDM_IER);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ val = rv_readl(rtd->acp3x_base + mmACP_BTTDM_ITER);
+ val = val & ~BIT(0);
+ rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_ITER);
+ } else {
+ val = rv_readl(rtd->acp3x_base + mmACP_BTTDM_IRER);
+ val = val & ~BIT(0);
+ rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_IRER);
+ }
+ rv_writel(0, rtd->acp3x_base + mmACP_BTTDM_IER);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
struct snd_soc_dai_ops acp3x_dai_i2s_ops = {
- .hw_params = NULL,
- .trigger = NULL,
- .set_fmt = NULL,
+ .hw_params = acp3x_dai_i2s_hwparams,
+ .trigger = acp3x_dai_i2s_trigger,
};
static struct snd_soc_dai_driver acp3x_i2s_dai_driver = {
--
2.19.1