blob: fa338b2282d7c9aae4859719b6b56c43cab9932e [file] [log] [blame]
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
2 *
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#include <linux/slab.h>
13#include <linux/kthread.h>
14#include <linux/kernel.h>
15#include <linux/module.h>
16#include <linux/uaccess.h>
17#include <linux/wait.h>
18#include <linux/mutex.h>
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053019
20#include <soc/qcom/socinfo.h>
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053021
Laxminath Kasam605b42f2017-08-01 22:02:15 +053022#include <dsp/msm_audio_ion.h>
23#include <dsp/q6audio-v2.h>
24#include <dsp/apr_audio-v2.h>
25#include <dsp/q6afe-v2.h>
26#include <dsp/audio_cal_utils.h>
Laxminath Kasam38070be2017-08-17 18:21:59 +053027#include <dsp/q6core.h>
Laxminath Kasam605b42f2017-08-01 22:02:15 +053028#include <dsp/q6voice.h>
Laxminath Kasam38070be2017-08-17 18:21:59 +053029#include <ipc/apr_tal.h>
Laxminath Kasam605b42f2017-08-01 22:02:15 +053030#include "adsp_err.h"
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053031
32#define TIMEOUT_MS 300
33
34
35#define CMD_STATUS_SUCCESS 0
36#define CMD_STATUS_FAIL 1
Laxminath Kasam38070be2017-08-17 18:21:59 +053037#define NUM_CHANNELS_MONO 1
38#define NUM_CHANNELS_STEREO 2
39#define CVP_VERSION_2 2
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053040
41enum {
42 VOC_TOKEN_NONE,
43 VOIP_MEM_MAP_TOKEN,
44 VOC_CAL_MEM_MAP_TOKEN,
45 VOC_VOICE_HOST_PCM_MAP_TOKEN,
46 VOC_RTAC_MEM_MAP_TOKEN,
47 VOC_SOURCE_TRACKING_MEM_MAP_TOKEN
48};
49
50struct cvd_version_table cvd_version_table_mapping[CVD_INT_VERSION_MAX] = {
51 {CVD_VERSION_DEFAULT, CVD_INT_VERSION_DEFAULT},
52 {CVD_VERSION_0_0, CVD_INT_VERSION_0_0},
53 {CVD_VERSION_2_1, CVD_INT_VERSION_2_1},
54 {CVD_VERSION_2_2, CVD_INT_VERSION_2_2},
55 {CVD_VERSION_2_3, CVD_INT_VERSION_2_3},
56};
57
58static struct common_data common;
59static bool module_initialized;
60
61static int voice_send_enable_vocproc_cmd(struct voice_data *v);
62static int voice_send_netid_timing_cmd(struct voice_data *v);
63static int voice_send_attach_vocproc_cmd(struct voice_data *v);
64static int voice_send_set_device_cmd(struct voice_data *v);
65static int voice_send_vol_step_cmd(struct voice_data *v);
66static int voice_send_mvm_unmap_memory_physical_cmd(struct voice_data *v,
67 uint32_t mem_handle);
68static int voice_send_mvm_cal_network_cmd(struct voice_data *v);
69static int voice_send_mvm_media_type_cmd(struct voice_data *v);
70static int voice_send_mvm_cvd_version_cmd(struct voice_data *v);
71static int voice_send_cvs_data_exchange_mode_cmd(struct voice_data *v);
72static int voice_send_cvs_packet_exchange_config_cmd(struct voice_data *v);
73static int voice_set_packet_exchange_mode_and_config(uint32_t session_id,
74 uint32_t mode);
75
76static int voice_send_cvs_register_cal_cmd(struct voice_data *v);
77static int voice_send_cvs_deregister_cal_cmd(struct voice_data *v);
78static int voice_send_cvp_create_cmd(struct voice_data *v);
79static int voice_send_cvp_register_dev_cfg_cmd(struct voice_data *v);
80static int voice_send_cvp_deregister_dev_cfg_cmd(struct voice_data *v);
81static int voice_send_cvp_register_cal_cmd(struct voice_data *v);
82static int voice_send_cvp_deregister_cal_cmd(struct voice_data *v);
83static int voice_send_cvp_register_vol_cal_cmd(struct voice_data *v);
84static int voice_send_cvp_deregister_vol_cal_cmd(struct voice_data *v);
85static int voice_send_cvp_media_fmt_info_cmd(struct voice_data *v);
86static int voice_send_cvp_device_channels_cmd(struct voice_data *v);
87static int voice_send_cvp_media_format_cmd(struct voice_data *v,
88 uint32_t param_type);
89static int voice_send_cvp_topology_commit_cmd(struct voice_data *v);
Laxminath Kasam38070be2017-08-17 18:21:59 +053090static int voice_send_cvp_channel_info_cmd(struct voice_data *v);
91static int voice_send_cvp_channel_info_v2(struct voice_data *v,
92 uint32_t param_type);
93static int voice_get_avcs_version_per_service(uint32_t service_id);
94
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053095
96static int voice_cvs_stop_playback(struct voice_data *v);
97static int voice_cvs_start_playback(struct voice_data *v);
98static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode);
99static int voice_cvs_stop_record(struct voice_data *v);
100
101static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv);
102static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv);
103static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv);
104
105static int voice_send_set_pp_enable_cmd(struct voice_data *v,
106 uint32_t module_id, int enable);
107static int is_cal_memory_allocated(void);
108static bool is_cvd_version_queried(void);
109static int is_voip_memory_allocated(void);
110static int voice_get_cvd_int_version(char *cvd_ver_string);
111static int voice_alloc_cal_mem_map_table(void);
112static int voice_alloc_rtac_mem_map_table(void);
113static int voice_alloc_oob_shared_mem(void);
114static int voice_free_oob_shared_mem(void);
115static int voice_alloc_oob_mem_table(void);
116static int voice_alloc_and_map_oob_mem(struct voice_data *v);
117
118static struct voice_data *voice_get_session_by_idx(int idx);
119
120static int remap_cal_data(struct cal_block_data *cal_block,
121 uint32_t session_id);
122static int voice_unmap_cal_memory(int32_t cal_type,
123 struct cal_block_data *cal_block);
124
125static int is_source_tracking_shared_memomry_allocated(void);
126static int voice_alloc_source_tracking_shared_memory(void);
127static int voice_alloc_and_map_source_tracking_shared_memory(
128 struct voice_data *v);
129static int voice_unmap_and_free_source_tracking_shared_memory(
130 struct voice_data *v);
131static int voice_send_set_sound_focus_cmd(struct voice_data *v,
132 struct sound_focus_param soundFocusData);
133static int voice_send_get_sound_focus_cmd(struct voice_data *v,
134 struct sound_focus_param *soundFocusData);
135static int voice_send_get_source_tracking_cmd(struct voice_data *v,
136 struct source_tracking_param *sourceTrackingData);
137
138static void voice_itr_init(struct voice_session_itr *itr,
139 u32 session_id)
140{
141 if (itr == NULL)
142 return;
143 itr->session_idx = voice_get_idx_for_session(session_id);
144 if (session_id == ALL_SESSION_VSID)
145 itr->cur_idx = 0;
146 else
147 itr->cur_idx = itr->session_idx;
148
149}
150
151static bool voice_itr_get_next_session(struct voice_session_itr *itr,
152 struct voice_data **voice)
153{
154 bool ret = false;
155
156 if (itr == NULL)
157 return false;
158 pr_debug("%s : cur idx = %d session idx = %d\n",
159 __func__, itr->cur_idx, itr->session_idx);
160
161 if (itr->cur_idx <= itr->session_idx) {
162 ret = true;
163 *voice = voice_get_session_by_idx(itr->cur_idx);
164 itr->cur_idx++;
165 } else {
166 *voice = NULL;
167 }
168
169 return ret;
170}
171
172static bool voice_is_valid_session_id(uint32_t session_id)
173{
174 bool ret = false;
175
176 switch (session_id) {
177 case VOICE_SESSION_VSID:
178 case VOICE2_SESSION_VSID:
179 case VOLTE_SESSION_VSID:
180 case VOIP_SESSION_VSID:
181 case QCHAT_SESSION_VSID:
182 case VOWLAN_SESSION_VSID:
183 case VOICEMMODE1_VSID:
184 case VOICEMMODE2_VSID:
185 case ALL_SESSION_VSID:
186 ret = true;
187 break;
188 default:
189 pr_err("%s: Invalid session_id : %x\n", __func__, session_id);
190
191 break;
192 }
193
194 return ret;
195}
196
197static u16 voice_get_mvm_handle(struct voice_data *v)
198{
199 if (v == NULL) {
200 pr_err("%s: v is NULL\n", __func__);
201 return 0;
202 }
203
204 pr_debug("%s: mvm_handle %d\n", __func__, v->mvm_handle);
205
206 return v->mvm_handle;
207}
208
209static void voice_set_mvm_handle(struct voice_data *v, u16 mvm_handle)
210{
211 pr_debug("%s: mvm_handle %d\n", __func__, mvm_handle);
212 if (v == NULL) {
213 pr_err("%s: v is NULL\n", __func__);
214 return;
215 }
216
217 v->mvm_handle = mvm_handle;
218}
219
220static u16 voice_get_cvs_handle(struct voice_data *v)
221{
222 if (v == NULL) {
223 pr_err("%s: v is NULL\n", __func__);
224 return 0;
225 }
226
227 pr_debug("%s: cvs_handle %d\n", __func__, v->cvs_handle);
228
229 return v->cvs_handle;
230}
231
232static void voice_set_cvs_handle(struct voice_data *v, u16 cvs_handle)
233{
234 pr_debug("%s: cvs_handle %d\n", __func__, cvs_handle);
235 if (v == NULL) {
236 pr_err("%s: v is NULL\n", __func__);
237 return;
238 }
239
240 v->cvs_handle = cvs_handle;
241}
242
243static u16 voice_get_cvp_handle(struct voice_data *v)
244{
245 if (v == NULL) {
246 pr_err("%s: v is NULL\n", __func__);
247 return 0;
248 }
249
250 pr_debug("%s: cvp_handle %d\n", __func__, v->cvp_handle);
251
252 return v->cvp_handle;
253}
254
255static void voice_set_cvp_handle(struct voice_data *v, u16 cvp_handle)
256{
257 pr_debug("%s: cvp_handle %d\n", __func__, cvp_handle);
258 if (v == NULL) {
259 pr_err("%s: v is NULL\n", __func__);
260 return;
261 }
262
263 v->cvp_handle = cvp_handle;
264}
265
266char *voc_get_session_name(u32 session_id)
267{
268 char *session_name = NULL;
269
270 if (session_id == common.voice[VOC_PATH_PASSIVE].session_id) {
271 session_name = VOICE_SESSION_NAME;
272 } else if (session_id ==
273 common.voice[VOC_PATH_VOLTE_PASSIVE].session_id) {
274 session_name = VOLTE_SESSION_NAME;
275 } else if (session_id ==
276 common.voice[VOC_PATH_QCHAT_PASSIVE].session_id) {
277 session_name = QCHAT_SESSION_NAME;
278 } else if (session_id ==
279 common.voice[VOC_PATH_VOWLAN_PASSIVE].session_id) {
280 session_name = VOWLAN_SESSION_NAME;
281 } else if (session_id ==
282 common.voice[VOC_PATH_VOICEMMODE1_PASSIVE].session_id) {
283 session_name = VOICEMMODE1_NAME;
284 } else if (session_id ==
285 common.voice[VOC_PATH_VOICEMMODE2_PASSIVE].session_id) {
286 session_name = VOICEMMODE2_NAME;
287 } else if (session_id == common.voice[VOC_PATH_FULL].session_id) {
288 session_name = VOIP_SESSION_NAME;
289 }
290 return session_name;
291}
292
293uint32_t voc_get_session_id(char *name)
294{
295 u32 session_id = 0;
296
297 if (name != NULL) {
298 if (!strcmp(name, "Voice session"))
299 session_id = common.voice[VOC_PATH_PASSIVE].session_id;
300 else if (!strcmp(name, "Voice2 session"))
301 session_id =
302 common.voice[VOC_PATH_VOICE2_PASSIVE].session_id;
303 else if (!strcmp(name, "VoLTE session"))
304 session_id =
305 common.voice[VOC_PATH_VOLTE_PASSIVE].session_id;
306 else if (!strcmp(name, "QCHAT session"))
307 session_id =
308 common.voice[VOC_PATH_QCHAT_PASSIVE].session_id;
309 else if (!strcmp(name, "VoWLAN session"))
310 session_id =
311 common.voice[VOC_PATH_VOWLAN_PASSIVE].session_id;
312 else if (!strcmp(name, "VoiceMMode1"))
313 session_id =
314 common.voice[VOC_PATH_VOICEMMODE1_PASSIVE].session_id;
315 else if (!strcmp(name, "VoiceMMode2"))
316 session_id =
317 common.voice[VOC_PATH_VOICEMMODE2_PASSIVE].session_id;
318 else
319 session_id = common.voice[VOC_PATH_FULL].session_id;
320
321 pr_debug("%s: %s has session id 0x%x\n", __func__, name,
322 session_id);
323 }
324
325 return session_id;
326}
327
328static struct voice_data *voice_get_session(u32 session_id)
329{
330 struct voice_data *v = NULL;
331
332 switch (session_id) {
333 case VOICE_SESSION_VSID:
334 v = &common.voice[VOC_PATH_PASSIVE];
335 break;
336
337 case VOICE2_SESSION_VSID:
338 v = &common.voice[VOC_PATH_VOICE2_PASSIVE];
339 break;
340
341 case VOLTE_SESSION_VSID:
342 v = &common.voice[VOC_PATH_VOLTE_PASSIVE];
343 break;
344
345 case VOIP_SESSION_VSID:
346 v = &common.voice[VOC_PATH_FULL];
347 break;
348
349 case QCHAT_SESSION_VSID:
350 v = &common.voice[VOC_PATH_QCHAT_PASSIVE];
351 break;
352
353 case VOWLAN_SESSION_VSID:
354 v = &common.voice[VOC_PATH_VOWLAN_PASSIVE];
355 break;
356
357 case VOICEMMODE1_VSID:
358 v = &common.voice[VOC_PATH_VOICEMMODE1_PASSIVE];
359 break;
360
361 case VOICEMMODE2_VSID:
362 v = &common.voice[VOC_PATH_VOICEMMODE2_PASSIVE];
363 break;
364
365 case ALL_SESSION_VSID:
366 break;
367
368 default:
369 pr_err("%s: Invalid session_id : %x\n", __func__, session_id);
370
371 break;
372 }
373
374 pr_debug("%s:session_id 0x%x session handle %pK\n",
375 __func__, session_id, v);
376
377 return v;
378}
379
380int voice_get_idx_for_session(u32 session_id)
381{
382 int idx = 0;
383
384 switch (session_id) {
385 case VOICE_SESSION_VSID:
386 idx = VOC_PATH_PASSIVE;
387 break;
388
389 case VOICE2_SESSION_VSID:
390 idx = VOC_PATH_VOICE2_PASSIVE;
391 break;
392
393 case VOLTE_SESSION_VSID:
394 idx = VOC_PATH_VOLTE_PASSIVE;
395 break;
396
397 case VOIP_SESSION_VSID:
398 idx = VOC_PATH_FULL;
399 break;
400
401 case QCHAT_SESSION_VSID:
402 idx = VOC_PATH_QCHAT_PASSIVE;
403 break;
404
405 case VOWLAN_SESSION_VSID:
406 idx = VOC_PATH_VOWLAN_PASSIVE;
407 break;
408
409 case VOICEMMODE1_VSID:
410 idx = VOC_PATH_VOICEMMODE1_PASSIVE;
411 break;
412
413 case VOICEMMODE2_VSID:
414 idx = VOC_PATH_VOICEMMODE2_PASSIVE;
415 break;
416
417 case ALL_SESSION_VSID:
418 idx = MAX_VOC_SESSIONS - 1;
419 break;
420
421 default:
422 pr_err("%s: Invalid session_id : %x\n", __func__, session_id);
423
424 break;
425 }
426
427 return idx;
428}
429
430static struct voice_data *voice_get_session_by_idx(int idx)
431{
432 return ((idx < 0 || idx >= MAX_VOC_SESSIONS) ?
433 NULL : &common.voice[idx]);
434}
435
436static bool is_voip_session(u32 session_id)
437{
438 return (session_id == common.voice[VOC_PATH_FULL].session_id);
439}
440
441static bool is_volte_session(u32 session_id)
442{
443 return (session_id == common.voice[VOC_PATH_VOLTE_PASSIVE].session_id);
444}
445
446static bool is_voice2_session(u32 session_id)
447{
448 return (session_id == common.voice[VOC_PATH_VOICE2_PASSIVE].session_id);
449}
450
451static bool is_qchat_session(u32 session_id)
452{
453 return (session_id == common.voice[VOC_PATH_QCHAT_PASSIVE].session_id);
454}
455
456static bool is_vowlan_session(u32 session_id)
457{
458 return (session_id == common.voice[VOC_PATH_VOWLAN_PASSIVE].session_id);
459}
460
461static bool is_voicemmode1(u32 session_id)
462{
463 return session_id ==
464 common.voice[VOC_PATH_VOICEMMODE1_PASSIVE].session_id;
465}
466
467static bool is_voicemmode2(u32 session_id)
468{
469 return session_id ==
470 common.voice[VOC_PATH_VOICEMMODE2_PASSIVE].session_id;
471}
472
473static bool is_voc_state_active(int voc_state)
474{
475 if ((voc_state == VOC_RUN) ||
476 (voc_state == VOC_CHANGE) ||
477 (voc_state == VOC_STANDBY))
478 return true;
479
480 return false;
481}
482
483static void voc_set_error_state(uint16_t reset_proc)
484{
485 struct voice_data *v = NULL;
486 int i;
487
488 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
489 v = &common.voice[i];
490 if (v != NULL) {
491 v->voc_state = VOC_ERROR;
492 v->rec_info.recording = 0;
493 }
494 }
495}
496
497static bool is_other_session_active(u32 session_id)
498{
499 int i;
500 bool ret = false;
501
502 /* Check if there is other active session except the input one */
503 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
504 if (common.voice[i].session_id == session_id)
505 continue;
506
507 if (is_voc_state_active(common.voice[i].voc_state)) {
508 ret = true;
509 break;
510 }
511 }
512 pr_debug("%s: ret %d\n", __func__, ret);
513
514 return ret;
515}
516
517static bool is_sub1_vsid(u32 session_id)
518{
519 bool ret;
520
521 switch (session_id) {
522 case VOICE_SESSION_VSID:
523 case VOLTE_SESSION_VSID:
524 case VOWLAN_SESSION_VSID:
525 case VOICEMMODE1_VSID:
526 ret = true;
527 break;
528 default:
529 ret = false;
530 }
531
532 return ret;
533}
534
535static bool is_sub2_vsid(u32 session_id)
536{
537 bool ret;
538
539 switch (session_id) {
540 case VOICE2_SESSION_VSID:
541 case VOICEMMODE2_VSID:
542 ret = true;
543 break;
544 default:
545 ret = false;
546 }
547
548 return ret;
549}
550
551static bool is_voice_app_id(u32 session_id)
552{
553 return is_sub1_vsid(session_id) || is_sub2_vsid(session_id);
554}
555
556static void init_session_id(void)
557{
558 common.voice[VOC_PATH_PASSIVE].session_id = VOICE_SESSION_VSID;
559 common.voice[VOC_PATH_VOLTE_PASSIVE].session_id = VOLTE_SESSION_VSID;
560 common.voice[VOC_PATH_VOICE2_PASSIVE].session_id = VOICE2_SESSION_VSID;
561 common.voice[VOC_PATH_FULL].session_id = VOIP_SESSION_VSID;
562 common.voice[VOC_PATH_QCHAT_PASSIVE].session_id = QCHAT_SESSION_VSID;
563 common.voice[VOC_PATH_VOWLAN_PASSIVE].session_id = VOWLAN_SESSION_VSID;
564 common.voice[VOC_PATH_VOICEMMODE1_PASSIVE].session_id =
565 VOICEMMODE1_VSID;
566 common.voice[VOC_PATH_VOICEMMODE2_PASSIVE].session_id =
567 VOICEMMODE2_VSID;
568}
569
570static bool is_cvd_version_queried(void)
571{
572 bool ret = 0;
573
574 if (!strcmp(common.cvd_version, CVD_VERSION_DEFAULT))
575 ret = false;
576 else
577 ret = true;
578
579 return ret;
580}
581
582static int voice_get_cvd_int_version(char *cvd_ver_string)
583{
584 unsigned int idx;
585 int cvd_int_ver = CVD_INT_VERSION_DEFAULT;
586
587 for (idx = 0; idx < CVD_INT_VERSION_MAX; idx++) {
588 if (strcmp((char *)cvd_ver_string,
589 cvd_version_table_mapping[idx].cvd_ver) == 0) {
590 cvd_int_ver =
591 cvd_version_table_mapping[idx].cvd_ver_int;
592 break;
593 }
594 }
595 return cvd_int_ver;
596}
597
598static int voice_apr_register(uint32_t session_id)
599{
600
601 pr_debug("%s\n", __func__);
602
603 mutex_lock(&common.common_lock);
604
605 /* register callback to APR */
606 if (common.apr_q6_mvm == NULL) {
607 pr_debug("%s: Start to register MVM callback\n", __func__);
608
609 common.apr_q6_mvm = apr_register("ADSP", "MVM",
610 qdsp_mvm_callback,
611 0xFFFFFFFF, &common);
612
613 if (common.apr_q6_mvm == NULL) {
614 pr_err("%s: Unable to register MVM\n", __func__);
615 goto err;
616 }
617 }
618
619 if (common.apr_q6_cvs == NULL) {
620 pr_debug("%s: Start to register CVS callback\n", __func__);
621
622 common.apr_q6_cvs = apr_register("ADSP", "CVS",
623 qdsp_cvs_callback,
624 0xFFFFFFFF, &common);
625
626 if (common.apr_q6_cvs == NULL) {
627 pr_err("%s: Unable to register CVS\n", __func__);
628 goto err;
629 }
630 rtac_set_voice_handle(RTAC_CVS, common.apr_q6_cvs);
631 }
632
633 if (common.apr_q6_cvp == NULL) {
634 pr_debug("%s: Start to register CVP callback\n", __func__);
635
636 common.apr_q6_cvp = apr_register("ADSP", "CVP",
637 qdsp_cvp_callback,
638 0xFFFFFFFF, &common);
639
640 if (common.apr_q6_cvp == NULL) {
641 pr_err("%s: Unable to register CVP\n", __func__);
642 goto err;
643 }
644 rtac_set_voice_handle(RTAC_CVP, common.apr_q6_cvp);
645 }
646
647 mutex_unlock(&common.common_lock);
648
649 return 0;
650
651err:
652 if (common.apr_q6_cvs != NULL) {
653 apr_deregister(common.apr_q6_cvs);
654 common.apr_q6_cvs = NULL;
655 rtac_set_voice_handle(RTAC_CVS, NULL);
656 }
657 if (common.apr_q6_mvm != NULL) {
658 apr_deregister(common.apr_q6_mvm);
659 common.apr_q6_mvm = NULL;
660 }
661
662 mutex_unlock(&common.common_lock);
663
664 return -ENODEV;
665}
666
667static int voice_send_mvm_cvd_version_cmd(struct voice_data *v)
668{
669 int ret;
670 struct apr_hdr cvd_version_get_cmd;
671 void *apr_mvm;
672
673 if (v == NULL) {
674 pr_err("%s: v is NULL\n", __func__);
675
676 ret = -EINVAL;
677 goto done;
678 }
679
680 apr_mvm = common.apr_q6_mvm;
681 if (!apr_mvm) {
682 pr_err("%s: apr_mvm is NULL.\n", __func__);
683
684 ret = -EINVAL;
685 goto done;
686 }
687
688 /* Send command to CVD to retrieve Version */
689 cvd_version_get_cmd.hdr_field = APR_HDR_FIELD(
690 APR_MSG_TYPE_SEQ_CMD,
691 APR_HDR_LEN(APR_HDR_SIZE),
692 APR_PKT_VER);
693 cvd_version_get_cmd.pkt_size = APR_PKT_SIZE(
694 APR_HDR_SIZE,
695 sizeof(cvd_version_get_cmd) -
696 APR_HDR_SIZE);
697 cvd_version_get_cmd.src_port =
698 voice_get_idx_for_session(v->session_id);
699 cvd_version_get_cmd.dest_port = 0;
700 cvd_version_get_cmd.token = 0;
701 cvd_version_get_cmd.opcode = VSS_IVERSION_CMD_GET;
702
703 pr_debug("%s: send CVD version get cmd, pkt size = %d\n",
704 __func__, cvd_version_get_cmd.pkt_size);
705
706 v->mvm_state = CMD_STATUS_FAIL;
707 v->async_err = 0;
708 ret = apr_send_pkt(apr_mvm,
709 (uint32_t *) &cvd_version_get_cmd);
710 if (ret < 0) {
711 pr_err("%s: Error sending command\n", __func__);
712
713 ret = -EINVAL;
714 goto done;
715 }
716
717 ret = wait_event_timeout(v->mvm_wait,
718 (v->mvm_state == CMD_STATUS_SUCCESS),
719 msecs_to_jiffies(TIMEOUT_MS));
720 if (!ret) {
721 pr_err("%s: wait_event timeout, fall back to default\n",
722 __func__);
723
724 ret = -EINVAL;
725 goto done;
726 }
727 if (v->async_err > 0) {
728 pr_err("%s: DSP returned error[%s]\n",
729 __func__, adsp_err_get_err_str(
730 v->async_err));
731 ret = adsp_err_get_lnx_err_code(
732 v->async_err);
733 goto done;
734 }
735 ret = 0;
736
737done:
738 if (ret) {
739 strlcpy(common.cvd_version, CVD_VERSION_0_0,
740 sizeof(common.cvd_version));
741 }
742 pr_debug("%s: CVD Version retrieved=%s\n",
743 __func__, common.cvd_version);
744
745 return ret;
746}
747
748static int voice_send_dual_control_cmd(struct voice_data *v)
749{
750 int ret = 0;
751 struct mvm_modem_dual_control_session_cmd mvm_voice_ctl_cmd;
752 void *apr_mvm;
753 u16 mvm_handle;
754
755 if (v == NULL) {
756 pr_err("%s: v is NULL\n", __func__);
757 return -EINVAL;
758 }
759 apr_mvm = common.apr_q6_mvm;
760 if (!apr_mvm) {
761 pr_err("%s: apr_mvm is NULL.\n", __func__);
762 return -EINVAL;
763 }
764 pr_debug("%s: Send Dual Control command to MVM\n", __func__);
765 if (!is_voip_session(v->session_id)) {
766 mvm_handle = voice_get_mvm_handle(v);
767 mvm_voice_ctl_cmd.hdr.hdr_field = APR_HDR_FIELD(
768 APR_MSG_TYPE_SEQ_CMD,
769 APR_HDR_LEN(APR_HDR_SIZE),
770 APR_PKT_VER);
771 mvm_voice_ctl_cmd.hdr.pkt_size = APR_PKT_SIZE(
772 APR_HDR_SIZE,
773 sizeof(mvm_voice_ctl_cmd) -
774 APR_HDR_SIZE);
775 pr_debug("%s: send mvm Voice Ctl pkt size = %d\n",
776 __func__, mvm_voice_ctl_cmd.hdr.pkt_size);
777 mvm_voice_ctl_cmd.hdr.src_port =
778 voice_get_idx_for_session(v->session_id);
779 mvm_voice_ctl_cmd.hdr.dest_port = mvm_handle;
780 mvm_voice_ctl_cmd.hdr.token = 0;
781 mvm_voice_ctl_cmd.hdr.opcode =
782 VSS_IMVM_CMD_SET_POLICY_DUAL_CONTROL;
783 mvm_voice_ctl_cmd.voice_ctl.enable_flag = true;
784 v->mvm_state = CMD_STATUS_FAIL;
785 v->async_err = 0;
786
787 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_voice_ctl_cmd);
788 if (ret < 0) {
789 pr_err("%s: Error sending MVM Voice CTL CMD\n",
790 __func__);
791 ret = -EINVAL;
792 goto fail;
793 }
794 ret = wait_event_timeout(v->mvm_wait,
795 (v->mvm_state == CMD_STATUS_SUCCESS),
796 msecs_to_jiffies(TIMEOUT_MS));
797 if (!ret) {
798 pr_err("%s: wait_event timeout\n", __func__);
799 ret = -EINVAL;
800 goto fail;
801 }
802 if (v->async_err > 0) {
803 pr_err("%s: DSP returned error[%s]\n",
804 __func__, adsp_err_get_err_str(
805 v->async_err));
806 ret = adsp_err_get_lnx_err_code(
807 v->async_err);
808 goto fail;
809 }
810 }
811 ret = 0;
812fail:
813 return ret;
814}
815
816
817static int voice_create_mvm_cvs_session(struct voice_data *v)
818{
819 int ret = 0;
820 struct mvm_create_ctl_session_cmd mvm_session_cmd;
821 struct cvs_create_passive_ctl_session_cmd cvs_session_cmd;
822 struct cvs_create_full_ctl_session_cmd cvs_full_ctl_cmd;
823 struct mvm_attach_stream_cmd attach_stream_cmd;
824 void *apr_mvm, *apr_cvs, *apr_cvp;
825 u16 mvm_handle, cvs_handle, cvp_handle;
826
827 if (v == NULL) {
828 pr_err("%s: v is NULL\n", __func__);
829 return -EINVAL;
830 }
831 apr_mvm = common.apr_q6_mvm;
832 apr_cvs = common.apr_q6_cvs;
833 apr_cvp = common.apr_q6_cvp;
834
835 if (!apr_mvm || !apr_cvs || !apr_cvp) {
836 pr_err("%s: apr_mvm or apr_cvs or apr_cvp is NULL\n", __func__);
837 return -EINVAL;
838 }
839 mvm_handle = voice_get_mvm_handle(v);
840 cvs_handle = voice_get_cvs_handle(v);
841 cvp_handle = voice_get_cvp_handle(v);
842
843 pr_debug("%s: mvm_hdl=%d, cvs_hdl=%d\n", __func__,
844 mvm_handle, cvs_handle);
845 /* send cmd to create mvm session and wait for response */
846
847 if (!mvm_handle) {
848 memset(mvm_session_cmd.mvm_session.name, 0,
849 sizeof(mvm_session_cmd.mvm_session.name));
850 if (!is_voip_session(v->session_id)) {
851 mvm_session_cmd.hdr.hdr_field = APR_HDR_FIELD(
852 APR_MSG_TYPE_SEQ_CMD,
853 APR_HDR_LEN(APR_HDR_SIZE),
854 APR_PKT_VER);
855 mvm_session_cmd.hdr.pkt_size = APR_PKT_SIZE(
856 APR_HDR_SIZE,
857 sizeof(mvm_session_cmd) -
858 APR_HDR_SIZE);
859 pr_debug("%s: send mvm create session pkt size = %d\n",
860 __func__, mvm_session_cmd.hdr.pkt_size);
861 mvm_session_cmd.hdr.src_port =
862 voice_get_idx_for_session(v->session_id);
863 mvm_session_cmd.hdr.dest_port = 0;
864 mvm_session_cmd.hdr.token = 0;
865 mvm_session_cmd.hdr.opcode =
866 VSS_IMVM_CMD_CREATE_PASSIVE_CONTROL_SESSION;
867 if (is_volte_session(v->session_id)) {
868 strlcpy(mvm_session_cmd.mvm_session.name,
869 "default volte voice",
870 strlen("default volte voice")+1);
871 } else if (is_voice2_session(v->session_id)) {
872 strlcpy(mvm_session_cmd.mvm_session.name,
873 VOICE2_SESSION_VSID_STR,
874 strlen(VOICE2_SESSION_VSID_STR)+1);
875 } else if (is_qchat_session(v->session_id)) {
876 strlcpy(mvm_session_cmd.mvm_session.name,
877 QCHAT_SESSION_VSID_STR,
878 strlen(QCHAT_SESSION_VSID_STR)+1);
879 } else if (is_vowlan_session(v->session_id)) {
880 strlcpy(mvm_session_cmd.mvm_session.name,
881 VOWLAN_SESSION_VSID_STR,
882 strlen(VOWLAN_SESSION_VSID_STR)+1);
883 } else if (is_voicemmode1(v->session_id)) {
884 strlcpy(mvm_session_cmd.mvm_session.name,
885 VOICEMMODE1_VSID_STR,
886 strlen(VOICEMMODE1_VSID_STR) + 1);
887 } else if (is_voicemmode2(v->session_id)) {
888 strlcpy(mvm_session_cmd.mvm_session.name,
889 VOICEMMODE2_VSID_STR,
890 strlen(VOICEMMODE2_VSID_STR) + 1);
891 } else {
892 strlcpy(mvm_session_cmd.mvm_session.name,
893 "default modem voice",
894 strlen("default modem voice")+1);
895 }
896
897 v->mvm_state = CMD_STATUS_FAIL;
898 v->async_err = 0;
899
900 ret = apr_send_pkt(apr_mvm,
901 (uint32_t *) &mvm_session_cmd);
902 if (ret < 0) {
903 pr_err("%s: Error sending MVM_CONTROL_SESSION\n",
904 __func__);
905 goto fail;
906 }
907 ret = wait_event_timeout(v->mvm_wait,
908 (v->mvm_state == CMD_STATUS_SUCCESS),
909 msecs_to_jiffies(TIMEOUT_MS));
910 if (!ret) {
911 pr_err("%s: wait_event timeout\n", __func__);
912 goto fail;
913 }
914 if (v->async_err > 0) {
915 pr_err("%s: DSP returned error[%s]\n",
916 __func__, adsp_err_get_err_str(
917 v->async_err));
918 ret = adsp_err_get_lnx_err_code(
919 v->async_err);
920 goto fail;
921 }
922 } else {
923 pr_debug("%s: creating MVM full ctrl\n", __func__);
924 mvm_session_cmd.hdr.hdr_field =
925 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
926 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
927 mvm_session_cmd.hdr.pkt_size =
928 APR_PKT_SIZE(APR_HDR_SIZE,
929 sizeof(mvm_session_cmd) -
930 APR_HDR_SIZE);
931 mvm_session_cmd.hdr.src_port =
932 voice_get_idx_for_session(v->session_id);
933 mvm_session_cmd.hdr.dest_port = 0;
934 mvm_session_cmd.hdr.token = 0;
935 mvm_session_cmd.hdr.opcode =
936 VSS_IMVM_CMD_CREATE_FULL_CONTROL_SESSION;
937 strlcpy(mvm_session_cmd.mvm_session.name,
938 "default voip",
939 strlen("default voip")+1);
940
941 v->mvm_state = CMD_STATUS_FAIL;
942 v->async_err = 0;
943
944 ret = apr_send_pkt(apr_mvm,
945 (uint32_t *) &mvm_session_cmd);
946 if (ret < 0) {
947 pr_err("Fail in sending MVM_CONTROL_SESSION\n");
948 goto fail;
949 }
950 ret = wait_event_timeout(v->mvm_wait,
951 (v->mvm_state == CMD_STATUS_SUCCESS),
952 msecs_to_jiffies(TIMEOUT_MS));
953 if (!ret) {
954 pr_err("%s: wait_event timeout\n", __func__);
955 goto fail;
956 }
957 if (v->async_err > 0) {
958 pr_err("%s: DSP returned error[%s]\n",
959 __func__, adsp_err_get_err_str(
960 v->async_err));
961 ret = adsp_err_get_lnx_err_code(
962 v->async_err);
963 goto fail;
964 }
965 }
966 /* Get the created MVM handle. */
967 mvm_handle = voice_get_mvm_handle(v);
968 }
969 /* send cmd to create cvs session */
970 if (!cvs_handle) {
971 memset(cvs_session_cmd.cvs_session.name, 0,
972 sizeof(cvs_session_cmd.cvs_session.name));
973 if (!is_voip_session(v->session_id)) {
974 pr_debug("%s: creating CVS passive session\n",
975 __func__);
976
977 cvs_session_cmd.hdr.hdr_field = APR_HDR_FIELD(
978 APR_MSG_TYPE_SEQ_CMD,
979 APR_HDR_LEN(APR_HDR_SIZE),
980 APR_PKT_VER);
981 cvs_session_cmd.hdr.pkt_size =
982 APR_PKT_SIZE(APR_HDR_SIZE,
983 sizeof(cvs_session_cmd) -
984 APR_HDR_SIZE);
985 cvs_session_cmd.hdr.src_port =
986 voice_get_idx_for_session(v->session_id);
987 cvs_session_cmd.hdr.dest_port = 0;
988 cvs_session_cmd.hdr.token = 0;
989 cvs_session_cmd.hdr.opcode =
990 VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION;
991 if (is_volte_session(v->session_id)) {
992 strlcpy(cvs_session_cmd.cvs_session.name,
993 "default volte voice",
994 strlen("default volte voice")+1);
995 } else if (is_voice2_session(v->session_id)) {
996 strlcpy(cvs_session_cmd.cvs_session.name,
997 VOICE2_SESSION_VSID_STR,
998 strlen(VOICE2_SESSION_VSID_STR)+1);
999 } else if (is_qchat_session(v->session_id)) {
1000 strlcpy(cvs_session_cmd.cvs_session.name,
1001 QCHAT_SESSION_VSID_STR,
1002 strlen(QCHAT_SESSION_VSID_STR)+1);
1003 } else if (is_vowlan_session(v->session_id)) {
1004 strlcpy(cvs_session_cmd.cvs_session.name,
1005 VOWLAN_SESSION_VSID_STR,
1006 strlen(VOWLAN_SESSION_VSID_STR)+1);
1007 } else if (is_voicemmode1(v->session_id)) {
1008 strlcpy(cvs_session_cmd.cvs_session.name,
1009 VOICEMMODE1_VSID_STR,
1010 strlen(VOICEMMODE1_VSID_STR) + 1);
1011 } else if (is_voicemmode2(v->session_id)) {
1012 strlcpy(cvs_session_cmd.cvs_session.name,
1013 VOICEMMODE2_VSID_STR,
1014 strlen(VOICEMMODE2_VSID_STR) + 1);
1015 } else {
1016 strlcpy(cvs_session_cmd.cvs_session.name,
1017 "default modem voice",
1018 strlen("default modem voice")+1);
1019 }
1020 v->cvs_state = CMD_STATUS_FAIL;
1021 v->async_err = 0;
1022
1023 ret = apr_send_pkt(apr_cvs,
1024 (uint32_t *) &cvs_session_cmd);
1025 if (ret < 0) {
1026 pr_err("Fail in sending STREAM_CONTROL_SESSION\n");
1027 goto fail;
1028 }
1029 ret = wait_event_timeout(v->cvs_wait,
1030 (v->cvs_state == CMD_STATUS_SUCCESS),
1031 msecs_to_jiffies(TIMEOUT_MS));
1032 if (!ret) {
1033 pr_err("%s: wait_event timeout\n", __func__);
1034 goto fail;
1035 }
1036 if (v->async_err > 0) {
1037 pr_err("%s: DSP returned error[%s]\n",
1038 __func__, adsp_err_get_err_str(
1039 v->async_err));
1040 ret = adsp_err_get_lnx_err_code(
1041 v->async_err);
1042 goto fail;
1043 }
1044 /* Get the created CVS handle. */
1045 cvs_handle = voice_get_cvs_handle(v);
1046
1047 } else {
1048 pr_debug("%s: creating CVS full session\n", __func__);
1049
1050 cvs_full_ctl_cmd.hdr.hdr_field =
1051 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1052 APR_HDR_LEN(APR_HDR_SIZE),
1053 APR_PKT_VER);
1054
1055 cvs_full_ctl_cmd.hdr.pkt_size =
1056 APR_PKT_SIZE(APR_HDR_SIZE,
1057 sizeof(cvs_full_ctl_cmd) -
1058 APR_HDR_SIZE);
1059
1060 cvs_full_ctl_cmd.hdr.src_port =
1061 voice_get_idx_for_session(v->session_id);
1062 cvs_full_ctl_cmd.hdr.dest_port = 0;
1063 cvs_full_ctl_cmd.hdr.token = 0;
1064 cvs_full_ctl_cmd.hdr.opcode =
1065 VSS_ISTREAM_CMD_CREATE_FULL_CONTROL_SESSION;
1066 cvs_full_ctl_cmd.cvs_session.direction = 2;
1067 cvs_full_ctl_cmd.cvs_session.enc_media_type =
1068 common.mvs_info.media_type;
1069 cvs_full_ctl_cmd.cvs_session.dec_media_type =
1070 common.mvs_info.media_type;
1071 cvs_full_ctl_cmd.cvs_session.network_id =
1072 common.mvs_info.network_type;
1073 strlcpy(cvs_full_ctl_cmd.cvs_session.name,
1074 "default q6 voice",
1075 strlen("default q6 voice")+1);
1076
1077 v->cvs_state = CMD_STATUS_FAIL;
1078 v->async_err = 0;
1079
1080 ret = apr_send_pkt(apr_cvs,
1081 (uint32_t *) &cvs_full_ctl_cmd);
1082
1083 if (ret < 0) {
1084 pr_err("%s: Err %d sending CREATE_FULL_CTRL\n",
1085 __func__, ret);
1086 goto fail;
1087 }
1088 ret = wait_event_timeout(v->cvs_wait,
1089 (v->cvs_state == CMD_STATUS_SUCCESS),
1090 msecs_to_jiffies(TIMEOUT_MS));
1091 if (!ret) {
1092 pr_err("%s: wait_event timeout\n", __func__);
1093 goto fail;
1094 }
1095 if (v->async_err > 0) {
1096 pr_err("%s: DSP returned error[%s]\n",
1097 __func__, adsp_err_get_err_str(
1098 v->async_err));
1099 ret = adsp_err_get_lnx_err_code(
1100 v->async_err);
1101 goto fail;
1102 }
1103 /* Get the created CVS handle. */
1104 cvs_handle = voice_get_cvs_handle(v);
1105
1106 /* Attach MVM to CVS. */
1107 pr_debug("%s: Attach MVM to stream\n", __func__);
1108
1109 attach_stream_cmd.hdr.hdr_field =
1110 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1111 APR_HDR_LEN(APR_HDR_SIZE),
1112 APR_PKT_VER);
1113 attach_stream_cmd.hdr.pkt_size =
1114 APR_PKT_SIZE(APR_HDR_SIZE,
1115 sizeof(attach_stream_cmd) -
1116 APR_HDR_SIZE);
1117 attach_stream_cmd.hdr.src_port =
1118 voice_get_idx_for_session(v->session_id);
1119 attach_stream_cmd.hdr.dest_port = mvm_handle;
1120 attach_stream_cmd.hdr.token = 0;
1121 attach_stream_cmd.hdr.opcode =
1122 VSS_IMVM_CMD_ATTACH_STREAM;
1123 attach_stream_cmd.attach_stream.handle = cvs_handle;
1124
1125 v->mvm_state = CMD_STATUS_FAIL;
1126 v->async_err = 0;
1127 ret = apr_send_pkt(apr_mvm,
1128 (uint32_t *) &attach_stream_cmd);
1129 if (ret < 0) {
1130 pr_err("%s: Error %d sending ATTACH_STREAM\n",
1131 __func__, ret);
1132 goto fail;
1133 }
1134 ret = wait_event_timeout(v->mvm_wait,
1135 (v->mvm_state == CMD_STATUS_SUCCESS),
1136 msecs_to_jiffies(TIMEOUT_MS));
1137 if (!ret) {
1138 pr_err("%s: wait_event timeout\n", __func__);
1139 goto fail;
1140 }
1141 if (v->async_err > 0) {
1142 pr_err("%s: DSP returned error[%s]\n",
1143 __func__, adsp_err_get_err_str(
1144 v->async_err));
1145 ret = adsp_err_get_lnx_err_code(
1146 v->async_err);
1147 goto fail;
1148 }
1149 }
1150 }
1151 return 0;
1152
1153fail:
1154 return ret;
1155}
1156
1157static int voice_unmap_cal_block(struct voice_data *v, int cal_index)
1158{
1159 int result = 0;
1160 struct cal_block_data *cal_block;
1161
1162 if (common.cal_data[cal_index] == NULL) {
1163 pr_err("%s: Cal type is NULL, index %d!\n",
1164 __func__, cal_index);
1165
1166 goto done;
1167 }
1168
1169 mutex_lock(&common.cal_data[cal_index]->lock);
1170 cal_block = cal_utils_get_only_cal_block(
1171 common.cal_data[cal_index]);
1172 if (cal_block == NULL) {
1173 pr_err("%s: Cal block is NULL, index %d!\n",
1174 __func__, cal_index);
1175
1176 result = -EINVAL;
1177 goto unlock;
1178 }
1179
1180 if (cal_block->map_data.q6map_handle == 0) {
1181 pr_debug("%s: Q6 handle is not set!\n", __func__);
1182
1183 result = -EINVAL;
1184 goto unlock;
1185 }
1186
1187 mutex_lock(&common.common_lock);
1188 result = voice_send_mvm_unmap_memory_physical_cmd(
1189 v, cal_block->map_data.q6map_handle);
1190 if (result)
1191 pr_err("%s: Voice_send_mvm_unmap_memory_physical_cmd failed for session 0x%x, err %d!\n",
1192 __func__, v->session_id, result);
1193
1194 cal_block->map_data.q6map_handle = 0;
1195 mutex_unlock(&common.common_lock);
1196unlock:
1197 mutex_unlock(&common.cal_data[cal_index]->lock);
1198done:
1199 return result;
1200}
1201
1202static int voice_destroy_mvm_cvs_session(struct voice_data *v)
1203{
1204 int ret = 0;
1205 struct mvm_detach_stream_cmd detach_stream;
1206 struct apr_hdr mvm_destroy;
1207 struct apr_hdr cvs_destroy;
1208 void *apr_mvm, *apr_cvs;
1209 u16 mvm_handle, cvs_handle;
1210
1211 if (v == NULL) {
1212 pr_err("%s: v is NULL\n", __func__);
1213 return -EINVAL;
1214 }
1215 apr_mvm = common.apr_q6_mvm;
1216 apr_cvs = common.apr_q6_cvs;
1217
1218 if (!apr_mvm || !apr_cvs) {
1219 pr_err("%s: apr_mvm or apr_cvs is NULL\n", __func__);
1220 return -EINVAL;
1221 }
1222 mvm_handle = voice_get_mvm_handle(v);
1223 cvs_handle = voice_get_cvs_handle(v);
1224
1225 /* MVM, CVS sessions are destroyed only for Full control sessions. */
1226 if (is_voip_session(v->session_id)) {
1227 pr_debug("%s: MVM detach stream, VOC_STATE: %d\n", __func__,
1228 v->voc_state);
1229
1230 /* Detach voice stream. */
1231 detach_stream.hdr.hdr_field =
1232 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1233 APR_HDR_LEN(APR_HDR_SIZE),
1234 APR_PKT_VER);
1235 detach_stream.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1236 sizeof(detach_stream) - APR_HDR_SIZE);
1237 detach_stream.hdr.src_port =
1238 voice_get_idx_for_session(v->session_id);
1239 detach_stream.hdr.dest_port = mvm_handle;
1240 detach_stream.hdr.token = 0;
1241 detach_stream.hdr.opcode = VSS_IMVM_CMD_DETACH_STREAM;
1242 detach_stream.detach_stream.handle = cvs_handle;
1243
1244 v->mvm_state = CMD_STATUS_FAIL;
1245 v->async_err = 0;
1246 ret = apr_send_pkt(apr_mvm, (uint32_t *) &detach_stream);
1247 if (ret < 0) {
1248 pr_err("%s: Error %d sending DETACH_STREAM\n",
1249 __func__, ret);
1250
1251 goto fail;
1252 }
1253 ret = wait_event_timeout(v->mvm_wait,
1254 (v->mvm_state == CMD_STATUS_SUCCESS),
1255 msecs_to_jiffies(TIMEOUT_MS));
1256 if (!ret) {
1257 pr_err("%s: wait event timeout\n", __func__);
1258
1259 goto fail;
1260 }
1261 if (v->async_err > 0) {
1262 pr_err("%s: DSP returned error[%s]\n",
1263 __func__, adsp_err_get_err_str(
1264 v->async_err));
1265 ret = adsp_err_get_lnx_err_code(
1266 v->async_err);
1267 goto fail;
1268 }
1269
1270 /* Unmap memory */
1271 if (v->shmem_info.mem_handle != 0) {
1272 ret = voice_send_mvm_unmap_memory_physical_cmd(v,
1273 v->shmem_info.mem_handle);
1274 if (ret < 0) {
1275 pr_err("%s Memory_unmap for voip failed %d\n",
1276 __func__, ret);
1277
1278 goto fail;
1279 }
1280 v->shmem_info.mem_handle = 0;
1281 }
1282 }
1283
1284 /* Unmap Source Tracking shared memory if mapped earlier */
1285 voice_unmap_and_free_source_tracking_shared_memory(v);
1286
1287 if (is_voip_session(v->session_id) ||
1288 is_qchat_session(v->session_id) ||
1289 is_volte_session(v->session_id) ||
1290 is_vowlan_session(v->session_id) ||
1291 v->voc_state == VOC_ERROR || common.is_destroy_cvd) {
1292 /* Destroy CVS. */
1293 pr_debug("%s: CVS destroy session\n", __func__);
1294
1295 cvs_destroy.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1296 APR_HDR_LEN(APR_HDR_SIZE),
1297 APR_PKT_VER);
1298 cvs_destroy.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1299 sizeof(cvs_destroy) - APR_HDR_SIZE);
1300 cvs_destroy.src_port =
1301 voice_get_idx_for_session(v->session_id);
1302 cvs_destroy.dest_port = cvs_handle;
1303 cvs_destroy.token = 0;
1304 cvs_destroy.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
1305
1306 v->cvs_state = CMD_STATUS_FAIL;
1307 v->async_err = 0;
1308 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_destroy);
1309 if (ret < 0) {
1310 pr_err("%s: Error %d sending CVS DESTROY\n",
1311 __func__, ret);
1312
1313 goto fail;
1314 }
1315 ret = wait_event_timeout(v->cvs_wait,
1316 (v->cvs_state == CMD_STATUS_SUCCESS),
1317 msecs_to_jiffies(TIMEOUT_MS));
1318 if (!ret) {
1319 pr_err("%s: wait event timeout\n", __func__);
1320
1321 goto fail;
1322 }
1323 if (v->async_err > 0) {
1324 pr_err("%s: DSP returned error[%s]\n",
1325 __func__, adsp_err_get_err_str(
1326 v->async_err));
1327 ret = adsp_err_get_lnx_err_code(
1328 v->async_err);
1329 goto fail;
1330 }
1331 cvs_handle = 0;
1332 voice_set_cvs_handle(v, cvs_handle);
1333
1334 /* Unmap physical memory for all calibration buffers */
1335 if (!is_other_session_active(v->session_id)) {
1336 if (voice_unmap_cal_block(v, CVP_VOCPROC_CAL))
1337 pr_err("%s: Unmap VOCPROC cal failed\n",
1338 __func__);
1339 if (voice_unmap_cal_block(v, CVP_VOCVOL_CAL))
1340 pr_err("%s: Unmap VOCVOL cal failed\n",
1341 __func__);
1342 if (voice_unmap_cal_block(v, CVP_VOCDEV_CFG_CAL))
1343 pr_err("%s: Unmap VOCDEV_CFG cal failed\n",
1344 __func__);
1345 if (voice_unmap_cal_block(v, CVS_VOCSTRM_CAL))
1346 pr_err("%s: Unmap VOCSTRM cal failed\n",
1347 __func__);
1348 }
1349
1350 /* Destroy MVM. */
1351 pr_debug("%s: MVM destroy session\n", __func__);
1352
1353 mvm_destroy.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1354 APR_HDR_LEN(APR_HDR_SIZE),
1355 APR_PKT_VER);
1356 mvm_destroy.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1357 sizeof(mvm_destroy) - APR_HDR_SIZE);
1358 mvm_destroy.src_port =
1359 voice_get_idx_for_session(v->session_id);
1360 mvm_destroy.dest_port = mvm_handle;
1361 mvm_destroy.token = 0;
1362 mvm_destroy.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
1363
1364 v->mvm_state = CMD_STATUS_FAIL;
1365 v->async_err = 0;
1366
1367 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_destroy);
1368 if (ret < 0) {
1369 pr_err("%s: Error %d sending MVM DESTROY\n",
1370 __func__, ret);
1371
1372 goto fail;
1373 }
1374 ret = wait_event_timeout(v->mvm_wait,
1375 (v->mvm_state == CMD_STATUS_SUCCESS),
1376 msecs_to_jiffies(TIMEOUT_MS));
1377 if (!ret) {
1378 pr_err("%s: wait event timeout\n", __func__);
1379 goto fail;
1380 }
1381 if (v->async_err > 0) {
1382 pr_err("%s: DSP returned error[%s]\n",
1383 __func__, adsp_err_get_err_str(
1384 v->async_err));
1385 ret = adsp_err_get_lnx_err_code(
1386 v->async_err);
1387 goto fail;
1388 }
1389 mvm_handle = 0;
1390 voice_set_mvm_handle(v, mvm_handle);
1391 }
1392 return 0;
1393fail:
1394 return ret;
1395}
1396
1397static int voice_send_tty_mode_cmd(struct voice_data *v)
1398{
1399 int ret = 0;
1400 struct mvm_set_tty_mode_cmd mvm_tty_mode_cmd;
1401 void *apr_mvm;
1402 u16 mvm_handle;
1403
1404 if (v == NULL) {
1405 pr_err("%s: v is NULL\n", __func__);
1406 return -EINVAL;
1407 }
1408 apr_mvm = common.apr_q6_mvm;
1409
1410 if (!apr_mvm) {
1411 pr_err("%s: apr_mvm is NULL.\n", __func__);
1412 return -EINVAL;
1413 }
1414 mvm_handle = voice_get_mvm_handle(v);
1415
1416 /* send tty mode cmd to mvm */
1417 mvm_tty_mode_cmd.hdr.hdr_field = APR_HDR_FIELD(
1418 APR_MSG_TYPE_SEQ_CMD,
1419 APR_HDR_LEN(APR_HDR_SIZE),
1420 APR_PKT_VER);
1421 mvm_tty_mode_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1422 sizeof(mvm_tty_mode_cmd) -
1423 APR_HDR_SIZE);
1424 pr_debug("%s: pkt size = %d\n",
1425 __func__, mvm_tty_mode_cmd.hdr.pkt_size);
1426 mvm_tty_mode_cmd.hdr.src_port =
1427 voice_get_idx_for_session(v->session_id);
1428 mvm_tty_mode_cmd.hdr.dest_port = mvm_handle;
1429 mvm_tty_mode_cmd.hdr.token = 0;
1430 mvm_tty_mode_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_TTY_MODE;
1431 mvm_tty_mode_cmd.tty_mode.mode = v->tty_mode;
1432 pr_debug("tty mode =%d\n", mvm_tty_mode_cmd.tty_mode.mode);
1433
1434 v->mvm_state = CMD_STATUS_FAIL;
1435 v->async_err = 0;
1436 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_tty_mode_cmd);
1437 if (ret < 0) {
1438 pr_err("%s: Error %d sending SET_TTY_MODE\n",
1439 __func__, ret);
1440 goto fail;
1441 }
1442 ret = wait_event_timeout(v->mvm_wait,
1443 (v->mvm_state == CMD_STATUS_SUCCESS),
1444 msecs_to_jiffies(TIMEOUT_MS));
1445 if (!ret) {
1446 pr_err("%s: wait_event timeout\n", __func__);
1447 goto fail;
1448 }
1449 if (v->async_err > 0) {
1450 pr_err("%s: DSP returned error[%s]\n",
1451 __func__, adsp_err_get_err_str(
1452 v->async_err));
1453 ret = adsp_err_get_lnx_err_code(
1454 v->async_err);
1455 goto fail;
1456 }
1457 return 0;
1458fail:
1459 return ret;
1460}
1461
1462static int voice_send_set_pp_enable_cmd(struct voice_data *v,
1463 uint32_t module_id, int enable)
1464{
1465 struct cvs_set_pp_enable_cmd cvs_set_pp_cmd;
1466 int ret = 0;
1467 void *apr_cvs;
1468 u16 cvs_handle;
1469
1470 if (v == NULL) {
1471 pr_err("%s: v is NULL\n", __func__);
1472 return -EINVAL;
1473 }
1474 apr_cvs = common.apr_q6_cvs;
1475
1476 if (!apr_cvs) {
1477 pr_err("%s: apr_cvs is NULL.\n", __func__);
1478 return -EINVAL;
1479 }
1480 cvs_handle = voice_get_cvs_handle(v);
1481
1482 cvs_set_pp_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1483 APR_HDR_LEN(APR_HDR_SIZE),
1484 APR_PKT_VER);
1485 cvs_set_pp_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1486 sizeof(cvs_set_pp_cmd) -
1487 APR_HDR_SIZE);
1488 cvs_set_pp_cmd.hdr.src_port = voice_get_idx_for_session(v->session_id);
1489 cvs_set_pp_cmd.hdr.dest_port = cvs_handle;
1490 cvs_set_pp_cmd.hdr.token = 0;
1491 cvs_set_pp_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_UI_PROPERTY;
1492
1493 cvs_set_pp_cmd.vss_set_pp.module_id = module_id;
1494 cvs_set_pp_cmd.vss_set_pp.param_id = VOICE_PARAM_MOD_ENABLE;
1495 cvs_set_pp_cmd.vss_set_pp.param_size = MOD_ENABLE_PARAM_LEN;
1496 cvs_set_pp_cmd.vss_set_pp.reserved = 0;
1497 cvs_set_pp_cmd.vss_set_pp.enable = enable;
1498 cvs_set_pp_cmd.vss_set_pp.reserved_field = 0;
1499 pr_debug("voice_send_set_pp_enable_cmd, module_id=%d, enable=%d\n",
1500 module_id, enable);
1501
1502 v->cvs_state = CMD_STATUS_FAIL;
1503 v->async_err = 0;
1504 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_pp_cmd);
1505 if (ret < 0) {
1506 pr_err("Fail: sending cvs set pp enable,\n");
1507 goto fail;
1508 }
1509 ret = wait_event_timeout(v->cvs_wait,
1510 (v->cvs_state == CMD_STATUS_SUCCESS),
1511 msecs_to_jiffies(TIMEOUT_MS));
1512 if (!ret) {
1513 pr_err("%s: wait_event timeout\n", __func__);
1514 goto fail;
1515 }
1516 if (v->async_err > 0) {
1517 pr_err("%s: DSP returned error[%s]\n",
1518 __func__, adsp_err_get_err_str(
1519 v->async_err));
1520 ret = adsp_err_get_lnx_err_code(
1521 v->async_err);
1522 goto fail;
1523 }
1524 return 0;
1525fail:
1526 return ret;
1527}
1528
1529static int voice_send_hd_cmd(struct voice_data *v, int enable)
1530{
1531 struct mvm_set_hd_enable_cmd mvm_set_hd_cmd;
1532 int ret = 0;
1533 void *apr_mvm;
1534 u16 mvm_handle;
1535
1536 if (v == NULL) {
1537 pr_err("%s: v is NULL\n", __func__);
1538
1539 ret = -EINVAL;
1540 goto done;
1541 }
1542
1543 apr_mvm = common.apr_q6_mvm;
1544 if (!apr_mvm) {
1545 pr_err("%s: apr_mvm is NULL.\n", __func__);
1546
1547 ret = -EINVAL;
1548 goto done;
1549 }
1550
1551 mvm_handle = voice_get_mvm_handle(v);
1552 if (!mvm_handle) {
1553 pr_err("%s: mvm_handle is NULL\n", __func__);
1554
1555 ret = -EINVAL;
1556 goto done;
1557 }
1558
1559 mvm_set_hd_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1560 APR_HDR_LEN(APR_HDR_SIZE),
1561 APR_PKT_VER);
1562 mvm_set_hd_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1563 sizeof(mvm_set_hd_cmd) -
1564 APR_HDR_SIZE);
1565 mvm_set_hd_cmd.hdr.src_port = voice_get_idx_for_session(v->session_id);
1566 mvm_set_hd_cmd.hdr.dest_port = mvm_handle;
1567 mvm_set_hd_cmd.hdr.token = 0;
1568
1569 if (enable)
1570 mvm_set_hd_cmd.hdr.opcode = VSS_IHDVOICE_CMD_ENABLE;
1571 else
1572 mvm_set_hd_cmd.hdr.opcode = VSS_IHDVOICE_CMD_DISABLE;
1573
1574 pr_debug("%s: enable=%d\n", __func__, enable);
1575
1576 v->mvm_state = CMD_STATUS_FAIL;
1577 v->async_err = 0;
1578 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_hd_cmd);
1579 if (ret < 0) {
1580 pr_err("%s: Failed to sending mvm set HD Voice enable %d\n",
1581 __func__, ret);
1582
1583 ret = -EINVAL;
1584 goto done;
1585 }
1586
1587 ret = wait_event_timeout(v->mvm_wait,
1588 (v->mvm_state == CMD_STATUS_SUCCESS),
1589 msecs_to_jiffies(TIMEOUT_MS));
1590 if (!ret) {
1591 pr_err("%s: wait_event timeout\n", __func__);
1592
1593 ret = -EINVAL;
1594 goto done;
1595 }
1596 if (v->async_err > 0) {
1597 pr_err("%s: DSP returned error[%s]\n",
1598 __func__, adsp_err_get_err_str(
1599 v->async_err));
1600 ret = adsp_err_get_lnx_err_code(
1601 v->async_err);
1602 goto done;
1603 }
1604
1605done:
1606 return ret;
1607}
1608
1609static int voice_set_dtx(struct voice_data *v)
1610{
1611 int ret = 0;
1612 void *apr_cvs;
1613 u16 cvs_handle;
1614 struct cvs_set_enc_dtx_mode_cmd cvs_set_dtx;
1615
1616 if (v == NULL) {
1617 pr_err("%s: v is NULL\n", __func__);
1618 return -EINVAL;
1619 }
1620 apr_cvs = common.apr_q6_cvs;
1621
1622 if (!apr_cvs) {
1623 pr_err("%s: apr_cvs is NULL.\n", __func__);
1624 return -EINVAL;
1625 }
1626
1627 cvs_handle = voice_get_cvs_handle(v);
1628
1629 /* Set DTX */
1630 cvs_set_dtx.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1631 APR_HDR_LEN(APR_HDR_SIZE),
1632 APR_PKT_VER);
1633 cvs_set_dtx.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1634 sizeof(cvs_set_dtx) - APR_HDR_SIZE);
1635 cvs_set_dtx.hdr.src_port =
1636 voice_get_idx_for_session(v->session_id);
1637 cvs_set_dtx.hdr.dest_port = cvs_handle;
1638 cvs_set_dtx.hdr.token = 0;
1639 cvs_set_dtx.hdr.opcode = VSS_ISTREAM_CMD_SET_ENC_DTX_MODE;
1640 cvs_set_dtx.dtx_mode.enable = common.mvs_info.dtx_mode;
1641
1642 pr_debug("%s: Setting DTX %d\n", __func__, common.mvs_info.dtx_mode);
1643
1644 v->cvs_state = CMD_STATUS_FAIL;
1645 v->async_err = 0;
1646
1647 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_dtx);
1648 if (ret < 0) {
1649 pr_err("%s: Error %d sending SET_DTX\n", __func__, ret);
1650 return -EINVAL;
1651 }
1652
1653 ret = wait_event_timeout(v->cvs_wait,
1654 (v->cvs_state == CMD_STATUS_SUCCESS),
1655 msecs_to_jiffies(TIMEOUT_MS));
1656 if (!ret) {
1657 pr_err("%s: wait_event timeout\n", __func__);
1658 return -EINVAL;
1659 }
1660 if (v->async_err > 0) {
1661 pr_err("%s: DSP returned error[%s]\n",
1662 __func__, adsp_err_get_err_str(
1663 v->async_err));
1664 ret = adsp_err_get_lnx_err_code(
1665 v->async_err);
1666 return ret;
1667 }
1668
1669 return 0;
1670}
1671
1672static int voice_send_mvm_media_type_cmd(struct voice_data *v)
1673{
1674 struct vss_imvm_cmd_set_cal_media_type_t mvm_set_cal_media_type;
1675 int ret = 0;
1676 void *apr_mvm;
1677 u16 mvm_handle;
1678
1679 if (v == NULL) {
1680 pr_err("%s: v is NULL\n", __func__);
1681 return -EINVAL;
1682 }
1683 apr_mvm = common.apr_q6_mvm;
1684
1685 if (!apr_mvm) {
1686 pr_err("%s: apr_mvm is NULL.\n", __func__);
1687 return -EINVAL;
1688 }
1689 mvm_handle = voice_get_mvm_handle(v);
1690
1691 mvm_set_cal_media_type.hdr.hdr_field =
1692 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1693 APR_HDR_LEN(APR_HDR_SIZE),
1694 APR_PKT_VER);
1695 mvm_set_cal_media_type.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1696 sizeof(mvm_set_cal_media_type) -
1697 APR_HDR_SIZE);
1698 mvm_set_cal_media_type.hdr.src_port =
1699 voice_get_idx_for_session(v->session_id);
1700 mvm_set_cal_media_type.hdr.dest_port = mvm_handle;
1701 mvm_set_cal_media_type.hdr.token = 0;
1702 mvm_set_cal_media_type.hdr.opcode = VSS_IMVM_CMD_SET_CAL_MEDIA_TYPE;
1703 mvm_set_cal_media_type.media_id = common.mvs_info.media_type;
1704 pr_debug("%s: setting media_id as %x\n",
1705 __func__, mvm_set_cal_media_type.media_id);
1706
1707 v->mvm_state = CMD_STATUS_FAIL;
1708 v->async_err = 0;
1709 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_cal_media_type);
1710 if (ret < 0) {
1711 pr_err("%s: Error %d sending media type\n", __func__, ret);
1712 goto fail;
1713 }
1714
1715 ret = wait_event_timeout(v->mvm_wait,
1716 (v->mvm_state == CMD_STATUS_SUCCESS),
1717 msecs_to_jiffies(TIMEOUT_MS));
1718 if (!ret) {
1719 pr_err("%s: wait_event timeout %d\n", __func__, ret);
1720 goto fail;
1721 }
1722 if (v->async_err > 0) {
1723 pr_err("%s: DSP returned error[%s]\n",
1724 __func__, adsp_err_get_err_str(
1725 v->async_err));
1726 ret = adsp_err_get_lnx_err_code(
1727 v->async_err);
1728 goto fail;
1729 }
1730 return 0;
1731fail:
1732 return ret;
1733}
1734
1735static int voice_send_dtmf_rx_detection_cmd(struct voice_data *v,
1736 uint32_t enable)
1737{
1738 int ret = 0;
1739 void *apr_cvs;
1740 u16 cvs_handle;
1741 struct cvs_set_rx_dtmf_detection_cmd cvs_dtmf_rx_detection;
1742
1743 if (v == NULL) {
1744 pr_err("%s: v is NULL\n", __func__);
1745 return -EINVAL;
1746 }
1747 apr_cvs = common.apr_q6_cvs;
1748
1749 if (!apr_cvs) {
1750 pr_err("%s: apr_cvs is NULL.\n", __func__);
1751 return -EINVAL;
1752 }
1753
1754 cvs_handle = voice_get_cvs_handle(v);
1755
1756 /* Set SET_DTMF_RX_DETECTION */
1757 cvs_dtmf_rx_detection.hdr.hdr_field =
1758 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1759 APR_HDR_LEN(APR_HDR_SIZE),
1760 APR_PKT_VER);
1761 cvs_dtmf_rx_detection.hdr.pkt_size =
1762 APR_PKT_SIZE(APR_HDR_SIZE,
1763 sizeof(cvs_dtmf_rx_detection) - APR_HDR_SIZE);
1764 cvs_dtmf_rx_detection.hdr.src_port =
1765 voice_get_idx_for_session(v->session_id);
1766 cvs_dtmf_rx_detection.hdr.dest_port = cvs_handle;
1767 cvs_dtmf_rx_detection.hdr.token = 0;
1768 cvs_dtmf_rx_detection.hdr.opcode =
1769 VSS_ISTREAM_CMD_SET_RX_DTMF_DETECTION;
1770 cvs_dtmf_rx_detection.cvs_dtmf_det.enable = enable;
1771
1772 v->cvs_state = CMD_STATUS_FAIL;
1773 v->async_err = 0;
1774
1775 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_dtmf_rx_detection);
1776 if (ret < 0) {
1777 pr_err("%s: Error %d sending SET_DTMF_RX_DETECTION\n",
1778 __func__,
1779 ret);
1780 return -EINVAL;
1781 }
1782
1783 ret = wait_event_timeout(v->cvs_wait,
1784 (v->cvs_state == CMD_STATUS_SUCCESS),
1785 msecs_to_jiffies(TIMEOUT_MS));
1786
1787 if (!ret) {
1788 pr_err("%s: wait_event timeout\n", __func__);
1789 return -EINVAL;
1790 }
1791 if (v->async_err > 0) {
1792 pr_err("%s: DSP returned error[%s]\n",
1793 __func__, adsp_err_get_err_str(
1794 v->async_err));
1795 ret = adsp_err_get_lnx_err_code(
1796 v->async_err);
1797 return ret;
1798 }
1799
1800 return ret;
1801}
1802
1803void voc_disable_dtmf_det_on_active_sessions(void)
1804{
1805 struct voice_data *v = NULL;
1806 int i;
1807
1808 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
1809 v = &common.voice[i];
1810 if ((v->dtmf_rx_detect_en) &&
1811 is_voc_state_active(v->voc_state)) {
1812
1813 pr_debug("disable dtmf det on ses_id=%d\n",
1814 v->session_id);
1815 voice_send_dtmf_rx_detection_cmd(v, 0);
1816 }
1817 }
1818}
1819
1820int voc_enable_dtmf_rx_detection(uint32_t session_id, uint32_t enable)
1821{
1822 struct voice_data *v = voice_get_session(session_id);
1823 int ret = 0;
1824
1825 if (v == NULL) {
1826 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
1827 return -EINVAL;
1828 }
1829
1830 mutex_lock(&v->lock);
1831 v->dtmf_rx_detect_en = enable;
1832
1833 if (is_voc_state_active(v->voc_state))
1834 ret = voice_send_dtmf_rx_detection_cmd(v,
1835 v->dtmf_rx_detect_en);
1836
1837 mutex_unlock(&v->lock);
1838
1839 return ret;
1840}
1841
1842void voc_set_destroy_cvd_flag(bool is_destroy_cvd)
1843{
1844 pr_debug("%s: %d\n", __func__, is_destroy_cvd);
1845 common.is_destroy_cvd = is_destroy_cvd;
1846}
1847
1848int voc_alloc_cal_shared_memory(void)
1849{
1850 int rc = 0;
1851
1852 mutex_lock(&common.common_lock);
1853 if (is_cal_memory_allocated()) {
1854 pr_debug("%s: Calibration shared buffer already allocated",
1855 __func__);
1856 } else {
1857 /* Allocate memory for calibration memory map table. */
1858 rc = voice_alloc_cal_mem_map_table();
1859 if ((rc < 0) && (rc != -EPROBE_DEFER)) {
1860 pr_err("%s: Failed to allocate cal memory, err=%d",
1861 __func__, rc);
1862 }
1863 }
1864 mutex_unlock(&common.common_lock);
1865
1866 return rc;
1867}
1868
1869int voc_alloc_voip_shared_memory(void)
1870{
1871 int rc = 0;
1872
1873 /* Allocate shared memory for OOB Voip */
1874 rc = voice_alloc_oob_shared_mem();
1875 if (rc < 0) {
1876 pr_err("%s: Failed to alloc shared memory for OOB rc:%d\n",
1877 __func__, rc);
1878 } else {
1879 /* Allocate mem map table for OOB */
1880 rc = voice_alloc_oob_mem_table();
1881 if (rc < 0) {
1882 pr_err("%s: Failed to alloc mem map talbe rc:%d\n",
1883 __func__, rc);
1884
1885 voice_free_oob_shared_mem();
1886 }
1887 }
1888
1889 return rc;
1890}
1891
1892static int is_cal_memory_allocated(void)
1893{
1894 bool ret;
1895
1896 if (common.cal_mem_map_table.client != NULL &&
1897 common.cal_mem_map_table.handle != NULL)
1898 ret = true;
1899 else
1900 ret = false;
1901
1902 return ret;
1903}
1904
1905
1906static int free_cal_map_table(void)
1907{
1908 int ret = 0;
1909
1910 if ((common.cal_mem_map_table.client == NULL) ||
1911 (common.cal_mem_map_table.handle == NULL))
1912 goto done;
1913
1914 ret = msm_audio_ion_free(common.cal_mem_map_table.client,
1915 common.cal_mem_map_table.handle);
1916 if (ret < 0)
1917 pr_err("%s: msm_audio_ion_free failed:\n", __func__);
1918
1919done:
1920 common.cal_mem_map_table.client = NULL;
1921 common.cal_mem_map_table.handle = NULL;
1922 return ret;
1923}
1924
1925static int is_rtac_memory_allocated(void)
1926{
1927 bool ret;
1928
1929 if (common.rtac_mem_map_table.client != NULL &&
1930 common.rtac_mem_map_table.handle != NULL)
1931 ret = true;
1932 else
1933 ret = false;
1934
1935 return ret;
1936}
1937
1938static int free_rtac_map_table(void)
1939{
1940 int ret = 0;
1941
1942 if ((common.rtac_mem_map_table.client == NULL) ||
1943 (common.rtac_mem_map_table.handle == NULL))
1944 goto done;
1945
1946 ret = msm_audio_ion_free(common.rtac_mem_map_table.client,
1947 common.rtac_mem_map_table.handle);
1948 if (ret < 0)
1949 pr_err("%s: msm_audio_ion_free failed:\n", __func__);
1950
1951done:
1952 common.rtac_mem_map_table.client = NULL;
1953 common.rtac_mem_map_table.handle = NULL;
1954 return ret;
1955}
1956
1957
1958static int is_voip_memory_allocated(void)
1959{
1960 bool ret;
1961 struct voice_data *v = voice_get_session(
1962 common.voice[VOC_PATH_FULL].session_id);
1963
1964 if (v == NULL) {
1965 pr_err("%s: v is NULL, session_id:%d\n", __func__,
1966 common.voice[VOC_PATH_FULL].session_id);
1967
1968 ret = false;
1969 goto done;
1970 }
1971
1972 mutex_lock(&common.common_lock);
1973 if (v->shmem_info.sh_buf.client != NULL &&
1974 v->shmem_info.sh_buf.handle != NULL)
1975 ret = true;
1976 else
1977 ret = false;
1978 mutex_unlock(&common.common_lock);
1979
1980done:
1981 return ret;
1982}
1983
1984static int voice_config_cvs_vocoder_amr_rate(struct voice_data *v)
1985{
1986 int ret = 0;
1987 void *apr_cvs;
1988 u16 cvs_handle;
1989 struct cvs_set_amr_enc_rate_cmd cvs_set_amr_rate;
1990
1991 if (v == NULL) {
1992 pr_err("%s: v is NULL\n", __func__);
1993
1994 ret = -EINVAL;
1995 goto done;
1996 }
1997 apr_cvs = common.apr_q6_cvs;
1998
1999 if (!apr_cvs) {
2000 pr_err("%s: apr_cvs is NULL.\n", __func__);
2001
2002 ret = -EINVAL;
2003 goto done;
2004 }
2005
2006 cvs_handle = voice_get_cvs_handle(v);
2007
2008 pr_debug("%s: Setting AMR rate. Media Type: %d\n", __func__,
2009 common.mvs_info.media_type);
2010
2011 cvs_set_amr_rate.hdr.hdr_field =
2012 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2013 APR_HDR_LEN(APR_HDR_SIZE),
2014 APR_PKT_VER);
2015 cvs_set_amr_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2016 sizeof(cvs_set_amr_rate) - APR_HDR_SIZE);
2017 cvs_set_amr_rate.hdr.src_port =
2018 voice_get_idx_for_session(v->session_id);
2019 cvs_set_amr_rate.hdr.dest_port = cvs_handle;
2020 cvs_set_amr_rate.hdr.token = 0;
2021
2022 if (common.mvs_info.media_type == VSS_MEDIA_ID_AMR_NB_MODEM)
2023 cvs_set_amr_rate.hdr.opcode =
2024 VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE;
2025 else if (common.mvs_info.media_type == VSS_MEDIA_ID_AMR_WB_MODEM)
2026 cvs_set_amr_rate.hdr.opcode =
2027 VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE;
2028
2029 cvs_set_amr_rate.amr_rate.mode = common.mvs_info.rate;
2030
2031 v->cvs_state = CMD_STATUS_FAIL;
2032 v->async_err = 0;
2033
2034 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_amr_rate);
2035 if (ret < 0) {
2036 pr_err("%s: Error %d sending SET_AMR_RATE\n",
2037 __func__, ret);
2038
2039 goto done;
2040 }
2041 ret = wait_event_timeout(v->cvs_wait,
2042 (v->cvs_state == CMD_STATUS_SUCCESS),
2043 msecs_to_jiffies(TIMEOUT_MS));
2044 if (!ret) {
2045 pr_err("%s: wait_event timeout\n", __func__);
2046
2047 ret = -EINVAL;
2048 goto done;
2049 }
2050 if (v->async_err > 0) {
2051 pr_err("%s: DSP returned error[%s]\n",
2052 __func__, adsp_err_get_err_str(
2053 v->async_err));
2054 ret = adsp_err_get_lnx_err_code(
2055 v->async_err);
2056 goto done;
2057 }
2058
2059 return 0;
2060done:
2061 return ret;
2062}
2063
2064static int voice_config_cvs_vocoder(struct voice_data *v)
2065{
2066 int ret = 0;
2067 void *apr_cvs;
2068 u16 cvs_handle;
2069 /* Set media type. */
2070 struct cvs_set_media_type_cmd cvs_set_media_cmd;
2071
2072 if (v == NULL) {
2073 pr_err("%s: v is NULL\n", __func__);
2074 return -EINVAL;
2075 }
2076 apr_cvs = common.apr_q6_cvs;
2077
2078 if (!apr_cvs) {
2079 pr_err("%s: apr_cvs is NULL.\n", __func__);
2080 return -EINVAL;
2081 }
2082
2083 cvs_handle = voice_get_cvs_handle(v);
2084
2085 cvs_set_media_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2086 APR_HDR_LEN(APR_HDR_SIZE),
2087 APR_PKT_VER);
2088 cvs_set_media_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2089 sizeof(cvs_set_media_cmd) -
2090 APR_HDR_SIZE);
2091 cvs_set_media_cmd.hdr.src_port =
2092 voice_get_idx_for_session(v->session_id);
2093 cvs_set_media_cmd.hdr.dest_port = cvs_handle;
2094 cvs_set_media_cmd.hdr.token = 0;
2095 cvs_set_media_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_MEDIA_TYPE;
2096 cvs_set_media_cmd.media_type.tx_media_id = common.mvs_info.media_type;
2097 cvs_set_media_cmd.media_type.rx_media_id = common.mvs_info.media_type;
2098
2099 v->cvs_state = CMD_STATUS_FAIL;
2100 v->async_err = 0;
2101
2102 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_media_cmd);
2103 if (ret < 0) {
2104 pr_err("%s: Error %d sending SET_MEDIA_TYPE\n",
2105 __func__, ret);
2106
2107 goto fail;
2108 }
2109 ret = wait_event_timeout(v->cvs_wait,
2110 (v->cvs_state == CMD_STATUS_SUCCESS),
2111 msecs_to_jiffies(TIMEOUT_MS));
2112 if (!ret) {
2113 pr_err("%s: wait_event timeout\n", __func__);
2114
2115 goto fail;
2116 }
2117 if (v->async_err > 0) {
2118 pr_err("%s: DSP returned error[%s]\n",
2119 __func__, adsp_err_get_err_str(
2120 v->async_err));
2121 ret = adsp_err_get_lnx_err_code(
2122 v->async_err);
2123 goto fail;
2124 }
2125 /* Set encoder properties. */
2126 switch (common.mvs_info.media_type) {
2127 case VSS_MEDIA_ID_EVRC_MODEM:
2128 case VSS_MEDIA_ID_4GV_NB_MODEM:
2129 case VSS_MEDIA_ID_4GV_WB_MODEM:
2130 case VSS_MEDIA_ID_4GV_NW_MODEM: {
2131 struct cvs_set_cdma_enc_minmax_rate_cmd cvs_set_cdma_rate;
2132
2133 pr_debug("Setting EVRC min-max rate\n");
2134
2135 cvs_set_cdma_rate.hdr.hdr_field =
2136 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2137 APR_HDR_LEN(APR_HDR_SIZE),
2138 APR_PKT_VER);
2139 cvs_set_cdma_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2140 sizeof(cvs_set_cdma_rate) - APR_HDR_SIZE);
2141 cvs_set_cdma_rate.hdr.src_port =
2142 voice_get_idx_for_session(v->session_id);
2143 cvs_set_cdma_rate.hdr.dest_port = cvs_handle;
2144 cvs_set_cdma_rate.hdr.token = 0;
2145 cvs_set_cdma_rate.hdr.opcode =
2146 VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE;
2147 cvs_set_cdma_rate.cdma_rate.min_rate =
2148 common.mvs_info.evrc_min_rate;
2149 cvs_set_cdma_rate.cdma_rate.max_rate =
2150 common.mvs_info.evrc_max_rate;
2151
2152 v->cvs_state = CMD_STATUS_FAIL;
2153 v->async_err = 0;
2154
2155 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_cdma_rate);
2156 if (ret < 0) {
2157 pr_err("%s: Error %d sending SET_EVRC_MINMAX_RATE\n",
2158 __func__, ret);
2159 goto fail;
2160 }
2161 ret = wait_event_timeout(v->cvs_wait,
2162 (v->cvs_state == CMD_STATUS_SUCCESS),
2163 msecs_to_jiffies(TIMEOUT_MS));
2164 if (!ret) {
2165 pr_err("%s: wait_event timeout\n", __func__);
2166
2167 goto fail;
2168 }
2169 if (v->async_err > 0) {
2170 pr_err("%s: DSP returned error[%s]\n",
2171 __func__, adsp_err_get_err_str(
2172 v->async_err));
2173 ret = adsp_err_get_lnx_err_code(
2174 v->async_err);
2175 goto fail;
2176 }
2177
2178 if (common.mvs_info.media_type != VSS_MEDIA_ID_EVRC_MODEM) {
2179 ret = voice_set_dtx(v);
2180 if (ret < 0)
2181 goto fail;
2182 }
2183
2184 break;
2185 }
2186 case VSS_MEDIA_ID_AMR_NB_MODEM:
2187 case VSS_MEDIA_ID_AMR_WB_MODEM: {
2188 ret = voice_config_cvs_vocoder_amr_rate(v);
2189 if (ret) {
2190 pr_err("%s: Failed to update vocoder rate. %d\n",
2191 __func__, ret);
2192
2193 goto fail;
2194 }
2195
2196 ret = voice_set_dtx(v);
2197 if (ret < 0)
2198 goto fail;
2199
2200 break;
2201 }
2202 case VSS_MEDIA_ID_G729:
2203 case VSS_MEDIA_ID_G711_ALAW:
2204 case VSS_MEDIA_ID_G711_MULAW: {
2205 ret = voice_set_dtx(v);
2206
2207 break;
2208 }
2209 default:
2210 /* Do nothing. */
2211 break;
2212 }
2213 return 0;
2214
2215fail:
2216 return ret;
2217}
2218
2219int voc_update_amr_vocoder_rate(uint32_t session_id)
2220{
2221 int ret = 0;
2222 struct voice_data *v;
2223
2224 pr_debug("%s: session_id:%d", __func__, session_id);
2225
2226 v = voice_get_session(session_id);
2227
2228 if (v == NULL) {
2229 pr_err("%s: v is NULL, session_id:%d\n", __func__,
2230 session_id);
2231
2232 ret = -EINVAL;
2233 goto done;
2234 }
2235
2236 mutex_lock(&v->lock);
2237 ret = voice_config_cvs_vocoder_amr_rate(v);
2238 mutex_unlock(&v->lock);
2239
2240done:
2241 return ret;
2242}
2243
2244static int voice_send_start_voice_cmd(struct voice_data *v)
2245{
2246 struct apr_hdr mvm_start_voice_cmd;
2247 int ret = 0;
2248 void *apr_mvm;
2249 u16 mvm_handle;
2250
2251 if (v == NULL) {
2252 pr_err("%s: v is NULL\n", __func__);
2253 return -EINVAL;
2254 }
2255 apr_mvm = common.apr_q6_mvm;
2256
2257 if (!apr_mvm) {
2258 pr_err("%s: apr_mvm is NULL.\n", __func__);
2259 return -EINVAL;
2260 }
2261 mvm_handle = voice_get_mvm_handle(v);
2262
2263 mvm_start_voice_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2264 APR_HDR_LEN(APR_HDR_SIZE),
2265 APR_PKT_VER);
2266 mvm_start_voice_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2267 sizeof(mvm_start_voice_cmd) - APR_HDR_SIZE);
2268 pr_debug("send mvm_start_voice_cmd pkt size = %d\n",
2269 mvm_start_voice_cmd.pkt_size);
2270 mvm_start_voice_cmd.src_port =
2271 voice_get_idx_for_session(v->session_id);
2272 mvm_start_voice_cmd.dest_port = mvm_handle;
2273 mvm_start_voice_cmd.token = 0;
2274 mvm_start_voice_cmd.opcode = VSS_IMVM_CMD_START_VOICE;
2275
2276 v->mvm_state = CMD_STATUS_FAIL;
2277 v->async_err = 0;
2278 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_start_voice_cmd);
2279 if (ret < 0) {
2280 pr_err("Fail in sending VSS_IMVM_CMD_START_VOICE\n");
2281 goto fail;
2282 }
2283 ret = wait_event_timeout(v->mvm_wait,
2284 (v->mvm_state == CMD_STATUS_SUCCESS),
2285 msecs_to_jiffies(TIMEOUT_MS));
2286 if (!ret) {
2287 pr_err("%s: wait_event timeout\n", __func__);
2288 goto fail;
2289 }
2290 if (v->async_err > 0) {
2291 pr_err("%s: DSP returned error[%s]\n",
2292 __func__, adsp_err_get_err_str(
2293 v->async_err));
2294 ret = adsp_err_get_lnx_err_code(
2295 v->async_err);
2296 goto fail;
2297 }
2298 return 0;
2299fail:
2300 return ret;
2301}
2302
2303static void voc_get_tx_rx_topology(struct voice_data *v,
2304 uint32_t *tx_topology_id,
2305 uint32_t *rx_topology_id)
2306{
2307 uint32_t tx_id = 0;
2308 uint32_t rx_id = 0;
2309
2310 if (v->lch_mode == VOICE_LCH_START || v->disable_topology) {
2311 pr_debug("%s: Setting TX and RX topology to NONE for LCH\n",
2312 __func__);
2313
2314 tx_id = VSS_IVOCPROC_TOPOLOGY_ID_NONE;
2315 rx_id = VSS_IVOCPROC_TOPOLOGY_ID_NONE;
2316 } else {
2317 tx_id = voice_get_topology(CVP_VOC_TX_TOPOLOGY_CAL);
2318 rx_id = voice_get_topology(CVP_VOC_RX_TOPOLOGY_CAL);
2319 }
2320
2321 *tx_topology_id = tx_id;
2322 *rx_topology_id = rx_id;
2323}
2324
2325static int voice_send_set_device_cmd(struct voice_data *v)
2326{
2327 struct cvp_set_device_cmd cvp_setdev_cmd;
2328 int ret = 0;
2329 void *apr_cvp;
2330 u16 cvp_handle;
2331
2332 if (v == NULL) {
2333 pr_err("%s: v is NULL\n", __func__);
2334 return -EINVAL;
2335 }
2336 apr_cvp = common.apr_q6_cvp;
2337
2338 if (!apr_cvp) {
2339 pr_err("%s: apr_cvp is NULL.\n", __func__);
2340 return -EINVAL;
2341 }
2342 cvp_handle = voice_get_cvp_handle(v);
2343
2344 /* set device and wait for response */
2345 cvp_setdev_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2346 APR_HDR_LEN(APR_HDR_SIZE),
2347 APR_PKT_VER);
2348 cvp_setdev_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2349 sizeof(cvp_setdev_cmd) - APR_HDR_SIZE);
2350 pr_debug(" send create cvp setdev, pkt size = %d\n",
2351 cvp_setdev_cmd.hdr.pkt_size);
2352 cvp_setdev_cmd.hdr.src_port =
2353 voice_get_idx_for_session(v->session_id);
2354 cvp_setdev_cmd.hdr.dest_port = cvp_handle;
2355 cvp_setdev_cmd.hdr.token = 0;
2356
2357 if (voice_get_cvd_int_version(common.cvd_version) >=
2358 CVD_INT_VERSION_2_2)
2359 cvp_setdev_cmd.hdr.opcode =
2360 VSS_IVOCPROC_CMD_SET_DEVICE_V3;
2361 else
2362 cvp_setdev_cmd.hdr.opcode =
2363 VSS_IVOCPROC_CMD_SET_DEVICE_V2;
2364
2365 voc_get_tx_rx_topology(v,
2366 &cvp_setdev_cmd.cvp_set_device_v2.tx_topology_id,
2367 &cvp_setdev_cmd.cvp_set_device_v2.rx_topology_id);
2368
2369 cvp_setdev_cmd.cvp_set_device_v2.tx_port_id = v->dev_tx.port_id;
2370 cvp_setdev_cmd.cvp_set_device_v2.rx_port_id = v->dev_rx.port_id;
2371
2372 if (common.ec_ref_ext) {
2373 cvp_setdev_cmd.cvp_set_device_v2.vocproc_mode =
2374 VSS_IVOCPROC_VOCPROC_MODE_EC_EXT_MIXING;
2375 cvp_setdev_cmd.cvp_set_device_v2.ec_ref_port_id =
2376 common.ec_media_fmt_info.port_id;
2377 } else {
2378 cvp_setdev_cmd.cvp_set_device_v2.vocproc_mode =
2379 VSS_IVOCPROC_VOCPROC_MODE_EC_INT_MIXING;
2380 cvp_setdev_cmd.cvp_set_device_v2.ec_ref_port_id =
2381 VSS_IVOCPROC_PORT_ID_NONE;
2382 }
2383 pr_debug("topology=%d , tx_port_id=%d, rx_port_id=%d\n",
2384 cvp_setdev_cmd.cvp_set_device_v2.tx_topology_id,
2385 cvp_setdev_cmd.cvp_set_device_v2.tx_port_id,
2386 cvp_setdev_cmd.cvp_set_device_v2.rx_port_id);
2387
2388 v->cvp_state = CMD_STATUS_FAIL;
2389 v->async_err = 0;
2390 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_setdev_cmd);
2391 if (ret < 0) {
2392 pr_err("Fail in sending VSS_IVOCPROC_CMD_SET_DEVICE\n");
2393 goto fail;
2394 }
2395
2396 ret = wait_event_timeout(v->cvp_wait,
2397 (v->cvp_state == CMD_STATUS_SUCCESS),
2398 msecs_to_jiffies(TIMEOUT_MS));
2399 if (!ret) {
2400 pr_err("%s: wait_event timeout\n", __func__);
2401 goto fail;
2402 }
2403 if (v->async_err > 0) {
2404 pr_err("%s: DSP returned error[%s]\n",
2405 __func__, adsp_err_get_err_str(
2406 v->async_err));
2407 ret = adsp_err_get_lnx_err_code(
2408 v->async_err);
2409 goto fail;
2410 }
2411
2412 return 0;
2413fail:
2414 return ret;
2415}
2416
2417static int voice_send_stop_voice_cmd(struct voice_data *v)
2418{
2419 struct apr_hdr mvm_stop_voice_cmd;
2420 int ret = 0;
2421 void *apr_mvm;
2422 u16 mvm_handle;
2423
2424 if (v == NULL) {
2425 pr_err("%s: v is NULL\n", __func__);
2426 return -EINVAL;
2427 }
2428 apr_mvm = common.apr_q6_mvm;
2429
2430 if (!apr_mvm) {
2431 pr_err("%s: apr_mvm is NULL.\n", __func__);
2432 return -EINVAL;
2433 }
2434 mvm_handle = voice_get_mvm_handle(v);
2435
2436 mvm_stop_voice_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2437 APR_HDR_LEN(APR_HDR_SIZE),
2438 APR_PKT_VER);
2439 mvm_stop_voice_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2440 sizeof(mvm_stop_voice_cmd) - APR_HDR_SIZE);
2441 pr_debug("send mvm_stop_voice_cmd pkt size = %d\n",
2442 mvm_stop_voice_cmd.pkt_size);
2443 mvm_stop_voice_cmd.src_port =
2444 voice_get_idx_for_session(v->session_id);
2445 mvm_stop_voice_cmd.dest_port = mvm_handle;
2446 mvm_stop_voice_cmd.token = 0;
2447 mvm_stop_voice_cmd.opcode = VSS_IMVM_CMD_STOP_VOICE;
2448
2449 v->mvm_state = CMD_STATUS_FAIL;
2450 v->async_err = 0;
2451 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_stop_voice_cmd);
2452 if (ret < 0) {
2453 pr_err("Fail in sending VSS_IMVM_CMD_STOP_VOICE\n");
2454 goto fail;
2455 }
2456 ret = wait_event_timeout(v->mvm_wait,
2457 (v->mvm_state == CMD_STATUS_SUCCESS),
2458 msecs_to_jiffies(TIMEOUT_MS));
2459 if (!ret) {
2460 pr_err("%s: wait_event timeout\n", __func__);
2461 goto fail;
2462 }
2463 if (v->async_err > 0) {
2464 pr_err("%s: DSP returned error[%s]\n",
2465 __func__, adsp_err_get_err_str(
2466 v->async_err));
2467 ret = adsp_err_get_lnx_err_code(
2468 v->async_err);
2469 goto fail;
2470 }
2471
2472 return 0;
2473fail:
2474 return ret;
2475}
2476static int voice_get_cal(struct cal_block_data **cal_block,
2477 int cal_block_idx,
2478 struct cal_block_data **col_data,
2479 int col_data_idx, int session_id)
2480{
2481 int ret = 0;
2482
2483 *cal_block = cal_utils_get_only_cal_block(
2484 common.cal_data[cal_block_idx]);
2485 if (*cal_block == NULL) {
2486 pr_err("%s: No cal data for cal %d!\n",
2487 __func__, cal_block_idx);
2488
2489 ret = -ENODEV;
2490 goto done;
2491 }
2492 ret = remap_cal_data(*cal_block, session_id);
2493 if (ret < 0) {
2494 pr_err("%s: Remap_cal_data failed for cal %d!\n",
2495 __func__, cal_block_idx);
2496
2497 ret = -ENODEV;
2498 goto done;
2499 }
2500
2501 if (col_data == NULL)
2502 goto done;
2503
2504 *col_data = cal_utils_get_only_cal_block(
2505 common.cal_data[col_data_idx]);
2506 if (*col_data == NULL) {
2507 pr_err("%s: No cal data for cal %d!\n",
2508 __func__, col_data_idx);
2509
2510 ret = -ENODEV;
2511 goto done;
2512 }
2513done:
2514 return ret;
2515}
2516
2517static int voice_send_cvs_register_cal_cmd(struct voice_data *v)
2518{
2519 struct cvs_register_cal_data_cmd cvs_reg_cal_cmd;
2520 struct cal_block_data *cal_block = NULL;
2521 struct cal_block_data *col_data = NULL;
2522 int ret = 0;
2523
2524 memset(&cvs_reg_cal_cmd, 0, sizeof(cvs_reg_cal_cmd));
2525
2526 if (v == NULL) {
2527 pr_err("%s: v is NULL\n", __func__);
2528
2529 ret = -EINVAL;
2530 goto done;
2531 }
2532
2533 if (!common.apr_q6_cvs) {
2534 pr_err("%s: apr_cvs is NULL\n", __func__);
2535
2536 ret = -EINVAL;
2537 goto done;
2538 }
2539
2540 mutex_lock(&common.cal_data[CVS_VOCSTRM_CAL]->lock);
2541 mutex_lock(&common.cal_data[CVS_VOCSTRM_COL_CAL]->lock);
2542
2543 ret = voice_get_cal(&cal_block, CVS_VOCSTRM_CAL, &col_data,
2544 CVS_VOCSTRM_COL_CAL, v->session_id);
2545 if (ret < 0) {
2546 pr_err("%s: Voice_get_cal failed for cal %d!\n",
2547 __func__, CVS_VOCSTRM_CAL);
2548
2549 goto unlock;
2550 }
2551
2552 memcpy(&cvs_reg_cal_cmd.cvs_cal_data.column_info[0],
2553 (void *) &((struct audio_cal_info_voc_col *)
2554 col_data->cal_info)->data,
2555 col_data->cal_data.size);
2556
2557 cvs_reg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2558 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2559 cvs_reg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2560 sizeof(cvs_reg_cal_cmd) - APR_HDR_SIZE);
2561 cvs_reg_cal_cmd.hdr.src_port =
2562 voice_get_idx_for_session(v->session_id);
2563 cvs_reg_cal_cmd.hdr.dest_port = voice_get_cvs_handle(v);
2564 cvs_reg_cal_cmd.hdr.token = 0;
2565 if (common.is_per_vocoder_cal_enabled)
2566 cvs_reg_cal_cmd.hdr.opcode =
2567 VSS_ISTREAM_CMD_REGISTER_STATIC_CALIBRATION_DATA;
2568 else
2569 cvs_reg_cal_cmd.hdr.opcode =
2570 VSS_ISTREAM_CMD_REGISTER_CALIBRATION_DATA_V2;
2571
2572 cvs_reg_cal_cmd.cvs_cal_data.cal_mem_handle =
2573 cal_block->map_data.q6map_handle;
2574 cvs_reg_cal_cmd.cvs_cal_data.cal_mem_address_lsw =
2575 lower_32_bits(cal_block->cal_data.paddr);
2576 cvs_reg_cal_cmd.cvs_cal_data.cal_mem_address_msw =
2577 msm_audio_populate_upper_32_bits(cal_block->cal_data.paddr);
2578 cvs_reg_cal_cmd.cvs_cal_data.cal_mem_size =
2579 cal_block->cal_data.size;
2580
2581 v->cvs_state = CMD_STATUS_FAIL;
2582 v->async_err = 0;
2583 ret = apr_send_pkt(common.apr_q6_cvs, (uint32_t *) &cvs_reg_cal_cmd);
2584 if (ret < 0) {
2585 pr_err("%s: Error %d registering CVS cal\n", __func__, ret);
2586
2587 ret = -EINVAL;
2588 goto unlock;
2589 }
2590 ret = wait_event_timeout(v->cvs_wait,
2591 (v->cvs_state == CMD_STATUS_SUCCESS),
2592 msecs_to_jiffies(TIMEOUT_MS));
2593 if (!ret) {
2594 pr_err("%s: Command timeout\n", __func__);
2595
2596 ret = -EINVAL;
2597 goto unlock;
2598 }
2599 if (v->async_err > 0) {
2600 pr_err("%s: DSP returned error[%s]\n",
2601 __func__, adsp_err_get_err_str(
2602 v->async_err));
2603 ret = adsp_err_get_lnx_err_code(
2604 v->async_err);
2605 goto unlock;
2606 }
2607unlock:
2608 mutex_unlock(&common.cal_data[CVS_VOCSTRM_COL_CAL]->lock);
2609 mutex_unlock(&common.cal_data[CVS_VOCSTRM_CAL]->lock);
2610done:
2611 return ret;
2612}
2613
2614static int voice_send_cvs_deregister_cal_cmd(struct voice_data *v)
2615{
2616 struct cvs_deregister_cal_data_cmd cvs_dereg_cal_cmd;
2617 int ret = 0;
2618
2619 memset(&cvs_dereg_cal_cmd, 0, sizeof(cvs_dereg_cal_cmd));
2620
2621 if (v == NULL) {
2622 pr_err("%s: v is NULL\n", __func__);
2623
2624 ret = -EINVAL;
2625 goto done;
2626 }
2627
2628 if (!common.apr_q6_cvs) {
2629 pr_err("%s: apr_cvs is NULL\n", __func__);
2630
2631 ret = -EPERM;
2632 goto done;
2633 }
2634
2635 cvs_dereg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2636 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2637 cvs_dereg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2638 sizeof(cvs_dereg_cal_cmd) - APR_HDR_SIZE);
2639 cvs_dereg_cal_cmd.hdr.src_port =
2640 voice_get_idx_for_session(v->session_id);
2641 cvs_dereg_cal_cmd.hdr.dest_port = voice_get_cvs_handle(v);
2642 cvs_dereg_cal_cmd.hdr.token = 0;
2643 if (common.is_per_vocoder_cal_enabled)
2644 cvs_dereg_cal_cmd.hdr.opcode =
2645 VSS_ISTREAM_CMD_DEREGISTER_STATIC_CALIBRATION_DATA;
2646 else
2647 cvs_dereg_cal_cmd.hdr.opcode =
2648 VSS_ISTREAM_CMD_DEREGISTER_CALIBRATION_DATA;
2649
2650 v->cvs_state = CMD_STATUS_FAIL;
2651 v->async_err = 0;
2652 ret = apr_send_pkt(common.apr_q6_cvs, (uint32_t *) &cvs_dereg_cal_cmd);
2653 if (ret < 0) {
2654 pr_err("%s: Error %d de-registering CVS cal\n", __func__, ret);
2655 goto done;
2656 }
2657 ret = wait_event_timeout(v->cvs_wait,
2658 (v->cvs_state == CMD_STATUS_SUCCESS),
2659 msecs_to_jiffies(TIMEOUT_MS));
2660 if (!ret) {
2661 pr_err("%s: Command timeout\n", __func__);
2662 goto done;
2663 }
2664 if (v->async_err > 0) {
2665 pr_err("%s: DSP returned error[%s]\n",
2666 __func__, adsp_err_get_err_str(
2667 v->async_err));
2668 ret = adsp_err_get_lnx_err_code(
2669 v->async_err);
2670 goto done;
2671 }
2672
2673done:
2674 return ret;
2675
2676}
2677
2678static int voice_send_cvp_create_cmd(struct voice_data *v)
2679{
2680 struct cvp_create_full_ctl_session_cmd cvp_session_cmd;
2681 void *apr_cvp;
2682 int ret = 0;
2683
2684 if (v == NULL) {
2685 pr_err("%s: v is NULL\n", __func__);
2686 ret = -EINVAL;
2687 goto done;
2688 }
2689
2690 apr_cvp = common.apr_q6_cvp;
2691 if (!apr_cvp) {
2692 pr_err("%s: apr_cvp is NULL.\n", __func__);
2693
2694 ret = -EINVAL;
2695 goto done;
2696 }
2697
2698 /* create cvp session and wait for response */
2699 cvp_session_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2700 APR_HDR_LEN(APR_HDR_SIZE),
2701 APR_PKT_VER);
2702 cvp_session_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2703 sizeof(cvp_session_cmd) - APR_HDR_SIZE);
2704 pr_debug("%s: send create cvp session, pkt size = %d\n",
2705 __func__, cvp_session_cmd.hdr.pkt_size);
2706 cvp_session_cmd.hdr.src_port =
2707 voice_get_idx_for_session(v->session_id);
2708 cvp_session_cmd.hdr.dest_port = 0;
2709 cvp_session_cmd.hdr.token = 0;
2710
2711 if (voice_get_cvd_int_version(common.cvd_version) >=
2712 CVD_INT_VERSION_2_2)
2713 cvp_session_cmd.hdr.opcode =
2714 VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION_V3;
2715 else
2716 cvp_session_cmd.hdr.opcode =
2717 VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION_V2;
2718
2719 voc_get_tx_rx_topology(v,
2720 &cvp_session_cmd.cvp_session.tx_topology_id,
2721 &cvp_session_cmd.cvp_session.rx_topology_id);
2722
2723 cvp_session_cmd.cvp_session.direction = 2; /*tx and rx*/
2724 cvp_session_cmd.cvp_session.tx_port_id = v->dev_tx.port_id;
2725 cvp_session_cmd.cvp_session.rx_port_id = v->dev_rx.port_id;
2726 cvp_session_cmd.cvp_session.profile_id =
2727 VSS_ICOMMON_CAL_NETWORK_ID_NONE;
2728 if (common.ec_ref_ext) {
2729 cvp_session_cmd.cvp_session.vocproc_mode =
2730 VSS_IVOCPROC_VOCPROC_MODE_EC_EXT_MIXING;
2731 cvp_session_cmd.cvp_session.ec_ref_port_id =
2732 common.ec_media_fmt_info.port_id;
2733 } else {
2734 cvp_session_cmd.cvp_session.vocproc_mode =
2735 VSS_IVOCPROC_VOCPROC_MODE_EC_INT_MIXING;
2736 cvp_session_cmd.cvp_session.ec_ref_port_id =
2737 VSS_IVOCPROC_PORT_ID_NONE;
2738 }
2739
2740 pr_debug("tx_topology: %d tx_port_id=%d, rx_port_id=%d, mode: 0x%x\n",
2741 cvp_session_cmd.cvp_session.tx_topology_id,
2742 cvp_session_cmd.cvp_session.tx_port_id,
2743 cvp_session_cmd.cvp_session.rx_port_id,
2744 cvp_session_cmd.cvp_session.vocproc_mode);
2745 pr_debug("rx_topology: %d, profile_id: 0x%x, pkt_size: %d\n",
2746 cvp_session_cmd.cvp_session.rx_topology_id,
2747 cvp_session_cmd.cvp_session.profile_id,
2748 cvp_session_cmd.hdr.pkt_size);
2749
2750 v->cvp_state = CMD_STATUS_FAIL;
2751 v->async_err = 0;
2752 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_session_cmd);
2753 if (ret < 0) {
2754 pr_err("Fail in sending VOCPROC_FULL_CONTROL_SESSION\n");
2755
2756 ret = -EINVAL;
2757 goto done;
2758 }
2759
2760 ret = wait_event_timeout(v->cvp_wait,
2761 (v->cvp_state == CMD_STATUS_SUCCESS),
2762 msecs_to_jiffies(TIMEOUT_MS));
2763 if (!ret) {
2764 pr_err("%s: wait_event timeout\n", __func__);
2765
2766 ret = -EINVAL;
2767 goto done;
2768 }
2769 if (v->async_err > 0) {
2770 pr_err("%s: DSP returned error[%s]\n",
2771 __func__, adsp_err_get_err_str(
2772 v->async_err));
2773 ret = adsp_err_get_lnx_err_code(
2774 v->async_err);
2775 goto done;
2776 }
2777
2778done:
2779 return ret;
2780}
2781
2782static int voice_send_cvp_register_dev_cfg_cmd(struct voice_data *v)
2783{
2784 struct cvp_register_dev_cfg_cmd cvp_reg_dev_cfg_cmd;
2785 struct cal_block_data *cal_block = NULL;
2786 int ret = 0;
2787
2788 memset(&cvp_reg_dev_cfg_cmd, 0, sizeof(cvp_reg_dev_cfg_cmd));
2789
2790 if (v == NULL) {
2791 pr_err("%s: v is NULL\n", __func__);
2792
2793 ret = -EINVAL;
2794 goto done;
2795 }
2796
2797 if (!common.apr_q6_cvp) {
2798 pr_err("%s: apr_cvp is NULL\n", __func__);
2799
2800 ret = -EPERM;
2801 goto done;
2802 }
2803
2804 mutex_lock(&common.cal_data[CVP_VOCDEV_CFG_CAL]->lock);
2805
2806 ret = voice_get_cal(&cal_block, CVP_VOCDEV_CFG_CAL, NULL,
2807 0, v->session_id);
2808 if (ret < 0) {
2809 pr_err("%s: Voice_get_cal failed for cal %d!\n",
2810 __func__, CVP_VOCDEV_CFG_CAL);
2811
2812 goto unlock;
2813 }
2814
2815 cvp_reg_dev_cfg_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2816 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2817 cvp_reg_dev_cfg_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2818 sizeof(cvp_reg_dev_cfg_cmd) - APR_HDR_SIZE);
2819 cvp_reg_dev_cfg_cmd.hdr.src_port =
2820 voice_get_idx_for_session(v->session_id);
2821 cvp_reg_dev_cfg_cmd.hdr.dest_port = voice_get_cvp_handle(v);
2822 cvp_reg_dev_cfg_cmd.hdr.token = 0;
2823 cvp_reg_dev_cfg_cmd.hdr.opcode =
2824 VSS_IVOCPROC_CMD_REGISTER_DEVICE_CONFIG;
2825
2826 cvp_reg_dev_cfg_cmd.cvp_dev_cfg_data.mem_handle =
2827 cal_block->map_data.q6map_handle;
2828 cvp_reg_dev_cfg_cmd.cvp_dev_cfg_data.mem_address_lsw =
2829 lower_32_bits(cal_block->cal_data.paddr);
2830 cvp_reg_dev_cfg_cmd.cvp_dev_cfg_data.mem_address_msw =
2831 msm_audio_populate_upper_32_bits(cal_block->cal_data.paddr);
2832 cvp_reg_dev_cfg_cmd.cvp_dev_cfg_data.mem_size =
2833 cal_block->cal_data.size;
2834
2835 v->cvp_state = CMD_STATUS_FAIL;
2836 v->async_err = 0;
2837 ret = apr_send_pkt(common.apr_q6_cvp,
2838 (uint32_t *) &cvp_reg_dev_cfg_cmd);
2839 if (ret < 0) {
2840 pr_err("%s: Error %d registering CVP dev cfg cal\n",
2841 __func__, ret);
2842
2843 ret = -EINVAL;
2844 goto unlock;
2845 }
2846 ret = wait_event_timeout(v->cvp_wait,
2847 (v->cvp_state == CMD_STATUS_SUCCESS),
2848 msecs_to_jiffies(TIMEOUT_MS));
2849 if (!ret) {
2850 pr_err("%s: Command timeout\n", __func__);
2851
2852 ret = -EINVAL;
2853 goto unlock;
2854 }
2855 if (v->async_err > 0) {
2856 pr_err("%s: DSP returned error[%s]\n",
2857 __func__, adsp_err_get_err_str(
2858 v->async_err));
2859 ret = adsp_err_get_lnx_err_code(
2860 v->async_err);
2861 goto unlock;
2862 }
2863unlock:
2864 mutex_unlock(&common.cal_data[CVP_VOCDEV_CFG_CAL]->lock);
2865done:
2866 return ret;
2867}
2868
2869static int voice_send_cvp_deregister_dev_cfg_cmd(struct voice_data *v)
2870{
2871 struct cvp_deregister_dev_cfg_cmd cvp_dereg_dev_cfg_cmd;
2872 int ret = 0;
2873
2874 memset(&cvp_dereg_dev_cfg_cmd, 0, sizeof(cvp_dereg_dev_cfg_cmd));
2875
2876 if (v == NULL) {
2877 pr_err("%s: v is NULL\n", __func__);
2878
2879 ret = -EINVAL;
2880 goto done;
2881 }
2882
2883 if (!common.apr_q6_cvp) {
2884 pr_err("%s: apr_cvp is NULL\n", __func__);
2885
2886 ret = -EPERM;
2887 goto done;
2888 }
2889
2890 cvp_dereg_dev_cfg_cmd.hdr.hdr_field =
2891 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2892 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2893 cvp_dereg_dev_cfg_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2894 sizeof(cvp_dereg_dev_cfg_cmd) - APR_HDR_SIZE);
2895 cvp_dereg_dev_cfg_cmd.hdr.src_port =
2896 voice_get_idx_for_session(v->session_id);
2897 cvp_dereg_dev_cfg_cmd.hdr.dest_port = voice_get_cvp_handle(v);
2898 cvp_dereg_dev_cfg_cmd.hdr.token = 0;
2899 cvp_dereg_dev_cfg_cmd.hdr.opcode =
2900 VSS_IVOCPROC_CMD_DEREGISTER_DEVICE_CONFIG;
2901
2902 v->cvp_state = CMD_STATUS_FAIL;
2903 v->async_err = 0;
2904 ret = apr_send_pkt(common.apr_q6_cvp,
2905 (uint32_t *) &cvp_dereg_dev_cfg_cmd);
2906 if (ret < 0) {
2907 pr_err("%s: Error %d de-registering CVP dev cfg cal\n",
2908 __func__, ret);
2909 goto done;
2910 }
2911 ret = wait_event_timeout(v->cvp_wait,
2912 (v->cvp_state == CMD_STATUS_SUCCESS),
2913 msecs_to_jiffies(TIMEOUT_MS));
2914 if (!ret) {
2915 pr_err("%s: Command timeout\n", __func__);
2916 goto done;
2917 }
2918 if (v->async_err > 0) {
2919 pr_err("%s: DSP returned error[%s]\n",
2920 __func__, adsp_err_get_err_str(
2921 v->async_err));
2922 ret = adsp_err_get_lnx_err_code(
2923 v->async_err);
2924 goto done;
2925 }
2926
2927done:
2928 return ret;
2929}
2930
2931static int voice_send_cvp_register_cal_cmd(struct voice_data *v)
2932{
2933 struct cvp_register_cal_data_cmd cvp_reg_cal_cmd;
2934 struct cal_block_data *cal_block = NULL;
2935 struct cal_block_data *col_data = NULL;
2936 int ret = 0;
2937
2938 memset(&cvp_reg_cal_cmd, 0, sizeof(cvp_reg_cal_cmd));
2939
2940 if (v == NULL) {
2941 pr_err("%s: v is NULL\n", __func__);
2942
2943 ret = -EINVAL;
2944 goto done;
2945 }
2946
2947 if (!common.apr_q6_cvp) {
2948 pr_err("%s: apr_cvp is NULL\n", __func__);
2949
2950 ret = -EINVAL;
2951 goto done;
2952 }
2953
2954 mutex_lock(&common.cal_data[CVP_VOCPROC_CAL]->lock);
2955 mutex_lock(&common.cal_data[CVP_VOCPROC_COL_CAL]->lock);
2956
2957 ret = voice_get_cal(&cal_block, CVP_VOCPROC_CAL, &col_data,
2958 CVP_VOCPROC_COL_CAL, v->session_id);
2959 if (ret < 0) {
2960 pr_err("%s: Voice_get_cal failed for cal %d!\n",
2961 __func__, CVP_VOCPROC_CAL);
2962
2963 goto unlock;
2964 }
2965
2966 v->dev_tx.dev_id = ((struct audio_cal_info_vocproc *)
2967 cal_block->cal_info)->tx_acdb_id;
2968 v->dev_rx.dev_id = ((struct audio_cal_info_vocproc *)
2969 cal_block->cal_info)->rx_acdb_id;
2970 pr_debug("%s: %s: Tx acdb id = %d and Rx acdb id = %d", __func__,
2971 voc_get_session_name(v->session_id), v->dev_tx.dev_id,
2972 v->dev_rx.dev_id);
2973
2974 memcpy(&cvp_reg_cal_cmd.cvp_cal_data.column_info[0],
2975 (void *) &((struct audio_cal_info_voc_col *)
2976 col_data->cal_info)->data,
2977 col_data->cal_data.size);
2978
2979 cvp_reg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2980 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2981 cvp_reg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2982 sizeof(cvp_reg_cal_cmd) - APR_HDR_SIZE);
2983 cvp_reg_cal_cmd.hdr.src_port =
2984 voice_get_idx_for_session(v->session_id);
2985 cvp_reg_cal_cmd.hdr.dest_port = voice_get_cvp_handle(v);
2986 cvp_reg_cal_cmd.hdr.token = 0;
2987 if (common.is_per_vocoder_cal_enabled)
2988 cvp_reg_cal_cmd.hdr.opcode =
2989 VSS_IVOCPROC_CMD_REGISTER_STATIC_CALIBRATION_DATA;
2990 else
2991 cvp_reg_cal_cmd.hdr.opcode =
2992 VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA_V2;
2993
2994 cvp_reg_cal_cmd.cvp_cal_data.cal_mem_handle =
2995 cal_block->map_data.q6map_handle;
2996 cvp_reg_cal_cmd.cvp_cal_data.cal_mem_address_lsw =
2997 lower_32_bits(cal_block->cal_data.paddr);
2998 cvp_reg_cal_cmd.cvp_cal_data.cal_mem_address_msw =
2999 msm_audio_populate_upper_32_bits(cal_block->cal_data.paddr);
3000 cvp_reg_cal_cmd.cvp_cal_data.cal_mem_size =
3001 cal_block->cal_data.size;
3002
3003 v->cvp_state = CMD_STATUS_FAIL;
3004 v->async_err = 0;
3005 ret = apr_send_pkt(common.apr_q6_cvp, (uint32_t *) &cvp_reg_cal_cmd);
3006 if (ret < 0) {
3007 pr_err("%s: Error %d registering CVP cal\n", __func__, ret);
3008
3009 ret = -EINVAL;
3010 goto unlock;
3011 }
3012 ret = wait_event_timeout(v->cvp_wait,
3013 (v->cvp_state == CMD_STATUS_SUCCESS),
3014 msecs_to_jiffies(TIMEOUT_MS));
3015 if (!ret) {
3016 pr_err("%s: Command timeout\n", __func__);
3017
3018 ret = -EINVAL;
3019 goto unlock;
3020 }
3021 if (v->async_err > 0) {
3022 pr_err("%s: DSP returned error[%s]\n",
3023 __func__, adsp_err_get_err_str(
3024 v->async_err));
3025 ret = adsp_err_get_lnx_err_code(
3026 v->async_err);
3027 goto unlock;
3028 }
3029unlock:
3030 mutex_unlock(&common.cal_data[CVP_VOCPROC_COL_CAL]->lock);
3031 mutex_unlock(&common.cal_data[CVP_VOCPROC_CAL]->lock);
3032done:
3033 return ret;
3034}
3035
3036static int voice_send_cvp_deregister_cal_cmd(struct voice_data *v)
3037{
3038 struct cvp_deregister_cal_data_cmd cvp_dereg_cal_cmd;
3039 int ret = 0;
3040
3041 memset(&cvp_dereg_cal_cmd, 0, sizeof(cvp_dereg_cal_cmd));
3042
3043 if (v == NULL) {
3044 pr_err("%s: v is NULL\n", __func__);
3045
3046 ret = -EINVAL;
3047 goto done;
3048 }
3049
3050 if (!common.apr_q6_cvp) {
3051 pr_err("%s: apr_cvp is NULL.\n", __func__);
3052
3053 ret = -EPERM;
3054 goto done;
3055 }
3056
3057 cvp_dereg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
3058 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
3059 cvp_dereg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
3060 sizeof(cvp_dereg_cal_cmd) - APR_HDR_SIZE);
3061 cvp_dereg_cal_cmd.hdr.src_port =
3062 voice_get_idx_for_session(v->session_id);
3063 cvp_dereg_cal_cmd.hdr.dest_port = voice_get_cvp_handle(v);
3064 cvp_dereg_cal_cmd.hdr.token = 0;
3065 if (common.is_per_vocoder_cal_enabled)
3066 cvp_dereg_cal_cmd.hdr.opcode =
3067 VSS_IVOCPROC_CMD_DEREGISTER_STATIC_CALIBRATION_DATA;
3068 else
3069 cvp_dereg_cal_cmd.hdr.opcode =
3070 VSS_IVOCPROC_CMD_DEREGISTER_CALIBRATION_DATA;
3071
3072 v->cvp_state = CMD_STATUS_FAIL;
3073 v->async_err = 0;
3074 ret = apr_send_pkt(common.apr_q6_cvp, (uint32_t *) &cvp_dereg_cal_cmd);
3075 if (ret < 0) {
3076 pr_err("%s: Error %d de-registering CVP cal\n", __func__, ret);
3077 goto done;
3078 }
3079 ret = wait_event_timeout(v->cvp_wait,
3080 (v->cvp_state == CMD_STATUS_SUCCESS),
3081 msecs_to_jiffies(TIMEOUT_MS));
3082 if (!ret) {
3083 pr_err("%s: Command timeout\n", __func__);
3084 goto done;
3085 }
3086 if (v->async_err > 0) {
3087 pr_err("%s: DSP returned error[%s]\n",
3088 __func__, adsp_err_get_err_str(
3089 v->async_err));
3090 ret = adsp_err_get_lnx_err_code(
3091 v->async_err);
3092 goto done;
3093 }
3094
3095done:
3096 return ret;
3097}
3098
3099static int voice_send_cvp_register_vol_cal_cmd(struct voice_data *v)
3100{
3101 struct cvp_register_vol_cal_data_cmd cvp_reg_vol_cal_cmd;
3102 struct cal_block_data *cal_block = NULL;
3103 struct cal_block_data *col_data = NULL;
3104 int ret = 0;
3105
3106 memset(&cvp_reg_vol_cal_cmd, 0, sizeof(cvp_reg_vol_cal_cmd));
3107
3108 if (v == NULL) {
3109 pr_err("%s: v is NULL\n", __func__);
3110
3111 ret = -EINVAL;
3112 goto done;
3113 }
3114
3115 if (!common.apr_q6_cvp) {
3116 pr_err("%s: apr_cvp is NULL\n", __func__);
3117
3118 ret = -EINVAL;
3119 goto done;
3120 }
3121
3122 mutex_lock(&common.cal_data[CVP_VOCVOL_CAL]->lock);
3123 mutex_lock(&common.cal_data[CVP_VOCVOL_COL_CAL]->lock);
3124
3125 ret = voice_get_cal(&cal_block, CVP_VOCVOL_CAL, &col_data,
3126 CVP_VOCVOL_COL_CAL, v->session_id);
3127 if (ret < 0) {
3128 pr_err("%s: Voice_get_cal failed for cal %d!\n",
3129 __func__, CVP_VOCVOL_CAL);
3130
3131 goto unlock;
3132 }
3133
3134 memcpy(&cvp_reg_vol_cal_cmd.cvp_vol_cal_data.column_info[0],
3135 (void *) &((struct audio_cal_info_voc_col *)
3136 col_data->cal_info)->data,
3137 col_data->cal_data.size);
3138
3139 cvp_reg_vol_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
3140 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
3141 cvp_reg_vol_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
3142 sizeof(cvp_reg_vol_cal_cmd) - APR_HDR_SIZE);
3143 cvp_reg_vol_cal_cmd.hdr.src_port =
3144 voice_get_idx_for_session(v->session_id);
3145 cvp_reg_vol_cal_cmd.hdr.dest_port = voice_get_cvp_handle(v);
3146 cvp_reg_vol_cal_cmd.hdr.token = 0;
3147 if (common.is_per_vocoder_cal_enabled)
3148 cvp_reg_vol_cal_cmd.hdr.opcode =
3149 VSS_IVOCPROC_CMD_REGISTER_DYNAMIC_CALIBRATION_DATA;
3150 else
3151 cvp_reg_vol_cal_cmd.hdr.opcode =
3152 VSS_IVOCPROC_CMD_REGISTER_VOL_CALIBRATION_DATA;
3153
3154 cvp_reg_vol_cal_cmd.cvp_vol_cal_data.cal_mem_handle =
3155 cal_block->map_data.q6map_handle;
3156 cvp_reg_vol_cal_cmd.cvp_vol_cal_data.cal_mem_address_lsw =
3157 lower_32_bits(cal_block->cal_data.paddr);
3158 cvp_reg_vol_cal_cmd.cvp_vol_cal_data.cal_mem_address_msw =
3159 msm_audio_populate_upper_32_bits(cal_block->cal_data.paddr);
3160 cvp_reg_vol_cal_cmd.cvp_vol_cal_data.cal_mem_size =
3161 cal_block->cal_data.size;
3162
3163 v->cvp_state = CMD_STATUS_FAIL;
3164 v->async_err = 0;
3165 ret = apr_send_pkt(common.apr_q6_cvp,
3166 (uint32_t *) &cvp_reg_vol_cal_cmd);
3167 if (ret < 0) {
3168 pr_err("%s: Error %d registering CVP vol cal\n", __func__, ret);
3169
3170 ret = -EINVAL;
3171 goto unlock;
3172 }
3173 ret = wait_event_timeout(v->cvp_wait,
3174 (v->cvp_state == CMD_STATUS_SUCCESS),
3175 msecs_to_jiffies(TIMEOUT_MS));
3176 if (!ret) {
3177 pr_err("%s: Command timeout\n", __func__);
3178
3179 ret = -EINVAL;
3180 goto unlock;
3181 }
3182 if (v->async_err > 0) {
3183 pr_err("%s: DSP returned error[%s]\n",
3184 __func__, adsp_err_get_err_str(
3185 v->async_err));
3186 ret = adsp_err_get_lnx_err_code(
3187 v->async_err);
3188 goto unlock;
3189 }
3190unlock:
3191 mutex_unlock(&common.cal_data[CVP_VOCVOL_COL_CAL]->lock);
3192 mutex_unlock(&common.cal_data[CVP_VOCVOL_CAL]->lock);
3193done:
3194 return ret;
3195}
3196
3197static int voice_send_cvp_deregister_vol_cal_cmd(struct voice_data *v)
3198{
3199 struct cvp_deregister_vol_cal_data_cmd cvp_dereg_vol_cal_cmd;
3200 int ret = 0;
3201
3202 memset(&cvp_dereg_vol_cal_cmd, 0, sizeof(cvp_dereg_vol_cal_cmd));
3203
3204 if (v == NULL) {
3205 pr_err("%s: v is NULL\n", __func__);
3206
3207 ret = -EINVAL;
3208 goto done;
3209 }
3210
3211 if (!common.apr_q6_cvp) {
3212 pr_err("%s: apr_cvp is NULL\n", __func__);
3213
3214 ret = -EPERM;
3215 goto done;
3216 }
3217
3218 cvp_dereg_vol_cal_cmd.hdr.hdr_field =
3219 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
3220 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
3221 cvp_dereg_vol_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
3222 sizeof(cvp_dereg_vol_cal_cmd) - APR_HDR_SIZE);
3223 cvp_dereg_vol_cal_cmd.hdr.src_port =
3224 voice_get_idx_for_session(v->session_id);
3225 cvp_dereg_vol_cal_cmd.hdr.dest_port = voice_get_cvp_handle(v);
3226 cvp_dereg_vol_cal_cmd.hdr.token = 0;
3227 if (common.is_per_vocoder_cal_enabled)
3228 cvp_dereg_vol_cal_cmd.hdr.opcode =
3229 VSS_IVOCPROC_CMD_DEREGISTER_DYNAMIC_CALIBRATION_DATA;
3230 else
3231 cvp_dereg_vol_cal_cmd.hdr.opcode =
3232 VSS_IVOCPROC_CMD_DEREGISTER_VOL_CALIBRATION_DATA;
3233
3234 v->cvp_state = CMD_STATUS_FAIL;
3235 v->async_err = 0;
3236 ret = apr_send_pkt(common.apr_q6_cvp,
3237 (uint32_t *) &cvp_dereg_vol_cal_cmd);
3238 if (ret < 0) {
3239 pr_err("%s: Error %d de-registering CVP vol cal\n",
3240 __func__, ret);
3241 goto done;
3242 }
3243 ret = wait_event_timeout(v->cvp_wait,
3244 (v->cvp_state == CMD_STATUS_SUCCESS),
3245 msecs_to_jiffies(TIMEOUT_MS));
3246 if (!ret) {
3247 pr_err("%s: Command timeout\n", __func__);
3248 goto done;
3249 }
3250 if (v->async_err > 0) {
3251 pr_err("%s: DSP returned error[%s]\n",
3252 __func__, adsp_err_get_err_str(
3253 v->async_err));
3254 ret = adsp_err_get_lnx_err_code(
3255 v->async_err);
3256 goto done;
3257 }
3258
3259done:
3260 return ret;
3261}
3262
3263static int voice_map_memory_physical_cmd(struct voice_data *v,
3264 struct mem_map_table *table_info,
3265 dma_addr_t phys,
3266 uint32_t size,
3267 uint32_t token)
3268{
3269 struct vss_imemory_cmd_map_physical_t mvm_map_phys_cmd;
3270 uint32_t *memtable;
3271 int ret = 0;
3272
3273 if (v == NULL) {
3274 pr_err("%s: v is NULL\n", __func__);
3275 ret = -EINVAL;
3276 goto fail;
3277 }
3278
3279 if (!common.apr_q6_mvm) {
3280 pr_err("%s: apr_mvm is NULL.\n", __func__);
3281 ret = -EINVAL;
3282 goto fail;
3283 }
3284
3285 if (!table_info->data) {
3286 pr_err("%s: memory table is NULL.\n", __func__);
3287 ret = -EINVAL;
3288 goto fail;
3289 }
3290
3291 memtable = (uint32_t *) table_info->data;
3292
3293 /*
3294 * Store next table descriptor's address(64 bit) as NULL as there
3295 * is only one memory block
3296 */
3297 memtable[0] = 0;
3298 memtable[1] = 0;
3299
3300 /* Store next table descriptor's size */
3301 memtable[2] = 0;
3302
3303 /* Store shared mem adddress (64 bit) */
3304 memtable[3] = lower_32_bits(phys);
3305 memtable[4] = msm_audio_populate_upper_32_bits(phys);
3306
3307 /* Store shared memory size */
3308 memtable[5] = size;
3309
3310 mvm_map_phys_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
3311 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
3312 mvm_map_phys_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
3313 sizeof(mvm_map_phys_cmd) - APR_HDR_SIZE);
3314 mvm_map_phys_cmd.hdr.src_port =
3315 voice_get_idx_for_session(v->session_id);
3316 mvm_map_phys_cmd.hdr.dest_port = voice_get_mvm_handle(v);
3317 mvm_map_phys_cmd.hdr.token = token;
3318 mvm_map_phys_cmd.hdr.opcode = VSS_IMEMORY_CMD_MAP_PHYSICAL;
3319
3320 mvm_map_phys_cmd.table_descriptor.mem_address_lsw =
3321 lower_32_bits(table_info->phys);
3322 mvm_map_phys_cmd.table_descriptor.mem_address_msw =
3323 msm_audio_populate_upper_32_bits(table_info->phys);
3324 mvm_map_phys_cmd.table_descriptor.mem_size =
3325 sizeof(struct vss_imemory_block_t) +
3326 sizeof(struct vss_imemory_table_descriptor_t);
3327 mvm_map_phys_cmd.is_cached = true;
3328 mvm_map_phys_cmd.cache_line_size = 128;
3329 mvm_map_phys_cmd.access_mask = 3;
3330 mvm_map_phys_cmd.page_align = 4096;
3331 mvm_map_phys_cmd.min_data_width = 8;
3332 mvm_map_phys_cmd.max_data_width = 64;
3333
3334 pr_debug("%s: next table desc: add: %lld, size: %d\n",
3335 __func__, *((uint64_t *) memtable),
3336 *(((uint32_t *) memtable) + 2));
3337 pr_debug("%s: phy add of of mem being mapped LSW:0x%x, MSW:0x%x size: %d\n",
3338 __func__, *(((uint32_t *) memtable) + 3),
3339 *(((uint32_t *) memtable) + 4), *(((uint32_t *) memtable) + 5));
3340
3341 v->mvm_state = CMD_STATUS_FAIL;
3342 v->async_err = 0;
3343 ret = apr_send_pkt(common.apr_q6_mvm, (uint32_t *) &mvm_map_phys_cmd);
3344 if (ret < 0) {
3345 pr_err("%s: Error %d sending mvm map phy cmd\n", __func__, ret);
3346
3347 goto fail;
3348 }
3349
3350 ret = wait_event_timeout(v->mvm_wait,
3351 (v->mvm_state == CMD_STATUS_SUCCESS),
3352 msecs_to_jiffies(TIMEOUT_MS));
3353 if (!ret) {
3354 pr_err("%s: Command timeout\n", __func__);
3355
3356 goto fail;
3357 }
3358 if (v->async_err > 0) {
3359 pr_err("%s: DSP returned error[%s]\n",
3360 __func__, adsp_err_get_err_str(
3361 v->async_err));
3362 ret = adsp_err_get_lnx_err_code(
3363 v->async_err);
3364 goto fail;
3365 }
3366
3367 return 0;
3368
3369fail:
3370 return ret;
3371}
3372
3373static int voice_pause_voice_call(struct voice_data *v)
3374{
3375 struct apr_hdr mvm_pause_voice_cmd;
3376 void *apr_mvm;
3377 int ret = 0;
3378
3379 pr_debug("%s\n", __func__);
3380
3381 if (v == NULL) {
3382 pr_err("%s: Voice data is NULL\n", __func__);
3383
3384 ret = -EINVAL;
3385 goto done;
3386 }
3387
3388 apr_mvm = common.apr_q6_mvm;
3389 if (!apr_mvm) {
3390 pr_err("%s: apr_mvm is NULL.\n", __func__);
3391
3392 ret = -EINVAL;
3393 goto done;
3394 }
3395
3396 mvm_pause_voice_cmd.hdr_field =
3397 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
3398 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
3399 mvm_pause_voice_cmd.pkt_size =
3400 APR_PKT_SIZE(APR_HDR_SIZE,
3401 sizeof(mvm_pause_voice_cmd) - APR_HDR_SIZE);
3402 mvm_pause_voice_cmd.src_port =
3403 voice_get_idx_for_session(v->session_id);
3404 mvm_pause_voice_cmd.dest_port = voice_get_mvm_handle(v);
3405 mvm_pause_voice_cmd.token = 0;
3406 mvm_pause_voice_cmd.opcode = VSS_IMVM_CMD_PAUSE_VOICE;
3407 v->mvm_state = CMD_STATUS_FAIL;
3408 v->async_err = 0;
3409
3410 pr_debug("%s: send mvm_pause_voice_cmd pkt size = %d\n",
3411 __func__, mvm_pause_voice_cmd.pkt_size);
3412
3413 ret = apr_send_pkt(apr_mvm,
3414 (uint32_t *)&mvm_pause_voice_cmd);
3415 if (ret < 0) {
3416 pr_err("Fail in sending VSS_IMVM_CMD_PAUSE_VOICE\n");
3417
3418 ret = -EINVAL;
3419 goto done;
3420 }
3421
3422 ret = wait_event_timeout(v->mvm_wait,
3423 (v->mvm_state == CMD_STATUS_SUCCESS),
3424 msecs_to_jiffies(TIMEOUT_MS));
3425 if (!ret) {
3426 pr_err("%s: Command timeout\n", __func__);
3427
3428 ret = -EINVAL;
3429 goto done;
3430 }
3431 if (v->async_err > 0) {
3432 pr_err("%s: DSP returned error[%s]\n",
3433 __func__, adsp_err_get_err_str(
3434 v->async_err));
3435 ret = adsp_err_get_lnx_err_code(
3436 v->async_err);
3437 goto done;
3438 }
3439
3440done:
3441 return ret;
3442}
3443
3444static int voice_map_cal_memory(struct cal_block_data *cal_block,
3445 uint32_t session_id)
3446{
3447 int result = 0;
3448 int voc_index;
3449 struct voice_data *v = NULL;
3450
3451 pr_debug("%s\n", __func__);
3452
3453 if (cal_block == NULL) {
3454 pr_err("%s: Cal block is NULL!\n", __func__);
3455
3456 result = -EINVAL;
3457 goto done;
3458 }
3459
3460 if (cal_block->cal_data.paddr == 0) {
3461 pr_debug("%s: No address to map!\n", __func__);
3462
3463 result = -EINVAL;
3464 goto done;
3465 }
3466
3467 if (cal_block->map_data.map_size == 0) {
3468 pr_debug("%s: Map size is 0!\n", __func__);
3469
3470 result = -EINVAL;
3471 goto done;
3472 }
3473
3474 voc_index = voice_get_idx_for_session(session_id);
3475 if (voc_index < 0) {
3476 pr_err("%s: Invalid session ID %d\n", __func__, session_id);
3477
3478 goto done;
3479 }
3480
3481 mutex_lock(&common.common_lock);
3482 v = &common.voice[voc_index];
3483
3484 result = voice_map_memory_physical_cmd(v,
3485 &common.cal_mem_map_table,
3486 (dma_addr_t)cal_block->cal_data.paddr,
3487 cal_block->map_data.map_size,
3488 VOC_CAL_MEM_MAP_TOKEN);
3489 if (result < 0) {
3490 pr_err("%s: Mmap did not work! addr = 0x%pK, size = %zd\n",
3491 __func__,
3492 &cal_block->cal_data.paddr,
3493 cal_block->map_data.map_size);
3494
3495 goto done_unlock;
3496 }
3497
3498 cal_block->map_data.q6map_handle = common.cal_mem_handle;
3499done_unlock:
3500 mutex_unlock(&common.common_lock);
3501done:
3502 return result;
3503}
3504
3505static int remap_cal_data(struct cal_block_data *cal_block,
3506 uint32_t session_id)
3507{
3508 int ret = 0;
3509
3510 pr_debug("%s\n", __func__);
3511
3512 if (cal_block->map_data.ion_client == NULL) {
3513 pr_err("%s: No ION allocation for session_id %d!\n",
3514 __func__, session_id);
3515 ret = -EINVAL;
3516 goto done;
3517 }
3518
3519 if ((cal_block->map_data.map_size > 0) &&
3520 (cal_block->map_data.q6map_handle == 0)) {
3521
3522 /* cal type not used */
3523 ret = voice_map_cal_memory(cal_block, session_id);
3524 if (ret < 0) {
3525 pr_err("%s: Mmap did not work! size = %zd\n",
3526 __func__, cal_block->map_data.map_size);
3527
3528 goto done;
3529 }
3530 } else {
3531 pr_debug("%s: Cal block 0x%pK, size %zd already mapped. Q6 map handle = %d\n",
3532 __func__, &cal_block->cal_data.paddr,
3533 cal_block->map_data.map_size,
3534 cal_block->map_data.q6map_handle);
3535 }
3536done:
3537 return ret;
3538}
3539
3540static int voice_unmap_cal_memory(int32_t cal_type,
3541 struct cal_block_data *cal_block)
3542{
3543 int result = 0;
3544 int result2 = 0;
3545 int i;
3546 struct voice_data *v = NULL;
3547
3548 pr_debug("%s\n", __func__);
3549
3550 if (cal_block == NULL) {
3551 pr_err("%s: Cal block is NULL!\n", __func__);
3552
3553 result = -EINVAL;
3554 goto done;
3555 }
3556
3557 if (cal_block->map_data.q6map_handle == 0) {
3558 pr_debug("%s: Q6 handle is not set!\n", __func__);
3559
3560 result = -EINVAL;
3561 goto done;
3562 }
3563
3564 mutex_lock(&common.common_lock);
3565
3566 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
3567 v = &common.voice[i];
3568
3569 mutex_lock(&v->lock);
3570 if (is_voc_state_active(v->voc_state)) {
3571 result2 = voice_pause_voice_call(v);
3572 if (result2 < 0) {
3573 pr_err("%s: Voice_pause_voice_call failed for session 0x%x, err %d!\n",
3574 __func__, v->session_id, result2);
3575
3576 result = result2;
3577 }
3578
3579 if (cal_type == CVP_VOCPROC_DYNAMIC_CAL_TYPE)
3580 voice_send_cvp_deregister_vol_cal_cmd(v);
3581 else if (cal_type == CVP_VOCPROC_STATIC_CAL_TYPE)
3582 voice_send_cvp_deregister_cal_cmd(v);
3583 else if (cal_type == CVP_VOCDEV_CFG_CAL_TYPE)
3584 voice_send_cvp_deregister_dev_cfg_cmd(v);
3585 else if (cal_type == CVS_VOCSTRM_STATIC_CAL_TYPE)
3586 voice_send_cvs_deregister_cal_cmd(v);
3587 else
3588 pr_err("%s: Invalid cal type %d!\n",
3589 __func__, cal_type);
3590
3591 result2 = voice_send_start_voice_cmd(v);
3592 if (result2) {
3593 pr_err("%s: Voice_send_start_voice_cmd failed for session 0x%x, err %d!\n",
3594 __func__, v->session_id, result2);
3595
3596 result = result2;
3597 }
3598 }
3599
3600 if ((cal_block->map_data.q6map_handle != 0) &&
3601 (!is_other_session_active(v->session_id))) {
3602
3603 result2 = voice_send_mvm_unmap_memory_physical_cmd(
3604 v, cal_block->map_data.q6map_handle);
3605 if (result2) {
3606 pr_err("%s: Voice_send_mvm_unmap_memory_physical_cmd failed for session 0x%x, err %d!\n",
3607 __func__, v->session_id, result2);
3608
3609 result = result2;
3610 }
3611 cal_block->map_data.q6map_handle = 0;
3612 }
3613 mutex_unlock(&v->lock);
3614 }
3615 mutex_unlock(&common.common_lock);
3616done:
3617 return result;
3618}
3619
3620int voc_register_vocproc_vol_table(void)
3621{
3622 int result = 0;
3623 int result2 = 0;
3624 int i;
3625 struct voice_data *v = NULL;
3626
3627 pr_debug("%s\n", __func__);
3628
3629 mutex_lock(&common.common_lock);
3630 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
3631 v = &common.voice[i];
3632
3633 mutex_lock(&v->lock);
3634 if (is_voc_state_active(v->voc_state)) {
3635 result2 = voice_send_cvp_register_vol_cal_cmd(v);
3636 if (result2 < 0) {
3637 pr_err("%s: Failed to register vocvol table for session 0x%x!\n",
3638 __func__, v->session_id);
3639
3640 result = result2;
3641 /* Still try to register other sessions */
3642 }
3643 }
3644 mutex_unlock(&v->lock);
3645 }
3646
3647 mutex_unlock(&common.common_lock);
3648 return result;
3649}
3650
3651int voc_deregister_vocproc_vol_table(void)
3652{
3653 int result = 0;
3654 int success = 0;
3655 int i;
3656 struct voice_data *v = NULL;
3657
3658 pr_debug("%s\n", __func__);
3659
3660 mutex_lock(&common.common_lock);
3661 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
3662 v = &common.voice[i];
3663
3664 mutex_lock(&v->lock);
3665 if (is_voc_state_active(v->voc_state)) {
3666 result = voice_send_cvp_deregister_vol_cal_cmd(v);
3667 if (result < 0) {
3668 pr_err("%s: Failed to deregister vocvol table for session 0x%x!\n",
3669 __func__, v->session_id);
3670
3671 mutex_unlock(&v->lock);
3672 mutex_unlock(&common.common_lock);
3673 if (success) {
3674 pr_err("%s: Try to re-register all deregistered sessions!\n",
3675 __func__);
3676
3677 voc_register_vocproc_vol_table();
3678 }
3679 goto done;
3680 } else {
3681 success = 1;
3682 }
3683 }
3684 mutex_unlock(&v->lock);
3685 }
3686 mutex_unlock(&common.common_lock);
3687done:
3688 return result;
3689}
3690
3691int voc_map_rtac_block(struct rtac_cal_block_data *cal_block)
3692{
3693 int result = 0;
3694 struct voice_data *v = NULL;
3695
3696 pr_debug("%s\n", __func__);
3697
3698 if (cal_block == NULL) {
3699 pr_err("%s: cal_block is NULL!\n",
3700 __func__);
3701
3702 result = -EINVAL;
3703 goto done;
3704 }
3705
3706 if (cal_block->cal_data.paddr == 0) {
3707 pr_debug("%s: No address to map!\n",
3708 __func__);
3709
3710 result = -EINVAL;
3711 goto done;
3712 }
3713
3714 if (cal_block->map_data.map_size == 0) {
3715 pr_debug("%s: map size is 0!\n",
3716 __func__);
3717
3718 result = -EINVAL;
3719 goto done;
3720 }
3721
3722 mutex_lock(&common.common_lock);
3723 /* use first session */
3724 v = &common.voice[0];
3725 mutex_lock(&v->lock);
3726
3727 if (!is_rtac_memory_allocated()) {
3728 result = voice_alloc_rtac_mem_map_table();
3729 if (result < 0) {
3730 pr_err("%s: RTAC alloc mem map table did not work! addr = 0x%pK, size = %d\n",
3731 __func__,
3732 &cal_block->cal_data.paddr,
3733 cal_block->map_data.map_size);
3734
3735 goto done_unlock;
3736 }
3737 }
3738
3739 result = voice_map_memory_physical_cmd(v,
3740 &common.rtac_mem_map_table,
3741 (dma_addr_t)cal_block->cal_data.paddr,
3742 cal_block->map_data.map_size,
3743 VOC_RTAC_MEM_MAP_TOKEN);
3744 if (result < 0) {
3745 pr_err("%s: RTAC mmap did not work! addr = 0x%pK, size = %d\n",
3746 __func__,
3747 &cal_block->cal_data.paddr,
3748 cal_block->map_data.map_size);
3749
3750 free_rtac_map_table();
3751 goto done_unlock;
3752 }
3753
3754 cal_block->map_data.map_handle = common.rtac_mem_handle;
3755done_unlock:
3756 mutex_unlock(&v->lock);
3757 mutex_unlock(&common.common_lock);
3758done:
3759 return result;
3760}
3761
3762int voc_unmap_rtac_block(uint32_t *mem_map_handle)
3763{
3764 int result = 0;
3765 struct voice_data *v = NULL;
3766
3767 pr_debug("%s\n", __func__);
3768
3769 if (mem_map_handle == NULL) {
3770 pr_debug("%s: Map handle is NULL, nothing to unmap\n",
3771 __func__);
3772
3773 goto done;
3774 }
3775
3776 if (*mem_map_handle == 0) {
3777 pr_debug("%s: Map handle is 0, nothing to unmap\n",
3778 __func__);
3779
3780 goto done;
3781 }
3782
3783 mutex_lock(&common.common_lock);
3784 /* Use first session */
3785 /* Only used for apr wait lock */
3786 v = &common.voice[0];
3787 mutex_lock(&v->lock);
3788
3789 result = voice_send_mvm_unmap_memory_physical_cmd(
3790 v, *mem_map_handle);
3791 if (result) {
3792 pr_err("%s: voice_send_mvm_unmap_memory_physical_cmd Failed for session 0x%x!\n",
3793 __func__, v->session_id);
3794 } else {
3795 *mem_map_handle = 0;
3796 common.rtac_mem_handle = 0;
3797 free_rtac_map_table();
3798 }
3799 mutex_unlock(&v->lock);
3800 mutex_unlock(&common.common_lock);
3801done:
3802 return result;
3803}
3804
Laxminath Kasam38070be2017-08-17 18:21:59 +05303805static int voice_send_cvp_channel_info_v2(struct voice_data *v,
3806 uint32_t param_type)
3807{
3808 int ret;
3809 struct cvp_set_channel_info_cmd_v2 cvp_set_channel_info_cmd;
3810 void *apr_cvp;
3811 u16 cvp_handle;
3812 struct vss_icommon_param_data_channel_info_v2_t
3813 *channel_info_param_data =
3814 &cvp_set_channel_info_cmd.
3815 cvp_set_ch_info_param_v2.param_data;
3816 struct vss_param_vocproc_dev_channel_info_t *channel_info =
3817 &channel_info_param_data->channel_info;
3818
3819 if (v == NULL) {
3820 pr_err("%s: v is NULL\n", __func__);
3821 ret = -EINVAL;
3822 goto done;
3823 }
3824
3825 apr_cvp = common.apr_q6_cvp;
3826 if (!apr_cvp) {
3827 pr_err("%s: apr_cvp is NULL\n", __func__);
3828 ret = -EINVAL;
3829 goto done;
3830 }
3831
3832 cvp_handle = voice_get_cvp_handle(v);
3833 memset(&cvp_set_channel_info_cmd, 0, sizeof(cvp_set_channel_info_cmd));
3834
3835 cvp_set_channel_info_cmd.hdr.hdr_field =
3836 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
3837 APR_PKT_VER);
3838 cvp_set_channel_info_cmd.hdr.pkt_size =
3839 APR_PKT_SIZE(APR_HDR_SIZE,
3840 sizeof(cvp_set_channel_info_cmd) - APR_HDR_SIZE);
3841 cvp_set_channel_info_cmd.hdr.src_svc = 0;
3842 cvp_set_channel_info_cmd.hdr.src_domain = APR_DOMAIN_APPS;
3843 cvp_set_channel_info_cmd.hdr.src_port =
3844 voice_get_idx_for_session(v->session_id);
3845 cvp_set_channel_info_cmd.hdr.dest_svc = 0;
3846 cvp_set_channel_info_cmd.hdr.dest_domain = APR_DOMAIN_ADSP;
3847 cvp_set_channel_info_cmd.hdr.dest_port = cvp_handle;
3848 cvp_set_channel_info_cmd.hdr.token = 0;
3849 cvp_set_channel_info_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_PARAM_V2;
3850
3851 cvp_set_channel_info_cmd.cvp_set_ch_info_param_v2.mem_size =
3852 sizeof(struct vss_icommon_param_data_channel_info_v2_t);
3853
3854 channel_info_param_data->module_id = VSS_MODULE_CVD_GENERIC;
3855 channel_info_param_data->param_size =
3856 sizeof(struct vss_param_vocproc_dev_channel_info_t);
3857
3858 /* Device specific data */
3859 switch (param_type) {
3860 case RX_PATH:
3861 channel_info_param_data->param_id =
3862 VSS_PARAM_VOCPROC_RX_CHANNEL_INFO;
3863 channel_info->num_channels = v->dev_rx.no_of_channels;
3864 channel_info->bits_per_sample = v->dev_rx.bits_per_sample;
3865 break;
3866
3867 case TX_PATH:
3868 channel_info_param_data->param_id =
3869 VSS_PARAM_VOCPROC_TX_CHANNEL_INFO;
3870 channel_info->num_channels = v->dev_tx.no_of_channels;
3871 channel_info->bits_per_sample = v->dev_tx.bits_per_sample;
3872 break;
3873
3874 case EC_REF_PATH:
3875 channel_info_param_data->param_id =
3876 VSS_PARAM_VOCPROC_EC_REF_CHANNEL_INFO;
3877 channel_info->num_channels = v->dev_rx.no_of_channels;
3878 channel_info->bits_per_sample = v->dev_rx.bits_per_sample;
3879 break;
3880 default:
3881 pr_err("%s: Invalid param type\n",
3882 __func__);
3883 ret = -EINVAL;
3884 goto done;
3885 }
3886
3887 if (channel_info->num_channels == NUM_CHANNELS_MONO) {
3888 channel_info->channel_mapping[0] = PCM_CHANNEL_FC;
3889 } else if (channel_info->num_channels == NUM_CHANNELS_STEREO) {
3890 channel_info->channel_mapping[0] = PCM_CHANNEL_FL;
3891 channel_info->channel_mapping[1] = PCM_CHANNEL_FR;
3892 } else {
3893 pr_err("%s: Unsupported num channels: %d\n",
3894 __func__, channel_info->num_channels);
3895 ret = -EINVAL;
3896 goto done;
3897 }
3898
3899 v->cvp_state = CMD_STATUS_FAIL;
3900 v->async_err = 0;
3901 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_set_channel_info_cmd);
3902 if (ret < 0) {
3903 pr_err("%s: Failed to send VSS_ICOMMON_CMD_SET_PARAM_V2\n",
3904 __func__);
3905 goto done;
3906 }
3907
3908 ret = wait_event_timeout(v->cvp_wait,
3909 (v->cvp_state == CMD_STATUS_SUCCESS),
3910 msecs_to_jiffies(TIMEOUT_MS));
3911 if (!ret) {
3912 pr_err("%s: wait_event timeout\n", __func__);
3913 ret = -ETIMEDOUT;
3914 goto done;
3915 }
3916
3917 if (v->async_err > 0) {
3918 pr_err("%s: DSP returned error[%s] handle = %d\n", __func__,
3919 adsp_err_get_err_str(v->async_err), cvp_handle);
3920 ret = adsp_err_get_lnx_err_code(v->async_err);
3921 goto done;
3922 }
3923 ret = 0;
3924done:
3925 return ret;
3926}
3927
3928static int voice_send_cvp_channel_info_cmd(struct voice_data *v)
3929{
3930 int ret = 0;
3931
3932 ret = voice_send_cvp_channel_info_v2(v, RX_PATH);
3933 if (ret < 0) {
3934 pr_err("%s: Error in sending cvp_channel_info RX: %d\n",
3935 __func__, ret);
3936 goto done;
3937 }
3938
3939 ret = voice_send_cvp_channel_info_v2(v, TX_PATH);
3940 if (ret < 0) {
3941 pr_err("%s: Error in sending cvp_channel_info TX: %d\n",
3942 __func__, ret);
3943 goto done;
3944 }
3945
3946 ret = voice_send_cvp_channel_info_v2(v, EC_REF_PATH);
3947 if (ret < 0) {
3948 pr_err("%s: Error in sending cvp_channel_info EC Ref: %d\n",
3949 __func__, ret);
3950 goto done;
3951 }
3952done:
3953 return ret;
3954}
3955
3956static int voice_send_cvp_mfc_config_v2(struct voice_data *v)
3957{
3958 int ret;
3959 struct cvp_set_mfc_config_cmd_v2 cvp_set_mfc_config_cmd;
3960 void *apr_cvp;
3961 u16 cvp_handle;
3962 struct vss_icommon_param_data_mfc_config_v2_t *cvp_config_param_data =
3963 &cvp_set_mfc_config_cmd.cvp_set_mfc_param_v2.param_data;
3964 struct vss_param_mfc_config_info_t *mfc_config_info =
3965 &cvp_config_param_data->mfc_config_info;
3966
3967 if (v == NULL) {
3968 pr_err("%s: v is NULL\n", __func__);
3969 ret = -EINVAL;
3970 goto done;
3971 }
3972
3973 apr_cvp = common.apr_q6_cvp;
3974 if (!apr_cvp) {
3975 pr_err("%s: apr_cvp is NULL\n", __func__);
3976 ret = -EINVAL;
3977 goto done;
3978 }
3979
3980 cvp_handle = voice_get_cvp_handle(v);
3981 memset(&cvp_set_mfc_config_cmd, 0, sizeof(cvp_set_mfc_config_cmd));
3982
3983 cvp_set_mfc_config_cmd.hdr.hdr_field =
3984 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
3985 APR_PKT_VER);
3986 cvp_set_mfc_config_cmd.hdr.pkt_size =
3987 APR_PKT_SIZE(APR_HDR_SIZE,
3988 sizeof(cvp_set_mfc_config_cmd) - APR_HDR_SIZE);
3989 cvp_set_mfc_config_cmd.hdr.src_svc = 0;
3990 cvp_set_mfc_config_cmd.hdr.src_domain = APR_DOMAIN_APPS;
3991 cvp_set_mfc_config_cmd.hdr.src_port =
3992 voice_get_idx_for_session(v->session_id);
3993 cvp_set_mfc_config_cmd.hdr.dest_svc = 0;
3994 cvp_set_mfc_config_cmd.hdr.dest_domain = APR_DOMAIN_ADSP;
3995 cvp_set_mfc_config_cmd.hdr.dest_port = cvp_handle;
3996 cvp_set_mfc_config_cmd.hdr.token = 0;
3997 cvp_set_mfc_config_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_PARAM_V2;
3998 cvp_set_mfc_config_cmd.cvp_set_mfc_param_v2.mem_size =
3999 sizeof(struct vss_icommon_param_data_mfc_config_v2_t);
4000
4001 cvp_config_param_data->module_id = AUDPROC_MODULE_ID_MFC;
4002 cvp_config_param_data->param_id =
4003 AUDPROC_PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT;
4004 cvp_config_param_data->param_size =
4005 sizeof(struct vss_param_mfc_config_info_t);
4006
4007 mfc_config_info->num_channels = v->dev_rx.no_of_channels;
4008 mfc_config_info->bits_per_sample = 16;
4009 mfc_config_info->sample_rate = v->dev_rx.sample_rate;
4010
4011 if (mfc_config_info->num_channels == NUM_CHANNELS_MONO) {
4012 mfc_config_info->channel_type[0] = PCM_CHANNEL_FC;
4013 } else if (mfc_config_info->num_channels == NUM_CHANNELS_STEREO) {
4014 mfc_config_info->channel_type[0] = PCM_CHANNEL_FL;
4015 mfc_config_info->channel_type[1] = PCM_CHANNEL_FR;
4016 } else {
4017 pr_err("%s: Unsupported num channels: %d\n",
4018 __func__, mfc_config_info->num_channels);
4019 ret = -EINVAL;
4020 goto done;
4021 }
4022
4023 v->cvp_state = CMD_STATUS_FAIL;
4024 v->async_err = 0;
4025 ret = apr_send_pkt(apr_cvp, (uint32_t *)&cvp_set_mfc_config_cmd);
4026 if (ret < 0) {
4027 pr_err("%s: Failed to send VSS_ICOMMON_CMD_SET_PARAM_V2 %d\n",
4028 __func__, ret);
4029 goto done;
4030 }
4031 ret = wait_event_timeout(v->cvp_wait,
4032 (v->cvp_state == CMD_STATUS_SUCCESS),
4033 msecs_to_jiffies(TIMEOUT_MS));
4034
4035 if (!ret) {
4036 pr_err("%s: wait_event timeout\n", __func__);
4037 ret = -ETIMEDOUT;
4038 goto done;
4039 }
4040
4041 if (v->async_err > 0) {
4042 pr_err("%s: DSP returned error[%s] handle = %d\n", __func__,
4043 adsp_err_get_err_str(v->async_err), cvp_handle);
4044 ret = adsp_err_get_lnx_err_code(v->async_err);
4045 goto done;
4046 }
4047 ret = 0;
4048done:
4049 return ret;
4050}
4051
4052static int voice_send_cvp_mfc_config_cmd(struct voice_data *v)
4053{
4054 int ret = 0;
4055
4056 if (common.cvp_version >= CVP_VERSION_2) {
4057 ret = voice_send_cvp_mfc_config_v2(v);
4058 } else {
4059 pr_warn("%s: CVP Version not supported\n", __func__);
4060 ret = -EINVAL;
4061 }
4062
4063 return ret;
4064}
4065
4066static int voice_get_avcs_version_per_service(uint32_t service_id)
4067{
4068 int ret = 0;
Siena Richard2d0102d2017-09-05 11:15:45 -07004069 size_t ver_size;
4070 struct avcs_fwk_ver_info *ver_info = NULL;
Laxminath Kasam38070be2017-08-17 18:21:59 +05304071
4072 if (service_id == AVCS_SERVICE_ID_ALL) {
4073 pr_err("%s: Invalid service id: %d", __func__,
4074 AVCS_SERVICE_ID_ALL);
4075 return -EINVAL;
4076 }
4077
Siena Richard2d0102d2017-09-05 11:15:45 -07004078 ver_size = sizeof(struct avcs_get_fwk_version) +
4079 sizeof(struct avs_svc_api_info);
4080 ver_info = kzalloc(ver_size, GFP_KERNEL);
4081 if (ver_info == NULL)
Laxminath Kasam38070be2017-08-17 18:21:59 +05304082 return -ENOMEM;
4083
Siena Richard2d0102d2017-09-05 11:15:45 -07004084 ret = q6core_get_service_version(service_id, ver_info, ver_size);
Laxminath Kasam38070be2017-08-17 18:21:59 +05304085 if (ret < 0)
4086 goto done;
4087
Siena Richard2d0102d2017-09-05 11:15:45 -07004088 ret = ver_info->services[0].api_version;
Laxminath Kasam38070be2017-08-17 18:21:59 +05304089 common.is_avcs_version_queried = true;
4090done:
Siena Richard2d0102d2017-09-05 11:15:45 -07004091 kfree(ver_info);
Laxminath Kasam38070be2017-08-17 18:21:59 +05304092 return ret;
4093}
4094
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304095static int voice_setup_vocproc(struct voice_data *v)
4096{
4097 int ret = 0;
4098
4099 ret = voice_send_cvp_create_cmd(v);
4100 if (ret < 0) {
4101 pr_err("%s: CVP create failed err:%d\n", __func__, ret);
4102 goto fail;
4103 }
4104
Laxminath Kasam38070be2017-08-17 18:21:59 +05304105 if (common.is_avcs_version_queried == false)
4106 common.cvp_version = voice_get_avcs_version_per_service(
4107 APRV2_IDS_SERVICE_ID_ADSP_CVP_V);
4108
4109 if (common.cvp_version < 0) {
4110 pr_err("%s: Invalid CVP version %d\n",
4111 __func__, common.cvp_version);
4112 ret = -EINVAL;
4113 goto fail;
4114 }
4115 pr_debug("%s: CVP Version %d\n", __func__, common.cvp_version);
4116
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304117 ret = voice_send_cvp_media_fmt_info_cmd(v);
4118 if (ret < 0) {
4119 pr_err("%s: Set media format info failed err:%d\n", __func__,
4120 ret);
4121 goto fail;
4122 }
4123
4124 ret = voice_send_cvp_topology_commit_cmd(v);
4125 if (ret < 0) {
4126 pr_err("%s: Set topology commit failed err:%d\n",
4127 __func__, ret);
4128 goto fail;
4129 }
4130
Laxminath Kasam38070be2017-08-17 18:21:59 +05304131 /* Send MFC config only when the no of channels are more than 1 */
4132 if (v->dev_rx.no_of_channels > NUM_CHANNELS_MONO) {
4133 ret = voice_send_cvp_mfc_config_cmd(v);
4134 if (ret < 0) {
4135 pr_warn("%s: Set mfc config failed err:%d\n",
4136 __func__, ret);
4137 }
4138 }
4139
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304140 voice_send_cvs_register_cal_cmd(v);
4141 voice_send_cvp_register_dev_cfg_cmd(v);
4142 voice_send_cvp_register_cal_cmd(v);
4143 voice_send_cvp_register_vol_cal_cmd(v);
4144
4145 /* enable vocproc */
4146 ret = voice_send_enable_vocproc_cmd(v);
4147 if (ret < 0)
4148 goto fail;
4149
4150 /* attach vocproc */
4151 ret = voice_send_attach_vocproc_cmd(v);
4152 if (ret < 0)
4153 goto fail;
4154
4155 /* send tty mode if tty device is used */
4156 voice_send_tty_mode_cmd(v);
4157
4158 if (is_voip_session(v->session_id)) {
4159 ret = voice_send_mvm_cal_network_cmd(v);
4160 if (ret < 0)
4161 pr_err("%s: voice_send_mvm_cal_network_cmd: %d\n",
4162 __func__, ret);
4163
4164 ret = voice_send_mvm_media_type_cmd(v);
4165 if (ret < 0)
4166 pr_err("%s: voice_send_mvm_media_type_cmd: %d\n",
4167 __func__, ret);
4168
4169 voice_send_netid_timing_cmd(v);
4170 }
4171
4172 if (v->st_enable && !v->tty_mode)
4173 voice_send_set_pp_enable_cmd(v,
4174 MODULE_ID_VOICE_MODULE_ST,
4175 v->st_enable);
4176 /* Start in-call music delivery if this feature is enabled */
4177 if (v->music_info.play_enable)
4178 voice_cvs_start_playback(v);
4179
4180 /* Start in-call recording if this feature is enabled */
4181 if (v->rec_info.rec_enable)
4182 voice_cvs_start_record(v, v->rec_info.rec_mode);
4183
4184 if (v->dtmf_rx_detect_en)
4185 voice_send_dtmf_rx_detection_cmd(v, v->dtmf_rx_detect_en);
4186
4187 if (v->hd_enable)
4188 voice_send_hd_cmd(v, v->hd_enable);
4189
4190 rtac_add_voice(voice_get_cvs_handle(v),
4191 voice_get_cvp_handle(v),
4192 v->dev_rx.port_id, v->dev_tx.port_id,
4193 v->dev_rx.dev_id, v->dev_tx.dev_id,
4194 v->session_id);
4195
4196 return 0;
4197
4198fail:
4199 return ret;
4200}
4201
4202static int voice_send_cvp_device_channels_cmd(struct voice_data *v)
4203{
4204 int ret = 0;
4205 struct cvp_set_dev_channels_cmd cvp_set_dev_channels_cmd;
4206 void *apr_cvp;
4207 u16 cvp_handle;
4208
4209 if (!(voice_get_cvd_int_version(common.cvd_version) >=
4210 CVD_INT_VERSION_2_2)) {
4211 pr_debug("%s CVD ver %s doesn't support send_device_channels cmd\n",
4212 __func__, common.cvd_version);
4213
4214 goto done;
4215 }
4216
4217 if (v == NULL) {
4218 pr_err("%s: v is NULL\n", __func__);
4219
4220 ret = -EINVAL;
4221 goto done;
4222 }
4223
4224 apr_cvp = common.apr_q6_cvp;
4225 if (!apr_cvp) {
4226 pr_err("%s: apr_cvp is NULL.\n", __func__);
4227
4228 ret = -EINVAL;
4229 goto done;
4230 }
4231
4232 cvp_handle = voice_get_cvp_handle(v);
4233 cvp_set_dev_channels_cmd.hdr.hdr_field =
4234 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4235 APR_HDR_LEN(APR_HDR_SIZE),
4236 APR_PKT_VER);
4237 cvp_set_dev_channels_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
4238 sizeof(cvp_set_dev_channels_cmd) - APR_HDR_SIZE);
4239 cvp_set_dev_channels_cmd.hdr.src_port =
4240 voice_get_idx_for_session(v->session_id);
4241 cvp_set_dev_channels_cmd.hdr.dest_port = cvp_handle;
4242 cvp_set_dev_channels_cmd.hdr.token = 0;
4243 cvp_set_dev_channels_cmd.hdr.opcode =
4244 VSS_IVOCPROC_CMD_TOPOLOGY_SET_DEV_CHANNELS;
4245 cvp_set_dev_channels_cmd.cvp_set_channels.rx_num_channels =
4246 VSS_NUM_DEV_CHANNELS_1;
4247 cvp_set_dev_channels_cmd.cvp_set_channels.tx_num_channels =
4248 v->dev_tx.no_of_channels;
4249
4250 v->cvp_state = CMD_STATUS_FAIL;
4251 v->async_err = 0;
4252 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_set_dev_channels_cmd);
4253 if (ret < 0) {
4254 pr_err("%s: Fail in sending VSS_IVOCPROC_CMD_TOPOLOGY_SET_DEV_CHANNELS\n",
4255 __func__);
4256
4257 ret = -EINVAL;
4258 goto done;
4259 }
4260
4261 ret = wait_event_timeout(v->cvp_wait,
4262 (v->cvp_state == CMD_STATUS_SUCCESS),
4263 msecs_to_jiffies(TIMEOUT_MS));
4264 if (!ret) {
4265 pr_err("%s: wait_event timeout\n", __func__);
4266
4267 ret = -EINVAL;
4268 goto done;
4269 }
4270 if (v->async_err > 0) {
4271 pr_err("%s: DSP returned error[%s]\n",
4272 __func__, adsp_err_get_err_str(
4273 v->async_err));
4274 ret = adsp_err_get_lnx_err_code(
4275 v->async_err);
4276 goto done;
4277 }
4278
4279done:
4280 return ret;
4281}
4282
4283static int voice_send_cvp_media_fmt_info_cmd(struct voice_data *v)
4284{
Laxminath Kasam38070be2017-08-17 18:21:59 +05304285 int ret = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304286
Laxminath Kasam38070be2017-08-17 18:21:59 +05304287 if (common.cvp_version < CVP_VERSION_2)
4288 ret = voice_send_cvp_device_channels_cmd(v);
4289 else
4290 ret = voice_send_cvp_channel_info_cmd(v);
4291
4292 if (ret < 0) {
4293 pr_err("%s: Set channel info failed err: %d\n", __func__,
4294 ret);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304295 goto done;
Laxminath Kasam38070be2017-08-17 18:21:59 +05304296 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304297
4298 if (voice_get_cvd_int_version(common.cvd_version) >=
4299 CVD_INT_VERSION_2_3) {
4300 ret = voice_send_cvp_media_format_cmd(v, RX_PATH);
4301 if (ret < 0)
4302 goto done;
4303
4304 ret = voice_send_cvp_media_format_cmd(v, TX_PATH);
4305 if (ret < 0)
4306 goto done;
4307
4308 if (common.ec_ref_ext)
4309 ret = voice_send_cvp_media_format_cmd(v, EC_REF_PATH);
4310 }
4311
4312done:
4313 return ret;
4314}
4315
4316static int voice_send_cvp_media_format_cmd(struct voice_data *v,
4317 uint32_t param_type)
4318{
4319 int ret = 0;
4320 struct cvp_set_media_format_cmd cvp_set_media_format_cmd;
4321 void *apr_cvp;
4322 u16 cvp_handle;
4323 struct vss_icommon_param_data_t *media_fmt_param_data =
Laxminath Kasam38070be2017-08-17 18:21:59 +05304324 &cvp_set_media_format_cmd.cvp_set_media_param_v2.param_data;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304325 struct vss_param_endpoint_media_format_info_t *media_fmt_info =
4326 &media_fmt_param_data->media_format_info;
4327
4328 if (v == NULL) {
4329 pr_err("%s: v is NULL\n", __func__);
4330 ret = -EINVAL;
4331 goto done;
4332 }
4333
4334 apr_cvp = common.apr_q6_cvp;
4335 if (!apr_cvp) {
4336 pr_err("%s: apr_cvp is NULL.\n", __func__);
4337 ret = -EINVAL;
4338 goto done;
4339 }
4340
4341 cvp_handle = voice_get_cvp_handle(v);
4342 memset(&cvp_set_media_format_cmd, 0, sizeof(cvp_set_media_format_cmd));
4343
4344 /* Fill header data */
4345 cvp_set_media_format_cmd.hdr.hdr_field =
4346 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
4347 APR_PKT_VER);
4348 cvp_set_media_format_cmd.hdr.pkt_size =
4349 APR_PKT_SIZE(APR_HDR_SIZE,
4350 sizeof(cvp_set_media_format_cmd) - APR_HDR_SIZE);
4351 cvp_set_media_format_cmd.hdr.src_svc = 0;
4352 cvp_set_media_format_cmd.hdr.src_domain = APR_DOMAIN_APPS;
4353 cvp_set_media_format_cmd.hdr.src_port =
4354 voice_get_idx_for_session(v->session_id);
4355 cvp_set_media_format_cmd.hdr.dest_svc = 0;
4356 cvp_set_media_format_cmd.hdr.dest_domain = APR_DOMAIN_ADSP;
4357 cvp_set_media_format_cmd.hdr.dest_port = cvp_handle;
4358 cvp_set_media_format_cmd.hdr.token = VOC_SET_MEDIA_FORMAT_PARAM_TOKEN;
4359 cvp_set_media_format_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_PARAM_V2;
4360
4361 /* Fill param data */
Laxminath Kasam38070be2017-08-17 18:21:59 +05304362 cvp_set_media_format_cmd.cvp_set_media_param_v2.mem_size =
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304363 sizeof(struct vss_icommon_param_data_t);
4364 media_fmt_param_data->module_id = VSS_MODULE_CVD_GENERIC;
4365 media_fmt_param_data->param_size =
4366 sizeof(struct vss_param_endpoint_media_format_info_t);
4367
4368 /* Fill device specific data */
4369 switch (param_type) {
4370 case RX_PATH:
4371 media_fmt_param_data->param_id =
4372 VSS_PARAM_RX_PORT_ENDPOINT_MEDIA_INFO;
4373 media_fmt_info->port_id = v->dev_rx.port_id;
4374 media_fmt_info->num_channels = v->dev_rx.no_of_channels;
4375 media_fmt_info->bits_per_sample = v->dev_rx.bits_per_sample;
4376 media_fmt_info->sample_rate = v->dev_rx.sample_rate;
4377 memcpy(&media_fmt_info->channel_mapping,
4378 &v->dev_rx.channel_mapping, VSS_CHANNEL_MAPPING_SIZE);
4379 break;
4380
4381 case TX_PATH:
4382 media_fmt_param_data->param_id =
4383 VSS_PARAM_TX_PORT_ENDPOINT_MEDIA_INFO;
4384 media_fmt_info->port_id = v->dev_tx.port_id;
4385 media_fmt_info->num_channels = v->dev_tx.no_of_channels;
4386 media_fmt_info->bits_per_sample = v->dev_tx.bits_per_sample;
4387 media_fmt_info->sample_rate = v->dev_tx.sample_rate;
4388 memcpy(&media_fmt_info->channel_mapping,
4389 &v->dev_tx.channel_mapping, VSS_CHANNEL_MAPPING_SIZE);
4390 break;
4391
4392 case EC_REF_PATH:
4393 media_fmt_param_data->param_id =
4394 VSS_PARAM_EC_REF_PORT_ENDPOINT_MEDIA_INFO;
4395 media_fmt_info->port_id = common.ec_media_fmt_info.port_id;
4396 media_fmt_info->num_channels =
4397 common.ec_media_fmt_info.num_channels;
4398 media_fmt_info->bits_per_sample =
4399 common.ec_media_fmt_info.bits_per_sample;
4400 media_fmt_info->sample_rate =
4401 common.ec_media_fmt_info.sample_rate;
4402 memcpy(&media_fmt_info->channel_mapping,
4403 &common.ec_media_fmt_info.channel_mapping,
4404 VSS_CHANNEL_MAPPING_SIZE);
4405 break;
4406
4407 default:
4408 pr_err("%s: Invalid param type %d\n", __func__, param_type);
4409 ret = -EINVAL;
4410 goto done;
4411 }
4412
4413 /* Send command */
4414 v->cvp_state = CMD_STATUS_FAIL;
4415 v->async_err = 0;
4416 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_set_media_format_cmd);
4417 if (ret < 0) {
4418 pr_err("%s: Fail in sending VSS_ICOMMON_CMD_SET_PARAM_V2\n",
4419 __func__);
4420 ret = -EINVAL;
4421 goto done;
4422 }
4423
4424 ret = wait_event_timeout(v->cvp_wait,
4425 (v->cvp_state == CMD_STATUS_SUCCESS),
4426 msecs_to_jiffies(TIMEOUT_MS));
4427 if (!ret) {
4428 pr_err("%s: wait_event timeout\n", __func__);
4429 ret = -EINVAL;
4430 goto done;
4431 }
4432
4433 if (v->async_err > 0) {
4434 pr_err("%s: DSP returned error[%s] handle = %d\n", __func__,
4435 adsp_err_get_err_str(v->async_err), cvp_handle);
4436 ret = adsp_err_get_lnx_err_code(v->async_err);
4437 goto done;
4438 }
4439
4440done:
4441 return ret;
4442}
4443
4444static int voice_send_cvp_topology_commit_cmd(struct voice_data *v)
4445{
4446 int ret = 0;
4447 struct apr_hdr cvp_topology_commit_cmd;
4448 void *apr_cvp;
4449 u16 cvp_handle;
4450
4451 if (!(voice_get_cvd_int_version(common.cvd_version) >=
4452 CVD_INT_VERSION_2_2)) {
4453 pr_debug("%s CVD version string %s doesn't support this command\n",
4454 __func__, common.cvd_version);
4455
4456 goto done;
4457 }
4458
4459 if (v == NULL) {
4460 pr_err("%s: v is NULL\n", __func__);
4461
4462 ret = -EINVAL;
4463 goto done;
4464 }
4465
4466 apr_cvp = common.apr_q6_cvp;
4467 if (!apr_cvp) {
4468 pr_err("%s: apr_cvp is NULL.\n", __func__);
4469
4470 ret = -EINVAL;
4471 goto done;
4472 }
4473
4474 cvp_handle = voice_get_cvp_handle(v);
4475 cvp_topology_commit_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4476 APR_HDR_LEN(APR_HDR_SIZE),
4477 APR_PKT_VER);
4478 cvp_topology_commit_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
4479 sizeof(cvp_topology_commit_cmd) - APR_HDR_SIZE);
4480 cvp_topology_commit_cmd.src_port =
4481 voice_get_idx_for_session(v->session_id);
4482 cvp_topology_commit_cmd.dest_port = cvp_handle;
4483 cvp_topology_commit_cmd.token = 0;
4484 cvp_topology_commit_cmd.opcode = VSS_IVOCPROC_CMD_TOPOLOGY_COMMIT;
4485
4486 v->cvp_state = CMD_STATUS_FAIL;
4487 v->async_err = 0;
4488 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_topology_commit_cmd);
4489 if (ret < 0) {
4490 pr_err("%s: Fail in sending VSS_IVOCPROC_CMD_TOPOLOGY_COMMIT\n",
4491 __func__);
4492
4493 ret = -EINVAL;
4494 goto done;
4495 }
4496
4497 ret = wait_event_timeout(v->cvp_wait,
4498 (v->cvp_state == CMD_STATUS_SUCCESS),
4499 msecs_to_jiffies(TIMEOUT_MS));
4500 if (!ret) {
4501 pr_err("%s: wait_event timeout\n", __func__);
4502 ret = -EINVAL;
4503 goto done;
4504 }
4505 if (v->async_err > 0) {
4506 pr_err("%s: DSP returned error[%s]\n",
4507 __func__, adsp_err_get_err_str(
4508 v->async_err));
4509 ret = adsp_err_get_lnx_err_code(
4510 v->async_err);
4511 goto done;
4512 }
4513
4514done:
4515 return ret;
4516}
4517
4518static int voice_send_enable_vocproc_cmd(struct voice_data *v)
4519{
4520 int ret = 0;
4521 struct apr_hdr cvp_enable_cmd;
4522 void *apr_cvp;
4523 u16 cvp_handle;
4524
4525 if (v == NULL) {
4526 pr_err("%s: v is NULL\n", __func__);
4527 return -EINVAL;
4528 }
4529 apr_cvp = common.apr_q6_cvp;
4530
4531 if (!apr_cvp) {
4532 pr_err("%s: apr_cvp is NULL.\n", __func__);
4533 return -EINVAL;
4534 }
4535 cvp_handle = voice_get_cvp_handle(v);
4536
4537 /* enable vocproc and wait for respose */
4538 cvp_enable_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4539 APR_HDR_LEN(APR_HDR_SIZE),
4540 APR_PKT_VER);
4541 cvp_enable_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
4542 sizeof(cvp_enable_cmd) - APR_HDR_SIZE);
4543 pr_debug("cvp_enable_cmd pkt size = %d, cvp_handle=%d\n",
4544 cvp_enable_cmd.pkt_size, cvp_handle);
4545 cvp_enable_cmd.src_port =
4546 voice_get_idx_for_session(v->session_id);
4547 cvp_enable_cmd.dest_port = cvp_handle;
4548 cvp_enable_cmd.token = 0;
4549 cvp_enable_cmd.opcode = VSS_IVOCPROC_CMD_ENABLE;
4550
4551 v->cvp_state = CMD_STATUS_FAIL;
4552 v->async_err = 0;
4553 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_enable_cmd);
4554 if (ret < 0) {
4555 pr_err("Fail in sending VSS_IVOCPROC_CMD_ENABLE\n");
4556 goto fail;
4557 }
4558 ret = wait_event_timeout(v->cvp_wait,
4559 (v->cvp_state == CMD_STATUS_SUCCESS),
4560 msecs_to_jiffies(TIMEOUT_MS));
4561 if (!ret) {
4562 pr_err("%s: wait_event timeout\n", __func__);
4563 goto fail;
4564 }
4565 if (v->async_err > 0) {
4566 pr_err("%s: DSP returned error[%s]\n",
4567 __func__, adsp_err_get_err_str(
4568 v->async_err));
4569 ret = adsp_err_get_lnx_err_code(
4570 v->async_err);
4571 goto fail;
4572 }
4573
4574 return 0;
4575fail:
4576 return ret;
4577}
4578
4579static int voice_send_mvm_cal_network_cmd(struct voice_data *v)
4580{
4581 struct vss_imvm_cmd_set_cal_network_t mvm_set_cal_network;
4582 int ret = 0;
4583 void *apr_mvm;
4584 u16 mvm_handle;
4585
4586 if (v == NULL) {
4587 pr_err("%s: v is NULL\n", __func__);
4588 return -EINVAL;
4589 }
4590 apr_mvm = common.apr_q6_mvm;
4591
4592 if (!apr_mvm) {
4593 pr_err("%s: apr_mvm is NULL.\n", __func__);
4594 return -EINVAL;
4595 }
4596 mvm_handle = voice_get_mvm_handle(v);
4597
4598 mvm_set_cal_network.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4599 APR_HDR_LEN(APR_HDR_SIZE),
4600 APR_PKT_VER);
4601 mvm_set_cal_network.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
4602 sizeof(mvm_set_cal_network) - APR_HDR_SIZE);
4603 mvm_set_cal_network.hdr.src_port =
4604 voice_get_idx_for_session(v->session_id);
4605 mvm_set_cal_network.hdr.dest_port = mvm_handle;
4606 mvm_set_cal_network.hdr.token = 0;
4607 mvm_set_cal_network.hdr.opcode = VSS_IMVM_CMD_SET_CAL_NETWORK;
4608 mvm_set_cal_network.network_id = VSS_ICOMMON_CAL_NETWORK_ID_NONE;
4609
4610 v->mvm_state = CMD_STATUS_FAIL;
4611 v->async_err = 0;
4612 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_cal_network);
4613 if (ret < 0) {
4614 pr_err("%s: Error %d sending SET_NETWORK\n", __func__, ret);
4615 goto fail;
4616 }
4617
4618 ret = wait_event_timeout(v->mvm_wait,
4619 (v->mvm_state == CMD_STATUS_SUCCESS),
4620 msecs_to_jiffies(TIMEOUT_MS));
4621 if (!ret) {
4622 pr_err("%s: wait_event timeout %d\n", __func__, ret);
4623 goto fail;
4624 }
4625 if (v->async_err > 0) {
4626 pr_err("%s: DSP returned error[%s]\n",
4627 __func__, adsp_err_get_err_str(
4628 v->async_err));
4629 ret = adsp_err_get_lnx_err_code(
4630 v->async_err);
4631 goto fail;
4632 }
4633 return 0;
4634fail:
4635 return ret;
4636}
4637
4638static int voice_send_netid_timing_cmd(struct voice_data *v)
4639{
4640 int ret = 0;
4641 void *apr_mvm;
4642 u16 mvm_handle;
4643 struct mvm_set_network_cmd mvm_set_network;
4644 struct mvm_set_voice_timing_cmd mvm_set_voice_timing;
4645
4646 if (v == NULL) {
4647 pr_err("%s: v is NULL\n", __func__);
4648 return -EINVAL;
4649 }
4650 apr_mvm = common.apr_q6_mvm;
4651
4652 if (!apr_mvm) {
4653 pr_err("%s: apr_mvm is NULL.\n", __func__);
4654 return -EINVAL;
4655 }
4656 mvm_handle = voice_get_mvm_handle(v);
4657
4658 ret = voice_config_cvs_vocoder(v);
4659 if (ret < 0) {
4660 pr_err("%s: Error %d configuring CVS voc",
4661 __func__, ret);
4662 goto fail;
4663 }
4664 /* Set network ID. */
4665 pr_debug("Setting network ID %x\n", common.mvs_info.network_type);
4666
4667 mvm_set_network.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4668 APR_HDR_LEN(APR_HDR_SIZE),
4669 APR_PKT_VER);
4670 mvm_set_network.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
4671 sizeof(mvm_set_network) - APR_HDR_SIZE);
4672 mvm_set_network.hdr.src_port =
4673 voice_get_idx_for_session(v->session_id);
4674 mvm_set_network.hdr.dest_port = mvm_handle;
4675 mvm_set_network.hdr.token = 0;
4676 mvm_set_network.hdr.opcode = VSS_IMVM_CMD_SET_CAL_NETWORK;
4677 mvm_set_network.network.network_id = common.mvs_info.network_type;
4678
4679 v->mvm_state = CMD_STATUS_FAIL;
4680 v->async_err = 0;
4681 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_network);
4682 if (ret < 0) {
4683 pr_err("%s: Error %d sending SET_NETWORK\n", __func__, ret);
4684 goto fail;
4685 }
4686
4687 ret = wait_event_timeout(v->mvm_wait,
4688 (v->mvm_state == CMD_STATUS_SUCCESS),
4689 msecs_to_jiffies(TIMEOUT_MS));
4690 if (!ret) {
4691 pr_err("%s: wait_event timeout\n", __func__);
4692 goto fail;
4693 }
4694 if (v->async_err > 0) {
4695 pr_err("%s: DSP returned error[%s]\n",
4696 __func__, adsp_err_get_err_str(
4697 v->async_err));
4698 ret = adsp_err_get_lnx_err_code(
4699 v->async_err);
4700 goto fail;
4701 }
4702
4703 /* Set voice timing. */
4704 pr_debug("Setting voice timing\n");
4705
4706 mvm_set_voice_timing.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4707 APR_HDR_LEN(APR_HDR_SIZE),
4708 APR_PKT_VER);
4709 mvm_set_voice_timing.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
4710 sizeof(mvm_set_voice_timing) -
4711 APR_HDR_SIZE);
4712 mvm_set_voice_timing.hdr.src_port =
4713 voice_get_idx_for_session(v->session_id);
4714 mvm_set_voice_timing.hdr.dest_port = mvm_handle;
4715 mvm_set_voice_timing.hdr.token = 0;
4716 mvm_set_voice_timing.hdr.opcode = VSS_ICOMMON_CMD_SET_VOICE_TIMING;
4717 mvm_set_voice_timing.timing.mode = 0;
4718 mvm_set_voice_timing.timing.enc_offset = 8000;
4719 mvm_set_voice_timing.timing.dec_req_offset = 3300;
4720 mvm_set_voice_timing.timing.dec_offset = 8300;
4721
4722 v->mvm_state = CMD_STATUS_FAIL;
4723 v->async_err = 0;
4724
4725 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_voice_timing);
4726 if (ret < 0) {
4727 pr_err("%s: Error %d sending SET_TIMING\n", __func__, ret);
4728 goto fail;
4729 }
4730
4731 ret = wait_event_timeout(v->mvm_wait,
4732 (v->mvm_state == CMD_STATUS_SUCCESS),
4733 msecs_to_jiffies(TIMEOUT_MS));
4734 if (!ret) {
4735 pr_err("%s: wait_event timeout\n", __func__);
4736 goto fail;
4737 }
4738 if (v->async_err > 0) {
4739 pr_err("%s: DSP returned error[%s]\n",
4740 __func__, adsp_err_get_err_str(
4741 v->async_err));
4742 ret = adsp_err_get_lnx_err_code(
4743 v->async_err);
4744 goto fail;
4745 }
4746
4747 return 0;
4748fail:
4749 return ret;
4750}
4751
4752static int voice_send_attach_vocproc_cmd(struct voice_data *v)
4753{
4754 int ret = 0;
4755 struct mvm_attach_vocproc_cmd mvm_a_vocproc_cmd;
4756 void *apr_mvm;
4757 u16 mvm_handle, cvp_handle;
4758
4759 if (v == NULL) {
4760 pr_err("%s: v is NULL\n", __func__);
4761 return -EINVAL;
4762 }
4763 apr_mvm = common.apr_q6_mvm;
4764
4765 if (!apr_mvm) {
4766 pr_err("%s: apr_mvm is NULL.\n", __func__);
4767 return -EINVAL;
4768 }
4769 mvm_handle = voice_get_mvm_handle(v);
4770 cvp_handle = voice_get_cvp_handle(v);
4771
4772 /* attach vocproc and wait for response */
4773 mvm_a_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4774 APR_HDR_LEN(APR_HDR_SIZE),
4775 APR_PKT_VER);
4776 mvm_a_vocproc_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
4777 sizeof(mvm_a_vocproc_cmd) - APR_HDR_SIZE);
4778 pr_debug("send mvm_a_vocproc_cmd pkt size = %d\n",
4779 mvm_a_vocproc_cmd.hdr.pkt_size);
4780 mvm_a_vocproc_cmd.hdr.src_port =
4781 voice_get_idx_for_session(v->session_id);
4782 mvm_a_vocproc_cmd.hdr.dest_port = mvm_handle;
4783 mvm_a_vocproc_cmd.hdr.token = 0;
4784 mvm_a_vocproc_cmd.hdr.opcode = VSS_IMVM_CMD_ATTACH_VOCPROC;
4785 mvm_a_vocproc_cmd.mvm_attach_cvp_handle.handle = cvp_handle;
4786
4787 v->mvm_state = CMD_STATUS_FAIL;
4788 v->async_err = 0;
4789 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_a_vocproc_cmd);
4790 if (ret < 0) {
4791 pr_err("Fail in sending VSS_IMVM_CMD_ATTACH_VOCPROC\n");
4792 goto fail;
4793 }
4794 ret = wait_event_timeout(v->mvm_wait,
4795 (v->mvm_state == CMD_STATUS_SUCCESS),
4796 msecs_to_jiffies(TIMEOUT_MS));
4797 if (!ret) {
4798 pr_err("%s: wait_event timeout\n", __func__);
4799 goto fail;
4800 }
4801 if (v->async_err > 0) {
4802 pr_err("%s: DSP returned error[%s]\n",
4803 __func__, adsp_err_get_err_str(
4804 v->async_err));
4805 ret = adsp_err_get_lnx_err_code(
4806 v->async_err);
4807 goto fail;
4808 }
4809
4810 return 0;
4811fail:
4812 return ret;
4813}
4814
4815static void voc_update_session_params(struct voice_data *v)
4816{
4817 /* reset LCH mode */
4818 v->lch_mode = 0;
4819
4820 /* clear disable topology setting */
4821 v->disable_topology = false;
4822
4823 /* clear mute setting */
4824 v->dev_rx.dev_mute = common.default_mute_val;
4825 v->dev_tx.dev_mute = common.default_mute_val;
4826 v->stream_rx.stream_mute = common.default_mute_val;
4827 v->stream_tx.stream_mute = common.default_mute_val;
4828}
4829
4830static int voice_destroy_vocproc(struct voice_data *v)
4831{
4832 struct mvm_detach_vocproc_cmd mvm_d_vocproc_cmd;
4833 struct apr_hdr cvp_destroy_session_cmd;
4834 int ret = 0;
4835 void *apr_mvm, *apr_cvp;
4836 u16 mvm_handle, cvp_handle;
4837
4838 if (v == NULL) {
4839 pr_err("%s: v is NULL\n", __func__);
4840 return -EINVAL;
4841 }
4842 apr_mvm = common.apr_q6_mvm;
4843 apr_cvp = common.apr_q6_cvp;
4844
4845 if (!apr_mvm || !apr_cvp) {
4846 pr_err("%s: apr_mvm or apr_cvp is NULL.\n", __func__);
4847 return -EINVAL;
4848 }
4849 mvm_handle = voice_get_mvm_handle(v);
4850 cvp_handle = voice_get_cvp_handle(v);
4851
4852 /* disable slowtalk if st_enable is set */
4853 if (v->st_enable)
4854 voice_send_set_pp_enable_cmd(v, MODULE_ID_VOICE_MODULE_ST, 0);
4855
4856 /* Disable HD Voice if hd_enable is set */
4857 if (v->hd_enable)
4858 voice_send_hd_cmd(v, 0);
4859
4860 /* stop playback or recording */
4861 v->music_info.force = 1;
4862 voice_cvs_stop_playback(v);
4863 voice_cvs_stop_record(v);
4864 /* If voice call is active during VoLTE, SRVCC happens.
4865 * Start recording on voice session if recording started during VoLTE.
4866 */
4867 if (is_volte_session(v->session_id) &&
4868 ((common.voice[VOC_PATH_PASSIVE].voc_state == VOC_RUN) ||
4869 (common.voice[VOC_PATH_PASSIVE].voc_state == VOC_CHANGE))) {
4870 if (v->rec_info.rec_enable) {
4871 voice_cvs_start_record(
4872 &common.voice[VOC_PATH_PASSIVE],
4873 v->rec_info.rec_mode);
4874 common.srvcc_rec_flag = true;
4875
4876 pr_debug("%s: switch recording, srvcc_rec_flag %d\n",
4877 __func__, common.srvcc_rec_flag);
4878 }
4879 }
4880
4881 /* send stop voice cmd */
4882 voice_send_stop_voice_cmd(v);
4883
4884 /* send stop dtmf detecton cmd */
4885 if (v->dtmf_rx_detect_en)
4886 voice_send_dtmf_rx_detection_cmd(v, 0);
4887
4888 /* detach VOCPROC and wait for response from mvm */
4889 mvm_d_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4890 APR_HDR_LEN(APR_HDR_SIZE),
4891 APR_PKT_VER);
4892 mvm_d_vocproc_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
4893 sizeof(mvm_d_vocproc_cmd) - APR_HDR_SIZE);
4894 pr_debug("mvm_d_vocproc_cmd pkt size = %d\n",
4895 mvm_d_vocproc_cmd.hdr.pkt_size);
4896 mvm_d_vocproc_cmd.hdr.src_port =
4897 voice_get_idx_for_session(v->session_id);
4898 mvm_d_vocproc_cmd.hdr.dest_port = mvm_handle;
4899 mvm_d_vocproc_cmd.hdr.token = 0;
4900 mvm_d_vocproc_cmd.hdr.opcode = VSS_IMVM_CMD_DETACH_VOCPROC;
4901 mvm_d_vocproc_cmd.mvm_detach_cvp_handle.handle = cvp_handle;
4902
4903 v->mvm_state = CMD_STATUS_FAIL;
4904 v->async_err = 0;
4905 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_d_vocproc_cmd);
4906 if (ret < 0) {
4907 pr_err("Fail in sending VSS_IMVM_CMD_DETACH_VOCPROC\n");
4908 goto fail;
4909 }
4910 ret = wait_event_timeout(v->mvm_wait,
4911 (v->mvm_state == CMD_STATUS_SUCCESS),
4912 msecs_to_jiffies(TIMEOUT_MS));
4913 if (!ret) {
4914 pr_err("%s: wait_event timeout\n", __func__);
4915 goto fail;
4916 }
4917 if (v->async_err > 0) {
4918 pr_err("%s: DSP returned error[%s]\n",
4919 __func__, adsp_err_get_err_str(
4920 v->async_err));
4921 ret = adsp_err_get_lnx_err_code(
4922 v->async_err);
4923 goto fail;
4924 }
4925
4926 voice_send_cvp_deregister_vol_cal_cmd(v);
4927 voice_send_cvp_deregister_cal_cmd(v);
4928 voice_send_cvp_deregister_dev_cfg_cmd(v);
4929 voice_send_cvs_deregister_cal_cmd(v);
4930
4931 /* destrop cvp session */
4932 cvp_destroy_session_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4933 APR_HDR_LEN(APR_HDR_SIZE),
4934 APR_PKT_VER);
4935 cvp_destroy_session_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
4936 sizeof(cvp_destroy_session_cmd) - APR_HDR_SIZE);
4937 pr_debug("cvp_destroy_session_cmd pkt size = %d\n",
4938 cvp_destroy_session_cmd.pkt_size);
4939 cvp_destroy_session_cmd.src_port =
4940 voice_get_idx_for_session(v->session_id);
4941 cvp_destroy_session_cmd.dest_port = cvp_handle;
4942 cvp_destroy_session_cmd.token = 0;
4943 cvp_destroy_session_cmd.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
4944
4945 v->cvp_state = CMD_STATUS_FAIL;
4946 v->async_err = 0;
4947 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_destroy_session_cmd);
4948 if (ret < 0) {
4949 pr_err("Fail in sending APRV2_IBASIC_CMD_DESTROY_SESSION\n");
4950 goto fail;
4951 }
4952 ret = wait_event_timeout(v->cvp_wait,
4953 (v->cvp_state == CMD_STATUS_SUCCESS),
4954 msecs_to_jiffies(TIMEOUT_MS));
4955 if (!ret) {
4956 pr_err("%s: wait_event timeout\n", __func__);
4957 goto fail;
4958 }
4959 if (v->async_err > 0) {
4960 pr_err("%s: DSP returned error[%s]\n",
4961 __func__, adsp_err_get_err_str(
4962 v->async_err));
4963 ret = adsp_err_get_lnx_err_code(
4964 v->async_err);
4965 goto fail;
4966 }
4967
4968 rtac_remove_voice(voice_get_cvs_handle(v));
4969 cvp_handle = 0;
4970 voice_set_cvp_handle(v, cvp_handle);
4971 return 0;
4972fail:
4973 return ret;
4974}
4975
4976static int voice_send_mvm_unmap_memory_physical_cmd(struct voice_data *v,
4977 uint32_t mem_handle)
4978{
4979 struct vss_imemory_cmd_unmap_t mem_unmap;
4980 int ret = 0;
4981 void *apr_mvm;
4982 u16 mvm_handle;
4983
4984 if (v == NULL) {
4985 pr_err("%s: v is NULL\n", __func__);
4986 return -EINVAL;
4987 }
4988 apr_mvm = common.apr_q6_mvm;
4989
4990 if (!apr_mvm) {
4991 pr_err("%s: apr_mvm is NULL.\n", __func__);
4992 return -EINVAL;
4993 }
4994 mvm_handle = voice_get_mvm_handle(v);
4995
4996 mem_unmap.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4997 APR_HDR_LEN(APR_HDR_SIZE),
4998 APR_PKT_VER);
4999 mem_unmap.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
5000 sizeof(mem_unmap) - APR_HDR_SIZE);
5001 mem_unmap.hdr.src_port =
5002 voice_get_idx_for_session(v->session_id);
5003 mem_unmap.hdr.dest_port = mvm_handle;
5004 mem_unmap.hdr.token = 0;
5005 mem_unmap.hdr.opcode = VSS_IMEMORY_CMD_UNMAP;
5006 mem_unmap.mem_handle = mem_handle;
5007
5008 pr_debug("%s: mem_handle: 0x%x\n", __func__, mem_unmap.mem_handle);
5009
5010 v->mvm_state = CMD_STATUS_FAIL;
5011 v->async_err = 0;
5012 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mem_unmap);
5013 if (ret < 0) {
5014 pr_err("mem_unmap op[0x%x]ret[%d]\n",
5015 mem_unmap.hdr.opcode, ret);
5016 goto fail;
5017 }
5018
5019 ret = wait_event_timeout(v->mvm_wait,
5020 (v->mvm_state == CMD_STATUS_SUCCESS),
5021 msecs_to_jiffies(TIMEOUT_MS));
5022 if (!ret) {
5023 pr_err("%s: wait_event timeout %d\n", __func__, ret);
5024 goto fail;
5025 }
5026 if (v->async_err > 0) {
5027 pr_err("%s: DSP returned error[%s]\n",
5028 __func__, adsp_err_get_err_str(
5029 v->async_err));
5030 ret = adsp_err_get_lnx_err_code(
5031 v->async_err);
5032 goto fail;
5033 }
5034 return 0;
5035
5036fail:
5037 return ret;
5038}
5039
5040static int voice_send_cvs_packet_exchange_config_cmd(struct voice_data *v)
5041{
5042 struct vss_istream_cmd_set_oob_packet_exchange_config_t
5043 packet_exchange_config_pkt;
5044 int ret = 0;
5045 void *apr_cvs;
5046 u16 cvs_handle;
5047
5048 if (v == NULL) {
5049 pr_err("%s: v is NULL\n", __func__);
5050 return -EINVAL;
5051 }
5052
5053 apr_cvs = common.apr_q6_cvs;
5054
5055 if (!apr_cvs) {
5056 pr_err("%s: apr_cvs is NULL.\n", __func__);
5057 return -EINVAL;
5058 }
5059 cvs_handle = voice_get_cvs_handle(v);
5060
5061 packet_exchange_config_pkt.hdr.hdr_field = APR_HDR_FIELD(
5062 APR_MSG_TYPE_SEQ_CMD,
5063 APR_HDR_LEN(APR_HDR_SIZE),
5064 APR_PKT_VER);
5065 packet_exchange_config_pkt.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
5066 sizeof(packet_exchange_config_pkt) -
5067 APR_HDR_SIZE);
5068 packet_exchange_config_pkt.hdr.src_port =
5069 voice_get_idx_for_session(v->session_id);
5070 packet_exchange_config_pkt.hdr.dest_port = cvs_handle;
5071 packet_exchange_config_pkt.hdr.token = 0;
5072 packet_exchange_config_pkt.hdr.opcode =
5073 VSS_ISTREAM_CMD_SET_OOB_PACKET_EXCHANGE_CONFIG;
5074 packet_exchange_config_pkt.mem_handle = v->shmem_info.mem_handle;
5075 /* dec buffer address */
5076 packet_exchange_config_pkt.dec_buf_addr_lsw =
5077 lower_32_bits(v->shmem_info.sh_buf.buf[0].phys);
5078 packet_exchange_config_pkt.dec_buf_addr_msw =
5079 msm_audio_populate_upper_32_bits(
5080 v->shmem_info.sh_buf.buf[0].phys);
5081 packet_exchange_config_pkt.dec_buf_size = 4096;
5082 /* enc buffer address */
5083 packet_exchange_config_pkt.enc_buf_addr_lsw =
5084 lower_32_bits(v->shmem_info.sh_buf.buf[1].phys);
5085 packet_exchange_config_pkt.enc_buf_addr_msw =
5086 msm_audio_populate_upper_32_bits(
5087 v->shmem_info.sh_buf.buf[1].phys);
5088 packet_exchange_config_pkt.enc_buf_size = 4096;
5089
5090 pr_debug("%s: dec buf add: lsw %0x msw %0x, size %d, enc buf add: lsw %0x msw %0x, size %d\n",
5091 __func__,
5092 packet_exchange_config_pkt.dec_buf_addr_lsw,
5093 packet_exchange_config_pkt.dec_buf_addr_msw,
5094 packet_exchange_config_pkt.dec_buf_size,
5095 packet_exchange_config_pkt.enc_buf_addr_lsw,
5096 packet_exchange_config_pkt.enc_buf_addr_msw,
5097 packet_exchange_config_pkt.enc_buf_size);
5098
5099 v->cvs_state = CMD_STATUS_FAIL;
5100 v->async_err = 0;
5101 ret = apr_send_pkt(apr_cvs, (uint32_t *) &packet_exchange_config_pkt);
5102 if (ret < 0) {
5103 pr_err("Failed to send packet exchange config cmd %d\n", ret);
5104 goto fail;
5105 }
5106
5107 ret = wait_event_timeout(v->cvs_wait,
5108 (v->cvs_state == CMD_STATUS_SUCCESS),
5109 msecs_to_jiffies(TIMEOUT_MS));
5110 if (!ret)
5111 pr_err("%s: wait_event timeout %d\n", __func__, ret);
5112
5113 if (v->async_err > 0) {
5114 pr_err("%s: DSP returned error[%s]\n",
5115 __func__, adsp_err_get_err_str(
5116 v->async_err));
5117 ret = adsp_err_get_lnx_err_code(
5118 v->async_err);
5119 goto fail;
5120 }
5121
5122 return 0;
5123fail:
5124 return ret;
5125}
5126
5127static int voice_send_cvs_data_exchange_mode_cmd(struct voice_data *v)
5128{
5129 struct vss_istream_cmd_set_packet_exchange_mode_t data_exchange_pkt;
5130 int ret = 0;
5131 void *apr_cvs;
5132 u16 cvs_handle;
5133
5134 if (v == NULL) {
5135 pr_err("%s: v is NULL\n", __func__);
5136 return -EINVAL;
5137 }
5138 apr_cvs = common.apr_q6_cvs;
5139
5140 if (!apr_cvs) {
5141 pr_err("%s: apr_cvs is NULL.\n", __func__);
5142 return -EINVAL;
5143 }
5144 cvs_handle = voice_get_cvs_handle(v);
5145
5146 data_exchange_pkt.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
5147 APR_HDR_LEN(APR_HDR_SIZE),
5148 APR_PKT_VER);
5149 data_exchange_pkt.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
5150 sizeof(data_exchange_pkt) - APR_HDR_SIZE);
5151 data_exchange_pkt.hdr.src_port =
5152 voice_get_idx_for_session(v->session_id);
5153 data_exchange_pkt.hdr.dest_port = cvs_handle;
5154 data_exchange_pkt.hdr.token = 0;
5155 data_exchange_pkt.hdr.opcode = VSS_ISTREAM_CMD_SET_PACKET_EXCHANGE_MODE;
5156 data_exchange_pkt.mode = VSS_ISTREAM_PACKET_EXCHANGE_MODE_OUT_OF_BAND;
5157
5158 v->cvs_state = CMD_STATUS_FAIL;
5159 v->async_err = 0;
5160 ret = apr_send_pkt(apr_cvs, (uint32_t *) &data_exchange_pkt);
5161 if (ret < 0) {
5162 pr_err("Failed to send data exchange mode %d\n", ret);
5163 goto fail;
5164 }
5165
5166 ret = wait_event_timeout(v->cvs_wait,
5167 (v->cvs_state == CMD_STATUS_SUCCESS),
5168 msecs_to_jiffies(TIMEOUT_MS));
5169 if (!ret)
5170 pr_err("%s: wait_event timeout %d\n", __func__, ret);
5171
5172 if (v->async_err > 0) {
5173 pr_err("%s: DSP returned error[%s]\n",
5174 __func__, adsp_err_get_err_str(
5175 v->async_err));
5176 ret = adsp_err_get_lnx_err_code(
5177 v->async_err);
5178 goto fail;
5179 }
5180 return 0;
5181fail:
5182 return ret;
5183}
5184
5185static int voice_send_stream_mute_cmd(struct voice_data *v, uint16_t direction,
5186 uint16_t mute_flag, uint32_t ramp_duration)
5187{
5188 struct cvs_set_mute_cmd cvs_mute_cmd;
5189 int ret = 0;
5190
5191 if (v == NULL) {
5192 pr_err("%s: v is NULL\n", __func__);
5193 ret = -EINVAL;
5194 goto fail;
5195 }
5196
5197 if (!common.apr_q6_cvs) {
5198 pr_err("%s: apr_cvs is NULL.\n", __func__);
5199 ret = -EINVAL;
5200 goto fail;
5201 }
5202
5203 /* send mute/unmute to cvs */
5204 cvs_mute_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
5205 APR_HDR_LEN(APR_HDR_SIZE),
5206 APR_PKT_VER);
5207 cvs_mute_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
5208 sizeof(cvs_mute_cmd) - APR_HDR_SIZE);
5209 cvs_mute_cmd.hdr.src_port =
5210 voice_get_idx_for_session(v->session_id);
5211 cvs_mute_cmd.hdr.dest_port = voice_get_cvs_handle(v);
5212 cvs_mute_cmd.hdr.token = 0;
5213 cvs_mute_cmd.hdr.opcode = VSS_IVOLUME_CMD_MUTE_V2;
5214 cvs_mute_cmd.cvs_set_mute.direction = direction;
5215 cvs_mute_cmd.cvs_set_mute.mute_flag = mute_flag;
5216 cvs_mute_cmd.cvs_set_mute.ramp_duration_ms = ramp_duration;
5217
5218 v->cvs_state = CMD_STATUS_FAIL;
5219 v->async_err = 0;
5220 ret = apr_send_pkt(common.apr_q6_cvs, (uint32_t *) &cvs_mute_cmd);
5221 if (ret < 0) {
5222 pr_err("%s: Error %d sending stream mute\n", __func__, ret);
5223
5224 goto fail;
5225 }
5226 ret = wait_event_timeout(v->cvs_wait,
5227 (v->cvs_state == CMD_STATUS_SUCCESS),
5228 msecs_to_jiffies(TIMEOUT_MS));
5229 if (!ret) {
5230 pr_err("%s: Command timeout\n", __func__);
5231 goto fail;
5232 }
5233 if (v->async_err > 0) {
5234 pr_err("%s: DSP returned error[%s]\n",
5235 __func__, adsp_err_get_err_str(
5236 v->async_err));
5237 ret = adsp_err_get_lnx_err_code(
5238 v->async_err);
5239 goto fail;
5240 }
5241
5242 return 0;
5243
5244fail:
5245 return ret;
5246}
5247
5248static int voice_send_device_mute_cmd(struct voice_data *v, uint16_t direction,
5249 uint16_t mute_flag, uint32_t ramp_duration)
5250{
5251 struct cvp_set_mute_cmd cvp_mute_cmd;
5252 int ret = 0;
5253
5254 if (v == NULL) {
5255 pr_err("%s: v is NULL\n", __func__);
5256 ret = -EINVAL;
5257 goto fail;
5258 }
5259
5260 if (!common.apr_q6_cvp) {
5261 pr_err("%s: apr_cvp is NULL.\n", __func__);
5262 ret = -EINVAL;
5263 goto fail;
5264 }
5265
5266 cvp_mute_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
5267 APR_HDR_LEN(APR_HDR_SIZE),
5268 APR_PKT_VER);
5269 cvp_mute_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
5270 sizeof(cvp_mute_cmd) - APR_HDR_SIZE);
5271 cvp_mute_cmd.hdr.src_port =
5272 voice_get_idx_for_session(v->session_id);
5273 cvp_mute_cmd.hdr.dest_port = voice_get_cvp_handle(v);
5274 cvp_mute_cmd.hdr.token = 0;
5275 cvp_mute_cmd.hdr.opcode = VSS_IVOLUME_CMD_MUTE_V2;
5276 cvp_mute_cmd.cvp_set_mute.direction = direction;
5277 cvp_mute_cmd.cvp_set_mute.mute_flag = mute_flag;
5278 cvp_mute_cmd.cvp_set_mute.ramp_duration_ms = ramp_duration;
5279
5280 v->cvp_state = CMD_STATUS_FAIL;
5281 v->async_err = 0;
5282 ret = apr_send_pkt(common.apr_q6_cvp, (uint32_t *) &cvp_mute_cmd);
5283 if (ret < 0) {
5284 pr_err("%s: Error %d sending rx device cmd\n", __func__, ret);
5285
5286 goto fail;
5287 }
5288 ret = wait_event_timeout(v->cvp_wait,
5289 (v->cvp_state == CMD_STATUS_SUCCESS),
5290 msecs_to_jiffies(TIMEOUT_MS));
5291 if (!ret) {
5292 pr_err("%s: Command timeout\n", __func__);
5293 goto fail;
5294 }
5295 if (v->async_err > 0) {
5296 pr_err("%s: DSP returned error[%s]\n",
5297 __func__, adsp_err_get_err_str(
5298 v->async_err));
5299 ret = adsp_err_get_lnx_err_code(
5300 v->async_err);
5301 goto fail;
5302 }
5303
5304 return 0;
5305
5306fail:
5307 return ret;
5308}
5309
5310static int voice_send_vol_step_cmd(struct voice_data *v)
5311{
5312 struct cvp_set_rx_volume_step_cmd cvp_vol_step_cmd;
5313 int ret = 0;
5314 void *apr_cvp;
5315 u16 cvp_handle;
5316
5317 if (v == NULL) {
5318 pr_err("%s: v is NULL\n", __func__);
5319 return -EINVAL;
5320 }
5321 apr_cvp = common.apr_q6_cvp;
5322
5323 if (!apr_cvp) {
5324 pr_err("%s: apr_cvp is NULL.\n", __func__);
5325 return -EINVAL;
5326 }
5327 cvp_handle = voice_get_cvp_handle(v);
5328
5329 /* send volume index to cvp */
5330 cvp_vol_step_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
5331 APR_HDR_LEN(APR_HDR_SIZE),
5332 APR_PKT_VER);
5333 cvp_vol_step_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
5334 sizeof(cvp_vol_step_cmd) - APR_HDR_SIZE);
5335 cvp_vol_step_cmd.hdr.src_port =
5336 voice_get_idx_for_session(v->session_id);
5337 cvp_vol_step_cmd.hdr.dest_port = cvp_handle;
5338 cvp_vol_step_cmd.hdr.token = 0;
5339 cvp_vol_step_cmd.hdr.opcode = VSS_IVOLUME_CMD_SET_STEP;
5340 cvp_vol_step_cmd.cvp_set_vol_step.direction = VSS_IVOLUME_DIRECTION_RX;
5341 cvp_vol_step_cmd.cvp_set_vol_step.value = v->dev_rx.volume_step_value;
5342 cvp_vol_step_cmd.cvp_set_vol_step.ramp_duration_ms =
5343 v->dev_rx.volume_ramp_duration_ms;
5344 pr_debug("%s step_value:%d, ramp_duration_ms:%d",
5345 __func__,
5346 cvp_vol_step_cmd.cvp_set_vol_step.value,
5347 cvp_vol_step_cmd.cvp_set_vol_step.ramp_duration_ms);
5348
5349 v->cvp_state = CMD_STATUS_FAIL;
5350 v->async_err = 0;
5351 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_vol_step_cmd);
5352 if (ret < 0) {
5353 pr_err("Fail in sending RX VOL step\n");
5354 return -EINVAL;
5355 }
5356 ret = wait_event_timeout(v->cvp_wait,
5357 (v->cvp_state == CMD_STATUS_SUCCESS),
5358 msecs_to_jiffies(TIMEOUT_MS));
5359 if (!ret) {
5360 pr_err("%s: wait_event timeout\n", __func__);
5361 return -EINVAL;
5362 }
5363 if (v->async_err > 0) {
5364 pr_err("%s: DSP returned error[%s]\n",
5365 __func__, adsp_err_get_err_str(
5366 v->async_err));
5367 ret = adsp_err_get_lnx_err_code(
5368 v->async_err);
5369 return ret;
5370 }
5371 return 0;
5372}
5373
5374static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode)
5375{
5376 int ret = 0;
5377 void *apr_cvs;
5378 u16 cvs_handle;
5379
5380 struct cvs_start_record_cmd cvs_start_record;
5381
5382 if (v == NULL) {
5383 pr_err("%s: v is NULL\n", __func__);
5384 return -EINVAL;
5385 }
5386 apr_cvs = common.apr_q6_cvs;
5387
5388 if (!apr_cvs) {
5389 pr_err("%s: apr_cvs is NULL.\n", __func__);
5390 return -EINVAL;
5391 }
5392
5393 cvs_handle = voice_get_cvs_handle(v);
5394
5395 if (!v->rec_info.recording) {
5396 cvs_start_record.hdr.hdr_field = APR_HDR_FIELD(
5397 APR_MSG_TYPE_SEQ_CMD,
5398 APR_HDR_LEN(APR_HDR_SIZE),
5399 APR_PKT_VER);
5400 cvs_start_record.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
5401 sizeof(cvs_start_record) - APR_HDR_SIZE);
5402 cvs_start_record.hdr.src_port =
5403 voice_get_idx_for_session(v->session_id);
5404 cvs_start_record.hdr.dest_port = cvs_handle;
5405 cvs_start_record.hdr.token = 0;
5406 cvs_start_record.hdr.opcode = VSS_IRECORD_CMD_START;
5407
5408 cvs_start_record.rec_mode.port_id =
5409 VSS_IRECORD_PORT_ID_DEFAULT;
5410 if (rec_mode == VOC_REC_UPLINK) {
5411 cvs_start_record.rec_mode.rx_tap_point =
5412 VSS_IRECORD_TAP_POINT_NONE;
5413 cvs_start_record.rec_mode.tx_tap_point =
5414 VSS_IRECORD_TAP_POINT_STREAM_END;
5415 } else if (rec_mode == VOC_REC_DOWNLINK) {
5416 cvs_start_record.rec_mode.rx_tap_point =
5417 VSS_IRECORD_TAP_POINT_STREAM_END;
5418 cvs_start_record.rec_mode.tx_tap_point =
5419 VSS_IRECORD_TAP_POINT_NONE;
5420 } else if (rec_mode == VOC_REC_BOTH) {
5421 cvs_start_record.rec_mode.rx_tap_point =
5422 VSS_IRECORD_TAP_POINT_STREAM_END;
5423 cvs_start_record.rec_mode.tx_tap_point =
5424 VSS_IRECORD_TAP_POINT_STREAM_END;
5425 } else {
5426 pr_err("%s: Invalid in-call rec_mode %d\n", __func__,
5427 rec_mode);
5428
5429 ret = -EINVAL;
5430 goto fail;
5431 }
5432
5433 v->cvs_state = CMD_STATUS_FAIL;
5434 v->async_err = 0;
5435
5436 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_start_record);
5437 if (ret < 0) {
5438 pr_err("%s: Error %d sending START_RECORD\n", __func__,
5439 ret);
5440
5441 goto fail;
5442 }
5443
5444 ret = wait_event_timeout(v->cvs_wait,
5445 (v->cvs_state == CMD_STATUS_SUCCESS),
5446 msecs_to_jiffies(TIMEOUT_MS));
5447
5448 if (!ret) {
5449 pr_err("%s: wait_event timeout\n", __func__);
5450
5451 goto fail;
5452 }
5453 if (v->async_err > 0) {
5454 pr_err("%s: DSP returned error[%s]\n",
5455 __func__, adsp_err_get_err_str(
5456 v->async_err));
5457 ret = adsp_err_get_lnx_err_code(
5458 v->async_err);
5459 goto fail;
5460 }
5461 v->rec_info.recording = 1;
5462 } else {
5463 pr_debug("%s: Start record already sent\n", __func__);
5464 }
5465
5466 return 0;
5467
5468fail:
5469 return ret;
5470}
5471
5472static int voice_cvs_stop_record(struct voice_data *v)
5473{
5474 int ret = 0;
5475 void *apr_cvs;
5476 u16 cvs_handle;
5477 struct apr_hdr cvs_stop_record;
5478
5479 if (v == NULL) {
5480 pr_err("%s: v is NULL\n", __func__);
5481 return -EINVAL;
5482 }
5483 apr_cvs = common.apr_q6_cvs;
5484
5485 if (!apr_cvs) {
5486 pr_err("%s: apr_cvs is NULL.\n", __func__);
5487 return -EINVAL;
5488 }
5489
5490 cvs_handle = voice_get_cvs_handle(v);
5491
5492 if (v->rec_info.recording) {
5493 cvs_stop_record.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
5494 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
5495 cvs_stop_record.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
5496 sizeof(cvs_stop_record) - APR_HDR_SIZE);
5497 cvs_stop_record.src_port =
5498 voice_get_idx_for_session(v->session_id);
5499 cvs_stop_record.dest_port = cvs_handle;
5500 cvs_stop_record.token = 0;
5501 cvs_stop_record.opcode = VSS_IRECORD_CMD_STOP;
5502
5503 v->cvs_state = CMD_STATUS_FAIL;
5504 v->async_err = 0;
5505
5506 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_stop_record);
5507 if (ret < 0) {
5508 pr_err("%s: Error %d sending STOP_RECORD\n",
5509 __func__, ret);
5510
5511 goto fail;
5512 }
5513
5514 ret = wait_event_timeout(v->cvs_wait,
5515 (v->cvs_state == CMD_STATUS_SUCCESS),
5516 msecs_to_jiffies(TIMEOUT_MS));
5517 if (!ret) {
5518 pr_err("%s: wait_event timeout\n", __func__);
5519
5520 goto fail;
5521 }
5522 if (v->async_err > 0) {
5523 pr_err("%s: DSP returned error[%s]\n",
5524 __func__, adsp_err_get_err_str(
5525 v->async_err));
5526 ret = adsp_err_get_lnx_err_code(
5527 v->async_err);
5528 goto fail;
5529 }
5530 v->rec_info.recording = 0;
5531 } else {
5532 pr_debug("%s: Stop record already sent\n", __func__);
5533 }
5534
5535 return 0;
5536
5537fail:
5538 return ret;
5539}
5540
5541int voc_start_record(uint32_t port_id, uint32_t set, uint32_t session_id)
5542{
5543 int ret = 0;
5544 int rec_mode = 0;
5545 u16 cvs_handle;
5546 int rec_set = 0;
5547 struct voice_session_itr itr;
5548 struct voice_data *v = NULL;
5549
5550 /* check if session_id is valid */
5551 if (!voice_is_valid_session_id(session_id)) {
5552 pr_err("%s: Invalid session id:%u\n", __func__,
5553 session_id);
5554
5555 return -EINVAL;
5556 }
5557
5558 voice_itr_init(&itr, session_id);
5559 pr_debug("%s: session_id:%u\n", __func__, session_id);
5560
5561 while (voice_itr_get_next_session(&itr, &v)) {
5562 if (v == NULL) {
5563 pr_err("%s: v is NULL, sessionid:%u\n", __func__,
5564 session_id);
5565
5566 break;
5567 }
5568 pr_debug("%s: port_id: %d, set: %d, v: %pK\n",
5569 __func__, port_id, set, v);
5570
5571 mutex_lock(&v->lock);
5572 rec_mode = v->rec_info.rec_mode;
5573 rec_set = set;
5574 if (set) {
5575 if ((v->rec_route_state.ul_flag != 0) &&
5576 (v->rec_route_state.dl_flag != 0)) {
5577 pr_debug("%s: rec mode already set.\n",
5578 __func__);
5579
5580 mutex_unlock(&v->lock);
5581 continue;
5582 }
5583
5584 if (port_id == VOICE_RECORD_TX) {
5585 if ((v->rec_route_state.ul_flag == 0)
5586 && (v->rec_route_state.dl_flag == 0)) {
5587 rec_mode = VOC_REC_UPLINK;
5588 v->rec_route_state.ul_flag = 1;
5589 } else if ((v->rec_route_state.ul_flag == 0)
5590 && (v->rec_route_state.dl_flag != 0)) {
5591 voice_cvs_stop_record(v);
5592 rec_mode = VOC_REC_BOTH;
5593 v->rec_route_state.ul_flag = 1;
5594 }
5595 } else if (port_id == VOICE_RECORD_RX) {
5596 if ((v->rec_route_state.ul_flag == 0)
5597 && (v->rec_route_state.dl_flag == 0)) {
5598 rec_mode = VOC_REC_DOWNLINK;
5599 v->rec_route_state.dl_flag = 1;
5600 } else if ((v->rec_route_state.ul_flag != 0)
5601 && (v->rec_route_state.dl_flag == 0)) {
5602 voice_cvs_stop_record(v);
5603 rec_mode = VOC_REC_BOTH;
5604 v->rec_route_state.dl_flag = 1;
5605 }
5606 }
5607 rec_set = 1;
5608 } else {
5609 if ((v->rec_route_state.ul_flag == 0) &&
5610 (v->rec_route_state.dl_flag == 0)) {
5611 pr_debug("%s: rec already stops.\n",
5612 __func__);
5613 mutex_unlock(&v->lock);
5614 continue;
5615 }
5616
5617 if (port_id == VOICE_RECORD_TX) {
5618 if ((v->rec_route_state.ul_flag != 0)
5619 && (v->rec_route_state.dl_flag == 0)) {
5620 v->rec_route_state.ul_flag = 0;
5621 rec_set = 0;
5622 } else if ((v->rec_route_state.ul_flag != 0)
5623 && (v->rec_route_state.dl_flag != 0)) {
5624 voice_cvs_stop_record(v);
5625 v->rec_route_state.ul_flag = 0;
5626 rec_mode = VOC_REC_DOWNLINK;
5627 rec_set = 1;
5628 }
5629 } else if (port_id == VOICE_RECORD_RX) {
5630 if ((v->rec_route_state.ul_flag == 0)
5631 && (v->rec_route_state.dl_flag != 0)) {
5632 v->rec_route_state.dl_flag = 0;
5633 rec_set = 0;
5634 } else if ((v->rec_route_state.ul_flag != 0)
5635 && (v->rec_route_state.dl_flag != 0)) {
5636 voice_cvs_stop_record(v);
5637 v->rec_route_state.dl_flag = 0;
5638 rec_mode = VOC_REC_UPLINK;
5639 rec_set = 1;
5640 }
5641 }
5642 }
5643 pr_debug("%s: mode =%d, set =%d\n", __func__,
5644 rec_mode, rec_set);
5645 cvs_handle = voice_get_cvs_handle(v);
5646
5647 if (cvs_handle != 0) {
5648 if (rec_set)
5649 ret = voice_cvs_start_record(v, rec_mode);
5650 else
5651 ret = voice_cvs_stop_record(v);
5652 }
5653
5654 /* During SRVCC, recording will switch from VoLTE session to
5655 * voice session.
5656 * Then stop recording, need to stop recording on voice session.
5657 */
5658 if ((!rec_set) && common.srvcc_rec_flag) {
5659 pr_debug("%s, srvcc_rec_flag:%d\n", __func__,
5660 common.srvcc_rec_flag);
5661
5662 voice_cvs_stop_record(&common.voice[VOC_PATH_PASSIVE]);
5663 common.srvcc_rec_flag = false;
5664 }
5665
5666 /* Cache the value */
5667 v->rec_info.rec_enable = rec_set;
5668 v->rec_info.rec_mode = rec_mode;
5669
5670 mutex_unlock(&v->lock);
5671 }
5672
5673 return ret;
5674}
5675
5676static int voice_cvs_start_playback(struct voice_data *v)
5677{
5678 int ret = 0;
5679 struct cvs_start_playback_cmd cvs_start_playback;
5680 void *apr_cvs;
5681 u16 cvs_handle;
5682
5683 if (v == NULL) {
5684 pr_err("%s: v is NULL\n", __func__);
5685 return -EINVAL;
5686 }
5687 apr_cvs = common.apr_q6_cvs;
5688
5689 if (!apr_cvs) {
5690 pr_err("%s: apr_cvs is NULL.\n", __func__);
5691 return -EINVAL;
5692 }
5693
5694 cvs_handle = voice_get_cvs_handle(v);
5695
5696 if (!v->music_info.playing && v->music_info.count) {
5697 cvs_start_playback.hdr.hdr_field = APR_HDR_FIELD(
5698 APR_MSG_TYPE_SEQ_CMD,
5699 APR_HDR_LEN(APR_HDR_SIZE),
5700 APR_PKT_VER);
5701 cvs_start_playback.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
5702 sizeof(cvs_start_playback) - APR_HDR_SIZE);
5703 cvs_start_playback.hdr.src_port =
5704 voice_get_idx_for_session(v->session_id);
5705 cvs_start_playback.hdr.dest_port = cvs_handle;
5706 cvs_start_playback.hdr.token = 0;
5707 cvs_start_playback.hdr.opcode = VSS_IPLAYBACK_CMD_START;
5708 cvs_start_playback.playback_mode.port_id =
5709 v->music_info.port_id;
5710
5711 v->cvs_state = CMD_STATUS_FAIL;
5712 v->async_err = 0;
5713
5714 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_start_playback);
5715
5716 if (ret < 0) {
5717 pr_err("%s: Error %d sending START_PLAYBACK\n",
5718 __func__, ret);
5719
5720 goto fail;
5721 }
5722
5723 ret = wait_event_timeout(v->cvs_wait,
5724 (v->cvs_state == CMD_STATUS_SUCCESS),
5725 msecs_to_jiffies(TIMEOUT_MS));
5726 if (!ret) {
5727 pr_err("%s: wait_event timeout\n", __func__);
5728
5729 goto fail;
5730 }
5731 if (v->async_err > 0) {
5732 pr_err("%s: DSP returned error[%s]\n",
5733 __func__, adsp_err_get_err_str(
5734 v->async_err));
5735 ret = adsp_err_get_lnx_err_code(
5736 v->async_err);
5737 goto fail;
5738 }
5739
5740 v->music_info.playing = 1;
5741 } else {
5742 pr_debug("%s: Start playback already sent\n", __func__);
5743 }
5744
5745 return 0;
5746
5747fail:
5748 return ret;
5749}
5750
5751static int voice_cvs_stop_playback(struct voice_data *v)
5752{
5753 int ret = 0;
5754 struct apr_hdr cvs_stop_playback;
5755 void *apr_cvs;
5756 u16 cvs_handle;
5757
5758 if (v == NULL) {
5759 pr_err("%s: v is NULL\n", __func__);
5760 return -EINVAL;
5761 }
5762 apr_cvs = common.apr_q6_cvs;
5763
5764 if (!apr_cvs) {
5765 pr_err("%s: apr_cvs is NULL.\n", __func__);
5766 return -EINVAL;
5767 }
5768
5769 cvs_handle = voice_get_cvs_handle(v);
5770
5771 if (v->music_info.playing && ((!v->music_info.count) ||
5772 (v->music_info.force))) {
5773 cvs_stop_playback.hdr_field =
5774 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
5775 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
5776 cvs_stop_playback.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
5777 sizeof(cvs_stop_playback) - APR_HDR_SIZE);
5778 cvs_stop_playback.src_port =
5779 voice_get_idx_for_session(v->session_id);
5780 cvs_stop_playback.dest_port = cvs_handle;
5781 cvs_stop_playback.token = 0;
5782
5783 cvs_stop_playback.opcode = VSS_IPLAYBACK_CMD_STOP;
5784
5785 v->cvs_state = CMD_STATUS_FAIL;
5786 v->async_err = 0;
5787
5788 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_stop_playback);
5789 if (ret < 0) {
5790 pr_err("%s: Error %d sending STOP_PLAYBACK\n",
5791 __func__, ret);
5792
5793
5794 goto fail;
5795 }
5796
5797 ret = wait_event_timeout(v->cvs_wait,
5798 (v->cvs_state == CMD_STATUS_SUCCESS),
5799 msecs_to_jiffies(TIMEOUT_MS));
5800 if (!ret) {
5801 pr_err("%s: wait_event timeout\n", __func__);
5802
5803 goto fail;
5804 }
5805 if (v->async_err > 0) {
5806 pr_err("%s: DSP returned error[%s]\n",
5807 __func__, adsp_err_get_err_str(
5808 v->async_err));
5809 ret = adsp_err_get_lnx_err_code(
5810 v->async_err);
5811 goto fail;
5812 }
5813
5814 v->music_info.playing = 0;
5815 v->music_info.force = 0;
5816 } else {
5817 pr_debug("%s: Stop playback already sent\n", __func__);
5818 }
5819
5820 return 0;
5821
5822fail:
5823 return ret;
5824}
5825
5826static int voc_lch_ops(struct voice_data *v, enum voice_lch_mode lch_mode)
5827{
5828 int ret = 0;
5829
5830 if (v == NULL) {
5831 pr_err("%s: v is NULL\n", __func__);
5832
5833 ret = -EINVAL;
5834 goto done;
5835 }
5836
5837 switch (lch_mode) {
5838 case VOICE_LCH_START:
5839
5840 ret = voc_end_voice_call(v->session_id);
5841 if (ret < 0)
5842 pr_err("%s: voice call end failed %d\n",
5843 __func__, ret);
5844 break;
5845 case VOICE_LCH_STOP:
5846
5847 ret = voc_start_voice_call(v->session_id);
5848 if (ret < 0) {
5849 pr_err("%s: voice call start failed %d\n",
5850 __func__, ret);
5851 goto done;
5852 }
5853 break;
5854 default:
5855 pr_err("%s: Invalid LCH mode: %d\n",
5856 __func__, v->lch_mode);
5857 break;
5858 }
5859done:
5860 return ret;
5861}
5862
5863int voc_start_playback(uint32_t set, uint16_t port_id)
5864{
5865 struct voice_data *v = NULL;
5866 int ret = 0;
5867 struct voice_session_itr itr;
5868 u16 cvs_handle;
5869
5870 pr_debug("%s port_id = %#x set = %d", __func__, port_id, set);
5871
5872 voice_itr_init(&itr, ALL_SESSION_VSID);
5873 while (voice_itr_get_next_session(&itr, &v)) {
5874 if ((v != NULL) &&
5875 (((port_id == VOICE_PLAYBACK_TX) &&
5876 is_sub1_vsid(v->session_id)) ||
5877 ((port_id == VOICE2_PLAYBACK_TX) &&
5878 is_sub2_vsid(v->session_id)))) {
5879
5880 mutex_lock(&v->lock);
5881 v->music_info.port_id = port_id;
5882 v->music_info.play_enable = set;
5883 if (set)
5884 v->music_info.count++;
5885 else
5886 v->music_info.count--;
5887 pr_debug("%s: music_info count=%d\n", __func__,
5888 v->music_info.count);
5889
5890 cvs_handle = voice_get_cvs_handle(v);
5891 if (cvs_handle != 0) {
5892 if (set)
5893 ret = voice_cvs_start_playback(v);
5894 else
5895 ret = voice_cvs_stop_playback(v);
5896 }
5897 mutex_unlock(&v->lock);
5898 } else {
5899 pr_err("%s: Invalid session\n", __func__);
5900 }
5901 }
5902
5903 return ret;
5904}
5905
5906int voc_disable_topology(uint32_t session_id, uint32_t disable)
5907{
5908 struct voice_data *v = voice_get_session(session_id);
5909 int ret = 0;
5910
5911 if (v == NULL) {
5912 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
5913
5914 return -EINVAL;
5915 }
5916
5917 mutex_lock(&v->lock);
5918
5919 v->disable_topology = disable;
5920
5921 mutex_unlock(&v->lock);
5922
5923 return ret;
5924}
5925
5926static int voice_set_packet_exchange_mode_and_config(uint32_t session_id,
5927 uint32_t mode)
5928{
5929 struct voice_data *v = voice_get_session(session_id);
5930 int ret = 0;
5931
5932 if (v == NULL) {
5933 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
5934 return -EINVAL;
5935 }
5936
5937 if (v->voc_state != VOC_RUN)
5938 ret = voice_send_cvs_data_exchange_mode_cmd(v);
5939
5940 if (ret) {
5941 pr_err("%s: Error voice_send_data_exchange_mode_cmd %d\n",
5942 __func__, ret);
5943 goto fail;
5944 }
5945
5946 ret = voice_send_cvs_packet_exchange_config_cmd(v);
5947 if (ret) {
5948 pr_err("%s: Error: voice_send_packet_exchange_config_cmd %d\n",
5949 __func__, ret);
5950 goto fail;
5951 }
5952
5953 return ret;
5954fail:
5955 return -EINVAL;
5956}
5957
5958int voc_set_tx_mute(uint32_t session_id, uint32_t dir, uint32_t mute,
5959 uint32_t ramp_duration)
5960{
5961 struct voice_data *v = NULL;
5962 int ret = 0;
5963 struct voice_session_itr itr;
5964
5965 voice_itr_init(&itr, session_id);
5966 while (voice_itr_get_next_session(&itr, &v)) {
5967 if (v != NULL) {
5968 mutex_lock(&v->lock);
5969 v->stream_tx.stream_mute = mute;
5970 v->stream_tx.stream_mute_ramp_duration_ms =
5971 ramp_duration;
5972 if (is_voc_state_active(v->voc_state) &&
5973 (v->lch_mode == 0))
5974 ret = voice_send_stream_mute_cmd(v,
5975 VSS_IVOLUME_DIRECTION_TX,
5976 v->stream_tx.stream_mute,
5977 v->stream_tx.stream_mute_ramp_duration_ms);
5978 mutex_unlock(&v->lock);
5979 } else {
5980 pr_err("%s: invalid session_id 0x%x\n", __func__,
5981 session_id);
5982
5983 ret = -EINVAL;
5984 break;
5985 }
5986 }
5987
5988 return ret;
5989}
5990
5991int voc_set_device_mute(uint32_t session_id, uint32_t dir, uint32_t mute,
5992 uint32_t ramp_duration)
5993{
5994 struct voice_data *v = NULL;
5995 int ret = 0;
5996 struct voice_session_itr itr;
5997
5998 voice_itr_init(&itr, session_id);
5999 while (voice_itr_get_next_session(&itr, &v)) {
6000 if (v != NULL) {
6001 mutex_lock(&v->lock);
6002 if (dir == VSS_IVOLUME_DIRECTION_TX) {
6003 v->dev_tx.dev_mute = mute;
6004 v->dev_tx.dev_mute_ramp_duration_ms =
6005 ramp_duration;
6006 } else {
6007 v->dev_rx.dev_mute = mute;
6008 v->dev_rx.dev_mute_ramp_duration_ms =
6009 ramp_duration;
6010 }
6011
6012 if (((v->voc_state == VOC_RUN) ||
6013 (v->voc_state == VOC_STANDBY)) &&
6014 (v->lch_mode == 0))
6015 ret = voice_send_device_mute_cmd(v,
6016 dir,
6017 mute,
6018 ramp_duration);
6019 mutex_unlock(&v->lock);
6020 } else {
6021 pr_err("%s: invalid session_id 0x%x\n", __func__,
6022 session_id);
6023
6024 ret = -EINVAL;
6025 break;
6026 }
6027 }
6028
6029 return ret;
6030}
6031
6032int voc_get_rx_device_mute(uint32_t session_id)
6033{
6034 struct voice_data *v = voice_get_session(session_id);
6035 int ret = 0;
6036
6037 if (v == NULL) {
6038 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
6039
6040 return -EINVAL;
6041 }
6042
6043 mutex_lock(&v->lock);
6044
6045 ret = v->dev_rx.dev_mute;
6046
6047 mutex_unlock(&v->lock);
6048
6049 return ret;
6050}
6051
6052int voc_set_tty_mode(uint32_t session_id, uint8_t tty_mode)
6053{
6054 struct voice_data *v = voice_get_session(session_id);
6055 int ret = 0;
6056
6057 if (v == NULL) {
6058 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
6059
6060 return -EINVAL;
6061 }
6062
6063 mutex_lock(&v->lock);
6064
6065 v->tty_mode = tty_mode;
6066
6067 mutex_unlock(&v->lock);
6068
6069 return ret;
6070}
6071
6072uint8_t voc_get_tty_mode(uint32_t session_id)
6073{
6074 struct voice_data *v = voice_get_session(session_id);
6075 int ret = 0;
6076
6077 if (v == NULL) {
6078 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
6079
6080 return -EINVAL;
6081 }
6082
6083 mutex_lock(&v->lock);
6084
6085 ret = v->tty_mode;
6086
6087 mutex_unlock(&v->lock);
6088
6089 return ret;
6090}
6091
6092int voc_set_pp_enable(uint32_t session_id, uint32_t module_id, uint32_t enable)
6093{
6094 struct voice_data *v = NULL;
6095 int ret = 0;
6096 struct voice_session_itr itr;
6097
6098 voice_itr_init(&itr, session_id);
6099 while (voice_itr_get_next_session(&itr, &v)) {
6100 if (v != NULL) {
6101 if (!(is_voice_app_id(v->session_id)))
6102 continue;
6103
6104 mutex_lock(&v->lock);
6105 if (module_id == MODULE_ID_VOICE_MODULE_ST)
6106 v->st_enable = enable;
6107
6108 if (v->voc_state == VOC_RUN) {
6109 if ((module_id == MODULE_ID_VOICE_MODULE_ST) &&
6110 (!v->tty_mode))
6111 ret = voice_send_set_pp_enable_cmd(v,
6112 MODULE_ID_VOICE_MODULE_ST,
6113 enable);
6114 }
6115 mutex_unlock(&v->lock);
6116 } else {
6117 pr_err("%s: invalid session_id 0x%x\n", __func__,
6118 session_id);
6119 ret = -EINVAL;
6120 break;
6121 }
6122 }
6123
6124 return ret;
6125}
6126
6127int voc_set_hd_enable(uint32_t session_id, uint32_t enable)
6128{
6129 struct voice_data *v = NULL;
6130 int ret = 0;
6131 struct voice_session_itr itr;
6132
6133 voice_itr_init(&itr, session_id);
6134 while (voice_itr_get_next_session(&itr, &v)) {
6135 if (v != NULL) {
6136 mutex_lock(&v->lock);
6137 v->hd_enable = enable;
6138
6139 if (v->voc_state == VOC_RUN)
6140 ret = voice_send_hd_cmd(v, enable);
6141
6142 mutex_unlock(&v->lock);
6143 } else {
6144 pr_err("%s: invalid session_id 0x%x\n", __func__,
6145 session_id);
6146 ret = -EINVAL;
6147 break;
6148 }
6149 }
6150
6151 return ret;
6152}
6153
6154int voc_set_afe_sidetone(uint32_t session_id, bool sidetone_enable)
6155{
6156 struct voice_data *v = NULL;
6157 int ret = -EINVAL;
6158 struct voice_session_itr itr;
6159 u16 rx_port, tx_port;
6160
6161 common.sidetone_enable = sidetone_enable;
6162 voice_itr_init(&itr, session_id);
6163 while (voice_itr_get_next_session(&itr, &v)) {
6164 if (v == NULL) {
6165 pr_err("%s: invalid session_id 0x%x\n", __func__,
6166 session_id);
6167 ret = -EINVAL;
6168 break;
6169 }
6170 mutex_lock(&v->lock);
6171 if (v->voc_state != VOC_RUN) {
6172 mutex_unlock(&v->lock);
6173 continue;
6174 }
6175 rx_port = v->dev_rx.port_id;
6176 tx_port = v->dev_tx.port_id;
6177 ret = afe_sidetone_enable(tx_port, rx_port,
6178 sidetone_enable);
6179 if (!ret) {
6180 mutex_unlock(&v->lock);
6181 break;
6182 }
6183 mutex_unlock(&v->lock);
6184 }
6185 return ret;
6186}
6187
6188bool voc_get_afe_sidetone(void)
6189{
6190 bool ret;
6191
6192 ret = common.sidetone_enable;
6193 return ret;
6194}
6195
6196int voc_get_pp_enable(uint32_t session_id, uint32_t module_id)
6197{
6198 struct voice_data *v = voice_get_session(session_id);
6199 int ret = 0;
6200
6201 if (v == NULL) {
6202 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
6203
6204 return -EINVAL;
6205 }
6206
6207 mutex_lock(&v->lock);
6208 if (module_id == MODULE_ID_VOICE_MODULE_ST)
6209 ret = v->st_enable;
6210 mutex_unlock(&v->lock);
6211
6212 return ret;
6213}
6214
6215int voc_set_rx_vol_step(uint32_t session_id, uint32_t dir, uint32_t vol_step,
6216 uint32_t ramp_duration)
6217{
6218 struct voice_data *v = NULL;
6219 int ret = 0;
6220 struct voice_session_itr itr;
6221
6222 pr_debug("%s session id = %#x vol = %u", __func__, session_id,
6223 vol_step);
6224
6225 voice_itr_init(&itr, session_id);
6226 while (voice_itr_get_next_session(&itr, &v)) {
6227 if (v != NULL) {
6228 mutex_lock(&v->lock);
6229 v->dev_rx.volume_step_value = vol_step;
6230 v->dev_rx.volume_ramp_duration_ms = ramp_duration;
6231 if (is_voc_state_active(v->voc_state))
6232 ret = voice_send_vol_step_cmd(v);
6233 mutex_unlock(&v->lock);
6234 } else {
6235 pr_err("%s: invalid session_id 0x%x\n", __func__,
6236 session_id);
6237
6238 ret = -EINVAL;
6239 break;
6240 }
6241 }
6242
6243 return ret;
6244}
6245
6246int voc_set_device_config(uint32_t session_id, uint8_t path_dir,
6247 struct media_format_info *finfo)
6248{
6249 struct voice_data *v = voice_get_session(session_id);
6250
6251 if (v == NULL) {
6252 pr_err("%s: Invalid session_id 0x%x\n", __func__, session_id);
6253
6254 return -EINVAL;
6255 }
6256
6257 pr_debug("%s: path_dir=%d port_id=%x, channels=%d, sample_rate=%d, bits_per_sample=%d\n",
6258 __func__, path_dir, finfo->port_id, finfo->num_channels,
6259 finfo->sample_rate, finfo->bits_per_sample);
6260
6261 mutex_lock(&v->lock);
6262 switch (path_dir) {
6263 case RX_PATH:
6264 v->dev_rx.port_id = q6audio_get_port_id(finfo->port_id);
6265 v->dev_rx.no_of_channels = finfo->num_channels;
6266 v->dev_rx.sample_rate = finfo->sample_rate;
6267 v->dev_rx.bits_per_sample = finfo->bits_per_sample;
6268 memcpy(&v->dev_rx.channel_mapping, &finfo->channel_mapping,
6269 VSS_CHANNEL_MAPPING_SIZE);
6270 break;
6271 case TX_PATH:
6272 v->dev_tx.port_id = q6audio_get_port_id(finfo->port_id);
6273 v->dev_tx.no_of_channels = finfo->num_channels;
6274 v->dev_tx.sample_rate = finfo->sample_rate;
6275 v->dev_tx.bits_per_sample = finfo->bits_per_sample;
6276 memcpy(&v->dev_tx.channel_mapping, &finfo->channel_mapping,
6277 VSS_CHANNEL_MAPPING_SIZE);
6278 break;
6279 default:
6280 pr_err("%s: Invalid path_dir %d\n", __func__, path_dir);
6281 return -EINVAL;
6282 }
6283
6284 mutex_unlock(&v->lock);
6285
6286 return 0;
6287}
6288
6289int voc_set_ext_ec_ref_media_fmt_info(struct media_format_info *finfo)
6290{
6291 mutex_lock(&common.common_lock);
6292 if (common.ec_ref_ext) {
6293 common.ec_media_fmt_info.num_channels = finfo->num_channels;
6294 common.ec_media_fmt_info.bits_per_sample =
6295 finfo->bits_per_sample;
6296 common.ec_media_fmt_info.sample_rate = finfo->sample_rate;
6297 memcpy(&common.ec_media_fmt_info.channel_mapping,
6298 &finfo->channel_mapping, VSS_CHANNEL_MAPPING_SIZE);
6299 } else {
6300 pr_debug("%s: Ext Ec Ref not active, returning", __func__);
6301 }
6302 mutex_unlock(&common.common_lock);
6303 return 0;
6304}
6305
6306int voc_set_route_flag(uint32_t session_id, uint8_t path_dir, uint8_t set)
6307{
6308 struct voice_data *v = voice_get_session(session_id);
6309
6310 if (v == NULL) {
6311 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
6312
6313 return -EINVAL;
6314 }
6315
6316 pr_debug("%s: path_dir=%d, set=%d\n", __func__, path_dir, set);
6317
6318 mutex_lock(&v->lock);
6319
6320 if (path_dir == RX_PATH)
6321 v->voc_route_state.rx_route_flag = set;
6322 else
6323 v->voc_route_state.tx_route_flag = set;
6324
6325 mutex_unlock(&v->lock);
6326
6327 return 0;
6328}
6329
6330uint8_t voc_get_route_flag(uint32_t session_id, uint8_t path_dir)
6331{
6332 struct voice_data *v = voice_get_session(session_id);
6333 int ret = 0;
6334
6335 if (v == NULL) {
6336 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
6337
6338 return 0;
6339 }
6340
6341 mutex_lock(&v->lock);
6342
6343 if (path_dir == RX_PATH)
6344 ret = v->voc_route_state.rx_route_flag;
6345 else
6346 ret = v->voc_route_state.tx_route_flag;
6347
6348 mutex_unlock(&v->lock);
6349
6350 return ret;
6351}
6352
6353int voc_end_voice_call(uint32_t session_id)
6354{
6355 struct voice_data *v = voice_get_session(session_id);
6356 int ret = 0;
6357
6358 if (v == NULL) {
6359 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
6360
6361 return -EINVAL;
6362 }
6363
6364 mutex_lock(&v->lock);
6365
6366 if (v->voc_state == VOC_RUN || v->voc_state == VOC_ERROR ||
6367 v->voc_state == VOC_CHANGE || v->voc_state == VOC_STANDBY) {
6368
6369 pr_debug("%s: VOC_STATE: %d\n", __func__, v->voc_state);
6370
6371 ret = voice_destroy_vocproc(v);
6372 if (ret < 0)
6373 pr_err("%s: destroy voice failed\n", __func__);
6374
6375 voc_update_session_params(v);
6376
6377 voice_destroy_mvm_cvs_session(v);
6378 v->voc_state = VOC_RELEASE;
6379 } else {
6380 pr_err("%s: Error: End voice called in state %d\n",
6381 __func__, v->voc_state);
6382
6383 ret = -EINVAL;
6384 }
6385
6386 mutex_unlock(&v->lock);
6387 return ret;
6388}
6389
6390int voc_standby_voice_call(uint32_t session_id)
6391{
6392 struct voice_data *v = voice_get_session(session_id);
6393 struct apr_hdr mvm_standby_voice_cmd;
6394 void *apr_mvm;
6395 u16 mvm_handle;
6396 int ret = 0;
6397
6398 if (v == NULL) {
6399 pr_err("%s: v is NULL\n", __func__);
6400 return -EINVAL;
6401 }
6402 pr_debug("%s: voc state=%d", __func__, v->voc_state);
6403
6404 if (v->voc_state == VOC_RUN) {
6405 apr_mvm = common.apr_q6_mvm;
6406 if (!apr_mvm) {
6407 pr_err("%s: apr_mvm is NULL.\n", __func__);
6408 ret = -EINVAL;
6409 goto fail;
6410 }
6411 mvm_handle = voice_get_mvm_handle(v);
6412 mvm_standby_voice_cmd.hdr_field =
6413 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
6414 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
6415 mvm_standby_voice_cmd.pkt_size =
6416 APR_PKT_SIZE(APR_HDR_SIZE,
6417 sizeof(mvm_standby_voice_cmd) - APR_HDR_SIZE);
6418 pr_debug("send mvm_standby_voice_cmd pkt size = %d\n",
6419 mvm_standby_voice_cmd.pkt_size);
6420 mvm_standby_voice_cmd.src_port =
6421 voice_get_idx_for_session(v->session_id);
6422 mvm_standby_voice_cmd.dest_port = mvm_handle;
6423 mvm_standby_voice_cmd.token = 0;
6424 mvm_standby_voice_cmd.opcode = VSS_IMVM_CMD_STANDBY_VOICE;
6425 v->mvm_state = CMD_STATUS_FAIL;
6426 ret = apr_send_pkt(apr_mvm,
6427 (uint32_t *)&mvm_standby_voice_cmd);
6428 if (ret < 0) {
6429 pr_err("Fail in sending VSS_IMVM_CMD_STANDBY_VOICE\n");
6430 ret = -EINVAL;
6431 goto fail;
6432 }
6433 v->voc_state = VOC_STANDBY;
6434 }
6435fail:
6436 return ret;
6437}
6438
6439int voc_disable_device(uint32_t session_id)
6440{
6441 struct voice_data *v = voice_get_session(session_id);
6442 int ret = 0;
6443
6444 if (v == NULL) {
6445 pr_err("%s: v is NULL\n", __func__);
6446 return -EINVAL;
6447 }
6448
6449 pr_debug("%s: voc state=%d\n", __func__, v->voc_state);
6450
6451 mutex_lock(&v->lock);
6452 if (v->voc_state == VOC_RUN) {
6453 ret = voice_pause_voice_call(v);
6454 if (ret < 0) {
6455 pr_err("%s: Pause Voice Call failed for session 0x%x, err %d!\n",
6456 __func__, v->session_id, ret);
6457 goto done;
6458 }
6459 rtac_remove_voice(voice_get_cvs_handle(v));
6460 voice_send_cvp_deregister_vol_cal_cmd(v);
6461 voice_send_cvp_deregister_cal_cmd(v);
6462 voice_send_cvp_deregister_dev_cfg_cmd(v);
6463
6464 v->voc_state = VOC_CHANGE;
6465 } else {
6466 pr_debug("%s: called in voc state=%d, No_OP\n",
6467 __func__, v->voc_state);
6468 }
6469
6470done:
6471 mutex_unlock(&v->lock);
6472
6473 return ret;
6474}
6475
6476int voc_enable_device(uint32_t session_id)
6477{
6478 struct voice_data *v = voice_get_session(session_id);
6479 int ret = 0;
6480
6481 if (v == NULL) {
6482 pr_err("%s: v is NULL\n", __func__);
6483 return -EINVAL;
6484 }
6485
6486 pr_debug("%s: voc state=%d\n", __func__, v->voc_state);
6487 mutex_lock(&v->lock);
6488 if (v->voc_state == VOC_CHANGE) {
6489 ret = voice_send_tty_mode_cmd(v);
6490 if (ret < 0) {
6491 pr_err("%s: Sending TTY mode failed, ret=%d\n",
6492 __func__, ret);
6493 /* Not a critical error, allow voice call to continue */
6494 }
6495
6496 if (v->tty_mode) {
6497 /* disable slowtalk */
6498 voice_send_set_pp_enable_cmd(v,
6499 MODULE_ID_VOICE_MODULE_ST,
6500 0);
6501 } else {
6502 /* restore slowtalk */
6503 voice_send_set_pp_enable_cmd(v,
6504 MODULE_ID_VOICE_MODULE_ST,
6505 v->st_enable);
6506 }
6507
6508 ret = voice_send_set_device_cmd(v);
6509 if (ret < 0) {
6510 pr_err("%s: Set device failed, ret=%d\n",
6511 __func__, ret);
6512 goto done;
6513 }
6514
6515 ret = voice_send_cvp_media_fmt_info_cmd(v);
6516 if (ret < 0) {
6517 pr_err("%s: Set format failed err:%d\n", __func__, ret);
6518 goto done;
6519 }
6520
6521 ret = voice_send_cvp_topology_commit_cmd(v);
6522 if (ret < 0) {
6523 pr_err("%s: Set topology commit failed\n", __func__);
6524 goto done;
6525 }
6526
Laxminath Kasam38070be2017-08-17 18:21:59 +05306527 /* Send MFC config only when the no of channels are > 1 */
6528 if (v->dev_rx.no_of_channels > NUM_CHANNELS_MONO) {
6529 ret = voice_send_cvp_mfc_config_cmd(v);
6530 if (ret < 0) {
6531 pr_warn("%s: Set mfc config failed err: %d\n",
6532 __func__, ret);
6533 }
6534 }
6535
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306536 voice_send_cvp_register_dev_cfg_cmd(v);
6537 voice_send_cvp_register_cal_cmd(v);
6538 voice_send_cvp_register_vol_cal_cmd(v);
6539
6540 rtac_add_voice(voice_get_cvs_handle(v),
6541 voice_get_cvp_handle(v),
6542 v->dev_rx.port_id, v->dev_tx.port_id,
6543 v->dev_rx.dev_id, v->dev_tx.dev_id,
6544 v->session_id);
6545
6546 ret = voice_send_start_voice_cmd(v);
6547 if (ret < 0) {
6548 pr_err("%s: Fail in sending START_VOICE, ret=%d\n",
6549 __func__, ret);
6550 goto done;
6551 }
6552 v->voc_state = VOC_RUN;
6553 } else {
6554 pr_debug("%s: called in voc state=%d, No_OP\n",
6555 __func__, v->voc_state);
6556 }
6557
6558done:
6559 mutex_unlock(&v->lock);
6560
6561 return ret;
6562}
6563
6564int voc_set_lch(uint32_t session_id, enum voice_lch_mode lch_mode)
6565{
6566 struct voice_data *v = voice_get_session(session_id);
6567 int ret = 0;
6568
6569 if (v == NULL) {
6570 pr_err("%s: Invalid session_id 0x%x\n", __func__, session_id);
6571
6572 ret = -EINVAL;
6573 goto done;
6574 }
6575
6576 mutex_lock(&v->lock);
6577 if (v->lch_mode == lch_mode) {
6578 pr_debug("%s: Session %d already in LCH mode %d\n",
6579 __func__, session_id, lch_mode);
6580
6581 mutex_unlock(&v->lock);
6582 goto done;
6583 }
6584
6585 v->lch_mode = lch_mode;
6586 mutex_unlock(&v->lock);
6587
6588 ret = voc_lch_ops(v, v->lch_mode);
6589 if (ret < 0) {
6590 pr_err("%s: lch ops failed %d\n", __func__, ret);
6591 goto done;
6592 }
6593
6594done:
6595 return ret;
6596}
6597
6598int voc_resume_voice_call(uint32_t session_id)
6599{
6600 struct voice_data *v = voice_get_session(session_id);
6601 int ret = 0;
6602
6603 ret = voice_send_start_voice_cmd(v);
6604 if (ret < 0) {
6605 pr_err("Fail in sending START_VOICE\n");
6606 goto fail;
6607 }
6608 v->voc_state = VOC_RUN;
6609 return 0;
6610fail:
6611 return -EINVAL;
6612}
6613
6614int voc_start_voice_call(uint32_t session_id)
6615{
6616 struct voice_data *v = voice_get_session(session_id);
6617 int ret = 0;
6618
6619 if (v == NULL) {
6620 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
6621
6622 return -EINVAL;
6623 }
6624
6625 mutex_lock(&v->lock);
6626
6627 if (v->voc_state == VOC_ERROR) {
6628 pr_debug("%s: VOC in ERR state\n", __func__);
6629
6630 voice_destroy_mvm_cvs_session(v);
6631 v->voc_state = VOC_INIT;
6632 }
6633
6634 if ((v->voc_state == VOC_INIT) ||
6635 (v->voc_state == VOC_RELEASE)) {
6636 ret = voice_apr_register(session_id);
6637 if (ret < 0) {
6638 pr_err("%s: apr register failed\n", __func__);
6639 goto fail;
6640 }
6641
6642 if (is_cvd_version_queried()) {
6643 pr_debug("%s: Returning the cached value %s\n",
6644 __func__, common.cvd_version);
6645 } else {
6646 ret = voice_send_mvm_cvd_version_cmd(v);
6647 if (ret < 0)
6648 pr_debug("%s: Error retrieving CVD version %d\n",
6649 __func__, ret);
6650 }
6651
6652 ret = voice_create_mvm_cvs_session(v);
6653 if (ret < 0) {
6654 pr_err("create mvm and cvs failed\n");
6655 goto fail;
6656 }
6657
6658 if (is_voip_session(session_id)) {
6659 /* Allocate oob mem if not already allocated and
6660 * memory map the oob memory block.
6661 */
6662 ret = voice_alloc_and_map_oob_mem(v);
6663 if (ret < 0) {
6664 pr_err("%s: voice_alloc_and_map_oob_mem() failed, ret:%d\n",
6665 __func__, ret);
6666
6667 goto fail;
6668 }
6669
6670 ret = voice_set_packet_exchange_mode_and_config(
6671 session_id,
6672 VSS_ISTREAM_PACKET_EXCHANGE_MODE_OUT_OF_BAND);
6673 if (ret) {
6674 pr_err("%s: Err: exchange_mode_and_config %d\n",
6675 __func__, ret);
6676
6677 goto fail;
6678 }
6679 }
6680 ret = voice_send_dual_control_cmd(v);
6681 if (ret < 0) {
6682 pr_err("Err Dual command failed\n");
6683 goto fail;
6684 }
6685 ret = voice_setup_vocproc(v);
6686 if (ret < 0) {
6687 pr_err("setup voice failed\n");
6688 goto fail;
6689 }
6690
6691 ret = voice_send_vol_step_cmd(v);
6692 if (ret < 0)
6693 pr_err("voice volume failed\n");
6694
6695 ret = voice_send_stream_mute_cmd(v,
6696 VSS_IVOLUME_DIRECTION_TX,
6697 v->stream_tx.stream_mute,
6698 v->stream_tx.stream_mute_ramp_duration_ms);
6699 if (ret < 0)
6700 pr_err("voice mute failed\n");
6701
6702 ret = voice_send_start_voice_cmd(v);
6703 if (ret < 0) {
6704 pr_err("start voice failed\n");
6705 goto fail;
6706 }
6707
6708 v->voc_state = VOC_RUN;
6709 } else {
6710 pr_err("%s: Error: Start voice called in state %d\n",
6711 __func__, v->voc_state);
6712
6713 ret = -EINVAL;
6714 goto fail;
6715 }
6716fail:
6717 mutex_unlock(&v->lock);
6718 return ret;
6719}
6720
6721int voc_set_ext_ec_ref_port_id(uint16_t port_id, bool state)
6722{
6723 int ret = 0;
6724
6725 mutex_lock(&common.common_lock);
6726 if (state == true) {
6727 if (port_id == AFE_PORT_INVALID) {
6728 pr_err("%s: Invalid port id", __func__);
6729 ret = -EINVAL;
6730 goto exit;
6731 }
6732 common.ec_ref_ext = true;
6733 } else {
6734 common.ec_ref_ext = false;
6735 }
6736 /* Cache EC Fromat Info in common */
6737 common.ec_media_fmt_info.port_id = port_id;
6738exit:
6739 mutex_unlock(&common.common_lock);
6740 return ret;
6741}
6742
6743int voc_get_ext_ec_ref_port_id(void)
6744{
6745 if (common.ec_ref_ext)
6746 return common.ec_media_fmt_info.port_id;
6747 else
6748 return AFE_PORT_INVALID;
6749}
6750
6751void voc_register_mvs_cb(ul_cb_fn ul_cb,
6752 dl_cb_fn dl_cb,
6753 voip_ssr_cb ssr_cb,
6754 void *private_data)
6755{
6756 common.mvs_info.ul_cb = ul_cb;
6757 common.mvs_info.dl_cb = dl_cb;
6758 common.mvs_info.ssr_cb = ssr_cb;
6759 common.mvs_info.private_data = private_data;
6760}
6761
6762void voc_register_dtmf_rx_detection_cb(dtmf_rx_det_cb_fn dtmf_rx_ul_cb,
6763 void *private_data)
6764{
6765 common.dtmf_info.dtmf_rx_ul_cb = dtmf_rx_ul_cb;
6766 common.dtmf_info.private_data = private_data;
6767}
6768
6769void voc_config_vocoder(uint32_t media_type,
6770 uint32_t rate,
6771 uint32_t network_type,
6772 uint32_t dtx_mode,
6773 uint32_t evrc_min_rate,
6774 uint32_t evrc_max_rate)
6775{
6776 common.mvs_info.media_type = media_type;
6777 common.mvs_info.rate = rate;
6778 common.mvs_info.network_type = network_type;
6779 common.mvs_info.dtx_mode = dtx_mode;
6780 common.mvs_info.evrc_min_rate = evrc_min_rate;
6781 common.mvs_info.evrc_max_rate = evrc_max_rate;
6782}
6783
6784static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv)
6785{
6786 uint32_t *ptr = NULL;
6787 struct common_data *c = NULL;
6788 struct voice_data *v = NULL;
6789 int i = 0;
6790 struct vss_iversion_rsp_get_t *version_rsp = NULL;
6791
6792 if ((data == NULL) || (priv == NULL)) {
6793 pr_err("%s: data or priv is NULL\n", __func__);
6794 return -EINVAL;
6795 }
6796
6797 c = priv;
6798
6799 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
6800 data->payload_size, data->opcode);
6801
6802 if (data->opcode == RESET_EVENTS) {
6803 pr_debug("%s: Reset event received in Voice service\n",
6804 __func__);
6805
6806 if (common.mvs_info.ssr_cb) {
6807 pr_debug("%s: Informing reset event to VoIP\n",
6808 __func__);
6809 common.mvs_info.ssr_cb(data->opcode,
6810 common.mvs_info.private_data);
6811 }
6812
6813 apr_reset(c->apr_q6_mvm);
6814 c->apr_q6_mvm = NULL;
6815
6816 /* clean up memory handle */
6817 c->cal_mem_handle = 0;
6818 c->rtac_mem_handle = 0;
6819 cal_utils_clear_cal_block_q6maps(MAX_VOICE_CAL_TYPES,
6820 common.cal_data);
6821 rtac_clear_mapping(VOICE_RTAC_CAL);
6822
6823 /* Sub-system restart is applicable to all sessions. */
6824 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
6825 c->voice[i].mvm_handle = 0;
6826 c->voice[i].shmem_info.mem_handle = 0;
6827 }
6828
6829 /* Free the ION memory and clear handles for Source Tracking */
6830 if (is_source_tracking_shared_memomry_allocated()) {
6831 msm_audio_ion_free(
6832 common.source_tracking_sh_mem.sh_mem_block.client,
6833 common.source_tracking_sh_mem.sh_mem_block.handle);
6834 common.source_tracking_sh_mem.mem_handle = 0;
6835 common.source_tracking_sh_mem.sh_mem_block.client =
6836 NULL;
6837 common.source_tracking_sh_mem.sh_mem_block.handle =
6838 NULL;
6839 }
6840 /* clean up srvcc rec flag */
6841 c->srvcc_rec_flag = false;
6842 voc_set_error_state(data->reset_proc);
6843 return 0;
6844 }
6845
6846 pr_debug("%s: session_idx 0x%x\n", __func__, data->dest_port);
6847
6848 v = voice_get_session_by_idx(data->dest_port);
6849 if (v == NULL) {
6850 pr_err("%s: v is NULL\n", __func__);
6851
6852 return -EINVAL;
6853 }
6854
6855 if (data->opcode == APR_BASIC_RSP_RESULT) {
6856 if (data->payload_size) {
6857 ptr = data->payload;
6858
6859 pr_debug("%x %x\n", ptr[0], ptr[1]);
6860 /* ping mvm service ACK */
6861 switch (ptr[0]) {
6862 case VSS_IMVM_CMD_CREATE_PASSIVE_CONTROL_SESSION:
6863 case VSS_IMVM_CMD_CREATE_FULL_CONTROL_SESSION:
6864 /* Passive session is used for CS call
6865 * Full session is used for VoIP call.
6866 */
6867 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
6868 if (!ptr[1]) {
6869 pr_debug("%s: MVM handle is %d\n",
6870 __func__, data->src_port);
6871 voice_set_mvm_handle(v, data->src_port);
6872 } else
6873 pr_err("got NACK for sending MVM create session\n");
6874 v->mvm_state = CMD_STATUS_SUCCESS;
6875 v->async_err = ptr[1];
6876 wake_up(&v->mvm_wait);
6877 break;
6878 case VSS_IMVM_CMD_START_VOICE:
6879 case VSS_IMVM_CMD_ATTACH_VOCPROC:
6880 case VSS_IMVM_CMD_STOP_VOICE:
6881 case VSS_IMVM_CMD_DETACH_VOCPROC:
6882 case VSS_ISTREAM_CMD_SET_TTY_MODE:
6883 case APRV2_IBASIC_CMD_DESTROY_SESSION:
6884 case VSS_IMVM_CMD_ATTACH_STREAM:
6885 case VSS_IMVM_CMD_DETACH_STREAM:
6886 case VSS_ICOMMON_CMD_SET_NETWORK:
6887 case VSS_ICOMMON_CMD_SET_VOICE_TIMING:
6888 case VSS_IMVM_CMD_SET_POLICY_DUAL_CONTROL:
6889 case VSS_IMVM_CMD_SET_CAL_NETWORK:
6890 case VSS_IMVM_CMD_SET_CAL_MEDIA_TYPE:
6891 case VSS_IMEMORY_CMD_MAP_PHYSICAL:
6892 case VSS_IMEMORY_CMD_UNMAP:
6893 case VSS_IMVM_CMD_PAUSE_VOICE:
6894 case VSS_IMVM_CMD_STANDBY_VOICE:
6895 case VSS_IHDVOICE_CMD_ENABLE:
6896 case VSS_IHDVOICE_CMD_DISABLE:
6897 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
6898 v->mvm_state = CMD_STATUS_SUCCESS;
6899 v->async_err = ptr[1];
6900 wake_up(&v->mvm_wait);
6901 break;
6902 case VSS_IVERSION_CMD_GET:
6903 pr_debug("%s: Error retrieving CVD Version, error:%d\n",
6904 __func__, ptr[1]);
6905
6906 strlcpy(common.cvd_version, CVD_VERSION_0_0,
6907 sizeof(common.cvd_version));
6908 pr_debug("%s: Fall back to default value, CVD Version = %s\n",
6909 __func__, common.cvd_version);
6910
6911 v->mvm_state = CMD_STATUS_SUCCESS;
6912 v->async_err = ptr[1];
6913 wake_up(&v->mvm_wait);
6914 break;
6915 default:
6916 pr_debug("%s: not match cmd = 0x%x\n",
6917 __func__, ptr[0]);
6918 break;
6919 }
6920 }
6921 } else if (data->opcode == VSS_IMEMORY_RSP_MAP) {
6922 pr_debug("%s, Revd VSS_IMEMORY_RSP_MAP response\n", __func__);
6923
6924 if (data->payload_size && data->token == VOIP_MEM_MAP_TOKEN) {
6925 ptr = data->payload;
6926 if (ptr[0]) {
6927 v->shmem_info.mem_handle = ptr[0];
6928 pr_debug("%s: shared mem_handle: 0x[%x]\n",
6929 __func__, v->shmem_info.mem_handle);
6930 v->mvm_state = CMD_STATUS_SUCCESS;
6931 wake_up(&v->mvm_wait);
6932 }
6933 } else if (data->payload_size &&
6934 data->token == VOC_CAL_MEM_MAP_TOKEN) {
6935 ptr = data->payload;
6936 if (ptr[0]) {
6937 c->cal_mem_handle = ptr[0];
6938
6939 pr_debug("%s: cal mem handle 0x%x\n",
6940 __func__, c->cal_mem_handle);
6941
6942 v->mvm_state = CMD_STATUS_SUCCESS;
6943 wake_up(&v->mvm_wait);
6944 }
6945 } else if (data->payload_size &&
6946 data->token == VOC_VOICE_HOST_PCM_MAP_TOKEN) {
6947 ptr = data->payload;
6948 if (ptr[0]) {
6949 common.voice_host_pcm_mem_handle = ptr[0];
6950
6951 pr_debug("%s: vhpcm mem handle 0x%x\n",
6952 __func__,
6953 common.voice_host_pcm_mem_handle);
6954 v->mvm_state = CMD_STATUS_SUCCESS;
6955 wake_up(&v->mvm_wait);
6956 }
6957 } else if (data->payload_size &&
6958 data->token == VOC_RTAC_MEM_MAP_TOKEN) {
6959 ptr = data->payload;
6960 if (ptr[0]) {
6961 c->rtac_mem_handle = ptr[0];
6962
6963 pr_debug("%s: cal mem handle 0x%x\n",
6964 __func__, c->rtac_mem_handle);
6965
6966 v->mvm_state = CMD_STATUS_SUCCESS;
6967 wake_up(&v->mvm_wait);
6968 }
6969 } else if (data->payload_size &&
6970 data->token == VOC_SOURCE_TRACKING_MEM_MAP_TOKEN) {
6971 ptr = data->payload;
6972 if (ptr[0]) {
6973 common.source_tracking_sh_mem.mem_handle =
6974 ptr[0];
6975
6976 pr_debug("%s: Source Tracking shared mem handle 0x%x\n",
6977 __func__,
6978 common.source_tracking_sh_mem.mem_handle);
6979
6980 v->mvm_state = CMD_STATUS_SUCCESS;
6981 wake_up(&v->mvm_wait);
6982 }
6983 } else {
6984 pr_err("%s: Unknown mem map token %d\n",
6985 __func__, data->token);
6986 }
6987 } else if (data->opcode == VSS_IVERSION_RSP_GET) {
6988 pr_debug("%s: Received VSS_IVERSION_RSP_GET\n", __func__);
6989
6990 if (data->payload_size) {
6991 version_rsp =
6992 (struct vss_iversion_rsp_get_t *)data->payload;
6993 memcpy(common.cvd_version, version_rsp->version,
6994 CVD_VERSION_STRING_MAX_SIZE);
6995 pr_debug("%s: CVD Version = %s\n",
6996 __func__, common.cvd_version);
6997
6998 v->mvm_state = CMD_STATUS_SUCCESS;
6999 wake_up(&v->mvm_wait);
7000 }
7001 }
7002 return 0;
7003}
7004
7005static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv)
7006{
7007 uint32_t *ptr = NULL;
7008 struct common_data *c = NULL;
7009 struct voice_data *v = NULL;
7010 int i = 0;
7011
7012 if ((data == NULL) || (priv == NULL)) {
7013 pr_err("%s: data or priv is NULL\n", __func__);
7014 return -EINVAL;
7015 }
7016
7017 c = priv;
7018
7019 pr_debug("%s: session_id 0x%x\n", __func__, data->dest_port);
7020 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
7021 data->payload_size, data->opcode);
7022
7023 if (data->opcode == RESET_EVENTS) {
7024 pr_debug("%s: Reset event received in Voice service\n",
7025 __func__);
7026
7027 apr_reset(c->apr_q6_cvs);
7028 c->apr_q6_cvs = NULL;
7029
7030 /* Sub-system restart is applicable to all sessions. */
7031 for (i = 0; i < MAX_VOC_SESSIONS; i++)
7032 c->voice[i].cvs_handle = 0;
7033
7034 cal_utils_clear_cal_block_q6maps(MAX_VOICE_CAL_TYPES,
7035 common.cal_data);
7036
7037 /* Free the ION memory and clear handles for Source Tracking */
7038 if (is_source_tracking_shared_memomry_allocated()) {
7039 msm_audio_ion_free(
7040 common.source_tracking_sh_mem.sh_mem_block.client,
7041 common.source_tracking_sh_mem.sh_mem_block.handle);
7042 common.source_tracking_sh_mem.mem_handle = 0;
7043 common.source_tracking_sh_mem.sh_mem_block.client =
7044 NULL;
7045 common.source_tracking_sh_mem.sh_mem_block.handle =
7046 NULL;
7047 }
7048 voc_set_error_state(data->reset_proc);
7049 return 0;
7050 }
7051
7052 v = voice_get_session_by_idx(data->dest_port);
7053 if (v == NULL) {
7054 pr_err("%s: v is NULL\n", __func__);
7055
7056 return -EINVAL;
7057 }
7058
7059 if (data->opcode == APR_BASIC_RSP_RESULT) {
7060 if (data->payload_size) {
7061 ptr = data->payload;
7062
7063 pr_debug("%x %x\n", ptr[0], ptr[1]);
7064 if (ptr[1] != 0) {
7065 pr_err("%s: cmd = 0x%x returned error = 0x%x\n",
7066 __func__, ptr[0], ptr[1]);
7067 }
7068 /*response from CVS */
7069 switch (ptr[0]) {
7070 case VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION:
7071 case VSS_ISTREAM_CMD_CREATE_FULL_CONTROL_SESSION:
7072 if (!ptr[1]) {
7073 pr_debug("%s: CVS handle is %d\n",
7074 __func__, data->src_port);
7075 voice_set_cvs_handle(v, data->src_port);
7076 } else
7077 pr_err("got NACK for sending CVS create session\n");
7078 v->cvs_state = CMD_STATUS_SUCCESS;
7079 v->async_err = ptr[1];
7080 wake_up(&v->cvs_wait);
7081 break;
7082 case VSS_IVOLUME_CMD_MUTE_V2:
7083 case VSS_ISTREAM_CMD_SET_MEDIA_TYPE:
7084 case VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE:
7085 case VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE:
7086 case VSS_ISTREAM_CMD_SET_ENC_DTX_MODE:
7087 case VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE:
7088 case APRV2_IBASIC_CMD_DESTROY_SESSION:
7089 case VSS_ISTREAM_CMD_REGISTER_CALIBRATION_DATA_V2:
7090 case VSS_ISTREAM_CMD_DEREGISTER_CALIBRATION_DATA:
7091 case VSS_ISTREAM_CMD_REGISTER_STATIC_CALIBRATION_DATA:
7092 case VSS_ISTREAM_CMD_DEREGISTER_STATIC_CALIBRATION_DATA:
7093 case VSS_ICOMMON_CMD_MAP_MEMORY:
7094 case VSS_ICOMMON_CMD_UNMAP_MEMORY:
7095 case VSS_ICOMMON_CMD_SET_UI_PROPERTY:
7096 case VSS_IPLAYBACK_CMD_START:
7097 case VSS_IPLAYBACK_CMD_STOP:
7098 case VSS_IRECORD_CMD_START:
7099 case VSS_IRECORD_CMD_STOP:
7100 case VSS_ISTREAM_CMD_SET_PACKET_EXCHANGE_MODE:
7101 case VSS_ISTREAM_CMD_SET_OOB_PACKET_EXCHANGE_CONFIG:
7102 case VSS_ISTREAM_CMD_SET_RX_DTMF_DETECTION:
7103 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
7104 v->cvs_state = CMD_STATUS_SUCCESS;
7105 v->async_err = ptr[1];
7106 wake_up(&v->cvs_wait);
7107 break;
7108 case VSS_ICOMMON_CMD_SET_PARAM_V2:
7109 pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM_V2\n",
7110 __func__);
7111 rtac_make_voice_callback(RTAC_CVS, ptr,
7112 data->payload_size);
7113 break;
7114 case VSS_ICOMMON_CMD_GET_PARAM_V2:
7115 pr_debug("%s: VSS_ICOMMON_CMD_GET_PARAM_V2\n",
7116 __func__);
7117 /* Should only come here if there is an APR */
7118 /* error or malformed APR packet. Otherwise */
7119 /* response will be returned as */
7120 /* VSS_ICOMMON_RSP_GET_PARAM */
7121 if (ptr[1] != 0) {
7122 pr_err("%s: CVP get param error = %d, resuming\n",
7123 __func__, ptr[1]);
7124 rtac_make_voice_callback(RTAC_CVP,
7125 data->payload,
7126 data->payload_size);
7127 }
7128 break;
7129 default:
7130 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
7131 break;
7132 }
7133 }
7134 } else if (data->opcode ==
7135 VSS_ISTREAM_EVT_OOB_NOTIFY_ENC_BUFFER_READY) {
7136 int ret = 0;
7137 u16 cvs_handle;
7138 uint32_t *cvs_voc_pkt;
7139 struct cvs_enc_buffer_consumed_cmd send_enc_buf_consumed_cmd;
7140 void *apr_cvs;
7141
7142 pr_debug("Encoder buffer is ready\n");
7143
7144 apr_cvs = common.apr_q6_cvs;
7145 if (!apr_cvs) {
7146 pr_err("%s: apr_cvs is NULL\n", __func__);
7147 return -EINVAL;
7148 }
7149 cvs_handle = voice_get_cvs_handle(v);
7150
7151 send_enc_buf_consumed_cmd.hdr.hdr_field =
7152 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
7153 APR_HDR_LEN(APR_HDR_SIZE),
7154 APR_PKT_VER);
7155 send_enc_buf_consumed_cmd.hdr.pkt_size =
7156 APR_PKT_SIZE(APR_HDR_SIZE,
7157 sizeof(send_enc_buf_consumed_cmd) - APR_HDR_SIZE);
7158
7159 send_enc_buf_consumed_cmd.hdr.src_port =
7160 voice_get_idx_for_session(v->session_id);
7161 send_enc_buf_consumed_cmd.hdr.dest_port = cvs_handle;
7162 send_enc_buf_consumed_cmd.hdr.token = 0;
7163 send_enc_buf_consumed_cmd.hdr.opcode =
7164 VSS_ISTREAM_EVT_OOB_NOTIFY_ENC_BUFFER_CONSUMED;
7165
7166 cvs_voc_pkt = v->shmem_info.sh_buf.buf[1].data;
7167 if (cvs_voc_pkt != NULL && common.mvs_info.ul_cb != NULL) {
7168 /* cvs_voc_pkt[0] contains tx timestamp */
7169 common.mvs_info.ul_cb((uint8_t *)&cvs_voc_pkt[3],
7170 cvs_voc_pkt[2],
7171 cvs_voc_pkt[0],
7172 common.mvs_info.private_data);
7173 } else
7174 pr_err("%s: cvs_voc_pkt or ul_cb is NULL\n", __func__);
7175
7176 ret = apr_send_pkt(apr_cvs,
7177 (uint32_t *) &send_enc_buf_consumed_cmd);
7178 if (ret < 0) {
7179 pr_err("%s: Err send ENC_BUF_CONSUMED_NOTIFY %d\n",
7180 __func__, ret);
7181 goto fail;
7182 }
7183 } else if (data->opcode == VSS_ISTREAM_EVT_SEND_ENC_BUFFER) {
7184 pr_debug("Recd VSS_ISTREAM_EVT_SEND_ENC_BUFFER\n");
7185 } else if (data->opcode ==
7186 VSS_ISTREAM_EVT_OOB_NOTIFY_DEC_BUFFER_REQUEST) {
7187 int ret = 0;
7188 u16 cvs_handle;
7189 uint32_t *cvs_voc_pkt;
7190 struct cvs_dec_buffer_ready_cmd send_dec_buf;
7191 void *apr_cvs;
7192
7193 apr_cvs = common.apr_q6_cvs;
7194
7195 if (!apr_cvs) {
7196 pr_err("%s: apr_cvs is NULL\n", __func__);
7197 return -EINVAL;
7198 }
7199 cvs_handle = voice_get_cvs_handle(v);
7200
7201 send_dec_buf.hdr.hdr_field =
7202 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
7203 APR_HDR_LEN(APR_HDR_SIZE),
7204 APR_PKT_VER);
7205
7206 send_dec_buf.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
7207 sizeof(send_dec_buf) - APR_HDR_SIZE);
7208
7209 send_dec_buf.hdr.src_port =
7210 voice_get_idx_for_session(v->session_id);
7211 send_dec_buf.hdr.dest_port = cvs_handle;
7212 send_dec_buf.hdr.token = 0;
7213 send_dec_buf.hdr.opcode =
7214 VSS_ISTREAM_EVT_OOB_NOTIFY_DEC_BUFFER_READY;
7215
7216 cvs_voc_pkt = (uint32_t *)(v->shmem_info.sh_buf.buf[0].data);
7217 if (cvs_voc_pkt != NULL && common.mvs_info.dl_cb != NULL) {
7218 /* Set timestamp to 0 and advance the pointer */
7219 cvs_voc_pkt[0] = 0;
7220 /* Set media_type and advance the pointer */
7221 cvs_voc_pkt[1] = common.mvs_info.media_type;
7222 common.mvs_info.dl_cb(
7223 (uint8_t *)&cvs_voc_pkt[2],
7224 common.mvs_info.private_data);
7225 ret = apr_send_pkt(apr_cvs, (uint32_t *) &send_dec_buf);
7226 if (ret < 0) {
7227 pr_err("%s: Err send DEC_BUF_READY_NOTIFI %d\n",
7228 __func__, ret);
7229 goto fail;
7230 }
7231 } else {
7232 pr_debug("%s: voc_pkt or dl_cb is NULL\n", __func__);
7233 goto fail;
7234 }
7235 } else if (data->opcode == VSS_ISTREAM_EVT_REQUEST_DEC_BUFFER) {
7236 pr_debug("Recd VSS_ISTREAM_EVT_REQUEST_DEC_BUFFER\n");
7237 } else if (data->opcode == VSS_ISTREAM_EVT_SEND_DEC_BUFFER) {
7238 pr_debug("Send dec buf resp\n");
7239 } else if (data->opcode == APR_RSP_ACCEPTED) {
7240 ptr = data->payload;
7241 if (ptr[0])
7242 pr_debug("%s: APR_RSP_ACCEPTED for 0x%x:\n",
7243 __func__, ptr[0]);
7244 } else if (data->opcode == VSS_ISTREAM_EVT_NOT_READY) {
7245 pr_debug("Recd VSS_ISTREAM_EVT_NOT_READY\n");
7246 } else if (data->opcode == VSS_ISTREAM_EVT_READY) {
7247 pr_debug("Recd VSS_ISTREAM_EVT_READY\n");
7248 } else if (data->opcode == VSS_ICOMMON_RSP_GET_PARAM) {
7249 pr_debug("%s: VSS_ICOMMON_RSP_GET_PARAM\n", __func__);
7250 ptr = data->payload;
7251 if (ptr[0] != 0) {
7252 pr_err("%s: VSS_ICOMMON_RSP_GET_PARAM returned error = 0x%x\n",
7253 __func__, ptr[0]);
7254 }
7255 rtac_make_voice_callback(RTAC_CVS, data->payload,
7256 data->payload_size);
7257 } else if (data->opcode == VSS_ISTREAM_EVT_RX_DTMF_DETECTED) {
7258 struct vss_istream_evt_rx_dtmf_detected *dtmf_rx_detected;
7259 uint32_t *voc_pkt = data->payload;
7260 uint32_t pkt_len = data->payload_size;
7261
7262 if ((voc_pkt != NULL) &&
7263 (pkt_len ==
7264 sizeof(struct vss_istream_evt_rx_dtmf_detected))) {
7265
7266 dtmf_rx_detected =
7267 (struct vss_istream_evt_rx_dtmf_detected *) voc_pkt;
7268 pr_debug("RX_DTMF_DETECTED low_freq=%d high_freq=%d\n",
7269 dtmf_rx_detected->low_freq,
7270 dtmf_rx_detected->high_freq);
7271 if (c->dtmf_info.dtmf_rx_ul_cb)
7272 c->dtmf_info.dtmf_rx_ul_cb((uint8_t *)voc_pkt,
7273 voc_get_session_name(v->session_id),
7274 c->dtmf_info.private_data);
7275 } else {
7276 pr_err("Invalid packet\n");
7277 }
7278 } else
7279 pr_debug("Unknown opcode 0x%x\n", data->opcode);
7280
7281fail:
7282 return 0;
7283}
7284
7285static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv)
7286{
7287 uint32_t *ptr = NULL;
7288 struct common_data *c = NULL;
7289 struct voice_data *v = NULL;
7290 int i = 0;
7291
7292 if ((data == NULL) || (priv == NULL)) {
7293 pr_err("%s: data or priv is NULL\n", __func__);
7294 return -EINVAL;
7295 }
7296
7297 c = priv;
7298
7299 if (data->opcode == RESET_EVENTS) {
7300 pr_debug("%s: Reset event received in Voice service\n",
7301 __func__);
7302
7303 apr_reset(c->apr_q6_cvp);
7304 c->apr_q6_cvp = NULL;
7305 cal_utils_clear_cal_block_q6maps(MAX_VOICE_CAL_TYPES,
7306 common.cal_data);
7307
7308 /* Sub-system restart is applicable to all sessions. */
7309 for (i = 0; i < MAX_VOC_SESSIONS; i++)
7310 c->voice[i].cvp_handle = 0;
7311
7312 /*
7313 * Free the ION memory and clear handles for
7314 * Source Tracking
7315 */
7316 if (is_source_tracking_shared_memomry_allocated()) {
7317 msm_audio_ion_free(
7318 common.source_tracking_sh_mem.sh_mem_block.client,
7319 common.source_tracking_sh_mem.sh_mem_block.handle);
7320 common.source_tracking_sh_mem.mem_handle = 0;
7321 common.source_tracking_sh_mem.sh_mem_block.client =
7322 NULL;
7323 common.source_tracking_sh_mem.sh_mem_block.handle =
7324 NULL;
7325 }
7326 voc_set_error_state(data->reset_proc);
7327 return 0;
7328 }
7329
7330 v = voice_get_session_by_idx(data->dest_port);
7331 if (v == NULL) {
7332 pr_err("%s: v is NULL\n", __func__);
7333
7334 return -EINVAL;
7335 }
7336
7337 if (data->opcode == APR_BASIC_RSP_RESULT) {
7338 if (data->payload_size) {
7339 ptr = data->payload;
7340
7341 pr_debug("%x %x\n", ptr[0], ptr[1]);
7342 if (ptr[1] != 0) {
7343 pr_err("%s: cmd = 0x%x returned error = 0x%x\n",
7344 __func__, ptr[0], ptr[1]);
7345 }
7346 switch (ptr[0]) {
7347 case VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION_V2:
7348 case VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION_V3:
7349 /*response from CVP */
7350 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
7351 if (!ptr[1]) {
7352 voice_set_cvp_handle(v, data->src_port);
7353 pr_debug("status: %d, cvphdl=%d\n",
7354 ptr[1], data->src_port);
7355 } else
7356 pr_err("got NACK from CVP create session response\n");
7357 v->cvp_state = CMD_STATUS_SUCCESS;
7358 v->async_err = ptr[1];
7359 wake_up(&v->cvp_wait);
7360 break;
7361 case VSS_IVOCPROC_CMD_SET_DEVICE_V2:
7362 case VSS_IVOCPROC_CMD_SET_DEVICE_V3:
7363 case VSS_IVOLUME_CMD_SET_STEP:
7364 case VSS_IVOCPROC_CMD_ENABLE:
7365 case VSS_IVOCPROC_CMD_DISABLE:
7366 case APRV2_IBASIC_CMD_DESTROY_SESSION:
7367 case VSS_IVOCPROC_CMD_REGISTER_VOL_CALIBRATION_DATA:
7368 case VSS_IVOCPROC_CMD_DEREGISTER_VOL_CALIBRATION_DATA:
7369 case VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA_V2:
7370 case VSS_IVOCPROC_CMD_DEREGISTER_CALIBRATION_DATA:
7371 case VSS_IVOCPROC_CMD_REGISTER_DYNAMIC_CALIBRATION_DATA:
7372 case VSS_IVOCPROC_CMD_DEREGISTER_DYNAMIC_CALIBRATION_DATA:
7373 case VSS_IVOCPROC_CMD_REGISTER_STATIC_CALIBRATION_DATA:
7374 case VSS_IVOCPROC_CMD_DEREGISTER_STATIC_CALIBRATION_DATA:
7375 case VSS_IVOCPROC_CMD_REGISTER_DEVICE_CONFIG:
7376 case VSS_IVOCPROC_CMD_DEREGISTER_DEVICE_CONFIG:
7377 case VSS_ICOMMON_CMD_MAP_MEMORY:
7378 case VSS_ICOMMON_CMD_UNMAP_MEMORY:
7379 case VSS_IVOLUME_CMD_MUTE_V2:
7380 case VSS_IVPCM_CMD_START_V2:
7381 case VSS_IVPCM_CMD_STOP:
7382 case VSS_IVOCPROC_CMD_TOPOLOGY_SET_DEV_CHANNELS:
7383 case VSS_IVOCPROC_CMD_TOPOLOGY_COMMIT:
7384 v->cvp_state = CMD_STATUS_SUCCESS;
7385 v->async_err = ptr[1];
7386 wake_up(&v->cvp_wait);
7387 break;
7388 case VSS_IVPCM_EVT_PUSH_BUFFER_V2:
7389 break;
7390 case VSS_ICOMMON_CMD_SET_PARAM_V2:
7391 switch (data->token) {
7392 case VOC_SET_MEDIA_FORMAT_PARAM_TOKEN:
Laxminath Kasam38070be2017-08-17 18:21:59 +05307393 case VOC_GENERIC_SET_PARAM_TOKEN:
7394 pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM_V2 called\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307395 __func__);
7396 v->cvp_state = CMD_STATUS_SUCCESS;
7397 v->async_err = ptr[1];
7398 wake_up(&v->cvp_wait);
7399 break;
7400 case VOC_RTAC_SET_PARAM_TOKEN:
7401 pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM_V2 called by rtac\n",
7402 __func__);
7403 rtac_make_voice_callback(
7404 RTAC_CVP, ptr,
7405 data->payload_size);
7406 break;
7407 default:
7408 pr_debug("%s: invalid token for command VSS_ICOMMON_CMD_SET_PARAM_V2: %d\n",
7409 __func__, data->token);
7410 break;
7411 }
7412 break;
7413 case VSS_ICOMMON_CMD_GET_PARAM_V2:
7414 pr_debug("%s: VSS_ICOMMON_CMD_GET_PARAM_V2\n",
7415 __func__);
7416 /* Should only come here if there is an APR */
7417 /* error or malformed APR packet. Otherwise */
7418 /* response will be returned as */
7419 /* VSS_ICOMMON_RSP_GET_PARAM */
7420 if (ptr[1] != 0) {
7421 pr_err("%s: CVP get param error = %d, resuming\n",
7422 __func__, ptr[1]);
7423 rtac_make_voice_callback(RTAC_CVP,
7424 data->payload,
7425 data->payload_size);
7426 }
7427 break;
7428 case VSS_ISOUNDFOCUS_CMD_SET_SECTORS:
7429 if (!ptr[1])
7430 common.is_sound_focus_resp_success =
7431 true;
7432 else
7433 common.is_sound_focus_resp_success =
7434 false;
7435 v->cvp_state = CMD_STATUS_SUCCESS;
7436 v->async_err = ptr[1];
7437 wake_up(&v->cvp_wait);
7438 break;
7439 case VSS_ISOUNDFOCUS_CMD_GET_SECTORS:
7440 /*
7441 * Should only come here if there is an error
7442 * response received from ADSP. Otherwise
7443 * response will be returned as
7444 * VSS_ISOUNDFOCUS_RSP_GET_SECTORS
7445 */
7446 pr_err("%s: VSS_ISOUNDFOCUS_CMD_GET_SECTORS failed\n",
7447 __func__);
7448
7449 common.is_sound_focus_resp_success = false;
7450 v->cvp_state = CMD_STATUS_SUCCESS;
7451 v->async_err = ptr[1];
7452 wake_up(&v->cvp_wait);
7453 break;
7454 case VSS_ISOURCETRACK_CMD_GET_ACTIVITY:
7455 if (!ptr[1]) {
7456 /* Read data from shared memory */
7457 memcpy(&common.sourceTrackingResponse,
7458 common.source_tracking_sh_mem.
7459 sh_mem_block.data,
7460 sizeof(struct
7461 vss_isourcetrack_activity_data_t));
7462 common.is_source_tracking_resp_success =
7463 true;
7464 } else {
7465 common.is_source_tracking_resp_success =
7466 false;
7467 pr_err("%s: Error received for source tracking params\n",
7468 __func__);
7469 }
7470 v->cvp_state = CMD_STATUS_SUCCESS;
7471 v->async_err = ptr[1];
7472 wake_up(&v->cvp_wait);
7473 break;
7474 default:
7475 pr_debug("%s: not match cmd = 0x%x\n",
7476 __func__, ptr[0]);
7477 break;
7478 }
7479 }
7480 } else if (data->opcode == VSS_ICOMMON_RSP_GET_PARAM) {
7481 pr_debug("%s: VSS_ICOMMON_RSP_GET_PARAM\n", __func__);
7482 ptr = data->payload;
7483 if (ptr[0] != 0) {
7484 pr_err("%s: VSS_ICOMMON_RSP_GET_PARAM returned error = 0x%x\n",
7485 __func__, ptr[0]);
7486 }
7487 rtac_make_voice_callback(RTAC_CVP, data->payload,
7488 data->payload_size);
7489 } else if (data->opcode == VSS_IVPCM_EVT_NOTIFY_V2) {
7490 if ((data->payload != NULL) && data->payload_size ==
7491 sizeof(struct vss_ivpcm_evt_notify_v2_t) &&
7492 common.hostpcm_info.hostpcm_evt_cb != NULL) {
7493 common.hostpcm_info.hostpcm_evt_cb(data->payload,
7494 voc_get_session_name(v->session_id),
7495 common.hostpcm_info.private_data);
7496 }
7497 } else if (data->opcode == VSS_ISOUNDFOCUS_RSP_GET_SECTORS) {
7498 if (data->payload && (data->payload_size ==
7499 sizeof(struct vss_isoundfocus_rsp_get_sectors_t))) {
7500 common.is_sound_focus_resp_success = true;
7501 memcpy(&common.soundFocusResponse,
7502 (struct vss_isoundfocus_rsp_get_sectors_t *)
7503 data->payload,
7504 sizeof(struct
7505 vss_isoundfocus_rsp_get_sectors_t));
7506 } else {
7507 common.is_sound_focus_resp_success = false;
7508 pr_debug("%s: Invalid payload received from CVD\n",
7509 __func__);
7510 }
7511 v->cvp_state = CMD_STATUS_SUCCESS;
7512 wake_up(&v->cvp_wait);
7513 }
7514 return 0;
7515}
7516
7517static int voice_free_oob_shared_mem(void)
7518{
7519 int rc = 0;
7520 int cnt = 0;
7521 int bufcnt = NUM_OF_BUFFERS;
7522 struct voice_data *v = voice_get_session(
7523 common.voice[VOC_PATH_FULL].session_id);
7524
7525 mutex_lock(&common.common_lock);
7526 if (v == NULL) {
7527 pr_err("%s: v is NULL\n", __func__);
7528
7529 rc = -EINVAL;
7530 goto done;
7531 }
7532
7533 rc = msm_audio_ion_free(v->shmem_info.sh_buf.client,
7534 v->shmem_info.sh_buf.handle);
7535 v->shmem_info.sh_buf.client = NULL;
7536 v->shmem_info.sh_buf.handle = NULL;
7537 if (rc < 0) {
7538 pr_err("%s: Error:%d freeing memory\n", __func__, rc);
7539
7540 goto done;
7541 }
7542
7543
7544 while (cnt < bufcnt) {
7545 v->shmem_info.sh_buf.buf[cnt].data = NULL;
7546 v->shmem_info.sh_buf.buf[cnt].phys = 0;
7547 cnt++;
7548 }
7549
7550 v->shmem_info.sh_buf.client = NULL;
7551 v->shmem_info.sh_buf.handle = NULL;
7552
7553done:
7554 mutex_unlock(&common.common_lock);
7555 return rc;
7556}
7557
7558static int voice_alloc_oob_shared_mem(void)
7559{
7560 int cnt = 0;
7561 int rc = 0;
7562 size_t len;
7563 void *mem_addr;
7564 dma_addr_t phys;
7565 int bufsz = BUFFER_BLOCK_SIZE;
7566 int bufcnt = NUM_OF_BUFFERS;
7567 struct voice_data *v = voice_get_session(
7568 common.voice[VOC_PATH_FULL].session_id);
7569
7570 mutex_lock(&common.common_lock);
7571 if (v == NULL) {
7572 pr_err("%s: v is NULL\n", __func__);
7573
7574 rc = -EINVAL;
7575 goto done;
7576 }
7577
7578 rc = msm_audio_ion_alloc("voip_client", &(v->shmem_info.sh_buf.client),
7579 &(v->shmem_info.sh_buf.handle),
7580 bufsz*bufcnt,
7581 &phys, &len,
7582 &mem_addr);
7583 if (rc < 0) {
7584 pr_err("%s: audio ION alloc failed, rc = %d\n",
7585 __func__, rc);
7586
7587 goto done;
7588 }
7589
7590 while (cnt < bufcnt) {
7591 v->shmem_info.sh_buf.buf[cnt].data = mem_addr + (cnt * bufsz);
7592 v->shmem_info.sh_buf.buf[cnt].phys = phys + (cnt * bufsz);
7593 v->shmem_info.sh_buf.buf[cnt].size = bufsz;
7594 cnt++;
7595 }
7596
7597 pr_debug("%s buf[0].data:[%pK], buf[0].phys:[%pK], &buf[0].phys:[%pK],\n",
7598 __func__,
7599 (void *)v->shmem_info.sh_buf.buf[0].data,
7600 &v->shmem_info.sh_buf.buf[0].phys,
7601 (void *)&v->shmem_info.sh_buf.buf[0].phys);
7602 pr_debug("%s: buf[1].data:[%pK], buf[1].phys[%pK], &buf[1].phys[%pK]\n",
7603 __func__,
7604 (void *)v->shmem_info.sh_buf.buf[1].data,
7605 &v->shmem_info.sh_buf.buf[1].phys,
7606 (void *)&v->shmem_info.sh_buf.buf[1].phys);
7607
7608 memset((void *)v->shmem_info.sh_buf.buf[0].data, 0, (bufsz * bufcnt));
7609
7610done:
7611 mutex_unlock(&common.common_lock);
7612 return rc;
7613}
7614
7615static int voice_alloc_oob_mem_table(void)
7616{
7617 int rc = 0;
7618 size_t len;
7619 struct voice_data *v = voice_get_session(
7620 common.voice[VOC_PATH_FULL].session_id);
7621
7622 mutex_lock(&common.common_lock);
7623 if (v == NULL) {
7624 pr_err("%s: v is NULL\n", __func__);
7625
7626 rc = -EINVAL;
7627 goto done;
7628 }
7629
7630 rc = msm_audio_ion_alloc("voip_client", &(v->shmem_info.memtbl.client),
7631 &(v->shmem_info.memtbl.handle),
7632 sizeof(struct vss_imemory_table_t),
7633 &v->shmem_info.memtbl.phys,
7634 &len,
7635 &(v->shmem_info.memtbl.data));
7636 if (rc < 0) {
7637 pr_err("%s: audio ION alloc failed, rc = %d\n",
7638 __func__, rc);
7639
7640 goto done;
7641 }
7642
7643 v->shmem_info.memtbl.size = sizeof(struct vss_imemory_table_t);
7644 pr_debug("%s data[%pK]phys[%pK][%pK]\n", __func__,
7645 (void *)v->shmem_info.memtbl.data,
7646 &v->shmem_info.memtbl.phys,
7647 (void *)&v->shmem_info.memtbl.phys);
7648
7649done:
7650 mutex_unlock(&common.common_lock);
7651 return rc;
7652}
7653
7654int voc_send_cvp_start_vocpcm(uint32_t session_id,
7655 struct vss_ivpcm_tap_point *vpcm_tp,
7656 uint32_t no_of_tp)
7657{
7658 struct cvp_start_cmd cvp_start_cmd;
7659 int ret = 0;
7660 void *apr_cvp;
7661 u16 cvp_handle;
7662 struct voice_data *v = voice_get_session(session_id);
7663 int i = 0;
7664
7665 if (v == NULL) {
7666 pr_err("%s: v is NULL\n", __func__);
7667 ret = -EINVAL;
7668 goto done;
7669 }
7670 apr_cvp = common.apr_q6_cvp;
7671
7672 if (!apr_cvp) {
7673 pr_err("%s: apr_cvp is NULL.\n", __func__);
7674 ret = -EINVAL;
7675 goto done;
7676 }
7677
7678 cvp_handle = voice_get_cvp_handle(v);
7679
7680 /* Fill the header */
7681 cvp_start_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
7682 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
7683 cvp_start_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
7684 sizeof(struct vss_ivpcm_tap_point) * no_of_tp) +
7685 sizeof(cvp_start_cmd.vpcm_start_cmd.num_tap_points) +
7686 sizeof(cvp_start_cmd.vpcm_start_cmd.mem_handle);
7687 cvp_start_cmd.hdr.src_port = voice_get_idx_for_session(v->session_id);
7688 cvp_start_cmd.hdr.dest_port = cvp_handle;
7689 cvp_start_cmd.hdr.token = 0;
7690 cvp_start_cmd.hdr.opcode = VSS_IVPCM_CMD_START_V2;
7691
7692 for (i = 0; i < no_of_tp; i++) {
7693 cvp_start_cmd.vpcm_start_cmd.tap_points[i].tap_point =
7694 vpcm_tp[i].tap_point;
7695 cvp_start_cmd.vpcm_start_cmd.tap_points[i].direction =
7696 vpcm_tp[i].direction;
7697 cvp_start_cmd.vpcm_start_cmd.tap_points[i].sampling_rate =
7698 vpcm_tp[i].sampling_rate;
7699 cvp_start_cmd.vpcm_start_cmd.tap_points[i].duration = 0;
7700 }
7701
7702 cvp_start_cmd.vpcm_start_cmd.mem_handle =
7703 common.voice_host_pcm_mem_handle;
7704 cvp_start_cmd.vpcm_start_cmd.num_tap_points = no_of_tp;
7705
7706 v->cvp_state = CMD_STATUS_FAIL;
7707 v->async_err = 0;
7708 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_start_cmd);
7709 if (ret < 0) {
7710 pr_err("%s: Fail: sending vocpcm map memory,\n", __func__);
7711 goto done;
7712 }
7713 ret = wait_event_timeout(v->cvp_wait,
7714 (v->cvp_state == CMD_STATUS_SUCCESS),
7715 msecs_to_jiffies(TIMEOUT_MS));
7716 if (!ret) {
7717 pr_err("%s: wait_event timeout\n", __func__);
7718 goto done;
7719 }
7720 if (v->async_err > 0) {
7721 pr_err("%s: DSP returned error[%s]\n",
7722 __func__, adsp_err_get_err_str(
7723 v->async_err));
7724 ret = adsp_err_get_lnx_err_code(
7725 v->async_err);
7726 goto done;
7727 }
7728
7729done:
7730 return ret;
7731}
7732
7733int voc_send_cvp_stop_vocpcm(uint32_t session_id)
7734{
7735 struct cvp_command vpcm_stop_cmd;
7736 int ret = 0;
7737 void *apr_cvp;
7738 u16 cvp_handle;
7739 struct voice_data *v = voice_get_session(session_id);
7740
7741 if (v == NULL) {
7742 pr_err("%s: v is NULL\n", __func__);
7743 ret = -EINVAL;
7744 goto done;
7745 }
7746 apr_cvp = common.apr_q6_cvp;
7747
7748 if (!apr_cvp) {
7749 pr_err("%s: apr_cvp is NULL.\n", __func__);
7750 ret = -EINVAL;
7751 goto done;
7752 }
7753
7754 cvp_handle = voice_get_cvp_handle(v);
7755
7756 /* fill in the header */
7757 vpcm_stop_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
7758 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
7759 vpcm_stop_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
7760 sizeof(vpcm_stop_cmd) - APR_HDR_SIZE);
7761 vpcm_stop_cmd.hdr.src_port = voice_get_idx_for_session(v->session_id);
7762 vpcm_stop_cmd.hdr.dest_port = cvp_handle;
7763 vpcm_stop_cmd.hdr.token = 0;
7764 vpcm_stop_cmd.hdr.opcode = VSS_IVPCM_CMD_STOP;
7765
7766 v->cvp_state = CMD_STATUS_FAIL;
7767 v->async_err = 0;
7768 ret = apr_send_pkt(apr_cvp, (uint32_t *) &vpcm_stop_cmd);
7769 if (ret < 0) {
7770 pr_err("Fail: sending vocpcm stop,\n");
7771 goto done;
7772 }
7773 ret = wait_event_timeout(v->cvp_wait,
7774 (v->cvp_state == CMD_STATUS_SUCCESS),
7775 msecs_to_jiffies(TIMEOUT_MS));
7776 if (!ret) {
7777 pr_err("%s: wait_event timeout\n", __func__);
7778 goto done;
7779 }
7780
7781 if (v->async_err > 0) {
7782 pr_err("%s: DSP returned error[%s]\n",
7783 __func__, adsp_err_get_err_str(
7784 v->async_err));
7785 ret = adsp_err_get_lnx_err_code(
7786 v->async_err);
7787 goto done;
7788 }
7789
7790done:
7791 return ret;
7792}
7793
7794int voc_send_cvp_map_vocpcm_memory(uint32_t session_id,
7795 struct mem_map_table *tp_mem_table,
7796 phys_addr_t paddr, uint32_t bufsize)
7797{
7798 return voice_map_memory_physical_cmd(voice_get_session(session_id),
7799 tp_mem_table,
7800 (dma_addr_t) paddr, bufsize,
7801 VOC_VOICE_HOST_PCM_MAP_TOKEN);
7802}
7803
7804int voc_send_cvp_unmap_vocpcm_memory(uint32_t session_id)
7805{
7806 int ret = 0;
7807
7808 ret = voice_send_mvm_unmap_memory_physical_cmd(
7809 voice_get_session(session_id),
7810 common.voice_host_pcm_mem_handle);
7811
7812 if (ret == 0)
7813 common.voice_host_pcm_mem_handle = 0;
7814
7815 return ret;
7816}
7817
7818int voc_send_cvp_vocpcm_push_buf_evt(uint32_t session_id,
7819 struct vss_ivpcm_evt_push_buffer_v2_t *push_buff_evt)
7820{
7821 struct cvp_push_buf_cmd vpcm_push_buf_cmd;
7822 int ret = 0;
7823 void *apr_cvp;
7824 u16 cvp_handle;
7825 struct voice_data *v = voice_get_session(session_id);
7826
7827 if (v == NULL) {
7828 pr_err("%s: v is NULL\n", __func__);
7829 ret = -EINVAL;
7830 goto done;
7831 }
7832 apr_cvp = common.apr_q6_cvp;
7833
7834 if (!apr_cvp) {
7835 pr_err("%s: apr_cvp is NULL.\n", __func__);
7836 ret = -EINVAL;
7837 goto done;
7838 }
7839
7840 memset(&vpcm_push_buf_cmd, 0, sizeof(vpcm_push_buf_cmd));
7841 cvp_handle = voice_get_cvp_handle(v);
7842
7843 /* fill in the header */
7844 vpcm_push_buf_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
7845 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
7846 vpcm_push_buf_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
7847 sizeof(vpcm_push_buf_cmd) - APR_HDR_SIZE);
7848 vpcm_push_buf_cmd.hdr.src_port =
7849 voice_get_idx_for_session(v->session_id);
7850 vpcm_push_buf_cmd.hdr.dest_port = cvp_handle;
7851 vpcm_push_buf_cmd.hdr.token = 0;
7852 vpcm_push_buf_cmd.hdr.opcode = VSS_IVPCM_EVT_PUSH_BUFFER_V2;
7853
7854 vpcm_push_buf_cmd.vpcm_evt_push_buffer.tap_point =
7855 push_buff_evt->tap_point;
7856 vpcm_push_buf_cmd.vpcm_evt_push_buffer.push_buf_mask =
7857 push_buff_evt->push_buf_mask;
7858 vpcm_push_buf_cmd.vpcm_evt_push_buffer.out_buf_mem_address =
7859 push_buff_evt->out_buf_mem_address;
7860 vpcm_push_buf_cmd.vpcm_evt_push_buffer.in_buf_mem_address =
7861 push_buff_evt->in_buf_mem_address;
7862 vpcm_push_buf_cmd.vpcm_evt_push_buffer.out_buf_mem_size =
7863 push_buff_evt->out_buf_mem_size;
7864 vpcm_push_buf_cmd.vpcm_evt_push_buffer.in_buf_mem_size =
7865 push_buff_evt->in_buf_mem_size;
7866 vpcm_push_buf_cmd.vpcm_evt_push_buffer.sampling_rate =
7867 push_buff_evt->sampling_rate;
7868 vpcm_push_buf_cmd.vpcm_evt_push_buffer.num_in_channels =
7869 push_buff_evt->num_in_channels;
7870
7871 ret = apr_send_pkt(apr_cvp, (uint32_t *) &vpcm_push_buf_cmd);
7872 if (ret < 0) {
7873 pr_err("Fail: sending vocpcm map memory,\n");
7874 goto done;
7875 }
7876
7877done:
7878 return ret;
7879}
7880
7881void voc_register_hpcm_evt_cb(hostpcm_cb_fn hostpcm_cb,
7882 void *private_data)
7883{
7884 common.hostpcm_info.hostpcm_evt_cb = hostpcm_cb;
7885 common.hostpcm_info.private_data = private_data;
7886}
7887
7888void voc_deregister_hpcm_evt_cb(void)
7889{
7890 common.hostpcm_info.hostpcm_evt_cb = NULL;
7891 common.hostpcm_info.private_data = NULL;
7892}
7893
7894int voc_get_cvd_version(char *cvd_version)
7895{
7896 int ret = 0;
7897 struct voice_data *v = voice_get_session(VOICE_SESSION_VSID);
7898
7899
7900 if (v == NULL) {
7901 pr_err("%s: invalid session_id 0x%x\n",
7902 __func__, VOICE_SESSION_VSID);
7903
7904 ret = -EINVAL;
7905 goto done;
7906 }
7907
7908 if (is_cvd_version_queried()) {
7909 pr_debug("%s: Returning the cached value %s\n",
7910 __func__, common.cvd_version);
7911
7912 goto done;
7913 }
7914
7915 /* Register callback to APR */
7916 ret = voice_apr_register(VOICE_SESSION_VSID);
7917 if (ret < 0) {
7918 pr_err("%s: apr register failed\n", __func__);
7919 goto done;
7920 }
7921
7922 mutex_lock(&common.common_lock);
7923 mutex_lock(&v->lock);
7924 ret = voice_send_mvm_cvd_version_cmd(v);
7925 if (ret < 0) {
7926 pr_err("%s: voice_send_mvm_cvd_version_cmd failed\n", __func__);
7927 goto unlock;
7928 }
7929 ret = 0;
7930
7931unlock:
7932 mutex_unlock(&v->lock);
7933 mutex_unlock(&common.common_lock);
7934
7935done:
7936 if (cvd_version)
7937 memcpy(cvd_version, common.cvd_version,
7938 CVD_VERSION_STRING_MAX_SIZE);
7939
7940 return ret;
7941}
7942
7943static int voice_alloc_cal_mem_map_table(void)
7944{
7945 int ret = 0;
7946 size_t len;
7947
7948 ret = msm_audio_ion_alloc("voc_cal",
7949 &(common.cal_mem_map_table.client),
7950 &(common.cal_mem_map_table.handle),
7951 sizeof(struct vss_imemory_table_t),
7952 &common.cal_mem_map_table.phys,
7953 &len,
7954 &(common.cal_mem_map_table.data));
7955 if ((ret < 0) && (ret != -EPROBE_DEFER)) {
7956 pr_err("%s: audio ION alloc failed, rc = %d\n",
7957 __func__, ret);
7958 goto done;
7959 }
7960
7961 common.cal_mem_map_table.size = sizeof(struct vss_imemory_table_t);
7962 pr_debug("%s: data %pK phys %pK\n", __func__,
7963 common.cal_mem_map_table.data,
7964 &common.cal_mem_map_table.phys);
7965
7966done:
7967 return ret;
7968}
7969
7970static int voice_alloc_rtac_mem_map_table(void)
7971{
7972 int ret = 0;
7973 size_t len;
7974
7975 ret = msm_audio_ion_alloc("voc_rtac_cal",
7976 &(common.rtac_mem_map_table.client),
7977 &(common.rtac_mem_map_table.handle),
7978 sizeof(struct vss_imemory_table_t),
7979 &common.rtac_mem_map_table.phys,
7980 &len,
7981 &(common.rtac_mem_map_table.data));
7982 if (ret < 0) {
7983 pr_err("%s: audio ION alloc failed, rc = %d\n",
7984 __func__, ret);
7985 goto done;
7986 }
7987
7988 common.rtac_mem_map_table.size = sizeof(struct vss_imemory_table_t);
7989 pr_debug("%s: data %pK phys %pK\n", __func__,
7990 common.rtac_mem_map_table.data,
7991 &common.rtac_mem_map_table.phys);
7992
7993done:
7994 return ret;
7995}
7996
7997static int voice_alloc_and_map_oob_mem(struct voice_data *v)
7998{
7999 int ret = 0;
8000
8001 if (v == NULL) {
8002 pr_err("%s: v is NULL\n", __func__);
8003
8004 return -EINVAL;
8005 }
8006
8007 if (!is_voip_memory_allocated()) {
8008 ret = voc_alloc_voip_shared_memory();
8009 if (ret < 0) {
8010 pr_err("%s: Failed to create voip oob memory %d\n",
8011 __func__, ret);
8012
8013 goto done;
8014 }
8015 }
8016
8017 ret = voice_map_memory_physical_cmd(v,
8018 &v->shmem_info.memtbl,
8019 v->shmem_info.sh_buf.buf[0].phys,
8020 v->shmem_info.sh_buf.buf[0].size * NUM_OF_BUFFERS,
8021 VOIP_MEM_MAP_TOKEN);
8022 if (ret) {
8023 pr_err("%s: mvm_map_memory_phy failed %d\n",
8024 __func__, ret);
8025
8026 goto done;
8027 }
8028
8029done:
8030 return ret;
8031}
8032
8033uint32_t voice_get_topology(uint32_t topology_idx)
8034{
8035 uint32_t topology = VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
8036 struct cal_block_data *cal_block = NULL;
8037
8038 /* initialize as default topology */
8039 if (topology_idx == CVP_VOC_RX_TOPOLOGY_CAL) {
8040 topology = VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
8041 } else if (topology_idx == CVP_VOC_TX_TOPOLOGY_CAL) {
Laxminath Kasam8f7ccc22017-08-28 17:35:04 +05308042 topology = VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS_V2;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308043 } else {
8044 pr_err("%s: cal index %x is invalid!\n",
8045 __func__, topology_idx);
8046
8047 goto done;
8048 }
8049
8050 if (common.cal_data[topology_idx] == NULL) {
8051 pr_err("%s: cal type is NULL for cal index %x\n",
8052 __func__, topology_idx);
8053
8054 goto done;
8055 }
8056
8057 mutex_lock(&common.cal_data[topology_idx]->lock);
8058 cal_block = cal_utils_get_only_cal_block(
8059 common.cal_data[topology_idx]);
8060 if (cal_block == NULL) {
8061 pr_debug("%s: cal_block not found for cal index %x\n",
8062 __func__, topology_idx);
8063
8064 goto unlock;
8065 }
8066
8067 topology = ((struct audio_cal_info_voc_top *)
8068 cal_block->cal_info)->topology;
8069unlock:
8070 mutex_unlock(&common.cal_data[topology_idx]->lock);
8071done:
8072 pr_debug("%s: Using topology %d\n", __func__, topology);
8073
8074 return topology;
8075}
8076
8077static int get_cal_type_index(int32_t cal_type)
8078{
8079 int ret = -EINVAL;
8080
8081 switch (cal_type) {
8082 case CVP_VOC_RX_TOPOLOGY_CAL_TYPE:
8083 ret = CVP_VOC_RX_TOPOLOGY_CAL;
8084 break;
8085 case CVP_VOC_TX_TOPOLOGY_CAL_TYPE:
8086 ret = CVP_VOC_TX_TOPOLOGY_CAL;
8087 break;
8088 case CVP_VOCPROC_STATIC_CAL_TYPE:
8089 ret = CVP_VOCPROC_CAL;
8090 break;
8091 case CVP_VOCPROC_DYNAMIC_CAL_TYPE:
8092 ret = CVP_VOCVOL_CAL;
8093 break;
8094 case CVS_VOCSTRM_STATIC_CAL_TYPE:
8095 ret = CVS_VOCSTRM_CAL;
8096 break;
8097 case CVP_VOCDEV_CFG_CAL_TYPE:
8098 ret = CVP_VOCDEV_CFG_CAL;
8099 break;
8100 case CVP_VOCPROC_STATIC_COL_CAL_TYPE:
8101 ret = CVP_VOCPROC_COL_CAL;
8102 break;
8103 case CVP_VOCPROC_DYNAMIC_COL_CAL_TYPE:
8104 ret = CVP_VOCVOL_COL_CAL;
8105 break;
8106 case CVS_VOCSTRM_STATIC_COL_CAL_TYPE:
8107 ret = CVS_VOCSTRM_COL_CAL;
8108 break;
8109 case VOICE_RTAC_INFO_CAL_TYPE:
8110 ret = VOICE_RTAC_INFO_CAL;
8111 break;
8112 case VOICE_RTAC_APR_CAL_TYPE:
8113 ret = VOICE_RTAC_APR_CAL;
8114 break;
8115 default:
8116 pr_err("%s: Invalid cal type %d!\n", __func__, cal_type);
8117 }
8118 return ret;
8119}
8120
8121static int voice_prepare_volume_boost(int32_t cal_type,
8122 size_t data_size, void *data)
8123{
8124 return voc_deregister_vocproc_vol_table();
8125}
8126
8127static int voice_enable_volume_boost(int32_t cal_type,
8128 size_t data_size, void *data)
8129{
8130 return voc_register_vocproc_vol_table();
8131}
8132
8133static int voice_alloc_cal(int32_t cal_type,
8134 size_t data_size, void *data)
8135{
8136 int ret = 0;
8137 int cal_index;
8138 int cal_version;
8139
8140 pr_debug("%s\n", __func__);
8141
8142 cal_version = cal_utils_get_cal_type_version(data);
8143 common.is_per_vocoder_cal_enabled =
8144 !!(cal_version & PER_VOCODER_CAL_BIT_MASK);
8145
8146 cal_index = get_cal_type_index(cal_type);
8147 if (cal_index < 0) {
8148 pr_err("%s: Could not get cal index %d!\n",
8149 __func__, cal_index);
8150 ret = -EINVAL;
8151 goto done;
8152 }
8153
8154 ret = cal_utils_alloc_cal(data_size, data,
8155 common.cal_data[cal_index], 0, NULL);
8156 if (ret < 0) {
8157 pr_err("%s: Cal_utils_alloc_block failed, ret = %d, cal type = %d!\n",
8158 __func__, ret, cal_type);
8159 ret = -EINVAL;
8160 goto done;
8161 }
8162done:
8163 return ret;
8164}
8165
8166static int voice_dealloc_cal(int32_t cal_type,
8167 size_t data_size, void *data)
8168{
8169 int ret = 0;
8170 int cal_index;
8171
8172 pr_debug("%s\n", __func__);
8173
8174 cal_index = get_cal_type_index(cal_type);
8175 if (cal_index < 0) {
8176 pr_err("%s: Could not get cal index %d!\n",
8177 __func__, cal_index);
8178
8179 ret = -EINVAL;
8180 goto done;
8181 }
8182
8183 ret = cal_utils_dealloc_cal(data_size, data,
8184 common.cal_data[cal_index]);
8185 if (ret < 0) {
8186 pr_err("%s: Cal_utils_dealloc_block failed, ret = %d, cal type = %d!\n",
8187 __func__, ret, cal_type);
8188
8189 ret = -EINVAL;
8190 goto done;
8191 }
8192done:
8193 return ret;
8194}
8195
8196static int voice_set_cal(int32_t cal_type,
8197 size_t data_size, void *data)
8198{
8199 int ret = 0;
8200 int cal_index;
8201
8202 pr_debug("%s\n", __func__);
8203
8204 cal_index = get_cal_type_index(cal_type);
8205 if (cal_index < 0) {
8206 pr_err("%s: Could not get cal index %d!\n",
8207 __func__, cal_index);
8208
8209 ret = -EINVAL;
8210 goto done;
8211 }
8212
8213 ret = cal_utils_set_cal(data_size, data,
8214 common.cal_data[cal_index], 0, NULL);
8215 if (ret < 0) {
8216 pr_err("%s: Cal_utils_set_cal failed, ret = %d, cal type = %d!\n",
8217 __func__, ret, cal_type);
8218
8219 ret = -EINVAL;
8220 goto done;
8221 }
8222done:
8223 return ret;
8224}
8225
8226static void voice_delete_cal_data(void)
8227{
8228 pr_debug("%s\n", __func__);
8229
8230 cal_utils_destroy_cal_types(MAX_VOICE_CAL_TYPES, common.cal_data);
8231}
8232
8233static int voice_init_cal_data(void)
8234{
8235 int ret = 0;
8236 struct cal_type_info cal_type_info[] = {
8237 {{CVP_VOC_RX_TOPOLOGY_CAL_TYPE,
8238 {NULL, NULL, NULL, voice_set_cal, NULL, NULL} },
8239 {NULL, NULL, cal_utils_match_buf_num} },
8240
8241 {{CVP_VOC_TX_TOPOLOGY_CAL_TYPE,
8242 {NULL, NULL, NULL, voice_set_cal, NULL, NULL} },
8243 {NULL, NULL, cal_utils_match_buf_num} },
8244
8245 {{CVP_VOCPROC_STATIC_CAL_TYPE,
8246 {voice_alloc_cal, voice_dealloc_cal, NULL,
8247 voice_set_cal, NULL, NULL} },
8248 {NULL, voice_unmap_cal_memory,
8249 cal_utils_match_buf_num} },
8250
8251 {{CVP_VOCPROC_DYNAMIC_CAL_TYPE,
8252 {voice_alloc_cal, voice_dealloc_cal,
8253 voice_prepare_volume_boost,
8254 voice_set_cal, NULL,
8255 voice_enable_volume_boost} },
8256 {NULL, voice_unmap_cal_memory,
8257 cal_utils_match_buf_num} },
8258
8259 {{CVP_VOCDEV_CFG_CAL_TYPE,
8260 {voice_alloc_cal, voice_dealloc_cal, NULL,
8261 voice_set_cal, NULL, NULL} },
8262 {NULL, voice_unmap_cal_memory,
8263 cal_utils_match_buf_num} },
8264
8265 {{CVP_VOCPROC_STATIC_COL_CAL_TYPE,
8266 {NULL, NULL, NULL, voice_set_cal, NULL, NULL} },
8267 {NULL, NULL, cal_utils_match_buf_num} },
8268
8269 {{CVP_VOCPROC_DYNAMIC_COL_CAL_TYPE,
8270 {NULL, NULL, NULL, voice_set_cal, NULL, NULL} },
8271 {NULL, NULL, cal_utils_match_buf_num} },
8272
8273 {{CVS_VOCSTRM_STATIC_CAL_TYPE,
8274 {voice_alloc_cal, voice_dealloc_cal, NULL,
8275 voice_set_cal, NULL, NULL} },
8276 {NULL, voice_unmap_cal_memory,
8277 cal_utils_match_buf_num} },
8278
8279 {{CVS_VOCSTRM_STATIC_COL_CAL_TYPE,
8280 {NULL, NULL, NULL, voice_set_cal, NULL, NULL} },
8281 {NULL, NULL, cal_utils_match_buf_num} },
8282
8283 {{VOICE_RTAC_INFO_CAL_TYPE,
8284 {NULL, NULL, NULL, NULL, NULL, NULL} },
8285 {NULL, NULL, cal_utils_match_buf_num} },
8286
8287 {{VOICE_RTAC_APR_CAL_TYPE,
8288 {NULL, NULL, NULL, NULL, NULL, NULL} },
8289 {NULL, NULL, cal_utils_match_buf_num} },
8290 };
8291
8292 ret = cal_utils_create_cal_types(MAX_VOICE_CAL_TYPES, common.cal_data,
8293 cal_type_info);
8294 if (ret < 0) {
8295 pr_err("%s: Could not create cal type!\n",
8296 __func__);
8297
8298 ret = -EINVAL;
8299 goto err;
8300 }
8301
8302 return ret;
8303err:
8304 voice_delete_cal_data();
8305 memset(&common, 0, sizeof(struct common_data));
8306 return ret;
8307}
8308
8309static int voice_send_set_sound_focus_cmd(struct voice_data *v,
8310 struct sound_focus_param soundFocusData)
8311{
8312 struct cvp_set_sound_focus_param_cmd_t cvp_set_sound_focus_param_cmd;
8313 int ret = 0;
8314 void *apr_cvp;
8315 u16 cvp_handle;
8316 int i;
8317
8318 pr_debug("%s: Enter\n", __func__);
8319
8320 if (v == NULL) {
8321 pr_err("%s: v is NULL\n", __func__);
8322
8323 ret = -EINVAL;
8324 goto done;
8325 }
8326 apr_cvp = common.apr_q6_cvp;
8327
8328 if (!apr_cvp) {
8329 pr_err("%s: apr_cvp is NULL.\n", __func__);
8330
8331 ret = -EINVAL;
8332 goto done;
8333 }
8334 cvp_handle = voice_get_cvp_handle(v);
8335
8336 /* send Sound Focus Params to cvp */
8337 cvp_set_sound_focus_param_cmd.hdr.hdr_field =
8338 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
8339 APR_HDR_LEN(APR_HDR_SIZE),
8340 APR_PKT_VER);
8341 cvp_set_sound_focus_param_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
8342 sizeof(cvp_set_sound_focus_param_cmd) - APR_HDR_SIZE);
8343 cvp_set_sound_focus_param_cmd.hdr.src_port =
8344 voice_get_idx_for_session(v->session_id);
8345 cvp_set_sound_focus_param_cmd.hdr.dest_port = cvp_handle;
8346 cvp_set_sound_focus_param_cmd.hdr.token = 0;
8347 cvp_set_sound_focus_param_cmd.hdr.opcode =
8348 VSS_ISOUNDFOCUS_CMD_SET_SECTORS;
8349
8350 memset(&(cvp_set_sound_focus_param_cmd.cvp_set_sound_focus_param), 0xFF,
8351 sizeof(struct vss_isoundfocus_cmd_set_sectors_t));
8352 for (i = 0; i < MAX_SECTORS; i++) {
8353 cvp_set_sound_focus_param_cmd.cvp_set_sound_focus_param.
8354 start_angles[i] = soundFocusData.start_angle[i];
8355 cvp_set_sound_focus_param_cmd.cvp_set_sound_focus_param.
8356 enables[i] = soundFocusData.enable[i];
8357 pr_debug("%s: start_angle[%d] = %d\n",
8358 __func__, i, soundFocusData.start_angle[i]);
8359 pr_debug("%s: enable[%d] = %d\n",
8360 __func__, i, soundFocusData.enable[i]);
8361 }
8362 cvp_set_sound_focus_param_cmd.cvp_set_sound_focus_param.gain_step =
8363 soundFocusData.gain_step;
8364 pr_debug("%s: gain_step = %d\n", __func__, soundFocusData.gain_step);
8365
8366 v->cvp_state = CMD_STATUS_FAIL;
8367 v->async_err = 0;
8368
8369 ret = apr_send_pkt(apr_cvp, (uint32_t *)&cvp_set_sound_focus_param_cmd);
8370 if (ret < 0) {
8371 pr_err("%s: Error in sending APR command\n", __func__);
8372
8373 ret = -EINVAL;
8374 goto done;
8375 }
8376 ret = wait_event_timeout(v->cvp_wait,
8377 (v->cvp_state == CMD_STATUS_SUCCESS),
8378 msecs_to_jiffies(TIMEOUT_MS));
8379 if (!ret) {
8380 pr_err("%s: wait_event timeout\n", __func__);
8381
8382 ret = -EINVAL;
8383 goto done;
8384 }
8385
8386 if (v->async_err > 0) {
8387 pr_err("%s: DSP returned error[%s]\n",
8388 __func__, adsp_err_get_err_str(
8389 v->async_err));
8390 ret = adsp_err_get_lnx_err_code(
8391 v->async_err);
8392 goto done;
8393 }
8394
8395 if (common.is_sound_focus_resp_success) {
8396 ret = 0;
8397 } else {
8398 pr_err("%s: Error in setting sound focus params\n", __func__);
8399
8400 ret = -EINVAL;
8401 }
8402
8403done:
8404 pr_debug("%s: Exit, ret=%d\n", __func__, ret);
8405
8406 return ret;
8407}
8408
8409int voc_set_sound_focus(struct sound_focus_param soundFocusData)
8410{
8411 struct voice_data *v = NULL;
8412 int ret = -EINVAL;
8413 struct voice_session_itr itr;
8414
8415 pr_debug("%s: Enter\n", __func__);
8416
8417 mutex_lock(&common.common_lock);
8418 voice_itr_init(&itr, ALL_SESSION_VSID);
8419 while (voice_itr_get_next_session(&itr, &v)) {
8420 if (v != NULL) {
8421 mutex_lock(&v->lock);
8422 if (is_voc_state_active(v->voc_state) &&
8423 (v->lch_mode != VOICE_LCH_START) &&
8424 !v->disable_topology)
8425 ret = voice_send_set_sound_focus_cmd(v,
8426 soundFocusData);
8427 mutex_unlock(&v->lock);
8428 } else {
8429 pr_err("%s: invalid session\n", __func__);
8430
8431 ret = -EINVAL;
8432 break;
8433 }
8434 }
8435 mutex_unlock(&common.common_lock);
8436 pr_debug("%s: Exit, ret=%d\n", __func__, ret);
8437
8438 return ret;
8439}
8440
8441static int voice_send_get_sound_focus_cmd(struct voice_data *v,
8442 struct sound_focus_param *soundFocusData)
8443{
8444 struct apr_hdr cvp_get_sound_focus_param_cmd;
8445 int ret = 0;
8446 void *apr_cvp;
8447 u16 cvp_handle;
8448 int i;
8449
8450 pr_debug("%s: Enter\n", __func__);
8451
8452 if (!v) {
8453 pr_err("%s: v is NULL\n", __func__);
8454
8455 ret = -EINVAL;
8456 goto done;
8457 }
8458 apr_cvp = common.apr_q6_cvp;
8459
8460 if (!apr_cvp) {
8461 pr_err("%s: apr_cvp is NULL\n", __func__);
8462
8463 ret = -EINVAL;
8464 goto done;
8465 }
8466
8467 cvp_handle = voice_get_cvp_handle(v);
8468
8469 /* send APR command to retrieve Sound Focus Params */
8470 cvp_get_sound_focus_param_cmd.hdr_field =
8471 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
8472 APR_HDR_LEN(APR_HDR_SIZE),
8473 APR_PKT_VER);
8474 cvp_get_sound_focus_param_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
8475 sizeof(cvp_get_sound_focus_param_cmd) - APR_HDR_SIZE);
8476 cvp_get_sound_focus_param_cmd.src_port =
8477 voice_get_idx_for_session(v->session_id);
8478 cvp_get_sound_focus_param_cmd.dest_port = cvp_handle;
8479 cvp_get_sound_focus_param_cmd.token = 0;
8480 cvp_get_sound_focus_param_cmd.opcode = VSS_ISOUNDFOCUS_CMD_GET_SECTORS;
8481
8482 v->cvp_state = CMD_STATUS_FAIL;
8483 v->async_err = 0;
8484 ret = apr_send_pkt(apr_cvp, (uint32_t *)&cvp_get_sound_focus_param_cmd);
8485 if (ret < 0) {
8486 pr_err("%s: Error in sending APR command\n", __func__);
8487
8488 ret = -EINVAL;
8489 goto done;
8490 }
8491 ret = wait_event_timeout(v->cvp_wait,
8492 (v->cvp_state == CMD_STATUS_SUCCESS),
8493 msecs_to_jiffies(TIMEOUT_MS));
8494 if (!ret) {
8495 pr_err("%s: wait_event timeout\n", __func__);
8496
8497 ret = -EINVAL;
8498 goto done;
8499 }
8500
8501 if (v->async_err > 0) {
8502 pr_err("%s: DSP returned error[%s]\n",
8503 __func__, adsp_err_get_err_str(
8504 v->async_err));
8505 ret = adsp_err_get_lnx_err_code(
8506 v->async_err);
8507 goto done;
8508 }
8509
8510 if (common.is_sound_focus_resp_success) {
8511 for (i = 0; i < MAX_SECTORS; i++) {
8512 soundFocusData->start_angle[i] =
8513 common.soundFocusResponse.start_angles[i];
8514 soundFocusData->enable[i] =
8515 common.soundFocusResponse.enables[i];
8516 pr_debug("%s: start_angle[%d] = %d\n",
8517 __func__, i, soundFocusData->start_angle[i]);
8518 pr_debug("%s: enable[%d] = %d\n",
8519 __func__, i, soundFocusData->enable[i]);
8520 }
8521 soundFocusData->gain_step = common.soundFocusResponse.gain_step;
8522 pr_debug("%s: gain_step = %d\n", __func__,
8523 soundFocusData->gain_step);
8524
8525 common.is_sound_focus_resp_success = false;
8526 ret = 0;
8527 } else {
8528 pr_err("%s: Invalid payload received from CVD\n", __func__);
8529
8530 ret = -EINVAL;
8531 }
8532done:
8533 pr_debug("%s: Exit, ret=%d\n", __func__, ret);
8534
8535 return ret;
8536}
8537
8538int voc_get_sound_focus(struct sound_focus_param *soundFocusData)
8539{
8540 struct voice_data *v = NULL;
8541 int ret = -EINVAL;
8542 struct voice_session_itr itr;
8543
8544 pr_debug("%s: Enter\n", __func__);
8545
8546 mutex_lock(&common.common_lock);
8547 voice_itr_init(&itr, ALL_SESSION_VSID);
8548 while (voice_itr_get_next_session(&itr, &v)) {
8549 if (v) {
8550 mutex_lock(&v->lock);
8551 if (is_voc_state_active(v->voc_state) &&
8552 (v->lch_mode != VOICE_LCH_START) &&
8553 !v->disable_topology)
8554 ret = voice_send_get_sound_focus_cmd(v,
8555 soundFocusData);
8556 mutex_unlock(&v->lock);
8557 } else {
8558 pr_err("%s: invalid session\n", __func__);
8559
8560 ret = -EINVAL;
8561 break;
8562 }
8563 }
8564 mutex_unlock(&common.common_lock);
8565 pr_debug("%s: Exit, ret=%d\n", __func__, ret);
8566
8567 return ret;
8568}
8569
8570static int is_source_tracking_shared_memomry_allocated(void)
8571{
8572 bool ret;
8573
8574 pr_debug("%s: Enter\n", __func__);
8575
8576 if (common.source_tracking_sh_mem.sh_mem_block.client != NULL &&
8577 common.source_tracking_sh_mem.sh_mem_block.handle != NULL)
8578 ret = true;
8579 else
8580 ret = false;
8581
8582 pr_debug("%s: Exit\n", __func__);
8583
8584 return ret;
8585}
8586
8587static int voice_alloc_source_tracking_shared_memory(void)
8588{
8589 int ret = 0;
8590
8591 pr_debug("%s: Enter\n", __func__);
8592
8593 ret = msm_audio_ion_alloc("source_tracking_sh_mem_block",
8594 &(common.source_tracking_sh_mem.sh_mem_block.client),
8595 &(common.source_tracking_sh_mem.sh_mem_block.handle),
8596 BUFFER_BLOCK_SIZE,
8597 &(common.source_tracking_sh_mem.sh_mem_block.phys),
8598 (size_t *)&(common.source_tracking_sh_mem.sh_mem_block.size),
8599 &(common.source_tracking_sh_mem.sh_mem_block.data));
8600 if (ret < 0) {
8601 pr_err("%s: audio ION alloc failed for sh_mem block, ret = %d\n",
8602 __func__, ret);
8603
8604 ret = -EINVAL;
8605 goto done;
8606 }
8607 memset((void *)(common.source_tracking_sh_mem.sh_mem_block.data), 0,
8608 common.source_tracking_sh_mem.sh_mem_block.size);
8609
8610 pr_debug("%s: sh_mem_block: phys:[%pK], data:[0x%pK], size:[%zd]\n",
8611 __func__,
8612 &(common.source_tracking_sh_mem.sh_mem_block.phys),
8613 (void *)(common.source_tracking_sh_mem.sh_mem_block.data),
8614 (size_t)(common.source_tracking_sh_mem.sh_mem_block.size));
8615
8616 ret = msm_audio_ion_alloc("source_tracking_sh_mem_table",
8617 &(common.source_tracking_sh_mem.sh_mem_table.client),
8618 &(common.source_tracking_sh_mem.sh_mem_table.handle),
8619 sizeof(struct vss_imemory_table_t),
8620 &(common.source_tracking_sh_mem.sh_mem_table.phys),
8621 (size_t *)&(common.source_tracking_sh_mem.sh_mem_table.size),
8622 &(common.source_tracking_sh_mem.sh_mem_table.data));
8623 if (ret < 0) {
8624 pr_err("%s: audio ION alloc failed for sh_mem table, ret = %d\n",
8625 __func__, ret);
8626
8627 ret = msm_audio_ion_free(
8628 common.source_tracking_sh_mem.sh_mem_block.client,
8629 common.source_tracking_sh_mem.sh_mem_block.handle);
8630 common.source_tracking_sh_mem.sh_mem_block.client = NULL;
8631 common.source_tracking_sh_mem.sh_mem_block.handle = NULL;
8632 if (ret < 0)
8633 pr_err("%s: Error:%d freeing memory\n", __func__, ret);
8634
8635 ret = -EINVAL;
8636 goto done;
8637 }
8638 memset((void *)(common.source_tracking_sh_mem.sh_mem_table.data), 0,
8639 common.source_tracking_sh_mem.sh_mem_table.size);
8640
8641 pr_debug("%s sh_mem_table: phys:[%pK], data:[0x%pK], size:[%zd],\n",
8642 __func__,
8643 &(common.source_tracking_sh_mem.sh_mem_table.phys),
8644 (void *)(common.source_tracking_sh_mem.sh_mem_table.data),
8645 (size_t)(common.source_tracking_sh_mem.sh_mem_table.size));
8646
8647done:
8648 pr_debug("%s: Exit, ret=%d\n", __func__, ret);
8649
8650 return ret;
8651}
8652
8653static int voice_alloc_and_map_source_tracking_shared_memory(
8654 struct voice_data *v)
8655{
8656 int ret = 0;
8657
8658 pr_debug("%s: Enter\n", __func__);
8659
8660 ret = voice_alloc_source_tracking_shared_memory();
8661 if (ret) {
8662 pr_err("%s: Failed to allocate shared memory %d\n",
8663 __func__, ret);
8664
8665 ret = -EINVAL;
8666 goto done;
8667 }
8668
8669 ret = voice_map_memory_physical_cmd(v,
8670 &(common.source_tracking_sh_mem.sh_mem_table),
8671 common.source_tracking_sh_mem.sh_mem_block.phys,
8672 common.source_tracking_sh_mem.sh_mem_block.size,
8673 VOC_SOURCE_TRACKING_MEM_MAP_TOKEN);
8674 if (ret) {
8675 pr_err("%s: memory mapping failed %d\n",
8676 __func__, ret);
8677
8678 ret = -EINVAL;
8679 goto done;
8680 }
8681
8682done:
8683 pr_debug("%s: Exit, ret=%d\n", __func__, ret);
8684
8685 return ret;
8686}
8687
8688static int voice_unmap_and_free_source_tracking_shared_memory(
8689 struct voice_data *v)
8690{
8691 int ret = 0;
8692
8693 pr_debug("%s: Enter\n", __func__);
8694
8695 if (common.source_tracking_sh_mem.mem_handle != 0) {
8696 ret = voice_send_mvm_unmap_memory_physical_cmd(v,
8697 common.source_tracking_sh_mem.mem_handle);
8698 if (ret < 0) {
8699 pr_err("%s: Memory_unmap failed err %d\n",
8700 __func__, ret);
8701
8702 ret = -EINVAL;
8703 goto done;
8704 }
8705 }
8706
8707 if ((common.source_tracking_sh_mem.sh_mem_block.client == NULL) ||
8708 (common.source_tracking_sh_mem.sh_mem_block.handle == NULL))
8709 goto done;
8710
8711 ret = msm_audio_ion_free(
8712 common.source_tracking_sh_mem.sh_mem_block.client,
8713 common.source_tracking_sh_mem.sh_mem_block.handle);
8714 if (ret < 0) {
8715 pr_err("%s: Error:%d freeing memory\n", __func__, ret);
8716
8717 ret = -EINVAL;
8718 goto done;
8719 }
8720
8721done:
8722 common.source_tracking_sh_mem.mem_handle = 0;
8723 common.source_tracking_sh_mem.sh_mem_block.client = NULL;
8724 common.source_tracking_sh_mem.sh_mem_block.handle = NULL;
8725 pr_debug("%s: Exit, ret=%d\n", __func__, ret);
8726
8727 return ret;
8728}
8729
8730static int voice_send_get_source_tracking_cmd(struct voice_data *v,
8731 struct source_tracking_param *sourceTrackingData)
8732{
8733 struct cvp_get_source_tracking_param_cmd_t st_cmd;
8734 int ret = 0;
8735 void *apr_cvp;
8736 u16 cvp_handle;
8737 int i;
8738
8739 pr_debug("%s: Enter\n", __func__);
8740
8741 if (!v) {
8742 pr_err("%s: v is NULL\n", __func__);
8743 return -EINVAL;
8744 }
8745 apr_cvp = common.apr_q6_cvp;
8746
8747 if (!apr_cvp) {
8748 pr_err("%s: apr_cvp is NULL.\n", __func__);
8749 return -EINVAL;
8750 }
8751
8752 cvp_handle = voice_get_cvp_handle(v);
8753
8754 if (!is_source_tracking_shared_memomry_allocated()) {
8755 ret = voice_alloc_and_map_source_tracking_shared_memory(v);
8756 if (ret) {
8757 pr_err("%s: Fail in allocating/mapping shared memory\n",
8758 __func__);
8759
8760 ret = -EINVAL;
8761 goto done;
8762 }
8763 }
8764 st_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
8765 APR_HDR_LEN(APR_HDR_SIZE),
8766 APR_PKT_VER);
8767 st_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
8768 sizeof(st_cmd) - APR_HDR_SIZE);
8769 st_cmd.hdr.src_port = voice_get_idx_for_session(v->session_id);
8770 st_cmd.hdr.dest_port = cvp_handle;
8771 st_cmd.hdr.token = 0;
8772 st_cmd.hdr.opcode = VSS_ISOURCETRACK_CMD_GET_ACTIVITY;
8773
8774 st_cmd.cvp_get_source_tracking_param.mem_handle =
8775 common.source_tracking_sh_mem.mem_handle;
8776 st_cmd.cvp_get_source_tracking_param.mem_address_lsw =
8777 lower_32_bits(common.source_tracking_sh_mem.sh_mem_block.phys);
8778 st_cmd.cvp_get_source_tracking_param.mem_address_msw =
8779 msm_audio_populate_upper_32_bits(common.source_tracking_sh_mem.
8780 sh_mem_block.phys);
8781 st_cmd.cvp_get_source_tracking_param.mem_size =
8782 (uint32_t)common.source_tracking_sh_mem.sh_mem_block.size;
8783 pr_debug("%s: mem_handle=0x%x, mem_address_lsw=0x%x, msw=0x%x, mem_size=%d\n",
8784 __func__,
8785 st_cmd.cvp_get_source_tracking_param.mem_handle,
8786 st_cmd.cvp_get_source_tracking_param.mem_address_lsw,
8787 st_cmd.cvp_get_source_tracking_param.mem_address_msw,
8788 (uint32_t)st_cmd.cvp_get_source_tracking_param.mem_size);
8789
8790 v->cvp_state = CMD_STATUS_FAIL;
8791 v->async_err = 0;
8792 ret = apr_send_pkt(apr_cvp,
8793 (uint32_t *) &st_cmd);
8794 if (ret < 0) {
8795 pr_err("%s: Error in sending APR command\n", __func__);
8796
8797 ret = -EINVAL;
8798 goto done;
8799 }
8800 ret = wait_event_timeout(v->cvp_wait,
8801 (v->cvp_state == CMD_STATUS_SUCCESS),
8802 msecs_to_jiffies(TIMEOUT_MS));
8803 if (!ret) {
8804 pr_err("%s: wait_event timeout\n", __func__);
8805
8806 ret = -EINVAL;
8807 goto done;
8808 }
8809
8810 if (v->async_err > 0) {
8811 pr_err("%s: DSP returned error[%s]\n",
8812 __func__, adsp_err_get_err_str(
8813 v->async_err));
8814 ret = adsp_err_get_lnx_err_code(
8815 v->async_err);
8816 goto done;
8817 }
8818
8819 if (common.is_source_tracking_resp_success) {
8820 for (i = 0; i < MAX_SECTORS; i++) {
8821 sourceTrackingData->vad[i] =
8822 common.sourceTrackingResponse.voice_active[i];
8823 pr_debug("%s: vad[%d] = %d\n",
8824 __func__, i, sourceTrackingData->vad[i]);
8825 }
8826 sourceTrackingData->doa_speech =
8827 common.sourceTrackingResponse.talker_doa;
8828 pr_debug("%s: doa_speech = %d\n",
8829 __func__, sourceTrackingData->doa_speech);
8830
8831 for (i = 0; i < MAX_NOISE_SOURCE_INDICATORS; i++) {
8832 sourceTrackingData->doa_noise[i] =
8833 common.sourceTrackingResponse.interferer_doa[i];
8834 pr_debug("%s: doa_noise[%d] = %d\n",
8835 __func__, i, sourceTrackingData->doa_noise[i]);
8836 }
8837 for (i = 0; i < MAX_POLAR_ACTIVITY_INDICATORS; i++) {
8838 sourceTrackingData->polar_activity[i] =
8839 common.sourceTrackingResponse.sound_strength[i];
8840 pr_debug("%s: polar_activity[%d] = %d\n",
8841 __func__, i, sourceTrackingData->polar_activity[i]);
8842 }
8843 common.is_source_tracking_resp_success = false;
8844 ret = 0;
8845 } else {
8846 pr_err("%s: Error response received from CVD\n", __func__);
8847
8848 ret = -EINVAL;
8849 }
8850done:
8851 pr_debug("%s: Exit, ret=%d\n", __func__, ret);
8852
8853 return ret;
8854}
8855
8856int voc_get_source_tracking(struct source_tracking_param *sourceTrackingData)
8857{
8858 struct voice_data *v = NULL;
8859 int ret = -EINVAL;
8860 struct voice_session_itr itr;
8861
8862 pr_debug("%s: Enter\n", __func__);
8863
8864 mutex_lock(&common.common_lock);
8865
8866 voice_itr_init(&itr, ALL_SESSION_VSID);
8867 while (voice_itr_get_next_session(&itr, &v)) {
8868 if (v != NULL) {
8869 mutex_lock(&v->lock);
8870 if (is_voc_state_active(v->voc_state) &&
8871 (v->lch_mode != VOICE_LCH_START) &&
8872 !v->disable_topology)
8873 ret = voice_send_get_source_tracking_cmd(v,
8874 sourceTrackingData);
8875 mutex_unlock(&v->lock);
8876 } else {
8877 pr_err("%s: invalid session\n", __func__);
8878
8879 break;
8880 }
8881 }
8882
8883 mutex_unlock(&common.common_lock);
8884 pr_debug("%s: Exit, ret=%d\n", __func__, ret);
8885
8886 return ret;
8887}
8888
8889int is_voc_initialized(void)
8890{
8891 return module_initialized;
8892}
8893
8894static int __init voice_init(void)
8895{
8896 int rc = 0, i = 0;
8897
8898 memset(&common, 0, sizeof(struct common_data));
8899
8900 /* set default value */
8901 common.default_mute_val = 0; /* default is un-mute */
8902 common.default_sample_val = 8000;
8903 common.default_vol_step_val = 0;
8904 common.default_vol_ramp_duration_ms = DEFAULT_VOLUME_RAMP_DURATION;
8905 common.default_mute_ramp_duration_ms = DEFAULT_MUTE_RAMP_DURATION;
Laxminath Kasam38070be2017-08-17 18:21:59 +05308906 common.cvp_version = 0;
8907 common.is_avcs_version_queried = false;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308908 /* Initialize EC Ref media format info */
8909 common.ec_ref_ext = false;
8910 common.ec_media_fmt_info.port_id = AFE_PORT_INVALID;
8911 common.ec_media_fmt_info.num_channels = 0;
8912 common.ec_media_fmt_info.bits_per_sample = 16;
8913 common.ec_media_fmt_info.sample_rate = 8000;
8914 memset(&common.ec_media_fmt_info.channel_mapping, 0,
8915 VSS_CHANNEL_MAPPING_SIZE);
8916
8917 /* Initialize AFE Sidetone Enable */
8918 common.sidetone_enable = false;
8919
8920 /* Initialize MVS info. */
8921 common.mvs_info.network_type = VSS_NETWORK_ID_DEFAULT;
8922
8923 /* Initialize is low memory flag */
8924 common.is_destroy_cvd = false;
8925
8926 /* Initialize CVD version */
8927 strlcpy(common.cvd_version, CVD_VERSION_DEFAULT,
8928 sizeof(common.cvd_version));
8929 /* Initialize Per-Vocoder Calibration flag */
8930 common.is_per_vocoder_cal_enabled = false;
8931
8932 mutex_init(&common.common_lock);
8933
8934 /* Initialize session id with vsid */
8935 init_session_id();
8936
8937 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
8938
8939 /* initialize dev_rx and dev_tx */
8940 common.voice[i].dev_rx.dev_mute = common.default_mute_val;
8941 common.voice[i].dev_tx.dev_mute = common.default_mute_val;
8942 common.voice[i].dev_rx.volume_step_value =
8943 common.default_vol_step_val;
8944 common.voice[i].dev_rx.volume_ramp_duration_ms =
8945 common.default_vol_ramp_duration_ms;
8946 common.voice[i].dev_rx.dev_mute_ramp_duration_ms =
8947 common.default_mute_ramp_duration_ms;
8948 common.voice[i].dev_tx.dev_mute_ramp_duration_ms =
8949 common.default_mute_ramp_duration_ms;
8950 common.voice[i].stream_rx.stream_mute = common.default_mute_val;
8951 common.voice[i].stream_tx.stream_mute = common.default_mute_val;
8952
8953 common.voice[i].dev_tx.port_id = 0x100B;
8954 common.voice[i].dev_rx.port_id = 0x100A;
8955 common.voice[i].dev_tx.dev_id = 0;
8956 common.voice[i].dev_rx.dev_id = 0;
8957 common.voice[i].dev_tx.no_of_channels = 0;
8958 common.voice[i].dev_rx.no_of_channels = 0;
8959 common.voice[i].dev_tx.sample_rate = 8000;
8960 common.voice[i].dev_rx.sample_rate = 8000;
8961 common.voice[i].dev_tx.bits_per_sample = 16;
8962 common.voice[i].dev_rx.bits_per_sample = 16;
8963 memset(&common.voice[i].dev_tx.channel_mapping, 0,
8964 VSS_CHANNEL_MAPPING_SIZE);
8965 memset(&common.voice[i].dev_rx.channel_mapping, 0,
8966 VSS_CHANNEL_MAPPING_SIZE);
8967 common.voice[i].sidetone_gain = 0x512;
8968 common.voice[i].dtmf_rx_detect_en = 0;
8969 common.voice[i].lch_mode = 0;
8970 common.voice[i].disable_topology = false;
8971
8972 common.voice[i].voc_state = VOC_INIT;
8973
8974 init_waitqueue_head(&common.voice[i].mvm_wait);
8975 init_waitqueue_head(&common.voice[i].cvs_wait);
8976 init_waitqueue_head(&common.voice[i].cvp_wait);
8977
8978 mutex_init(&common.voice[i].lock);
8979 }
8980
8981 if (voice_init_cal_data())
8982 pr_err("%s: Could not init cal data!\n", __func__);
8983
8984 if (rc == 0)
8985 module_initialized = true;
8986
8987 pr_debug("%s: rc=%d\n", __func__, rc);
8988 return rc;
8989}
8990
8991device_initcall(voice_init);
8992
8993static void __exit voice_exit(void)
8994{
8995 voice_delete_cal_data();
8996 free_cal_map_table();
8997}
8998
8999__exitcall(voice_exit);