xref: /linux/sound/soc/codecs/rk3328_codec.c (revision c32759035ad246d3e4c65d23a07f9e6ba32caeaf)
1*c3275903SKatsuhiro Suzuki // SPDX-License-Identifier: GPL-2.0
2*c3275903SKatsuhiro Suzuki //
3*c3275903SKatsuhiro Suzuki // rk3328 ALSA SoC Audio driver
4*c3275903SKatsuhiro Suzuki //
5*c3275903SKatsuhiro Suzuki // Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd All rights reserved.
6*c3275903SKatsuhiro Suzuki 
7*c3275903SKatsuhiro Suzuki #include <linux/clk.h>
8*c3275903SKatsuhiro Suzuki #include <linux/delay.h>
9*c3275903SKatsuhiro Suzuki #include <linux/device.h>
10*c3275903SKatsuhiro Suzuki #include <linux/module.h>
11*c3275903SKatsuhiro Suzuki #include <linux/of.h>
12*c3275903SKatsuhiro Suzuki #include <linux/platform_device.h>
13*c3275903SKatsuhiro Suzuki #include <linux/pm_runtime.h>
14*c3275903SKatsuhiro Suzuki #include <linux/regmap.h>
15*c3275903SKatsuhiro Suzuki #include <linux/mfd/syscon.h>
16*c3275903SKatsuhiro Suzuki #include <sound/dmaengine_pcm.h>
17*c3275903SKatsuhiro Suzuki #include <sound/pcm_params.h>
18*c3275903SKatsuhiro Suzuki #include "rk3328_codec.h"
19*c3275903SKatsuhiro Suzuki 
20*c3275903SKatsuhiro Suzuki /*
21*c3275903SKatsuhiro Suzuki  * volume setting
22*c3275903SKatsuhiro Suzuki  * 0: -39dB
23*c3275903SKatsuhiro Suzuki  * 26: 0dB
24*c3275903SKatsuhiro Suzuki  * 31: 6dB
25*c3275903SKatsuhiro Suzuki  * Step: 1.5dB
26*c3275903SKatsuhiro Suzuki  */
27*c3275903SKatsuhiro Suzuki #define OUT_VOLUME	(0x18)
28*c3275903SKatsuhiro Suzuki #define RK3328_GRF_SOC_CON2	(0x0408)
29*c3275903SKatsuhiro Suzuki #define RK3328_GRF_SOC_CON10	(0x0428)
30*c3275903SKatsuhiro Suzuki #define INITIAL_FREQ	(11289600)
31*c3275903SKatsuhiro Suzuki 
32*c3275903SKatsuhiro Suzuki struct rk3328_codec_priv {
33*c3275903SKatsuhiro Suzuki 	struct regmap *regmap;
34*c3275903SKatsuhiro Suzuki 	struct regmap *grf;
35*c3275903SKatsuhiro Suzuki 	struct clk *mclk;
36*c3275903SKatsuhiro Suzuki 	struct clk *pclk;
37*c3275903SKatsuhiro Suzuki 	unsigned int sclk;
38*c3275903SKatsuhiro Suzuki 	int spk_depop_time; /* msec */
39*c3275903SKatsuhiro Suzuki };
40*c3275903SKatsuhiro Suzuki 
41*c3275903SKatsuhiro Suzuki static const struct reg_default rk3328_codec_reg_defaults[] = {
42*c3275903SKatsuhiro Suzuki 	{ CODEC_RESET, 0x03 },
43*c3275903SKatsuhiro Suzuki 	{ DAC_INIT_CTRL1, 0x00 },
44*c3275903SKatsuhiro Suzuki 	{ DAC_INIT_CTRL2, 0x50 },
45*c3275903SKatsuhiro Suzuki 	{ DAC_INIT_CTRL3, 0x0e },
46*c3275903SKatsuhiro Suzuki 	{ DAC_PRECHARGE_CTRL, 0x01 },
47*c3275903SKatsuhiro Suzuki 	{ DAC_PWR_CTRL, 0x00 },
48*c3275903SKatsuhiro Suzuki 	{ DAC_CLK_CTRL, 0x00 },
49*c3275903SKatsuhiro Suzuki 	{ HPMIX_CTRL, 0x00 },
50*c3275903SKatsuhiro Suzuki 	{ HPOUT_CTRL, 0x00 },
51*c3275903SKatsuhiro Suzuki 	{ HPOUTL_GAIN_CTRL, 0x00 },
52*c3275903SKatsuhiro Suzuki 	{ HPOUTR_GAIN_CTRL, 0x00 },
53*c3275903SKatsuhiro Suzuki 	{ HPOUT_POP_CTRL, 0x11 },
54*c3275903SKatsuhiro Suzuki };
55*c3275903SKatsuhiro Suzuki 
56*c3275903SKatsuhiro Suzuki static int rk3328_codec_reset(struct rk3328_codec_priv *rk3328)
57*c3275903SKatsuhiro Suzuki {
58*c3275903SKatsuhiro Suzuki 	regmap_write(rk3328->regmap, CODEC_RESET, 0x00);
59*c3275903SKatsuhiro Suzuki 	mdelay(10);
60*c3275903SKatsuhiro Suzuki 	regmap_write(rk3328->regmap, CODEC_RESET, 0x03);
61*c3275903SKatsuhiro Suzuki 
62*c3275903SKatsuhiro Suzuki 	return 0;
63*c3275903SKatsuhiro Suzuki }
64*c3275903SKatsuhiro Suzuki 
65*c3275903SKatsuhiro Suzuki static int rk3328_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
66*c3275903SKatsuhiro Suzuki {
67*c3275903SKatsuhiro Suzuki 	struct rk3328_codec_priv *rk3328 =
68*c3275903SKatsuhiro Suzuki 		snd_soc_component_get_drvdata(dai->component);
69*c3275903SKatsuhiro Suzuki 	unsigned int val;
70*c3275903SKatsuhiro Suzuki 
71*c3275903SKatsuhiro Suzuki 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
72*c3275903SKatsuhiro Suzuki 	case SND_SOC_DAIFMT_CBS_CFS:
73*c3275903SKatsuhiro Suzuki 		val = PIN_DIRECTION_IN | DAC_I2S_MODE_SLAVE;
74*c3275903SKatsuhiro Suzuki 		break;
75*c3275903SKatsuhiro Suzuki 	case SND_SOC_DAIFMT_CBM_CFM:
76*c3275903SKatsuhiro Suzuki 		val = PIN_DIRECTION_OUT | DAC_I2S_MODE_MASTER;
77*c3275903SKatsuhiro Suzuki 		break;
78*c3275903SKatsuhiro Suzuki 	default:
79*c3275903SKatsuhiro Suzuki 		return -EINVAL;
80*c3275903SKatsuhiro Suzuki 	}
81*c3275903SKatsuhiro Suzuki 
82*c3275903SKatsuhiro Suzuki 	regmap_update_bits(rk3328->regmap, DAC_INIT_CTRL1,
83*c3275903SKatsuhiro Suzuki 			   PIN_DIRECTION_MASK | DAC_I2S_MODE_MASK, val);
84*c3275903SKatsuhiro Suzuki 
85*c3275903SKatsuhiro Suzuki 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
86*c3275903SKatsuhiro Suzuki 	case SND_SOC_DAIFMT_DSP_A:
87*c3275903SKatsuhiro Suzuki 	case SND_SOC_DAIFMT_DSP_B:
88*c3275903SKatsuhiro Suzuki 		val = DAC_MODE_PCM;
89*c3275903SKatsuhiro Suzuki 		break;
90*c3275903SKatsuhiro Suzuki 	case SND_SOC_DAIFMT_I2S:
91*c3275903SKatsuhiro Suzuki 		val = DAC_MODE_I2S;
92*c3275903SKatsuhiro Suzuki 		break;
93*c3275903SKatsuhiro Suzuki 	case SND_SOC_DAIFMT_RIGHT_J:
94*c3275903SKatsuhiro Suzuki 		val = DAC_MODE_RJM;
95*c3275903SKatsuhiro Suzuki 		break;
96*c3275903SKatsuhiro Suzuki 	case SND_SOC_DAIFMT_LEFT_J:
97*c3275903SKatsuhiro Suzuki 		val = DAC_MODE_LJM;
98*c3275903SKatsuhiro Suzuki 		break;
99*c3275903SKatsuhiro Suzuki 	default:
100*c3275903SKatsuhiro Suzuki 		return -EINVAL;
101*c3275903SKatsuhiro Suzuki 	}
102*c3275903SKatsuhiro Suzuki 
103*c3275903SKatsuhiro Suzuki 	regmap_update_bits(rk3328->regmap, DAC_INIT_CTRL2,
104*c3275903SKatsuhiro Suzuki 			   DAC_MODE_MASK, val);
105*c3275903SKatsuhiro Suzuki 
106*c3275903SKatsuhiro Suzuki 	return 0;
107*c3275903SKatsuhiro Suzuki }
108*c3275903SKatsuhiro Suzuki 
109*c3275903SKatsuhiro Suzuki static void rk3328_analog_output(struct rk3328_codec_priv *rk3328, int mute)
110*c3275903SKatsuhiro Suzuki {
111*c3275903SKatsuhiro Suzuki 	unsigned int val = BIT(17);
112*c3275903SKatsuhiro Suzuki 
113*c3275903SKatsuhiro Suzuki 	if (mute)
114*c3275903SKatsuhiro Suzuki 		val |= BIT(1);
115*c3275903SKatsuhiro Suzuki 
116*c3275903SKatsuhiro Suzuki 	regmap_write(rk3328->grf, RK3328_GRF_SOC_CON10, val);
117*c3275903SKatsuhiro Suzuki }
118*c3275903SKatsuhiro Suzuki 
119*c3275903SKatsuhiro Suzuki static int rk3328_digital_mute(struct snd_soc_dai *dai, int mute)
120*c3275903SKatsuhiro Suzuki {
121*c3275903SKatsuhiro Suzuki 	struct rk3328_codec_priv *rk3328 =
122*c3275903SKatsuhiro Suzuki 		snd_soc_component_get_drvdata(dai->component);
123*c3275903SKatsuhiro Suzuki 	unsigned int val;
124*c3275903SKatsuhiro Suzuki 
125*c3275903SKatsuhiro Suzuki 	if (mute)
126*c3275903SKatsuhiro Suzuki 		val = HPOUTL_MUTE | HPOUTR_MUTE;
127*c3275903SKatsuhiro Suzuki 	else
128*c3275903SKatsuhiro Suzuki 		val = HPOUTL_UNMUTE | HPOUTR_UNMUTE;
129*c3275903SKatsuhiro Suzuki 
130*c3275903SKatsuhiro Suzuki 	regmap_update_bits(rk3328->regmap, HPOUT_CTRL,
131*c3275903SKatsuhiro Suzuki 			   HPOUTL_MUTE_MASK | HPOUTR_MUTE_MASK, val);
132*c3275903SKatsuhiro Suzuki 
133*c3275903SKatsuhiro Suzuki 	return 0;
134*c3275903SKatsuhiro Suzuki }
135*c3275903SKatsuhiro Suzuki 
136*c3275903SKatsuhiro Suzuki static int rk3328_codec_power_on(struct rk3328_codec_priv *rk3328, int wait_ms)
137*c3275903SKatsuhiro Suzuki {
138*c3275903SKatsuhiro Suzuki 	regmap_update_bits(rk3328->regmap, DAC_PRECHARGE_CTRL,
139*c3275903SKatsuhiro Suzuki 			   DAC_CHARGE_XCHARGE_MASK, DAC_CHARGE_PRECHARGE);
140*c3275903SKatsuhiro Suzuki 	mdelay(10);
141*c3275903SKatsuhiro Suzuki 	regmap_update_bits(rk3328->regmap, DAC_PRECHARGE_CTRL,
142*c3275903SKatsuhiro Suzuki 			   DAC_CHARGE_CURRENT_ALL_MASK,
143*c3275903SKatsuhiro Suzuki 			   DAC_CHARGE_CURRENT_ALL_ON);
144*c3275903SKatsuhiro Suzuki 	mdelay(wait_ms);
145*c3275903SKatsuhiro Suzuki 
146*c3275903SKatsuhiro Suzuki 	return 0;
147*c3275903SKatsuhiro Suzuki }
148*c3275903SKatsuhiro Suzuki 
149*c3275903SKatsuhiro Suzuki static int rk3328_codec_power_off(struct rk3328_codec_priv *rk3328, int wait_ms)
150*c3275903SKatsuhiro Suzuki {
151*c3275903SKatsuhiro Suzuki 	regmap_update_bits(rk3328->regmap, DAC_PRECHARGE_CTRL,
152*c3275903SKatsuhiro Suzuki 			   DAC_CHARGE_XCHARGE_MASK, DAC_CHARGE_DISCHARGE);
153*c3275903SKatsuhiro Suzuki 	mdelay(10);
154*c3275903SKatsuhiro Suzuki 	regmap_update_bits(rk3328->regmap, DAC_PRECHARGE_CTRL,
155*c3275903SKatsuhiro Suzuki 			   DAC_CHARGE_CURRENT_ALL_MASK,
156*c3275903SKatsuhiro Suzuki 			   DAC_CHARGE_CURRENT_ALL_ON);
157*c3275903SKatsuhiro Suzuki 	mdelay(wait_ms);
158*c3275903SKatsuhiro Suzuki 
159*c3275903SKatsuhiro Suzuki 	return 0;
160*c3275903SKatsuhiro Suzuki }
161*c3275903SKatsuhiro Suzuki 
162*c3275903SKatsuhiro Suzuki static const struct rk3328_reg_msk_val playback_open_list[] = {
163*c3275903SKatsuhiro Suzuki 	{ DAC_PWR_CTRL, DAC_PWR_MASK, DAC_PWR_ON },
164*c3275903SKatsuhiro Suzuki 	{ DAC_PWR_CTRL, DACL_PATH_REFV_MASK | DACR_PATH_REFV_MASK,
165*c3275903SKatsuhiro Suzuki 	  DACL_PATH_REFV_ON | DACR_PATH_REFV_ON },
166*c3275903SKatsuhiro Suzuki 	{ DAC_PWR_CTRL, HPOUTL_ZERO_CROSSING_MASK | HPOUTR_ZERO_CROSSING_MASK,
167*c3275903SKatsuhiro Suzuki 	  HPOUTL_ZERO_CROSSING_ON | HPOUTR_ZERO_CROSSING_ON },
168*c3275903SKatsuhiro Suzuki 	{ HPOUT_POP_CTRL, HPOUTR_POP_MASK | HPOUTL_POP_MASK,
169*c3275903SKatsuhiro Suzuki 	  HPOUTR_POP_WORK | HPOUTL_POP_WORK },
170*c3275903SKatsuhiro Suzuki 	{ HPMIX_CTRL, HPMIXL_MASK | HPMIXR_MASK, HPMIXL_EN | HPMIXR_EN },
171*c3275903SKatsuhiro Suzuki 	{ HPMIX_CTRL, HPMIXL_INIT_MASK | HPMIXR_INIT_MASK,
172*c3275903SKatsuhiro Suzuki 	  HPMIXL_INIT_EN | HPMIXR_INIT_EN },
173*c3275903SKatsuhiro Suzuki 	{ HPOUT_CTRL, HPOUTL_MASK | HPOUTR_MASK, HPOUTL_EN | HPOUTR_EN },
174*c3275903SKatsuhiro Suzuki 	{ HPOUT_CTRL, HPOUTL_INIT_MASK | HPOUTR_INIT_MASK,
175*c3275903SKatsuhiro Suzuki 	  HPOUTL_INIT_EN | HPOUTR_INIT_EN },
176*c3275903SKatsuhiro Suzuki 	{ DAC_CLK_CTRL, DACL_REFV_MASK | DACR_REFV_MASK,
177*c3275903SKatsuhiro Suzuki 	  DACL_REFV_ON | DACR_REFV_ON },
178*c3275903SKatsuhiro Suzuki 	{ DAC_CLK_CTRL, DACL_CLK_MASK | DACR_CLK_MASK,
179*c3275903SKatsuhiro Suzuki 	  DACL_CLK_ON | DACR_CLK_ON },
180*c3275903SKatsuhiro Suzuki 	{ DAC_CLK_CTRL, DACL_MASK | DACR_MASK, DACL_ON | DACR_ON },
181*c3275903SKatsuhiro Suzuki 	{ DAC_CLK_CTRL, DACL_INIT_MASK | DACR_INIT_MASK,
182*c3275903SKatsuhiro Suzuki 	  DACL_INIT_ON | DACR_INIT_ON },
183*c3275903SKatsuhiro Suzuki 	{ DAC_SELECT, DACL_SELECT_MASK | DACR_SELECT_MASK,
184*c3275903SKatsuhiro Suzuki 	  DACL_SELECT | DACR_SELECT },
185*c3275903SKatsuhiro Suzuki 	{ HPMIX_CTRL, HPMIXL_INIT2_MASK | HPMIXR_INIT2_MASK,
186*c3275903SKatsuhiro Suzuki 	  HPMIXL_INIT2_EN | HPMIXR_INIT2_EN },
187*c3275903SKatsuhiro Suzuki 	{ HPOUT_CTRL, HPOUTL_MUTE_MASK | HPOUTR_MUTE_MASK,
188*c3275903SKatsuhiro Suzuki 	  HPOUTL_UNMUTE | HPOUTR_UNMUTE },
189*c3275903SKatsuhiro Suzuki };
190*c3275903SKatsuhiro Suzuki 
191*c3275903SKatsuhiro Suzuki static int rk3328_codec_open_playback(struct rk3328_codec_priv *rk3328)
192*c3275903SKatsuhiro Suzuki {
193*c3275903SKatsuhiro Suzuki 	int i;
194*c3275903SKatsuhiro Suzuki 
195*c3275903SKatsuhiro Suzuki 	regmap_update_bits(rk3328->regmap, DAC_PRECHARGE_CTRL,
196*c3275903SKatsuhiro Suzuki 			   DAC_CHARGE_CURRENT_ALL_MASK,
197*c3275903SKatsuhiro Suzuki 			   DAC_CHARGE_CURRENT_I);
198*c3275903SKatsuhiro Suzuki 
199*c3275903SKatsuhiro Suzuki 	for (i = 0; i < ARRAY_SIZE(playback_open_list); i++) {
200*c3275903SKatsuhiro Suzuki 		regmap_update_bits(rk3328->regmap,
201*c3275903SKatsuhiro Suzuki 				   playback_open_list[i].reg,
202*c3275903SKatsuhiro Suzuki 				   playback_open_list[i].msk,
203*c3275903SKatsuhiro Suzuki 				   playback_open_list[i].val);
204*c3275903SKatsuhiro Suzuki 		mdelay(1);
205*c3275903SKatsuhiro Suzuki 	}
206*c3275903SKatsuhiro Suzuki 
207*c3275903SKatsuhiro Suzuki 	msleep(rk3328->spk_depop_time);
208*c3275903SKatsuhiro Suzuki 	rk3328_analog_output(rk3328, 1);
209*c3275903SKatsuhiro Suzuki 
210*c3275903SKatsuhiro Suzuki 	regmap_update_bits(rk3328->regmap, HPOUTL_GAIN_CTRL,
211*c3275903SKatsuhiro Suzuki 			   HPOUTL_GAIN_MASK, OUT_VOLUME);
212*c3275903SKatsuhiro Suzuki 	regmap_update_bits(rk3328->regmap, HPOUTR_GAIN_CTRL,
213*c3275903SKatsuhiro Suzuki 			   HPOUTR_GAIN_MASK, OUT_VOLUME);
214*c3275903SKatsuhiro Suzuki 
215*c3275903SKatsuhiro Suzuki 	return 0;
216*c3275903SKatsuhiro Suzuki }
217*c3275903SKatsuhiro Suzuki 
218*c3275903SKatsuhiro Suzuki static const struct rk3328_reg_msk_val playback_close_list[] = {
219*c3275903SKatsuhiro Suzuki 	{ HPMIX_CTRL, HPMIXL_INIT2_MASK | HPMIXR_INIT2_MASK,
220*c3275903SKatsuhiro Suzuki 	  HPMIXL_INIT2_DIS | HPMIXR_INIT2_DIS },
221*c3275903SKatsuhiro Suzuki 	{ DAC_SELECT, DACL_SELECT_MASK | DACR_SELECT_MASK,
222*c3275903SKatsuhiro Suzuki 	  DACL_UNSELECT | DACR_UNSELECT },
223*c3275903SKatsuhiro Suzuki 	{ HPOUT_CTRL, HPOUTL_MUTE_MASK | HPOUTR_MUTE_MASK,
224*c3275903SKatsuhiro Suzuki 	  HPOUTL_MUTE | HPOUTR_MUTE },
225*c3275903SKatsuhiro Suzuki 	{ HPOUT_CTRL, HPOUTL_INIT_MASK | HPOUTR_INIT_MASK,
226*c3275903SKatsuhiro Suzuki 	  HPOUTL_INIT_DIS | HPOUTR_INIT_DIS },
227*c3275903SKatsuhiro Suzuki 	{ HPOUT_CTRL, HPOUTL_MASK | HPOUTR_MASK, HPOUTL_DIS | HPOUTR_DIS },
228*c3275903SKatsuhiro Suzuki 	{ HPMIX_CTRL, HPMIXL_MASK | HPMIXR_MASK, HPMIXL_DIS | HPMIXR_DIS },
229*c3275903SKatsuhiro Suzuki 	{ DAC_CLK_CTRL, DACL_MASK | DACR_MASK, DACL_OFF | DACR_OFF },
230*c3275903SKatsuhiro Suzuki 	{ DAC_CLK_CTRL, DACL_CLK_MASK | DACR_CLK_MASK,
231*c3275903SKatsuhiro Suzuki 	  DACL_CLK_OFF | DACR_CLK_OFF },
232*c3275903SKatsuhiro Suzuki 	{ DAC_CLK_CTRL, DACL_REFV_MASK | DACR_REFV_MASK,
233*c3275903SKatsuhiro Suzuki 	  DACL_REFV_OFF | DACR_REFV_OFF },
234*c3275903SKatsuhiro Suzuki 	{ HPOUT_POP_CTRL, HPOUTR_POP_MASK | HPOUTL_POP_MASK,
235*c3275903SKatsuhiro Suzuki 	  HPOUTR_POP_XCHARGE | HPOUTL_POP_XCHARGE },
236*c3275903SKatsuhiro Suzuki 	{ DAC_PWR_CTRL, DACL_PATH_REFV_MASK | DACR_PATH_REFV_MASK,
237*c3275903SKatsuhiro Suzuki 	  DACL_PATH_REFV_OFF | DACR_PATH_REFV_OFF },
238*c3275903SKatsuhiro Suzuki 	{ DAC_PWR_CTRL, DAC_PWR_MASK, DAC_PWR_OFF },
239*c3275903SKatsuhiro Suzuki 	{ HPMIX_CTRL, HPMIXL_INIT_MASK | HPMIXR_INIT_MASK,
240*c3275903SKatsuhiro Suzuki 	  HPMIXL_INIT_DIS | HPMIXR_INIT_DIS },
241*c3275903SKatsuhiro Suzuki 	{ DAC_CLK_CTRL, DACL_INIT_MASK | DACR_INIT_MASK,
242*c3275903SKatsuhiro Suzuki 	  DACL_INIT_OFF | DACR_INIT_OFF },
243*c3275903SKatsuhiro Suzuki };
244*c3275903SKatsuhiro Suzuki 
245*c3275903SKatsuhiro Suzuki static int rk3328_codec_close_playback(struct rk3328_codec_priv *rk3328)
246*c3275903SKatsuhiro Suzuki {
247*c3275903SKatsuhiro Suzuki 	size_t i;
248*c3275903SKatsuhiro Suzuki 
249*c3275903SKatsuhiro Suzuki 	rk3328_analog_output(rk3328, 0);
250*c3275903SKatsuhiro Suzuki 
251*c3275903SKatsuhiro Suzuki 	regmap_update_bits(rk3328->regmap, HPOUTL_GAIN_CTRL,
252*c3275903SKatsuhiro Suzuki 			   HPOUTL_GAIN_MASK, 0);
253*c3275903SKatsuhiro Suzuki 	regmap_update_bits(rk3328->regmap, HPOUTR_GAIN_CTRL,
254*c3275903SKatsuhiro Suzuki 			   HPOUTR_GAIN_MASK, 0);
255*c3275903SKatsuhiro Suzuki 
256*c3275903SKatsuhiro Suzuki 	for (i = 0; i < ARRAY_SIZE(playback_close_list); i++) {
257*c3275903SKatsuhiro Suzuki 		regmap_update_bits(rk3328->regmap,
258*c3275903SKatsuhiro Suzuki 				   playback_close_list[i].reg,
259*c3275903SKatsuhiro Suzuki 				   playback_close_list[i].msk,
260*c3275903SKatsuhiro Suzuki 				   playback_close_list[i].val);
261*c3275903SKatsuhiro Suzuki 		mdelay(1);
262*c3275903SKatsuhiro Suzuki 	}
263*c3275903SKatsuhiro Suzuki 
264*c3275903SKatsuhiro Suzuki 	regmap_update_bits(rk3328->regmap, DAC_PRECHARGE_CTRL,
265*c3275903SKatsuhiro Suzuki 			   DAC_CHARGE_CURRENT_ALL_MASK,
266*c3275903SKatsuhiro Suzuki 			   DAC_CHARGE_CURRENT_I);
267*c3275903SKatsuhiro Suzuki 
268*c3275903SKatsuhiro Suzuki 	return 0;
269*c3275903SKatsuhiro Suzuki }
270*c3275903SKatsuhiro Suzuki 
271*c3275903SKatsuhiro Suzuki static int rk3328_hw_params(struct snd_pcm_substream *substream,
272*c3275903SKatsuhiro Suzuki 			    struct snd_pcm_hw_params *params,
273*c3275903SKatsuhiro Suzuki 			    struct snd_soc_dai *dai)
274*c3275903SKatsuhiro Suzuki {
275*c3275903SKatsuhiro Suzuki 	struct rk3328_codec_priv *rk3328 =
276*c3275903SKatsuhiro Suzuki 		snd_soc_component_get_drvdata(dai->component);
277*c3275903SKatsuhiro Suzuki 	unsigned int val = 0;
278*c3275903SKatsuhiro Suzuki 
279*c3275903SKatsuhiro Suzuki 	switch (params_format(params)) {
280*c3275903SKatsuhiro Suzuki 	case SNDRV_PCM_FORMAT_S16_LE:
281*c3275903SKatsuhiro Suzuki 		val = DAC_VDL_16BITS;
282*c3275903SKatsuhiro Suzuki 		break;
283*c3275903SKatsuhiro Suzuki 	case SNDRV_PCM_FORMAT_S20_3LE:
284*c3275903SKatsuhiro Suzuki 		val = DAC_VDL_20BITS;
285*c3275903SKatsuhiro Suzuki 		break;
286*c3275903SKatsuhiro Suzuki 	case SNDRV_PCM_FORMAT_S24_LE:
287*c3275903SKatsuhiro Suzuki 		val = DAC_VDL_24BITS;
288*c3275903SKatsuhiro Suzuki 		break;
289*c3275903SKatsuhiro Suzuki 	case SNDRV_PCM_FORMAT_S32_LE:
290*c3275903SKatsuhiro Suzuki 		val = DAC_VDL_32BITS;
291*c3275903SKatsuhiro Suzuki 		break;
292*c3275903SKatsuhiro Suzuki 	default:
293*c3275903SKatsuhiro Suzuki 		return -EINVAL;
294*c3275903SKatsuhiro Suzuki 	}
295*c3275903SKatsuhiro Suzuki 	regmap_update_bits(rk3328->regmap, DAC_INIT_CTRL2, DAC_VDL_MASK, val);
296*c3275903SKatsuhiro Suzuki 
297*c3275903SKatsuhiro Suzuki 	val = DAC_WL_32BITS | DAC_RST_DIS;
298*c3275903SKatsuhiro Suzuki 	regmap_update_bits(rk3328->regmap, DAC_INIT_CTRL3,
299*c3275903SKatsuhiro Suzuki 			   DAC_WL_MASK | DAC_RST_MASK, val);
300*c3275903SKatsuhiro Suzuki 
301*c3275903SKatsuhiro Suzuki 	return 0;
302*c3275903SKatsuhiro Suzuki }
303*c3275903SKatsuhiro Suzuki 
304*c3275903SKatsuhiro Suzuki static int rk3328_pcm_startup(struct snd_pcm_substream *substream,
305*c3275903SKatsuhiro Suzuki 			      struct snd_soc_dai *dai)
306*c3275903SKatsuhiro Suzuki {
307*c3275903SKatsuhiro Suzuki 	struct rk3328_codec_priv *rk3328 =
308*c3275903SKatsuhiro Suzuki 		snd_soc_component_get_drvdata(dai->component);
309*c3275903SKatsuhiro Suzuki 
310*c3275903SKatsuhiro Suzuki 	return rk3328_codec_open_playback(rk3328);
311*c3275903SKatsuhiro Suzuki }
312*c3275903SKatsuhiro Suzuki 
313*c3275903SKatsuhiro Suzuki static void rk3328_pcm_shutdown(struct snd_pcm_substream *substream,
314*c3275903SKatsuhiro Suzuki 				struct snd_soc_dai *dai)
315*c3275903SKatsuhiro Suzuki {
316*c3275903SKatsuhiro Suzuki 	struct rk3328_codec_priv *rk3328 =
317*c3275903SKatsuhiro Suzuki 		snd_soc_component_get_drvdata(dai->component);
318*c3275903SKatsuhiro Suzuki 
319*c3275903SKatsuhiro Suzuki 	rk3328_codec_close_playback(rk3328);
320*c3275903SKatsuhiro Suzuki }
321*c3275903SKatsuhiro Suzuki 
322*c3275903SKatsuhiro Suzuki static const struct snd_soc_dai_ops rk3328_dai_ops = {
323*c3275903SKatsuhiro Suzuki 	.hw_params = rk3328_hw_params,
324*c3275903SKatsuhiro Suzuki 	.set_fmt = rk3328_set_dai_fmt,
325*c3275903SKatsuhiro Suzuki 	.digital_mute = rk3328_digital_mute,
326*c3275903SKatsuhiro Suzuki 	.startup = rk3328_pcm_startup,
327*c3275903SKatsuhiro Suzuki 	.shutdown = rk3328_pcm_shutdown,
328*c3275903SKatsuhiro Suzuki };
329*c3275903SKatsuhiro Suzuki 
330*c3275903SKatsuhiro Suzuki static struct snd_soc_dai_driver rk3328_dai[] = {
331*c3275903SKatsuhiro Suzuki 	{
332*c3275903SKatsuhiro Suzuki 		.name = "rk3328-hifi",
333*c3275903SKatsuhiro Suzuki 		.id = RK3328_HIFI,
334*c3275903SKatsuhiro Suzuki 		.playback = {
335*c3275903SKatsuhiro Suzuki 			.stream_name = "HIFI Playback",
336*c3275903SKatsuhiro Suzuki 			.channels_min = 1,
337*c3275903SKatsuhiro Suzuki 			.channels_max = 2,
338*c3275903SKatsuhiro Suzuki 			.rates = SNDRV_PCM_RATE_8000_96000,
339*c3275903SKatsuhiro Suzuki 			.formats = (SNDRV_PCM_FMTBIT_S16_LE |
340*c3275903SKatsuhiro Suzuki 				    SNDRV_PCM_FMTBIT_S20_3LE |
341*c3275903SKatsuhiro Suzuki 				    SNDRV_PCM_FMTBIT_S24_LE |
342*c3275903SKatsuhiro Suzuki 				    SNDRV_PCM_FMTBIT_S32_LE),
343*c3275903SKatsuhiro Suzuki 		},
344*c3275903SKatsuhiro Suzuki 		.capture = {
345*c3275903SKatsuhiro Suzuki 			.stream_name = "HIFI Capture",
346*c3275903SKatsuhiro Suzuki 			.channels_min = 2,
347*c3275903SKatsuhiro Suzuki 			.channels_max = 8,
348*c3275903SKatsuhiro Suzuki 			.rates = SNDRV_PCM_RATE_8000_96000,
349*c3275903SKatsuhiro Suzuki 			.formats = (SNDRV_PCM_FMTBIT_S16_LE |
350*c3275903SKatsuhiro Suzuki 				    SNDRV_PCM_FMTBIT_S20_3LE |
351*c3275903SKatsuhiro Suzuki 				    SNDRV_PCM_FMTBIT_S24_LE |
352*c3275903SKatsuhiro Suzuki 				    SNDRV_PCM_FMTBIT_S32_LE),
353*c3275903SKatsuhiro Suzuki 		},
354*c3275903SKatsuhiro Suzuki 		.ops = &rk3328_dai_ops,
355*c3275903SKatsuhiro Suzuki 	},
356*c3275903SKatsuhiro Suzuki };
357*c3275903SKatsuhiro Suzuki 
358*c3275903SKatsuhiro Suzuki static int rk3328_codec_probe(struct snd_soc_component *component)
359*c3275903SKatsuhiro Suzuki {
360*c3275903SKatsuhiro Suzuki 	struct rk3328_codec_priv *rk3328 =
361*c3275903SKatsuhiro Suzuki 		snd_soc_component_get_drvdata(component);
362*c3275903SKatsuhiro Suzuki 
363*c3275903SKatsuhiro Suzuki 	rk3328_codec_reset(rk3328);
364*c3275903SKatsuhiro Suzuki 	rk3328_codec_power_on(rk3328, 0);
365*c3275903SKatsuhiro Suzuki 
366*c3275903SKatsuhiro Suzuki 	return 0;
367*c3275903SKatsuhiro Suzuki }
368*c3275903SKatsuhiro Suzuki 
369*c3275903SKatsuhiro Suzuki static void rk3328_codec_remove(struct snd_soc_component *component)
370*c3275903SKatsuhiro Suzuki {
371*c3275903SKatsuhiro Suzuki 	struct rk3328_codec_priv *rk3328 =
372*c3275903SKatsuhiro Suzuki 		snd_soc_component_get_drvdata(component);
373*c3275903SKatsuhiro Suzuki 
374*c3275903SKatsuhiro Suzuki 	rk3328_codec_close_playback(rk3328);
375*c3275903SKatsuhiro Suzuki 	rk3328_codec_power_off(rk3328, 0);
376*c3275903SKatsuhiro Suzuki }
377*c3275903SKatsuhiro Suzuki 
378*c3275903SKatsuhiro Suzuki static const struct snd_soc_component_driver soc_codec_rk3328 = {
379*c3275903SKatsuhiro Suzuki 	.probe = rk3328_codec_probe,
380*c3275903SKatsuhiro Suzuki 	.remove = rk3328_codec_remove,
381*c3275903SKatsuhiro Suzuki };
382*c3275903SKatsuhiro Suzuki 
383*c3275903SKatsuhiro Suzuki static bool rk3328_codec_write_read_reg(struct device *dev, unsigned int reg)
384*c3275903SKatsuhiro Suzuki {
385*c3275903SKatsuhiro Suzuki 	switch (reg) {
386*c3275903SKatsuhiro Suzuki 	case CODEC_RESET:
387*c3275903SKatsuhiro Suzuki 	case DAC_INIT_CTRL1:
388*c3275903SKatsuhiro Suzuki 	case DAC_INIT_CTRL2:
389*c3275903SKatsuhiro Suzuki 	case DAC_INIT_CTRL3:
390*c3275903SKatsuhiro Suzuki 	case DAC_PRECHARGE_CTRL:
391*c3275903SKatsuhiro Suzuki 	case DAC_PWR_CTRL:
392*c3275903SKatsuhiro Suzuki 	case DAC_CLK_CTRL:
393*c3275903SKatsuhiro Suzuki 	case HPMIX_CTRL:
394*c3275903SKatsuhiro Suzuki 	case DAC_SELECT:
395*c3275903SKatsuhiro Suzuki 	case HPOUT_CTRL:
396*c3275903SKatsuhiro Suzuki 	case HPOUTL_GAIN_CTRL:
397*c3275903SKatsuhiro Suzuki 	case HPOUTR_GAIN_CTRL:
398*c3275903SKatsuhiro Suzuki 	case HPOUT_POP_CTRL:
399*c3275903SKatsuhiro Suzuki 		return true;
400*c3275903SKatsuhiro Suzuki 	default:
401*c3275903SKatsuhiro Suzuki 		return false;
402*c3275903SKatsuhiro Suzuki 	}
403*c3275903SKatsuhiro Suzuki }
404*c3275903SKatsuhiro Suzuki 
405*c3275903SKatsuhiro Suzuki static bool rk3328_codec_volatile_reg(struct device *dev, unsigned int reg)
406*c3275903SKatsuhiro Suzuki {
407*c3275903SKatsuhiro Suzuki 	switch (reg) {
408*c3275903SKatsuhiro Suzuki 	case CODEC_RESET:
409*c3275903SKatsuhiro Suzuki 		return true;
410*c3275903SKatsuhiro Suzuki 	default:
411*c3275903SKatsuhiro Suzuki 		return false;
412*c3275903SKatsuhiro Suzuki 	}
413*c3275903SKatsuhiro Suzuki }
414*c3275903SKatsuhiro Suzuki 
415*c3275903SKatsuhiro Suzuki static const struct regmap_config rk3328_codec_regmap_config = {
416*c3275903SKatsuhiro Suzuki 	.reg_bits = 32,
417*c3275903SKatsuhiro Suzuki 	.reg_stride = 4,
418*c3275903SKatsuhiro Suzuki 	.val_bits = 32,
419*c3275903SKatsuhiro Suzuki 	.max_register = HPOUT_POP_CTRL,
420*c3275903SKatsuhiro Suzuki 	.writeable_reg = rk3328_codec_write_read_reg,
421*c3275903SKatsuhiro Suzuki 	.readable_reg = rk3328_codec_write_read_reg,
422*c3275903SKatsuhiro Suzuki 	.volatile_reg = rk3328_codec_volatile_reg,
423*c3275903SKatsuhiro Suzuki 	.reg_defaults = rk3328_codec_reg_defaults,
424*c3275903SKatsuhiro Suzuki 	.num_reg_defaults = ARRAY_SIZE(rk3328_codec_reg_defaults),
425*c3275903SKatsuhiro Suzuki 	.cache_type = REGCACHE_FLAT,
426*c3275903SKatsuhiro Suzuki };
427*c3275903SKatsuhiro Suzuki 
428*c3275903SKatsuhiro Suzuki static int rk3328_platform_probe(struct platform_device *pdev)
429*c3275903SKatsuhiro Suzuki {
430*c3275903SKatsuhiro Suzuki 	struct device_node *rk3328_np = pdev->dev.of_node;
431*c3275903SKatsuhiro Suzuki 	struct rk3328_codec_priv *rk3328;
432*c3275903SKatsuhiro Suzuki 	struct resource *res;
433*c3275903SKatsuhiro Suzuki 	struct regmap *grf;
434*c3275903SKatsuhiro Suzuki 	void __iomem *base;
435*c3275903SKatsuhiro Suzuki 	int ret = 0;
436*c3275903SKatsuhiro Suzuki 
437*c3275903SKatsuhiro Suzuki 	rk3328 = devm_kzalloc(&pdev->dev, sizeof(*rk3328), GFP_KERNEL);
438*c3275903SKatsuhiro Suzuki 	if (!rk3328)
439*c3275903SKatsuhiro Suzuki 		return -ENOMEM;
440*c3275903SKatsuhiro Suzuki 
441*c3275903SKatsuhiro Suzuki 	grf = syscon_regmap_lookup_by_phandle(rk3328_np,
442*c3275903SKatsuhiro Suzuki 					      "rockchip,grf");
443*c3275903SKatsuhiro Suzuki 	if (IS_ERR(grf)) {
444*c3275903SKatsuhiro Suzuki 		dev_err(&pdev->dev, "missing 'rockchip,grf'\n");
445*c3275903SKatsuhiro Suzuki 		return PTR_ERR(grf);
446*c3275903SKatsuhiro Suzuki 	}
447*c3275903SKatsuhiro Suzuki 	rk3328->grf = grf;
448*c3275903SKatsuhiro Suzuki 	/* enable i2s_acodec_en */
449*c3275903SKatsuhiro Suzuki 	regmap_write(grf, RK3328_GRF_SOC_CON2,
450*c3275903SKatsuhiro Suzuki 		     (BIT(14) << 16 | BIT(14)));
451*c3275903SKatsuhiro Suzuki 
452*c3275903SKatsuhiro Suzuki 	ret = of_property_read_u32(rk3328_np, "spk-depop-time-ms",
453*c3275903SKatsuhiro Suzuki 				   &rk3328->spk_depop_time);
454*c3275903SKatsuhiro Suzuki 	if (ret < 0) {
455*c3275903SKatsuhiro Suzuki 		dev_info(&pdev->dev, "spk_depop_time use default value.\n");
456*c3275903SKatsuhiro Suzuki 		rk3328->spk_depop_time = 200;
457*c3275903SKatsuhiro Suzuki 	}
458*c3275903SKatsuhiro Suzuki 
459*c3275903SKatsuhiro Suzuki 	rk3328_analog_output(rk3328, 0);
460*c3275903SKatsuhiro Suzuki 
461*c3275903SKatsuhiro Suzuki 	rk3328->mclk = devm_clk_get(&pdev->dev, "mclk");
462*c3275903SKatsuhiro Suzuki 	if (IS_ERR(rk3328->mclk))
463*c3275903SKatsuhiro Suzuki 		return PTR_ERR(rk3328->mclk);
464*c3275903SKatsuhiro Suzuki 
465*c3275903SKatsuhiro Suzuki 	ret = clk_prepare_enable(rk3328->mclk);
466*c3275903SKatsuhiro Suzuki 	if (ret)
467*c3275903SKatsuhiro Suzuki 		return ret;
468*c3275903SKatsuhiro Suzuki 	clk_set_rate(rk3328->mclk, INITIAL_FREQ);
469*c3275903SKatsuhiro Suzuki 
470*c3275903SKatsuhiro Suzuki 	rk3328->pclk = devm_clk_get(&pdev->dev, "pclk");
471*c3275903SKatsuhiro Suzuki 	if (IS_ERR(rk3328->pclk)) {
472*c3275903SKatsuhiro Suzuki 		dev_err(&pdev->dev, "can't get acodec pclk\n");
473*c3275903SKatsuhiro Suzuki 		return PTR_ERR(rk3328->pclk);
474*c3275903SKatsuhiro Suzuki 	}
475*c3275903SKatsuhiro Suzuki 
476*c3275903SKatsuhiro Suzuki 	ret = clk_prepare_enable(rk3328->pclk);
477*c3275903SKatsuhiro Suzuki 	if (ret < 0) {
478*c3275903SKatsuhiro Suzuki 		dev_err(&pdev->dev, "failed to enable acodec pclk\n");
479*c3275903SKatsuhiro Suzuki 		return ret;
480*c3275903SKatsuhiro Suzuki 	}
481*c3275903SKatsuhiro Suzuki 
482*c3275903SKatsuhiro Suzuki 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
483*c3275903SKatsuhiro Suzuki 	base = devm_ioremap_resource(&pdev->dev, res);
484*c3275903SKatsuhiro Suzuki 	if (IS_ERR(base))
485*c3275903SKatsuhiro Suzuki 		return PTR_ERR(base);
486*c3275903SKatsuhiro Suzuki 
487*c3275903SKatsuhiro Suzuki 	rk3328->regmap = devm_regmap_init_mmio(&pdev->dev, base,
488*c3275903SKatsuhiro Suzuki 					       &rk3328_codec_regmap_config);
489*c3275903SKatsuhiro Suzuki 	if (IS_ERR(rk3328->regmap))
490*c3275903SKatsuhiro Suzuki 		return PTR_ERR(rk3328->regmap);
491*c3275903SKatsuhiro Suzuki 
492*c3275903SKatsuhiro Suzuki 	platform_set_drvdata(pdev, rk3328);
493*c3275903SKatsuhiro Suzuki 
494*c3275903SKatsuhiro Suzuki 	return devm_snd_soc_register_component(&pdev->dev, &soc_codec_rk3328,
495*c3275903SKatsuhiro Suzuki 					       rk3328_dai,
496*c3275903SKatsuhiro Suzuki 					       ARRAY_SIZE(rk3328_dai));
497*c3275903SKatsuhiro Suzuki }
498*c3275903SKatsuhiro Suzuki 
499*c3275903SKatsuhiro Suzuki static const struct of_device_id rk3328_codec_of_match[] = {
500*c3275903SKatsuhiro Suzuki 		{ .compatible = "rockchip,rk3328-codec", },
501*c3275903SKatsuhiro Suzuki 		{},
502*c3275903SKatsuhiro Suzuki };
503*c3275903SKatsuhiro Suzuki MODULE_DEVICE_TABLE(of, rk3328_codec_of_match);
504*c3275903SKatsuhiro Suzuki 
505*c3275903SKatsuhiro Suzuki static struct platform_driver rk3328_codec_driver = {
506*c3275903SKatsuhiro Suzuki 	.driver = {
507*c3275903SKatsuhiro Suzuki 		   .name = "rk3328-codec",
508*c3275903SKatsuhiro Suzuki 		   .owner = THIS_MODULE,
509*c3275903SKatsuhiro Suzuki 		   .of_match_table = of_match_ptr(rk3328_codec_of_match),
510*c3275903SKatsuhiro Suzuki 	},
511*c3275903SKatsuhiro Suzuki 	.probe = rk3328_platform_probe,
512*c3275903SKatsuhiro Suzuki };
513*c3275903SKatsuhiro Suzuki module_platform_driver(rk3328_codec_driver);
514*c3275903SKatsuhiro Suzuki 
515*c3275903SKatsuhiro Suzuki MODULE_AUTHOR("Sugar Zhang <sugar.zhang@rock-chips.com>");
516*c3275903SKatsuhiro Suzuki MODULE_DESCRIPTION("ASoC rk3328 codec driver");
517*c3275903SKatsuhiro Suzuki MODULE_LICENSE("GPL v2");
518