^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * ALSA SoC Voice Codec Interface for TI DAVINCI processor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2010 Texas Instruments.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Author: Miguel Aguilar <miguel.aguilar@ridgerun.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/mfd/davinci_voicecodec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <sound/pcm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <sound/pcm_params.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <sound/initval.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <sound/soc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <sound/dmaengine_pcm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "edma-pcm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "davinci-i2s.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define MOD_REG_BIT(val, mask, set) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) if (set) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) val |= mask; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) } else { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) val &= ~mask; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct davinci_vcif_dev {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct davinci_vc *davinci_vc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct snd_dmaengine_dai_dma_data dma_data[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) int dma_request[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static void davinci_vcif_start(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct davinci_vcif_dev *davinci_vcif_dev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) struct davinci_vc *davinci_vc = davinci_vcif_dev->davinci_vc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) u32 w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /* Start the sample generator and enable transmitter/receiver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) w = readl(davinci_vc->base + DAVINCI_VC_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTDAC, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTADC, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) writel(w, davinci_vc->base + DAVINCI_VC_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static void davinci_vcif_stop(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct davinci_vcif_dev *davinci_vcif_dev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct davinci_vc *davinci_vc = davinci_vcif_dev->davinci_vc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) u32 w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) /* Reset transmitter/receiver and sample rate/frame sync generators */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) w = readl(davinci_vc->base + DAVINCI_VC_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTDAC, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTADC, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) writel(w, davinci_vc->base + DAVINCI_VC_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static int davinci_vcif_hw_params(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct snd_pcm_hw_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct davinci_vcif_dev *davinci_vcif_dev = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct davinci_vc *davinci_vc = davinci_vcif_dev->davinci_vc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) u32 w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /* Restart the codec before setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) davinci_vcif_stop(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) davinci_vcif_start(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) /* General line settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) writel(DAVINCI_VC_CTRL_MASK, davinci_vc->base + DAVINCI_VC_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) writel(DAVINCI_VC_INT_MASK, davinci_vc->base + DAVINCI_VC_INTCLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) writel(DAVINCI_VC_INT_MASK, davinci_vc->base + DAVINCI_VC_INTEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) w = readl(davinci_vc->base + DAVINCI_VC_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /* Determine xfer data type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) switch (params_format(params)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) case SNDRV_PCM_FORMAT_U8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) MOD_REG_BIT(w, DAVINCI_VC_CTRL_RD_BITS_8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) DAVINCI_VC_CTRL_RD_UNSIGNED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) DAVINCI_VC_CTRL_WD_BITS_8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) DAVINCI_VC_CTRL_WD_UNSIGNED, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) case SNDRV_PCM_FORMAT_S8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) MOD_REG_BIT(w, DAVINCI_VC_CTRL_RD_BITS_8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) DAVINCI_VC_CTRL_WD_BITS_8, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) MOD_REG_BIT(w, DAVINCI_VC_CTRL_RD_UNSIGNED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) DAVINCI_VC_CTRL_WD_UNSIGNED, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) case SNDRV_PCM_FORMAT_S16_LE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) MOD_REG_BIT(w, DAVINCI_VC_CTRL_RD_BITS_8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) DAVINCI_VC_CTRL_RD_UNSIGNED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) DAVINCI_VC_CTRL_WD_BITS_8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) DAVINCI_VC_CTRL_WD_UNSIGNED, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) printk(KERN_WARNING "davinci-vcif: unsupported PCM format");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) writel(w, davinci_vc->base + DAVINCI_VC_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static int davinci_vcif_trigger(struct snd_pcm_substream *substream, int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) case SNDRV_PCM_TRIGGER_RESUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) davinci_vcif_start(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) case SNDRV_PCM_TRIGGER_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) davinci_vcif_stop(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #define DAVINCI_VCIF_RATES SNDRV_PCM_RATE_8000_48000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) static const struct snd_soc_dai_ops davinci_vcif_dai_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) .trigger = davinci_vcif_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) .hw_params = davinci_vcif_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) static int davinci_vcif_dai_probe(struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) struct davinci_vcif_dev *dev = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) dai->playback_dma_data = &dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) dai->capture_dma_data = &dev->dma_data[SNDRV_PCM_STREAM_CAPTURE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) static struct snd_soc_dai_driver davinci_vcif_dai = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) .probe = davinci_vcif_dai_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) .playback = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) .rates = DAVINCI_VCIF_RATES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) .formats = SNDRV_PCM_FMTBIT_S16_LE,},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) .capture = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) .rates = DAVINCI_VCIF_RATES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) .formats = SNDRV_PCM_FMTBIT_S16_LE,},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) .ops = &davinci_vcif_dai_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) static const struct snd_soc_component_driver davinci_vcif_component = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) .name = "davinci-vcif",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static int davinci_vcif_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) struct davinci_vc *davinci_vc = pdev->dev.platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) struct davinci_vcif_dev *davinci_vcif_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) davinci_vcif_dev = devm_kzalloc(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) sizeof(struct davinci_vcif_dev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (!davinci_vcif_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) /* DMA tx params */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) davinci_vcif_dev->davinci_vc = davinci_vc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) davinci_vcif_dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].filter_data =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) &davinci_vc->davinci_vcif.dma_tx_channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) davinci_vcif_dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) davinci_vc->davinci_vcif.dma_tx_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) /* DMA rx params */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) davinci_vcif_dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].filter_data =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) &davinci_vc->davinci_vcif.dma_rx_channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) davinci_vcif_dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) davinci_vc->davinci_vcif.dma_rx_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) dev_set_drvdata(&pdev->dev, davinci_vcif_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) ret = devm_snd_soc_register_component(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) &davinci_vcif_component,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) &davinci_vcif_dai, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) dev_err(&pdev->dev, "could not register dai\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) ret = edma_pcm_platform_register(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) dev_err(&pdev->dev, "register PCM failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) static struct platform_driver davinci_vcif_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) .probe = davinci_vcif_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) .name = "davinci-vcif",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) module_platform_driver(davinci_vcif_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) MODULE_AUTHOR("Miguel Aguilar");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) MODULE_DESCRIPTION("Texas Instruments DaVinci ASoC Voice Codec Interface");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) MODULE_LICENSE("GPL");