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-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Rockchip PDM ALSA SoC Digital Audio Interface(DAI)  driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 2017 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) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/rational.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/reset.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <sound/dmaengine_pcm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <sound/pcm_params.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include "rockchip_pdm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #define PDM_DMA_BURST_SIZE		(8) /* size * width: 8*4 = 32 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define PDM_SIGNOFF_CLK_100M		(100000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define PDM_SIGNOFF_CLK_300M		(300000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define PDM_PATH_MAX			(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define PDM_DEFAULT_RATE		(48000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define PDM_START_DELAY_MS_DEFAULT	(20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define PDM_START_DELAY_MS_MIN		(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define PDM_START_DELAY_MS_MAX		(1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define PDM_FILTER_DELAY_MS_MIN		(20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define PDM_FILTER_DELAY_MS_MAX		(1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define PDM_CLK_SHIFT_PPM_MAX		(1000000) /* 1 ppm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) enum rk_pdm_version {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	RK_PDM_RK3229,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	RK_PDM_RK3308,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	RK_PDM_RK3588,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	RK_PDM_RV1126,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) struct rk_pdm_dev {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	struct clk *hclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	struct snd_dmaengine_dai_dma_data capture_dma_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	struct reset_control *reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	unsigned int start_delay_ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	unsigned int filter_delay_ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	enum rk_pdm_version version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) struct rk_pdm_clkref {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	unsigned int sr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	unsigned int clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	unsigned int clk_out;
^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 rk_pdm_ds_ratio {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	unsigned int ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	unsigned int sr;
^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) static struct rk_pdm_clkref clkref[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	{ 8000, 40960000, 2048000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	{ 11025, 56448000, 2822400 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	{ 12000, 61440000, 3072000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	{ 8000, 98304000, 2048000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	{ 12000, 98304000, 3072000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) static struct rk_pdm_ds_ratio ds_ratio[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	{ 0, 192000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	{ 0, 176400 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	{ 0, 128000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	{ 1, 96000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	{ 1, 88200 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	{ 1, 64000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	{ 2, 48000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	{ 2, 44100 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	{ 2, 32000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	{ 3, 24000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	{ 3, 22050 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	{ 3, 16000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	{ 4, 12000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	{ 4, 11025 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	{ 4, 8000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) static unsigned int get_pdm_clk(struct rk_pdm_dev *pdm, unsigned int sr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 				unsigned int *clk_src, unsigned int *clk_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 				unsigned int signoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	unsigned int i, count, clk, div, rate, delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	clk = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	if (!sr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		return clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	count = ARRAY_SIZE(clkref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	for (i = 0; i < count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		if (sr % clkref[i].sr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		div = sr / clkref[i].sr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		if ((div & (div - 1)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 			*clk_out = clkref[i].clk_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 			rate = clk_round_rate(pdm->clk, clkref[i].clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 			delta = clkref[i].clk / PDM_CLK_SHIFT_PPM_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 			if (rate < clkref[i].clk - delta ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 			    rate > clkref[i].clk + delta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 			clk = clkref[i].clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 			*clk_src = clkref[i].clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		}
^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) 	if (!clk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		clk = clk_round_rate(pdm->clk, signoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		*clk_src = clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	return clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) static unsigned int get_pdm_ds_ratio(unsigned int sr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	unsigned int i, count, ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	ratio = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	if (!sr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		return ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	count = ARRAY_SIZE(ds_ratio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	for (i = 0; i < count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		if (sr == ds_ratio[i].sr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 			ratio = ds_ratio[i].ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	return ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static unsigned int get_pdm_cic_ratio(unsigned int clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	switch (clk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	case 4096000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	case 5644800:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	case 6144000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	case 2048000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	case 2822400:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	case 3072000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	case 1024000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	case 1411200:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	case 1536000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		return 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static unsigned int samplerate_to_bit(unsigned int samplerate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	switch (samplerate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	case 8000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	case 11025:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	case 12000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	case 16000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	case 22050:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	case 24000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	case 32000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		return 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	case 44100:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	case 48000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 		return 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	case 64000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	case 88200:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	case 96000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 		return 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	case 128000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	case 176400:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	case 192000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 		return 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) static inline struct rk_pdm_dev *to_info(struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	return snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) static void rockchip_pdm_drop_fifo(struct rk_pdm_dev *pdm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	int cnt, val, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	/* drop the dirty data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	regmap_read(pdm->regmap, PDM_FIFO_CTRL, &cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	for (i = 0; i < PDM_FIFO_CNT(cnt); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		regmap_read(pdm->regmap, PDM_RXFIFO_DATA, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) static void rockchip_pdm_rxctrl(struct rk_pdm_dev *pdm, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	if (on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 		rockchip_pdm_drop_fifo(pdm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		regmap_update_bits(pdm->regmap, PDM_DMA_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 				   PDM_DMA_RD_MSK, PDM_DMA_RD_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		regmap_update_bits(pdm->regmap, PDM_DMA_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 				   PDM_DMA_RD_MSK, PDM_DMA_RD_DIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		regmap_update_bits(pdm->regmap, PDM_SYSCONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 				   PDM_RX_MASK | PDM_RX_CLR_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 				   PDM_RX_STOP | PDM_RX_CLR_WR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) static int rockchip_pdm_set_samplerate(struct rk_pdm_dev *pdm, unsigned int samplerate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	unsigned int val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	unsigned int clk_rate, clk_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	unsigned int clk_src = 0, clk_out = 0, signoff = PDM_SIGNOFF_CLK_100M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	unsigned long m, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	bool change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	if (pdm->version == RK_PDM_RK3588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		signoff = PDM_SIGNOFF_CLK_300M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	clk_rate = get_pdm_clk(pdm, samplerate, &clk_src, &clk_out, signoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	if (!clk_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	ret = clk_set_rate(pdm->clk, clk_src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	if (pdm->version == RK_PDM_RK3308 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	    pdm->version == RK_PDM_RK3588 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	    pdm->version == RK_PDM_RV1126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		rational_best_approximation(clk_out, clk_src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 					    GENMASK(16 - 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 					    GENMASK(16 - 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 					    &m, &n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		val = (m << PDM_FD_NUMERATOR_SFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 			(n << PDM_FD_DENOMINATOR_SFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 		regmap_update_bits_check(pdm->regmap, PDM_CTRL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 					 PDM_FD_NUMERATOR_MSK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 					 PDM_FD_DENOMINATOR_MSK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 					 val, &change);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 		if (change) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 			reset_control_assert(pdm->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 			reset_control_deassert(pdm->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 			rockchip_pdm_rxctrl(pdm, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		clk_div = n / m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		if (clk_div >= 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 			val = PDM_CLK_FD_RATIO_40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		else if (clk_div <= 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 			val = PDM_CLK_FD_RATIO_35;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 		regmap_update_bits(pdm->regmap, PDM_CLK_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 				   PDM_CLK_FD_RATIO_MSK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 				   val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	if (pdm->version == RK_PDM_RK3588 || pdm->version == RK_PDM_RV1126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 		val = get_pdm_cic_ratio(clk_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 		regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, PDM_CIC_RATIO_MSK, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		val = samplerate_to_bit(samplerate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 		regmap_update_bits(pdm->regmap, PDM_CTRL0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 				   PDM_SAMPLERATE_MSK, PDM_SAMPLERATE(val));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 		val = get_pdm_ds_ratio(samplerate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 		regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, PDM_DS_RATIO_MSK, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	regmap_update_bits(pdm->regmap, PDM_HPF_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 			   PDM_HPF_CF_MSK, PDM_HPF_60HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	regmap_update_bits(pdm->regmap, PDM_HPF_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 			   PDM_HPF_LE | PDM_HPF_RE, PDM_HPF_LE | PDM_HPF_RE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) static int rockchip_pdm_hw_params(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 				  struct snd_pcm_hw_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 				  struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	struct rk_pdm_dev *pdm = to_info(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	unsigned int val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	rockchip_pdm_set_samplerate(pdm, params_rate(params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	if (pdm->version != RK_PDM_RK3229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 		regmap_update_bits(pdm->regmap, PDM_CTRL0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 				   PDM_MODE_MSK, PDM_MODE_LJ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	switch (params_format(params)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	case SNDRV_PCM_FORMAT_S8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		val |= PDM_VDW(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	case SNDRV_PCM_FORMAT_S16_LE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		val |= PDM_VDW(16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	case SNDRV_PCM_FORMAT_S20_3LE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 		val |= PDM_VDW(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	case SNDRV_PCM_FORMAT_S24_LE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 		val |= PDM_VDW(24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	case SNDRV_PCM_FORMAT_S32_LE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 		val |= PDM_VDW(32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	switch (params_channels(params)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 		val |= PDM_PATH3_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		val |= PDM_PATH2_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 		val |= PDM_PATH1_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 		val |= PDM_PATH0_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 		dev_err(pdm->dev, "invalid channel: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 			params_channels(params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	regmap_update_bits(pdm->regmap, PDM_CTRL0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 			   PDM_PATH_MSK | PDM_VDW_MSK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 			   val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	/* all channels share the single FIFO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	regmap_update_bits(pdm->regmap, PDM_DMA_CTRL, PDM_DMA_RDL_MSK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 			   PDM_DMA_RDL(8 * params_channels(params)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) static int rockchip_pdm_set_fmt(struct snd_soc_dai *cpu_dai,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 				unsigned int fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	struct rk_pdm_dev *pdm = to_info(cpu_dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	unsigned int mask = 0, val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	mask = PDM_CKP_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	case SND_SOC_DAIFMT_NB_NF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 		val = PDM_CKP_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	case SND_SOC_DAIFMT_IB_NF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 		val = PDM_CKP_INVERTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	pm_runtime_get_sync(cpu_dai->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	pm_runtime_put(cpu_dai->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) static int rockchip_pdm_trigger(struct snd_pcm_substream *substream, int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 				struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	struct rk_pdm_dev *pdm = to_info(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	case SNDRV_PCM_TRIGGER_RESUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 			rockchip_pdm_rxctrl(pdm, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	case SNDRV_PCM_TRIGGER_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 		if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 			rockchip_pdm_rxctrl(pdm, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) static int rockchip_pdm_start_delay_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 					 struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	uinfo->value.integer.min = PDM_START_DELAY_MS_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	uinfo->value.integer.max = PDM_START_DELAY_MS_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	uinfo->value.integer.step = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) static int rockchip_pdm_start_delay_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 					struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	struct rk_pdm_dev *pdm = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	ucontrol->value.integer.value[0] = pdm->start_delay_ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) static int rockchip_pdm_start_delay_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 					struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	struct rk_pdm_dev *pdm = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	if ((ucontrol->value.integer.value[0] < PDM_START_DELAY_MS_MIN) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	    (ucontrol->value.integer.value[0] > PDM_START_DELAY_MS_MAX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	pdm->start_delay_ms = ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) static int rockchip_pdm_filter_delay_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 					  struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	uinfo->value.integer.min = PDM_FILTER_DELAY_MS_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	uinfo->value.integer.max = PDM_FILTER_DELAY_MS_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	uinfo->value.integer.step = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) static int rockchip_pdm_filter_delay_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 					 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	struct rk_pdm_dev *pdm = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	ucontrol->value.integer.value[0] = pdm->filter_delay_ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) static int rockchip_pdm_filter_delay_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 					 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 	struct rk_pdm_dev *pdm = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	if ((ucontrol->value.integer.value[0] < PDM_FILTER_DELAY_MS_MIN) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	    (ucontrol->value.integer.value[0] > PDM_FILTER_DELAY_MS_MAX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	pdm->filter_delay_ms = ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) static const struct snd_kcontrol_new rockchip_pdm_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 		.name = "PDM Start Delay Ms",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 		.info = rockchip_pdm_start_delay_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 		.get = rockchip_pdm_start_delay_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 		.put = rockchip_pdm_start_delay_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 		.name = "PDM Filter Delay Ms",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 		.info = rockchip_pdm_filter_delay_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 		.get = rockchip_pdm_filter_delay_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 		.put = rockchip_pdm_filter_delay_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) static int rockchip_pdm_dai_probe(struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	struct rk_pdm_dev *pdm = to_info(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	dai->capture_dma_data = &pdm->capture_dma_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	snd_soc_add_dai_controls(dai, rockchip_pdm_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 				 ARRAY_SIZE(rockchip_pdm_controls));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) static void rockchip_pdm_shutdown(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 				  struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	struct rk_pdm_dev *pdm = to_info(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	if (substream->stream != SNDRV_PCM_STREAM_CAPTURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, PDM_CLK_MSK, PDM_CLK_DIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) static int rockchip_pdm_prepare(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 				struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	struct rk_pdm_dev *pdm = to_info(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	if (substream->stream != SNDRV_PCM_STREAM_CAPTURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	regmap_update_bits(pdm->regmap, PDM_SYSCONFIG, PDM_RX_MASK, PDM_RX_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 	 * after xfer start, a necessary delay for filter to init and will drop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	 * the dirty data in the trigger-START late.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 	usleep_range((pdm->filter_delay_ms) * 1000, (pdm->filter_delay_ms + 1) * 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) static int rockchip_pdm_startup(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 				struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 	struct rk_pdm_dev *pdm = to_info(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	if (substream->stream != SNDRV_PCM_STREAM_CAPTURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, PDM_CLK_MSK, PDM_CLK_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 	 * a necessary delay for dmics wake-up after clk enabled, and drop the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	 * dirty data in this duration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 	usleep_range((pdm->start_delay_ms + 1) * 1000, (pdm->start_delay_ms + 2) * 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) static const struct snd_soc_dai_ops rockchip_pdm_dai_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 	.startup = rockchip_pdm_startup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	.shutdown = rockchip_pdm_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 	.set_fmt = rockchip_pdm_set_fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 	.trigger = rockchip_pdm_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 	.prepare = rockchip_pdm_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	.hw_params = rockchip_pdm_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) #define ROCKCHIP_PDM_RATES SNDRV_PCM_RATE_8000_192000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) #define ROCKCHIP_PDM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 			      SNDRV_PCM_FMTBIT_S20_3LE | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 			      SNDRV_PCM_FMTBIT_S24_LE | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 			      SNDRV_PCM_FMTBIT_S32_LE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) static struct snd_soc_dai_driver rockchip_pdm_dai = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	.probe = rockchip_pdm_dai_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 	.capture = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 		.stream_name = "Capture",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 		.channels_min = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 		.channels_max = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 		.rates = ROCKCHIP_PDM_RATES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 		.formats = ROCKCHIP_PDM_FORMATS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	.ops = &rockchip_pdm_dai_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	.symmetric_rates = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) static const struct snd_soc_component_driver rockchip_pdm_component = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 	.name = "rockchip-pdm",
^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 int rockchip_pdm_runtime_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	struct rk_pdm_dev *pdm = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	regcache_cache_only(pdm->regmap, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	clk_disable_unprepare(pdm->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	clk_disable_unprepare(pdm->hclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) static int rockchip_pdm_runtime_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	struct rk_pdm_dev *pdm = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 	ret = clk_prepare_enable(pdm->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 		dev_err(pdm->dev, "clock enable failed %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	ret = clk_prepare_enable(pdm->hclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 		dev_err(pdm->dev, "hclock enable failed %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 	rockchip_pdm_rxctrl(pdm, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	regcache_cache_only(pdm->regmap, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 	regcache_mark_dirty(pdm->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 	ret = regcache_sync(pdm->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 		clk_disable_unprepare(pdm->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 		clk_disable_unprepare(pdm->hclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) static bool rockchip_pdm_wr_reg(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	case PDM_SYSCONFIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	case PDM_CTRL0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	case PDM_CTRL1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 	case PDM_CLK_CTRL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	case PDM_HPF_CTRL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 	case PDM_FIFO_CTRL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 	case PDM_DMA_CTRL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 	case PDM_INT_EN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 	case PDM_INT_CLR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 	case PDM_DATA_VALID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 	}
^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 bool rockchip_pdm_rd_reg(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 	switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 	case PDM_SYSCONFIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 	case PDM_CTRL0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 	case PDM_CTRL1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 	case PDM_CLK_CTRL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 	case PDM_HPF_CTRL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 	case PDM_FIFO_CTRL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 	case PDM_DMA_CTRL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 	case PDM_INT_EN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 	case PDM_INT_CLR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 	case PDM_INT_ST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 	case PDM_DATA_VALID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 	case PDM_RXFIFO_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 	case PDM_VERSION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 	}
^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) static bool rockchip_pdm_volatile_reg(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 	switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 	case PDM_SYSCONFIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 	case PDM_FIFO_CTRL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 	case PDM_INT_CLR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 	case PDM_INT_ST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 	case PDM_RXFIFO_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) static bool rockchip_pdm_precious_reg(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 	switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 	case PDM_RXFIFO_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) static const struct reg_default rockchip_pdm_reg_defaults[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 	{ PDM_CTRL0, 0x78000017 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 	{ PDM_CTRL1, 0x0bb8ea60 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 	{ PDM_CLK_CTRL, 0x0000e401 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 	{ PDM_DMA_CTRL, 0x0000001f },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) static const struct regmap_config rockchip_pdm_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 	.reg_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 	.reg_stride = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 	.val_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 	.max_register = PDM_VERSION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 	.reg_defaults = rockchip_pdm_reg_defaults,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 	.num_reg_defaults = ARRAY_SIZE(rockchip_pdm_reg_defaults),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 	.writeable_reg = rockchip_pdm_wr_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 	.readable_reg = rockchip_pdm_rd_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 	.volatile_reg = rockchip_pdm_volatile_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 	.precious_reg = rockchip_pdm_precious_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 	.cache_type = REGCACHE_FLAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) static const struct of_device_id rockchip_pdm_match[] __maybe_unused = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 	{ .compatible = "rockchip,pdm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 	  .data = (void *)RK_PDM_RK3229 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 	{ .compatible = "rockchip,px30-pdm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 	  .data = (void *)RK_PDM_RK3308 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 	{ .compatible = "rockchip,rk1808-pdm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 	  .data = (void *)RK_PDM_RK3308 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 	{ .compatible = "rockchip,rk3308-pdm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 	  .data = (void *)RK_PDM_RK3308 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 	{ .compatible = "rockchip,rk3568-pdm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 	  .data = (void *)RK_PDM_RV1126 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 	{ .compatible = "rockchip,rk3588-pdm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 	  .data = (void *)RK_PDM_RK3588 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 	{ .compatible = "rockchip,rv1126-pdm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 	  .data = (void *)RK_PDM_RV1126 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 	{},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) MODULE_DEVICE_TABLE(of, rockchip_pdm_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) static int rockchip_pdm_path_parse(struct rk_pdm_dev *pdm, struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 	unsigned int path[PDM_PATH_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 	int cnt = 0, ret = 0, i = 0, val = 0, msk = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	cnt = of_count_phandle_with_args(node, "rockchip,path-map",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 					 NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 	if (cnt != PDM_PATH_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 		return cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 	ret = of_property_read_u32_array(node, "rockchip,path-map",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 					 path, cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 	for (i = 0; i < cnt; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 		if (path[i] >= PDM_PATH_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 		msk |= PDM_PATH_MASK(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 		val |= PDM_PATH(i, path[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 	regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, msk, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) static int rockchip_pdm_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 	struct device_node *node = pdev->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 	const struct of_device_id *match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 	struct rk_pdm_dev *pdm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 	struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 	void __iomem *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 	pdm = devm_kzalloc(&pdev->dev, sizeof(*pdm), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 	if (!pdm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 	match = of_match_device(rockchip_pdm_match, &pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 	if (match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 		pdm->version = (enum rk_pdm_version)match->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 	if (pdm->version == RK_PDM_RK3308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 		pdm->reset = devm_reset_control_get(&pdev->dev, "pdm-m");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 		if (IS_ERR(pdm->reset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 			return PTR_ERR(pdm->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 	regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 	if (IS_ERR(regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 		return PTR_ERR(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 	pdm->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 					    &rockchip_pdm_regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 	if (IS_ERR(pdm->regmap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 		return PTR_ERR(pdm->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) 	pdm->capture_dma_data.addr = res->start + PDM_RXFIFO_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 	pdm->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) 	pdm->capture_dma_data.maxburst = PDM_DMA_BURST_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 	pdm->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 	dev_set_drvdata(&pdev->dev, pdm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 	pdm->start_delay_ms = PDM_START_DELAY_MS_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 	pdm->filter_delay_ms = PDM_FILTER_DELAY_MS_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 	pdm->clk = devm_clk_get(&pdev->dev, "pdm_clk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 	if (IS_ERR(pdm->clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 		return PTR_ERR(pdm->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 	pdm->hclk = devm_clk_get(&pdev->dev, "pdm_hclk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 	if (IS_ERR(pdm->hclk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 		return PTR_ERR(pdm->hclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 	ret = clk_prepare_enable(pdm->hclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 	pm_runtime_enable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 	if (!pm_runtime_enabled(&pdev->dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 		ret = rockchip_pdm_runtime_resume(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) 			goto err_pm_disable;
^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) 	ret = devm_snd_soc_register_component(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) 					      &rockchip_pdm_component,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) 					      &rockchip_pdm_dai, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) 		dev_err(&pdev->dev, "could not register dai: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) 		goto err_suspend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) 	rockchip_pdm_set_samplerate(pdm, PDM_DEFAULT_RATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 	rockchip_pdm_rxctrl(pdm, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) 	ret = rockchip_pdm_path_parse(pdm, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 	if (ret != 0 && ret != -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) 		goto err_suspend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) 	if (of_property_read_bool(node, "rockchip,no-dmaengine"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) 	ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) 		dev_err(&pdev->dev, "could not register pcm: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 		goto err_suspend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) err_suspend:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) 	if (!pm_runtime_status_suspended(&pdev->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) 		rockchip_pdm_runtime_suspend(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) err_pm_disable:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) 	pm_runtime_disable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) 	clk_disable_unprepare(pdm->hclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) static int rockchip_pdm_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) 	struct rk_pdm_dev *pdm = dev_get_drvdata(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) 	pm_runtime_disable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) 	if (!pm_runtime_status_suspended(&pdev->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) 		rockchip_pdm_runtime_suspend(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) 	clk_disable_unprepare(pdm->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) 	clk_disable_unprepare(pdm->hclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) static int rockchip_pdm_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) 	struct rk_pdm_dev *pdm = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) 	regcache_mark_dirty(pdm->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) static int rockchip_pdm_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) 	struct rk_pdm_dev *pdm = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) 	ret = pm_runtime_get_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) 		pm_runtime_put(dev);
^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) 	ret = regcache_sync(pdm->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) 	pm_runtime_put(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) static const struct dev_pm_ops rockchip_pdm_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) 	SET_RUNTIME_PM_OPS(rockchip_pdm_runtime_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) 			   rockchip_pdm_runtime_resume, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) 	SET_SYSTEM_SLEEP_PM_OPS(rockchip_pdm_suspend, rockchip_pdm_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) static struct platform_driver rockchip_pdm_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) 	.probe  = rockchip_pdm_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) 	.remove = rockchip_pdm_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) 		.name = "rockchip-pdm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) 		.of_match_table = of_match_ptr(rockchip_pdm_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) 		.pm = &rockchip_pdm_pm_ops,
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) module_platform_driver(rockchip_pdm_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) MODULE_AUTHOR("Sugar <sugar.zhang@rock-chips.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) MODULE_DESCRIPTION("Rockchip PDM Controller Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) MODULE_LICENSE("GPL v2");