blob: 9a076d6a39044daac1a2a0a5fba9cf175cd11058 [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},
Neema Shettyfeea7742011-09-11 12:30:36 -0700117};
118
119
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700120/* Track ASM playback & capture sessions of DAI */
Patrick Lai770ca3e42011-12-12 13:44:54 -0800121static int fe_dai_map[MSM_FRONTEND_DAI_MM_SIZE][2] = {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700122 /* MULTIMEDIA1 */
123 {INVALID_SESSION, INVALID_SESSION},
124 /* MULTIMEDIA2 */
125 {INVALID_SESSION, INVALID_SESSION},
126 /* MULTIMEDIA3 */
127 {INVALID_SESSION, INVALID_SESSION},
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530128 /* MULTIMEDIA4 */
129 {INVALID_SESSION, INVALID_SESSION},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700130};
131
Patrick Laicf999112011-08-23 11:27:20 -0700132static void msm_pcm_routing_build_matrix(int fedai_id, int dspst_id,
133 int path_type)
134{
135 int i, port_type;
136 struct route_payload payload;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700137
Patrick Laicf999112011-08-23 11:27:20 -0700138 payload.num_copps = 0;
139 port_type = (path_type == ADM_PATH_PLAYBACK ?
140 MSM_AFE_PORT_TYPE_RX : MSM_AFE_PORT_TYPE_TX);
141
142 for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) {
143 if ((afe_get_port_type(msm_bedais[i].port_id) ==
144 port_type) &&
145 msm_bedais[i].active && (test_bit(fedai_id,
146 &msm_bedais[i].fe_sessions)))
147 payload.copp_ids[payload.num_copps++] =
148 msm_bedais[i].port_id;
149 }
150
151 if (payload.num_copps)
152 adm_matrix_map(dspst_id, path_type,
153 payload.num_copps, payload.copp_ids, 0);
154}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700155
156void msm_pcm_routing_reg_phy_stream(int fedai_id, int dspst_id, int stream_type)
157{
Patrick Laicf999112011-08-23 11:27:20 -0700158 int i, session_type, path_type, port_type;
159 struct route_payload payload;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700160
Patrick Lai770ca3e42011-12-12 13:44:54 -0800161 if (fedai_id > MSM_FRONTEND_DAI_MM_MAX_ID) {
162 /* bad ID assigned in machine driver */
163 pr_err("%s: bad MM ID\n", __func__);
164 return;
165 }
166
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700167 if (stream_type == SNDRV_PCM_STREAM_PLAYBACK) {
Patrick Laicf999112011-08-23 11:27:20 -0700168 session_type = SESSION_TYPE_RX;
169 path_type = ADM_PATH_PLAYBACK;
170 port_type = MSM_AFE_PORT_TYPE_RX;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700171 } else {
Patrick Laicf999112011-08-23 11:27:20 -0700172 session_type = SESSION_TYPE_TX;
173 path_type = ADM_PATH_LIVE_REC;
174 port_type = MSM_AFE_PORT_TYPE_TX;
175 }
176
177 mutex_lock(&routing_lock);
178
179 payload.num_copps = 0; /* only RX needs to use payload */
180 fe_dai_map[fedai_id][session_type] = dspst_id;
Ben Romberger037dd2f2011-09-22 14:01:32 -0700181 /* re-enable EQ if active */
182 if (eq_data[fedai_id].enable)
183 msm_send_eq_values(fedai_id);
Patrick Laicf999112011-08-23 11:27:20 -0700184 for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) {
185 if ((afe_get_port_type(msm_bedais[i].port_id) ==
186 port_type) && msm_bedais[i].active &&
187 (test_bit(fedai_id,
188 &msm_bedais[i].fe_sessions))) {
189 adm_open(msm_bedais[i].port_id,
190 path_type,
191 params_rate(msm_bedais[i].hw_params),
192 params_channels(msm_bedais[i].hw_params),
193 DEFAULT_COPP_TOPOLOGY);
194 payload.copp_ids[payload.num_copps++] =
195 msm_bedais[i].port_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700196 }
197 }
Patrick Laicf999112011-08-23 11:27:20 -0700198 if (payload.num_copps)
199 adm_matrix_map(dspst_id, path_type,
200 payload.num_copps, payload.copp_ids, 0);
201
202 mutex_unlock(&routing_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700203}
204
205void msm_pcm_routing_dereg_phy_stream(int fedai_id, int stream_type)
206{
Patrick Laicf999112011-08-23 11:27:20 -0700207 int i, port_type, session_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700208
Patrick Lai770ca3e42011-12-12 13:44:54 -0800209 if (fedai_id > MSM_FRONTEND_DAI_MM_MAX_ID) {
210 /* bad ID assigned in machine driver */
211 pr_err("%s: bad MM ID\n", __func__);
212 return;
213 }
214
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700215 if (stream_type == SNDRV_PCM_STREAM_PLAYBACK) {
Patrick Laicf999112011-08-23 11:27:20 -0700216 port_type = MSM_AFE_PORT_TYPE_RX;
217 session_type = SESSION_TYPE_RX;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700218 } else {
Patrick Laicf999112011-08-23 11:27:20 -0700219 port_type = MSM_AFE_PORT_TYPE_TX;
220 session_type = SESSION_TYPE_TX;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700221 }
Patrick Laicf999112011-08-23 11:27:20 -0700222
223 mutex_lock(&routing_lock);
224
225 for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) {
226 if ((afe_get_port_type(msm_bedais[i].port_id) ==
227 port_type) && msm_bedais[i].active &&
228 (test_bit(fedai_id,
229 &msm_bedais[i].fe_sessions)))
230 adm_close(msm_bedais[i].port_id);
231 }
232
233 fe_dai_map[fedai_id][session_type] = INVALID_SESSION;
234
235 mutex_unlock(&routing_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700236}
237
238static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set)
239{
Patrick Laicf999112011-08-23 11:27:20 -0700240 int session_type, path_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700241
242 pr_debug("%s: reg %x val %x set %x\n", __func__, reg, val, set);
243
Patrick Lai770ca3e42011-12-12 13:44:54 -0800244 if (val > MSM_FRONTEND_DAI_MM_MAX_ID) {
245 /* recheck FE ID in the mixer control defined in this file */
246 pr_err("%s: bad MM ID\n", __func__);
247 return;
248 }
249
Patrick Laicf999112011-08-23 11:27:20 -0700250 if (afe_get_port_type(msm_bedais[reg].port_id) ==
251 MSM_AFE_PORT_TYPE_RX) {
252 session_type = SESSION_TYPE_RX;
253 path_type = ADM_PATH_PLAYBACK;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700254 } else {
Patrick Laicf999112011-08-23 11:27:20 -0700255 session_type = SESSION_TYPE_TX;
256 path_type = ADM_PATH_LIVE_REC;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700257 }
Patrick Laicf999112011-08-23 11:27:20 -0700258
259 mutex_lock(&routing_lock);
260
261 if (set) {
262 set_bit(val, &msm_bedais[reg].fe_sessions);
263 if (msm_bedais[reg].active && fe_dai_map[val][session_type] !=
264 INVALID_SESSION) {
265 adm_open(msm_bedais[reg].port_id, path_type,
266 params_rate(msm_bedais[reg].hw_params),
267 params_channels(msm_bedais[reg].hw_params),
268 DEFAULT_COPP_TOPOLOGY);
269 msm_pcm_routing_build_matrix(val,
270 fe_dai_map[val][session_type], path_type);
271 }
272 } else {
273 clear_bit(val, &msm_bedais[reg].fe_sessions);
274 if (msm_bedais[reg].active && fe_dai_map[val][session_type] !=
275 INVALID_SESSION) {
276 adm_close(msm_bedais[reg].port_id);
277 msm_pcm_routing_build_matrix(val,
278 fe_dai_map[val][session_type], path_type);
279 }
280 }
281
282 mutex_unlock(&routing_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700283}
284
285static int msm_routing_get_audio_mixer(struct snd_kcontrol *kcontrol,
286 struct snd_ctl_elem_value *ucontrol)
287{
288 struct soc_mixer_control *mc =
289 (struct soc_mixer_control *)kcontrol->private_value;
290
Patrick Laicf999112011-08-23 11:27:20 -0700291 if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700292 ucontrol->value.integer.value[0] = 1;
293 else
294 ucontrol->value.integer.value[0] = 0;
295
296 pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift,
297 ucontrol->value.integer.value[0]);
298
299 return 0;
300}
301
302static int msm_routing_put_audio_mixer(struct snd_kcontrol *kcontrol,
303 struct snd_ctl_elem_value *ucontrol)
304{
Patrick Laiec2b8942011-09-01 11:01:51 -0700305 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
306 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700307 struct soc_mixer_control *mc =
308 (struct soc_mixer_control *)kcontrol->private_value;
309
310
311 if (ucontrol->value.integer.value[0]) {
312 msm_pcm_routing_process_audio(mc->reg, mc->shift, 1);
313 snd_soc_dapm_mixer_update_power(widget, kcontrol, 1);
314 } else {
315 msm_pcm_routing_process_audio(mc->reg, mc->shift, 0);
316 snd_soc_dapm_mixer_update_power(widget, kcontrol, 0);
317 }
318
319 return 1;
320}
321
Neema Shettyfeea7742011-09-11 12:30:36 -0700322static void msm_pcm_routing_process_voice(u16 reg, u16 val, int set)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700323{
Neema Shetty2c07eb52011-08-21 20:33:52 -0700324 u16 session_id = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700325
Neema Shettyfeea7742011-09-11 12:30:36 -0700326 pr_debug("%s: reg %x val %x set %x\n", __func__, reg, val, set);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700327
Neema Shettyfeea7742011-09-11 12:30:36 -0700328 if (val == MSM_FRONTEND_DAI_CS_VOICE)
Neema Shetty2c07eb52011-08-21 20:33:52 -0700329 session_id = voc_get_session_id(VOICE_SESSION_NAME);
330 else
331 session_id = voc_get_session_id(VOIP_SESSION_NAME);
332
333 pr_debug("%s: FE DAI 0x%x session_id 0x%x\n",
Neema Shettyfeea7742011-09-11 12:30:36 -0700334 __func__, val, session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700335
Neema Shettyfeea7742011-09-11 12:30:36 -0700336 mutex_lock(&routing_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700337
338 if (set)
Neema Shettyfeea7742011-09-11 12:30:36 -0700339 set_bit(val, &msm_bedais[reg].fe_sessions);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700340 else
Neema Shettyfeea7742011-09-11 12:30:36 -0700341 clear_bit(val, &msm_bedais[reg].fe_sessions);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700342
Neema Shettyfeea7742011-09-11 12:30:36 -0700343 mutex_unlock(&routing_lock);
344
345 if (afe_get_port_type(msm_bedais[reg].port_id) ==
346 MSM_AFE_PORT_TYPE_RX) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700347 voc_set_route_flag(session_id, RX_PATH, set);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700348 if (set) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700349 voc_set_rxtx_port(session_id,
Neema Shettyfeea7742011-09-11 12:30:36 -0700350 msm_bedais[reg].port_id, DEV_RX);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700351
Neema Shetty2c07eb52011-08-21 20:33:52 -0700352 if (voc_get_route_flag(session_id, RX_PATH) &&
353 voc_get_route_flag(session_id, TX_PATH))
354 voc_enable_cvp(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700355 } else {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700356 voc_disable_cvp(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700357 }
358 } else {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700359 voc_set_route_flag(session_id, TX_PATH, set);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700360 if (set) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700361 voc_set_rxtx_port(session_id,
Neema Shettyfeea7742011-09-11 12:30:36 -0700362 msm_bedais[reg].port_id, DEV_TX);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700363 if (voc_get_route_flag(session_id, RX_PATH) &&
364 voc_get_route_flag(session_id, TX_PATH))
365 voc_enable_cvp(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700366 } else {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700367 voc_disable_cvp(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700368 }
369 }
370}
371
372static int msm_routing_get_voice_mixer(struct snd_kcontrol *kcontrol,
373 struct snd_ctl_elem_value *ucontrol)
374{
375 struct soc_mixer_control *mc =
376 (struct soc_mixer_control *)kcontrol->private_value;
377
Neema Shettyfeea7742011-09-11 12:30:36 -0700378 mutex_lock(&routing_lock);
379
380 if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700381 ucontrol->value.integer.value[0] = 1;
382 else
383 ucontrol->value.integer.value[0] = 0;
384
Neema Shettyfeea7742011-09-11 12:30:36 -0700385 mutex_unlock(&routing_lock);
386
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700387 pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift,
388 ucontrol->value.integer.value[0]);
389
390 return 0;
391}
392
393static int msm_routing_put_voice_mixer(struct snd_kcontrol *kcontrol,
394 struct snd_ctl_elem_value *ucontrol)
395{
Patrick Laiec2b8942011-09-01 11:01:51 -0700396 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
397 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700398 struct soc_mixer_control *mc =
399 (struct soc_mixer_control *)kcontrol->private_value;
400
401 if (ucontrol->value.integer.value[0]) {
Neema Shettyfeea7742011-09-11 12:30:36 -0700402 msm_pcm_routing_process_voice(mc->reg, mc->shift, 1);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700403 snd_soc_dapm_mixer_update_power(widget, kcontrol, 1);
404 } else {
Neema Shettyfeea7742011-09-11 12:30:36 -0700405 msm_pcm_routing_process_voice(mc->reg, mc->shift, 0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700406 snd_soc_dapm_mixer_update_power(widget, kcontrol, 0);
407 }
408
409 return 1;
410}
411
Sriranjan Srikantama4969dd2011-07-14 00:34:56 -0700412static int msm_routing_get_switch_mixer(struct snd_kcontrol *kcontrol,
413 struct snd_ctl_elem_value *ucontrol)
414{
415 ucontrol->value.integer.value[0] = fm_switch_enable;
416 pr_debug("%s: FM Switch enable %ld\n", __func__,
417 ucontrol->value.integer.value[0]);
418 return 0;
419}
420
421static int msm_routing_put_switch_mixer(struct snd_kcontrol *kcontrol,
422 struct snd_ctl_elem_value *ucontrol)
423{
Sriranjan Srikantamdf509d12011-10-24 17:53:27 -0700424 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
425 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
Sriranjan Srikantama4969dd2011-07-14 00:34:56 -0700426
427 pr_debug("%s: FM Switch enable %ld\n", __func__,
428 ucontrol->value.integer.value[0]);
429 if (ucontrol->value.integer.value[0])
430 snd_soc_dapm_mixer_update_power(widget, kcontrol, 1);
431 else
432 snd_soc_dapm_mixer_update_power(widget, kcontrol, 0);
433 fm_switch_enable = ucontrol->value.integer.value[0];
434 return 1;
435}
436
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700437static int msm_routing_get_port_mixer(struct snd_kcontrol *kcontrol,
438 struct snd_ctl_elem_value *ucontrol)
439{
440 struct soc_mixer_control *mc =
441 (struct soc_mixer_control *)kcontrol->private_value;
442
Patrick Laicf999112011-08-23 11:27:20 -0700443 if (test_bit(mc->shift, &msm_bedais[mc->reg].port_sessions))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700444 ucontrol->value.integer.value[0] = 1;
445 else
446 ucontrol->value.integer.value[0] = 0;
447
448 pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift,
449 ucontrol->value.integer.value[0]);
450
451 return 0;
452}
453
454static int msm_routing_put_port_mixer(struct snd_kcontrol *kcontrol,
455 struct snd_ctl_elem_value *ucontrol)
456{
457 struct soc_mixer_control *mc =
458 (struct soc_mixer_control *)kcontrol->private_value;
459
460 pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg,
461 mc->shift, ucontrol->value.integer.value[0]);
462
463 if (ucontrol->value.integer.value[0]) {
Patrick Laicf999112011-08-23 11:27:20 -0700464 afe_loopback(1, msm_bedais[mc->reg].port_id,
465 msm_bedais[mc->shift].port_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700466 set_bit(mc->shift,
Patrick Laicf999112011-08-23 11:27:20 -0700467 &msm_bedais[mc->reg].port_sessions);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700468 } else {
Patrick Laicf999112011-08-23 11:27:20 -0700469 afe_loopback(0, msm_bedais[mc->reg].port_id,
470 msm_bedais[mc->shift].port_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700471 clear_bit(mc->shift,
Patrick Laicf999112011-08-23 11:27:20 -0700472 &msm_bedais[mc->reg].port_sessions);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700473 }
474
475 return 1;
476}
477
Jayasena Sangaraboinacb1e22f2011-07-18 10:36:57 -0700478static int msm_routing_get_fm_vol_mixer(struct snd_kcontrol *kcontrol,
479 struct snd_ctl_elem_value *ucontrol)
480{
481 ucontrol->value.integer.value[0] = msm_route_fm_vol_control;
482 return 0;
483}
484
485static int msm_routing_set_fm_vol_mixer(struct snd_kcontrol *kcontrol,
486 struct snd_ctl_elem_value *ucontrol)
487{
488 afe_loopback_gain(INT_FM_TX , ucontrol->value.integer.value[0]);
489
490 msm_route_fm_vol_control = ucontrol->value.integer.value[0];
491
492 return 0;
493}
494
Asish Bhattacharya0ec76182011-07-29 16:58:11 +0530495static int msm_routing_get_lpa_vol_mixer(struct snd_kcontrol *kcontrol,
496 struct snd_ctl_elem_value *ucontrol)
497{
498 ucontrol->value.integer.value[0] = msm_route_lpa_vol_control;
499 return 0;
500}
501
502static int msm_routing_set_lpa_vol_mixer(struct snd_kcontrol *kcontrol,
503 struct snd_ctl_elem_value *ucontrol)
504{
505 if (!lpa_set_volume(ucontrol->value.integer.value[0]))
506 msm_route_lpa_vol_control =
507 ucontrol->value.integer.value[0];
508
509 return 0;
510}
511
Ben Romberger037dd2f2011-09-22 14:01:32 -0700512static void msm_send_eq_values(int eq_idx)
513{
514 int result;
515 struct audio_client *ac =
516 q6asm_get_audio_client(fe_dai_map[eq_idx][SESSION_TYPE_RX]);
517
518 if (ac == NULL) {
519 pr_err("%s: Could not get audio client for session: %d\n",
520 __func__, fe_dai_map[eq_idx][SESSION_TYPE_RX]);
521 goto done;
522 }
523
524 result = q6asm_equalizer(ac, &eq_data[eq_idx]);
525
526 if (result < 0)
527 pr_err("%s: Call to ASM equalizer failed, returned = %d\n",
528 __func__, result);
529done:
530 return;
531}
532
533static int msm_routing_get_eq_enable_mixer(struct snd_kcontrol *kcontrol,
534 struct snd_ctl_elem_value *ucontrol)
535{
536 int eq_idx = ((struct soc_multi_mixer_control *)
537 kcontrol->private_value)->reg;
538
Ben Romberger76f57032011-12-08 20:07:34 -0800539 ucontrol->value.integer.value[0] = eq_data[eq_idx].enable;
540
Ben Romberger037dd2f2011-09-22 14:01:32 -0700541 pr_debug("%s: EQ #%d enable %d\n", __func__,
542 eq_idx, eq_data[eq_idx].enable);
Ben Romberger76f57032011-12-08 20:07:34 -0800543 return 0;
Ben Romberger037dd2f2011-09-22 14:01:32 -0700544}
545
546static int msm_routing_put_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 int value = ucontrol->value.integer.value[0];
552
553 pr_debug("%s: EQ #%d enable %d\n", __func__,
554 eq_idx, value);
555 eq_data[eq_idx].enable = value;
556
557 msm_send_eq_values(eq_idx);
558 return 0;
559}
560
561static int msm_routing_get_eq_band_count_audio_mixer(
562 struct snd_kcontrol *kcontrol,
563 struct snd_ctl_elem_value *ucontrol)
564{
565 int eq_idx = ((struct soc_multi_mixer_control *)
566 kcontrol->private_value)->reg;
567
Ben Romberger76f57032011-12-08 20:07:34 -0800568 ucontrol->value.integer.value[0] = eq_data[eq_idx].num_bands;
569
Ben Romberger037dd2f2011-09-22 14:01:32 -0700570 pr_debug("%s: EQ #%d bands %d\n", __func__,
571 eq_idx, eq_data[eq_idx].num_bands);
572 return eq_data[eq_idx].num_bands;
573}
574
575static int msm_routing_put_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 int value = ucontrol->value.integer.value[0];
582
Ben Romberger037dd2f2011-09-22 14:01:32 -0700583 pr_debug("%s: EQ #%d bands %d\n", __func__,
584 eq_idx, value);
585 eq_data[eq_idx].num_bands = value;
586 return 0;
587}
588
589static int msm_routing_get_eq_band_audio_mixer(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 band_idx = ((struct soc_multi_mixer_control *)
595 kcontrol->private_value)->shift;
596
Ben Romberger76f57032011-12-08 20:07:34 -0800597 ucontrol->value.integer.value[0] =
598 eq_data[eq_idx].eq_bands[band_idx].band_idx;
599 ucontrol->value.integer.value[1] =
600 eq_data[eq_idx].eq_bands[band_idx].filter_type;
601 ucontrol->value.integer.value[2] =
602 eq_data[eq_idx].eq_bands[band_idx].center_freq_hz;
603 ucontrol->value.integer.value[3] =
604 eq_data[eq_idx].eq_bands[band_idx].filter_gain;
605 ucontrol->value.integer.value[4] =
606 eq_data[eq_idx].eq_bands[band_idx].q_factor;
607
Ben Romberger037dd2f2011-09-22 14:01:32 -0700608 pr_debug("%s: band_idx = %d\n", __func__,
609 eq_data[eq_idx].eq_bands[band_idx].band_idx);
610 pr_debug("%s: filter_type = %d\n", __func__,
611 eq_data[eq_idx].eq_bands[band_idx].filter_type);
612 pr_debug("%s: center_freq_hz = %d\n", __func__,
613 eq_data[eq_idx].eq_bands[band_idx].center_freq_hz);
614 pr_debug("%s: filter_gain = %d\n", __func__,
615 eq_data[eq_idx].eq_bands[band_idx].filter_gain);
616 pr_debug("%s: q_factor = %d\n", __func__,
617 eq_data[eq_idx].eq_bands[band_idx].q_factor);
618 return 0;
619}
620
621static int msm_routing_put_eq_band_audio_mixer(struct snd_kcontrol *kcontrol,
622 struct snd_ctl_elem_value *ucontrol)
623{
624 int eq_idx = ((struct soc_multi_mixer_control *)
625 kcontrol->private_value)->reg;
626 int band_idx = ((struct soc_multi_mixer_control *)
627 kcontrol->private_value)->shift;
628
629 eq_data[eq_idx].eq_bands[band_idx].band_idx =
630 ucontrol->value.integer.value[0];
631 eq_data[eq_idx].eq_bands[band_idx].filter_type =
632 ucontrol->value.integer.value[1];
633 eq_data[eq_idx].eq_bands[band_idx].center_freq_hz =
634 ucontrol->value.integer.value[2];
635 eq_data[eq_idx].eq_bands[band_idx].filter_gain =
636 ucontrol->value.integer.value[3];
637 eq_data[eq_idx].eq_bands[band_idx].q_factor =
638 ucontrol->value.integer.value[4];
639 return 0;
640}
641
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700642static const struct snd_kcontrol_new pri_i2s_rx_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700643 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_PRI_I2S_RX ,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700644 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
645 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700646 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_PRI_I2S_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700647 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
648 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700649 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_PRI_I2S_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700650 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
651 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530652 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_PRI_I2S_RX,
653 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
654 msm_routing_put_audio_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700655};
656
657static const struct snd_kcontrol_new slimbus_rx_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700658 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SLIMBUS_0_RX ,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700659 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
660 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700661 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SLIMBUS_0_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700662 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
663 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700664 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SLIMBUS_0_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700665 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
666 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530667 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SLIMBUS_0_RX,
668 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
669 msm_routing_put_audio_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700670};
671
672static const struct snd_kcontrol_new hdmi_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700673 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_HDMI_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700674 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
675 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700676 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_HDMI_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700677 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
678 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700679 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_HDMI_RX,
Asish Bhattacharyac592eed2011-09-16 17:43:02 +0530680 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
681 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530682 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_HDMI_RX,
683 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
684 msm_routing_put_audio_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700685};
686
687static const struct snd_kcontrol_new int_bt_sco_rx_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700688 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_INT_BT_SCO_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700689 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
690 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700691 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_INT_BT_SCO_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700692 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
693 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700694 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_INT_BT_SCO_RX,
Asish Bhattacharyac592eed2011-09-16 17:43:02 +0530695 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
696 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530697 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_INT_BT_SCO_RX,
698 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
699 msm_routing_put_audio_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700700};
701
702static const struct snd_kcontrol_new int_fm_rx_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700703 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_INT_FM_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700704 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
705 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700706 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_INT_FM_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700707 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
708 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700709 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_INT_FM_RX,
Asish Bhattacharyac592eed2011-09-16 17:43:02 +0530710 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
711 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530712 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_INT_FM_RX,
713 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
714 msm_routing_put_audio_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700715};
716
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530717static const struct snd_kcontrol_new afe_pcm_rx_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700718 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_AFE_PCM_RX,
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530719 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
720 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700721 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_AFE_PCM_RX,
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530722 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
723 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700724 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_AFE_PCM_RX,
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530725 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
726 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530727 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_AFE_PCM_RX,
728 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
729 msm_routing_put_audio_mixer),
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530730};
731
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700732static const struct snd_kcontrol_new auxpcm_rx_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700733 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_AUXPCM_RX,
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700734 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
735 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700736 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_AUXPCM_RX,
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700737 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
738 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700739 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_AUXPCM_RX,
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700740 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
741 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530742 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_AUXPCM_RX,
743 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
744 msm_routing_put_audio_mixer),
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700745};
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530746
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700747static const struct snd_kcontrol_new mmul1_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700748 SOC_SINGLE_EXT("PRI_TX", MSM_BACKEND_DAI_PRI_I2S_TX,
749 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
750 msm_routing_put_audio_mixer),
751 SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX,
752 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
753 msm_routing_put_audio_mixer),
754 SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_AUXPCM_TX,
755 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
756 msm_routing_put_audio_mixer),
757 SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX,
758 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
759 msm_routing_put_audio_mixer),
760 SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX,
761 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
762 msm_routing_put_audio_mixer),
763 SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX,
764 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
765 msm_routing_put_audio_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700766};
767
Jayasena Sangaraboina99fee652011-09-19 07:43:13 -0700768static const struct snd_kcontrol_new mmul2_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700769 SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX,
770 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
Jayasena Sangaraboina99fee652011-09-19 07:43:13 -0700771 msm_routing_put_audio_mixer),
772};
773
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700774static const struct snd_kcontrol_new pri_rx_voice_mixer_controls[] = {
Neema Shettyfeea7742011-09-11 12:30:36 -0700775 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_PRI_I2S_RX,
776 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
777 msm_routing_put_voice_mixer),
778 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_PRI_I2S_RX,
779 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
780 msm_routing_put_voice_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700781};
782
783static const struct snd_kcontrol_new slimbus_rx_voice_mixer_controls[] = {
Neema Shettyfeea7742011-09-11 12:30:36 -0700784 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_SLIMBUS_0_RX,
785 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
786 msm_routing_put_voice_mixer),
787 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SLIMBUS_0_RX ,
788 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
789 msm_routing_put_voice_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700790};
791
792static const struct snd_kcontrol_new bt_sco_rx_voice_mixer_controls[] = {
Neema Shettyfeea7742011-09-11 12:30:36 -0700793 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_INT_BT_SCO_RX,
794 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
795 msm_routing_put_voice_mixer),
796 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_INT_BT_SCO_RX ,
797 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
798 msm_routing_put_voice_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700799};
800
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530801static const struct snd_kcontrol_new afe_pcm_rx_voice_mixer_controls[] = {
802 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_AFE_PCM_RX,
803 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
804 msm_routing_put_voice_mixer),
805 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_AFE_PCM_RX,
806 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
807 msm_routing_put_voice_mixer),
808};
809
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700810static const struct snd_kcontrol_new aux_pcm_rx_voice_mixer_controls[] = {
811 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_AUXPCM_RX,
812 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
813 msm_routing_put_voice_mixer),
814 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_AUXPCM_RX,
815 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
816 msm_routing_put_voice_mixer),
817};
818
Alex Wong593576c2011-11-15 08:03:24 -0800819static const struct snd_kcontrol_new hdmi_rx_voice_mixer_controls[] = {
820 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_HDMI_RX,
821 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
822 msm_routing_put_voice_mixer),
823 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_HDMI_RX,
824 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
825 msm_routing_put_voice_mixer),
826};
827
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700828static const struct snd_kcontrol_new tx_voice_mixer_controls[] = {
Neema Shettyfeea7742011-09-11 12:30:36 -0700829 SOC_SINGLE_EXT("PRI_TX_Voice", MSM_BACKEND_DAI_PRI_I2S_TX,
830 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
831 msm_routing_put_voice_mixer),
832 SOC_SINGLE_EXT("SLIM_0_TX_Voice", MSM_BACKEND_DAI_SLIMBUS_0_TX,
833 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
834 msm_routing_put_voice_mixer),
835 SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_Voice",
836 MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_CS_VOICE, 1, 0,
Neema Shetty2c07eb52011-08-21 20:33:52 -0700837 msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530838 SOC_SINGLE_EXT("AFE_PCM_TX_Voice", MSM_BACKEND_DAI_AFE_PCM_TX,
839 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
840 msm_routing_put_voice_mixer),
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700841 SOC_SINGLE_EXT("AUX_PCM_TX_Voice", MSM_BACKEND_DAI_AUXPCM_TX,
842 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
843 msm_routing_put_voice_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700844};
845
846static const struct snd_kcontrol_new tx_voip_mixer_controls[] = {
Neema Shettyfeea7742011-09-11 12:30:36 -0700847 SOC_SINGLE_EXT("PRI_TX_Voip", MSM_BACKEND_DAI_PRI_I2S_TX,
848 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
849 msm_routing_put_voice_mixer),
850 SOC_SINGLE_EXT("SLIM_0_TX_Voip", MSM_BACKEND_DAI_SLIMBUS_0_TX,
851 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
852 msm_routing_put_voice_mixer),
853 SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_Voip", MSM_BACKEND_DAI_INT_BT_SCO_TX,
854 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
855 msm_routing_put_voice_mixer),
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530856 SOC_SINGLE_EXT("AFE_PCM_TX_Voip", MSM_BACKEND_DAI_AFE_PCM_TX,
857 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
858 msm_routing_put_voice_mixer),
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700859 SOC_SINGLE_EXT("AUX_PCM_TX_Voip", MSM_BACKEND_DAI_AUXPCM_TX,
860 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
861 msm_routing_put_voice_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700862};
863
864static const struct snd_kcontrol_new sbus_0_rx_port_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700865 SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700866 MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer,
867 msm_routing_put_port_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700868 SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700869 MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer,
870 msm_routing_put_port_mixer),
871};
872
Sriranjan Srikantama4969dd2011-07-14 00:34:56 -0700873static const struct snd_kcontrol_new fm_switch_mixer_controls =
874 SOC_SINGLE_EXT("Switch", SND_SOC_NOPM,
875 0, 1, 0, msm_routing_get_switch_mixer,
876 msm_routing_put_switch_mixer);
877
Jayasena Sangaraboinacb1e22f2011-07-18 10:36:57 -0700878static const struct snd_kcontrol_new int_fm_vol_mixer_controls[] = {
879 SOC_SINGLE_EXT_TLV("Internal FM RX Volume", SND_SOC_NOPM, 0,
880 INT_FM_RX_VOL_GAIN, 0, msm_routing_get_fm_vol_mixer,
881 msm_routing_set_fm_vol_mixer, fm_rx_vol_gain),
882};
883
Asish Bhattacharya0ec76182011-07-29 16:58:11 +0530884static const struct snd_kcontrol_new lpa_vol_mixer_controls[] = {
885 SOC_SINGLE_EXT_TLV("LPA RX Volume", SND_SOC_NOPM, 0,
886 INT_LPA_RX_VOL_GAIN, 0, msm_routing_get_lpa_vol_mixer,
887 msm_routing_set_lpa_vol_mixer, lpa_rx_vol_gain),
888};
889
Ben Romberger037dd2f2011-09-22 14:01:32 -0700890static const struct snd_kcontrol_new eq_enable_mixer_controls[] = {
891 SOC_SINGLE_EXT("MultiMedia1 EQ Enable", SND_SOC_NOPM,
892 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_eq_enable_mixer,
893 msm_routing_put_eq_enable_mixer),
894 SOC_SINGLE_EXT("MultiMedia2 EQ Enable", SND_SOC_NOPM,
895 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_eq_enable_mixer,
896 msm_routing_put_eq_enable_mixer),
897 SOC_SINGLE_EXT("MultiMedia3 EQ Enable", SND_SOC_NOPM,
898 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_eq_enable_mixer,
899 msm_routing_put_eq_enable_mixer),
900};
901
902static const struct snd_kcontrol_new eq_band_mixer_controls[] = {
903 SOC_SINGLE_EXT("MultiMedia1 EQ Band Count", SND_SOC_NOPM,
904 MSM_FRONTEND_DAI_MULTIMEDIA1, 11, 0,
905 msm_routing_get_eq_band_count_audio_mixer,
906 msm_routing_put_eq_band_count_audio_mixer),
907 SOC_SINGLE_EXT("MultiMedia2 EQ Band Count", SND_SOC_NOPM,
908 MSM_FRONTEND_DAI_MULTIMEDIA2, 11, 0,
909 msm_routing_get_eq_band_count_audio_mixer,
910 msm_routing_put_eq_band_count_audio_mixer),
911 SOC_SINGLE_EXT("MultiMedia3 EQ Band Count", SND_SOC_NOPM,
912 MSM_FRONTEND_DAI_MULTIMEDIA3, 11, 0,
913 msm_routing_get_eq_band_count_audio_mixer,
914 msm_routing_put_eq_band_count_audio_mixer),
915};
916
917static const struct snd_kcontrol_new eq_coeff_mixer_controls[] = {
918 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band1", EQ_BAND1,
919 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
920 msm_routing_get_eq_band_audio_mixer,
921 msm_routing_put_eq_band_audio_mixer),
922 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band2", EQ_BAND2,
923 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
924 msm_routing_get_eq_band_audio_mixer,
925 msm_routing_put_eq_band_audio_mixer),
926 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band3", EQ_BAND3,
927 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
928 msm_routing_get_eq_band_audio_mixer,
929 msm_routing_put_eq_band_audio_mixer),
930 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band4", EQ_BAND4,
931 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
932 msm_routing_get_eq_band_audio_mixer,
933 msm_routing_put_eq_band_audio_mixer),
934 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band5", EQ_BAND5,
935 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
936 msm_routing_get_eq_band_audio_mixer,
937 msm_routing_put_eq_band_audio_mixer),
938 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band6", EQ_BAND6,
939 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
940 msm_routing_get_eq_band_audio_mixer,
941 msm_routing_put_eq_band_audio_mixer),
942 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band7", EQ_BAND7,
943 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
944 msm_routing_get_eq_band_audio_mixer,
945 msm_routing_put_eq_band_audio_mixer),
946 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band8", EQ_BAND8,
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 Band9", EQ_BAND9,
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 Band10", EQ_BAND10,
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 Band11", EQ_BAND11,
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 Band12", EQ_BAND12,
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("MultiMedia2 EQ Band1", EQ_BAND1,
967 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
968 msm_routing_get_eq_band_audio_mixer,
969 msm_routing_put_eq_band_audio_mixer),
970 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band2", EQ_BAND2,
971 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
972 msm_routing_get_eq_band_audio_mixer,
973 msm_routing_put_eq_band_audio_mixer),
974 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band3", EQ_BAND3,
975 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
976 msm_routing_get_eq_band_audio_mixer,
977 msm_routing_put_eq_band_audio_mixer),
978 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band4", EQ_BAND4,
979 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
980 msm_routing_get_eq_band_audio_mixer,
981 msm_routing_put_eq_band_audio_mixer),
982 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band5", EQ_BAND5,
983 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
984 msm_routing_get_eq_band_audio_mixer,
985 msm_routing_put_eq_band_audio_mixer),
986 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band6", EQ_BAND6,
987 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
988 msm_routing_get_eq_band_audio_mixer,
989 msm_routing_put_eq_band_audio_mixer),
990 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band7", EQ_BAND7,
991 MSM_FRONTEND_DAI_MULTIMEDIA2, 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 Band8", EQ_BAND8,
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 Band9", EQ_BAND9,
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 Band10", EQ_BAND10,
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 Band11", EQ_BAND11,
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 Band12", EQ_BAND12,
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("MultiMedia3 EQ Band1", EQ_BAND1,
1015 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1016 msm_routing_get_eq_band_audio_mixer,
1017 msm_routing_put_eq_band_audio_mixer),
1018 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band2", EQ_BAND2,
1019 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1020 msm_routing_get_eq_band_audio_mixer,
1021 msm_routing_put_eq_band_audio_mixer),
1022 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band3", EQ_BAND3,
1023 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1024 msm_routing_get_eq_band_audio_mixer,
1025 msm_routing_put_eq_band_audio_mixer),
1026 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band4", EQ_BAND4,
1027 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1028 msm_routing_get_eq_band_audio_mixer,
1029 msm_routing_put_eq_band_audio_mixer),
1030 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band5", EQ_BAND5,
1031 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1032 msm_routing_get_eq_band_audio_mixer,
1033 msm_routing_put_eq_band_audio_mixer),
1034 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band6", EQ_BAND6,
1035 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1036 msm_routing_get_eq_band_audio_mixer,
1037 msm_routing_put_eq_band_audio_mixer),
1038 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band7", EQ_BAND7,
1039 MSM_FRONTEND_DAI_MULTIMEDIA3, 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 Band8", EQ_BAND8,
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 Band9", EQ_BAND9,
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 Band10", EQ_BAND10,
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 Band11", EQ_BAND11,
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 Band12", EQ_BAND12,
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};
1063
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001064static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
1065 /* Frontend AIF */
1066 /* Widget name equals to Front-End DAI name<Need confirmation>,
1067 * Stream name must contains substring of front-end dai name
1068 */
1069 SND_SOC_DAPM_AIF_IN("MM_DL1", "MultiMedia1 Playback", 0, 0, 0, 0),
1070 SND_SOC_DAPM_AIF_IN("MM_DL2", "MultiMedia2 Playback", 0, 0, 0, 0),
1071 SND_SOC_DAPM_AIF_IN("MM_DL3", "MultiMedia3 Playback", 0, 0, 0, 0),
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301072 SND_SOC_DAPM_AIF_IN("MM_DL4", "MultiMedia4 Playback", 0, 0, 0, 0),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001073 SND_SOC_DAPM_AIF_IN("VOIP_DL", "VoIP Playback", 0, 0, 0, 0),
1074 SND_SOC_DAPM_AIF_OUT("MM_UL1", "MultiMedia1 Capture", 0, 0, 0, 0),
Jayasena Sangaraboina99fee652011-09-19 07:43:13 -07001075 SND_SOC_DAPM_AIF_OUT("MM_UL2", "MultiMedia2 Capture", 0, 0, 0, 0),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001076 SND_SOC_DAPM_AIF_IN("CS-VOICE_DL1", "CS-VOICE Playback", 0, 0, 0, 0),
1077 SND_SOC_DAPM_AIF_OUT("CS-VOICE_UL1", "CS-VOICE Capture", 0, 0, 0, 0),
1078 SND_SOC_DAPM_AIF_OUT("VOIP_UL", "VoIP Capture", 0, 0, 0, 0),
1079 SND_SOC_DAPM_AIF_IN("SLIM0_DL_HL", "SLIMBUS0_HOSTLESS Playback",
1080 0, 0, 0, 0),
1081 SND_SOC_DAPM_AIF_OUT("SLIM0_UL_HL", "SLIMBUS0_HOSTLESS Capture",
1082 0, 0, 0, 0),
1083 SND_SOC_DAPM_AIF_IN("INTFM_DL_HL", "INT_FM_HOSTLESS Playback",
1084 0, 0, 0, 0),
1085 SND_SOC_DAPM_AIF_OUT("INTFM_UL_HL", "INT_FM_HOSTLESS Capture",
1086 0, 0, 0, 0),
1087 /* Backend AIF */
1088 /* Stream name equals to backend dai link stream name
1089 */
1090 SND_SOC_DAPM_AIF_OUT("PRI_I2S_RX", "Primary I2S Playback", 0, 0, 0, 0),
1091 SND_SOC_DAPM_AIF_OUT("SLIMBUS_0_RX", "Slimbus Playback", 0, 0, 0, 0),
1092 SND_SOC_DAPM_AIF_OUT("HDMI", "HDMI Playback", 0, 0, 0 , 0),
1093 SND_SOC_DAPM_AIF_IN("PRI_I2S_TX", "Primary I2S Capture", 0, 0, 0, 0),
1094 SND_SOC_DAPM_AIF_IN("SLIMBUS_0_TX", "Slimbus Capture", 0, 0, 0, 0),
1095 SND_SOC_DAPM_AIF_OUT("INT_BT_SCO_RX", "Internal BT-SCO Playback",
1096 0, 0, 0 , 0),
1097 SND_SOC_DAPM_AIF_IN("INT_BT_SCO_TX", "Internal BT-SCO Capture",
1098 0, 0, 0, 0),
1099 SND_SOC_DAPM_AIF_OUT("INT_FM_RX", "Internal FM Playback",
1100 0, 0, 0 , 0),
1101 SND_SOC_DAPM_AIF_IN("INT_FM_TX", "Internal FM Capture",
1102 0, 0, 0, 0),
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301103 SND_SOC_DAPM_AIF_OUT("PCM_RX", "AFE Playback",
1104 0, 0, 0 , 0),
1105 SND_SOC_DAPM_AIF_IN("PCM_TX", "AFE Capture",
1106 0, 0, 0, 0),
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001107 SND_SOC_DAPM_AIF_OUT("AUX_PCM_RX", "AUX PCM Playback", 0, 0, 0, 0),
1108 SND_SOC_DAPM_AIF_IN("AUX_PCM_TX", "AUX PCM Capture", 0, 0, 0, 0),
Sriranjan Srikantama4969dd2011-07-14 00:34:56 -07001109 /* Switch Definitions */
Sriranjan Srikantamdf509d12011-10-24 17:53:27 -07001110 SND_SOC_DAPM_SWITCH("SLIMBUS_DL_HL", SND_SOC_NOPM, 0, 0,
Sriranjan Srikantama4969dd2011-07-14 00:34:56 -07001111 &fm_switch_mixer_controls),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001112 /* Mixer definitions */
1113 SND_SOC_DAPM_MIXER("PRI_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1114 pri_i2s_rx_mixer_controls, ARRAY_SIZE(pri_i2s_rx_mixer_controls)),
1115 SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1116 slimbus_rx_mixer_controls, ARRAY_SIZE(slimbus_rx_mixer_controls)),
1117 SND_SOC_DAPM_MIXER("HDMI Mixer", SND_SOC_NOPM, 0, 0,
1118 hdmi_mixer_controls, ARRAY_SIZE(hdmi_mixer_controls)),
1119 SND_SOC_DAPM_MIXER("MultiMedia1 Mixer", SND_SOC_NOPM, 0, 0,
1120 mmul1_mixer_controls, ARRAY_SIZE(mmul1_mixer_controls)),
Jayasena Sangaraboina99fee652011-09-19 07:43:13 -07001121 SND_SOC_DAPM_MIXER("MultiMedia2 Mixer", SND_SOC_NOPM, 0, 0,
1122 mmul2_mixer_controls, ARRAY_SIZE(mmul2_mixer_controls)),
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001123 SND_SOC_DAPM_MIXER("AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1124 auxpcm_rx_mixer_controls, ARRAY_SIZE(auxpcm_rx_mixer_controls)),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001125 /* Voice Mixer */
1126 SND_SOC_DAPM_MIXER("PRI_RX_Voice Mixer",
1127 SND_SOC_NOPM, 0, 0, pri_rx_voice_mixer_controls,
1128 ARRAY_SIZE(pri_rx_voice_mixer_controls)),
1129 SND_SOC_DAPM_MIXER("SLIM_0_RX_Voice Mixer",
1130 SND_SOC_NOPM, 0, 0,
1131 slimbus_rx_voice_mixer_controls,
1132 ARRAY_SIZE(slimbus_rx_voice_mixer_controls)),
1133 SND_SOC_DAPM_MIXER("INTERNAL_BT_SCO_RX_Voice Mixer",
1134 SND_SOC_NOPM, 0, 0,
1135 bt_sco_rx_voice_mixer_controls,
1136 ARRAY_SIZE(bt_sco_rx_voice_mixer_controls)),
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301137 SND_SOC_DAPM_MIXER("AFE_PCM_RX_Voice Mixer",
1138 SND_SOC_NOPM, 0, 0,
1139 afe_pcm_rx_voice_mixer_controls,
1140 ARRAY_SIZE(afe_pcm_rx_voice_mixer_controls)),
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001141 SND_SOC_DAPM_MIXER("AUX_PCM_RX_Voice Mixer",
1142 SND_SOC_NOPM, 0, 0,
1143 aux_pcm_rx_voice_mixer_controls,
1144 ARRAY_SIZE(aux_pcm_rx_voice_mixer_controls)),
Alex Wong593576c2011-11-15 08:03:24 -08001145 SND_SOC_DAPM_MIXER("HDMI_RX_Voice Mixer",
1146 SND_SOC_NOPM, 0, 0,
1147 hdmi_rx_voice_mixer_controls,
1148 ARRAY_SIZE(hdmi_rx_voice_mixer_controls)),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001149 SND_SOC_DAPM_MIXER("Voice_Tx Mixer",
1150 SND_SOC_NOPM, 0, 0, tx_voice_mixer_controls,
1151 ARRAY_SIZE(tx_voice_mixer_controls)),
1152 SND_SOC_DAPM_MIXER("Voip_Tx Mixer",
1153 SND_SOC_NOPM, 0, 0, tx_voip_mixer_controls,
1154 ARRAY_SIZE(tx_voip_mixer_controls)),
1155 SND_SOC_DAPM_MIXER("INTERNAL_BT_SCO_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1156 int_bt_sco_rx_mixer_controls, ARRAY_SIZE(int_bt_sco_rx_mixer_controls)),
1157 SND_SOC_DAPM_MIXER("INTERNAL_FM_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1158 int_fm_rx_mixer_controls, ARRAY_SIZE(int_fm_rx_mixer_controls)),
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301159 SND_SOC_DAPM_MIXER("AFE_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1160 afe_pcm_rx_mixer_controls, ARRAY_SIZE(afe_pcm_rx_mixer_controls)),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001161 SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Port Mixer",
1162 SND_SOC_NOPM, 0, 0, sbus_0_rx_port_mixer_controls,
1163 ARRAY_SIZE(sbus_0_rx_port_mixer_controls)),
1164};
1165
1166static const struct snd_soc_dapm_route intercon[] = {
1167 {"PRI_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1168 {"PRI_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
1169 {"PRI_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301170 {"PRI_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001171 {"PRI_I2S_RX", NULL, "PRI_RX Audio Mixer"},
1172
1173 {"SLIMBUS_0_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1174 {"SLIMBUS_0_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
1175 {"SLIMBUS_0_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301176 {"SLIMBUS_0_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001177 {"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Audio Mixer"},
1178
1179 {"HDMI Mixer", "MultiMedia1", "MM_DL1"},
1180 {"HDMI Mixer", "MultiMedia2", "MM_DL2"},
Asish Bhattacharyac592eed2011-09-16 17:43:02 +05301181 {"HDMI Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301182 {"HDMI Mixer", "MultiMedia4", "MM_DL4"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001183 {"HDMI", NULL, "HDMI Mixer"},
1184
1185 {"MultiMedia1 Mixer", "PRI_TX", "PRI_I2S_TX"},
1186 {"MultiMedia1 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001187 {"MultiMedia1 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001188
1189 {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1190 {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
Asish Bhattacharyac592eed2011-09-16 17:43:02 +05301191 {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301192 {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001193 {"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX Audio Mixer"},
1194
1195 {"INTERNAL_FM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1196 {"INTERNAL_FM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
Asish Bhattacharyac592eed2011-09-16 17:43:02 +05301197 {"INTERNAL_FM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301198 {"INTERNAL_FM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001199 {"INT_FM_RX", NULL, "INTERNAL_FM_RX Audio Mixer"},
1200
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301201 {"AFE_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1202 {"AFE_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
1203 {"AFE_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301204 {"AFE_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301205 {"PCM_RX", NULL, "AFE_PCM_RX Audio Mixer"},
1206
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001207 {"MultiMedia1 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
1208 {"MultiMedia1 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301209
1210 {"MultiMedia1 Mixer", "AFE_PCM_TX", "PCM_TX"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001211 {"MM_UL1", NULL, "MultiMedia1 Mixer"},
Jayasena Sangaraboina99fee652011-09-19 07:43:13 -07001212 {"MultiMedia2 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
1213 {"MM_UL2", NULL, "MultiMedia2 Mixer"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001214
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001215 {"AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1216 {"AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
1217 {"AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301218 {"AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001219 {"AUX_PCM_RX", NULL, "AUX_PCM_RX Audio Mixer"},
1220
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001221 {"PRI_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1222 {"PRI_RX_Voice Mixer", "Voip", "VOIP_DL"},
1223 {"PRI_I2S_RX", NULL, "PRI_RX_Voice Mixer"},
1224
1225 {"SLIM_0_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1226 {"SLIM_0_RX_Voice Mixer", "Voip", "VOIP_DL"},
1227 {"SLIMBUS_0_RX", NULL, "SLIM_0_RX_Voice Mixer"},
1228
1229 {"INTERNAL_BT_SCO_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1230 {"INTERNAL_BT_SCO_RX_Voice Mixer", "Voip", "VOIP_DL"},
1231 {"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX_Voice Mixer"},
1232
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301233 {"AFE_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1234 {"AFE_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"},
1235 {"PCM_RX", NULL, "AFE_PCM_RX_Voice Mixer"},
1236
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001237 {"AUX_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1238 {"AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"},
1239 {"AUX_PCM_RX", NULL, "AUX_PCM_RX_Voice Mixer"},
1240
Alex Wong593576c2011-11-15 08:03:24 -08001241 {"HDMI_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1242 {"HDMI_RX_Voice Mixer", "Voip", "VOIP_DL"},
1243 {"HDMI", NULL, "HDMI_RX_Voice Mixer"},
1244
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001245 {"Voice_Tx Mixer", "PRI_TX_Voice", "PRI_I2S_TX"},
1246 {"Voice_Tx Mixer", "SLIM_0_TX_Voice", "SLIMBUS_0_TX"},
1247 {"Voice_Tx Mixer", "INTERNAL_BT_SCO_TX_Voice", "INT_BT_SCO_TX"},
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301248 {"Voice_Tx Mixer", "AFE_PCM_TX_Voice", "PCM_TX"},
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001249 {"Voice_Tx Mixer", "AUX_PCM_TX_Voice", "AUX_PCM_TX"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001250 {"CS-VOICE_UL1", NULL, "Voice_Tx Mixer"},
1251 {"Voip_Tx Mixer", "PRI_TX_Voip", "PRI_I2S_TX"},
1252 {"Voip_Tx Mixer", "SLIM_0_TX_Voip", "SLIMBUS_0_TX"},
1253 {"Voip_Tx Mixer", "INTERNAL_BT_SCO_TX_Voip", "INT_BT_SCO_TX"},
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301254 {"Voip_Tx Mixer", "AFE_PCM_TX_Voip", "PCM_TX"},
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001255 {"Voip_Tx Mixer", "AUX_PCM_TX_Voip", "AUX_PCM_TX"},
1256
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001257 {"VOIP_UL", NULL, "Voip_Tx Mixer"},
Sriranjan Srikantamdf509d12011-10-24 17:53:27 -07001258 {"SLIMBUS_DL_HL", "Switch", "SLIM0_DL_HL"},
1259 {"SLIMBUS_0_RX", NULL, "SLIMBUS_DL_HL"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001260 {"SLIM0_UL_HL", NULL, "SLIMBUS_0_TX"},
1261 {"INT_FM_RX", NULL, "INTFM_DL_HL"},
1262 {"INTFM_UL_HL", NULL, "INT_FM_TX"},
1263 {"SLIMBUS_0_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
1264 {"SLIMBUS_0_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
1265 {"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Port Mixer"},
1266};
1267
Patrick Laicf999112011-08-23 11:27:20 -07001268static int msm_pcm_routing_hw_params(struct snd_pcm_substream *substream,
1269 struct snd_pcm_hw_params *params)
1270{
1271 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1272 unsigned int be_id = rtd->dai_link->be_id;
1273
Patrick Lai770ca3e42011-12-12 13:44:54 -08001274 if (be_id >= MSM_BACKEND_DAI_MAX) {
1275 pr_err("%s: unexpected be_id %d\n", __func__, be_id);
1276 return -EINVAL;
1277 }
1278
Patrick Laicf999112011-08-23 11:27:20 -07001279 mutex_lock(&routing_lock);
1280 msm_bedais[be_id].hw_params = params;
1281 mutex_unlock(&routing_lock);
1282 return 0;
1283}
1284
1285static int msm_pcm_routing_close(struct snd_pcm_substream *substream)
1286{
1287 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1288 unsigned int be_id = rtd->dai_link->be_id;
1289 int i, session_type;
1290 struct msm_pcm_routing_bdai_data *bedai;
1291
1292 if (be_id >= MSM_BACKEND_DAI_MAX) {
1293 pr_err("%s: unexpected be_id %d\n", __func__, be_id);
1294 return -EINVAL;
1295 }
1296
1297 bedai = &msm_bedais[be_id];
1298
1299 session_type = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
1300 0 : 1);
1301
1302 mutex_lock(&routing_lock);
1303
Patrick Lai770ca3e42011-12-12 13:44:54 -08001304 for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MM_MAX_ID) {
Patrick Laicf999112011-08-23 11:27:20 -07001305 if (fe_dai_map[i][session_type] != INVALID_SESSION)
1306 adm_close(bedai->port_id);
1307 }
1308
1309 bedai->active = 0;
1310 bedai->hw_params = NULL;
1311
1312 mutex_unlock(&routing_lock);
1313
1314 return 0;
1315}
1316
1317static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream)
1318{
1319 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1320 unsigned int be_id = rtd->dai_link->be_id;
1321 int i, path_type, session_type;
1322 struct msm_pcm_routing_bdai_data *bedai;
1323
1324 if (be_id >= MSM_BACKEND_DAI_MAX) {
1325 pr_err("%s: unexpected be_id %d\n", __func__, be_id);
1326 return -EINVAL;
1327 }
1328
1329
1330 bedai = &msm_bedais[be_id];
1331
Jay Wangc8e03a82011-10-31 11:53:23 -07001332 if (bedai->hw_params == NULL) {
1333 pr_err("%s: HW param is not configured", __func__);
1334 return -EINVAL;
1335 }
1336
1337
Patrick Laicf999112011-08-23 11:27:20 -07001338 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1339 path_type = ADM_PATH_PLAYBACK;
1340 session_type = SESSION_TYPE_RX;
1341 } else {
1342 path_type = ADM_PATH_LIVE_REC;
1343 session_type = SESSION_TYPE_TX;
1344 }
1345
1346 mutex_lock(&routing_lock);
1347
1348 if (bedai->active == 1)
1349 goto done; /* Ignore prepare if back-end already active */
1350
1351 /* AFE port is not active at this point. However, still
1352 * go ahead setting active flag under the notion that
1353 * QDSP6 is able to handle ADM starting before AFE port
1354 * is started.
1355 */
1356 bedai->active = 1;
1357
Patrick Lai770ca3e42011-12-12 13:44:54 -08001358 for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MM_MAX_ID) {
Patrick Laicf999112011-08-23 11:27:20 -07001359 if (fe_dai_map[i][session_type] != INVALID_SESSION) {
1360 adm_open(bedai->port_id, path_type,
1361 params_rate(bedai->hw_params),
1362 params_channels(bedai->hw_params),
1363 DEFAULT_COPP_TOPOLOGY);
1364 msm_pcm_routing_build_matrix(i,
1365 fe_dai_map[i][session_type], path_type);
1366 }
1367 }
1368
1369done:
1370 mutex_unlock(&routing_lock);
1371
1372 return 0;
1373}
1374
1375static struct snd_pcm_ops msm_routing_pcm_ops = {
1376 .hw_params = msm_pcm_routing_hw_params,
1377 .close = msm_pcm_routing_close,
1378 .prepare = msm_pcm_routing_prepare,
1379};
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001380
1381static unsigned int msm_routing_read(struct snd_soc_platform *platform,
1382 unsigned int reg)
1383{
1384 dev_dbg(platform->dev, "reg %x\n", reg);
1385 return 0;
1386}
1387
1388/* Not used but frame seems to require it */
1389static int msm_routing_write(struct snd_soc_platform *platform,
1390 unsigned int reg, unsigned int val)
1391{
1392 dev_dbg(platform->dev, "reg %x val %x\n", reg, val);
1393 return 0;
1394}
1395
1396/* Not used but frame seems to require it */
1397static int msm_routing_probe(struct snd_soc_platform *platform)
1398{
1399 snd_soc_dapm_new_controls(&platform->dapm, msm_qdsp6_widgets,
1400 ARRAY_SIZE(msm_qdsp6_widgets));
1401 snd_soc_dapm_add_routes(&platform->dapm, intercon,
1402 ARRAY_SIZE(intercon));
1403
1404 snd_soc_dapm_new_widgets(&platform->dapm);
1405
Jayasena Sangaraboinacb1e22f2011-07-18 10:36:57 -07001406 snd_soc_add_platform_controls(platform,
1407 int_fm_vol_mixer_controls,
1408 ARRAY_SIZE(int_fm_vol_mixer_controls));
Asish Bhattacharya0ec76182011-07-29 16:58:11 +05301409
1410 snd_soc_add_platform_controls(platform,
1411 lpa_vol_mixer_controls,
1412 ARRAY_SIZE(lpa_vol_mixer_controls));
Ben Romberger037dd2f2011-09-22 14:01:32 -07001413
1414 snd_soc_add_platform_controls(platform,
1415 eq_enable_mixer_controls,
1416 ARRAY_SIZE(eq_enable_mixer_controls));
1417
1418 snd_soc_add_platform_controls(platform,
1419 eq_band_mixer_controls,
1420 ARRAY_SIZE(eq_band_mixer_controls));
1421
1422 snd_soc_add_platform_controls(platform,
1423 eq_coeff_mixer_controls,
1424 ARRAY_SIZE(eq_coeff_mixer_controls));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001425 return 0;
1426}
1427
1428static struct snd_soc_platform_driver msm_soc_routing_platform = {
1429 .ops = &msm_routing_pcm_ops,
1430 .probe = msm_routing_probe,
1431 .read = msm_routing_read,
1432 .write = msm_routing_write,
1433};
1434
1435static __devinit int msm_routing_pcm_probe(struct platform_device *pdev)
1436{
1437 dev_dbg(&pdev->dev, "dev name %s\n", dev_name(&pdev->dev));
1438 return snd_soc_register_platform(&pdev->dev,
1439 &msm_soc_routing_platform);
1440}
1441
1442static int msm_routing_pcm_remove(struct platform_device *pdev)
1443{
1444 snd_soc_unregister_platform(&pdev->dev);
1445 return 0;
1446}
1447
1448static struct platform_driver msm_routing_pcm_driver = {
1449 .driver = {
1450 .name = "msm-pcm-routing",
1451 .owner = THIS_MODULE,
1452 },
1453 .probe = msm_routing_pcm_probe,
1454 .remove = __devexit_p(msm_routing_pcm_remove),
1455};
1456
1457static int __init msm_soc_routing_platform_init(void)
1458{
Neema Shettyfeea7742011-09-11 12:30:36 -07001459 mutex_init(&routing_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001460 return platform_driver_register(&msm_routing_pcm_driver);
1461}
1462module_init(msm_soc_routing_platform_init);
1463
1464static void __exit msm_soc_routing_platform_exit(void)
1465{
1466 platform_driver_unregister(&msm_routing_pcm_driver);
1467}
1468module_exit(msm_soc_routing_platform_exit);
1469
1470MODULE_DESCRIPTION("MSM routing platform driver");
1471MODULE_LICENSE("GPL v2");