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