blob: c96c5bca703766473a2790185cb3aaac320857f9 [file] [log] [blame]
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001/*
2 * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#include <linux/clk.h>
15#include <linux/delay.h>
16#include <linux/gpio.h>
17#include <linux/of_gpio.h>
18#include <linux/platform_device.h>
19#include <linux/slab.h>
20#include <linux/regulator/consumer.h>
21#include <linux/io.h>
22#include <linux/module.h>
23#include <linux/switch.h>
24#include <linux/input.h>
25#include <linux/of_device.h>
26#include <linux/mfd/msm-cdc-pinctrl.h>
27#include <sound/core.h>
28#include <sound/soc.h>
29#include <sound/soc-dapm.h>
30#include <sound/pcm.h>
31#include <sound/jack.h>
32#include <sound/q6afe-v2.h>
33#include <sound/q6core.h>
34#include <sound/pcm_params.h>
35#include <sound/info.h>
36#include <device_event.h>
37#include <linux/qdsp6v2/audio_notifier.h>
38#include "qdsp6v2/msm-pcm-routing-v2.h"
39#include "../codecs/wcd9335.h"
40#include "../codecs/wcd934x/wcd934x.h"
41#include "../codecs/wcd934x/wcd934x-mbhc.h"
42#include "../codecs/wsa881x.h"
43
44#define DRV_NAME "msm8998-asoc-snd"
45
46#define __CHIPSET__ "MSM8998 "
47#define MSM_DAILINK_NAME(name) (__CHIPSET__#name)
48
49#define SAMPLING_RATE_8KHZ 8000
50#define SAMPLING_RATE_11P025KHZ 11025
51#define SAMPLING_RATE_16KHZ 16000
52#define SAMPLING_RATE_22P05KHZ 22050
53#define SAMPLING_RATE_32KHZ 32000
54#define SAMPLING_RATE_44P1KHZ 44100
55#define SAMPLING_RATE_48KHZ 48000
56#define SAMPLING_RATE_88P2KHZ 88200
57#define SAMPLING_RATE_96KHZ 96000
58#define SAMPLING_RATE_176P4KHZ 176400
59#define SAMPLING_RATE_192KHZ 192000
60#define SAMPLING_RATE_352P8KHZ 352800
61#define SAMPLING_RATE_384KHZ 384000
62
63#define WCD9XXX_MBHC_DEF_BUTTONS 8
64#define WCD9XXX_MBHC_DEF_RLOADS 5
65#define CODEC_EXT_CLK_RATE 9600000
66#define ADSP_STATE_READY_TIMEOUT_MS 3000
67#define DEV_NAME_STR_LEN 32
68
69#define WSA8810_NAME_1 "wsa881x.20170211"
70#define WSA8810_NAME_2 "wsa881x.20170212"
71
72#define WCN_CDC_SLIM_RX_CH_MAX 2
73#define WCN_CDC_SLIM_TX_CH_MAX 3
74
75#define TDM_CHANNEL_MAX 8
76#define TDM_SLOT_OFFSET_MAX 8
77
78#define MSM_HIFI_ON 1
79
80enum {
81 SLIM_RX_0 = 0,
82 SLIM_RX_1,
83 SLIM_RX_2,
84 SLIM_RX_3,
85 SLIM_RX_4,
86 SLIM_RX_5,
87 SLIM_RX_6,
88 SLIM_RX_7,
89 SLIM_RX_MAX,
90};
91
92enum {
93 SLIM_TX_0 = 0,
94 SLIM_TX_1,
95 SLIM_TX_2,
96 SLIM_TX_3,
97 SLIM_TX_4,
98 SLIM_TX_5,
99 SLIM_TX_6,
100 SLIM_TX_7,
101 SLIM_TX_8,
102 SLIM_TX_MAX,
103};
104
105enum {
106 PRIM_MI2S = 0,
107 SEC_MI2S,
108 TERT_MI2S,
109 QUAT_MI2S,
110 MI2S_MAX,
111};
112
113enum {
114 PRIM_AUX_PCM = 0,
115 SEC_AUX_PCM,
116 TERT_AUX_PCM,
117 QUAT_AUX_PCM,
118 AUX_PCM_MAX,
119};
120
121enum {
122 PCM_I2S_SEL_PRIM = 0,
123 PCM_I2S_SEL_SEC,
124 PCM_I2S_SEL_TERT,
125 PCM_I2S_SEL_QUAT,
126 PCM_I2S_SEL_MAX,
127};
128
129struct mi2s_aux_pcm_common_conf {
130 struct mutex lock;
131 void *pcm_i2s_sel_vt_addr;
132};
133
134struct mi2s_conf {
135 struct mutex lock;
136 u32 ref_cnt;
137 u32 msm_is_mi2s_master;
138};
139
140struct auxpcm_conf {
141 struct mutex lock;
142 u32 ref_cnt;
143};
144
145struct dev_config {
146 u32 sample_rate;
147 u32 bit_format;
148 u32 channels;
149};
150
151enum {
152 HDMI_RX_IDX = 0,
153 DP_RX_IDX,
154 EXT_DISP_RX_IDX_MAX,
155};
156
157struct msm_wsa881x_dev_info {
158 struct device_node *of_node;
159 u32 index;
160};
161
162struct msm_asoc_mach_data {
163 u32 mclk_freq;
164 int us_euro_gpio; /* used by gpio driver API */
165 struct device_node *us_euro_gpio_p; /* used by pinctrl API */
166 struct device_node *hph_en1_gpio_p; /* used by pinctrl API */
167 struct device_node *hph_en0_gpio_p; /* used by pinctrl API */
168 struct snd_info_entry *codec_root;
169};
170
171struct msm_asoc_wcd93xx_codec {
172 void* (*get_afe_config_fn)(struct snd_soc_codec *codec,
173 enum afe_config_type config_type);
174 void (*mbhc_hs_detect_exit)(struct snd_soc_codec *codec);
175};
176
177enum {
178 TDM_0 = 0,
179 TDM_1,
180 TDM_2,
181 TDM_3,
182 TDM_4,
183 TDM_5,
184 TDM_6,
185 TDM_7,
186 TDM_PORT_MAX,
187};
188
189enum {
190 TDM_PRI = 0,
191 TDM_SEC,
192 TDM_TERT,
193 TDM_QUAT,
194 TDM_INTERFACE_MAX,
195};
196
197struct tdm_port {
198 u32 mode;
199 u32 channel;
200};
201
202/* TDM default config */
203static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = {
204 { /* PRI TDM */
205 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */
206 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */
207 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */
208 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */
209 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */
210 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */
211 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */
212 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */
213 },
214 { /* SEC TDM */
215 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */
216 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */
217 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */
218 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */
219 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */
220 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */
221 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */
222 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */
223 },
224 { /* TERT TDM */
225 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */
226 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */
227 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */
228 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */
229 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */
230 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */
231 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */
232 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */
233 },
234 { /* QUAT TDM */
235 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */
236 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */
237 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */
238 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */
239 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */
240 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */
241 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */
242 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */
243 }
244};
245
246/* TDM default config */
247static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = {
248 { /* PRI TDM */
249 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */
250 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */
251 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */
252 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */
253 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */
254 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */
255 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */
256 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */
257 },
258 { /* SEC TDM */
259 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */
260 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */
261 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */
262 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */
263 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */
264 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */
265 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */
266 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */
267 },
268 { /* TERT TDM */
269 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */
270 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */
271 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */
272 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */
273 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */
274 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */
275 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */
276 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */
277 },
278 { /* QUAT TDM */
279 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */
280 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */
281 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */
282 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */
283 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */
284 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */
285 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */
286 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */
287 }
288};
289
290/*TDM default offset currently only supporting TDM_RX_0 and TDM_TX_0 */
291static unsigned int tdm_slot_offset[TDM_PORT_MAX][TDM_SLOT_OFFSET_MAX] = {
292 {0, 4, 8, 12, 16, 20, 24, 28},/* TX_0 | RX_0 */
293 {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_1 | RX_1 */
294 {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_2 | RX_2 */
295 {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_3 | RX_3 */
296 {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_4 | RX_4 */
297 {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_5 | RX_5 */
298 {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_6 | RX_6 */
299 {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_7 | RX_7 */
300};
301
302/* Default configuration of slimbus channels */
303static struct dev_config slim_rx_cfg[] = {
304 [SLIM_RX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
305 [SLIM_RX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
306 [SLIM_RX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
307 [SLIM_RX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
308 [SLIM_RX_4] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
309 [SLIM_RX_5] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
310 [SLIM_RX_6] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
311 [SLIM_RX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
312};
313
314static struct dev_config slim_tx_cfg[] = {
315 [SLIM_TX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
316 [SLIM_TX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
317 [SLIM_TX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
318 [SLIM_TX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
319 [SLIM_TX_4] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
320 [SLIM_TX_5] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
321 [SLIM_TX_6] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
322 [SLIM_TX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
323 [SLIM_TX_8] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
324};
325
326
327/* Default configuration of external display BE */
328static struct dev_config ext_disp_rx_cfg[] = {
329 [HDMI_RX_IDX] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
330 [DP_RX_IDX] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
331};
332
333static struct dev_config usb_rx_cfg = {
334 .sample_rate = SAMPLING_RATE_48KHZ,
335 .bit_format = SNDRV_PCM_FORMAT_S16_LE,
336 .channels = 2,
337};
338
339static struct dev_config usb_tx_cfg = {
340 .sample_rate = SAMPLING_RATE_48KHZ,
341 .bit_format = SNDRV_PCM_FORMAT_S16_LE,
342 .channels = 1,
343};
344
345static struct dev_config proxy_rx_cfg = {
346 .sample_rate = SAMPLING_RATE_48KHZ,
347 .bit_format = SNDRV_PCM_FORMAT_S16_LE,
348 .channels = 2,
349};
350
351/* Default configuration of MI2S channels */
352static struct dev_config mi2s_rx_cfg[] = {
353 [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
354 [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
355 [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
356 [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
357};
358
359static struct dev_config mi2s_tx_cfg[] = {
360 [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
361 [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
362 [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
363 [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
364};
365
366static struct dev_config aux_pcm_rx_cfg[] = {
367 [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
368 [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
369 [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
370 [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
371};
372
373static struct dev_config aux_pcm_tx_cfg[] = {
374 [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
375 [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
376 [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
377 [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
378};
379
380static int msm_vi_feed_tx_ch = 2;
381static const char *const slim_rx_ch_text[] = {"One", "Two"};
382static const char *const slim_tx_ch_text[] = {"One", "Two", "Three", "Four",
383 "Five", "Six", "Seven",
384 "Eight"};
385static const char *const vi_feed_ch_text[] = {"One", "Two"};
386static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE",
387 "S32_LE"};
388static char const *ext_disp_bit_format_text[] = {"S16_LE", "S24_LE"};
389static char const *slim_sample_rate_text[] = {"KHZ_8", "KHZ_16",
390 "KHZ_32", "KHZ_44P1", "KHZ_48",
391 "KHZ_88P2", "KHZ_96", "KHZ_176P4",
392 "KHZ_192", "KHZ_352P8", "KHZ_384"};
393static char const *bt_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_48"};
394static const char *const usb_ch_text[] = {"One", "Two", "Three", "Four",
395 "Five", "Six", "Seven",
396 "Eight"};
397static char const *ch_text[] = {"Two", "Three", "Four", "Five",
398 "Six", "Seven", "Eight"};
399static char const *usb_sample_rate_text[] = {"KHZ_8", "KHZ_11P025",
400 "KHZ_16", "KHZ_22P05",
401 "KHZ_32", "KHZ_44P1", "KHZ_48",
402 "KHZ_88P2", "KHZ_96", "KHZ_176P4",
403 "KHZ_192", "KHZ_352P8", "KHZ_384"};
404static char const *ext_disp_sample_rate_text[] = {"KHZ_48", "KHZ_96",
405 "KHZ_192"};
406static char const *tdm_ch_text[] = {"One", "Two", "Three", "Four",
407 "Five", "Six", "Seven", "Eight"};
408static char const *tdm_bit_format_text[] = {"S16_LE", "S24_LE", "S32_LE"};
409static char const *tdm_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32",
410 "KHZ_44P1", "KHZ_48", "KHZ_96",
411 "KHZ_192", "KHZ_352P8", "KHZ_384"};
412static const char *const auxpcm_rate_text[] = {"KHZ_8", "KHZ_16"};
413static char const *mi2s_rate_text[] = {"KHZ_8", "KHZ_16",
414 "KHZ_32", "KHZ_44P1", "KHZ_48",
415 "KHZ_96", "KHZ_192"};
416static const char *const mi2s_ch_text[] = {"One", "Two", "Three", "Four",
417 "Five", "Six", "Seven",
418 "Eight"};
419static const char *const hifi_text[] = {"Off", "On"};
420
421static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_chs, slim_rx_ch_text);
422static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_chs, slim_rx_ch_text);
423static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_chs, slim_tx_ch_text);
424static SOC_ENUM_SINGLE_EXT_DECL(slim_1_tx_chs, slim_tx_ch_text);
425static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_chs, slim_rx_ch_text);
426static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_chs, slim_rx_ch_text);
427static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_chs, usb_ch_text);
428static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_chs, usb_ch_text);
429static SOC_ENUM_SINGLE_EXT_DECL(vi_feed_tx_chs, vi_feed_ch_text);
430static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_chs, ch_text);
431static SOC_ENUM_SINGLE_EXT_DECL(proxy_rx_chs, ch_text);
432static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_format, bit_format_text);
433static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_format, bit_format_text);
434static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_format, bit_format_text);
435static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_format, bit_format_text);
436static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_format, bit_format_text);
437static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_format, bit_format_text);
438static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_format, ext_disp_bit_format_text);
439static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_sample_rate, slim_sample_rate_text);
440static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_sample_rate, slim_sample_rate_text);
441static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_sample_rate, slim_sample_rate_text);
442static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_sample_rate, slim_sample_rate_text);
443static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_sample_rate, slim_sample_rate_text);
444static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate, bt_sample_rate_text);
445static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_sample_rate, usb_sample_rate_text);
446static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_sample_rate, usb_sample_rate_text);
447static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_sample_rate,
448 ext_disp_sample_rate_text);
449static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_chs, tdm_ch_text);
450static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_format, tdm_bit_format_text);
451static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_sample_rate, tdm_sample_rate_text);
452static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_chs, tdm_ch_text);
453static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_format, tdm_bit_format_text);
454static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_sample_rate, tdm_sample_rate_text);
455static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_rx_sample_rate, auxpcm_rate_text);
456static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_rx_sample_rate, auxpcm_rate_text);
457static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_rx_sample_rate, auxpcm_rate_text);
458static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_rx_sample_rate, auxpcm_rate_text);
459static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_tx_sample_rate, auxpcm_rate_text);
460static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_tx_sample_rate, auxpcm_rate_text);
461static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_tx_sample_rate, auxpcm_rate_text);
462static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_tx_sample_rate, auxpcm_rate_text);
463static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_sample_rate, mi2s_rate_text);
464static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_sample_rate, mi2s_rate_text);
465static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_sample_rate, mi2s_rate_text);
466static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_sample_rate, mi2s_rate_text);
467static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_sample_rate, mi2s_rate_text);
468static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_sample_rate, mi2s_rate_text);
469static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_sample_rate, mi2s_rate_text);
470static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_sample_rate, mi2s_rate_text);
471static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_chs, mi2s_ch_text);
472static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_chs, mi2s_ch_text);
473static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_chs, mi2s_ch_text);
474static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_chs, mi2s_ch_text);
475static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_chs, mi2s_ch_text);
476static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_chs, mi2s_ch_text);
477static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_chs, mi2s_ch_text);
478static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_chs, mi2s_ch_text);
479static SOC_ENUM_SINGLE_EXT_DECL(hifi_function, hifi_text);
480
481static struct platform_device *spdev;
482static int msm_hifi_control;
483
484static bool is_initial_boot;
485static bool codec_reg_done;
486static struct snd_soc_aux_dev *msm_aux_dev;
487static struct snd_soc_codec_conf *msm_codec_conf;
488static struct msm_asoc_wcd93xx_codec msm_codec_fn;
489
490static void *def_tasha_mbhc_cal(void);
491static void *def_tavil_mbhc_cal(void);
492static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec,
493 int enable, bool dapm);
494static int msm_wsa881x_init(struct snd_soc_component *component);
495
496/*
497 * Need to report LINEIN
498 * if R/L channel impedance is larger than 5K ohm
499 */
500static struct wcd_mbhc_config wcd_mbhc_cfg = {
501 .read_fw_bin = false,
502 .calibration = NULL,
503 .detect_extn_cable = true,
504 .mono_stero_detection = false,
505 .swap_gnd_mic = NULL,
506 .hs_ext_micbias = true,
507 .key_code[0] = KEY_MEDIA,
508 .key_code[1] = KEY_VOICECOMMAND,
509 .key_code[2] = KEY_VOLUMEUP,
510 .key_code[3] = KEY_VOLUMEDOWN,
511 .key_code[4] = 0,
512 .key_code[5] = 0,
513 .key_code[6] = 0,
514 .key_code[7] = 0,
515 .linein_th = 5000,
516 .moisture_en = true,
517};
518
519static struct snd_soc_dapm_route wcd_audio_paths_tasha[] = {
520 {"MIC BIAS1", NULL, "MCLK TX"},
521 {"MIC BIAS2", NULL, "MCLK TX"},
522 {"MIC BIAS3", NULL, "MCLK TX"},
523 {"MIC BIAS4", NULL, "MCLK TX"},
524};
525
526static struct snd_soc_dapm_route wcd_audio_paths[] = {
527 {"MIC BIAS1", NULL, "MCLK"},
528 {"MIC BIAS2", NULL, "MCLK"},
529 {"MIC BIAS3", NULL, "MCLK"},
530 {"MIC BIAS4", NULL, "MCLK"},
531};
532
533static struct afe_clk_set mi2s_clk[MI2S_MAX] = {
534 {
535 AFE_API_VERSION_I2S_CONFIG,
536 Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT,
537 Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
538 Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
539 Q6AFE_LPASS_CLK_ROOT_DEFAULT,
540 0,
541 },
542 {
543 AFE_API_VERSION_I2S_CONFIG,
544 Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT,
545 Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
546 Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
547 Q6AFE_LPASS_CLK_ROOT_DEFAULT,
548 0,
549 },
550 {
551 AFE_API_VERSION_I2S_CONFIG,
552 Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT,
553 Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
554 Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
555 Q6AFE_LPASS_CLK_ROOT_DEFAULT,
556 0,
557 },
558 {
559 AFE_API_VERSION_I2S_CONFIG,
560 Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT,
561 Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
562 Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
563 Q6AFE_LPASS_CLK_ROOT_DEFAULT,
564 0,
565 }
566};
567
568static struct mi2s_aux_pcm_common_conf mi2s_auxpcm_conf[PCM_I2S_SEL_MAX];
569static struct mi2s_conf mi2s_intf_conf[MI2S_MAX];
570static struct auxpcm_conf auxpcm_intf_conf[AUX_PCM_MAX];
571
572static int slim_get_sample_rate_val(int sample_rate)
573{
574 int sample_rate_val = 0;
575
576 switch (sample_rate) {
577 case SAMPLING_RATE_8KHZ:
578 sample_rate_val = 0;
579 break;
580 case SAMPLING_RATE_16KHZ:
581 sample_rate_val = 1;
582 break;
583 case SAMPLING_RATE_32KHZ:
584 sample_rate_val = 2;
585 break;
586 case SAMPLING_RATE_44P1KHZ:
587 sample_rate_val = 3;
588 break;
589 case SAMPLING_RATE_48KHZ:
590 sample_rate_val = 4;
591 break;
592 case SAMPLING_RATE_88P2KHZ:
593 sample_rate_val = 5;
594 break;
595 case SAMPLING_RATE_96KHZ:
596 sample_rate_val = 6;
597 break;
598 case SAMPLING_RATE_176P4KHZ:
599 sample_rate_val = 7;
600 break;
601 case SAMPLING_RATE_192KHZ:
602 sample_rate_val = 8;
603 break;
604 case SAMPLING_RATE_352P8KHZ:
605 sample_rate_val = 9;
606 break;
607 case SAMPLING_RATE_384KHZ:
608 sample_rate_val = 10;
609 break;
610 default:
611 sample_rate_val = 4;
612 break;
613 }
614 return sample_rate_val;
615}
616
617static int slim_get_sample_rate(int value)
618{
619 int sample_rate = 0;
620
621 switch (value) {
622 case 0:
623 sample_rate = SAMPLING_RATE_8KHZ;
624 break;
625 case 1:
626 sample_rate = SAMPLING_RATE_16KHZ;
627 break;
628 case 2:
629 sample_rate = SAMPLING_RATE_32KHZ;
630 break;
631 case 3:
632 sample_rate = SAMPLING_RATE_44P1KHZ;
633 break;
634 case 4:
635 sample_rate = SAMPLING_RATE_48KHZ;
636 break;
637 case 5:
638 sample_rate = SAMPLING_RATE_88P2KHZ;
639 break;
640 case 6:
641 sample_rate = SAMPLING_RATE_96KHZ;
642 break;
643 case 7:
644 sample_rate = SAMPLING_RATE_176P4KHZ;
645 break;
646 case 8:
647 sample_rate = SAMPLING_RATE_192KHZ;
648 break;
649 case 9:
650 sample_rate = SAMPLING_RATE_352P8KHZ;
651 break;
652 case 10:
653 sample_rate = SAMPLING_RATE_384KHZ;
654 break;
655 default:
656 sample_rate = SAMPLING_RATE_48KHZ;
657 break;
658 }
659 return sample_rate;
660}
661
662static int slim_get_bit_format_val(int bit_format)
663{
664 int val = 0;
665
666 switch (bit_format) {
667 case SNDRV_PCM_FORMAT_S32_LE:
668 val = 3;
669 break;
670 case SNDRV_PCM_FORMAT_S24_3LE:
671 val = 2;
672 break;
673 case SNDRV_PCM_FORMAT_S24_LE:
674 val = 1;
675 break;
676 case SNDRV_PCM_FORMAT_S16_LE:
677 default:
678 val = 0;
679 break;
680 }
681 return val;
682}
683
684static int slim_get_bit_format(int val)
685{
686 int bit_fmt = SNDRV_PCM_FORMAT_S16_LE;
687
688 switch (val) {
689 case 0:
690 bit_fmt = SNDRV_PCM_FORMAT_S16_LE;
691 break;
692 case 1:
693 bit_fmt = SNDRV_PCM_FORMAT_S24_LE;
694 break;
695 case 2:
696 bit_fmt = SNDRV_PCM_FORMAT_S24_3LE;
697 break;
698 case 3:
699 bit_fmt = SNDRV_PCM_FORMAT_S32_LE;
700 break;
701 default:
702 bit_fmt = SNDRV_PCM_FORMAT_S16_LE;
703 break;
704 }
705 return bit_fmt;
706}
707
708static int slim_get_port_idx(struct snd_kcontrol *kcontrol)
709{
710 int port_id = 0;
711
712 if (strnstr(kcontrol->id.name, "SLIM_0_RX", sizeof("SLIM_0_RX")))
713 port_id = SLIM_RX_0;
714 else if (strnstr(kcontrol->id.name, "SLIM_2_RX", sizeof("SLIM_2_RX")))
715 port_id = SLIM_RX_2;
716 else if (strnstr(kcontrol->id.name, "SLIM_5_RX", sizeof("SLIM_5_RX")))
717 port_id = SLIM_RX_5;
718 else if (strnstr(kcontrol->id.name, "SLIM_6_RX", sizeof("SLIM_6_RX")))
719 port_id = SLIM_RX_6;
720 else if (strnstr(kcontrol->id.name, "SLIM_0_TX", sizeof("SLIM_0_TX")))
721 port_id = SLIM_TX_0;
722 else if (strnstr(kcontrol->id.name, "SLIM_1_TX", sizeof("SLIM_1_TX")))
723 port_id = SLIM_TX_1;
724 else {
725 pr_err("%s: unsupported channel: %s",
726 __func__, kcontrol->id.name);
727 return -EINVAL;
728 }
729
730 return port_id;
731}
732
733static int slim_rx_sample_rate_get(struct snd_kcontrol *kcontrol,
734 struct snd_ctl_elem_value *ucontrol)
735{
736 int ch_num = slim_get_port_idx(kcontrol);
737
738 if (ch_num < 0)
739 return ch_num;
740
741 ucontrol->value.enumerated.item[0] =
742 slim_get_sample_rate_val(slim_rx_cfg[ch_num].sample_rate);
743
744 pr_debug("%s: slim[%d]_rx_sample_rate = %d, item = %d\n", __func__,
745 ch_num, slim_rx_cfg[ch_num].sample_rate,
746 ucontrol->value.enumerated.item[0]);
747
748 return 0;
749}
750
751static int slim_rx_sample_rate_put(struct snd_kcontrol *kcontrol,
752 struct snd_ctl_elem_value *ucontrol)
753{
754 int ch_num = slim_get_port_idx(kcontrol);
755
756 if (ch_num < 0)
757 return ch_num;
758
759 slim_rx_cfg[ch_num].sample_rate =
760 slim_get_sample_rate(ucontrol->value.enumerated.item[0]);
761
762 pr_debug("%s: slim[%d]_rx_sample_rate = %d, item = %d\n", __func__,
763 ch_num, slim_rx_cfg[ch_num].sample_rate,
764 ucontrol->value.enumerated.item[0]);
765
766 return 0;
767}
768
769static int slim_tx_sample_rate_get(struct snd_kcontrol *kcontrol,
770 struct snd_ctl_elem_value *ucontrol)
771{
772 int ch_num = slim_get_port_idx(kcontrol);
773
774 if (ch_num < 0)
775 return ch_num;
776
777 ucontrol->value.enumerated.item[0] =
778 slim_get_sample_rate_val(slim_tx_cfg[ch_num].sample_rate);
779
780 pr_debug("%s: slim[%d]_tx_sample_rate = %d, item = %d\n", __func__,
781 ch_num, slim_tx_cfg[ch_num].sample_rate,
782 ucontrol->value.enumerated.item[0]);
783
784 return 0;
785}
786
787static int slim_tx_sample_rate_put(struct snd_kcontrol *kcontrol,
788 struct snd_ctl_elem_value *ucontrol)
789{
790 int sample_rate = 0;
791 int ch_num = slim_get_port_idx(kcontrol);
792
793 if (ch_num < 0)
794 return ch_num;
795
796 sample_rate = slim_get_sample_rate(ucontrol->value.enumerated.item[0]);
797 if (sample_rate == SAMPLING_RATE_44P1KHZ) {
798 pr_err("%s: Unsupported sample rate %d: for Tx path\n",
799 __func__, sample_rate);
800 return -EINVAL;
801 }
802 slim_tx_cfg[ch_num].sample_rate = sample_rate;
803
804 pr_debug("%s: slim[%d]_tx_sample_rate = %d, value = %d\n", __func__,
805 ch_num, slim_tx_cfg[ch_num].sample_rate,
806 ucontrol->value.enumerated.item[0]);
807
808 return 0;
809}
810
811static int slim_rx_bit_format_get(struct snd_kcontrol *kcontrol,
812 struct snd_ctl_elem_value *ucontrol)
813{
814 int ch_num = slim_get_port_idx(kcontrol);
815
816 if (ch_num < 0)
817 return ch_num;
818
819 ucontrol->value.enumerated.item[0] =
820 slim_get_bit_format_val(slim_rx_cfg[ch_num].bit_format);
821
822 pr_debug("%s: slim[%d]_rx_bit_format = %d, ucontrol value = %d\n",
823 __func__, ch_num, slim_rx_cfg[ch_num].bit_format,
824 ucontrol->value.enumerated.item[0]);
825
826 return 0;
827}
828
829static int slim_rx_bit_format_put(struct snd_kcontrol *kcontrol,
830 struct snd_ctl_elem_value *ucontrol)
831{
832 int ch_num = slim_get_port_idx(kcontrol);
833
834 if (ch_num < 0)
835 return ch_num;
836
837 slim_rx_cfg[ch_num].bit_format =
838 slim_get_bit_format(ucontrol->value.enumerated.item[0]);
839
840 pr_debug("%s: slim[%d]_rx_bit_format = %d, ucontrol value = %d\n",
841 __func__, ch_num, slim_rx_cfg[ch_num].bit_format,
842 ucontrol->value.enumerated.item[0]);
843
844 return 0;
845}
846
847static int slim_tx_bit_format_get(struct snd_kcontrol *kcontrol,
848 struct snd_ctl_elem_value *ucontrol)
849{
850 int ch_num = slim_get_port_idx(kcontrol);
851
852 if (ch_num < 0)
853 return ch_num;
854
855 ucontrol->value.enumerated.item[0] =
856 slim_get_bit_format_val(slim_tx_cfg[ch_num].bit_format);
857
858 pr_debug("%s: slim[%d]_tx_bit_format = %d, ucontrol value = %d\n",
859 __func__, ch_num, slim_tx_cfg[ch_num].bit_format,
860 ucontrol->value.enumerated.item[0]);
861
862 return 0;
863}
864
865static int slim_tx_bit_format_put(struct snd_kcontrol *kcontrol,
866 struct snd_ctl_elem_value *ucontrol)
867{
868 int ch_num = slim_get_port_idx(kcontrol);
869
870 if (ch_num < 0)
871 return ch_num;
872
873 slim_tx_cfg[ch_num].bit_format =
874 slim_get_bit_format(ucontrol->value.enumerated.item[0]);
875
876 pr_debug("%s: slim[%d]_tx_bit_format = %d, ucontrol value = %d\n",
877 __func__, ch_num, slim_tx_cfg[ch_num].bit_format,
878 ucontrol->value.enumerated.item[0]);
879
880 return 0;
881}
882
883static int msm_slim_rx_ch_get(struct snd_kcontrol *kcontrol,
884 struct snd_ctl_elem_value *ucontrol)
885{
886 int ch_num = slim_get_port_idx(kcontrol);
887
888 if (ch_num < 0)
889 return ch_num;
890
891 pr_debug("%s: msm_slim_[%d]_rx_ch = %d\n", __func__,
892 ch_num, slim_rx_cfg[ch_num].channels);
893 ucontrol->value.enumerated.item[0] = slim_rx_cfg[ch_num].channels - 1;
894
895 return 0;
896}
897
898static int msm_slim_rx_ch_put(struct snd_kcontrol *kcontrol,
899 struct snd_ctl_elem_value *ucontrol)
900{
901 int ch_num = slim_get_port_idx(kcontrol);
902
903 if (ch_num < 0)
904 return ch_num;
905
906 slim_rx_cfg[ch_num].channels = ucontrol->value.enumerated.item[0] + 1;
907 pr_debug("%s: msm_slim_[%d]_rx_ch = %d\n", __func__,
908 ch_num, slim_rx_cfg[ch_num].channels);
909
910 return 1;
911}
912
913static int msm_slim_tx_ch_get(struct snd_kcontrol *kcontrol,
914 struct snd_ctl_elem_value *ucontrol)
915{
916 int ch_num = slim_get_port_idx(kcontrol);
917
918 if (ch_num < 0)
919 return ch_num;
920
921 pr_debug("%s: msm_slim_[%d]_tx_ch = %d\n", __func__,
922 ch_num, slim_tx_cfg[ch_num].channels);
923 ucontrol->value.enumerated.item[0] = slim_tx_cfg[ch_num].channels - 1;
924
925 return 0;
926}
927
928static int msm_slim_tx_ch_put(struct snd_kcontrol *kcontrol,
929 struct snd_ctl_elem_value *ucontrol)
930{
931 int ch_num = slim_get_port_idx(kcontrol);
932
933 if (ch_num < 0)
934 return ch_num;
935
936 slim_tx_cfg[ch_num].channels = ucontrol->value.enumerated.item[0] + 1;
937 pr_debug("%s: msm_slim_[%d]_tx_ch = %d\n", __func__,
938 ch_num, slim_tx_cfg[ch_num].channels);
939
940 return 1;
941}
942
943static int msm_vi_feed_tx_ch_get(struct snd_kcontrol *kcontrol,
944 struct snd_ctl_elem_value *ucontrol)
945{
946 ucontrol->value.integer.value[0] = msm_vi_feed_tx_ch - 1;
947 pr_debug("%s: msm_vi_feed_tx_ch = %ld\n", __func__,
948 ucontrol->value.integer.value[0]);
949 return 0;
950}
951
952static int msm_vi_feed_tx_ch_put(struct snd_kcontrol *kcontrol,
953 struct snd_ctl_elem_value *ucontrol)
954{
955 msm_vi_feed_tx_ch = ucontrol->value.integer.value[0] + 1;
956
957 pr_debug("%s: msm_vi_feed_tx_ch = %d\n", __func__, msm_vi_feed_tx_ch);
958 return 1;
959}
960
961static int msm_bt_sample_rate_get(struct snd_kcontrol *kcontrol,
962 struct snd_ctl_elem_value *ucontrol)
963{
964 /*
965 * Slimbus_7_Rx/Tx sample rate values should always be in sync (same)
966 * when used for BT_SCO use case. Return either Rx or Tx sample rate
967 * value.
968 */
969 switch (slim_rx_cfg[SLIM_RX_7].sample_rate) {
970 case SAMPLING_RATE_48KHZ:
971 ucontrol->value.integer.value[0] = 2;
972 break;
973 case SAMPLING_RATE_16KHZ:
974 ucontrol->value.integer.value[0] = 1;
975 break;
976 case SAMPLING_RATE_8KHZ:
977 default:
978 ucontrol->value.integer.value[0] = 0;
979 break;
980 }
981 pr_debug("%s: sample rate = %d", __func__,
982 slim_rx_cfg[SLIM_RX_7].sample_rate);
983
984 return 0;
985}
986
987static int msm_bt_sample_rate_put(struct snd_kcontrol *kcontrol,
988 struct snd_ctl_elem_value *ucontrol)
989{
990 switch (ucontrol->value.integer.value[0]) {
991 case 1:
992 slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_16KHZ;
993 slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_16KHZ;
994 break;
995 case 2:
996 slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_48KHZ;
997 slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_48KHZ;
998 break;
999 case 0:
1000 default:
1001 slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_8KHZ;
1002 slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_8KHZ;
1003 break;
1004 }
1005 pr_debug("%s: sample rates: slim7_rx = %d, slim7_tx = %d, value = %d\n",
1006 __func__,
1007 slim_rx_cfg[SLIM_RX_7].sample_rate,
1008 slim_tx_cfg[SLIM_TX_7].sample_rate,
1009 ucontrol->value.enumerated.item[0]);
1010
1011 return 0;
1012}
1013
1014static int usb_audio_rx_ch_get(struct snd_kcontrol *kcontrol,
1015 struct snd_ctl_elem_value *ucontrol)
1016{
1017 pr_debug("%s: usb_audio_rx_ch = %d\n", __func__,
1018 usb_rx_cfg.channels);
1019 ucontrol->value.integer.value[0] = usb_rx_cfg.channels - 1;
1020 return 0;
1021}
1022
1023static int usb_audio_rx_ch_put(struct snd_kcontrol *kcontrol,
1024 struct snd_ctl_elem_value *ucontrol)
1025{
1026 usb_rx_cfg.channels = ucontrol->value.integer.value[0] + 1;
1027
1028 pr_debug("%s: usb_audio_rx_ch = %d\n", __func__, usb_rx_cfg.channels);
1029 return 1;
1030}
1031
1032static int usb_audio_rx_sample_rate_get(struct snd_kcontrol *kcontrol,
1033 struct snd_ctl_elem_value *ucontrol)
1034{
1035 int sample_rate_val;
1036
1037 switch (usb_rx_cfg.sample_rate) {
1038 case SAMPLING_RATE_384KHZ:
1039 sample_rate_val = 12;
1040 break;
1041 case SAMPLING_RATE_352P8KHZ:
1042 sample_rate_val = 11;
1043 break;
1044 case SAMPLING_RATE_192KHZ:
1045 sample_rate_val = 10;
1046 break;
1047 case SAMPLING_RATE_176P4KHZ:
1048 sample_rate_val = 9;
1049 break;
1050 case SAMPLING_RATE_96KHZ:
1051 sample_rate_val = 8;
1052 break;
1053 case SAMPLING_RATE_88P2KHZ:
1054 sample_rate_val = 7;
1055 break;
1056 case SAMPLING_RATE_48KHZ:
1057 sample_rate_val = 6;
1058 break;
1059 case SAMPLING_RATE_44P1KHZ:
1060 sample_rate_val = 5;
1061 break;
1062 case SAMPLING_RATE_32KHZ:
1063 sample_rate_val = 4;
1064 break;
1065 case SAMPLING_RATE_22P05KHZ:
1066 sample_rate_val = 3;
1067 break;
1068 case SAMPLING_RATE_16KHZ:
1069 sample_rate_val = 2;
1070 break;
1071 case SAMPLING_RATE_11P025KHZ:
1072 sample_rate_val = 1;
1073 break;
1074 case SAMPLING_RATE_8KHZ:
1075 default:
1076 sample_rate_val = 0;
1077 break;
1078 }
1079
1080 ucontrol->value.integer.value[0] = sample_rate_val;
1081 pr_debug("%s: usb_audio_rx_sample_rate = %d\n", __func__,
1082 usb_rx_cfg.sample_rate);
1083 return 0;
1084}
1085
1086static int usb_audio_rx_sample_rate_put(struct snd_kcontrol *kcontrol,
1087 struct snd_ctl_elem_value *ucontrol)
1088{
1089 switch (ucontrol->value.integer.value[0]) {
1090 case 12:
1091 usb_rx_cfg.sample_rate = SAMPLING_RATE_384KHZ;
1092 break;
1093 case 11:
1094 usb_rx_cfg.sample_rate = SAMPLING_RATE_352P8KHZ;
1095 break;
1096 case 10:
1097 usb_rx_cfg.sample_rate = SAMPLING_RATE_192KHZ;
1098 break;
1099 case 9:
1100 usb_rx_cfg.sample_rate = SAMPLING_RATE_176P4KHZ;
1101 break;
1102 case 8:
1103 usb_rx_cfg.sample_rate = SAMPLING_RATE_96KHZ;
1104 break;
1105 case 7:
1106 usb_rx_cfg.sample_rate = SAMPLING_RATE_88P2KHZ;
1107 break;
1108 case 6:
1109 usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ;
1110 break;
1111 case 5:
1112 usb_rx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ;
1113 break;
1114 case 4:
1115 usb_rx_cfg.sample_rate = SAMPLING_RATE_32KHZ;
1116 break;
1117 case 3:
1118 usb_rx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ;
1119 break;
1120 case 2:
1121 usb_rx_cfg.sample_rate = SAMPLING_RATE_16KHZ;
1122 break;
1123 case 1:
1124 usb_rx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ;
1125 break;
1126 case 0:
1127 usb_rx_cfg.sample_rate = SAMPLING_RATE_8KHZ;
1128 break;
1129 default:
1130 usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ;
1131 break;
1132 }
1133
1134 pr_debug("%s: control value = %ld, usb_audio_rx_sample_rate = %d\n",
1135 __func__, ucontrol->value.integer.value[0],
1136 usb_rx_cfg.sample_rate);
1137 return 0;
1138}
1139
1140static int usb_audio_rx_format_get(struct snd_kcontrol *kcontrol,
1141 struct snd_ctl_elem_value *ucontrol)
1142{
1143 switch (usb_rx_cfg.bit_format) {
1144 case SNDRV_PCM_FORMAT_S32_LE:
1145 ucontrol->value.integer.value[0] = 3;
1146 break;
1147 case SNDRV_PCM_FORMAT_S24_3LE:
1148 ucontrol->value.integer.value[0] = 2;
1149 break;
1150 case SNDRV_PCM_FORMAT_S24_LE:
1151 ucontrol->value.integer.value[0] = 1;
1152 break;
1153 case SNDRV_PCM_FORMAT_S16_LE:
1154 default:
1155 ucontrol->value.integer.value[0] = 0;
1156 break;
1157 }
1158
1159 pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n",
1160 __func__, usb_rx_cfg.bit_format,
1161 ucontrol->value.integer.value[0]);
1162 return 0;
1163}
1164
1165static int usb_audio_rx_format_put(struct snd_kcontrol *kcontrol,
1166 struct snd_ctl_elem_value *ucontrol)
1167{
1168 int rc = 0;
1169
1170 switch (ucontrol->value.integer.value[0]) {
1171 case 3:
1172 usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE;
1173 break;
1174 case 2:
1175 usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE;
1176 break;
1177 case 1:
1178 usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE;
1179 break;
1180 case 0:
1181 default:
1182 usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE;
1183 break;
1184 }
1185 pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n",
1186 __func__, usb_rx_cfg.bit_format,
1187 ucontrol->value.integer.value[0]);
1188
1189 return rc;
1190}
1191
1192static int usb_audio_tx_ch_get(struct snd_kcontrol *kcontrol,
1193 struct snd_ctl_elem_value *ucontrol)
1194{
1195 pr_debug("%s: usb_audio_tx_ch = %d\n", __func__,
1196 usb_tx_cfg.channels);
1197 ucontrol->value.integer.value[0] = usb_tx_cfg.channels - 1;
1198 return 0;
1199}
1200
1201static int usb_audio_tx_ch_put(struct snd_kcontrol *kcontrol,
1202 struct snd_ctl_elem_value *ucontrol)
1203{
1204 usb_tx_cfg.channels = ucontrol->value.integer.value[0] + 1;
1205
1206 pr_debug("%s: usb_audio_tx_ch = %d\n", __func__, usb_tx_cfg.channels);
1207 return 1;
1208}
1209
1210static int usb_audio_tx_sample_rate_get(struct snd_kcontrol *kcontrol,
1211 struct snd_ctl_elem_value *ucontrol)
1212{
1213 int sample_rate_val;
1214
1215 switch (usb_tx_cfg.sample_rate) {
1216 case SAMPLING_RATE_384KHZ:
1217 sample_rate_val = 12;
1218 break;
1219 case SAMPLING_RATE_352P8KHZ:
1220 sample_rate_val = 11;
1221 break;
1222 case SAMPLING_RATE_192KHZ:
1223 sample_rate_val = 10;
1224 break;
1225 case SAMPLING_RATE_176P4KHZ:
1226 sample_rate_val = 9;
1227 break;
1228 case SAMPLING_RATE_96KHZ:
1229 sample_rate_val = 8;
1230 break;
1231 case SAMPLING_RATE_88P2KHZ:
1232 sample_rate_val = 7;
1233 break;
1234 case SAMPLING_RATE_48KHZ:
1235 sample_rate_val = 6;
1236 break;
1237 case SAMPLING_RATE_44P1KHZ:
1238 sample_rate_val = 5;
1239 break;
1240 case SAMPLING_RATE_32KHZ:
1241 sample_rate_val = 4;
1242 break;
1243 case SAMPLING_RATE_22P05KHZ:
1244 sample_rate_val = 3;
1245 break;
1246 case SAMPLING_RATE_16KHZ:
1247 sample_rate_val = 2;
1248 break;
1249 case SAMPLING_RATE_11P025KHZ:
1250 sample_rate_val = 1;
1251 break;
1252 case SAMPLING_RATE_8KHZ:
1253 sample_rate_val = 0;
1254 break;
1255 default:
1256 sample_rate_val = 6;
1257 break;
1258 }
1259
1260 ucontrol->value.integer.value[0] = sample_rate_val;
1261 pr_debug("%s: usb_audio_tx_sample_rate = %d\n", __func__,
1262 usb_tx_cfg.sample_rate);
1263 return 0;
1264}
1265
1266static int usb_audio_tx_sample_rate_put(struct snd_kcontrol *kcontrol,
1267 struct snd_ctl_elem_value *ucontrol)
1268{
1269 switch (ucontrol->value.integer.value[0]) {
1270 case 12:
1271 usb_tx_cfg.sample_rate = SAMPLING_RATE_384KHZ;
1272 break;
1273 case 11:
1274 usb_tx_cfg.sample_rate = SAMPLING_RATE_352P8KHZ;
1275 break;
1276 case 10:
1277 usb_tx_cfg.sample_rate = SAMPLING_RATE_192KHZ;
1278 break;
1279 case 9:
1280 usb_tx_cfg.sample_rate = SAMPLING_RATE_176P4KHZ;
1281 break;
1282 case 8:
1283 usb_tx_cfg.sample_rate = SAMPLING_RATE_96KHZ;
1284 break;
1285 case 7:
1286 usb_tx_cfg.sample_rate = SAMPLING_RATE_88P2KHZ;
1287 break;
1288 case 6:
1289 usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ;
1290 break;
1291 case 5:
1292 usb_tx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ;
1293 break;
1294 case 4:
1295 usb_tx_cfg.sample_rate = SAMPLING_RATE_32KHZ;
1296 break;
1297 case 3:
1298 usb_tx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ;
1299 break;
1300 case 2:
1301 usb_tx_cfg.sample_rate = SAMPLING_RATE_16KHZ;
1302 break;
1303 case 1:
1304 usb_tx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ;
1305 break;
1306 case 0:
1307 usb_tx_cfg.sample_rate = SAMPLING_RATE_8KHZ;
1308 break;
1309 default:
1310 usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ;
1311 break;
1312 }
1313
1314 pr_debug("%s: control value = %ld, usb_audio_tx_sample_rate = %d\n",
1315 __func__, ucontrol->value.integer.value[0],
1316 usb_tx_cfg.sample_rate);
1317 return 0;
1318}
1319
1320static int usb_audio_tx_format_get(struct snd_kcontrol *kcontrol,
1321 struct snd_ctl_elem_value *ucontrol)
1322{
1323 switch (usb_tx_cfg.bit_format) {
1324 case SNDRV_PCM_FORMAT_S32_LE:
1325 ucontrol->value.integer.value[0] = 3;
1326 break;
1327 case SNDRV_PCM_FORMAT_S24_3LE:
1328 ucontrol->value.integer.value[0] = 2;
1329 break;
1330 case SNDRV_PCM_FORMAT_S24_LE:
1331 ucontrol->value.integer.value[0] = 1;
1332 break;
1333 case SNDRV_PCM_FORMAT_S16_LE:
1334 default:
1335 ucontrol->value.integer.value[0] = 0;
1336 break;
1337 }
1338
1339 pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n",
1340 __func__, usb_tx_cfg.bit_format,
1341 ucontrol->value.integer.value[0]);
1342 return 0;
1343}
1344
1345static int usb_audio_tx_format_put(struct snd_kcontrol *kcontrol,
1346 struct snd_ctl_elem_value *ucontrol)
1347{
1348 int rc = 0;
1349
1350 switch (ucontrol->value.integer.value[0]) {
1351 case 3:
1352 usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE;
1353 break;
1354 case 2:
1355 usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE;
1356 break;
1357 case 1:
1358 usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE;
1359 break;
1360 case 0:
1361 default:
1362 usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE;
1363 break;
1364 }
1365 pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n",
1366 __func__, usb_tx_cfg.bit_format,
1367 ucontrol->value.integer.value[0]);
1368
1369 return rc;
1370}
1371
1372static int ext_disp_get_port_idx(struct snd_kcontrol *kcontrol)
1373{
1374 int idx;
1375
1376 if (strnstr(kcontrol->id.name, "HDMI_RX", sizeof("HDMI_RX")))
1377 idx = HDMI_RX_IDX;
1378 else if (strnstr(kcontrol->id.name, "Display Port RX",
1379 sizeof("Display Port RX")))
1380 idx = DP_RX_IDX;
1381 else {
1382 pr_err("%s: unsupported BE: %s",
1383 __func__, kcontrol->id.name);
1384 idx = -EINVAL;
1385 }
1386
1387 return idx;
1388}
1389
1390static int ext_disp_rx_format_get(struct snd_kcontrol *kcontrol,
1391 struct snd_ctl_elem_value *ucontrol)
1392{
1393 int idx = ext_disp_get_port_idx(kcontrol);
1394
1395 if (idx < 0)
1396 return idx;
1397
1398 switch (ext_disp_rx_cfg[idx].bit_format) {
1399 case SNDRV_PCM_FORMAT_S24_LE:
1400 ucontrol->value.integer.value[0] = 1;
1401 break;
1402
1403 case SNDRV_PCM_FORMAT_S16_LE:
1404 default:
1405 ucontrol->value.integer.value[0] = 0;
1406 break;
1407 }
1408
1409 pr_debug("%s: ext_disp_rx[%d].format = %d, ucontrol value = %ld\n",
1410 __func__, idx, ext_disp_rx_cfg[idx].bit_format,
1411 ucontrol->value.integer.value[0]);
1412 return 0;
1413}
1414
1415static int ext_disp_rx_format_put(struct snd_kcontrol *kcontrol,
1416 struct snd_ctl_elem_value *ucontrol)
1417{
1418 int idx = ext_disp_get_port_idx(kcontrol);
1419
1420 if (idx < 0)
1421 return idx;
1422
1423 switch (ucontrol->value.integer.value[0]) {
1424 case 1:
1425 ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S24_LE;
1426 break;
1427 case 0:
1428 default:
1429 ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S16_LE;
1430 break;
1431 }
1432 pr_debug("%s: ext_disp_rx[%d].format = %d, ucontrol value = %ld\n",
1433 __func__, idx, ext_disp_rx_cfg[idx].bit_format,
1434 ucontrol->value.integer.value[0]);
1435
1436 return 0;
1437}
1438
1439static int ext_disp_rx_ch_get(struct snd_kcontrol *kcontrol,
1440 struct snd_ctl_elem_value *ucontrol)
1441{
1442 int idx = ext_disp_get_port_idx(kcontrol);
1443
1444 if (idx < 0)
1445 return idx;
1446
1447 ucontrol->value.integer.value[0] =
1448 ext_disp_rx_cfg[idx].channels - 2;
1449
1450 pr_debug("%s: ext_disp_rx[%d].ch = %d\n", __func__,
1451 idx, ext_disp_rx_cfg[idx].channels);
1452
1453 return 0;
1454}
1455
1456static int ext_disp_rx_ch_put(struct snd_kcontrol *kcontrol,
1457 struct snd_ctl_elem_value *ucontrol)
1458{
1459 int idx = ext_disp_get_port_idx(kcontrol);
1460
1461 if (idx < 0)
1462 return idx;
1463
1464 ext_disp_rx_cfg[idx].channels =
1465 ucontrol->value.integer.value[0] + 2;
1466
1467 pr_debug("%s: ext_disp_rx[%d].ch = %d\n", __func__,
1468 idx, ext_disp_rx_cfg[idx].channels);
1469 return 1;
1470}
1471
1472static int ext_disp_rx_sample_rate_get(struct snd_kcontrol *kcontrol,
1473 struct snd_ctl_elem_value *ucontrol)
1474{
1475 int sample_rate_val;
1476 int idx = ext_disp_get_port_idx(kcontrol);
1477
1478 if (idx < 0)
1479 return idx;
1480
1481 switch (ext_disp_rx_cfg[idx].sample_rate) {
1482 case SAMPLING_RATE_192KHZ:
1483 sample_rate_val = 2;
1484 break;
1485
1486 case SAMPLING_RATE_96KHZ:
1487 sample_rate_val = 1;
1488 break;
1489
1490 case SAMPLING_RATE_48KHZ:
1491 default:
1492 sample_rate_val = 0;
1493 break;
1494 }
1495
1496 ucontrol->value.integer.value[0] = sample_rate_val;
1497 pr_debug("%s: ext_disp_rx[%d].sample_rate = %d\n", __func__,
1498 idx, ext_disp_rx_cfg[idx].sample_rate);
1499
1500 return 0;
1501}
1502
1503static int ext_disp_rx_sample_rate_put(struct snd_kcontrol *kcontrol,
1504 struct snd_ctl_elem_value *ucontrol)
1505{
1506 int idx = ext_disp_get_port_idx(kcontrol);
1507
1508 if (idx < 0)
1509 return idx;
1510
1511 switch (ucontrol->value.integer.value[0]) {
1512 case 2:
1513 ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_192KHZ;
1514 break;
1515 case 1:
1516 ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_96KHZ;
1517 break;
1518 case 0:
1519 default:
1520 ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_48KHZ;
1521 break;
1522 }
1523
1524 pr_debug("%s: control value = %ld, ext_disp_rx[%d].sample_rate = %d\n",
1525 __func__, ucontrol->value.integer.value[0], idx,
1526 ext_disp_rx_cfg[idx].sample_rate);
1527 return 0;
1528}
1529
1530static int proxy_rx_ch_get(struct snd_kcontrol *kcontrol,
1531 struct snd_ctl_elem_value *ucontrol)
1532{
1533 pr_debug("%s: proxy_rx channels = %d\n",
1534 __func__, proxy_rx_cfg.channels);
1535 ucontrol->value.integer.value[0] = proxy_rx_cfg.channels - 2;
1536
1537 return 0;
1538}
1539
1540static int proxy_rx_ch_put(struct snd_kcontrol *kcontrol,
1541 struct snd_ctl_elem_value *ucontrol)
1542{
1543 proxy_rx_cfg.channels = ucontrol->value.integer.value[0] + 2;
1544 pr_debug("%s: proxy_rx channels = %d\n",
1545 __func__, proxy_rx_cfg.channels);
1546
1547 return 1;
1548}
1549
1550static int tdm_get_sample_rate(int value)
1551{
1552 int sample_rate = 0;
1553
1554 switch (value) {
1555 case 0:
1556 sample_rate = SAMPLING_RATE_8KHZ;
1557 break;
1558 case 1:
1559 sample_rate = SAMPLING_RATE_16KHZ;
1560 break;
1561 case 2:
1562 sample_rate = SAMPLING_RATE_32KHZ;
1563 break;
1564 case 3:
1565 sample_rate = SAMPLING_RATE_44P1KHZ;
1566 break;
1567 case 4:
1568 sample_rate = SAMPLING_RATE_48KHZ;
1569 break;
1570 case 5:
1571 sample_rate = SAMPLING_RATE_96KHZ;
1572 break;
1573 case 6:
1574 sample_rate = SAMPLING_RATE_192KHZ;
1575 break;
1576 case 7:
1577 sample_rate = SAMPLING_RATE_352P8KHZ;
1578 break;
1579 case 8:
1580 sample_rate = SAMPLING_RATE_384KHZ;
1581 break;
1582 default:
1583 sample_rate = SAMPLING_RATE_48KHZ;
1584 break;
1585 }
1586 return sample_rate;
1587}
1588
1589static int aux_pcm_get_sample_rate(int value)
1590{
1591 int sample_rate;
1592
1593 switch (value) {
1594 case 1:
1595 sample_rate = SAMPLING_RATE_16KHZ;
1596 break;
1597 case 0:
1598 default:
1599 sample_rate = SAMPLING_RATE_8KHZ;
1600 break;
1601 }
1602 return sample_rate;
1603}
1604
1605static int tdm_get_sample_rate_val(int sample_rate)
1606{
1607 int sample_rate_val = 0;
1608
1609 switch (sample_rate) {
1610 case SAMPLING_RATE_8KHZ:
1611 sample_rate_val = 0;
1612 break;
1613 case SAMPLING_RATE_16KHZ:
1614 sample_rate_val = 1;
1615 break;
1616 case SAMPLING_RATE_32KHZ:
1617 sample_rate_val = 2;
1618 break;
1619 case SAMPLING_RATE_44P1KHZ:
1620 sample_rate_val = 3;
1621 break;
1622 case SAMPLING_RATE_48KHZ:
1623 sample_rate_val = 4;
1624 break;
1625 case SAMPLING_RATE_96KHZ:
1626 sample_rate_val = 5;
1627 break;
1628 case SAMPLING_RATE_192KHZ:
1629 sample_rate_val = 6;
1630 break;
1631 case SAMPLING_RATE_352P8KHZ:
1632 sample_rate_val = 7;
1633 break;
1634 case SAMPLING_RATE_384KHZ:
1635 sample_rate_val = 8;
1636 break;
1637 default:
1638 sample_rate_val = 4;
1639 break;
1640 }
1641 return sample_rate_val;
1642}
1643
1644static int aux_pcm_get_sample_rate_val(int sample_rate)
1645{
1646 int sample_rate_val;
1647
1648 switch (sample_rate) {
1649 case SAMPLING_RATE_16KHZ:
1650 sample_rate_val = 1;
1651 break;
1652 case SAMPLING_RATE_8KHZ:
1653 default:
1654 sample_rate_val = 0;
1655 break;
1656 }
1657 return sample_rate_val;
1658}
1659
1660static int tdm_get_port_idx(struct snd_kcontrol *kcontrol,
1661 struct tdm_port *port)
1662{
1663 if (port) {
1664 if (strnstr(kcontrol->id.name, "PRI",
1665 sizeof(kcontrol->id.name))) {
1666 port->mode = TDM_PRI;
1667 } else if (strnstr(kcontrol->id.name, "SEC",
1668 sizeof(kcontrol->id.name))) {
1669 port->mode = TDM_SEC;
1670 } else if (strnstr(kcontrol->id.name, "TERT",
1671 sizeof(kcontrol->id.name))) {
1672 port->mode = TDM_TERT;
1673 } else if (strnstr(kcontrol->id.name, "QUAT",
1674 sizeof(kcontrol->id.name))) {
1675 port->mode = TDM_QUAT;
1676 } else {
1677 pr_err("%s: unsupported mode in: %s",
1678 __func__, kcontrol->id.name);
1679 return -EINVAL;
1680 }
1681
1682 if (strnstr(kcontrol->id.name, "RX_0",
1683 sizeof(kcontrol->id.name)) ||
1684 strnstr(kcontrol->id.name, "TX_0",
1685 sizeof(kcontrol->id.name))) {
1686 port->channel = TDM_0;
1687 } else if (strnstr(kcontrol->id.name, "RX_1",
1688 sizeof(kcontrol->id.name)) ||
1689 strnstr(kcontrol->id.name, "TX_1",
1690 sizeof(kcontrol->id.name))) {
1691 port->channel = TDM_1;
1692 } else if (strnstr(kcontrol->id.name, "RX_2",
1693 sizeof(kcontrol->id.name)) ||
1694 strnstr(kcontrol->id.name, "TX_2",
1695 sizeof(kcontrol->id.name))) {
1696 port->channel = TDM_2;
1697 } else if (strnstr(kcontrol->id.name, "RX_3",
1698 sizeof(kcontrol->id.name)) ||
1699 strnstr(kcontrol->id.name, "TX_3",
1700 sizeof(kcontrol->id.name))) {
1701 port->channel = TDM_3;
1702 } else if (strnstr(kcontrol->id.name, "RX_4",
1703 sizeof(kcontrol->id.name)) ||
1704 strnstr(kcontrol->id.name, "TX_4",
1705 sizeof(kcontrol->id.name))) {
1706 port->channel = TDM_4;
1707 } else if (strnstr(kcontrol->id.name, "RX_5",
1708 sizeof(kcontrol->id.name)) ||
1709 strnstr(kcontrol->id.name, "TX_5",
1710 sizeof(kcontrol->id.name))) {
1711 port->channel = TDM_5;
1712 } else if (strnstr(kcontrol->id.name, "RX_6",
1713 sizeof(kcontrol->id.name)) ||
1714 strnstr(kcontrol->id.name, "TX_6",
1715 sizeof(kcontrol->id.name))) {
1716 port->channel = TDM_6;
1717 } else if (strnstr(kcontrol->id.name, "RX_7",
1718 sizeof(kcontrol->id.name)) ||
1719 strnstr(kcontrol->id.name, "TX_7",
1720 sizeof(kcontrol->id.name))) {
1721 port->channel = TDM_7;
1722 } else {
1723 pr_err("%s: unsupported channel in: %s",
1724 __func__, kcontrol->id.name);
1725 return -EINVAL;
1726 }
1727 } else
1728 return -EINVAL;
1729 return 0;
1730}
1731
1732static int tdm_rx_sample_rate_get(struct snd_kcontrol *kcontrol,
1733 struct snd_ctl_elem_value *ucontrol)
1734{
1735 struct tdm_port port;
1736 int ret = tdm_get_port_idx(kcontrol, &port);
1737
1738 if (ret) {
1739 pr_err("%s: unsupported control: %s",
1740 __func__, kcontrol->id.name);
1741 } else {
1742 ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val(
1743 tdm_rx_cfg[port.mode][port.channel].sample_rate);
1744
1745 pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__,
1746 tdm_rx_cfg[port.mode][port.channel].sample_rate,
1747 ucontrol->value.enumerated.item[0]);
1748 }
1749 return ret;
1750}
1751
1752static int tdm_rx_sample_rate_put(struct snd_kcontrol *kcontrol,
1753 struct snd_ctl_elem_value *ucontrol)
1754{
1755 struct tdm_port port;
1756 int ret = tdm_get_port_idx(kcontrol, &port);
1757
1758 if (ret) {
1759 pr_err("%s: unsupported control: %s",
1760 __func__, kcontrol->id.name);
1761 } else {
1762 tdm_rx_cfg[port.mode][port.channel].sample_rate =
1763 tdm_get_sample_rate(ucontrol->value.enumerated.item[0]);
1764
1765 pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__,
1766 tdm_rx_cfg[port.mode][port.channel].sample_rate,
1767 ucontrol->value.enumerated.item[0]);
1768 }
1769 return ret;
1770}
1771
1772static int tdm_tx_sample_rate_get(struct snd_kcontrol *kcontrol,
1773 struct snd_ctl_elem_value *ucontrol)
1774{
1775 struct tdm_port port;
1776 int ret = tdm_get_port_idx(kcontrol, &port);
1777
1778 if (ret) {
1779 pr_err("%s: unsupported control: %s",
1780 __func__, kcontrol->id.name);
1781 } else {
1782 ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val(
1783 tdm_tx_cfg[port.mode][port.channel].sample_rate);
1784
1785 pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__,
1786 tdm_tx_cfg[port.mode][port.channel].sample_rate,
1787 ucontrol->value.enumerated.item[0]);
1788 }
1789 return ret;
1790}
1791
1792static int tdm_tx_sample_rate_put(struct snd_kcontrol *kcontrol,
1793 struct snd_ctl_elem_value *ucontrol)
1794{
1795 struct tdm_port port;
1796 int ret = tdm_get_port_idx(kcontrol, &port);
1797
1798 if (ret) {
1799 pr_err("%s: unsupported control: %s",
1800 __func__, kcontrol->id.name);
1801 } else {
1802 tdm_tx_cfg[port.mode][port.channel].sample_rate =
1803 tdm_get_sample_rate(ucontrol->value.enumerated.item[0]);
1804
1805 pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__,
1806 tdm_tx_cfg[port.mode][port.channel].sample_rate,
1807 ucontrol->value.enumerated.item[0]);
1808 }
1809 return ret;
1810}
1811
1812static int tdm_get_format(int value)
1813{
1814 int format = 0;
1815
1816 switch (value) {
1817 case 0:
1818 format = SNDRV_PCM_FORMAT_S16_LE;
1819 break;
1820 case 1:
1821 format = SNDRV_PCM_FORMAT_S24_LE;
1822 break;
1823 case 2:
1824 format = SNDRV_PCM_FORMAT_S32_LE;
1825 break;
1826 default:
1827 format = SNDRV_PCM_FORMAT_S16_LE;
1828 break;
1829 }
1830 return format;
1831}
1832
1833static int tdm_get_format_val(int format)
1834{
1835 int value = 0;
1836
1837 switch (format) {
1838 case SNDRV_PCM_FORMAT_S16_LE:
1839 value = 0;
1840 break;
1841 case SNDRV_PCM_FORMAT_S24_LE:
1842 value = 1;
1843 break;
1844 case SNDRV_PCM_FORMAT_S32_LE:
1845 value = 2;
1846 break;
1847 default:
1848 value = 0;
1849 break;
1850 }
1851 return value;
1852}
1853
1854static int tdm_rx_format_get(struct snd_kcontrol *kcontrol,
1855 struct snd_ctl_elem_value *ucontrol)
1856{
1857 struct tdm_port port;
1858 int ret = tdm_get_port_idx(kcontrol, &port);
1859
1860 if (ret) {
1861 pr_err("%s: unsupported control: %s",
1862 __func__, kcontrol->id.name);
1863 } else {
1864 ucontrol->value.enumerated.item[0] = tdm_get_format_val(
1865 tdm_rx_cfg[port.mode][port.channel].bit_format);
1866
1867 pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__,
1868 tdm_rx_cfg[port.mode][port.channel].bit_format,
1869 ucontrol->value.enumerated.item[0]);
1870 }
1871 return ret;
1872}
1873
1874static int tdm_rx_format_put(struct snd_kcontrol *kcontrol,
1875 struct snd_ctl_elem_value *ucontrol)
1876{
1877 struct tdm_port port;
1878 int ret = tdm_get_port_idx(kcontrol, &port);
1879
1880 if (ret) {
1881 pr_err("%s: unsupported control: %s",
1882 __func__, kcontrol->id.name);
1883 } else {
1884 tdm_rx_cfg[port.mode][port.channel].bit_format =
1885 tdm_get_format(ucontrol->value.enumerated.item[0]);
1886
1887 pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__,
1888 tdm_rx_cfg[port.mode][port.channel].bit_format,
1889 ucontrol->value.enumerated.item[0]);
1890 }
1891 return ret;
1892}
1893
1894static int tdm_tx_format_get(struct snd_kcontrol *kcontrol,
1895 struct snd_ctl_elem_value *ucontrol)
1896{
1897 struct tdm_port port;
1898 int ret = tdm_get_port_idx(kcontrol, &port);
1899
1900 if (ret) {
1901 pr_err("%s: unsupported control: %s",
1902 __func__, kcontrol->id.name);
1903 } else {
1904 ucontrol->value.enumerated.item[0] = tdm_get_format_val(
1905 tdm_tx_cfg[port.mode][port.channel].bit_format);
1906
1907 pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__,
1908 tdm_tx_cfg[port.mode][port.channel].bit_format,
1909 ucontrol->value.enumerated.item[0]);
1910 }
1911 return ret;
1912}
1913
1914static int tdm_tx_format_put(struct snd_kcontrol *kcontrol,
1915 struct snd_ctl_elem_value *ucontrol)
1916{
1917 struct tdm_port port;
1918 int ret = tdm_get_port_idx(kcontrol, &port);
1919
1920 if (ret) {
1921 pr_err("%s: unsupported control: %s",
1922 __func__, kcontrol->id.name);
1923 } else {
1924 tdm_tx_cfg[port.mode][port.channel].bit_format =
1925 tdm_get_format(ucontrol->value.enumerated.item[0]);
1926
1927 pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__,
1928 tdm_tx_cfg[port.mode][port.channel].bit_format,
1929 ucontrol->value.enumerated.item[0]);
1930 }
1931 return ret;
1932}
1933
1934static int tdm_rx_ch_get(struct snd_kcontrol *kcontrol,
1935 struct snd_ctl_elem_value *ucontrol)
1936{
1937 struct tdm_port port;
1938 int ret = tdm_get_port_idx(kcontrol, &port);
1939
1940 if (ret) {
1941 pr_err("%s: unsupported control: %s",
1942 __func__, kcontrol->id.name);
1943 } else {
1944
1945 ucontrol->value.enumerated.item[0] =
1946 tdm_rx_cfg[port.mode][port.channel].channels - 1;
1947
1948 pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__,
1949 tdm_rx_cfg[port.mode][port.channel].channels - 1,
1950 ucontrol->value.enumerated.item[0]);
1951 }
1952 return ret;
1953}
1954
1955static int tdm_rx_ch_put(struct snd_kcontrol *kcontrol,
1956 struct snd_ctl_elem_value *ucontrol)
1957{
1958 struct tdm_port port;
1959 int ret = tdm_get_port_idx(kcontrol, &port);
1960
1961 if (ret) {
1962 pr_err("%s: unsupported control: %s",
1963 __func__, kcontrol->id.name);
1964 } else {
1965 tdm_rx_cfg[port.mode][port.channel].channels =
1966 ucontrol->value.enumerated.item[0] + 1;
1967
1968 pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__,
1969 tdm_rx_cfg[port.mode][port.channel].channels,
1970 ucontrol->value.enumerated.item[0] + 1);
1971 }
1972 return ret;
1973}
1974
1975static int tdm_tx_ch_get(struct snd_kcontrol *kcontrol,
1976 struct snd_ctl_elem_value *ucontrol)
1977{
1978 struct tdm_port port;
1979 int ret = tdm_get_port_idx(kcontrol, &port);
1980
1981 if (ret) {
1982 pr_err("%s: unsupported control: %s",
1983 __func__, kcontrol->id.name);
1984 } else {
1985 ucontrol->value.enumerated.item[0] =
1986 tdm_tx_cfg[port.mode][port.channel].channels - 1;
1987
1988 pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__,
1989 tdm_tx_cfg[port.mode][port.channel].channels - 1,
1990 ucontrol->value.enumerated.item[0]);
1991 }
1992 return ret;
1993}
1994
1995static int tdm_tx_ch_put(struct snd_kcontrol *kcontrol,
1996 struct snd_ctl_elem_value *ucontrol)
1997{
1998 struct tdm_port port;
1999 int ret = tdm_get_port_idx(kcontrol, &port);
2000
2001 if (ret) {
2002 pr_err("%s: unsupported control: %s",
2003 __func__, kcontrol->id.name);
2004 } else {
2005 tdm_tx_cfg[port.mode][port.channel].channels =
2006 ucontrol->value.enumerated.item[0] + 1;
2007
2008 pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__,
2009 tdm_tx_cfg[port.mode][port.channel].channels,
2010 ucontrol->value.enumerated.item[0] + 1);
2011 }
2012 return ret;
2013}
2014
2015static int aux_pcm_get_port_idx(struct snd_kcontrol *kcontrol)
2016{
2017 int idx;
2018
2019 if (strnstr(kcontrol->id.name, "PRIM_AUX_PCM",
2020 sizeof("PRIM_AUX_PCM")))
2021 idx = PRIM_AUX_PCM;
2022 else if (strnstr(kcontrol->id.name, "SEC_AUX_PCM",
2023 sizeof("SEC_AUX_PCM")))
2024 idx = SEC_AUX_PCM;
2025 else if (strnstr(kcontrol->id.name, "TERT_AUX_PCM",
2026 sizeof("TERT_AUX_PCM")))
2027 idx = TERT_AUX_PCM;
2028 else if (strnstr(kcontrol->id.name, "QUAT_AUX_PCM",
2029 sizeof("QUAT_AUX_PCM")))
2030 idx = QUAT_AUX_PCM;
2031 else {
2032 pr_err("%s: unsupported port: %s",
2033 __func__, kcontrol->id.name);
2034 idx = -EINVAL;
2035 }
2036
2037 return idx;
2038}
2039
2040static int aux_pcm_rx_sample_rate_put(struct snd_kcontrol *kcontrol,
2041 struct snd_ctl_elem_value *ucontrol)
2042{
2043 int idx = aux_pcm_get_port_idx(kcontrol);
2044
2045 if (idx < 0)
2046 return idx;
2047
2048 aux_pcm_rx_cfg[idx].sample_rate =
2049 aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]);
2050
2051 pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__,
2052 idx, aux_pcm_rx_cfg[idx].sample_rate,
2053 ucontrol->value.enumerated.item[0]);
2054
2055 return 0;
2056}
2057
2058static int aux_pcm_rx_sample_rate_get(struct snd_kcontrol *kcontrol,
2059 struct snd_ctl_elem_value *ucontrol)
2060{
2061 int idx = aux_pcm_get_port_idx(kcontrol);
2062
2063 if (idx < 0)
2064 return idx;
2065
2066 ucontrol->value.enumerated.item[0] =
2067 aux_pcm_get_sample_rate_val(aux_pcm_rx_cfg[idx].sample_rate);
2068
2069 pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__,
2070 idx, aux_pcm_rx_cfg[idx].sample_rate,
2071 ucontrol->value.enumerated.item[0]);
2072
2073 return 0;
2074}
2075
2076static int aux_pcm_tx_sample_rate_put(struct snd_kcontrol *kcontrol,
2077 struct snd_ctl_elem_value *ucontrol)
2078{
2079 int idx = aux_pcm_get_port_idx(kcontrol);
2080
2081 if (idx < 0)
2082 return idx;
2083
2084 aux_pcm_tx_cfg[idx].sample_rate =
2085 aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]);
2086
2087 pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__,
2088 idx, aux_pcm_tx_cfg[idx].sample_rate,
2089 ucontrol->value.enumerated.item[0]);
2090
2091 return 0;
2092}
2093
2094static int aux_pcm_tx_sample_rate_get(struct snd_kcontrol *kcontrol,
2095 struct snd_ctl_elem_value *ucontrol)
2096{
2097 int idx = aux_pcm_get_port_idx(kcontrol);
2098
2099 if (idx < 0)
2100 return idx;
2101
2102 ucontrol->value.enumerated.item[0] =
2103 aux_pcm_get_sample_rate_val(aux_pcm_tx_cfg[idx].sample_rate);
2104
2105 pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__,
2106 idx, aux_pcm_tx_cfg[idx].sample_rate,
2107 ucontrol->value.enumerated.item[0]);
2108
2109 return 0;
2110}
2111
2112static int mi2s_get_port_idx(struct snd_kcontrol *kcontrol)
2113{
2114 int idx;
2115
2116 if (strnstr(kcontrol->id.name, "PRIM_MI2S_RX",
2117 sizeof("PRIM_MI2S_RX")))
2118 idx = PRIM_MI2S;
2119 else if (strnstr(kcontrol->id.name, "SEC_MI2S_RX",
2120 sizeof("SEC_MI2S_RX")))
2121 idx = SEC_MI2S;
2122 else if (strnstr(kcontrol->id.name, "TERT_MI2S_RX",
2123 sizeof("TERT_MI2S_RX")))
2124 idx = TERT_MI2S;
2125 else if (strnstr(kcontrol->id.name, "QUAT_MI2S_RX",
2126 sizeof("QUAT_MI2S_RX")))
2127 idx = QUAT_MI2S;
2128 else if (strnstr(kcontrol->id.name, "PRIM_MI2S_TX",
2129 sizeof("PRIM_MI2S_TX")))
2130 idx = PRIM_MI2S;
2131 else if (strnstr(kcontrol->id.name, "SEC_MI2S_TX",
2132 sizeof("SEC_MI2S_TX")))
2133 idx = SEC_MI2S;
2134 else if (strnstr(kcontrol->id.name, "TERT_MI2S_TX",
2135 sizeof("TERT_MI2S_TX")))
2136 idx = TERT_MI2S;
2137 else if (strnstr(kcontrol->id.name, "QUAT_MI2S_TX",
2138 sizeof("QUAT_MI2S_TX")))
2139 idx = QUAT_MI2S;
2140 else {
2141 pr_err("%s: unsupported channel: %s",
2142 __func__, kcontrol->id.name);
2143 idx = -EINVAL;
2144 }
2145
2146 return idx;
2147}
2148
2149static int mi2s_get_sample_rate_val(int sample_rate)
2150{
2151 int sample_rate_val;
2152
2153 switch (sample_rate) {
2154 case SAMPLING_RATE_8KHZ:
2155 sample_rate_val = 0;
2156 break;
2157 case SAMPLING_RATE_16KHZ:
2158 sample_rate_val = 1;
2159 break;
2160 case SAMPLING_RATE_32KHZ:
2161 sample_rate_val = 2;
2162 break;
2163 case SAMPLING_RATE_44P1KHZ:
2164 sample_rate_val = 3;
2165 break;
2166 case SAMPLING_RATE_48KHZ:
2167 sample_rate_val = 4;
2168 break;
2169 case SAMPLING_RATE_96KHZ:
2170 sample_rate_val = 5;
2171 break;
2172 case SAMPLING_RATE_192KHZ:
2173 sample_rate_val = 6;
2174 break;
2175 default:
2176 sample_rate_val = 4;
2177 break;
2178 }
2179 return sample_rate_val;
2180}
2181
2182static int mi2s_get_sample_rate(int value)
2183{
2184 int sample_rate;
2185
2186 switch (value) {
2187 case 0:
2188 sample_rate = SAMPLING_RATE_8KHZ;
2189 break;
2190 case 1:
2191 sample_rate = SAMPLING_RATE_16KHZ;
2192 break;
2193 case 2:
2194 sample_rate = SAMPLING_RATE_32KHZ;
2195 break;
2196 case 3:
2197 sample_rate = SAMPLING_RATE_44P1KHZ;
2198 break;
2199 case 4:
2200 sample_rate = SAMPLING_RATE_48KHZ;
2201 break;
2202 case 5:
2203 sample_rate = SAMPLING_RATE_96KHZ;
2204 break;
2205 case 6:
2206 sample_rate = SAMPLING_RATE_192KHZ;
2207 break;
2208 default:
2209 sample_rate = SAMPLING_RATE_48KHZ;
2210 break;
2211 }
2212 return sample_rate;
2213}
2214
2215static int mi2s_rx_sample_rate_put(struct snd_kcontrol *kcontrol,
2216 struct snd_ctl_elem_value *ucontrol)
2217{
2218 int idx = mi2s_get_port_idx(kcontrol);
2219
2220 if (idx < 0)
2221 return idx;
2222
2223 mi2s_rx_cfg[idx].sample_rate =
2224 mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]);
2225
2226 pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__,
2227 idx, mi2s_rx_cfg[idx].sample_rate,
2228 ucontrol->value.enumerated.item[0]);
2229
2230 return 0;
2231}
2232
2233static int mi2s_rx_sample_rate_get(struct snd_kcontrol *kcontrol,
2234 struct snd_ctl_elem_value *ucontrol)
2235{
2236 int idx = mi2s_get_port_idx(kcontrol);
2237
2238 if (idx < 0)
2239 return idx;
2240
2241 ucontrol->value.enumerated.item[0] =
2242 mi2s_get_sample_rate_val(mi2s_rx_cfg[idx].sample_rate);
2243
2244 pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__,
2245 idx, mi2s_rx_cfg[idx].sample_rate,
2246 ucontrol->value.enumerated.item[0]);
2247
2248 return 0;
2249}
2250
2251static int mi2s_tx_sample_rate_put(struct snd_kcontrol *kcontrol,
2252 struct snd_ctl_elem_value *ucontrol)
2253{
2254 int idx = mi2s_get_port_idx(kcontrol);
2255
2256 if (idx < 0)
2257 return idx;
2258
2259 mi2s_tx_cfg[idx].sample_rate =
2260 mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]);
2261
2262 pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__,
2263 idx, mi2s_tx_cfg[idx].sample_rate,
2264 ucontrol->value.enumerated.item[0]);
2265
2266 return 0;
2267}
2268
2269static int mi2s_tx_sample_rate_get(struct snd_kcontrol *kcontrol,
2270 struct snd_ctl_elem_value *ucontrol)
2271{
2272 int idx = mi2s_get_port_idx(kcontrol);
2273
2274 if (idx < 0)
2275 return idx;
2276
2277 ucontrol->value.enumerated.item[0] =
2278 mi2s_get_sample_rate_val(mi2s_tx_cfg[idx].sample_rate);
2279
2280 pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__,
2281 idx, mi2s_tx_cfg[idx].sample_rate,
2282 ucontrol->value.enumerated.item[0]);
2283
2284 return 0;
2285}
2286
2287static int msm_mi2s_rx_ch_get(struct snd_kcontrol *kcontrol,
2288 struct snd_ctl_elem_value *ucontrol)
2289{
2290 int idx = mi2s_get_port_idx(kcontrol);
2291
2292 if (idx < 0)
2293 return idx;
2294
2295 pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__,
2296 idx, mi2s_rx_cfg[idx].channels);
2297 ucontrol->value.enumerated.item[0] = mi2s_rx_cfg[idx].channels - 1;
2298
2299 return 0;
2300}
2301
2302static int msm_mi2s_rx_ch_put(struct snd_kcontrol *kcontrol,
2303 struct snd_ctl_elem_value *ucontrol)
2304{
2305 int idx = mi2s_get_port_idx(kcontrol);
2306
2307 if (idx < 0)
2308 return idx;
2309
2310 mi2s_rx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1;
2311 pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__,
2312 idx, mi2s_rx_cfg[idx].channels);
2313
2314 return 1;
2315}
2316
2317static int msm_mi2s_tx_ch_get(struct snd_kcontrol *kcontrol,
2318 struct snd_ctl_elem_value *ucontrol)
2319{
2320 int idx = mi2s_get_port_idx(kcontrol);
2321
2322 if (idx < 0)
2323 return idx;
2324
2325 pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__,
2326 idx, mi2s_tx_cfg[idx].channels);
2327 ucontrol->value.enumerated.item[0] = mi2s_tx_cfg[idx].channels - 1;
2328
2329 return 0;
2330}
2331
2332static int msm_mi2s_tx_ch_put(struct snd_kcontrol *kcontrol,
2333 struct snd_ctl_elem_value *ucontrol)
2334{
2335 int idx = mi2s_get_port_idx(kcontrol);
2336
2337 if (idx < 0)
2338 return idx;
2339
2340 mi2s_tx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1;
2341 pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__,
2342 idx, mi2s_tx_cfg[idx].channels);
2343
2344 return 1;
2345}
2346
2347static int msm_hifi_ctrl(struct snd_soc_codec *codec)
2348{
2349 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
2350 struct snd_soc_card *card = codec->component.card;
2351 struct msm_asoc_mach_data *pdata =
2352 snd_soc_card_get_drvdata(card);
2353
2354 pr_debug("%s: msm_hifi_control = %d", __func__,
2355 msm_hifi_control);
2356
2357 if (!pdata || !pdata->hph_en1_gpio_p) {
2358 pr_err("%s: hph_en1_gpio is invalid\n", __func__);
2359 return -EINVAL;
2360 }
2361 if (msm_hifi_control == MSM_HIFI_ON) {
2362 msm_cdc_pinctrl_select_active_state(pdata->hph_en1_gpio_p);
2363 /* 5msec delay needed as per HW requirement */
2364 usleep_range(5000, 5010);
2365 } else {
2366 msm_cdc_pinctrl_select_sleep_state(pdata->hph_en1_gpio_p);
2367 }
2368 snd_soc_dapm_sync(dapm);
2369
2370 return 0;
2371}
2372
2373static int msm_hifi_get(struct snd_kcontrol *kcontrol,
2374 struct snd_ctl_elem_value *ucontrol)
2375{
2376 pr_debug("%s: msm_hifi_control = %d\n",
2377 __func__, msm_hifi_control);
2378 ucontrol->value.integer.value[0] = msm_hifi_control;
2379
2380 return 0;
2381}
2382
2383static int msm_hifi_put(struct snd_kcontrol *kcontrol,
2384 struct snd_ctl_elem_value *ucontrol)
2385{
2386 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2387
2388 pr_debug("%s() ucontrol->value.integer.value[0] = %ld\n",
2389 __func__, ucontrol->value.integer.value[0]);
2390
2391 msm_hifi_control = ucontrol->value.integer.value[0];
2392 msm_hifi_ctrl(codec);
2393
2394 return 0;
2395}
2396
2397static const struct snd_kcontrol_new msm_snd_controls[] = {
2398 SOC_ENUM_EXT("SLIM_0_RX Channels", slim_0_rx_chs,
2399 msm_slim_rx_ch_get, msm_slim_rx_ch_put),
2400 SOC_ENUM_EXT("SLIM_2_RX Channels", slim_2_rx_chs,
2401 msm_slim_rx_ch_get, msm_slim_rx_ch_put),
2402 SOC_ENUM_EXT("SLIM_0_TX Channels", slim_0_tx_chs,
2403 msm_slim_tx_ch_get, msm_slim_tx_ch_put),
2404 SOC_ENUM_EXT("SLIM_1_TX Channels", slim_1_tx_chs,
2405 msm_slim_tx_ch_get, msm_slim_tx_ch_put),
2406 SOC_ENUM_EXT("SLIM_5_RX Channels", slim_5_rx_chs,
2407 msm_slim_rx_ch_get, msm_slim_rx_ch_put),
2408 SOC_ENUM_EXT("SLIM_6_RX Channels", slim_6_rx_chs,
2409 msm_slim_rx_ch_get, msm_slim_rx_ch_put),
2410 SOC_ENUM_EXT("VI_FEED_TX Channels", vi_feed_tx_chs,
2411 msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put),
2412 SOC_ENUM_EXT("USB_AUDIO_RX Channels", usb_rx_chs,
2413 usb_audio_rx_ch_get, usb_audio_rx_ch_put),
2414 SOC_ENUM_EXT("USB_AUDIO_TX Channels", usb_tx_chs,
2415 usb_audio_tx_ch_get, usb_audio_tx_ch_put),
2416 SOC_ENUM_EXT("HDMI_RX Channels", ext_disp_rx_chs,
2417 ext_disp_rx_ch_get, ext_disp_rx_ch_put),
2418 SOC_ENUM_EXT("Display Port RX Channels", ext_disp_rx_chs,
2419 ext_disp_rx_ch_get, ext_disp_rx_ch_put),
2420 SOC_ENUM_EXT("PROXY_RX Channels", proxy_rx_chs,
2421 proxy_rx_ch_get, proxy_rx_ch_put),
2422 SOC_ENUM_EXT("SLIM_0_RX Format", slim_0_rx_format,
2423 slim_rx_bit_format_get, slim_rx_bit_format_put),
2424 SOC_ENUM_EXT("SLIM_5_RX Format", slim_5_rx_format,
2425 slim_rx_bit_format_get, slim_rx_bit_format_put),
2426 SOC_ENUM_EXT("SLIM_6_RX Format", slim_6_rx_format,
2427 slim_rx_bit_format_get, slim_rx_bit_format_put),
2428 SOC_ENUM_EXT("SLIM_0_TX Format", slim_0_tx_format,
2429 slim_tx_bit_format_get, slim_tx_bit_format_put),
2430 SOC_ENUM_EXT("USB_AUDIO_RX Format", usb_rx_format,
2431 usb_audio_rx_format_get, usb_audio_rx_format_put),
2432 SOC_ENUM_EXT("USB_AUDIO_TX Format", usb_tx_format,
2433 usb_audio_tx_format_get, usb_audio_tx_format_put),
2434 SOC_ENUM_EXT("HDMI_RX Bit Format", ext_disp_rx_format,
2435 ext_disp_rx_format_get, ext_disp_rx_format_put),
2436 SOC_ENUM_EXT("Display Port RX Bit Format", ext_disp_rx_format,
2437 ext_disp_rx_format_get, ext_disp_rx_format_put),
2438 SOC_ENUM_EXT("SLIM_0_RX SampleRate", slim_0_rx_sample_rate,
2439 slim_rx_sample_rate_get, slim_rx_sample_rate_put),
2440 SOC_ENUM_EXT("SLIM_2_RX SampleRate", slim_2_rx_sample_rate,
2441 slim_rx_sample_rate_get, slim_rx_sample_rate_put),
2442 SOC_ENUM_EXT("SLIM_0_TX SampleRate", slim_0_tx_sample_rate,
2443 slim_tx_sample_rate_get, slim_tx_sample_rate_put),
2444 SOC_ENUM_EXT("SLIM_5_RX SampleRate", slim_5_rx_sample_rate,
2445 slim_rx_sample_rate_get, slim_rx_sample_rate_put),
2446 SOC_ENUM_EXT("SLIM_6_RX SampleRate", slim_6_rx_sample_rate,
2447 slim_rx_sample_rate_get, slim_rx_sample_rate_put),
2448 SOC_ENUM_EXT("BT SampleRate", bt_sample_rate,
2449 msm_bt_sample_rate_get,
2450 msm_bt_sample_rate_put),
2451 SOC_ENUM_EXT("USB_AUDIO_RX SampleRate", usb_rx_sample_rate,
2452 usb_audio_rx_sample_rate_get,
2453 usb_audio_rx_sample_rate_put),
2454 SOC_ENUM_EXT("USB_AUDIO_TX SampleRate", usb_tx_sample_rate,
2455 usb_audio_tx_sample_rate_get,
2456 usb_audio_tx_sample_rate_put),
2457 SOC_ENUM_EXT("HDMI_RX SampleRate", ext_disp_rx_sample_rate,
2458 ext_disp_rx_sample_rate_get,
2459 ext_disp_rx_sample_rate_put),
2460 SOC_ENUM_EXT("Display Port RX SampleRate", ext_disp_rx_sample_rate,
2461 ext_disp_rx_sample_rate_get,
2462 ext_disp_rx_sample_rate_put),
2463 SOC_ENUM_EXT("PRI_TDM_RX_0 SampleRate", tdm_rx_sample_rate,
2464 tdm_rx_sample_rate_get,
2465 tdm_rx_sample_rate_put),
2466 SOC_ENUM_EXT("PRI_TDM_TX_0 SampleRate", tdm_tx_sample_rate,
2467 tdm_tx_sample_rate_get,
2468 tdm_tx_sample_rate_put),
2469 SOC_ENUM_EXT("PRI_TDM_RX_0 Format", tdm_rx_format,
2470 tdm_rx_format_get,
2471 tdm_rx_format_put),
2472 SOC_ENUM_EXT("PRI_TDM_TX_0 Format", tdm_tx_format,
2473 tdm_tx_format_get,
2474 tdm_tx_format_put),
2475 SOC_ENUM_EXT("PRI_TDM_RX_0 Channels", tdm_rx_chs,
2476 tdm_rx_ch_get,
2477 tdm_rx_ch_put),
2478 SOC_ENUM_EXT("PRI_TDM_TX_0 Channels", tdm_tx_chs,
2479 tdm_tx_ch_get,
2480 tdm_tx_ch_put),
2481 SOC_ENUM_EXT("SEC_TDM_RX_0 SampleRate", tdm_rx_sample_rate,
2482 tdm_rx_sample_rate_get,
2483 tdm_rx_sample_rate_put),
2484 SOC_ENUM_EXT("SEC_TDM_TX_0 SampleRate", tdm_tx_sample_rate,
2485 tdm_tx_sample_rate_get,
2486 tdm_tx_sample_rate_put),
2487 SOC_ENUM_EXT("SEC_TDM_RX_0 Format", tdm_rx_format,
2488 tdm_rx_format_get,
2489 tdm_rx_format_put),
2490 SOC_ENUM_EXT("SEC_TDM_TX_0 Format", tdm_tx_format,
2491 tdm_tx_format_get,
2492 tdm_tx_format_put),
2493 SOC_ENUM_EXT("SEC_TDM_RX_0 Channels", tdm_rx_chs,
2494 tdm_rx_ch_get,
2495 tdm_rx_ch_put),
2496 SOC_ENUM_EXT("SEC_TDM_TX_0 Channels", tdm_tx_chs,
2497 tdm_tx_ch_get,
2498 tdm_tx_ch_put),
2499 SOC_ENUM_EXT("TERT_TDM_RX_0 SampleRate", tdm_rx_sample_rate,
2500 tdm_rx_sample_rate_get,
2501 tdm_rx_sample_rate_put),
2502 SOC_ENUM_EXT("TERT_TDM_TX_0 SampleRate", tdm_tx_sample_rate,
2503 tdm_tx_sample_rate_get,
2504 tdm_tx_sample_rate_put),
2505 SOC_ENUM_EXT("TERT_TDM_RX_0 Format", tdm_rx_format,
2506 tdm_rx_format_get,
2507 tdm_rx_format_put),
2508 SOC_ENUM_EXT("TERT_TDM_TX_0 Format", tdm_tx_format,
2509 tdm_tx_format_get,
2510 tdm_tx_format_put),
2511 SOC_ENUM_EXT("TERT_TDM_RX_0 Channels", tdm_rx_chs,
2512 tdm_rx_ch_get,
2513 tdm_rx_ch_put),
2514 SOC_ENUM_EXT("TERT_TDM_TX_0 Channels", tdm_tx_chs,
2515 tdm_tx_ch_get,
2516 tdm_tx_ch_put),
2517 SOC_ENUM_EXT("QUAT_TDM_RX_0 SampleRate", tdm_rx_sample_rate,
2518 tdm_rx_sample_rate_get,
2519 tdm_rx_sample_rate_put),
2520 SOC_ENUM_EXT("QUAT_TDM_TX_0 SampleRate", tdm_tx_sample_rate,
2521 tdm_tx_sample_rate_get,
2522 tdm_tx_sample_rate_put),
2523 SOC_ENUM_EXT("QUAT_TDM_RX_0 Format", tdm_rx_format,
2524 tdm_rx_format_get,
2525 tdm_rx_format_put),
2526 SOC_ENUM_EXT("QUAT_TDM_TX_0 Format", tdm_tx_format,
2527 tdm_tx_format_get,
2528 tdm_tx_format_put),
2529 SOC_ENUM_EXT("QUAT_TDM_RX_0 Channels", tdm_rx_chs,
2530 tdm_rx_ch_get,
2531 tdm_rx_ch_put),
2532 SOC_ENUM_EXT("QUAT_TDM_TX_0 Channels", tdm_tx_chs,
2533 tdm_tx_ch_get,
2534 tdm_tx_ch_put),
2535 SOC_ENUM_EXT("PRIM_AUX_PCM_RX SampleRate", prim_aux_pcm_rx_sample_rate,
2536 aux_pcm_rx_sample_rate_get,
2537 aux_pcm_rx_sample_rate_put),
2538 SOC_ENUM_EXT("SEC_AUX_PCM_RX SampleRate", sec_aux_pcm_rx_sample_rate,
2539 aux_pcm_rx_sample_rate_get,
2540 aux_pcm_rx_sample_rate_put),
2541 SOC_ENUM_EXT("TERT_AUX_PCM_RX SampleRate", tert_aux_pcm_rx_sample_rate,
2542 aux_pcm_rx_sample_rate_get,
2543 aux_pcm_rx_sample_rate_put),
2544 SOC_ENUM_EXT("QUAT_AUX_PCM_RX SampleRate", quat_aux_pcm_rx_sample_rate,
2545 aux_pcm_rx_sample_rate_get,
2546 aux_pcm_rx_sample_rate_put),
2547 SOC_ENUM_EXT("PRIM_AUX_PCM_TX SampleRate", prim_aux_pcm_tx_sample_rate,
2548 aux_pcm_tx_sample_rate_get,
2549 aux_pcm_tx_sample_rate_put),
2550 SOC_ENUM_EXT("SEC_AUX_PCM_TX SampleRate", sec_aux_pcm_tx_sample_rate,
2551 aux_pcm_tx_sample_rate_get,
2552 aux_pcm_tx_sample_rate_put),
2553 SOC_ENUM_EXT("TERT_AUX_PCM_TX SampleRate", tert_aux_pcm_tx_sample_rate,
2554 aux_pcm_tx_sample_rate_get,
2555 aux_pcm_tx_sample_rate_put),
2556 SOC_ENUM_EXT("QUAT_AUX_PCM_TX SampleRate", quat_aux_pcm_tx_sample_rate,
2557 aux_pcm_tx_sample_rate_get,
2558 aux_pcm_tx_sample_rate_put),
2559 SOC_ENUM_EXT("PRIM_MI2S_RX SampleRate", prim_mi2s_rx_sample_rate,
2560 mi2s_rx_sample_rate_get,
2561 mi2s_rx_sample_rate_put),
2562 SOC_ENUM_EXT("SEC_MI2S_RX SampleRate", sec_mi2s_rx_sample_rate,
2563 mi2s_rx_sample_rate_get,
2564 mi2s_rx_sample_rate_put),
2565 SOC_ENUM_EXT("TERT_MI2S_RX SampleRate", tert_mi2s_rx_sample_rate,
2566 mi2s_rx_sample_rate_get,
2567 mi2s_rx_sample_rate_put),
2568 SOC_ENUM_EXT("QUAT_MI2S_RX SampleRate", quat_mi2s_rx_sample_rate,
2569 mi2s_rx_sample_rate_get,
2570 mi2s_rx_sample_rate_put),
2571 SOC_ENUM_EXT("PRIM_MI2S_TX SampleRate", prim_mi2s_tx_sample_rate,
2572 mi2s_tx_sample_rate_get,
2573 mi2s_tx_sample_rate_put),
2574 SOC_ENUM_EXT("SEC_MI2S_TX SampleRate", sec_mi2s_tx_sample_rate,
2575 mi2s_tx_sample_rate_get,
2576 mi2s_tx_sample_rate_put),
2577 SOC_ENUM_EXT("TERT_MI2S_TX SampleRate", tert_mi2s_tx_sample_rate,
2578 mi2s_tx_sample_rate_get,
2579 mi2s_tx_sample_rate_put),
2580 SOC_ENUM_EXT("QUAT_MI2S_TX SampleRate", quat_mi2s_tx_sample_rate,
2581 mi2s_tx_sample_rate_get,
2582 mi2s_tx_sample_rate_put),
2583 SOC_ENUM_EXT("PRIM_MI2S_RX Channels", prim_mi2s_rx_chs,
2584 msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put),
2585 SOC_ENUM_EXT("PRIM_MI2S_TX Channels", prim_mi2s_tx_chs,
2586 msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put),
2587 SOC_ENUM_EXT("SEC_MI2S_RX Channels", sec_mi2s_rx_chs,
2588 msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put),
2589 SOC_ENUM_EXT("SEC_MI2S_TX Channels", sec_mi2s_tx_chs,
2590 msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put),
2591 SOC_ENUM_EXT("TERT_MI2S_RX Channels", tert_mi2s_rx_chs,
2592 msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put),
2593 SOC_ENUM_EXT("TERT_MI2S_TX Channels", tert_mi2s_tx_chs,
2594 msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put),
2595 SOC_ENUM_EXT("QUAT_MI2S_RX Channels", quat_mi2s_rx_chs,
2596 msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put),
2597 SOC_ENUM_EXT("QUAT_MI2S_TX Channels", quat_mi2s_tx_chs,
2598 msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put),
2599 SOC_ENUM_EXT("HiFi Function", hifi_function, msm_hifi_get,
2600 msm_hifi_put),
2601};
2602
2603static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec,
2604 int enable, bool dapm)
2605{
2606 int ret = 0;
2607
2608 if (!strcmp(dev_name(codec->dev), "tasha_codec"))
2609 ret = tasha_cdc_mclk_enable(codec, enable, dapm);
2610 else if (!strcmp(dev_name(codec->dev), "tavil_codec"))
2611 ret = tavil_cdc_mclk_enable(codec, enable);
2612 else {
2613 dev_err(codec->dev, "%s: unknown codec to enable ext clk\n",
2614 __func__);
2615 ret = -EINVAL;
2616 }
2617 return ret;
2618}
2619
2620static int msm_snd_enable_codec_ext_tx_clk(struct snd_soc_codec *codec,
2621 int enable, bool dapm)
2622{
2623 int ret = 0;
2624
2625 if (!strcmp(dev_name(codec->dev), "tasha_codec"))
2626 ret = tasha_cdc_mclk_tx_enable(codec, enable, dapm);
2627 else {
2628 dev_err(codec->dev, "%s: unknown codec to enable ext clk\n",
2629 __func__);
2630 ret = -EINVAL;
2631 }
2632 return ret;
2633}
2634
2635static int msm_mclk_tx_event(struct snd_soc_dapm_widget *w,
2636 struct snd_kcontrol *kcontrol, int event)
2637{
2638 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
2639
2640 pr_debug("%s: event = %d\n", __func__, event);
2641
2642 switch (event) {
2643 case SND_SOC_DAPM_PRE_PMU:
2644 return msm_snd_enable_codec_ext_tx_clk(codec, 1, true);
2645 case SND_SOC_DAPM_POST_PMD:
2646 return msm_snd_enable_codec_ext_tx_clk(codec, 0, true);
2647 }
2648 return 0;
2649}
2650
2651static int msm_mclk_event(struct snd_soc_dapm_widget *w,
2652 struct snd_kcontrol *kcontrol, int event)
2653{
2654 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
2655
2656 pr_debug("%s: event = %d\n", __func__, event);
2657
2658 switch (event) {
2659 case SND_SOC_DAPM_PRE_PMU:
2660 return msm_snd_enable_codec_ext_clk(codec, 1, true);
2661 case SND_SOC_DAPM_POST_PMD:
2662 return msm_snd_enable_codec_ext_clk(codec, 0, true);
2663 }
2664 return 0;
2665}
2666
2667static int msm_hifi_ctrl_event(struct snd_soc_dapm_widget *w,
2668 struct snd_kcontrol *k, int event)
2669{
2670 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
2671 struct snd_soc_card *card = codec->component.card;
2672 struct msm_asoc_mach_data *pdata =
2673 snd_soc_card_get_drvdata(card);
2674
2675 pr_debug("%s: msm_hifi_control = %d", __func__, msm_hifi_control);
2676
2677 if (!pdata || !pdata->hph_en0_gpio_p) {
2678 pr_err("%s: hph_en0_gpio is invalid\n", __func__);
2679 return -EINVAL;
2680 }
2681
2682 if (msm_hifi_control != MSM_HIFI_ON) {
2683 pr_debug("%s: HiFi mixer control is not set\n",
2684 __func__);
2685 return 0;
2686 }
2687
2688 switch (event) {
2689 case SND_SOC_DAPM_POST_PMU:
2690 msm_cdc_pinctrl_select_active_state(pdata->hph_en0_gpio_p);
2691 break;
2692 case SND_SOC_DAPM_PRE_PMD:
2693 msm_cdc_pinctrl_select_sleep_state(pdata->hph_en0_gpio_p);
2694 break;
2695 }
2696
2697 return 0;
2698}
2699
2700static const struct snd_soc_dapm_widget msm_dapm_widgets[] = {
2701
2702 SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0,
2703 msm_mclk_event,
2704 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2705
2706 SND_SOC_DAPM_SUPPLY("MCLK TX", SND_SOC_NOPM, 0, 0,
2707 msm_mclk_tx_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2708
2709 SND_SOC_DAPM_SPK("Lineout_1 amp", NULL),
2710 SND_SOC_DAPM_SPK("Lineout_3 amp", NULL),
2711 SND_SOC_DAPM_SPK("Lineout_2 amp", NULL),
2712 SND_SOC_DAPM_SPK("Lineout_4 amp", NULL),
2713 SND_SOC_DAPM_SPK("hifi amp", msm_hifi_ctrl_event),
2714 SND_SOC_DAPM_MIC("Handset Mic", NULL),
2715 SND_SOC_DAPM_MIC("Headset Mic", NULL),
2716 SND_SOC_DAPM_MIC("ANCRight Headset Mic", NULL),
2717 SND_SOC_DAPM_MIC("ANCLeft Headset Mic", NULL),
2718 SND_SOC_DAPM_MIC("Analog Mic5", NULL),
2719 SND_SOC_DAPM_MIC("Analog Mic6", NULL),
2720
2721 SND_SOC_DAPM_MIC("Digital Mic0", NULL),
2722 SND_SOC_DAPM_MIC("Digital Mic1", NULL),
2723 SND_SOC_DAPM_MIC("Digital Mic2", NULL),
2724 SND_SOC_DAPM_MIC("Digital Mic3", NULL),
2725 SND_SOC_DAPM_MIC("Digital Mic4", NULL),
2726 SND_SOC_DAPM_MIC("Digital Mic5", NULL),
2727};
2728
2729static inline int param_is_mask(int p)
2730{
2731 return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) &&
2732 (p <= SNDRV_PCM_HW_PARAM_LAST_MASK);
2733}
2734
2735static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p,
2736 int n)
2737{
2738 return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]);
2739}
2740
2741static void param_set_mask(struct snd_pcm_hw_params *p, int n, unsigned int bit)
2742{
2743 if (bit >= SNDRV_MASK_MAX)
2744 return;
2745 if (param_is_mask(n)) {
2746 struct snd_mask *m = param_to_mask(p, n);
2747
2748 m->bits[0] = 0;
2749 m->bits[1] = 0;
2750 m->bits[bit >> 5] |= (1 << (bit & 31));
2751 }
2752}
2753
2754static int msm_slim_get_ch_from_beid(int32_t be_id)
2755{
2756 int ch_id = 0;
2757
2758 switch (be_id) {
2759 case MSM_BACKEND_DAI_SLIMBUS_0_RX:
2760 ch_id = SLIM_RX_0;
2761 break;
2762 case MSM_BACKEND_DAI_SLIMBUS_1_RX:
2763 ch_id = SLIM_RX_1;
2764 break;
2765 case MSM_BACKEND_DAI_SLIMBUS_2_RX:
2766 ch_id = SLIM_RX_2;
2767 break;
2768 case MSM_BACKEND_DAI_SLIMBUS_3_RX:
2769 ch_id = SLIM_RX_3;
2770 break;
2771 case MSM_BACKEND_DAI_SLIMBUS_4_RX:
2772 ch_id = SLIM_RX_4;
2773 break;
2774 case MSM_BACKEND_DAI_SLIMBUS_6_RX:
2775 ch_id = SLIM_RX_6;
2776 break;
2777 case MSM_BACKEND_DAI_SLIMBUS_0_TX:
2778 ch_id = SLIM_TX_0;
2779 break;
2780 case MSM_BACKEND_DAI_SLIMBUS_3_TX:
2781 ch_id = SLIM_TX_3;
2782 break;
2783 default:
2784 ch_id = SLIM_RX_0;
2785 break;
2786 }
2787
2788 return ch_id;
2789}
2790
2791static int msm_ext_disp_get_idx_from_beid(int32_t be_id)
2792{
2793 int idx;
2794
2795 switch (be_id) {
2796 case MSM_BACKEND_DAI_HDMI_RX:
2797 idx = HDMI_RX_IDX;
2798 break;
2799 case MSM_BACKEND_DAI_DISPLAY_PORT_RX:
2800 idx = DP_RX_IDX;
2801 break;
2802 default:
2803 pr_err("%s: Incorrect ext_disp be_id %d\n", __func__, be_id);
2804 idx = -EINVAL;
2805 break;
2806 }
2807
2808 return idx;
2809}
2810
2811static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
2812 struct snd_pcm_hw_params *params)
2813{
2814 struct snd_soc_dai_link *dai_link = rtd->dai_link;
2815 struct snd_interval *rate = hw_param_interval(params,
2816 SNDRV_PCM_HW_PARAM_RATE);
2817 struct snd_interval *channels = hw_param_interval(params,
2818 SNDRV_PCM_HW_PARAM_CHANNELS);
2819 int rc = 0;
2820 int idx;
2821 void *config = NULL;
2822 struct snd_soc_codec *codec = NULL;
2823
2824 pr_debug("%s: format = %d, rate = %d\n",
2825 __func__, params_format(params), params_rate(params));
2826
2827 switch (dai_link->be_id) {
2828 case MSM_BACKEND_DAI_SLIMBUS_0_RX:
2829 case MSM_BACKEND_DAI_SLIMBUS_1_RX:
2830 case MSM_BACKEND_DAI_SLIMBUS_2_RX:
2831 case MSM_BACKEND_DAI_SLIMBUS_3_RX:
2832 case MSM_BACKEND_DAI_SLIMBUS_4_RX:
2833 case MSM_BACKEND_DAI_SLIMBUS_6_RX:
2834 idx = msm_slim_get_ch_from_beid(dai_link->be_id);
2835 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2836 slim_rx_cfg[idx].bit_format);
2837 rate->min = rate->max = slim_rx_cfg[idx].sample_rate;
2838 channels->min = channels->max = slim_rx_cfg[idx].channels;
2839 break;
2840
2841 case MSM_BACKEND_DAI_SLIMBUS_0_TX:
2842 case MSM_BACKEND_DAI_SLIMBUS_3_TX:
2843 idx = msm_slim_get_ch_from_beid(dai_link->be_id);
2844 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2845 slim_tx_cfg[idx].bit_format);
2846 rate->min = rate->max = slim_tx_cfg[idx].sample_rate;
2847 channels->min = channels->max = slim_tx_cfg[idx].channels;
2848 break;
2849
2850 case MSM_BACKEND_DAI_SLIMBUS_1_TX:
2851 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2852 slim_tx_cfg[1].bit_format);
2853 rate->min = rate->max = slim_tx_cfg[1].sample_rate;
2854 channels->min = channels->max = slim_tx_cfg[1].channels;
2855 break;
2856
2857 case MSM_BACKEND_DAI_SLIMBUS_4_TX:
2858 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2859 SNDRV_PCM_FORMAT_S32_LE);
2860 rate->min = rate->max = SAMPLING_RATE_8KHZ;
2861 channels->min = channels->max = msm_vi_feed_tx_ch;
2862 break;
2863
2864 case MSM_BACKEND_DAI_SLIMBUS_5_RX:
2865 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2866 slim_rx_cfg[5].bit_format);
2867 rate->min = rate->max = slim_rx_cfg[5].sample_rate;
2868 channels->min = channels->max = slim_rx_cfg[5].channels;
2869 break;
2870
2871 case MSM_BACKEND_DAI_SLIMBUS_5_TX:
2872 codec = rtd->codec;
2873 rate->min = rate->max = SAMPLING_RATE_16KHZ;
2874 channels->min = channels->max = 1;
2875
2876 config = msm_codec_fn.get_afe_config_fn(codec,
2877 AFE_SLIMBUS_SLAVE_PORT_CONFIG);
2878 if (config) {
2879 rc = afe_set_config(AFE_SLIMBUS_SLAVE_PORT_CONFIG,
2880 config, SLIMBUS_5_TX);
2881 if (rc)
2882 pr_err("%s: Failed to set slimbus slave port config %d\n",
2883 __func__, rc);
2884 }
2885 break;
2886
2887 case MSM_BACKEND_DAI_SLIMBUS_7_RX:
2888 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2889 slim_rx_cfg[SLIM_RX_7].bit_format);
2890 rate->min = rate->max = slim_rx_cfg[SLIM_RX_7].sample_rate;
2891 channels->min = channels->max =
2892 slim_rx_cfg[SLIM_RX_7].channels;
2893 break;
2894
2895 case MSM_BACKEND_DAI_SLIMBUS_7_TX:
2896 rate->min = rate->max = slim_tx_cfg[SLIM_TX_7].sample_rate;
2897 channels->min = channels->max =
2898 slim_tx_cfg[SLIM_TX_7].channels;
2899 break;
2900
2901 case MSM_BACKEND_DAI_SLIMBUS_8_TX:
2902 rate->min = rate->max = slim_tx_cfg[SLIM_TX_8].sample_rate;
2903 channels->min = channels->max =
2904 slim_tx_cfg[SLIM_TX_8].channels;
2905 break;
2906
2907 case MSM_BACKEND_DAI_USB_RX:
2908 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2909 usb_rx_cfg.bit_format);
2910 rate->min = rate->max = usb_rx_cfg.sample_rate;
2911 channels->min = channels->max = usb_rx_cfg.channels;
2912 break;
2913
2914 case MSM_BACKEND_DAI_USB_TX:
2915 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2916 usb_tx_cfg.bit_format);
2917 rate->min = rate->max = usb_tx_cfg.sample_rate;
2918 channels->min = channels->max = usb_tx_cfg.channels;
2919 break;
2920
2921 case MSM_BACKEND_DAI_HDMI_RX:
2922 case MSM_BACKEND_DAI_DISPLAY_PORT_RX:
2923 idx = msm_ext_disp_get_idx_from_beid(dai_link->be_id);
2924 if (IS_ERR_VALUE(idx)) {
2925 pr_err("%s: Incorrect ext disp idx %d\n",
2926 __func__, idx);
2927 rc = idx;
2928 goto done;
2929 }
2930
2931 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2932 ext_disp_rx_cfg[idx].bit_format);
2933 rate->min = rate->max = ext_disp_rx_cfg[idx].sample_rate;
2934 channels->min = channels->max = ext_disp_rx_cfg[idx].channels;
2935 break;
2936
2937 case MSM_BACKEND_DAI_AFE_PCM_RX:
2938 channels->min = channels->max = proxy_rx_cfg.channels;
2939 rate->min = rate->max = SAMPLING_RATE_48KHZ;
2940 break;
2941
2942 case MSM_BACKEND_DAI_PRI_TDM_RX_0:
2943 channels->min = channels->max =
2944 tdm_rx_cfg[TDM_PRI][TDM_0].channels;
2945 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2946 tdm_rx_cfg[TDM_PRI][TDM_0].bit_format);
2947 rate->min = rate->max = tdm_rx_cfg[TDM_PRI][TDM_0].sample_rate;
2948 break;
2949
2950 case MSM_BACKEND_DAI_PRI_TDM_TX_0:
2951 channels->min = channels->max =
2952 tdm_tx_cfg[TDM_PRI][TDM_0].channels;
2953 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2954 tdm_tx_cfg[TDM_PRI][TDM_0].bit_format);
2955 rate->min = rate->max = tdm_tx_cfg[TDM_PRI][TDM_0].sample_rate;
2956 break;
2957
2958 case MSM_BACKEND_DAI_SEC_TDM_RX_0:
2959 channels->min = channels->max =
2960 tdm_rx_cfg[TDM_SEC][TDM_0].channels;
2961 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2962 tdm_rx_cfg[TDM_SEC][TDM_0].bit_format);
2963 rate->min = rate->max = tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate;
2964 break;
2965
2966 case MSM_BACKEND_DAI_SEC_TDM_TX_0:
2967 channels->min = channels->max =
2968 tdm_tx_cfg[TDM_SEC][TDM_0].channels;
2969 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2970 tdm_tx_cfg[TDM_SEC][TDM_0].bit_format);
2971 rate->min = rate->max = tdm_tx_cfg[TDM_SEC][TDM_0].sample_rate;
2972 break;
2973
2974 case MSM_BACKEND_DAI_TERT_TDM_RX_0:
2975 channels->min = channels->max =
2976 tdm_rx_cfg[TDM_TERT][TDM_0].channels;
2977 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2978 tdm_rx_cfg[TDM_TERT][TDM_0].bit_format);
2979 rate->min = rate->max = tdm_rx_cfg[TDM_TERT][TDM_0].sample_rate;
2980 break;
2981
2982 case MSM_BACKEND_DAI_TERT_TDM_TX_0:
2983 channels->min = channels->max =
2984 tdm_tx_cfg[TDM_TERT][TDM_0].channels;
2985 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2986 tdm_tx_cfg[TDM_TERT][TDM_0].bit_format);
2987 rate->min = rate->max = tdm_tx_cfg[TDM_TERT][TDM_0].sample_rate;
2988 break;
2989
2990 case MSM_BACKEND_DAI_QUAT_TDM_RX_0:
2991 channels->min = channels->max =
2992 tdm_rx_cfg[TDM_QUAT][TDM_0].channels;
2993 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2994 tdm_rx_cfg[TDM_QUAT][TDM_0].bit_format);
2995 rate->min = rate->max = tdm_rx_cfg[TDM_QUAT][TDM_0].sample_rate;
2996 break;
2997
2998 case MSM_BACKEND_DAI_QUAT_TDM_TX_0:
2999 channels->min = channels->max =
3000 tdm_tx_cfg[TDM_QUAT][TDM_0].channels;
3001 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
3002 tdm_tx_cfg[TDM_QUAT][TDM_0].bit_format);
3003 rate->min = rate->max = tdm_tx_cfg[TDM_QUAT][TDM_0].sample_rate;
3004 break;
3005
3006 case MSM_BACKEND_DAI_AUXPCM_RX:
3007 rate->min = rate->max =
3008 aux_pcm_rx_cfg[PRIM_AUX_PCM].sample_rate;
3009 channels->min = channels->max =
3010 aux_pcm_rx_cfg[PRIM_AUX_PCM].channels;
3011 break;
3012
3013 case MSM_BACKEND_DAI_AUXPCM_TX:
3014 rate->min = rate->max =
3015 aux_pcm_tx_cfg[PRIM_AUX_PCM].sample_rate;
3016 channels->min = channels->max =
3017 aux_pcm_tx_cfg[PRIM_AUX_PCM].channels;
3018 break;
3019
3020 case MSM_BACKEND_DAI_SEC_AUXPCM_RX:
3021 rate->min = rate->max =
3022 aux_pcm_rx_cfg[SEC_AUX_PCM].sample_rate;
3023 channels->min = channels->max =
3024 aux_pcm_rx_cfg[SEC_AUX_PCM].channels;
3025 break;
3026
3027 case MSM_BACKEND_DAI_SEC_AUXPCM_TX:
3028 rate->min = rate->max =
3029 aux_pcm_tx_cfg[SEC_AUX_PCM].sample_rate;
3030 channels->min = channels->max =
3031 aux_pcm_tx_cfg[SEC_AUX_PCM].channels;
3032 break;
3033
3034 case MSM_BACKEND_DAI_TERT_AUXPCM_RX:
3035 rate->min = rate->max =
3036 aux_pcm_rx_cfg[TERT_AUX_PCM].sample_rate;
3037 channels->min = channels->max =
3038 aux_pcm_rx_cfg[TERT_AUX_PCM].channels;
3039 break;
3040
3041 case MSM_BACKEND_DAI_TERT_AUXPCM_TX:
3042 rate->min = rate->max =
3043 aux_pcm_tx_cfg[TERT_AUX_PCM].sample_rate;
3044 channels->min = channels->max =
3045 aux_pcm_tx_cfg[TERT_AUX_PCM].channels;
3046 break;
3047
3048 case MSM_BACKEND_DAI_QUAT_AUXPCM_RX:
3049 rate->min = rate->max =
3050 aux_pcm_rx_cfg[QUAT_AUX_PCM].sample_rate;
3051 channels->min = channels->max =
3052 aux_pcm_rx_cfg[QUAT_AUX_PCM].channels;
3053 break;
3054
3055 case MSM_BACKEND_DAI_QUAT_AUXPCM_TX:
3056 rate->min = rate->max =
3057 aux_pcm_tx_cfg[QUAT_AUX_PCM].sample_rate;
3058 channels->min = channels->max =
3059 aux_pcm_tx_cfg[QUAT_AUX_PCM].channels;
3060 break;
3061
3062 case MSM_BACKEND_DAI_PRI_MI2S_RX:
3063 rate->min = rate->max = mi2s_rx_cfg[PRIM_MI2S].sample_rate;
3064 channels->min = channels->max =
3065 mi2s_rx_cfg[PRIM_MI2S].channels;
3066 break;
3067
3068 case MSM_BACKEND_DAI_PRI_MI2S_TX:
3069 rate->min = rate->max = mi2s_tx_cfg[PRIM_MI2S].sample_rate;
3070 channels->min = channels->max =
3071 mi2s_tx_cfg[PRIM_MI2S].channels;
3072 break;
3073
3074 case MSM_BACKEND_DAI_SECONDARY_MI2S_RX:
3075 rate->min = rate->max = mi2s_rx_cfg[SEC_MI2S].sample_rate;
3076 channels->min = channels->max =
3077 mi2s_rx_cfg[SEC_MI2S].channels;
3078 break;
3079
3080 case MSM_BACKEND_DAI_SECONDARY_MI2S_TX:
3081 rate->min = rate->max = mi2s_tx_cfg[SEC_MI2S].sample_rate;
3082 channels->min = channels->max =
3083 mi2s_tx_cfg[SEC_MI2S].channels;
3084 break;
3085
3086 case MSM_BACKEND_DAI_TERTIARY_MI2S_RX:
3087 rate->min = rate->max = mi2s_rx_cfg[TERT_MI2S].sample_rate;
3088 channels->min = channels->max =
3089 mi2s_rx_cfg[TERT_MI2S].channels;
3090 break;
3091
3092 case MSM_BACKEND_DAI_TERTIARY_MI2S_TX:
3093 rate->min = rate->max = mi2s_tx_cfg[TERT_MI2S].sample_rate;
3094 channels->min = channels->max =
3095 mi2s_tx_cfg[TERT_MI2S].channels;
3096 break;
3097
3098 case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX:
3099 rate->min = rate->max = mi2s_rx_cfg[QUAT_MI2S].sample_rate;
3100 channels->min = channels->max =
3101 mi2s_rx_cfg[QUAT_MI2S].channels;
3102 break;
3103
3104 case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX:
3105 rate->min = rate->max = mi2s_tx_cfg[QUAT_MI2S].sample_rate;
3106 channels->min = channels->max =
3107 mi2s_tx_cfg[QUAT_MI2S].channels;
3108 break;
3109
3110 default:
3111 rate->min = rate->max = SAMPLING_RATE_48KHZ;
3112 break;
3113 }
3114
3115done:
3116 return rc;
3117}
3118
3119static bool msm_swap_gnd_mic(struct snd_soc_codec *codec)
3120{
3121 struct snd_soc_card *card = codec->component.card;
3122 struct msm_asoc_mach_data *pdata =
3123 snd_soc_card_get_drvdata(card);
3124 int value = 0;
3125
3126 if (pdata->us_euro_gpio_p) {
3127 value = msm_cdc_pinctrl_get_state(pdata->us_euro_gpio_p);
3128 if (value)
3129 msm_cdc_pinctrl_select_sleep_state(
3130 pdata->us_euro_gpio_p);
3131 else
3132 msm_cdc_pinctrl_select_active_state(
3133 pdata->us_euro_gpio_p);
3134 } else if (pdata->us_euro_gpio >= 0) {
3135 value = gpio_get_value_cansleep(pdata->us_euro_gpio);
3136 gpio_set_value_cansleep(pdata->us_euro_gpio, !value);
3137 }
3138 pr_debug("%s: swap select switch %d to %d\n", __func__, value, !value);
3139 return true;
3140}
3141
3142static int msm_afe_set_config(struct snd_soc_codec *codec)
3143{
3144 int ret = 0;
3145 void *config_data = NULL;
3146
3147 if (!msm_codec_fn.get_afe_config_fn) {
3148 dev_err(codec->dev, "%s: codec get afe config not init'ed\n",
3149 __func__);
3150 return -EINVAL;
3151 }
3152
3153 config_data = msm_codec_fn.get_afe_config_fn(codec,
3154 AFE_CDC_REGISTERS_CONFIG);
3155 if (config_data) {
3156 ret = afe_set_config(AFE_CDC_REGISTERS_CONFIG, config_data, 0);
3157 if (ret) {
3158 dev_err(codec->dev,
3159 "%s: Failed to set codec registers config %d\n",
3160 __func__, ret);
3161 return ret;
3162 }
3163 }
3164
3165 config_data = msm_codec_fn.get_afe_config_fn(codec,
3166 AFE_CDC_REGISTER_PAGE_CONFIG);
3167 if (config_data) {
3168 ret = afe_set_config(AFE_CDC_REGISTER_PAGE_CONFIG, config_data,
3169 0);
3170 if (ret)
3171 dev_err(codec->dev,
3172 "%s: Failed to set cdc register page config\n",
3173 __func__);
3174 }
3175
3176 config_data = msm_codec_fn.get_afe_config_fn(codec,
3177 AFE_SLIMBUS_SLAVE_CONFIG);
3178 if (config_data) {
3179 ret = afe_set_config(AFE_SLIMBUS_SLAVE_CONFIG, config_data, 0);
3180 if (ret) {
3181 dev_err(codec->dev,
3182 "%s: Failed to set slimbus slave config %d\n",
3183 __func__, ret);
3184 return ret;
3185 }
3186 }
3187
3188 return 0;
3189}
3190
3191static void msm_afe_clear_config(void)
3192{
3193 afe_clear_config(AFE_CDC_REGISTERS_CONFIG);
3194 afe_clear_config(AFE_SLIMBUS_SLAVE_CONFIG);
3195}
3196
3197static int msm_adsp_power_up_config(struct snd_soc_codec *codec)
3198{
3199 int ret = 0;
3200 unsigned long timeout;
3201 int adsp_ready = 0;
3202
3203 timeout = jiffies +
3204 msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS);
3205
3206 do {
3207 if (q6core_is_adsp_ready()) {
3208 pr_debug("%s: ADSP Audio is ready\n", __func__);
3209 adsp_ready = 1;
3210 break;
3211 }
3212 /*
3213 * ADSP will be coming up after subsystem restart and
3214 * it might not be fully up when the control reaches
3215 * here. So, wait for 50msec before checking ADSP state
3216 */
3217 msleep(50);
3218 } while (time_after(timeout, jiffies));
3219
3220 if (!adsp_ready) {
3221 pr_err("%s: timed out waiting for ADSP Audio\n", __func__);
3222 ret = -ETIMEDOUT;
3223 goto err_fail;
3224 }
3225
3226 ret = msm_afe_set_config(codec);
3227 if (ret)
3228 pr_err("%s: Failed to set AFE config. err %d\n",
3229 __func__, ret);
3230
3231 return 0;
3232
3233err_fail:
3234 return ret;
3235}
3236
3237static int msm8998_notifier_service_cb(struct notifier_block *this,
3238 unsigned long opcode, void *ptr)
3239{
3240 int ret;
3241 struct snd_soc_card *card = NULL;
3242 const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX;
3243 struct snd_soc_pcm_runtime *rtd;
3244 struct snd_soc_codec *codec;
3245
3246 pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode);
3247
3248 switch (opcode) {
3249 case AUDIO_NOTIFIER_SERVICE_DOWN:
3250 /*
3251 * Use flag to ignore initial boot notifications
3252 * On initial boot msm_adsp_power_up_config is
3253 * called on init. There is no need to clear
3254 * and set the config again on initial boot.
3255 */
3256 if (is_initial_boot)
3257 break;
3258 msm_afe_clear_config();
3259 break;
3260 case AUDIO_NOTIFIER_SERVICE_UP:
3261 if (is_initial_boot) {
3262 is_initial_boot = false;
3263 break;
3264 }
3265 if (!spdev)
3266 return -EINVAL;
3267
3268 card = platform_get_drvdata(spdev);
3269 rtd = snd_soc_get_pcm_runtime(card, be_dl_name);
3270 if (!rtd) {
3271 dev_err(card->dev,
3272 "%s: snd_soc_get_pcm_runtime for %s failed!\n",
3273 __func__, be_dl_name);
3274 ret = -EINVAL;
3275 goto done;
3276 }
3277 codec = rtd->codec;
3278
3279 ret = msm_adsp_power_up_config(codec);
3280 if (ret < 0) {
3281 dev_err(card->dev,
3282 "%s: msm_adsp_power_up_config failed ret = %d!\n",
3283 __func__, ret);
3284 goto done;
3285 }
3286 break;
3287 default:
3288 break;
3289 }
3290done:
3291 return NOTIFY_OK;
3292}
3293
3294static struct notifier_block service_nb = {
3295 .notifier_call = msm8998_notifier_service_cb,
3296 .priority = -INT_MAX,
3297};
3298
3299static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
3300{
3301 int ret = 0;
3302 void *config_data;
3303 struct snd_soc_codec *codec = rtd->codec;
3304 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
3305 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
3306 struct snd_soc_dai *codec_dai = rtd->codec_dai;
3307 struct snd_soc_pcm_runtime *rtd_aux = rtd->card->rtd_aux;
3308 struct snd_card *card;
3309 struct snd_info_entry *entry;
3310 struct msm_asoc_mach_data *pdata =
3311 snd_soc_card_get_drvdata(rtd->card);
3312
3313 /* Codec SLIMBUS configuration
3314 * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8, RX9, RX10, RX11, RX12, RX13
3315 * TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13
3316 * TX14, TX15, TX16
3317 */
3318 unsigned int rx_ch[TASHA_RX_MAX] = {144, 145, 146, 147, 148, 149, 150,
3319 151, 152, 153, 154, 155, 156};
3320 unsigned int tx_ch[TASHA_TX_MAX] = {128, 129, 130, 131, 132, 133,
3321 134, 135, 136, 137, 138, 139,
3322 140, 141, 142, 143};
3323
3324 pr_info("%s: dev_name%s\n", __func__, dev_name(cpu_dai->dev));
3325
3326 rtd->pmdown_time = 0;
3327
3328 ret = snd_soc_add_codec_controls(codec, msm_snd_controls,
3329 ARRAY_SIZE(msm_snd_controls));
3330 if (ret < 0) {
3331 pr_err("%s: add_codec_controls failed, err %d\n",
3332 __func__, ret);
3333 return ret;
3334 }
3335
3336 snd_soc_dapm_new_controls(dapm, msm_dapm_widgets,
3337 ARRAY_SIZE(msm_dapm_widgets));
3338
3339 if (!strcmp(dev_name(codec_dai->dev), "tasha_codec"))
3340 snd_soc_dapm_add_routes(dapm, wcd_audio_paths_tasha,
3341 ARRAY_SIZE(wcd_audio_paths_tasha));
3342 else
3343 snd_soc_dapm_add_routes(dapm, wcd_audio_paths,
3344 ARRAY_SIZE(wcd_audio_paths));
3345
3346 snd_soc_dapm_ignore_suspend(dapm, "Handset Mic");
3347 snd_soc_dapm_ignore_suspend(dapm, "Headset Mic");
3348 snd_soc_dapm_ignore_suspend(dapm, "ANCRight Headset Mic");
3349 snd_soc_dapm_ignore_suspend(dapm, "ANCLeft Headset Mic");
3350 snd_soc_dapm_ignore_suspend(dapm, "Digital Mic0");
3351 snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1");
3352 snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2");
3353 snd_soc_dapm_ignore_suspend(dapm, "Digital Mic3");
3354 snd_soc_dapm_ignore_suspend(dapm, "Digital Mic4");
3355 snd_soc_dapm_ignore_suspend(dapm, "Digital Mic5");
3356 snd_soc_dapm_ignore_suspend(dapm, "Analog Mic5");
3357 snd_soc_dapm_ignore_suspend(dapm, "Analog Mic6");
3358 snd_soc_dapm_ignore_suspend(dapm, "MADINPUT");
3359 snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_INPUT");
3360 snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_OUT1");
3361 snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_OUT2");
3362 snd_soc_dapm_ignore_suspend(dapm, "EAR");
3363 snd_soc_dapm_ignore_suspend(dapm, "LINEOUT1");
3364 snd_soc_dapm_ignore_suspend(dapm, "LINEOUT2");
3365 snd_soc_dapm_ignore_suspend(dapm, "ANC EAR");
3366 snd_soc_dapm_ignore_suspend(dapm, "SPK1 OUT");
3367 snd_soc_dapm_ignore_suspend(dapm, "SPK2 OUT");
3368 snd_soc_dapm_ignore_suspend(dapm, "HPHL");
3369 snd_soc_dapm_ignore_suspend(dapm, "HPHR");
3370 snd_soc_dapm_ignore_suspend(dapm, "AIF4 VI");
3371 snd_soc_dapm_ignore_suspend(dapm, "VIINPUT");
3372
3373 if (!strcmp(dev_name(codec_dai->dev), "tasha_codec")) {
3374 snd_soc_dapm_ignore_suspend(dapm, "LINEOUT3");
3375 snd_soc_dapm_ignore_suspend(dapm, "LINEOUT4");
3376 snd_soc_dapm_ignore_suspend(dapm, "ANC HPHL");
3377 snd_soc_dapm_ignore_suspend(dapm, "ANC HPHR");
3378 snd_soc_dapm_ignore_suspend(dapm, "ANC LINEOUT1");
3379 snd_soc_dapm_ignore_suspend(dapm, "ANC LINEOUT2");
3380 }
3381
3382 snd_soc_dapm_sync(dapm);
3383
3384 snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch),
3385 tx_ch, ARRAY_SIZE(rx_ch), rx_ch);
3386
3387 if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) {
3388 msm_codec_fn.get_afe_config_fn = tavil_get_afe_config;
3389 } else {
3390 msm_codec_fn.get_afe_config_fn = tasha_get_afe_config;
3391 msm_codec_fn.mbhc_hs_detect_exit = tasha_mbhc_hs_detect_exit;
3392 }
3393
3394 ret = msm_adsp_power_up_config(codec);
3395 if (ret) {
3396 pr_err("%s: Failed to set AFE config %d\n", __func__, ret);
3397 goto err_afe_cfg;
3398 }
3399
3400 config_data = msm_codec_fn.get_afe_config_fn(codec,
3401 AFE_AANC_VERSION);
3402 if (config_data) {
3403 ret = afe_set_config(AFE_AANC_VERSION, config_data, 0);
3404 if (ret) {
3405 pr_err("%s: Failed to set aanc version %d\n",
3406 __func__, ret);
3407 goto err_afe_cfg;
3408 }
3409 }
3410
3411 if (!strcmp(dev_name(codec_dai->dev), "tasha_codec")) {
3412 config_data = msm_codec_fn.get_afe_config_fn(codec,
3413 AFE_CDC_CLIP_REGISTERS_CONFIG);
3414 if (config_data) {
3415 ret = afe_set_config(AFE_CDC_CLIP_REGISTERS_CONFIG,
3416 config_data, 0);
3417 if (ret) {
3418 pr_err("%s: Failed to set clip registers %d\n",
3419 __func__, ret);
3420 goto err_afe_cfg;
3421 }
3422 }
3423 config_data = msm_codec_fn.get_afe_config_fn(codec,
3424 AFE_CLIP_BANK_SEL);
3425 if (config_data) {
3426 ret = afe_set_config(AFE_CLIP_BANK_SEL, config_data, 0);
3427 if (ret) {
3428 pr_err("%s: Failed to set AFE bank selection %d\n",
3429 __func__, ret);
3430 goto err_afe_cfg;
3431 }
3432 }
3433 }
3434
3435 /*
3436 * Send speaker configuration only for WSA8810.
3437 * Defalut configuration is for WSA8815.
3438 */
3439 pr_debug("%s: Number of aux devices: %d\n",
3440 __func__, rtd->card->num_aux_devs);
3441 if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) {
3442 if (rtd->card->num_aux_devs && rtd_aux && rtd_aux->component)
3443 if (!strcmp(rtd_aux->component->name, WSA8810_NAME_1) ||
3444 !strcmp(rtd_aux->component->name, WSA8810_NAME_2)) {
3445 tavil_set_spkr_mode(rtd->codec, SPKR_MODE_1);
3446 tavil_set_spkr_gain_offset(rtd->codec,
3447 RX_GAIN_OFFSET_M1P5_DB);
3448 }
3449 card = rtd->card->snd_card;
3450 entry = snd_info_create_subdir(card->module, "codecs",
3451 card->proc_root);
3452 if (!entry) {
3453 pr_debug("%s: Cannot create codecs module entry\n",
3454 __func__);
3455 pdata->codec_root = NULL;
3456 goto done;
3457 }
3458 pdata->codec_root = entry;
3459 tavil_codec_info_create_codec_entry(pdata->codec_root, codec);
3460 } else {
3461 if (rtd->card->num_aux_devs && rtd_aux && rtd_aux->component)
3462 if (!strcmp(rtd_aux->component->name, WSA8810_NAME_1) ||
3463 !strcmp(rtd_aux->component->name, WSA8810_NAME_2)) {
3464 tasha_set_spkr_mode(rtd->codec, SPKR_MODE_1);
3465 tasha_set_spkr_gain_offset(rtd->codec,
3466 RX_GAIN_OFFSET_M1P5_DB);
3467 }
3468 card = rtd->card->snd_card;
3469 entry = snd_info_create_subdir(card->module, "codecs",
3470 card->proc_root);
3471 if (!entry) {
3472 pr_debug("%s: Cannot create codecs module entry\n",
3473 __func__);
3474 ret = 0;
3475 goto err_snd_module;
3476 }
3477 pdata->codec_root = entry;
3478 tasha_codec_info_create_codec_entry(pdata->codec_root, codec);
3479 }
3480done:
3481 codec_reg_done = true;
3482 return 0;
3483
3484err_snd_module:
3485err_afe_cfg:
3486 return ret;
3487}
3488
3489static int msm_wcn_init(struct snd_soc_pcm_runtime *rtd)
3490{
3491 unsigned int rx_ch[WCN_CDC_SLIM_RX_CH_MAX] = {157, 158};
3492 unsigned int tx_ch[WCN_CDC_SLIM_TX_CH_MAX] = {159, 160, 161};
3493 struct snd_soc_dai *codec_dai = rtd->codec_dai;
3494
3495 return snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch),
3496 tx_ch, ARRAY_SIZE(rx_ch), rx_ch);
3497}
3498
3499static void *def_tasha_mbhc_cal(void)
3500{
3501 void *tasha_wcd_cal;
3502 struct wcd_mbhc_btn_detect_cfg *btn_cfg;
3503 u16 *btn_high;
3504
3505 tasha_wcd_cal = kzalloc(WCD_MBHC_CAL_SIZE(WCD_MBHC_DEF_BUTTONS,
3506 WCD9XXX_MBHC_DEF_RLOADS), GFP_KERNEL);
3507 if (!tasha_wcd_cal)
3508 return NULL;
3509
3510#define S(X, Y) ((WCD_MBHC_CAL_PLUG_TYPE_PTR(tasha_wcd_cal)->X) = (Y))
3511 S(v_hs_max, 1600);
3512#undef S
3513#define S(X, Y) ((WCD_MBHC_CAL_BTN_DET_PTR(tasha_wcd_cal)->X) = (Y))
3514 S(num_btn, WCD_MBHC_DEF_BUTTONS);
3515#undef S
3516
3517 btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(tasha_wcd_cal);
3518 btn_high = ((void *)&btn_cfg->_v_btn_low) +
3519 (sizeof(btn_cfg->_v_btn_low[0]) * btn_cfg->num_btn);
3520
3521 btn_high[0] = 75;
3522 btn_high[1] = 150;
3523 btn_high[2] = 237;
3524 btn_high[3] = 500;
3525 btn_high[4] = 500;
3526 btn_high[5] = 500;
3527 btn_high[6] = 500;
3528 btn_high[7] = 500;
3529
3530 return tasha_wcd_cal;
3531}
3532
3533static void *def_tavil_mbhc_cal(void)
3534{
3535 void *tavil_wcd_cal;
3536 struct wcd_mbhc_btn_detect_cfg *btn_cfg;
3537 u16 *btn_high;
3538
3539 tavil_wcd_cal = kzalloc(WCD_MBHC_CAL_SIZE(WCD_MBHC_DEF_BUTTONS,
3540 WCD9XXX_MBHC_DEF_RLOADS), GFP_KERNEL);
3541 if (!tavil_wcd_cal)
3542 return NULL;
3543
3544#define S(X, Y) ((WCD_MBHC_CAL_PLUG_TYPE_PTR(tavil_wcd_cal)->X) = (Y))
3545 S(v_hs_max, 1600);
3546#undef S
3547#define S(X, Y) ((WCD_MBHC_CAL_BTN_DET_PTR(tavil_wcd_cal)->X) = (Y))
3548 S(num_btn, WCD_MBHC_DEF_BUTTONS);
3549#undef S
3550
3551 btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(tavil_wcd_cal);
3552 btn_high = ((void *)&btn_cfg->_v_btn_low) +
3553 (sizeof(btn_cfg->_v_btn_low[0]) * btn_cfg->num_btn);
3554
3555 btn_high[0] = 75;
3556 btn_high[1] = 150;
3557 btn_high[2] = 237;
3558 btn_high[3] = 500;
3559 btn_high[4] = 500;
3560 btn_high[5] = 500;
3561 btn_high[6] = 500;
3562 btn_high[7] = 500;
3563
3564 return tavil_wcd_cal;
3565}
3566
3567static int msm_snd_hw_params(struct snd_pcm_substream *substream,
3568 struct snd_pcm_hw_params *params)
3569{
3570 struct snd_soc_pcm_runtime *rtd = substream->private_data;
3571 struct snd_soc_dai *codec_dai = rtd->codec_dai;
3572 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
3573 struct snd_soc_dai_link *dai_link = rtd->dai_link;
3574
3575 int ret = 0;
3576 u32 rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS];
3577 u32 rx_ch_cnt = 0, tx_ch_cnt = 0;
3578 u32 user_set_tx_ch = 0;
3579 u32 rx_ch_count;
3580
3581 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
3582 ret = snd_soc_dai_get_channel_map(codec_dai,
3583 &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch);
3584 if (ret < 0) {
3585 pr_err("%s: failed to get codec chan map, err:%d\n",
3586 __func__, ret);
3587 goto err_ch_map;
3588 }
3589 if (dai_link->be_id == MSM_BACKEND_DAI_SLIMBUS_5_RX) {
3590 pr_debug("%s: rx_5_ch=%d\n", __func__,
3591 slim_rx_cfg[5].channels);
3592 rx_ch_count = slim_rx_cfg[5].channels;
3593 } else if (dai_link->be_id == MSM_BACKEND_DAI_SLIMBUS_2_RX) {
3594 pr_debug("%s: rx_2_ch=%d\n", __func__,
3595 slim_rx_cfg[2].channels);
3596 rx_ch_count = slim_rx_cfg[2].channels;
3597 } else if (dai_link->be_id == MSM_BACKEND_DAI_SLIMBUS_6_RX) {
3598 pr_debug("%s: rx_6_ch=%d\n", __func__,
3599 slim_rx_cfg[6].channels);
3600 rx_ch_count = slim_rx_cfg[6].channels;
3601 } else {
3602 pr_debug("%s: rx_0_ch=%d\n", __func__,
3603 slim_rx_cfg[0].channels);
3604 rx_ch_count = slim_rx_cfg[0].channels;
3605 }
3606 ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0,
3607 rx_ch_count, rx_ch);
3608 if (ret < 0) {
3609 pr_err("%s: failed to set cpu chan map, err:%d\n",
3610 __func__, ret);
3611 goto err_ch_map;
3612 }
3613 } else {
3614
3615 pr_debug("%s: %s_tx_dai_id_%d_ch=%d\n", __func__,
3616 codec_dai->name, codec_dai->id, user_set_tx_ch);
3617 ret = snd_soc_dai_get_channel_map(codec_dai,
3618 &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch);
3619 if (ret < 0) {
3620 pr_err("%s: failed to get codec chan map\n, err:%d\n",
3621 __func__, ret);
3622 goto err_ch_map;
3623 }
3624 /* For <codec>_tx1 case */
3625 if (dai_link->be_id == MSM_BACKEND_DAI_SLIMBUS_0_TX)
3626 user_set_tx_ch = slim_tx_cfg[0].channels;
3627 /* For <codec>_tx3 case */
3628 else if (dai_link->be_id == MSM_BACKEND_DAI_SLIMBUS_1_TX)
3629 user_set_tx_ch = slim_tx_cfg[1].channels;
3630 else if (dai_link->be_id == MSM_BACKEND_DAI_SLIMBUS_4_TX)
3631 user_set_tx_ch = msm_vi_feed_tx_ch;
3632 else
3633 user_set_tx_ch = tx_ch_cnt;
3634
3635 pr_debug("%s: msm_slim_0_tx_ch(%d) user_set_tx_ch(%d) tx_ch_cnt(%d), be_id (%d)\n",
3636 __func__, slim_tx_cfg[0].channels, user_set_tx_ch,
3637 tx_ch_cnt, dai_link->be_id);
3638
3639 ret = snd_soc_dai_set_channel_map(cpu_dai,
3640 user_set_tx_ch, tx_ch, 0, 0);
3641 if (ret < 0)
3642 pr_err("%s: failed to set cpu chan map, err:%d\n",
3643 __func__, ret);
3644 }
3645
3646err_ch_map:
3647 return ret;
3648}
3649
3650static int msm_snd_cpe_hw_params(struct snd_pcm_substream *substream,
3651 struct snd_pcm_hw_params *params)
3652{
3653 struct snd_soc_pcm_runtime *rtd = substream->private_data;
3654 struct snd_soc_dai *codec_dai = rtd->codec_dai;
3655 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
3656 struct snd_soc_dai_link *dai_link = rtd->dai_link;
3657
3658 int ret = 0;
3659 u32 tx_ch[SLIM_MAX_TX_PORTS];
3660 u32 tx_ch_cnt = 0;
3661 u32 user_set_tx_ch = 0;
3662
3663 if (substream->stream != SNDRV_PCM_STREAM_CAPTURE) {
3664 pr_err("%s: Invalid stream type %d\n",
3665 __func__, substream->stream);
3666 ret = -EINVAL;
3667 goto err_stream_type;
3668 }
3669
3670 pr_debug("%s: %s_tx_dai_id_%d\n", __func__,
3671 codec_dai->name, codec_dai->id);
3672 ret = snd_soc_dai_get_channel_map(codec_dai,
3673 &tx_ch_cnt, tx_ch, NULL, NULL);
3674 if (ret < 0) {
3675 pr_err("%s: failed to get codec chan map\n, err:%d\n",
3676 __func__, ret);
3677 goto err_ch_map;
3678 }
3679
3680 user_set_tx_ch = tx_ch_cnt;
3681
3682 pr_debug("%s: tx_ch_cnt(%d) be_id %d\n",
3683 __func__, tx_ch_cnt, dai_link->be_id);
3684
3685 ret = snd_soc_dai_set_channel_map(cpu_dai,
3686 user_set_tx_ch, tx_ch, 0, 0);
3687 if (ret < 0)
3688 pr_err("%s: failed to set cpu chan map, err:%d\n",
3689 __func__, ret);
3690err_ch_map:
3691err_stream_type:
3692 return ret;
3693}
3694
3695static int msm_slimbus_2_hw_params(struct snd_pcm_substream *substream,
3696 struct snd_pcm_hw_params *params)
3697{
3698 struct snd_soc_pcm_runtime *rtd = substream->private_data;
3699 struct snd_soc_dai *codec_dai = rtd->codec_dai;
3700 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
3701 unsigned int rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS];
3702 unsigned int rx_ch_cnt = 0, tx_ch_cnt = 0;
3703 unsigned int num_tx_ch = 0;
3704 unsigned int num_rx_ch = 0;
3705 int ret = 0;
3706
3707 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
3708 num_rx_ch = params_channels(params);
3709 pr_debug("%s: %s rx_dai_id = %d num_ch = %d\n", __func__,
3710 codec_dai->name, codec_dai->id, num_rx_ch);
3711 ret = snd_soc_dai_get_channel_map(codec_dai,
3712 &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch);
3713 if (ret < 0) {
3714 pr_err("%s: failed to get codec chan map, err:%d\n",
3715 __func__, ret);
3716 goto err_ch_map;
3717 }
3718 ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0,
3719 num_rx_ch, rx_ch);
3720 if (ret < 0) {
3721 pr_err("%s: failed to set cpu chan map, err:%d\n",
3722 __func__, ret);
3723 goto err_ch_map;
3724 }
3725 } else {
3726 num_tx_ch = params_channels(params);
3727 pr_debug("%s: %s tx_dai_id = %d num_ch = %d\n", __func__,
3728 codec_dai->name, codec_dai->id, num_tx_ch);
3729 ret = snd_soc_dai_get_channel_map(codec_dai,
3730 &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch);
3731 if (ret < 0) {
3732 pr_err("%s: failed to get codec chan map, err:%d\n",
3733 __func__, ret);
3734 goto err_ch_map;
3735 }
3736 ret = snd_soc_dai_set_channel_map(cpu_dai,
3737 num_tx_ch, tx_ch, 0, 0);
3738 if (ret < 0) {
3739 pr_err("%s: failed to set cpu chan map, err:%d\n",
3740 __func__, ret);
3741 goto err_ch_map;
3742 }
3743 }
3744
3745err_ch_map:
3746 return ret;
3747}
3748
3749static int msm_wcn_hw_params(struct snd_pcm_substream *substream,
3750 struct snd_pcm_hw_params *params)
3751{
3752 struct snd_soc_pcm_runtime *rtd = substream->private_data;
3753 struct snd_soc_dai *codec_dai = rtd->codec_dai;
3754 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
3755 struct snd_soc_dai_link *dai_link = rtd->dai_link;
3756 u32 rx_ch[WCN_CDC_SLIM_RX_CH_MAX], tx_ch[WCN_CDC_SLIM_TX_CH_MAX];
3757 u32 rx_ch_cnt = 0, tx_ch_cnt = 0;
3758 int ret;
3759
3760 dev_dbg(rtd->dev, "%s: %s_tx_dai_id_%d\n", __func__,
3761 codec_dai->name, codec_dai->id);
3762 ret = snd_soc_dai_get_channel_map(codec_dai,
3763 &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch);
3764 if (ret) {
3765 dev_err(rtd->dev,
3766 "%s: failed to get BTFM codec chan map\n, err:%d\n",
3767 __func__, ret);
3768 goto exit;
3769 }
3770
3771 dev_dbg(rtd->dev, "%s: tx_ch_cnt(%d) be_id %d\n",
3772 __func__, tx_ch_cnt, dai_link->be_id);
3773
3774 ret = snd_soc_dai_set_channel_map(cpu_dai,
3775 tx_ch_cnt, tx_ch, rx_ch_cnt, rx_ch);
3776 if (ret)
3777 dev_err(rtd->dev, "%s: failed to set cpu chan map, err:%d\n",
3778 __func__, ret);
3779
3780exit:
3781 return ret;
3782}
3783
3784static int msm_aux_pcm_snd_startup(struct snd_pcm_substream *substream)
3785{
3786 int ret = 0;
3787 struct snd_soc_pcm_runtime *rtd = substream->private_data;
3788 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
3789 int index = cpu_dai->id - 1;
3790 return ret = 0;
3791
3792 dev_dbg(rtd->card->dev,
3793 "%s: substream = %s stream = %d, dai name %s, dai ID %d\n",
3794 __func__, substream->name, substream->stream,
3795 cpu_dai->name, cpu_dai->id);
3796
3797 if (index < PRIM_AUX_PCM || index > QUAT_AUX_PCM) {
3798 ret = -EINVAL;
3799 dev_err(rtd->card->dev,
3800 "%s: CPU DAI id (%d) out of range\n",
3801 __func__, cpu_dai->id);
3802 goto done;
3803 }
3804
3805 mutex_lock(&auxpcm_intf_conf[index].lock);
3806 if (++auxpcm_intf_conf[index].ref_cnt == 1) {
3807 if (mi2s_auxpcm_conf[index].pcm_i2s_sel_vt_addr != NULL) {
3808 mutex_lock(&mi2s_auxpcm_conf[index].lock);
3809 iowrite32(1,
3810 mi2s_auxpcm_conf[index].pcm_i2s_sel_vt_addr);
3811 mutex_unlock(&mi2s_auxpcm_conf[index].lock);
3812 } else {
3813 dev_err(rtd->card->dev,
3814 "%s lpaif_tert_muxsel_virt_addr is NULL\n",
3815 __func__);
3816 ret = -EINVAL;
3817 }
3818 }
3819 if (IS_ERR_VALUE(ret))
3820 auxpcm_intf_conf[index].ref_cnt--;
3821
3822 mutex_unlock(&auxpcm_intf_conf[index].lock);
3823
3824done:
3825 return ret;
3826}
3827
3828static void msm_aux_pcm_snd_shutdown(struct snd_pcm_substream *substream)
3829{
3830 struct snd_soc_pcm_runtime *rtd = substream->private_data;
3831 int index = rtd->cpu_dai->id - 1;
3832
3833 dev_dbg(rtd->card->dev,
3834 "%s: substream = %s stream = %d, dai name %s, dai ID %d\n",
3835 __func__,
3836 substream->name, substream->stream,
3837 rtd->cpu_dai->name, rtd->cpu_dai->id);
3838
3839 if (index < PRIM_AUX_PCM || index > QUAT_AUX_PCM) {
3840 dev_err(rtd->card->dev,
3841 "%s: CPU DAI id (%d) out of range\n",
3842 __func__, rtd->cpu_dai->id);
3843 return;
3844 }
3845
3846 mutex_lock(&auxpcm_intf_conf[index].lock);
3847 if (--auxpcm_intf_conf[index].ref_cnt == 0) {
3848 if (mi2s_auxpcm_conf[index].pcm_i2s_sel_vt_addr != NULL) {
3849 mutex_lock(&mi2s_auxpcm_conf[index].lock);
3850 iowrite32(0,
3851 mi2s_auxpcm_conf[index].pcm_i2s_sel_vt_addr);
3852 mutex_unlock(&mi2s_auxpcm_conf[index].lock);
3853 } else {
3854 dev_err(rtd->card->dev,
3855 "%s lpaif_tert_muxsel_virt_addr is NULL\n",
3856 __func__);
3857 auxpcm_intf_conf[index].ref_cnt++;
3858 }
3859 }
3860 mutex_unlock(&auxpcm_intf_conf[index].lock);
3861}
3862
3863static int msm_get_port_id(int be_id)
3864{
3865 int afe_port_id;
3866
3867 switch (be_id) {
3868 case MSM_BACKEND_DAI_PRI_MI2S_RX:
3869 afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_RX;
3870 break;
3871 case MSM_BACKEND_DAI_PRI_MI2S_TX:
3872 afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_TX;
3873 break;
3874 case MSM_BACKEND_DAI_SECONDARY_MI2S_RX:
3875 afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_RX;
3876 break;
3877 case MSM_BACKEND_DAI_SECONDARY_MI2S_TX:
3878 afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_TX;
3879 break;
3880 case MSM_BACKEND_DAI_TERTIARY_MI2S_RX:
3881 afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_RX;
3882 break;
3883 case MSM_BACKEND_DAI_TERTIARY_MI2S_TX:
3884 afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_TX;
3885 break;
3886 case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX:
3887 afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_RX;
3888 break;
3889 case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX:
3890 afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX;
3891 break;
3892 default:
3893 pr_err("%s: Invalid be_id: %d\n", __func__, be_id);
3894 afe_port_id = -EINVAL;
3895 }
3896
3897 return afe_port_id;
3898}
3899
3900static u32 get_mi2s_bits_per_sample(u32 bit_format)
3901{
3902 u32 bit_per_sample;
3903
3904 switch (bit_format) {
3905 case SNDRV_PCM_FORMAT_S24_3LE:
3906 case SNDRV_PCM_FORMAT_S24_LE:
3907 bit_per_sample = 32;
3908 break;
3909 case SNDRV_PCM_FORMAT_S16_LE:
3910 default:
3911 bit_per_sample = 16;
3912 break;
3913 }
3914
3915 return bit_per_sample;
3916}
3917
3918static void update_mi2s_clk_val(int dai_id, int stream)
3919{
3920 u32 bit_per_sample;
3921
3922 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
3923 bit_per_sample =
3924 get_mi2s_bits_per_sample(mi2s_rx_cfg[dai_id].bit_format);
3925 mi2s_clk[dai_id].clk_freq_in_hz =
3926 mi2s_rx_cfg[dai_id].sample_rate * 2 * bit_per_sample;
3927 } else {
3928 bit_per_sample =
3929 get_mi2s_bits_per_sample(mi2s_tx_cfg[dai_id].bit_format);
3930 mi2s_clk[dai_id].clk_freq_in_hz =
3931 mi2s_tx_cfg[dai_id].sample_rate * 2 * bit_per_sample;
3932 }
3933
3934 if (!mi2s_intf_conf[dai_id].msm_is_mi2s_master)
3935 mi2s_clk[dai_id].clk_freq_in_hz = 0;
3936}
3937
3938static int msm_mi2s_set_sclk(struct snd_pcm_substream *substream, bool enable)
3939{
3940 int ret = 0;
3941 struct snd_soc_pcm_runtime *rtd = substream->private_data;
3942 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
3943 int port_id = 0;
3944 int index = cpu_dai->id;
3945
3946 port_id = msm_get_port_id(rtd->dai_link->be_id);
3947 if (IS_ERR_VALUE(port_id)) {
3948 dev_err(rtd->card->dev, "%s: Invalid port_id\n", __func__);
3949 ret = port_id;
3950 goto done;
3951 }
3952
3953 if (enable) {
3954 update_mi2s_clk_val(index, substream->stream);
3955 dev_dbg(rtd->card->dev, "%s: clock rate %ul\n", __func__,
3956 mi2s_clk[index].clk_freq_in_hz);
3957 }
3958
3959 mi2s_clk[index].enable = enable;
3960 ret = afe_set_lpass_clock_v2(port_id,
3961 &mi2s_clk[index]);
3962 if (ret < 0) {
3963 dev_err(rtd->card->dev,
3964 "%s: afe lpass clock failed for port 0x%x , err:%d\n",
3965 __func__, port_id, ret);
3966 goto done;
3967 }
3968
3969done:
3970 return ret;
3971}
3972
3973static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
3974{
3975 int ret = 0;
3976 struct snd_soc_pcm_runtime *rtd = substream->private_data;
3977 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
3978 int index = cpu_dai->id;
3979 unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS;
3980
3981 dev_dbg(rtd->card->dev,
3982 "%s: substream = %s stream = %d, dai name %s, dai ID %d\n",
3983 __func__, substream->name, substream->stream,
3984 cpu_dai->name, cpu_dai->id);
3985
3986 if (index < PRIM_MI2S || index > QUAT_MI2S) {
3987 ret = -EINVAL;
3988 dev_err(rtd->card->dev,
3989 "%s: CPU DAI id (%d) out of range\n",
3990 __func__, cpu_dai->id);
3991 goto done;
3992 }
3993 /*
3994 * Muxtex protection in case the same MI2S
3995 * interface using for both TX and RX so
3996 * that the same clock won't be enable twice.
3997 */
3998 mutex_lock(&mi2s_intf_conf[index].lock);
3999 if (++mi2s_intf_conf[index].ref_cnt == 1) {
4000 ret = msm_mi2s_set_sclk(substream, true);
4001 if (IS_ERR_VALUE(ret)) {
4002 dev_err(rtd->card->dev,
4003 "%s: afe lpass clock failed to enable MI2S clock, err:%d\n",
4004 __func__, ret);
4005 goto clean_up;
4006 }
4007 if (mi2s_auxpcm_conf[index].pcm_i2s_sel_vt_addr != NULL) {
4008 mutex_lock(&mi2s_auxpcm_conf[index].lock);
4009 iowrite32(0,
4010 mi2s_auxpcm_conf[index].pcm_i2s_sel_vt_addr);
4011 mutex_unlock(&mi2s_auxpcm_conf[index].lock);
4012 } else {
4013 dev_err(rtd->card->dev,
4014 "%s lpaif_muxsel_virt_addr is NULL for dai %d\n",
4015 __func__, index);
4016 ret = -EINVAL;
4017 goto clk_off;
4018 }
4019 /* Check if msm needs to provide the clock to the interface */
4020 if (!mi2s_intf_conf[index].msm_is_mi2s_master)
4021 fmt = SND_SOC_DAIFMT_CBM_CFM;
4022 ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
4023 if (IS_ERR_VALUE(ret)) {
4024 pr_err("%s: set fmt cpu dai failed for MI2S (%d), err:%d\n",
4025 __func__, index, ret);
4026 goto clk_off;
4027 }
4028 }
4029clk_off:
4030 if (IS_ERR_VALUE(ret))
4031 msm_mi2s_set_sclk(substream, false);
4032clean_up:
4033 if (IS_ERR_VALUE(ret))
4034 mi2s_intf_conf[index].ref_cnt--;
4035 mutex_unlock(&mi2s_intf_conf[index].lock);
4036done:
4037 return ret;
4038}
4039
4040static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream)
4041{
4042 int ret;
4043 struct snd_soc_pcm_runtime *rtd = substream->private_data;
4044 int index = rtd->cpu_dai->id;
4045
4046 pr_debug("%s(): substream = %s stream = %d\n", __func__,
4047 substream->name, substream->stream);
4048 if (index < PRIM_MI2S || index > QUAT_MI2S) {
4049 pr_err("%s:invalid MI2S DAI(%d)\n", __func__, index);
4050 return;
4051 }
4052
4053 mutex_lock(&mi2s_intf_conf[index].lock);
4054 if (--mi2s_intf_conf[index].ref_cnt == 0) {
4055 ret = msm_mi2s_set_sclk(substream, false);
4056 if (ret < 0) {
4057 pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n",
4058 __func__, index, ret);
4059 mi2s_intf_conf[index].ref_cnt++;
4060 }
4061 }
4062 mutex_unlock(&mi2s_intf_conf[index].lock);
4063}
4064
4065static struct snd_soc_ops msm_mi2s_be_ops = {
4066 .startup = msm_mi2s_snd_startup,
4067 .shutdown = msm_mi2s_snd_shutdown,
4068};
4069
4070static struct snd_soc_ops msm_aux_pcm_be_ops = {
4071 .startup = msm_aux_pcm_snd_startup,
4072 .shutdown = msm_aux_pcm_snd_shutdown,
4073};
4074
4075static unsigned int tdm_param_set_slot_mask(u16 port_id, int slot_width,
4076 int slots)
4077{
4078 unsigned int slot_mask = 0;
4079 int i, j;
4080 unsigned int *slot_offset;
4081
4082 for (i = TDM_0; i < TDM_PORT_MAX; i++) {
4083 slot_offset = tdm_slot_offset[i];
4084
4085 for (j = 0; j < TDM_SLOT_OFFSET_MAX; j++) {
4086 if (slot_offset[j] != AFE_SLOT_MAPPING_OFFSET_INVALID)
4087 slot_mask |=
4088 (1 << ((slot_offset[j] * 8) / slot_width));
4089 else
4090 break;
4091 }
4092 }
4093
4094 return slot_mask;
4095}
4096
4097static int msm_tdm_snd_hw_params(struct snd_pcm_substream *substream,
4098 struct snd_pcm_hw_params *params)
4099{
4100 struct snd_soc_pcm_runtime *rtd = substream->private_data;
4101 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
4102 int ret = 0;
4103 int channels, slot_width, slots;
4104 unsigned int slot_mask;
4105 unsigned int *slot_offset;
4106 int offset_channels = 0;
4107 int i;
4108
4109 pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id);
4110
4111 channels = params_channels(params);
4112 switch (channels) {
4113 case 1:
4114 case 2:
4115 case 3:
4116 case 4:
4117 case 5:
4118 case 6:
4119 case 7:
4120 case 8:
4121 switch (params_format(params)) {
4122 case SNDRV_PCM_FORMAT_S32_LE:
4123 case SNDRV_PCM_FORMAT_S24_LE:
4124 case SNDRV_PCM_FORMAT_S16_LE:
4125 /*
4126 * up to 8 channels HW config should
4127 * use 32 bit slot width for max support of
4128 * stream bit width. (slot_width > bit_width)
4129 */
4130 slot_width = 32;
4131 break;
4132 default:
4133 pr_err("%s: invalid param format 0x%x\n",
4134 __func__, params_format(params));
4135 return -EINVAL;
4136 }
4137 slots = 8;
4138 slot_mask = tdm_param_set_slot_mask(cpu_dai->id,
4139 slot_width,
4140 slots);
4141 if (!slot_mask) {
4142 pr_err("%s: invalid slot_mask 0x%x\n",
4143 __func__, slot_mask);
4144 return -EINVAL;
4145 }
4146 break;
4147 default:
4148 pr_err("%s: invalid param channels %d\n",
4149 __func__, channels);
4150 return -EINVAL;
4151 }
4152 /* currently only supporting TDM_RX_0 and TDM_TX_0 */
4153 switch (cpu_dai->id) {
4154 case AFE_PORT_ID_PRIMARY_TDM_RX:
4155 case AFE_PORT_ID_SECONDARY_TDM_RX:
4156 case AFE_PORT_ID_TERTIARY_TDM_RX:
4157 case AFE_PORT_ID_QUATERNARY_TDM_RX:
4158 case AFE_PORT_ID_PRIMARY_TDM_TX:
4159 case AFE_PORT_ID_SECONDARY_TDM_TX:
4160 case AFE_PORT_ID_TERTIARY_TDM_TX:
4161 case AFE_PORT_ID_QUATERNARY_TDM_TX:
4162 slot_offset = tdm_slot_offset[TDM_0];
4163 break;
4164 default:
4165 pr_err("%s: dai id 0x%x not supported\n",
4166 __func__, cpu_dai->id);
4167 return -EINVAL;
4168 }
4169
4170 for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) {
4171 if (slot_offset[i] != AFE_SLOT_MAPPING_OFFSET_INVALID)
4172 offset_channels++;
4173 else
4174 break;
4175 }
4176
4177 if (offset_channels == 0) {
4178 pr_err("%s: slot offset not supported, offset_channels %d\n",
4179 __func__, offset_channels);
4180 return -EINVAL;
4181 }
4182
4183 if (channels > offset_channels) {
4184 pr_err("%s: channels %d exceed offset_channels %d\n",
4185 __func__, channels, offset_channels);
4186 return -EINVAL;
4187 }
4188
4189 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
4190 ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask,
4191 slots, slot_width);
4192 if (ret < 0) {
4193 pr_err("%s: failed to set tdm slot, err:%d\n",
4194 __func__, ret);
4195 goto end;
4196 }
4197
4198 ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL,
4199 channels, slot_offset);
4200 if (ret < 0) {
4201 pr_err("%s: failed to set channel map, err:%d\n",
4202 __func__, ret);
4203 goto end;
4204 }
4205 } else {
4206 ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0,
4207 slots, slot_width);
4208 if (ret < 0) {
4209 pr_err("%s: failed to set tdm slot, err:%d\n",
4210 __func__, ret);
4211 goto end;
4212 }
4213
4214 ret = snd_soc_dai_set_channel_map(cpu_dai, channels,
4215 slot_offset, 0, NULL);
4216 if (ret < 0) {
4217 pr_err("%s: failed to set channel map, err:%d\n",
4218 __func__, ret);
4219 goto end;
4220 }
4221 }
4222end:
4223 return ret;
4224}
4225
4226static struct snd_soc_ops msm_be_ops = {
4227 .hw_params = msm_snd_hw_params,
4228};
4229
4230static struct snd_soc_ops msm_cpe_ops = {
4231 .hw_params = msm_snd_cpe_hw_params,
4232};
4233
4234static struct snd_soc_ops msm_slimbus_2_be_ops = {
4235 .hw_params = msm_slimbus_2_hw_params,
4236};
4237
4238static struct snd_soc_ops msm_wcn_ops = {
4239 .hw_params = msm_wcn_hw_params,
4240};
4241
4242static struct snd_soc_ops msm_tdm_be_ops = {
4243 .hw_params = msm_tdm_snd_hw_params
4244};
4245
4246/* Digital audio interface glue - connects codec <---> CPU */
4247static struct snd_soc_dai_link msm_common_dai_links[] = {
4248 /* FrontEnd DAI Links */
4249 {
4250 .name = MSM_DAILINK_NAME(Media1),
4251 .stream_name = "MultiMedia1",
4252 .cpu_dai_name = "MultiMedia1",
4253 .platform_name = "msm-pcm-dsp.0",
4254 .dynamic = 1,
4255 .async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
4256 .dpcm_playback = 1,
4257 .dpcm_capture = 1,
4258 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
4259 SND_SOC_DPCM_TRIGGER_POST},
4260 .codec_dai_name = "snd-soc-dummy-dai",
4261 .codec_name = "snd-soc-dummy",
4262 .ignore_suspend = 1,
4263 /* this dainlink has playback support */
4264 .ignore_pmdown_time = 1,
4265 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA1
4266 },
4267 {
4268 .name = MSM_DAILINK_NAME(Media2),
4269 .stream_name = "MultiMedia2",
4270 .cpu_dai_name = "MultiMedia2",
4271 .platform_name = "msm-pcm-dsp.0",
4272 .dynamic = 1,
4273 .dpcm_playback = 1,
4274 .dpcm_capture = 1,
4275 .codec_dai_name = "snd-soc-dummy-dai",
4276 .codec_name = "snd-soc-dummy",
4277 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
4278 SND_SOC_DPCM_TRIGGER_POST},
4279 .ignore_suspend = 1,
4280 /* this dainlink has playback support */
4281 .ignore_pmdown_time = 1,
4282 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA2,
4283 },
4284 {
4285 .name = "VoiceMMode1",
4286 .stream_name = "VoiceMMode1",
4287 .cpu_dai_name = "VoiceMMode1",
4288 .platform_name = "msm-pcm-voice",
4289 .dynamic = 1,
4290 .dpcm_playback = 1,
4291 .dpcm_capture = 1,
4292 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
4293 SND_SOC_DPCM_TRIGGER_POST},
4294 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
4295 .ignore_suspend = 1,
4296 .ignore_pmdown_time = 1,
4297 .codec_dai_name = "snd-soc-dummy-dai",
4298 .codec_name = "snd-soc-dummy",
4299 .be_id = MSM_FRONTEND_DAI_VOICEMMODE1,
4300 },
4301 {
4302 .name = "MSM VoIP",
4303 .stream_name = "VoIP",
4304 .cpu_dai_name = "VoIP",
4305 .platform_name = "msm-voip-dsp",
4306 .dynamic = 1,
4307 .dpcm_playback = 1,
4308 .dpcm_capture = 1,
4309 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
4310 SND_SOC_DPCM_TRIGGER_POST},
4311 .codec_dai_name = "snd-soc-dummy-dai",
4312 .codec_name = "snd-soc-dummy",
4313 .ignore_suspend = 1,
4314 /* this dainlink has playback support */
4315 .ignore_pmdown_time = 1,
4316 .be_id = MSM_FRONTEND_DAI_VOIP,
4317 },
4318 {
4319 .name = MSM_DAILINK_NAME(ULL),
4320 .stream_name = "MultiMedia3",
4321 .cpu_dai_name = "MultiMedia3",
4322 .platform_name = "msm-pcm-dsp.2",
4323 .dynamic = 1,
4324 .async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
4325 .dpcm_playback = 1,
4326 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
4327 SND_SOC_DPCM_TRIGGER_POST},
4328 .codec_dai_name = "snd-soc-dummy-dai",
4329 .codec_name = "snd-soc-dummy",
4330 .ignore_suspend = 1,
4331 /* this dainlink has playback support */
4332 .ignore_pmdown_time = 1,
4333 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA3,
4334 },
4335 /* Hostless PCM purpose */
4336 {
4337 .name = "SLIMBUS_0 Hostless",
4338 .stream_name = "SLIMBUS_0 Hostless",
4339 .cpu_dai_name = "SLIMBUS0_HOSTLESS",
4340 .platform_name = "msm-pcm-hostless",
4341 .dynamic = 1,
4342 .dpcm_playback = 1,
4343 .dpcm_capture = 1,
4344 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
4345 SND_SOC_DPCM_TRIGGER_POST},
4346 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
4347 .ignore_suspend = 1,
4348 /* this dailink has playback support */
4349 .ignore_pmdown_time = 1,
4350 .codec_dai_name = "snd-soc-dummy-dai",
4351 .codec_name = "snd-soc-dummy",
4352 },
4353 {
4354 .name = "MSM AFE-PCM RX",
4355 .stream_name = "AFE-PROXY RX",
4356 .cpu_dai_name = "msm-dai-q6-dev.241",
4357 .codec_name = "msm-stub-codec.1",
4358 .codec_dai_name = "msm-stub-rx",
4359 .platform_name = "msm-pcm-afe",
4360 .dpcm_playback = 1,
4361 .ignore_suspend = 1,
4362 /* this dainlink has playback support */
4363 .ignore_pmdown_time = 1,
4364 },
4365 {
4366 .name = "MSM AFE-PCM TX",
4367 .stream_name = "AFE-PROXY TX",
4368 .cpu_dai_name = "msm-dai-q6-dev.240",
4369 .codec_name = "msm-stub-codec.1",
4370 .codec_dai_name = "msm-stub-tx",
4371 .platform_name = "msm-pcm-afe",
4372 .dpcm_capture = 1,
4373 .ignore_suspend = 1,
4374 },
4375 {
4376 .name = MSM_DAILINK_NAME(Compress1),
4377 .stream_name = "Compress1",
4378 .cpu_dai_name = "MultiMedia4",
4379 .platform_name = "msm-compress-dsp",
4380 .dynamic = 1,
4381 .async_ops = ASYNC_DPCM_SND_SOC_HW_PARAMS,
4382 .dpcm_playback = 1,
4383 .dpcm_capture = 1,
4384 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
4385 SND_SOC_DPCM_TRIGGER_POST},
4386 .codec_dai_name = "snd-soc-dummy-dai",
4387 .codec_name = "snd-soc-dummy",
4388 .ignore_suspend = 1,
4389 .ignore_pmdown_time = 1,
4390 /* this dainlink has playback support */
4391 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA4,
4392 },
4393 {
4394 .name = "AUXPCM Hostless",
4395 .stream_name = "AUXPCM Hostless",
4396 .cpu_dai_name = "AUXPCM_HOSTLESS",
4397 .platform_name = "msm-pcm-hostless",
4398 .dynamic = 1,
4399 .dpcm_playback = 1,
4400 .dpcm_capture = 1,
4401 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
4402 SND_SOC_DPCM_TRIGGER_POST},
4403 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
4404 .ignore_suspend = 1,
4405 /* this dainlink has playback support */
4406 .ignore_pmdown_time = 1,
4407 .codec_dai_name = "snd-soc-dummy-dai",
4408 .codec_name = "snd-soc-dummy",
4409 },
4410 {
4411 .name = "SLIMBUS_1 Hostless",
4412 .stream_name = "SLIMBUS_1 Hostless",
4413 .cpu_dai_name = "SLIMBUS1_HOSTLESS",
4414 .platform_name = "msm-pcm-hostless",
4415 .dynamic = 1,
4416 .dpcm_playback = 1,
4417 .dpcm_capture = 1,
4418 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
4419 SND_SOC_DPCM_TRIGGER_POST},
4420 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
4421 .ignore_suspend = 1,
4422 /* this dailink has playback support */
4423 .ignore_pmdown_time = 1,
4424 .codec_dai_name = "snd-soc-dummy-dai",
4425 .codec_name = "snd-soc-dummy",
4426 },
4427 {
4428 .name = "SLIMBUS_3 Hostless",
4429 .stream_name = "SLIMBUS_3 Hostless",
4430 .cpu_dai_name = "SLIMBUS3_HOSTLESS",
4431 .platform_name = "msm-pcm-hostless",
4432 .dynamic = 1,
4433 .dpcm_playback = 1,
4434 .dpcm_capture = 1,
4435 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
4436 SND_SOC_DPCM_TRIGGER_POST},
4437 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
4438 .ignore_suspend = 1,
4439 /* this dailink has playback support */
4440 .ignore_pmdown_time = 1,
4441 .codec_dai_name = "snd-soc-dummy-dai",
4442 .codec_name = "snd-soc-dummy",
4443 },
4444 {
4445 .name = "SLIMBUS_4 Hostless",
4446 .stream_name = "SLIMBUS_4 Hostless",
4447 .cpu_dai_name = "SLIMBUS4_HOSTLESS",
4448 .platform_name = "msm-pcm-hostless",
4449 .dynamic = 1,
4450 .dpcm_playback = 1,
4451 .dpcm_capture = 1,
4452 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
4453 SND_SOC_DPCM_TRIGGER_POST},
4454 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
4455 .ignore_suspend = 1,
4456 /* this dailink has playback support */
4457 .ignore_pmdown_time = 1,
4458 .codec_dai_name = "snd-soc-dummy-dai",
4459 .codec_name = "snd-soc-dummy",
4460 },
4461 {
4462 .name = MSM_DAILINK_NAME(LowLatency),
4463 .stream_name = "MultiMedia5",
4464 .cpu_dai_name = "MultiMedia5",
4465 .platform_name = "msm-pcm-dsp.1",
4466 .dynamic = 1,
4467 .async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
4468 .dpcm_playback = 1,
4469 .dpcm_capture = 1,
4470 .codec_dai_name = "snd-soc-dummy-dai",
4471 .codec_name = "snd-soc-dummy",
4472 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
4473 SND_SOC_DPCM_TRIGGER_POST},
4474 .ignore_suspend = 1,
4475 /* this dainlink has playback support */
4476 .ignore_pmdown_time = 1,
4477 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA5,
4478 },
4479 {
4480 .name = "Listen 1 Audio Service",
4481 .stream_name = "Listen 1 Audio Service",
4482 .cpu_dai_name = "LSM1",
4483 .platform_name = "msm-lsm-client",
4484 .dynamic = 1,
4485 .dpcm_capture = 1,
4486 .trigger = { SND_SOC_DPCM_TRIGGER_POST,
4487 SND_SOC_DPCM_TRIGGER_POST },
4488 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
4489 .ignore_suspend = 1,
4490 .ignore_pmdown_time = 1,
4491 .codec_dai_name = "snd-soc-dummy-dai",
4492 .codec_name = "snd-soc-dummy",
4493 .be_id = MSM_FRONTEND_DAI_LSM1,
4494 },
4495 /* Multiple Tunnel instances */
4496 {
4497 .name = MSM_DAILINK_NAME(Compress2),
4498 .stream_name = "Compress2",
4499 .cpu_dai_name = "MultiMedia7",
4500 .platform_name = "msm-compress-dsp",
4501 .dynamic = 1,
4502 .dpcm_playback = 1,
4503 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
4504 SND_SOC_DPCM_TRIGGER_POST},
4505 .codec_dai_name = "snd-soc-dummy-dai",
4506 .codec_name = "snd-soc-dummy",
4507 .ignore_suspend = 1,
4508 .ignore_pmdown_time = 1,
4509 /* this dainlink has playback support */
4510 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA7,
4511 },
4512 {
4513 .name = MSM_DAILINK_NAME(Compress3),
4514 .stream_name = "Compress3",
4515 .cpu_dai_name = "MultiMedia10",
4516 .platform_name = "msm-compress-dsp",
4517 .dynamic = 1,
4518 .dpcm_playback = 1,
4519 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
4520 SND_SOC_DPCM_TRIGGER_POST},
4521 .codec_dai_name = "snd-soc-dummy-dai",
4522 .codec_name = "snd-soc-dummy",
4523 .ignore_suspend = 1,
4524 .ignore_pmdown_time = 1,
4525 /* this dainlink has playback support */
4526 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA10,
4527 },
4528 {
4529 .name = MSM_DAILINK_NAME(ULL_NOIRQ),
4530 .stream_name = "MM_NOIRQ",
4531 .cpu_dai_name = "MultiMedia8",
4532 .platform_name = "msm-pcm-dsp-noirq",
4533 .dynamic = 1,
4534 .dpcm_playback = 1,
4535 .dpcm_capture = 1,
4536 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
4537 SND_SOC_DPCM_TRIGGER_POST},
4538 .codec_dai_name = "snd-soc-dummy-dai",
4539 .codec_name = "snd-soc-dummy",
4540 .ignore_suspend = 1,
4541 .ignore_pmdown_time = 1,
4542 /* this dainlink has playback support */
4543 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA8,
4544 },
4545 /* HDMI Hostless */
4546 {
4547 .name = "HDMI_RX_HOSTLESS",
4548 .stream_name = "HDMI_RX_HOSTLESS",
4549 .cpu_dai_name = "HDMI_HOSTLESS",
4550 .platform_name = "msm-pcm-hostless",
4551 .dynamic = 1,
4552 .dpcm_playback = 1,
4553 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
4554 SND_SOC_DPCM_TRIGGER_POST},
4555 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
4556 .ignore_suspend = 1,
4557 .ignore_pmdown_time = 1,
4558 .codec_dai_name = "snd-soc-dummy-dai",
4559 .codec_name = "snd-soc-dummy",
4560 },
4561 {
4562 .name = "VoiceMMode2",
4563 .stream_name = "VoiceMMode2",
4564 .cpu_dai_name = "VoiceMMode2",
4565 .platform_name = "msm-pcm-voice",
4566 .dynamic = 1,
4567 .dpcm_playback = 1,
4568 .dpcm_capture = 1,
4569 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
4570 SND_SOC_DPCM_TRIGGER_POST},
4571 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
4572 .ignore_suspend = 1,
4573 .ignore_pmdown_time = 1,
4574 .codec_dai_name = "snd-soc-dummy-dai",
4575 .codec_name = "snd-soc-dummy",
4576 .be_id = MSM_FRONTEND_DAI_VOICEMMODE2,
4577 },
4578 /* LSM FE */
4579 {
4580 .name = "Listen 2 Audio Service",
4581 .stream_name = "Listen 2 Audio Service",
4582 .cpu_dai_name = "LSM2",
4583 .platform_name = "msm-lsm-client",
4584 .dynamic = 1,
4585 .dpcm_capture = 1,
4586 .trigger = { SND_SOC_DPCM_TRIGGER_POST,
4587 SND_SOC_DPCM_TRIGGER_POST },
4588 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
4589 .ignore_suspend = 1,
4590 .ignore_pmdown_time = 1,
4591 .codec_dai_name = "snd-soc-dummy-dai",
4592 .codec_name = "snd-soc-dummy",
4593 .be_id = MSM_FRONTEND_DAI_LSM2,
4594 },
4595 {
4596 .name = "Listen 3 Audio Service",
4597 .stream_name = "Listen 3 Audio Service",
4598 .cpu_dai_name = "LSM3",
4599 .platform_name = "msm-lsm-client",
4600 .dynamic = 1,
4601 .dpcm_capture = 1,
4602 .trigger = { SND_SOC_DPCM_TRIGGER_POST,
4603 SND_SOC_DPCM_TRIGGER_POST },
4604 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
4605 .ignore_suspend = 1,
4606 .ignore_pmdown_time = 1,
4607 .codec_dai_name = "snd-soc-dummy-dai",
4608 .codec_name = "snd-soc-dummy",
4609 .be_id = MSM_FRONTEND_DAI_LSM3,
4610 },
4611 {
4612 .name = "Listen 4 Audio Service",
4613 .stream_name = "Listen 4 Audio Service",
4614 .cpu_dai_name = "LSM4",
4615 .platform_name = "msm-lsm-client",
4616 .dynamic = 1,
4617 .dpcm_capture = 1,
4618 .trigger = { SND_SOC_DPCM_TRIGGER_POST,
4619 SND_SOC_DPCM_TRIGGER_POST },
4620 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
4621 .ignore_suspend = 1,
4622 .ignore_pmdown_time = 1,
4623 .codec_dai_name = "snd-soc-dummy-dai",
4624 .codec_name = "snd-soc-dummy",
4625 .be_id = MSM_FRONTEND_DAI_LSM4,
4626 },
4627 {
4628 .name = "Listen 5 Audio Service",
4629 .stream_name = "Listen 5 Audio Service",
4630 .cpu_dai_name = "LSM5",
4631 .platform_name = "msm-lsm-client",
4632 .dynamic = 1,
4633 .dpcm_capture = 1,
4634 .trigger = { SND_SOC_DPCM_TRIGGER_POST,
4635 SND_SOC_DPCM_TRIGGER_POST },
4636 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
4637 .ignore_suspend = 1,
4638 .ignore_pmdown_time = 1,
4639 .codec_dai_name = "snd-soc-dummy-dai",
4640 .codec_name = "snd-soc-dummy",
4641 .be_id = MSM_FRONTEND_DAI_LSM5,
4642 },
4643 {
4644 .name = "Listen 6 Audio Service",
4645 .stream_name = "Listen 6 Audio Service",
4646 .cpu_dai_name = "LSM6",
4647 .platform_name = "msm-lsm-client",
4648 .dynamic = 1,
4649 .dpcm_capture = 1,
4650 .trigger = { SND_SOC_DPCM_TRIGGER_POST,
4651 SND_SOC_DPCM_TRIGGER_POST },
4652 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
4653 .ignore_suspend = 1,
4654 .ignore_pmdown_time = 1,
4655 .codec_dai_name = "snd-soc-dummy-dai",
4656 .codec_name = "snd-soc-dummy",
4657 .be_id = MSM_FRONTEND_DAI_LSM6,
4658 },
4659 {
4660 .name = "Listen 7 Audio Service",
4661 .stream_name = "Listen 7 Audio Service",
4662 .cpu_dai_name = "LSM7",
4663 .platform_name = "msm-lsm-client",
4664 .dynamic = 1,
4665 .dpcm_capture = 1,
4666 .trigger = { SND_SOC_DPCM_TRIGGER_POST,
4667 SND_SOC_DPCM_TRIGGER_POST },
4668 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
4669 .ignore_suspend = 1,
4670 .ignore_pmdown_time = 1,
4671 .codec_dai_name = "snd-soc-dummy-dai",
4672 .codec_name = "snd-soc-dummy",
4673 .be_id = MSM_FRONTEND_DAI_LSM7,
4674 },
4675 {
4676 .name = "Listen 8 Audio Service",
4677 .stream_name = "Listen 8 Audio Service",
4678 .cpu_dai_name = "LSM8",
4679 .platform_name = "msm-lsm-client",
4680 .dynamic = 1,
4681 .dpcm_capture = 1,
4682 .trigger = { SND_SOC_DPCM_TRIGGER_POST,
4683 SND_SOC_DPCM_TRIGGER_POST },
4684 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
4685 .ignore_suspend = 1,
4686 .ignore_pmdown_time = 1,
4687 .codec_dai_name = "snd-soc-dummy-dai",
4688 .codec_name = "snd-soc-dummy",
4689 .be_id = MSM_FRONTEND_DAI_LSM8,
4690 },
4691 {
4692 .name = MSM_DAILINK_NAME(Media9),
4693 .stream_name = "MultiMedia9",
4694 .cpu_dai_name = "MultiMedia9",
4695 .platform_name = "msm-pcm-dsp.0",
4696 .dynamic = 1,
4697 .dpcm_playback = 1,
4698 .dpcm_capture = 1,
4699 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
4700 SND_SOC_DPCM_TRIGGER_POST},
4701 .codec_dai_name = "snd-soc-dummy-dai",
4702 .codec_name = "snd-soc-dummy",
4703 .ignore_suspend = 1,
4704 /* this dainlink has playback support */
4705 .ignore_pmdown_time = 1,
4706 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA9,
4707 },
4708 {
4709 .name = MSM_DAILINK_NAME(Compress4),
4710 .stream_name = "Compress4",
4711 .cpu_dai_name = "MultiMedia11",
4712 .platform_name = "msm-compress-dsp",
4713 .dynamic = 1,
4714 .dpcm_playback = 1,
4715 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
4716 SND_SOC_DPCM_TRIGGER_POST},
4717 .codec_dai_name = "snd-soc-dummy-dai",
4718 .codec_name = "snd-soc-dummy",
4719 .ignore_suspend = 1,
4720 .ignore_pmdown_time = 1,
4721 /* this dainlink has playback support */
4722 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA11,
4723 },
4724 {
4725 .name = MSM_DAILINK_NAME(Compress5),
4726 .stream_name = "Compress5",
4727 .cpu_dai_name = "MultiMedia12",
4728 .platform_name = "msm-compress-dsp",
4729 .dynamic = 1,
4730 .dpcm_playback = 1,
4731 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
4732 SND_SOC_DPCM_TRIGGER_POST},
4733 .codec_dai_name = "snd-soc-dummy-dai",
4734 .codec_name = "snd-soc-dummy",
4735 .ignore_suspend = 1,
4736 .ignore_pmdown_time = 1,
4737 /* this dainlink has playback support */
4738 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA12,
4739 },
4740 {
4741 .name = MSM_DAILINK_NAME(Compress6),
4742 .stream_name = "Compress6",
4743 .cpu_dai_name = "MultiMedia13",
4744 .platform_name = "msm-compress-dsp",
4745 .dynamic = 1,
4746 .dpcm_playback = 1,
4747 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
4748 SND_SOC_DPCM_TRIGGER_POST},
4749 .codec_dai_name = "snd-soc-dummy-dai",
4750 .codec_name = "snd-soc-dummy",
4751 .ignore_suspend = 1,
4752 .ignore_pmdown_time = 1,
4753 /* this dainlink has playback support */
4754 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA13,
4755 },
4756 {
4757 .name = MSM_DAILINK_NAME(Compress7),
4758 .stream_name = "Compress7",
4759 .cpu_dai_name = "MultiMedia14",
4760 .platform_name = "msm-compress-dsp",
4761 .dynamic = 1,
4762 .dpcm_playback = 1,
4763 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
4764 SND_SOC_DPCM_TRIGGER_POST},
4765 .codec_dai_name = "snd-soc-dummy-dai",
4766 .codec_name = "snd-soc-dummy",
4767 .ignore_suspend = 1,
4768 .ignore_pmdown_time = 1,
4769 /* this dainlink has playback support */
4770 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA14,
4771 },
4772 {
4773 .name = MSM_DAILINK_NAME(Compress8),
4774 .stream_name = "Compress8",
4775 .cpu_dai_name = "MultiMedia15",
4776 .platform_name = "msm-compress-dsp",
4777 .dynamic = 1,
4778 .dpcm_playback = 1,
4779 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
4780 SND_SOC_DPCM_TRIGGER_POST},
4781 .codec_dai_name = "snd-soc-dummy-dai",
4782 .codec_name = "snd-soc-dummy",
4783 .ignore_suspend = 1,
4784 .ignore_pmdown_time = 1,
4785 /* this dainlink has playback support */
4786 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA15,
4787 },
4788 {
4789 .name = MSM_DAILINK_NAME(Compress9),
4790 .stream_name = "Compress9",
4791 .cpu_dai_name = "MultiMedia16",
4792 .platform_name = "msm-compress-dsp",
4793 .dynamic = 1,
4794 .dpcm_playback = 1,
4795 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
4796 SND_SOC_DPCM_TRIGGER_POST},
4797 .codec_dai_name = "snd-soc-dummy-dai",
4798 .codec_name = "snd-soc-dummy",
4799 .ignore_suspend = 1,
4800 .ignore_pmdown_time = 1,
4801 /* this dainlink has playback support */
4802 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA16,
4803 },
4804 {
4805 .name = "SLIMBUS_8 Hostless",
4806 .stream_name = "SLIMBUS8_HOSTLESS Capture",
4807 .cpu_dai_name = "SLIMBUS8_HOSTLESS",
4808 .platform_name = "msm-pcm-hostless",
4809 .dynamic = 1,
4810 .dpcm_capture = 1,
4811 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
4812 SND_SOC_DPCM_TRIGGER_POST},
4813 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
4814 .ignore_suspend = 1,
4815 .ignore_pmdown_time = 1,
4816 .codec_dai_name = "snd-soc-dummy-dai",
4817 .codec_name = "snd-soc-dummy",
4818 },
4819};
4820
4821static struct snd_soc_dai_link msm_tasha_fe_dai_links[] = {
4822 {
4823 .name = LPASS_BE_SLIMBUS_4_TX,
4824 .stream_name = "Slimbus4 Capture",
4825 .cpu_dai_name = "msm-dai-q6-dev.16393",
4826 .platform_name = "msm-pcm-hostless",
4827 .codec_name = "tasha_codec",
4828 .codec_dai_name = "tasha_vifeedback",
4829 .be_id = MSM_BACKEND_DAI_SLIMBUS_4_TX,
4830 .be_hw_params_fixup = msm_be_hw_params_fixup,
4831 .ops = &msm_be_ops,
4832 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
4833 .ignore_suspend = 1,
4834 },
4835 /* Ultrasound RX DAI Link */
4836 {
4837 .name = "SLIMBUS_2 Hostless Playback",
4838 .stream_name = "SLIMBUS_2 Hostless Playback",
4839 .cpu_dai_name = "msm-dai-q6-dev.16388",
4840 .platform_name = "msm-pcm-hostless",
4841 .codec_name = "tasha_codec",
4842 .codec_dai_name = "tasha_rx2",
4843 .ignore_suspend = 1,
4844 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
4845 .ops = &msm_slimbus_2_be_ops,
4846 },
4847 /* Ultrasound TX DAI Link */
4848 {
4849 .name = "SLIMBUS_2 Hostless Capture",
4850 .stream_name = "SLIMBUS_2 Hostless Capture",
4851 .cpu_dai_name = "msm-dai-q6-dev.16389",
4852 .platform_name = "msm-pcm-hostless",
4853 .codec_name = "tasha_codec",
4854 .codec_dai_name = "tasha_tx2",
4855 .ignore_suspend = 1,
4856 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
4857 .ops = &msm_slimbus_2_be_ops,
4858 },
4859 /* CPE LSM direct dai-link */
4860 {
4861 .name = "CPE Listen service",
4862 .stream_name = "CPE Listen Audio Service",
4863 .cpu_dai_name = "msm-dai-slim",
4864 .platform_name = "msm-cpe-lsm",
4865 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
4866 SND_SOC_DPCM_TRIGGER_POST},
4867 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
4868 .ignore_suspend = 1,
4869 .ignore_pmdown_time = 1,
4870 .codec_dai_name = "tasha_mad1",
4871 .codec_name = "tasha_codec",
4872 .ops = &msm_cpe_ops,
4873 },
4874 {
4875 .name = "SLIMBUS_6 Hostless Playback",
4876 .stream_name = "SLIMBUS_6 Hostless",
4877 .cpu_dai_name = "SLIMBUS6_HOSTLESS",
4878 .platform_name = "msm-pcm-hostless",
4879 .dynamic = 1,
4880 .dpcm_playback = 1,
4881 .dpcm_capture = 1,
4882 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
4883 SND_SOC_DPCM_TRIGGER_POST},
4884 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
4885 .ignore_suspend = 1,
4886 /* this dailink has playback support */
4887 .ignore_pmdown_time = 1,
4888 .codec_dai_name = "snd-soc-dummy-dai",
4889 .codec_name = "snd-soc-dummy",
4890 },
4891 /* CPE LSM EC PP direct dai-link */
4892 {
4893 .name = "CPE Listen service ECPP",
4894 .stream_name = "CPE Listen Audio Service ECPP",
4895 .cpu_dai_name = "CPE_LSM_NOHOST",
4896 .platform_name = "msm-cpe-lsm.3",
4897 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
4898 SND_SOC_DPCM_TRIGGER_POST},
4899 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
4900 .ignore_suspend = 1,
4901 .ignore_pmdown_time = 1,
4902 .codec_dai_name = "tasha_cpe",
4903 .codec_name = "tasha_codec",
4904 },
4905};
4906
4907static struct snd_soc_dai_link msm_tavil_fe_dai_links[] = {
4908 {
4909 .name = LPASS_BE_SLIMBUS_4_TX,
4910 .stream_name = "Slimbus4 Capture",
4911 .cpu_dai_name = "msm-dai-q6-dev.16393",
4912 .platform_name = "msm-pcm-hostless",
4913 .codec_name = "tavil_codec",
4914 .codec_dai_name = "tavil_vifeedback",
4915 .be_id = MSM_BACKEND_DAI_SLIMBUS_4_TX,
4916 .be_hw_params_fixup = msm_be_hw_params_fixup,
4917 .ops = &msm_be_ops,
4918 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
4919 .ignore_suspend = 1,
4920 },
4921 /* Ultrasound RX DAI Link */
4922 {
4923 .name = "SLIMBUS_2 Hostless Playback",
4924 .stream_name = "SLIMBUS_2 Hostless Playback",
4925 .cpu_dai_name = "msm-dai-q6-dev.16388",
4926 .platform_name = "msm-pcm-hostless",
4927 .codec_name = "tavil_codec",
4928 .codec_dai_name = "tavil_rx2",
4929 .ignore_suspend = 1,
4930 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
4931 .ops = &msm_slimbus_2_be_ops,
4932 },
4933 /* Ultrasound TX DAI Link */
4934 {
4935 .name = "SLIMBUS_2 Hostless Capture",
4936 .stream_name = "SLIMBUS_2 Hostless Capture",
4937 .cpu_dai_name = "msm-dai-q6-dev.16389",
4938 .platform_name = "msm-pcm-hostless",
4939 .codec_name = "tavil_codec",
4940 .codec_dai_name = "tavil_tx2",
4941 .ignore_suspend = 1,
4942 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
4943 .ops = &msm_slimbus_2_be_ops,
4944 },
4945};
4946
4947static struct snd_soc_dai_link msm_common_be_dai_links[] = {
4948 /* Backend AFE DAI Links */
4949 {
4950 .name = LPASS_BE_AFE_PCM_RX,
4951 .stream_name = "AFE Playback",
4952 .cpu_dai_name = "msm-dai-q6-dev.224",
4953 .platform_name = "msm-pcm-routing",
4954 .codec_name = "msm-stub-codec.1",
4955 .codec_dai_name = "msm-stub-rx",
4956 .no_pcm = 1,
4957 .dpcm_playback = 1,
4958 .be_id = MSM_BACKEND_DAI_AFE_PCM_RX,
4959 .be_hw_params_fixup = msm_be_hw_params_fixup,
4960 /* this dainlink has playback support */
4961 .ignore_pmdown_time = 1,
4962 .ignore_suspend = 1,
4963 },
4964 {
4965 .name = LPASS_BE_AFE_PCM_TX,
4966 .stream_name = "AFE Capture",
4967 .cpu_dai_name = "msm-dai-q6-dev.225",
4968 .platform_name = "msm-pcm-routing",
4969 .codec_name = "msm-stub-codec.1",
4970 .codec_dai_name = "msm-stub-tx",
4971 .no_pcm = 1,
4972 .dpcm_capture = 1,
4973 .be_id = MSM_BACKEND_DAI_AFE_PCM_TX,
4974 .be_hw_params_fixup = msm_be_hw_params_fixup,
4975 .ignore_suspend = 1,
4976 },
4977 /* Incall Record Uplink BACK END DAI Link */
4978 {
4979 .name = LPASS_BE_INCALL_RECORD_TX,
4980 .stream_name = "Voice Uplink Capture",
4981 .cpu_dai_name = "msm-dai-q6-dev.32772",
4982 .platform_name = "msm-pcm-routing",
4983 .codec_name = "msm-stub-codec.1",
4984 .codec_dai_name = "msm-stub-tx",
4985 .no_pcm = 1,
4986 .dpcm_capture = 1,
4987 .be_id = MSM_BACKEND_DAI_INCALL_RECORD_TX,
4988 .be_hw_params_fixup = msm_be_hw_params_fixup,
4989 .ignore_suspend = 1,
4990 },
4991 /* Incall Record Downlink BACK END DAI Link */
4992 {
4993 .name = LPASS_BE_INCALL_RECORD_RX,
4994 .stream_name = "Voice Downlink Capture",
4995 .cpu_dai_name = "msm-dai-q6-dev.32771",
4996 .platform_name = "msm-pcm-routing",
4997 .codec_name = "msm-stub-codec.1",
4998 .codec_dai_name = "msm-stub-tx",
4999 .no_pcm = 1,
5000 .dpcm_capture = 1,
5001 .be_id = MSM_BACKEND_DAI_INCALL_RECORD_RX,
5002 .be_hw_params_fixup = msm_be_hw_params_fixup,
5003 .ignore_suspend = 1,
5004 },
5005 /* Incall Music BACK END DAI Link */
5006 {
5007 .name = LPASS_BE_VOICE_PLAYBACK_TX,
5008 .stream_name = "Voice Farend Playback",
5009 .cpu_dai_name = "msm-dai-q6-dev.32773",
5010 .platform_name = "msm-pcm-routing",
5011 .codec_name = "msm-stub-codec.1",
5012 .codec_dai_name = "msm-stub-rx",
5013 .no_pcm = 1,
5014 .dpcm_playback = 1,
5015 .be_id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX,
5016 .be_hw_params_fixup = msm_be_hw_params_fixup,
5017 .ignore_suspend = 1,
5018 },
5019 /* Incall Music 2 BACK END DAI Link */
5020 {
5021 .name = LPASS_BE_VOICE2_PLAYBACK_TX,
5022 .stream_name = "Voice2 Farend Playback",
5023 .cpu_dai_name = "msm-dai-q6-dev.32770",
5024 .platform_name = "msm-pcm-routing",
5025 .codec_name = "msm-stub-codec.1",
5026 .codec_dai_name = "msm-stub-rx",
5027 .no_pcm = 1,
5028 .dpcm_playback = 1,
5029 .be_id = MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX,
5030 .be_hw_params_fixup = msm_be_hw_params_fixup,
5031 .ignore_suspend = 1,
5032 },
5033 {
5034 .name = LPASS_BE_USB_AUDIO_RX,
5035 .stream_name = "USB Audio Playback",
5036 .cpu_dai_name = "msm-dai-q6-dev.28672",
5037 .platform_name = "msm-pcm-routing",
5038 .codec_name = "msm-stub-codec.1",
5039 .codec_dai_name = "msm-stub-rx",
5040 .no_pcm = 1,
5041 .dpcm_playback = 1,
5042 .be_id = MSM_BACKEND_DAI_USB_RX,
5043 .be_hw_params_fixup = msm_be_hw_params_fixup,
5044 .ignore_pmdown_time = 1,
5045 .ignore_suspend = 1,
5046 },
5047 {
5048 .name = LPASS_BE_USB_AUDIO_TX,
5049 .stream_name = "USB Audio Capture",
5050 .cpu_dai_name = "msm-dai-q6-dev.28673",
5051 .platform_name = "msm-pcm-routing",
5052 .codec_name = "msm-stub-codec.1",
5053 .codec_dai_name = "msm-stub-tx",
5054 .no_pcm = 1,
5055 .dpcm_capture = 1,
5056 .be_id = MSM_BACKEND_DAI_USB_TX,
5057 .be_hw_params_fixup = msm_be_hw_params_fixup,
5058 .ignore_suspend = 1,
5059 },
5060 {
5061 .name = LPASS_BE_PRI_TDM_RX_0,
5062 .stream_name = "Primary TDM0 Playback",
5063 .cpu_dai_name = "msm-dai-q6-tdm.36864",
5064 .platform_name = "msm-pcm-routing",
5065 .codec_name = "msm-stub-codec.1",
5066 .codec_dai_name = "msm-stub-rx",
5067 .no_pcm = 1,
5068 .dpcm_playback = 1,
5069 .be_id = MSM_BACKEND_DAI_PRI_TDM_RX_0,
5070 .be_hw_params_fixup = msm_be_hw_params_fixup,
5071 .ops = &msm_tdm_be_ops,
5072 .ignore_suspend = 1,
5073 },
5074 {
5075 .name = LPASS_BE_PRI_TDM_TX_0,
5076 .stream_name = "Primary TDM0 Capture",
5077 .cpu_dai_name = "msm-dai-q6-tdm.36865",
5078 .platform_name = "msm-pcm-routing",
5079 .codec_name = "msm-stub-codec.1",
5080 .codec_dai_name = "msm-stub-tx",
5081 .no_pcm = 1,
5082 .dpcm_capture = 1,
5083 .be_id = MSM_BACKEND_DAI_PRI_TDM_TX_0,
5084 .be_hw_params_fixup = msm_be_hw_params_fixup,
5085 .ops = &msm_tdm_be_ops,
5086 .ignore_suspend = 1,
5087 },
5088 {
5089 .name = LPASS_BE_SEC_TDM_RX_0,
5090 .stream_name = "Secondary TDM0 Playback",
5091 .cpu_dai_name = "msm-dai-q6-tdm.36880",
5092 .platform_name = "msm-pcm-routing",
5093 .codec_name = "msm-stub-codec.1",
5094 .codec_dai_name = "msm-stub-rx",
5095 .no_pcm = 1,
5096 .dpcm_playback = 1,
5097 .be_id = MSM_BACKEND_DAI_SEC_TDM_RX_0,
5098 .be_hw_params_fixup = msm_be_hw_params_fixup,
5099 .ops = &msm_tdm_be_ops,
5100 .ignore_suspend = 1,
5101 },
5102 {
5103 .name = LPASS_BE_SEC_TDM_TX_0,
5104 .stream_name = "Secondary TDM0 Capture",
5105 .cpu_dai_name = "msm-dai-q6-tdm.36881",
5106 .platform_name = "msm-pcm-routing",
5107 .codec_name = "msm-stub-codec.1",
5108 .codec_dai_name = "msm-stub-tx",
5109 .no_pcm = 1,
5110 .dpcm_capture = 1,
5111 .be_id = MSM_BACKEND_DAI_SEC_TDM_TX_0,
5112 .be_hw_params_fixup = msm_be_hw_params_fixup,
5113 .ops = &msm_tdm_be_ops,
5114 .ignore_suspend = 1,
5115 },
5116 {
5117 .name = LPASS_BE_TERT_TDM_RX_0,
5118 .stream_name = "Tertiary TDM0 Playback",
5119 .cpu_dai_name = "msm-dai-q6-tdm.36896",
5120 .platform_name = "msm-pcm-routing",
5121 .codec_name = "msm-stub-codec.1",
5122 .codec_dai_name = "msm-stub-rx",
5123 .no_pcm = 1,
5124 .dpcm_playback = 1,
5125 .be_id = MSM_BACKEND_DAI_TERT_TDM_RX_0,
5126 .be_hw_params_fixup = msm_be_hw_params_fixup,
5127 .ops = &msm_tdm_be_ops,
5128 .ignore_suspend = 1,
5129 },
5130 {
5131 .name = LPASS_BE_TERT_TDM_TX_0,
5132 .stream_name = "Tertiary TDM0 Capture",
5133 .cpu_dai_name = "msm-dai-q6-tdm.36897",
5134 .platform_name = "msm-pcm-routing",
5135 .codec_name = "msm-stub-codec.1",
5136 .codec_dai_name = "msm-stub-tx",
5137 .no_pcm = 1,
5138 .dpcm_capture = 1,
5139 .be_id = MSM_BACKEND_DAI_TERT_TDM_TX_0,
5140 .be_hw_params_fixup = msm_be_hw_params_fixup,
5141 .ops = &msm_tdm_be_ops,
5142 .ignore_suspend = 1,
5143 },
5144 {
5145 .name = LPASS_BE_QUAT_TDM_RX_0,
5146 .stream_name = "Quaternary TDM0 Playback",
5147 .cpu_dai_name = "msm-dai-q6-tdm.36912",
5148 .platform_name = "msm-pcm-routing",
5149 .codec_name = "msm-stub-codec.1",
5150 .codec_dai_name = "msm-stub-rx",
5151 .no_pcm = 1,
5152 .dpcm_playback = 1,
5153 .be_id = MSM_BACKEND_DAI_QUAT_TDM_RX_0,
5154 .be_hw_params_fixup = msm_be_hw_params_fixup,
5155 .ops = &msm_tdm_be_ops,
5156 .ignore_suspend = 1,
5157 },
5158 {
5159 .name = LPASS_BE_QUAT_TDM_TX_0,
5160 .stream_name = "Quaternary TDM0 Capture",
5161 .cpu_dai_name = "msm-dai-q6-tdm.36913",
5162 .platform_name = "msm-pcm-routing",
5163 .codec_name = "msm-stub-codec.1",
5164 .codec_dai_name = "msm-stub-tx",
5165 .no_pcm = 1,
5166 .dpcm_capture = 1,
5167 .be_id = MSM_BACKEND_DAI_QUAT_TDM_TX_0,
5168 .be_hw_params_fixup = msm_be_hw_params_fixup,
5169 .ops = &msm_tdm_be_ops,
5170 .ignore_suspend = 1,
5171 },
5172};
5173
5174static struct snd_soc_dai_link msm_tasha_be_dai_links[] = {
5175 {
5176 .name = LPASS_BE_SLIMBUS_0_RX,
5177 .stream_name = "Slimbus Playback",
5178 .cpu_dai_name = "msm-dai-q6-dev.16384",
5179 .platform_name = "msm-pcm-routing",
5180 .codec_name = "tasha_codec",
5181 .codec_dai_name = "tasha_mix_rx1",
5182 .no_pcm = 1,
5183 .dpcm_playback = 1,
5184 .be_id = MSM_BACKEND_DAI_SLIMBUS_0_RX,
5185 .init = &msm_audrx_init,
5186 .be_hw_params_fixup = msm_be_hw_params_fixup,
5187 /* this dainlink has playback support */
5188 .ignore_pmdown_time = 1,
5189 .ignore_suspend = 1,
5190 .ops = &msm_be_ops,
5191 },
5192 {
5193 .name = LPASS_BE_SLIMBUS_0_TX,
5194 .stream_name = "Slimbus Capture",
5195 .cpu_dai_name = "msm-dai-q6-dev.16385",
5196 .platform_name = "msm-pcm-routing",
5197 .codec_name = "tasha_codec",
5198 .codec_dai_name = "tasha_tx1",
5199 .no_pcm = 1,
5200 .dpcm_capture = 1,
5201 .be_id = MSM_BACKEND_DAI_SLIMBUS_0_TX,
5202 .be_hw_params_fixup = msm_be_hw_params_fixup,
5203 .ignore_suspend = 1,
5204 .ops = &msm_be_ops,
5205 },
5206 {
5207 .name = LPASS_BE_SLIMBUS_1_RX,
5208 .stream_name = "Slimbus1 Playback",
5209 .cpu_dai_name = "msm-dai-q6-dev.16386",
5210 .platform_name = "msm-pcm-routing",
5211 .codec_name = "tasha_codec",
5212 .codec_dai_name = "tasha_mix_rx1",
5213 .no_pcm = 1,
5214 .dpcm_playback = 1,
5215 .be_id = MSM_BACKEND_DAI_SLIMBUS_1_RX,
5216 .be_hw_params_fixup = msm_be_hw_params_fixup,
5217 .ops = &msm_be_ops,
5218 /* dai link has playback support */
5219 .ignore_pmdown_time = 1,
5220 .ignore_suspend = 1,
5221 },
5222 {
5223 .name = LPASS_BE_SLIMBUS_1_TX,
5224 .stream_name = "Slimbus1 Capture",
5225 .cpu_dai_name = "msm-dai-q6-dev.16387",
5226 .platform_name = "msm-pcm-routing",
5227 .codec_name = "tasha_codec",
5228 .codec_dai_name = "tasha_tx3",
5229 .no_pcm = 1,
5230 .dpcm_capture = 1,
5231 .be_id = MSM_BACKEND_DAI_SLIMBUS_1_TX,
5232 .be_hw_params_fixup = msm_be_hw_params_fixup,
5233 .ops = &msm_be_ops,
5234 .ignore_suspend = 1,
5235 },
5236 {
5237 .name = LPASS_BE_SLIMBUS_3_RX,
5238 .stream_name = "Slimbus3 Playback",
5239 .cpu_dai_name = "msm-dai-q6-dev.16390",
5240 .platform_name = "msm-pcm-routing",
5241 .codec_name = "tasha_codec",
5242 .codec_dai_name = "tasha_mix_rx1",
5243 .no_pcm = 1,
5244 .dpcm_playback = 1,
5245 .be_id = MSM_BACKEND_DAI_SLIMBUS_3_RX,
5246 .be_hw_params_fixup = msm_be_hw_params_fixup,
5247 .ops = &msm_be_ops,
5248 /* dai link has playback support */
5249 .ignore_pmdown_time = 1,
5250 .ignore_suspend = 1,
5251 },
5252 {
5253 .name = LPASS_BE_SLIMBUS_3_TX,
5254 .stream_name = "Slimbus3 Capture",
5255 .cpu_dai_name = "msm-dai-q6-dev.16391",
5256 .platform_name = "msm-pcm-routing",
5257 .codec_name = "tasha_codec",
5258 .codec_dai_name = "tasha_tx1",
5259 .no_pcm = 1,
5260 .dpcm_capture = 1,
5261 .be_id = MSM_BACKEND_DAI_SLIMBUS_3_TX,
5262 .be_hw_params_fixup = msm_be_hw_params_fixup,
5263 .ops = &msm_be_ops,
5264 .ignore_suspend = 1,
5265 },
5266 {
5267 .name = LPASS_BE_SLIMBUS_4_RX,
5268 .stream_name = "Slimbus4 Playback",
5269 .cpu_dai_name = "msm-dai-q6-dev.16392",
5270 .platform_name = "msm-pcm-routing",
5271 .codec_name = "tasha_codec",
5272 .codec_dai_name = "tasha_mix_rx1",
5273 .no_pcm = 1,
5274 .dpcm_playback = 1,
5275 .be_id = MSM_BACKEND_DAI_SLIMBUS_4_RX,
5276 .be_hw_params_fixup = msm_be_hw_params_fixup,
5277 .ops = &msm_be_ops,
5278 /* dai link has playback support */
5279 .ignore_pmdown_time = 1,
5280 .ignore_suspend = 1,
5281 },
5282 {
5283 .name = LPASS_BE_SLIMBUS_5_RX,
5284 .stream_name = "Slimbus5 Playback",
5285 .cpu_dai_name = "msm-dai-q6-dev.16394",
5286 .platform_name = "msm-pcm-routing",
5287 .codec_name = "tasha_codec",
5288 .codec_dai_name = "tasha_rx3",
5289 .no_pcm = 1,
5290 .dpcm_playback = 1,
5291 .be_id = MSM_BACKEND_DAI_SLIMBUS_5_RX,
5292 .be_hw_params_fixup = msm_be_hw_params_fixup,
5293 .ops = &msm_be_ops,
5294 /* dai link has playback support */
5295 .ignore_pmdown_time = 1,
5296 .ignore_suspend = 1,
5297 },
5298 /* MAD BE */
5299 {
5300 .name = LPASS_BE_SLIMBUS_5_TX,
5301 .stream_name = "Slimbus5 Capture",
5302 .cpu_dai_name = "msm-dai-q6-dev.16395",
5303 .platform_name = "msm-pcm-routing",
5304 .codec_name = "tasha_codec",
5305 .codec_dai_name = "tasha_mad1",
5306 .no_pcm = 1,
5307 .dpcm_capture = 1,
5308 .be_id = MSM_BACKEND_DAI_SLIMBUS_5_TX,
5309 .be_hw_params_fixup = msm_be_hw_params_fixup,
5310 .ops = &msm_be_ops,
5311 .ignore_suspend = 1,
5312 },
5313 {
5314 .name = LPASS_BE_SLIMBUS_6_RX,
5315 .stream_name = "Slimbus6 Playback",
5316 .cpu_dai_name = "msm-dai-q6-dev.16396",
5317 .platform_name = "msm-pcm-routing",
5318 .codec_name = "tasha_codec",
5319 .codec_dai_name = "tasha_rx4",
5320 .no_pcm = 1,
5321 .dpcm_playback = 1,
5322 .be_id = MSM_BACKEND_DAI_SLIMBUS_6_RX,
5323 .be_hw_params_fixup = msm_be_hw_params_fixup,
5324 .ops = &msm_be_ops,
5325 /* dai link has playback support */
5326 .ignore_pmdown_time = 1,
5327 .ignore_suspend = 1,
5328 },
5329};
5330
5331static struct snd_soc_dai_link msm_tavil_be_dai_links[] = {
5332 {
5333 .name = LPASS_BE_SLIMBUS_0_RX,
5334 .stream_name = "Slimbus Playback",
5335 .cpu_dai_name = "msm-dai-q6-dev.16384",
5336 .platform_name = "msm-pcm-routing",
5337 .codec_name = "tavil_codec",
5338 .codec_dai_name = "tavil_rx1",
5339 .no_pcm = 1,
5340 .dpcm_playback = 1,
5341 .be_id = MSM_BACKEND_DAI_SLIMBUS_0_RX,
5342 .init = &msm_audrx_init,
5343 .be_hw_params_fixup = msm_be_hw_params_fixup,
5344 /* this dainlink has playback support */
5345 .ignore_pmdown_time = 1,
5346 .ignore_suspend = 1,
5347 .ops = &msm_be_ops,
5348 },
5349 {
5350 .name = LPASS_BE_SLIMBUS_0_TX,
5351 .stream_name = "Slimbus Capture",
5352 .cpu_dai_name = "msm-dai-q6-dev.16385",
5353 .platform_name = "msm-pcm-routing",
5354 .codec_name = "tavil_codec",
5355 .codec_dai_name = "tavil_tx1",
5356 .no_pcm = 1,
5357 .dpcm_capture = 1,
5358 .be_id = MSM_BACKEND_DAI_SLIMBUS_0_TX,
5359 .be_hw_params_fixup = msm_be_hw_params_fixup,
5360 .ignore_suspend = 1,
5361 .ops = &msm_be_ops,
5362 },
5363 {
5364 .name = LPASS_BE_SLIMBUS_1_RX,
5365 .stream_name = "Slimbus1 Playback",
5366 .cpu_dai_name = "msm-dai-q6-dev.16386",
5367 .platform_name = "msm-pcm-routing",
5368 .codec_name = "tavil_codec",
5369 .codec_dai_name = "tavil_rx1",
5370 .no_pcm = 1,
5371 .dpcm_playback = 1,
5372 .be_id = MSM_BACKEND_DAI_SLIMBUS_1_RX,
5373 .be_hw_params_fixup = msm_be_hw_params_fixup,
5374 .ops = &msm_be_ops,
5375 /* dai link has playback support */
5376 .ignore_pmdown_time = 1,
5377 .ignore_suspend = 1,
5378 },
5379 {
5380 .name = LPASS_BE_SLIMBUS_1_TX,
5381 .stream_name = "Slimbus1 Capture",
5382 .cpu_dai_name = "msm-dai-q6-dev.16387",
5383 .platform_name = "msm-pcm-routing",
5384 .codec_name = "tavil_codec",
5385 .codec_dai_name = "tavil_tx3",
5386 .no_pcm = 1,
5387 .dpcm_capture = 1,
5388 .be_id = MSM_BACKEND_DAI_SLIMBUS_1_TX,
5389 .be_hw_params_fixup = msm_be_hw_params_fixup,
5390 .ops = &msm_be_ops,
5391 .ignore_suspend = 1,
5392 },
5393 {
5394 .name = LPASS_BE_SLIMBUS_2_RX,
5395 .stream_name = "Slimbus2 Playback",
5396 .cpu_dai_name = "msm-dai-q6-dev.16388",
5397 .platform_name = "msm-pcm-routing",
5398 .codec_name = "tavil_codec",
5399 .codec_dai_name = "tavil_rx2",
5400 .no_pcm = 1,
5401 .dpcm_playback = 1,
5402 .be_id = MSM_BACKEND_DAI_SLIMBUS_2_RX,
5403 .be_hw_params_fixup = msm_be_hw_params_fixup,
5404 .ops = &msm_be_ops,
5405 .ignore_pmdown_time = 1,
5406 .ignore_suspend = 1,
5407 },
5408 {
5409 .name = LPASS_BE_SLIMBUS_3_RX,
5410 .stream_name = "Slimbus3 Playback",
5411 .cpu_dai_name = "msm-dai-q6-dev.16390",
5412 .platform_name = "msm-pcm-routing",
5413 .codec_name = "tavil_codec",
5414 .codec_dai_name = "tavil_rx1",
5415 .no_pcm = 1,
5416 .dpcm_playback = 1,
5417 .be_id = MSM_BACKEND_DAI_SLIMBUS_3_RX,
5418 .be_hw_params_fixup = msm_be_hw_params_fixup,
5419 .ops = &msm_be_ops,
5420 /* dai link has playback support */
5421 .ignore_pmdown_time = 1,
5422 .ignore_suspend = 1,
5423 },
5424 {
5425 .name = LPASS_BE_SLIMBUS_3_TX,
5426 .stream_name = "Slimbus3 Capture",
5427 .cpu_dai_name = "msm-dai-q6-dev.16391",
5428 .platform_name = "msm-pcm-routing",
5429 .codec_name = "tavil_codec",
5430 .codec_dai_name = "tavil_tx1",
5431 .no_pcm = 1,
5432 .dpcm_capture = 1,
5433 .be_id = MSM_BACKEND_DAI_SLIMBUS_3_TX,
5434 .be_hw_params_fixup = msm_be_hw_params_fixup,
5435 .ops = &msm_be_ops,
5436 .ignore_suspend = 1,
5437 },
5438 {
5439 .name = LPASS_BE_SLIMBUS_4_RX,
5440 .stream_name = "Slimbus4 Playback",
5441 .cpu_dai_name = "msm-dai-q6-dev.16392",
5442 .platform_name = "msm-pcm-routing",
5443 .codec_name = "tavil_codec",
5444 .codec_dai_name = "tavil_rx1",
5445 .no_pcm = 1,
5446 .dpcm_playback = 1,
5447 .be_id = MSM_BACKEND_DAI_SLIMBUS_4_RX,
5448 .be_hw_params_fixup = msm_be_hw_params_fixup,
5449 .ops = &msm_be_ops,
5450 /* dai link has playback support */
5451 .ignore_pmdown_time = 1,
5452 .ignore_suspend = 1,
5453 },
5454 {
5455 .name = LPASS_BE_SLIMBUS_5_RX,
5456 .stream_name = "Slimbus5 Playback",
5457 .cpu_dai_name = "msm-dai-q6-dev.16394",
5458 .platform_name = "msm-pcm-routing",
5459 .codec_name = "tavil_codec",
5460 .codec_dai_name = "tavil_rx3",
5461 .no_pcm = 1,
5462 .dpcm_playback = 1,
5463 .be_id = MSM_BACKEND_DAI_SLIMBUS_5_RX,
5464 .be_hw_params_fixup = msm_be_hw_params_fixup,
5465 .ops = &msm_be_ops,
5466 /* dai link has playback support */
5467 .ignore_pmdown_time = 1,
5468 .ignore_suspend = 1,
5469 },
5470 /* MAD BE */
5471 {
5472 .name = LPASS_BE_SLIMBUS_5_TX,
5473 .stream_name = "Slimbus5 Capture",
5474 .cpu_dai_name = "msm-dai-q6-dev.16395",
5475 .platform_name = "msm-pcm-routing",
5476 .codec_name = "tavil_codec",
5477 .codec_dai_name = "tavil_mad1",
5478 .no_pcm = 1,
5479 .dpcm_capture = 1,
5480 .be_id = MSM_BACKEND_DAI_SLIMBUS_5_TX,
5481 .be_hw_params_fixup = msm_be_hw_params_fixup,
5482 .ops = &msm_be_ops,
5483 .ignore_suspend = 1,
5484 },
5485 {
5486 .name = LPASS_BE_SLIMBUS_6_RX,
5487 .stream_name = "Slimbus6 Playback",
5488 .cpu_dai_name = "msm-dai-q6-dev.16396",
5489 .platform_name = "msm-pcm-routing",
5490 .codec_name = "tavil_codec",
5491 .codec_dai_name = "tavil_rx4",
5492 .no_pcm = 1,
5493 .dpcm_playback = 1,
5494 .be_id = MSM_BACKEND_DAI_SLIMBUS_6_RX,
5495 .be_hw_params_fixup = msm_be_hw_params_fixup,
5496 .ops = &msm_be_ops,
5497 /* dai link has playback support */
5498 .ignore_pmdown_time = 1,
5499 .ignore_suspend = 1,
5500 },
5501};
5502
5503static struct snd_soc_dai_link msm_wcn_be_dai_links[] = {
5504 {
5505 .name = LPASS_BE_SLIMBUS_7_RX,
5506 .stream_name = "Slimbus7 Playback",
5507 .cpu_dai_name = "msm-dai-q6-dev.16398",
5508 .platform_name = "msm-pcm-routing",
5509 .codec_name = "btfmslim_slave",
5510 /* BT codec driver determines capabilities based on
5511 * dai name, bt codecdai name should always contains
5512 * supported usecase information
5513 */
5514 .codec_dai_name = "btfm_bt_sco_a2dp_slim_rx",
5515 .no_pcm = 1,
5516 .dpcm_playback = 1,
5517 .be_id = MSM_BACKEND_DAI_SLIMBUS_7_RX,
5518 .be_hw_params_fixup = msm_be_hw_params_fixup,
5519 .ops = &msm_wcn_ops,
5520 /* dai link has playback support */
5521 .ignore_pmdown_time = 1,
5522 .ignore_suspend = 1,
5523 },
5524 {
5525 .name = LPASS_BE_SLIMBUS_7_TX,
5526 .stream_name = "Slimbus7 Capture",
5527 .cpu_dai_name = "msm-dai-q6-dev.16399",
5528 .platform_name = "msm-pcm-routing",
5529 .codec_name = "btfmslim_slave",
5530 .codec_dai_name = "btfm_bt_sco_slim_tx",
5531 .no_pcm = 1,
5532 .dpcm_capture = 1,
5533 .be_id = MSM_BACKEND_DAI_SLIMBUS_7_TX,
5534 .be_hw_params_fixup = msm_be_hw_params_fixup,
5535 .ops = &msm_wcn_ops,
5536 .ignore_suspend = 1,
5537 },
5538 {
5539 .name = LPASS_BE_SLIMBUS_8_TX,
5540 .stream_name = "Slimbus8 Capture",
5541 .cpu_dai_name = "msm-dai-q6-dev.16401",
5542 .platform_name = "msm-pcm-routing",
5543 .codec_name = "btfmslim_slave",
5544 .codec_dai_name = "btfm_fm_slim_tx",
5545 .no_pcm = 1,
5546 .dpcm_capture = 1,
5547 .be_id = MSM_BACKEND_DAI_SLIMBUS_8_TX,
5548 .be_hw_params_fixup = msm_be_hw_params_fixup,
5549 .init = &msm_wcn_init,
5550 .ops = &msm_wcn_ops,
5551 .ignore_suspend = 1,
5552 },
5553};
5554
5555static struct snd_soc_dai_link ext_disp_be_dai_link[] = {
5556 /* HDMI BACK END DAI Link */
5557 {
5558 .name = LPASS_BE_HDMI,
5559 .stream_name = "HDMI Playback",
5560 .cpu_dai_name = "msm-dai-q6-hdmi.8",
5561 .platform_name = "msm-pcm-routing",
5562 .codec_name = "msm-ext-disp-audio-codec-rx",
5563 .codec_dai_name = "msm_hdmi_audio_codec_rx_dai",
5564 .no_pcm = 1,
5565 .dpcm_playback = 1,
5566 .be_id = MSM_BACKEND_DAI_HDMI_RX,
5567 .be_hw_params_fixup = msm_be_hw_params_fixup,
5568 .ignore_pmdown_time = 1,
5569 .ignore_suspend = 1,
5570 },
5571 /* DISP PORT BACK END DAI Link */
5572 {
5573 .name = LPASS_BE_DISPLAY_PORT,
5574 .stream_name = "Display Port Playback",
5575 .cpu_dai_name = "msm-dai-q6-dp.24608",
5576 .platform_name = "msm-pcm-routing",
5577 .codec_name = "msm-ext-disp-audio-codec-rx",
5578 .codec_dai_name = "msm_dp_audio_codec_rx_dai",
5579 .no_pcm = 1,
5580 .dpcm_playback = 1,
5581 .be_id = MSM_BACKEND_DAI_DISPLAY_PORT_RX,
5582 .be_hw_params_fixup = msm_be_hw_params_fixup,
5583 .ignore_pmdown_time = 1,
5584 .ignore_suspend = 1,
5585 },
5586};
5587
5588static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = {
5589 {
5590 .name = LPASS_BE_PRI_MI2S_RX,
5591 .stream_name = "Primary MI2S Playback",
5592 .cpu_dai_name = "msm-dai-q6-mi2s.0",
5593 .platform_name = "msm-pcm-routing",
5594 .codec_name = "msm-stub-codec.1",
5595 .codec_dai_name = "msm-stub-rx",
5596 .no_pcm = 1,
5597 .dpcm_playback = 1,
5598 .be_id = MSM_BACKEND_DAI_PRI_MI2S_RX,
5599 .be_hw_params_fixup = msm_be_hw_params_fixup,
5600 .ops = &msm_mi2s_be_ops,
5601 .ignore_suspend = 1,
5602 .ignore_pmdown_time = 1,
5603 },
5604 {
5605 .name = LPASS_BE_PRI_MI2S_TX,
5606 .stream_name = "Primary MI2S Capture",
5607 .cpu_dai_name = "msm-dai-q6-mi2s.0",
5608 .platform_name = "msm-pcm-routing",
5609 .codec_name = "msm-stub-codec.1",
5610 .codec_dai_name = "msm-stub-tx",
5611 .no_pcm = 1,
5612 .dpcm_capture = 1,
5613 .be_id = MSM_BACKEND_DAI_PRI_MI2S_TX,
5614 .be_hw_params_fixup = msm_be_hw_params_fixup,
5615 .ops = &msm_mi2s_be_ops,
5616 .ignore_suspend = 1,
5617 },
5618 {
5619 .name = LPASS_BE_SEC_MI2S_RX,
5620 .stream_name = "Secondary MI2S Playback",
5621 .cpu_dai_name = "msm-dai-q6-mi2s.1",
5622 .platform_name = "msm-pcm-routing",
5623 .codec_name = "msm-stub-codec.1",
5624 .codec_dai_name = "msm-stub-rx",
5625 .no_pcm = 1,
5626 .dpcm_playback = 1,
5627 .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX,
5628 .be_hw_params_fixup = msm_be_hw_params_fixup,
5629 .ops = &msm_mi2s_be_ops,
5630 .ignore_suspend = 1,
5631 .ignore_pmdown_time = 1,
5632 },
5633 {
5634 .name = LPASS_BE_SEC_MI2S_TX,
5635 .stream_name = "Secondary MI2S Capture",
5636 .cpu_dai_name = "msm-dai-q6-mi2s.1",
5637 .platform_name = "msm-pcm-routing",
5638 .codec_name = "msm-stub-codec.1",
5639 .codec_dai_name = "msm-stub-tx",
5640 .no_pcm = 1,
5641 .dpcm_capture = 1,
5642 .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX,
5643 .be_hw_params_fixup = msm_be_hw_params_fixup,
5644 .ops = &msm_mi2s_be_ops,
5645 .ignore_suspend = 1,
5646 },
5647 {
5648 .name = LPASS_BE_TERT_MI2S_RX,
5649 .stream_name = "Tertiary MI2S Playback",
5650 .cpu_dai_name = "msm-dai-q6-mi2s.2",
5651 .platform_name = "msm-pcm-routing",
5652 .codec_name = "msm-stub-codec.1",
5653 .codec_dai_name = "msm-stub-rx",
5654 .no_pcm = 1,
5655 .dpcm_playback = 1,
5656 .be_id = MSM_BACKEND_DAI_TERTIARY_MI2S_RX,
5657 .be_hw_params_fixup = msm_be_hw_params_fixup,
5658 .ops = &msm_mi2s_be_ops,
5659 .ignore_suspend = 1,
5660 .ignore_pmdown_time = 1,
5661 },
5662 {
5663 .name = LPASS_BE_TERT_MI2S_TX,
5664 .stream_name = "Tertiary MI2S Capture",
5665 .cpu_dai_name = "msm-dai-q6-mi2s.2",
5666 .platform_name = "msm-pcm-routing",
5667 .codec_name = "msm-stub-codec.1",
5668 .codec_dai_name = "msm-stub-tx",
5669 .no_pcm = 1,
5670 .dpcm_capture = 1,
5671 .be_id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX,
5672 .be_hw_params_fixup = msm_be_hw_params_fixup,
5673 .ops = &msm_mi2s_be_ops,
5674 .ignore_suspend = 1,
5675 },
5676 {
5677 .name = LPASS_BE_QUAT_MI2S_RX,
5678 .stream_name = "Quaternary MI2S Playback",
5679 .cpu_dai_name = "msm-dai-q6-mi2s.3",
5680 .platform_name = "msm-pcm-routing",
5681 .codec_name = "msm-stub-codec.1",
5682 .codec_dai_name = "msm-stub-rx",
5683 .no_pcm = 1,
5684 .dpcm_playback = 1,
5685 .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX,
5686 .be_hw_params_fixup = msm_be_hw_params_fixup,
5687 .ops = &msm_mi2s_be_ops,
5688 .ignore_suspend = 1,
5689 .ignore_pmdown_time = 1,
5690 },
5691 {
5692 .name = LPASS_BE_QUAT_MI2S_TX,
5693 .stream_name = "Quaternary MI2S Capture",
5694 .cpu_dai_name = "msm-dai-q6-mi2s.3",
5695 .platform_name = "msm-pcm-routing",
5696 .codec_name = "msm-stub-codec.1",
5697 .codec_dai_name = "msm-stub-tx",
5698 .no_pcm = 1,
5699 .dpcm_capture = 1,
5700 .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX,
5701 .be_hw_params_fixup = msm_be_hw_params_fixup,
5702 .ops = &msm_mi2s_be_ops,
5703 .ignore_suspend = 1,
5704 },
5705};
5706
5707static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = {
5708 /* Primary AUX PCM Backend DAI Links */
5709 {
5710 .name = LPASS_BE_AUXPCM_RX,
5711 .stream_name = "AUX PCM Playback",
5712 .cpu_dai_name = "msm-dai-q6-auxpcm.1",
5713 .platform_name = "msm-pcm-routing",
5714 .codec_name = "msm-stub-codec.1",
5715 .codec_dai_name = "msm-stub-rx",
5716 .no_pcm = 1,
5717 .dpcm_playback = 1,
5718 .be_id = MSM_BACKEND_DAI_AUXPCM_RX,
5719 .be_hw_params_fixup = msm_be_hw_params_fixup,
5720 .ignore_pmdown_time = 1,
5721 .ignore_suspend = 1,
5722 .ops = &msm_aux_pcm_be_ops,
5723 },
5724 {
5725 .name = LPASS_BE_AUXPCM_TX,
5726 .stream_name = "AUX PCM Capture",
5727 .cpu_dai_name = "msm-dai-q6-auxpcm.1",
5728 .platform_name = "msm-pcm-routing",
5729 .codec_name = "msm-stub-codec.1",
5730 .codec_dai_name = "msm-stub-tx",
5731 .no_pcm = 1,
5732 .dpcm_capture = 1,
5733 .be_id = MSM_BACKEND_DAI_AUXPCM_TX,
5734 .be_hw_params_fixup = msm_be_hw_params_fixup,
5735 .ignore_pmdown_time = 1,
5736 .ignore_suspend = 1,
5737 .ops = &msm_aux_pcm_be_ops,
5738 },
5739 /* Secondary AUX PCM Backend DAI Links */
5740 {
5741 .name = LPASS_BE_SEC_AUXPCM_RX,
5742 .stream_name = "Sec AUX PCM Playback",
5743 .cpu_dai_name = "msm-dai-q6-auxpcm.2",
5744 .platform_name = "msm-pcm-routing",
5745 .codec_name = "msm-stub-codec.1",
5746 .codec_dai_name = "msm-stub-rx",
5747 .no_pcm = 1,
5748 .dpcm_playback = 1,
5749 .be_id = MSM_BACKEND_DAI_SEC_AUXPCM_RX,
5750 .be_hw_params_fixup = msm_be_hw_params_fixup,
5751 .ignore_pmdown_time = 1,
5752 .ignore_suspend = 1,
5753 .ops = &msm_aux_pcm_be_ops,
5754 },
5755 {
5756 .name = LPASS_BE_SEC_AUXPCM_TX,
5757 .stream_name = "Sec AUX PCM Capture",
5758 .cpu_dai_name = "msm-dai-q6-auxpcm.2",
5759 .platform_name = "msm-pcm-routing",
5760 .codec_name = "msm-stub-codec.1",
5761 .codec_dai_name = "msm-stub-tx",
5762 .no_pcm = 1,
5763 .dpcm_capture = 1,
5764 .be_id = MSM_BACKEND_DAI_SEC_AUXPCM_TX,
5765 .be_hw_params_fixup = msm_be_hw_params_fixup,
5766 .ignore_suspend = 1,
5767 .ignore_pmdown_time = 1,
5768 .ops = &msm_aux_pcm_be_ops,
5769 },
5770 /* Tertiary AUX PCM Backend DAI Links */
5771 {
5772 .name = LPASS_BE_TERT_AUXPCM_RX,
5773 .stream_name = "Tert AUX PCM Playback",
5774 .cpu_dai_name = "msm-dai-q6-auxpcm.3",
5775 .platform_name = "msm-pcm-routing",
5776 .codec_name = "msm-stub-codec.1",
5777 .codec_dai_name = "msm-stub-rx",
5778 .no_pcm = 1,
5779 .dpcm_playback = 1,
5780 .be_id = MSM_BACKEND_DAI_TERT_AUXPCM_RX,
5781 .be_hw_params_fixup = msm_be_hw_params_fixup,
5782 .ignore_pmdown_time = 1,
5783 .ignore_suspend = 1,
5784 .ops = &msm_aux_pcm_be_ops,
5785 },
5786 {
5787 .name = LPASS_BE_TERT_AUXPCM_TX,
5788 .stream_name = "Tert AUX PCM Capture",
5789 .cpu_dai_name = "msm-dai-q6-auxpcm.3",
5790 .platform_name = "msm-pcm-routing",
5791 .codec_name = "msm-stub-codec.1",
5792 .codec_dai_name = "msm-stub-tx",
5793 .no_pcm = 1,
5794 .dpcm_capture = 1,
5795 .be_id = MSM_BACKEND_DAI_TERT_AUXPCM_TX,
5796 .be_hw_params_fixup = msm_be_hw_params_fixup,
5797 .ignore_suspend = 1,
5798 .ignore_pmdown_time = 1,
5799 .ops = &msm_aux_pcm_be_ops,
5800 },
5801 /* Quaternary AUX PCM Backend DAI Links */
5802 {
5803 .name = LPASS_BE_QUAT_AUXPCM_RX,
5804 .stream_name = "Quat AUX PCM Playback",
5805 .cpu_dai_name = "msm-dai-q6-auxpcm.4",
5806 .platform_name = "msm-pcm-routing",
5807 .codec_name = "msm-stub-codec.1",
5808 .codec_dai_name = "msm-stub-rx",
5809 .no_pcm = 1,
5810 .dpcm_playback = 1,
5811 .be_id = MSM_BACKEND_DAI_QUAT_AUXPCM_RX,
5812 .be_hw_params_fixup = msm_be_hw_params_fixup,
5813 .ignore_pmdown_time = 1,
5814 .ignore_suspend = 1,
5815 .ops = &msm_aux_pcm_be_ops,
5816 },
5817 {
5818 .name = LPASS_BE_QUAT_AUXPCM_TX,
5819 .stream_name = "Quat AUX PCM Capture",
5820 .cpu_dai_name = "msm-dai-q6-auxpcm.4",
5821 .platform_name = "msm-pcm-routing",
5822 .codec_name = "msm-stub-codec.1",
5823 .codec_dai_name = "msm-stub-tx",
5824 .no_pcm = 1,
5825 .dpcm_capture = 1,
5826 .be_id = MSM_BACKEND_DAI_QUAT_AUXPCM_TX,
5827 .be_hw_params_fixup = msm_be_hw_params_fixup,
5828 .ignore_suspend = 1,
5829 .ignore_pmdown_time = 1,
5830 .ops = &msm_aux_pcm_be_ops,
5831 },
5832};
5833
5834static struct snd_soc_dai_link msm_tasha_dai_links[
5835 ARRAY_SIZE(msm_common_dai_links) +
5836 ARRAY_SIZE(msm_tasha_fe_dai_links) +
5837 ARRAY_SIZE(msm_common_be_dai_links) +
5838 ARRAY_SIZE(msm_tasha_be_dai_links) +
5839 ARRAY_SIZE(msm_wcn_be_dai_links) +
5840 ARRAY_SIZE(ext_disp_be_dai_link) +
5841 ARRAY_SIZE(msm_mi2s_be_dai_links) +
5842 ARRAY_SIZE(msm_auxpcm_be_dai_links)];
5843
5844static struct snd_soc_dai_link msm_tavil_dai_links[
5845 ARRAY_SIZE(msm_common_dai_links) +
5846 ARRAY_SIZE(msm_tavil_fe_dai_links) +
5847 ARRAY_SIZE(msm_common_be_dai_links) +
5848 ARRAY_SIZE(msm_tavil_be_dai_links) +
5849 ARRAY_SIZE(msm_wcn_be_dai_links) +
5850 ARRAY_SIZE(ext_disp_be_dai_link) +
5851 ARRAY_SIZE(msm_mi2s_be_dai_links) +
5852 ARRAY_SIZE(msm_auxpcm_be_dai_links)];
5853
5854static int msm_snd_card_late_probe(struct snd_soc_card *card)
5855{
5856 const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX;
5857 struct snd_soc_pcm_runtime *rtd;
5858 int ret = 0;
5859 void *mbhc_calibration;
5860
5861 rtd = snd_soc_get_pcm_runtime(card, be_dl_name);
5862 if (!rtd) {
5863 dev_err(card->dev,
5864 "%s: snd_soc_get_pcm_runtime for %s failed!\n",
5865 __func__, be_dl_name);
5866 ret = -EINVAL;
5867 goto err_pcm_runtime;
5868 }
5869
5870 mbhc_calibration = def_tasha_mbhc_cal();
5871 if (!mbhc_calibration) {
5872 ret = -ENOMEM;
5873 goto err_mbhc_cal;
5874 }
5875 wcd_mbhc_cfg.calibration = mbhc_calibration;
5876 ret = tasha_mbhc_hs_detect(rtd->codec, &wcd_mbhc_cfg);
5877 if (ret) {
5878 dev_err(card->dev, "%s: mbhc hs detect failed, err:%d\n",
5879 __func__, ret);
5880 goto err_hs_detect;
5881 }
5882 return 0;
5883
5884err_hs_detect:
5885 kfree(mbhc_calibration);
5886err_mbhc_cal:
5887err_pcm_runtime:
5888 return ret;
5889}
5890
5891static int msm_snd_card_tavil_late_probe(struct snd_soc_card *card)
5892{
5893 const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX;
5894 struct snd_soc_pcm_runtime *rtd;
5895 int ret = 0;
5896 void *mbhc_calibration;
5897
5898 rtd = snd_soc_get_pcm_runtime(card, be_dl_name);
5899 if (!rtd) {
5900 dev_err(card->dev,
5901 "%s: snd_soc_get_pcm_runtime for %s failed!\n",
5902 __func__, be_dl_name);
5903 ret = -EINVAL;
5904 goto err_pcm_runtime;
5905 }
5906
5907 mbhc_calibration = def_tavil_mbhc_cal();
5908 if (!mbhc_calibration) {
5909 ret = -ENOMEM;
5910 goto err_mbhc_cal;
5911 }
5912 wcd_mbhc_cfg.calibration = mbhc_calibration;
5913 ret = tavil_mbhc_hs_detect(rtd->codec, &wcd_mbhc_cfg);
5914 if (ret) {
5915 dev_err(card->dev, "%s: mbhc hs detect failed, err:%d\n",
5916 __func__, ret);
5917 goto err_hs_detect;
5918 }
5919 return 0;
5920
5921err_hs_detect:
5922 kfree(mbhc_calibration);
5923err_mbhc_cal:
5924err_pcm_runtime:
5925 return ret;
5926}
5927
5928struct snd_soc_card snd_soc_card_tasha_msm = {
5929 .name = "msm8998-tasha-snd-card",
5930 .late_probe = msm_snd_card_late_probe,
5931};
5932
5933struct snd_soc_card snd_soc_card_tavil_msm = {
5934 .name = "msm8998-tavil-snd-card",
5935 .late_probe = msm_snd_card_tavil_late_probe,
5936};
5937
5938static int msm_populate_dai_link_component_of_node(
5939 struct snd_soc_card *card)
5940{
5941 int i, index, ret = 0;
5942 struct device *cdev = card->dev;
5943 struct snd_soc_dai_link *dai_link = card->dai_link;
5944 struct device_node *np;
5945
5946 if (!cdev) {
5947 pr_err("%s: Sound card device memory NULL\n", __func__);
5948 return -ENODEV;
5949 }
5950
5951 for (i = 0; i < card->num_links; i++) {
5952 if (dai_link[i].platform_of_node && dai_link[i].cpu_of_node)
5953 continue;
5954
5955 /* populate platform_of_node for snd card dai links */
5956 if (dai_link[i].platform_name &&
5957 !dai_link[i].platform_of_node) {
5958 index = of_property_match_string(cdev->of_node,
5959 "asoc-platform-names",
5960 dai_link[i].platform_name);
5961 if (index < 0) {
5962 pr_err("%s: No match found for platform name: %s\n",
5963 __func__, dai_link[i].platform_name);
5964 ret = index;
5965 goto err;
5966 }
5967 np = of_parse_phandle(cdev->of_node, "asoc-platform",
5968 index);
5969 if (!np) {
5970 pr_err("%s: retrieving phandle for platform %s, index %d failed\n",
5971 __func__, dai_link[i].platform_name,
5972 index);
5973 ret = -ENODEV;
5974 goto err;
5975 }
5976 dai_link[i].platform_of_node = np;
5977 dai_link[i].platform_name = NULL;
5978 }
5979
5980 /* populate cpu_of_node for snd card dai links */
5981 if (dai_link[i].cpu_dai_name && !dai_link[i].cpu_of_node) {
5982 index = of_property_match_string(cdev->of_node,
5983 "asoc-cpu-names",
5984 dai_link[i].cpu_dai_name);
5985 if (index >= 0) {
5986 np = of_parse_phandle(cdev->of_node, "asoc-cpu",
5987 index);
5988 if (!np) {
5989 pr_err("%s: retrieving phandle for cpu dai %s failed\n",
5990 __func__,
5991 dai_link[i].cpu_dai_name);
5992 ret = -ENODEV;
5993 goto err;
5994 }
5995 dai_link[i].cpu_of_node = np;
5996 dai_link[i].cpu_dai_name = NULL;
5997 }
5998 }
5999
6000 /* populate codec_of_node for snd card dai links */
6001 if (dai_link[i].codec_name && !dai_link[i].codec_of_node) {
6002 index = of_property_match_string(cdev->of_node,
6003 "asoc-codec-names",
6004 dai_link[i].codec_name);
6005 if (index < 0)
6006 continue;
6007 np = of_parse_phandle(cdev->of_node, "asoc-codec",
6008 index);
6009 if (!np) {
6010 pr_err("%s: retrieving phandle for codec %s failed\n",
6011 __func__, dai_link[i].codec_name);
6012 ret = -ENODEV;
6013 goto err;
6014 }
6015 dai_link[i].codec_of_node = np;
6016 dai_link[i].codec_name = NULL;
6017 }
6018 }
6019
6020err:
6021 return ret;
6022}
6023
6024static int msm_prepare_us_euro(struct snd_soc_card *card)
6025{
6026 struct msm_asoc_mach_data *pdata =
6027 snd_soc_card_get_drvdata(card);
6028 int ret = 0;
6029
6030 if (pdata->us_euro_gpio >= 0) {
6031 dev_dbg(card->dev, "%s: us_euro gpio request %d", __func__,
6032 pdata->us_euro_gpio);
6033 ret = gpio_request(pdata->us_euro_gpio, "TASHA_CODEC_US_EURO");
6034 if (ret) {
6035 dev_err(card->dev,
6036 "%s: Failed to request codec US/EURO gpio %d error %d\n",
6037 __func__, pdata->us_euro_gpio, ret);
6038 }
6039 }
6040
6041 return ret;
6042}
6043
6044static int msm_audrx_stub_init(struct snd_soc_pcm_runtime *rtd)
6045{
6046 int ret = 0;
6047 struct snd_soc_codec *codec = rtd->codec;
6048 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
6049
6050 ret = snd_soc_add_codec_controls(codec, msm_snd_controls,
6051 ARRAY_SIZE(msm_snd_controls));
6052 if (ret < 0) {
6053 dev_err(codec->dev, "%s: add_codec_controls failed, err%d\n",
6054 __func__, ret);
6055 return ret;
6056 }
6057
6058 snd_soc_dapm_new_controls(dapm, msm_dapm_widgets,
6059 ARRAY_SIZE(msm_dapm_widgets));
6060
6061 return 0;
6062}
6063
6064static int msm_snd_stub_hw_params(struct snd_pcm_substream *substream,
6065 struct snd_pcm_hw_params *params)
6066{
6067 struct snd_soc_pcm_runtime *rtd = substream->private_data;
6068 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
6069
6070 int ret = 0;
6071 unsigned int rx_ch[] = {144, 145, 146, 147, 148, 149, 150,
6072 151, 152, 153, 154, 155, 156};
6073 unsigned int tx_ch[] = {128, 129, 130, 131, 132, 133,
6074 134, 135, 136, 137, 138, 139,
6075 140, 141, 142, 143};
6076
6077 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
6078 ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0,
6079 slim_rx_cfg[0].channels,
6080 rx_ch);
6081 if (ret < 0)
6082 pr_err("%s: RX failed to set cpu chan map error %d\n",
6083 __func__, ret);
6084 } else {
6085 ret = snd_soc_dai_set_channel_map(cpu_dai,
6086 slim_tx_cfg[0].channels,
6087 tx_ch, 0, 0);
6088 if (ret < 0)
6089 pr_err("%s: TX failed to set cpu chan map error %d\n",
6090 __func__, ret);
6091 }
6092
6093 return ret;
6094}
6095
6096static struct snd_soc_ops msm_stub_be_ops = {
6097 .hw_params = msm_snd_stub_hw_params,
6098};
6099
6100static struct snd_soc_dai_link msm_stub_fe_dai_links[] = {
6101
6102 /* FrontEnd DAI Links */
6103 {
6104 .name = "MSMSTUB Media1",
6105 .stream_name = "MultiMedia1",
6106 .cpu_dai_name = "MultiMedia1",
6107 .platform_name = "msm-pcm-dsp.0",
6108 .dynamic = 1,
6109 .async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
6110 .dpcm_playback = 1,
6111 .dpcm_capture = 1,
6112 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
6113 SND_SOC_DPCM_TRIGGER_POST},
6114 .codec_dai_name = "snd-soc-dummy-dai",
6115 .codec_name = "snd-soc-dummy",
6116 .ignore_suspend = 1,
6117 /* this dainlink has playback support */
6118 .ignore_pmdown_time = 1,
6119 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA1
6120 },
6121};
6122
6123static struct snd_soc_dai_link msm_stub_be_dai_links[] = {
6124
6125 /* Backend DAI Links */
6126 {
6127 .name = LPASS_BE_SLIMBUS_0_RX,
6128 .stream_name = "Slimbus Playback",
6129 .cpu_dai_name = "msm-dai-q6-dev.16384",
6130 .platform_name = "msm-pcm-routing",
6131 .codec_name = "msm-stub-codec.1",
6132 .codec_dai_name = "msm-stub-rx",
6133 .no_pcm = 1,
6134 .dpcm_playback = 1,
6135 .be_id = MSM_BACKEND_DAI_SLIMBUS_0_RX,
6136 .init = &msm_audrx_stub_init,
6137 .be_hw_params_fixup = msm_be_hw_params_fixup,
6138 .ignore_pmdown_time = 1, /* dai link has playback support */
6139 .ignore_suspend = 1,
6140 .ops = &msm_stub_be_ops,
6141 },
6142 {
6143 .name = LPASS_BE_SLIMBUS_0_TX,
6144 .stream_name = "Slimbus Capture",
6145 .cpu_dai_name = "msm-dai-q6-dev.16385",
6146 .platform_name = "msm-pcm-routing",
6147 .codec_name = "msm-stub-codec.1",
6148 .codec_dai_name = "msm-stub-tx",
6149 .no_pcm = 1,
6150 .dpcm_capture = 1,
6151 .be_id = MSM_BACKEND_DAI_SLIMBUS_0_TX,
6152 .be_hw_params_fixup = msm_be_hw_params_fixup,
6153 .ignore_suspend = 1,
6154 .ops = &msm_stub_be_ops,
6155 },
6156};
6157
6158static struct snd_soc_dai_link msm_stub_dai_links[
6159 ARRAY_SIZE(msm_stub_fe_dai_links) +
6160 ARRAY_SIZE(msm_stub_be_dai_links)];
6161
6162struct snd_soc_card snd_soc_card_stub_msm = {
6163 .name = "msm8998-stub-snd-card",
6164};
6165
6166static const struct of_device_id msm8998_asoc_machine_of_match[] = {
6167 { .compatible = "qcom,msm8998-asoc-snd-tasha",
6168 .data = "tasha_codec"},
6169 { .compatible = "qcom,msm8998-asoc-snd-tavil",
6170 .data = "tavil_codec"},
6171 { .compatible = "qcom,msm8998-asoc-snd-stub",
6172 .data = "stub_codec"},
6173 {},
6174};
6175
6176static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev)
6177{
6178 struct snd_soc_card *card = NULL;
6179 struct snd_soc_dai_link *dailink;
6180 int len_1, len_2, len_3;
6181 int total_links;
6182 const struct of_device_id *match;
6183
6184 match = of_match_node(msm8998_asoc_machine_of_match, dev->of_node);
6185 if (!match) {
6186 dev_err(dev, "%s: No DT match found for sound card\n",
6187 __func__);
6188 return NULL;
6189 }
6190
6191 if (!strcmp(match->data, "tasha_codec")) {
6192 card = &snd_soc_card_tasha_msm;
6193 len_1 = ARRAY_SIZE(msm_common_dai_links);
6194 len_2 = len_1 + ARRAY_SIZE(msm_tasha_fe_dai_links);
6195 len_3 = len_2 + ARRAY_SIZE(msm_common_be_dai_links);
6196 total_links = len_3 + ARRAY_SIZE(msm_tasha_be_dai_links);
6197 memcpy(msm_tasha_dai_links,
6198 msm_common_dai_links,
6199 sizeof(msm_common_dai_links));
6200 memcpy(msm_tasha_dai_links + len_1,
6201 msm_tasha_fe_dai_links,
6202 sizeof(msm_tasha_fe_dai_links));
6203 memcpy(msm_tasha_dai_links + len_2,
6204 msm_common_be_dai_links,
6205 sizeof(msm_common_be_dai_links));
6206 memcpy(msm_tasha_dai_links + len_3,
6207 msm_tasha_be_dai_links,
6208 sizeof(msm_tasha_be_dai_links));
6209
6210 if (of_property_read_bool(dev->of_node, "qcom,wcn-btfm")) {
6211 dev_dbg(dev, "%s(): WCN BTFM support present\n",
6212 __func__);
6213 memcpy(msm_tasha_dai_links + total_links,
6214 msm_wcn_be_dai_links,
6215 sizeof(msm_wcn_be_dai_links));
6216 total_links += ARRAY_SIZE(msm_wcn_be_dai_links);
6217 }
6218
6219 if (of_property_read_bool(dev->of_node,
6220 "qcom,ext-disp-audio-rx")) {
6221 dev_dbg(dev, "%s(): External display audio support present\n",
6222 __func__);
6223 memcpy(msm_tasha_dai_links + total_links,
6224 ext_disp_be_dai_link,
6225 sizeof(ext_disp_be_dai_link));
6226 total_links += ARRAY_SIZE(ext_disp_be_dai_link);
6227 }
6228 if (of_property_read_bool(dev->of_node,
6229 "qcom,mi2s-audio-intf")) {
6230 memcpy(msm_tasha_dai_links + total_links,
6231 msm_mi2s_be_dai_links,
6232 sizeof(msm_mi2s_be_dai_links));
6233 total_links += ARRAY_SIZE(msm_mi2s_be_dai_links);
6234 }
6235 if (of_property_read_bool(dev->of_node,
6236 "qcom,auxpcm-audio-intf")) {
6237 memcpy(msm_tasha_dai_links + total_links,
6238 msm_auxpcm_be_dai_links,
6239 sizeof(msm_auxpcm_be_dai_links));
6240 total_links += ARRAY_SIZE(msm_auxpcm_be_dai_links);
6241 }
6242 dailink = msm_tasha_dai_links;
6243 } else if (!strcmp(match->data, "tavil_codec")) {
6244 card = &snd_soc_card_tavil_msm;
6245 len_1 = ARRAY_SIZE(msm_common_dai_links);
6246 len_2 = len_1 + ARRAY_SIZE(msm_tavil_fe_dai_links);
6247 len_3 = len_2 + ARRAY_SIZE(msm_common_be_dai_links);
6248 total_links = len_3 + ARRAY_SIZE(msm_tavil_be_dai_links);
6249 memcpy(msm_tavil_dai_links,
6250 msm_common_dai_links,
6251 sizeof(msm_common_dai_links));
6252 memcpy(msm_tavil_dai_links + len_1,
6253 msm_tavil_fe_dai_links,
6254 sizeof(msm_tavil_fe_dai_links));
6255 memcpy(msm_tavil_dai_links + len_2,
6256 msm_common_be_dai_links,
6257 sizeof(msm_common_be_dai_links));
6258 memcpy(msm_tavil_dai_links + len_3,
6259 msm_tavil_be_dai_links,
6260 sizeof(msm_tavil_be_dai_links));
6261
6262 if (of_property_read_bool(dev->of_node, "qcom,wcn-btfm")) {
6263 dev_dbg(dev, "%s(): WCN BTFM support present\n",
6264 __func__);
6265 memcpy(msm_tavil_dai_links + total_links,
6266 msm_wcn_be_dai_links,
6267 sizeof(msm_wcn_be_dai_links));
6268 total_links += ARRAY_SIZE(msm_wcn_be_dai_links);
6269 }
6270
6271 if (of_property_read_bool(dev->of_node,
6272 "qcom,ext-disp-audio-rx")) {
6273 dev_dbg(dev, "%s(): ext disp audio support present\n",
6274 __func__);
6275 memcpy(msm_tavil_dai_links + total_links,
6276 ext_disp_be_dai_link,
6277 sizeof(ext_disp_be_dai_link));
6278 total_links += ARRAY_SIZE(ext_disp_be_dai_link);
6279 }
6280 if (of_property_read_bool(dev->of_node,
6281 "qcom,mi2s-audio-intf")) {
6282 memcpy(msm_tavil_dai_links + total_links,
6283 msm_mi2s_be_dai_links,
6284 sizeof(msm_mi2s_be_dai_links));
6285 total_links += ARRAY_SIZE(msm_mi2s_be_dai_links);
6286 }
6287 if (of_property_read_bool(dev->of_node,
6288 "qcom,auxpcm-audio-intf")) {
6289 memcpy(msm_tavil_dai_links + total_links,
6290 msm_auxpcm_be_dai_links,
6291 sizeof(msm_auxpcm_be_dai_links));
6292 total_links += ARRAY_SIZE(msm_auxpcm_be_dai_links);
6293 }
6294 dailink = msm_tavil_dai_links;
6295 } else if (!strcmp(match->data, "stub_codec")) {
6296 card = &snd_soc_card_stub_msm;
6297 len_1 = ARRAY_SIZE(msm_stub_fe_dai_links);
6298 len_2 = len_1 + ARRAY_SIZE(msm_stub_be_dai_links);
6299
6300 memcpy(msm_stub_dai_links,
6301 msm_stub_fe_dai_links,
6302 sizeof(msm_stub_fe_dai_links));
6303 memcpy(msm_stub_dai_links + len_1,
6304 msm_stub_be_dai_links,
6305 sizeof(msm_stub_be_dai_links));
6306
6307 dailink = msm_stub_dai_links;
6308 total_links = len_2;
6309 }
6310
6311 if (card) {
6312 card->dai_link = dailink;
6313 card->num_links = total_links;
6314 }
6315
6316 return card;
6317}
6318
6319static int msm_wsa881x_init(struct snd_soc_component *component)
6320{
6321 u8 spkleft_ports[WSA881X_MAX_SWR_PORTS] = {100, 101, 102, 106};
6322 u8 spkright_ports[WSA881X_MAX_SWR_PORTS] = {103, 104, 105, 107};
6323 unsigned int ch_rate[WSA881X_MAX_SWR_PORTS] = {2400, 600, 300, 1200};
6324 unsigned int ch_mask[WSA881X_MAX_SWR_PORTS] = {0x1, 0xF, 0x3, 0x3};
6325 struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
6326 struct msm_asoc_mach_data *pdata;
6327 struct snd_soc_dapm_context *dapm;
6328 int ret = 0;
6329
6330 if (!codec) {
6331 pr_err("%s codec is NULL\n", __func__);
6332 return -EINVAL;
6333 }
6334
6335 dapm = snd_soc_codec_get_dapm(codec);
6336
6337 if (!strcmp(component->name_prefix, "SpkrLeft")) {
6338 dev_dbg(codec->dev, "%s: setting left ch map to codec %s\n",
6339 __func__, codec->component.name);
6340 wsa881x_set_channel_map(codec, &spkleft_ports[0],
6341 WSA881X_MAX_SWR_PORTS, &ch_mask[0],
6342 &ch_rate[0]);
6343 if (dapm->component) {
6344 snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft IN");
6345 snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR");
6346 }
6347 } else if (!strcmp(component->name_prefix, "SpkrRight")) {
6348 dev_dbg(codec->dev, "%s: setting right ch map to codec %s\n",
6349 __func__, codec->component.name);
6350 wsa881x_set_channel_map(codec, &spkright_ports[0],
6351 WSA881X_MAX_SWR_PORTS, &ch_mask[0],
6352 &ch_rate[0]);
6353 if (dapm->component) {
6354 snd_soc_dapm_ignore_suspend(dapm, "SpkrRight IN");
6355 snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR");
6356 }
6357 } else {
6358 dev_err(codec->dev, "%s: wrong codec name %s\n", __func__,
6359 codec->component.name);
6360 ret = -EINVAL;
6361 goto err_codec;
6362 }
6363 pdata = snd_soc_card_get_drvdata(component->card);
6364 if (pdata && pdata->codec_root)
6365 wsa881x_codec_info_create_codec_entry(pdata->codec_root,
6366 codec);
6367
6368err_codec:
6369 return ret;
6370}
6371
6372static int msm_init_wsa_dev(struct platform_device *pdev,
6373 struct snd_soc_card *card)
6374{
6375 struct device_node *wsa_of_node;
6376 u32 wsa_max_devs;
6377 u32 wsa_dev_cnt;
6378 int i;
6379 struct msm_wsa881x_dev_info *wsa881x_dev_info;
6380 const char *wsa_auxdev_name_prefix[1];
6381 char *dev_name_str = NULL;
6382 int found = 0;
6383 int ret = 0;
6384
6385 /* Get maximum WSA device count for this platform */
6386 ret = of_property_read_u32(pdev->dev.of_node,
6387 "qcom,wsa-max-devs", &wsa_max_devs);
6388 if (ret) {
6389 dev_dbg(&pdev->dev,
6390 "%s: wsa-max-devs property missing in DT %s, ret = %d\n",
6391 __func__, pdev->dev.of_node->full_name, ret);
6392 goto err_dt;
6393 }
6394 if (wsa_max_devs == 0) {
6395 dev_warn(&pdev->dev,
6396 "%s: Max WSA devices is 0 for this target?\n",
6397 __func__);
6398 goto err_dt;
6399 }
6400
6401 /* Get count of WSA device phandles for this platform */
6402 wsa_dev_cnt = of_count_phandle_with_args(pdev->dev.of_node,
6403 "qcom,wsa-devs", NULL);
6404 if (wsa_dev_cnt == -ENOENT) {
6405 dev_warn(&pdev->dev, "%s: No wsa device defined in DT.\n",
6406 __func__);
6407 goto err_dt;
6408 } else if (wsa_dev_cnt <= 0) {
6409 dev_err(&pdev->dev,
6410 "%s: Error reading wsa device from DT. wsa_dev_cnt = %d\n",
6411 __func__, wsa_dev_cnt);
6412 ret = -EINVAL;
6413 goto err_dt;
6414 }
6415
6416 /*
6417 * Expect total phandles count to be NOT less than maximum possible
6418 * WSA count. However, if it is less, then assign same value to
6419 * max count as well.
6420 */
6421 if (wsa_dev_cnt < wsa_max_devs) {
6422 dev_dbg(&pdev->dev,
6423 "%s: wsa_max_devs = %d cannot exceed wsa_dev_cnt = %d\n",
6424 __func__, wsa_max_devs, wsa_dev_cnt);
6425 wsa_max_devs = wsa_dev_cnt;
6426 }
6427
6428 /* Make sure prefix string passed for each WSA device */
6429 ret = of_property_count_strings(pdev->dev.of_node,
6430 "qcom,wsa-aux-dev-prefix");
6431 if (ret != wsa_dev_cnt) {
6432 dev_err(&pdev->dev,
6433 "%s: expecting %d wsa prefix. Defined only %d in DT\n",
6434 __func__, wsa_dev_cnt, ret);
6435 ret = -EINVAL;
6436 goto err_dt;
6437 }
6438
6439 /*
6440 * Alloc mem to store phandle and index info of WSA device, if already
6441 * registered with ALSA core
6442 */
6443 wsa881x_dev_info = devm_kcalloc(&pdev->dev, wsa_max_devs,
6444 sizeof(struct msm_wsa881x_dev_info),
6445 GFP_KERNEL);
6446 if (!wsa881x_dev_info) {
6447 ret = -ENOMEM;
6448 goto err_mem;
6449 }
6450
6451 /*
6452 * search and check whether all WSA devices are already
6453 * registered with ALSA core or not. If found a node, store
6454 * the node and the index in a local array of struct for later
6455 * use.
6456 */
6457 for (i = 0; i < wsa_dev_cnt; i++) {
6458 wsa_of_node = of_parse_phandle(pdev->dev.of_node,
6459 "qcom,wsa-devs", i);
6460 if (unlikely(!wsa_of_node)) {
6461 /* we should not be here */
6462 dev_err(&pdev->dev,
6463 "%s: wsa dev node is not present\n",
6464 __func__);
6465 ret = -EINVAL;
6466 goto err_dev_node;
6467 }
6468 if (soc_find_component(wsa_of_node, NULL)) {
6469 /* WSA device registered with ALSA core */
6470 wsa881x_dev_info[found].of_node = wsa_of_node;
6471 wsa881x_dev_info[found].index = i;
6472 found++;
6473 if (found == wsa_max_devs)
6474 break;
6475 }
6476 }
6477
6478 if (found < wsa_max_devs) {
6479 dev_dbg(&pdev->dev,
6480 "%s: failed to find %d components. Found only %d\n",
6481 __func__, wsa_max_devs, found);
6482 return -EPROBE_DEFER;
6483 }
6484 dev_info(&pdev->dev,
6485 "%s: found %d wsa881x devices registered with ALSA core\n",
6486 __func__, found);
6487
6488 card->num_aux_devs = wsa_max_devs;
6489 card->num_configs = wsa_max_devs;
6490
6491 /* Alloc array of AUX devs struct */
6492 msm_aux_dev = devm_kcalloc(&pdev->dev, card->num_aux_devs,
6493 sizeof(struct snd_soc_aux_dev),
6494 GFP_KERNEL);
6495 if (!msm_aux_dev) {
6496 ret = -ENOMEM;
6497 goto err_auxdev_mem;
6498 }
6499
6500 /* Alloc array of codec conf struct */
6501 msm_codec_conf = devm_kcalloc(&pdev->dev, card->num_aux_devs,
6502 sizeof(struct snd_soc_codec_conf),
6503 GFP_KERNEL);
6504 if (!msm_codec_conf) {
6505 ret = -ENOMEM;
6506 goto err_codec_conf;
6507 }
6508
6509 for (i = 0; i < card->num_aux_devs; i++) {
6510 dev_name_str = devm_kzalloc(&pdev->dev, DEV_NAME_STR_LEN,
6511 GFP_KERNEL);
6512 if (!dev_name_str) {
6513 ret = -ENOMEM;
6514 goto err_dev_str;
6515 }
6516
6517 ret = of_property_read_string_index(pdev->dev.of_node,
6518 "qcom,wsa-aux-dev-prefix",
6519 wsa881x_dev_info[i].index,
6520 wsa_auxdev_name_prefix);
6521 if (ret) {
6522 dev_err(&pdev->dev,
6523 "%s: failed to read wsa aux dev prefix, ret = %d\n",
6524 __func__, ret);
6525 ret = -EINVAL;
6526 goto err_dt_prop;
6527 }
6528
6529 snprintf(dev_name_str, strlen("wsa881x.%d"), "wsa881x.%d", i);
6530 msm_aux_dev[i].name = dev_name_str;
6531 msm_aux_dev[i].codec_name = NULL;
6532 msm_aux_dev[i].codec_of_node =
6533 wsa881x_dev_info[i].of_node;
6534 msm_aux_dev[i].init = msm_wsa881x_init;
6535 msm_codec_conf[i].dev_name = NULL;
6536 msm_codec_conf[i].name_prefix = wsa_auxdev_name_prefix[0];
6537 msm_codec_conf[i].of_node =
6538 wsa881x_dev_info[i].of_node;
6539 }
6540 card->codec_conf = msm_codec_conf;
6541 card->aux_dev = msm_aux_dev;
6542
6543 return 0;
6544
6545err_dt_prop:
6546 devm_kfree(&pdev->dev, dev_name_str);
6547err_dev_str:
6548 devm_kfree(&pdev->dev, msm_codec_conf);
6549err_codec_conf:
6550 devm_kfree(&pdev->dev, msm_aux_dev);
6551err_auxdev_mem:
6552err_dev_node:
6553 devm_kfree(&pdev->dev, wsa881x_dev_info);
6554err_mem:
6555err_dt:
6556 return ret;
6557}
6558
6559static void i2s_auxpcm_init(struct platform_device *pdev)
6560{
6561 struct resource *muxsel;
6562 int count;
6563 u32 mi2s_master_slave[MI2S_MAX];
6564 int ret;
6565 char *str[PCM_I2S_SEL_MAX] = {
6566 "lpaif_pri_mode_muxsel",
6567 "lpaif_sec_mode_muxsel",
6568 "lpaif_tert_mode_muxsel",
6569 "lpaif_quat_mode_muxsel"
6570 };
6571
6572 for (count = 0; count < MI2S_MAX; count++) {
6573 mutex_init(&mi2s_intf_conf[count].lock);
6574 mi2s_intf_conf[count].ref_cnt = 0;
6575 }
6576
6577 for (count = 0; count < AUX_PCM_MAX; count++) {
6578 mutex_init(&auxpcm_intf_conf[count].lock);
6579 auxpcm_intf_conf[count].ref_cnt = 0;
6580 }
6581
6582 for (count = 0; count < PCM_I2S_SEL_MAX; count++) {
6583 mutex_init(&mi2s_auxpcm_conf[count].lock);
6584 mi2s_auxpcm_conf[count].pcm_i2s_sel_vt_addr = NULL;
6585 }
6586
6587 for (count = 0; count < PCM_I2S_SEL_MAX; count++) {
6588 muxsel = platform_get_resource_byname(pdev, IORESOURCE_MEM,
6589 str[count]);
6590 if (muxsel) {
6591 mi2s_auxpcm_conf[count].pcm_i2s_sel_vt_addr
6592 = ioremap(muxsel->start, resource_size(muxsel));
6593 }
6594 }
6595
6596 ret = of_property_read_u32_array(pdev->dev.of_node,
6597 "qcom,msm-mi2s-master",
6598 mi2s_master_slave, MI2S_MAX);
6599 if (ret) {
6600 dev_dbg(&pdev->dev, "%s: no qcom,msm-mi2s-master in DT node\n",
6601 __func__);
6602 } else {
6603 for (count = 0; count < MI2S_MAX; count++) {
6604 mi2s_intf_conf[count].msm_is_mi2s_master =
6605 mi2s_master_slave[count];
6606 }
6607 }
6608}
6609
6610static void i2s_auxpcm_deinit(void)
6611{
6612 int count;
6613
6614 for (count = 0; count < PCM_I2S_SEL_MAX; count++)
6615 if (mi2s_auxpcm_conf[count].pcm_i2s_sel_vt_addr !=
6616 NULL)
6617 iounmap(
6618 mi2s_auxpcm_conf[count].pcm_i2s_sel_vt_addr);
6619}
6620
6621static int msm_asoc_machine_probe(struct platform_device *pdev)
6622{
6623 struct snd_soc_card *card;
6624 struct msm_asoc_mach_data *pdata;
6625 const char *mbhc_audio_jack_type = NULL;
6626 char *mclk_freq_prop_name;
6627 const struct of_device_id *match;
6628 int ret;
6629
6630 if (!pdev->dev.of_node) {
6631 dev_err(&pdev->dev, "No platform supplied from device tree\n");
6632 return -EINVAL;
6633 }
6634
6635 pdata = devm_kzalloc(&pdev->dev,
6636 sizeof(struct msm_asoc_mach_data), GFP_KERNEL);
6637 if (!pdata)
6638 return -ENOMEM;
6639
6640 card = populate_snd_card_dailinks(&pdev->dev);
6641 if (!card) {
6642 dev_err(&pdev->dev, "%s: Card uninitialized\n", __func__);
6643 ret = -EINVAL;
6644 goto err;
6645 }
6646 card->dev = &pdev->dev;
6647 platform_set_drvdata(pdev, card);
6648 snd_soc_card_set_drvdata(card, pdata);
6649
6650 ret = snd_soc_of_parse_card_name(card, "qcom,model");
6651 if (ret) {
6652 dev_err(&pdev->dev, "parse card name failed, err:%d\n",
6653 ret);
6654 goto err;
6655 }
6656
6657 ret = snd_soc_of_parse_audio_routing(card, "qcom,audio-routing");
6658 if (ret) {
6659 dev_err(&pdev->dev, "parse audio routing failed, err:%d\n",
6660 ret);
6661 goto err;
6662 }
6663
6664 match = of_match_node(msm8998_asoc_machine_of_match,
6665 pdev->dev.of_node);
6666 if (!match) {
6667 dev_err(&pdev->dev, "%s: no matched codec is found.\n",
6668 __func__);
6669 goto err;
6670 }
6671
6672 if (!strcmp(match->data, "tasha_codec"))
6673 mclk_freq_prop_name = "qcom,tasha-mclk-clk-freq";
6674 else
6675 mclk_freq_prop_name = "qcom,tavil-mclk-clk-freq";
6676
6677 ret = of_property_read_u32(pdev->dev.of_node,
6678 mclk_freq_prop_name, &pdata->mclk_freq);
6679 if (ret) {
6680 dev_err(&pdev->dev,
6681 "Looking up %s property in node %s failed, err%d\n",
6682 mclk_freq_prop_name,
6683 pdev->dev.of_node->full_name, ret);
6684 goto err;
6685 }
6686
6687 if (pdata->mclk_freq != CODEC_EXT_CLK_RATE) {
6688 dev_err(&pdev->dev, "unsupported mclk freq %u\n",
6689 pdata->mclk_freq);
6690 ret = -EINVAL;
6691 goto err;
6692 }
6693
6694 ret = msm_populate_dai_link_component_of_node(card);
6695 if (ret) {
6696 ret = -EPROBE_DEFER;
6697 goto err;
6698 }
6699 ret = msm_init_wsa_dev(pdev, card);
6700 if (ret)
6701 goto err;
6702
6703 ret = devm_snd_soc_register_card(&pdev->dev, card);
6704 if (ret == -EPROBE_DEFER) {
6705 if (codec_reg_done)
6706 ret = -EINVAL;
6707 goto err;
6708 } else if (ret) {
6709 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
6710 ret);
6711 goto err;
6712 }
6713 dev_info(&pdev->dev, "Sound card %s registered\n", card->name);
6714 spdev = pdev;
6715
6716 ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
6717 if (ret) {
6718 dev_dbg(&pdev->dev, "%s: failed to add child nodes, ret=%d\n",
6719 __func__, ret);
6720 } else {
6721 pdata->hph_en1_gpio_p = of_parse_phandle(pdev->dev.of_node,
6722 "qcom,hph-en1-gpio", 0);
6723 if (!pdata->hph_en1_gpio_p) {
6724 dev_dbg(&pdev->dev, "property %s not detected in node %s",
6725 "qcom,hph-en1-gpio",
6726 pdev->dev.of_node->full_name);
6727 }
6728
6729 pdata->hph_en0_gpio_p = of_parse_phandle(pdev->dev.of_node,
6730 "qcom,hph-en0-gpio", 0);
6731 if (!pdata->hph_en0_gpio_p) {
6732 dev_dbg(&pdev->dev, "property %s not detected in node %s",
6733 "qcom,hph-en0-gpio",
6734 pdev->dev.of_node->full_name);
6735 }
6736 }
6737
6738 ret = of_property_read_string(pdev->dev.of_node,
6739 "qcom,mbhc-audio-jack-type", &mbhc_audio_jack_type);
6740 if (ret) {
6741 dev_dbg(&pdev->dev, "Looking up %s property in node %s failed",
6742 "qcom,mbhc-audio-jack-type",
6743 pdev->dev.of_node->full_name);
6744 dev_dbg(&pdev->dev, "Jack type properties set to default");
6745 } else {
6746 if (!strcmp(mbhc_audio_jack_type, "4-pole-jack"))
6747 dev_dbg(&pdev->dev, "This hardware has 4 pole jack");
6748 else if (!strcmp(mbhc_audio_jack_type, "5-pole-jack"))
6749 dev_dbg(&pdev->dev, "This hardware has 5 pole jack");
6750 else if (!strcmp(mbhc_audio_jack_type, "6-pole-jack"))
6751 dev_dbg(&pdev->dev, "This hardware has 6 pole jack");
6752 else
6753 dev_dbg(&pdev->dev, "Unknown value, set to default");
6754 }
6755 /*
6756 * Parse US-Euro gpio info from DT. Report no error if us-euro
6757 * entry is not found in DT file as some targets do not support
6758 * US-Euro detection
6759 */
6760 pdata->us_euro_gpio = of_get_named_gpio(pdev->dev.of_node,
6761 "qcom,us-euro-gpios", 0);
6762 if (!gpio_is_valid(pdata->us_euro_gpio))
6763 pdata->us_euro_gpio_p = of_parse_phandle(pdev->dev.of_node,
6764 "qcom,us-euro-gpios", 0);
6765 if (!gpio_is_valid(pdata->us_euro_gpio) && (!pdata->us_euro_gpio_p)) {
6766 dev_dbg(&pdev->dev, "property %s not detected in node %s",
6767 "qcom,us-euro-gpios", pdev->dev.of_node->full_name);
6768 } else {
6769 dev_dbg(&pdev->dev, "%s detected",
6770 "qcom,us-euro-gpios");
6771 wcd_mbhc_cfg.swap_gnd_mic = msm_swap_gnd_mic;
6772 }
6773
6774 ret = msm_prepare_us_euro(card);
6775 if (ret)
6776 dev_dbg(&pdev->dev, "msm_prepare_us_euro failed (%d)\n",
6777 ret);
6778
6779 i2s_auxpcm_init(pdev);
6780
6781 is_initial_boot = true;
6782 ret = audio_notifier_register("msm8998", AUDIO_NOTIFIER_ADSP_DOMAIN,
6783 &service_nb);
6784 if (ret < 0)
6785 pr_err("%s: Audio notifier register failed ret = %d\n",
6786 __func__, ret);
6787
6788 return 0;
6789err:
6790 if (pdata->us_euro_gpio > 0) {
6791 dev_dbg(&pdev->dev, "%s free us_euro gpio %d\n",
6792 __func__, pdata->us_euro_gpio);
6793 gpio_free(pdata->us_euro_gpio);
6794 pdata->us_euro_gpio = 0;
6795 }
6796 devm_kfree(&pdev->dev, pdata);
6797 return ret;
6798}
6799
6800static int msm_asoc_machine_remove(struct platform_device *pdev)
6801{
6802 struct snd_soc_card *card = platform_get_drvdata(pdev);
6803 struct msm_asoc_mach_data *pdata =
6804 snd_soc_card_get_drvdata(card);
6805
6806 gpio_free(pdata->us_euro_gpio);
6807 i2s_auxpcm_deinit();
6808
6809 snd_soc_unregister_card(card);
6810 return 0;
6811}
6812
6813static struct platform_driver msm8998_asoc_machine_driver = {
6814 .driver = {
6815 .name = DRV_NAME,
6816 .owner = THIS_MODULE,
6817 .pm = &snd_soc_pm_ops,
6818 .of_match_table = msm8998_asoc_machine_of_match,
6819 },
6820 .probe = msm_asoc_machine_probe,
6821 .remove = msm_asoc_machine_remove,
6822};
6823module_platform_driver(msm8998_asoc_machine_driver);
6824
6825MODULE_DESCRIPTION("ALSA SoC msm");
6826MODULE_LICENSE("GPL v2");
6827MODULE_ALIAS("platform:" DRV_NAME);
6828MODULE_DEVICE_TABLE(of, msm8998_asoc_machine_of_match);