xref: /openbmc/linux/sound/soc/codecs/jz4725b.c (revision e6233ee2)
1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // JZ4725B CODEC driver
4 //
5 // Copyright (C) 2019, Paul Cercueil <paul@crapouillou.net>
6 
7 #include <linux/kernel.h>
8 #include <linux/module.h>
9 #include <linux/platform_device.h>
10 #include <linux/slab.h>
11 #include <linux/io.h>
12 #include <linux/iopoll.h>
13 #include <linux/regmap.h>
14 #include <linux/clk.h>
15 
16 #include <linux/delay.h>
17 
18 #include <sound/core.h>
19 #include <sound/pcm.h>
20 #include <sound/pcm_params.h>
21 #include <sound/initval.h>
22 #include <sound/soc.h>
23 #include <sound/tlv.h>
24 
25 #define ICDC_RGADW_OFFSET		0x00
26 #define ICDC_RGDATA_OFFSET		0x04
27 
28 /* ICDC internal register access control register(RGADW) */
29 #define ICDC_RGADW_RGWR			BIT(16)
30 
31 #define ICDC_RGADW_RGADDR_OFFSET	8
32 #define	ICDC_RGADW_RGADDR_MASK		GENMASK(14, ICDC_RGADW_RGADDR_OFFSET)
33 
34 #define ICDC_RGADW_RGDIN_OFFSET		0
35 #define	ICDC_RGADW_RGDIN_MASK		GENMASK(7, ICDC_RGADW_RGDIN_OFFSET)
36 
37 /* ICDC internal register data output register (RGDATA)*/
38 #define ICDC_RGDATA_IRQ			BIT(8)
39 
40 #define ICDC_RGDATA_RGDOUT_OFFSET	0
41 #define ICDC_RGDATA_RGDOUT_MASK		GENMASK(7, ICDC_RGDATA_RGDOUT_OFFSET)
42 
43 /* JZ internal register space */
44 enum {
45 	JZ4725B_CODEC_REG_AICR,
46 	JZ4725B_CODEC_REG_CR1,
47 	JZ4725B_CODEC_REG_CR2,
48 	JZ4725B_CODEC_REG_CCR1,
49 	JZ4725B_CODEC_REG_CCR2,
50 	JZ4725B_CODEC_REG_PMR1,
51 	JZ4725B_CODEC_REG_PMR2,
52 	JZ4725B_CODEC_REG_CRR,
53 	JZ4725B_CODEC_REG_ICR,
54 	JZ4725B_CODEC_REG_IFR,
55 	JZ4725B_CODEC_REG_CGR1,
56 	JZ4725B_CODEC_REG_CGR2,
57 	JZ4725B_CODEC_REG_CGR3,
58 	JZ4725B_CODEC_REG_CGR4,
59 	JZ4725B_CODEC_REG_CGR5,
60 	JZ4725B_CODEC_REG_CGR6,
61 	JZ4725B_CODEC_REG_CGR7,
62 	JZ4725B_CODEC_REG_CGR8,
63 	JZ4725B_CODEC_REG_CGR9,
64 	JZ4725B_CODEC_REG_CGR10,
65 	JZ4725B_CODEC_REG_TR1,
66 	JZ4725B_CODEC_REG_TR2,
67 	JZ4725B_CODEC_REG_CR3,
68 	JZ4725B_CODEC_REG_AGC1,
69 	JZ4725B_CODEC_REG_AGC2,
70 	JZ4725B_CODEC_REG_AGC3,
71 	JZ4725B_CODEC_REG_AGC4,
72 	JZ4725B_CODEC_REG_AGC5,
73 };
74 
75 #define REG_AICR_CONFIG1_OFFSET		0
76 #define REG_AICR_CONFIG1_MASK		(0xf << REG_AICR_CONFIG1_OFFSET)
77 
78 #define REG_CR1_SB_MICBIAS_OFFSET	7
79 #define REG_CR1_MONO_OFFSET		6
80 #define REG_CR1_DAC_MUTE_OFFSET		5
81 #define REG_CR1_HP_DIS_OFFSET		4
82 #define REG_CR1_DACSEL_OFFSET		3
83 #define REG_CR1_BYPASS_OFFSET		2
84 
85 #define REG_CR2_DAC_DEEMP_OFFSET	7
86 #define REG_CR2_DAC_ADWL_OFFSET		5
87 #define REG_CR2_DAC_ADWL_MASK		(0x3 << REG_CR2_DAC_ADWL_OFFSET)
88 #define REG_CR2_ADC_ADWL_OFFSET		3
89 #define REG_CR2_ADC_ADWL_MASK		(0x3 << REG_CR2_ADC_ADWL_OFFSET)
90 #define REG_CR2_ADC_HPF_OFFSET		2
91 
92 #define REG_CR3_SB_MIC1_OFFSET		7
93 #define REG_CR3_SB_MIC2_OFFSET		6
94 #define REG_CR3_SIDETONE1_OFFSET	5
95 #define REG_CR3_SIDETONE2_OFFSET	4
96 #define REG_CR3_MICDIFF_OFFSET		3
97 #define REG_CR3_MICSTEREO_OFFSET	2
98 #define REG_CR3_INSEL_OFFSET		0
99 #define REG_CR3_INSEL_MASK		(0x3 << REG_CR3_INSEL_OFFSET)
100 
101 #define REG_CCR1_CONFIG4_OFFSET		0
102 #define REG_CCR1_CONFIG4_MASK		(0xf << REG_CCR1_CONFIG4_OFFSET)
103 
104 #define REG_CCR2_DFREQ_OFFSET		4
105 #define REG_CCR2_DFREQ_MASK		(0xf << REG_CCR2_DFREQ_OFFSET)
106 #define REG_CCR2_AFREQ_OFFSET		0
107 #define REG_CCR2_AFREQ_MASK		(0xf << REG_CCR2_AFREQ_OFFSET)
108 
109 #define REG_PMR1_SB_DAC_OFFSET		7
110 #define REG_PMR1_SB_OUT_OFFSET		6
111 #define REG_PMR1_SB_MIX_OFFSET		5
112 #define REG_PMR1_SB_ADC_OFFSET		4
113 #define REG_PMR1_SB_LIN_OFFSET		3
114 #define REG_PMR1_SB_IND_OFFSET		0
115 
116 #define REG_PMR2_LRGI_OFFSET		7
117 #define REG_PMR2_RLGI_OFFSET		6
118 #define REG_PMR2_LRGOD_OFFSET		5
119 #define REG_PMR2_RLGOD_OFFSET		4
120 #define REG_PMR2_GIM_OFFSET		3
121 #define REG_PMR2_SB_MC_OFFSET		2
122 #define REG_PMR2_SB_OFFSET		1
123 #define REG_PMR2_SB_SLEEP_OFFSET	0
124 
125 #define REG_IFR_RAMP_UP_DONE_OFFSET	3
126 #define REG_IFR_RAMP_DOWN_DONE_OFFSET	2
127 
128 #define REG_CGR1_GODL_OFFSET		4
129 #define REG_CGR1_GODL_MASK		(0xf << REG_CGR1_GODL_OFFSET)
130 #define REG_CGR1_GODR_OFFSET		0
131 #define REG_CGR1_GODR_MASK		(0xf << REG_CGR1_GODR_OFFSET)
132 
133 #define REG_CGR2_GO1R_OFFSET		0
134 #define REG_CGR2_GO1R_MASK		(0x1f << REG_CGR2_GO1R_OFFSET)
135 
136 #define REG_CGR3_GO1L_OFFSET		0
137 #define REG_CGR3_GO1L_MASK		(0x1f << REG_CGR3_GO1L_OFFSET)
138 
139 #define REG_CGR8_GOR_OFFSET		0
140 #define REG_CGR8_GOR_MASK		(0x1f << REG_CGR8_GOR_OFFSET)
141 
142 #define REG_CGR9_GOL_OFFSET		0
143 #define REG_CGR9_GOL_MASK		(0x1f << REG_CGR9_GOL_OFFSET)
144 
145 #define REG_CGR10_GIL_OFFSET		0
146 #define REG_CGR10_GIR_OFFSET		4
147 
148 struct jz_icdc {
149 	struct regmap *regmap;
150 	void __iomem *base;
151 	struct clk *clk;
152 };
153 
154 static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(jz4725b_adc_tlv,     0, 150, 0);
155 static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(jz4725b_dac_tlv, -2250, 150, 0);
156 static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(jz4725b_out_tlv,
157 	 0, 11, TLV_DB_SCALE_ITEM(-3350, 200, 0),
158 	12, 23, TLV_DB_SCALE_ITEM(-1050, 100, 0),
159 	24, 31, TLV_DB_SCALE_ITEM(  100,  50, 0),
160 );
161 
162 static const struct snd_kcontrol_new jz4725b_codec_controls[] = {
163 	SOC_DOUBLE_TLV("DAC Playback Volume",
164 		       JZ4725B_CODEC_REG_CGR1,
165 		       REG_CGR1_GODL_OFFSET,
166 		       REG_CGR1_GODR_OFFSET,
167 		       0xf, 1, jz4725b_dac_tlv),
168 	SOC_DOUBLE_TLV("Master Capture Volume",
169 		       JZ4725B_CODEC_REG_CGR10,
170 		       REG_CGR10_GIL_OFFSET,
171 		       REG_CGR10_GIR_OFFSET,
172 		       0xf, 0, jz4725b_adc_tlv),
173 
174 	SOC_DOUBLE_R_TLV("Master Playback Volume",
175 			 JZ4725B_CODEC_REG_CGR9,
176 			 JZ4725B_CODEC_REG_CGR8,
177 			 REG_CGR8_GOR_OFFSET,
178 			 0x1f, 1, jz4725b_out_tlv),
179 
180 	SOC_SINGLE("DAC Playback Switch", JZ4725B_CODEC_REG_CR1,
181 		   REG_CR1_DAC_MUTE_OFFSET, 1, 1),
182 
183 	SOC_SINGLE("Deemphasize Filter Playback Switch",
184 		   JZ4725B_CODEC_REG_CR2,
185 		   REG_CR2_DAC_DEEMP_OFFSET, 1, 0),
186 
187 	SOC_SINGLE("High-Pass Filter Capture Switch",
188 		   JZ4725B_CODEC_REG_CR2,
189 		   REG_CR2_ADC_HPF_OFFSET, 1, 0),
190 };
191 
192 static const char * const jz4725b_codec_adc_src_texts[] = {
193 	"Mic 1", "Mic 2", "Line In", "Mixer",
194 };
195 static const unsigned int jz4725b_codec_adc_src_values[] = { 0, 1, 2, 3, };
196 static SOC_VALUE_ENUM_SINGLE_DECL(jz4725b_codec_adc_src_enum,
197 				  JZ4725B_CODEC_REG_CR3,
198 				  REG_CR3_INSEL_OFFSET,
199 				  REG_CR3_INSEL_MASK,
200 				  jz4725b_codec_adc_src_texts,
201 				  jz4725b_codec_adc_src_values);
202 static const struct snd_kcontrol_new jz4725b_codec_adc_src_ctrl =
203 	SOC_DAPM_ENUM("ADC Source Capture Route", jz4725b_codec_adc_src_enum);
204 
205 static const struct snd_kcontrol_new jz4725b_codec_mixer_controls[] = {
206 	SOC_DAPM_SINGLE("Line In Bypass", JZ4725B_CODEC_REG_CR1,
207 			REG_CR1_BYPASS_OFFSET, 1, 0),
208 };
209 
210 static int jz4725b_out_stage_enable(struct snd_soc_dapm_widget *w,
211 				    struct snd_kcontrol *kcontrol,
212 				    int event)
213 {
214 	struct snd_soc_component *codec = snd_soc_dapm_to_component(w->dapm);
215 	struct jz_icdc *icdc = snd_soc_component_get_drvdata(codec);
216 	struct regmap *map = icdc->regmap;
217 	unsigned int val;
218 
219 	switch (event) {
220 	case SND_SOC_DAPM_PRE_PMU:
221 		return regmap_clear_bits(map, JZ4725B_CODEC_REG_IFR,
222 					 BIT(REG_IFR_RAMP_UP_DONE_OFFSET));
223 	case SND_SOC_DAPM_POST_PMU:
224 		return regmap_read_poll_timeout(map, JZ4725B_CODEC_REG_IFR,
225 			       val, val & BIT(REG_IFR_RAMP_UP_DONE_OFFSET),
226 			       100000, 500000);
227 	case SND_SOC_DAPM_PRE_PMD:
228 		return regmap_clear_bits(map, JZ4725B_CODEC_REG_IFR,
229 				BIT(REG_IFR_RAMP_DOWN_DONE_OFFSET));
230 	case SND_SOC_DAPM_POST_PMD:
231 		return regmap_read_poll_timeout(map, JZ4725B_CODEC_REG_IFR,
232 			       val, val & BIT(REG_IFR_RAMP_DOWN_DONE_OFFSET),
233 			       100000, 500000);
234 	default:
235 		return -EINVAL;
236 	}
237 }
238 
239 static const struct snd_soc_dapm_widget jz4725b_codec_dapm_widgets[] = {
240 	/* DAC */
241 	SND_SOC_DAPM_DAC("DAC", "Playback",
242 			 JZ4725B_CODEC_REG_PMR1, REG_PMR1_SB_DAC_OFFSET, 1),
243 
244 	/* ADC */
245 	SND_SOC_DAPM_ADC("ADC", "Capture",
246 			 JZ4725B_CODEC_REG_PMR1, REG_PMR1_SB_ADC_OFFSET, 1),
247 
248 	SND_SOC_DAPM_MUX("ADC Source Capture Route", SND_SOC_NOPM, 0, 0,
249 			 &jz4725b_codec_adc_src_ctrl),
250 
251 	/* Mixer */
252 	SND_SOC_DAPM_MIXER("Mixer", JZ4725B_CODEC_REG_PMR1,
253 			   REG_PMR1_SB_MIX_OFFSET, 1,
254 			   jz4725b_codec_mixer_controls,
255 			   ARRAY_SIZE(jz4725b_codec_mixer_controls)),
256 	SND_SOC_DAPM_MIXER("DAC to Mixer", JZ4725B_CODEC_REG_CR1,
257 			   REG_CR1_DACSEL_OFFSET, 0, NULL, 0),
258 
259 	SND_SOC_DAPM_MIXER("Line In", JZ4725B_CODEC_REG_PMR1,
260 			   REG_PMR1_SB_LIN_OFFSET, 1, NULL, 0),
261 	SND_SOC_DAPM_MIXER("HP Out", JZ4725B_CODEC_REG_CR1,
262 			   REG_CR1_HP_DIS_OFFSET, 1, NULL, 0),
263 
264 	SND_SOC_DAPM_MIXER("Mic 1", JZ4725B_CODEC_REG_CR3,
265 			   REG_CR3_SB_MIC1_OFFSET, 1, NULL, 0),
266 	SND_SOC_DAPM_MIXER("Mic 2", JZ4725B_CODEC_REG_CR3,
267 			   REG_CR3_SB_MIC2_OFFSET, 1, NULL, 0),
268 
269 	SND_SOC_DAPM_MIXER_E("Out Stage", JZ4725B_CODEC_REG_PMR1,
270 			     REG_PMR1_SB_OUT_OFFSET, 1, NULL, 0,
271 			     jz4725b_out_stage_enable,
272 			     SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
273 			     SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
274 	SND_SOC_DAPM_MIXER("Mixer to ADC", JZ4725B_CODEC_REG_PMR1,
275 			   REG_PMR1_SB_IND_OFFSET, 1, NULL, 0),
276 
277 	SND_SOC_DAPM_SUPPLY("Mic Bias", JZ4725B_CODEC_REG_CR1,
278 			    REG_CR1_SB_MICBIAS_OFFSET, 1, NULL, 0),
279 
280 	/* Pins */
281 	SND_SOC_DAPM_INPUT("MIC1P"),
282 	SND_SOC_DAPM_INPUT("MIC1N"),
283 	SND_SOC_DAPM_INPUT("MIC2P"),
284 	SND_SOC_DAPM_INPUT("MIC2N"),
285 
286 	SND_SOC_DAPM_INPUT("LLINEIN"),
287 	SND_SOC_DAPM_INPUT("RLINEIN"),
288 
289 	SND_SOC_DAPM_OUTPUT("LHPOUT"),
290 	SND_SOC_DAPM_OUTPUT("RHPOUT"),
291 };
292 
293 static const struct snd_soc_dapm_route jz4725b_codec_dapm_routes[] = {
294 	{"Mic 1", NULL, "MIC1P"},
295 	{"Mic 1", NULL, "MIC1N"},
296 	{"Mic 2", NULL, "MIC2P"},
297 	{"Mic 2", NULL, "MIC2N"},
298 
299 	{"Line In", NULL, "LLINEIN"},
300 	{"Line In", NULL, "RLINEIN"},
301 
302 	{"Mixer", "Line In Bypass", "Line In"},
303 	{"DAC to Mixer", NULL, "DAC"},
304 	{"Mixer", NULL, "DAC to Mixer"},
305 
306 	{"Mixer to ADC", NULL, "Mixer"},
307 	{"ADC Source Capture Route", "Mixer", "Mixer to ADC"},
308 	{"ADC Sourc Capture Routee", "Line In", "Line In"},
309 	{"ADC Source Capture Route", "Mic 1", "Mic 1"},
310 	{"ADC Source Capture Route", "Mic 2", "Mic 2"},
311 	{"ADC", NULL, "ADC Source Capture Route"},
312 
313 	{"Out Stage", NULL, "Mixer"},
314 	{"HP Out", NULL, "Out Stage"},
315 	{"LHPOUT", NULL, "HP Out"},
316 	{"RHPOUT", NULL, "HP Out"},
317 };
318 
319 static int jz4725b_codec_set_bias_level(struct snd_soc_component *component,
320 					enum snd_soc_bias_level level)
321 {
322 	struct jz_icdc *icdc = snd_soc_component_get_drvdata(component);
323 	struct regmap *map = icdc->regmap;
324 
325 	switch (level) {
326 	case SND_SOC_BIAS_ON:
327 		regmap_clear_bits(map, JZ4725B_CODEC_REG_PMR2,
328 				  BIT(REG_PMR2_SB_SLEEP_OFFSET));
329 		break;
330 	case SND_SOC_BIAS_PREPARE:
331 		/* Enable sound hardware */
332 		regmap_clear_bits(map, JZ4725B_CODEC_REG_PMR2,
333 				  BIT(REG_PMR2_SB_OFFSET));
334 		msleep(224);
335 		break;
336 	case SND_SOC_BIAS_STANDBY:
337 		regmap_set_bits(map, JZ4725B_CODEC_REG_PMR2,
338 				BIT(REG_PMR2_SB_SLEEP_OFFSET));
339 		break;
340 	case SND_SOC_BIAS_OFF:
341 		regmap_set_bits(map, JZ4725B_CODEC_REG_PMR2,
342 				BIT(REG_PMR2_SB_OFFSET));
343 		break;
344 	}
345 
346 	return 0;
347 }
348 
349 static int jz4725b_codec_dev_probe(struct snd_soc_component *component)
350 {
351 	struct jz_icdc *icdc = snd_soc_component_get_drvdata(component);
352 	struct regmap *map = icdc->regmap;
353 
354 	clk_prepare_enable(icdc->clk);
355 
356 	/* Write CONFIGn (n=1 to 8) bits.
357 	 * The value 0x0f is specified in the datasheet as a requirement.
358 	 */
359 	regmap_write(map, JZ4725B_CODEC_REG_AICR,
360 		     0xf << REG_AICR_CONFIG1_OFFSET);
361 	regmap_write(map, JZ4725B_CODEC_REG_CCR1,
362 		     0x0 << REG_CCR1_CONFIG4_OFFSET);
363 
364 	return 0;
365 }
366 
367 static void jz4725b_codec_dev_remove(struct snd_soc_component *component)
368 {
369 	struct jz_icdc *icdc = snd_soc_component_get_drvdata(component);
370 
371 	clk_disable_unprepare(icdc->clk);
372 }
373 
374 static const struct snd_soc_component_driver jz4725b_codec = {
375 	.probe			= jz4725b_codec_dev_probe,
376 	.remove			= jz4725b_codec_dev_remove,
377 	.set_bias_level		= jz4725b_codec_set_bias_level,
378 	.controls		= jz4725b_codec_controls,
379 	.num_controls		= ARRAY_SIZE(jz4725b_codec_controls),
380 	.dapm_widgets		= jz4725b_codec_dapm_widgets,
381 	.num_dapm_widgets	= ARRAY_SIZE(jz4725b_codec_dapm_widgets),
382 	.dapm_routes		= jz4725b_codec_dapm_routes,
383 	.num_dapm_routes	= ARRAY_SIZE(jz4725b_codec_dapm_routes),
384 	.suspend_bias_off	= 1,
385 	.use_pmdown_time	= 1,
386 };
387 
388 static const unsigned int jz4725b_codec_sample_rates[] = {
389 	96000, 48000, 44100, 32000,
390 	24000, 22050, 16000, 12000,
391 	11025, 9600, 8000,
392 };
393 
394 static int jz4725b_codec_hw_params(struct snd_pcm_substream *substream,
395 	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
396 {
397 	struct jz_icdc *icdc = snd_soc_component_get_drvdata(dai->component);
398 	unsigned int rate, bit_width;
399 
400 	switch (params_format(params)) {
401 	case SNDRV_PCM_FORMAT_S16_LE:
402 		bit_width = 0;
403 		break;
404 	case SNDRV_PCM_FORMAT_S18_3LE:
405 		bit_width = 1;
406 		break;
407 	case SNDRV_PCM_FORMAT_S20_3LE:
408 		bit_width = 2;
409 		break;
410 	case SNDRV_PCM_FORMAT_S24_3LE:
411 		bit_width = 3;
412 		break;
413 	default:
414 		return -EINVAL;
415 	}
416 
417 	for (rate = 0; rate < ARRAY_SIZE(jz4725b_codec_sample_rates); rate++) {
418 		if (jz4725b_codec_sample_rates[rate] == params_rate(params))
419 			break;
420 	}
421 
422 	if (rate == ARRAY_SIZE(jz4725b_codec_sample_rates))
423 		return -EINVAL;
424 
425 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
426 		regmap_update_bits(icdc->regmap,
427 				   JZ4725B_CODEC_REG_CR2,
428 				   REG_CR2_DAC_ADWL_MASK,
429 				   bit_width << REG_CR2_DAC_ADWL_OFFSET);
430 
431 		regmap_update_bits(icdc->regmap,
432 				   JZ4725B_CODEC_REG_CCR2,
433 				   REG_CCR2_DFREQ_MASK,
434 				   rate << REG_CCR2_DFREQ_OFFSET);
435 	} else {
436 		regmap_update_bits(icdc->regmap,
437 				   JZ4725B_CODEC_REG_CR2,
438 				   REG_CR2_ADC_ADWL_MASK,
439 				   bit_width << REG_CR2_ADC_ADWL_OFFSET);
440 
441 		regmap_update_bits(icdc->regmap,
442 				   JZ4725B_CODEC_REG_CCR2,
443 				   REG_CCR2_AFREQ_MASK,
444 				   rate << REG_CCR2_AFREQ_OFFSET);
445 	}
446 
447 	return 0;
448 }
449 
450 static const struct snd_soc_dai_ops jz4725b_codec_dai_ops = {
451 	.hw_params = jz4725b_codec_hw_params,
452 };
453 
454 #define JZ_ICDC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE  | SNDRV_PCM_FMTBIT_S18_3LE | \
455 			 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_3LE)
456 
457 static struct snd_soc_dai_driver jz4725b_codec_dai = {
458 	.name = "jz4725b-hifi",
459 	.playback = {
460 		.stream_name = "Playback",
461 		.channels_min = 2,
462 		.channels_max = 2,
463 		.rates = SNDRV_PCM_RATE_8000_96000,
464 		.formats = JZ_ICDC_FORMATS,
465 	},
466 	.capture = {
467 		.stream_name = "Capture",
468 		.channels_min = 2,
469 		.channels_max = 2,
470 		.rates = SNDRV_PCM_RATE_8000_96000,
471 		.formats = JZ_ICDC_FORMATS,
472 	},
473 	.ops = &jz4725b_codec_dai_ops,
474 };
475 
476 static bool jz4725b_codec_volatile(struct device *dev, unsigned int reg)
477 {
478 	return reg == JZ4725B_CODEC_REG_IFR;
479 }
480 
481 static bool jz4725b_codec_can_access_reg(struct device *dev, unsigned int reg)
482 {
483 	return (reg != JZ4725B_CODEC_REG_TR1) && (reg != JZ4725B_CODEC_REG_TR2);
484 }
485 
486 static int jz4725b_codec_io_wait(struct jz_icdc *icdc)
487 {
488 	u32 reg;
489 
490 	return readl_poll_timeout(icdc->base + ICDC_RGADW_OFFSET, reg,
491 				  !(reg & ICDC_RGADW_RGWR), 1000, 10000);
492 }
493 
494 static int jz4725b_codec_reg_read(void *context, unsigned int reg,
495 				  unsigned int *val)
496 {
497 	struct jz_icdc *icdc = context;
498 	unsigned int i;
499 	u32 tmp;
500 	int ret;
501 
502 	ret = jz4725b_codec_io_wait(icdc);
503 	if (ret)
504 		return ret;
505 
506 	tmp = readl(icdc->base + ICDC_RGADW_OFFSET);
507 	tmp = (tmp & ~ICDC_RGADW_RGADDR_MASK)
508 	    | (reg << ICDC_RGADW_RGADDR_OFFSET);
509 	writel(tmp, icdc->base + ICDC_RGADW_OFFSET);
510 
511 	/* wait 6+ cycles */
512 	for (i = 0; i < 6; i++)
513 		*val = readl(icdc->base + ICDC_RGDATA_OFFSET) &
514 			ICDC_RGDATA_RGDOUT_MASK;
515 
516 	return 0;
517 }
518 
519 static int jz4725b_codec_reg_write(void *context, unsigned int reg,
520 				   unsigned int val)
521 {
522 	struct jz_icdc *icdc = context;
523 	int ret;
524 
525 	ret = jz4725b_codec_io_wait(icdc);
526 	if (ret)
527 		return ret;
528 
529 	writel(ICDC_RGADW_RGWR | (reg << ICDC_RGADW_RGADDR_OFFSET) | val,
530 			icdc->base + ICDC_RGADW_OFFSET);
531 
532 	ret = jz4725b_codec_io_wait(icdc);
533 	if (ret)
534 		return ret;
535 
536 	return 0;
537 }
538 
539 static const u8 jz4725b_codec_reg_defaults[] = {
540 	0x0c, 0xaa, 0x78, 0x00, 0x00, 0xff, 0x03, 0x51,
541 	0x3f, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04,
542 	0x04, 0x0a, 0x0a, 0x00, 0x00, 0x00, 0xc0, 0x34,
543 	0x07, 0x44, 0x1f, 0x00,
544 };
545 
546 static const struct regmap_config jz4725b_codec_regmap_config = {
547 	.reg_bits = 7,
548 	.val_bits = 8,
549 
550 	.max_register = JZ4725B_CODEC_REG_AGC5,
551 	.volatile_reg = jz4725b_codec_volatile,
552 	.readable_reg = jz4725b_codec_can_access_reg,
553 	.writeable_reg = jz4725b_codec_can_access_reg,
554 
555 	.reg_read = jz4725b_codec_reg_read,
556 	.reg_write = jz4725b_codec_reg_write,
557 
558 	.reg_defaults_raw = jz4725b_codec_reg_defaults,
559 	.num_reg_defaults_raw = ARRAY_SIZE(jz4725b_codec_reg_defaults),
560 	.cache_type = REGCACHE_FLAT,
561 };
562 
563 static int jz4725b_codec_probe(struct platform_device *pdev)
564 {
565 	struct device *dev = &pdev->dev;
566 	struct jz_icdc *icdc;
567 	int ret;
568 
569 	icdc = devm_kzalloc(dev, sizeof(*icdc), GFP_KERNEL);
570 	if (!icdc)
571 		return -ENOMEM;
572 
573 	icdc->base = devm_platform_ioremap_resource(pdev, 0);
574 	if (IS_ERR(icdc->base))
575 		return PTR_ERR(icdc->base);
576 
577 	icdc->regmap = devm_regmap_init(dev, NULL, icdc,
578 					&jz4725b_codec_regmap_config);
579 	if (IS_ERR(icdc->regmap))
580 		return PTR_ERR(icdc->regmap);
581 
582 	icdc->clk = devm_clk_get(&pdev->dev, "aic");
583 	if (IS_ERR(icdc->clk))
584 		return PTR_ERR(icdc->clk);
585 
586 	platform_set_drvdata(pdev, icdc);
587 
588 	ret = devm_snd_soc_register_component(dev, &jz4725b_codec,
589 					      &jz4725b_codec_dai, 1);
590 	if (ret)
591 		dev_err(dev, "Failed to register codec\n");
592 
593 	return ret;
594 }
595 
596 static const struct of_device_id jz4725b_codec_of_matches[] = {
597 	{ .compatible = "ingenic,jz4725b-codec", },
598 	{ }
599 };
600 MODULE_DEVICE_TABLE(of, jz4725b_codec_of_matches);
601 
602 static struct platform_driver jz4725b_codec_driver = {
603 	.probe = jz4725b_codec_probe,
604 	.driver = {
605 		.name = "jz4725b-codec",
606 		.of_match_table = jz4725b_codec_of_matches,
607 	},
608 };
609 module_platform_driver(jz4725b_codec_driver);
610 
611 MODULE_DESCRIPTION("JZ4725B SoC internal codec driver");
612 MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>");
613 MODULE_LICENSE("GPL v2");
614