xref: /OK3568_Linux_fs/kernel/sound/soc/codecs/rk_dsm.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Rockchip Audio Delta-sigma Digital Converter Interface
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (C) 2023 Rockchip Electronics Co.,Ltd
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  */
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #include <linux/module.h>
10*4882a593Smuzhiyun #include <linux/device.h>
11*4882a593Smuzhiyun #include <linux/delay.h>
12*4882a593Smuzhiyun #include <linux/of.h>
13*4882a593Smuzhiyun #include <linux/of_gpio.h>
14*4882a593Smuzhiyun #include <linux/of_platform.h>
15*4882a593Smuzhiyun #include <linux/clk.h>
16*4882a593Smuzhiyun #include <linux/mfd/syscon.h>
17*4882a593Smuzhiyun #include <linux/platform_device.h>
18*4882a593Smuzhiyun #include <linux/pm_runtime.h>
19*4882a593Smuzhiyun #include <linux/regmap.h>
20*4882a593Smuzhiyun #include <linux/reset.h>
21*4882a593Smuzhiyun #include <sound/pcm_params.h>
22*4882a593Smuzhiyun #include <sound/dmaengine_pcm.h>
23*4882a593Smuzhiyun #include <sound/tlv.h>
24*4882a593Smuzhiyun #include "rk_dsm.h"
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun #define RK3562_GRF_PERI_AUDIO_CON	(0x0070)
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun struct rk_dsm_soc_data {
29*4882a593Smuzhiyun 	int (*init)(struct device *dev);
30*4882a593Smuzhiyun 	void (*deinit)(struct device *dev);
31*4882a593Smuzhiyun };
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun struct rk_dsm_priv {
34*4882a593Smuzhiyun 	struct regmap *grf;
35*4882a593Smuzhiyun 	struct regmap *regmap;
36*4882a593Smuzhiyun 	struct clk *clk_dac;
37*4882a593Smuzhiyun 	struct clk *pclk;
38*4882a593Smuzhiyun 	unsigned int pa_ctl_delay_ms;
39*4882a593Smuzhiyun 	struct gpio_desc *pa_ctl;
40*4882a593Smuzhiyun 	struct reset_control *rc;
41*4882a593Smuzhiyun 	const struct rk_dsm_soc_data *data;
42*4882a593Smuzhiyun };
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun /* DAC digital gain */
45*4882a593Smuzhiyun static const DECLARE_TLV_DB_SCALE(dac_tlv, -95625, 375, 0);
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun /* DAC Cutoff for High Pass Filter */
48*4882a593Smuzhiyun static const char * const dac_hpf_cutoff_text[] = {
49*4882a593Smuzhiyun 	"80Hz", "100Hz", "120Hz", "140Hz",
50*4882a593Smuzhiyun };
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun static SOC_ENUM_SINGLE_DECL(dac_hpf_cutoff_enum, DACHPF, 4,
53*4882a593Smuzhiyun 			    dac_hpf_cutoff_text);
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun static const char * const pa_ctl[] = {"Off", "On"};
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun static const struct soc_enum pa_enum =
58*4882a593Smuzhiyun 	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(pa_ctl), pa_ctl);
59*4882a593Smuzhiyun 
rk_dsm_dac_vol_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)60*4882a593Smuzhiyun static int rk_dsm_dac_vol_get(struct snd_kcontrol *kcontrol,
61*4882a593Smuzhiyun 			      struct snd_ctl_elem_value *ucontrol)
62*4882a593Smuzhiyun {
63*4882a593Smuzhiyun 	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
64*4882a593Smuzhiyun 	struct soc_mixer_control *mc =
65*4882a593Smuzhiyun 		(struct soc_mixer_control *)kcontrol->private_value;
66*4882a593Smuzhiyun 	unsigned int val = snd_soc_component_read(component, mc->reg);
67*4882a593Smuzhiyun 	unsigned int sign = snd_soc_component_read(component, DACVOGP);
68*4882a593Smuzhiyun 	unsigned int mask = (1 << fls(mc->max)) - 1;
69*4882a593Smuzhiyun 	unsigned int shift = mc->shift;
70*4882a593Smuzhiyun 	int mid = mc->max / 2;
71*4882a593Smuzhiyun 	int uv;
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun 	uv = (val >> shift) & mask;
74*4882a593Smuzhiyun 	if (sign)
75*4882a593Smuzhiyun 		uv = mid + uv;
76*4882a593Smuzhiyun 	else
77*4882a593Smuzhiyun 		uv = mid - uv;
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun 	ucontrol->value.integer.value[0] = uv;
80*4882a593Smuzhiyun 	ucontrol->value.integer.value[1] = uv;
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun 	return 0;
83*4882a593Smuzhiyun }
84*4882a593Smuzhiyun 
rk_dsm_dac_vol_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)85*4882a593Smuzhiyun static int rk_dsm_dac_vol_put(struct snd_kcontrol *kcontrol,
86*4882a593Smuzhiyun 			      struct snd_ctl_elem_value *ucontrol)
87*4882a593Smuzhiyun {
88*4882a593Smuzhiyun 	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
89*4882a593Smuzhiyun 	struct soc_mixer_control *mc =
90*4882a593Smuzhiyun 		(struct soc_mixer_control *)kcontrol->private_value;
91*4882a593Smuzhiyun 	unsigned int reg = mc->reg;
92*4882a593Smuzhiyun 	unsigned int rreg = mc->rreg;
93*4882a593Smuzhiyun 	unsigned int shift = mc->shift;
94*4882a593Smuzhiyun 	unsigned int mask = (1 << fls(mc->max)) - 1;
95*4882a593Smuzhiyun 	unsigned int val, val_mask, sign;
96*4882a593Smuzhiyun 	int uv = ucontrol->value.integer.value[0];
97*4882a593Smuzhiyun 	int min = mc->min;
98*4882a593Smuzhiyun 	int mid = mc->max / 2;
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun 	if (uv > mid) {
101*4882a593Smuzhiyun 		sign = DSM_DACVOGP_VOLGPL0_POS | DSM_DACVOGP_VOLGPR0_POS;
102*4882a593Smuzhiyun 		uv = uv - mid;
103*4882a593Smuzhiyun 	} else {
104*4882a593Smuzhiyun 		sign = DSM_DACVOGP_VOLGPL0_NEG | DSM_DACVOGP_VOLGPR0_NEG;
105*4882a593Smuzhiyun 		uv = mid - uv;
106*4882a593Smuzhiyun 	}
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun 	val = ((uv + min) & mask);
109*4882a593Smuzhiyun 	val_mask = mask << shift;
110*4882a593Smuzhiyun 	val = val << shift;
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun 	snd_soc_component_update_bits(component, reg, val_mask, val);
113*4882a593Smuzhiyun 	snd_soc_component_update_bits(component, rreg, val_mask, val);
114*4882a593Smuzhiyun 	snd_soc_component_write(component, DACVOGP, sign);
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun 	return 0;
117*4882a593Smuzhiyun }
118*4882a593Smuzhiyun 
rk_dsm_dac_pa_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)119*4882a593Smuzhiyun static int rk_dsm_dac_pa_get(struct snd_kcontrol *kcontrol,
120*4882a593Smuzhiyun 			     struct snd_ctl_elem_value *ucontrol)
121*4882a593Smuzhiyun {
122*4882a593Smuzhiyun 	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
123*4882a593Smuzhiyun 	struct rk_dsm_priv *rd = snd_soc_component_get_drvdata(component);
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun 	if (!rd->pa_ctl)
126*4882a593Smuzhiyun 		return -EINVAL;
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun 	ucontrol->value.enumerated.item[0] = gpiod_get_value(rd->pa_ctl);
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun 	return 0;
131*4882a593Smuzhiyun }
132*4882a593Smuzhiyun 
rk_dsm_dac_pa_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)133*4882a593Smuzhiyun static int rk_dsm_dac_pa_put(struct snd_kcontrol *kcontrol,
134*4882a593Smuzhiyun 			     struct snd_ctl_elem_value *ucontrol)
135*4882a593Smuzhiyun {
136*4882a593Smuzhiyun 	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
137*4882a593Smuzhiyun 	struct rk_dsm_priv *rd = snd_soc_component_get_drvdata(component);
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun 	if (!rd->pa_ctl)
140*4882a593Smuzhiyun 		return -EINVAL;
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun 	gpiod_set_value(rd->pa_ctl, ucontrol->value.enumerated.item[0]);
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun 	return 0;
145*4882a593Smuzhiyun }
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun static const struct snd_kcontrol_new rk_dsm_snd_controls[] = {
148*4882a593Smuzhiyun 	SOC_DOUBLE_R_EXT_TLV("DAC Digital Volume",
149*4882a593Smuzhiyun 			     DACVOLL0, DACVOLR0, 0, 0x1fe, 0,
150*4882a593Smuzhiyun 			     rk_dsm_dac_vol_get,
151*4882a593Smuzhiyun 			     rk_dsm_dac_vol_put,
152*4882a593Smuzhiyun 			     dac_tlv),
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun 	SOC_ENUM("DAC HPF Cutoff", dac_hpf_cutoff_enum),
155*4882a593Smuzhiyun 	SOC_SINGLE("DAC HPF Switch", DACHPF, 0, 1, 0),
156*4882a593Smuzhiyun 	SOC_ENUM_EXT("Power Amplifier", pa_enum,
157*4882a593Smuzhiyun 		     rk_dsm_dac_pa_get,
158*4882a593Smuzhiyun 		     rk_dsm_dac_pa_put),
159*4882a593Smuzhiyun };
160*4882a593Smuzhiyun 
161*4882a593Smuzhiyun /*
162*4882a593Smuzhiyun  * ACDC_CLK  D2A_CLK   D2A_SYNC Sample rates supported
163*4882a593Smuzhiyun  * 49.152MHz 49.152MHz 6.144MHz 12/24/48/96/192kHz
164*4882a593Smuzhiyun  * 45.154MHz 45.154MHz 5.644MHz 11.025/22.05/44.1/88.2/176.4kHz
165*4882a593Smuzhiyun  * 32.768MHz 32.768MHz 4.096MHz 8/16/32/64/128kHz
166*4882a593Smuzhiyun  */
rk_dsm_get_clk(unsigned int samplerate,unsigned int * mclk,unsigned int * sclk)167*4882a593Smuzhiyun static void rk_dsm_get_clk(unsigned int samplerate,
168*4882a593Smuzhiyun 			   unsigned int *mclk,
169*4882a593Smuzhiyun 			   unsigned int *sclk)
170*4882a593Smuzhiyun {
171*4882a593Smuzhiyun 	switch (samplerate) {
172*4882a593Smuzhiyun 	case 12000:
173*4882a593Smuzhiyun 	case 24000:
174*4882a593Smuzhiyun 	case 48000:
175*4882a593Smuzhiyun 	case 96000:
176*4882a593Smuzhiyun 	case 192000:
177*4882a593Smuzhiyun 		*mclk = 49152000;
178*4882a593Smuzhiyun 		*sclk = 6144000;
179*4882a593Smuzhiyun 		break;
180*4882a593Smuzhiyun 	case 11025:
181*4882a593Smuzhiyun 	case 22050:
182*4882a593Smuzhiyun 	case 44100:
183*4882a593Smuzhiyun 	case 88200:
184*4882a593Smuzhiyun 	case 176400:
185*4882a593Smuzhiyun 		*mclk = 45158400;
186*4882a593Smuzhiyun 		*sclk = 5644800;
187*4882a593Smuzhiyun 		break;
188*4882a593Smuzhiyun 	case 8000:
189*4882a593Smuzhiyun 	case 16000:
190*4882a593Smuzhiyun 	case 32000:
191*4882a593Smuzhiyun 	case 64000:
192*4882a593Smuzhiyun 	case 128000:
193*4882a593Smuzhiyun 		*mclk = 32768000;
194*4882a593Smuzhiyun 		*sclk = 4096000;
195*4882a593Smuzhiyun 		break;
196*4882a593Smuzhiyun 	default:
197*4882a593Smuzhiyun 		*mclk = 0;
198*4882a593Smuzhiyun 		*sclk = 0;
199*4882a593Smuzhiyun 		break;
200*4882a593Smuzhiyun 	}
201*4882a593Smuzhiyun }
202*4882a593Smuzhiyun 
rk_dsm_enable_clk_dac(struct rk_dsm_priv * rd)203*4882a593Smuzhiyun static void rk_dsm_enable_clk_dac(struct rk_dsm_priv *rd)
204*4882a593Smuzhiyun {
205*4882a593Smuzhiyun 	regmap_update_bits(rd->regmap, DACCLKCTRL,
206*4882a593Smuzhiyun 			   DSM_DACCLKCTRL_DAC_CKE_MASK |
207*4882a593Smuzhiyun 			   DSM_DACCLKCTRL_I2SRX_CKE_MASK |
208*4882a593Smuzhiyun 			   DSM_DACCLKCTRL_CKE_BCLKRX_MASK |
209*4882a593Smuzhiyun 			   DSM_DACCLKCTRL_DAC_SYNC_ENA_MASK |
210*4882a593Smuzhiyun 			   DSM_DACCLKCTRL_DAC_MODE_ATTENU_MASK,
211*4882a593Smuzhiyun 			   DSM_DACCLKCTRL_DAC_CKE_EN |
212*4882a593Smuzhiyun 			   DSM_DACCLKCTRL_I2SRX_CKE_EN |
213*4882a593Smuzhiyun 			   DSM_DACCLKCTRL_CKE_BCLKRX_EN |
214*4882a593Smuzhiyun 			   DSM_DACCLKCTRL_DAC_SYNC_ENA_EN |
215*4882a593Smuzhiyun 			   DSM_DACCLKCTRL_DAC_MODE_ATTENU_EN);
216*4882a593Smuzhiyun }
217*4882a593Smuzhiyun 
rk_dsm_set_clk(struct rk_dsm_priv * rd,struct snd_pcm_substream * substream,unsigned int samplerate)218*4882a593Smuzhiyun static int rk_dsm_set_clk(struct rk_dsm_priv *rd,
219*4882a593Smuzhiyun 			  struct snd_pcm_substream *substream,
220*4882a593Smuzhiyun 			  unsigned int samplerate)
221*4882a593Smuzhiyun {
222*4882a593Smuzhiyun 	unsigned int mclk, sclk, bclk;
223*4882a593Smuzhiyun 	unsigned int div_bclk;
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun 	rk_dsm_get_clk(samplerate, &mclk, &sclk);
226*4882a593Smuzhiyun 	if (!mclk || !sclk)
227*4882a593Smuzhiyun 		return -EINVAL;
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun 	bclk = 64 * samplerate;
230*4882a593Smuzhiyun 	div_bclk = DIV_ROUND_CLOSEST(mclk, bclk);
231*4882a593Smuzhiyun 
232*4882a593Smuzhiyun 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
233*4882a593Smuzhiyun 		clk_set_rate(rd->clk_dac, mclk);
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun 		rk_dsm_enable_clk_dac(rd);
236*4882a593Smuzhiyun 
237*4882a593Smuzhiyun 		regmap_update_bits(rd->regmap, DACSCLKRXINT_DIV,
238*4882a593Smuzhiyun 				   DSM_DACSCLKRXINT_DIV_SCKRXDIV_MASK,
239*4882a593Smuzhiyun 				   DSM_DACSCLKRXINT_DIV_SCKRXDIV(div_bclk));
240*4882a593Smuzhiyun 		regmap_update_bits(rd->regmap, I2S_CKR0,
241*4882a593Smuzhiyun 				   DSM_I2S_CKR0_RSD_MASK,
242*4882a593Smuzhiyun 				   DSM_I2S_CKR0_RSD_64);
243*4882a593Smuzhiyun 	}
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun 	return 0;
246*4882a593Smuzhiyun }
247*4882a593Smuzhiyun 
rk_dsm_set_dai_fmt(struct snd_soc_dai * dai,unsigned int fmt)248*4882a593Smuzhiyun static int rk_dsm_set_dai_fmt(struct snd_soc_dai *dai,
249*4882a593Smuzhiyun 			      unsigned int fmt)
250*4882a593Smuzhiyun {
251*4882a593Smuzhiyun 	struct rk_dsm_priv *rd =
252*4882a593Smuzhiyun 		snd_soc_component_get_drvdata(dai->component);
253*4882a593Smuzhiyun 	unsigned int mask = 0, val = 0;
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun 	/* master mode only */
256*4882a593Smuzhiyun 	regmap_update_bits(rd->regmap, I2S_CKR1,
257*4882a593Smuzhiyun 			   DSM_I2S_CKR1_MSS_MASK,
258*4882a593Smuzhiyun 			   DSM_I2S_CKR1_MSS_MASTER);
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun 	mask = DSM_I2S_CKR1_CKP_MASK |
261*4882a593Smuzhiyun 	       DSM_I2S_CKR1_RLP_MASK;
262*4882a593Smuzhiyun 
263*4882a593Smuzhiyun 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
264*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_NB_NF:
265*4882a593Smuzhiyun 		val = DSM_I2S_CKR1_CKP_NORMAL |
266*4882a593Smuzhiyun 		      DSM_I2S_CKR1_RLP_NORMAL;
267*4882a593Smuzhiyun 		break;
268*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_IB_IF:
269*4882a593Smuzhiyun 		val = DSM_I2S_CKR1_CKP_INVERTED |
270*4882a593Smuzhiyun 		      DSM_I2S_CKR1_RLP_INVERTED;
271*4882a593Smuzhiyun 		break;
272*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_IB_NF:
273*4882a593Smuzhiyun 		val = DSM_I2S_CKR1_CKP_INVERTED |
274*4882a593Smuzhiyun 		      DSM_I2S_CKR1_RLP_NORMAL;
275*4882a593Smuzhiyun 		break;
276*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_NB_IF:
277*4882a593Smuzhiyun 		val = DSM_I2S_CKR1_CKP_NORMAL |
278*4882a593Smuzhiyun 		      DSM_I2S_CKR1_RLP_INVERTED;
279*4882a593Smuzhiyun 		break;
280*4882a593Smuzhiyun 	default:
281*4882a593Smuzhiyun 		return -EINVAL;
282*4882a593Smuzhiyun 	}
283*4882a593Smuzhiyun 
284*4882a593Smuzhiyun 	regmap_update_bits(rd->regmap, I2S_CKR1, mask, val);
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun 	return 0;
287*4882a593Smuzhiyun }
288*4882a593Smuzhiyun 
rk_dsm_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)289*4882a593Smuzhiyun static int rk_dsm_hw_params(struct snd_pcm_substream *substream,
290*4882a593Smuzhiyun 			    struct snd_pcm_hw_params *params,
291*4882a593Smuzhiyun 			    struct snd_soc_dai *dai)
292*4882a593Smuzhiyun {
293*4882a593Smuzhiyun 	struct rk_dsm_priv *rd =
294*4882a593Smuzhiyun 		snd_soc_component_get_drvdata(dai->component);
295*4882a593Smuzhiyun 	unsigned int srt = 0, val = 0;
296*4882a593Smuzhiyun 
297*4882a593Smuzhiyun 	rk_dsm_set_clk(rd, substream, params_rate(params));
298*4882a593Smuzhiyun 
299*4882a593Smuzhiyun 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
300*4882a593Smuzhiyun 		switch (params_rate(params)) {
301*4882a593Smuzhiyun 		case 8000:
302*4882a593Smuzhiyun 		case 11025:
303*4882a593Smuzhiyun 		case 12000:
304*4882a593Smuzhiyun 			srt = 0;
305*4882a593Smuzhiyun 			break;
306*4882a593Smuzhiyun 		case 16000:
307*4882a593Smuzhiyun 		case 22050:
308*4882a593Smuzhiyun 		case 24000:
309*4882a593Smuzhiyun 			srt = 1;
310*4882a593Smuzhiyun 			break;
311*4882a593Smuzhiyun 		case 32000:
312*4882a593Smuzhiyun 		case 44100:
313*4882a593Smuzhiyun 		case 48000:
314*4882a593Smuzhiyun 			srt = 2;
315*4882a593Smuzhiyun 			break;
316*4882a593Smuzhiyun 		case 64000:
317*4882a593Smuzhiyun 		case 88200:
318*4882a593Smuzhiyun 		case 96000:
319*4882a593Smuzhiyun 			srt = 3;
320*4882a593Smuzhiyun 			break;
321*4882a593Smuzhiyun 		case 128000:
322*4882a593Smuzhiyun 		case 176400:
323*4882a593Smuzhiyun 		case 192000:
324*4882a593Smuzhiyun 			srt = 4;
325*4882a593Smuzhiyun 			break;
326*4882a593Smuzhiyun 		default:
327*4882a593Smuzhiyun 			return -EINVAL;
328*4882a593Smuzhiyun 		}
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun 		regmap_update_bits(rd->regmap, DACCFG1,
331*4882a593Smuzhiyun 				   DSM_DACCFG1_DACSRT_MASK,
332*4882a593Smuzhiyun 				   DSM_DACCFG1_DACSRT(srt));
333*4882a593Smuzhiyun 
334*4882a593Smuzhiyun 		switch (params_format(params)) {
335*4882a593Smuzhiyun 		case SNDRV_PCM_FORMAT_S16_LE:
336*4882a593Smuzhiyun 			val = 16;
337*4882a593Smuzhiyun 			break;
338*4882a593Smuzhiyun 		case SNDRV_PCM_FORMAT_S24_LE:
339*4882a593Smuzhiyun 		case SNDRV_PCM_FORMAT_S32_LE:
340*4882a593Smuzhiyun 			val = 24;
341*4882a593Smuzhiyun 			break;
342*4882a593Smuzhiyun 		default:
343*4882a593Smuzhiyun 			return -EINVAL;
344*4882a593Smuzhiyun 		}
345*4882a593Smuzhiyun 
346*4882a593Smuzhiyun 		regmap_update_bits(rd->regmap, I2S_RXCR0,
347*4882a593Smuzhiyun 				   DSM_I2S_RXCR0_VDW_MASK,
348*4882a593Smuzhiyun 				   DSM_I2S_RXCR0_VDW(val));
349*4882a593Smuzhiyun 		regmap_update_bits(rd->regmap, DACPWM_CTRL,
350*4882a593Smuzhiyun 				   DSM_DACPWM_CTRL_PWM_MODE_CKE_MASK |
351*4882a593Smuzhiyun 				   DSM_DACPWM_CTRL_PWM_EN_MASK,
352*4882a593Smuzhiyun 				   DSM_DACPWM_CTRL_PWM_MODE_CKE_EN |
353*4882a593Smuzhiyun 				   DSM_DACPWM_CTRL_PWM_EN);
354*4882a593Smuzhiyun 	}
355*4882a593Smuzhiyun 
356*4882a593Smuzhiyun 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
357*4882a593Smuzhiyun 		regmap_update_bits(rd->regmap, I2S_XFER,
358*4882a593Smuzhiyun 				   DSM_I2S_XFER_RXS_MASK,
359*4882a593Smuzhiyun 				   DSM_I2S_XFER_RXS_START);
360*4882a593Smuzhiyun 		regmap_update_bits(rd->regmap, DACDIGEN,
361*4882a593Smuzhiyun 				   DSM_DACDIGEN_DAC_GLBEN_MASK |
362*4882a593Smuzhiyun 				   DSM_DACDIGEN_DACEN_L0R1_MASK,
363*4882a593Smuzhiyun 				   DSM_DACDIGEN_DAC_GLBEN_EN |
364*4882a593Smuzhiyun 				   DSM_DACDIGEN_DACEN_L0R1_EN);
365*4882a593Smuzhiyun 	}
366*4882a593Smuzhiyun 
367*4882a593Smuzhiyun 	return 0;
368*4882a593Smuzhiyun }
369*4882a593Smuzhiyun 
rk_dsm_pcm_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)370*4882a593Smuzhiyun static int rk_dsm_pcm_startup(struct snd_pcm_substream *substream,
371*4882a593Smuzhiyun 			      struct snd_soc_dai *dai)
372*4882a593Smuzhiyun {
373*4882a593Smuzhiyun 	struct rk_dsm_priv *rd =
374*4882a593Smuzhiyun 		snd_soc_component_get_drvdata(dai->component);
375*4882a593Smuzhiyun 
376*4882a593Smuzhiyun 	gpiod_set_value(rd->pa_ctl, 1);
377*4882a593Smuzhiyun 	if (rd->pa_ctl_delay_ms)
378*4882a593Smuzhiyun 		msleep(rd->pa_ctl_delay_ms);
379*4882a593Smuzhiyun 
380*4882a593Smuzhiyun 	return 0;
381*4882a593Smuzhiyun }
382*4882a593Smuzhiyun 
rk_dsm_reset(struct rk_dsm_priv * rd)383*4882a593Smuzhiyun static void rk_dsm_reset(struct rk_dsm_priv *rd)
384*4882a593Smuzhiyun {
385*4882a593Smuzhiyun 	if (IS_ERR(rd->rc))
386*4882a593Smuzhiyun 		return;
387*4882a593Smuzhiyun 
388*4882a593Smuzhiyun 	reset_control_assert(rd->rc);
389*4882a593Smuzhiyun 	udelay(5);
390*4882a593Smuzhiyun 	reset_control_deassert(rd->rc);
391*4882a593Smuzhiyun 	udelay(5);
392*4882a593Smuzhiyun }
393*4882a593Smuzhiyun 
rk_dsm_pcm_shutdown(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)394*4882a593Smuzhiyun static void rk_dsm_pcm_shutdown(struct snd_pcm_substream *substream,
395*4882a593Smuzhiyun 				struct snd_soc_dai *dai)
396*4882a593Smuzhiyun {
397*4882a593Smuzhiyun 	struct rk_dsm_priv *rd =
398*4882a593Smuzhiyun 		snd_soc_component_get_drvdata(dai->component);
399*4882a593Smuzhiyun 
400*4882a593Smuzhiyun 	gpiod_set_value(rd->pa_ctl, 0);
401*4882a593Smuzhiyun 
402*4882a593Smuzhiyun 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
403*4882a593Smuzhiyun 		regmap_update_bits(rd->regmap, DACPWM_CTRL,
404*4882a593Smuzhiyun 				   DSM_DACPWM_CTRL_PWM_MODE_CKE_MASK |
405*4882a593Smuzhiyun 				   DSM_DACPWM_CTRL_PWM_EN_MASK,
406*4882a593Smuzhiyun 				   DSM_DACPWM_CTRL_PWM_MODE_CKE_DIS |
407*4882a593Smuzhiyun 				   DSM_DACPWM_CTRL_PWM_DIS);
408*4882a593Smuzhiyun 		regmap_update_bits(rd->regmap, I2S_XFER,
409*4882a593Smuzhiyun 				   DSM_I2S_XFER_RXS_MASK,
410*4882a593Smuzhiyun 				   DSM_I2S_XFER_RXS_STOP);
411*4882a593Smuzhiyun 		regmap_update_bits(rd->regmap, I2S_CLR,
412*4882a593Smuzhiyun 				   DSM_I2S_CLR_RXC_MASK,
413*4882a593Smuzhiyun 				   DSM_I2S_CLR_RXC_CLR);
414*4882a593Smuzhiyun 		regmap_update_bits(rd->regmap, DACDIGEN,
415*4882a593Smuzhiyun 				   DSM_DACDIGEN_DAC_GLBEN_MASK |
416*4882a593Smuzhiyun 				   DSM_DACDIGEN_DACEN_L0R1_MASK,
417*4882a593Smuzhiyun 				   DSM_DACDIGEN_DAC_GLBEN_DIS |
418*4882a593Smuzhiyun 				   DSM_DACDIGEN_DACEN_L0R1_DIS);
419*4882a593Smuzhiyun 	}
420*4882a593Smuzhiyun 
421*4882a593Smuzhiyun 	rk_dsm_reset(rd);
422*4882a593Smuzhiyun }
423*4882a593Smuzhiyun 
424*4882a593Smuzhiyun static const struct snd_soc_dai_ops rd_dai_ops = {
425*4882a593Smuzhiyun 	.hw_params = rk_dsm_hw_params,
426*4882a593Smuzhiyun 	.set_fmt = rk_dsm_set_dai_fmt,
427*4882a593Smuzhiyun 	.startup = rk_dsm_pcm_startup,
428*4882a593Smuzhiyun 	.shutdown = rk_dsm_pcm_shutdown,
429*4882a593Smuzhiyun };
430*4882a593Smuzhiyun 
431*4882a593Smuzhiyun static struct snd_soc_dai_driver rd_dai[] = {
432*4882a593Smuzhiyun 	{
433*4882a593Smuzhiyun 		.name = "rk_dsm",
434*4882a593Smuzhiyun 		.id = 0,
435*4882a593Smuzhiyun 		.playback = {
436*4882a593Smuzhiyun 			.stream_name = "Playback",
437*4882a593Smuzhiyun 			.channels_min = 2,
438*4882a593Smuzhiyun 			.channels_max = 2,
439*4882a593Smuzhiyun 			.rates = SNDRV_PCM_RATE_8000_192000,
440*4882a593Smuzhiyun 			.formats = (SNDRV_PCM_FMTBIT_S16_LE |
441*4882a593Smuzhiyun 				    SNDRV_PCM_FMTBIT_S24_LE |
442*4882a593Smuzhiyun 				    SNDRV_PCM_FMTBIT_S32_LE),
443*4882a593Smuzhiyun 		},
444*4882a593Smuzhiyun 		.ops = &rd_dai_ops,
445*4882a593Smuzhiyun 	},
446*4882a593Smuzhiyun };
447*4882a593Smuzhiyun 
448*4882a593Smuzhiyun static const struct snd_soc_component_driver soc_codec_dev_rd = {
449*4882a593Smuzhiyun 	.controls = rk_dsm_snd_controls,
450*4882a593Smuzhiyun 	.num_controls = ARRAY_SIZE(rk_dsm_snd_controls),
451*4882a593Smuzhiyun };
452*4882a593Smuzhiyun 
453*4882a593Smuzhiyun static const struct regmap_config rd_regmap_config = {
454*4882a593Smuzhiyun 	.reg_bits = 32,
455*4882a593Smuzhiyun 	.reg_stride = 4,
456*4882a593Smuzhiyun 	.val_bits = 32,
457*4882a593Smuzhiyun 	.max_register = VERSION,
458*4882a593Smuzhiyun 	.cache_type = REGCACHE_FLAT,
459*4882a593Smuzhiyun };
460*4882a593Smuzhiyun 
rk3562_soc_init(struct device * dev)461*4882a593Smuzhiyun static int rk3562_soc_init(struct device *dev)
462*4882a593Smuzhiyun {
463*4882a593Smuzhiyun 	struct rk_dsm_priv *rd = dev_get_drvdata(dev);
464*4882a593Smuzhiyun 
465*4882a593Smuzhiyun 	if (IS_ERR(rd->grf))
466*4882a593Smuzhiyun 		return PTR_ERR(rd->grf);
467*4882a593Smuzhiyun 
468*4882a593Smuzhiyun 	/* enable internal codec to i2s1 */
469*4882a593Smuzhiyun 	return regmap_write(rd->grf, RK3562_GRF_PERI_AUDIO_CON,
470*4882a593Smuzhiyun 			    (BIT(14) << 16 | BIT(14) | 0x0a100a10));
471*4882a593Smuzhiyun }
472*4882a593Smuzhiyun 
rk3562_soc_deinit(struct device * dev)473*4882a593Smuzhiyun static void rk3562_soc_deinit(struct device *dev)
474*4882a593Smuzhiyun {
475*4882a593Smuzhiyun 	struct rk_dsm_priv *rd = dev_get_drvdata(dev);
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun 	if (IS_ERR(rd->grf))
478*4882a593Smuzhiyun 		return;
479*4882a593Smuzhiyun 
480*4882a593Smuzhiyun 	regmap_write(rd->grf, RK3562_GRF_PERI_AUDIO_CON, (BIT(14) << 16) | 0x0a100a10);
481*4882a593Smuzhiyun }
482*4882a593Smuzhiyun 
483*4882a593Smuzhiyun static const struct rk_dsm_soc_data rk3562_data = {
484*4882a593Smuzhiyun 	.init = rk3562_soc_init,
485*4882a593Smuzhiyun 	.deinit = rk3562_soc_deinit,
486*4882a593Smuzhiyun };
487*4882a593Smuzhiyun 
488*4882a593Smuzhiyun #ifdef CONFIG_OF
489*4882a593Smuzhiyun static const struct of_device_id rd_of_match[] = {
490*4882a593Smuzhiyun 	{ .compatible = "rockchip,rk3562-dsm", .data = &rk3562_data },
491*4882a593Smuzhiyun 	{},
492*4882a593Smuzhiyun };
493*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, rd_of_match);
494*4882a593Smuzhiyun #endif
495*4882a593Smuzhiyun 
496*4882a593Smuzhiyun #ifdef CONFIG_PM
rk_dsm_runtime_resume(struct device * dev)497*4882a593Smuzhiyun static int rk_dsm_runtime_resume(struct device *dev)
498*4882a593Smuzhiyun {
499*4882a593Smuzhiyun 	struct rk_dsm_priv *rd = dev_get_drvdata(dev);
500*4882a593Smuzhiyun 	int ret = 0;
501*4882a593Smuzhiyun 
502*4882a593Smuzhiyun 	ret = clk_prepare_enable(rd->pclk);
503*4882a593Smuzhiyun 	if (ret)
504*4882a593Smuzhiyun 		return ret;
505*4882a593Smuzhiyun 
506*4882a593Smuzhiyun 	regcache_cache_only(rd->regmap, false);
507*4882a593Smuzhiyun 	regcache_mark_dirty(rd->regmap);
508*4882a593Smuzhiyun 
509*4882a593Smuzhiyun 	ret = clk_prepare_enable(rd->clk_dac);
510*4882a593Smuzhiyun 	if (ret)
511*4882a593Smuzhiyun 		goto err;
512*4882a593Smuzhiyun 
513*4882a593Smuzhiyun 	return 0;
514*4882a593Smuzhiyun err:
515*4882a593Smuzhiyun 	clk_disable_unprepare(rd->pclk);
516*4882a593Smuzhiyun 
517*4882a593Smuzhiyun 	return ret;
518*4882a593Smuzhiyun }
519*4882a593Smuzhiyun 
rk_dsm_runtime_suspend(struct device * dev)520*4882a593Smuzhiyun static int rk_dsm_runtime_suspend(struct device *dev)
521*4882a593Smuzhiyun {
522*4882a593Smuzhiyun 	struct rk_dsm_priv *rd = dev_get_drvdata(dev);
523*4882a593Smuzhiyun 
524*4882a593Smuzhiyun 	regcache_cache_only(rd->regmap, true);
525*4882a593Smuzhiyun 	clk_disable_unprepare(rd->clk_dac);
526*4882a593Smuzhiyun 	clk_disable_unprepare(rd->pclk);
527*4882a593Smuzhiyun 
528*4882a593Smuzhiyun 	return 0;
529*4882a593Smuzhiyun }
530*4882a593Smuzhiyun #endif
531*4882a593Smuzhiyun 
rk_dsm_platform_probe(struct platform_device * pdev)532*4882a593Smuzhiyun static int rk_dsm_platform_probe(struct platform_device *pdev)
533*4882a593Smuzhiyun {
534*4882a593Smuzhiyun 	struct device_node *np = pdev->dev.of_node;
535*4882a593Smuzhiyun 	struct rk_dsm_priv *rd;
536*4882a593Smuzhiyun 	void __iomem *base;
537*4882a593Smuzhiyun 	int ret = 0;
538*4882a593Smuzhiyun 
539*4882a593Smuzhiyun 	rd = devm_kzalloc(&pdev->dev, sizeof(*rd), GFP_KERNEL);
540*4882a593Smuzhiyun 	if (!rd)
541*4882a593Smuzhiyun 		return -ENOMEM;
542*4882a593Smuzhiyun 
543*4882a593Smuzhiyun 	rd->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
544*4882a593Smuzhiyun 	if (IS_ERR(rd->grf))
545*4882a593Smuzhiyun 		return PTR_ERR(rd->grf);
546*4882a593Smuzhiyun 
547*4882a593Smuzhiyun 	if (device_property_read_u32(&pdev->dev, "rockchip,pa-ctl-delay-ms",
548*4882a593Smuzhiyun 				     &rd->pa_ctl_delay_ms))
549*4882a593Smuzhiyun 		rd->pa_ctl_delay_ms = 0;
550*4882a593Smuzhiyun 
551*4882a593Smuzhiyun 	rd->rc = devm_reset_control_get(&pdev->dev, "reset");
552*4882a593Smuzhiyun 
553*4882a593Smuzhiyun 	rd->clk_dac = devm_clk_get(&pdev->dev, "dac");
554*4882a593Smuzhiyun 	if (IS_ERR(rd->clk_dac))
555*4882a593Smuzhiyun 		return PTR_ERR(rd->clk_dac);
556*4882a593Smuzhiyun 
557*4882a593Smuzhiyun 	rd->pclk = devm_clk_get(&pdev->dev, "pclk");
558*4882a593Smuzhiyun 	if (IS_ERR(rd->pclk))
559*4882a593Smuzhiyun 		return PTR_ERR(rd->pclk);
560*4882a593Smuzhiyun 
561*4882a593Smuzhiyun 	base = devm_platform_ioremap_resource(pdev, 0);
562*4882a593Smuzhiyun 	if (IS_ERR(base))
563*4882a593Smuzhiyun 		return PTR_ERR(base);
564*4882a593Smuzhiyun 
565*4882a593Smuzhiyun 	rd->regmap =
566*4882a593Smuzhiyun 		devm_regmap_init_mmio(&pdev->dev, base, &rd_regmap_config);
567*4882a593Smuzhiyun 	if (IS_ERR(rd->regmap))
568*4882a593Smuzhiyun 		return PTR_ERR(rd->regmap);
569*4882a593Smuzhiyun 
570*4882a593Smuzhiyun 	platform_set_drvdata(pdev, rd);
571*4882a593Smuzhiyun 
572*4882a593Smuzhiyun 	rd->data = device_get_match_data(&pdev->dev);
573*4882a593Smuzhiyun 	if (rd->data && rd->data->init) {
574*4882a593Smuzhiyun 		ret = rd->data->init(&pdev->dev);
575*4882a593Smuzhiyun 		if (ret)
576*4882a593Smuzhiyun 			return ret;
577*4882a593Smuzhiyun 	}
578*4882a593Smuzhiyun 
579*4882a593Smuzhiyun 	pm_runtime_enable(&pdev->dev);
580*4882a593Smuzhiyun 	if (!pm_runtime_enabled(&pdev->dev)) {
581*4882a593Smuzhiyun 		ret = rk_dsm_runtime_resume(&pdev->dev);
582*4882a593Smuzhiyun 		if (ret)
583*4882a593Smuzhiyun 			goto err_pm_disable;
584*4882a593Smuzhiyun 	}
585*4882a593Smuzhiyun 
586*4882a593Smuzhiyun 	regmap_update_bits(rd->regmap, DACPWM_CTRL,
587*4882a593Smuzhiyun 			   DSM_DACPWM_CTRL_PWM_MODE_MASK,
588*4882a593Smuzhiyun 			   DSM_DACPWM_CTRL_PWM_MODE_0);
589*4882a593Smuzhiyun 
590*4882a593Smuzhiyun 	rd->pa_ctl = devm_gpiod_get_optional(&pdev->dev, "pa-ctl",
591*4882a593Smuzhiyun 					     GPIOD_OUT_LOW);
592*4882a593Smuzhiyun 
593*4882a593Smuzhiyun 	if (!rd->pa_ctl) {
594*4882a593Smuzhiyun 		dev_info(&pdev->dev, "no need pa-ctl gpio\n");
595*4882a593Smuzhiyun 	} else if (IS_ERR(rd->pa_ctl)) {
596*4882a593Smuzhiyun 		ret = PTR_ERR(rd->pa_ctl);
597*4882a593Smuzhiyun 		dev_err(&pdev->dev, "fail to request gpio pa-ctl\n");
598*4882a593Smuzhiyun 		goto err_suspend;
599*4882a593Smuzhiyun 	}
600*4882a593Smuzhiyun 
601*4882a593Smuzhiyun 	ret = devm_snd_soc_register_component(&pdev->dev, &soc_codec_dev_rd,
602*4882a593Smuzhiyun 					      rd_dai, ARRAY_SIZE(rd_dai));
603*4882a593Smuzhiyun 
604*4882a593Smuzhiyun 	if (ret)
605*4882a593Smuzhiyun 		goto err_suspend;
606*4882a593Smuzhiyun 
607*4882a593Smuzhiyun 	return 0;
608*4882a593Smuzhiyun 
609*4882a593Smuzhiyun err_suspend:
610*4882a593Smuzhiyun 	if (!pm_runtime_status_suspended(&pdev->dev))
611*4882a593Smuzhiyun 		rk_dsm_runtime_suspend(&pdev->dev);
612*4882a593Smuzhiyun err_pm_disable:
613*4882a593Smuzhiyun 	pm_runtime_disable(&pdev->dev);
614*4882a593Smuzhiyun 
615*4882a593Smuzhiyun 	if (rd->data && rd->data->deinit)
616*4882a593Smuzhiyun 		rd->data->deinit(&pdev->dev);
617*4882a593Smuzhiyun 
618*4882a593Smuzhiyun 	return ret;
619*4882a593Smuzhiyun }
620*4882a593Smuzhiyun 
rk_dsm_platform_remove(struct platform_device * pdev)621*4882a593Smuzhiyun static int rk_dsm_platform_remove(struct platform_device *pdev)
622*4882a593Smuzhiyun {
623*4882a593Smuzhiyun 	struct rk_dsm_priv *rd = dev_get_drvdata(&pdev->dev);
624*4882a593Smuzhiyun 
625*4882a593Smuzhiyun 	pm_runtime_disable(&pdev->dev);
626*4882a593Smuzhiyun 	if (!pm_runtime_status_suspended(&pdev->dev))
627*4882a593Smuzhiyun 		rk_dsm_runtime_suspend(&pdev->dev);
628*4882a593Smuzhiyun 
629*4882a593Smuzhiyun 	if (rd->data && rd->data->deinit)
630*4882a593Smuzhiyun 		rd->data->deinit(&pdev->dev);
631*4882a593Smuzhiyun 
632*4882a593Smuzhiyun 	return 0;
633*4882a593Smuzhiyun }
634*4882a593Smuzhiyun 
635*4882a593Smuzhiyun static const struct dev_pm_ops rd_pm = {
636*4882a593Smuzhiyun 	SET_RUNTIME_PM_OPS(rk_dsm_runtime_suspend,
637*4882a593Smuzhiyun 			   rk_dsm_runtime_resume, NULL)
638*4882a593Smuzhiyun };
639*4882a593Smuzhiyun 
640*4882a593Smuzhiyun static struct platform_driver rk_dsm_driver = {
641*4882a593Smuzhiyun 	.driver = {
642*4882a593Smuzhiyun 		.name = "rk_dsm",
643*4882a593Smuzhiyun 		.of_match_table = of_match_ptr(rd_of_match),
644*4882a593Smuzhiyun 		.pm = &rd_pm,
645*4882a593Smuzhiyun 	},
646*4882a593Smuzhiyun 	.probe = rk_dsm_platform_probe,
647*4882a593Smuzhiyun 	.remove = rk_dsm_platform_remove,
648*4882a593Smuzhiyun };
649*4882a593Smuzhiyun module_platform_driver(rk_dsm_driver);
650*4882a593Smuzhiyun 
651*4882a593Smuzhiyun MODULE_AUTHOR("Jason Zhu <jason.zhu@rock-chips.com>");
652*4882a593Smuzhiyun MODULE_DESCRIPTION("ASoC Rockchip Delta-sigma Digital Converter Driver");
653*4882a593Smuzhiyun MODULE_LICENSE("GPL");
654