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