xref: /OK3568_Linux_fs/u-boot/drivers/sound/rk817_codec.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 // SPDX-License-Identifier:     GPL-2.0+
2 /*
3  * (C) Copyright 2018 Rockchip Electronics Co., Ltd
4  */
5 
6 #include <common.h>
7 #include <dm.h>
8 #include <power/pmic.h>
9 #include <power/rk8xx_pmic.h>
10 #include <sound.h>
11 #include "rk817_codec.h"
12 
13 #define DBG(format, ...) \
14 		printf("RK817: " format, ## __VA_ARGS__)
15 
16 /* For route */
17 #define RK817_CODEC_PLAYBACK	1
18 #define RK817_CODEC_CAPTURE	2
19 #define RK817_CODEC_INCALL	4
20 #define RK817_CODEC_ALL	(RK817_CODEC_PLAYBACK |\
21 	RK817_CODEC_CAPTURE | RK817_CODEC_INCALL)
22 
23 /*
24  * DDAC L/R volume setting
25  * 0db~-95db,0.375db/step,for example:
26  * 0: 0dB
27  * 0x0a: -3.75dB
28  * 0x7d: -46dB
29  * 0xff: -95dB
30  */
31 #define OUT_VOLUME	(0x03)
32 
33 #define CODEC_SET_SPK 1
34 #define CODEC_SET_HP 2
35 #define INITIAL_VOLUME	3
36 
37 struct rk817_codec_priv {
38 	struct udevice *dev;
39 	struct rk8xx_priv *rk817;
40 	unsigned int stereo_sysclk;
41 	unsigned int rate;
42 	unsigned int spk_volume;
43 	unsigned int hp_volume;
44 	bool use_ext_amplifier;
45 	long int playback_path;
46 	int spk_mute_delay;
47 	int hp_mute_delay;
48 };
49 
snd_soc_write(struct udevice * dev,unsigned int reg,unsigned int val)50 static int snd_soc_write(struct udevice *dev, unsigned int reg,
51 			 unsigned int val)
52 {
53 	return pmic_reg_write(dev, reg, val);
54 }
55 
snd_soc_update_bits(struct udevice * dev,unsigned int reg,unsigned int mask,unsigned int value)56 static int snd_soc_update_bits(struct udevice *dev, unsigned int reg,
57 			       unsigned int mask, unsigned int value)
58 {
59 	return pmic_clrsetbits(dev, reg, mask, value);
60 }
61 
rk817_reset(struct rk817_codec_priv * priv)62 static int rk817_reset(struct rk817_codec_priv *priv)
63 {
64 	struct udevice *codec = priv->dev->parent;
65 
66 	snd_soc_write(codec, RK817_CODEC_DTOP_LPT_SRST, 0x40);
67 	snd_soc_write(codec, RK817_CODEC_DDAC_POPD_DACST, 0x02);
68 
69 	return 0;
70 }
71 
72 static struct rk817_reg_val_typ playback_power_up_list[] = {
73 	{RK817_CODEC_AREF_RTCFG1, 0x40},
74 	{RK817_CODEC_DDAC_POPD_DACST, 0x02},
75 	{RK817_CODEC_DDAC_SR_LMT0, 0x02},
76 	/* {RK817_CODEC_DTOP_DIGEN_CLKE, 0x0f}, */
77 	/* APLL */
78 	{RK817_CODEC_APLL_CFG0, 0x04},
79 	{RK817_CODEC_APLL_CFG1, 0x58},
80 	{RK817_CODEC_APLL_CFG2, 0x2d},
81 	{RK817_CODEC_APLL_CFG3, 0x0c},
82 	{RK817_CODEC_APLL_CFG4, 0xa5},
83 	{RK817_CODEC_APLL_CFG5, 0x00},
84 
85 	{RK817_CODEC_DI2S_RXCMD_TSD, 0x00},
86 	{RK817_CODEC_DI2S_RSD, 0x00},
87 	/* {RK817_CODEC_DI2S_CKM, 0x00}, */
88 	{RK817_CODEC_DI2S_RXCR1, 0x00},
89 	{RK817_CODEC_DI2S_RXCMD_TSD, 0x20},
90 	{RK817_CODEC_DTOP_VUCTIME, 0xf4},
91 	{RK817_CODEC_DDAC_MUTE_MIXCTL, 0x00},
92 
93 	{RK817_CODEC_DDAC_VOLL, 0x0a},
94 	{RK817_CODEC_DDAC_VOLR, 0x0a},
95 };
96 
97 #define RK817_CODEC_PLAYBACK_POWER_UP_LIST_LEN \
98 	ARRAY_SIZE(playback_power_up_list)
99 
100 static struct rk817_reg_val_typ playback_power_down_list[] = {
101 	{RK817_CODEC_DDAC_MUTE_MIXCTL, 0x01},
102 	{RK817_CODEC_ADAC_CFG1, 0x0f},
103 	/* HP */
104 	{RK817_CODEC_AHP_CFG0, 0xe0},
105 	{RK817_CODEC_AHP_CP, 0x09},
106 	/* SPK */
107 	{RK817_CODEC_ACLASSD_CFG1, 0x69},
108 };
109 
110 #define RK817_CODEC_PLAYBACK_POWER_DOWN_LIST_LEN \
111 	ARRAY_SIZE(playback_power_down_list)
112 
rk817_codec_power_up(struct rk817_codec_priv * rk817,int type)113 static int rk817_codec_power_up(struct rk817_codec_priv *rk817, int type)
114 {
115 	struct udevice *codec = rk817->dev->parent;
116 	int i;
117 
118 	DBG("%s : power up %s %s %s\n", __func__,
119 	    type & RK817_CODEC_PLAYBACK ? "playback" : "",
120 	    type & RK817_CODEC_CAPTURE ? "capture" : "",
121 	    type & RK817_CODEC_INCALL ? "incall" : "");
122 
123 	if (type & RK817_CODEC_PLAYBACK) {
124 		snd_soc_update_bits(codec, RK817_CODEC_DTOP_DIGEN_CLKE,
125 				    DAC_DIG_CLK_MASK, DAC_DIG_CLK_EN);
126 		for (i = 0; i < RK817_CODEC_PLAYBACK_POWER_UP_LIST_LEN; i++) {
127 			snd_soc_write(codec, playback_power_up_list[i].reg,
128 				      playback_power_up_list[i].value);
129 		}
130 	}
131 
132 	return 0;
133 }
134 
rk817_codec_power_down(struct rk817_codec_priv * rk817,int type)135 static int rk817_codec_power_down(struct rk817_codec_priv *rk817, int type)
136 {
137 	struct udevice *codec = rk817->dev->parent;
138 	int i;
139 
140 	DBG("%s : power down %s %s %s\n", __func__,
141 	    type & RK817_CODEC_PLAYBACK ? "playback" : "",
142 	    type & RK817_CODEC_CAPTURE ? "capture" : "",
143 	    type & RK817_CODEC_INCALL ? "incall" : "");
144 
145 	/* mute output for pop noise */
146 	if ((type & RK817_CODEC_PLAYBACK) ||
147 	    (type & RK817_CODEC_INCALL)) {
148 		snd_soc_update_bits(codec, RK817_CODEC_DDAC_MUTE_MIXCTL,
149 				    DACMT_ENABLE, DACMT_ENABLE);
150 	}
151 
152 	if (type & RK817_CODEC_PLAYBACK) {
153 		for (i = 0; i < RK817_CODEC_PLAYBACK_POWER_DOWN_LIST_LEN; i++) {
154 			snd_soc_write(codec, playback_power_down_list[i].reg,
155 				      playback_power_down_list[i].value);
156 		}
157 		snd_soc_update_bits(codec, RK817_CODEC_DTOP_DIGEN_CLKE,
158 				    DAC_DIG_CLK_MASK, DAC_DIG_CLK_DIS);
159 	}
160 
161 	if (type == RK817_CODEC_ALL) {
162 		for (i = 0; i < RK817_CODEC_PLAYBACK_POWER_DOWN_LIST_LEN; i++) {
163 			snd_soc_write(codec, playback_power_down_list[i].reg,
164 				      playback_power_down_list[i].value);
165 		}
166 		snd_soc_write(codec, RK817_CODEC_DTOP_DIGEN_CLKE, 0x00);
167 		snd_soc_write(codec, RK817_CODEC_APLL_CFG5, 0x01);
168 		snd_soc_write(codec, RK817_CODEC_AREF_RTCFG1, 0x06);
169 	}
170 
171 	return 0;
172 }
173 
rk817_playback_path_put(struct rk817_codec_priv * rk817,int path)174 static int rk817_playback_path_put(struct rk817_codec_priv *rk817, int path)
175 {
176 	struct udevice *codec = rk817->dev->parent;
177 	long int pre_path;
178 
179 	if (rk817->playback_path == path) {
180 		DBG("%s : playback_path is not changed!\n", __func__);
181 		return 0;
182 	}
183 
184 	pre_path = rk817->playback_path;
185 	rk817->playback_path = path;
186 
187 	DBG("%s : set playback_path %ld, pre_path %ld\n",
188 	    __func__, rk817->playback_path, pre_path);
189 
190 	switch (rk817->playback_path) {
191 	case OFF:
192 		rk817_codec_power_down(rk817, RK817_CODEC_PLAYBACK);
193 		break;
194 	case RCV:
195 	case SPK_PATH:
196 	case RING_SPK:
197 		if (pre_path == OFF)
198 			rk817_codec_power_up(rk817, RK817_CODEC_PLAYBACK);
199 		if (!rk817->use_ext_amplifier) {
200 			/* power on dac ibias/l/r */
201 			snd_soc_write(codec, RK817_CODEC_ADAC_CFG1,
202 				      PWD_DACBIAS_ON | PWD_DACD_ON |
203 				      PWD_DACL_ON | PWD_DACR_ON);
204 			/* CLASS D mode */
205 			snd_soc_write(codec, RK817_CODEC_DDAC_MUTE_MIXCTL, 0x10);
206 			/* CLASS D enable */
207 			snd_soc_write(codec, RK817_CODEC_ACLASSD_CFG1, 0xa5);
208 			/* restart CLASS D, OCPP/N */
209 			snd_soc_write(codec, RK817_CODEC_ACLASSD_CFG2, 0xc4);
210 		} else {
211 			/* HP_CP_EN , CP 2.3V */
212 			snd_soc_write(codec, RK817_CODEC_AHP_CP, 0x11);
213 			/* power on HP two stage opamp ,HP amplitude 0db */
214 			snd_soc_write(codec, RK817_CODEC_AHP_CFG0, 0x80);
215 			/* power on dac ibias/l/r */
216 			snd_soc_write(codec, RK817_CODEC_ADAC_CFG1,
217 				      PWD_DACBIAS_ON | PWD_DACD_DOWN |
218 				      PWD_DACL_ON | PWD_DACR_ON);
219 			snd_soc_update_bits(codec, RK817_CODEC_DDAC_MUTE_MIXCTL,
220 					    DACMT_ENABLE, DACMT_DISABLE);
221 		}
222 		snd_soc_write(codec, RK817_CODEC_DDAC_VOLL, rk817->spk_volume);
223 		snd_soc_write(codec, RK817_CODEC_DDAC_VOLR, rk817->spk_volume);
224 		break;
225 	case HP_PATH:
226 	case HP_NO_MIC:
227 	case RING_HP:
228 	case RING_HP_NO_MIC:
229 		if (pre_path == OFF)
230 			rk817_codec_power_up(rk817, RK817_CODEC_PLAYBACK);
231 		/* HP_CP_EN , CP 2.3V */
232 		snd_soc_write(codec, RK817_CODEC_AHP_CP, 0x11);
233 		/* power on HP two stage opamp ,HP amplitude 0db */
234 		snd_soc_write(codec, RK817_CODEC_AHP_CFG0, 0x80);
235 		/* power on dac ibias/l/r */
236 		snd_soc_write(codec, RK817_CODEC_ADAC_CFG1,
237 			      PWD_DACBIAS_ON | PWD_DACD_DOWN |
238 			      PWD_DACL_ON | PWD_DACR_ON);
239 		snd_soc_update_bits(codec, RK817_CODEC_DDAC_MUTE_MIXCTL,
240 				    DACMT_ENABLE, DACMT_DISABLE);
241 
242 		snd_soc_write(codec, RK817_CODEC_DDAC_VOLL, rk817->hp_volume);
243 		snd_soc_write(codec, RK817_CODEC_DDAC_VOLR, rk817->hp_volume);
244 		break;
245 	case BT:
246 		break;
247 	case SPK_HP:
248 	case RING_SPK_HP:
249 		if (pre_path == OFF)
250 			rk817_codec_power_up(rk817, RK817_CODEC_PLAYBACK);
251 
252 		/* HP_CP_EN , CP 2.3V  */
253 		snd_soc_write(codec, RK817_CODEC_AHP_CP, 0x11);
254 		/* power on HP two stage opamp ,HP amplitude 0db */
255 		snd_soc_write(codec, RK817_CODEC_AHP_CFG0, 0x80);
256 
257 		/* power on dac ibias/l/r */
258 		snd_soc_write(codec, RK817_CODEC_ADAC_CFG1,
259 			      PWD_DACBIAS_ON | PWD_DACD_ON |
260 			      PWD_DACL_ON | PWD_DACR_ON);
261 
262 		if (!rk817->use_ext_amplifier) {
263 			/* CLASS D mode */
264 			snd_soc_write(codec, RK817_CODEC_DDAC_MUTE_MIXCTL, 0x10);
265 			/* CLASS D enable */
266 			snd_soc_write(codec, RK817_CODEC_ACLASSD_CFG1, 0xa5);
267 			/* restart CLASS D, OCPP/N */
268 			snd_soc_write(codec, RK817_CODEC_ACLASSD_CFG2, 0xc4);
269 		}
270 
271 		snd_soc_write(codec, RK817_CODEC_DDAC_VOLL, rk817->hp_volume);
272 		snd_soc_write(codec, RK817_CODEC_DDAC_VOLR, rk817->hp_volume);
273 		break;
274 	default:
275 		return -EINVAL;
276 	}
277 
278 	return 0;
279 }
280 
rk817_hw_params(struct udevice * dev,unsigned int samplerate,unsigned int fmt,unsigned int channels)281 static int rk817_hw_params(struct udevice *dev, unsigned int samplerate,
282 			   unsigned int fmt, unsigned int channels)
283 {
284 	struct rk817_codec_priv *rk817 = dev_get_priv(dev);
285 	struct udevice *codec = rk817->dev->parent;
286 
287 	snd_soc_update_bits(codec, RK817_CODEC_DI2S_CKM,
288 			    RK817_I2S_MODE_MASK, RK817_I2S_MODE_SLV);
289 	snd_soc_write(codec, RK817_CODEC_DI2S_RXCR2, VDW_RX_16BITS);
290 	snd_soc_write(codec, RK817_CODEC_DI2S_TXCR2, VDW_TX_16BITS);
291 
292 	return 0;
293 }
294 
rk817_digital_mute(struct rk817_codec_priv * rk817,int mute)295 static int rk817_digital_mute(struct rk817_codec_priv *rk817, int mute)
296 {
297 	struct udevice *codec = rk817->dev->parent;
298 
299 	if (mute)
300 		snd_soc_update_bits(codec, RK817_CODEC_DDAC_MUTE_MIXCTL,
301 				    DACMT_ENABLE, DACMT_ENABLE);
302 	else
303 		snd_soc_update_bits(codec, RK817_CODEC_DDAC_MUTE_MIXCTL,
304 				    DACMT_ENABLE, DACMT_DISABLE);
305 
306 	return 0;
307 }
308 
rk817_startup(struct udevice * dev)309 static int rk817_startup(struct udevice *dev)
310 {
311 	struct rk817_codec_priv *rk817 = dev_get_priv(dev);
312 
313 	rk817_playback_path_put(rk817, SPK_HP);
314 	rk817_digital_mute(rk817, 0);
315 
316 	return 0;
317 }
318 
319 static const struct snd_soc_dai_ops rk817_codec_ops = {
320 	.hw_params = rk817_hw_params,
321 	.startup = rk817_startup,
322 };
323 
rk817_codec_probe(struct udevice * dev)324 static int rk817_codec_probe(struct udevice *dev)
325 {
326 	struct rk8xx_priv *rk817 = dev_get_priv(dev->parent);
327 	struct rk817_codec_priv *rk817_codec = dev_get_priv(dev);
328 
329 	if (!rk817) {
330 		printf("%s : rk817 is null\n", __func__);
331 		return -EINVAL;
332 	}
333 
334 	switch (rk817->variant) {
335 	case RK809_ID:
336 	case RK817_ID:
337 		break;
338 	default:
339 		return -EINVAL;
340 	}
341 
342 	rk817_codec->dev = dev;
343 	rk817_codec->hp_volume = INITIAL_VOLUME;
344 	rk817_codec->spk_volume = INITIAL_VOLUME;
345 	rk817_codec->playback_path = OFF;
346 	rk817_reset(rk817_codec);
347 
348 	return 0;
349 }
350 
351 static const struct udevice_id rk817_codec_ids[] = {
352 	{ .compatible = "rockchip,rk817-codec" },
353 	{ }
354 };
355 
356 U_BOOT_DRIVER(rk817) = {
357 	.name = "rk817_codec",
358 	.id = UCLASS_CODEC,
359 	.of_match = rk817_codec_ids,
360 	.probe = rk817_codec_probe,
361 	.priv_auto_alloc_size = sizeof(struct rk817_codec_priv),
362 	.ops = &rk817_codec_ops,
363 };
364 
365 UCLASS_DRIVER(codec) = {
366 	.id = UCLASS_CODEC,
367 	.name = "codec",
368 };
369