xref: /openbmc/linux/sound/soc/tegra/tegra210_ahub.c (revision 1f012283)
1 // SPDX-License-Identifier: GPL-2.0-only
2 //
3 // tegra210_ahub.c - Tegra210 AHUB driver
4 //
5 // Copyright (c) 2020 NVIDIA CORPORATION.  All rights reserved.
6 
7 #include <linux/clk.h>
8 #include <linux/device.h>
9 #include <linux/module.h>
10 #include <linux/of_platform.h>
11 #include <linux/platform_device.h>
12 #include <linux/pm_runtime.h>
13 #include <linux/regmap.h>
14 #include <sound/soc.h>
15 #include "tegra210_ahub.h"
16 
17 static int tegra_ahub_get_value_enum(struct snd_kcontrol *kctl,
18 				     struct snd_ctl_elem_value *uctl)
19 {
20 	struct snd_soc_component *cmpnt = snd_soc_dapm_kcontrol_component(kctl);
21 	struct tegra_ahub *ahub = snd_soc_component_get_drvdata(cmpnt);
22 	struct soc_enum *e = (struct soc_enum *)kctl->private_value;
23 	unsigned int reg, i, bit_pos = 0;
24 
25 	/*
26 	 * Find the bit position of current MUX input.
27 	 * If nothing is set, position would be 0 and it corresponds to 'None'.
28 	 */
29 	for (i = 0; i < ahub->soc_data->reg_count; i++) {
30 		unsigned int reg_val;
31 
32 		reg = e->reg + (TEGRA210_XBAR_PART1_RX * i);
33 		reg_val = snd_soc_component_read(cmpnt, reg);
34 		reg_val &= ahub->soc_data->mask[i];
35 
36 		if (reg_val) {
37 			bit_pos = ffs(reg_val) +
38 				  (8 * cmpnt->val_bytes * i);
39 			break;
40 		}
41 	}
42 
43 	/* Find index related to the item in array *_ahub_mux_texts[] */
44 	for (i = 0; i < e->items; i++) {
45 		if (bit_pos == e->values[i]) {
46 			uctl->value.enumerated.item[0] = i;
47 			break;
48 		}
49 	}
50 
51 	return 0;
52 }
53 
54 static int tegra_ahub_put_value_enum(struct snd_kcontrol *kctl,
55 				     struct snd_ctl_elem_value *uctl)
56 {
57 	struct snd_soc_component *cmpnt = snd_soc_dapm_kcontrol_component(kctl);
58 	struct tegra_ahub *ahub = snd_soc_component_get_drvdata(cmpnt);
59 	struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kctl);
60 	struct soc_enum *e = (struct soc_enum *)kctl->private_value;
61 	struct snd_soc_dapm_update update[TEGRA_XBAR_UPDATE_MAX_REG] = { };
62 	unsigned int *item = uctl->value.enumerated.item;
63 	unsigned int value = e->values[item[0]];
64 	unsigned int i, bit_pos, reg_idx = 0, reg_val = 0;
65 
66 	if (item[0] >= e->items)
67 		return -EINVAL;
68 
69 	if (value) {
70 		/* Get the register index and value to set */
71 		reg_idx = (value - 1) / (8 * cmpnt->val_bytes);
72 		bit_pos = (value - 1) % (8 * cmpnt->val_bytes);
73 		reg_val = BIT(bit_pos);
74 	}
75 
76 	/*
77 	 * Run through all parts of a MUX register to find the state changes.
78 	 * There will be an additional update if new MUX input value is from
79 	 * different part of the MUX register.
80 	 */
81 	for (i = 0; i < ahub->soc_data->reg_count; i++) {
82 		update[i].reg = e->reg + (TEGRA210_XBAR_PART1_RX * i);
83 		update[i].val = (i == reg_idx) ? reg_val : 0;
84 		update[i].mask = ahub->soc_data->mask[i];
85 		update[i].kcontrol = kctl;
86 
87 		/* Update widget power if state has changed */
88 		if (snd_soc_component_test_bits(cmpnt, update[i].reg,
89 						update[i].mask, update[i].val))
90 			snd_soc_dapm_mux_update_power(dapm, kctl, item[0], e,
91 						      &update[i]);
92 	}
93 
94 	return 0;
95 }
96 
97 static struct snd_soc_dai_driver tegra210_ahub_dais[] = {
98 	DAI(ADMAIF1),
99 	DAI(ADMAIF2),
100 	DAI(ADMAIF3),
101 	DAI(ADMAIF4),
102 	DAI(ADMAIF5),
103 	DAI(ADMAIF6),
104 	DAI(ADMAIF7),
105 	DAI(ADMAIF8),
106 	DAI(ADMAIF9),
107 	DAI(ADMAIF10),
108 	/* XBAR <-> I2S <-> Codec */
109 	DAI(I2S1),
110 	DAI(I2S2),
111 	DAI(I2S3),
112 	DAI(I2S4),
113 	DAI(I2S5),
114 	/* XBAR <- DMIC <- Codec */
115 	DAI(DMIC1),
116 	DAI(DMIC2),
117 	DAI(DMIC3),
118 	/* XBAR -> SFC -> XBAR */
119 	DAI(SFC1 RX),
120 	DAI(SFC1 TX),
121 	DAI(SFC2 RX),
122 	DAI(SFC2 TX),
123 	DAI(SFC3 RX),
124 	DAI(SFC3 TX),
125 	DAI(SFC4 RX),
126 	DAI(SFC4 TX),
127 	/* XBAR -> MVC -> XBAR */
128 	DAI(MVC1 RX),
129 	DAI(MVC1 TX),
130 	DAI(MVC2 RX),
131 	DAI(MVC2 TX),
132 	/* XBAR -> AMX(4:1) -> XBAR */
133 	DAI(AMX1 RX1),
134 	DAI(AMX1 RX2),
135 	DAI(AMX1 RX3),
136 	DAI(AMX1 RX4),
137 	DAI(AMX1),
138 	DAI(AMX2 RX1),
139 	DAI(AMX2 RX2),
140 	DAI(AMX2 RX3),
141 	DAI(AMX2 RX4),
142 	DAI(AMX2),
143 	/* XBAR -> ADX(1:4) -> XBAR */
144 	DAI(ADX1),
145 	DAI(ADX1 TX1),
146 	DAI(ADX1 TX2),
147 	DAI(ADX1 TX3),
148 	DAI(ADX1 TX4),
149 	DAI(ADX2),
150 	DAI(ADX2 TX1),
151 	DAI(ADX2 TX2),
152 	DAI(ADX2 TX3),
153 	DAI(ADX2 TX4),
154 	/* XBAR -> MIXER(10:5) -> XBAR */
155 	DAI(MIXER1 RX1),
156 	DAI(MIXER1 RX2),
157 	DAI(MIXER1 RX3),
158 	DAI(MIXER1 RX4),
159 	DAI(MIXER1 RX5),
160 	DAI(MIXER1 RX6),
161 	DAI(MIXER1 RX7),
162 	DAI(MIXER1 RX8),
163 	DAI(MIXER1 RX9),
164 	DAI(MIXER1 RX10),
165 	DAI(MIXER1 TX1),
166 	DAI(MIXER1 TX2),
167 	DAI(MIXER1 TX3),
168 	DAI(MIXER1 TX4),
169 	DAI(MIXER1 TX5),
170 };
171 
172 static struct snd_soc_dai_driver tegra186_ahub_dais[] = {
173 	DAI(ADMAIF1),
174 	DAI(ADMAIF2),
175 	DAI(ADMAIF3),
176 	DAI(ADMAIF4),
177 	DAI(ADMAIF5),
178 	DAI(ADMAIF6),
179 	DAI(ADMAIF7),
180 	DAI(ADMAIF8),
181 	DAI(ADMAIF9),
182 	DAI(ADMAIF10),
183 	DAI(ADMAIF11),
184 	DAI(ADMAIF12),
185 	DAI(ADMAIF13),
186 	DAI(ADMAIF14),
187 	DAI(ADMAIF15),
188 	DAI(ADMAIF16),
189 	DAI(ADMAIF17),
190 	DAI(ADMAIF18),
191 	DAI(ADMAIF19),
192 	DAI(ADMAIF20),
193 	/* XBAR <-> I2S <-> Codec */
194 	DAI(I2S1),
195 	DAI(I2S2),
196 	DAI(I2S3),
197 	DAI(I2S4),
198 	DAI(I2S5),
199 	DAI(I2S6),
200 	/* XBAR <- DMIC <- Codec */
201 	DAI(DMIC1),
202 	DAI(DMIC2),
203 	DAI(DMIC3),
204 	DAI(DMIC4),
205 	/* XBAR -> DSPK -> Codec */
206 	DAI(DSPK1),
207 	DAI(DSPK2),
208 	/* XBAR -> SFC -> XBAR */
209 	DAI(SFC1 RX),
210 	DAI(SFC1 TX),
211 	DAI(SFC2 RX),
212 	DAI(SFC2 TX),
213 	DAI(SFC3 RX),
214 	DAI(SFC3 TX),
215 	DAI(SFC4 RX),
216 	DAI(SFC4 TX),
217 	/* XBAR -> MVC -> XBAR */
218 	DAI(MVC1 RX),
219 	DAI(MVC1 TX),
220 	DAI(MVC2 RX),
221 	DAI(MVC2 TX),
222 	/* XBAR -> AMX(4:1) -> XBAR */
223 	DAI(AMX1 RX1),
224 	DAI(AMX1 RX2),
225 	DAI(AMX1 RX3),
226 	DAI(AMX1 RX4),
227 	DAI(AMX1),
228 	DAI(AMX2 RX1),
229 	DAI(AMX2 RX2),
230 	DAI(AMX2 RX3),
231 	DAI(AMX2 RX4),
232 	DAI(AMX2),
233 	DAI(AMX3 RX1),
234 	DAI(AMX3 RX2),
235 	DAI(AMX3 RX3),
236 	DAI(AMX3 RX4),
237 	DAI(AMX3),
238 	DAI(AMX4 RX1),
239 	DAI(AMX4 RX2),
240 	DAI(AMX4 RX3),
241 	DAI(AMX4 RX4),
242 	DAI(AMX4),
243 	/* XBAR -> ADX(1:4) -> XBAR */
244 	DAI(ADX1),
245 	DAI(ADX1 TX1),
246 	DAI(ADX1 TX2),
247 	DAI(ADX1 TX3),
248 	DAI(ADX1 TX4),
249 	DAI(ADX2),
250 	DAI(ADX2 TX1),
251 	DAI(ADX2 TX2),
252 	DAI(ADX2 TX3),
253 	DAI(ADX2 TX4),
254 	DAI(ADX3),
255 	DAI(ADX3 TX1),
256 	DAI(ADX3 TX2),
257 	DAI(ADX3 TX3),
258 	DAI(ADX3 TX4),
259 	DAI(ADX4),
260 	DAI(ADX4 TX1),
261 	DAI(ADX4 TX2),
262 	DAI(ADX4 TX3),
263 	DAI(ADX4 TX4),
264 	/* XBAR -> MIXER1(10:5) -> XBAR */
265 	DAI(MIXER1 RX1),
266 	DAI(MIXER1 RX2),
267 	DAI(MIXER1 RX3),
268 	DAI(MIXER1 RX4),
269 	DAI(MIXER1 RX5),
270 	DAI(MIXER1 RX6),
271 	DAI(MIXER1 RX7),
272 	DAI(MIXER1 RX8),
273 	DAI(MIXER1 RX9),
274 	DAI(MIXER1 RX10),
275 	DAI(MIXER1 TX1),
276 	DAI(MIXER1 TX2),
277 	DAI(MIXER1 TX3),
278 	DAI(MIXER1 TX4),
279 	DAI(MIXER1 TX5),
280 };
281 
282 static const char * const tegra210_ahub_mux_texts[] = {
283 	"None",
284 	"ADMAIF1",
285 	"ADMAIF2",
286 	"ADMAIF3",
287 	"ADMAIF4",
288 	"ADMAIF5",
289 	"ADMAIF6",
290 	"ADMAIF7",
291 	"ADMAIF8",
292 	"ADMAIF9",
293 	"ADMAIF10",
294 	"I2S1",
295 	"I2S2",
296 	"I2S3",
297 	"I2S4",
298 	"I2S5",
299 	"DMIC1",
300 	"DMIC2",
301 	"DMIC3",
302 	"SFC1",
303 	"SFC2",
304 	"SFC3",
305 	"SFC4",
306 	"MVC1",
307 	"MVC2",
308 	"AMX1",
309 	"AMX2",
310 	"ADX1 TX1",
311 	"ADX1 TX2",
312 	"ADX1 TX3",
313 	"ADX1 TX4",
314 	"ADX2 TX1",
315 	"ADX2 TX2",
316 	"ADX2 TX3",
317 	"ADX2 TX4",
318 	"MIXER1 TX1",
319 	"MIXER1 TX2",
320 	"MIXER1 TX3",
321 	"MIXER1 TX4",
322 	"MIXER1 TX5",
323 };
324 
325 static const char * const tegra186_ahub_mux_texts[] = {
326 	"None",
327 	"ADMAIF1",
328 	"ADMAIF2",
329 	"ADMAIF3",
330 	"ADMAIF4",
331 	"ADMAIF5",
332 	"ADMAIF6",
333 	"ADMAIF7",
334 	"ADMAIF8",
335 	"ADMAIF9",
336 	"ADMAIF10",
337 	"ADMAIF11",
338 	"ADMAIF12",
339 	"ADMAIF13",
340 	"ADMAIF14",
341 	"ADMAIF15",
342 	"ADMAIF16",
343 	"I2S1",
344 	"I2S2",
345 	"I2S3",
346 	"I2S4",
347 	"I2S5",
348 	"I2S6",
349 	"ADMAIF17",
350 	"ADMAIF18",
351 	"ADMAIF19",
352 	"ADMAIF20",
353 	"DMIC1",
354 	"DMIC2",
355 	"DMIC3",
356 	"DMIC4",
357 	"SFC1",
358 	"SFC2",
359 	"SFC3",
360 	"SFC4",
361 	"MVC1",
362 	"MVC2",
363 	"AMX1",
364 	"AMX2",
365 	"AMX3",
366 	"AMX4",
367 	"ADX1 TX1",
368 	"ADX1 TX2",
369 	"ADX1 TX3",
370 	"ADX1 TX4",
371 	"ADX2 TX1",
372 	"ADX2 TX2",
373 	"ADX2 TX3",
374 	"ADX2 TX4",
375 	"ADX3 TX1",
376 	"ADX3 TX2",
377 	"ADX3 TX3",
378 	"ADX3 TX4",
379 	"ADX4 TX1",
380 	"ADX4 TX2",
381 	"ADX4 TX3",
382 	"ADX4 TX4",
383 	"MIXER1 TX1",
384 	"MIXER1 TX2",
385 	"MIXER1 TX3",
386 	"MIXER1 TX4",
387 	"MIXER1 TX5",
388 };
389 
390 static const unsigned int tegra210_ahub_mux_values[] = {
391 	0,
392 	/* ADMAIF */
393 	MUX_VALUE(0, 0),
394 	MUX_VALUE(0, 1),
395 	MUX_VALUE(0, 2),
396 	MUX_VALUE(0, 3),
397 	MUX_VALUE(0, 4),
398 	MUX_VALUE(0, 5),
399 	MUX_VALUE(0, 6),
400 	MUX_VALUE(0, 7),
401 	MUX_VALUE(0, 8),
402 	MUX_VALUE(0, 9),
403 	/* I2S */
404 	MUX_VALUE(0, 16),
405 	MUX_VALUE(0, 17),
406 	MUX_VALUE(0, 18),
407 	MUX_VALUE(0, 19),
408 	MUX_VALUE(0, 20),
409 	/* DMIC */
410 	MUX_VALUE(2, 18),
411 	MUX_VALUE(2, 19),
412 	MUX_VALUE(2, 20),
413 	/* SFC */
414 	MUX_VALUE(0, 24),
415 	MUX_VALUE(0, 25),
416 	MUX_VALUE(0, 26),
417 	MUX_VALUE(0, 27),
418 	/* MVC */
419 	MUX_VALUE(2, 8),
420 	MUX_VALUE(2, 9),
421 	/* AMX */
422 	MUX_VALUE(1, 8),
423 	MUX_VALUE(1, 9),
424 	/* ADX */
425 	MUX_VALUE(2, 24),
426 	MUX_VALUE(2, 25),
427 	MUX_VALUE(2, 26),
428 	MUX_VALUE(2, 27),
429 	MUX_VALUE(2, 28),
430 	MUX_VALUE(2, 29),
431 	MUX_VALUE(2, 30),
432 	MUX_VALUE(2, 31),
433 	/* MIXER */
434 	MUX_VALUE(1, 0),
435 	MUX_VALUE(1, 1),
436 	MUX_VALUE(1, 2),
437 	MUX_VALUE(1, 3),
438 	MUX_VALUE(1, 4),
439 };
440 
441 static const unsigned int tegra186_ahub_mux_values[] = {
442 	0,
443 	/* ADMAIF */
444 	MUX_VALUE(0, 0),
445 	MUX_VALUE(0, 1),
446 	MUX_VALUE(0, 2),
447 	MUX_VALUE(0, 3),
448 	MUX_VALUE(0, 4),
449 	MUX_VALUE(0, 5),
450 	MUX_VALUE(0, 6),
451 	MUX_VALUE(0, 7),
452 	MUX_VALUE(0, 8),
453 	MUX_VALUE(0, 9),
454 	MUX_VALUE(0, 10),
455 	MUX_VALUE(0, 11),
456 	MUX_VALUE(0, 12),
457 	MUX_VALUE(0, 13),
458 	MUX_VALUE(0, 14),
459 	MUX_VALUE(0, 15),
460 	/* I2S */
461 	MUX_VALUE(0, 16),
462 	MUX_VALUE(0, 17),
463 	MUX_VALUE(0, 18),
464 	MUX_VALUE(0, 19),
465 	MUX_VALUE(0, 20),
466 	MUX_VALUE(0, 21),
467 	/* ADMAIF */
468 	MUX_VALUE(3, 16),
469 	MUX_VALUE(3, 17),
470 	MUX_VALUE(3, 18),
471 	MUX_VALUE(3, 19),
472 	/* DMIC */
473 	MUX_VALUE(2, 18),
474 	MUX_VALUE(2, 19),
475 	MUX_VALUE(2, 20),
476 	MUX_VALUE(2, 21),
477 	/* SFC */
478 	MUX_VALUE(0, 24),
479 	MUX_VALUE(0, 25),
480 	MUX_VALUE(0, 26),
481 	MUX_VALUE(0, 27),
482 	/* MVC */
483 	MUX_VALUE(2, 8),
484 	MUX_VALUE(2, 9),
485 	/* AMX */
486 	MUX_VALUE(1, 8),
487 	MUX_VALUE(1, 9),
488 	MUX_VALUE(1, 10),
489 	MUX_VALUE(1, 11),
490 	/* ADX */
491 	MUX_VALUE(2, 24),
492 	MUX_VALUE(2, 25),
493 	MUX_VALUE(2, 26),
494 	MUX_VALUE(2, 27),
495 	MUX_VALUE(2, 28),
496 	MUX_VALUE(2, 29),
497 	MUX_VALUE(2, 30),
498 	MUX_VALUE(2, 31),
499 	MUX_VALUE(3, 0),
500 	MUX_VALUE(3, 1),
501 	MUX_VALUE(3, 2),
502 	MUX_VALUE(3, 3),
503 	MUX_VALUE(3, 4),
504 	MUX_VALUE(3, 5),
505 	MUX_VALUE(3, 6),
506 	MUX_VALUE(3, 7),
507 	/* MIXER */
508 	MUX_VALUE(1, 0),
509 	MUX_VALUE(1, 1),
510 	MUX_VALUE(1, 2),
511 	MUX_VALUE(1, 3),
512 	MUX_VALUE(1, 4),
513 };
514 
515 /* Controls for t210 */
516 MUX_ENUM_CTRL_DECL(t210_admaif1_tx, 0x00);
517 MUX_ENUM_CTRL_DECL(t210_admaif2_tx, 0x01);
518 MUX_ENUM_CTRL_DECL(t210_admaif3_tx, 0x02);
519 MUX_ENUM_CTRL_DECL(t210_admaif4_tx, 0x03);
520 MUX_ENUM_CTRL_DECL(t210_admaif5_tx, 0x04);
521 MUX_ENUM_CTRL_DECL(t210_admaif6_tx, 0x05);
522 MUX_ENUM_CTRL_DECL(t210_admaif7_tx, 0x06);
523 MUX_ENUM_CTRL_DECL(t210_admaif8_tx, 0x07);
524 MUX_ENUM_CTRL_DECL(t210_admaif9_tx, 0x08);
525 MUX_ENUM_CTRL_DECL(t210_admaif10_tx, 0x09);
526 MUX_ENUM_CTRL_DECL(t210_i2s1_tx, 0x10);
527 MUX_ENUM_CTRL_DECL(t210_i2s2_tx, 0x11);
528 MUX_ENUM_CTRL_DECL(t210_i2s3_tx, 0x12);
529 MUX_ENUM_CTRL_DECL(t210_i2s4_tx, 0x13);
530 MUX_ENUM_CTRL_DECL(t210_i2s5_tx, 0x14);
531 MUX_ENUM_CTRL_DECL(t210_sfc1_tx, 0x18);
532 MUX_ENUM_CTRL_DECL(t210_sfc2_tx, 0x19);
533 MUX_ENUM_CTRL_DECL(t210_sfc3_tx, 0x1a);
534 MUX_ENUM_CTRL_DECL(t210_sfc4_tx, 0x1b);
535 MUX_ENUM_CTRL_DECL(t210_mvc1_tx, 0x48);
536 MUX_ENUM_CTRL_DECL(t210_mvc2_tx, 0x49);
537 MUX_ENUM_CTRL_DECL(t210_amx11_tx, 0x50);
538 MUX_ENUM_CTRL_DECL(t210_amx12_tx, 0x51);
539 MUX_ENUM_CTRL_DECL(t210_amx13_tx, 0x52);
540 MUX_ENUM_CTRL_DECL(t210_amx14_tx, 0x53);
541 MUX_ENUM_CTRL_DECL(t210_amx21_tx, 0x54);
542 MUX_ENUM_CTRL_DECL(t210_amx22_tx, 0x55);
543 MUX_ENUM_CTRL_DECL(t210_amx23_tx, 0x56);
544 MUX_ENUM_CTRL_DECL(t210_amx24_tx, 0x57);
545 MUX_ENUM_CTRL_DECL(t210_adx1_tx, 0x58);
546 MUX_ENUM_CTRL_DECL(t210_adx2_tx, 0x59);
547 MUX_ENUM_CTRL_DECL(t210_mixer11_tx, 0x20);
548 MUX_ENUM_CTRL_DECL(t210_mixer12_tx, 0x21);
549 MUX_ENUM_CTRL_DECL(t210_mixer13_tx, 0x22);
550 MUX_ENUM_CTRL_DECL(t210_mixer14_tx, 0x23);
551 MUX_ENUM_CTRL_DECL(t210_mixer15_tx, 0x24);
552 MUX_ENUM_CTRL_DECL(t210_mixer16_tx, 0x25);
553 MUX_ENUM_CTRL_DECL(t210_mixer17_tx, 0x26);
554 MUX_ENUM_CTRL_DECL(t210_mixer18_tx, 0x27);
555 MUX_ENUM_CTRL_DECL(t210_mixer19_tx, 0x28);
556 MUX_ENUM_CTRL_DECL(t210_mixer110_tx, 0x29);
557 
558 /* Controls for t186 */
559 MUX_ENUM_CTRL_DECL_186(t186_admaif1_tx, 0x00);
560 MUX_ENUM_CTRL_DECL_186(t186_admaif2_tx, 0x01);
561 MUX_ENUM_CTRL_DECL_186(t186_admaif3_tx, 0x02);
562 MUX_ENUM_CTRL_DECL_186(t186_admaif4_tx, 0x03);
563 MUX_ENUM_CTRL_DECL_186(t186_admaif5_tx, 0x04);
564 MUX_ENUM_CTRL_DECL_186(t186_admaif6_tx, 0x05);
565 MUX_ENUM_CTRL_DECL_186(t186_admaif7_tx, 0x06);
566 MUX_ENUM_CTRL_DECL_186(t186_admaif8_tx, 0x07);
567 MUX_ENUM_CTRL_DECL_186(t186_admaif9_tx, 0x08);
568 MUX_ENUM_CTRL_DECL_186(t186_admaif10_tx, 0x09);
569 MUX_ENUM_CTRL_DECL_186(t186_i2s1_tx, 0x10);
570 MUX_ENUM_CTRL_DECL_186(t186_i2s2_tx, 0x11);
571 MUX_ENUM_CTRL_DECL_186(t186_i2s3_tx, 0x12);
572 MUX_ENUM_CTRL_DECL_186(t186_i2s4_tx, 0x13);
573 MUX_ENUM_CTRL_DECL_186(t186_i2s5_tx, 0x14);
574 MUX_ENUM_CTRL_DECL_186(t186_admaif11_tx, 0x0a);
575 MUX_ENUM_CTRL_DECL_186(t186_admaif12_tx, 0x0b);
576 MUX_ENUM_CTRL_DECL_186(t186_admaif13_tx, 0x0c);
577 MUX_ENUM_CTRL_DECL_186(t186_admaif14_tx, 0x0d);
578 MUX_ENUM_CTRL_DECL_186(t186_admaif15_tx, 0x0e);
579 MUX_ENUM_CTRL_DECL_186(t186_admaif16_tx, 0x0f);
580 MUX_ENUM_CTRL_DECL_186(t186_i2s6_tx, 0x15);
581 MUX_ENUM_CTRL_DECL_186(t186_dspk1_tx, 0x30);
582 MUX_ENUM_CTRL_DECL_186(t186_dspk2_tx, 0x31);
583 MUX_ENUM_CTRL_DECL_186(t186_admaif17_tx, 0x68);
584 MUX_ENUM_CTRL_DECL_186(t186_admaif18_tx, 0x69);
585 MUX_ENUM_CTRL_DECL_186(t186_admaif19_tx, 0x6a);
586 MUX_ENUM_CTRL_DECL_186(t186_admaif20_tx, 0x6b);
587 MUX_ENUM_CTRL_DECL_186(t186_sfc1_tx, 0x18);
588 MUX_ENUM_CTRL_DECL_186(t186_sfc2_tx, 0x19);
589 MUX_ENUM_CTRL_DECL_186(t186_sfc3_tx, 0x1a);
590 MUX_ENUM_CTRL_DECL_186(t186_sfc4_tx, 0x1b);
591 MUX_ENUM_CTRL_DECL_186(t186_mvc1_tx, 0x48);
592 MUX_ENUM_CTRL_DECL_186(t186_mvc2_tx, 0x49);
593 MUX_ENUM_CTRL_DECL_186(t186_amx11_tx, 0x50);
594 MUX_ENUM_CTRL_DECL_186(t186_amx12_tx, 0x51);
595 MUX_ENUM_CTRL_DECL_186(t186_amx13_tx, 0x52);
596 MUX_ENUM_CTRL_DECL_186(t186_amx14_tx, 0x53);
597 MUX_ENUM_CTRL_DECL_186(t186_amx21_tx, 0x54);
598 MUX_ENUM_CTRL_DECL_186(t186_amx22_tx, 0x55);
599 MUX_ENUM_CTRL_DECL_186(t186_amx23_tx, 0x56);
600 MUX_ENUM_CTRL_DECL_186(t186_amx24_tx, 0x57);
601 MUX_ENUM_CTRL_DECL_186(t186_amx31_tx, 0x58);
602 MUX_ENUM_CTRL_DECL_186(t186_amx32_tx, 0x59);
603 MUX_ENUM_CTRL_DECL_186(t186_amx33_tx, 0x5a);
604 MUX_ENUM_CTRL_DECL_186(t186_amx34_tx, 0x5b);
605 MUX_ENUM_CTRL_DECL_186(t186_amx41_tx, 0x64);
606 MUX_ENUM_CTRL_DECL_186(t186_amx42_tx, 0x65);
607 MUX_ENUM_CTRL_DECL_186(t186_amx43_tx, 0x66);
608 MUX_ENUM_CTRL_DECL_186(t186_amx44_tx, 0x67);
609 MUX_ENUM_CTRL_DECL_186(t186_adx1_tx, 0x60);
610 MUX_ENUM_CTRL_DECL_186(t186_adx2_tx, 0x61);
611 MUX_ENUM_CTRL_DECL_186(t186_adx3_tx, 0x62);
612 MUX_ENUM_CTRL_DECL_186(t186_adx4_tx, 0x63);
613 MUX_ENUM_CTRL_DECL_186(t186_mixer11_tx, 0x20);
614 MUX_ENUM_CTRL_DECL_186(t186_mixer12_tx, 0x21);
615 MUX_ENUM_CTRL_DECL_186(t186_mixer13_tx, 0x22);
616 MUX_ENUM_CTRL_DECL_186(t186_mixer14_tx, 0x23);
617 MUX_ENUM_CTRL_DECL_186(t186_mixer15_tx, 0x24);
618 MUX_ENUM_CTRL_DECL_186(t186_mixer16_tx, 0x25);
619 MUX_ENUM_CTRL_DECL_186(t186_mixer17_tx, 0x26);
620 MUX_ENUM_CTRL_DECL_186(t186_mixer18_tx, 0x27);
621 MUX_ENUM_CTRL_DECL_186(t186_mixer19_tx, 0x28);
622 MUX_ENUM_CTRL_DECL_186(t186_mixer110_tx, 0x29);
623 
624 /*
625  * The number of entries in, and order of, this array is closely tied to the
626  * calculation of tegra210_ahub_codec.num_dapm_widgets near the end of
627  * tegra210_ahub_probe()
628  */
629 static const struct snd_soc_dapm_widget tegra210_ahub_widgets[] = {
630 	WIDGETS("ADMAIF1", t210_admaif1_tx),
631 	WIDGETS("ADMAIF2", t210_admaif2_tx),
632 	WIDGETS("ADMAIF3", t210_admaif3_tx),
633 	WIDGETS("ADMAIF4", t210_admaif4_tx),
634 	WIDGETS("ADMAIF5", t210_admaif5_tx),
635 	WIDGETS("ADMAIF6", t210_admaif6_tx),
636 	WIDGETS("ADMAIF7", t210_admaif7_tx),
637 	WIDGETS("ADMAIF8", t210_admaif8_tx),
638 	WIDGETS("ADMAIF9", t210_admaif9_tx),
639 	WIDGETS("ADMAIF10", t210_admaif10_tx),
640 	WIDGETS("I2S1", t210_i2s1_tx),
641 	WIDGETS("I2S2", t210_i2s2_tx),
642 	WIDGETS("I2S3", t210_i2s3_tx),
643 	WIDGETS("I2S4", t210_i2s4_tx),
644 	WIDGETS("I2S5", t210_i2s5_tx),
645 	TX_WIDGETS("DMIC1"),
646 	TX_WIDGETS("DMIC2"),
647 	TX_WIDGETS("DMIC3"),
648 	WIDGETS("SFC1", t210_sfc1_tx),
649 	WIDGETS("SFC2", t210_sfc2_tx),
650 	WIDGETS("SFC3", t210_sfc3_tx),
651 	WIDGETS("SFC4", t210_sfc4_tx),
652 	WIDGETS("MVC1", t210_mvc1_tx),
653 	WIDGETS("MVC2", t210_mvc2_tx),
654 	WIDGETS("AMX1 RX1", t210_amx11_tx),
655 	WIDGETS("AMX1 RX2", t210_amx12_tx),
656 	WIDGETS("AMX1 RX3", t210_amx13_tx),
657 	WIDGETS("AMX1 RX4", t210_amx14_tx),
658 	WIDGETS("AMX2 RX1", t210_amx21_tx),
659 	WIDGETS("AMX2 RX2", t210_amx22_tx),
660 	WIDGETS("AMX2 RX3", t210_amx23_tx),
661 	WIDGETS("AMX2 RX4", t210_amx24_tx),
662 	TX_WIDGETS("AMX1"),
663 	TX_WIDGETS("AMX2"),
664 	WIDGETS("ADX1", t210_adx1_tx),
665 	WIDGETS("ADX2", t210_adx2_tx),
666 	TX_WIDGETS("ADX1 TX1"),
667 	TX_WIDGETS("ADX1 TX2"),
668 	TX_WIDGETS("ADX1 TX3"),
669 	TX_WIDGETS("ADX1 TX4"),
670 	TX_WIDGETS("ADX2 TX1"),
671 	TX_WIDGETS("ADX2 TX2"),
672 	TX_WIDGETS("ADX2 TX3"),
673 	TX_WIDGETS("ADX2 TX4"),
674 	WIDGETS("MIXER1 RX1", t210_mixer11_tx),
675 	WIDGETS("MIXER1 RX2", t210_mixer12_tx),
676 	WIDGETS("MIXER1 RX3", t210_mixer13_tx),
677 	WIDGETS("MIXER1 RX4", t210_mixer14_tx),
678 	WIDGETS("MIXER1 RX5", t210_mixer15_tx),
679 	WIDGETS("MIXER1 RX6", t210_mixer16_tx),
680 	WIDGETS("MIXER1 RX7", t210_mixer17_tx),
681 	WIDGETS("MIXER1 RX8", t210_mixer18_tx),
682 	WIDGETS("MIXER1 RX9", t210_mixer19_tx),
683 	WIDGETS("MIXER1 RX10", t210_mixer110_tx),
684 	TX_WIDGETS("MIXER1 TX1"),
685 	TX_WIDGETS("MIXER1 TX2"),
686 	TX_WIDGETS("MIXER1 TX3"),
687 	TX_WIDGETS("MIXER1 TX4"),
688 	TX_WIDGETS("MIXER1 TX5"),
689 };
690 
691 static const struct snd_soc_dapm_widget tegra186_ahub_widgets[] = {
692 	WIDGETS("ADMAIF1", t186_admaif1_tx),
693 	WIDGETS("ADMAIF2", t186_admaif2_tx),
694 	WIDGETS("ADMAIF3", t186_admaif3_tx),
695 	WIDGETS("ADMAIF4", t186_admaif4_tx),
696 	WIDGETS("ADMAIF5", t186_admaif5_tx),
697 	WIDGETS("ADMAIF6", t186_admaif6_tx),
698 	WIDGETS("ADMAIF7", t186_admaif7_tx),
699 	WIDGETS("ADMAIF8", t186_admaif8_tx),
700 	WIDGETS("ADMAIF9", t186_admaif9_tx),
701 	WIDGETS("ADMAIF10", t186_admaif10_tx),
702 	WIDGETS("ADMAIF11", t186_admaif11_tx),
703 	WIDGETS("ADMAIF12", t186_admaif12_tx),
704 	WIDGETS("ADMAIF13", t186_admaif13_tx),
705 	WIDGETS("ADMAIF14", t186_admaif14_tx),
706 	WIDGETS("ADMAIF15", t186_admaif15_tx),
707 	WIDGETS("ADMAIF16", t186_admaif16_tx),
708 	WIDGETS("ADMAIF17", t186_admaif17_tx),
709 	WIDGETS("ADMAIF18", t186_admaif18_tx),
710 	WIDGETS("ADMAIF19", t186_admaif19_tx),
711 	WIDGETS("ADMAIF20", t186_admaif20_tx),
712 	WIDGETS("I2S1", t186_i2s1_tx),
713 	WIDGETS("I2S2", t186_i2s2_tx),
714 	WIDGETS("I2S3", t186_i2s3_tx),
715 	WIDGETS("I2S4", t186_i2s4_tx),
716 	WIDGETS("I2S5", t186_i2s5_tx),
717 	WIDGETS("I2S6", t186_i2s6_tx),
718 	TX_WIDGETS("DMIC1"),
719 	TX_WIDGETS("DMIC2"),
720 	TX_WIDGETS("DMIC3"),
721 	TX_WIDGETS("DMIC4"),
722 	WIDGETS("DSPK1", t186_dspk1_tx),
723 	WIDGETS("DSPK2", t186_dspk2_tx),
724 	WIDGETS("SFC1", t186_sfc1_tx),
725 	WIDGETS("SFC2", t186_sfc2_tx),
726 	WIDGETS("SFC3", t186_sfc3_tx),
727 	WIDGETS("SFC4", t186_sfc4_tx),
728 	WIDGETS("MVC1", t186_mvc1_tx),
729 	WIDGETS("MVC2", t186_mvc2_tx),
730 	WIDGETS("AMX1 RX1", t186_amx11_tx),
731 	WIDGETS("AMX1 RX2", t186_amx12_tx),
732 	WIDGETS("AMX1 RX3", t186_amx13_tx),
733 	WIDGETS("AMX1 RX4", t186_amx14_tx),
734 	WIDGETS("AMX2 RX1", t186_amx21_tx),
735 	WIDGETS("AMX2 RX2", t186_amx22_tx),
736 	WIDGETS("AMX2 RX3", t186_amx23_tx),
737 	WIDGETS("AMX2 RX4", t186_amx24_tx),
738 	WIDGETS("AMX3 RX1", t186_amx31_tx),
739 	WIDGETS("AMX3 RX2", t186_amx32_tx),
740 	WIDGETS("AMX3 RX3", t186_amx33_tx),
741 	WIDGETS("AMX3 RX4", t186_amx34_tx),
742 	WIDGETS("AMX4 RX1", t186_amx41_tx),
743 	WIDGETS("AMX4 RX2", t186_amx42_tx),
744 	WIDGETS("AMX4 RX3", t186_amx43_tx),
745 	WIDGETS("AMX4 RX4", t186_amx44_tx),
746 	TX_WIDGETS("AMX1"),
747 	TX_WIDGETS("AMX2"),
748 	TX_WIDGETS("AMX3"),
749 	TX_WIDGETS("AMX4"),
750 	WIDGETS("ADX1", t186_adx1_tx),
751 	WIDGETS("ADX2", t186_adx2_tx),
752 	WIDGETS("ADX3", t186_adx3_tx),
753 	WIDGETS("ADX4", t186_adx4_tx),
754 	TX_WIDGETS("ADX1 TX1"),
755 	TX_WIDGETS("ADX1 TX2"),
756 	TX_WIDGETS("ADX1 TX3"),
757 	TX_WIDGETS("ADX1 TX4"),
758 	TX_WIDGETS("ADX2 TX1"),
759 	TX_WIDGETS("ADX2 TX2"),
760 	TX_WIDGETS("ADX2 TX3"),
761 	TX_WIDGETS("ADX2 TX4"),
762 	TX_WIDGETS("ADX3 TX1"),
763 	TX_WIDGETS("ADX3 TX2"),
764 	TX_WIDGETS("ADX3 TX3"),
765 	TX_WIDGETS("ADX3 TX4"),
766 	TX_WIDGETS("ADX4 TX1"),
767 	TX_WIDGETS("ADX4 TX2"),
768 	TX_WIDGETS("ADX4 TX3"),
769 	TX_WIDGETS("ADX4 TX4"),
770 	WIDGETS("MIXER1 RX1", t186_mixer11_tx),
771 	WIDGETS("MIXER1 RX2", t186_mixer12_tx),
772 	WIDGETS("MIXER1 RX3", t186_mixer13_tx),
773 	WIDGETS("MIXER1 RX4", t186_mixer14_tx),
774 	WIDGETS("MIXER1 RX5", t186_mixer15_tx),
775 	WIDGETS("MIXER1 RX6", t186_mixer16_tx),
776 	WIDGETS("MIXER1 RX7", t186_mixer17_tx),
777 	WIDGETS("MIXER1 RX8", t186_mixer18_tx),
778 	WIDGETS("MIXER1 RX9", t186_mixer19_tx),
779 	WIDGETS("MIXER1 RX10", t186_mixer110_tx),
780 	TX_WIDGETS("MIXER1 TX1"),
781 	TX_WIDGETS("MIXER1 TX2"),
782 	TX_WIDGETS("MIXER1 TX3"),
783 	TX_WIDGETS("MIXER1 TX4"),
784 	TX_WIDGETS("MIXER1 TX5"),
785 };
786 
787 #define TEGRA_COMMON_MUX_ROUTES(name)					\
788 	{ name " XBAR-TX",	 NULL,		name " Mux" },		\
789 	{ name " Mux",		"ADMAIF1",	"ADMAIF1 XBAR-RX" },	\
790 	{ name " Mux",		"ADMAIF2",	"ADMAIF2 XBAR-RX" },	\
791 	{ name " Mux",		"ADMAIF3",	"ADMAIF3 XBAR-RX" },	\
792 	{ name " Mux",		"ADMAIF4",	"ADMAIF4 XBAR-RX" },	\
793 	{ name " Mux",		"ADMAIF5",	"ADMAIF5 XBAR-RX" },	\
794 	{ name " Mux",		"ADMAIF6",	"ADMAIF6 XBAR-RX" },	\
795 	{ name " Mux",		"ADMAIF7",	"ADMAIF7 XBAR-RX" },	\
796 	{ name " Mux",		"ADMAIF8",	"ADMAIF8 XBAR-RX" },	\
797 	{ name " Mux",		"ADMAIF9",	"ADMAIF9 XBAR-RX" },	\
798 	{ name " Mux",		"ADMAIF10",	"ADMAIF10 XBAR-RX" },	\
799 	{ name " Mux",		"I2S1",		"I2S1 XBAR-RX" },	\
800 	{ name " Mux",		"I2S2",		"I2S2 XBAR-RX" },	\
801 	{ name " Mux",		"I2S3",		"I2S3 XBAR-RX" },	\
802 	{ name " Mux",		"I2S4",		"I2S4 XBAR-RX" },	\
803 	{ name " Mux",		"I2S5",		"I2S5 XBAR-RX" },	\
804 	{ name " Mux",		"DMIC1",	"DMIC1 XBAR-RX" },	\
805 	{ name " Mux",		"DMIC2",	"DMIC2 XBAR-RX" },	\
806 	{ name " Mux",		"DMIC3",	"DMIC3 XBAR-RX" },	\
807 	{ name " Mux",		"SFC1",		"SFC1 XBAR-RX" },	\
808 	{ name " Mux",		"SFC2",		"SFC2 XBAR-RX" },	\
809 	{ name " Mux",		"SFC3",		"SFC3 XBAR-RX" },	\
810 	{ name " Mux",		"SFC4",		"SFC4 XBAR-RX" },	\
811 	{ name " Mux",		"MVC1",		"MVC1 XBAR-RX" },	\
812 	{ name " Mux",		"MVC2",		"MVC2 XBAR-RX" },	\
813 	{ name " Mux",		"AMX1",		"AMX1 XBAR-RX" },	\
814 	{ name " Mux",		"AMX2",		"AMX2 XBAR-RX" },	\
815 	{ name " Mux",		"ADX1 TX1",	"ADX1 TX1 XBAR-RX" },	\
816 	{ name " Mux",		"ADX1 TX2",	"ADX1 TX2 XBAR-RX" },	\
817 	{ name " Mux",		"ADX1 TX3",	"ADX1 TX3 XBAR-RX" },	\
818 	{ name " Mux",		"ADX1 TX4",	"ADX1 TX4 XBAR-RX" },	\
819 	{ name " Mux",		"ADX2 TX1",	"ADX2 TX1 XBAR-RX" },	\
820 	{ name " Mux",		"ADX2 TX2",	"ADX2 TX2 XBAR-RX" },	\
821 	{ name " Mux",		"ADX2 TX3",	"ADX2 TX3 XBAR-RX" },	\
822 	{ name " Mux",		"ADX2 TX4",	"ADX2 TX4 XBAR-RX" },	\
823 	{ name " Mux",		"MIXER1 TX1",	"MIXER1 TX1 XBAR-RX" },	\
824 	{ name " Mux",		"MIXER1 TX2",	"MIXER1 TX2 XBAR-RX" },	\
825 	{ name " Mux",		"MIXER1 TX3",	"MIXER1 TX3 XBAR-RX" },	\
826 	{ name " Mux",		"MIXER1 TX4",	"MIXER1 TX4 XBAR-RX" },	\
827 	{ name " Mux",		"MIXER1 TX5",	"MIXER1 TX5 XBAR-RX" },
828 
829 #define TEGRA186_ONLY_MUX_ROUTES(name)					\
830 	{ name " Mux",		"ADMAIF11",	"ADMAIF11 XBAR-RX" },	\
831 	{ name " Mux",		"ADMAIF12",	"ADMAIF12 XBAR-RX" },	\
832 	{ name " Mux",		"ADMAIF13",	"ADMAIF13 XBAR-RX" },	\
833 	{ name " Mux",		"ADMAIF14",	"ADMAIF14 XBAR-RX" },	\
834 	{ name " Mux",		"ADMAIF15",	"ADMAIF15 XBAR-RX" },	\
835 	{ name " Mux",		"ADMAIF16",	"ADMAIF16 XBAR-RX" },	\
836 	{ name " Mux",		"ADMAIF17",	"ADMAIF17 XBAR-RX" },	\
837 	{ name " Mux",		"ADMAIF18",	"ADMAIF18 XBAR-RX" },	\
838 	{ name " Mux",		"ADMAIF19",	"ADMAIF19 XBAR-RX" },	\
839 	{ name " Mux",		"ADMAIF20",	"ADMAIF20 XBAR-RX" },	\
840 	{ name " Mux",		"I2S6",		"I2S6 XBAR-RX" },	\
841 	{ name " Mux",		"DMIC4",	"DMIC4 XBAR-RX" },	\
842 	{ name " Mux",		"AMX3",		"AMX3 XBAR-RX" },	\
843 	{ name " Mux",		"AMX4",		"AMX4 XBAR-RX" },	\
844 	{ name " Mux",		"ADX3 TX1",	"ADX3 TX1 XBAR-RX" },	\
845 	{ name " Mux",		"ADX3 TX2",	"ADX3 TX2 XBAR-RX" },	\
846 	{ name " Mux",		"ADX3 TX3",	"ADX3 TX3 XBAR-RX" },	\
847 	{ name " Mux",		"ADX3 TX4",	"ADX3 TX4 XBAR-RX" },	\
848 	{ name " Mux",		"ADX4 TX1",	"ADX4 TX1 XBAR-RX" },	\
849 	{ name " Mux",		"ADX4 TX2",	"ADX4 TX2 XBAR-RX" },	\
850 	{ name " Mux",		"ADX4 TX3",	"ADX4 TX3 XBAR-RX" },	\
851 	{ name " Mux",		"ADX4 TX4",	"ADX4 TX4 XBAR-RX" },
852 
853 #define TEGRA210_MUX_ROUTES(name)						\
854 	TEGRA_COMMON_MUX_ROUTES(name)
855 
856 #define TEGRA186_MUX_ROUTES(name)						\
857 	TEGRA_COMMON_MUX_ROUTES(name)					\
858 	TEGRA186_ONLY_MUX_ROUTES(name)
859 
860 /* Connect FEs with XBAR */
861 #define TEGRA_FE_ROUTES(name) \
862 	{ name " XBAR-Playback",	NULL,	name " Playback" },	\
863 	{ name " XBAR-RX",		NULL,	name " XBAR-Playback"}, \
864 	{ name " XBAR-Capture",		NULL,	name " XBAR-TX" },      \
865 	{ name " Capture",		NULL,	name " XBAR-Capture" },
866 
867 /*
868  * The number of entries in, and order of, this array is closely tied to the
869  * calculation of tegra210_ahub_codec.num_dapm_routes near the end of
870  * tegra210_ahub_probe()
871  */
872 static const struct snd_soc_dapm_route tegra210_ahub_routes[] = {
873 	TEGRA_FE_ROUTES("ADMAIF1")
874 	TEGRA_FE_ROUTES("ADMAIF2")
875 	TEGRA_FE_ROUTES("ADMAIF3")
876 	TEGRA_FE_ROUTES("ADMAIF4")
877 	TEGRA_FE_ROUTES("ADMAIF5")
878 	TEGRA_FE_ROUTES("ADMAIF6")
879 	TEGRA_FE_ROUTES("ADMAIF7")
880 	TEGRA_FE_ROUTES("ADMAIF8")
881 	TEGRA_FE_ROUTES("ADMAIF9")
882 	TEGRA_FE_ROUTES("ADMAIF10")
883 	TEGRA210_MUX_ROUTES("ADMAIF1")
884 	TEGRA210_MUX_ROUTES("ADMAIF2")
885 	TEGRA210_MUX_ROUTES("ADMAIF3")
886 	TEGRA210_MUX_ROUTES("ADMAIF4")
887 	TEGRA210_MUX_ROUTES("ADMAIF5")
888 	TEGRA210_MUX_ROUTES("ADMAIF6")
889 	TEGRA210_MUX_ROUTES("ADMAIF7")
890 	TEGRA210_MUX_ROUTES("ADMAIF8")
891 	TEGRA210_MUX_ROUTES("ADMAIF9")
892 	TEGRA210_MUX_ROUTES("ADMAIF10")
893 	TEGRA210_MUX_ROUTES("I2S1")
894 	TEGRA210_MUX_ROUTES("I2S2")
895 	TEGRA210_MUX_ROUTES("I2S3")
896 	TEGRA210_MUX_ROUTES("I2S4")
897 	TEGRA210_MUX_ROUTES("I2S5")
898 	TEGRA210_MUX_ROUTES("SFC1")
899 	TEGRA210_MUX_ROUTES("SFC2")
900 	TEGRA210_MUX_ROUTES("SFC3")
901 	TEGRA210_MUX_ROUTES("SFC4")
902 	TEGRA210_MUX_ROUTES("MVC1")
903 	TEGRA210_MUX_ROUTES("MVC2")
904 	TEGRA210_MUX_ROUTES("AMX1 RX1")
905 	TEGRA210_MUX_ROUTES("AMX1 RX2")
906 	TEGRA210_MUX_ROUTES("AMX1 RX3")
907 	TEGRA210_MUX_ROUTES("AMX1 RX4")
908 	TEGRA210_MUX_ROUTES("AMX2 RX1")
909 	TEGRA210_MUX_ROUTES("AMX2 RX2")
910 	TEGRA210_MUX_ROUTES("AMX2 RX3")
911 	TEGRA210_MUX_ROUTES("AMX2 RX4")
912 	TEGRA210_MUX_ROUTES("ADX1")
913 	TEGRA210_MUX_ROUTES("ADX2")
914 	TEGRA210_MUX_ROUTES("MIXER1 RX1")
915 	TEGRA210_MUX_ROUTES("MIXER1 RX2")
916 	TEGRA210_MUX_ROUTES("MIXER1 RX3")
917 	TEGRA210_MUX_ROUTES("MIXER1 RX4")
918 	TEGRA210_MUX_ROUTES("MIXER1 RX5")
919 	TEGRA210_MUX_ROUTES("MIXER1 RX6")
920 	TEGRA210_MUX_ROUTES("MIXER1 RX7")
921 	TEGRA210_MUX_ROUTES("MIXER1 RX8")
922 	TEGRA210_MUX_ROUTES("MIXER1 RX9")
923 	TEGRA210_MUX_ROUTES("MIXER1 RX10")
924 };
925 
926 static const struct snd_soc_dapm_route tegra186_ahub_routes[] = {
927 	TEGRA_FE_ROUTES("ADMAIF1")
928 	TEGRA_FE_ROUTES("ADMAIF2")
929 	TEGRA_FE_ROUTES("ADMAIF3")
930 	TEGRA_FE_ROUTES("ADMAIF4")
931 	TEGRA_FE_ROUTES("ADMAIF5")
932 	TEGRA_FE_ROUTES("ADMAIF6")
933 	TEGRA_FE_ROUTES("ADMAIF7")
934 	TEGRA_FE_ROUTES("ADMAIF8")
935 	TEGRA_FE_ROUTES("ADMAIF9")
936 	TEGRA_FE_ROUTES("ADMAIF10")
937 	TEGRA_FE_ROUTES("ADMAIF11")
938 	TEGRA_FE_ROUTES("ADMAIF12")
939 	TEGRA_FE_ROUTES("ADMAIF13")
940 	TEGRA_FE_ROUTES("ADMAIF14")
941 	TEGRA_FE_ROUTES("ADMAIF15")
942 	TEGRA_FE_ROUTES("ADMAIF16")
943 	TEGRA_FE_ROUTES("ADMAIF17")
944 	TEGRA_FE_ROUTES("ADMAIF18")
945 	TEGRA_FE_ROUTES("ADMAIF19")
946 	TEGRA_FE_ROUTES("ADMAIF20")
947 	TEGRA186_MUX_ROUTES("ADMAIF1")
948 	TEGRA186_MUX_ROUTES("ADMAIF2")
949 	TEGRA186_MUX_ROUTES("ADMAIF3")
950 	TEGRA186_MUX_ROUTES("ADMAIF4")
951 	TEGRA186_MUX_ROUTES("ADMAIF5")
952 	TEGRA186_MUX_ROUTES("ADMAIF6")
953 	TEGRA186_MUX_ROUTES("ADMAIF7")
954 	TEGRA186_MUX_ROUTES("ADMAIF8")
955 	TEGRA186_MUX_ROUTES("ADMAIF9")
956 	TEGRA186_MUX_ROUTES("ADMAIF10")
957 	TEGRA186_MUX_ROUTES("ADMAIF11")
958 	TEGRA186_MUX_ROUTES("ADMAIF12")
959 	TEGRA186_MUX_ROUTES("ADMAIF13")
960 	TEGRA186_MUX_ROUTES("ADMAIF14")
961 	TEGRA186_MUX_ROUTES("ADMAIF15")
962 	TEGRA186_MUX_ROUTES("ADMAIF16")
963 	TEGRA186_MUX_ROUTES("ADMAIF17")
964 	TEGRA186_MUX_ROUTES("ADMAIF18")
965 	TEGRA186_MUX_ROUTES("ADMAIF19")
966 	TEGRA186_MUX_ROUTES("ADMAIF20")
967 	TEGRA186_MUX_ROUTES("I2S1")
968 	TEGRA186_MUX_ROUTES("I2S2")
969 	TEGRA186_MUX_ROUTES("I2S3")
970 	TEGRA186_MUX_ROUTES("I2S4")
971 	TEGRA186_MUX_ROUTES("I2S5")
972 	TEGRA186_MUX_ROUTES("I2S6")
973 	TEGRA186_MUX_ROUTES("DSPK1")
974 	TEGRA186_MUX_ROUTES("DSPK2")
975 	TEGRA186_MUX_ROUTES("SFC1")
976 	TEGRA186_MUX_ROUTES("SFC2")
977 	TEGRA186_MUX_ROUTES("SFC3")
978 	TEGRA186_MUX_ROUTES("SFC4")
979 	TEGRA186_MUX_ROUTES("MVC1")
980 	TEGRA186_MUX_ROUTES("MVC2")
981 	TEGRA186_MUX_ROUTES("AMX1 RX1")
982 	TEGRA186_MUX_ROUTES("AMX1 RX2")
983 	TEGRA186_MUX_ROUTES("AMX1 RX3")
984 	TEGRA186_MUX_ROUTES("AMX1 RX4")
985 	TEGRA186_MUX_ROUTES("AMX2 RX1")
986 	TEGRA186_MUX_ROUTES("AMX2 RX2")
987 	TEGRA186_MUX_ROUTES("AMX2 RX3")
988 	TEGRA186_MUX_ROUTES("AMX2 RX4")
989 	TEGRA186_MUX_ROUTES("AMX3 RX1")
990 	TEGRA186_MUX_ROUTES("AMX3 RX2")
991 	TEGRA186_MUX_ROUTES("AMX3 RX3")
992 	TEGRA186_MUX_ROUTES("AMX3 RX4")
993 	TEGRA186_MUX_ROUTES("AMX4 RX1")
994 	TEGRA186_MUX_ROUTES("AMX4 RX2")
995 	TEGRA186_MUX_ROUTES("AMX4 RX3")
996 	TEGRA186_MUX_ROUTES("AMX4 RX4")
997 	TEGRA186_MUX_ROUTES("ADX1")
998 	TEGRA186_MUX_ROUTES("ADX2")
999 	TEGRA186_MUX_ROUTES("ADX3")
1000 	TEGRA186_MUX_ROUTES("ADX4")
1001 	TEGRA186_MUX_ROUTES("MIXER1 RX1")
1002 	TEGRA186_MUX_ROUTES("MIXER1 RX2")
1003 	TEGRA186_MUX_ROUTES("MIXER1 RX3")
1004 	TEGRA186_MUX_ROUTES("MIXER1 RX4")
1005 	TEGRA186_MUX_ROUTES("MIXER1 RX5")
1006 	TEGRA186_MUX_ROUTES("MIXER1 RX6")
1007 	TEGRA186_MUX_ROUTES("MIXER1 RX7")
1008 	TEGRA186_MUX_ROUTES("MIXER1 RX8")
1009 	TEGRA186_MUX_ROUTES("MIXER1 RX9")
1010 	TEGRA186_MUX_ROUTES("MIXER1 RX10")
1011 };
1012 
1013 static const struct snd_soc_component_driver tegra210_ahub_component = {
1014 	.dapm_widgets		= tegra210_ahub_widgets,
1015 	.num_dapm_widgets	= ARRAY_SIZE(tegra210_ahub_widgets),
1016 	.dapm_routes		= tegra210_ahub_routes,
1017 	.num_dapm_routes	= ARRAY_SIZE(tegra210_ahub_routes),
1018 };
1019 
1020 static const struct snd_soc_component_driver tegra186_ahub_component = {
1021 	.dapm_widgets = tegra186_ahub_widgets,
1022 	.num_dapm_widgets = ARRAY_SIZE(tegra186_ahub_widgets),
1023 	.dapm_routes = tegra186_ahub_routes,
1024 	.num_dapm_routes = ARRAY_SIZE(tegra186_ahub_routes),
1025 };
1026 
1027 static const struct regmap_config tegra210_ahub_regmap_config = {
1028 	.reg_bits		= 32,
1029 	.val_bits		= 32,
1030 	.reg_stride		= 4,
1031 	.max_register		= TEGRA210_MAX_REGISTER_ADDR,
1032 	.cache_type		= REGCACHE_FLAT,
1033 };
1034 
1035 static const struct regmap_config tegra186_ahub_regmap_config = {
1036 	.reg_bits		= 32,
1037 	.val_bits		= 32,
1038 	.reg_stride		= 4,
1039 	.max_register		= TEGRA186_MAX_REGISTER_ADDR,
1040 	.cache_type		= REGCACHE_FLAT,
1041 };
1042 
1043 static const struct tegra_ahub_soc_data soc_data_tegra210 = {
1044 	.cmpnt_drv	= &tegra210_ahub_component,
1045 	.dai_drv	= tegra210_ahub_dais,
1046 	.num_dais	= ARRAY_SIZE(tegra210_ahub_dais),
1047 	.regmap_config	= &tegra210_ahub_regmap_config,
1048 	.mask[0]	= TEGRA210_XBAR_REG_MASK_0,
1049 	.mask[1]	= TEGRA210_XBAR_REG_MASK_1,
1050 	.mask[2]	= TEGRA210_XBAR_REG_MASK_2,
1051 	.mask[3]	= TEGRA210_XBAR_REG_MASK_3,
1052 	.reg_count	= TEGRA210_XBAR_UPDATE_MAX_REG,
1053 };
1054 
1055 static const struct tegra_ahub_soc_data soc_data_tegra186 = {
1056 	.cmpnt_drv	= &tegra186_ahub_component,
1057 	.dai_drv	= tegra186_ahub_dais,
1058 	.num_dais	= ARRAY_SIZE(tegra186_ahub_dais),
1059 	.regmap_config	= &tegra186_ahub_regmap_config,
1060 	.mask[0]	= TEGRA186_XBAR_REG_MASK_0,
1061 	.mask[1]	= TEGRA186_XBAR_REG_MASK_1,
1062 	.mask[2]	= TEGRA186_XBAR_REG_MASK_2,
1063 	.mask[3]	= TEGRA186_XBAR_REG_MASK_3,
1064 	.reg_count	= TEGRA186_XBAR_UPDATE_MAX_REG,
1065 };
1066 
1067 static const struct of_device_id tegra_ahub_of_match[] = {
1068 	{ .compatible = "nvidia,tegra210-ahub", .data = &soc_data_tegra210 },
1069 	{ .compatible = "nvidia,tegra186-ahub", .data = &soc_data_tegra186 },
1070 	{},
1071 };
1072 MODULE_DEVICE_TABLE(of, tegra_ahub_of_match);
1073 
1074 static int __maybe_unused tegra_ahub_runtime_suspend(struct device *dev)
1075 {
1076 	struct tegra_ahub *ahub = dev_get_drvdata(dev);
1077 
1078 	regcache_cache_only(ahub->regmap, true);
1079 	regcache_mark_dirty(ahub->regmap);
1080 
1081 	clk_disable_unprepare(ahub->clk);
1082 
1083 	return 0;
1084 }
1085 
1086 static int __maybe_unused tegra_ahub_runtime_resume(struct device *dev)
1087 {
1088 	struct tegra_ahub *ahub = dev_get_drvdata(dev);
1089 	int err;
1090 
1091 	err = clk_prepare_enable(ahub->clk);
1092 	if (err) {
1093 		dev_err(dev, "failed to enable AHUB clock, err: %d\n", err);
1094 		return err;
1095 	}
1096 
1097 	regcache_cache_only(ahub->regmap, false);
1098 	regcache_sync(ahub->regmap);
1099 
1100 	return 0;
1101 }
1102 
1103 static int tegra_ahub_probe(struct platform_device *pdev)
1104 {
1105 	struct tegra_ahub *ahub;
1106 	void __iomem *regs;
1107 	int err;
1108 
1109 	ahub = devm_kzalloc(&pdev->dev, sizeof(*ahub), GFP_KERNEL);
1110 	if (!ahub)
1111 		return -ENOMEM;
1112 
1113 	ahub->soc_data = of_device_get_match_data(&pdev->dev);
1114 
1115 	platform_set_drvdata(pdev, ahub);
1116 
1117 	ahub->clk = devm_clk_get(&pdev->dev, "ahub");
1118 	if (IS_ERR(ahub->clk)) {
1119 		dev_err(&pdev->dev, "can't retrieve AHUB clock\n");
1120 		return PTR_ERR(ahub->clk);
1121 	}
1122 
1123 	regs = devm_platform_ioremap_resource(pdev, 0);
1124 	if (IS_ERR(regs))
1125 		return PTR_ERR(regs);
1126 
1127 	ahub->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
1128 					     ahub->soc_data->regmap_config);
1129 	if (IS_ERR(ahub->regmap)) {
1130 		dev_err(&pdev->dev, "regmap init failed\n");
1131 		return PTR_ERR(ahub->regmap);
1132 	}
1133 
1134 	regcache_cache_only(ahub->regmap, true);
1135 
1136 	err = devm_snd_soc_register_component(&pdev->dev,
1137 					      ahub->soc_data->cmpnt_drv,
1138 					      ahub->soc_data->dai_drv,
1139 					      ahub->soc_data->num_dais);
1140 	if (err) {
1141 		dev_err(&pdev->dev, "can't register AHUB component, err: %d\n",
1142 			err);
1143 		return err;
1144 	}
1145 
1146 	err = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
1147 	if (err)
1148 		return err;
1149 
1150 	pm_runtime_enable(&pdev->dev);
1151 
1152 	return 0;
1153 }
1154 
1155 static int tegra_ahub_remove(struct platform_device *pdev)
1156 {
1157 	pm_runtime_disable(&pdev->dev);
1158 
1159 	return 0;
1160 }
1161 
1162 static const struct dev_pm_ops tegra_ahub_pm_ops = {
1163 	SET_RUNTIME_PM_OPS(tegra_ahub_runtime_suspend,
1164 			   tegra_ahub_runtime_resume, NULL)
1165 	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
1166 				pm_runtime_force_resume)
1167 };
1168 
1169 static struct platform_driver tegra_ahub_driver = {
1170 	.probe = tegra_ahub_probe,
1171 	.remove = tegra_ahub_remove,
1172 	.driver = {
1173 		.name = "tegra210-ahub",
1174 		.of_match_table = tegra_ahub_of_match,
1175 		.pm = &tegra_ahub_pm_ops,
1176 	},
1177 };
1178 module_platform_driver(tegra_ahub_driver);
1179 
1180 MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
1181 MODULE_AUTHOR("Mohan Kumar <mkumard@nvidia.com>");
1182 MODULE_DESCRIPTION("Tegra210 ASoC AHUB driver");
1183 MODULE_LICENSE("GPL v2");
1184