xref: /openbmc/linux/sound/soc/codecs/adau17x1.c (revision 6774def6)
1 /*
2  * Common code for ADAU1X61 and ADAU1X81 codecs
3  *
4  * Copyright 2011-2014 Analog Devices Inc.
5  * Author: Lars-Peter Clausen <lars@metafoo.de>
6  *
7  * Licensed under the GPL-2 or later.
8  */
9 
10 #include <linux/module.h>
11 #include <linux/init.h>
12 #include <linux/delay.h>
13 #include <linux/slab.h>
14 #include <sound/core.h>
15 #include <sound/pcm.h>
16 #include <sound/pcm_params.h>
17 #include <sound/soc.h>
18 #include <sound/tlv.h>
19 #include <linux/gcd.h>
20 #include <linux/i2c.h>
21 #include <linux/spi/spi.h>
22 #include <linux/regmap.h>
23 
24 #include "sigmadsp.h"
25 #include "adau17x1.h"
26 
27 static const char * const adau17x1_capture_mixer_boost_text[] = {
28 	"Normal operation", "Boost Level 1", "Boost Level 2", "Boost Level 3",
29 };
30 
31 static SOC_ENUM_SINGLE_DECL(adau17x1_capture_boost_enum,
32 	ADAU17X1_REC_POWER_MGMT, 5, adau17x1_capture_mixer_boost_text);
33 
34 static const char * const adau17x1_mic_bias_mode_text[] = {
35 	"Normal operation", "High performance",
36 };
37 
38 static SOC_ENUM_SINGLE_DECL(adau17x1_mic_bias_mode_enum,
39 	ADAU17X1_MICBIAS, 3, adau17x1_mic_bias_mode_text);
40 
41 static const DECLARE_TLV_DB_MINMAX(adau17x1_digital_tlv, -9563, 0);
42 
43 static const struct snd_kcontrol_new adau17x1_controls[] = {
44 	SOC_DOUBLE_R_TLV("Digital Capture Volume",
45 		ADAU17X1_LEFT_INPUT_DIGITAL_VOL,
46 		ADAU17X1_RIGHT_INPUT_DIGITAL_VOL,
47 		0, 0xff, 1, adau17x1_digital_tlv),
48 	SOC_DOUBLE_R_TLV("Digital Playback Volume", ADAU17X1_DAC_CONTROL1,
49 		ADAU17X1_DAC_CONTROL2, 0, 0xff, 1, adau17x1_digital_tlv),
50 
51 	SOC_SINGLE("ADC High Pass Filter Switch", ADAU17X1_ADC_CONTROL,
52 		5, 1, 0),
53 	SOC_SINGLE("Playback De-emphasis Switch", ADAU17X1_DAC_CONTROL0,
54 		2, 1, 0),
55 
56 	SOC_ENUM("Capture Boost", adau17x1_capture_boost_enum),
57 
58 	SOC_ENUM("Mic Bias Mode", adau17x1_mic_bias_mode_enum),
59 };
60 
61 static int adau17x1_pll_event(struct snd_soc_dapm_widget *w,
62 	struct snd_kcontrol *kcontrol, int event)
63 {
64 	struct adau *adau = snd_soc_codec_get_drvdata(w->codec);
65 	int ret;
66 
67 	if (SND_SOC_DAPM_EVENT_ON(event)) {
68 		adau->pll_regs[5] = 1;
69 	} else {
70 		adau->pll_regs[5] = 0;
71 		/* Bypass the PLL when disabled, otherwise registers will become
72 		 * inaccessible. */
73 		regmap_update_bits(adau->regmap, ADAU17X1_CLOCK_CONTROL,
74 			ADAU17X1_CLOCK_CONTROL_CORECLK_SRC_PLL, 0);
75 	}
76 
77 	/* The PLL register is 6 bytes long and can only be written at once. */
78 	ret = regmap_raw_write(adau->regmap, ADAU17X1_PLL_CONTROL,
79 			adau->pll_regs, ARRAY_SIZE(adau->pll_regs));
80 
81 	if (SND_SOC_DAPM_EVENT_ON(event)) {
82 		mdelay(5);
83 		regmap_update_bits(adau->regmap, ADAU17X1_CLOCK_CONTROL,
84 			ADAU17X1_CLOCK_CONTROL_CORECLK_SRC_PLL,
85 			ADAU17X1_CLOCK_CONTROL_CORECLK_SRC_PLL);
86 	}
87 
88 	return 0;
89 }
90 
91 static const char * const adau17x1_mono_stereo_text[] = {
92 	"Stereo",
93 	"Mono Left Channel (L+R)",
94 	"Mono Right Channel (L+R)",
95 	"Mono (L+R)",
96 };
97 
98 static SOC_ENUM_SINGLE_DECL(adau17x1_dac_mode_enum,
99 	ADAU17X1_DAC_CONTROL0, 6, adau17x1_mono_stereo_text);
100 
101 static const struct snd_kcontrol_new adau17x1_dac_mode_mux =
102 	SOC_DAPM_ENUM("DAC Mono-Stereo-Mode", adau17x1_dac_mode_enum);
103 
104 static const struct snd_soc_dapm_widget adau17x1_dapm_widgets[] = {
105 	SND_SOC_DAPM_SUPPLY_S("PLL", 3, SND_SOC_NOPM, 0, 0, adau17x1_pll_event,
106 		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
107 
108 	SND_SOC_DAPM_SUPPLY("AIFCLK", SND_SOC_NOPM, 0, 0, NULL, 0),
109 
110 	SND_SOC_DAPM_SUPPLY("MICBIAS", ADAU17X1_MICBIAS, 0, 0, NULL, 0),
111 
112 	SND_SOC_DAPM_SUPPLY("Left Playback Enable", ADAU17X1_PLAY_POWER_MGMT,
113 		0, 0, NULL, 0),
114 	SND_SOC_DAPM_SUPPLY("Right Playback Enable", ADAU17X1_PLAY_POWER_MGMT,
115 		1, 0, NULL, 0),
116 
117 	SND_SOC_DAPM_MUX("Left DAC Mode Mux", SND_SOC_NOPM, 0, 0,
118 		&adau17x1_dac_mode_mux),
119 	SND_SOC_DAPM_MUX("Right DAC Mode Mux", SND_SOC_NOPM, 0, 0,
120 		&adau17x1_dac_mode_mux),
121 
122 	SND_SOC_DAPM_ADC("Left Decimator", NULL, ADAU17X1_ADC_CONTROL, 0, 0),
123 	SND_SOC_DAPM_ADC("Right Decimator", NULL, ADAU17X1_ADC_CONTROL, 1, 0),
124 	SND_SOC_DAPM_DAC("Left DAC", NULL, ADAU17X1_DAC_CONTROL0, 0, 0),
125 	SND_SOC_DAPM_DAC("Right DAC", NULL, ADAU17X1_DAC_CONTROL0, 1, 0),
126 };
127 
128 static const struct snd_soc_dapm_route adau17x1_dapm_routes[] = {
129 	{ "Left Decimator", NULL, "SYSCLK" },
130 	{ "Right Decimator", NULL, "SYSCLK" },
131 	{ "Left DAC", NULL, "SYSCLK" },
132 	{ "Right DAC", NULL, "SYSCLK" },
133 	{ "Capture", NULL, "SYSCLK" },
134 	{ "Playback", NULL, "SYSCLK" },
135 
136 	{ "Left DAC", NULL, "Left DAC Mode Mux" },
137 	{ "Right DAC", NULL, "Right DAC Mode Mux" },
138 
139 	{ "Capture", NULL, "AIFCLK" },
140 	{ "Playback", NULL, "AIFCLK" },
141 };
142 
143 static const struct snd_soc_dapm_route adau17x1_dapm_pll_route = {
144 	"SYSCLK", NULL, "PLL",
145 };
146 
147 /*
148  * The MUX register for the Capture and Playback MUXs selects either DSP as
149  * source/destination or one of the TDM slots. The TDM slot is selected via
150  * snd_soc_dai_set_tdm_slot(), so we only expose whether to go to the DSP or
151  * directly to the DAI interface with this control.
152  */
153 static int adau17x1_dsp_mux_enum_put(struct snd_kcontrol *kcontrol,
154 	struct snd_ctl_elem_value *ucontrol)
155 {
156 	struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
157 	struct adau *adau = snd_soc_codec_get_drvdata(codec);
158 	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
159 	struct snd_soc_dapm_update update;
160 	unsigned int stream = e->shift_l;
161 	unsigned int val, change;
162 	int reg;
163 
164 	if (ucontrol->value.enumerated.item[0] >= e->items)
165 		return -EINVAL;
166 
167 	switch (ucontrol->value.enumerated.item[0]) {
168 	case 0:
169 		val = 0;
170 		adau->dsp_bypass[stream] = false;
171 		break;
172 	default:
173 		val = (adau->tdm_slot[stream] * 2) + 1;
174 		adau->dsp_bypass[stream] = true;
175 		break;
176 	}
177 
178 	if (stream == SNDRV_PCM_STREAM_PLAYBACK)
179 		reg = ADAU17X1_SERIAL_INPUT_ROUTE;
180 	else
181 		reg = ADAU17X1_SERIAL_OUTPUT_ROUTE;
182 
183 	change = snd_soc_test_bits(codec, reg, 0xff, val);
184 	if (change) {
185 		update.kcontrol = kcontrol;
186 		update.mask = 0xff;
187 		update.reg = reg;
188 		update.val = val;
189 
190 		snd_soc_dapm_mux_update_power(&codec->dapm, kcontrol,
191 				ucontrol->value.enumerated.item[0], e, &update);
192 	}
193 
194 	return change;
195 }
196 
197 static int adau17x1_dsp_mux_enum_get(struct snd_kcontrol *kcontrol,
198 	struct snd_ctl_elem_value *ucontrol)
199 {
200 	struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
201 	struct adau *adau = snd_soc_codec_get_drvdata(codec);
202 	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
203 	unsigned int stream = e->shift_l;
204 	unsigned int reg, val;
205 	int ret;
206 
207 	if (stream == SNDRV_PCM_STREAM_PLAYBACK)
208 		reg = ADAU17X1_SERIAL_INPUT_ROUTE;
209 	else
210 		reg = ADAU17X1_SERIAL_OUTPUT_ROUTE;
211 
212 	ret = regmap_read(adau->regmap, reg, &val);
213 	if (ret)
214 		return ret;
215 
216 	if (val != 0)
217 		val = 1;
218 	ucontrol->value.enumerated.item[0] = val;
219 
220 	return 0;
221 }
222 
223 #define DECLARE_ADAU17X1_DSP_MUX_CTRL(_name, _label, _stream, _text) \
224 	const struct snd_kcontrol_new _name = \
225 		SOC_DAPM_ENUM_EXT(_label, (const struct soc_enum)\
226 			SOC_ENUM_SINGLE(SND_SOC_NOPM, _stream, \
227 				ARRAY_SIZE(_text), _text), \
228 			adau17x1_dsp_mux_enum_get, adau17x1_dsp_mux_enum_put)
229 
230 static const char * const adau17x1_dac_mux_text[] = {
231 	"DSP",
232 	"AIFIN",
233 };
234 
235 static const char * const adau17x1_capture_mux_text[] = {
236 	"DSP",
237 	"Decimator",
238 };
239 
240 static DECLARE_ADAU17X1_DSP_MUX_CTRL(adau17x1_dac_mux, "DAC Playback Mux",
241 	SNDRV_PCM_STREAM_PLAYBACK, adau17x1_dac_mux_text);
242 
243 static DECLARE_ADAU17X1_DSP_MUX_CTRL(adau17x1_capture_mux, "Capture Mux",
244 	SNDRV_PCM_STREAM_CAPTURE, adau17x1_capture_mux_text);
245 
246 static const struct snd_soc_dapm_widget adau17x1_dsp_dapm_widgets[] = {
247 	SND_SOC_DAPM_PGA("DSP", ADAU17X1_DSP_RUN, 0, 0, NULL, 0),
248 	SND_SOC_DAPM_SIGGEN("DSP Siggen"),
249 
250 	SND_SOC_DAPM_MUX("DAC Playback Mux", SND_SOC_NOPM, 0, 0,
251 		&adau17x1_dac_mux),
252 	SND_SOC_DAPM_MUX("Capture Mux", SND_SOC_NOPM, 0, 0,
253 		&adau17x1_capture_mux),
254 };
255 
256 static const struct snd_soc_dapm_route adau17x1_dsp_dapm_routes[] = {
257 	{ "DAC Playback Mux", "DSP", "DSP" },
258 	{ "DAC Playback Mux", "AIFIN", "Playback" },
259 
260 	{ "Left DAC Mode Mux", "Stereo", "DAC Playback Mux" },
261 	{ "Left DAC Mode Mux", "Mono (L+R)", "DAC Playback Mux" },
262 	{ "Left DAC Mode Mux", "Mono Left Channel (L+R)", "DAC Playback Mux" },
263 	{ "Right DAC Mode Mux", "Stereo", "DAC Playback Mux" },
264 	{ "Right DAC Mode Mux", "Mono (L+R)", "DAC Playback Mux" },
265 	{ "Right DAC Mode Mux", "Mono Right Channel (L+R)", "DAC Playback Mux" },
266 
267 	{ "Capture Mux", "DSP", "DSP" },
268 	{ "Capture Mux", "Decimator", "Left Decimator" },
269 	{ "Capture Mux", "Decimator", "Right Decimator" },
270 
271 	{ "Capture", NULL, "Capture Mux" },
272 
273 	{ "DSP", NULL, "DSP Siggen" },
274 
275 	{ "DSP", NULL, "Left Decimator" },
276 	{ "DSP", NULL, "Right Decimator" },
277 };
278 
279 static const struct snd_soc_dapm_route adau17x1_no_dsp_dapm_routes[] = {
280 	{ "Left DAC Mode Mux", "Stereo", "Playback" },
281 	{ "Left DAC Mode Mux", "Mono (L+R)", "Playback" },
282 	{ "Left DAC Mode Mux", "Mono Left Channel (L+R)", "Playback" },
283 	{ "Right DAC Mode Mux", "Stereo", "Playback" },
284 	{ "Right DAC Mode Mux", "Mono (L+R)", "Playback" },
285 	{ "Right DAC Mode Mux", "Mono Right Channel (L+R)", "Playback" },
286 	{ "Capture", NULL, "Left Decimator" },
287 	{ "Capture", NULL, "Right Decimator" },
288 };
289 
290 bool adau17x1_has_dsp(struct adau *adau)
291 {
292 	switch (adau->type) {
293 	case ADAU1761:
294 	case ADAU1381:
295 	case ADAU1781:
296 		return true;
297 	default:
298 		return false;
299 	}
300 }
301 EXPORT_SYMBOL_GPL(adau17x1_has_dsp);
302 
303 static int adau17x1_hw_params(struct snd_pcm_substream *substream,
304 	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
305 {
306 	struct snd_soc_codec *codec = dai->codec;
307 	struct adau *adau = snd_soc_codec_get_drvdata(codec);
308 	unsigned int val, div, dsp_div;
309 	unsigned int freq;
310 
311 	if (adau->clk_src == ADAU17X1_CLK_SRC_PLL)
312 		freq = adau->pll_freq;
313 	else
314 		freq = adau->sysclk;
315 
316 	if (freq % params_rate(params) != 0)
317 		return -EINVAL;
318 
319 	switch (freq / params_rate(params)) {
320 	case 1024: /* fs */
321 		div = 0;
322 		dsp_div = 1;
323 		break;
324 	case 6144: /* fs / 6 */
325 		div = 1;
326 		dsp_div = 6;
327 		break;
328 	case 4096: /* fs / 4 */
329 		div = 2;
330 		dsp_div = 5;
331 		break;
332 	case 3072: /* fs / 3 */
333 		div = 3;
334 		dsp_div = 4;
335 		break;
336 	case 2048: /* fs / 2 */
337 		div = 4;
338 		dsp_div = 3;
339 		break;
340 	case 1536: /* fs / 1.5 */
341 		div = 5;
342 		dsp_div = 2;
343 		break;
344 	case 512: /* fs / 0.5 */
345 		div = 6;
346 		dsp_div = 0;
347 		break;
348 	default:
349 		return -EINVAL;
350 	}
351 
352 	regmap_update_bits(adau->regmap, ADAU17X1_CONVERTER0,
353 		ADAU17X1_CONVERTER0_CONVSR_MASK, div);
354 	if (adau17x1_has_dsp(adau)) {
355 		regmap_write(adau->regmap, ADAU17X1_SERIAL_SAMPLING_RATE, div);
356 		regmap_write(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, dsp_div);
357 	}
358 
359 	if (adau->dai_fmt != SND_SOC_DAIFMT_RIGHT_J)
360 		return 0;
361 
362 	switch (params_width(params)) {
363 	case 16:
364 		val = ADAU17X1_SERIAL_PORT1_DELAY16;
365 		break;
366 	case 24:
367 		val = ADAU17X1_SERIAL_PORT1_DELAY8;
368 		break;
369 	case 32:
370 		val = ADAU17X1_SERIAL_PORT1_DELAY0;
371 		break;
372 	default:
373 		return -EINVAL;
374 	}
375 
376 	return regmap_update_bits(adau->regmap, ADAU17X1_SERIAL_PORT1,
377 			ADAU17X1_SERIAL_PORT1_DELAY_MASK, val);
378 }
379 
380 static int adau17x1_set_dai_pll(struct snd_soc_dai *dai, int pll_id,
381 	int source, unsigned int freq_in, unsigned int freq_out)
382 {
383 	struct snd_soc_codec *codec = dai->codec;
384 	struct adau *adau = snd_soc_codec_get_drvdata(codec);
385 	unsigned int r, n, m, i, j;
386 	unsigned int div;
387 	int ret;
388 
389 	if (freq_in < 8000000 || freq_in > 27000000)
390 		return -EINVAL;
391 
392 	if (!freq_out) {
393 		r = 0;
394 		n = 0;
395 		m = 0;
396 		div = 0;
397 	} else {
398 		if (freq_out % freq_in != 0) {
399 			div = DIV_ROUND_UP(freq_in, 13500000);
400 			freq_in /= div;
401 			r = freq_out / freq_in;
402 			i = freq_out % freq_in;
403 			j = gcd(i, freq_in);
404 			n = i / j;
405 			m = freq_in / j;
406 			div--;
407 		} else {
408 			r = freq_out / freq_in;
409 			n = 0;
410 			m = 0;
411 			div = 0;
412 		}
413 		if (n > 0xffff || m > 0xffff || div > 3 || r > 8 || r < 2)
414 			return -EINVAL;
415 	}
416 
417 	adau->pll_regs[0] = m >> 8;
418 	adau->pll_regs[1] = m & 0xff;
419 	adau->pll_regs[2] = n >> 8;
420 	adau->pll_regs[3] = n & 0xff;
421 	adau->pll_regs[4] = (r << 3) | (div << 1);
422 	if (m != 0)
423 		adau->pll_regs[4] |= 1; /* Fractional mode */
424 
425 	/* The PLL register is 6 bytes long and can only be written at once. */
426 	ret = regmap_raw_write(adau->regmap, ADAU17X1_PLL_CONTROL,
427 			adau->pll_regs, ARRAY_SIZE(adau->pll_regs));
428 	if (ret)
429 		return ret;
430 
431 	adau->pll_freq = freq_out;
432 
433 	return 0;
434 }
435 
436 static int adau17x1_set_dai_sysclk(struct snd_soc_dai *dai,
437 		int clk_id, unsigned int freq, int dir)
438 {
439 	struct adau *adau = snd_soc_codec_get_drvdata(dai->codec);
440 	struct snd_soc_dapm_context *dapm = &dai->codec->dapm;
441 
442 	switch (clk_id) {
443 	case ADAU17X1_CLK_SRC_MCLK:
444 	case ADAU17X1_CLK_SRC_PLL:
445 		break;
446 	default:
447 		return -EINVAL;
448 	}
449 
450 	adau->sysclk = freq;
451 
452 	if (adau->clk_src != clk_id) {
453 		if (clk_id == ADAU17X1_CLK_SRC_PLL) {
454 			snd_soc_dapm_add_routes(dapm,
455 				&adau17x1_dapm_pll_route, 1);
456 		} else {
457 			snd_soc_dapm_del_routes(dapm,
458 				&adau17x1_dapm_pll_route, 1);
459 		}
460 	}
461 
462 	adau->clk_src = clk_id;
463 
464 	return 0;
465 }
466 
467 static int adau17x1_set_dai_fmt(struct snd_soc_dai *dai,
468 		unsigned int fmt)
469 {
470 	struct adau *adau = snd_soc_codec_get_drvdata(dai->codec);
471 	unsigned int ctrl0, ctrl1;
472 	int lrclk_pol;
473 
474 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
475 	case SND_SOC_DAIFMT_CBM_CFM:
476 		ctrl0 = ADAU17X1_SERIAL_PORT0_MASTER;
477 		adau->master = true;
478 		break;
479 	case SND_SOC_DAIFMT_CBS_CFS:
480 		ctrl0 = 0;
481 		adau->master = false;
482 		break;
483 	default:
484 		return -EINVAL;
485 	}
486 
487 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
488 	case SND_SOC_DAIFMT_I2S:
489 		lrclk_pol = 0;
490 		ctrl1 = ADAU17X1_SERIAL_PORT1_DELAY1;
491 		break;
492 	case SND_SOC_DAIFMT_LEFT_J:
493 	case SND_SOC_DAIFMT_RIGHT_J:
494 		lrclk_pol = 1;
495 		ctrl1 = ADAU17X1_SERIAL_PORT1_DELAY0;
496 		break;
497 	case SND_SOC_DAIFMT_DSP_A:
498 		lrclk_pol = 1;
499 		ctrl0 |= ADAU17X1_SERIAL_PORT0_PULSE_MODE;
500 		ctrl1 = ADAU17X1_SERIAL_PORT1_DELAY1;
501 		break;
502 	case SND_SOC_DAIFMT_DSP_B:
503 		lrclk_pol = 1;
504 		ctrl0 |= ADAU17X1_SERIAL_PORT0_PULSE_MODE;
505 		ctrl1 = ADAU17X1_SERIAL_PORT1_DELAY0;
506 		break;
507 	default:
508 		return -EINVAL;
509 	}
510 
511 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
512 	case SND_SOC_DAIFMT_NB_NF:
513 		break;
514 	case SND_SOC_DAIFMT_IB_NF:
515 		ctrl0 |= ADAU17X1_SERIAL_PORT0_BCLK_POL;
516 		break;
517 	case SND_SOC_DAIFMT_NB_IF:
518 		lrclk_pol = !lrclk_pol;
519 		break;
520 	case SND_SOC_DAIFMT_IB_IF:
521 		ctrl0 |= ADAU17X1_SERIAL_PORT0_BCLK_POL;
522 		lrclk_pol = !lrclk_pol;
523 		break;
524 	default:
525 		return -EINVAL;
526 	}
527 
528 	if (lrclk_pol)
529 		ctrl0 |= ADAU17X1_SERIAL_PORT0_LRCLK_POL;
530 
531 	regmap_write(adau->regmap, ADAU17X1_SERIAL_PORT0, ctrl0);
532 	regmap_write(adau->regmap, ADAU17X1_SERIAL_PORT1, ctrl1);
533 
534 	adau->dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
535 
536 	return 0;
537 }
538 
539 static int adau17x1_set_dai_tdm_slot(struct snd_soc_dai *dai,
540 	unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
541 {
542 	struct adau *adau = snd_soc_codec_get_drvdata(dai->codec);
543 	unsigned int ser_ctrl0, ser_ctrl1;
544 	unsigned int conv_ctrl0, conv_ctrl1;
545 
546 	/* I2S mode */
547 	if (slots == 0) {
548 		slots = 2;
549 		rx_mask = 3;
550 		tx_mask = 3;
551 		slot_width = 32;
552 	}
553 
554 	switch (slots) {
555 	case 2:
556 		ser_ctrl0 = ADAU17X1_SERIAL_PORT0_STEREO;
557 		break;
558 	case 4:
559 		ser_ctrl0 = ADAU17X1_SERIAL_PORT0_TDM4;
560 		break;
561 	case 8:
562 		if (adau->type == ADAU1361)
563 			return -EINVAL;
564 
565 		ser_ctrl0 = ADAU17X1_SERIAL_PORT0_TDM8;
566 		break;
567 	default:
568 		return -EINVAL;
569 	}
570 
571 	switch (slot_width * slots) {
572 	case 32:
573 		if (adau->type == ADAU1761)
574 			return -EINVAL;
575 
576 		ser_ctrl1 = ADAU17X1_SERIAL_PORT1_BCLK32;
577 		break;
578 	case 64:
579 		ser_ctrl1 = ADAU17X1_SERIAL_PORT1_BCLK64;
580 		break;
581 	case 48:
582 		ser_ctrl1 = ADAU17X1_SERIAL_PORT1_BCLK48;
583 		break;
584 	case 128:
585 		ser_ctrl1 = ADAU17X1_SERIAL_PORT1_BCLK128;
586 		break;
587 	case 256:
588 		if (adau->type == ADAU1361)
589 			return -EINVAL;
590 
591 		ser_ctrl1 = ADAU17X1_SERIAL_PORT1_BCLK256;
592 		break;
593 	default:
594 		return -EINVAL;
595 	}
596 
597 	switch (rx_mask) {
598 	case 0x03:
599 		conv_ctrl1 = ADAU17X1_CONVERTER1_ADC_PAIR(1);
600 		adau->tdm_slot[SNDRV_PCM_STREAM_CAPTURE] = 0;
601 		break;
602 	case 0x0c:
603 		conv_ctrl1 = ADAU17X1_CONVERTER1_ADC_PAIR(2);
604 		adau->tdm_slot[SNDRV_PCM_STREAM_CAPTURE] = 1;
605 		break;
606 	case 0x30:
607 		conv_ctrl1 = ADAU17X1_CONVERTER1_ADC_PAIR(3);
608 		adau->tdm_slot[SNDRV_PCM_STREAM_CAPTURE] = 2;
609 		break;
610 	case 0xc0:
611 		conv_ctrl1 = ADAU17X1_CONVERTER1_ADC_PAIR(4);
612 		adau->tdm_slot[SNDRV_PCM_STREAM_CAPTURE] = 3;
613 		break;
614 	default:
615 		return -EINVAL;
616 	}
617 
618 	switch (tx_mask) {
619 	case 0x03:
620 		conv_ctrl0 = ADAU17X1_CONVERTER0_DAC_PAIR(1);
621 		adau->tdm_slot[SNDRV_PCM_STREAM_PLAYBACK] = 0;
622 		break;
623 	case 0x0c:
624 		conv_ctrl0 = ADAU17X1_CONVERTER0_DAC_PAIR(2);
625 		adau->tdm_slot[SNDRV_PCM_STREAM_PLAYBACK] = 1;
626 		break;
627 	case 0x30:
628 		conv_ctrl0 = ADAU17X1_CONVERTER0_DAC_PAIR(3);
629 		adau->tdm_slot[SNDRV_PCM_STREAM_PLAYBACK] = 2;
630 		break;
631 	case 0xc0:
632 		conv_ctrl0 = ADAU17X1_CONVERTER0_DAC_PAIR(4);
633 		adau->tdm_slot[SNDRV_PCM_STREAM_PLAYBACK] = 3;
634 		break;
635 	default:
636 		return -EINVAL;
637 	}
638 
639 	regmap_update_bits(adau->regmap, ADAU17X1_CONVERTER0,
640 		ADAU17X1_CONVERTER0_DAC_PAIR_MASK, conv_ctrl0);
641 	regmap_update_bits(adau->regmap, ADAU17X1_CONVERTER1,
642 		ADAU17X1_CONVERTER1_ADC_PAIR_MASK, conv_ctrl1);
643 	regmap_update_bits(adau->regmap, ADAU17X1_SERIAL_PORT0,
644 		ADAU17X1_SERIAL_PORT0_TDM_MASK, ser_ctrl0);
645 	regmap_update_bits(adau->regmap, ADAU17X1_SERIAL_PORT1,
646 		ADAU17X1_SERIAL_PORT1_BCLK_MASK, ser_ctrl1);
647 
648 	if (!adau17x1_has_dsp(adau))
649 		return 0;
650 
651 	if (adau->dsp_bypass[SNDRV_PCM_STREAM_PLAYBACK]) {
652 		regmap_write(adau->regmap, ADAU17X1_SERIAL_INPUT_ROUTE,
653 			(adau->tdm_slot[SNDRV_PCM_STREAM_PLAYBACK] * 2) + 1);
654 	}
655 
656 	if (adau->dsp_bypass[SNDRV_PCM_STREAM_CAPTURE]) {
657 		regmap_write(adau->regmap, ADAU17X1_SERIAL_OUTPUT_ROUTE,
658 			(adau->tdm_slot[SNDRV_PCM_STREAM_CAPTURE] * 2) + 1);
659 	}
660 
661 	return 0;
662 }
663 
664 const struct snd_soc_dai_ops adau17x1_dai_ops = {
665 	.hw_params	= adau17x1_hw_params,
666 	.set_sysclk	= adau17x1_set_dai_sysclk,
667 	.set_fmt	= adau17x1_set_dai_fmt,
668 	.set_pll	= adau17x1_set_dai_pll,
669 	.set_tdm_slot	= adau17x1_set_dai_tdm_slot,
670 };
671 EXPORT_SYMBOL_GPL(adau17x1_dai_ops);
672 
673 int adau17x1_set_micbias_voltage(struct snd_soc_codec *codec,
674 	enum adau17x1_micbias_voltage micbias)
675 {
676 	struct adau *adau = snd_soc_codec_get_drvdata(codec);
677 
678 	switch (micbias) {
679 	case ADAU17X1_MICBIAS_0_90_AVDD:
680 	case ADAU17X1_MICBIAS_0_65_AVDD:
681 		break;
682 	default:
683 		return -EINVAL;
684 	}
685 
686 	return regmap_write(adau->regmap, ADAU17X1_MICBIAS, micbias << 2);
687 }
688 EXPORT_SYMBOL_GPL(adau17x1_set_micbias_voltage);
689 
690 bool adau17x1_readable_register(struct device *dev, unsigned int reg)
691 {
692 	switch (reg) {
693 	case ADAU17X1_CLOCK_CONTROL:
694 	case ADAU17X1_PLL_CONTROL:
695 	case ADAU17X1_REC_POWER_MGMT:
696 	case ADAU17X1_MICBIAS:
697 	case ADAU17X1_SERIAL_PORT0:
698 	case ADAU17X1_SERIAL_PORT1:
699 	case ADAU17X1_CONVERTER0:
700 	case ADAU17X1_CONVERTER1:
701 	case ADAU17X1_LEFT_INPUT_DIGITAL_VOL:
702 	case ADAU17X1_RIGHT_INPUT_DIGITAL_VOL:
703 	case ADAU17X1_ADC_CONTROL:
704 	case ADAU17X1_PLAY_POWER_MGMT:
705 	case ADAU17X1_DAC_CONTROL0:
706 	case ADAU17X1_DAC_CONTROL1:
707 	case ADAU17X1_DAC_CONTROL2:
708 	case ADAU17X1_SERIAL_PORT_PAD:
709 	case ADAU17X1_CONTROL_PORT_PAD0:
710 	case ADAU17X1_CONTROL_PORT_PAD1:
711 	case ADAU17X1_DSP_SAMPLING_RATE:
712 	case ADAU17X1_SERIAL_INPUT_ROUTE:
713 	case ADAU17X1_SERIAL_OUTPUT_ROUTE:
714 	case ADAU17X1_DSP_ENABLE:
715 	case ADAU17X1_DSP_RUN:
716 	case ADAU17X1_SERIAL_SAMPLING_RATE:
717 		return true;
718 	default:
719 		break;
720 	}
721 	return false;
722 }
723 EXPORT_SYMBOL_GPL(adau17x1_readable_register);
724 
725 bool adau17x1_volatile_register(struct device *dev, unsigned int reg)
726 {
727 	/* SigmaDSP parameter and program memory */
728 	if (reg < 0x4000)
729 		return true;
730 
731 	switch (reg) {
732 	/* The PLL register is 6 bytes long */
733 	case ADAU17X1_PLL_CONTROL:
734 	case ADAU17X1_PLL_CONTROL + 1:
735 	case ADAU17X1_PLL_CONTROL + 2:
736 	case ADAU17X1_PLL_CONTROL + 3:
737 	case ADAU17X1_PLL_CONTROL + 4:
738 	case ADAU17X1_PLL_CONTROL + 5:
739 		return true;
740 	default:
741 		break;
742 	}
743 
744 	return false;
745 }
746 EXPORT_SYMBOL_GPL(adau17x1_volatile_register);
747 
748 int adau17x1_load_firmware(struct adau *adau, struct device *dev,
749 	const char *firmware)
750 {
751 	int ret;
752 	int dspsr;
753 
754 	ret = regmap_read(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, &dspsr);
755 	if (ret)
756 		return ret;
757 
758 	regmap_write(adau->regmap, ADAU17X1_DSP_ENABLE, 1);
759 	regmap_write(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, 0xf);
760 
761 	ret = process_sigma_firmware_regmap(dev, adau->regmap, firmware);
762 	if (ret) {
763 		regmap_write(adau->regmap, ADAU17X1_DSP_ENABLE, 0);
764 		return ret;
765 	}
766 	regmap_write(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, dspsr);
767 
768 	return 0;
769 }
770 EXPORT_SYMBOL_GPL(adau17x1_load_firmware);
771 
772 int adau17x1_add_widgets(struct snd_soc_codec *codec)
773 {
774 	struct adau *adau = snd_soc_codec_get_drvdata(codec);
775 	int ret;
776 
777 	ret = snd_soc_add_codec_controls(codec, adau17x1_controls,
778 		ARRAY_SIZE(adau17x1_controls));
779 	if (ret)
780 		return ret;
781 	ret = snd_soc_dapm_new_controls(&codec->dapm, adau17x1_dapm_widgets,
782 		ARRAY_SIZE(adau17x1_dapm_widgets));
783 	if (ret)
784 		return ret;
785 
786 	if (adau17x1_has_dsp(adau)) {
787 		ret = snd_soc_dapm_new_controls(&codec->dapm,
788 			adau17x1_dsp_dapm_widgets,
789 			ARRAY_SIZE(adau17x1_dsp_dapm_widgets));
790 	}
791 	return ret;
792 }
793 EXPORT_SYMBOL_GPL(adau17x1_add_widgets);
794 
795 int adau17x1_add_routes(struct snd_soc_codec *codec)
796 {
797 	struct adau *adau = snd_soc_codec_get_drvdata(codec);
798 	int ret;
799 
800 	ret = snd_soc_dapm_add_routes(&codec->dapm, adau17x1_dapm_routes,
801 		ARRAY_SIZE(adau17x1_dapm_routes));
802 	if (ret)
803 		return ret;
804 
805 	if (adau17x1_has_dsp(adau)) {
806 		ret = snd_soc_dapm_add_routes(&codec->dapm,
807 			adau17x1_dsp_dapm_routes,
808 			ARRAY_SIZE(adau17x1_dsp_dapm_routes));
809 	} else {
810 		ret = snd_soc_dapm_add_routes(&codec->dapm,
811 			adau17x1_no_dsp_dapm_routes,
812 			ARRAY_SIZE(adau17x1_no_dsp_dapm_routes));
813 	}
814 	return ret;
815 }
816 EXPORT_SYMBOL_GPL(adau17x1_add_routes);
817 
818 int adau17x1_resume(struct snd_soc_codec *codec)
819 {
820 	struct adau *adau = snd_soc_codec_get_drvdata(codec);
821 
822 	if (adau->switch_mode)
823 		adau->switch_mode(codec->dev);
824 
825 	regcache_sync(adau->regmap);
826 
827 	return 0;
828 }
829 EXPORT_SYMBOL_GPL(adau17x1_resume);
830 
831 int adau17x1_probe(struct device *dev, struct regmap *regmap,
832 	enum adau17x1_type type, void (*switch_mode)(struct device *dev))
833 {
834 	struct adau *adau;
835 
836 	if (IS_ERR(regmap))
837 		return PTR_ERR(regmap);
838 
839 	adau = devm_kzalloc(dev, sizeof(*adau), GFP_KERNEL);
840 	if (!adau)
841 		return -ENOMEM;
842 
843 	adau->regmap = regmap;
844 	adau->switch_mode = switch_mode;
845 	adau->type = type;
846 
847 	dev_set_drvdata(dev, adau);
848 
849 	if (switch_mode)
850 		switch_mode(dev);
851 
852 	return 0;
853 }
854 EXPORT_SYMBOL_GPL(adau17x1_probe);
855 
856 MODULE_DESCRIPTION("ASoC ADAU1X61/ADAU1X81 common code");
857 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
858 MODULE_LICENSE("GPL");
859