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