blob: dab4daaa0c788289b4c8adc817f9d997dd48750f [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Copyright (c) 2010-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 */
13#include <linux/slab.h>
14#include <linux/kernel.h>
15#include <linux/module.h>
16#include <linux/miscdevice.h>
17#include <linux/uaccess.h>
18#include <linux/fs.h>
19#include <linux/sched.h>
20#include <linux/msm_audio.h>
21#include <linux/kthread.h>
22#include <linux/completion.h>
23#include <linux/wait.h>
24#include <linux/mutex.h>
25#include <mach/qdsp6v2/audio_dev_ctl.h>
26#include <mach/dal.h>
27#include <mach/qdsp6v2/q6voice.h>
28#include <mach/qdsp6v2/rtac.h>
29#include <mach/qdsp6v2/audio_acdb.h>
30#include "q6core.h"
31
32
33#define TIMEOUT_MS 3000
34#define SNDDEV_CAP_TTY 0x20
35
36#define CMD_STATUS_SUCCESS 0
37#define CMD_STATUS_FAIL 1
38
39#define VOC_PATH_PASSIVE 0
40#define VOC_PATH_FULL 1
41#define ADSP_VERSION_CVD 0x60300000
42
43#define BUFFER_PAYLOAD_SIZE 4000
44
45#define VOC_REC_NONE 0xFF
46
47struct voice_data voice;
48
49static bool is_adsp_support_cvd(void)
50{
51 return (voice.adsp_version >= ADSP_VERSION_CVD);
52}
53static int voice_send_enable_vocproc_cmd(struct voice_data *v);
54static int voice_send_netid_timing_cmd(struct voice_data *v);
55
56static void *voice_get_apr_mvm(struct voice_data *v)
57{
58 void *apr_mvm = NULL;
59
60 if (v->voc_path == VOC_PATH_PASSIVE &&
61 !(is_adsp_support_cvd()))
62 apr_mvm = v->apr_mvm;
63 else
64 apr_mvm = v->apr_q6_mvm;
65
66 pr_debug("%s: apr_mvm 0x%x\n", __func__, (unsigned int)apr_mvm);
67
68 return apr_mvm;
69}
70
71static void voice_set_apr_mvm(struct voice_data *v, void *apr_mvm)
72{
73 pr_debug("%s: apr_mvm 0x%x\n", __func__, (unsigned int)apr_mvm);
74
75 if (v->voc_path == VOC_PATH_PASSIVE &&
76 !(is_adsp_support_cvd()))
77 v->apr_mvm = apr_mvm;
78 else
79 v->apr_q6_mvm = apr_mvm;
80}
81
82static void *voice_get_apr_cvs(struct voice_data *v)
83{
84 void *apr_cvs = NULL;
85
86 if (v->voc_path == VOC_PATH_PASSIVE &&
87 !(is_adsp_support_cvd()))
88 apr_cvs = v->apr_cvs;
89 else
90 apr_cvs = v->apr_q6_cvs;
91
92 pr_debug("%s: apr_cvs 0x%x\n", __func__, (unsigned int)apr_cvs);
93
94 return apr_cvs;
95}
96
97static void voice_set_apr_cvs(struct voice_data *v, void *apr_cvs)
98{
99 pr_debug("%s: apr_cvs 0x%x\n", __func__, (unsigned int)apr_cvs);
100
101 if (v->voc_path == VOC_PATH_PASSIVE &&
102 !(is_adsp_support_cvd()))
103 v->apr_cvs = apr_cvs;
104 else
105 v->apr_q6_cvs = apr_cvs;
106#ifdef CONFIG_MSM8X60_RTAC
107 rtac_set_voice_handle(RTAC_CVS, apr_cvs);
108#endif
109}
110
111static void *voice_get_apr_cvp(struct voice_data *v)
112{
113 void *apr_cvp = NULL;
114
115 if (v->voc_path == VOC_PATH_PASSIVE &&
116 !(is_adsp_support_cvd()))
117 apr_cvp = v->apr_cvp;
118 else
119 apr_cvp = v->apr_q6_cvp;
120
121 pr_debug("%s: apr_cvp 0x%x\n", __func__, (unsigned int)apr_cvp);
122
123 return apr_cvp;
124}
125
126static void voice_set_apr_cvp(struct voice_data *v, void *apr_cvp)
127{
128 pr_debug("%s: apr_cvp 0x%x\n", __func__, (unsigned int)apr_cvp);
129
130 if (v->voc_path == VOC_PATH_PASSIVE &&
131 !(is_adsp_support_cvd()))
132 v->apr_cvp = apr_cvp;
133 else
134 v->apr_q6_cvp = apr_cvp;
135#ifdef CONFIG_MSM8X60_RTAC
136 rtac_set_voice_handle(RTAC_CVP, apr_cvp);
137#endif
138}
139
140static u16 voice_get_mvm_handle(struct voice_data *v)
141{
142 u16 mvm_handle = 0;
143
144 if (v->voc_path == VOC_PATH_PASSIVE)
145 mvm_handle = v->mvm_handle;
146 else
147 mvm_handle = v->mvm_q6_handle;
148
149 pr_debug("%s: mvm_handle %d\n", __func__, mvm_handle);
150
151 return mvm_handle;
152}
153
154static void voice_set_mvm_handle(struct voice_data *v, u16 mvm_handle)
155{
156 pr_debug("%s: mvm_handle %d\n", __func__, mvm_handle);
157
158 if (v->voc_path == VOC_PATH_PASSIVE)
159 v->mvm_handle = mvm_handle;
160 else
161 v->mvm_q6_handle = mvm_handle;
162}
163
164static u16 voice_get_cvs_handle(struct voice_data *v)
165{
166 u16 cvs_handle = 0;
167
168 if (v->voc_path == VOC_PATH_PASSIVE)
169 cvs_handle = v->cvs_handle;
170 else
171 cvs_handle = v->cvs_q6_handle;
172
173 pr_debug("%s: cvs_handle %d\n", __func__, cvs_handle);
174
175 return cvs_handle;
176}
177
178static void voice_set_cvs_handle(struct voice_data *v, u16 cvs_handle)
179{
180 pr_debug("%s: cvs_handle %d\n", __func__, cvs_handle);
181
182 if (v->voc_path == VOC_PATH_PASSIVE)
183 v->cvs_handle = cvs_handle;
184 else
185 v->cvs_q6_handle = cvs_handle;
186}
187
188static u16 voice_get_cvp_handle(struct voice_data *v)
189{
190 u16 cvp_handle = 0;
191
192 if (v->voc_path == VOC_PATH_PASSIVE)
193 cvp_handle = v->cvp_handle;
194 else
195 cvp_handle = v->cvp_q6_handle;
196
197 pr_debug("%s: cvp_handle %d\n", __func__, cvp_handle);
198
199 return cvp_handle;
200}
201
202static void voice_set_cvp_handle(struct voice_data *v, u16 cvp_handle)
203{
204 pr_debug("%s: cvp_handle %d\n", __func__, cvp_handle);
205
206 if (v->voc_path == VOC_PATH_PASSIVE)
207 v->cvp_handle = cvp_handle;
208 else
209 v->cvp_q6_handle = cvp_handle;
210}
211
212static void voice_auddev_cb_function(u32 evt_id,
213 union auddev_evt_data *evt_payload,
214 void *private_data);
215
216static int32_t modem_mvm_callback(struct apr_client_data *data, void *priv);
217static int32_t modem_cvs_callback(struct apr_client_data *data, void *priv);
218static int32_t modem_cvp_callback(struct apr_client_data *data, void *priv);
219
220static int voice_apr_register(struct voice_data *v)
221{
222 int rc = 0;
223 void *apr_mvm;
224 void *apr_cvs;
225 void *apr_cvp;
226
227 if (v->adsp_version == 0) {
228 v->adsp_version = core_get_adsp_version();
229 pr_info("adsp_ver fetched:%x\n", v->adsp_version);
230 }
231 apr_mvm = voice_get_apr_mvm(v);
232 apr_cvs = voice_get_apr_cvs(v);
233 apr_cvp = voice_get_apr_cvp(v);
234
235
236 pr_debug("into voice_apr_register_callback\n");
237 /* register callback to APR */
238 if (apr_mvm == NULL) {
239 pr_debug("start to register MVM callback\n");
240
241 if (v->voc_path == VOC_PATH_PASSIVE &&
242 !(is_adsp_support_cvd())) {
243 apr_mvm = apr_register("MODEM", "MVM",
244 modem_mvm_callback, 0xFFFFFFFF,
245 v);
246 } else {
247 apr_mvm = apr_register("ADSP", "MVM",
248 modem_mvm_callback, 0xFFFFFFFF,
249 v);
250 }
251
252 if (apr_mvm == NULL) {
253 pr_err("Unable to register MVM %d\n",
254 is_adsp_support_cvd());
255 rc = -ENODEV;
256 goto done;
257 }
258
259 voice_set_apr_mvm(v, apr_mvm);
260 }
261
262 if (apr_cvs == NULL) {
263 pr_debug("start to register CVS callback\n");
264
265 if (v->voc_path == VOC_PATH_PASSIVE &&
266 !(is_adsp_support_cvd())) {
267 apr_cvs = apr_register("MODEM", "CVS",
268 modem_cvs_callback, 0xFFFFFFFF,
269 v);
270 } else {
271 apr_cvs = apr_register("ADSP", "CVS",
272 modem_cvs_callback, 0xFFFFFFFF,
273 v);
274 }
275
276 if (apr_cvs == NULL) {
277 pr_err("Unable to register CVS %d\n",
278 is_adsp_support_cvd());
279 rc = -ENODEV;
280 goto err;
281 }
282
283 voice_set_apr_cvs(v, apr_cvs);
284 }
285
286 if (apr_cvp == NULL) {
287 pr_debug("start to register CVP callback\n");
288
289 if (v->voc_path == VOC_PATH_PASSIVE &&
290 !(is_adsp_support_cvd())) {
291 apr_cvp = apr_register("MODEM", "CVP",
292 modem_cvp_callback, 0xFFFFFFFF,
293 v);
294 } else {
295 apr_cvp = apr_register("ADSP", "CVP",
296 modem_cvp_callback, 0xFFFFFFFF,
297 v);
298 }
299
300 if (apr_cvp == NULL) {
301 pr_err("Unable to register CVP %d\n",
302 is_adsp_support_cvd());
303 rc = -ENODEV;
304 goto err1;
305 }
306
307 voice_set_apr_cvp(v, apr_cvp);
308 }
309 return 0;
310
311err1:
312 apr_deregister(apr_cvs);
313 apr_cvs = NULL;
314 voice_set_apr_cvs(v, apr_cvs);
315err:
316 apr_deregister(apr_mvm);
317 apr_mvm = NULL;
318 voice_set_apr_mvm(v, apr_mvm);
319
320done:
321 return rc;
322}
323
324static int voice_create_mvm_cvs_session(struct voice_data *v)
325{
326 int ret = 0;
327 struct mvm_create_ctl_session_cmd mvm_session_cmd;
328 struct cvs_create_passive_ctl_session_cmd cvs_session_cmd;
329 struct cvs_create_full_ctl_session_cmd cvs_full_ctl_cmd;
330 struct mvm_attach_stream_cmd attach_stream_cmd;
331 void *apr_mvm = voice_get_apr_mvm(v);
332 void *apr_cvs = voice_get_apr_cvs(v);
333 void *apr_cvp = voice_get_apr_cvp(v);
334 u16 mvm_handle = voice_get_mvm_handle(v);
335 u16 cvs_handle = voice_get_cvs_handle(v);
336 u16 cvp_handle = voice_get_cvp_handle(v);
337
338 pr_info("%s:\n", __func__);
339
340 /* start to ping if modem service is up */
341 pr_debug("in voice_create_mvm_cvs_session, mvm_hdl=%d, cvs_hdl=%d\n",
342 mvm_handle, cvs_handle);
343 /* send cmd to create mvm session and wait for response */
344
345 if (!mvm_handle) {
346 if (v->voc_path == VOC_PATH_PASSIVE) {
347 mvm_session_cmd.hdr.hdr_field =
348 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
349 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
350 mvm_session_cmd.hdr.pkt_size =
351 APR_PKT_SIZE(APR_HDR_SIZE,
352 sizeof(mvm_session_cmd) - APR_HDR_SIZE);
353 pr_debug("Send mvm create session pkt size = %d\n",
354 mvm_session_cmd.hdr.pkt_size);
355 mvm_session_cmd.hdr.src_port = 0;
356 mvm_session_cmd.hdr.dest_port = 0;
357 mvm_session_cmd.hdr.token = 0;
358 pr_debug("%s: Creating MVM passive ctrl\n", __func__);
359 mvm_session_cmd.hdr.opcode =
360 VSS_IMVM_CMD_CREATE_PASSIVE_CONTROL_SESSION;
361 strncpy(mvm_session_cmd.mvm_session.name,
362 "default modem voice", SESSION_NAME_LEN);
363
364 v->mvm_state = CMD_STATUS_FAIL;
365
366 ret = apr_send_pkt(apr_mvm,
367 (uint32_t *) &mvm_session_cmd);
368 if (ret < 0) {
369 pr_err("Error sending MVM_CONTROL_SESSION\n");
370 goto fail;
371 }
372 ret = wait_event_timeout(v->mvm_wait,
373 (v->mvm_state == CMD_STATUS_SUCCESS),
374 msecs_to_jiffies(TIMEOUT_MS));
375 if (!ret) {
376 pr_err("%s: wait_event timeout\n", __func__);
377 goto fail;
378 }
379 } else {
380 mvm_session_cmd.hdr.hdr_field =
381 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
382 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
383 mvm_session_cmd.hdr.pkt_size =
384 APR_PKT_SIZE(APR_HDR_SIZE,
385 sizeof(mvm_session_cmd) - APR_HDR_SIZE);
386 pr_debug("Send mvm create session pkt size = %d\n",
387 mvm_session_cmd.hdr.pkt_size);
388 mvm_session_cmd.hdr.src_port = 0;
389 mvm_session_cmd.hdr.dest_port = 0;
390 mvm_session_cmd.hdr.token = 0;
391 pr_debug("%s: Creating MVM full ctrl\n", __func__);
392 mvm_session_cmd.hdr.opcode =
393 VSS_IMVM_CMD_CREATE_FULL_CONTROL_SESSION;
394 strncpy(mvm_session_cmd.mvm_session.name,
395 "default voip", SESSION_NAME_LEN);
396
397 v->mvm_state = CMD_STATUS_FAIL;
398
399 ret = apr_send_pkt(apr_mvm,
400 (uint32_t *) &mvm_session_cmd);
401 if (ret < 0) {
402 pr_err("Error sending MVM_FULL_CTL_SESSION\n");
403 goto fail;
404 }
405 ret = wait_event_timeout(v->mvm_wait,
406 (v->mvm_state == CMD_STATUS_SUCCESS),
407 msecs_to_jiffies(TIMEOUT_MS));
408 if (!ret) {
409 pr_err("%s: wait_event timeout\n", __func__);
410 goto fail;
411 }
412 }
413
414 /* Get the created MVM handle. */
415 mvm_handle = voice_get_mvm_handle(v);
416 }
417
418 /* send cmd to create cvs session */
419 if (!cvs_handle) {
420 if (v->voc_path == VOC_PATH_PASSIVE) {
421 pr_info("%s:creating CVS passive session\n", __func__);
422
423 cvs_session_cmd.hdr.hdr_field = APR_HDR_FIELD(
424 APR_MSG_TYPE_SEQ_CMD,
425 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
426 cvs_session_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
427 sizeof(cvs_session_cmd) - APR_HDR_SIZE);
428 pr_info("send stream create session pkt size = %d\n",
429 cvs_session_cmd.hdr.pkt_size);
430 cvs_session_cmd.hdr.src_port = 0;
431 cvs_session_cmd.hdr.dest_port = 0;
432 cvs_session_cmd.hdr.token = 0;
433 cvs_session_cmd.hdr.opcode =
434 VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION;
435 strncpy(cvs_session_cmd.cvs_session.name,
436 "default modem voice", SESSION_NAME_LEN);
437
438 v->cvs_state = CMD_STATUS_FAIL;
439
440 pr_info("%s: CVS create\n", __func__);
441 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_session_cmd);
442 if (ret < 0) {
443 pr_err("Fail in sending STREAM_CONTROL_SESSION\n");
444 goto fail;
445 }
446 ret = wait_event_timeout(v->cvs_wait,
447 (v->cvs_state == CMD_STATUS_SUCCESS),
448 msecs_to_jiffies(TIMEOUT_MS));
449 if (!ret) {
450 pr_err("%s: wait_event timeout\n", __func__);
451 goto fail;
452 }
453
454 /* Get the created CVS handle. */
455 cvs_handle = voice_get_cvs_handle(v);
456 } else {
457 pr_info("%s:creating CVS full session\n", __func__);
458
459 cvs_full_ctl_cmd.hdr.hdr_field =
460 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
461 APR_HDR_LEN(APR_HDR_SIZE),
462 APR_PKT_VER);
463
464 cvs_full_ctl_cmd.hdr.pkt_size =
465 APR_PKT_SIZE(APR_HDR_SIZE,
466 sizeof(cvs_full_ctl_cmd) - APR_HDR_SIZE);
467
468 cvs_full_ctl_cmd.hdr.src_port = 0;
469 cvs_full_ctl_cmd.hdr.dest_port = 0;
470 cvs_full_ctl_cmd.hdr.token = 0;
471 cvs_full_ctl_cmd.hdr.opcode =
472 VSS_ISTREAM_CMD_CREATE_FULL_CONTROL_SESSION;
473 cvs_full_ctl_cmd.cvs_session.direction = 2;
474
475 cvs_full_ctl_cmd.cvs_session.enc_media_type =
476 v->mvs_info.media_type;
477 cvs_full_ctl_cmd.cvs_session.dec_media_type =
478 v->mvs_info.media_type;
479 cvs_full_ctl_cmd.cvs_session.network_id =
480 v->mvs_info.network_type;
481 strncpy(cvs_full_ctl_cmd.cvs_session.name,
482 "default voip", SESSION_NAME_LEN);
483
484 v->cvs_state = CMD_STATUS_FAIL;
485
486 ret = apr_send_pkt(apr_cvs,
487 (uint32_t *) &cvs_full_ctl_cmd);
488
489 if (ret < 0) {
490 pr_err("%s: Err %d sending CREATE_FULL_CTRL\n",
491 __func__, ret);
492 goto fail;
493 }
494 ret = wait_event_timeout(v->cvs_wait,
495 (v->cvs_state == CMD_STATUS_SUCCESS),
496 msecs_to_jiffies(TIMEOUT_MS));
497 if (!ret) {
498 pr_err("%s: wait_event timeout\n", __func__);
499 goto fail;
500 }
501
502 /* Get the created CVS handle. */
503 cvs_handle = voice_get_cvs_handle(v);
504
505 /* Attach MVM to CVS. */
506 pr_info("%s: Attach MVM to stream\n", __func__);
507
508 attach_stream_cmd.hdr.hdr_field =
509 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
510 APR_HDR_LEN(APR_HDR_SIZE),
511 APR_PKT_VER);
512
513 attach_stream_cmd.hdr.pkt_size =
514 APR_PKT_SIZE(APR_HDR_SIZE,
515 sizeof(attach_stream_cmd) - APR_HDR_SIZE);
516 attach_stream_cmd.hdr.src_port = 0;
517 attach_stream_cmd.hdr.dest_port = mvm_handle;
518 attach_stream_cmd.hdr.token = 0;
519 attach_stream_cmd.hdr.opcode =
520 VSS_IMVM_CMD_ATTACH_STREAM;
521 attach_stream_cmd.attach_stream.handle = cvs_handle;
522
523 v->mvm_state = CMD_STATUS_FAIL;
524 ret = apr_send_pkt(apr_mvm,
525 (uint32_t *) &attach_stream_cmd);
526 if (ret < 0) {
527 pr_err("%s: Error %d sending ATTACH_STREAM\n",
528 __func__, ret);
529 goto fail;
530 }
531 ret = wait_event_timeout(v->mvm_wait,
532 (v->mvm_state == CMD_STATUS_SUCCESS),
533 msecs_to_jiffies(TIMEOUT_MS));
534 if (!ret) {
535 pr_err("%s: wait_event timeout\n", __func__);
536 goto fail;
537 }
538 }
539 }
540
541 return 0;
542
543fail:
544 apr_deregister(apr_mvm);
545 apr_mvm = NULL;
546 voice_set_apr_mvm(v, apr_mvm);
547
548 apr_deregister(apr_cvs);
549 apr_cvs = NULL;
550 voice_set_apr_cvs(v, apr_cvs);
551
552 apr_deregister(apr_cvp);
553 apr_cvp = NULL;
554 voice_set_apr_cvp(v, apr_cvp);
555
556 cvp_handle = 0;
557 voice_set_cvp_handle(v, cvp_handle);
558
559 cvs_handle = 0;
560 voice_set_cvs_handle(v, cvs_handle);
561
562 return -EINVAL;
563}
564
565static int voice_destroy_mvm_cvs_session(struct voice_data *v)
566{
567 int ret = 0;
568 struct mvm_detach_stream_cmd detach_stream;
569 struct apr_hdr mvm_destroy;
570 struct apr_hdr cvs_destroy;
571 void *apr_mvm = voice_get_apr_mvm(v);
572 void *apr_cvs = voice_get_apr_cvs(v);
573 u16 mvm_handle = voice_get_mvm_handle(v);
574 u16 cvs_handle = voice_get_cvs_handle(v);
575
576 /* MVM, CVS sessions are destroyed only for Full control sessions. */
577 if (v->voc_path == VOC_PATH_FULL) {
578 pr_info("%s: MVM detach stream\n", __func__);
579
580 /* Detach voice stream. */
581 detach_stream.hdr.hdr_field =
582 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
583 APR_HDR_LEN(APR_HDR_SIZE),
584 APR_PKT_VER);
585 detach_stream.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
586 sizeof(detach_stream) - APR_HDR_SIZE);
587 detach_stream.hdr.src_port = 0;
588 detach_stream.hdr.dest_port = mvm_handle;
589 detach_stream.hdr.token = 0;
590 detach_stream.hdr.opcode = VSS_IMVM_CMD_DETACH_STREAM;
591 detach_stream.detach_stream.handle = cvs_handle;
592
593 v->mvm_state = CMD_STATUS_FAIL;
594
595 ret = apr_send_pkt(apr_mvm, (uint32_t *) &detach_stream);
596 if (ret < 0) {
597 pr_err("%s: Error %d sending DETACH_STREAM\n",
598 __func__, ret);
599
600 goto fail;
601 }
602
603 ret = wait_event_timeout(v->mvm_wait,
604 (v->mvm_state == CMD_STATUS_SUCCESS),
605 msecs_to_jiffies(TIMEOUT_MS));
606 if (!ret) {
607 pr_err("%s: wait event timeout\n", __func__);
608 goto fail;
609 }
610
611 /* Destroy CVS. */
612 pr_info("%s: CVS destroy session\n", __func__);
613
614 cvs_destroy.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
615 APR_HDR_LEN(APR_HDR_SIZE),
616 APR_PKT_VER);
617 cvs_destroy.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
618 sizeof(cvs_destroy) - APR_HDR_SIZE);
619 cvs_destroy.src_port = 0;
620 cvs_destroy.dest_port = cvs_handle;
621 cvs_destroy.token = 0;
622 cvs_destroy.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
623
624 v->cvs_state = CMD_STATUS_FAIL;
625
626 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_destroy);
627 if (ret < 0) {
628 pr_err("%s: Error %d sending CVS DESTROY\n",
629 __func__, ret);
630
631 goto fail;
632 }
633
634 ret = wait_event_timeout(v->cvs_wait,
635 (v->cvs_state == CMD_STATUS_SUCCESS),
636 msecs_to_jiffies(TIMEOUT_MS));
637 if (!ret) {
638 pr_err("%s: wait event timeout\n", __func__);
639
640 goto fail;
641 }
642 cvs_handle = 0;
643 voice_set_cvs_handle(v, cvs_handle);
644
645 /* Destroy MVM. */
646 pr_info("%s: MVM destroy session\n", __func__);
647
648 mvm_destroy.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
649 APR_HDR_LEN(APR_HDR_SIZE),
650 APR_PKT_VER);
651 mvm_destroy.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
652 sizeof(mvm_destroy) - APR_HDR_SIZE);
653 mvm_destroy.src_port = 0;
654 mvm_destroy.dest_port = mvm_handle;
655 mvm_destroy.token = 0;
656 mvm_destroy.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
657
658 v->mvm_state = CMD_STATUS_FAIL;
659
660 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_destroy);
661 if (ret < 0) {
662 pr_err("%s: Error %d sending MVM DESTROY\n",
663 __func__, ret);
664
665 goto fail;
666 }
667
668 ret = wait_event_timeout(v->mvm_wait,
669 (v->mvm_state == CMD_STATUS_SUCCESS),
670 msecs_to_jiffies(TIMEOUT_MS));
671 if (!ret) {
672 pr_err("%s: wait event timeout\n", __func__);
673
674 goto fail;
675 }
676 mvm_handle = 0;
677 voice_set_mvm_handle(v, mvm_handle);
678 }
679
680fail:
681 return 0;
682}
683
684static int voice_send_tty_mode_to_modem(struct voice_data *v)
685{
686 struct msm_snddev_info *dev_tx_info;
687 struct msm_snddev_info *dev_rx_info;
688 int tty_mode = 0;
689 int ret = 0;
690 struct mvm_set_tty_mode_cmd mvm_tty_mode_cmd;
691 void *apr_mvm = voice_get_apr_mvm(v);
692 u16 mvm_handle = voice_get_mvm_handle(v);
693
694 dev_rx_info = audio_dev_ctrl_find_dev(v->dev_rx.dev_id);
695 if (IS_ERR(dev_rx_info)) {
696 pr_err("bad dev_id %d\n", v->dev_rx.dev_id);
697 goto done;
698 }
699
700 dev_tx_info = audio_dev_ctrl_find_dev(v->dev_tx.dev_id);
701 if (IS_ERR(dev_tx_info)) {
702 pr_err("bad dev_id %d\n", v->dev_tx.dev_id);
703 goto done;
704 }
705
706 if ((dev_rx_info->capability & SNDDEV_CAP_TTY) &&
707 (dev_tx_info->capability & SNDDEV_CAP_TTY))
708 tty_mode = 3; /* FULL */
709 else if (!(dev_tx_info->capability & SNDDEV_CAP_TTY) &&
710 (dev_rx_info->capability & SNDDEV_CAP_TTY))
711 tty_mode = 2; /* VCO */
712 else if ((dev_tx_info->capability & SNDDEV_CAP_TTY) &&
713 !(dev_rx_info->capability & SNDDEV_CAP_TTY))
714 tty_mode = 1; /* HCO */
715
716 if (tty_mode) {
717 /* send tty mode cmd to mvm */
718 mvm_tty_mode_cmd.hdr.hdr_field = APR_HDR_FIELD(
719 APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
720 APR_PKT_VER);
721 mvm_tty_mode_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
722 sizeof(mvm_tty_mode_cmd) - APR_HDR_SIZE);
723 pr_debug("pkt size = %d\n", mvm_tty_mode_cmd.hdr.pkt_size);
724 mvm_tty_mode_cmd.hdr.src_port = 0;
725 mvm_tty_mode_cmd.hdr.dest_port = mvm_handle;
726 mvm_tty_mode_cmd.hdr.token = 0;
727 mvm_tty_mode_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_TTY_MODE;
728 mvm_tty_mode_cmd.tty_mode.mode = tty_mode;
729 pr_info("tty mode =%d\n", mvm_tty_mode_cmd.tty_mode.mode);
730
731 v->mvm_state = CMD_STATUS_FAIL;
732 pr_info("%s: MVM set tty\n", __func__);
733 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_tty_mode_cmd);
734 if (ret < 0) {
735 pr_err("Fail: sending VSS_ISTREAM_CMD_SET_TTY_MODE\n");
736 goto done;
737 }
738 ret = wait_event_timeout(v->mvm_wait,
739 (v->mvm_state == CMD_STATUS_SUCCESS),
740 msecs_to_jiffies(TIMEOUT_MS));
741 if (!ret) {
742 pr_err("%s: wait_event timeout\n", __func__);
743 goto done;
744 }
745 }
746 return 0;
747done:
748 return -EINVAL;
749}
750
751static int voice_send_cvs_cal_to_modem(struct voice_data *v)
752{
753 struct apr_hdr cvs_cal_cmd_hdr;
754 uint32_t *cmd_buf;
755 struct acdb_cal_data cal_data;
756 struct acdb_cal_block *cal_blk;
757 int32_t cal_size_per_network;
758 uint32_t *cal_data_per_network;
759 int index = 0;
760 int ret = 0;
761 void *apr_cvs = voice_get_apr_cvs(v);
762 u16 cvs_handle = voice_get_cvs_handle(v);
763
764 /* fill the header */
765 cvs_cal_cmd_hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
766 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
767 cvs_cal_cmd_hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
768 sizeof(cvs_cal_cmd_hdr) - APR_HDR_SIZE);
769 cvs_cal_cmd_hdr.src_port = 0;
770 cvs_cal_cmd_hdr.dest_port = cvs_handle;
771 cvs_cal_cmd_hdr.token = 0;
772 cvs_cal_cmd_hdr.opcode =
773 VSS_ISTREAM_CMD_CACHE_CALIBRATION_DATA;
774
775 pr_debug("voice_send_cvs_cal_to_modem\n");
776 /* get the cvs cal data */
777 get_vocstrm_cal(&cal_data);
778 if (cal_data.num_cal_blocks == 0) {
779 pr_err("%s: No calibration data to send!\n", __func__);
780 goto done;
781 }
782
783 /* send cvs cal to modem */
784 cmd_buf = kzalloc((sizeof(struct apr_hdr) + BUFFER_PAYLOAD_SIZE),
785 GFP_KERNEL);
786 if (!cmd_buf) {
787 pr_err("No memory is allocated.\n");
788 return -ENOMEM;
789 }
790 pr_debug("----- num_cal_blocks=%d\n", (s32)cal_data.num_cal_blocks);
791 cal_blk = cal_data.cal_blocks;
792 pr_debug("cal_blk =%x\n", (uint32_t)cal_data.cal_blocks);
793
794 for (; index < cal_data.num_cal_blocks; index++) {
795 cal_size_per_network = cal_blk[index].cal_size;
796 pr_debug(" cal size =%d\n", cal_size_per_network);
797 if (cal_size_per_network >= BUFFER_PAYLOAD_SIZE)
798 pr_err("Cal size is too big\n");
799 cal_data_per_network = (u32 *)cal_blk[index].cal_kvaddr;
800 pr_debug(" cal data=%x\n", (uint32_t)cal_data_per_network);
801 cvs_cal_cmd_hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
802 cal_size_per_network);
803 pr_debug("header size =%d, pkt_size =%d\n",
804 APR_HDR_SIZE, cvs_cal_cmd_hdr.pkt_size);
805 memcpy(cmd_buf, &cvs_cal_cmd_hdr, APR_HDR_SIZE);
806 memcpy(cmd_buf + (APR_HDR_SIZE / sizeof(uint32_t)),
807 cal_data_per_network, cal_size_per_network);
808 pr_debug("send cvs cal: index =%d\n", index);
809 v->cvs_state = CMD_STATUS_FAIL;
810 ret = apr_send_pkt(apr_cvs, cmd_buf);
811 if (ret < 0) {
812 pr_err("Fail: sending cvs cal, idx=%d\n", index);
813 continue;
814 }
815 ret = wait_event_timeout(v->cvs_wait,
816 (v->cvs_state == CMD_STATUS_SUCCESS),
817 msecs_to_jiffies(TIMEOUT_MS));
818 if (!ret) {
819 pr_err("%s: wait_event timeout\n", __func__);
820 return -EINVAL;
821 }
822 }
823 kfree(cmd_buf);
824done:
825 return 0;
826}
827
828static int voice_send_cvp_cal_to_modem(struct voice_data *v)
829{
830 struct apr_hdr cvp_cal_cmd_hdr;
831 uint32_t *cmd_buf;
832 struct acdb_cal_data cal_data;
833 struct acdb_cal_block *cal_blk;
834 int32_t cal_size_per_network;
835 uint32_t *cal_data_per_network;
836 int index = 0;
837 int ret = 0;
838 void *apr_cvp = voice_get_apr_cvp(v);
839 u16 cvp_handle = voice_get_cvp_handle(v);
840
841
842 /* fill the header */
843 cvp_cal_cmd_hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
844 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
845 cvp_cal_cmd_hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
846 sizeof(cvp_cal_cmd_hdr) - APR_HDR_SIZE);
847 cvp_cal_cmd_hdr.src_port = 0;
848 cvp_cal_cmd_hdr.dest_port = cvp_handle;
849 cvp_cal_cmd_hdr.token = 0;
850 cvp_cal_cmd_hdr.opcode =
851 VSS_IVOCPROC_CMD_CACHE_CALIBRATION_DATA;
852
853 /* get cal data */
854 get_vocproc_cal(&cal_data);
855 if (cal_data.num_cal_blocks == 0) {
856 pr_err("%s: No calibration data to send!\n", __func__);
857 goto done;
858 }
859
860 /* send cal to modem */
861 cmd_buf = kzalloc((sizeof(struct apr_hdr) + BUFFER_PAYLOAD_SIZE),
862 GFP_KERNEL);
863 if (!cmd_buf) {
864 pr_err("No memory is allocated.\n");
865 return -ENOMEM;
866 }
867 pr_debug("----- num_cal_blocks=%d\n", (s32)cal_data.num_cal_blocks);
868 cal_blk = cal_data.cal_blocks;
869 pr_debug(" cal_blk =%x\n", (uint32_t)cal_data.cal_blocks);
870
871 for (; index < cal_data.num_cal_blocks; index++) {
872 cal_size_per_network = cal_blk[index].cal_size;
873 if (cal_size_per_network >= BUFFER_PAYLOAD_SIZE)
874 pr_err("Cal size is too big\n");
875 pr_debug(" cal size =%d\n", cal_size_per_network);
876 cal_data_per_network = (u32 *)cal_blk[index].cal_kvaddr;
877 pr_debug(" cal data=%x\n", (uint32_t)cal_data_per_network);
878
879 cvp_cal_cmd_hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
880 cal_size_per_network);
881 memcpy(cmd_buf, &cvp_cal_cmd_hdr, APR_HDR_SIZE);
882 memcpy(cmd_buf + (APR_HDR_SIZE / sizeof(*cmd_buf)),
883 cal_data_per_network, cal_size_per_network);
884 pr_debug("Send cvp cal\n");
885 v->cvp_state = CMD_STATUS_FAIL;
886 pr_info("%s: CVP calib\n", __func__);
887 ret = apr_send_pkt(apr_cvp, cmd_buf);
888 if (ret < 0) {
889 pr_err("Fail: sending cvp cal, idx=%d\n", index);
890 continue;
891 }
892 ret = wait_event_timeout(v->cvp_wait,
893 (v->cvp_state == CMD_STATUS_SUCCESS),
894 msecs_to_jiffies(TIMEOUT_MS));
895 if (!ret) {
896 pr_err("%s: wait_event timeout\n", __func__);
897 return -EINVAL;
898 }
899 }
900 kfree(cmd_buf);
901done:
902 return 0;
903}
904
905static int voice_send_cvp_vol_tbl_to_modem(struct voice_data *v)
906{
907 struct apr_hdr cvp_vol_cal_cmd_hdr;
908 uint32_t *cmd_buf;
909 struct acdb_cal_data cal_data;
910 struct acdb_cal_block *cal_blk;
911 int32_t cal_size_per_network;
912 uint32_t *cal_data_per_network;
Ben Rombergerb4f562a2011-07-13 19:57:54 -0700913 uint32_t num_volume_steps;
914 int offset = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700915 int index = 0;
916 int ret = 0;
917 void *apr_cvp = voice_get_apr_cvp(v);
918 u16 cvp_handle = voice_get_cvp_handle(v);
919
920
921 /* fill the header */
922 cvp_vol_cal_cmd_hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
923 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
924 cvp_vol_cal_cmd_hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
925 sizeof(cvp_vol_cal_cmd_hdr) - APR_HDR_SIZE);
926 cvp_vol_cal_cmd_hdr.src_port = 0;
927 cvp_vol_cal_cmd_hdr.dest_port = cvp_handle;
928 cvp_vol_cal_cmd_hdr.token = 0;
929 cvp_vol_cal_cmd_hdr.opcode =
930 VSS_IVOCPROC_CMD_CACHE_VOLUME_CALIBRATION_TABLE;
931
932 /* get cal data */
933 get_vocvol_cal(&cal_data);
934 if (cal_data.num_cal_blocks == 0) {
935 pr_err("%s: No calibration data to send!\n", __func__);
936 goto done;
937 }
938
939 /* send cal to modem */
940 cmd_buf = kzalloc((sizeof(struct apr_hdr) + BUFFER_PAYLOAD_SIZE),
941 GFP_KERNEL);
942 if (!cmd_buf) {
943 pr_err("No memory is allocated.\n");
944 return -ENOMEM;
945 }
946 pr_debug("----- num_cal_blocks=%d\n", (s32)cal_data.num_cal_blocks);
947 cal_blk = cal_data.cal_blocks;
948 pr_debug("Cal_blk =%x\n", (uint32_t)cal_data.cal_blocks);
949
950 for (; index < cal_data.num_cal_blocks; index++) {
951 cal_size_per_network = cal_blk[index].cal_size;
952 cal_data_per_network = (u32 *)cal_blk[index].cal_kvaddr;
Ben Rombergerb4f562a2011-07-13 19:57:54 -0700953
954 /* Number of volume steps are only included in the */
955 /* first block, need to be inserted into the rest */
956 if (index != 0) {
957 offset = sizeof(num_volume_steps);
958 memcpy(cmd_buf + (APR_HDR_SIZE / sizeof(uint32_t)),
959 &num_volume_steps, offset);
960 } else {
961 num_volume_steps = *cal_data_per_network;
962 }
963
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700964 pr_debug("Cal size =%d, index=%d\n", cal_size_per_network,
965 index);
966 pr_debug("Cal data=%x\n", (uint32_t)cal_data_per_network);
967 cvp_vol_cal_cmd_hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
Ben Rombergerb4f562a2011-07-13 19:57:54 -0700968 cal_size_per_network + offset);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700969 memcpy(cmd_buf, &cvp_vol_cal_cmd_hdr, APR_HDR_SIZE);
Ben Rombergerb4f562a2011-07-13 19:57:54 -0700970 memcpy(cmd_buf + (APR_HDR_SIZE / sizeof(uint32_t)) +
971 offset, cal_data_per_network, cal_size_per_network);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700972 pr_debug("Send vol table\n");
973
974 v->cvp_state = CMD_STATUS_FAIL;
975 ret = apr_send_pkt(apr_cvp, cmd_buf);
976 if (ret < 0) {
977 pr_err("Fail: sending cvp vol cal, idx=%d\n", index);
978 continue;
979 }
980 ret = wait_event_timeout(v->cvp_wait,
981 (v->cvp_state == CMD_STATUS_SUCCESS),
982 msecs_to_jiffies(TIMEOUT_MS));
983 if (!ret) {
984 pr_err("%s: wait_event timeout\n", __func__);
985 return -EINVAL;
986 }
987 }
988 kfree(cmd_buf);
989done:
990 return 0;
991}
992
993static int voice_set_dtx(struct voice_data *v)
994{
995 int ret = 0;
996 void *apr_cvs = voice_get_apr_cvs(v);
997 u16 cvs_handle = voice_get_cvs_handle(v);
998
999 /* Set DTX */
1000 struct cvs_set_enc_dtx_mode_cmd cvs_set_dtx = {
1001 .hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1002 APR_HDR_LEN(APR_HDR_SIZE),
1003 APR_PKT_VER),
1004 .hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1005 sizeof(cvs_set_dtx) - APR_HDR_SIZE),
1006 .hdr.src_port = 0,
1007 .hdr.dest_port = cvs_handle,
1008 .hdr.token = 0,
1009 .hdr.opcode = VSS_ISTREAM_CMD_SET_ENC_DTX_MODE,
1010 .dtx_mode.enable = v->mvs_info.dtx_mode,
1011 };
1012
1013 pr_debug("%s: Setting DTX %d\n", __func__, v->mvs_info.dtx_mode);
1014
1015 v->cvs_state = CMD_STATUS_FAIL;
1016
1017 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_dtx);
1018 if (ret < 0) {
1019 pr_err("%s: Error %d sending SET_DTX\n", __func__, ret);
1020
1021 goto done;
1022 }
1023
1024 ret = wait_event_timeout(v->cvs_wait,
1025 (v->cvs_state == CMD_STATUS_SUCCESS),
1026 msecs_to_jiffies(TIMEOUT_MS));
1027 if (!ret) {
1028 pr_err("%s: wait_event timeout\n", __func__);
1029
1030 ret = -EINVAL;
1031 }
1032
1033done:
1034 return ret;
1035}
1036
1037static int voice_config_cvs_vocoder(struct voice_data *v)
1038{
1039 int ret = 0;
1040 void *apr_cvs = voice_get_apr_cvs(v);
1041 u16 cvs_handle = voice_get_cvs_handle(v);
1042
1043 /* Set media type. */
1044 struct cvs_set_media_type_cmd cvs_set_media_cmd;
1045
1046 pr_info("%s: Setting media type\n", __func__);
1047
1048 cvs_set_media_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1049 APR_HDR_LEN(APR_HDR_SIZE),
1050 APR_PKT_VER);
1051 cvs_set_media_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1052 sizeof(cvs_set_media_cmd) - APR_HDR_SIZE);
1053 cvs_set_media_cmd.hdr.src_port = 0;
1054 cvs_set_media_cmd.hdr.dest_port = cvs_handle;
1055 cvs_set_media_cmd.hdr.token = 0;
1056 cvs_set_media_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_MEDIA_TYPE;
1057 cvs_set_media_cmd.media_type.tx_media_id = v->mvs_info.media_type;
1058 cvs_set_media_cmd.media_type.rx_media_id = v->mvs_info.media_type;
1059
1060 v->cvs_state = CMD_STATUS_FAIL;
1061
1062 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_media_cmd);
1063 if (ret < 0) {
1064 pr_err("%s: Error %d sending SET_MEDIA_TYPE\n",
1065 __func__, ret);
1066
1067 goto done;
1068 }
1069
1070 ret = wait_event_timeout(v->cvs_wait,
1071 (v->cvs_state == CMD_STATUS_SUCCESS),
1072 msecs_to_jiffies(TIMEOUT_MS));
1073 if (!ret) {
1074 pr_err("%s: wait_event timeout\n", __func__);
1075
1076 ret = -EINVAL;
1077 goto done;
1078 }
1079
1080 /* Set encoder properties. */
1081 switch (v->mvs_info.media_type) {
1082 case VSS_MEDIA_ID_EVRC_MODEM: {
1083 struct cvs_set_cdma_enc_minmax_rate_cmd cvs_set_cdma_rate;
1084
1085 pr_info("%s: Setting EVRC min-max rate\n", __func__);
1086
1087 cvs_set_cdma_rate.hdr.hdr_field =
1088 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1089 APR_HDR_LEN(APR_HDR_SIZE),
1090 APR_PKT_VER);
1091 cvs_set_cdma_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1092 sizeof(cvs_set_cdma_rate) - APR_HDR_SIZE);
1093 cvs_set_cdma_rate.hdr.src_port = 0;
1094 cvs_set_cdma_rate.hdr.dest_port = cvs_handle;
1095 cvs_set_cdma_rate.hdr.token = 0;
1096 cvs_set_cdma_rate.hdr.opcode =
1097 VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE;
1098 cvs_set_cdma_rate.cdma_rate.min_rate = v->mvs_info.rate;
1099 cvs_set_cdma_rate.cdma_rate.max_rate = v->mvs_info.rate;
1100
1101 v->cvs_state = CMD_STATUS_FAIL;
1102
1103 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_cdma_rate);
1104 if (ret < 0) {
1105 pr_err("%s: Error %d sending SET_EVRC_MINMAX_RATE\n",
1106 __func__, ret);
1107
1108 goto done;
1109 }
1110
1111 ret = wait_event_timeout(v->cvs_wait,
1112 (v->cvs_state == CMD_STATUS_SUCCESS),
1113 msecs_to_jiffies(TIMEOUT_MS));
1114 if (!ret) {
1115 pr_err("%s: wait_event timeout\n", __func__);
1116
1117 ret = -EINVAL;
1118 goto done;
1119 }
1120
1121 break;
1122 }
1123
1124 case VSS_MEDIA_ID_AMR_NB_MODEM: {
1125 struct cvs_set_amr_enc_rate_cmd cvs_set_amr_rate;
1126
1127 pr_info("%s: Setting AMR rate\n", __func__);
1128
1129 cvs_set_amr_rate.hdr.hdr_field =
1130 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1131 APR_HDR_LEN(APR_HDR_SIZE),
1132 APR_PKT_VER);
1133 cvs_set_amr_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1134 sizeof(cvs_set_amr_rate) - APR_HDR_SIZE);
1135 cvs_set_amr_rate.hdr.src_port = 0;
1136 cvs_set_amr_rate.hdr.dest_port = cvs_handle;
1137 cvs_set_amr_rate.hdr.token = 0;
1138 cvs_set_amr_rate.hdr.opcode =
1139 VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE;
1140 cvs_set_amr_rate.amr_rate.mode = v->mvs_info.rate;
1141
1142 v->cvs_state = CMD_STATUS_FAIL;
1143
1144 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_amr_rate);
1145 if (ret < 0) {
1146 pr_err("%s: Error %d sending SET_AMR_RATE\n",
1147 __func__, ret);
1148
1149 goto done;
1150 }
1151
1152 ret = wait_event_timeout(v->cvs_wait,
1153 (v->cvs_state == CMD_STATUS_SUCCESS),
1154 msecs_to_jiffies(TIMEOUT_MS));
1155 if (!ret) {
1156 pr_err("%s: wait_event timeout\n", __func__);
1157
1158 ret = -EINVAL;
1159 goto done;
1160 }
1161
1162 ret = voice_set_dtx(v);
1163
1164 break;
1165 }
1166
1167 case VSS_MEDIA_ID_AMR_WB_MODEM: {
1168 struct cvs_set_amrwb_enc_rate_cmd cvs_set_amrwb_rate;
1169
1170 pr_info("%s: Setting AMR WB rate\n", __func__);
1171
1172 cvs_set_amrwb_rate.hdr.hdr_field =
1173 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1174 APR_HDR_LEN(APR_HDR_SIZE),
1175 APR_PKT_VER);
1176 cvs_set_amrwb_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1177 sizeof(cvs_set_amrwb_rate) - APR_HDR_SIZE);
1178 cvs_set_amrwb_rate.hdr.src_port = 0;
1179 cvs_set_amrwb_rate.hdr.dest_port = cvs_handle;
1180 cvs_set_amrwb_rate.hdr.token = 0;
1181 cvs_set_amrwb_rate.hdr.opcode =
1182 VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE;
1183 cvs_set_amrwb_rate.amrwb_rate.mode = v->mvs_info.rate;
1184
1185 v->cvs_state = CMD_STATUS_FAIL;
1186
1187 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_amrwb_rate);
1188 if (ret < 0) {
1189 pr_err("%s: Error %d sending SET_AMRWB_RATE\n",
1190 __func__, ret);
1191
1192 goto done;
1193 }
1194
1195 ret = wait_event_timeout(v->cvs_wait,
1196 (v->cvs_state == CMD_STATUS_SUCCESS),
1197 msecs_to_jiffies(TIMEOUT_MS));
1198 if (!ret) {
1199 pr_err("%s: wait_event timeout\n", __func__);
1200
1201 ret = -EINVAL;
1202 goto done;
1203 }
1204
1205 ret = voice_set_dtx(v);
1206
1207 break;
1208 }
1209
1210 case VSS_MEDIA_ID_G729:
1211 case VSS_MEDIA_ID_G711_ALAW:
1212 case VSS_MEDIA_ID_G711_MULAW: {
1213 ret = voice_set_dtx(v);
1214
1215 break;
1216 }
1217
1218 default: {
1219 /* Do nothing. */
1220 }
1221 }
1222
1223done:
1224 return ret;
1225}
1226
1227static int voice_send_start_voice_cmd(struct voice_data *v)
1228{
1229 struct apr_hdr mvm_start_voice_cmd;
1230 int ret = 0;
1231 void *apr_mvm = voice_get_apr_mvm(v);
1232 u16 mvm_handle = voice_get_mvm_handle(v);
1233
1234 mvm_start_voice_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1235 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1236 mvm_start_voice_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1237 sizeof(mvm_start_voice_cmd) - APR_HDR_SIZE);
1238 pr_info("send mvm_start_voice_cmd pkt size = %d\n",
1239 mvm_start_voice_cmd.pkt_size);
1240 mvm_start_voice_cmd.src_port = 0;
1241 mvm_start_voice_cmd.dest_port = mvm_handle;
1242 mvm_start_voice_cmd.token = 0;
1243 mvm_start_voice_cmd.opcode = VSS_IMVM_CMD_START_VOICE;
1244
1245 v->mvm_state = CMD_STATUS_FAIL;
1246 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_start_voice_cmd);
1247 if (ret < 0) {
1248 pr_err("Fail in sending VSS_IMVM_CMD_START_VOICE\n");
1249 goto fail;
1250 }
1251 ret = wait_event_timeout(v->mvm_wait,
1252 (v->mvm_state == CMD_STATUS_SUCCESS),
1253 msecs_to_jiffies(TIMEOUT_MS));
1254 if (!ret) {
1255 pr_err("%s: wait_event timeout\n", __func__);
1256 goto fail;
1257 }
1258
1259 return 0;
1260fail:
1261 return -EINVAL;
1262}
1263
1264static int voice_disable_vocproc(struct voice_data *v)
1265{
1266 struct apr_hdr cvp_disable_cmd;
1267 int ret = 0;
1268 void *apr_cvp = voice_get_apr_cvp(v);
1269 u16 cvp_handle = voice_get_cvp_handle(v);
1270
1271 /* disable vocproc and wait for respose */
1272 cvp_disable_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1273 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1274 cvp_disable_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1275 sizeof(cvp_disable_cmd) - APR_HDR_SIZE);
1276 pr_debug("cvp_disable_cmd pkt size = %d, cvp_handle=%d\n",
1277 cvp_disable_cmd.pkt_size, cvp_handle);
1278 cvp_disable_cmd.src_port = 0;
1279 cvp_disable_cmd.dest_port = cvp_handle;
1280 cvp_disable_cmd.token = 0;
1281 cvp_disable_cmd.opcode = VSS_IVOCPROC_CMD_DISABLE;
1282
1283 v->cvp_state = CMD_STATUS_FAIL;
1284 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_disable_cmd);
1285 if (ret < 0) {
1286 pr_err("Fail in sending VSS_IVOCPROC_CMD_DISABLE\n");
1287 goto fail;
1288 }
1289 ret = wait_event_timeout(v->cvp_wait,
1290 (v->cvp_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#ifdef CONFIG_MSM8X60_RTAC
1297 rtac_remove_voice(v);
1298#endif
1299
1300 return 0;
1301fail:
1302 return -EINVAL;
1303}
1304
1305static int voice_set_device(struct voice_data *v)
1306{
1307 struct cvp_set_device_cmd cvp_setdev_cmd;
1308 struct msm_snddev_info *dev_tx_info;
1309 int ret = 0;
1310 void *apr_cvp = voice_get_apr_cvp(v);
1311 u16 cvp_handle = voice_get_cvp_handle(v);
1312
1313
1314 /* set device and wait for response */
1315 cvp_setdev_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1316 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1317 cvp_setdev_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1318 sizeof(cvp_setdev_cmd) - APR_HDR_SIZE);
1319 pr_debug(" send create cvp setdev, pkt size = %d\n",
1320 cvp_setdev_cmd.hdr.pkt_size);
1321 cvp_setdev_cmd.hdr.src_port = 0;
1322 cvp_setdev_cmd.hdr.dest_port = cvp_handle;
1323 cvp_setdev_cmd.hdr.token = 0;
1324 cvp_setdev_cmd.hdr.opcode = VSS_IVOCPROC_CMD_SET_DEVICE;
1325
1326 dev_tx_info = audio_dev_ctrl_find_dev(v->dev_tx.dev_id);
1327 if (IS_ERR(dev_tx_info)) {
1328 pr_err("bad dev_id %d\n", v->dev_tx.dev_id);
1329 goto fail;
1330 }
1331
1332 cvp_setdev_cmd.cvp_set_device.tx_topology_id =
1333 get_voice_tx_topology();
1334 if (cvp_setdev_cmd.cvp_set_device.tx_topology_id == 0) {
1335 if (dev_tx_info->channel_mode > 1)
1336 cvp_setdev_cmd.cvp_set_device.tx_topology_id =
1337 VSS_IVOCPROC_TOPOLOGY_ID_TX_DM_FLUENCE;
1338 else
1339 cvp_setdev_cmd.cvp_set_device.tx_topology_id =
1340 VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
1341 }
1342
1343 /* Use default topology if invalid value in ACDB */
1344 cvp_setdev_cmd.cvp_set_device.rx_topology_id =
1345 get_voice_rx_topology();
1346 if (cvp_setdev_cmd.cvp_set_device.rx_topology_id == 0)
1347 cvp_setdev_cmd.cvp_set_device.rx_topology_id =
1348 VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
1349 cvp_setdev_cmd.cvp_set_device.tx_port_id = v->dev_tx.dev_port_id;
1350 cvp_setdev_cmd.cvp_set_device.rx_port_id = v->dev_rx.dev_port_id;
1351 pr_info("topology=%d , tx_port_id=%d, rx_port_id=%d\n",
1352 cvp_setdev_cmd.cvp_set_device.tx_topology_id,
1353 cvp_setdev_cmd.cvp_set_device.tx_port_id,
1354 cvp_setdev_cmd.cvp_set_device.rx_port_id);
1355
1356 v->cvp_state = CMD_STATUS_FAIL;
1357 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_setdev_cmd);
1358 if (ret < 0) {
1359 pr_err("Fail in sending VOCPROC_FULL_CONTROL_SESSION\n");
1360 goto fail;
1361 }
1362 pr_debug("wait for cvp create session event\n");
1363 ret = wait_event_timeout(v->cvp_wait,
1364 (v->cvp_state == CMD_STATUS_SUCCESS),
1365 msecs_to_jiffies(TIMEOUT_MS));
1366 if (!ret) {
1367 pr_err("%s: wait_event timeout\n", __func__);
1368 goto fail;
1369 }
1370
1371 /* send cvs cal */
1372 voice_send_cvs_cal_to_modem(v);
1373
1374 /* send cvp cal */
1375 voice_send_cvp_cal_to_modem(v);
1376
1377 /* send cvp vol table cal */
1378 voice_send_cvp_vol_tbl_to_modem(v);
1379
1380 /* enable vocproc and wait for respose */
1381 voice_send_enable_vocproc_cmd(v);
1382
1383 /* send tty mode if tty device is used */
1384 voice_send_tty_mode_to_modem(v);
1385
1386 if (v->voc_path == VOC_PATH_FULL)
1387 voice_send_netid_timing_cmd(v);
1388
1389#ifdef CONFIG_MSM8X60_RTAC
1390 rtac_add_voice(v);
1391#endif
1392
1393 return 0;
1394fail:
1395 return -EINVAL;
1396}
1397
1398static int voice_send_stop_voice_cmd(struct voice_data *v)
1399{
1400 struct apr_hdr mvm_stop_voice_cmd;
1401 int ret = 0;
1402 void *apr_mvm = voice_get_apr_mvm(v);
1403 u16 mvm_handle = voice_get_mvm_handle(v);
1404
1405 mvm_stop_voice_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1406 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1407 mvm_stop_voice_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1408 sizeof(mvm_stop_voice_cmd) - APR_HDR_SIZE);
1409 pr_info("send mvm_stop_voice_cmd pkt size = %d\n",
1410 mvm_stop_voice_cmd.pkt_size);
1411 mvm_stop_voice_cmd.src_port = 0;
1412 mvm_stop_voice_cmd.dest_port = mvm_handle;
1413 mvm_stop_voice_cmd.token = 0;
1414 mvm_stop_voice_cmd.opcode = VSS_IMVM_CMD_STOP_VOICE;
1415
1416 v->mvm_state = CMD_STATUS_FAIL;
1417 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_stop_voice_cmd);
1418 if (ret < 0) {
1419 pr_err("Fail in sending VSS_IMVM_CMD_STOP_VOICE\n");
1420 goto fail;
1421 }
1422 ret = wait_event_timeout(v->mvm_wait,
1423 (v->mvm_state == CMD_STATUS_SUCCESS),
1424 msecs_to_jiffies(TIMEOUT_MS));
1425 if (!ret) {
1426 pr_err("%s: wait_event timeout\n", __func__);
1427 goto fail;
1428 }
1429
1430 return 0;
1431fail:
1432 return -EINVAL;
1433}
1434
1435static int voice_setup_modem_voice(struct voice_data *v)
1436{
1437 struct cvp_create_full_ctl_session_cmd cvp_session_cmd;
1438 int ret = 0;
1439 struct msm_snddev_info *dev_tx_info;
1440 void *apr_cvp = voice_get_apr_cvp(v);
1441
1442 /* create cvp session and wait for response */
1443 cvp_session_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1444 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1445 cvp_session_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1446 sizeof(cvp_session_cmd) - APR_HDR_SIZE);
1447 pr_info(" send create cvp session, pkt size = %d\n",
1448 cvp_session_cmd.hdr.pkt_size);
1449 cvp_session_cmd.hdr.src_port = 0;
1450 cvp_session_cmd.hdr.dest_port = 0;
1451 cvp_session_cmd.hdr.token = 0;
1452 cvp_session_cmd.hdr.opcode =
1453 VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION;
1454
1455 dev_tx_info = audio_dev_ctrl_find_dev(v->dev_tx.dev_id);
1456 if (IS_ERR(dev_tx_info)) {
1457 pr_err("bad dev_id %d\n", v->dev_tx.dev_id);
1458 goto fail;
1459 }
1460
1461 /* Use default topology if invalid value in ACDB */
1462 cvp_session_cmd.cvp_session.tx_topology_id =
1463 get_voice_tx_topology();
1464 if (cvp_session_cmd.cvp_session.tx_topology_id == 0) {
1465 if (dev_tx_info->channel_mode > 1)
1466 cvp_session_cmd.cvp_session.tx_topology_id =
1467 VSS_IVOCPROC_TOPOLOGY_ID_TX_DM_FLUENCE;
1468 else
1469 cvp_session_cmd.cvp_session.tx_topology_id =
1470 VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
1471 }
1472
1473 cvp_session_cmd.cvp_session.rx_topology_id =
1474 get_voice_rx_topology();
1475 if (cvp_session_cmd.cvp_session.rx_topology_id == 0)
1476 cvp_session_cmd.cvp_session.rx_topology_id =
1477 VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
1478
1479 cvp_session_cmd.cvp_session.direction = 2; /*tx and rx*/
1480 cvp_session_cmd.cvp_session.network_id = VSS_NETWORK_ID_DEFAULT;
1481 cvp_session_cmd.cvp_session.tx_port_id = v->dev_tx.dev_port_id;
1482 cvp_session_cmd.cvp_session.rx_port_id = v->dev_rx.dev_port_id;
1483 pr_info("topology=%d net_id=%d, dir=%d tx_port_id=%d, rx_port_id=%d\n",
1484 cvp_session_cmd.cvp_session.tx_topology_id,
1485 cvp_session_cmd.cvp_session.network_id,
1486 cvp_session_cmd.cvp_session.direction,
1487 cvp_session_cmd.cvp_session.tx_port_id,
1488 cvp_session_cmd.cvp_session.rx_port_id);
1489
1490 v->cvp_state = CMD_STATUS_FAIL;
1491 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_session_cmd);
1492 if (ret < 0) {
1493 pr_err("Fail in sending VOCPROC_FULL_CONTROL_SESSION\n");
1494 goto fail;
1495 }
1496 pr_debug("wait for cvp create session event\n");
1497 ret = wait_event_timeout(v->cvp_wait,
1498 (v->cvp_state == CMD_STATUS_SUCCESS),
1499 msecs_to_jiffies(TIMEOUT_MS));
1500 if (!ret) {
1501 pr_err("%s: wait_event timeout\n", __func__);
1502 goto fail;
1503 }
1504
1505 /* send cvs cal */
1506 voice_send_cvs_cal_to_modem(v);
1507
1508 /* send cvp cal */
1509 voice_send_cvp_cal_to_modem(v);
1510
1511 /* send cvp vol table cal */
1512 voice_send_cvp_vol_tbl_to_modem(v);
1513
1514 return 0;
1515
1516fail:
1517 return -EINVAL;
1518}
1519
1520static int voice_send_enable_vocproc_cmd(struct voice_data *v)
1521{
1522 int ret = 0;
1523 struct apr_hdr cvp_enable_cmd;
1524
1525 u16 cvp_handle = voice_get_cvp_handle(v);
1526 void *apr_cvp = voice_get_apr_cvp(v);
1527
1528 /* enable vocproc and wait for respose */
1529 cvp_enable_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1530 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1531 cvp_enable_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1532 sizeof(cvp_enable_cmd) - APR_HDR_SIZE);
1533 pr_debug("cvp_enable_cmd pkt size = %d, cvp_handle=%d\n",
1534 cvp_enable_cmd.pkt_size, cvp_handle);
1535 cvp_enable_cmd.src_port = 0;
1536 cvp_enable_cmd.dest_port = cvp_handle;
1537 cvp_enable_cmd.token = 0;
1538 cvp_enable_cmd.opcode = VSS_IVOCPROC_CMD_ENABLE;
1539
1540 v->cvp_state = CMD_STATUS_FAIL;
1541 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_enable_cmd);
1542 if (ret < 0) {
1543 pr_err("Fail in sending VSS_IVOCPROC_CMD_ENABLE\n");
1544 goto fail;
1545 }
1546 ret = wait_event_timeout(v->cvp_wait,
1547 (v->cvp_state == CMD_STATUS_SUCCESS),
1548 msecs_to_jiffies(TIMEOUT_MS));
1549 if (!ret) {
1550 pr_err("%s: wait_event timeout\n", __func__);
1551 goto fail;
1552 }
1553
1554 return 0;
1555fail:
1556 return -EINVAL;
1557}
1558
1559static int voice_send_netid_timing_cmd(struct voice_data *v)
1560{
1561 int ret = 0;
1562 void *apr_mvm = voice_get_apr_mvm(v);
1563 struct mvm_set_network_cmd mvm_set_network;
1564 struct mvm_set_voice_timing_cmd mvm_set_voice_timing;
1565 u16 mvm_handle = voice_get_mvm_handle(v);
1566
1567 ret = voice_config_cvs_vocoder(v);
1568 if (ret < 0) {
1569 pr_err("%s: Error %d configuring CVS voc",
1570 __func__, ret);
1571 goto fail;
1572 }
1573 /* Set network ID. */
1574 pr_debug("%s: Setting network ID\n", __func__);
1575
1576 mvm_set_network.hdr.hdr_field =
1577 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1578 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1579 mvm_set_network.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1580 sizeof(mvm_set_network) - APR_HDR_SIZE);
1581 mvm_set_network.hdr.src_port = 0;
1582 mvm_set_network.hdr.dest_port = mvm_handle;
1583 mvm_set_network.hdr.token = 0;
1584 mvm_set_network.hdr.opcode = VSS_ICOMMON_CMD_SET_NETWORK;
1585 mvm_set_network.network.network_id = v->mvs_info.network_type;
1586
1587 v->mvm_state = CMD_STATUS_FAIL;
1588 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_network);
1589 if (ret < 0) {
1590 pr_err("%s: Error %d sending SET_NETWORK\n", __func__, ret);
1591 goto fail;
1592 }
1593
1594 ret = wait_event_timeout(v->mvm_wait,
1595 (v->mvm_state == CMD_STATUS_SUCCESS),
1596 msecs_to_jiffies(TIMEOUT_MS));
1597 if (!ret) {
1598 pr_err("%s: wait_event timeout\n", __func__);
1599 goto fail;
1600 }
1601
1602 /* Set voice timing. */
1603 pr_debug("%s: Setting voice timing\n", __func__);
1604
1605 mvm_set_voice_timing.hdr.hdr_field =
1606 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1607 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1608 mvm_set_voice_timing.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1609 sizeof(mvm_set_voice_timing) - APR_HDR_SIZE);
1610 mvm_set_voice_timing.hdr.src_port = 0;
1611 mvm_set_voice_timing.hdr.dest_port = mvm_handle;
1612 mvm_set_voice_timing.hdr.token = 0;
1613 mvm_set_voice_timing.hdr.opcode =
1614 VSS_ICOMMON_CMD_SET_VOICE_TIMING;
1615 mvm_set_voice_timing.timing.mode = 0;
1616 mvm_set_voice_timing.timing.enc_offset = 8000;
1617 mvm_set_voice_timing.timing.dec_req_offset = 3300;
1618 mvm_set_voice_timing.timing.dec_offset = 8300;
1619
1620 v->mvm_state = CMD_STATUS_FAIL;
1621
1622 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_voice_timing);
1623 if (ret < 0) {
1624 pr_err("%s: Error %d sending SET_TIMING\n", __func__, ret);
1625 goto fail;
1626 }
1627
1628 ret = wait_event_timeout(v->mvm_wait,
1629 (v->mvm_state == CMD_STATUS_SUCCESS),
1630 msecs_to_jiffies(TIMEOUT_MS));
1631 if (!ret) {
1632 pr_err("%s: wait_event timeout\n", __func__);
1633 goto fail;
1634 }
1635
1636 return 0;
1637fail:
1638 return -EINVAL;
1639}
1640
1641static int voice_attach_vocproc(struct voice_data *v)
1642{
1643 int ret = 0;
1644 struct mvm_attach_vocproc_cmd mvm_a_vocproc_cmd;
1645 void *apr_mvm = voice_get_apr_mvm(v);
1646 u16 mvm_handle = voice_get_mvm_handle(v);
1647 u16 cvp_handle = voice_get_cvp_handle(v);
1648
1649 /* send enable vocproc */
1650 voice_send_enable_vocproc_cmd(v);
1651
1652 /* attach vocproc and wait for response */
1653 mvm_a_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1654 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1655 mvm_a_vocproc_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1656 sizeof(mvm_a_vocproc_cmd) - APR_HDR_SIZE);
1657 pr_info("send mvm_a_vocproc_cmd pkt size = %d\n",
1658 mvm_a_vocproc_cmd.hdr.pkt_size);
1659 mvm_a_vocproc_cmd.hdr.src_port = 0;
1660 mvm_a_vocproc_cmd.hdr.dest_port = mvm_handle;
1661 mvm_a_vocproc_cmd.hdr.token = 0;
1662 mvm_a_vocproc_cmd.hdr.opcode = VSS_IMVM_CMD_ATTACH_VOCPROC;
1663 mvm_a_vocproc_cmd.mvm_attach_cvp_handle.handle = cvp_handle;
1664
1665 v->mvm_state = CMD_STATUS_FAIL;
1666 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_a_vocproc_cmd);
1667 if (ret < 0) {
1668 pr_err("Fail in sending VSS_IMVM_CMD_ATTACH_VOCPROC\n");
1669 goto fail;
1670 }
1671 ret = wait_event_timeout(v->mvm_wait,
1672 (v->mvm_state == CMD_STATUS_SUCCESS),
1673 msecs_to_jiffies(TIMEOUT_MS));
1674 if (!ret) {
1675 pr_err("%s: wait_event timeout\n", __func__);
1676 goto fail;
1677 }
1678
1679 /* send tty mode if tty device is used */
1680 voice_send_tty_mode_to_modem(v);
1681
1682 if (v->voc_path == VOC_PATH_FULL)
1683 voice_send_netid_timing_cmd(v);
1684
1685#ifdef CONFIG_MSM8X60_RTAC
1686 rtac_add_voice(v);
1687#endif
1688 return 0;
1689fail:
1690 return -EINVAL;
1691}
1692
1693static int voice_destroy_modem_voice(struct voice_data *v)
1694{
1695 struct mvm_detach_vocproc_cmd mvm_d_vocproc_cmd;
1696 struct apr_hdr cvp_destroy_session_cmd;
1697 int ret = 0;
1698 void *apr_mvm = voice_get_apr_mvm(v);
1699 void *apr_cvp = voice_get_apr_cvp(v);
1700 u16 mvm_handle = voice_get_mvm_handle(v);
1701 u16 cvp_handle = voice_get_cvp_handle(v);
1702
1703 /* detach VOCPROC and wait for response from mvm */
1704 mvm_d_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1705 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1706 mvm_d_vocproc_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1707 sizeof(mvm_d_vocproc_cmd) - APR_HDR_SIZE);
1708 pr_info("mvm_d_vocproc_cmd pkt size = %d\n",
1709 mvm_d_vocproc_cmd.hdr.pkt_size);
1710 mvm_d_vocproc_cmd.hdr.src_port = 0;
1711 mvm_d_vocproc_cmd.hdr.dest_port = mvm_handle;
1712 mvm_d_vocproc_cmd.hdr.token = 0;
1713 mvm_d_vocproc_cmd.hdr.opcode = VSS_IMVM_CMD_DETACH_VOCPROC;
1714 mvm_d_vocproc_cmd.mvm_detach_cvp_handle.handle = cvp_handle;
1715
1716 v->mvm_state = CMD_STATUS_FAIL;
1717 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_d_vocproc_cmd);
1718 if (ret < 0) {
1719 pr_err("Fail in sending VSS_IMVM_CMD_DETACH_VOCPROC\n");
1720 goto fail;
1721 }
1722 ret = wait_event_timeout(v->mvm_wait,
1723 (v->mvm_state == CMD_STATUS_SUCCESS),
1724 msecs_to_jiffies(TIMEOUT_MS));
1725 if (!ret) {
1726 pr_err("%s: wait_event timeout\n", __func__);
1727 goto fail;
1728 }
1729
1730 /* destrop cvp session */
1731 cvp_destroy_session_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1732 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1733 cvp_destroy_session_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1734 sizeof(cvp_destroy_session_cmd) - APR_HDR_SIZE);
1735 pr_info("cvp_destroy_session_cmd pkt size = %d\n",
1736 cvp_destroy_session_cmd.pkt_size);
1737 cvp_destroy_session_cmd.src_port = 0;
1738 cvp_destroy_session_cmd.dest_port = cvp_handle;
1739 cvp_destroy_session_cmd.token = 0;
1740 cvp_destroy_session_cmd.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
1741
1742 v->cvp_state = CMD_STATUS_FAIL;
1743 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_destroy_session_cmd);
1744 if (ret < 0) {
1745 pr_err("Fail in sending APRV2_IBASIC_CMD_DESTROY_SESSION\n");
1746 goto fail;
1747 }
1748 ret = wait_event_timeout(v->cvp_wait,
1749 (v->cvp_state == CMD_STATUS_SUCCESS),
1750 msecs_to_jiffies(TIMEOUT_MS));
1751 if (!ret) {
1752 pr_err("%s: wait_event timeout\n", __func__);
1753 goto fail;
1754 }
1755
1756#ifdef CONFIG_MSM8X60_RTAC
1757 rtac_remove_voice(v);
1758#endif
1759 cvp_handle = 0;
1760 voice_set_cvp_handle(v, cvp_handle);
1761
1762 return 0;
1763
1764fail:
1765 return -EINVAL;
1766}
1767
1768static int voice_send_mute_cmd_to_modem(struct voice_data *v)
1769{
1770 struct cvs_set_mute_cmd cvs_mute_cmd;
1771 int ret = 0;
1772 void *apr_cvs = voice_get_apr_cvs(v);
1773 u16 cvs_handle = voice_get_cvs_handle(v);
1774
1775 /* send mute/unmute to cvs */
1776 cvs_mute_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1777 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1778 cvs_mute_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1779 sizeof(cvs_mute_cmd) - APR_HDR_SIZE);
1780 cvs_mute_cmd.hdr.src_port = 0;
1781 cvs_mute_cmd.hdr.dest_port = cvs_handle;
1782 cvs_mute_cmd.hdr.token = 0;
1783 cvs_mute_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_MUTE;
1784 cvs_mute_cmd.cvs_set_mute.direction = 0; /*tx*/
1785 cvs_mute_cmd.cvs_set_mute.mute_flag = v->dev_tx.mute;
1786
1787 pr_info(" mute value =%d\n", cvs_mute_cmd.cvs_set_mute.mute_flag);
1788 v->cvs_state = CMD_STATUS_FAIL;
1789 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_mute_cmd);
1790 if (ret < 0) {
1791 pr_err("Fail: send STREAM SET MUTE\n");
1792 goto fail;
1793 }
1794 ret = wait_event_timeout(v->cvs_wait,
1795 (v->cvs_state == CMD_STATUS_SUCCESS),
1796 msecs_to_jiffies(TIMEOUT_MS));
1797 if (!ret)
1798 pr_err("%s: wait_event timeout\n", __func__);
1799
1800fail:
1801 return 0;
1802}
1803
1804static int voice_send_vol_index_to_modem(struct voice_data *v)
1805{
1806 struct cvp_set_rx_volume_index_cmd cvp_vol_cmd;
1807 int ret = 0;
1808 void *apr_cvp = voice_get_apr_cvp(v);
1809 u16 cvp_handle = voice_get_cvp_handle(v);
1810
1811 /* send volume index to cvp */
1812 cvp_vol_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1813 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1814 cvp_vol_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1815 sizeof(cvp_vol_cmd) - APR_HDR_SIZE);
1816 cvp_vol_cmd.hdr.src_port = 0;
1817 cvp_vol_cmd.hdr.dest_port = cvp_handle;
1818 cvp_vol_cmd.hdr.token = 0;
1819 cvp_vol_cmd.hdr.opcode =
1820 VSS_IVOCPROC_CMD_SET_RX_VOLUME_INDEX;
1821 cvp_vol_cmd.cvp_set_vol_idx.vol_index = v->dev_rx.volume;
1822 v->cvp_state = CMD_STATUS_FAIL;
1823 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_vol_cmd);
1824 if (ret < 0) {
1825 pr_err("Fail in sending RX VOL INDEX\n");
1826 return -EINVAL;
1827 }
1828 ret = wait_event_timeout(v->cvp_wait,
1829 (v->cvp_state == CMD_STATUS_SUCCESS),
1830 msecs_to_jiffies(TIMEOUT_MS));
1831 if (!ret) {
1832 pr_err("%s: wait_event timeout\n", __func__);
1833 return -EINVAL;
1834 }
1835 return 0;
1836}
1837
1838static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode)
1839{
1840 int ret = 0;
1841 void *apr_cvs = voice_get_apr_cvs(v);
1842 u16 cvs_handle = voice_get_cvs_handle(v);
1843 struct cvs_start_record_cmd cvs_start_record;
1844
1845 pr_debug("%s: Start record %d\n", __func__, rec_mode);
1846
1847 cvs_start_record.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1848 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1849 cvs_start_record.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1850 sizeof(cvs_start_record) - APR_HDR_SIZE);
1851 cvs_start_record.hdr.src_port = 0;
1852 cvs_start_record.hdr.dest_port = cvs_handle;
1853 cvs_start_record.hdr.token = 0;
1854 cvs_start_record.hdr.opcode = VSS_ISTREAM_CMD_START_RECORD;
1855
1856 if (rec_mode == VOC_REC_UPLINK) {
1857 cvs_start_record.rec_mode.rx_tap_point = VSS_TAP_POINT_NONE;
1858 cvs_start_record.rec_mode.tx_tap_point =
1859 VSS_TAP_POINT_STREAM_END;
1860 } else if (rec_mode == VOC_REC_DOWNLINK) {
1861 cvs_start_record.rec_mode.rx_tap_point =
1862 VSS_TAP_POINT_STREAM_END;
1863 cvs_start_record.rec_mode.tx_tap_point = VSS_TAP_POINT_NONE;
1864 } else if (rec_mode == VOC_REC_BOTH) {
1865 cvs_start_record.rec_mode.rx_tap_point =
1866 VSS_TAP_POINT_STREAM_END;
1867 cvs_start_record.rec_mode.tx_tap_point =
1868 VSS_TAP_POINT_STREAM_END;
1869 } else {
1870 pr_err("%s: Invalid in-call rec_mode %d\n", __func__, rec_mode);
1871
1872 ret = -EINVAL;
1873 goto fail;
1874 }
1875
1876 v->cvs_state = CMD_STATUS_FAIL;
1877
1878 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_start_record);
1879 if (ret < 0) {
1880 pr_err("%s: Error %d sending START_RECORD\n", __func__, ret);
1881
1882 goto fail;
1883 }
1884
1885 ret = wait_event_timeout(v->cvs_wait,
1886 (v->cvs_state == CMD_STATUS_SUCCESS),
1887 msecs_to_jiffies(TIMEOUT_MS));
1888 if (!ret) {
1889 pr_err("%s: wait_event timeout\n", __func__);
1890
1891 goto fail;
1892 }
1893
1894 return 0;
1895
1896fail:
1897 return ret;
1898}
1899
1900static int voice_cvs_stop_record(struct voice_data *v)
1901{
1902 int ret = 0;
1903 void *apr_cvs = voice_get_apr_cvs(v);
1904 u16 cvs_handle = voice_get_cvs_handle(v);
1905 struct apr_hdr cvs_stop_record;
1906
1907 pr_debug("%s: Stop record\n", __func__);
1908
1909 cvs_stop_record.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1910 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1911 cvs_stop_record.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1912 sizeof(cvs_stop_record) - APR_HDR_SIZE);
1913 cvs_stop_record.src_port = 0;
1914 cvs_stop_record.dest_port = cvs_handle;
1915 cvs_stop_record.token = 0;
1916 cvs_stop_record.opcode = VSS_ISTREAM_CMD_STOP_RECORD;
1917
1918 v->cvs_state = CMD_STATUS_FAIL;
1919
1920 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_stop_record);
1921 if (ret < 0) {
1922 pr_err("%s: Error %d sending STOP_RECORD\n", __func__, ret);
1923
1924 goto fail;
1925 }
1926
1927 ret = wait_event_timeout(v->cvs_wait,
1928 (v->cvs_state == CMD_STATUS_SUCCESS),
1929 msecs_to_jiffies(TIMEOUT_MS));
1930 if (!ret) {
1931 pr_err("%s: wait_event timeout\n", __func__);
1932
1933 goto fail;
1934 }
1935
1936 return 0;
1937
1938fail:
1939 return ret;
1940}
1941
1942int voice_start_record(uint32_t rec_mode, uint32_t set)
1943{
1944 int ret = 0;
1945 u16 cvs_handle;
1946
1947 pr_debug("%s: rec_mode %d, set %d\n", __func__, rec_mode, set);
1948
1949 mutex_lock(&voice.lock);
1950
1951 cvs_handle = voice_get_cvs_handle(&voice);
1952
1953 if (cvs_handle != 0) {
1954 if (set)
1955 ret = voice_cvs_start_record(&voice, rec_mode);
1956 else
1957 ret = voice_cvs_stop_record(&voice);
1958 } else {
1959 /* Cache the value for later. */
1960 voice.rec_info.pending = set;
1961 voice.rec_info.rec_mode = rec_mode;
1962 }
1963
1964 mutex_unlock(&voice.lock);
1965
1966 return ret;
1967}
1968
1969static int voice_cvs_start_playback(struct voice_data *v)
1970{
1971 int ret = 0;
1972 void *apr_cvs = voice_get_apr_cvs(v);
1973 u16 cvs_handle = voice_get_cvs_handle(v);
1974 struct apr_hdr cvs_start_playback;
1975
1976 pr_debug("%s: Start playback\n", __func__);
1977
1978 cvs_start_playback.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1979 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1980 cvs_start_playback.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1981 sizeof(cvs_start_playback) - APR_HDR_SIZE);
1982 cvs_start_playback.src_port = 0;
1983 cvs_start_playback.dest_port = cvs_handle;
1984 cvs_start_playback.token = 0;
1985 cvs_start_playback.opcode = VSS_ISTREAM_CMD_START_PLAYBACK;
1986
1987 v->cvs_state = CMD_STATUS_FAIL;
1988
1989 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_start_playback);
1990 if (ret < 0) {
1991 pr_err("%s: Error %d sending START_PLAYBACK\n",
1992 __func__, ret);
1993
1994 goto fail;
1995 }
1996
1997 ret = wait_event_timeout(v->cvs_wait,
1998 (v->cvs_state == CMD_STATUS_SUCCESS),
1999 msecs_to_jiffies(TIMEOUT_MS));
2000 if (!ret) {
2001 pr_err("%s: wait_event timeout\n", __func__);
2002
2003 goto fail;
2004 }
2005
2006 v->music_info.playing = 1;
2007
2008 return 0;
2009
2010fail:
2011 return ret;
2012}
2013
2014static int voice_cvs_stop_playback(struct voice_data *v)
2015{
2016 int ret = 0;
2017 void *apr_cvs = voice_get_apr_cvs(v);
2018 u16 cvs_handle = voice_get_cvs_handle(v);
2019 struct apr_hdr cvs_stop_playback;
2020
2021 pr_debug("%s: Stop playback\n", __func__);
2022
2023 if (v->music_info.playing) {
2024 cvs_stop_playback.hdr_field =
2025 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2026 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2027 cvs_stop_playback.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2028 sizeof(cvs_stop_playback) - APR_HDR_SIZE);
2029 cvs_stop_playback.src_port = 0;
2030 cvs_stop_playback.dest_port = cvs_handle;
2031 cvs_stop_playback.token = 0;
2032
2033 cvs_stop_playback.opcode = VSS_ISTREAM_CMD_STOP_PLAYBACK;
2034
2035 v->cvs_state = CMD_STATUS_FAIL;
2036
2037 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_stop_playback);
2038 if (ret < 0) {
2039 pr_err("%s: Error %d sending STOP_PLAYBACK\n",
2040 __func__, ret);
2041
2042 goto fail;
2043 }
2044
2045 ret = wait_event_timeout(v->cvs_wait,
2046 (v->cvs_state == CMD_STATUS_SUCCESS),
2047 msecs_to_jiffies(TIMEOUT_MS));
2048 if (!ret) {
2049 pr_err("%s: wait_event timeout\n", __func__);
2050
2051 goto fail;
2052 }
2053
2054 v->music_info.playing = 0;
2055 } else {
2056 pr_err("%s: Stop playback already sent\n", __func__);
2057 }
2058
2059 return 0;
2060
2061fail:
2062 return ret;
2063}
2064
2065int voice_start_playback(uint32_t set)
2066{
2067 int ret = 0;
2068 u16 cvs_handle;
2069
2070 pr_debug("%s: Start playback %d\n", __func__, set);
2071
2072 mutex_lock(&voice.lock);
2073
2074 cvs_handle = voice_get_cvs_handle(&voice);
2075
2076 if (cvs_handle != 0) {
2077 if (set)
2078 ret = voice_cvs_start_playback(&voice);
2079 else
2080 ret = voice_cvs_stop_playback(&voice);
2081 } else {
2082 /* Cache the value for later. */
2083 pr_debug("%s: Caching ICP value", __func__);
2084
2085 voice.music_info.pending = set;
2086 }
2087
2088 mutex_unlock(&voice.lock);
2089
2090 return ret;
2091}
2092
2093static void voice_auddev_cb_function(u32 evt_id,
2094 union auddev_evt_data *evt_payload,
2095 void *private_data)
2096{
2097 struct voice_data *v = &voice;
2098 struct sidetone_cal sidetone_cal_data;
2099 int rc = 0;
2100 pr_info("auddev_cb_function, evt_id=%d,\n", evt_id);
2101 if ((evt_id != AUDDEV_EVT_START_VOICE) ||
2102 (evt_id != AUDDEV_EVT_END_VOICE)) {
2103 if (evt_payload == NULL) {
2104 pr_err(" evt_payload is NULL pointer\n");
2105 return;
2106 }
2107 }
2108
2109 switch (evt_id) {
2110 case AUDDEV_EVT_START_VOICE:
2111 mutex_lock(&v->lock);
2112
2113 if ((v->voc_state == VOC_INIT) ||
2114 (v->voc_state == VOC_RELEASE)) {
2115 v->v_call_status = VOICE_CALL_START;
2116 if ((v->dev_rx.enabled == VOICE_DEV_ENABLED)
2117 && (v->dev_tx.enabled == VOICE_DEV_ENABLED)) {
2118 rc = voice_apr_register(v);
2119 if (rc < 0) {
2120 pr_err("%s: voice apr registration"
2121 "failed\n", __func__);
2122 mutex_unlock(&v->lock);
2123 return;
2124 }
2125 voice_create_mvm_cvs_session(v);
2126 voice_setup_modem_voice(v);
2127 voice_attach_vocproc(v);
2128 voice_send_start_voice_cmd(v);
2129 get_sidetone_cal(&sidetone_cal_data);
2130 msm_snddev_enable_sidetone(
2131 v->dev_rx.dev_id,
2132 sidetone_cal_data.enable,
2133 sidetone_cal_data.gain);
2134 v->voc_state = VOC_RUN;
2135
2136 /* Start in-call recording if command was
2137 * pending. */
2138 if (v->rec_info.pending) {
2139 voice_cvs_start_record(v,
2140 v->rec_info.rec_mode);
2141
2142 v->rec_info.pending = 0;
2143 }
2144
2145 /* Start in-call music delivery if command was
2146 * pending. */
2147 if (v->music_info.pending) {
2148 voice_cvs_start_playback(v);
2149
2150 v->music_info.pending = 0;
2151 }
2152 }
2153 }
2154
2155 mutex_unlock(&v->lock);
2156 break;
2157 case AUDDEV_EVT_DEV_CHG_VOICE:
2158 if (v->dev_rx.enabled == VOICE_DEV_ENABLED)
2159 msm_snddev_enable_sidetone(v->dev_rx.dev_id, 0, 0);
2160 v->dev_rx.enabled = VOICE_DEV_DISABLED;
2161 v->dev_tx.enabled = VOICE_DEV_DISABLED;
2162
2163 mutex_lock(&v->lock);
2164
2165 if (v->voc_state == VOC_RUN) {
2166 /* send cmd to modem to do voice device change */
2167 voice_disable_vocproc(v);
2168 v->voc_state = VOC_CHANGE;
2169 }
2170
2171 mutex_unlock(&v->lock);
2172 break;
2173 case AUDDEV_EVT_DEV_RDY:
2174 mutex_lock(&v->lock);
2175
2176 if (v->voc_state == VOC_CHANGE) {
2177 /* get port Ids */
2178 if (evt_payload->voc_devinfo.dev_type == DIR_RX) {
2179 v->dev_rx.dev_port_id =
2180 evt_payload->voc_devinfo.dev_port_id;
2181 v->dev_rx.sample =
2182 evt_payload->voc_devinfo.dev_sample;
2183 v->dev_rx.dev_id =
2184 evt_payload->voc_devinfo.dev_id;
2185 v->dev_rx.enabled = VOICE_DEV_ENABLED;
2186 } else {
2187 v->dev_tx.dev_port_id =
2188 evt_payload->voc_devinfo.dev_port_id;
2189 v->dev_tx.sample =
2190 evt_payload->voc_devinfo.dev_sample;
2191 v->dev_tx.enabled = VOICE_DEV_ENABLED;
2192 v->dev_tx.dev_id =
2193 evt_payload->voc_devinfo.dev_id;
2194 }
2195 if ((v->dev_rx.enabled == VOICE_DEV_ENABLED) &&
2196 (v->dev_tx.enabled == VOICE_DEV_ENABLED)) {
2197 voice_set_device(v);
2198 get_sidetone_cal(&sidetone_cal_data);
2199 msm_snddev_enable_sidetone(
2200 v->dev_rx.dev_id,
2201 sidetone_cal_data.enable,
2202 sidetone_cal_data.gain);
2203 v->voc_state = VOC_RUN;
2204 }
2205 } else if ((v->voc_state == VOC_INIT) ||
2206 (v->voc_state == VOC_RELEASE)) {
2207 /* get AFE ports */
2208 if (evt_payload->voc_devinfo.dev_type == DIR_RX) {
2209 /* get rx port id */
2210 v->dev_rx.dev_port_id =
2211 evt_payload->voc_devinfo.dev_port_id;
2212 v->dev_rx.sample =
2213 evt_payload->voc_devinfo.dev_sample;
2214 v->dev_rx.dev_id =
2215 evt_payload->voc_devinfo.dev_id;
2216 v->dev_rx.enabled = VOICE_DEV_ENABLED;
2217 } else {
2218 /* get tx port id */
2219 v->dev_tx.dev_port_id =
2220 evt_payload->voc_devinfo.dev_port_id;
2221 v->dev_tx.sample =
2222 evt_payload->voc_devinfo.dev_sample;
2223 v->dev_tx.dev_id =
2224 evt_payload->voc_devinfo.dev_id;
2225 v->dev_tx.enabled = VOICE_DEV_ENABLED;
2226 }
2227 if ((v->dev_rx.enabled == VOICE_DEV_ENABLED) &&
2228 (v->dev_tx.enabled == VOICE_DEV_ENABLED) &&
2229 (v->v_call_status == VOICE_CALL_START)) {
2230 rc = voice_apr_register(v);
2231 if (rc < 0) {
2232 pr_err("%s: voice apr registration"
2233 "failed\n", __func__);
2234 mutex_unlock(&v->lock);
2235 return;
2236 }
2237 voice_create_mvm_cvs_session(v);
2238 voice_setup_modem_voice(v);
2239 voice_attach_vocproc(v);
2240 voice_send_start_voice_cmd(v);
2241 get_sidetone_cal(&sidetone_cal_data);
2242 msm_snddev_enable_sidetone(
2243 v->dev_rx.dev_id,
2244 sidetone_cal_data.enable,
2245 sidetone_cal_data.gain);
2246 v->voc_state = VOC_RUN;
2247
2248 /* Start in-call recording if command was
2249 * pending. */
2250 if (v->rec_info.pending) {
2251 voice_cvs_start_record(v,
2252 v->rec_info.rec_mode);
2253
2254 v->rec_info.pending = 0;
2255 }
2256
2257 /* Start in-call music delivery if command was
2258 * pending. */
2259 if (v->music_info.pending) {
2260 voice_cvs_start_playback(v);
2261
2262 v->music_info.pending = 0;
2263 }
2264 }
2265 }
2266
2267 mutex_unlock(&v->lock);
2268 break;
2269 case AUDDEV_EVT_DEVICE_VOL_MUTE_CHG:
2270 /* cache the mute and volume index value */
2271 if (evt_payload->voc_devinfo.dev_type == DIR_TX) {
2272 v->dev_tx.mute =
2273 evt_payload->voc_vm_info.dev_vm_val.mute;
2274
2275 mutex_lock(&v->lock);
2276
2277 if (v->voc_state == VOC_RUN)
2278 voice_send_mute_cmd_to_modem(v);
2279
2280 mutex_unlock(&v->lock);
2281 } else {
2282 v->dev_rx.volume = evt_payload->
2283 voc_vm_info.dev_vm_val.vol;
2284
2285 mutex_lock(&v->lock);
2286
2287 if (v->voc_state == VOC_RUN)
2288 voice_send_vol_index_to_modem(v);
2289
2290 mutex_unlock(&v->lock);
2291 }
2292 break;
2293 case AUDDEV_EVT_REL_PENDING:
2294
2295 mutex_lock(&v->lock);
2296
2297 if (v->voc_state == VOC_RUN) {
2298 voice_disable_vocproc(v);
2299 v->voc_state = VOC_CHANGE;
2300 }
2301
2302 mutex_unlock(&v->lock);
2303
2304 if (evt_payload->voc_devinfo.dev_type == DIR_RX)
2305 v->dev_rx.enabled = VOICE_DEV_DISABLED;
2306 else
2307 v->dev_tx.enabled = VOICE_DEV_DISABLED;
2308
2309 break;
2310 case AUDDEV_EVT_END_VOICE:
2311 /* recover the tx mute and rx volume to the default values */
2312 v->dev_tx.mute = v->default_mute_val;
2313 v->dev_rx.volume = v->default_vol_val;
2314 if (v->dev_rx.enabled == VOICE_DEV_ENABLED)
2315 msm_snddev_enable_sidetone(v->dev_rx.dev_id, 0, 0);
2316
2317 mutex_lock(&v->lock);
2318
2319 if (v->voc_state == VOC_RUN) {
2320 /* call stop modem voice */
2321 voice_send_stop_voice_cmd(v);
2322 voice_destroy_modem_voice(v);
2323 voice_destroy_mvm_cvs_session(v);
2324 v->voc_state = VOC_RELEASE;
2325 } else if (v->voc_state == VOC_CHANGE) {
2326 voice_send_stop_voice_cmd(v);
2327 voice_destroy_mvm_cvs_session(v);
2328 v->voc_state = VOC_RELEASE;
2329 }
2330
2331 mutex_unlock(&v->lock);
2332
2333 v->v_call_status = VOICE_CALL_END;
2334
2335 break;
2336 default:
2337 pr_err("UNKNOWN EVENT\n");
2338 }
2339 return;
2340}
2341EXPORT_SYMBOL(voice_auddev_cb_function);
2342
2343int voice_set_voc_path_full(uint32_t set)
2344{
2345 int rc = 0;
2346
2347 pr_info("%s: %d\n", __func__, set);
2348
2349 mutex_lock(&voice.lock);
2350
2351 if (voice.voc_state == VOC_INIT || voice.voc_state == VOC_RELEASE) {
2352 if (set)
2353 voice.voc_path = VOC_PATH_FULL;
2354 else
2355 voice.voc_path = VOC_PATH_PASSIVE;
2356 } else {
2357 pr_err("%s: Invalid voc path set to %d, in state %d\n",
2358 __func__, set, voice.voc_state);
2359
2360 rc = -EPERM;
2361 }
2362
2363 mutex_unlock(&voice.lock);
2364
2365 return rc;
2366}
2367EXPORT_SYMBOL(voice_set_voc_path_full);
2368
2369void voice_register_mvs_cb(ul_cb_fn ul_cb,
2370 dl_cb_fn dl_cb,
2371 void *private_data)
2372{
2373 voice.mvs_info.ul_cb = ul_cb;
2374 voice.mvs_info.dl_cb = dl_cb;
2375 voice.mvs_info.private_data = private_data;
2376}
2377
2378void voice_config_vocoder(uint32_t media_type,
2379 uint32_t rate,
2380 uint32_t network_type,
2381 uint32_t dtx_mode)
2382{
2383 voice.mvs_info.media_type = media_type;
2384 voice.mvs_info.rate = rate;
2385 voice.mvs_info.network_type = network_type;
2386 voice.mvs_info.dtx_mode = dtx_mode;
2387}
2388
2389static int32_t modem_mvm_callback(struct apr_client_data *data, void *priv)
2390{
2391 uint32_t *ptr;
2392 struct voice_data *v = priv;
2393
2394 pr_debug("%s\n", __func__);
2395 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
2396 data->payload_size, data->opcode);
2397
2398 if (data->opcode == RESET_EVENTS) {
2399 pr_debug("%s:Reset event received in Voice service\n",
2400 __func__);
2401 apr_reset(v->apr_mvm);
2402 apr_reset(v->apr_q6_mvm);
2403 v->apr_q6_mvm = NULL;
2404 v->apr_mvm = NULL;
2405 v->mvm_handle = 0;
2406 v->mvm_q6_handle = 0;
2407 return 0;
2408 }
2409
2410 if (data->opcode == APR_BASIC_RSP_RESULT) {
2411 if (data->payload_size) {
2412 ptr = data->payload;
2413
2414 pr_info("%x %x\n", ptr[0], ptr[1]);
2415 /* ping mvm service ACK */
2416
2417 if (ptr[0] ==
2418 VSS_IMVM_CMD_CREATE_PASSIVE_CONTROL_SESSION ||
2419 ptr[0] ==
2420 VSS_IMVM_CMD_CREATE_FULL_CONTROL_SESSION) {
2421 /* Passive session is used for voice call
2422 * through modem. Full session is used for voice
2423 * call through Q6. */
2424 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2425 if (!ptr[1]) {
2426 pr_debug("%s: MVM handle is %d\n",
2427 __func__, data->src_port);
2428
2429 voice_set_mvm_handle(v, data->src_port);
2430 } else
2431 pr_info("got NACK for sending \
2432 MVM create session \n");
2433 v->mvm_state = CMD_STATUS_SUCCESS;
2434 wake_up(&v->mvm_wait);
2435 } else if (ptr[0] == VSS_IMVM_CMD_START_VOICE) {
2436 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2437 v->mvm_state = CMD_STATUS_SUCCESS;
2438 wake_up(&v->mvm_wait);
2439 } else if (ptr[0] == VSS_IMVM_CMD_ATTACH_VOCPROC) {
2440 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2441 v->mvm_state = CMD_STATUS_SUCCESS;
2442 wake_up(&v->mvm_wait);
2443 } else if (ptr[0] == VSS_IMVM_CMD_STOP_VOICE) {
2444 v->mvm_state = CMD_STATUS_SUCCESS;
2445 wake_up(&v->mvm_wait);
2446 } else if (ptr[0] == VSS_IMVM_CMD_DETACH_VOCPROC) {
2447 v->mvm_state = CMD_STATUS_SUCCESS;
2448 wake_up(&v->mvm_wait);
2449 } else if (ptr[0] == VSS_ISTREAM_CMD_SET_TTY_MODE) {
2450 v->mvm_state = CMD_STATUS_SUCCESS;
2451 wake_up(&v->mvm_wait);
2452 } else if (ptr[0] == APRV2_IBASIC_CMD_DESTROY_SESSION) {
2453 pr_debug("%s: DESTROY resp\n", __func__);
2454
2455 v->mvm_state = CMD_STATUS_SUCCESS;
2456 wake_up(&v->mvm_wait);
2457 } else if (ptr[0] == VSS_IMVM_CMD_ATTACH_STREAM) {
2458 pr_debug("%s: ATTACH_STREAM resp 0x%x\n",
2459 __func__, ptr[1]);
2460
2461 v->mvm_state = CMD_STATUS_SUCCESS;
2462 wake_up(&v->mvm_wait);
2463 } else if (ptr[0] == VSS_IMVM_CMD_DETACH_STREAM) {
2464 pr_debug("%s: DETACH_STREAM resp 0x%x\n",
2465 __func__, ptr[1]);
2466
2467 v->mvm_state = CMD_STATUS_SUCCESS;
2468 wake_up(&v->mvm_wait);
2469 } else if (ptr[0] == VSS_ICOMMON_CMD_SET_NETWORK) {
2470 pr_debug("%s: SET_NETWORK resp 0x%x\n",
2471 __func__, ptr[1]);
2472
2473 v->mvm_state = CMD_STATUS_SUCCESS;
2474 wake_up(&v->mvm_wait);
2475 } else if (ptr[0] == VSS_ICOMMON_CMD_SET_VOICE_TIMING) {
2476 pr_debug("%s: SET_VOICE_TIMING resp 0x%x\n",
2477 __func__, ptr[1]);
2478
2479 v->mvm_state = CMD_STATUS_SUCCESS;
2480 wake_up(&v->mvm_wait);
2481 } else
2482 pr_debug("%s: not match cmd = 0x%x\n",
2483 __func__, ptr[0]);
2484 }
2485 }
2486
2487 return 0;
2488}
2489
2490static int32_t modem_cvs_callback(struct apr_client_data *data, void *priv)
2491{
2492 uint32_t *ptr;
2493 struct voice_data *v = priv;
2494
2495 pr_debug("%s\n", __func__);
2496 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
2497 data->payload_size, data->opcode);
2498
2499 if (data->opcode == RESET_EVENTS) {
2500 pr_debug("%s:Reset event received in Voice service\n",
2501 __func__);
2502 apr_reset(v->apr_cvs);
2503 apr_reset(v->apr_q6_cvs);
2504 v->apr_q6_cvs = NULL;
2505 v->apr_cvs = NULL;
2506 v->cvs_handle = 0;
2507 v->cvs_q6_handle = 0;
2508 return 0;
2509 }
2510
2511 if (data->opcode == APR_BASIC_RSP_RESULT) {
2512 if (data->payload_size) {
2513 ptr = data->payload;
2514
2515 pr_info("%x %x\n", ptr[0], ptr[1]);
2516 /*response from modem CVS */
2517 if (ptr[0] ==
2518 VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION ||
2519 ptr[0] ==
2520 VSS_ISTREAM_CMD_CREATE_FULL_CONTROL_SESSION) {
2521 if (!ptr[1]) {
2522 pr_debug("%s: CVS handle is %d\n",
2523 __func__, data->src_port);
2524 voice_set_cvs_handle(v, data->src_port);
2525 } else
2526 pr_info("got NACK for sending \
2527 CVS create session \n");
2528 v->cvs_state = CMD_STATUS_SUCCESS;
2529 wake_up(&v->cvs_wait);
2530 } else if (ptr[0] ==
2531 VSS_ISTREAM_CMD_CACHE_CALIBRATION_DATA) {
2532 v->cvs_state = CMD_STATUS_SUCCESS;
2533 wake_up(&v->cvs_wait);
2534 } else if (ptr[0] ==
2535 VSS_ISTREAM_CMD_SET_MUTE) {
2536 v->cvs_state = CMD_STATUS_SUCCESS;
2537 wake_up(&v->cvs_wait);
2538 } else if (ptr[0] == VSS_ISTREAM_CMD_SET_MEDIA_TYPE) {
2539 pr_debug("%s: SET_MEDIA resp 0x%x\n",
2540 __func__, ptr[1]);
2541
2542 v->cvs_state = CMD_STATUS_SUCCESS;
2543 wake_up(&v->cvs_wait);
2544 } else if (ptr[0] ==
2545 VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE) {
2546 pr_debug("%s: SET_AMR_RATE resp 0x%x\n",
2547 __func__, ptr[1]);
2548
2549 v->cvs_state = CMD_STATUS_SUCCESS;
2550 wake_up(&v->cvs_wait);
2551 } else if (ptr[0] ==
2552 VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE) {
2553 pr_debug("%s: SET_AMR_WB_RATE resp 0x%x\n",
2554 __func__, ptr[1]);
2555
2556 v->cvs_state = CMD_STATUS_SUCCESS;
2557 wake_up(&v->cvs_wait);
2558 } else if (ptr[0] == VSS_ISTREAM_CMD_SET_ENC_DTX_MODE) {
2559 pr_debug("%s: SET_DTX resp 0x%x\n",
2560 __func__, ptr[1]);
2561
2562 v->cvs_state = CMD_STATUS_SUCCESS;
2563 wake_up(&v->cvs_wait);
2564 } else if (ptr[0] ==
2565 VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE) {
2566 pr_debug("%s: SET_CDMA_RATE resp 0x%x\n",
2567 __func__, ptr[1]);
2568
2569 v->cvs_state = CMD_STATUS_SUCCESS;
2570 wake_up(&v->cvs_wait);
2571 } else if (ptr[0] == APRV2_IBASIC_CMD_DESTROY_SESSION) {
2572 pr_debug("%s: DESTROY resp\n", __func__);
2573
2574 v->cvs_state = CMD_STATUS_SUCCESS;
2575 wake_up(&v->cvs_wait);
2576 } else if (ptr[0] == VSS_ISTREAM_CMD_START_RECORD) {
2577 pr_debug("%s: START_RECORD resp 0x%x\n",
2578 __func__, ptr[1]);
2579
2580 v->cvs_state = CMD_STATUS_SUCCESS;
2581 wake_up(&v->cvs_wait);
2582 } else if (ptr[0] == VSS_ISTREAM_CMD_STOP_RECORD) {
2583 pr_debug("%s: STOP_RECORD resp 0x%x\n",
2584 __func__, ptr[1]);
2585
2586 v->cvs_state = CMD_STATUS_SUCCESS;
2587 wake_up(&v->cvs_wait);
2588#ifdef CONFIG_MSM8X60_RTAC
2589 } else if (ptr[0] == VOICE_CMD_SET_PARAM) {
2590 rtac_make_voice_callback(RTAC_CVS, ptr,
2591 data->payload_size);
2592#endif
2593 } else if (ptr[0] == VSS_ISTREAM_CMD_START_PLAYBACK) {
2594 pr_debug("%s: START_PLAYBACK resp 0x%x\n",
2595 __func__, ptr[1]);
2596
2597 v->cvs_state = CMD_STATUS_SUCCESS;
2598 wake_up(&v->cvs_wait);
2599 } else if (ptr[0] == VSS_ISTREAM_CMD_STOP_PLAYBACK) {
2600 pr_debug("%s: STOP_PLAYBACK resp 0x%x\n",
2601 __func__, ptr[1]);
2602
2603 v->cvs_state = CMD_STATUS_SUCCESS;
2604 wake_up(&v->cvs_wait);
2605 } else
2606 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2607 }
2608 } else if (data->opcode == VSS_ISTREAM_EVT_SEND_ENC_BUFFER) {
2609 uint32_t *voc_pkt = data->payload;
2610 uint32_t pkt_len = data->payload_size;
2611
2612 if (voc_pkt != NULL && v->mvs_info.ul_cb != NULL) {
2613 pr_debug("%s: Media type is 0x%x\n",
2614 __func__, voc_pkt[0]);
2615
2616 /* Remove media ID from payload. */
2617 voc_pkt++;
2618 pkt_len = pkt_len - 4;
2619
2620 v->mvs_info.ul_cb((uint8_t *)voc_pkt,
2621 pkt_len,
2622 v->mvs_info.private_data);
2623 } else {
2624 pr_err("%s: voc_pkt is 0x%x ul_cb is 0x%x\n",
2625 __func__, (unsigned int)voc_pkt,
2626 (unsigned int) v->mvs_info.ul_cb);
2627 }
2628 } else if (data->opcode == VSS_ISTREAM_EVT_SEND_DEC_BUFFER) {
2629 pr_debug("%s: Send dec buf resp\n", __func__);
2630 } else if (data->opcode == VSS_ISTREAM_EVT_REQUEST_DEC_BUFFER) {
2631 struct cvs_send_dec_buf_cmd send_dec_buf;
2632 int ret = 0;
2633 uint32_t pkt_len = 0;
2634
2635 if (v->mvs_info.dl_cb != NULL) {
2636 send_dec_buf.dec_buf.media_id = v->mvs_info.media_type;
2637
2638 v->mvs_info.dl_cb(
2639 (uint8_t *)&send_dec_buf.dec_buf.packet_data,
2640 &pkt_len,
2641 v->mvs_info.private_data);
2642
2643 send_dec_buf.hdr.hdr_field =
2644 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2645 APR_HDR_LEN(APR_HDR_SIZE),
2646 APR_PKT_VER);
2647 send_dec_buf.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2648 sizeof(send_dec_buf.dec_buf.media_id) + pkt_len);
2649 send_dec_buf.hdr.src_port = 0;
2650 send_dec_buf.hdr.dest_port = voice_get_cvs_handle(v);
2651 send_dec_buf.hdr.token = 0;
2652 send_dec_buf.hdr.opcode =
2653 VSS_ISTREAM_EVT_SEND_DEC_BUFFER;
2654
2655 ret = apr_send_pkt(voice_get_apr_cvs(v),
2656 (uint32_t *) &send_dec_buf);
2657 if (ret < 0) {
2658 pr_err("%s: Error %d sending DEC_BUF\n",
2659 __func__, ret);
2660 goto fail;
2661 }
2662 } else {
2663 pr_err("%s: ul_cb is NULL\n", __func__);
2664 }
2665#ifdef CONFIG_MSM8X60_RTAC
2666 } else if (data->opcode == VOICE_EVT_GET_PARAM_ACK) {
2667 rtac_make_voice_callback(RTAC_CVS, data->payload,
2668 data->payload_size);
2669#endif
2670
2671 } else {
2672 pr_debug("%s: Unknown opcode 0x%x\n", __func__, data->opcode);
2673 }
2674
2675fail:
2676 return 0;
2677}
2678
2679static int32_t modem_cvp_callback(struct apr_client_data *data, void *priv)
2680{
2681 uint32_t *ptr;
2682 struct voice_data *v = priv;
2683
2684 pr_debug("%s\n", __func__);
2685 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
2686 data->payload_size, data->opcode);
2687
2688 if (data->opcode == RESET_EVENTS) {
2689 pr_debug("%s:Reset event received in Voice service\n",
2690 __func__);
2691 apr_reset(v->apr_cvp);
2692 apr_reset(v->apr_q6_cvp);
2693 v->apr_q6_cvp = NULL;
2694 v->apr_cvp = NULL;
2695 v->cvp_handle = 0;
2696 v->cvp_q6_handle = 0;
2697 return 0;
2698 }
2699
2700 if (data->opcode == APR_BASIC_RSP_RESULT) {
2701 if (data->payload_size) {
2702 ptr = data->payload;
2703
2704 pr_info("%x %x\n", ptr[0], ptr[1]);
2705 /*response from modem CVP */
2706 if (ptr[0] ==
2707 VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION) {
2708 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2709 if (!ptr[1]) {
2710 voice_set_cvp_handle(v, data->src_port);
2711 pr_debug("cvphdl=%d\n", data->src_port);
2712 } else
2713 pr_info("got NACK from CVP create \
2714 session response\n");
2715 v->cvp_state = CMD_STATUS_SUCCESS;
2716 wake_up(&v->cvp_wait);
2717 } else if (ptr[0] ==
2718 VSS_IVOCPROC_CMD_CACHE_CALIBRATION_DATA) {
2719 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2720 v->cvp_state = CMD_STATUS_SUCCESS;
2721 wake_up(&v->cvp_wait);
2722 } else if (ptr[0] == VSS_IVOCPROC_CMD_SET_DEVICE) {
2723 v->cvp_state = CMD_STATUS_SUCCESS;
2724 wake_up(&v->cvp_wait);
2725 } else if (ptr[0] ==
2726 VSS_IVOCPROC_CMD_SET_RX_VOLUME_INDEX) {
2727 v->cvp_state = CMD_STATUS_SUCCESS;
2728 wake_up(&v->cvp_wait);
2729 } else if (ptr[0] == VSS_IVOCPROC_CMD_ENABLE) {
2730 v->cvp_state = CMD_STATUS_SUCCESS;
2731 wake_up(&v->cvp_wait);
2732 } else if (ptr[0] == VSS_IVOCPROC_CMD_DISABLE) {
2733 v->cvp_state = CMD_STATUS_SUCCESS;
2734 wake_up(&v->cvp_wait);
2735 } else if (ptr[0] == APRV2_IBASIC_CMD_DESTROY_SESSION) {
2736 v->cvp_state = CMD_STATUS_SUCCESS;
2737 wake_up(&v->cvp_wait);
2738 } else if (ptr[0] ==
2739 VSS_IVOCPROC_CMD_CACHE_VOLUME_CALIBRATION_TABLE
2740 ) {
2741
2742 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2743 v->cvp_state = CMD_STATUS_SUCCESS;
2744 wake_up(&v->cvp_wait);
2745#ifdef CONFIG_MSM8X60_RTAC
2746 } else if (ptr[0] == VOICE_CMD_SET_PARAM) {
2747 rtac_make_voice_callback(RTAC_CVP, ptr,
2748 data->payload_size);
2749#endif
2750 } else
2751 pr_debug("%s: not match cmd = 0x%x\n",
2752 __func__, ptr[0]);
2753 }
2754#ifdef CONFIG_MSM8X60_RTAC
2755 } else if (data->opcode == VOICE_EVT_GET_PARAM_ACK) {
2756 rtac_make_voice_callback(RTAC_CVP, data->payload,
2757 data->payload_size);
2758#endif
2759 }
2760 return 0;
2761}
2762
2763
2764static int __init voice_init(void)
2765{
2766 int rc = 0;
2767 struct voice_data *v = &voice;
2768
2769 /* set default value */
2770 v->default_mute_val = 1; /* default is mute */
2771 v->default_vol_val = 0;
2772 v->default_sample_val = 8000;
2773
2774 /* initialize dev_rx and dev_tx */
2775 memset(&v->dev_tx, 0, sizeof(struct device_data));
2776 memset(&v->dev_rx, 0, sizeof(struct device_data));
2777 v->dev_rx.volume = v->default_vol_val;
2778 v->dev_tx.mute = v->default_mute_val;
2779
2780 v->voc_state = VOC_INIT;
2781 v->voc_path = VOC_PATH_PASSIVE;
2782 v->adsp_version = 0;
2783 init_waitqueue_head(&v->mvm_wait);
2784 init_waitqueue_head(&v->cvs_wait);
2785 init_waitqueue_head(&v->cvp_wait);
2786
2787 mutex_init(&v->lock);
2788
2789 v->mvm_handle = 0;
2790 v->cvs_handle = 0;
2791 v->cvp_handle = 0;
2792
2793 v->mvm_q6_handle = 0;
2794 v->cvs_q6_handle = 0;
2795 v->cvp_q6_handle = 0;
2796
2797 v->apr_mvm = NULL;
2798 v->apr_cvs = NULL;
2799 v->apr_cvp = NULL;
2800
2801 v->apr_q6_mvm = NULL;
2802 v->apr_q6_cvs = NULL;
2803 v->apr_q6_cvp = NULL;
2804
2805 /* Initialize MVS info. */
2806 memset(&v->mvs_info, 0, sizeof(v->mvs_info));
2807 v->mvs_info.network_type = VSS_NETWORK_ID_DEFAULT;
2808
2809 v->rec_info.pending = 0;
2810 v->rec_info.rec_mode = VOC_REC_NONE;
2811
2812 memset(&v->music_info, 0, sizeof(v->music_info));
2813
2814 v->device_events = AUDDEV_EVT_DEV_CHG_VOICE |
2815 AUDDEV_EVT_DEV_RDY |
2816 AUDDEV_EVT_REL_PENDING |
2817 AUDDEV_EVT_START_VOICE |
2818 AUDDEV_EVT_END_VOICE |
2819 AUDDEV_EVT_DEVICE_VOL_MUTE_CHG |
2820 AUDDEV_EVT_FREQ_CHG;
2821
2822 pr_debug("to register call back\n");
2823 /* register callback to auddev */
2824 auddev_register_evt_listner(v->device_events, AUDDEV_CLNT_VOC,
2825 0, voice_auddev_cb_function, v);
2826
2827 return rc;
2828}
2829
2830device_initcall(voice_init);