blob: d9c7b5c9896bf9923abe0bf2b78bcc2845fc58a6 [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{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700561 int ret = 0;
562 struct mvm_set_tty_mode_cmd mvm_tty_mode_cmd;
563 void *apr_mvm;
564 u16 mvm_handle;
565
566 if (v == NULL) {
567 pr_err("%s: v is NULL\n", __func__);
568 return -EINVAL;
569 }
570 apr_mvm = v->apr_q6_mvm;
571
572 if (!apr_mvm) {
573 pr_err("%s: apr_mvm is NULL.\n", __func__);
574 return -EINVAL;
575 }
576 mvm_handle = voice_get_mvm_handle(v);
577
Helen Zengcc65b5b2011-07-06 19:14:48 -0700578 if (v->tty_mode) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700579 /* send tty mode cmd to mvm */
580 mvm_tty_mode_cmd.hdr.hdr_field = APR_HDR_FIELD(
581 APR_MSG_TYPE_SEQ_CMD,
582 APR_HDR_LEN(APR_HDR_SIZE),
583 APR_PKT_VER);
584 mvm_tty_mode_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
585 sizeof(mvm_tty_mode_cmd) -
586 APR_HDR_SIZE);
587 pr_debug("pkt size = %d\n", mvm_tty_mode_cmd.hdr.pkt_size);
588 mvm_tty_mode_cmd.hdr.src_port = 0;
589 mvm_tty_mode_cmd.hdr.dest_port = mvm_handle;
590 mvm_tty_mode_cmd.hdr.token = 0;
591 mvm_tty_mode_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_TTY_MODE;
Helen Zengcc65b5b2011-07-06 19:14:48 -0700592 mvm_tty_mode_cmd.tty_mode.mode = v->tty_mode;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700593 pr_debug("tty mode =%d\n", mvm_tty_mode_cmd.tty_mode.mode);
594
595 v->mvm_state = CMD_STATUS_FAIL;
596 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_tty_mode_cmd);
597 if (ret < 0) {
598 pr_err("Fail: sending VSS_ISTREAM_CMD_SET_TTY_MODE\n");
599 goto fail;
600 }
601 ret = wait_event_timeout(v->mvm_wait,
602 (v->mvm_state == CMD_STATUS_SUCCESS),
603 msecs_to_jiffies(TIMEOUT_MS));
604 if (!ret) {
605 pr_err("%s: wait_event timeout\n", __func__);
606 goto fail;
607 }
608 }
609 return 0;
610fail:
611 return -EINVAL;
612}
613
614static int voice_config_cvs_vocoder(struct voice_data *v)
615{
616 int ret = 0;
617 void *apr_cvs;
618 u16 cvs_handle;
619 /* Set media type. */
620 struct cvs_set_media_type_cmd cvs_set_media_cmd;
621
622 if (v == NULL) {
623 pr_err("%s: v is NULL\n", __func__);
624 return -EINVAL;
625 }
626 apr_cvs = v->apr_q6_cvs;
627
628 if (!apr_cvs) {
629 pr_err("%s: apr_cvs is NULL.\n", __func__);
630 return -EINVAL;
631 }
632
633 cvs_handle = voice_get_cvs_handle(v);
634
635 cvs_set_media_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
636 APR_HDR_LEN(APR_HDR_SIZE),
637 APR_PKT_VER);
638 cvs_set_media_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
639 sizeof(cvs_set_media_cmd) - APR_HDR_SIZE);
640 cvs_set_media_cmd.hdr.src_port = 0;
641 cvs_set_media_cmd.hdr.dest_port = cvs_handle;
642 cvs_set_media_cmd.hdr.token = 0;
643 cvs_set_media_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_MEDIA_TYPE;
644 cvs_set_media_cmd.media_type.tx_media_id = v->mvs_info.media_type;
645 cvs_set_media_cmd.media_type.rx_media_id = v->mvs_info.media_type;
646
647 v->cvs_state = CMD_STATUS_FAIL;
648
649 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_media_cmd);
650 if (ret < 0) {
651 pr_err("%s: Error %d sending SET_MEDIA_TYPE\n",
652 __func__, ret);
653
654 goto fail;
655 }
656 ret = wait_event_timeout(v->cvs_wait,
657 (v->cvs_state == CMD_STATUS_SUCCESS),
658 msecs_to_jiffies(TIMEOUT_MS));
659 if (!ret) {
660 pr_err("%s: wait_event timeout\n", __func__);
661
662 goto fail;
663 }
664 /* Set encoder properties. */
665 switch (v->mvs_info.media_type) {
666 case VSS_MEDIA_ID_EVRC_MODEM: {
667 struct cvs_set_cdma_enc_minmax_rate_cmd cvs_set_cdma_rate;
668
669 pr_debug("Setting EVRC min-max rate\n");
670
671 cvs_set_cdma_rate.hdr.hdr_field =
672 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
673 APR_HDR_LEN(APR_HDR_SIZE),
674 APR_PKT_VER);
675 cvs_set_cdma_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
676 sizeof(cvs_set_cdma_rate) - APR_HDR_SIZE);
677 cvs_set_cdma_rate.hdr.src_port = 0;
678 cvs_set_cdma_rate.hdr.dest_port = cvs_handle;
679 cvs_set_cdma_rate.hdr.token = 0;
680 cvs_set_cdma_rate.hdr.opcode =
681 VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE;
682 cvs_set_cdma_rate.cdma_rate.min_rate = v->mvs_info.rate;
683 cvs_set_cdma_rate.cdma_rate.max_rate = v->mvs_info.rate;
684
685 v->cvs_state = CMD_STATUS_FAIL;
686
687 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_cdma_rate);
688 if (ret < 0) {
689 pr_err("%s: Error %d sending SET_EVRC_MINMAX_RATE\n",
690 __func__, ret);
691 goto fail;
692 }
693 ret = wait_event_timeout(v->cvs_wait,
694 (v->cvs_state == CMD_STATUS_SUCCESS),
695 msecs_to_jiffies(TIMEOUT_MS));
696 if (!ret) {
697 pr_err("%s: wait_event timeout\n", __func__);
698
699 goto fail;
700 }
701 break;
702 }
703 case VSS_MEDIA_ID_AMR_NB_MODEM: {
704 struct cvs_set_amr_enc_rate_cmd cvs_set_amr_rate;
705 struct cvs_set_enc_dtx_mode_cmd cvs_set_dtx;
706
707 pr_debug("Setting AMR rate\n");
708
709 cvs_set_amr_rate.hdr.hdr_field =
710 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
711 APR_HDR_LEN(APR_HDR_SIZE),
712 APR_PKT_VER);
713 cvs_set_amr_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
714 sizeof(cvs_set_amr_rate) - APR_HDR_SIZE);
715 cvs_set_amr_rate.hdr.src_port = 0;
716 cvs_set_amr_rate.hdr.dest_port = cvs_handle;
717 cvs_set_amr_rate.hdr.token = 0;
718 cvs_set_amr_rate.hdr.opcode =
719 VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE;
720 cvs_set_amr_rate.amr_rate.mode = v->mvs_info.rate;
721
722 v->cvs_state = CMD_STATUS_FAIL;
723
724 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_amr_rate);
725 if (ret < 0) {
726 pr_err("%s: Error %d sending SET_AMR_RATE\n",
727 __func__, ret);
728 goto fail;
729 }
730 ret = wait_event_timeout(v->cvs_wait,
731 (v->cvs_state == CMD_STATUS_SUCCESS),
732 msecs_to_jiffies(TIMEOUT_MS));
733 if (!ret) {
734 pr_err("%s: wait_event timeout\n", __func__);
735 goto fail;
736 }
737 /* Disable DTX */
738 pr_debug("Disabling DTX\n");
739
740 cvs_set_dtx.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
741 APR_HDR_LEN(APR_HDR_SIZE),
742 APR_PKT_VER);
743 cvs_set_dtx.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
744 sizeof(cvs_set_dtx) - APR_HDR_SIZE);
745 cvs_set_dtx.hdr.src_port = 0;
746 cvs_set_dtx.hdr.dest_port = cvs_handle;
747 cvs_set_dtx.hdr.token = 0;
748 cvs_set_dtx.hdr.opcode = VSS_ISTREAM_CMD_SET_ENC_DTX_MODE;
749 cvs_set_dtx.dtx_mode.enable = 0;
750
751 v->cvs_state = CMD_STATUS_FAIL;
752
753 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_dtx);
754 if (ret < 0) {
755 pr_err("%s: Error %d sending SET_DTX\n",
756 __func__, ret);
757 goto fail;
758 }
759 ret = wait_event_timeout(v->cvs_wait,
760 (v->cvs_state == CMD_STATUS_SUCCESS),
761 msecs_to_jiffies(TIMEOUT_MS));
762 if (!ret) {
763 pr_err("%s: wait_event timeout\n", __func__);
764 goto fail;
765 }
766 break;
767 }
768 case VSS_MEDIA_ID_AMR_WB_MODEM: {
769 struct cvs_set_amrwb_enc_rate_cmd cvs_set_amrwb_rate;
770 struct cvs_set_enc_dtx_mode_cmd cvs_set_dtx;
771
772 pr_debug("Setting AMR WB rate\n");
773
774 cvs_set_amrwb_rate.hdr.hdr_field =
775 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
776 APR_HDR_LEN(APR_HDR_SIZE),
777 APR_PKT_VER);
778 cvs_set_amrwb_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
779 sizeof(cvs_set_amrwb_rate) -
780 APR_HDR_SIZE);
781 cvs_set_amrwb_rate.hdr.src_port = 0;
782 cvs_set_amrwb_rate.hdr.dest_port = cvs_handle;
783 cvs_set_amrwb_rate.hdr.token = 0;
784 cvs_set_amrwb_rate.hdr.opcode =
785 VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE;
786 cvs_set_amrwb_rate.amrwb_rate.mode = v->mvs_info.rate;
787
788 v->cvs_state = CMD_STATUS_FAIL;
789
790 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_amrwb_rate);
791 if (ret < 0) {
792 pr_err("%s: Error %d sending SET_AMRWB_RATE\n",
793 __func__, ret);
794 goto fail;
795 }
796 ret = wait_event_timeout(v->cvs_wait,
797 (v->cvs_state == CMD_STATUS_SUCCESS),
798 msecs_to_jiffies(TIMEOUT_MS));
799 if (!ret) {
800 pr_err("%s: wait_event timeout\n", __func__);
801 goto fail;
802 }
803 /* Disable DTX */
804 pr_debug("Disabling DTX\n");
805
806 cvs_set_dtx.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
807 APR_HDR_LEN(APR_HDR_SIZE),
808 APR_PKT_VER);
809 cvs_set_dtx.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
810 sizeof(cvs_set_dtx) - APR_HDR_SIZE);
811 cvs_set_dtx.hdr.src_port = 0;
812 cvs_set_dtx.hdr.dest_port = cvs_handle;
813 cvs_set_dtx.hdr.token = 0;
814 cvs_set_dtx.hdr.opcode = VSS_ISTREAM_CMD_SET_ENC_DTX_MODE;
815 cvs_set_dtx.dtx_mode.enable = 0;
816
817 v->cvs_state = CMD_STATUS_FAIL;
818
819 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_dtx);
820 if (ret < 0) {
821 pr_err("%s: Error %d sending SET_DTX\n",
822 __func__, ret);
823 goto fail;
824 }
825 ret = wait_event_timeout(v->cvs_wait,
826 (v->cvs_state == CMD_STATUS_SUCCESS),
827 msecs_to_jiffies(TIMEOUT_MS));
828 if (!ret) {
829 pr_err("%s: wait_event timeout\n", __func__);
830 goto fail;
831 }
832 break;
833 }
834 case VSS_MEDIA_ID_G729:
835 case VSS_MEDIA_ID_G711_ALAW:
836 case VSS_MEDIA_ID_G711_MULAW: {
837 struct cvs_set_enc_dtx_mode_cmd cvs_set_dtx;
838 /* Disable DTX */
839 pr_debug("Disabling DTX\n");
840
841 cvs_set_dtx.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
842 APR_HDR_LEN(APR_HDR_SIZE),
843 APR_PKT_VER);
844 cvs_set_dtx.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
845 sizeof(cvs_set_dtx) - APR_HDR_SIZE);
846 cvs_set_dtx.hdr.src_port = 0;
847 cvs_set_dtx.hdr.dest_port = cvs_handle;
848 cvs_set_dtx.hdr.token = 0;
849 cvs_set_dtx.hdr.opcode = VSS_ISTREAM_CMD_SET_ENC_DTX_MODE;
850 cvs_set_dtx.dtx_mode.enable = 0;
851
852 v->cvs_state = CMD_STATUS_FAIL;
853
854 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_dtx);
855 if (ret < 0) {
856 pr_err("%s: Error %d sending SET_DTX\n",
857 __func__, ret);
858 goto fail;
859 }
860 ret = wait_event_timeout(v->cvs_wait,
861 (v->cvs_state == CMD_STATUS_SUCCESS),
862 msecs_to_jiffies(TIMEOUT_MS));
863 if (!ret) {
864 pr_err("%s: wait_event timeout\n", __func__);
865 goto fail;
866 }
867 break;
868 }
869 default:
870 /* Do nothing. */
871 break;
872 }
873 return 0;
874
875fail:
876 return -EINVAL;
877}
878
879static int voice_send_start_voice_cmd(struct voice_data *v)
880{
881 struct apr_hdr mvm_start_voice_cmd;
882 int ret = 0;
883 void *apr_mvm;
884 u16 mvm_handle;
885
886 if (v == NULL) {
887 pr_err("%s: v is NULL\n", __func__);
888 return -EINVAL;
889 }
890 apr_mvm = v->apr_q6_mvm;
891
892 if (!apr_mvm) {
893 pr_err("%s: apr_mvm is NULL.\n", __func__);
894 return -EINVAL;
895 }
896 mvm_handle = voice_get_mvm_handle(v);
897
898 mvm_start_voice_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
899 APR_HDR_LEN(APR_HDR_SIZE),
900 APR_PKT_VER);
901 mvm_start_voice_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
902 sizeof(mvm_start_voice_cmd) - APR_HDR_SIZE);
903 pr_debug("send mvm_start_voice_cmd pkt size = %d\n",
904 mvm_start_voice_cmd.pkt_size);
905 mvm_start_voice_cmd.src_port = 0;
906 mvm_start_voice_cmd.dest_port = mvm_handle;
907 mvm_start_voice_cmd.token = 0;
908 mvm_start_voice_cmd.opcode = VSS_IMVM_CMD_START_VOICE;
909
910 v->mvm_state = CMD_STATUS_FAIL;
911 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_start_voice_cmd);
912 if (ret < 0) {
913 pr_err("Fail in sending VSS_IMVM_CMD_START_VOICE\n");
914 goto fail;
915 }
916 ret = wait_event_timeout(v->mvm_wait,
917 (v->mvm_state == CMD_STATUS_SUCCESS),
918 msecs_to_jiffies(TIMEOUT_MS));
919 if (!ret) {
920 pr_err("%s: wait_event timeout\n", __func__);
921 goto fail;
922 }
923 return 0;
924fail:
925 return -EINVAL;
926}
927
928static int voice_send_disable_vocproc_cmd(struct voice_data *v)
929{
930 struct apr_hdr cvp_disable_cmd;
931 int ret = 0;
932 void *apr_cvp;
933 u16 cvp_handle;
934
935 if (v == NULL) {
936 pr_err("%s: v is NULL\n", __func__);
937 return -EINVAL;
938 }
939 apr_cvp = v->apr_q6_cvp;
940
941 if (!apr_cvp) {
942 pr_err("%s: apr regist failed\n", __func__);
943 return -EINVAL;
944 }
945 cvp_handle = voice_get_cvp_handle(v);
946
947 /* disable vocproc and wait for respose */
948 cvp_disable_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
949 APR_HDR_LEN(APR_HDR_SIZE),
950 APR_PKT_VER);
951 cvp_disable_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
952 sizeof(cvp_disable_cmd) - APR_HDR_SIZE);
953 pr_debug("cvp_disable_cmd pkt size = %d, cvp_handle=%d\n",
954 cvp_disable_cmd.pkt_size, cvp_handle);
955 cvp_disable_cmd.src_port = 0;
956 cvp_disable_cmd.dest_port = cvp_handle;
957 cvp_disable_cmd.token = 0;
958 cvp_disable_cmd.opcode = VSS_IVOCPROC_CMD_DISABLE;
959
960 v->cvp_state = CMD_STATUS_FAIL;
961 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_disable_cmd);
962 if (ret < 0) {
963 pr_err("Fail in sending VSS_IVOCPROC_CMD_DISABLE\n");
964 goto fail;
965 }
966 ret = wait_event_timeout(v->cvp_wait,
967 (v->cvp_state == CMD_STATUS_SUCCESS),
968 msecs_to_jiffies(TIMEOUT_MS));
969 if (!ret) {
970 pr_err("%s: wait_event timeout\n", __func__);
971 goto fail;
972 }
973
974 return 0;
975fail:
976 return -EINVAL;
977}
978
979static int voice_send_set_device_cmd(struct voice_data *v)
980{
981 struct cvp_set_device_cmd cvp_setdev_cmd;
982 int ret = 0;
983 void *apr_cvp;
984 u16 cvp_handle;
985
986 if (v == NULL) {
987 pr_err("%s: v is NULL\n", __func__);
988 return -EINVAL;
989 }
990 apr_cvp = v->apr_q6_cvp;
991
992 if (!apr_cvp) {
993 pr_err("%s: apr_cvp is NULL.\n", __func__);
994 return -EINVAL;
995 }
996 cvp_handle = voice_get_cvp_handle(v);
997
998 /* set device and wait for response */
999 cvp_setdev_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1000 APR_HDR_LEN(APR_HDR_SIZE),
1001 APR_PKT_VER);
1002 cvp_setdev_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1003 sizeof(cvp_setdev_cmd) - APR_HDR_SIZE);
1004 pr_debug(" send create cvp setdev, pkt size = %d\n",
1005 cvp_setdev_cmd.hdr.pkt_size);
1006 cvp_setdev_cmd.hdr.src_port = 0;
1007 cvp_setdev_cmd.hdr.dest_port = cvp_handle;
1008 cvp_setdev_cmd.hdr.token = 0;
1009 cvp_setdev_cmd.hdr.opcode = VSS_IVOCPROC_CMD_SET_DEVICE;
1010
1011 /* Use default topology if invalid value in ACDB */
1012 cvp_setdev_cmd.cvp_set_device.tx_topology_id =
1013 get_voice_tx_topology();
1014 if (cvp_setdev_cmd.cvp_set_device.tx_topology_id == 0)
1015 cvp_setdev_cmd.cvp_set_device.tx_topology_id =
1016 VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
1017
1018 cvp_setdev_cmd.cvp_set_device.rx_topology_id =
1019 get_voice_rx_topology();
1020 if (cvp_setdev_cmd.cvp_set_device.rx_topology_id == 0)
1021 cvp_setdev_cmd.cvp_set_device.rx_topology_id =
1022 VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
1023 cvp_setdev_cmd.cvp_set_device.tx_port_id = v->dev_tx.port_id;
1024 cvp_setdev_cmd.cvp_set_device.rx_port_id = v->dev_rx.port_id;
1025 pr_debug("topology=%d , tx_port_id=%d, rx_port_id=%d\n",
1026 cvp_setdev_cmd.cvp_set_device.tx_topology_id,
1027 cvp_setdev_cmd.cvp_set_device.tx_port_id,
1028 cvp_setdev_cmd.cvp_set_device.rx_port_id);
1029
1030 v->cvp_state = CMD_STATUS_FAIL;
1031 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_setdev_cmd);
1032 if (ret < 0) {
1033 pr_err("Fail in sending VOCPROC_FULL_CONTROL_SESSION\n");
1034 goto fail;
1035 }
1036 pr_debug("wait for cvp create session event\n");
1037 ret = wait_event_timeout(v->cvp_wait,
1038 (v->cvp_state == CMD_STATUS_SUCCESS),
1039 msecs_to_jiffies(TIMEOUT_MS));
1040 if (!ret) {
1041 pr_err("%s: wait_event timeout\n", __func__);
1042 goto fail;
1043 }
1044
1045 return 0;
1046fail:
1047 return -EINVAL;
1048}
1049
1050static int voice_send_stop_voice_cmd(struct voice_data *v)
1051{
1052 struct apr_hdr mvm_stop_voice_cmd;
1053 int ret = 0;
1054 void *apr_mvm;
1055 u16 mvm_handle;
1056
1057 if (v == NULL) {
1058 pr_err("%s: v is NULL\n", __func__);
1059 return -EINVAL;
1060 }
1061 apr_mvm = v->apr_q6_mvm;
1062
1063 if (!apr_mvm) {
1064 pr_err("%s: apr_mvm is NULL.\n", __func__);
1065 return -EINVAL;
1066 }
1067 mvm_handle = voice_get_mvm_handle(v);
1068
1069 mvm_stop_voice_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1070 APR_HDR_LEN(APR_HDR_SIZE),
1071 APR_PKT_VER);
1072 mvm_stop_voice_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1073 sizeof(mvm_stop_voice_cmd) - APR_HDR_SIZE);
1074 pr_debug("send mvm_stop_voice_cmd pkt size = %d\n",
1075 mvm_stop_voice_cmd.pkt_size);
1076 mvm_stop_voice_cmd.src_port = 0;
1077 mvm_stop_voice_cmd.dest_port = mvm_handle;
1078 mvm_stop_voice_cmd.token = 0;
1079 mvm_stop_voice_cmd.opcode = VSS_IMVM_CMD_STOP_VOICE;
1080
1081 v->mvm_state = CMD_STATUS_FAIL;
1082 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_stop_voice_cmd);
1083 if (ret < 0) {
1084 pr_err("Fail in sending VSS_IMVM_CMD_STOP_VOICE\n");
1085 goto fail;
1086 }
1087 ret = wait_event_timeout(v->mvm_wait,
1088 (v->mvm_state == CMD_STATUS_SUCCESS),
1089 msecs_to_jiffies(TIMEOUT_MS));
1090 if (!ret) {
1091 pr_err("%s: wait_event timeout\n", __func__);
1092 goto fail;
1093 }
1094
1095 return 0;
1096fail:
1097 return -EINVAL;
1098}
1099
1100static int voice_setup_vocproc(struct voice_data *v)
1101{
1102 struct cvp_create_full_ctl_session_cmd cvp_session_cmd;
1103 int ret = 0;
1104 void *apr_cvp;
1105 if (v == NULL) {
1106 pr_err("%s: v is NULL\n", __func__);
1107 return -EINVAL;
1108 }
1109 apr_cvp = v->apr_q6_cvp;
1110
1111 if (!apr_cvp) {
1112 pr_err("%s: apr_cvp is NULL.\n", __func__);
1113 return -EINVAL;
1114 }
1115
1116 /* create cvp session and wait for response */
1117 cvp_session_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1118 APR_HDR_LEN(APR_HDR_SIZE),
1119 APR_PKT_VER);
1120 cvp_session_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1121 sizeof(cvp_session_cmd) - APR_HDR_SIZE);
1122 pr_debug(" send create cvp session, pkt size = %d\n",
1123 cvp_session_cmd.hdr.pkt_size);
1124 cvp_session_cmd.hdr.src_port = 0;
1125 cvp_session_cmd.hdr.dest_port = 0;
1126 cvp_session_cmd.hdr.token = 0;
1127 cvp_session_cmd.hdr.opcode =
1128 VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION;
1129
1130 /* Use default topology if invalid value in ACDB */
1131 cvp_session_cmd.cvp_session.tx_topology_id =
1132 get_voice_tx_topology();
1133 if (cvp_session_cmd.cvp_session.tx_topology_id == 0)
1134 cvp_session_cmd.cvp_session.tx_topology_id =
1135 VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
1136
1137 cvp_session_cmd.cvp_session.rx_topology_id =
1138 get_voice_rx_topology();
1139 if (cvp_session_cmd.cvp_session.rx_topology_id == 0)
1140 cvp_session_cmd.cvp_session.rx_topology_id =
1141 VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
1142
1143 cvp_session_cmd.cvp_session.direction = 2; /*tx and rx*/
1144 cvp_session_cmd.cvp_session.network_id = VSS_NETWORK_ID_DEFAULT;
1145 cvp_session_cmd.cvp_session.tx_port_id = v->dev_tx.port_id;
1146 cvp_session_cmd.cvp_session.rx_port_id = v->dev_rx.port_id;
1147
1148 pr_debug("topology=%d net_id=%d, dir=%d tx_port_id=%d, rx_port_id=%d\n",
1149 cvp_session_cmd.cvp_session.tx_topology_id,
1150 cvp_session_cmd.cvp_session.network_id,
1151 cvp_session_cmd.cvp_session.direction,
1152 cvp_session_cmd.cvp_session.tx_port_id,
1153 cvp_session_cmd.cvp_session.rx_port_id);
1154
1155 v->cvp_state = CMD_STATUS_FAIL;
1156 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_session_cmd);
1157 if (ret < 0) {
1158 pr_err("Fail in sending VOCPROC_FULL_CONTROL_SESSION\n");
1159 goto fail;
1160 }
1161 ret = wait_event_timeout(v->cvp_wait,
1162 (v->cvp_state == CMD_STATUS_SUCCESS),
1163 msecs_to_jiffies(TIMEOUT_MS));
1164 if (!ret) {
1165 pr_err("%s: wait_event timeout\n", __func__);
1166 goto fail;
1167 }
1168
1169 /* enable vocproc */
1170 ret = voice_send_enable_vocproc_cmd(v);
1171 if (ret < 0)
1172 goto fail;
1173
1174 /* attach vocproc */
1175 ret = voice_send_attach_vocproc_cmd(v);
1176 if (ret < 0)
1177 goto fail;
1178
1179 /* send tty mode if tty device is used */
1180 voice_send_tty_mode_cmd(v);
1181
1182 if (v->voc_path == VOC_PATH_FULL)
1183 voice_send_netid_timing_cmd(v);
1184
1185 return 0;
1186
1187fail:
1188 return -EINVAL;
1189}
1190
1191static int voice_send_enable_vocproc_cmd(struct voice_data *v)
1192{
1193 int ret = 0;
1194 struct apr_hdr cvp_enable_cmd;
1195 void *apr_cvp;
1196 u16 cvp_handle;
1197
1198 if (v == NULL) {
1199 pr_err("%s: v is NULL\n", __func__);
1200 return -EINVAL;
1201 }
1202 apr_cvp = v->apr_q6_cvp;
1203
1204 if (!apr_cvp) {
1205 pr_err("%s: apr_cvp is NULL.\n", __func__);
1206 return -EINVAL;
1207 }
1208 cvp_handle = voice_get_cvp_handle(v);
1209
1210 /* enable vocproc and wait for respose */
1211 cvp_enable_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1212 APR_HDR_LEN(APR_HDR_SIZE),
1213 APR_PKT_VER);
1214 cvp_enable_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1215 sizeof(cvp_enable_cmd) - APR_HDR_SIZE);
1216 pr_debug("cvp_enable_cmd pkt size = %d, cvp_handle=%d\n",
1217 cvp_enable_cmd.pkt_size, cvp_handle);
1218 cvp_enable_cmd.src_port = 0;
1219 cvp_enable_cmd.dest_port = cvp_handle;
1220 cvp_enable_cmd.token = 0;
1221 cvp_enable_cmd.opcode = VSS_IVOCPROC_CMD_ENABLE;
1222
1223 v->cvp_state = CMD_STATUS_FAIL;
1224 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_enable_cmd);
1225 if (ret < 0) {
1226 pr_err("Fail in sending VSS_IVOCPROC_CMD_ENABLE\n");
1227 goto fail;
1228 }
1229 ret = wait_event_timeout(v->cvp_wait,
1230 (v->cvp_state == CMD_STATUS_SUCCESS),
1231 msecs_to_jiffies(TIMEOUT_MS));
1232 if (!ret) {
1233 pr_err("%s: wait_event timeout\n", __func__);
1234 goto fail;
1235 }
1236
1237 return 0;
1238fail:
1239 return -EINVAL;
1240}
1241
1242static int voice_send_netid_timing_cmd(struct voice_data *v)
1243{
1244 int ret = 0;
1245 void *apr_mvm;
1246 u16 mvm_handle;
1247 struct mvm_set_network_cmd mvm_set_network;
1248 struct mvm_set_voice_timing_cmd mvm_set_voice_timing;
1249
1250 if (v == NULL) {
1251 pr_err("%s: v is NULL\n", __func__);
1252 return -EINVAL;
1253 }
1254 apr_mvm = v->apr_q6_mvm;
1255
1256 if (!apr_mvm) {
1257 pr_err("%s: apr_mvm is NULL.\n", __func__);
1258 return -EINVAL;
1259 }
1260 mvm_handle = voice_get_mvm_handle(v);
1261
1262 ret = voice_config_cvs_vocoder(v);
1263 if (ret < 0) {
1264 pr_err("%s: Error %d configuring CVS voc",
1265 __func__, ret);
1266 goto fail;
1267 }
1268 /* Set network ID. */
1269 pr_debug("Setting network ID\n");
1270
1271 mvm_set_network.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1272 APR_HDR_LEN(APR_HDR_SIZE),
1273 APR_PKT_VER);
1274 mvm_set_network.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1275 sizeof(mvm_set_network) - APR_HDR_SIZE);
1276 mvm_set_network.hdr.src_port = 0;
1277 mvm_set_network.hdr.dest_port = mvm_handle;
1278 mvm_set_network.hdr.token = 0;
1279 mvm_set_network.hdr.opcode = VSS_ICOMMON_CMD_SET_NETWORK;
1280 mvm_set_network.network.network_id = v->mvs_info.network_type;
1281
1282 v->mvm_state = CMD_STATUS_FAIL;
1283 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_network);
1284 if (ret < 0) {
1285 pr_err("%s: Error %d sending SET_NETWORK\n", __func__, ret);
1286 goto fail;
1287 }
1288
1289 ret = wait_event_timeout(v->mvm_wait,
1290 (v->mvm_state == CMD_STATUS_SUCCESS),
1291 msecs_to_jiffies(TIMEOUT_MS));
1292 if (!ret) {
1293 pr_err("%s: wait_event timeout\n", __func__);
1294 goto fail;
1295 }
1296
1297 /* Set voice timing. */
1298 pr_debug("Setting voice timing\n");
1299
1300 mvm_set_voice_timing.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1301 APR_HDR_LEN(APR_HDR_SIZE),
1302 APR_PKT_VER);
1303 mvm_set_voice_timing.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1304 sizeof(mvm_set_voice_timing) -
1305 APR_HDR_SIZE);
1306 mvm_set_voice_timing.hdr.src_port = 0;
1307 mvm_set_voice_timing.hdr.dest_port = mvm_handle;
1308 mvm_set_voice_timing.hdr.token = 0;
1309 mvm_set_voice_timing.hdr.opcode = VSS_ICOMMON_CMD_SET_VOICE_TIMING;
1310 mvm_set_voice_timing.timing.mode = 0;
1311 mvm_set_voice_timing.timing.enc_offset = 8000;
1312 mvm_set_voice_timing.timing.dec_req_offset = 3300;
1313 mvm_set_voice_timing.timing.dec_offset = 8300;
1314
1315 v->mvm_state = CMD_STATUS_FAIL;
1316
1317 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_voice_timing);
1318 if (ret < 0) {
1319 pr_err("%s: Error %d sending SET_TIMING\n", __func__, ret);
1320 goto fail;
1321 }
1322
1323 ret = wait_event_timeout(v->mvm_wait,
1324 (v->mvm_state == CMD_STATUS_SUCCESS),
1325 msecs_to_jiffies(TIMEOUT_MS));
1326 if (!ret) {
1327 pr_err("%s: wait_event timeout\n", __func__);
1328 goto fail;
1329 }
1330
1331 return 0;
1332fail:
1333 return -EINVAL;
1334}
1335
1336static int voice_send_attach_vocproc_cmd(struct voice_data *v)
1337{
1338 int ret = 0;
1339 struct mvm_attach_vocproc_cmd mvm_a_vocproc_cmd;
1340 void *apr_mvm;
1341 u16 mvm_handle, cvp_handle;
1342
1343 if (v == NULL) {
1344 pr_err("%s: v is NULL\n", __func__);
1345 return -EINVAL;
1346 }
1347 apr_mvm = v->apr_q6_mvm;
1348
1349 if (!apr_mvm) {
1350 pr_err("%s: apr_mvm is NULL.\n", __func__);
1351 return -EINVAL;
1352 }
1353 mvm_handle = voice_get_mvm_handle(v);
1354 cvp_handle = voice_get_cvp_handle(v);
1355
1356 /* attach vocproc and wait for response */
1357 mvm_a_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1358 APR_HDR_LEN(APR_HDR_SIZE),
1359 APR_PKT_VER);
1360 mvm_a_vocproc_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1361 sizeof(mvm_a_vocproc_cmd) - APR_HDR_SIZE);
1362 pr_debug("send mvm_a_vocproc_cmd pkt size = %d\n",
1363 mvm_a_vocproc_cmd.hdr.pkt_size);
1364 mvm_a_vocproc_cmd.hdr.src_port = 0;
1365 mvm_a_vocproc_cmd.hdr.dest_port = mvm_handle;
1366 mvm_a_vocproc_cmd.hdr.token = 0;
Helen Zeng69b00962011-07-08 11:38:36 -07001367 mvm_a_vocproc_cmd.hdr.opcode = VSS_IMVM_CMD_ATTACH_VOCPROC;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001368 mvm_a_vocproc_cmd.mvm_attach_cvp_handle.handle = cvp_handle;
1369
1370 v->mvm_state = CMD_STATUS_FAIL;
1371 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_a_vocproc_cmd);
1372 if (ret < 0) {
Helen Zeng69b00962011-07-08 11:38:36 -07001373 pr_err("Fail in sending VSS_IMVM_CMD_ATTACH_VOCPROC\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001374 goto fail;
1375 }
1376 ret = wait_event_timeout(v->mvm_wait,
1377 (v->mvm_state == CMD_STATUS_SUCCESS),
1378 msecs_to_jiffies(TIMEOUT_MS));
1379 if (!ret) {
1380 pr_err("%s: wait_event timeout\n", __func__);
1381 goto fail;
1382 }
1383
1384 return 0;
1385fail:
1386 return -EINVAL;
1387}
1388
1389static int voice_destroy_vocproc(struct voice_data *v)
1390{
1391 struct mvm_detach_vocproc_cmd mvm_d_vocproc_cmd;
1392 struct apr_hdr cvp_destroy_session_cmd;
1393 int ret = 0;
1394 void *apr_mvm, *apr_cvp;
1395 u16 mvm_handle, cvp_handle;
1396
1397 if (v == NULL) {
1398 pr_err("%s: v is NULL\n", __func__);
1399 return -EINVAL;
1400 }
1401 apr_mvm = v->apr_q6_mvm;
1402 apr_cvp = v->apr_q6_cvp;
1403
1404 if (!apr_mvm || !apr_cvp) {
1405 pr_err("%s: apr_mvm or apr_cvp is NULL.\n", __func__);
1406 return -EINVAL;
1407 }
1408 mvm_handle = voice_get_mvm_handle(v);
1409 cvp_handle = voice_get_cvp_handle(v);
1410
1411 /* send stop voice cmd */
1412 voice_send_stop_voice_cmd(v);
1413
1414 /* detach VOCPROC and wait for response from mvm */
1415 mvm_d_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1416 APR_HDR_LEN(APR_HDR_SIZE),
1417 APR_PKT_VER);
1418 mvm_d_vocproc_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1419 sizeof(mvm_d_vocproc_cmd) - APR_HDR_SIZE);
1420 pr_debug("mvm_d_vocproc_cmd pkt size = %d\n",
1421 mvm_d_vocproc_cmd.hdr.pkt_size);
1422 mvm_d_vocproc_cmd.hdr.src_port = 0;
1423 mvm_d_vocproc_cmd.hdr.dest_port = mvm_handle;
1424 mvm_d_vocproc_cmd.hdr.token = 0;
Helen Zeng69b00962011-07-08 11:38:36 -07001425 mvm_d_vocproc_cmd.hdr.opcode = VSS_IMVM_CMD_DETACH_VOCPROC;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001426 mvm_d_vocproc_cmd.mvm_detach_cvp_handle.handle = cvp_handle;
1427
1428 v->mvm_state = CMD_STATUS_FAIL;
1429 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_d_vocproc_cmd);
1430 if (ret < 0) {
Helen Zeng69b00962011-07-08 11:38:36 -07001431 pr_err("Fail in sending VSS_IMVM_CMD_DETACH_VOCPROC\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001432 goto fail;
1433 }
1434 ret = wait_event_timeout(v->mvm_wait,
1435 (v->mvm_state == CMD_STATUS_SUCCESS),
1436 msecs_to_jiffies(TIMEOUT_MS));
1437 if (!ret) {
1438 pr_err("%s: wait_event timeout\n", __func__);
1439 goto fail;
1440 }
1441
1442 /* destrop cvp session */
1443 cvp_destroy_session_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1444 APR_HDR_LEN(APR_HDR_SIZE),
1445 APR_PKT_VER);
1446 cvp_destroy_session_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1447 sizeof(cvp_destroy_session_cmd) - APR_HDR_SIZE);
1448 pr_debug("cvp_destroy_session_cmd pkt size = %d\n",
1449 cvp_destroy_session_cmd.pkt_size);
1450 cvp_destroy_session_cmd.src_port = 0;
1451 cvp_destroy_session_cmd.dest_port = cvp_handle;
1452 cvp_destroy_session_cmd.token = 0;
1453 cvp_destroy_session_cmd.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
1454
1455 v->cvp_state = CMD_STATUS_FAIL;
1456 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_destroy_session_cmd);
1457 if (ret < 0) {
1458 pr_err("Fail in sending APRV2_IBASIC_CMD_DESTROY_SESSION\n");
1459 goto fail;
1460 }
1461 ret = wait_event_timeout(v->cvp_wait,
1462 (v->cvp_state == CMD_STATUS_SUCCESS),
1463 msecs_to_jiffies(TIMEOUT_MS));
1464 if (!ret) {
1465 pr_err("%s: wait_event timeout\n", __func__);
1466 goto fail;
1467 }
1468
1469 cvp_handle = 0;
1470 voice_set_cvp_handle(v, cvp_handle);
1471
1472 return 0;
1473
1474fail:
1475 return -EINVAL;
1476}
1477
1478static int voice_send_mute_cmd(struct voice_data *v)
1479{
1480 struct cvs_set_mute_cmd cvs_mute_cmd;
1481 int ret = 0;
1482 void *apr_cvs;
1483 u16 cvs_handle;
1484
1485 if (v == NULL) {
1486 pr_err("%s: v is NULL\n", __func__);
1487 return -EINVAL;
1488 }
1489 apr_cvs = v->apr_q6_cvs;
1490
1491 if (!apr_cvs) {
1492 pr_err("%s: apr_cvs is NULL.\n", __func__);
1493 return -EINVAL;
1494 }
1495 cvs_handle = voice_get_cvs_handle(v);
1496
1497 /* send mute/unmute to cvs */
1498 cvs_mute_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1499 APR_HDR_LEN(APR_HDR_SIZE),
1500 APR_PKT_VER);
1501 cvs_mute_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1502 sizeof(cvs_mute_cmd) - APR_HDR_SIZE);
1503 cvs_mute_cmd.hdr.src_port = 0;
1504 cvs_mute_cmd.hdr.dest_port = cvs_handle;
1505 cvs_mute_cmd.hdr.token = 0;
1506 cvs_mute_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_MUTE;
1507 cvs_mute_cmd.cvs_set_mute.direction = 0; /*tx*/
1508 cvs_mute_cmd.cvs_set_mute.mute_flag = v->dev_tx.mute;
1509
1510 pr_info(" mute value =%d\n", cvs_mute_cmd.cvs_set_mute.mute_flag);
1511 v->cvs_state = CMD_STATUS_FAIL;
1512 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_mute_cmd);
1513 if (ret < 0) {
1514 pr_err("Fail: send STREAM SET MUTE\n");
1515 goto fail;
1516 }
1517 ret = wait_event_timeout(v->cvs_wait,
1518 (v->cvs_state == CMD_STATUS_SUCCESS),
1519 msecs_to_jiffies(TIMEOUT_MS));
1520 if (!ret)
1521 pr_err("%s: wait_event timeout\n", __func__);
1522
1523 return 0;
1524fail:
1525 return -EINVAL;
1526}
1527
1528static int voice_send_vol_index_cmd(struct voice_data *v)
1529{
1530 struct cvp_set_rx_volume_index_cmd cvp_vol_cmd;
1531 int ret = 0;
1532 void *apr_cvp;
1533 u16 cvp_handle;
1534 if (v == NULL) {
1535 pr_err("%s: v is NULL\n", __func__);
1536 return -EINVAL;
1537 }
1538 apr_cvp = v->apr_q6_cvp;
1539
1540 if (!apr_cvp) {
1541 pr_err("%s: apr_cvp is NULL.\n", __func__);
1542 return -EINVAL;
1543 }
1544 cvp_handle = voice_get_cvp_handle(v);
1545
1546 /* send volume index to cvp */
1547 cvp_vol_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1548 APR_HDR_LEN(APR_HDR_SIZE),
1549 APR_PKT_VER);
1550 cvp_vol_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1551 sizeof(cvp_vol_cmd) - APR_HDR_SIZE);
1552 cvp_vol_cmd.hdr.src_port = 0;
1553 cvp_vol_cmd.hdr.dest_port = cvp_handle;
1554 cvp_vol_cmd.hdr.token = 0;
1555 cvp_vol_cmd.hdr.opcode = VSS_IVOCPROC_CMD_SET_RX_VOLUME_INDEX;
1556 cvp_vol_cmd.cvp_set_vol_idx.vol_index = v->dev_rx.volume;
1557 v->cvp_state = CMD_STATUS_FAIL;
1558 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_vol_cmd);
1559 if (ret < 0) {
1560 pr_err("Fail in sending RX VOL INDEX\n");
1561 return -EINVAL;
1562 }
1563 ret = wait_event_timeout(v->cvp_wait,
1564 (v->cvp_state == CMD_STATUS_SUCCESS),
1565 msecs_to_jiffies(TIMEOUT_MS));
1566 if (!ret) {
1567 pr_err("%s: wait_event timeout\n", __func__);
1568 return -EINVAL;
1569 }
1570 return 0;
1571}
1572
1573int voc_disable_cvp(void)
1574{
1575 struct voice_data *v = &voice;
1576 int ret = 0;
1577
1578 mutex_lock(&v->lock);
1579
1580 if (v->voc_state == VOC_RUN) {
1581 afe_sidetone(v->dev_tx.port_id, v->dev_rx.port_id, 0, 0);
1582 /* send cmd to dsp to disable vocproc */
1583 ret = voice_send_disable_vocproc_cmd(v);
1584 if (ret < 0) {
1585 pr_err("%s: disable vocproc failed\n", __func__);
1586 goto fail;
1587 }
1588 v->voc_state = VOC_CHANGE;
1589 }
1590
1591fail: mutex_unlock(&v->lock);
1592
1593 return ret;
1594}
1595
1596int voc_enable_cvp(void)
1597{
1598 struct voice_data *v = &voice;
Helen Zengbd58e2c2011-07-01 16:24:31 -07001599 struct sidetone_cal sidetone_cal_data;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001600 int ret = 0;
1601
1602 mutex_lock(&v->lock);
1603
1604 if (v->voc_state == VOC_CHANGE) {
1605 ret = voice_send_set_device_cmd(v);
1606 if (ret < 0) {
1607 pr_err("%s: set device failed\n", __func__);
1608 goto fail;
1609 }
1610 ret = voice_send_enable_vocproc_cmd(v);
1611 if (ret < 0) {
1612 pr_err("enable vocproc failed\n");
1613 goto fail;
Helen Zengcc65b5b2011-07-06 19:14:48 -07001614
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001615 }
Helen Zengcc65b5b2011-07-06 19:14:48 -07001616 /* send tty mode if tty device is used */
1617 voice_send_tty_mode_cmd(v);
1618
Helen Zengbd58e2c2011-07-01 16:24:31 -07001619 get_sidetone_cal(&sidetone_cal_data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001620 ret = afe_sidetone(v->dev_tx.port_id, v->dev_rx.port_id,
Helen Zengbd58e2c2011-07-01 16:24:31 -07001621 sidetone_cal_data.enable,
1622 sidetone_cal_data.gain);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001623
1624 if (ret < 0)
1625 pr_err("AFE command sidetone failed\n");
1626
1627 v->voc_state = VOC_RUN;
1628 }
1629
1630fail:
1631 mutex_unlock(&v->lock);
1632
1633 return ret;
1634}
1635
1636int voc_set_tx_mute(uint32_t dir, uint32_t mute)
1637{
1638 struct voice_data *v = &voice;
1639 int ret = 0;
1640
1641 mutex_lock(&v->lock);
1642
1643 v->dev_tx.mute = mute;
1644
1645 if (v->voc_state == VOC_RUN)
1646 ret = voice_send_mute_cmd(v);
1647
1648 mutex_unlock(&v->lock);
1649
1650 return ret;
1651}
1652
Helen Zengcc65b5b2011-07-06 19:14:48 -07001653int voc_set_tty_mode(uint8_t tty_mode)
1654{
1655 struct voice_data *v = &voice;
1656 int ret = 0;
1657
1658 mutex_lock(&v->lock);
1659
1660 v->tty_mode = tty_mode;
1661
1662 mutex_unlock(&v->lock);
1663
1664 return ret;
1665}
1666
1667uint8_t voc_get_tty_mode(void)
1668{
1669 struct voice_data *v = &voice;
1670 int ret = 0;
1671
1672 mutex_lock(&v->lock);
1673
1674 ret = v->tty_mode;
1675
1676 mutex_unlock(&v->lock);
1677
1678 return ret;
1679}
1680
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001681int voc_set_rx_vol_index(uint32_t dir, uint32_t vol_idx)
1682{
1683 struct voice_data *v = &voice;
1684 int ret = 0;
1685
1686 mutex_lock(&v->lock);
1687
1688 v->dev_rx.volume = vol_idx;
1689
1690 if (v->voc_state == VOC_RUN)
1691 ret = voice_send_vol_index_cmd(v);
1692
1693 mutex_unlock(&v->lock);
1694
1695 return ret;
1696}
1697
1698void voc_set_rxtx_port(uint32_t port_id, uint32_t dev_type)
1699{
1700 struct voice_data *v = &voice;
1701
1702 pr_debug(" port_id=%d, type=%d\n", port_id, dev_type);
1703
1704 mutex_lock(&v->lock);
1705
1706 if (dev_type == DEV_RX)
1707 v->dev_rx.port_id = port_id;
1708 else
1709 v->dev_tx.port_id = port_id;
1710
1711 mutex_unlock(&v->lock);
1712
1713 return;
1714}
1715
1716void voc_set_route_flag(uint8_t path_dir, uint8_t set)
1717{
1718 struct voice_data *v = &voice;
1719
1720 pr_debug("path_dir=%d, set=%d\n", path_dir, set);
1721
1722 mutex_lock(&v->lock);
1723
1724 if (path_dir == RX_PATH)
1725 v->voc_route_state.rx_route_flag = set;
1726 else
1727 v->voc_route_state.tx_route_flag = set;
1728
1729 mutex_unlock(&v->lock);
1730
1731 return;
1732}
1733
1734uint8_t voc_get_route_flag(uint8_t path_dir)
1735{
1736 struct voice_data *v = &voice;
1737 int ret = 0;
1738
1739 mutex_lock(&v->lock);
1740
1741 if (path_dir == RX_PATH)
1742 ret = v->voc_route_state.rx_route_flag;
1743 else
1744 ret = v->voc_route_state.tx_route_flag;
1745
1746 mutex_unlock(&v->lock);
1747
1748 return ret;
1749}
1750
1751int voc_end_voice_call(void)
1752{
1753 struct voice_data *v = &voice;
1754 int ret = 0;
1755
1756 mutex_lock(&v->lock);
1757
1758 if (v->voc_state == VOC_RUN) {
Helen Zengbd58e2c2011-07-01 16:24:31 -07001759 afe_sidetone(v->dev_tx.port_id, v->dev_rx.port_id, 0, 0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001760 ret = voice_destroy_vocproc(v);
1761 if (ret < 0)
1762 pr_err("%s: destroy voice failed\n", __func__);
1763 voice_destroy_mvm_cvs_session(v);
1764
1765 v->voc_state = VOC_RELEASE;
1766 }
1767 mutex_unlock(&v->lock);
1768 return ret;
1769}
1770
1771int voc_start_voice_call(void)
1772{
1773 struct voice_data *v = &voice;
Helen Zengbd58e2c2011-07-01 16:24:31 -07001774 struct sidetone_cal sidetone_cal_data;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001775 int ret = 0;
1776
1777 mutex_lock(&v->lock);
1778
1779 if ((v->voc_state == VOC_INIT) ||
1780 (v->voc_state == VOC_RELEASE)) {
1781 ret = voice_apr_register(v);
1782 if (ret < 0) {
1783 pr_err("%s: apr register failed\n", __func__);
1784 goto fail;
1785 }
1786 ret = voice_create_mvm_cvs_session(v);
1787 if (ret < 0) {
1788 pr_err("create mvm and cvs failed\n");
1789 goto fail;
1790 }
1791 ret = voice_setup_vocproc(v);
1792 if (ret < 0) {
1793 pr_err("setup voice failed\n");
1794 goto fail;
1795 }
1796 ret = voice_send_start_voice_cmd(v);
1797 if (ret < 0) {
1798 pr_err("start voice failed\n");
1799 goto fail;
1800 }
Helen Zengbd58e2c2011-07-01 16:24:31 -07001801 get_sidetone_cal(&sidetone_cal_data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001802 ret = afe_sidetone(v->dev_tx.port_id,
Helen Zengbd58e2c2011-07-01 16:24:31 -07001803 v->dev_rx.port_id,
1804 sidetone_cal_data.enable,
1805 sidetone_cal_data.gain);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001806 if (ret < 0)
1807 pr_err("AFE command sidetone failed\n");
1808
1809 v->voc_state = VOC_RUN;
1810 }
1811
1812fail: mutex_unlock(&v->lock);
1813 return ret;
1814}
1815
1816int voc_set_voc_path_full(uint32_t set)
1817{
1818 int rc = 0;
1819
1820 pr_debug("set voc path: %d\n", set);
1821
1822 mutex_lock(&voice.lock);
1823
1824 if (voice.voc_state == VOC_INIT || voice.voc_state == VOC_RELEASE) {
1825 if (set)
1826 voice.voc_path = VOC_PATH_FULL;
1827 else
1828 voice.voc_path = VOC_PATH_PASSIVE;
1829 } else {
1830 pr_err("%s: Invalid voc path set to %d, in state %d\n",
1831 __func__, set, voice.voc_state);
1832 rc = -EPERM;
1833 }
1834
1835 mutex_unlock(&voice.lock);
1836
1837 return rc;
1838}
1839EXPORT_SYMBOL(voc_set_voc_path_full);
1840
1841void voc_register_mvs_cb(ul_cb_fn ul_cb,
1842 dl_cb_fn dl_cb,
1843 void *private_data)
1844{
1845 voice.mvs_info.ul_cb = ul_cb;
1846 voice.mvs_info.dl_cb = dl_cb;
1847 voice.mvs_info.private_data = private_data;
1848}
1849
1850void voc_config_vocoder(uint32_t media_type,
1851 uint32_t rate,
1852 uint32_t network_type)
1853{
1854 voice.mvs_info.media_type = media_type;
1855 voice.mvs_info.rate = rate;
1856 voice.mvs_info.network_type = network_type;
1857}
1858
1859static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv)
1860{
1861 uint32_t *ptr;
1862 struct voice_data *v;
1863
1864 if ((data == NULL) || (priv == NULL)) {
1865 pr_err("%s: data or priv is NULL\n", __func__);
1866 return -EINVAL;
1867 }
1868 v = priv;
1869
1870 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
1871 data->payload_size, data->opcode);
1872
1873 if (data->opcode == APR_BASIC_RSP_RESULT) {
1874 if (data->payload_size) {
1875 ptr = data->payload;
1876
1877 pr_info("%x %x\n", ptr[0], ptr[1]);
1878 /* ping mvm service ACK */
1879 switch (ptr[0]) {
1880 case VSS_IMVM_CMD_CREATE_PASSIVE_CONTROL_SESSION:
1881 case VSS_IMVM_CMD_CREATE_FULL_CONTROL_SESSION:
1882 /* Passive session is used for CS call
1883 * Full session is used for VoIP call. */
1884 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
1885 if (!ptr[1]) {
1886 pr_debug("%s: MVM handle is %d\n",
1887 __func__, data->src_port);
1888 voice_set_mvm_handle(v, data->src_port);
1889 } else
1890 pr_err("got NACK for sending \
1891 MVM create session \n");
1892 v->mvm_state = CMD_STATUS_SUCCESS;
1893 wake_up(&v->mvm_wait);
1894 break;
1895 case VSS_IMVM_CMD_START_VOICE:
Helen Zeng69b00962011-07-08 11:38:36 -07001896 case VSS_IMVM_CMD_ATTACH_VOCPROC:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001897 case VSS_IMVM_CMD_STOP_VOICE:
Helen Zeng69b00962011-07-08 11:38:36 -07001898 case VSS_IMVM_CMD_DETACH_VOCPROC:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001899 case VSS_ISTREAM_CMD_SET_TTY_MODE:
1900 case APRV2_IBASIC_CMD_DESTROY_SESSION:
1901 case VSS_IMVM_CMD_ATTACH_STREAM:
1902 case VSS_IMVM_CMD_DETACH_STREAM:
1903 case VSS_ICOMMON_CMD_SET_NETWORK:
1904 case VSS_ICOMMON_CMD_SET_VOICE_TIMING:
1905 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
1906 v->mvm_state = CMD_STATUS_SUCCESS;
1907 wake_up(&v->mvm_wait);
1908 break;
1909 default:
1910 pr_debug("%s: not match cmd = 0x%x\n",
1911 __func__, ptr[0]);
1912 break;
1913 }
1914 }
1915 }
1916
1917 return 0;
1918}
1919
1920static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv)
1921{
1922 uint32_t *ptr;
1923 struct voice_data *v;
1924
1925 if ((data == NULL) || (priv == NULL)) {
1926 pr_err("%s: data or priv is NULL\n", __func__);
1927 return -EINVAL;
1928 }
1929 v = priv;
1930
1931 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
1932 data->payload_size, data->opcode);
1933
1934 if (data->opcode == APR_BASIC_RSP_RESULT) {
1935 if (data->payload_size) {
1936 ptr = data->payload;
1937
1938 pr_info("%x %x\n", ptr[0], ptr[1]);
1939 /*response from CVS */
1940 switch (ptr[0]) {
1941 case VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION:
1942 case VSS_ISTREAM_CMD_CREATE_FULL_CONTROL_SESSION:
1943 if (!ptr[1]) {
1944 pr_debug("%s: CVS handle is %d\n",
1945 __func__, data->src_port);
1946 voice_set_cvs_handle(v, data->src_port);
1947 } else
1948 pr_err("got NACK for sending \
1949 CVS create session \n");
1950 v->cvs_state = CMD_STATUS_SUCCESS;
1951 wake_up(&v->cvs_wait);
1952 break;
1953 case VSS_ISTREAM_CMD_SET_MUTE:
1954 case VSS_ISTREAM_CMD_SET_MEDIA_TYPE:
1955 case VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE:
1956 case VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE:
1957 case VSS_ISTREAM_CMD_SET_ENC_DTX_MODE:
1958 case VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE:
1959 case APRV2_IBASIC_CMD_DESTROY_SESSION:
1960 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
1961 v->cvs_state = CMD_STATUS_SUCCESS;
1962 wake_up(&v->cvs_wait);
1963 break;
1964 default:
1965 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
1966 break;
1967 }
1968 }
1969 } else if (data->opcode == VSS_ISTREAM_EVT_SEND_ENC_BUFFER) {
1970 uint32_t *voc_pkt = data->payload;
1971 uint32_t pkt_len = data->payload_size;
1972
1973 if (voc_pkt != NULL && v->mvs_info.ul_cb != NULL) {
1974 pr_debug("%s: Media type is 0x%x\n",
1975 __func__, voc_pkt[0]);
1976
1977 /* Remove media ID from payload. */
1978 voc_pkt++;
1979 pkt_len = pkt_len - 4;
1980
1981 v->mvs_info.ul_cb((uint8_t *)voc_pkt,
1982 pkt_len,
1983 v->mvs_info.private_data);
1984 } else
1985 pr_err("%s: voc_pkt is 0x%x ul_cb is 0x%x\n",
1986 __func__, (unsigned int)voc_pkt,
1987 (unsigned int) v->mvs_info.ul_cb);
1988 } else if (data->opcode == VSS_ISTREAM_EVT_REQUEST_DEC_BUFFER) {
1989 struct cvs_send_dec_buf_cmd send_dec_buf;
1990 int ret = 0;
1991 uint32_t pkt_len = 0;
1992
1993 if (v->mvs_info.dl_cb != NULL) {
1994 send_dec_buf.dec_buf.media_id = v->mvs_info.media_type;
1995
1996 v->mvs_info.dl_cb(
1997 (uint8_t *)&send_dec_buf.dec_buf.packet_data,
1998 &pkt_len,
1999 v->mvs_info.private_data);
2000
2001 send_dec_buf.hdr.hdr_field =
2002 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2003 APR_HDR_LEN(APR_HDR_SIZE),
2004 APR_PKT_VER);
2005 send_dec_buf.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2006 sizeof(send_dec_buf.dec_buf.media_id) + pkt_len);
2007 send_dec_buf.hdr.src_port = 0;
2008 send_dec_buf.hdr.dest_port = voice_get_cvs_handle(v);
2009 send_dec_buf.hdr.token = 0;
2010 send_dec_buf.hdr.opcode =
2011 VSS_ISTREAM_EVT_SEND_DEC_BUFFER;
2012
2013 ret = apr_send_pkt(v->apr_q6_cvs,
2014 (uint32_t *) &send_dec_buf);
2015 if (ret < 0) {
2016 pr_err("%s: Error %d sending DEC_BUF\n",
2017 __func__, ret);
2018 goto fail;
2019 }
2020 } else
2021 pr_debug("%s: dl_cb is NULL\n", __func__);
2022 } else if (data->opcode == VSS_ISTREAM_EVT_SEND_DEC_BUFFER)
2023 pr_debug("Send dec buf resp\n");
2024
2025 else
2026 pr_debug("Unknown opcode 0x%x\n", data->opcode);
2027
2028fail:
2029 return 0;
2030}
2031
2032static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv)
2033{
2034 uint32_t *ptr;
2035 struct voice_data *v;
2036
2037 if ((data == NULL) || (priv == NULL)) {
2038 pr_err("%s: data or priv is NULL\n", __func__);
2039 return -EINVAL;
2040 }
2041 v = priv;
2042
2043 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
2044 data->payload_size, data->opcode);
2045
2046 if (data->opcode == APR_BASIC_RSP_RESULT) {
2047 if (data->payload_size) {
2048 ptr = data->payload;
2049
2050 pr_info("%x %x\n", ptr[0], ptr[1]);
2051
2052 switch (ptr[0]) {
2053 case VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION:
2054 /*response from CVP */
2055 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2056 if (!ptr[1]) {
2057 voice_set_cvp_handle(v, data->src_port);
2058 pr_debug("cvphdl=%d\n", data->src_port);
2059 } else
2060 pr_err("got NACK from CVP create \
2061 session response\n");
2062 v->cvp_state = CMD_STATUS_SUCCESS;
2063 wake_up(&v->cvp_wait);
2064 break;
2065 case VSS_IVOCPROC_CMD_SET_DEVICE:
2066 case VSS_IVOCPROC_CMD_SET_RX_VOLUME_INDEX:
2067 case VSS_IVOCPROC_CMD_ENABLE:
2068 case VSS_IVOCPROC_CMD_DISABLE:
2069 case APRV2_IBASIC_CMD_DESTROY_SESSION:
2070 v->cvp_state = CMD_STATUS_SUCCESS;
2071 wake_up(&v->cvp_wait);
2072 break;
2073 default:
2074 pr_debug("%s: not match cmd = 0x%x\n",
2075 __func__, ptr[0]);
2076 break;
2077 }
2078 }
2079 }
2080 return 0;
2081}
2082
2083
2084static int __init voice_init(void)
2085{
2086 int rc = 0;
2087 struct voice_data *v = &voice;
2088
2089 /* set default value */
2090 v->default_mute_val = 1; /* default is mute */
2091 v->default_vol_val = 0;
2092 v->default_sample_val = 8000;
2093 v->sidetone_gain = 0x512;
2094
2095 /* initialize dev_rx and dev_tx */
2096 memset(&v->dev_tx, 0, sizeof(struct device_data));
2097 memset(&v->dev_rx, 0, sizeof(struct device_data));
2098 v->dev_rx.volume = v->default_vol_val;
2099 v->dev_tx.mute = v->default_mute_val;
2100
2101 v->dev_tx.port_id = 1;
2102 v->dev_rx.port_id = 0;
2103
Helen Zengcc65b5b2011-07-06 19:14:48 -07002104 v->tty_mode = 0;
2105
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002106 v->voc_state = VOC_INIT;
2107 v->voc_path = VOC_PATH_PASSIVE;
2108 init_waitqueue_head(&v->mvm_wait);
2109 init_waitqueue_head(&v->cvs_wait);
2110 init_waitqueue_head(&v->cvp_wait);
2111
2112 mutex_init(&v->lock);
2113
2114 v->mvm_full_handle = 0;
2115 v->mvm_passive_handle = 0;
2116 v->cvs_full_handle = 0;
2117 v->cvs_passive_handle = 0;
2118 v->cvp_full_handle = 0;
2119 v->cvp_passive_handle = 0;
2120
2121 v->apr_q6_mvm = NULL;
2122 v->apr_q6_cvs = NULL;
2123 v->apr_q6_cvp = NULL;
2124
2125 /* Initialize MVS info. */
2126 memset(&v->mvs_info, 0, sizeof(v->mvs_info));
2127 v->mvs_info.network_type = VSS_NETWORK_ID_DEFAULT;
2128
2129 return rc;
2130}
2131
2132device_initcall(voice_init);