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