blob: 2815daaadea7d3d337940e797074ee83a40bd715 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Copyright (c) 2011, 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>
Neema Shettyfeea7742011-09-11 12:30:36 -070020#include <linux/mutex.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070021#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.h>
Ben Romberger037dd2f2011-09-22 14:01:32 -070028#include <sound/q6asm.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070029#include <sound/q6afe.h>
Jayasena Sangaraboinacb1e22f2011-07-18 10:36:57 -070030#include <sound/tlv.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070031#include "msm-pcm-routing.h"
32#include "qdsp6/q6voice.h"
33
Neema Shettyfeea7742011-09-11 12:30:36 -070034struct 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
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070042#define INVALID_SESSION -1
Patrick Laicf999112011-08-23 11:27:20 -070043#define SESSION_TYPE_RX 0
44#define SESSION_TYPE_TX 1
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070045
Neema Shettyfeea7742011-09-11 12:30:36 -070046static struct mutex routing_lock;
47
Sriranjan Srikantama4969dd2011-07-14 00:34:56 -070048static int fm_switch_enable;
Jayasena Sangaraboinacb1e22f2011-07-18 10:36:57 -070049#define INT_FM_RX_VOL_MAX_STEPS 100
50#define INT_FM_RX_VOL_GAIN 2000
51
52static int msm_route_fm_vol_control;
53static const DECLARE_TLV_DB_SCALE(fm_rx_vol_gain, 0,
54 INT_FM_RX_VOL_MAX_STEPS, 0);
Sriranjan Srikantama4969dd2011-07-14 00:34:56 -070055
Sriranjan Srikantam269de7f2011-09-06 18:24:45 -070056#define INT_LPA_RX_VOL_MAX_STEPS 100
57#define INT_LPA_RX_VOL_GAIN 0x2000
Asish Bhattacharya0ec76182011-07-29 16:58:11 +053058
59static int msm_route_lpa_vol_control;
60static const DECLARE_TLV_DB_SCALE(lpa_rx_vol_gain, 0,
61 INT_LPA_RX_VOL_MAX_STEPS, 0);
62
Ben Romberger037dd2f2011-09-22 14:01:32 -070063/* Equal to Frontend after last of the MULTIMEDIA SESSIONS */
64#define MAX_EQ_SESSIONS MSM_FRONTEND_DAI_CS_VOICE
65
66enum {
67 EQ_BAND1 = 0,
68 EQ_BAND2,
69 EQ_BAND3,
70 EQ_BAND4,
71 EQ_BAND5,
72 EQ_BAND6,
73 EQ_BAND7,
74 EQ_BAND8,
75 EQ_BAND9,
76 EQ_BAND10,
77 EQ_BAND11,
78 EQ_BAND12,
79 EQ_BAND_MAX,
80};
81
82struct msm_audio_eq_band {
83 uint16_t band_idx; /* The band index, 0 .. 11 */
84 uint32_t filter_type; /* Filter band type */
85 uint32_t center_freq_hz; /* Filter band center frequency */
86 uint32_t filter_gain; /* Filter band initial gain (dB) */
87 /* Range is +12 dB to -12 dB with 1dB increments. */
88 uint32_t q_factor;
89} __packed;
90
91struct msm_audio_eq_stream_config {
92 uint32_t enable; /* Number of consequtive bands specified */
93 uint32_t num_bands;
94 struct msm_audio_eq_band eq_bands[EQ_BAND_MAX];
95} __packed;
96
97struct msm_audio_eq_stream_config eq_data[MAX_EQ_SESSIONS];
98
99static void msm_send_eq_values(int eq_idx);
Neema Shettyfeea7742011-09-11 12:30:36 -0700100/* This array is indexed by back-end DAI ID defined in msm-pcm-routing.h
101 * If new back-end is defined, add new back-end DAI ID at the end of enum
102 */
103static struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = {
104 { PRIMARY_I2S_RX, 0, NULL, 0, 0},
105 { PRIMARY_I2S_TX, 0, NULL, 0, 0},
106 { SLIMBUS_0_RX, 0, NULL, 0, 0},
107 { SLIMBUS_0_TX, 0, NULL, 0, 0},
108 { HDMI_RX, 0, NULL, 0, 0},
109 { INT_BT_SCO_RX, 0, NULL, 0, 0},
110 { INT_BT_SCO_TX, 0, NULL, 0, 0},
111 { INT_FM_RX, 0, NULL, 0, 0},
112 { INT_FM_TX, 0, NULL, 0, 0},
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530113 { RT_PROXY_PORT_001_RX, 0, NULL, 0, 0},
114 { RT_PROXY_PORT_001_TX, 0, NULL, 0, 0},
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700115 { PCM_RX, 0, NULL, 0, 0},
116 { PCM_TX, 0, NULL, 0, 0},
Helen Zeng0705a5f2011-10-14 15:29:52 -0700117 { VOICE_PLAYBACK_TX, 0, NULL, 0, 0},
Helen Zenge3d716a2011-10-14 16:32:16 -0700118 { VOICE_RECORD_RX, 0, NULL, 0, 0},
119 { VOICE_RECORD_TX, 0, NULL, 0, 0},
Kuirong Wang274f21a2011-12-15 21:29:08 -0800120 { MI2S_RX, 0, NULL, 0, 0},
Neema Shettyfeea7742011-09-11 12:30:36 -0700121};
122
123
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700124/* Track ASM playback & capture sessions of DAI */
Patrick Lai770ca3e42011-12-12 13:44:54 -0800125static int fe_dai_map[MSM_FRONTEND_DAI_MM_SIZE][2] = {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700126 /* MULTIMEDIA1 */
127 {INVALID_SESSION, INVALID_SESSION},
128 /* MULTIMEDIA2 */
129 {INVALID_SESSION, INVALID_SESSION},
130 /* MULTIMEDIA3 */
131 {INVALID_SESSION, INVALID_SESSION},
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530132 /* MULTIMEDIA4 */
133 {INVALID_SESSION, INVALID_SESSION},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700134};
135
Patrick Laicf999112011-08-23 11:27:20 -0700136static void msm_pcm_routing_build_matrix(int fedai_id, int dspst_id,
137 int path_type)
138{
139 int i, port_type;
140 struct route_payload payload;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700141
Patrick Laicf999112011-08-23 11:27:20 -0700142 payload.num_copps = 0;
143 port_type = (path_type == ADM_PATH_PLAYBACK ?
144 MSM_AFE_PORT_TYPE_RX : MSM_AFE_PORT_TYPE_TX);
145
146 for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) {
147 if ((afe_get_port_type(msm_bedais[i].port_id) ==
148 port_type) &&
149 msm_bedais[i].active && (test_bit(fedai_id,
150 &msm_bedais[i].fe_sessions)))
151 payload.copp_ids[payload.num_copps++] =
152 msm_bedais[i].port_id;
153 }
154
155 if (payload.num_copps)
156 adm_matrix_map(dspst_id, path_type,
157 payload.num_copps, payload.copp_ids, 0);
158}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700159
160void msm_pcm_routing_reg_phy_stream(int fedai_id, int dspst_id, int stream_type)
161{
Patrick Laicf999112011-08-23 11:27:20 -0700162 int i, session_type, path_type, port_type;
163 struct route_payload payload;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700164
Patrick Lai770ca3e42011-12-12 13:44:54 -0800165 if (fedai_id > MSM_FRONTEND_DAI_MM_MAX_ID) {
166 /* bad ID assigned in machine driver */
167 pr_err("%s: bad MM ID\n", __func__);
168 return;
169 }
170
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700171 if (stream_type == SNDRV_PCM_STREAM_PLAYBACK) {
Patrick Laicf999112011-08-23 11:27:20 -0700172 session_type = SESSION_TYPE_RX;
173 path_type = ADM_PATH_PLAYBACK;
174 port_type = MSM_AFE_PORT_TYPE_RX;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700175 } else {
Patrick Laicf999112011-08-23 11:27:20 -0700176 session_type = SESSION_TYPE_TX;
177 path_type = ADM_PATH_LIVE_REC;
178 port_type = MSM_AFE_PORT_TYPE_TX;
179 }
180
181 mutex_lock(&routing_lock);
182
183 payload.num_copps = 0; /* only RX needs to use payload */
184 fe_dai_map[fedai_id][session_type] = dspst_id;
Ben Romberger037dd2f2011-09-22 14:01:32 -0700185 /* re-enable EQ if active */
186 if (eq_data[fedai_id].enable)
187 msm_send_eq_values(fedai_id);
Patrick Laicf999112011-08-23 11:27:20 -0700188 for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) {
189 if ((afe_get_port_type(msm_bedais[i].port_id) ==
190 port_type) && msm_bedais[i].active &&
191 (test_bit(fedai_id,
192 &msm_bedais[i].fe_sessions))) {
193 adm_open(msm_bedais[i].port_id,
194 path_type,
195 params_rate(msm_bedais[i].hw_params),
196 params_channels(msm_bedais[i].hw_params),
197 DEFAULT_COPP_TOPOLOGY);
198 payload.copp_ids[payload.num_copps++] =
199 msm_bedais[i].port_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700200 }
201 }
Patrick Laicf999112011-08-23 11:27:20 -0700202 if (payload.num_copps)
203 adm_matrix_map(dspst_id, path_type,
204 payload.num_copps, payload.copp_ids, 0);
205
206 mutex_unlock(&routing_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700207}
208
209void msm_pcm_routing_dereg_phy_stream(int fedai_id, int stream_type)
210{
Patrick Laicf999112011-08-23 11:27:20 -0700211 int i, port_type, session_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700212
Patrick Lai770ca3e42011-12-12 13:44:54 -0800213 if (fedai_id > MSM_FRONTEND_DAI_MM_MAX_ID) {
214 /* bad ID assigned in machine driver */
215 pr_err("%s: bad MM ID\n", __func__);
216 return;
217 }
218
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700219 if (stream_type == SNDRV_PCM_STREAM_PLAYBACK) {
Patrick Laicf999112011-08-23 11:27:20 -0700220 port_type = MSM_AFE_PORT_TYPE_RX;
221 session_type = SESSION_TYPE_RX;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700222 } else {
Patrick Laicf999112011-08-23 11:27:20 -0700223 port_type = MSM_AFE_PORT_TYPE_TX;
224 session_type = SESSION_TYPE_TX;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700225 }
Patrick Laicf999112011-08-23 11:27:20 -0700226
227 mutex_lock(&routing_lock);
228
229 for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) {
230 if ((afe_get_port_type(msm_bedais[i].port_id) ==
231 port_type) && msm_bedais[i].active &&
232 (test_bit(fedai_id,
233 &msm_bedais[i].fe_sessions)))
234 adm_close(msm_bedais[i].port_id);
235 }
236
237 fe_dai_map[fedai_id][session_type] = INVALID_SESSION;
238
239 mutex_unlock(&routing_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700240}
241
242static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set)
243{
Patrick Laicf999112011-08-23 11:27:20 -0700244 int session_type, path_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700245
246 pr_debug("%s: reg %x val %x set %x\n", __func__, reg, val, set);
247
Patrick Lai770ca3e42011-12-12 13:44:54 -0800248 if (val > MSM_FRONTEND_DAI_MM_MAX_ID) {
249 /* recheck FE ID in the mixer control defined in this file */
250 pr_err("%s: bad MM ID\n", __func__);
251 return;
252 }
253
Patrick Laicf999112011-08-23 11:27:20 -0700254 if (afe_get_port_type(msm_bedais[reg].port_id) ==
255 MSM_AFE_PORT_TYPE_RX) {
256 session_type = SESSION_TYPE_RX;
257 path_type = ADM_PATH_PLAYBACK;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700258 } else {
Patrick Laicf999112011-08-23 11:27:20 -0700259 session_type = SESSION_TYPE_TX;
260 path_type = ADM_PATH_LIVE_REC;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700261 }
Patrick Laicf999112011-08-23 11:27:20 -0700262
263 mutex_lock(&routing_lock);
264
265 if (set) {
Helen Zeng0705a5f2011-10-14 15:29:52 -0700266 if (!test_bit(val, &msm_bedais[reg].fe_sessions) &&
267 (msm_bedais[reg].port_id == VOICE_PLAYBACK_TX))
268 voc_start_playback(set);
269
Patrick Laicf999112011-08-23 11:27:20 -0700270 set_bit(val, &msm_bedais[reg].fe_sessions);
271 if (msm_bedais[reg].active && fe_dai_map[val][session_type] !=
272 INVALID_SESSION) {
273 adm_open(msm_bedais[reg].port_id, path_type,
274 params_rate(msm_bedais[reg].hw_params),
275 params_channels(msm_bedais[reg].hw_params),
276 DEFAULT_COPP_TOPOLOGY);
277 msm_pcm_routing_build_matrix(val,
278 fe_dai_map[val][session_type], path_type);
279 }
280 } else {
Helen Zeng0705a5f2011-10-14 15:29:52 -0700281 if (test_bit(val, &msm_bedais[reg].fe_sessions) &&
282 (msm_bedais[reg].port_id == VOICE_PLAYBACK_TX))
283 voc_start_playback(set);
Patrick Laicf999112011-08-23 11:27:20 -0700284 clear_bit(val, &msm_bedais[reg].fe_sessions);
285 if (msm_bedais[reg].active && fe_dai_map[val][session_type] !=
286 INVALID_SESSION) {
287 adm_close(msm_bedais[reg].port_id);
288 msm_pcm_routing_build_matrix(val,
289 fe_dai_map[val][session_type], path_type);
290 }
291 }
Helen Zenge3d716a2011-10-14 16:32:16 -0700292 if ((msm_bedais[reg].port_id == VOICE_RECORD_RX)
293 || (msm_bedais[reg].port_id == VOICE_RECORD_TX))
294 voc_start_record(msm_bedais[reg].port_id, set);
Patrick Laicf999112011-08-23 11:27:20 -0700295
296 mutex_unlock(&routing_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700297}
298
299static int msm_routing_get_audio_mixer(struct snd_kcontrol *kcontrol,
300 struct snd_ctl_elem_value *ucontrol)
301{
302 struct soc_mixer_control *mc =
303 (struct soc_mixer_control *)kcontrol->private_value;
304
Patrick Laicf999112011-08-23 11:27:20 -0700305 if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700306 ucontrol->value.integer.value[0] = 1;
307 else
308 ucontrol->value.integer.value[0] = 0;
309
310 pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift,
311 ucontrol->value.integer.value[0]);
312
313 return 0;
314}
315
316static int msm_routing_put_audio_mixer(struct snd_kcontrol *kcontrol,
317 struct snd_ctl_elem_value *ucontrol)
318{
Patrick Laiec2b8942011-09-01 11:01:51 -0700319 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
320 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700321 struct soc_mixer_control *mc =
322 (struct soc_mixer_control *)kcontrol->private_value;
323
324
325 if (ucontrol->value.integer.value[0]) {
326 msm_pcm_routing_process_audio(mc->reg, mc->shift, 1);
327 snd_soc_dapm_mixer_update_power(widget, kcontrol, 1);
328 } else {
329 msm_pcm_routing_process_audio(mc->reg, mc->shift, 0);
330 snd_soc_dapm_mixer_update_power(widget, kcontrol, 0);
331 }
332
333 return 1;
334}
335
Neema Shettyfeea7742011-09-11 12:30:36 -0700336static void msm_pcm_routing_process_voice(u16 reg, u16 val, int set)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700337{
Neema Shetty2c07eb52011-08-21 20:33:52 -0700338 u16 session_id = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700339
Neema Shettyfeea7742011-09-11 12:30:36 -0700340 pr_debug("%s: reg %x val %x set %x\n", __func__, reg, val, set);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700341
Neema Shettyfeea7742011-09-11 12:30:36 -0700342 if (val == MSM_FRONTEND_DAI_CS_VOICE)
Neema Shetty2c07eb52011-08-21 20:33:52 -0700343 session_id = voc_get_session_id(VOICE_SESSION_NAME);
344 else
345 session_id = voc_get_session_id(VOIP_SESSION_NAME);
346
347 pr_debug("%s: FE DAI 0x%x session_id 0x%x\n",
Neema Shettyfeea7742011-09-11 12:30:36 -0700348 __func__, val, session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700349
Neema Shettyfeea7742011-09-11 12:30:36 -0700350 mutex_lock(&routing_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700351
352 if (set)
Neema Shettyfeea7742011-09-11 12:30:36 -0700353 set_bit(val, &msm_bedais[reg].fe_sessions);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700354 else
Neema Shettyfeea7742011-09-11 12:30:36 -0700355 clear_bit(val, &msm_bedais[reg].fe_sessions);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700356
Neema Shettyfeea7742011-09-11 12:30:36 -0700357 mutex_unlock(&routing_lock);
358
359 if (afe_get_port_type(msm_bedais[reg].port_id) ==
360 MSM_AFE_PORT_TYPE_RX) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700361 voc_set_route_flag(session_id, RX_PATH, set);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700362 if (set) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700363 voc_set_rxtx_port(session_id,
Neema Shettyfeea7742011-09-11 12:30:36 -0700364 msm_bedais[reg].port_id, DEV_RX);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700365
Neema Shetty2c07eb52011-08-21 20:33:52 -0700366 if (voc_get_route_flag(session_id, RX_PATH) &&
367 voc_get_route_flag(session_id, TX_PATH))
368 voc_enable_cvp(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700369 } else {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700370 voc_disable_cvp(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700371 }
372 } else {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700373 voc_set_route_flag(session_id, TX_PATH, set);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700374 if (set) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700375 voc_set_rxtx_port(session_id,
Neema Shettyfeea7742011-09-11 12:30:36 -0700376 msm_bedais[reg].port_id, DEV_TX);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700377 if (voc_get_route_flag(session_id, RX_PATH) &&
378 voc_get_route_flag(session_id, TX_PATH))
379 voc_enable_cvp(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700380 } else {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700381 voc_disable_cvp(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700382 }
383 }
384}
385
386static int msm_routing_get_voice_mixer(struct snd_kcontrol *kcontrol,
387 struct snd_ctl_elem_value *ucontrol)
388{
389 struct soc_mixer_control *mc =
390 (struct soc_mixer_control *)kcontrol->private_value;
391
Neema Shettyfeea7742011-09-11 12:30:36 -0700392 mutex_lock(&routing_lock);
393
394 if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700395 ucontrol->value.integer.value[0] = 1;
396 else
397 ucontrol->value.integer.value[0] = 0;
398
Neema Shettyfeea7742011-09-11 12:30:36 -0700399 mutex_unlock(&routing_lock);
400
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700401 pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift,
402 ucontrol->value.integer.value[0]);
403
404 return 0;
405}
406
407static int msm_routing_put_voice_mixer(struct snd_kcontrol *kcontrol,
408 struct snd_ctl_elem_value *ucontrol)
409{
Patrick Laiec2b8942011-09-01 11:01:51 -0700410 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
411 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700412 struct soc_mixer_control *mc =
413 (struct soc_mixer_control *)kcontrol->private_value;
414
415 if (ucontrol->value.integer.value[0]) {
Neema Shettyfeea7742011-09-11 12:30:36 -0700416 msm_pcm_routing_process_voice(mc->reg, mc->shift, 1);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700417 snd_soc_dapm_mixer_update_power(widget, kcontrol, 1);
418 } else {
Neema Shettyfeea7742011-09-11 12:30:36 -0700419 msm_pcm_routing_process_voice(mc->reg, mc->shift, 0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700420 snd_soc_dapm_mixer_update_power(widget, kcontrol, 0);
421 }
422
423 return 1;
424}
425
Sriranjan Srikantama4969dd2011-07-14 00:34:56 -0700426static int msm_routing_get_switch_mixer(struct snd_kcontrol *kcontrol,
427 struct snd_ctl_elem_value *ucontrol)
428{
429 ucontrol->value.integer.value[0] = fm_switch_enable;
430 pr_debug("%s: FM Switch enable %ld\n", __func__,
431 ucontrol->value.integer.value[0]);
432 return 0;
433}
434
435static int msm_routing_put_switch_mixer(struct snd_kcontrol *kcontrol,
436 struct snd_ctl_elem_value *ucontrol)
437{
Sriranjan Srikantamdf509d12011-10-24 17:53:27 -0700438 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
439 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
Sriranjan Srikantama4969dd2011-07-14 00:34:56 -0700440
441 pr_debug("%s: FM Switch enable %ld\n", __func__,
442 ucontrol->value.integer.value[0]);
443 if (ucontrol->value.integer.value[0])
444 snd_soc_dapm_mixer_update_power(widget, kcontrol, 1);
445 else
446 snd_soc_dapm_mixer_update_power(widget, kcontrol, 0);
447 fm_switch_enable = ucontrol->value.integer.value[0];
448 return 1;
449}
450
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700451static int msm_routing_get_port_mixer(struct snd_kcontrol *kcontrol,
452 struct snd_ctl_elem_value *ucontrol)
453{
454 struct soc_mixer_control *mc =
455 (struct soc_mixer_control *)kcontrol->private_value;
456
Patrick Laicf999112011-08-23 11:27:20 -0700457 if (test_bit(mc->shift, &msm_bedais[mc->reg].port_sessions))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700458 ucontrol->value.integer.value[0] = 1;
459 else
460 ucontrol->value.integer.value[0] = 0;
461
462 pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift,
463 ucontrol->value.integer.value[0]);
464
465 return 0;
466}
467
468static int msm_routing_put_port_mixer(struct snd_kcontrol *kcontrol,
469 struct snd_ctl_elem_value *ucontrol)
470{
471 struct soc_mixer_control *mc =
472 (struct soc_mixer_control *)kcontrol->private_value;
473
474 pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg,
475 mc->shift, ucontrol->value.integer.value[0]);
476
477 if (ucontrol->value.integer.value[0]) {
Patrick Laicf999112011-08-23 11:27:20 -0700478 afe_loopback(1, msm_bedais[mc->reg].port_id,
479 msm_bedais[mc->shift].port_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700480 set_bit(mc->shift,
Patrick Laicf999112011-08-23 11:27:20 -0700481 &msm_bedais[mc->reg].port_sessions);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700482 } else {
Patrick Laicf999112011-08-23 11:27:20 -0700483 afe_loopback(0, msm_bedais[mc->reg].port_id,
484 msm_bedais[mc->shift].port_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700485 clear_bit(mc->shift,
Patrick Laicf999112011-08-23 11:27:20 -0700486 &msm_bedais[mc->reg].port_sessions);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700487 }
488
489 return 1;
490}
491
Jayasena Sangaraboinacb1e22f2011-07-18 10:36:57 -0700492static int msm_routing_get_fm_vol_mixer(struct snd_kcontrol *kcontrol,
493 struct snd_ctl_elem_value *ucontrol)
494{
495 ucontrol->value.integer.value[0] = msm_route_fm_vol_control;
496 return 0;
497}
498
499static int msm_routing_set_fm_vol_mixer(struct snd_kcontrol *kcontrol,
500 struct snd_ctl_elem_value *ucontrol)
501{
502 afe_loopback_gain(INT_FM_TX , ucontrol->value.integer.value[0]);
503
504 msm_route_fm_vol_control = ucontrol->value.integer.value[0];
505
506 return 0;
507}
508
Asish Bhattacharya0ec76182011-07-29 16:58:11 +0530509static int msm_routing_get_lpa_vol_mixer(struct snd_kcontrol *kcontrol,
510 struct snd_ctl_elem_value *ucontrol)
511{
512 ucontrol->value.integer.value[0] = msm_route_lpa_vol_control;
513 return 0;
514}
515
516static int msm_routing_set_lpa_vol_mixer(struct snd_kcontrol *kcontrol,
517 struct snd_ctl_elem_value *ucontrol)
518{
519 if (!lpa_set_volume(ucontrol->value.integer.value[0]))
520 msm_route_lpa_vol_control =
521 ucontrol->value.integer.value[0];
522
523 return 0;
524}
525
Ben Romberger037dd2f2011-09-22 14:01:32 -0700526static void msm_send_eq_values(int eq_idx)
527{
528 int result;
529 struct audio_client *ac =
530 q6asm_get_audio_client(fe_dai_map[eq_idx][SESSION_TYPE_RX]);
531
532 if (ac == NULL) {
533 pr_err("%s: Could not get audio client for session: %d\n",
534 __func__, fe_dai_map[eq_idx][SESSION_TYPE_RX]);
535 goto done;
536 }
537
538 result = q6asm_equalizer(ac, &eq_data[eq_idx]);
539
540 if (result < 0)
541 pr_err("%s: Call to ASM equalizer failed, returned = %d\n",
542 __func__, result);
543done:
544 return;
545}
546
547static int msm_routing_get_eq_enable_mixer(struct snd_kcontrol *kcontrol,
548 struct snd_ctl_elem_value *ucontrol)
549{
550 int eq_idx = ((struct soc_multi_mixer_control *)
551 kcontrol->private_value)->reg;
552
Ben Romberger76f57032011-12-08 20:07:34 -0800553 ucontrol->value.integer.value[0] = eq_data[eq_idx].enable;
554
Ben Romberger037dd2f2011-09-22 14:01:32 -0700555 pr_debug("%s: EQ #%d enable %d\n", __func__,
556 eq_idx, eq_data[eq_idx].enable);
Ben Romberger76f57032011-12-08 20:07:34 -0800557 return 0;
Ben Romberger037dd2f2011-09-22 14:01:32 -0700558}
559
560static int msm_routing_put_eq_enable_mixer(struct snd_kcontrol *kcontrol,
561 struct snd_ctl_elem_value *ucontrol)
562{
563 int eq_idx = ((struct soc_multi_mixer_control *)
564 kcontrol->private_value)->reg;
565 int value = ucontrol->value.integer.value[0];
566
567 pr_debug("%s: EQ #%d enable %d\n", __func__,
568 eq_idx, value);
569 eq_data[eq_idx].enable = value;
570
571 msm_send_eq_values(eq_idx);
572 return 0;
573}
574
575static int msm_routing_get_eq_band_count_audio_mixer(
576 struct snd_kcontrol *kcontrol,
577 struct snd_ctl_elem_value *ucontrol)
578{
579 int eq_idx = ((struct soc_multi_mixer_control *)
580 kcontrol->private_value)->reg;
581
Ben Romberger76f57032011-12-08 20:07:34 -0800582 ucontrol->value.integer.value[0] = eq_data[eq_idx].num_bands;
583
Ben Romberger037dd2f2011-09-22 14:01:32 -0700584 pr_debug("%s: EQ #%d bands %d\n", __func__,
585 eq_idx, eq_data[eq_idx].num_bands);
586 return eq_data[eq_idx].num_bands;
587}
588
589static int msm_routing_put_eq_band_count_audio_mixer(
590 struct snd_kcontrol *kcontrol,
591 struct snd_ctl_elem_value *ucontrol)
592{
593 int eq_idx = ((struct soc_multi_mixer_control *)
594 kcontrol->private_value)->reg;
595 int value = ucontrol->value.integer.value[0];
596
Ben Romberger037dd2f2011-09-22 14:01:32 -0700597 pr_debug("%s: EQ #%d bands %d\n", __func__,
598 eq_idx, value);
599 eq_data[eq_idx].num_bands = value;
600 return 0;
601}
602
603static int msm_routing_get_eq_band_audio_mixer(struct snd_kcontrol *kcontrol,
604 struct snd_ctl_elem_value *ucontrol)
605{
606 int eq_idx = ((struct soc_multi_mixer_control *)
607 kcontrol->private_value)->reg;
608 int band_idx = ((struct soc_multi_mixer_control *)
609 kcontrol->private_value)->shift;
610
Ben Romberger76f57032011-12-08 20:07:34 -0800611 ucontrol->value.integer.value[0] =
612 eq_data[eq_idx].eq_bands[band_idx].band_idx;
613 ucontrol->value.integer.value[1] =
614 eq_data[eq_idx].eq_bands[band_idx].filter_type;
615 ucontrol->value.integer.value[2] =
616 eq_data[eq_idx].eq_bands[band_idx].center_freq_hz;
617 ucontrol->value.integer.value[3] =
618 eq_data[eq_idx].eq_bands[band_idx].filter_gain;
619 ucontrol->value.integer.value[4] =
620 eq_data[eq_idx].eq_bands[band_idx].q_factor;
621
Ben Romberger037dd2f2011-09-22 14:01:32 -0700622 pr_debug("%s: band_idx = %d\n", __func__,
623 eq_data[eq_idx].eq_bands[band_idx].band_idx);
624 pr_debug("%s: filter_type = %d\n", __func__,
625 eq_data[eq_idx].eq_bands[band_idx].filter_type);
626 pr_debug("%s: center_freq_hz = %d\n", __func__,
627 eq_data[eq_idx].eq_bands[band_idx].center_freq_hz);
628 pr_debug("%s: filter_gain = %d\n", __func__,
629 eq_data[eq_idx].eq_bands[band_idx].filter_gain);
630 pr_debug("%s: q_factor = %d\n", __func__,
631 eq_data[eq_idx].eq_bands[band_idx].q_factor);
632 return 0;
633}
634
635static int msm_routing_put_eq_band_audio_mixer(struct snd_kcontrol *kcontrol,
636 struct snd_ctl_elem_value *ucontrol)
637{
638 int eq_idx = ((struct soc_multi_mixer_control *)
639 kcontrol->private_value)->reg;
640 int band_idx = ((struct soc_multi_mixer_control *)
641 kcontrol->private_value)->shift;
642
643 eq_data[eq_idx].eq_bands[band_idx].band_idx =
644 ucontrol->value.integer.value[0];
645 eq_data[eq_idx].eq_bands[band_idx].filter_type =
646 ucontrol->value.integer.value[1];
647 eq_data[eq_idx].eq_bands[band_idx].center_freq_hz =
648 ucontrol->value.integer.value[2];
649 eq_data[eq_idx].eq_bands[band_idx].filter_gain =
650 ucontrol->value.integer.value[3];
651 eq_data[eq_idx].eq_bands[band_idx].q_factor =
652 ucontrol->value.integer.value[4];
653 return 0;
654}
655
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700656static const struct snd_kcontrol_new pri_i2s_rx_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700657 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_PRI_I2S_RX ,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700658 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
659 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700660 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_PRI_I2S_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700661 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
662 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700663 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_PRI_I2S_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700664 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
665 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530666 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_PRI_I2S_RX,
667 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
668 msm_routing_put_audio_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700669};
670
671static const struct snd_kcontrol_new slimbus_rx_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700672 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SLIMBUS_0_RX ,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700673 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
674 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700675 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SLIMBUS_0_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700676 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
677 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700678 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SLIMBUS_0_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700679 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
680 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530681 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SLIMBUS_0_RX,
682 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
683 msm_routing_put_audio_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700684};
685
Kuirong Wang274f21a2011-12-15 21:29:08 -0800686static const struct snd_kcontrol_new mi2s_rx_mixer_controls[] = {
687 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_MI2S_RX ,
688 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
689 msm_routing_put_audio_mixer),
690 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_MI2S_RX,
691 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
692 msm_routing_put_audio_mixer),
693 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_MI2S_RX,
694 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
695 msm_routing_put_audio_mixer),
696 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_MI2S_RX,
697 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
698 msm_routing_put_audio_mixer),
699};
700
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700701static const struct snd_kcontrol_new hdmi_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700702 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_HDMI_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700703 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
704 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700705 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_HDMI_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700706 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
707 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700708 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_HDMI_RX,
Asish Bhattacharyac592eed2011-09-16 17:43:02 +0530709 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
710 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530711 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_HDMI_RX,
712 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
713 msm_routing_put_audio_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700714};
Helen Zeng0705a5f2011-10-14 15:29:52 -0700715 /* incall music delivery mixer */
716static const struct snd_kcontrol_new incall_music_delivery_mixer_controls[] = {
717 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_VOICE_PLAYBACK_TX,
718 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
719 msm_routing_put_audio_mixer),
720 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_VOICE_PLAYBACK_TX,
721 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
722 msm_routing_put_audio_mixer),
723};
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700724
725static const struct snd_kcontrol_new int_bt_sco_rx_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700726 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_INT_BT_SCO_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700727 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
728 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700729 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_INT_BT_SCO_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700730 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
731 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700732 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_INT_BT_SCO_RX,
Asish Bhattacharyac592eed2011-09-16 17:43:02 +0530733 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
734 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530735 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_INT_BT_SCO_RX,
736 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
737 msm_routing_put_audio_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700738};
739
740static const struct snd_kcontrol_new int_fm_rx_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700741 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_INT_FM_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700742 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
743 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700744 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_INT_FM_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700745 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
746 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700747 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_INT_FM_RX,
Asish Bhattacharyac592eed2011-09-16 17:43:02 +0530748 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
749 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530750 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_INT_FM_RX,
751 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
752 msm_routing_put_audio_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700753};
754
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530755static const struct snd_kcontrol_new afe_pcm_rx_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700756 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_AFE_PCM_RX,
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530757 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
758 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700759 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_AFE_PCM_RX,
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530760 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
761 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700762 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_AFE_PCM_RX,
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530763 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
764 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530765 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_AFE_PCM_RX,
766 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
767 msm_routing_put_audio_mixer),
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530768};
769
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700770static const struct snd_kcontrol_new auxpcm_rx_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700771 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_AUXPCM_RX,
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700772 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
773 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700774 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_AUXPCM_RX,
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700775 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
776 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700777 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_AUXPCM_RX,
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700778 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
779 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530780 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_AUXPCM_RX,
781 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
782 msm_routing_put_audio_mixer),
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700783};
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530784
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700785static const struct snd_kcontrol_new mmul1_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700786 SOC_SINGLE_EXT("PRI_TX", MSM_BACKEND_DAI_PRI_I2S_TX,
787 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
788 msm_routing_put_audio_mixer),
789 SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX,
790 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
791 msm_routing_put_audio_mixer),
792 SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_AUXPCM_TX,
793 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
794 msm_routing_put_audio_mixer),
795 SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX,
796 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
797 msm_routing_put_audio_mixer),
798 SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX,
799 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
800 msm_routing_put_audio_mixer),
801 SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX,
802 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
803 msm_routing_put_audio_mixer),
Helen Zenge3d716a2011-10-14 16:32:16 -0700804 SOC_SINGLE_EXT("VOC_REC_DL", MSM_BACKEND_DAI_INCALL_RECORD_RX,
805 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
806 msm_routing_put_audio_mixer),
807 SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX,
808 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
809 msm_routing_put_audio_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700810};
811
Jayasena Sangaraboina99fee652011-09-19 07:43:13 -0700812static const struct snd_kcontrol_new mmul2_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700813 SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX,
814 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
Jayasena Sangaraboina99fee652011-09-19 07:43:13 -0700815 msm_routing_put_audio_mixer),
816};
817
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700818static const struct snd_kcontrol_new pri_rx_voice_mixer_controls[] = {
Neema Shettyfeea7742011-09-11 12:30:36 -0700819 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_PRI_I2S_RX,
820 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
821 msm_routing_put_voice_mixer),
822 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_PRI_I2S_RX,
823 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
824 msm_routing_put_voice_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700825};
826
827static const struct snd_kcontrol_new slimbus_rx_voice_mixer_controls[] = {
Neema Shettyfeea7742011-09-11 12:30:36 -0700828 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_SLIMBUS_0_RX,
829 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
830 msm_routing_put_voice_mixer),
831 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SLIMBUS_0_RX ,
832 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
833 msm_routing_put_voice_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700834};
835
836static const struct snd_kcontrol_new bt_sco_rx_voice_mixer_controls[] = {
Neema Shettyfeea7742011-09-11 12:30:36 -0700837 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_INT_BT_SCO_RX,
838 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
839 msm_routing_put_voice_mixer),
840 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_INT_BT_SCO_RX ,
841 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
842 msm_routing_put_voice_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700843};
844
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530845static const struct snd_kcontrol_new afe_pcm_rx_voice_mixer_controls[] = {
846 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_AFE_PCM_RX,
847 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
848 msm_routing_put_voice_mixer),
849 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_AFE_PCM_RX,
850 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
851 msm_routing_put_voice_mixer),
852};
853
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700854static const struct snd_kcontrol_new aux_pcm_rx_voice_mixer_controls[] = {
855 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_AUXPCM_RX,
856 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
857 msm_routing_put_voice_mixer),
858 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_AUXPCM_RX,
859 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
860 msm_routing_put_voice_mixer),
861};
862
Alex Wong593576c2011-11-15 08:03:24 -0800863static const struct snd_kcontrol_new hdmi_rx_voice_mixer_controls[] = {
864 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_HDMI_RX,
865 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
866 msm_routing_put_voice_mixer),
867 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_HDMI_RX,
868 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
869 msm_routing_put_voice_mixer),
870};
871
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700872static const struct snd_kcontrol_new tx_voice_mixer_controls[] = {
Neema Shettyfeea7742011-09-11 12:30:36 -0700873 SOC_SINGLE_EXT("PRI_TX_Voice", MSM_BACKEND_DAI_PRI_I2S_TX,
874 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
875 msm_routing_put_voice_mixer),
876 SOC_SINGLE_EXT("SLIM_0_TX_Voice", MSM_BACKEND_DAI_SLIMBUS_0_TX,
877 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
878 msm_routing_put_voice_mixer),
879 SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_Voice",
880 MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_CS_VOICE, 1, 0,
Neema Shetty2c07eb52011-08-21 20:33:52 -0700881 msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530882 SOC_SINGLE_EXT("AFE_PCM_TX_Voice", MSM_BACKEND_DAI_AFE_PCM_TX,
883 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
884 msm_routing_put_voice_mixer),
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700885 SOC_SINGLE_EXT("AUX_PCM_TX_Voice", MSM_BACKEND_DAI_AUXPCM_TX,
886 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
887 msm_routing_put_voice_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700888};
889
890static const struct snd_kcontrol_new tx_voip_mixer_controls[] = {
Neema Shettyfeea7742011-09-11 12:30:36 -0700891 SOC_SINGLE_EXT("PRI_TX_Voip", MSM_BACKEND_DAI_PRI_I2S_TX,
892 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
893 msm_routing_put_voice_mixer),
894 SOC_SINGLE_EXT("SLIM_0_TX_Voip", MSM_BACKEND_DAI_SLIMBUS_0_TX,
895 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
896 msm_routing_put_voice_mixer),
897 SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_Voip", MSM_BACKEND_DAI_INT_BT_SCO_TX,
898 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
899 msm_routing_put_voice_mixer),
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530900 SOC_SINGLE_EXT("AFE_PCM_TX_Voip", MSM_BACKEND_DAI_AFE_PCM_TX,
901 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
902 msm_routing_put_voice_mixer),
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700903 SOC_SINGLE_EXT("AUX_PCM_TX_Voip", MSM_BACKEND_DAI_AUXPCM_TX,
904 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
905 msm_routing_put_voice_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700906};
907
908static const struct snd_kcontrol_new sbus_0_rx_port_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700909 SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700910 MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer,
911 msm_routing_put_port_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700912 SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700913 MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer,
914 msm_routing_put_port_mixer),
915};
916
Sriranjan Srikantama4969dd2011-07-14 00:34:56 -0700917static const struct snd_kcontrol_new fm_switch_mixer_controls =
918 SOC_SINGLE_EXT("Switch", SND_SOC_NOPM,
919 0, 1, 0, msm_routing_get_switch_mixer,
920 msm_routing_put_switch_mixer);
921
Jayasena Sangaraboinacb1e22f2011-07-18 10:36:57 -0700922static const struct snd_kcontrol_new int_fm_vol_mixer_controls[] = {
923 SOC_SINGLE_EXT_TLV("Internal FM RX Volume", SND_SOC_NOPM, 0,
924 INT_FM_RX_VOL_GAIN, 0, msm_routing_get_fm_vol_mixer,
925 msm_routing_set_fm_vol_mixer, fm_rx_vol_gain),
926};
927
Asish Bhattacharya0ec76182011-07-29 16:58:11 +0530928static const struct snd_kcontrol_new lpa_vol_mixer_controls[] = {
929 SOC_SINGLE_EXT_TLV("LPA RX Volume", SND_SOC_NOPM, 0,
930 INT_LPA_RX_VOL_GAIN, 0, msm_routing_get_lpa_vol_mixer,
931 msm_routing_set_lpa_vol_mixer, lpa_rx_vol_gain),
932};
933
Ben Romberger037dd2f2011-09-22 14:01:32 -0700934static const struct snd_kcontrol_new eq_enable_mixer_controls[] = {
935 SOC_SINGLE_EXT("MultiMedia1 EQ Enable", SND_SOC_NOPM,
936 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_eq_enable_mixer,
937 msm_routing_put_eq_enable_mixer),
938 SOC_SINGLE_EXT("MultiMedia2 EQ Enable", SND_SOC_NOPM,
939 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_eq_enable_mixer,
940 msm_routing_put_eq_enable_mixer),
941 SOC_SINGLE_EXT("MultiMedia3 EQ Enable", SND_SOC_NOPM,
942 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_eq_enable_mixer,
943 msm_routing_put_eq_enable_mixer),
944};
945
946static const struct snd_kcontrol_new eq_band_mixer_controls[] = {
947 SOC_SINGLE_EXT("MultiMedia1 EQ Band Count", SND_SOC_NOPM,
948 MSM_FRONTEND_DAI_MULTIMEDIA1, 11, 0,
949 msm_routing_get_eq_band_count_audio_mixer,
950 msm_routing_put_eq_band_count_audio_mixer),
951 SOC_SINGLE_EXT("MultiMedia2 EQ Band Count", SND_SOC_NOPM,
952 MSM_FRONTEND_DAI_MULTIMEDIA2, 11, 0,
953 msm_routing_get_eq_band_count_audio_mixer,
954 msm_routing_put_eq_band_count_audio_mixer),
955 SOC_SINGLE_EXT("MultiMedia3 EQ Band Count", SND_SOC_NOPM,
956 MSM_FRONTEND_DAI_MULTIMEDIA3, 11, 0,
957 msm_routing_get_eq_band_count_audio_mixer,
958 msm_routing_put_eq_band_count_audio_mixer),
959};
960
961static const struct snd_kcontrol_new eq_coeff_mixer_controls[] = {
962 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band1", EQ_BAND1,
963 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
964 msm_routing_get_eq_band_audio_mixer,
965 msm_routing_put_eq_band_audio_mixer),
966 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band2", EQ_BAND2,
967 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
968 msm_routing_get_eq_band_audio_mixer,
969 msm_routing_put_eq_band_audio_mixer),
970 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band3", EQ_BAND3,
971 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
972 msm_routing_get_eq_band_audio_mixer,
973 msm_routing_put_eq_band_audio_mixer),
974 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band4", EQ_BAND4,
975 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
976 msm_routing_get_eq_band_audio_mixer,
977 msm_routing_put_eq_band_audio_mixer),
978 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band5", EQ_BAND5,
979 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
980 msm_routing_get_eq_band_audio_mixer,
981 msm_routing_put_eq_band_audio_mixer),
982 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band6", EQ_BAND6,
983 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
984 msm_routing_get_eq_band_audio_mixer,
985 msm_routing_put_eq_band_audio_mixer),
986 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band7", EQ_BAND7,
987 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
988 msm_routing_get_eq_band_audio_mixer,
989 msm_routing_put_eq_band_audio_mixer),
990 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band8", EQ_BAND8,
991 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
992 msm_routing_get_eq_band_audio_mixer,
993 msm_routing_put_eq_band_audio_mixer),
994 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band9", EQ_BAND9,
995 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
996 msm_routing_get_eq_band_audio_mixer,
997 msm_routing_put_eq_band_audio_mixer),
998 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band10", EQ_BAND10,
999 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
1000 msm_routing_get_eq_band_audio_mixer,
1001 msm_routing_put_eq_band_audio_mixer),
1002 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band11", EQ_BAND11,
1003 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
1004 msm_routing_get_eq_band_audio_mixer,
1005 msm_routing_put_eq_band_audio_mixer),
1006 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band12", EQ_BAND12,
1007 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
1008 msm_routing_get_eq_band_audio_mixer,
1009 msm_routing_put_eq_band_audio_mixer),
1010 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band1", EQ_BAND1,
1011 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1012 msm_routing_get_eq_band_audio_mixer,
1013 msm_routing_put_eq_band_audio_mixer),
1014 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band2", EQ_BAND2,
1015 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1016 msm_routing_get_eq_band_audio_mixer,
1017 msm_routing_put_eq_band_audio_mixer),
1018 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band3", EQ_BAND3,
1019 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1020 msm_routing_get_eq_band_audio_mixer,
1021 msm_routing_put_eq_band_audio_mixer),
1022 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band4", EQ_BAND4,
1023 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1024 msm_routing_get_eq_band_audio_mixer,
1025 msm_routing_put_eq_band_audio_mixer),
1026 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band5", EQ_BAND5,
1027 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1028 msm_routing_get_eq_band_audio_mixer,
1029 msm_routing_put_eq_band_audio_mixer),
1030 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band6", EQ_BAND6,
1031 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1032 msm_routing_get_eq_band_audio_mixer,
1033 msm_routing_put_eq_band_audio_mixer),
1034 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band7", EQ_BAND7,
1035 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1036 msm_routing_get_eq_band_audio_mixer,
1037 msm_routing_put_eq_band_audio_mixer),
1038 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band8", EQ_BAND8,
1039 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1040 msm_routing_get_eq_band_audio_mixer,
1041 msm_routing_put_eq_band_audio_mixer),
1042 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band9", EQ_BAND9,
1043 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1044 msm_routing_get_eq_band_audio_mixer,
1045 msm_routing_put_eq_band_audio_mixer),
1046 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band10", EQ_BAND10,
1047 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1048 msm_routing_get_eq_band_audio_mixer,
1049 msm_routing_put_eq_band_audio_mixer),
1050 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band11", EQ_BAND11,
1051 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1052 msm_routing_get_eq_band_audio_mixer,
1053 msm_routing_put_eq_band_audio_mixer),
1054 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band12", EQ_BAND12,
1055 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1056 msm_routing_get_eq_band_audio_mixer,
1057 msm_routing_put_eq_band_audio_mixer),
1058 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band1", EQ_BAND1,
1059 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1060 msm_routing_get_eq_band_audio_mixer,
1061 msm_routing_put_eq_band_audio_mixer),
1062 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band2", EQ_BAND2,
1063 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1064 msm_routing_get_eq_band_audio_mixer,
1065 msm_routing_put_eq_band_audio_mixer),
1066 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band3", EQ_BAND3,
1067 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1068 msm_routing_get_eq_band_audio_mixer,
1069 msm_routing_put_eq_band_audio_mixer),
1070 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band4", EQ_BAND4,
1071 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1072 msm_routing_get_eq_band_audio_mixer,
1073 msm_routing_put_eq_band_audio_mixer),
1074 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band5", EQ_BAND5,
1075 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1076 msm_routing_get_eq_band_audio_mixer,
1077 msm_routing_put_eq_band_audio_mixer),
1078 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band6", EQ_BAND6,
1079 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1080 msm_routing_get_eq_band_audio_mixer,
1081 msm_routing_put_eq_band_audio_mixer),
1082 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band7", EQ_BAND7,
1083 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1084 msm_routing_get_eq_band_audio_mixer,
1085 msm_routing_put_eq_band_audio_mixer),
1086 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band8", EQ_BAND8,
1087 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1088 msm_routing_get_eq_band_audio_mixer,
1089 msm_routing_put_eq_band_audio_mixer),
1090 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band9", EQ_BAND9,
1091 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1092 msm_routing_get_eq_band_audio_mixer,
1093 msm_routing_put_eq_band_audio_mixer),
1094 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band10", EQ_BAND10,
1095 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1096 msm_routing_get_eq_band_audio_mixer,
1097 msm_routing_put_eq_band_audio_mixer),
1098 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band11", EQ_BAND11,
1099 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1100 msm_routing_get_eq_band_audio_mixer,
1101 msm_routing_put_eq_band_audio_mixer),
1102 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band12", EQ_BAND12,
1103 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1104 msm_routing_get_eq_band_audio_mixer,
1105 msm_routing_put_eq_band_audio_mixer),
1106};
1107
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001108static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
1109 /* Frontend AIF */
1110 /* Widget name equals to Front-End DAI name<Need confirmation>,
1111 * Stream name must contains substring of front-end dai name
1112 */
1113 SND_SOC_DAPM_AIF_IN("MM_DL1", "MultiMedia1 Playback", 0, 0, 0, 0),
1114 SND_SOC_DAPM_AIF_IN("MM_DL2", "MultiMedia2 Playback", 0, 0, 0, 0),
1115 SND_SOC_DAPM_AIF_IN("MM_DL3", "MultiMedia3 Playback", 0, 0, 0, 0),
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301116 SND_SOC_DAPM_AIF_IN("MM_DL4", "MultiMedia4 Playback", 0, 0, 0, 0),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001117 SND_SOC_DAPM_AIF_IN("VOIP_DL", "VoIP Playback", 0, 0, 0, 0),
1118 SND_SOC_DAPM_AIF_OUT("MM_UL1", "MultiMedia1 Capture", 0, 0, 0, 0),
Jayasena Sangaraboina99fee652011-09-19 07:43:13 -07001119 SND_SOC_DAPM_AIF_OUT("MM_UL2", "MultiMedia2 Capture", 0, 0, 0, 0),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001120 SND_SOC_DAPM_AIF_IN("CS-VOICE_DL1", "CS-VOICE Playback", 0, 0, 0, 0),
1121 SND_SOC_DAPM_AIF_OUT("CS-VOICE_UL1", "CS-VOICE Capture", 0, 0, 0, 0),
1122 SND_SOC_DAPM_AIF_OUT("VOIP_UL", "VoIP Capture", 0, 0, 0, 0),
1123 SND_SOC_DAPM_AIF_IN("SLIM0_DL_HL", "SLIMBUS0_HOSTLESS Playback",
1124 0, 0, 0, 0),
1125 SND_SOC_DAPM_AIF_OUT("SLIM0_UL_HL", "SLIMBUS0_HOSTLESS Capture",
1126 0, 0, 0, 0),
1127 SND_SOC_DAPM_AIF_IN("INTFM_DL_HL", "INT_FM_HOSTLESS Playback",
1128 0, 0, 0, 0),
1129 SND_SOC_DAPM_AIF_OUT("INTFM_UL_HL", "INT_FM_HOSTLESS Capture",
1130 0, 0, 0, 0),
1131 /* Backend AIF */
1132 /* Stream name equals to backend dai link stream name
1133 */
1134 SND_SOC_DAPM_AIF_OUT("PRI_I2S_RX", "Primary I2S Playback", 0, 0, 0, 0),
1135 SND_SOC_DAPM_AIF_OUT("SLIMBUS_0_RX", "Slimbus Playback", 0, 0, 0, 0),
1136 SND_SOC_DAPM_AIF_OUT("HDMI", "HDMI Playback", 0, 0, 0 , 0),
Kuirong Wang274f21a2011-12-15 21:29:08 -08001137 SND_SOC_DAPM_AIF_OUT("MI2S_RX", "MI2S Playback", 0, 0, 0, 0),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001138 SND_SOC_DAPM_AIF_IN("PRI_I2S_TX", "Primary I2S Capture", 0, 0, 0, 0),
1139 SND_SOC_DAPM_AIF_IN("SLIMBUS_0_TX", "Slimbus Capture", 0, 0, 0, 0),
1140 SND_SOC_DAPM_AIF_OUT("INT_BT_SCO_RX", "Internal BT-SCO Playback",
1141 0, 0, 0 , 0),
1142 SND_SOC_DAPM_AIF_IN("INT_BT_SCO_TX", "Internal BT-SCO Capture",
1143 0, 0, 0, 0),
1144 SND_SOC_DAPM_AIF_OUT("INT_FM_RX", "Internal FM Playback",
1145 0, 0, 0 , 0),
1146 SND_SOC_DAPM_AIF_IN("INT_FM_TX", "Internal FM Capture",
1147 0, 0, 0, 0),
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301148 SND_SOC_DAPM_AIF_OUT("PCM_RX", "AFE Playback",
1149 0, 0, 0 , 0),
1150 SND_SOC_DAPM_AIF_IN("PCM_TX", "AFE Capture",
Helen Zeng0705a5f2011-10-14 15:29:52 -07001151 0, 0, 0 , 0),
1152 /* incall */
1153 SND_SOC_DAPM_AIF_OUT("VOICE_PLAYBACK_TX", "Voice Farend Playback",
1154 0, 0, 0 , 0),
Helen Zenge3d716a2011-10-14 16:32:16 -07001155 SND_SOC_DAPM_AIF_IN("INCALL_RECORD_TX", "Voice Uplink Capture",
1156 0, 0, 0, 0),
1157 SND_SOC_DAPM_AIF_IN("INCALL_RECORD_RX", "Voice Downlink Capture",
1158 0, 0, 0, 0),
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001159 SND_SOC_DAPM_AIF_OUT("AUX_PCM_RX", "AUX PCM Playback", 0, 0, 0, 0),
1160 SND_SOC_DAPM_AIF_IN("AUX_PCM_TX", "AUX PCM Capture", 0, 0, 0, 0),
Sriranjan Srikantama4969dd2011-07-14 00:34:56 -07001161 /* Switch Definitions */
Sriranjan Srikantamdf509d12011-10-24 17:53:27 -07001162 SND_SOC_DAPM_SWITCH("SLIMBUS_DL_HL", SND_SOC_NOPM, 0, 0,
Sriranjan Srikantama4969dd2011-07-14 00:34:56 -07001163 &fm_switch_mixer_controls),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001164 /* Mixer definitions */
1165 SND_SOC_DAPM_MIXER("PRI_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1166 pri_i2s_rx_mixer_controls, ARRAY_SIZE(pri_i2s_rx_mixer_controls)),
1167 SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1168 slimbus_rx_mixer_controls, ARRAY_SIZE(slimbus_rx_mixer_controls)),
1169 SND_SOC_DAPM_MIXER("HDMI Mixer", SND_SOC_NOPM, 0, 0,
1170 hdmi_mixer_controls, ARRAY_SIZE(hdmi_mixer_controls)),
Kuirong Wang274f21a2011-12-15 21:29:08 -08001171 SND_SOC_DAPM_MIXER("MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1172 mi2s_rx_mixer_controls, ARRAY_SIZE(mi2s_rx_mixer_controls)),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001173 SND_SOC_DAPM_MIXER("MultiMedia1 Mixer", SND_SOC_NOPM, 0, 0,
1174 mmul1_mixer_controls, ARRAY_SIZE(mmul1_mixer_controls)),
Jayasena Sangaraboina99fee652011-09-19 07:43:13 -07001175 SND_SOC_DAPM_MIXER("MultiMedia2 Mixer", SND_SOC_NOPM, 0, 0,
1176 mmul2_mixer_controls, ARRAY_SIZE(mmul2_mixer_controls)),
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001177 SND_SOC_DAPM_MIXER("AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1178 auxpcm_rx_mixer_controls, ARRAY_SIZE(auxpcm_rx_mixer_controls)),
Helen Zeng0705a5f2011-10-14 15:29:52 -07001179 /* incall */
1180 SND_SOC_DAPM_MIXER("Incall_Music Audio Mixer", SND_SOC_NOPM, 0, 0,
1181 incall_music_delivery_mixer_controls,
1182 ARRAY_SIZE(incall_music_delivery_mixer_controls)),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001183 /* Voice Mixer */
1184 SND_SOC_DAPM_MIXER("PRI_RX_Voice Mixer",
1185 SND_SOC_NOPM, 0, 0, pri_rx_voice_mixer_controls,
1186 ARRAY_SIZE(pri_rx_voice_mixer_controls)),
1187 SND_SOC_DAPM_MIXER("SLIM_0_RX_Voice Mixer",
1188 SND_SOC_NOPM, 0, 0,
1189 slimbus_rx_voice_mixer_controls,
1190 ARRAY_SIZE(slimbus_rx_voice_mixer_controls)),
1191 SND_SOC_DAPM_MIXER("INTERNAL_BT_SCO_RX_Voice Mixer",
1192 SND_SOC_NOPM, 0, 0,
1193 bt_sco_rx_voice_mixer_controls,
1194 ARRAY_SIZE(bt_sco_rx_voice_mixer_controls)),
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301195 SND_SOC_DAPM_MIXER("AFE_PCM_RX_Voice Mixer",
1196 SND_SOC_NOPM, 0, 0,
1197 afe_pcm_rx_voice_mixer_controls,
1198 ARRAY_SIZE(afe_pcm_rx_voice_mixer_controls)),
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001199 SND_SOC_DAPM_MIXER("AUX_PCM_RX_Voice Mixer",
1200 SND_SOC_NOPM, 0, 0,
1201 aux_pcm_rx_voice_mixer_controls,
1202 ARRAY_SIZE(aux_pcm_rx_voice_mixer_controls)),
Alex Wong593576c2011-11-15 08:03:24 -08001203 SND_SOC_DAPM_MIXER("HDMI_RX_Voice Mixer",
1204 SND_SOC_NOPM, 0, 0,
1205 hdmi_rx_voice_mixer_controls,
1206 ARRAY_SIZE(hdmi_rx_voice_mixer_controls)),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001207 SND_SOC_DAPM_MIXER("Voice_Tx Mixer",
1208 SND_SOC_NOPM, 0, 0, tx_voice_mixer_controls,
1209 ARRAY_SIZE(tx_voice_mixer_controls)),
1210 SND_SOC_DAPM_MIXER("Voip_Tx Mixer",
1211 SND_SOC_NOPM, 0, 0, tx_voip_mixer_controls,
1212 ARRAY_SIZE(tx_voip_mixer_controls)),
1213 SND_SOC_DAPM_MIXER("INTERNAL_BT_SCO_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1214 int_bt_sco_rx_mixer_controls, ARRAY_SIZE(int_bt_sco_rx_mixer_controls)),
1215 SND_SOC_DAPM_MIXER("INTERNAL_FM_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1216 int_fm_rx_mixer_controls, ARRAY_SIZE(int_fm_rx_mixer_controls)),
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301217 SND_SOC_DAPM_MIXER("AFE_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1218 afe_pcm_rx_mixer_controls, ARRAY_SIZE(afe_pcm_rx_mixer_controls)),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001219 SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Port Mixer",
1220 SND_SOC_NOPM, 0, 0, sbus_0_rx_port_mixer_controls,
1221 ARRAY_SIZE(sbus_0_rx_port_mixer_controls)),
1222};
1223
1224static const struct snd_soc_dapm_route intercon[] = {
1225 {"PRI_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1226 {"PRI_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
1227 {"PRI_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301228 {"PRI_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001229 {"PRI_I2S_RX", NULL, "PRI_RX Audio Mixer"},
1230
1231 {"SLIMBUS_0_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1232 {"SLIMBUS_0_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
1233 {"SLIMBUS_0_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301234 {"SLIMBUS_0_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001235 {"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Audio Mixer"},
1236
1237 {"HDMI Mixer", "MultiMedia1", "MM_DL1"},
1238 {"HDMI Mixer", "MultiMedia2", "MM_DL2"},
Asish Bhattacharyac592eed2011-09-16 17:43:02 +05301239 {"HDMI Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301240 {"HDMI Mixer", "MultiMedia4", "MM_DL4"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001241 {"HDMI", NULL, "HDMI Mixer"},
1242
Helen Zeng0705a5f2011-10-14 15:29:52 -07001243 /* incall */
1244 {"Incall_Music Audio Mixer", "MultiMedia1", "MM_DL1"},
1245 {"Incall_Music Audio Mixer", "MultiMedia2", "MM_DL2"},
1246 {"VOICE_PLAYBACK_TX", NULL, "Incall_Music Audio Mixer"},
Helen Zenge3d716a2011-10-14 16:32:16 -07001247
1248 {"MultiMedia1 Mixer", "VOC_REC_UL", "INCALL_RECORD_TX"},
1249 {"MultiMedia1 Mixer", "VOC_REC_DL", "INCALL_RECORD_RX"},
Kuirong Wang274f21a2011-12-15 21:29:08 -08001250 {"MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1251 {"MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
1252 {"MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
1253 {"MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
1254 {"MI2S_RX", NULL, "MI2S_RX Audio Mixer"},
Helen Zenge3d716a2011-10-14 16:32:16 -07001255
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001256 {"MultiMedia1 Mixer", "PRI_TX", "PRI_I2S_TX"},
1257 {"MultiMedia1 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001258 {"MultiMedia1 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001259
1260 {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1261 {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
Asish Bhattacharyac592eed2011-09-16 17:43:02 +05301262 {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301263 {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001264 {"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX Audio Mixer"},
1265
1266 {"INTERNAL_FM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1267 {"INTERNAL_FM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
Asish Bhattacharyac592eed2011-09-16 17:43:02 +05301268 {"INTERNAL_FM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301269 {"INTERNAL_FM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001270 {"INT_FM_RX", NULL, "INTERNAL_FM_RX Audio Mixer"},
1271
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301272 {"AFE_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1273 {"AFE_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
1274 {"AFE_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301275 {"AFE_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301276 {"PCM_RX", NULL, "AFE_PCM_RX Audio Mixer"},
1277
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001278 {"MultiMedia1 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
1279 {"MultiMedia1 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301280
1281 {"MultiMedia1 Mixer", "AFE_PCM_TX", "PCM_TX"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001282 {"MM_UL1", NULL, "MultiMedia1 Mixer"},
Jayasena Sangaraboina99fee652011-09-19 07:43:13 -07001283 {"MultiMedia2 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
1284 {"MM_UL2", NULL, "MultiMedia2 Mixer"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001285
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001286 {"AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1287 {"AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
1288 {"AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301289 {"AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001290 {"AUX_PCM_RX", NULL, "AUX_PCM_RX Audio Mixer"},
1291
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001292 {"PRI_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1293 {"PRI_RX_Voice Mixer", "Voip", "VOIP_DL"},
1294 {"PRI_I2S_RX", NULL, "PRI_RX_Voice Mixer"},
1295
1296 {"SLIM_0_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1297 {"SLIM_0_RX_Voice Mixer", "Voip", "VOIP_DL"},
1298 {"SLIMBUS_0_RX", NULL, "SLIM_0_RX_Voice Mixer"},
1299
1300 {"INTERNAL_BT_SCO_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1301 {"INTERNAL_BT_SCO_RX_Voice Mixer", "Voip", "VOIP_DL"},
1302 {"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX_Voice Mixer"},
1303
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301304 {"AFE_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1305 {"AFE_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"},
1306 {"PCM_RX", NULL, "AFE_PCM_RX_Voice Mixer"},
1307
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001308 {"AUX_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1309 {"AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"},
1310 {"AUX_PCM_RX", NULL, "AUX_PCM_RX_Voice Mixer"},
1311
Alex Wong593576c2011-11-15 08:03:24 -08001312 {"HDMI_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1313 {"HDMI_RX_Voice Mixer", "Voip", "VOIP_DL"},
1314 {"HDMI", NULL, "HDMI_RX_Voice Mixer"},
1315
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001316 {"Voice_Tx Mixer", "PRI_TX_Voice", "PRI_I2S_TX"},
1317 {"Voice_Tx Mixer", "SLIM_0_TX_Voice", "SLIMBUS_0_TX"},
1318 {"Voice_Tx Mixer", "INTERNAL_BT_SCO_TX_Voice", "INT_BT_SCO_TX"},
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301319 {"Voice_Tx Mixer", "AFE_PCM_TX_Voice", "PCM_TX"},
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001320 {"Voice_Tx Mixer", "AUX_PCM_TX_Voice", "AUX_PCM_TX"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001321 {"CS-VOICE_UL1", NULL, "Voice_Tx Mixer"},
1322 {"Voip_Tx Mixer", "PRI_TX_Voip", "PRI_I2S_TX"},
1323 {"Voip_Tx Mixer", "SLIM_0_TX_Voip", "SLIMBUS_0_TX"},
1324 {"Voip_Tx Mixer", "INTERNAL_BT_SCO_TX_Voip", "INT_BT_SCO_TX"},
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301325 {"Voip_Tx Mixer", "AFE_PCM_TX_Voip", "PCM_TX"},
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001326 {"Voip_Tx Mixer", "AUX_PCM_TX_Voip", "AUX_PCM_TX"},
1327
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001328 {"VOIP_UL", NULL, "Voip_Tx Mixer"},
Sriranjan Srikantamdf509d12011-10-24 17:53:27 -07001329 {"SLIMBUS_DL_HL", "Switch", "SLIM0_DL_HL"},
1330 {"SLIMBUS_0_RX", NULL, "SLIMBUS_DL_HL"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001331 {"SLIM0_UL_HL", NULL, "SLIMBUS_0_TX"},
1332 {"INT_FM_RX", NULL, "INTFM_DL_HL"},
1333 {"INTFM_UL_HL", NULL, "INT_FM_TX"},
1334 {"SLIMBUS_0_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
1335 {"SLIMBUS_0_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
1336 {"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Port Mixer"},
1337};
1338
Patrick Laicf999112011-08-23 11:27:20 -07001339static int msm_pcm_routing_hw_params(struct snd_pcm_substream *substream,
1340 struct snd_pcm_hw_params *params)
1341{
1342 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1343 unsigned int be_id = rtd->dai_link->be_id;
1344
Patrick Lai770ca3e42011-12-12 13:44:54 -08001345 if (be_id >= MSM_BACKEND_DAI_MAX) {
1346 pr_err("%s: unexpected be_id %d\n", __func__, be_id);
1347 return -EINVAL;
1348 }
1349
Patrick Laicf999112011-08-23 11:27:20 -07001350 mutex_lock(&routing_lock);
1351 msm_bedais[be_id].hw_params = params;
1352 mutex_unlock(&routing_lock);
1353 return 0;
1354}
1355
1356static int msm_pcm_routing_close(struct snd_pcm_substream *substream)
1357{
1358 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1359 unsigned int be_id = rtd->dai_link->be_id;
1360 int i, session_type;
1361 struct msm_pcm_routing_bdai_data *bedai;
1362
1363 if (be_id >= MSM_BACKEND_DAI_MAX) {
1364 pr_err("%s: unexpected be_id %d\n", __func__, be_id);
1365 return -EINVAL;
1366 }
1367
1368 bedai = &msm_bedais[be_id];
1369
1370 session_type = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
1371 0 : 1);
1372
1373 mutex_lock(&routing_lock);
1374
Asish Bhattacharya70b43c72011-12-29 00:50:38 +05301375 for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MM_SIZE) {
Patrick Laicf999112011-08-23 11:27:20 -07001376 if (fe_dai_map[i][session_type] != INVALID_SESSION)
1377 adm_close(bedai->port_id);
1378 }
1379
1380 bedai->active = 0;
1381 bedai->hw_params = NULL;
1382
1383 mutex_unlock(&routing_lock);
1384
1385 return 0;
1386}
1387
1388static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream)
1389{
1390 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1391 unsigned int be_id = rtd->dai_link->be_id;
1392 int i, path_type, session_type;
1393 struct msm_pcm_routing_bdai_data *bedai;
1394
1395 if (be_id >= MSM_BACKEND_DAI_MAX) {
1396 pr_err("%s: unexpected be_id %d\n", __func__, be_id);
1397 return -EINVAL;
1398 }
1399
1400
1401 bedai = &msm_bedais[be_id];
1402
Jay Wangc8e03a82011-10-31 11:53:23 -07001403 if (bedai->hw_params == NULL) {
1404 pr_err("%s: HW param is not configured", __func__);
1405 return -EINVAL;
1406 }
1407
1408
Patrick Laicf999112011-08-23 11:27:20 -07001409 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1410 path_type = ADM_PATH_PLAYBACK;
1411 session_type = SESSION_TYPE_RX;
1412 } else {
1413 path_type = ADM_PATH_LIVE_REC;
1414 session_type = SESSION_TYPE_TX;
1415 }
1416
1417 mutex_lock(&routing_lock);
1418
1419 if (bedai->active == 1)
1420 goto done; /* Ignore prepare if back-end already active */
1421
1422 /* AFE port is not active at this point. However, still
1423 * go ahead setting active flag under the notion that
1424 * QDSP6 is able to handle ADM starting before AFE port
1425 * is started.
1426 */
1427 bedai->active = 1;
1428
Asish Bhattacharya70b43c72011-12-29 00:50:38 +05301429 for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MM_SIZE) {
Patrick Laicf999112011-08-23 11:27:20 -07001430 if (fe_dai_map[i][session_type] != INVALID_SESSION) {
1431 adm_open(bedai->port_id, path_type,
1432 params_rate(bedai->hw_params),
1433 params_channels(bedai->hw_params),
1434 DEFAULT_COPP_TOPOLOGY);
1435 msm_pcm_routing_build_matrix(i,
1436 fe_dai_map[i][session_type], path_type);
1437 }
1438 }
1439
1440done:
1441 mutex_unlock(&routing_lock);
1442
1443 return 0;
1444}
1445
1446static struct snd_pcm_ops msm_routing_pcm_ops = {
1447 .hw_params = msm_pcm_routing_hw_params,
1448 .close = msm_pcm_routing_close,
1449 .prepare = msm_pcm_routing_prepare,
1450};
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001451
1452static unsigned int msm_routing_read(struct snd_soc_platform *platform,
1453 unsigned int reg)
1454{
1455 dev_dbg(platform->dev, "reg %x\n", reg);
1456 return 0;
1457}
1458
1459/* Not used but frame seems to require it */
1460static int msm_routing_write(struct snd_soc_platform *platform,
1461 unsigned int reg, unsigned int val)
1462{
1463 dev_dbg(platform->dev, "reg %x val %x\n", reg, val);
1464 return 0;
1465}
1466
1467/* Not used but frame seems to require it */
1468static int msm_routing_probe(struct snd_soc_platform *platform)
1469{
1470 snd_soc_dapm_new_controls(&platform->dapm, msm_qdsp6_widgets,
1471 ARRAY_SIZE(msm_qdsp6_widgets));
1472 snd_soc_dapm_add_routes(&platform->dapm, intercon,
1473 ARRAY_SIZE(intercon));
1474
1475 snd_soc_dapm_new_widgets(&platform->dapm);
1476
Jayasena Sangaraboinacb1e22f2011-07-18 10:36:57 -07001477 snd_soc_add_platform_controls(platform,
1478 int_fm_vol_mixer_controls,
1479 ARRAY_SIZE(int_fm_vol_mixer_controls));
Asish Bhattacharya0ec76182011-07-29 16:58:11 +05301480
1481 snd_soc_add_platform_controls(platform,
1482 lpa_vol_mixer_controls,
1483 ARRAY_SIZE(lpa_vol_mixer_controls));
Ben Romberger037dd2f2011-09-22 14:01:32 -07001484
1485 snd_soc_add_platform_controls(platform,
1486 eq_enable_mixer_controls,
1487 ARRAY_SIZE(eq_enable_mixer_controls));
1488
1489 snd_soc_add_platform_controls(platform,
1490 eq_band_mixer_controls,
1491 ARRAY_SIZE(eq_band_mixer_controls));
1492
1493 snd_soc_add_platform_controls(platform,
1494 eq_coeff_mixer_controls,
1495 ARRAY_SIZE(eq_coeff_mixer_controls));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001496 return 0;
1497}
1498
1499static struct snd_soc_platform_driver msm_soc_routing_platform = {
1500 .ops = &msm_routing_pcm_ops,
1501 .probe = msm_routing_probe,
1502 .read = msm_routing_read,
1503 .write = msm_routing_write,
1504};
1505
1506static __devinit int msm_routing_pcm_probe(struct platform_device *pdev)
1507{
1508 dev_dbg(&pdev->dev, "dev name %s\n", dev_name(&pdev->dev));
1509 return snd_soc_register_platform(&pdev->dev,
1510 &msm_soc_routing_platform);
1511}
1512
1513static int msm_routing_pcm_remove(struct platform_device *pdev)
1514{
1515 snd_soc_unregister_platform(&pdev->dev);
1516 return 0;
1517}
1518
1519static struct platform_driver msm_routing_pcm_driver = {
1520 .driver = {
1521 .name = "msm-pcm-routing",
1522 .owner = THIS_MODULE,
1523 },
1524 .probe = msm_routing_pcm_probe,
1525 .remove = __devexit_p(msm_routing_pcm_remove),
1526};
1527
1528static int __init msm_soc_routing_platform_init(void)
1529{
Neema Shettyfeea7742011-09-11 12:30:36 -07001530 mutex_init(&routing_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001531 return platform_driver_register(&msm_routing_pcm_driver);
1532}
1533module_init(msm_soc_routing_platform_init);
1534
1535static void __exit msm_soc_routing_platform_exit(void)
1536{
1537 platform_driver_unregister(&msm_routing_pcm_driver);
1538}
1539module_exit(msm_soc_routing_platform_exit);
1540
1541MODULE_DESCRIPTION("MSM routing platform driver");
1542MODULE_LICENSE("GPL v2");