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