[PATCH 007/117] ASoC: AMD: add ACP3x i2s ops
Alex Deucher
alexdeucher at gmail.com
Wed May 10 18:46:06 UTC 2017
From: Maruthi Srinivas Bayyavarapu <Maruthi.Bayyavarapu at amd.com>
ACP3x has a i2s controller block for playback and capture. This patch
adds ACP3x i2s operations.
Signed-off-by: Maruthi Bayyavarapu <maruthi.bayyavarapu at amd.com>
Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
---
sound/soc/amd/raven/acp3x-pcm-dma.c | 85 +++++++++++++++++++++++++++++++++++--
1 file changed, 82 insertions(+), 3 deletions(-)
diff --git a/sound/soc/amd/raven/acp3x-pcm-dma.c b/sound/soc/amd/raven/acp3x-pcm-dma.c
index 346ebcb..5e589dc 100644
--- a/sound/soc/amd/raven/acp3x-pcm-dma.c
+++ b/sound/soc/amd/raven/acp3x-pcm-dma.c
@@ -436,10 +436,89 @@ static struct snd_soc_platform_driver acp3x_asoc_platform = {
.pcm_new = acp3x_dma_new,
};
+static int acp3x_dai_i2s_hwparams(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ 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;
+ }
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ rv_writel((rtd->xfer_resolution << 3),
+ rtd->acp3x_base + mmACP_BTTDM_ITER);
+ else
+ rv_writel((rtd->xfer_resolution << 3),
+ 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;
+
+ 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) {
+ 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(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.5.5
More information about the amd-gfx
mailing list