blob: 94ed5043e534152e65118c7232213949060319bb [file] [log] [blame]
Alex Wongb3d06a02012-01-12 10:00:41 -08001/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13
14#include <linux/init.h>
15#include <linux/err.h>
16#include <linux/module.h>
17#include <linux/moduleparam.h>
18#include <linux/platform_device.h>
19#include <linux/bitops.h>
Neema Shettyfeea7742011-09-11 12:30:36 -070020#include <linux/mutex.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070021#include <sound/core.h>
22#include <sound/soc.h>
23#include <sound/soc-dapm.h>
24#include <sound/pcm.h>
25#include <sound/initval.h>
26#include <sound/control.h>
27#include <sound/q6adm.h>
Ben Romberger037dd2f2011-09-22 14:01:32 -070028#include <sound/q6asm.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070029#include <sound/q6afe.h>
Jayasena Sangaraboinacb1e22f2011-07-18 10:36:57 -070030#include <sound/tlv.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070031#include "msm-pcm-routing.h"
32#include "qdsp6/q6voice.h"
33
Neema Shettyfeea7742011-09-11 12:30:36 -070034struct msm_pcm_routing_bdai_data {
35 u16 port_id; /* AFE port ID */
36 u8 active; /* track if this backend is enabled */
37 struct snd_pcm_hw_params *hw_params; /* to get freq and channel mode */
38 unsigned long fe_sessions; /* Front-end sessions */
39 unsigned long port_sessions; /* track Tx BE ports -> Rx BE */
40};
41
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070042#define INVALID_SESSION -1
Patrick Laicf999112011-08-23 11:27:20 -070043#define SESSION_TYPE_RX 0
44#define SESSION_TYPE_TX 1
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070045
Neema Shettyfeea7742011-09-11 12:30:36 -070046static struct mutex routing_lock;
47
Sriranjan Srikantama4969dd2011-07-14 00:34:56 -070048static int fm_switch_enable;
Jayasena Sangaraboinacb1e22f2011-07-18 10:36:57 -070049#define INT_FM_RX_VOL_MAX_STEPS 100
50#define INT_FM_RX_VOL_GAIN 2000
51
52static int msm_route_fm_vol_control;
53static const DECLARE_TLV_DB_SCALE(fm_rx_vol_gain, 0,
54 INT_FM_RX_VOL_MAX_STEPS, 0);
Sriranjan Srikantama4969dd2011-07-14 00:34:56 -070055
Sriranjan Srikantam269de7f2011-09-06 18:24:45 -070056#define INT_LPA_RX_VOL_MAX_STEPS 100
57#define INT_LPA_RX_VOL_GAIN 0x2000
Asish Bhattacharya0ec76182011-07-29 16:58:11 +053058
59static int msm_route_lpa_vol_control;
60static const DECLARE_TLV_DB_SCALE(lpa_rx_vol_gain, 0,
61 INT_LPA_RX_VOL_MAX_STEPS, 0);
62
Ben Romberger037dd2f2011-09-22 14:01:32 -070063/* Equal to Frontend after last of the MULTIMEDIA SESSIONS */
64#define MAX_EQ_SESSIONS MSM_FRONTEND_DAI_CS_VOICE
65
66enum {
67 EQ_BAND1 = 0,
68 EQ_BAND2,
69 EQ_BAND3,
70 EQ_BAND4,
71 EQ_BAND5,
72 EQ_BAND6,
73 EQ_BAND7,
74 EQ_BAND8,
75 EQ_BAND9,
76 EQ_BAND10,
77 EQ_BAND11,
78 EQ_BAND12,
79 EQ_BAND_MAX,
80};
81
82struct msm_audio_eq_band {
83 uint16_t band_idx; /* The band index, 0 .. 11 */
84 uint32_t filter_type; /* Filter band type */
85 uint32_t center_freq_hz; /* Filter band center frequency */
86 uint32_t filter_gain; /* Filter band initial gain (dB) */
87 /* Range is +12 dB to -12 dB with 1dB increments. */
88 uint32_t q_factor;
89} __packed;
90
91struct msm_audio_eq_stream_config {
92 uint32_t enable; /* Number of consequtive bands specified */
93 uint32_t num_bands;
94 struct msm_audio_eq_band eq_bands[EQ_BAND_MAX];
95} __packed;
96
97struct msm_audio_eq_stream_config eq_data[MAX_EQ_SESSIONS];
98
99static void msm_send_eq_values(int eq_idx);
Neema Shettyfeea7742011-09-11 12:30:36 -0700100/* This array is indexed by back-end DAI ID defined in msm-pcm-routing.h
101 * If new back-end is defined, add new back-end DAI ID at the end of enum
102 */
103static struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = {
104 { PRIMARY_I2S_RX, 0, NULL, 0, 0},
105 { PRIMARY_I2S_TX, 0, NULL, 0, 0},
106 { SLIMBUS_0_RX, 0, NULL, 0, 0},
107 { SLIMBUS_0_TX, 0, NULL, 0, 0},
108 { HDMI_RX, 0, NULL, 0, 0},
109 { INT_BT_SCO_RX, 0, NULL, 0, 0},
110 { INT_BT_SCO_TX, 0, NULL, 0, 0},
111 { INT_FM_RX, 0, NULL, 0, 0},
112 { INT_FM_TX, 0, NULL, 0, 0},
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530113 { RT_PROXY_PORT_001_RX, 0, NULL, 0, 0},
114 { RT_PROXY_PORT_001_TX, 0, NULL, 0, 0},
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700115 { PCM_RX, 0, NULL, 0, 0},
116 { PCM_TX, 0, NULL, 0, 0},
Helen Zeng0705a5f2011-10-14 15:29:52 -0700117 { VOICE_PLAYBACK_TX, 0, NULL, 0, 0},
Helen Zenge3d716a2011-10-14 16:32:16 -0700118 { VOICE_RECORD_RX, 0, NULL, 0, 0},
119 { VOICE_RECORD_TX, 0, NULL, 0, 0},
Kuirong Wang274f21a2011-12-15 21:29:08 -0800120 { MI2S_RX, 0, NULL, 0, 0},
Kuirong Wang9bbf6132012-01-10 18:28:49 -0800121 { SECONDARY_I2S_RX, 0, NULL, 0, 0},
Neema Shettyfeea7742011-09-11 12:30:36 -0700122};
123
124
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700125/* Track ASM playback & capture sessions of DAI */
Patrick Lai770ca3e42011-12-12 13:44:54 -0800126static int fe_dai_map[MSM_FRONTEND_DAI_MM_SIZE][2] = {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700127 /* MULTIMEDIA1 */
128 {INVALID_SESSION, INVALID_SESSION},
129 /* MULTIMEDIA2 */
130 {INVALID_SESSION, INVALID_SESSION},
131 /* MULTIMEDIA3 */
132 {INVALID_SESSION, INVALID_SESSION},
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530133 /* MULTIMEDIA4 */
134 {INVALID_SESSION, INVALID_SESSION},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700135};
136
Patrick Laicf999112011-08-23 11:27:20 -0700137static void msm_pcm_routing_build_matrix(int fedai_id, int dspst_id,
138 int path_type)
139{
140 int i, port_type;
141 struct route_payload payload;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700142
Patrick Laicf999112011-08-23 11:27:20 -0700143 payload.num_copps = 0;
144 port_type = (path_type == ADM_PATH_PLAYBACK ?
145 MSM_AFE_PORT_TYPE_RX : MSM_AFE_PORT_TYPE_TX);
146
147 for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) {
148 if ((afe_get_port_type(msm_bedais[i].port_id) ==
149 port_type) &&
150 msm_bedais[i].active && (test_bit(fedai_id,
151 &msm_bedais[i].fe_sessions)))
152 payload.copp_ids[payload.num_copps++] =
153 msm_bedais[i].port_id;
154 }
155
156 if (payload.num_copps)
157 adm_matrix_map(dspst_id, path_type,
158 payload.num_copps, payload.copp_ids, 0);
159}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700160
161void msm_pcm_routing_reg_phy_stream(int fedai_id, int dspst_id, int stream_type)
162{
Patrick Laicf999112011-08-23 11:27:20 -0700163 int i, session_type, path_type, port_type;
164 struct route_payload payload;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700165
Patrick Lai770ca3e42011-12-12 13:44:54 -0800166 if (fedai_id > MSM_FRONTEND_DAI_MM_MAX_ID) {
167 /* bad ID assigned in machine driver */
168 pr_err("%s: bad MM ID\n", __func__);
169 return;
170 }
171
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700172 if (stream_type == SNDRV_PCM_STREAM_PLAYBACK) {
Patrick Laicf999112011-08-23 11:27:20 -0700173 session_type = SESSION_TYPE_RX;
174 path_type = ADM_PATH_PLAYBACK;
175 port_type = MSM_AFE_PORT_TYPE_RX;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700176 } else {
Patrick Laicf999112011-08-23 11:27:20 -0700177 session_type = SESSION_TYPE_TX;
178 path_type = ADM_PATH_LIVE_REC;
179 port_type = MSM_AFE_PORT_TYPE_TX;
180 }
181
182 mutex_lock(&routing_lock);
183
184 payload.num_copps = 0; /* only RX needs to use payload */
185 fe_dai_map[fedai_id][session_type] = dspst_id;
Ben Romberger037dd2f2011-09-22 14:01:32 -0700186 /* re-enable EQ if active */
187 if (eq_data[fedai_id].enable)
188 msm_send_eq_values(fedai_id);
Patrick Laicf999112011-08-23 11:27:20 -0700189 for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) {
190 if ((afe_get_port_type(msm_bedais[i].port_id) ==
191 port_type) && msm_bedais[i].active &&
192 (test_bit(fedai_id,
193 &msm_bedais[i].fe_sessions))) {
194 adm_open(msm_bedais[i].port_id,
195 path_type,
196 params_rate(msm_bedais[i].hw_params),
197 params_channels(msm_bedais[i].hw_params),
198 DEFAULT_COPP_TOPOLOGY);
199 payload.copp_ids[payload.num_copps++] =
200 msm_bedais[i].port_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700201 }
202 }
Patrick Laicf999112011-08-23 11:27:20 -0700203 if (payload.num_copps)
204 adm_matrix_map(dspst_id, path_type,
205 payload.num_copps, payload.copp_ids, 0);
206
207 mutex_unlock(&routing_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700208}
209
210void msm_pcm_routing_dereg_phy_stream(int fedai_id, int stream_type)
211{
Patrick Laicf999112011-08-23 11:27:20 -0700212 int i, port_type, session_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700213
Patrick Lai770ca3e42011-12-12 13:44:54 -0800214 if (fedai_id > MSM_FRONTEND_DAI_MM_MAX_ID) {
215 /* bad ID assigned in machine driver */
216 pr_err("%s: bad MM ID\n", __func__);
217 return;
218 }
219
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700220 if (stream_type == SNDRV_PCM_STREAM_PLAYBACK) {
Patrick Laicf999112011-08-23 11:27:20 -0700221 port_type = MSM_AFE_PORT_TYPE_RX;
222 session_type = SESSION_TYPE_RX;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700223 } else {
Patrick Laicf999112011-08-23 11:27:20 -0700224 port_type = MSM_AFE_PORT_TYPE_TX;
225 session_type = SESSION_TYPE_TX;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700226 }
Patrick Laicf999112011-08-23 11:27:20 -0700227
228 mutex_lock(&routing_lock);
229
230 for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) {
231 if ((afe_get_port_type(msm_bedais[i].port_id) ==
232 port_type) && msm_bedais[i].active &&
233 (test_bit(fedai_id,
234 &msm_bedais[i].fe_sessions)))
235 adm_close(msm_bedais[i].port_id);
236 }
237
238 fe_dai_map[fedai_id][session_type] = INVALID_SESSION;
239
240 mutex_unlock(&routing_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700241}
242
243static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set)
244{
Patrick Laicf999112011-08-23 11:27:20 -0700245 int session_type, path_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700246
247 pr_debug("%s: reg %x val %x set %x\n", __func__, reg, val, set);
248
Patrick Lai770ca3e42011-12-12 13:44:54 -0800249 if (val > MSM_FRONTEND_DAI_MM_MAX_ID) {
250 /* recheck FE ID in the mixer control defined in this file */
251 pr_err("%s: bad MM ID\n", __func__);
252 return;
253 }
254
Patrick Laicf999112011-08-23 11:27:20 -0700255 if (afe_get_port_type(msm_bedais[reg].port_id) ==
256 MSM_AFE_PORT_TYPE_RX) {
257 session_type = SESSION_TYPE_RX;
258 path_type = ADM_PATH_PLAYBACK;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700259 } else {
Patrick Laicf999112011-08-23 11:27:20 -0700260 session_type = SESSION_TYPE_TX;
261 path_type = ADM_PATH_LIVE_REC;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700262 }
Patrick Laicf999112011-08-23 11:27:20 -0700263
264 mutex_lock(&routing_lock);
265
266 if (set) {
Helen Zeng0705a5f2011-10-14 15:29:52 -0700267 if (!test_bit(val, &msm_bedais[reg].fe_sessions) &&
268 (msm_bedais[reg].port_id == VOICE_PLAYBACK_TX))
269 voc_start_playback(set);
270
Patrick Laicf999112011-08-23 11:27:20 -0700271 set_bit(val, &msm_bedais[reg].fe_sessions);
272 if (msm_bedais[reg].active && fe_dai_map[val][session_type] !=
273 INVALID_SESSION) {
274 adm_open(msm_bedais[reg].port_id, path_type,
275 params_rate(msm_bedais[reg].hw_params),
276 params_channels(msm_bedais[reg].hw_params),
277 DEFAULT_COPP_TOPOLOGY);
278 msm_pcm_routing_build_matrix(val,
279 fe_dai_map[val][session_type], path_type);
280 }
281 } else {
Helen Zeng0705a5f2011-10-14 15:29:52 -0700282 if (test_bit(val, &msm_bedais[reg].fe_sessions) &&
283 (msm_bedais[reg].port_id == VOICE_PLAYBACK_TX))
284 voc_start_playback(set);
Patrick Laicf999112011-08-23 11:27:20 -0700285 clear_bit(val, &msm_bedais[reg].fe_sessions);
286 if (msm_bedais[reg].active && fe_dai_map[val][session_type] !=
287 INVALID_SESSION) {
288 adm_close(msm_bedais[reg].port_id);
289 msm_pcm_routing_build_matrix(val,
290 fe_dai_map[val][session_type], path_type);
291 }
292 }
Helen Zenge3d716a2011-10-14 16:32:16 -0700293 if ((msm_bedais[reg].port_id == VOICE_RECORD_RX)
294 || (msm_bedais[reg].port_id == VOICE_RECORD_TX))
295 voc_start_record(msm_bedais[reg].port_id, set);
Patrick Laicf999112011-08-23 11:27:20 -0700296
297 mutex_unlock(&routing_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700298}
299
300static int msm_routing_get_audio_mixer(struct snd_kcontrol *kcontrol,
301 struct snd_ctl_elem_value *ucontrol)
302{
303 struct soc_mixer_control *mc =
304 (struct soc_mixer_control *)kcontrol->private_value;
305
Patrick Laicf999112011-08-23 11:27:20 -0700306 if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700307 ucontrol->value.integer.value[0] = 1;
308 else
309 ucontrol->value.integer.value[0] = 0;
310
311 pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift,
312 ucontrol->value.integer.value[0]);
313
314 return 0;
315}
316
317static int msm_routing_put_audio_mixer(struct snd_kcontrol *kcontrol,
318 struct snd_ctl_elem_value *ucontrol)
319{
Patrick Laiec2b8942011-09-01 11:01:51 -0700320 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
321 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700322 struct soc_mixer_control *mc =
323 (struct soc_mixer_control *)kcontrol->private_value;
324
325
326 if (ucontrol->value.integer.value[0]) {
327 msm_pcm_routing_process_audio(mc->reg, mc->shift, 1);
328 snd_soc_dapm_mixer_update_power(widget, kcontrol, 1);
329 } else {
330 msm_pcm_routing_process_audio(mc->reg, mc->shift, 0);
331 snd_soc_dapm_mixer_update_power(widget, kcontrol, 0);
332 }
333
334 return 1;
335}
336
Neema Shettyfeea7742011-09-11 12:30:36 -0700337static void msm_pcm_routing_process_voice(u16 reg, u16 val, int set)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700338{
Neema Shetty2c07eb52011-08-21 20:33:52 -0700339 u16 session_id = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700340
Neema Shettyfeea7742011-09-11 12:30:36 -0700341 pr_debug("%s: reg %x val %x set %x\n", __func__, reg, val, set);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700342
Neema Shettyfeea7742011-09-11 12:30:36 -0700343 if (val == MSM_FRONTEND_DAI_CS_VOICE)
Neema Shetty2c07eb52011-08-21 20:33:52 -0700344 session_id = voc_get_session_id(VOICE_SESSION_NAME);
345 else
346 session_id = voc_get_session_id(VOIP_SESSION_NAME);
347
348 pr_debug("%s: FE DAI 0x%x session_id 0x%x\n",
Neema Shettyfeea7742011-09-11 12:30:36 -0700349 __func__, val, session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700350
Neema Shettyfeea7742011-09-11 12:30:36 -0700351 mutex_lock(&routing_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700352
353 if (set)
Neema Shettyfeea7742011-09-11 12:30:36 -0700354 set_bit(val, &msm_bedais[reg].fe_sessions);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700355 else
Neema Shettyfeea7742011-09-11 12:30:36 -0700356 clear_bit(val, &msm_bedais[reg].fe_sessions);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700357
Neema Shettyfeea7742011-09-11 12:30:36 -0700358 mutex_unlock(&routing_lock);
359
360 if (afe_get_port_type(msm_bedais[reg].port_id) ==
361 MSM_AFE_PORT_TYPE_RX) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700362 voc_set_route_flag(session_id, RX_PATH, set);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700363 if (set) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700364 voc_set_rxtx_port(session_id,
Neema Shettyfeea7742011-09-11 12:30:36 -0700365 msm_bedais[reg].port_id, DEV_RX);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700366
Neema Shetty2c07eb52011-08-21 20:33:52 -0700367 if (voc_get_route_flag(session_id, RX_PATH) &&
368 voc_get_route_flag(session_id, TX_PATH))
369 voc_enable_cvp(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700370 } else {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700371 voc_disable_cvp(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700372 }
373 } else {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700374 voc_set_route_flag(session_id, TX_PATH, set);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700375 if (set) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700376 voc_set_rxtx_port(session_id,
Neema Shettyfeea7742011-09-11 12:30:36 -0700377 msm_bedais[reg].port_id, DEV_TX);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700378 if (voc_get_route_flag(session_id, RX_PATH) &&
379 voc_get_route_flag(session_id, TX_PATH))
380 voc_enable_cvp(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700381 } else {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700382 voc_disable_cvp(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700383 }
384 }
385}
386
387static int msm_routing_get_voice_mixer(struct snd_kcontrol *kcontrol,
388 struct snd_ctl_elem_value *ucontrol)
389{
390 struct soc_mixer_control *mc =
391 (struct soc_mixer_control *)kcontrol->private_value;
392
Neema Shettyfeea7742011-09-11 12:30:36 -0700393 mutex_lock(&routing_lock);
394
395 if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700396 ucontrol->value.integer.value[0] = 1;
397 else
398 ucontrol->value.integer.value[0] = 0;
399
Neema Shettyfeea7742011-09-11 12:30:36 -0700400 mutex_unlock(&routing_lock);
401
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700402 pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift,
403 ucontrol->value.integer.value[0]);
404
405 return 0;
406}
407
408static int msm_routing_put_voice_mixer(struct snd_kcontrol *kcontrol,
409 struct snd_ctl_elem_value *ucontrol)
410{
Patrick Laiec2b8942011-09-01 11:01:51 -0700411 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
412 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700413 struct soc_mixer_control *mc =
414 (struct soc_mixer_control *)kcontrol->private_value;
415
416 if (ucontrol->value.integer.value[0]) {
Neema Shettyfeea7742011-09-11 12:30:36 -0700417 msm_pcm_routing_process_voice(mc->reg, mc->shift, 1);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700418 snd_soc_dapm_mixer_update_power(widget, kcontrol, 1);
419 } else {
Neema Shettyfeea7742011-09-11 12:30:36 -0700420 msm_pcm_routing_process_voice(mc->reg, mc->shift, 0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700421 snd_soc_dapm_mixer_update_power(widget, kcontrol, 0);
422 }
423
424 return 1;
425}
426
Sriranjan Srikantama4969dd2011-07-14 00:34:56 -0700427static int msm_routing_get_switch_mixer(struct snd_kcontrol *kcontrol,
428 struct snd_ctl_elem_value *ucontrol)
429{
430 ucontrol->value.integer.value[0] = fm_switch_enable;
431 pr_debug("%s: FM Switch enable %ld\n", __func__,
432 ucontrol->value.integer.value[0]);
433 return 0;
434}
435
436static int msm_routing_put_switch_mixer(struct snd_kcontrol *kcontrol,
437 struct snd_ctl_elem_value *ucontrol)
438{
Sriranjan Srikantamdf509d12011-10-24 17:53:27 -0700439 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
440 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
Sriranjan Srikantama4969dd2011-07-14 00:34:56 -0700441
442 pr_debug("%s: FM Switch enable %ld\n", __func__,
443 ucontrol->value.integer.value[0]);
444 if (ucontrol->value.integer.value[0])
445 snd_soc_dapm_mixer_update_power(widget, kcontrol, 1);
446 else
447 snd_soc_dapm_mixer_update_power(widget, kcontrol, 0);
448 fm_switch_enable = ucontrol->value.integer.value[0];
449 return 1;
450}
451
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700452static int msm_routing_get_port_mixer(struct snd_kcontrol *kcontrol,
453 struct snd_ctl_elem_value *ucontrol)
454{
455 struct soc_mixer_control *mc =
456 (struct soc_mixer_control *)kcontrol->private_value;
457
Patrick Laicf999112011-08-23 11:27:20 -0700458 if (test_bit(mc->shift, &msm_bedais[mc->reg].port_sessions))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700459 ucontrol->value.integer.value[0] = 1;
460 else
461 ucontrol->value.integer.value[0] = 0;
462
463 pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift,
464 ucontrol->value.integer.value[0]);
465
466 return 0;
467}
468
469static int msm_routing_put_port_mixer(struct snd_kcontrol *kcontrol,
470 struct snd_ctl_elem_value *ucontrol)
471{
472 struct soc_mixer_control *mc =
473 (struct soc_mixer_control *)kcontrol->private_value;
474
475 pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg,
476 mc->shift, ucontrol->value.integer.value[0]);
477
478 if (ucontrol->value.integer.value[0]) {
Patrick Laicf999112011-08-23 11:27:20 -0700479 afe_loopback(1, msm_bedais[mc->reg].port_id,
480 msm_bedais[mc->shift].port_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700481 set_bit(mc->shift,
Patrick Laicf999112011-08-23 11:27:20 -0700482 &msm_bedais[mc->reg].port_sessions);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700483 } else {
Patrick Laicf999112011-08-23 11:27:20 -0700484 afe_loopback(0, msm_bedais[mc->reg].port_id,
485 msm_bedais[mc->shift].port_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700486 clear_bit(mc->shift,
Patrick Laicf999112011-08-23 11:27:20 -0700487 &msm_bedais[mc->reg].port_sessions);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700488 }
489
490 return 1;
491}
492
Jayasena Sangaraboinacb1e22f2011-07-18 10:36:57 -0700493static int msm_routing_get_fm_vol_mixer(struct snd_kcontrol *kcontrol,
494 struct snd_ctl_elem_value *ucontrol)
495{
496 ucontrol->value.integer.value[0] = msm_route_fm_vol_control;
497 return 0;
498}
499
500static int msm_routing_set_fm_vol_mixer(struct snd_kcontrol *kcontrol,
501 struct snd_ctl_elem_value *ucontrol)
502{
503 afe_loopback_gain(INT_FM_TX , ucontrol->value.integer.value[0]);
504
505 msm_route_fm_vol_control = ucontrol->value.integer.value[0];
506
507 return 0;
508}
509
Asish Bhattacharya0ec76182011-07-29 16:58:11 +0530510static int msm_routing_get_lpa_vol_mixer(struct snd_kcontrol *kcontrol,
511 struct snd_ctl_elem_value *ucontrol)
512{
513 ucontrol->value.integer.value[0] = msm_route_lpa_vol_control;
514 return 0;
515}
516
517static int msm_routing_set_lpa_vol_mixer(struct snd_kcontrol *kcontrol,
518 struct snd_ctl_elem_value *ucontrol)
519{
520 if (!lpa_set_volume(ucontrol->value.integer.value[0]))
521 msm_route_lpa_vol_control =
522 ucontrol->value.integer.value[0];
523
524 return 0;
525}
526
Ben Romberger037dd2f2011-09-22 14:01:32 -0700527static void msm_send_eq_values(int eq_idx)
528{
529 int result;
530 struct audio_client *ac =
531 q6asm_get_audio_client(fe_dai_map[eq_idx][SESSION_TYPE_RX]);
532
533 if (ac == NULL) {
534 pr_err("%s: Could not get audio client for session: %d\n",
535 __func__, fe_dai_map[eq_idx][SESSION_TYPE_RX]);
536 goto done;
537 }
538
539 result = q6asm_equalizer(ac, &eq_data[eq_idx]);
540
541 if (result < 0)
542 pr_err("%s: Call to ASM equalizer failed, returned = %d\n",
543 __func__, result);
544done:
545 return;
546}
547
548static int msm_routing_get_eq_enable_mixer(struct snd_kcontrol *kcontrol,
549 struct snd_ctl_elem_value *ucontrol)
550{
551 int eq_idx = ((struct soc_multi_mixer_control *)
552 kcontrol->private_value)->reg;
553
Ben Romberger76f57032011-12-08 20:07:34 -0800554 ucontrol->value.integer.value[0] = eq_data[eq_idx].enable;
555
Ben Romberger037dd2f2011-09-22 14:01:32 -0700556 pr_debug("%s: EQ #%d enable %d\n", __func__,
557 eq_idx, eq_data[eq_idx].enable);
Ben Romberger76f57032011-12-08 20:07:34 -0800558 return 0;
Ben Romberger037dd2f2011-09-22 14:01:32 -0700559}
560
561static int msm_routing_put_eq_enable_mixer(struct snd_kcontrol *kcontrol,
562 struct snd_ctl_elem_value *ucontrol)
563{
564 int eq_idx = ((struct soc_multi_mixer_control *)
565 kcontrol->private_value)->reg;
566 int value = ucontrol->value.integer.value[0];
567
568 pr_debug("%s: EQ #%d enable %d\n", __func__,
569 eq_idx, value);
570 eq_data[eq_idx].enable = value;
571
572 msm_send_eq_values(eq_idx);
573 return 0;
574}
575
576static int msm_routing_get_eq_band_count_audio_mixer(
577 struct snd_kcontrol *kcontrol,
578 struct snd_ctl_elem_value *ucontrol)
579{
580 int eq_idx = ((struct soc_multi_mixer_control *)
581 kcontrol->private_value)->reg;
582
Ben Romberger76f57032011-12-08 20:07:34 -0800583 ucontrol->value.integer.value[0] = eq_data[eq_idx].num_bands;
584
Ben Romberger037dd2f2011-09-22 14:01:32 -0700585 pr_debug("%s: EQ #%d bands %d\n", __func__,
586 eq_idx, eq_data[eq_idx].num_bands);
587 return eq_data[eq_idx].num_bands;
588}
589
590static int msm_routing_put_eq_band_count_audio_mixer(
591 struct snd_kcontrol *kcontrol,
592 struct snd_ctl_elem_value *ucontrol)
593{
594 int eq_idx = ((struct soc_multi_mixer_control *)
595 kcontrol->private_value)->reg;
596 int value = ucontrol->value.integer.value[0];
597
Ben Romberger037dd2f2011-09-22 14:01:32 -0700598 pr_debug("%s: EQ #%d bands %d\n", __func__,
599 eq_idx, value);
600 eq_data[eq_idx].num_bands = value;
601 return 0;
602}
603
604static int msm_routing_get_eq_band_audio_mixer(struct snd_kcontrol *kcontrol,
605 struct snd_ctl_elem_value *ucontrol)
606{
607 int eq_idx = ((struct soc_multi_mixer_control *)
608 kcontrol->private_value)->reg;
609 int band_idx = ((struct soc_multi_mixer_control *)
610 kcontrol->private_value)->shift;
611
Ben Romberger76f57032011-12-08 20:07:34 -0800612 ucontrol->value.integer.value[0] =
613 eq_data[eq_idx].eq_bands[band_idx].band_idx;
614 ucontrol->value.integer.value[1] =
615 eq_data[eq_idx].eq_bands[band_idx].filter_type;
616 ucontrol->value.integer.value[2] =
617 eq_data[eq_idx].eq_bands[band_idx].center_freq_hz;
618 ucontrol->value.integer.value[3] =
619 eq_data[eq_idx].eq_bands[band_idx].filter_gain;
620 ucontrol->value.integer.value[4] =
621 eq_data[eq_idx].eq_bands[band_idx].q_factor;
622
Ben Romberger037dd2f2011-09-22 14:01:32 -0700623 pr_debug("%s: band_idx = %d\n", __func__,
624 eq_data[eq_idx].eq_bands[band_idx].band_idx);
625 pr_debug("%s: filter_type = %d\n", __func__,
626 eq_data[eq_idx].eq_bands[band_idx].filter_type);
627 pr_debug("%s: center_freq_hz = %d\n", __func__,
628 eq_data[eq_idx].eq_bands[band_idx].center_freq_hz);
629 pr_debug("%s: filter_gain = %d\n", __func__,
630 eq_data[eq_idx].eq_bands[band_idx].filter_gain);
631 pr_debug("%s: q_factor = %d\n", __func__,
632 eq_data[eq_idx].eq_bands[band_idx].q_factor);
633 return 0;
634}
635
636static int msm_routing_put_eq_band_audio_mixer(struct snd_kcontrol *kcontrol,
637 struct snd_ctl_elem_value *ucontrol)
638{
639 int eq_idx = ((struct soc_multi_mixer_control *)
640 kcontrol->private_value)->reg;
641 int band_idx = ((struct soc_multi_mixer_control *)
642 kcontrol->private_value)->shift;
643
644 eq_data[eq_idx].eq_bands[band_idx].band_idx =
645 ucontrol->value.integer.value[0];
646 eq_data[eq_idx].eq_bands[band_idx].filter_type =
647 ucontrol->value.integer.value[1];
648 eq_data[eq_idx].eq_bands[band_idx].center_freq_hz =
649 ucontrol->value.integer.value[2];
650 eq_data[eq_idx].eq_bands[band_idx].filter_gain =
651 ucontrol->value.integer.value[3];
652 eq_data[eq_idx].eq_bands[band_idx].q_factor =
653 ucontrol->value.integer.value[4];
654 return 0;
655}
656
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700657static const struct snd_kcontrol_new pri_i2s_rx_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700658 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_PRI_I2S_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_PRI_I2S_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_PRI_I2S_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_PRI_I2S_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
Kuirong Wang9bbf6132012-01-10 18:28:49 -0800672static const struct snd_kcontrol_new sec_i2s_rx_mixer_controls[] = {
673 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SEC_I2S_RX ,
674 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
675 msm_routing_put_audio_mixer),
676 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SEC_I2S_RX,
677 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
678 msm_routing_put_audio_mixer),
679 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SEC_I2S_RX,
680 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
681 msm_routing_put_audio_mixer),
682 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SEC_I2S_RX,
683 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
684 msm_routing_put_audio_mixer),
685};
686
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700687static const struct snd_kcontrol_new slimbus_rx_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700688 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SLIMBUS_0_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_SLIMBUS_0_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_SLIMBUS_0_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700695 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_SLIMBUS_0_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
Kuirong Wang274f21a2011-12-15 21:29:08 -0800702static const struct snd_kcontrol_new mi2s_rx_mixer_controls[] = {
703 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_MI2S_RX ,
704 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
705 msm_routing_put_audio_mixer),
706 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_MI2S_RX,
707 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
708 msm_routing_put_audio_mixer),
709 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_MI2S_RX,
710 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
711 msm_routing_put_audio_mixer),
712 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_MI2S_RX,
713 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
714 msm_routing_put_audio_mixer),
715};
716
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700717static const struct snd_kcontrol_new hdmi_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700718 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_HDMI_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700719 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_HDMI_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700722 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_HDMI_RX,
Asish Bhattacharyac592eed2011-09-16 17:43:02 +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_HDMI_RX,
728 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
729 msm_routing_put_audio_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700730};
Helen Zeng0705a5f2011-10-14 15:29:52 -0700731 /* incall music delivery mixer */
732static const struct snd_kcontrol_new incall_music_delivery_mixer_controls[] = {
733 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_VOICE_PLAYBACK_TX,
734 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
735 msm_routing_put_audio_mixer),
736 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_VOICE_PLAYBACK_TX,
737 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
738 msm_routing_put_audio_mixer),
739};
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700740
741static const struct snd_kcontrol_new int_bt_sco_rx_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700742 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_INT_BT_SCO_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700743 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
744 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700745 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_INT_BT_SCO_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700746 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
747 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700748 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_INT_BT_SCO_RX,
Asish Bhattacharyac592eed2011-09-16 17:43:02 +0530749 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
750 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530751 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_INT_BT_SCO_RX,
752 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
753 msm_routing_put_audio_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700754};
755
756static const struct snd_kcontrol_new int_fm_rx_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700757 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_INT_FM_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700758 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
759 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700760 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_INT_FM_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700761 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
762 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700763 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_INT_FM_RX,
Asish Bhattacharyac592eed2011-09-16 17:43:02 +0530764 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
765 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530766 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_INT_FM_RX,
767 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
768 msm_routing_put_audio_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700769};
770
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530771static const struct snd_kcontrol_new afe_pcm_rx_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700772 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_AFE_PCM_RX,
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530773 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
774 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700775 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_AFE_PCM_RX,
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530776 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
777 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700778 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_AFE_PCM_RX,
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530779 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
780 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530781 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_AFE_PCM_RX,
782 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
783 msm_routing_put_audio_mixer),
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530784};
785
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700786static const struct snd_kcontrol_new auxpcm_rx_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700787 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_AUXPCM_RX,
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700788 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
789 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700790 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_AUXPCM_RX,
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700791 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
792 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700793 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_AUXPCM_RX,
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700794 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
795 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530796 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_AUXPCM_RX,
797 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
798 msm_routing_put_audio_mixer),
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700799};
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530800
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700801static const struct snd_kcontrol_new mmul1_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700802 SOC_SINGLE_EXT("PRI_TX", MSM_BACKEND_DAI_PRI_I2S_TX,
803 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
804 msm_routing_put_audio_mixer),
805 SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX,
806 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
807 msm_routing_put_audio_mixer),
808 SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_AUXPCM_TX,
809 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
810 msm_routing_put_audio_mixer),
811 SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX,
812 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
813 msm_routing_put_audio_mixer),
814 SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX,
815 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
816 msm_routing_put_audio_mixer),
817 SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX,
818 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
819 msm_routing_put_audio_mixer),
Helen Zenge3d716a2011-10-14 16:32:16 -0700820 SOC_SINGLE_EXT("VOC_REC_DL", MSM_BACKEND_DAI_INCALL_RECORD_RX,
821 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
822 msm_routing_put_audio_mixer),
823 SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX,
824 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
825 msm_routing_put_audio_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700826};
827
Jayasena Sangaraboina99fee652011-09-19 07:43:13 -0700828static const struct snd_kcontrol_new mmul2_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700829 SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX,
830 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
Jayasena Sangaraboina99fee652011-09-19 07:43:13 -0700831 msm_routing_put_audio_mixer),
832};
833
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700834static const struct snd_kcontrol_new pri_rx_voice_mixer_controls[] = {
Neema Shettyfeea7742011-09-11 12:30:36 -0700835 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_PRI_I2S_RX,
836 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
837 msm_routing_put_voice_mixer),
838 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_PRI_I2S_RX,
839 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
840 msm_routing_put_voice_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700841};
842
Kuirong Wang9bbf6132012-01-10 18:28:49 -0800843static const struct snd_kcontrol_new sec_i2s_rx_voice_mixer_controls[] = {
844 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_SEC_I2S_RX,
845 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
846 msm_routing_put_voice_mixer),
847 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SEC_I2S_RX,
848 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
849 msm_routing_put_voice_mixer),
850};
851
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700852static const struct snd_kcontrol_new slimbus_rx_voice_mixer_controls[] = {
Neema Shettyfeea7742011-09-11 12:30:36 -0700853 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_SLIMBUS_0_RX,
854 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
855 msm_routing_put_voice_mixer),
856 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SLIMBUS_0_RX ,
857 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
858 msm_routing_put_voice_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700859};
860
861static const struct snd_kcontrol_new bt_sco_rx_voice_mixer_controls[] = {
Neema Shettyfeea7742011-09-11 12:30:36 -0700862 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_INT_BT_SCO_RX,
863 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
864 msm_routing_put_voice_mixer),
865 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_INT_BT_SCO_RX ,
866 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
867 msm_routing_put_voice_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700868};
869
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530870static const struct snd_kcontrol_new afe_pcm_rx_voice_mixer_controls[] = {
871 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_AFE_PCM_RX,
872 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
873 msm_routing_put_voice_mixer),
874 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_AFE_PCM_RX,
875 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
876 msm_routing_put_voice_mixer),
877};
878
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700879static const struct snd_kcontrol_new aux_pcm_rx_voice_mixer_controls[] = {
880 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_AUXPCM_RX,
881 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
882 msm_routing_put_voice_mixer),
883 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_AUXPCM_RX,
884 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
885 msm_routing_put_voice_mixer),
886};
887
Alex Wong593576c2011-11-15 08:03:24 -0800888static const struct snd_kcontrol_new hdmi_rx_voice_mixer_controls[] = {
889 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_HDMI_RX,
890 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
891 msm_routing_put_voice_mixer),
892 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_HDMI_RX,
893 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
894 msm_routing_put_voice_mixer),
895};
896
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700897static const struct snd_kcontrol_new tx_voice_mixer_controls[] = {
Neema Shettyfeea7742011-09-11 12:30:36 -0700898 SOC_SINGLE_EXT("PRI_TX_Voice", MSM_BACKEND_DAI_PRI_I2S_TX,
899 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
900 msm_routing_put_voice_mixer),
901 SOC_SINGLE_EXT("SLIM_0_TX_Voice", MSM_BACKEND_DAI_SLIMBUS_0_TX,
902 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
903 msm_routing_put_voice_mixer),
904 SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_Voice",
905 MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_CS_VOICE, 1, 0,
Neema Shetty2c07eb52011-08-21 20:33:52 -0700906 msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530907 SOC_SINGLE_EXT("AFE_PCM_TX_Voice", MSM_BACKEND_DAI_AFE_PCM_TX,
908 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
909 msm_routing_put_voice_mixer),
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700910 SOC_SINGLE_EXT("AUX_PCM_TX_Voice", MSM_BACKEND_DAI_AUXPCM_TX,
911 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
912 msm_routing_put_voice_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700913};
914
915static const struct snd_kcontrol_new tx_voip_mixer_controls[] = {
Neema Shettyfeea7742011-09-11 12:30:36 -0700916 SOC_SINGLE_EXT("PRI_TX_Voip", MSM_BACKEND_DAI_PRI_I2S_TX,
917 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
918 msm_routing_put_voice_mixer),
919 SOC_SINGLE_EXT("SLIM_0_TX_Voip", MSM_BACKEND_DAI_SLIMBUS_0_TX,
920 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
921 msm_routing_put_voice_mixer),
922 SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_Voip", MSM_BACKEND_DAI_INT_BT_SCO_TX,
923 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
924 msm_routing_put_voice_mixer),
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530925 SOC_SINGLE_EXT("AFE_PCM_TX_Voip", MSM_BACKEND_DAI_AFE_PCM_TX,
926 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
927 msm_routing_put_voice_mixer),
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700928 SOC_SINGLE_EXT("AUX_PCM_TX_Voip", MSM_BACKEND_DAI_AUXPCM_TX,
929 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
930 msm_routing_put_voice_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700931};
932
933static const struct snd_kcontrol_new sbus_0_rx_port_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700934 SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700935 MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer,
936 msm_routing_put_port_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700937 SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700938 MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer,
939 msm_routing_put_port_mixer),
940};
941
Sriranjan Srikantama4969dd2011-07-14 00:34:56 -0700942static const struct snd_kcontrol_new fm_switch_mixer_controls =
943 SOC_SINGLE_EXT("Switch", SND_SOC_NOPM,
944 0, 1, 0, msm_routing_get_switch_mixer,
945 msm_routing_put_switch_mixer);
946
Jayasena Sangaraboinacb1e22f2011-07-18 10:36:57 -0700947static const struct snd_kcontrol_new int_fm_vol_mixer_controls[] = {
948 SOC_SINGLE_EXT_TLV("Internal FM RX Volume", SND_SOC_NOPM, 0,
949 INT_FM_RX_VOL_GAIN, 0, msm_routing_get_fm_vol_mixer,
950 msm_routing_set_fm_vol_mixer, fm_rx_vol_gain),
951};
952
Asish Bhattacharya0ec76182011-07-29 16:58:11 +0530953static const struct snd_kcontrol_new lpa_vol_mixer_controls[] = {
954 SOC_SINGLE_EXT_TLV("LPA RX Volume", SND_SOC_NOPM, 0,
955 INT_LPA_RX_VOL_GAIN, 0, msm_routing_get_lpa_vol_mixer,
956 msm_routing_set_lpa_vol_mixer, lpa_rx_vol_gain),
957};
958
Ben Romberger037dd2f2011-09-22 14:01:32 -0700959static const struct snd_kcontrol_new eq_enable_mixer_controls[] = {
960 SOC_SINGLE_EXT("MultiMedia1 EQ Enable", SND_SOC_NOPM,
961 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_eq_enable_mixer,
962 msm_routing_put_eq_enable_mixer),
963 SOC_SINGLE_EXT("MultiMedia2 EQ Enable", SND_SOC_NOPM,
964 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_eq_enable_mixer,
965 msm_routing_put_eq_enable_mixer),
966 SOC_SINGLE_EXT("MultiMedia3 EQ Enable", SND_SOC_NOPM,
967 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_eq_enable_mixer,
968 msm_routing_put_eq_enable_mixer),
969};
970
971static const struct snd_kcontrol_new eq_band_mixer_controls[] = {
972 SOC_SINGLE_EXT("MultiMedia1 EQ Band Count", SND_SOC_NOPM,
973 MSM_FRONTEND_DAI_MULTIMEDIA1, 11, 0,
974 msm_routing_get_eq_band_count_audio_mixer,
975 msm_routing_put_eq_band_count_audio_mixer),
976 SOC_SINGLE_EXT("MultiMedia2 EQ Band Count", SND_SOC_NOPM,
977 MSM_FRONTEND_DAI_MULTIMEDIA2, 11, 0,
978 msm_routing_get_eq_band_count_audio_mixer,
979 msm_routing_put_eq_band_count_audio_mixer),
980 SOC_SINGLE_EXT("MultiMedia3 EQ Band Count", SND_SOC_NOPM,
981 MSM_FRONTEND_DAI_MULTIMEDIA3, 11, 0,
982 msm_routing_get_eq_band_count_audio_mixer,
983 msm_routing_put_eq_band_count_audio_mixer),
984};
985
986static const struct snd_kcontrol_new eq_coeff_mixer_controls[] = {
987 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band1", EQ_BAND1,
988 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
989 msm_routing_get_eq_band_audio_mixer,
990 msm_routing_put_eq_band_audio_mixer),
991 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band2", EQ_BAND2,
992 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
993 msm_routing_get_eq_band_audio_mixer,
994 msm_routing_put_eq_band_audio_mixer),
995 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band3", EQ_BAND3,
996 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
997 msm_routing_get_eq_band_audio_mixer,
998 msm_routing_put_eq_band_audio_mixer),
999 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band4", EQ_BAND4,
1000 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
1001 msm_routing_get_eq_band_audio_mixer,
1002 msm_routing_put_eq_band_audio_mixer),
1003 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band5", EQ_BAND5,
1004 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
1005 msm_routing_get_eq_band_audio_mixer,
1006 msm_routing_put_eq_band_audio_mixer),
1007 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band6", EQ_BAND6,
1008 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
1009 msm_routing_get_eq_band_audio_mixer,
1010 msm_routing_put_eq_band_audio_mixer),
1011 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band7", EQ_BAND7,
1012 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
1013 msm_routing_get_eq_band_audio_mixer,
1014 msm_routing_put_eq_band_audio_mixer),
1015 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band8", EQ_BAND8,
1016 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
1017 msm_routing_get_eq_band_audio_mixer,
1018 msm_routing_put_eq_band_audio_mixer),
1019 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band9", EQ_BAND9,
1020 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
1021 msm_routing_get_eq_band_audio_mixer,
1022 msm_routing_put_eq_band_audio_mixer),
1023 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band10", EQ_BAND10,
1024 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
1025 msm_routing_get_eq_band_audio_mixer,
1026 msm_routing_put_eq_band_audio_mixer),
1027 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band11", EQ_BAND11,
1028 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
1029 msm_routing_get_eq_band_audio_mixer,
1030 msm_routing_put_eq_band_audio_mixer),
1031 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band12", EQ_BAND12,
1032 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
1033 msm_routing_get_eq_band_audio_mixer,
1034 msm_routing_put_eq_band_audio_mixer),
1035 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band1", EQ_BAND1,
1036 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1037 msm_routing_get_eq_band_audio_mixer,
1038 msm_routing_put_eq_band_audio_mixer),
1039 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band2", EQ_BAND2,
1040 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1041 msm_routing_get_eq_band_audio_mixer,
1042 msm_routing_put_eq_band_audio_mixer),
1043 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band3", EQ_BAND3,
1044 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1045 msm_routing_get_eq_band_audio_mixer,
1046 msm_routing_put_eq_band_audio_mixer),
1047 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band4", EQ_BAND4,
1048 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1049 msm_routing_get_eq_band_audio_mixer,
1050 msm_routing_put_eq_band_audio_mixer),
1051 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band5", EQ_BAND5,
1052 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1053 msm_routing_get_eq_band_audio_mixer,
1054 msm_routing_put_eq_band_audio_mixer),
1055 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band6", EQ_BAND6,
1056 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1057 msm_routing_get_eq_band_audio_mixer,
1058 msm_routing_put_eq_band_audio_mixer),
1059 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band7", EQ_BAND7,
1060 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1061 msm_routing_get_eq_band_audio_mixer,
1062 msm_routing_put_eq_band_audio_mixer),
1063 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band8", EQ_BAND8,
1064 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1065 msm_routing_get_eq_band_audio_mixer,
1066 msm_routing_put_eq_band_audio_mixer),
1067 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band9", EQ_BAND9,
1068 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1069 msm_routing_get_eq_band_audio_mixer,
1070 msm_routing_put_eq_band_audio_mixer),
1071 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band10", EQ_BAND10,
1072 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1073 msm_routing_get_eq_band_audio_mixer,
1074 msm_routing_put_eq_band_audio_mixer),
1075 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band11", EQ_BAND11,
1076 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1077 msm_routing_get_eq_band_audio_mixer,
1078 msm_routing_put_eq_band_audio_mixer),
1079 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band12", EQ_BAND12,
1080 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
1081 msm_routing_get_eq_band_audio_mixer,
1082 msm_routing_put_eq_band_audio_mixer),
1083 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band1", EQ_BAND1,
1084 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1085 msm_routing_get_eq_band_audio_mixer,
1086 msm_routing_put_eq_band_audio_mixer),
1087 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band2", EQ_BAND2,
1088 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1089 msm_routing_get_eq_band_audio_mixer,
1090 msm_routing_put_eq_band_audio_mixer),
1091 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band3", EQ_BAND3,
1092 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1093 msm_routing_get_eq_band_audio_mixer,
1094 msm_routing_put_eq_band_audio_mixer),
1095 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band4", EQ_BAND4,
1096 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1097 msm_routing_get_eq_band_audio_mixer,
1098 msm_routing_put_eq_band_audio_mixer),
1099 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band5", EQ_BAND5,
1100 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1101 msm_routing_get_eq_band_audio_mixer,
1102 msm_routing_put_eq_band_audio_mixer),
1103 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band6", EQ_BAND6,
1104 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1105 msm_routing_get_eq_band_audio_mixer,
1106 msm_routing_put_eq_band_audio_mixer),
1107 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band7", EQ_BAND7,
1108 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1109 msm_routing_get_eq_band_audio_mixer,
1110 msm_routing_put_eq_band_audio_mixer),
1111 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band8", EQ_BAND8,
1112 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1113 msm_routing_get_eq_band_audio_mixer,
1114 msm_routing_put_eq_band_audio_mixer),
1115 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band9", EQ_BAND9,
1116 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1117 msm_routing_get_eq_band_audio_mixer,
1118 msm_routing_put_eq_band_audio_mixer),
1119 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band10", EQ_BAND10,
1120 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1121 msm_routing_get_eq_band_audio_mixer,
1122 msm_routing_put_eq_band_audio_mixer),
1123 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band11", EQ_BAND11,
1124 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1125 msm_routing_get_eq_band_audio_mixer,
1126 msm_routing_put_eq_band_audio_mixer),
1127 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band12", EQ_BAND12,
1128 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1129 msm_routing_get_eq_band_audio_mixer,
1130 msm_routing_put_eq_band_audio_mixer),
1131};
1132
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001133static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
1134 /* Frontend AIF */
1135 /* Widget name equals to Front-End DAI name<Need confirmation>,
1136 * Stream name must contains substring of front-end dai name
1137 */
1138 SND_SOC_DAPM_AIF_IN("MM_DL1", "MultiMedia1 Playback", 0, 0, 0, 0),
1139 SND_SOC_DAPM_AIF_IN("MM_DL2", "MultiMedia2 Playback", 0, 0, 0, 0),
1140 SND_SOC_DAPM_AIF_IN("MM_DL3", "MultiMedia3 Playback", 0, 0, 0, 0),
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301141 SND_SOC_DAPM_AIF_IN("MM_DL4", "MultiMedia4 Playback", 0, 0, 0, 0),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001142 SND_SOC_DAPM_AIF_IN("VOIP_DL", "VoIP Playback", 0, 0, 0, 0),
1143 SND_SOC_DAPM_AIF_OUT("MM_UL1", "MultiMedia1 Capture", 0, 0, 0, 0),
Jayasena Sangaraboina99fee652011-09-19 07:43:13 -07001144 SND_SOC_DAPM_AIF_OUT("MM_UL2", "MultiMedia2 Capture", 0, 0, 0, 0),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001145 SND_SOC_DAPM_AIF_IN("CS-VOICE_DL1", "CS-VOICE Playback", 0, 0, 0, 0),
1146 SND_SOC_DAPM_AIF_OUT("CS-VOICE_UL1", "CS-VOICE Capture", 0, 0, 0, 0),
1147 SND_SOC_DAPM_AIF_OUT("VOIP_UL", "VoIP Capture", 0, 0, 0, 0),
1148 SND_SOC_DAPM_AIF_IN("SLIM0_DL_HL", "SLIMBUS0_HOSTLESS Playback",
1149 0, 0, 0, 0),
1150 SND_SOC_DAPM_AIF_OUT("SLIM0_UL_HL", "SLIMBUS0_HOSTLESS Capture",
1151 0, 0, 0, 0),
1152 SND_SOC_DAPM_AIF_IN("INTFM_DL_HL", "INT_FM_HOSTLESS Playback",
1153 0, 0, 0, 0),
1154 SND_SOC_DAPM_AIF_OUT("INTFM_UL_HL", "INT_FM_HOSTLESS Capture",
1155 0, 0, 0, 0),
Alex Wongb3d06a02012-01-12 10:00:41 -08001156 SND_SOC_DAPM_AIF_IN("HDMI_DL_HL", "HDMI_HOSTLESS Playback", 0, 0, 0, 0),
1157
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001158 /* Backend AIF */
1159 /* Stream name equals to backend dai link stream name
1160 */
1161 SND_SOC_DAPM_AIF_OUT("PRI_I2S_RX", "Primary I2S Playback", 0, 0, 0, 0),
Kuirong Wang9bbf6132012-01-10 18:28:49 -08001162 SND_SOC_DAPM_AIF_OUT("SEC_I2S_RX", "Secondary I2S Playback",
1163 0, 0, 0 , 0),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001164 SND_SOC_DAPM_AIF_OUT("SLIMBUS_0_RX", "Slimbus Playback", 0, 0, 0, 0),
1165 SND_SOC_DAPM_AIF_OUT("HDMI", "HDMI Playback", 0, 0, 0 , 0),
Kuirong Wang274f21a2011-12-15 21:29:08 -08001166 SND_SOC_DAPM_AIF_OUT("MI2S_RX", "MI2S Playback", 0, 0, 0, 0),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001167 SND_SOC_DAPM_AIF_IN("PRI_I2S_TX", "Primary I2S Capture", 0, 0, 0, 0),
1168 SND_SOC_DAPM_AIF_IN("SLIMBUS_0_TX", "Slimbus Capture", 0, 0, 0, 0),
1169 SND_SOC_DAPM_AIF_OUT("INT_BT_SCO_RX", "Internal BT-SCO Playback",
1170 0, 0, 0 , 0),
1171 SND_SOC_DAPM_AIF_IN("INT_BT_SCO_TX", "Internal BT-SCO Capture",
1172 0, 0, 0, 0),
1173 SND_SOC_DAPM_AIF_OUT("INT_FM_RX", "Internal FM Playback",
1174 0, 0, 0 , 0),
1175 SND_SOC_DAPM_AIF_IN("INT_FM_TX", "Internal FM Capture",
1176 0, 0, 0, 0),
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301177 SND_SOC_DAPM_AIF_OUT("PCM_RX", "AFE Playback",
1178 0, 0, 0 , 0),
1179 SND_SOC_DAPM_AIF_IN("PCM_TX", "AFE Capture",
Helen Zeng0705a5f2011-10-14 15:29:52 -07001180 0, 0, 0 , 0),
1181 /* incall */
1182 SND_SOC_DAPM_AIF_OUT("VOICE_PLAYBACK_TX", "Voice Farend Playback",
1183 0, 0, 0 , 0),
Helen Zenge3d716a2011-10-14 16:32:16 -07001184 SND_SOC_DAPM_AIF_IN("INCALL_RECORD_TX", "Voice Uplink Capture",
1185 0, 0, 0, 0),
1186 SND_SOC_DAPM_AIF_IN("INCALL_RECORD_RX", "Voice Downlink Capture",
1187 0, 0, 0, 0),
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001188 SND_SOC_DAPM_AIF_OUT("AUX_PCM_RX", "AUX PCM Playback", 0, 0, 0, 0),
1189 SND_SOC_DAPM_AIF_IN("AUX_PCM_TX", "AUX PCM Capture", 0, 0, 0, 0),
Sriranjan Srikantama4969dd2011-07-14 00:34:56 -07001190 /* Switch Definitions */
Sriranjan Srikantamdf509d12011-10-24 17:53:27 -07001191 SND_SOC_DAPM_SWITCH("SLIMBUS_DL_HL", SND_SOC_NOPM, 0, 0,
Sriranjan Srikantama4969dd2011-07-14 00:34:56 -07001192 &fm_switch_mixer_controls),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001193 /* Mixer definitions */
1194 SND_SOC_DAPM_MIXER("PRI_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1195 pri_i2s_rx_mixer_controls, ARRAY_SIZE(pri_i2s_rx_mixer_controls)),
Kuirong Wang9bbf6132012-01-10 18:28:49 -08001196 SND_SOC_DAPM_MIXER("SEC_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1197 sec_i2s_rx_mixer_controls, ARRAY_SIZE(sec_i2s_rx_mixer_controls)),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001198 SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1199 slimbus_rx_mixer_controls, ARRAY_SIZE(slimbus_rx_mixer_controls)),
1200 SND_SOC_DAPM_MIXER("HDMI Mixer", SND_SOC_NOPM, 0, 0,
1201 hdmi_mixer_controls, ARRAY_SIZE(hdmi_mixer_controls)),
Kuirong Wang274f21a2011-12-15 21:29:08 -08001202 SND_SOC_DAPM_MIXER("MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1203 mi2s_rx_mixer_controls, ARRAY_SIZE(mi2s_rx_mixer_controls)),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001204 SND_SOC_DAPM_MIXER("MultiMedia1 Mixer", SND_SOC_NOPM, 0, 0,
1205 mmul1_mixer_controls, ARRAY_SIZE(mmul1_mixer_controls)),
Jayasena Sangaraboina99fee652011-09-19 07:43:13 -07001206 SND_SOC_DAPM_MIXER("MultiMedia2 Mixer", SND_SOC_NOPM, 0, 0,
1207 mmul2_mixer_controls, ARRAY_SIZE(mmul2_mixer_controls)),
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001208 SND_SOC_DAPM_MIXER("AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1209 auxpcm_rx_mixer_controls, ARRAY_SIZE(auxpcm_rx_mixer_controls)),
Helen Zeng0705a5f2011-10-14 15:29:52 -07001210 /* incall */
1211 SND_SOC_DAPM_MIXER("Incall_Music Audio Mixer", SND_SOC_NOPM, 0, 0,
1212 incall_music_delivery_mixer_controls,
1213 ARRAY_SIZE(incall_music_delivery_mixer_controls)),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001214 /* Voice Mixer */
1215 SND_SOC_DAPM_MIXER("PRI_RX_Voice Mixer",
1216 SND_SOC_NOPM, 0, 0, pri_rx_voice_mixer_controls,
1217 ARRAY_SIZE(pri_rx_voice_mixer_controls)),
Kuirong Wang9bbf6132012-01-10 18:28:49 -08001218 SND_SOC_DAPM_MIXER("SEC_RX_Voice Mixer",
1219 SND_SOC_NOPM, 0, 0,
1220 sec_i2s_rx_voice_mixer_controls,
1221 ARRAY_SIZE(sec_i2s_rx_voice_mixer_controls)),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001222 SND_SOC_DAPM_MIXER("SLIM_0_RX_Voice Mixer",
1223 SND_SOC_NOPM, 0, 0,
1224 slimbus_rx_voice_mixer_controls,
1225 ARRAY_SIZE(slimbus_rx_voice_mixer_controls)),
1226 SND_SOC_DAPM_MIXER("INTERNAL_BT_SCO_RX_Voice Mixer",
1227 SND_SOC_NOPM, 0, 0,
1228 bt_sco_rx_voice_mixer_controls,
1229 ARRAY_SIZE(bt_sco_rx_voice_mixer_controls)),
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301230 SND_SOC_DAPM_MIXER("AFE_PCM_RX_Voice Mixer",
1231 SND_SOC_NOPM, 0, 0,
1232 afe_pcm_rx_voice_mixer_controls,
1233 ARRAY_SIZE(afe_pcm_rx_voice_mixer_controls)),
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001234 SND_SOC_DAPM_MIXER("AUX_PCM_RX_Voice Mixer",
1235 SND_SOC_NOPM, 0, 0,
1236 aux_pcm_rx_voice_mixer_controls,
1237 ARRAY_SIZE(aux_pcm_rx_voice_mixer_controls)),
Alex Wong593576c2011-11-15 08:03:24 -08001238 SND_SOC_DAPM_MIXER("HDMI_RX_Voice Mixer",
1239 SND_SOC_NOPM, 0, 0,
1240 hdmi_rx_voice_mixer_controls,
1241 ARRAY_SIZE(hdmi_rx_voice_mixer_controls)),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001242 SND_SOC_DAPM_MIXER("Voice_Tx Mixer",
1243 SND_SOC_NOPM, 0, 0, tx_voice_mixer_controls,
1244 ARRAY_SIZE(tx_voice_mixer_controls)),
1245 SND_SOC_DAPM_MIXER("Voip_Tx Mixer",
1246 SND_SOC_NOPM, 0, 0, tx_voip_mixer_controls,
1247 ARRAY_SIZE(tx_voip_mixer_controls)),
1248 SND_SOC_DAPM_MIXER("INTERNAL_BT_SCO_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1249 int_bt_sco_rx_mixer_controls, ARRAY_SIZE(int_bt_sco_rx_mixer_controls)),
1250 SND_SOC_DAPM_MIXER("INTERNAL_FM_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1251 int_fm_rx_mixer_controls, ARRAY_SIZE(int_fm_rx_mixer_controls)),
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301252 SND_SOC_DAPM_MIXER("AFE_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1253 afe_pcm_rx_mixer_controls, ARRAY_SIZE(afe_pcm_rx_mixer_controls)),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001254 SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Port Mixer",
1255 SND_SOC_NOPM, 0, 0, sbus_0_rx_port_mixer_controls,
1256 ARRAY_SIZE(sbus_0_rx_port_mixer_controls)),
1257};
1258
1259static const struct snd_soc_dapm_route intercon[] = {
1260 {"PRI_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1261 {"PRI_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
1262 {"PRI_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301263 {"PRI_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001264 {"PRI_I2S_RX", NULL, "PRI_RX Audio Mixer"},
1265
Kuirong Wang9bbf6132012-01-10 18:28:49 -08001266 {"SEC_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1267 {"SEC_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
1268 {"SEC_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
1269 {"SEC_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
1270 {"SEC_I2S_RX", NULL, "SEC_RX Audio Mixer"},
1271
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001272 {"SLIMBUS_0_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1273 {"SLIMBUS_0_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
1274 {"SLIMBUS_0_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301275 {"SLIMBUS_0_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001276 {"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Audio Mixer"},
1277
1278 {"HDMI Mixer", "MultiMedia1", "MM_DL1"},
1279 {"HDMI Mixer", "MultiMedia2", "MM_DL2"},
Asish Bhattacharyac592eed2011-09-16 17:43:02 +05301280 {"HDMI Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301281 {"HDMI Mixer", "MultiMedia4", "MM_DL4"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001282 {"HDMI", NULL, "HDMI Mixer"},
1283
Helen Zeng0705a5f2011-10-14 15:29:52 -07001284 /* incall */
1285 {"Incall_Music Audio Mixer", "MultiMedia1", "MM_DL1"},
1286 {"Incall_Music Audio Mixer", "MultiMedia2", "MM_DL2"},
1287 {"VOICE_PLAYBACK_TX", NULL, "Incall_Music Audio Mixer"},
Helen Zenge3d716a2011-10-14 16:32:16 -07001288
1289 {"MultiMedia1 Mixer", "VOC_REC_UL", "INCALL_RECORD_TX"},
1290 {"MultiMedia1 Mixer", "VOC_REC_DL", "INCALL_RECORD_RX"},
Kuirong Wang274f21a2011-12-15 21:29:08 -08001291 {"MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1292 {"MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
1293 {"MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
1294 {"MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
1295 {"MI2S_RX", NULL, "MI2S_RX Audio Mixer"},
Helen Zenge3d716a2011-10-14 16:32:16 -07001296
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001297 {"MultiMedia1 Mixer", "PRI_TX", "PRI_I2S_TX"},
1298 {"MultiMedia1 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001299 {"MultiMedia1 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001300
1301 {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1302 {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
Asish Bhattacharyac592eed2011-09-16 17:43:02 +05301303 {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301304 {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001305 {"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX Audio Mixer"},
1306
1307 {"INTERNAL_FM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1308 {"INTERNAL_FM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
Asish Bhattacharyac592eed2011-09-16 17:43:02 +05301309 {"INTERNAL_FM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301310 {"INTERNAL_FM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001311 {"INT_FM_RX", NULL, "INTERNAL_FM_RX Audio Mixer"},
1312
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301313 {"AFE_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1314 {"AFE_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
1315 {"AFE_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301316 {"AFE_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301317 {"PCM_RX", NULL, "AFE_PCM_RX Audio Mixer"},
1318
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001319 {"MultiMedia1 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
1320 {"MultiMedia1 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301321
1322 {"MultiMedia1 Mixer", "AFE_PCM_TX", "PCM_TX"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001323 {"MM_UL1", NULL, "MultiMedia1 Mixer"},
Jayasena Sangaraboina99fee652011-09-19 07:43:13 -07001324 {"MultiMedia2 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
1325 {"MM_UL2", NULL, "MultiMedia2 Mixer"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001326
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001327 {"AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1328 {"AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
1329 {"AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301330 {"AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001331 {"AUX_PCM_RX", NULL, "AUX_PCM_RX Audio Mixer"},
1332
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001333 {"PRI_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1334 {"PRI_RX_Voice Mixer", "Voip", "VOIP_DL"},
1335 {"PRI_I2S_RX", NULL, "PRI_RX_Voice Mixer"},
1336
Kuirong Wang9bbf6132012-01-10 18:28:49 -08001337 {"SEC_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1338 {"SEC_RX_Voice Mixer", "Voip", "VOIP_DL"},
1339 {"SEC_I2S_RX", NULL, "SEC_RX_Voice Mixer"},
1340
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001341 {"SLIM_0_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1342 {"SLIM_0_RX_Voice Mixer", "Voip", "VOIP_DL"},
1343 {"SLIMBUS_0_RX", NULL, "SLIM_0_RX_Voice Mixer"},
1344
1345 {"INTERNAL_BT_SCO_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1346 {"INTERNAL_BT_SCO_RX_Voice Mixer", "Voip", "VOIP_DL"},
1347 {"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX_Voice Mixer"},
1348
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301349 {"AFE_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1350 {"AFE_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"},
1351 {"PCM_RX", NULL, "AFE_PCM_RX_Voice Mixer"},
1352
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001353 {"AUX_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1354 {"AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"},
1355 {"AUX_PCM_RX", NULL, "AUX_PCM_RX_Voice Mixer"},
1356
Alex Wong593576c2011-11-15 08:03:24 -08001357 {"HDMI_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1358 {"HDMI_RX_Voice Mixer", "Voip", "VOIP_DL"},
1359 {"HDMI", NULL, "HDMI_RX_Voice Mixer"},
Alex Wongb3d06a02012-01-12 10:00:41 -08001360 {"HDMI", NULL, "HDMI_DL_HL"},
Alex Wong593576c2011-11-15 08:03:24 -08001361
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001362 {"Voice_Tx Mixer", "PRI_TX_Voice", "PRI_I2S_TX"},
1363 {"Voice_Tx Mixer", "SLIM_0_TX_Voice", "SLIMBUS_0_TX"},
1364 {"Voice_Tx Mixer", "INTERNAL_BT_SCO_TX_Voice", "INT_BT_SCO_TX"},
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301365 {"Voice_Tx Mixer", "AFE_PCM_TX_Voice", "PCM_TX"},
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001366 {"Voice_Tx Mixer", "AUX_PCM_TX_Voice", "AUX_PCM_TX"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001367 {"CS-VOICE_UL1", NULL, "Voice_Tx Mixer"},
1368 {"Voip_Tx Mixer", "PRI_TX_Voip", "PRI_I2S_TX"},
1369 {"Voip_Tx Mixer", "SLIM_0_TX_Voip", "SLIMBUS_0_TX"},
1370 {"Voip_Tx Mixer", "INTERNAL_BT_SCO_TX_Voip", "INT_BT_SCO_TX"},
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301371 {"Voip_Tx Mixer", "AFE_PCM_TX_Voip", "PCM_TX"},
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001372 {"Voip_Tx Mixer", "AUX_PCM_TX_Voip", "AUX_PCM_TX"},
1373
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001374 {"VOIP_UL", NULL, "Voip_Tx Mixer"},
Sriranjan Srikantamdf509d12011-10-24 17:53:27 -07001375 {"SLIMBUS_DL_HL", "Switch", "SLIM0_DL_HL"},
1376 {"SLIMBUS_0_RX", NULL, "SLIMBUS_DL_HL"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001377 {"SLIM0_UL_HL", NULL, "SLIMBUS_0_TX"},
1378 {"INT_FM_RX", NULL, "INTFM_DL_HL"},
1379 {"INTFM_UL_HL", NULL, "INT_FM_TX"},
1380 {"SLIMBUS_0_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
1381 {"SLIMBUS_0_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
1382 {"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Port Mixer"},
1383};
1384
Patrick Laicf999112011-08-23 11:27:20 -07001385static int msm_pcm_routing_hw_params(struct snd_pcm_substream *substream,
1386 struct snd_pcm_hw_params *params)
1387{
1388 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1389 unsigned int be_id = rtd->dai_link->be_id;
1390
Patrick Lai770ca3e42011-12-12 13:44:54 -08001391 if (be_id >= MSM_BACKEND_DAI_MAX) {
1392 pr_err("%s: unexpected be_id %d\n", __func__, be_id);
1393 return -EINVAL;
1394 }
1395
Patrick Laicf999112011-08-23 11:27:20 -07001396 mutex_lock(&routing_lock);
1397 msm_bedais[be_id].hw_params = params;
1398 mutex_unlock(&routing_lock);
1399 return 0;
1400}
1401
1402static int msm_pcm_routing_close(struct snd_pcm_substream *substream)
1403{
1404 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1405 unsigned int be_id = rtd->dai_link->be_id;
1406 int i, session_type;
1407 struct msm_pcm_routing_bdai_data *bedai;
1408
1409 if (be_id >= MSM_BACKEND_DAI_MAX) {
1410 pr_err("%s: unexpected be_id %d\n", __func__, be_id);
1411 return -EINVAL;
1412 }
1413
1414 bedai = &msm_bedais[be_id];
1415
1416 session_type = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
1417 0 : 1);
1418
1419 mutex_lock(&routing_lock);
1420
Asish Bhattacharya70b43c72011-12-29 00:50:38 +05301421 for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MM_SIZE) {
Patrick Laicf999112011-08-23 11:27:20 -07001422 if (fe_dai_map[i][session_type] != INVALID_SESSION)
1423 adm_close(bedai->port_id);
1424 }
1425
1426 bedai->active = 0;
1427 bedai->hw_params = NULL;
1428
1429 mutex_unlock(&routing_lock);
1430
1431 return 0;
1432}
1433
1434static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream)
1435{
1436 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1437 unsigned int be_id = rtd->dai_link->be_id;
1438 int i, path_type, session_type;
1439 struct msm_pcm_routing_bdai_data *bedai;
1440
1441 if (be_id >= MSM_BACKEND_DAI_MAX) {
1442 pr_err("%s: unexpected be_id %d\n", __func__, be_id);
1443 return -EINVAL;
1444 }
1445
1446
1447 bedai = &msm_bedais[be_id];
1448
Jay Wangc8e03a82011-10-31 11:53:23 -07001449 if (bedai->hw_params == NULL) {
1450 pr_err("%s: HW param is not configured", __func__);
1451 return -EINVAL;
1452 }
1453
1454
Patrick Laicf999112011-08-23 11:27:20 -07001455 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1456 path_type = ADM_PATH_PLAYBACK;
1457 session_type = SESSION_TYPE_RX;
1458 } else {
1459 path_type = ADM_PATH_LIVE_REC;
1460 session_type = SESSION_TYPE_TX;
1461 }
1462
1463 mutex_lock(&routing_lock);
1464
1465 if (bedai->active == 1)
1466 goto done; /* Ignore prepare if back-end already active */
1467
1468 /* AFE port is not active at this point. However, still
1469 * go ahead setting active flag under the notion that
1470 * QDSP6 is able to handle ADM starting before AFE port
1471 * is started.
1472 */
1473 bedai->active = 1;
1474
Asish Bhattacharya70b43c72011-12-29 00:50:38 +05301475 for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MM_SIZE) {
Patrick Laicf999112011-08-23 11:27:20 -07001476 if (fe_dai_map[i][session_type] != INVALID_SESSION) {
1477 adm_open(bedai->port_id, path_type,
1478 params_rate(bedai->hw_params),
1479 params_channels(bedai->hw_params),
1480 DEFAULT_COPP_TOPOLOGY);
1481 msm_pcm_routing_build_matrix(i,
1482 fe_dai_map[i][session_type], path_type);
1483 }
1484 }
1485
1486done:
1487 mutex_unlock(&routing_lock);
1488
1489 return 0;
1490}
1491
1492static struct snd_pcm_ops msm_routing_pcm_ops = {
1493 .hw_params = msm_pcm_routing_hw_params,
1494 .close = msm_pcm_routing_close,
1495 .prepare = msm_pcm_routing_prepare,
1496};
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001497
1498static unsigned int msm_routing_read(struct snd_soc_platform *platform,
1499 unsigned int reg)
1500{
1501 dev_dbg(platform->dev, "reg %x\n", reg);
1502 return 0;
1503}
1504
1505/* Not used but frame seems to require it */
1506static int msm_routing_write(struct snd_soc_platform *platform,
1507 unsigned int reg, unsigned int val)
1508{
1509 dev_dbg(platform->dev, "reg %x val %x\n", reg, val);
1510 return 0;
1511}
1512
1513/* Not used but frame seems to require it */
1514static int msm_routing_probe(struct snd_soc_platform *platform)
1515{
1516 snd_soc_dapm_new_controls(&platform->dapm, msm_qdsp6_widgets,
1517 ARRAY_SIZE(msm_qdsp6_widgets));
1518 snd_soc_dapm_add_routes(&platform->dapm, intercon,
1519 ARRAY_SIZE(intercon));
1520
1521 snd_soc_dapm_new_widgets(&platform->dapm);
1522
Jayasena Sangaraboinacb1e22f2011-07-18 10:36:57 -07001523 snd_soc_add_platform_controls(platform,
1524 int_fm_vol_mixer_controls,
1525 ARRAY_SIZE(int_fm_vol_mixer_controls));
Asish Bhattacharya0ec76182011-07-29 16:58:11 +05301526
1527 snd_soc_add_platform_controls(platform,
1528 lpa_vol_mixer_controls,
1529 ARRAY_SIZE(lpa_vol_mixer_controls));
Ben Romberger037dd2f2011-09-22 14:01:32 -07001530
1531 snd_soc_add_platform_controls(platform,
1532 eq_enable_mixer_controls,
1533 ARRAY_SIZE(eq_enable_mixer_controls));
1534
1535 snd_soc_add_platform_controls(platform,
1536 eq_band_mixer_controls,
1537 ARRAY_SIZE(eq_band_mixer_controls));
1538
1539 snd_soc_add_platform_controls(platform,
1540 eq_coeff_mixer_controls,
1541 ARRAY_SIZE(eq_coeff_mixer_controls));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001542 return 0;
1543}
1544
1545static struct snd_soc_platform_driver msm_soc_routing_platform = {
1546 .ops = &msm_routing_pcm_ops,
1547 .probe = msm_routing_probe,
1548 .read = msm_routing_read,
1549 .write = msm_routing_write,
1550};
1551
1552static __devinit int msm_routing_pcm_probe(struct platform_device *pdev)
1553{
1554 dev_dbg(&pdev->dev, "dev name %s\n", dev_name(&pdev->dev));
1555 return snd_soc_register_platform(&pdev->dev,
1556 &msm_soc_routing_platform);
1557}
1558
1559static int msm_routing_pcm_remove(struct platform_device *pdev)
1560{
1561 snd_soc_unregister_platform(&pdev->dev);
1562 return 0;
1563}
1564
1565static struct platform_driver msm_routing_pcm_driver = {
1566 .driver = {
1567 .name = "msm-pcm-routing",
1568 .owner = THIS_MODULE,
1569 },
1570 .probe = msm_routing_pcm_probe,
1571 .remove = __devexit_p(msm_routing_pcm_remove),
1572};
1573
1574static int __init msm_soc_routing_platform_init(void)
1575{
Neema Shettyfeea7742011-09-11 12:30:36 -07001576 mutex_init(&routing_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001577 return platform_driver_register(&msm_routing_pcm_driver);
1578}
1579module_init(msm_soc_routing_platform_init);
1580
1581static void __exit msm_soc_routing_platform_exit(void)
1582{
1583 platform_driver_unregister(&msm_routing_pcm_driver);
1584}
1585module_exit(msm_soc_routing_platform_exit);
1586
1587MODULE_DESCRIPTION("MSM routing platform driver");
1588MODULE_LICENSE("GPL v2");