blob: a7a8c7a98004a37bca79bf94aaa089d87382f2ad [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;
Helen Zengbd58e2c2011-07-01 16:24:31 -07001598 struct sidetone_cal sidetone_cal_data;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001599 int ret = 0;
1600
1601 mutex_lock(&v->lock);
1602
1603 if (v->voc_state == VOC_CHANGE) {
1604 ret = voice_send_set_device_cmd(v);
1605 if (ret < 0) {
1606 pr_err("%s: set device failed\n", __func__);
1607 goto fail;
1608 }
1609 ret = voice_send_enable_vocproc_cmd(v);
1610 if (ret < 0) {
1611 pr_err("enable vocproc failed\n");
1612 goto fail;
1613 }
Helen Zengbd58e2c2011-07-01 16:24:31 -07001614 get_sidetone_cal(&sidetone_cal_data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001615 ret = afe_sidetone(v->dev_tx.port_id, v->dev_rx.port_id,
Helen Zengbd58e2c2011-07-01 16:24:31 -07001616 sidetone_cal_data.enable,
1617 sidetone_cal_data.gain);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001618
1619 if (ret < 0)
1620 pr_err("AFE command sidetone failed\n");
1621
1622 v->voc_state = VOC_RUN;
1623 }
1624
1625fail:
1626 mutex_unlock(&v->lock);
1627
1628 return ret;
1629}
1630
1631int voc_set_tx_mute(uint32_t dir, uint32_t mute)
1632{
1633 struct voice_data *v = &voice;
1634 int ret = 0;
1635
1636 mutex_lock(&v->lock);
1637
1638 v->dev_tx.mute = mute;
1639
1640 if (v->voc_state == VOC_RUN)
1641 ret = voice_send_mute_cmd(v);
1642
1643 mutex_unlock(&v->lock);
1644
1645 return ret;
1646}
1647
1648int voc_set_rx_vol_index(uint32_t dir, uint32_t vol_idx)
1649{
1650 struct voice_data *v = &voice;
1651 int ret = 0;
1652
1653 mutex_lock(&v->lock);
1654
1655 v->dev_rx.volume = vol_idx;
1656
1657 if (v->voc_state == VOC_RUN)
1658 ret = voice_send_vol_index_cmd(v);
1659
1660 mutex_unlock(&v->lock);
1661
1662 return ret;
1663}
1664
1665void voc_set_rxtx_port(uint32_t port_id, uint32_t dev_type)
1666{
1667 struct voice_data *v = &voice;
1668
1669 pr_debug(" port_id=%d, type=%d\n", port_id, dev_type);
1670
1671 mutex_lock(&v->lock);
1672
1673 if (dev_type == DEV_RX)
1674 v->dev_rx.port_id = port_id;
1675 else
1676 v->dev_tx.port_id = port_id;
1677
1678 mutex_unlock(&v->lock);
1679
1680 return;
1681}
1682
1683void voc_set_route_flag(uint8_t path_dir, uint8_t set)
1684{
1685 struct voice_data *v = &voice;
1686
1687 pr_debug("path_dir=%d, set=%d\n", path_dir, set);
1688
1689 mutex_lock(&v->lock);
1690
1691 if (path_dir == RX_PATH)
1692 v->voc_route_state.rx_route_flag = set;
1693 else
1694 v->voc_route_state.tx_route_flag = set;
1695
1696 mutex_unlock(&v->lock);
1697
1698 return;
1699}
1700
1701uint8_t voc_get_route_flag(uint8_t path_dir)
1702{
1703 struct voice_data *v = &voice;
1704 int ret = 0;
1705
1706 mutex_lock(&v->lock);
1707
1708 if (path_dir == RX_PATH)
1709 ret = v->voc_route_state.rx_route_flag;
1710 else
1711 ret = v->voc_route_state.tx_route_flag;
1712
1713 mutex_unlock(&v->lock);
1714
1715 return ret;
1716}
1717
1718int voc_end_voice_call(void)
1719{
1720 struct voice_data *v = &voice;
1721 int ret = 0;
1722
1723 mutex_lock(&v->lock);
1724
1725 if (v->voc_state == VOC_RUN) {
Helen Zengbd58e2c2011-07-01 16:24:31 -07001726 afe_sidetone(v->dev_tx.port_id, v->dev_rx.port_id, 0, 0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001727 ret = voice_destroy_vocproc(v);
1728 if (ret < 0)
1729 pr_err("%s: destroy voice failed\n", __func__);
1730 voice_destroy_mvm_cvs_session(v);
1731
1732 v->voc_state = VOC_RELEASE;
1733 }
1734 mutex_unlock(&v->lock);
1735 return ret;
1736}
1737
1738int voc_start_voice_call(void)
1739{
1740 struct voice_data *v = &voice;
Helen Zengbd58e2c2011-07-01 16:24:31 -07001741 struct sidetone_cal sidetone_cal_data;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001742 int ret = 0;
1743
1744 mutex_lock(&v->lock);
1745
1746 if ((v->voc_state == VOC_INIT) ||
1747 (v->voc_state == VOC_RELEASE)) {
1748 ret = voice_apr_register(v);
1749 if (ret < 0) {
1750 pr_err("%s: apr register failed\n", __func__);
1751 goto fail;
1752 }
1753 ret = voice_create_mvm_cvs_session(v);
1754 if (ret < 0) {
1755 pr_err("create mvm and cvs failed\n");
1756 goto fail;
1757 }
1758 ret = voice_setup_vocproc(v);
1759 if (ret < 0) {
1760 pr_err("setup voice failed\n");
1761 goto fail;
1762 }
1763 ret = voice_send_start_voice_cmd(v);
1764 if (ret < 0) {
1765 pr_err("start voice failed\n");
1766 goto fail;
1767 }
Helen Zengbd58e2c2011-07-01 16:24:31 -07001768 get_sidetone_cal(&sidetone_cal_data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001769 ret = afe_sidetone(v->dev_tx.port_id,
Helen Zengbd58e2c2011-07-01 16:24:31 -07001770 v->dev_rx.port_id,
1771 sidetone_cal_data.enable,
1772 sidetone_cal_data.gain);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001773 if (ret < 0)
1774 pr_err("AFE command sidetone failed\n");
1775
1776 v->voc_state = VOC_RUN;
1777 }
1778
1779fail: mutex_unlock(&v->lock);
1780 return ret;
1781}
1782
1783int voc_set_voc_path_full(uint32_t set)
1784{
1785 int rc = 0;
1786
1787 pr_debug("set voc path: %d\n", set);
1788
1789 mutex_lock(&voice.lock);
1790
1791 if (voice.voc_state == VOC_INIT || voice.voc_state == VOC_RELEASE) {
1792 if (set)
1793 voice.voc_path = VOC_PATH_FULL;
1794 else
1795 voice.voc_path = VOC_PATH_PASSIVE;
1796 } else {
1797 pr_err("%s: Invalid voc path set to %d, in state %d\n",
1798 __func__, set, voice.voc_state);
1799 rc = -EPERM;
1800 }
1801
1802 mutex_unlock(&voice.lock);
1803
1804 return rc;
1805}
1806EXPORT_SYMBOL(voc_set_voc_path_full);
1807
1808void voc_register_mvs_cb(ul_cb_fn ul_cb,
1809 dl_cb_fn dl_cb,
1810 void *private_data)
1811{
1812 voice.mvs_info.ul_cb = ul_cb;
1813 voice.mvs_info.dl_cb = dl_cb;
1814 voice.mvs_info.private_data = private_data;
1815}
1816
1817void voc_config_vocoder(uint32_t media_type,
1818 uint32_t rate,
1819 uint32_t network_type)
1820{
1821 voice.mvs_info.media_type = media_type;
1822 voice.mvs_info.rate = rate;
1823 voice.mvs_info.network_type = network_type;
1824}
1825
1826static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv)
1827{
1828 uint32_t *ptr;
1829 struct voice_data *v;
1830
1831 if ((data == NULL) || (priv == NULL)) {
1832 pr_err("%s: data or priv is NULL\n", __func__);
1833 return -EINVAL;
1834 }
1835 v = priv;
1836
1837 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
1838 data->payload_size, data->opcode);
1839
1840 if (data->opcode == APR_BASIC_RSP_RESULT) {
1841 if (data->payload_size) {
1842 ptr = data->payload;
1843
1844 pr_info("%x %x\n", ptr[0], ptr[1]);
1845 /* ping mvm service ACK */
1846 switch (ptr[0]) {
1847 case VSS_IMVM_CMD_CREATE_PASSIVE_CONTROL_SESSION:
1848 case VSS_IMVM_CMD_CREATE_FULL_CONTROL_SESSION:
1849 /* Passive session is used for CS call
1850 * Full session is used for VoIP call. */
1851 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
1852 if (!ptr[1]) {
1853 pr_debug("%s: MVM handle is %d\n",
1854 __func__, data->src_port);
1855 voice_set_mvm_handle(v, data->src_port);
1856 } else
1857 pr_err("got NACK for sending \
1858 MVM create session \n");
1859 v->mvm_state = CMD_STATUS_SUCCESS;
1860 wake_up(&v->mvm_wait);
1861 break;
1862 case VSS_IMVM_CMD_START_VOICE:
1863 case VSS_ISTREAM_CMD_ATTACH_VOCPROC:
1864 case VSS_IMVM_CMD_STOP_VOICE:
1865 case VSS_ISTREAM_CMD_DETACH_VOCPROC:
1866 case VSS_ISTREAM_CMD_SET_TTY_MODE:
1867 case APRV2_IBASIC_CMD_DESTROY_SESSION:
1868 case VSS_IMVM_CMD_ATTACH_STREAM:
1869 case VSS_IMVM_CMD_DETACH_STREAM:
1870 case VSS_ICOMMON_CMD_SET_NETWORK:
1871 case VSS_ICOMMON_CMD_SET_VOICE_TIMING:
1872 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
1873 v->mvm_state = CMD_STATUS_SUCCESS;
1874 wake_up(&v->mvm_wait);
1875 break;
1876 default:
1877 pr_debug("%s: not match cmd = 0x%x\n",
1878 __func__, ptr[0]);
1879 break;
1880 }
1881 }
1882 }
1883
1884 return 0;
1885}
1886
1887static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv)
1888{
1889 uint32_t *ptr;
1890 struct voice_data *v;
1891
1892 if ((data == NULL) || (priv == NULL)) {
1893 pr_err("%s: data or priv is NULL\n", __func__);
1894 return -EINVAL;
1895 }
1896 v = priv;
1897
1898 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
1899 data->payload_size, data->opcode);
1900
1901 if (data->opcode == APR_BASIC_RSP_RESULT) {
1902 if (data->payload_size) {
1903 ptr = data->payload;
1904
1905 pr_info("%x %x\n", ptr[0], ptr[1]);
1906 /*response from CVS */
1907 switch (ptr[0]) {
1908 case VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION:
1909 case VSS_ISTREAM_CMD_CREATE_FULL_CONTROL_SESSION:
1910 if (!ptr[1]) {
1911 pr_debug("%s: CVS handle is %d\n",
1912 __func__, data->src_port);
1913 voice_set_cvs_handle(v, data->src_port);
1914 } else
1915 pr_err("got NACK for sending \
1916 CVS create session \n");
1917 v->cvs_state = CMD_STATUS_SUCCESS;
1918 wake_up(&v->cvs_wait);
1919 break;
1920 case VSS_ISTREAM_CMD_SET_MUTE:
1921 case VSS_ISTREAM_CMD_SET_MEDIA_TYPE:
1922 case VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE:
1923 case VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE:
1924 case VSS_ISTREAM_CMD_SET_ENC_DTX_MODE:
1925 case VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE:
1926 case APRV2_IBASIC_CMD_DESTROY_SESSION:
1927 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
1928 v->cvs_state = CMD_STATUS_SUCCESS;
1929 wake_up(&v->cvs_wait);
1930 break;
1931 default:
1932 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
1933 break;
1934 }
1935 }
1936 } else if (data->opcode == VSS_ISTREAM_EVT_SEND_ENC_BUFFER) {
1937 uint32_t *voc_pkt = data->payload;
1938 uint32_t pkt_len = data->payload_size;
1939
1940 if (voc_pkt != NULL && v->mvs_info.ul_cb != NULL) {
1941 pr_debug("%s: Media type is 0x%x\n",
1942 __func__, voc_pkt[0]);
1943
1944 /* Remove media ID from payload. */
1945 voc_pkt++;
1946 pkt_len = pkt_len - 4;
1947
1948 v->mvs_info.ul_cb((uint8_t *)voc_pkt,
1949 pkt_len,
1950 v->mvs_info.private_data);
1951 } else
1952 pr_err("%s: voc_pkt is 0x%x ul_cb is 0x%x\n",
1953 __func__, (unsigned int)voc_pkt,
1954 (unsigned int) v->mvs_info.ul_cb);
1955 } else if (data->opcode == VSS_ISTREAM_EVT_REQUEST_DEC_BUFFER) {
1956 struct cvs_send_dec_buf_cmd send_dec_buf;
1957 int ret = 0;
1958 uint32_t pkt_len = 0;
1959
1960 if (v->mvs_info.dl_cb != NULL) {
1961 send_dec_buf.dec_buf.media_id = v->mvs_info.media_type;
1962
1963 v->mvs_info.dl_cb(
1964 (uint8_t *)&send_dec_buf.dec_buf.packet_data,
1965 &pkt_len,
1966 v->mvs_info.private_data);
1967
1968 send_dec_buf.hdr.hdr_field =
1969 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1970 APR_HDR_LEN(APR_HDR_SIZE),
1971 APR_PKT_VER);
1972 send_dec_buf.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1973 sizeof(send_dec_buf.dec_buf.media_id) + pkt_len);
1974 send_dec_buf.hdr.src_port = 0;
1975 send_dec_buf.hdr.dest_port = voice_get_cvs_handle(v);
1976 send_dec_buf.hdr.token = 0;
1977 send_dec_buf.hdr.opcode =
1978 VSS_ISTREAM_EVT_SEND_DEC_BUFFER;
1979
1980 ret = apr_send_pkt(v->apr_q6_cvs,
1981 (uint32_t *) &send_dec_buf);
1982 if (ret < 0) {
1983 pr_err("%s: Error %d sending DEC_BUF\n",
1984 __func__, ret);
1985 goto fail;
1986 }
1987 } else
1988 pr_debug("%s: dl_cb is NULL\n", __func__);
1989 } else if (data->opcode == VSS_ISTREAM_EVT_SEND_DEC_BUFFER)
1990 pr_debug("Send dec buf resp\n");
1991
1992 else
1993 pr_debug("Unknown opcode 0x%x\n", data->opcode);
1994
1995fail:
1996 return 0;
1997}
1998
1999static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv)
2000{
2001 uint32_t *ptr;
2002 struct voice_data *v;
2003
2004 if ((data == NULL) || (priv == NULL)) {
2005 pr_err("%s: data or priv is NULL\n", __func__);
2006 return -EINVAL;
2007 }
2008 v = priv;
2009
2010 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
2011 data->payload_size, data->opcode);
2012
2013 if (data->opcode == APR_BASIC_RSP_RESULT) {
2014 if (data->payload_size) {
2015 ptr = data->payload;
2016
2017 pr_info("%x %x\n", ptr[0], ptr[1]);
2018
2019 switch (ptr[0]) {
2020 case VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION:
2021 /*response from CVP */
2022 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2023 if (!ptr[1]) {
2024 voice_set_cvp_handle(v, data->src_port);
2025 pr_debug("cvphdl=%d\n", data->src_port);
2026 } else
2027 pr_err("got NACK from CVP create \
2028 session response\n");
2029 v->cvp_state = CMD_STATUS_SUCCESS;
2030 wake_up(&v->cvp_wait);
2031 break;
2032 case VSS_IVOCPROC_CMD_SET_DEVICE:
2033 case VSS_IVOCPROC_CMD_SET_RX_VOLUME_INDEX:
2034 case VSS_IVOCPROC_CMD_ENABLE:
2035 case VSS_IVOCPROC_CMD_DISABLE:
2036 case APRV2_IBASIC_CMD_DESTROY_SESSION:
2037 v->cvp_state = CMD_STATUS_SUCCESS;
2038 wake_up(&v->cvp_wait);
2039 break;
2040 default:
2041 pr_debug("%s: not match cmd = 0x%x\n",
2042 __func__, ptr[0]);
2043 break;
2044 }
2045 }
2046 }
2047 return 0;
2048}
2049
2050
2051static int __init voice_init(void)
2052{
2053 int rc = 0;
2054 struct voice_data *v = &voice;
2055
2056 /* set default value */
2057 v->default_mute_val = 1; /* default is mute */
2058 v->default_vol_val = 0;
2059 v->default_sample_val = 8000;
2060 v->sidetone_gain = 0x512;
2061
2062 /* initialize dev_rx and dev_tx */
2063 memset(&v->dev_tx, 0, sizeof(struct device_data));
2064 memset(&v->dev_rx, 0, sizeof(struct device_data));
2065 v->dev_rx.volume = v->default_vol_val;
2066 v->dev_tx.mute = v->default_mute_val;
2067
2068 v->dev_tx.port_id = 1;
2069 v->dev_rx.port_id = 0;
2070
2071 v->voc_state = VOC_INIT;
2072 v->voc_path = VOC_PATH_PASSIVE;
2073 init_waitqueue_head(&v->mvm_wait);
2074 init_waitqueue_head(&v->cvs_wait);
2075 init_waitqueue_head(&v->cvp_wait);
2076
2077 mutex_init(&v->lock);
2078
2079 v->mvm_full_handle = 0;
2080 v->mvm_passive_handle = 0;
2081 v->cvs_full_handle = 0;
2082 v->cvs_passive_handle = 0;
2083 v->cvp_full_handle = 0;
2084 v->cvp_passive_handle = 0;
2085
2086 v->apr_q6_mvm = NULL;
2087 v->apr_q6_cvs = NULL;
2088 v->apr_q6_cvp = NULL;
2089
2090 /* Initialize MVS info. */
2091 memset(&v->mvs_info, 0, sizeof(v->mvs_info));
2092 v->mvs_info.network_type = VSS_NETWORK_ID_DEFAULT;
2093
2094 return rc;
2095}
2096
2097device_initcall(voice_init);