blob: 258eefd66392a35c658b4cd259fec2138438b9d8 [file] [log] [blame]
Dhanalakshmi Siddanid70a4f72019-11-27 15:35:41 +05301/* Copyright (c) 2015-2019, 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
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053085/* Default configuration of slimbus channels */
86static struct dev_config slim_rx_cfg[] = {
87 [SLIM_RX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
88 [SLIM_RX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
89 [SLIM_RX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
90 [SLIM_RX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
91 [SLIM_RX_4] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
92 [SLIM_RX_5] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
93 [SLIM_RX_6] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
94 [SLIM_RX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
95};
96
97static struct dev_config slim_tx_cfg[] = {
98 [SLIM_TX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
99 [SLIM_TX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
100 [SLIM_TX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
101 [SLIM_TX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
102 [SLIM_TX_4] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
103 [SLIM_TX_5] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
104 [SLIM_TX_6] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
105 [SLIM_TX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
106 [SLIM_TX_8] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
107};
108
Surendar Karka813c3d22018-11-05 13:46:17 +0530109static struct snd_soc_jack linein_jack;
110
111static struct snd_soc_jack_pin linein_jack_pins[] = {
112 {
113 .pin = "Linein",
114 .mask = SND_JACK_LINEIN,
115 },
116};
117
118static struct snd_soc_jack_gpio linein_jack_gpio = {
119 .name = "Linein detection",
120 .report = SND_JACK_LINEIN,
121 .debounce_time = 800,
122};
123
124static struct snd_soc_jack lineout_jack;
125
126static struct snd_soc_jack_pin lineout_jack_pins[] = {
127 {
128 .pin = "Lineout",
129 .mask = SND_JACK_LINEOUT,
130 },
131};
132
133static struct snd_soc_jack_gpio lineout_jack_gpio = {
134 .name = "Lineout detection",
135 .report = SND_JACK_LINEOUT,
136 .debounce_time = 800,
137};
138
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530139static int msm_vi_feed_tx_ch = 2;
Dhanalakshmi Siddani7ce33bb2018-11-28 22:01:53 +0530140static const char *const slim_rx_ch_text[] = {"One", "Two", "Three", "Four",
141 "Five", "Six", "Seven",
142 "Eight"};
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530143static const char *const slim_tx_ch_text[] = {"One", "Two", "Three", "Four",
144 "Five", "Six", "Seven",
145 "Eight"};
146static const char *const vi_feed_ch_text[] = {"One", "Two"};
147static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE",
148 "S32_LE"};
149static char const *slim_sample_rate_text[] = {"KHZ_8", "KHZ_16",
150 "KHZ_32", "KHZ_44P1", "KHZ_48",
151 "KHZ_88P2", "KHZ_96", "KHZ_176P4",
152 "KHZ_192", "KHZ_352P8", "KHZ_384"};
153static const char *const spk_function_text[] = {"Off", "On"};
Preetam Singh Ranawat66f1f212017-12-05 15:30:24 +0530154static char const *bt_sample_rate_text[] = {"KHZ_8", "KHZ_16",
155 "KHZ_44P1", "KHZ_48",
156 "KHZ_88P2", "KHZ_96"};
Preetam Singh Ranawatd79190a2018-06-25 15:59:23 +0530157static char const *bt_sample_rate_rx_text[] = {"KHZ_8", "KHZ_16",
158 "KHZ_44P1", "KHZ_48",
159 "KHZ_88P2", "KHZ_96"};
160static char const *bt_sample_rate_tx_text[] = {"KHZ_8", "KHZ_16",
161 "KHZ_44P1", "KHZ_48",
162 "KHZ_88P2", "KHZ_96"};
Dhanalakshmi Siddani7ce33bb2018-11-28 22:01:53 +0530163static const char *const hifi_text[] = {"Off", "On"};
164
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530165static SOC_ENUM_SINGLE_EXT_DECL(spk_func_en, spk_function_text);
166static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_chs, slim_rx_ch_text);
167static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_chs, slim_rx_ch_text);
168static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_chs, slim_tx_ch_text);
169static SOC_ENUM_SINGLE_EXT_DECL(slim_1_tx_chs, slim_tx_ch_text);
170static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_chs, slim_rx_ch_text);
171static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_chs, slim_rx_ch_text);
172static SOC_ENUM_SINGLE_EXT_DECL(vi_feed_tx_chs, vi_feed_ch_text);
173static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_format, bit_format_text);
174static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_format, bit_format_text);
175static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_format, bit_format_text);
176static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_format, bit_format_text);
177static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_sample_rate, slim_sample_rate_text);
178static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_sample_rate, slim_sample_rate_text);
179static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_sample_rate, slim_sample_rate_text);
180static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_sample_rate, slim_sample_rate_text);
181static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_sample_rate, slim_sample_rate_text);
182static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate, bt_sample_rate_text);
Preetam Singh Ranawatd79190a2018-06-25 15:59:23 +0530183static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate_rx, bt_sample_rate_rx_text);
184static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate_tx, bt_sample_rate_tx_text);
Dhanalakshmi Siddani7ce33bb2018-11-28 22:01:53 +0530185static SOC_ENUM_SINGLE_EXT_DECL(hifi_function, hifi_text);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530186
187static int slim_get_sample_rate_val(int sample_rate)
188{
189 int sample_rate_val = 0;
190
191 switch (sample_rate) {
192 case SAMPLING_RATE_8KHZ:
193 sample_rate_val = 0;
194 break;
195 case SAMPLING_RATE_16KHZ:
196 sample_rate_val = 1;
197 break;
198 case SAMPLING_RATE_32KHZ:
199 sample_rate_val = 2;
200 break;
201 case SAMPLING_RATE_44P1KHZ:
202 sample_rate_val = 3;
203 break;
204 case SAMPLING_RATE_48KHZ:
205 sample_rate_val = 4;
206 break;
207 case SAMPLING_RATE_88P2KHZ:
208 sample_rate_val = 5;
209 break;
210 case SAMPLING_RATE_96KHZ:
211 sample_rate_val = 6;
212 break;
213 case SAMPLING_RATE_176P4KHZ:
214 sample_rate_val = 7;
215 break;
216 case SAMPLING_RATE_192KHZ:
217 sample_rate_val = 8;
218 break;
219 case SAMPLING_RATE_352P8KHZ:
220 sample_rate_val = 9;
221 break;
222 case SAMPLING_RATE_384KHZ:
223 sample_rate_val = 10;
224 break;
225 default:
226 sample_rate_val = 4;
227 break;
228 }
229 return sample_rate_val;
230}
231
232static int slim_get_sample_rate(int value)
233{
234 int sample_rate = 0;
235
236 switch (value) {
237 case 0:
238 sample_rate = SAMPLING_RATE_8KHZ;
239 break;
240 case 1:
241 sample_rate = SAMPLING_RATE_16KHZ;
242 break;
243 case 2:
244 sample_rate = SAMPLING_RATE_32KHZ;
245 break;
246 case 3:
247 sample_rate = SAMPLING_RATE_44P1KHZ;
248 break;
249 case 4:
250 sample_rate = SAMPLING_RATE_48KHZ;
251 break;
252 case 5:
253 sample_rate = SAMPLING_RATE_88P2KHZ;
254 break;
255 case 6:
256 sample_rate = SAMPLING_RATE_96KHZ;
257 break;
258 case 7:
259 sample_rate = SAMPLING_RATE_176P4KHZ;
260 break;
261 case 8:
262 sample_rate = SAMPLING_RATE_192KHZ;
263 break;
264 case 9:
265 sample_rate = SAMPLING_RATE_352P8KHZ;
266 break;
267 case 10:
268 sample_rate = SAMPLING_RATE_384KHZ;
269 break;
270 default:
271 sample_rate = SAMPLING_RATE_48KHZ;
272 break;
273 }
274 return sample_rate;
275}
276
277static int slim_get_bit_format_val(int bit_format)
278{
279 int val = 0;
280
281 switch (bit_format) {
282 case SNDRV_PCM_FORMAT_S32_LE:
283 val = 3;
284 break;
285 case SNDRV_PCM_FORMAT_S24_3LE:
286 val = 2;
287 break;
288 case SNDRV_PCM_FORMAT_S24_LE:
289 val = 1;
290 break;
291 case SNDRV_PCM_FORMAT_S16_LE:
292 default:
293 val = 0;
294 break;
295 }
296 return val;
297}
298
299static int slim_get_bit_format(int val)
300{
301 int bit_fmt = SNDRV_PCM_FORMAT_S16_LE;
302
303 switch (val) {
304 case 0:
305 bit_fmt = SNDRV_PCM_FORMAT_S16_LE;
306 break;
307 case 1:
308 bit_fmt = SNDRV_PCM_FORMAT_S24_LE;
309 break;
310 case 2:
311 bit_fmt = SNDRV_PCM_FORMAT_S24_3LE;
312 break;
313 case 3:
314 bit_fmt = SNDRV_PCM_FORMAT_S32_LE;
315 break;
316 default:
317 bit_fmt = SNDRV_PCM_FORMAT_S16_LE;
318 break;
319 }
320 return bit_fmt;
321}
322
323static int slim_get_port_idx(struct snd_kcontrol *kcontrol)
324{
325 int port_id = 0;
326
327 if (strnstr(kcontrol->id.name, "SLIM_0_RX", sizeof("SLIM_0_RX")))
328 port_id = SLIM_RX_0;
329 else if (strnstr(kcontrol->id.name, "SLIM_2_RX", sizeof("SLIM_2_RX")))
330 port_id = SLIM_RX_2;
331 else if (strnstr(kcontrol->id.name, "SLIM_5_RX", sizeof("SLIM_5_RX")))
332 port_id = SLIM_RX_5;
333 else if (strnstr(kcontrol->id.name, "SLIM_6_RX", sizeof("SLIM_6_RX")))
334 port_id = SLIM_RX_6;
335 else if (strnstr(kcontrol->id.name, "SLIM_0_TX", sizeof("SLIM_0_TX")))
336 port_id = SLIM_TX_0;
337 else if (strnstr(kcontrol->id.name, "SLIM_1_TX", sizeof("SLIM_1_TX")))
338 port_id = SLIM_TX_1;
339 else {
340 pr_err("%s: unsupported channel: %s",
341 __func__, kcontrol->id.name);
342 return -EINVAL;
343 }
344
345 return port_id;
346}
347
348static int msm_bt_sample_rate_get(struct snd_kcontrol *kcontrol,
349 struct snd_ctl_elem_value *ucontrol)
350{
351 /*
352 * Slimbus_7_Rx/Tx sample rate values should always be in sync (same)
353 * when used for BT_SCO use case. Return either Rx or Tx sample rate
354 * value.
355 */
356 switch (slim_rx_cfg[SLIM_RX_7].sample_rate) {
Preetam Singh Ranawat66f1f212017-12-05 15:30:24 +0530357 case SAMPLING_RATE_96KHZ:
358 ucontrol->value.integer.value[0] = 5;
359 break;
360 case SAMPLING_RATE_88P2KHZ:
361 ucontrol->value.integer.value[0] = 4;
362 break;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530363 case SAMPLING_RATE_48KHZ:
Preetam Singh Ranawat66f1f212017-12-05 15:30:24 +0530364 ucontrol->value.integer.value[0] = 3;
365 break;
366 case SAMPLING_RATE_44P1KHZ:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530367 ucontrol->value.integer.value[0] = 2;
368 break;
369 case SAMPLING_RATE_16KHZ:
370 ucontrol->value.integer.value[0] = 1;
371 break;
372 case SAMPLING_RATE_8KHZ:
373 default:
374 ucontrol->value.integer.value[0] = 0;
375 break;
376 }
377 pr_debug("%s: sample rate = %d", __func__,
378 slim_rx_cfg[SLIM_RX_7].sample_rate);
379
380 return 0;
381}
382
383static int msm_bt_sample_rate_put(struct snd_kcontrol *kcontrol,
384 struct snd_ctl_elem_value *ucontrol)
385{
386 switch (ucontrol->value.integer.value[0]) {
387 case 1:
388 slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_16KHZ;
389 slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_16KHZ;
390 break;
391 case 2:
Preetam Singh Ranawat66f1f212017-12-05 15:30:24 +0530392 slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_44P1KHZ;
393 slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_44P1KHZ;
394 break;
395 case 3:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530396 slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_48KHZ;
397 slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_48KHZ;
398 break;
Preetam Singh Ranawat66f1f212017-12-05 15:30:24 +0530399 case 4:
400 slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_88P2KHZ;
401 slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_88P2KHZ;
402 break;
403 case 5:
404 slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_96KHZ;
405 slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_96KHZ;
406 break;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530407 case 0:
408 default:
409 slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_8KHZ;
410 slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_8KHZ;
411 break;
412 }
413 pr_debug("%s: sample rates: slim7_rx = %d, slim7_tx = %d, value = %d\n",
414 __func__,
415 slim_rx_cfg[SLIM_RX_7].sample_rate,
416 slim_tx_cfg[SLIM_TX_7].sample_rate,
417 ucontrol->value.enumerated.item[0]);
418
419 return 0;
420}
421
Preetam Singh Ranawatd79190a2018-06-25 15:59:23 +0530422static int msm_bt_sample_rate_rx_get(struct snd_kcontrol *kcontrol,
423 struct snd_ctl_elem_value *ucontrol)
424{
425 switch (slim_rx_cfg[SLIM_RX_7].sample_rate) {
426 case SAMPLING_RATE_96KHZ:
427 ucontrol->value.integer.value[0] = 5;
428 break;
429 case SAMPLING_RATE_88P2KHZ:
430 ucontrol->value.integer.value[0] = 4;
431 break;
432 case SAMPLING_RATE_48KHZ:
433 ucontrol->value.integer.value[0] = 3;
434 break;
435 case SAMPLING_RATE_44P1KHZ:
436 ucontrol->value.integer.value[0] = 2;
437 break;
438 case SAMPLING_RATE_16KHZ:
439 ucontrol->value.integer.value[0] = 1;
440 break;
441 case SAMPLING_RATE_8KHZ:
442 default:
443 ucontrol->value.integer.value[0] = 0;
444 break;
445 }
446 pr_debug("%s: sample rate = %d", __func__,
447 slim_rx_cfg[SLIM_RX_7].sample_rate);
448
449 return 0;
450}
451
452static int msm_bt_sample_rate_rx_put(struct snd_kcontrol *kcontrol,
453 struct snd_ctl_elem_value *ucontrol)
454{
455 switch (ucontrol->value.integer.value[0]) {
456 case 1:
457 slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_16KHZ;
458 break;
459 case 2:
460 slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_44P1KHZ;
461 break;
462 case 3:
463 slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_48KHZ;
464 break;
465 case 4:
466 slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_88P2KHZ;
467 break;
468 case 5:
469 slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_96KHZ;
470 break;
471 case 0:
472 default:
473 slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_8KHZ;
474 break;
475 }
476 pr_debug("%s: sample rates: slim7_rx = %d, value = %d\n",
477 __func__,
478 slim_rx_cfg[SLIM_RX_7].sample_rate,
479 ucontrol->value.enumerated.item[0]);
480
481 return 0;
482}
483
484static int msm_bt_sample_rate_tx_get(struct snd_kcontrol *kcontrol,
485 struct snd_ctl_elem_value *ucontrol)
486{
487 switch (slim_tx_cfg[SLIM_TX_7].sample_rate) {
488 case SAMPLING_RATE_96KHZ:
489 ucontrol->value.integer.value[0] = 5;
490 break;
491 case SAMPLING_RATE_88P2KHZ:
492 ucontrol->value.integer.value[0] = 4;
493 break;
494 case SAMPLING_RATE_48KHZ:
495 ucontrol->value.integer.value[0] = 3;
496 break;
497 case SAMPLING_RATE_44P1KHZ:
498 ucontrol->value.integer.value[0] = 2;
499 break;
500 case SAMPLING_RATE_16KHZ:
501 ucontrol->value.integer.value[0] = 1;
502 break;
503 case SAMPLING_RATE_8KHZ:
504 default:
505 ucontrol->value.integer.value[0] = 0;
506 break;
507 }
508 pr_debug("%s: sample rate = %d", __func__,
509 slim_tx_cfg[SLIM_TX_7].sample_rate);
510
511 return 0;
512}
513
514static int msm_bt_sample_rate_tx_put(struct snd_kcontrol *kcontrol,
515 struct snd_ctl_elem_value *ucontrol)
516{
517 switch (ucontrol->value.integer.value[0]) {
518 case 1:
519 slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_16KHZ;
520 break;
521 case 2:
522 slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_44P1KHZ;
523 break;
524 case 3:
525 slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_48KHZ;
526 break;
527 case 4:
528 slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_88P2KHZ;
529 break;
530 case 5:
531 slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_96KHZ;
532 break;
533 case 0:
534 default:
535 slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_8KHZ;
536 break;
537 }
538 pr_debug("%s: sample rates: slim7_tx = %d, value = %d\n",
539 __func__,
540 slim_tx_cfg[SLIM_TX_7].sample_rate,
541 ucontrol->value.enumerated.item[0]);
542
543 return 0;
544}
545
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530546static int slim_rx_sample_rate_get(struct snd_kcontrol *kcontrol,
547 struct snd_ctl_elem_value *ucontrol)
548{
549 int ch_num = slim_get_port_idx(kcontrol);
550
551 if (ch_num < 0)
552 return ch_num;
553
554 ucontrol->value.enumerated.item[0] =
555 slim_get_sample_rate_val(slim_rx_cfg[ch_num].sample_rate);
556
557 pr_debug("%s: slim[%d]_rx_sample_rate = %d, item = %d\n", __func__,
558 ch_num, slim_rx_cfg[ch_num].sample_rate,
559 ucontrol->value.enumerated.item[0]);
560
561 return 0;
562}
563
564static int slim_rx_sample_rate_put(struct snd_kcontrol *kcontrol,
565 struct snd_ctl_elem_value *ucontrol)
566{
567 int ch_num = slim_get_port_idx(kcontrol);
568
569 if (ch_num < 0)
570 return ch_num;
571
572 slim_rx_cfg[ch_num].sample_rate =
573 slim_get_sample_rate(ucontrol->value.enumerated.item[0]);
574
575 pr_debug("%s: slim[%d]_rx_sample_rate = %d, item = %d\n", __func__,
576 ch_num, slim_rx_cfg[ch_num].sample_rate,
577 ucontrol->value.enumerated.item[0]);
578
579 return 0;
580}
581
582static int slim_tx_sample_rate_get(struct snd_kcontrol *kcontrol,
583 struct snd_ctl_elem_value *ucontrol)
584{
585 int ch_num = slim_get_port_idx(kcontrol);
586
587 if (ch_num < 0)
588 return ch_num;
589
590 ucontrol->value.enumerated.item[0] =
591 slim_get_sample_rate_val(slim_tx_cfg[ch_num].sample_rate);
592
593 pr_debug("%s: slim[%d]_tx_sample_rate = %d, item = %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_tx_sample_rate_put(struct snd_kcontrol *kcontrol,
601 struct snd_ctl_elem_value *ucontrol)
602{
603 int sample_rate = 0;
604 int ch_num = slim_get_port_idx(kcontrol);
605
606 if (ch_num < 0)
607 return ch_num;
608
609 sample_rate = slim_get_sample_rate(ucontrol->value.enumerated.item[0]);
610 if (sample_rate == SAMPLING_RATE_44P1KHZ) {
611 pr_err("%s: Unsupported sample rate %d: for Tx path\n",
612 __func__, sample_rate);
613 return -EINVAL;
614 }
615 slim_tx_cfg[ch_num].sample_rate = sample_rate;
616
617 pr_debug("%s: slim[%d]_tx_sample_rate = %d, value = %d\n", __func__,
618 ch_num, slim_tx_cfg[ch_num].sample_rate,
619 ucontrol->value.enumerated.item[0]);
620
621 return 0;
622}
623
624static int slim_rx_bit_format_get(struct snd_kcontrol *kcontrol,
625 struct snd_ctl_elem_value *ucontrol)
626{
627 int ch_num = slim_get_port_idx(kcontrol);
628
629 if (ch_num < 0)
630 return ch_num;
631
632 ucontrol->value.enumerated.item[0] =
633 slim_get_bit_format_val(slim_rx_cfg[ch_num].bit_format);
634
635 pr_debug("%s: slim[%d]_rx_bit_format = %d, ucontrol value = %d\n",
636 __func__, ch_num, slim_rx_cfg[ch_num].bit_format,
637 ucontrol->value.enumerated.item[0]);
638
639 return 0;
640}
641
642static int slim_rx_bit_format_put(struct snd_kcontrol *kcontrol,
643 struct snd_ctl_elem_value *ucontrol)
644{
645 int ch_num = slim_get_port_idx(kcontrol);
646
647 if (ch_num < 0)
648 return ch_num;
649
650 slim_rx_cfg[ch_num].bit_format =
651 slim_get_bit_format(ucontrol->value.enumerated.item[0]);
652
653 pr_debug("%s: slim[%d]_rx_bit_format = %d, ucontrol value = %d\n",
654 __func__, ch_num, slim_rx_cfg[ch_num].bit_format,
655 ucontrol->value.enumerated.item[0]);
656
657 return 0;
658}
659
660static int slim_tx_bit_format_get(struct snd_kcontrol *kcontrol,
661 struct snd_ctl_elem_value *ucontrol)
662{
663 int ch_num = slim_get_port_idx(kcontrol);
664
665 if (ch_num < 0)
666 return ch_num;
667
668 ucontrol->value.enumerated.item[0] =
669 slim_get_bit_format_val(slim_tx_cfg[ch_num].bit_format);
670
671 pr_debug("%s: slim[%d]_tx_bit_format = %d, ucontrol value = %d\n",
672 __func__, ch_num, slim_tx_cfg[ch_num].bit_format,
673 ucontrol->value.enumerated.item[0]);
674
675 return 0;
676}
677
678static int slim_tx_bit_format_put(struct snd_kcontrol *kcontrol,
679 struct snd_ctl_elem_value *ucontrol)
680{
681 int ch_num = slim_get_port_idx(kcontrol);
682
683 if (ch_num < 0)
684 return ch_num;
685
686 slim_tx_cfg[ch_num].bit_format =
687 slim_get_bit_format(ucontrol->value.enumerated.item[0]);
688
689 pr_debug("%s: slim[%d]_tx_bit_format = %d, ucontrol value = %d\n",
690 __func__, ch_num, slim_tx_cfg[ch_num].bit_format,
691 ucontrol->value.enumerated.item[0]);
692
693 return 0;
694}
695
696static int msm_slim_rx_ch_get(struct snd_kcontrol *kcontrol,
697 struct snd_ctl_elem_value *ucontrol)
698{
699 int ch_num = slim_get_port_idx(kcontrol);
700
701 if (ch_num < 0)
702 return ch_num;
703
704 pr_debug("%s: msm_slim_[%d]_rx_ch = %d\n", __func__,
705 ch_num, slim_rx_cfg[ch_num].channels);
706 ucontrol->value.enumerated.item[0] = slim_rx_cfg[ch_num].channels - 1;
707
708 return 0;
709}
710
711static int msm_slim_rx_ch_put(struct snd_kcontrol *kcontrol,
712 struct snd_ctl_elem_value *ucontrol)
713{
714 int ch_num = slim_get_port_idx(kcontrol);
715
716 if (ch_num < 0)
717 return ch_num;
718
719 slim_rx_cfg[ch_num].channels = ucontrol->value.enumerated.item[0] + 1;
720 pr_debug("%s: msm_slim_[%d]_rx_ch = %d\n", __func__,
721 ch_num, slim_rx_cfg[ch_num].channels);
722
723 return 1;
724}
725
726static int msm_slim_tx_ch_get(struct snd_kcontrol *kcontrol,
727 struct snd_ctl_elem_value *ucontrol)
728{
729 int ch_num = slim_get_port_idx(kcontrol);
730
731 if (ch_num < 0)
732 return ch_num;
733
734 pr_debug("%s: msm_slim_[%d]_tx_ch = %d\n", __func__,
735 ch_num, slim_tx_cfg[ch_num].channels);
736 ucontrol->value.enumerated.item[0] = slim_tx_cfg[ch_num].channels - 1;
737
738 return 0;
739}
740
741static int msm_slim_tx_ch_put(struct snd_kcontrol *kcontrol,
742 struct snd_ctl_elem_value *ucontrol)
743{
744 int ch_num = slim_get_port_idx(kcontrol);
745
746 if (ch_num < 0)
747 return ch_num;
748
749 slim_tx_cfg[ch_num].channels = ucontrol->value.enumerated.item[0] + 1;
750 pr_debug("%s: msm_slim_[%d]_tx_ch = %d\n", __func__,
751 ch_num, slim_tx_cfg[ch_num].channels);
752
753 return 1;
754}
755
756static int msm_vi_feed_tx_ch_get(struct snd_kcontrol *kcontrol,
757 struct snd_ctl_elem_value *ucontrol)
758{
759 ucontrol->value.integer.value[0] = msm_vi_feed_tx_ch - 1;
760 pr_debug("%s: msm_vi_feed_tx_ch = %ld\n", __func__,
761 ucontrol->value.integer.value[0]);
762 return 0;
763}
764
765static int msm_vi_feed_tx_ch_put(struct snd_kcontrol *kcontrol,
766 struct snd_ctl_elem_value *ucontrol)
767{
768 msm_vi_feed_tx_ch = ucontrol->value.integer.value[0] + 1;
769
770 pr_debug("%s: msm_vi_feed_tx_ch = %d\n", __func__, msm_vi_feed_tx_ch);
771 return 1;
772}
773
Dhanalakshmi Siddani7ce33bb2018-11-28 22:01:53 +0530774static int msm_hifi_ctrl(struct snd_soc_codec *codec)
775{
776 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
777 struct snd_soc_card *card = codec->component.card;
778 struct msm_asoc_mach_data *pdata =
779 snd_soc_card_get_drvdata(card);
780
781 pr_debug("%s: msm_hifi_control = %d\n", __func__,
782 msm_hifi_control);
783
784 if (!pdata || !pdata->hph_en1_gpio_p) {
785 pr_err("%s: hph_en1_gpio is invalid\n", __func__);
786 return -EINVAL;
787 }
788 if (msm_hifi_control == MSM_HIFI_ON) {
789 msm_cdc_pinctrl_select_active_state(pdata->hph_en1_gpio_p);
790 /* 5msec delay needed as per HW requirement */
791 usleep_range(5000, 5010);
792 } else {
793 msm_cdc_pinctrl_select_sleep_state(pdata->hph_en1_gpio_p);
794 }
795 snd_soc_dapm_sync(dapm);
796
797 return 0;
798}
799
800static int msm_hifi_get(struct snd_kcontrol *kcontrol,
801 struct snd_ctl_elem_value *ucontrol)
802{
803 pr_debug("%s: msm_hifi_control = %d\n",
804 __func__, msm_hifi_control);
805 ucontrol->value.integer.value[0] = msm_hifi_control;
806
807 return 0;
808}
809
810static int msm_hifi_put(struct snd_kcontrol *kcontrol,
811 struct snd_ctl_elem_value *ucontrol)
812{
813 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
814
815 pr_debug("%s() ucontrol->value.integer.value[0] = %ld\n",
816 __func__, ucontrol->value.integer.value[0]);
817
818 msm_hifi_control = ucontrol->value.integer.value[0];
819 msm_hifi_ctrl(codec);
820
821 return 0;
822}
823
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530824static void *def_ext_mbhc_cal(void)
825{
Laxminath Kasam38070be2017-08-17 18:21:59 +0530826 void *wcd_mbhc_cal;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530827 struct wcd_mbhc_btn_detect_cfg *btn_cfg;
828 u16 *btn_high;
829
Laxminath Kasam38070be2017-08-17 18:21:59 +0530830 wcd_mbhc_cal = kzalloc(WCD_MBHC_CAL_SIZE(WCD_MBHC_DEF_BUTTONS,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530831 WCD9XXX_MBHC_DEF_RLOADS), GFP_KERNEL);
Laxminath Kasam38070be2017-08-17 18:21:59 +0530832 if (!wcd_mbhc_cal)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530833 return NULL;
834
Laxminath Kasam38070be2017-08-17 18:21:59 +0530835#define S(X, Y) ((WCD_MBHC_CAL_PLUG_TYPE_PTR(wcd_mbhc_cal)->X) = (Y))
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530836 S(v_hs_max, 1600);
837#undef S
Laxminath Kasam38070be2017-08-17 18:21:59 +0530838#define S(X, Y) ((WCD_MBHC_CAL_BTN_DET_PTR(wcd_mbhc_cal)->X) = (Y))
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530839 S(num_btn, WCD_MBHC_DEF_BUTTONS);
840#undef S
841
Laxminath Kasam38070be2017-08-17 18:21:59 +0530842 btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(wcd_mbhc_cal);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530843 btn_high = ((void *)&btn_cfg->_v_btn_low) +
844 (sizeof(btn_cfg->_v_btn_low[0]) * btn_cfg->num_btn);
845
846 btn_high[0] = 75;
847 btn_high[1] = 150;
848 btn_high[2] = 237;
849 btn_high[3] = 500;
850 btn_high[4] = 500;
851 btn_high[5] = 500;
852 btn_high[6] = 500;
853 btn_high[7] = 500;
854
Laxminath Kasam38070be2017-08-17 18:21:59 +0530855 return wcd_mbhc_cal;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530856}
857
858static inline int param_is_mask(int p)
859{
860 return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) &&
861 (p <= SNDRV_PCM_HW_PARAM_LAST_MASK);
862}
863
864static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p, int n)
865{
866 return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]);
867}
868
869
870static void msm_ext_control(struct snd_soc_codec *codec)
871{
872 struct snd_soc_dapm_context *dapm =
873 snd_soc_codec_get_dapm(codec);
874
875 pr_debug("%s: msm_ext_spk_control = %d", __func__, msm_ext_spk_control);
876 if (msm_ext_spk_control == SDM660_SPK_ON) {
877 snd_soc_dapm_enable_pin(dapm, "Lineout_1 amp");
878 snd_soc_dapm_enable_pin(dapm, "Lineout_3 amp");
879 } else {
880 snd_soc_dapm_disable_pin(dapm, "Lineout_1 amp");
881 snd_soc_dapm_disable_pin(dapm, "Lineout_3 amp");
882 }
883 snd_soc_dapm_sync(dapm);
884}
885
886static int msm_ext_get_spk(struct snd_kcontrol *kcontrol,
887 struct snd_ctl_elem_value *ucontrol)
888{
889 pr_debug("%s: msm_ext_spk_control = %d\n",
890 __func__, msm_ext_spk_control);
891 ucontrol->value.integer.value[0] = msm_ext_spk_control;
892 return 0;
893}
894
895static int msm_ext_set_spk(struct snd_kcontrol *kcontrol,
896 struct snd_ctl_elem_value *ucontrol)
897{
898 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
899
900 pr_debug("%s()\n", __func__);
901 if (msm_ext_spk_control == ucontrol->value.integer.value[0])
902 return 0;
903
904 msm_ext_spk_control = ucontrol->value.integer.value[0];
905 msm_ext_control(codec);
906 return 1;
907}
908
909
910int msm_ext_enable_codec_mclk(struct snd_soc_codec *codec, int enable,
911 bool dapm)
912{
913 int ret;
914
915 pr_debug("%s: enable = %d\n", __func__, enable);
916
917 if (!strcmp(dev_name(codec->dev), "tasha_codec"))
918 ret = tasha_cdc_mclk_enable(codec, enable, dapm);
919 else if (!strcmp(dev_name(codec->dev), "tavil_codec"))
920 ret = tavil_cdc_mclk_enable(codec, enable);
921 else {
922 dev_err(codec->dev, "%s: unknown codec to enable ext clk\n",
923 __func__);
924 ret = -EINVAL;
925 }
926 return ret;
927}
928
929static const struct snd_kcontrol_new msm_snd_controls[] = {
930 SOC_ENUM_EXT("Speaker Function", spk_func_en, msm_ext_get_spk,
931 msm_ext_set_spk),
932 SOC_ENUM_EXT("SLIM_0_RX Channels", slim_0_rx_chs,
933 msm_slim_rx_ch_get, msm_slim_rx_ch_put),
934 SOC_ENUM_EXT("SLIM_2_RX Channels", slim_2_rx_chs,
935 msm_slim_rx_ch_get, msm_slim_rx_ch_put),
936 SOC_ENUM_EXT("SLIM_0_TX Channels", slim_0_tx_chs,
937 msm_slim_tx_ch_get, msm_slim_tx_ch_put),
938 SOC_ENUM_EXT("SLIM_1_TX Channels", slim_1_tx_chs,
939 msm_slim_tx_ch_get, msm_slim_tx_ch_put),
940 SOC_ENUM_EXT("SLIM_5_RX Channels", slim_5_rx_chs,
941 msm_slim_rx_ch_get, msm_slim_rx_ch_put),
942 SOC_ENUM_EXT("SLIM_6_RX Channels", slim_6_rx_chs,
943 msm_slim_rx_ch_get, msm_slim_rx_ch_put),
944 SOC_ENUM_EXT("VI_FEED_TX Channels", vi_feed_tx_chs,
945 msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put),
946 SOC_ENUM_EXT("SLIM_0_RX Format", slim_0_rx_format,
947 slim_rx_bit_format_get, slim_rx_bit_format_put),
948 SOC_ENUM_EXT("SLIM_5_RX Format", slim_5_rx_format,
949 slim_rx_bit_format_get, slim_rx_bit_format_put),
950 SOC_ENUM_EXT("SLIM_6_RX Format", slim_6_rx_format,
951 slim_rx_bit_format_get, slim_rx_bit_format_put),
952 SOC_ENUM_EXT("SLIM_0_TX Format", slim_0_tx_format,
953 slim_tx_bit_format_get, slim_tx_bit_format_put),
954 SOC_ENUM_EXT("SLIM_0_RX SampleRate", slim_0_rx_sample_rate,
955 slim_rx_sample_rate_get, slim_rx_sample_rate_put),
956 SOC_ENUM_EXT("SLIM_2_RX SampleRate", slim_2_rx_sample_rate,
957 slim_rx_sample_rate_get, slim_rx_sample_rate_put),
958 SOC_ENUM_EXT("SLIM_0_TX SampleRate", slim_0_tx_sample_rate,
959 slim_tx_sample_rate_get, slim_tx_sample_rate_put),
960 SOC_ENUM_EXT("SLIM_5_RX SampleRate", slim_5_rx_sample_rate,
961 slim_rx_sample_rate_get, slim_rx_sample_rate_put),
962 SOC_ENUM_EXT("SLIM_6_RX SampleRate", slim_6_rx_sample_rate,
963 slim_rx_sample_rate_get, slim_rx_sample_rate_put),
964 SOC_ENUM_EXT("BT SampleRate", bt_sample_rate,
965 msm_bt_sample_rate_get,
966 msm_bt_sample_rate_put),
Preetam Singh Ranawatd79190a2018-06-25 15:59:23 +0530967 SOC_ENUM_EXT("BT SampleRate RX", bt_sample_rate_rx,
968 msm_bt_sample_rate_rx_get,
969 msm_bt_sample_rate_rx_put),
970 SOC_ENUM_EXT("BT SampleRate TX", bt_sample_rate_tx,
971 msm_bt_sample_rate_tx_get,
972 msm_bt_sample_rate_tx_put),
Dhanalakshmi Siddani7ce33bb2018-11-28 22:01:53 +0530973 SOC_ENUM_EXT("HiFi Function", hifi_function, msm_hifi_get,
974 msm_hifi_put),
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530975};
976
Asish Bhattacharya84f7f732017-07-25 16:29:27 +0530977static int msm_slim_get_ch_from_beid(int32_t id)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530978{
979 int ch_id = 0;
980
Asish Bhattacharya84f7f732017-07-25 16:29:27 +0530981 switch (id) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530982 case MSM_BACKEND_DAI_SLIMBUS_0_RX:
983 ch_id = SLIM_RX_0;
984 break;
985 case MSM_BACKEND_DAI_SLIMBUS_1_RX:
986 ch_id = SLIM_RX_1;
987 break;
988 case MSM_BACKEND_DAI_SLIMBUS_2_RX:
989 ch_id = SLIM_RX_2;
990 break;
991 case MSM_BACKEND_DAI_SLIMBUS_3_RX:
992 ch_id = SLIM_RX_3;
993 break;
994 case MSM_BACKEND_DAI_SLIMBUS_4_RX:
995 ch_id = SLIM_RX_4;
996 break;
997 case MSM_BACKEND_DAI_SLIMBUS_6_RX:
998 ch_id = SLIM_RX_6;
999 break;
1000 case MSM_BACKEND_DAI_SLIMBUS_0_TX:
1001 ch_id = SLIM_TX_0;
1002 break;
1003 case MSM_BACKEND_DAI_SLIMBUS_3_TX:
1004 ch_id = SLIM_TX_3;
1005 break;
1006 default:
1007 ch_id = SLIM_RX_0;
1008 break;
1009 }
1010
1011 return ch_id;
1012}
1013
1014static void param_set_mask(struct snd_pcm_hw_params *p, int n, unsigned int bit)
1015{
1016 if (bit >= SNDRV_MASK_MAX)
1017 return;
1018 if (param_is_mask(n)) {
1019 struct snd_mask *m = param_to_mask(p, n);
1020
1021 m->bits[0] = 0;
1022 m->bits[1] = 0;
1023 m->bits[bit >> 5] |= (1 << (bit & 31));
1024 }
1025}
1026
1027/**
1028 * msm_ext_be_hw_params_fixup - updates settings of ALSA BE hw params.
1029 *
1030 * @rtd: runtime dailink instance
1031 * @params: HW params of associated backend dailink.
1032 *
1033 * Returns 0 on success or rc on failure.
1034 */
1035int msm_ext_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
1036 struct snd_pcm_hw_params *params)
1037{
1038 struct snd_soc_dai_link *dai_link = rtd->dai_link;
1039 struct snd_interval *rate = hw_param_interval(params,
1040 SNDRV_PCM_HW_PARAM_RATE);
1041 struct snd_interval *channels = hw_param_interval(params,
1042 SNDRV_PCM_HW_PARAM_CHANNELS);
1043 int rc = 0;
1044 int idx;
1045 void *config = NULL;
1046 struct snd_soc_codec *codec = rtd->codec;
1047
1048 pr_debug("%s: format = %d, rate = %d\n",
1049 __func__, params_format(params), params_rate(params));
1050
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05301051 switch (dai_link->id) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301052 case MSM_BACKEND_DAI_SLIMBUS_0_RX:
1053 case MSM_BACKEND_DAI_SLIMBUS_1_RX:
1054 case MSM_BACKEND_DAI_SLIMBUS_2_RX:
1055 case MSM_BACKEND_DAI_SLIMBUS_3_RX:
1056 case MSM_BACKEND_DAI_SLIMBUS_4_RX:
1057 case MSM_BACKEND_DAI_SLIMBUS_6_RX:
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05301058 idx = msm_slim_get_ch_from_beid(dai_link->id);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301059 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
1060 slim_rx_cfg[idx].bit_format);
1061 rate->min = rate->max = slim_rx_cfg[idx].sample_rate;
1062 channels->min = channels->max = slim_rx_cfg[idx].channels;
1063 break;
1064
1065 case MSM_BACKEND_DAI_SLIMBUS_0_TX:
1066 case MSM_BACKEND_DAI_SLIMBUS_3_TX:
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05301067 idx = msm_slim_get_ch_from_beid(dai_link->id);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301068 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
1069 slim_tx_cfg[idx].bit_format);
1070 rate->min = rate->max = slim_tx_cfg[idx].sample_rate;
1071 channels->min = channels->max = slim_tx_cfg[idx].channels;
1072 break;
1073
1074 case MSM_BACKEND_DAI_SLIMBUS_1_TX:
1075 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
1076 slim_tx_cfg[1].bit_format);
1077 rate->min = rate->max = slim_tx_cfg[1].sample_rate;
1078 channels->min = channels->max = slim_tx_cfg[1].channels;
1079 break;
1080
1081 case MSM_BACKEND_DAI_SLIMBUS_4_TX:
1082 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
1083 SNDRV_PCM_FORMAT_S32_LE);
1084 rate->min = rate->max = SAMPLING_RATE_8KHZ;
1085 channels->min = channels->max = msm_vi_feed_tx_ch;
1086 break;
1087
1088 case MSM_BACKEND_DAI_SLIMBUS_5_RX:
1089 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
1090 slim_rx_cfg[5].bit_format);
1091 rate->min = rate->max = slim_rx_cfg[5].sample_rate;
1092 channels->min = channels->max = slim_rx_cfg[5].channels;
1093 break;
1094
1095 case MSM_BACKEND_DAI_SLIMBUS_5_TX:
1096 rate->min = rate->max = SAMPLING_RATE_16KHZ;
1097 channels->min = channels->max = 1;
1098
1099 config = msm_codec_fn.get_afe_config_fn(codec,
1100 AFE_SLIMBUS_SLAVE_PORT_CONFIG);
1101 if (config) {
1102 rc = afe_set_config(AFE_SLIMBUS_SLAVE_PORT_CONFIG,
1103 config, SLIMBUS_5_TX);
1104 if (rc)
1105 pr_err("%s: Failed to set slimbus slave port config %d\n",
1106 __func__, rc);
1107 }
1108 break;
1109
1110 case MSM_BACKEND_DAI_SLIMBUS_7_RX:
1111 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
1112 slim_rx_cfg[SLIM_RX_7].bit_format);
1113 rate->min = rate->max = slim_rx_cfg[SLIM_RX_7].sample_rate;
1114 channels->min = channels->max =
1115 slim_rx_cfg[SLIM_RX_7].channels;
1116 break;
1117
1118 case MSM_BACKEND_DAI_SLIMBUS_7_TX:
1119 rate->min = rate->max = slim_tx_cfg[SLIM_TX_7].sample_rate;
1120 channels->min = channels->max =
1121 slim_tx_cfg[SLIM_TX_7].channels;
1122 break;
1123
1124 case MSM_BACKEND_DAI_SLIMBUS_8_TX:
1125 rate->min = rate->max = slim_tx_cfg[SLIM_TX_8].sample_rate;
1126 channels->min = channels->max =
1127 slim_tx_cfg[SLIM_TX_8].channels;
1128 break;
1129
1130 default:
1131 rate->min = rate->max = SAMPLING_RATE_48KHZ;
1132 break;
1133 }
1134 return rc;
1135}
1136EXPORT_SYMBOL(msm_ext_be_hw_params_fixup);
1137
1138/**
1139 * msm_snd_hw_params - hw params ops of backend dailink.
1140 *
1141 * @substream: PCM stream of associated backend dailink.
1142 * @params: HW params of associated backend dailink.
1143 *
1144 * Returns 0 on success or ret on failure.
1145 */
1146int msm_snd_hw_params(struct snd_pcm_substream *substream,
1147 struct snd_pcm_hw_params *params)
1148{
1149 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1150 struct snd_soc_dai *codec_dai = rtd->codec_dai;
1151 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1152 struct snd_soc_dai_link *dai_link = rtd->dai_link;
1153
1154 int ret = 0;
1155 u32 rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS];
1156 u32 rx_ch_cnt = 0, tx_ch_cnt = 0;
1157 u32 user_set_tx_ch = 0;
1158 u32 rx_ch_count;
1159
1160 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1161 ret = snd_soc_dai_get_channel_map(codec_dai,
1162 &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch);
1163 if (ret < 0) {
1164 pr_err("%s: failed to get codec chan map, err:%d\n",
1165 __func__, ret);
1166 goto err_ch_map;
1167 }
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05301168 if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_5_RX) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301169 pr_debug("%s: rx_5_ch=%d\n", __func__,
1170 slim_rx_cfg[5].channels);
1171 rx_ch_count = slim_rx_cfg[5].channels;
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05301172 } else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_2_RX) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301173 pr_debug("%s: rx_2_ch=%d\n", __func__,
1174 slim_rx_cfg[2].channels);
1175 rx_ch_count = slim_rx_cfg[2].channels;
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05301176 } else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_6_RX) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301177 pr_debug("%s: rx_6_ch=%d\n", __func__,
1178 slim_rx_cfg[6].channels);
1179 rx_ch_count = slim_rx_cfg[6].channels;
1180 } else {
1181 pr_debug("%s: rx_0_ch=%d\n", __func__,
1182 slim_rx_cfg[0].channels);
1183 rx_ch_count = slim_rx_cfg[0].channels;
1184 }
1185 ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0,
1186 rx_ch_count, rx_ch);
1187 if (ret < 0) {
1188 pr_err("%s: failed to set cpu chan map, err:%d\n",
1189 __func__, ret);
1190 goto err_ch_map;
1191 }
1192 } else {
1193 pr_debug("%s: %s_tx_dai_id_%d_ch=%d\n", __func__,
1194 codec_dai->name, codec_dai->id, user_set_tx_ch);
1195 ret = snd_soc_dai_get_channel_map(codec_dai,
1196 &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch);
1197 if (ret < 0) {
1198 pr_err("%s: failed to get codec chan map\n, err:%d\n",
1199 __func__, ret);
1200 goto err_ch_map;
1201 }
1202 /* For <codec>_tx1 case */
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05301203 if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_0_TX)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301204 user_set_tx_ch = slim_tx_cfg[0].channels;
1205 /* For <codec>_tx3 case */
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05301206 else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_1_TX)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301207 user_set_tx_ch = slim_tx_cfg[1].channels;
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05301208 else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_4_TX)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301209 user_set_tx_ch = msm_vi_feed_tx_ch;
1210 else
1211 user_set_tx_ch = tx_ch_cnt;
1212
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05301213 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 +05301214 __func__, slim_tx_cfg[0].channels, user_set_tx_ch,
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05301215 tx_ch_cnt, dai_link->id);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301216
1217 ret = snd_soc_dai_set_channel_map(cpu_dai,
1218 user_set_tx_ch, tx_ch, 0, 0);
1219 if (ret < 0)
1220 pr_err("%s: failed to set cpu chan map, err:%d\n",
1221 __func__, ret);
1222 }
1223
1224err_ch_map:
1225 return ret;
1226}
1227EXPORT_SYMBOL(msm_snd_hw_params);
1228
1229/**
1230 * msm_ext_slimbus_2_hw_params - hw params ops of slimbus_2 BE.
1231 *
1232 * @substream: PCM stream of associated backend dailink.
1233 * @params: HW params of associated backend dailink.
1234 *
1235 * Returns 0 on success or ret on failure.
1236 */
1237int msm_ext_slimbus_2_hw_params(struct snd_pcm_substream *substream,
1238 struct snd_pcm_hw_params *params)
1239{
1240 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1241 struct snd_soc_dai *codec_dai = rtd->codec_dai;
1242 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1243 int ret = 0;
1244 unsigned int rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS];
1245 unsigned int rx_ch_cnt = 0, tx_ch_cnt = 0;
1246 unsigned int num_tx_ch = 0;
1247 unsigned int num_rx_ch = 0;
1248
1249 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1250 num_rx_ch = params_channels(params);
1251 pr_debug("%s: %s rx_dai_id = %d num_ch = %d\n", __func__,
1252 codec_dai->name, codec_dai->id, num_rx_ch);
1253 ret = snd_soc_dai_get_channel_map(codec_dai,
1254 &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch);
1255 if (ret < 0) {
1256 pr_err("%s: failed to get codec chan map, err:%d\n",
1257 __func__, ret);
1258 goto end;
1259 }
1260 ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0,
1261 num_rx_ch, rx_ch);
1262 if (ret < 0) {
1263 pr_err("%s: failed to set cpu chan map, err:%d\n",
1264 __func__, ret);
1265 goto end;
1266 }
1267 } else {
1268 num_tx_ch = params_channels(params);
1269 pr_debug("%s: %s tx_dai_id = %d num_ch = %d\n", __func__,
1270 codec_dai->name, codec_dai->id, num_tx_ch);
1271 ret = snd_soc_dai_get_channel_map(codec_dai,
1272 &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch);
1273 if (ret < 0) {
1274 pr_err("%s: failed to get codec chan map, err:%d\n",
1275 __func__, ret);
1276 goto end;
1277 }
1278 ret = snd_soc_dai_set_channel_map(cpu_dai,
1279 num_tx_ch, tx_ch, 0, 0);
1280 if (ret < 0) {
1281 pr_err("%s: failed to set cpu chan map, err:%d\n",
1282 __func__, ret);
1283 goto end;
1284 }
1285 }
1286end:
1287 return ret;
1288}
1289EXPORT_SYMBOL(msm_ext_slimbus_2_hw_params);
1290
1291/**
1292 * msm_snd_cpe_hw_params - hw params ops of CPE backend.
1293 *
1294 * @substream: PCM stream of associated backend dailink.
1295 * @params: HW params of associated backend dailink.
1296 *
1297 * Returns 0 on success or ret on failure.
1298 */
1299int msm_snd_cpe_hw_params(struct snd_pcm_substream *substream,
1300 struct snd_pcm_hw_params *params)
1301{
1302 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1303 struct snd_soc_dai *codec_dai = rtd->codec_dai;
1304 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1305 struct snd_soc_dai_link *dai_link = rtd->dai_link;
1306 int ret = 0;
1307 u32 tx_ch[SLIM_MAX_TX_PORTS];
1308 u32 tx_ch_cnt = 0;
1309
1310 if (substream->stream != SNDRV_PCM_STREAM_CAPTURE) {
1311 pr_err("%s: Invalid stream type %d\n",
1312 __func__, substream->stream);
1313 ret = -EINVAL;
1314 goto end;
1315 }
1316
1317 pr_debug("%s: %s_tx_dai_id_%d\n", __func__,
1318 codec_dai->name, codec_dai->id);
1319 ret = snd_soc_dai_get_channel_map(codec_dai,
1320 &tx_ch_cnt, tx_ch, NULL, NULL);
1321 if (ret < 0) {
1322 pr_err("%s: failed to get codec chan map\n, err:%d\n",
1323 __func__, ret);
1324 goto end;
1325 }
1326
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05301327 pr_debug("%s: tx_ch_cnt(%d) id %d\n",
1328 __func__, tx_ch_cnt, dai_link->id);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301329
1330 ret = snd_soc_dai_set_channel_map(cpu_dai,
1331 tx_ch_cnt, tx_ch, 0, 0);
1332 if (ret < 0) {
1333 pr_err("%s: failed to set cpu chan map, err:%d\n",
1334 __func__, ret);
1335 goto end;
1336 }
1337end:
1338 return ret;
1339}
1340EXPORT_SYMBOL(msm_snd_cpe_hw_params);
1341
1342static int msm_afe_set_config(struct snd_soc_codec *codec)
1343{
1344 int rc;
1345 void *config_data;
1346
1347 pr_debug("%s: enter\n", __func__);
1348
1349 if (!msm_codec_fn.get_afe_config_fn) {
1350 dev_err(codec->dev, "%s: codec get afe config not init'ed\n",
1351 __func__);
1352 return -EINVAL;
1353 }
1354 config_data = msm_codec_fn.get_afe_config_fn(codec,
1355 AFE_CDC_REGISTERS_CONFIG);
1356 if (config_data) {
1357 rc = afe_set_config(AFE_CDC_REGISTERS_CONFIG, config_data, 0);
1358 if (rc) {
1359 pr_err("%s: Failed to set codec registers config %d\n",
1360 __func__, rc);
1361 return rc;
1362 }
1363 }
1364
1365 config_data = msm_codec_fn.get_afe_config_fn(codec,
1366 AFE_CDC_REGISTER_PAGE_CONFIG);
1367 if (config_data) {
1368 rc = afe_set_config(AFE_CDC_REGISTER_PAGE_CONFIG, config_data,
1369 0);
1370 if (rc)
1371 pr_err("%s: Failed to set cdc register page config\n",
1372 __func__);
1373 }
1374
1375 config_data = msm_codec_fn.get_afe_config_fn(codec,
1376 AFE_SLIMBUS_SLAVE_CONFIG);
1377 if (config_data) {
1378 rc = afe_set_config(AFE_SLIMBUS_SLAVE_CONFIG, config_data, 0);
1379 if (rc) {
1380 pr_err("%s: Failed to set slimbus slave config %d\n",
1381 __func__, rc);
1382 return rc;
1383 }
1384 }
1385
1386 config_data = msm_codec_fn.get_afe_config_fn(codec,
1387 AFE_AANC_VERSION);
1388 if (config_data) {
1389 rc = afe_set_config(AFE_AANC_VERSION, config_data, 0);
1390 if (rc) {
1391 pr_err("%s: Failed to set AANC version %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_CLIP_REGISTERS_CONFIG);
1399 if (config_data) {
1400 rc = afe_set_config(AFE_CDC_CLIP_REGISTERS_CONFIG,
1401 config_data, 0);
1402 if (rc) {
1403 pr_err("%s: Failed to set clip registers %d\n",
1404 __func__, rc);
1405 return rc;
1406 }
1407 }
1408
1409 config_data = msm_codec_fn.get_afe_config_fn(codec,
1410 AFE_CLIP_BANK_SEL);
1411 if (config_data) {
1412 rc = afe_set_config(AFE_CLIP_BANK_SEL,
1413 config_data, 0);
1414 if (rc) {
1415 pr_err("%s: Failed to set AFE bank selection %d\n",
1416 __func__, rc);
1417 return rc;
1418 }
1419 }
1420
1421 config_data = msm_codec_fn.get_afe_config_fn(codec,
1422 AFE_CDC_REGISTER_PAGE_CONFIG);
1423 if (config_data) {
1424 rc = afe_set_config(AFE_CDC_REGISTER_PAGE_CONFIG, config_data,
1425 0);
1426 if (rc)
1427 pr_err("%s: Failed to set cdc register page config\n",
1428 __func__);
1429 }
1430
1431 return 0;
1432}
1433
1434static void msm_afe_clear_config(void)
1435{
1436 afe_clear_config(AFE_CDC_REGISTERS_CONFIG);
1437 afe_clear_config(AFE_SLIMBUS_SLAVE_CONFIG);
1438}
1439
Aditya Bavanarid61b84d2018-01-03 13:24:06 +05301440static int msm_adsp_power_up_config(struct snd_soc_codec *codec,
1441 struct snd_card *card)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301442{
1443 int ret = 0;
1444 unsigned long timeout;
1445 int adsp_ready = 0;
Aditya Bavanarid61b84d2018-01-03 13:24:06 +05301446 bool snd_card_online = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301447
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301448 timeout = jiffies +
1449 msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS);
1450
1451 do {
Aditya Bavanarid61b84d2018-01-03 13:24:06 +05301452 if (!snd_card_online) {
1453 snd_card_online = snd_card_is_online_state(card);
1454 pr_debug("%s: Sound card is %s\n", __func__,
1455 snd_card_online ? "Online" : "Offline");
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301456 }
Aditya Bavanarid61b84d2018-01-03 13:24:06 +05301457 if (!adsp_ready) {
1458 adsp_ready = q6core_is_adsp_ready();
1459 pr_debug("%s: ADSP Audio is %s\n", __func__,
1460 adsp_ready ? "ready" : "not ready");
1461 }
1462 if (snd_card_online && adsp_ready)
1463 break;
1464
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301465 /*
Aditya Bavanarid61b84d2018-01-03 13:24:06 +05301466 * Sound card/ADSP will be coming up after subsystem restart and
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301467 * it might not be fully up when the control reaches
1468 * here. So, wait for 50msec before checking ADSP state
1469 */
1470 msleep(50);
1471 } while (time_after(timeout, jiffies));
1472
Aditya Bavanarid61b84d2018-01-03 13:24:06 +05301473 if (!snd_card_online || !adsp_ready) {
1474 pr_err("%s: Timeout. Sound card is %s, ADSP Audio is %s\n",
1475 __func__,
1476 snd_card_online ? "Online" : "Offline",
1477 adsp_ready ? "ready" : "not ready");
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301478 ret = -ETIMEDOUT;
1479 goto err_fail;
1480 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301481
1482 ret = msm_afe_set_config(codec);
1483 if (ret)
1484 pr_err("%s: Failed to set AFE config. err %d\n",
1485 __func__, ret);
1486
1487 return 0;
1488
1489err_fail:
1490 return ret;
1491}
1492
1493static int sdm660_notifier_service_cb(struct notifier_block *this,
1494 unsigned long opcode, void *ptr)
1495{
1496 int ret;
1497 struct snd_soc_card *card = NULL;
1498 const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX;
1499 struct snd_soc_pcm_runtime *rtd;
1500 struct snd_soc_codec *codec;
1501
1502 pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode);
1503
1504 switch (opcode) {
1505 case AUDIO_NOTIFIER_SERVICE_DOWN:
1506 /*
1507 * Use flag to ignore initial boot notifications
1508 * On initial boot msm_adsp_power_up_config is
1509 * called on init. There is no need to clear
1510 * and set the config again on initial boot.
1511 */
1512 if (is_initial_boot)
1513 break;
1514 msm_afe_clear_config();
1515 break;
1516 case AUDIO_NOTIFIER_SERVICE_UP:
1517 if (is_initial_boot) {
1518 is_initial_boot = false;
1519 break;
1520 }
1521 if (!spdev)
1522 return -EINVAL;
1523
1524 card = platform_get_drvdata(spdev);
1525 rtd = snd_soc_get_pcm_runtime(card, be_dl_name);
1526 if (!rtd) {
1527 dev_err(card->dev,
1528 "%s: snd_soc_get_pcm_runtime for %s failed!\n",
1529 __func__, be_dl_name);
1530 ret = -EINVAL;
1531 goto done;
1532 }
1533 codec = rtd->codec;
1534
Aditya Bavanarid61b84d2018-01-03 13:24:06 +05301535 ret = msm_adsp_power_up_config(codec, card->snd_card);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301536 if (ret < 0) {
1537 dev_err(card->dev,
1538 "%s: msm_adsp_power_up_config failed ret = %d!\n",
1539 __func__, ret);
1540 goto done;
1541 }
1542 break;
1543 default:
1544 break;
1545 }
1546done:
1547 return NOTIFY_OK;
1548}
1549
1550static struct notifier_block service_nb = {
1551 .notifier_call = sdm660_notifier_service_cb,
1552 .priority = -INT_MAX,
1553};
1554
1555static int msm_config_hph_en0_gpio(struct snd_soc_codec *codec, bool high)
1556{
1557 struct snd_soc_card *card = codec->component.card;
1558 struct msm_asoc_mach_data *pdata;
1559 int val;
1560
1561 if (!card)
1562 return 0;
1563
1564 pdata = snd_soc_card_get_drvdata(card);
1565 if (!pdata || !gpio_is_valid(pdata->hph_en0_gpio))
1566 return 0;
1567
1568 val = gpio_get_value_cansleep(pdata->hph_en0_gpio);
1569 if ((!!val) == high)
1570 return 0;
1571
1572 gpio_direction_output(pdata->hph_en0_gpio, (int)high);
1573
1574 return 1;
1575}
1576
1577static int msm_snd_enable_codec_ext_tx_clk(struct snd_soc_codec *codec,
1578 int enable, bool dapm)
1579{
1580 int ret = 0;
1581
1582 if (!strcmp(dev_name(codec->dev), "tasha_codec"))
1583 ret = tasha_cdc_mclk_tx_enable(codec, enable, dapm);
1584 else {
1585 dev_err(codec->dev, "%s: unknown codec to enable ext clk\n",
1586 __func__);
1587 ret = -EINVAL;
1588 }
1589 return ret;
1590}
1591
1592static int msm_ext_mclk_tx_event(struct snd_soc_dapm_widget *w,
1593 struct snd_kcontrol *kcontrol, int event)
1594{
1595 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1596
1597 pr_debug("%s: event = %d\n", __func__, event);
1598
1599 switch (event) {
1600 case SND_SOC_DAPM_PRE_PMU:
1601 return msm_snd_enable_codec_ext_tx_clk(codec, 1, true);
1602 case SND_SOC_DAPM_POST_PMD:
1603 return msm_snd_enable_codec_ext_tx_clk(codec, 0, true);
1604 }
1605 return 0;
1606}
1607
1608static int msm_ext_mclk_event(struct snd_soc_dapm_widget *w,
1609 struct snd_kcontrol *kcontrol, int event)
1610{
1611 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1612
1613 pr_debug("%s: event = %d\n", __func__, event);
1614
1615 switch (event) {
1616 case SND_SOC_DAPM_PRE_PMU:
1617 return msm_ext_enable_codec_mclk(codec, 1, true);
1618 case SND_SOC_DAPM_POST_PMD:
1619 return msm_ext_enable_codec_mclk(codec, 0, true);
1620 }
1621 return 0;
1622}
1623
Dhanalakshmi Siddani7ce33bb2018-11-28 22:01:53 +05301624static int msm_hifi_ctrl_event(struct snd_soc_dapm_widget *w,
1625 struct snd_kcontrol *k, int event)
1626{
1627 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1628 struct snd_soc_card *card = codec->component.card;
1629 struct msm_asoc_mach_data *pdata =
1630 snd_soc_card_get_drvdata(card);
1631
1632 pr_debug("%s: msm_hifi_control = %d\n", __func__, msm_hifi_control);
1633
1634 if (!pdata || !pdata->hph_en0_gpio_p) {
1635 pr_err("%s: hph_en0_gpio is invalid\n", __func__);
1636 return -EINVAL;
1637 }
1638
1639 if (msm_hifi_control != MSM_HIFI_ON) {
1640 pr_debug("%s: HiFi mixer control is not set\n",
1641 __func__);
1642 return 0;
1643 }
1644
1645 switch (event) {
1646 case SND_SOC_DAPM_POST_PMU:
1647 msm_cdc_pinctrl_select_active_state(pdata->hph_en0_gpio_p);
1648 break;
1649 case SND_SOC_DAPM_PRE_PMD:
1650 msm_cdc_pinctrl_select_sleep_state(pdata->hph_en0_gpio_p);
1651 break;
1652 }
1653
1654 return 0;
1655}
1656
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301657static int msm_ext_prepare_hifi(struct msm_asoc_mach_data *pdata)
1658{
1659 int ret = 0;
1660
1661 if (gpio_is_valid(pdata->hph_en1_gpio)) {
1662 pr_debug("%s: hph_en1_gpio request %d\n", __func__,
1663 pdata->hph_en1_gpio);
1664 ret = gpio_request(pdata->hph_en1_gpio, "hph_en1_gpio");
1665 if (ret) {
1666 pr_err("%s: hph_en1_gpio request failed, ret:%d\n",
1667 __func__, ret);
1668 goto err;
1669 }
1670 }
1671 if (gpio_is_valid(pdata->hph_en0_gpio)) {
1672 pr_debug("%s: hph_en0_gpio request %d\n", __func__,
1673 pdata->hph_en0_gpio);
1674 ret = gpio_request(pdata->hph_en0_gpio, "hph_en0_gpio");
1675 if (ret)
1676 pr_err("%s: hph_en0_gpio request failed, ret:%d\n",
1677 __func__, ret);
1678 }
1679
1680err:
1681 return ret;
1682}
1683
1684static const struct snd_soc_dapm_widget msm_dapm_widgets[] = {
1685
1686 SND_SOC_DAPM_SUPPLY_S("MCLK", -1, SND_SOC_NOPM, 0, 0,
1687 msm_ext_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1688
1689 SND_SOC_DAPM_SUPPLY_S("MCLK TX", -1, SND_SOC_NOPM, 0, 0,
1690 msm_ext_mclk_tx_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1691
1692 SND_SOC_DAPM_SPK("Lineout_1 amp", NULL),
1693 SND_SOC_DAPM_SPK("Lineout_3 amp", NULL),
1694 SND_SOC_DAPM_SPK("Lineout_2 amp", NULL),
1695 SND_SOC_DAPM_SPK("Lineout_4 amp", NULL),
Dhanalakshmi Siddani7ce33bb2018-11-28 22:01:53 +05301696 SND_SOC_DAPM_SPK("hifi amp", msm_hifi_ctrl_event),
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301697 SND_SOC_DAPM_MIC("Handset Mic", NULL),
1698 SND_SOC_DAPM_MIC("Headset Mic", NULL),
1699 SND_SOC_DAPM_MIC("Secondary Mic", NULL),
1700 SND_SOC_DAPM_MIC("ANCRight Headset Mic", NULL),
1701 SND_SOC_DAPM_MIC("ANCLeft Headset Mic", NULL),
1702 SND_SOC_DAPM_MIC("Analog Mic4", NULL),
1703 SND_SOC_DAPM_MIC("Analog Mic6", NULL),
1704 SND_SOC_DAPM_MIC("Analog Mic7", NULL),
1705 SND_SOC_DAPM_MIC("Analog Mic8", NULL),
1706
1707 SND_SOC_DAPM_MIC("Digital Mic0", NULL),
1708 SND_SOC_DAPM_MIC("Digital Mic1", NULL),
1709 SND_SOC_DAPM_MIC("Digital Mic2", NULL),
1710 SND_SOC_DAPM_MIC("Digital Mic3", NULL),
1711 SND_SOC_DAPM_MIC("Digital Mic4", NULL),
1712 SND_SOC_DAPM_MIC("Digital Mic5", NULL),
1713 SND_SOC_DAPM_MIC("Digital Mic6", NULL),
Surendar Karka813c3d22018-11-05 13:46:17 +05301714 SND_SOC_DAPM_HP("Lineout", NULL),
1715 SND_SOC_DAPM_MIC("Linein", NULL),
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301716};
1717
1718static struct snd_soc_dapm_route wcd_audio_paths_tasha[] = {
1719 {"MIC BIAS1", NULL, "MCLK TX"},
1720 {"MIC BIAS2", NULL, "MCLK TX"},
1721 {"MIC BIAS3", NULL, "MCLK TX"},
1722 {"MIC BIAS4", NULL, "MCLK TX"},
1723};
1724
1725static struct snd_soc_dapm_route wcd_audio_paths[] = {
1726 {"MIC BIAS1", NULL, "MCLK"},
1727 {"MIC BIAS2", NULL, "MCLK"},
1728 {"MIC BIAS3", NULL, "MCLK"},
1729 {"MIC BIAS4", NULL, "MCLK"},
1730};
1731
Laxminath Kasam38070be2017-08-17 18:21:59 +05301732int msm_snd_card_tasha_late_probe(struct snd_soc_card *card)
1733{
1734 const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX;
1735 struct snd_soc_pcm_runtime *rtd;
1736 int ret = 0;
1737 void *mbhc_calibration;
1738
1739 rtd = snd_soc_get_pcm_runtime(card, be_dl_name);
1740 if (!rtd) {
1741 dev_err(card->dev,
1742 "%s: snd_soc_get_pcm_runtime for %s failed!\n",
1743 __func__, be_dl_name);
1744 ret = -EINVAL;
1745 goto err_pcm_runtime;
1746 }
1747
1748 mbhc_calibration = def_ext_mbhc_cal();
1749 if (!mbhc_calibration) {
1750 ret = -ENOMEM;
1751 goto err_mbhc_cal;
1752 }
1753 wcd_mbhc_cfg_ptr->calibration = mbhc_calibration;
1754 ret = tasha_mbhc_hs_detect(rtd->codec, wcd_mbhc_cfg_ptr);
1755 if (ret) {
1756 dev_err(card->dev, "%s: mbhc hs detect failed, err:%d\n",
1757 __func__, ret);
1758 goto err_hs_detect;
1759 }
1760 return 0;
1761
1762err_hs_detect:
1763 kfree(mbhc_calibration);
1764err_mbhc_cal:
1765err_pcm_runtime:
1766 return ret;
1767}
1768
1769int msm_snd_card_tavil_late_probe(struct snd_soc_card *card)
1770{
1771 const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX;
1772 struct snd_soc_pcm_runtime *rtd;
1773 int ret = 0;
1774 void *mbhc_calibration;
1775
1776 rtd = snd_soc_get_pcm_runtime(card, be_dl_name);
1777 if (!rtd) {
1778 dev_err(card->dev,
1779 "%s: snd_soc_get_pcm_runtime for %s failed!\n",
1780 __func__, be_dl_name);
1781 ret = -EINVAL;
1782 goto err;
1783 }
1784
1785 mbhc_calibration = def_ext_mbhc_cal();
1786 if (!mbhc_calibration) {
1787 ret = -ENOMEM;
1788 goto err;
1789 }
1790 wcd_mbhc_cfg_ptr->calibration = mbhc_calibration;
1791 ret = tavil_mbhc_hs_detect(rtd->codec, wcd_mbhc_cfg_ptr);
1792 if (ret) {
1793 dev_err(card->dev, "%s: mbhc hs detect failed, err:%d\n",
1794 __func__, ret);
1795 goto err_free_mbhc_cal;
1796 }
1797 return 0;
1798
1799err_free_mbhc_cal:
1800 kfree(mbhc_calibration);
1801err:
1802 return ret;
1803}
1804
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301805/**
1806 * msm_audrx_init - Audio init function of sound card instantiate.
1807 *
1808 * @rtd: runtime dailink instance
1809 *
1810 * Returns 0 on success or ret on failure.
1811 */
1812int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
1813{
1814 int ret;
1815 void *config_data;
1816 struct snd_soc_codec *codec = rtd->codec;
1817 struct snd_soc_dapm_context *dapm =
1818 snd_soc_codec_get_dapm(codec);
1819 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1820 struct snd_soc_dai *codec_dai = rtd->codec_dai;
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05301821 struct snd_soc_component *aux_comp;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301822 struct snd_card *card;
1823 struct snd_info_entry *entry;
1824 struct msm_asoc_mach_data *pdata =
1825 snd_soc_card_get_drvdata(rtd->card);
1826
1827 /* Codec SLIMBUS configuration
1828 * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8, RX9, RX10, RX11, RX12, RX13
1829 * TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13
1830 * TX14, TX15, TX16
1831 */
1832 unsigned int rx_ch[TASHA_RX_MAX] = {144, 145, 146, 147, 148, 149, 150,
1833 151, 152, 153, 154, 155, 156};
1834 unsigned int tx_ch[TASHA_TX_MAX] = {128, 129, 130, 131, 132, 133,
1835 134, 135, 136, 137, 138, 139,
1836 140, 141, 142, 143};
1837
1838 /* Tavil Codec SLIMBUS configuration
1839 * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8
1840 * TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13
1841 * TX14, TX15, TX16
1842 */
1843 unsigned int rx_ch_tavil[WCD934X_RX_MAX] = {144, 145, 146, 147, 148,
1844 149, 150, 151};
1845 unsigned int tx_ch_tavil[WCD934X_TX_MAX] = {128, 129, 130, 131, 132,
1846 133, 134, 135, 136, 137, 138,
1847 139, 140, 141, 142, 143};
1848
1849 pr_debug("%s: dev_name%s\n", __func__, dev_name(cpu_dai->dev));
1850
1851 rtd->pmdown_time = 0;
1852
1853 ret = snd_soc_add_codec_controls(codec, msm_snd_controls,
1854 ARRAY_SIZE(msm_snd_controls));
1855 if (ret < 0) {
1856 pr_err("%s: add_codec_controls failed: %d\n",
1857 __func__, ret);
1858 return ret;
1859 }
1860
1861 ret = snd_soc_add_codec_controls(codec, msm_common_snd_controls,
1862 msm_common_snd_controls_size());
1863 if (ret < 0) {
1864 pr_err("%s: add_common_snd_controls failed: %d\n",
1865 __func__, ret);
1866 return ret;
1867 }
1868
1869 snd_soc_dapm_new_controls(dapm, msm_dapm_widgets,
1870 ARRAY_SIZE(msm_dapm_widgets));
1871
1872 if (!strcmp(dev_name(codec_dai->dev), "tasha_codec"))
1873 snd_soc_dapm_add_routes(dapm, wcd_audio_paths_tasha,
1874 ARRAY_SIZE(wcd_audio_paths_tasha));
1875 else
1876 snd_soc_dapm_add_routes(dapm, wcd_audio_paths,
1877 ARRAY_SIZE(wcd_audio_paths));
1878
1879 snd_soc_dapm_enable_pin(dapm, "Lineout_1 amp");
1880 snd_soc_dapm_enable_pin(dapm, "Lineout_3 amp");
1881 snd_soc_dapm_enable_pin(dapm, "Lineout_2 amp");
1882 snd_soc_dapm_enable_pin(dapm, "Lineout_4 amp");
1883
1884 snd_soc_dapm_ignore_suspend(dapm, "MADINPUT");
1885 snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_INPUT");
1886 snd_soc_dapm_ignore_suspend(dapm, "Handset Mic");
1887 snd_soc_dapm_ignore_suspend(dapm, "Headset Mic");
1888 snd_soc_dapm_ignore_suspend(dapm, "Secondary Mic");
1889 snd_soc_dapm_ignore_suspend(dapm, "Lineout_1 amp");
1890 snd_soc_dapm_ignore_suspend(dapm, "Lineout_3 amp");
1891 snd_soc_dapm_ignore_suspend(dapm, "Lineout_2 amp");
1892 snd_soc_dapm_ignore_suspend(dapm, "Lineout_4 amp");
1893 snd_soc_dapm_ignore_suspend(dapm, "ANCRight Headset Mic");
1894 snd_soc_dapm_ignore_suspend(dapm, "ANCLeft Headset Mic");
1895 snd_soc_dapm_ignore_suspend(dapm, "Digital Mic0");
1896 snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1");
1897 snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2");
1898 snd_soc_dapm_ignore_suspend(dapm, "Digital Mic3");
1899 snd_soc_dapm_ignore_suspend(dapm, "Digital Mic4");
1900 snd_soc_dapm_ignore_suspend(dapm, "Digital Mic5");
1901 snd_soc_dapm_ignore_suspend(dapm, "Analog Mic4");
1902 snd_soc_dapm_ignore_suspend(dapm, "Analog Mic6");
1903 snd_soc_dapm_ignore_suspend(dapm, "Analog Mic7");
1904 snd_soc_dapm_ignore_suspend(dapm, "Analog Mic8");
1905
1906 snd_soc_dapm_ignore_suspend(dapm, "EAR");
1907 snd_soc_dapm_ignore_suspend(dapm, "LINEOUT1");
1908 snd_soc_dapm_ignore_suspend(dapm, "LINEOUT2");
1909 snd_soc_dapm_ignore_suspend(dapm, "AMIC1");
1910 snd_soc_dapm_ignore_suspend(dapm, "AMIC2");
1911 snd_soc_dapm_ignore_suspend(dapm, "AMIC3");
1912 snd_soc_dapm_ignore_suspend(dapm, "AMIC4");
1913 snd_soc_dapm_ignore_suspend(dapm, "AMIC5");
1914 snd_soc_dapm_ignore_suspend(dapm, "DMIC0");
1915 snd_soc_dapm_ignore_suspend(dapm, "DMIC1");
1916 snd_soc_dapm_ignore_suspend(dapm, "DMIC2");
1917 snd_soc_dapm_ignore_suspend(dapm, "DMIC3");
1918 snd_soc_dapm_ignore_suspend(dapm, "DMIC4");
1919 snd_soc_dapm_ignore_suspend(dapm, "DMIC5");
1920 snd_soc_dapm_ignore_suspend(dapm, "ANC EAR");
1921 snd_soc_dapm_ignore_suspend(dapm, "SPK1 OUT");
1922 snd_soc_dapm_ignore_suspend(dapm, "SPK2 OUT");
1923 snd_soc_dapm_ignore_suspend(dapm, "HPHL");
1924 snd_soc_dapm_ignore_suspend(dapm, "HPHR");
1925 snd_soc_dapm_ignore_suspend(dapm, "AIF4 VI");
1926 snd_soc_dapm_ignore_suspend(dapm, "VIINPUT");
1927
1928 if (!strcmp(dev_name(codec_dai->dev), "tasha_codec")) {
1929 snd_soc_dapm_ignore_suspend(dapm, "LINEOUT3");
1930 snd_soc_dapm_ignore_suspend(dapm, "LINEOUT4");
1931 snd_soc_dapm_ignore_suspend(dapm, "ANC HPHL");
1932 snd_soc_dapm_ignore_suspend(dapm, "ANC HPHR");
1933 snd_soc_dapm_ignore_suspend(dapm, "ANC LINEOUT1");
1934 snd_soc_dapm_ignore_suspend(dapm, "ANC LINEOUT2");
1935 } else {
1936 snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_OUT1");
1937 snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_OUT2");
1938 }
1939
1940 snd_soc_dapm_sync(dapm);
1941
1942 if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) {
1943 snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch_tavil),
1944 tx_ch_tavil, ARRAY_SIZE(rx_ch_tavil),
1945 rx_ch_tavil);
1946 } else {
1947 snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch),
1948 tx_ch, ARRAY_SIZE(rx_ch),
1949 rx_ch);
1950 }
1951
1952 if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) {
1953 msm_codec_fn.get_afe_config_fn = tavil_get_afe_config;
1954 } else {
1955 msm_codec_fn.get_afe_config_fn = tasha_get_afe_config;
1956 msm_codec_fn.mbhc_hs_detect_exit = tasha_mbhc_hs_detect_exit;
1957 }
1958
Aditya Bavanarid61b84d2018-01-03 13:24:06 +05301959 ret = msm_adsp_power_up_config(codec, rtd->card->snd_card);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301960 if (ret) {
1961 pr_err("%s: Failed to set AFE config %d\n", __func__, ret);
1962 goto err_afe_cfg;
1963 }
1964
1965 config_data = msm_codec_fn.get_afe_config_fn(codec,
1966 AFE_AANC_VERSION);
1967 if (config_data) {
1968 ret = afe_set_config(AFE_AANC_VERSION, config_data, 0);
1969 if (ret) {
1970 pr_err("%s: Failed to set aanc version %d\n",
1971 __func__, ret);
1972 goto err_afe_cfg;
1973 }
1974 }
1975
1976 if (!strcmp(dev_name(codec_dai->dev), "tasha_codec")) {
1977 config_data = msm_codec_fn.get_afe_config_fn(codec,
1978 AFE_CDC_CLIP_REGISTERS_CONFIG);
1979 if (config_data) {
1980 ret = afe_set_config(AFE_CDC_CLIP_REGISTERS_CONFIG,
1981 config_data, 0);
1982 if (ret) {
1983 pr_err("%s: Failed to set clip registers %d\n",
1984 __func__, ret);
1985 goto err_afe_cfg;
1986 }
1987 }
1988 config_data = msm_codec_fn.get_afe_config_fn(codec,
1989 AFE_CLIP_BANK_SEL);
1990 if (config_data) {
1991 ret = afe_set_config(AFE_CLIP_BANK_SEL, config_data, 0);
1992 if (ret) {
1993 pr_err("%s: Failed to set AFE bank selection %d\n",
1994 __func__, ret);
1995 goto err_afe_cfg;
1996 }
1997 }
1998 }
1999
2000 /*
2001 * Send speaker configuration only for WSA8810.
2002 * Defalut configuration is for WSA8815.
2003 */
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05302004 pr_debug("%s: Number of aux devices: %d\n",
2005 __func__, rtd->card->num_aux_devs);
2006
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302007 if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) {
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05302008 if (rtd->card->num_aux_devs &&
2009 !list_empty(&rtd->card->aux_comp_list)) {
2010 aux_comp = list_first_entry(&rtd->card->aux_comp_list,
2011 struct snd_soc_component, list_aux);
2012 if (!strcmp(aux_comp->name, WSA8810_NAME_1) ||
2013 !strcmp(aux_comp->name, WSA8810_NAME_2)) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302014 tavil_set_spkr_mode(rtd->codec, SPKR_MODE_1);
2015 tavil_set_spkr_gain_offset(rtd->codec,
2016 RX_GAIN_OFFSET_M1P5_DB);
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05302017 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302018 }
2019 card = rtd->card->snd_card;
2020 entry = snd_info_create_subdir(card->module, "codecs",
2021 card->proc_root);
2022 if (!entry) {
2023 pr_debug("%s: Cannot create codecs module entry\n",
2024 __func__);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302025 goto done;
2026 }
2027 pdata->codec_root = entry;
2028 tavil_codec_info_create_codec_entry(pdata->codec_root, codec);
2029 } else {
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05302030 if (rtd->card->num_aux_devs &&
2031 !list_empty(&rtd->card->aux_comp_list)) {
2032 aux_comp = list_first_entry(&rtd->card->aux_comp_list,
2033 struct snd_soc_component, list_aux);
2034 if (!strcmp(aux_comp->name, WSA8810_NAME_1) ||
2035 !strcmp(aux_comp->name, WSA8810_NAME_2)) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302036 tasha_set_spkr_mode(rtd->codec, SPKR_MODE_1);
2037 tasha_set_spkr_gain_offset(rtd->codec,
2038 RX_GAIN_OFFSET_M1P5_DB);
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05302039 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302040 }
2041 card = rtd->card->snd_card;
2042 entry = snd_info_create_subdir(card->module, "codecs",
2043 card->proc_root);
2044 if (!entry) {
2045 pr_debug("%s: Cannot create codecs module entry\n",
2046 __func__);
Laxminath Kasam38070be2017-08-17 18:21:59 +05302047 goto done;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302048 }
2049 pdata->codec_root = entry;
2050 tasha_codec_info_create_codec_entry(pdata->codec_root, codec);
2051 tasha_mbhc_zdet_gpio_ctrl(msm_config_hph_en0_gpio, rtd->codec);
2052 }
Surendar Karka813c3d22018-11-05 13:46:17 +05302053
2054 if (gpio_is_valid(pdata->gpio_linein_det)) {
2055 snd_soc_card_jack_new(rtd->card, "Linein", SND_JACK_LINEIN,
2056 &linein_jack, linein_jack_pins,
2057 ARRAY_SIZE(linein_jack_pins));
2058
2059 linein_jack_gpio.invert = pdata->linein_det_swh;
2060 linein_jack_gpio.gpio = pdata->gpio_linein_det;
2061 snd_soc_jack_add_gpios(&linein_jack, 1, &linein_jack_gpio);
2062 }
2063
2064 if (gpio_is_valid(pdata->gpio_lineout_det)) {
2065 snd_soc_card_jack_new(rtd->card, "Lineout", SND_JACK_LINEOUT,
2066 &lineout_jack, lineout_jack_pins,
2067 ARRAY_SIZE(lineout_jack_pins));
2068
2069 lineout_jack_gpio.invert = pdata->lineout_det_swh;
2070 lineout_jack_gpio.gpio = pdata->gpio_lineout_det;
2071 snd_soc_jack_add_gpios(&lineout_jack, 1, &lineout_jack_gpio);
2072 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302073done:
Laxminath Kasam38070be2017-08-17 18:21:59 +05302074 msm_set_codec_reg_done(true);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302075 return 0;
2076
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302077err_afe_cfg:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302078 return ret;
2079}
2080EXPORT_SYMBOL(msm_audrx_init);
2081
2082/**
2083 * msm_ext_register_audio_notifier - register SSR notifier.
2084 */
2085void msm_ext_register_audio_notifier(struct platform_device *pdev)
2086{
2087 int ret;
2088
2089 is_initial_boot = true;
2090 spdev = pdev;
2091 ret = audio_notifier_register("sdm660", AUDIO_NOTIFIER_ADSP_DOMAIN,
2092 &service_nb);
2093 if (ret < 0)
2094 pr_err("%s: Audio notifier register failed ret = %d\n",
2095 __func__, ret);
2096}
2097EXPORT_SYMBOL(msm_ext_register_audio_notifier);
2098
2099/**
2100 * msm_ext_cdc_init - external codec machine specific init.
2101 *
2102 * @pdev: platform device handle
2103 * @pdata: private data of machine driver
2104 * @card: sound card pointer reference
2105 * @mbhc_cfg: MBHC config reference
2106 *
2107 * Returns 0 on success or ret on failure.
2108 */
2109int msm_ext_cdc_init(struct platform_device *pdev,
2110 struct msm_asoc_mach_data *pdata,
2111 struct snd_soc_card **card,
2112 struct wcd_mbhc_config *wcd_mbhc_cfg_ptr1)
2113{
2114 int ret = 0;
2115
2116 wcd_mbhc_cfg_ptr = wcd_mbhc_cfg_ptr1;
2117 pdev->id = 0;
2118 wcd_mbhc_cfg_ptr->moisture_en = true;
2119 wcd_mbhc_cfg_ptr->mbhc_micbias = MIC_BIAS_2;
2120 wcd_mbhc_cfg_ptr->anc_micbias = MIC_BIAS_2;
2121 wcd_mbhc_cfg_ptr->enable_anc_mic_detect = false;
2122
2123 *card = populate_snd_card_dailinks(&pdev->dev, pdata->snd_card_val);
2124 if (!(*card)) {
2125 dev_err(&pdev->dev, "%s: Card uninitialized\n", __func__);
2126 ret = -EPROBE_DEFER;
2127 goto err;
2128 }
2129 platform_set_drvdata(pdev, *card);
2130 snd_soc_card_set_drvdata(*card, pdata);
2131 pdata->hph_en1_gpio = of_get_named_gpio(pdev->dev.of_node,
2132 "qcom,hph-en1-gpio", 0);
2133 if (!gpio_is_valid(pdata->hph_en1_gpio))
2134 pdata->hph_en1_gpio_p = of_parse_phandle(pdev->dev.of_node,
2135 "qcom,hph-en1-gpio", 0);
2136 if (!gpio_is_valid(pdata->hph_en1_gpio) && (!pdata->hph_en1_gpio_p)) {
2137 dev_dbg(&pdev->dev, "property %s not detected in node %s",
2138 "qcom,hph-en1-gpio", pdev->dev.of_node->full_name);
2139 }
2140
2141 pdata->hph_en0_gpio = of_get_named_gpio(pdev->dev.of_node,
2142 "qcom,hph-en0-gpio", 0);
2143 if (!gpio_is_valid(pdata->hph_en0_gpio))
2144 pdata->hph_en0_gpio_p = of_parse_phandle(pdev->dev.of_node,
2145 "qcom,hph-en0-gpio", 0);
2146 if (!gpio_is_valid(pdata->hph_en0_gpio) && (!pdata->hph_en0_gpio_p)) {
2147 dev_dbg(&pdev->dev, "property %s not detected in node %s",
2148 "qcom,hph-en0-gpio", pdev->dev.of_node->full_name);
2149 }
2150
Surendar Karka813c3d22018-11-05 13:46:17 +05302151 ret = of_property_read_u32(pdev->dev.of_node, "qcom,linein-det-swh",
2152 &pdata->linein_det_swh);
2153 if (ret) {
2154 dev_dbg(&pdev->dev, "%s: missing %s in dt node\n",
2155 __func__, "qcom,linein-det-swh");
2156 }
2157
2158 ret = of_property_read_u32(pdev->dev.of_node, "qcom,lineout-det-swh",
2159 &pdata->lineout_det_swh);
2160 if (ret) {
2161 dev_dbg(&pdev->dev, "%s: missing %s in dt node\n",
2162 __func__, "qcom,lineout-det-swh");
2163 }
2164
2165 pdata->gpio_linein_det = of_get_named_gpio(pdev->dev.of_node,
2166 "qcom,linein-det-gpio", 0);
2167 if (pdata->gpio_linein_det < 0) {
2168 dev_dbg(&pdev->dev, "property %s not detected in node %s\n",
2169 "qcom,linein-det-gpio", pdev->dev.of_node->full_name);
2170 }
2171
2172 pdata->gpio_lineout_det = of_get_named_gpio(pdev->dev.of_node,
2173 "qcom,lineout-det-gpio", 0);
2174 if (pdata->gpio_lineout_det < 0) {
2175 dev_dbg(&pdev->dev, "property %s not detected in node %s\n",
2176 "qcom,lineout-det-gpio", pdev->dev.of_node->full_name);
2177 }
2178
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302179 ret = msm_ext_prepare_hifi(pdata);
2180 if (ret) {
2181 dev_dbg(&pdev->dev, "msm_ext_prepare_hifi failed (%d)\n",
2182 ret);
2183 ret = 0;
2184 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302185err:
2186 return ret;
2187}
2188EXPORT_SYMBOL(msm_ext_cdc_init);