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