blob: 28d1acf04957ca2451b39468a9fe48e85c5b6b7f [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Copyright (c) 2011, 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#include <mach/qdsp6v2/audio_acdb.h>
20#include "sound/apr_audio.h"
21#include "sound/q6afe.h"
22#include "q6voice.h"
23
24#define TIMEOUT_MS 3000
25
26#define CMD_STATUS_SUCCESS 0
27#define CMD_STATUS_FAIL 1
28
29#define VOC_PATH_PASSIVE 0
30#define VOC_PATH_FULL 1
31
32static struct voice_data voice;
33
34static int voice_send_enable_vocproc_cmd(struct voice_data *v);
35static int voice_send_netid_timing_cmd(struct voice_data *v);
36static int voice_send_attach_vocproc_cmd(struct voice_data *v);
37static int voice_send_set_device_cmd(struct voice_data *v);
38static int voice_send_disable_vocproc_cmd(struct voice_data *v);
39static int voice_send_vol_index_cmd(struct voice_data *v);
40
41static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv);
42static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv);
43static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv);
44
45static u16 voice_get_mvm_handle(struct voice_data *v)
46{
47 u16 mvm_handle = 0;
48
49 if (v == NULL) {
50 pr_err("%s: v is NULL\n", __func__);
51 return -EINVAL;
52 }
53 if (v->voc_path == VOC_PATH_PASSIVE)
54 mvm_handle = v->mvm_passive_handle;
55 else
56 mvm_handle = v->mvm_full_handle;
57
58 pr_debug("%s: mvm_handle %d\n", __func__, mvm_handle);
59
60 return mvm_handle;
61}
62
63static void voice_set_mvm_handle(struct voice_data *v, u16 mvm_handle)
64{
65 pr_debug("%s: mvm_handle %d\n", __func__, mvm_handle);
66 if (v == NULL) {
67 pr_err("%s: v is NULL\n", __func__);
68 return;
69 }
70
71 if (v->voc_path == VOC_PATH_PASSIVE)
72 v->mvm_passive_handle = mvm_handle;
73 else
74 v->mvm_full_handle = mvm_handle;
75}
76
77static u16 voice_get_cvs_handle(struct voice_data *v)
78{
79 u16 cvs_handle = 0;
80
81 if (v == NULL) {
82 pr_err("%s: v is NULL\n", __func__);
83 return -EINVAL;
84 }
85 if (v->voc_path == VOC_PATH_PASSIVE)
86 cvs_handle = v->cvs_passive_handle;
87 else
88 cvs_handle = v->cvs_full_handle;
89
90 pr_debug("%s: cvs_handle %d\n", __func__, cvs_handle);
91
92 return cvs_handle;
93}
94
95static void voice_set_cvs_handle(struct voice_data *v, u16 cvs_handle)
96{
97 pr_debug("%s: cvs_handle %d\n", __func__, cvs_handle);
98 if (v == NULL) {
99 pr_err("%s: v is NULL\n", __func__);
100 return;
101 }
102 if (v->voc_path == VOC_PATH_PASSIVE)
103 v->cvs_passive_handle = cvs_handle;
104 else
105 v->cvs_full_handle = cvs_handle;
106}
107
108static u16 voice_get_cvp_handle(struct voice_data *v)
109{
110 u16 cvp_handle = 0;
111
112 if (v->voc_path == VOC_PATH_PASSIVE)
113 cvp_handle = v->cvp_passive_handle;
114 else
115 cvp_handle = v->cvp_full_handle;
116
117 pr_debug("%s: cvp_handle %d\n", __func__, cvp_handle);
118
119 return cvp_handle;
120}
121
122static void voice_set_cvp_handle(struct voice_data *v, u16 cvp_handle)
123{
124 pr_debug("%s: cvp_handle %d\n", __func__, cvp_handle);
125 if (v == NULL) {
126 pr_err("%s: v is NULL\n", __func__);
127 return;
128 }
129 if (v->voc_path == VOC_PATH_PASSIVE)
130 v->cvp_passive_handle = cvp_handle;
131 else
132 v->cvp_full_handle = cvp_handle;
133}
134
135static int voice_apr_register(struct voice_data *v)
136{
137 void *apr_mvm, *apr_cvs, *apr_cvp;
138
139 if (v == NULL) {
140 pr_err("%s: v is NULL\n", __func__);
141 return -EINVAL;
142 }
143 apr_mvm = v->apr_q6_mvm;
144 apr_cvs = v->apr_q6_cvs;
145 apr_cvp = v->apr_q6_cvp;
146
147 pr_debug("into voice_apr_register_callback\n");
148 /* register callback to APR */
149 if (apr_mvm == NULL) {
150 pr_debug("start to register MVM callback\n");
151
152 apr_mvm = apr_register("ADSP", "MVM",
153 qdsp_mvm_callback,
154 0xFFFFFFFF, v);
155
156 if (apr_mvm == NULL) {
157 pr_err("Unable to register MVM\n");
158 goto err;
159 }
160 v->apr_q6_mvm = apr_mvm;
161 }
162
163 if (apr_cvs == NULL) {
164 pr_debug("start to register CVS callback\n");
165
166 apr_cvs = apr_register("ADSP", "CVS",
167 qdsp_cvs_callback,
168 0xFFFFFFFF, v);
169
170 if (apr_cvs == NULL) {
171 pr_err("Unable to register CVS\n");
172 goto err;
173 }
174 v->apr_q6_cvs = apr_cvs;
175 }
176
177 if (apr_cvp == NULL) {
178 pr_debug("start to register CVP callback\n");
179
180 apr_cvp = apr_register("ADSP", "CVP",
181 qdsp_cvp_callback,
182 0xFFFFFFFF, v);
183
184 if (apr_cvp == NULL) {
185 pr_err("Unable to register CVP\n");
186 goto err;
187 }
188 v->apr_q6_cvp = apr_cvp;
189 }
190 return 0;
191
192err:
193 if (v->apr_q6_cvs != NULL) {
194 apr_deregister(apr_cvs);
195 v->apr_q6_cvs = NULL;
196 }
197 if (v->apr_q6_mvm != NULL) {
198 apr_deregister(apr_mvm);
199 v->apr_q6_mvm = NULL;
200 }
201
202 return -ENODEV;
203}
204
205static int voice_create_mvm_cvs_session(struct voice_data *v)
206{
207 int ret = 0;
208 struct mvm_create_passive_ctl_session_cmd mvm_session_cmd;
209 struct cvs_create_passive_ctl_session_cmd cvs_session_cmd;
210 struct mvm_create_full_ctl_session_cmd mvm_full_ctl_cmd;
211 struct cvs_create_full_ctl_session_cmd cvs_full_ctl_cmd;
212 struct mvm_attach_stream_cmd attach_stream_cmd;
213 void *apr_mvm, *apr_cvs, *apr_cvp;
214 u16 mvm_handle, cvs_handle, cvp_handle;
215
216 if (v == NULL) {
217 pr_err("%s: v is NULL\n", __func__);
218 return -EINVAL;
219 }
220 apr_mvm = v->apr_q6_mvm;
221 apr_cvs = v->apr_q6_cvs;
222 apr_cvp = v->apr_q6_cvp;
223
224 if (!apr_mvm || !apr_cvs || !apr_cvp) {
225 pr_err("%s: apr_mvm or apr_cvs or apr_cvp is NULL\n", __func__);
226 return -EINVAL;
227 }
228 mvm_handle = voice_get_mvm_handle(v);
229 cvs_handle = voice_get_cvs_handle(v);
230 cvp_handle = voice_get_cvp_handle(v);
231
232 pr_debug("%s: mvm_hdl=%d, cvs_hdl=%d\n", __func__,
233 mvm_handle, cvs_handle);
234 /* send cmd to create mvm session and wait for response */
235
236 if (!mvm_handle) {
237 if (v->voc_path == VOC_PATH_PASSIVE) {
238 mvm_session_cmd.hdr.hdr_field = APR_HDR_FIELD(
239 APR_MSG_TYPE_SEQ_CMD,
240 APR_HDR_LEN(APR_HDR_SIZE),
241 APR_PKT_VER);
242 mvm_session_cmd.hdr.pkt_size = APR_PKT_SIZE(
243 APR_HDR_SIZE,
244 sizeof(mvm_session_cmd) -
245 APR_HDR_SIZE);
246 pr_debug("send mvm create session pkt size = %d\n",
247 mvm_session_cmd.hdr.pkt_size);
248 mvm_session_cmd.hdr.src_port = 0;
249 mvm_session_cmd.hdr.dest_port = 0;
250 mvm_session_cmd.hdr.token = 0;
251 mvm_session_cmd.hdr.opcode =
252 VSS_IMVM_CMD_CREATE_PASSIVE_CONTROL_SESSION;
253 v->mvm_state = CMD_STATUS_FAIL;
254
255 ret = apr_send_pkt(apr_mvm,
256 (uint32_t *) &mvm_session_cmd);
257 if (ret < 0) {
258 pr_err("Error sending MVM_CONTROL_SESSION\n");
259 goto fail;
260 }
261 ret = wait_event_timeout(v->mvm_wait,
262 (v->mvm_state == CMD_STATUS_SUCCESS),
263 msecs_to_jiffies(TIMEOUT_MS));
264 if (!ret) {
265 pr_err("%s: wait_event timeout\n", __func__);
266 goto fail;
267 }
268 } else {
269 pr_debug("%s: creating MVM full ctrl\n", __func__);
270 mvm_full_ctl_cmd.hdr.hdr_field =
271 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
272 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
273 mvm_full_ctl_cmd.hdr.pkt_size =
274 APR_PKT_SIZE(APR_HDR_SIZE,
275 sizeof(mvm_full_ctl_cmd) -
276 APR_HDR_SIZE);
277 mvm_full_ctl_cmd.hdr.src_port = 0;
278 mvm_full_ctl_cmd.hdr.dest_port = 0;
279 mvm_full_ctl_cmd.hdr.token = 0;
280 mvm_full_ctl_cmd.hdr.opcode =
281 VSS_IMVM_CMD_CREATE_FULL_CONTROL_SESSION;
282 strncpy(mvm_full_ctl_cmd.mvm_session.name,
283 "default voip", 12);
284
285 v->mvm_state = CMD_STATUS_FAIL;
286
287 ret = apr_send_pkt(apr_mvm,
288 (uint32_t *) &mvm_full_ctl_cmd);
289 if (ret < 0) {
290 pr_err("Fail in sending MVM_CONTROL_SESSION\n");
291 goto fail;
292 }
293 ret = wait_event_timeout(v->mvm_wait,
294 (v->mvm_state == CMD_STATUS_SUCCESS),
295 msecs_to_jiffies(TIMEOUT_MS));
296 if (!ret) {
297 pr_err("%s: wait_event timeout\n", __func__);
298 goto fail;
299 }
300 }
301 /* Get the created MVM handle. */
302 mvm_handle = voice_get_mvm_handle(v);
303 }
304 /* send cmd to create cvs session */
305 if (!cvs_handle) {
306 if (v->voc_path == VOC_PATH_PASSIVE) {
307 pr_debug("creating CVS passive session\n");
308
309 cvs_session_cmd.hdr.hdr_field = APR_HDR_FIELD(
310 APR_MSG_TYPE_SEQ_CMD,
311 APR_HDR_LEN(APR_HDR_SIZE),
312 APR_PKT_VER);
313 cvs_session_cmd.hdr.pkt_size =
314 APR_PKT_SIZE(APR_HDR_SIZE,
315 sizeof(cvs_session_cmd) -
316 APR_HDR_SIZE);
317 cvs_session_cmd.hdr.src_port = 0;
318 cvs_session_cmd.hdr.dest_port = 0;
319 cvs_session_cmd.hdr.token = 0;
320 cvs_session_cmd.hdr.opcode =
321 VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION;
322 strncpy(cvs_session_cmd.cvs_session.name,
323 "default modem voice", 19);
324
325 v->cvs_state = CMD_STATUS_FAIL;
326
327 ret = apr_send_pkt(apr_cvs,
328 (uint32_t *) &cvs_session_cmd);
329 if (ret < 0) {
330 pr_err("Fail in sending STREAM_CONTROL_SESSION\n");
331 goto fail;
332 }
333 ret = wait_event_timeout(v->cvs_wait,
334 (v->cvs_state == CMD_STATUS_SUCCESS),
335 msecs_to_jiffies(TIMEOUT_MS));
336 if (!ret) {
337 pr_err("%s: wait_event timeout\n", __func__);
338 goto fail;
339 }
340 /* Get the created CVS handle. */
341 cvs_handle = voice_get_cvs_handle(v);
342
343 } else {
344 pr_debug("creating CVS full session\n");
345
346 cvs_full_ctl_cmd.hdr.hdr_field =
347 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
348 APR_HDR_LEN(APR_HDR_SIZE),
349 APR_PKT_VER);
350
351 cvs_full_ctl_cmd.hdr.pkt_size =
352 APR_PKT_SIZE(APR_HDR_SIZE,
353 sizeof(cvs_full_ctl_cmd) -
354 APR_HDR_SIZE);
355
356 cvs_full_ctl_cmd.hdr.src_port = 0;
357 cvs_full_ctl_cmd.hdr.dest_port = 0;
358 cvs_full_ctl_cmd.hdr.token = 0;
359 cvs_full_ctl_cmd.hdr.opcode =
360 VSS_ISTREAM_CMD_CREATE_FULL_CONTROL_SESSION;
361 cvs_full_ctl_cmd.cvs_session.direction = 2;
362 cvs_full_ctl_cmd.cvs_session.enc_media_type =
363 v->mvs_info.media_type;
364 cvs_full_ctl_cmd.cvs_session.dec_media_type =
365 v->mvs_info.media_type;
366 cvs_full_ctl_cmd.cvs_session.network_id =
367 v->mvs_info.network_type;
368 strncpy(cvs_full_ctl_cmd.cvs_session.name,
369 "default q6 voice", 16);
370
371 v->cvs_state = CMD_STATUS_FAIL;
372
373 ret = apr_send_pkt(apr_cvs,
374 (uint32_t *) &cvs_full_ctl_cmd);
375
376 if (ret < 0) {
377 pr_err("%s: Err %d sending CREATE_FULL_CTRL\n",
378 __func__, ret);
379 goto fail;
380 }
381 ret = wait_event_timeout(v->cvs_wait,
382 (v->cvs_state == CMD_STATUS_SUCCESS),
383 msecs_to_jiffies(TIMEOUT_MS));
384 if (!ret) {
385 pr_err("%s: wait_event timeout\n", __func__);
386 goto fail;
387 }
388 /* Get the created CVS handle. */
389 cvs_handle = voice_get_cvs_handle(v);
390
391 /* Attach MVM to CVS. */
392 pr_debug("Attach MVM to stream\n");
393
394 attach_stream_cmd.hdr.hdr_field =
395 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
396 APR_HDR_LEN(APR_HDR_SIZE),
397 APR_PKT_VER);
398 attach_stream_cmd.hdr.pkt_size =
399 APR_PKT_SIZE(APR_HDR_SIZE,
400 sizeof(attach_stream_cmd) -
401 APR_HDR_SIZE);
402 attach_stream_cmd.hdr.src_port = 0;
403 attach_stream_cmd.hdr.dest_port = mvm_handle;
404 attach_stream_cmd.hdr.token = 0;
405 attach_stream_cmd.hdr.opcode =
406 VSS_IMVM_CMD_ATTACH_STREAM;
407 attach_stream_cmd.attach_stream.handle = cvs_handle;
408
409 v->mvm_state = CMD_STATUS_FAIL;
410 ret = apr_send_pkt(apr_mvm,
411 (uint32_t *) &attach_stream_cmd);
412 if (ret < 0) {
413 pr_err("%s: Error %d sending ATTACH_STREAM\n",
414 __func__, ret);
415 goto fail;
416 }
417 ret = wait_event_timeout(v->mvm_wait,
418 (v->mvm_state == CMD_STATUS_SUCCESS),
419 msecs_to_jiffies(TIMEOUT_MS));
420 if (!ret) {
421 pr_err("%s: wait_event timeout\n", __func__);
422 goto fail;
423 }
424 }
425 }
426 return 0;
427
428fail:
429 return -EINVAL;
430}
431
432static int voice_destroy_mvm_cvs_session(struct voice_data *v)
433{
434 int ret = 0;
435 struct mvm_detach_stream_cmd detach_stream;
436 struct apr_hdr mvm_destroy;
437 struct apr_hdr cvs_destroy;
438 void *apr_mvm, *apr_cvs;
439 u16 mvm_handle, cvs_handle;
440
441 if (v == NULL) {
442 pr_err("%s: v is NULL\n", __func__);
443 return -EINVAL;
444 }
445 apr_mvm = v->apr_q6_mvm;
446 apr_cvs = v->apr_q6_cvs;
447
448 if (!apr_mvm || !apr_cvs) {
449 pr_err("%s: apr_mvm or apr_cvs is NULL\n", __func__);
450 return -EINVAL;
451 }
452 mvm_handle = voice_get_mvm_handle(v);
453 cvs_handle = voice_get_cvs_handle(v);
454
455 /* MVM, CVS sessions are destroyed only for Full control sessions. */
456 if (v->voc_path == VOC_PATH_FULL) {
457 pr_debug("MVM detach stream\n");
458
459 /* Detach voice stream. */
460 detach_stream.hdr.hdr_field =
461 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
462 APR_HDR_LEN(APR_HDR_SIZE),
463 APR_PKT_VER);
464 detach_stream.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
465 sizeof(detach_stream) - APR_HDR_SIZE);
466 detach_stream.hdr.src_port = 0;
467 detach_stream.hdr.dest_port = mvm_handle;
468 detach_stream.hdr.token = 0;
469 detach_stream.hdr.opcode = VSS_IMVM_CMD_DETACH_STREAM;
470 detach_stream.detach_stream.handle = cvs_handle;
471
472 v->mvm_state = CMD_STATUS_FAIL;
473
474 ret = apr_send_pkt(apr_mvm, (uint32_t *) &detach_stream);
475 if (ret < 0) {
476 pr_err("%s: Error %d sending DETACH_STREAM\n",
477 __func__, ret);
478 goto fail;
479 }
480 ret = wait_event_timeout(v->mvm_wait,
481 (v->mvm_state == CMD_STATUS_SUCCESS),
482 msecs_to_jiffies(TIMEOUT_MS));
483 if (!ret) {
484 pr_err("%s: wait event timeout\n", __func__);
485 goto fail;
486 }
487 /* Destroy CVS. */
488 pr_debug("CVS destroy session\n");
489
490 cvs_destroy.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
491 APR_HDR_LEN(APR_HDR_SIZE),
492 APR_PKT_VER);
493 cvs_destroy.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
494 sizeof(cvs_destroy) - APR_HDR_SIZE);
495 cvs_destroy.src_port = 0;
496 cvs_destroy.dest_port = cvs_handle;
497 cvs_destroy.token = 0;
498 cvs_destroy.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
499
500 v->cvs_state = CMD_STATUS_FAIL;
501
502 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_destroy);
503 if (ret < 0) {
504 pr_err("%s: Error %d sending CVS DESTROY\n",
505 __func__, ret);
506 goto fail;
507 }
508 ret = wait_event_timeout(v->cvs_wait,
509 (v->cvs_state == CMD_STATUS_SUCCESS),
510 msecs_to_jiffies(TIMEOUT_MS));
511 if (!ret) {
512 pr_err("%s: wait event timeout\n", __func__);
513
514 goto fail;
515 }
516 cvs_handle = 0;
517 voice_set_cvs_handle(v, cvs_handle);
518
519 /* Destroy MVM. */
520 pr_debug("MVM destroy session\n");
521
522 mvm_destroy.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
523 APR_HDR_LEN(APR_HDR_SIZE),
524 APR_PKT_VER);
525 mvm_destroy.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
526 sizeof(mvm_destroy) - APR_HDR_SIZE);
527 mvm_destroy.src_port = 0;
528 mvm_destroy.dest_port = mvm_handle;
529 mvm_destroy.token = 0;
530 mvm_destroy.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
531
532 v->mvm_state = CMD_STATUS_FAIL;
533
534 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_destroy);
535 if (ret < 0) {
536 pr_err("%s: Error %d sending MVM DESTROY\n",
537 __func__, ret);
538
539 goto fail;
540 }
541 ret = wait_event_timeout(v->mvm_wait,
542 (v->mvm_state == CMD_STATUS_SUCCESS),
543 msecs_to_jiffies(TIMEOUT_MS));
544 if (!ret) {
545 pr_err("%s: wait event timeout\n", __func__);
546
547 goto fail;
548 }
549 mvm_handle = 0;
550 voice_set_mvm_handle(v, mvm_handle);
551 }
552 return 0;
553fail:
554 return -EINVAL;
555}
556
557static int voice_send_tty_mode_cmd(struct voice_data *v)
558{
559 int tty_mode = 0;
560 int ret = 0;
561 struct mvm_set_tty_mode_cmd mvm_tty_mode_cmd;
562 void *apr_mvm;
563 u16 mvm_handle;
564
565 if (v == NULL) {
566 pr_err("%s: v is NULL\n", __func__);
567 return -EINVAL;
568 }
569 apr_mvm = v->apr_q6_mvm;
570
571 if (!apr_mvm) {
572 pr_err("%s: apr_mvm is NULL.\n", __func__);
573 return -EINVAL;
574 }
575 mvm_handle = voice_get_mvm_handle(v);
576
577 if (tty_mode) {
578 /* send tty mode cmd to mvm */
579 mvm_tty_mode_cmd.hdr.hdr_field = APR_HDR_FIELD(
580 APR_MSG_TYPE_SEQ_CMD,
581 APR_HDR_LEN(APR_HDR_SIZE),
582 APR_PKT_VER);
583 mvm_tty_mode_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
584 sizeof(mvm_tty_mode_cmd) -
585 APR_HDR_SIZE);
586 pr_debug("pkt size = %d\n", mvm_tty_mode_cmd.hdr.pkt_size);
587 mvm_tty_mode_cmd.hdr.src_port = 0;
588 mvm_tty_mode_cmd.hdr.dest_port = mvm_handle;
589 mvm_tty_mode_cmd.hdr.token = 0;
590 mvm_tty_mode_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_TTY_MODE;
591 mvm_tty_mode_cmd.tty_mode.mode = tty_mode;
592 pr_debug("tty mode =%d\n", mvm_tty_mode_cmd.tty_mode.mode);
593
594 v->mvm_state = CMD_STATUS_FAIL;
595 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_tty_mode_cmd);
596 if (ret < 0) {
597 pr_err("Fail: sending VSS_ISTREAM_CMD_SET_TTY_MODE\n");
598 goto fail;
599 }
600 ret = wait_event_timeout(v->mvm_wait,
601 (v->mvm_state == CMD_STATUS_SUCCESS),
602 msecs_to_jiffies(TIMEOUT_MS));
603 if (!ret) {
604 pr_err("%s: wait_event timeout\n", __func__);
605 goto fail;
606 }
607 }
608 return 0;
609fail:
610 return -EINVAL;
611}
612
613static int voice_config_cvs_vocoder(struct voice_data *v)
614{
615 int ret = 0;
616 void *apr_cvs;
617 u16 cvs_handle;
618 /* Set media type. */
619 struct cvs_set_media_type_cmd cvs_set_media_cmd;
620
621 if (v == NULL) {
622 pr_err("%s: v is NULL\n", __func__);
623 return -EINVAL;
624 }
625 apr_cvs = v->apr_q6_cvs;
626
627 if (!apr_cvs) {
628 pr_err("%s: apr_cvs is NULL.\n", __func__);
629 return -EINVAL;
630 }
631
632 cvs_handle = voice_get_cvs_handle(v);
633
634 cvs_set_media_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
635 APR_HDR_LEN(APR_HDR_SIZE),
636 APR_PKT_VER);
637 cvs_set_media_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
638 sizeof(cvs_set_media_cmd) - APR_HDR_SIZE);
639 cvs_set_media_cmd.hdr.src_port = 0;
640 cvs_set_media_cmd.hdr.dest_port = cvs_handle;
641 cvs_set_media_cmd.hdr.token = 0;
642 cvs_set_media_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_MEDIA_TYPE;
643 cvs_set_media_cmd.media_type.tx_media_id = v->mvs_info.media_type;
644 cvs_set_media_cmd.media_type.rx_media_id = v->mvs_info.media_type;
645
646 v->cvs_state = CMD_STATUS_FAIL;
647
648 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_media_cmd);
649 if (ret < 0) {
650 pr_err("%s: Error %d sending SET_MEDIA_TYPE\n",
651 __func__, ret);
652
653 goto fail;
654 }
655 ret = wait_event_timeout(v->cvs_wait,
656 (v->cvs_state == CMD_STATUS_SUCCESS),
657 msecs_to_jiffies(TIMEOUT_MS));
658 if (!ret) {
659 pr_err("%s: wait_event timeout\n", __func__);
660
661 goto fail;
662 }
663 /* Set encoder properties. */
664 switch (v->mvs_info.media_type) {
665 case VSS_MEDIA_ID_EVRC_MODEM: {
666 struct cvs_set_cdma_enc_minmax_rate_cmd cvs_set_cdma_rate;
667
668 pr_debug("Setting EVRC min-max rate\n");
669
670 cvs_set_cdma_rate.hdr.hdr_field =
671 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
672 APR_HDR_LEN(APR_HDR_SIZE),
673 APR_PKT_VER);
674 cvs_set_cdma_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
675 sizeof(cvs_set_cdma_rate) - APR_HDR_SIZE);
676 cvs_set_cdma_rate.hdr.src_port = 0;
677 cvs_set_cdma_rate.hdr.dest_port = cvs_handle;
678 cvs_set_cdma_rate.hdr.token = 0;
679 cvs_set_cdma_rate.hdr.opcode =
680 VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE;
681 cvs_set_cdma_rate.cdma_rate.min_rate = v->mvs_info.rate;
682 cvs_set_cdma_rate.cdma_rate.max_rate = v->mvs_info.rate;
683
684 v->cvs_state = CMD_STATUS_FAIL;
685
686 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_cdma_rate);
687 if (ret < 0) {
688 pr_err("%s: Error %d sending SET_EVRC_MINMAX_RATE\n",
689 __func__, ret);
690 goto fail;
691 }
692 ret = wait_event_timeout(v->cvs_wait,
693 (v->cvs_state == CMD_STATUS_SUCCESS),
694 msecs_to_jiffies(TIMEOUT_MS));
695 if (!ret) {
696 pr_err("%s: wait_event timeout\n", __func__);
697
698 goto fail;
699 }
700 break;
701 }
702 case VSS_MEDIA_ID_AMR_NB_MODEM: {
703 struct cvs_set_amr_enc_rate_cmd cvs_set_amr_rate;
704 struct cvs_set_enc_dtx_mode_cmd cvs_set_dtx;
705
706 pr_debug("Setting AMR rate\n");
707
708 cvs_set_amr_rate.hdr.hdr_field =
709 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
710 APR_HDR_LEN(APR_HDR_SIZE),
711 APR_PKT_VER);
712 cvs_set_amr_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
713 sizeof(cvs_set_amr_rate) - APR_HDR_SIZE);
714 cvs_set_amr_rate.hdr.src_port = 0;
715 cvs_set_amr_rate.hdr.dest_port = cvs_handle;
716 cvs_set_amr_rate.hdr.token = 0;
717 cvs_set_amr_rate.hdr.opcode =
718 VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE;
719 cvs_set_amr_rate.amr_rate.mode = v->mvs_info.rate;
720
721 v->cvs_state = CMD_STATUS_FAIL;
722
723 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_amr_rate);
724 if (ret < 0) {
725 pr_err("%s: Error %d sending SET_AMR_RATE\n",
726 __func__, ret);
727 goto fail;
728 }
729 ret = wait_event_timeout(v->cvs_wait,
730 (v->cvs_state == CMD_STATUS_SUCCESS),
731 msecs_to_jiffies(TIMEOUT_MS));
732 if (!ret) {
733 pr_err("%s: wait_event timeout\n", __func__);
734 goto fail;
735 }
736 /* Disable DTX */
737 pr_debug("Disabling DTX\n");
738
739 cvs_set_dtx.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
740 APR_HDR_LEN(APR_HDR_SIZE),
741 APR_PKT_VER);
742 cvs_set_dtx.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
743 sizeof(cvs_set_dtx) - APR_HDR_SIZE);
744 cvs_set_dtx.hdr.src_port = 0;
745 cvs_set_dtx.hdr.dest_port = cvs_handle;
746 cvs_set_dtx.hdr.token = 0;
747 cvs_set_dtx.hdr.opcode = VSS_ISTREAM_CMD_SET_ENC_DTX_MODE;
748 cvs_set_dtx.dtx_mode.enable = 0;
749
750 v->cvs_state = CMD_STATUS_FAIL;
751
752 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_dtx);
753 if (ret < 0) {
754 pr_err("%s: Error %d sending SET_DTX\n",
755 __func__, ret);
756 goto fail;
757 }
758 ret = wait_event_timeout(v->cvs_wait,
759 (v->cvs_state == CMD_STATUS_SUCCESS),
760 msecs_to_jiffies(TIMEOUT_MS));
761 if (!ret) {
762 pr_err("%s: wait_event timeout\n", __func__);
763 goto fail;
764 }
765 break;
766 }
767 case VSS_MEDIA_ID_AMR_WB_MODEM: {
768 struct cvs_set_amrwb_enc_rate_cmd cvs_set_amrwb_rate;
769 struct cvs_set_enc_dtx_mode_cmd cvs_set_dtx;
770
771 pr_debug("Setting AMR WB rate\n");
772
773 cvs_set_amrwb_rate.hdr.hdr_field =
774 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
775 APR_HDR_LEN(APR_HDR_SIZE),
776 APR_PKT_VER);
777 cvs_set_amrwb_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
778 sizeof(cvs_set_amrwb_rate) -
779 APR_HDR_SIZE);
780 cvs_set_amrwb_rate.hdr.src_port = 0;
781 cvs_set_amrwb_rate.hdr.dest_port = cvs_handle;
782 cvs_set_amrwb_rate.hdr.token = 0;
783 cvs_set_amrwb_rate.hdr.opcode =
784 VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE;
785 cvs_set_amrwb_rate.amrwb_rate.mode = v->mvs_info.rate;
786
787 v->cvs_state = CMD_STATUS_FAIL;
788
789 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_amrwb_rate);
790 if (ret < 0) {
791 pr_err("%s: Error %d sending SET_AMRWB_RATE\n",
792 __func__, ret);
793 goto fail;
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 goto fail;
801 }
802 /* Disable DTX */
803 pr_debug("Disabling DTX\n");
804
805 cvs_set_dtx.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
806 APR_HDR_LEN(APR_HDR_SIZE),
807 APR_PKT_VER);
808 cvs_set_dtx.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
809 sizeof(cvs_set_dtx) - APR_HDR_SIZE);
810 cvs_set_dtx.hdr.src_port = 0;
811 cvs_set_dtx.hdr.dest_port = cvs_handle;
812 cvs_set_dtx.hdr.token = 0;
813 cvs_set_dtx.hdr.opcode = VSS_ISTREAM_CMD_SET_ENC_DTX_MODE;
814 cvs_set_dtx.dtx_mode.enable = 0;
815
816 v->cvs_state = CMD_STATUS_FAIL;
817
818 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_dtx);
819 if (ret < 0) {
820 pr_err("%s: Error %d sending SET_DTX\n",
821 __func__, ret);
822 goto fail;
823 }
824 ret = wait_event_timeout(v->cvs_wait,
825 (v->cvs_state == CMD_STATUS_SUCCESS),
826 msecs_to_jiffies(TIMEOUT_MS));
827 if (!ret) {
828 pr_err("%s: wait_event timeout\n", __func__);
829 goto fail;
830 }
831 break;
832 }
833 case VSS_MEDIA_ID_G729:
834 case VSS_MEDIA_ID_G711_ALAW:
835 case VSS_MEDIA_ID_G711_MULAW: {
836 struct cvs_set_enc_dtx_mode_cmd cvs_set_dtx;
837 /* Disable DTX */
838 pr_debug("Disabling DTX\n");
839
840 cvs_set_dtx.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
841 APR_HDR_LEN(APR_HDR_SIZE),
842 APR_PKT_VER);
843 cvs_set_dtx.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
844 sizeof(cvs_set_dtx) - APR_HDR_SIZE);
845 cvs_set_dtx.hdr.src_port = 0;
846 cvs_set_dtx.hdr.dest_port = cvs_handle;
847 cvs_set_dtx.hdr.token = 0;
848 cvs_set_dtx.hdr.opcode = VSS_ISTREAM_CMD_SET_ENC_DTX_MODE;
849 cvs_set_dtx.dtx_mode.enable = 0;
850
851 v->cvs_state = CMD_STATUS_FAIL;
852
853 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_dtx);
854 if (ret < 0) {
855 pr_err("%s: Error %d sending SET_DTX\n",
856 __func__, ret);
857 goto fail;
858 }
859 ret = wait_event_timeout(v->cvs_wait,
860 (v->cvs_state == CMD_STATUS_SUCCESS),
861 msecs_to_jiffies(TIMEOUT_MS));
862 if (!ret) {
863 pr_err("%s: wait_event timeout\n", __func__);
864 goto fail;
865 }
866 break;
867 }
868 default:
869 /* Do nothing. */
870 break;
871 }
872 return 0;
873
874fail:
875 return -EINVAL;
876}
877
878static int voice_send_start_voice_cmd(struct voice_data *v)
879{
880 struct apr_hdr mvm_start_voice_cmd;
881 int ret = 0;
882 void *apr_mvm;
883 u16 mvm_handle;
884
885 if (v == NULL) {
886 pr_err("%s: v is NULL\n", __func__);
887 return -EINVAL;
888 }
889 apr_mvm = v->apr_q6_mvm;
890
891 if (!apr_mvm) {
892 pr_err("%s: apr_mvm is NULL.\n", __func__);
893 return -EINVAL;
894 }
895 mvm_handle = voice_get_mvm_handle(v);
896
897 mvm_start_voice_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
898 APR_HDR_LEN(APR_HDR_SIZE),
899 APR_PKT_VER);
900 mvm_start_voice_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
901 sizeof(mvm_start_voice_cmd) - APR_HDR_SIZE);
902 pr_debug("send mvm_start_voice_cmd pkt size = %d\n",
903 mvm_start_voice_cmd.pkt_size);
904 mvm_start_voice_cmd.src_port = 0;
905 mvm_start_voice_cmd.dest_port = mvm_handle;
906 mvm_start_voice_cmd.token = 0;
907 mvm_start_voice_cmd.opcode = VSS_IMVM_CMD_START_VOICE;
908
909 v->mvm_state = CMD_STATUS_FAIL;
910 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_start_voice_cmd);
911 if (ret < 0) {
912 pr_err("Fail in sending VSS_IMVM_CMD_START_VOICE\n");
913 goto fail;
914 }
915 ret = wait_event_timeout(v->mvm_wait,
916 (v->mvm_state == CMD_STATUS_SUCCESS),
917 msecs_to_jiffies(TIMEOUT_MS));
918 if (!ret) {
919 pr_err("%s: wait_event timeout\n", __func__);
920 goto fail;
921 }
922 return 0;
923fail:
924 return -EINVAL;
925}
926
927static int voice_send_disable_vocproc_cmd(struct voice_data *v)
928{
929 struct apr_hdr cvp_disable_cmd;
930 int ret = 0;
931 void *apr_cvp;
932 u16 cvp_handle;
933
934 if (v == NULL) {
935 pr_err("%s: v is NULL\n", __func__);
936 return -EINVAL;
937 }
938 apr_cvp = v->apr_q6_cvp;
939
940 if (!apr_cvp) {
941 pr_err("%s: apr regist failed\n", __func__);
942 return -EINVAL;
943 }
944 cvp_handle = voice_get_cvp_handle(v);
945
946 /* disable vocproc and wait for respose */
947 cvp_disable_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
948 APR_HDR_LEN(APR_HDR_SIZE),
949 APR_PKT_VER);
950 cvp_disable_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
951 sizeof(cvp_disable_cmd) - APR_HDR_SIZE);
952 pr_debug("cvp_disable_cmd pkt size = %d, cvp_handle=%d\n",
953 cvp_disable_cmd.pkt_size, cvp_handle);
954 cvp_disable_cmd.src_port = 0;
955 cvp_disable_cmd.dest_port = cvp_handle;
956 cvp_disable_cmd.token = 0;
957 cvp_disable_cmd.opcode = VSS_IVOCPROC_CMD_DISABLE;
958
959 v->cvp_state = CMD_STATUS_FAIL;
960 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_disable_cmd);
961 if (ret < 0) {
962 pr_err("Fail in sending VSS_IVOCPROC_CMD_DISABLE\n");
963 goto fail;
964 }
965 ret = wait_event_timeout(v->cvp_wait,
966 (v->cvp_state == CMD_STATUS_SUCCESS),
967 msecs_to_jiffies(TIMEOUT_MS));
968 if (!ret) {
969 pr_err("%s: wait_event timeout\n", __func__);
970 goto fail;
971 }
972
973 return 0;
974fail:
975 return -EINVAL;
976}
977
978static int voice_send_set_device_cmd(struct voice_data *v)
979{
980 struct cvp_set_device_cmd cvp_setdev_cmd;
981 int ret = 0;
982 void *apr_cvp;
983 u16 cvp_handle;
984
985 if (v == NULL) {
986 pr_err("%s: v is NULL\n", __func__);
987 return -EINVAL;
988 }
989 apr_cvp = v->apr_q6_cvp;
990
991 if (!apr_cvp) {
992 pr_err("%s: apr_cvp is NULL.\n", __func__);
993 return -EINVAL;
994 }
995 cvp_handle = voice_get_cvp_handle(v);
996
997 /* set device and wait for response */
998 cvp_setdev_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
999 APR_HDR_LEN(APR_HDR_SIZE),
1000 APR_PKT_VER);
1001 cvp_setdev_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1002 sizeof(cvp_setdev_cmd) - APR_HDR_SIZE);
1003 pr_debug(" send create cvp setdev, pkt size = %d\n",
1004 cvp_setdev_cmd.hdr.pkt_size);
1005 cvp_setdev_cmd.hdr.src_port = 0;
1006 cvp_setdev_cmd.hdr.dest_port = cvp_handle;
1007 cvp_setdev_cmd.hdr.token = 0;
1008 cvp_setdev_cmd.hdr.opcode = VSS_IVOCPROC_CMD_SET_DEVICE;
1009
1010 /* Use default topology if invalid value in ACDB */
1011 cvp_setdev_cmd.cvp_set_device.tx_topology_id =
1012 get_voice_tx_topology();
1013 if (cvp_setdev_cmd.cvp_set_device.tx_topology_id == 0)
1014 cvp_setdev_cmd.cvp_set_device.tx_topology_id =
1015 VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
1016
1017 cvp_setdev_cmd.cvp_set_device.rx_topology_id =
1018 get_voice_rx_topology();
1019 if (cvp_setdev_cmd.cvp_set_device.rx_topology_id == 0)
1020 cvp_setdev_cmd.cvp_set_device.rx_topology_id =
1021 VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
1022 cvp_setdev_cmd.cvp_set_device.tx_port_id = v->dev_tx.port_id;
1023 cvp_setdev_cmd.cvp_set_device.rx_port_id = v->dev_rx.port_id;
1024 pr_debug("topology=%d , tx_port_id=%d, rx_port_id=%d\n",
1025 cvp_setdev_cmd.cvp_set_device.tx_topology_id,
1026 cvp_setdev_cmd.cvp_set_device.tx_port_id,
1027 cvp_setdev_cmd.cvp_set_device.rx_port_id);
1028
1029 v->cvp_state = CMD_STATUS_FAIL;
1030 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_setdev_cmd);
1031 if (ret < 0) {
1032 pr_err("Fail in sending VOCPROC_FULL_CONTROL_SESSION\n");
1033 goto fail;
1034 }
1035 pr_debug("wait for cvp create session event\n");
1036 ret = wait_event_timeout(v->cvp_wait,
1037 (v->cvp_state == CMD_STATUS_SUCCESS),
1038 msecs_to_jiffies(TIMEOUT_MS));
1039 if (!ret) {
1040 pr_err("%s: wait_event timeout\n", __func__);
1041 goto fail;
1042 }
1043
1044 return 0;
1045fail:
1046 return -EINVAL;
1047}
1048
1049static int voice_send_stop_voice_cmd(struct voice_data *v)
1050{
1051 struct apr_hdr mvm_stop_voice_cmd;
1052 int ret = 0;
1053 void *apr_mvm;
1054 u16 mvm_handle;
1055
1056 if (v == NULL) {
1057 pr_err("%s: v is NULL\n", __func__);
1058 return -EINVAL;
1059 }
1060 apr_mvm = v->apr_q6_mvm;
1061
1062 if (!apr_mvm) {
1063 pr_err("%s: apr_mvm is NULL.\n", __func__);
1064 return -EINVAL;
1065 }
1066 mvm_handle = voice_get_mvm_handle(v);
1067
1068 mvm_stop_voice_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1069 APR_HDR_LEN(APR_HDR_SIZE),
1070 APR_PKT_VER);
1071 mvm_stop_voice_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1072 sizeof(mvm_stop_voice_cmd) - APR_HDR_SIZE);
1073 pr_debug("send mvm_stop_voice_cmd pkt size = %d\n",
1074 mvm_stop_voice_cmd.pkt_size);
1075 mvm_stop_voice_cmd.src_port = 0;
1076 mvm_stop_voice_cmd.dest_port = mvm_handle;
1077 mvm_stop_voice_cmd.token = 0;
1078 mvm_stop_voice_cmd.opcode = VSS_IMVM_CMD_STOP_VOICE;
1079
1080 v->mvm_state = CMD_STATUS_FAIL;
1081 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_stop_voice_cmd);
1082 if (ret < 0) {
1083 pr_err("Fail in sending VSS_IMVM_CMD_STOP_VOICE\n");
1084 goto fail;
1085 }
1086 ret = wait_event_timeout(v->mvm_wait,
1087 (v->mvm_state == CMD_STATUS_SUCCESS),
1088 msecs_to_jiffies(TIMEOUT_MS));
1089 if (!ret) {
1090 pr_err("%s: wait_event timeout\n", __func__);
1091 goto fail;
1092 }
1093
1094 return 0;
1095fail:
1096 return -EINVAL;
1097}
1098
1099static int voice_setup_vocproc(struct voice_data *v)
1100{
1101 struct cvp_create_full_ctl_session_cmd cvp_session_cmd;
1102 int ret = 0;
1103 void *apr_cvp;
1104 if (v == NULL) {
1105 pr_err("%s: v is NULL\n", __func__);
1106 return -EINVAL;
1107 }
1108 apr_cvp = v->apr_q6_cvp;
1109
1110 if (!apr_cvp) {
1111 pr_err("%s: apr_cvp is NULL.\n", __func__);
1112 return -EINVAL;
1113 }
1114
1115 /* create cvp session and wait for response */
1116 cvp_session_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1117 APR_HDR_LEN(APR_HDR_SIZE),
1118 APR_PKT_VER);
1119 cvp_session_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1120 sizeof(cvp_session_cmd) - APR_HDR_SIZE);
1121 pr_debug(" send create cvp session, pkt size = %d\n",
1122 cvp_session_cmd.hdr.pkt_size);
1123 cvp_session_cmd.hdr.src_port = 0;
1124 cvp_session_cmd.hdr.dest_port = 0;
1125 cvp_session_cmd.hdr.token = 0;
1126 cvp_session_cmd.hdr.opcode =
1127 VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION;
1128
1129 /* Use default topology if invalid value in ACDB */
1130 cvp_session_cmd.cvp_session.tx_topology_id =
1131 get_voice_tx_topology();
1132 if (cvp_session_cmd.cvp_session.tx_topology_id == 0)
1133 cvp_session_cmd.cvp_session.tx_topology_id =
1134 VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
1135
1136 cvp_session_cmd.cvp_session.rx_topology_id =
1137 get_voice_rx_topology();
1138 if (cvp_session_cmd.cvp_session.rx_topology_id == 0)
1139 cvp_session_cmd.cvp_session.rx_topology_id =
1140 VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
1141
1142 cvp_session_cmd.cvp_session.direction = 2; /*tx and rx*/
1143 cvp_session_cmd.cvp_session.network_id = VSS_NETWORK_ID_DEFAULT;
1144 cvp_session_cmd.cvp_session.tx_port_id = v->dev_tx.port_id;
1145 cvp_session_cmd.cvp_session.rx_port_id = v->dev_rx.port_id;
1146
1147 pr_debug("topology=%d net_id=%d, dir=%d tx_port_id=%d, rx_port_id=%d\n",
1148 cvp_session_cmd.cvp_session.tx_topology_id,
1149 cvp_session_cmd.cvp_session.network_id,
1150 cvp_session_cmd.cvp_session.direction,
1151 cvp_session_cmd.cvp_session.tx_port_id,
1152 cvp_session_cmd.cvp_session.rx_port_id);
1153
1154 v->cvp_state = CMD_STATUS_FAIL;
1155 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_session_cmd);
1156 if (ret < 0) {
1157 pr_err("Fail in sending VOCPROC_FULL_CONTROL_SESSION\n");
1158 goto fail;
1159 }
1160 ret = wait_event_timeout(v->cvp_wait,
1161 (v->cvp_state == CMD_STATUS_SUCCESS),
1162 msecs_to_jiffies(TIMEOUT_MS));
1163 if (!ret) {
1164 pr_err("%s: wait_event timeout\n", __func__);
1165 goto fail;
1166 }
1167
1168 /* enable vocproc */
1169 ret = voice_send_enable_vocproc_cmd(v);
1170 if (ret < 0)
1171 goto fail;
1172
1173 /* attach vocproc */
1174 ret = voice_send_attach_vocproc_cmd(v);
1175 if (ret < 0)
1176 goto fail;
1177
1178 /* send tty mode if tty device is used */
1179 voice_send_tty_mode_cmd(v);
1180
1181 if (v->voc_path == VOC_PATH_FULL)
1182 voice_send_netid_timing_cmd(v);
1183
1184 return 0;
1185
1186fail:
1187 return -EINVAL;
1188}
1189
1190static int voice_send_enable_vocproc_cmd(struct voice_data *v)
1191{
1192 int ret = 0;
1193 struct apr_hdr cvp_enable_cmd;
1194 void *apr_cvp;
1195 u16 cvp_handle;
1196
1197 if (v == NULL) {
1198 pr_err("%s: v is NULL\n", __func__);
1199 return -EINVAL;
1200 }
1201 apr_cvp = v->apr_q6_cvp;
1202
1203 if (!apr_cvp) {
1204 pr_err("%s: apr_cvp is NULL.\n", __func__);
1205 return -EINVAL;
1206 }
1207 cvp_handle = voice_get_cvp_handle(v);
1208
1209 /* enable vocproc and wait for respose */
1210 cvp_enable_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1211 APR_HDR_LEN(APR_HDR_SIZE),
1212 APR_PKT_VER);
1213 cvp_enable_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1214 sizeof(cvp_enable_cmd) - APR_HDR_SIZE);
1215 pr_debug("cvp_enable_cmd pkt size = %d, cvp_handle=%d\n",
1216 cvp_enable_cmd.pkt_size, cvp_handle);
1217 cvp_enable_cmd.src_port = 0;
1218 cvp_enable_cmd.dest_port = cvp_handle;
1219 cvp_enable_cmd.token = 0;
1220 cvp_enable_cmd.opcode = VSS_IVOCPROC_CMD_ENABLE;
1221
1222 v->cvp_state = CMD_STATUS_FAIL;
1223 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_enable_cmd);
1224 if (ret < 0) {
1225 pr_err("Fail in sending VSS_IVOCPROC_CMD_ENABLE\n");
1226 goto fail;
1227 }
1228 ret = wait_event_timeout(v->cvp_wait,
1229 (v->cvp_state == CMD_STATUS_SUCCESS),
1230 msecs_to_jiffies(TIMEOUT_MS));
1231 if (!ret) {
1232 pr_err("%s: wait_event timeout\n", __func__);
1233 goto fail;
1234 }
1235
1236 return 0;
1237fail:
1238 return -EINVAL;
1239}
1240
1241static int voice_send_netid_timing_cmd(struct voice_data *v)
1242{
1243 int ret = 0;
1244 void *apr_mvm;
1245 u16 mvm_handle;
1246 struct mvm_set_network_cmd mvm_set_network;
1247 struct mvm_set_voice_timing_cmd mvm_set_voice_timing;
1248
1249 if (v == NULL) {
1250 pr_err("%s: v is NULL\n", __func__);
1251 return -EINVAL;
1252 }
1253 apr_mvm = v->apr_q6_mvm;
1254
1255 if (!apr_mvm) {
1256 pr_err("%s: apr_mvm is NULL.\n", __func__);
1257 return -EINVAL;
1258 }
1259 mvm_handle = voice_get_mvm_handle(v);
1260
1261 ret = voice_config_cvs_vocoder(v);
1262 if (ret < 0) {
1263 pr_err("%s: Error %d configuring CVS voc",
1264 __func__, ret);
1265 goto fail;
1266 }
1267 /* Set network ID. */
1268 pr_debug("Setting network ID\n");
1269
1270 mvm_set_network.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1271 APR_HDR_LEN(APR_HDR_SIZE),
1272 APR_PKT_VER);
1273 mvm_set_network.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1274 sizeof(mvm_set_network) - APR_HDR_SIZE);
1275 mvm_set_network.hdr.src_port = 0;
1276 mvm_set_network.hdr.dest_port = mvm_handle;
1277 mvm_set_network.hdr.token = 0;
1278 mvm_set_network.hdr.opcode = VSS_ICOMMON_CMD_SET_NETWORK;
1279 mvm_set_network.network.network_id = v->mvs_info.network_type;
1280
1281 v->mvm_state = CMD_STATUS_FAIL;
1282 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_network);
1283 if (ret < 0) {
1284 pr_err("%s: Error %d sending SET_NETWORK\n", __func__, ret);
1285 goto fail;
1286 }
1287
1288 ret = wait_event_timeout(v->mvm_wait,
1289 (v->mvm_state == CMD_STATUS_SUCCESS),
1290 msecs_to_jiffies(TIMEOUT_MS));
1291 if (!ret) {
1292 pr_err("%s: wait_event timeout\n", __func__);
1293 goto fail;
1294 }
1295
1296 /* Set voice timing. */
1297 pr_debug("Setting voice timing\n");
1298
1299 mvm_set_voice_timing.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1300 APR_HDR_LEN(APR_HDR_SIZE),
1301 APR_PKT_VER);
1302 mvm_set_voice_timing.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1303 sizeof(mvm_set_voice_timing) -
1304 APR_HDR_SIZE);
1305 mvm_set_voice_timing.hdr.src_port = 0;
1306 mvm_set_voice_timing.hdr.dest_port = mvm_handle;
1307 mvm_set_voice_timing.hdr.token = 0;
1308 mvm_set_voice_timing.hdr.opcode = VSS_ICOMMON_CMD_SET_VOICE_TIMING;
1309 mvm_set_voice_timing.timing.mode = 0;
1310 mvm_set_voice_timing.timing.enc_offset = 8000;
1311 mvm_set_voice_timing.timing.dec_req_offset = 3300;
1312 mvm_set_voice_timing.timing.dec_offset = 8300;
1313
1314 v->mvm_state = CMD_STATUS_FAIL;
1315
1316 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_voice_timing);
1317 if (ret < 0) {
1318 pr_err("%s: Error %d sending SET_TIMING\n", __func__, ret);
1319 goto fail;
1320 }
1321
1322 ret = wait_event_timeout(v->mvm_wait,
1323 (v->mvm_state == CMD_STATUS_SUCCESS),
1324 msecs_to_jiffies(TIMEOUT_MS));
1325 if (!ret) {
1326 pr_err("%s: wait_event timeout\n", __func__);
1327 goto fail;
1328 }
1329
1330 return 0;
1331fail:
1332 return -EINVAL;
1333}
1334
1335static int voice_send_attach_vocproc_cmd(struct voice_data *v)
1336{
1337 int ret = 0;
1338 struct mvm_attach_vocproc_cmd mvm_a_vocproc_cmd;
1339 void *apr_mvm;
1340 u16 mvm_handle, cvp_handle;
1341
1342 if (v == NULL) {
1343 pr_err("%s: v is NULL\n", __func__);
1344 return -EINVAL;
1345 }
1346 apr_mvm = v->apr_q6_mvm;
1347
1348 if (!apr_mvm) {
1349 pr_err("%s: apr_mvm is NULL.\n", __func__);
1350 return -EINVAL;
1351 }
1352 mvm_handle = voice_get_mvm_handle(v);
1353 cvp_handle = voice_get_cvp_handle(v);
1354
1355 /* attach vocproc and wait for response */
1356 mvm_a_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1357 APR_HDR_LEN(APR_HDR_SIZE),
1358 APR_PKT_VER);
1359 mvm_a_vocproc_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1360 sizeof(mvm_a_vocproc_cmd) - APR_HDR_SIZE);
1361 pr_debug("send mvm_a_vocproc_cmd pkt size = %d\n",
1362 mvm_a_vocproc_cmd.hdr.pkt_size);
1363 mvm_a_vocproc_cmd.hdr.src_port = 0;
1364 mvm_a_vocproc_cmd.hdr.dest_port = mvm_handle;
1365 mvm_a_vocproc_cmd.hdr.token = 0;
1366 mvm_a_vocproc_cmd.hdr.opcode = VSS_ISTREAM_CMD_ATTACH_VOCPROC;
1367 mvm_a_vocproc_cmd.mvm_attach_cvp_handle.handle = cvp_handle;
1368
1369 v->mvm_state = CMD_STATUS_FAIL;
1370 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_a_vocproc_cmd);
1371 if (ret < 0) {
1372 pr_err("Fail in sending VSS_ISTREAM_CMD_ATTACH_VOCPROC\n");
1373 goto fail;
1374 }
1375 ret = wait_event_timeout(v->mvm_wait,
1376 (v->mvm_state == CMD_STATUS_SUCCESS),
1377 msecs_to_jiffies(TIMEOUT_MS));
1378 if (!ret) {
1379 pr_err("%s: wait_event timeout\n", __func__);
1380 goto fail;
1381 }
1382
1383 return 0;
1384fail:
1385 return -EINVAL;
1386}
1387
1388static int voice_destroy_vocproc(struct voice_data *v)
1389{
1390 struct mvm_detach_vocproc_cmd mvm_d_vocproc_cmd;
1391 struct apr_hdr cvp_destroy_session_cmd;
1392 int ret = 0;
1393 void *apr_mvm, *apr_cvp;
1394 u16 mvm_handle, cvp_handle;
1395
1396 if (v == NULL) {
1397 pr_err("%s: v is NULL\n", __func__);
1398 return -EINVAL;
1399 }
1400 apr_mvm = v->apr_q6_mvm;
1401 apr_cvp = v->apr_q6_cvp;
1402
1403 if (!apr_mvm || !apr_cvp) {
1404 pr_err("%s: apr_mvm or apr_cvp is NULL.\n", __func__);
1405 return -EINVAL;
1406 }
1407 mvm_handle = voice_get_mvm_handle(v);
1408 cvp_handle = voice_get_cvp_handle(v);
1409
1410 /* send stop voice cmd */
1411 voice_send_stop_voice_cmd(v);
1412
1413 /* detach VOCPROC and wait for response from mvm */
1414 mvm_d_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1415 APR_HDR_LEN(APR_HDR_SIZE),
1416 APR_PKT_VER);
1417 mvm_d_vocproc_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1418 sizeof(mvm_d_vocproc_cmd) - APR_HDR_SIZE);
1419 pr_debug("mvm_d_vocproc_cmd pkt size = %d\n",
1420 mvm_d_vocproc_cmd.hdr.pkt_size);
1421 mvm_d_vocproc_cmd.hdr.src_port = 0;
1422 mvm_d_vocproc_cmd.hdr.dest_port = mvm_handle;
1423 mvm_d_vocproc_cmd.hdr.token = 0;
1424 mvm_d_vocproc_cmd.hdr.opcode = VSS_ISTREAM_CMD_DETACH_VOCPROC;
1425 mvm_d_vocproc_cmd.mvm_detach_cvp_handle.handle = cvp_handle;
1426
1427 v->mvm_state = CMD_STATUS_FAIL;
1428 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_d_vocproc_cmd);
1429 if (ret < 0) {
1430 pr_err("Fail in sending VSS_ISTREAM_CMD_DETACH_VOCPROC\n");
1431 goto fail;
1432 }
1433 ret = wait_event_timeout(v->mvm_wait,
1434 (v->mvm_state == CMD_STATUS_SUCCESS),
1435 msecs_to_jiffies(TIMEOUT_MS));
1436 if (!ret) {
1437 pr_err("%s: wait_event timeout\n", __func__);
1438 goto fail;
1439 }
1440
1441 /* destrop cvp session */
1442 cvp_destroy_session_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1443 APR_HDR_LEN(APR_HDR_SIZE),
1444 APR_PKT_VER);
1445 cvp_destroy_session_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1446 sizeof(cvp_destroy_session_cmd) - APR_HDR_SIZE);
1447 pr_debug("cvp_destroy_session_cmd pkt size = %d\n",
1448 cvp_destroy_session_cmd.pkt_size);
1449 cvp_destroy_session_cmd.src_port = 0;
1450 cvp_destroy_session_cmd.dest_port = cvp_handle;
1451 cvp_destroy_session_cmd.token = 0;
1452 cvp_destroy_session_cmd.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
1453
1454 v->cvp_state = CMD_STATUS_FAIL;
1455 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_destroy_session_cmd);
1456 if (ret < 0) {
1457 pr_err("Fail in sending APRV2_IBASIC_CMD_DESTROY_SESSION\n");
1458 goto fail;
1459 }
1460 ret = wait_event_timeout(v->cvp_wait,
1461 (v->cvp_state == CMD_STATUS_SUCCESS),
1462 msecs_to_jiffies(TIMEOUT_MS));
1463 if (!ret) {
1464 pr_err("%s: wait_event timeout\n", __func__);
1465 goto fail;
1466 }
1467
1468 cvp_handle = 0;
1469 voice_set_cvp_handle(v, cvp_handle);
1470
1471 return 0;
1472
1473fail:
1474 return -EINVAL;
1475}
1476
1477static int voice_send_mute_cmd(struct voice_data *v)
1478{
1479 struct cvs_set_mute_cmd cvs_mute_cmd;
1480 int ret = 0;
1481 void *apr_cvs;
1482 u16 cvs_handle;
1483
1484 if (v == NULL) {
1485 pr_err("%s: v is NULL\n", __func__);
1486 return -EINVAL;
1487 }
1488 apr_cvs = v->apr_q6_cvs;
1489
1490 if (!apr_cvs) {
1491 pr_err("%s: apr_cvs is NULL.\n", __func__);
1492 return -EINVAL;
1493 }
1494 cvs_handle = voice_get_cvs_handle(v);
1495
1496 /* send mute/unmute to cvs */
1497 cvs_mute_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1498 APR_HDR_LEN(APR_HDR_SIZE),
1499 APR_PKT_VER);
1500 cvs_mute_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1501 sizeof(cvs_mute_cmd) - APR_HDR_SIZE);
1502 cvs_mute_cmd.hdr.src_port = 0;
1503 cvs_mute_cmd.hdr.dest_port = cvs_handle;
1504 cvs_mute_cmd.hdr.token = 0;
1505 cvs_mute_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_MUTE;
1506 cvs_mute_cmd.cvs_set_mute.direction = 0; /*tx*/
1507 cvs_mute_cmd.cvs_set_mute.mute_flag = v->dev_tx.mute;
1508
1509 pr_info(" mute value =%d\n", cvs_mute_cmd.cvs_set_mute.mute_flag);
1510 v->cvs_state = CMD_STATUS_FAIL;
1511 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_mute_cmd);
1512 if (ret < 0) {
1513 pr_err("Fail: send STREAM SET MUTE\n");
1514 goto fail;
1515 }
1516 ret = wait_event_timeout(v->cvs_wait,
1517 (v->cvs_state == CMD_STATUS_SUCCESS),
1518 msecs_to_jiffies(TIMEOUT_MS));
1519 if (!ret)
1520 pr_err("%s: wait_event timeout\n", __func__);
1521
1522 return 0;
1523fail:
1524 return -EINVAL;
1525}
1526
1527static int voice_send_vol_index_cmd(struct voice_data *v)
1528{
1529 struct cvp_set_rx_volume_index_cmd cvp_vol_cmd;
1530 int ret = 0;
1531 void *apr_cvp;
1532 u16 cvp_handle;
1533 if (v == NULL) {
1534 pr_err("%s: v is NULL\n", __func__);
1535 return -EINVAL;
1536 }
1537 apr_cvp = v->apr_q6_cvp;
1538
1539 if (!apr_cvp) {
1540 pr_err("%s: apr_cvp is NULL.\n", __func__);
1541 return -EINVAL;
1542 }
1543 cvp_handle = voice_get_cvp_handle(v);
1544
1545 /* send volume index to cvp */
1546 cvp_vol_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1547 APR_HDR_LEN(APR_HDR_SIZE),
1548 APR_PKT_VER);
1549 cvp_vol_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1550 sizeof(cvp_vol_cmd) - APR_HDR_SIZE);
1551 cvp_vol_cmd.hdr.src_port = 0;
1552 cvp_vol_cmd.hdr.dest_port = cvp_handle;
1553 cvp_vol_cmd.hdr.token = 0;
1554 cvp_vol_cmd.hdr.opcode = VSS_IVOCPROC_CMD_SET_RX_VOLUME_INDEX;
1555 cvp_vol_cmd.cvp_set_vol_idx.vol_index = v->dev_rx.volume;
1556 v->cvp_state = CMD_STATUS_FAIL;
1557 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_vol_cmd);
1558 if (ret < 0) {
1559 pr_err("Fail in sending RX VOL INDEX\n");
1560 return -EINVAL;
1561 }
1562 ret = wait_event_timeout(v->cvp_wait,
1563 (v->cvp_state == CMD_STATUS_SUCCESS),
1564 msecs_to_jiffies(TIMEOUT_MS));
1565 if (!ret) {
1566 pr_err("%s: wait_event timeout\n", __func__);
1567 return -EINVAL;
1568 }
1569 return 0;
1570}
1571
1572int voc_disable_cvp(void)
1573{
1574 struct voice_data *v = &voice;
1575 int ret = 0;
1576
1577 mutex_lock(&v->lock);
1578
1579 if (v->voc_state == VOC_RUN) {
1580 afe_sidetone(v->dev_tx.port_id, v->dev_rx.port_id, 0, 0);
1581 /* send cmd to dsp to disable vocproc */
1582 ret = voice_send_disable_vocproc_cmd(v);
1583 if (ret < 0) {
1584 pr_err("%s: disable vocproc failed\n", __func__);
1585 goto fail;
1586 }
1587 v->voc_state = VOC_CHANGE;
1588 }
1589
1590fail: mutex_unlock(&v->lock);
1591
1592 return ret;
1593}
1594
1595int voc_enable_cvp(void)
1596{
1597 struct voice_data *v = &voice;
1598 int ret = 0;
1599
1600 mutex_lock(&v->lock);
1601
1602 if (v->voc_state == VOC_CHANGE) {
1603 ret = voice_send_set_device_cmd(v);
1604 if (ret < 0) {
1605 pr_err("%s: set device failed\n", __func__);
1606 goto fail;
1607 }
1608 ret = voice_send_enable_vocproc_cmd(v);
1609 if (ret < 0) {
1610 pr_err("enable vocproc failed\n");
1611 goto fail;
1612 }
1613 ret = afe_sidetone(v->dev_tx.port_id, v->dev_rx.port_id,
1614 1, v->sidetone_gain);
1615
1616 if (ret < 0)
1617 pr_err("AFE command sidetone failed\n");
1618
1619 v->voc_state = VOC_RUN;
1620 }
1621
1622fail:
1623 mutex_unlock(&v->lock);
1624
1625 return ret;
1626}
1627
1628int voc_set_tx_mute(uint32_t dir, uint32_t mute)
1629{
1630 struct voice_data *v = &voice;
1631 int ret = 0;
1632
1633 mutex_lock(&v->lock);
1634
1635 v->dev_tx.mute = mute;
1636
1637 if (v->voc_state == VOC_RUN)
1638 ret = voice_send_mute_cmd(v);
1639
1640 mutex_unlock(&v->lock);
1641
1642 return ret;
1643}
1644
1645int voc_set_rx_vol_index(uint32_t dir, uint32_t vol_idx)
1646{
1647 struct voice_data *v = &voice;
1648 int ret = 0;
1649
1650 mutex_lock(&v->lock);
1651
1652 v->dev_rx.volume = vol_idx;
1653
1654 if (v->voc_state == VOC_RUN)
1655 ret = voice_send_vol_index_cmd(v);
1656
1657 mutex_unlock(&v->lock);
1658
1659 return ret;
1660}
1661
1662void voc_set_rxtx_port(uint32_t port_id, uint32_t dev_type)
1663{
1664 struct voice_data *v = &voice;
1665
1666 pr_debug(" port_id=%d, type=%d\n", port_id, dev_type);
1667
1668 mutex_lock(&v->lock);
1669
1670 if (dev_type == DEV_RX)
1671 v->dev_rx.port_id = port_id;
1672 else
1673 v->dev_tx.port_id = port_id;
1674
1675 mutex_unlock(&v->lock);
1676
1677 return;
1678}
1679
1680void voc_set_route_flag(uint8_t path_dir, uint8_t set)
1681{
1682 struct voice_data *v = &voice;
1683
1684 pr_debug("path_dir=%d, set=%d\n", path_dir, set);
1685
1686 mutex_lock(&v->lock);
1687
1688 if (path_dir == RX_PATH)
1689 v->voc_route_state.rx_route_flag = set;
1690 else
1691 v->voc_route_state.tx_route_flag = set;
1692
1693 mutex_unlock(&v->lock);
1694
1695 return;
1696}
1697
1698uint8_t voc_get_route_flag(uint8_t path_dir)
1699{
1700 struct voice_data *v = &voice;
1701 int ret = 0;
1702
1703 mutex_lock(&v->lock);
1704
1705 if (path_dir == RX_PATH)
1706 ret = v->voc_route_state.rx_route_flag;
1707 else
1708 ret = v->voc_route_state.tx_route_flag;
1709
1710 mutex_unlock(&v->lock);
1711
1712 return ret;
1713}
1714
1715int voc_end_voice_call(void)
1716{
1717 struct voice_data *v = &voice;
1718 int ret = 0;
1719
1720 mutex_lock(&v->lock);
1721
1722 if (v->voc_state == VOC_RUN) {
1723 ret = voice_destroy_vocproc(v);
1724 if (ret < 0)
1725 pr_err("%s: destroy voice failed\n", __func__);
1726 voice_destroy_mvm_cvs_session(v);
1727
1728 v->voc_state = VOC_RELEASE;
1729 }
1730 mutex_unlock(&v->lock);
1731 return ret;
1732}
1733
1734int voc_start_voice_call(void)
1735{
1736 struct voice_data *v = &voice;
1737 int ret = 0;
1738
1739 mutex_lock(&v->lock);
1740
1741 if ((v->voc_state == VOC_INIT) ||
1742 (v->voc_state == VOC_RELEASE)) {
1743 ret = voice_apr_register(v);
1744 if (ret < 0) {
1745 pr_err("%s: apr register failed\n", __func__);
1746 goto fail;
1747 }
1748 ret = voice_create_mvm_cvs_session(v);
1749 if (ret < 0) {
1750 pr_err("create mvm and cvs failed\n");
1751 goto fail;
1752 }
1753 ret = voice_setup_vocproc(v);
1754 if (ret < 0) {
1755 pr_err("setup voice failed\n");
1756 goto fail;
1757 }
1758 ret = voice_send_start_voice_cmd(v);
1759 if (ret < 0) {
1760 pr_err("start voice failed\n");
1761 goto fail;
1762 }
1763 ret = afe_sidetone(v->dev_tx.port_id,
1764 v->dev_rx.port_id, 1, v->sidetone_gain);
1765 if (ret < 0)
1766 pr_err("AFE command sidetone failed\n");
1767
1768 v->voc_state = VOC_RUN;
1769 }
1770
1771fail: mutex_unlock(&v->lock);
1772 return ret;
1773}
1774
1775int voc_set_voc_path_full(uint32_t set)
1776{
1777 int rc = 0;
1778
1779 pr_debug("set voc path: %d\n", set);
1780
1781 mutex_lock(&voice.lock);
1782
1783 if (voice.voc_state == VOC_INIT || voice.voc_state == VOC_RELEASE) {
1784 if (set)
1785 voice.voc_path = VOC_PATH_FULL;
1786 else
1787 voice.voc_path = VOC_PATH_PASSIVE;
1788 } else {
1789 pr_err("%s: Invalid voc path set to %d, in state %d\n",
1790 __func__, set, voice.voc_state);
1791 rc = -EPERM;
1792 }
1793
1794 mutex_unlock(&voice.lock);
1795
1796 return rc;
1797}
1798EXPORT_SYMBOL(voc_set_voc_path_full);
1799
1800void voc_register_mvs_cb(ul_cb_fn ul_cb,
1801 dl_cb_fn dl_cb,
1802 void *private_data)
1803{
1804 voice.mvs_info.ul_cb = ul_cb;
1805 voice.mvs_info.dl_cb = dl_cb;
1806 voice.mvs_info.private_data = private_data;
1807}
1808
1809void voc_config_vocoder(uint32_t media_type,
1810 uint32_t rate,
1811 uint32_t network_type)
1812{
1813 voice.mvs_info.media_type = media_type;
1814 voice.mvs_info.rate = rate;
1815 voice.mvs_info.network_type = network_type;
1816}
1817
1818static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv)
1819{
1820 uint32_t *ptr;
1821 struct voice_data *v;
1822
1823 if ((data == NULL) || (priv == NULL)) {
1824 pr_err("%s: data or priv is NULL\n", __func__);
1825 return -EINVAL;
1826 }
1827 v = priv;
1828
1829 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
1830 data->payload_size, data->opcode);
1831
1832 if (data->opcode == APR_BASIC_RSP_RESULT) {
1833 if (data->payload_size) {
1834 ptr = data->payload;
1835
1836 pr_info("%x %x\n", ptr[0], ptr[1]);
1837 /* ping mvm service ACK */
1838 switch (ptr[0]) {
1839 case VSS_IMVM_CMD_CREATE_PASSIVE_CONTROL_SESSION:
1840 case VSS_IMVM_CMD_CREATE_FULL_CONTROL_SESSION:
1841 /* Passive session is used for CS call
1842 * Full session is used for VoIP call. */
1843 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
1844 if (!ptr[1]) {
1845 pr_debug("%s: MVM handle is %d\n",
1846 __func__, data->src_port);
1847 voice_set_mvm_handle(v, data->src_port);
1848 } else
1849 pr_err("got NACK for sending \
1850 MVM create session \n");
1851 v->mvm_state = CMD_STATUS_SUCCESS;
1852 wake_up(&v->mvm_wait);
1853 break;
1854 case VSS_IMVM_CMD_START_VOICE:
1855 case VSS_ISTREAM_CMD_ATTACH_VOCPROC:
1856 case VSS_IMVM_CMD_STOP_VOICE:
1857 case VSS_ISTREAM_CMD_DETACH_VOCPROC:
1858 case VSS_ISTREAM_CMD_SET_TTY_MODE:
1859 case APRV2_IBASIC_CMD_DESTROY_SESSION:
1860 case VSS_IMVM_CMD_ATTACH_STREAM:
1861 case VSS_IMVM_CMD_DETACH_STREAM:
1862 case VSS_ICOMMON_CMD_SET_NETWORK:
1863 case VSS_ICOMMON_CMD_SET_VOICE_TIMING:
1864 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
1865 v->mvm_state = CMD_STATUS_SUCCESS;
1866 wake_up(&v->mvm_wait);
1867 break;
1868 default:
1869 pr_debug("%s: not match cmd = 0x%x\n",
1870 __func__, ptr[0]);
1871 break;
1872 }
1873 }
1874 }
1875
1876 return 0;
1877}
1878
1879static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv)
1880{
1881 uint32_t *ptr;
1882 struct voice_data *v;
1883
1884 if ((data == NULL) || (priv == NULL)) {
1885 pr_err("%s: data or priv is NULL\n", __func__);
1886 return -EINVAL;
1887 }
1888 v = priv;
1889
1890 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
1891 data->payload_size, data->opcode);
1892
1893 if (data->opcode == APR_BASIC_RSP_RESULT) {
1894 if (data->payload_size) {
1895 ptr = data->payload;
1896
1897 pr_info("%x %x\n", ptr[0], ptr[1]);
1898 /*response from CVS */
1899 switch (ptr[0]) {
1900 case VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION:
1901 case VSS_ISTREAM_CMD_CREATE_FULL_CONTROL_SESSION:
1902 if (!ptr[1]) {
1903 pr_debug("%s: CVS handle is %d\n",
1904 __func__, data->src_port);
1905 voice_set_cvs_handle(v, data->src_port);
1906 } else
1907 pr_err("got NACK for sending \
1908 CVS create session \n");
1909 v->cvs_state = CMD_STATUS_SUCCESS;
1910 wake_up(&v->cvs_wait);
1911 break;
1912 case VSS_ISTREAM_CMD_SET_MUTE:
1913 case VSS_ISTREAM_CMD_SET_MEDIA_TYPE:
1914 case VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE:
1915 case VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE:
1916 case VSS_ISTREAM_CMD_SET_ENC_DTX_MODE:
1917 case VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE:
1918 case APRV2_IBASIC_CMD_DESTROY_SESSION:
1919 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
1920 v->cvs_state = CMD_STATUS_SUCCESS;
1921 wake_up(&v->cvs_wait);
1922 break;
1923 default:
1924 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
1925 break;
1926 }
1927 }
1928 } else if (data->opcode == VSS_ISTREAM_EVT_SEND_ENC_BUFFER) {
1929 uint32_t *voc_pkt = data->payload;
1930 uint32_t pkt_len = data->payload_size;
1931
1932 if (voc_pkt != NULL && v->mvs_info.ul_cb != NULL) {
1933 pr_debug("%s: Media type is 0x%x\n",
1934 __func__, voc_pkt[0]);
1935
1936 /* Remove media ID from payload. */
1937 voc_pkt++;
1938 pkt_len = pkt_len - 4;
1939
1940 v->mvs_info.ul_cb((uint8_t *)voc_pkt,
1941 pkt_len,
1942 v->mvs_info.private_data);
1943 } else
1944 pr_err("%s: voc_pkt is 0x%x ul_cb is 0x%x\n",
1945 __func__, (unsigned int)voc_pkt,
1946 (unsigned int) v->mvs_info.ul_cb);
1947 } else if (data->opcode == VSS_ISTREAM_EVT_REQUEST_DEC_BUFFER) {
1948 struct cvs_send_dec_buf_cmd send_dec_buf;
1949 int ret = 0;
1950 uint32_t pkt_len = 0;
1951
1952 if (v->mvs_info.dl_cb != NULL) {
1953 send_dec_buf.dec_buf.media_id = v->mvs_info.media_type;
1954
1955 v->mvs_info.dl_cb(
1956 (uint8_t *)&send_dec_buf.dec_buf.packet_data,
1957 &pkt_len,
1958 v->mvs_info.private_data);
1959
1960 send_dec_buf.hdr.hdr_field =
1961 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1962 APR_HDR_LEN(APR_HDR_SIZE),
1963 APR_PKT_VER);
1964 send_dec_buf.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1965 sizeof(send_dec_buf.dec_buf.media_id) + pkt_len);
1966 send_dec_buf.hdr.src_port = 0;
1967 send_dec_buf.hdr.dest_port = voice_get_cvs_handle(v);
1968 send_dec_buf.hdr.token = 0;
1969 send_dec_buf.hdr.opcode =
1970 VSS_ISTREAM_EVT_SEND_DEC_BUFFER;
1971
1972 ret = apr_send_pkt(v->apr_q6_cvs,
1973 (uint32_t *) &send_dec_buf);
1974 if (ret < 0) {
1975 pr_err("%s: Error %d sending DEC_BUF\n",
1976 __func__, ret);
1977 goto fail;
1978 }
1979 } else
1980 pr_debug("%s: dl_cb is NULL\n", __func__);
1981 } else if (data->opcode == VSS_ISTREAM_EVT_SEND_DEC_BUFFER)
1982 pr_debug("Send dec buf resp\n");
1983
1984 else
1985 pr_debug("Unknown opcode 0x%x\n", data->opcode);
1986
1987fail:
1988 return 0;
1989}
1990
1991static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv)
1992{
1993 uint32_t *ptr;
1994 struct voice_data *v;
1995
1996 if ((data == NULL) || (priv == NULL)) {
1997 pr_err("%s: data or priv is NULL\n", __func__);
1998 return -EINVAL;
1999 }
2000 v = priv;
2001
2002 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
2003 data->payload_size, data->opcode);
2004
2005 if (data->opcode == APR_BASIC_RSP_RESULT) {
2006 if (data->payload_size) {
2007 ptr = data->payload;
2008
2009 pr_info("%x %x\n", ptr[0], ptr[1]);
2010
2011 switch (ptr[0]) {
2012 case VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION:
2013 /*response from CVP */
2014 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2015 if (!ptr[1]) {
2016 voice_set_cvp_handle(v, data->src_port);
2017 pr_debug("cvphdl=%d\n", data->src_port);
2018 } else
2019 pr_err("got NACK from CVP create \
2020 session response\n");
2021 v->cvp_state = CMD_STATUS_SUCCESS;
2022 wake_up(&v->cvp_wait);
2023 break;
2024 case VSS_IVOCPROC_CMD_SET_DEVICE:
2025 case VSS_IVOCPROC_CMD_SET_RX_VOLUME_INDEX:
2026 case VSS_IVOCPROC_CMD_ENABLE:
2027 case VSS_IVOCPROC_CMD_DISABLE:
2028 case APRV2_IBASIC_CMD_DESTROY_SESSION:
2029 v->cvp_state = CMD_STATUS_SUCCESS;
2030 wake_up(&v->cvp_wait);
2031 break;
2032 default:
2033 pr_debug("%s: not match cmd = 0x%x\n",
2034 __func__, ptr[0]);
2035 break;
2036 }
2037 }
2038 }
2039 return 0;
2040}
2041
2042
2043static int __init voice_init(void)
2044{
2045 int rc = 0;
2046 struct voice_data *v = &voice;
2047
2048 /* set default value */
2049 v->default_mute_val = 1; /* default is mute */
2050 v->default_vol_val = 0;
2051 v->default_sample_val = 8000;
2052 v->sidetone_gain = 0x512;
2053
2054 /* initialize dev_rx and dev_tx */
2055 memset(&v->dev_tx, 0, sizeof(struct device_data));
2056 memset(&v->dev_rx, 0, sizeof(struct device_data));
2057 v->dev_rx.volume = v->default_vol_val;
2058 v->dev_tx.mute = v->default_mute_val;
2059
2060 v->dev_tx.port_id = 1;
2061 v->dev_rx.port_id = 0;
2062
2063 v->voc_state = VOC_INIT;
2064 v->voc_path = VOC_PATH_PASSIVE;
2065 init_waitqueue_head(&v->mvm_wait);
2066 init_waitqueue_head(&v->cvs_wait);
2067 init_waitqueue_head(&v->cvp_wait);
2068
2069 mutex_init(&v->lock);
2070
2071 v->mvm_full_handle = 0;
2072 v->mvm_passive_handle = 0;
2073 v->cvs_full_handle = 0;
2074 v->cvs_passive_handle = 0;
2075 v->cvp_full_handle = 0;
2076 v->cvp_passive_handle = 0;
2077
2078 v->apr_q6_mvm = NULL;
2079 v->apr_q6_cvs = NULL;
2080 v->apr_q6_cvp = NULL;
2081
2082 /* Initialize MVS info. */
2083 memset(&v->mvs_info, 0, sizeof(v->mvs_info));
2084 v->mvs_info.network_type = VSS_NETWORK_ID_DEFAULT;
2085
2086 return rc;
2087}
2088
2089device_initcall(voice_init);