blob: 453bce49a5ec22a62e745785c64f9448e92a5deb [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},
Neema Shettyfeea7742011-09-11 12:30:36 -0700120};
121
122
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700123/* Track ASM playback & capture sessions of DAI */
Patrick Lai770ca3e42011-12-12 13:44:54 -0800124static int fe_dai_map[MSM_FRONTEND_DAI_MM_SIZE][2] = {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700125 /* MULTIMEDIA1 */
126 {INVALID_SESSION, INVALID_SESSION},
127 /* MULTIMEDIA2 */
128 {INVALID_SESSION, INVALID_SESSION},
129 /* MULTIMEDIA3 */
130 {INVALID_SESSION, INVALID_SESSION},
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530131 /* MULTIMEDIA4 */
132 {INVALID_SESSION, INVALID_SESSION},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700133};
134
Patrick Laicf999112011-08-23 11:27:20 -0700135static void msm_pcm_routing_build_matrix(int fedai_id, int dspst_id,
136 int path_type)
137{
138 int i, port_type;
139 struct route_payload payload;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700140
Patrick Laicf999112011-08-23 11:27:20 -0700141 payload.num_copps = 0;
142 port_type = (path_type == ADM_PATH_PLAYBACK ?
143 MSM_AFE_PORT_TYPE_RX : MSM_AFE_PORT_TYPE_TX);
144
145 for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) {
146 if ((afe_get_port_type(msm_bedais[i].port_id) ==
147 port_type) &&
148 msm_bedais[i].active && (test_bit(fedai_id,
149 &msm_bedais[i].fe_sessions)))
150 payload.copp_ids[payload.num_copps++] =
151 msm_bedais[i].port_id;
152 }
153
154 if (payload.num_copps)
155 adm_matrix_map(dspst_id, path_type,
156 payload.num_copps, payload.copp_ids, 0);
157}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700158
159void msm_pcm_routing_reg_phy_stream(int fedai_id, int dspst_id, int stream_type)
160{
Patrick Laicf999112011-08-23 11:27:20 -0700161 int i, session_type, path_type, port_type;
162 struct route_payload payload;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700163
Patrick Lai770ca3e42011-12-12 13:44:54 -0800164 if (fedai_id > MSM_FRONTEND_DAI_MM_MAX_ID) {
165 /* bad ID assigned in machine driver */
166 pr_err("%s: bad MM ID\n", __func__);
167 return;
168 }
169
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700170 if (stream_type == SNDRV_PCM_STREAM_PLAYBACK) {
Patrick Laicf999112011-08-23 11:27:20 -0700171 session_type = SESSION_TYPE_RX;
172 path_type = ADM_PATH_PLAYBACK;
173 port_type = MSM_AFE_PORT_TYPE_RX;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700174 } else {
Patrick Laicf999112011-08-23 11:27:20 -0700175 session_type = SESSION_TYPE_TX;
176 path_type = ADM_PATH_LIVE_REC;
177 port_type = MSM_AFE_PORT_TYPE_TX;
178 }
179
180 mutex_lock(&routing_lock);
181
182 payload.num_copps = 0; /* only RX needs to use payload */
183 fe_dai_map[fedai_id][session_type] = dspst_id;
Ben Romberger037dd2f2011-09-22 14:01:32 -0700184 /* re-enable EQ if active */
185 if (eq_data[fedai_id].enable)
186 msm_send_eq_values(fedai_id);
Patrick Laicf999112011-08-23 11:27:20 -0700187 for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) {
188 if ((afe_get_port_type(msm_bedais[i].port_id) ==
189 port_type) && msm_bedais[i].active &&
190 (test_bit(fedai_id,
191 &msm_bedais[i].fe_sessions))) {
192 adm_open(msm_bedais[i].port_id,
193 path_type,
194 params_rate(msm_bedais[i].hw_params),
195 params_channels(msm_bedais[i].hw_params),
196 DEFAULT_COPP_TOPOLOGY);
197 payload.copp_ids[payload.num_copps++] =
198 msm_bedais[i].port_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700199 }
200 }
Patrick Laicf999112011-08-23 11:27:20 -0700201 if (payload.num_copps)
202 adm_matrix_map(dspst_id, path_type,
203 payload.num_copps, payload.copp_ids, 0);
204
205 mutex_unlock(&routing_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700206}
207
208void msm_pcm_routing_dereg_phy_stream(int fedai_id, int stream_type)
209{
Patrick Laicf999112011-08-23 11:27:20 -0700210 int i, port_type, session_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700211
Patrick Lai770ca3e42011-12-12 13:44:54 -0800212 if (fedai_id > MSM_FRONTEND_DAI_MM_MAX_ID) {
213 /* bad ID assigned in machine driver */
214 pr_err("%s: bad MM ID\n", __func__);
215 return;
216 }
217
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700218 if (stream_type == SNDRV_PCM_STREAM_PLAYBACK) {
Patrick Laicf999112011-08-23 11:27:20 -0700219 port_type = MSM_AFE_PORT_TYPE_RX;
220 session_type = SESSION_TYPE_RX;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700221 } else {
Patrick Laicf999112011-08-23 11:27:20 -0700222 port_type = MSM_AFE_PORT_TYPE_TX;
223 session_type = SESSION_TYPE_TX;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700224 }
Patrick Laicf999112011-08-23 11:27:20 -0700225
226 mutex_lock(&routing_lock);
227
228 for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) {
229 if ((afe_get_port_type(msm_bedais[i].port_id) ==
230 port_type) && msm_bedais[i].active &&
231 (test_bit(fedai_id,
232 &msm_bedais[i].fe_sessions)))
233 adm_close(msm_bedais[i].port_id);
234 }
235
236 fe_dai_map[fedai_id][session_type] = INVALID_SESSION;
237
238 mutex_unlock(&routing_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700239}
240
241static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set)
242{
Patrick Laicf999112011-08-23 11:27:20 -0700243 int session_type, path_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700244
245 pr_debug("%s: reg %x val %x set %x\n", __func__, reg, val, set);
246
Patrick Lai770ca3e42011-12-12 13:44:54 -0800247 if (val > MSM_FRONTEND_DAI_MM_MAX_ID) {
248 /* recheck FE ID in the mixer control defined in this file */
249 pr_err("%s: bad MM ID\n", __func__);
250 return;
251 }
252
Patrick Laicf999112011-08-23 11:27:20 -0700253 if (afe_get_port_type(msm_bedais[reg].port_id) ==
254 MSM_AFE_PORT_TYPE_RX) {
255 session_type = SESSION_TYPE_RX;
256 path_type = ADM_PATH_PLAYBACK;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700257 } else {
Patrick Laicf999112011-08-23 11:27:20 -0700258 session_type = SESSION_TYPE_TX;
259 path_type = ADM_PATH_LIVE_REC;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700260 }
Patrick Laicf999112011-08-23 11:27:20 -0700261
262 mutex_lock(&routing_lock);
263
264 if (set) {
Helen Zeng0705a5f2011-10-14 15:29:52 -0700265 if (!test_bit(val, &msm_bedais[reg].fe_sessions) &&
266 (msm_bedais[reg].port_id == VOICE_PLAYBACK_TX))
267 voc_start_playback(set);
268
Patrick Laicf999112011-08-23 11:27:20 -0700269 set_bit(val, &msm_bedais[reg].fe_sessions);
270 if (msm_bedais[reg].active && fe_dai_map[val][session_type] !=
271 INVALID_SESSION) {
272 adm_open(msm_bedais[reg].port_id, path_type,
273 params_rate(msm_bedais[reg].hw_params),
274 params_channels(msm_bedais[reg].hw_params),
275 DEFAULT_COPP_TOPOLOGY);
276 msm_pcm_routing_build_matrix(val,
277 fe_dai_map[val][session_type], path_type);
278 }
279 } else {
Helen Zeng0705a5f2011-10-14 15:29:52 -0700280 if (test_bit(val, &msm_bedais[reg].fe_sessions) &&
281 (msm_bedais[reg].port_id == VOICE_PLAYBACK_TX))
282 voc_start_playback(set);
Patrick Laicf999112011-08-23 11:27:20 -0700283 clear_bit(val, &msm_bedais[reg].fe_sessions);
284 if (msm_bedais[reg].active && fe_dai_map[val][session_type] !=
285 INVALID_SESSION) {
286 adm_close(msm_bedais[reg].port_id);
287 msm_pcm_routing_build_matrix(val,
288 fe_dai_map[val][session_type], path_type);
289 }
290 }
Helen Zenge3d716a2011-10-14 16:32:16 -0700291 if ((msm_bedais[reg].port_id == VOICE_RECORD_RX)
292 || (msm_bedais[reg].port_id == VOICE_RECORD_TX))
293 voc_start_record(msm_bedais[reg].port_id, set);
Patrick Laicf999112011-08-23 11:27:20 -0700294
295 mutex_unlock(&routing_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700296}
297
298static int msm_routing_get_audio_mixer(struct snd_kcontrol *kcontrol,
299 struct snd_ctl_elem_value *ucontrol)
300{
301 struct soc_mixer_control *mc =
302 (struct soc_mixer_control *)kcontrol->private_value;
303
Patrick Laicf999112011-08-23 11:27:20 -0700304 if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700305 ucontrol->value.integer.value[0] = 1;
306 else
307 ucontrol->value.integer.value[0] = 0;
308
309 pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift,
310 ucontrol->value.integer.value[0]);
311
312 return 0;
313}
314
315static int msm_routing_put_audio_mixer(struct snd_kcontrol *kcontrol,
316 struct snd_ctl_elem_value *ucontrol)
317{
Patrick Laiec2b8942011-09-01 11:01:51 -0700318 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
319 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700320 struct soc_mixer_control *mc =
321 (struct soc_mixer_control *)kcontrol->private_value;
322
323
324 if (ucontrol->value.integer.value[0]) {
325 msm_pcm_routing_process_audio(mc->reg, mc->shift, 1);
326 snd_soc_dapm_mixer_update_power(widget, kcontrol, 1);
327 } else {
328 msm_pcm_routing_process_audio(mc->reg, mc->shift, 0);
329 snd_soc_dapm_mixer_update_power(widget, kcontrol, 0);
330 }
331
332 return 1;
333}
334
Neema Shettyfeea7742011-09-11 12:30:36 -0700335static void msm_pcm_routing_process_voice(u16 reg, u16 val, int set)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700336{
Neema Shetty2c07eb52011-08-21 20:33:52 -0700337 u16 session_id = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700338
Neema Shettyfeea7742011-09-11 12:30:36 -0700339 pr_debug("%s: reg %x val %x set %x\n", __func__, reg, val, set);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700340
Neema Shettyfeea7742011-09-11 12:30:36 -0700341 if (val == MSM_FRONTEND_DAI_CS_VOICE)
Neema Shetty2c07eb52011-08-21 20:33:52 -0700342 session_id = voc_get_session_id(VOICE_SESSION_NAME);
343 else
344 session_id = voc_get_session_id(VOIP_SESSION_NAME);
345
346 pr_debug("%s: FE DAI 0x%x session_id 0x%x\n",
Neema Shettyfeea7742011-09-11 12:30:36 -0700347 __func__, val, session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700348
Neema Shettyfeea7742011-09-11 12:30:36 -0700349 mutex_lock(&routing_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700350
351 if (set)
Neema Shettyfeea7742011-09-11 12:30:36 -0700352 set_bit(val, &msm_bedais[reg].fe_sessions);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700353 else
Neema Shettyfeea7742011-09-11 12:30:36 -0700354 clear_bit(val, &msm_bedais[reg].fe_sessions);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700355
Neema Shettyfeea7742011-09-11 12:30:36 -0700356 mutex_unlock(&routing_lock);
357
358 if (afe_get_port_type(msm_bedais[reg].port_id) ==
359 MSM_AFE_PORT_TYPE_RX) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700360 voc_set_route_flag(session_id, RX_PATH, set);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700361 if (set) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700362 voc_set_rxtx_port(session_id,
Neema Shettyfeea7742011-09-11 12:30:36 -0700363 msm_bedais[reg].port_id, DEV_RX);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700364
Neema Shetty2c07eb52011-08-21 20:33:52 -0700365 if (voc_get_route_flag(session_id, RX_PATH) &&
366 voc_get_route_flag(session_id, TX_PATH))
367 voc_enable_cvp(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700368 } else {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700369 voc_disable_cvp(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700370 }
371 } else {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700372 voc_set_route_flag(session_id, TX_PATH, set);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700373 if (set) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700374 voc_set_rxtx_port(session_id,
Neema Shettyfeea7742011-09-11 12:30:36 -0700375 msm_bedais[reg].port_id, DEV_TX);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700376 if (voc_get_route_flag(session_id, RX_PATH) &&
377 voc_get_route_flag(session_id, TX_PATH))
378 voc_enable_cvp(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700379 } else {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700380 voc_disable_cvp(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700381 }
382 }
383}
384
385static int msm_routing_get_voice_mixer(struct snd_kcontrol *kcontrol,
386 struct snd_ctl_elem_value *ucontrol)
387{
388 struct soc_mixer_control *mc =
389 (struct soc_mixer_control *)kcontrol->private_value;
390
Neema Shettyfeea7742011-09-11 12:30:36 -0700391 mutex_lock(&routing_lock);
392
393 if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700394 ucontrol->value.integer.value[0] = 1;
395 else
396 ucontrol->value.integer.value[0] = 0;
397
Neema Shettyfeea7742011-09-11 12:30:36 -0700398 mutex_unlock(&routing_lock);
399
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700400 pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift,
401 ucontrol->value.integer.value[0]);
402
403 return 0;
404}
405
406static int msm_routing_put_voice_mixer(struct snd_kcontrol *kcontrol,
407 struct snd_ctl_elem_value *ucontrol)
408{
Patrick Laiec2b8942011-09-01 11:01:51 -0700409 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
410 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700411 struct soc_mixer_control *mc =
412 (struct soc_mixer_control *)kcontrol->private_value;
413
414 if (ucontrol->value.integer.value[0]) {
Neema Shettyfeea7742011-09-11 12:30:36 -0700415 msm_pcm_routing_process_voice(mc->reg, mc->shift, 1);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700416 snd_soc_dapm_mixer_update_power(widget, kcontrol, 1);
417 } else {
Neema Shettyfeea7742011-09-11 12:30:36 -0700418 msm_pcm_routing_process_voice(mc->reg, mc->shift, 0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700419 snd_soc_dapm_mixer_update_power(widget, kcontrol, 0);
420 }
421
422 return 1;
423}
424
Sriranjan Srikantama4969dd2011-07-14 00:34:56 -0700425static int msm_routing_get_switch_mixer(struct snd_kcontrol *kcontrol,
426 struct snd_ctl_elem_value *ucontrol)
427{
428 ucontrol->value.integer.value[0] = fm_switch_enable;
429 pr_debug("%s: FM Switch enable %ld\n", __func__,
430 ucontrol->value.integer.value[0]);
431 return 0;
432}
433
434static int msm_routing_put_switch_mixer(struct snd_kcontrol *kcontrol,
435 struct snd_ctl_elem_value *ucontrol)
436{
Sriranjan Srikantamdf509d12011-10-24 17:53:27 -0700437 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
438 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
Sriranjan Srikantama4969dd2011-07-14 00:34:56 -0700439
440 pr_debug("%s: FM Switch enable %ld\n", __func__,
441 ucontrol->value.integer.value[0]);
442 if (ucontrol->value.integer.value[0])
443 snd_soc_dapm_mixer_update_power(widget, kcontrol, 1);
444 else
445 snd_soc_dapm_mixer_update_power(widget, kcontrol, 0);
446 fm_switch_enable = ucontrol->value.integer.value[0];
447 return 1;
448}
449
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700450static int msm_routing_get_port_mixer(struct snd_kcontrol *kcontrol,
451 struct snd_ctl_elem_value *ucontrol)
452{
453 struct soc_mixer_control *mc =
454 (struct soc_mixer_control *)kcontrol->private_value;
455
Patrick Laicf999112011-08-23 11:27:20 -0700456 if (test_bit(mc->shift, &msm_bedais[mc->reg].port_sessions))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700457 ucontrol->value.integer.value[0] = 1;
458 else
459 ucontrol->value.integer.value[0] = 0;
460
461 pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift,
462 ucontrol->value.integer.value[0]);
463
464 return 0;
465}
466
467static int msm_routing_put_port_mixer(struct snd_kcontrol *kcontrol,
468 struct snd_ctl_elem_value *ucontrol)
469{
470 struct soc_mixer_control *mc =
471 (struct soc_mixer_control *)kcontrol->private_value;
472
473 pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg,
474 mc->shift, ucontrol->value.integer.value[0]);
475
476 if (ucontrol->value.integer.value[0]) {
Patrick Laicf999112011-08-23 11:27:20 -0700477 afe_loopback(1, msm_bedais[mc->reg].port_id,
478 msm_bedais[mc->shift].port_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700479 set_bit(mc->shift,
Patrick Laicf999112011-08-23 11:27:20 -0700480 &msm_bedais[mc->reg].port_sessions);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700481 } else {
Patrick Laicf999112011-08-23 11:27:20 -0700482 afe_loopback(0, msm_bedais[mc->reg].port_id,
483 msm_bedais[mc->shift].port_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700484 clear_bit(mc->shift,
Patrick Laicf999112011-08-23 11:27:20 -0700485 &msm_bedais[mc->reg].port_sessions);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700486 }
487
488 return 1;
489}
490
Jayasena Sangaraboinacb1e22f2011-07-18 10:36:57 -0700491static int msm_routing_get_fm_vol_mixer(struct snd_kcontrol *kcontrol,
492 struct snd_ctl_elem_value *ucontrol)
493{
494 ucontrol->value.integer.value[0] = msm_route_fm_vol_control;
495 return 0;
496}
497
498static int msm_routing_set_fm_vol_mixer(struct snd_kcontrol *kcontrol,
499 struct snd_ctl_elem_value *ucontrol)
500{
501 afe_loopback_gain(INT_FM_TX , ucontrol->value.integer.value[0]);
502
503 msm_route_fm_vol_control = ucontrol->value.integer.value[0];
504
505 return 0;
506}
507
Asish Bhattacharya0ec76182011-07-29 16:58:11 +0530508static int msm_routing_get_lpa_vol_mixer(struct snd_kcontrol *kcontrol,
509 struct snd_ctl_elem_value *ucontrol)
510{
511 ucontrol->value.integer.value[0] = msm_route_lpa_vol_control;
512 return 0;
513}
514
515static int msm_routing_set_lpa_vol_mixer(struct snd_kcontrol *kcontrol,
516 struct snd_ctl_elem_value *ucontrol)
517{
518 if (!lpa_set_volume(ucontrol->value.integer.value[0]))
519 msm_route_lpa_vol_control =
520 ucontrol->value.integer.value[0];
521
522 return 0;
523}
524
Ben Romberger037dd2f2011-09-22 14:01:32 -0700525static void msm_send_eq_values(int eq_idx)
526{
527 int result;
528 struct audio_client *ac =
529 q6asm_get_audio_client(fe_dai_map[eq_idx][SESSION_TYPE_RX]);
530
531 if (ac == NULL) {
532 pr_err("%s: Could not get audio client for session: %d\n",
533 __func__, fe_dai_map[eq_idx][SESSION_TYPE_RX]);
534 goto done;
535 }
536
537 result = q6asm_equalizer(ac, &eq_data[eq_idx]);
538
539 if (result < 0)
540 pr_err("%s: Call to ASM equalizer failed, returned = %d\n",
541 __func__, result);
542done:
543 return;
544}
545
546static int msm_routing_get_eq_enable_mixer(struct snd_kcontrol *kcontrol,
547 struct snd_ctl_elem_value *ucontrol)
548{
549 int eq_idx = ((struct soc_multi_mixer_control *)
550 kcontrol->private_value)->reg;
551
Ben Romberger76f57032011-12-08 20:07:34 -0800552 ucontrol->value.integer.value[0] = eq_data[eq_idx].enable;
553
Ben Romberger037dd2f2011-09-22 14:01:32 -0700554 pr_debug("%s: EQ #%d enable %d\n", __func__,
555 eq_idx, eq_data[eq_idx].enable);
Ben Romberger76f57032011-12-08 20:07:34 -0800556 return 0;
Ben Romberger037dd2f2011-09-22 14:01:32 -0700557}
558
559static int msm_routing_put_eq_enable_mixer(struct snd_kcontrol *kcontrol,
560 struct snd_ctl_elem_value *ucontrol)
561{
562 int eq_idx = ((struct soc_multi_mixer_control *)
563 kcontrol->private_value)->reg;
564 int value = ucontrol->value.integer.value[0];
565
566 pr_debug("%s: EQ #%d enable %d\n", __func__,
567 eq_idx, value);
568 eq_data[eq_idx].enable = value;
569
570 msm_send_eq_values(eq_idx);
571 return 0;
572}
573
574static int msm_routing_get_eq_band_count_audio_mixer(
575 struct snd_kcontrol *kcontrol,
576 struct snd_ctl_elem_value *ucontrol)
577{
578 int eq_idx = ((struct soc_multi_mixer_control *)
579 kcontrol->private_value)->reg;
580
Ben Romberger76f57032011-12-08 20:07:34 -0800581 ucontrol->value.integer.value[0] = eq_data[eq_idx].num_bands;
582
Ben Romberger037dd2f2011-09-22 14:01:32 -0700583 pr_debug("%s: EQ #%d bands %d\n", __func__,
584 eq_idx, eq_data[eq_idx].num_bands);
585 return eq_data[eq_idx].num_bands;
586}
587
588static int msm_routing_put_eq_band_count_audio_mixer(
589 struct snd_kcontrol *kcontrol,
590 struct snd_ctl_elem_value *ucontrol)
591{
592 int eq_idx = ((struct soc_multi_mixer_control *)
593 kcontrol->private_value)->reg;
594 int value = ucontrol->value.integer.value[0];
595
Ben Romberger037dd2f2011-09-22 14:01:32 -0700596 pr_debug("%s: EQ #%d bands %d\n", __func__,
597 eq_idx, value);
598 eq_data[eq_idx].num_bands = value;
599 return 0;
600}
601
602static int msm_routing_get_eq_band_audio_mixer(struct snd_kcontrol *kcontrol,
603 struct snd_ctl_elem_value *ucontrol)
604{
605 int eq_idx = ((struct soc_multi_mixer_control *)
606 kcontrol->private_value)->reg;
607 int band_idx = ((struct soc_multi_mixer_control *)
608 kcontrol->private_value)->shift;
609
Ben Romberger76f57032011-12-08 20:07:34 -0800610 ucontrol->value.integer.value[0] =
611 eq_data[eq_idx].eq_bands[band_idx].band_idx;
612 ucontrol->value.integer.value[1] =
613 eq_data[eq_idx].eq_bands[band_idx].filter_type;
614 ucontrol->value.integer.value[2] =
615 eq_data[eq_idx].eq_bands[band_idx].center_freq_hz;
616 ucontrol->value.integer.value[3] =
617 eq_data[eq_idx].eq_bands[band_idx].filter_gain;
618 ucontrol->value.integer.value[4] =
619 eq_data[eq_idx].eq_bands[band_idx].q_factor;
620
Ben Romberger037dd2f2011-09-22 14:01:32 -0700621 pr_debug("%s: band_idx = %d\n", __func__,
622 eq_data[eq_idx].eq_bands[band_idx].band_idx);
623 pr_debug("%s: filter_type = %d\n", __func__,
624 eq_data[eq_idx].eq_bands[band_idx].filter_type);
625 pr_debug("%s: center_freq_hz = %d\n", __func__,
626 eq_data[eq_idx].eq_bands[band_idx].center_freq_hz);
627 pr_debug("%s: filter_gain = %d\n", __func__,
628 eq_data[eq_idx].eq_bands[band_idx].filter_gain);
629 pr_debug("%s: q_factor = %d\n", __func__,
630 eq_data[eq_idx].eq_bands[band_idx].q_factor);
631 return 0;
632}
633
634static int msm_routing_put_eq_band_audio_mixer(struct snd_kcontrol *kcontrol,
635 struct snd_ctl_elem_value *ucontrol)
636{
637 int eq_idx = ((struct soc_multi_mixer_control *)
638 kcontrol->private_value)->reg;
639 int band_idx = ((struct soc_multi_mixer_control *)
640 kcontrol->private_value)->shift;
641
642 eq_data[eq_idx].eq_bands[band_idx].band_idx =
643 ucontrol->value.integer.value[0];
644 eq_data[eq_idx].eq_bands[band_idx].filter_type =
645 ucontrol->value.integer.value[1];
646 eq_data[eq_idx].eq_bands[band_idx].center_freq_hz =
647 ucontrol->value.integer.value[2];
648 eq_data[eq_idx].eq_bands[band_idx].filter_gain =
649 ucontrol->value.integer.value[3];
650 eq_data[eq_idx].eq_bands[band_idx].q_factor =
651 ucontrol->value.integer.value[4];
652 return 0;
653}
654
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700655static const struct snd_kcontrol_new pri_i2s_rx_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700656 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_PRI_I2S_RX ,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700657 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
658 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700659 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_PRI_I2S_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700660 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
661 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700662 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_PRI_I2S_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700663 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
664 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530665 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_PRI_I2S_RX,
666 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
667 msm_routing_put_audio_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700668};
669
670static const struct snd_kcontrol_new slimbus_rx_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700671 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SLIMBUS_0_RX ,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700672 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
673 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700674 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SLIMBUS_0_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700675 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
676 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700677 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SLIMBUS_0_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700678 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
679 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530680 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SLIMBUS_0_RX,
681 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
682 msm_routing_put_audio_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700683};
684
685static const struct snd_kcontrol_new hdmi_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700686 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_HDMI_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700687 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
688 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700689 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_HDMI_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700690 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
691 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700692 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_HDMI_RX,
Asish Bhattacharyac592eed2011-09-16 17:43:02 +0530693 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
694 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530695 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_HDMI_RX,
696 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
697 msm_routing_put_audio_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700698};
Helen Zeng0705a5f2011-10-14 15:29:52 -0700699 /* incall music delivery mixer */
700static const struct snd_kcontrol_new incall_music_delivery_mixer_controls[] = {
701 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_VOICE_PLAYBACK_TX,
702 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
703 msm_routing_put_audio_mixer),
704 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_VOICE_PLAYBACK_TX,
705 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
706 msm_routing_put_audio_mixer),
707};
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700708
709static const struct snd_kcontrol_new int_bt_sco_rx_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700710 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_INT_BT_SCO_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700711 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
712 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700713 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_INT_BT_SCO_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700714 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
715 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700716 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_INT_BT_SCO_RX,
Asish Bhattacharyac592eed2011-09-16 17:43:02 +0530717 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
718 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530719 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_INT_BT_SCO_RX,
720 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
721 msm_routing_put_audio_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700722};
723
724static const struct snd_kcontrol_new int_fm_rx_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700725 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_INT_FM_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700726 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
727 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700728 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_INT_FM_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700729 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
730 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700731 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_INT_FM_RX,
Asish Bhattacharyac592eed2011-09-16 17:43:02 +0530732 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
733 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530734 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_INT_FM_RX,
735 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
736 msm_routing_put_audio_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700737};
738
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530739static const struct snd_kcontrol_new afe_pcm_rx_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700740 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_AFE_PCM_RX,
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530741 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
742 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700743 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_AFE_PCM_RX,
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530744 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
745 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700746 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_AFE_PCM_RX,
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530747 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
748 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530749 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_AFE_PCM_RX,
750 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
751 msm_routing_put_audio_mixer),
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530752};
753
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700754static const struct snd_kcontrol_new auxpcm_rx_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700755 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_AUXPCM_RX,
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700756 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
757 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700758 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_AUXPCM_RX,
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700759 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
760 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700761 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_AUXPCM_RX,
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700762 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
763 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530764 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_AUXPCM_RX,
765 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
766 msm_routing_put_audio_mixer),
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700767};
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530768
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700769static const struct snd_kcontrol_new mmul1_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700770 SOC_SINGLE_EXT("PRI_TX", MSM_BACKEND_DAI_PRI_I2S_TX,
771 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
772 msm_routing_put_audio_mixer),
773 SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX,
774 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
775 msm_routing_put_audio_mixer),
776 SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_AUXPCM_TX,
777 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
778 msm_routing_put_audio_mixer),
779 SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX,
780 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
781 msm_routing_put_audio_mixer),
782 SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX,
783 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
784 msm_routing_put_audio_mixer),
785 SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX,
786 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
787 msm_routing_put_audio_mixer),
Helen Zenge3d716a2011-10-14 16:32:16 -0700788 SOC_SINGLE_EXT("VOC_REC_DL", MSM_BACKEND_DAI_INCALL_RECORD_RX,
789 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
790 msm_routing_put_audio_mixer),
791 SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX,
792 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
793 msm_routing_put_audio_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700794};
795
Jayasena Sangaraboina99fee652011-09-19 07:43:13 -0700796static const struct snd_kcontrol_new mmul2_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700797 SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX,
798 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
Jayasena Sangaraboina99fee652011-09-19 07:43:13 -0700799 msm_routing_put_audio_mixer),
800};
801
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700802static const struct snd_kcontrol_new pri_rx_voice_mixer_controls[] = {
Neema Shettyfeea7742011-09-11 12:30:36 -0700803 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_PRI_I2S_RX,
804 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
805 msm_routing_put_voice_mixer),
806 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_PRI_I2S_RX,
807 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
808 msm_routing_put_voice_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700809};
810
811static const struct snd_kcontrol_new slimbus_rx_voice_mixer_controls[] = {
Neema Shettyfeea7742011-09-11 12:30:36 -0700812 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_SLIMBUS_0_RX,
813 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
814 msm_routing_put_voice_mixer),
815 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SLIMBUS_0_RX ,
816 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
817 msm_routing_put_voice_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700818};
819
820static const struct snd_kcontrol_new bt_sco_rx_voice_mixer_controls[] = {
Neema Shettyfeea7742011-09-11 12:30:36 -0700821 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_INT_BT_SCO_RX,
822 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
823 msm_routing_put_voice_mixer),
824 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_INT_BT_SCO_RX ,
825 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
826 msm_routing_put_voice_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700827};
828
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530829static const struct snd_kcontrol_new afe_pcm_rx_voice_mixer_controls[] = {
830 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_AFE_PCM_RX,
831 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
832 msm_routing_put_voice_mixer),
833 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_AFE_PCM_RX,
834 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
835 msm_routing_put_voice_mixer),
836};
837
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700838static const struct snd_kcontrol_new aux_pcm_rx_voice_mixer_controls[] = {
839 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_AUXPCM_RX,
840 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
841 msm_routing_put_voice_mixer),
842 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_AUXPCM_RX,
843 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
844 msm_routing_put_voice_mixer),
845};
846
Alex Wong593576c2011-11-15 08:03:24 -0800847static const struct snd_kcontrol_new hdmi_rx_voice_mixer_controls[] = {
848 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_HDMI_RX,
849 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
850 msm_routing_put_voice_mixer),
851 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_HDMI_RX,
852 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
853 msm_routing_put_voice_mixer),
854};
855
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700856static const struct snd_kcontrol_new tx_voice_mixer_controls[] = {
Neema Shettyfeea7742011-09-11 12:30:36 -0700857 SOC_SINGLE_EXT("PRI_TX_Voice", MSM_BACKEND_DAI_PRI_I2S_TX,
858 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
859 msm_routing_put_voice_mixer),
860 SOC_SINGLE_EXT("SLIM_0_TX_Voice", MSM_BACKEND_DAI_SLIMBUS_0_TX,
861 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
862 msm_routing_put_voice_mixer),
863 SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_Voice",
864 MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_CS_VOICE, 1, 0,
Neema Shetty2c07eb52011-08-21 20:33:52 -0700865 msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530866 SOC_SINGLE_EXT("AFE_PCM_TX_Voice", MSM_BACKEND_DAI_AFE_PCM_TX,
867 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
868 msm_routing_put_voice_mixer),
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700869 SOC_SINGLE_EXT("AUX_PCM_TX_Voice", MSM_BACKEND_DAI_AUXPCM_TX,
870 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
871 msm_routing_put_voice_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700872};
873
874static const struct snd_kcontrol_new tx_voip_mixer_controls[] = {
Neema Shettyfeea7742011-09-11 12:30:36 -0700875 SOC_SINGLE_EXT("PRI_TX_Voip", MSM_BACKEND_DAI_PRI_I2S_TX,
876 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
877 msm_routing_put_voice_mixer),
878 SOC_SINGLE_EXT("SLIM_0_TX_Voip", MSM_BACKEND_DAI_SLIMBUS_0_TX,
879 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
880 msm_routing_put_voice_mixer),
881 SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_Voip", MSM_BACKEND_DAI_INT_BT_SCO_TX,
882 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
883 msm_routing_put_voice_mixer),
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530884 SOC_SINGLE_EXT("AFE_PCM_TX_Voip", MSM_BACKEND_DAI_AFE_PCM_TX,
885 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
886 msm_routing_put_voice_mixer),
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700887 SOC_SINGLE_EXT("AUX_PCM_TX_Voip", MSM_BACKEND_DAI_AUXPCM_TX,
888 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
889 msm_routing_put_voice_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700890};
891
892static const struct snd_kcontrol_new sbus_0_rx_port_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700893 SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700894 MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer,
895 msm_routing_put_port_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700896 SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700897 MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer,
898 msm_routing_put_port_mixer),
899};
900
Sriranjan Srikantama4969dd2011-07-14 00:34:56 -0700901static const struct snd_kcontrol_new fm_switch_mixer_controls =
902 SOC_SINGLE_EXT("Switch", SND_SOC_NOPM,
903 0, 1, 0, msm_routing_get_switch_mixer,
904 msm_routing_put_switch_mixer);
905
Jayasena Sangaraboinacb1e22f2011-07-18 10:36:57 -0700906static const struct snd_kcontrol_new int_fm_vol_mixer_controls[] = {
907 SOC_SINGLE_EXT_TLV("Internal FM RX Volume", SND_SOC_NOPM, 0,
908 INT_FM_RX_VOL_GAIN, 0, msm_routing_get_fm_vol_mixer,
909 msm_routing_set_fm_vol_mixer, fm_rx_vol_gain),
910};
911
Asish Bhattacharya0ec76182011-07-29 16:58:11 +0530912static const struct snd_kcontrol_new lpa_vol_mixer_controls[] = {
913 SOC_SINGLE_EXT_TLV("LPA RX Volume", SND_SOC_NOPM, 0,
914 INT_LPA_RX_VOL_GAIN, 0, msm_routing_get_lpa_vol_mixer,
915 msm_routing_set_lpa_vol_mixer, lpa_rx_vol_gain),
916};
917
Ben Romberger037dd2f2011-09-22 14:01:32 -0700918static const struct snd_kcontrol_new eq_enable_mixer_controls[] = {
919 SOC_SINGLE_EXT("MultiMedia1 EQ Enable", SND_SOC_NOPM,
920 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_eq_enable_mixer,
921 msm_routing_put_eq_enable_mixer),
922 SOC_SINGLE_EXT("MultiMedia2 EQ Enable", SND_SOC_NOPM,
923 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_eq_enable_mixer,
924 msm_routing_put_eq_enable_mixer),
925 SOC_SINGLE_EXT("MultiMedia3 EQ Enable", SND_SOC_NOPM,
926 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_eq_enable_mixer,
927 msm_routing_put_eq_enable_mixer),
928};
929
930static const struct snd_kcontrol_new eq_band_mixer_controls[] = {
931 SOC_SINGLE_EXT("MultiMedia1 EQ Band Count", SND_SOC_NOPM,
932 MSM_FRONTEND_DAI_MULTIMEDIA1, 11, 0,
933 msm_routing_get_eq_band_count_audio_mixer,
934 msm_routing_put_eq_band_count_audio_mixer),
935 SOC_SINGLE_EXT("MultiMedia2 EQ Band Count", SND_SOC_NOPM,
936 MSM_FRONTEND_DAI_MULTIMEDIA2, 11, 0,
937 msm_routing_get_eq_band_count_audio_mixer,
938 msm_routing_put_eq_band_count_audio_mixer),
939 SOC_SINGLE_EXT("MultiMedia3 EQ Band Count", SND_SOC_NOPM,
940 MSM_FRONTEND_DAI_MULTIMEDIA3, 11, 0,
941 msm_routing_get_eq_band_count_audio_mixer,
942 msm_routing_put_eq_band_count_audio_mixer),
943};
944
945static const struct snd_kcontrol_new eq_coeff_mixer_controls[] = {
946 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band1", EQ_BAND1,
947 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
948 msm_routing_get_eq_band_audio_mixer,
949 msm_routing_put_eq_band_audio_mixer),
950 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band2", EQ_BAND2,
951 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
952 msm_routing_get_eq_band_audio_mixer,
953 msm_routing_put_eq_band_audio_mixer),
954 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band3", EQ_BAND3,
955 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
956 msm_routing_get_eq_band_audio_mixer,
957 msm_routing_put_eq_band_audio_mixer),
958 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band4", EQ_BAND4,
959 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
960 msm_routing_get_eq_band_audio_mixer,
961 msm_routing_put_eq_band_audio_mixer),
962 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band5", EQ_BAND5,
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 Band6", EQ_BAND6,
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 Band7", EQ_BAND7,
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 Band8", EQ_BAND8,
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 Band9", EQ_BAND9,
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 Band10", EQ_BAND10,
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 Band11", EQ_BAND11,
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 Band12", EQ_BAND12,
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("MultiMedia2 EQ Band1", EQ_BAND1,
995 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
996 msm_routing_get_eq_band_audio_mixer,
997 msm_routing_put_eq_band_audio_mixer),
998 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band2", EQ_BAND2,
999 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1000 msm_routing_get_eq_band_audio_mixer,
1001 msm_routing_put_eq_band_audio_mixer),
1002 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band3", EQ_BAND3,
1003 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1004 msm_routing_get_eq_band_audio_mixer,
1005 msm_routing_put_eq_band_audio_mixer),
1006 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band4", EQ_BAND4,
1007 MSM_FRONTEND_DAI_MULTIMEDIA2, 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 Band5", EQ_BAND5,
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 Band6", EQ_BAND6,
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 Band7", EQ_BAND7,
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 Band8", EQ_BAND8,
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 Band9", EQ_BAND9,
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 Band10", EQ_BAND10,
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 Band11", EQ_BAND11,
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 Band12", EQ_BAND12,
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("MultiMedia3 EQ Band1", EQ_BAND1,
1043 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1044 msm_routing_get_eq_band_audio_mixer,
1045 msm_routing_put_eq_band_audio_mixer),
1046 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band2", EQ_BAND2,
1047 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1048 msm_routing_get_eq_band_audio_mixer,
1049 msm_routing_put_eq_band_audio_mixer),
1050 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band3", EQ_BAND3,
1051 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1052 msm_routing_get_eq_band_audio_mixer,
1053 msm_routing_put_eq_band_audio_mixer),
1054 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band4", EQ_BAND4,
1055 MSM_FRONTEND_DAI_MULTIMEDIA3, 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 Band5", EQ_BAND5,
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 Band6", EQ_BAND6,
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 Band7", EQ_BAND7,
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 Band8", EQ_BAND8,
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 Band9", EQ_BAND9,
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 Band10", EQ_BAND10,
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 Band11", EQ_BAND11,
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 Band12", EQ_BAND12,
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};
1091
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001092static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
1093 /* Frontend AIF */
1094 /* Widget name equals to Front-End DAI name<Need confirmation>,
1095 * Stream name must contains substring of front-end dai name
1096 */
1097 SND_SOC_DAPM_AIF_IN("MM_DL1", "MultiMedia1 Playback", 0, 0, 0, 0),
1098 SND_SOC_DAPM_AIF_IN("MM_DL2", "MultiMedia2 Playback", 0, 0, 0, 0),
1099 SND_SOC_DAPM_AIF_IN("MM_DL3", "MultiMedia3 Playback", 0, 0, 0, 0),
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301100 SND_SOC_DAPM_AIF_IN("MM_DL4", "MultiMedia4 Playback", 0, 0, 0, 0),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001101 SND_SOC_DAPM_AIF_IN("VOIP_DL", "VoIP Playback", 0, 0, 0, 0),
1102 SND_SOC_DAPM_AIF_OUT("MM_UL1", "MultiMedia1 Capture", 0, 0, 0, 0),
Jayasena Sangaraboina99fee652011-09-19 07:43:13 -07001103 SND_SOC_DAPM_AIF_OUT("MM_UL2", "MultiMedia2 Capture", 0, 0, 0, 0),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001104 SND_SOC_DAPM_AIF_IN("CS-VOICE_DL1", "CS-VOICE Playback", 0, 0, 0, 0),
1105 SND_SOC_DAPM_AIF_OUT("CS-VOICE_UL1", "CS-VOICE Capture", 0, 0, 0, 0),
1106 SND_SOC_DAPM_AIF_OUT("VOIP_UL", "VoIP Capture", 0, 0, 0, 0),
1107 SND_SOC_DAPM_AIF_IN("SLIM0_DL_HL", "SLIMBUS0_HOSTLESS Playback",
1108 0, 0, 0, 0),
1109 SND_SOC_DAPM_AIF_OUT("SLIM0_UL_HL", "SLIMBUS0_HOSTLESS Capture",
1110 0, 0, 0, 0),
1111 SND_SOC_DAPM_AIF_IN("INTFM_DL_HL", "INT_FM_HOSTLESS Playback",
1112 0, 0, 0, 0),
1113 SND_SOC_DAPM_AIF_OUT("INTFM_UL_HL", "INT_FM_HOSTLESS Capture",
1114 0, 0, 0, 0),
1115 /* Backend AIF */
1116 /* Stream name equals to backend dai link stream name
1117 */
1118 SND_SOC_DAPM_AIF_OUT("PRI_I2S_RX", "Primary I2S Playback", 0, 0, 0, 0),
1119 SND_SOC_DAPM_AIF_OUT("SLIMBUS_0_RX", "Slimbus Playback", 0, 0, 0, 0),
1120 SND_SOC_DAPM_AIF_OUT("HDMI", "HDMI Playback", 0, 0, 0 , 0),
1121 SND_SOC_DAPM_AIF_IN("PRI_I2S_TX", "Primary I2S Capture", 0, 0, 0, 0),
1122 SND_SOC_DAPM_AIF_IN("SLIMBUS_0_TX", "Slimbus Capture", 0, 0, 0, 0),
1123 SND_SOC_DAPM_AIF_OUT("INT_BT_SCO_RX", "Internal BT-SCO Playback",
1124 0, 0, 0 , 0),
1125 SND_SOC_DAPM_AIF_IN("INT_BT_SCO_TX", "Internal BT-SCO Capture",
1126 0, 0, 0, 0),
1127 SND_SOC_DAPM_AIF_OUT("INT_FM_RX", "Internal FM Playback",
1128 0, 0, 0 , 0),
1129 SND_SOC_DAPM_AIF_IN("INT_FM_TX", "Internal FM Capture",
1130 0, 0, 0, 0),
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301131 SND_SOC_DAPM_AIF_OUT("PCM_RX", "AFE Playback",
1132 0, 0, 0 , 0),
1133 SND_SOC_DAPM_AIF_IN("PCM_TX", "AFE Capture",
Helen Zeng0705a5f2011-10-14 15:29:52 -07001134 0, 0, 0 , 0),
1135 /* incall */
1136 SND_SOC_DAPM_AIF_OUT("VOICE_PLAYBACK_TX", "Voice Farend Playback",
1137 0, 0, 0 , 0),
Helen Zenge3d716a2011-10-14 16:32:16 -07001138 SND_SOC_DAPM_AIF_IN("INCALL_RECORD_TX", "Voice Uplink Capture",
1139 0, 0, 0, 0),
1140 SND_SOC_DAPM_AIF_IN("INCALL_RECORD_RX", "Voice Downlink Capture",
1141 0, 0, 0, 0),
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001142 SND_SOC_DAPM_AIF_OUT("AUX_PCM_RX", "AUX PCM Playback", 0, 0, 0, 0),
1143 SND_SOC_DAPM_AIF_IN("AUX_PCM_TX", "AUX PCM Capture", 0, 0, 0, 0),
Sriranjan Srikantama4969dd2011-07-14 00:34:56 -07001144 /* Switch Definitions */
Sriranjan Srikantamdf509d12011-10-24 17:53:27 -07001145 SND_SOC_DAPM_SWITCH("SLIMBUS_DL_HL", SND_SOC_NOPM, 0, 0,
Sriranjan Srikantama4969dd2011-07-14 00:34:56 -07001146 &fm_switch_mixer_controls),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001147 /* Mixer definitions */
1148 SND_SOC_DAPM_MIXER("PRI_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1149 pri_i2s_rx_mixer_controls, ARRAY_SIZE(pri_i2s_rx_mixer_controls)),
1150 SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1151 slimbus_rx_mixer_controls, ARRAY_SIZE(slimbus_rx_mixer_controls)),
1152 SND_SOC_DAPM_MIXER("HDMI Mixer", SND_SOC_NOPM, 0, 0,
1153 hdmi_mixer_controls, ARRAY_SIZE(hdmi_mixer_controls)),
1154 SND_SOC_DAPM_MIXER("MultiMedia1 Mixer", SND_SOC_NOPM, 0, 0,
1155 mmul1_mixer_controls, ARRAY_SIZE(mmul1_mixer_controls)),
Jayasena Sangaraboina99fee652011-09-19 07:43:13 -07001156 SND_SOC_DAPM_MIXER("MultiMedia2 Mixer", SND_SOC_NOPM, 0, 0,
1157 mmul2_mixer_controls, ARRAY_SIZE(mmul2_mixer_controls)),
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001158 SND_SOC_DAPM_MIXER("AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1159 auxpcm_rx_mixer_controls, ARRAY_SIZE(auxpcm_rx_mixer_controls)),
Helen Zeng0705a5f2011-10-14 15:29:52 -07001160 /* incall */
1161 SND_SOC_DAPM_MIXER("Incall_Music Audio Mixer", SND_SOC_NOPM, 0, 0,
1162 incall_music_delivery_mixer_controls,
1163 ARRAY_SIZE(incall_music_delivery_mixer_controls)),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001164 /* Voice Mixer */
1165 SND_SOC_DAPM_MIXER("PRI_RX_Voice Mixer",
1166 SND_SOC_NOPM, 0, 0, pri_rx_voice_mixer_controls,
1167 ARRAY_SIZE(pri_rx_voice_mixer_controls)),
1168 SND_SOC_DAPM_MIXER("SLIM_0_RX_Voice Mixer",
1169 SND_SOC_NOPM, 0, 0,
1170 slimbus_rx_voice_mixer_controls,
1171 ARRAY_SIZE(slimbus_rx_voice_mixer_controls)),
1172 SND_SOC_DAPM_MIXER("INTERNAL_BT_SCO_RX_Voice Mixer",
1173 SND_SOC_NOPM, 0, 0,
1174 bt_sco_rx_voice_mixer_controls,
1175 ARRAY_SIZE(bt_sco_rx_voice_mixer_controls)),
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301176 SND_SOC_DAPM_MIXER("AFE_PCM_RX_Voice Mixer",
1177 SND_SOC_NOPM, 0, 0,
1178 afe_pcm_rx_voice_mixer_controls,
1179 ARRAY_SIZE(afe_pcm_rx_voice_mixer_controls)),
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001180 SND_SOC_DAPM_MIXER("AUX_PCM_RX_Voice Mixer",
1181 SND_SOC_NOPM, 0, 0,
1182 aux_pcm_rx_voice_mixer_controls,
1183 ARRAY_SIZE(aux_pcm_rx_voice_mixer_controls)),
Alex Wong593576c2011-11-15 08:03:24 -08001184 SND_SOC_DAPM_MIXER("HDMI_RX_Voice Mixer",
1185 SND_SOC_NOPM, 0, 0,
1186 hdmi_rx_voice_mixer_controls,
1187 ARRAY_SIZE(hdmi_rx_voice_mixer_controls)),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001188 SND_SOC_DAPM_MIXER("Voice_Tx Mixer",
1189 SND_SOC_NOPM, 0, 0, tx_voice_mixer_controls,
1190 ARRAY_SIZE(tx_voice_mixer_controls)),
1191 SND_SOC_DAPM_MIXER("Voip_Tx Mixer",
1192 SND_SOC_NOPM, 0, 0, tx_voip_mixer_controls,
1193 ARRAY_SIZE(tx_voip_mixer_controls)),
1194 SND_SOC_DAPM_MIXER("INTERNAL_BT_SCO_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1195 int_bt_sco_rx_mixer_controls, ARRAY_SIZE(int_bt_sco_rx_mixer_controls)),
1196 SND_SOC_DAPM_MIXER("INTERNAL_FM_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1197 int_fm_rx_mixer_controls, ARRAY_SIZE(int_fm_rx_mixer_controls)),
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301198 SND_SOC_DAPM_MIXER("AFE_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1199 afe_pcm_rx_mixer_controls, ARRAY_SIZE(afe_pcm_rx_mixer_controls)),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001200 SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Port Mixer",
1201 SND_SOC_NOPM, 0, 0, sbus_0_rx_port_mixer_controls,
1202 ARRAY_SIZE(sbus_0_rx_port_mixer_controls)),
1203};
1204
1205static const struct snd_soc_dapm_route intercon[] = {
1206 {"PRI_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1207 {"PRI_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
1208 {"PRI_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301209 {"PRI_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001210 {"PRI_I2S_RX", NULL, "PRI_RX Audio Mixer"},
1211
1212 {"SLIMBUS_0_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1213 {"SLIMBUS_0_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
1214 {"SLIMBUS_0_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301215 {"SLIMBUS_0_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001216 {"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Audio Mixer"},
1217
1218 {"HDMI Mixer", "MultiMedia1", "MM_DL1"},
1219 {"HDMI Mixer", "MultiMedia2", "MM_DL2"},
Asish Bhattacharyac592eed2011-09-16 17:43:02 +05301220 {"HDMI Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301221 {"HDMI Mixer", "MultiMedia4", "MM_DL4"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001222 {"HDMI", NULL, "HDMI Mixer"},
1223
Helen Zeng0705a5f2011-10-14 15:29:52 -07001224 /* incall */
1225 {"Incall_Music Audio Mixer", "MultiMedia1", "MM_DL1"},
1226 {"Incall_Music Audio Mixer", "MultiMedia2", "MM_DL2"},
1227 {"VOICE_PLAYBACK_TX", NULL, "Incall_Music Audio Mixer"},
Helen Zenge3d716a2011-10-14 16:32:16 -07001228
1229 {"MultiMedia1 Mixer", "VOC_REC_UL", "INCALL_RECORD_TX"},
1230 {"MultiMedia1 Mixer", "VOC_REC_DL", "INCALL_RECORD_RX"},
1231
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001232 {"MultiMedia1 Mixer", "PRI_TX", "PRI_I2S_TX"},
1233 {"MultiMedia1 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001234 {"MultiMedia1 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001235
1236 {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1237 {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
Asish Bhattacharyac592eed2011-09-16 17:43:02 +05301238 {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301239 {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001240 {"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX Audio Mixer"},
1241
1242 {"INTERNAL_FM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1243 {"INTERNAL_FM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
Asish Bhattacharyac592eed2011-09-16 17:43:02 +05301244 {"INTERNAL_FM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301245 {"INTERNAL_FM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001246 {"INT_FM_RX", NULL, "INTERNAL_FM_RX Audio Mixer"},
1247
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301248 {"AFE_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1249 {"AFE_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
1250 {"AFE_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301251 {"AFE_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301252 {"PCM_RX", NULL, "AFE_PCM_RX Audio Mixer"},
1253
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001254 {"MultiMedia1 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
1255 {"MultiMedia1 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301256
1257 {"MultiMedia1 Mixer", "AFE_PCM_TX", "PCM_TX"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001258 {"MM_UL1", NULL, "MultiMedia1 Mixer"},
Jayasena Sangaraboina99fee652011-09-19 07:43:13 -07001259 {"MultiMedia2 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
1260 {"MM_UL2", NULL, "MultiMedia2 Mixer"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001261
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001262 {"AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1263 {"AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
1264 {"AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301265 {"AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001266 {"AUX_PCM_RX", NULL, "AUX_PCM_RX Audio Mixer"},
1267
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001268 {"PRI_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1269 {"PRI_RX_Voice Mixer", "Voip", "VOIP_DL"},
1270 {"PRI_I2S_RX", NULL, "PRI_RX_Voice Mixer"},
1271
1272 {"SLIM_0_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1273 {"SLIM_0_RX_Voice Mixer", "Voip", "VOIP_DL"},
1274 {"SLIMBUS_0_RX", NULL, "SLIM_0_RX_Voice Mixer"},
1275
1276 {"INTERNAL_BT_SCO_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1277 {"INTERNAL_BT_SCO_RX_Voice Mixer", "Voip", "VOIP_DL"},
1278 {"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX_Voice Mixer"},
1279
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301280 {"AFE_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1281 {"AFE_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"},
1282 {"PCM_RX", NULL, "AFE_PCM_RX_Voice Mixer"},
1283
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001284 {"AUX_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1285 {"AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"},
1286 {"AUX_PCM_RX", NULL, "AUX_PCM_RX_Voice Mixer"},
1287
Alex Wong593576c2011-11-15 08:03:24 -08001288 {"HDMI_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1289 {"HDMI_RX_Voice Mixer", "Voip", "VOIP_DL"},
1290 {"HDMI", NULL, "HDMI_RX_Voice Mixer"},
1291
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001292 {"Voice_Tx Mixer", "PRI_TX_Voice", "PRI_I2S_TX"},
1293 {"Voice_Tx Mixer", "SLIM_0_TX_Voice", "SLIMBUS_0_TX"},
1294 {"Voice_Tx Mixer", "INTERNAL_BT_SCO_TX_Voice", "INT_BT_SCO_TX"},
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301295 {"Voice_Tx Mixer", "AFE_PCM_TX_Voice", "PCM_TX"},
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001296 {"Voice_Tx Mixer", "AUX_PCM_TX_Voice", "AUX_PCM_TX"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001297 {"CS-VOICE_UL1", NULL, "Voice_Tx Mixer"},
1298 {"Voip_Tx Mixer", "PRI_TX_Voip", "PRI_I2S_TX"},
1299 {"Voip_Tx Mixer", "SLIM_0_TX_Voip", "SLIMBUS_0_TX"},
1300 {"Voip_Tx Mixer", "INTERNAL_BT_SCO_TX_Voip", "INT_BT_SCO_TX"},
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301301 {"Voip_Tx Mixer", "AFE_PCM_TX_Voip", "PCM_TX"},
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001302 {"Voip_Tx Mixer", "AUX_PCM_TX_Voip", "AUX_PCM_TX"},
1303
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001304 {"VOIP_UL", NULL, "Voip_Tx Mixer"},
Sriranjan Srikantamdf509d12011-10-24 17:53:27 -07001305 {"SLIMBUS_DL_HL", "Switch", "SLIM0_DL_HL"},
1306 {"SLIMBUS_0_RX", NULL, "SLIMBUS_DL_HL"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001307 {"SLIM0_UL_HL", NULL, "SLIMBUS_0_TX"},
1308 {"INT_FM_RX", NULL, "INTFM_DL_HL"},
1309 {"INTFM_UL_HL", NULL, "INT_FM_TX"},
1310 {"SLIMBUS_0_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
1311 {"SLIMBUS_0_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
1312 {"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Port Mixer"},
1313};
1314
Patrick Laicf999112011-08-23 11:27:20 -07001315static int msm_pcm_routing_hw_params(struct snd_pcm_substream *substream,
1316 struct snd_pcm_hw_params *params)
1317{
1318 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1319 unsigned int be_id = rtd->dai_link->be_id;
1320
Patrick Lai770ca3e42011-12-12 13:44:54 -08001321 if (be_id >= MSM_BACKEND_DAI_MAX) {
1322 pr_err("%s: unexpected be_id %d\n", __func__, be_id);
1323 return -EINVAL;
1324 }
1325
Patrick Laicf999112011-08-23 11:27:20 -07001326 mutex_lock(&routing_lock);
1327 msm_bedais[be_id].hw_params = params;
1328 mutex_unlock(&routing_lock);
1329 return 0;
1330}
1331
1332static int msm_pcm_routing_close(struct snd_pcm_substream *substream)
1333{
1334 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1335 unsigned int be_id = rtd->dai_link->be_id;
1336 int i, session_type;
1337 struct msm_pcm_routing_bdai_data *bedai;
1338
1339 if (be_id >= MSM_BACKEND_DAI_MAX) {
1340 pr_err("%s: unexpected be_id %d\n", __func__, be_id);
1341 return -EINVAL;
1342 }
1343
1344 bedai = &msm_bedais[be_id];
1345
1346 session_type = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
1347 0 : 1);
1348
1349 mutex_lock(&routing_lock);
1350
Patrick Lai770ca3e42011-12-12 13:44:54 -08001351 for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MM_MAX_ID) {
Patrick Laicf999112011-08-23 11:27:20 -07001352 if (fe_dai_map[i][session_type] != INVALID_SESSION)
1353 adm_close(bedai->port_id);
1354 }
1355
1356 bedai->active = 0;
1357 bedai->hw_params = NULL;
1358
1359 mutex_unlock(&routing_lock);
1360
1361 return 0;
1362}
1363
1364static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream)
1365{
1366 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1367 unsigned int be_id = rtd->dai_link->be_id;
1368 int i, path_type, session_type;
1369 struct msm_pcm_routing_bdai_data *bedai;
1370
1371 if (be_id >= MSM_BACKEND_DAI_MAX) {
1372 pr_err("%s: unexpected be_id %d\n", __func__, be_id);
1373 return -EINVAL;
1374 }
1375
1376
1377 bedai = &msm_bedais[be_id];
1378
Jay Wangc8e03a82011-10-31 11:53:23 -07001379 if (bedai->hw_params == NULL) {
1380 pr_err("%s: HW param is not configured", __func__);
1381 return -EINVAL;
1382 }
1383
1384
Patrick Laicf999112011-08-23 11:27:20 -07001385 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1386 path_type = ADM_PATH_PLAYBACK;
1387 session_type = SESSION_TYPE_RX;
1388 } else {
1389 path_type = ADM_PATH_LIVE_REC;
1390 session_type = SESSION_TYPE_TX;
1391 }
1392
1393 mutex_lock(&routing_lock);
1394
1395 if (bedai->active == 1)
1396 goto done; /* Ignore prepare if back-end already active */
1397
1398 /* AFE port is not active at this point. However, still
1399 * go ahead setting active flag under the notion that
1400 * QDSP6 is able to handle ADM starting before AFE port
1401 * is started.
1402 */
1403 bedai->active = 1;
1404
Patrick Lai770ca3e42011-12-12 13:44:54 -08001405 for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MM_MAX_ID) {
Patrick Laicf999112011-08-23 11:27:20 -07001406 if (fe_dai_map[i][session_type] != INVALID_SESSION) {
1407 adm_open(bedai->port_id, path_type,
1408 params_rate(bedai->hw_params),
1409 params_channels(bedai->hw_params),
1410 DEFAULT_COPP_TOPOLOGY);
1411 msm_pcm_routing_build_matrix(i,
1412 fe_dai_map[i][session_type], path_type);
1413 }
1414 }
1415
1416done:
1417 mutex_unlock(&routing_lock);
1418
1419 return 0;
1420}
1421
1422static struct snd_pcm_ops msm_routing_pcm_ops = {
1423 .hw_params = msm_pcm_routing_hw_params,
1424 .close = msm_pcm_routing_close,
1425 .prepare = msm_pcm_routing_prepare,
1426};
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001427
1428static unsigned int msm_routing_read(struct snd_soc_platform *platform,
1429 unsigned int reg)
1430{
1431 dev_dbg(platform->dev, "reg %x\n", reg);
1432 return 0;
1433}
1434
1435/* Not used but frame seems to require it */
1436static int msm_routing_write(struct snd_soc_platform *platform,
1437 unsigned int reg, unsigned int val)
1438{
1439 dev_dbg(platform->dev, "reg %x val %x\n", reg, val);
1440 return 0;
1441}
1442
1443/* Not used but frame seems to require it */
1444static int msm_routing_probe(struct snd_soc_platform *platform)
1445{
1446 snd_soc_dapm_new_controls(&platform->dapm, msm_qdsp6_widgets,
1447 ARRAY_SIZE(msm_qdsp6_widgets));
1448 snd_soc_dapm_add_routes(&platform->dapm, intercon,
1449 ARRAY_SIZE(intercon));
1450
1451 snd_soc_dapm_new_widgets(&platform->dapm);
1452
Jayasena Sangaraboinacb1e22f2011-07-18 10:36:57 -07001453 snd_soc_add_platform_controls(platform,
1454 int_fm_vol_mixer_controls,
1455 ARRAY_SIZE(int_fm_vol_mixer_controls));
Asish Bhattacharya0ec76182011-07-29 16:58:11 +05301456
1457 snd_soc_add_platform_controls(platform,
1458 lpa_vol_mixer_controls,
1459 ARRAY_SIZE(lpa_vol_mixer_controls));
Ben Romberger037dd2f2011-09-22 14:01:32 -07001460
1461 snd_soc_add_platform_controls(platform,
1462 eq_enable_mixer_controls,
1463 ARRAY_SIZE(eq_enable_mixer_controls));
1464
1465 snd_soc_add_platform_controls(platform,
1466 eq_band_mixer_controls,
1467 ARRAY_SIZE(eq_band_mixer_controls));
1468
1469 snd_soc_add_platform_controls(platform,
1470 eq_coeff_mixer_controls,
1471 ARRAY_SIZE(eq_coeff_mixer_controls));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001472 return 0;
1473}
1474
1475static struct snd_soc_platform_driver msm_soc_routing_platform = {
1476 .ops = &msm_routing_pcm_ops,
1477 .probe = msm_routing_probe,
1478 .read = msm_routing_read,
1479 .write = msm_routing_write,
1480};
1481
1482static __devinit int msm_routing_pcm_probe(struct platform_device *pdev)
1483{
1484 dev_dbg(&pdev->dev, "dev name %s\n", dev_name(&pdev->dev));
1485 return snd_soc_register_platform(&pdev->dev,
1486 &msm_soc_routing_platform);
1487}
1488
1489static int msm_routing_pcm_remove(struct platform_device *pdev)
1490{
1491 snd_soc_unregister_platform(&pdev->dev);
1492 return 0;
1493}
1494
1495static struct platform_driver msm_routing_pcm_driver = {
1496 .driver = {
1497 .name = "msm-pcm-routing",
1498 .owner = THIS_MODULE,
1499 },
1500 .probe = msm_routing_pcm_probe,
1501 .remove = __devexit_p(msm_routing_pcm_remove),
1502};
1503
1504static int __init msm_soc_routing_platform_init(void)
1505{
Neema Shettyfeea7742011-09-11 12:30:36 -07001506 mutex_init(&routing_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001507 return platform_driver_register(&msm_routing_pcm_driver);
1508}
1509module_init(msm_soc_routing_platform_init);
1510
1511static void __exit msm_soc_routing_platform_exit(void)
1512{
1513 platform_driver_unregister(&msm_routing_pcm_driver);
1514}
1515module_exit(msm_soc_routing_platform_exit);
1516
1517MODULE_DESCRIPTION("MSM routing platform driver");
1518MODULE_LICENSE("GPL v2");