blob: d0fec7c7d24d37a6549a4b9ed8f2d60e26113ab8 [file] [log] [blame]
Ben Rombergerc1bb79e2012-01-13 21:48:35 -08001/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002 *
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;
951 int index = 0;
952 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -0700953 void *apr_cvp = voice_get_apr_cvp();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700954 u16 cvp_handle = voice_get_cvp_handle(v);
955
956
957 /* fill the header */
958 cvp_vol_cal_cmd_hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
959 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
960 cvp_vol_cal_cmd_hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
961 sizeof(cvp_vol_cal_cmd_hdr) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -0700962 cvp_vol_cal_cmd_hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700963 cvp_vol_cal_cmd_hdr.dest_port = cvp_handle;
964 cvp_vol_cal_cmd_hdr.token = 0;
965 cvp_vol_cal_cmd_hdr.opcode =
966 VSS_IVOCPROC_CMD_CACHE_VOLUME_CALIBRATION_TABLE;
967
968 /* get cal data */
969 get_vocvol_cal(&cal_data);
970 if (cal_data.num_cal_blocks == 0) {
971 pr_err("%s: No calibration data to send!\n", __func__);
972 goto done;
973 }
974
975 /* send cal to modem */
976 cmd_buf = kzalloc((sizeof(struct apr_hdr) + BUFFER_PAYLOAD_SIZE),
977 GFP_KERNEL);
978 if (!cmd_buf) {
979 pr_err("No memory is allocated.\n");
980 return -ENOMEM;
981 }
982 pr_debug("----- num_cal_blocks=%d\n", (s32)cal_data.num_cal_blocks);
983 cal_blk = cal_data.cal_blocks;
984 pr_debug("Cal_blk =%x\n", (uint32_t)cal_data.cal_blocks);
985
986 for (; index < cal_data.num_cal_blocks; index++) {
987 cal_size_per_network = cal_blk[index].cal_size;
988 cal_data_per_network = (u32 *)cal_blk[index].cal_kvaddr;
Ben Rombergerb4f562a2011-07-13 19:57:54 -0700989
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700990 pr_debug("Cal size =%d, index=%d\n", cal_size_per_network,
991 index);
992 pr_debug("Cal data=%x\n", (uint32_t)cal_data_per_network);
993 cvp_vol_cal_cmd_hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
Ben Rombergerc1bb79e2012-01-13 21:48:35 -0800994 cal_size_per_network);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700995 memcpy(cmd_buf, &cvp_vol_cal_cmd_hdr, APR_HDR_SIZE);
Ben Rombergerc1bb79e2012-01-13 21:48:35 -0800996 memcpy(cmd_buf + (APR_HDR_SIZE / sizeof(uint32_t)),
997 cal_data_per_network, cal_size_per_network);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700998 pr_debug("Send vol table\n");
999
1000 v->cvp_state = CMD_STATUS_FAIL;
1001 ret = apr_send_pkt(apr_cvp, cmd_buf);
1002 if (ret < 0) {
1003 pr_err("Fail: sending cvp vol cal, idx=%d\n", index);
1004 continue;
1005 }
1006 ret = wait_event_timeout(v->cvp_wait,
1007 (v->cvp_state == CMD_STATUS_SUCCESS),
1008 msecs_to_jiffies(TIMEOUT_MS));
1009 if (!ret) {
1010 pr_err("%s: wait_event timeout\n", __func__);
1011 return -EINVAL;
1012 }
1013 }
1014 kfree(cmd_buf);
1015done:
1016 return 0;
1017}
1018
1019static int voice_set_dtx(struct voice_data *v)
1020{
1021 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001022 void *apr_cvs = voice_get_apr_cvs();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001023 u16 cvs_handle = voice_get_cvs_handle(v);
1024
1025 /* Set DTX */
1026 struct cvs_set_enc_dtx_mode_cmd cvs_set_dtx = {
1027 .hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1028 APR_HDR_LEN(APR_HDR_SIZE),
1029 APR_PKT_VER),
1030 .hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1031 sizeof(cvs_set_dtx) - APR_HDR_SIZE),
Neema Shetty90189b82011-06-27 14:58:37 -07001032 .hdr.src_port = v->session_id,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001033 .hdr.dest_port = cvs_handle,
1034 .hdr.token = 0,
1035 .hdr.opcode = VSS_ISTREAM_CMD_SET_ENC_DTX_MODE,
Neema Shetty90189b82011-06-27 14:58:37 -07001036 .dtx_mode.enable = common.mvs_info.dtx_mode,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001037 };
1038
Neema Shetty90189b82011-06-27 14:58:37 -07001039 pr_debug("%s: Setting DTX %d\n", __func__, common.mvs_info.dtx_mode);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001040
1041 v->cvs_state = CMD_STATUS_FAIL;
1042
1043 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_dtx);
1044 if (ret < 0) {
1045 pr_err("%s: Error %d sending SET_DTX\n", __func__, ret);
1046
1047 goto done;
1048 }
1049
1050 ret = wait_event_timeout(v->cvs_wait,
1051 (v->cvs_state == CMD_STATUS_SUCCESS),
1052 msecs_to_jiffies(TIMEOUT_MS));
1053 if (!ret) {
1054 pr_err("%s: wait_event timeout\n", __func__);
1055
1056 ret = -EINVAL;
1057 }
1058
1059done:
1060 return ret;
1061}
1062
1063static int voice_config_cvs_vocoder(struct voice_data *v)
1064{
1065 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001066 void *apr_cvs = voice_get_apr_cvs();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001067 u16 cvs_handle = voice_get_cvs_handle(v);
1068
1069 /* Set media type. */
1070 struct cvs_set_media_type_cmd cvs_set_media_cmd;
1071
1072 pr_info("%s: Setting media type\n", __func__);
1073
1074 cvs_set_media_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1075 APR_HDR_LEN(APR_HDR_SIZE),
1076 APR_PKT_VER);
1077 cvs_set_media_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1078 sizeof(cvs_set_media_cmd) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001079 cvs_set_media_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001080 cvs_set_media_cmd.hdr.dest_port = cvs_handle;
1081 cvs_set_media_cmd.hdr.token = 0;
1082 cvs_set_media_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_MEDIA_TYPE;
Neema Shetty90189b82011-06-27 14:58:37 -07001083 cvs_set_media_cmd.media_type.tx_media_id = common.mvs_info.media_type;
1084 cvs_set_media_cmd.media_type.rx_media_id = common.mvs_info.media_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001085
1086 v->cvs_state = CMD_STATUS_FAIL;
1087
1088 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_media_cmd);
1089 if (ret < 0) {
1090 pr_err("%s: Error %d sending SET_MEDIA_TYPE\n",
1091 __func__, ret);
1092
1093 goto done;
1094 }
1095
1096 ret = wait_event_timeout(v->cvs_wait,
1097 (v->cvs_state == CMD_STATUS_SUCCESS),
1098 msecs_to_jiffies(TIMEOUT_MS));
1099 if (!ret) {
1100 pr_err("%s: wait_event timeout\n", __func__);
1101
1102 ret = -EINVAL;
1103 goto done;
1104 }
1105
1106 /* Set encoder properties. */
Neema Shetty90189b82011-06-27 14:58:37 -07001107 switch (common.mvs_info.media_type) {
Chaithanya Krishna Bacharaju68993b52011-10-18 08:41:30 +05301108 case VSS_MEDIA_ID_13K_MODEM:
Chaithanya Krishna Bacharaju2f2e8a52011-10-17 14:54:07 +05301109 case VSS_MEDIA_ID_4GV_NB_MODEM:
1110 case VSS_MEDIA_ID_4GV_WB_MODEM:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001111 case VSS_MEDIA_ID_EVRC_MODEM: {
1112 struct cvs_set_cdma_enc_minmax_rate_cmd cvs_set_cdma_rate;
1113
Chaithanya Krishna Bacharaju2f2e8a52011-10-17 14:54:07 +05301114 pr_info("%s: Setting CDMA min-max rate\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001115
1116 cvs_set_cdma_rate.hdr.hdr_field =
1117 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1118 APR_HDR_LEN(APR_HDR_SIZE),
1119 APR_PKT_VER);
1120 cvs_set_cdma_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1121 sizeof(cvs_set_cdma_rate) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001122 cvs_set_cdma_rate.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001123 cvs_set_cdma_rate.hdr.dest_port = cvs_handle;
1124 cvs_set_cdma_rate.hdr.token = 0;
1125 cvs_set_cdma_rate.hdr.opcode =
1126 VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE;
Chaithanya Krishna Bacharaju2f2e8a52011-10-17 14:54:07 +05301127 cvs_set_cdma_rate.cdma_rate.min_rate =
1128 common.mvs_info.q_min_max_rate.min_rate;
1129 cvs_set_cdma_rate.cdma_rate.max_rate =
1130 common.mvs_info.q_min_max_rate.max_rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001131
1132 v->cvs_state = CMD_STATUS_FAIL;
1133
1134 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_cdma_rate);
1135 if (ret < 0) {
Chaithanya Krishna Bacharaju2f2e8a52011-10-17 14:54:07 +05301136 pr_err("%s: Error %d sending CDMA_SET_ENC_MINMAX_RATE\n",
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001137 __func__, ret);
1138
1139 goto done;
1140 }
1141
1142 ret = wait_event_timeout(v->cvs_wait,
1143 (v->cvs_state == CMD_STATUS_SUCCESS),
1144 msecs_to_jiffies(TIMEOUT_MS));
1145 if (!ret) {
1146 pr_err("%s: wait_event timeout\n", __func__);
1147
1148 ret = -EINVAL;
1149 goto done;
1150 }
1151
Chaithanya Krishna Bacharaju2f2e8a52011-10-17 14:54:07 +05301152 if ((common.mvs_info.media_type == VSS_MEDIA_ID_4GV_NB_MODEM) ||
1153 (common.mvs_info.media_type == VSS_MEDIA_ID_4GV_WB_MODEM))
1154 ret = voice_set_dtx(v);
1155
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001156 break;
1157 }
1158
1159 case VSS_MEDIA_ID_AMR_NB_MODEM: {
1160 struct cvs_set_amr_enc_rate_cmd cvs_set_amr_rate;
1161
1162 pr_info("%s: Setting AMR rate\n", __func__);
1163
1164 cvs_set_amr_rate.hdr.hdr_field =
1165 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1166 APR_HDR_LEN(APR_HDR_SIZE),
1167 APR_PKT_VER);
1168 cvs_set_amr_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1169 sizeof(cvs_set_amr_rate) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001170 cvs_set_amr_rate.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001171 cvs_set_amr_rate.hdr.dest_port = cvs_handle;
1172 cvs_set_amr_rate.hdr.token = 0;
1173 cvs_set_amr_rate.hdr.opcode =
1174 VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE;
Neema Shetty90189b82011-06-27 14:58:37 -07001175 cvs_set_amr_rate.amr_rate.mode = common.mvs_info.rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001176
1177 v->cvs_state = CMD_STATUS_FAIL;
1178
1179 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_amr_rate);
1180 if (ret < 0) {
1181 pr_err("%s: Error %d sending SET_AMR_RATE\n",
1182 __func__, ret);
1183
1184 goto done;
1185 }
1186
1187 ret = wait_event_timeout(v->cvs_wait,
1188 (v->cvs_state == CMD_STATUS_SUCCESS),
1189 msecs_to_jiffies(TIMEOUT_MS));
1190 if (!ret) {
1191 pr_err("%s: wait_event timeout\n", __func__);
1192
1193 ret = -EINVAL;
1194 goto done;
1195 }
1196
1197 ret = voice_set_dtx(v);
1198
1199 break;
1200 }
1201
1202 case VSS_MEDIA_ID_AMR_WB_MODEM: {
1203 struct cvs_set_amrwb_enc_rate_cmd cvs_set_amrwb_rate;
1204
1205 pr_info("%s: Setting AMR WB rate\n", __func__);
1206
1207 cvs_set_amrwb_rate.hdr.hdr_field =
1208 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1209 APR_HDR_LEN(APR_HDR_SIZE),
1210 APR_PKT_VER);
1211 cvs_set_amrwb_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1212 sizeof(cvs_set_amrwb_rate) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001213 cvs_set_amrwb_rate.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001214 cvs_set_amrwb_rate.hdr.dest_port = cvs_handle;
1215 cvs_set_amrwb_rate.hdr.token = 0;
1216 cvs_set_amrwb_rate.hdr.opcode =
1217 VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE;
Neema Shetty90189b82011-06-27 14:58:37 -07001218 cvs_set_amrwb_rate.amrwb_rate.mode = common.mvs_info.rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001219
1220 v->cvs_state = CMD_STATUS_FAIL;
1221
1222 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_amrwb_rate);
1223 if (ret < 0) {
1224 pr_err("%s: Error %d sending SET_AMRWB_RATE\n",
1225 __func__, ret);
1226
1227 goto done;
1228 }
1229
1230 ret = wait_event_timeout(v->cvs_wait,
1231 (v->cvs_state == CMD_STATUS_SUCCESS),
1232 msecs_to_jiffies(TIMEOUT_MS));
1233 if (!ret) {
1234 pr_err("%s: wait_event timeout\n", __func__);
1235
1236 ret = -EINVAL;
1237 goto done;
1238 }
1239
1240 ret = voice_set_dtx(v);
1241
1242 break;
1243 }
1244
Chaithanya Krishna Bacharaju68993b52011-10-18 08:41:30 +05301245 case VSS_MEDIA_ID_EFR_MODEM:
1246 case VSS_MEDIA_ID_FR_MODEM:
1247 case VSS_MEDIA_ID_HR_MODEM:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001248 case VSS_MEDIA_ID_G729:
1249 case VSS_MEDIA_ID_G711_ALAW:
1250 case VSS_MEDIA_ID_G711_MULAW: {
1251 ret = voice_set_dtx(v);
1252
1253 break;
1254 }
1255
1256 default: {
1257 /* Do nothing. */
1258 }
1259 }
1260
1261done:
1262 return ret;
1263}
1264
1265static int voice_send_start_voice_cmd(struct voice_data *v)
1266{
1267 struct apr_hdr mvm_start_voice_cmd;
1268 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001269 void *apr_mvm = voice_get_apr_mvm();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001270 u16 mvm_handle = voice_get_mvm_handle(v);
1271
1272 mvm_start_voice_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1273 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1274 mvm_start_voice_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1275 sizeof(mvm_start_voice_cmd) - APR_HDR_SIZE);
1276 pr_info("send mvm_start_voice_cmd pkt size = %d\n",
1277 mvm_start_voice_cmd.pkt_size);
Neema Shetty90189b82011-06-27 14:58:37 -07001278 mvm_start_voice_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001279 mvm_start_voice_cmd.dest_port = mvm_handle;
1280 mvm_start_voice_cmd.token = 0;
1281 mvm_start_voice_cmd.opcode = VSS_IMVM_CMD_START_VOICE;
1282
1283 v->mvm_state = CMD_STATUS_FAIL;
1284 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_start_voice_cmd);
1285 if (ret < 0) {
1286 pr_err("Fail in sending VSS_IMVM_CMD_START_VOICE\n");
1287 goto fail;
1288 }
1289 ret = wait_event_timeout(v->mvm_wait,
1290 (v->mvm_state == CMD_STATUS_SUCCESS),
1291 msecs_to_jiffies(TIMEOUT_MS));
1292 if (!ret) {
1293 pr_err("%s: wait_event timeout\n", __func__);
1294 goto fail;
1295 }
1296
1297 return 0;
1298fail:
1299 return -EINVAL;
1300}
1301
1302static int voice_disable_vocproc(struct voice_data *v)
1303{
1304 struct apr_hdr cvp_disable_cmd;
1305 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001306 void *apr_cvp = voice_get_apr_cvp();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001307 u16 cvp_handle = voice_get_cvp_handle(v);
1308
1309 /* disable vocproc and wait for respose */
1310 cvp_disable_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1311 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1312 cvp_disable_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1313 sizeof(cvp_disable_cmd) - APR_HDR_SIZE);
1314 pr_debug("cvp_disable_cmd pkt size = %d, cvp_handle=%d\n",
1315 cvp_disable_cmd.pkt_size, cvp_handle);
Neema Shetty90189b82011-06-27 14:58:37 -07001316 cvp_disable_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001317 cvp_disable_cmd.dest_port = cvp_handle;
1318 cvp_disable_cmd.token = 0;
1319 cvp_disable_cmd.opcode = VSS_IVOCPROC_CMD_DISABLE;
1320
1321 v->cvp_state = CMD_STATUS_FAIL;
1322 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_disable_cmd);
1323 if (ret < 0) {
1324 pr_err("Fail in sending VSS_IVOCPROC_CMD_DISABLE\n");
1325 goto fail;
1326 }
1327 ret = wait_event_timeout(v->cvp_wait,
1328 (v->cvp_state == CMD_STATUS_SUCCESS),
1329 msecs_to_jiffies(TIMEOUT_MS));
1330 if (!ret) {
1331 pr_err("%s: wait_event timeout\n", __func__);
1332 goto fail;
1333 }
Ben Rombergerfce8f512011-07-18 16:46:09 -07001334 rtac_remove_voice(v->cvs_handle);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001335
1336 return 0;
1337fail:
1338 return -EINVAL;
1339}
1340
1341static int voice_set_device(struct voice_data *v)
1342{
1343 struct cvp_set_device_cmd cvp_setdev_cmd;
1344 struct msm_snddev_info *dev_tx_info;
1345 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001346 void *apr_cvp = voice_get_apr_cvp();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001347 u16 cvp_handle = voice_get_cvp_handle(v);
1348
1349
1350 /* set device and wait for response */
1351 cvp_setdev_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1352 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1353 cvp_setdev_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1354 sizeof(cvp_setdev_cmd) - APR_HDR_SIZE);
1355 pr_debug(" send create cvp setdev, pkt size = %d\n",
1356 cvp_setdev_cmd.hdr.pkt_size);
Neema Shetty90189b82011-06-27 14:58:37 -07001357 cvp_setdev_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001358 cvp_setdev_cmd.hdr.dest_port = cvp_handle;
1359 cvp_setdev_cmd.hdr.token = 0;
1360 cvp_setdev_cmd.hdr.opcode = VSS_IVOCPROC_CMD_SET_DEVICE;
1361
1362 dev_tx_info = audio_dev_ctrl_find_dev(v->dev_tx.dev_id);
1363 if (IS_ERR(dev_tx_info)) {
1364 pr_err("bad dev_id %d\n", v->dev_tx.dev_id);
1365 goto fail;
1366 }
1367
1368 cvp_setdev_cmd.cvp_set_device.tx_topology_id =
1369 get_voice_tx_topology();
1370 if (cvp_setdev_cmd.cvp_set_device.tx_topology_id == 0) {
1371 if (dev_tx_info->channel_mode > 1)
1372 cvp_setdev_cmd.cvp_set_device.tx_topology_id =
1373 VSS_IVOCPROC_TOPOLOGY_ID_TX_DM_FLUENCE;
1374 else
1375 cvp_setdev_cmd.cvp_set_device.tx_topology_id =
1376 VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
1377 }
1378
1379 /* Use default topology if invalid value in ACDB */
1380 cvp_setdev_cmd.cvp_set_device.rx_topology_id =
1381 get_voice_rx_topology();
1382 if (cvp_setdev_cmd.cvp_set_device.rx_topology_id == 0)
1383 cvp_setdev_cmd.cvp_set_device.rx_topology_id =
1384 VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
1385 cvp_setdev_cmd.cvp_set_device.tx_port_id = v->dev_tx.dev_port_id;
1386 cvp_setdev_cmd.cvp_set_device.rx_port_id = v->dev_rx.dev_port_id;
1387 pr_info("topology=%d , tx_port_id=%d, rx_port_id=%d\n",
1388 cvp_setdev_cmd.cvp_set_device.tx_topology_id,
1389 cvp_setdev_cmd.cvp_set_device.tx_port_id,
1390 cvp_setdev_cmd.cvp_set_device.rx_port_id);
1391
1392 v->cvp_state = CMD_STATUS_FAIL;
1393 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_setdev_cmd);
1394 if (ret < 0) {
1395 pr_err("Fail in sending VOCPROC_FULL_CONTROL_SESSION\n");
1396 goto fail;
1397 }
1398 pr_debug("wait for cvp create session event\n");
1399 ret = wait_event_timeout(v->cvp_wait,
1400 (v->cvp_state == CMD_STATUS_SUCCESS),
1401 msecs_to_jiffies(TIMEOUT_MS));
1402 if (!ret) {
1403 pr_err("%s: wait_event timeout\n", __func__);
1404 goto fail;
1405 }
1406
1407 /* send cvs cal */
1408 voice_send_cvs_cal_to_modem(v);
1409
1410 /* send cvp cal */
1411 voice_send_cvp_cal_to_modem(v);
1412
1413 /* send cvp vol table cal */
1414 voice_send_cvp_vol_tbl_to_modem(v);
1415
1416 /* enable vocproc and wait for respose */
1417 voice_send_enable_vocproc_cmd(v);
1418
1419 /* send tty mode if tty device is used */
1420 voice_send_tty_mode_to_modem(v);
1421
Neema Shetty90189b82011-06-27 14:58:37 -07001422 if (is_voip_session(v->session_id))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001423 voice_send_netid_timing_cmd(v);
1424
Ben Rombergerfce8f512011-07-18 16:46:09 -07001425 rtac_add_voice(v->cvs_handle, v->cvp_handle,
Ben Rombergerc5d6a372011-09-22 18:01:49 -07001426 v->dev_rx.dev_port_id, v->dev_tx.dev_port_id,
1427 v->session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001428
1429 return 0;
1430fail:
1431 return -EINVAL;
1432}
1433
1434static int voice_send_stop_voice_cmd(struct voice_data *v)
1435{
1436 struct apr_hdr mvm_stop_voice_cmd;
1437 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001438 void *apr_mvm = voice_get_apr_mvm();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001439 u16 mvm_handle = voice_get_mvm_handle(v);
1440
1441 mvm_stop_voice_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1442 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1443 mvm_stop_voice_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1444 sizeof(mvm_stop_voice_cmd) - APR_HDR_SIZE);
1445 pr_info("send mvm_stop_voice_cmd pkt size = %d\n",
1446 mvm_stop_voice_cmd.pkt_size);
Neema Shetty90189b82011-06-27 14:58:37 -07001447 mvm_stop_voice_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001448 mvm_stop_voice_cmd.dest_port = mvm_handle;
1449 mvm_stop_voice_cmd.token = 0;
1450 mvm_stop_voice_cmd.opcode = VSS_IMVM_CMD_STOP_VOICE;
1451
1452 v->mvm_state = CMD_STATUS_FAIL;
1453 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_stop_voice_cmd);
1454 if (ret < 0) {
1455 pr_err("Fail in sending VSS_IMVM_CMD_STOP_VOICE\n");
1456 goto fail;
1457 }
1458 ret = wait_event_timeout(v->mvm_wait,
1459 (v->mvm_state == CMD_STATUS_SUCCESS),
1460 msecs_to_jiffies(TIMEOUT_MS));
1461 if (!ret) {
1462 pr_err("%s: wait_event timeout\n", __func__);
1463 goto fail;
1464 }
1465
1466 return 0;
1467fail:
1468 return -EINVAL;
1469}
1470
1471static int voice_setup_modem_voice(struct voice_data *v)
1472{
1473 struct cvp_create_full_ctl_session_cmd cvp_session_cmd;
1474 int ret = 0;
1475 struct msm_snddev_info *dev_tx_info;
Neema Shetty90189b82011-06-27 14:58:37 -07001476 void *apr_cvp = voice_get_apr_cvp();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001477
1478 /* create cvp session and wait for response */
1479 cvp_session_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1480 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1481 cvp_session_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1482 sizeof(cvp_session_cmd) - APR_HDR_SIZE);
1483 pr_info(" send create cvp session, pkt size = %d\n",
1484 cvp_session_cmd.hdr.pkt_size);
Neema Shetty90189b82011-06-27 14:58:37 -07001485 cvp_session_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001486 cvp_session_cmd.hdr.dest_port = 0;
1487 cvp_session_cmd.hdr.token = 0;
1488 cvp_session_cmd.hdr.opcode =
1489 VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION;
1490
1491 dev_tx_info = audio_dev_ctrl_find_dev(v->dev_tx.dev_id);
1492 if (IS_ERR(dev_tx_info)) {
1493 pr_err("bad dev_id %d\n", v->dev_tx.dev_id);
1494 goto fail;
1495 }
1496
1497 /* Use default topology if invalid value in ACDB */
1498 cvp_session_cmd.cvp_session.tx_topology_id =
1499 get_voice_tx_topology();
1500 if (cvp_session_cmd.cvp_session.tx_topology_id == 0) {
1501 if (dev_tx_info->channel_mode > 1)
1502 cvp_session_cmd.cvp_session.tx_topology_id =
1503 VSS_IVOCPROC_TOPOLOGY_ID_TX_DM_FLUENCE;
1504 else
1505 cvp_session_cmd.cvp_session.tx_topology_id =
1506 VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
1507 }
1508
1509 cvp_session_cmd.cvp_session.rx_topology_id =
1510 get_voice_rx_topology();
1511 if (cvp_session_cmd.cvp_session.rx_topology_id == 0)
1512 cvp_session_cmd.cvp_session.rx_topology_id =
1513 VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
1514
1515 cvp_session_cmd.cvp_session.direction = 2; /*tx and rx*/
1516 cvp_session_cmd.cvp_session.network_id = VSS_NETWORK_ID_DEFAULT;
1517 cvp_session_cmd.cvp_session.tx_port_id = v->dev_tx.dev_port_id;
1518 cvp_session_cmd.cvp_session.rx_port_id = v->dev_rx.dev_port_id;
1519 pr_info("topology=%d net_id=%d, dir=%d tx_port_id=%d, rx_port_id=%d\n",
1520 cvp_session_cmd.cvp_session.tx_topology_id,
1521 cvp_session_cmd.cvp_session.network_id,
1522 cvp_session_cmd.cvp_session.direction,
1523 cvp_session_cmd.cvp_session.tx_port_id,
1524 cvp_session_cmd.cvp_session.rx_port_id);
1525
1526 v->cvp_state = CMD_STATUS_FAIL;
1527 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_session_cmd);
1528 if (ret < 0) {
1529 pr_err("Fail in sending VOCPROC_FULL_CONTROL_SESSION\n");
1530 goto fail;
1531 }
1532 pr_debug("wait for cvp create session event\n");
1533 ret = wait_event_timeout(v->cvp_wait,
1534 (v->cvp_state == CMD_STATUS_SUCCESS),
1535 msecs_to_jiffies(TIMEOUT_MS));
1536 if (!ret) {
1537 pr_err("%s: wait_event timeout\n", __func__);
1538 goto fail;
1539 }
1540
1541 /* send cvs cal */
1542 voice_send_cvs_cal_to_modem(v);
1543
1544 /* send cvp cal */
1545 voice_send_cvp_cal_to_modem(v);
1546
1547 /* send cvp vol table cal */
1548 voice_send_cvp_vol_tbl_to_modem(v);
1549
1550 return 0;
1551
1552fail:
1553 return -EINVAL;
1554}
1555
1556static int voice_send_enable_vocproc_cmd(struct voice_data *v)
1557{
1558 int ret = 0;
1559 struct apr_hdr cvp_enable_cmd;
1560
1561 u16 cvp_handle = voice_get_cvp_handle(v);
Neema Shetty90189b82011-06-27 14:58:37 -07001562 void *apr_cvp = voice_get_apr_cvp();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001563
1564 /* enable vocproc and wait for respose */
1565 cvp_enable_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1566 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1567 cvp_enable_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1568 sizeof(cvp_enable_cmd) - APR_HDR_SIZE);
1569 pr_debug("cvp_enable_cmd pkt size = %d, cvp_handle=%d\n",
1570 cvp_enable_cmd.pkt_size, cvp_handle);
Neema Shetty90189b82011-06-27 14:58:37 -07001571 cvp_enable_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001572 cvp_enable_cmd.dest_port = cvp_handle;
1573 cvp_enable_cmd.token = 0;
1574 cvp_enable_cmd.opcode = VSS_IVOCPROC_CMD_ENABLE;
1575
1576 v->cvp_state = CMD_STATUS_FAIL;
1577 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_enable_cmd);
1578 if (ret < 0) {
1579 pr_err("Fail in sending VSS_IVOCPROC_CMD_ENABLE\n");
1580 goto fail;
1581 }
1582 ret = wait_event_timeout(v->cvp_wait,
1583 (v->cvp_state == CMD_STATUS_SUCCESS),
1584 msecs_to_jiffies(TIMEOUT_MS));
1585 if (!ret) {
1586 pr_err("%s: wait_event timeout\n", __func__);
1587 goto fail;
1588 }
1589
1590 return 0;
1591fail:
1592 return -EINVAL;
1593}
1594
1595static int voice_send_netid_timing_cmd(struct voice_data *v)
1596{
1597 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001598 void *apr_mvm = voice_get_apr_mvm();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001599 struct mvm_set_network_cmd mvm_set_network;
1600 struct mvm_set_voice_timing_cmd mvm_set_voice_timing;
1601 u16 mvm_handle = voice_get_mvm_handle(v);
1602
1603 ret = voice_config_cvs_vocoder(v);
1604 if (ret < 0) {
1605 pr_err("%s: Error %d configuring CVS voc",
1606 __func__, ret);
1607 goto fail;
1608 }
1609 /* Set network ID. */
1610 pr_debug("%s: Setting network ID\n", __func__);
1611
1612 mvm_set_network.hdr.hdr_field =
1613 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1614 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1615 mvm_set_network.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1616 sizeof(mvm_set_network) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001617 mvm_set_network.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001618 mvm_set_network.hdr.dest_port = mvm_handle;
1619 mvm_set_network.hdr.token = 0;
1620 mvm_set_network.hdr.opcode = VSS_ICOMMON_CMD_SET_NETWORK;
Neema Shetty90189b82011-06-27 14:58:37 -07001621 mvm_set_network.network.network_id = common.mvs_info.network_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001622
1623 v->mvm_state = CMD_STATUS_FAIL;
1624 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_network);
1625 if (ret < 0) {
1626 pr_err("%s: Error %d sending SET_NETWORK\n", __func__, ret);
1627 goto fail;
1628 }
1629
1630 ret = wait_event_timeout(v->mvm_wait,
1631 (v->mvm_state == CMD_STATUS_SUCCESS),
1632 msecs_to_jiffies(TIMEOUT_MS));
1633 if (!ret) {
1634 pr_err("%s: wait_event timeout\n", __func__);
1635 goto fail;
1636 }
1637
1638 /* Set voice timing. */
1639 pr_debug("%s: Setting voice timing\n", __func__);
1640
1641 mvm_set_voice_timing.hdr.hdr_field =
1642 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1643 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1644 mvm_set_voice_timing.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1645 sizeof(mvm_set_voice_timing) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001646 mvm_set_voice_timing.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001647 mvm_set_voice_timing.hdr.dest_port = mvm_handle;
1648 mvm_set_voice_timing.hdr.token = 0;
1649 mvm_set_voice_timing.hdr.opcode =
1650 VSS_ICOMMON_CMD_SET_VOICE_TIMING;
1651 mvm_set_voice_timing.timing.mode = 0;
1652 mvm_set_voice_timing.timing.enc_offset = 8000;
1653 mvm_set_voice_timing.timing.dec_req_offset = 3300;
1654 mvm_set_voice_timing.timing.dec_offset = 8300;
1655
1656 v->mvm_state = CMD_STATUS_FAIL;
1657
1658 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_voice_timing);
1659 if (ret < 0) {
1660 pr_err("%s: Error %d sending SET_TIMING\n", __func__, ret);
1661 goto fail;
1662 }
1663
1664 ret = wait_event_timeout(v->mvm_wait,
1665 (v->mvm_state == CMD_STATUS_SUCCESS),
1666 msecs_to_jiffies(TIMEOUT_MS));
1667 if (!ret) {
1668 pr_err("%s: wait_event timeout\n", __func__);
1669 goto fail;
1670 }
1671
1672 return 0;
1673fail:
1674 return -EINVAL;
1675}
1676
1677static int voice_attach_vocproc(struct voice_data *v)
1678{
1679 int ret = 0;
1680 struct mvm_attach_vocproc_cmd mvm_a_vocproc_cmd;
Neema Shetty90189b82011-06-27 14:58:37 -07001681 void *apr_mvm = voice_get_apr_mvm();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001682 u16 mvm_handle = voice_get_mvm_handle(v);
1683 u16 cvp_handle = voice_get_cvp_handle(v);
1684
1685 /* send enable vocproc */
1686 voice_send_enable_vocproc_cmd(v);
1687
1688 /* attach vocproc and wait for response */
1689 mvm_a_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1690 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1691 mvm_a_vocproc_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1692 sizeof(mvm_a_vocproc_cmd) - APR_HDR_SIZE);
1693 pr_info("send mvm_a_vocproc_cmd pkt size = %d\n",
1694 mvm_a_vocproc_cmd.hdr.pkt_size);
Neema Shetty90189b82011-06-27 14:58:37 -07001695 mvm_a_vocproc_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001696 mvm_a_vocproc_cmd.hdr.dest_port = mvm_handle;
1697 mvm_a_vocproc_cmd.hdr.token = 0;
Neema Shetty7e4a9b52011-07-26 15:24:51 -07001698 mvm_a_vocproc_cmd.hdr.opcode = VSS_ISTREAM_CMD_ATTACH_VOCPROC;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001699 mvm_a_vocproc_cmd.mvm_attach_cvp_handle.handle = cvp_handle;
1700
1701 v->mvm_state = CMD_STATUS_FAIL;
1702 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_a_vocproc_cmd);
1703 if (ret < 0) {
Neema Shetty7e4a9b52011-07-26 15:24:51 -07001704 pr_err("Fail in sending VSS_ISTREAM_CMD_ATTACH_VOCPROC\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001705 goto fail;
1706 }
1707 ret = wait_event_timeout(v->mvm_wait,
1708 (v->mvm_state == CMD_STATUS_SUCCESS),
1709 msecs_to_jiffies(TIMEOUT_MS));
1710 if (!ret) {
1711 pr_err("%s: wait_event timeout\n", __func__);
1712 goto fail;
1713 }
1714
1715 /* send tty mode if tty device is used */
1716 voice_send_tty_mode_to_modem(v);
1717
Neema Shetty90189b82011-06-27 14:58:37 -07001718 if (is_voip_session(v->session_id))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001719 voice_send_netid_timing_cmd(v);
1720
Ben Rombergerfce8f512011-07-18 16:46:09 -07001721 rtac_add_voice(v->cvs_handle, v->cvp_handle,
Ben Rombergerc5d6a372011-09-22 18:01:49 -07001722 v->dev_rx.dev_port_id, v->dev_tx.dev_port_id,
1723 v->session_id);
Ben Rombergerfce8f512011-07-18 16:46:09 -07001724
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001725 return 0;
1726fail:
1727 return -EINVAL;
1728}
1729
1730static int voice_destroy_modem_voice(struct voice_data *v)
1731{
1732 struct mvm_detach_vocproc_cmd mvm_d_vocproc_cmd;
1733 struct apr_hdr cvp_destroy_session_cmd;
1734 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001735 void *apr_mvm = voice_get_apr_mvm();
1736 void *apr_cvp = voice_get_apr_cvp();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001737 u16 mvm_handle = voice_get_mvm_handle(v);
1738 u16 cvp_handle = voice_get_cvp_handle(v);
1739
1740 /* detach VOCPROC and wait for response from mvm */
1741 mvm_d_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1742 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1743 mvm_d_vocproc_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1744 sizeof(mvm_d_vocproc_cmd) - APR_HDR_SIZE);
1745 pr_info("mvm_d_vocproc_cmd pkt size = %d\n",
1746 mvm_d_vocproc_cmd.hdr.pkt_size);
Neema Shetty90189b82011-06-27 14:58:37 -07001747 mvm_d_vocproc_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001748 mvm_d_vocproc_cmd.hdr.dest_port = mvm_handle;
1749 mvm_d_vocproc_cmd.hdr.token = 0;
Neema Shetty7e4a9b52011-07-26 15:24:51 -07001750 mvm_d_vocproc_cmd.hdr.opcode = VSS_ISTREAM_CMD_DETACH_VOCPROC;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001751 mvm_d_vocproc_cmd.mvm_detach_cvp_handle.handle = cvp_handle;
1752
1753 v->mvm_state = CMD_STATUS_FAIL;
1754 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_d_vocproc_cmd);
1755 if (ret < 0) {
Neema Shetty7e4a9b52011-07-26 15:24:51 -07001756 pr_err("Fail in sending VSS_ISTREAM_CMD_DETACH_VOCPROC\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001757 goto fail;
1758 }
1759 ret = wait_event_timeout(v->mvm_wait,
1760 (v->mvm_state == CMD_STATUS_SUCCESS),
1761 msecs_to_jiffies(TIMEOUT_MS));
1762 if (!ret) {
1763 pr_err("%s: wait_event timeout\n", __func__);
1764 goto fail;
1765 }
1766
1767 /* destrop cvp session */
1768 cvp_destroy_session_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1769 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1770 cvp_destroy_session_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1771 sizeof(cvp_destroy_session_cmd) - APR_HDR_SIZE);
1772 pr_info("cvp_destroy_session_cmd pkt size = %d\n",
1773 cvp_destroy_session_cmd.pkt_size);
Neema Shetty90189b82011-06-27 14:58:37 -07001774 cvp_destroy_session_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001775 cvp_destroy_session_cmd.dest_port = cvp_handle;
1776 cvp_destroy_session_cmd.token = 0;
1777 cvp_destroy_session_cmd.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
1778
1779 v->cvp_state = CMD_STATUS_FAIL;
1780 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_destroy_session_cmd);
1781 if (ret < 0) {
1782 pr_err("Fail in sending APRV2_IBASIC_CMD_DESTROY_SESSION\n");
1783 goto fail;
1784 }
1785 ret = wait_event_timeout(v->cvp_wait,
1786 (v->cvp_state == CMD_STATUS_SUCCESS),
1787 msecs_to_jiffies(TIMEOUT_MS));
1788 if (!ret) {
1789 pr_err("%s: wait_event timeout\n", __func__);
1790 goto fail;
1791 }
Ben Rombergerfce8f512011-07-18 16:46:09 -07001792 rtac_remove_voice(v->cvs_handle);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001793 cvp_handle = 0;
1794 voice_set_cvp_handle(v, cvp_handle);
1795
1796 return 0;
1797
1798fail:
1799 return -EINVAL;
1800}
1801
1802static int voice_send_mute_cmd_to_modem(struct voice_data *v)
1803{
1804 struct cvs_set_mute_cmd cvs_mute_cmd;
1805 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001806 void *apr_cvs = voice_get_apr_cvs();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001807 u16 cvs_handle = voice_get_cvs_handle(v);
1808
1809 /* send mute/unmute to cvs */
1810 cvs_mute_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1811 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1812 cvs_mute_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1813 sizeof(cvs_mute_cmd) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001814 cvs_mute_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001815 cvs_mute_cmd.hdr.dest_port = cvs_handle;
1816 cvs_mute_cmd.hdr.token = 0;
1817 cvs_mute_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_MUTE;
1818 cvs_mute_cmd.cvs_set_mute.direction = 0; /*tx*/
1819 cvs_mute_cmd.cvs_set_mute.mute_flag = v->dev_tx.mute;
1820
1821 pr_info(" mute value =%d\n", cvs_mute_cmd.cvs_set_mute.mute_flag);
1822 v->cvs_state = CMD_STATUS_FAIL;
1823 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_mute_cmd);
1824 if (ret < 0) {
1825 pr_err("Fail: send STREAM SET MUTE\n");
1826 goto fail;
1827 }
1828 ret = wait_event_timeout(v->cvs_wait,
1829 (v->cvs_state == CMD_STATUS_SUCCESS),
1830 msecs_to_jiffies(TIMEOUT_MS));
1831 if (!ret)
1832 pr_err("%s: wait_event timeout\n", __func__);
1833
1834fail:
1835 return 0;
1836}
1837
1838static int voice_send_vol_index_to_modem(struct voice_data *v)
1839{
1840 struct cvp_set_rx_volume_index_cmd cvp_vol_cmd;
1841 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001842 void *apr_cvp = voice_get_apr_cvp();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001843 u16 cvp_handle = voice_get_cvp_handle(v);
1844
1845 /* send volume index to cvp */
1846 cvp_vol_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1847 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1848 cvp_vol_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1849 sizeof(cvp_vol_cmd) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001850 cvp_vol_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001851 cvp_vol_cmd.hdr.dest_port = cvp_handle;
1852 cvp_vol_cmd.hdr.token = 0;
1853 cvp_vol_cmd.hdr.opcode =
1854 VSS_IVOCPROC_CMD_SET_RX_VOLUME_INDEX;
1855 cvp_vol_cmd.cvp_set_vol_idx.vol_index = v->dev_rx.volume;
1856 v->cvp_state = CMD_STATUS_FAIL;
1857 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_vol_cmd);
1858 if (ret < 0) {
1859 pr_err("Fail in sending RX VOL INDEX\n");
1860 return -EINVAL;
1861 }
1862 ret = wait_event_timeout(v->cvp_wait,
1863 (v->cvp_state == CMD_STATUS_SUCCESS),
1864 msecs_to_jiffies(TIMEOUT_MS));
1865 if (!ret) {
1866 pr_err("%s: wait_event timeout\n", __func__);
1867 return -EINVAL;
1868 }
1869 return 0;
1870}
1871
1872static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode)
1873{
1874 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001875 void *apr_cvs = voice_get_apr_cvs();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001876 u16 cvs_handle = voice_get_cvs_handle(v);
1877 struct cvs_start_record_cmd cvs_start_record;
1878
1879 pr_debug("%s: Start record %d\n", __func__, rec_mode);
1880
1881 cvs_start_record.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1882 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1883 cvs_start_record.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1884 sizeof(cvs_start_record) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001885 cvs_start_record.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001886 cvs_start_record.hdr.dest_port = cvs_handle;
1887 cvs_start_record.hdr.token = 0;
1888 cvs_start_record.hdr.opcode = VSS_ISTREAM_CMD_START_RECORD;
1889
1890 if (rec_mode == VOC_REC_UPLINK) {
1891 cvs_start_record.rec_mode.rx_tap_point = VSS_TAP_POINT_NONE;
1892 cvs_start_record.rec_mode.tx_tap_point =
1893 VSS_TAP_POINT_STREAM_END;
1894 } else if (rec_mode == VOC_REC_DOWNLINK) {
1895 cvs_start_record.rec_mode.rx_tap_point =
1896 VSS_TAP_POINT_STREAM_END;
1897 cvs_start_record.rec_mode.tx_tap_point = VSS_TAP_POINT_NONE;
1898 } else if (rec_mode == VOC_REC_BOTH) {
1899 cvs_start_record.rec_mode.rx_tap_point =
1900 VSS_TAP_POINT_STREAM_END;
1901 cvs_start_record.rec_mode.tx_tap_point =
1902 VSS_TAP_POINT_STREAM_END;
1903 } else {
1904 pr_err("%s: Invalid in-call rec_mode %d\n", __func__, rec_mode);
1905
1906 ret = -EINVAL;
1907 goto fail;
1908 }
1909
1910 v->cvs_state = CMD_STATUS_FAIL;
1911
1912 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_start_record);
1913 if (ret < 0) {
1914 pr_err("%s: Error %d sending START_RECORD\n", __func__, ret);
1915
1916 goto fail;
1917 }
1918
1919 ret = wait_event_timeout(v->cvs_wait,
1920 (v->cvs_state == CMD_STATUS_SUCCESS),
1921 msecs_to_jiffies(TIMEOUT_MS));
1922 if (!ret) {
1923 pr_err("%s: wait_event timeout\n", __func__);
1924
1925 goto fail;
1926 }
1927
1928 return 0;
1929
1930fail:
1931 return ret;
1932}
1933
1934static int voice_cvs_stop_record(struct voice_data *v)
1935{
1936 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001937 void *apr_cvs = voice_get_apr_cvs();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001938 u16 cvs_handle = voice_get_cvs_handle(v);
1939 struct apr_hdr cvs_stop_record;
1940
1941 pr_debug("%s: Stop record\n", __func__);
1942
1943 cvs_stop_record.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1944 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1945 cvs_stop_record.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1946 sizeof(cvs_stop_record) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001947 cvs_stop_record.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001948 cvs_stop_record.dest_port = cvs_handle;
1949 cvs_stop_record.token = 0;
1950 cvs_stop_record.opcode = VSS_ISTREAM_CMD_STOP_RECORD;
1951
1952 v->cvs_state = CMD_STATUS_FAIL;
1953
1954 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_stop_record);
1955 if (ret < 0) {
1956 pr_err("%s: Error %d sending STOP_RECORD\n", __func__, ret);
1957
1958 goto fail;
1959 }
1960
1961 ret = wait_event_timeout(v->cvs_wait,
1962 (v->cvs_state == CMD_STATUS_SUCCESS),
1963 msecs_to_jiffies(TIMEOUT_MS));
1964 if (!ret) {
1965 pr_err("%s: wait_event timeout\n", __func__);
1966
1967 goto fail;
1968 }
1969
1970 return 0;
1971
1972fail:
1973 return ret;
1974}
1975
1976int voice_start_record(uint32_t rec_mode, uint32_t set)
1977{
Neema Shetty90189b82011-06-27 14:58:37 -07001978 int ret = 0, i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001979 u16 cvs_handle;
1980
1981 pr_debug("%s: rec_mode %d, set %d\n", __func__, rec_mode, set);
1982
Neema Shetty90189b82011-06-27 14:58:37 -07001983 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
1984 struct voice_data *v = &common.voice[i];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001985
Neema Shetty90189b82011-06-27 14:58:37 -07001986 mutex_lock(&v->lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001987
Neema Shetty90189b82011-06-27 14:58:37 -07001988 cvs_handle = voice_get_cvs_handle(v);
1989
1990 if (cvs_handle != 0) {
1991 if (set)
1992 ret = voice_cvs_start_record(v, rec_mode);
1993 else
1994 ret = voice_cvs_stop_record(v);
1995 } else {
1996 /* Cache the value for later. */
1997 v->rec_info.pending = set;
1998 v->rec_info.rec_mode = rec_mode;
1999 }
2000
2001 mutex_unlock(&v->lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002002 }
2003
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002004 return ret;
2005}
2006
2007static int voice_cvs_start_playback(struct voice_data *v)
2008{
2009 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07002010 void *apr_cvs = voice_get_apr_cvs();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002011 u16 cvs_handle = voice_get_cvs_handle(v);
2012 struct apr_hdr cvs_start_playback;
2013
2014 pr_debug("%s: Start playback\n", __func__);
2015
2016 cvs_start_playback.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2017 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2018 cvs_start_playback.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2019 sizeof(cvs_start_playback) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07002020 cvs_start_playback.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002021 cvs_start_playback.dest_port = cvs_handle;
2022 cvs_start_playback.token = 0;
2023 cvs_start_playback.opcode = VSS_ISTREAM_CMD_START_PLAYBACK;
2024
2025 v->cvs_state = CMD_STATUS_FAIL;
2026
2027 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_start_playback);
2028 if (ret < 0) {
2029 pr_err("%s: Error %d sending START_PLAYBACK\n",
2030 __func__, ret);
2031
2032 goto fail;
2033 }
2034
2035 ret = wait_event_timeout(v->cvs_wait,
2036 (v->cvs_state == CMD_STATUS_SUCCESS),
2037 msecs_to_jiffies(TIMEOUT_MS));
2038 if (!ret) {
2039 pr_err("%s: wait_event timeout\n", __func__);
2040
2041 goto fail;
2042 }
2043
2044 v->music_info.playing = 1;
2045
2046 return 0;
2047
2048fail:
2049 return ret;
2050}
2051
2052static int voice_cvs_stop_playback(struct voice_data *v)
2053{
2054 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07002055 void *apr_cvs = voice_get_apr_cvs();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002056 u16 cvs_handle = voice_get_cvs_handle(v);
2057 struct apr_hdr cvs_stop_playback;
2058
2059 pr_debug("%s: Stop playback\n", __func__);
2060
2061 if (v->music_info.playing) {
2062 cvs_stop_playback.hdr_field =
2063 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2064 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2065 cvs_stop_playback.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2066 sizeof(cvs_stop_playback) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07002067 cvs_stop_playback.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002068 cvs_stop_playback.dest_port = cvs_handle;
2069 cvs_stop_playback.token = 0;
2070
2071 cvs_stop_playback.opcode = VSS_ISTREAM_CMD_STOP_PLAYBACK;
2072
2073 v->cvs_state = CMD_STATUS_FAIL;
2074
2075 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_stop_playback);
2076 if (ret < 0) {
2077 pr_err("%s: Error %d sending STOP_PLAYBACK\n",
2078 __func__, ret);
2079
2080 goto fail;
2081 }
2082
2083 ret = wait_event_timeout(v->cvs_wait,
2084 (v->cvs_state == CMD_STATUS_SUCCESS),
2085 msecs_to_jiffies(TIMEOUT_MS));
2086 if (!ret) {
2087 pr_err("%s: wait_event timeout\n", __func__);
2088
2089 goto fail;
2090 }
2091
2092 v->music_info.playing = 0;
2093 } else {
2094 pr_err("%s: Stop playback already sent\n", __func__);
2095 }
2096
2097 return 0;
2098
2099fail:
2100 return ret;
2101}
2102
2103int voice_start_playback(uint32_t set)
2104{
Neema Shetty90189b82011-06-27 14:58:37 -07002105 int ret = 0, i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002106 u16 cvs_handle;
2107
2108 pr_debug("%s: Start playback %d\n", __func__, set);
2109
Neema Shetty90189b82011-06-27 14:58:37 -07002110 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
2111 struct voice_data *v = &common.voice[i];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002112
Neema Shetty90189b82011-06-27 14:58:37 -07002113 mutex_lock(&v->lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002114
Neema Shetty90189b82011-06-27 14:58:37 -07002115 cvs_handle = voice_get_cvs_handle(v);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002116
Neema Shetty90189b82011-06-27 14:58:37 -07002117 if (cvs_handle != 0) {
2118 if (set)
2119 ret = voice_cvs_start_playback(v);
2120 else
2121 ret = voice_cvs_stop_playback(v);
2122 } else {
2123 /* Cache the value for later. */
2124 pr_debug("%s: Caching ICP value", __func__);
2125
2126 v->music_info.pending = set;
2127 }
2128
2129 mutex_unlock(&v->lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002130 }
2131
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002132 return ret;
2133}
2134
2135static void voice_auddev_cb_function(u32 evt_id,
2136 union auddev_evt_data *evt_payload,
2137 void *private_data)
2138{
Neema Shetty90189b82011-06-27 14:58:37 -07002139 struct common_data *c = private_data;
2140 struct voice_data *v = NULL;
2141
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002142 struct sidetone_cal sidetone_cal_data;
Neema Shetty90189b82011-06-27 14:58:37 -07002143 int rc = 0, i = 0;
Bharath Ramachandramurthyb9209472011-09-27 17:56:20 -07002144 int rc1 = 0;
2145
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002146 pr_info("auddev_cb_function, evt_id=%d,\n", evt_id);
Neema Shetty90189b82011-06-27 14:58:37 -07002147
2148 if (evt_payload == NULL) {
2149 pr_err("%s: evt_payload is NULL pointer\n", __func__);
2150 return;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002151 }
2152
2153 switch (evt_id) {
2154 case AUDDEV_EVT_START_VOICE:
Neema Shetty90189b82011-06-27 14:58:37 -07002155 v = voice_get_session(evt_payload->voice_session_id);
2156 if (v == NULL) {
2157 pr_err("%s: v is NULL\n", __func__);
2158 return;
2159 }
2160
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002161 mutex_lock(&v->lock);
2162
2163 if ((v->voc_state == VOC_INIT) ||
2164 (v->voc_state == VOC_RELEASE)) {
2165 v->v_call_status = VOICE_CALL_START;
2166 if ((v->dev_rx.enabled == VOICE_DEV_ENABLED)
2167 && (v->dev_tx.enabled == VOICE_DEV_ENABLED)) {
Neema Shetty90189b82011-06-27 14:58:37 -07002168 rc = voice_apr_register();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002169 if (rc < 0) {
2170 pr_err("%s: voice apr registration"
2171 "failed\n", __func__);
2172 mutex_unlock(&v->lock);
2173 return;
2174 }
Bharath Ramachandramurthyb9209472011-09-27 17:56:20 -07002175 rc1 = voice_create_mvm_cvs_session(v);
2176 if (rc1 < 0) {
2177 pr_err("%s: create mvm-cvs failed\n",
2178 __func__);
2179 msleep(100);
2180 rc = voice_apr_register();
2181 if (rc < 0) {
2182 mutex_unlock(&v->lock);
2183 pr_err("%s: voice apr regn"
2184 "failed\n", __func__);
2185 return;
2186 }
2187 rc1 = voice_create_mvm_cvs_session(v);
2188 if (rc1 < 0) {
2189 mutex_unlock(&v->lock);
2190 pr_err("%s:Retry mvmcvs "
2191 "failed\n",
2192 __func__);
2193 return;
2194 }
2195 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002196 voice_setup_modem_voice(v);
2197 voice_attach_vocproc(v);
2198 voice_send_start_voice_cmd(v);
2199 get_sidetone_cal(&sidetone_cal_data);
2200 msm_snddev_enable_sidetone(
2201 v->dev_rx.dev_id,
2202 sidetone_cal_data.enable,
2203 sidetone_cal_data.gain);
2204 v->voc_state = VOC_RUN;
2205
2206 /* Start in-call recording if command was
2207 * pending. */
2208 if (v->rec_info.pending) {
2209 voice_cvs_start_record(v,
2210 v->rec_info.rec_mode);
2211
2212 v->rec_info.pending = 0;
2213 }
2214
2215 /* Start in-call music delivery if command was
2216 * pending. */
2217 if (v->music_info.pending) {
2218 voice_cvs_start_playback(v);
2219
2220 v->music_info.pending = 0;
2221 }
2222 }
2223 }
2224
2225 mutex_unlock(&v->lock);
2226 break;
2227 case AUDDEV_EVT_DEV_CHG_VOICE:
Neema Shetty90189b82011-06-27 14:58:37 -07002228 /* Device change is applicable to all sessions. */
2229 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
2230 v = &c->voice[i];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002231
Neema Shetty90189b82011-06-27 14:58:37 -07002232 if (v->dev_rx.enabled == VOICE_DEV_ENABLED)
2233 msm_snddev_enable_sidetone(v->dev_rx.dev_id,
2234 0, 0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002235
Neema Shetty90189b82011-06-27 14:58:37 -07002236 v->dev_rx.enabled = VOICE_DEV_DISABLED;
2237 v->dev_tx.enabled = VOICE_DEV_DISABLED;
2238
2239 mutex_lock(&v->lock);
2240
2241 if (v->voc_state == VOC_RUN) {
2242 /* send cmd to modem to do voice device
2243 * change */
2244 voice_disable_vocproc(v);
2245 v->voc_state = VOC_CHANGE;
2246 }
2247
2248 mutex_unlock(&v->lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002249 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002250 break;
2251 case AUDDEV_EVT_DEV_RDY:
Neema Shetty90189b82011-06-27 14:58:37 -07002252 /* Device change is applicable to all sessions. */
2253 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
2254 v = &c->voice[i];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002255
Neema Shetty90189b82011-06-27 14:58:37 -07002256 mutex_lock(&v->lock);
2257
2258 if (v->voc_state == VOC_CHANGE) {
2259 /* get port Ids */
2260 if (evt_payload->voc_devinfo.dev_type ==
2261 DIR_RX) {
2262 v->dev_rx.dev_port_id =
2263 evt_payload->voc_devinfo.dev_port_id;
2264 v->dev_rx.sample =
2265 evt_payload->voc_devinfo.dev_sample;
2266 v->dev_rx.dev_id =
2267 evt_payload->voc_devinfo.dev_id;
2268 v->dev_rx.enabled = VOICE_DEV_ENABLED;
2269 } else {
2270 v->dev_tx.dev_port_id =
2271 evt_payload->voc_devinfo.dev_port_id;
2272 v->dev_tx.sample =
2273 evt_payload->voc_devinfo.dev_sample;
2274 v->dev_tx.enabled = VOICE_DEV_ENABLED;
2275 v->dev_tx.dev_id =
2276 evt_payload->voc_devinfo.dev_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002277 }
Neema Shetty90189b82011-06-27 14:58:37 -07002278 if ((v->dev_rx.enabled == VOICE_DEV_ENABLED) &&
2279 (v->dev_tx.enabled == VOICE_DEV_ENABLED)) {
2280 voice_set_device(v);
2281 get_sidetone_cal(&sidetone_cal_data);
2282 msm_snddev_enable_sidetone(
2283 v->dev_rx.dev_id,
2284 sidetone_cal_data.enable,
2285 sidetone_cal_data.gain);
2286 v->voc_state = VOC_RUN;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002287 }
Neema Shetty90189b82011-06-27 14:58:37 -07002288 } else if ((v->voc_state == VOC_INIT) ||
2289 (v->voc_state == VOC_RELEASE)) {
2290 /* get AFE ports */
2291 if (evt_payload->voc_devinfo.dev_type ==
2292 DIR_RX) {
2293 /* get rx port id */
2294 v->dev_rx.dev_port_id =
2295 evt_payload->voc_devinfo.dev_port_id;
2296 v->dev_rx.sample =
2297 evt_payload->voc_devinfo.dev_sample;
2298 v->dev_rx.dev_id =
2299 evt_payload->voc_devinfo.dev_id;
2300 v->dev_rx.enabled = VOICE_DEV_ENABLED;
2301 } else {
2302 /* get tx port id */
2303 v->dev_tx.dev_port_id =
2304 evt_payload->voc_devinfo.dev_port_id;
2305 v->dev_tx.sample =
2306 evt_payload->voc_devinfo.dev_sample;
2307 v->dev_tx.dev_id =
2308 evt_payload->voc_devinfo.dev_id;
2309 v->dev_tx.enabled = VOICE_DEV_ENABLED;
2310 }
2311 if ((v->dev_rx.enabled == VOICE_DEV_ENABLED) &&
2312 (v->dev_tx.enabled == VOICE_DEV_ENABLED) &&
2313 (v->v_call_status == VOICE_CALL_START)) {
2314 rc = voice_apr_register();
2315 if (rc < 0) {
2316 pr_err("%s: voice apr"
2317 "registration failed\n",
2318 __func__);
2319 mutex_unlock(&v->lock);
2320 return;
2321 }
2322 voice_create_mvm_cvs_session(v);
2323 voice_setup_modem_voice(v);
2324 voice_attach_vocproc(v);
2325 voice_send_start_voice_cmd(v);
2326 get_sidetone_cal(&sidetone_cal_data);
2327 msm_snddev_enable_sidetone(
2328 v->dev_rx.dev_id,
2329 sidetone_cal_data.enable,
2330 sidetone_cal_data.gain);
2331 v->voc_state = VOC_RUN;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002332
Neema Shetty90189b82011-06-27 14:58:37 -07002333 /* Start in-call recording if command
2334 * was pending. */
2335 if (v->rec_info.pending) {
2336 voice_cvs_start_record(v,
2337 v->rec_info.rec_mode);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002338
Neema Shetty90189b82011-06-27 14:58:37 -07002339 v->rec_info.pending = 0;
2340 }
2341
2342 /* Start in-call music delivery if
2343 * command was pending. */
2344 if (v->music_info.pending) {
2345 voice_cvs_start_playback(v);
2346
2347 v->music_info.pending = 0;
2348 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002349 }
2350 }
Neema Shetty90189b82011-06-27 14:58:37 -07002351
2352 mutex_unlock(&v->lock);
2353 }
2354 break;
2355 case AUDDEV_EVT_DEVICE_VOL_MUTE_CHG:
2356 v = voice_get_session(
2357 evt_payload->voc_vm_info.voice_session_id);
2358 if (v == NULL) {
2359 pr_err("%s: v is NULL\n", __func__);
2360 return;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002361 }
2362
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002363 /* cache the mute and volume index value */
Neema Shetty90189b82011-06-27 14:58:37 -07002364 if (evt_payload->voc_vm_info.dev_type == DIR_TX) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002365 v->dev_tx.mute =
2366 evt_payload->voc_vm_info.dev_vm_val.mute;
2367
2368 mutex_lock(&v->lock);
2369
2370 if (v->voc_state == VOC_RUN)
2371 voice_send_mute_cmd_to_modem(v);
2372
2373 mutex_unlock(&v->lock);
2374 } else {
Neema Shetty90189b82011-06-27 14:58:37 -07002375 v->dev_rx.volume =
2376 evt_payload->voc_vm_info.dev_vm_val.vol;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002377
2378 mutex_lock(&v->lock);
2379
2380 if (v->voc_state == VOC_RUN)
2381 voice_send_vol_index_to_modem(v);
2382
2383 mutex_unlock(&v->lock);
2384 }
2385 break;
2386 case AUDDEV_EVT_REL_PENDING:
Neema Shetty90189b82011-06-27 14:58:37 -07002387 /* Device change is applicable to all sessions. */
2388 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
2389 v = &c->voice[i];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002390
Neema Shetty90189b82011-06-27 14:58:37 -07002391 mutex_lock(&v->lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002392
Neema Shetty90189b82011-06-27 14:58:37 -07002393 if (v->voc_state == VOC_RUN) {
2394 voice_disable_vocproc(v);
2395 v->voc_state = VOC_CHANGE;
2396 }
2397
2398 mutex_unlock(&v->lock);
2399
2400 if (evt_payload->voc_devinfo.dev_type == DIR_RX)
2401 v->dev_rx.enabled = VOICE_DEV_DISABLED;
2402 else
2403 v->dev_tx.enabled = VOICE_DEV_DISABLED;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002404 }
2405
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002406 break;
2407 case AUDDEV_EVT_END_VOICE:
Neema Shetty90189b82011-06-27 14:58:37 -07002408 v = voice_get_session(evt_payload->voice_session_id);
2409 if (v == NULL) {
2410 pr_err("%s: v is NULL\n", __func__);
2411 return;
2412 }
2413
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002414 /* recover the tx mute and rx volume to the default values */
Neema Shetty90189b82011-06-27 14:58:37 -07002415 v->dev_tx.mute = c->default_mute_val;
2416 v->dev_rx.volume = c->default_vol_val;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002417 if (v->dev_rx.enabled == VOICE_DEV_ENABLED)
2418 msm_snddev_enable_sidetone(v->dev_rx.dev_id, 0, 0);
2419
2420 mutex_lock(&v->lock);
2421
2422 if (v->voc_state == VOC_RUN) {
2423 /* call stop modem voice */
2424 voice_send_stop_voice_cmd(v);
2425 voice_destroy_modem_voice(v);
2426 voice_destroy_mvm_cvs_session(v);
2427 v->voc_state = VOC_RELEASE;
2428 } else if (v->voc_state == VOC_CHANGE) {
2429 voice_send_stop_voice_cmd(v);
2430 voice_destroy_mvm_cvs_session(v);
2431 v->voc_state = VOC_RELEASE;
2432 }
2433
2434 mutex_unlock(&v->lock);
2435
2436 v->v_call_status = VOICE_CALL_END;
2437
2438 break;
2439 default:
2440 pr_err("UNKNOWN EVENT\n");
2441 }
2442 return;
2443}
2444EXPORT_SYMBOL(voice_auddev_cb_function);
2445
2446int voice_set_voc_path_full(uint32_t set)
2447{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002448 pr_info("%s: %d\n", __func__, set);
2449
Neema Shetty90189b82011-06-27 14:58:37 -07002450 mutex_lock(&common.common_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002451
Neema Shetty90189b82011-06-27 14:58:37 -07002452 if (set)
2453 common.voc_path = VOC_PATH_FULL;
2454 else
2455 common.voc_path = VOC_PATH_PASSIVE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002456
Neema Shetty90189b82011-06-27 14:58:37 -07002457 mutex_unlock(&common.common_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002458
Neema Shetty90189b82011-06-27 14:58:37 -07002459 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002460}
2461EXPORT_SYMBOL(voice_set_voc_path_full);
2462
2463void voice_register_mvs_cb(ul_cb_fn ul_cb,
2464 dl_cb_fn dl_cb,
2465 void *private_data)
2466{
Neema Shetty90189b82011-06-27 14:58:37 -07002467 common.mvs_info.ul_cb = ul_cb;
2468 common.mvs_info.dl_cb = dl_cb;
2469 common.mvs_info.private_data = private_data;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002470}
2471
2472void voice_config_vocoder(uint32_t media_type,
2473 uint32_t rate,
2474 uint32_t network_type,
Chaithanya Krishna Bacharaju2f2e8a52011-10-17 14:54:07 +05302475 uint32_t dtx_mode,
2476 struct q_min_max_rate q_min_max_rate)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002477{
Neema Shetty90189b82011-06-27 14:58:37 -07002478 common.mvs_info.media_type = media_type;
2479 common.mvs_info.rate = rate;
2480 common.mvs_info.network_type = network_type;
2481 common.mvs_info.dtx_mode = dtx_mode;
Chaithanya Krishna Bacharaju2f2e8a52011-10-17 14:54:07 +05302482 common.mvs_info.q_min_max_rate = q_min_max_rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002483}
2484
2485static int32_t modem_mvm_callback(struct apr_client_data *data, void *priv)
2486{
2487 uint32_t *ptr;
Neema Shetty90189b82011-06-27 14:58:37 -07002488 struct common_data *c = priv;
2489 struct voice_data *v = NULL;
2490 int i = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002491
Neema Shetty90189b82011-06-27 14:58:37 -07002492 pr_debug("%s: session_id 0x%x\n", __func__, data->dest_port);
2493
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002494 if (data->opcode == RESET_EVENTS) {
2495 pr_debug("%s:Reset event received in Voice service\n",
2496 __func__);
Neema Shetty90189b82011-06-27 14:58:37 -07002497 apr_reset(c->apr_mvm);
2498 c->apr_mvm = NULL;
2499 apr_reset(c->apr_q6_mvm);
2500 c->apr_q6_mvm = NULL;
2501
2502 /* Sub-system restart is applicable to all sessions. */
2503 for (i = 0; i < MAX_VOC_SESSIONS; i++)
2504 c->voice[i].mvm_handle = 0;
2505
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002506 return 0;
2507 }
2508
Swaminathan Sathappan71809462011-11-11 13:49:27 -08002509 v = voice_get_session(data->dest_port);
2510 if (v == NULL) {
2511 pr_err("%s: v is NULL\n", __func__);
2512 return -EINVAL;
2513 }
2514
2515 pr_debug("%s: common data 0x%x, session 0x%x\n",
2516 __func__, (unsigned int)c, (unsigned int)v);
2517 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
2518 data->payload_size, data->opcode);
2519
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002520 if (data->opcode == APR_BASIC_RSP_RESULT) {
2521 if (data->payload_size) {
2522 ptr = data->payload;
2523
2524 pr_info("%x %x\n", ptr[0], ptr[1]);
2525 /* ping mvm service ACK */
2526
2527 if (ptr[0] ==
2528 VSS_IMVM_CMD_CREATE_PASSIVE_CONTROL_SESSION ||
2529 ptr[0] ==
2530 VSS_IMVM_CMD_CREATE_FULL_CONTROL_SESSION) {
2531 /* Passive session is used for voice call
2532 * through modem. Full session is used for voice
2533 * call through Q6. */
2534 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2535 if (!ptr[1]) {
2536 pr_debug("%s: MVM handle is %d\n",
2537 __func__, data->src_port);
2538
2539 voice_set_mvm_handle(v, data->src_port);
2540 } else
2541 pr_info("got NACK for sending \
2542 MVM create session \n");
2543 v->mvm_state = CMD_STATUS_SUCCESS;
2544 wake_up(&v->mvm_wait);
2545 } else if (ptr[0] == VSS_IMVM_CMD_START_VOICE) {
2546 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2547 v->mvm_state = CMD_STATUS_SUCCESS;
2548 wake_up(&v->mvm_wait);
Neema Shetty7e4a9b52011-07-26 15:24:51 -07002549 } else if (ptr[0] == VSS_ISTREAM_CMD_ATTACH_VOCPROC) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002550 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2551 v->mvm_state = CMD_STATUS_SUCCESS;
2552 wake_up(&v->mvm_wait);
2553 } else if (ptr[0] == VSS_IMVM_CMD_STOP_VOICE) {
2554 v->mvm_state = CMD_STATUS_SUCCESS;
2555 wake_up(&v->mvm_wait);
Neema Shetty7e4a9b52011-07-26 15:24:51 -07002556 } else if (ptr[0] == VSS_ISTREAM_CMD_DETACH_VOCPROC) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002557 v->mvm_state = CMD_STATUS_SUCCESS;
2558 wake_up(&v->mvm_wait);
2559 } else if (ptr[0] == VSS_ISTREAM_CMD_SET_TTY_MODE) {
2560 v->mvm_state = CMD_STATUS_SUCCESS;
2561 wake_up(&v->mvm_wait);
2562 } else if (ptr[0] == APRV2_IBASIC_CMD_DESTROY_SESSION) {
2563 pr_debug("%s: DESTROY resp\n", __func__);
2564
2565 v->mvm_state = CMD_STATUS_SUCCESS;
2566 wake_up(&v->mvm_wait);
2567 } else if (ptr[0] == VSS_IMVM_CMD_ATTACH_STREAM) {
2568 pr_debug("%s: ATTACH_STREAM resp 0x%x\n",
2569 __func__, ptr[1]);
2570
2571 v->mvm_state = CMD_STATUS_SUCCESS;
2572 wake_up(&v->mvm_wait);
2573 } else if (ptr[0] == VSS_IMVM_CMD_DETACH_STREAM) {
2574 pr_debug("%s: DETACH_STREAM resp 0x%x\n",
2575 __func__, ptr[1]);
2576
2577 v->mvm_state = CMD_STATUS_SUCCESS;
2578 wake_up(&v->mvm_wait);
2579 } else if (ptr[0] == VSS_ICOMMON_CMD_SET_NETWORK) {
2580 pr_debug("%s: SET_NETWORK 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_ICOMMON_CMD_SET_VOICE_TIMING) {
2586 pr_debug("%s: SET_VOICE_TIMING resp 0x%x\n",
2587 __func__, ptr[1]);
2588
2589 v->mvm_state = CMD_STATUS_SUCCESS;
2590 wake_up(&v->mvm_wait);
2591 } else
2592 pr_debug("%s: not match cmd = 0x%x\n",
2593 __func__, ptr[0]);
2594 }
2595 }
2596
2597 return 0;
2598}
2599
2600static int32_t modem_cvs_callback(struct apr_client_data *data, void *priv)
2601{
2602 uint32_t *ptr;
Neema Shetty90189b82011-06-27 14:58:37 -07002603 struct common_data *c = priv;
2604 struct voice_data *v = NULL;
2605 int i = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002606
Neema Shetty90189b82011-06-27 14:58:37 -07002607 pr_debug("%s: session_id 0x%x\n", __func__, data->dest_port);
2608
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002609 if (data->opcode == RESET_EVENTS) {
2610 pr_debug("%s:Reset event received in Voice service\n",
2611 __func__);
Neema Shetty90189b82011-06-27 14:58:37 -07002612 apr_reset(c->apr_cvs);
2613 c->apr_cvs = NULL;
2614 apr_reset(c->apr_q6_cvs);
2615 c->apr_q6_cvs = NULL;
2616
2617 /* Sub-system restart is applicable to all sessions. */
2618 for (i = 0; i < MAX_VOC_SESSIONS; i++)
2619 c->voice[i].cvs_handle = 0;
2620
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002621 return 0;
2622 }
2623
Swaminathan Sathappan71809462011-11-11 13:49:27 -08002624 v = voice_get_session(data->dest_port);
2625 if (v == NULL) {
2626 pr_err("%s: v is NULL\n", __func__);
2627 return -EINVAL;
2628 }
2629
2630 pr_debug("%s: common data 0x%x, session 0x%x\n",
2631 __func__, (unsigned int)c, (unsigned int)v);
2632 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
2633 data->payload_size, data->opcode);
2634
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002635 if (data->opcode == APR_BASIC_RSP_RESULT) {
2636 if (data->payload_size) {
2637 ptr = data->payload;
2638
2639 pr_info("%x %x\n", ptr[0], ptr[1]);
2640 /*response from modem CVS */
2641 if (ptr[0] ==
2642 VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION ||
2643 ptr[0] ==
2644 VSS_ISTREAM_CMD_CREATE_FULL_CONTROL_SESSION) {
2645 if (!ptr[1]) {
2646 pr_debug("%s: CVS handle is %d\n",
2647 __func__, data->src_port);
2648 voice_set_cvs_handle(v, data->src_port);
2649 } else
2650 pr_info("got NACK for sending \
2651 CVS create session \n");
2652 v->cvs_state = CMD_STATUS_SUCCESS;
2653 wake_up(&v->cvs_wait);
2654 } else if (ptr[0] ==
2655 VSS_ISTREAM_CMD_CACHE_CALIBRATION_DATA) {
2656 v->cvs_state = CMD_STATUS_SUCCESS;
2657 wake_up(&v->cvs_wait);
2658 } else if (ptr[0] ==
2659 VSS_ISTREAM_CMD_SET_MUTE) {
2660 v->cvs_state = CMD_STATUS_SUCCESS;
2661 wake_up(&v->cvs_wait);
2662 } else if (ptr[0] == VSS_ISTREAM_CMD_SET_MEDIA_TYPE) {
2663 pr_debug("%s: SET_MEDIA resp 0x%x\n",
2664 __func__, ptr[1]);
2665
2666 v->cvs_state = CMD_STATUS_SUCCESS;
2667 wake_up(&v->cvs_wait);
2668 } else if (ptr[0] ==
2669 VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE) {
2670 pr_debug("%s: SET_AMR_RATE resp 0x%x\n",
2671 __func__, ptr[1]);
2672
2673 v->cvs_state = CMD_STATUS_SUCCESS;
2674 wake_up(&v->cvs_wait);
2675 } else if (ptr[0] ==
2676 VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE) {
2677 pr_debug("%s: SET_AMR_WB_RATE resp 0x%x\n",
2678 __func__, ptr[1]);
2679
2680 v->cvs_state = CMD_STATUS_SUCCESS;
2681 wake_up(&v->cvs_wait);
2682 } else if (ptr[0] == VSS_ISTREAM_CMD_SET_ENC_DTX_MODE) {
2683 pr_debug("%s: SET_DTX resp 0x%x\n",
2684 __func__, ptr[1]);
2685
2686 v->cvs_state = CMD_STATUS_SUCCESS;
2687 wake_up(&v->cvs_wait);
2688 } else if (ptr[0] ==
2689 VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE) {
2690 pr_debug("%s: SET_CDMA_RATE resp 0x%x\n",
2691 __func__, ptr[1]);
2692
2693 v->cvs_state = CMD_STATUS_SUCCESS;
2694 wake_up(&v->cvs_wait);
2695 } else if (ptr[0] == APRV2_IBASIC_CMD_DESTROY_SESSION) {
2696 pr_debug("%s: DESTROY resp\n", __func__);
2697
2698 v->cvs_state = CMD_STATUS_SUCCESS;
2699 wake_up(&v->cvs_wait);
2700 } else if (ptr[0] == VSS_ISTREAM_CMD_START_RECORD) {
2701 pr_debug("%s: START_RECORD resp 0x%x\n",
2702 __func__, ptr[1]);
2703
2704 v->cvs_state = CMD_STATUS_SUCCESS;
2705 wake_up(&v->cvs_wait);
2706 } else if (ptr[0] == VSS_ISTREAM_CMD_STOP_RECORD) {
2707 pr_debug("%s: STOP_RECORD resp 0x%x\n",
2708 __func__, ptr[1]);
2709
2710 v->cvs_state = CMD_STATUS_SUCCESS;
2711 wake_up(&v->cvs_wait);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002712 } else if (ptr[0] == VOICE_CMD_SET_PARAM) {
2713 rtac_make_voice_callback(RTAC_CVS, ptr,
2714 data->payload_size);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002715 } else if (ptr[0] == VSS_ISTREAM_CMD_START_PLAYBACK) {
2716 pr_debug("%s: START_PLAYBACK resp 0x%x\n",
2717 __func__, ptr[1]);
2718
2719 v->cvs_state = CMD_STATUS_SUCCESS;
2720 wake_up(&v->cvs_wait);
2721 } else if (ptr[0] == VSS_ISTREAM_CMD_STOP_PLAYBACK) {
2722 pr_debug("%s: STOP_PLAYBACK resp 0x%x\n",
2723 __func__, ptr[1]);
2724
2725 v->cvs_state = CMD_STATUS_SUCCESS;
2726 wake_up(&v->cvs_wait);
2727 } else
2728 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2729 }
2730 } else if (data->opcode == VSS_ISTREAM_EVT_SEND_ENC_BUFFER) {
2731 uint32_t *voc_pkt = data->payload;
2732 uint32_t pkt_len = data->payload_size;
2733
Neema Shetty90189b82011-06-27 14:58:37 -07002734 if (voc_pkt != NULL && c->mvs_info.ul_cb != NULL) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002735 pr_debug("%s: Media type is 0x%x\n",
2736 __func__, voc_pkt[0]);
2737
2738 /* Remove media ID from payload. */
2739 voc_pkt++;
2740 pkt_len = pkt_len - 4;
2741
Neema Shetty90189b82011-06-27 14:58:37 -07002742 c->mvs_info.ul_cb((uint8_t *)voc_pkt,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002743 pkt_len,
Neema Shetty90189b82011-06-27 14:58:37 -07002744 c->mvs_info.private_data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002745 } else {
2746 pr_err("%s: voc_pkt is 0x%x ul_cb is 0x%x\n",
2747 __func__, (unsigned int)voc_pkt,
Neema Shetty90189b82011-06-27 14:58:37 -07002748 (unsigned int)c->mvs_info.ul_cb);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002749 }
2750 } else if (data->opcode == VSS_ISTREAM_EVT_SEND_DEC_BUFFER) {
2751 pr_debug("%s: Send dec buf resp\n", __func__);
2752 } else if (data->opcode == VSS_ISTREAM_EVT_REQUEST_DEC_BUFFER) {
2753 struct cvs_send_dec_buf_cmd send_dec_buf;
2754 int ret = 0;
2755 uint32_t pkt_len = 0;
2756
Neema Shetty90189b82011-06-27 14:58:37 -07002757 if (c->mvs_info.dl_cb != NULL) {
2758 send_dec_buf.dec_buf.media_id = c->mvs_info.media_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002759
Neema Shetty90189b82011-06-27 14:58:37 -07002760 c->mvs_info.dl_cb(
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002761 (uint8_t *)&send_dec_buf.dec_buf.packet_data,
2762 &pkt_len,
Neema Shetty90189b82011-06-27 14:58:37 -07002763 c->mvs_info.private_data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002764
2765 send_dec_buf.hdr.hdr_field =
2766 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2767 APR_HDR_LEN(APR_HDR_SIZE),
2768 APR_PKT_VER);
2769 send_dec_buf.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2770 sizeof(send_dec_buf.dec_buf.media_id) + pkt_len);
Neema Shetty90189b82011-06-27 14:58:37 -07002771 send_dec_buf.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002772 send_dec_buf.hdr.dest_port = voice_get_cvs_handle(v);
2773 send_dec_buf.hdr.token = 0;
2774 send_dec_buf.hdr.opcode =
2775 VSS_ISTREAM_EVT_SEND_DEC_BUFFER;
2776
Neema Shetty90189b82011-06-27 14:58:37 -07002777 ret = apr_send_pkt(voice_get_apr_cvs(),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002778 (uint32_t *) &send_dec_buf);
2779 if (ret < 0) {
2780 pr_err("%s: Error %d sending DEC_BUF\n",
2781 __func__, ret);
2782 goto fail;
2783 }
2784 } else {
2785 pr_err("%s: ul_cb is NULL\n", __func__);
2786 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002787 } else if (data->opcode == VOICE_EVT_GET_PARAM_ACK) {
2788 rtac_make_voice_callback(RTAC_CVS, data->payload,
2789 data->payload_size);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002790 } else {
2791 pr_debug("%s: Unknown opcode 0x%x\n", __func__, data->opcode);
2792 }
2793
2794fail:
2795 return 0;
2796}
2797
2798static int32_t modem_cvp_callback(struct apr_client_data *data, void *priv)
2799{
2800 uint32_t *ptr;
Neema Shetty90189b82011-06-27 14:58:37 -07002801 struct common_data *c = priv;
2802 struct voice_data *v = NULL;
2803 int i = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002804
Neema Shetty90189b82011-06-27 14:58:37 -07002805 pr_debug("%s: session_id 0x%x\n", __func__, data->dest_port);
2806
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002807 if (data->opcode == RESET_EVENTS) {
2808 pr_debug("%s:Reset event received in Voice service\n",
2809 __func__);
Neema Shetty90189b82011-06-27 14:58:37 -07002810 apr_reset(c->apr_cvp);
2811 c->apr_cvp = NULL;
2812 apr_reset(c->apr_q6_cvp);
2813 c->apr_q6_cvp = NULL;
2814
2815 /* Sub-system restart is applicable to all sessions. */
2816 for (i = 0; i < MAX_VOC_SESSIONS; i++)
2817 c->voice[i].cvp_handle = 0;
2818
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002819 return 0;
2820 }
2821
Swaminathan Sathappan71809462011-11-11 13:49:27 -08002822 v = voice_get_session(data->dest_port);
2823 if (v == NULL) {
2824 pr_err("%s: v is NULL\n", __func__);
2825 return -EINVAL;
2826 }
2827
2828 pr_debug("%s: common data 0x%x, session 0x%x\n",
2829 __func__, (unsigned int)c, (unsigned int)v);
2830 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
2831 data->payload_size, data->opcode);
2832
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002833 if (data->opcode == APR_BASIC_RSP_RESULT) {
2834 if (data->payload_size) {
2835 ptr = data->payload;
2836
2837 pr_info("%x %x\n", ptr[0], ptr[1]);
2838 /*response from modem CVP */
2839 if (ptr[0] ==
2840 VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION) {
2841 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2842 if (!ptr[1]) {
2843 voice_set_cvp_handle(v, data->src_port);
2844 pr_debug("cvphdl=%d\n", data->src_port);
2845 } else
2846 pr_info("got NACK from CVP create \
2847 session response\n");
2848 v->cvp_state = CMD_STATUS_SUCCESS;
2849 wake_up(&v->cvp_wait);
2850 } else if (ptr[0] ==
2851 VSS_IVOCPROC_CMD_CACHE_CALIBRATION_DATA) {
2852 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2853 v->cvp_state = CMD_STATUS_SUCCESS;
2854 wake_up(&v->cvp_wait);
2855 } else if (ptr[0] == VSS_IVOCPROC_CMD_SET_DEVICE) {
2856 v->cvp_state = CMD_STATUS_SUCCESS;
2857 wake_up(&v->cvp_wait);
2858 } else if (ptr[0] ==
2859 VSS_IVOCPROC_CMD_SET_RX_VOLUME_INDEX) {
2860 v->cvp_state = CMD_STATUS_SUCCESS;
2861 wake_up(&v->cvp_wait);
2862 } else if (ptr[0] == VSS_IVOCPROC_CMD_ENABLE) {
2863 v->cvp_state = CMD_STATUS_SUCCESS;
2864 wake_up(&v->cvp_wait);
2865 } else if (ptr[0] == VSS_IVOCPROC_CMD_DISABLE) {
2866 v->cvp_state = CMD_STATUS_SUCCESS;
2867 wake_up(&v->cvp_wait);
2868 } else if (ptr[0] == APRV2_IBASIC_CMD_DESTROY_SESSION) {
2869 v->cvp_state = CMD_STATUS_SUCCESS;
2870 wake_up(&v->cvp_wait);
2871 } else if (ptr[0] ==
2872 VSS_IVOCPROC_CMD_CACHE_VOLUME_CALIBRATION_TABLE
2873 ) {
2874
2875 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2876 v->cvp_state = CMD_STATUS_SUCCESS;
2877 wake_up(&v->cvp_wait);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002878 } else if (ptr[0] == VOICE_CMD_SET_PARAM) {
2879 rtac_make_voice_callback(RTAC_CVP, ptr,
2880 data->payload_size);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002881 } else
2882 pr_debug("%s: not match cmd = 0x%x\n",
2883 __func__, ptr[0]);
2884 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002885 } else if (data->opcode == VOICE_EVT_GET_PARAM_ACK) {
2886 rtac_make_voice_callback(RTAC_CVP, data->payload,
2887 data->payload_size);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002888 }
2889 return 0;
2890}
2891
2892
2893static int __init voice_init(void)
2894{
Neema Shetty90189b82011-06-27 14:58:37 -07002895 int rc = 0, i = 0;
2896
2897 memset(&common, 0, sizeof(struct common_data));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002898
2899 /* set default value */
Neema Shetty90189b82011-06-27 14:58:37 -07002900 common.default_mute_val = 1; /* default is mute */
2901 common.default_vol_val = 0;
2902 common.default_sample_val = 8000;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002903
Neema Shetty90189b82011-06-27 14:58:37 -07002904 common.voc_path = VOC_PATH_PASSIVE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002905
2906 /* Initialize MVS info. */
Neema Shetty90189b82011-06-27 14:58:37 -07002907 common.mvs_info.network_type = VSS_NETWORK_ID_DEFAULT;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002908
Neema Shetty90189b82011-06-27 14:58:37 -07002909 mutex_init(&common.common_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002910
Neema Shetty90189b82011-06-27 14:58:37 -07002911 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
2912 common.voice[i].session_id = SESSION_ID_BASE + i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002913
Neema Shetty90189b82011-06-27 14:58:37 -07002914 common.voice[i].dev_rx.volume = common.default_vol_val;
2915 common.voice[i].dev_tx.mute = common.default_mute_val;
2916
2917 common.voice[i].voc_state = VOC_INIT;
2918
2919 common.voice[i].rec_info.rec_mode = VOC_REC_NONE;
2920
2921 init_waitqueue_head(&common.voice[i].mvm_wait);
2922 init_waitqueue_head(&common.voice[i].cvs_wait);
2923 init_waitqueue_head(&common.voice[i].cvp_wait);
2924
2925 mutex_init(&common.voice[i].lock);
2926
2927 }
2928
2929 common.device_events = AUDDEV_EVT_DEV_CHG_VOICE |
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002930 AUDDEV_EVT_DEV_RDY |
2931 AUDDEV_EVT_REL_PENDING |
2932 AUDDEV_EVT_START_VOICE |
2933 AUDDEV_EVT_END_VOICE |
2934 AUDDEV_EVT_DEVICE_VOL_MUTE_CHG |
2935 AUDDEV_EVT_FREQ_CHG;
2936
2937 pr_debug("to register call back\n");
2938 /* register callback to auddev */
Neema Shetty90189b82011-06-27 14:58:37 -07002939 auddev_register_evt_listner(common.device_events, AUDDEV_CLNT_VOC,
2940 0, voice_auddev_cb_function, &common);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002941
2942 return rc;
2943}
2944
2945device_initcall(voice_init);