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