blob: 933e4a88dfa37b81f6984fd3ab6473bc44a0cb68 [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},
Neema Shettyfeea7742011-09-11 12:30:36 -0700118};
119
120
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700121/* Track ASM playback & capture sessions of DAI */
Patrick Lai770ca3e42011-12-12 13:44:54 -0800122static int fe_dai_map[MSM_FRONTEND_DAI_MM_SIZE][2] = {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700123 /* MULTIMEDIA1 */
124 {INVALID_SESSION, INVALID_SESSION},
125 /* MULTIMEDIA2 */
126 {INVALID_SESSION, INVALID_SESSION},
127 /* MULTIMEDIA3 */
128 {INVALID_SESSION, INVALID_SESSION},
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530129 /* MULTIMEDIA4 */
130 {INVALID_SESSION, INVALID_SESSION},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700131};
132
Patrick Laicf999112011-08-23 11:27:20 -0700133static void msm_pcm_routing_build_matrix(int fedai_id, int dspst_id,
134 int path_type)
135{
136 int i, port_type;
137 struct route_payload payload;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700138
Patrick Laicf999112011-08-23 11:27:20 -0700139 payload.num_copps = 0;
140 port_type = (path_type == ADM_PATH_PLAYBACK ?
141 MSM_AFE_PORT_TYPE_RX : MSM_AFE_PORT_TYPE_TX);
142
143 for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) {
144 if ((afe_get_port_type(msm_bedais[i].port_id) ==
145 port_type) &&
146 msm_bedais[i].active && (test_bit(fedai_id,
147 &msm_bedais[i].fe_sessions)))
148 payload.copp_ids[payload.num_copps++] =
149 msm_bedais[i].port_id;
150 }
151
152 if (payload.num_copps)
153 adm_matrix_map(dspst_id, path_type,
154 payload.num_copps, payload.copp_ids, 0);
155}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700156
157void msm_pcm_routing_reg_phy_stream(int fedai_id, int dspst_id, int stream_type)
158{
Patrick Laicf999112011-08-23 11:27:20 -0700159 int i, session_type, path_type, port_type;
160 struct route_payload payload;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700161
Patrick Lai770ca3e42011-12-12 13:44:54 -0800162 if (fedai_id > MSM_FRONTEND_DAI_MM_MAX_ID) {
163 /* bad ID assigned in machine driver */
164 pr_err("%s: bad MM ID\n", __func__);
165 return;
166 }
167
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700168 if (stream_type == SNDRV_PCM_STREAM_PLAYBACK) {
Patrick Laicf999112011-08-23 11:27:20 -0700169 session_type = SESSION_TYPE_RX;
170 path_type = ADM_PATH_PLAYBACK;
171 port_type = MSM_AFE_PORT_TYPE_RX;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700172 } else {
Patrick Laicf999112011-08-23 11:27:20 -0700173 session_type = SESSION_TYPE_TX;
174 path_type = ADM_PATH_LIVE_REC;
175 port_type = MSM_AFE_PORT_TYPE_TX;
176 }
177
178 mutex_lock(&routing_lock);
179
180 payload.num_copps = 0; /* only RX needs to use payload */
181 fe_dai_map[fedai_id][session_type] = dspst_id;
Ben Romberger037dd2f2011-09-22 14:01:32 -0700182 /* re-enable EQ if active */
183 if (eq_data[fedai_id].enable)
184 msm_send_eq_values(fedai_id);
Patrick Laicf999112011-08-23 11:27:20 -0700185 for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) {
186 if ((afe_get_port_type(msm_bedais[i].port_id) ==
187 port_type) && msm_bedais[i].active &&
188 (test_bit(fedai_id,
189 &msm_bedais[i].fe_sessions))) {
190 adm_open(msm_bedais[i].port_id,
191 path_type,
192 params_rate(msm_bedais[i].hw_params),
193 params_channels(msm_bedais[i].hw_params),
194 DEFAULT_COPP_TOPOLOGY);
195 payload.copp_ids[payload.num_copps++] =
196 msm_bedais[i].port_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700197 }
198 }
Patrick Laicf999112011-08-23 11:27:20 -0700199 if (payload.num_copps)
200 adm_matrix_map(dspst_id, path_type,
201 payload.num_copps, payload.copp_ids, 0);
202
203 mutex_unlock(&routing_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700204}
205
206void msm_pcm_routing_dereg_phy_stream(int fedai_id, int stream_type)
207{
Patrick Laicf999112011-08-23 11:27:20 -0700208 int i, port_type, session_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700209
Patrick Lai770ca3e42011-12-12 13:44:54 -0800210 if (fedai_id > MSM_FRONTEND_DAI_MM_MAX_ID) {
211 /* bad ID assigned in machine driver */
212 pr_err("%s: bad MM ID\n", __func__);
213 return;
214 }
215
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700216 if (stream_type == SNDRV_PCM_STREAM_PLAYBACK) {
Patrick Laicf999112011-08-23 11:27:20 -0700217 port_type = MSM_AFE_PORT_TYPE_RX;
218 session_type = SESSION_TYPE_RX;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700219 } else {
Patrick Laicf999112011-08-23 11:27:20 -0700220 port_type = MSM_AFE_PORT_TYPE_TX;
221 session_type = SESSION_TYPE_TX;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700222 }
Patrick Laicf999112011-08-23 11:27:20 -0700223
224 mutex_lock(&routing_lock);
225
226 for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) {
227 if ((afe_get_port_type(msm_bedais[i].port_id) ==
228 port_type) && msm_bedais[i].active &&
229 (test_bit(fedai_id,
230 &msm_bedais[i].fe_sessions)))
231 adm_close(msm_bedais[i].port_id);
232 }
233
234 fe_dai_map[fedai_id][session_type] = INVALID_SESSION;
235
236 mutex_unlock(&routing_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700237}
238
239static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set)
240{
Patrick Laicf999112011-08-23 11:27:20 -0700241 int session_type, path_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700242
243 pr_debug("%s: reg %x val %x set %x\n", __func__, reg, val, set);
244
Patrick Lai770ca3e42011-12-12 13:44:54 -0800245 if (val > MSM_FRONTEND_DAI_MM_MAX_ID) {
246 /* recheck FE ID in the mixer control defined in this file */
247 pr_err("%s: bad MM ID\n", __func__);
248 return;
249 }
250
Patrick Laicf999112011-08-23 11:27:20 -0700251 if (afe_get_port_type(msm_bedais[reg].port_id) ==
252 MSM_AFE_PORT_TYPE_RX) {
253 session_type = SESSION_TYPE_RX;
254 path_type = ADM_PATH_PLAYBACK;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700255 } else {
Patrick Laicf999112011-08-23 11:27:20 -0700256 session_type = SESSION_TYPE_TX;
257 path_type = ADM_PATH_LIVE_REC;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700258 }
Patrick Laicf999112011-08-23 11:27:20 -0700259
260 mutex_lock(&routing_lock);
261
262 if (set) {
Helen Zeng0705a5f2011-10-14 15:29:52 -0700263 if (!test_bit(val, &msm_bedais[reg].fe_sessions) &&
264 (msm_bedais[reg].port_id == VOICE_PLAYBACK_TX))
265 voc_start_playback(set);
266
Patrick Laicf999112011-08-23 11:27:20 -0700267 set_bit(val, &msm_bedais[reg].fe_sessions);
268 if (msm_bedais[reg].active && fe_dai_map[val][session_type] !=
269 INVALID_SESSION) {
270 adm_open(msm_bedais[reg].port_id, path_type,
271 params_rate(msm_bedais[reg].hw_params),
272 params_channels(msm_bedais[reg].hw_params),
273 DEFAULT_COPP_TOPOLOGY);
274 msm_pcm_routing_build_matrix(val,
275 fe_dai_map[val][session_type], path_type);
276 }
277 } else {
Helen Zeng0705a5f2011-10-14 15:29:52 -0700278 if (test_bit(val, &msm_bedais[reg].fe_sessions) &&
279 (msm_bedais[reg].port_id == VOICE_PLAYBACK_TX))
280 voc_start_playback(set);
Patrick Laicf999112011-08-23 11:27:20 -0700281 clear_bit(val, &msm_bedais[reg].fe_sessions);
282 if (msm_bedais[reg].active && fe_dai_map[val][session_type] !=
283 INVALID_SESSION) {
284 adm_close(msm_bedais[reg].port_id);
285 msm_pcm_routing_build_matrix(val,
286 fe_dai_map[val][session_type], path_type);
287 }
288 }
289
290 mutex_unlock(&routing_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700291}
292
293static int msm_routing_get_audio_mixer(struct snd_kcontrol *kcontrol,
294 struct snd_ctl_elem_value *ucontrol)
295{
296 struct soc_mixer_control *mc =
297 (struct soc_mixer_control *)kcontrol->private_value;
298
Patrick Laicf999112011-08-23 11:27:20 -0700299 if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700300 ucontrol->value.integer.value[0] = 1;
301 else
302 ucontrol->value.integer.value[0] = 0;
303
304 pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift,
305 ucontrol->value.integer.value[0]);
306
307 return 0;
308}
309
310static int msm_routing_put_audio_mixer(struct snd_kcontrol *kcontrol,
311 struct snd_ctl_elem_value *ucontrol)
312{
Patrick Laiec2b8942011-09-01 11:01:51 -0700313 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
314 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700315 struct soc_mixer_control *mc =
316 (struct soc_mixer_control *)kcontrol->private_value;
317
318
319 if (ucontrol->value.integer.value[0]) {
320 msm_pcm_routing_process_audio(mc->reg, mc->shift, 1);
321 snd_soc_dapm_mixer_update_power(widget, kcontrol, 1);
322 } else {
323 msm_pcm_routing_process_audio(mc->reg, mc->shift, 0);
324 snd_soc_dapm_mixer_update_power(widget, kcontrol, 0);
325 }
326
327 return 1;
328}
329
Neema Shettyfeea7742011-09-11 12:30:36 -0700330static void msm_pcm_routing_process_voice(u16 reg, u16 val, int set)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700331{
Neema Shetty2c07eb52011-08-21 20:33:52 -0700332 u16 session_id = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700333
Neema Shettyfeea7742011-09-11 12:30:36 -0700334 pr_debug("%s: reg %x val %x set %x\n", __func__, reg, val, set);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700335
Neema Shettyfeea7742011-09-11 12:30:36 -0700336 if (val == MSM_FRONTEND_DAI_CS_VOICE)
Neema Shetty2c07eb52011-08-21 20:33:52 -0700337 session_id = voc_get_session_id(VOICE_SESSION_NAME);
338 else
339 session_id = voc_get_session_id(VOIP_SESSION_NAME);
340
341 pr_debug("%s: FE DAI 0x%x session_id 0x%x\n",
Neema Shettyfeea7742011-09-11 12:30:36 -0700342 __func__, val, session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700343
Neema Shettyfeea7742011-09-11 12:30:36 -0700344 mutex_lock(&routing_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700345
346 if (set)
Neema Shettyfeea7742011-09-11 12:30:36 -0700347 set_bit(val, &msm_bedais[reg].fe_sessions);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700348 else
Neema Shettyfeea7742011-09-11 12:30:36 -0700349 clear_bit(val, &msm_bedais[reg].fe_sessions);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700350
Neema Shettyfeea7742011-09-11 12:30:36 -0700351 mutex_unlock(&routing_lock);
352
353 if (afe_get_port_type(msm_bedais[reg].port_id) ==
354 MSM_AFE_PORT_TYPE_RX) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700355 voc_set_route_flag(session_id, RX_PATH, set);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700356 if (set) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700357 voc_set_rxtx_port(session_id,
Neema Shettyfeea7742011-09-11 12:30:36 -0700358 msm_bedais[reg].port_id, DEV_RX);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700359
Neema Shetty2c07eb52011-08-21 20:33:52 -0700360 if (voc_get_route_flag(session_id, RX_PATH) &&
361 voc_get_route_flag(session_id, TX_PATH))
362 voc_enable_cvp(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700363 } else {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700364 voc_disable_cvp(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700365 }
366 } else {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700367 voc_set_route_flag(session_id, TX_PATH, set);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700368 if (set) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700369 voc_set_rxtx_port(session_id,
Neema Shettyfeea7742011-09-11 12:30:36 -0700370 msm_bedais[reg].port_id, DEV_TX);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700371 if (voc_get_route_flag(session_id, RX_PATH) &&
372 voc_get_route_flag(session_id, TX_PATH))
373 voc_enable_cvp(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700374 } else {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700375 voc_disable_cvp(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700376 }
377 }
378}
379
380static int msm_routing_get_voice_mixer(struct snd_kcontrol *kcontrol,
381 struct snd_ctl_elem_value *ucontrol)
382{
383 struct soc_mixer_control *mc =
384 (struct soc_mixer_control *)kcontrol->private_value;
385
Neema Shettyfeea7742011-09-11 12:30:36 -0700386 mutex_lock(&routing_lock);
387
388 if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700389 ucontrol->value.integer.value[0] = 1;
390 else
391 ucontrol->value.integer.value[0] = 0;
392
Neema Shettyfeea7742011-09-11 12:30:36 -0700393 mutex_unlock(&routing_lock);
394
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700395 pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift,
396 ucontrol->value.integer.value[0]);
397
398 return 0;
399}
400
401static int msm_routing_put_voice_mixer(struct snd_kcontrol *kcontrol,
402 struct snd_ctl_elem_value *ucontrol)
403{
Patrick Laiec2b8942011-09-01 11:01:51 -0700404 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
405 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700406 struct soc_mixer_control *mc =
407 (struct soc_mixer_control *)kcontrol->private_value;
408
409 if (ucontrol->value.integer.value[0]) {
Neema Shettyfeea7742011-09-11 12:30:36 -0700410 msm_pcm_routing_process_voice(mc->reg, mc->shift, 1);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700411 snd_soc_dapm_mixer_update_power(widget, kcontrol, 1);
412 } else {
Neema Shettyfeea7742011-09-11 12:30:36 -0700413 msm_pcm_routing_process_voice(mc->reg, mc->shift, 0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700414 snd_soc_dapm_mixer_update_power(widget, kcontrol, 0);
415 }
416
417 return 1;
418}
419
Sriranjan Srikantama4969dd2011-07-14 00:34:56 -0700420static int msm_routing_get_switch_mixer(struct snd_kcontrol *kcontrol,
421 struct snd_ctl_elem_value *ucontrol)
422{
423 ucontrol->value.integer.value[0] = fm_switch_enable;
424 pr_debug("%s: FM Switch enable %ld\n", __func__,
425 ucontrol->value.integer.value[0]);
426 return 0;
427}
428
429static int msm_routing_put_switch_mixer(struct snd_kcontrol *kcontrol,
430 struct snd_ctl_elem_value *ucontrol)
431{
Sriranjan Srikantamdf509d12011-10-24 17:53:27 -0700432 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
433 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
Sriranjan Srikantama4969dd2011-07-14 00:34:56 -0700434
435 pr_debug("%s: FM Switch enable %ld\n", __func__,
436 ucontrol->value.integer.value[0]);
437 if (ucontrol->value.integer.value[0])
438 snd_soc_dapm_mixer_update_power(widget, kcontrol, 1);
439 else
440 snd_soc_dapm_mixer_update_power(widget, kcontrol, 0);
441 fm_switch_enable = ucontrol->value.integer.value[0];
442 return 1;
443}
444
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700445static int msm_routing_get_port_mixer(struct snd_kcontrol *kcontrol,
446 struct snd_ctl_elem_value *ucontrol)
447{
448 struct soc_mixer_control *mc =
449 (struct soc_mixer_control *)kcontrol->private_value;
450
Patrick Laicf999112011-08-23 11:27:20 -0700451 if (test_bit(mc->shift, &msm_bedais[mc->reg].port_sessions))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700452 ucontrol->value.integer.value[0] = 1;
453 else
454 ucontrol->value.integer.value[0] = 0;
455
456 pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift,
457 ucontrol->value.integer.value[0]);
458
459 return 0;
460}
461
462static int msm_routing_put_port_mixer(struct snd_kcontrol *kcontrol,
463 struct snd_ctl_elem_value *ucontrol)
464{
465 struct soc_mixer_control *mc =
466 (struct soc_mixer_control *)kcontrol->private_value;
467
468 pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg,
469 mc->shift, ucontrol->value.integer.value[0]);
470
471 if (ucontrol->value.integer.value[0]) {
Patrick Laicf999112011-08-23 11:27:20 -0700472 afe_loopback(1, msm_bedais[mc->reg].port_id,
473 msm_bedais[mc->shift].port_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700474 set_bit(mc->shift,
Patrick Laicf999112011-08-23 11:27:20 -0700475 &msm_bedais[mc->reg].port_sessions);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700476 } else {
Patrick Laicf999112011-08-23 11:27:20 -0700477 afe_loopback(0, msm_bedais[mc->reg].port_id,
478 msm_bedais[mc->shift].port_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700479 clear_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 }
482
483 return 1;
484}
485
Jayasena Sangaraboinacb1e22f2011-07-18 10:36:57 -0700486static int msm_routing_get_fm_vol_mixer(struct snd_kcontrol *kcontrol,
487 struct snd_ctl_elem_value *ucontrol)
488{
489 ucontrol->value.integer.value[0] = msm_route_fm_vol_control;
490 return 0;
491}
492
493static int msm_routing_set_fm_vol_mixer(struct snd_kcontrol *kcontrol,
494 struct snd_ctl_elem_value *ucontrol)
495{
496 afe_loopback_gain(INT_FM_TX , ucontrol->value.integer.value[0]);
497
498 msm_route_fm_vol_control = ucontrol->value.integer.value[0];
499
500 return 0;
501}
502
Asish Bhattacharya0ec76182011-07-29 16:58:11 +0530503static int msm_routing_get_lpa_vol_mixer(struct snd_kcontrol *kcontrol,
504 struct snd_ctl_elem_value *ucontrol)
505{
506 ucontrol->value.integer.value[0] = msm_route_lpa_vol_control;
507 return 0;
508}
509
510static int msm_routing_set_lpa_vol_mixer(struct snd_kcontrol *kcontrol,
511 struct snd_ctl_elem_value *ucontrol)
512{
513 if (!lpa_set_volume(ucontrol->value.integer.value[0]))
514 msm_route_lpa_vol_control =
515 ucontrol->value.integer.value[0];
516
517 return 0;
518}
519
Ben Romberger037dd2f2011-09-22 14:01:32 -0700520static void msm_send_eq_values(int eq_idx)
521{
522 int result;
523 struct audio_client *ac =
524 q6asm_get_audio_client(fe_dai_map[eq_idx][SESSION_TYPE_RX]);
525
526 if (ac == NULL) {
527 pr_err("%s: Could not get audio client for session: %d\n",
528 __func__, fe_dai_map[eq_idx][SESSION_TYPE_RX]);
529 goto done;
530 }
531
532 result = q6asm_equalizer(ac, &eq_data[eq_idx]);
533
534 if (result < 0)
535 pr_err("%s: Call to ASM equalizer failed, returned = %d\n",
536 __func__, result);
537done:
538 return;
539}
540
541static int msm_routing_get_eq_enable_mixer(struct snd_kcontrol *kcontrol,
542 struct snd_ctl_elem_value *ucontrol)
543{
544 int eq_idx = ((struct soc_multi_mixer_control *)
545 kcontrol->private_value)->reg;
546
Ben Romberger76f57032011-12-08 20:07:34 -0800547 ucontrol->value.integer.value[0] = eq_data[eq_idx].enable;
548
Ben Romberger037dd2f2011-09-22 14:01:32 -0700549 pr_debug("%s: EQ #%d enable %d\n", __func__,
550 eq_idx, eq_data[eq_idx].enable);
Ben Romberger76f57032011-12-08 20:07:34 -0800551 return 0;
Ben Romberger037dd2f2011-09-22 14:01:32 -0700552}
553
554static int msm_routing_put_eq_enable_mixer(struct snd_kcontrol *kcontrol,
555 struct snd_ctl_elem_value *ucontrol)
556{
557 int eq_idx = ((struct soc_multi_mixer_control *)
558 kcontrol->private_value)->reg;
559 int value = ucontrol->value.integer.value[0];
560
561 pr_debug("%s: EQ #%d enable %d\n", __func__,
562 eq_idx, value);
563 eq_data[eq_idx].enable = value;
564
565 msm_send_eq_values(eq_idx);
566 return 0;
567}
568
569static int msm_routing_get_eq_band_count_audio_mixer(
570 struct snd_kcontrol *kcontrol,
571 struct snd_ctl_elem_value *ucontrol)
572{
573 int eq_idx = ((struct soc_multi_mixer_control *)
574 kcontrol->private_value)->reg;
575
Ben Romberger76f57032011-12-08 20:07:34 -0800576 ucontrol->value.integer.value[0] = eq_data[eq_idx].num_bands;
577
Ben Romberger037dd2f2011-09-22 14:01:32 -0700578 pr_debug("%s: EQ #%d bands %d\n", __func__,
579 eq_idx, eq_data[eq_idx].num_bands);
580 return eq_data[eq_idx].num_bands;
581}
582
583static int msm_routing_put_eq_band_count_audio_mixer(
584 struct snd_kcontrol *kcontrol,
585 struct snd_ctl_elem_value *ucontrol)
586{
587 int eq_idx = ((struct soc_multi_mixer_control *)
588 kcontrol->private_value)->reg;
589 int value = ucontrol->value.integer.value[0];
590
Ben Romberger037dd2f2011-09-22 14:01:32 -0700591 pr_debug("%s: EQ #%d bands %d\n", __func__,
592 eq_idx, value);
593 eq_data[eq_idx].num_bands = value;
594 return 0;
595}
596
597static int msm_routing_get_eq_band_audio_mixer(struct snd_kcontrol *kcontrol,
598 struct snd_ctl_elem_value *ucontrol)
599{
600 int eq_idx = ((struct soc_multi_mixer_control *)
601 kcontrol->private_value)->reg;
602 int band_idx = ((struct soc_multi_mixer_control *)
603 kcontrol->private_value)->shift;
604
Ben Romberger76f57032011-12-08 20:07:34 -0800605 ucontrol->value.integer.value[0] =
606 eq_data[eq_idx].eq_bands[band_idx].band_idx;
607 ucontrol->value.integer.value[1] =
608 eq_data[eq_idx].eq_bands[band_idx].filter_type;
609 ucontrol->value.integer.value[2] =
610 eq_data[eq_idx].eq_bands[band_idx].center_freq_hz;
611 ucontrol->value.integer.value[3] =
612 eq_data[eq_idx].eq_bands[band_idx].filter_gain;
613 ucontrol->value.integer.value[4] =
614 eq_data[eq_idx].eq_bands[band_idx].q_factor;
615
Ben Romberger037dd2f2011-09-22 14:01:32 -0700616 pr_debug("%s: band_idx = %d\n", __func__,
617 eq_data[eq_idx].eq_bands[band_idx].band_idx);
618 pr_debug("%s: filter_type = %d\n", __func__,
619 eq_data[eq_idx].eq_bands[band_idx].filter_type);
620 pr_debug("%s: center_freq_hz = %d\n", __func__,
621 eq_data[eq_idx].eq_bands[band_idx].center_freq_hz);
622 pr_debug("%s: filter_gain = %d\n", __func__,
623 eq_data[eq_idx].eq_bands[band_idx].filter_gain);
624 pr_debug("%s: q_factor = %d\n", __func__,
625 eq_data[eq_idx].eq_bands[band_idx].q_factor);
626 return 0;
627}
628
629static int msm_routing_put_eq_band_audio_mixer(struct snd_kcontrol *kcontrol,
630 struct snd_ctl_elem_value *ucontrol)
631{
632 int eq_idx = ((struct soc_multi_mixer_control *)
633 kcontrol->private_value)->reg;
634 int band_idx = ((struct soc_multi_mixer_control *)
635 kcontrol->private_value)->shift;
636
637 eq_data[eq_idx].eq_bands[band_idx].band_idx =
638 ucontrol->value.integer.value[0];
639 eq_data[eq_idx].eq_bands[band_idx].filter_type =
640 ucontrol->value.integer.value[1];
641 eq_data[eq_idx].eq_bands[band_idx].center_freq_hz =
642 ucontrol->value.integer.value[2];
643 eq_data[eq_idx].eq_bands[band_idx].filter_gain =
644 ucontrol->value.integer.value[3];
645 eq_data[eq_idx].eq_bands[band_idx].q_factor =
646 ucontrol->value.integer.value[4];
647 return 0;
648}
649
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700650static const struct snd_kcontrol_new pri_i2s_rx_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700651 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_PRI_I2S_RX ,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700652 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
653 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700654 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_PRI_I2S_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700655 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
656 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700657 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_PRI_I2S_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700658 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
659 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530660 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_PRI_I2S_RX,
661 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
662 msm_routing_put_audio_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700663};
664
665static const struct snd_kcontrol_new slimbus_rx_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700666 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SLIMBUS_0_RX ,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700667 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
668 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700669 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SLIMBUS_0_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700670 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
671 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700672 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SLIMBUS_0_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700673 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
674 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530675 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SLIMBUS_0_RX,
676 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
677 msm_routing_put_audio_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700678};
679
680static const struct snd_kcontrol_new hdmi_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700681 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_HDMI_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700682 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
683 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700684 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_HDMI_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700685 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
686 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700687 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_HDMI_RX,
Asish Bhattacharyac592eed2011-09-16 17:43:02 +0530688 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
689 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530690 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_HDMI_RX,
691 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
692 msm_routing_put_audio_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700693};
Helen Zeng0705a5f2011-10-14 15:29:52 -0700694 /* incall music delivery mixer */
695static const struct snd_kcontrol_new incall_music_delivery_mixer_controls[] = {
696 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_VOICE_PLAYBACK_TX,
697 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
698 msm_routing_put_audio_mixer),
699 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_VOICE_PLAYBACK_TX,
700 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
701 msm_routing_put_audio_mixer),
702};
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700703
704static const struct snd_kcontrol_new int_bt_sco_rx_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700705 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_INT_BT_SCO_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700706 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
707 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700708 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_INT_BT_SCO_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700709 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
710 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700711 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_INT_BT_SCO_RX,
Asish Bhattacharyac592eed2011-09-16 17:43:02 +0530712 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
713 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530714 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_INT_BT_SCO_RX,
715 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
716 msm_routing_put_audio_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700717};
718
719static const struct snd_kcontrol_new int_fm_rx_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700720 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_INT_FM_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700721 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
722 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700723 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_INT_FM_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700724 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
725 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700726 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_INT_FM_RX,
Asish Bhattacharyac592eed2011-09-16 17:43:02 +0530727 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
728 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530729 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_INT_FM_RX,
730 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
731 msm_routing_put_audio_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700732};
733
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530734static const struct snd_kcontrol_new afe_pcm_rx_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700735 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_AFE_PCM_RX,
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530736 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
737 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700738 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_AFE_PCM_RX,
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530739 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
740 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700741 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_AFE_PCM_RX,
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530742 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
743 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530744 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_AFE_PCM_RX,
745 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
746 msm_routing_put_audio_mixer),
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530747};
748
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700749static const struct snd_kcontrol_new auxpcm_rx_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700750 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_AUXPCM_RX,
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700751 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
752 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700753 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_AUXPCM_RX,
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700754 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
755 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700756 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_AUXPCM_RX,
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700757 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
758 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530759 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_AUXPCM_RX,
760 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
761 msm_routing_put_audio_mixer),
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700762};
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530763
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700764static const struct snd_kcontrol_new mmul1_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700765 SOC_SINGLE_EXT("PRI_TX", MSM_BACKEND_DAI_PRI_I2S_TX,
766 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
767 msm_routing_put_audio_mixer),
768 SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX,
769 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
770 msm_routing_put_audio_mixer),
771 SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_AUXPCM_TX,
772 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
773 msm_routing_put_audio_mixer),
774 SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX,
775 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
776 msm_routing_put_audio_mixer),
777 SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX,
778 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
779 msm_routing_put_audio_mixer),
780 SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX,
781 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
782 msm_routing_put_audio_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700783};
784
Jayasena Sangaraboina99fee652011-09-19 07:43:13 -0700785static const struct snd_kcontrol_new mmul2_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700786 SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX,
787 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
Jayasena Sangaraboina99fee652011-09-19 07:43:13 -0700788 msm_routing_put_audio_mixer),
789};
790
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700791static const struct snd_kcontrol_new pri_rx_voice_mixer_controls[] = {
Neema Shettyfeea7742011-09-11 12:30:36 -0700792 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_PRI_I2S_RX,
793 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
794 msm_routing_put_voice_mixer),
795 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_PRI_I2S_RX,
796 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
797 msm_routing_put_voice_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700798};
799
800static const struct snd_kcontrol_new slimbus_rx_voice_mixer_controls[] = {
Neema Shettyfeea7742011-09-11 12:30:36 -0700801 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_SLIMBUS_0_RX,
802 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
803 msm_routing_put_voice_mixer),
804 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SLIMBUS_0_RX ,
805 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
806 msm_routing_put_voice_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700807};
808
809static const struct snd_kcontrol_new bt_sco_rx_voice_mixer_controls[] = {
Neema Shettyfeea7742011-09-11 12:30:36 -0700810 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_INT_BT_SCO_RX,
811 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
812 msm_routing_put_voice_mixer),
813 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_INT_BT_SCO_RX ,
814 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
815 msm_routing_put_voice_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700816};
817
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530818static const struct snd_kcontrol_new afe_pcm_rx_voice_mixer_controls[] = {
819 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_AFE_PCM_RX,
820 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
821 msm_routing_put_voice_mixer),
822 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_AFE_PCM_RX,
823 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
824 msm_routing_put_voice_mixer),
825};
826
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700827static const struct snd_kcontrol_new aux_pcm_rx_voice_mixer_controls[] = {
828 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_AUXPCM_RX,
829 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
830 msm_routing_put_voice_mixer),
831 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_AUXPCM_RX,
832 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
833 msm_routing_put_voice_mixer),
834};
835
Alex Wong593576c2011-11-15 08:03:24 -0800836static const struct snd_kcontrol_new hdmi_rx_voice_mixer_controls[] = {
837 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_HDMI_RX,
838 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
839 msm_routing_put_voice_mixer),
840 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_HDMI_RX,
841 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
842 msm_routing_put_voice_mixer),
843};
844
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700845static const struct snd_kcontrol_new tx_voice_mixer_controls[] = {
Neema Shettyfeea7742011-09-11 12:30:36 -0700846 SOC_SINGLE_EXT("PRI_TX_Voice", MSM_BACKEND_DAI_PRI_I2S_TX,
847 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
848 msm_routing_put_voice_mixer),
849 SOC_SINGLE_EXT("SLIM_0_TX_Voice", MSM_BACKEND_DAI_SLIMBUS_0_TX,
850 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
851 msm_routing_put_voice_mixer),
852 SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_Voice",
853 MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_CS_VOICE, 1, 0,
Neema Shetty2c07eb52011-08-21 20:33:52 -0700854 msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530855 SOC_SINGLE_EXT("AFE_PCM_TX_Voice", MSM_BACKEND_DAI_AFE_PCM_TX,
856 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
857 msm_routing_put_voice_mixer),
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700858 SOC_SINGLE_EXT("AUX_PCM_TX_Voice", MSM_BACKEND_DAI_AUXPCM_TX,
859 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
860 msm_routing_put_voice_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700861};
862
863static const struct snd_kcontrol_new tx_voip_mixer_controls[] = {
Neema Shettyfeea7742011-09-11 12:30:36 -0700864 SOC_SINGLE_EXT("PRI_TX_Voip", MSM_BACKEND_DAI_PRI_I2S_TX,
865 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
866 msm_routing_put_voice_mixer),
867 SOC_SINGLE_EXT("SLIM_0_TX_Voip", MSM_BACKEND_DAI_SLIMBUS_0_TX,
868 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
869 msm_routing_put_voice_mixer),
870 SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_Voip", MSM_BACKEND_DAI_INT_BT_SCO_TX,
871 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
872 msm_routing_put_voice_mixer),
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530873 SOC_SINGLE_EXT("AFE_PCM_TX_Voip", MSM_BACKEND_DAI_AFE_PCM_TX,
874 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
875 msm_routing_put_voice_mixer),
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700876 SOC_SINGLE_EXT("AUX_PCM_TX_Voip", MSM_BACKEND_DAI_AUXPCM_TX,
877 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
878 msm_routing_put_voice_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700879};
880
881static const struct snd_kcontrol_new sbus_0_rx_port_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700882 SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700883 MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer,
884 msm_routing_put_port_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700885 SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700886 MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer,
887 msm_routing_put_port_mixer),
888};
889
Sriranjan Srikantama4969dd2011-07-14 00:34:56 -0700890static const struct snd_kcontrol_new fm_switch_mixer_controls =
891 SOC_SINGLE_EXT("Switch", SND_SOC_NOPM,
892 0, 1, 0, msm_routing_get_switch_mixer,
893 msm_routing_put_switch_mixer);
894
Jayasena Sangaraboinacb1e22f2011-07-18 10:36:57 -0700895static const struct snd_kcontrol_new int_fm_vol_mixer_controls[] = {
896 SOC_SINGLE_EXT_TLV("Internal FM RX Volume", SND_SOC_NOPM, 0,
897 INT_FM_RX_VOL_GAIN, 0, msm_routing_get_fm_vol_mixer,
898 msm_routing_set_fm_vol_mixer, fm_rx_vol_gain),
899};
900
Asish Bhattacharya0ec76182011-07-29 16:58:11 +0530901static const struct snd_kcontrol_new lpa_vol_mixer_controls[] = {
902 SOC_SINGLE_EXT_TLV("LPA RX Volume", SND_SOC_NOPM, 0,
903 INT_LPA_RX_VOL_GAIN, 0, msm_routing_get_lpa_vol_mixer,
904 msm_routing_set_lpa_vol_mixer, lpa_rx_vol_gain),
905};
906
Ben Romberger037dd2f2011-09-22 14:01:32 -0700907static const struct snd_kcontrol_new eq_enable_mixer_controls[] = {
908 SOC_SINGLE_EXT("MultiMedia1 EQ Enable", SND_SOC_NOPM,
909 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_eq_enable_mixer,
910 msm_routing_put_eq_enable_mixer),
911 SOC_SINGLE_EXT("MultiMedia2 EQ Enable", SND_SOC_NOPM,
912 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_eq_enable_mixer,
913 msm_routing_put_eq_enable_mixer),
914 SOC_SINGLE_EXT("MultiMedia3 EQ Enable", SND_SOC_NOPM,
915 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_eq_enable_mixer,
916 msm_routing_put_eq_enable_mixer),
917};
918
919static const struct snd_kcontrol_new eq_band_mixer_controls[] = {
920 SOC_SINGLE_EXT("MultiMedia1 EQ Band Count", SND_SOC_NOPM,
921 MSM_FRONTEND_DAI_MULTIMEDIA1, 11, 0,
922 msm_routing_get_eq_band_count_audio_mixer,
923 msm_routing_put_eq_band_count_audio_mixer),
924 SOC_SINGLE_EXT("MultiMedia2 EQ Band Count", SND_SOC_NOPM,
925 MSM_FRONTEND_DAI_MULTIMEDIA2, 11, 0,
926 msm_routing_get_eq_band_count_audio_mixer,
927 msm_routing_put_eq_band_count_audio_mixer),
928 SOC_SINGLE_EXT("MultiMedia3 EQ Band Count", SND_SOC_NOPM,
929 MSM_FRONTEND_DAI_MULTIMEDIA3, 11, 0,
930 msm_routing_get_eq_band_count_audio_mixer,
931 msm_routing_put_eq_band_count_audio_mixer),
932};
933
934static const struct snd_kcontrol_new eq_coeff_mixer_controls[] = {
935 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band1", EQ_BAND1,
936 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
937 msm_routing_get_eq_band_audio_mixer,
938 msm_routing_put_eq_band_audio_mixer),
939 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band2", EQ_BAND2,
940 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
941 msm_routing_get_eq_band_audio_mixer,
942 msm_routing_put_eq_band_audio_mixer),
943 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band3", EQ_BAND3,
944 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
945 msm_routing_get_eq_band_audio_mixer,
946 msm_routing_put_eq_band_audio_mixer),
947 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band4", EQ_BAND4,
948 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
949 msm_routing_get_eq_band_audio_mixer,
950 msm_routing_put_eq_band_audio_mixer),
951 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band5", EQ_BAND5,
952 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
953 msm_routing_get_eq_band_audio_mixer,
954 msm_routing_put_eq_band_audio_mixer),
955 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band6", EQ_BAND6,
956 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
957 msm_routing_get_eq_band_audio_mixer,
958 msm_routing_put_eq_band_audio_mixer),
959 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band7", EQ_BAND7,
960 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
961 msm_routing_get_eq_band_audio_mixer,
962 msm_routing_put_eq_band_audio_mixer),
963 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band8", EQ_BAND8,
964 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
965 msm_routing_get_eq_band_audio_mixer,
966 msm_routing_put_eq_band_audio_mixer),
967 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band9", EQ_BAND9,
968 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
969 msm_routing_get_eq_band_audio_mixer,
970 msm_routing_put_eq_band_audio_mixer),
971 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band10", EQ_BAND10,
972 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
973 msm_routing_get_eq_band_audio_mixer,
974 msm_routing_put_eq_band_audio_mixer),
975 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band11", EQ_BAND11,
976 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
977 msm_routing_get_eq_band_audio_mixer,
978 msm_routing_put_eq_band_audio_mixer),
979 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band12", EQ_BAND12,
980 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
981 msm_routing_get_eq_band_audio_mixer,
982 msm_routing_put_eq_band_audio_mixer),
983 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band1", EQ_BAND1,
984 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
985 msm_routing_get_eq_band_audio_mixer,
986 msm_routing_put_eq_band_audio_mixer),
987 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band2", EQ_BAND2,
988 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
989 msm_routing_get_eq_band_audio_mixer,
990 msm_routing_put_eq_band_audio_mixer),
991 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band3", EQ_BAND3,
992 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
993 msm_routing_get_eq_band_audio_mixer,
994 msm_routing_put_eq_band_audio_mixer),
995 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band4", EQ_BAND4,
996 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
997 msm_routing_get_eq_band_audio_mixer,
998 msm_routing_put_eq_band_audio_mixer),
999 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band5", EQ_BAND5,
1000 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1001 msm_routing_get_eq_band_audio_mixer,
1002 msm_routing_put_eq_band_audio_mixer),
1003 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band6", EQ_BAND6,
1004 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1005 msm_routing_get_eq_band_audio_mixer,
1006 msm_routing_put_eq_band_audio_mixer),
1007 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band7", EQ_BAND7,
1008 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1009 msm_routing_get_eq_band_audio_mixer,
1010 msm_routing_put_eq_band_audio_mixer),
1011 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band8", EQ_BAND8,
1012 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1013 msm_routing_get_eq_band_audio_mixer,
1014 msm_routing_put_eq_band_audio_mixer),
1015 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band9", EQ_BAND9,
1016 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1017 msm_routing_get_eq_band_audio_mixer,
1018 msm_routing_put_eq_band_audio_mixer),
1019 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band10", EQ_BAND10,
1020 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1021 msm_routing_get_eq_band_audio_mixer,
1022 msm_routing_put_eq_band_audio_mixer),
1023 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band11", EQ_BAND11,
1024 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1025 msm_routing_get_eq_band_audio_mixer,
1026 msm_routing_put_eq_band_audio_mixer),
1027 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band12", EQ_BAND12,
1028 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1029 msm_routing_get_eq_band_audio_mixer,
1030 msm_routing_put_eq_band_audio_mixer),
1031 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band1", EQ_BAND1,
1032 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1033 msm_routing_get_eq_band_audio_mixer,
1034 msm_routing_put_eq_band_audio_mixer),
1035 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band2", EQ_BAND2,
1036 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1037 msm_routing_get_eq_band_audio_mixer,
1038 msm_routing_put_eq_band_audio_mixer),
1039 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band3", EQ_BAND3,
1040 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1041 msm_routing_get_eq_band_audio_mixer,
1042 msm_routing_put_eq_band_audio_mixer),
1043 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band4", EQ_BAND4,
1044 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1045 msm_routing_get_eq_band_audio_mixer,
1046 msm_routing_put_eq_band_audio_mixer),
1047 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band5", EQ_BAND5,
1048 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1049 msm_routing_get_eq_band_audio_mixer,
1050 msm_routing_put_eq_band_audio_mixer),
1051 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band6", EQ_BAND6,
1052 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1053 msm_routing_get_eq_band_audio_mixer,
1054 msm_routing_put_eq_band_audio_mixer),
1055 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band7", EQ_BAND7,
1056 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1057 msm_routing_get_eq_band_audio_mixer,
1058 msm_routing_put_eq_band_audio_mixer),
1059 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band8", EQ_BAND8,
1060 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1061 msm_routing_get_eq_band_audio_mixer,
1062 msm_routing_put_eq_band_audio_mixer),
1063 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band9", EQ_BAND9,
1064 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1065 msm_routing_get_eq_band_audio_mixer,
1066 msm_routing_put_eq_band_audio_mixer),
1067 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band10", EQ_BAND10,
1068 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1069 msm_routing_get_eq_band_audio_mixer,
1070 msm_routing_put_eq_band_audio_mixer),
1071 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band11", EQ_BAND11,
1072 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1073 msm_routing_get_eq_band_audio_mixer,
1074 msm_routing_put_eq_band_audio_mixer),
1075 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band12", EQ_BAND12,
1076 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1077 msm_routing_get_eq_band_audio_mixer,
1078 msm_routing_put_eq_band_audio_mixer),
1079};
1080
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001081static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
1082 /* Frontend AIF */
1083 /* Widget name equals to Front-End DAI name<Need confirmation>,
1084 * Stream name must contains substring of front-end dai name
1085 */
1086 SND_SOC_DAPM_AIF_IN("MM_DL1", "MultiMedia1 Playback", 0, 0, 0, 0),
1087 SND_SOC_DAPM_AIF_IN("MM_DL2", "MultiMedia2 Playback", 0, 0, 0, 0),
1088 SND_SOC_DAPM_AIF_IN("MM_DL3", "MultiMedia3 Playback", 0, 0, 0, 0),
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301089 SND_SOC_DAPM_AIF_IN("MM_DL4", "MultiMedia4 Playback", 0, 0, 0, 0),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001090 SND_SOC_DAPM_AIF_IN("VOIP_DL", "VoIP Playback", 0, 0, 0, 0),
1091 SND_SOC_DAPM_AIF_OUT("MM_UL1", "MultiMedia1 Capture", 0, 0, 0, 0),
Jayasena Sangaraboina99fee652011-09-19 07:43:13 -07001092 SND_SOC_DAPM_AIF_OUT("MM_UL2", "MultiMedia2 Capture", 0, 0, 0, 0),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001093 SND_SOC_DAPM_AIF_IN("CS-VOICE_DL1", "CS-VOICE Playback", 0, 0, 0, 0),
1094 SND_SOC_DAPM_AIF_OUT("CS-VOICE_UL1", "CS-VOICE Capture", 0, 0, 0, 0),
1095 SND_SOC_DAPM_AIF_OUT("VOIP_UL", "VoIP Capture", 0, 0, 0, 0),
1096 SND_SOC_DAPM_AIF_IN("SLIM0_DL_HL", "SLIMBUS0_HOSTLESS Playback",
1097 0, 0, 0, 0),
1098 SND_SOC_DAPM_AIF_OUT("SLIM0_UL_HL", "SLIMBUS0_HOSTLESS Capture",
1099 0, 0, 0, 0),
1100 SND_SOC_DAPM_AIF_IN("INTFM_DL_HL", "INT_FM_HOSTLESS Playback",
1101 0, 0, 0, 0),
1102 SND_SOC_DAPM_AIF_OUT("INTFM_UL_HL", "INT_FM_HOSTLESS Capture",
1103 0, 0, 0, 0),
1104 /* Backend AIF */
1105 /* Stream name equals to backend dai link stream name
1106 */
1107 SND_SOC_DAPM_AIF_OUT("PRI_I2S_RX", "Primary I2S Playback", 0, 0, 0, 0),
1108 SND_SOC_DAPM_AIF_OUT("SLIMBUS_0_RX", "Slimbus Playback", 0, 0, 0, 0),
1109 SND_SOC_DAPM_AIF_OUT("HDMI", "HDMI Playback", 0, 0, 0 , 0),
1110 SND_SOC_DAPM_AIF_IN("PRI_I2S_TX", "Primary I2S Capture", 0, 0, 0, 0),
1111 SND_SOC_DAPM_AIF_IN("SLIMBUS_0_TX", "Slimbus Capture", 0, 0, 0, 0),
1112 SND_SOC_DAPM_AIF_OUT("INT_BT_SCO_RX", "Internal BT-SCO Playback",
1113 0, 0, 0 , 0),
1114 SND_SOC_DAPM_AIF_IN("INT_BT_SCO_TX", "Internal BT-SCO Capture",
1115 0, 0, 0, 0),
1116 SND_SOC_DAPM_AIF_OUT("INT_FM_RX", "Internal FM Playback",
1117 0, 0, 0 , 0),
1118 SND_SOC_DAPM_AIF_IN("INT_FM_TX", "Internal FM Capture",
1119 0, 0, 0, 0),
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301120 SND_SOC_DAPM_AIF_OUT("PCM_RX", "AFE Playback",
1121 0, 0, 0 , 0),
1122 SND_SOC_DAPM_AIF_IN("PCM_TX", "AFE Capture",
Helen Zeng0705a5f2011-10-14 15:29:52 -07001123 0, 0, 0 , 0),
1124 /* incall */
1125 SND_SOC_DAPM_AIF_OUT("VOICE_PLAYBACK_TX", "Voice Farend Playback",
1126 0, 0, 0 , 0),
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001127 SND_SOC_DAPM_AIF_OUT("AUX_PCM_RX", "AUX PCM Playback", 0, 0, 0, 0),
1128 SND_SOC_DAPM_AIF_IN("AUX_PCM_TX", "AUX PCM Capture", 0, 0, 0, 0),
Sriranjan Srikantama4969dd2011-07-14 00:34:56 -07001129 /* Switch Definitions */
Sriranjan Srikantamdf509d12011-10-24 17:53:27 -07001130 SND_SOC_DAPM_SWITCH("SLIMBUS_DL_HL", SND_SOC_NOPM, 0, 0,
Sriranjan Srikantama4969dd2011-07-14 00:34:56 -07001131 &fm_switch_mixer_controls),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001132 /* Mixer definitions */
1133 SND_SOC_DAPM_MIXER("PRI_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1134 pri_i2s_rx_mixer_controls, ARRAY_SIZE(pri_i2s_rx_mixer_controls)),
1135 SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1136 slimbus_rx_mixer_controls, ARRAY_SIZE(slimbus_rx_mixer_controls)),
1137 SND_SOC_DAPM_MIXER("HDMI Mixer", SND_SOC_NOPM, 0, 0,
1138 hdmi_mixer_controls, ARRAY_SIZE(hdmi_mixer_controls)),
1139 SND_SOC_DAPM_MIXER("MultiMedia1 Mixer", SND_SOC_NOPM, 0, 0,
1140 mmul1_mixer_controls, ARRAY_SIZE(mmul1_mixer_controls)),
Jayasena Sangaraboina99fee652011-09-19 07:43:13 -07001141 SND_SOC_DAPM_MIXER("MultiMedia2 Mixer", SND_SOC_NOPM, 0, 0,
1142 mmul2_mixer_controls, ARRAY_SIZE(mmul2_mixer_controls)),
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001143 SND_SOC_DAPM_MIXER("AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1144 auxpcm_rx_mixer_controls, ARRAY_SIZE(auxpcm_rx_mixer_controls)),
Helen Zeng0705a5f2011-10-14 15:29:52 -07001145 /* incall */
1146 SND_SOC_DAPM_MIXER("Incall_Music Audio Mixer", SND_SOC_NOPM, 0, 0,
1147 incall_music_delivery_mixer_controls,
1148 ARRAY_SIZE(incall_music_delivery_mixer_controls)),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001149 /* Voice Mixer */
1150 SND_SOC_DAPM_MIXER("PRI_RX_Voice Mixer",
1151 SND_SOC_NOPM, 0, 0, pri_rx_voice_mixer_controls,
1152 ARRAY_SIZE(pri_rx_voice_mixer_controls)),
1153 SND_SOC_DAPM_MIXER("SLIM_0_RX_Voice Mixer",
1154 SND_SOC_NOPM, 0, 0,
1155 slimbus_rx_voice_mixer_controls,
1156 ARRAY_SIZE(slimbus_rx_voice_mixer_controls)),
1157 SND_SOC_DAPM_MIXER("INTERNAL_BT_SCO_RX_Voice Mixer",
1158 SND_SOC_NOPM, 0, 0,
1159 bt_sco_rx_voice_mixer_controls,
1160 ARRAY_SIZE(bt_sco_rx_voice_mixer_controls)),
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301161 SND_SOC_DAPM_MIXER("AFE_PCM_RX_Voice Mixer",
1162 SND_SOC_NOPM, 0, 0,
1163 afe_pcm_rx_voice_mixer_controls,
1164 ARRAY_SIZE(afe_pcm_rx_voice_mixer_controls)),
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001165 SND_SOC_DAPM_MIXER("AUX_PCM_RX_Voice Mixer",
1166 SND_SOC_NOPM, 0, 0,
1167 aux_pcm_rx_voice_mixer_controls,
1168 ARRAY_SIZE(aux_pcm_rx_voice_mixer_controls)),
Alex Wong593576c2011-11-15 08:03:24 -08001169 SND_SOC_DAPM_MIXER("HDMI_RX_Voice Mixer",
1170 SND_SOC_NOPM, 0, 0,
1171 hdmi_rx_voice_mixer_controls,
1172 ARRAY_SIZE(hdmi_rx_voice_mixer_controls)),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001173 SND_SOC_DAPM_MIXER("Voice_Tx Mixer",
1174 SND_SOC_NOPM, 0, 0, tx_voice_mixer_controls,
1175 ARRAY_SIZE(tx_voice_mixer_controls)),
1176 SND_SOC_DAPM_MIXER("Voip_Tx Mixer",
1177 SND_SOC_NOPM, 0, 0, tx_voip_mixer_controls,
1178 ARRAY_SIZE(tx_voip_mixer_controls)),
1179 SND_SOC_DAPM_MIXER("INTERNAL_BT_SCO_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1180 int_bt_sco_rx_mixer_controls, ARRAY_SIZE(int_bt_sco_rx_mixer_controls)),
1181 SND_SOC_DAPM_MIXER("INTERNAL_FM_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1182 int_fm_rx_mixer_controls, ARRAY_SIZE(int_fm_rx_mixer_controls)),
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301183 SND_SOC_DAPM_MIXER("AFE_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1184 afe_pcm_rx_mixer_controls, ARRAY_SIZE(afe_pcm_rx_mixer_controls)),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001185 SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Port Mixer",
1186 SND_SOC_NOPM, 0, 0, sbus_0_rx_port_mixer_controls,
1187 ARRAY_SIZE(sbus_0_rx_port_mixer_controls)),
1188};
1189
1190static const struct snd_soc_dapm_route intercon[] = {
1191 {"PRI_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1192 {"PRI_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
1193 {"PRI_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301194 {"PRI_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001195 {"PRI_I2S_RX", NULL, "PRI_RX Audio Mixer"},
1196
1197 {"SLIMBUS_0_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1198 {"SLIMBUS_0_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
1199 {"SLIMBUS_0_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301200 {"SLIMBUS_0_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001201 {"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Audio Mixer"},
1202
1203 {"HDMI Mixer", "MultiMedia1", "MM_DL1"},
1204 {"HDMI Mixer", "MultiMedia2", "MM_DL2"},
Asish Bhattacharyac592eed2011-09-16 17:43:02 +05301205 {"HDMI Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301206 {"HDMI Mixer", "MultiMedia4", "MM_DL4"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001207 {"HDMI", NULL, "HDMI Mixer"},
1208
Helen Zeng0705a5f2011-10-14 15:29:52 -07001209 /* incall */
1210 {"Incall_Music Audio Mixer", "MultiMedia1", "MM_DL1"},
1211 {"Incall_Music Audio Mixer", "MultiMedia2", "MM_DL2"},
1212 {"VOICE_PLAYBACK_TX", NULL, "Incall_Music Audio Mixer"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001213 {"MultiMedia1 Mixer", "PRI_TX", "PRI_I2S_TX"},
1214 {"MultiMedia1 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001215 {"MultiMedia1 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001216
1217 {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1218 {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
Asish Bhattacharyac592eed2011-09-16 17:43:02 +05301219 {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301220 {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001221 {"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX Audio Mixer"},
1222
1223 {"INTERNAL_FM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1224 {"INTERNAL_FM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
Asish Bhattacharyac592eed2011-09-16 17:43:02 +05301225 {"INTERNAL_FM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301226 {"INTERNAL_FM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001227 {"INT_FM_RX", NULL, "INTERNAL_FM_RX Audio Mixer"},
1228
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301229 {"AFE_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1230 {"AFE_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
1231 {"AFE_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301232 {"AFE_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301233 {"PCM_RX", NULL, "AFE_PCM_RX Audio Mixer"},
1234
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001235 {"MultiMedia1 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
1236 {"MultiMedia1 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301237
1238 {"MultiMedia1 Mixer", "AFE_PCM_TX", "PCM_TX"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001239 {"MM_UL1", NULL, "MultiMedia1 Mixer"},
Jayasena Sangaraboina99fee652011-09-19 07:43:13 -07001240 {"MultiMedia2 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
1241 {"MM_UL2", NULL, "MultiMedia2 Mixer"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001242
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001243 {"AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1244 {"AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
1245 {"AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301246 {"AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001247 {"AUX_PCM_RX", NULL, "AUX_PCM_RX Audio Mixer"},
1248
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001249 {"PRI_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1250 {"PRI_RX_Voice Mixer", "Voip", "VOIP_DL"},
1251 {"PRI_I2S_RX", NULL, "PRI_RX_Voice Mixer"},
1252
1253 {"SLIM_0_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1254 {"SLIM_0_RX_Voice Mixer", "Voip", "VOIP_DL"},
1255 {"SLIMBUS_0_RX", NULL, "SLIM_0_RX_Voice Mixer"},
1256
1257 {"INTERNAL_BT_SCO_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1258 {"INTERNAL_BT_SCO_RX_Voice Mixer", "Voip", "VOIP_DL"},
1259 {"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX_Voice Mixer"},
1260
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301261 {"AFE_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1262 {"AFE_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"},
1263 {"PCM_RX", NULL, "AFE_PCM_RX_Voice Mixer"},
1264
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001265 {"AUX_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1266 {"AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"},
1267 {"AUX_PCM_RX", NULL, "AUX_PCM_RX_Voice Mixer"},
1268
Alex Wong593576c2011-11-15 08:03:24 -08001269 {"HDMI_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1270 {"HDMI_RX_Voice Mixer", "Voip", "VOIP_DL"},
1271 {"HDMI", NULL, "HDMI_RX_Voice Mixer"},
1272
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001273 {"Voice_Tx Mixer", "PRI_TX_Voice", "PRI_I2S_TX"},
1274 {"Voice_Tx Mixer", "SLIM_0_TX_Voice", "SLIMBUS_0_TX"},
1275 {"Voice_Tx Mixer", "INTERNAL_BT_SCO_TX_Voice", "INT_BT_SCO_TX"},
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301276 {"Voice_Tx Mixer", "AFE_PCM_TX_Voice", "PCM_TX"},
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001277 {"Voice_Tx Mixer", "AUX_PCM_TX_Voice", "AUX_PCM_TX"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001278 {"CS-VOICE_UL1", NULL, "Voice_Tx Mixer"},
1279 {"Voip_Tx Mixer", "PRI_TX_Voip", "PRI_I2S_TX"},
1280 {"Voip_Tx Mixer", "SLIM_0_TX_Voip", "SLIMBUS_0_TX"},
1281 {"Voip_Tx Mixer", "INTERNAL_BT_SCO_TX_Voip", "INT_BT_SCO_TX"},
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301282 {"Voip_Tx Mixer", "AFE_PCM_TX_Voip", "PCM_TX"},
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001283 {"Voip_Tx Mixer", "AUX_PCM_TX_Voip", "AUX_PCM_TX"},
1284
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001285 {"VOIP_UL", NULL, "Voip_Tx Mixer"},
Sriranjan Srikantamdf509d12011-10-24 17:53:27 -07001286 {"SLIMBUS_DL_HL", "Switch", "SLIM0_DL_HL"},
1287 {"SLIMBUS_0_RX", NULL, "SLIMBUS_DL_HL"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001288 {"SLIM0_UL_HL", NULL, "SLIMBUS_0_TX"},
1289 {"INT_FM_RX", NULL, "INTFM_DL_HL"},
1290 {"INTFM_UL_HL", NULL, "INT_FM_TX"},
1291 {"SLIMBUS_0_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
1292 {"SLIMBUS_0_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
1293 {"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Port Mixer"},
1294};
1295
Patrick Laicf999112011-08-23 11:27:20 -07001296static int msm_pcm_routing_hw_params(struct snd_pcm_substream *substream,
1297 struct snd_pcm_hw_params *params)
1298{
1299 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1300 unsigned int be_id = rtd->dai_link->be_id;
1301
Patrick Lai770ca3e42011-12-12 13:44:54 -08001302 if (be_id >= MSM_BACKEND_DAI_MAX) {
1303 pr_err("%s: unexpected be_id %d\n", __func__, be_id);
1304 return -EINVAL;
1305 }
1306
Patrick Laicf999112011-08-23 11:27:20 -07001307 mutex_lock(&routing_lock);
1308 msm_bedais[be_id].hw_params = params;
1309 mutex_unlock(&routing_lock);
1310 return 0;
1311}
1312
1313static int msm_pcm_routing_close(struct snd_pcm_substream *substream)
1314{
1315 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1316 unsigned int be_id = rtd->dai_link->be_id;
1317 int i, session_type;
1318 struct msm_pcm_routing_bdai_data *bedai;
1319
1320 if (be_id >= MSM_BACKEND_DAI_MAX) {
1321 pr_err("%s: unexpected be_id %d\n", __func__, be_id);
1322 return -EINVAL;
1323 }
1324
1325 bedai = &msm_bedais[be_id];
1326
1327 session_type = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
1328 0 : 1);
1329
1330 mutex_lock(&routing_lock);
1331
Patrick Lai770ca3e42011-12-12 13:44:54 -08001332 for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MM_MAX_ID) {
Patrick Laicf999112011-08-23 11:27:20 -07001333 if (fe_dai_map[i][session_type] != INVALID_SESSION)
1334 adm_close(bedai->port_id);
1335 }
1336
1337 bedai->active = 0;
1338 bedai->hw_params = NULL;
1339
1340 mutex_unlock(&routing_lock);
1341
1342 return 0;
1343}
1344
1345static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream)
1346{
1347 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1348 unsigned int be_id = rtd->dai_link->be_id;
1349 int i, path_type, session_type;
1350 struct msm_pcm_routing_bdai_data *bedai;
1351
1352 if (be_id >= MSM_BACKEND_DAI_MAX) {
1353 pr_err("%s: unexpected be_id %d\n", __func__, be_id);
1354 return -EINVAL;
1355 }
1356
1357
1358 bedai = &msm_bedais[be_id];
1359
Jay Wangc8e03a82011-10-31 11:53:23 -07001360 if (bedai->hw_params == NULL) {
1361 pr_err("%s: HW param is not configured", __func__);
1362 return -EINVAL;
1363 }
1364
1365
Patrick Laicf999112011-08-23 11:27:20 -07001366 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1367 path_type = ADM_PATH_PLAYBACK;
1368 session_type = SESSION_TYPE_RX;
1369 } else {
1370 path_type = ADM_PATH_LIVE_REC;
1371 session_type = SESSION_TYPE_TX;
1372 }
1373
1374 mutex_lock(&routing_lock);
1375
1376 if (bedai->active == 1)
1377 goto done; /* Ignore prepare if back-end already active */
1378
1379 /* AFE port is not active at this point. However, still
1380 * go ahead setting active flag under the notion that
1381 * QDSP6 is able to handle ADM starting before AFE port
1382 * is started.
1383 */
1384 bedai->active = 1;
1385
Patrick Lai770ca3e42011-12-12 13:44:54 -08001386 for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MM_MAX_ID) {
Patrick Laicf999112011-08-23 11:27:20 -07001387 if (fe_dai_map[i][session_type] != INVALID_SESSION) {
1388 adm_open(bedai->port_id, path_type,
1389 params_rate(bedai->hw_params),
1390 params_channels(bedai->hw_params),
1391 DEFAULT_COPP_TOPOLOGY);
1392 msm_pcm_routing_build_matrix(i,
1393 fe_dai_map[i][session_type], path_type);
1394 }
1395 }
1396
1397done:
1398 mutex_unlock(&routing_lock);
1399
1400 return 0;
1401}
1402
1403static struct snd_pcm_ops msm_routing_pcm_ops = {
1404 .hw_params = msm_pcm_routing_hw_params,
1405 .close = msm_pcm_routing_close,
1406 .prepare = msm_pcm_routing_prepare,
1407};
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001408
1409static unsigned int msm_routing_read(struct snd_soc_platform *platform,
1410 unsigned int reg)
1411{
1412 dev_dbg(platform->dev, "reg %x\n", reg);
1413 return 0;
1414}
1415
1416/* Not used but frame seems to require it */
1417static int msm_routing_write(struct snd_soc_platform *platform,
1418 unsigned int reg, unsigned int val)
1419{
1420 dev_dbg(platform->dev, "reg %x val %x\n", reg, val);
1421 return 0;
1422}
1423
1424/* Not used but frame seems to require it */
1425static int msm_routing_probe(struct snd_soc_platform *platform)
1426{
1427 snd_soc_dapm_new_controls(&platform->dapm, msm_qdsp6_widgets,
1428 ARRAY_SIZE(msm_qdsp6_widgets));
1429 snd_soc_dapm_add_routes(&platform->dapm, intercon,
1430 ARRAY_SIZE(intercon));
1431
1432 snd_soc_dapm_new_widgets(&platform->dapm);
1433
Jayasena Sangaraboinacb1e22f2011-07-18 10:36:57 -07001434 snd_soc_add_platform_controls(platform,
1435 int_fm_vol_mixer_controls,
1436 ARRAY_SIZE(int_fm_vol_mixer_controls));
Asish Bhattacharya0ec76182011-07-29 16:58:11 +05301437
1438 snd_soc_add_platform_controls(platform,
1439 lpa_vol_mixer_controls,
1440 ARRAY_SIZE(lpa_vol_mixer_controls));
Ben Romberger037dd2f2011-09-22 14:01:32 -07001441
1442 snd_soc_add_platform_controls(platform,
1443 eq_enable_mixer_controls,
1444 ARRAY_SIZE(eq_enable_mixer_controls));
1445
1446 snd_soc_add_platform_controls(platform,
1447 eq_band_mixer_controls,
1448 ARRAY_SIZE(eq_band_mixer_controls));
1449
1450 snd_soc_add_platform_controls(platform,
1451 eq_coeff_mixer_controls,
1452 ARRAY_SIZE(eq_coeff_mixer_controls));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001453 return 0;
1454}
1455
1456static struct snd_soc_platform_driver msm_soc_routing_platform = {
1457 .ops = &msm_routing_pcm_ops,
1458 .probe = msm_routing_probe,
1459 .read = msm_routing_read,
1460 .write = msm_routing_write,
1461};
1462
1463static __devinit int msm_routing_pcm_probe(struct platform_device *pdev)
1464{
1465 dev_dbg(&pdev->dev, "dev name %s\n", dev_name(&pdev->dev));
1466 return snd_soc_register_platform(&pdev->dev,
1467 &msm_soc_routing_platform);
1468}
1469
1470static int msm_routing_pcm_remove(struct platform_device *pdev)
1471{
1472 snd_soc_unregister_platform(&pdev->dev);
1473 return 0;
1474}
1475
1476static struct platform_driver msm_routing_pcm_driver = {
1477 .driver = {
1478 .name = "msm-pcm-routing",
1479 .owner = THIS_MODULE,
1480 },
1481 .probe = msm_routing_pcm_probe,
1482 .remove = __devexit_p(msm_routing_pcm_remove),
1483};
1484
1485static int __init msm_soc_routing_platform_init(void)
1486{
Neema Shettyfeea7742011-09-11 12:30:36 -07001487 mutex_init(&routing_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001488 return platform_driver_register(&msm_routing_pcm_driver);
1489}
1490module_init(msm_soc_routing_platform_init);
1491
1492static void __exit msm_soc_routing_platform_exit(void)
1493{
1494 platform_driver_unregister(&msm_routing_pcm_driver);
1495}
1496module_exit(msm_soc_routing_platform_exit);
1497
1498MODULE_DESCRIPTION("MSM routing platform driver");
1499MODULE_LICENSE("GPL v2");