blob: de6f646fee27d24f0218f4f4635730c7fd935a11 [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
Neema Shetty90189b82011-06-27 14:58:37 -070039/* Voice session creates passive control sessions for MVM and CVS. */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070040#define VOC_PATH_PASSIVE 0
Neema Shetty90189b82011-06-27 14:58:37 -070041
42/* VoIP session creates full control sessions for MVM and CVS. */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070043#define VOC_PATH_FULL 1
Neema Shetty90189b82011-06-27 14:58:37 -070044
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070045#define ADSP_VERSION_CVD 0x60300000
46
47#define BUFFER_PAYLOAD_SIZE 4000
48
49#define VOC_REC_NONE 0xFF
50
Neema Shetty90189b82011-06-27 14:58:37 -070051struct common_data common;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070052
53static bool is_adsp_support_cvd(void)
54{
Neema Shetty90189b82011-06-27 14:58:37 -070055 return (common.adsp_version >= ADSP_VERSION_CVD);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070056}
57static int voice_send_enable_vocproc_cmd(struct voice_data *v);
58static int voice_send_netid_timing_cmd(struct voice_data *v);
59
Neema Shetty90189b82011-06-27 14:58:37 -070060static void *voice_get_apr_mvm(void)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070061{
62 void *apr_mvm = NULL;
63
Neema Shetty90189b82011-06-27 14:58:37 -070064 if (common.voc_path == VOC_PATH_PASSIVE &&
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070065 !(is_adsp_support_cvd()))
Neema Shetty90189b82011-06-27 14:58:37 -070066 apr_mvm = common.apr_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070067 else
Neema Shetty90189b82011-06-27 14:58:37 -070068 apr_mvm = common.apr_q6_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070069
70 pr_debug("%s: apr_mvm 0x%x\n", __func__, (unsigned int)apr_mvm);
71
72 return apr_mvm;
73}
74
Neema Shetty90189b82011-06-27 14:58:37 -070075static void voice_set_apr_mvm(void *apr_mvm)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070076{
77 pr_debug("%s: apr_mvm 0x%x\n", __func__, (unsigned int)apr_mvm);
78
Neema Shetty90189b82011-06-27 14:58:37 -070079 if (common.voc_path == VOC_PATH_PASSIVE &&
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070080 !(is_adsp_support_cvd()))
Neema Shetty90189b82011-06-27 14:58:37 -070081 common.apr_mvm = apr_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070082 else
Neema Shetty90189b82011-06-27 14:58:37 -070083 common.apr_q6_mvm = apr_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070084}
85
Neema Shetty90189b82011-06-27 14:58:37 -070086static void *voice_get_apr_cvs(void)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070087{
88 void *apr_cvs = NULL;
89
Neema Shetty90189b82011-06-27 14:58:37 -070090 if (common.voc_path == VOC_PATH_PASSIVE &&
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070091 !(is_adsp_support_cvd()))
Neema Shetty90189b82011-06-27 14:58:37 -070092 apr_cvs = common.apr_cvs;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070093 else
Neema Shetty90189b82011-06-27 14:58:37 -070094 apr_cvs = common.apr_q6_cvs;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070095
96 pr_debug("%s: apr_cvs 0x%x\n", __func__, (unsigned int)apr_cvs);
97
98 return apr_cvs;
99}
100
Neema Shetty90189b82011-06-27 14:58:37 -0700101static void voice_set_apr_cvs(void *apr_cvs)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700102{
103 pr_debug("%s: apr_cvs 0x%x\n", __func__, (unsigned int)apr_cvs);
104
Neema Shetty90189b82011-06-27 14:58:37 -0700105 if (common.voc_path == VOC_PATH_PASSIVE &&
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700106 !(is_adsp_support_cvd()))
Neema Shetty90189b82011-06-27 14:58:37 -0700107 common.apr_cvs = apr_cvs;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700108 else
Neema Shetty90189b82011-06-27 14:58:37 -0700109 common.apr_q6_cvs = apr_cvs;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700110#ifdef CONFIG_MSM8X60_RTAC
111 rtac_set_voice_handle(RTAC_CVS, apr_cvs);
112#endif
113}
114
Neema Shetty90189b82011-06-27 14:58:37 -0700115static void *voice_get_apr_cvp(void)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700116{
117 void *apr_cvp = NULL;
118
Neema Shetty90189b82011-06-27 14:58:37 -0700119 if (common.voc_path == VOC_PATH_PASSIVE &&
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700120 !(is_adsp_support_cvd()))
Neema Shetty90189b82011-06-27 14:58:37 -0700121 apr_cvp = common.apr_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700122 else
Neema Shetty90189b82011-06-27 14:58:37 -0700123 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700124
125 pr_debug("%s: apr_cvp 0x%x\n", __func__, (unsigned int)apr_cvp);
126
127 return apr_cvp;
128}
129
Neema Shetty90189b82011-06-27 14:58:37 -0700130static void voice_set_apr_cvp(void *apr_cvp)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700131{
132 pr_debug("%s: apr_cvp 0x%x\n", __func__, (unsigned int)apr_cvp);
133
Neema Shetty90189b82011-06-27 14:58:37 -0700134 if (common.voc_path == VOC_PATH_PASSIVE &&
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700135 !(is_adsp_support_cvd()))
Neema Shetty90189b82011-06-27 14:58:37 -0700136 common.apr_cvp = apr_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700137 else
Neema Shetty90189b82011-06-27 14:58:37 -0700138 common.apr_q6_cvp = apr_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700139#ifdef CONFIG_MSM8X60_RTAC
140 rtac_set_voice_handle(RTAC_CVP, apr_cvp);
141#endif
142}
143
144static u16 voice_get_mvm_handle(struct voice_data *v)
145{
Neema Shetty90189b82011-06-27 14:58:37 -0700146 pr_debug("%s: mvm_handle %d\n", __func__, v->mvm_handle);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700147
Neema Shetty90189b82011-06-27 14:58:37 -0700148 return v->mvm_handle;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700149}
150
151static void voice_set_mvm_handle(struct voice_data *v, u16 mvm_handle)
152{
Neema Shetty90189b82011-06-27 14:58:37 -0700153 pr_debug("%s: session 0x%x, mvm_handle %d\n",
154 __func__, (unsigned int)v, mvm_handle);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700155
Neema Shetty90189b82011-06-27 14:58:37 -0700156 v->mvm_handle = mvm_handle;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700157}
158
159static u16 voice_get_cvs_handle(struct voice_data *v)
160{
Neema Shetty90189b82011-06-27 14:58:37 -0700161 pr_debug("%s: cvs_handle %d\n", __func__, v->cvs_handle);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700162
Neema Shetty90189b82011-06-27 14:58:37 -0700163 return v->cvs_handle;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700164}
165
166static void voice_set_cvs_handle(struct voice_data *v, u16 cvs_handle)
167{
Neema Shetty90189b82011-06-27 14:58:37 -0700168 pr_debug("%s: session 0x%x, cvs_handle %d\n",
169 __func__, (unsigned int)v, cvs_handle);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700170
Neema Shetty90189b82011-06-27 14:58:37 -0700171 v->cvs_handle = cvs_handle;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700172}
173
174static u16 voice_get_cvp_handle(struct voice_data *v)
175{
Neema Shetty90189b82011-06-27 14:58:37 -0700176 pr_debug("%s: cvp_handle %d\n", __func__, v->cvp_handle);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700177
Neema Shetty90189b82011-06-27 14:58:37 -0700178 return v->cvp_handle;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700179}
180
181static void voice_set_cvp_handle(struct voice_data *v, u16 cvp_handle)
182{
Neema Shetty90189b82011-06-27 14:58:37 -0700183 pr_debug("%s: session 0x%x, cvp_handle %d\n",
184 __func__, (unsigned int)v, cvp_handle);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700185
Neema Shetty90189b82011-06-27 14:58:37 -0700186 v->cvp_handle = cvp_handle;
187}
188
189u16 voice_get_session_id(const char *name)
190{
191 u16 session_id = 0;
192
193 if (name != NULL) {
194 if (!strncmp(name, "Voice session", 13))
195 session_id = common.voice[VOC_PATH_PASSIVE].session_id;
196 else
197 session_id = common.voice[VOC_PATH_FULL].session_id;
198 }
199
200 pr_debug("%s: %s has session id 0x%x\n", __func__, name, session_id);
201
202 return session_id;
203}
204
205static struct voice_data *voice_get_session(u16 session_id)
206{
207 struct voice_data *v = NULL;
208
209 if (session_id == 0) {
210 mutex_lock(&common.common_lock);
211
212 pr_debug("%s: NULL id, voc_path is %d\n",
213 __func__, common.voc_path);
214
215 if (common.voc_path == VOC_PATH_PASSIVE)
216 v = &common.voice[VOC_PATH_PASSIVE];
217 else
218 v = &common.voice[VOC_PATH_FULL];
219
220 mutex_unlock(&common.common_lock);
221 } else if ((session_id >= SESSION_ID_BASE) &&
222 (session_id < SESSION_ID_BASE + MAX_VOC_SESSIONS)) {
223 v = &common.voice[session_id - SESSION_ID_BASE];
224 } else {
225 pr_err("%s: Invalid session_id 0x%x\n", __func__, session_id);
226 }
227
228 pr_debug("%s: session_id 0x%x session handle 0x%x\n",
229 __func__, session_id, (unsigned int)v);
230
231 return v;
232}
233
234static bool is_voice_session(u16 session_id)
235{
236 return (session_id == common.voice[VOC_PATH_PASSIVE].session_id);
237}
238
239static bool is_voip_session(u16 session_id)
240{
241 return (session_id == common.voice[VOC_PATH_FULL].session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700242}
243
244static void voice_auddev_cb_function(u32 evt_id,
245 union auddev_evt_data *evt_payload,
246 void *private_data);
247
248static int32_t modem_mvm_callback(struct apr_client_data *data, void *priv);
249static int32_t modem_cvs_callback(struct apr_client_data *data, void *priv);
250static int32_t modem_cvp_callback(struct apr_client_data *data, void *priv);
251
Neema Shetty90189b82011-06-27 14:58:37 -0700252static int voice_apr_register(void)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700253{
254 int rc = 0;
255 void *apr_mvm;
256 void *apr_cvs;
257 void *apr_cvp;
258
Neema Shetty90189b82011-06-27 14:58:37 -0700259 if (common.adsp_version == 0) {
260 common.adsp_version = core_get_adsp_version();
261 pr_info("adsp_ver fetched:%x\n", common.adsp_version);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700262 }
Neema Shetty90189b82011-06-27 14:58:37 -0700263
264 mutex_lock(&common.common_lock);
265
266 apr_mvm = voice_get_apr_mvm();
267 apr_cvs = voice_get_apr_cvs();
268 apr_cvp = voice_get_apr_cvp();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700269
270
271 pr_debug("into voice_apr_register_callback\n");
272 /* register callback to APR */
273 if (apr_mvm == NULL) {
274 pr_debug("start to register MVM callback\n");
275
Neema Shetty90189b82011-06-27 14:58:37 -0700276 if (common.voc_path == VOC_PATH_PASSIVE &&
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700277 !(is_adsp_support_cvd())) {
278 apr_mvm = apr_register("MODEM", "MVM",
279 modem_mvm_callback, 0xFFFFFFFF,
Neema Shetty90189b82011-06-27 14:58:37 -0700280 &common);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700281 } else {
282 apr_mvm = apr_register("ADSP", "MVM",
283 modem_mvm_callback, 0xFFFFFFFF,
Neema Shetty90189b82011-06-27 14:58:37 -0700284 &common);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700285 }
286
287 if (apr_mvm == NULL) {
288 pr_err("Unable to register MVM %d\n",
289 is_adsp_support_cvd());
290 rc = -ENODEV;
291 goto done;
292 }
293
Neema Shetty90189b82011-06-27 14:58:37 -0700294 voice_set_apr_mvm(apr_mvm);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700295 }
296
297 if (apr_cvs == NULL) {
298 pr_debug("start to register CVS callback\n");
299
Neema Shetty90189b82011-06-27 14:58:37 -0700300 if (common.voc_path == VOC_PATH_PASSIVE &&
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700301 !(is_adsp_support_cvd())) {
302 apr_cvs = apr_register("MODEM", "CVS",
303 modem_cvs_callback, 0xFFFFFFFF,
Neema Shetty90189b82011-06-27 14:58:37 -0700304 &common);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700305 } else {
306 apr_cvs = apr_register("ADSP", "CVS",
307 modem_cvs_callback, 0xFFFFFFFF,
Neema Shetty90189b82011-06-27 14:58:37 -0700308 &common);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700309 }
310
311 if (apr_cvs == NULL) {
312 pr_err("Unable to register CVS %d\n",
313 is_adsp_support_cvd());
314 rc = -ENODEV;
315 goto err;
316 }
317
Neema Shetty90189b82011-06-27 14:58:37 -0700318 voice_set_apr_cvs(apr_cvs);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700319 }
320
321 if (apr_cvp == NULL) {
322 pr_debug("start to register CVP callback\n");
323
Neema Shetty90189b82011-06-27 14:58:37 -0700324 if (common.voc_path == VOC_PATH_PASSIVE &&
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700325 !(is_adsp_support_cvd())) {
326 apr_cvp = apr_register("MODEM", "CVP",
327 modem_cvp_callback, 0xFFFFFFFF,
Neema Shetty90189b82011-06-27 14:58:37 -0700328 &common);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700329 } else {
330 apr_cvp = apr_register("ADSP", "CVP",
331 modem_cvp_callback, 0xFFFFFFFF,
Neema Shetty90189b82011-06-27 14:58:37 -0700332 &common);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700333 }
334
335 if (apr_cvp == NULL) {
336 pr_err("Unable to register CVP %d\n",
337 is_adsp_support_cvd());
338 rc = -ENODEV;
339 goto err1;
340 }
341
Neema Shetty90189b82011-06-27 14:58:37 -0700342 voice_set_apr_cvp(apr_cvp);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700343 }
Neema Shetty90189b82011-06-27 14:58:37 -0700344
345 mutex_unlock(&common.common_lock);
346
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700347 return 0;
348
349err1:
350 apr_deregister(apr_cvs);
351 apr_cvs = NULL;
Neema Shetty90189b82011-06-27 14:58:37 -0700352 voice_set_apr_cvs(apr_cvs);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700353err:
354 apr_deregister(apr_mvm);
355 apr_mvm = NULL;
Neema Shetty90189b82011-06-27 14:58:37 -0700356 voice_set_apr_mvm(apr_mvm);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700357
358done:
Neema Shetty90189b82011-06-27 14:58:37 -0700359 mutex_unlock(&common.common_lock);
360
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700361 return rc;
362}
363
364static int voice_create_mvm_cvs_session(struct voice_data *v)
365{
366 int ret = 0;
367 struct mvm_create_ctl_session_cmd mvm_session_cmd;
368 struct cvs_create_passive_ctl_session_cmd cvs_session_cmd;
369 struct cvs_create_full_ctl_session_cmd cvs_full_ctl_cmd;
370 struct mvm_attach_stream_cmd attach_stream_cmd;
Neema Shetty90189b82011-06-27 14:58:37 -0700371 void *apr_mvm = voice_get_apr_mvm();
372 void *apr_cvs = voice_get_apr_cvs();
373 void *apr_cvp = voice_get_apr_cvp();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700374 u16 mvm_handle = voice_get_mvm_handle(v);
375 u16 cvs_handle = voice_get_cvs_handle(v);
376 u16 cvp_handle = voice_get_cvp_handle(v);
377
378 pr_info("%s:\n", __func__);
379
380 /* start to ping if modem service is up */
381 pr_debug("in voice_create_mvm_cvs_session, mvm_hdl=%d, cvs_hdl=%d\n",
382 mvm_handle, cvs_handle);
383 /* send cmd to create mvm session and wait for response */
384
385 if (!mvm_handle) {
Neema Shetty90189b82011-06-27 14:58:37 -0700386 if (is_voice_session(v->session_id)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700387 mvm_session_cmd.hdr.hdr_field =
388 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
389 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
390 mvm_session_cmd.hdr.pkt_size =
391 APR_PKT_SIZE(APR_HDR_SIZE,
392 sizeof(mvm_session_cmd) - APR_HDR_SIZE);
393 pr_debug("Send mvm create session pkt size = %d\n",
394 mvm_session_cmd.hdr.pkt_size);
Neema Shetty90189b82011-06-27 14:58:37 -0700395 mvm_session_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700396 mvm_session_cmd.hdr.dest_port = 0;
397 mvm_session_cmd.hdr.token = 0;
398 pr_debug("%s: Creating MVM passive ctrl\n", __func__);
399 mvm_session_cmd.hdr.opcode =
400 VSS_IMVM_CMD_CREATE_PASSIVE_CONTROL_SESSION;
401 strncpy(mvm_session_cmd.mvm_session.name,
402 "default modem voice", SESSION_NAME_LEN);
403
404 v->mvm_state = CMD_STATUS_FAIL;
405
406 ret = apr_send_pkt(apr_mvm,
407 (uint32_t *) &mvm_session_cmd);
408 if (ret < 0) {
409 pr_err("Error sending MVM_CONTROL_SESSION\n");
410 goto fail;
411 }
412 ret = wait_event_timeout(v->mvm_wait,
413 (v->mvm_state == CMD_STATUS_SUCCESS),
414 msecs_to_jiffies(TIMEOUT_MS));
415 if (!ret) {
416 pr_err("%s: wait_event timeout\n", __func__);
417 goto fail;
418 }
419 } else {
420 mvm_session_cmd.hdr.hdr_field =
421 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
422 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
423 mvm_session_cmd.hdr.pkt_size =
424 APR_PKT_SIZE(APR_HDR_SIZE,
425 sizeof(mvm_session_cmd) - APR_HDR_SIZE);
426 pr_debug("Send mvm create session pkt size = %d\n",
427 mvm_session_cmd.hdr.pkt_size);
Neema Shetty90189b82011-06-27 14:58:37 -0700428 mvm_session_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700429 mvm_session_cmd.hdr.dest_port = 0;
430 mvm_session_cmd.hdr.token = 0;
431 pr_debug("%s: Creating MVM full ctrl\n", __func__);
432 mvm_session_cmd.hdr.opcode =
433 VSS_IMVM_CMD_CREATE_FULL_CONTROL_SESSION;
434 strncpy(mvm_session_cmd.mvm_session.name,
435 "default voip", SESSION_NAME_LEN);
436
437 v->mvm_state = CMD_STATUS_FAIL;
438
439 ret = apr_send_pkt(apr_mvm,
440 (uint32_t *) &mvm_session_cmd);
441 if (ret < 0) {
442 pr_err("Error sending MVM_FULL_CTL_SESSION\n");
443 goto fail;
444 }
445 ret = wait_event_timeout(v->mvm_wait,
446 (v->mvm_state == CMD_STATUS_SUCCESS),
447 msecs_to_jiffies(TIMEOUT_MS));
448 if (!ret) {
449 pr_err("%s: wait_event timeout\n", __func__);
450 goto fail;
451 }
452 }
453
454 /* Get the created MVM handle. */
455 mvm_handle = voice_get_mvm_handle(v);
456 }
457
458 /* send cmd to create cvs session */
459 if (!cvs_handle) {
Neema Shetty90189b82011-06-27 14:58:37 -0700460 if (is_voice_session(v->session_id)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700461 pr_info("%s:creating CVS passive session\n", __func__);
462
463 cvs_session_cmd.hdr.hdr_field = APR_HDR_FIELD(
464 APR_MSG_TYPE_SEQ_CMD,
465 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
466 cvs_session_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
467 sizeof(cvs_session_cmd) - APR_HDR_SIZE);
468 pr_info("send stream create session pkt size = %d\n",
469 cvs_session_cmd.hdr.pkt_size);
Neema Shetty90189b82011-06-27 14:58:37 -0700470 cvs_session_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700471 cvs_session_cmd.hdr.dest_port = 0;
472 cvs_session_cmd.hdr.token = 0;
473 cvs_session_cmd.hdr.opcode =
474 VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION;
475 strncpy(cvs_session_cmd.cvs_session.name,
476 "default modem voice", SESSION_NAME_LEN);
477
478 v->cvs_state = CMD_STATUS_FAIL;
479
480 pr_info("%s: CVS create\n", __func__);
481 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_session_cmd);
482 if (ret < 0) {
483 pr_err("Fail in sending STREAM_CONTROL_SESSION\n");
484 goto fail;
485 }
486 ret = wait_event_timeout(v->cvs_wait,
487 (v->cvs_state == CMD_STATUS_SUCCESS),
488 msecs_to_jiffies(TIMEOUT_MS));
489 if (!ret) {
490 pr_err("%s: wait_event timeout\n", __func__);
491 goto fail;
492 }
493
494 /* Get the created CVS handle. */
495 cvs_handle = voice_get_cvs_handle(v);
496 } else {
497 pr_info("%s:creating CVS full session\n", __func__);
498
499 cvs_full_ctl_cmd.hdr.hdr_field =
500 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
501 APR_HDR_LEN(APR_HDR_SIZE),
502 APR_PKT_VER);
503
504 cvs_full_ctl_cmd.hdr.pkt_size =
505 APR_PKT_SIZE(APR_HDR_SIZE,
506 sizeof(cvs_full_ctl_cmd) - APR_HDR_SIZE);
507
Neema Shetty90189b82011-06-27 14:58:37 -0700508 cvs_full_ctl_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700509 cvs_full_ctl_cmd.hdr.dest_port = 0;
510 cvs_full_ctl_cmd.hdr.token = 0;
511 cvs_full_ctl_cmd.hdr.opcode =
512 VSS_ISTREAM_CMD_CREATE_FULL_CONTROL_SESSION;
513 cvs_full_ctl_cmd.cvs_session.direction = 2;
514
515 cvs_full_ctl_cmd.cvs_session.enc_media_type =
Neema Shetty90189b82011-06-27 14:58:37 -0700516 common.mvs_info.media_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700517 cvs_full_ctl_cmd.cvs_session.dec_media_type =
Neema Shetty90189b82011-06-27 14:58:37 -0700518 common.mvs_info.media_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700519 cvs_full_ctl_cmd.cvs_session.network_id =
Neema Shetty90189b82011-06-27 14:58:37 -0700520 common.mvs_info.network_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700521 strncpy(cvs_full_ctl_cmd.cvs_session.name,
522 "default voip", SESSION_NAME_LEN);
523
524 v->cvs_state = CMD_STATUS_FAIL;
525
526 ret = apr_send_pkt(apr_cvs,
527 (uint32_t *) &cvs_full_ctl_cmd);
528
529 if (ret < 0) {
530 pr_err("%s: Err %d sending CREATE_FULL_CTRL\n",
531 __func__, ret);
532 goto fail;
533 }
534 ret = wait_event_timeout(v->cvs_wait,
535 (v->cvs_state == CMD_STATUS_SUCCESS),
536 msecs_to_jiffies(TIMEOUT_MS));
537 if (!ret) {
538 pr_err("%s: wait_event timeout\n", __func__);
539 goto fail;
540 }
541
542 /* Get the created CVS handle. */
543 cvs_handle = voice_get_cvs_handle(v);
544
545 /* Attach MVM to CVS. */
546 pr_info("%s: Attach MVM to stream\n", __func__);
547
548 attach_stream_cmd.hdr.hdr_field =
549 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
550 APR_HDR_LEN(APR_HDR_SIZE),
551 APR_PKT_VER);
552
553 attach_stream_cmd.hdr.pkt_size =
554 APR_PKT_SIZE(APR_HDR_SIZE,
555 sizeof(attach_stream_cmd) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -0700556 attach_stream_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700557 attach_stream_cmd.hdr.dest_port = mvm_handle;
558 attach_stream_cmd.hdr.token = 0;
559 attach_stream_cmd.hdr.opcode =
560 VSS_IMVM_CMD_ATTACH_STREAM;
561 attach_stream_cmd.attach_stream.handle = cvs_handle;
562
563 v->mvm_state = CMD_STATUS_FAIL;
564 ret = apr_send_pkt(apr_mvm,
565 (uint32_t *) &attach_stream_cmd);
566 if (ret < 0) {
567 pr_err("%s: Error %d sending ATTACH_STREAM\n",
568 __func__, ret);
569 goto fail;
570 }
571 ret = wait_event_timeout(v->mvm_wait,
572 (v->mvm_state == CMD_STATUS_SUCCESS),
573 msecs_to_jiffies(TIMEOUT_MS));
574 if (!ret) {
575 pr_err("%s: wait_event timeout\n", __func__);
576 goto fail;
577 }
578 }
579 }
580
581 return 0;
582
583fail:
584 apr_deregister(apr_mvm);
585 apr_mvm = NULL;
Neema Shetty90189b82011-06-27 14:58:37 -0700586 voice_set_apr_mvm(apr_mvm);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700587
588 apr_deregister(apr_cvs);
589 apr_cvs = NULL;
Neema Shetty90189b82011-06-27 14:58:37 -0700590 voice_set_apr_cvs(apr_cvs);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700591
592 apr_deregister(apr_cvp);
593 apr_cvp = NULL;
Neema Shetty90189b82011-06-27 14:58:37 -0700594 voice_set_apr_cvp(apr_cvp);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700595
596 cvp_handle = 0;
597 voice_set_cvp_handle(v, cvp_handle);
598
599 cvs_handle = 0;
600 voice_set_cvs_handle(v, cvs_handle);
601
602 return -EINVAL;
603}
604
605static int voice_destroy_mvm_cvs_session(struct voice_data *v)
606{
607 int ret = 0;
608 struct mvm_detach_stream_cmd detach_stream;
609 struct apr_hdr mvm_destroy;
610 struct apr_hdr cvs_destroy;
Neema Shetty90189b82011-06-27 14:58:37 -0700611 void *apr_mvm = voice_get_apr_mvm();
612 void *apr_cvs = voice_get_apr_cvs();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700613 u16 mvm_handle = voice_get_mvm_handle(v);
614 u16 cvs_handle = voice_get_cvs_handle(v);
615
616 /* MVM, CVS sessions are destroyed only for Full control sessions. */
Neema Shetty90189b82011-06-27 14:58:37 -0700617 if (is_voip_session(v->session_id)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700618 pr_info("%s: MVM detach stream\n", __func__);
619
620 /* Detach voice stream. */
621 detach_stream.hdr.hdr_field =
622 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
623 APR_HDR_LEN(APR_HDR_SIZE),
624 APR_PKT_VER);
625 detach_stream.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
626 sizeof(detach_stream) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -0700627 detach_stream.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700628 detach_stream.hdr.dest_port = mvm_handle;
629 detach_stream.hdr.token = 0;
630 detach_stream.hdr.opcode = VSS_IMVM_CMD_DETACH_STREAM;
631 detach_stream.detach_stream.handle = cvs_handle;
632
633 v->mvm_state = CMD_STATUS_FAIL;
634
635 ret = apr_send_pkt(apr_mvm, (uint32_t *) &detach_stream);
636 if (ret < 0) {
637 pr_err("%s: Error %d sending DETACH_STREAM\n",
638 __func__, ret);
639
640 goto fail;
641 }
642
643 ret = wait_event_timeout(v->mvm_wait,
644 (v->mvm_state == CMD_STATUS_SUCCESS),
645 msecs_to_jiffies(TIMEOUT_MS));
646 if (!ret) {
647 pr_err("%s: wait event timeout\n", __func__);
648 goto fail;
649 }
650
651 /* Destroy CVS. */
652 pr_info("%s: CVS destroy session\n", __func__);
653
654 cvs_destroy.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
655 APR_HDR_LEN(APR_HDR_SIZE),
656 APR_PKT_VER);
657 cvs_destroy.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
658 sizeof(cvs_destroy) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -0700659 cvs_destroy.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700660 cvs_destroy.dest_port = cvs_handle;
661 cvs_destroy.token = 0;
662 cvs_destroy.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
663
664 v->cvs_state = CMD_STATUS_FAIL;
665
666 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_destroy);
667 if (ret < 0) {
668 pr_err("%s: Error %d sending CVS DESTROY\n",
669 __func__, ret);
670
671 goto fail;
672 }
673
674 ret = wait_event_timeout(v->cvs_wait,
675 (v->cvs_state == CMD_STATUS_SUCCESS),
676 msecs_to_jiffies(TIMEOUT_MS));
677 if (!ret) {
678 pr_err("%s: wait event timeout\n", __func__);
679
680 goto fail;
681 }
682 cvs_handle = 0;
683 voice_set_cvs_handle(v, cvs_handle);
684
685 /* Destroy MVM. */
686 pr_info("%s: MVM destroy session\n", __func__);
687
688 mvm_destroy.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
689 APR_HDR_LEN(APR_HDR_SIZE),
690 APR_PKT_VER);
691 mvm_destroy.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
692 sizeof(mvm_destroy) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -0700693 mvm_destroy.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700694 mvm_destroy.dest_port = mvm_handle;
695 mvm_destroy.token = 0;
696 mvm_destroy.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
697
698 v->mvm_state = CMD_STATUS_FAIL;
699
700 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_destroy);
701 if (ret < 0) {
702 pr_err("%s: Error %d sending MVM DESTROY\n",
703 __func__, ret);
704
705 goto fail;
706 }
707
708 ret = wait_event_timeout(v->mvm_wait,
709 (v->mvm_state == CMD_STATUS_SUCCESS),
710 msecs_to_jiffies(TIMEOUT_MS));
711 if (!ret) {
712 pr_err("%s: wait event timeout\n", __func__);
713
714 goto fail;
715 }
716 mvm_handle = 0;
717 voice_set_mvm_handle(v, mvm_handle);
718 }
719
720fail:
721 return 0;
722}
723
724static int voice_send_tty_mode_to_modem(struct voice_data *v)
725{
726 struct msm_snddev_info *dev_tx_info;
727 struct msm_snddev_info *dev_rx_info;
728 int tty_mode = 0;
729 int ret = 0;
730 struct mvm_set_tty_mode_cmd mvm_tty_mode_cmd;
Neema Shetty90189b82011-06-27 14:58:37 -0700731 void *apr_mvm = voice_get_apr_mvm();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700732 u16 mvm_handle = voice_get_mvm_handle(v);
733
734 dev_rx_info = audio_dev_ctrl_find_dev(v->dev_rx.dev_id);
735 if (IS_ERR(dev_rx_info)) {
736 pr_err("bad dev_id %d\n", v->dev_rx.dev_id);
737 goto done;
738 }
739
740 dev_tx_info = audio_dev_ctrl_find_dev(v->dev_tx.dev_id);
741 if (IS_ERR(dev_tx_info)) {
742 pr_err("bad dev_id %d\n", v->dev_tx.dev_id);
743 goto done;
744 }
745
746 if ((dev_rx_info->capability & SNDDEV_CAP_TTY) &&
747 (dev_tx_info->capability & SNDDEV_CAP_TTY))
748 tty_mode = 3; /* FULL */
749 else if (!(dev_tx_info->capability & SNDDEV_CAP_TTY) &&
750 (dev_rx_info->capability & SNDDEV_CAP_TTY))
751 tty_mode = 2; /* VCO */
752 else if ((dev_tx_info->capability & SNDDEV_CAP_TTY) &&
753 !(dev_rx_info->capability & SNDDEV_CAP_TTY))
754 tty_mode = 1; /* HCO */
755
756 if (tty_mode) {
757 /* send tty mode cmd to mvm */
758 mvm_tty_mode_cmd.hdr.hdr_field = APR_HDR_FIELD(
759 APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
760 APR_PKT_VER);
761 mvm_tty_mode_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
762 sizeof(mvm_tty_mode_cmd) - APR_HDR_SIZE);
763 pr_debug("pkt size = %d\n", mvm_tty_mode_cmd.hdr.pkt_size);
Neema Shetty90189b82011-06-27 14:58:37 -0700764 mvm_tty_mode_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700765 mvm_tty_mode_cmd.hdr.dest_port = mvm_handle;
766 mvm_tty_mode_cmd.hdr.token = 0;
767 mvm_tty_mode_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_TTY_MODE;
768 mvm_tty_mode_cmd.tty_mode.mode = tty_mode;
769 pr_info("tty mode =%d\n", mvm_tty_mode_cmd.tty_mode.mode);
770
771 v->mvm_state = CMD_STATUS_FAIL;
772 pr_info("%s: MVM set tty\n", __func__);
773 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_tty_mode_cmd);
774 if (ret < 0) {
775 pr_err("Fail: sending VSS_ISTREAM_CMD_SET_TTY_MODE\n");
776 goto done;
777 }
778 ret = wait_event_timeout(v->mvm_wait,
779 (v->mvm_state == CMD_STATUS_SUCCESS),
780 msecs_to_jiffies(TIMEOUT_MS));
781 if (!ret) {
782 pr_err("%s: wait_event timeout\n", __func__);
783 goto done;
784 }
785 }
786 return 0;
787done:
788 return -EINVAL;
789}
790
791static int voice_send_cvs_cal_to_modem(struct voice_data *v)
792{
793 struct apr_hdr cvs_cal_cmd_hdr;
794 uint32_t *cmd_buf;
795 struct acdb_cal_data cal_data;
796 struct acdb_cal_block *cal_blk;
797 int32_t cal_size_per_network;
798 uint32_t *cal_data_per_network;
799 int index = 0;
800 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -0700801 void *apr_cvs = voice_get_apr_cvs();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700802 u16 cvs_handle = voice_get_cvs_handle(v);
803
804 /* fill the header */
805 cvs_cal_cmd_hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
806 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
807 cvs_cal_cmd_hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
808 sizeof(cvs_cal_cmd_hdr) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -0700809 cvs_cal_cmd_hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700810 cvs_cal_cmd_hdr.dest_port = cvs_handle;
811 cvs_cal_cmd_hdr.token = 0;
812 cvs_cal_cmd_hdr.opcode =
813 VSS_ISTREAM_CMD_CACHE_CALIBRATION_DATA;
814
815 pr_debug("voice_send_cvs_cal_to_modem\n");
816 /* get the cvs cal data */
817 get_vocstrm_cal(&cal_data);
818 if (cal_data.num_cal_blocks == 0) {
819 pr_err("%s: No calibration data to send!\n", __func__);
820 goto done;
821 }
822
823 /* send cvs cal to modem */
824 cmd_buf = kzalloc((sizeof(struct apr_hdr) + BUFFER_PAYLOAD_SIZE),
825 GFP_KERNEL);
826 if (!cmd_buf) {
827 pr_err("No memory is allocated.\n");
828 return -ENOMEM;
829 }
830 pr_debug("----- num_cal_blocks=%d\n", (s32)cal_data.num_cal_blocks);
831 cal_blk = cal_data.cal_blocks;
832 pr_debug("cal_blk =%x\n", (uint32_t)cal_data.cal_blocks);
833
834 for (; index < cal_data.num_cal_blocks; index++) {
835 cal_size_per_network = cal_blk[index].cal_size;
836 pr_debug(" cal size =%d\n", cal_size_per_network);
837 if (cal_size_per_network >= BUFFER_PAYLOAD_SIZE)
838 pr_err("Cal size is too big\n");
839 cal_data_per_network = (u32 *)cal_blk[index].cal_kvaddr;
840 pr_debug(" cal data=%x\n", (uint32_t)cal_data_per_network);
841 cvs_cal_cmd_hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
842 cal_size_per_network);
843 pr_debug("header size =%d, pkt_size =%d\n",
844 APR_HDR_SIZE, cvs_cal_cmd_hdr.pkt_size);
845 memcpy(cmd_buf, &cvs_cal_cmd_hdr, APR_HDR_SIZE);
846 memcpy(cmd_buf + (APR_HDR_SIZE / sizeof(uint32_t)),
847 cal_data_per_network, cal_size_per_network);
848 pr_debug("send cvs cal: index =%d\n", index);
849 v->cvs_state = CMD_STATUS_FAIL;
850 ret = apr_send_pkt(apr_cvs, cmd_buf);
851 if (ret < 0) {
852 pr_err("Fail: sending cvs cal, idx=%d\n", index);
853 continue;
854 }
855 ret = wait_event_timeout(v->cvs_wait,
856 (v->cvs_state == CMD_STATUS_SUCCESS),
857 msecs_to_jiffies(TIMEOUT_MS));
858 if (!ret) {
859 pr_err("%s: wait_event timeout\n", __func__);
860 return -EINVAL;
861 }
862 }
863 kfree(cmd_buf);
864done:
865 return 0;
866}
867
868static int voice_send_cvp_cal_to_modem(struct voice_data *v)
869{
870 struct apr_hdr cvp_cal_cmd_hdr;
871 uint32_t *cmd_buf;
872 struct acdb_cal_data cal_data;
873 struct acdb_cal_block *cal_blk;
874 int32_t cal_size_per_network;
875 uint32_t *cal_data_per_network;
876 int index = 0;
877 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -0700878 void *apr_cvp = voice_get_apr_cvp();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700879 u16 cvp_handle = voice_get_cvp_handle(v);
880
881
882 /* fill the header */
883 cvp_cal_cmd_hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
884 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
885 cvp_cal_cmd_hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
886 sizeof(cvp_cal_cmd_hdr) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -0700887 cvp_cal_cmd_hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700888 cvp_cal_cmd_hdr.dest_port = cvp_handle;
889 cvp_cal_cmd_hdr.token = 0;
890 cvp_cal_cmd_hdr.opcode =
891 VSS_IVOCPROC_CMD_CACHE_CALIBRATION_DATA;
892
893 /* get cal data */
894 get_vocproc_cal(&cal_data);
895 if (cal_data.num_cal_blocks == 0) {
896 pr_err("%s: No calibration data to send!\n", __func__);
897 goto done;
898 }
899
900 /* send cal to modem */
901 cmd_buf = kzalloc((sizeof(struct apr_hdr) + BUFFER_PAYLOAD_SIZE),
902 GFP_KERNEL);
903 if (!cmd_buf) {
904 pr_err("No memory is allocated.\n");
905 return -ENOMEM;
906 }
907 pr_debug("----- num_cal_blocks=%d\n", (s32)cal_data.num_cal_blocks);
908 cal_blk = cal_data.cal_blocks;
909 pr_debug(" cal_blk =%x\n", (uint32_t)cal_data.cal_blocks);
910
911 for (; index < cal_data.num_cal_blocks; index++) {
912 cal_size_per_network = cal_blk[index].cal_size;
913 if (cal_size_per_network >= BUFFER_PAYLOAD_SIZE)
914 pr_err("Cal size is too big\n");
915 pr_debug(" cal size =%d\n", cal_size_per_network);
916 cal_data_per_network = (u32 *)cal_blk[index].cal_kvaddr;
917 pr_debug(" cal data=%x\n", (uint32_t)cal_data_per_network);
918
919 cvp_cal_cmd_hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
920 cal_size_per_network);
921 memcpy(cmd_buf, &cvp_cal_cmd_hdr, APR_HDR_SIZE);
922 memcpy(cmd_buf + (APR_HDR_SIZE / sizeof(*cmd_buf)),
923 cal_data_per_network, cal_size_per_network);
924 pr_debug("Send cvp cal\n");
925 v->cvp_state = CMD_STATUS_FAIL;
926 pr_info("%s: CVP calib\n", __func__);
927 ret = apr_send_pkt(apr_cvp, cmd_buf);
928 if (ret < 0) {
929 pr_err("Fail: sending cvp cal, idx=%d\n", index);
930 continue;
931 }
932 ret = wait_event_timeout(v->cvp_wait,
933 (v->cvp_state == CMD_STATUS_SUCCESS),
934 msecs_to_jiffies(TIMEOUT_MS));
935 if (!ret) {
936 pr_err("%s: wait_event timeout\n", __func__);
937 return -EINVAL;
938 }
939 }
940 kfree(cmd_buf);
941done:
942 return 0;
943}
944
945static int voice_send_cvp_vol_tbl_to_modem(struct voice_data *v)
946{
947 struct apr_hdr cvp_vol_cal_cmd_hdr;
948 uint32_t *cmd_buf;
949 struct acdb_cal_data cal_data;
950 struct acdb_cal_block *cal_blk;
951 int32_t cal_size_per_network;
952 uint32_t *cal_data_per_network;
Ben Rombergerb4f562a2011-07-13 19:57:54 -0700953 uint32_t num_volume_steps;
954 int offset = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700955 int index = 0;
956 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -0700957 void *apr_cvp = voice_get_apr_cvp();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700958 u16 cvp_handle = voice_get_cvp_handle(v);
959
960
961 /* fill the header */
962 cvp_vol_cal_cmd_hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
963 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
964 cvp_vol_cal_cmd_hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
965 sizeof(cvp_vol_cal_cmd_hdr) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -0700966 cvp_vol_cal_cmd_hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700967 cvp_vol_cal_cmd_hdr.dest_port = cvp_handle;
968 cvp_vol_cal_cmd_hdr.token = 0;
969 cvp_vol_cal_cmd_hdr.opcode =
970 VSS_IVOCPROC_CMD_CACHE_VOLUME_CALIBRATION_TABLE;
971
972 /* get cal data */
973 get_vocvol_cal(&cal_data);
974 if (cal_data.num_cal_blocks == 0) {
975 pr_err("%s: No calibration data to send!\n", __func__);
976 goto done;
977 }
978
979 /* send cal to modem */
980 cmd_buf = kzalloc((sizeof(struct apr_hdr) + BUFFER_PAYLOAD_SIZE),
981 GFP_KERNEL);
982 if (!cmd_buf) {
983 pr_err("No memory is allocated.\n");
984 return -ENOMEM;
985 }
986 pr_debug("----- num_cal_blocks=%d\n", (s32)cal_data.num_cal_blocks);
987 cal_blk = cal_data.cal_blocks;
988 pr_debug("Cal_blk =%x\n", (uint32_t)cal_data.cal_blocks);
989
990 for (; index < cal_data.num_cal_blocks; index++) {
991 cal_size_per_network = cal_blk[index].cal_size;
992 cal_data_per_network = (u32 *)cal_blk[index].cal_kvaddr;
Ben Rombergerb4f562a2011-07-13 19:57:54 -0700993
994 /* Number of volume steps are only included in the */
995 /* first block, need to be inserted into the rest */
996 if (index != 0) {
997 offset = sizeof(num_volume_steps);
998 memcpy(cmd_buf + (APR_HDR_SIZE / sizeof(uint32_t)),
999 &num_volume_steps, offset);
1000 } else {
1001 num_volume_steps = *cal_data_per_network;
1002 }
1003
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001004 pr_debug("Cal size =%d, index=%d\n", cal_size_per_network,
1005 index);
1006 pr_debug("Cal data=%x\n", (uint32_t)cal_data_per_network);
1007 cvp_vol_cal_cmd_hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
Ben Rombergerb4f562a2011-07-13 19:57:54 -07001008 cal_size_per_network + offset);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001009 memcpy(cmd_buf, &cvp_vol_cal_cmd_hdr, APR_HDR_SIZE);
Ben Rombergerb4f562a2011-07-13 19:57:54 -07001010 memcpy(cmd_buf + (APR_HDR_SIZE / sizeof(uint32_t)) +
1011 offset, cal_data_per_network, cal_size_per_network);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001012 pr_debug("Send vol table\n");
1013
1014 v->cvp_state = CMD_STATUS_FAIL;
1015 ret = apr_send_pkt(apr_cvp, cmd_buf);
1016 if (ret < 0) {
1017 pr_err("Fail: sending cvp vol cal, idx=%d\n", index);
1018 continue;
1019 }
1020 ret = wait_event_timeout(v->cvp_wait,
1021 (v->cvp_state == CMD_STATUS_SUCCESS),
1022 msecs_to_jiffies(TIMEOUT_MS));
1023 if (!ret) {
1024 pr_err("%s: wait_event timeout\n", __func__);
1025 return -EINVAL;
1026 }
1027 }
1028 kfree(cmd_buf);
1029done:
1030 return 0;
1031}
1032
1033static int voice_set_dtx(struct voice_data *v)
1034{
1035 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001036 void *apr_cvs = voice_get_apr_cvs();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001037 u16 cvs_handle = voice_get_cvs_handle(v);
1038
1039 /* Set DTX */
1040 struct cvs_set_enc_dtx_mode_cmd cvs_set_dtx = {
1041 .hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1042 APR_HDR_LEN(APR_HDR_SIZE),
1043 APR_PKT_VER),
1044 .hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1045 sizeof(cvs_set_dtx) - APR_HDR_SIZE),
Neema Shetty90189b82011-06-27 14:58:37 -07001046 .hdr.src_port = v->session_id,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001047 .hdr.dest_port = cvs_handle,
1048 .hdr.token = 0,
1049 .hdr.opcode = VSS_ISTREAM_CMD_SET_ENC_DTX_MODE,
Neema Shetty90189b82011-06-27 14:58:37 -07001050 .dtx_mode.enable = common.mvs_info.dtx_mode,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001051 };
1052
Neema Shetty90189b82011-06-27 14:58:37 -07001053 pr_debug("%s: Setting DTX %d\n", __func__, common.mvs_info.dtx_mode);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001054
1055 v->cvs_state = CMD_STATUS_FAIL;
1056
1057 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_dtx);
1058 if (ret < 0) {
1059 pr_err("%s: Error %d sending SET_DTX\n", __func__, ret);
1060
1061 goto done;
1062 }
1063
1064 ret = wait_event_timeout(v->cvs_wait,
1065 (v->cvs_state == CMD_STATUS_SUCCESS),
1066 msecs_to_jiffies(TIMEOUT_MS));
1067 if (!ret) {
1068 pr_err("%s: wait_event timeout\n", __func__);
1069
1070 ret = -EINVAL;
1071 }
1072
1073done:
1074 return ret;
1075}
1076
1077static int voice_config_cvs_vocoder(struct voice_data *v)
1078{
1079 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001080 void *apr_cvs = voice_get_apr_cvs();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001081 u16 cvs_handle = voice_get_cvs_handle(v);
1082
1083 /* Set media type. */
1084 struct cvs_set_media_type_cmd cvs_set_media_cmd;
1085
1086 pr_info("%s: Setting media type\n", __func__);
1087
1088 cvs_set_media_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1089 APR_HDR_LEN(APR_HDR_SIZE),
1090 APR_PKT_VER);
1091 cvs_set_media_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1092 sizeof(cvs_set_media_cmd) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001093 cvs_set_media_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001094 cvs_set_media_cmd.hdr.dest_port = cvs_handle;
1095 cvs_set_media_cmd.hdr.token = 0;
1096 cvs_set_media_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_MEDIA_TYPE;
Neema Shetty90189b82011-06-27 14:58:37 -07001097 cvs_set_media_cmd.media_type.tx_media_id = common.mvs_info.media_type;
1098 cvs_set_media_cmd.media_type.rx_media_id = common.mvs_info.media_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001099
1100 v->cvs_state = CMD_STATUS_FAIL;
1101
1102 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_media_cmd);
1103 if (ret < 0) {
1104 pr_err("%s: Error %d sending SET_MEDIA_TYPE\n",
1105 __func__, ret);
1106
1107 goto done;
1108 }
1109
1110 ret = wait_event_timeout(v->cvs_wait,
1111 (v->cvs_state == CMD_STATUS_SUCCESS),
1112 msecs_to_jiffies(TIMEOUT_MS));
1113 if (!ret) {
1114 pr_err("%s: wait_event timeout\n", __func__);
1115
1116 ret = -EINVAL;
1117 goto done;
1118 }
1119
1120 /* Set encoder properties. */
Neema Shetty90189b82011-06-27 14:58:37 -07001121 switch (common.mvs_info.media_type) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001122 case VSS_MEDIA_ID_EVRC_MODEM: {
1123 struct cvs_set_cdma_enc_minmax_rate_cmd cvs_set_cdma_rate;
1124
1125 pr_info("%s: Setting EVRC min-max rate\n", __func__);
1126
1127 cvs_set_cdma_rate.hdr.hdr_field =
1128 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1129 APR_HDR_LEN(APR_HDR_SIZE),
1130 APR_PKT_VER);
1131 cvs_set_cdma_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1132 sizeof(cvs_set_cdma_rate) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001133 cvs_set_cdma_rate.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001134 cvs_set_cdma_rate.hdr.dest_port = cvs_handle;
1135 cvs_set_cdma_rate.hdr.token = 0;
1136 cvs_set_cdma_rate.hdr.opcode =
1137 VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE;
Neema Shetty90189b82011-06-27 14:58:37 -07001138 cvs_set_cdma_rate.cdma_rate.min_rate = common.mvs_info.rate;
1139 cvs_set_cdma_rate.cdma_rate.max_rate = common.mvs_info.rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001140
1141 v->cvs_state = CMD_STATUS_FAIL;
1142
1143 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_cdma_rate);
1144 if (ret < 0) {
1145 pr_err("%s: Error %d sending SET_EVRC_MINMAX_RATE\n",
1146 __func__, ret);
1147
1148 goto done;
1149 }
1150
1151 ret = wait_event_timeout(v->cvs_wait,
1152 (v->cvs_state == CMD_STATUS_SUCCESS),
1153 msecs_to_jiffies(TIMEOUT_MS));
1154 if (!ret) {
1155 pr_err("%s: wait_event timeout\n", __func__);
1156
1157 ret = -EINVAL;
1158 goto done;
1159 }
1160
1161 break;
1162 }
1163
1164 case VSS_MEDIA_ID_AMR_NB_MODEM: {
1165 struct cvs_set_amr_enc_rate_cmd cvs_set_amr_rate;
1166
1167 pr_info("%s: Setting AMR rate\n", __func__);
1168
1169 cvs_set_amr_rate.hdr.hdr_field =
1170 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1171 APR_HDR_LEN(APR_HDR_SIZE),
1172 APR_PKT_VER);
1173 cvs_set_amr_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1174 sizeof(cvs_set_amr_rate) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001175 cvs_set_amr_rate.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001176 cvs_set_amr_rate.hdr.dest_port = cvs_handle;
1177 cvs_set_amr_rate.hdr.token = 0;
1178 cvs_set_amr_rate.hdr.opcode =
1179 VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE;
Neema Shetty90189b82011-06-27 14:58:37 -07001180 cvs_set_amr_rate.amr_rate.mode = common.mvs_info.rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001181
1182 v->cvs_state = CMD_STATUS_FAIL;
1183
1184 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_amr_rate);
1185 if (ret < 0) {
1186 pr_err("%s: Error %d sending SET_AMR_RATE\n",
1187 __func__, ret);
1188
1189 goto done;
1190 }
1191
1192 ret = wait_event_timeout(v->cvs_wait,
1193 (v->cvs_state == CMD_STATUS_SUCCESS),
1194 msecs_to_jiffies(TIMEOUT_MS));
1195 if (!ret) {
1196 pr_err("%s: wait_event timeout\n", __func__);
1197
1198 ret = -EINVAL;
1199 goto done;
1200 }
1201
1202 ret = voice_set_dtx(v);
1203
1204 break;
1205 }
1206
1207 case VSS_MEDIA_ID_AMR_WB_MODEM: {
1208 struct cvs_set_amrwb_enc_rate_cmd cvs_set_amrwb_rate;
1209
1210 pr_info("%s: Setting AMR WB rate\n", __func__);
1211
1212 cvs_set_amrwb_rate.hdr.hdr_field =
1213 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1214 APR_HDR_LEN(APR_HDR_SIZE),
1215 APR_PKT_VER);
1216 cvs_set_amrwb_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1217 sizeof(cvs_set_amrwb_rate) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001218 cvs_set_amrwb_rate.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001219 cvs_set_amrwb_rate.hdr.dest_port = cvs_handle;
1220 cvs_set_amrwb_rate.hdr.token = 0;
1221 cvs_set_amrwb_rate.hdr.opcode =
1222 VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE;
Neema Shetty90189b82011-06-27 14:58:37 -07001223 cvs_set_amrwb_rate.amrwb_rate.mode = common.mvs_info.rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001224
1225 v->cvs_state = CMD_STATUS_FAIL;
1226
1227 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_amrwb_rate);
1228 if (ret < 0) {
1229 pr_err("%s: Error %d sending SET_AMRWB_RATE\n",
1230 __func__, ret);
1231
1232 goto done;
1233 }
1234
1235 ret = wait_event_timeout(v->cvs_wait,
1236 (v->cvs_state == CMD_STATUS_SUCCESS),
1237 msecs_to_jiffies(TIMEOUT_MS));
1238 if (!ret) {
1239 pr_err("%s: wait_event timeout\n", __func__);
1240
1241 ret = -EINVAL;
1242 goto done;
1243 }
1244
1245 ret = voice_set_dtx(v);
1246
1247 break;
1248 }
1249
1250 case VSS_MEDIA_ID_G729:
1251 case VSS_MEDIA_ID_G711_ALAW:
1252 case VSS_MEDIA_ID_G711_MULAW: {
1253 ret = voice_set_dtx(v);
1254
1255 break;
1256 }
1257
1258 default: {
1259 /* Do nothing. */
1260 }
1261 }
1262
1263done:
1264 return ret;
1265}
1266
1267static int voice_send_start_voice_cmd(struct voice_data *v)
1268{
1269 struct apr_hdr mvm_start_voice_cmd;
1270 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001271 void *apr_mvm = voice_get_apr_mvm();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001272 u16 mvm_handle = voice_get_mvm_handle(v);
1273
1274 mvm_start_voice_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1275 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1276 mvm_start_voice_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1277 sizeof(mvm_start_voice_cmd) - APR_HDR_SIZE);
1278 pr_info("send mvm_start_voice_cmd pkt size = %d\n",
1279 mvm_start_voice_cmd.pkt_size);
Neema Shetty90189b82011-06-27 14:58:37 -07001280 mvm_start_voice_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001281 mvm_start_voice_cmd.dest_port = mvm_handle;
1282 mvm_start_voice_cmd.token = 0;
1283 mvm_start_voice_cmd.opcode = VSS_IMVM_CMD_START_VOICE;
1284
1285 v->mvm_state = CMD_STATUS_FAIL;
1286 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_start_voice_cmd);
1287 if (ret < 0) {
1288 pr_err("Fail in sending VSS_IMVM_CMD_START_VOICE\n");
1289 goto fail;
1290 }
1291 ret = wait_event_timeout(v->mvm_wait,
1292 (v->mvm_state == CMD_STATUS_SUCCESS),
1293 msecs_to_jiffies(TIMEOUT_MS));
1294 if (!ret) {
1295 pr_err("%s: wait_event timeout\n", __func__);
1296 goto fail;
1297 }
1298
1299 return 0;
1300fail:
1301 return -EINVAL;
1302}
1303
1304static int voice_disable_vocproc(struct voice_data *v)
1305{
1306 struct apr_hdr cvp_disable_cmd;
1307 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001308 void *apr_cvp = voice_get_apr_cvp();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001309 u16 cvp_handle = voice_get_cvp_handle(v);
1310
1311 /* disable vocproc and wait for respose */
1312 cvp_disable_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1313 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1314 cvp_disable_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1315 sizeof(cvp_disable_cmd) - APR_HDR_SIZE);
1316 pr_debug("cvp_disable_cmd pkt size = %d, cvp_handle=%d\n",
1317 cvp_disable_cmd.pkt_size, cvp_handle);
Neema Shetty90189b82011-06-27 14:58:37 -07001318 cvp_disable_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001319 cvp_disable_cmd.dest_port = cvp_handle;
1320 cvp_disable_cmd.token = 0;
1321 cvp_disable_cmd.opcode = VSS_IVOCPROC_CMD_DISABLE;
1322
1323 v->cvp_state = CMD_STATUS_FAIL;
1324 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_disable_cmd);
1325 if (ret < 0) {
1326 pr_err("Fail in sending VSS_IVOCPROC_CMD_DISABLE\n");
1327 goto fail;
1328 }
1329 ret = wait_event_timeout(v->cvp_wait,
1330 (v->cvp_state == CMD_STATUS_SUCCESS),
1331 msecs_to_jiffies(TIMEOUT_MS));
1332 if (!ret) {
1333 pr_err("%s: wait_event timeout\n", __func__);
1334 goto fail;
1335 }
1336#ifdef CONFIG_MSM8X60_RTAC
1337 rtac_remove_voice(v);
1338#endif
1339
1340 return 0;
1341fail:
1342 return -EINVAL;
1343}
1344
1345static int voice_set_device(struct voice_data *v)
1346{
1347 struct cvp_set_device_cmd cvp_setdev_cmd;
1348 struct msm_snddev_info *dev_tx_info;
1349 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001350 void *apr_cvp = voice_get_apr_cvp();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001351 u16 cvp_handle = voice_get_cvp_handle(v);
1352
1353
1354 /* set device and wait for response */
1355 cvp_setdev_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1356 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1357 cvp_setdev_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1358 sizeof(cvp_setdev_cmd) - APR_HDR_SIZE);
1359 pr_debug(" send create cvp setdev, pkt size = %d\n",
1360 cvp_setdev_cmd.hdr.pkt_size);
Neema Shetty90189b82011-06-27 14:58:37 -07001361 cvp_setdev_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001362 cvp_setdev_cmd.hdr.dest_port = cvp_handle;
1363 cvp_setdev_cmd.hdr.token = 0;
1364 cvp_setdev_cmd.hdr.opcode = VSS_IVOCPROC_CMD_SET_DEVICE;
1365
1366 dev_tx_info = audio_dev_ctrl_find_dev(v->dev_tx.dev_id);
1367 if (IS_ERR(dev_tx_info)) {
1368 pr_err("bad dev_id %d\n", v->dev_tx.dev_id);
1369 goto fail;
1370 }
1371
1372 cvp_setdev_cmd.cvp_set_device.tx_topology_id =
1373 get_voice_tx_topology();
1374 if (cvp_setdev_cmd.cvp_set_device.tx_topology_id == 0) {
1375 if (dev_tx_info->channel_mode > 1)
1376 cvp_setdev_cmd.cvp_set_device.tx_topology_id =
1377 VSS_IVOCPROC_TOPOLOGY_ID_TX_DM_FLUENCE;
1378 else
1379 cvp_setdev_cmd.cvp_set_device.tx_topology_id =
1380 VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
1381 }
1382
1383 /* Use default topology if invalid value in ACDB */
1384 cvp_setdev_cmd.cvp_set_device.rx_topology_id =
1385 get_voice_rx_topology();
1386 if (cvp_setdev_cmd.cvp_set_device.rx_topology_id == 0)
1387 cvp_setdev_cmd.cvp_set_device.rx_topology_id =
1388 VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
1389 cvp_setdev_cmd.cvp_set_device.tx_port_id = v->dev_tx.dev_port_id;
1390 cvp_setdev_cmd.cvp_set_device.rx_port_id = v->dev_rx.dev_port_id;
1391 pr_info("topology=%d , tx_port_id=%d, rx_port_id=%d\n",
1392 cvp_setdev_cmd.cvp_set_device.tx_topology_id,
1393 cvp_setdev_cmd.cvp_set_device.tx_port_id,
1394 cvp_setdev_cmd.cvp_set_device.rx_port_id);
1395
1396 v->cvp_state = CMD_STATUS_FAIL;
1397 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_setdev_cmd);
1398 if (ret < 0) {
1399 pr_err("Fail in sending VOCPROC_FULL_CONTROL_SESSION\n");
1400 goto fail;
1401 }
1402 pr_debug("wait for cvp create session event\n");
1403 ret = wait_event_timeout(v->cvp_wait,
1404 (v->cvp_state == CMD_STATUS_SUCCESS),
1405 msecs_to_jiffies(TIMEOUT_MS));
1406 if (!ret) {
1407 pr_err("%s: wait_event timeout\n", __func__);
1408 goto fail;
1409 }
1410
1411 /* send cvs cal */
1412 voice_send_cvs_cal_to_modem(v);
1413
1414 /* send cvp cal */
1415 voice_send_cvp_cal_to_modem(v);
1416
1417 /* send cvp vol table cal */
1418 voice_send_cvp_vol_tbl_to_modem(v);
1419
1420 /* enable vocproc and wait for respose */
1421 voice_send_enable_vocproc_cmd(v);
1422
1423 /* send tty mode if tty device is used */
1424 voice_send_tty_mode_to_modem(v);
1425
Neema Shetty90189b82011-06-27 14:58:37 -07001426 if (is_voip_session(v->session_id))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001427 voice_send_netid_timing_cmd(v);
1428
1429#ifdef CONFIG_MSM8X60_RTAC
1430 rtac_add_voice(v);
1431#endif
1432
1433 return 0;
1434fail:
1435 return -EINVAL;
1436}
1437
1438static int voice_send_stop_voice_cmd(struct voice_data *v)
1439{
1440 struct apr_hdr mvm_stop_voice_cmd;
1441 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001442 void *apr_mvm = voice_get_apr_mvm();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001443 u16 mvm_handle = voice_get_mvm_handle(v);
1444
1445 mvm_stop_voice_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1446 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1447 mvm_stop_voice_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1448 sizeof(mvm_stop_voice_cmd) - APR_HDR_SIZE);
1449 pr_info("send mvm_stop_voice_cmd pkt size = %d\n",
1450 mvm_stop_voice_cmd.pkt_size);
Neema Shetty90189b82011-06-27 14:58:37 -07001451 mvm_stop_voice_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001452 mvm_stop_voice_cmd.dest_port = mvm_handle;
1453 mvm_stop_voice_cmd.token = 0;
1454 mvm_stop_voice_cmd.opcode = VSS_IMVM_CMD_STOP_VOICE;
1455
1456 v->mvm_state = CMD_STATUS_FAIL;
1457 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_stop_voice_cmd);
1458 if (ret < 0) {
1459 pr_err("Fail in sending VSS_IMVM_CMD_STOP_VOICE\n");
1460 goto fail;
1461 }
1462 ret = wait_event_timeout(v->mvm_wait,
1463 (v->mvm_state == CMD_STATUS_SUCCESS),
1464 msecs_to_jiffies(TIMEOUT_MS));
1465 if (!ret) {
1466 pr_err("%s: wait_event timeout\n", __func__);
1467 goto fail;
1468 }
1469
1470 return 0;
1471fail:
1472 return -EINVAL;
1473}
1474
1475static int voice_setup_modem_voice(struct voice_data *v)
1476{
1477 struct cvp_create_full_ctl_session_cmd cvp_session_cmd;
1478 int ret = 0;
1479 struct msm_snddev_info *dev_tx_info;
Neema Shetty90189b82011-06-27 14:58:37 -07001480 void *apr_cvp = voice_get_apr_cvp();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001481
1482 /* create cvp session and wait for response */
1483 cvp_session_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1484 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1485 cvp_session_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1486 sizeof(cvp_session_cmd) - APR_HDR_SIZE);
1487 pr_info(" send create cvp session, pkt size = %d\n",
1488 cvp_session_cmd.hdr.pkt_size);
Neema Shetty90189b82011-06-27 14:58:37 -07001489 cvp_session_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001490 cvp_session_cmd.hdr.dest_port = 0;
1491 cvp_session_cmd.hdr.token = 0;
1492 cvp_session_cmd.hdr.opcode =
1493 VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION;
1494
1495 dev_tx_info = audio_dev_ctrl_find_dev(v->dev_tx.dev_id);
1496 if (IS_ERR(dev_tx_info)) {
1497 pr_err("bad dev_id %d\n", v->dev_tx.dev_id);
1498 goto fail;
1499 }
1500
1501 /* Use default topology if invalid value in ACDB */
1502 cvp_session_cmd.cvp_session.tx_topology_id =
1503 get_voice_tx_topology();
1504 if (cvp_session_cmd.cvp_session.tx_topology_id == 0) {
1505 if (dev_tx_info->channel_mode > 1)
1506 cvp_session_cmd.cvp_session.tx_topology_id =
1507 VSS_IVOCPROC_TOPOLOGY_ID_TX_DM_FLUENCE;
1508 else
1509 cvp_session_cmd.cvp_session.tx_topology_id =
1510 VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
1511 }
1512
1513 cvp_session_cmd.cvp_session.rx_topology_id =
1514 get_voice_rx_topology();
1515 if (cvp_session_cmd.cvp_session.rx_topology_id == 0)
1516 cvp_session_cmd.cvp_session.rx_topology_id =
1517 VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
1518
1519 cvp_session_cmd.cvp_session.direction = 2; /*tx and rx*/
1520 cvp_session_cmd.cvp_session.network_id = VSS_NETWORK_ID_DEFAULT;
1521 cvp_session_cmd.cvp_session.tx_port_id = v->dev_tx.dev_port_id;
1522 cvp_session_cmd.cvp_session.rx_port_id = v->dev_rx.dev_port_id;
1523 pr_info("topology=%d net_id=%d, dir=%d tx_port_id=%d, rx_port_id=%d\n",
1524 cvp_session_cmd.cvp_session.tx_topology_id,
1525 cvp_session_cmd.cvp_session.network_id,
1526 cvp_session_cmd.cvp_session.direction,
1527 cvp_session_cmd.cvp_session.tx_port_id,
1528 cvp_session_cmd.cvp_session.rx_port_id);
1529
1530 v->cvp_state = CMD_STATUS_FAIL;
1531 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_session_cmd);
1532 if (ret < 0) {
1533 pr_err("Fail in sending VOCPROC_FULL_CONTROL_SESSION\n");
1534 goto fail;
1535 }
1536 pr_debug("wait for cvp create session event\n");
1537 ret = wait_event_timeout(v->cvp_wait,
1538 (v->cvp_state == CMD_STATUS_SUCCESS),
1539 msecs_to_jiffies(TIMEOUT_MS));
1540 if (!ret) {
1541 pr_err("%s: wait_event timeout\n", __func__);
1542 goto fail;
1543 }
1544
1545 /* send cvs cal */
1546 voice_send_cvs_cal_to_modem(v);
1547
1548 /* send cvp cal */
1549 voice_send_cvp_cal_to_modem(v);
1550
1551 /* send cvp vol table cal */
1552 voice_send_cvp_vol_tbl_to_modem(v);
1553
1554 return 0;
1555
1556fail:
1557 return -EINVAL;
1558}
1559
1560static int voice_send_enable_vocproc_cmd(struct voice_data *v)
1561{
1562 int ret = 0;
1563 struct apr_hdr cvp_enable_cmd;
1564
1565 u16 cvp_handle = voice_get_cvp_handle(v);
Neema Shetty90189b82011-06-27 14:58:37 -07001566 void *apr_cvp = voice_get_apr_cvp();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001567
1568 /* enable vocproc and wait for respose */
1569 cvp_enable_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1570 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1571 cvp_enable_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1572 sizeof(cvp_enable_cmd) - APR_HDR_SIZE);
1573 pr_debug("cvp_enable_cmd pkt size = %d, cvp_handle=%d\n",
1574 cvp_enable_cmd.pkt_size, cvp_handle);
Neema Shetty90189b82011-06-27 14:58:37 -07001575 cvp_enable_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001576 cvp_enable_cmd.dest_port = cvp_handle;
1577 cvp_enable_cmd.token = 0;
1578 cvp_enable_cmd.opcode = VSS_IVOCPROC_CMD_ENABLE;
1579
1580 v->cvp_state = CMD_STATUS_FAIL;
1581 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_enable_cmd);
1582 if (ret < 0) {
1583 pr_err("Fail in sending VSS_IVOCPROC_CMD_ENABLE\n");
1584 goto fail;
1585 }
1586 ret = wait_event_timeout(v->cvp_wait,
1587 (v->cvp_state == CMD_STATUS_SUCCESS),
1588 msecs_to_jiffies(TIMEOUT_MS));
1589 if (!ret) {
1590 pr_err("%s: wait_event timeout\n", __func__);
1591 goto fail;
1592 }
1593
1594 return 0;
1595fail:
1596 return -EINVAL;
1597}
1598
1599static int voice_send_netid_timing_cmd(struct voice_data *v)
1600{
1601 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001602 void *apr_mvm = voice_get_apr_mvm();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001603 struct mvm_set_network_cmd mvm_set_network;
1604 struct mvm_set_voice_timing_cmd mvm_set_voice_timing;
1605 u16 mvm_handle = voice_get_mvm_handle(v);
1606
1607 ret = voice_config_cvs_vocoder(v);
1608 if (ret < 0) {
1609 pr_err("%s: Error %d configuring CVS voc",
1610 __func__, ret);
1611 goto fail;
1612 }
1613 /* Set network ID. */
1614 pr_debug("%s: Setting network ID\n", __func__);
1615
1616 mvm_set_network.hdr.hdr_field =
1617 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1618 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1619 mvm_set_network.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1620 sizeof(mvm_set_network) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001621 mvm_set_network.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001622 mvm_set_network.hdr.dest_port = mvm_handle;
1623 mvm_set_network.hdr.token = 0;
1624 mvm_set_network.hdr.opcode = VSS_ICOMMON_CMD_SET_NETWORK;
Neema Shetty90189b82011-06-27 14:58:37 -07001625 mvm_set_network.network.network_id = common.mvs_info.network_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001626
1627 v->mvm_state = CMD_STATUS_FAIL;
1628 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_network);
1629 if (ret < 0) {
1630 pr_err("%s: Error %d sending SET_NETWORK\n", __func__, ret);
1631 goto fail;
1632 }
1633
1634 ret = wait_event_timeout(v->mvm_wait,
1635 (v->mvm_state == CMD_STATUS_SUCCESS),
1636 msecs_to_jiffies(TIMEOUT_MS));
1637 if (!ret) {
1638 pr_err("%s: wait_event timeout\n", __func__);
1639 goto fail;
1640 }
1641
1642 /* Set voice timing. */
1643 pr_debug("%s: Setting voice timing\n", __func__);
1644
1645 mvm_set_voice_timing.hdr.hdr_field =
1646 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1647 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1648 mvm_set_voice_timing.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1649 sizeof(mvm_set_voice_timing) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001650 mvm_set_voice_timing.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001651 mvm_set_voice_timing.hdr.dest_port = mvm_handle;
1652 mvm_set_voice_timing.hdr.token = 0;
1653 mvm_set_voice_timing.hdr.opcode =
1654 VSS_ICOMMON_CMD_SET_VOICE_TIMING;
1655 mvm_set_voice_timing.timing.mode = 0;
1656 mvm_set_voice_timing.timing.enc_offset = 8000;
1657 mvm_set_voice_timing.timing.dec_req_offset = 3300;
1658 mvm_set_voice_timing.timing.dec_offset = 8300;
1659
1660 v->mvm_state = CMD_STATUS_FAIL;
1661
1662 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_voice_timing);
1663 if (ret < 0) {
1664 pr_err("%s: Error %d sending SET_TIMING\n", __func__, ret);
1665 goto fail;
1666 }
1667
1668 ret = wait_event_timeout(v->mvm_wait,
1669 (v->mvm_state == CMD_STATUS_SUCCESS),
1670 msecs_to_jiffies(TIMEOUT_MS));
1671 if (!ret) {
1672 pr_err("%s: wait_event timeout\n", __func__);
1673 goto fail;
1674 }
1675
1676 return 0;
1677fail:
1678 return -EINVAL;
1679}
1680
1681static int voice_attach_vocproc(struct voice_data *v)
1682{
1683 int ret = 0;
1684 struct mvm_attach_vocproc_cmd mvm_a_vocproc_cmd;
Neema Shetty90189b82011-06-27 14:58:37 -07001685 void *apr_mvm = voice_get_apr_mvm();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001686 u16 mvm_handle = voice_get_mvm_handle(v);
1687 u16 cvp_handle = voice_get_cvp_handle(v);
1688
1689 /* send enable vocproc */
1690 voice_send_enable_vocproc_cmd(v);
1691
1692 /* attach vocproc and wait for response */
1693 mvm_a_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1694 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1695 mvm_a_vocproc_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1696 sizeof(mvm_a_vocproc_cmd) - APR_HDR_SIZE);
1697 pr_info("send mvm_a_vocproc_cmd pkt size = %d\n",
1698 mvm_a_vocproc_cmd.hdr.pkt_size);
Neema Shetty90189b82011-06-27 14:58:37 -07001699 mvm_a_vocproc_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001700 mvm_a_vocproc_cmd.hdr.dest_port = mvm_handle;
1701 mvm_a_vocproc_cmd.hdr.token = 0;
Neema Shetty7e4a9b52011-07-26 15:24:51 -07001702 mvm_a_vocproc_cmd.hdr.opcode = VSS_ISTREAM_CMD_ATTACH_VOCPROC;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001703 mvm_a_vocproc_cmd.mvm_attach_cvp_handle.handle = cvp_handle;
1704
1705 v->mvm_state = CMD_STATUS_FAIL;
1706 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_a_vocproc_cmd);
1707 if (ret < 0) {
Neema Shetty7e4a9b52011-07-26 15:24:51 -07001708 pr_err("Fail in sending VSS_ISTREAM_CMD_ATTACH_VOCPROC\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001709 goto fail;
1710 }
1711 ret = wait_event_timeout(v->mvm_wait,
1712 (v->mvm_state == CMD_STATUS_SUCCESS),
1713 msecs_to_jiffies(TIMEOUT_MS));
1714 if (!ret) {
1715 pr_err("%s: wait_event timeout\n", __func__);
1716 goto fail;
1717 }
1718
1719 /* send tty mode if tty device is used */
1720 voice_send_tty_mode_to_modem(v);
1721
Neema Shetty90189b82011-06-27 14:58:37 -07001722 if (is_voip_session(v->session_id))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001723 voice_send_netid_timing_cmd(v);
1724
1725#ifdef CONFIG_MSM8X60_RTAC
1726 rtac_add_voice(v);
1727#endif
1728 return 0;
1729fail:
1730 return -EINVAL;
1731}
1732
1733static int voice_destroy_modem_voice(struct voice_data *v)
1734{
1735 struct mvm_detach_vocproc_cmd mvm_d_vocproc_cmd;
1736 struct apr_hdr cvp_destroy_session_cmd;
1737 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001738 void *apr_mvm = voice_get_apr_mvm();
1739 void *apr_cvp = voice_get_apr_cvp();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001740 u16 mvm_handle = voice_get_mvm_handle(v);
1741 u16 cvp_handle = voice_get_cvp_handle(v);
1742
1743 /* detach VOCPROC and wait for response from mvm */
1744 mvm_d_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1745 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1746 mvm_d_vocproc_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1747 sizeof(mvm_d_vocproc_cmd) - APR_HDR_SIZE);
1748 pr_info("mvm_d_vocproc_cmd pkt size = %d\n",
1749 mvm_d_vocproc_cmd.hdr.pkt_size);
Neema Shetty90189b82011-06-27 14:58:37 -07001750 mvm_d_vocproc_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001751 mvm_d_vocproc_cmd.hdr.dest_port = mvm_handle;
1752 mvm_d_vocproc_cmd.hdr.token = 0;
Neema Shetty7e4a9b52011-07-26 15:24:51 -07001753 mvm_d_vocproc_cmd.hdr.opcode = VSS_ISTREAM_CMD_DETACH_VOCPROC;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001754 mvm_d_vocproc_cmd.mvm_detach_cvp_handle.handle = cvp_handle;
1755
1756 v->mvm_state = CMD_STATUS_FAIL;
1757 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_d_vocproc_cmd);
1758 if (ret < 0) {
Neema Shetty7e4a9b52011-07-26 15:24:51 -07001759 pr_err("Fail in sending VSS_ISTREAM_CMD_DETACH_VOCPROC\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001760 goto fail;
1761 }
1762 ret = wait_event_timeout(v->mvm_wait,
1763 (v->mvm_state == CMD_STATUS_SUCCESS),
1764 msecs_to_jiffies(TIMEOUT_MS));
1765 if (!ret) {
1766 pr_err("%s: wait_event timeout\n", __func__);
1767 goto fail;
1768 }
1769
1770 /* destrop cvp session */
1771 cvp_destroy_session_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1772 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1773 cvp_destroy_session_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1774 sizeof(cvp_destroy_session_cmd) - APR_HDR_SIZE);
1775 pr_info("cvp_destroy_session_cmd pkt size = %d\n",
1776 cvp_destroy_session_cmd.pkt_size);
Neema Shetty90189b82011-06-27 14:58:37 -07001777 cvp_destroy_session_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001778 cvp_destroy_session_cmd.dest_port = cvp_handle;
1779 cvp_destroy_session_cmd.token = 0;
1780 cvp_destroy_session_cmd.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
1781
1782 v->cvp_state = CMD_STATUS_FAIL;
1783 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_destroy_session_cmd);
1784 if (ret < 0) {
1785 pr_err("Fail in sending APRV2_IBASIC_CMD_DESTROY_SESSION\n");
1786 goto fail;
1787 }
1788 ret = wait_event_timeout(v->cvp_wait,
1789 (v->cvp_state == CMD_STATUS_SUCCESS),
1790 msecs_to_jiffies(TIMEOUT_MS));
1791 if (!ret) {
1792 pr_err("%s: wait_event timeout\n", __func__);
1793 goto fail;
1794 }
1795
1796#ifdef CONFIG_MSM8X60_RTAC
1797 rtac_remove_voice(v);
1798#endif
1799 cvp_handle = 0;
1800 voice_set_cvp_handle(v, cvp_handle);
1801
1802 return 0;
1803
1804fail:
1805 return -EINVAL;
1806}
1807
1808static int voice_send_mute_cmd_to_modem(struct voice_data *v)
1809{
1810 struct cvs_set_mute_cmd cvs_mute_cmd;
1811 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001812 void *apr_cvs = voice_get_apr_cvs();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001813 u16 cvs_handle = voice_get_cvs_handle(v);
1814
1815 /* send mute/unmute to cvs */
1816 cvs_mute_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1817 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1818 cvs_mute_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1819 sizeof(cvs_mute_cmd) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001820 cvs_mute_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001821 cvs_mute_cmd.hdr.dest_port = cvs_handle;
1822 cvs_mute_cmd.hdr.token = 0;
1823 cvs_mute_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_MUTE;
1824 cvs_mute_cmd.cvs_set_mute.direction = 0; /*tx*/
1825 cvs_mute_cmd.cvs_set_mute.mute_flag = v->dev_tx.mute;
1826
1827 pr_info(" mute value =%d\n", cvs_mute_cmd.cvs_set_mute.mute_flag);
1828 v->cvs_state = CMD_STATUS_FAIL;
1829 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_mute_cmd);
1830 if (ret < 0) {
1831 pr_err("Fail: send STREAM SET MUTE\n");
1832 goto fail;
1833 }
1834 ret = wait_event_timeout(v->cvs_wait,
1835 (v->cvs_state == CMD_STATUS_SUCCESS),
1836 msecs_to_jiffies(TIMEOUT_MS));
1837 if (!ret)
1838 pr_err("%s: wait_event timeout\n", __func__);
1839
1840fail:
1841 return 0;
1842}
1843
1844static int voice_send_vol_index_to_modem(struct voice_data *v)
1845{
1846 struct cvp_set_rx_volume_index_cmd cvp_vol_cmd;
1847 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001848 void *apr_cvp = voice_get_apr_cvp();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001849 u16 cvp_handle = voice_get_cvp_handle(v);
1850
1851 /* send volume index to cvp */
1852 cvp_vol_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1853 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1854 cvp_vol_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1855 sizeof(cvp_vol_cmd) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001856 cvp_vol_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001857 cvp_vol_cmd.hdr.dest_port = cvp_handle;
1858 cvp_vol_cmd.hdr.token = 0;
1859 cvp_vol_cmd.hdr.opcode =
1860 VSS_IVOCPROC_CMD_SET_RX_VOLUME_INDEX;
1861 cvp_vol_cmd.cvp_set_vol_idx.vol_index = v->dev_rx.volume;
1862 v->cvp_state = CMD_STATUS_FAIL;
1863 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_vol_cmd);
1864 if (ret < 0) {
1865 pr_err("Fail in sending RX VOL INDEX\n");
1866 return -EINVAL;
1867 }
1868 ret = wait_event_timeout(v->cvp_wait,
1869 (v->cvp_state == CMD_STATUS_SUCCESS),
1870 msecs_to_jiffies(TIMEOUT_MS));
1871 if (!ret) {
1872 pr_err("%s: wait_event timeout\n", __func__);
1873 return -EINVAL;
1874 }
1875 return 0;
1876}
1877
1878static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode)
1879{
1880 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001881 void *apr_cvs = voice_get_apr_cvs();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001882 u16 cvs_handle = voice_get_cvs_handle(v);
1883 struct cvs_start_record_cmd cvs_start_record;
1884
1885 pr_debug("%s: Start record %d\n", __func__, rec_mode);
1886
1887 cvs_start_record.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1888 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1889 cvs_start_record.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1890 sizeof(cvs_start_record) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001891 cvs_start_record.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001892 cvs_start_record.hdr.dest_port = cvs_handle;
1893 cvs_start_record.hdr.token = 0;
1894 cvs_start_record.hdr.opcode = VSS_ISTREAM_CMD_START_RECORD;
1895
1896 if (rec_mode == VOC_REC_UPLINK) {
1897 cvs_start_record.rec_mode.rx_tap_point = VSS_TAP_POINT_NONE;
1898 cvs_start_record.rec_mode.tx_tap_point =
1899 VSS_TAP_POINT_STREAM_END;
1900 } else if (rec_mode == VOC_REC_DOWNLINK) {
1901 cvs_start_record.rec_mode.rx_tap_point =
1902 VSS_TAP_POINT_STREAM_END;
1903 cvs_start_record.rec_mode.tx_tap_point = VSS_TAP_POINT_NONE;
1904 } else if (rec_mode == VOC_REC_BOTH) {
1905 cvs_start_record.rec_mode.rx_tap_point =
1906 VSS_TAP_POINT_STREAM_END;
1907 cvs_start_record.rec_mode.tx_tap_point =
1908 VSS_TAP_POINT_STREAM_END;
1909 } else {
1910 pr_err("%s: Invalid in-call rec_mode %d\n", __func__, rec_mode);
1911
1912 ret = -EINVAL;
1913 goto fail;
1914 }
1915
1916 v->cvs_state = CMD_STATUS_FAIL;
1917
1918 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_start_record);
1919 if (ret < 0) {
1920 pr_err("%s: Error %d sending START_RECORD\n", __func__, ret);
1921
1922 goto fail;
1923 }
1924
1925 ret = wait_event_timeout(v->cvs_wait,
1926 (v->cvs_state == CMD_STATUS_SUCCESS),
1927 msecs_to_jiffies(TIMEOUT_MS));
1928 if (!ret) {
1929 pr_err("%s: wait_event timeout\n", __func__);
1930
1931 goto fail;
1932 }
1933
1934 return 0;
1935
1936fail:
1937 return ret;
1938}
1939
1940static int voice_cvs_stop_record(struct voice_data *v)
1941{
1942 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001943 void *apr_cvs = voice_get_apr_cvs();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001944 u16 cvs_handle = voice_get_cvs_handle(v);
1945 struct apr_hdr cvs_stop_record;
1946
1947 pr_debug("%s: Stop record\n", __func__);
1948
1949 cvs_stop_record.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1950 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1951 cvs_stop_record.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1952 sizeof(cvs_stop_record) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001953 cvs_stop_record.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001954 cvs_stop_record.dest_port = cvs_handle;
1955 cvs_stop_record.token = 0;
1956 cvs_stop_record.opcode = VSS_ISTREAM_CMD_STOP_RECORD;
1957
1958 v->cvs_state = CMD_STATUS_FAIL;
1959
1960 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_stop_record);
1961 if (ret < 0) {
1962 pr_err("%s: Error %d sending STOP_RECORD\n", __func__, ret);
1963
1964 goto fail;
1965 }
1966
1967 ret = wait_event_timeout(v->cvs_wait,
1968 (v->cvs_state == CMD_STATUS_SUCCESS),
1969 msecs_to_jiffies(TIMEOUT_MS));
1970 if (!ret) {
1971 pr_err("%s: wait_event timeout\n", __func__);
1972
1973 goto fail;
1974 }
1975
1976 return 0;
1977
1978fail:
1979 return ret;
1980}
1981
1982int voice_start_record(uint32_t rec_mode, uint32_t set)
1983{
Neema Shetty90189b82011-06-27 14:58:37 -07001984 int ret = 0, i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001985 u16 cvs_handle;
1986
1987 pr_debug("%s: rec_mode %d, set %d\n", __func__, rec_mode, set);
1988
Neema Shetty90189b82011-06-27 14:58:37 -07001989 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
1990 struct voice_data *v = &common.voice[i];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001991
Neema Shetty90189b82011-06-27 14:58:37 -07001992 mutex_lock(&v->lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001993
Neema Shetty90189b82011-06-27 14:58:37 -07001994 cvs_handle = voice_get_cvs_handle(v);
1995
1996 if (cvs_handle != 0) {
1997 if (set)
1998 ret = voice_cvs_start_record(v, rec_mode);
1999 else
2000 ret = voice_cvs_stop_record(v);
2001 } else {
2002 /* Cache the value for later. */
2003 v->rec_info.pending = set;
2004 v->rec_info.rec_mode = rec_mode;
2005 }
2006
2007 mutex_unlock(&v->lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002008 }
2009
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002010 return ret;
2011}
2012
2013static int voice_cvs_start_playback(struct voice_data *v)
2014{
2015 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07002016 void *apr_cvs = voice_get_apr_cvs();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002017 u16 cvs_handle = voice_get_cvs_handle(v);
2018 struct apr_hdr cvs_start_playback;
2019
2020 pr_debug("%s: Start playback\n", __func__);
2021
2022 cvs_start_playback.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2023 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2024 cvs_start_playback.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2025 sizeof(cvs_start_playback) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07002026 cvs_start_playback.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002027 cvs_start_playback.dest_port = cvs_handle;
2028 cvs_start_playback.token = 0;
2029 cvs_start_playback.opcode = VSS_ISTREAM_CMD_START_PLAYBACK;
2030
2031 v->cvs_state = CMD_STATUS_FAIL;
2032
2033 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_start_playback);
2034 if (ret < 0) {
2035 pr_err("%s: Error %d sending START_PLAYBACK\n",
2036 __func__, ret);
2037
2038 goto fail;
2039 }
2040
2041 ret = wait_event_timeout(v->cvs_wait,
2042 (v->cvs_state == CMD_STATUS_SUCCESS),
2043 msecs_to_jiffies(TIMEOUT_MS));
2044 if (!ret) {
2045 pr_err("%s: wait_event timeout\n", __func__);
2046
2047 goto fail;
2048 }
2049
2050 v->music_info.playing = 1;
2051
2052 return 0;
2053
2054fail:
2055 return ret;
2056}
2057
2058static int voice_cvs_stop_playback(struct voice_data *v)
2059{
2060 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07002061 void *apr_cvs = voice_get_apr_cvs();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002062 u16 cvs_handle = voice_get_cvs_handle(v);
2063 struct apr_hdr cvs_stop_playback;
2064
2065 pr_debug("%s: Stop playback\n", __func__);
2066
2067 if (v->music_info.playing) {
2068 cvs_stop_playback.hdr_field =
2069 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2070 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2071 cvs_stop_playback.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2072 sizeof(cvs_stop_playback) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07002073 cvs_stop_playback.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002074 cvs_stop_playback.dest_port = cvs_handle;
2075 cvs_stop_playback.token = 0;
2076
2077 cvs_stop_playback.opcode = VSS_ISTREAM_CMD_STOP_PLAYBACK;
2078
2079 v->cvs_state = CMD_STATUS_FAIL;
2080
2081 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_stop_playback);
2082 if (ret < 0) {
2083 pr_err("%s: Error %d sending STOP_PLAYBACK\n",
2084 __func__, ret);
2085
2086 goto fail;
2087 }
2088
2089 ret = wait_event_timeout(v->cvs_wait,
2090 (v->cvs_state == CMD_STATUS_SUCCESS),
2091 msecs_to_jiffies(TIMEOUT_MS));
2092 if (!ret) {
2093 pr_err("%s: wait_event timeout\n", __func__);
2094
2095 goto fail;
2096 }
2097
2098 v->music_info.playing = 0;
2099 } else {
2100 pr_err("%s: Stop playback already sent\n", __func__);
2101 }
2102
2103 return 0;
2104
2105fail:
2106 return ret;
2107}
2108
2109int voice_start_playback(uint32_t set)
2110{
Neema Shetty90189b82011-06-27 14:58:37 -07002111 int ret = 0, i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002112 u16 cvs_handle;
2113
2114 pr_debug("%s: Start playback %d\n", __func__, set);
2115
Neema Shetty90189b82011-06-27 14:58:37 -07002116 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
2117 struct voice_data *v = &common.voice[i];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002118
Neema Shetty90189b82011-06-27 14:58:37 -07002119 mutex_lock(&v->lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002120
Neema Shetty90189b82011-06-27 14:58:37 -07002121 cvs_handle = voice_get_cvs_handle(v);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002122
Neema Shetty90189b82011-06-27 14:58:37 -07002123 if (cvs_handle != 0) {
2124 if (set)
2125 ret = voice_cvs_start_playback(v);
2126 else
2127 ret = voice_cvs_stop_playback(v);
2128 } else {
2129 /* Cache the value for later. */
2130 pr_debug("%s: Caching ICP value", __func__);
2131
2132 v->music_info.pending = set;
2133 }
2134
2135 mutex_unlock(&v->lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002136 }
2137
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002138 return ret;
2139}
2140
2141static void voice_auddev_cb_function(u32 evt_id,
2142 union auddev_evt_data *evt_payload,
2143 void *private_data)
2144{
Neema Shetty90189b82011-06-27 14:58:37 -07002145 struct common_data *c = private_data;
2146 struct voice_data *v = NULL;
2147
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002148 struct sidetone_cal sidetone_cal_data;
Neema Shetty90189b82011-06-27 14:58:37 -07002149 int rc = 0, i = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002150 pr_info("auddev_cb_function, evt_id=%d,\n", evt_id);
Neema Shetty90189b82011-06-27 14:58:37 -07002151
2152 if (evt_payload == NULL) {
2153 pr_err("%s: evt_payload is NULL pointer\n", __func__);
2154 return;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002155 }
2156
2157 switch (evt_id) {
2158 case AUDDEV_EVT_START_VOICE:
Neema Shetty90189b82011-06-27 14:58:37 -07002159 v = voice_get_session(evt_payload->voice_session_id);
2160 if (v == NULL) {
2161 pr_err("%s: v is NULL\n", __func__);
2162 return;
2163 }
2164
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002165 mutex_lock(&v->lock);
2166
2167 if ((v->voc_state == VOC_INIT) ||
2168 (v->voc_state == VOC_RELEASE)) {
2169 v->v_call_status = VOICE_CALL_START;
2170 if ((v->dev_rx.enabled == VOICE_DEV_ENABLED)
2171 && (v->dev_tx.enabled == VOICE_DEV_ENABLED)) {
Neema Shetty90189b82011-06-27 14:58:37 -07002172 rc = voice_apr_register();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002173 if (rc < 0) {
2174 pr_err("%s: voice apr registration"
2175 "failed\n", __func__);
2176 mutex_unlock(&v->lock);
2177 return;
2178 }
2179 voice_create_mvm_cvs_session(v);
2180 voice_setup_modem_voice(v);
2181 voice_attach_vocproc(v);
2182 voice_send_start_voice_cmd(v);
2183 get_sidetone_cal(&sidetone_cal_data);
2184 msm_snddev_enable_sidetone(
2185 v->dev_rx.dev_id,
2186 sidetone_cal_data.enable,
2187 sidetone_cal_data.gain);
2188 v->voc_state = VOC_RUN;
2189
2190 /* Start in-call recording if command was
2191 * pending. */
2192 if (v->rec_info.pending) {
2193 voice_cvs_start_record(v,
2194 v->rec_info.rec_mode);
2195
2196 v->rec_info.pending = 0;
2197 }
2198
2199 /* Start in-call music delivery if command was
2200 * pending. */
2201 if (v->music_info.pending) {
2202 voice_cvs_start_playback(v);
2203
2204 v->music_info.pending = 0;
2205 }
2206 }
2207 }
2208
2209 mutex_unlock(&v->lock);
2210 break;
2211 case AUDDEV_EVT_DEV_CHG_VOICE:
Neema Shetty90189b82011-06-27 14:58:37 -07002212 /* Device change is applicable to all sessions. */
2213 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
2214 v = &c->voice[i];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002215
Neema Shetty90189b82011-06-27 14:58:37 -07002216 if (v->dev_rx.enabled == VOICE_DEV_ENABLED)
2217 msm_snddev_enable_sidetone(v->dev_rx.dev_id,
2218 0, 0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002219
Neema Shetty90189b82011-06-27 14:58:37 -07002220 v->dev_rx.enabled = VOICE_DEV_DISABLED;
2221 v->dev_tx.enabled = VOICE_DEV_DISABLED;
2222
2223 mutex_lock(&v->lock);
2224
2225 if (v->voc_state == VOC_RUN) {
2226 /* send cmd to modem to do voice device
2227 * change */
2228 voice_disable_vocproc(v);
2229 v->voc_state = VOC_CHANGE;
2230 }
2231
2232 mutex_unlock(&v->lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002233 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002234 break;
2235 case AUDDEV_EVT_DEV_RDY:
Neema Shetty90189b82011-06-27 14:58:37 -07002236 /* Device change is applicable to all sessions. */
2237 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
2238 v = &c->voice[i];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002239
Neema Shetty90189b82011-06-27 14:58:37 -07002240 mutex_lock(&v->lock);
2241
2242 if (v->voc_state == VOC_CHANGE) {
2243 /* get port Ids */
2244 if (evt_payload->voc_devinfo.dev_type ==
2245 DIR_RX) {
2246 v->dev_rx.dev_port_id =
2247 evt_payload->voc_devinfo.dev_port_id;
2248 v->dev_rx.sample =
2249 evt_payload->voc_devinfo.dev_sample;
2250 v->dev_rx.dev_id =
2251 evt_payload->voc_devinfo.dev_id;
2252 v->dev_rx.enabled = VOICE_DEV_ENABLED;
2253 } else {
2254 v->dev_tx.dev_port_id =
2255 evt_payload->voc_devinfo.dev_port_id;
2256 v->dev_tx.sample =
2257 evt_payload->voc_devinfo.dev_sample;
2258 v->dev_tx.enabled = VOICE_DEV_ENABLED;
2259 v->dev_tx.dev_id =
2260 evt_payload->voc_devinfo.dev_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002261 }
Neema Shetty90189b82011-06-27 14:58:37 -07002262 if ((v->dev_rx.enabled == VOICE_DEV_ENABLED) &&
2263 (v->dev_tx.enabled == VOICE_DEV_ENABLED)) {
2264 voice_set_device(v);
2265 get_sidetone_cal(&sidetone_cal_data);
2266 msm_snddev_enable_sidetone(
2267 v->dev_rx.dev_id,
2268 sidetone_cal_data.enable,
2269 sidetone_cal_data.gain);
2270 v->voc_state = VOC_RUN;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002271 }
Neema Shetty90189b82011-06-27 14:58:37 -07002272 } else if ((v->voc_state == VOC_INIT) ||
2273 (v->voc_state == VOC_RELEASE)) {
2274 /* get AFE ports */
2275 if (evt_payload->voc_devinfo.dev_type ==
2276 DIR_RX) {
2277 /* get rx port id */
2278 v->dev_rx.dev_port_id =
2279 evt_payload->voc_devinfo.dev_port_id;
2280 v->dev_rx.sample =
2281 evt_payload->voc_devinfo.dev_sample;
2282 v->dev_rx.dev_id =
2283 evt_payload->voc_devinfo.dev_id;
2284 v->dev_rx.enabled = VOICE_DEV_ENABLED;
2285 } else {
2286 /* get tx port id */
2287 v->dev_tx.dev_port_id =
2288 evt_payload->voc_devinfo.dev_port_id;
2289 v->dev_tx.sample =
2290 evt_payload->voc_devinfo.dev_sample;
2291 v->dev_tx.dev_id =
2292 evt_payload->voc_devinfo.dev_id;
2293 v->dev_tx.enabled = VOICE_DEV_ENABLED;
2294 }
2295 if ((v->dev_rx.enabled == VOICE_DEV_ENABLED) &&
2296 (v->dev_tx.enabled == VOICE_DEV_ENABLED) &&
2297 (v->v_call_status == VOICE_CALL_START)) {
2298 rc = voice_apr_register();
2299 if (rc < 0) {
2300 pr_err("%s: voice apr"
2301 "registration failed\n",
2302 __func__);
2303 mutex_unlock(&v->lock);
2304 return;
2305 }
2306 voice_create_mvm_cvs_session(v);
2307 voice_setup_modem_voice(v);
2308 voice_attach_vocproc(v);
2309 voice_send_start_voice_cmd(v);
2310 get_sidetone_cal(&sidetone_cal_data);
2311 msm_snddev_enable_sidetone(
2312 v->dev_rx.dev_id,
2313 sidetone_cal_data.enable,
2314 sidetone_cal_data.gain);
2315 v->voc_state = VOC_RUN;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002316
Neema Shetty90189b82011-06-27 14:58:37 -07002317 /* Start in-call recording if command
2318 * was pending. */
2319 if (v->rec_info.pending) {
2320 voice_cvs_start_record(v,
2321 v->rec_info.rec_mode);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002322
Neema Shetty90189b82011-06-27 14:58:37 -07002323 v->rec_info.pending = 0;
2324 }
2325
2326 /* Start in-call music delivery if
2327 * command was pending. */
2328 if (v->music_info.pending) {
2329 voice_cvs_start_playback(v);
2330
2331 v->music_info.pending = 0;
2332 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002333 }
2334 }
Neema Shetty90189b82011-06-27 14:58:37 -07002335
2336 mutex_unlock(&v->lock);
2337 }
2338 break;
2339 case AUDDEV_EVT_DEVICE_VOL_MUTE_CHG:
2340 v = voice_get_session(
2341 evt_payload->voc_vm_info.voice_session_id);
2342 if (v == NULL) {
2343 pr_err("%s: v is NULL\n", __func__);
2344 return;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002345 }
2346
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002347 /* cache the mute and volume index value */
Neema Shetty90189b82011-06-27 14:58:37 -07002348 if (evt_payload->voc_vm_info.dev_type == DIR_TX) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002349 v->dev_tx.mute =
2350 evt_payload->voc_vm_info.dev_vm_val.mute;
2351
2352 mutex_lock(&v->lock);
2353
2354 if (v->voc_state == VOC_RUN)
2355 voice_send_mute_cmd_to_modem(v);
2356
2357 mutex_unlock(&v->lock);
2358 } else {
Neema Shetty90189b82011-06-27 14:58:37 -07002359 v->dev_rx.volume =
2360 evt_payload->voc_vm_info.dev_vm_val.vol;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002361
2362 mutex_lock(&v->lock);
2363
2364 if (v->voc_state == VOC_RUN)
2365 voice_send_vol_index_to_modem(v);
2366
2367 mutex_unlock(&v->lock);
2368 }
2369 break;
2370 case AUDDEV_EVT_REL_PENDING:
Neema Shetty90189b82011-06-27 14:58:37 -07002371 /* Device change is applicable to all sessions. */
2372 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
2373 v = &c->voice[i];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002374
Neema Shetty90189b82011-06-27 14:58:37 -07002375 mutex_lock(&v->lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002376
Neema Shetty90189b82011-06-27 14:58:37 -07002377 if (v->voc_state == VOC_RUN) {
2378 voice_disable_vocproc(v);
2379 v->voc_state = VOC_CHANGE;
2380 }
2381
2382 mutex_unlock(&v->lock);
2383
2384 if (evt_payload->voc_devinfo.dev_type == DIR_RX)
2385 v->dev_rx.enabled = VOICE_DEV_DISABLED;
2386 else
2387 v->dev_tx.enabled = VOICE_DEV_DISABLED;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002388 }
2389
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002390 break;
2391 case AUDDEV_EVT_END_VOICE:
Neema Shetty90189b82011-06-27 14:58:37 -07002392 v = voice_get_session(evt_payload->voice_session_id);
2393 if (v == NULL) {
2394 pr_err("%s: v is NULL\n", __func__);
2395 return;
2396 }
2397
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002398 /* recover the tx mute and rx volume to the default values */
Neema Shetty90189b82011-06-27 14:58:37 -07002399 v->dev_tx.mute = c->default_mute_val;
2400 v->dev_rx.volume = c->default_vol_val;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002401 if (v->dev_rx.enabled == VOICE_DEV_ENABLED)
2402 msm_snddev_enable_sidetone(v->dev_rx.dev_id, 0, 0);
2403
2404 mutex_lock(&v->lock);
2405
2406 if (v->voc_state == VOC_RUN) {
2407 /* call stop modem voice */
2408 voice_send_stop_voice_cmd(v);
2409 voice_destroy_modem_voice(v);
2410 voice_destroy_mvm_cvs_session(v);
2411 v->voc_state = VOC_RELEASE;
2412 } else if (v->voc_state == VOC_CHANGE) {
2413 voice_send_stop_voice_cmd(v);
2414 voice_destroy_mvm_cvs_session(v);
2415 v->voc_state = VOC_RELEASE;
2416 }
2417
2418 mutex_unlock(&v->lock);
2419
2420 v->v_call_status = VOICE_CALL_END;
2421
2422 break;
2423 default:
2424 pr_err("UNKNOWN EVENT\n");
2425 }
2426 return;
2427}
2428EXPORT_SYMBOL(voice_auddev_cb_function);
2429
2430int voice_set_voc_path_full(uint32_t set)
2431{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002432 pr_info("%s: %d\n", __func__, set);
2433
Neema Shetty90189b82011-06-27 14:58:37 -07002434 mutex_lock(&common.common_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002435
Neema Shetty90189b82011-06-27 14:58:37 -07002436 if (set)
2437 common.voc_path = VOC_PATH_FULL;
2438 else
2439 common.voc_path = VOC_PATH_PASSIVE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002440
Neema Shetty90189b82011-06-27 14:58:37 -07002441 mutex_unlock(&common.common_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002442
Neema Shetty90189b82011-06-27 14:58:37 -07002443 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002444}
2445EXPORT_SYMBOL(voice_set_voc_path_full);
2446
2447void voice_register_mvs_cb(ul_cb_fn ul_cb,
2448 dl_cb_fn dl_cb,
2449 void *private_data)
2450{
Neema Shetty90189b82011-06-27 14:58:37 -07002451 common.mvs_info.ul_cb = ul_cb;
2452 common.mvs_info.dl_cb = dl_cb;
2453 common.mvs_info.private_data = private_data;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002454}
2455
2456void voice_config_vocoder(uint32_t media_type,
2457 uint32_t rate,
2458 uint32_t network_type,
2459 uint32_t dtx_mode)
2460{
Neema Shetty90189b82011-06-27 14:58:37 -07002461 common.mvs_info.media_type = media_type;
2462 common.mvs_info.rate = rate;
2463 common.mvs_info.network_type = network_type;
2464 common.mvs_info.dtx_mode = dtx_mode;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002465}
2466
2467static int32_t modem_mvm_callback(struct apr_client_data *data, void *priv)
2468{
2469 uint32_t *ptr;
Neema Shetty90189b82011-06-27 14:58:37 -07002470 struct common_data *c = priv;
2471 struct voice_data *v = NULL;
2472 int i = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002473
Neema Shetty90189b82011-06-27 14:58:37 -07002474 pr_debug("%s: session_id 0x%x\n", __func__, data->dest_port);
2475
2476 v = voice_get_session(data->dest_port);
2477 if (v == NULL) {
2478 pr_err("%s: v is NULL\n", __func__);
2479 return -EINVAL;
2480 }
2481
2482 pr_debug("%s: common data 0x%x, session 0x%x\n",
2483 __func__, (unsigned int)c, (unsigned int)v);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002484 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
2485 data->payload_size, data->opcode);
2486
2487 if (data->opcode == RESET_EVENTS) {
2488 pr_debug("%s:Reset event received in Voice service\n",
2489 __func__);
Neema Shetty90189b82011-06-27 14:58:37 -07002490 apr_reset(c->apr_mvm);
2491 c->apr_mvm = NULL;
2492 apr_reset(c->apr_q6_mvm);
2493 c->apr_q6_mvm = NULL;
2494
2495 /* Sub-system restart is applicable to all sessions. */
2496 for (i = 0; i < MAX_VOC_SESSIONS; i++)
2497 c->voice[i].mvm_handle = 0;
2498
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002499 return 0;
2500 }
2501
2502 if (data->opcode == APR_BASIC_RSP_RESULT) {
2503 if (data->payload_size) {
2504 ptr = data->payload;
2505
2506 pr_info("%x %x\n", ptr[0], ptr[1]);
2507 /* ping mvm service ACK */
2508
2509 if (ptr[0] ==
2510 VSS_IMVM_CMD_CREATE_PASSIVE_CONTROL_SESSION ||
2511 ptr[0] ==
2512 VSS_IMVM_CMD_CREATE_FULL_CONTROL_SESSION) {
2513 /* Passive session is used for voice call
2514 * through modem. Full session is used for voice
2515 * call through Q6. */
2516 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2517 if (!ptr[1]) {
2518 pr_debug("%s: MVM handle is %d\n",
2519 __func__, data->src_port);
2520
2521 voice_set_mvm_handle(v, data->src_port);
2522 } else
2523 pr_info("got NACK for sending \
2524 MVM create session \n");
2525 v->mvm_state = CMD_STATUS_SUCCESS;
2526 wake_up(&v->mvm_wait);
2527 } else if (ptr[0] == VSS_IMVM_CMD_START_VOICE) {
2528 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2529 v->mvm_state = CMD_STATUS_SUCCESS;
2530 wake_up(&v->mvm_wait);
Neema Shetty7e4a9b52011-07-26 15:24:51 -07002531 } else if (ptr[0] == VSS_ISTREAM_CMD_ATTACH_VOCPROC) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002532 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2533 v->mvm_state = CMD_STATUS_SUCCESS;
2534 wake_up(&v->mvm_wait);
2535 } else if (ptr[0] == VSS_IMVM_CMD_STOP_VOICE) {
2536 v->mvm_state = CMD_STATUS_SUCCESS;
2537 wake_up(&v->mvm_wait);
Neema Shetty7e4a9b52011-07-26 15:24:51 -07002538 } else if (ptr[0] == VSS_ISTREAM_CMD_DETACH_VOCPROC) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002539 v->mvm_state = CMD_STATUS_SUCCESS;
2540 wake_up(&v->mvm_wait);
2541 } else if (ptr[0] == VSS_ISTREAM_CMD_SET_TTY_MODE) {
2542 v->mvm_state = CMD_STATUS_SUCCESS;
2543 wake_up(&v->mvm_wait);
2544 } else if (ptr[0] == APRV2_IBASIC_CMD_DESTROY_SESSION) {
2545 pr_debug("%s: DESTROY resp\n", __func__);
2546
2547 v->mvm_state = CMD_STATUS_SUCCESS;
2548 wake_up(&v->mvm_wait);
2549 } else if (ptr[0] == VSS_IMVM_CMD_ATTACH_STREAM) {
2550 pr_debug("%s: ATTACH_STREAM resp 0x%x\n",
2551 __func__, ptr[1]);
2552
2553 v->mvm_state = CMD_STATUS_SUCCESS;
2554 wake_up(&v->mvm_wait);
2555 } else if (ptr[0] == VSS_IMVM_CMD_DETACH_STREAM) {
2556 pr_debug("%s: DETACH_STREAM resp 0x%x\n",
2557 __func__, ptr[1]);
2558
2559 v->mvm_state = CMD_STATUS_SUCCESS;
2560 wake_up(&v->mvm_wait);
2561 } else if (ptr[0] == VSS_ICOMMON_CMD_SET_NETWORK) {
2562 pr_debug("%s: SET_NETWORK resp 0x%x\n",
2563 __func__, ptr[1]);
2564
2565 v->mvm_state = CMD_STATUS_SUCCESS;
2566 wake_up(&v->mvm_wait);
2567 } else if (ptr[0] == VSS_ICOMMON_CMD_SET_VOICE_TIMING) {
2568 pr_debug("%s: SET_VOICE_TIMING resp 0x%x\n",
2569 __func__, ptr[1]);
2570
2571 v->mvm_state = CMD_STATUS_SUCCESS;
2572 wake_up(&v->mvm_wait);
2573 } else
2574 pr_debug("%s: not match cmd = 0x%x\n",
2575 __func__, ptr[0]);
2576 }
2577 }
2578
2579 return 0;
2580}
2581
2582static int32_t modem_cvs_callback(struct apr_client_data *data, void *priv)
2583{
2584 uint32_t *ptr;
Neema Shetty90189b82011-06-27 14:58:37 -07002585 struct common_data *c = priv;
2586 struct voice_data *v = NULL;
2587 int i = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002588
Neema Shetty90189b82011-06-27 14:58:37 -07002589 pr_debug("%s: session_id 0x%x\n", __func__, data->dest_port);
2590
2591 v = voice_get_session(data->dest_port);
2592 if (v == NULL) {
2593 pr_err("%s: v is NULL\n", __func__);
2594 return -EINVAL;
2595 }
2596
2597 pr_debug("%s: common data 0x%x, session 0x%x\n",
2598 __func__, (unsigned int)c, (unsigned int)v);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002599 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
2600 data->payload_size, data->opcode);
2601
2602 if (data->opcode == RESET_EVENTS) {
2603 pr_debug("%s:Reset event received in Voice service\n",
2604 __func__);
Neema Shetty90189b82011-06-27 14:58:37 -07002605 apr_reset(c->apr_cvs);
2606 c->apr_cvs = NULL;
2607 apr_reset(c->apr_q6_cvs);
2608 c->apr_q6_cvs = NULL;
2609
2610 /* Sub-system restart is applicable to all sessions. */
2611 for (i = 0; i < MAX_VOC_SESSIONS; i++)
2612 c->voice[i].cvs_handle = 0;
2613
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002614 return 0;
2615 }
2616
2617 if (data->opcode == APR_BASIC_RSP_RESULT) {
2618 if (data->payload_size) {
2619 ptr = data->payload;
2620
2621 pr_info("%x %x\n", ptr[0], ptr[1]);
2622 /*response from modem CVS */
2623 if (ptr[0] ==
2624 VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION ||
2625 ptr[0] ==
2626 VSS_ISTREAM_CMD_CREATE_FULL_CONTROL_SESSION) {
2627 if (!ptr[1]) {
2628 pr_debug("%s: CVS handle is %d\n",
2629 __func__, data->src_port);
2630 voice_set_cvs_handle(v, data->src_port);
2631 } else
2632 pr_info("got NACK for sending \
2633 CVS create session \n");
2634 v->cvs_state = CMD_STATUS_SUCCESS;
2635 wake_up(&v->cvs_wait);
2636 } else if (ptr[0] ==
2637 VSS_ISTREAM_CMD_CACHE_CALIBRATION_DATA) {
2638 v->cvs_state = CMD_STATUS_SUCCESS;
2639 wake_up(&v->cvs_wait);
2640 } else if (ptr[0] ==
2641 VSS_ISTREAM_CMD_SET_MUTE) {
2642 v->cvs_state = CMD_STATUS_SUCCESS;
2643 wake_up(&v->cvs_wait);
2644 } else if (ptr[0] == VSS_ISTREAM_CMD_SET_MEDIA_TYPE) {
2645 pr_debug("%s: SET_MEDIA resp 0x%x\n",
2646 __func__, ptr[1]);
2647
2648 v->cvs_state = CMD_STATUS_SUCCESS;
2649 wake_up(&v->cvs_wait);
2650 } else if (ptr[0] ==
2651 VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE) {
2652 pr_debug("%s: SET_AMR_RATE resp 0x%x\n",
2653 __func__, ptr[1]);
2654
2655 v->cvs_state = CMD_STATUS_SUCCESS;
2656 wake_up(&v->cvs_wait);
2657 } else if (ptr[0] ==
2658 VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE) {
2659 pr_debug("%s: SET_AMR_WB_RATE resp 0x%x\n",
2660 __func__, ptr[1]);
2661
2662 v->cvs_state = CMD_STATUS_SUCCESS;
2663 wake_up(&v->cvs_wait);
2664 } else if (ptr[0] == VSS_ISTREAM_CMD_SET_ENC_DTX_MODE) {
2665 pr_debug("%s: SET_DTX resp 0x%x\n",
2666 __func__, ptr[1]);
2667
2668 v->cvs_state = CMD_STATUS_SUCCESS;
2669 wake_up(&v->cvs_wait);
2670 } else if (ptr[0] ==
2671 VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE) {
2672 pr_debug("%s: SET_CDMA_RATE resp 0x%x\n",
2673 __func__, ptr[1]);
2674
2675 v->cvs_state = CMD_STATUS_SUCCESS;
2676 wake_up(&v->cvs_wait);
2677 } else if (ptr[0] == APRV2_IBASIC_CMD_DESTROY_SESSION) {
2678 pr_debug("%s: DESTROY resp\n", __func__);
2679
2680 v->cvs_state = CMD_STATUS_SUCCESS;
2681 wake_up(&v->cvs_wait);
2682 } else if (ptr[0] == VSS_ISTREAM_CMD_START_RECORD) {
2683 pr_debug("%s: START_RECORD resp 0x%x\n",
2684 __func__, ptr[1]);
2685
2686 v->cvs_state = CMD_STATUS_SUCCESS;
2687 wake_up(&v->cvs_wait);
2688 } else if (ptr[0] == VSS_ISTREAM_CMD_STOP_RECORD) {
2689 pr_debug("%s: STOP_RECORD resp 0x%x\n",
2690 __func__, ptr[1]);
2691
2692 v->cvs_state = CMD_STATUS_SUCCESS;
2693 wake_up(&v->cvs_wait);
2694#ifdef CONFIG_MSM8X60_RTAC
2695 } else if (ptr[0] == VOICE_CMD_SET_PARAM) {
2696 rtac_make_voice_callback(RTAC_CVS, ptr,
2697 data->payload_size);
2698#endif
2699 } else if (ptr[0] == VSS_ISTREAM_CMD_START_PLAYBACK) {
2700 pr_debug("%s: START_PLAYBACK resp 0x%x\n",
2701 __func__, ptr[1]);
2702
2703 v->cvs_state = CMD_STATUS_SUCCESS;
2704 wake_up(&v->cvs_wait);
2705 } else if (ptr[0] == VSS_ISTREAM_CMD_STOP_PLAYBACK) {
2706 pr_debug("%s: STOP_PLAYBACK resp 0x%x\n",
2707 __func__, ptr[1]);
2708
2709 v->cvs_state = CMD_STATUS_SUCCESS;
2710 wake_up(&v->cvs_wait);
2711 } else
2712 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2713 }
2714 } else if (data->opcode == VSS_ISTREAM_EVT_SEND_ENC_BUFFER) {
2715 uint32_t *voc_pkt = data->payload;
2716 uint32_t pkt_len = data->payload_size;
2717
Neema Shetty90189b82011-06-27 14:58:37 -07002718 if (voc_pkt != NULL && c->mvs_info.ul_cb != NULL) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002719 pr_debug("%s: Media type is 0x%x\n",
2720 __func__, voc_pkt[0]);
2721
2722 /* Remove media ID from payload. */
2723 voc_pkt++;
2724 pkt_len = pkt_len - 4;
2725
Neema Shetty90189b82011-06-27 14:58:37 -07002726 c->mvs_info.ul_cb((uint8_t *)voc_pkt,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002727 pkt_len,
Neema Shetty90189b82011-06-27 14:58:37 -07002728 c->mvs_info.private_data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002729 } else {
2730 pr_err("%s: voc_pkt is 0x%x ul_cb is 0x%x\n",
2731 __func__, (unsigned int)voc_pkt,
Neema Shetty90189b82011-06-27 14:58:37 -07002732 (unsigned int)c->mvs_info.ul_cb);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002733 }
2734 } else if (data->opcode == VSS_ISTREAM_EVT_SEND_DEC_BUFFER) {
2735 pr_debug("%s: Send dec buf resp\n", __func__);
2736 } else if (data->opcode == VSS_ISTREAM_EVT_REQUEST_DEC_BUFFER) {
2737 struct cvs_send_dec_buf_cmd send_dec_buf;
2738 int ret = 0;
2739 uint32_t pkt_len = 0;
2740
Neema Shetty90189b82011-06-27 14:58:37 -07002741 if (c->mvs_info.dl_cb != NULL) {
2742 send_dec_buf.dec_buf.media_id = c->mvs_info.media_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002743
Neema Shetty90189b82011-06-27 14:58:37 -07002744 c->mvs_info.dl_cb(
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002745 (uint8_t *)&send_dec_buf.dec_buf.packet_data,
2746 &pkt_len,
Neema Shetty90189b82011-06-27 14:58:37 -07002747 c->mvs_info.private_data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002748
2749 send_dec_buf.hdr.hdr_field =
2750 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2751 APR_HDR_LEN(APR_HDR_SIZE),
2752 APR_PKT_VER);
2753 send_dec_buf.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2754 sizeof(send_dec_buf.dec_buf.media_id) + pkt_len);
Neema Shetty90189b82011-06-27 14:58:37 -07002755 send_dec_buf.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002756 send_dec_buf.hdr.dest_port = voice_get_cvs_handle(v);
2757 send_dec_buf.hdr.token = 0;
2758 send_dec_buf.hdr.opcode =
2759 VSS_ISTREAM_EVT_SEND_DEC_BUFFER;
2760
Neema Shetty90189b82011-06-27 14:58:37 -07002761 ret = apr_send_pkt(voice_get_apr_cvs(),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002762 (uint32_t *) &send_dec_buf);
2763 if (ret < 0) {
2764 pr_err("%s: Error %d sending DEC_BUF\n",
2765 __func__, ret);
2766 goto fail;
2767 }
2768 } else {
2769 pr_err("%s: ul_cb is NULL\n", __func__);
2770 }
2771#ifdef CONFIG_MSM8X60_RTAC
2772 } else if (data->opcode == VOICE_EVT_GET_PARAM_ACK) {
2773 rtac_make_voice_callback(RTAC_CVS, data->payload,
2774 data->payload_size);
2775#endif
2776
2777 } else {
2778 pr_debug("%s: Unknown opcode 0x%x\n", __func__, data->opcode);
2779 }
2780
2781fail:
2782 return 0;
2783}
2784
2785static int32_t modem_cvp_callback(struct apr_client_data *data, void *priv)
2786{
2787 uint32_t *ptr;
Neema Shetty90189b82011-06-27 14:58:37 -07002788 struct common_data *c = priv;
2789 struct voice_data *v = NULL;
2790 int i = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002791
Neema Shetty90189b82011-06-27 14:58:37 -07002792 pr_debug("%s: session_id 0x%x\n", __func__, data->dest_port);
2793
2794 v = voice_get_session(data->dest_port);
2795 if (v == NULL) {
2796 pr_err("%s: v is NULL\n", __func__);
2797 return -EINVAL;
2798 }
2799
2800 pr_debug("%s: common data 0x%x, session 0x%x\n",
2801 __func__, (unsigned int)c, (unsigned int)v);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002802 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
2803 data->payload_size, data->opcode);
2804
2805 if (data->opcode == RESET_EVENTS) {
2806 pr_debug("%s:Reset event received in Voice service\n",
2807 __func__);
Neema Shetty90189b82011-06-27 14:58:37 -07002808 apr_reset(c->apr_cvp);
2809 c->apr_cvp = NULL;
2810 apr_reset(c->apr_q6_cvp);
2811 c->apr_q6_cvp = NULL;
2812
2813 /* Sub-system restart is applicable to all sessions. */
2814 for (i = 0; i < MAX_VOC_SESSIONS; i++)
2815 c->voice[i].cvp_handle = 0;
2816
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002817 return 0;
2818 }
2819
2820 if (data->opcode == APR_BASIC_RSP_RESULT) {
2821 if (data->payload_size) {
2822 ptr = data->payload;
2823
2824 pr_info("%x %x\n", ptr[0], ptr[1]);
2825 /*response from modem CVP */
2826 if (ptr[0] ==
2827 VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION) {
2828 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2829 if (!ptr[1]) {
2830 voice_set_cvp_handle(v, data->src_port);
2831 pr_debug("cvphdl=%d\n", data->src_port);
2832 } else
2833 pr_info("got NACK from CVP create \
2834 session response\n");
2835 v->cvp_state = CMD_STATUS_SUCCESS;
2836 wake_up(&v->cvp_wait);
2837 } else if (ptr[0] ==
2838 VSS_IVOCPROC_CMD_CACHE_CALIBRATION_DATA) {
2839 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2840 v->cvp_state = CMD_STATUS_SUCCESS;
2841 wake_up(&v->cvp_wait);
2842 } else if (ptr[0] == VSS_IVOCPROC_CMD_SET_DEVICE) {
2843 v->cvp_state = CMD_STATUS_SUCCESS;
2844 wake_up(&v->cvp_wait);
2845 } else if (ptr[0] ==
2846 VSS_IVOCPROC_CMD_SET_RX_VOLUME_INDEX) {
2847 v->cvp_state = CMD_STATUS_SUCCESS;
2848 wake_up(&v->cvp_wait);
2849 } else if (ptr[0] == VSS_IVOCPROC_CMD_ENABLE) {
2850 v->cvp_state = CMD_STATUS_SUCCESS;
2851 wake_up(&v->cvp_wait);
2852 } else if (ptr[0] == VSS_IVOCPROC_CMD_DISABLE) {
2853 v->cvp_state = CMD_STATUS_SUCCESS;
2854 wake_up(&v->cvp_wait);
2855 } else if (ptr[0] == APRV2_IBASIC_CMD_DESTROY_SESSION) {
2856 v->cvp_state = CMD_STATUS_SUCCESS;
2857 wake_up(&v->cvp_wait);
2858 } else if (ptr[0] ==
2859 VSS_IVOCPROC_CMD_CACHE_VOLUME_CALIBRATION_TABLE
2860 ) {
2861
2862 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2863 v->cvp_state = CMD_STATUS_SUCCESS;
2864 wake_up(&v->cvp_wait);
2865#ifdef CONFIG_MSM8X60_RTAC
2866 } else if (ptr[0] == VOICE_CMD_SET_PARAM) {
2867 rtac_make_voice_callback(RTAC_CVP, ptr,
2868 data->payload_size);
2869#endif
2870 } else
2871 pr_debug("%s: not match cmd = 0x%x\n",
2872 __func__, ptr[0]);
2873 }
2874#ifdef CONFIG_MSM8X60_RTAC
2875 } else if (data->opcode == VOICE_EVT_GET_PARAM_ACK) {
2876 rtac_make_voice_callback(RTAC_CVP, data->payload,
2877 data->payload_size);
2878#endif
2879 }
2880 return 0;
2881}
2882
2883
2884static int __init voice_init(void)
2885{
Neema Shetty90189b82011-06-27 14:58:37 -07002886 int rc = 0, i = 0;
2887
2888 memset(&common, 0, sizeof(struct common_data));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002889
2890 /* set default value */
Neema Shetty90189b82011-06-27 14:58:37 -07002891 common.default_mute_val = 1; /* default is mute */
2892 common.default_vol_val = 0;
2893 common.default_sample_val = 8000;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002894
Neema Shetty90189b82011-06-27 14:58:37 -07002895 common.voc_path = VOC_PATH_PASSIVE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002896
2897 /* Initialize MVS info. */
Neema Shetty90189b82011-06-27 14:58:37 -07002898 common.mvs_info.network_type = VSS_NETWORK_ID_DEFAULT;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002899
Neema Shetty90189b82011-06-27 14:58:37 -07002900 mutex_init(&common.common_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002901
Neema Shetty90189b82011-06-27 14:58:37 -07002902 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
2903 common.voice[i].session_id = SESSION_ID_BASE + i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002904
Neema Shetty90189b82011-06-27 14:58:37 -07002905 common.voice[i].dev_rx.volume = common.default_vol_val;
2906 common.voice[i].dev_tx.mute = common.default_mute_val;
2907
2908 common.voice[i].voc_state = VOC_INIT;
2909
2910 common.voice[i].rec_info.rec_mode = VOC_REC_NONE;
2911
2912 init_waitqueue_head(&common.voice[i].mvm_wait);
2913 init_waitqueue_head(&common.voice[i].cvs_wait);
2914 init_waitqueue_head(&common.voice[i].cvp_wait);
2915
2916 mutex_init(&common.voice[i].lock);
2917
2918 }
2919
2920 common.device_events = AUDDEV_EVT_DEV_CHG_VOICE |
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002921 AUDDEV_EVT_DEV_RDY |
2922 AUDDEV_EVT_REL_PENDING |
2923 AUDDEV_EVT_START_VOICE |
2924 AUDDEV_EVT_END_VOICE |
2925 AUDDEV_EVT_DEVICE_VOL_MUTE_CHG |
2926 AUDDEV_EVT_FREQ_CHG;
2927
2928 pr_debug("to register call back\n");
2929 /* register callback to auddev */
Neema Shetty90189b82011-06-27 14:58:37 -07002930 auddev_register_evt_listner(common.device_events, AUDDEV_CLNT_VOC,
2931 0, voice_auddev_cb_function, &common);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002932
2933 return rc;
2934}
2935
2936device_initcall(voice_init);