blob: b254cd892ee2c61ab33daa0a18d77465ab45af86 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13
14#include <linux/init.h>
15#include <linux/err.h>
16#include <linux/module.h>
17#include <linux/moduleparam.h>
18#include <linux/platform_device.h>
19#include <linux/bitops.h>
Neema Shettyfeea7742011-09-11 12:30:36 -070020#include <linux/mutex.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070021#include <sound/core.h>
22#include <sound/soc.h>
23#include <sound/soc-dapm.h>
24#include <sound/pcm.h>
25#include <sound/initval.h>
26#include <sound/control.h>
27#include <sound/q6adm.h>
Ben Romberger037dd2f2011-09-22 14:01:32 -070028#include <sound/q6asm.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070029#include <sound/q6afe.h>
Jayasena Sangaraboinacb1e22f2011-07-18 10:36:57 -070030#include <sound/tlv.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070031#include "msm-pcm-routing.h"
32#include "qdsp6/q6voice.h"
33
Neema Shettyfeea7742011-09-11 12:30:36 -070034struct msm_pcm_routing_bdai_data {
35 u16 port_id; /* AFE port ID */
36 u8 active; /* track if this backend is enabled */
37 struct snd_pcm_hw_params *hw_params; /* to get freq and channel mode */
38 unsigned long fe_sessions; /* Front-end sessions */
39 unsigned long port_sessions; /* track Tx BE ports -> Rx BE */
40};
41
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070042#define INVALID_SESSION -1
Patrick Laicf999112011-08-23 11:27:20 -070043#define SESSION_TYPE_RX 0
44#define SESSION_TYPE_TX 1
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070045
Neema Shettyfeea7742011-09-11 12:30:36 -070046static struct mutex routing_lock;
47
Sriranjan Srikantama4969dd2011-07-14 00:34:56 -070048static int fm_switch_enable;
Jayasena Sangaraboinacb1e22f2011-07-18 10:36:57 -070049#define INT_FM_RX_VOL_MAX_STEPS 100
50#define INT_FM_RX_VOL_GAIN 2000
51
52static int msm_route_fm_vol_control;
53static const DECLARE_TLV_DB_SCALE(fm_rx_vol_gain, 0,
54 INT_FM_RX_VOL_MAX_STEPS, 0);
Sriranjan Srikantama4969dd2011-07-14 00:34:56 -070055
Sriranjan Srikantam269de7f2011-09-06 18:24:45 -070056#define INT_LPA_RX_VOL_MAX_STEPS 100
57#define INT_LPA_RX_VOL_GAIN 0x2000
Asish Bhattacharya0ec76182011-07-29 16:58:11 +053058
59static int msm_route_lpa_vol_control;
60static const DECLARE_TLV_DB_SCALE(lpa_rx_vol_gain, 0,
61 INT_LPA_RX_VOL_MAX_STEPS, 0);
62
Ben Romberger037dd2f2011-09-22 14:01:32 -070063/* Equal to Frontend after last of the MULTIMEDIA SESSIONS */
64#define MAX_EQ_SESSIONS MSM_FRONTEND_DAI_CS_VOICE
65
66enum {
67 EQ_BAND1 = 0,
68 EQ_BAND2,
69 EQ_BAND3,
70 EQ_BAND4,
71 EQ_BAND5,
72 EQ_BAND6,
73 EQ_BAND7,
74 EQ_BAND8,
75 EQ_BAND9,
76 EQ_BAND10,
77 EQ_BAND11,
78 EQ_BAND12,
79 EQ_BAND_MAX,
80};
81
82struct msm_audio_eq_band {
83 uint16_t band_idx; /* The band index, 0 .. 11 */
84 uint32_t filter_type; /* Filter band type */
85 uint32_t center_freq_hz; /* Filter band center frequency */
86 uint32_t filter_gain; /* Filter band initial gain (dB) */
87 /* Range is +12 dB to -12 dB with 1dB increments. */
88 uint32_t q_factor;
89} __packed;
90
91struct msm_audio_eq_stream_config {
92 uint32_t enable; /* Number of consequtive bands specified */
93 uint32_t num_bands;
94 struct msm_audio_eq_band eq_bands[EQ_BAND_MAX];
95} __packed;
96
97struct msm_audio_eq_stream_config eq_data[MAX_EQ_SESSIONS];
98
99static void msm_send_eq_values(int eq_idx);
Neema Shettyfeea7742011-09-11 12:30:36 -0700100/* This array is indexed by back-end DAI ID defined in msm-pcm-routing.h
101 * If new back-end is defined, add new back-end DAI ID at the end of enum
102 */
103static struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = {
104 { PRIMARY_I2S_RX, 0, NULL, 0, 0},
105 { PRIMARY_I2S_TX, 0, NULL, 0, 0},
106 { SLIMBUS_0_RX, 0, NULL, 0, 0},
107 { SLIMBUS_0_TX, 0, NULL, 0, 0},
108 { HDMI_RX, 0, NULL, 0, 0},
109 { INT_BT_SCO_RX, 0, NULL, 0, 0},
110 { INT_BT_SCO_TX, 0, NULL, 0, 0},
111 { INT_FM_RX, 0, NULL, 0, 0},
112 { INT_FM_TX, 0, NULL, 0, 0},
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530113 { RT_PROXY_PORT_001_RX, 0, NULL, 0, 0},
114 { RT_PROXY_PORT_001_TX, 0, NULL, 0, 0},
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700115 { PCM_RX, 0, NULL, 0, 0},
116 { PCM_TX, 0, NULL, 0, 0},
Neema Shettyfeea7742011-09-11 12:30:36 -0700117};
118
119
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700120/* Track ASM playback & capture sessions of DAI */
121static int fe_dai_map[MSM_FRONTEND_DAI_MAX][2] = {
122 /* MULTIMEDIA1 */
123 {INVALID_SESSION, INVALID_SESSION},
124 /* MULTIMEDIA2 */
125 {INVALID_SESSION, INVALID_SESSION},
126 /* MULTIMEDIA3 */
127 {INVALID_SESSION, INVALID_SESSION},
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530128 /* MULTIMEDIA4 */
129 {INVALID_SESSION, INVALID_SESSION},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700130};
131
Patrick Laicf999112011-08-23 11:27:20 -0700132static void msm_pcm_routing_build_matrix(int fedai_id, int dspst_id,
133 int path_type)
134{
135 int i, port_type;
136 struct route_payload payload;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700137
Patrick Laicf999112011-08-23 11:27:20 -0700138 payload.num_copps = 0;
139 port_type = (path_type == ADM_PATH_PLAYBACK ?
140 MSM_AFE_PORT_TYPE_RX : MSM_AFE_PORT_TYPE_TX);
141
142 for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) {
143 if ((afe_get_port_type(msm_bedais[i].port_id) ==
144 port_type) &&
145 msm_bedais[i].active && (test_bit(fedai_id,
146 &msm_bedais[i].fe_sessions)))
147 payload.copp_ids[payload.num_copps++] =
148 msm_bedais[i].port_id;
149 }
150
151 if (payload.num_copps)
152 adm_matrix_map(dspst_id, path_type,
153 payload.num_copps, payload.copp_ids, 0);
154}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700155
156void msm_pcm_routing_reg_phy_stream(int fedai_id, int dspst_id, int stream_type)
157{
Patrick Laicf999112011-08-23 11:27:20 -0700158 int i, session_type, path_type, port_type;
159 struct route_payload payload;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700160
161 if (stream_type == SNDRV_PCM_STREAM_PLAYBACK) {
Patrick Laicf999112011-08-23 11:27:20 -0700162 session_type = SESSION_TYPE_RX;
163 path_type = ADM_PATH_PLAYBACK;
164 port_type = MSM_AFE_PORT_TYPE_RX;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700165 } else {
Patrick Laicf999112011-08-23 11:27:20 -0700166 session_type = SESSION_TYPE_TX;
167 path_type = ADM_PATH_LIVE_REC;
168 port_type = MSM_AFE_PORT_TYPE_TX;
169 }
170
171 mutex_lock(&routing_lock);
172
173 payload.num_copps = 0; /* only RX needs to use payload */
174 fe_dai_map[fedai_id][session_type] = dspst_id;
Ben Romberger037dd2f2011-09-22 14:01:32 -0700175 /* re-enable EQ if active */
176 if (eq_data[fedai_id].enable)
177 msm_send_eq_values(fedai_id);
Patrick Laicf999112011-08-23 11:27:20 -0700178 for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) {
179 if ((afe_get_port_type(msm_bedais[i].port_id) ==
180 port_type) && msm_bedais[i].active &&
181 (test_bit(fedai_id,
182 &msm_bedais[i].fe_sessions))) {
183 adm_open(msm_bedais[i].port_id,
184 path_type,
185 params_rate(msm_bedais[i].hw_params),
186 params_channels(msm_bedais[i].hw_params),
187 DEFAULT_COPP_TOPOLOGY);
188 payload.copp_ids[payload.num_copps++] =
189 msm_bedais[i].port_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700190 }
191 }
Patrick Laicf999112011-08-23 11:27:20 -0700192 if (payload.num_copps)
193 adm_matrix_map(dspst_id, path_type,
194 payload.num_copps, payload.copp_ids, 0);
195
196 mutex_unlock(&routing_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700197}
198
199void msm_pcm_routing_dereg_phy_stream(int fedai_id, int stream_type)
200{
Patrick Laicf999112011-08-23 11:27:20 -0700201 int i, port_type, session_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700202
203 if (stream_type == SNDRV_PCM_STREAM_PLAYBACK) {
Patrick Laicf999112011-08-23 11:27:20 -0700204 port_type = MSM_AFE_PORT_TYPE_RX;
205 session_type = SESSION_TYPE_RX;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700206 } else {
Patrick Laicf999112011-08-23 11:27:20 -0700207 port_type = MSM_AFE_PORT_TYPE_TX;
208 session_type = SESSION_TYPE_TX;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700209 }
Patrick Laicf999112011-08-23 11:27:20 -0700210
211 mutex_lock(&routing_lock);
212
213 for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) {
214 if ((afe_get_port_type(msm_bedais[i].port_id) ==
215 port_type) && msm_bedais[i].active &&
216 (test_bit(fedai_id,
217 &msm_bedais[i].fe_sessions)))
218 adm_close(msm_bedais[i].port_id);
219 }
220
221 fe_dai_map[fedai_id][session_type] = INVALID_SESSION;
222
223 mutex_unlock(&routing_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700224}
225
226static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set)
227{
Patrick Laicf999112011-08-23 11:27:20 -0700228 int session_type, path_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700229
230 pr_debug("%s: reg %x val %x set %x\n", __func__, reg, val, set);
231
Patrick Laicf999112011-08-23 11:27:20 -0700232 if (afe_get_port_type(msm_bedais[reg].port_id) ==
233 MSM_AFE_PORT_TYPE_RX) {
234 session_type = SESSION_TYPE_RX;
235 path_type = ADM_PATH_PLAYBACK;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700236 } else {
Patrick Laicf999112011-08-23 11:27:20 -0700237 session_type = SESSION_TYPE_TX;
238 path_type = ADM_PATH_LIVE_REC;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700239 }
Patrick Laicf999112011-08-23 11:27:20 -0700240
241 mutex_lock(&routing_lock);
242
243 if (set) {
244 set_bit(val, &msm_bedais[reg].fe_sessions);
245 if (msm_bedais[reg].active && fe_dai_map[val][session_type] !=
246 INVALID_SESSION) {
247 adm_open(msm_bedais[reg].port_id, path_type,
248 params_rate(msm_bedais[reg].hw_params),
249 params_channels(msm_bedais[reg].hw_params),
250 DEFAULT_COPP_TOPOLOGY);
251 msm_pcm_routing_build_matrix(val,
252 fe_dai_map[val][session_type], path_type);
253 }
254 } else {
255 clear_bit(val, &msm_bedais[reg].fe_sessions);
256 if (msm_bedais[reg].active && fe_dai_map[val][session_type] !=
257 INVALID_SESSION) {
258 adm_close(msm_bedais[reg].port_id);
259 msm_pcm_routing_build_matrix(val,
260 fe_dai_map[val][session_type], path_type);
261 }
262 }
263
264 mutex_unlock(&routing_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700265}
266
267static int msm_routing_get_audio_mixer(struct snd_kcontrol *kcontrol,
268 struct snd_ctl_elem_value *ucontrol)
269{
270 struct soc_mixer_control *mc =
271 (struct soc_mixer_control *)kcontrol->private_value;
272
Patrick Laicf999112011-08-23 11:27:20 -0700273 if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700274 ucontrol->value.integer.value[0] = 1;
275 else
276 ucontrol->value.integer.value[0] = 0;
277
278 pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift,
279 ucontrol->value.integer.value[0]);
280
281 return 0;
282}
283
284static int msm_routing_put_audio_mixer(struct snd_kcontrol *kcontrol,
285 struct snd_ctl_elem_value *ucontrol)
286{
Patrick Laiec2b8942011-09-01 11:01:51 -0700287 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
288 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700289 struct soc_mixer_control *mc =
290 (struct soc_mixer_control *)kcontrol->private_value;
291
292
293 if (ucontrol->value.integer.value[0]) {
294 msm_pcm_routing_process_audio(mc->reg, mc->shift, 1);
295 snd_soc_dapm_mixer_update_power(widget, kcontrol, 1);
296 } else {
297 msm_pcm_routing_process_audio(mc->reg, mc->shift, 0);
298 snd_soc_dapm_mixer_update_power(widget, kcontrol, 0);
299 }
300
301 return 1;
302}
303
Neema Shettyfeea7742011-09-11 12:30:36 -0700304static void msm_pcm_routing_process_voice(u16 reg, u16 val, int set)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700305{
Neema Shetty2c07eb52011-08-21 20:33:52 -0700306 u16 session_id = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700307
Neema Shettyfeea7742011-09-11 12:30:36 -0700308 pr_debug("%s: reg %x val %x set %x\n", __func__, reg, val, set);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700309
Neema Shettyfeea7742011-09-11 12:30:36 -0700310 if (val == MSM_FRONTEND_DAI_CS_VOICE)
Neema Shetty2c07eb52011-08-21 20:33:52 -0700311 session_id = voc_get_session_id(VOICE_SESSION_NAME);
312 else
313 session_id = voc_get_session_id(VOIP_SESSION_NAME);
314
315 pr_debug("%s: FE DAI 0x%x session_id 0x%x\n",
Neema Shettyfeea7742011-09-11 12:30:36 -0700316 __func__, val, session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700317
Neema Shettyfeea7742011-09-11 12:30:36 -0700318 mutex_lock(&routing_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700319
320 if (set)
Neema Shettyfeea7742011-09-11 12:30:36 -0700321 set_bit(val, &msm_bedais[reg].fe_sessions);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700322 else
Neema Shettyfeea7742011-09-11 12:30:36 -0700323 clear_bit(val, &msm_bedais[reg].fe_sessions);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700324
Neema Shettyfeea7742011-09-11 12:30:36 -0700325 mutex_unlock(&routing_lock);
326
327 if (afe_get_port_type(msm_bedais[reg].port_id) ==
328 MSM_AFE_PORT_TYPE_RX) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700329 voc_set_route_flag(session_id, RX_PATH, set);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700330 if (set) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700331 voc_set_rxtx_port(session_id,
Neema Shettyfeea7742011-09-11 12:30:36 -0700332 msm_bedais[reg].port_id, DEV_RX);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700333
Neema Shetty2c07eb52011-08-21 20:33:52 -0700334 if (voc_get_route_flag(session_id, RX_PATH) &&
335 voc_get_route_flag(session_id, TX_PATH))
336 voc_enable_cvp(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700337 } else {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700338 voc_disable_cvp(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700339 }
340 } else {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700341 voc_set_route_flag(session_id, TX_PATH, set);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700342 if (set) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700343 voc_set_rxtx_port(session_id,
Neema Shettyfeea7742011-09-11 12:30:36 -0700344 msm_bedais[reg].port_id, DEV_TX);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700345 if (voc_get_route_flag(session_id, RX_PATH) &&
346 voc_get_route_flag(session_id, TX_PATH))
347 voc_enable_cvp(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700348 } else {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700349 voc_disable_cvp(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700350 }
351 }
352}
353
354static int msm_routing_get_voice_mixer(struct snd_kcontrol *kcontrol,
355 struct snd_ctl_elem_value *ucontrol)
356{
357 struct soc_mixer_control *mc =
358 (struct soc_mixer_control *)kcontrol->private_value;
359
Neema Shettyfeea7742011-09-11 12:30:36 -0700360 mutex_lock(&routing_lock);
361
362 if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700363 ucontrol->value.integer.value[0] = 1;
364 else
365 ucontrol->value.integer.value[0] = 0;
366
Neema Shettyfeea7742011-09-11 12:30:36 -0700367 mutex_unlock(&routing_lock);
368
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700369 pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift,
370 ucontrol->value.integer.value[0]);
371
372 return 0;
373}
374
375static int msm_routing_put_voice_mixer(struct snd_kcontrol *kcontrol,
376 struct snd_ctl_elem_value *ucontrol)
377{
Patrick Laiec2b8942011-09-01 11:01:51 -0700378 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
379 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700380 struct soc_mixer_control *mc =
381 (struct soc_mixer_control *)kcontrol->private_value;
382
383 if (ucontrol->value.integer.value[0]) {
Neema Shettyfeea7742011-09-11 12:30:36 -0700384 msm_pcm_routing_process_voice(mc->reg, mc->shift, 1);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700385 snd_soc_dapm_mixer_update_power(widget, kcontrol, 1);
386 } else {
Neema Shettyfeea7742011-09-11 12:30:36 -0700387 msm_pcm_routing_process_voice(mc->reg, mc->shift, 0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700388 snd_soc_dapm_mixer_update_power(widget, kcontrol, 0);
389 }
390
391 return 1;
392}
393
Sriranjan Srikantama4969dd2011-07-14 00:34:56 -0700394static int msm_routing_get_switch_mixer(struct snd_kcontrol *kcontrol,
395 struct snd_ctl_elem_value *ucontrol)
396{
397 ucontrol->value.integer.value[0] = fm_switch_enable;
398 pr_debug("%s: FM Switch enable %ld\n", __func__,
399 ucontrol->value.integer.value[0]);
400 return 0;
401}
402
403static int msm_routing_put_switch_mixer(struct snd_kcontrol *kcontrol,
404 struct snd_ctl_elem_value *ucontrol)
405{
Sriranjan Srikantamdf509d12011-10-24 17:53:27 -0700406 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
407 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
Sriranjan Srikantama4969dd2011-07-14 00:34:56 -0700408
409 pr_debug("%s: FM Switch enable %ld\n", __func__,
410 ucontrol->value.integer.value[0]);
411 if (ucontrol->value.integer.value[0])
412 snd_soc_dapm_mixer_update_power(widget, kcontrol, 1);
413 else
414 snd_soc_dapm_mixer_update_power(widget, kcontrol, 0);
415 fm_switch_enable = ucontrol->value.integer.value[0];
416 return 1;
417}
418
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700419static int msm_routing_get_port_mixer(struct snd_kcontrol *kcontrol,
420 struct snd_ctl_elem_value *ucontrol)
421{
422 struct soc_mixer_control *mc =
423 (struct soc_mixer_control *)kcontrol->private_value;
424
Patrick Laicf999112011-08-23 11:27:20 -0700425 if (test_bit(mc->shift, &msm_bedais[mc->reg].port_sessions))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700426 ucontrol->value.integer.value[0] = 1;
427 else
428 ucontrol->value.integer.value[0] = 0;
429
430 pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift,
431 ucontrol->value.integer.value[0]);
432
433 return 0;
434}
435
436static int msm_routing_put_port_mixer(struct snd_kcontrol *kcontrol,
437 struct snd_ctl_elem_value *ucontrol)
438{
439 struct soc_mixer_control *mc =
440 (struct soc_mixer_control *)kcontrol->private_value;
441
442 pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg,
443 mc->shift, ucontrol->value.integer.value[0]);
444
445 if (ucontrol->value.integer.value[0]) {
Patrick Laicf999112011-08-23 11:27:20 -0700446 afe_loopback(1, msm_bedais[mc->reg].port_id,
447 msm_bedais[mc->shift].port_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700448 set_bit(mc->shift,
Patrick Laicf999112011-08-23 11:27:20 -0700449 &msm_bedais[mc->reg].port_sessions);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700450 } else {
Patrick Laicf999112011-08-23 11:27:20 -0700451 afe_loopback(0, msm_bedais[mc->reg].port_id,
452 msm_bedais[mc->shift].port_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700453 clear_bit(mc->shift,
Patrick Laicf999112011-08-23 11:27:20 -0700454 &msm_bedais[mc->reg].port_sessions);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700455 }
456
457 return 1;
458}
459
Jayasena Sangaraboinacb1e22f2011-07-18 10:36:57 -0700460static int msm_routing_get_fm_vol_mixer(struct snd_kcontrol *kcontrol,
461 struct snd_ctl_elem_value *ucontrol)
462{
463 ucontrol->value.integer.value[0] = msm_route_fm_vol_control;
464 return 0;
465}
466
467static int msm_routing_set_fm_vol_mixer(struct snd_kcontrol *kcontrol,
468 struct snd_ctl_elem_value *ucontrol)
469{
470 afe_loopback_gain(INT_FM_TX , ucontrol->value.integer.value[0]);
471
472 msm_route_fm_vol_control = ucontrol->value.integer.value[0];
473
474 return 0;
475}
476
Asish Bhattacharya0ec76182011-07-29 16:58:11 +0530477static int msm_routing_get_lpa_vol_mixer(struct snd_kcontrol *kcontrol,
478 struct snd_ctl_elem_value *ucontrol)
479{
480 ucontrol->value.integer.value[0] = msm_route_lpa_vol_control;
481 return 0;
482}
483
484static int msm_routing_set_lpa_vol_mixer(struct snd_kcontrol *kcontrol,
485 struct snd_ctl_elem_value *ucontrol)
486{
487 if (!lpa_set_volume(ucontrol->value.integer.value[0]))
488 msm_route_lpa_vol_control =
489 ucontrol->value.integer.value[0];
490
491 return 0;
492}
493
Ben Romberger037dd2f2011-09-22 14:01:32 -0700494static void msm_send_eq_values(int eq_idx)
495{
496 int result;
497 struct audio_client *ac =
498 q6asm_get_audio_client(fe_dai_map[eq_idx][SESSION_TYPE_RX]);
499
500 if (ac == NULL) {
501 pr_err("%s: Could not get audio client for session: %d\n",
502 __func__, fe_dai_map[eq_idx][SESSION_TYPE_RX]);
503 goto done;
504 }
505
506 result = q6asm_equalizer(ac, &eq_data[eq_idx]);
507
508 if (result < 0)
509 pr_err("%s: Call to ASM equalizer failed, returned = %d\n",
510 __func__, result);
511done:
512 return;
513}
514
515static int msm_routing_get_eq_enable_mixer(struct snd_kcontrol *kcontrol,
516 struct snd_ctl_elem_value *ucontrol)
517{
518 int eq_idx = ((struct soc_multi_mixer_control *)
519 kcontrol->private_value)->reg;
520
Ben Romberger76f57032011-12-08 20:07:34 -0800521 ucontrol->value.integer.value[0] = eq_data[eq_idx].enable;
522
Ben Romberger037dd2f2011-09-22 14:01:32 -0700523 pr_debug("%s: EQ #%d enable %d\n", __func__,
524 eq_idx, eq_data[eq_idx].enable);
Ben Romberger76f57032011-12-08 20:07:34 -0800525 return 0;
Ben Romberger037dd2f2011-09-22 14:01:32 -0700526}
527
528static int msm_routing_put_eq_enable_mixer(struct snd_kcontrol *kcontrol,
529 struct snd_ctl_elem_value *ucontrol)
530{
531 int eq_idx = ((struct soc_multi_mixer_control *)
532 kcontrol->private_value)->reg;
533 int value = ucontrol->value.integer.value[0];
534
535 pr_debug("%s: EQ #%d enable %d\n", __func__,
536 eq_idx, value);
537 eq_data[eq_idx].enable = value;
538
539 msm_send_eq_values(eq_idx);
540 return 0;
541}
542
543static int msm_routing_get_eq_band_count_audio_mixer(
544 struct snd_kcontrol *kcontrol,
545 struct snd_ctl_elem_value *ucontrol)
546{
547 int eq_idx = ((struct soc_multi_mixer_control *)
548 kcontrol->private_value)->reg;
549
Ben Romberger76f57032011-12-08 20:07:34 -0800550 ucontrol->value.integer.value[0] = eq_data[eq_idx].num_bands;
551
Ben Romberger037dd2f2011-09-22 14:01:32 -0700552 pr_debug("%s: EQ #%d bands %d\n", __func__,
553 eq_idx, eq_data[eq_idx].num_bands);
554 return eq_data[eq_idx].num_bands;
555}
556
557static int msm_routing_put_eq_band_count_audio_mixer(
558 struct snd_kcontrol *kcontrol,
559 struct snd_ctl_elem_value *ucontrol)
560{
561 int eq_idx = ((struct soc_multi_mixer_control *)
562 kcontrol->private_value)->reg;
563 int value = ucontrol->value.integer.value[0];
564
Ben Romberger037dd2f2011-09-22 14:01:32 -0700565 pr_debug("%s: EQ #%d bands %d\n", __func__,
566 eq_idx, value);
567 eq_data[eq_idx].num_bands = value;
568 return 0;
569}
570
571static int msm_routing_get_eq_band_audio_mixer(struct snd_kcontrol *kcontrol,
572 struct snd_ctl_elem_value *ucontrol)
573{
574 int eq_idx = ((struct soc_multi_mixer_control *)
575 kcontrol->private_value)->reg;
576 int band_idx = ((struct soc_multi_mixer_control *)
577 kcontrol->private_value)->shift;
578
Ben Romberger76f57032011-12-08 20:07:34 -0800579 ucontrol->value.integer.value[0] =
580 eq_data[eq_idx].eq_bands[band_idx].band_idx;
581 ucontrol->value.integer.value[1] =
582 eq_data[eq_idx].eq_bands[band_idx].filter_type;
583 ucontrol->value.integer.value[2] =
584 eq_data[eq_idx].eq_bands[band_idx].center_freq_hz;
585 ucontrol->value.integer.value[3] =
586 eq_data[eq_idx].eq_bands[band_idx].filter_gain;
587 ucontrol->value.integer.value[4] =
588 eq_data[eq_idx].eq_bands[band_idx].q_factor;
589
Ben Romberger037dd2f2011-09-22 14:01:32 -0700590 pr_debug("%s: band_idx = %d\n", __func__,
591 eq_data[eq_idx].eq_bands[band_idx].band_idx);
592 pr_debug("%s: filter_type = %d\n", __func__,
593 eq_data[eq_idx].eq_bands[band_idx].filter_type);
594 pr_debug("%s: center_freq_hz = %d\n", __func__,
595 eq_data[eq_idx].eq_bands[band_idx].center_freq_hz);
596 pr_debug("%s: filter_gain = %d\n", __func__,
597 eq_data[eq_idx].eq_bands[band_idx].filter_gain);
598 pr_debug("%s: q_factor = %d\n", __func__,
599 eq_data[eq_idx].eq_bands[band_idx].q_factor);
600 return 0;
601}
602
603static int msm_routing_put_eq_band_audio_mixer(struct snd_kcontrol *kcontrol,
604 struct snd_ctl_elem_value *ucontrol)
605{
606 int eq_idx = ((struct soc_multi_mixer_control *)
607 kcontrol->private_value)->reg;
608 int band_idx = ((struct soc_multi_mixer_control *)
609 kcontrol->private_value)->shift;
610
611 eq_data[eq_idx].eq_bands[band_idx].band_idx =
612 ucontrol->value.integer.value[0];
613 eq_data[eq_idx].eq_bands[band_idx].filter_type =
614 ucontrol->value.integer.value[1];
615 eq_data[eq_idx].eq_bands[band_idx].center_freq_hz =
616 ucontrol->value.integer.value[2];
617 eq_data[eq_idx].eq_bands[band_idx].filter_gain =
618 ucontrol->value.integer.value[3];
619 eq_data[eq_idx].eq_bands[band_idx].q_factor =
620 ucontrol->value.integer.value[4];
621 return 0;
622}
623
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700624static const struct snd_kcontrol_new pri_i2s_rx_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700625 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_PRI_I2S_RX ,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700626 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
627 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700628 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_PRI_I2S_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700629 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
630 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700631 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_PRI_I2S_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700632 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
633 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530634 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_PRI_I2S_RX,
635 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
636 msm_routing_put_audio_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700637};
638
639static const struct snd_kcontrol_new slimbus_rx_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700640 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SLIMBUS_0_RX ,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700641 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
642 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700643 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SLIMBUS_0_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700644 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
645 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700646 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SLIMBUS_0_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700647 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
648 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530649 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SLIMBUS_0_RX,
650 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
651 msm_routing_put_audio_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700652};
653
654static const struct snd_kcontrol_new hdmi_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700655 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_HDMI_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700656 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
657 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700658 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_HDMI_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700659 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
660 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700661 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_HDMI_RX,
Asish Bhattacharyac592eed2011-09-16 17:43:02 +0530662 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
663 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530664 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_HDMI_RX,
665 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
666 msm_routing_put_audio_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700667};
668
669static const struct snd_kcontrol_new int_bt_sco_rx_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700670 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_INT_BT_SCO_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700671 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
672 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700673 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_INT_BT_SCO_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700674 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
675 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700676 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_INT_BT_SCO_RX,
Asish Bhattacharyac592eed2011-09-16 17:43:02 +0530677 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
678 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530679 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_INT_BT_SCO_RX,
680 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
681 msm_routing_put_audio_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700682};
683
684static const struct snd_kcontrol_new int_fm_rx_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700685 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_INT_FM_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700686 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
687 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700688 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_INT_FM_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700689 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
690 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700691 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_INT_FM_RX,
Asish Bhattacharyac592eed2011-09-16 17:43:02 +0530692 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
693 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530694 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_INT_FM_RX,
695 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
696 msm_routing_put_audio_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700697};
698
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530699static const struct snd_kcontrol_new afe_pcm_rx_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700700 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_AFE_PCM_RX,
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530701 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
702 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700703 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_AFE_PCM_RX,
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530704 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
705 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700706 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_AFE_PCM_RX,
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530707 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
708 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530709 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_AFE_PCM_RX,
710 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
711 msm_routing_put_audio_mixer),
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530712};
713
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700714static const struct snd_kcontrol_new auxpcm_rx_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700715 SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_AUXPCM_RX,
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700716 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
717 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700718 SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_AUXPCM_RX,
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700719 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
720 msm_routing_put_audio_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700721 SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_AUXPCM_RX,
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700722 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
723 msm_routing_put_audio_mixer),
Asish Bhattacharya305d1752011-11-01 20:38:26 +0530724 SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_AUXPCM_RX,
725 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
726 msm_routing_put_audio_mixer),
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700727};
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530728
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700729static const struct snd_kcontrol_new mmul1_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700730 SOC_SINGLE_EXT("PRI_TX", MSM_BACKEND_DAI_PRI_I2S_TX,
731 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
732 msm_routing_put_audio_mixer),
733 SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX,
734 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
735 msm_routing_put_audio_mixer),
736 SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_AUXPCM_TX,
737 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
738 msm_routing_put_audio_mixer),
739 SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX,
740 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
741 msm_routing_put_audio_mixer),
742 SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX,
743 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
744 msm_routing_put_audio_mixer),
745 SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX,
746 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
747 msm_routing_put_audio_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700748};
749
Jayasena Sangaraboina99fee652011-09-19 07:43:13 -0700750static const struct snd_kcontrol_new mmul2_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700751 SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX,
752 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
Jayasena Sangaraboina99fee652011-09-19 07:43:13 -0700753 msm_routing_put_audio_mixer),
754};
755
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700756static const struct snd_kcontrol_new pri_rx_voice_mixer_controls[] = {
Neema Shettyfeea7742011-09-11 12:30:36 -0700757 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_PRI_I2S_RX,
758 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
759 msm_routing_put_voice_mixer),
760 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_PRI_I2S_RX,
761 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
762 msm_routing_put_voice_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700763};
764
765static const struct snd_kcontrol_new slimbus_rx_voice_mixer_controls[] = {
Neema Shettyfeea7742011-09-11 12:30:36 -0700766 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_SLIMBUS_0_RX,
767 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
768 msm_routing_put_voice_mixer),
769 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SLIMBUS_0_RX ,
770 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
771 msm_routing_put_voice_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700772};
773
774static const struct snd_kcontrol_new bt_sco_rx_voice_mixer_controls[] = {
Neema Shettyfeea7742011-09-11 12:30:36 -0700775 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_INT_BT_SCO_RX,
776 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
777 msm_routing_put_voice_mixer),
778 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_INT_BT_SCO_RX ,
779 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
780 msm_routing_put_voice_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700781};
782
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530783static const struct snd_kcontrol_new afe_pcm_rx_voice_mixer_controls[] = {
784 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_AFE_PCM_RX,
785 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
786 msm_routing_put_voice_mixer),
787 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_AFE_PCM_RX,
788 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
789 msm_routing_put_voice_mixer),
790};
791
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700792static const struct snd_kcontrol_new aux_pcm_rx_voice_mixer_controls[] = {
793 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_AUXPCM_RX,
794 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
795 msm_routing_put_voice_mixer),
796 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_AUXPCM_RX,
797 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
798 msm_routing_put_voice_mixer),
799};
800
Alex Wong593576c2011-11-15 08:03:24 -0800801static const struct snd_kcontrol_new hdmi_rx_voice_mixer_controls[] = {
802 SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_HDMI_RX,
803 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
804 msm_routing_put_voice_mixer),
805 SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_HDMI_RX,
806 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
807 msm_routing_put_voice_mixer),
808};
809
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700810static const struct snd_kcontrol_new tx_voice_mixer_controls[] = {
Neema Shettyfeea7742011-09-11 12:30:36 -0700811 SOC_SINGLE_EXT("PRI_TX_Voice", MSM_BACKEND_DAI_PRI_I2S_TX,
812 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
813 msm_routing_put_voice_mixer),
814 SOC_SINGLE_EXT("SLIM_0_TX_Voice", MSM_BACKEND_DAI_SLIMBUS_0_TX,
815 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
816 msm_routing_put_voice_mixer),
817 SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_Voice",
818 MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_CS_VOICE, 1, 0,
Neema Shetty2c07eb52011-08-21 20:33:52 -0700819 msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530820 SOC_SINGLE_EXT("AFE_PCM_TX_Voice", MSM_BACKEND_DAI_AFE_PCM_TX,
821 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
822 msm_routing_put_voice_mixer),
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700823 SOC_SINGLE_EXT("AUX_PCM_TX_Voice", MSM_BACKEND_DAI_AUXPCM_TX,
824 MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
825 msm_routing_put_voice_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700826};
827
828static const struct snd_kcontrol_new tx_voip_mixer_controls[] = {
Neema Shettyfeea7742011-09-11 12:30:36 -0700829 SOC_SINGLE_EXT("PRI_TX_Voip", MSM_BACKEND_DAI_PRI_I2S_TX,
830 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
831 msm_routing_put_voice_mixer),
832 SOC_SINGLE_EXT("SLIM_0_TX_Voip", MSM_BACKEND_DAI_SLIMBUS_0_TX,
833 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
834 msm_routing_put_voice_mixer),
835 SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_Voip", MSM_BACKEND_DAI_INT_BT_SCO_TX,
836 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
837 msm_routing_put_voice_mixer),
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530838 SOC_SINGLE_EXT("AFE_PCM_TX_Voip", MSM_BACKEND_DAI_AFE_PCM_TX,
839 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
840 msm_routing_put_voice_mixer),
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700841 SOC_SINGLE_EXT("AUX_PCM_TX_Voip", MSM_BACKEND_DAI_AUXPCM_TX,
842 MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
843 msm_routing_put_voice_mixer),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700844};
845
846static const struct snd_kcontrol_new sbus_0_rx_port_mixer_controls[] = {
Patrick Laicf999112011-08-23 11:27:20 -0700847 SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700848 MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer,
849 msm_routing_put_port_mixer),
Patrick Laicf999112011-08-23 11:27:20 -0700850 SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700851 MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer,
852 msm_routing_put_port_mixer),
853};
854
Sriranjan Srikantama4969dd2011-07-14 00:34:56 -0700855static const struct snd_kcontrol_new fm_switch_mixer_controls =
856 SOC_SINGLE_EXT("Switch", SND_SOC_NOPM,
857 0, 1, 0, msm_routing_get_switch_mixer,
858 msm_routing_put_switch_mixer);
859
Jayasena Sangaraboinacb1e22f2011-07-18 10:36:57 -0700860static const struct snd_kcontrol_new int_fm_vol_mixer_controls[] = {
861 SOC_SINGLE_EXT_TLV("Internal FM RX Volume", SND_SOC_NOPM, 0,
862 INT_FM_RX_VOL_GAIN, 0, msm_routing_get_fm_vol_mixer,
863 msm_routing_set_fm_vol_mixer, fm_rx_vol_gain),
864};
865
Asish Bhattacharya0ec76182011-07-29 16:58:11 +0530866static const struct snd_kcontrol_new lpa_vol_mixer_controls[] = {
867 SOC_SINGLE_EXT_TLV("LPA RX Volume", SND_SOC_NOPM, 0,
868 INT_LPA_RX_VOL_GAIN, 0, msm_routing_get_lpa_vol_mixer,
869 msm_routing_set_lpa_vol_mixer, lpa_rx_vol_gain),
870};
871
Ben Romberger037dd2f2011-09-22 14:01:32 -0700872static const struct snd_kcontrol_new eq_enable_mixer_controls[] = {
873 SOC_SINGLE_EXT("MultiMedia1 EQ Enable", SND_SOC_NOPM,
874 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_eq_enable_mixer,
875 msm_routing_put_eq_enable_mixer),
876 SOC_SINGLE_EXT("MultiMedia2 EQ Enable", SND_SOC_NOPM,
877 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_eq_enable_mixer,
878 msm_routing_put_eq_enable_mixer),
879 SOC_SINGLE_EXT("MultiMedia3 EQ Enable", SND_SOC_NOPM,
880 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_eq_enable_mixer,
881 msm_routing_put_eq_enable_mixer),
882};
883
884static const struct snd_kcontrol_new eq_band_mixer_controls[] = {
885 SOC_SINGLE_EXT("MultiMedia1 EQ Band Count", SND_SOC_NOPM,
886 MSM_FRONTEND_DAI_MULTIMEDIA1, 11, 0,
887 msm_routing_get_eq_band_count_audio_mixer,
888 msm_routing_put_eq_band_count_audio_mixer),
889 SOC_SINGLE_EXT("MultiMedia2 EQ Band Count", SND_SOC_NOPM,
890 MSM_FRONTEND_DAI_MULTIMEDIA2, 11, 0,
891 msm_routing_get_eq_band_count_audio_mixer,
892 msm_routing_put_eq_band_count_audio_mixer),
893 SOC_SINGLE_EXT("MultiMedia3 EQ Band Count", SND_SOC_NOPM,
894 MSM_FRONTEND_DAI_MULTIMEDIA3, 11, 0,
895 msm_routing_get_eq_band_count_audio_mixer,
896 msm_routing_put_eq_band_count_audio_mixer),
897};
898
899static const struct snd_kcontrol_new eq_coeff_mixer_controls[] = {
900 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band1", EQ_BAND1,
901 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
902 msm_routing_get_eq_band_audio_mixer,
903 msm_routing_put_eq_band_audio_mixer),
904 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band2", EQ_BAND2,
905 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
906 msm_routing_get_eq_band_audio_mixer,
907 msm_routing_put_eq_band_audio_mixer),
908 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band3", EQ_BAND3,
909 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
910 msm_routing_get_eq_band_audio_mixer,
911 msm_routing_put_eq_band_audio_mixer),
912 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band4", EQ_BAND4,
913 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
914 msm_routing_get_eq_band_audio_mixer,
915 msm_routing_put_eq_band_audio_mixer),
916 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band5", EQ_BAND5,
917 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
918 msm_routing_get_eq_band_audio_mixer,
919 msm_routing_put_eq_band_audio_mixer),
920 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band6", EQ_BAND6,
921 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
922 msm_routing_get_eq_band_audio_mixer,
923 msm_routing_put_eq_band_audio_mixer),
924 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band7", EQ_BAND7,
925 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
926 msm_routing_get_eq_band_audio_mixer,
927 msm_routing_put_eq_band_audio_mixer),
928 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band8", EQ_BAND8,
929 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
930 msm_routing_get_eq_band_audio_mixer,
931 msm_routing_put_eq_band_audio_mixer),
932 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band9", EQ_BAND9,
933 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
934 msm_routing_get_eq_band_audio_mixer,
935 msm_routing_put_eq_band_audio_mixer),
936 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band10", EQ_BAND10,
937 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
938 msm_routing_get_eq_band_audio_mixer,
939 msm_routing_put_eq_band_audio_mixer),
940 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band11", EQ_BAND11,
941 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
942 msm_routing_get_eq_band_audio_mixer,
943 msm_routing_put_eq_band_audio_mixer),
944 SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band12", EQ_BAND12,
945 MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5,
946 msm_routing_get_eq_band_audio_mixer,
947 msm_routing_put_eq_band_audio_mixer),
948 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band1", EQ_BAND1,
949 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
950 msm_routing_get_eq_band_audio_mixer,
951 msm_routing_put_eq_band_audio_mixer),
952 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band2", EQ_BAND2,
953 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
954 msm_routing_get_eq_band_audio_mixer,
955 msm_routing_put_eq_band_audio_mixer),
956 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band3", EQ_BAND3,
957 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
958 msm_routing_get_eq_band_audio_mixer,
959 msm_routing_put_eq_band_audio_mixer),
960 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band4", EQ_BAND4,
961 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
962 msm_routing_get_eq_band_audio_mixer,
963 msm_routing_put_eq_band_audio_mixer),
964 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band5", EQ_BAND5,
965 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
966 msm_routing_get_eq_band_audio_mixer,
967 msm_routing_put_eq_band_audio_mixer),
968 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band6", EQ_BAND6,
969 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
970 msm_routing_get_eq_band_audio_mixer,
971 msm_routing_put_eq_band_audio_mixer),
972 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band7", EQ_BAND7,
973 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
974 msm_routing_get_eq_band_audio_mixer,
975 msm_routing_put_eq_band_audio_mixer),
976 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band8", EQ_BAND8,
977 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
978 msm_routing_get_eq_band_audio_mixer,
979 msm_routing_put_eq_band_audio_mixer),
980 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band9", EQ_BAND9,
981 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
982 msm_routing_get_eq_band_audio_mixer,
983 msm_routing_put_eq_band_audio_mixer),
984 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band10", EQ_BAND10,
985 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
986 msm_routing_get_eq_band_audio_mixer,
987 msm_routing_put_eq_band_audio_mixer),
988 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band11", EQ_BAND11,
989 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
990 msm_routing_get_eq_band_audio_mixer,
991 msm_routing_put_eq_band_audio_mixer),
992 SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band12", EQ_BAND12,
993 MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5,
994 msm_routing_get_eq_band_audio_mixer,
995 msm_routing_put_eq_band_audio_mixer),
996 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band1", EQ_BAND1,
997 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
998 msm_routing_get_eq_band_audio_mixer,
999 msm_routing_put_eq_band_audio_mixer),
1000 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band2", EQ_BAND2,
1001 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1002 msm_routing_get_eq_band_audio_mixer,
1003 msm_routing_put_eq_band_audio_mixer),
1004 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band3", EQ_BAND3,
1005 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1006 msm_routing_get_eq_band_audio_mixer,
1007 msm_routing_put_eq_band_audio_mixer),
1008 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band4", EQ_BAND4,
1009 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1010 msm_routing_get_eq_band_audio_mixer,
1011 msm_routing_put_eq_band_audio_mixer),
1012 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band5", EQ_BAND5,
1013 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1014 msm_routing_get_eq_band_audio_mixer,
1015 msm_routing_put_eq_band_audio_mixer),
1016 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band6", EQ_BAND6,
1017 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1018 msm_routing_get_eq_band_audio_mixer,
1019 msm_routing_put_eq_band_audio_mixer),
1020 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band7", EQ_BAND7,
1021 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1022 msm_routing_get_eq_band_audio_mixer,
1023 msm_routing_put_eq_band_audio_mixer),
1024 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band8", EQ_BAND8,
1025 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1026 msm_routing_get_eq_band_audio_mixer,
1027 msm_routing_put_eq_band_audio_mixer),
1028 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band9", EQ_BAND9,
1029 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1030 msm_routing_get_eq_band_audio_mixer,
1031 msm_routing_put_eq_band_audio_mixer),
1032 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band10", EQ_BAND10,
1033 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1034 msm_routing_get_eq_band_audio_mixer,
1035 msm_routing_put_eq_band_audio_mixer),
1036 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band11", EQ_BAND11,
1037 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1038 msm_routing_get_eq_band_audio_mixer,
1039 msm_routing_put_eq_band_audio_mixer),
1040 SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band12", EQ_BAND12,
1041 MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5,
1042 msm_routing_get_eq_band_audio_mixer,
1043 msm_routing_put_eq_band_audio_mixer),
1044};
1045
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001046static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
1047 /* Frontend AIF */
1048 /* Widget name equals to Front-End DAI name<Need confirmation>,
1049 * Stream name must contains substring of front-end dai name
1050 */
1051 SND_SOC_DAPM_AIF_IN("MM_DL1", "MultiMedia1 Playback", 0, 0, 0, 0),
1052 SND_SOC_DAPM_AIF_IN("MM_DL2", "MultiMedia2 Playback", 0, 0, 0, 0),
1053 SND_SOC_DAPM_AIF_IN("MM_DL3", "MultiMedia3 Playback", 0, 0, 0, 0),
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301054 SND_SOC_DAPM_AIF_IN("MM_DL4", "MultiMedia4 Playback", 0, 0, 0, 0),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001055 SND_SOC_DAPM_AIF_IN("VOIP_DL", "VoIP Playback", 0, 0, 0, 0),
1056 SND_SOC_DAPM_AIF_OUT("MM_UL1", "MultiMedia1 Capture", 0, 0, 0, 0),
Jayasena Sangaraboina99fee652011-09-19 07:43:13 -07001057 SND_SOC_DAPM_AIF_OUT("MM_UL2", "MultiMedia2 Capture", 0, 0, 0, 0),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001058 SND_SOC_DAPM_AIF_IN("CS-VOICE_DL1", "CS-VOICE Playback", 0, 0, 0, 0),
1059 SND_SOC_DAPM_AIF_OUT("CS-VOICE_UL1", "CS-VOICE Capture", 0, 0, 0, 0),
1060 SND_SOC_DAPM_AIF_OUT("VOIP_UL", "VoIP Capture", 0, 0, 0, 0),
1061 SND_SOC_DAPM_AIF_IN("SLIM0_DL_HL", "SLIMBUS0_HOSTLESS Playback",
1062 0, 0, 0, 0),
1063 SND_SOC_DAPM_AIF_OUT("SLIM0_UL_HL", "SLIMBUS0_HOSTLESS Capture",
1064 0, 0, 0, 0),
1065 SND_SOC_DAPM_AIF_IN("INTFM_DL_HL", "INT_FM_HOSTLESS Playback",
1066 0, 0, 0, 0),
1067 SND_SOC_DAPM_AIF_OUT("INTFM_UL_HL", "INT_FM_HOSTLESS Capture",
1068 0, 0, 0, 0),
1069 /* Backend AIF */
1070 /* Stream name equals to backend dai link stream name
1071 */
1072 SND_SOC_DAPM_AIF_OUT("PRI_I2S_RX", "Primary I2S Playback", 0, 0, 0, 0),
1073 SND_SOC_DAPM_AIF_OUT("SLIMBUS_0_RX", "Slimbus Playback", 0, 0, 0, 0),
1074 SND_SOC_DAPM_AIF_OUT("HDMI", "HDMI Playback", 0, 0, 0 , 0),
1075 SND_SOC_DAPM_AIF_IN("PRI_I2S_TX", "Primary I2S Capture", 0, 0, 0, 0),
1076 SND_SOC_DAPM_AIF_IN("SLIMBUS_0_TX", "Slimbus Capture", 0, 0, 0, 0),
1077 SND_SOC_DAPM_AIF_OUT("INT_BT_SCO_RX", "Internal BT-SCO Playback",
1078 0, 0, 0 , 0),
1079 SND_SOC_DAPM_AIF_IN("INT_BT_SCO_TX", "Internal BT-SCO Capture",
1080 0, 0, 0, 0),
1081 SND_SOC_DAPM_AIF_OUT("INT_FM_RX", "Internal FM Playback",
1082 0, 0, 0 , 0),
1083 SND_SOC_DAPM_AIF_IN("INT_FM_TX", "Internal FM Capture",
1084 0, 0, 0, 0),
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301085 SND_SOC_DAPM_AIF_OUT("PCM_RX", "AFE Playback",
1086 0, 0, 0 , 0),
1087 SND_SOC_DAPM_AIF_IN("PCM_TX", "AFE Capture",
1088 0, 0, 0, 0),
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001089 SND_SOC_DAPM_AIF_OUT("AUX_PCM_RX", "AUX PCM Playback", 0, 0, 0, 0),
1090 SND_SOC_DAPM_AIF_IN("AUX_PCM_TX", "AUX PCM Capture", 0, 0, 0, 0),
Sriranjan Srikantama4969dd2011-07-14 00:34:56 -07001091 /* Switch Definitions */
Sriranjan Srikantamdf509d12011-10-24 17:53:27 -07001092 SND_SOC_DAPM_SWITCH("SLIMBUS_DL_HL", SND_SOC_NOPM, 0, 0,
Sriranjan Srikantama4969dd2011-07-14 00:34:56 -07001093 &fm_switch_mixer_controls),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001094 /* Mixer definitions */
1095 SND_SOC_DAPM_MIXER("PRI_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1096 pri_i2s_rx_mixer_controls, ARRAY_SIZE(pri_i2s_rx_mixer_controls)),
1097 SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1098 slimbus_rx_mixer_controls, ARRAY_SIZE(slimbus_rx_mixer_controls)),
1099 SND_SOC_DAPM_MIXER("HDMI Mixer", SND_SOC_NOPM, 0, 0,
1100 hdmi_mixer_controls, ARRAY_SIZE(hdmi_mixer_controls)),
1101 SND_SOC_DAPM_MIXER("MultiMedia1 Mixer", SND_SOC_NOPM, 0, 0,
1102 mmul1_mixer_controls, ARRAY_SIZE(mmul1_mixer_controls)),
Jayasena Sangaraboina99fee652011-09-19 07:43:13 -07001103 SND_SOC_DAPM_MIXER("MultiMedia2 Mixer", SND_SOC_NOPM, 0, 0,
1104 mmul2_mixer_controls, ARRAY_SIZE(mmul2_mixer_controls)),
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001105 SND_SOC_DAPM_MIXER("AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1106 auxpcm_rx_mixer_controls, ARRAY_SIZE(auxpcm_rx_mixer_controls)),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001107 /* Voice Mixer */
1108 SND_SOC_DAPM_MIXER("PRI_RX_Voice Mixer",
1109 SND_SOC_NOPM, 0, 0, pri_rx_voice_mixer_controls,
1110 ARRAY_SIZE(pri_rx_voice_mixer_controls)),
1111 SND_SOC_DAPM_MIXER("SLIM_0_RX_Voice Mixer",
1112 SND_SOC_NOPM, 0, 0,
1113 slimbus_rx_voice_mixer_controls,
1114 ARRAY_SIZE(slimbus_rx_voice_mixer_controls)),
1115 SND_SOC_DAPM_MIXER("INTERNAL_BT_SCO_RX_Voice Mixer",
1116 SND_SOC_NOPM, 0, 0,
1117 bt_sco_rx_voice_mixer_controls,
1118 ARRAY_SIZE(bt_sco_rx_voice_mixer_controls)),
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301119 SND_SOC_DAPM_MIXER("AFE_PCM_RX_Voice Mixer",
1120 SND_SOC_NOPM, 0, 0,
1121 afe_pcm_rx_voice_mixer_controls,
1122 ARRAY_SIZE(afe_pcm_rx_voice_mixer_controls)),
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001123 SND_SOC_DAPM_MIXER("AUX_PCM_RX_Voice Mixer",
1124 SND_SOC_NOPM, 0, 0,
1125 aux_pcm_rx_voice_mixer_controls,
1126 ARRAY_SIZE(aux_pcm_rx_voice_mixer_controls)),
Alex Wong593576c2011-11-15 08:03:24 -08001127 SND_SOC_DAPM_MIXER("HDMI_RX_Voice Mixer",
1128 SND_SOC_NOPM, 0, 0,
1129 hdmi_rx_voice_mixer_controls,
1130 ARRAY_SIZE(hdmi_rx_voice_mixer_controls)),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001131 SND_SOC_DAPM_MIXER("Voice_Tx Mixer",
1132 SND_SOC_NOPM, 0, 0, tx_voice_mixer_controls,
1133 ARRAY_SIZE(tx_voice_mixer_controls)),
1134 SND_SOC_DAPM_MIXER("Voip_Tx Mixer",
1135 SND_SOC_NOPM, 0, 0, tx_voip_mixer_controls,
1136 ARRAY_SIZE(tx_voip_mixer_controls)),
1137 SND_SOC_DAPM_MIXER("INTERNAL_BT_SCO_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1138 int_bt_sco_rx_mixer_controls, ARRAY_SIZE(int_bt_sco_rx_mixer_controls)),
1139 SND_SOC_DAPM_MIXER("INTERNAL_FM_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1140 int_fm_rx_mixer_controls, ARRAY_SIZE(int_fm_rx_mixer_controls)),
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301141 SND_SOC_DAPM_MIXER("AFE_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
1142 afe_pcm_rx_mixer_controls, ARRAY_SIZE(afe_pcm_rx_mixer_controls)),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001143 SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Port Mixer",
1144 SND_SOC_NOPM, 0, 0, sbus_0_rx_port_mixer_controls,
1145 ARRAY_SIZE(sbus_0_rx_port_mixer_controls)),
1146};
1147
1148static const struct snd_soc_dapm_route intercon[] = {
1149 {"PRI_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1150 {"PRI_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
1151 {"PRI_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301152 {"PRI_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001153 {"PRI_I2S_RX", NULL, "PRI_RX Audio Mixer"},
1154
1155 {"SLIMBUS_0_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1156 {"SLIMBUS_0_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
1157 {"SLIMBUS_0_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301158 {"SLIMBUS_0_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001159 {"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Audio Mixer"},
1160
1161 {"HDMI Mixer", "MultiMedia1", "MM_DL1"},
1162 {"HDMI Mixer", "MultiMedia2", "MM_DL2"},
Asish Bhattacharyac592eed2011-09-16 17:43:02 +05301163 {"HDMI Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301164 {"HDMI Mixer", "MultiMedia4", "MM_DL4"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001165 {"HDMI", NULL, "HDMI Mixer"},
1166
1167 {"MultiMedia1 Mixer", "PRI_TX", "PRI_I2S_TX"},
1168 {"MultiMedia1 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001169 {"MultiMedia1 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001170
1171 {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1172 {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
Asish Bhattacharyac592eed2011-09-16 17:43:02 +05301173 {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301174 {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001175 {"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX Audio Mixer"},
1176
1177 {"INTERNAL_FM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1178 {"INTERNAL_FM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
Asish Bhattacharyac592eed2011-09-16 17:43:02 +05301179 {"INTERNAL_FM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301180 {"INTERNAL_FM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001181 {"INT_FM_RX", NULL, "INTERNAL_FM_RX Audio Mixer"},
1182
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301183 {"AFE_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1184 {"AFE_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
1185 {"AFE_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301186 {"AFE_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301187 {"PCM_RX", NULL, "AFE_PCM_RX Audio Mixer"},
1188
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001189 {"MultiMedia1 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
1190 {"MultiMedia1 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301191
1192 {"MultiMedia1 Mixer", "AFE_PCM_TX", "PCM_TX"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001193 {"MM_UL1", NULL, "MultiMedia1 Mixer"},
Jayasena Sangaraboina99fee652011-09-19 07:43:13 -07001194 {"MultiMedia2 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
1195 {"MM_UL2", NULL, "MultiMedia2 Mixer"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001196
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001197 {"AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
1198 {"AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
1199 {"AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
Asish Bhattacharya305d1752011-11-01 20:38:26 +05301200 {"AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001201 {"AUX_PCM_RX", NULL, "AUX_PCM_RX Audio Mixer"},
1202
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001203 {"PRI_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1204 {"PRI_RX_Voice Mixer", "Voip", "VOIP_DL"},
1205 {"PRI_I2S_RX", NULL, "PRI_RX_Voice Mixer"},
1206
1207 {"SLIM_0_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1208 {"SLIM_0_RX_Voice Mixer", "Voip", "VOIP_DL"},
1209 {"SLIMBUS_0_RX", NULL, "SLIM_0_RX_Voice Mixer"},
1210
1211 {"INTERNAL_BT_SCO_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1212 {"INTERNAL_BT_SCO_RX_Voice Mixer", "Voip", "VOIP_DL"},
1213 {"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX_Voice Mixer"},
1214
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301215 {"AFE_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1216 {"AFE_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"},
1217 {"PCM_RX", NULL, "AFE_PCM_RX_Voice Mixer"},
1218
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001219 {"AUX_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1220 {"AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"},
1221 {"AUX_PCM_RX", NULL, "AUX_PCM_RX_Voice Mixer"},
1222
Alex Wong593576c2011-11-15 08:03:24 -08001223 {"HDMI_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
1224 {"HDMI_RX_Voice Mixer", "Voip", "VOIP_DL"},
1225 {"HDMI", NULL, "HDMI_RX_Voice Mixer"},
1226
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001227 {"Voice_Tx Mixer", "PRI_TX_Voice", "PRI_I2S_TX"},
1228 {"Voice_Tx Mixer", "SLIM_0_TX_Voice", "SLIMBUS_0_TX"},
1229 {"Voice_Tx Mixer", "INTERNAL_BT_SCO_TX_Voice", "INT_BT_SCO_TX"},
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301230 {"Voice_Tx Mixer", "AFE_PCM_TX_Voice", "PCM_TX"},
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001231 {"Voice_Tx Mixer", "AUX_PCM_TX_Voice", "AUX_PCM_TX"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001232 {"CS-VOICE_UL1", NULL, "Voice_Tx Mixer"},
1233 {"Voip_Tx Mixer", "PRI_TX_Voip", "PRI_I2S_TX"},
1234 {"Voip_Tx Mixer", "SLIM_0_TX_Voip", "SLIMBUS_0_TX"},
1235 {"Voip_Tx Mixer", "INTERNAL_BT_SCO_TX_Voip", "INT_BT_SCO_TX"},
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301236 {"Voip_Tx Mixer", "AFE_PCM_TX_Voip", "PCM_TX"},
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001237 {"Voip_Tx Mixer", "AUX_PCM_TX_Voip", "AUX_PCM_TX"},
1238
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001239 {"VOIP_UL", NULL, "Voip_Tx Mixer"},
Sriranjan Srikantamdf509d12011-10-24 17:53:27 -07001240 {"SLIMBUS_DL_HL", "Switch", "SLIM0_DL_HL"},
1241 {"SLIMBUS_0_RX", NULL, "SLIMBUS_DL_HL"},
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001242 {"SLIM0_UL_HL", NULL, "SLIMBUS_0_TX"},
1243 {"INT_FM_RX", NULL, "INTFM_DL_HL"},
1244 {"INTFM_UL_HL", NULL, "INT_FM_TX"},
1245 {"SLIMBUS_0_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
1246 {"SLIMBUS_0_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
1247 {"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Port Mixer"},
1248};
1249
Patrick Laicf999112011-08-23 11:27:20 -07001250static int msm_pcm_routing_hw_params(struct snd_pcm_substream *substream,
1251 struct snd_pcm_hw_params *params)
1252{
1253 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1254 unsigned int be_id = rtd->dai_link->be_id;
1255
1256 mutex_lock(&routing_lock);
1257 msm_bedais[be_id].hw_params = params;
1258 mutex_unlock(&routing_lock);
1259 return 0;
1260}
1261
1262static int msm_pcm_routing_close(struct snd_pcm_substream *substream)
1263{
1264 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1265 unsigned int be_id = rtd->dai_link->be_id;
1266 int i, session_type;
1267 struct msm_pcm_routing_bdai_data *bedai;
1268
1269 if (be_id >= MSM_BACKEND_DAI_MAX) {
1270 pr_err("%s: unexpected be_id %d\n", __func__, be_id);
1271 return -EINVAL;
1272 }
1273
1274 bedai = &msm_bedais[be_id];
1275
1276 session_type = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
1277 0 : 1);
1278
1279 mutex_lock(&routing_lock);
1280
1281 for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MAX) {
1282 if (fe_dai_map[i][session_type] != INVALID_SESSION)
1283 adm_close(bedai->port_id);
1284 }
1285
1286 bedai->active = 0;
1287 bedai->hw_params = NULL;
1288
1289 mutex_unlock(&routing_lock);
1290
1291 return 0;
1292}
1293
1294static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream)
1295{
1296 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1297 unsigned int be_id = rtd->dai_link->be_id;
1298 int i, path_type, session_type;
1299 struct msm_pcm_routing_bdai_data *bedai;
1300
1301 if (be_id >= MSM_BACKEND_DAI_MAX) {
1302 pr_err("%s: unexpected be_id %d\n", __func__, be_id);
1303 return -EINVAL;
1304 }
1305
1306
1307 bedai = &msm_bedais[be_id];
1308
Jay Wangc8e03a82011-10-31 11:53:23 -07001309 if (bedai->hw_params == NULL) {
1310 pr_err("%s: HW param is not configured", __func__);
1311 return -EINVAL;
1312 }
1313
1314
Patrick Laicf999112011-08-23 11:27:20 -07001315 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1316 path_type = ADM_PATH_PLAYBACK;
1317 session_type = SESSION_TYPE_RX;
1318 } else {
1319 path_type = ADM_PATH_LIVE_REC;
1320 session_type = SESSION_TYPE_TX;
1321 }
1322
1323 mutex_lock(&routing_lock);
1324
1325 if (bedai->active == 1)
1326 goto done; /* Ignore prepare if back-end already active */
1327
1328 /* AFE port is not active at this point. However, still
1329 * go ahead setting active flag under the notion that
1330 * QDSP6 is able to handle ADM starting before AFE port
1331 * is started.
1332 */
1333 bedai->active = 1;
1334
1335 for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MAX) {
1336 if (fe_dai_map[i][session_type] != INVALID_SESSION) {
1337 adm_open(bedai->port_id, path_type,
1338 params_rate(bedai->hw_params),
1339 params_channels(bedai->hw_params),
1340 DEFAULT_COPP_TOPOLOGY);
1341 msm_pcm_routing_build_matrix(i,
1342 fe_dai_map[i][session_type], path_type);
1343 }
1344 }
1345
1346done:
1347 mutex_unlock(&routing_lock);
1348
1349 return 0;
1350}
1351
1352static struct snd_pcm_ops msm_routing_pcm_ops = {
1353 .hw_params = msm_pcm_routing_hw_params,
1354 .close = msm_pcm_routing_close,
1355 .prepare = msm_pcm_routing_prepare,
1356};
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001357
1358static unsigned int msm_routing_read(struct snd_soc_platform *platform,
1359 unsigned int reg)
1360{
1361 dev_dbg(platform->dev, "reg %x\n", reg);
1362 return 0;
1363}
1364
1365/* Not used but frame seems to require it */
1366static int msm_routing_write(struct snd_soc_platform *platform,
1367 unsigned int reg, unsigned int val)
1368{
1369 dev_dbg(platform->dev, "reg %x val %x\n", reg, val);
1370 return 0;
1371}
1372
1373/* Not used but frame seems to require it */
1374static int msm_routing_probe(struct snd_soc_platform *platform)
1375{
1376 snd_soc_dapm_new_controls(&platform->dapm, msm_qdsp6_widgets,
1377 ARRAY_SIZE(msm_qdsp6_widgets));
1378 snd_soc_dapm_add_routes(&platform->dapm, intercon,
1379 ARRAY_SIZE(intercon));
1380
1381 snd_soc_dapm_new_widgets(&platform->dapm);
1382
Jayasena Sangaraboinacb1e22f2011-07-18 10:36:57 -07001383 snd_soc_add_platform_controls(platform,
1384 int_fm_vol_mixer_controls,
1385 ARRAY_SIZE(int_fm_vol_mixer_controls));
Asish Bhattacharya0ec76182011-07-29 16:58:11 +05301386
1387 snd_soc_add_platform_controls(platform,
1388 lpa_vol_mixer_controls,
1389 ARRAY_SIZE(lpa_vol_mixer_controls));
Ben Romberger037dd2f2011-09-22 14:01:32 -07001390
1391 snd_soc_add_platform_controls(platform,
1392 eq_enable_mixer_controls,
1393 ARRAY_SIZE(eq_enable_mixer_controls));
1394
1395 snd_soc_add_platform_controls(platform,
1396 eq_band_mixer_controls,
1397 ARRAY_SIZE(eq_band_mixer_controls));
1398
1399 snd_soc_add_platform_controls(platform,
1400 eq_coeff_mixer_controls,
1401 ARRAY_SIZE(eq_coeff_mixer_controls));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001402 return 0;
1403}
1404
1405static struct snd_soc_platform_driver msm_soc_routing_platform = {
1406 .ops = &msm_routing_pcm_ops,
1407 .probe = msm_routing_probe,
1408 .read = msm_routing_read,
1409 .write = msm_routing_write,
1410};
1411
1412static __devinit int msm_routing_pcm_probe(struct platform_device *pdev)
1413{
1414 dev_dbg(&pdev->dev, "dev name %s\n", dev_name(&pdev->dev));
1415 return snd_soc_register_platform(&pdev->dev,
1416 &msm_soc_routing_platform);
1417}
1418
1419static int msm_routing_pcm_remove(struct platform_device *pdev)
1420{
1421 snd_soc_unregister_platform(&pdev->dev);
1422 return 0;
1423}
1424
1425static struct platform_driver msm_routing_pcm_driver = {
1426 .driver = {
1427 .name = "msm-pcm-routing",
1428 .owner = THIS_MODULE,
1429 },
1430 .probe = msm_routing_pcm_probe,
1431 .remove = __devexit_p(msm_routing_pcm_remove),
1432};
1433
1434static int __init msm_soc_routing_platform_init(void)
1435{
Neema Shettyfeea7742011-09-11 12:30:36 -07001436 mutex_init(&routing_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001437 return platform_driver_register(&msm_routing_pcm_driver);
1438}
1439module_init(msm_soc_routing_platform_init);
1440
1441static void __exit msm_soc_routing_platform_exit(void)
1442{
1443 platform_driver_unregister(&msm_routing_pcm_driver);
1444}
1445module_exit(msm_soc_routing_platform_exit);
1446
1447MODULE_DESCRIPTION("MSM routing platform driver");
1448MODULE_LICENSE("GPL v2");