Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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", &reg, &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);