xref: /OK3568_Linux_fs/kernel/sound/soc/codecs/rk1000_codec.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun //
3*4882a593Smuzhiyun // rxk1000_codec.c  --  rk1000 ALSA Soc Audio driver
4*4882a593Smuzhiyun //
5*4882a593Smuzhiyun // Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd All rights reserved.
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #include <linux/delay.h>
8*4882a593Smuzhiyun #include <linux/gpio/consumer.h>
9*4882a593Smuzhiyun #include <linux/i2c.h>
10*4882a593Smuzhiyun #include <linux/module.h>
11*4882a593Smuzhiyun #include <sound/core.h>
12*4882a593Smuzhiyun #include <sound/pcm.h>
13*4882a593Smuzhiyun #include <sound/pcm_params.h>
14*4882a593Smuzhiyun #include <sound/soc.h>
15*4882a593Smuzhiyun #include <sound/soc-dapm.h>
16*4882a593Smuzhiyun #include "rk1000_codec.h"
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun #define FREQ441KHZ	(0x11 << 1)
19*4882a593Smuzhiyun /* rk1000 output volume, DAC Digital Gain */
20*4882a593Smuzhiyun /* 0x0000 ~ 0xF42 */
21*4882a593Smuzhiyun #define VOLUME_OUTPUT	0xF42
22*4882a593Smuzhiyun /* 0x0 ~ 0x3f(bit0-bit5)  max=0x0(+6DB) min=0x3f(-60DB)	 Analog Gain */
23*4882a593Smuzhiyun #define VOLUME_CODEC_PA	0x0
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun /* rk1000 input volume, rk610 can not adjust the recording volume */
26*4882a593Smuzhiyun #define VOLUME_INPUT	0x07
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun #define OUT_CAPLESS	(1)
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun static const struct reg_default rk1000_codec_reg[] = {
31*4882a593Smuzhiyun 	{ 0x00, 0x05 },
32*4882a593Smuzhiyun 	{ 0x01, 0x04 },
33*4882a593Smuzhiyun 	{ 0x02, 0xfd },
34*4882a593Smuzhiyun 	{ 0x03, 0xf3 },
35*4882a593Smuzhiyun 	{ 0x04, 0x03 },
36*4882a593Smuzhiyun 	{ 0x05, 0x00 },
37*4882a593Smuzhiyun 	{ 0x06, 0x00 },
38*4882a593Smuzhiyun 	{ 0x07, 0x00 },
39*4882a593Smuzhiyun 	{ 0x08, 0x00 },
40*4882a593Smuzhiyun 	{ 0x09, 0x05 },
41*4882a593Smuzhiyun 	{ 0x0a, 0x00 },
42*4882a593Smuzhiyun 	{ 0x0b, 0x00 },
43*4882a593Smuzhiyun 	{ 0x0c, 0x97 },
44*4882a593Smuzhiyun 	{ 0x0d, 0x97 },
45*4882a593Smuzhiyun 	{ 0x0e, 0x97 },
46*4882a593Smuzhiyun 	{ 0x0f, 0x97 },
47*4882a593Smuzhiyun 	{ 0x10, 0x97 },
48*4882a593Smuzhiyun 	{ 0x11, 0x97 },
49*4882a593Smuzhiyun 	{ 0x12, 0xcc },
50*4882a593Smuzhiyun 	{ 0x13, 0x00 },
51*4882a593Smuzhiyun 	{ 0x14, 0x00 },
52*4882a593Smuzhiyun 	{ 0x15, 0xf1 },
53*4882a593Smuzhiyun 	{ 0x16, 0x90 },
54*4882a593Smuzhiyun 	{ 0x17, 0xff },
55*4882a593Smuzhiyun 	{ 0x18, 0xff },
56*4882a593Smuzhiyun 	{ 0x19, 0xff },
57*4882a593Smuzhiyun 	{ 0x1a, 0x9c },
58*4882a593Smuzhiyun 	{ 0x1b, 0x00 },
59*4882a593Smuzhiyun 	{ 0x1c, 0x00 },
60*4882a593Smuzhiyun 	{ 0x1d, 0xff },
61*4882a593Smuzhiyun 	{ 0x1e, 0xff },
62*4882a593Smuzhiyun 	{ 0x1f, 0xff },
63*4882a593Smuzhiyun };
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun struct rk1000_codec_priv {
66*4882a593Smuzhiyun 	struct regmap *regmap;
67*4882a593Smuzhiyun 	struct regmap *ctlmap;
68*4882a593Smuzhiyun 	struct snd_soc_component *component;
69*4882a593Smuzhiyun 	struct delayed_work pa_delayed_work;
70*4882a593Smuzhiyun 	struct gpio_desc *spk_en_gpio;
71*4882a593Smuzhiyun 	/*
72*4882a593Smuzhiyun 	 * Some amplifiers enable a longer time.
73*4882a593Smuzhiyun 	 * config after pa_enable_io delay pa_enable_time(ms)
74*4882a593Smuzhiyun 	 * so value range is 0 - 8000.
75*4882a593Smuzhiyun 	 */
76*4882a593Smuzhiyun 	unsigned int pa_enable_time;
77*4882a593Smuzhiyun };
78*4882a593Smuzhiyun 
spk_ctrl_fun(struct snd_soc_component * component,int status)79*4882a593Smuzhiyun static void spk_ctrl_fun(struct snd_soc_component *component, int status)
80*4882a593Smuzhiyun {
81*4882a593Smuzhiyun 	struct rk1000_codec_priv *rk1000_codec;
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun 	rk1000_codec = snd_soc_component_get_drvdata(component);
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun 	if (rk1000_codec->spk_en_gpio)
86*4882a593Smuzhiyun 		gpiod_set_value(rk1000_codec->spk_en_gpio, status);
87*4882a593Smuzhiyun }
88*4882a593Smuzhiyun 
rk1000_codec_set_bias_level(struct snd_soc_component * component,enum snd_soc_bias_level level)89*4882a593Smuzhiyun static int rk1000_codec_set_bias_level(struct snd_soc_component *component,
90*4882a593Smuzhiyun 				       enum snd_soc_bias_level level)
91*4882a593Smuzhiyun {
92*4882a593Smuzhiyun 	switch (level) {
93*4882a593Smuzhiyun 	case SND_SOC_BIAS_ON:
94*4882a593Smuzhiyun 		break;
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun 	case SND_SOC_BIAS_PREPARE:
97*4882a593Smuzhiyun 		snd_soc_component_write(component, ACCELCODEC_R1D, 0x2a);
98*4882a593Smuzhiyun 		snd_soc_component_write(component, ACCELCODEC_R1E, 0x40);
99*4882a593Smuzhiyun 		snd_soc_component_write(component, ACCELCODEC_R1F, 0x49);
100*4882a593Smuzhiyun 		break;
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun 	case SND_SOC_BIAS_STANDBY:
103*4882a593Smuzhiyun 		snd_soc_component_write(component, ACCELCODEC_R1D, 0x2a);
104*4882a593Smuzhiyun 		snd_soc_component_write(component, ACCELCODEC_R1E, 0x40);
105*4882a593Smuzhiyun 		snd_soc_component_write(component, ACCELCODEC_R1F, 0x49);
106*4882a593Smuzhiyun 		break;
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun 	case SND_SOC_BIAS_OFF:
109*4882a593Smuzhiyun 		spk_ctrl_fun(component, GPIO_LOW);
110*4882a593Smuzhiyun 		snd_soc_component_write(component, ACCELCODEC_R1D, 0xFF);
111*4882a593Smuzhiyun 		snd_soc_component_write(component, ACCELCODEC_R1E, 0xFF);
112*4882a593Smuzhiyun 		snd_soc_component_write(component, ACCELCODEC_R1F, 0xFF);
113*4882a593Smuzhiyun 		break;
114*4882a593Smuzhiyun 	}
115*4882a593Smuzhiyun 	return 0;
116*4882a593Smuzhiyun }
117*4882a593Smuzhiyun 
rk1000_codec_set_dai_fmt(struct snd_soc_dai * codec_dai,unsigned int fmt)118*4882a593Smuzhiyun static int rk1000_codec_set_dai_fmt(struct snd_soc_dai *codec_dai,
119*4882a593Smuzhiyun 				    unsigned int fmt)
120*4882a593Smuzhiyun {
121*4882a593Smuzhiyun 	struct snd_soc_component *component = codec_dai->component;
122*4882a593Smuzhiyun 	struct rk1000_codec_priv *rk1000_codec;
123*4882a593Smuzhiyun 	u16 iface = 0;
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun 	rk1000_codec = snd_soc_component_get_drvdata(component);
126*4882a593Smuzhiyun 	/* setup Vmid and Vref, other module power down */
127*4882a593Smuzhiyun 	snd_soc_component_write(component, ACCELCODEC_R1D, 0x2a);
128*4882a593Smuzhiyun 	snd_soc_component_write(component, ACCELCODEC_R1E, 0x40);
129*4882a593Smuzhiyun 	/* set master/slave audio interface */
130*4882a593Smuzhiyun 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
131*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_CBM_CFM:
132*4882a593Smuzhiyun 		iface = 0x0040;
133*4882a593Smuzhiyun 		break;
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_CBS_CFS:
136*4882a593Smuzhiyun 		iface = 0x0000;
137*4882a593Smuzhiyun 		break;
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun 	default:
140*4882a593Smuzhiyun 		return -EINVAL;
141*4882a593Smuzhiyun 	}
142*4882a593Smuzhiyun 	/* interface format */
143*4882a593Smuzhiyun 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
144*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_I2S:
145*4882a593Smuzhiyun 		iface |= 0x0002;
146*4882a593Smuzhiyun 		break;
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_RIGHT_J:
149*4882a593Smuzhiyun 		break;
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_LEFT_J:
152*4882a593Smuzhiyun 		iface |= 0x0001;
153*4882a593Smuzhiyun 		break;
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_DSP_A:
156*4882a593Smuzhiyun 		iface |= 0x0003;
157*4882a593Smuzhiyun 		break;
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_DSP_B:
160*4882a593Smuzhiyun 		iface |= 0x0013;
161*4882a593Smuzhiyun 		break;
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun 	default:
164*4882a593Smuzhiyun 		return -EINVAL;
165*4882a593Smuzhiyun 	}
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun 	/* clock inversion */
168*4882a593Smuzhiyun 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
169*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_NB_NF:
170*4882a593Smuzhiyun 		break;
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_IB_IF:
173*4882a593Smuzhiyun 		iface |= 0x0090;
174*4882a593Smuzhiyun 		break;
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_IB_NF:
177*4882a593Smuzhiyun 		iface |= 0x0080;
178*4882a593Smuzhiyun 		break;
179*4882a593Smuzhiyun 
180*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_NB_IF:
181*4882a593Smuzhiyun 		iface |= 0x0010;
182*4882a593Smuzhiyun 		break;
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun 	default:
185*4882a593Smuzhiyun 		return -EINVAL;
186*4882a593Smuzhiyun 	}
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun 	snd_soc_component_write(component, ACCELCODEC_R09, iface);
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun 	return 0;
191*4882a593Smuzhiyun }
192*4882a593Smuzhiyun 
rk1000_codec_pcm_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)193*4882a593Smuzhiyun static int rk1000_codec_pcm_hw_params(struct snd_pcm_substream *substream,
194*4882a593Smuzhiyun 				      struct snd_pcm_hw_params *params,
195*4882a593Smuzhiyun 				      struct snd_soc_dai *dai)
196*4882a593Smuzhiyun {
197*4882a593Smuzhiyun 	u32 iface;
198*4882a593Smuzhiyun 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
199*4882a593Smuzhiyun 	struct snd_soc_component *component = dai->component;
200*4882a593Smuzhiyun 	unsigned int dai_fmt;
201*4882a593Smuzhiyun 
202*4882a593Smuzhiyun 	dai_fmt = rtd->card->dai_link[0].dai_fmt;
203*4882a593Smuzhiyun 	iface = snd_soc_component_read(component, ACCELCODEC_R09) & 0x1f3;
204*4882a593Smuzhiyun 	snd_soc_component_write(component, ACCELCODEC_R0C, 0x17);
205*4882a593Smuzhiyun 	snd_soc_component_write(component, ACCELCODEC_R04,
206*4882a593Smuzhiyun 				ASC_INT_MUTE_L | ASC_INT_MUTE_R |
207*4882a593Smuzhiyun 		      ASC_SIDETONE_L_OFF | ASC_SIDETONE_R_OFF);
208*4882a593Smuzhiyun 	snd_soc_component_write(component, ACCELCODEC_R0B,
209*4882a593Smuzhiyun 				ASC_DEC_DISABLE | ASC_INT_DISABLE);
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun 	if ((dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM)
212*4882a593Smuzhiyun 		iface |= ASC_INVERT_BCLK;
213*4882a593Smuzhiyun 	snd_soc_component_write(component, ACCELCODEC_R09, iface);
214*4882a593Smuzhiyun 	snd_soc_component_write(component, ACCELCODEC_R0A, 0xa0);
215*4882a593Smuzhiyun 	snd_soc_component_write(component, ACCELCODEC_R0B, ASC_DEC_ENABLE | ASC_INT_ENABLE);
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun 	return 0;
218*4882a593Smuzhiyun }
219*4882a593Smuzhiyun 
rk1000_codec_mute(struct snd_soc_dai * dai,int mute,int stream)220*4882a593Smuzhiyun static int rk1000_codec_mute(struct snd_soc_dai *dai, int mute, int stream)
221*4882a593Smuzhiyun {
222*4882a593Smuzhiyun 	struct snd_soc_component *component = dai->component;
223*4882a593Smuzhiyun 	struct rk1000_codec_priv *rk1000_codec;
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun 	rk1000_codec = snd_soc_component_get_drvdata(component);
226*4882a593Smuzhiyun 	if (mute) {
227*4882a593Smuzhiyun 		/* AOL */
228*4882a593Smuzhiyun 		snd_soc_component_write(component, ACCELCODEC_R17, 0xFF);
229*4882a593Smuzhiyun 		/* AOR */
230*4882a593Smuzhiyun 		snd_soc_component_write(component, ACCELCODEC_R18, 0xFF);
231*4882a593Smuzhiyun 		/* AOM */
232*4882a593Smuzhiyun 		snd_soc_component_write(component, ACCELCODEC_R19, 0xFF);
233*4882a593Smuzhiyun 		/* soft mute */
234*4882a593Smuzhiyun 		snd_soc_component_write(component, ACCELCODEC_R04,
235*4882a593Smuzhiyun 					ASC_INT_MUTE_L | ASC_INT_MUTE_R |
236*4882a593Smuzhiyun 			      ASC_SIDETONE_L_OFF | ASC_SIDETONE_R_OFF);
237*4882a593Smuzhiyun 	} else {
238*4882a593Smuzhiyun 		/* setup Vmid and Vref, other module power down */
239*4882a593Smuzhiyun 		snd_soc_component_write(component, ACCELCODEC_R1D, 0x2a);
240*4882a593Smuzhiyun 		snd_soc_component_write(component, ACCELCODEC_R1E, 0x40);
241*4882a593Smuzhiyun 		/* AOL */
242*4882a593Smuzhiyun 		snd_soc_component_write(component, ACCELCODEC_R17,
243*4882a593Smuzhiyun 					VOLUME_CODEC_PA | ASC_OUTPUT_ACTIVE |
244*4882a593Smuzhiyun 			      ASC_CROSSZERO_EN);
245*4882a593Smuzhiyun 		/* AOR */
246*4882a593Smuzhiyun 		snd_soc_component_write(component, ACCELCODEC_R18,
247*4882a593Smuzhiyun 					VOLUME_CODEC_PA | ASC_OUTPUT_ACTIVE |
248*4882a593Smuzhiyun 			      ASC_CROSSZERO_EN);
249*4882a593Smuzhiyun 		snd_soc_component_write(component, ACCELCODEC_R04,
250*4882a593Smuzhiyun 					ASC_INT_ACTIVE_L | ASC_INT_ACTIVE_R |
251*4882a593Smuzhiyun 			      ASC_SIDETONE_L_OFF | ASC_SIDETONE_R_OFF);
252*4882a593Smuzhiyun 		/* AOM */
253*4882a593Smuzhiyun 		snd_soc_component_write(component, ACCELCODEC_R19, 0x7F);
254*4882a593Smuzhiyun 		#if OUT_CAPLESS
255*4882a593Smuzhiyun 		snd_soc_component_write(component, ACCELCODEC_R1F,
256*4882a593Smuzhiyun 					0x09 | ASC_PDMIXM_ENABLE);
257*4882a593Smuzhiyun 		#else
258*4882a593Smuzhiyun 		snd_soc_component_write(component, ACCELCODEC_R1F,
259*4882a593Smuzhiyun 					0x09 | ASC_PDMIXM_ENABLE | ASC_PDPAM_ENABLE);
260*4882a593Smuzhiyun 		#endif
261*4882a593Smuzhiyun 	}
262*4882a593Smuzhiyun 
263*4882a593Smuzhiyun 	return 0;
264*4882a593Smuzhiyun }
265*4882a593Smuzhiyun 
pa_delayedwork(struct work_struct * work)266*4882a593Smuzhiyun static void pa_delayedwork(struct work_struct *work)
267*4882a593Smuzhiyun {
268*4882a593Smuzhiyun 	struct rk1000_codec_priv *priv = container_of(work,
269*4882a593Smuzhiyun 						      struct rk1000_codec_priv,
270*4882a593Smuzhiyun 						      pa_delayed_work.work);
271*4882a593Smuzhiyun 	struct snd_soc_component *component = priv->component;
272*4882a593Smuzhiyun 
273*4882a593Smuzhiyun 	spk_ctrl_fun(component, GPIO_HIGH);
274*4882a593Smuzhiyun }
275*4882a593Smuzhiyun 
276*4882a593Smuzhiyun static struct snd_soc_dai_ops rk1000_codec_ops = {
277*4882a593Smuzhiyun 	.hw_params = rk1000_codec_pcm_hw_params,
278*4882a593Smuzhiyun 	.set_fmt = rk1000_codec_set_dai_fmt,
279*4882a593Smuzhiyun 	.mute_stream = rk1000_codec_mute,
280*4882a593Smuzhiyun 	.no_capture_mute = 1,
281*4882a593Smuzhiyun };
282*4882a593Smuzhiyun 
283*4882a593Smuzhiyun #define RK1000_CODEC_RATES SNDRV_PCM_RATE_8000_192000
284*4882a593Smuzhiyun #define RK1000_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |  \
285*4882a593Smuzhiyun 			      SNDRV_PCM_FMTBIT_S20_3LE | \
286*4882a593Smuzhiyun 			      SNDRV_PCM_FMTBIT_S24_LE)
287*4882a593Smuzhiyun 
288*4882a593Smuzhiyun static struct snd_soc_dai_driver rk1000_codec_dai[] = {
289*4882a593Smuzhiyun 	{
290*4882a593Smuzhiyun 		.name = "rk1000_codec",
291*4882a593Smuzhiyun 		.playback = {
292*4882a593Smuzhiyun 			.stream_name = "Playback",
293*4882a593Smuzhiyun 			.channels_min = 2,
294*4882a593Smuzhiyun 			.channels_max = 8,
295*4882a593Smuzhiyun 			.rates = RK1000_CODEC_RATES,
296*4882a593Smuzhiyun 			.formats = RK1000_CODEC_FORMATS,
297*4882a593Smuzhiyun 		},
298*4882a593Smuzhiyun 		.capture = {
299*4882a593Smuzhiyun 			.stream_name = "Capture",
300*4882a593Smuzhiyun 			.channels_min = 2,
301*4882a593Smuzhiyun 			.channels_max = 2,
302*4882a593Smuzhiyun 			.rates = RK1000_CODEC_RATES,
303*4882a593Smuzhiyun 			.formats = RK1000_CODEC_FORMATS,
304*4882a593Smuzhiyun 		 },
305*4882a593Smuzhiyun 		.ops = &rk1000_codec_ops,
306*4882a593Smuzhiyun 		.symmetric_rates = 1,
307*4882a593Smuzhiyun 	}
308*4882a593Smuzhiyun };
309*4882a593Smuzhiyun 
rk1000_codec_reg_init(struct snd_soc_component * component)310*4882a593Smuzhiyun static void rk1000_codec_reg_init(struct snd_soc_component *component)
311*4882a593Smuzhiyun {
312*4882a593Smuzhiyun 	struct rk1000_codec_priv *rk1000_codec;
313*4882a593Smuzhiyun 	unsigned int digital_gain;
314*4882a593Smuzhiyun 	unsigned int mic_vol;
315*4882a593Smuzhiyun 	int ret;
316*4882a593Smuzhiyun 
317*4882a593Smuzhiyun 	mic_vol = VOLUME_INPUT;
318*4882a593Smuzhiyun 	rk1000_codec = snd_soc_component_get_drvdata(component);
319*4882a593Smuzhiyun 	ret = snd_soc_component_write(component, ACCELCODEC_R1D, 0x30);
320*4882a593Smuzhiyun 	snd_soc_component_write(component, ACCELCODEC_R1E, 0x40);
321*4882a593Smuzhiyun 	/*Route R-LPF->R-Mixer, L-LPF->L-Mixer*/
322*4882a593Smuzhiyun 	snd_soc_component_write(component, ACCELCODEC_R15, 0xC1);
323*4882a593Smuzhiyun 	/*With Cap Output, VMID ramp up slow*/
324*4882a593Smuzhiyun 	snd_soc_component_write(component, ACCELCODEC_R1A, 0x14);
325*4882a593Smuzhiyun 	mdelay(10);
326*4882a593Smuzhiyun 	snd_soc_component_write(component, ACCELCODEC_R0C, 0x10 | ASC_INPUT_VOL_0DB);
327*4882a593Smuzhiyun 	snd_soc_component_write(component, ACCELCODEC_R0D, 0x10 | ASC_INPUT_VOL_0DB);
328*4882a593Smuzhiyun 	if (mic_vol > 0x07) {
329*4882a593Smuzhiyun 		/*Select MIC input*/
330*4882a593Smuzhiyun 		snd_soc_component_write(component, ACCELCODEC_R12,
331*4882a593Smuzhiyun 					0x4c | ASC_MIC_INPUT | ASC_MIC_BOOST_20DB);
332*4882a593Smuzhiyun 		mic_vol -= 0x07;
333*4882a593Smuzhiyun 	} else {
334*4882a593Smuzhiyun 		/*Select MIC input*/
335*4882a593Smuzhiyun 		snd_soc_component_write(component, ACCELCODEC_R12, 0x4c | ASC_MIC_INPUT);
336*4882a593Smuzhiyun 	}
337*4882a593Smuzhiyun 	/*use default value*/
338*4882a593Smuzhiyun 	snd_soc_component_write(component, ACCELCODEC_R1C, ASC_DEM_ENABLE);
339*4882a593Smuzhiyun 	snd_soc_component_write(component, ACCELCODEC_R0E, 0x10 | mic_vol);
340*4882a593Smuzhiyun 	/* disable route PGA->R/L Mixer, PGA gain 0db. */
341*4882a593Smuzhiyun 	snd_soc_component_write(component, ACCELCODEC_R13, 0x05 | 0 << 3);
342*4882a593Smuzhiyun 	snd_soc_component_write(component, ACCELCODEC_R14, 0x05 | 0 << 3);
343*4882a593Smuzhiyun 	/*2soft mute*/
344*4882a593Smuzhiyun 	snd_soc_component_write(component, ACCELCODEC_R04,
345*4882a593Smuzhiyun 				ASC_INT_MUTE_L | ASC_INT_MUTE_R |
346*4882a593Smuzhiyun 				ASC_SIDETONE_L_OFF | ASC_SIDETONE_R_OFF);
347*4882a593Smuzhiyun 	/*2set default SR and clk*/
348*4882a593Smuzhiyun 	snd_soc_component_write(component, ACCELCODEC_R0A, FREQ441KHZ | ASC_NORMAL_MODE |
349*4882a593Smuzhiyun 				(0x10 << 1) | ASC_CLKNODIV | ASC_CLK_ENABLE);
350*4882a593Smuzhiyun 	/*2Config audio  interface*/
351*4882a593Smuzhiyun 	snd_soc_component_write(component, ACCELCODEC_R09, ASC_I2S_MODE |
352*4882a593Smuzhiyun 				ASC_16BIT_MODE | ASC_NORMAL_LRCLK |
353*4882a593Smuzhiyun 				ASC_LRSWAP_DISABLE | ASC_NORMAL_BCLK);
354*4882a593Smuzhiyun 	snd_soc_component_write(component, ACCELCODEC_R00, ASC_HPF_ENABLE |
355*4882a593Smuzhiyun 				ASC_DSM_MODE_ENABLE | ASC_SCRAMBLE_ENABLE |
356*4882a593Smuzhiyun 				ASC_DITHER_ENABLE | ASC_BCLKDIV_4);
357*4882a593Smuzhiyun 	/*2volume,input,output*/
358*4882a593Smuzhiyun 	digital_gain = VOLUME_OUTPUT;
359*4882a593Smuzhiyun 	if (snd_soc_component_read(component, ACCELCODEC_R05) != 0x0f) {
360*4882a593Smuzhiyun 		snd_soc_component_write(component, ACCELCODEC_R05,
361*4882a593Smuzhiyun 					(digital_gain >> 8) & 0xFF);
362*4882a593Smuzhiyun 		snd_soc_component_write(component, ACCELCODEC_R06, digital_gain & 0xFF);
363*4882a593Smuzhiyun 	}
364*4882a593Smuzhiyun 
365*4882a593Smuzhiyun 	if (snd_soc_component_read(component, ACCELCODEC_R07) != 0x0f) {
366*4882a593Smuzhiyun 		snd_soc_component_write(component, ACCELCODEC_R07,
367*4882a593Smuzhiyun 					(digital_gain >> 8) & 0xFF);
368*4882a593Smuzhiyun 		snd_soc_component_write(component, ACCELCODEC_R08, digital_gain & 0xFF);
369*4882a593Smuzhiyun 	}
370*4882a593Smuzhiyun 
371*4882a593Smuzhiyun 	snd_soc_component_write(component, ACCELCODEC_R0B,
372*4882a593Smuzhiyun 				ASC_DEC_ENABLE | ASC_INT_ENABLE);
373*4882a593Smuzhiyun 
374*4882a593Smuzhiyun 	#if OUT_CAPLESS
375*4882a593Smuzhiyun 	snd_soc_component_write(component, ACCELCODEC_R1F,
376*4882a593Smuzhiyun 				0x09 | ASC_PDMIXM_ENABLE);
377*4882a593Smuzhiyun 	#else
378*4882a593Smuzhiyun 	snd_soc_component_write(component, ACCELCODEC_R1F, 0x09 |
379*4882a593Smuzhiyun 				ASC_PDMIXM_ENABLE | ASC_PDPAM_ENABLE);
380*4882a593Smuzhiyun 	#endif
381*4882a593Smuzhiyun 
382*4882a593Smuzhiyun 	snd_soc_component_write(component, ACCELCODEC_R17, VOLUME_CODEC_PA |
383*4882a593Smuzhiyun 				ASC_OUTPUT_ACTIVE | ASC_CROSSZERO_EN);
384*4882a593Smuzhiyun 	snd_soc_component_write(component, ACCELCODEC_R18, VOLUME_CODEC_PA |
385*4882a593Smuzhiyun 				ASC_OUTPUT_ACTIVE | ASC_CROSSZERO_EN);
386*4882a593Smuzhiyun 	snd_soc_component_write(component, ACCELCODEC_R04, ASC_INT_ACTIVE_L |
387*4882a593Smuzhiyun 				ASC_INT_ACTIVE_R | ASC_SIDETONE_L_OFF |
388*4882a593Smuzhiyun 				ASC_SIDETONE_R_OFF);
389*4882a593Smuzhiyun 	snd_soc_component_write(component, ACCELCODEC_R19, 0x7F);
390*4882a593Smuzhiyun }
391*4882a593Smuzhiyun 
rk1000_codec_suspend(struct snd_soc_component * component)392*4882a593Smuzhiyun static int rk1000_codec_suspend(struct snd_soc_component *component)
393*4882a593Smuzhiyun {
394*4882a593Smuzhiyun 	spk_ctrl_fun(component, GPIO_LOW);
395*4882a593Smuzhiyun 	rk1000_codec_set_bias_level(component, SND_SOC_BIAS_OFF);
396*4882a593Smuzhiyun 
397*4882a593Smuzhiyun 	return 0;
398*4882a593Smuzhiyun }
399*4882a593Smuzhiyun 
rk1000_codec_resume(struct snd_soc_component * component)400*4882a593Smuzhiyun static int rk1000_codec_resume(struct snd_soc_component *component)
401*4882a593Smuzhiyun {
402*4882a593Smuzhiyun 	rk1000_codec_set_bias_level(component, SND_SOC_BIAS_PREPARE);
403*4882a593Smuzhiyun 	spk_ctrl_fun(component, GPIO_HIGH);
404*4882a593Smuzhiyun 
405*4882a593Smuzhiyun 	return 0;
406*4882a593Smuzhiyun }
407*4882a593Smuzhiyun 
rk1000_codec_probe(struct snd_soc_component * component)408*4882a593Smuzhiyun static int rk1000_codec_probe(struct snd_soc_component *component)
409*4882a593Smuzhiyun {
410*4882a593Smuzhiyun 	struct rk1000_codec_priv *rk1000_codec;
411*4882a593Smuzhiyun 
412*4882a593Smuzhiyun 	rk1000_codec = snd_soc_component_get_drvdata(component);
413*4882a593Smuzhiyun 	rk1000_codec->component = component;
414*4882a593Smuzhiyun 
415*4882a593Smuzhiyun 	INIT_DELAYED_WORK(&rk1000_codec->pa_delayed_work,
416*4882a593Smuzhiyun 			  pa_delayedwork);
417*4882a593Smuzhiyun 
418*4882a593Smuzhiyun 	rk1000_codec_set_bias_level(component, SND_SOC_BIAS_PREPARE);
419*4882a593Smuzhiyun 	schedule_delayed_work(&rk1000_codec->pa_delayed_work,
420*4882a593Smuzhiyun 			      msecs_to_jiffies(rk1000_codec->pa_enable_time));
421*4882a593Smuzhiyun 	rk1000_codec_reg_init(component);
422*4882a593Smuzhiyun 
423*4882a593Smuzhiyun 	return 0;
424*4882a593Smuzhiyun }
425*4882a593Smuzhiyun 
rk1000_codec_remove(struct snd_soc_component * component)426*4882a593Smuzhiyun static void rk1000_codec_remove(struct snd_soc_component *component)
427*4882a593Smuzhiyun {
428*4882a593Smuzhiyun 	rk1000_codec_set_bias_level(component, SND_SOC_BIAS_OFF);
429*4882a593Smuzhiyun }
430*4882a593Smuzhiyun 
431*4882a593Smuzhiyun static const struct snd_soc_component_driver soc_codec_dev_rk1000_codec = {
432*4882a593Smuzhiyun 	.probe = rk1000_codec_probe,
433*4882a593Smuzhiyun 	.remove = rk1000_codec_remove,
434*4882a593Smuzhiyun 	.suspend = rk1000_codec_suspend,
435*4882a593Smuzhiyun 	.resume = rk1000_codec_resume,
436*4882a593Smuzhiyun 	.set_bias_level = rk1000_codec_set_bias_level,
437*4882a593Smuzhiyun };
438*4882a593Smuzhiyun 
rk1000_reg_write(void * context,unsigned int reg,unsigned int value)439*4882a593Smuzhiyun static int rk1000_reg_write(void *context, unsigned int reg,
440*4882a593Smuzhiyun 			    unsigned int value)
441*4882a593Smuzhiyun {
442*4882a593Smuzhiyun 	struct i2c_client *i2c = context;
443*4882a593Smuzhiyun 	struct i2c_msg msg;
444*4882a593Smuzhiyun 	u8 buf;
445*4882a593Smuzhiyun 	int ret;
446*4882a593Smuzhiyun 
447*4882a593Smuzhiyun 	buf = value;
448*4882a593Smuzhiyun 	msg.addr = i2c->addr | reg;
449*4882a593Smuzhiyun 	msg.flags = i2c->flags & I2C_M_TEN;
450*4882a593Smuzhiyun 	msg.len = 1;
451*4882a593Smuzhiyun 	msg.buf = &buf;
452*4882a593Smuzhiyun 
453*4882a593Smuzhiyun 	ret = i2c_transfer(i2c->adapter, &msg, 1);
454*4882a593Smuzhiyun 
455*4882a593Smuzhiyun 	return (ret == 1) ? 0 : ret;
456*4882a593Smuzhiyun }
457*4882a593Smuzhiyun 
rk1000_reg_read(void * context,unsigned int reg,unsigned int * value)458*4882a593Smuzhiyun static int rk1000_reg_read(void *context, unsigned int reg,
459*4882a593Smuzhiyun 			   unsigned int *value)
460*4882a593Smuzhiyun {
461*4882a593Smuzhiyun 	struct i2c_client *i2c = context;
462*4882a593Smuzhiyun 	struct i2c_msg msg;
463*4882a593Smuzhiyun 	u8 buf;
464*4882a593Smuzhiyun 	int ret;
465*4882a593Smuzhiyun 
466*4882a593Smuzhiyun 	msg.addr = i2c->addr | reg;
467*4882a593Smuzhiyun 	msg.flags = I2C_M_RD;
468*4882a593Smuzhiyun 	msg.len = 1;
469*4882a593Smuzhiyun 	msg.buf = &buf;
470*4882a593Smuzhiyun 
471*4882a593Smuzhiyun 	ret = i2c_transfer(i2c->adapter, &msg, 1);
472*4882a593Smuzhiyun 	if (ret != 1)
473*4882a593Smuzhiyun 		return ret;
474*4882a593Smuzhiyun 
475*4882a593Smuzhiyun 	*value = buf;
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun 	return 0;
478*4882a593Smuzhiyun }
479*4882a593Smuzhiyun 
480*4882a593Smuzhiyun static const struct regmap_config rk1000_codec_regmap = {
481*4882a593Smuzhiyun 	.reg_bits = 8,
482*4882a593Smuzhiyun 	.val_bits = 8,
483*4882a593Smuzhiyun 	.reg_write = rk1000_reg_write,
484*4882a593Smuzhiyun 	.reg_read = rk1000_reg_read,
485*4882a593Smuzhiyun 	.max_register = ACCELCODEC_R1F,
486*4882a593Smuzhiyun 	.cache_type = REGCACHE_FLAT,
487*4882a593Smuzhiyun 	.reg_defaults = rk1000_codec_reg,
488*4882a593Smuzhiyun 	.num_reg_defaults = ARRAY_SIZE(rk1000_codec_reg),
489*4882a593Smuzhiyun };
490*4882a593Smuzhiyun 
491*4882a593Smuzhiyun static const struct regmap_config rk1000_ctl_regmap = {
492*4882a593Smuzhiyun 	.reg_bits = 8,
493*4882a593Smuzhiyun 	.val_bits = 8,
494*4882a593Smuzhiyun 	.max_register = CODEC_CON,
495*4882a593Smuzhiyun 	.cache_type = REGCACHE_FLAT,
496*4882a593Smuzhiyun };
497*4882a593Smuzhiyun 
rk1000_codec_i2c_probe(struct i2c_client * i2c,const struct i2c_device_id * id)498*4882a593Smuzhiyun static int rk1000_codec_i2c_probe(struct i2c_client *i2c,
499*4882a593Smuzhiyun 				  const struct i2c_device_id *id)
500*4882a593Smuzhiyun {
501*4882a593Smuzhiyun 	struct rk1000_codec_priv *rk1000;
502*4882a593Smuzhiyun 	struct device_node *np = i2c->dev.of_node;
503*4882a593Smuzhiyun 	struct device_node *ctl;
504*4882a593Smuzhiyun 	struct i2c_client *ctl_client;
505*4882a593Smuzhiyun 
506*4882a593Smuzhiyun 	rk1000 = devm_kzalloc(&i2c->dev, sizeof(*rk1000), GFP_KERNEL);
507*4882a593Smuzhiyun 	if (!rk1000)
508*4882a593Smuzhiyun 		return -ENOMEM;
509*4882a593Smuzhiyun 
510*4882a593Smuzhiyun 	i2c_set_clientdata(i2c, rk1000);
511*4882a593Smuzhiyun 
512*4882a593Smuzhiyun 	of_property_read_u32(np, "rockchip,pa-en-time-ms",
513*4882a593Smuzhiyun 			     &rk1000->pa_enable_time);
514*4882a593Smuzhiyun 
515*4882a593Smuzhiyun 	rk1000->spk_en_gpio = devm_gpiod_get_optional(&i2c->dev, "rockchip,spk-en",
516*4882a593Smuzhiyun 						      GPIOD_OUT_LOW);
517*4882a593Smuzhiyun 	if (IS_ERR(rk1000->spk_en_gpio))
518*4882a593Smuzhiyun 		return PTR_ERR(rk1000->spk_en_gpio);
519*4882a593Smuzhiyun 
520*4882a593Smuzhiyun 	ctl = of_parse_phandle(np, "rockchip,ctl", 0);
521*4882a593Smuzhiyun 	if (!ctl)
522*4882a593Smuzhiyun 		return -EINVAL;
523*4882a593Smuzhiyun 
524*4882a593Smuzhiyun 	ctl_client = of_find_i2c_device_by_node(ctl);
525*4882a593Smuzhiyun 	if (!ctl_client) {
526*4882a593Smuzhiyun 		dev_err(&i2c->dev, "can't find control client\n");
527*4882a593Smuzhiyun 		return -EPROBE_DEFER;
528*4882a593Smuzhiyun 	}
529*4882a593Smuzhiyun 
530*4882a593Smuzhiyun 	rk1000->regmap = devm_regmap_init(&i2c->dev, NULL,
531*4882a593Smuzhiyun 					  i2c, &rk1000_codec_regmap);
532*4882a593Smuzhiyun 	if (IS_ERR(rk1000->regmap))
533*4882a593Smuzhiyun 		return PTR_ERR(rk1000->regmap);
534*4882a593Smuzhiyun 
535*4882a593Smuzhiyun 	rk1000->ctlmap = devm_regmap_init_i2c(ctl_client,
536*4882a593Smuzhiyun 					      &rk1000_ctl_regmap);
537*4882a593Smuzhiyun 	if (IS_ERR(rk1000->ctlmap))
538*4882a593Smuzhiyun 		return PTR_ERR(rk1000->ctlmap);
539*4882a593Smuzhiyun 
540*4882a593Smuzhiyun 	regmap_write(rk1000->ctlmap, CODEC_CON, CODEC_ON);
541*4882a593Smuzhiyun 
542*4882a593Smuzhiyun 	return devm_snd_soc_register_component(&i2c->dev, &soc_codec_dev_rk1000_codec,
543*4882a593Smuzhiyun 					       rk1000_codec_dai,
544*4882a593Smuzhiyun 					       ARRAY_SIZE(rk1000_codec_dai));
545*4882a593Smuzhiyun }
546*4882a593Smuzhiyun 
rk1000_codec_i2c_remove(struct i2c_client * i2c)547*4882a593Smuzhiyun static int rk1000_codec_i2c_remove(struct i2c_client *i2c)
548*4882a593Smuzhiyun {
549*4882a593Smuzhiyun 	struct rk1000_codec_priv *rk1000 = i2c_get_clientdata(i2c);
550*4882a593Smuzhiyun 
551*4882a593Smuzhiyun 	regmap_write(rk1000->ctlmap, CODEC_CON, CODEC_OFF);
552*4882a593Smuzhiyun 
553*4882a593Smuzhiyun 	return 0;
554*4882a593Smuzhiyun }
555*4882a593Smuzhiyun 
556*4882a593Smuzhiyun static const struct i2c_device_id rk1000_codec_i2c_id[] = {
557*4882a593Smuzhiyun 	{ "rk1000_codec", 0 },
558*4882a593Smuzhiyun 	{ }
559*4882a593Smuzhiyun };
560*4882a593Smuzhiyun MODULE_DEVICE_TABLE(i2c, rk1000_codec_i2c_id);
561*4882a593Smuzhiyun 
562*4882a593Smuzhiyun static const struct of_device_id rk1000_codec_of_match[] = {
563*4882a593Smuzhiyun 	{ .compatible = "rockchip,rk1000-codec", },
564*4882a593Smuzhiyun 	{},
565*4882a593Smuzhiyun };
566*4882a593Smuzhiyun 
567*4882a593Smuzhiyun static struct i2c_driver rk1000_codec_i2c_driver = {
568*4882a593Smuzhiyun 	.driver = {
569*4882a593Smuzhiyun 		.name = "rk1000_codec",
570*4882a593Smuzhiyun 		.of_match_table = of_match_ptr(rk1000_codec_of_match),
571*4882a593Smuzhiyun 	},
572*4882a593Smuzhiyun 	.probe = rk1000_codec_i2c_probe,
573*4882a593Smuzhiyun 	.remove   = rk1000_codec_i2c_remove,
574*4882a593Smuzhiyun 	.id_table = rk1000_codec_i2c_id,
575*4882a593Smuzhiyun };
576*4882a593Smuzhiyun module_i2c_driver(rk1000_codec_i2c_driver);
577*4882a593Smuzhiyun 
578*4882a593Smuzhiyun MODULE_DESCRIPTION("Rockchip RK1000 CODEC driver");
579*4882a593Smuzhiyun MODULE_AUTHOR("Sugar Zhang <sugar.zhang@rock-chips.com>");
580*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
581