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