blob: 2eebae5613c797988625f627251c2edcf7d90c7a [file] [log] [blame]
Bharath Ramachandramurthy4d99b502012-05-04 18:52:52 -07001/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13
14#include <linux/init.h>
15#include <linux/err.h>
16#include <linux/module.h>
17#include <linux/moduleparam.h>
18#include <linux/platform_device.h>
19#include <linux/bitops.h>
20#include <linux/mutex.h>
21#include <sound/core.h>
22#include <sound/soc.h>
23#include <sound/soc-dapm.h>
24#include <sound/pcm.h>
25#include <sound/initval.h>
26#include <sound/control.h>
27#include <sound/q6adm-v2.h>
28#include <sound/q6asm-v2.h>
29#include <sound/q6afe-v2.h>
30#include <sound/tlv.h>
31#include "msm-pcm-routing-v2.h"
32#include "../qdsp6/q6voice.h"
33
34struct msm_pcm_routing_bdai_data {
35 u16 port_id; /* AFE port ID */
36 u8 active; /* track if this backend is enabled */
37 struct snd_pcm_hw_params *hw_params; /* to get freq and channel mode */
38 unsigned long fe_sessions; /* Front-end sessions */
39 unsigned long port_sessions; /* track Tx BE ports -> Rx BE */
40};
41
42#define INVALID_SESSION -1
43#define SESSION_TYPE_RX 0
44#define SESSION_TYPE_TX 1
45
46static struct mutex routing_lock;
47
48static int fm_switch_enable;
49
50#define INT_FM_RX_VOL_MAX_STEPS 100
51#define INT_FM_RX_VOL_GAIN 2000
52
53static int msm_route_fm_vol_control;
54static const DECLARE_TLV_DB_SCALE(fm_rx_vol_gain, 0,
55 INT_FM_RX_VOL_MAX_STEPS, 0);
56
57#define INT_RX_VOL_MAX_STEPS 100
58#define INT_RX_VOL_GAIN 0x2000
59
60static int msm_route_lpa_vol_control;
61static const DECLARE_TLV_DB_SCALE(lpa_rx_vol_gain, 0,
62 INT_RX_VOL_MAX_STEPS, 0);
63
64static int msm_route_multimedia2_vol_control;
65static const DECLARE_TLV_DB_SCALE(multimedia2_rx_vol_gain, 0,
66 INT_RX_VOL_MAX_STEPS, 0);
67
68static int msm_route_compressed_vol_control;
69static const DECLARE_TLV_DB_SCALE(compressed_rx_vol_gain, 0,
70 INT_RX_VOL_MAX_STEPS, 0);
71
72
73
74/* Equal to Frontend after last of the MULTIMEDIA SESSIONS */
75#define MAX_EQ_SESSIONS MSM_FRONTEND_DAI_CS_VOICE
76
77enum {
78 EQ_BAND1 = 0,
79 EQ_BAND2,
80 EQ_BAND3,
81 EQ_BAND4,
82 EQ_BAND5,
83 EQ_BAND6,
84 EQ_BAND7,
85 EQ_BAND8,
86 EQ_BAND9,
87 EQ_BAND10,
88 EQ_BAND11,
89 EQ_BAND12,
90 EQ_BAND_MAX,
91};
92
93struct msm_audio_eq_band {
94 uint16_t band_idx; /* The band index, 0 .. 11 */
95 uint32_t filter_type; /* Filter band type */
96 uint32_t center_freq_hz; /* Filter band center frequency */
97 uint32_t filter_gain; /* Filter band initial gain (dB) */
98 /* Range is +12 dB to -12 dB with 1dB increments. */
99 uint32_t q_factor;
100} __packed;
101
102struct msm_audio_eq_stream_config {
103 uint32_t enable; /* Number of consequtive bands specified */
104 uint32_t num_bands;
105 struct msm_audio_eq_band eq_bands[EQ_BAND_MAX];
106} __packed;
107
108struct msm_audio_eq_stream_config eq_data[MAX_EQ_SESSIONS];
109
110static void msm_send_eq_values(int eq_idx);
111/* This array is indexed by back-end DAI ID defined in msm-pcm-routing.h
112 * If new back-end is defined, add new back-end DAI ID at the end of enum
113 */
114static struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = {
115 { PRIMARY_I2S_RX, 0, NULL, 0, 0},
116 { PRIMARY_I2S_TX, 0, NULL, 0, 0},
117 { SLIMBUS_0_RX, 0, NULL, 0, 0},
118 { SLIMBUS_0_TX, 0, NULL, 0, 0},
119 { HDMI_RX, 0, NULL, 0, 0},
120 { INT_BT_SCO_RX, 0, NULL, 0, 0},
121 { INT_BT_SCO_TX, 0, NULL, 0, 0},
122 { INT_FM_RX, 0, NULL, 0, 0},
123 { INT_FM_TX, 0, NULL, 0, 0},
124 { RT_PROXY_PORT_001_RX, 0, NULL, 0, 0},
125 { RT_PROXY_PORT_001_TX, 0, NULL, 0, 0},
126 { PCM_RX, 0, NULL, 0, 0},
127 { PCM_TX, 0, NULL, 0, 0},
128 { VOICE_PLAYBACK_TX, 0, NULL, 0, 0},
129 { VOICE_RECORD_RX, 0, NULL, 0, 0},
130 { VOICE_RECORD_TX, 0, NULL, 0, 0},
131 { MI2S_RX, 0, NULL, 0, 0},
132 { SECONDARY_I2S_RX, 0, NULL, 0, 0},
133 { SLIMBUS_1_RX, 0, NULL, 0, 0},
134 { SLIMBUS_1_TX, 0, NULL, 0, 0},
135 { SLIMBUS_INVALID, 0, NULL, 0, 0},
136};
137
138
139/* Track ASM playback & capture sessions of DAI */
140static int fe_dai_map[MSM_FRONTEND_DAI_MM_SIZE][2] = {
141 /* MULTIMEDIA1 */
142 {INVALID_SESSION, INVALID_SESSION},
143 /* MULTIMEDIA2 */
144 {INVALID_SESSION, INVALID_SESSION},
145 /* MULTIMEDIA3 */
146 {INVALID_SESSION, INVALID_SESSION},
147 /* MULTIMEDIA4 */
148 {INVALID_SESSION, INVALID_SESSION},
149};
150
151static void msm_pcm_routing_build_matrix(int fedai_id, int dspst_id,
152 int path_type)
153{
154 int i, port_type;
155 struct route_payload payload;
156
157 payload.num_copps = 0;
158 port_type = (path_type == ADM_PATH_PLAYBACK ?
159 MSM_AFE_PORT_TYPE_RX : MSM_AFE_PORT_TYPE_TX);
160
161 for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) {
162 if ((afe_get_port_type(msm_bedais[i].port_id) ==
163 port_type) &&
164 msm_bedais[i].active && (test_bit(fedai_id,
165 &msm_bedais[i].fe_sessions)))
166 payload.copp_ids[payload.num_copps++] =
167 msm_bedais[i].port_id;
168 }
169
170 if (payload.num_copps)
171 adm_matrix_map(dspst_id, path_type,
172 payload.num_copps, payload.copp_ids, 0);
173}
174
175void msm_pcm_routing_reg_phy_stream(int fedai_id, int dspst_id, int stream_type)
176{
177 int i, session_type, path_type, port_type;
178 struct route_payload payload;
179 u32 channels;
180
181 if (fedai_id > MSM_FRONTEND_DAI_MM_MAX_ID) {
182 /* bad ID assigned in machine driver */
183 pr_err("%s: bad MM ID %d\n", __func__, fedai_id);
184 return;
185 }
186
187 if (stream_type == SNDRV_PCM_STREAM_PLAYBACK) {
188 session_type = SESSION_TYPE_RX;
189 path_type = ADM_PATH_PLAYBACK;
190 port_type = MSM_AFE_PORT_TYPE_RX;
191 } else {
192 session_type = SESSION_TYPE_TX;
193 path_type = ADM_PATH_LIVE_REC;
194 port_type = MSM_AFE_PORT_TYPE_TX;
195 }
196
197 mutex_lock(&routing_lock);
198
199 payload.num_copps = 0; /* only RX needs to use payload */
200 fe_dai_map[fedai_id][session_type] = dspst_id;
201 /* re-enable EQ if active */
202 if (eq_data[fedai_id].enable)
203 msm_send_eq_values(fedai_id);
204 for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) {
205 if ((afe_get_port_type(msm_bedais[i].port_id) ==
206 port_type) && msm_bedais[i].active &&
207 (test_bit(fedai_id,
208 &msm_bedais[i].fe_sessions))) {
209
210 channels = params_channels(msm_bedais[i].hw_params);
211
212 if ((stream_type == SNDRV_PCM_STREAM_PLAYBACK) &&
213 (channels > 2))
214 adm_multi_ch_copp_open(msm_bedais[i].port_id,
215 path_type,
216 params_rate(msm_bedais[i].hw_params),
217 channels,
218 DEFAULT_COPP_TOPOLOGY);
219 else
220 adm_open(msm_bedais[i].port_id,
221 path_type,
222 params_rate(msm_bedais[i].hw_params),
223 params_channels(msm_bedais[i].hw_params),
224 DEFAULT_COPP_TOPOLOGY);
225
226 payload.copp_ids[payload.num_copps++] =
227 msm_bedais[i].port_id;
228 }
229 }
230 if (payload.num_copps)
231 adm_matrix_map(dspst_id, path_type,
232 payload.num_copps, payload.copp_ids, 0);
233
234 mutex_unlock(&routing_lock);
235}
236
237void msm_pcm_routing_dereg_phy_stream(int fedai_id, int stream_type)
238{
239 int i, port_type, session_type;
240
241 if (fedai_id > MSM_FRONTEND_DAI_MM_MAX_ID) {
242 /* bad ID assigned in machine driver */
243 pr_err("%s: bad MM ID\n", __func__);
244 return;
245 }
246
247 if (stream_type == SNDRV_PCM_STREAM_PLAYBACK) {
248 port_type = MSM_AFE_PORT_TYPE_RX;
249 session_type = SESSION_TYPE_RX;
250 } else {
251 port_type = MSM_AFE_PORT_TYPE_TX;
252 session_type = SESSION_TYPE_TX;
253 }
254
255 mutex_lock(&routing_lock);
256
257 for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) {
258 if ((afe_get_port_type(msm_bedais[i].port_id) ==
259 port_type) && msm_bedais[i].active &&
260 (test_bit(fedai_id,
261 &msm_bedais[i].fe_sessions)))
262 adm_close(msm_bedais[i].port_id);
263 }
264
265 fe_dai_map[fedai_id][session_type] = INVALID_SESSION;
266
267 mutex_unlock(&routing_lock);
268}
269
270/* Check if FE/BE route is set */
271static bool msm_pcm_routing_route_is_set(u16 be_id, u16 fe_id)
272{
273 bool rc = false;
274
275 if (fe_id > MSM_FRONTEND_DAI_MM_MAX_ID) {
276 /* recheck FE ID in the mixer control defined in this file */
277 pr_err("%s: bad MM ID\n", __func__);
278 return rc;
279 }
280
281 if (test_bit(fe_id, &msm_bedais[be_id].fe_sessions))
282 rc = true;
283
284 return rc;
285}
286
287static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set)
288{
289 int session_type, path_type;
290 u32 channels;
291
292 pr_debug("%s: reg %x val %x set %x\n", __func__, reg, val, set);
293
294 if (val > MSM_FRONTEND_DAI_MM_MAX_ID) {
295 /* recheck FE ID in the mixer control defined in this file */
296 pr_err("%s: bad MM ID\n", __func__);
297 return;
298 }
299
300 if (afe_get_port_type(msm_bedais[reg].port_id) ==
301 MSM_AFE_PORT_TYPE_RX) {
302 session_type = SESSION_TYPE_RX;
303 path_type = ADM_PATH_PLAYBACK;
304 } else {
305 session_type = SESSION_TYPE_TX;
306 path_type = ADM_PATH_LIVE_REC;
307 }
308
309 mutex_lock(&routing_lock);
310
311 if (set) {
312 set_bit(val, &msm_bedais[reg].fe_sessions);
313 if (msm_bedais[reg].active && fe_dai_map[val][session_type] !=
314 INVALID_SESSION) {
315
316 channels = params_channels(msm_bedais[reg].hw_params);
317
318 if ((session_type == SESSION_TYPE_RX) && (channels > 2))
319 adm_multi_ch_copp_open(msm_bedais[reg].port_id,
320 path_type,
321 params_rate(msm_bedais[reg].hw_params),
322 channels,
323 DEFAULT_COPP_TOPOLOGY);
324 else
325 adm_open(msm_bedais[reg].port_id,
326 path_type,
327 params_rate(msm_bedais[reg].hw_params),
328 params_channels(msm_bedais[reg].hw_params),
329 DEFAULT_COPP_TOPOLOGY);
330
331 msm_pcm_routing_build_matrix(val,
332 fe_dai_map[val][session_type], path_type);
333 }
334 } else {
335 clear_bit(val, &msm_bedais[reg].fe_sessions);
336 if (msm_bedais[reg].active && fe_dai_map[val][session_type] !=
337 INVALID_SESSION) {
338 adm_close(msm_bedais[reg].port_id);
339 msm_pcm_routing_build_matrix(val,
340 fe_dai_map[val][session_type], path_type);
341 }
342 }
343 mutex_unlock(&routing_lock);
344}
345
346static int msm_routing_get_audio_mixer(struct snd_kcontrol *kcontrol,
347 struct snd_ctl_elem_value *ucontrol)
348{
349 struct soc_mixer_control *mc =
350 (struct soc_mixer_control *)kcontrol->private_value;
351
352 if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions))
353 ucontrol->value.integer.value[0] = 1;
354 else
355 ucontrol->value.integer.value[0] = 0;
356
357 pr_info("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift,
358 ucontrol->value.integer.value[0]);
359
360 return 0;
361}
362
363static int msm_routing_put_audio_mixer(struct snd_kcontrol *kcontrol,
364 struct snd_ctl_elem_value *ucontrol)
365{
366 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
367 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
368 struct soc_mixer_control *mc =
369 (struct soc_mixer_control *)kcontrol->private_value;
370
371
372 if (ucontrol->value.integer.value[0] &&
373 msm_pcm_routing_route_is_set(mc->reg, mc->shift) == false) {
374 msm_pcm_routing_process_audio(mc->reg, mc->shift, 1);
375 snd_soc_dapm_mixer_update_power(widget, kcontrol, 1);
376 } else if (!ucontrol->value.integer.value[0] &&
377 msm_pcm_routing_route_is_set(mc->reg, mc->shift) == true) {
378 msm_pcm_routing_process_audio(mc->reg, mc->shift, 0);
379 snd_soc_dapm_mixer_update_power(widget, kcontrol, 0);
380 }
381 pr_info("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift,
382 ucontrol->value.integer.value[0]);
383
384 return 1;
385}
386
387static void msm_pcm_routing_process_voice(u16 reg, u16 val, int set)
388{
389 return;
390}
391
392static int msm_routing_get_voice_mixer(struct snd_kcontrol *kcontrol,
393 struct snd_ctl_elem_value *ucontrol)
394{
395 struct soc_mixer_control *mc =
396 (struct soc_mixer_control *)kcontrol->private_value;
397
398 mutex_lock(&routing_lock);
399
400 if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions))
401 ucontrol->value.integer.value[0] = 1;
402 else
403 ucontrol->value.integer.value[0] = 0;
404
405 mutex_unlock(&routing_lock);
406
407 pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift,
408 ucontrol->value.integer.value[0]);
409
410 return 0;
411}
412
413static int msm_routing_put_voice_mixer(struct snd_kcontrol *kcontrol,
414 struct snd_ctl_elem_value *ucontrol)
415{
416 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
417 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
418 struct soc_mixer_control *mc =
419 (struct soc_mixer_control *)kcontrol->private_value;
420
421 if (ucontrol->value.integer.value[0]) {
422 msm_pcm_routing_process_voice(mc->reg, mc->shift, 1);
423 snd_soc_dapm_mixer_update_power(widget, kcontrol, 1);
424 } else {
425 msm_pcm_routing_process_voice(mc->reg, mc->shift, 0);
426 snd_soc_dapm_mixer_update_power(widget, kcontrol, 0);
427 }
428
429 return 1;
430}
431
432static int msm_routing_get_voice_stub_mixer(struct snd_kcontrol *kcontrol,
433 struct snd_ctl_elem_value *ucontrol)
434{
435 struct soc_mixer_control *mc =
436 (struct soc_mixer_control *)kcontrol->private_value;
437
438 mutex_lock(&routing_lock);
439
440 if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions))
441 ucontrol->value.integer.value[0] = 1;
442 else
443 ucontrol->value.integer.value[0] = 0;
444
445 mutex_unlock(&routing_lock);
446
447 pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift,
448 ucontrol->value.integer.value[0]);
449
450 return 0;
451}
452
453static int msm_routing_put_voice_stub_mixer(struct snd_kcontrol *kcontrol,
454 struct snd_ctl_elem_value *ucontrol)
455{
456 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
457 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
458 struct soc_mixer_control *mc =
459 (struct soc_mixer_control *)kcontrol->private_value;
460
461 if (ucontrol->value.integer.value[0]) {
462 mutex_lock(&routing_lock);
463 set_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions);
464 mutex_unlock(&routing_lock);
465
466 snd_soc_dapm_mixer_update_power(widget, kcontrol, 1);
467 } else {
468 mutex_lock(&routing_lock);
469 clear_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions);
470 mutex_unlock(&routing_lock);
471
472 snd_soc_dapm_mixer_update_power(widget, kcontrol, 0);
473 }
474
475 pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift,
476 ucontrol->value.integer.value[0]);
477
478 return 1;
479}
480
481static int msm_routing_get_switch_mixer(struct snd_kcontrol *kcontrol,
482 struct snd_ctl_elem_value *ucontrol)
483{
484 ucontrol->value.integer.value[0] = fm_switch_enable;
485 pr_debug("%s: FM Switch enable %ld\n", __func__,
486 ucontrol->value.integer.value[0]);
487 return 0;
488}
489
490static int msm_routing_put_switch_mixer(struct snd_kcontrol *kcontrol,
491 struct snd_ctl_elem_value *ucontrol)
492{
493 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
494 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
495
496 pr_debug("%s: FM Switch enable %ld\n", __func__,
497 ucontrol->value.integer.value[0]);
498 if (ucontrol->value.integer.value[0])
499 snd_soc_dapm_mixer_update_power(widget, kcontrol, 1);
500 else
501 snd_soc_dapm_mixer_update_power(widget, kcontrol, 0);
502 fm_switch_enable = ucontrol->value.integer.value[0];
503 return 1;
504}
505
506static int msm_routing_get_port_mixer(struct snd_kcontrol *kcontrol,
507 struct snd_ctl_elem_value *ucontrol)
508{
509 struct soc_mixer_control *mc =
510 (struct soc_mixer_control *)kcontrol->private_value;
511
512 if (test_bit(mc->shift, &msm_bedais[mc->reg].port_sessions))
513 ucontrol->value.integer.value[0] = 1;
514 else
515 ucontrol->value.integer.value[0] = 0;
516
517 pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift,
518 ucontrol->value.integer.value[0]);
519
520 return 0;
521}
522
523static int msm_routing_put_port_mixer(struct snd_kcontrol *kcontrol,
524 struct snd_ctl_elem_value *ucontrol)
525{
526 struct soc_mixer_control *mc =
527 (struct soc_mixer_control *)kcontrol->private_value;
528
529 pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg,
530 mc->shift, ucontrol->value.integer.value[0]);
531
532 if (ucontrol->value.integer.value[0]) {
533 afe_loopback(1, msm_bedais[mc->reg].port_id,
534 msm_bedais[mc->shift].port_id);
535 set_bit(mc->shift,
536 &msm_bedais[mc->reg].port_sessions);
537 } else {
538 afe_loopback(0, msm_bedais[mc->reg].port_id,
539 msm_bedais[mc->shift].port_id);
540 clear_bit(mc->shift,
541 &msm_bedais[mc->reg].port_sessions);
542 }
543
544 return 1;
545}
546
547static int msm_routing_get_fm_vol_mixer(struct snd_kcontrol *kcontrol,
548 struct snd_ctl_elem_value *ucontrol)
549{
550 ucontrol->value.integer.value[0] = msm_route_fm_vol_control;
551 return 0;
552}
553
554static int msm_routing_set_fm_vol_mixer(struct snd_kcontrol *kcontrol,
555 struct snd_ctl_elem_value *ucontrol)
556{
557 afe_loopback_gain(INT_FM_TX , ucontrol->value.integer.value[0]);
558
559 msm_route_fm_vol_control = ucontrol->value.integer.value[0];
560
561 return 0;
562}
563
564static int msm_routing_get_lpa_vol_mixer(struct snd_kcontrol *kcontrol,
565 struct snd_ctl_elem_value *ucontrol)
566{
567 ucontrol->value.integer.value[0] = msm_route_lpa_vol_control;
568 return 0;
569}
570
571static int msm_routing_set_lpa_vol_mixer(struct snd_kcontrol *kcontrol,
572 struct snd_ctl_elem_value *ucontrol)
573{
574 if (!lpa_set_volume(ucontrol->value.integer.value[0]))
575 msm_route_lpa_vol_control =
576 ucontrol->value.integer.value[0];
577
578 return 0;
579
580}
581
582static int msm_routing_get_multimedia2_vol_mixer(struct snd_kcontrol *kcontrol,
583 struct snd_ctl_elem_value *ucontrol)
584{
585
586 ucontrol->value.integer.value[0] = msm_route_multimedia2_vol_control;
587 return 0;
588}
589
590static int msm_routing_set_multimedia2_vol_mixer(struct snd_kcontrol *kcontrol,
591 struct snd_ctl_elem_value *ucontrol)
592{
593 if (!multi_ch_pcm_set_volume(ucontrol->value.integer.value[0]))
594 msm_route_multimedia2_vol_control =
595 ucontrol->value.integer.value[0];
596 return 0;
597}
598
599static int msm_routing_get_compressed_vol_mixer(struct snd_kcontrol *kcontrol,
600 struct snd_ctl_elem_value *ucontrol)
601{
602
603 ucontrol->value.integer.value[0] = msm_route_compressed_vol_control;
604 return 0;
605}
606
607static int msm_routing_set_compressed_vol_mixer(struct snd_kcontrol *kcontrol,
608 struct snd_ctl_elem_value *ucontrol)
609{
610 if (!compressed_set_volume(ucontrol->value.integer.value[0]))
611 msm_route_compressed_vol_control =
612 ucontrol->value.integer.value[0];
613 return 0;
614}
615
616static void msm_send_eq_values(int eq_idx)
617{
618 int result;
619 struct audio_client *ac =
620 q6asm_get_audio_client(fe_dai_map[eq_idx][SESSION_TYPE_RX]);
621
622 if (ac == NULL) {
623 pr_err("%s: Could not get audio client for session: %d\n",
624 __func__, fe_dai_map[eq_idx][SESSION_TYPE_RX]);
625 goto done;
626 }
627
628 result = q6asm_equalizer(ac, &eq_data[eq_idx]);
629
630 if (result < 0)
631 pr_err("%s: Call to ASM equalizer failed, returned = %d\n",
632 __func__, result);
633done:
634 return;
635}
636
637static int msm_routing_get_eq_enable_mixer(struct snd_kcontrol *kcontrol,
638 struct snd_ctl_elem_value *ucontrol)
639{
640 int eq_idx = ((struct soc_multi_mixer_control *)
641 kcontrol->private_value)->reg;
642
643 ucontrol->value.integer.value[0] = eq_data[eq_idx].enable;
644
645 pr_debug("%s: EQ #%d enable %d\n", __func__,
646 eq_idx, eq_data[eq_idx].enable);
647 return 0;
648}
649
650static int msm_routing_put_eq_enable_mixer(struct snd_kcontrol *kcontrol,
651 struct snd_ctl_elem_value *ucontrol)
652{
653 int eq_idx = ((struct soc_multi_mixer_control *)
654 kcontrol->private_value)->reg;
655 int value = ucontrol->value.integer.value[0];
656
657 pr_debug("%s: EQ #%d enable %d\n", __func__,
658 eq_idx, value);
659 eq_data[eq_idx].enable = value;
660
661 msm_send_eq_values(eq_idx);
662 return 0;
663}
664
665static int msm_routing_get_eq_band_count_audio_mixer(
666 struct snd_kcontrol *kcontrol,
667 struct snd_ctl_elem_value *ucontrol)
668{
669 int eq_idx = ((struct soc_multi_mixer_control *)
670 kcontrol->private_value)->reg;
671
672 ucontrol->value.integer.value[0] = eq_data[eq_idx].num_bands;
673
674 pr_debug("%s: EQ #%d bands %d\n", __func__,
675 eq_idx, eq_data[eq_idx].num_bands);
676 return eq_data[eq_idx].num_bands;
677}
678
679static int msm_routing_put_eq_band_count_audio_mixer(
680 struct snd_kcontrol *kcontrol,
681 struct snd_ctl_elem_value *ucontrol)
682{
683 int eq_idx = ((struct soc_multi_mixer_control *)
684 kcontrol->private_value)->reg;
685 int value = ucontrol->value.integer.value[0];
686
687 pr_debug("%s: EQ #%d bands %d\n", __func__,
688 eq_idx, value);
689 eq_data[eq_idx].num_bands = value;
690 return 0;
691}
692
693static int msm_routing_get_eq_band_audio_mixer(struct snd_kcontrol *kcontrol,
694 struct snd_ctl_elem_value *ucontrol)
695{
696 int eq_idx = ((struct soc_multi_mixer_control *)
697 kcontrol->private_value)->reg;
698 int band_idx = ((struct soc_multi_mixer_control *)
699 kcontrol->private_value)->shift;
700
701 ucontrol->value.integer.value[0] =
702 eq_data[eq_idx].eq_bands[band_idx].band_idx;
703 ucontrol->value.integer.value[1] =
704 eq_data[eq_idx].eq_bands[band_idx].filter_type;
705 ucontrol->value.integer.value[2] =
706 eq_data[eq_idx].eq_bands[band_idx].center_freq_hz;
707 ucontrol->value.integer.value[3] =
708 eq_data[eq_idx].eq_bands[band_idx].filter_gain;
709 ucontrol->value.integer.value[4] =
710 eq_data[eq_idx].eq_bands[band_idx].q_factor;
711
712 pr_debug("%s: band_idx = %d\n", __func__,
713 eq_data[eq_idx].eq_bands[band_idx].band_idx);
714 pr_debug("%s: filter_type = %d\n", __func__,
715 eq_data[eq_idx].eq_bands[band_idx].filter_type);
716 pr_debug("%s: center_freq_hz = %d\n", __func__,
717 eq_data[eq_idx].eq_bands[band_idx].center_freq_hz);
718 pr_debug("%s: filter_gain = %d\n", __func__,
719 eq_data[eq_idx].eq_bands[band_idx].filter_gain);
720 pr_debug("%s: q_factor = %d\n", __func__,
721 eq_data[eq_idx].eq_bands[band_idx].q_factor);
722 return 0;
723}
724
725static int msm_routing_put_eq_band_audio_mixer(struct snd_kcontrol *kcontrol,
726 struct snd_ctl_elem_value *ucontrol)
727{
728 int eq_idx = ((struct soc_multi_mixer_control *)
729 kcontrol->private_value)->reg;
730 int band_idx = ((struct soc_multi_mixer_control *)
731 kcontrol->private_value)->shift;
732
733 eq_data[eq_idx].eq_bands[band_idx].band_idx =
734 ucontrol->value.integer.value[0];
735 eq_data[eq_idx].eq_bands[band_idx].filter_type =
736 ucontrol->value.integer.value[1];
737 eq_data[eq_idx].eq_bands[band_idx].center_freq_hz =
738 ucontrol->value.integer.value[2];
739 eq_data[eq_idx].eq_bands[band_idx].filter_gain =
740 ucontrol->value.integer.value[3];
741 eq_data[eq_idx].eq_bands[band_idx].q_factor =
742 ucontrol->value.integer.value[4];
743 return 0;
744}
745
746static const struct snd_kcontrol_new pri_i2s_rx_mixer_controls[] = {
747 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_PRI_I2S_RX ,
748 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
749 msm_routing_put_audio_mixer),
750 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_PRI_I2S_RX,
751 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
752 msm_routing_put_audio_mixer),
753 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_PRI_I2S_RX,
754 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
755 msm_routing_put_audio_mixer),
756 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_PRI_I2S_RX,
757 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
758 msm_routing_put_audio_mixer),
759};
760
761static const struct snd_kcontrol_new sec_i2s_rx_mixer_controls[] = {
762 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SEC_I2S_RX ,
763 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
764 msm_routing_put_audio_mixer),
765 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SEC_I2S_RX,
766 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
767 msm_routing_put_audio_mixer),
768 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SEC_I2S_RX,
769 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
770 msm_routing_put_audio_mixer),
771 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SEC_I2S_RX,
772 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
773 msm_routing_put_audio_mixer),
774};
775
776static const struct snd_kcontrol_new slimbus_rx_mixer_controls[] = {
777 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SLIMBUS_0_RX ,
778 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
779 msm_routing_put_audio_mixer),
780 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SLIMBUS_0_RX,
781 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
782 msm_routing_put_audio_mixer),
783 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SLIMBUS_0_RX,
784 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
785 msm_routing_put_audio_mixer),
786 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SLIMBUS_0_RX,
787 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
788 msm_routing_put_audio_mixer),
789};
790
791static const struct snd_kcontrol_new mi2s_rx_mixer_controls[] = {
792 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_MI2S_RX ,
793 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
794 msm_routing_put_audio_mixer),
795 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_MI2S_RX,
796 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
797 msm_routing_put_audio_mixer),
798 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_MI2S_RX,
799 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
800 msm_routing_put_audio_mixer),
801 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_MI2S_RX,
802 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
803 msm_routing_put_audio_mixer),
804};
805
806static const struct snd_kcontrol_new hdmi_mixer_controls[] = {
807 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_HDMI_RX,
808 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
809 msm_routing_put_audio_mixer),
810 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_HDMI_RX,
811 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
812 msm_routing_put_audio_mixer),
813 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_HDMI_RX,
814 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
815 msm_routing_put_audio_mixer),
816 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_HDMI_RX,
817 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
818 msm_routing_put_audio_mixer),
819};
820 /* incall music delivery mixer */
821static const struct snd_kcontrol_new incall_music_delivery_mixer_controls[] = {
822 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_VOICE_PLAYBACK_TX,
823 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
824 msm_routing_put_audio_mixer),
825 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_VOICE_PLAYBACK_TX,
826 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
827 msm_routing_put_audio_mixer),
828};
829
830static const struct snd_kcontrol_new int_bt_sco_rx_mixer_controls[] = {
831 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_INT_BT_SCO_RX,
832 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
833 msm_routing_put_audio_mixer),
834 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_INT_BT_SCO_RX,
835 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
836 msm_routing_put_audio_mixer),
837 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_INT_BT_SCO_RX,
838 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
839 msm_routing_put_audio_mixer),
840 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_INT_BT_SCO_RX,
841 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
842 msm_routing_put_audio_mixer),
843};
844
845static const struct snd_kcontrol_new int_fm_rx_mixer_controls[] = {
846 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_INT_FM_RX,
847 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
848 msm_routing_put_audio_mixer),
849 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_INT_FM_RX,
850 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
851 msm_routing_put_audio_mixer),
852 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_INT_FM_RX,
853 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
854 msm_routing_put_audio_mixer),
855 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_INT_FM_RX,
856 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
857 msm_routing_put_audio_mixer),
858};
859
860static const struct snd_kcontrol_new afe_pcm_rx_mixer_controls[] = {
861 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_AFE_PCM_RX,
862 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
863 msm_routing_put_audio_mixer),
864 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_AFE_PCM_RX,
865 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
866 msm_routing_put_audio_mixer),
867 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_AFE_PCM_RX,
868 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
869 msm_routing_put_audio_mixer),
870 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_AFE_PCM_RX,
871 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
872 msm_routing_put_audio_mixer),
873};
874
875static const struct snd_kcontrol_new auxpcm_rx_mixer_controls[] = {
876 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_AUXPCM_RX,
877 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
878 msm_routing_put_audio_mixer),
879 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_AUXPCM_RX,
880 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
881 msm_routing_put_audio_mixer),
882 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_AUXPCM_RX,
883 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
884 msm_routing_put_audio_mixer),
885 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_AUXPCM_RX,
886 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
887 msm_routing_put_audio_mixer),
888};
889
890static const struct snd_kcontrol_new mmul1_mixer_controls[] = {
891 SOC_SINGLE_EXT("PRI_TX", MSM_BACKEND_DAI_PRI_I2S_TX,
892 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
893 msm_routing_put_audio_mixer),
894 SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX,
895 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
896 msm_routing_put_audio_mixer),
897 SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_AUXPCM_TX,
898 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
899 msm_routing_put_audio_mixer),
900 SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX,
901 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
902 msm_routing_put_audio_mixer),
903 SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX,
904 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
905 msm_routing_put_audio_mixer),
906 SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX,
907 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
908 msm_routing_put_audio_mixer),
909 SOC_SINGLE_EXT("VOC_REC_DL", MSM_BACKEND_DAI_INCALL_RECORD_RX,
910 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
911 msm_routing_put_audio_mixer),
912 SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX,
913 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
914 msm_routing_put_audio_mixer),
915};
916
917static const struct snd_kcontrol_new mmul2_mixer_controls[] = {
918 SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX,
919 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
920 msm_routing_put_audio_mixer),
921};
922
923static const struct snd_kcontrol_new pri_rx_voice_mixer_controls[] = {
924 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_PRI_I2S_RX,
925 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
926 msm_routing_put_voice_mixer),
927 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_PRI_I2S_RX,
928 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
929 msm_routing_put_voice_mixer),
930};
931
932static const struct snd_kcontrol_new sec_i2s_rx_voice_mixer_controls[] = {
933 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_SEC_I2S_RX,
934 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
935 msm_routing_put_voice_mixer),
936 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SEC_I2S_RX,
937 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
938 msm_routing_put_voice_mixer),
939};
940
941static const struct snd_kcontrol_new slimbus_rx_voice_mixer_controls[] = {
942 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_SLIMBUS_0_RX,
943 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
944 msm_routing_put_voice_mixer),
945 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SLIMBUS_0_RX ,
946 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
947 msm_routing_put_voice_mixer),
948};
949
950static const struct snd_kcontrol_new bt_sco_rx_voice_mixer_controls[] = {
951 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_INT_BT_SCO_RX,
952 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
953 msm_routing_put_voice_mixer),
954 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_INT_BT_SCO_RX ,
955 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
956 msm_routing_put_voice_mixer),
957 SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_INT_BT_SCO_RX,
958 MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
959 msm_routing_put_voice_stub_mixer),
960};
961
962static const struct snd_kcontrol_new afe_pcm_rx_voice_mixer_controls[] = {
963 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_AFE_PCM_RX,
964 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
965 msm_routing_put_voice_mixer),
966 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_AFE_PCM_RX,
967 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
968 msm_routing_put_voice_mixer),
969 SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_AFE_PCM_RX,
970 MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
971 msm_routing_put_voice_stub_mixer),
972};
973
974static const struct snd_kcontrol_new aux_pcm_rx_voice_mixer_controls[] = {
975 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_AUXPCM_RX,
976 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
977 msm_routing_put_voice_mixer),
978 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_AUXPCM_RX,
979 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
980 msm_routing_put_voice_mixer),
981 SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_AUXPCM_RX,
982 MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
983 msm_routing_put_voice_stub_mixer),
984};
985
986static const struct snd_kcontrol_new hdmi_rx_voice_mixer_controls[] = {
987 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_HDMI_RX,
988 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
989 msm_routing_put_voice_mixer),
990 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_HDMI_RX,
991 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
992 msm_routing_put_voice_mixer),
993};
994
995static const struct snd_kcontrol_new stub_rx_mixer_controls[] = {
996 SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_INVALID,
997 MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
998 msm_routing_put_voice_stub_mixer),
999};
1000
1001static const struct snd_kcontrol_new slimbus_1_rx_mixer_controls[] = {
1002 SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_SLIMBUS_1_RX,
1003 MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
1004 msm_routing_put_voice_stub_mixer),
1005};
1006
1007static const struct snd_kcontrol_new tx_voice_mixer_controls[] = {
1008 SOC_SINGLE_EXT("PRI_TX_Voice", MSM_BACKEND_DAI_PRI_I2S_TX,
1009 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
1010 msm_routing_put_voice_mixer),
1011 SOC_SINGLE_EXT("SLIM_0_TX_Voice", MSM_BACKEND_DAI_SLIMBUS_0_TX,
1012 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
1013 msm_routing_put_voice_mixer),
1014 SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_Voice",
1015 MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_CS_VOICE, 1, 0,
1016 msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
1017 SOC_SINGLE_EXT("AFE_PCM_TX_Voice", MSM_BACKEND_DAI_AFE_PCM_TX,
1018 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
1019 msm_routing_put_voice_mixer),
1020 SOC_SINGLE_EXT("AUX_PCM_TX_Voice", MSM_BACKEND_DAI_AUXPCM_TX,
1021 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
1022 msm_routing_put_voice_mixer),
1023};
1024
1025static const struct snd_kcontrol_new tx_voip_mixer_controls[] = {
1026 SOC_SINGLE_EXT("PRI_TX_Voip", MSM_BACKEND_DAI_PRI_I2S_TX,
1027 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
1028 msm_routing_put_voice_mixer),
1029 SOC_SINGLE_EXT("SLIM_0_TX_Voip", MSM_BACKEND_DAI_SLIMBUS_0_TX,
1030 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
1031 msm_routing_put_voice_mixer),
1032 SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_Voip", MSM_BACKEND_DAI_INT_BT_SCO_TX,
1033 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
1034 msm_routing_put_voice_mixer),
1035 SOC_SINGLE_EXT("AFE_PCM_TX_Voip", MSM_BACKEND_DAI_AFE_PCM_TX,
1036 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
1037 msm_routing_put_voice_mixer),
1038 SOC_SINGLE_EXT("AUX_PCM_TX_Voip", MSM_BACKEND_DAI_AUXPCM_TX,
1039 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
1040 msm_routing_put_voice_mixer),
1041};
1042
1043static const struct snd_kcontrol_new tx_voice_stub_mixer_controls[] = {
1044 SOC_SINGLE_EXT("STUB_TX_HL", MSM_BACKEND_DAI_INVALID,
1045 MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
1046 msm_routing_put_voice_stub_mixer),
1047 SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX,
1048 MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
1049 msm_routing_put_voice_stub_mixer),
1050 SOC_SINGLE_EXT("SLIM_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX,
1051 MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
1052 msm_routing_put_voice_stub_mixer),
1053};
1054
1055static const struct snd_kcontrol_new sbus_0_rx_port_mixer_controls[] = {
1056 SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX,
1057 MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer,
1058 msm_routing_put_port_mixer),
1059 SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX,
1060 MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer,
1061 msm_routing_put_port_mixer),
1062 SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX,
1063 MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer,
1064 msm_routing_put_port_mixer),
1065};
1066
1067static const struct snd_kcontrol_new auxpcm_rx_port_mixer_controls[] = {
1068 SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_AUXPCM_RX,
1069 MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer,
1070 msm_routing_put_port_mixer),
1071 SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_AUXPCM_RX,
1072 MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer,
1073 msm_routing_put_port_mixer),
1074};
1075
1076static const struct snd_kcontrol_new sbus_1_rx_port_mixer_controls[] = {
1077 SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_SLIMBUS_1_RX,
1078 MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer,
1079 msm_routing_put_port_mixer),
1080};
1081
1082static const struct snd_kcontrol_new bt_sco_rx_port_mixer_controls[] = {
1083 SOC_SINGLE_EXT("SLIM_1_TX", MSM_BACKEND_DAI_INT_BT_SCO_RX,
1084 MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer,
1085 msm_routing_put_port_mixer),
1086};
1087
1088static const struct snd_kcontrol_new fm_switch_mixer_controls =
1089 SOC_SINGLE_EXT("Switch", SND_SOC_NOPM,
1090 0, 1, 0, msm_routing_get_switch_mixer,
1091 msm_routing_put_switch_mixer);
1092
1093static const struct snd_kcontrol_new int_fm_vol_mixer_controls[] = {
1094 SOC_SINGLE_EXT_TLV("Internal FM RX Volume", SND_SOC_NOPM, 0,
1095 INT_FM_RX_VOL_GAIN, 0, msm_routing_get_fm_vol_mixer,
1096 msm_routing_set_fm_vol_mixer, fm_rx_vol_gain),
1097};
1098
1099static const struct snd_kcontrol_new lpa_vol_mixer_controls[] = {
1100 SOC_SINGLE_EXT_TLV("LPA RX Volume", SND_SOC_NOPM, 0,
1101 INT_RX_VOL_GAIN, 0, msm_routing_get_lpa_vol_mixer,
1102 msm_routing_set_lpa_vol_mixer, lpa_rx_vol_gain),
1103};
1104
1105static const struct snd_kcontrol_new multimedia2_vol_mixer_controls[] = {
1106 SOC_SINGLE_EXT_TLV("HIFI2 RX Volume", SND_SOC_NOPM, 0,
1107 INT_RX_VOL_GAIN, 0, msm_routing_get_multimedia2_vol_mixer,
1108 msm_routing_set_multimedia2_vol_mixer, multimedia2_rx_vol_gain),
1109};
1110
1111static const struct snd_kcontrol_new compressed_vol_mixer_controls[] = {
1112 SOC_SINGLE_EXT_TLV("COMPRESSED RX Volume", SND_SOC_NOPM, 0,
1113 INT_RX_VOL_GAIN, 0, msm_routing_get_compressed_vol_mixer,
1114 msm_routing_set_compressed_vol_mixer, compressed_rx_vol_gain),
1115};
1116
1117static const struct snd_kcontrol_new eq_enable_mixer_controls[] = {
1118 SOC_SINGLE_EXT("MultiMedia1 EQ Enable", SND_SOC_NOPM,
1119 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_eq_enable_mixer,
1120 msm_routing_put_eq_enable_mixer),
1121 SOC_SINGLE_EXT("MultiMedia2 EQ Enable", SND_SOC_NOPM,
1122 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_eq_enable_mixer,
1123 msm_routing_put_eq_enable_mixer),
1124 SOC_SINGLE_EXT("MultiMedia3 EQ Enable", SND_SOC_NOPM,
1125 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_eq_enable_mixer,
1126 msm_routing_put_eq_enable_mixer),
1127};
1128
1129static const struct snd_kcontrol_new eq_band_mixer_controls[] = {
1130 SOC_SINGLE_EXT("MultiMedia1 EQ Band Count", SND_SOC_NOPM,
1131 MSM_FRONTEND_DAI_MULTIMEDIA1, 11, 0,
1132 msm_routing_get_eq_band_count_audio_mixer,
1133 msm_routing_put_eq_band_count_audio_mixer),
1134 SOC_SINGLE_EXT("MultiMedia2 EQ Band Count", SND_SOC_NOPM,
1135 MSM_FRONTEND_DAI_MULTIMEDIA2, 11, 0,
1136 msm_routing_get_eq_band_count_audio_mixer,
1137 msm_routing_put_eq_band_count_audio_mixer),
1138 SOC_SINGLE_EXT("MultiMedia3 EQ Band Count", SND_SOC_NOPM,
1139 MSM_FRONTEND_DAI_MULTIMEDIA3, 11, 0,
1140 msm_routing_get_eq_band_count_audio_mixer,
1141 msm_routing_put_eq_band_count_audio_mixer),
1142};
1143
1144static const struct snd_kcontrol_new eq_coeff_mixer_controls[] = {
1145 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band1", EQ_BAND1,
1146 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
1147 msm_routing_get_eq_band_audio_mixer,
1148 msm_routing_put_eq_band_audio_mixer),
1149 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band2", EQ_BAND2,
1150 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
1151 msm_routing_get_eq_band_audio_mixer,
1152 msm_routing_put_eq_band_audio_mixer),
1153 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band3", EQ_BAND3,
1154 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
1155 msm_routing_get_eq_band_audio_mixer,
1156 msm_routing_put_eq_band_audio_mixer),
1157 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band4", EQ_BAND4,
1158 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
1159 msm_routing_get_eq_band_audio_mixer,
1160 msm_routing_put_eq_band_audio_mixer),
1161 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band5", EQ_BAND5,
1162 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
1163 msm_routing_get_eq_band_audio_mixer,
1164 msm_routing_put_eq_band_audio_mixer),
1165 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band6", EQ_BAND6,
1166 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
1167 msm_routing_get_eq_band_audio_mixer,
1168 msm_routing_put_eq_band_audio_mixer),
1169 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band7", EQ_BAND7,
1170 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
1171 msm_routing_get_eq_band_audio_mixer,
1172 msm_routing_put_eq_band_audio_mixer),
1173 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band8", EQ_BAND8,
1174 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
1175 msm_routing_get_eq_band_audio_mixer,
1176 msm_routing_put_eq_band_audio_mixer),
1177 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band9", EQ_BAND9,
1178 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
1179 msm_routing_get_eq_band_audio_mixer,
1180 msm_routing_put_eq_band_audio_mixer),
1181 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band10", EQ_BAND10,
1182 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
1183 msm_routing_get_eq_band_audio_mixer,
1184 msm_routing_put_eq_band_audio_mixer),
1185 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band11", EQ_BAND11,
1186 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
1187 msm_routing_get_eq_band_audio_mixer,
1188 msm_routing_put_eq_band_audio_mixer),
1189 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band12", EQ_BAND12,
1190 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
1191 msm_routing_get_eq_band_audio_mixer,
1192 msm_routing_put_eq_band_audio_mixer),
1193 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band1", EQ_BAND1,
1194 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1195 msm_routing_get_eq_band_audio_mixer,
1196 msm_routing_put_eq_band_audio_mixer),
1197 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band2", EQ_BAND2,
1198 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1199 msm_routing_get_eq_band_audio_mixer,
1200 msm_routing_put_eq_band_audio_mixer),
1201 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band3", EQ_BAND3,
1202 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1203 msm_routing_get_eq_band_audio_mixer,
1204 msm_routing_put_eq_band_audio_mixer),
1205 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band4", EQ_BAND4,
1206 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1207 msm_routing_get_eq_band_audio_mixer,
1208 msm_routing_put_eq_band_audio_mixer),
1209 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band5", EQ_BAND5,
1210 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1211 msm_routing_get_eq_band_audio_mixer,
1212 msm_routing_put_eq_band_audio_mixer),
1213 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band6", EQ_BAND6,
1214 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1215 msm_routing_get_eq_band_audio_mixer,
1216 msm_routing_put_eq_band_audio_mixer),
1217 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band7", EQ_BAND7,
1218 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1219 msm_routing_get_eq_band_audio_mixer,
1220 msm_routing_put_eq_band_audio_mixer),
1221 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band8", EQ_BAND8,
1222 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1223 msm_routing_get_eq_band_audio_mixer,
1224 msm_routing_put_eq_band_audio_mixer),
1225 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band9", EQ_BAND9,
1226 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1227 msm_routing_get_eq_band_audio_mixer,
1228 msm_routing_put_eq_band_audio_mixer),
1229 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band10", EQ_BAND10,
1230 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1231 msm_routing_get_eq_band_audio_mixer,
1232 msm_routing_put_eq_band_audio_mixer),
1233 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band11", EQ_BAND11,
1234 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1235 msm_routing_get_eq_band_audio_mixer,
1236 msm_routing_put_eq_band_audio_mixer),
1237 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band12", EQ_BAND12,
1238 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1239 msm_routing_get_eq_band_audio_mixer,
1240 msm_routing_put_eq_band_audio_mixer),
1241 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band1", EQ_BAND1,
1242 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1243 msm_routing_get_eq_band_audio_mixer,
1244 msm_routing_put_eq_band_audio_mixer),
1245 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band2", EQ_BAND2,
1246 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1247 msm_routing_get_eq_band_audio_mixer,
1248 msm_routing_put_eq_band_audio_mixer),
1249 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band3", EQ_BAND3,
1250 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1251 msm_routing_get_eq_band_audio_mixer,
1252 msm_routing_put_eq_band_audio_mixer),
1253 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band4", EQ_BAND4,
1254 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1255 msm_routing_get_eq_band_audio_mixer,
1256 msm_routing_put_eq_band_audio_mixer),
1257 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band5", EQ_BAND5,
1258 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1259 msm_routing_get_eq_band_audio_mixer,
1260 msm_routing_put_eq_band_audio_mixer),
1261 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band6", EQ_BAND6,
1262 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1263 msm_routing_get_eq_band_audio_mixer,
1264 msm_routing_put_eq_band_audio_mixer),
1265 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band7", EQ_BAND7,
1266 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1267 msm_routing_get_eq_band_audio_mixer,
1268 msm_routing_put_eq_band_audio_mixer),
1269 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band8", EQ_BAND8,
1270 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1271 msm_routing_get_eq_band_audio_mixer,
1272 msm_routing_put_eq_band_audio_mixer),
1273 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band9", EQ_BAND9,
1274 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1275 msm_routing_get_eq_band_audio_mixer,
1276 msm_routing_put_eq_band_audio_mixer),
1277 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band10", EQ_BAND10,
1278 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1279 msm_routing_get_eq_band_audio_mixer,
1280 msm_routing_put_eq_band_audio_mixer),
1281 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band11", EQ_BAND11,
1282 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1283 msm_routing_get_eq_band_audio_mixer,
1284 msm_routing_put_eq_band_audio_mixer),
1285 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band12", EQ_BAND12,
1286 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1287 msm_routing_get_eq_band_audio_mixer,
1288 msm_routing_put_eq_band_audio_mixer),
1289};
1290
1291static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
1292 /* Frontend AIF */
1293 /* Widget name equals to Front-End DAI name<Need confirmation>,
1294 * Stream name must contains substring of front-end dai name
1295 */
1296 SND_SOC_DAPM_AIF_IN("MM_DL1", "MultiMedia1 Playback", 0, 0, 0, 0),
1297 SND_SOC_DAPM_AIF_IN("MM_DL2", "MultiMedia2 Playback", 0, 0, 0, 0),
1298 SND_SOC_DAPM_AIF_IN("MM_DL3", "MultiMedia3 Playback", 0, 0, 0, 0),
1299 SND_SOC_DAPM_AIF_IN("MM_DL4", "MultiMedia4 Playback", 0, 0, 0, 0),
1300 SND_SOC_DAPM_AIF_IN("VOIP_DL", "VoIP Playback", 0, 0, 0, 0),
1301 SND_SOC_DAPM_AIF_OUT("MM_UL1", "MultiMedia1 Capture", 0, 0, 0, 0),
1302 SND_SOC_DAPM_AIF_OUT("MM_UL2", "MultiMedia2 Capture", 0, 0, 0, 0),
1303 SND_SOC_DAPM_AIF_IN("CS-VOICE_DL1", "CS-VOICE Playback", 0, 0, 0, 0),
1304 SND_SOC_DAPM_AIF_OUT("CS-VOICE_UL1", "CS-VOICE Capture", 0, 0, 0, 0),
1305 SND_SOC_DAPM_AIF_OUT("VOIP_UL", "VoIP Capture", 0, 0, 0, 0),
1306 SND_SOC_DAPM_AIF_IN("SLIM0_DL_HL", "SLIMBUS0_HOSTLESS Playback",
1307 0, 0, 0, 0),
1308 SND_SOC_DAPM_AIF_OUT("SLIM0_UL_HL", "SLIMBUS0_HOSTLESS Capture",
1309 0, 0, 0, 0),
1310 SND_SOC_DAPM_AIF_IN("INTFM_DL_HL", "INT_FM_HOSTLESS Playback",
1311 0, 0, 0, 0),
1312 SND_SOC_DAPM_AIF_OUT("INTFM_UL_HL", "INT_FM_HOSTLESS Capture",
1313 0, 0, 0, 0),
1314 SND_SOC_DAPM_AIF_IN("HDMI_DL_HL", "HDMI_HOSTLESS Playback", 0, 0, 0, 0),
1315 SND_SOC_DAPM_AIF_IN("AUXPCM_DL_HL", "AUXPCM_HOSTLESS Playback",
1316 0, 0, 0, 0),
1317 SND_SOC_DAPM_AIF_OUT("AUXPCM_UL_HL", "AUXPCM_HOSTLESS Capture",
1318 0, 0, 0, 0),
1319
1320 /* Backend AIF */
1321 /* Stream name equals to backend dai link stream name
1322 */
1323 SND_SOC_DAPM_AIF_OUT("PRI_I2S_RX", "Primary I2S Playback", 0, 0, 0, 0),
1324 SND_SOC_DAPM_AIF_OUT("SEC_I2S_RX", "Secondary I2S Playback",
1325 0, 0, 0 , 0),
1326 SND_SOC_DAPM_AIF_OUT("SLIMBUS_0_RX", "Slimbus Playback", 0, 0, 0, 0),
1327 SND_SOC_DAPM_AIF_OUT("HDMI", "HDMI Playback", 0, 0, 0 , 0),
1328 SND_SOC_DAPM_AIF_OUT("MI2S_RX", "MI2S Playback", 0, 0, 0, 0),
1329 SND_SOC_DAPM_AIF_IN("PRI_I2S_TX", "Primary I2S Capture", 0, 0, 0, 0),
1330 SND_SOC_DAPM_AIF_IN("SLIMBUS_0_TX", "Slimbus Capture", 0, 0, 0, 0),
1331 SND_SOC_DAPM_AIF_OUT("INT_BT_SCO_RX", "Internal BT-SCO Playback",
1332 0, 0, 0 , 0),
1333 SND_SOC_DAPM_AIF_IN("INT_BT_SCO_TX", "Internal BT-SCO Capture",
1334 0, 0, 0, 0),
1335 SND_SOC_DAPM_AIF_OUT("INT_FM_RX", "Internal FM Playback",
1336 0, 0, 0 , 0),
1337 SND_SOC_DAPM_AIF_IN("INT_FM_TX", "Internal FM Capture",
1338 0, 0, 0, 0),
1339 SND_SOC_DAPM_AIF_OUT("PCM_RX", "AFE Playback",
1340 0, 0, 0 , 0),
1341 SND_SOC_DAPM_AIF_IN("PCM_TX", "AFE Capture",
1342 0, 0, 0 , 0),
1343 /* incall */
1344 SND_SOC_DAPM_AIF_OUT("VOICE_PLAYBACK_TX", "Voice Farend Playback",
1345 0, 0, 0 , 0),
1346 SND_SOC_DAPM_AIF_IN("INCALL_RECORD_TX", "Voice Uplink Capture",
1347 0, 0, 0, 0),
1348 SND_SOC_DAPM_AIF_IN("INCALL_RECORD_RX", "Voice Downlink Capture",
1349 0, 0, 0, 0),
1350 SND_SOC_DAPM_AIF_OUT("AUX_PCM_RX", "AUX PCM Playback", 0, 0, 0, 0),
1351 SND_SOC_DAPM_AIF_IN("AUX_PCM_TX", "AUX PCM Capture", 0, 0, 0, 0),
1352 SND_SOC_DAPM_AIF_IN("VOICE_STUB_DL", "VOICE_STUB Playback", 0, 0, 0, 0),
1353 SND_SOC_DAPM_AIF_OUT("VOICE_STUB_UL", "VOICE_STUB Capture", 0, 0, 0, 0),
1354 SND_SOC_DAPM_AIF_OUT("STUB_RX", "Stub Playback", 0, 0, 0, 0),
1355 SND_SOC_DAPM_AIF_IN("STUB_TX", "Stub Capture", 0, 0, 0, 0),
1356 SND_SOC_DAPM_AIF_OUT("SLIMBUS_1_RX", "Slimbus1 Playback", 0, 0, 0, 0),
1357 SND_SOC_DAPM_AIF_IN("SLIMBUS_1_TX", "Slimbus1 Capture", 0, 0, 0, 0),
1358
1359 /* Switch Definitions */
1360 SND_SOC_DAPM_SWITCH("SLIMBUS_DL_HL", SND_SOC_NOPM, 0, 0,
1361 &fm_switch_mixer_controls),
1362 /* Mixer definitions */
1363 SND_SOC_DAPM_MIXER("PRI_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1364 pri_i2s_rx_mixer_controls, ARRAY_SIZE(pri_i2s_rx_mixer_controls)),
1365 SND_SOC_DAPM_MIXER("SEC_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1366 sec_i2s_rx_mixer_controls, ARRAY_SIZE(sec_i2s_rx_mixer_controls)),
1367 SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1368 slimbus_rx_mixer_controls, ARRAY_SIZE(slimbus_rx_mixer_controls)),
1369 SND_SOC_DAPM_MIXER("HDMI Mixer", SND_SOC_NOPM, 0, 0,
1370 hdmi_mixer_controls, ARRAY_SIZE(hdmi_mixer_controls)),
1371 SND_SOC_DAPM_MIXER("MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1372 mi2s_rx_mixer_controls, ARRAY_SIZE(mi2s_rx_mixer_controls)),
1373 SND_SOC_DAPM_MIXER("MultiMedia1 Mixer", SND_SOC_NOPM, 0, 0,
1374 mmul1_mixer_controls, ARRAY_SIZE(mmul1_mixer_controls)),
1375 SND_SOC_DAPM_MIXER("MultiMedia2 Mixer", SND_SOC_NOPM, 0, 0,
1376 mmul2_mixer_controls, ARRAY_SIZE(mmul2_mixer_controls)),
1377 SND_SOC_DAPM_MIXER("AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1378 auxpcm_rx_mixer_controls, ARRAY_SIZE(auxpcm_rx_mixer_controls)),
1379 /* incall */
1380 SND_SOC_DAPM_MIXER("Incall_Music Audio Mixer", SND_SOC_NOPM, 0, 0,
1381 incall_music_delivery_mixer_controls,
1382 ARRAY_SIZE(incall_music_delivery_mixer_controls)),
1383 /* Voice Mixer */
1384 SND_SOC_DAPM_MIXER("PRI_RX_Voice Mixer",
1385 SND_SOC_NOPM, 0, 0, pri_rx_voice_mixer_controls,
1386 ARRAY_SIZE(pri_rx_voice_mixer_controls)),
1387 SND_SOC_DAPM_MIXER("SEC_RX_Voice Mixer",
1388 SND_SOC_NOPM, 0, 0,
1389 sec_i2s_rx_voice_mixer_controls,
1390 ARRAY_SIZE(sec_i2s_rx_voice_mixer_controls)),
1391 SND_SOC_DAPM_MIXER("SLIM_0_RX_Voice Mixer",
1392 SND_SOC_NOPM, 0, 0,
1393 slimbus_rx_voice_mixer_controls,
1394 ARRAY_SIZE(slimbus_rx_voice_mixer_controls)),
1395 SND_SOC_DAPM_MIXER("INTERNAL_BT_SCO_RX_Voice Mixer",
1396 SND_SOC_NOPM, 0, 0,
1397 bt_sco_rx_voice_mixer_controls,
1398 ARRAY_SIZE(bt_sco_rx_voice_mixer_controls)),
1399 SND_SOC_DAPM_MIXER("AFE_PCM_RX_Voice Mixer",
1400 SND_SOC_NOPM, 0, 0,
1401 afe_pcm_rx_voice_mixer_controls,
1402 ARRAY_SIZE(afe_pcm_rx_voice_mixer_controls)),
1403 SND_SOC_DAPM_MIXER("AUX_PCM_RX_Voice Mixer",
1404 SND_SOC_NOPM, 0, 0,
1405 aux_pcm_rx_voice_mixer_controls,
1406 ARRAY_SIZE(aux_pcm_rx_voice_mixer_controls)),
1407 SND_SOC_DAPM_MIXER("HDMI_RX_Voice Mixer",
1408 SND_SOC_NOPM, 0, 0,
1409 hdmi_rx_voice_mixer_controls,
1410 ARRAY_SIZE(hdmi_rx_voice_mixer_controls)),
1411 SND_SOC_DAPM_MIXER("Voice_Tx Mixer",
1412 SND_SOC_NOPM, 0, 0, tx_voice_mixer_controls,
1413 ARRAY_SIZE(tx_voice_mixer_controls)),
1414 SND_SOC_DAPM_MIXER("Voip_Tx Mixer",
1415 SND_SOC_NOPM, 0, 0, tx_voip_mixer_controls,
1416 ARRAY_SIZE(tx_voip_mixer_controls)),
1417 SND_SOC_DAPM_MIXER("INTERNAL_BT_SCO_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1418 int_bt_sco_rx_mixer_controls, ARRAY_SIZE(int_bt_sco_rx_mixer_controls)),
1419 SND_SOC_DAPM_MIXER("INTERNAL_FM_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1420 int_fm_rx_mixer_controls, ARRAY_SIZE(int_fm_rx_mixer_controls)),
1421 SND_SOC_DAPM_MIXER("AFE_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1422 afe_pcm_rx_mixer_controls, ARRAY_SIZE(afe_pcm_rx_mixer_controls)),
1423 SND_SOC_DAPM_MIXER("Voice Stub Tx Mixer", SND_SOC_NOPM, 0, 0,
1424 tx_voice_stub_mixer_controls, ARRAY_SIZE(tx_voice_stub_mixer_controls)),
1425 SND_SOC_DAPM_MIXER("STUB_RX Mixer", SND_SOC_NOPM, 0, 0,
1426 stub_rx_mixer_controls, ARRAY_SIZE(stub_rx_mixer_controls)),
1427 SND_SOC_DAPM_MIXER("SLIMBUS_1_RX Mixer", SND_SOC_NOPM, 0, 0,
1428 slimbus_1_rx_mixer_controls, ARRAY_SIZE(slimbus_1_rx_mixer_controls)),
1429 SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Port Mixer",
1430 SND_SOC_NOPM, 0, 0, sbus_0_rx_port_mixer_controls,
1431 ARRAY_SIZE(sbus_0_rx_port_mixer_controls)),
1432 SND_SOC_DAPM_MIXER("AUXPCM_RX Port Mixer",
1433 SND_SOC_NOPM, 0, 0, auxpcm_rx_port_mixer_controls,
1434 ARRAY_SIZE(auxpcm_rx_port_mixer_controls)),
1435 SND_SOC_DAPM_MIXER("SLIMBUS_1_RX Port Mixer", SND_SOC_NOPM, 0, 0,
1436 sbus_1_rx_port_mixer_controls,
1437 ARRAY_SIZE(sbus_1_rx_port_mixer_controls)),
1438 SND_SOC_DAPM_MIXER("INTERNAL_BT_SCO_RX Port Mixer", SND_SOC_NOPM, 0, 0,
1439 bt_sco_rx_port_mixer_controls,
1440 ARRAY_SIZE(bt_sco_rx_port_mixer_controls)),
1441};
1442
1443static const struct snd_soc_dapm_route intercon[] = {
1444 {"PRI_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1445 {"PRI_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
1446 {"PRI_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
1447 {"PRI_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
1448 {"PRI_I2S_RX", NULL, "PRI_RX Audio Mixer"},
1449
1450 {"SEC_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1451 {"SEC_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
1452 {"SEC_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
1453 {"SEC_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
1454 {"SEC_I2S_RX", NULL, "SEC_RX Audio Mixer"},
1455
1456 {"SLIMBUS_0_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1457 {"SLIMBUS_0_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
1458 {"SLIMBUS_0_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
1459 {"SLIMBUS_0_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
1460 {"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Audio Mixer"},
1461
1462 {"HDMI Mixer", "MultiMedia1", "MM_DL1"},
1463 {"HDMI Mixer", "MultiMedia2", "MM_DL2"},
1464 {"HDMI Mixer", "MultiMedia3", "MM_DL3"},
1465 {"HDMI Mixer", "MultiMedia4", "MM_DL4"},
1466 {"HDMI", NULL, "HDMI Mixer"},
1467
1468 /* incall */
1469 {"Incall_Music Audio Mixer", "MultiMedia1", "MM_DL1"},
1470 {"Incall_Music Audio Mixer", "MultiMedia2", "MM_DL2"},
1471 {"VOICE_PLAYBACK_TX", NULL, "Incall_Music Audio Mixer"},
1472
1473 {"MultiMedia1 Mixer", "VOC_REC_UL", "INCALL_RECORD_TX"},
1474 {"MultiMedia1 Mixer", "VOC_REC_DL", "INCALL_RECORD_RX"},
1475 {"MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1476 {"MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
1477 {"MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
1478 {"MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
1479 {"MI2S_RX", NULL, "MI2S_RX Audio Mixer"},
1480
1481 {"MultiMedia1 Mixer", "PRI_TX", "PRI_I2S_TX"},
1482 {"MultiMedia1 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
1483 {"MultiMedia1 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
1484
1485 {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1486 {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
1487 {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
1488 {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
1489 {"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX Audio Mixer"},
1490
1491 {"INTERNAL_FM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1492 {"INTERNAL_FM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
1493 {"INTERNAL_FM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
1494 {"INTERNAL_FM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
1495 {"INT_FM_RX", NULL, "INTERNAL_FM_RX Audio Mixer"},
1496
1497 {"AFE_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1498 {"AFE_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
1499 {"AFE_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
1500 {"AFE_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
1501 {"PCM_RX", NULL, "AFE_PCM_RX Audio Mixer"},
1502
1503 {"MultiMedia1 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
1504 {"MultiMedia1 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
1505
1506 {"MultiMedia1 Mixer", "AFE_PCM_TX", "PCM_TX"},
1507 {"MM_UL1", NULL, "MultiMedia1 Mixer"},
1508 {"MultiMedia2 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
1509 {"MM_UL2", NULL, "MultiMedia2 Mixer"},
1510
1511 {"AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1512 {"AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
1513 {"AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
1514 {"AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
1515 {"AUX_PCM_RX", NULL, "AUX_PCM_RX Audio Mixer"},
1516
1517 {"PRI_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1518 {"PRI_RX_Voice Mixer", "Voip", "VOIP_DL"},
1519 {"PRI_I2S_RX", NULL, "PRI_RX_Voice Mixer"},
1520
1521 {"SEC_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1522 {"SEC_RX_Voice Mixer", "Voip", "VOIP_DL"},
1523 {"SEC_I2S_RX", NULL, "SEC_RX_Voice Mixer"},
1524
1525 {"SLIM_0_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1526 {"SLIM_0_RX_Voice Mixer", "Voip", "VOIP_DL"},
1527 {"SLIMBUS_0_RX", NULL, "SLIM_0_RX_Voice Mixer"},
1528
1529 {"INTERNAL_BT_SCO_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1530 {"INTERNAL_BT_SCO_RX_Voice Mixer", "Voip", "VOIP_DL"},
1531 {"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX_Voice Mixer"},
1532
1533 {"AFE_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1534 {"AFE_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"},
1535 {"PCM_RX", NULL, "AFE_PCM_RX_Voice Mixer"},
1536
1537 {"AUX_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1538 {"AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"},
1539 {"AUX_PCM_RX", NULL, "AUX_PCM_RX_Voice Mixer"},
1540
1541 {"HDMI_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1542 {"HDMI_RX_Voice Mixer", "Voip", "VOIP_DL"},
1543 {"HDMI", NULL, "HDMI_RX_Voice Mixer"},
1544 {"HDMI", NULL, "HDMI_DL_HL"},
1545
1546 {"Voice_Tx Mixer", "PRI_TX_Voice", "PRI_I2S_TX"},
1547 {"Voice_Tx Mixer", "SLIM_0_TX_Voice", "SLIMBUS_0_TX"},
1548 {"Voice_Tx Mixer", "INTERNAL_BT_SCO_TX_Voice", "INT_BT_SCO_TX"},
1549 {"Voice_Tx Mixer", "AFE_PCM_TX_Voice", "PCM_TX"},
1550 {"Voice_Tx Mixer", "AUX_PCM_TX_Voice", "AUX_PCM_TX"},
1551 {"CS-VOICE_UL1", NULL, "Voice_Tx Mixer"},
1552 {"Voip_Tx Mixer", "PRI_TX_Voip", "PRI_I2S_TX"},
1553 {"Voip_Tx Mixer", "SLIM_0_TX_Voip", "SLIMBUS_0_TX"},
1554 {"Voip_Tx Mixer", "INTERNAL_BT_SCO_TX_Voip", "INT_BT_SCO_TX"},
1555 {"Voip_Tx Mixer", "AFE_PCM_TX_Voip", "PCM_TX"},
1556 {"Voip_Tx Mixer", "AUX_PCM_TX_Voip", "AUX_PCM_TX"},
1557
1558 {"VOIP_UL", NULL, "Voip_Tx Mixer"},
1559 {"SLIMBUS_DL_HL", "Switch", "SLIM0_DL_HL"},
1560 {"SLIMBUS_0_RX", NULL, "SLIMBUS_DL_HL"},
1561 {"SLIM0_UL_HL", NULL, "SLIMBUS_0_TX"},
1562 {"INT_FM_RX", NULL, "INTFM_DL_HL"},
1563 {"INTFM_UL_HL", NULL, "INT_FM_TX"},
1564 {"AUX_PCM_RX", NULL, "AUXPCM_DL_HL"},
1565 {"AUXPCM_UL_HL", NULL, "AUX_PCM_TX"},
1566 {"SLIMBUS_0_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
1567 {"SLIMBUS_0_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
1568 {"SLIMBUS_0_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
1569 {"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Port Mixer"},
1570
1571 {"AUXPCM_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
1572 {"AUXPCM_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
1573 {"AUX_PCM_RX", NULL, "AUXPCM_RX Port Mixer"},
1574
1575 {"Voice Stub Tx Mixer", "STUB_TX_HL", "STUB_TX"},
1576 {"Voice Stub Tx Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"},
1577 {"Voice Stub Tx Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
1578 {"VOICE_STUB_UL", NULL, "Voice Stub Tx Mixer"},
1579
1580 {"STUB_RX Mixer", "Voice Stub", "VOICE_STUB_DL"},
1581 {"STUB_RX", NULL, "STUB_RX Mixer"},
1582 {"SLIMBUS_1_RX Mixer", "Voice Stub", "VOICE_STUB_DL"},
1583 {"SLIMBUS_1_RX", NULL, "SLIMBUS_1_RX Mixer"},
1584 {"INTERNAL_BT_SCO_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"},
1585
1586 {"SLIMBUS_1_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
1587 {"SLIMBUS_1_RX", NULL, "SLIMBUS_1_RX Port Mixer"},
1588 {"INTERNAL_BT_SCO_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"},
1589 {"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX Port Mixer"},
1590};
1591
1592static int msm_pcm_routing_hw_params(struct snd_pcm_substream *substream,
1593 struct snd_pcm_hw_params *params)
1594{
1595 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1596 unsigned int be_id = rtd->dai_link->be_id;
1597
1598 if (be_id >= MSM_BACKEND_DAI_MAX) {
1599 pr_err("%s: unexpected be_id %d\n", __func__, be_id);
1600 return -EINVAL;
1601 }
1602
1603 mutex_lock(&routing_lock);
1604 msm_bedais[be_id].hw_params = params;
1605 mutex_unlock(&routing_lock);
1606 return 0;
1607}
1608
1609static int msm_pcm_routing_close(struct snd_pcm_substream *substream)
1610{
1611 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1612 unsigned int be_id = rtd->dai_link->be_id;
1613 int i, session_type;
1614 struct msm_pcm_routing_bdai_data *bedai;
1615
1616 if (be_id >= MSM_BACKEND_DAI_MAX) {
1617 pr_err("%s: unexpected be_id %d\n", __func__, be_id);
1618 return -EINVAL;
1619 }
1620
1621 bedai = &msm_bedais[be_id];
1622
1623 session_type = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
1624 0 : 1);
1625
1626 mutex_lock(&routing_lock);
1627
1628 for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MM_SIZE) {
1629 if (fe_dai_map[i][session_type] != INVALID_SESSION)
1630 adm_close(bedai->port_id);
1631 }
1632
1633 bedai->active = 0;
1634 bedai->hw_params = NULL;
1635
1636 mutex_unlock(&routing_lock);
1637
1638 return 0;
1639}
1640
1641static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream)
1642{
1643 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1644 unsigned int be_id = rtd->dai_link->be_id;
1645 int i, path_type, session_type;
1646 struct msm_pcm_routing_bdai_data *bedai;
1647 u32 channels;
1648
1649 if (be_id >= MSM_BACKEND_DAI_MAX) {
1650 pr_err("%s: unexpected be_id %d\n", __func__, be_id);
1651 return -EINVAL;
1652 }
1653
1654
1655 bedai = &msm_bedais[be_id];
1656
1657 if (bedai->hw_params == NULL) {
1658 pr_err("%s: HW param is not configured", __func__);
1659 return -EINVAL;
1660 }
1661
1662
1663 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1664 path_type = ADM_PATH_PLAYBACK;
1665 session_type = SESSION_TYPE_RX;
1666 } else {
1667 path_type = ADM_PATH_LIVE_REC;
1668 session_type = SESSION_TYPE_TX;
1669 }
1670
1671 mutex_lock(&routing_lock);
1672
1673 if (bedai->active == 1)
1674 goto done; /* Ignore prepare if back-end already active */
1675
1676 /* AFE port is not active at this point. However, still
1677 * go ahead setting active flag under the notion that
1678 * QDSP6 is able to handle ADM starting before AFE port
1679 * is started.
1680 */
1681 bedai->active = 1;
1682
1683 for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MM_SIZE) {
1684 if (fe_dai_map[i][session_type] != INVALID_SESSION) {
1685
1686 channels = params_channels(bedai->hw_params);
1687 if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) &&
1688 (channels > 2))
1689 adm_multi_ch_copp_open(bedai->port_id,
1690 path_type,
1691 params_rate(bedai->hw_params),
1692 channels,
1693 DEFAULT_COPP_TOPOLOGY);
1694 else
1695 adm_open(bedai->port_id,
1696 path_type,
1697 params_rate(bedai->hw_params),
1698 params_channels(bedai->hw_params),
1699 DEFAULT_COPP_TOPOLOGY);
1700
1701 msm_pcm_routing_build_matrix(i,
1702 fe_dai_map[i][session_type], path_type);
1703 }
1704 }
1705
1706done:
1707 mutex_unlock(&routing_lock);
1708
1709 return 0;
1710}
1711
1712static struct snd_pcm_ops msm_routing_pcm_ops = {
1713 .hw_params = msm_pcm_routing_hw_params,
1714 .close = msm_pcm_routing_close,
1715 .prepare = msm_pcm_routing_prepare,
1716};
1717
1718static unsigned int msm_routing_read(struct snd_soc_platform *platform,
1719 unsigned int reg)
1720{
1721 dev_dbg(platform->dev, "reg %x\n", reg);
1722 return 0;
1723}
1724
1725/* Not used but frame seems to require it */
1726static int msm_routing_write(struct snd_soc_platform *platform,
1727 unsigned int reg, unsigned int val)
1728{
1729 dev_dbg(platform->dev, "reg %x val %x\n", reg, val);
1730 return 0;
1731}
1732
1733/* Not used but frame seems to require it */
1734static int msm_routing_probe(struct snd_soc_platform *platform)
1735{
1736 snd_soc_dapm_new_controls(&platform->dapm, msm_qdsp6_widgets,
1737 ARRAY_SIZE(msm_qdsp6_widgets));
1738 snd_soc_dapm_add_routes(&platform->dapm, intercon,
1739 ARRAY_SIZE(intercon));
1740
1741 snd_soc_dapm_new_widgets(&platform->dapm);
1742
1743 snd_soc_add_platform_controls(platform,
1744 int_fm_vol_mixer_controls,
1745 ARRAY_SIZE(int_fm_vol_mixer_controls));
1746
1747 snd_soc_add_platform_controls(platform,
1748 lpa_vol_mixer_controls,
1749 ARRAY_SIZE(lpa_vol_mixer_controls));
1750
1751 snd_soc_add_platform_controls(platform,
1752 eq_enable_mixer_controls,
1753 ARRAY_SIZE(eq_enable_mixer_controls));
1754
1755 snd_soc_add_platform_controls(platform,
1756 eq_band_mixer_controls,
1757 ARRAY_SIZE(eq_band_mixer_controls));
1758
1759 snd_soc_add_platform_controls(platform,
1760 eq_coeff_mixer_controls,
1761 ARRAY_SIZE(eq_coeff_mixer_controls));
1762
1763 snd_soc_add_platform_controls(platform,
1764 multimedia2_vol_mixer_controls,
1765 ARRAY_SIZE(multimedia2_vol_mixer_controls));
1766
1767 snd_soc_add_platform_controls(platform,
1768 compressed_vol_mixer_controls,
1769 ARRAY_SIZE(compressed_vol_mixer_controls));
1770
1771 return 0;
1772}
1773
1774static struct snd_soc_platform_driver msm_soc_routing_platform = {
1775 .ops = &msm_routing_pcm_ops,
1776 .probe = msm_routing_probe,
1777 .read = msm_routing_read,
1778 .write = msm_routing_write,
1779};
1780
1781static __devinit int msm_routing_pcm_probe(struct platform_device *pdev)
1782{
1783 dev_dbg(&pdev->dev, "dev name %s\n", dev_name(&pdev->dev));
1784 return snd_soc_register_platform(&pdev->dev,
1785 &msm_soc_routing_platform);
1786}
1787
1788static int msm_routing_pcm_remove(struct platform_device *pdev)
1789{
1790 snd_soc_unregister_platform(&pdev->dev);
1791 return 0;
1792}
1793
1794static struct platform_driver msm_routing_pcm_driver = {
1795 .driver = {
1796 .name = "msm-pcm-routing",
1797 .owner = THIS_MODULE,
1798 },
1799 .probe = msm_routing_pcm_probe,
1800 .remove = __devexit_p(msm_routing_pcm_remove),
1801};
1802
1803int msm_routing_check_backend_enabled(int fedai_id)
1804{
1805 int i;
1806 if (fedai_id >= MSM_FRONTEND_DAI_MM_MAX_ID) {
1807 /* bad ID assigned in machine driver */
1808 pr_err("%s: bad MM ID\n", __func__);
1809 return 0;
1810 }
1811 for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) {
1812 if ((test_bit(fedai_id,
1813 &msm_bedais[i].fe_sessions))) {
1814 return msm_bedais[i].active;
1815 }
1816 }
1817 return 0;
1818}
1819
1820static int __init msm_soc_routing_platform_init(void)
1821{
1822 mutex_init(&routing_lock);
1823 return platform_driver_register(&msm_routing_pcm_driver);
1824}
1825module_init(msm_soc_routing_platform_init);
1826
1827static void __exit msm_soc_routing_platform_exit(void)
1828{
1829 platform_driver_unregister(&msm_routing_pcm_driver);
1830}
1831module_exit(msm_soc_routing_platform_exit);
1832
1833MODULE_DESCRIPTION("MSM routing platform driver");
1834MODULE_LICENSE("GPL v2");