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