blob: aff8895b5ed778c7416bf9fd9989bf603be9a2f8 [file] [log] [blame]
Phani Kumar Uppalapati4fbf4c42012-05-21 20:35:45 -07001/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12#include <linux/slab.h>
13#include <linux/kthread.h>
14#include <linux/kernel.h>
15#include <linux/module.h>
16#include <linux/uaccess.h>
17#include <linux/wait.h>
18#include <linux/mutex.h>
19
20#include <asm/mach-types.h>
21#include <mach/qdsp6v2/audio_acdb.h>
22#include <mach/qdsp6v2/rtac.h>
23#include <mach/socinfo.h>
24
25#include "sound/apr_audio-v2.h"
26#include "sound/q6afe-v2.h"
27
28#include "q6voice.h"
29
30#define TIMEOUT_MS 200
31
32
33#define CMD_STATUS_SUCCESS 0
34#define CMD_STATUS_FAIL 1
35
36#define VOC_PATH_PASSIVE 0
37#define VOC_PATH_FULL 1
38#define VOC_PATH_VOLTE_PASSIVE 2
39
40/* CVP CAL Size: 245760 = 240 * 1024 */
41#define CVP_CAL_SIZE 245760
42/* CVS CAL Size: 49152 = 48 * 1024 */
43#define CVS_CAL_SIZE 49152
44
45static struct common_data common;
46
47static int voice_send_enable_vocproc_cmd(struct voice_data *v);
48static int voice_send_netid_timing_cmd(struct voice_data *v);
49static int voice_send_attach_vocproc_cmd(struct voice_data *v);
50static int voice_send_set_device_cmd(struct voice_data *v);
51static int voice_send_disable_vocproc_cmd(struct voice_data *v);
52static int voice_send_vol_index_cmd(struct voice_data *v);
53static int voice_send_cvp_map_memory_cmd(struct voice_data *v);
54static int voice_send_cvp_unmap_memory_cmd(struct voice_data *v);
55static int voice_send_cvs_map_memory_cmd(struct voice_data *v);
56static int voice_send_cvs_unmap_memory_cmd(struct voice_data *v);
57static int voice_send_cvs_register_cal_cmd(struct voice_data *v);
58static int voice_send_cvs_deregister_cal_cmd(struct voice_data *v);
59static int voice_send_cvp_register_cal_cmd(struct voice_data *v);
60static int voice_send_cvp_deregister_cal_cmd(struct voice_data *v);
61static int voice_send_cvp_register_vol_cal_table_cmd(struct voice_data *v);
62static int voice_send_cvp_deregister_vol_cal_table_cmd(struct voice_data *v);
63static int voice_send_set_widevoice_enable_cmd(struct voice_data *v);
64static int voice_send_set_pp_enable_cmd(struct voice_data *v,
65 uint32_t module_id, int enable);
66static int voice_cvs_stop_playback(struct voice_data *v);
67static int voice_cvs_start_playback(struct voice_data *v);
68static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode);
69static int voice_cvs_stop_record(struct voice_data *v);
70
71static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv);
72static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv);
73static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv);
74
75static u16 voice_get_mvm_handle(struct voice_data *v)
76{
77 if (v == NULL) {
78 pr_err("%s: v is NULL\n", __func__);
79 return 0;
80 }
81
82 pr_debug("%s: mvm_handle %d\n", __func__, v->mvm_handle);
83
84 return v->mvm_handle;
85}
86
87static void voice_set_mvm_handle(struct voice_data *v, u16 mvm_handle)
88{
89 pr_debug("%s: mvm_handle %d\n", __func__, mvm_handle);
90 if (v == NULL) {
91 pr_err("%s: v is NULL\n", __func__);
92 return;
93 }
94
95 v->mvm_handle = mvm_handle;
96}
97
98static u16 voice_get_cvs_handle(struct voice_data *v)
99{
100 if (v == NULL) {
101 pr_err("%s: v is NULL\n", __func__);
102 return 0;
103 }
104
105 pr_debug("%s: cvs_handle %d\n", __func__, v->cvs_handle);
106
107 return v->cvs_handle;
108}
109
110static void voice_set_cvs_handle(struct voice_data *v, u16 cvs_handle)
111{
112 pr_debug("%s: cvs_handle %d\n", __func__, cvs_handle);
113 if (v == NULL) {
114 pr_err("%s: v is NULL\n", __func__);
115 return;
116 }
117
118 v->cvs_handle = cvs_handle;
119}
120
121static u16 voice_get_cvp_handle(struct voice_data *v)
122{
123 if (v == NULL) {
124 pr_err("%s: v is NULL\n", __func__);
125 return 0;
126 }
127
128 pr_debug("%s: cvp_handle %d\n", __func__, v->cvp_handle);
129
130 return v->cvp_handle;
131}
132
133static void voice_set_cvp_handle(struct voice_data *v, u16 cvp_handle)
134{
135 pr_debug("%s: cvp_handle %d\n", __func__, cvp_handle);
136 if (v == NULL) {
137 pr_err("%s: v is NULL\n", __func__);
138 return;
139 }
140
141 v->cvp_handle = cvp_handle;
142}
143
144uint16_t voc_get_session_id(char *name)
145{
146 u16 session_id = 0;
147
148 if (name != NULL) {
149 if (!strncmp(name, "Voice session", 13))
150 session_id = common.voice[VOC_PATH_PASSIVE].session_id;
151 else if (!strncmp(name, "VoLTE session", 13))
152 session_id =
153 common.voice[VOC_PATH_VOLTE_PASSIVE].session_id;
154 else
155 session_id = common.voice[VOC_PATH_FULL].session_id;
156
157 pr_debug("%s: %s has session id 0x%x\n", __func__, name,
158 session_id);
159 }
160
161 return session_id;
162}
163
164static struct voice_data *voice_get_session(u16 session_id)
165{
166 struct voice_data *v = NULL;
167
168 if ((session_id >= SESSION_ID_BASE) &&
169 (session_id < SESSION_ID_BASE + MAX_VOC_SESSIONS)) {
170 v = &common.voice[session_id - SESSION_ID_BASE];
171 }
172
173 pr_debug("%s: session_id 0x%x session handle 0x%x\n",
174 __func__, session_id, (unsigned int)v);
175
176 return v;
177}
178
179static bool is_voice_session(u16 session_id)
180{
181 return (session_id == common.voice[VOC_PATH_PASSIVE].session_id);
182}
183
184static bool is_voip_session(u16 session_id)
185{
186 return (session_id == common.voice[VOC_PATH_FULL].session_id);
187}
188
189static bool is_volte_session(u16 session_id)
190{
191 return (session_id == common.voice[VOC_PATH_VOLTE_PASSIVE].session_id);
192}
193
194static int voice_apr_register(void)
195{
196 pr_debug("%s\n", __func__);
197
198 mutex_lock(&common.common_lock);
199
200 /* register callback to APR */
201 if (common.apr_q6_mvm == NULL) {
202 pr_debug("%s: Start to register MVM callback\n", __func__);
203
204 common.apr_q6_mvm = apr_register("ADSP", "MVM",
205 qdsp_mvm_callback,
206 0xFFFFFFFF, &common);
207
208 if (common.apr_q6_mvm == NULL) {
209 pr_err("%s: Unable to register MVM\n", __func__);
210 goto err;
211 }
212 }
213
214 if (common.apr_q6_cvs == NULL) {
215 pr_debug("%s: Start to register CVS callback\n", __func__);
216
217 common.apr_q6_cvs = apr_register("ADSP", "CVS",
218 qdsp_cvs_callback,
219 0xFFFFFFFF, &common);
220
221 if (common.apr_q6_cvs == NULL) {
222 pr_err("%s: Unable to register CVS\n", __func__);
223 goto err;
224 }
225
226 rtac_set_voice_handle(RTAC_CVS, common.apr_q6_cvs);
227 }
228
229 if (common.apr_q6_cvp == NULL) {
230 pr_debug("%s: Start to register CVP callback\n", __func__);
231
232 common.apr_q6_cvp = apr_register("ADSP", "CVP",
233 qdsp_cvp_callback,
234 0xFFFFFFFF, &common);
235
236 if (common.apr_q6_cvp == NULL) {
237 pr_err("%s: Unable to register CVP\n", __func__);
238 goto err;
239 }
240
241 rtac_set_voice_handle(RTAC_CVP, common.apr_q6_cvp);
242 }
243
244 mutex_unlock(&common.common_lock);
245
246 return 0;
247
248err:
249 if (common.apr_q6_cvs != NULL) {
250 apr_deregister(common.apr_q6_cvs);
251 common.apr_q6_cvs = NULL;
252 rtac_set_voice_handle(RTAC_CVS, NULL);
253 }
254 if (common.apr_q6_mvm != NULL) {
255 apr_deregister(common.apr_q6_mvm);
256 common.apr_q6_mvm = NULL;
257 }
258
259 mutex_unlock(&common.common_lock);
260
261 return -ENODEV;
262}
263
264static int voice_send_dual_control_cmd(struct voice_data *v)
265{
266 int ret = 0;
267 struct mvm_modem_dual_control_session_cmd mvm_voice_ctl_cmd;
268 void *apr_mvm;
269 u16 mvm_handle;
270
271 if (v == NULL) {
272 pr_err("%s: v is NULL\n", __func__);
273 return -EINVAL;
274 }
275 apr_mvm = common.apr_q6_mvm;
276 if (!apr_mvm) {
277 pr_err("%s: apr_mvm is NULL.\n", __func__);
278 return -EINVAL;
279 }
280 pr_debug("%s: VoLTE command to MVM\n", __func__);
281 if (is_volte_session(v->session_id)) {
282 mvm_handle = voice_get_mvm_handle(v);
283 mvm_voice_ctl_cmd.hdr.hdr_field = APR_HDR_FIELD(
284 APR_MSG_TYPE_SEQ_CMD,
285 APR_HDR_LEN(APR_HDR_SIZE),
286 APR_PKT_VER);
287 mvm_voice_ctl_cmd.hdr.pkt_size = APR_PKT_SIZE(
288 APR_HDR_SIZE,
289 sizeof(mvm_voice_ctl_cmd) -
290 APR_HDR_SIZE);
291 pr_debug("%s: send mvm Voice Ctl pkt size = %d\n",
292 __func__, mvm_voice_ctl_cmd.hdr.pkt_size);
293 mvm_voice_ctl_cmd.hdr.src_port = v->session_id;
294 mvm_voice_ctl_cmd.hdr.dest_port = mvm_handle;
295 mvm_voice_ctl_cmd.hdr.token = 0;
296 mvm_voice_ctl_cmd.hdr.opcode =
297 VSS_IMVM_CMD_SET_POLICY_DUAL_CONTROL;
298 mvm_voice_ctl_cmd.voice_ctl.enable_flag = true;
299 v->mvm_state = CMD_STATUS_FAIL;
300
301 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_voice_ctl_cmd);
302 if (ret < 0) {
303 pr_err("%s: Error sending MVM Voice CTL CMD\n",
304 __func__);
305 ret = -EINVAL;
306 goto fail;
307 }
308 ret = wait_event_timeout(v->mvm_wait,
309 (v->mvm_state == CMD_STATUS_SUCCESS),
310 msecs_to_jiffies(TIMEOUT_MS));
311 if (!ret) {
312 pr_err("%s: wait_event timeout\n", __func__);
313 ret = -EINVAL;
314 goto fail;
315 }
316 }
317 ret = 0;
318fail:
319 return ret;
320}
321
322
323static int voice_create_mvm_cvs_session(struct voice_data *v)
324{
325 int ret = 0;
326 struct mvm_create_ctl_session_cmd mvm_session_cmd;
327 struct cvs_create_passive_ctl_session_cmd cvs_session_cmd;
328 struct cvs_create_full_ctl_session_cmd cvs_full_ctl_cmd;
329 struct mvm_attach_stream_cmd attach_stream_cmd;
330 void *apr_mvm, *apr_cvs, *apr_cvp;
331 u16 mvm_handle, cvs_handle, cvp_handle;
332
333 if (v == NULL) {
334 pr_err("%s: v is NULL\n", __func__);
335 return -EINVAL;
336 }
337 apr_mvm = common.apr_q6_mvm;
338 apr_cvs = common.apr_q6_cvs;
339 apr_cvp = common.apr_q6_cvp;
340
341 if (!apr_mvm || !apr_cvs || !apr_cvp) {
342 pr_err("%s: apr_mvm or apr_cvs or apr_cvp is NULL\n", __func__);
343 return -EINVAL;
344 }
345 mvm_handle = voice_get_mvm_handle(v);
346 cvs_handle = voice_get_cvs_handle(v);
347 cvp_handle = voice_get_cvp_handle(v);
348
349 pr_debug("%s: mvm_hdl=%d, cvs_hdl=%d\n", __func__,
350 mvm_handle, cvs_handle);
351 /* send cmd to create mvm session and wait for response */
352
353 if (!mvm_handle) {
354 if (is_voice_session(v->session_id) ||
355 is_volte_session(v->session_id)) {
356 mvm_session_cmd.hdr.hdr_field = APR_HDR_FIELD(
357 APR_MSG_TYPE_SEQ_CMD,
358 APR_HDR_LEN(APR_HDR_SIZE),
359 APR_PKT_VER);
360 mvm_session_cmd.hdr.pkt_size = APR_PKT_SIZE(
361 APR_HDR_SIZE,
362 sizeof(mvm_session_cmd) -
363 APR_HDR_SIZE);
364 pr_debug("%s: send mvm create session pkt size = %d\n",
365 __func__, mvm_session_cmd.hdr.pkt_size);
366 mvm_session_cmd.hdr.src_port = v->session_id;
367 mvm_session_cmd.hdr.dest_port = 0;
368 mvm_session_cmd.hdr.token = 0;
369 mvm_session_cmd.hdr.opcode =
370 VSS_IMVM_CMD_CREATE_PASSIVE_CONTROL_SESSION;
371 if (is_volte_session(v->session_id)) {
372 strlcpy(mvm_session_cmd.mvm_session.name,
373 "default volte voice",
374 sizeof(mvm_session_cmd.mvm_session.name));
375 } else {
376 strlcpy(mvm_session_cmd.mvm_session.name,
377 "default modem voice",
378 sizeof(mvm_session_cmd.mvm_session.name));
379 }
380
381 v->mvm_state = CMD_STATUS_FAIL;
382
383 ret = apr_send_pkt(apr_mvm,
384 (uint32_t *) &mvm_session_cmd);
385 if (ret < 0) {
386 pr_err("%s: Error sending MVM_CONTROL_SESSION\n",
387 __func__);
388 goto fail;
389 }
390 ret = wait_event_timeout(v->mvm_wait,
391 (v->mvm_state == CMD_STATUS_SUCCESS),
392 msecs_to_jiffies(TIMEOUT_MS));
393 if (!ret) {
394 pr_err("%s: wait_event timeout\n", __func__);
395 goto fail;
396 }
397 } else {
398 pr_debug("%s: creating MVM full ctrl\n", __func__);
399 mvm_session_cmd.hdr.hdr_field =
400 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
401 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
402 mvm_session_cmd.hdr.pkt_size =
403 APR_PKT_SIZE(APR_HDR_SIZE,
404 sizeof(mvm_session_cmd) -
405 APR_HDR_SIZE);
406 mvm_session_cmd.hdr.src_port = v->session_id;
407 mvm_session_cmd.hdr.dest_port = 0;
408 mvm_session_cmd.hdr.token = 0;
409 mvm_session_cmd.hdr.opcode =
410 VSS_IMVM_CMD_CREATE_FULL_CONTROL_SESSION;
411 strlcpy(mvm_session_cmd.mvm_session.name,
412 "default voip",
413 sizeof(mvm_session_cmd.mvm_session.name));
414
415 v->mvm_state = CMD_STATUS_FAIL;
416
417 ret = apr_send_pkt(apr_mvm,
418 (uint32_t *) &mvm_session_cmd);
419 if (ret < 0) {
420 pr_err("Fail in sending MVM_CONTROL_SESSION\n");
421 goto fail;
422 }
423 ret = wait_event_timeout(v->mvm_wait,
424 (v->mvm_state == CMD_STATUS_SUCCESS),
425 msecs_to_jiffies(TIMEOUT_MS));
426 if (!ret) {
427 pr_err("%s: wait_event timeout\n", __func__);
428 goto fail;
429 }
430 }
431 /* Get the created MVM handle. */
432 mvm_handle = voice_get_mvm_handle(v);
433 }
434 /* send cmd to create cvs session */
435 if (!cvs_handle) {
436 if (is_voice_session(v->session_id) ||
437 is_volte_session(v->session_id)) {
438 pr_debug("%s: creating CVS passive session\n",
439 __func__);
440
441 cvs_session_cmd.hdr.hdr_field = APR_HDR_FIELD(
442 APR_MSG_TYPE_SEQ_CMD,
443 APR_HDR_LEN(APR_HDR_SIZE),
444 APR_PKT_VER);
445 cvs_session_cmd.hdr.pkt_size =
446 APR_PKT_SIZE(APR_HDR_SIZE,
447 sizeof(cvs_session_cmd) -
448 APR_HDR_SIZE);
449 cvs_session_cmd.hdr.src_port = v->session_id;
450 cvs_session_cmd.hdr.dest_port = 0;
451 cvs_session_cmd.hdr.token = 0;
452 cvs_session_cmd.hdr.opcode =
453 VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION;
454 if (is_volte_session(v->session_id)) {
455 strlcpy(mvm_session_cmd.mvm_session.name,
456 "default volte voice",
457 sizeof(mvm_session_cmd.mvm_session.name));
458 } else {
459 strlcpy(cvs_session_cmd.cvs_session.name,
460 "default modem voice",
461 sizeof(cvs_session_cmd.cvs_session.name));
462 }
463 v->cvs_state = CMD_STATUS_FAIL;
464
465 ret = apr_send_pkt(apr_cvs,
466 (uint32_t *) &cvs_session_cmd);
467 if (ret < 0) {
468 pr_err("Fail in sending STREAM_CONTROL_SESSION\n");
469 goto fail;
470 }
471 ret = wait_event_timeout(v->cvs_wait,
472 (v->cvs_state == CMD_STATUS_SUCCESS),
473 msecs_to_jiffies(TIMEOUT_MS));
474 if (!ret) {
475 pr_err("%s: wait_event timeout\n", __func__);
476 goto fail;
477 }
478 /* Get the created CVS handle. */
479 cvs_handle = voice_get_cvs_handle(v);
480
481 } else {
482 pr_debug("%s: creating CVS full session\n", __func__);
483
484 cvs_full_ctl_cmd.hdr.hdr_field =
485 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
486 APR_HDR_LEN(APR_HDR_SIZE),
487 APR_PKT_VER);
488
489 cvs_full_ctl_cmd.hdr.pkt_size =
490 APR_PKT_SIZE(APR_HDR_SIZE,
491 sizeof(cvs_full_ctl_cmd) -
492 APR_HDR_SIZE);
493
494 cvs_full_ctl_cmd.hdr.src_port = v->session_id;
495 cvs_full_ctl_cmd.hdr.dest_port = 0;
496 cvs_full_ctl_cmd.hdr.token = 0;
497 cvs_full_ctl_cmd.hdr.opcode =
498 VSS_ISTREAM_CMD_CREATE_FULL_CONTROL_SESSION;
499 cvs_full_ctl_cmd.cvs_session.direction = 2;
500 cvs_full_ctl_cmd.cvs_session.enc_media_type =
501 common.mvs_info.media_type;
502 cvs_full_ctl_cmd.cvs_session.dec_media_type =
503 common.mvs_info.media_type;
504 cvs_full_ctl_cmd.cvs_session.network_id =
505 common.mvs_info.network_type;
506 strlcpy(cvs_full_ctl_cmd.cvs_session.name,
507 "default q6 voice",
508 sizeof(cvs_full_ctl_cmd.cvs_session.name));
509
510 v->cvs_state = CMD_STATUS_FAIL;
511
512 ret = apr_send_pkt(apr_cvs,
513 (uint32_t *) &cvs_full_ctl_cmd);
514
515 if (ret < 0) {
516 pr_err("%s: Err %d sending CREATE_FULL_CTRL\n",
517 __func__, ret);
518 goto fail;
519 }
520 ret = wait_event_timeout(v->cvs_wait,
521 (v->cvs_state == CMD_STATUS_SUCCESS),
522 msecs_to_jiffies(TIMEOUT_MS));
523 if (!ret) {
524 pr_err("%s: wait_event timeout\n", __func__);
525 goto fail;
526 }
527 /* Get the created CVS handle. */
528 cvs_handle = voice_get_cvs_handle(v);
529
530 /* Attach MVM to CVS. */
531 pr_debug("%s: Attach MVM to stream\n", __func__);
532
533 attach_stream_cmd.hdr.hdr_field =
534 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
535 APR_HDR_LEN(APR_HDR_SIZE),
536 APR_PKT_VER);
537 attach_stream_cmd.hdr.pkt_size =
538 APR_PKT_SIZE(APR_HDR_SIZE,
539 sizeof(attach_stream_cmd) -
540 APR_HDR_SIZE);
541 attach_stream_cmd.hdr.src_port = v->session_id;
542 attach_stream_cmd.hdr.dest_port = mvm_handle;
543 attach_stream_cmd.hdr.token = 0;
544 attach_stream_cmd.hdr.opcode =
545 VSS_IMVM_CMD_ATTACH_STREAM;
546 attach_stream_cmd.attach_stream.handle = cvs_handle;
547
548 v->mvm_state = CMD_STATUS_FAIL;
549 ret = apr_send_pkt(apr_mvm,
550 (uint32_t *) &attach_stream_cmd);
551 if (ret < 0) {
552 pr_err("%s: Error %d sending ATTACH_STREAM\n",
553 __func__, ret);
554 goto fail;
555 }
556 ret = wait_event_timeout(v->mvm_wait,
557 (v->mvm_state == CMD_STATUS_SUCCESS),
558 msecs_to_jiffies(TIMEOUT_MS));
559 if (!ret) {
560 pr_err("%s: wait_event timeout\n", __func__);
561 goto fail;
562 }
563 }
564 }
565 return 0;
566
567fail:
568 return -EINVAL;
569}
570
571static int voice_destroy_mvm_cvs_session(struct voice_data *v)
572{
573 int ret = 0;
574 struct mvm_detach_stream_cmd detach_stream;
575 struct apr_hdr mvm_destroy;
576 struct apr_hdr cvs_destroy;
577 void *apr_mvm, *apr_cvs;
578 u16 mvm_handle, cvs_handle;
579
580 if (v == NULL) {
581 pr_err("%s: v is NULL\n", __func__);
582 return -EINVAL;
583 }
584 apr_mvm = common.apr_q6_mvm;
585 apr_cvs = common.apr_q6_cvs;
586
587 if (!apr_mvm || !apr_cvs) {
588 pr_err("%s: apr_mvm or apr_cvs is NULL\n", __func__);
589 return -EINVAL;
590 }
591 mvm_handle = voice_get_mvm_handle(v);
592 cvs_handle = voice_get_cvs_handle(v);
593
594 /* MVM, CVS sessions are destroyed only for Full control sessions. */
595 if (is_voip_session(v->session_id)) {
596 pr_debug("%s: MVM detach stream\n", __func__);
597
598 /* Detach voice stream. */
599 detach_stream.hdr.hdr_field =
600 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
601 APR_HDR_LEN(APR_HDR_SIZE),
602 APR_PKT_VER);
603 detach_stream.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
604 sizeof(detach_stream) - APR_HDR_SIZE);
605 detach_stream.hdr.src_port = v->session_id;
606 detach_stream.hdr.dest_port = mvm_handle;
607 detach_stream.hdr.token = 0;
608 detach_stream.hdr.opcode = VSS_IMVM_CMD_DETACH_STREAM;
609 detach_stream.detach_stream.handle = cvs_handle;
610
611 v->mvm_state = CMD_STATUS_FAIL;
612
613 ret = apr_send_pkt(apr_mvm, (uint32_t *) &detach_stream);
614 if (ret < 0) {
615 pr_err("%s: Error %d sending DETACH_STREAM\n",
616 __func__, ret);
617 goto fail;
618 }
619 ret = wait_event_timeout(v->mvm_wait,
620 (v->mvm_state == CMD_STATUS_SUCCESS),
621 msecs_to_jiffies(TIMEOUT_MS));
622 if (!ret) {
623 pr_err("%s: wait event timeout\n", __func__);
624 goto fail;
625 }
626 /* Destroy CVS. */
627 pr_debug("%s: CVS destroy session\n", __func__);
628
629 cvs_destroy.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
630 APR_HDR_LEN(APR_HDR_SIZE),
631 APR_PKT_VER);
632 cvs_destroy.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
633 sizeof(cvs_destroy) - APR_HDR_SIZE);
634 cvs_destroy.src_port = v->session_id;
635 cvs_destroy.dest_port = cvs_handle;
636 cvs_destroy.token = 0;
637 cvs_destroy.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
638
639 v->cvs_state = CMD_STATUS_FAIL;
640
641 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_destroy);
642 if (ret < 0) {
643 pr_err("%s: Error %d sending CVS DESTROY\n",
644 __func__, ret);
645 goto fail;
646 }
647 ret = wait_event_timeout(v->cvs_wait,
648 (v->cvs_state == CMD_STATUS_SUCCESS),
649 msecs_to_jiffies(TIMEOUT_MS));
650 if (!ret) {
651 pr_err("%s: wait event timeout\n", __func__);
652
653 goto fail;
654 }
655 cvs_handle = 0;
656 voice_set_cvs_handle(v, cvs_handle);
657
658 /* Destroy MVM. */
659 pr_debug("MVM destroy session\n");
660
661 mvm_destroy.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
662 APR_HDR_LEN(APR_HDR_SIZE),
663 APR_PKT_VER);
664 mvm_destroy.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
665 sizeof(mvm_destroy) - APR_HDR_SIZE);
666 mvm_destroy.src_port = v->session_id;
667 mvm_destroy.dest_port = mvm_handle;
668 mvm_destroy.token = 0;
669 mvm_destroy.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
670
671 v->mvm_state = CMD_STATUS_FAIL;
672
673 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_destroy);
674 if (ret < 0) {
675 pr_err("%s: Error %d sending MVM DESTROY\n",
676 __func__, ret);
677
678 goto fail;
679 }
680 ret = wait_event_timeout(v->mvm_wait,
681 (v->mvm_state == CMD_STATUS_SUCCESS),
682 msecs_to_jiffies(TIMEOUT_MS));
683 if (!ret) {
684 pr_err("%s: wait event timeout\n", __func__);
685
686 goto fail;
687 }
688 mvm_handle = 0;
689 voice_set_mvm_handle(v, mvm_handle);
690 }
691 return 0;
692fail:
693 return -EINVAL;
694}
695
696static int voice_send_tty_mode_cmd(struct voice_data *v)
697{
698 int ret = 0;
699 struct mvm_set_tty_mode_cmd mvm_tty_mode_cmd;
700 void *apr_mvm;
701 u16 mvm_handle;
702
703 if (v == NULL) {
704 pr_err("%s: v is NULL\n", __func__);
705 return -EINVAL;
706 }
707 apr_mvm = common.apr_q6_mvm;
708
709 if (!apr_mvm) {
710 pr_err("%s: apr_mvm is NULL.\n", __func__);
711 return -EINVAL;
712 }
713 mvm_handle = voice_get_mvm_handle(v);
714
715 if (v->tty_mode) {
716 /* send tty mode cmd to mvm */
717 mvm_tty_mode_cmd.hdr.hdr_field = APR_HDR_FIELD(
718 APR_MSG_TYPE_SEQ_CMD,
719 APR_HDR_LEN(APR_HDR_SIZE),
720 APR_PKT_VER);
721 mvm_tty_mode_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
722 sizeof(mvm_tty_mode_cmd) -
723 APR_HDR_SIZE);
724 pr_debug("%s: pkt size = %d\n",
725 __func__, mvm_tty_mode_cmd.hdr.pkt_size);
726 mvm_tty_mode_cmd.hdr.src_port = v->session_id;
727 mvm_tty_mode_cmd.hdr.dest_port = mvm_handle;
728 mvm_tty_mode_cmd.hdr.token = 0;
729 mvm_tty_mode_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_TTY_MODE;
730 mvm_tty_mode_cmd.tty_mode.mode = v->tty_mode;
731 pr_debug("tty mode =%d\n", mvm_tty_mode_cmd.tty_mode.mode);
732
733 v->mvm_state = CMD_STATUS_FAIL;
734 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_tty_mode_cmd);
735 if (ret < 0) {
736 pr_err("%s: Error %d sending SET_TTY_MODE\n",
737 __func__, ret);
738 goto fail;
739 }
740 ret = wait_event_timeout(v->mvm_wait,
741 (v->mvm_state == CMD_STATUS_SUCCESS),
742 msecs_to_jiffies(TIMEOUT_MS));
743 if (!ret) {
744 pr_err("%s: wait_event timeout\n", __func__);
745 goto fail;
746 }
747 }
748 return 0;
749fail:
750 return -EINVAL;
751}
752
753static int voice_set_dtx(struct voice_data *v)
754{
755 int ret = 0;
756 void *apr_cvs;
757 u16 cvs_handle;
758 struct cvs_set_enc_dtx_mode_cmd cvs_set_dtx;
759
760 if (v == NULL) {
761 pr_err("%s: v is NULL\n", __func__);
762 return -EINVAL;
763 }
764 apr_cvs = common.apr_q6_cvs;
765
766 if (!apr_cvs) {
767 pr_err("%s: apr_cvs is NULL.\n", __func__);
768 return -EINVAL;
769 }
770
771 cvs_handle = voice_get_cvs_handle(v);
772
773 /* Set DTX */
774 cvs_set_dtx.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
775 APR_HDR_LEN(APR_HDR_SIZE),
776 APR_PKT_VER);
777 cvs_set_dtx.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
778 sizeof(cvs_set_dtx) - APR_HDR_SIZE);
779 cvs_set_dtx.hdr.src_port = v->session_id;
780 cvs_set_dtx.hdr.dest_port = cvs_handle;
781 cvs_set_dtx.hdr.token = 0;
782 cvs_set_dtx.hdr.opcode = VSS_ISTREAM_CMD_SET_ENC_DTX_MODE;
783 cvs_set_dtx.dtx_mode.enable = common.mvs_info.dtx_mode;
784
785 pr_debug("%s: Setting DTX %d\n", __func__, common.mvs_info.dtx_mode);
786
787 v->cvs_state = CMD_STATUS_FAIL;
788
789 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_dtx);
790 if (ret < 0) {
791 pr_err("%s: Error %d sending SET_DTX\n", __func__, ret);
792 return -EINVAL;
793 }
794
795 ret = wait_event_timeout(v->cvs_wait,
796 (v->cvs_state == CMD_STATUS_SUCCESS),
797 msecs_to_jiffies(TIMEOUT_MS));
798 if (!ret) {
799 pr_err("%s: wait_event timeout\n", __func__);
800 return -EINVAL;
801 }
802
803 return 0;
804}
805
806static int voice_config_cvs_vocoder(struct voice_data *v)
807{
808 int ret = 0;
809 void *apr_cvs;
810 u16 cvs_handle;
811 /* Set media type. */
812 struct cvs_set_media_type_cmd cvs_set_media_cmd;
813
814 if (v == NULL) {
815 pr_err("%s: v is NULL\n", __func__);
816 return -EINVAL;
817 }
818 apr_cvs = common.apr_q6_cvs;
819
820 if (!apr_cvs) {
821 pr_err("%s: apr_cvs is NULL.\n", __func__);
822 return -EINVAL;
823 }
824
825 cvs_handle = voice_get_cvs_handle(v);
826
827 cvs_set_media_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
828 APR_HDR_LEN(APR_HDR_SIZE),
829 APR_PKT_VER);
830 cvs_set_media_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
831 sizeof(cvs_set_media_cmd) - APR_HDR_SIZE);
832 cvs_set_media_cmd.hdr.src_port = v->session_id;
833 cvs_set_media_cmd.hdr.dest_port = cvs_handle;
834 cvs_set_media_cmd.hdr.token = 0;
835 cvs_set_media_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_MEDIA_TYPE;
836 cvs_set_media_cmd.media_type.tx_media_id = common.mvs_info.media_type;
837 cvs_set_media_cmd.media_type.rx_media_id = common.mvs_info.media_type;
838
839 v->cvs_state = CMD_STATUS_FAIL;
840
841 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_media_cmd);
842 if (ret < 0) {
843 pr_err("%s: Error %d sending SET_MEDIA_TYPE\n",
844 __func__, ret);
845
846 goto fail;
847 }
848 ret = wait_event_timeout(v->cvs_wait,
849 (v->cvs_state == CMD_STATUS_SUCCESS),
850 msecs_to_jiffies(TIMEOUT_MS));
851 if (!ret) {
852 pr_err("%s: wait_event timeout\n", __func__);
853
854 goto fail;
855 }
856 /* Set encoder properties. */
857 switch (common.mvs_info.media_type) {
858 case VSS_MEDIA_ID_EVRC_MODEM: {
859 struct cvs_set_cdma_enc_minmax_rate_cmd cvs_set_cdma_rate;
860
861 pr_debug("Setting EVRC min-max rate\n");
862
863 cvs_set_cdma_rate.hdr.hdr_field =
864 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
865 APR_HDR_LEN(APR_HDR_SIZE),
866 APR_PKT_VER);
867 cvs_set_cdma_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
868 sizeof(cvs_set_cdma_rate) - APR_HDR_SIZE);
869 cvs_set_cdma_rate.hdr.src_port = v->session_id;
870 cvs_set_cdma_rate.hdr.dest_port = cvs_handle;
871 cvs_set_cdma_rate.hdr.token = 0;
872 cvs_set_cdma_rate.hdr.opcode =
873 VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE;
874 cvs_set_cdma_rate.cdma_rate.min_rate = common.mvs_info.rate;
875 cvs_set_cdma_rate.cdma_rate.max_rate = common.mvs_info.rate;
876
877 v->cvs_state = CMD_STATUS_FAIL;
878
879 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_cdma_rate);
880 if (ret < 0) {
881 pr_err("%s: Error %d sending SET_EVRC_MINMAX_RATE\n",
882 __func__, ret);
883 goto fail;
884 }
885 ret = wait_event_timeout(v->cvs_wait,
886 (v->cvs_state == CMD_STATUS_SUCCESS),
887 msecs_to_jiffies(TIMEOUT_MS));
888 if (!ret) {
889 pr_err("%s: wait_event timeout\n", __func__);
890
891 goto fail;
892 }
893 break;
894 }
895 case VSS_MEDIA_ID_AMR_NB_MODEM: {
896 struct cvs_set_amr_enc_rate_cmd cvs_set_amr_rate;
897
898 pr_debug("Setting AMR rate\n");
899
900 cvs_set_amr_rate.hdr.hdr_field =
901 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
902 APR_HDR_LEN(APR_HDR_SIZE),
903 APR_PKT_VER);
904 cvs_set_amr_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
905 sizeof(cvs_set_amr_rate) - APR_HDR_SIZE);
906 cvs_set_amr_rate.hdr.src_port = v->session_id;
907 cvs_set_amr_rate.hdr.dest_port = cvs_handle;
908 cvs_set_amr_rate.hdr.token = 0;
909 cvs_set_amr_rate.hdr.opcode =
910 VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE;
911 cvs_set_amr_rate.amr_rate.mode = common.mvs_info.rate;
912
913 v->cvs_state = CMD_STATUS_FAIL;
914
915 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_amr_rate);
916 if (ret < 0) {
917 pr_err("%s: Error %d sending SET_AMR_RATE\n",
918 __func__, ret);
919 goto fail;
920 }
921 ret = wait_event_timeout(v->cvs_wait,
922 (v->cvs_state == CMD_STATUS_SUCCESS),
923 msecs_to_jiffies(TIMEOUT_MS));
924 if (!ret) {
925 pr_err("%s: wait_event timeout\n", __func__);
926 goto fail;
927 }
928
929 ret = voice_set_dtx(v);
930 if (ret < 0)
931 goto fail;
932
933 break;
934 }
935 case VSS_MEDIA_ID_AMR_WB_MODEM: {
936 struct cvs_set_amrwb_enc_rate_cmd cvs_set_amrwb_rate;
937
938 pr_debug("Setting AMR WB rate\n");
939
940 cvs_set_amrwb_rate.hdr.hdr_field =
941 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
942 APR_HDR_LEN(APR_HDR_SIZE),
943 APR_PKT_VER);
944 cvs_set_amrwb_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
945 sizeof(cvs_set_amrwb_rate) -
946 APR_HDR_SIZE);
947 cvs_set_amrwb_rate.hdr.src_port = v->session_id;
948 cvs_set_amrwb_rate.hdr.dest_port = cvs_handle;
949 cvs_set_amrwb_rate.hdr.token = 0;
950 cvs_set_amrwb_rate.hdr.opcode =
951 VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE;
952 cvs_set_amrwb_rate.amrwb_rate.mode = common.mvs_info.rate;
953
954 v->cvs_state = CMD_STATUS_FAIL;
955
956 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_amrwb_rate);
957 if (ret < 0) {
958 pr_err("%s: Error %d sending SET_AMRWB_RATE\n",
959 __func__, ret);
960 goto fail;
961 }
962 ret = wait_event_timeout(v->cvs_wait,
963 (v->cvs_state == CMD_STATUS_SUCCESS),
964 msecs_to_jiffies(TIMEOUT_MS));
965 if (!ret) {
966 pr_err("%s: wait_event timeout\n", __func__);
967 goto fail;
968 }
969
970 ret = voice_set_dtx(v);
971 if (ret < 0)
972 goto fail;
973
974 break;
975 }
976 case VSS_MEDIA_ID_G729:
977 case VSS_MEDIA_ID_G711_ALAW:
978 case VSS_MEDIA_ID_G711_MULAW: {
979 ret = voice_set_dtx(v);
980
981 break;
982 }
983 default:
984 /* Do nothing. */
985 break;
986 }
987 return 0;
988
989fail:
990 return -EINVAL;
991}
992
993static int voice_send_start_voice_cmd(struct voice_data *v)
994{
995 struct apr_hdr mvm_start_voice_cmd;
996 int ret = 0;
997 void *apr_mvm;
998 u16 mvm_handle;
999
1000 if (v == NULL) {
1001 pr_err("%s: v is NULL\n", __func__);
1002 return -EINVAL;
1003 }
1004 apr_mvm = common.apr_q6_mvm;
1005
1006 if (!apr_mvm) {
1007 pr_err("%s: apr_mvm is NULL.\n", __func__);
1008 return -EINVAL;
1009 }
1010 mvm_handle = voice_get_mvm_handle(v);
1011
1012 mvm_start_voice_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1013 APR_HDR_LEN(APR_HDR_SIZE),
1014 APR_PKT_VER);
1015 mvm_start_voice_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1016 sizeof(mvm_start_voice_cmd) - APR_HDR_SIZE);
1017 pr_debug("send mvm_start_voice_cmd pkt size = %d\n",
1018 mvm_start_voice_cmd.pkt_size);
1019 mvm_start_voice_cmd.src_port = v->session_id;
1020 mvm_start_voice_cmd.dest_port = mvm_handle;
1021 mvm_start_voice_cmd.token = 0;
1022 mvm_start_voice_cmd.opcode = VSS_IMVM_CMD_START_VOICE;
1023
1024 v->mvm_state = CMD_STATUS_FAIL;
1025 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_start_voice_cmd);
1026 if (ret < 0) {
1027 pr_err("Fail in sending VSS_IMVM_CMD_START_VOICE\n");
1028 goto fail;
1029 }
1030 ret = wait_event_timeout(v->mvm_wait,
1031 (v->mvm_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 return 0;
1038fail:
1039 return -EINVAL;
1040}
1041
1042static int voice_send_disable_vocproc_cmd(struct voice_data *v)
1043{
1044 struct apr_hdr cvp_disable_cmd;
1045 int ret = 0;
1046 void *apr_cvp;
1047 u16 cvp_handle;
1048
1049 if (v == NULL) {
1050 pr_err("%s: v is NULL\n", __func__);
1051 return -EINVAL;
1052 }
1053 apr_cvp = common.apr_q6_cvp;
1054
1055 if (!apr_cvp) {
1056 pr_err("%s: apr regist failed\n", __func__);
1057 return -EINVAL;
1058 }
1059 cvp_handle = voice_get_cvp_handle(v);
1060
1061 /* disable vocproc and wait for respose */
1062 cvp_disable_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1063 APR_HDR_LEN(APR_HDR_SIZE),
1064 APR_PKT_VER);
1065 cvp_disable_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1066 sizeof(cvp_disable_cmd) - APR_HDR_SIZE);
1067 pr_debug("cvp_disable_cmd pkt size = %d, cvp_handle=%d\n",
1068 cvp_disable_cmd.pkt_size, cvp_handle);
1069 cvp_disable_cmd.src_port = v->session_id;
1070 cvp_disable_cmd.dest_port = cvp_handle;
1071 cvp_disable_cmd.token = 0;
1072 cvp_disable_cmd.opcode = VSS_IVOCPROC_CMD_DISABLE;
1073
1074 v->cvp_state = CMD_STATUS_FAIL;
1075 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_disable_cmd);
1076 if (ret < 0) {
1077 pr_err("Fail in sending VSS_IVOCPROC_CMD_DISABLE\n");
1078 goto fail;
1079 }
1080 ret = wait_event_timeout(v->cvp_wait,
1081 (v->cvp_state == CMD_STATUS_SUCCESS),
1082 msecs_to_jiffies(TIMEOUT_MS));
1083 if (!ret) {
1084 pr_err("%s: wait_event timeout\n", __func__);
1085 goto fail;
1086 }
1087
1088 return 0;
1089fail:
1090 return -EINVAL;
1091}
1092
1093static int voice_send_set_device_cmd(struct voice_data *v)
1094{
1095 struct cvp_set_device_cmd cvp_setdev_cmd;
1096 int ret = 0;
1097 void *apr_cvp;
1098 u16 cvp_handle;
1099
1100 if (v == NULL) {
1101 pr_err("%s: v is NULL\n", __func__);
1102 return -EINVAL;
1103 }
1104 apr_cvp = common.apr_q6_cvp;
1105
1106 if (!apr_cvp) {
1107 pr_err("%s: apr_cvp is NULL.\n", __func__);
1108 return -EINVAL;
1109 }
1110 cvp_handle = voice_get_cvp_handle(v);
1111
1112 /* set device and wait for response */
1113 cvp_setdev_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1114 APR_HDR_LEN(APR_HDR_SIZE),
1115 APR_PKT_VER);
1116 cvp_setdev_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1117 sizeof(cvp_setdev_cmd) - APR_HDR_SIZE);
1118 pr_debug(" send create cvp setdev, pkt size = %d\n",
1119 cvp_setdev_cmd.hdr.pkt_size);
1120 cvp_setdev_cmd.hdr.src_port = v->session_id;
1121 cvp_setdev_cmd.hdr.dest_port = cvp_handle;
1122 cvp_setdev_cmd.hdr.token = 0;
1123 cvp_setdev_cmd.hdr.opcode = VSS_IVOCPROC_CMD_SET_DEVICE;
1124
1125 /* Use default topology if invalid value in ACDB */
1126 cvp_setdev_cmd.cvp_set_device.tx_topology_id =
1127 get_voice_tx_topology();
1128 if (cvp_setdev_cmd.cvp_set_device.tx_topology_id == 0)
1129 cvp_setdev_cmd.cvp_set_device.tx_topology_id =
1130 VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
1131
1132 cvp_setdev_cmd.cvp_set_device.rx_topology_id =
1133 get_voice_rx_topology();
1134 if (cvp_setdev_cmd.cvp_set_device.rx_topology_id == 0)
1135 cvp_setdev_cmd.cvp_set_device.rx_topology_id =
1136 VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
1137 cvp_setdev_cmd.cvp_set_device.tx_port_id = v->dev_tx.port_id;
1138 cvp_setdev_cmd.cvp_set_device.rx_port_id = v->dev_rx.port_id;
1139 pr_debug("topology=%d , tx_port_id=%d, rx_port_id=%d\n",
1140 cvp_setdev_cmd.cvp_set_device.tx_topology_id,
1141 cvp_setdev_cmd.cvp_set_device.tx_port_id,
1142 cvp_setdev_cmd.cvp_set_device.rx_port_id);
1143
1144 v->cvp_state = CMD_STATUS_FAIL;
1145 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_setdev_cmd);
1146 if (ret < 0) {
1147 pr_err("Fail in sending VOCPROC_FULL_CONTROL_SESSION\n");
1148 goto fail;
1149 }
1150 pr_debug("wait for cvp create session event\n");
1151 ret = wait_event_timeout(v->cvp_wait,
1152 (v->cvp_state == CMD_STATUS_SUCCESS),
1153 msecs_to_jiffies(TIMEOUT_MS));
1154 if (!ret) {
1155 pr_err("%s: wait_event timeout\n", __func__);
1156 goto fail;
1157 }
1158
1159 return 0;
1160fail:
1161 return -EINVAL;
1162}
1163
1164static int voice_send_stop_voice_cmd(struct voice_data *v)
1165{
1166 struct apr_hdr mvm_stop_voice_cmd;
1167 int ret = 0;
1168 void *apr_mvm;
1169 u16 mvm_handle;
1170
1171 if (v == NULL) {
1172 pr_err("%s: v is NULL\n", __func__);
1173 return -EINVAL;
1174 }
1175 apr_mvm = common.apr_q6_mvm;
1176
1177 if (!apr_mvm) {
1178 pr_err("%s: apr_mvm is NULL.\n", __func__);
1179 return -EINVAL;
1180 }
1181 mvm_handle = voice_get_mvm_handle(v);
1182
1183 mvm_stop_voice_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1184 APR_HDR_LEN(APR_HDR_SIZE),
1185 APR_PKT_VER);
1186 mvm_stop_voice_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1187 sizeof(mvm_stop_voice_cmd) - APR_HDR_SIZE);
1188 pr_debug("send mvm_stop_voice_cmd pkt size = %d\n",
1189 mvm_stop_voice_cmd.pkt_size);
1190 mvm_stop_voice_cmd.src_port = v->session_id;
1191 mvm_stop_voice_cmd.dest_port = mvm_handle;
1192 mvm_stop_voice_cmd.token = 0;
1193 mvm_stop_voice_cmd.opcode = VSS_IMVM_CMD_STOP_VOICE;
1194
1195 v->mvm_state = CMD_STATUS_FAIL;
1196 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_stop_voice_cmd);
1197 if (ret < 0) {
1198 pr_err("Fail in sending VSS_IMVM_CMD_STOP_VOICE\n");
1199 goto fail;
1200 }
1201 ret = wait_event_timeout(v->mvm_wait,
1202 (v->mvm_state == CMD_STATUS_SUCCESS),
1203 msecs_to_jiffies(TIMEOUT_MS));
1204 if (!ret) {
1205 pr_err("%s: wait_event timeout\n", __func__);
1206 goto fail;
1207 }
1208
1209 return 0;
1210fail:
1211 return -EINVAL;
1212}
1213
1214static int voice_send_cvs_register_cal_cmd(struct voice_data *v)
1215{
1216 struct cvs_register_cal_data_cmd cvs_reg_cal_cmd;
1217 struct acdb_cal_block cal_block;
1218 int ret = 0;
1219 void *apr_cvs;
1220 u16 cvs_handle;
1221 uint32_t cal_paddr;
1222
1223 /* get the cvs cal data */
1224 get_all_vocstrm_cal(&cal_block);
1225 if (cal_block.cal_size == 0)
1226 goto fail;
1227
1228 if (v == NULL) {
1229 pr_err("%s: v is NULL\n", __func__);
1230 return -EINVAL;
1231 }
1232 apr_cvs = common.apr_q6_cvs;
1233
1234 if (!apr_cvs) {
1235 pr_err("%s: apr_cvs is NULL.\n", __func__);
1236 return -EINVAL;
1237 }
1238
1239 if (is_voip_session(v->session_id)) {
1240 if (common.cvs_cal.buf) {
1241 cal_paddr = common.cvs_cal.phy;
1242
1243 memcpy(common.cvs_cal.buf,
1244 (void *) cal_block.cal_kvaddr,
1245 cal_block.cal_size);
1246 } else {
1247 return -EINVAL;
1248 }
1249 } else {
1250 cal_paddr = cal_block.cal_paddr;
1251 }
1252
1253 cvs_handle = voice_get_cvs_handle(v);
1254
1255 /* fill in the header */
1256 cvs_reg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1257 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1258 cvs_reg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1259 sizeof(cvs_reg_cal_cmd) - APR_HDR_SIZE);
1260 cvs_reg_cal_cmd.hdr.src_port = v->session_id;
1261 cvs_reg_cal_cmd.hdr.dest_port = cvs_handle;
1262 cvs_reg_cal_cmd.hdr.token = 0;
1263 cvs_reg_cal_cmd.hdr.opcode = VSS_ISTREAM_CMD_REGISTER_CALIBRATION_DATA;
1264
1265 cvs_reg_cal_cmd.cvs_cal_data.phys_addr = cal_paddr;
1266 cvs_reg_cal_cmd.cvs_cal_data.mem_size = cal_block.cal_size;
1267
1268 v->cvs_state = CMD_STATUS_FAIL;
1269 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_reg_cal_cmd);
1270 if (ret < 0) {
1271 pr_err("Fail: sending cvs cal,\n");
1272 goto fail;
1273 }
1274 ret = wait_event_timeout(v->cvs_wait,
1275 (v->cvs_state == CMD_STATUS_SUCCESS),
1276 msecs_to_jiffies(TIMEOUT_MS));
1277 if (!ret) {
1278 pr_err("%s: wait_event timeout\n", __func__);
1279 goto fail;
1280 }
1281 return 0;
1282fail:
1283 return -EINVAL;
1284
1285}
1286
1287static int voice_send_cvs_deregister_cal_cmd(struct voice_data *v)
1288{
1289 struct cvs_deregister_cal_data_cmd cvs_dereg_cal_cmd;
1290 struct acdb_cal_block cal_block;
1291 int ret = 0;
1292 void *apr_cvs;
1293 u16 cvs_handle;
1294
1295 get_all_vocstrm_cal(&cal_block);
1296 if (cal_block.cal_size == 0)
1297 return 0;
1298
1299 if (v == NULL) {
1300 pr_err("%s: v is NULL\n", __func__);
1301 return -EINVAL;
1302 }
1303 apr_cvs = common.apr_q6_cvs;
1304
1305 if (!apr_cvs) {
1306 pr_err("%s: apr_cvs is NULL.\n", __func__);
1307 return -EINVAL;
1308 }
1309 cvs_handle = voice_get_cvs_handle(v);
1310
1311 /* fill in the header */
1312 cvs_dereg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1313 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1314 cvs_dereg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1315 sizeof(cvs_dereg_cal_cmd) - APR_HDR_SIZE);
1316 cvs_dereg_cal_cmd.hdr.src_port = v->session_id;
1317 cvs_dereg_cal_cmd.hdr.dest_port = cvs_handle;
1318 cvs_dereg_cal_cmd.hdr.token = 0;
1319 cvs_dereg_cal_cmd.hdr.opcode =
1320 VSS_ISTREAM_CMD_DEREGISTER_CALIBRATION_DATA;
1321
1322 v->cvs_state = CMD_STATUS_FAIL;
1323 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_dereg_cal_cmd);
1324 if (ret < 0) {
1325 pr_err("Fail: sending cvs cal,\n");
1326 goto fail;
1327 }
1328 ret = wait_event_timeout(v->cvs_wait,
1329 (v->cvs_state == CMD_STATUS_SUCCESS),
1330 msecs_to_jiffies(TIMEOUT_MS));
1331 if (!ret) {
1332 pr_err("%s: wait_event timeout\n", __func__);
1333 goto fail;
1334 }
1335 return 0;
1336fail:
1337 return -EINVAL;
1338
1339}
1340
1341static int voice_send_cvp_map_memory_cmd(struct voice_data *v)
1342{
1343 struct vss_map_memory_cmd cvp_map_mem_cmd;
1344 struct acdb_cal_block cal_block;
1345 int ret = 0;
1346 void *apr_cvp;
1347 u16 cvp_handle;
1348 uint32_t cal_paddr;
1349
1350 /* get all cvp cal data */
1351 get_all_cvp_cal(&cal_block);
1352 if (cal_block.cal_size == 0)
1353 goto fail;
1354
1355 if (v == NULL) {
1356 pr_err("%s: v is NULL\n", __func__);
1357 return -EINVAL;
1358 }
1359 apr_cvp = common.apr_q6_cvp;
1360
1361 if (!apr_cvp) {
1362 pr_err("%s: apr_cvp is NULL.\n", __func__);
1363 return -EINVAL;
1364 }
1365
1366 if (is_voip_session(v->session_id)) {
1367 if (common.cvp_cal.buf)
1368 cal_paddr = common.cvp_cal.phy;
1369 else
1370 return -EINVAL;
1371 } else {
1372 cal_paddr = cal_block.cal_paddr;
1373 }
1374 cvp_handle = voice_get_cvp_handle(v);
1375
1376 /* fill in the header */
1377 cvp_map_mem_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1378 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1379 cvp_map_mem_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1380 sizeof(cvp_map_mem_cmd) - APR_HDR_SIZE);
1381 cvp_map_mem_cmd.hdr.src_port = v->session_id;
1382 cvp_map_mem_cmd.hdr.dest_port = cvp_handle;
1383 cvp_map_mem_cmd.hdr.token = 0;
1384 cvp_map_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_MAP_MEMORY;
1385
1386 pr_debug("%s, phy_addr:0x%x, mem_size:%d\n", __func__,
1387 cal_paddr, cal_block.cal_size);
1388 cvp_map_mem_cmd.vss_map_mem.phys_addr = cal_paddr;
1389 cvp_map_mem_cmd.vss_map_mem.mem_size = cal_block.cal_size;
1390 cvp_map_mem_cmd.vss_map_mem.mem_pool_id =
1391 VSS_ICOMMON_MAP_MEMORY_SHMEM8_4K_POOL;
1392
1393 v->cvp_state = CMD_STATUS_FAIL;
1394 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_map_mem_cmd);
1395 if (ret < 0) {
1396 pr_err("Fail: sending cvp cal,\n");
1397 goto fail;
1398 }
1399 ret = wait_event_timeout(v->cvp_wait,
1400 (v->cvp_state == CMD_STATUS_SUCCESS),
1401 msecs_to_jiffies(TIMEOUT_MS));
1402 if (!ret) {
1403 pr_err("%s: wait_event timeout\n", __func__);
1404 goto fail;
1405 }
1406 return 0;
1407fail:
1408 return -EINVAL;
1409
1410}
1411
1412static int voice_send_cvp_unmap_memory_cmd(struct voice_data *v)
1413{
1414 struct vss_unmap_memory_cmd cvp_unmap_mem_cmd;
1415 struct acdb_cal_block cal_block;
1416 int ret = 0;
1417 void *apr_cvp;
1418 u16 cvp_handle;
1419 uint32_t cal_paddr;
1420
1421 get_all_cvp_cal(&cal_block);
1422 if (cal_block.cal_size == 0)
1423 return 0;
1424
1425 if (v == NULL) {
1426 pr_err("%s: v is NULL\n", __func__);
1427 return -EINVAL;
1428 }
1429 apr_cvp = common.apr_q6_cvp;
1430
1431 if (!apr_cvp) {
1432 pr_err("%s: apr_cvp is NULL.\n", __func__);
1433 return -EINVAL;
1434 }
1435
1436 if (is_voip_session(v->session_id))
1437 cal_paddr = common.cvp_cal.phy;
1438 else
1439 cal_paddr = cal_block.cal_paddr;
1440
1441 cvp_handle = voice_get_cvp_handle(v);
1442
1443 /* fill in the header */
1444 cvp_unmap_mem_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1445 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1446 cvp_unmap_mem_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1447 sizeof(cvp_unmap_mem_cmd) - APR_HDR_SIZE);
1448 cvp_unmap_mem_cmd.hdr.src_port = v->session_id;
1449 cvp_unmap_mem_cmd.hdr.dest_port = cvp_handle;
1450 cvp_unmap_mem_cmd.hdr.token = 0;
1451 cvp_unmap_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_UNMAP_MEMORY;
1452
1453 cvp_unmap_mem_cmd.vss_unmap_mem.phys_addr = cal_paddr;
1454
1455 v->cvp_state = CMD_STATUS_FAIL;
1456 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_unmap_mem_cmd);
1457 if (ret < 0) {
1458 pr_err("Fail: sending cvp cal,\n");
1459 goto fail;
1460 }
1461 ret = wait_event_timeout(v->cvp_wait,
1462 (v->cvp_state == CMD_STATUS_SUCCESS),
1463 msecs_to_jiffies(TIMEOUT_MS));
1464 if (!ret) {
1465 pr_err("%s: wait_event timeout\n", __func__);
1466 goto fail;
1467 }
1468 return 0;
1469fail:
1470 return -EINVAL;
1471
1472}
1473
1474static int voice_send_cvs_map_memory_cmd(struct voice_data *v)
1475{
1476 struct vss_map_memory_cmd cvs_map_mem_cmd;
1477 struct acdb_cal_block cal_block;
1478 int ret = 0;
1479 void *apr_cvs;
1480 u16 cvs_handle;
1481 uint32_t cal_paddr;
1482
1483 /* get all cvs cal data */
1484 get_all_vocstrm_cal(&cal_block);
1485 if (cal_block.cal_size == 0)
1486 goto fail;
1487
1488 if (v == NULL) {
1489 pr_err("%s: v is NULL\n", __func__);
1490 return -EINVAL;
1491 }
1492 apr_cvs = common.apr_q6_cvs;
1493
1494 if (!apr_cvs) {
1495 pr_err("%s: apr_cvs is NULL.\n", __func__);
1496 return -EINVAL;
1497 }
1498
1499 if (is_voip_session(v->session_id)) {
1500 if (common.cvs_cal.buf)
1501 cal_paddr = common.cvs_cal.phy;
1502 else
1503 return -EINVAL;
1504 } else {
1505 cal_paddr = cal_block.cal_paddr;
1506 }
1507
1508 cvs_handle = voice_get_cvs_handle(v);
1509
1510 /* fill in the header */
1511 cvs_map_mem_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1512 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1513 cvs_map_mem_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1514 sizeof(cvs_map_mem_cmd) - APR_HDR_SIZE);
1515 cvs_map_mem_cmd.hdr.src_port = v->session_id;
1516 cvs_map_mem_cmd.hdr.dest_port = cvs_handle;
1517 cvs_map_mem_cmd.hdr.token = 0;
1518 cvs_map_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_MAP_MEMORY;
1519
1520 pr_debug("%s, phys_addr: 0x%x, mem_size: %d\n", __func__,
1521 cal_paddr, cal_block.cal_size);
1522 cvs_map_mem_cmd.vss_map_mem.phys_addr = cal_paddr;
1523 cvs_map_mem_cmd.vss_map_mem.mem_size = cal_block.cal_size;
1524 cvs_map_mem_cmd.vss_map_mem.mem_pool_id =
1525 VSS_ICOMMON_MAP_MEMORY_SHMEM8_4K_POOL;
1526
1527 v->cvs_state = CMD_STATUS_FAIL;
1528 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_map_mem_cmd);
1529 if (ret < 0) {
1530 pr_err("Fail: sending cvs cal,\n");
1531 goto fail;
1532 }
1533 ret = wait_event_timeout(v->cvs_wait,
1534 (v->cvs_state == CMD_STATUS_SUCCESS),
1535 msecs_to_jiffies(TIMEOUT_MS));
1536 if (!ret) {
1537 pr_err("%s: wait_event timeout\n", __func__);
1538 goto fail;
1539 }
1540 return 0;
1541fail:
1542 return -EINVAL;
1543
1544}
1545
1546static int voice_send_cvs_unmap_memory_cmd(struct voice_data *v)
1547{
1548 struct vss_unmap_memory_cmd cvs_unmap_mem_cmd;
1549 struct acdb_cal_block cal_block;
1550 int ret = 0;
1551 void *apr_cvs;
1552 u16 cvs_handle;
1553 uint32_t cal_paddr;
1554
1555 get_all_vocstrm_cal(&cal_block);
1556 if (cal_block.cal_size == 0)
1557 return 0;
1558
1559 if (v == NULL) {
1560 pr_err("%s: v is NULL\n", __func__);
1561 return -EINVAL;
1562 }
1563 apr_cvs = common.apr_q6_cvs;
1564
1565 if (!apr_cvs) {
1566 pr_err("%s: apr_cvs is NULL.\n", __func__);
1567 return -EINVAL;
1568 }
1569
1570 if (is_voip_session(v->session_id))
1571 cal_paddr = common.cvs_cal.phy;
1572 else
1573 cal_paddr = cal_block.cal_paddr;
1574
1575 cvs_handle = voice_get_cvs_handle(v);
1576
1577 /* fill in the header */
1578 cvs_unmap_mem_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1579 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1580 cvs_unmap_mem_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1581 sizeof(cvs_unmap_mem_cmd) - APR_HDR_SIZE);
1582 cvs_unmap_mem_cmd.hdr.src_port = v->session_id;
1583 cvs_unmap_mem_cmd.hdr.dest_port = cvs_handle;
1584 cvs_unmap_mem_cmd.hdr.token = 0;
1585 cvs_unmap_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_UNMAP_MEMORY;
1586
1587 cvs_unmap_mem_cmd.vss_unmap_mem.phys_addr = cal_paddr;
1588
1589 v->cvs_state = CMD_STATUS_FAIL;
1590 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_unmap_mem_cmd);
1591 if (ret < 0) {
1592 pr_err("Fail: sending cvs cal,\n");
1593 goto fail;
1594 }
1595 ret = wait_event_timeout(v->cvs_wait,
1596 (v->cvs_state == CMD_STATUS_SUCCESS),
1597 msecs_to_jiffies(TIMEOUT_MS));
1598 if (!ret) {
1599 pr_err("%s: wait_event timeout\n", __func__);
1600 goto fail;
1601 }
1602 return 0;
1603fail:
1604 return -EINVAL;
1605
1606}
1607
1608static int voice_send_cvp_register_cal_cmd(struct voice_data *v)
1609{
1610 struct cvp_register_cal_data_cmd cvp_reg_cal_cmd;
1611 struct acdb_cal_block cal_block;
1612 int ret = 0;
1613 void *apr_cvp;
1614 u16 cvp_handle;
1615 uint32_t cal_paddr;
1616
1617 /* get the cvp cal data */
1618 get_all_vocproc_cal(&cal_block);
1619 if (cal_block.cal_size == 0)
1620 goto fail;
1621
1622 if (v == NULL) {
1623 pr_err("%s: v is NULL\n", __func__);
1624 return -EINVAL;
1625 }
1626 apr_cvp = common.apr_q6_cvp;
1627
1628 if (!apr_cvp) {
1629 pr_err("%s: apr_cvp is NULL.\n", __func__);
1630 return -EINVAL;
1631 }
1632
1633 if (is_voip_session(v->session_id)) {
1634 if (common.cvp_cal.buf) {
1635 cal_paddr = common.cvp_cal.phy;
1636
1637 memcpy(common.cvp_cal.buf,
1638 (void *)cal_block.cal_kvaddr,
1639 cal_block.cal_size);
1640 } else {
1641 return -EINVAL;
1642 }
1643 } else {
1644 cal_paddr = cal_block.cal_paddr;
1645 }
1646
1647 cvp_handle = voice_get_cvp_handle(v);
1648
1649 /* fill in the header */
1650 cvp_reg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1651 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1652 cvp_reg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1653 sizeof(cvp_reg_cal_cmd) - APR_HDR_SIZE);
1654 cvp_reg_cal_cmd.hdr.src_port = v->session_id;
1655 cvp_reg_cal_cmd.hdr.dest_port = cvp_handle;
1656 cvp_reg_cal_cmd.hdr.token = 0;
1657 cvp_reg_cal_cmd.hdr.opcode = VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA;
1658
1659 cvp_reg_cal_cmd.cvp_cal_data.phys_addr = cal_paddr;
1660 cvp_reg_cal_cmd.cvp_cal_data.mem_size = cal_block.cal_size;
1661
1662 v->cvp_state = CMD_STATUS_FAIL;
1663 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_reg_cal_cmd);
1664 if (ret < 0) {
1665 pr_err("Fail: sending cvp cal,\n");
1666 goto fail;
1667 }
1668 ret = wait_event_timeout(v->cvp_wait,
1669 (v->cvp_state == CMD_STATUS_SUCCESS),
1670 msecs_to_jiffies(TIMEOUT_MS));
1671 if (!ret) {
1672 pr_err("%s: wait_event timeout\n", __func__);
1673 goto fail;
1674 }
1675 return 0;
1676fail:
1677 return -EINVAL;
1678
1679}
1680
1681static int voice_send_cvp_deregister_cal_cmd(struct voice_data *v)
1682{
1683 struct cvp_deregister_cal_data_cmd cvp_dereg_cal_cmd;
1684 struct acdb_cal_block cal_block;
1685 int ret = 0;
1686 void *apr_cvp;
1687 u16 cvp_handle;
1688
1689 get_all_vocproc_cal(&cal_block);
1690 if (cal_block.cal_size == 0)
1691 return 0;
1692
1693 if (v == NULL) {
1694 pr_err("%s: v is NULL\n", __func__);
1695 return -EINVAL;
1696 }
1697 apr_cvp = common.apr_q6_cvp;
1698
1699 if (!apr_cvp) {
1700 pr_err("%s: apr_cvp is NULL.\n", __func__);
1701 return -EINVAL;
1702 }
1703 cvp_handle = voice_get_cvp_handle(v);
1704
1705 /* fill in the header */
1706 cvp_dereg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1707 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1708 cvp_dereg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1709 sizeof(cvp_dereg_cal_cmd) - APR_HDR_SIZE);
1710 cvp_dereg_cal_cmd.hdr.src_port = v->session_id;
1711 cvp_dereg_cal_cmd.hdr.dest_port = cvp_handle;
1712 cvp_dereg_cal_cmd.hdr.token = 0;
1713 cvp_dereg_cal_cmd.hdr.opcode =
1714 VSS_IVOCPROC_CMD_DEREGISTER_CALIBRATION_DATA;
1715
1716 v->cvp_state = CMD_STATUS_FAIL;
1717 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_dereg_cal_cmd);
1718 if (ret < 0) {
1719 pr_err("Fail: sending cvp cal,\n");
1720 goto fail;
1721 }
1722 ret = wait_event_timeout(v->cvp_wait,
1723 (v->cvp_state == CMD_STATUS_SUCCESS),
1724 msecs_to_jiffies(TIMEOUT_MS));
1725 if (!ret) {
1726 pr_err("%s: wait_event timeout\n", __func__);
1727 goto fail;
1728 }
1729 return 0;
1730fail:
1731 return -EINVAL;
1732
1733}
1734
1735static int voice_send_cvp_register_vol_cal_table_cmd(struct voice_data *v)
1736{
1737 struct cvp_register_vol_cal_table_cmd cvp_reg_cal_tbl_cmd;
1738 struct acdb_cal_block vol_block;
1739 struct acdb_cal_block voc_block;
1740 int ret = 0;
1741 void *apr_cvp;
1742 u16 cvp_handle;
1743 uint32_t cal_paddr;
1744
1745 /* get the cvp vol cal data */
1746 get_all_vocvol_cal(&vol_block);
1747 get_all_vocproc_cal(&voc_block);
1748
1749 if (vol_block.cal_size == 0)
1750 goto fail;
1751
1752 if (v == NULL) {
1753 pr_err("%s: v is NULL\n", __func__);
1754 return -EINVAL;
1755 }
1756 apr_cvp = common.apr_q6_cvp;
1757
1758 if (!apr_cvp) {
1759 pr_err("%s: apr_cvp is NULL.\n", __func__);
1760 return -EINVAL;
1761 }
1762
1763 if (is_voip_session(v->session_id)) {
1764 if (common.cvp_cal.buf) {
1765 cal_paddr = common.cvp_cal.phy + voc_block.cal_size;
1766
1767 memcpy(common.cvp_cal.buf + voc_block.cal_size,
1768 (void *) vol_block.cal_kvaddr,
1769 vol_block.cal_size);
1770 } else {
1771 return -EINVAL;
1772 }
1773 } else {
1774 cal_paddr = vol_block.cal_paddr;
1775 }
1776
1777 cvp_handle = voice_get_cvp_handle(v);
1778
1779 /* fill in the header */
1780 cvp_reg_cal_tbl_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1781 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1782 cvp_reg_cal_tbl_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1783 sizeof(cvp_reg_cal_tbl_cmd) - APR_HDR_SIZE);
1784 cvp_reg_cal_tbl_cmd.hdr.src_port = v->session_id;
1785 cvp_reg_cal_tbl_cmd.hdr.dest_port = cvp_handle;
1786 cvp_reg_cal_tbl_cmd.hdr.token = 0;
1787 cvp_reg_cal_tbl_cmd.hdr.opcode =
1788 VSS_IVOCPROC_CMD_REGISTER_VOLUME_CAL_TABLE;
1789
1790 cvp_reg_cal_tbl_cmd.cvp_vol_cal_tbl.phys_addr = cal_paddr;
1791 cvp_reg_cal_tbl_cmd.cvp_vol_cal_tbl.mem_size = vol_block.cal_size;
1792
1793 v->cvp_state = CMD_STATUS_FAIL;
1794 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_reg_cal_tbl_cmd);
1795 if (ret < 0) {
1796 pr_err("Fail: sending cvp cal table,\n");
1797 goto fail;
1798 }
1799 ret = wait_event_timeout(v->cvp_wait,
1800 (v->cvp_state == CMD_STATUS_SUCCESS),
1801 msecs_to_jiffies(TIMEOUT_MS));
1802 if (!ret) {
1803 pr_err("%s: wait_event timeout\n", __func__);
1804 goto fail;
1805 }
1806 return 0;
1807fail:
1808 return -EINVAL;
1809
1810}
1811
1812static int voice_send_cvp_deregister_vol_cal_table_cmd(struct voice_data *v)
1813{
1814 struct cvp_deregister_vol_cal_table_cmd cvp_dereg_cal_tbl_cmd;
1815 struct acdb_cal_block cal_block;
1816 int ret = 0;
1817 void *apr_cvp;
1818 u16 cvp_handle;
1819
1820 get_all_vocvol_cal(&cal_block);
1821 if (cal_block.cal_size == 0)
1822 return 0;
1823
1824 if (v == NULL) {
1825 pr_err("%s: v is NULL\n", __func__);
1826 return -EINVAL;
1827 }
1828 apr_cvp = common.apr_q6_cvp;
1829
1830 if (!apr_cvp) {
1831 pr_err("%s: apr_cvp is NULL.\n", __func__);
1832 return -EINVAL;
1833 }
1834 cvp_handle = voice_get_cvp_handle(v);
1835
1836 /* fill in the header */
1837 cvp_dereg_cal_tbl_cmd.hdr.hdr_field = APR_HDR_FIELD(
1838 APR_MSG_TYPE_SEQ_CMD,
1839 APR_HDR_LEN(APR_HDR_SIZE),
1840 APR_PKT_VER);
1841 cvp_dereg_cal_tbl_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1842 sizeof(cvp_dereg_cal_tbl_cmd) - APR_HDR_SIZE);
1843 cvp_dereg_cal_tbl_cmd.hdr.src_port = v->session_id;
1844 cvp_dereg_cal_tbl_cmd.hdr.dest_port = cvp_handle;
1845 cvp_dereg_cal_tbl_cmd.hdr.token = 0;
1846 cvp_dereg_cal_tbl_cmd.hdr.opcode =
1847 VSS_IVOCPROC_CMD_DEREGISTER_VOLUME_CAL_TABLE;
1848
1849 v->cvp_state = CMD_STATUS_FAIL;
1850 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_dereg_cal_tbl_cmd);
1851 if (ret < 0) {
1852 pr_err("Fail: sending cvp cal table,\n");
1853 goto fail;
1854 }
1855 ret = wait_event_timeout(v->cvp_wait,
1856 (v->cvp_state == CMD_STATUS_SUCCESS),
1857 msecs_to_jiffies(TIMEOUT_MS));
1858 if (!ret) {
1859 pr_err("%s: wait_event timeout\n", __func__);
1860 goto fail;
1861 }
1862 return 0;
1863fail:
1864 return -EINVAL;
1865
1866}
1867
1868static int voice_send_set_widevoice_enable_cmd(struct voice_data *v)
1869{
1870 struct mvm_set_widevoice_enable_cmd mvm_set_wv_cmd;
1871 int ret = 0;
1872 void *apr_mvm;
1873 u16 mvm_handle;
1874
1875 if (v == NULL) {
1876 pr_err("%s: v is NULL\n", __func__);
1877 return -EINVAL;
1878 }
1879 apr_mvm = common.apr_q6_mvm;
1880
1881 if (!apr_mvm) {
1882 pr_err("%s: apr_mvm is NULL.\n", __func__);
1883 return -EINVAL;
1884 }
1885 mvm_handle = voice_get_mvm_handle(v);
1886
1887 /* fill in the header */
1888 mvm_set_wv_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1889 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1890 mvm_set_wv_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1891 sizeof(mvm_set_wv_cmd) - APR_HDR_SIZE);
1892 mvm_set_wv_cmd.hdr.src_port = v->session_id;
1893 mvm_set_wv_cmd.hdr.dest_port = mvm_handle;
1894 mvm_set_wv_cmd.hdr.token = 0;
1895 mvm_set_wv_cmd.hdr.opcode = VSS_IWIDEVOICE_CMD_SET_WIDEVOICE;
1896
1897 mvm_set_wv_cmd.vss_set_wv.enable = v->wv_enable;
1898
1899 v->mvm_state = CMD_STATUS_FAIL;
1900 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_wv_cmd);
1901 if (ret < 0) {
1902 pr_err("Fail: sending mvm set widevoice enable,\n");
1903 goto fail;
1904 }
1905 ret = wait_event_timeout(v->mvm_wait,
1906 (v->mvm_state == CMD_STATUS_SUCCESS),
1907 msecs_to_jiffies(TIMEOUT_MS));
1908 if (!ret) {
1909 pr_err("%s: wait_event timeout\n", __func__);
1910 goto fail;
1911 }
1912 return 0;
1913fail:
1914 return -EINVAL;
1915}
1916
1917static int voice_send_set_pp_enable_cmd(struct voice_data *v,
1918 uint32_t module_id, int enable)
1919{
1920 struct cvs_set_pp_enable_cmd cvs_set_pp_cmd;
1921 int ret = 0;
1922 void *apr_cvs;
1923 u16 cvs_handle;
1924
1925 if (v == NULL) {
1926 pr_err("%s: v is NULL\n", __func__);
1927 return -EINVAL;
1928 }
1929 apr_cvs = common.apr_q6_cvs;
1930
1931 if (!apr_cvs) {
1932 pr_err("%s: apr_cvs is NULL.\n", __func__);
1933 return -EINVAL;
1934 }
1935 cvs_handle = voice_get_cvs_handle(v);
1936
1937 /* fill in the header */
1938 cvs_set_pp_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1939 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1940 cvs_set_pp_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1941 sizeof(cvs_set_pp_cmd) - APR_HDR_SIZE);
1942 cvs_set_pp_cmd.hdr.src_port = v->session_id;
1943 cvs_set_pp_cmd.hdr.dest_port = cvs_handle;
1944 cvs_set_pp_cmd.hdr.token = 0;
1945 cvs_set_pp_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_UI_PROPERTY;
1946
1947 cvs_set_pp_cmd.vss_set_pp.module_id = module_id;
1948 cvs_set_pp_cmd.vss_set_pp.param_id = VOICE_PARAM_MOD_ENABLE;
1949 cvs_set_pp_cmd.vss_set_pp.param_size = MOD_ENABLE_PARAM_LEN;
1950 cvs_set_pp_cmd.vss_set_pp.reserved = 0;
1951 cvs_set_pp_cmd.vss_set_pp.enable = enable;
1952 cvs_set_pp_cmd.vss_set_pp.reserved_field = 0;
1953 pr_debug("voice_send_set_pp_enable_cmd, module_id=%d, enable=%d\n",
1954 module_id, enable);
1955
1956 v->cvs_state = CMD_STATUS_FAIL;
1957 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_pp_cmd);
1958 if (ret < 0) {
1959 pr_err("Fail: sending cvs set slowtalk enable,\n");
1960 goto fail;
1961 }
1962 ret = wait_event_timeout(v->cvs_wait,
1963 (v->cvs_state == CMD_STATUS_SUCCESS),
1964 msecs_to_jiffies(TIMEOUT_MS));
1965 if (!ret) {
1966 pr_err("%s: wait_event timeout\n", __func__);
1967 goto fail;
1968 }
1969 return 0;
1970fail:
1971 return -EINVAL;
1972}
1973
1974static int voice_setup_vocproc(struct voice_data *v)
1975{
1976 struct cvp_create_full_ctl_session_cmd cvp_session_cmd;
1977 int ret = 0;
1978 void *apr_cvp;
1979 if (v == NULL) {
1980 pr_err("%s: v is NULL\n", __func__);
1981 return -EINVAL;
1982 }
1983 apr_cvp = common.apr_q6_cvp;
1984
1985 if (!apr_cvp) {
1986 pr_err("%s: apr_cvp is NULL.\n", __func__);
1987 return -EINVAL;
1988 }
1989
1990 /* create cvp session and wait for response */
1991 cvp_session_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1992 APR_HDR_LEN(APR_HDR_SIZE),
1993 APR_PKT_VER);
1994 cvp_session_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1995 sizeof(cvp_session_cmd) - APR_HDR_SIZE);
1996 pr_debug(" send create cvp session, pkt size = %d\n",
1997 cvp_session_cmd.hdr.pkt_size);
1998 cvp_session_cmd.hdr.src_port = v->session_id;
1999 cvp_session_cmd.hdr.dest_port = 0;
2000 cvp_session_cmd.hdr.token = 0;
2001 cvp_session_cmd.hdr.opcode =
2002 VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION;
2003
2004 /* Use default topology if invalid value in ACDB */
2005 cvp_session_cmd.cvp_session.tx_topology_id =
2006 get_voice_tx_topology();
2007 if (cvp_session_cmd.cvp_session.tx_topology_id == 0)
2008 cvp_session_cmd.cvp_session.tx_topology_id =
2009 VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
2010
2011 cvp_session_cmd.cvp_session.rx_topology_id =
2012 get_voice_rx_topology();
2013 if (cvp_session_cmd.cvp_session.rx_topology_id == 0)
2014 cvp_session_cmd.cvp_session.rx_topology_id =
2015 VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
2016
2017 cvp_session_cmd.cvp_session.direction = 2; /*tx and rx*/
2018 cvp_session_cmd.cvp_session.network_id = VSS_NETWORK_ID_DEFAULT;
2019 cvp_session_cmd.cvp_session.tx_port_id = v->dev_tx.port_id;
2020 cvp_session_cmd.cvp_session.rx_port_id = v->dev_rx.port_id;
2021
2022 pr_debug("topology=%d net_id=%d, dir=%d tx_port_id=%d, rx_port_id=%d\n",
2023 cvp_session_cmd.cvp_session.tx_topology_id,
2024 cvp_session_cmd.cvp_session.network_id,
2025 cvp_session_cmd.cvp_session.direction,
2026 cvp_session_cmd.cvp_session.tx_port_id,
2027 cvp_session_cmd.cvp_session.rx_port_id);
2028
2029 v->cvp_state = CMD_STATUS_FAIL;
2030 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_session_cmd);
2031 if (ret < 0) {
2032 pr_err("Fail in sending VOCPROC_FULL_CONTROL_SESSION\n");
2033 goto fail;
2034 }
2035 ret = wait_event_timeout(v->cvp_wait,
2036 (v->cvp_state == CMD_STATUS_SUCCESS),
2037 msecs_to_jiffies(TIMEOUT_MS));
2038 if (!ret) {
2039 pr_err("%s: wait_event timeout\n", __func__);
2040 goto fail;
2041 }
2042
2043 /* send cvs cal */
2044 ret = voice_send_cvs_map_memory_cmd(v);
2045 if (!ret)
2046 voice_send_cvs_register_cal_cmd(v);
2047
2048 /* send cvp and vol cal */
2049 ret = voice_send_cvp_map_memory_cmd(v);
2050 if (!ret) {
2051 voice_send_cvp_register_cal_cmd(v);
2052 voice_send_cvp_register_vol_cal_table_cmd(v);
2053 }
2054
2055 /* enable vocproc */
2056 ret = voice_send_enable_vocproc_cmd(v);
2057 if (ret < 0)
2058 goto fail;
2059
2060 /* attach vocproc */
2061 ret = voice_send_attach_vocproc_cmd(v);
2062 if (ret < 0)
2063 goto fail;
2064
2065 /* send tty mode if tty device is used */
2066 voice_send_tty_mode_cmd(v);
2067
2068 /* enable widevoice if wv_enable is set */
2069 if (v->wv_enable)
2070 voice_send_set_widevoice_enable_cmd(v);
2071
2072 /* enable slowtalk if st_enable is set */
2073 if (v->st_enable)
2074 voice_send_set_pp_enable_cmd(v, MODULE_ID_VOICE_MODULE_ST,
2075 v->st_enable);
2076 voice_send_set_pp_enable_cmd(v, MODULE_ID_VOICE_MODULE_FENS,
2077 v->fens_enable);
2078
2079 if (is_voip_session(v->session_id))
2080 voice_send_netid_timing_cmd(v);
2081
2082 /* Start in-call music delivery if this feature is enabled */
2083 if (v->music_info.play_enable)
2084 voice_cvs_start_playback(v);
2085
2086 /* Start in-call recording if this feature is enabled */
2087 if (v->rec_info.rec_enable)
2088 voice_cvs_start_record(v, v->rec_info.rec_mode);
2089
2090 rtac_add_voice(voice_get_cvs_handle(v),
2091 voice_get_cvp_handle(v),
2092 v->dev_rx.port_id, v->dev_tx.port_id,
2093 v->session_id);
2094
2095 return 0;
2096
2097fail:
2098 return -EINVAL;
2099}
2100
2101static int voice_send_enable_vocproc_cmd(struct voice_data *v)
2102{
2103 int ret = 0;
2104 struct apr_hdr cvp_enable_cmd;
2105 void *apr_cvp;
2106 u16 cvp_handle;
2107
2108 if (v == NULL) {
2109 pr_err("%s: v is NULL\n", __func__);
2110 return -EINVAL;
2111 }
2112 apr_cvp = common.apr_q6_cvp;
2113
2114 if (!apr_cvp) {
2115 pr_err("%s: apr_cvp is NULL.\n", __func__);
2116 return -EINVAL;
2117 }
2118 cvp_handle = voice_get_cvp_handle(v);
2119
2120 /* enable vocproc and wait for respose */
2121 cvp_enable_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2122 APR_HDR_LEN(APR_HDR_SIZE),
2123 APR_PKT_VER);
2124 cvp_enable_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2125 sizeof(cvp_enable_cmd) - APR_HDR_SIZE);
2126 pr_debug("cvp_enable_cmd pkt size = %d, cvp_handle=%d\n",
2127 cvp_enable_cmd.pkt_size, cvp_handle);
2128 cvp_enable_cmd.src_port = v->session_id;
2129 cvp_enable_cmd.dest_port = cvp_handle;
2130 cvp_enable_cmd.token = 0;
2131 cvp_enable_cmd.opcode = VSS_IVOCPROC_CMD_ENABLE;
2132
2133 v->cvp_state = CMD_STATUS_FAIL;
2134 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_enable_cmd);
2135 if (ret < 0) {
2136 pr_err("Fail in sending VSS_IVOCPROC_CMD_ENABLE\n");
2137 goto fail;
2138 }
2139 ret = wait_event_timeout(v->cvp_wait,
2140 (v->cvp_state == CMD_STATUS_SUCCESS),
2141 msecs_to_jiffies(TIMEOUT_MS));
2142 if (!ret) {
2143 pr_err("%s: wait_event timeout\n", __func__);
2144 goto fail;
2145 }
2146
2147 return 0;
2148fail:
2149 return -EINVAL;
2150}
2151
2152static int voice_send_netid_timing_cmd(struct voice_data *v)
2153{
2154 int ret = 0;
2155 void *apr_mvm;
2156 u16 mvm_handle;
2157 struct mvm_set_network_cmd mvm_set_network;
2158 struct mvm_set_voice_timing_cmd mvm_set_voice_timing;
2159
2160 if (v == NULL) {
2161 pr_err("%s: v is NULL\n", __func__);
2162 return -EINVAL;
2163 }
2164 apr_mvm = common.apr_q6_mvm;
2165
2166 if (!apr_mvm) {
2167 pr_err("%s: apr_mvm is NULL.\n", __func__);
2168 return -EINVAL;
2169 }
2170 mvm_handle = voice_get_mvm_handle(v);
2171
2172 ret = voice_config_cvs_vocoder(v);
2173 if (ret < 0) {
2174 pr_err("%s: Error %d configuring CVS voc",
2175 __func__, ret);
2176 goto fail;
2177 }
2178 /* Set network ID. */
2179 pr_debug("Setting network ID\n");
2180
2181 mvm_set_network.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2182 APR_HDR_LEN(APR_HDR_SIZE),
2183 APR_PKT_VER);
2184 mvm_set_network.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2185 sizeof(mvm_set_network) - APR_HDR_SIZE);
2186 mvm_set_network.hdr.src_port = v->session_id;
2187 mvm_set_network.hdr.dest_port = mvm_handle;
2188 mvm_set_network.hdr.token = 0;
2189 mvm_set_network.hdr.opcode = VSS_ICOMMON_CMD_SET_NETWORK;
2190 mvm_set_network.network.network_id = common.mvs_info.network_type;
2191
2192 v->mvm_state = CMD_STATUS_FAIL;
2193 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_network);
2194 if (ret < 0) {
2195 pr_err("%s: Error %d sending SET_NETWORK\n", __func__, ret);
2196 goto fail;
2197 }
2198
2199 ret = wait_event_timeout(v->mvm_wait,
2200 (v->mvm_state == CMD_STATUS_SUCCESS),
2201 msecs_to_jiffies(TIMEOUT_MS));
2202 if (!ret) {
2203 pr_err("%s: wait_event timeout\n", __func__);
2204 goto fail;
2205 }
2206
2207 /* Set voice timing. */
2208 pr_debug("Setting voice timing\n");
2209
2210 mvm_set_voice_timing.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2211 APR_HDR_LEN(APR_HDR_SIZE),
2212 APR_PKT_VER);
2213 mvm_set_voice_timing.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2214 sizeof(mvm_set_voice_timing) -
2215 APR_HDR_SIZE);
2216 mvm_set_voice_timing.hdr.src_port = v->session_id;
2217 mvm_set_voice_timing.hdr.dest_port = mvm_handle;
2218 mvm_set_voice_timing.hdr.token = 0;
2219 mvm_set_voice_timing.hdr.opcode = VSS_ICOMMON_CMD_SET_VOICE_TIMING;
2220 mvm_set_voice_timing.timing.mode = 0;
2221 mvm_set_voice_timing.timing.enc_offset = 8000;
Abhimanyu Kapur90ced6e2012-06-26 17:41:25 -07002222 if ((machine_is_apq8064_sim()) || (machine_is_msm8974_sim())) {
2223 pr_debug("%s: Machine is MSM8974 sim\n", __func__);
Phani Kumar Uppalapati4fbf4c42012-05-21 20:35:45 -07002224 mvm_set_voice_timing.timing.dec_req_offset = 0;
2225 mvm_set_voice_timing.timing.dec_offset = 18000;
2226 } else {
2227 mvm_set_voice_timing.timing.dec_req_offset = 3300;
2228 mvm_set_voice_timing.timing.dec_offset = 8300;
2229 }
2230
2231 v->mvm_state = CMD_STATUS_FAIL;
2232
2233 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_voice_timing);
2234 if (ret < 0) {
2235 pr_err("%s: Error %d sending SET_TIMING\n", __func__, ret);
2236 goto fail;
2237 }
2238
2239 ret = wait_event_timeout(v->mvm_wait,
2240 (v->mvm_state == CMD_STATUS_SUCCESS),
2241 msecs_to_jiffies(TIMEOUT_MS));
2242 if (!ret) {
2243 pr_err("%s: wait_event timeout\n", __func__);
2244 goto fail;
2245 }
2246
2247 return 0;
2248fail:
2249 return -EINVAL;
2250}
2251
2252static int voice_send_attach_vocproc_cmd(struct voice_data *v)
2253{
2254 int ret = 0;
2255 struct mvm_attach_vocproc_cmd mvm_a_vocproc_cmd;
2256 void *apr_mvm;
2257 u16 mvm_handle, cvp_handle;
2258
2259 if (v == NULL) {
2260 pr_err("%s: v is NULL\n", __func__);
2261 return -EINVAL;
2262 }
2263 apr_mvm = common.apr_q6_mvm;
2264
2265 if (!apr_mvm) {
2266 pr_err("%s: apr_mvm is NULL.\n", __func__);
2267 return -EINVAL;
2268 }
2269 mvm_handle = voice_get_mvm_handle(v);
2270 cvp_handle = voice_get_cvp_handle(v);
2271
2272 /* attach vocproc and wait for response */
2273 mvm_a_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2274 APR_HDR_LEN(APR_HDR_SIZE),
2275 APR_PKT_VER);
2276 mvm_a_vocproc_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2277 sizeof(mvm_a_vocproc_cmd) - APR_HDR_SIZE);
2278 pr_debug("send mvm_a_vocproc_cmd pkt size = %d\n",
2279 mvm_a_vocproc_cmd.hdr.pkt_size);
2280 mvm_a_vocproc_cmd.hdr.src_port = v->session_id;
2281 mvm_a_vocproc_cmd.hdr.dest_port = mvm_handle;
2282 mvm_a_vocproc_cmd.hdr.token = 0;
2283 mvm_a_vocproc_cmd.hdr.opcode = VSS_IMVM_CMD_ATTACH_VOCPROC;
2284 mvm_a_vocproc_cmd.mvm_attach_cvp_handle.handle = cvp_handle;
2285
2286 v->mvm_state = CMD_STATUS_FAIL;
2287 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_a_vocproc_cmd);
2288 if (ret < 0) {
2289 pr_err("Fail in sending VSS_IMVM_CMD_ATTACH_VOCPROC\n");
2290 goto fail;
2291 }
2292 ret = wait_event_timeout(v->mvm_wait,
2293 (v->mvm_state == CMD_STATUS_SUCCESS),
2294 msecs_to_jiffies(TIMEOUT_MS));
2295 if (!ret) {
2296 pr_err("%s: wait_event timeout\n", __func__);
2297 goto fail;
2298 }
2299
2300 return 0;
2301fail:
2302 return -EINVAL;
2303}
2304
2305static int voice_destroy_vocproc(struct voice_data *v)
2306{
2307 struct mvm_detach_vocproc_cmd mvm_d_vocproc_cmd;
2308 struct apr_hdr cvp_destroy_session_cmd;
2309 int ret = 0;
2310 void *apr_mvm, *apr_cvp;
2311 u16 mvm_handle, cvp_handle;
2312
2313 if (v == NULL) {
2314 pr_err("%s: v is NULL\n", __func__);
2315 return -EINVAL;
2316 }
2317 apr_mvm = common.apr_q6_mvm;
2318 apr_cvp = common.apr_q6_cvp;
2319
2320 if (!apr_mvm || !apr_cvp) {
2321 pr_err("%s: apr_mvm or apr_cvp is NULL.\n", __func__);
2322 return -EINVAL;
2323 }
2324 mvm_handle = voice_get_mvm_handle(v);
2325 cvp_handle = voice_get_cvp_handle(v);
2326
2327 /* stop playback or recording */
2328 v->music_info.force = 1;
2329 voice_cvs_stop_playback(v);
2330 voice_cvs_stop_record(v);
2331 /* send stop voice cmd */
2332 voice_send_stop_voice_cmd(v);
2333
2334 /* detach VOCPROC and wait for response from mvm */
2335 mvm_d_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2336 APR_HDR_LEN(APR_HDR_SIZE),
2337 APR_PKT_VER);
2338 mvm_d_vocproc_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2339 sizeof(mvm_d_vocproc_cmd) - APR_HDR_SIZE);
2340 pr_debug("mvm_d_vocproc_cmd pkt size = %d\n",
2341 mvm_d_vocproc_cmd.hdr.pkt_size);
2342 mvm_d_vocproc_cmd.hdr.src_port = v->session_id;
2343 mvm_d_vocproc_cmd.hdr.dest_port = mvm_handle;
2344 mvm_d_vocproc_cmd.hdr.token = 0;
2345 mvm_d_vocproc_cmd.hdr.opcode = VSS_IMVM_CMD_DETACH_VOCPROC;
2346 mvm_d_vocproc_cmd.mvm_detach_cvp_handle.handle = cvp_handle;
2347
2348 v->mvm_state = CMD_STATUS_FAIL;
2349 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_d_vocproc_cmd);
2350 if (ret < 0) {
2351 pr_err("Fail in sending VSS_IMVM_CMD_DETACH_VOCPROC\n");
2352 goto fail;
2353 }
2354 ret = wait_event_timeout(v->mvm_wait,
2355 (v->mvm_state == CMD_STATUS_SUCCESS),
2356 msecs_to_jiffies(TIMEOUT_MS));
2357 if (!ret) {
2358 pr_err("%s: wait_event timeout\n", __func__);
2359 goto fail;
2360 }
2361
2362 /* deregister cvp and vol cal */
2363 voice_send_cvp_deregister_vol_cal_table_cmd(v);
2364 voice_send_cvp_deregister_cal_cmd(v);
2365 voice_send_cvp_unmap_memory_cmd(v);
2366
2367 /* deregister cvs cal */
2368 voice_send_cvs_deregister_cal_cmd(v);
2369 voice_send_cvs_unmap_memory_cmd(v);
2370
2371 /* destrop cvp session */
2372 cvp_destroy_session_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2373 APR_HDR_LEN(APR_HDR_SIZE),
2374 APR_PKT_VER);
2375 cvp_destroy_session_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2376 sizeof(cvp_destroy_session_cmd) - APR_HDR_SIZE);
2377 pr_debug("cvp_destroy_session_cmd pkt size = %d\n",
2378 cvp_destroy_session_cmd.pkt_size);
2379 cvp_destroy_session_cmd.src_port = v->session_id;
2380 cvp_destroy_session_cmd.dest_port = cvp_handle;
2381 cvp_destroy_session_cmd.token = 0;
2382 cvp_destroy_session_cmd.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
2383
2384 v->cvp_state = CMD_STATUS_FAIL;
2385 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_destroy_session_cmd);
2386 if (ret < 0) {
2387 pr_err("Fail in sending APRV2_IBASIC_CMD_DESTROY_SESSION\n");
2388 goto fail;
2389 }
2390 ret = wait_event_timeout(v->cvp_wait,
2391 (v->cvp_state == CMD_STATUS_SUCCESS),
2392 msecs_to_jiffies(TIMEOUT_MS));
2393 if (!ret) {
2394 pr_err("%s: wait_event timeout\n", __func__);
2395 goto fail;
2396 }
2397
2398 rtac_remove_voice(voice_get_cvs_handle(v));
2399 cvp_handle = 0;
2400 voice_set_cvp_handle(v, cvp_handle);
2401
2402 return 0;
2403
2404fail:
2405 return -EINVAL;
2406}
2407
2408static int voice_send_mute_cmd(struct voice_data *v)
2409{
2410 struct cvs_set_mute_cmd cvs_mute_cmd;
2411 int ret = 0;
2412 void *apr_cvs;
2413 u16 cvs_handle;
2414
2415 if (v == NULL) {
2416 pr_err("%s: v is NULL\n", __func__);
2417 return -EINVAL;
2418 }
2419 apr_cvs = common.apr_q6_cvs;
2420
2421 if (!apr_cvs) {
2422 pr_err("%s: apr_cvs is NULL.\n", __func__);
2423 return -EINVAL;
2424 }
2425 cvs_handle = voice_get_cvs_handle(v);
2426
2427 /* send mute/unmute to cvs */
2428 cvs_mute_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2429 APR_HDR_LEN(APR_HDR_SIZE),
2430 APR_PKT_VER);
2431 cvs_mute_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2432 sizeof(cvs_mute_cmd) - APR_HDR_SIZE);
2433 cvs_mute_cmd.hdr.src_port = v->session_id;
2434 cvs_mute_cmd.hdr.dest_port = cvs_handle;
2435 cvs_mute_cmd.hdr.token = 0;
2436 cvs_mute_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_MUTE;
2437 cvs_mute_cmd.cvs_set_mute.direction = 0; /*tx*/
2438 cvs_mute_cmd.cvs_set_mute.mute_flag = v->dev_tx.mute;
2439
2440 v->cvs_state = CMD_STATUS_FAIL;
2441 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_mute_cmd);
2442 if (ret < 0) {
2443 pr_err("Fail: send STREAM SET MUTE\n");
2444 goto fail;
2445 }
2446 ret = wait_event_timeout(v->cvs_wait,
2447 (v->cvs_state == CMD_STATUS_SUCCESS),
2448 msecs_to_jiffies(TIMEOUT_MS));
2449 if (!ret)
2450 pr_err("%s: wait_event timeout\n", __func__);
2451
2452 return 0;
2453fail:
2454 return -EINVAL;
2455}
2456
2457static int voice_send_rx_device_mute_cmd(struct voice_data *v)
2458{
2459 struct cvp_set_mute_cmd cvp_mute_cmd;
2460 int ret = 0;
2461 void *apr_cvp;
2462 u16 cvp_handle;
2463 if (v == NULL) {
2464 pr_err("%s: v is NULL\n", __func__);
2465 return -EINVAL;
2466 }
2467 apr_cvp = common.apr_q6_cvp;
2468
2469 if (!apr_cvp) {
2470 pr_err("%s: apr_cvp is NULL.\n", __func__);
2471 return -EINVAL;
2472 }
2473 cvp_handle = voice_get_cvp_handle(v);
2474
2475 cvp_mute_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2476 APR_HDR_LEN(APR_HDR_SIZE),
2477 APR_PKT_VER);
2478 cvp_mute_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2479 sizeof(cvp_mute_cmd) - APR_HDR_SIZE);
2480 cvp_mute_cmd.hdr.src_port = v->session_id;
2481 cvp_mute_cmd.hdr.dest_port = cvp_handle;
2482 cvp_mute_cmd.hdr.token = 0;
2483 cvp_mute_cmd.hdr.opcode = VSS_IVOCPROC_CMD_SET_MUTE;
2484 cvp_mute_cmd.cvp_set_mute.direction = 1;
2485 cvp_mute_cmd.cvp_set_mute.mute_flag = v->dev_rx.mute;
2486 v->cvp_state = CMD_STATUS_FAIL;
2487 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_mute_cmd);
2488 if (ret < 0) {
2489 pr_err("Fail in sending RX device mute cmd\n");
2490 return -EINVAL;
2491 }
2492 ret = wait_event_timeout(v->cvp_wait,
2493 (v->cvp_state == CMD_STATUS_SUCCESS),
2494 msecs_to_jiffies(TIMEOUT_MS));
2495 if (!ret) {
2496 pr_err("%s: wait_event timeout\n", __func__);
2497 return -EINVAL;
2498 }
2499 return 0;
2500}
2501
2502static int voice_send_vol_index_cmd(struct voice_data *v)
2503{
2504 struct cvp_set_rx_volume_index_cmd cvp_vol_cmd;
2505 int ret = 0;
2506 void *apr_cvp;
2507 u16 cvp_handle;
2508 if (v == NULL) {
2509 pr_err("%s: v is NULL\n", __func__);
2510 return -EINVAL;
2511 }
2512 apr_cvp = common.apr_q6_cvp;
2513
2514 if (!apr_cvp) {
2515 pr_err("%s: apr_cvp is NULL.\n", __func__);
2516 return -EINVAL;
2517 }
2518 cvp_handle = voice_get_cvp_handle(v);
2519
2520 /* send volume index to cvp */
2521 cvp_vol_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2522 APR_HDR_LEN(APR_HDR_SIZE),
2523 APR_PKT_VER);
2524 cvp_vol_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2525 sizeof(cvp_vol_cmd) - APR_HDR_SIZE);
2526 cvp_vol_cmd.hdr.src_port = v->session_id;
2527 cvp_vol_cmd.hdr.dest_port = cvp_handle;
2528 cvp_vol_cmd.hdr.token = 0;
2529 cvp_vol_cmd.hdr.opcode = VSS_IVOCPROC_CMD_SET_RX_VOLUME_INDEX;
2530 cvp_vol_cmd.cvp_set_vol_idx.vol_index = v->dev_rx.volume;
2531 v->cvp_state = CMD_STATUS_FAIL;
2532 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_vol_cmd);
2533 if (ret < 0) {
2534 pr_err("Fail in sending RX VOL INDEX\n");
2535 return -EINVAL;
2536 }
2537 ret = wait_event_timeout(v->cvp_wait,
2538 (v->cvp_state == CMD_STATUS_SUCCESS),
2539 msecs_to_jiffies(TIMEOUT_MS));
2540 if (!ret) {
2541 pr_err("%s: wait_event timeout\n", __func__);
2542 return -EINVAL;
2543 }
2544 return 0;
2545}
2546
2547static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode)
2548{
2549 int ret = 0;
2550 void *apr_cvs;
2551 u16 cvs_handle;
2552
2553 struct cvs_start_record_cmd cvs_start_record;
2554
2555 if (v == NULL) {
2556 pr_err("%s: v is NULL\n", __func__);
2557 return -EINVAL;
2558 }
2559 apr_cvs = common.apr_q6_cvs;
2560
2561 if (!apr_cvs) {
2562 pr_err("%s: apr_cvs is NULL.\n", __func__);
2563 return -EINVAL;
2564 }
2565
2566 cvs_handle = voice_get_cvs_handle(v);
2567
2568 if (!v->rec_info.recording) {
2569 cvs_start_record.hdr.hdr_field = APR_HDR_FIELD(
2570 APR_MSG_TYPE_SEQ_CMD,
2571 APR_HDR_LEN(APR_HDR_SIZE),
2572 APR_PKT_VER);
2573 cvs_start_record.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2574 sizeof(cvs_start_record) - APR_HDR_SIZE);
2575 cvs_start_record.hdr.src_port = v->session_id;
2576 cvs_start_record.hdr.dest_port = cvs_handle;
2577 cvs_start_record.hdr.token = 0;
2578 cvs_start_record.hdr.opcode = VSS_ISTREAM_CMD_START_RECORD;
2579
2580 if (rec_mode == VOC_REC_UPLINK) {
2581 cvs_start_record.rec_mode.rx_tap_point =
2582 VSS_TAP_POINT_NONE;
2583 cvs_start_record.rec_mode.tx_tap_point =
2584 VSS_TAP_POINT_STREAM_END;
2585 } else if (rec_mode == VOC_REC_DOWNLINK) {
2586 cvs_start_record.rec_mode.rx_tap_point =
2587 VSS_TAP_POINT_STREAM_END;
2588 cvs_start_record.rec_mode.tx_tap_point =
2589 VSS_TAP_POINT_NONE;
2590 } else if (rec_mode == VOC_REC_BOTH) {
2591 cvs_start_record.rec_mode.rx_tap_point =
2592 VSS_TAP_POINT_STREAM_END;
2593 cvs_start_record.rec_mode.tx_tap_point =
2594 VSS_TAP_POINT_STREAM_END;
2595 } else {
2596 pr_err("%s: Invalid in-call rec_mode %d\n", __func__,
2597 rec_mode);
2598
2599 ret = -EINVAL;
2600 goto fail;
2601 }
2602
2603 v->cvs_state = CMD_STATUS_FAIL;
2604
2605 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_start_record);
2606 if (ret < 0) {
2607 pr_err("%s: Error %d sending START_RECORD\n", __func__,
2608 ret);
2609
2610 goto fail;
2611 }
2612
2613 ret = wait_event_timeout(v->cvs_wait,
2614 (v->cvs_state == CMD_STATUS_SUCCESS),
2615 msecs_to_jiffies(TIMEOUT_MS));
2616
2617 if (!ret) {
2618 pr_err("%s: wait_event timeout\n", __func__);
2619
2620 goto fail;
2621 }
2622 v->rec_info.recording = 1;
2623 } else {
2624 pr_debug("%s: Start record already sent\n", __func__);
2625 }
2626
2627 return 0;
2628
2629fail:
2630 return ret;
2631}
2632
2633static int voice_cvs_stop_record(struct voice_data *v)
2634{
2635 int ret = 0;
2636 void *apr_cvs;
2637 u16 cvs_handle;
2638 struct apr_hdr cvs_stop_record;
2639
2640 if (v == NULL) {
2641 pr_err("%s: v is NULL\n", __func__);
2642 return -EINVAL;
2643 }
2644 apr_cvs = common.apr_q6_cvs;
2645
2646 if (!apr_cvs) {
2647 pr_err("%s: apr_cvs is NULL.\n", __func__);
2648 return -EINVAL;
2649 }
2650
2651 cvs_handle = voice_get_cvs_handle(v);
2652
2653 if (v->rec_info.recording) {
2654 cvs_stop_record.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2655 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2656 cvs_stop_record.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2657 sizeof(cvs_stop_record) - APR_HDR_SIZE);
2658 cvs_stop_record.src_port = v->session_id;
2659 cvs_stop_record.dest_port = cvs_handle;
2660 cvs_stop_record.token = 0;
2661 cvs_stop_record.opcode = VSS_ISTREAM_CMD_STOP_RECORD;
2662
2663 v->cvs_state = CMD_STATUS_FAIL;
2664
2665 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_stop_record);
2666 if (ret < 0) {
2667 pr_err("%s: Error %d sending STOP_RECORD\n",
2668 __func__, ret);
2669
2670 goto fail;
2671 }
2672
2673 ret = wait_event_timeout(v->cvs_wait,
2674 (v->cvs_state == CMD_STATUS_SUCCESS),
2675 msecs_to_jiffies(TIMEOUT_MS));
2676 if (!ret) {
2677 pr_err("%s: wait_event timeout\n", __func__);
2678
2679 goto fail;
2680 }
2681 v->rec_info.recording = 0;
2682 } else {
2683 pr_debug("%s: Stop record already sent\n", __func__);
2684 }
2685
2686 return 0;
2687
2688fail:
2689
2690 return ret;
2691}
2692
2693int voc_start_record(uint32_t port_id, uint32_t set)
2694{
2695 int ret = 0;
2696 int rec_mode = 0;
2697 u16 cvs_handle;
2698 int i, rec_set = 0;
2699
2700 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
2701 struct voice_data *v = &common.voice[i];
2702 pr_debug("%s: i:%d port_id: %d, set: %d\n",
2703 __func__, i, port_id, set);
2704
2705 mutex_lock(&v->lock);
2706 rec_mode = v->rec_info.rec_mode;
2707 rec_set = set;
2708 if (set) {
2709 if ((v->rec_route_state.ul_flag != 0) &&
2710 (v->rec_route_state.dl_flag != 0)) {
2711 pr_debug("%s: i=%d, rec mode already set.\n",
2712 __func__, i);
2713 mutex_unlock(&v->lock);
2714 if (i < MAX_VOC_SESSIONS)
2715 continue;
2716 else
2717 return 0;
2718 }
2719
2720 if (port_id == VOICE_RECORD_TX) {
2721 if ((v->rec_route_state.ul_flag == 0)
2722 && (v->rec_route_state.dl_flag == 0)) {
2723 rec_mode = VOC_REC_UPLINK;
2724 v->rec_route_state.ul_flag = 1;
2725 } else if ((v->rec_route_state.ul_flag == 0)
2726 && (v->rec_route_state.dl_flag != 0)) {
2727 voice_cvs_stop_record(v);
2728 rec_mode = VOC_REC_BOTH;
2729 v->rec_route_state.ul_flag = 1;
2730 }
2731 } else if (port_id == VOICE_RECORD_RX) {
2732 if ((v->rec_route_state.ul_flag == 0)
2733 && (v->rec_route_state.dl_flag == 0)) {
2734 rec_mode = VOC_REC_DOWNLINK;
2735 v->rec_route_state.dl_flag = 1;
2736 } else if ((v->rec_route_state.ul_flag != 0)
2737 && (v->rec_route_state.dl_flag == 0)) {
2738 voice_cvs_stop_record(v);
2739 rec_mode = VOC_REC_BOTH;
2740 v->rec_route_state.dl_flag = 1;
2741 }
2742 }
2743 rec_set = 1;
2744 } else {
2745 if ((v->rec_route_state.ul_flag == 0) &&
2746 (v->rec_route_state.dl_flag == 0)) {
2747 pr_debug("%s: i=%d, rec already stops.\n",
2748 __func__, i);
2749 mutex_unlock(&v->lock);
2750 if (i < MAX_VOC_SESSIONS)
2751 continue;
2752 else
2753 return 0;
2754 }
2755
2756 if (port_id == VOICE_RECORD_TX) {
2757 if ((v->rec_route_state.ul_flag != 0)
2758 && (v->rec_route_state.dl_flag == 0)) {
2759 v->rec_route_state.ul_flag = 0;
2760 rec_set = 0;
2761 } else if ((v->rec_route_state.ul_flag != 0)
2762 && (v->rec_route_state.dl_flag != 0)) {
2763 voice_cvs_stop_record(v);
2764 v->rec_route_state.ul_flag = 0;
2765 rec_mode = VOC_REC_DOWNLINK;
2766 rec_set = 1;
2767 }
2768 } else if (port_id == VOICE_RECORD_RX) {
2769 if ((v->rec_route_state.ul_flag == 0)
2770 && (v->rec_route_state.dl_flag != 0)) {
2771 v->rec_route_state.dl_flag = 0;
2772 rec_set = 0;
2773 } else if ((v->rec_route_state.ul_flag != 0)
2774 && (v->rec_route_state.dl_flag != 0)) {
2775 voice_cvs_stop_record(v);
2776 v->rec_route_state.dl_flag = 0;
2777 rec_mode = VOC_REC_UPLINK;
2778 rec_set = 1;
2779 }
2780 }
2781 }
2782 pr_debug("%s: i=%d, mode =%d, set =%d\n", __func__,
2783 i, rec_mode, rec_set);
2784 cvs_handle = voice_get_cvs_handle(v);
2785
2786 if (cvs_handle != 0) {
2787 if (rec_set)
2788 ret = voice_cvs_start_record(v, rec_mode);
2789 else
2790 ret = voice_cvs_stop_record(v);
2791 }
2792
2793 /* Cache the value */
2794 v->rec_info.rec_enable = rec_set;
2795 v->rec_info.rec_mode = rec_mode;
2796
2797 mutex_unlock(&v->lock);
2798 }
2799
2800 return ret;
2801}
2802
2803static int voice_cvs_start_playback(struct voice_data *v)
2804{
2805 int ret = 0;
2806 struct apr_hdr cvs_start_playback;
2807 void *apr_cvs;
2808 u16 cvs_handle;
2809
2810 if (v == NULL) {
2811 pr_err("%s: v is NULL\n", __func__);
2812 return -EINVAL;
2813 }
2814 apr_cvs = common.apr_q6_cvs;
2815
2816 if (!apr_cvs) {
2817 pr_err("%s: apr_cvs is NULL.\n", __func__);
2818 return -EINVAL;
2819 }
2820
2821 cvs_handle = voice_get_cvs_handle(v);
2822
2823 if (!v->music_info.playing && v->music_info.count) {
2824 cvs_start_playback.hdr_field = APR_HDR_FIELD(
2825 APR_MSG_TYPE_SEQ_CMD,
2826 APR_HDR_LEN(APR_HDR_SIZE),
2827 APR_PKT_VER);
2828 cvs_start_playback.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2829 sizeof(cvs_start_playback) - APR_HDR_SIZE);
2830 cvs_start_playback.src_port = v->session_id;
2831 cvs_start_playback.dest_port = cvs_handle;
2832 cvs_start_playback.token = 0;
2833 cvs_start_playback.opcode = VSS_ISTREAM_CMD_START_PLAYBACK;
2834
2835 v->cvs_state = CMD_STATUS_FAIL;
2836
2837 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_start_playback);
2838
2839 if (ret < 0) {
2840 pr_err("%s: Error %d sending START_PLAYBACK\n",
2841 __func__, ret);
2842
2843 goto fail;
2844 }
2845
2846 ret = wait_event_timeout(v->cvs_wait,
2847 (v->cvs_state == CMD_STATUS_SUCCESS),
2848 msecs_to_jiffies(TIMEOUT_MS));
2849 if (!ret) {
2850 pr_err("%s: wait_event timeout\n", __func__);
2851
2852 goto fail;
2853 }
2854
2855 v->music_info.playing = 1;
2856 } else {
2857 pr_debug("%s: Start playback already sent\n", __func__);
2858 }
2859
2860 return 0;
2861
2862fail:
2863 return ret;
2864}
2865
2866static int voice_cvs_stop_playback(struct voice_data *v)
2867{
2868 int ret = 0;
2869 struct apr_hdr cvs_stop_playback;
2870 void *apr_cvs;
2871 u16 cvs_handle;
2872
2873 if (v == NULL) {
2874 pr_err("%s: v is NULL\n", __func__);
2875 return -EINVAL;
2876 }
2877 apr_cvs = common.apr_q6_cvs;
2878
2879 if (!apr_cvs) {
2880 pr_err("%s: apr_cvs is NULL.\n", __func__);
2881 return -EINVAL;
2882 }
2883
2884 cvs_handle = voice_get_cvs_handle(v);
2885
2886 if (v->music_info.playing && ((!v->music_info.count) ||
2887 (v->music_info.force))) {
2888 cvs_stop_playback.hdr_field =
2889 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2890 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2891 cvs_stop_playback.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2892 sizeof(cvs_stop_playback) - APR_HDR_SIZE);
2893 cvs_stop_playback.src_port = v->session_id;
2894 cvs_stop_playback.dest_port = cvs_handle;
2895 cvs_stop_playback.token = 0;
2896
2897 cvs_stop_playback.opcode = VSS_ISTREAM_CMD_STOP_PLAYBACK;
2898
2899 v->cvs_state = CMD_STATUS_FAIL;
2900
2901 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_stop_playback);
2902 if (ret < 0) {
2903 pr_err("%s: Error %d sending STOP_PLAYBACK\n",
2904 __func__, ret);
2905
2906
2907 goto fail;
2908 }
2909
2910 ret = wait_event_timeout(v->cvs_wait,
2911 (v->cvs_state == CMD_STATUS_SUCCESS),
2912 msecs_to_jiffies(TIMEOUT_MS));
2913 if (!ret) {
2914 pr_err("%s: wait_event timeout\n", __func__);
2915
2916 goto fail;
2917 }
2918
2919 v->music_info.playing = 0;
2920 v->music_info.force = 0;
2921 } else {
2922 pr_debug("%s: Stop playback already sent\n", __func__);
2923 }
2924
2925 return 0;
2926
2927fail:
2928 return ret;
2929}
2930
2931int voc_start_playback(uint32_t set)
2932{
2933 int ret = 0;
2934 u16 cvs_handle;
2935 int i;
2936
2937
2938 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
2939 struct voice_data *v = &common.voice[i];
2940
2941 mutex_lock(&v->lock);
2942 v->music_info.play_enable = set;
2943 if (set)
2944 v->music_info.count++;
2945 else
2946 v->music_info.count--;
2947 pr_debug("%s: music_info count =%d\n", __func__,
2948 v->music_info.count);
2949
2950 cvs_handle = voice_get_cvs_handle(v);
2951 if (cvs_handle != 0) {
2952 if (set)
2953 ret = voice_cvs_start_playback(v);
2954 else
2955 ret = voice_cvs_stop_playback(v);
2956 }
2957
2958 mutex_unlock(&v->lock);
2959 }
2960
2961 return ret;
2962}
2963
2964int voc_disable_cvp(uint16_t session_id)
2965{
2966 struct voice_data *v = voice_get_session(session_id);
2967 int ret = 0;
2968
2969 if (v == NULL) {
2970 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2971
2972 return -EINVAL;
2973 }
2974
2975 mutex_lock(&v->lock);
2976
2977 if (v->voc_state == VOC_RUN) {
2978 if (v->dev_tx.port_id != RT_PROXY_PORT_001_TX &&
2979 v->dev_rx.port_id != RT_PROXY_PORT_001_RX)
2980 afe_sidetone(v->dev_tx.port_id, v->dev_rx.port_id,
2981 0, 0);
2982
2983 rtac_remove_voice(voice_get_cvs_handle(v));
2984 /* send cmd to dsp to disable vocproc */
2985 ret = voice_send_disable_vocproc_cmd(v);
2986 if (ret < 0) {
2987 pr_err("%s: disable vocproc failed\n", __func__);
2988 goto fail;
2989 }
2990
2991 /* deregister cvp and vol cal */
2992 voice_send_cvp_deregister_vol_cal_table_cmd(v);
2993 voice_send_cvp_deregister_cal_cmd(v);
2994 voice_send_cvp_unmap_memory_cmd(v);
2995
2996 v->voc_state = VOC_CHANGE;
2997 }
2998
2999fail: mutex_unlock(&v->lock);
3000
3001 return ret;
3002}
3003
3004int voc_enable_cvp(uint16_t session_id)
3005{
3006 struct voice_data *v = voice_get_session(session_id);
3007 struct sidetone_cal sidetone_cal_data;
3008 int ret = 0;
3009
3010 if (v == NULL) {
3011 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3012
3013 return -EINVAL;
3014 }
3015
3016 mutex_lock(&v->lock);
3017
3018 if (v->voc_state == VOC_CHANGE) {
3019 ret = voice_send_set_device_cmd(v);
3020 if (ret < 0) {
3021 pr_err("%s: set device failed\n", __func__);
3022 goto fail;
3023 }
3024 /* send cvp and vol cal */
3025 ret = voice_send_cvp_map_memory_cmd(v);
3026 if (!ret) {
3027 voice_send_cvp_register_cal_cmd(v);
3028 voice_send_cvp_register_vol_cal_table_cmd(v);
3029 }
3030 ret = voice_send_enable_vocproc_cmd(v);
3031 if (ret < 0) {
3032 pr_err("%s: enable vocproc failed\n", __func__);
3033 goto fail;
3034
3035 }
3036 /* send tty mode if tty device is used */
3037 voice_send_tty_mode_cmd(v);
3038
3039 /* enable widevoice if wv_enable is set */
3040 if (v->wv_enable)
3041 voice_send_set_widevoice_enable_cmd(v);
3042
3043 /* enable slowtalk */
3044 if (v->st_enable)
3045 voice_send_set_pp_enable_cmd(v,
3046 MODULE_ID_VOICE_MODULE_ST,
3047 v->st_enable);
3048 /* enable FENS */
3049 if (v->fens_enable)
3050 voice_send_set_pp_enable_cmd(v,
3051 MODULE_ID_VOICE_MODULE_FENS,
3052 v->fens_enable);
3053
3054 get_sidetone_cal(&sidetone_cal_data);
3055 if (v->dev_tx.port_id != RT_PROXY_PORT_001_TX &&
3056 v->dev_rx.port_id != RT_PROXY_PORT_001_RX) {
3057 ret = afe_sidetone(v->dev_tx.port_id,
3058 v->dev_rx.port_id,
3059 sidetone_cal_data.enable,
3060 sidetone_cal_data.gain);
3061
3062 if (ret < 0)
3063 pr_err("%s: AFE command sidetone failed\n",
3064 __func__);
3065 }
3066
3067 rtac_add_voice(voice_get_cvs_handle(v),
3068 voice_get_cvp_handle(v),
3069 v->dev_rx.port_id, v->dev_tx.port_id,
3070 v->session_id);
3071 v->voc_state = VOC_RUN;
3072 }
3073
3074fail:
3075 mutex_unlock(&v->lock);
3076
3077 return ret;
3078}
3079
3080int voc_set_tx_mute(uint16_t session_id, uint32_t dir, uint32_t mute)
3081{
3082 struct voice_data *v = voice_get_session(session_id);
3083 int ret = 0;
3084
3085 if (v == NULL) {
3086 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3087
3088 return -EINVAL;
3089 }
3090
3091 mutex_lock(&v->lock);
3092
3093 v->dev_tx.mute = mute;
3094
3095 if (v->voc_state == VOC_RUN)
3096 ret = voice_send_mute_cmd(v);
3097
3098 mutex_unlock(&v->lock);
3099
3100 return ret;
3101}
3102
3103int voc_set_rx_device_mute(uint16_t session_id, uint32_t mute)
3104{
3105 struct voice_data *v = voice_get_session(session_id);
3106 int ret = 0;
3107
3108 if (v == NULL) {
3109 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3110
3111 return -EINVAL;
3112 }
3113
3114 mutex_lock(&v->lock);
3115
3116 v->dev_rx.mute = mute;
3117
3118 if (v->voc_state == VOC_RUN)
3119 ret = voice_send_rx_device_mute_cmd(v);
3120
3121 mutex_unlock(&v->lock);
3122
3123 return ret;
3124}
3125
3126int voc_get_rx_device_mute(uint16_t session_id)
3127{
3128 struct voice_data *v = voice_get_session(session_id);
3129 int ret = 0;
3130
3131 if (v == NULL) {
3132 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3133
3134 return -EINVAL;
3135 }
3136
3137 mutex_lock(&v->lock);
3138
3139 ret = v->dev_rx.mute;
3140
3141 mutex_unlock(&v->lock);
3142
3143 return ret;
3144}
3145
3146int voc_set_tty_mode(uint16_t session_id, uint8_t tty_mode)
3147{
3148 struct voice_data *v = voice_get_session(session_id);
3149 int ret = 0;
3150
3151 if (v == NULL) {
3152 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3153
3154 return -EINVAL;
3155 }
3156
3157 mutex_lock(&v->lock);
3158
3159 v->tty_mode = tty_mode;
3160
3161 mutex_unlock(&v->lock);
3162
3163 return ret;
3164}
3165
3166uint8_t voc_get_tty_mode(uint16_t session_id)
3167{
3168 struct voice_data *v = voice_get_session(session_id);
3169 int ret = 0;
3170
3171 if (v == NULL) {
3172 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3173
3174 return -EINVAL;
3175 }
3176
3177 mutex_lock(&v->lock);
3178
3179 ret = v->tty_mode;
3180
3181 mutex_unlock(&v->lock);
3182
3183 return ret;
3184}
3185
3186int voc_set_widevoice_enable(uint16_t session_id, uint32_t wv_enable)
3187{
3188 struct voice_data *v = voice_get_session(session_id);
3189 u16 mvm_handle;
3190 int ret = 0;
3191
3192 if (v == NULL) {
3193 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3194
3195 return -EINVAL;
3196 }
3197
3198 mutex_lock(&v->lock);
3199
3200 v->wv_enable = wv_enable;
3201
3202 mvm_handle = voice_get_mvm_handle(v);
3203
3204 if (mvm_handle != 0)
3205 voice_send_set_widevoice_enable_cmd(v);
3206
3207 mutex_unlock(&v->lock);
3208
3209 return ret;
3210}
3211
3212uint32_t voc_get_widevoice_enable(uint16_t session_id)
3213{
3214 struct voice_data *v = voice_get_session(session_id);
3215 int ret = 0;
3216
3217 if (v == NULL) {
3218 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3219
3220 return -EINVAL;
3221 }
3222
3223 mutex_lock(&v->lock);
3224
3225 ret = v->wv_enable;
3226
3227 mutex_unlock(&v->lock);
3228
3229 return ret;
3230}
3231
3232int voc_set_pp_enable(uint16_t session_id, uint32_t module_id, uint32_t enable)
3233{
3234 struct voice_data *v = voice_get_session(session_id);
3235 int ret = 0;
3236
3237 if (v == NULL) {
3238 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3239
3240 return -EINVAL;
3241 }
3242
3243 mutex_lock(&v->lock);
3244 if (module_id == MODULE_ID_VOICE_MODULE_ST)
3245 v->st_enable = enable;
3246 else if (module_id == MODULE_ID_VOICE_MODULE_FENS)
3247 v->fens_enable = enable;
3248
3249 if (v->voc_state == VOC_RUN) {
3250 if (module_id == MODULE_ID_VOICE_MODULE_ST)
3251 ret = voice_send_set_pp_enable_cmd(v,
3252 MODULE_ID_VOICE_MODULE_ST,
3253 enable);
3254 else if (module_id == MODULE_ID_VOICE_MODULE_FENS)
3255 ret = voice_send_set_pp_enable_cmd(v,
3256 MODULE_ID_VOICE_MODULE_FENS,
3257 enable);
3258 }
3259 mutex_unlock(&v->lock);
3260
3261 return ret;
3262}
3263
3264int voc_get_pp_enable(uint16_t session_id, uint32_t module_id)
3265{
3266 struct voice_data *v = voice_get_session(session_id);
3267 int ret = 0;
3268
3269 if (v == NULL) {
3270 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3271
3272 return -EINVAL;
3273 }
3274
3275 mutex_lock(&v->lock);
3276 if (module_id == MODULE_ID_VOICE_MODULE_ST)
3277 ret = v->st_enable;
3278 else if (module_id == MODULE_ID_VOICE_MODULE_FENS)
3279 ret = v->fens_enable;
3280
3281 mutex_unlock(&v->lock);
3282
3283 return ret;
3284}
3285
3286int voc_set_rx_vol_index(uint16_t session_id, uint32_t dir, uint32_t vol_idx)
3287{
3288 struct voice_data *v = voice_get_session(session_id);
3289 int ret = 0;
3290
3291 if (v == NULL) {
3292 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3293
3294 return -EINVAL;
3295 }
3296
3297 mutex_lock(&v->lock);
3298
3299 v->dev_rx.volume = vol_idx;
3300
3301 if (v->voc_state == VOC_RUN)
3302 ret = voice_send_vol_index_cmd(v);
3303
3304 mutex_unlock(&v->lock);
3305
3306 return ret;
3307}
3308
3309int voc_set_rxtx_port(uint16_t session_id, uint32_t port_id, uint32_t dev_type)
3310{
3311 struct voice_data *v = voice_get_session(session_id);
3312
3313 if (v == NULL) {
3314 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3315
3316 return -EINVAL;
3317 }
3318
3319 pr_debug("%s: port_id=%d, type=%d\n", __func__, port_id, dev_type);
3320
3321 mutex_lock(&v->lock);
3322
3323 if (dev_type == DEV_RX)
3324 v->dev_rx.port_id = q6audio_get_port_id(port_id);
3325 else
3326 v->dev_tx.port_id = q6audio_get_port_id(port_id);
3327
3328 mutex_unlock(&v->lock);
3329
3330 return 0;
3331}
3332
3333int voc_set_route_flag(uint16_t session_id, uint8_t path_dir, uint8_t set)
3334{
3335 struct voice_data *v = voice_get_session(session_id);
3336
3337 if (v == NULL) {
3338 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3339
3340 return -EINVAL;
3341 }
3342
3343 pr_debug("%s: path_dir=%d, set=%d\n", __func__, path_dir, set);
3344
3345 mutex_lock(&v->lock);
3346
3347 if (path_dir == RX_PATH)
3348 v->voc_route_state.rx_route_flag = set;
3349 else
3350 v->voc_route_state.tx_route_flag = set;
3351
3352 mutex_unlock(&v->lock);
3353
3354 return 0;
3355}
3356
3357uint8_t voc_get_route_flag(uint16_t session_id, uint8_t path_dir)
3358{
3359 struct voice_data *v = voice_get_session(session_id);
3360 int ret = 0;
3361
3362 if (v == NULL) {
3363 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3364
3365 return 0;
3366 }
3367
3368 mutex_lock(&v->lock);
3369
3370 if (path_dir == RX_PATH)
3371 ret = v->voc_route_state.rx_route_flag;
3372 else
3373 ret = v->voc_route_state.tx_route_flag;
3374
3375 mutex_unlock(&v->lock);
3376
3377 return ret;
3378}
3379
3380int voc_end_voice_call(uint16_t session_id)
3381{
3382 struct voice_data *v = voice_get_session(session_id);
3383 int ret = 0;
3384
3385 if (v == NULL) {
3386 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3387
3388 return -EINVAL;
3389 }
3390
3391 mutex_lock(&v->lock);
3392
3393 if (v->voc_state == VOC_RUN) {
3394 if (v->dev_tx.port_id != RT_PROXY_PORT_001_TX &&
3395 v->dev_rx.port_id != RT_PROXY_PORT_001_RX)
3396 afe_sidetone(v->dev_tx.port_id, v->dev_rx.port_id,
3397 0, 0);
3398 ret = voice_destroy_vocproc(v);
3399 if (ret < 0)
3400 pr_err("%s: destroy voice failed\n", __func__);
3401 voice_destroy_mvm_cvs_session(v);
3402
3403 v->voc_state = VOC_RELEASE;
3404 }
3405 mutex_unlock(&v->lock);
3406 return ret;
3407}
3408
3409int voc_start_voice_call(uint16_t session_id)
3410{
3411 struct voice_data *v = voice_get_session(session_id);
3412 struct sidetone_cal sidetone_cal_data;
3413 int ret = 0;
3414
3415 if (v == NULL) {
3416 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3417
3418 return -EINVAL;
3419 }
3420
3421 mutex_lock(&v->lock);
3422
3423 if ((v->voc_state == VOC_INIT) ||
3424 (v->voc_state == VOC_RELEASE)) {
3425 ret = voice_apr_register();
3426 if (ret < 0) {
3427 pr_err("%s: apr register failed\n", __func__);
3428 goto fail;
3429 }
3430 ret = voice_create_mvm_cvs_session(v);
3431 if (ret < 0) {
3432 pr_err("create mvm and cvs failed\n");
3433 goto fail;
3434 }
3435 ret = voice_send_dual_control_cmd(v);
3436 if (ret < 0) {
3437 pr_err("Err Dual command failed\n");
3438 goto fail;
3439 }
3440 ret = voice_setup_vocproc(v);
3441 if (ret < 0) {
3442 pr_err("setup voice failed\n");
3443 goto fail;
3444 }
3445 ret = voice_send_start_voice_cmd(v);
3446 if (ret < 0) {
3447 pr_err("start voice failed\n");
3448 goto fail;
3449 }
3450 get_sidetone_cal(&sidetone_cal_data);
3451 if (v->dev_tx.port_id != RT_PROXY_PORT_001_TX &&
3452 v->dev_rx.port_id != RT_PROXY_PORT_001_RX) {
3453 ret = afe_sidetone(v->dev_tx.port_id,
3454 v->dev_rx.port_id,
3455 sidetone_cal_data.enable,
3456 sidetone_cal_data.gain);
3457 if (ret < 0)
3458 pr_err("AFE command sidetone failed\n");
3459 }
3460
3461 v->voc_state = VOC_RUN;
3462 }
3463fail: mutex_unlock(&v->lock);
3464 return ret;
3465}
3466
3467void voc_register_mvs_cb(ul_cb_fn ul_cb,
3468 dl_cb_fn dl_cb,
3469 void *private_data)
3470{
3471 common.mvs_info.ul_cb = ul_cb;
3472 common.mvs_info.dl_cb = dl_cb;
3473 common.mvs_info.private_data = private_data;
3474}
3475
3476void voc_config_vocoder(uint32_t media_type,
3477 uint32_t rate,
3478 uint32_t network_type,
3479 uint32_t dtx_mode)
3480{
3481 common.mvs_info.media_type = media_type;
3482 common.mvs_info.rate = rate;
3483 common.mvs_info.network_type = network_type;
3484 common.mvs_info.dtx_mode = dtx_mode;
3485}
3486
3487static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv)
3488{
3489 uint32_t *ptr = NULL;
3490 struct common_data *c = NULL;
3491 struct voice_data *v = NULL;
3492 int i = 0;
3493
3494 if ((data == NULL) || (priv == NULL)) {
3495 pr_err("%s: data or priv is NULL\n", __func__);
3496 return -EINVAL;
3497 }
3498
3499 c = priv;
3500
3501 pr_debug("%s: session_id 0x%x\n", __func__, data->dest_port);
3502
3503 v = voice_get_session(data->dest_port);
3504 if (v == NULL) {
3505 pr_err("%s: v is NULL\n", __func__);
3506
3507 return -EINVAL;
3508 }
3509
3510 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
3511 data->payload_size, data->opcode);
3512
3513 if (data->opcode == RESET_EVENTS) {
3514 pr_debug("%s: Reset event received in Voice service\n",
3515 __func__);
3516
3517 apr_reset(c->apr_q6_mvm);
3518 c->apr_q6_mvm = NULL;
3519
3520 /* Sub-system restart is applicable to all sessions. */
3521 for (i = 0; i < MAX_VOC_SESSIONS; i++)
3522 c->voice[i].mvm_handle = 0;
3523
3524 return 0;
3525 }
3526
3527 if (data->opcode == APR_BASIC_RSP_RESULT) {
3528 if (data->payload_size) {
3529 ptr = data->payload;
3530
3531 /* ping mvm service ACK */
3532 switch (ptr[0]) {
3533 case VSS_IMVM_CMD_CREATE_PASSIVE_CONTROL_SESSION:
3534 case VSS_IMVM_CMD_CREATE_FULL_CONTROL_SESSION:
3535 /* Passive session is used for CS call
3536 * Full session is used for VoIP call. */
3537 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
3538 if (!ptr[1]) {
3539 pr_debug("%s: MVM handle is %d\n",
3540 __func__, data->src_port);
3541 voice_set_mvm_handle(v, data->src_port);
3542 } else
3543 pr_err("got NACK for sending MVM create session\n");
3544 v->mvm_state = CMD_STATUS_SUCCESS;
3545 wake_up(&v->mvm_wait);
3546 break;
3547 case VSS_IMVM_CMD_START_VOICE:
3548 case VSS_IMVM_CMD_ATTACH_VOCPROC:
3549 case VSS_IMVM_CMD_STOP_VOICE:
3550 case VSS_IMVM_CMD_DETACH_VOCPROC:
3551 case VSS_ISTREAM_CMD_SET_TTY_MODE:
3552 case APRV2_IBASIC_CMD_DESTROY_SESSION:
3553 case VSS_IMVM_CMD_ATTACH_STREAM:
3554 case VSS_IMVM_CMD_DETACH_STREAM:
3555 case VSS_ICOMMON_CMD_SET_NETWORK:
3556 case VSS_ICOMMON_CMD_SET_VOICE_TIMING:
3557 case VSS_IWIDEVOICE_CMD_SET_WIDEVOICE:
3558 case VSS_IMVM_CMD_SET_POLICY_DUAL_CONTROL:
3559 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
3560 v->mvm_state = CMD_STATUS_SUCCESS;
3561 wake_up(&v->mvm_wait);
3562 break;
3563 default:
3564 pr_debug("%s: not match cmd = 0x%x\n",
3565 __func__, ptr[0]);
3566 break;
3567 }
3568 }
3569 }
3570
3571 return 0;
3572}
3573
3574static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv)
3575{
3576 uint32_t *ptr = NULL;
3577 struct common_data *c = NULL;
3578 struct voice_data *v = NULL;
3579 int i = 0;
3580
3581 if ((data == NULL) || (priv == NULL)) {
3582 pr_err("%s: data or priv is NULL\n", __func__);
3583 return -EINVAL;
3584 }
3585
3586 c = priv;
3587
3588 pr_debug("%s: session_id 0x%x\n", __func__, data->dest_port);
3589
3590 v = voice_get_session(data->dest_port);
3591 if (v == NULL) {
3592 pr_err("%s: v is NULL\n", __func__);
3593
3594 return -EINVAL;
3595 }
3596
3597 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
3598 data->payload_size, data->opcode);
3599
3600 if (data->opcode == RESET_EVENTS) {
3601 pr_debug("%s: Reset event received in Voice service\n",
3602 __func__);
3603
3604 apr_reset(c->apr_q6_cvs);
3605 c->apr_q6_cvs = NULL;
3606
3607 /* Sub-system restart is applicable to all sessions. */
3608 for (i = 0; i < MAX_VOC_SESSIONS; i++)
3609 c->voice[i].cvs_handle = 0;
3610
3611 return 0;
3612 }
3613
3614 if (data->opcode == APR_BASIC_RSP_RESULT) {
3615 if (data->payload_size) {
3616 ptr = data->payload;
3617
3618 /*response from CVS */
3619 switch (ptr[0]) {
3620 case VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION:
3621 case VSS_ISTREAM_CMD_CREATE_FULL_CONTROL_SESSION:
3622 if (!ptr[1]) {
3623 pr_debug("%s: CVS handle is %d\n",
3624 __func__, data->src_port);
3625 voice_set_cvs_handle(v, data->src_port);
3626 } else
3627 pr_err("got NACK for sending CVS create session\n");
3628 v->cvs_state = CMD_STATUS_SUCCESS;
3629 wake_up(&v->cvs_wait);
3630 break;
3631 case VSS_ISTREAM_CMD_SET_MUTE:
3632 case VSS_ISTREAM_CMD_SET_MEDIA_TYPE:
3633 case VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE:
3634 case VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE:
3635 case VSS_ISTREAM_CMD_SET_ENC_DTX_MODE:
3636 case VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE:
3637 case APRV2_IBASIC_CMD_DESTROY_SESSION:
3638 case VSS_ISTREAM_CMD_REGISTER_CALIBRATION_DATA:
3639 case VSS_ISTREAM_CMD_DEREGISTER_CALIBRATION_DATA:
3640 case VSS_ICOMMON_CMD_MAP_MEMORY:
3641 case VSS_ICOMMON_CMD_UNMAP_MEMORY:
3642 case VSS_ICOMMON_CMD_SET_UI_PROPERTY:
3643 case VSS_ISTREAM_CMD_START_PLAYBACK:
3644 case VSS_ISTREAM_CMD_STOP_PLAYBACK:
3645 case VSS_ISTREAM_CMD_START_RECORD:
3646 case VSS_ISTREAM_CMD_STOP_RECORD:
3647 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
3648 v->cvs_state = CMD_STATUS_SUCCESS;
3649 wake_up(&v->cvs_wait);
3650 break;
3651 case VOICE_CMD_SET_PARAM:
3652 rtac_make_voice_callback(RTAC_CVS, ptr,
3653 data->payload_size);
3654 break;
3655 default:
3656 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
3657 break;
3658 }
3659 }
3660 } else if (data->opcode == VSS_ISTREAM_EVT_SEND_ENC_BUFFER) {
3661 uint32_t *voc_pkt = data->payload;
3662 uint32_t pkt_len = data->payload_size;
3663
3664 if (voc_pkt != NULL && c->mvs_info.ul_cb != NULL) {
3665 pr_debug("%s: Media type is 0x%x\n",
3666 __func__, voc_pkt[0]);
3667
3668 /* Remove media ID from payload. */
3669 voc_pkt++;
3670 pkt_len = pkt_len - 4;
3671
3672 c->mvs_info.ul_cb((uint8_t *)voc_pkt,
3673 pkt_len,
3674 c->mvs_info.private_data);
3675 } else
3676 pr_err("%s: voc_pkt is 0x%x ul_cb is 0x%x\n",
3677 __func__, (unsigned int)voc_pkt,
3678 (unsigned int) c->mvs_info.ul_cb);
3679 } else if (data->opcode == VSS_ISTREAM_EVT_REQUEST_DEC_BUFFER) {
3680 struct cvs_send_dec_buf_cmd send_dec_buf;
3681 int ret = 0;
3682 uint32_t pkt_len = 0;
3683
3684 if (c->mvs_info.dl_cb != NULL) {
3685 send_dec_buf.dec_buf.media_id = c->mvs_info.media_type;
3686
3687 c->mvs_info.dl_cb(
3688 (uint8_t *)&send_dec_buf.dec_buf.packet_data,
3689 &pkt_len,
3690 c->mvs_info.private_data);
3691
3692 send_dec_buf.hdr.hdr_field =
3693 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
3694 APR_HDR_LEN(APR_HDR_SIZE),
3695 APR_PKT_VER);
3696 send_dec_buf.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
3697 sizeof(send_dec_buf.dec_buf.media_id) + pkt_len);
3698 send_dec_buf.hdr.src_port = v->session_id;
3699 send_dec_buf.hdr.dest_port = voice_get_cvs_handle(v);
3700 send_dec_buf.hdr.token = 0;
3701 send_dec_buf.hdr.opcode =
3702 VSS_ISTREAM_EVT_SEND_DEC_BUFFER;
3703
3704 ret = apr_send_pkt(c->apr_q6_cvs,
3705 (uint32_t *) &send_dec_buf);
3706 if (ret < 0) {
3707 pr_err("%s: Error %d sending DEC_BUF\n",
3708 __func__, ret);
3709 goto fail;
3710 }
3711 } else
3712 pr_debug("%s: dl_cb is NULL\n", __func__);
3713 } else if (data->opcode == VSS_ISTREAM_EVT_SEND_DEC_BUFFER) {
3714 pr_debug("Send dec buf resp\n");
3715 } else if (data->opcode == VOICE_EVT_GET_PARAM_ACK) {
3716 rtac_make_voice_callback(RTAC_CVS, data->payload,
3717 data->payload_size);
3718 } else
3719 pr_debug("Unknown opcode 0x%x\n", data->opcode);
3720
3721fail:
3722 return 0;
3723}
3724
3725static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv)
3726{
3727 uint32_t *ptr = NULL;
3728 struct common_data *c = NULL;
3729 struct voice_data *v = NULL;
3730 int i = 0;
3731
3732 if ((data == NULL) || (priv == NULL)) {
3733 pr_err("%s: data or priv is NULL\n", __func__);
3734 return -EINVAL;
3735 }
3736
3737 c = priv;
3738
3739 v = voice_get_session(data->dest_port);
3740 if (v == NULL) {
3741 pr_err("%s: v is NULL\n", __func__);
3742
3743 return -EINVAL;
3744 }
3745
3746 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
3747 data->payload_size, data->opcode);
3748
3749 if (data->opcode == RESET_EVENTS) {
3750 pr_debug("%s: Reset event received in Voice service\n",
3751 __func__);
3752
3753 apr_reset(c->apr_q6_cvp);
3754 c->apr_q6_cvp = NULL;
3755
3756 /* Sub-system restart is applicable to all sessions. */
3757 for (i = 0; i < MAX_VOC_SESSIONS; i++)
3758 c->voice[i].cvp_handle = 0;
3759
3760 return 0;
3761 }
3762
3763 if (data->opcode == APR_BASIC_RSP_RESULT) {
3764 if (data->payload_size) {
3765 ptr = data->payload;
3766
3767 switch (ptr[0]) {
3768 case VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION:
3769 /*response from CVP */
3770 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
3771 if (!ptr[1]) {
3772 voice_set_cvp_handle(v, data->src_port);
3773 pr_debug("cvphdl=%d\n", data->src_port);
3774 } else
3775 pr_err("got NACK from CVP create session response\n");
3776 v->cvp_state = CMD_STATUS_SUCCESS;
3777 wake_up(&v->cvp_wait);
3778 break;
3779 case VSS_IVOCPROC_CMD_SET_DEVICE:
3780 case VSS_IVOCPROC_CMD_SET_RX_VOLUME_INDEX:
3781 case VSS_IVOCPROC_CMD_ENABLE:
3782 case VSS_IVOCPROC_CMD_DISABLE:
3783 case APRV2_IBASIC_CMD_DESTROY_SESSION:
3784 case VSS_IVOCPROC_CMD_REGISTER_VOLUME_CAL_TABLE:
3785 case VSS_IVOCPROC_CMD_DEREGISTER_VOLUME_CAL_TABLE:
3786 case VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA:
3787 case VSS_IVOCPROC_CMD_DEREGISTER_CALIBRATION_DATA:
3788 case VSS_ICOMMON_CMD_MAP_MEMORY:
3789 case VSS_ICOMMON_CMD_UNMAP_MEMORY:
3790 case VSS_IVOCPROC_CMD_SET_MUTE:
3791 v->cvp_state = CMD_STATUS_SUCCESS;
3792 wake_up(&v->cvp_wait);
3793 break;
3794 case VOICE_CMD_SET_PARAM:
3795 rtac_make_voice_callback(RTAC_CVP, ptr,
3796 data->payload_size);
3797 break;
3798 default:
3799 pr_debug("%s: not match cmd = 0x%x\n",
3800 __func__, ptr[0]);
3801 break;
3802 }
3803 }
3804 } else if (data->opcode == VOICE_EVT_GET_PARAM_ACK) {
3805 rtac_make_voice_callback(RTAC_CVP, data->payload,
3806 data->payload_size);
3807 }
3808 return 0;
3809}
3810
3811
3812static int __init voice_init(void)
3813{
3814 int rc = 0, i = 0;
3815 int len;
3816
3817 memset(&common, 0, sizeof(struct common_data));
3818
3819 /* Allocate memory for VoIP calibration */
3820 common.client = msm_ion_client_create(UINT_MAX, "voip_client");
3821 if (IS_ERR_OR_NULL((void *)common.client)) {
3822 pr_err("%s: ION create client for Voip failed\n", __func__);
3823 goto cont;
3824 }
3825 common.cvp_cal.handle = ion_alloc(common.client, CVP_CAL_SIZE, SZ_4K,
Hanumant Singh2ac41c92012-08-29 18:39:44 -07003826 ION_HEAP(ION_AUDIO_HEAP_ID), 0);
Phani Kumar Uppalapati4fbf4c42012-05-21 20:35:45 -07003827 if (IS_ERR_OR_NULL((void *) common.cvp_cal.handle)) {
3828 pr_err("%s: ION memory allocation for CVP failed\n",
3829 __func__);
3830 ion_client_destroy(common.client);
3831 goto cont;
3832 }
3833
3834 rc = ion_phys(common.client, common.cvp_cal.handle,
3835 (ion_phys_addr_t *)&common.cvp_cal.phy, (size_t *)&len);
3836 if (rc) {
3837 pr_err("%s: ION Get Physical for cvp failed, rc = %d\n",
3838 __func__, rc);
3839 ion_free(common.client, common.cvp_cal.handle);
3840 ion_client_destroy(common.client);
3841 goto cont;
3842 }
3843
3844 common.cvp_cal.buf = ion_map_kernel(common.client,
3845 common.cvp_cal.handle, 0);
3846 if (IS_ERR_OR_NULL((void *) common.cvp_cal.buf)) {
3847 pr_err("%s: ION memory mapping for cvp failed\n", __func__);
3848 common.cvp_cal.buf = NULL;
3849 ion_free(common.client, common.cvp_cal.handle);
3850 ion_client_destroy(common.client);
3851 goto cont;
3852 }
3853 memset((void *)common.cvp_cal.buf, 0, CVP_CAL_SIZE);
3854
3855 common.cvs_cal.handle = ion_alloc(common.client, CVS_CAL_SIZE, SZ_4K,
Hanumant Singh2ac41c92012-08-29 18:39:44 -07003856 ION_HEAP(ION_AUDIO_HEAP_ID), 0);
Phani Kumar Uppalapati4fbf4c42012-05-21 20:35:45 -07003857 if (IS_ERR_OR_NULL((void *) common.cvs_cal.handle)) {
3858 pr_err("%s: ION memory allocation for CVS failed\n",
3859 __func__);
3860 goto cont;
3861 }
3862
3863 rc = ion_phys(common.client, common.cvs_cal.handle,
3864 (ion_phys_addr_t *)&common.cvs_cal.phy, (size_t *)&len);
3865 if (rc) {
3866 pr_err("%s: ION Get Physical for cvs failed, rc = %d\n",
3867 __func__, rc);
3868 ion_free(common.client, common.cvs_cal.handle);
3869 goto cont;
3870 }
3871
3872 common.cvs_cal.buf = ion_map_kernel(common.client,
3873 common.cvs_cal.handle, 0);
3874 if (IS_ERR_OR_NULL((void *) common.cvs_cal.buf)) {
3875 pr_err("%s: ION memory mapping for cvs failed\n", __func__);
3876 common.cvs_cal.buf = NULL;
3877 ion_free(common.client, common.cvs_cal.handle);
3878 goto cont;
3879 }
3880 memset((void *)common.cvs_cal.buf, 0, CVS_CAL_SIZE);
3881cont:
3882 /* set default value */
3883 common.default_mute_val = 1; /* default is mute */
3884 common.default_vol_val = 0;
3885 common.default_sample_val = 8000;
3886
3887 /* Initialize MVS info. */
3888 common.mvs_info.network_type = VSS_NETWORK_ID_DEFAULT;
3889
3890 mutex_init(&common.common_lock);
3891
3892 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
3893 common.voice[i].session_id = SESSION_ID_BASE + i;
3894
3895 /* initialize dev_rx and dev_tx */
3896 common.voice[i].dev_rx.volume = common.default_vol_val;
3897 common.voice[i].dev_rx.mute = 0;
3898 common.voice[i].dev_tx.mute = common.default_mute_val;
3899
3900 common.voice[i].dev_tx.port_id = 0x100B;
3901 common.voice[i].dev_rx.port_id = 0x100A;
3902 common.voice[i].sidetone_gain = 0x512;
3903
3904 common.voice[i].voc_state = VOC_INIT;
3905
3906 init_waitqueue_head(&common.voice[i].mvm_wait);
3907 init_waitqueue_head(&common.voice[i].cvs_wait);
3908 init_waitqueue_head(&common.voice[i].cvp_wait);
3909
3910 mutex_init(&common.voice[i].lock);
3911 }
3912
3913 return rc;
3914}
3915
3916device_initcall(voice_init);