blob: acfafe4c58fb36d2aaaecc2ccc888d94fd83340a [file] [log] [blame]
Aditya Bavanarid61b84d2018-01-03 13:24:06 +05301/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/delay.h>
14#include <linux/of_gpio.h>
15#include <linux/platform_device.h>
16#include <linux/module.h>
17#include <sound/soc.h>
18#include <sound/pcm.h>
19#include <sound/pcm_params.h>
Laxminath Kasam605b42f2017-08-01 22:02:15 +053020#include <dsp/q6core.h>
21#include <dsp/audio_notifier.h>
22#include "msm-pcm-routing-v2.h"
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053023#include "sdm660-common.h"
24#include "sdm660-external.h"
Dhanalakshmi Siddani7ce33bb2018-11-28 22:01:53 +053025#include "codecs/msm-cdc-pinctrl.h"
Laxminath Kasam605b42f2017-08-01 22:02:15 +053026#include "codecs/wcd9335.h"
27#include "codecs/wcd934x/wcd934x.h"
28#include "codecs/wcd934x/wcd934x-mbhc.h"
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053029
30#define SDM660_SPK_ON 1
31#define SDM660_SPK_OFF 0
32
33#define WCD9XXX_MBHC_DEF_BUTTONS 8
34#define WCD9XXX_MBHC_DEF_RLOADS 5
35#define CODEC_EXT_CLK_RATE 9600000
36#define ADSP_STATE_READY_TIMEOUT_MS 3000
37
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053038#define WSA8810_NAME_1 "wsa881x.20170211"
39#define WSA8810_NAME_2 "wsa881x.20170212"
40
Dhanalakshmi Siddani7ce33bb2018-11-28 22:01:53 +053041#define MSM_HIFI_ON 1
42
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053043static int msm_ext_spk_control = 1;
44static struct wcd_mbhc_config *wcd_mbhc_cfg_ptr;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053045
46struct msm_asoc_wcd93xx_codec {
47 void* (*get_afe_config_fn)(struct snd_soc_codec *codec,
48 enum afe_config_type config_type);
49 void (*mbhc_hs_detect_exit)(struct snd_soc_codec *codec);
50};
51
52static struct msm_asoc_wcd93xx_codec msm_codec_fn;
53static struct platform_device *spdev;
Dhanalakshmi Siddani7ce33bb2018-11-28 22:01:53 +053054static int msm_hifi_control;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053055
56static bool is_initial_boot;
57
58static void *def_ext_mbhc_cal(void);
59
60enum {
61 SLIM_RX_0 = 0,
62 SLIM_RX_1,
63 SLIM_RX_2,
64 SLIM_RX_3,
65 SLIM_RX_4,
66 SLIM_RX_5,
67 SLIM_RX_6,
68 SLIM_RX_7,
69 SLIM_RX_MAX,
70};
71
72enum {
73 SLIM_TX_0 = 0,
74 SLIM_TX_1,
75 SLIM_TX_2,
76 SLIM_TX_3,
77 SLIM_TX_4,
78 SLIM_TX_5,
79 SLIM_TX_6,
80 SLIM_TX_7,
81 SLIM_TX_8,
82 SLIM_TX_MAX,
83};
84
85struct dev_config {
86 u32 sample_rate;
87 u32 bit_format;
88 u32 channels;
89};
90
91/* Default configuration of slimbus channels */
92static struct dev_config slim_rx_cfg[] = {
93 [SLIM_RX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
94 [SLIM_RX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
95 [SLIM_RX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
96 [SLIM_RX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
97 [SLIM_RX_4] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
98 [SLIM_RX_5] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
99 [SLIM_RX_6] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
100 [SLIM_RX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
101};
102
103static struct dev_config slim_tx_cfg[] = {
104 [SLIM_TX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
105 [SLIM_TX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
106 [SLIM_TX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
107 [SLIM_TX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
108 [SLIM_TX_4] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
109 [SLIM_TX_5] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
110 [SLIM_TX_6] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
111 [SLIM_TX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
112 [SLIM_TX_8] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
113};
114
115static int msm_vi_feed_tx_ch = 2;
Dhanalakshmi Siddani7ce33bb2018-11-28 22:01:53 +0530116static const char *const slim_rx_ch_text[] = {"One", "Two", "Three", "Four",
117 "Five", "Six", "Seven",
118 "Eight"};
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530119static const char *const slim_tx_ch_text[] = {"One", "Two", "Three", "Four",
120 "Five", "Six", "Seven",
121 "Eight"};
122static const char *const vi_feed_ch_text[] = {"One", "Two"};
123static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE",
124 "S32_LE"};
125static char const *slim_sample_rate_text[] = {"KHZ_8", "KHZ_16",
126 "KHZ_32", "KHZ_44P1", "KHZ_48",
127 "KHZ_88P2", "KHZ_96", "KHZ_176P4",
128 "KHZ_192", "KHZ_352P8", "KHZ_384"};
129static const char *const spk_function_text[] = {"Off", "On"};
Preetam Singh Ranawat66f1f212017-12-05 15:30:24 +0530130static char const *bt_sample_rate_text[] = {"KHZ_8", "KHZ_16",
131 "KHZ_44P1", "KHZ_48",
132 "KHZ_88P2", "KHZ_96"};
Preetam Singh Ranawatd79190a2018-06-25 15:59:23 +0530133static char const *bt_sample_rate_rx_text[] = {"KHZ_8", "KHZ_16",
134 "KHZ_44P1", "KHZ_48",
135 "KHZ_88P2", "KHZ_96"};
136static char const *bt_sample_rate_tx_text[] = {"KHZ_8", "KHZ_16",
137 "KHZ_44P1", "KHZ_48",
138 "KHZ_88P2", "KHZ_96"};
Dhanalakshmi Siddani7ce33bb2018-11-28 22:01:53 +0530139static const char *const hifi_text[] = {"Off", "On"};
140
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530141static SOC_ENUM_SINGLE_EXT_DECL(spk_func_en, spk_function_text);
142static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_chs, slim_rx_ch_text);
143static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_chs, slim_rx_ch_text);
144static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_chs, slim_tx_ch_text);
145static SOC_ENUM_SINGLE_EXT_DECL(slim_1_tx_chs, slim_tx_ch_text);
146static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_chs, slim_rx_ch_text);
147static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_chs, slim_rx_ch_text);
148static SOC_ENUM_SINGLE_EXT_DECL(vi_feed_tx_chs, vi_feed_ch_text);
149static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_format, bit_format_text);
150static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_format, bit_format_text);
151static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_format, bit_format_text);
152static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_format, bit_format_text);
153static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_sample_rate, slim_sample_rate_text);
154static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_sample_rate, slim_sample_rate_text);
155static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_sample_rate, slim_sample_rate_text);
156static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_sample_rate, slim_sample_rate_text);
157static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_sample_rate, slim_sample_rate_text);
158static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate, bt_sample_rate_text);
Preetam Singh Ranawatd79190a2018-06-25 15:59:23 +0530159static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate_rx, bt_sample_rate_rx_text);
160static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate_tx, bt_sample_rate_tx_text);
Dhanalakshmi Siddani7ce33bb2018-11-28 22:01:53 +0530161static SOC_ENUM_SINGLE_EXT_DECL(hifi_function, hifi_text);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530162
163static int slim_get_sample_rate_val(int sample_rate)
164{
165 int sample_rate_val = 0;
166
167 switch (sample_rate) {
168 case SAMPLING_RATE_8KHZ:
169 sample_rate_val = 0;
170 break;
171 case SAMPLING_RATE_16KHZ:
172 sample_rate_val = 1;
173 break;
174 case SAMPLING_RATE_32KHZ:
175 sample_rate_val = 2;
176 break;
177 case SAMPLING_RATE_44P1KHZ:
178 sample_rate_val = 3;
179 break;
180 case SAMPLING_RATE_48KHZ:
181 sample_rate_val = 4;
182 break;
183 case SAMPLING_RATE_88P2KHZ:
184 sample_rate_val = 5;
185 break;
186 case SAMPLING_RATE_96KHZ:
187 sample_rate_val = 6;
188 break;
189 case SAMPLING_RATE_176P4KHZ:
190 sample_rate_val = 7;
191 break;
192 case SAMPLING_RATE_192KHZ:
193 sample_rate_val = 8;
194 break;
195 case SAMPLING_RATE_352P8KHZ:
196 sample_rate_val = 9;
197 break;
198 case SAMPLING_RATE_384KHZ:
199 sample_rate_val = 10;
200 break;
201 default:
202 sample_rate_val = 4;
203 break;
204 }
205 return sample_rate_val;
206}
207
208static int slim_get_sample_rate(int value)
209{
210 int sample_rate = 0;
211
212 switch (value) {
213 case 0:
214 sample_rate = SAMPLING_RATE_8KHZ;
215 break;
216 case 1:
217 sample_rate = SAMPLING_RATE_16KHZ;
218 break;
219 case 2:
220 sample_rate = SAMPLING_RATE_32KHZ;
221 break;
222 case 3:
223 sample_rate = SAMPLING_RATE_44P1KHZ;
224 break;
225 case 4:
226 sample_rate = SAMPLING_RATE_48KHZ;
227 break;
228 case 5:
229 sample_rate = SAMPLING_RATE_88P2KHZ;
230 break;
231 case 6:
232 sample_rate = SAMPLING_RATE_96KHZ;
233 break;
234 case 7:
235 sample_rate = SAMPLING_RATE_176P4KHZ;
236 break;
237 case 8:
238 sample_rate = SAMPLING_RATE_192KHZ;
239 break;
240 case 9:
241 sample_rate = SAMPLING_RATE_352P8KHZ;
242 break;
243 case 10:
244 sample_rate = SAMPLING_RATE_384KHZ;
245 break;
246 default:
247 sample_rate = SAMPLING_RATE_48KHZ;
248 break;
249 }
250 return sample_rate;
251}
252
253static int slim_get_bit_format_val(int bit_format)
254{
255 int val = 0;
256
257 switch (bit_format) {
258 case SNDRV_PCM_FORMAT_S32_LE:
259 val = 3;
260 break;
261 case SNDRV_PCM_FORMAT_S24_3LE:
262 val = 2;
263 break;
264 case SNDRV_PCM_FORMAT_S24_LE:
265 val = 1;
266 break;
267 case SNDRV_PCM_FORMAT_S16_LE:
268 default:
269 val = 0;
270 break;
271 }
272 return val;
273}
274
275static int slim_get_bit_format(int val)
276{
277 int bit_fmt = SNDRV_PCM_FORMAT_S16_LE;
278
279 switch (val) {
280 case 0:
281 bit_fmt = SNDRV_PCM_FORMAT_S16_LE;
282 break;
283 case 1:
284 bit_fmt = SNDRV_PCM_FORMAT_S24_LE;
285 break;
286 case 2:
287 bit_fmt = SNDRV_PCM_FORMAT_S24_3LE;
288 break;
289 case 3:
290 bit_fmt = SNDRV_PCM_FORMAT_S32_LE;
291 break;
292 default:
293 bit_fmt = SNDRV_PCM_FORMAT_S16_LE;
294 break;
295 }
296 return bit_fmt;
297}
298
299static int slim_get_port_idx(struct snd_kcontrol *kcontrol)
300{
301 int port_id = 0;
302
303 if (strnstr(kcontrol->id.name, "SLIM_0_RX", sizeof("SLIM_0_RX")))
304 port_id = SLIM_RX_0;
305 else if (strnstr(kcontrol->id.name, "SLIM_2_RX", sizeof("SLIM_2_RX")))
306 port_id = SLIM_RX_2;
307 else if (strnstr(kcontrol->id.name, "SLIM_5_RX", sizeof("SLIM_5_RX")))
308 port_id = SLIM_RX_5;
309 else if (strnstr(kcontrol->id.name, "SLIM_6_RX", sizeof("SLIM_6_RX")))
310 port_id = SLIM_RX_6;
311 else if (strnstr(kcontrol->id.name, "SLIM_0_TX", sizeof("SLIM_0_TX")))
312 port_id = SLIM_TX_0;
313 else if (strnstr(kcontrol->id.name, "SLIM_1_TX", sizeof("SLIM_1_TX")))
314 port_id = SLIM_TX_1;
315 else {
316 pr_err("%s: unsupported channel: %s",
317 __func__, kcontrol->id.name);
318 return -EINVAL;
319 }
320
321 return port_id;
322}
323
324static int msm_bt_sample_rate_get(struct snd_kcontrol *kcontrol,
325 struct snd_ctl_elem_value *ucontrol)
326{
327 /*
328 * Slimbus_7_Rx/Tx sample rate values should always be in sync (same)
329 * when used for BT_SCO use case. Return either Rx or Tx sample rate
330 * value.
331 */
332 switch (slim_rx_cfg[SLIM_RX_7].sample_rate) {
Preetam Singh Ranawat66f1f212017-12-05 15:30:24 +0530333 case SAMPLING_RATE_96KHZ:
334 ucontrol->value.integer.value[0] = 5;
335 break;
336 case SAMPLING_RATE_88P2KHZ:
337 ucontrol->value.integer.value[0] = 4;
338 break;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530339 case SAMPLING_RATE_48KHZ:
Preetam Singh Ranawat66f1f212017-12-05 15:30:24 +0530340 ucontrol->value.integer.value[0] = 3;
341 break;
342 case SAMPLING_RATE_44P1KHZ:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530343 ucontrol->value.integer.value[0] = 2;
344 break;
345 case SAMPLING_RATE_16KHZ:
346 ucontrol->value.integer.value[0] = 1;
347 break;
348 case SAMPLING_RATE_8KHZ:
349 default:
350 ucontrol->value.integer.value[0] = 0;
351 break;
352 }
353 pr_debug("%s: sample rate = %d", __func__,
354 slim_rx_cfg[SLIM_RX_7].sample_rate);
355
356 return 0;
357}
358
359static int msm_bt_sample_rate_put(struct snd_kcontrol *kcontrol,
360 struct snd_ctl_elem_value *ucontrol)
361{
362 switch (ucontrol->value.integer.value[0]) {
363 case 1:
364 slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_16KHZ;
365 slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_16KHZ;
366 break;
367 case 2:
Preetam Singh Ranawat66f1f212017-12-05 15:30:24 +0530368 slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_44P1KHZ;
369 slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_44P1KHZ;
370 break;
371 case 3:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530372 slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_48KHZ;
373 slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_48KHZ;
374 break;
Preetam Singh Ranawat66f1f212017-12-05 15:30:24 +0530375 case 4:
376 slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_88P2KHZ;
377 slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_88P2KHZ;
378 break;
379 case 5:
380 slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_96KHZ;
381 slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_96KHZ;
382 break;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530383 case 0:
384 default:
385 slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_8KHZ;
386 slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_8KHZ;
387 break;
388 }
389 pr_debug("%s: sample rates: slim7_rx = %d, slim7_tx = %d, value = %d\n",
390 __func__,
391 slim_rx_cfg[SLIM_RX_7].sample_rate,
392 slim_tx_cfg[SLIM_TX_7].sample_rate,
393 ucontrol->value.enumerated.item[0]);
394
395 return 0;
396}
397
Preetam Singh Ranawatd79190a2018-06-25 15:59:23 +0530398static int msm_bt_sample_rate_rx_get(struct snd_kcontrol *kcontrol,
399 struct snd_ctl_elem_value *ucontrol)
400{
401 switch (slim_rx_cfg[SLIM_RX_7].sample_rate) {
402 case SAMPLING_RATE_96KHZ:
403 ucontrol->value.integer.value[0] = 5;
404 break;
405 case SAMPLING_RATE_88P2KHZ:
406 ucontrol->value.integer.value[0] = 4;
407 break;
408 case SAMPLING_RATE_48KHZ:
409 ucontrol->value.integer.value[0] = 3;
410 break;
411 case SAMPLING_RATE_44P1KHZ:
412 ucontrol->value.integer.value[0] = 2;
413 break;
414 case SAMPLING_RATE_16KHZ:
415 ucontrol->value.integer.value[0] = 1;
416 break;
417 case SAMPLING_RATE_8KHZ:
418 default:
419 ucontrol->value.integer.value[0] = 0;
420 break;
421 }
422 pr_debug("%s: sample rate = %d", __func__,
423 slim_rx_cfg[SLIM_RX_7].sample_rate);
424
425 return 0;
426}
427
428static int msm_bt_sample_rate_rx_put(struct snd_kcontrol *kcontrol,
429 struct snd_ctl_elem_value *ucontrol)
430{
431 switch (ucontrol->value.integer.value[0]) {
432 case 1:
433 slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_16KHZ;
434 break;
435 case 2:
436 slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_44P1KHZ;
437 break;
438 case 3:
439 slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_48KHZ;
440 break;
441 case 4:
442 slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_88P2KHZ;
443 break;
444 case 5:
445 slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_96KHZ;
446 break;
447 case 0:
448 default:
449 slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_8KHZ;
450 break;
451 }
452 pr_debug("%s: sample rates: slim7_rx = %d, value = %d\n",
453 __func__,
454 slim_rx_cfg[SLIM_RX_7].sample_rate,
455 ucontrol->value.enumerated.item[0]);
456
457 return 0;
458}
459
460static int msm_bt_sample_rate_tx_get(struct snd_kcontrol *kcontrol,
461 struct snd_ctl_elem_value *ucontrol)
462{
463 switch (slim_tx_cfg[SLIM_TX_7].sample_rate) {
464 case SAMPLING_RATE_96KHZ:
465 ucontrol->value.integer.value[0] = 5;
466 break;
467 case SAMPLING_RATE_88P2KHZ:
468 ucontrol->value.integer.value[0] = 4;
469 break;
470 case SAMPLING_RATE_48KHZ:
471 ucontrol->value.integer.value[0] = 3;
472 break;
473 case SAMPLING_RATE_44P1KHZ:
474 ucontrol->value.integer.value[0] = 2;
475 break;
476 case SAMPLING_RATE_16KHZ:
477 ucontrol->value.integer.value[0] = 1;
478 break;
479 case SAMPLING_RATE_8KHZ:
480 default:
481 ucontrol->value.integer.value[0] = 0;
482 break;
483 }
484 pr_debug("%s: sample rate = %d", __func__,
485 slim_tx_cfg[SLIM_TX_7].sample_rate);
486
487 return 0;
488}
489
490static int msm_bt_sample_rate_tx_put(struct snd_kcontrol *kcontrol,
491 struct snd_ctl_elem_value *ucontrol)
492{
493 switch (ucontrol->value.integer.value[0]) {
494 case 1:
495 slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_16KHZ;
496 break;
497 case 2:
498 slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_44P1KHZ;
499 break;
500 case 3:
501 slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_48KHZ;
502 break;
503 case 4:
504 slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_88P2KHZ;
505 break;
506 case 5:
507 slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_96KHZ;
508 break;
509 case 0:
510 default:
511 slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_8KHZ;
512 break;
513 }
514 pr_debug("%s: sample rates: slim7_tx = %d, value = %d\n",
515 __func__,
516 slim_tx_cfg[SLIM_TX_7].sample_rate,
517 ucontrol->value.enumerated.item[0]);
518
519 return 0;
520}
521
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530522static int slim_rx_sample_rate_get(struct snd_kcontrol *kcontrol,
523 struct snd_ctl_elem_value *ucontrol)
524{
525 int ch_num = slim_get_port_idx(kcontrol);
526
527 if (ch_num < 0)
528 return ch_num;
529
530 ucontrol->value.enumerated.item[0] =
531 slim_get_sample_rate_val(slim_rx_cfg[ch_num].sample_rate);
532
533 pr_debug("%s: slim[%d]_rx_sample_rate = %d, item = %d\n", __func__,
534 ch_num, slim_rx_cfg[ch_num].sample_rate,
535 ucontrol->value.enumerated.item[0]);
536
537 return 0;
538}
539
540static int slim_rx_sample_rate_put(struct snd_kcontrol *kcontrol,
541 struct snd_ctl_elem_value *ucontrol)
542{
543 int ch_num = slim_get_port_idx(kcontrol);
544
545 if (ch_num < 0)
546 return ch_num;
547
548 slim_rx_cfg[ch_num].sample_rate =
549 slim_get_sample_rate(ucontrol->value.enumerated.item[0]);
550
551 pr_debug("%s: slim[%d]_rx_sample_rate = %d, item = %d\n", __func__,
552 ch_num, slim_rx_cfg[ch_num].sample_rate,
553 ucontrol->value.enumerated.item[0]);
554
555 return 0;
556}
557
558static int slim_tx_sample_rate_get(struct snd_kcontrol *kcontrol,
559 struct snd_ctl_elem_value *ucontrol)
560{
561 int ch_num = slim_get_port_idx(kcontrol);
562
563 if (ch_num < 0)
564 return ch_num;
565
566 ucontrol->value.enumerated.item[0] =
567 slim_get_sample_rate_val(slim_tx_cfg[ch_num].sample_rate);
568
569 pr_debug("%s: slim[%d]_tx_sample_rate = %d, item = %d\n", __func__,
570 ch_num, slim_tx_cfg[ch_num].sample_rate,
571 ucontrol->value.enumerated.item[0]);
572
573 return 0;
574}
575
576static int slim_tx_sample_rate_put(struct snd_kcontrol *kcontrol,
577 struct snd_ctl_elem_value *ucontrol)
578{
579 int sample_rate = 0;
580 int ch_num = slim_get_port_idx(kcontrol);
581
582 if (ch_num < 0)
583 return ch_num;
584
585 sample_rate = slim_get_sample_rate(ucontrol->value.enumerated.item[0]);
586 if (sample_rate == SAMPLING_RATE_44P1KHZ) {
587 pr_err("%s: Unsupported sample rate %d: for Tx path\n",
588 __func__, sample_rate);
589 return -EINVAL;
590 }
591 slim_tx_cfg[ch_num].sample_rate = sample_rate;
592
593 pr_debug("%s: slim[%d]_tx_sample_rate = %d, value = %d\n", __func__,
594 ch_num, slim_tx_cfg[ch_num].sample_rate,
595 ucontrol->value.enumerated.item[0]);
596
597 return 0;
598}
599
600static int slim_rx_bit_format_get(struct snd_kcontrol *kcontrol,
601 struct snd_ctl_elem_value *ucontrol)
602{
603 int ch_num = slim_get_port_idx(kcontrol);
604
605 if (ch_num < 0)
606 return ch_num;
607
608 ucontrol->value.enumerated.item[0] =
609 slim_get_bit_format_val(slim_rx_cfg[ch_num].bit_format);
610
611 pr_debug("%s: slim[%d]_rx_bit_format = %d, ucontrol value = %d\n",
612 __func__, ch_num, slim_rx_cfg[ch_num].bit_format,
613 ucontrol->value.enumerated.item[0]);
614
615 return 0;
616}
617
618static int slim_rx_bit_format_put(struct snd_kcontrol *kcontrol,
619 struct snd_ctl_elem_value *ucontrol)
620{
621 int ch_num = slim_get_port_idx(kcontrol);
622
623 if (ch_num < 0)
624 return ch_num;
625
626 slim_rx_cfg[ch_num].bit_format =
627 slim_get_bit_format(ucontrol->value.enumerated.item[0]);
628
629 pr_debug("%s: slim[%d]_rx_bit_format = %d, ucontrol value = %d\n",
630 __func__, ch_num, slim_rx_cfg[ch_num].bit_format,
631 ucontrol->value.enumerated.item[0]);
632
633 return 0;
634}
635
636static int slim_tx_bit_format_get(struct snd_kcontrol *kcontrol,
637 struct snd_ctl_elem_value *ucontrol)
638{
639 int ch_num = slim_get_port_idx(kcontrol);
640
641 if (ch_num < 0)
642 return ch_num;
643
644 ucontrol->value.enumerated.item[0] =
645 slim_get_bit_format_val(slim_tx_cfg[ch_num].bit_format);
646
647 pr_debug("%s: slim[%d]_tx_bit_format = %d, ucontrol value = %d\n",
648 __func__, ch_num, slim_tx_cfg[ch_num].bit_format,
649 ucontrol->value.enumerated.item[0]);
650
651 return 0;
652}
653
654static int slim_tx_bit_format_put(struct snd_kcontrol *kcontrol,
655 struct snd_ctl_elem_value *ucontrol)
656{
657 int ch_num = slim_get_port_idx(kcontrol);
658
659 if (ch_num < 0)
660 return ch_num;
661
662 slim_tx_cfg[ch_num].bit_format =
663 slim_get_bit_format(ucontrol->value.enumerated.item[0]);
664
665 pr_debug("%s: slim[%d]_tx_bit_format = %d, ucontrol value = %d\n",
666 __func__, ch_num, slim_tx_cfg[ch_num].bit_format,
667 ucontrol->value.enumerated.item[0]);
668
669 return 0;
670}
671
672static int msm_slim_rx_ch_get(struct snd_kcontrol *kcontrol,
673 struct snd_ctl_elem_value *ucontrol)
674{
675 int ch_num = slim_get_port_idx(kcontrol);
676
677 if (ch_num < 0)
678 return ch_num;
679
680 pr_debug("%s: msm_slim_[%d]_rx_ch = %d\n", __func__,
681 ch_num, slim_rx_cfg[ch_num].channels);
682 ucontrol->value.enumerated.item[0] = slim_rx_cfg[ch_num].channels - 1;
683
684 return 0;
685}
686
687static int msm_slim_rx_ch_put(struct snd_kcontrol *kcontrol,
688 struct snd_ctl_elem_value *ucontrol)
689{
690 int ch_num = slim_get_port_idx(kcontrol);
691
692 if (ch_num < 0)
693 return ch_num;
694
695 slim_rx_cfg[ch_num].channels = ucontrol->value.enumerated.item[0] + 1;
696 pr_debug("%s: msm_slim_[%d]_rx_ch = %d\n", __func__,
697 ch_num, slim_rx_cfg[ch_num].channels);
698
699 return 1;
700}
701
702static int msm_slim_tx_ch_get(struct snd_kcontrol *kcontrol,
703 struct snd_ctl_elem_value *ucontrol)
704{
705 int ch_num = slim_get_port_idx(kcontrol);
706
707 if (ch_num < 0)
708 return ch_num;
709
710 pr_debug("%s: msm_slim_[%d]_tx_ch = %d\n", __func__,
711 ch_num, slim_tx_cfg[ch_num].channels);
712 ucontrol->value.enumerated.item[0] = slim_tx_cfg[ch_num].channels - 1;
713
714 return 0;
715}
716
717static int msm_slim_tx_ch_put(struct snd_kcontrol *kcontrol,
718 struct snd_ctl_elem_value *ucontrol)
719{
720 int ch_num = slim_get_port_idx(kcontrol);
721
722 if (ch_num < 0)
723 return ch_num;
724
725 slim_tx_cfg[ch_num].channels = ucontrol->value.enumerated.item[0] + 1;
726 pr_debug("%s: msm_slim_[%d]_tx_ch = %d\n", __func__,
727 ch_num, slim_tx_cfg[ch_num].channels);
728
729 return 1;
730}
731
732static int msm_vi_feed_tx_ch_get(struct snd_kcontrol *kcontrol,
733 struct snd_ctl_elem_value *ucontrol)
734{
735 ucontrol->value.integer.value[0] = msm_vi_feed_tx_ch - 1;
736 pr_debug("%s: msm_vi_feed_tx_ch = %ld\n", __func__,
737 ucontrol->value.integer.value[0]);
738 return 0;
739}
740
741static int msm_vi_feed_tx_ch_put(struct snd_kcontrol *kcontrol,
742 struct snd_ctl_elem_value *ucontrol)
743{
744 msm_vi_feed_tx_ch = ucontrol->value.integer.value[0] + 1;
745
746 pr_debug("%s: msm_vi_feed_tx_ch = %d\n", __func__, msm_vi_feed_tx_ch);
747 return 1;
748}
749
Dhanalakshmi Siddani7ce33bb2018-11-28 22:01:53 +0530750static int msm_hifi_ctrl(struct snd_soc_codec *codec)
751{
752 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
753 struct snd_soc_card *card = codec->component.card;
754 struct msm_asoc_mach_data *pdata =
755 snd_soc_card_get_drvdata(card);
756
757 pr_debug("%s: msm_hifi_control = %d\n", __func__,
758 msm_hifi_control);
759
760 if (!pdata || !pdata->hph_en1_gpio_p) {
761 pr_err("%s: hph_en1_gpio is invalid\n", __func__);
762 return -EINVAL;
763 }
764 if (msm_hifi_control == MSM_HIFI_ON) {
765 msm_cdc_pinctrl_select_active_state(pdata->hph_en1_gpio_p);
766 /* 5msec delay needed as per HW requirement */
767 usleep_range(5000, 5010);
768 } else {
769 msm_cdc_pinctrl_select_sleep_state(pdata->hph_en1_gpio_p);
770 }
771 snd_soc_dapm_sync(dapm);
772
773 return 0;
774}
775
776static int msm_hifi_get(struct snd_kcontrol *kcontrol,
777 struct snd_ctl_elem_value *ucontrol)
778{
779 pr_debug("%s: msm_hifi_control = %d\n",
780 __func__, msm_hifi_control);
781 ucontrol->value.integer.value[0] = msm_hifi_control;
782
783 return 0;
784}
785
786static int msm_hifi_put(struct snd_kcontrol *kcontrol,
787 struct snd_ctl_elem_value *ucontrol)
788{
789 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
790
791 pr_debug("%s() ucontrol->value.integer.value[0] = %ld\n",
792 __func__, ucontrol->value.integer.value[0]);
793
794 msm_hifi_control = ucontrol->value.integer.value[0];
795 msm_hifi_ctrl(codec);
796
797 return 0;
798}
799
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530800static void *def_ext_mbhc_cal(void)
801{
Laxminath Kasam38070be2017-08-17 18:21:59 +0530802 void *wcd_mbhc_cal;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530803 struct wcd_mbhc_btn_detect_cfg *btn_cfg;
804 u16 *btn_high;
805
Laxminath Kasam38070be2017-08-17 18:21:59 +0530806 wcd_mbhc_cal = kzalloc(WCD_MBHC_CAL_SIZE(WCD_MBHC_DEF_BUTTONS,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530807 WCD9XXX_MBHC_DEF_RLOADS), GFP_KERNEL);
Laxminath Kasam38070be2017-08-17 18:21:59 +0530808 if (!wcd_mbhc_cal)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530809 return NULL;
810
Laxminath Kasam38070be2017-08-17 18:21:59 +0530811#define S(X, Y) ((WCD_MBHC_CAL_PLUG_TYPE_PTR(wcd_mbhc_cal)->X) = (Y))
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530812 S(v_hs_max, 1600);
813#undef S
Laxminath Kasam38070be2017-08-17 18:21:59 +0530814#define S(X, Y) ((WCD_MBHC_CAL_BTN_DET_PTR(wcd_mbhc_cal)->X) = (Y))
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530815 S(num_btn, WCD_MBHC_DEF_BUTTONS);
816#undef S
817
Laxminath Kasam38070be2017-08-17 18:21:59 +0530818 btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(wcd_mbhc_cal);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530819 btn_high = ((void *)&btn_cfg->_v_btn_low) +
820 (sizeof(btn_cfg->_v_btn_low[0]) * btn_cfg->num_btn);
821
822 btn_high[0] = 75;
823 btn_high[1] = 150;
824 btn_high[2] = 237;
825 btn_high[3] = 500;
826 btn_high[4] = 500;
827 btn_high[5] = 500;
828 btn_high[6] = 500;
829 btn_high[7] = 500;
830
Laxminath Kasam38070be2017-08-17 18:21:59 +0530831 return wcd_mbhc_cal;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530832}
833
834static inline int param_is_mask(int p)
835{
836 return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) &&
837 (p <= SNDRV_PCM_HW_PARAM_LAST_MASK);
838}
839
840static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p, int n)
841{
842 return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]);
843}
844
845
846static void msm_ext_control(struct snd_soc_codec *codec)
847{
848 struct snd_soc_dapm_context *dapm =
849 snd_soc_codec_get_dapm(codec);
850
851 pr_debug("%s: msm_ext_spk_control = %d", __func__, msm_ext_spk_control);
852 if (msm_ext_spk_control == SDM660_SPK_ON) {
853 snd_soc_dapm_enable_pin(dapm, "Lineout_1 amp");
854 snd_soc_dapm_enable_pin(dapm, "Lineout_3 amp");
855 } else {
856 snd_soc_dapm_disable_pin(dapm, "Lineout_1 amp");
857 snd_soc_dapm_disable_pin(dapm, "Lineout_3 amp");
858 }
859 snd_soc_dapm_sync(dapm);
860}
861
862static int msm_ext_get_spk(struct snd_kcontrol *kcontrol,
863 struct snd_ctl_elem_value *ucontrol)
864{
865 pr_debug("%s: msm_ext_spk_control = %d\n",
866 __func__, msm_ext_spk_control);
867 ucontrol->value.integer.value[0] = msm_ext_spk_control;
868 return 0;
869}
870
871static int msm_ext_set_spk(struct snd_kcontrol *kcontrol,
872 struct snd_ctl_elem_value *ucontrol)
873{
874 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
875
876 pr_debug("%s()\n", __func__);
877 if (msm_ext_spk_control == ucontrol->value.integer.value[0])
878 return 0;
879
880 msm_ext_spk_control = ucontrol->value.integer.value[0];
881 msm_ext_control(codec);
882 return 1;
883}
884
885
886int msm_ext_enable_codec_mclk(struct snd_soc_codec *codec, int enable,
887 bool dapm)
888{
889 int ret;
890
891 pr_debug("%s: enable = %d\n", __func__, enable);
892
893 if (!strcmp(dev_name(codec->dev), "tasha_codec"))
894 ret = tasha_cdc_mclk_enable(codec, enable, dapm);
895 else if (!strcmp(dev_name(codec->dev), "tavil_codec"))
896 ret = tavil_cdc_mclk_enable(codec, enable);
897 else {
898 dev_err(codec->dev, "%s: unknown codec to enable ext clk\n",
899 __func__);
900 ret = -EINVAL;
901 }
902 return ret;
903}
904
905static const struct snd_kcontrol_new msm_snd_controls[] = {
906 SOC_ENUM_EXT("Speaker Function", spk_func_en, msm_ext_get_spk,
907 msm_ext_set_spk),
908 SOC_ENUM_EXT("SLIM_0_RX Channels", slim_0_rx_chs,
909 msm_slim_rx_ch_get, msm_slim_rx_ch_put),
910 SOC_ENUM_EXT("SLIM_2_RX Channels", slim_2_rx_chs,
911 msm_slim_rx_ch_get, msm_slim_rx_ch_put),
912 SOC_ENUM_EXT("SLIM_0_TX Channels", slim_0_tx_chs,
913 msm_slim_tx_ch_get, msm_slim_tx_ch_put),
914 SOC_ENUM_EXT("SLIM_1_TX Channels", slim_1_tx_chs,
915 msm_slim_tx_ch_get, msm_slim_tx_ch_put),
916 SOC_ENUM_EXT("SLIM_5_RX Channels", slim_5_rx_chs,
917 msm_slim_rx_ch_get, msm_slim_rx_ch_put),
918 SOC_ENUM_EXT("SLIM_6_RX Channels", slim_6_rx_chs,
919 msm_slim_rx_ch_get, msm_slim_rx_ch_put),
920 SOC_ENUM_EXT("VI_FEED_TX Channels", vi_feed_tx_chs,
921 msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put),
922 SOC_ENUM_EXT("SLIM_0_RX Format", slim_0_rx_format,
923 slim_rx_bit_format_get, slim_rx_bit_format_put),
924 SOC_ENUM_EXT("SLIM_5_RX Format", slim_5_rx_format,
925 slim_rx_bit_format_get, slim_rx_bit_format_put),
926 SOC_ENUM_EXT("SLIM_6_RX Format", slim_6_rx_format,
927 slim_rx_bit_format_get, slim_rx_bit_format_put),
928 SOC_ENUM_EXT("SLIM_0_TX Format", slim_0_tx_format,
929 slim_tx_bit_format_get, slim_tx_bit_format_put),
930 SOC_ENUM_EXT("SLIM_0_RX SampleRate", slim_0_rx_sample_rate,
931 slim_rx_sample_rate_get, slim_rx_sample_rate_put),
932 SOC_ENUM_EXT("SLIM_2_RX SampleRate", slim_2_rx_sample_rate,
933 slim_rx_sample_rate_get, slim_rx_sample_rate_put),
934 SOC_ENUM_EXT("SLIM_0_TX SampleRate", slim_0_tx_sample_rate,
935 slim_tx_sample_rate_get, slim_tx_sample_rate_put),
936 SOC_ENUM_EXT("SLIM_5_RX SampleRate", slim_5_rx_sample_rate,
937 slim_rx_sample_rate_get, slim_rx_sample_rate_put),
938 SOC_ENUM_EXT("SLIM_6_RX SampleRate", slim_6_rx_sample_rate,
939 slim_rx_sample_rate_get, slim_rx_sample_rate_put),
940 SOC_ENUM_EXT("BT SampleRate", bt_sample_rate,
941 msm_bt_sample_rate_get,
942 msm_bt_sample_rate_put),
Preetam Singh Ranawatd79190a2018-06-25 15:59:23 +0530943 SOC_ENUM_EXT("BT SampleRate RX", bt_sample_rate_rx,
944 msm_bt_sample_rate_rx_get,
945 msm_bt_sample_rate_rx_put),
946 SOC_ENUM_EXT("BT SampleRate TX", bt_sample_rate_tx,
947 msm_bt_sample_rate_tx_get,
948 msm_bt_sample_rate_tx_put),
Dhanalakshmi Siddani7ce33bb2018-11-28 22:01:53 +0530949 SOC_ENUM_EXT("HiFi Function", hifi_function, msm_hifi_get,
950 msm_hifi_put),
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530951};
952
Asish Bhattacharya84f7f732017-07-25 16:29:27 +0530953static int msm_slim_get_ch_from_beid(int32_t id)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530954{
955 int ch_id = 0;
956
Asish Bhattacharya84f7f732017-07-25 16:29:27 +0530957 switch (id) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530958 case MSM_BACKEND_DAI_SLIMBUS_0_RX:
959 ch_id = SLIM_RX_0;
960 break;
961 case MSM_BACKEND_DAI_SLIMBUS_1_RX:
962 ch_id = SLIM_RX_1;
963 break;
964 case MSM_BACKEND_DAI_SLIMBUS_2_RX:
965 ch_id = SLIM_RX_2;
966 break;
967 case MSM_BACKEND_DAI_SLIMBUS_3_RX:
968 ch_id = SLIM_RX_3;
969 break;
970 case MSM_BACKEND_DAI_SLIMBUS_4_RX:
971 ch_id = SLIM_RX_4;
972 break;
973 case MSM_BACKEND_DAI_SLIMBUS_6_RX:
974 ch_id = SLIM_RX_6;
975 break;
976 case MSM_BACKEND_DAI_SLIMBUS_0_TX:
977 ch_id = SLIM_TX_0;
978 break;
979 case MSM_BACKEND_DAI_SLIMBUS_3_TX:
980 ch_id = SLIM_TX_3;
981 break;
982 default:
983 ch_id = SLIM_RX_0;
984 break;
985 }
986
987 return ch_id;
988}
989
990static void param_set_mask(struct snd_pcm_hw_params *p, int n, unsigned int bit)
991{
992 if (bit >= SNDRV_MASK_MAX)
993 return;
994 if (param_is_mask(n)) {
995 struct snd_mask *m = param_to_mask(p, n);
996
997 m->bits[0] = 0;
998 m->bits[1] = 0;
999 m->bits[bit >> 5] |= (1 << (bit & 31));
1000 }
1001}
1002
1003/**
1004 * msm_ext_be_hw_params_fixup - updates settings of ALSA BE hw params.
1005 *
1006 * @rtd: runtime dailink instance
1007 * @params: HW params of associated backend dailink.
1008 *
1009 * Returns 0 on success or rc on failure.
1010 */
1011int msm_ext_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
1012 struct snd_pcm_hw_params *params)
1013{
1014 struct snd_soc_dai_link *dai_link = rtd->dai_link;
1015 struct snd_interval *rate = hw_param_interval(params,
1016 SNDRV_PCM_HW_PARAM_RATE);
1017 struct snd_interval *channels = hw_param_interval(params,
1018 SNDRV_PCM_HW_PARAM_CHANNELS);
1019 int rc = 0;
1020 int idx;
1021 void *config = NULL;
1022 struct snd_soc_codec *codec = rtd->codec;
1023
1024 pr_debug("%s: format = %d, rate = %d\n",
1025 __func__, params_format(params), params_rate(params));
1026
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05301027 switch (dai_link->id) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301028 case MSM_BACKEND_DAI_SLIMBUS_0_RX:
1029 case MSM_BACKEND_DAI_SLIMBUS_1_RX:
1030 case MSM_BACKEND_DAI_SLIMBUS_2_RX:
1031 case MSM_BACKEND_DAI_SLIMBUS_3_RX:
1032 case MSM_BACKEND_DAI_SLIMBUS_4_RX:
1033 case MSM_BACKEND_DAI_SLIMBUS_6_RX:
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05301034 idx = msm_slim_get_ch_from_beid(dai_link->id);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301035 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
1036 slim_rx_cfg[idx].bit_format);
1037 rate->min = rate->max = slim_rx_cfg[idx].sample_rate;
1038 channels->min = channels->max = slim_rx_cfg[idx].channels;
1039 break;
1040
1041 case MSM_BACKEND_DAI_SLIMBUS_0_TX:
1042 case MSM_BACKEND_DAI_SLIMBUS_3_TX:
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05301043 idx = msm_slim_get_ch_from_beid(dai_link->id);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301044 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
1045 slim_tx_cfg[idx].bit_format);
1046 rate->min = rate->max = slim_tx_cfg[idx].sample_rate;
1047 channels->min = channels->max = slim_tx_cfg[idx].channels;
1048 break;
1049
1050 case MSM_BACKEND_DAI_SLIMBUS_1_TX:
1051 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
1052 slim_tx_cfg[1].bit_format);
1053 rate->min = rate->max = slim_tx_cfg[1].sample_rate;
1054 channels->min = channels->max = slim_tx_cfg[1].channels;
1055 break;
1056
1057 case MSM_BACKEND_DAI_SLIMBUS_4_TX:
1058 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
1059 SNDRV_PCM_FORMAT_S32_LE);
1060 rate->min = rate->max = SAMPLING_RATE_8KHZ;
1061 channels->min = channels->max = msm_vi_feed_tx_ch;
1062 break;
1063
1064 case MSM_BACKEND_DAI_SLIMBUS_5_RX:
1065 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
1066 slim_rx_cfg[5].bit_format);
1067 rate->min = rate->max = slim_rx_cfg[5].sample_rate;
1068 channels->min = channels->max = slim_rx_cfg[5].channels;
1069 break;
1070
1071 case MSM_BACKEND_DAI_SLIMBUS_5_TX:
1072 rate->min = rate->max = SAMPLING_RATE_16KHZ;
1073 channels->min = channels->max = 1;
1074
1075 config = msm_codec_fn.get_afe_config_fn(codec,
1076 AFE_SLIMBUS_SLAVE_PORT_CONFIG);
1077 if (config) {
1078 rc = afe_set_config(AFE_SLIMBUS_SLAVE_PORT_CONFIG,
1079 config, SLIMBUS_5_TX);
1080 if (rc)
1081 pr_err("%s: Failed to set slimbus slave port config %d\n",
1082 __func__, rc);
1083 }
1084 break;
1085
1086 case MSM_BACKEND_DAI_SLIMBUS_7_RX:
1087 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
1088 slim_rx_cfg[SLIM_RX_7].bit_format);
1089 rate->min = rate->max = slim_rx_cfg[SLIM_RX_7].sample_rate;
1090 channels->min = channels->max =
1091 slim_rx_cfg[SLIM_RX_7].channels;
1092 break;
1093
1094 case MSM_BACKEND_DAI_SLIMBUS_7_TX:
1095 rate->min = rate->max = slim_tx_cfg[SLIM_TX_7].sample_rate;
1096 channels->min = channels->max =
1097 slim_tx_cfg[SLIM_TX_7].channels;
1098 break;
1099
1100 case MSM_BACKEND_DAI_SLIMBUS_8_TX:
1101 rate->min = rate->max = slim_tx_cfg[SLIM_TX_8].sample_rate;
1102 channels->min = channels->max =
1103 slim_tx_cfg[SLIM_TX_8].channels;
1104 break;
1105
1106 default:
1107 rate->min = rate->max = SAMPLING_RATE_48KHZ;
1108 break;
1109 }
1110 return rc;
1111}
1112EXPORT_SYMBOL(msm_ext_be_hw_params_fixup);
1113
1114/**
1115 * msm_snd_hw_params - hw params ops of backend dailink.
1116 *
1117 * @substream: PCM stream of associated backend dailink.
1118 * @params: HW params of associated backend dailink.
1119 *
1120 * Returns 0 on success or ret on failure.
1121 */
1122int msm_snd_hw_params(struct snd_pcm_substream *substream,
1123 struct snd_pcm_hw_params *params)
1124{
1125 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1126 struct snd_soc_dai *codec_dai = rtd->codec_dai;
1127 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1128 struct snd_soc_dai_link *dai_link = rtd->dai_link;
1129
1130 int ret = 0;
1131 u32 rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS];
1132 u32 rx_ch_cnt = 0, tx_ch_cnt = 0;
1133 u32 user_set_tx_ch = 0;
1134 u32 rx_ch_count;
1135
1136 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1137 ret = snd_soc_dai_get_channel_map(codec_dai,
1138 &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch);
1139 if (ret < 0) {
1140 pr_err("%s: failed to get codec chan map, err:%d\n",
1141 __func__, ret);
1142 goto err_ch_map;
1143 }
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05301144 if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_5_RX) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301145 pr_debug("%s: rx_5_ch=%d\n", __func__,
1146 slim_rx_cfg[5].channels);
1147 rx_ch_count = slim_rx_cfg[5].channels;
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05301148 } else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_2_RX) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301149 pr_debug("%s: rx_2_ch=%d\n", __func__,
1150 slim_rx_cfg[2].channels);
1151 rx_ch_count = slim_rx_cfg[2].channels;
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05301152 } else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_6_RX) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301153 pr_debug("%s: rx_6_ch=%d\n", __func__,
1154 slim_rx_cfg[6].channels);
1155 rx_ch_count = slim_rx_cfg[6].channels;
1156 } else {
1157 pr_debug("%s: rx_0_ch=%d\n", __func__,
1158 slim_rx_cfg[0].channels);
1159 rx_ch_count = slim_rx_cfg[0].channels;
1160 }
1161 ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0,
1162 rx_ch_count, rx_ch);
1163 if (ret < 0) {
1164 pr_err("%s: failed to set cpu chan map, err:%d\n",
1165 __func__, ret);
1166 goto err_ch_map;
1167 }
1168 } else {
1169 pr_debug("%s: %s_tx_dai_id_%d_ch=%d\n", __func__,
1170 codec_dai->name, codec_dai->id, user_set_tx_ch);
1171 ret = snd_soc_dai_get_channel_map(codec_dai,
1172 &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch);
1173 if (ret < 0) {
1174 pr_err("%s: failed to get codec chan map\n, err:%d\n",
1175 __func__, ret);
1176 goto err_ch_map;
1177 }
1178 /* For <codec>_tx1 case */
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05301179 if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_0_TX)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301180 user_set_tx_ch = slim_tx_cfg[0].channels;
1181 /* For <codec>_tx3 case */
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05301182 else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_1_TX)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301183 user_set_tx_ch = slim_tx_cfg[1].channels;
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05301184 else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_4_TX)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301185 user_set_tx_ch = msm_vi_feed_tx_ch;
1186 else
1187 user_set_tx_ch = tx_ch_cnt;
1188
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05301189 pr_debug("%s: msm_slim_0_tx_ch(%d) user_set_tx_ch(%d) tx_ch_cnt(%d), id (%d)\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301190 __func__, slim_tx_cfg[0].channels, user_set_tx_ch,
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05301191 tx_ch_cnt, dai_link->id);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301192
1193 ret = snd_soc_dai_set_channel_map(cpu_dai,
1194 user_set_tx_ch, tx_ch, 0, 0);
1195 if (ret < 0)
1196 pr_err("%s: failed to set cpu chan map, err:%d\n",
1197 __func__, ret);
1198 }
1199
1200err_ch_map:
1201 return ret;
1202}
1203EXPORT_SYMBOL(msm_snd_hw_params);
1204
1205/**
1206 * msm_ext_slimbus_2_hw_params - hw params ops of slimbus_2 BE.
1207 *
1208 * @substream: PCM stream of associated backend dailink.
1209 * @params: HW params of associated backend dailink.
1210 *
1211 * Returns 0 on success or ret on failure.
1212 */
1213int msm_ext_slimbus_2_hw_params(struct snd_pcm_substream *substream,
1214 struct snd_pcm_hw_params *params)
1215{
1216 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1217 struct snd_soc_dai *codec_dai = rtd->codec_dai;
1218 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1219 int ret = 0;
1220 unsigned int rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS];
1221 unsigned int rx_ch_cnt = 0, tx_ch_cnt = 0;
1222 unsigned int num_tx_ch = 0;
1223 unsigned int num_rx_ch = 0;
1224
1225 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1226 num_rx_ch = params_channels(params);
1227 pr_debug("%s: %s rx_dai_id = %d num_ch = %d\n", __func__,
1228 codec_dai->name, codec_dai->id, num_rx_ch);
1229 ret = snd_soc_dai_get_channel_map(codec_dai,
1230 &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch);
1231 if (ret < 0) {
1232 pr_err("%s: failed to get codec chan map, err:%d\n",
1233 __func__, ret);
1234 goto end;
1235 }
1236 ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0,
1237 num_rx_ch, rx_ch);
1238 if (ret < 0) {
1239 pr_err("%s: failed to set cpu chan map, err:%d\n",
1240 __func__, ret);
1241 goto end;
1242 }
1243 } else {
1244 num_tx_ch = params_channels(params);
1245 pr_debug("%s: %s tx_dai_id = %d num_ch = %d\n", __func__,
1246 codec_dai->name, codec_dai->id, num_tx_ch);
1247 ret = snd_soc_dai_get_channel_map(codec_dai,
1248 &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch);
1249 if (ret < 0) {
1250 pr_err("%s: failed to get codec chan map, err:%d\n",
1251 __func__, ret);
1252 goto end;
1253 }
1254 ret = snd_soc_dai_set_channel_map(cpu_dai,
1255 num_tx_ch, tx_ch, 0, 0);
1256 if (ret < 0) {
1257 pr_err("%s: failed to set cpu chan map, err:%d\n",
1258 __func__, ret);
1259 goto end;
1260 }
1261 }
1262end:
1263 return ret;
1264}
1265EXPORT_SYMBOL(msm_ext_slimbus_2_hw_params);
1266
1267/**
1268 * msm_snd_cpe_hw_params - hw params ops of CPE backend.
1269 *
1270 * @substream: PCM stream of associated backend dailink.
1271 * @params: HW params of associated backend dailink.
1272 *
1273 * Returns 0 on success or ret on failure.
1274 */
1275int msm_snd_cpe_hw_params(struct snd_pcm_substream *substream,
1276 struct snd_pcm_hw_params *params)
1277{
1278 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1279 struct snd_soc_dai *codec_dai = rtd->codec_dai;
1280 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1281 struct snd_soc_dai_link *dai_link = rtd->dai_link;
1282 int ret = 0;
1283 u32 tx_ch[SLIM_MAX_TX_PORTS];
1284 u32 tx_ch_cnt = 0;
1285
1286 if (substream->stream != SNDRV_PCM_STREAM_CAPTURE) {
1287 pr_err("%s: Invalid stream type %d\n",
1288 __func__, substream->stream);
1289 ret = -EINVAL;
1290 goto end;
1291 }
1292
1293 pr_debug("%s: %s_tx_dai_id_%d\n", __func__,
1294 codec_dai->name, codec_dai->id);
1295 ret = snd_soc_dai_get_channel_map(codec_dai,
1296 &tx_ch_cnt, tx_ch, NULL, NULL);
1297 if (ret < 0) {
1298 pr_err("%s: failed to get codec chan map\n, err:%d\n",
1299 __func__, ret);
1300 goto end;
1301 }
1302
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05301303 pr_debug("%s: tx_ch_cnt(%d) id %d\n",
1304 __func__, tx_ch_cnt, dai_link->id);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301305
1306 ret = snd_soc_dai_set_channel_map(cpu_dai,
1307 tx_ch_cnt, tx_ch, 0, 0);
1308 if (ret < 0) {
1309 pr_err("%s: failed to set cpu chan map, err:%d\n",
1310 __func__, ret);
1311 goto end;
1312 }
1313end:
1314 return ret;
1315}
1316EXPORT_SYMBOL(msm_snd_cpe_hw_params);
1317
1318static int msm_afe_set_config(struct snd_soc_codec *codec)
1319{
1320 int rc;
1321 void *config_data;
1322
1323 pr_debug("%s: enter\n", __func__);
1324
1325 if (!msm_codec_fn.get_afe_config_fn) {
1326 dev_err(codec->dev, "%s: codec get afe config not init'ed\n",
1327 __func__);
1328 return -EINVAL;
1329 }
1330 config_data = msm_codec_fn.get_afe_config_fn(codec,
1331 AFE_CDC_REGISTERS_CONFIG);
1332 if (config_data) {
1333 rc = afe_set_config(AFE_CDC_REGISTERS_CONFIG, config_data, 0);
1334 if (rc) {
1335 pr_err("%s: Failed to set codec registers config %d\n",
1336 __func__, rc);
1337 return rc;
1338 }
1339 }
1340
1341 config_data = msm_codec_fn.get_afe_config_fn(codec,
1342 AFE_CDC_REGISTER_PAGE_CONFIG);
1343 if (config_data) {
1344 rc = afe_set_config(AFE_CDC_REGISTER_PAGE_CONFIG, config_data,
1345 0);
1346 if (rc)
1347 pr_err("%s: Failed to set cdc register page config\n",
1348 __func__);
1349 }
1350
1351 config_data = msm_codec_fn.get_afe_config_fn(codec,
1352 AFE_SLIMBUS_SLAVE_CONFIG);
1353 if (config_data) {
1354 rc = afe_set_config(AFE_SLIMBUS_SLAVE_CONFIG, config_data, 0);
1355 if (rc) {
1356 pr_err("%s: Failed to set slimbus slave config %d\n",
1357 __func__, rc);
1358 return rc;
1359 }
1360 }
1361
1362 config_data = msm_codec_fn.get_afe_config_fn(codec,
1363 AFE_AANC_VERSION);
1364 if (config_data) {
1365 rc = afe_set_config(AFE_AANC_VERSION, config_data, 0);
1366 if (rc) {
1367 pr_err("%s: Failed to set AANC version %d\n",
1368 __func__, rc);
1369 return rc;
1370 }
1371 }
1372
1373 config_data = msm_codec_fn.get_afe_config_fn(codec,
1374 AFE_CDC_CLIP_REGISTERS_CONFIG);
1375 if (config_data) {
1376 rc = afe_set_config(AFE_CDC_CLIP_REGISTERS_CONFIG,
1377 config_data, 0);
1378 if (rc) {
1379 pr_err("%s: Failed to set clip registers %d\n",
1380 __func__, rc);
1381 return rc;
1382 }
1383 }
1384
1385 config_data = msm_codec_fn.get_afe_config_fn(codec,
1386 AFE_CLIP_BANK_SEL);
1387 if (config_data) {
1388 rc = afe_set_config(AFE_CLIP_BANK_SEL,
1389 config_data, 0);
1390 if (rc) {
1391 pr_err("%s: Failed to set AFE bank selection %d\n",
1392 __func__, rc);
1393 return rc;
1394 }
1395 }
1396
1397 config_data = msm_codec_fn.get_afe_config_fn(codec,
1398 AFE_CDC_REGISTER_PAGE_CONFIG);
1399 if (config_data) {
1400 rc = afe_set_config(AFE_CDC_REGISTER_PAGE_CONFIG, config_data,
1401 0);
1402 if (rc)
1403 pr_err("%s: Failed to set cdc register page config\n",
1404 __func__);
1405 }
1406
1407 return 0;
1408}
1409
1410static void msm_afe_clear_config(void)
1411{
1412 afe_clear_config(AFE_CDC_REGISTERS_CONFIG);
1413 afe_clear_config(AFE_SLIMBUS_SLAVE_CONFIG);
1414}
1415
Aditya Bavanarid61b84d2018-01-03 13:24:06 +05301416static int msm_adsp_power_up_config(struct snd_soc_codec *codec,
1417 struct snd_card *card)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301418{
1419 int ret = 0;
1420 unsigned long timeout;
1421 int adsp_ready = 0;
Aditya Bavanarid61b84d2018-01-03 13:24:06 +05301422 bool snd_card_online = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301423
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301424 timeout = jiffies +
1425 msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS);
1426
1427 do {
Aditya Bavanarid61b84d2018-01-03 13:24:06 +05301428 if (!snd_card_online) {
1429 snd_card_online = snd_card_is_online_state(card);
1430 pr_debug("%s: Sound card is %s\n", __func__,
1431 snd_card_online ? "Online" : "Offline");
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301432 }
Aditya Bavanarid61b84d2018-01-03 13:24:06 +05301433 if (!adsp_ready) {
1434 adsp_ready = q6core_is_adsp_ready();
1435 pr_debug("%s: ADSP Audio is %s\n", __func__,
1436 adsp_ready ? "ready" : "not ready");
1437 }
1438 if (snd_card_online && adsp_ready)
1439 break;
1440
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301441 /*
Aditya Bavanarid61b84d2018-01-03 13:24:06 +05301442 * Sound card/ADSP will be coming up after subsystem restart and
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301443 * it might not be fully up when the control reaches
1444 * here. So, wait for 50msec before checking ADSP state
1445 */
1446 msleep(50);
1447 } while (time_after(timeout, jiffies));
1448
Aditya Bavanarid61b84d2018-01-03 13:24:06 +05301449 if (!snd_card_online || !adsp_ready) {
1450 pr_err("%s: Timeout. Sound card is %s, ADSP Audio is %s\n",
1451 __func__,
1452 snd_card_online ? "Online" : "Offline",
1453 adsp_ready ? "ready" : "not ready");
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301454 ret = -ETIMEDOUT;
1455 goto err_fail;
1456 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301457
1458 ret = msm_afe_set_config(codec);
1459 if (ret)
1460 pr_err("%s: Failed to set AFE config. err %d\n",
1461 __func__, ret);
1462
1463 return 0;
1464
1465err_fail:
1466 return ret;
1467}
1468
1469static int sdm660_notifier_service_cb(struct notifier_block *this,
1470 unsigned long opcode, void *ptr)
1471{
1472 int ret;
1473 struct snd_soc_card *card = NULL;
1474 const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX;
1475 struct snd_soc_pcm_runtime *rtd;
1476 struct snd_soc_codec *codec;
1477
1478 pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode);
1479
1480 switch (opcode) {
1481 case AUDIO_NOTIFIER_SERVICE_DOWN:
1482 /*
1483 * Use flag to ignore initial boot notifications
1484 * On initial boot msm_adsp_power_up_config is
1485 * called on init. There is no need to clear
1486 * and set the config again on initial boot.
1487 */
1488 if (is_initial_boot)
1489 break;
1490 msm_afe_clear_config();
1491 break;
1492 case AUDIO_NOTIFIER_SERVICE_UP:
1493 if (is_initial_boot) {
1494 is_initial_boot = false;
1495 break;
1496 }
1497 if (!spdev)
1498 return -EINVAL;
1499
1500 card = platform_get_drvdata(spdev);
1501 rtd = snd_soc_get_pcm_runtime(card, be_dl_name);
1502 if (!rtd) {
1503 dev_err(card->dev,
1504 "%s: snd_soc_get_pcm_runtime for %s failed!\n",
1505 __func__, be_dl_name);
1506 ret = -EINVAL;
1507 goto done;
1508 }
1509 codec = rtd->codec;
1510
Aditya Bavanarid61b84d2018-01-03 13:24:06 +05301511 ret = msm_adsp_power_up_config(codec, card->snd_card);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301512 if (ret < 0) {
1513 dev_err(card->dev,
1514 "%s: msm_adsp_power_up_config failed ret = %d!\n",
1515 __func__, ret);
1516 goto done;
1517 }
1518 break;
1519 default:
1520 break;
1521 }
1522done:
1523 return NOTIFY_OK;
1524}
1525
1526static struct notifier_block service_nb = {
1527 .notifier_call = sdm660_notifier_service_cb,
1528 .priority = -INT_MAX,
1529};
1530
1531static int msm_config_hph_en0_gpio(struct snd_soc_codec *codec, bool high)
1532{
1533 struct snd_soc_card *card = codec->component.card;
1534 struct msm_asoc_mach_data *pdata;
1535 int val;
1536
1537 if (!card)
1538 return 0;
1539
1540 pdata = snd_soc_card_get_drvdata(card);
1541 if (!pdata || !gpio_is_valid(pdata->hph_en0_gpio))
1542 return 0;
1543
1544 val = gpio_get_value_cansleep(pdata->hph_en0_gpio);
1545 if ((!!val) == high)
1546 return 0;
1547
1548 gpio_direction_output(pdata->hph_en0_gpio, (int)high);
1549
1550 return 1;
1551}
1552
1553static int msm_snd_enable_codec_ext_tx_clk(struct snd_soc_codec *codec,
1554 int enable, bool dapm)
1555{
1556 int ret = 0;
1557
1558 if (!strcmp(dev_name(codec->dev), "tasha_codec"))
1559 ret = tasha_cdc_mclk_tx_enable(codec, enable, dapm);
1560 else {
1561 dev_err(codec->dev, "%s: unknown codec to enable ext clk\n",
1562 __func__);
1563 ret = -EINVAL;
1564 }
1565 return ret;
1566}
1567
1568static int msm_ext_mclk_tx_event(struct snd_soc_dapm_widget *w,
1569 struct snd_kcontrol *kcontrol, int event)
1570{
1571 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1572
1573 pr_debug("%s: event = %d\n", __func__, event);
1574
1575 switch (event) {
1576 case SND_SOC_DAPM_PRE_PMU:
1577 return msm_snd_enable_codec_ext_tx_clk(codec, 1, true);
1578 case SND_SOC_DAPM_POST_PMD:
1579 return msm_snd_enable_codec_ext_tx_clk(codec, 0, true);
1580 }
1581 return 0;
1582}
1583
1584static int msm_ext_mclk_event(struct snd_soc_dapm_widget *w,
1585 struct snd_kcontrol *kcontrol, int event)
1586{
1587 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1588
1589 pr_debug("%s: event = %d\n", __func__, event);
1590
1591 switch (event) {
1592 case SND_SOC_DAPM_PRE_PMU:
1593 return msm_ext_enable_codec_mclk(codec, 1, true);
1594 case SND_SOC_DAPM_POST_PMD:
1595 return msm_ext_enable_codec_mclk(codec, 0, true);
1596 }
1597 return 0;
1598}
1599
Dhanalakshmi Siddani7ce33bb2018-11-28 22:01:53 +05301600static int msm_hifi_ctrl_event(struct snd_soc_dapm_widget *w,
1601 struct snd_kcontrol *k, int event)
1602{
1603 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1604 struct snd_soc_card *card = codec->component.card;
1605 struct msm_asoc_mach_data *pdata =
1606 snd_soc_card_get_drvdata(card);
1607
1608 pr_debug("%s: msm_hifi_control = %d\n", __func__, msm_hifi_control);
1609
1610 if (!pdata || !pdata->hph_en0_gpio_p) {
1611 pr_err("%s: hph_en0_gpio is invalid\n", __func__);
1612 return -EINVAL;
1613 }
1614
1615 if (msm_hifi_control != MSM_HIFI_ON) {
1616 pr_debug("%s: HiFi mixer control is not set\n",
1617 __func__);
1618 return 0;
1619 }
1620
1621 switch (event) {
1622 case SND_SOC_DAPM_POST_PMU:
1623 msm_cdc_pinctrl_select_active_state(pdata->hph_en0_gpio_p);
1624 break;
1625 case SND_SOC_DAPM_PRE_PMD:
1626 msm_cdc_pinctrl_select_sleep_state(pdata->hph_en0_gpio_p);
1627 break;
1628 }
1629
1630 return 0;
1631}
1632
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301633static int msm_ext_prepare_hifi(struct msm_asoc_mach_data *pdata)
1634{
1635 int ret = 0;
1636
1637 if (gpio_is_valid(pdata->hph_en1_gpio)) {
1638 pr_debug("%s: hph_en1_gpio request %d\n", __func__,
1639 pdata->hph_en1_gpio);
1640 ret = gpio_request(pdata->hph_en1_gpio, "hph_en1_gpio");
1641 if (ret) {
1642 pr_err("%s: hph_en1_gpio request failed, ret:%d\n",
1643 __func__, ret);
1644 goto err;
1645 }
1646 }
1647 if (gpio_is_valid(pdata->hph_en0_gpio)) {
1648 pr_debug("%s: hph_en0_gpio request %d\n", __func__,
1649 pdata->hph_en0_gpio);
1650 ret = gpio_request(pdata->hph_en0_gpio, "hph_en0_gpio");
1651 if (ret)
1652 pr_err("%s: hph_en0_gpio request failed, ret:%d\n",
1653 __func__, ret);
1654 }
1655
1656err:
1657 return ret;
1658}
1659
1660static const struct snd_soc_dapm_widget msm_dapm_widgets[] = {
1661
1662 SND_SOC_DAPM_SUPPLY_S("MCLK", -1, SND_SOC_NOPM, 0, 0,
1663 msm_ext_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1664
1665 SND_SOC_DAPM_SUPPLY_S("MCLK TX", -1, SND_SOC_NOPM, 0, 0,
1666 msm_ext_mclk_tx_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1667
1668 SND_SOC_DAPM_SPK("Lineout_1 amp", NULL),
1669 SND_SOC_DAPM_SPK("Lineout_3 amp", NULL),
1670 SND_SOC_DAPM_SPK("Lineout_2 amp", NULL),
1671 SND_SOC_DAPM_SPK("Lineout_4 amp", NULL),
Dhanalakshmi Siddani7ce33bb2018-11-28 22:01:53 +05301672 SND_SOC_DAPM_SPK("hifi amp", msm_hifi_ctrl_event),
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301673 SND_SOC_DAPM_MIC("Handset Mic", NULL),
1674 SND_SOC_DAPM_MIC("Headset Mic", NULL),
1675 SND_SOC_DAPM_MIC("Secondary Mic", NULL),
1676 SND_SOC_DAPM_MIC("ANCRight Headset Mic", NULL),
1677 SND_SOC_DAPM_MIC("ANCLeft Headset Mic", NULL),
1678 SND_SOC_DAPM_MIC("Analog Mic4", NULL),
1679 SND_SOC_DAPM_MIC("Analog Mic6", NULL),
1680 SND_SOC_DAPM_MIC("Analog Mic7", NULL),
1681 SND_SOC_DAPM_MIC("Analog Mic8", NULL),
1682
1683 SND_SOC_DAPM_MIC("Digital Mic0", NULL),
1684 SND_SOC_DAPM_MIC("Digital Mic1", NULL),
1685 SND_SOC_DAPM_MIC("Digital Mic2", NULL),
1686 SND_SOC_DAPM_MIC("Digital Mic3", NULL),
1687 SND_SOC_DAPM_MIC("Digital Mic4", NULL),
1688 SND_SOC_DAPM_MIC("Digital Mic5", NULL),
1689 SND_SOC_DAPM_MIC("Digital Mic6", NULL),
1690};
1691
1692static struct snd_soc_dapm_route wcd_audio_paths_tasha[] = {
1693 {"MIC BIAS1", NULL, "MCLK TX"},
1694 {"MIC BIAS2", NULL, "MCLK TX"},
1695 {"MIC BIAS3", NULL, "MCLK TX"},
1696 {"MIC BIAS4", NULL, "MCLK TX"},
1697};
1698
1699static struct snd_soc_dapm_route wcd_audio_paths[] = {
1700 {"MIC BIAS1", NULL, "MCLK"},
1701 {"MIC BIAS2", NULL, "MCLK"},
1702 {"MIC BIAS3", NULL, "MCLK"},
1703 {"MIC BIAS4", NULL, "MCLK"},
1704};
1705
Laxminath Kasam38070be2017-08-17 18:21:59 +05301706int msm_snd_card_tasha_late_probe(struct snd_soc_card *card)
1707{
1708 const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX;
1709 struct snd_soc_pcm_runtime *rtd;
1710 int ret = 0;
1711 void *mbhc_calibration;
1712
1713 rtd = snd_soc_get_pcm_runtime(card, be_dl_name);
1714 if (!rtd) {
1715 dev_err(card->dev,
1716 "%s: snd_soc_get_pcm_runtime for %s failed!\n",
1717 __func__, be_dl_name);
1718 ret = -EINVAL;
1719 goto err_pcm_runtime;
1720 }
1721
1722 mbhc_calibration = def_ext_mbhc_cal();
1723 if (!mbhc_calibration) {
1724 ret = -ENOMEM;
1725 goto err_mbhc_cal;
1726 }
1727 wcd_mbhc_cfg_ptr->calibration = mbhc_calibration;
1728 ret = tasha_mbhc_hs_detect(rtd->codec, wcd_mbhc_cfg_ptr);
1729 if (ret) {
1730 dev_err(card->dev, "%s: mbhc hs detect failed, err:%d\n",
1731 __func__, ret);
1732 goto err_hs_detect;
1733 }
1734 return 0;
1735
1736err_hs_detect:
1737 kfree(mbhc_calibration);
1738err_mbhc_cal:
1739err_pcm_runtime:
1740 return ret;
1741}
1742
1743int msm_snd_card_tavil_late_probe(struct snd_soc_card *card)
1744{
1745 const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX;
1746 struct snd_soc_pcm_runtime *rtd;
1747 int ret = 0;
1748 void *mbhc_calibration;
1749
1750 rtd = snd_soc_get_pcm_runtime(card, be_dl_name);
1751 if (!rtd) {
1752 dev_err(card->dev,
1753 "%s: snd_soc_get_pcm_runtime for %s failed!\n",
1754 __func__, be_dl_name);
1755 ret = -EINVAL;
1756 goto err;
1757 }
1758
1759 mbhc_calibration = def_ext_mbhc_cal();
1760 if (!mbhc_calibration) {
1761 ret = -ENOMEM;
1762 goto err;
1763 }
1764 wcd_mbhc_cfg_ptr->calibration = mbhc_calibration;
1765 ret = tavil_mbhc_hs_detect(rtd->codec, wcd_mbhc_cfg_ptr);
1766 if (ret) {
1767 dev_err(card->dev, "%s: mbhc hs detect failed, err:%d\n",
1768 __func__, ret);
1769 goto err_free_mbhc_cal;
1770 }
1771 return 0;
1772
1773err_free_mbhc_cal:
1774 kfree(mbhc_calibration);
1775err:
1776 return ret;
1777}
1778
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301779/**
1780 * msm_audrx_init - Audio init function of sound card instantiate.
1781 *
1782 * @rtd: runtime dailink instance
1783 *
1784 * Returns 0 on success or ret on failure.
1785 */
1786int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
1787{
1788 int ret;
1789 void *config_data;
1790 struct snd_soc_codec *codec = rtd->codec;
1791 struct snd_soc_dapm_context *dapm =
1792 snd_soc_codec_get_dapm(codec);
1793 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1794 struct snd_soc_dai *codec_dai = rtd->codec_dai;
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05301795 struct snd_soc_component *aux_comp;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301796 struct snd_card *card;
1797 struct snd_info_entry *entry;
1798 struct msm_asoc_mach_data *pdata =
1799 snd_soc_card_get_drvdata(rtd->card);
1800
1801 /* Codec SLIMBUS configuration
1802 * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8, RX9, RX10, RX11, RX12, RX13
1803 * TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13
1804 * TX14, TX15, TX16
1805 */
1806 unsigned int rx_ch[TASHA_RX_MAX] = {144, 145, 146, 147, 148, 149, 150,
1807 151, 152, 153, 154, 155, 156};
1808 unsigned int tx_ch[TASHA_TX_MAX] = {128, 129, 130, 131, 132, 133,
1809 134, 135, 136, 137, 138, 139,
1810 140, 141, 142, 143};
1811
1812 /* Tavil Codec SLIMBUS configuration
1813 * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8
1814 * TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13
1815 * TX14, TX15, TX16
1816 */
1817 unsigned int rx_ch_tavil[WCD934X_RX_MAX] = {144, 145, 146, 147, 148,
1818 149, 150, 151};
1819 unsigned int tx_ch_tavil[WCD934X_TX_MAX] = {128, 129, 130, 131, 132,
1820 133, 134, 135, 136, 137, 138,
1821 139, 140, 141, 142, 143};
1822
1823 pr_debug("%s: dev_name%s\n", __func__, dev_name(cpu_dai->dev));
1824
1825 rtd->pmdown_time = 0;
1826
1827 ret = snd_soc_add_codec_controls(codec, msm_snd_controls,
1828 ARRAY_SIZE(msm_snd_controls));
1829 if (ret < 0) {
1830 pr_err("%s: add_codec_controls failed: %d\n",
1831 __func__, ret);
1832 return ret;
1833 }
1834
1835 ret = snd_soc_add_codec_controls(codec, msm_common_snd_controls,
1836 msm_common_snd_controls_size());
1837 if (ret < 0) {
1838 pr_err("%s: add_common_snd_controls failed: %d\n",
1839 __func__, ret);
1840 return ret;
1841 }
1842
1843 snd_soc_dapm_new_controls(dapm, msm_dapm_widgets,
1844 ARRAY_SIZE(msm_dapm_widgets));
1845
1846 if (!strcmp(dev_name(codec_dai->dev), "tasha_codec"))
1847 snd_soc_dapm_add_routes(dapm, wcd_audio_paths_tasha,
1848 ARRAY_SIZE(wcd_audio_paths_tasha));
1849 else
1850 snd_soc_dapm_add_routes(dapm, wcd_audio_paths,
1851 ARRAY_SIZE(wcd_audio_paths));
1852
1853 snd_soc_dapm_enable_pin(dapm, "Lineout_1 amp");
1854 snd_soc_dapm_enable_pin(dapm, "Lineout_3 amp");
1855 snd_soc_dapm_enable_pin(dapm, "Lineout_2 amp");
1856 snd_soc_dapm_enable_pin(dapm, "Lineout_4 amp");
1857
1858 snd_soc_dapm_ignore_suspend(dapm, "MADINPUT");
1859 snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_INPUT");
1860 snd_soc_dapm_ignore_suspend(dapm, "Handset Mic");
1861 snd_soc_dapm_ignore_suspend(dapm, "Headset Mic");
1862 snd_soc_dapm_ignore_suspend(dapm, "Secondary Mic");
1863 snd_soc_dapm_ignore_suspend(dapm, "Lineout_1 amp");
1864 snd_soc_dapm_ignore_suspend(dapm, "Lineout_3 amp");
1865 snd_soc_dapm_ignore_suspend(dapm, "Lineout_2 amp");
1866 snd_soc_dapm_ignore_suspend(dapm, "Lineout_4 amp");
1867 snd_soc_dapm_ignore_suspend(dapm, "ANCRight Headset Mic");
1868 snd_soc_dapm_ignore_suspend(dapm, "ANCLeft Headset Mic");
1869 snd_soc_dapm_ignore_suspend(dapm, "Digital Mic0");
1870 snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1");
1871 snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2");
1872 snd_soc_dapm_ignore_suspend(dapm, "Digital Mic3");
1873 snd_soc_dapm_ignore_suspend(dapm, "Digital Mic4");
1874 snd_soc_dapm_ignore_suspend(dapm, "Digital Mic5");
1875 snd_soc_dapm_ignore_suspend(dapm, "Analog Mic4");
1876 snd_soc_dapm_ignore_suspend(dapm, "Analog Mic6");
1877 snd_soc_dapm_ignore_suspend(dapm, "Analog Mic7");
1878 snd_soc_dapm_ignore_suspend(dapm, "Analog Mic8");
1879
1880 snd_soc_dapm_ignore_suspend(dapm, "EAR");
1881 snd_soc_dapm_ignore_suspend(dapm, "LINEOUT1");
1882 snd_soc_dapm_ignore_suspend(dapm, "LINEOUT2");
1883 snd_soc_dapm_ignore_suspend(dapm, "AMIC1");
1884 snd_soc_dapm_ignore_suspend(dapm, "AMIC2");
1885 snd_soc_dapm_ignore_suspend(dapm, "AMIC3");
1886 snd_soc_dapm_ignore_suspend(dapm, "AMIC4");
1887 snd_soc_dapm_ignore_suspend(dapm, "AMIC5");
1888 snd_soc_dapm_ignore_suspend(dapm, "DMIC0");
1889 snd_soc_dapm_ignore_suspend(dapm, "DMIC1");
1890 snd_soc_dapm_ignore_suspend(dapm, "DMIC2");
1891 snd_soc_dapm_ignore_suspend(dapm, "DMIC3");
1892 snd_soc_dapm_ignore_suspend(dapm, "DMIC4");
1893 snd_soc_dapm_ignore_suspend(dapm, "DMIC5");
1894 snd_soc_dapm_ignore_suspend(dapm, "ANC EAR");
1895 snd_soc_dapm_ignore_suspend(dapm, "SPK1 OUT");
1896 snd_soc_dapm_ignore_suspend(dapm, "SPK2 OUT");
1897 snd_soc_dapm_ignore_suspend(dapm, "HPHL");
1898 snd_soc_dapm_ignore_suspend(dapm, "HPHR");
1899 snd_soc_dapm_ignore_suspend(dapm, "AIF4 VI");
1900 snd_soc_dapm_ignore_suspend(dapm, "VIINPUT");
1901
1902 if (!strcmp(dev_name(codec_dai->dev), "tasha_codec")) {
1903 snd_soc_dapm_ignore_suspend(dapm, "LINEOUT3");
1904 snd_soc_dapm_ignore_suspend(dapm, "LINEOUT4");
1905 snd_soc_dapm_ignore_suspend(dapm, "ANC HPHL");
1906 snd_soc_dapm_ignore_suspend(dapm, "ANC HPHR");
1907 snd_soc_dapm_ignore_suspend(dapm, "ANC LINEOUT1");
1908 snd_soc_dapm_ignore_suspend(dapm, "ANC LINEOUT2");
1909 } else {
1910 snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_OUT1");
1911 snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_OUT2");
1912 }
1913
1914 snd_soc_dapm_sync(dapm);
1915
1916 if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) {
1917 snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch_tavil),
1918 tx_ch_tavil, ARRAY_SIZE(rx_ch_tavil),
1919 rx_ch_tavil);
1920 } else {
1921 snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch),
1922 tx_ch, ARRAY_SIZE(rx_ch),
1923 rx_ch);
1924 }
1925
1926 if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) {
1927 msm_codec_fn.get_afe_config_fn = tavil_get_afe_config;
1928 } else {
1929 msm_codec_fn.get_afe_config_fn = tasha_get_afe_config;
1930 msm_codec_fn.mbhc_hs_detect_exit = tasha_mbhc_hs_detect_exit;
1931 }
1932
Aditya Bavanarid61b84d2018-01-03 13:24:06 +05301933 ret = msm_adsp_power_up_config(codec, rtd->card->snd_card);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301934 if (ret) {
1935 pr_err("%s: Failed to set AFE config %d\n", __func__, ret);
1936 goto err_afe_cfg;
1937 }
1938
1939 config_data = msm_codec_fn.get_afe_config_fn(codec,
1940 AFE_AANC_VERSION);
1941 if (config_data) {
1942 ret = afe_set_config(AFE_AANC_VERSION, config_data, 0);
1943 if (ret) {
1944 pr_err("%s: Failed to set aanc version %d\n",
1945 __func__, ret);
1946 goto err_afe_cfg;
1947 }
1948 }
1949
1950 if (!strcmp(dev_name(codec_dai->dev), "tasha_codec")) {
1951 config_data = msm_codec_fn.get_afe_config_fn(codec,
1952 AFE_CDC_CLIP_REGISTERS_CONFIG);
1953 if (config_data) {
1954 ret = afe_set_config(AFE_CDC_CLIP_REGISTERS_CONFIG,
1955 config_data, 0);
1956 if (ret) {
1957 pr_err("%s: Failed to set clip registers %d\n",
1958 __func__, ret);
1959 goto err_afe_cfg;
1960 }
1961 }
1962 config_data = msm_codec_fn.get_afe_config_fn(codec,
1963 AFE_CLIP_BANK_SEL);
1964 if (config_data) {
1965 ret = afe_set_config(AFE_CLIP_BANK_SEL, config_data, 0);
1966 if (ret) {
1967 pr_err("%s: Failed to set AFE bank selection %d\n",
1968 __func__, ret);
1969 goto err_afe_cfg;
1970 }
1971 }
1972 }
1973
1974 /*
1975 * Send speaker configuration only for WSA8810.
1976 * Defalut configuration is for WSA8815.
1977 */
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05301978 pr_debug("%s: Number of aux devices: %d\n",
1979 __func__, rtd->card->num_aux_devs);
1980
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301981 if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) {
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05301982 if (rtd->card->num_aux_devs &&
1983 !list_empty(&rtd->card->aux_comp_list)) {
1984 aux_comp = list_first_entry(&rtd->card->aux_comp_list,
1985 struct snd_soc_component, list_aux);
1986 if (!strcmp(aux_comp->name, WSA8810_NAME_1) ||
1987 !strcmp(aux_comp->name, WSA8810_NAME_2)) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301988 tavil_set_spkr_mode(rtd->codec, SPKR_MODE_1);
1989 tavil_set_spkr_gain_offset(rtd->codec,
1990 RX_GAIN_OFFSET_M1P5_DB);
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05301991 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301992 }
1993 card = rtd->card->snd_card;
1994 entry = snd_info_create_subdir(card->module, "codecs",
1995 card->proc_root);
1996 if (!entry) {
1997 pr_debug("%s: Cannot create codecs module entry\n",
1998 __func__);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301999 goto done;
2000 }
2001 pdata->codec_root = entry;
2002 tavil_codec_info_create_codec_entry(pdata->codec_root, codec);
2003 } else {
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05302004 if (rtd->card->num_aux_devs &&
2005 !list_empty(&rtd->card->aux_comp_list)) {
2006 aux_comp = list_first_entry(&rtd->card->aux_comp_list,
2007 struct snd_soc_component, list_aux);
2008 if (!strcmp(aux_comp->name, WSA8810_NAME_1) ||
2009 !strcmp(aux_comp->name, WSA8810_NAME_2)) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302010 tasha_set_spkr_mode(rtd->codec, SPKR_MODE_1);
2011 tasha_set_spkr_gain_offset(rtd->codec,
2012 RX_GAIN_OFFSET_M1P5_DB);
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05302013 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302014 }
2015 card = rtd->card->snd_card;
2016 entry = snd_info_create_subdir(card->module, "codecs",
2017 card->proc_root);
2018 if (!entry) {
2019 pr_debug("%s: Cannot create codecs module entry\n",
2020 __func__);
Laxminath Kasam38070be2017-08-17 18:21:59 +05302021 goto done;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302022 }
2023 pdata->codec_root = entry;
2024 tasha_codec_info_create_codec_entry(pdata->codec_root, codec);
2025 tasha_mbhc_zdet_gpio_ctrl(msm_config_hph_en0_gpio, rtd->codec);
2026 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302027done:
Laxminath Kasam38070be2017-08-17 18:21:59 +05302028 msm_set_codec_reg_done(true);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302029 return 0;
2030
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302031err_afe_cfg:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302032 return ret;
2033}
2034EXPORT_SYMBOL(msm_audrx_init);
2035
2036/**
2037 * msm_ext_register_audio_notifier - register SSR notifier.
2038 */
2039void msm_ext_register_audio_notifier(struct platform_device *pdev)
2040{
2041 int ret;
2042
2043 is_initial_boot = true;
2044 spdev = pdev;
2045 ret = audio_notifier_register("sdm660", AUDIO_NOTIFIER_ADSP_DOMAIN,
2046 &service_nb);
2047 if (ret < 0)
2048 pr_err("%s: Audio notifier register failed ret = %d\n",
2049 __func__, ret);
2050}
2051EXPORT_SYMBOL(msm_ext_register_audio_notifier);
2052
2053/**
2054 * msm_ext_cdc_init - external codec machine specific init.
2055 *
2056 * @pdev: platform device handle
2057 * @pdata: private data of machine driver
2058 * @card: sound card pointer reference
2059 * @mbhc_cfg: MBHC config reference
2060 *
2061 * Returns 0 on success or ret on failure.
2062 */
2063int msm_ext_cdc_init(struct platform_device *pdev,
2064 struct msm_asoc_mach_data *pdata,
2065 struct snd_soc_card **card,
2066 struct wcd_mbhc_config *wcd_mbhc_cfg_ptr1)
2067{
2068 int ret = 0;
2069
2070 wcd_mbhc_cfg_ptr = wcd_mbhc_cfg_ptr1;
2071 pdev->id = 0;
2072 wcd_mbhc_cfg_ptr->moisture_en = true;
2073 wcd_mbhc_cfg_ptr->mbhc_micbias = MIC_BIAS_2;
2074 wcd_mbhc_cfg_ptr->anc_micbias = MIC_BIAS_2;
2075 wcd_mbhc_cfg_ptr->enable_anc_mic_detect = false;
2076
2077 *card = populate_snd_card_dailinks(&pdev->dev, pdata->snd_card_val);
2078 if (!(*card)) {
2079 dev_err(&pdev->dev, "%s: Card uninitialized\n", __func__);
2080 ret = -EPROBE_DEFER;
2081 goto err;
2082 }
2083 platform_set_drvdata(pdev, *card);
2084 snd_soc_card_set_drvdata(*card, pdata);
2085 pdata->hph_en1_gpio = of_get_named_gpio(pdev->dev.of_node,
2086 "qcom,hph-en1-gpio", 0);
2087 if (!gpio_is_valid(pdata->hph_en1_gpio))
2088 pdata->hph_en1_gpio_p = of_parse_phandle(pdev->dev.of_node,
2089 "qcom,hph-en1-gpio", 0);
2090 if (!gpio_is_valid(pdata->hph_en1_gpio) && (!pdata->hph_en1_gpio_p)) {
2091 dev_dbg(&pdev->dev, "property %s not detected in node %s",
2092 "qcom,hph-en1-gpio", pdev->dev.of_node->full_name);
2093 }
2094
2095 pdata->hph_en0_gpio = of_get_named_gpio(pdev->dev.of_node,
2096 "qcom,hph-en0-gpio", 0);
2097 if (!gpio_is_valid(pdata->hph_en0_gpio))
2098 pdata->hph_en0_gpio_p = of_parse_phandle(pdev->dev.of_node,
2099 "qcom,hph-en0-gpio", 0);
2100 if (!gpio_is_valid(pdata->hph_en0_gpio) && (!pdata->hph_en0_gpio_p)) {
2101 dev_dbg(&pdev->dev, "property %s not detected in node %s",
2102 "qcom,hph-en0-gpio", pdev->dev.of_node->full_name);
2103 }
2104
2105 ret = msm_ext_prepare_hifi(pdata);
2106 if (ret) {
2107 dev_dbg(&pdev->dev, "msm_ext_prepare_hifi failed (%d)\n",
2108 ret);
2109 ret = 0;
2110 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302111err:
2112 return ret;
2113}
2114EXPORT_SYMBOL(msm_ext_cdc_init);