xref: /openbmc/linux/sound/soc/codecs/jz4770.c (revision f5ad1c74)
1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // Ingenic JZ4770 CODEC driver
4 //
5 // Copyright (C) 2012, Maarten ter Huurne <maarten@treewalker.org>
6 // Copyright (C) 2019, Paul Cercueil <paul@crapouillou.net>
7 
8 #include <linux/clk.h>
9 #include <linux/delay.h>
10 #include <linux/iopoll.h>
11 #include <linux/module.h>
12 #include <linux/regmap.h>
13 #include <linux/time64.h>
14 
15 #include <sound/pcm_params.h>
16 #include <sound/soc.h>
17 #include <sound/soc-dai.h>
18 #include <sound/soc-dapm.h>
19 #include <sound/tlv.h>
20 
21 #define ICDC_RGADW_OFFSET		0x00
22 #define ICDC_RGDATA_OFFSET		0x04
23 
24 /* ICDC internal register access control register(RGADW) */
25 #define ICDC_RGADW_RGWR			BIT(16)
26 
27 #define ICDC_RGADW_RGADDR_OFFSET	8
28 #define	ICDC_RGADW_RGADDR_MASK		GENMASK(14, ICDC_RGADW_RGADDR_OFFSET)
29 
30 #define ICDC_RGADW_RGDIN_OFFSET		0
31 #define	ICDC_RGADW_RGDIN_MASK		GENMASK(7, ICDC_RGADW_RGDIN_OFFSET)
32 
33 /* ICDC internal register data output register (RGDATA)*/
34 #define ICDC_RGDATA_IRQ			BIT(8)
35 
36 #define ICDC_RGDATA_RGDOUT_OFFSET	0
37 #define ICDC_RGDATA_RGDOUT_MASK		GENMASK(7, ICDC_RGDATA_RGDOUT_OFFSET)
38 
39 /* Internal register space, accessed through regmap */
40 enum {
41 	JZ4770_CODEC_REG_SR,
42 	JZ4770_CODEC_REG_AICR_DAC,
43 	JZ4770_CODEC_REG_AICR_ADC,
44 	JZ4770_CODEC_REG_CR_LO,
45 	JZ4770_CODEC_REG_CR_HP,
46 
47 	JZ4770_CODEC_REG_MISSING_REG1,
48 
49 	JZ4770_CODEC_REG_CR_DAC,
50 	JZ4770_CODEC_REG_CR_MIC,
51 	JZ4770_CODEC_REG_CR_LI,
52 	JZ4770_CODEC_REG_CR_ADC,
53 	JZ4770_CODEC_REG_CR_MIX,
54 	JZ4770_CODEC_REG_CR_VIC,
55 	JZ4770_CODEC_REG_CCR,
56 	JZ4770_CODEC_REG_FCR_DAC,
57 	JZ4770_CODEC_REG_FCR_ADC,
58 	JZ4770_CODEC_REG_ICR,
59 	JZ4770_CODEC_REG_IMR,
60 	JZ4770_CODEC_REG_IFR,
61 	JZ4770_CODEC_REG_GCR_HPL,
62 	JZ4770_CODEC_REG_GCR_HPR,
63 	JZ4770_CODEC_REG_GCR_LIBYL,
64 	JZ4770_CODEC_REG_GCR_LIBYR,
65 	JZ4770_CODEC_REG_GCR_DACL,
66 	JZ4770_CODEC_REG_GCR_DACR,
67 	JZ4770_CODEC_REG_GCR_MIC1,
68 	JZ4770_CODEC_REG_GCR_MIC2,
69 	JZ4770_CODEC_REG_GCR_ADCL,
70 	JZ4770_CODEC_REG_GCR_ADCR,
71 
72 	JZ4770_CODEC_REG_MISSING_REG2,
73 
74 	JZ4770_CODEC_REG_GCR_MIXADC,
75 	JZ4770_CODEC_REG_GCR_MIXDAC,
76 	JZ4770_CODEC_REG_AGC1,
77 	JZ4770_CODEC_REG_AGC2,
78 	JZ4770_CODEC_REG_AGC3,
79 	JZ4770_CODEC_REG_AGC4,
80 	JZ4770_CODEC_REG_AGC5,
81 };
82 
83 #define REG_AICR_DAC_ADWL_OFFSET	6
84 #define REG_AICR_DAC_ADWL_MASK		(0x3 << REG_AICR_DAC_ADWL_OFFSET)
85 #define REG_AICR_DAC_SERIAL		BIT(1)
86 #define REG_AICR_DAC_I2S		BIT(0)
87 
88 #define REG_AICR_ADC_ADWL_OFFSET	6
89 #define REG_AICR_ADC_ADWL_MASK		(0x3 << REG_AICR_ADC_ADWL_OFFSET)
90 #define REG_AICR_ADC_SERIAL		BIT(1)
91 #define REG_AICR_ADC_I2S		BIT(0)
92 
93 #define REG_CR_LO_MUTE_OFFSET		7
94 #define REG_CR_LO_SB_OFFSET		4
95 #define REG_CR_LO_SEL_OFFSET		0
96 #define REG_CR_LO_SEL_MASK		(0x3 << REG_CR_LO_SEL_OFFSET)
97 
98 #define REG_CR_HP_MUTE			BIT(7)
99 #define REG_CR_HP_LOAD			BIT(6)
100 #define REG_CR_HP_SB_OFFSET		4
101 #define REG_CR_HP_SB_HPCM_OFFSET	3
102 #define REG_CR_HP_SEL_OFFSET		0
103 #define REG_CR_HP_SEL_MASK		(0x3 << REG_CR_HP_SEL_OFFSET)
104 
105 #define REG_CR_DAC_MUTE			BIT(7)
106 #define REG_CR_DAC_MONO			BIT(6)
107 #define REG_CR_DAC_LEFT_ONLY		BIT(5)
108 #define REG_CR_DAC_SB_OFFSET		4
109 #define REG_CR_DAC_LRSWAP		BIT(3)
110 
111 #define REG_CR_MIC_STEREO_OFFSET	7
112 #define REG_CR_MIC_IDIFF_OFFSET		6
113 #define REG_CR_MIC_SB_MIC2_OFFSET	5
114 #define REG_CR_MIC_SB_MIC1_OFFSET	4
115 #define REG_CR_MIC_BIAS_V0_OFFSET	1
116 #define REG_CR_MIC_BIAS_SB_OFFSET	0
117 
118 #define REG_CR_LI_LIBY_OFFSET		4
119 #define REG_CR_LI_SB_OFFSET		0
120 
121 #define REG_CR_ADC_DMIC_SEL		BIT(7)
122 #define REG_CR_ADC_MONO			BIT(6)
123 #define REG_CR_ADC_LEFT_ONLY		BIT(5)
124 #define REG_CR_ADC_SB_OFFSET		4
125 #define REG_CR_ADC_LRSWAP		BIT(3)
126 #define REG_CR_ADC_IN_SEL_OFFSET	0
127 #define REG_CR_ADC_IN_SEL_MASK		(0x3 << REG_CR_ADC_IN_SEL_OFFSET)
128 
129 #define REG_CR_VIC_SB_SLEEP		BIT(1)
130 #define REG_CR_VIC_SB			BIT(0)
131 
132 #define REG_CCR_CRYSTAL_OFFSET		0
133 #define REG_CCR_CRYSTAL_MASK		(0xf << REG_CCR_CRYSTAL_OFFSET)
134 
135 #define REG_FCR_DAC_FREQ_OFFSET		0
136 #define REG_FCR_DAC_FREQ_MASK		(0xf << REG_FCR_DAC_FREQ_OFFSET)
137 
138 #define REG_FCR_ADC_FREQ_OFFSET		0
139 #define REG_FCR_ADC_FREQ_MASK		(0xf << REG_FCR_ADC_FREQ_OFFSET)
140 
141 #define REG_ICR_INT_FORM_OFFSET		6
142 #define REG_ICR_INT_FORM_MASK		(0x3 << REG_ICR_INT_FORM_OFFSET)
143 
144 #define REG_IMR_ALL_MASK		(0x7f)
145 #define REG_IMR_SCLR_MASK		BIT(6)
146 #define REG_IMR_JACK_MASK		BIT(5)
147 #define REG_IMR_SCMC_MASK		BIT(4)
148 #define REG_IMR_RUP_MASK		BIT(3)
149 #define REG_IMR_RDO_MASK		BIT(2)
150 #define REG_IMR_GUP_MASK		BIT(1)
151 #define REG_IMR_GDO_MASK		BIT(0)
152 
153 #define REG_IFR_ALL_MASK		(0x7f)
154 #define REG_IFR_SCLR			BIT(6)
155 #define REG_IFR_JACK			BIT(5)
156 #define REG_IFR_SCMC			BIT(4)
157 #define REG_IFR_RUP			BIT(3)
158 #define REG_IFR_RDO			BIT(2)
159 #define REG_IFR_GUP			BIT(1)
160 #define REG_IFR_GDO			BIT(0)
161 
162 #define REG_GCR_HPL_LRGO		BIT(7)
163 
164 #define REG_GCR_DACL_RLGOD		BIT(7)
165 
166 #define REG_GCR_GAIN_OFFSET		0
167 #define REG_GCR_GAIN_MAX		0x1f
168 
169 #define REG_GCR_MIC_GAIN_OFFSET		0
170 #define REG_GCR_MIC_GAIN_MAX		5
171 
172 #define REG_GCR_ADC_GAIN_OFFSET		0
173 #define REG_GCR_ADC_GAIN_MAX		23
174 
175 #define REG_AGC1_EN			BIT(7)
176 
177 /* codec private data */
178 struct jz_codec {
179 	struct device *dev;
180 	struct regmap *regmap;
181 	void __iomem *base;
182 	struct clk *clk;
183 };
184 
185 static int jz4770_codec_set_bias_level(struct snd_soc_component *codec,
186 				       enum snd_soc_bias_level level)
187 {
188 	struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
189 	struct regmap *regmap = jz_codec->regmap;
190 
191 	switch (level) {
192 	case SND_SOC_BIAS_PREPARE:
193 		/* Reset all interrupt flags. */
194 		regmap_write(regmap, JZ4770_CODEC_REG_IFR, REG_IFR_ALL_MASK);
195 
196 		regmap_clear_bits(regmap, JZ4770_CODEC_REG_CR_VIC,
197 				  REG_CR_VIC_SB);
198 		msleep(250);
199 		regmap_clear_bits(regmap, JZ4770_CODEC_REG_CR_VIC,
200 				  REG_CR_VIC_SB_SLEEP);
201 		msleep(400);
202 		break;
203 	case SND_SOC_BIAS_STANDBY:
204 		regmap_set_bits(regmap, JZ4770_CODEC_REG_CR_VIC,
205 				REG_CR_VIC_SB_SLEEP);
206 		regmap_set_bits(regmap, JZ4770_CODEC_REG_CR_VIC,
207 				REG_CR_VIC_SB);
208 		fallthrough;
209 	default:
210 		break;
211 	}
212 
213 	return 0;
214 }
215 
216 static int jz4770_codec_startup(struct snd_pcm_substream *substream,
217 				struct snd_soc_dai *dai)
218 {
219 	struct snd_soc_component *codec = dai->component;
220 	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(codec);
221 
222 	/*
223 	 * SYSCLK output from the codec to the AIC is required to keep the
224 	 * DMA transfer going during playback when all audible outputs have
225 	 * been disabled.
226 	 */
227 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
228 		snd_soc_dapm_force_enable_pin(dapm, "SYSCLK");
229 
230 	return 0;
231 }
232 
233 static void jz4770_codec_shutdown(struct snd_pcm_substream *substream,
234 				  struct snd_soc_dai *dai)
235 {
236 	struct snd_soc_component *codec = dai->component;
237 	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(codec);
238 
239 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
240 		snd_soc_dapm_disable_pin(dapm, "SYSCLK");
241 }
242 
243 
244 static int jz4770_codec_pcm_trigger(struct snd_pcm_substream *substream,
245 				    int cmd, struct snd_soc_dai *dai)
246 {
247 	struct snd_soc_component *codec = dai->component;
248 	int ret = 0;
249 
250 	switch (cmd) {
251 	case SNDRV_PCM_TRIGGER_START:
252 	case SNDRV_PCM_TRIGGER_RESUME:
253 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
254 		if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
255 			snd_soc_component_force_bias_level(codec,
256 							   SND_SOC_BIAS_ON);
257 		break;
258 	case SNDRV_PCM_TRIGGER_STOP:
259 	case SNDRV_PCM_TRIGGER_SUSPEND:
260 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
261 		/* do nothing */
262 		break;
263 	default:
264 		ret = -EINVAL;
265 	}
266 
267 	return ret;
268 }
269 
270 static int jz4770_codec_mute_stream(struct snd_soc_dai *dai, int mute, int direction)
271 {
272 	struct snd_soc_component *codec = dai->component;
273 	struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
274 	unsigned int gain_bit = mute ? REG_IFR_GDO : REG_IFR_GUP;
275 	unsigned int val;
276 	int change, err;
277 
278 	change = snd_soc_component_update_bits(codec, JZ4770_CODEC_REG_CR_DAC,
279 					       REG_CR_DAC_MUTE,
280 					       mute ? REG_CR_DAC_MUTE : 0);
281 	if (change == 1) {
282 		regmap_read(jz_codec->regmap, JZ4770_CODEC_REG_CR_DAC, &val);
283 
284 		if (val & BIT(REG_CR_DAC_SB_OFFSET))
285 			return 1;
286 
287 		err = regmap_read_poll_timeout(jz_codec->regmap,
288 					       JZ4770_CODEC_REG_IFR,
289 					       val, val & gain_bit,
290 					       1000, 1 * USEC_PER_SEC);
291 		if (err) {
292 			dev_err(jz_codec->dev,
293 				"Timeout while setting digital mute: %d", err);
294 			return err;
295 		}
296 
297 		/* clear GUP/GDO flag */
298 		regmap_set_bits(jz_codec->regmap, JZ4770_CODEC_REG_IFR,
299 				gain_bit);
300 	}
301 
302 	return 0;
303 }
304 
305 /* unit: 0.01dB */
306 static const DECLARE_TLV_DB_MINMAX_MUTE(dac_tlv, -3100, 0);
307 static const DECLARE_TLV_DB_SCALE(adc_tlv, 0, 100, 0);
308 static const DECLARE_TLV_DB_MINMAX(out_tlv, -2500, 600);
309 static const DECLARE_TLV_DB_SCALE(linein_tlv, -2500, 100, 0);
310 
311 /* Unconditional controls. */
312 static const struct snd_kcontrol_new jz4770_codec_snd_controls[] = {
313 	/* record gain control */
314 	SOC_DOUBLE_R_TLV("PCM Capture Volume",
315 			 JZ4770_CODEC_REG_GCR_ADCL, JZ4770_CODEC_REG_GCR_ADCR,
316 			 REG_GCR_ADC_GAIN_OFFSET, REG_GCR_ADC_GAIN_MAX,
317 			 0, adc_tlv),
318 
319 	SOC_DOUBLE_R_TLV("Line In Bypass Playback Volume",
320 			 JZ4770_CODEC_REG_GCR_LIBYL, JZ4770_CODEC_REG_GCR_LIBYR,
321 			 REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 1, linein_tlv),
322 };
323 
324 static const struct snd_kcontrol_new jz4770_codec_pcm_playback_controls[] = {
325 	{
326 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
327 		.name = "Volume",
328 		.info = snd_soc_info_volsw,
329 		.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ
330 			| SNDRV_CTL_ELEM_ACCESS_READWRITE,
331 		.tlv.p = dac_tlv,
332 		.get = snd_soc_dapm_get_volsw,
333 		.put = snd_soc_dapm_put_volsw,
334 		/*
335 		 * NOTE: DACR/DACL are inversed; the gain value written to DACR
336 		 * seems to affect the left channel, and the gain value written
337 		 * to DACL seems to affect the right channel.
338 		 */
339 		.private_value = SOC_DOUBLE_R_VALUE(JZ4770_CODEC_REG_GCR_DACR,
340 						    JZ4770_CODEC_REG_GCR_DACL,
341 						    REG_GCR_GAIN_OFFSET,
342 						    REG_GCR_GAIN_MAX, 1),
343 	},
344 };
345 
346 static const struct snd_kcontrol_new jz4770_codec_hp_playback_controls[] = {
347 	{
348 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
349 		.name = "Volume",
350 		.info = snd_soc_info_volsw,
351 		.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ
352 			| SNDRV_CTL_ELEM_ACCESS_READWRITE,
353 		.tlv.p = out_tlv,
354 		.get = snd_soc_dapm_get_volsw,
355 		.put = snd_soc_dapm_put_volsw,
356 		/* HPR/HPL inversed for the same reason as above */
357 		.private_value = SOC_DOUBLE_R_VALUE(JZ4770_CODEC_REG_GCR_HPR,
358 						    JZ4770_CODEC_REG_GCR_HPL,
359 						    REG_GCR_GAIN_OFFSET,
360 						    REG_GCR_GAIN_MAX, 1),
361 	},
362 };
363 
364 static int hpout_event(struct snd_soc_dapm_widget *w,
365 		       struct snd_kcontrol *kcontrol, int event)
366 {
367 	struct snd_soc_component *codec = snd_soc_dapm_to_component(w->dapm);
368 	struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
369 	unsigned int val;
370 	int err;
371 
372 	switch (event) {
373 	case SND_SOC_DAPM_PRE_PMU:
374 		/* unmute HP */
375 		regmap_clear_bits(jz_codec->regmap, JZ4770_CODEC_REG_CR_HP,
376 				  REG_CR_HP_MUTE);
377 		break;
378 
379 	case SND_SOC_DAPM_POST_PMU:
380 		/* wait for ramp-up complete (RUP) */
381 		err = regmap_read_poll_timeout(jz_codec->regmap,
382 					       JZ4770_CODEC_REG_IFR,
383 					       val, val & REG_IFR_RUP,
384 					       1000, 1 * USEC_PER_SEC);
385 		if (err) {
386 			dev_err(jz_codec->dev, "RUP timeout: %d", err);
387 			return err;
388 		}
389 
390 		/* clear RUP flag */
391 		regmap_set_bits(jz_codec->regmap, JZ4770_CODEC_REG_IFR,
392 				REG_IFR_RUP);
393 
394 		break;
395 
396 	case SND_SOC_DAPM_POST_PMD:
397 		/* mute HP */
398 		regmap_set_bits(jz_codec->regmap, JZ4770_CODEC_REG_CR_HP,
399 				REG_CR_HP_MUTE);
400 
401 		err = regmap_read_poll_timeout(jz_codec->regmap,
402 					       JZ4770_CODEC_REG_IFR,
403 					       val, val & REG_IFR_RDO,
404 					       1000, 1 * USEC_PER_SEC);
405 		if (err) {
406 			dev_err(jz_codec->dev, "RDO timeout: %d", err);
407 			return err;
408 		}
409 
410 		/* clear RDO flag */
411 		regmap_set_bits(jz_codec->regmap, JZ4770_CODEC_REG_IFR,
412 				REG_IFR_RDO);
413 
414 		break;
415 	}
416 
417 	return 0;
418 }
419 
420 static int adc_poweron_event(struct snd_soc_dapm_widget *w,
421 			     struct snd_kcontrol *kcontrol, int event)
422 {
423 	if (event == SND_SOC_DAPM_POST_PMU)
424 		msleep(1000);
425 
426 	return 0;
427 }
428 
429 static const char * const jz4770_codec_hp_texts[] = {
430 	"PCM", "Line In", "Mic 1", "Mic 2"
431 };
432 static const unsigned int jz4770_codec_hp_values[] = { 3, 2, 0, 1 };
433 static SOC_VALUE_ENUM_SINGLE_DECL(jz4770_codec_hp_enum,
434 				  JZ4770_CODEC_REG_CR_HP,
435 				  REG_CR_HP_SEL_OFFSET,
436 				  REG_CR_HP_SEL_MASK,
437 				  jz4770_codec_hp_texts,
438 				  jz4770_codec_hp_values);
439 static const struct snd_kcontrol_new jz4770_codec_hp_source =
440 			SOC_DAPM_ENUM("Route", jz4770_codec_hp_enum);
441 
442 static SOC_VALUE_ENUM_SINGLE_DECL(jz4770_codec_lo_enum,
443 				  JZ4770_CODEC_REG_CR_LO,
444 				  REG_CR_LO_SEL_OFFSET,
445 				  REG_CR_LO_SEL_MASK,
446 				  jz4770_codec_hp_texts,
447 				  jz4770_codec_hp_values);
448 static const struct snd_kcontrol_new jz4770_codec_lo_source =
449 			SOC_DAPM_ENUM("Route", jz4770_codec_lo_enum);
450 
451 static const char * const jz4770_codec_cap_texts[] = {
452 	"Line In", "Mic 1", "Mic 2"
453 };
454 static const unsigned int jz4770_codec_cap_values[] = { 2, 0, 1 };
455 static SOC_VALUE_ENUM_SINGLE_DECL(jz4770_codec_cap_enum,
456 				  JZ4770_CODEC_REG_CR_ADC,
457 				  REG_CR_ADC_IN_SEL_OFFSET,
458 				  REG_CR_ADC_IN_SEL_MASK,
459 				  jz4770_codec_cap_texts,
460 				  jz4770_codec_cap_values);
461 static const struct snd_kcontrol_new jz4770_codec_cap_source =
462 			SOC_DAPM_ENUM("Route", jz4770_codec_cap_enum);
463 
464 static const struct snd_kcontrol_new jz4770_codec_mic_controls[] = {
465 	SOC_DAPM_SINGLE("Stereo Capture Switch", JZ4770_CODEC_REG_CR_MIC,
466 			REG_CR_MIC_STEREO_OFFSET, 1, 0),
467 };
468 
469 static const struct snd_soc_dapm_widget jz4770_codec_dapm_widgets[] = {
470 	SND_SOC_DAPM_PGA_E("HP Out", JZ4770_CODEC_REG_CR_HP,
471 			   REG_CR_HP_SB_OFFSET, 1, NULL, 0, hpout_event,
472 			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
473 			   SND_SOC_DAPM_POST_PMD),
474 
475 	SND_SOC_DAPM_PGA("Line Out", JZ4770_CODEC_REG_CR_LO,
476 			 REG_CR_LO_SB_OFFSET, 1, NULL, 0),
477 
478 	SND_SOC_DAPM_PGA("Line Out Switch 2", JZ4770_CODEC_REG_CR_LO,
479 			 REG_CR_LO_MUTE_OFFSET, 1, NULL, 0),
480 
481 	SND_SOC_DAPM_PGA("Line In", JZ4770_CODEC_REG_CR_LI,
482 			 REG_CR_LI_SB_OFFSET, 1, NULL, 0),
483 
484 	SND_SOC_DAPM_MUX("Headphones Source", SND_SOC_NOPM, 0, 0,
485 			 &jz4770_codec_hp_source),
486 	SND_SOC_DAPM_MUX("Capture Source", SND_SOC_NOPM, 0, 0,
487 			 &jz4770_codec_cap_source),
488 	SND_SOC_DAPM_MUX("Line Out Source", SND_SOC_NOPM, 0, 0,
489 			 &jz4770_codec_lo_source),
490 
491 	SND_SOC_DAPM_PGA("Mic 1", JZ4770_CODEC_REG_CR_MIC,
492 			 REG_CR_MIC_SB_MIC1_OFFSET, 1, NULL, 0),
493 	SND_SOC_DAPM_PGA("Mic 2", JZ4770_CODEC_REG_CR_MIC,
494 			 REG_CR_MIC_SB_MIC2_OFFSET, 1, NULL, 0),
495 
496 	SND_SOC_DAPM_PGA("Mic Diff", JZ4770_CODEC_REG_CR_MIC,
497 			 REG_CR_MIC_IDIFF_OFFSET, 0, NULL, 0),
498 
499 	SND_SOC_DAPM_MIXER("Mic", SND_SOC_NOPM, 0, 0,
500 			   jz4770_codec_mic_controls,
501 			   ARRAY_SIZE(jz4770_codec_mic_controls)),
502 
503 	SND_SOC_DAPM_PGA("Line In Bypass", JZ4770_CODEC_REG_CR_LI,
504 			 REG_CR_LI_LIBY_OFFSET, 1, NULL, 0),
505 
506 	SND_SOC_DAPM_ADC_E("ADC", "HiFi Capture", JZ4770_CODEC_REG_CR_ADC,
507 			   REG_CR_ADC_SB_OFFSET, 1, adc_poweron_event,
508 			   SND_SOC_DAPM_POST_PMU),
509 	SND_SOC_DAPM_DAC("DAC", "HiFi Playback", JZ4770_CODEC_REG_CR_DAC,
510 			 REG_CR_DAC_SB_OFFSET, 1),
511 
512 	SND_SOC_DAPM_MIXER("PCM Playback", SND_SOC_NOPM, 0, 0,
513 			   jz4770_codec_pcm_playback_controls,
514 			   ARRAY_SIZE(jz4770_codec_pcm_playback_controls)),
515 	SND_SOC_DAPM_MIXER("Headphones Playback", SND_SOC_NOPM, 0, 0,
516 			   jz4770_codec_hp_playback_controls,
517 			   ARRAY_SIZE(jz4770_codec_hp_playback_controls)),
518 
519 	SND_SOC_DAPM_SUPPLY("MICBIAS", JZ4770_CODEC_REG_CR_MIC,
520 			    REG_CR_MIC_BIAS_SB_OFFSET, 1, NULL, 0),
521 
522 	SND_SOC_DAPM_SUPPLY("Cap-less", JZ4770_CODEC_REG_CR_HP,
523 			    REG_CR_HP_SB_HPCM_OFFSET, 1, NULL, 0),
524 
525 	SND_SOC_DAPM_INPUT("MIC1P"),
526 	SND_SOC_DAPM_INPUT("MIC1N"),
527 	SND_SOC_DAPM_INPUT("MIC2P"),
528 	SND_SOC_DAPM_INPUT("MIC2N"),
529 
530 	SND_SOC_DAPM_OUTPUT("LOUT"),
531 	SND_SOC_DAPM_OUTPUT("ROUT"),
532 
533 	SND_SOC_DAPM_OUTPUT("LHPOUT"),
534 	SND_SOC_DAPM_OUTPUT("RHPOUT"),
535 
536 	SND_SOC_DAPM_INPUT("LLINEIN"),
537 	SND_SOC_DAPM_INPUT("RLINEIN"),
538 
539 	SND_SOC_DAPM_OUTPUT("SYSCLK"),
540 };
541 
542 /* Unconditional routes. */
543 static const struct snd_soc_dapm_route jz4770_codec_dapm_routes[] = {
544 	{ "Mic 1", NULL, "MIC1P" },
545 	{ "Mic Diff", NULL, "MIC1N" },
546 	{ "Mic 1", NULL, "Mic Diff" },
547 	{ "Mic 2", NULL, "MIC2P" },
548 	{ "Mic Diff", NULL, "MIC2N" },
549 	{ "Mic 2", NULL, "Mic Diff" },
550 
551 	{ "Line In", NULL, "LLINEIN" },
552 	{ "Line In", NULL, "RLINEIN" },
553 
554 	{ "Mic", "Stereo Capture Switch", "Mic 1" },
555 	{ "Mic", "Stereo Capture Switch", "Mic 2" },
556 	{ "Headphones Source", "Mic 1", "Mic" },
557 	{ "Headphones Source", "Mic 2", "Mic" },
558 	{ "Capture Source", "Mic 1", "Mic" },
559 	{ "Capture Source", "Mic 2", "Mic" },
560 
561 	{ "Headphones Source", "Mic 1", "Mic 1" },
562 	{ "Headphones Source", "Mic 2", "Mic 2" },
563 	{ "Headphones Source", "Line In", "Line In Bypass" },
564 	{ "Headphones Source", "PCM", "Headphones Playback" },
565 	{ "HP Out", NULL, "Headphones Source" },
566 
567 	{ "Capture Source", "Line In", "Line In" },
568 	{ "Capture Source", "Mic 1", "Mic 1" },
569 	{ "Capture Source", "Mic 2", "Mic 2" },
570 	{ "ADC", NULL, "Capture Source" },
571 
572 	{ "Line In Bypass", NULL, "Line In" },
573 	{ "Line Out Source", "Line In", "Line In Bypass" },
574 	{ "Line Out Source", "PCM", "PCM Playback" },
575 
576 	{ "LHPOUT", NULL, "HP Out"},
577 	{ "RHPOUT", NULL, "HP Out"},
578 
579 	{ "Line Out", NULL, "Line Out Source" },
580 	{ "Line Out Switch 2", NULL, "Line Out" },
581 
582 	{ "LOUT", NULL, "Line Out Switch 2"},
583 	{ "ROUT", NULL, "Line Out Switch 2"},
584 
585 	{ "PCM Playback", "Volume", "DAC" },
586 	{ "Headphones Playback", "Volume", "PCM Playback" },
587 
588 	{ "SYSCLK", NULL, "DAC" },
589 };
590 
591 static void jz4770_codec_codec_init_regs(struct snd_soc_component *codec)
592 {
593 	struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
594 	struct regmap *regmap = jz_codec->regmap;
595 
596 	/* Collect updates for later sending. */
597 	regcache_cache_only(regmap, true);
598 
599 	/* default HP output to PCM */
600 	regmap_set_bits(regmap, JZ4770_CODEC_REG_CR_HP, REG_CR_HP_SEL_MASK);
601 
602 	/* default line output to PCM */
603 	regmap_set_bits(regmap, JZ4770_CODEC_REG_CR_LO, REG_CR_LO_SEL_MASK);
604 
605 	/* Disable stereo mic */
606 	regmap_clear_bits(regmap, JZ4770_CODEC_REG_CR_MIC,
607 			  BIT(REG_CR_MIC_STEREO_OFFSET));
608 
609 	/* Set mic 1 as default source for ADC */
610 	regmap_clear_bits(regmap, JZ4770_CODEC_REG_CR_ADC,
611 			  REG_CR_ADC_IN_SEL_MASK);
612 
613 	/* ADC/DAC: serial + i2s */
614 	regmap_set_bits(regmap, JZ4770_CODEC_REG_AICR_ADC,
615 			REG_AICR_ADC_SERIAL | REG_AICR_ADC_I2S);
616 	regmap_set_bits(regmap, JZ4770_CODEC_REG_AICR_DAC,
617 			REG_AICR_DAC_SERIAL | REG_AICR_DAC_I2S);
618 
619 	/* The generated IRQ is a high level */
620 	regmap_clear_bits(regmap, JZ4770_CODEC_REG_ICR, REG_ICR_INT_FORM_MASK);
621 	regmap_update_bits(regmap, JZ4770_CODEC_REG_IMR, REG_IMR_ALL_MASK,
622 			   REG_IMR_JACK_MASK | REG_IMR_RUP_MASK |
623 			   REG_IMR_RDO_MASK | REG_IMR_GUP_MASK |
624 			   REG_IMR_GDO_MASK);
625 
626 	/* 12M oscillator */
627 	regmap_clear_bits(regmap, JZ4770_CODEC_REG_CCR, REG_CCR_CRYSTAL_MASK);
628 
629 	/* 0: 16ohm/220uF, 1: 10kohm/1uF */
630 	regmap_clear_bits(regmap, JZ4770_CODEC_REG_CR_HP, REG_CR_HP_LOAD);
631 
632 	/* disable automatic gain */
633 	regmap_clear_bits(regmap, JZ4770_CODEC_REG_AGC1, REG_AGC1_EN);
634 
635 	/* Disable DAC lrswap */
636 	regmap_set_bits(regmap, JZ4770_CODEC_REG_CR_DAC, REG_CR_DAC_LRSWAP);
637 
638 	/* Independent L/R DAC gain control */
639 	regmap_clear_bits(regmap, JZ4770_CODEC_REG_GCR_DACL,
640 			  REG_GCR_DACL_RLGOD);
641 
642 	/* Disable ADC lrswap */
643 	regmap_set_bits(regmap, JZ4770_CODEC_REG_CR_ADC, REG_CR_ADC_LRSWAP);
644 
645 	/* default to cap-less mode(0) */
646 	regmap_clear_bits(regmap, JZ4770_CODEC_REG_CR_HP,
647 			  BIT(REG_CR_HP_SB_HPCM_OFFSET));
648 
649 	/* Send collected updates. */
650 	regcache_cache_only(regmap, false);
651 	regcache_sync(regmap);
652 }
653 
654 static int jz4770_codec_codec_probe(struct snd_soc_component *codec)
655 {
656 	struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
657 
658 	clk_prepare_enable(jz_codec->clk);
659 
660 	jz4770_codec_codec_init_regs(codec);
661 
662 	return 0;
663 }
664 
665 static void jz4770_codec_codec_remove(struct snd_soc_component *codec)
666 {
667 	struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
668 
669 	clk_disable_unprepare(jz_codec->clk);
670 }
671 
672 static const struct snd_soc_component_driver jz4770_codec_soc_codec_dev = {
673 	.probe			= jz4770_codec_codec_probe,
674 	.remove			= jz4770_codec_codec_remove,
675 	.set_bias_level		= jz4770_codec_set_bias_level,
676 	.controls		= jz4770_codec_snd_controls,
677 	.num_controls		= ARRAY_SIZE(jz4770_codec_snd_controls),
678 	.dapm_widgets		= jz4770_codec_dapm_widgets,
679 	.num_dapm_widgets	= ARRAY_SIZE(jz4770_codec_dapm_widgets),
680 	.dapm_routes		= jz4770_codec_dapm_routes,
681 	.num_dapm_routes	= ARRAY_SIZE(jz4770_codec_dapm_routes),
682 	.suspend_bias_off	= 1,
683 	.use_pmdown_time	= 1,
684 };
685 
686 static const unsigned int jz4770_codec_sample_rates[] = {
687 	96000, 48000, 44100, 32000,
688 	24000, 22050, 16000, 12000,
689 	11025, 9600, 8000,
690 };
691 
692 static int jz4770_codec_hw_params(struct snd_pcm_substream *substream,
693 				  struct snd_pcm_hw_params *params,
694 				  struct snd_soc_dai *dai)
695 {
696 	struct jz_codec *codec = snd_soc_component_get_drvdata(dai->component);
697 	unsigned int rate, bit_width;
698 
699 	switch (params_format(params)) {
700 	case SNDRV_PCM_FORMAT_S16_LE:
701 		bit_width = 0;
702 		break;
703 	case SNDRV_PCM_FORMAT_S18_3LE:
704 		bit_width = 1;
705 		break;
706 	case SNDRV_PCM_FORMAT_S20_3LE:
707 		bit_width = 2;
708 		break;
709 	case SNDRV_PCM_FORMAT_S24_3LE:
710 		bit_width = 3;
711 		break;
712 	default:
713 		return -EINVAL;
714 	}
715 
716 	for (rate = 0; rate < ARRAY_SIZE(jz4770_codec_sample_rates); rate++) {
717 		if (jz4770_codec_sample_rates[rate] == params_rate(params))
718 			break;
719 	}
720 
721 	if (rate == ARRAY_SIZE(jz4770_codec_sample_rates))
722 		return -EINVAL;
723 
724 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
725 		regmap_update_bits(codec->regmap, JZ4770_CODEC_REG_AICR_DAC,
726 				   REG_AICR_DAC_ADWL_MASK,
727 				   bit_width << REG_AICR_DAC_ADWL_OFFSET);
728 		regmap_update_bits(codec->regmap, JZ4770_CODEC_REG_FCR_DAC,
729 				   REG_FCR_DAC_FREQ_MASK,
730 				   rate << REG_FCR_DAC_FREQ_OFFSET);
731 	} else {
732 		regmap_update_bits(codec->regmap, JZ4770_CODEC_REG_AICR_ADC,
733 				   REG_AICR_ADC_ADWL_MASK,
734 				   bit_width << REG_AICR_ADC_ADWL_OFFSET);
735 		regmap_update_bits(codec->regmap, JZ4770_CODEC_REG_FCR_ADC,
736 				   REG_FCR_ADC_FREQ_MASK,
737 				   rate << REG_FCR_ADC_FREQ_OFFSET);
738 	}
739 
740 	return 0;
741 }
742 
743 static const struct snd_soc_dai_ops jz4770_codec_dai_ops = {
744 	.startup	= jz4770_codec_startup,
745 	.shutdown	= jz4770_codec_shutdown,
746 	.hw_params	= jz4770_codec_hw_params,
747 	.trigger	= jz4770_codec_pcm_trigger,
748 	.mute_stream	= jz4770_codec_mute_stream,
749 	.no_capture_mute = 1,
750 };
751 
752 #define JZ_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE  | \
753 			  SNDRV_PCM_FMTBIT_S18_3LE | \
754 			  SNDRV_PCM_FMTBIT_S20_3LE | \
755 			  SNDRV_PCM_FMTBIT_S24_3LE)
756 
757 static struct snd_soc_dai_driver jz4770_codec_dai = {
758 	.name = "jz4770-hifi",
759 	.playback = {
760 		.stream_name = "Playback",
761 		.channels_min = 2,
762 		.channels_max = 2,
763 		.rates = SNDRV_PCM_RATE_8000_96000,
764 		.formats = JZ_CODEC_FORMATS,
765 	},
766 	.capture = {
767 		.stream_name = "Capture",
768 		.channels_min = 2,
769 		.channels_max = 2,
770 		.rates = SNDRV_PCM_RATE_8000_96000,
771 		.formats = JZ_CODEC_FORMATS,
772 	},
773 	.ops = &jz4770_codec_dai_ops,
774 };
775 
776 static bool jz4770_codec_volatile(struct device *dev, unsigned int reg)
777 {
778 	return reg == JZ4770_CODEC_REG_SR || reg == JZ4770_CODEC_REG_IFR;
779 }
780 
781 static bool jz4770_codec_readable(struct device *dev, unsigned int reg)
782 {
783 	switch (reg) {
784 	case JZ4770_CODEC_REG_MISSING_REG1:
785 	case JZ4770_CODEC_REG_MISSING_REG2:
786 		return false;
787 	default:
788 		return true;
789 	}
790 }
791 
792 static bool jz4770_codec_writeable(struct device *dev, unsigned int reg)
793 {
794 	switch (reg) {
795 	case JZ4770_CODEC_REG_SR:
796 	case JZ4770_CODEC_REG_MISSING_REG1:
797 	case JZ4770_CODEC_REG_MISSING_REG2:
798 		return false;
799 	default:
800 		return true;
801 	}
802 }
803 
804 static int jz4770_codec_io_wait(struct jz_codec *codec)
805 {
806 	u32 reg;
807 
808 	return readl_poll_timeout(codec->base + ICDC_RGADW_OFFSET, reg,
809 				  !(reg & ICDC_RGADW_RGWR),
810 				  1000, 1 * USEC_PER_SEC);
811 }
812 
813 static int jz4770_codec_reg_read(void *context, unsigned int reg,
814 				 unsigned int *val)
815 {
816 	struct jz_codec *codec = context;
817 	unsigned int i;
818 	u32 tmp;
819 	int ret;
820 
821 	ret = jz4770_codec_io_wait(codec);
822 	if (ret)
823 		return ret;
824 
825 	tmp = readl(codec->base + ICDC_RGADW_OFFSET);
826 	tmp = (tmp & ~ICDC_RGADW_RGADDR_MASK)
827 	    | (reg << ICDC_RGADW_RGADDR_OFFSET);
828 	writel(tmp, codec->base + ICDC_RGADW_OFFSET);
829 
830 	/* wait 6+ cycles */
831 	for (i = 0; i < 6; i++)
832 		*val = readl(codec->base + ICDC_RGDATA_OFFSET) &
833 			ICDC_RGDATA_RGDOUT_MASK;
834 
835 	return 0;
836 }
837 
838 static int jz4770_codec_reg_write(void *context, unsigned int reg,
839 				  unsigned int val)
840 {
841 	struct jz_codec *codec = context;
842 	int ret;
843 
844 	ret = jz4770_codec_io_wait(codec);
845 	if (ret)
846 		return ret;
847 
848 	writel(ICDC_RGADW_RGWR | (reg << ICDC_RGADW_RGADDR_OFFSET) | val,
849 	       codec->base + ICDC_RGADW_OFFSET);
850 
851 	ret = jz4770_codec_io_wait(codec);
852 	if (ret)
853 		return ret;
854 
855 	return 0;
856 }
857 
858 static const u8 jz4770_codec_reg_defaults[] = {
859 	0x00, 0xC3, 0xC3, 0x90, 0x98, 0xFF, 0x90, 0xB1,
860 	0x11, 0x10, 0x00, 0x03, 0x00, 0x00, 0x40, 0x00,
861 	0xFF, 0x00, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00,
862 	0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x34,
863 	0x07, 0x44, 0x1F, 0x00
864 };
865 
866 static struct regmap_config jz4770_codec_regmap_config = {
867 	.reg_bits = 7,
868 	.val_bits = 8,
869 
870 	.max_register = JZ4770_CODEC_REG_AGC5,
871 	.volatile_reg = jz4770_codec_volatile,
872 	.readable_reg = jz4770_codec_readable,
873 	.writeable_reg = jz4770_codec_writeable,
874 
875 	.reg_read = jz4770_codec_reg_read,
876 	.reg_write = jz4770_codec_reg_write,
877 
878 	.reg_defaults_raw = jz4770_codec_reg_defaults,
879 	.num_reg_defaults_raw = ARRAY_SIZE(jz4770_codec_reg_defaults),
880 	.cache_type = REGCACHE_FLAT,
881 };
882 
883 static int jz4770_codec_probe(struct platform_device *pdev)
884 {
885 	struct device *dev = &pdev->dev;
886 	struct jz_codec *codec;
887 	int ret;
888 
889 	codec = devm_kzalloc(dev, sizeof(*codec), GFP_KERNEL);
890 	if (!codec)
891 		return -ENOMEM;
892 
893 	codec->dev = dev;
894 
895 	codec->base = devm_platform_ioremap_resource(pdev, 0);
896 	if (IS_ERR(codec->base)) {
897 		ret = PTR_ERR(codec->base);
898 		dev_err(dev, "Failed to ioremap mmio memory: %d\n", ret);
899 		return ret;
900 	}
901 
902 	codec->regmap = devm_regmap_init(dev, NULL, codec,
903 					&jz4770_codec_regmap_config);
904 	if (IS_ERR(codec->regmap))
905 		return PTR_ERR(codec->regmap);
906 
907 	codec->clk = devm_clk_get(dev, "aic");
908 	if (IS_ERR(codec->clk))
909 		return PTR_ERR(codec->clk);
910 
911 	platform_set_drvdata(pdev, codec);
912 
913 	ret = devm_snd_soc_register_component(dev, &jz4770_codec_soc_codec_dev,
914 					      &jz4770_codec_dai, 1);
915 	if (ret) {
916 		dev_err(dev, "Failed to register codec: %d\n", ret);
917 		return ret;
918 	}
919 
920 	return 0;
921 }
922 
923 static const struct of_device_id jz4770_codec_of_matches[] = {
924 	{ .compatible = "ingenic,jz4770-codec", },
925 	{ /* sentinel */ }
926 };
927 MODULE_DEVICE_TABLE(of, jz4770_codec_of_matches);
928 
929 static struct platform_driver jz4770_codec_driver = {
930 	.probe			= jz4770_codec_probe,
931 	.driver			= {
932 		.name		= "jz4770-codec",
933 		.of_match_table = jz4770_codec_of_matches,
934 	},
935 };
936 module_platform_driver(jz4770_codec_driver);
937 
938 MODULE_DESCRIPTION("JZ4770 SoC internal codec driver");
939 MODULE_AUTHOR("Maarten ter Huurne <maarten@treewalker.org>");
940 MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>");
941 MODULE_LICENSE("GPL v2");
942