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