blob: 34169c09913686b60c2cf26609a81adcd11fd918 [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>
Bharath Ramachandramurthyb9209472011-09-27 17:56:20 -070025#include <linux/delay.h>
Ben Rombergerfce8f512011-07-18 16:46:09 -070026
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070027#include <mach/qdsp6v2/audio_dev_ctl.h>
28#include <mach/dal.h>
29#include <mach/qdsp6v2/q6voice.h>
30#include <mach/qdsp6v2/rtac.h>
31#include <mach/qdsp6v2/audio_acdb.h>
Ben Rombergerfce8f512011-07-18 16:46:09 -070032
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070033#include "q6core.h"
34
35
36#define TIMEOUT_MS 3000
37#define SNDDEV_CAP_TTY 0x20
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070038#define CMD_STATUS_SUCCESS 0
39#define CMD_STATUS_FAIL 1
40
Neema Shetty90189b82011-06-27 14:58:37 -070041/* Voice session creates passive control sessions for MVM and CVS. */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070042#define VOC_PATH_PASSIVE 0
Neema Shetty90189b82011-06-27 14:58:37 -070043
44/* VoIP session creates full control sessions for MVM and CVS. */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070045#define VOC_PATH_FULL 1
Neema Shetty90189b82011-06-27 14:58:37 -070046
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070047#define ADSP_VERSION_CVD 0x60300000
48
49#define BUFFER_PAYLOAD_SIZE 4000
50
51#define VOC_REC_NONE 0xFF
52
Neema Shetty90189b82011-06-27 14:58:37 -070053struct common_data common;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070054
55static bool is_adsp_support_cvd(void)
56{
Neema Shetty90189b82011-06-27 14:58:37 -070057 return (common.adsp_version >= ADSP_VERSION_CVD);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070058}
59static int voice_send_enable_vocproc_cmd(struct voice_data *v);
60static int voice_send_netid_timing_cmd(struct voice_data *v);
61
Neema Shetty90189b82011-06-27 14:58:37 -070062static void *voice_get_apr_mvm(void)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070063{
64 void *apr_mvm = NULL;
65
Neema Shetty90189b82011-06-27 14:58:37 -070066 if (common.voc_path == VOC_PATH_PASSIVE &&
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070067 !(is_adsp_support_cvd()))
Neema Shetty90189b82011-06-27 14:58:37 -070068 apr_mvm = common.apr_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070069 else
Neema Shetty90189b82011-06-27 14:58:37 -070070 apr_mvm = common.apr_q6_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070071
72 pr_debug("%s: apr_mvm 0x%x\n", __func__, (unsigned int)apr_mvm);
73
74 return apr_mvm;
75}
76
Neema Shetty90189b82011-06-27 14:58:37 -070077static void voice_set_apr_mvm(void *apr_mvm)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070078{
79 pr_debug("%s: apr_mvm 0x%x\n", __func__, (unsigned int)apr_mvm);
80
Neema Shetty90189b82011-06-27 14:58:37 -070081 if (common.voc_path == VOC_PATH_PASSIVE &&
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070082 !(is_adsp_support_cvd()))
Neema Shetty90189b82011-06-27 14:58:37 -070083 common.apr_mvm = apr_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070084 else
Neema Shetty90189b82011-06-27 14:58:37 -070085 common.apr_q6_mvm = apr_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070086}
87
Neema Shetty90189b82011-06-27 14:58:37 -070088static void *voice_get_apr_cvs(void)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070089{
90 void *apr_cvs = NULL;
91
Neema Shetty90189b82011-06-27 14:58:37 -070092 if (common.voc_path == VOC_PATH_PASSIVE &&
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070093 !(is_adsp_support_cvd()))
Neema Shetty90189b82011-06-27 14:58:37 -070094 apr_cvs = common.apr_cvs;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070095 else
Neema Shetty90189b82011-06-27 14:58:37 -070096 apr_cvs = common.apr_q6_cvs;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070097
98 pr_debug("%s: apr_cvs 0x%x\n", __func__, (unsigned int)apr_cvs);
99
100 return apr_cvs;
101}
102
Neema Shetty90189b82011-06-27 14:58:37 -0700103static void voice_set_apr_cvs(void *apr_cvs)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700104{
105 pr_debug("%s: apr_cvs 0x%x\n", __func__, (unsigned int)apr_cvs);
106
Neema Shetty90189b82011-06-27 14:58:37 -0700107 if (common.voc_path == VOC_PATH_PASSIVE &&
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700108 !(is_adsp_support_cvd()))
Neema Shetty90189b82011-06-27 14:58:37 -0700109 common.apr_cvs = apr_cvs;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700110 else
Neema Shetty90189b82011-06-27 14:58:37 -0700111 common.apr_q6_cvs = apr_cvs;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700112 rtac_set_voice_handle(RTAC_CVS, apr_cvs);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700113}
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 rtac_set_voice_handle(RTAC_CVP, apr_cvp);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700140}
141
142static u16 voice_get_mvm_handle(struct voice_data *v)
143{
Neema Shetty90189b82011-06-27 14:58:37 -0700144 pr_debug("%s: mvm_handle %d\n", __func__, v->mvm_handle);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700145
Neema Shetty90189b82011-06-27 14:58:37 -0700146 return v->mvm_handle;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700147}
148
149static void voice_set_mvm_handle(struct voice_data *v, u16 mvm_handle)
150{
Neema Shetty90189b82011-06-27 14:58:37 -0700151 pr_debug("%s: session 0x%x, mvm_handle %d\n",
152 __func__, (unsigned int)v, mvm_handle);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700153
Neema Shetty90189b82011-06-27 14:58:37 -0700154 v->mvm_handle = mvm_handle;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700155}
156
157static u16 voice_get_cvs_handle(struct voice_data *v)
158{
Neema Shetty90189b82011-06-27 14:58:37 -0700159 pr_debug("%s: cvs_handle %d\n", __func__, v->cvs_handle);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700160
Neema Shetty90189b82011-06-27 14:58:37 -0700161 return v->cvs_handle;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700162}
163
164static void voice_set_cvs_handle(struct voice_data *v, u16 cvs_handle)
165{
Neema Shetty90189b82011-06-27 14:58:37 -0700166 pr_debug("%s: session 0x%x, cvs_handle %d\n",
167 __func__, (unsigned int)v, cvs_handle);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700168
Neema Shetty90189b82011-06-27 14:58:37 -0700169 v->cvs_handle = cvs_handle;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700170}
171
172static u16 voice_get_cvp_handle(struct voice_data *v)
173{
Neema Shetty90189b82011-06-27 14:58:37 -0700174 pr_debug("%s: cvp_handle %d\n", __func__, v->cvp_handle);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700175
Neema Shetty90189b82011-06-27 14:58:37 -0700176 return v->cvp_handle;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700177}
178
179static void voice_set_cvp_handle(struct voice_data *v, u16 cvp_handle)
180{
Neema Shetty90189b82011-06-27 14:58:37 -0700181 pr_debug("%s: session 0x%x, cvp_handle %d\n",
182 __func__, (unsigned int)v, cvp_handle);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700183
Neema Shetty90189b82011-06-27 14:58:37 -0700184 v->cvp_handle = cvp_handle;
185}
186
187u16 voice_get_session_id(const char *name)
188{
189 u16 session_id = 0;
190
191 if (name != NULL) {
192 if (!strncmp(name, "Voice session", 13))
193 session_id = common.voice[VOC_PATH_PASSIVE].session_id;
194 else
195 session_id = common.voice[VOC_PATH_FULL].session_id;
196 }
197
198 pr_debug("%s: %s has session id 0x%x\n", __func__, name, session_id);
199
200 return session_id;
201}
202
203static struct voice_data *voice_get_session(u16 session_id)
204{
205 struct voice_data *v = NULL;
206
207 if (session_id == 0) {
208 mutex_lock(&common.common_lock);
209
210 pr_debug("%s: NULL id, voc_path is %d\n",
211 __func__, common.voc_path);
212
213 if (common.voc_path == VOC_PATH_PASSIVE)
214 v = &common.voice[VOC_PATH_PASSIVE];
215 else
216 v = &common.voice[VOC_PATH_FULL];
217
218 mutex_unlock(&common.common_lock);
219 } else if ((session_id >= SESSION_ID_BASE) &&
220 (session_id < SESSION_ID_BASE + MAX_VOC_SESSIONS)) {
221 v = &common.voice[session_id - SESSION_ID_BASE];
222 } else {
223 pr_err("%s: Invalid session_id 0x%x\n", __func__, session_id);
224 }
225
226 pr_debug("%s: session_id 0x%x session handle 0x%x\n",
227 __func__, session_id, (unsigned int)v);
228
229 return v;
230}
231
232static bool is_voice_session(u16 session_id)
233{
234 return (session_id == common.voice[VOC_PATH_PASSIVE].session_id);
235}
236
237static bool is_voip_session(u16 session_id)
238{
239 return (session_id == common.voice[VOC_PATH_FULL].session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700240}
241
242static void voice_auddev_cb_function(u32 evt_id,
243 union auddev_evt_data *evt_payload,
244 void *private_data);
245
246static int32_t modem_mvm_callback(struct apr_client_data *data, void *priv);
247static int32_t modem_cvs_callback(struct apr_client_data *data, void *priv);
248static int32_t modem_cvp_callback(struct apr_client_data *data, void *priv);
249
Neema Shetty90189b82011-06-27 14:58:37 -0700250static int voice_apr_register(void)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700251{
252 int rc = 0;
253 void *apr_mvm;
254 void *apr_cvs;
255 void *apr_cvp;
256
Neema Shetty90189b82011-06-27 14:58:37 -0700257 if (common.adsp_version == 0) {
258 common.adsp_version = core_get_adsp_version();
259 pr_info("adsp_ver fetched:%x\n", common.adsp_version);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700260 }
Neema Shetty90189b82011-06-27 14:58:37 -0700261
262 mutex_lock(&common.common_lock);
263
264 apr_mvm = voice_get_apr_mvm();
265 apr_cvs = voice_get_apr_cvs();
266 apr_cvp = voice_get_apr_cvp();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700267
268
269 pr_debug("into voice_apr_register_callback\n");
270 /* register callback to APR */
271 if (apr_mvm == NULL) {
272 pr_debug("start to register MVM callback\n");
273
Neema Shetty90189b82011-06-27 14:58:37 -0700274 if (common.voc_path == VOC_PATH_PASSIVE &&
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700275 !(is_adsp_support_cvd())) {
276 apr_mvm = apr_register("MODEM", "MVM",
277 modem_mvm_callback, 0xFFFFFFFF,
Neema Shetty90189b82011-06-27 14:58:37 -0700278 &common);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700279 } else {
280 apr_mvm = apr_register("ADSP", "MVM",
281 modem_mvm_callback, 0xFFFFFFFF,
Neema Shetty90189b82011-06-27 14:58:37 -0700282 &common);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700283 }
284
285 if (apr_mvm == NULL) {
286 pr_err("Unable to register MVM %d\n",
287 is_adsp_support_cvd());
288 rc = -ENODEV;
289 goto done;
290 }
291
Neema Shetty90189b82011-06-27 14:58:37 -0700292 voice_set_apr_mvm(apr_mvm);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700293 }
294
295 if (apr_cvs == NULL) {
296 pr_debug("start to register CVS callback\n");
297
Neema Shetty90189b82011-06-27 14:58:37 -0700298 if (common.voc_path == VOC_PATH_PASSIVE &&
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700299 !(is_adsp_support_cvd())) {
300 apr_cvs = apr_register("MODEM", "CVS",
301 modem_cvs_callback, 0xFFFFFFFF,
Neema Shetty90189b82011-06-27 14:58:37 -0700302 &common);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700303 } else {
304 apr_cvs = apr_register("ADSP", "CVS",
305 modem_cvs_callback, 0xFFFFFFFF,
Neema Shetty90189b82011-06-27 14:58:37 -0700306 &common);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700307 }
308
309 if (apr_cvs == NULL) {
310 pr_err("Unable to register CVS %d\n",
311 is_adsp_support_cvd());
312 rc = -ENODEV;
313 goto err;
314 }
315
Neema Shetty90189b82011-06-27 14:58:37 -0700316 voice_set_apr_cvs(apr_cvs);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700317 }
318
319 if (apr_cvp == NULL) {
320 pr_debug("start to register CVP callback\n");
321
Neema Shetty90189b82011-06-27 14:58:37 -0700322 if (common.voc_path == VOC_PATH_PASSIVE &&
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700323 !(is_adsp_support_cvd())) {
324 apr_cvp = apr_register("MODEM", "CVP",
325 modem_cvp_callback, 0xFFFFFFFF,
Neema Shetty90189b82011-06-27 14:58:37 -0700326 &common);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700327 } else {
328 apr_cvp = apr_register("ADSP", "CVP",
329 modem_cvp_callback, 0xFFFFFFFF,
Neema Shetty90189b82011-06-27 14:58:37 -0700330 &common);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700331 }
332
333 if (apr_cvp == NULL) {
334 pr_err("Unable to register CVP %d\n",
335 is_adsp_support_cvd());
336 rc = -ENODEV;
337 goto err1;
338 }
339
Neema Shetty90189b82011-06-27 14:58:37 -0700340 voice_set_apr_cvp(apr_cvp);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700341 }
Neema Shetty90189b82011-06-27 14:58:37 -0700342
343 mutex_unlock(&common.common_lock);
344
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700345 return 0;
346
347err1:
348 apr_deregister(apr_cvs);
349 apr_cvs = NULL;
Neema Shetty90189b82011-06-27 14:58:37 -0700350 voice_set_apr_cvs(apr_cvs);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700351err:
352 apr_deregister(apr_mvm);
353 apr_mvm = NULL;
Neema Shetty90189b82011-06-27 14:58:37 -0700354 voice_set_apr_mvm(apr_mvm);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700355
356done:
Neema Shetty90189b82011-06-27 14:58:37 -0700357 mutex_unlock(&common.common_lock);
358
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700359 return rc;
360}
361
362static int voice_create_mvm_cvs_session(struct voice_data *v)
363{
364 int ret = 0;
365 struct mvm_create_ctl_session_cmd mvm_session_cmd;
366 struct cvs_create_passive_ctl_session_cmd cvs_session_cmd;
367 struct cvs_create_full_ctl_session_cmd cvs_full_ctl_cmd;
368 struct mvm_attach_stream_cmd attach_stream_cmd;
Neema Shetty90189b82011-06-27 14:58:37 -0700369 void *apr_mvm = voice_get_apr_mvm();
370 void *apr_cvs = voice_get_apr_cvs();
371 void *apr_cvp = voice_get_apr_cvp();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700372 u16 mvm_handle = voice_get_mvm_handle(v);
373 u16 cvs_handle = voice_get_cvs_handle(v);
374 u16 cvp_handle = voice_get_cvp_handle(v);
375
376 pr_info("%s:\n", __func__);
377
378 /* start to ping if modem service is up */
379 pr_debug("in voice_create_mvm_cvs_session, mvm_hdl=%d, cvs_hdl=%d\n",
380 mvm_handle, cvs_handle);
381 /* send cmd to create mvm session and wait for response */
382
383 if (!mvm_handle) {
Neema Shetty90189b82011-06-27 14:58:37 -0700384 if (is_voice_session(v->session_id)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700385 mvm_session_cmd.hdr.hdr_field =
386 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
387 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
388 mvm_session_cmd.hdr.pkt_size =
389 APR_PKT_SIZE(APR_HDR_SIZE,
390 sizeof(mvm_session_cmd) - APR_HDR_SIZE);
391 pr_debug("Send mvm create session pkt size = %d\n",
392 mvm_session_cmd.hdr.pkt_size);
Neema Shetty90189b82011-06-27 14:58:37 -0700393 mvm_session_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700394 mvm_session_cmd.hdr.dest_port = 0;
395 mvm_session_cmd.hdr.token = 0;
396 pr_debug("%s: Creating MVM passive ctrl\n", __func__);
397 mvm_session_cmd.hdr.opcode =
398 VSS_IMVM_CMD_CREATE_PASSIVE_CONTROL_SESSION;
399 strncpy(mvm_session_cmd.mvm_session.name,
400 "default modem voice", SESSION_NAME_LEN);
401
402 v->mvm_state = CMD_STATUS_FAIL;
403
404 ret = apr_send_pkt(apr_mvm,
405 (uint32_t *) &mvm_session_cmd);
406 if (ret < 0) {
407 pr_err("Error sending MVM_CONTROL_SESSION\n");
408 goto fail;
409 }
410 ret = wait_event_timeout(v->mvm_wait,
411 (v->mvm_state == CMD_STATUS_SUCCESS),
412 msecs_to_jiffies(TIMEOUT_MS));
413 if (!ret) {
414 pr_err("%s: wait_event timeout\n", __func__);
415 goto fail;
416 }
417 } else {
418 mvm_session_cmd.hdr.hdr_field =
419 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
420 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
421 mvm_session_cmd.hdr.pkt_size =
422 APR_PKT_SIZE(APR_HDR_SIZE,
423 sizeof(mvm_session_cmd) - APR_HDR_SIZE);
424 pr_debug("Send mvm create session pkt size = %d\n",
425 mvm_session_cmd.hdr.pkt_size);
Neema Shetty90189b82011-06-27 14:58:37 -0700426 mvm_session_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700427 mvm_session_cmd.hdr.dest_port = 0;
428 mvm_session_cmd.hdr.token = 0;
429 pr_debug("%s: Creating MVM full ctrl\n", __func__);
430 mvm_session_cmd.hdr.opcode =
431 VSS_IMVM_CMD_CREATE_FULL_CONTROL_SESSION;
432 strncpy(mvm_session_cmd.mvm_session.name,
433 "default voip", SESSION_NAME_LEN);
434
435 v->mvm_state = CMD_STATUS_FAIL;
436
437 ret = apr_send_pkt(apr_mvm,
438 (uint32_t *) &mvm_session_cmd);
439 if (ret < 0) {
440 pr_err("Error sending MVM_FULL_CTL_SESSION\n");
441 goto fail;
442 }
443 ret = wait_event_timeout(v->mvm_wait,
444 (v->mvm_state == CMD_STATUS_SUCCESS),
445 msecs_to_jiffies(TIMEOUT_MS));
446 if (!ret) {
447 pr_err("%s: wait_event timeout\n", __func__);
448 goto fail;
449 }
450 }
451
452 /* Get the created MVM handle. */
453 mvm_handle = voice_get_mvm_handle(v);
454 }
455
456 /* send cmd to create cvs session */
457 if (!cvs_handle) {
Neema Shetty90189b82011-06-27 14:58:37 -0700458 if (is_voice_session(v->session_id)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700459 pr_info("%s:creating CVS passive session\n", __func__);
460
461 cvs_session_cmd.hdr.hdr_field = APR_HDR_FIELD(
462 APR_MSG_TYPE_SEQ_CMD,
463 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
464 cvs_session_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
465 sizeof(cvs_session_cmd) - APR_HDR_SIZE);
466 pr_info("send stream create session pkt size = %d\n",
467 cvs_session_cmd.hdr.pkt_size);
Neema Shetty90189b82011-06-27 14:58:37 -0700468 cvs_session_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700469 cvs_session_cmd.hdr.dest_port = 0;
470 cvs_session_cmd.hdr.token = 0;
471 cvs_session_cmd.hdr.opcode =
472 VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION;
473 strncpy(cvs_session_cmd.cvs_session.name,
474 "default modem voice", SESSION_NAME_LEN);
475
476 v->cvs_state = CMD_STATUS_FAIL;
477
478 pr_info("%s: CVS create\n", __func__);
479 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_session_cmd);
480 if (ret < 0) {
481 pr_err("Fail in sending STREAM_CONTROL_SESSION\n");
482 goto fail;
483 }
484 ret = wait_event_timeout(v->cvs_wait,
485 (v->cvs_state == CMD_STATUS_SUCCESS),
486 msecs_to_jiffies(TIMEOUT_MS));
487 if (!ret) {
488 pr_err("%s: wait_event timeout\n", __func__);
489 goto fail;
490 }
491
492 /* Get the created CVS handle. */
493 cvs_handle = voice_get_cvs_handle(v);
494 } else {
495 pr_info("%s:creating CVS full session\n", __func__);
496
497 cvs_full_ctl_cmd.hdr.hdr_field =
498 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
499 APR_HDR_LEN(APR_HDR_SIZE),
500 APR_PKT_VER);
501
502 cvs_full_ctl_cmd.hdr.pkt_size =
503 APR_PKT_SIZE(APR_HDR_SIZE,
504 sizeof(cvs_full_ctl_cmd) - APR_HDR_SIZE);
505
Neema Shetty90189b82011-06-27 14:58:37 -0700506 cvs_full_ctl_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700507 cvs_full_ctl_cmd.hdr.dest_port = 0;
508 cvs_full_ctl_cmd.hdr.token = 0;
509 cvs_full_ctl_cmd.hdr.opcode =
510 VSS_ISTREAM_CMD_CREATE_FULL_CONTROL_SESSION;
511 cvs_full_ctl_cmd.cvs_session.direction = 2;
512
513 cvs_full_ctl_cmd.cvs_session.enc_media_type =
Neema Shetty90189b82011-06-27 14:58:37 -0700514 common.mvs_info.media_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700515 cvs_full_ctl_cmd.cvs_session.dec_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.network_id =
Neema Shetty90189b82011-06-27 14:58:37 -0700518 common.mvs_info.network_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700519 strncpy(cvs_full_ctl_cmd.cvs_session.name,
520 "default voip", SESSION_NAME_LEN);
521
522 v->cvs_state = CMD_STATUS_FAIL;
523
524 ret = apr_send_pkt(apr_cvs,
525 (uint32_t *) &cvs_full_ctl_cmd);
526
527 if (ret < 0) {
528 pr_err("%s: Err %d sending CREATE_FULL_CTRL\n",
529 __func__, ret);
530 goto fail;
531 }
532 ret = wait_event_timeout(v->cvs_wait,
533 (v->cvs_state == CMD_STATUS_SUCCESS),
534 msecs_to_jiffies(TIMEOUT_MS));
535 if (!ret) {
536 pr_err("%s: wait_event timeout\n", __func__);
537 goto fail;
538 }
539
540 /* Get the created CVS handle. */
541 cvs_handle = voice_get_cvs_handle(v);
542
543 /* Attach MVM to CVS. */
544 pr_info("%s: Attach MVM to stream\n", __func__);
545
546 attach_stream_cmd.hdr.hdr_field =
547 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
548 APR_HDR_LEN(APR_HDR_SIZE),
549 APR_PKT_VER);
550
551 attach_stream_cmd.hdr.pkt_size =
552 APR_PKT_SIZE(APR_HDR_SIZE,
553 sizeof(attach_stream_cmd) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -0700554 attach_stream_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700555 attach_stream_cmd.hdr.dest_port = mvm_handle;
556 attach_stream_cmd.hdr.token = 0;
557 attach_stream_cmd.hdr.opcode =
558 VSS_IMVM_CMD_ATTACH_STREAM;
559 attach_stream_cmd.attach_stream.handle = cvs_handle;
560
561 v->mvm_state = CMD_STATUS_FAIL;
562 ret = apr_send_pkt(apr_mvm,
563 (uint32_t *) &attach_stream_cmd);
564 if (ret < 0) {
565 pr_err("%s: Error %d sending ATTACH_STREAM\n",
566 __func__, ret);
567 goto fail;
568 }
569 ret = wait_event_timeout(v->mvm_wait,
570 (v->mvm_state == CMD_STATUS_SUCCESS),
571 msecs_to_jiffies(TIMEOUT_MS));
572 if (!ret) {
573 pr_err("%s: wait_event timeout\n", __func__);
574 goto fail;
575 }
576 }
577 }
578
579 return 0;
580
581fail:
582 apr_deregister(apr_mvm);
583 apr_mvm = NULL;
Neema Shetty90189b82011-06-27 14:58:37 -0700584 voice_set_apr_mvm(apr_mvm);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700585
586 apr_deregister(apr_cvs);
587 apr_cvs = NULL;
Neema Shetty90189b82011-06-27 14:58:37 -0700588 voice_set_apr_cvs(apr_cvs);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700589
590 apr_deregister(apr_cvp);
591 apr_cvp = NULL;
Neema Shetty90189b82011-06-27 14:58:37 -0700592 voice_set_apr_cvp(apr_cvp);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700593
594 cvp_handle = 0;
595 voice_set_cvp_handle(v, cvp_handle);
596
597 cvs_handle = 0;
598 voice_set_cvs_handle(v, cvs_handle);
599
600 return -EINVAL;
601}
602
603static int voice_destroy_mvm_cvs_session(struct voice_data *v)
604{
605 int ret = 0;
606 struct mvm_detach_stream_cmd detach_stream;
607 struct apr_hdr mvm_destroy;
608 struct apr_hdr cvs_destroy;
Neema Shetty90189b82011-06-27 14:58:37 -0700609 void *apr_mvm = voice_get_apr_mvm();
610 void *apr_cvs = voice_get_apr_cvs();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700611 u16 mvm_handle = voice_get_mvm_handle(v);
612 u16 cvs_handle = voice_get_cvs_handle(v);
613
614 /* MVM, CVS sessions are destroyed only for Full control sessions. */
Neema Shetty90189b82011-06-27 14:58:37 -0700615 if (is_voip_session(v->session_id)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700616 pr_info("%s: MVM detach stream\n", __func__);
617
618 /* Detach voice stream. */
619 detach_stream.hdr.hdr_field =
620 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
621 APR_HDR_LEN(APR_HDR_SIZE),
622 APR_PKT_VER);
623 detach_stream.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
624 sizeof(detach_stream) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -0700625 detach_stream.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700626 detach_stream.hdr.dest_port = mvm_handle;
627 detach_stream.hdr.token = 0;
628 detach_stream.hdr.opcode = VSS_IMVM_CMD_DETACH_STREAM;
629 detach_stream.detach_stream.handle = cvs_handle;
630
631 v->mvm_state = CMD_STATUS_FAIL;
632
633 ret = apr_send_pkt(apr_mvm, (uint32_t *) &detach_stream);
634 if (ret < 0) {
635 pr_err("%s: Error %d sending DETACH_STREAM\n",
636 __func__, ret);
637
638 goto fail;
639 }
640
641 ret = wait_event_timeout(v->mvm_wait,
642 (v->mvm_state == CMD_STATUS_SUCCESS),
643 msecs_to_jiffies(TIMEOUT_MS));
644 if (!ret) {
645 pr_err("%s: wait event timeout\n", __func__);
646 goto fail;
647 }
648
649 /* Destroy CVS. */
650 pr_info("%s: CVS destroy session\n", __func__);
651
652 cvs_destroy.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
653 APR_HDR_LEN(APR_HDR_SIZE),
654 APR_PKT_VER);
655 cvs_destroy.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
656 sizeof(cvs_destroy) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -0700657 cvs_destroy.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700658 cvs_destroy.dest_port = cvs_handle;
659 cvs_destroy.token = 0;
660 cvs_destroy.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
661
662 v->cvs_state = CMD_STATUS_FAIL;
663
664 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_destroy);
665 if (ret < 0) {
666 pr_err("%s: Error %d sending CVS DESTROY\n",
667 __func__, ret);
668
669 goto fail;
670 }
671
672 ret = wait_event_timeout(v->cvs_wait,
673 (v->cvs_state == CMD_STATUS_SUCCESS),
674 msecs_to_jiffies(TIMEOUT_MS));
675 if (!ret) {
676 pr_err("%s: wait event timeout\n", __func__);
677
678 goto fail;
679 }
680 cvs_handle = 0;
681 voice_set_cvs_handle(v, cvs_handle);
682
683 /* Destroy MVM. */
684 pr_info("%s: MVM destroy session\n", __func__);
685
686 mvm_destroy.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
687 APR_HDR_LEN(APR_HDR_SIZE),
688 APR_PKT_VER);
689 mvm_destroy.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
690 sizeof(mvm_destroy) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -0700691 mvm_destroy.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700692 mvm_destroy.dest_port = mvm_handle;
693 mvm_destroy.token = 0;
694 mvm_destroy.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
695
696 v->mvm_state = CMD_STATUS_FAIL;
697
698 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_destroy);
699 if (ret < 0) {
700 pr_err("%s: Error %d sending MVM DESTROY\n",
701 __func__, ret);
702
703 goto fail;
704 }
705
706 ret = wait_event_timeout(v->mvm_wait,
707 (v->mvm_state == CMD_STATUS_SUCCESS),
708 msecs_to_jiffies(TIMEOUT_MS));
709 if (!ret) {
710 pr_err("%s: wait event timeout\n", __func__);
711
712 goto fail;
713 }
714 mvm_handle = 0;
715 voice_set_mvm_handle(v, mvm_handle);
716 }
717
718fail:
719 return 0;
720}
721
722static int voice_send_tty_mode_to_modem(struct voice_data *v)
723{
724 struct msm_snddev_info *dev_tx_info;
725 struct msm_snddev_info *dev_rx_info;
726 int tty_mode = 0;
727 int ret = 0;
728 struct mvm_set_tty_mode_cmd mvm_tty_mode_cmd;
Neema Shetty90189b82011-06-27 14:58:37 -0700729 void *apr_mvm = voice_get_apr_mvm();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700730 u16 mvm_handle = voice_get_mvm_handle(v);
731
732 dev_rx_info = audio_dev_ctrl_find_dev(v->dev_rx.dev_id);
733 if (IS_ERR(dev_rx_info)) {
734 pr_err("bad dev_id %d\n", v->dev_rx.dev_id);
735 goto done;
736 }
737
738 dev_tx_info = audio_dev_ctrl_find_dev(v->dev_tx.dev_id);
739 if (IS_ERR(dev_tx_info)) {
740 pr_err("bad dev_id %d\n", v->dev_tx.dev_id);
741 goto done;
742 }
743
744 if ((dev_rx_info->capability & SNDDEV_CAP_TTY) &&
745 (dev_tx_info->capability & SNDDEV_CAP_TTY))
746 tty_mode = 3; /* FULL */
747 else if (!(dev_tx_info->capability & SNDDEV_CAP_TTY) &&
748 (dev_rx_info->capability & SNDDEV_CAP_TTY))
749 tty_mode = 2; /* VCO */
750 else if ((dev_tx_info->capability & SNDDEV_CAP_TTY) &&
751 !(dev_rx_info->capability & SNDDEV_CAP_TTY))
752 tty_mode = 1; /* HCO */
753
754 if (tty_mode) {
755 /* send tty mode cmd to mvm */
756 mvm_tty_mode_cmd.hdr.hdr_field = APR_HDR_FIELD(
757 APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
758 APR_PKT_VER);
759 mvm_tty_mode_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
760 sizeof(mvm_tty_mode_cmd) - APR_HDR_SIZE);
761 pr_debug("pkt size = %d\n", mvm_tty_mode_cmd.hdr.pkt_size);
Neema Shetty90189b82011-06-27 14:58:37 -0700762 mvm_tty_mode_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700763 mvm_tty_mode_cmd.hdr.dest_port = mvm_handle;
764 mvm_tty_mode_cmd.hdr.token = 0;
765 mvm_tty_mode_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_TTY_MODE;
766 mvm_tty_mode_cmd.tty_mode.mode = tty_mode;
767 pr_info("tty mode =%d\n", mvm_tty_mode_cmd.tty_mode.mode);
768
769 v->mvm_state = CMD_STATUS_FAIL;
770 pr_info("%s: MVM set tty\n", __func__);
771 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_tty_mode_cmd);
772 if (ret < 0) {
773 pr_err("Fail: sending VSS_ISTREAM_CMD_SET_TTY_MODE\n");
774 goto done;
775 }
776 ret = wait_event_timeout(v->mvm_wait,
777 (v->mvm_state == CMD_STATUS_SUCCESS),
778 msecs_to_jiffies(TIMEOUT_MS));
779 if (!ret) {
780 pr_err("%s: wait_event timeout\n", __func__);
781 goto done;
782 }
783 }
784 return 0;
785done:
786 return -EINVAL;
787}
788
789static int voice_send_cvs_cal_to_modem(struct voice_data *v)
790{
791 struct apr_hdr cvs_cal_cmd_hdr;
792 uint32_t *cmd_buf;
793 struct acdb_cal_data cal_data;
794 struct acdb_cal_block *cal_blk;
795 int32_t cal_size_per_network;
796 uint32_t *cal_data_per_network;
797 int index = 0;
798 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -0700799 void *apr_cvs = voice_get_apr_cvs();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700800 u16 cvs_handle = voice_get_cvs_handle(v);
801
802 /* fill the header */
803 cvs_cal_cmd_hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
804 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
805 cvs_cal_cmd_hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
806 sizeof(cvs_cal_cmd_hdr) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -0700807 cvs_cal_cmd_hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700808 cvs_cal_cmd_hdr.dest_port = cvs_handle;
809 cvs_cal_cmd_hdr.token = 0;
810 cvs_cal_cmd_hdr.opcode =
811 VSS_ISTREAM_CMD_CACHE_CALIBRATION_DATA;
812
813 pr_debug("voice_send_cvs_cal_to_modem\n");
814 /* get the cvs cal data */
815 get_vocstrm_cal(&cal_data);
816 if (cal_data.num_cal_blocks == 0) {
817 pr_err("%s: No calibration data to send!\n", __func__);
818 goto done;
819 }
820
821 /* send cvs cal to modem */
822 cmd_buf = kzalloc((sizeof(struct apr_hdr) + BUFFER_PAYLOAD_SIZE),
823 GFP_KERNEL);
824 if (!cmd_buf) {
825 pr_err("No memory is allocated.\n");
826 return -ENOMEM;
827 }
828 pr_debug("----- num_cal_blocks=%d\n", (s32)cal_data.num_cal_blocks);
829 cal_blk = cal_data.cal_blocks;
830 pr_debug("cal_blk =%x\n", (uint32_t)cal_data.cal_blocks);
831
832 for (; index < cal_data.num_cal_blocks; index++) {
833 cal_size_per_network = cal_blk[index].cal_size;
834 pr_debug(" cal size =%d\n", cal_size_per_network);
835 if (cal_size_per_network >= BUFFER_PAYLOAD_SIZE)
836 pr_err("Cal size is too big\n");
837 cal_data_per_network = (u32 *)cal_blk[index].cal_kvaddr;
838 pr_debug(" cal data=%x\n", (uint32_t)cal_data_per_network);
839 cvs_cal_cmd_hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
840 cal_size_per_network);
841 pr_debug("header size =%d, pkt_size =%d\n",
842 APR_HDR_SIZE, cvs_cal_cmd_hdr.pkt_size);
843 memcpy(cmd_buf, &cvs_cal_cmd_hdr, APR_HDR_SIZE);
844 memcpy(cmd_buf + (APR_HDR_SIZE / sizeof(uint32_t)),
845 cal_data_per_network, cal_size_per_network);
846 pr_debug("send cvs cal: index =%d\n", index);
847 v->cvs_state = CMD_STATUS_FAIL;
848 ret = apr_send_pkt(apr_cvs, cmd_buf);
849 if (ret < 0) {
850 pr_err("Fail: sending cvs cal, idx=%d\n", index);
851 continue;
852 }
853 ret = wait_event_timeout(v->cvs_wait,
854 (v->cvs_state == CMD_STATUS_SUCCESS),
855 msecs_to_jiffies(TIMEOUT_MS));
856 if (!ret) {
857 pr_err("%s: wait_event timeout\n", __func__);
858 return -EINVAL;
859 }
860 }
861 kfree(cmd_buf);
862done:
863 return 0;
864}
865
866static int voice_send_cvp_cal_to_modem(struct voice_data *v)
867{
868 struct apr_hdr cvp_cal_cmd_hdr;
869 uint32_t *cmd_buf;
870 struct acdb_cal_data cal_data;
871 struct acdb_cal_block *cal_blk;
872 int32_t cal_size_per_network;
873 uint32_t *cal_data_per_network;
874 int index = 0;
875 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -0700876 void *apr_cvp = voice_get_apr_cvp();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700877 u16 cvp_handle = voice_get_cvp_handle(v);
878
879
880 /* fill the header */
881 cvp_cal_cmd_hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
882 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
883 cvp_cal_cmd_hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
884 sizeof(cvp_cal_cmd_hdr) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -0700885 cvp_cal_cmd_hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700886 cvp_cal_cmd_hdr.dest_port = cvp_handle;
887 cvp_cal_cmd_hdr.token = 0;
888 cvp_cal_cmd_hdr.opcode =
889 VSS_IVOCPROC_CMD_CACHE_CALIBRATION_DATA;
890
891 /* get cal data */
892 get_vocproc_cal(&cal_data);
893 if (cal_data.num_cal_blocks == 0) {
894 pr_err("%s: No calibration data to send!\n", __func__);
895 goto done;
896 }
897
898 /* send cal to modem */
899 cmd_buf = kzalloc((sizeof(struct apr_hdr) + BUFFER_PAYLOAD_SIZE),
900 GFP_KERNEL);
901 if (!cmd_buf) {
902 pr_err("No memory is allocated.\n");
903 return -ENOMEM;
904 }
905 pr_debug("----- num_cal_blocks=%d\n", (s32)cal_data.num_cal_blocks);
906 cal_blk = cal_data.cal_blocks;
907 pr_debug(" cal_blk =%x\n", (uint32_t)cal_data.cal_blocks);
908
909 for (; index < cal_data.num_cal_blocks; index++) {
910 cal_size_per_network = cal_blk[index].cal_size;
911 if (cal_size_per_network >= BUFFER_PAYLOAD_SIZE)
912 pr_err("Cal size is too big\n");
913 pr_debug(" cal size =%d\n", cal_size_per_network);
914 cal_data_per_network = (u32 *)cal_blk[index].cal_kvaddr;
915 pr_debug(" cal data=%x\n", (uint32_t)cal_data_per_network);
916
917 cvp_cal_cmd_hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
918 cal_size_per_network);
919 memcpy(cmd_buf, &cvp_cal_cmd_hdr, APR_HDR_SIZE);
920 memcpy(cmd_buf + (APR_HDR_SIZE / sizeof(*cmd_buf)),
921 cal_data_per_network, cal_size_per_network);
922 pr_debug("Send cvp cal\n");
923 v->cvp_state = CMD_STATUS_FAIL;
924 pr_info("%s: CVP calib\n", __func__);
925 ret = apr_send_pkt(apr_cvp, cmd_buf);
926 if (ret < 0) {
927 pr_err("Fail: sending cvp cal, idx=%d\n", index);
928 continue;
929 }
930 ret = wait_event_timeout(v->cvp_wait,
931 (v->cvp_state == CMD_STATUS_SUCCESS),
932 msecs_to_jiffies(TIMEOUT_MS));
933 if (!ret) {
934 pr_err("%s: wait_event timeout\n", __func__);
935 return -EINVAL;
936 }
937 }
938 kfree(cmd_buf);
939done:
940 return 0;
941}
942
943static int voice_send_cvp_vol_tbl_to_modem(struct voice_data *v)
944{
945 struct apr_hdr cvp_vol_cal_cmd_hdr;
946 uint32_t *cmd_buf;
947 struct acdb_cal_data cal_data;
948 struct acdb_cal_block *cal_blk;
949 int32_t cal_size_per_network;
950 uint32_t *cal_data_per_network;
Ben Rombergerb4f562a2011-07-13 19:57:54 -0700951 uint32_t num_volume_steps;
952 int offset = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700953 int index = 0;
954 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -0700955 void *apr_cvp = voice_get_apr_cvp();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700956 u16 cvp_handle = voice_get_cvp_handle(v);
957
958
959 /* fill the header */
960 cvp_vol_cal_cmd_hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
961 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
962 cvp_vol_cal_cmd_hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
963 sizeof(cvp_vol_cal_cmd_hdr) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -0700964 cvp_vol_cal_cmd_hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700965 cvp_vol_cal_cmd_hdr.dest_port = cvp_handle;
966 cvp_vol_cal_cmd_hdr.token = 0;
967 cvp_vol_cal_cmd_hdr.opcode =
968 VSS_IVOCPROC_CMD_CACHE_VOLUME_CALIBRATION_TABLE;
969
970 /* get cal data */
971 get_vocvol_cal(&cal_data);
972 if (cal_data.num_cal_blocks == 0) {
973 pr_err("%s: No calibration data to send!\n", __func__);
974 goto done;
975 }
976
977 /* send cal to modem */
978 cmd_buf = kzalloc((sizeof(struct apr_hdr) + BUFFER_PAYLOAD_SIZE),
979 GFP_KERNEL);
980 if (!cmd_buf) {
981 pr_err("No memory is allocated.\n");
982 return -ENOMEM;
983 }
984 pr_debug("----- num_cal_blocks=%d\n", (s32)cal_data.num_cal_blocks);
985 cal_blk = cal_data.cal_blocks;
986 pr_debug("Cal_blk =%x\n", (uint32_t)cal_data.cal_blocks);
987
988 for (; index < cal_data.num_cal_blocks; index++) {
989 cal_size_per_network = cal_blk[index].cal_size;
990 cal_data_per_network = (u32 *)cal_blk[index].cal_kvaddr;
Ben Rombergerb4f562a2011-07-13 19:57:54 -0700991
992 /* Number of volume steps are only included in the */
993 /* first block, need to be inserted into the rest */
994 if (index != 0) {
995 offset = sizeof(num_volume_steps);
996 memcpy(cmd_buf + (APR_HDR_SIZE / sizeof(uint32_t)),
997 &num_volume_steps, offset);
998 } else {
999 num_volume_steps = *cal_data_per_network;
1000 }
1001
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001002 pr_debug("Cal size =%d, index=%d\n", cal_size_per_network,
1003 index);
1004 pr_debug("Cal data=%x\n", (uint32_t)cal_data_per_network);
1005 cvp_vol_cal_cmd_hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
Ben Rombergerb4f562a2011-07-13 19:57:54 -07001006 cal_size_per_network + offset);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001007 memcpy(cmd_buf, &cvp_vol_cal_cmd_hdr, APR_HDR_SIZE);
Ben Rombergerb4f562a2011-07-13 19:57:54 -07001008 memcpy(cmd_buf + (APR_HDR_SIZE / sizeof(uint32_t)) +
1009 offset, cal_data_per_network, cal_size_per_network);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001010 pr_debug("Send vol table\n");
1011
1012 v->cvp_state = CMD_STATUS_FAIL;
1013 ret = apr_send_pkt(apr_cvp, cmd_buf);
1014 if (ret < 0) {
1015 pr_err("Fail: sending cvp vol cal, idx=%d\n", index);
1016 continue;
1017 }
1018 ret = wait_event_timeout(v->cvp_wait,
1019 (v->cvp_state == CMD_STATUS_SUCCESS),
1020 msecs_to_jiffies(TIMEOUT_MS));
1021 if (!ret) {
1022 pr_err("%s: wait_event timeout\n", __func__);
1023 return -EINVAL;
1024 }
1025 }
1026 kfree(cmd_buf);
1027done:
1028 return 0;
1029}
1030
1031static int voice_set_dtx(struct voice_data *v)
1032{
1033 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001034 void *apr_cvs = voice_get_apr_cvs();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001035 u16 cvs_handle = voice_get_cvs_handle(v);
1036
1037 /* Set DTX */
1038 struct cvs_set_enc_dtx_mode_cmd cvs_set_dtx = {
1039 .hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1040 APR_HDR_LEN(APR_HDR_SIZE),
1041 APR_PKT_VER),
1042 .hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1043 sizeof(cvs_set_dtx) - APR_HDR_SIZE),
Neema Shetty90189b82011-06-27 14:58:37 -07001044 .hdr.src_port = v->session_id,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001045 .hdr.dest_port = cvs_handle,
1046 .hdr.token = 0,
1047 .hdr.opcode = VSS_ISTREAM_CMD_SET_ENC_DTX_MODE,
Neema Shetty90189b82011-06-27 14:58:37 -07001048 .dtx_mode.enable = common.mvs_info.dtx_mode,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001049 };
1050
Neema Shetty90189b82011-06-27 14:58:37 -07001051 pr_debug("%s: Setting DTX %d\n", __func__, common.mvs_info.dtx_mode);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001052
1053 v->cvs_state = CMD_STATUS_FAIL;
1054
1055 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_dtx);
1056 if (ret < 0) {
1057 pr_err("%s: Error %d sending SET_DTX\n", __func__, ret);
1058
1059 goto done;
1060 }
1061
1062 ret = wait_event_timeout(v->cvs_wait,
1063 (v->cvs_state == CMD_STATUS_SUCCESS),
1064 msecs_to_jiffies(TIMEOUT_MS));
1065 if (!ret) {
1066 pr_err("%s: wait_event timeout\n", __func__);
1067
1068 ret = -EINVAL;
1069 }
1070
1071done:
1072 return ret;
1073}
1074
1075static int voice_config_cvs_vocoder(struct voice_data *v)
1076{
1077 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001078 void *apr_cvs = voice_get_apr_cvs();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001079 u16 cvs_handle = voice_get_cvs_handle(v);
1080
1081 /* Set media type. */
1082 struct cvs_set_media_type_cmd cvs_set_media_cmd;
1083
1084 pr_info("%s: Setting media type\n", __func__);
1085
1086 cvs_set_media_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1087 APR_HDR_LEN(APR_HDR_SIZE),
1088 APR_PKT_VER);
1089 cvs_set_media_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1090 sizeof(cvs_set_media_cmd) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001091 cvs_set_media_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001092 cvs_set_media_cmd.hdr.dest_port = cvs_handle;
1093 cvs_set_media_cmd.hdr.token = 0;
1094 cvs_set_media_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_MEDIA_TYPE;
Neema Shetty90189b82011-06-27 14:58:37 -07001095 cvs_set_media_cmd.media_type.tx_media_id = common.mvs_info.media_type;
1096 cvs_set_media_cmd.media_type.rx_media_id = common.mvs_info.media_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001097
1098 v->cvs_state = CMD_STATUS_FAIL;
1099
1100 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_media_cmd);
1101 if (ret < 0) {
1102 pr_err("%s: Error %d sending SET_MEDIA_TYPE\n",
1103 __func__, ret);
1104
1105 goto done;
1106 }
1107
1108 ret = wait_event_timeout(v->cvs_wait,
1109 (v->cvs_state == CMD_STATUS_SUCCESS),
1110 msecs_to_jiffies(TIMEOUT_MS));
1111 if (!ret) {
1112 pr_err("%s: wait_event timeout\n", __func__);
1113
1114 ret = -EINVAL;
1115 goto done;
1116 }
1117
1118 /* Set encoder properties. */
Neema Shetty90189b82011-06-27 14:58:37 -07001119 switch (common.mvs_info.media_type) {
Chaithanya Krishna Bacharaju68993b52011-10-18 08:41:30 +05301120 case VSS_MEDIA_ID_13K_MODEM:
Chaithanya Krishna Bacharaju2f2e8a52011-10-17 14:54:07 +05301121 case VSS_MEDIA_ID_4GV_NB_MODEM:
1122 case VSS_MEDIA_ID_4GV_WB_MODEM:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001123 case VSS_MEDIA_ID_EVRC_MODEM: {
1124 struct cvs_set_cdma_enc_minmax_rate_cmd cvs_set_cdma_rate;
1125
Chaithanya Krishna Bacharaju2f2e8a52011-10-17 14:54:07 +05301126 pr_info("%s: Setting CDMA min-max rate\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001127
1128 cvs_set_cdma_rate.hdr.hdr_field =
1129 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1130 APR_HDR_LEN(APR_HDR_SIZE),
1131 APR_PKT_VER);
1132 cvs_set_cdma_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1133 sizeof(cvs_set_cdma_rate) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001134 cvs_set_cdma_rate.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001135 cvs_set_cdma_rate.hdr.dest_port = cvs_handle;
1136 cvs_set_cdma_rate.hdr.token = 0;
1137 cvs_set_cdma_rate.hdr.opcode =
1138 VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE;
Chaithanya Krishna Bacharaju2f2e8a52011-10-17 14:54:07 +05301139 cvs_set_cdma_rate.cdma_rate.min_rate =
1140 common.mvs_info.q_min_max_rate.min_rate;
1141 cvs_set_cdma_rate.cdma_rate.max_rate =
1142 common.mvs_info.q_min_max_rate.max_rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001143
1144 v->cvs_state = CMD_STATUS_FAIL;
1145
1146 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_cdma_rate);
1147 if (ret < 0) {
Chaithanya Krishna Bacharaju2f2e8a52011-10-17 14:54:07 +05301148 pr_err("%s: Error %d sending CDMA_SET_ENC_MINMAX_RATE\n",
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001149 __func__, ret);
1150
1151 goto done;
1152 }
1153
1154 ret = wait_event_timeout(v->cvs_wait,
1155 (v->cvs_state == CMD_STATUS_SUCCESS),
1156 msecs_to_jiffies(TIMEOUT_MS));
1157 if (!ret) {
1158 pr_err("%s: wait_event timeout\n", __func__);
1159
1160 ret = -EINVAL;
1161 goto done;
1162 }
1163
Chaithanya Krishna Bacharaju2f2e8a52011-10-17 14:54:07 +05301164 if ((common.mvs_info.media_type == VSS_MEDIA_ID_4GV_NB_MODEM) ||
1165 (common.mvs_info.media_type == VSS_MEDIA_ID_4GV_WB_MODEM))
1166 ret = voice_set_dtx(v);
1167
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001168 break;
1169 }
1170
1171 case VSS_MEDIA_ID_AMR_NB_MODEM: {
1172 struct cvs_set_amr_enc_rate_cmd cvs_set_amr_rate;
1173
1174 pr_info("%s: Setting AMR rate\n", __func__);
1175
1176 cvs_set_amr_rate.hdr.hdr_field =
1177 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1178 APR_HDR_LEN(APR_HDR_SIZE),
1179 APR_PKT_VER);
1180 cvs_set_amr_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1181 sizeof(cvs_set_amr_rate) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001182 cvs_set_amr_rate.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001183 cvs_set_amr_rate.hdr.dest_port = cvs_handle;
1184 cvs_set_amr_rate.hdr.token = 0;
1185 cvs_set_amr_rate.hdr.opcode =
1186 VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE;
Neema Shetty90189b82011-06-27 14:58:37 -07001187 cvs_set_amr_rate.amr_rate.mode = common.mvs_info.rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001188
1189 v->cvs_state = CMD_STATUS_FAIL;
1190
1191 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_amr_rate);
1192 if (ret < 0) {
1193 pr_err("%s: Error %d sending SET_AMR_RATE\n",
1194 __func__, ret);
1195
1196 goto done;
1197 }
1198
1199 ret = wait_event_timeout(v->cvs_wait,
1200 (v->cvs_state == CMD_STATUS_SUCCESS),
1201 msecs_to_jiffies(TIMEOUT_MS));
1202 if (!ret) {
1203 pr_err("%s: wait_event timeout\n", __func__);
1204
1205 ret = -EINVAL;
1206 goto done;
1207 }
1208
1209 ret = voice_set_dtx(v);
1210
1211 break;
1212 }
1213
1214 case VSS_MEDIA_ID_AMR_WB_MODEM: {
1215 struct cvs_set_amrwb_enc_rate_cmd cvs_set_amrwb_rate;
1216
1217 pr_info("%s: Setting AMR WB rate\n", __func__);
1218
1219 cvs_set_amrwb_rate.hdr.hdr_field =
1220 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1221 APR_HDR_LEN(APR_HDR_SIZE),
1222 APR_PKT_VER);
1223 cvs_set_amrwb_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1224 sizeof(cvs_set_amrwb_rate) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001225 cvs_set_amrwb_rate.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001226 cvs_set_amrwb_rate.hdr.dest_port = cvs_handle;
1227 cvs_set_amrwb_rate.hdr.token = 0;
1228 cvs_set_amrwb_rate.hdr.opcode =
1229 VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE;
Neema Shetty90189b82011-06-27 14:58:37 -07001230 cvs_set_amrwb_rate.amrwb_rate.mode = common.mvs_info.rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001231
1232 v->cvs_state = CMD_STATUS_FAIL;
1233
1234 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_amrwb_rate);
1235 if (ret < 0) {
1236 pr_err("%s: Error %d sending SET_AMRWB_RATE\n",
1237 __func__, ret);
1238
1239 goto done;
1240 }
1241
1242 ret = wait_event_timeout(v->cvs_wait,
1243 (v->cvs_state == CMD_STATUS_SUCCESS),
1244 msecs_to_jiffies(TIMEOUT_MS));
1245 if (!ret) {
1246 pr_err("%s: wait_event timeout\n", __func__);
1247
1248 ret = -EINVAL;
1249 goto done;
1250 }
1251
1252 ret = voice_set_dtx(v);
1253
1254 break;
1255 }
1256
Chaithanya Krishna Bacharaju68993b52011-10-18 08:41:30 +05301257 case VSS_MEDIA_ID_EFR_MODEM:
1258 case VSS_MEDIA_ID_FR_MODEM:
1259 case VSS_MEDIA_ID_HR_MODEM:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001260 case VSS_MEDIA_ID_G729:
1261 case VSS_MEDIA_ID_G711_ALAW:
1262 case VSS_MEDIA_ID_G711_MULAW: {
1263 ret = voice_set_dtx(v);
1264
1265 break;
1266 }
1267
1268 default: {
1269 /* Do nothing. */
1270 }
1271 }
1272
1273done:
1274 return ret;
1275}
1276
1277static int voice_send_start_voice_cmd(struct voice_data *v)
1278{
1279 struct apr_hdr mvm_start_voice_cmd;
1280 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001281 void *apr_mvm = voice_get_apr_mvm();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001282 u16 mvm_handle = voice_get_mvm_handle(v);
1283
1284 mvm_start_voice_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1285 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1286 mvm_start_voice_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1287 sizeof(mvm_start_voice_cmd) - APR_HDR_SIZE);
1288 pr_info("send mvm_start_voice_cmd pkt size = %d\n",
1289 mvm_start_voice_cmd.pkt_size);
Neema Shetty90189b82011-06-27 14:58:37 -07001290 mvm_start_voice_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001291 mvm_start_voice_cmd.dest_port = mvm_handle;
1292 mvm_start_voice_cmd.token = 0;
1293 mvm_start_voice_cmd.opcode = VSS_IMVM_CMD_START_VOICE;
1294
1295 v->mvm_state = CMD_STATUS_FAIL;
1296 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_start_voice_cmd);
1297 if (ret < 0) {
1298 pr_err("Fail in sending VSS_IMVM_CMD_START_VOICE\n");
1299 goto fail;
1300 }
1301 ret = wait_event_timeout(v->mvm_wait,
1302 (v->mvm_state == CMD_STATUS_SUCCESS),
1303 msecs_to_jiffies(TIMEOUT_MS));
1304 if (!ret) {
1305 pr_err("%s: wait_event timeout\n", __func__);
1306 goto fail;
1307 }
1308
1309 return 0;
1310fail:
1311 return -EINVAL;
1312}
1313
1314static int voice_disable_vocproc(struct voice_data *v)
1315{
1316 struct apr_hdr cvp_disable_cmd;
1317 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001318 void *apr_cvp = voice_get_apr_cvp();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001319 u16 cvp_handle = voice_get_cvp_handle(v);
1320
1321 /* disable vocproc and wait for respose */
1322 cvp_disable_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1323 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1324 cvp_disable_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1325 sizeof(cvp_disable_cmd) - APR_HDR_SIZE);
1326 pr_debug("cvp_disable_cmd pkt size = %d, cvp_handle=%d\n",
1327 cvp_disable_cmd.pkt_size, cvp_handle);
Neema Shetty90189b82011-06-27 14:58:37 -07001328 cvp_disable_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001329 cvp_disable_cmd.dest_port = cvp_handle;
1330 cvp_disable_cmd.token = 0;
1331 cvp_disable_cmd.opcode = VSS_IVOCPROC_CMD_DISABLE;
1332
1333 v->cvp_state = CMD_STATUS_FAIL;
1334 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_disable_cmd);
1335 if (ret < 0) {
1336 pr_err("Fail in sending VSS_IVOCPROC_CMD_DISABLE\n");
1337 goto fail;
1338 }
1339 ret = wait_event_timeout(v->cvp_wait,
1340 (v->cvp_state == CMD_STATUS_SUCCESS),
1341 msecs_to_jiffies(TIMEOUT_MS));
1342 if (!ret) {
1343 pr_err("%s: wait_event timeout\n", __func__);
1344 goto fail;
1345 }
Ben Rombergerfce8f512011-07-18 16:46:09 -07001346 rtac_remove_voice(v->cvs_handle);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001347
1348 return 0;
1349fail:
1350 return -EINVAL;
1351}
1352
1353static int voice_set_device(struct voice_data *v)
1354{
1355 struct cvp_set_device_cmd cvp_setdev_cmd;
1356 struct msm_snddev_info *dev_tx_info;
1357 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001358 void *apr_cvp = voice_get_apr_cvp();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001359 u16 cvp_handle = voice_get_cvp_handle(v);
1360
1361
1362 /* set device and wait for response */
1363 cvp_setdev_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1364 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1365 cvp_setdev_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1366 sizeof(cvp_setdev_cmd) - APR_HDR_SIZE);
1367 pr_debug(" send create cvp setdev, pkt size = %d\n",
1368 cvp_setdev_cmd.hdr.pkt_size);
Neema Shetty90189b82011-06-27 14:58:37 -07001369 cvp_setdev_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001370 cvp_setdev_cmd.hdr.dest_port = cvp_handle;
1371 cvp_setdev_cmd.hdr.token = 0;
1372 cvp_setdev_cmd.hdr.opcode = VSS_IVOCPROC_CMD_SET_DEVICE;
1373
1374 dev_tx_info = audio_dev_ctrl_find_dev(v->dev_tx.dev_id);
1375 if (IS_ERR(dev_tx_info)) {
1376 pr_err("bad dev_id %d\n", v->dev_tx.dev_id);
1377 goto fail;
1378 }
1379
1380 cvp_setdev_cmd.cvp_set_device.tx_topology_id =
1381 get_voice_tx_topology();
1382 if (cvp_setdev_cmd.cvp_set_device.tx_topology_id == 0) {
1383 if (dev_tx_info->channel_mode > 1)
1384 cvp_setdev_cmd.cvp_set_device.tx_topology_id =
1385 VSS_IVOCPROC_TOPOLOGY_ID_TX_DM_FLUENCE;
1386 else
1387 cvp_setdev_cmd.cvp_set_device.tx_topology_id =
1388 VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
1389 }
1390
1391 /* Use default topology if invalid value in ACDB */
1392 cvp_setdev_cmd.cvp_set_device.rx_topology_id =
1393 get_voice_rx_topology();
1394 if (cvp_setdev_cmd.cvp_set_device.rx_topology_id == 0)
1395 cvp_setdev_cmd.cvp_set_device.rx_topology_id =
1396 VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
1397 cvp_setdev_cmd.cvp_set_device.tx_port_id = v->dev_tx.dev_port_id;
1398 cvp_setdev_cmd.cvp_set_device.rx_port_id = v->dev_rx.dev_port_id;
1399 pr_info("topology=%d , tx_port_id=%d, rx_port_id=%d\n",
1400 cvp_setdev_cmd.cvp_set_device.tx_topology_id,
1401 cvp_setdev_cmd.cvp_set_device.tx_port_id,
1402 cvp_setdev_cmd.cvp_set_device.rx_port_id);
1403
1404 v->cvp_state = CMD_STATUS_FAIL;
1405 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_setdev_cmd);
1406 if (ret < 0) {
1407 pr_err("Fail in sending VOCPROC_FULL_CONTROL_SESSION\n");
1408 goto fail;
1409 }
1410 pr_debug("wait for cvp create session event\n");
1411 ret = wait_event_timeout(v->cvp_wait,
1412 (v->cvp_state == CMD_STATUS_SUCCESS),
1413 msecs_to_jiffies(TIMEOUT_MS));
1414 if (!ret) {
1415 pr_err("%s: wait_event timeout\n", __func__);
1416 goto fail;
1417 }
1418
1419 /* send cvs cal */
1420 voice_send_cvs_cal_to_modem(v);
1421
1422 /* send cvp cal */
1423 voice_send_cvp_cal_to_modem(v);
1424
1425 /* send cvp vol table cal */
1426 voice_send_cvp_vol_tbl_to_modem(v);
1427
1428 /* enable vocproc and wait for respose */
1429 voice_send_enable_vocproc_cmd(v);
1430
1431 /* send tty mode if tty device is used */
1432 voice_send_tty_mode_to_modem(v);
1433
Neema Shetty90189b82011-06-27 14:58:37 -07001434 if (is_voip_session(v->session_id))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001435 voice_send_netid_timing_cmd(v);
1436
Ben Rombergerfce8f512011-07-18 16:46:09 -07001437 rtac_add_voice(v->cvs_handle, v->cvp_handle,
Ben Rombergerc5d6a372011-09-22 18:01:49 -07001438 v->dev_rx.dev_port_id, v->dev_tx.dev_port_id,
1439 v->session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001440
1441 return 0;
1442fail:
1443 return -EINVAL;
1444}
1445
1446static int voice_send_stop_voice_cmd(struct voice_data *v)
1447{
1448 struct apr_hdr mvm_stop_voice_cmd;
1449 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001450 void *apr_mvm = voice_get_apr_mvm();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001451 u16 mvm_handle = voice_get_mvm_handle(v);
1452
1453 mvm_stop_voice_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1454 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1455 mvm_stop_voice_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1456 sizeof(mvm_stop_voice_cmd) - APR_HDR_SIZE);
1457 pr_info("send mvm_stop_voice_cmd pkt size = %d\n",
1458 mvm_stop_voice_cmd.pkt_size);
Neema Shetty90189b82011-06-27 14:58:37 -07001459 mvm_stop_voice_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001460 mvm_stop_voice_cmd.dest_port = mvm_handle;
1461 mvm_stop_voice_cmd.token = 0;
1462 mvm_stop_voice_cmd.opcode = VSS_IMVM_CMD_STOP_VOICE;
1463
1464 v->mvm_state = CMD_STATUS_FAIL;
1465 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_stop_voice_cmd);
1466 if (ret < 0) {
1467 pr_err("Fail in sending VSS_IMVM_CMD_STOP_VOICE\n");
1468 goto fail;
1469 }
1470 ret = wait_event_timeout(v->mvm_wait,
1471 (v->mvm_state == CMD_STATUS_SUCCESS),
1472 msecs_to_jiffies(TIMEOUT_MS));
1473 if (!ret) {
1474 pr_err("%s: wait_event timeout\n", __func__);
1475 goto fail;
1476 }
1477
1478 return 0;
1479fail:
1480 return -EINVAL;
1481}
1482
1483static int voice_setup_modem_voice(struct voice_data *v)
1484{
1485 struct cvp_create_full_ctl_session_cmd cvp_session_cmd;
1486 int ret = 0;
1487 struct msm_snddev_info *dev_tx_info;
Neema Shetty90189b82011-06-27 14:58:37 -07001488 void *apr_cvp = voice_get_apr_cvp();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001489
1490 /* create cvp session and wait for response */
1491 cvp_session_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1492 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1493 cvp_session_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1494 sizeof(cvp_session_cmd) - APR_HDR_SIZE);
1495 pr_info(" send create cvp session, pkt size = %d\n",
1496 cvp_session_cmd.hdr.pkt_size);
Neema Shetty90189b82011-06-27 14:58:37 -07001497 cvp_session_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001498 cvp_session_cmd.hdr.dest_port = 0;
1499 cvp_session_cmd.hdr.token = 0;
1500 cvp_session_cmd.hdr.opcode =
1501 VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION;
1502
1503 dev_tx_info = audio_dev_ctrl_find_dev(v->dev_tx.dev_id);
1504 if (IS_ERR(dev_tx_info)) {
1505 pr_err("bad dev_id %d\n", v->dev_tx.dev_id);
1506 goto fail;
1507 }
1508
1509 /* Use default topology if invalid value in ACDB */
1510 cvp_session_cmd.cvp_session.tx_topology_id =
1511 get_voice_tx_topology();
1512 if (cvp_session_cmd.cvp_session.tx_topology_id == 0) {
1513 if (dev_tx_info->channel_mode > 1)
1514 cvp_session_cmd.cvp_session.tx_topology_id =
1515 VSS_IVOCPROC_TOPOLOGY_ID_TX_DM_FLUENCE;
1516 else
1517 cvp_session_cmd.cvp_session.tx_topology_id =
1518 VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
1519 }
1520
1521 cvp_session_cmd.cvp_session.rx_topology_id =
1522 get_voice_rx_topology();
1523 if (cvp_session_cmd.cvp_session.rx_topology_id == 0)
1524 cvp_session_cmd.cvp_session.rx_topology_id =
1525 VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
1526
1527 cvp_session_cmd.cvp_session.direction = 2; /*tx and rx*/
1528 cvp_session_cmd.cvp_session.network_id = VSS_NETWORK_ID_DEFAULT;
1529 cvp_session_cmd.cvp_session.tx_port_id = v->dev_tx.dev_port_id;
1530 cvp_session_cmd.cvp_session.rx_port_id = v->dev_rx.dev_port_id;
1531 pr_info("topology=%d net_id=%d, dir=%d tx_port_id=%d, rx_port_id=%d\n",
1532 cvp_session_cmd.cvp_session.tx_topology_id,
1533 cvp_session_cmd.cvp_session.network_id,
1534 cvp_session_cmd.cvp_session.direction,
1535 cvp_session_cmd.cvp_session.tx_port_id,
1536 cvp_session_cmd.cvp_session.rx_port_id);
1537
1538 v->cvp_state = CMD_STATUS_FAIL;
1539 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_session_cmd);
1540 if (ret < 0) {
1541 pr_err("Fail in sending VOCPROC_FULL_CONTROL_SESSION\n");
1542 goto fail;
1543 }
1544 pr_debug("wait for cvp create session event\n");
1545 ret = wait_event_timeout(v->cvp_wait,
1546 (v->cvp_state == CMD_STATUS_SUCCESS),
1547 msecs_to_jiffies(TIMEOUT_MS));
1548 if (!ret) {
1549 pr_err("%s: wait_event timeout\n", __func__);
1550 goto fail;
1551 }
1552
1553 /* send cvs cal */
1554 voice_send_cvs_cal_to_modem(v);
1555
1556 /* send cvp cal */
1557 voice_send_cvp_cal_to_modem(v);
1558
1559 /* send cvp vol table cal */
1560 voice_send_cvp_vol_tbl_to_modem(v);
1561
1562 return 0;
1563
1564fail:
1565 return -EINVAL;
1566}
1567
1568static int voice_send_enable_vocproc_cmd(struct voice_data *v)
1569{
1570 int ret = 0;
1571 struct apr_hdr cvp_enable_cmd;
1572
1573 u16 cvp_handle = voice_get_cvp_handle(v);
Neema Shetty90189b82011-06-27 14:58:37 -07001574 void *apr_cvp = voice_get_apr_cvp();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001575
1576 /* enable vocproc and wait for respose */
1577 cvp_enable_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1578 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1579 cvp_enable_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1580 sizeof(cvp_enable_cmd) - APR_HDR_SIZE);
1581 pr_debug("cvp_enable_cmd pkt size = %d, cvp_handle=%d\n",
1582 cvp_enable_cmd.pkt_size, cvp_handle);
Neema Shetty90189b82011-06-27 14:58:37 -07001583 cvp_enable_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001584 cvp_enable_cmd.dest_port = cvp_handle;
1585 cvp_enable_cmd.token = 0;
1586 cvp_enable_cmd.opcode = VSS_IVOCPROC_CMD_ENABLE;
1587
1588 v->cvp_state = CMD_STATUS_FAIL;
1589 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_enable_cmd);
1590 if (ret < 0) {
1591 pr_err("Fail in sending VSS_IVOCPROC_CMD_ENABLE\n");
1592 goto fail;
1593 }
1594 ret = wait_event_timeout(v->cvp_wait,
1595 (v->cvp_state == CMD_STATUS_SUCCESS),
1596 msecs_to_jiffies(TIMEOUT_MS));
1597 if (!ret) {
1598 pr_err("%s: wait_event timeout\n", __func__);
1599 goto fail;
1600 }
1601
1602 return 0;
1603fail:
1604 return -EINVAL;
1605}
1606
1607static int voice_send_netid_timing_cmd(struct voice_data *v)
1608{
1609 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001610 void *apr_mvm = voice_get_apr_mvm();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001611 struct mvm_set_network_cmd mvm_set_network;
1612 struct mvm_set_voice_timing_cmd mvm_set_voice_timing;
1613 u16 mvm_handle = voice_get_mvm_handle(v);
1614
1615 ret = voice_config_cvs_vocoder(v);
1616 if (ret < 0) {
1617 pr_err("%s: Error %d configuring CVS voc",
1618 __func__, ret);
1619 goto fail;
1620 }
1621 /* Set network ID. */
1622 pr_debug("%s: Setting network ID\n", __func__);
1623
1624 mvm_set_network.hdr.hdr_field =
1625 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1626 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1627 mvm_set_network.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1628 sizeof(mvm_set_network) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001629 mvm_set_network.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001630 mvm_set_network.hdr.dest_port = mvm_handle;
1631 mvm_set_network.hdr.token = 0;
1632 mvm_set_network.hdr.opcode = VSS_ICOMMON_CMD_SET_NETWORK;
Neema Shetty90189b82011-06-27 14:58:37 -07001633 mvm_set_network.network.network_id = common.mvs_info.network_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001634
1635 v->mvm_state = CMD_STATUS_FAIL;
1636 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_network);
1637 if (ret < 0) {
1638 pr_err("%s: Error %d sending SET_NETWORK\n", __func__, ret);
1639 goto fail;
1640 }
1641
1642 ret = wait_event_timeout(v->mvm_wait,
1643 (v->mvm_state == CMD_STATUS_SUCCESS),
1644 msecs_to_jiffies(TIMEOUT_MS));
1645 if (!ret) {
1646 pr_err("%s: wait_event timeout\n", __func__);
1647 goto fail;
1648 }
1649
1650 /* Set voice timing. */
1651 pr_debug("%s: Setting voice timing\n", __func__);
1652
1653 mvm_set_voice_timing.hdr.hdr_field =
1654 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1655 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1656 mvm_set_voice_timing.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1657 sizeof(mvm_set_voice_timing) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001658 mvm_set_voice_timing.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001659 mvm_set_voice_timing.hdr.dest_port = mvm_handle;
1660 mvm_set_voice_timing.hdr.token = 0;
1661 mvm_set_voice_timing.hdr.opcode =
1662 VSS_ICOMMON_CMD_SET_VOICE_TIMING;
1663 mvm_set_voice_timing.timing.mode = 0;
1664 mvm_set_voice_timing.timing.enc_offset = 8000;
1665 mvm_set_voice_timing.timing.dec_req_offset = 3300;
1666 mvm_set_voice_timing.timing.dec_offset = 8300;
1667
1668 v->mvm_state = CMD_STATUS_FAIL;
1669
1670 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_voice_timing);
1671 if (ret < 0) {
1672 pr_err("%s: Error %d sending SET_TIMING\n", __func__, ret);
1673 goto fail;
1674 }
1675
1676 ret = wait_event_timeout(v->mvm_wait,
1677 (v->mvm_state == CMD_STATUS_SUCCESS),
1678 msecs_to_jiffies(TIMEOUT_MS));
1679 if (!ret) {
1680 pr_err("%s: wait_event timeout\n", __func__);
1681 goto fail;
1682 }
1683
1684 return 0;
1685fail:
1686 return -EINVAL;
1687}
1688
1689static int voice_attach_vocproc(struct voice_data *v)
1690{
1691 int ret = 0;
1692 struct mvm_attach_vocproc_cmd mvm_a_vocproc_cmd;
Neema Shetty90189b82011-06-27 14:58:37 -07001693 void *apr_mvm = voice_get_apr_mvm();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001694 u16 mvm_handle = voice_get_mvm_handle(v);
1695 u16 cvp_handle = voice_get_cvp_handle(v);
1696
1697 /* send enable vocproc */
1698 voice_send_enable_vocproc_cmd(v);
1699
1700 /* attach vocproc and wait for response */
1701 mvm_a_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1702 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1703 mvm_a_vocproc_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1704 sizeof(mvm_a_vocproc_cmd) - APR_HDR_SIZE);
1705 pr_info("send mvm_a_vocproc_cmd pkt size = %d\n",
1706 mvm_a_vocproc_cmd.hdr.pkt_size);
Neema Shetty90189b82011-06-27 14:58:37 -07001707 mvm_a_vocproc_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001708 mvm_a_vocproc_cmd.hdr.dest_port = mvm_handle;
1709 mvm_a_vocproc_cmd.hdr.token = 0;
Neema Shetty7e4a9b52011-07-26 15:24:51 -07001710 mvm_a_vocproc_cmd.hdr.opcode = VSS_ISTREAM_CMD_ATTACH_VOCPROC;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001711 mvm_a_vocproc_cmd.mvm_attach_cvp_handle.handle = cvp_handle;
1712
1713 v->mvm_state = CMD_STATUS_FAIL;
1714 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_a_vocproc_cmd);
1715 if (ret < 0) {
Neema Shetty7e4a9b52011-07-26 15:24:51 -07001716 pr_err("Fail in sending VSS_ISTREAM_CMD_ATTACH_VOCPROC\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001717 goto fail;
1718 }
1719 ret = wait_event_timeout(v->mvm_wait,
1720 (v->mvm_state == CMD_STATUS_SUCCESS),
1721 msecs_to_jiffies(TIMEOUT_MS));
1722 if (!ret) {
1723 pr_err("%s: wait_event timeout\n", __func__);
1724 goto fail;
1725 }
1726
1727 /* send tty mode if tty device is used */
1728 voice_send_tty_mode_to_modem(v);
1729
Neema Shetty90189b82011-06-27 14:58:37 -07001730 if (is_voip_session(v->session_id))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001731 voice_send_netid_timing_cmd(v);
1732
Ben Rombergerfce8f512011-07-18 16:46:09 -07001733 rtac_add_voice(v->cvs_handle, v->cvp_handle,
Ben Rombergerc5d6a372011-09-22 18:01:49 -07001734 v->dev_rx.dev_port_id, v->dev_tx.dev_port_id,
1735 v->session_id);
Ben Rombergerfce8f512011-07-18 16:46:09 -07001736
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001737 return 0;
1738fail:
1739 return -EINVAL;
1740}
1741
1742static int voice_destroy_modem_voice(struct voice_data *v)
1743{
1744 struct mvm_detach_vocproc_cmd mvm_d_vocproc_cmd;
1745 struct apr_hdr cvp_destroy_session_cmd;
1746 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001747 void *apr_mvm = voice_get_apr_mvm();
1748 void *apr_cvp = voice_get_apr_cvp();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001749 u16 mvm_handle = voice_get_mvm_handle(v);
1750 u16 cvp_handle = voice_get_cvp_handle(v);
1751
1752 /* detach VOCPROC and wait for response from mvm */
1753 mvm_d_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1754 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1755 mvm_d_vocproc_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1756 sizeof(mvm_d_vocproc_cmd) - APR_HDR_SIZE);
1757 pr_info("mvm_d_vocproc_cmd pkt size = %d\n",
1758 mvm_d_vocproc_cmd.hdr.pkt_size);
Neema Shetty90189b82011-06-27 14:58:37 -07001759 mvm_d_vocproc_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001760 mvm_d_vocproc_cmd.hdr.dest_port = mvm_handle;
1761 mvm_d_vocproc_cmd.hdr.token = 0;
Neema Shetty7e4a9b52011-07-26 15:24:51 -07001762 mvm_d_vocproc_cmd.hdr.opcode = VSS_ISTREAM_CMD_DETACH_VOCPROC;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001763 mvm_d_vocproc_cmd.mvm_detach_cvp_handle.handle = cvp_handle;
1764
1765 v->mvm_state = CMD_STATUS_FAIL;
1766 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_d_vocproc_cmd);
1767 if (ret < 0) {
Neema Shetty7e4a9b52011-07-26 15:24:51 -07001768 pr_err("Fail in sending VSS_ISTREAM_CMD_DETACH_VOCPROC\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001769 goto fail;
1770 }
1771 ret = wait_event_timeout(v->mvm_wait,
1772 (v->mvm_state == CMD_STATUS_SUCCESS),
1773 msecs_to_jiffies(TIMEOUT_MS));
1774 if (!ret) {
1775 pr_err("%s: wait_event timeout\n", __func__);
1776 goto fail;
1777 }
1778
1779 /* destrop cvp session */
1780 cvp_destroy_session_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1781 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1782 cvp_destroy_session_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1783 sizeof(cvp_destroy_session_cmd) - APR_HDR_SIZE);
1784 pr_info("cvp_destroy_session_cmd pkt size = %d\n",
1785 cvp_destroy_session_cmd.pkt_size);
Neema Shetty90189b82011-06-27 14:58:37 -07001786 cvp_destroy_session_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001787 cvp_destroy_session_cmd.dest_port = cvp_handle;
1788 cvp_destroy_session_cmd.token = 0;
1789 cvp_destroy_session_cmd.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
1790
1791 v->cvp_state = CMD_STATUS_FAIL;
1792 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_destroy_session_cmd);
1793 if (ret < 0) {
1794 pr_err("Fail in sending APRV2_IBASIC_CMD_DESTROY_SESSION\n");
1795 goto fail;
1796 }
1797 ret = wait_event_timeout(v->cvp_wait,
1798 (v->cvp_state == CMD_STATUS_SUCCESS),
1799 msecs_to_jiffies(TIMEOUT_MS));
1800 if (!ret) {
1801 pr_err("%s: wait_event timeout\n", __func__);
1802 goto fail;
1803 }
Ben Rombergerfce8f512011-07-18 16:46:09 -07001804 rtac_remove_voice(v->cvs_handle);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001805 cvp_handle = 0;
1806 voice_set_cvp_handle(v, cvp_handle);
1807
1808 return 0;
1809
1810fail:
1811 return -EINVAL;
1812}
1813
1814static int voice_send_mute_cmd_to_modem(struct voice_data *v)
1815{
1816 struct cvs_set_mute_cmd cvs_mute_cmd;
1817 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001818 void *apr_cvs = voice_get_apr_cvs();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001819 u16 cvs_handle = voice_get_cvs_handle(v);
1820
1821 /* send mute/unmute to cvs */
1822 cvs_mute_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1823 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1824 cvs_mute_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1825 sizeof(cvs_mute_cmd) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001826 cvs_mute_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001827 cvs_mute_cmd.hdr.dest_port = cvs_handle;
1828 cvs_mute_cmd.hdr.token = 0;
1829 cvs_mute_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_MUTE;
1830 cvs_mute_cmd.cvs_set_mute.direction = 0; /*tx*/
1831 cvs_mute_cmd.cvs_set_mute.mute_flag = v->dev_tx.mute;
1832
1833 pr_info(" mute value =%d\n", cvs_mute_cmd.cvs_set_mute.mute_flag);
1834 v->cvs_state = CMD_STATUS_FAIL;
1835 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_mute_cmd);
1836 if (ret < 0) {
1837 pr_err("Fail: send STREAM SET MUTE\n");
1838 goto fail;
1839 }
1840 ret = wait_event_timeout(v->cvs_wait,
1841 (v->cvs_state == CMD_STATUS_SUCCESS),
1842 msecs_to_jiffies(TIMEOUT_MS));
1843 if (!ret)
1844 pr_err("%s: wait_event timeout\n", __func__);
1845
1846fail:
1847 return 0;
1848}
1849
1850static int voice_send_vol_index_to_modem(struct voice_data *v)
1851{
1852 struct cvp_set_rx_volume_index_cmd cvp_vol_cmd;
1853 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001854 void *apr_cvp = voice_get_apr_cvp();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001855 u16 cvp_handle = voice_get_cvp_handle(v);
1856
1857 /* send volume index to cvp */
1858 cvp_vol_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1859 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1860 cvp_vol_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1861 sizeof(cvp_vol_cmd) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001862 cvp_vol_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001863 cvp_vol_cmd.hdr.dest_port = cvp_handle;
1864 cvp_vol_cmd.hdr.token = 0;
1865 cvp_vol_cmd.hdr.opcode =
1866 VSS_IVOCPROC_CMD_SET_RX_VOLUME_INDEX;
1867 cvp_vol_cmd.cvp_set_vol_idx.vol_index = v->dev_rx.volume;
1868 v->cvp_state = CMD_STATUS_FAIL;
1869 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_vol_cmd);
1870 if (ret < 0) {
1871 pr_err("Fail in sending RX VOL INDEX\n");
1872 return -EINVAL;
1873 }
1874 ret = wait_event_timeout(v->cvp_wait,
1875 (v->cvp_state == CMD_STATUS_SUCCESS),
1876 msecs_to_jiffies(TIMEOUT_MS));
1877 if (!ret) {
1878 pr_err("%s: wait_event timeout\n", __func__);
1879 return -EINVAL;
1880 }
1881 return 0;
1882}
1883
1884static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode)
1885{
1886 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001887 void *apr_cvs = voice_get_apr_cvs();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001888 u16 cvs_handle = voice_get_cvs_handle(v);
1889 struct cvs_start_record_cmd cvs_start_record;
1890
1891 pr_debug("%s: Start record %d\n", __func__, rec_mode);
1892
1893 cvs_start_record.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1894 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1895 cvs_start_record.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1896 sizeof(cvs_start_record) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001897 cvs_start_record.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001898 cvs_start_record.hdr.dest_port = cvs_handle;
1899 cvs_start_record.hdr.token = 0;
1900 cvs_start_record.hdr.opcode = VSS_ISTREAM_CMD_START_RECORD;
1901
1902 if (rec_mode == VOC_REC_UPLINK) {
1903 cvs_start_record.rec_mode.rx_tap_point = VSS_TAP_POINT_NONE;
1904 cvs_start_record.rec_mode.tx_tap_point =
1905 VSS_TAP_POINT_STREAM_END;
1906 } else if (rec_mode == VOC_REC_DOWNLINK) {
1907 cvs_start_record.rec_mode.rx_tap_point =
1908 VSS_TAP_POINT_STREAM_END;
1909 cvs_start_record.rec_mode.tx_tap_point = VSS_TAP_POINT_NONE;
1910 } else if (rec_mode == VOC_REC_BOTH) {
1911 cvs_start_record.rec_mode.rx_tap_point =
1912 VSS_TAP_POINT_STREAM_END;
1913 cvs_start_record.rec_mode.tx_tap_point =
1914 VSS_TAP_POINT_STREAM_END;
1915 } else {
1916 pr_err("%s: Invalid in-call rec_mode %d\n", __func__, rec_mode);
1917
1918 ret = -EINVAL;
1919 goto fail;
1920 }
1921
1922 v->cvs_state = CMD_STATUS_FAIL;
1923
1924 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_start_record);
1925 if (ret < 0) {
1926 pr_err("%s: Error %d sending START_RECORD\n", __func__, ret);
1927
1928 goto fail;
1929 }
1930
1931 ret = wait_event_timeout(v->cvs_wait,
1932 (v->cvs_state == CMD_STATUS_SUCCESS),
1933 msecs_to_jiffies(TIMEOUT_MS));
1934 if (!ret) {
1935 pr_err("%s: wait_event timeout\n", __func__);
1936
1937 goto fail;
1938 }
1939
1940 return 0;
1941
1942fail:
1943 return ret;
1944}
1945
1946static int voice_cvs_stop_record(struct voice_data *v)
1947{
1948 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001949 void *apr_cvs = voice_get_apr_cvs();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001950 u16 cvs_handle = voice_get_cvs_handle(v);
1951 struct apr_hdr cvs_stop_record;
1952
1953 pr_debug("%s: Stop record\n", __func__);
1954
1955 cvs_stop_record.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1956 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1957 cvs_stop_record.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1958 sizeof(cvs_stop_record) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001959 cvs_stop_record.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001960 cvs_stop_record.dest_port = cvs_handle;
1961 cvs_stop_record.token = 0;
1962 cvs_stop_record.opcode = VSS_ISTREAM_CMD_STOP_RECORD;
1963
1964 v->cvs_state = CMD_STATUS_FAIL;
1965
1966 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_stop_record);
1967 if (ret < 0) {
1968 pr_err("%s: Error %d sending STOP_RECORD\n", __func__, ret);
1969
1970 goto fail;
1971 }
1972
1973 ret = wait_event_timeout(v->cvs_wait,
1974 (v->cvs_state == CMD_STATUS_SUCCESS),
1975 msecs_to_jiffies(TIMEOUT_MS));
1976 if (!ret) {
1977 pr_err("%s: wait_event timeout\n", __func__);
1978
1979 goto fail;
1980 }
1981
1982 return 0;
1983
1984fail:
1985 return ret;
1986}
1987
1988int voice_start_record(uint32_t rec_mode, uint32_t set)
1989{
Neema Shetty90189b82011-06-27 14:58:37 -07001990 int ret = 0, i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001991 u16 cvs_handle;
1992
1993 pr_debug("%s: rec_mode %d, set %d\n", __func__, rec_mode, set);
1994
Neema Shetty90189b82011-06-27 14:58:37 -07001995 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
1996 struct voice_data *v = &common.voice[i];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001997
Neema Shetty90189b82011-06-27 14:58:37 -07001998 mutex_lock(&v->lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001999
Neema Shetty90189b82011-06-27 14:58:37 -07002000 cvs_handle = voice_get_cvs_handle(v);
2001
2002 if (cvs_handle != 0) {
2003 if (set)
2004 ret = voice_cvs_start_record(v, rec_mode);
2005 else
2006 ret = voice_cvs_stop_record(v);
2007 } else {
2008 /* Cache the value for later. */
2009 v->rec_info.pending = set;
2010 v->rec_info.rec_mode = rec_mode;
2011 }
2012
2013 mutex_unlock(&v->lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002014 }
2015
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002016 return ret;
2017}
2018
2019static int voice_cvs_start_playback(struct voice_data *v)
2020{
2021 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07002022 void *apr_cvs = voice_get_apr_cvs();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002023 u16 cvs_handle = voice_get_cvs_handle(v);
2024 struct apr_hdr cvs_start_playback;
2025
2026 pr_debug("%s: Start playback\n", __func__);
2027
2028 cvs_start_playback.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2029 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2030 cvs_start_playback.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2031 sizeof(cvs_start_playback) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07002032 cvs_start_playback.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002033 cvs_start_playback.dest_port = cvs_handle;
2034 cvs_start_playback.token = 0;
2035 cvs_start_playback.opcode = VSS_ISTREAM_CMD_START_PLAYBACK;
2036
2037 v->cvs_state = CMD_STATUS_FAIL;
2038
2039 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_start_playback);
2040 if (ret < 0) {
2041 pr_err("%s: Error %d sending START_PLAYBACK\n",
2042 __func__, ret);
2043
2044 goto fail;
2045 }
2046
2047 ret = wait_event_timeout(v->cvs_wait,
2048 (v->cvs_state == CMD_STATUS_SUCCESS),
2049 msecs_to_jiffies(TIMEOUT_MS));
2050 if (!ret) {
2051 pr_err("%s: wait_event timeout\n", __func__);
2052
2053 goto fail;
2054 }
2055
2056 v->music_info.playing = 1;
2057
2058 return 0;
2059
2060fail:
2061 return ret;
2062}
2063
2064static int voice_cvs_stop_playback(struct voice_data *v)
2065{
2066 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07002067 void *apr_cvs = voice_get_apr_cvs();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002068 u16 cvs_handle = voice_get_cvs_handle(v);
2069 struct apr_hdr cvs_stop_playback;
2070
2071 pr_debug("%s: Stop playback\n", __func__);
2072
2073 if (v->music_info.playing) {
2074 cvs_stop_playback.hdr_field =
2075 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2076 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2077 cvs_stop_playback.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2078 sizeof(cvs_stop_playback) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07002079 cvs_stop_playback.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002080 cvs_stop_playback.dest_port = cvs_handle;
2081 cvs_stop_playback.token = 0;
2082
2083 cvs_stop_playback.opcode = VSS_ISTREAM_CMD_STOP_PLAYBACK;
2084
2085 v->cvs_state = CMD_STATUS_FAIL;
2086
2087 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_stop_playback);
2088 if (ret < 0) {
2089 pr_err("%s: Error %d sending STOP_PLAYBACK\n",
2090 __func__, ret);
2091
2092 goto fail;
2093 }
2094
2095 ret = wait_event_timeout(v->cvs_wait,
2096 (v->cvs_state == CMD_STATUS_SUCCESS),
2097 msecs_to_jiffies(TIMEOUT_MS));
2098 if (!ret) {
2099 pr_err("%s: wait_event timeout\n", __func__);
2100
2101 goto fail;
2102 }
2103
2104 v->music_info.playing = 0;
2105 } else {
2106 pr_err("%s: Stop playback already sent\n", __func__);
2107 }
2108
2109 return 0;
2110
2111fail:
2112 return ret;
2113}
2114
2115int voice_start_playback(uint32_t set)
2116{
Neema Shetty90189b82011-06-27 14:58:37 -07002117 int ret = 0, i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002118 u16 cvs_handle;
2119
2120 pr_debug("%s: Start playback %d\n", __func__, set);
2121
Neema Shetty90189b82011-06-27 14:58:37 -07002122 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
2123 struct voice_data *v = &common.voice[i];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002124
Neema Shetty90189b82011-06-27 14:58:37 -07002125 mutex_lock(&v->lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002126
Neema Shetty90189b82011-06-27 14:58:37 -07002127 cvs_handle = voice_get_cvs_handle(v);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002128
Neema Shetty90189b82011-06-27 14:58:37 -07002129 if (cvs_handle != 0) {
2130 if (set)
2131 ret = voice_cvs_start_playback(v);
2132 else
2133 ret = voice_cvs_stop_playback(v);
2134 } else {
2135 /* Cache the value for later. */
2136 pr_debug("%s: Caching ICP value", __func__);
2137
2138 v->music_info.pending = set;
2139 }
2140
2141 mutex_unlock(&v->lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002142 }
2143
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002144 return ret;
2145}
2146
2147static void voice_auddev_cb_function(u32 evt_id,
2148 union auddev_evt_data *evt_payload,
2149 void *private_data)
2150{
Neema Shetty90189b82011-06-27 14:58:37 -07002151 struct common_data *c = private_data;
2152 struct voice_data *v = NULL;
2153
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002154 struct sidetone_cal sidetone_cal_data;
Neema Shetty90189b82011-06-27 14:58:37 -07002155 int rc = 0, i = 0;
Bharath Ramachandramurthyb9209472011-09-27 17:56:20 -07002156 int rc1 = 0;
2157
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002158 pr_info("auddev_cb_function, evt_id=%d,\n", evt_id);
Neema Shetty90189b82011-06-27 14:58:37 -07002159
2160 if (evt_payload == NULL) {
2161 pr_err("%s: evt_payload is NULL pointer\n", __func__);
2162 return;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002163 }
2164
2165 switch (evt_id) {
2166 case AUDDEV_EVT_START_VOICE:
Neema Shetty90189b82011-06-27 14:58:37 -07002167 v = voice_get_session(evt_payload->voice_session_id);
2168 if (v == NULL) {
2169 pr_err("%s: v is NULL\n", __func__);
2170 return;
2171 }
2172
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002173 mutex_lock(&v->lock);
2174
2175 if ((v->voc_state == VOC_INIT) ||
2176 (v->voc_state == VOC_RELEASE)) {
2177 v->v_call_status = VOICE_CALL_START;
2178 if ((v->dev_rx.enabled == VOICE_DEV_ENABLED)
2179 && (v->dev_tx.enabled == VOICE_DEV_ENABLED)) {
Neema Shetty90189b82011-06-27 14:58:37 -07002180 rc = voice_apr_register();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002181 if (rc < 0) {
2182 pr_err("%s: voice apr registration"
2183 "failed\n", __func__);
2184 mutex_unlock(&v->lock);
2185 return;
2186 }
Bharath Ramachandramurthyb9209472011-09-27 17:56:20 -07002187 rc1 = voice_create_mvm_cvs_session(v);
2188 if (rc1 < 0) {
2189 pr_err("%s: create mvm-cvs failed\n",
2190 __func__);
2191 msleep(100);
2192 rc = voice_apr_register();
2193 if (rc < 0) {
2194 mutex_unlock(&v->lock);
2195 pr_err("%s: voice apr regn"
2196 "failed\n", __func__);
2197 return;
2198 }
2199 rc1 = voice_create_mvm_cvs_session(v);
2200 if (rc1 < 0) {
2201 mutex_unlock(&v->lock);
2202 pr_err("%s:Retry mvmcvs "
2203 "failed\n",
2204 __func__);
2205 return;
2206 }
2207 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002208 voice_setup_modem_voice(v);
2209 voice_attach_vocproc(v);
2210 voice_send_start_voice_cmd(v);
2211 get_sidetone_cal(&sidetone_cal_data);
2212 msm_snddev_enable_sidetone(
2213 v->dev_rx.dev_id,
2214 sidetone_cal_data.enable,
2215 sidetone_cal_data.gain);
2216 v->voc_state = VOC_RUN;
2217
2218 /* Start in-call recording if command was
2219 * pending. */
2220 if (v->rec_info.pending) {
2221 voice_cvs_start_record(v,
2222 v->rec_info.rec_mode);
2223
2224 v->rec_info.pending = 0;
2225 }
2226
2227 /* Start in-call music delivery if command was
2228 * pending. */
2229 if (v->music_info.pending) {
2230 voice_cvs_start_playback(v);
2231
2232 v->music_info.pending = 0;
2233 }
2234 }
2235 }
2236
2237 mutex_unlock(&v->lock);
2238 break;
2239 case AUDDEV_EVT_DEV_CHG_VOICE:
Neema Shetty90189b82011-06-27 14:58:37 -07002240 /* Device change is applicable to all sessions. */
2241 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
2242 v = &c->voice[i];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002243
Neema Shetty90189b82011-06-27 14:58:37 -07002244 if (v->dev_rx.enabled == VOICE_DEV_ENABLED)
2245 msm_snddev_enable_sidetone(v->dev_rx.dev_id,
2246 0, 0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002247
Neema Shetty90189b82011-06-27 14:58:37 -07002248 v->dev_rx.enabled = VOICE_DEV_DISABLED;
2249 v->dev_tx.enabled = VOICE_DEV_DISABLED;
2250
2251 mutex_lock(&v->lock);
2252
2253 if (v->voc_state == VOC_RUN) {
2254 /* send cmd to modem to do voice device
2255 * change */
2256 voice_disable_vocproc(v);
2257 v->voc_state = VOC_CHANGE;
2258 }
2259
2260 mutex_unlock(&v->lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002261 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002262 break;
2263 case AUDDEV_EVT_DEV_RDY:
Neema Shetty90189b82011-06-27 14:58:37 -07002264 /* Device change is applicable to all sessions. */
2265 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
2266 v = &c->voice[i];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002267
Neema Shetty90189b82011-06-27 14:58:37 -07002268 mutex_lock(&v->lock);
2269
2270 if (v->voc_state == VOC_CHANGE) {
2271 /* get port Ids */
2272 if (evt_payload->voc_devinfo.dev_type ==
2273 DIR_RX) {
2274 v->dev_rx.dev_port_id =
2275 evt_payload->voc_devinfo.dev_port_id;
2276 v->dev_rx.sample =
2277 evt_payload->voc_devinfo.dev_sample;
2278 v->dev_rx.dev_id =
2279 evt_payload->voc_devinfo.dev_id;
2280 v->dev_rx.enabled = VOICE_DEV_ENABLED;
2281 } else {
2282 v->dev_tx.dev_port_id =
2283 evt_payload->voc_devinfo.dev_port_id;
2284 v->dev_tx.sample =
2285 evt_payload->voc_devinfo.dev_sample;
2286 v->dev_tx.enabled = VOICE_DEV_ENABLED;
2287 v->dev_tx.dev_id =
2288 evt_payload->voc_devinfo.dev_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002289 }
Neema Shetty90189b82011-06-27 14:58:37 -07002290 if ((v->dev_rx.enabled == VOICE_DEV_ENABLED) &&
2291 (v->dev_tx.enabled == VOICE_DEV_ENABLED)) {
2292 voice_set_device(v);
2293 get_sidetone_cal(&sidetone_cal_data);
2294 msm_snddev_enable_sidetone(
2295 v->dev_rx.dev_id,
2296 sidetone_cal_data.enable,
2297 sidetone_cal_data.gain);
2298 v->voc_state = VOC_RUN;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002299 }
Neema Shetty90189b82011-06-27 14:58:37 -07002300 } else if ((v->voc_state == VOC_INIT) ||
2301 (v->voc_state == VOC_RELEASE)) {
2302 /* get AFE ports */
2303 if (evt_payload->voc_devinfo.dev_type ==
2304 DIR_RX) {
2305 /* get rx port id */
2306 v->dev_rx.dev_port_id =
2307 evt_payload->voc_devinfo.dev_port_id;
2308 v->dev_rx.sample =
2309 evt_payload->voc_devinfo.dev_sample;
2310 v->dev_rx.dev_id =
2311 evt_payload->voc_devinfo.dev_id;
2312 v->dev_rx.enabled = VOICE_DEV_ENABLED;
2313 } else {
2314 /* get tx port id */
2315 v->dev_tx.dev_port_id =
2316 evt_payload->voc_devinfo.dev_port_id;
2317 v->dev_tx.sample =
2318 evt_payload->voc_devinfo.dev_sample;
2319 v->dev_tx.dev_id =
2320 evt_payload->voc_devinfo.dev_id;
2321 v->dev_tx.enabled = VOICE_DEV_ENABLED;
2322 }
2323 if ((v->dev_rx.enabled == VOICE_DEV_ENABLED) &&
2324 (v->dev_tx.enabled == VOICE_DEV_ENABLED) &&
2325 (v->v_call_status == VOICE_CALL_START)) {
2326 rc = voice_apr_register();
2327 if (rc < 0) {
2328 pr_err("%s: voice apr"
2329 "registration failed\n",
2330 __func__);
2331 mutex_unlock(&v->lock);
2332 return;
2333 }
2334 voice_create_mvm_cvs_session(v);
2335 voice_setup_modem_voice(v);
2336 voice_attach_vocproc(v);
2337 voice_send_start_voice_cmd(v);
2338 get_sidetone_cal(&sidetone_cal_data);
2339 msm_snddev_enable_sidetone(
2340 v->dev_rx.dev_id,
2341 sidetone_cal_data.enable,
2342 sidetone_cal_data.gain);
2343 v->voc_state = VOC_RUN;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002344
Neema Shetty90189b82011-06-27 14:58:37 -07002345 /* Start in-call recording if command
2346 * was pending. */
2347 if (v->rec_info.pending) {
2348 voice_cvs_start_record(v,
2349 v->rec_info.rec_mode);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002350
Neema Shetty90189b82011-06-27 14:58:37 -07002351 v->rec_info.pending = 0;
2352 }
2353
2354 /* Start in-call music delivery if
2355 * command was pending. */
2356 if (v->music_info.pending) {
2357 voice_cvs_start_playback(v);
2358
2359 v->music_info.pending = 0;
2360 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002361 }
2362 }
Neema Shetty90189b82011-06-27 14:58:37 -07002363
2364 mutex_unlock(&v->lock);
2365 }
2366 break;
2367 case AUDDEV_EVT_DEVICE_VOL_MUTE_CHG:
2368 v = voice_get_session(
2369 evt_payload->voc_vm_info.voice_session_id);
2370 if (v == NULL) {
2371 pr_err("%s: v is NULL\n", __func__);
2372 return;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002373 }
2374
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002375 /* cache the mute and volume index value */
Neema Shetty90189b82011-06-27 14:58:37 -07002376 if (evt_payload->voc_vm_info.dev_type == DIR_TX) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002377 v->dev_tx.mute =
2378 evt_payload->voc_vm_info.dev_vm_val.mute;
2379
2380 mutex_lock(&v->lock);
2381
2382 if (v->voc_state == VOC_RUN)
2383 voice_send_mute_cmd_to_modem(v);
2384
2385 mutex_unlock(&v->lock);
2386 } else {
Neema Shetty90189b82011-06-27 14:58:37 -07002387 v->dev_rx.volume =
2388 evt_payload->voc_vm_info.dev_vm_val.vol;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002389
2390 mutex_lock(&v->lock);
2391
2392 if (v->voc_state == VOC_RUN)
2393 voice_send_vol_index_to_modem(v);
2394
2395 mutex_unlock(&v->lock);
2396 }
2397 break;
2398 case AUDDEV_EVT_REL_PENDING:
Neema Shetty90189b82011-06-27 14:58:37 -07002399 /* Device change is applicable to all sessions. */
2400 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
2401 v = &c->voice[i];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002402
Neema Shetty90189b82011-06-27 14:58:37 -07002403 mutex_lock(&v->lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002404
Neema Shetty90189b82011-06-27 14:58:37 -07002405 if (v->voc_state == VOC_RUN) {
2406 voice_disable_vocproc(v);
2407 v->voc_state = VOC_CHANGE;
2408 }
2409
2410 mutex_unlock(&v->lock);
2411
2412 if (evt_payload->voc_devinfo.dev_type == DIR_RX)
2413 v->dev_rx.enabled = VOICE_DEV_DISABLED;
2414 else
2415 v->dev_tx.enabled = VOICE_DEV_DISABLED;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002416 }
2417
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002418 break;
2419 case AUDDEV_EVT_END_VOICE:
Neema Shetty90189b82011-06-27 14:58:37 -07002420 v = voice_get_session(evt_payload->voice_session_id);
2421 if (v == NULL) {
2422 pr_err("%s: v is NULL\n", __func__);
2423 return;
2424 }
2425
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002426 /* recover the tx mute and rx volume to the default values */
Neema Shetty90189b82011-06-27 14:58:37 -07002427 v->dev_tx.mute = c->default_mute_val;
2428 v->dev_rx.volume = c->default_vol_val;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002429 if (v->dev_rx.enabled == VOICE_DEV_ENABLED)
2430 msm_snddev_enable_sidetone(v->dev_rx.dev_id, 0, 0);
2431
2432 mutex_lock(&v->lock);
2433
2434 if (v->voc_state == VOC_RUN) {
2435 /* call stop modem voice */
2436 voice_send_stop_voice_cmd(v);
2437 voice_destroy_modem_voice(v);
2438 voice_destroy_mvm_cvs_session(v);
2439 v->voc_state = VOC_RELEASE;
2440 } else if (v->voc_state == VOC_CHANGE) {
2441 voice_send_stop_voice_cmd(v);
2442 voice_destroy_mvm_cvs_session(v);
2443 v->voc_state = VOC_RELEASE;
2444 }
2445
2446 mutex_unlock(&v->lock);
2447
2448 v->v_call_status = VOICE_CALL_END;
2449
2450 break;
2451 default:
2452 pr_err("UNKNOWN EVENT\n");
2453 }
2454 return;
2455}
2456EXPORT_SYMBOL(voice_auddev_cb_function);
2457
2458int voice_set_voc_path_full(uint32_t set)
2459{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002460 pr_info("%s: %d\n", __func__, set);
2461
Neema Shetty90189b82011-06-27 14:58:37 -07002462 mutex_lock(&common.common_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002463
Neema Shetty90189b82011-06-27 14:58:37 -07002464 if (set)
2465 common.voc_path = VOC_PATH_FULL;
2466 else
2467 common.voc_path = VOC_PATH_PASSIVE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002468
Neema Shetty90189b82011-06-27 14:58:37 -07002469 mutex_unlock(&common.common_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002470
Neema Shetty90189b82011-06-27 14:58:37 -07002471 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002472}
2473EXPORT_SYMBOL(voice_set_voc_path_full);
2474
2475void voice_register_mvs_cb(ul_cb_fn ul_cb,
2476 dl_cb_fn dl_cb,
2477 void *private_data)
2478{
Neema Shetty90189b82011-06-27 14:58:37 -07002479 common.mvs_info.ul_cb = ul_cb;
2480 common.mvs_info.dl_cb = dl_cb;
2481 common.mvs_info.private_data = private_data;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002482}
2483
2484void voice_config_vocoder(uint32_t media_type,
2485 uint32_t rate,
2486 uint32_t network_type,
Chaithanya Krishna Bacharaju2f2e8a52011-10-17 14:54:07 +05302487 uint32_t dtx_mode,
2488 struct q_min_max_rate q_min_max_rate)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002489{
Neema Shetty90189b82011-06-27 14:58:37 -07002490 common.mvs_info.media_type = media_type;
2491 common.mvs_info.rate = rate;
2492 common.mvs_info.network_type = network_type;
2493 common.mvs_info.dtx_mode = dtx_mode;
Chaithanya Krishna Bacharaju2f2e8a52011-10-17 14:54:07 +05302494 common.mvs_info.q_min_max_rate = q_min_max_rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002495}
2496
2497static int32_t modem_mvm_callback(struct apr_client_data *data, void *priv)
2498{
2499 uint32_t *ptr;
Neema Shetty90189b82011-06-27 14:58:37 -07002500 struct common_data *c = priv;
2501 struct voice_data *v = NULL;
2502 int i = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002503
Neema Shetty90189b82011-06-27 14:58:37 -07002504 pr_debug("%s: session_id 0x%x\n", __func__, data->dest_port);
2505
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002506 if (data->opcode == RESET_EVENTS) {
2507 pr_debug("%s:Reset event received in Voice service\n",
2508 __func__);
Neema Shetty90189b82011-06-27 14:58:37 -07002509 apr_reset(c->apr_mvm);
2510 c->apr_mvm = NULL;
2511 apr_reset(c->apr_q6_mvm);
2512 c->apr_q6_mvm = NULL;
2513
2514 /* Sub-system restart is applicable to all sessions. */
2515 for (i = 0; i < MAX_VOC_SESSIONS; i++)
2516 c->voice[i].mvm_handle = 0;
2517
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002518 return 0;
2519 }
2520
Swaminathan Sathappan71809462011-11-11 13:49:27 -08002521 v = voice_get_session(data->dest_port);
2522 if (v == NULL) {
2523 pr_err("%s: v is NULL\n", __func__);
2524 return -EINVAL;
2525 }
2526
2527 pr_debug("%s: common data 0x%x, session 0x%x\n",
2528 __func__, (unsigned int)c, (unsigned int)v);
2529 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
2530 data->payload_size, data->opcode);
2531
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002532 if (data->opcode == APR_BASIC_RSP_RESULT) {
2533 if (data->payload_size) {
2534 ptr = data->payload;
2535
2536 pr_info("%x %x\n", ptr[0], ptr[1]);
2537 /* ping mvm service ACK */
2538
2539 if (ptr[0] ==
2540 VSS_IMVM_CMD_CREATE_PASSIVE_CONTROL_SESSION ||
2541 ptr[0] ==
2542 VSS_IMVM_CMD_CREATE_FULL_CONTROL_SESSION) {
2543 /* Passive session is used for voice call
2544 * through modem. Full session is used for voice
2545 * call through Q6. */
2546 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2547 if (!ptr[1]) {
2548 pr_debug("%s: MVM handle is %d\n",
2549 __func__, data->src_port);
2550
2551 voice_set_mvm_handle(v, data->src_port);
2552 } else
2553 pr_info("got NACK for sending \
2554 MVM create session \n");
2555 v->mvm_state = CMD_STATUS_SUCCESS;
2556 wake_up(&v->mvm_wait);
2557 } else if (ptr[0] == VSS_IMVM_CMD_START_VOICE) {
2558 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2559 v->mvm_state = CMD_STATUS_SUCCESS;
2560 wake_up(&v->mvm_wait);
Neema Shetty7e4a9b52011-07-26 15:24:51 -07002561 } else if (ptr[0] == VSS_ISTREAM_CMD_ATTACH_VOCPROC) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002562 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2563 v->mvm_state = CMD_STATUS_SUCCESS;
2564 wake_up(&v->mvm_wait);
2565 } else if (ptr[0] == VSS_IMVM_CMD_STOP_VOICE) {
2566 v->mvm_state = CMD_STATUS_SUCCESS;
2567 wake_up(&v->mvm_wait);
Neema Shetty7e4a9b52011-07-26 15:24:51 -07002568 } else if (ptr[0] == VSS_ISTREAM_CMD_DETACH_VOCPROC) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002569 v->mvm_state = CMD_STATUS_SUCCESS;
2570 wake_up(&v->mvm_wait);
2571 } else if (ptr[0] == VSS_ISTREAM_CMD_SET_TTY_MODE) {
2572 v->mvm_state = CMD_STATUS_SUCCESS;
2573 wake_up(&v->mvm_wait);
2574 } else if (ptr[0] == APRV2_IBASIC_CMD_DESTROY_SESSION) {
2575 pr_debug("%s: DESTROY resp\n", __func__);
2576
2577 v->mvm_state = CMD_STATUS_SUCCESS;
2578 wake_up(&v->mvm_wait);
2579 } else if (ptr[0] == VSS_IMVM_CMD_ATTACH_STREAM) {
2580 pr_debug("%s: ATTACH_STREAM resp 0x%x\n",
2581 __func__, ptr[1]);
2582
2583 v->mvm_state = CMD_STATUS_SUCCESS;
2584 wake_up(&v->mvm_wait);
2585 } else if (ptr[0] == VSS_IMVM_CMD_DETACH_STREAM) {
2586 pr_debug("%s: DETACH_STREAM resp 0x%x\n",
2587 __func__, ptr[1]);
2588
2589 v->mvm_state = CMD_STATUS_SUCCESS;
2590 wake_up(&v->mvm_wait);
2591 } else if (ptr[0] == VSS_ICOMMON_CMD_SET_NETWORK) {
2592 pr_debug("%s: SET_NETWORK resp 0x%x\n",
2593 __func__, ptr[1]);
2594
2595 v->mvm_state = CMD_STATUS_SUCCESS;
2596 wake_up(&v->mvm_wait);
2597 } else if (ptr[0] == VSS_ICOMMON_CMD_SET_VOICE_TIMING) {
2598 pr_debug("%s: SET_VOICE_TIMING resp 0x%x\n",
2599 __func__, ptr[1]);
2600
2601 v->mvm_state = CMD_STATUS_SUCCESS;
2602 wake_up(&v->mvm_wait);
2603 } else
2604 pr_debug("%s: not match cmd = 0x%x\n",
2605 __func__, ptr[0]);
2606 }
2607 }
2608
2609 return 0;
2610}
2611
2612static int32_t modem_cvs_callback(struct apr_client_data *data, void *priv)
2613{
2614 uint32_t *ptr;
Neema Shetty90189b82011-06-27 14:58:37 -07002615 struct common_data *c = priv;
2616 struct voice_data *v = NULL;
2617 int i = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002618
Neema Shetty90189b82011-06-27 14:58:37 -07002619 pr_debug("%s: session_id 0x%x\n", __func__, data->dest_port);
2620
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002621 if (data->opcode == RESET_EVENTS) {
2622 pr_debug("%s:Reset event received in Voice service\n",
2623 __func__);
Neema Shetty90189b82011-06-27 14:58:37 -07002624 apr_reset(c->apr_cvs);
2625 c->apr_cvs = NULL;
2626 apr_reset(c->apr_q6_cvs);
2627 c->apr_q6_cvs = NULL;
2628
2629 /* Sub-system restart is applicable to all sessions. */
2630 for (i = 0; i < MAX_VOC_SESSIONS; i++)
2631 c->voice[i].cvs_handle = 0;
2632
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002633 return 0;
2634 }
2635
Swaminathan Sathappan71809462011-11-11 13:49:27 -08002636 v = voice_get_session(data->dest_port);
2637 if (v == NULL) {
2638 pr_err("%s: v is NULL\n", __func__);
2639 return -EINVAL;
2640 }
2641
2642 pr_debug("%s: common data 0x%x, session 0x%x\n",
2643 __func__, (unsigned int)c, (unsigned int)v);
2644 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
2645 data->payload_size, data->opcode);
2646
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002647 if (data->opcode == APR_BASIC_RSP_RESULT) {
2648 if (data->payload_size) {
2649 ptr = data->payload;
2650
2651 pr_info("%x %x\n", ptr[0], ptr[1]);
2652 /*response from modem CVS */
2653 if (ptr[0] ==
2654 VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION ||
2655 ptr[0] ==
2656 VSS_ISTREAM_CMD_CREATE_FULL_CONTROL_SESSION) {
2657 if (!ptr[1]) {
2658 pr_debug("%s: CVS handle is %d\n",
2659 __func__, data->src_port);
2660 voice_set_cvs_handle(v, data->src_port);
2661 } else
2662 pr_info("got NACK for sending \
2663 CVS create session \n");
2664 v->cvs_state = CMD_STATUS_SUCCESS;
2665 wake_up(&v->cvs_wait);
2666 } else if (ptr[0] ==
2667 VSS_ISTREAM_CMD_CACHE_CALIBRATION_DATA) {
2668 v->cvs_state = CMD_STATUS_SUCCESS;
2669 wake_up(&v->cvs_wait);
2670 } else if (ptr[0] ==
2671 VSS_ISTREAM_CMD_SET_MUTE) {
2672 v->cvs_state = CMD_STATUS_SUCCESS;
2673 wake_up(&v->cvs_wait);
2674 } else if (ptr[0] == VSS_ISTREAM_CMD_SET_MEDIA_TYPE) {
2675 pr_debug("%s: SET_MEDIA resp 0x%x\n",
2676 __func__, ptr[1]);
2677
2678 v->cvs_state = CMD_STATUS_SUCCESS;
2679 wake_up(&v->cvs_wait);
2680 } else if (ptr[0] ==
2681 VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE) {
2682 pr_debug("%s: SET_AMR_RATE resp 0x%x\n",
2683 __func__, ptr[1]);
2684
2685 v->cvs_state = CMD_STATUS_SUCCESS;
2686 wake_up(&v->cvs_wait);
2687 } else if (ptr[0] ==
2688 VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE) {
2689 pr_debug("%s: SET_AMR_WB_RATE resp 0x%x\n",
2690 __func__, ptr[1]);
2691
2692 v->cvs_state = CMD_STATUS_SUCCESS;
2693 wake_up(&v->cvs_wait);
2694 } else if (ptr[0] == VSS_ISTREAM_CMD_SET_ENC_DTX_MODE) {
2695 pr_debug("%s: SET_DTX resp 0x%x\n",
2696 __func__, ptr[1]);
2697
2698 v->cvs_state = CMD_STATUS_SUCCESS;
2699 wake_up(&v->cvs_wait);
2700 } else if (ptr[0] ==
2701 VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE) {
2702 pr_debug("%s: SET_CDMA_RATE resp 0x%x\n",
2703 __func__, ptr[1]);
2704
2705 v->cvs_state = CMD_STATUS_SUCCESS;
2706 wake_up(&v->cvs_wait);
2707 } else if (ptr[0] == APRV2_IBASIC_CMD_DESTROY_SESSION) {
2708 pr_debug("%s: DESTROY resp\n", __func__);
2709
2710 v->cvs_state = CMD_STATUS_SUCCESS;
2711 wake_up(&v->cvs_wait);
2712 } else if (ptr[0] == VSS_ISTREAM_CMD_START_RECORD) {
2713 pr_debug("%s: START_RECORD resp 0x%x\n",
2714 __func__, ptr[1]);
2715
2716 v->cvs_state = CMD_STATUS_SUCCESS;
2717 wake_up(&v->cvs_wait);
2718 } else if (ptr[0] == VSS_ISTREAM_CMD_STOP_RECORD) {
2719 pr_debug("%s: STOP_RECORD resp 0x%x\n",
2720 __func__, ptr[1]);
2721
2722 v->cvs_state = CMD_STATUS_SUCCESS;
2723 wake_up(&v->cvs_wait);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002724 } else if (ptr[0] == VOICE_CMD_SET_PARAM) {
2725 rtac_make_voice_callback(RTAC_CVS, ptr,
2726 data->payload_size);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002727 } else if (ptr[0] == VSS_ISTREAM_CMD_START_PLAYBACK) {
2728 pr_debug("%s: START_PLAYBACK resp 0x%x\n",
2729 __func__, ptr[1]);
2730
2731 v->cvs_state = CMD_STATUS_SUCCESS;
2732 wake_up(&v->cvs_wait);
2733 } else if (ptr[0] == VSS_ISTREAM_CMD_STOP_PLAYBACK) {
2734 pr_debug("%s: STOP_PLAYBACK resp 0x%x\n",
2735 __func__, ptr[1]);
2736
2737 v->cvs_state = CMD_STATUS_SUCCESS;
2738 wake_up(&v->cvs_wait);
2739 } else
2740 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2741 }
2742 } else if (data->opcode == VSS_ISTREAM_EVT_SEND_ENC_BUFFER) {
2743 uint32_t *voc_pkt = data->payload;
2744 uint32_t pkt_len = data->payload_size;
2745
Neema Shetty90189b82011-06-27 14:58:37 -07002746 if (voc_pkt != NULL && c->mvs_info.ul_cb != NULL) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002747 pr_debug("%s: Media type is 0x%x\n",
2748 __func__, voc_pkt[0]);
2749
2750 /* Remove media ID from payload. */
2751 voc_pkt++;
2752 pkt_len = pkt_len - 4;
2753
Neema Shetty90189b82011-06-27 14:58:37 -07002754 c->mvs_info.ul_cb((uint8_t *)voc_pkt,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002755 pkt_len,
Neema Shetty90189b82011-06-27 14:58:37 -07002756 c->mvs_info.private_data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002757 } else {
2758 pr_err("%s: voc_pkt is 0x%x ul_cb is 0x%x\n",
2759 __func__, (unsigned int)voc_pkt,
Neema Shetty90189b82011-06-27 14:58:37 -07002760 (unsigned int)c->mvs_info.ul_cb);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002761 }
2762 } else if (data->opcode == VSS_ISTREAM_EVT_SEND_DEC_BUFFER) {
2763 pr_debug("%s: Send dec buf resp\n", __func__);
2764 } else if (data->opcode == VSS_ISTREAM_EVT_REQUEST_DEC_BUFFER) {
2765 struct cvs_send_dec_buf_cmd send_dec_buf;
2766 int ret = 0;
2767 uint32_t pkt_len = 0;
2768
Neema Shetty90189b82011-06-27 14:58:37 -07002769 if (c->mvs_info.dl_cb != NULL) {
2770 send_dec_buf.dec_buf.media_id = c->mvs_info.media_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002771
Neema Shetty90189b82011-06-27 14:58:37 -07002772 c->mvs_info.dl_cb(
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002773 (uint8_t *)&send_dec_buf.dec_buf.packet_data,
2774 &pkt_len,
Neema Shetty90189b82011-06-27 14:58:37 -07002775 c->mvs_info.private_data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002776
2777 send_dec_buf.hdr.hdr_field =
2778 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2779 APR_HDR_LEN(APR_HDR_SIZE),
2780 APR_PKT_VER);
2781 send_dec_buf.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2782 sizeof(send_dec_buf.dec_buf.media_id) + pkt_len);
Neema Shetty90189b82011-06-27 14:58:37 -07002783 send_dec_buf.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002784 send_dec_buf.hdr.dest_port = voice_get_cvs_handle(v);
2785 send_dec_buf.hdr.token = 0;
2786 send_dec_buf.hdr.opcode =
2787 VSS_ISTREAM_EVT_SEND_DEC_BUFFER;
2788
Neema Shetty90189b82011-06-27 14:58:37 -07002789 ret = apr_send_pkt(voice_get_apr_cvs(),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002790 (uint32_t *) &send_dec_buf);
2791 if (ret < 0) {
2792 pr_err("%s: Error %d sending DEC_BUF\n",
2793 __func__, ret);
2794 goto fail;
2795 }
2796 } else {
2797 pr_err("%s: ul_cb is NULL\n", __func__);
2798 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002799 } else if (data->opcode == VOICE_EVT_GET_PARAM_ACK) {
2800 rtac_make_voice_callback(RTAC_CVS, data->payload,
2801 data->payload_size);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002802 } else {
2803 pr_debug("%s: Unknown opcode 0x%x\n", __func__, data->opcode);
2804 }
2805
2806fail:
2807 return 0;
2808}
2809
2810static int32_t modem_cvp_callback(struct apr_client_data *data, void *priv)
2811{
2812 uint32_t *ptr;
Neema Shetty90189b82011-06-27 14:58:37 -07002813 struct common_data *c = priv;
2814 struct voice_data *v = NULL;
2815 int i = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002816
Neema Shetty90189b82011-06-27 14:58:37 -07002817 pr_debug("%s: session_id 0x%x\n", __func__, data->dest_port);
2818
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002819 if (data->opcode == RESET_EVENTS) {
2820 pr_debug("%s:Reset event received in Voice service\n",
2821 __func__);
Neema Shetty90189b82011-06-27 14:58:37 -07002822 apr_reset(c->apr_cvp);
2823 c->apr_cvp = NULL;
2824 apr_reset(c->apr_q6_cvp);
2825 c->apr_q6_cvp = NULL;
2826
2827 /* Sub-system restart is applicable to all sessions. */
2828 for (i = 0; i < MAX_VOC_SESSIONS; i++)
2829 c->voice[i].cvp_handle = 0;
2830
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002831 return 0;
2832 }
2833
Swaminathan Sathappan71809462011-11-11 13:49:27 -08002834 v = voice_get_session(data->dest_port);
2835 if (v == NULL) {
2836 pr_err("%s: v is NULL\n", __func__);
2837 return -EINVAL;
2838 }
2839
2840 pr_debug("%s: common data 0x%x, session 0x%x\n",
2841 __func__, (unsigned int)c, (unsigned int)v);
2842 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
2843 data->payload_size, data->opcode);
2844
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002845 if (data->opcode == APR_BASIC_RSP_RESULT) {
2846 if (data->payload_size) {
2847 ptr = data->payload;
2848
2849 pr_info("%x %x\n", ptr[0], ptr[1]);
2850 /*response from modem CVP */
2851 if (ptr[0] ==
2852 VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION) {
2853 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2854 if (!ptr[1]) {
2855 voice_set_cvp_handle(v, data->src_port);
2856 pr_debug("cvphdl=%d\n", data->src_port);
2857 } else
2858 pr_info("got NACK from CVP create \
2859 session response\n");
2860 v->cvp_state = CMD_STATUS_SUCCESS;
2861 wake_up(&v->cvp_wait);
2862 } else if (ptr[0] ==
2863 VSS_IVOCPROC_CMD_CACHE_CALIBRATION_DATA) {
2864 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2865 v->cvp_state = CMD_STATUS_SUCCESS;
2866 wake_up(&v->cvp_wait);
2867 } else if (ptr[0] == VSS_IVOCPROC_CMD_SET_DEVICE) {
2868 v->cvp_state = CMD_STATUS_SUCCESS;
2869 wake_up(&v->cvp_wait);
2870 } else if (ptr[0] ==
2871 VSS_IVOCPROC_CMD_SET_RX_VOLUME_INDEX) {
2872 v->cvp_state = CMD_STATUS_SUCCESS;
2873 wake_up(&v->cvp_wait);
2874 } else if (ptr[0] == VSS_IVOCPROC_CMD_ENABLE) {
2875 v->cvp_state = CMD_STATUS_SUCCESS;
2876 wake_up(&v->cvp_wait);
2877 } else if (ptr[0] == VSS_IVOCPROC_CMD_DISABLE) {
2878 v->cvp_state = CMD_STATUS_SUCCESS;
2879 wake_up(&v->cvp_wait);
2880 } else if (ptr[0] == APRV2_IBASIC_CMD_DESTROY_SESSION) {
2881 v->cvp_state = CMD_STATUS_SUCCESS;
2882 wake_up(&v->cvp_wait);
2883 } else if (ptr[0] ==
2884 VSS_IVOCPROC_CMD_CACHE_VOLUME_CALIBRATION_TABLE
2885 ) {
2886
2887 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2888 v->cvp_state = CMD_STATUS_SUCCESS;
2889 wake_up(&v->cvp_wait);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002890 } else if (ptr[0] == VOICE_CMD_SET_PARAM) {
2891 rtac_make_voice_callback(RTAC_CVP, ptr,
2892 data->payload_size);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002893 } else
2894 pr_debug("%s: not match cmd = 0x%x\n",
2895 __func__, ptr[0]);
2896 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002897 } else if (data->opcode == VOICE_EVT_GET_PARAM_ACK) {
2898 rtac_make_voice_callback(RTAC_CVP, data->payload,
2899 data->payload_size);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002900 }
2901 return 0;
2902}
2903
2904
2905static int __init voice_init(void)
2906{
Neema Shetty90189b82011-06-27 14:58:37 -07002907 int rc = 0, i = 0;
2908
2909 memset(&common, 0, sizeof(struct common_data));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002910
2911 /* set default value */
Neema Shetty90189b82011-06-27 14:58:37 -07002912 common.default_mute_val = 1; /* default is mute */
2913 common.default_vol_val = 0;
2914 common.default_sample_val = 8000;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002915
Neema Shetty90189b82011-06-27 14:58:37 -07002916 common.voc_path = VOC_PATH_PASSIVE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002917
2918 /* Initialize MVS info. */
Neema Shetty90189b82011-06-27 14:58:37 -07002919 common.mvs_info.network_type = VSS_NETWORK_ID_DEFAULT;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002920
Neema Shetty90189b82011-06-27 14:58:37 -07002921 mutex_init(&common.common_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002922
Neema Shetty90189b82011-06-27 14:58:37 -07002923 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
2924 common.voice[i].session_id = SESSION_ID_BASE + i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002925
Neema Shetty90189b82011-06-27 14:58:37 -07002926 common.voice[i].dev_rx.volume = common.default_vol_val;
2927 common.voice[i].dev_tx.mute = common.default_mute_val;
2928
2929 common.voice[i].voc_state = VOC_INIT;
2930
2931 common.voice[i].rec_info.rec_mode = VOC_REC_NONE;
2932
2933 init_waitqueue_head(&common.voice[i].mvm_wait);
2934 init_waitqueue_head(&common.voice[i].cvs_wait);
2935 init_waitqueue_head(&common.voice[i].cvp_wait);
2936
2937 mutex_init(&common.voice[i].lock);
2938
2939 }
2940
2941 common.device_events = AUDDEV_EVT_DEV_CHG_VOICE |
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002942 AUDDEV_EVT_DEV_RDY |
2943 AUDDEV_EVT_REL_PENDING |
2944 AUDDEV_EVT_START_VOICE |
2945 AUDDEV_EVT_END_VOICE |
2946 AUDDEV_EVT_DEVICE_VOL_MUTE_CHG |
2947 AUDDEV_EVT_FREQ_CHG;
2948
2949 pr_debug("to register call back\n");
2950 /* register callback to auddev */
Neema Shetty90189b82011-06-27 14:58:37 -07002951 auddev_register_evt_listner(common.device_events, AUDDEV_CLNT_VOC,
2952 0, voice_auddev_cb_function, &common);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002953
2954 return rc;
2955}
2956
2957device_initcall(voice_init);