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