^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Rockchip VAD driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2018 Fuzhou Rockchip Electronics Co., Ltd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <sound/pcm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <sound/pcm_params.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <sound/soc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "rockchip_vad.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "rockchip_multi_dais.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "vad_preprocess.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define DRV_NAME "rockchip-vad"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define VAD_RATES SNDRV_PCM_RATE_8000_192000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define VAD_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) SNDRV_PCM_FMTBIT_S20_3LE | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) SNDRV_PCM_FMTBIT_S24_LE | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) SNDRV_PCM_FMTBIT_S32_LE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define ACODEC_REG_NUM 28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define CHUNK_SIZE 64 /* bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static struct snd_pcm_substream *vad_substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static unsigned int voice_inactive_frames;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) module_param(voice_inactive_frames, uint, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) MODULE_PARM_DESC(voice_inactive_frames, "voice inactive frame count");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) enum rk_vad_version {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) VAD_RK1808ES = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) VAD_RK1808,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) VAD_RK3308,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) struct vad_buf {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) void __iomem *begin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) void __iomem *end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) void __iomem *cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) void __iomem *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) int loop_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) bool loop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) bool sorted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct audio_src_addr_map {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) u32 id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) u32 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct vad_soc_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) enum rk_vad_version version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) const struct audio_src_addr_map *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct rockchip_vad {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct device_node *audio_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct clk *hclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) unsigned int memphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) unsigned int memphy_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) void __iomem *membase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) struct vad_buf vbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct vad_params params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) struct vad_uparams uparams;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct snd_soc_dai *cpu_dai;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct snd_pcm_substream *substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct vad_soc_data *soc_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) int mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) u32 audio_src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) u32 audio_src_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) u32 audio_chnl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) u32 channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) u32 sample_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) u32 buffer_time; /* msec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) struct dentry *debugfs_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) void *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) bool acodec_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) bool vswitch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) bool h_16bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) enum rk_vad_version version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static inline int vframe_size(struct rockchip_vad *vad, int bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) return bytes / vad->channels / vad->sample_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static int chunk_sort(void __iomem *pos, void __iomem *end, int loop_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) char tbuf[CHUNK_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) int size1, size2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) size1 = loop_cnt * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) size2 = CHUNK_SIZE - size1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) while (pos < end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) memcpy_fromio(&tbuf[0], pos + size1, size2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) memcpy_fromio(&tbuf[size2], pos, size1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) memcpy_toio(pos, &tbuf[0], CHUNK_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) pos += CHUNK_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static int vad_buffer_sort(struct rockchip_vad *vad)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct vad_buf *vbuf = &vad->vbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) int loop_cnt = vbuf->loop_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (vad->version != VAD_RK1808ES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (vbuf->sorted || !vbuf->loop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) /* 16 words align */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if ((vbuf->pos - vbuf->begin) % CHUNK_SIZE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) (vbuf->end - vbuf->pos) % CHUNK_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) switch (loop_cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) loop_cnt = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) chunk_sort(vbuf->pos, vbuf->end, loop_cnt - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) vbuf->sorted = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) chunk_sort(vbuf->begin, vbuf->pos, loop_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) vbuf->sorted = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) case 2 ... 15:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) chunk_sort(vbuf->pos, vbuf->end, loop_cnt - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) chunk_sort(vbuf->begin, vbuf->pos, loop_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) vbuf->sorted = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) static int rockchip_vad_stop(struct rockchip_vad *vad)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) unsigned int val, frames;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct vad_buf *vbuf = &vad->vbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) struct vad_params *params = &vad->params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) regmap_read(vad->regmap, VAD_CTRL, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if ((val & VAD_EN_MASK) == VAD_DISABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /* sample cnt will be clear after vad disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (vad->version == VAD_RK1808ES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) regmap_read(vad->regmap, VAD_SAMPLE_CNT, &frames);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) regmap_update_bits(vad->regmap, VAD_CTRL, VAD_EN_MASK, VAD_DISABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) regmap_read(vad->regmap, VAD_CTRL, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) vad->h_16bit = (val & AUDIO_24BIT_SAT_MASK) == AUDIO_H16B;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) regmap_read(vad->regmap, VAD_RAM_END_ADDR, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) vbuf->end = vbuf->begin + (val - vad->memphy) + 0x8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) regmap_read(vad->regmap, VAD_INT, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) val &= BIT(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) vbuf->loop = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) regmap_read(vad->regmap, VAD_RAM_CUR_ADDR, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (!val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) vbuf->size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) vbuf->cur = vbuf->begin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) vbuf->cur = vbuf->begin + (val - vad->memphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (vbuf->loop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) vbuf->size = vbuf->end - vbuf->begin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) vbuf->pos = vbuf->cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) vbuf->size = vbuf->cur - vbuf->begin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) vbuf->end = vbuf->cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) vbuf->pos = vbuf->begin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (vad->version == VAD_RK1808ES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) vbuf->loop_cnt = (frames / vframe_size(vad, vbuf->size)) % 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) /* due to get loop_cnt before vad disable, we should take
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * the boundary issue into account, and judge whether the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * loop_cnt change to loop_cnt + 1 or not when vad disable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (vbuf->loop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) frames = frames % vframe_size(vad, vbuf->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) val = vframe_size(vad, vbuf->pos - vbuf->begin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if (frames > val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) vbuf->loop_cnt = (vbuf->loop_cnt + 1) % 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) vbuf->sorted = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) regmap_read(vad->regmap, VAD_DET_CON0, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) params->noise_level = (val & NOISE_LEVEL_MASK) >> NOISE_LEVEL_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) params->vad_con_thd = (val & VAD_CON_THD_MASK) >> VAD_CON_THD_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) params->voice_gain = (val & GAIN_MASK) >> GAIN_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) regmap_read(vad->regmap, VAD_DET_CON1, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) params->sound_thd = val & SOUND_THD_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) regmap_read(vad->regmap, VAD_DET_CON5, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) params->noise_abs = val & NOISE_ABS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) vad_preprocess_init(params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) voice_inactive_frames = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) dev_info(vad->dev, "bufsize: %d, hw_abs: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) vbuf->size, params->noise_abs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) static int rockchip_vad_setup(struct rockchip_vad *vad)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) struct regmap *regmap = vad->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) u32 val, mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) dev_info(vad->dev, "sw_abs: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) vad->uparams.noise_abs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) regmap_update_bits(regmap, VAD_DET_CON5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) NOISE_ABS_MASK, vad->uparams.noise_abs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) regmap_update_bits(regmap, VAD_CTRL, VAD_EN_MASK, VAD_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) val = ERR_INT_EN | VAD_DET_INT_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) mask = ERR_INT_EN_MASK | VAD_DET_INT_EN_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) regmap_update_bits(regmap, VAD_INT, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) vad_preprocess_destroy();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) static struct rockchip_vad *substream_get_drvdata(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) struct snd_soc_pcm_runtime *rtd = substream->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct rockchip_vad *vad = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (!rtd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) for (i = 0; i < rtd->num_codecs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (strstr(codec_dai->name, "vad"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) vad = snd_soc_component_get_drvdata(codec_dai->component);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return vad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * snd_pcm_vad_avail - Get the available (readable) space for vad
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) * @runtime: PCM substream instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * Result is between 0 ... (boundary - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) snd_pcm_uframes_t snd_pcm_vad_avail(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) struct rockchip_vad *vad = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) struct vad_buf *vbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) snd_pcm_uframes_t vframes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) vad = substream_get_drvdata(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if (!vad)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) vbuf = &vad->vbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (vbuf->size <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) vframes = samples_to_bytes(runtime, vad->channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (vframes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) vframes = vbuf->size / vframes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (!vframes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) dev_err(vad->dev, "residue bytes: %d\n", vbuf->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return vframes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) EXPORT_SYMBOL(snd_pcm_vad_avail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) snd_pcm_sframes_t snd_pcm_vad_read(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) void __user *buf, snd_pcm_uframes_t frames)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) struct rockchip_vad *vad = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) struct vad_buf *vbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) snd_pcm_uframes_t avail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) int bytes, vbytes, frame_sz, vframe_sz, padding_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) void *pbuf, *sbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) vad = substream_get_drvdata(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (!vad)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) vbuf = &vad->vbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) avail = snd_pcm_vad_avail(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) avail = avail > frames ? frames : avail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) bytes = frames_to_bytes(runtime, avail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (bytes <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) if (vad_buffer_sort(vad) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) dev_err(vad->dev, "buffer sort failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (!vad->buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) vad->buf = kzalloc(bytes, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) if (!vad->buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) frame_sz = frames_to_bytes(runtime, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) vframe_sz = samples_to_bytes(runtime, vad->channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) padding_sz = frame_sz - vframe_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) vbytes = vframe_sz * avail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) sbuf = vad->buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) pbuf = vad->buf + bytes - vbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (!vbuf->loop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) memcpy_fromio(pbuf, vbuf->pos, vbytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) vbuf->pos += vbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) if ((vbuf->pos + vbytes) <= vbuf->end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) memcpy_fromio(pbuf, vbuf->pos, vbytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) vbuf->pos += vbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) int part1 = vbuf->end - vbuf->pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) int part2 = vbytes - part1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) memcpy_fromio(pbuf, vbuf->pos, part1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) memcpy_fromio(pbuf + part1, vbuf->begin, part2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) vbuf->pos = vbuf->begin + part2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (padding_sz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) for (i = 0; i < avail; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) memmove(sbuf, pbuf, vframe_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) sbuf += vframe_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) pbuf += vframe_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) memset(sbuf, 0x0, padding_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) sbuf += padding_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if (copy_to_user(buf, vad->buf, bytes))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) vbuf->size -= vbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) if (vbuf->size <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) kfree(vad->buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) vad->buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) return avail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) EXPORT_SYMBOL(snd_pcm_vad_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) int snd_pcm_vad_preprocess(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) void *buf, snd_pcm_uframes_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) struct rockchip_vad *vad = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) s16 *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) vad = substream_get_drvdata(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (!vad)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) buf += samples_to_bytes(runtime, vad->audio_chnl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) /* retrieve the high 16bit data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (runtime->sample_bits == 32 && vad->h_16bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) buf += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) for (i = 0; i < size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) data = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (vad_preprocess(*data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) voice_inactive_frames = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) voice_inactive_frames++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) buf += frames_to_bytes(runtime, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) vad_preprocess_update_params(&vad->uparams);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) EXPORT_SYMBOL(snd_pcm_vad_preprocess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) * snd_pcm_vad_attached - Check whether vad is attached to substream or not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) * @substream: PCM substream instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) * Result is true for attached or false for detached
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) bool snd_pcm_vad_attached(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) struct rockchip_vad *vad = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) if (vad_substream == substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) vad = substream_get_drvdata(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (vad && vad->vswitch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) EXPORT_SYMBOL(snd_pcm_vad_attached);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) static int vad_memcpy_fromio(void *to, void __iomem *from,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) int size, int frame_sz, int padding_sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) int i, step_src, step_dst, fcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) step_src = frame_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) step_dst = frame_sz + padding_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) if (size % frame_sz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) pr_err("%s: invalid size: %d\n", __func__, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) fcount = size / frame_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (padding_sz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) for (i = 0; i < fcount; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) memcpy_fromio(to, from, frame_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) to += step_dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) from += step_src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) memcpy_fromio(to, from, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) * snd_pcm_vad_memcpy - Copy vad data to dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) * @substream: PCM substream instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) * @buf: dst buf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) * @frames: size in frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) * Result is copied frames for success or errno for fail
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) snd_pcm_sframes_t snd_pcm_vad_memcpy(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) void *buf, snd_pcm_uframes_t frames)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) struct rockchip_vad *vad = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) struct vad_buf *vbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) snd_pcm_uframes_t avail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) int bytes, vbytes, frame_sz, vframe_sz, padding_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) vad = substream_get_drvdata(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) if (!vad)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) vbuf = &vad->vbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) avail = snd_pcm_vad_avail(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) avail = avail > frames ? frames : avail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) bytes = frames_to_bytes(runtime, avail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (bytes <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (vad_buffer_sort(vad) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) dev_err(vad->dev, "buffer sort failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) frame_sz = frames_to_bytes(runtime, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) vframe_sz = samples_to_bytes(runtime, vad->channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) padding_sz = frame_sz - vframe_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) vbytes = vframe_sz * avail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) memset(buf, 0x0, bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (!vbuf->loop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) vad_memcpy_fromio(buf, vbuf->pos, vbytes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) vframe_sz, padding_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) vbuf->pos += vbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) if ((vbuf->pos + vbytes) <= vbuf->end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) vad_memcpy_fromio(buf, vbuf->pos, vbytes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) vframe_sz, padding_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) vbuf->pos += vbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) int part1 = vbuf->end - vbuf->pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) int part2 = vbytes - part1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) int offset = part1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) if (padding_sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) offset = part1 / vframe_sz * frame_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) vad_memcpy_fromio(buf, vbuf->pos, part1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) vframe_sz, padding_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) vad_memcpy_fromio(buf + offset, vbuf->begin, part2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) vframe_sz, padding_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) vbuf->pos = vbuf->begin + part2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) vbuf->size -= vbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) return avail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) EXPORT_SYMBOL(snd_pcm_vad_memcpy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) static bool rockchip_vad_writeable_reg(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) static bool rockchip_vad_readable_reg(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) static bool rockchip_vad_volatile_reg(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) case VAD_INT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) case VAD_RAM_CUR_ADDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) case VAD_DET_CON5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) case VAD_SAMPLE_CNT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) static const struct reg_default rk1808_vad_reg_defaults[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) {VAD_CTRL, 0x03000000},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) {VAD_DET_CON0, 0x01024008},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) {VAD_DET_CON1, 0x04ff0064},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) {VAD_DET_CON2, 0x3bf5e663},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) {VAD_DET_CON3, 0x3bf58817},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) {VAD_DET_CON4, 0x382b8858},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) static const struct reg_default rk3308_vad_reg_defaults[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) {VAD_CTRL, 0x03000000},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) {VAD_DET_CON0, 0x00024020},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) {VAD_DET_CON1, 0x00ff0064},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) {VAD_DET_CON2, 0x3bf5e663},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) {VAD_DET_CON3, 0x3bf58817},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) {VAD_DET_CON4, 0x382b8858},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) {VAD_RAM_BEGIN_ADDR, 0xfff88000},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) {VAD_RAM_END_ADDR, 0xfffbfff8},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) static const struct regmap_config rk1808_vad_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) .reg_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) .reg_stride = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) .val_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) .max_register = VAD_NOISE_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) .reg_defaults = rk1808_vad_reg_defaults,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) .num_reg_defaults = ARRAY_SIZE(rk1808_vad_reg_defaults),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) .writeable_reg = rockchip_vad_writeable_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) .readable_reg = rockchip_vad_readable_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) .volatile_reg = rockchip_vad_volatile_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) .cache_type = REGCACHE_FLAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) static const struct regmap_config rk3308_vad_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) .reg_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) .reg_stride = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) .val_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) .max_register = VAD_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) .reg_defaults = rk3308_vad_reg_defaults,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) .num_reg_defaults = ARRAY_SIZE(rk3308_vad_reg_defaults),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) .writeable_reg = rockchip_vad_writeable_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) .readable_reg = rockchip_vad_readable_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) .volatile_reg = rockchip_vad_volatile_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) .cache_type = REGCACHE_FLAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) static const struct audio_src_addr_map rk1808_addr_map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) { 1, RK1808_I2S0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) { 3, RK1808_I2S1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) { 4, RK1808_PDM },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) { /* sentinel */ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) static const struct audio_src_addr_map rk3308_addr_map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) { 0, RK3308_I2S_8CH_0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) { 1, RK3308_I2S_8CH_1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) { 2, RK3308_I2S_8CH_2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) { 3, RK3308_I2S_8CH_3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) { 4, RK3308_PDM_8CH },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) { /* sentinel */ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) static const struct audio_src_addr_map rk3568_addr_map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) { 0, RK3568_I2S_8CH_1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) { 1, RK3568_I2S_2CH_2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) { 2, RK3568_I2S_2CH_3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) { 3, RK3568_PDM },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) { /* sentinel */ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) static const struct audio_src_addr_map rk3588_addr_map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) { 0, RK3588_PDM0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) { 1, RK3588_I2S1_8CH },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) { /* sentinel */ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) static const struct vad_soc_data rk1808es_soc_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) .version = VAD_RK1808ES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) .map = rk1808_addr_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) static const struct vad_soc_data rk1808_soc_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) .version = VAD_RK1808,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) .map = rk1808_addr_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) static const struct vad_soc_data rk3308_soc_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) .version = VAD_RK3308,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) .map = rk3308_addr_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) static const struct vad_soc_data rk3568_soc_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) .version = VAD_RK1808,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) .map = rk3568_addr_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) static const struct vad_soc_data rk3588_soc_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) .version = VAD_RK1808,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) .map = rk3588_addr_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) static int rockchip_vad_get_audio_src_address(struct rockchip_vad *vad,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) u32 addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) const struct audio_src_addr_map *map = vad->soc_data->map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) for (; map->addr; map++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) if ((map->addr & 0xffff0000) == addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) vad->audio_src = map->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) vad->audio_src_addr = map->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) static irqreturn_t rockchip_vad_irq(int irqno, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) struct rockchip_vad *vad = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) regmap_read(vad->regmap, VAD_INT, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) regmap_write(vad->regmap, VAD_INT, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) dev_dbg(vad->dev, "irq 0x%08x\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) static const struct reg_sequence rockchip_vad_acodec_adc_enable[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) { VAD_OD_ADDR0, 0x36261606 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) { VAD_D_DATA0, 0x51515151 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) { VAD_OD_ADDR1, 0x30201000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) { VAD_D_DATA1, 0xbbbbbbbb },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) { VAD_OD_ADDR2, 0x32221202 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) { VAD_D_DATA2, 0x11111111 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) { VAD_OD_ADDR3, 0x35251505 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) { VAD_D_DATA3, 0x77777777 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) { VAD_OD_ADDR4, 0x32221202 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) { VAD_D_DATA4, 0x33333333 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) { VAD_OD_ADDR5, 0x30201000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) { VAD_D_DATA5, 0xffffffff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) { VAD_OD_ADDR6, 0x32221202 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) { VAD_D_DATA6, 0x77777777 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) static int rockchip_vad_config_acodec(struct snd_pcm_hw_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) struct snd_soc_component *component = dai->component;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) struct rockchip_vad *vad = snd_soc_component_get_drvdata(component);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) unsigned int val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) if (!vad->acodec_cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) val = ACODEC_BASE + ACODEC_ADC_ANA_CON0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) regmap_write(vad->regmap, VAD_ID_ADDR, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) regmap_multi_reg_write(vad->regmap, rockchip_vad_acodec_adc_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) ARRAY_SIZE(rockchip_vad_acodec_adc_enable));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) regmap_update_bits(vad->regmap, VAD_CTRL, ACODE_CFG_REG_NUM_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) ACODE_CFG_REG_NUM(ACODEC_REG_NUM));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) regmap_update_bits(vad->regmap, VAD_CTRL, CFG_ACODE_AFTER_DET_EN_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) CFG_ACODE_AFTER_DET_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) static struct snd_soc_dai *rockchip_vad_find_dai(struct device_node *np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) struct snd_soc_dai_link_component dai_component = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) dai_component.of_node = np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) return snd_soc_find_dai(&dai_component);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) static void hw_refine_channels(struct snd_pcm_hw_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) unsigned int channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) struct snd_interval *c =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) c->min = channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) c->max = channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) static void rockchip_vad_params_fixup(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) struct snd_pcm_hw_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) struct rockchip_vad *vad = snd_soc_component_get_drvdata(dai->component);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) struct snd_soc_pcm_runtime *rtd = substream->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) struct snd_soc_dai *cpu_dai, *audio_src_dai;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) struct rk_mdais_dev *mdais;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) unsigned int *channel_maps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) cpu_dai = asoc_rtd_to_cpu(rtd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) vad->cpu_dai = cpu_dai;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) vad->substream = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) np = cpu_dai->dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) if (of_device_is_compatible(np, "rockchip,multi-dais")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) audio_src_dai = rockchip_vad_find_dai(vad->audio_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) mdais = snd_soc_dai_get_drvdata(cpu_dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) channel_maps = mdais->capture_channel_maps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) for (i = 0; i < mdais->num_dais; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) if (audio_src_dai == mdais->dais[i].dai &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) channel_maps[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) hw_refine_channels(params, channel_maps[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) static int rockchip_vad_hw_params(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) struct snd_pcm_hw_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) struct snd_soc_component *component = dai->component;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) struct rockchip_vad *vad = snd_soc_component_get_drvdata(component);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) unsigned int val = 0, mask = 0, frame_bytes, buf_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) rockchip_vad_params_fixup(substream, params, dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) vad->channels = params_channels(params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) switch (params_format(params)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) case SNDRV_PCM_FORMAT_S16_LE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) val = AUDIO_CHNL_16B;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) vad->sample_bytes = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) case SNDRV_PCM_FORMAT_S24_LE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) case SNDRV_PCM_FORMAT_S32_LE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) val = AUDIO_CHNL_24B;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) vad->sample_bytes = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) regmap_update_bits(vad->regmap, VAD_CTRL, AUDIO_CHNL_BW_MASK, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) regmap_update_bits(vad->regmap, VAD_CTRL, AUDIO_CHNL_NUM_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) AUDIO_CHNL_NUM(params_channels(params)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) val = SRC_ADDR_MODE_INC | SRC_BURST_INCR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) mask = SRC_ADDR_MODE_MASK | SRC_BURST_MASK | INCR_BURST_LEN_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) switch (params_channels(params)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) /* fallthrough */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) /* fallthrough */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) /* fallthrough */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) val |= INCR_BURST_LEN(params_channels(params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) if (vad->version == VAD_RK1808ES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) val = SRC_ADDR_MODE_INC | SRC_BURST_INCR16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) mask = SRC_ADDR_MODE_MASK | SRC_BURST_MASK | SRC_BURST_NUM_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) if (params_channels(params) == 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) val |= SRC_BURST_NUM(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) regmap_update_bits(vad->regmap, VAD_CTRL, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) /* calculate buffer space according buffer time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) if (vad->buffer_time) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) frame_bytes = snd_pcm_format_size(params_format(params),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) params_channels(params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) buf_time = vad->memphy_end - vad->memphy + 0x8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) buf_time *= 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) buf_time /= (frame_bytes * params_rate(params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) if (buf_time < vad->buffer_time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) dev_info(vad->dev, "max buffer time: %u ms.\n", buf_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) buf_time = min(buf_time, vad->buffer_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) val = params_rate(params) * buf_time / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) if (vad->version == VAD_RK1808ES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) val &= ~0xf; /* 16 align */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) val *= frame_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) val += vad->memphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) val -= 0x8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) if (val < vad->memphy || val > vad->memphy_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) regmap_write(vad->regmap, VAD_RAM_END_ADDR, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) * config acodec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) * audio_src 2/3 is connected to acodec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) val = vad->audio_src >> AUDIO_SRC_SEL_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) if (val == 2 || val == 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) rockchip_vad_config_acodec(params, dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) static int rockchip_vad_enable_cpudai(struct rockchip_vad *vad)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) struct snd_soc_dai *cpu_dai;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) struct snd_pcm_substream *substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) cpu_dai = vad->cpu_dai;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) substream = vad->substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) if (!cpu_dai || !substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) pm_runtime_get_sync(cpu_dai->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) if (cpu_dai->driver->ops) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) if (cpu_dai->driver->ops->startup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) ret = cpu_dai->driver->ops->startup(substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) cpu_dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) if (cpu_dai->driver->ops->prepare)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) ret |= cpu_dai->driver->ops->prepare(substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) cpu_dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) if (cpu_dai->driver->ops->trigger)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) ret |= cpu_dai->driver->ops->trigger(substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) SNDRV_PCM_TRIGGER_START,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) cpu_dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) static int rockchip_vad_disable_cpudai(struct rockchip_vad *vad)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) struct snd_soc_dai *cpu_dai;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) struct snd_pcm_substream *substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) cpu_dai = vad->cpu_dai;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) substream = vad->substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) if (!cpu_dai || !substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) pm_runtime_get_sync(cpu_dai->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) if (cpu_dai->driver->ops && cpu_dai->driver->ops->trigger)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) ret = cpu_dai->driver->ops->trigger(substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) SNDRV_PCM_TRIGGER_STOP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) cpu_dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) pm_runtime_put(cpu_dai->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) static int rockchip_vad_pcm_startup(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) vad_substream = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) static void rockchip_vad_pcm_shutdown(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) struct snd_soc_component *component = dai->component;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) struct rockchip_vad *vad = snd_soc_component_get_drvdata(component);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) if (vad->vswitch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) rockchip_vad_enable_cpudai(vad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) rockchip_vad_setup(vad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) vad_substream = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) static int rockchip_vad_trigger(struct snd_pcm_substream *substream, int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) struct snd_soc_component *component = dai->component;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) struct rockchip_vad *vad = snd_soc_component_get_drvdata(component);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) case SNDRV_PCM_TRIGGER_RESUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) rockchip_vad_stop(vad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) case SNDRV_PCM_TRIGGER_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) static struct snd_soc_dai_ops rockchip_vad_dai_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) .hw_params = rockchip_vad_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) .shutdown = rockchip_vad_pcm_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) .startup = rockchip_vad_pcm_startup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) .trigger = rockchip_vad_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) static struct snd_soc_dai_driver vad_dai = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) .name = "vad",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) .playback = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) .stream_name = "Playback",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) .channels_max = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) .rates = VAD_RATES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) .formats = VAD_FORMATS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) .capture = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) .stream_name = "Capture",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) .channels_max = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) .rates = VAD_RATES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) .formats = VAD_FORMATS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) .ops = &rockchip_vad_dai_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) static int rockchip_vad_switch_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) uinfo->value.integer.max = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) static int rockchip_vad_switch_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) struct rockchip_vad *vad = snd_soc_component_get_drvdata(component);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) ucontrol->value.integer.value[0] = vad->vswitch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) static int rockchip_vad_switch_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) struct rockchip_vad *vad = snd_soc_component_get_drvdata(component);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) val = ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) if (val && !vad->vswitch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) vad->vswitch = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) } else if (!val && vad->vswitch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) vad->vswitch = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) regmap_read(vad->regmap, VAD_CTRL, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) if ((val & VAD_EN_MASK) == VAD_DISABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) rockchip_vad_stop(vad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) rockchip_vad_disable_cpudai(vad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) /* this case we don't need vad data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) vad->vbuf.size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) #define SOC_ROCKCHIP_VAD_SWITCH_DECL(xname) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) .info = rockchip_vad_switch_info, .get = rockchip_vad_switch_get, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) .put = rockchip_vad_switch_put, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) static const struct snd_kcontrol_new rockchip_vad_dapm_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) SOC_ROCKCHIP_VAD_SWITCH_DECL("vad switch"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) static const struct snd_soc_component_driver soc_vad_codec = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) .controls = rockchip_vad_dapm_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) .num_controls = ARRAY_SIZE(rockchip_vad_dapm_controls),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) #if defined(CONFIG_DEBUG_FS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) #include <linux/debugfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) static int rockchip_vad_debugfs_reg_show(struct seq_file *s, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) struct rockchip_vad *vad = s->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) unsigned int max_register;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) if (vad->version == VAD_RK1808 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) vad->version == VAD_RK1808ES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) max_register = VAD_NOISE_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) max_register = VAD_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) for (i = VAD_CTRL; i <= max_register; i += 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) regmap_read(vad->regmap, i, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) if (!(i % 16))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) seq_printf(s, "\n%08x: ", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) seq_printf(s, "%08x ", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) static ssize_t rockchip_vad_debugfs_reg_write(struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) struct rockchip_vad *vad = ((struct seq_file *)file->private_data)->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) unsigned int reg, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) char kbuf[24];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) if (count >= sizeof(kbuf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) if (copy_from_user(kbuf, buf, count))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) kbuf[count] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) if (sscanf(kbuf, "%x %x", ®, &val) != 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) regmap_write(vad->regmap, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) static int rockchip_vad_debugfs_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) return single_open(file, rockchip_vad_debugfs_reg_show, inode->i_private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) static const struct file_operations rockchip_vad_reg_debugfs_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) .open = rockchip_vad_debugfs_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) .read = seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) .write = rockchip_vad_debugfs_reg_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) .llseek = seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) .release = single_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) static void rockchip_vad_init(struct rockchip_vad *vad)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) unsigned int val, mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) regmap_write(vad->regmap, VAD_RAM_BEGIN_ADDR, vad->memphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) regmap_write(vad->regmap, VAD_RAM_END_ADDR, vad->memphy_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) vad->vbuf.begin = vad->membase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) regmap_write(vad->regmap, VAD_IS_ADDR, vad->audio_src_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) val = VAD_DET_CHNL(vad->audio_chnl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) val |= vad->audio_src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) val |= vad->mode << VAD_MODE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) mask = VAD_DET_CHNL_MASK | AUDIO_SRC_SEL_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) VAD_MODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) regmap_update_bits(vad->regmap, VAD_CTRL, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) if (vad->version == VAD_RK1808 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) vad->version == VAD_RK1808ES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) regmap_update_bits(vad->regmap, VAD_AUX_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) RAM_ITF_EN_MASK | BUS_WRITE_EN_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) RAM_ITF_DIS | BUS_WRITE_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) regmap_update_bits(vad->regmap, VAD_AUX_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) SAMPLE_CNT_EN_MASK, SAMPLE_CNT_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) static const struct of_device_id rockchip_vad_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) { .compatible = "rockchip,rk1808es-vad", .data = &rk1808es_soc_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) { .compatible = "rockchip,rk1808-vad", .data = &rk1808_soc_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) { .compatible = "rockchip,rk3308-vad", .data = &rk3308_soc_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) { .compatible = "rockchip,rk3568-vad", .data = &rk3568_soc_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) { .compatible = "rockchip,rk3588-vad", .data = &rk3588_soc_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) static int rockchip_vad_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) struct device_node *np = pdev->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) struct device_node *asrc_np = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) struct device_node *sram_np = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) const struct of_device_id *match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) const struct regmap_config *regmap_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) struct rockchip_vad *vad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) struct resource audio_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) struct resource sram_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) void __iomem *regbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) vad = devm_kzalloc(&pdev->dev, sizeof(*vad), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) if (!vad)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) vad->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) match = of_match_device(rockchip_vad_match, &pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) if (!match || !match->data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) vad->soc_data = (struct vad_soc_data *)match->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) vad->version = vad->soc_data->version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) switch (vad->version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) case VAD_RK1808:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) case VAD_RK1808ES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) regmap_config = &rk1808_vad_regmap_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) case VAD_RK3308:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) regmap_config = &rk3308_vad_regmap_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) vad->acodec_cfg = of_property_read_bool(np, "rockchip,acodec-cfg");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) of_property_read_u32(np, "rockchip,mode", &vad->mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) of_property_read_u32(np, "rockchip,det-channel", &vad->audio_chnl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) of_property_read_u32(np, "rockchip,buffer-time-ms", &vad->buffer_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vad");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) regbase = devm_ioremap_resource(&pdev->dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) if (IS_ERR(regbase))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) return PTR_ERR(regbase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) sram_np = of_parse_phandle(np, "rockchip,audio-sram", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) if (!sram_np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) dev_err(&pdev->dev, "could not find sram dt node\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) asrc_np = of_parse_phandle(np, "rockchip,audio-src", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) if (!asrc_np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) goto err_phandle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) ret = of_address_to_resource(asrc_np, 0, &audio_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) goto err_phandle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) ret = rockchip_vad_get_audio_src_address(vad, audio_res.start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) goto err_phandle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) vad->audio_node = asrc_np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) vad->audio_src <<= AUDIO_SRC_SEL_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) ret = of_address_to_resource(sram_np, 0, &sram_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) goto err_phandle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) vad->memphy = sram_res.start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) vad->memphy_end = sram_res.start + resource_size(&sram_res) - 0x8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) vad->membase = devm_ioremap(&pdev->dev, sram_res.start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) resource_size(&sram_res));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) if (!vad->membase) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) goto err_phandle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) if (IS_ERR(vad->membase)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) ret = PTR_ERR(vad->membase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) goto err_phandle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) vad->hclk = devm_clk_get(&pdev->dev, "hclk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) if (IS_ERR(vad->hclk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) ret = PTR_ERR(vad->hclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) goto err_phandle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) ret = clk_prepare_enable(vad->hclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) goto err_phandle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) vad->regmap = devm_regmap_init_mmio(&pdev->dev, regbase,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) if (IS_ERR(vad->regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) ret = PTR_ERR(vad->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) rockchip_vad_init(vad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) irq = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) if (irq < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) ret = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) ret = devm_request_irq(&pdev->dev, irq, rockchip_vad_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 0, dev_name(&pdev->dev), vad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) #if defined(CONFIG_DEBUG_FS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) vad->debugfs_dir = debugfs_create_dir("vad", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) if (IS_ERR(vad->debugfs_dir))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) dev_err(&pdev->dev, "failed to create debugfs dir for vad!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) debugfs_create_file("reg", 0644, vad->debugfs_dir, vad,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) &rockchip_vad_reg_debugfs_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) platform_set_drvdata(pdev, vad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) ret = snd_soc_register_component(&pdev->dev, &soc_vad_codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) &vad_dai, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) of_node_put(sram_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) clk_disable_unprepare(vad->hclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) err_phandle:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) of_node_put(sram_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) of_node_put(asrc_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) static int rockchip_vad_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) struct rockchip_vad *vad = dev_get_drvdata(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) if (!IS_ERR(vad->hclk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) clk_disable_unprepare(vad->hclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) of_node_put(vad->audio_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) snd_soc_unregister_component(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) static struct platform_driver rockchip_vad_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) .probe = rockchip_vad_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) .remove = rockchip_vad_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) .name = DRV_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) .of_match_table = of_match_ptr(rockchip_vad_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) module_platform_driver(rockchip_vad_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) MODULE_DESCRIPTION("Rockchip VAD Controller");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) MODULE_AUTHOR("Andy Yan <andy.yan@rock-chips.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) MODULE_AUTHOR("Sugar Zhang <sugar.zhang@rock-chips.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) MODULE_ALIAS("platform:" DRV_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) MODULE_DEVICE_TABLE(of, rockchip_vad_match);