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