blob: 983e0a2388cab200a2caf5af8851bc56cdb2440c [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
Aditya Bavanari88513a32017-10-12 12:29:25 +05302371 voice_set_topology_specific_info(v, CVP_VOC_RX_TOPOLOGY_CAL);
2372 voice_set_topology_specific_info(v, CVP_VOC_TX_TOPOLOGY_CAL);
2373
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302374 cvp_setdev_cmd.cvp_set_device_v2.tx_port_id = v->dev_tx.port_id;
2375 cvp_setdev_cmd.cvp_set_device_v2.rx_port_id = v->dev_rx.port_id;
2376
2377 if (common.ec_ref_ext) {
2378 cvp_setdev_cmd.cvp_set_device_v2.vocproc_mode =
2379 VSS_IVOCPROC_VOCPROC_MODE_EC_EXT_MIXING;
2380 cvp_setdev_cmd.cvp_set_device_v2.ec_ref_port_id =
2381 common.ec_media_fmt_info.port_id;
2382 } else {
2383 cvp_setdev_cmd.cvp_set_device_v2.vocproc_mode =
2384 VSS_IVOCPROC_VOCPROC_MODE_EC_INT_MIXING;
2385 cvp_setdev_cmd.cvp_set_device_v2.ec_ref_port_id =
2386 VSS_IVOCPROC_PORT_ID_NONE;
2387 }
2388 pr_debug("topology=%d , tx_port_id=%d, rx_port_id=%d\n",
2389 cvp_setdev_cmd.cvp_set_device_v2.tx_topology_id,
2390 cvp_setdev_cmd.cvp_set_device_v2.tx_port_id,
2391 cvp_setdev_cmd.cvp_set_device_v2.rx_port_id);
2392
2393 v->cvp_state = CMD_STATUS_FAIL;
2394 v->async_err = 0;
2395 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_setdev_cmd);
2396 if (ret < 0) {
2397 pr_err("Fail in sending VSS_IVOCPROC_CMD_SET_DEVICE\n");
2398 goto fail;
2399 }
2400
2401 ret = wait_event_timeout(v->cvp_wait,
2402 (v->cvp_state == CMD_STATUS_SUCCESS),
2403 msecs_to_jiffies(TIMEOUT_MS));
2404 if (!ret) {
2405 pr_err("%s: wait_event timeout\n", __func__);
2406 goto fail;
2407 }
2408 if (v->async_err > 0) {
2409 pr_err("%s: DSP returned error[%s]\n",
2410 __func__, adsp_err_get_err_str(
2411 v->async_err));
2412 ret = adsp_err_get_lnx_err_code(
2413 v->async_err);
2414 goto fail;
2415 }
2416
2417 return 0;
2418fail:
2419 return ret;
2420}
2421
2422static int voice_send_stop_voice_cmd(struct voice_data *v)
2423{
2424 struct apr_hdr mvm_stop_voice_cmd;
2425 int ret = 0;
2426 void *apr_mvm;
2427 u16 mvm_handle;
2428
2429 if (v == NULL) {
2430 pr_err("%s: v is NULL\n", __func__);
2431 return -EINVAL;
2432 }
2433 apr_mvm = common.apr_q6_mvm;
2434
2435 if (!apr_mvm) {
2436 pr_err("%s: apr_mvm is NULL.\n", __func__);
2437 return -EINVAL;
2438 }
2439 mvm_handle = voice_get_mvm_handle(v);
2440
2441 mvm_stop_voice_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2442 APR_HDR_LEN(APR_HDR_SIZE),
2443 APR_PKT_VER);
2444 mvm_stop_voice_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2445 sizeof(mvm_stop_voice_cmd) - APR_HDR_SIZE);
2446 pr_debug("send mvm_stop_voice_cmd pkt size = %d\n",
2447 mvm_stop_voice_cmd.pkt_size);
2448 mvm_stop_voice_cmd.src_port =
2449 voice_get_idx_for_session(v->session_id);
2450 mvm_stop_voice_cmd.dest_port = mvm_handle;
2451 mvm_stop_voice_cmd.token = 0;
2452 mvm_stop_voice_cmd.opcode = VSS_IMVM_CMD_STOP_VOICE;
2453
2454 v->mvm_state = CMD_STATUS_FAIL;
2455 v->async_err = 0;
2456 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_stop_voice_cmd);
2457 if (ret < 0) {
2458 pr_err("Fail in sending VSS_IMVM_CMD_STOP_VOICE\n");
2459 goto fail;
2460 }
2461 ret = wait_event_timeout(v->mvm_wait,
2462 (v->mvm_state == CMD_STATUS_SUCCESS),
2463 msecs_to_jiffies(TIMEOUT_MS));
2464 if (!ret) {
2465 pr_err("%s: wait_event timeout\n", __func__);
2466 goto fail;
2467 }
2468 if (v->async_err > 0) {
2469 pr_err("%s: DSP returned error[%s]\n",
2470 __func__, adsp_err_get_err_str(
2471 v->async_err));
2472 ret = adsp_err_get_lnx_err_code(
2473 v->async_err);
2474 goto fail;
2475 }
2476
2477 return 0;
2478fail:
2479 return ret;
2480}
2481static int voice_get_cal(struct cal_block_data **cal_block,
2482 int cal_block_idx,
2483 struct cal_block_data **col_data,
2484 int col_data_idx, int session_id)
2485{
2486 int ret = 0;
2487
2488 *cal_block = cal_utils_get_only_cal_block(
2489 common.cal_data[cal_block_idx]);
2490 if (*cal_block == NULL) {
2491 pr_err("%s: No cal data for cal %d!\n",
2492 __func__, cal_block_idx);
2493
2494 ret = -ENODEV;
2495 goto done;
2496 }
2497 ret = remap_cal_data(*cal_block, session_id);
2498 if (ret < 0) {
2499 pr_err("%s: Remap_cal_data failed for cal %d!\n",
2500 __func__, cal_block_idx);
2501
2502 ret = -ENODEV;
2503 goto done;
2504 }
2505
2506 if (col_data == NULL)
2507 goto done;
2508
2509 *col_data = cal_utils_get_only_cal_block(
2510 common.cal_data[col_data_idx]);
2511 if (*col_data == NULL) {
2512 pr_err("%s: No cal data for cal %d!\n",
2513 __func__, col_data_idx);
2514
2515 ret = -ENODEV;
2516 goto done;
2517 }
2518done:
2519 return ret;
2520}
2521
2522static int voice_send_cvs_register_cal_cmd(struct voice_data *v)
2523{
2524 struct cvs_register_cal_data_cmd cvs_reg_cal_cmd;
2525 struct cal_block_data *cal_block = NULL;
2526 struct cal_block_data *col_data = NULL;
2527 int ret = 0;
2528
2529 memset(&cvs_reg_cal_cmd, 0, sizeof(cvs_reg_cal_cmd));
2530
2531 if (v == NULL) {
2532 pr_err("%s: v is NULL\n", __func__);
2533
2534 ret = -EINVAL;
2535 goto done;
2536 }
2537
2538 if (!common.apr_q6_cvs) {
2539 pr_err("%s: apr_cvs is NULL\n", __func__);
2540
2541 ret = -EINVAL;
2542 goto done;
2543 }
2544
2545 mutex_lock(&common.cal_data[CVS_VOCSTRM_CAL]->lock);
2546 mutex_lock(&common.cal_data[CVS_VOCSTRM_COL_CAL]->lock);
2547
2548 ret = voice_get_cal(&cal_block, CVS_VOCSTRM_CAL, &col_data,
2549 CVS_VOCSTRM_COL_CAL, v->session_id);
2550 if (ret < 0) {
2551 pr_err("%s: Voice_get_cal failed for cal %d!\n",
2552 __func__, CVS_VOCSTRM_CAL);
2553
2554 goto unlock;
2555 }
2556
2557 memcpy(&cvs_reg_cal_cmd.cvs_cal_data.column_info[0],
2558 (void *) &((struct audio_cal_info_voc_col *)
2559 col_data->cal_info)->data,
2560 col_data->cal_data.size);
2561
2562 cvs_reg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2563 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2564 cvs_reg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2565 sizeof(cvs_reg_cal_cmd) - APR_HDR_SIZE);
2566 cvs_reg_cal_cmd.hdr.src_port =
2567 voice_get_idx_for_session(v->session_id);
2568 cvs_reg_cal_cmd.hdr.dest_port = voice_get_cvs_handle(v);
2569 cvs_reg_cal_cmd.hdr.token = 0;
2570 if (common.is_per_vocoder_cal_enabled)
2571 cvs_reg_cal_cmd.hdr.opcode =
2572 VSS_ISTREAM_CMD_REGISTER_STATIC_CALIBRATION_DATA;
2573 else
2574 cvs_reg_cal_cmd.hdr.opcode =
2575 VSS_ISTREAM_CMD_REGISTER_CALIBRATION_DATA_V2;
2576
2577 cvs_reg_cal_cmd.cvs_cal_data.cal_mem_handle =
2578 cal_block->map_data.q6map_handle;
2579 cvs_reg_cal_cmd.cvs_cal_data.cal_mem_address_lsw =
2580 lower_32_bits(cal_block->cal_data.paddr);
2581 cvs_reg_cal_cmd.cvs_cal_data.cal_mem_address_msw =
2582 msm_audio_populate_upper_32_bits(cal_block->cal_data.paddr);
2583 cvs_reg_cal_cmd.cvs_cal_data.cal_mem_size =
2584 cal_block->cal_data.size;
2585
2586 v->cvs_state = CMD_STATUS_FAIL;
2587 v->async_err = 0;
2588 ret = apr_send_pkt(common.apr_q6_cvs, (uint32_t *) &cvs_reg_cal_cmd);
2589 if (ret < 0) {
2590 pr_err("%s: Error %d registering CVS cal\n", __func__, ret);
2591
2592 ret = -EINVAL;
2593 goto unlock;
2594 }
2595 ret = wait_event_timeout(v->cvs_wait,
2596 (v->cvs_state == CMD_STATUS_SUCCESS),
2597 msecs_to_jiffies(TIMEOUT_MS));
2598 if (!ret) {
2599 pr_err("%s: Command timeout\n", __func__);
2600
2601 ret = -EINVAL;
2602 goto unlock;
2603 }
2604 if (v->async_err > 0) {
2605 pr_err("%s: DSP returned error[%s]\n",
2606 __func__, adsp_err_get_err_str(
2607 v->async_err));
2608 ret = adsp_err_get_lnx_err_code(
2609 v->async_err);
2610 goto unlock;
2611 }
2612unlock:
2613 mutex_unlock(&common.cal_data[CVS_VOCSTRM_COL_CAL]->lock);
2614 mutex_unlock(&common.cal_data[CVS_VOCSTRM_CAL]->lock);
2615done:
2616 return ret;
2617}
2618
2619static int voice_send_cvs_deregister_cal_cmd(struct voice_data *v)
2620{
2621 struct cvs_deregister_cal_data_cmd cvs_dereg_cal_cmd;
2622 int ret = 0;
2623
2624 memset(&cvs_dereg_cal_cmd, 0, sizeof(cvs_dereg_cal_cmd));
2625
2626 if (v == NULL) {
2627 pr_err("%s: v is NULL\n", __func__);
2628
2629 ret = -EINVAL;
2630 goto done;
2631 }
2632
2633 if (!common.apr_q6_cvs) {
2634 pr_err("%s: apr_cvs is NULL\n", __func__);
2635
2636 ret = -EPERM;
2637 goto done;
2638 }
2639
2640 cvs_dereg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2641 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2642 cvs_dereg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2643 sizeof(cvs_dereg_cal_cmd) - APR_HDR_SIZE);
2644 cvs_dereg_cal_cmd.hdr.src_port =
2645 voice_get_idx_for_session(v->session_id);
2646 cvs_dereg_cal_cmd.hdr.dest_port = voice_get_cvs_handle(v);
2647 cvs_dereg_cal_cmd.hdr.token = 0;
2648 if (common.is_per_vocoder_cal_enabled)
2649 cvs_dereg_cal_cmd.hdr.opcode =
2650 VSS_ISTREAM_CMD_DEREGISTER_STATIC_CALIBRATION_DATA;
2651 else
2652 cvs_dereg_cal_cmd.hdr.opcode =
2653 VSS_ISTREAM_CMD_DEREGISTER_CALIBRATION_DATA;
2654
2655 v->cvs_state = CMD_STATUS_FAIL;
2656 v->async_err = 0;
2657 ret = apr_send_pkt(common.apr_q6_cvs, (uint32_t *) &cvs_dereg_cal_cmd);
2658 if (ret < 0) {
2659 pr_err("%s: Error %d de-registering CVS cal\n", __func__, ret);
2660 goto done;
2661 }
2662 ret = wait_event_timeout(v->cvs_wait,
2663 (v->cvs_state == CMD_STATUS_SUCCESS),
2664 msecs_to_jiffies(TIMEOUT_MS));
2665 if (!ret) {
2666 pr_err("%s: Command timeout\n", __func__);
2667 goto done;
2668 }
2669 if (v->async_err > 0) {
2670 pr_err("%s: DSP returned error[%s]\n",
2671 __func__, adsp_err_get_err_str(
2672 v->async_err));
2673 ret = adsp_err_get_lnx_err_code(
2674 v->async_err);
2675 goto done;
2676 }
2677
2678done:
2679 return ret;
2680
2681}
2682
2683static int voice_send_cvp_create_cmd(struct voice_data *v)
2684{
2685 struct cvp_create_full_ctl_session_cmd cvp_session_cmd;
2686 void *apr_cvp;
2687 int ret = 0;
2688
2689 if (v == NULL) {
2690 pr_err("%s: v is NULL\n", __func__);
2691 ret = -EINVAL;
2692 goto done;
2693 }
2694
2695 apr_cvp = common.apr_q6_cvp;
2696 if (!apr_cvp) {
2697 pr_err("%s: apr_cvp is NULL.\n", __func__);
2698
2699 ret = -EINVAL;
2700 goto done;
2701 }
2702
2703 /* create cvp session and wait for response */
2704 cvp_session_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2705 APR_HDR_LEN(APR_HDR_SIZE),
2706 APR_PKT_VER);
2707 cvp_session_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2708 sizeof(cvp_session_cmd) - APR_HDR_SIZE);
2709 pr_debug("%s: send create cvp session, pkt size = %d\n",
2710 __func__, cvp_session_cmd.hdr.pkt_size);
2711 cvp_session_cmd.hdr.src_port =
2712 voice_get_idx_for_session(v->session_id);
2713 cvp_session_cmd.hdr.dest_port = 0;
2714 cvp_session_cmd.hdr.token = 0;
2715
2716 if (voice_get_cvd_int_version(common.cvd_version) >=
2717 CVD_INT_VERSION_2_2)
2718 cvp_session_cmd.hdr.opcode =
2719 VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION_V3;
2720 else
2721 cvp_session_cmd.hdr.opcode =
2722 VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION_V2;
2723
2724 voc_get_tx_rx_topology(v,
2725 &cvp_session_cmd.cvp_session.tx_topology_id,
2726 &cvp_session_cmd.cvp_session.rx_topology_id);
2727
Aditya Bavanari88513a32017-10-12 12:29:25 +05302728 voice_set_topology_specific_info(v, CVP_VOC_RX_TOPOLOGY_CAL);
2729 voice_set_topology_specific_info(v, CVP_VOC_TX_TOPOLOGY_CAL);
2730
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302731 cvp_session_cmd.cvp_session.direction = 2; /*tx and rx*/
2732 cvp_session_cmd.cvp_session.tx_port_id = v->dev_tx.port_id;
2733 cvp_session_cmd.cvp_session.rx_port_id = v->dev_rx.port_id;
2734 cvp_session_cmd.cvp_session.profile_id =
2735 VSS_ICOMMON_CAL_NETWORK_ID_NONE;
2736 if (common.ec_ref_ext) {
2737 cvp_session_cmd.cvp_session.vocproc_mode =
2738 VSS_IVOCPROC_VOCPROC_MODE_EC_EXT_MIXING;
2739 cvp_session_cmd.cvp_session.ec_ref_port_id =
2740 common.ec_media_fmt_info.port_id;
2741 } else {
2742 cvp_session_cmd.cvp_session.vocproc_mode =
2743 VSS_IVOCPROC_VOCPROC_MODE_EC_INT_MIXING;
2744 cvp_session_cmd.cvp_session.ec_ref_port_id =
2745 VSS_IVOCPROC_PORT_ID_NONE;
2746 }
2747
2748 pr_debug("tx_topology: %d tx_port_id=%d, rx_port_id=%d, mode: 0x%x\n",
2749 cvp_session_cmd.cvp_session.tx_topology_id,
2750 cvp_session_cmd.cvp_session.tx_port_id,
2751 cvp_session_cmd.cvp_session.rx_port_id,
2752 cvp_session_cmd.cvp_session.vocproc_mode);
2753 pr_debug("rx_topology: %d, profile_id: 0x%x, pkt_size: %d\n",
2754 cvp_session_cmd.cvp_session.rx_topology_id,
2755 cvp_session_cmd.cvp_session.profile_id,
2756 cvp_session_cmd.hdr.pkt_size);
2757
2758 v->cvp_state = CMD_STATUS_FAIL;
2759 v->async_err = 0;
2760 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_session_cmd);
2761 if (ret < 0) {
2762 pr_err("Fail in sending VOCPROC_FULL_CONTROL_SESSION\n");
2763
2764 ret = -EINVAL;
2765 goto done;
2766 }
2767
2768 ret = wait_event_timeout(v->cvp_wait,
2769 (v->cvp_state == CMD_STATUS_SUCCESS),
2770 msecs_to_jiffies(TIMEOUT_MS));
2771 if (!ret) {
2772 pr_err("%s: wait_event timeout\n", __func__);
2773
2774 ret = -EINVAL;
2775 goto done;
2776 }
2777 if (v->async_err > 0) {
2778 pr_err("%s: DSP returned error[%s]\n",
2779 __func__, adsp_err_get_err_str(
2780 v->async_err));
2781 ret = adsp_err_get_lnx_err_code(
2782 v->async_err);
2783 goto done;
2784 }
2785
2786done:
2787 return ret;
2788}
2789
2790static int voice_send_cvp_register_dev_cfg_cmd(struct voice_data *v)
2791{
2792 struct cvp_register_dev_cfg_cmd cvp_reg_dev_cfg_cmd;
2793 struct cal_block_data *cal_block = NULL;
2794 int ret = 0;
2795
2796 memset(&cvp_reg_dev_cfg_cmd, 0, sizeof(cvp_reg_dev_cfg_cmd));
2797
2798 if (v == NULL) {
2799 pr_err("%s: v is NULL\n", __func__);
2800
2801 ret = -EINVAL;
2802 goto done;
2803 }
2804
2805 if (!common.apr_q6_cvp) {
2806 pr_err("%s: apr_cvp is NULL\n", __func__);
2807
2808 ret = -EPERM;
2809 goto done;
2810 }
2811
2812 mutex_lock(&common.cal_data[CVP_VOCDEV_CFG_CAL]->lock);
2813
2814 ret = voice_get_cal(&cal_block, CVP_VOCDEV_CFG_CAL, NULL,
2815 0, v->session_id);
2816 if (ret < 0) {
2817 pr_err("%s: Voice_get_cal failed for cal %d!\n",
2818 __func__, CVP_VOCDEV_CFG_CAL);
2819
2820 goto unlock;
2821 }
2822
2823 cvp_reg_dev_cfg_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2824 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2825 cvp_reg_dev_cfg_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2826 sizeof(cvp_reg_dev_cfg_cmd) - APR_HDR_SIZE);
2827 cvp_reg_dev_cfg_cmd.hdr.src_port =
2828 voice_get_idx_for_session(v->session_id);
2829 cvp_reg_dev_cfg_cmd.hdr.dest_port = voice_get_cvp_handle(v);
2830 cvp_reg_dev_cfg_cmd.hdr.token = 0;
2831 cvp_reg_dev_cfg_cmd.hdr.opcode =
2832 VSS_IVOCPROC_CMD_REGISTER_DEVICE_CONFIG;
2833
2834 cvp_reg_dev_cfg_cmd.cvp_dev_cfg_data.mem_handle =
2835 cal_block->map_data.q6map_handle;
2836 cvp_reg_dev_cfg_cmd.cvp_dev_cfg_data.mem_address_lsw =
2837 lower_32_bits(cal_block->cal_data.paddr);
2838 cvp_reg_dev_cfg_cmd.cvp_dev_cfg_data.mem_address_msw =
2839 msm_audio_populate_upper_32_bits(cal_block->cal_data.paddr);
2840 cvp_reg_dev_cfg_cmd.cvp_dev_cfg_data.mem_size =
2841 cal_block->cal_data.size;
2842
2843 v->cvp_state = CMD_STATUS_FAIL;
2844 v->async_err = 0;
2845 ret = apr_send_pkt(common.apr_q6_cvp,
2846 (uint32_t *) &cvp_reg_dev_cfg_cmd);
2847 if (ret < 0) {
2848 pr_err("%s: Error %d registering CVP dev cfg cal\n",
2849 __func__, ret);
2850
2851 ret = -EINVAL;
2852 goto unlock;
2853 }
2854 ret = wait_event_timeout(v->cvp_wait,
2855 (v->cvp_state == CMD_STATUS_SUCCESS),
2856 msecs_to_jiffies(TIMEOUT_MS));
2857 if (!ret) {
2858 pr_err("%s: Command timeout\n", __func__);
2859
2860 ret = -EINVAL;
2861 goto unlock;
2862 }
2863 if (v->async_err > 0) {
2864 pr_err("%s: DSP returned error[%s]\n",
2865 __func__, adsp_err_get_err_str(
2866 v->async_err));
2867 ret = adsp_err_get_lnx_err_code(
2868 v->async_err);
2869 goto unlock;
2870 }
2871unlock:
2872 mutex_unlock(&common.cal_data[CVP_VOCDEV_CFG_CAL]->lock);
2873done:
2874 return ret;
2875}
2876
2877static int voice_send_cvp_deregister_dev_cfg_cmd(struct voice_data *v)
2878{
2879 struct cvp_deregister_dev_cfg_cmd cvp_dereg_dev_cfg_cmd;
2880 int ret = 0;
2881
2882 memset(&cvp_dereg_dev_cfg_cmd, 0, sizeof(cvp_dereg_dev_cfg_cmd));
2883
2884 if (v == NULL) {
2885 pr_err("%s: v is NULL\n", __func__);
2886
2887 ret = -EINVAL;
2888 goto done;
2889 }
2890
2891 if (!common.apr_q6_cvp) {
2892 pr_err("%s: apr_cvp is NULL\n", __func__);
2893
2894 ret = -EPERM;
2895 goto done;
2896 }
2897
2898 cvp_dereg_dev_cfg_cmd.hdr.hdr_field =
2899 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2900 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2901 cvp_dereg_dev_cfg_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2902 sizeof(cvp_dereg_dev_cfg_cmd) - APR_HDR_SIZE);
2903 cvp_dereg_dev_cfg_cmd.hdr.src_port =
2904 voice_get_idx_for_session(v->session_id);
2905 cvp_dereg_dev_cfg_cmd.hdr.dest_port = voice_get_cvp_handle(v);
2906 cvp_dereg_dev_cfg_cmd.hdr.token = 0;
2907 cvp_dereg_dev_cfg_cmd.hdr.opcode =
2908 VSS_IVOCPROC_CMD_DEREGISTER_DEVICE_CONFIG;
2909
2910 v->cvp_state = CMD_STATUS_FAIL;
2911 v->async_err = 0;
2912 ret = apr_send_pkt(common.apr_q6_cvp,
2913 (uint32_t *) &cvp_dereg_dev_cfg_cmd);
2914 if (ret < 0) {
2915 pr_err("%s: Error %d de-registering CVP dev cfg cal\n",
2916 __func__, ret);
2917 goto done;
2918 }
2919 ret = wait_event_timeout(v->cvp_wait,
2920 (v->cvp_state == CMD_STATUS_SUCCESS),
2921 msecs_to_jiffies(TIMEOUT_MS));
2922 if (!ret) {
2923 pr_err("%s: Command timeout\n", __func__);
2924 goto done;
2925 }
2926 if (v->async_err > 0) {
2927 pr_err("%s: DSP returned error[%s]\n",
2928 __func__, adsp_err_get_err_str(
2929 v->async_err));
2930 ret = adsp_err_get_lnx_err_code(
2931 v->async_err);
2932 goto done;
2933 }
2934
2935done:
2936 return ret;
2937}
2938
2939static int voice_send_cvp_register_cal_cmd(struct voice_data *v)
2940{
2941 struct cvp_register_cal_data_cmd cvp_reg_cal_cmd;
2942 struct cal_block_data *cal_block = NULL;
2943 struct cal_block_data *col_data = NULL;
2944 int ret = 0;
2945
2946 memset(&cvp_reg_cal_cmd, 0, sizeof(cvp_reg_cal_cmd));
2947
2948 if (v == NULL) {
2949 pr_err("%s: v is NULL\n", __func__);
2950
2951 ret = -EINVAL;
2952 goto done;
2953 }
2954
2955 if (!common.apr_q6_cvp) {
2956 pr_err("%s: apr_cvp is NULL\n", __func__);
2957
2958 ret = -EINVAL;
2959 goto done;
2960 }
2961
2962 mutex_lock(&common.cal_data[CVP_VOCPROC_CAL]->lock);
2963 mutex_lock(&common.cal_data[CVP_VOCPROC_COL_CAL]->lock);
2964
2965 ret = voice_get_cal(&cal_block, CVP_VOCPROC_CAL, &col_data,
2966 CVP_VOCPROC_COL_CAL, v->session_id);
2967 if (ret < 0) {
2968 pr_err("%s: Voice_get_cal failed for cal %d!\n",
2969 __func__, CVP_VOCPROC_CAL);
2970
2971 goto unlock;
2972 }
2973
2974 v->dev_tx.dev_id = ((struct audio_cal_info_vocproc *)
2975 cal_block->cal_info)->tx_acdb_id;
2976 v->dev_rx.dev_id = ((struct audio_cal_info_vocproc *)
2977 cal_block->cal_info)->rx_acdb_id;
2978 pr_debug("%s: %s: Tx acdb id = %d and Rx acdb id = %d", __func__,
2979 voc_get_session_name(v->session_id), v->dev_tx.dev_id,
2980 v->dev_rx.dev_id);
2981
2982 memcpy(&cvp_reg_cal_cmd.cvp_cal_data.column_info[0],
2983 (void *) &((struct audio_cal_info_voc_col *)
2984 col_data->cal_info)->data,
2985 col_data->cal_data.size);
2986
2987 cvp_reg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2988 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2989 cvp_reg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2990 sizeof(cvp_reg_cal_cmd) - APR_HDR_SIZE);
2991 cvp_reg_cal_cmd.hdr.src_port =
2992 voice_get_idx_for_session(v->session_id);
2993 cvp_reg_cal_cmd.hdr.dest_port = voice_get_cvp_handle(v);
2994 cvp_reg_cal_cmd.hdr.token = 0;
2995 if (common.is_per_vocoder_cal_enabled)
2996 cvp_reg_cal_cmd.hdr.opcode =
2997 VSS_IVOCPROC_CMD_REGISTER_STATIC_CALIBRATION_DATA;
2998 else
2999 cvp_reg_cal_cmd.hdr.opcode =
3000 VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA_V2;
3001
3002 cvp_reg_cal_cmd.cvp_cal_data.cal_mem_handle =
3003 cal_block->map_data.q6map_handle;
3004 cvp_reg_cal_cmd.cvp_cal_data.cal_mem_address_lsw =
3005 lower_32_bits(cal_block->cal_data.paddr);
3006 cvp_reg_cal_cmd.cvp_cal_data.cal_mem_address_msw =
3007 msm_audio_populate_upper_32_bits(cal_block->cal_data.paddr);
3008 cvp_reg_cal_cmd.cvp_cal_data.cal_mem_size =
3009 cal_block->cal_data.size;
3010
3011 v->cvp_state = CMD_STATUS_FAIL;
3012 v->async_err = 0;
3013 ret = apr_send_pkt(common.apr_q6_cvp, (uint32_t *) &cvp_reg_cal_cmd);
3014 if (ret < 0) {
3015 pr_err("%s: Error %d registering CVP cal\n", __func__, ret);
3016
3017 ret = -EINVAL;
3018 goto unlock;
3019 }
3020 ret = wait_event_timeout(v->cvp_wait,
3021 (v->cvp_state == CMD_STATUS_SUCCESS),
3022 msecs_to_jiffies(TIMEOUT_MS));
3023 if (!ret) {
3024 pr_err("%s: Command timeout\n", __func__);
3025
3026 ret = -EINVAL;
3027 goto unlock;
3028 }
3029 if (v->async_err > 0) {
3030 pr_err("%s: DSP returned error[%s]\n",
3031 __func__, adsp_err_get_err_str(
3032 v->async_err));
3033 ret = adsp_err_get_lnx_err_code(
3034 v->async_err);
3035 goto unlock;
3036 }
3037unlock:
3038 mutex_unlock(&common.cal_data[CVP_VOCPROC_COL_CAL]->lock);
3039 mutex_unlock(&common.cal_data[CVP_VOCPROC_CAL]->lock);
3040done:
3041 return ret;
3042}
3043
3044static int voice_send_cvp_deregister_cal_cmd(struct voice_data *v)
3045{
3046 struct cvp_deregister_cal_data_cmd cvp_dereg_cal_cmd;
3047 int ret = 0;
3048
3049 memset(&cvp_dereg_cal_cmd, 0, sizeof(cvp_dereg_cal_cmd));
3050
3051 if (v == NULL) {
3052 pr_err("%s: v is NULL\n", __func__);
3053
3054 ret = -EINVAL;
3055 goto done;
3056 }
3057
3058 if (!common.apr_q6_cvp) {
3059 pr_err("%s: apr_cvp is NULL.\n", __func__);
3060
3061 ret = -EPERM;
3062 goto done;
3063 }
3064
3065 cvp_dereg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
3066 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
3067 cvp_dereg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
3068 sizeof(cvp_dereg_cal_cmd) - APR_HDR_SIZE);
3069 cvp_dereg_cal_cmd.hdr.src_port =
3070 voice_get_idx_for_session(v->session_id);
3071 cvp_dereg_cal_cmd.hdr.dest_port = voice_get_cvp_handle(v);
3072 cvp_dereg_cal_cmd.hdr.token = 0;
3073 if (common.is_per_vocoder_cal_enabled)
3074 cvp_dereg_cal_cmd.hdr.opcode =
3075 VSS_IVOCPROC_CMD_DEREGISTER_STATIC_CALIBRATION_DATA;
3076 else
3077 cvp_dereg_cal_cmd.hdr.opcode =
3078 VSS_IVOCPROC_CMD_DEREGISTER_CALIBRATION_DATA;
3079
3080 v->cvp_state = CMD_STATUS_FAIL;
3081 v->async_err = 0;
3082 ret = apr_send_pkt(common.apr_q6_cvp, (uint32_t *) &cvp_dereg_cal_cmd);
3083 if (ret < 0) {
3084 pr_err("%s: Error %d de-registering CVP cal\n", __func__, ret);
3085 goto done;
3086 }
3087 ret = wait_event_timeout(v->cvp_wait,
3088 (v->cvp_state == CMD_STATUS_SUCCESS),
3089 msecs_to_jiffies(TIMEOUT_MS));
3090 if (!ret) {
3091 pr_err("%s: Command timeout\n", __func__);
3092 goto done;
3093 }
3094 if (v->async_err > 0) {
3095 pr_err("%s: DSP returned error[%s]\n",
3096 __func__, adsp_err_get_err_str(
3097 v->async_err));
3098 ret = adsp_err_get_lnx_err_code(
3099 v->async_err);
3100 goto done;
3101 }
3102
3103done:
3104 return ret;
3105}
3106
3107static int voice_send_cvp_register_vol_cal_cmd(struct voice_data *v)
3108{
3109 struct cvp_register_vol_cal_data_cmd cvp_reg_vol_cal_cmd;
3110 struct cal_block_data *cal_block = NULL;
3111 struct cal_block_data *col_data = NULL;
3112 int ret = 0;
3113
3114 memset(&cvp_reg_vol_cal_cmd, 0, sizeof(cvp_reg_vol_cal_cmd));
3115
3116 if (v == NULL) {
3117 pr_err("%s: v is NULL\n", __func__);
3118
3119 ret = -EINVAL;
3120 goto done;
3121 }
3122
3123 if (!common.apr_q6_cvp) {
3124 pr_err("%s: apr_cvp is NULL\n", __func__);
3125
3126 ret = -EINVAL;
3127 goto done;
3128 }
3129
3130 mutex_lock(&common.cal_data[CVP_VOCVOL_CAL]->lock);
3131 mutex_lock(&common.cal_data[CVP_VOCVOL_COL_CAL]->lock);
3132
3133 ret = voice_get_cal(&cal_block, CVP_VOCVOL_CAL, &col_data,
3134 CVP_VOCVOL_COL_CAL, v->session_id);
3135 if (ret < 0) {
3136 pr_err("%s: Voice_get_cal failed for cal %d!\n",
3137 __func__, CVP_VOCVOL_CAL);
3138
3139 goto unlock;
3140 }
3141
3142 memcpy(&cvp_reg_vol_cal_cmd.cvp_vol_cal_data.column_info[0],
3143 (void *) &((struct audio_cal_info_voc_col *)
3144 col_data->cal_info)->data,
3145 col_data->cal_data.size);
3146
3147 cvp_reg_vol_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
3148 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
3149 cvp_reg_vol_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
3150 sizeof(cvp_reg_vol_cal_cmd) - APR_HDR_SIZE);
3151 cvp_reg_vol_cal_cmd.hdr.src_port =
3152 voice_get_idx_for_session(v->session_id);
3153 cvp_reg_vol_cal_cmd.hdr.dest_port = voice_get_cvp_handle(v);
3154 cvp_reg_vol_cal_cmd.hdr.token = 0;
3155 if (common.is_per_vocoder_cal_enabled)
3156 cvp_reg_vol_cal_cmd.hdr.opcode =
3157 VSS_IVOCPROC_CMD_REGISTER_DYNAMIC_CALIBRATION_DATA;
3158 else
3159 cvp_reg_vol_cal_cmd.hdr.opcode =
3160 VSS_IVOCPROC_CMD_REGISTER_VOL_CALIBRATION_DATA;
3161
3162 cvp_reg_vol_cal_cmd.cvp_vol_cal_data.cal_mem_handle =
3163 cal_block->map_data.q6map_handle;
3164 cvp_reg_vol_cal_cmd.cvp_vol_cal_data.cal_mem_address_lsw =
3165 lower_32_bits(cal_block->cal_data.paddr);
3166 cvp_reg_vol_cal_cmd.cvp_vol_cal_data.cal_mem_address_msw =
3167 msm_audio_populate_upper_32_bits(cal_block->cal_data.paddr);
3168 cvp_reg_vol_cal_cmd.cvp_vol_cal_data.cal_mem_size =
3169 cal_block->cal_data.size;
3170
3171 v->cvp_state = CMD_STATUS_FAIL;
3172 v->async_err = 0;
3173 ret = apr_send_pkt(common.apr_q6_cvp,
3174 (uint32_t *) &cvp_reg_vol_cal_cmd);
3175 if (ret < 0) {
3176 pr_err("%s: Error %d registering CVP vol cal\n", __func__, ret);
3177
3178 ret = -EINVAL;
3179 goto unlock;
3180 }
3181 ret = wait_event_timeout(v->cvp_wait,
3182 (v->cvp_state == CMD_STATUS_SUCCESS),
3183 msecs_to_jiffies(TIMEOUT_MS));
3184 if (!ret) {
3185 pr_err("%s: Command timeout\n", __func__);
3186
3187 ret = -EINVAL;
3188 goto unlock;
3189 }
3190 if (v->async_err > 0) {
3191 pr_err("%s: DSP returned error[%s]\n",
3192 __func__, adsp_err_get_err_str(
3193 v->async_err));
3194 ret = adsp_err_get_lnx_err_code(
3195 v->async_err);
3196 goto unlock;
3197 }
3198unlock:
3199 mutex_unlock(&common.cal_data[CVP_VOCVOL_COL_CAL]->lock);
3200 mutex_unlock(&common.cal_data[CVP_VOCVOL_CAL]->lock);
3201done:
3202 return ret;
3203}
3204
3205static int voice_send_cvp_deregister_vol_cal_cmd(struct voice_data *v)
3206{
3207 struct cvp_deregister_vol_cal_data_cmd cvp_dereg_vol_cal_cmd;
3208 int ret = 0;
3209
3210 memset(&cvp_dereg_vol_cal_cmd, 0, sizeof(cvp_dereg_vol_cal_cmd));
3211
3212 if (v == NULL) {
3213 pr_err("%s: v is NULL\n", __func__);
3214
3215 ret = -EINVAL;
3216 goto done;
3217 }
3218
3219 if (!common.apr_q6_cvp) {
3220 pr_err("%s: apr_cvp is NULL\n", __func__);
3221
3222 ret = -EPERM;
3223 goto done;
3224 }
3225
3226 cvp_dereg_vol_cal_cmd.hdr.hdr_field =
3227 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
3228 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
3229 cvp_dereg_vol_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
3230 sizeof(cvp_dereg_vol_cal_cmd) - APR_HDR_SIZE);
3231 cvp_dereg_vol_cal_cmd.hdr.src_port =
3232 voice_get_idx_for_session(v->session_id);
3233 cvp_dereg_vol_cal_cmd.hdr.dest_port = voice_get_cvp_handle(v);
3234 cvp_dereg_vol_cal_cmd.hdr.token = 0;
3235 if (common.is_per_vocoder_cal_enabled)
3236 cvp_dereg_vol_cal_cmd.hdr.opcode =
3237 VSS_IVOCPROC_CMD_DEREGISTER_DYNAMIC_CALIBRATION_DATA;
3238 else
3239 cvp_dereg_vol_cal_cmd.hdr.opcode =
3240 VSS_IVOCPROC_CMD_DEREGISTER_VOL_CALIBRATION_DATA;
3241
3242 v->cvp_state = CMD_STATUS_FAIL;
3243 v->async_err = 0;
3244 ret = apr_send_pkt(common.apr_q6_cvp,
3245 (uint32_t *) &cvp_dereg_vol_cal_cmd);
3246 if (ret < 0) {
3247 pr_err("%s: Error %d de-registering CVP vol cal\n",
3248 __func__, ret);
3249 goto done;
3250 }
3251 ret = wait_event_timeout(v->cvp_wait,
3252 (v->cvp_state == CMD_STATUS_SUCCESS),
3253 msecs_to_jiffies(TIMEOUT_MS));
3254 if (!ret) {
3255 pr_err("%s: Command timeout\n", __func__);
3256 goto done;
3257 }
3258 if (v->async_err > 0) {
3259 pr_err("%s: DSP returned error[%s]\n",
3260 __func__, adsp_err_get_err_str(
3261 v->async_err));
3262 ret = adsp_err_get_lnx_err_code(
3263 v->async_err);
3264 goto done;
3265 }
3266
3267done:
3268 return ret;
3269}
3270
3271static int voice_map_memory_physical_cmd(struct voice_data *v,
3272 struct mem_map_table *table_info,
3273 dma_addr_t phys,
3274 uint32_t size,
3275 uint32_t token)
3276{
3277 struct vss_imemory_cmd_map_physical_t mvm_map_phys_cmd;
3278 uint32_t *memtable;
3279 int ret = 0;
3280
3281 if (v == NULL) {
3282 pr_err("%s: v is NULL\n", __func__);
3283 ret = -EINVAL;
3284 goto fail;
3285 }
3286
3287 if (!common.apr_q6_mvm) {
3288 pr_err("%s: apr_mvm is NULL.\n", __func__);
3289 ret = -EINVAL;
3290 goto fail;
3291 }
3292
3293 if (!table_info->data) {
3294 pr_err("%s: memory table is NULL.\n", __func__);
3295 ret = -EINVAL;
3296 goto fail;
3297 }
3298
3299 memtable = (uint32_t *) table_info->data;
3300
3301 /*
3302 * Store next table descriptor's address(64 bit) as NULL as there
3303 * is only one memory block
3304 */
3305 memtable[0] = 0;
3306 memtable[1] = 0;
3307
3308 /* Store next table descriptor's size */
3309 memtable[2] = 0;
3310
3311 /* Store shared mem adddress (64 bit) */
3312 memtable[3] = lower_32_bits(phys);
3313 memtable[4] = msm_audio_populate_upper_32_bits(phys);
3314
3315 /* Store shared memory size */
3316 memtable[5] = size;
3317
3318 mvm_map_phys_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
3319 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
3320 mvm_map_phys_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
3321 sizeof(mvm_map_phys_cmd) - APR_HDR_SIZE);
3322 mvm_map_phys_cmd.hdr.src_port =
3323 voice_get_idx_for_session(v->session_id);
3324 mvm_map_phys_cmd.hdr.dest_port = voice_get_mvm_handle(v);
3325 mvm_map_phys_cmd.hdr.token = token;
3326 mvm_map_phys_cmd.hdr.opcode = VSS_IMEMORY_CMD_MAP_PHYSICAL;
3327
3328 mvm_map_phys_cmd.table_descriptor.mem_address_lsw =
3329 lower_32_bits(table_info->phys);
3330 mvm_map_phys_cmd.table_descriptor.mem_address_msw =
3331 msm_audio_populate_upper_32_bits(table_info->phys);
3332 mvm_map_phys_cmd.table_descriptor.mem_size =
3333 sizeof(struct vss_imemory_block_t) +
3334 sizeof(struct vss_imemory_table_descriptor_t);
3335 mvm_map_phys_cmd.is_cached = true;
3336 mvm_map_phys_cmd.cache_line_size = 128;
3337 mvm_map_phys_cmd.access_mask = 3;
3338 mvm_map_phys_cmd.page_align = 4096;
3339 mvm_map_phys_cmd.min_data_width = 8;
3340 mvm_map_phys_cmd.max_data_width = 64;
3341
3342 pr_debug("%s: next table desc: add: %lld, size: %d\n",
3343 __func__, *((uint64_t *) memtable),
3344 *(((uint32_t *) memtable) + 2));
3345 pr_debug("%s: phy add of of mem being mapped LSW:0x%x, MSW:0x%x size: %d\n",
3346 __func__, *(((uint32_t *) memtable) + 3),
3347 *(((uint32_t *) memtable) + 4), *(((uint32_t *) memtable) + 5));
3348
3349 v->mvm_state = CMD_STATUS_FAIL;
3350 v->async_err = 0;
3351 ret = apr_send_pkt(common.apr_q6_mvm, (uint32_t *) &mvm_map_phys_cmd);
3352 if (ret < 0) {
3353 pr_err("%s: Error %d sending mvm map phy cmd\n", __func__, ret);
3354
3355 goto fail;
3356 }
3357
3358 ret = wait_event_timeout(v->mvm_wait,
3359 (v->mvm_state == CMD_STATUS_SUCCESS),
3360 msecs_to_jiffies(TIMEOUT_MS));
3361 if (!ret) {
3362 pr_err("%s: Command timeout\n", __func__);
3363
3364 goto fail;
3365 }
3366 if (v->async_err > 0) {
3367 pr_err("%s: DSP returned error[%s]\n",
3368 __func__, adsp_err_get_err_str(
3369 v->async_err));
3370 ret = adsp_err_get_lnx_err_code(
3371 v->async_err);
3372 goto fail;
3373 }
3374
3375 return 0;
3376
3377fail:
3378 return ret;
3379}
3380
3381static int voice_pause_voice_call(struct voice_data *v)
3382{
3383 struct apr_hdr mvm_pause_voice_cmd;
3384 void *apr_mvm;
3385 int ret = 0;
3386
3387 pr_debug("%s\n", __func__);
3388
3389 if (v == NULL) {
3390 pr_err("%s: Voice data is NULL\n", __func__);
3391
3392 ret = -EINVAL;
3393 goto done;
3394 }
3395
3396 apr_mvm = common.apr_q6_mvm;
3397 if (!apr_mvm) {
3398 pr_err("%s: apr_mvm is NULL.\n", __func__);
3399
3400 ret = -EINVAL;
3401 goto done;
3402 }
3403
3404 mvm_pause_voice_cmd.hdr_field =
3405 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
3406 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
3407 mvm_pause_voice_cmd.pkt_size =
3408 APR_PKT_SIZE(APR_HDR_SIZE,
3409 sizeof(mvm_pause_voice_cmd) - APR_HDR_SIZE);
3410 mvm_pause_voice_cmd.src_port =
3411 voice_get_idx_for_session(v->session_id);
3412 mvm_pause_voice_cmd.dest_port = voice_get_mvm_handle(v);
3413 mvm_pause_voice_cmd.token = 0;
3414 mvm_pause_voice_cmd.opcode = VSS_IMVM_CMD_PAUSE_VOICE;
3415 v->mvm_state = CMD_STATUS_FAIL;
3416 v->async_err = 0;
3417
3418 pr_debug("%s: send mvm_pause_voice_cmd pkt size = %d\n",
3419 __func__, mvm_pause_voice_cmd.pkt_size);
3420
3421 ret = apr_send_pkt(apr_mvm,
3422 (uint32_t *)&mvm_pause_voice_cmd);
3423 if (ret < 0) {
3424 pr_err("Fail in sending VSS_IMVM_CMD_PAUSE_VOICE\n");
3425
3426 ret = -EINVAL;
3427 goto done;
3428 }
3429
3430 ret = wait_event_timeout(v->mvm_wait,
3431 (v->mvm_state == CMD_STATUS_SUCCESS),
3432 msecs_to_jiffies(TIMEOUT_MS));
3433 if (!ret) {
3434 pr_err("%s: Command timeout\n", __func__);
3435
3436 ret = -EINVAL;
3437 goto done;
3438 }
3439 if (v->async_err > 0) {
3440 pr_err("%s: DSP returned error[%s]\n",
3441 __func__, adsp_err_get_err_str(
3442 v->async_err));
3443 ret = adsp_err_get_lnx_err_code(
3444 v->async_err);
3445 goto done;
3446 }
3447
3448done:
3449 return ret;
3450}
3451
3452static int voice_map_cal_memory(struct cal_block_data *cal_block,
3453 uint32_t session_id)
3454{
3455 int result = 0;
3456 int voc_index;
3457 struct voice_data *v = NULL;
3458
3459 pr_debug("%s\n", __func__);
3460
3461 if (cal_block == NULL) {
3462 pr_err("%s: Cal block is NULL!\n", __func__);
3463
3464 result = -EINVAL;
3465 goto done;
3466 }
3467
3468 if (cal_block->cal_data.paddr == 0) {
3469 pr_debug("%s: No address to map!\n", __func__);
3470
3471 result = -EINVAL;
3472 goto done;
3473 }
3474
3475 if (cal_block->map_data.map_size == 0) {
3476 pr_debug("%s: Map size is 0!\n", __func__);
3477
3478 result = -EINVAL;
3479 goto done;
3480 }
3481
3482 voc_index = voice_get_idx_for_session(session_id);
3483 if (voc_index < 0) {
3484 pr_err("%s: Invalid session ID %d\n", __func__, session_id);
3485
3486 goto done;
3487 }
3488
3489 mutex_lock(&common.common_lock);
3490 v = &common.voice[voc_index];
3491
3492 result = voice_map_memory_physical_cmd(v,
3493 &common.cal_mem_map_table,
3494 (dma_addr_t)cal_block->cal_data.paddr,
3495 cal_block->map_data.map_size,
3496 VOC_CAL_MEM_MAP_TOKEN);
3497 if (result < 0) {
3498 pr_err("%s: Mmap did not work! addr = 0x%pK, size = %zd\n",
3499 __func__,
3500 &cal_block->cal_data.paddr,
3501 cal_block->map_data.map_size);
3502
3503 goto done_unlock;
3504 }
3505
3506 cal_block->map_data.q6map_handle = common.cal_mem_handle;
3507done_unlock:
3508 mutex_unlock(&common.common_lock);
3509done:
3510 return result;
3511}
3512
3513static int remap_cal_data(struct cal_block_data *cal_block,
3514 uint32_t session_id)
3515{
3516 int ret = 0;
3517
3518 pr_debug("%s\n", __func__);
3519
3520 if (cal_block->map_data.ion_client == NULL) {
3521 pr_err("%s: No ION allocation for session_id %d!\n",
3522 __func__, session_id);
3523 ret = -EINVAL;
3524 goto done;
3525 }
3526
3527 if ((cal_block->map_data.map_size > 0) &&
3528 (cal_block->map_data.q6map_handle == 0)) {
3529
3530 /* cal type not used */
3531 ret = voice_map_cal_memory(cal_block, session_id);
3532 if (ret < 0) {
3533 pr_err("%s: Mmap did not work! size = %zd\n",
3534 __func__, cal_block->map_data.map_size);
3535
3536 goto done;
3537 }
3538 } else {
3539 pr_debug("%s: Cal block 0x%pK, size %zd already mapped. Q6 map handle = %d\n",
3540 __func__, &cal_block->cal_data.paddr,
3541 cal_block->map_data.map_size,
3542 cal_block->map_data.q6map_handle);
3543 }
3544done:
3545 return ret;
3546}
3547
3548static int voice_unmap_cal_memory(int32_t cal_type,
3549 struct cal_block_data *cal_block)
3550{
3551 int result = 0;
3552 int result2 = 0;
3553 int i;
3554 struct voice_data *v = NULL;
3555
3556 pr_debug("%s\n", __func__);
3557
3558 if (cal_block == NULL) {
3559 pr_err("%s: Cal block is NULL!\n", __func__);
3560
3561 result = -EINVAL;
3562 goto done;
3563 }
3564
3565 if (cal_block->map_data.q6map_handle == 0) {
3566 pr_debug("%s: Q6 handle is not set!\n", __func__);
3567
3568 result = -EINVAL;
3569 goto done;
3570 }
3571
3572 mutex_lock(&common.common_lock);
3573
3574 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
3575 v = &common.voice[i];
3576
3577 mutex_lock(&v->lock);
3578 if (is_voc_state_active(v->voc_state)) {
3579 result2 = voice_pause_voice_call(v);
3580 if (result2 < 0) {
3581 pr_err("%s: Voice_pause_voice_call failed for session 0x%x, err %d!\n",
3582 __func__, v->session_id, result2);
3583
3584 result = result2;
3585 }
3586
3587 if (cal_type == CVP_VOCPROC_DYNAMIC_CAL_TYPE)
3588 voice_send_cvp_deregister_vol_cal_cmd(v);
3589 else if (cal_type == CVP_VOCPROC_STATIC_CAL_TYPE)
3590 voice_send_cvp_deregister_cal_cmd(v);
3591 else if (cal_type == CVP_VOCDEV_CFG_CAL_TYPE)
3592 voice_send_cvp_deregister_dev_cfg_cmd(v);
3593 else if (cal_type == CVS_VOCSTRM_STATIC_CAL_TYPE)
3594 voice_send_cvs_deregister_cal_cmd(v);
3595 else
3596 pr_err("%s: Invalid cal type %d!\n",
3597 __func__, cal_type);
3598
3599 result2 = voice_send_start_voice_cmd(v);
3600 if (result2) {
3601 pr_err("%s: Voice_send_start_voice_cmd failed for session 0x%x, err %d!\n",
3602 __func__, v->session_id, result2);
3603
3604 result = result2;
3605 }
3606 }
3607
3608 if ((cal_block->map_data.q6map_handle != 0) &&
3609 (!is_other_session_active(v->session_id))) {
3610
3611 result2 = voice_send_mvm_unmap_memory_physical_cmd(
3612 v, cal_block->map_data.q6map_handle);
3613 if (result2) {
3614 pr_err("%s: Voice_send_mvm_unmap_memory_physical_cmd failed for session 0x%x, err %d!\n",
3615 __func__, v->session_id, result2);
3616
3617 result = result2;
3618 }
3619 cal_block->map_data.q6map_handle = 0;
3620 }
3621 mutex_unlock(&v->lock);
3622 }
3623 mutex_unlock(&common.common_lock);
3624done:
3625 return result;
3626}
3627
3628int voc_register_vocproc_vol_table(void)
3629{
3630 int result = 0;
3631 int result2 = 0;
3632 int i;
3633 struct voice_data *v = NULL;
3634
3635 pr_debug("%s\n", __func__);
3636
3637 mutex_lock(&common.common_lock);
3638 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
3639 v = &common.voice[i];
3640
3641 mutex_lock(&v->lock);
3642 if (is_voc_state_active(v->voc_state)) {
3643 result2 = voice_send_cvp_register_vol_cal_cmd(v);
3644 if (result2 < 0) {
3645 pr_err("%s: Failed to register vocvol table for session 0x%x!\n",
3646 __func__, v->session_id);
3647
3648 result = result2;
3649 /* Still try to register other sessions */
3650 }
3651 }
3652 mutex_unlock(&v->lock);
3653 }
3654
3655 mutex_unlock(&common.common_lock);
3656 return result;
3657}
3658
3659int voc_deregister_vocproc_vol_table(void)
3660{
3661 int result = 0;
3662 int success = 0;
3663 int i;
3664 struct voice_data *v = NULL;
3665
3666 pr_debug("%s\n", __func__);
3667
3668 mutex_lock(&common.common_lock);
3669 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
3670 v = &common.voice[i];
3671
3672 mutex_lock(&v->lock);
3673 if (is_voc_state_active(v->voc_state)) {
3674 result = voice_send_cvp_deregister_vol_cal_cmd(v);
3675 if (result < 0) {
3676 pr_err("%s: Failed to deregister vocvol table for session 0x%x!\n",
3677 __func__, v->session_id);
3678
3679 mutex_unlock(&v->lock);
3680 mutex_unlock(&common.common_lock);
3681 if (success) {
3682 pr_err("%s: Try to re-register all deregistered sessions!\n",
3683 __func__);
3684
3685 voc_register_vocproc_vol_table();
3686 }
3687 goto done;
3688 } else {
3689 success = 1;
3690 }
3691 }
3692 mutex_unlock(&v->lock);
3693 }
3694 mutex_unlock(&common.common_lock);
3695done:
3696 return result;
3697}
3698
3699int voc_map_rtac_block(struct rtac_cal_block_data *cal_block)
3700{
3701 int result = 0;
3702 struct voice_data *v = NULL;
3703
3704 pr_debug("%s\n", __func__);
3705
3706 if (cal_block == NULL) {
3707 pr_err("%s: cal_block is NULL!\n",
3708 __func__);
3709
3710 result = -EINVAL;
3711 goto done;
3712 }
3713
3714 if (cal_block->cal_data.paddr == 0) {
3715 pr_debug("%s: No address to map!\n",
3716 __func__);
3717
3718 result = -EINVAL;
3719 goto done;
3720 }
3721
3722 if (cal_block->map_data.map_size == 0) {
3723 pr_debug("%s: map size is 0!\n",
3724 __func__);
3725
3726 result = -EINVAL;
3727 goto done;
3728 }
3729
3730 mutex_lock(&common.common_lock);
3731 /* use first session */
3732 v = &common.voice[0];
3733 mutex_lock(&v->lock);
3734
3735 if (!is_rtac_memory_allocated()) {
3736 result = voice_alloc_rtac_mem_map_table();
3737 if (result < 0) {
3738 pr_err("%s: RTAC alloc mem map table did not work! addr = 0x%pK, size = %d\n",
3739 __func__,
3740 &cal_block->cal_data.paddr,
3741 cal_block->map_data.map_size);
3742
3743 goto done_unlock;
3744 }
3745 }
3746
3747 result = voice_map_memory_physical_cmd(v,
3748 &common.rtac_mem_map_table,
3749 (dma_addr_t)cal_block->cal_data.paddr,
3750 cal_block->map_data.map_size,
3751 VOC_RTAC_MEM_MAP_TOKEN);
3752 if (result < 0) {
3753 pr_err("%s: RTAC mmap did not work! addr = 0x%pK, size = %d\n",
3754 __func__,
3755 &cal_block->cal_data.paddr,
3756 cal_block->map_data.map_size);
3757
3758 free_rtac_map_table();
3759 goto done_unlock;
3760 }
3761
3762 cal_block->map_data.map_handle = common.rtac_mem_handle;
3763done_unlock:
3764 mutex_unlock(&v->lock);
3765 mutex_unlock(&common.common_lock);
3766done:
3767 return result;
3768}
3769
3770int voc_unmap_rtac_block(uint32_t *mem_map_handle)
3771{
3772 int result = 0;
3773 struct voice_data *v = NULL;
3774
3775 pr_debug("%s\n", __func__);
3776
3777 if (mem_map_handle == NULL) {
3778 pr_debug("%s: Map handle is NULL, nothing to unmap\n",
3779 __func__);
3780
3781 goto done;
3782 }
3783
3784 if (*mem_map_handle == 0) {
3785 pr_debug("%s: Map handle is 0, nothing to unmap\n",
3786 __func__);
3787
3788 goto done;
3789 }
3790
3791 mutex_lock(&common.common_lock);
3792 /* Use first session */
3793 /* Only used for apr wait lock */
3794 v = &common.voice[0];
3795 mutex_lock(&v->lock);
3796
3797 result = voice_send_mvm_unmap_memory_physical_cmd(
3798 v, *mem_map_handle);
3799 if (result) {
3800 pr_err("%s: voice_send_mvm_unmap_memory_physical_cmd Failed for session 0x%x!\n",
3801 __func__, v->session_id);
3802 } else {
3803 *mem_map_handle = 0;
3804 common.rtac_mem_handle = 0;
3805 free_rtac_map_table();
3806 }
3807 mutex_unlock(&v->lock);
3808 mutex_unlock(&common.common_lock);
3809done:
3810 return result;
3811}
3812
Laxminath Kasam38070be2017-08-17 18:21:59 +05303813static int voice_send_cvp_channel_info_v2(struct voice_data *v,
3814 uint32_t param_type)
3815{
3816 int ret;
3817 struct cvp_set_channel_info_cmd_v2 cvp_set_channel_info_cmd;
3818 void *apr_cvp;
3819 u16 cvp_handle;
3820 struct vss_icommon_param_data_channel_info_v2_t
3821 *channel_info_param_data =
3822 &cvp_set_channel_info_cmd.
3823 cvp_set_ch_info_param_v2.param_data;
3824 struct vss_param_vocproc_dev_channel_info_t *channel_info =
3825 &channel_info_param_data->channel_info;
3826
3827 if (v == NULL) {
3828 pr_err("%s: v is NULL\n", __func__);
3829 ret = -EINVAL;
3830 goto done;
3831 }
3832
3833 apr_cvp = common.apr_q6_cvp;
3834 if (!apr_cvp) {
3835 pr_err("%s: apr_cvp is NULL\n", __func__);
3836 ret = -EINVAL;
3837 goto done;
3838 }
3839
3840 cvp_handle = voice_get_cvp_handle(v);
3841 memset(&cvp_set_channel_info_cmd, 0, sizeof(cvp_set_channel_info_cmd));
3842
3843 cvp_set_channel_info_cmd.hdr.hdr_field =
3844 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
3845 APR_PKT_VER);
3846 cvp_set_channel_info_cmd.hdr.pkt_size =
3847 APR_PKT_SIZE(APR_HDR_SIZE,
3848 sizeof(cvp_set_channel_info_cmd) - APR_HDR_SIZE);
3849 cvp_set_channel_info_cmd.hdr.src_svc = 0;
3850 cvp_set_channel_info_cmd.hdr.src_domain = APR_DOMAIN_APPS;
3851 cvp_set_channel_info_cmd.hdr.src_port =
3852 voice_get_idx_for_session(v->session_id);
3853 cvp_set_channel_info_cmd.hdr.dest_svc = 0;
3854 cvp_set_channel_info_cmd.hdr.dest_domain = APR_DOMAIN_ADSP;
3855 cvp_set_channel_info_cmd.hdr.dest_port = cvp_handle;
3856 cvp_set_channel_info_cmd.hdr.token = 0;
3857 cvp_set_channel_info_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_PARAM_V2;
3858
3859 cvp_set_channel_info_cmd.cvp_set_ch_info_param_v2.mem_size =
3860 sizeof(struct vss_icommon_param_data_channel_info_v2_t);
3861
3862 channel_info_param_data->module_id = VSS_MODULE_CVD_GENERIC;
3863 channel_info_param_data->param_size =
3864 sizeof(struct vss_param_vocproc_dev_channel_info_t);
3865
3866 /* Device specific data */
3867 switch (param_type) {
3868 case RX_PATH:
3869 channel_info_param_data->param_id =
3870 VSS_PARAM_VOCPROC_RX_CHANNEL_INFO;
3871 channel_info->num_channels = v->dev_rx.no_of_channels;
3872 channel_info->bits_per_sample = v->dev_rx.bits_per_sample;
Aditya Bavanari88513a32017-10-12 12:29:25 +05303873 memcpy(&channel_info->channel_mapping,
3874 v->dev_rx.channel_mapping,
3875 VSS_NUM_CHANNELS_MAX * sizeof(uint8_t));
Laxminath Kasam38070be2017-08-17 18:21:59 +05303876 break;
3877
3878 case TX_PATH:
3879 channel_info_param_data->param_id =
3880 VSS_PARAM_VOCPROC_TX_CHANNEL_INFO;
3881 channel_info->num_channels = v->dev_tx.no_of_channels;
3882 channel_info->bits_per_sample = v->dev_tx.bits_per_sample;
Aditya Bavanari88513a32017-10-12 12:29:25 +05303883 memcpy(&channel_info->channel_mapping,
3884 v->dev_tx.channel_mapping,
3885 VSS_NUM_CHANNELS_MAX * sizeof(uint8_t));
Laxminath Kasam38070be2017-08-17 18:21:59 +05303886 break;
3887
3888 case EC_REF_PATH:
3889 channel_info_param_data->param_id =
3890 VSS_PARAM_VOCPROC_EC_REF_CHANNEL_INFO;
3891 channel_info->num_channels = v->dev_rx.no_of_channels;
3892 channel_info->bits_per_sample = v->dev_rx.bits_per_sample;
Aditya Bavanari88513a32017-10-12 12:29:25 +05303893 memcpy(&channel_info->channel_mapping,
3894 v->dev_rx.channel_mapping,
3895 VSS_NUM_CHANNELS_MAX * sizeof(uint8_t));
Laxminath Kasam38070be2017-08-17 18:21:59 +05303896 break;
3897 default:
3898 pr_err("%s: Invalid param type\n",
3899 __func__);
3900 ret = -EINVAL;
3901 goto done;
3902 }
3903
Laxminath Kasam38070be2017-08-17 18:21:59 +05303904
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;
Aditya Bavanari88513a32017-10-12 12:29:25 +05304113 memcpy(&mfc_config_info->channel_type,
4114 v->dev_rx.channel_mapping,
4115 VSS_NUM_CHANNELS_MAX * sizeof(uint8_t));
Laxminath Kasam38070be2017-08-17 18:21:59 +05304116
4117 v->cvp_state = CMD_STATUS_FAIL;
4118 v->async_err = 0;
4119 ret = apr_send_pkt(apr_cvp, (uint32_t *)&cvp_set_mfc_config_cmd);
4120 if (ret < 0) {
4121 pr_err("%s: Failed to send VSS_ICOMMON_CMD_SET_PARAM_V2 %d\n",
4122 __func__, ret);
4123 goto done;
4124 }
4125 ret = wait_event_timeout(v->cvp_wait,
4126 (v->cvp_state == CMD_STATUS_SUCCESS),
4127 msecs_to_jiffies(TIMEOUT_MS));
4128
4129 if (!ret) {
4130 pr_err("%s: wait_event timeout\n", __func__);
4131 ret = -ETIMEDOUT;
4132 goto done;
4133 }
4134
4135 if (v->async_err > 0) {
4136 pr_err("%s: DSP returned error[%s] handle = %d\n", __func__,
4137 adsp_err_get_err_str(v->async_err), cvp_handle);
4138 ret = adsp_err_get_lnx_err_code(v->async_err);
4139 goto done;
4140 }
4141 ret = 0;
4142done:
4143 return ret;
4144}
4145
4146static int voice_send_cvp_mfc_config_cmd(struct voice_data *v)
4147{
4148 int ret = 0;
4149
4150 if (common.cvp_version >= CVP_VERSION_2) {
Aditya Bavanari245361d2017-09-07 12:11:30 +05304151 ret = voice_send_cvp_ch_mixer_info_v2(v);
4152 if (ret < 0)
4153 pr_warn("%s: Set channel mixer config failed err:%d",
4154 __func__, ret);
4155
Laxminath Kasam38070be2017-08-17 18:21:59 +05304156 ret = voice_send_cvp_mfc_config_v2(v);
Aditya Bavanari245361d2017-09-07 12:11:30 +05304157 if (ret < 0)
4158 pr_warn("%s: Set MFC config failed err:%d",
4159 __func__, ret);
Laxminath Kasam38070be2017-08-17 18:21:59 +05304160 } else {
4161 pr_warn("%s: CVP Version not supported\n", __func__);
4162 ret = -EINVAL;
4163 }
4164
4165 return ret;
4166}
4167
4168static int voice_get_avcs_version_per_service(uint32_t service_id)
4169{
4170 int ret = 0;
Siena Richard2d0102d2017-09-05 11:15:45 -07004171 size_t ver_size;
4172 struct avcs_fwk_ver_info *ver_info = NULL;
Laxminath Kasam38070be2017-08-17 18:21:59 +05304173
4174 if (service_id == AVCS_SERVICE_ID_ALL) {
4175 pr_err("%s: Invalid service id: %d", __func__,
4176 AVCS_SERVICE_ID_ALL);
4177 return -EINVAL;
4178 }
4179
Siena Richard2d0102d2017-09-05 11:15:45 -07004180 ver_size = sizeof(struct avcs_get_fwk_version) +
4181 sizeof(struct avs_svc_api_info);
4182 ver_info = kzalloc(ver_size, GFP_KERNEL);
4183 if (ver_info == NULL)
Laxminath Kasam38070be2017-08-17 18:21:59 +05304184 return -ENOMEM;
4185
Siena Richard2d0102d2017-09-05 11:15:45 -07004186 ret = q6core_get_service_version(service_id, ver_info, ver_size);
Laxminath Kasam38070be2017-08-17 18:21:59 +05304187 if (ret < 0)
4188 goto done;
4189
Siena Richard2d0102d2017-09-05 11:15:45 -07004190 ret = ver_info->services[0].api_version;
Laxminath Kasam38070be2017-08-17 18:21:59 +05304191 common.is_avcs_version_queried = true;
4192done:
Siena Richard2d0102d2017-09-05 11:15:45 -07004193 kfree(ver_info);
Laxminath Kasam38070be2017-08-17 18:21:59 +05304194 return ret;
4195}
4196
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304197static int voice_setup_vocproc(struct voice_data *v)
4198{
4199 int ret = 0;
4200
4201 ret = voice_send_cvp_create_cmd(v);
4202 if (ret < 0) {
4203 pr_err("%s: CVP create failed err:%d\n", __func__, ret);
4204 goto fail;
4205 }
4206
Laxminath Kasam38070be2017-08-17 18:21:59 +05304207 if (common.is_avcs_version_queried == false)
4208 common.cvp_version = voice_get_avcs_version_per_service(
4209 APRV2_IDS_SERVICE_ID_ADSP_CVP_V);
4210
4211 if (common.cvp_version < 0) {
4212 pr_err("%s: Invalid CVP version %d\n",
4213 __func__, common.cvp_version);
4214 ret = -EINVAL;
4215 goto fail;
4216 }
4217 pr_debug("%s: CVP Version %d\n", __func__, common.cvp_version);
4218
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304219 ret = voice_send_cvp_media_fmt_info_cmd(v);
4220 if (ret < 0) {
4221 pr_err("%s: Set media format info failed err:%d\n", __func__,
4222 ret);
4223 goto fail;
4224 }
4225
4226 ret = voice_send_cvp_topology_commit_cmd(v);
4227 if (ret < 0) {
4228 pr_err("%s: Set topology commit failed err:%d\n",
4229 __func__, ret);
4230 goto fail;
4231 }
4232
Laxminath Kasam38070be2017-08-17 18:21:59 +05304233 /* Send MFC config only when the no of channels are more than 1 */
4234 if (v->dev_rx.no_of_channels > NUM_CHANNELS_MONO) {
4235 ret = voice_send_cvp_mfc_config_cmd(v);
4236 if (ret < 0) {
4237 pr_warn("%s: Set mfc config failed err:%d\n",
4238 __func__, ret);
4239 }
4240 }
4241
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304242 voice_send_cvs_register_cal_cmd(v);
4243 voice_send_cvp_register_dev_cfg_cmd(v);
4244 voice_send_cvp_register_cal_cmd(v);
4245 voice_send_cvp_register_vol_cal_cmd(v);
4246
4247 /* enable vocproc */
4248 ret = voice_send_enable_vocproc_cmd(v);
4249 if (ret < 0)
4250 goto fail;
4251
4252 /* attach vocproc */
4253 ret = voice_send_attach_vocproc_cmd(v);
4254 if (ret < 0)
4255 goto fail;
4256
4257 /* send tty mode if tty device is used */
4258 voice_send_tty_mode_cmd(v);
4259
4260 if (is_voip_session(v->session_id)) {
4261 ret = voice_send_mvm_cal_network_cmd(v);
4262 if (ret < 0)
4263 pr_err("%s: voice_send_mvm_cal_network_cmd: %d\n",
4264 __func__, ret);
4265
4266 ret = voice_send_mvm_media_type_cmd(v);
4267 if (ret < 0)
4268 pr_err("%s: voice_send_mvm_media_type_cmd: %d\n",
4269 __func__, ret);
4270
4271 voice_send_netid_timing_cmd(v);
4272 }
4273
4274 if (v->st_enable && !v->tty_mode)
4275 voice_send_set_pp_enable_cmd(v,
4276 MODULE_ID_VOICE_MODULE_ST,
4277 v->st_enable);
4278 /* Start in-call music delivery if this feature is enabled */
4279 if (v->music_info.play_enable)
4280 voice_cvs_start_playback(v);
4281
4282 /* Start in-call recording if this feature is enabled */
4283 if (v->rec_info.rec_enable)
4284 voice_cvs_start_record(v, v->rec_info.rec_mode);
4285
4286 if (v->dtmf_rx_detect_en)
4287 voice_send_dtmf_rx_detection_cmd(v, v->dtmf_rx_detect_en);
4288
4289 if (v->hd_enable)
4290 voice_send_hd_cmd(v, v->hd_enable);
4291
4292 rtac_add_voice(voice_get_cvs_handle(v),
4293 voice_get_cvp_handle(v),
4294 v->dev_rx.port_id, v->dev_tx.port_id,
4295 v->dev_rx.dev_id, v->dev_tx.dev_id,
4296 v->session_id);
4297
4298 return 0;
4299
4300fail:
4301 return ret;
4302}
4303
4304static int voice_send_cvp_device_channels_cmd(struct voice_data *v)
4305{
4306 int ret = 0;
4307 struct cvp_set_dev_channels_cmd cvp_set_dev_channels_cmd;
4308 void *apr_cvp;
4309 u16 cvp_handle;
4310
4311 if (!(voice_get_cvd_int_version(common.cvd_version) >=
4312 CVD_INT_VERSION_2_2)) {
4313 pr_debug("%s CVD ver %s doesn't support send_device_channels cmd\n",
4314 __func__, common.cvd_version);
4315
4316 goto done;
4317 }
4318
4319 if (v == NULL) {
4320 pr_err("%s: v is NULL\n", __func__);
4321
4322 ret = -EINVAL;
4323 goto done;
4324 }
4325
4326 apr_cvp = common.apr_q6_cvp;
4327 if (!apr_cvp) {
4328 pr_err("%s: apr_cvp is NULL.\n", __func__);
4329
4330 ret = -EINVAL;
4331 goto done;
4332 }
4333
4334 cvp_handle = voice_get_cvp_handle(v);
4335 cvp_set_dev_channels_cmd.hdr.hdr_field =
4336 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4337 APR_HDR_LEN(APR_HDR_SIZE),
4338 APR_PKT_VER);
4339 cvp_set_dev_channels_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
4340 sizeof(cvp_set_dev_channels_cmd) - APR_HDR_SIZE);
4341 cvp_set_dev_channels_cmd.hdr.src_port =
4342 voice_get_idx_for_session(v->session_id);
4343 cvp_set_dev_channels_cmd.hdr.dest_port = cvp_handle;
4344 cvp_set_dev_channels_cmd.hdr.token = 0;
4345 cvp_set_dev_channels_cmd.hdr.opcode =
4346 VSS_IVOCPROC_CMD_TOPOLOGY_SET_DEV_CHANNELS;
4347 cvp_set_dev_channels_cmd.cvp_set_channels.rx_num_channels =
4348 VSS_NUM_DEV_CHANNELS_1;
4349 cvp_set_dev_channels_cmd.cvp_set_channels.tx_num_channels =
4350 v->dev_tx.no_of_channels;
4351
4352 v->cvp_state = CMD_STATUS_FAIL;
4353 v->async_err = 0;
4354 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_set_dev_channels_cmd);
4355 if (ret < 0) {
4356 pr_err("%s: Fail in sending VSS_IVOCPROC_CMD_TOPOLOGY_SET_DEV_CHANNELS\n",
4357 __func__);
4358
4359 ret = -EINVAL;
4360 goto done;
4361 }
4362
4363 ret = wait_event_timeout(v->cvp_wait,
4364 (v->cvp_state == CMD_STATUS_SUCCESS),
4365 msecs_to_jiffies(TIMEOUT_MS));
4366 if (!ret) {
4367 pr_err("%s: wait_event timeout\n", __func__);
4368
4369 ret = -EINVAL;
4370 goto done;
4371 }
4372 if (v->async_err > 0) {
4373 pr_err("%s: DSP returned error[%s]\n",
4374 __func__, adsp_err_get_err_str(
4375 v->async_err));
4376 ret = adsp_err_get_lnx_err_code(
4377 v->async_err);
4378 goto done;
4379 }
4380
4381done:
4382 return ret;
4383}
4384
4385static int voice_send_cvp_media_fmt_info_cmd(struct voice_data *v)
4386{
Laxminath Kasam38070be2017-08-17 18:21:59 +05304387 int ret = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304388
Laxminath Kasam38070be2017-08-17 18:21:59 +05304389 if (common.cvp_version < CVP_VERSION_2)
4390 ret = voice_send_cvp_device_channels_cmd(v);
4391 else
4392 ret = voice_send_cvp_channel_info_cmd(v);
4393
4394 if (ret < 0) {
4395 pr_err("%s: Set channel info failed err: %d\n", __func__,
4396 ret);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304397 goto done;
Laxminath Kasam38070be2017-08-17 18:21:59 +05304398 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304399
4400 if (voice_get_cvd_int_version(common.cvd_version) >=
4401 CVD_INT_VERSION_2_3) {
4402 ret = voice_send_cvp_media_format_cmd(v, RX_PATH);
4403 if (ret < 0)
4404 goto done;
4405
4406 ret = voice_send_cvp_media_format_cmd(v, TX_PATH);
4407 if (ret < 0)
4408 goto done;
4409
4410 if (common.ec_ref_ext)
4411 ret = voice_send_cvp_media_format_cmd(v, EC_REF_PATH);
4412 }
4413
4414done:
4415 return ret;
4416}
4417
4418static int voice_send_cvp_media_format_cmd(struct voice_data *v,
4419 uint32_t param_type)
4420{
4421 int ret = 0;
4422 struct cvp_set_media_format_cmd cvp_set_media_format_cmd;
4423 void *apr_cvp;
4424 u16 cvp_handle;
4425 struct vss_icommon_param_data_t *media_fmt_param_data =
Laxminath Kasam38070be2017-08-17 18:21:59 +05304426 &cvp_set_media_format_cmd.cvp_set_media_param_v2.param_data;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304427 struct vss_param_endpoint_media_format_info_t *media_fmt_info =
4428 &media_fmt_param_data->media_format_info;
4429
4430 if (v == NULL) {
4431 pr_err("%s: v is NULL\n", __func__);
4432 ret = -EINVAL;
4433 goto done;
4434 }
4435
4436 apr_cvp = common.apr_q6_cvp;
4437 if (!apr_cvp) {
4438 pr_err("%s: apr_cvp is NULL.\n", __func__);
4439 ret = -EINVAL;
4440 goto done;
4441 }
4442
4443 cvp_handle = voice_get_cvp_handle(v);
4444 memset(&cvp_set_media_format_cmd, 0, sizeof(cvp_set_media_format_cmd));
4445
4446 /* Fill header data */
4447 cvp_set_media_format_cmd.hdr.hdr_field =
4448 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
4449 APR_PKT_VER);
4450 cvp_set_media_format_cmd.hdr.pkt_size =
4451 APR_PKT_SIZE(APR_HDR_SIZE,
4452 sizeof(cvp_set_media_format_cmd) - APR_HDR_SIZE);
4453 cvp_set_media_format_cmd.hdr.src_svc = 0;
4454 cvp_set_media_format_cmd.hdr.src_domain = APR_DOMAIN_APPS;
4455 cvp_set_media_format_cmd.hdr.src_port =
4456 voice_get_idx_for_session(v->session_id);
4457 cvp_set_media_format_cmd.hdr.dest_svc = 0;
4458 cvp_set_media_format_cmd.hdr.dest_domain = APR_DOMAIN_ADSP;
4459 cvp_set_media_format_cmd.hdr.dest_port = cvp_handle;
4460 cvp_set_media_format_cmd.hdr.token = VOC_SET_MEDIA_FORMAT_PARAM_TOKEN;
4461 cvp_set_media_format_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_PARAM_V2;
4462
4463 /* Fill param data */
Laxminath Kasam38070be2017-08-17 18:21:59 +05304464 cvp_set_media_format_cmd.cvp_set_media_param_v2.mem_size =
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304465 sizeof(struct vss_icommon_param_data_t);
4466 media_fmt_param_data->module_id = VSS_MODULE_CVD_GENERIC;
4467 media_fmt_param_data->param_size =
4468 sizeof(struct vss_param_endpoint_media_format_info_t);
4469
4470 /* Fill device specific data */
4471 switch (param_type) {
4472 case RX_PATH:
4473 media_fmt_param_data->param_id =
4474 VSS_PARAM_RX_PORT_ENDPOINT_MEDIA_INFO;
4475 media_fmt_info->port_id = v->dev_rx.port_id;
4476 media_fmt_info->num_channels = v->dev_rx.no_of_channels;
4477 media_fmt_info->bits_per_sample = v->dev_rx.bits_per_sample;
4478 media_fmt_info->sample_rate = v->dev_rx.sample_rate;
4479 memcpy(&media_fmt_info->channel_mapping,
4480 &v->dev_rx.channel_mapping, VSS_CHANNEL_MAPPING_SIZE);
4481 break;
4482
4483 case TX_PATH:
4484 media_fmt_param_data->param_id =
4485 VSS_PARAM_TX_PORT_ENDPOINT_MEDIA_INFO;
4486 media_fmt_info->port_id = v->dev_tx.port_id;
4487 media_fmt_info->num_channels = v->dev_tx.no_of_channels;
4488 media_fmt_info->bits_per_sample = v->dev_tx.bits_per_sample;
4489 media_fmt_info->sample_rate = v->dev_tx.sample_rate;
4490 memcpy(&media_fmt_info->channel_mapping,
4491 &v->dev_tx.channel_mapping, VSS_CHANNEL_MAPPING_SIZE);
4492 break;
4493
4494 case EC_REF_PATH:
4495 media_fmt_param_data->param_id =
4496 VSS_PARAM_EC_REF_PORT_ENDPOINT_MEDIA_INFO;
4497 media_fmt_info->port_id = common.ec_media_fmt_info.port_id;
4498 media_fmt_info->num_channels =
4499 common.ec_media_fmt_info.num_channels;
4500 media_fmt_info->bits_per_sample =
4501 common.ec_media_fmt_info.bits_per_sample;
4502 media_fmt_info->sample_rate =
4503 common.ec_media_fmt_info.sample_rate;
4504 memcpy(&media_fmt_info->channel_mapping,
4505 &common.ec_media_fmt_info.channel_mapping,
4506 VSS_CHANNEL_MAPPING_SIZE);
4507 break;
4508
4509 default:
4510 pr_err("%s: Invalid param type %d\n", __func__, param_type);
4511 ret = -EINVAL;
4512 goto done;
4513 }
4514
4515 /* Send command */
4516 v->cvp_state = CMD_STATUS_FAIL;
4517 v->async_err = 0;
4518 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_set_media_format_cmd);
4519 if (ret < 0) {
4520 pr_err("%s: Fail in sending VSS_ICOMMON_CMD_SET_PARAM_V2\n",
4521 __func__);
4522 ret = -EINVAL;
4523 goto done;
4524 }
4525
4526 ret = wait_event_timeout(v->cvp_wait,
4527 (v->cvp_state == CMD_STATUS_SUCCESS),
4528 msecs_to_jiffies(TIMEOUT_MS));
4529 if (!ret) {
4530 pr_err("%s: wait_event timeout\n", __func__);
4531 ret = -EINVAL;
4532 goto done;
4533 }
4534
4535 if (v->async_err > 0) {
4536 pr_err("%s: DSP returned error[%s] handle = %d\n", __func__,
4537 adsp_err_get_err_str(v->async_err), cvp_handle);
4538 ret = adsp_err_get_lnx_err_code(v->async_err);
4539 goto done;
4540 }
4541
4542done:
4543 return ret;
4544}
4545
4546static int voice_send_cvp_topology_commit_cmd(struct voice_data *v)
4547{
4548 int ret = 0;
4549 struct apr_hdr cvp_topology_commit_cmd;
4550 void *apr_cvp;
4551 u16 cvp_handle;
4552
4553 if (!(voice_get_cvd_int_version(common.cvd_version) >=
4554 CVD_INT_VERSION_2_2)) {
4555 pr_debug("%s CVD version string %s doesn't support this command\n",
4556 __func__, common.cvd_version);
4557
4558 goto done;
4559 }
4560
4561 if (v == NULL) {
4562 pr_err("%s: v is NULL\n", __func__);
4563
4564 ret = -EINVAL;
4565 goto done;
4566 }
4567
4568 apr_cvp = common.apr_q6_cvp;
4569 if (!apr_cvp) {
4570 pr_err("%s: apr_cvp is NULL.\n", __func__);
4571
4572 ret = -EINVAL;
4573 goto done;
4574 }
4575
4576 cvp_handle = voice_get_cvp_handle(v);
4577 cvp_topology_commit_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4578 APR_HDR_LEN(APR_HDR_SIZE),
4579 APR_PKT_VER);
4580 cvp_topology_commit_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
4581 sizeof(cvp_topology_commit_cmd) - APR_HDR_SIZE);
4582 cvp_topology_commit_cmd.src_port =
4583 voice_get_idx_for_session(v->session_id);
4584 cvp_topology_commit_cmd.dest_port = cvp_handle;
4585 cvp_topology_commit_cmd.token = 0;
4586 cvp_topology_commit_cmd.opcode = VSS_IVOCPROC_CMD_TOPOLOGY_COMMIT;
4587
4588 v->cvp_state = CMD_STATUS_FAIL;
4589 v->async_err = 0;
4590 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_topology_commit_cmd);
4591 if (ret < 0) {
4592 pr_err("%s: Fail in sending VSS_IVOCPROC_CMD_TOPOLOGY_COMMIT\n",
4593 __func__);
4594
4595 ret = -EINVAL;
4596 goto done;
4597 }
4598
4599 ret = wait_event_timeout(v->cvp_wait,
4600 (v->cvp_state == CMD_STATUS_SUCCESS),
4601 msecs_to_jiffies(TIMEOUT_MS));
4602 if (!ret) {
4603 pr_err("%s: wait_event timeout\n", __func__);
4604 ret = -EINVAL;
4605 goto done;
4606 }
4607 if (v->async_err > 0) {
4608 pr_err("%s: DSP returned error[%s]\n",
4609 __func__, adsp_err_get_err_str(
4610 v->async_err));
4611 ret = adsp_err_get_lnx_err_code(
4612 v->async_err);
4613 goto done;
4614 }
4615
4616done:
4617 return ret;
4618}
4619
4620static int voice_send_enable_vocproc_cmd(struct voice_data *v)
4621{
4622 int ret = 0;
4623 struct apr_hdr cvp_enable_cmd;
4624 void *apr_cvp;
4625 u16 cvp_handle;
4626
4627 if (v == NULL) {
4628 pr_err("%s: v is NULL\n", __func__);
4629 return -EINVAL;
4630 }
4631 apr_cvp = common.apr_q6_cvp;
4632
4633 if (!apr_cvp) {
4634 pr_err("%s: apr_cvp is NULL.\n", __func__);
4635 return -EINVAL;
4636 }
4637 cvp_handle = voice_get_cvp_handle(v);
4638
4639 /* enable vocproc and wait for respose */
4640 cvp_enable_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4641 APR_HDR_LEN(APR_HDR_SIZE),
4642 APR_PKT_VER);
4643 cvp_enable_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
4644 sizeof(cvp_enable_cmd) - APR_HDR_SIZE);
4645 pr_debug("cvp_enable_cmd pkt size = %d, cvp_handle=%d\n",
4646 cvp_enable_cmd.pkt_size, cvp_handle);
4647 cvp_enable_cmd.src_port =
4648 voice_get_idx_for_session(v->session_id);
4649 cvp_enable_cmd.dest_port = cvp_handle;
4650 cvp_enable_cmd.token = 0;
4651 cvp_enable_cmd.opcode = VSS_IVOCPROC_CMD_ENABLE;
4652
4653 v->cvp_state = CMD_STATUS_FAIL;
4654 v->async_err = 0;
4655 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_enable_cmd);
4656 if (ret < 0) {
4657 pr_err("Fail in sending VSS_IVOCPROC_CMD_ENABLE\n");
4658 goto fail;
4659 }
4660 ret = wait_event_timeout(v->cvp_wait,
4661 (v->cvp_state == CMD_STATUS_SUCCESS),
4662 msecs_to_jiffies(TIMEOUT_MS));
4663 if (!ret) {
4664 pr_err("%s: wait_event timeout\n", __func__);
4665 goto fail;
4666 }
4667 if (v->async_err > 0) {
4668 pr_err("%s: DSP returned error[%s]\n",
4669 __func__, adsp_err_get_err_str(
4670 v->async_err));
4671 ret = adsp_err_get_lnx_err_code(
4672 v->async_err);
4673 goto fail;
4674 }
4675
4676 return 0;
4677fail:
4678 return ret;
4679}
4680
4681static int voice_send_mvm_cal_network_cmd(struct voice_data *v)
4682{
4683 struct vss_imvm_cmd_set_cal_network_t mvm_set_cal_network;
4684 int ret = 0;
4685 void *apr_mvm;
4686 u16 mvm_handle;
4687
4688 if (v == NULL) {
4689 pr_err("%s: v is NULL\n", __func__);
4690 return -EINVAL;
4691 }
4692 apr_mvm = common.apr_q6_mvm;
4693
4694 if (!apr_mvm) {
4695 pr_err("%s: apr_mvm is NULL.\n", __func__);
4696 return -EINVAL;
4697 }
4698 mvm_handle = voice_get_mvm_handle(v);
4699
4700 mvm_set_cal_network.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4701 APR_HDR_LEN(APR_HDR_SIZE),
4702 APR_PKT_VER);
4703 mvm_set_cal_network.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
4704 sizeof(mvm_set_cal_network) - APR_HDR_SIZE);
4705 mvm_set_cal_network.hdr.src_port =
4706 voice_get_idx_for_session(v->session_id);
4707 mvm_set_cal_network.hdr.dest_port = mvm_handle;
4708 mvm_set_cal_network.hdr.token = 0;
4709 mvm_set_cal_network.hdr.opcode = VSS_IMVM_CMD_SET_CAL_NETWORK;
4710 mvm_set_cal_network.network_id = VSS_ICOMMON_CAL_NETWORK_ID_NONE;
4711
4712 v->mvm_state = CMD_STATUS_FAIL;
4713 v->async_err = 0;
4714 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_cal_network);
4715 if (ret < 0) {
4716 pr_err("%s: Error %d sending SET_NETWORK\n", __func__, ret);
4717 goto fail;
4718 }
4719
4720 ret = wait_event_timeout(v->mvm_wait,
4721 (v->mvm_state == CMD_STATUS_SUCCESS),
4722 msecs_to_jiffies(TIMEOUT_MS));
4723 if (!ret) {
4724 pr_err("%s: wait_event timeout %d\n", __func__, ret);
4725 goto fail;
4726 }
4727 if (v->async_err > 0) {
4728 pr_err("%s: DSP returned error[%s]\n",
4729 __func__, adsp_err_get_err_str(
4730 v->async_err));
4731 ret = adsp_err_get_lnx_err_code(
4732 v->async_err);
4733 goto fail;
4734 }
4735 return 0;
4736fail:
4737 return ret;
4738}
4739
4740static int voice_send_netid_timing_cmd(struct voice_data *v)
4741{
4742 int ret = 0;
4743 void *apr_mvm;
4744 u16 mvm_handle;
4745 struct mvm_set_network_cmd mvm_set_network;
4746 struct mvm_set_voice_timing_cmd mvm_set_voice_timing;
4747
4748 if (v == NULL) {
4749 pr_err("%s: v is NULL\n", __func__);
4750 return -EINVAL;
4751 }
4752 apr_mvm = common.apr_q6_mvm;
4753
4754 if (!apr_mvm) {
4755 pr_err("%s: apr_mvm is NULL.\n", __func__);
4756 return -EINVAL;
4757 }
4758 mvm_handle = voice_get_mvm_handle(v);
4759
4760 ret = voice_config_cvs_vocoder(v);
4761 if (ret < 0) {
4762 pr_err("%s: Error %d configuring CVS voc",
4763 __func__, ret);
4764 goto fail;
4765 }
4766 /* Set network ID. */
4767 pr_debug("Setting network ID %x\n", common.mvs_info.network_type);
4768
4769 mvm_set_network.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4770 APR_HDR_LEN(APR_HDR_SIZE),
4771 APR_PKT_VER);
4772 mvm_set_network.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
4773 sizeof(mvm_set_network) - APR_HDR_SIZE);
4774 mvm_set_network.hdr.src_port =
4775 voice_get_idx_for_session(v->session_id);
4776 mvm_set_network.hdr.dest_port = mvm_handle;
4777 mvm_set_network.hdr.token = 0;
4778 mvm_set_network.hdr.opcode = VSS_IMVM_CMD_SET_CAL_NETWORK;
4779 mvm_set_network.network.network_id = common.mvs_info.network_type;
4780
4781 v->mvm_state = CMD_STATUS_FAIL;
4782 v->async_err = 0;
4783 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_network);
4784 if (ret < 0) {
4785 pr_err("%s: Error %d sending SET_NETWORK\n", __func__, ret);
4786 goto fail;
4787 }
4788
4789 ret = wait_event_timeout(v->mvm_wait,
4790 (v->mvm_state == CMD_STATUS_SUCCESS),
4791 msecs_to_jiffies(TIMEOUT_MS));
4792 if (!ret) {
4793 pr_err("%s: wait_event timeout\n", __func__);
4794 goto fail;
4795 }
4796 if (v->async_err > 0) {
4797 pr_err("%s: DSP returned error[%s]\n",
4798 __func__, adsp_err_get_err_str(
4799 v->async_err));
4800 ret = adsp_err_get_lnx_err_code(
4801 v->async_err);
4802 goto fail;
4803 }
4804
4805 /* Set voice timing. */
4806 pr_debug("Setting voice timing\n");
4807
4808 mvm_set_voice_timing.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4809 APR_HDR_LEN(APR_HDR_SIZE),
4810 APR_PKT_VER);
4811 mvm_set_voice_timing.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
4812 sizeof(mvm_set_voice_timing) -
4813 APR_HDR_SIZE);
4814 mvm_set_voice_timing.hdr.src_port =
4815 voice_get_idx_for_session(v->session_id);
4816 mvm_set_voice_timing.hdr.dest_port = mvm_handle;
4817 mvm_set_voice_timing.hdr.token = 0;
4818 mvm_set_voice_timing.hdr.opcode = VSS_ICOMMON_CMD_SET_VOICE_TIMING;
4819 mvm_set_voice_timing.timing.mode = 0;
4820 mvm_set_voice_timing.timing.enc_offset = 8000;
4821 mvm_set_voice_timing.timing.dec_req_offset = 3300;
4822 mvm_set_voice_timing.timing.dec_offset = 8300;
4823
4824 v->mvm_state = CMD_STATUS_FAIL;
4825 v->async_err = 0;
4826
4827 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_voice_timing);
4828 if (ret < 0) {
4829 pr_err("%s: Error %d sending SET_TIMING\n", __func__, ret);
4830 goto fail;
4831 }
4832
4833 ret = wait_event_timeout(v->mvm_wait,
4834 (v->mvm_state == CMD_STATUS_SUCCESS),
4835 msecs_to_jiffies(TIMEOUT_MS));
4836 if (!ret) {
4837 pr_err("%s: wait_event timeout\n", __func__);
4838 goto fail;
4839 }
4840 if (v->async_err > 0) {
4841 pr_err("%s: DSP returned error[%s]\n",
4842 __func__, adsp_err_get_err_str(
4843 v->async_err));
4844 ret = adsp_err_get_lnx_err_code(
4845 v->async_err);
4846 goto fail;
4847 }
4848
4849 return 0;
4850fail:
4851 return ret;
4852}
4853
4854static int voice_send_attach_vocproc_cmd(struct voice_data *v)
4855{
4856 int ret = 0;
4857 struct mvm_attach_vocproc_cmd mvm_a_vocproc_cmd;
4858 void *apr_mvm;
4859 u16 mvm_handle, cvp_handle;
4860
4861 if (v == NULL) {
4862 pr_err("%s: v is NULL\n", __func__);
4863 return -EINVAL;
4864 }
4865 apr_mvm = common.apr_q6_mvm;
4866
4867 if (!apr_mvm) {
4868 pr_err("%s: apr_mvm is NULL.\n", __func__);
4869 return -EINVAL;
4870 }
4871 mvm_handle = voice_get_mvm_handle(v);
4872 cvp_handle = voice_get_cvp_handle(v);
4873
4874 /* attach vocproc and wait for response */
4875 mvm_a_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4876 APR_HDR_LEN(APR_HDR_SIZE),
4877 APR_PKT_VER);
4878 mvm_a_vocproc_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
4879 sizeof(mvm_a_vocproc_cmd) - APR_HDR_SIZE);
4880 pr_debug("send mvm_a_vocproc_cmd pkt size = %d\n",
4881 mvm_a_vocproc_cmd.hdr.pkt_size);
4882 mvm_a_vocproc_cmd.hdr.src_port =
4883 voice_get_idx_for_session(v->session_id);
4884 mvm_a_vocproc_cmd.hdr.dest_port = mvm_handle;
4885 mvm_a_vocproc_cmd.hdr.token = 0;
4886 mvm_a_vocproc_cmd.hdr.opcode = VSS_IMVM_CMD_ATTACH_VOCPROC;
4887 mvm_a_vocproc_cmd.mvm_attach_cvp_handle.handle = cvp_handle;
4888
4889 v->mvm_state = CMD_STATUS_FAIL;
4890 v->async_err = 0;
4891 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_a_vocproc_cmd);
4892 if (ret < 0) {
4893 pr_err("Fail in sending VSS_IMVM_CMD_ATTACH_VOCPROC\n");
4894 goto fail;
4895 }
4896 ret = wait_event_timeout(v->mvm_wait,
4897 (v->mvm_state == CMD_STATUS_SUCCESS),
4898 msecs_to_jiffies(TIMEOUT_MS));
4899 if (!ret) {
4900 pr_err("%s: wait_event timeout\n", __func__);
4901 goto fail;
4902 }
4903 if (v->async_err > 0) {
4904 pr_err("%s: DSP returned error[%s]\n",
4905 __func__, adsp_err_get_err_str(
4906 v->async_err));
4907 ret = adsp_err_get_lnx_err_code(
4908 v->async_err);
4909 goto fail;
4910 }
4911
4912 return 0;
4913fail:
4914 return ret;
4915}
4916
4917static void voc_update_session_params(struct voice_data *v)
4918{
4919 /* reset LCH mode */
4920 v->lch_mode = 0;
4921
4922 /* clear disable topology setting */
4923 v->disable_topology = false;
4924
4925 /* clear mute setting */
4926 v->dev_rx.dev_mute = common.default_mute_val;
4927 v->dev_tx.dev_mute = common.default_mute_val;
4928 v->stream_rx.stream_mute = common.default_mute_val;
4929 v->stream_tx.stream_mute = common.default_mute_val;
4930}
4931
4932static int voice_destroy_vocproc(struct voice_data *v)
4933{
4934 struct mvm_detach_vocproc_cmd mvm_d_vocproc_cmd;
4935 struct apr_hdr cvp_destroy_session_cmd;
4936 int ret = 0;
4937 void *apr_mvm, *apr_cvp;
4938 u16 mvm_handle, cvp_handle;
4939
4940 if (v == NULL) {
4941 pr_err("%s: v is NULL\n", __func__);
4942 return -EINVAL;
4943 }
4944 apr_mvm = common.apr_q6_mvm;
4945 apr_cvp = common.apr_q6_cvp;
4946
4947 if (!apr_mvm || !apr_cvp) {
4948 pr_err("%s: apr_mvm or apr_cvp is NULL.\n", __func__);
4949 return -EINVAL;
4950 }
4951 mvm_handle = voice_get_mvm_handle(v);
4952 cvp_handle = voice_get_cvp_handle(v);
4953
4954 /* disable slowtalk if st_enable is set */
4955 if (v->st_enable)
4956 voice_send_set_pp_enable_cmd(v, MODULE_ID_VOICE_MODULE_ST, 0);
4957
4958 /* Disable HD Voice if hd_enable is set */
4959 if (v->hd_enable)
4960 voice_send_hd_cmd(v, 0);
4961
4962 /* stop playback or recording */
4963 v->music_info.force = 1;
4964 voice_cvs_stop_playback(v);
4965 voice_cvs_stop_record(v);
4966 /* If voice call is active during VoLTE, SRVCC happens.
4967 * Start recording on voice session if recording started during VoLTE.
4968 */
4969 if (is_volte_session(v->session_id) &&
4970 ((common.voice[VOC_PATH_PASSIVE].voc_state == VOC_RUN) ||
4971 (common.voice[VOC_PATH_PASSIVE].voc_state == VOC_CHANGE))) {
4972 if (v->rec_info.rec_enable) {
4973 voice_cvs_start_record(
4974 &common.voice[VOC_PATH_PASSIVE],
4975 v->rec_info.rec_mode);
4976 common.srvcc_rec_flag = true;
4977
4978 pr_debug("%s: switch recording, srvcc_rec_flag %d\n",
4979 __func__, common.srvcc_rec_flag);
4980 }
4981 }
4982
4983 /* send stop voice cmd */
4984 voice_send_stop_voice_cmd(v);
4985
4986 /* send stop dtmf detecton cmd */
4987 if (v->dtmf_rx_detect_en)
4988 voice_send_dtmf_rx_detection_cmd(v, 0);
4989
4990 /* detach VOCPROC and wait for response from mvm */
4991 mvm_d_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4992 APR_HDR_LEN(APR_HDR_SIZE),
4993 APR_PKT_VER);
4994 mvm_d_vocproc_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
4995 sizeof(mvm_d_vocproc_cmd) - APR_HDR_SIZE);
4996 pr_debug("mvm_d_vocproc_cmd pkt size = %d\n",
4997 mvm_d_vocproc_cmd.hdr.pkt_size);
4998 mvm_d_vocproc_cmd.hdr.src_port =
4999 voice_get_idx_for_session(v->session_id);
5000 mvm_d_vocproc_cmd.hdr.dest_port = mvm_handle;
5001 mvm_d_vocproc_cmd.hdr.token = 0;
5002 mvm_d_vocproc_cmd.hdr.opcode = VSS_IMVM_CMD_DETACH_VOCPROC;
5003 mvm_d_vocproc_cmd.mvm_detach_cvp_handle.handle = cvp_handle;
5004
5005 v->mvm_state = CMD_STATUS_FAIL;
5006 v->async_err = 0;
5007 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_d_vocproc_cmd);
5008 if (ret < 0) {
5009 pr_err("Fail in sending VSS_IMVM_CMD_DETACH_VOCPROC\n");
5010 goto fail;
5011 }
5012 ret = wait_event_timeout(v->mvm_wait,
5013 (v->mvm_state == CMD_STATUS_SUCCESS),
5014 msecs_to_jiffies(TIMEOUT_MS));
5015 if (!ret) {
5016 pr_err("%s: wait_event timeout\n", __func__);
5017 goto fail;
5018 }
5019 if (v->async_err > 0) {
5020 pr_err("%s: DSP returned error[%s]\n",
5021 __func__, adsp_err_get_err_str(
5022 v->async_err));
5023 ret = adsp_err_get_lnx_err_code(
5024 v->async_err);
5025 goto fail;
5026 }
5027
5028 voice_send_cvp_deregister_vol_cal_cmd(v);
5029 voice_send_cvp_deregister_cal_cmd(v);
5030 voice_send_cvp_deregister_dev_cfg_cmd(v);
5031 voice_send_cvs_deregister_cal_cmd(v);
5032
5033 /* destrop cvp session */
5034 cvp_destroy_session_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
5035 APR_HDR_LEN(APR_HDR_SIZE),
5036 APR_PKT_VER);
5037 cvp_destroy_session_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
5038 sizeof(cvp_destroy_session_cmd) - APR_HDR_SIZE);
5039 pr_debug("cvp_destroy_session_cmd pkt size = %d\n",
5040 cvp_destroy_session_cmd.pkt_size);
5041 cvp_destroy_session_cmd.src_port =
5042 voice_get_idx_for_session(v->session_id);
5043 cvp_destroy_session_cmd.dest_port = cvp_handle;
5044 cvp_destroy_session_cmd.token = 0;
5045 cvp_destroy_session_cmd.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
5046
5047 v->cvp_state = CMD_STATUS_FAIL;
5048 v->async_err = 0;
5049 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_destroy_session_cmd);
5050 if (ret < 0) {
5051 pr_err("Fail in sending APRV2_IBASIC_CMD_DESTROY_SESSION\n");
5052 goto fail;
5053 }
5054 ret = wait_event_timeout(v->cvp_wait,
5055 (v->cvp_state == CMD_STATUS_SUCCESS),
5056 msecs_to_jiffies(TIMEOUT_MS));
5057 if (!ret) {
5058 pr_err("%s: wait_event timeout\n", __func__);
5059 goto fail;
5060 }
5061 if (v->async_err > 0) {
5062 pr_err("%s: DSP returned error[%s]\n",
5063 __func__, adsp_err_get_err_str(
5064 v->async_err));
5065 ret = adsp_err_get_lnx_err_code(
5066 v->async_err);
5067 goto fail;
5068 }
5069
5070 rtac_remove_voice(voice_get_cvs_handle(v));
5071 cvp_handle = 0;
5072 voice_set_cvp_handle(v, cvp_handle);
5073 return 0;
5074fail:
5075 return ret;
5076}
5077
5078static int voice_send_mvm_unmap_memory_physical_cmd(struct voice_data *v,
5079 uint32_t mem_handle)
5080{
5081 struct vss_imemory_cmd_unmap_t mem_unmap;
5082 int ret = 0;
5083 void *apr_mvm;
5084 u16 mvm_handle;
5085
5086 if (v == NULL) {
5087 pr_err("%s: v is NULL\n", __func__);
5088 return -EINVAL;
5089 }
5090 apr_mvm = common.apr_q6_mvm;
5091
5092 if (!apr_mvm) {
5093 pr_err("%s: apr_mvm is NULL.\n", __func__);
5094 return -EINVAL;
5095 }
5096 mvm_handle = voice_get_mvm_handle(v);
5097
5098 mem_unmap.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
5099 APR_HDR_LEN(APR_HDR_SIZE),
5100 APR_PKT_VER);
5101 mem_unmap.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
5102 sizeof(mem_unmap) - APR_HDR_SIZE);
5103 mem_unmap.hdr.src_port =
5104 voice_get_idx_for_session(v->session_id);
5105 mem_unmap.hdr.dest_port = mvm_handle;
5106 mem_unmap.hdr.token = 0;
5107 mem_unmap.hdr.opcode = VSS_IMEMORY_CMD_UNMAP;
5108 mem_unmap.mem_handle = mem_handle;
5109
5110 pr_debug("%s: mem_handle: 0x%x\n", __func__, mem_unmap.mem_handle);
5111
5112 v->mvm_state = CMD_STATUS_FAIL;
5113 v->async_err = 0;
5114 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mem_unmap);
5115 if (ret < 0) {
5116 pr_err("mem_unmap op[0x%x]ret[%d]\n",
5117 mem_unmap.hdr.opcode, ret);
5118 goto fail;
5119 }
5120
5121 ret = wait_event_timeout(v->mvm_wait,
5122 (v->mvm_state == CMD_STATUS_SUCCESS),
5123 msecs_to_jiffies(TIMEOUT_MS));
5124 if (!ret) {
5125 pr_err("%s: wait_event timeout %d\n", __func__, ret);
5126 goto fail;
5127 }
5128 if (v->async_err > 0) {
5129 pr_err("%s: DSP returned error[%s]\n",
5130 __func__, adsp_err_get_err_str(
5131 v->async_err));
5132 ret = adsp_err_get_lnx_err_code(
5133 v->async_err);
5134 goto fail;
5135 }
5136 return 0;
5137
5138fail:
5139 return ret;
5140}
5141
5142static int voice_send_cvs_packet_exchange_config_cmd(struct voice_data *v)
5143{
5144 struct vss_istream_cmd_set_oob_packet_exchange_config_t
5145 packet_exchange_config_pkt;
5146 int ret = 0;
5147 void *apr_cvs;
5148 u16 cvs_handle;
5149
5150 if (v == NULL) {
5151 pr_err("%s: v is NULL\n", __func__);
5152 return -EINVAL;
5153 }
5154
5155 apr_cvs = common.apr_q6_cvs;
5156
5157 if (!apr_cvs) {
5158 pr_err("%s: apr_cvs is NULL.\n", __func__);
5159 return -EINVAL;
5160 }
5161 cvs_handle = voice_get_cvs_handle(v);
5162
5163 packet_exchange_config_pkt.hdr.hdr_field = APR_HDR_FIELD(
5164 APR_MSG_TYPE_SEQ_CMD,
5165 APR_HDR_LEN(APR_HDR_SIZE),
5166 APR_PKT_VER);
5167 packet_exchange_config_pkt.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
5168 sizeof(packet_exchange_config_pkt) -
5169 APR_HDR_SIZE);
5170 packet_exchange_config_pkt.hdr.src_port =
5171 voice_get_idx_for_session(v->session_id);
5172 packet_exchange_config_pkt.hdr.dest_port = cvs_handle;
5173 packet_exchange_config_pkt.hdr.token = 0;
5174 packet_exchange_config_pkt.hdr.opcode =
5175 VSS_ISTREAM_CMD_SET_OOB_PACKET_EXCHANGE_CONFIG;
5176 packet_exchange_config_pkt.mem_handle = v->shmem_info.mem_handle;
5177 /* dec buffer address */
5178 packet_exchange_config_pkt.dec_buf_addr_lsw =
5179 lower_32_bits(v->shmem_info.sh_buf.buf[0].phys);
5180 packet_exchange_config_pkt.dec_buf_addr_msw =
5181 msm_audio_populate_upper_32_bits(
5182 v->shmem_info.sh_buf.buf[0].phys);
5183 packet_exchange_config_pkt.dec_buf_size = 4096;
5184 /* enc buffer address */
5185 packet_exchange_config_pkt.enc_buf_addr_lsw =
5186 lower_32_bits(v->shmem_info.sh_buf.buf[1].phys);
5187 packet_exchange_config_pkt.enc_buf_addr_msw =
5188 msm_audio_populate_upper_32_bits(
5189 v->shmem_info.sh_buf.buf[1].phys);
5190 packet_exchange_config_pkt.enc_buf_size = 4096;
5191
5192 pr_debug("%s: dec buf add: lsw %0x msw %0x, size %d, enc buf add: lsw %0x msw %0x, size %d\n",
5193 __func__,
5194 packet_exchange_config_pkt.dec_buf_addr_lsw,
5195 packet_exchange_config_pkt.dec_buf_addr_msw,
5196 packet_exchange_config_pkt.dec_buf_size,
5197 packet_exchange_config_pkt.enc_buf_addr_lsw,
5198 packet_exchange_config_pkt.enc_buf_addr_msw,
5199 packet_exchange_config_pkt.enc_buf_size);
5200
5201 v->cvs_state = CMD_STATUS_FAIL;
5202 v->async_err = 0;
5203 ret = apr_send_pkt(apr_cvs, (uint32_t *) &packet_exchange_config_pkt);
5204 if (ret < 0) {
5205 pr_err("Failed to send packet exchange config cmd %d\n", ret);
5206 goto fail;
5207 }
5208
5209 ret = wait_event_timeout(v->cvs_wait,
5210 (v->cvs_state == CMD_STATUS_SUCCESS),
5211 msecs_to_jiffies(TIMEOUT_MS));
5212 if (!ret)
5213 pr_err("%s: wait_event timeout %d\n", __func__, ret);
5214
5215 if (v->async_err > 0) {
5216 pr_err("%s: DSP returned error[%s]\n",
5217 __func__, adsp_err_get_err_str(
5218 v->async_err));
5219 ret = adsp_err_get_lnx_err_code(
5220 v->async_err);
5221 goto fail;
5222 }
5223
5224 return 0;
5225fail:
5226 return ret;
5227}
5228
5229static int voice_send_cvs_data_exchange_mode_cmd(struct voice_data *v)
5230{
5231 struct vss_istream_cmd_set_packet_exchange_mode_t data_exchange_pkt;
5232 int ret = 0;
5233 void *apr_cvs;
5234 u16 cvs_handle;
5235
5236 if (v == NULL) {
5237 pr_err("%s: v is NULL\n", __func__);
5238 return -EINVAL;
5239 }
5240 apr_cvs = common.apr_q6_cvs;
5241
5242 if (!apr_cvs) {
5243 pr_err("%s: apr_cvs is NULL.\n", __func__);
5244 return -EINVAL;
5245 }
5246 cvs_handle = voice_get_cvs_handle(v);
5247
5248 data_exchange_pkt.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
5249 APR_HDR_LEN(APR_HDR_SIZE),
5250 APR_PKT_VER);
5251 data_exchange_pkt.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
5252 sizeof(data_exchange_pkt) - APR_HDR_SIZE);
5253 data_exchange_pkt.hdr.src_port =
5254 voice_get_idx_for_session(v->session_id);
5255 data_exchange_pkt.hdr.dest_port = cvs_handle;
5256 data_exchange_pkt.hdr.token = 0;
5257 data_exchange_pkt.hdr.opcode = VSS_ISTREAM_CMD_SET_PACKET_EXCHANGE_MODE;
5258 data_exchange_pkt.mode = VSS_ISTREAM_PACKET_EXCHANGE_MODE_OUT_OF_BAND;
5259
5260 v->cvs_state = CMD_STATUS_FAIL;
5261 v->async_err = 0;
5262 ret = apr_send_pkt(apr_cvs, (uint32_t *) &data_exchange_pkt);
5263 if (ret < 0) {
5264 pr_err("Failed to send data exchange mode %d\n", ret);
5265 goto fail;
5266 }
5267
5268 ret = wait_event_timeout(v->cvs_wait,
5269 (v->cvs_state == CMD_STATUS_SUCCESS),
5270 msecs_to_jiffies(TIMEOUT_MS));
5271 if (!ret)
5272 pr_err("%s: wait_event timeout %d\n", __func__, ret);
5273
5274 if (v->async_err > 0) {
5275 pr_err("%s: DSP returned error[%s]\n",
5276 __func__, adsp_err_get_err_str(
5277 v->async_err));
5278 ret = adsp_err_get_lnx_err_code(
5279 v->async_err);
5280 goto fail;
5281 }
5282 return 0;
5283fail:
5284 return ret;
5285}
5286
5287static int voice_send_stream_mute_cmd(struct voice_data *v, uint16_t direction,
5288 uint16_t mute_flag, uint32_t ramp_duration)
5289{
5290 struct cvs_set_mute_cmd cvs_mute_cmd;
5291 int ret = 0;
5292
5293 if (v == NULL) {
5294 pr_err("%s: v is NULL\n", __func__);
5295 ret = -EINVAL;
5296 goto fail;
5297 }
5298
5299 if (!common.apr_q6_cvs) {
5300 pr_err("%s: apr_cvs is NULL.\n", __func__);
5301 ret = -EINVAL;
5302 goto fail;
5303 }
5304
5305 /* send mute/unmute to cvs */
5306 cvs_mute_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
5307 APR_HDR_LEN(APR_HDR_SIZE),
5308 APR_PKT_VER);
5309 cvs_mute_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
5310 sizeof(cvs_mute_cmd) - APR_HDR_SIZE);
5311 cvs_mute_cmd.hdr.src_port =
5312 voice_get_idx_for_session(v->session_id);
5313 cvs_mute_cmd.hdr.dest_port = voice_get_cvs_handle(v);
5314 cvs_mute_cmd.hdr.token = 0;
5315 cvs_mute_cmd.hdr.opcode = VSS_IVOLUME_CMD_MUTE_V2;
5316 cvs_mute_cmd.cvs_set_mute.direction = direction;
5317 cvs_mute_cmd.cvs_set_mute.mute_flag = mute_flag;
5318 cvs_mute_cmd.cvs_set_mute.ramp_duration_ms = ramp_duration;
5319
5320 v->cvs_state = CMD_STATUS_FAIL;
5321 v->async_err = 0;
5322 ret = apr_send_pkt(common.apr_q6_cvs, (uint32_t *) &cvs_mute_cmd);
5323 if (ret < 0) {
5324 pr_err("%s: Error %d sending stream mute\n", __func__, ret);
5325
5326 goto fail;
5327 }
5328 ret = wait_event_timeout(v->cvs_wait,
5329 (v->cvs_state == CMD_STATUS_SUCCESS),
5330 msecs_to_jiffies(TIMEOUT_MS));
5331 if (!ret) {
5332 pr_err("%s: Command timeout\n", __func__);
5333 goto fail;
5334 }
5335 if (v->async_err > 0) {
5336 pr_err("%s: DSP returned error[%s]\n",
5337 __func__, adsp_err_get_err_str(
5338 v->async_err));
5339 ret = adsp_err_get_lnx_err_code(
5340 v->async_err);
5341 goto fail;
5342 }
5343
5344 return 0;
5345
5346fail:
5347 return ret;
5348}
5349
5350static int voice_send_device_mute_cmd(struct voice_data *v, uint16_t direction,
5351 uint16_t mute_flag, uint32_t ramp_duration)
5352{
5353 struct cvp_set_mute_cmd cvp_mute_cmd;
5354 int ret = 0;
5355
5356 if (v == NULL) {
5357 pr_err("%s: v is NULL\n", __func__);
5358 ret = -EINVAL;
5359 goto fail;
5360 }
5361
5362 if (!common.apr_q6_cvp) {
5363 pr_err("%s: apr_cvp is NULL.\n", __func__);
5364 ret = -EINVAL;
5365 goto fail;
5366 }
5367
5368 cvp_mute_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
5369 APR_HDR_LEN(APR_HDR_SIZE),
5370 APR_PKT_VER);
5371 cvp_mute_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
5372 sizeof(cvp_mute_cmd) - APR_HDR_SIZE);
5373 cvp_mute_cmd.hdr.src_port =
5374 voice_get_idx_for_session(v->session_id);
5375 cvp_mute_cmd.hdr.dest_port = voice_get_cvp_handle(v);
5376 cvp_mute_cmd.hdr.token = 0;
5377 cvp_mute_cmd.hdr.opcode = VSS_IVOLUME_CMD_MUTE_V2;
5378 cvp_mute_cmd.cvp_set_mute.direction = direction;
5379 cvp_mute_cmd.cvp_set_mute.mute_flag = mute_flag;
5380 cvp_mute_cmd.cvp_set_mute.ramp_duration_ms = ramp_duration;
5381
5382 v->cvp_state = CMD_STATUS_FAIL;
5383 v->async_err = 0;
5384 ret = apr_send_pkt(common.apr_q6_cvp, (uint32_t *) &cvp_mute_cmd);
5385 if (ret < 0) {
5386 pr_err("%s: Error %d sending rx device cmd\n", __func__, ret);
5387
5388 goto fail;
5389 }
5390 ret = wait_event_timeout(v->cvp_wait,
5391 (v->cvp_state == CMD_STATUS_SUCCESS),
5392 msecs_to_jiffies(TIMEOUT_MS));
5393 if (!ret) {
5394 pr_err("%s: Command timeout\n", __func__);
5395 goto fail;
5396 }
5397 if (v->async_err > 0) {
5398 pr_err("%s: DSP returned error[%s]\n",
5399 __func__, adsp_err_get_err_str(
5400 v->async_err));
5401 ret = adsp_err_get_lnx_err_code(
5402 v->async_err);
5403 goto fail;
5404 }
5405
5406 return 0;
5407
5408fail:
5409 return ret;
5410}
5411
5412static int voice_send_vol_step_cmd(struct voice_data *v)
5413{
5414 struct cvp_set_rx_volume_step_cmd cvp_vol_step_cmd;
5415 int ret = 0;
5416 void *apr_cvp;
5417 u16 cvp_handle;
5418
5419 if (v == NULL) {
5420 pr_err("%s: v is NULL\n", __func__);
5421 return -EINVAL;
5422 }
5423 apr_cvp = common.apr_q6_cvp;
5424
5425 if (!apr_cvp) {
5426 pr_err("%s: apr_cvp is NULL.\n", __func__);
5427 return -EINVAL;
5428 }
5429 cvp_handle = voice_get_cvp_handle(v);
5430
5431 /* send volume index to cvp */
5432 cvp_vol_step_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
5433 APR_HDR_LEN(APR_HDR_SIZE),
5434 APR_PKT_VER);
5435 cvp_vol_step_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
5436 sizeof(cvp_vol_step_cmd) - APR_HDR_SIZE);
5437 cvp_vol_step_cmd.hdr.src_port =
5438 voice_get_idx_for_session(v->session_id);
5439 cvp_vol_step_cmd.hdr.dest_port = cvp_handle;
5440 cvp_vol_step_cmd.hdr.token = 0;
5441 cvp_vol_step_cmd.hdr.opcode = VSS_IVOLUME_CMD_SET_STEP;
5442 cvp_vol_step_cmd.cvp_set_vol_step.direction = VSS_IVOLUME_DIRECTION_RX;
5443 cvp_vol_step_cmd.cvp_set_vol_step.value = v->dev_rx.volume_step_value;
5444 cvp_vol_step_cmd.cvp_set_vol_step.ramp_duration_ms =
5445 v->dev_rx.volume_ramp_duration_ms;
5446 pr_debug("%s step_value:%d, ramp_duration_ms:%d",
5447 __func__,
5448 cvp_vol_step_cmd.cvp_set_vol_step.value,
5449 cvp_vol_step_cmd.cvp_set_vol_step.ramp_duration_ms);
5450
5451 v->cvp_state = CMD_STATUS_FAIL;
5452 v->async_err = 0;
5453 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_vol_step_cmd);
5454 if (ret < 0) {
5455 pr_err("Fail in sending RX VOL step\n");
5456 return -EINVAL;
5457 }
5458 ret = wait_event_timeout(v->cvp_wait,
5459 (v->cvp_state == CMD_STATUS_SUCCESS),
5460 msecs_to_jiffies(TIMEOUT_MS));
5461 if (!ret) {
5462 pr_err("%s: wait_event timeout\n", __func__);
5463 return -EINVAL;
5464 }
5465 if (v->async_err > 0) {
5466 pr_err("%s: DSP returned error[%s]\n",
5467 __func__, adsp_err_get_err_str(
5468 v->async_err));
5469 ret = adsp_err_get_lnx_err_code(
5470 v->async_err);
5471 return ret;
5472 }
5473 return 0;
5474}
5475
5476static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode)
5477{
5478 int ret = 0;
5479 void *apr_cvs;
5480 u16 cvs_handle;
5481
5482 struct cvs_start_record_cmd cvs_start_record;
5483
5484 if (v == NULL) {
5485 pr_err("%s: v is NULL\n", __func__);
5486 return -EINVAL;
5487 }
5488 apr_cvs = common.apr_q6_cvs;
5489
5490 if (!apr_cvs) {
5491 pr_err("%s: apr_cvs is NULL.\n", __func__);
5492 return -EINVAL;
5493 }
5494
5495 cvs_handle = voice_get_cvs_handle(v);
5496
5497 if (!v->rec_info.recording) {
5498 cvs_start_record.hdr.hdr_field = APR_HDR_FIELD(
5499 APR_MSG_TYPE_SEQ_CMD,
5500 APR_HDR_LEN(APR_HDR_SIZE),
5501 APR_PKT_VER);
5502 cvs_start_record.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
5503 sizeof(cvs_start_record) - APR_HDR_SIZE);
5504 cvs_start_record.hdr.src_port =
5505 voice_get_idx_for_session(v->session_id);
5506 cvs_start_record.hdr.dest_port = cvs_handle;
5507 cvs_start_record.hdr.token = 0;
5508 cvs_start_record.hdr.opcode = VSS_IRECORD_CMD_START;
5509
5510 cvs_start_record.rec_mode.port_id =
5511 VSS_IRECORD_PORT_ID_DEFAULT;
5512 if (rec_mode == VOC_REC_UPLINK) {
5513 cvs_start_record.rec_mode.rx_tap_point =
5514 VSS_IRECORD_TAP_POINT_NONE;
5515 cvs_start_record.rec_mode.tx_tap_point =
5516 VSS_IRECORD_TAP_POINT_STREAM_END;
5517 } else if (rec_mode == VOC_REC_DOWNLINK) {
5518 cvs_start_record.rec_mode.rx_tap_point =
5519 VSS_IRECORD_TAP_POINT_STREAM_END;
5520 cvs_start_record.rec_mode.tx_tap_point =
5521 VSS_IRECORD_TAP_POINT_NONE;
5522 } else if (rec_mode == VOC_REC_BOTH) {
5523 cvs_start_record.rec_mode.rx_tap_point =
5524 VSS_IRECORD_TAP_POINT_STREAM_END;
5525 cvs_start_record.rec_mode.tx_tap_point =
5526 VSS_IRECORD_TAP_POINT_STREAM_END;
5527 } else {
5528 pr_err("%s: Invalid in-call rec_mode %d\n", __func__,
5529 rec_mode);
5530
5531 ret = -EINVAL;
5532 goto fail;
5533 }
5534
5535 v->cvs_state = CMD_STATUS_FAIL;
5536 v->async_err = 0;
5537
5538 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_start_record);
5539 if (ret < 0) {
5540 pr_err("%s: Error %d sending START_RECORD\n", __func__,
5541 ret);
5542
5543 goto fail;
5544 }
5545
5546 ret = wait_event_timeout(v->cvs_wait,
5547 (v->cvs_state == CMD_STATUS_SUCCESS),
5548 msecs_to_jiffies(TIMEOUT_MS));
5549
5550 if (!ret) {
5551 pr_err("%s: wait_event timeout\n", __func__);
5552
5553 goto fail;
5554 }
5555 if (v->async_err > 0) {
5556 pr_err("%s: DSP returned error[%s]\n",
5557 __func__, adsp_err_get_err_str(
5558 v->async_err));
5559 ret = adsp_err_get_lnx_err_code(
5560 v->async_err);
5561 goto fail;
5562 }
5563 v->rec_info.recording = 1;
5564 } else {
5565 pr_debug("%s: Start record already sent\n", __func__);
5566 }
5567
5568 return 0;
5569
5570fail:
5571 return ret;
5572}
5573
5574static int voice_cvs_stop_record(struct voice_data *v)
5575{
5576 int ret = 0;
5577 void *apr_cvs;
5578 u16 cvs_handle;
5579 struct apr_hdr cvs_stop_record;
5580
5581 if (v == NULL) {
5582 pr_err("%s: v is NULL\n", __func__);
5583 return -EINVAL;
5584 }
5585 apr_cvs = common.apr_q6_cvs;
5586
5587 if (!apr_cvs) {
5588 pr_err("%s: apr_cvs is NULL.\n", __func__);
5589 return -EINVAL;
5590 }
5591
5592 cvs_handle = voice_get_cvs_handle(v);
5593
5594 if (v->rec_info.recording) {
5595 cvs_stop_record.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
5596 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
5597 cvs_stop_record.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
5598 sizeof(cvs_stop_record) - APR_HDR_SIZE);
5599 cvs_stop_record.src_port =
5600 voice_get_idx_for_session(v->session_id);
5601 cvs_stop_record.dest_port = cvs_handle;
5602 cvs_stop_record.token = 0;
5603 cvs_stop_record.opcode = VSS_IRECORD_CMD_STOP;
5604
5605 v->cvs_state = CMD_STATUS_FAIL;
5606 v->async_err = 0;
5607
5608 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_stop_record);
5609 if (ret < 0) {
5610 pr_err("%s: Error %d sending STOP_RECORD\n",
5611 __func__, ret);
5612
5613 goto fail;
5614 }
5615
5616 ret = wait_event_timeout(v->cvs_wait,
5617 (v->cvs_state == CMD_STATUS_SUCCESS),
5618 msecs_to_jiffies(TIMEOUT_MS));
5619 if (!ret) {
5620 pr_err("%s: wait_event timeout\n", __func__);
5621
5622 goto fail;
5623 }
5624 if (v->async_err > 0) {
5625 pr_err("%s: DSP returned error[%s]\n",
5626 __func__, adsp_err_get_err_str(
5627 v->async_err));
5628 ret = adsp_err_get_lnx_err_code(
5629 v->async_err);
5630 goto fail;
5631 }
5632 v->rec_info.recording = 0;
5633 } else {
5634 pr_debug("%s: Stop record already sent\n", __func__);
5635 }
5636
5637 return 0;
5638
5639fail:
5640 return ret;
5641}
5642
5643int voc_start_record(uint32_t port_id, uint32_t set, uint32_t session_id)
5644{
5645 int ret = 0;
5646 int rec_mode = 0;
5647 u16 cvs_handle;
5648 int rec_set = 0;
5649 struct voice_session_itr itr;
5650 struct voice_data *v = NULL;
5651
5652 /* check if session_id is valid */
5653 if (!voice_is_valid_session_id(session_id)) {
5654 pr_err("%s: Invalid session id:%u\n", __func__,
5655 session_id);
5656
5657 return -EINVAL;
5658 }
5659
5660 voice_itr_init(&itr, session_id);
5661 pr_debug("%s: session_id:%u\n", __func__, session_id);
5662
5663 while (voice_itr_get_next_session(&itr, &v)) {
5664 if (v == NULL) {
5665 pr_err("%s: v is NULL, sessionid:%u\n", __func__,
5666 session_id);
5667
5668 break;
5669 }
5670 pr_debug("%s: port_id: %d, set: %d, v: %pK\n",
5671 __func__, port_id, set, v);
5672
5673 mutex_lock(&v->lock);
5674 rec_mode = v->rec_info.rec_mode;
5675 rec_set = set;
5676 if (set) {
5677 if ((v->rec_route_state.ul_flag != 0) &&
5678 (v->rec_route_state.dl_flag != 0)) {
5679 pr_debug("%s: rec mode already set.\n",
5680 __func__);
5681
5682 mutex_unlock(&v->lock);
5683 continue;
5684 }
5685
5686 if (port_id == VOICE_RECORD_TX) {
5687 if ((v->rec_route_state.ul_flag == 0)
5688 && (v->rec_route_state.dl_flag == 0)) {
5689 rec_mode = VOC_REC_UPLINK;
5690 v->rec_route_state.ul_flag = 1;
5691 } else if ((v->rec_route_state.ul_flag == 0)
5692 && (v->rec_route_state.dl_flag != 0)) {
5693 voice_cvs_stop_record(v);
5694 rec_mode = VOC_REC_BOTH;
5695 v->rec_route_state.ul_flag = 1;
5696 }
5697 } else if (port_id == VOICE_RECORD_RX) {
5698 if ((v->rec_route_state.ul_flag == 0)
5699 && (v->rec_route_state.dl_flag == 0)) {
5700 rec_mode = VOC_REC_DOWNLINK;
5701 v->rec_route_state.dl_flag = 1;
5702 } else if ((v->rec_route_state.ul_flag != 0)
5703 && (v->rec_route_state.dl_flag == 0)) {
5704 voice_cvs_stop_record(v);
5705 rec_mode = VOC_REC_BOTH;
5706 v->rec_route_state.dl_flag = 1;
5707 }
5708 }
5709 rec_set = 1;
5710 } else {
5711 if ((v->rec_route_state.ul_flag == 0) &&
5712 (v->rec_route_state.dl_flag == 0)) {
5713 pr_debug("%s: rec already stops.\n",
5714 __func__);
5715 mutex_unlock(&v->lock);
5716 continue;
5717 }
5718
5719 if (port_id == VOICE_RECORD_TX) {
5720 if ((v->rec_route_state.ul_flag != 0)
5721 && (v->rec_route_state.dl_flag == 0)) {
5722 v->rec_route_state.ul_flag = 0;
5723 rec_set = 0;
5724 } else if ((v->rec_route_state.ul_flag != 0)
5725 && (v->rec_route_state.dl_flag != 0)) {
5726 voice_cvs_stop_record(v);
5727 v->rec_route_state.ul_flag = 0;
5728 rec_mode = VOC_REC_DOWNLINK;
5729 rec_set = 1;
5730 }
5731 } else if (port_id == VOICE_RECORD_RX) {
5732 if ((v->rec_route_state.ul_flag == 0)
5733 && (v->rec_route_state.dl_flag != 0)) {
5734 v->rec_route_state.dl_flag = 0;
5735 rec_set = 0;
5736 } else if ((v->rec_route_state.ul_flag != 0)
5737 && (v->rec_route_state.dl_flag != 0)) {
5738 voice_cvs_stop_record(v);
5739 v->rec_route_state.dl_flag = 0;
5740 rec_mode = VOC_REC_UPLINK;
5741 rec_set = 1;
5742 }
5743 }
5744 }
5745 pr_debug("%s: mode =%d, set =%d\n", __func__,
5746 rec_mode, rec_set);
5747 cvs_handle = voice_get_cvs_handle(v);
5748
5749 if (cvs_handle != 0) {
5750 if (rec_set)
5751 ret = voice_cvs_start_record(v, rec_mode);
5752 else
5753 ret = voice_cvs_stop_record(v);
5754 }
5755
5756 /* During SRVCC, recording will switch from VoLTE session to
5757 * voice session.
5758 * Then stop recording, need to stop recording on voice session.
5759 */
5760 if ((!rec_set) && common.srvcc_rec_flag) {
5761 pr_debug("%s, srvcc_rec_flag:%d\n", __func__,
5762 common.srvcc_rec_flag);
5763
5764 voice_cvs_stop_record(&common.voice[VOC_PATH_PASSIVE]);
5765 common.srvcc_rec_flag = false;
5766 }
5767
5768 /* Cache the value */
5769 v->rec_info.rec_enable = rec_set;
5770 v->rec_info.rec_mode = rec_mode;
5771
5772 mutex_unlock(&v->lock);
5773 }
5774
5775 return ret;
5776}
5777
5778static int voice_cvs_start_playback(struct voice_data *v)
5779{
5780 int ret = 0;
5781 struct cvs_start_playback_cmd cvs_start_playback;
5782 void *apr_cvs;
5783 u16 cvs_handle;
5784
5785 if (v == NULL) {
5786 pr_err("%s: v is NULL\n", __func__);
5787 return -EINVAL;
5788 }
5789 apr_cvs = common.apr_q6_cvs;
5790
5791 if (!apr_cvs) {
5792 pr_err("%s: apr_cvs is NULL.\n", __func__);
5793 return -EINVAL;
5794 }
5795
5796 cvs_handle = voice_get_cvs_handle(v);
5797
5798 if (!v->music_info.playing && v->music_info.count) {
5799 cvs_start_playback.hdr.hdr_field = APR_HDR_FIELD(
5800 APR_MSG_TYPE_SEQ_CMD,
5801 APR_HDR_LEN(APR_HDR_SIZE),
5802 APR_PKT_VER);
5803 cvs_start_playback.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
5804 sizeof(cvs_start_playback) - APR_HDR_SIZE);
5805 cvs_start_playback.hdr.src_port =
5806 voice_get_idx_for_session(v->session_id);
5807 cvs_start_playback.hdr.dest_port = cvs_handle;
5808 cvs_start_playback.hdr.token = 0;
5809 cvs_start_playback.hdr.opcode = VSS_IPLAYBACK_CMD_START;
5810 cvs_start_playback.playback_mode.port_id =
5811 v->music_info.port_id;
5812
5813 v->cvs_state = CMD_STATUS_FAIL;
5814 v->async_err = 0;
5815
5816 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_start_playback);
5817
5818 if (ret < 0) {
5819 pr_err("%s: Error %d sending START_PLAYBACK\n",
5820 __func__, ret);
5821
5822 goto fail;
5823 }
5824
5825 ret = wait_event_timeout(v->cvs_wait,
5826 (v->cvs_state == CMD_STATUS_SUCCESS),
5827 msecs_to_jiffies(TIMEOUT_MS));
5828 if (!ret) {
5829 pr_err("%s: wait_event timeout\n", __func__);
5830
5831 goto fail;
5832 }
5833 if (v->async_err > 0) {
5834 pr_err("%s: DSP returned error[%s]\n",
5835 __func__, adsp_err_get_err_str(
5836 v->async_err));
5837 ret = adsp_err_get_lnx_err_code(
5838 v->async_err);
5839 goto fail;
5840 }
5841
5842 v->music_info.playing = 1;
5843 } else {
5844 pr_debug("%s: Start playback already sent\n", __func__);
5845 }
5846
5847 return 0;
5848
5849fail:
5850 return ret;
5851}
5852
5853static int voice_cvs_stop_playback(struct voice_data *v)
5854{
5855 int ret = 0;
5856 struct apr_hdr cvs_stop_playback;
5857 void *apr_cvs;
5858 u16 cvs_handle;
5859
5860 if (v == NULL) {
5861 pr_err("%s: v is NULL\n", __func__);
5862 return -EINVAL;
5863 }
5864 apr_cvs = common.apr_q6_cvs;
5865
5866 if (!apr_cvs) {
5867 pr_err("%s: apr_cvs is NULL.\n", __func__);
5868 return -EINVAL;
5869 }
5870
5871 cvs_handle = voice_get_cvs_handle(v);
5872
5873 if (v->music_info.playing && ((!v->music_info.count) ||
5874 (v->music_info.force))) {
5875 cvs_stop_playback.hdr_field =
5876 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
5877 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
5878 cvs_stop_playback.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
5879 sizeof(cvs_stop_playback) - APR_HDR_SIZE);
5880 cvs_stop_playback.src_port =
5881 voice_get_idx_for_session(v->session_id);
5882 cvs_stop_playback.dest_port = cvs_handle;
5883 cvs_stop_playback.token = 0;
5884
5885 cvs_stop_playback.opcode = VSS_IPLAYBACK_CMD_STOP;
5886
5887 v->cvs_state = CMD_STATUS_FAIL;
5888 v->async_err = 0;
5889
5890 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_stop_playback);
5891 if (ret < 0) {
5892 pr_err("%s: Error %d sending STOP_PLAYBACK\n",
5893 __func__, ret);
5894
5895
5896 goto fail;
5897 }
5898
5899 ret = wait_event_timeout(v->cvs_wait,
5900 (v->cvs_state == CMD_STATUS_SUCCESS),
5901 msecs_to_jiffies(TIMEOUT_MS));
5902 if (!ret) {
5903 pr_err("%s: wait_event timeout\n", __func__);
5904
5905 goto fail;
5906 }
5907 if (v->async_err > 0) {
5908 pr_err("%s: DSP returned error[%s]\n",
5909 __func__, adsp_err_get_err_str(
5910 v->async_err));
5911 ret = adsp_err_get_lnx_err_code(
5912 v->async_err);
5913 goto fail;
5914 }
5915
5916 v->music_info.playing = 0;
5917 v->music_info.force = 0;
5918 } else {
5919 pr_debug("%s: Stop playback already sent\n", __func__);
5920 }
5921
5922 return 0;
5923
5924fail:
5925 return ret;
5926}
5927
5928static int voc_lch_ops(struct voice_data *v, enum voice_lch_mode lch_mode)
5929{
5930 int ret = 0;
5931
5932 if (v == NULL) {
5933 pr_err("%s: v is NULL\n", __func__);
5934
5935 ret = -EINVAL;
5936 goto done;
5937 }
5938
5939 switch (lch_mode) {
5940 case VOICE_LCH_START:
5941
5942 ret = voc_end_voice_call(v->session_id);
5943 if (ret < 0)
5944 pr_err("%s: voice call end failed %d\n",
5945 __func__, ret);
5946 break;
5947 case VOICE_LCH_STOP:
5948
5949 ret = voc_start_voice_call(v->session_id);
5950 if (ret < 0) {
5951 pr_err("%s: voice call start failed %d\n",
5952 __func__, ret);
5953 goto done;
5954 }
5955 break;
5956 default:
5957 pr_err("%s: Invalid LCH mode: %d\n",
5958 __func__, v->lch_mode);
5959 break;
5960 }
5961done:
5962 return ret;
5963}
5964
5965int voc_start_playback(uint32_t set, uint16_t port_id)
5966{
5967 struct voice_data *v = NULL;
5968 int ret = 0;
5969 struct voice_session_itr itr;
5970 u16 cvs_handle;
5971
5972 pr_debug("%s port_id = %#x set = %d", __func__, port_id, set);
5973
5974 voice_itr_init(&itr, ALL_SESSION_VSID);
5975 while (voice_itr_get_next_session(&itr, &v)) {
5976 if ((v != NULL) &&
5977 (((port_id == VOICE_PLAYBACK_TX) &&
5978 is_sub1_vsid(v->session_id)) ||
5979 ((port_id == VOICE2_PLAYBACK_TX) &&
5980 is_sub2_vsid(v->session_id)))) {
5981
5982 mutex_lock(&v->lock);
5983 v->music_info.port_id = port_id;
5984 v->music_info.play_enable = set;
5985 if (set)
5986 v->music_info.count++;
5987 else
5988 v->music_info.count--;
5989 pr_debug("%s: music_info count=%d\n", __func__,
5990 v->music_info.count);
5991
5992 cvs_handle = voice_get_cvs_handle(v);
5993 if (cvs_handle != 0) {
5994 if (set)
5995 ret = voice_cvs_start_playback(v);
5996 else
5997 ret = voice_cvs_stop_playback(v);
5998 }
5999 mutex_unlock(&v->lock);
6000 } else {
6001 pr_err("%s: Invalid session\n", __func__);
6002 }
6003 }
6004
6005 return ret;
6006}
6007
6008int voc_disable_topology(uint32_t session_id, uint32_t disable)
6009{
6010 struct voice_data *v = voice_get_session(session_id);
6011 int ret = 0;
6012
6013 if (v == NULL) {
6014 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
6015
6016 return -EINVAL;
6017 }
6018
6019 mutex_lock(&v->lock);
6020
6021 v->disable_topology = disable;
6022
6023 mutex_unlock(&v->lock);
6024
6025 return ret;
6026}
6027
6028static int voice_set_packet_exchange_mode_and_config(uint32_t session_id,
6029 uint32_t mode)
6030{
6031 struct voice_data *v = voice_get_session(session_id);
6032 int ret = 0;
6033
6034 if (v == NULL) {
6035 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
6036 return -EINVAL;
6037 }
6038
6039 if (v->voc_state != VOC_RUN)
6040 ret = voice_send_cvs_data_exchange_mode_cmd(v);
6041
6042 if (ret) {
6043 pr_err("%s: Error voice_send_data_exchange_mode_cmd %d\n",
6044 __func__, ret);
6045 goto fail;
6046 }
6047
6048 ret = voice_send_cvs_packet_exchange_config_cmd(v);
6049 if (ret) {
6050 pr_err("%s: Error: voice_send_packet_exchange_config_cmd %d\n",
6051 __func__, ret);
6052 goto fail;
6053 }
6054
6055 return ret;
6056fail:
6057 return -EINVAL;
6058}
6059
6060int voc_set_tx_mute(uint32_t session_id, uint32_t dir, uint32_t mute,
6061 uint32_t ramp_duration)
6062{
6063 struct voice_data *v = NULL;
6064 int ret = 0;
6065 struct voice_session_itr itr;
6066
6067 voice_itr_init(&itr, session_id);
6068 while (voice_itr_get_next_session(&itr, &v)) {
6069 if (v != NULL) {
6070 mutex_lock(&v->lock);
6071 v->stream_tx.stream_mute = mute;
6072 v->stream_tx.stream_mute_ramp_duration_ms =
6073 ramp_duration;
6074 if (is_voc_state_active(v->voc_state) &&
6075 (v->lch_mode == 0))
6076 ret = voice_send_stream_mute_cmd(v,
6077 VSS_IVOLUME_DIRECTION_TX,
6078 v->stream_tx.stream_mute,
6079 v->stream_tx.stream_mute_ramp_duration_ms);
6080 mutex_unlock(&v->lock);
6081 } else {
6082 pr_err("%s: invalid session_id 0x%x\n", __func__,
6083 session_id);
6084
6085 ret = -EINVAL;
6086 break;
6087 }
6088 }
6089
6090 return ret;
6091}
6092
6093int voc_set_device_mute(uint32_t session_id, uint32_t dir, uint32_t mute,
6094 uint32_t ramp_duration)
6095{
6096 struct voice_data *v = NULL;
6097 int ret = 0;
6098 struct voice_session_itr itr;
6099
6100 voice_itr_init(&itr, session_id);
6101 while (voice_itr_get_next_session(&itr, &v)) {
6102 if (v != NULL) {
6103 mutex_lock(&v->lock);
6104 if (dir == VSS_IVOLUME_DIRECTION_TX) {
6105 v->dev_tx.dev_mute = mute;
6106 v->dev_tx.dev_mute_ramp_duration_ms =
6107 ramp_duration;
6108 } else {
6109 v->dev_rx.dev_mute = mute;
6110 v->dev_rx.dev_mute_ramp_duration_ms =
6111 ramp_duration;
6112 }
6113
6114 if (((v->voc_state == VOC_RUN) ||
6115 (v->voc_state == VOC_STANDBY)) &&
6116 (v->lch_mode == 0))
6117 ret = voice_send_device_mute_cmd(v,
6118 dir,
6119 mute,
6120 ramp_duration);
6121 mutex_unlock(&v->lock);
6122 } else {
6123 pr_err("%s: invalid session_id 0x%x\n", __func__,
6124 session_id);
6125
6126 ret = -EINVAL;
6127 break;
6128 }
6129 }
6130
6131 return ret;
6132}
6133
6134int voc_get_rx_device_mute(uint32_t session_id)
6135{
6136 struct voice_data *v = voice_get_session(session_id);
6137 int ret = 0;
6138
6139 if (v == NULL) {
6140 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
6141
6142 return -EINVAL;
6143 }
6144
6145 mutex_lock(&v->lock);
6146
6147 ret = v->dev_rx.dev_mute;
6148
6149 mutex_unlock(&v->lock);
6150
6151 return ret;
6152}
6153
6154int voc_set_tty_mode(uint32_t session_id, uint8_t tty_mode)
6155{
6156 struct voice_data *v = voice_get_session(session_id);
6157 int ret = 0;
6158
6159 if (v == NULL) {
6160 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
6161
6162 return -EINVAL;
6163 }
6164
6165 mutex_lock(&v->lock);
6166
6167 v->tty_mode = tty_mode;
6168
6169 mutex_unlock(&v->lock);
6170
6171 return ret;
6172}
6173
6174uint8_t voc_get_tty_mode(uint32_t session_id)
6175{
6176 struct voice_data *v = voice_get_session(session_id);
6177 int ret = 0;
6178
6179 if (v == NULL) {
6180 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
6181
6182 return -EINVAL;
6183 }
6184
6185 mutex_lock(&v->lock);
6186
6187 ret = v->tty_mode;
6188
6189 mutex_unlock(&v->lock);
6190
6191 return ret;
6192}
6193
6194int voc_set_pp_enable(uint32_t session_id, uint32_t module_id, uint32_t enable)
6195{
6196 struct voice_data *v = NULL;
6197 int ret = 0;
6198 struct voice_session_itr itr;
6199
6200 voice_itr_init(&itr, session_id);
6201 while (voice_itr_get_next_session(&itr, &v)) {
6202 if (v != NULL) {
6203 if (!(is_voice_app_id(v->session_id)))
6204 continue;
6205
6206 mutex_lock(&v->lock);
6207 if (module_id == MODULE_ID_VOICE_MODULE_ST)
6208 v->st_enable = enable;
6209
6210 if (v->voc_state == VOC_RUN) {
6211 if ((module_id == MODULE_ID_VOICE_MODULE_ST) &&
6212 (!v->tty_mode))
6213 ret = voice_send_set_pp_enable_cmd(v,
6214 MODULE_ID_VOICE_MODULE_ST,
6215 enable);
6216 }
6217 mutex_unlock(&v->lock);
6218 } else {
6219 pr_err("%s: invalid session_id 0x%x\n", __func__,
6220 session_id);
6221 ret = -EINVAL;
6222 break;
6223 }
6224 }
6225
6226 return ret;
6227}
6228
6229int voc_set_hd_enable(uint32_t session_id, uint32_t enable)
6230{
6231 struct voice_data *v = NULL;
6232 int ret = 0;
6233 struct voice_session_itr itr;
6234
6235 voice_itr_init(&itr, session_id);
6236 while (voice_itr_get_next_session(&itr, &v)) {
6237 if (v != NULL) {
6238 mutex_lock(&v->lock);
6239 v->hd_enable = enable;
6240
6241 if (v->voc_state == VOC_RUN)
6242 ret = voice_send_hd_cmd(v, enable);
6243
6244 mutex_unlock(&v->lock);
6245 } else {
6246 pr_err("%s: invalid session_id 0x%x\n", __func__,
6247 session_id);
6248 ret = -EINVAL;
6249 break;
6250 }
6251 }
6252
6253 return ret;
6254}
6255
6256int voc_set_afe_sidetone(uint32_t session_id, bool sidetone_enable)
6257{
6258 struct voice_data *v = NULL;
6259 int ret = -EINVAL;
6260 struct voice_session_itr itr;
6261 u16 rx_port, tx_port;
6262
6263 common.sidetone_enable = sidetone_enable;
6264 voice_itr_init(&itr, session_id);
6265 while (voice_itr_get_next_session(&itr, &v)) {
6266 if (v == NULL) {
6267 pr_err("%s: invalid session_id 0x%x\n", __func__,
6268 session_id);
6269 ret = -EINVAL;
6270 break;
6271 }
6272 mutex_lock(&v->lock);
6273 if (v->voc_state != VOC_RUN) {
6274 mutex_unlock(&v->lock);
6275 continue;
6276 }
6277 rx_port = v->dev_rx.port_id;
6278 tx_port = v->dev_tx.port_id;
6279 ret = afe_sidetone_enable(tx_port, rx_port,
6280 sidetone_enable);
6281 if (!ret) {
6282 mutex_unlock(&v->lock);
6283 break;
6284 }
6285 mutex_unlock(&v->lock);
6286 }
6287 return ret;
6288}
6289
6290bool voc_get_afe_sidetone(void)
6291{
6292 bool ret;
6293
6294 ret = common.sidetone_enable;
6295 return ret;
6296}
6297
6298int voc_get_pp_enable(uint32_t session_id, uint32_t module_id)
6299{
6300 struct voice_data *v = voice_get_session(session_id);
6301 int ret = 0;
6302
6303 if (v == NULL) {
6304 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
6305
6306 return -EINVAL;
6307 }
6308
6309 mutex_lock(&v->lock);
6310 if (module_id == MODULE_ID_VOICE_MODULE_ST)
6311 ret = v->st_enable;
6312 mutex_unlock(&v->lock);
6313
6314 return ret;
6315}
6316
6317int voc_set_rx_vol_step(uint32_t session_id, uint32_t dir, uint32_t vol_step,
6318 uint32_t ramp_duration)
6319{
6320 struct voice_data *v = NULL;
6321 int ret = 0;
6322 struct voice_session_itr itr;
6323
6324 pr_debug("%s session id = %#x vol = %u", __func__, session_id,
6325 vol_step);
6326
6327 voice_itr_init(&itr, session_id);
6328 while (voice_itr_get_next_session(&itr, &v)) {
6329 if (v != NULL) {
6330 mutex_lock(&v->lock);
6331 v->dev_rx.volume_step_value = vol_step;
6332 v->dev_rx.volume_ramp_duration_ms = ramp_duration;
6333 if (is_voc_state_active(v->voc_state))
6334 ret = voice_send_vol_step_cmd(v);
6335 mutex_unlock(&v->lock);
6336 } else {
6337 pr_err("%s: invalid session_id 0x%x\n", __func__,
6338 session_id);
6339
6340 ret = -EINVAL;
6341 break;
6342 }
6343 }
6344
6345 return ret;
6346}
6347
6348int voc_set_device_config(uint32_t session_id, uint8_t path_dir,
6349 struct media_format_info *finfo)
6350{
6351 struct voice_data *v = voice_get_session(session_id);
6352
6353 if (v == NULL) {
6354 pr_err("%s: Invalid session_id 0x%x\n", __func__, session_id);
6355
6356 return -EINVAL;
6357 }
6358
6359 pr_debug("%s: path_dir=%d port_id=%x, channels=%d, sample_rate=%d, bits_per_sample=%d\n",
6360 __func__, path_dir, finfo->port_id, finfo->num_channels,
6361 finfo->sample_rate, finfo->bits_per_sample);
6362
6363 mutex_lock(&v->lock);
6364 switch (path_dir) {
6365 case RX_PATH:
6366 v->dev_rx.port_id = q6audio_get_port_id(finfo->port_id);
6367 v->dev_rx.no_of_channels = finfo->num_channels;
6368 v->dev_rx.sample_rate = finfo->sample_rate;
6369 v->dev_rx.bits_per_sample = finfo->bits_per_sample;
6370 memcpy(&v->dev_rx.channel_mapping, &finfo->channel_mapping,
6371 VSS_CHANNEL_MAPPING_SIZE);
6372 break;
6373 case TX_PATH:
6374 v->dev_tx.port_id = q6audio_get_port_id(finfo->port_id);
6375 v->dev_tx.no_of_channels = finfo->num_channels;
6376 v->dev_tx.sample_rate = finfo->sample_rate;
6377 v->dev_tx.bits_per_sample = finfo->bits_per_sample;
6378 memcpy(&v->dev_tx.channel_mapping, &finfo->channel_mapping,
6379 VSS_CHANNEL_MAPPING_SIZE);
6380 break;
6381 default:
6382 pr_err("%s: Invalid path_dir %d\n", __func__, path_dir);
6383 return -EINVAL;
6384 }
6385
6386 mutex_unlock(&v->lock);
6387
6388 return 0;
6389}
6390
6391int voc_set_ext_ec_ref_media_fmt_info(struct media_format_info *finfo)
6392{
6393 mutex_lock(&common.common_lock);
6394 if (common.ec_ref_ext) {
6395 common.ec_media_fmt_info.num_channels = finfo->num_channels;
6396 common.ec_media_fmt_info.bits_per_sample =
6397 finfo->bits_per_sample;
6398 common.ec_media_fmt_info.sample_rate = finfo->sample_rate;
6399 memcpy(&common.ec_media_fmt_info.channel_mapping,
6400 &finfo->channel_mapping, VSS_CHANNEL_MAPPING_SIZE);
6401 } else {
6402 pr_debug("%s: Ext Ec Ref not active, returning", __func__);
6403 }
6404 mutex_unlock(&common.common_lock);
6405 return 0;
6406}
6407
6408int voc_set_route_flag(uint32_t session_id, uint8_t path_dir, uint8_t set)
6409{
6410 struct voice_data *v = voice_get_session(session_id);
6411
6412 if (v == NULL) {
6413 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
6414
6415 return -EINVAL;
6416 }
6417
6418 pr_debug("%s: path_dir=%d, set=%d\n", __func__, path_dir, set);
6419
6420 mutex_lock(&v->lock);
6421
6422 if (path_dir == RX_PATH)
6423 v->voc_route_state.rx_route_flag = set;
6424 else
6425 v->voc_route_state.tx_route_flag = set;
6426
6427 mutex_unlock(&v->lock);
6428
6429 return 0;
6430}
6431
6432uint8_t voc_get_route_flag(uint32_t session_id, uint8_t path_dir)
6433{
6434 struct voice_data *v = voice_get_session(session_id);
6435 int ret = 0;
6436
6437 if (v == NULL) {
6438 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
6439
6440 return 0;
6441 }
6442
6443 mutex_lock(&v->lock);
6444
6445 if (path_dir == RX_PATH)
6446 ret = v->voc_route_state.rx_route_flag;
6447 else
6448 ret = v->voc_route_state.tx_route_flag;
6449
6450 mutex_unlock(&v->lock);
6451
6452 return ret;
6453}
6454
6455int voc_end_voice_call(uint32_t session_id)
6456{
6457 struct voice_data *v = voice_get_session(session_id);
6458 int ret = 0;
6459
6460 if (v == NULL) {
6461 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
6462
6463 return -EINVAL;
6464 }
6465
6466 mutex_lock(&v->lock);
6467
6468 if (v->voc_state == VOC_RUN || v->voc_state == VOC_ERROR ||
6469 v->voc_state == VOC_CHANGE || v->voc_state == VOC_STANDBY) {
6470
6471 pr_debug("%s: VOC_STATE: %d\n", __func__, v->voc_state);
6472
6473 ret = voice_destroy_vocproc(v);
6474 if (ret < 0)
6475 pr_err("%s: destroy voice failed\n", __func__);
6476
6477 voc_update_session_params(v);
6478
6479 voice_destroy_mvm_cvs_session(v);
6480 v->voc_state = VOC_RELEASE;
6481 } else {
6482 pr_err("%s: Error: End voice called in state %d\n",
6483 __func__, v->voc_state);
6484
6485 ret = -EINVAL;
6486 }
6487
6488 mutex_unlock(&v->lock);
6489 return ret;
6490}
6491
6492int voc_standby_voice_call(uint32_t session_id)
6493{
6494 struct voice_data *v = voice_get_session(session_id);
6495 struct apr_hdr mvm_standby_voice_cmd;
6496 void *apr_mvm;
6497 u16 mvm_handle;
6498 int ret = 0;
6499
6500 if (v == NULL) {
6501 pr_err("%s: v is NULL\n", __func__);
6502 return -EINVAL;
6503 }
6504 pr_debug("%s: voc state=%d", __func__, v->voc_state);
6505
6506 if (v->voc_state == VOC_RUN) {
6507 apr_mvm = common.apr_q6_mvm;
6508 if (!apr_mvm) {
6509 pr_err("%s: apr_mvm is NULL.\n", __func__);
6510 ret = -EINVAL;
6511 goto fail;
6512 }
6513 mvm_handle = voice_get_mvm_handle(v);
6514 mvm_standby_voice_cmd.hdr_field =
6515 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
6516 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
6517 mvm_standby_voice_cmd.pkt_size =
6518 APR_PKT_SIZE(APR_HDR_SIZE,
6519 sizeof(mvm_standby_voice_cmd) - APR_HDR_SIZE);
6520 pr_debug("send mvm_standby_voice_cmd pkt size = %d\n",
6521 mvm_standby_voice_cmd.pkt_size);
6522 mvm_standby_voice_cmd.src_port =
6523 voice_get_idx_for_session(v->session_id);
6524 mvm_standby_voice_cmd.dest_port = mvm_handle;
6525 mvm_standby_voice_cmd.token = 0;
6526 mvm_standby_voice_cmd.opcode = VSS_IMVM_CMD_STANDBY_VOICE;
6527 v->mvm_state = CMD_STATUS_FAIL;
6528 ret = apr_send_pkt(apr_mvm,
6529 (uint32_t *)&mvm_standby_voice_cmd);
6530 if (ret < 0) {
6531 pr_err("Fail in sending VSS_IMVM_CMD_STANDBY_VOICE\n");
6532 ret = -EINVAL;
6533 goto fail;
6534 }
6535 v->voc_state = VOC_STANDBY;
6536 }
6537fail:
6538 return ret;
6539}
6540
6541int voc_disable_device(uint32_t session_id)
6542{
6543 struct voice_data *v = voice_get_session(session_id);
6544 int ret = 0;
6545
6546 if (v == NULL) {
6547 pr_err("%s: v is NULL\n", __func__);
6548 return -EINVAL;
6549 }
6550
6551 pr_debug("%s: voc state=%d\n", __func__, v->voc_state);
6552
6553 mutex_lock(&v->lock);
6554 if (v->voc_state == VOC_RUN) {
6555 ret = voice_pause_voice_call(v);
6556 if (ret < 0) {
6557 pr_err("%s: Pause Voice Call failed for session 0x%x, err %d!\n",
6558 __func__, v->session_id, ret);
6559 goto done;
6560 }
6561 rtac_remove_voice(voice_get_cvs_handle(v));
6562 voice_send_cvp_deregister_vol_cal_cmd(v);
6563 voice_send_cvp_deregister_cal_cmd(v);
6564 voice_send_cvp_deregister_dev_cfg_cmd(v);
6565
6566 v->voc_state = VOC_CHANGE;
6567 } else {
6568 pr_debug("%s: called in voc state=%d, No_OP\n",
6569 __func__, v->voc_state);
6570 }
6571
6572done:
6573 mutex_unlock(&v->lock);
6574
6575 return ret;
6576}
6577
6578int voc_enable_device(uint32_t session_id)
6579{
6580 struct voice_data *v = voice_get_session(session_id);
6581 int ret = 0;
6582
6583 if (v == NULL) {
6584 pr_err("%s: v is NULL\n", __func__);
6585 return -EINVAL;
6586 }
6587
6588 pr_debug("%s: voc state=%d\n", __func__, v->voc_state);
6589 mutex_lock(&v->lock);
6590 if (v->voc_state == VOC_CHANGE) {
6591 ret = voice_send_tty_mode_cmd(v);
6592 if (ret < 0) {
6593 pr_err("%s: Sending TTY mode failed, ret=%d\n",
6594 __func__, ret);
6595 /* Not a critical error, allow voice call to continue */
6596 }
6597
6598 if (v->tty_mode) {
6599 /* disable slowtalk */
6600 voice_send_set_pp_enable_cmd(v,
6601 MODULE_ID_VOICE_MODULE_ST,
6602 0);
6603 } else {
6604 /* restore slowtalk */
6605 voice_send_set_pp_enable_cmd(v,
6606 MODULE_ID_VOICE_MODULE_ST,
6607 v->st_enable);
6608 }
6609
6610 ret = voice_send_set_device_cmd(v);
6611 if (ret < 0) {
6612 pr_err("%s: Set device failed, ret=%d\n",
6613 __func__, ret);
6614 goto done;
6615 }
6616
6617 ret = voice_send_cvp_media_fmt_info_cmd(v);
6618 if (ret < 0) {
6619 pr_err("%s: Set format failed err:%d\n", __func__, ret);
6620 goto done;
6621 }
6622
6623 ret = voice_send_cvp_topology_commit_cmd(v);
6624 if (ret < 0) {
6625 pr_err("%s: Set topology commit failed\n", __func__);
6626 goto done;
6627 }
6628
Laxminath Kasam38070be2017-08-17 18:21:59 +05306629 /* Send MFC config only when the no of channels are > 1 */
6630 if (v->dev_rx.no_of_channels > NUM_CHANNELS_MONO) {
6631 ret = voice_send_cvp_mfc_config_cmd(v);
6632 if (ret < 0) {
6633 pr_warn("%s: Set mfc config failed err: %d\n",
6634 __func__, ret);
6635 }
6636 }
6637
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306638 voice_send_cvp_register_dev_cfg_cmd(v);
6639 voice_send_cvp_register_cal_cmd(v);
6640 voice_send_cvp_register_vol_cal_cmd(v);
6641
6642 rtac_add_voice(voice_get_cvs_handle(v),
6643 voice_get_cvp_handle(v),
6644 v->dev_rx.port_id, v->dev_tx.port_id,
6645 v->dev_rx.dev_id, v->dev_tx.dev_id,
6646 v->session_id);
6647
6648 ret = voice_send_start_voice_cmd(v);
6649 if (ret < 0) {
6650 pr_err("%s: Fail in sending START_VOICE, ret=%d\n",
6651 __func__, ret);
6652 goto done;
6653 }
6654 v->voc_state = VOC_RUN;
6655 } else {
6656 pr_debug("%s: called in voc state=%d, No_OP\n",
6657 __func__, v->voc_state);
6658 }
6659
6660done:
6661 mutex_unlock(&v->lock);
6662
6663 return ret;
6664}
6665
6666int voc_set_lch(uint32_t session_id, enum voice_lch_mode lch_mode)
6667{
6668 struct voice_data *v = voice_get_session(session_id);
6669 int ret = 0;
6670
6671 if (v == NULL) {
6672 pr_err("%s: Invalid session_id 0x%x\n", __func__, session_id);
6673
6674 ret = -EINVAL;
6675 goto done;
6676 }
6677
6678 mutex_lock(&v->lock);
6679 if (v->lch_mode == lch_mode) {
6680 pr_debug("%s: Session %d already in LCH mode %d\n",
6681 __func__, session_id, lch_mode);
6682
6683 mutex_unlock(&v->lock);
6684 goto done;
6685 }
6686
6687 v->lch_mode = lch_mode;
6688 mutex_unlock(&v->lock);
6689
6690 ret = voc_lch_ops(v, v->lch_mode);
6691 if (ret < 0) {
6692 pr_err("%s: lch ops failed %d\n", __func__, ret);
6693 goto done;
6694 }
6695
6696done:
6697 return ret;
6698}
6699
6700int voc_resume_voice_call(uint32_t session_id)
6701{
6702 struct voice_data *v = voice_get_session(session_id);
6703 int ret = 0;
6704
6705 ret = voice_send_start_voice_cmd(v);
6706 if (ret < 0) {
6707 pr_err("Fail in sending START_VOICE\n");
6708 goto fail;
6709 }
6710 v->voc_state = VOC_RUN;
6711 return 0;
6712fail:
6713 return -EINVAL;
6714}
6715
6716int voc_start_voice_call(uint32_t session_id)
6717{
6718 struct voice_data *v = voice_get_session(session_id);
6719 int ret = 0;
6720
6721 if (v == NULL) {
6722 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
6723
6724 return -EINVAL;
6725 }
6726
6727 mutex_lock(&v->lock);
6728
6729 if (v->voc_state == VOC_ERROR) {
6730 pr_debug("%s: VOC in ERR state\n", __func__);
6731
6732 voice_destroy_mvm_cvs_session(v);
6733 v->voc_state = VOC_INIT;
6734 }
6735
6736 if ((v->voc_state == VOC_INIT) ||
6737 (v->voc_state == VOC_RELEASE)) {
6738 ret = voice_apr_register(session_id);
6739 if (ret < 0) {
6740 pr_err("%s: apr register failed\n", __func__);
6741 goto fail;
6742 }
6743
6744 if (is_cvd_version_queried()) {
6745 pr_debug("%s: Returning the cached value %s\n",
6746 __func__, common.cvd_version);
6747 } else {
6748 ret = voice_send_mvm_cvd_version_cmd(v);
6749 if (ret < 0)
6750 pr_debug("%s: Error retrieving CVD version %d\n",
6751 __func__, ret);
6752 }
6753
6754 ret = voice_create_mvm_cvs_session(v);
6755 if (ret < 0) {
6756 pr_err("create mvm and cvs failed\n");
6757 goto fail;
6758 }
6759
6760 if (is_voip_session(session_id)) {
6761 /* Allocate oob mem if not already allocated and
6762 * memory map the oob memory block.
6763 */
6764 ret = voice_alloc_and_map_oob_mem(v);
6765 if (ret < 0) {
6766 pr_err("%s: voice_alloc_and_map_oob_mem() failed, ret:%d\n",
6767 __func__, ret);
6768
6769 goto fail;
6770 }
6771
6772 ret = voice_set_packet_exchange_mode_and_config(
6773 session_id,
6774 VSS_ISTREAM_PACKET_EXCHANGE_MODE_OUT_OF_BAND);
6775 if (ret) {
6776 pr_err("%s: Err: exchange_mode_and_config %d\n",
6777 __func__, ret);
6778
6779 goto fail;
6780 }
6781 }
6782 ret = voice_send_dual_control_cmd(v);
6783 if (ret < 0) {
6784 pr_err("Err Dual command failed\n");
6785 goto fail;
6786 }
6787 ret = voice_setup_vocproc(v);
6788 if (ret < 0) {
6789 pr_err("setup voice failed\n");
6790 goto fail;
6791 }
6792
6793 ret = voice_send_vol_step_cmd(v);
6794 if (ret < 0)
6795 pr_err("voice volume failed\n");
6796
6797 ret = voice_send_stream_mute_cmd(v,
6798 VSS_IVOLUME_DIRECTION_TX,
6799 v->stream_tx.stream_mute,
6800 v->stream_tx.stream_mute_ramp_duration_ms);
6801 if (ret < 0)
6802 pr_err("voice mute failed\n");
6803
6804 ret = voice_send_start_voice_cmd(v);
6805 if (ret < 0) {
6806 pr_err("start voice failed\n");
6807 goto fail;
6808 }
6809
6810 v->voc_state = VOC_RUN;
6811 } else {
6812 pr_err("%s: Error: Start voice called in state %d\n",
6813 __func__, v->voc_state);
6814
6815 ret = -EINVAL;
6816 goto fail;
6817 }
6818fail:
6819 mutex_unlock(&v->lock);
6820 return ret;
6821}
6822
6823int voc_set_ext_ec_ref_port_id(uint16_t port_id, bool state)
6824{
6825 int ret = 0;
6826
6827 mutex_lock(&common.common_lock);
6828 if (state == true) {
6829 if (port_id == AFE_PORT_INVALID) {
6830 pr_err("%s: Invalid port id", __func__);
6831 ret = -EINVAL;
6832 goto exit;
6833 }
6834 common.ec_ref_ext = true;
6835 } else {
6836 common.ec_ref_ext = false;
6837 }
6838 /* Cache EC Fromat Info in common */
6839 common.ec_media_fmt_info.port_id = port_id;
6840exit:
6841 mutex_unlock(&common.common_lock);
6842 return ret;
6843}
6844
6845int voc_get_ext_ec_ref_port_id(void)
6846{
6847 if (common.ec_ref_ext)
6848 return common.ec_media_fmt_info.port_id;
6849 else
6850 return AFE_PORT_INVALID;
6851}
6852
6853void voc_register_mvs_cb(ul_cb_fn ul_cb,
6854 dl_cb_fn dl_cb,
6855 voip_ssr_cb ssr_cb,
6856 void *private_data)
6857{
6858 common.mvs_info.ul_cb = ul_cb;
6859 common.mvs_info.dl_cb = dl_cb;
6860 common.mvs_info.ssr_cb = ssr_cb;
6861 common.mvs_info.private_data = private_data;
6862}
6863
6864void voc_register_dtmf_rx_detection_cb(dtmf_rx_det_cb_fn dtmf_rx_ul_cb,
6865 void *private_data)
6866{
6867 common.dtmf_info.dtmf_rx_ul_cb = dtmf_rx_ul_cb;
6868 common.dtmf_info.private_data = private_data;
6869}
6870
6871void voc_config_vocoder(uint32_t media_type,
6872 uint32_t rate,
6873 uint32_t network_type,
6874 uint32_t dtx_mode,
6875 uint32_t evrc_min_rate,
6876 uint32_t evrc_max_rate)
6877{
6878 common.mvs_info.media_type = media_type;
6879 common.mvs_info.rate = rate;
6880 common.mvs_info.network_type = network_type;
6881 common.mvs_info.dtx_mode = dtx_mode;
6882 common.mvs_info.evrc_min_rate = evrc_min_rate;
6883 common.mvs_info.evrc_max_rate = evrc_max_rate;
6884}
6885
6886static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv)
6887{
6888 uint32_t *ptr = NULL;
6889 struct common_data *c = NULL;
6890 struct voice_data *v = NULL;
6891 int i = 0;
6892 struct vss_iversion_rsp_get_t *version_rsp = NULL;
6893
6894 if ((data == NULL) || (priv == NULL)) {
6895 pr_err("%s: data or priv is NULL\n", __func__);
6896 return -EINVAL;
6897 }
6898
6899 c = priv;
6900
6901 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
6902 data->payload_size, data->opcode);
6903
6904 if (data->opcode == RESET_EVENTS) {
6905 pr_debug("%s: Reset event received in Voice service\n",
6906 __func__);
6907
6908 if (common.mvs_info.ssr_cb) {
6909 pr_debug("%s: Informing reset event to VoIP\n",
6910 __func__);
6911 common.mvs_info.ssr_cb(data->opcode,
6912 common.mvs_info.private_data);
6913 }
6914
6915 apr_reset(c->apr_q6_mvm);
6916 c->apr_q6_mvm = NULL;
6917
6918 /* clean up memory handle */
6919 c->cal_mem_handle = 0;
6920 c->rtac_mem_handle = 0;
6921 cal_utils_clear_cal_block_q6maps(MAX_VOICE_CAL_TYPES,
6922 common.cal_data);
6923 rtac_clear_mapping(VOICE_RTAC_CAL);
6924
6925 /* Sub-system restart is applicable to all sessions. */
6926 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
6927 c->voice[i].mvm_handle = 0;
6928 c->voice[i].shmem_info.mem_handle = 0;
6929 }
6930
6931 /* Free the ION memory and clear handles for Source Tracking */
6932 if (is_source_tracking_shared_memomry_allocated()) {
6933 msm_audio_ion_free(
6934 common.source_tracking_sh_mem.sh_mem_block.client,
6935 common.source_tracking_sh_mem.sh_mem_block.handle);
6936 common.source_tracking_sh_mem.mem_handle = 0;
6937 common.source_tracking_sh_mem.sh_mem_block.client =
6938 NULL;
6939 common.source_tracking_sh_mem.sh_mem_block.handle =
6940 NULL;
6941 }
6942 /* clean up srvcc rec flag */
6943 c->srvcc_rec_flag = false;
6944 voc_set_error_state(data->reset_proc);
6945 return 0;
6946 }
6947
6948 pr_debug("%s: session_idx 0x%x\n", __func__, data->dest_port);
6949
6950 v = voice_get_session_by_idx(data->dest_port);
6951 if (v == NULL) {
6952 pr_err("%s: v is NULL\n", __func__);
6953
6954 return -EINVAL;
6955 }
6956
6957 if (data->opcode == APR_BASIC_RSP_RESULT) {
6958 if (data->payload_size) {
6959 ptr = data->payload;
6960
6961 pr_debug("%x %x\n", ptr[0], ptr[1]);
6962 /* ping mvm service ACK */
6963 switch (ptr[0]) {
6964 case VSS_IMVM_CMD_CREATE_PASSIVE_CONTROL_SESSION:
6965 case VSS_IMVM_CMD_CREATE_FULL_CONTROL_SESSION:
6966 /* Passive session is used for CS call
6967 * Full session is used for VoIP call.
6968 */
6969 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
6970 if (!ptr[1]) {
6971 pr_debug("%s: MVM handle is %d\n",
6972 __func__, data->src_port);
6973 voice_set_mvm_handle(v, data->src_port);
6974 } else
6975 pr_err("got NACK for sending MVM create session\n");
6976 v->mvm_state = CMD_STATUS_SUCCESS;
6977 v->async_err = ptr[1];
6978 wake_up(&v->mvm_wait);
6979 break;
6980 case VSS_IMVM_CMD_START_VOICE:
6981 case VSS_IMVM_CMD_ATTACH_VOCPROC:
6982 case VSS_IMVM_CMD_STOP_VOICE:
6983 case VSS_IMVM_CMD_DETACH_VOCPROC:
6984 case VSS_ISTREAM_CMD_SET_TTY_MODE:
6985 case APRV2_IBASIC_CMD_DESTROY_SESSION:
6986 case VSS_IMVM_CMD_ATTACH_STREAM:
6987 case VSS_IMVM_CMD_DETACH_STREAM:
6988 case VSS_ICOMMON_CMD_SET_NETWORK:
6989 case VSS_ICOMMON_CMD_SET_VOICE_TIMING:
6990 case VSS_IMVM_CMD_SET_POLICY_DUAL_CONTROL:
6991 case VSS_IMVM_CMD_SET_CAL_NETWORK:
6992 case VSS_IMVM_CMD_SET_CAL_MEDIA_TYPE:
6993 case VSS_IMEMORY_CMD_MAP_PHYSICAL:
6994 case VSS_IMEMORY_CMD_UNMAP:
6995 case VSS_IMVM_CMD_PAUSE_VOICE:
6996 case VSS_IMVM_CMD_STANDBY_VOICE:
6997 case VSS_IHDVOICE_CMD_ENABLE:
6998 case VSS_IHDVOICE_CMD_DISABLE:
6999 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
7000 v->mvm_state = CMD_STATUS_SUCCESS;
7001 v->async_err = ptr[1];
7002 wake_up(&v->mvm_wait);
7003 break;
7004 case VSS_IVERSION_CMD_GET:
7005 pr_debug("%s: Error retrieving CVD Version, error:%d\n",
7006 __func__, ptr[1]);
7007
7008 strlcpy(common.cvd_version, CVD_VERSION_0_0,
7009 sizeof(common.cvd_version));
7010 pr_debug("%s: Fall back to default value, CVD Version = %s\n",
7011 __func__, common.cvd_version);
7012
7013 v->mvm_state = CMD_STATUS_SUCCESS;
7014 v->async_err = ptr[1];
7015 wake_up(&v->mvm_wait);
7016 break;
7017 default:
7018 pr_debug("%s: not match cmd = 0x%x\n",
7019 __func__, ptr[0]);
7020 break;
7021 }
7022 }
7023 } else if (data->opcode == VSS_IMEMORY_RSP_MAP) {
7024 pr_debug("%s, Revd VSS_IMEMORY_RSP_MAP response\n", __func__);
7025
7026 if (data->payload_size && data->token == VOIP_MEM_MAP_TOKEN) {
7027 ptr = data->payload;
7028 if (ptr[0]) {
7029 v->shmem_info.mem_handle = ptr[0];
7030 pr_debug("%s: shared mem_handle: 0x[%x]\n",
7031 __func__, v->shmem_info.mem_handle);
7032 v->mvm_state = CMD_STATUS_SUCCESS;
7033 wake_up(&v->mvm_wait);
7034 }
7035 } else if (data->payload_size &&
7036 data->token == VOC_CAL_MEM_MAP_TOKEN) {
7037 ptr = data->payload;
7038 if (ptr[0]) {
7039 c->cal_mem_handle = ptr[0];
7040
7041 pr_debug("%s: cal mem handle 0x%x\n",
7042 __func__, c->cal_mem_handle);
7043
7044 v->mvm_state = CMD_STATUS_SUCCESS;
7045 wake_up(&v->mvm_wait);
7046 }
7047 } else if (data->payload_size &&
7048 data->token == VOC_VOICE_HOST_PCM_MAP_TOKEN) {
7049 ptr = data->payload;
7050 if (ptr[0]) {
7051 common.voice_host_pcm_mem_handle = ptr[0];
7052
7053 pr_debug("%s: vhpcm mem handle 0x%x\n",
7054 __func__,
7055 common.voice_host_pcm_mem_handle);
7056 v->mvm_state = CMD_STATUS_SUCCESS;
7057 wake_up(&v->mvm_wait);
7058 }
7059 } else if (data->payload_size &&
7060 data->token == VOC_RTAC_MEM_MAP_TOKEN) {
7061 ptr = data->payload;
7062 if (ptr[0]) {
7063 c->rtac_mem_handle = ptr[0];
7064
7065 pr_debug("%s: cal mem handle 0x%x\n",
7066 __func__, c->rtac_mem_handle);
7067
7068 v->mvm_state = CMD_STATUS_SUCCESS;
7069 wake_up(&v->mvm_wait);
7070 }
7071 } else if (data->payload_size &&
7072 data->token == VOC_SOURCE_TRACKING_MEM_MAP_TOKEN) {
7073 ptr = data->payload;
7074 if (ptr[0]) {
7075 common.source_tracking_sh_mem.mem_handle =
7076 ptr[0];
7077
7078 pr_debug("%s: Source Tracking shared mem handle 0x%x\n",
7079 __func__,
7080 common.source_tracking_sh_mem.mem_handle);
7081
7082 v->mvm_state = CMD_STATUS_SUCCESS;
7083 wake_up(&v->mvm_wait);
7084 }
7085 } else {
7086 pr_err("%s: Unknown mem map token %d\n",
7087 __func__, data->token);
7088 }
7089 } else if (data->opcode == VSS_IVERSION_RSP_GET) {
7090 pr_debug("%s: Received VSS_IVERSION_RSP_GET\n", __func__);
7091
7092 if (data->payload_size) {
7093 version_rsp =
7094 (struct vss_iversion_rsp_get_t *)data->payload;
7095 memcpy(common.cvd_version, version_rsp->version,
7096 CVD_VERSION_STRING_MAX_SIZE);
7097 pr_debug("%s: CVD Version = %s\n",
7098 __func__, common.cvd_version);
7099
7100 v->mvm_state = CMD_STATUS_SUCCESS;
7101 wake_up(&v->mvm_wait);
7102 }
7103 }
7104 return 0;
7105}
7106
7107static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv)
7108{
7109 uint32_t *ptr = NULL;
7110 struct common_data *c = NULL;
7111 struct voice_data *v = NULL;
7112 int i = 0;
7113
7114 if ((data == NULL) || (priv == NULL)) {
7115 pr_err("%s: data or priv is NULL\n", __func__);
7116 return -EINVAL;
7117 }
7118
7119 c = priv;
7120
7121 pr_debug("%s: session_id 0x%x\n", __func__, data->dest_port);
7122 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
7123 data->payload_size, data->opcode);
7124
7125 if (data->opcode == RESET_EVENTS) {
7126 pr_debug("%s: Reset event received in Voice service\n",
7127 __func__);
7128
7129 apr_reset(c->apr_q6_cvs);
7130 c->apr_q6_cvs = NULL;
7131
7132 /* Sub-system restart is applicable to all sessions. */
7133 for (i = 0; i < MAX_VOC_SESSIONS; i++)
7134 c->voice[i].cvs_handle = 0;
7135
7136 cal_utils_clear_cal_block_q6maps(MAX_VOICE_CAL_TYPES,
7137 common.cal_data);
7138
7139 /* Free the ION memory and clear handles for Source Tracking */
7140 if (is_source_tracking_shared_memomry_allocated()) {
7141 msm_audio_ion_free(
7142 common.source_tracking_sh_mem.sh_mem_block.client,
7143 common.source_tracking_sh_mem.sh_mem_block.handle);
7144 common.source_tracking_sh_mem.mem_handle = 0;
7145 common.source_tracking_sh_mem.sh_mem_block.client =
7146 NULL;
7147 common.source_tracking_sh_mem.sh_mem_block.handle =
7148 NULL;
7149 }
7150 voc_set_error_state(data->reset_proc);
7151 return 0;
7152 }
7153
7154 v = voice_get_session_by_idx(data->dest_port);
7155 if (v == NULL) {
7156 pr_err("%s: v is NULL\n", __func__);
7157
7158 return -EINVAL;
7159 }
7160
7161 if (data->opcode == APR_BASIC_RSP_RESULT) {
7162 if (data->payload_size) {
7163 ptr = data->payload;
7164
7165 pr_debug("%x %x\n", ptr[0], ptr[1]);
7166 if (ptr[1] != 0) {
7167 pr_err("%s: cmd = 0x%x returned error = 0x%x\n",
7168 __func__, ptr[0], ptr[1]);
7169 }
7170 /*response from CVS */
7171 switch (ptr[0]) {
7172 case VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION:
7173 case VSS_ISTREAM_CMD_CREATE_FULL_CONTROL_SESSION:
7174 if (!ptr[1]) {
7175 pr_debug("%s: CVS handle is %d\n",
7176 __func__, data->src_port);
7177 voice_set_cvs_handle(v, data->src_port);
7178 } else
7179 pr_err("got NACK for sending CVS create session\n");
7180 v->cvs_state = CMD_STATUS_SUCCESS;
7181 v->async_err = ptr[1];
7182 wake_up(&v->cvs_wait);
7183 break;
7184 case VSS_IVOLUME_CMD_MUTE_V2:
7185 case VSS_ISTREAM_CMD_SET_MEDIA_TYPE:
7186 case VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE:
7187 case VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE:
7188 case VSS_ISTREAM_CMD_SET_ENC_DTX_MODE:
7189 case VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE:
7190 case APRV2_IBASIC_CMD_DESTROY_SESSION:
7191 case VSS_ISTREAM_CMD_REGISTER_CALIBRATION_DATA_V2:
7192 case VSS_ISTREAM_CMD_DEREGISTER_CALIBRATION_DATA:
7193 case VSS_ISTREAM_CMD_REGISTER_STATIC_CALIBRATION_DATA:
7194 case VSS_ISTREAM_CMD_DEREGISTER_STATIC_CALIBRATION_DATA:
7195 case VSS_ICOMMON_CMD_MAP_MEMORY:
7196 case VSS_ICOMMON_CMD_UNMAP_MEMORY:
7197 case VSS_ICOMMON_CMD_SET_UI_PROPERTY:
7198 case VSS_IPLAYBACK_CMD_START:
7199 case VSS_IPLAYBACK_CMD_STOP:
7200 case VSS_IRECORD_CMD_START:
7201 case VSS_IRECORD_CMD_STOP:
7202 case VSS_ISTREAM_CMD_SET_PACKET_EXCHANGE_MODE:
7203 case VSS_ISTREAM_CMD_SET_OOB_PACKET_EXCHANGE_CONFIG:
7204 case VSS_ISTREAM_CMD_SET_RX_DTMF_DETECTION:
7205 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
7206 v->cvs_state = CMD_STATUS_SUCCESS;
7207 v->async_err = ptr[1];
7208 wake_up(&v->cvs_wait);
7209 break;
7210 case VSS_ICOMMON_CMD_SET_PARAM_V2:
7211 pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM_V2\n",
7212 __func__);
7213 rtac_make_voice_callback(RTAC_CVS, ptr,
7214 data->payload_size);
7215 break;
7216 case VSS_ICOMMON_CMD_GET_PARAM_V2:
7217 pr_debug("%s: VSS_ICOMMON_CMD_GET_PARAM_V2\n",
7218 __func__);
7219 /* Should only come here if there is an APR */
7220 /* error or malformed APR packet. Otherwise */
7221 /* response will be returned as */
7222 /* VSS_ICOMMON_RSP_GET_PARAM */
7223 if (ptr[1] != 0) {
7224 pr_err("%s: CVP get param error = %d, resuming\n",
7225 __func__, ptr[1]);
7226 rtac_make_voice_callback(RTAC_CVP,
7227 data->payload,
7228 data->payload_size);
7229 }
7230 break;
7231 default:
7232 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
7233 break;
7234 }
7235 }
7236 } else if (data->opcode ==
7237 VSS_ISTREAM_EVT_OOB_NOTIFY_ENC_BUFFER_READY) {
7238 int ret = 0;
7239 u16 cvs_handle;
7240 uint32_t *cvs_voc_pkt;
7241 struct cvs_enc_buffer_consumed_cmd send_enc_buf_consumed_cmd;
7242 void *apr_cvs;
7243
7244 pr_debug("Encoder buffer is ready\n");
7245
7246 apr_cvs = common.apr_q6_cvs;
7247 if (!apr_cvs) {
7248 pr_err("%s: apr_cvs is NULL\n", __func__);
7249 return -EINVAL;
7250 }
7251 cvs_handle = voice_get_cvs_handle(v);
7252
7253 send_enc_buf_consumed_cmd.hdr.hdr_field =
7254 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
7255 APR_HDR_LEN(APR_HDR_SIZE),
7256 APR_PKT_VER);
7257 send_enc_buf_consumed_cmd.hdr.pkt_size =
7258 APR_PKT_SIZE(APR_HDR_SIZE,
7259 sizeof(send_enc_buf_consumed_cmd) - APR_HDR_SIZE);
7260
7261 send_enc_buf_consumed_cmd.hdr.src_port =
7262 voice_get_idx_for_session(v->session_id);
7263 send_enc_buf_consumed_cmd.hdr.dest_port = cvs_handle;
7264 send_enc_buf_consumed_cmd.hdr.token = 0;
7265 send_enc_buf_consumed_cmd.hdr.opcode =
7266 VSS_ISTREAM_EVT_OOB_NOTIFY_ENC_BUFFER_CONSUMED;
7267
7268 cvs_voc_pkt = v->shmem_info.sh_buf.buf[1].data;
7269 if (cvs_voc_pkt != NULL && common.mvs_info.ul_cb != NULL) {
7270 /* cvs_voc_pkt[0] contains tx timestamp */
7271 common.mvs_info.ul_cb((uint8_t *)&cvs_voc_pkt[3],
7272 cvs_voc_pkt[2],
7273 cvs_voc_pkt[0],
7274 common.mvs_info.private_data);
7275 } else
7276 pr_err("%s: cvs_voc_pkt or ul_cb is NULL\n", __func__);
7277
7278 ret = apr_send_pkt(apr_cvs,
7279 (uint32_t *) &send_enc_buf_consumed_cmd);
7280 if (ret < 0) {
7281 pr_err("%s: Err send ENC_BUF_CONSUMED_NOTIFY %d\n",
7282 __func__, ret);
7283 goto fail;
7284 }
7285 } else if (data->opcode == VSS_ISTREAM_EVT_SEND_ENC_BUFFER) {
7286 pr_debug("Recd VSS_ISTREAM_EVT_SEND_ENC_BUFFER\n");
7287 } else if (data->opcode ==
7288 VSS_ISTREAM_EVT_OOB_NOTIFY_DEC_BUFFER_REQUEST) {
7289 int ret = 0;
7290 u16 cvs_handle;
7291 uint32_t *cvs_voc_pkt;
7292 struct cvs_dec_buffer_ready_cmd send_dec_buf;
7293 void *apr_cvs;
7294
7295 apr_cvs = common.apr_q6_cvs;
7296
7297 if (!apr_cvs) {
7298 pr_err("%s: apr_cvs is NULL\n", __func__);
7299 return -EINVAL;
7300 }
7301 cvs_handle = voice_get_cvs_handle(v);
7302
7303 send_dec_buf.hdr.hdr_field =
7304 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
7305 APR_HDR_LEN(APR_HDR_SIZE),
7306 APR_PKT_VER);
7307
7308 send_dec_buf.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
7309 sizeof(send_dec_buf) - APR_HDR_SIZE);
7310
7311 send_dec_buf.hdr.src_port =
7312 voice_get_idx_for_session(v->session_id);
7313 send_dec_buf.hdr.dest_port = cvs_handle;
7314 send_dec_buf.hdr.token = 0;
7315 send_dec_buf.hdr.opcode =
7316 VSS_ISTREAM_EVT_OOB_NOTIFY_DEC_BUFFER_READY;
7317
7318 cvs_voc_pkt = (uint32_t *)(v->shmem_info.sh_buf.buf[0].data);
7319 if (cvs_voc_pkt != NULL && common.mvs_info.dl_cb != NULL) {
7320 /* Set timestamp to 0 and advance the pointer */
7321 cvs_voc_pkt[0] = 0;
7322 /* Set media_type and advance the pointer */
7323 cvs_voc_pkt[1] = common.mvs_info.media_type;
7324 common.mvs_info.dl_cb(
7325 (uint8_t *)&cvs_voc_pkt[2],
7326 common.mvs_info.private_data);
7327 ret = apr_send_pkt(apr_cvs, (uint32_t *) &send_dec_buf);
7328 if (ret < 0) {
7329 pr_err("%s: Err send DEC_BUF_READY_NOTIFI %d\n",
7330 __func__, ret);
7331 goto fail;
7332 }
7333 } else {
7334 pr_debug("%s: voc_pkt or dl_cb is NULL\n", __func__);
7335 goto fail;
7336 }
7337 } else if (data->opcode == VSS_ISTREAM_EVT_REQUEST_DEC_BUFFER) {
7338 pr_debug("Recd VSS_ISTREAM_EVT_REQUEST_DEC_BUFFER\n");
7339 } else if (data->opcode == VSS_ISTREAM_EVT_SEND_DEC_BUFFER) {
7340 pr_debug("Send dec buf resp\n");
7341 } else if (data->opcode == APR_RSP_ACCEPTED) {
7342 ptr = data->payload;
7343 if (ptr[0])
7344 pr_debug("%s: APR_RSP_ACCEPTED for 0x%x:\n",
7345 __func__, ptr[0]);
7346 } else if (data->opcode == VSS_ISTREAM_EVT_NOT_READY) {
7347 pr_debug("Recd VSS_ISTREAM_EVT_NOT_READY\n");
7348 } else if (data->opcode == VSS_ISTREAM_EVT_READY) {
7349 pr_debug("Recd VSS_ISTREAM_EVT_READY\n");
7350 } else if (data->opcode == VSS_ICOMMON_RSP_GET_PARAM) {
7351 pr_debug("%s: VSS_ICOMMON_RSP_GET_PARAM\n", __func__);
7352 ptr = data->payload;
7353 if (ptr[0] != 0) {
7354 pr_err("%s: VSS_ICOMMON_RSP_GET_PARAM returned error = 0x%x\n",
7355 __func__, ptr[0]);
7356 }
7357 rtac_make_voice_callback(RTAC_CVS, data->payload,
7358 data->payload_size);
7359 } else if (data->opcode == VSS_ISTREAM_EVT_RX_DTMF_DETECTED) {
7360 struct vss_istream_evt_rx_dtmf_detected *dtmf_rx_detected;
7361 uint32_t *voc_pkt = data->payload;
7362 uint32_t pkt_len = data->payload_size;
7363
7364 if ((voc_pkt != NULL) &&
7365 (pkt_len ==
7366 sizeof(struct vss_istream_evt_rx_dtmf_detected))) {
7367
7368 dtmf_rx_detected =
7369 (struct vss_istream_evt_rx_dtmf_detected *) voc_pkt;
7370 pr_debug("RX_DTMF_DETECTED low_freq=%d high_freq=%d\n",
7371 dtmf_rx_detected->low_freq,
7372 dtmf_rx_detected->high_freq);
7373 if (c->dtmf_info.dtmf_rx_ul_cb)
7374 c->dtmf_info.dtmf_rx_ul_cb((uint8_t *)voc_pkt,
7375 voc_get_session_name(v->session_id),
7376 c->dtmf_info.private_data);
7377 } else {
7378 pr_err("Invalid packet\n");
7379 }
7380 } else
7381 pr_debug("Unknown opcode 0x%x\n", data->opcode);
7382
7383fail:
7384 return 0;
7385}
7386
7387static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv)
7388{
7389 uint32_t *ptr = NULL;
7390 struct common_data *c = NULL;
7391 struct voice_data *v = NULL;
7392 int i = 0;
7393
7394 if ((data == NULL) || (priv == NULL)) {
7395 pr_err("%s: data or priv is NULL\n", __func__);
7396 return -EINVAL;
7397 }
7398
7399 c = priv;
7400
7401 if (data->opcode == RESET_EVENTS) {
7402 pr_debug("%s: Reset event received in Voice service\n",
7403 __func__);
7404
7405 apr_reset(c->apr_q6_cvp);
7406 c->apr_q6_cvp = NULL;
7407 cal_utils_clear_cal_block_q6maps(MAX_VOICE_CAL_TYPES,
7408 common.cal_data);
7409
7410 /* Sub-system restart is applicable to all sessions. */
7411 for (i = 0; i < MAX_VOC_SESSIONS; i++)
7412 c->voice[i].cvp_handle = 0;
7413
7414 /*
7415 * Free the ION memory and clear handles for
7416 * Source Tracking
7417 */
7418 if (is_source_tracking_shared_memomry_allocated()) {
7419 msm_audio_ion_free(
7420 common.source_tracking_sh_mem.sh_mem_block.client,
7421 common.source_tracking_sh_mem.sh_mem_block.handle);
7422 common.source_tracking_sh_mem.mem_handle = 0;
7423 common.source_tracking_sh_mem.sh_mem_block.client =
7424 NULL;
7425 common.source_tracking_sh_mem.sh_mem_block.handle =
7426 NULL;
7427 }
7428 voc_set_error_state(data->reset_proc);
7429 return 0;
7430 }
7431
7432 v = voice_get_session_by_idx(data->dest_port);
7433 if (v == NULL) {
7434 pr_err("%s: v is NULL\n", __func__);
7435
7436 return -EINVAL;
7437 }
7438
7439 if (data->opcode == APR_BASIC_RSP_RESULT) {
7440 if (data->payload_size) {
7441 ptr = data->payload;
7442
7443 pr_debug("%x %x\n", ptr[0], ptr[1]);
7444 if (ptr[1] != 0) {
7445 pr_err("%s: cmd = 0x%x returned error = 0x%x\n",
7446 __func__, ptr[0], ptr[1]);
7447 }
7448 switch (ptr[0]) {
7449 case VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION_V2:
7450 case VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION_V3:
7451 /*response from CVP */
7452 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
7453 if (!ptr[1]) {
7454 voice_set_cvp_handle(v, data->src_port);
7455 pr_debug("status: %d, cvphdl=%d\n",
7456 ptr[1], data->src_port);
7457 } else
7458 pr_err("got NACK from CVP create session response\n");
7459 v->cvp_state = CMD_STATUS_SUCCESS;
7460 v->async_err = ptr[1];
7461 wake_up(&v->cvp_wait);
7462 break;
7463 case VSS_IVOCPROC_CMD_SET_DEVICE_V2:
7464 case VSS_IVOCPROC_CMD_SET_DEVICE_V3:
7465 case VSS_IVOLUME_CMD_SET_STEP:
7466 case VSS_IVOCPROC_CMD_ENABLE:
7467 case VSS_IVOCPROC_CMD_DISABLE:
7468 case APRV2_IBASIC_CMD_DESTROY_SESSION:
7469 case VSS_IVOCPROC_CMD_REGISTER_VOL_CALIBRATION_DATA:
7470 case VSS_IVOCPROC_CMD_DEREGISTER_VOL_CALIBRATION_DATA:
7471 case VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA_V2:
7472 case VSS_IVOCPROC_CMD_DEREGISTER_CALIBRATION_DATA:
7473 case VSS_IVOCPROC_CMD_REGISTER_DYNAMIC_CALIBRATION_DATA:
7474 case VSS_IVOCPROC_CMD_DEREGISTER_DYNAMIC_CALIBRATION_DATA:
7475 case VSS_IVOCPROC_CMD_REGISTER_STATIC_CALIBRATION_DATA:
7476 case VSS_IVOCPROC_CMD_DEREGISTER_STATIC_CALIBRATION_DATA:
7477 case VSS_IVOCPROC_CMD_REGISTER_DEVICE_CONFIG:
7478 case VSS_IVOCPROC_CMD_DEREGISTER_DEVICE_CONFIG:
7479 case VSS_ICOMMON_CMD_MAP_MEMORY:
7480 case VSS_ICOMMON_CMD_UNMAP_MEMORY:
7481 case VSS_IVOLUME_CMD_MUTE_V2:
7482 case VSS_IVPCM_CMD_START_V2:
7483 case VSS_IVPCM_CMD_STOP:
7484 case VSS_IVOCPROC_CMD_TOPOLOGY_SET_DEV_CHANNELS:
7485 case VSS_IVOCPROC_CMD_TOPOLOGY_COMMIT:
7486 v->cvp_state = CMD_STATUS_SUCCESS;
7487 v->async_err = ptr[1];
7488 wake_up(&v->cvp_wait);
7489 break;
7490 case VSS_IVPCM_EVT_PUSH_BUFFER_V2:
7491 break;
7492 case VSS_ICOMMON_CMD_SET_PARAM_V2:
7493 switch (data->token) {
7494 case VOC_SET_MEDIA_FORMAT_PARAM_TOKEN:
Laxminath Kasam38070be2017-08-17 18:21:59 +05307495 case VOC_GENERIC_SET_PARAM_TOKEN:
7496 pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM_V2 called\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307497 __func__);
7498 v->cvp_state = CMD_STATUS_SUCCESS;
7499 v->async_err = ptr[1];
7500 wake_up(&v->cvp_wait);
7501 break;
7502 case VOC_RTAC_SET_PARAM_TOKEN:
7503 pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM_V2 called by rtac\n",
7504 __func__);
7505 rtac_make_voice_callback(
7506 RTAC_CVP, ptr,
7507 data->payload_size);
7508 break;
7509 default:
7510 pr_debug("%s: invalid token for command VSS_ICOMMON_CMD_SET_PARAM_V2: %d\n",
7511 __func__, data->token);
7512 break;
7513 }
7514 break;
7515 case VSS_ICOMMON_CMD_GET_PARAM_V2:
7516 pr_debug("%s: VSS_ICOMMON_CMD_GET_PARAM_V2\n",
7517 __func__);
7518 /* Should only come here if there is an APR */
7519 /* error or malformed APR packet. Otherwise */
7520 /* response will be returned as */
7521 /* VSS_ICOMMON_RSP_GET_PARAM */
7522 if (ptr[1] != 0) {
7523 pr_err("%s: CVP get param error = %d, resuming\n",
7524 __func__, ptr[1]);
7525 rtac_make_voice_callback(RTAC_CVP,
7526 data->payload,
7527 data->payload_size);
7528 }
7529 break;
7530 case VSS_ISOUNDFOCUS_CMD_SET_SECTORS:
7531 if (!ptr[1])
7532 common.is_sound_focus_resp_success =
7533 true;
7534 else
7535 common.is_sound_focus_resp_success =
7536 false;
7537 v->cvp_state = CMD_STATUS_SUCCESS;
7538 v->async_err = ptr[1];
7539 wake_up(&v->cvp_wait);
7540 break;
7541 case VSS_ISOUNDFOCUS_CMD_GET_SECTORS:
7542 /*
7543 * Should only come here if there is an error
7544 * response received from ADSP. Otherwise
7545 * response will be returned as
7546 * VSS_ISOUNDFOCUS_RSP_GET_SECTORS
7547 */
7548 pr_err("%s: VSS_ISOUNDFOCUS_CMD_GET_SECTORS failed\n",
7549 __func__);
7550
7551 common.is_sound_focus_resp_success = false;
7552 v->cvp_state = CMD_STATUS_SUCCESS;
7553 v->async_err = ptr[1];
7554 wake_up(&v->cvp_wait);
7555 break;
7556 case VSS_ISOURCETRACK_CMD_GET_ACTIVITY:
7557 if (!ptr[1]) {
7558 /* Read data from shared memory */
7559 memcpy(&common.sourceTrackingResponse,
7560 common.source_tracking_sh_mem.
7561 sh_mem_block.data,
7562 sizeof(struct
7563 vss_isourcetrack_activity_data_t));
7564 common.is_source_tracking_resp_success =
7565 true;
7566 } else {
7567 common.is_source_tracking_resp_success =
7568 false;
7569 pr_err("%s: Error received for source tracking params\n",
7570 __func__);
7571 }
7572 v->cvp_state = CMD_STATUS_SUCCESS;
7573 v->async_err = ptr[1];
7574 wake_up(&v->cvp_wait);
7575 break;
7576 default:
7577 pr_debug("%s: not match cmd = 0x%x\n",
7578 __func__, ptr[0]);
7579 break;
7580 }
7581 }
7582 } else if (data->opcode == VSS_ICOMMON_RSP_GET_PARAM) {
7583 pr_debug("%s: VSS_ICOMMON_RSP_GET_PARAM\n", __func__);
7584 ptr = data->payload;
7585 if (ptr[0] != 0) {
7586 pr_err("%s: VSS_ICOMMON_RSP_GET_PARAM returned error = 0x%x\n",
7587 __func__, ptr[0]);
7588 }
7589 rtac_make_voice_callback(RTAC_CVP, data->payload,
7590 data->payload_size);
7591 } else if (data->opcode == VSS_IVPCM_EVT_NOTIFY_V2) {
7592 if ((data->payload != NULL) && data->payload_size ==
7593 sizeof(struct vss_ivpcm_evt_notify_v2_t) &&
7594 common.hostpcm_info.hostpcm_evt_cb != NULL) {
7595 common.hostpcm_info.hostpcm_evt_cb(data->payload,
7596 voc_get_session_name(v->session_id),
7597 common.hostpcm_info.private_data);
7598 }
7599 } else if (data->opcode == VSS_ISOUNDFOCUS_RSP_GET_SECTORS) {
7600 if (data->payload && (data->payload_size ==
7601 sizeof(struct vss_isoundfocus_rsp_get_sectors_t))) {
7602 common.is_sound_focus_resp_success = true;
7603 memcpy(&common.soundFocusResponse,
7604 (struct vss_isoundfocus_rsp_get_sectors_t *)
7605 data->payload,
7606 sizeof(struct
7607 vss_isoundfocus_rsp_get_sectors_t));
7608 } else {
7609 common.is_sound_focus_resp_success = false;
7610 pr_debug("%s: Invalid payload received from CVD\n",
7611 __func__);
7612 }
7613 v->cvp_state = CMD_STATUS_SUCCESS;
7614 wake_up(&v->cvp_wait);
7615 }
7616 return 0;
7617}
7618
7619static int voice_free_oob_shared_mem(void)
7620{
7621 int rc = 0;
7622 int cnt = 0;
7623 int bufcnt = NUM_OF_BUFFERS;
7624 struct voice_data *v = voice_get_session(
7625 common.voice[VOC_PATH_FULL].session_id);
7626
7627 mutex_lock(&common.common_lock);
7628 if (v == NULL) {
7629 pr_err("%s: v is NULL\n", __func__);
7630
7631 rc = -EINVAL;
7632 goto done;
7633 }
7634
7635 rc = msm_audio_ion_free(v->shmem_info.sh_buf.client,
7636 v->shmem_info.sh_buf.handle);
7637 v->shmem_info.sh_buf.client = NULL;
7638 v->shmem_info.sh_buf.handle = NULL;
7639 if (rc < 0) {
7640 pr_err("%s: Error:%d freeing memory\n", __func__, rc);
7641
7642 goto done;
7643 }
7644
7645
7646 while (cnt < bufcnt) {
7647 v->shmem_info.sh_buf.buf[cnt].data = NULL;
7648 v->shmem_info.sh_buf.buf[cnt].phys = 0;
7649 cnt++;
7650 }
7651
7652 v->shmem_info.sh_buf.client = NULL;
7653 v->shmem_info.sh_buf.handle = NULL;
7654
7655done:
7656 mutex_unlock(&common.common_lock);
7657 return rc;
7658}
7659
7660static int voice_alloc_oob_shared_mem(void)
7661{
7662 int cnt = 0;
7663 int rc = 0;
7664 size_t len;
7665 void *mem_addr;
7666 dma_addr_t phys;
7667 int bufsz = BUFFER_BLOCK_SIZE;
7668 int bufcnt = NUM_OF_BUFFERS;
7669 struct voice_data *v = voice_get_session(
7670 common.voice[VOC_PATH_FULL].session_id);
7671
7672 mutex_lock(&common.common_lock);
7673 if (v == NULL) {
7674 pr_err("%s: v is NULL\n", __func__);
7675
7676 rc = -EINVAL;
7677 goto done;
7678 }
7679
7680 rc = msm_audio_ion_alloc("voip_client", &(v->shmem_info.sh_buf.client),
7681 &(v->shmem_info.sh_buf.handle),
7682 bufsz*bufcnt,
7683 &phys, &len,
7684 &mem_addr);
7685 if (rc < 0) {
7686 pr_err("%s: audio ION alloc failed, rc = %d\n",
7687 __func__, rc);
7688
7689 goto done;
7690 }
7691
7692 while (cnt < bufcnt) {
7693 v->shmem_info.sh_buf.buf[cnt].data = mem_addr + (cnt * bufsz);
7694 v->shmem_info.sh_buf.buf[cnt].phys = phys + (cnt * bufsz);
7695 v->shmem_info.sh_buf.buf[cnt].size = bufsz;
7696 cnt++;
7697 }
7698
7699 pr_debug("%s buf[0].data:[%pK], buf[0].phys:[%pK], &buf[0].phys:[%pK],\n",
7700 __func__,
7701 (void *)v->shmem_info.sh_buf.buf[0].data,
7702 &v->shmem_info.sh_buf.buf[0].phys,
7703 (void *)&v->shmem_info.sh_buf.buf[0].phys);
7704 pr_debug("%s: buf[1].data:[%pK], buf[1].phys[%pK], &buf[1].phys[%pK]\n",
7705 __func__,
7706 (void *)v->shmem_info.sh_buf.buf[1].data,
7707 &v->shmem_info.sh_buf.buf[1].phys,
7708 (void *)&v->shmem_info.sh_buf.buf[1].phys);
7709
7710 memset((void *)v->shmem_info.sh_buf.buf[0].data, 0, (bufsz * bufcnt));
7711
7712done:
7713 mutex_unlock(&common.common_lock);
7714 return rc;
7715}
7716
7717static int voice_alloc_oob_mem_table(void)
7718{
7719 int rc = 0;
7720 size_t len;
7721 struct voice_data *v = voice_get_session(
7722 common.voice[VOC_PATH_FULL].session_id);
7723
7724 mutex_lock(&common.common_lock);
7725 if (v == NULL) {
7726 pr_err("%s: v is NULL\n", __func__);
7727
7728 rc = -EINVAL;
7729 goto done;
7730 }
7731
7732 rc = msm_audio_ion_alloc("voip_client", &(v->shmem_info.memtbl.client),
7733 &(v->shmem_info.memtbl.handle),
7734 sizeof(struct vss_imemory_table_t),
7735 &v->shmem_info.memtbl.phys,
7736 &len,
7737 &(v->shmem_info.memtbl.data));
7738 if (rc < 0) {
7739 pr_err("%s: audio ION alloc failed, rc = %d\n",
7740 __func__, rc);
7741
7742 goto done;
7743 }
7744
7745 v->shmem_info.memtbl.size = sizeof(struct vss_imemory_table_t);
7746 pr_debug("%s data[%pK]phys[%pK][%pK]\n", __func__,
7747 (void *)v->shmem_info.memtbl.data,
7748 &v->shmem_info.memtbl.phys,
7749 (void *)&v->shmem_info.memtbl.phys);
7750
7751done:
7752 mutex_unlock(&common.common_lock);
7753 return rc;
7754}
7755
7756int voc_send_cvp_start_vocpcm(uint32_t session_id,
7757 struct vss_ivpcm_tap_point *vpcm_tp,
7758 uint32_t no_of_tp)
7759{
7760 struct cvp_start_cmd cvp_start_cmd;
7761 int ret = 0;
7762 void *apr_cvp;
7763 u16 cvp_handle;
7764 struct voice_data *v = voice_get_session(session_id);
7765 int i = 0;
7766
7767 if (v == NULL) {
7768 pr_err("%s: v is NULL\n", __func__);
7769 ret = -EINVAL;
7770 goto done;
7771 }
7772 apr_cvp = common.apr_q6_cvp;
7773
7774 if (!apr_cvp) {
7775 pr_err("%s: apr_cvp is NULL.\n", __func__);
7776 ret = -EINVAL;
7777 goto done;
7778 }
7779
7780 cvp_handle = voice_get_cvp_handle(v);
7781
7782 /* Fill the header */
7783 cvp_start_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
7784 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
7785 cvp_start_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
7786 sizeof(struct vss_ivpcm_tap_point) * no_of_tp) +
7787 sizeof(cvp_start_cmd.vpcm_start_cmd.num_tap_points) +
7788 sizeof(cvp_start_cmd.vpcm_start_cmd.mem_handle);
7789 cvp_start_cmd.hdr.src_port = voice_get_idx_for_session(v->session_id);
7790 cvp_start_cmd.hdr.dest_port = cvp_handle;
7791 cvp_start_cmd.hdr.token = 0;
7792 cvp_start_cmd.hdr.opcode = VSS_IVPCM_CMD_START_V2;
7793
7794 for (i = 0; i < no_of_tp; i++) {
7795 cvp_start_cmd.vpcm_start_cmd.tap_points[i].tap_point =
7796 vpcm_tp[i].tap_point;
7797 cvp_start_cmd.vpcm_start_cmd.tap_points[i].direction =
7798 vpcm_tp[i].direction;
7799 cvp_start_cmd.vpcm_start_cmd.tap_points[i].sampling_rate =
7800 vpcm_tp[i].sampling_rate;
7801 cvp_start_cmd.vpcm_start_cmd.tap_points[i].duration = 0;
7802 }
7803
7804 cvp_start_cmd.vpcm_start_cmd.mem_handle =
7805 common.voice_host_pcm_mem_handle;
7806 cvp_start_cmd.vpcm_start_cmd.num_tap_points = no_of_tp;
7807
7808 v->cvp_state = CMD_STATUS_FAIL;
7809 v->async_err = 0;
7810 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_start_cmd);
7811 if (ret < 0) {
7812 pr_err("%s: Fail: sending vocpcm map memory,\n", __func__);
7813 goto done;
7814 }
7815 ret = wait_event_timeout(v->cvp_wait,
7816 (v->cvp_state == CMD_STATUS_SUCCESS),
7817 msecs_to_jiffies(TIMEOUT_MS));
7818 if (!ret) {
7819 pr_err("%s: wait_event timeout\n", __func__);
7820 goto done;
7821 }
7822 if (v->async_err > 0) {
7823 pr_err("%s: DSP returned error[%s]\n",
7824 __func__, adsp_err_get_err_str(
7825 v->async_err));
7826 ret = adsp_err_get_lnx_err_code(
7827 v->async_err);
7828 goto done;
7829 }
7830
7831done:
7832 return ret;
7833}
7834
7835int voc_send_cvp_stop_vocpcm(uint32_t session_id)
7836{
7837 struct cvp_command vpcm_stop_cmd;
7838 int ret = 0;
7839 void *apr_cvp;
7840 u16 cvp_handle;
7841 struct voice_data *v = voice_get_session(session_id);
7842
7843 if (v == NULL) {
7844 pr_err("%s: v is NULL\n", __func__);
7845 ret = -EINVAL;
7846 goto done;
7847 }
7848 apr_cvp = common.apr_q6_cvp;
7849
7850 if (!apr_cvp) {
7851 pr_err("%s: apr_cvp is NULL.\n", __func__);
7852 ret = -EINVAL;
7853 goto done;
7854 }
7855
7856 cvp_handle = voice_get_cvp_handle(v);
7857
7858 /* fill in the header */
7859 vpcm_stop_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
7860 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
7861 vpcm_stop_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
7862 sizeof(vpcm_stop_cmd) - APR_HDR_SIZE);
7863 vpcm_stop_cmd.hdr.src_port = voice_get_idx_for_session(v->session_id);
7864 vpcm_stop_cmd.hdr.dest_port = cvp_handle;
7865 vpcm_stop_cmd.hdr.token = 0;
7866 vpcm_stop_cmd.hdr.opcode = VSS_IVPCM_CMD_STOP;
7867
7868 v->cvp_state = CMD_STATUS_FAIL;
7869 v->async_err = 0;
7870 ret = apr_send_pkt(apr_cvp, (uint32_t *) &vpcm_stop_cmd);
7871 if (ret < 0) {
7872 pr_err("Fail: sending vocpcm stop,\n");
7873 goto done;
7874 }
7875 ret = wait_event_timeout(v->cvp_wait,
7876 (v->cvp_state == CMD_STATUS_SUCCESS),
7877 msecs_to_jiffies(TIMEOUT_MS));
7878 if (!ret) {
7879 pr_err("%s: wait_event timeout\n", __func__);
7880 goto done;
7881 }
7882
7883 if (v->async_err > 0) {
7884 pr_err("%s: DSP returned error[%s]\n",
7885 __func__, adsp_err_get_err_str(
7886 v->async_err));
7887 ret = adsp_err_get_lnx_err_code(
7888 v->async_err);
7889 goto done;
7890 }
7891
7892done:
7893 return ret;
7894}
7895
7896int voc_send_cvp_map_vocpcm_memory(uint32_t session_id,
7897 struct mem_map_table *tp_mem_table,
7898 phys_addr_t paddr, uint32_t bufsize)
7899{
7900 return voice_map_memory_physical_cmd(voice_get_session(session_id),
7901 tp_mem_table,
7902 (dma_addr_t) paddr, bufsize,
7903 VOC_VOICE_HOST_PCM_MAP_TOKEN);
7904}
7905
7906int voc_send_cvp_unmap_vocpcm_memory(uint32_t session_id)
7907{
7908 int ret = 0;
7909
7910 ret = voice_send_mvm_unmap_memory_physical_cmd(
7911 voice_get_session(session_id),
7912 common.voice_host_pcm_mem_handle);
7913
7914 if (ret == 0)
7915 common.voice_host_pcm_mem_handle = 0;
7916
7917 return ret;
7918}
7919
7920int voc_send_cvp_vocpcm_push_buf_evt(uint32_t session_id,
7921 struct vss_ivpcm_evt_push_buffer_v2_t *push_buff_evt)
7922{
7923 struct cvp_push_buf_cmd vpcm_push_buf_cmd;
7924 int ret = 0;
7925 void *apr_cvp;
7926 u16 cvp_handle;
7927 struct voice_data *v = voice_get_session(session_id);
7928
7929 if (v == NULL) {
7930 pr_err("%s: v is NULL\n", __func__);
7931 ret = -EINVAL;
7932 goto done;
7933 }
7934 apr_cvp = common.apr_q6_cvp;
7935
7936 if (!apr_cvp) {
7937 pr_err("%s: apr_cvp is NULL.\n", __func__);
7938 ret = -EINVAL;
7939 goto done;
7940 }
7941
7942 memset(&vpcm_push_buf_cmd, 0, sizeof(vpcm_push_buf_cmd));
7943 cvp_handle = voice_get_cvp_handle(v);
7944
7945 /* fill in the header */
7946 vpcm_push_buf_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
7947 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
7948 vpcm_push_buf_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
7949 sizeof(vpcm_push_buf_cmd) - APR_HDR_SIZE);
7950 vpcm_push_buf_cmd.hdr.src_port =
7951 voice_get_idx_for_session(v->session_id);
7952 vpcm_push_buf_cmd.hdr.dest_port = cvp_handle;
7953 vpcm_push_buf_cmd.hdr.token = 0;
7954 vpcm_push_buf_cmd.hdr.opcode = VSS_IVPCM_EVT_PUSH_BUFFER_V2;
7955
7956 vpcm_push_buf_cmd.vpcm_evt_push_buffer.tap_point =
7957 push_buff_evt->tap_point;
7958 vpcm_push_buf_cmd.vpcm_evt_push_buffer.push_buf_mask =
7959 push_buff_evt->push_buf_mask;
7960 vpcm_push_buf_cmd.vpcm_evt_push_buffer.out_buf_mem_address =
7961 push_buff_evt->out_buf_mem_address;
7962 vpcm_push_buf_cmd.vpcm_evt_push_buffer.in_buf_mem_address =
7963 push_buff_evt->in_buf_mem_address;
7964 vpcm_push_buf_cmd.vpcm_evt_push_buffer.out_buf_mem_size =
7965 push_buff_evt->out_buf_mem_size;
7966 vpcm_push_buf_cmd.vpcm_evt_push_buffer.in_buf_mem_size =
7967 push_buff_evt->in_buf_mem_size;
7968 vpcm_push_buf_cmd.vpcm_evt_push_buffer.sampling_rate =
7969 push_buff_evt->sampling_rate;
7970 vpcm_push_buf_cmd.vpcm_evt_push_buffer.num_in_channels =
7971 push_buff_evt->num_in_channels;
7972
7973 ret = apr_send_pkt(apr_cvp, (uint32_t *) &vpcm_push_buf_cmd);
7974 if (ret < 0) {
7975 pr_err("Fail: sending vocpcm map memory,\n");
7976 goto done;
7977 }
7978
7979done:
7980 return ret;
7981}
7982
7983void voc_register_hpcm_evt_cb(hostpcm_cb_fn hostpcm_cb,
7984 void *private_data)
7985{
7986 common.hostpcm_info.hostpcm_evt_cb = hostpcm_cb;
7987 common.hostpcm_info.private_data = private_data;
7988}
7989
7990void voc_deregister_hpcm_evt_cb(void)
7991{
7992 common.hostpcm_info.hostpcm_evt_cb = NULL;
7993 common.hostpcm_info.private_data = NULL;
7994}
7995
7996int voc_get_cvd_version(char *cvd_version)
7997{
7998 int ret = 0;
7999 struct voice_data *v = voice_get_session(VOICE_SESSION_VSID);
8000
8001
8002 if (v == NULL) {
8003 pr_err("%s: invalid session_id 0x%x\n",
8004 __func__, VOICE_SESSION_VSID);
8005
8006 ret = -EINVAL;
8007 goto done;
8008 }
8009
8010 if (is_cvd_version_queried()) {
8011 pr_debug("%s: Returning the cached value %s\n",
8012 __func__, common.cvd_version);
8013
8014 goto done;
8015 }
8016
8017 /* Register callback to APR */
8018 ret = voice_apr_register(VOICE_SESSION_VSID);
8019 if (ret < 0) {
8020 pr_err("%s: apr register failed\n", __func__);
8021 goto done;
8022 }
8023
8024 mutex_lock(&common.common_lock);
8025 mutex_lock(&v->lock);
8026 ret = voice_send_mvm_cvd_version_cmd(v);
8027 if (ret < 0) {
8028 pr_err("%s: voice_send_mvm_cvd_version_cmd failed\n", __func__);
8029 goto unlock;
8030 }
8031 ret = 0;
8032
8033unlock:
8034 mutex_unlock(&v->lock);
8035 mutex_unlock(&common.common_lock);
8036
8037done:
8038 if (cvd_version)
8039 memcpy(cvd_version, common.cvd_version,
8040 CVD_VERSION_STRING_MAX_SIZE);
8041
8042 return ret;
8043}
8044
8045static int voice_alloc_cal_mem_map_table(void)
8046{
8047 int ret = 0;
8048 size_t len;
8049
8050 ret = msm_audio_ion_alloc("voc_cal",
8051 &(common.cal_mem_map_table.client),
8052 &(common.cal_mem_map_table.handle),
8053 sizeof(struct vss_imemory_table_t),
8054 &common.cal_mem_map_table.phys,
8055 &len,
8056 &(common.cal_mem_map_table.data));
8057 if ((ret < 0) && (ret != -EPROBE_DEFER)) {
8058 pr_err("%s: audio ION alloc failed, rc = %d\n",
8059 __func__, ret);
8060 goto done;
8061 }
8062
8063 common.cal_mem_map_table.size = sizeof(struct vss_imemory_table_t);
8064 pr_debug("%s: data %pK phys %pK\n", __func__,
8065 common.cal_mem_map_table.data,
8066 &common.cal_mem_map_table.phys);
8067
8068done:
8069 return ret;
8070}
8071
8072static int voice_alloc_rtac_mem_map_table(void)
8073{
8074 int ret = 0;
8075 size_t len;
8076
8077 ret = msm_audio_ion_alloc("voc_rtac_cal",
8078 &(common.rtac_mem_map_table.client),
8079 &(common.rtac_mem_map_table.handle),
8080 sizeof(struct vss_imemory_table_t),
8081 &common.rtac_mem_map_table.phys,
8082 &len,
8083 &(common.rtac_mem_map_table.data));
8084 if (ret < 0) {
8085 pr_err("%s: audio ION alloc failed, rc = %d\n",
8086 __func__, ret);
8087 goto done;
8088 }
8089
8090 common.rtac_mem_map_table.size = sizeof(struct vss_imemory_table_t);
8091 pr_debug("%s: data %pK phys %pK\n", __func__,
8092 common.rtac_mem_map_table.data,
8093 &common.rtac_mem_map_table.phys);
8094
8095done:
8096 return ret;
8097}
8098
8099static int voice_alloc_and_map_oob_mem(struct voice_data *v)
8100{
8101 int ret = 0;
8102
8103 if (v == NULL) {
8104 pr_err("%s: v is NULL\n", __func__);
8105
8106 return -EINVAL;
8107 }
8108
8109 if (!is_voip_memory_allocated()) {
8110 ret = voc_alloc_voip_shared_memory();
8111 if (ret < 0) {
8112 pr_err("%s: Failed to create voip oob memory %d\n",
8113 __func__, ret);
8114
8115 goto done;
8116 }
8117 }
8118
8119 ret = voice_map_memory_physical_cmd(v,
8120 &v->shmem_info.memtbl,
8121 v->shmem_info.sh_buf.buf[0].phys,
8122 v->shmem_info.sh_buf.buf[0].size * NUM_OF_BUFFERS,
8123 VOIP_MEM_MAP_TOKEN);
8124 if (ret) {
8125 pr_err("%s: mvm_map_memory_phy failed %d\n",
8126 __func__, ret);
8127
8128 goto done;
8129 }
8130
8131done:
8132 return ret;
8133}
8134
8135uint32_t voice_get_topology(uint32_t topology_idx)
8136{
8137 uint32_t topology = VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
8138 struct cal_block_data *cal_block = NULL;
8139
8140 /* initialize as default topology */
8141 if (topology_idx == CVP_VOC_RX_TOPOLOGY_CAL) {
8142 topology = VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
8143 } else if (topology_idx == CVP_VOC_TX_TOPOLOGY_CAL) {
Laxminath Kasam8f7ccc22017-08-28 17:35:04 +05308144 topology = VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS_V2;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308145 } else {
8146 pr_err("%s: cal index %x is invalid!\n",
8147 __func__, topology_idx);
8148
8149 goto done;
8150 }
8151
8152 if (common.cal_data[topology_idx] == NULL) {
8153 pr_err("%s: cal type is NULL for cal index %x\n",
8154 __func__, topology_idx);
8155
8156 goto done;
8157 }
8158
8159 mutex_lock(&common.cal_data[topology_idx]->lock);
8160 cal_block = cal_utils_get_only_cal_block(
8161 common.cal_data[topology_idx]);
8162 if (cal_block == NULL) {
8163 pr_debug("%s: cal_block not found for cal index %x\n",
8164 __func__, topology_idx);
8165
8166 goto unlock;
8167 }
8168
8169 topology = ((struct audio_cal_info_voc_top *)
8170 cal_block->cal_info)->topology;
8171unlock:
8172 mutex_unlock(&common.cal_data[topology_idx]->lock);
8173done:
8174 pr_debug("%s: Using topology %d\n", __func__, topology);
8175
8176 return topology;
8177}
8178
Aditya Bavanari88513a32017-10-12 12:29:25 +05308179int voice_set_topology_specific_info(struct voice_data *v,
8180 uint32_t topology_idx)
8181{
8182 struct cal_block_data *cal_block = NULL;
8183 int ret = 0;
8184 uint32_t topo_channels;
8185
8186 if (common.cal_data[topology_idx] == NULL) {
8187 pr_err("%s: cal type is NULL for cal index %x\n",
8188 __func__, topology_idx);
8189 ret = -EINVAL;
8190 goto done;
8191 }
8192
8193 mutex_lock(&common.cal_data[topology_idx]->lock);
8194 cal_block = cal_utils_get_only_cal_block(
8195 common.cal_data[topology_idx]);
8196 if (cal_block == NULL) {
8197 pr_debug("%s: cal_block not found for cal index %x\n",
8198 __func__, topology_idx);
8199 ret = -EINVAL;
8200 goto unlock;
8201 }
8202
8203 if (topology_idx == CVP_VOC_RX_TOPOLOGY_CAL) {
8204 topo_channels = ((struct audio_cal_info_voc_top *)
8205 cal_block->cal_info)->num_channels;
8206 if (topo_channels > 0) {
8207 v->dev_rx.no_of_channels = topo_channels;
8208 pr_debug("%s: Topology Rx no of channels: %d",
8209 __func__, v->dev_rx.no_of_channels);
8210 memcpy(&v->dev_rx.channel_mapping,
8211 &((struct audio_cal_info_voc_top *)
8212 cal_block->cal_info)->channel_mapping,
8213 VSS_CHANNEL_MAPPING_SIZE);
8214 } else {
8215 pr_debug("%s: cal data is zero, default to Rx backend config\n",
8216 __func__);
8217 if (v->dev_rx.no_of_channels == NUM_CHANNELS_MONO) {
8218 v->dev_rx.channel_mapping[0] = PCM_CHANNEL_FC;
8219 } else if (v->dev_rx.no_of_channels ==
8220 NUM_CHANNELS_STEREO) {
8221 v->dev_rx.channel_mapping[0] = PCM_CHANNEL_FL;
8222 v->dev_rx.channel_mapping[1] = PCM_CHANNEL_FR;
8223 } else {
8224 pr_warn("%s: Unsupported Rx num channels: %d\n",
8225 __func__, v->dev_rx.no_of_channels);
8226 }
8227 }
8228 } else if (topology_idx == CVP_VOC_TX_TOPOLOGY_CAL) {
8229 topo_channels = ((struct audio_cal_info_voc_top *)
8230 cal_block->cal_info)->num_channels;
8231 if (topo_channels > 0) {
8232 v->dev_tx.no_of_channels = topo_channels;
8233 pr_debug("%s: Topology Tx no of channels: %d",
8234 __func__, v->dev_tx.no_of_channels);
8235 memcpy(&v->dev_tx.channel_mapping,
8236 &((struct audio_cal_info_voc_top *)
8237 cal_block->cal_info)->channel_mapping,
8238 VSS_CHANNEL_MAPPING_SIZE);
8239 } else {
8240 pr_debug("%s: cal data is zero, default to Tx backend config\n",
8241 __func__);
8242 if (v->dev_tx.no_of_channels == NUM_CHANNELS_MONO) {
8243 v->dev_tx.channel_mapping[0] = PCM_CHANNEL_FC;
8244 } else if (v->dev_tx.no_of_channels ==
8245 NUM_CHANNELS_STEREO) {
8246 v->dev_tx.channel_mapping[0] = PCM_CHANNEL_FL;
8247 v->dev_tx.channel_mapping[1] = PCM_CHANNEL_FR;
8248 } else if (v->dev_tx.no_of_channels ==
8249 NUM_CHANNELS_QUAD) {
8250 v->dev_tx.channel_mapping[0] = PCM_CHANNEL_FL;
8251 v->dev_tx.channel_mapping[1] = PCM_CHANNEL_FR;
8252 v->dev_tx.channel_mapping[2] = PCM_CHANNEL_LS;
8253 v->dev_tx.channel_mapping[3] = PCM_CHANNEL_RS;
8254 } else {
8255 pr_warn("%s: Unsupported Tx num channels: %d\n",
8256 __func__, v->dev_tx.no_of_channels);
8257 }
8258 }
8259 } else {
8260 pr_err("%s: topology index %x is invalid\n",
8261 __func__, topology_idx);
8262 }
8263unlock:
8264 mutex_unlock(&common.cal_data[topology_idx]->lock);
8265done:
8266 return ret;
8267}
8268
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308269static int get_cal_type_index(int32_t cal_type)
8270{
8271 int ret = -EINVAL;
8272
8273 switch (cal_type) {
8274 case CVP_VOC_RX_TOPOLOGY_CAL_TYPE:
8275 ret = CVP_VOC_RX_TOPOLOGY_CAL;
8276 break;
8277 case CVP_VOC_TX_TOPOLOGY_CAL_TYPE:
8278 ret = CVP_VOC_TX_TOPOLOGY_CAL;
8279 break;
8280 case CVP_VOCPROC_STATIC_CAL_TYPE:
8281 ret = CVP_VOCPROC_CAL;
8282 break;
8283 case CVP_VOCPROC_DYNAMIC_CAL_TYPE:
8284 ret = CVP_VOCVOL_CAL;
8285 break;
8286 case CVS_VOCSTRM_STATIC_CAL_TYPE:
8287 ret = CVS_VOCSTRM_CAL;
8288 break;
8289 case CVP_VOCDEV_CFG_CAL_TYPE:
8290 ret = CVP_VOCDEV_CFG_CAL;
8291 break;
8292 case CVP_VOCPROC_STATIC_COL_CAL_TYPE:
8293 ret = CVP_VOCPROC_COL_CAL;
8294 break;
8295 case CVP_VOCPROC_DYNAMIC_COL_CAL_TYPE:
8296 ret = CVP_VOCVOL_COL_CAL;
8297 break;
8298 case CVS_VOCSTRM_STATIC_COL_CAL_TYPE:
8299 ret = CVS_VOCSTRM_COL_CAL;
8300 break;
8301 case VOICE_RTAC_INFO_CAL_TYPE:
8302 ret = VOICE_RTAC_INFO_CAL;
8303 break;
8304 case VOICE_RTAC_APR_CAL_TYPE:
8305 ret = VOICE_RTAC_APR_CAL;
8306 break;
8307 default:
8308 pr_err("%s: Invalid cal type %d!\n", __func__, cal_type);
8309 }
8310 return ret;
8311}
8312
8313static int voice_prepare_volume_boost(int32_t cal_type,
8314 size_t data_size, void *data)
8315{
8316 return voc_deregister_vocproc_vol_table();
8317}
8318
8319static int voice_enable_volume_boost(int32_t cal_type,
8320 size_t data_size, void *data)
8321{
8322 return voc_register_vocproc_vol_table();
8323}
8324
8325static int voice_alloc_cal(int32_t cal_type,
8326 size_t data_size, void *data)
8327{
8328 int ret = 0;
8329 int cal_index;
8330 int cal_version;
8331
8332 pr_debug("%s\n", __func__);
8333
8334 cal_version = cal_utils_get_cal_type_version(data);
8335 common.is_per_vocoder_cal_enabled =
8336 !!(cal_version & PER_VOCODER_CAL_BIT_MASK);
8337
8338 cal_index = get_cal_type_index(cal_type);
8339 if (cal_index < 0) {
8340 pr_err("%s: Could not get cal index %d!\n",
8341 __func__, cal_index);
8342 ret = -EINVAL;
8343 goto done;
8344 }
8345
8346 ret = cal_utils_alloc_cal(data_size, data,
8347 common.cal_data[cal_index], 0, NULL);
8348 if (ret < 0) {
8349 pr_err("%s: Cal_utils_alloc_block failed, ret = %d, cal type = %d!\n",
8350 __func__, ret, cal_type);
8351 ret = -EINVAL;
8352 goto done;
8353 }
8354done:
8355 return ret;
8356}
8357
8358static int voice_dealloc_cal(int32_t cal_type,
8359 size_t data_size, void *data)
8360{
8361 int ret = 0;
8362 int cal_index;
8363
8364 pr_debug("%s\n", __func__);
8365
8366 cal_index = get_cal_type_index(cal_type);
8367 if (cal_index < 0) {
8368 pr_err("%s: Could not get cal index %d!\n",
8369 __func__, cal_index);
8370
8371 ret = -EINVAL;
8372 goto done;
8373 }
8374
8375 ret = cal_utils_dealloc_cal(data_size, data,
8376 common.cal_data[cal_index]);
8377 if (ret < 0) {
8378 pr_err("%s: Cal_utils_dealloc_block failed, ret = %d, cal type = %d!\n",
8379 __func__, ret, cal_type);
8380
8381 ret = -EINVAL;
8382 goto done;
8383 }
8384done:
8385 return ret;
8386}
8387
8388static int voice_set_cal(int32_t cal_type,
8389 size_t data_size, void *data)
8390{
8391 int ret = 0;
8392 int cal_index;
8393
8394 pr_debug("%s\n", __func__);
8395
8396 cal_index = get_cal_type_index(cal_type);
8397 if (cal_index < 0) {
8398 pr_err("%s: Could not get cal index %d!\n",
8399 __func__, cal_index);
8400
8401 ret = -EINVAL;
8402 goto done;
8403 }
8404
8405 ret = cal_utils_set_cal(data_size, data,
8406 common.cal_data[cal_index], 0, NULL);
8407 if (ret < 0) {
8408 pr_err("%s: Cal_utils_set_cal failed, ret = %d, cal type = %d!\n",
8409 __func__, ret, cal_type);
8410
8411 ret = -EINVAL;
8412 goto done;
8413 }
8414done:
8415 return ret;
8416}
8417
8418static void voice_delete_cal_data(void)
8419{
8420 pr_debug("%s\n", __func__);
8421
8422 cal_utils_destroy_cal_types(MAX_VOICE_CAL_TYPES, common.cal_data);
8423}
8424
8425static int voice_init_cal_data(void)
8426{
8427 int ret = 0;
8428 struct cal_type_info cal_type_info[] = {
8429 {{CVP_VOC_RX_TOPOLOGY_CAL_TYPE,
8430 {NULL, NULL, NULL, voice_set_cal, NULL, NULL} },
8431 {NULL, NULL, cal_utils_match_buf_num} },
8432
8433 {{CVP_VOC_TX_TOPOLOGY_CAL_TYPE,
8434 {NULL, NULL, NULL, voice_set_cal, NULL, NULL} },
8435 {NULL, NULL, cal_utils_match_buf_num} },
8436
8437 {{CVP_VOCPROC_STATIC_CAL_TYPE,
8438 {voice_alloc_cal, voice_dealloc_cal, NULL,
8439 voice_set_cal, NULL, NULL} },
8440 {NULL, voice_unmap_cal_memory,
8441 cal_utils_match_buf_num} },
8442
8443 {{CVP_VOCPROC_DYNAMIC_CAL_TYPE,
8444 {voice_alloc_cal, voice_dealloc_cal,
8445 voice_prepare_volume_boost,
8446 voice_set_cal, NULL,
8447 voice_enable_volume_boost} },
8448 {NULL, voice_unmap_cal_memory,
8449 cal_utils_match_buf_num} },
8450
8451 {{CVP_VOCDEV_CFG_CAL_TYPE,
8452 {voice_alloc_cal, voice_dealloc_cal, NULL,
8453 voice_set_cal, NULL, NULL} },
8454 {NULL, voice_unmap_cal_memory,
8455 cal_utils_match_buf_num} },
8456
8457 {{CVP_VOCPROC_STATIC_COL_CAL_TYPE,
8458 {NULL, NULL, NULL, voice_set_cal, NULL, NULL} },
8459 {NULL, NULL, cal_utils_match_buf_num} },
8460
8461 {{CVP_VOCPROC_DYNAMIC_COL_CAL_TYPE,
8462 {NULL, NULL, NULL, voice_set_cal, NULL, NULL} },
8463 {NULL, NULL, cal_utils_match_buf_num} },
8464
8465 {{CVS_VOCSTRM_STATIC_CAL_TYPE,
8466 {voice_alloc_cal, voice_dealloc_cal, NULL,
8467 voice_set_cal, NULL, NULL} },
8468 {NULL, voice_unmap_cal_memory,
8469 cal_utils_match_buf_num} },
8470
8471 {{CVS_VOCSTRM_STATIC_COL_CAL_TYPE,
8472 {NULL, NULL, NULL, voice_set_cal, NULL, NULL} },
8473 {NULL, NULL, cal_utils_match_buf_num} },
8474
8475 {{VOICE_RTAC_INFO_CAL_TYPE,
8476 {NULL, NULL, NULL, NULL, NULL, NULL} },
8477 {NULL, NULL, cal_utils_match_buf_num} },
8478
8479 {{VOICE_RTAC_APR_CAL_TYPE,
8480 {NULL, NULL, NULL, NULL, NULL, NULL} },
8481 {NULL, NULL, cal_utils_match_buf_num} },
8482 };
8483
8484 ret = cal_utils_create_cal_types(MAX_VOICE_CAL_TYPES, common.cal_data,
8485 cal_type_info);
8486 if (ret < 0) {
8487 pr_err("%s: Could not create cal type!\n",
8488 __func__);
8489
8490 ret = -EINVAL;
8491 goto err;
8492 }
8493
8494 return ret;
8495err:
8496 voice_delete_cal_data();
8497 memset(&common, 0, sizeof(struct common_data));
8498 return ret;
8499}
8500
8501static int voice_send_set_sound_focus_cmd(struct voice_data *v,
8502 struct sound_focus_param soundFocusData)
8503{
8504 struct cvp_set_sound_focus_param_cmd_t cvp_set_sound_focus_param_cmd;
8505 int ret = 0;
8506 void *apr_cvp;
8507 u16 cvp_handle;
8508 int i;
8509
8510 pr_debug("%s: Enter\n", __func__);
8511
8512 if (v == NULL) {
8513 pr_err("%s: v is NULL\n", __func__);
8514
8515 ret = -EINVAL;
8516 goto done;
8517 }
8518 apr_cvp = common.apr_q6_cvp;
8519
8520 if (!apr_cvp) {
8521 pr_err("%s: apr_cvp is NULL.\n", __func__);
8522
8523 ret = -EINVAL;
8524 goto done;
8525 }
8526 cvp_handle = voice_get_cvp_handle(v);
8527
8528 /* send Sound Focus Params to cvp */
8529 cvp_set_sound_focus_param_cmd.hdr.hdr_field =
8530 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
8531 APR_HDR_LEN(APR_HDR_SIZE),
8532 APR_PKT_VER);
8533 cvp_set_sound_focus_param_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
8534 sizeof(cvp_set_sound_focus_param_cmd) - APR_HDR_SIZE);
8535 cvp_set_sound_focus_param_cmd.hdr.src_port =
8536 voice_get_idx_for_session(v->session_id);
8537 cvp_set_sound_focus_param_cmd.hdr.dest_port = cvp_handle;
8538 cvp_set_sound_focus_param_cmd.hdr.token = 0;
8539 cvp_set_sound_focus_param_cmd.hdr.opcode =
8540 VSS_ISOUNDFOCUS_CMD_SET_SECTORS;
8541
8542 memset(&(cvp_set_sound_focus_param_cmd.cvp_set_sound_focus_param), 0xFF,
8543 sizeof(struct vss_isoundfocus_cmd_set_sectors_t));
8544 for (i = 0; i < MAX_SECTORS; i++) {
8545 cvp_set_sound_focus_param_cmd.cvp_set_sound_focus_param.
8546 start_angles[i] = soundFocusData.start_angle[i];
8547 cvp_set_sound_focus_param_cmd.cvp_set_sound_focus_param.
8548 enables[i] = soundFocusData.enable[i];
8549 pr_debug("%s: start_angle[%d] = %d\n",
8550 __func__, i, soundFocusData.start_angle[i]);
8551 pr_debug("%s: enable[%d] = %d\n",
8552 __func__, i, soundFocusData.enable[i]);
8553 }
8554 cvp_set_sound_focus_param_cmd.cvp_set_sound_focus_param.gain_step =
8555 soundFocusData.gain_step;
8556 pr_debug("%s: gain_step = %d\n", __func__, soundFocusData.gain_step);
8557
8558 v->cvp_state = CMD_STATUS_FAIL;
8559 v->async_err = 0;
8560
8561 ret = apr_send_pkt(apr_cvp, (uint32_t *)&cvp_set_sound_focus_param_cmd);
8562 if (ret < 0) {
8563 pr_err("%s: Error in sending APR command\n", __func__);
8564
8565 ret = -EINVAL;
8566 goto done;
8567 }
8568 ret = wait_event_timeout(v->cvp_wait,
8569 (v->cvp_state == CMD_STATUS_SUCCESS),
8570 msecs_to_jiffies(TIMEOUT_MS));
8571 if (!ret) {
8572 pr_err("%s: wait_event timeout\n", __func__);
8573
8574 ret = -EINVAL;
8575 goto done;
8576 }
8577
8578 if (v->async_err > 0) {
8579 pr_err("%s: DSP returned error[%s]\n",
8580 __func__, adsp_err_get_err_str(
8581 v->async_err));
8582 ret = adsp_err_get_lnx_err_code(
8583 v->async_err);
8584 goto done;
8585 }
8586
8587 if (common.is_sound_focus_resp_success) {
8588 ret = 0;
8589 } else {
8590 pr_err("%s: Error in setting sound focus params\n", __func__);
8591
8592 ret = -EINVAL;
8593 }
8594
8595done:
8596 pr_debug("%s: Exit, ret=%d\n", __func__, ret);
8597
8598 return ret;
8599}
8600
8601int voc_set_sound_focus(struct sound_focus_param soundFocusData)
8602{
8603 struct voice_data *v = NULL;
8604 int ret = -EINVAL;
8605 struct voice_session_itr itr;
8606
8607 pr_debug("%s: Enter\n", __func__);
8608
8609 mutex_lock(&common.common_lock);
8610 voice_itr_init(&itr, ALL_SESSION_VSID);
8611 while (voice_itr_get_next_session(&itr, &v)) {
8612 if (v != NULL) {
8613 mutex_lock(&v->lock);
8614 if (is_voc_state_active(v->voc_state) &&
8615 (v->lch_mode != VOICE_LCH_START) &&
8616 !v->disable_topology)
8617 ret = voice_send_set_sound_focus_cmd(v,
8618 soundFocusData);
8619 mutex_unlock(&v->lock);
8620 } else {
8621 pr_err("%s: invalid session\n", __func__);
8622
8623 ret = -EINVAL;
8624 break;
8625 }
8626 }
8627 mutex_unlock(&common.common_lock);
8628 pr_debug("%s: Exit, ret=%d\n", __func__, ret);
8629
8630 return ret;
8631}
8632
8633static int voice_send_get_sound_focus_cmd(struct voice_data *v,
8634 struct sound_focus_param *soundFocusData)
8635{
8636 struct apr_hdr cvp_get_sound_focus_param_cmd;
8637 int ret = 0;
8638 void *apr_cvp;
8639 u16 cvp_handle;
8640 int i;
8641
8642 pr_debug("%s: Enter\n", __func__);
8643
8644 if (!v) {
8645 pr_err("%s: v is NULL\n", __func__);
8646
8647 ret = -EINVAL;
8648 goto done;
8649 }
8650 apr_cvp = common.apr_q6_cvp;
8651
8652 if (!apr_cvp) {
8653 pr_err("%s: apr_cvp is NULL\n", __func__);
8654
8655 ret = -EINVAL;
8656 goto done;
8657 }
8658
8659 cvp_handle = voice_get_cvp_handle(v);
8660
8661 /* send APR command to retrieve Sound Focus Params */
8662 cvp_get_sound_focus_param_cmd.hdr_field =
8663 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
8664 APR_HDR_LEN(APR_HDR_SIZE),
8665 APR_PKT_VER);
8666 cvp_get_sound_focus_param_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
8667 sizeof(cvp_get_sound_focus_param_cmd) - APR_HDR_SIZE);
8668 cvp_get_sound_focus_param_cmd.src_port =
8669 voice_get_idx_for_session(v->session_id);
8670 cvp_get_sound_focus_param_cmd.dest_port = cvp_handle;
8671 cvp_get_sound_focus_param_cmd.token = 0;
8672 cvp_get_sound_focus_param_cmd.opcode = VSS_ISOUNDFOCUS_CMD_GET_SECTORS;
8673
8674 v->cvp_state = CMD_STATUS_FAIL;
8675 v->async_err = 0;
8676 ret = apr_send_pkt(apr_cvp, (uint32_t *)&cvp_get_sound_focus_param_cmd);
8677 if (ret < 0) {
8678 pr_err("%s: Error in sending APR command\n", __func__);
8679
8680 ret = -EINVAL;
8681 goto done;
8682 }
8683 ret = wait_event_timeout(v->cvp_wait,
8684 (v->cvp_state == CMD_STATUS_SUCCESS),
8685 msecs_to_jiffies(TIMEOUT_MS));
8686 if (!ret) {
8687 pr_err("%s: wait_event timeout\n", __func__);
8688
8689 ret = -EINVAL;
8690 goto done;
8691 }
8692
8693 if (v->async_err > 0) {
8694 pr_err("%s: DSP returned error[%s]\n",
8695 __func__, adsp_err_get_err_str(
8696 v->async_err));
8697 ret = adsp_err_get_lnx_err_code(
8698 v->async_err);
8699 goto done;
8700 }
8701
8702 if (common.is_sound_focus_resp_success) {
8703 for (i = 0; i < MAX_SECTORS; i++) {
8704 soundFocusData->start_angle[i] =
8705 common.soundFocusResponse.start_angles[i];
8706 soundFocusData->enable[i] =
8707 common.soundFocusResponse.enables[i];
8708 pr_debug("%s: start_angle[%d] = %d\n",
8709 __func__, i, soundFocusData->start_angle[i]);
8710 pr_debug("%s: enable[%d] = %d\n",
8711 __func__, i, soundFocusData->enable[i]);
8712 }
8713 soundFocusData->gain_step = common.soundFocusResponse.gain_step;
8714 pr_debug("%s: gain_step = %d\n", __func__,
8715 soundFocusData->gain_step);
8716
8717 common.is_sound_focus_resp_success = false;
8718 ret = 0;
8719 } else {
8720 pr_err("%s: Invalid payload received from CVD\n", __func__);
8721
8722 ret = -EINVAL;
8723 }
8724done:
8725 pr_debug("%s: Exit, ret=%d\n", __func__, ret);
8726
8727 return ret;
8728}
8729
8730int voc_get_sound_focus(struct sound_focus_param *soundFocusData)
8731{
8732 struct voice_data *v = NULL;
8733 int ret = -EINVAL;
8734 struct voice_session_itr itr;
8735
8736 pr_debug("%s: Enter\n", __func__);
8737
8738 mutex_lock(&common.common_lock);
8739 voice_itr_init(&itr, ALL_SESSION_VSID);
8740 while (voice_itr_get_next_session(&itr, &v)) {
8741 if (v) {
8742 mutex_lock(&v->lock);
8743 if (is_voc_state_active(v->voc_state) &&
8744 (v->lch_mode != VOICE_LCH_START) &&
8745 !v->disable_topology)
8746 ret = voice_send_get_sound_focus_cmd(v,
8747 soundFocusData);
8748 mutex_unlock(&v->lock);
8749 } else {
8750 pr_err("%s: invalid session\n", __func__);
8751
8752 ret = -EINVAL;
8753 break;
8754 }
8755 }
8756 mutex_unlock(&common.common_lock);
8757 pr_debug("%s: Exit, ret=%d\n", __func__, ret);
8758
8759 return ret;
8760}
8761
8762static int is_source_tracking_shared_memomry_allocated(void)
8763{
8764 bool ret;
8765
8766 pr_debug("%s: Enter\n", __func__);
8767
8768 if (common.source_tracking_sh_mem.sh_mem_block.client != NULL &&
8769 common.source_tracking_sh_mem.sh_mem_block.handle != NULL)
8770 ret = true;
8771 else
8772 ret = false;
8773
8774 pr_debug("%s: Exit\n", __func__);
8775
8776 return ret;
8777}
8778
8779static int voice_alloc_source_tracking_shared_memory(void)
8780{
8781 int ret = 0;
8782
8783 pr_debug("%s: Enter\n", __func__);
8784
8785 ret = msm_audio_ion_alloc("source_tracking_sh_mem_block",
8786 &(common.source_tracking_sh_mem.sh_mem_block.client),
8787 &(common.source_tracking_sh_mem.sh_mem_block.handle),
8788 BUFFER_BLOCK_SIZE,
8789 &(common.source_tracking_sh_mem.sh_mem_block.phys),
8790 (size_t *)&(common.source_tracking_sh_mem.sh_mem_block.size),
8791 &(common.source_tracking_sh_mem.sh_mem_block.data));
8792 if (ret < 0) {
8793 pr_err("%s: audio ION alloc failed for sh_mem block, ret = %d\n",
8794 __func__, ret);
8795
8796 ret = -EINVAL;
8797 goto done;
8798 }
8799 memset((void *)(common.source_tracking_sh_mem.sh_mem_block.data), 0,
8800 common.source_tracking_sh_mem.sh_mem_block.size);
8801
8802 pr_debug("%s: sh_mem_block: phys:[%pK], data:[0x%pK], size:[%zd]\n",
8803 __func__,
8804 &(common.source_tracking_sh_mem.sh_mem_block.phys),
8805 (void *)(common.source_tracking_sh_mem.sh_mem_block.data),
8806 (size_t)(common.source_tracking_sh_mem.sh_mem_block.size));
8807
8808 ret = msm_audio_ion_alloc("source_tracking_sh_mem_table",
8809 &(common.source_tracking_sh_mem.sh_mem_table.client),
8810 &(common.source_tracking_sh_mem.sh_mem_table.handle),
8811 sizeof(struct vss_imemory_table_t),
8812 &(common.source_tracking_sh_mem.sh_mem_table.phys),
8813 (size_t *)&(common.source_tracking_sh_mem.sh_mem_table.size),
8814 &(common.source_tracking_sh_mem.sh_mem_table.data));
8815 if (ret < 0) {
8816 pr_err("%s: audio ION alloc failed for sh_mem table, ret = %d\n",
8817 __func__, ret);
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 common.source_tracking_sh_mem.sh_mem_block.client = NULL;
8823 common.source_tracking_sh_mem.sh_mem_block.handle = NULL;
8824 if (ret < 0)
8825 pr_err("%s: Error:%d freeing memory\n", __func__, ret);
8826
8827 ret = -EINVAL;
8828 goto done;
8829 }
8830 memset((void *)(common.source_tracking_sh_mem.sh_mem_table.data), 0,
8831 common.source_tracking_sh_mem.sh_mem_table.size);
8832
8833 pr_debug("%s sh_mem_table: phys:[%pK], data:[0x%pK], size:[%zd],\n",
8834 __func__,
8835 &(common.source_tracking_sh_mem.sh_mem_table.phys),
8836 (void *)(common.source_tracking_sh_mem.sh_mem_table.data),
8837 (size_t)(common.source_tracking_sh_mem.sh_mem_table.size));
8838
8839done:
8840 pr_debug("%s: Exit, ret=%d\n", __func__, ret);
8841
8842 return ret;
8843}
8844
8845static int voice_alloc_and_map_source_tracking_shared_memory(
8846 struct voice_data *v)
8847{
8848 int ret = 0;
8849
8850 pr_debug("%s: Enter\n", __func__);
8851
8852 ret = voice_alloc_source_tracking_shared_memory();
8853 if (ret) {
8854 pr_err("%s: Failed to allocate shared memory %d\n",
8855 __func__, ret);
8856
8857 ret = -EINVAL;
8858 goto done;
8859 }
8860
8861 ret = voice_map_memory_physical_cmd(v,
8862 &(common.source_tracking_sh_mem.sh_mem_table),
8863 common.source_tracking_sh_mem.sh_mem_block.phys,
8864 common.source_tracking_sh_mem.sh_mem_block.size,
8865 VOC_SOURCE_TRACKING_MEM_MAP_TOKEN);
8866 if (ret) {
8867 pr_err("%s: memory mapping failed %d\n",
8868 __func__, ret);
8869
8870 ret = -EINVAL;
8871 goto done;
8872 }
8873
8874done:
8875 pr_debug("%s: Exit, ret=%d\n", __func__, ret);
8876
8877 return ret;
8878}
8879
8880static int voice_unmap_and_free_source_tracking_shared_memory(
8881 struct voice_data *v)
8882{
8883 int ret = 0;
8884
8885 pr_debug("%s: Enter\n", __func__);
8886
8887 if (common.source_tracking_sh_mem.mem_handle != 0) {
8888 ret = voice_send_mvm_unmap_memory_physical_cmd(v,
8889 common.source_tracking_sh_mem.mem_handle);
8890 if (ret < 0) {
8891 pr_err("%s: Memory_unmap failed err %d\n",
8892 __func__, ret);
8893
8894 ret = -EINVAL;
8895 goto done;
8896 }
8897 }
8898
8899 if ((common.source_tracking_sh_mem.sh_mem_block.client == NULL) ||
8900 (common.source_tracking_sh_mem.sh_mem_block.handle == NULL))
8901 goto done;
8902
8903 ret = msm_audio_ion_free(
8904 common.source_tracking_sh_mem.sh_mem_block.client,
8905 common.source_tracking_sh_mem.sh_mem_block.handle);
8906 if (ret < 0) {
8907 pr_err("%s: Error:%d freeing memory\n", __func__, ret);
8908
8909 ret = -EINVAL;
8910 goto done;
8911 }
8912
8913done:
8914 common.source_tracking_sh_mem.mem_handle = 0;
8915 common.source_tracking_sh_mem.sh_mem_block.client = NULL;
8916 common.source_tracking_sh_mem.sh_mem_block.handle = NULL;
8917 pr_debug("%s: Exit, ret=%d\n", __func__, ret);
8918
8919 return ret;
8920}
8921
8922static int voice_send_get_source_tracking_cmd(struct voice_data *v,
8923 struct source_tracking_param *sourceTrackingData)
8924{
8925 struct cvp_get_source_tracking_param_cmd_t st_cmd;
8926 int ret = 0;
8927 void *apr_cvp;
8928 u16 cvp_handle;
8929 int i;
8930
8931 pr_debug("%s: Enter\n", __func__);
8932
8933 if (!v) {
8934 pr_err("%s: v is NULL\n", __func__);
8935 return -EINVAL;
8936 }
8937 apr_cvp = common.apr_q6_cvp;
8938
8939 if (!apr_cvp) {
8940 pr_err("%s: apr_cvp is NULL.\n", __func__);
8941 return -EINVAL;
8942 }
8943
8944 cvp_handle = voice_get_cvp_handle(v);
8945
8946 if (!is_source_tracking_shared_memomry_allocated()) {
8947 ret = voice_alloc_and_map_source_tracking_shared_memory(v);
8948 if (ret) {
8949 pr_err("%s: Fail in allocating/mapping shared memory\n",
8950 __func__);
8951
8952 ret = -EINVAL;
8953 goto done;
8954 }
8955 }
8956 st_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
8957 APR_HDR_LEN(APR_HDR_SIZE),
8958 APR_PKT_VER);
8959 st_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
8960 sizeof(st_cmd) - APR_HDR_SIZE);
8961 st_cmd.hdr.src_port = voice_get_idx_for_session(v->session_id);
8962 st_cmd.hdr.dest_port = cvp_handle;
8963 st_cmd.hdr.token = 0;
8964 st_cmd.hdr.opcode = VSS_ISOURCETRACK_CMD_GET_ACTIVITY;
8965
8966 st_cmd.cvp_get_source_tracking_param.mem_handle =
8967 common.source_tracking_sh_mem.mem_handle;
8968 st_cmd.cvp_get_source_tracking_param.mem_address_lsw =
8969 lower_32_bits(common.source_tracking_sh_mem.sh_mem_block.phys);
8970 st_cmd.cvp_get_source_tracking_param.mem_address_msw =
8971 msm_audio_populate_upper_32_bits(common.source_tracking_sh_mem.
8972 sh_mem_block.phys);
8973 st_cmd.cvp_get_source_tracking_param.mem_size =
8974 (uint32_t)common.source_tracking_sh_mem.sh_mem_block.size;
8975 pr_debug("%s: mem_handle=0x%x, mem_address_lsw=0x%x, msw=0x%x, mem_size=%d\n",
8976 __func__,
8977 st_cmd.cvp_get_source_tracking_param.mem_handle,
8978 st_cmd.cvp_get_source_tracking_param.mem_address_lsw,
8979 st_cmd.cvp_get_source_tracking_param.mem_address_msw,
8980 (uint32_t)st_cmd.cvp_get_source_tracking_param.mem_size);
8981
8982 v->cvp_state = CMD_STATUS_FAIL;
8983 v->async_err = 0;
8984 ret = apr_send_pkt(apr_cvp,
8985 (uint32_t *) &st_cmd);
8986 if (ret < 0) {
8987 pr_err("%s: Error in sending APR command\n", __func__);
8988
8989 ret = -EINVAL;
8990 goto done;
8991 }
8992 ret = wait_event_timeout(v->cvp_wait,
8993 (v->cvp_state == CMD_STATUS_SUCCESS),
8994 msecs_to_jiffies(TIMEOUT_MS));
8995 if (!ret) {
8996 pr_err("%s: wait_event timeout\n", __func__);
8997
8998 ret = -EINVAL;
8999 goto done;
9000 }
9001
9002 if (v->async_err > 0) {
9003 pr_err("%s: DSP returned error[%s]\n",
9004 __func__, adsp_err_get_err_str(
9005 v->async_err));
9006 ret = adsp_err_get_lnx_err_code(
9007 v->async_err);
9008 goto done;
9009 }
9010
9011 if (common.is_source_tracking_resp_success) {
9012 for (i = 0; i < MAX_SECTORS; i++) {
9013 sourceTrackingData->vad[i] =
9014 common.sourceTrackingResponse.voice_active[i];
9015 pr_debug("%s: vad[%d] = %d\n",
9016 __func__, i, sourceTrackingData->vad[i]);
9017 }
9018 sourceTrackingData->doa_speech =
9019 common.sourceTrackingResponse.talker_doa;
9020 pr_debug("%s: doa_speech = %d\n",
9021 __func__, sourceTrackingData->doa_speech);
9022
9023 for (i = 0; i < MAX_NOISE_SOURCE_INDICATORS; i++) {
9024 sourceTrackingData->doa_noise[i] =
9025 common.sourceTrackingResponse.interferer_doa[i];
9026 pr_debug("%s: doa_noise[%d] = %d\n",
9027 __func__, i, sourceTrackingData->doa_noise[i]);
9028 }
9029 for (i = 0; i < MAX_POLAR_ACTIVITY_INDICATORS; i++) {
9030 sourceTrackingData->polar_activity[i] =
9031 common.sourceTrackingResponse.sound_strength[i];
9032 pr_debug("%s: polar_activity[%d] = %d\n",
9033 __func__, i, sourceTrackingData->polar_activity[i]);
9034 }
9035 common.is_source_tracking_resp_success = false;
9036 ret = 0;
9037 } else {
9038 pr_err("%s: Error response received from CVD\n", __func__);
9039
9040 ret = -EINVAL;
9041 }
9042done:
9043 pr_debug("%s: Exit, ret=%d\n", __func__, ret);
9044
9045 return ret;
9046}
9047
9048int voc_get_source_tracking(struct source_tracking_param *sourceTrackingData)
9049{
9050 struct voice_data *v = NULL;
9051 int ret = -EINVAL;
9052 struct voice_session_itr itr;
9053
9054 pr_debug("%s: Enter\n", __func__);
9055
9056 mutex_lock(&common.common_lock);
9057
9058 voice_itr_init(&itr, ALL_SESSION_VSID);
9059 while (voice_itr_get_next_session(&itr, &v)) {
9060 if (v != NULL) {
9061 mutex_lock(&v->lock);
9062 if (is_voc_state_active(v->voc_state) &&
9063 (v->lch_mode != VOICE_LCH_START) &&
9064 !v->disable_topology)
9065 ret = voice_send_get_source_tracking_cmd(v,
9066 sourceTrackingData);
9067 mutex_unlock(&v->lock);
9068 } else {
9069 pr_err("%s: invalid session\n", __func__);
9070
9071 break;
9072 }
9073 }
9074
9075 mutex_unlock(&common.common_lock);
9076 pr_debug("%s: Exit, ret=%d\n", __func__, ret);
9077
9078 return ret;
9079}
9080
9081int is_voc_initialized(void)
9082{
9083 return module_initialized;
9084}
9085
9086static int __init voice_init(void)
9087{
9088 int rc = 0, i = 0;
9089
9090 memset(&common, 0, sizeof(struct common_data));
9091
9092 /* set default value */
9093 common.default_mute_val = 0; /* default is un-mute */
9094 common.default_sample_val = 8000;
9095 common.default_vol_step_val = 0;
9096 common.default_vol_ramp_duration_ms = DEFAULT_VOLUME_RAMP_DURATION;
9097 common.default_mute_ramp_duration_ms = DEFAULT_MUTE_RAMP_DURATION;
Laxminath Kasam38070be2017-08-17 18:21:59 +05309098 common.cvp_version = 0;
9099 common.is_avcs_version_queried = false;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309100 /* Initialize EC Ref media format info */
9101 common.ec_ref_ext = false;
9102 common.ec_media_fmt_info.port_id = AFE_PORT_INVALID;
9103 common.ec_media_fmt_info.num_channels = 0;
9104 common.ec_media_fmt_info.bits_per_sample = 16;
9105 common.ec_media_fmt_info.sample_rate = 8000;
9106 memset(&common.ec_media_fmt_info.channel_mapping, 0,
9107 VSS_CHANNEL_MAPPING_SIZE);
9108
9109 /* Initialize AFE Sidetone Enable */
9110 common.sidetone_enable = false;
9111
9112 /* Initialize MVS info. */
9113 common.mvs_info.network_type = VSS_NETWORK_ID_DEFAULT;
9114
9115 /* Initialize is low memory flag */
9116 common.is_destroy_cvd = false;
9117
9118 /* Initialize CVD version */
9119 strlcpy(common.cvd_version, CVD_VERSION_DEFAULT,
9120 sizeof(common.cvd_version));
9121 /* Initialize Per-Vocoder Calibration flag */
9122 common.is_per_vocoder_cal_enabled = false;
9123
9124 mutex_init(&common.common_lock);
9125
9126 /* Initialize session id with vsid */
9127 init_session_id();
9128
9129 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
9130
9131 /* initialize dev_rx and dev_tx */
9132 common.voice[i].dev_rx.dev_mute = common.default_mute_val;
9133 common.voice[i].dev_tx.dev_mute = common.default_mute_val;
9134 common.voice[i].dev_rx.volume_step_value =
9135 common.default_vol_step_val;
9136 common.voice[i].dev_rx.volume_ramp_duration_ms =
9137 common.default_vol_ramp_duration_ms;
9138 common.voice[i].dev_rx.dev_mute_ramp_duration_ms =
9139 common.default_mute_ramp_duration_ms;
9140 common.voice[i].dev_tx.dev_mute_ramp_duration_ms =
9141 common.default_mute_ramp_duration_ms;
9142 common.voice[i].stream_rx.stream_mute = common.default_mute_val;
9143 common.voice[i].stream_tx.stream_mute = common.default_mute_val;
9144
9145 common.voice[i].dev_tx.port_id = 0x100B;
9146 common.voice[i].dev_rx.port_id = 0x100A;
9147 common.voice[i].dev_tx.dev_id = 0;
9148 common.voice[i].dev_rx.dev_id = 0;
9149 common.voice[i].dev_tx.no_of_channels = 0;
9150 common.voice[i].dev_rx.no_of_channels = 0;
9151 common.voice[i].dev_tx.sample_rate = 8000;
9152 common.voice[i].dev_rx.sample_rate = 8000;
9153 common.voice[i].dev_tx.bits_per_sample = 16;
9154 common.voice[i].dev_rx.bits_per_sample = 16;
9155 memset(&common.voice[i].dev_tx.channel_mapping, 0,
9156 VSS_CHANNEL_MAPPING_SIZE);
9157 memset(&common.voice[i].dev_rx.channel_mapping, 0,
9158 VSS_CHANNEL_MAPPING_SIZE);
9159 common.voice[i].sidetone_gain = 0x512;
9160 common.voice[i].dtmf_rx_detect_en = 0;
9161 common.voice[i].lch_mode = 0;
9162 common.voice[i].disable_topology = false;
9163
9164 common.voice[i].voc_state = VOC_INIT;
9165
9166 init_waitqueue_head(&common.voice[i].mvm_wait);
9167 init_waitqueue_head(&common.voice[i].cvs_wait);
9168 init_waitqueue_head(&common.voice[i].cvp_wait);
9169
9170 mutex_init(&common.voice[i].lock);
9171 }
9172
9173 if (voice_init_cal_data())
9174 pr_err("%s: Could not init cal data!\n", __func__);
9175
9176 if (rc == 0)
9177 module_initialized = true;
9178
9179 pr_debug("%s: rc=%d\n", __func__, rc);
9180 return rc;
9181}
9182
9183device_initcall(voice_init);
9184
9185static void __exit voice_exit(void)
9186{
9187 voice_delete_cal_data();
9188 free_cal_map_table();
9189}
9190
9191__exitcall(voice_exit);