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