blob: 8569068180e821b3b5d831a58abca37de1912303 [file] [log] [blame]
Duy Truonge833aca2013-02-12 13:35:08 -08001/* Copyright (c) 2010-2012, The Linux Foundation. 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;
Ben Rombergerb7603232011-11-23 17:16:27 -0800794 struct acdb_atomic_cal_block *cal_blk;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700795 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++) {
Ben Rombergerb7603232011-11-23 17:16:27 -0800833 cal_size_per_network = atomic_read(&cal_blk[index].cal_size);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700834 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");
Ben Rombergerb7603232011-11-23 17:16:27 -0800837 cal_data_per_network =
838 (u32 *)atomic_read(&cal_blk[index].cal_kvaddr);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700839 pr_debug(" cal data=%x\n", (uint32_t)cal_data_per_network);
840 cvs_cal_cmd_hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
841 cal_size_per_network);
842 pr_debug("header size =%d, pkt_size =%d\n",
843 APR_HDR_SIZE, cvs_cal_cmd_hdr.pkt_size);
844 memcpy(cmd_buf, &cvs_cal_cmd_hdr, APR_HDR_SIZE);
845 memcpy(cmd_buf + (APR_HDR_SIZE / sizeof(uint32_t)),
846 cal_data_per_network, cal_size_per_network);
847 pr_debug("send cvs cal: index =%d\n", index);
848 v->cvs_state = CMD_STATUS_FAIL;
849 ret = apr_send_pkt(apr_cvs, cmd_buf);
850 if (ret < 0) {
851 pr_err("Fail: sending cvs cal, idx=%d\n", index);
852 continue;
853 }
854 ret = wait_event_timeout(v->cvs_wait,
855 (v->cvs_state == CMD_STATUS_SUCCESS),
856 msecs_to_jiffies(TIMEOUT_MS));
857 if (!ret) {
858 pr_err("%s: wait_event timeout\n", __func__);
859 return -EINVAL;
860 }
861 }
862 kfree(cmd_buf);
863done:
864 return 0;
865}
866
867static int voice_send_cvp_cal_to_modem(struct voice_data *v)
868{
869 struct apr_hdr cvp_cal_cmd_hdr;
870 uint32_t *cmd_buf;
871 struct acdb_cal_data cal_data;
Ben Rombergerb7603232011-11-23 17:16:27 -0800872 struct acdb_atomic_cal_block *cal_blk;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700873 int32_t cal_size_per_network;
874 uint32_t *cal_data_per_network;
875 int index = 0;
876 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -0700877 void *apr_cvp = voice_get_apr_cvp();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700878 u16 cvp_handle = voice_get_cvp_handle(v);
879
880
881 /* fill the header */
882 cvp_cal_cmd_hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
883 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
884 cvp_cal_cmd_hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
885 sizeof(cvp_cal_cmd_hdr) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -0700886 cvp_cal_cmd_hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700887 cvp_cal_cmd_hdr.dest_port = cvp_handle;
888 cvp_cal_cmd_hdr.token = 0;
889 cvp_cal_cmd_hdr.opcode =
890 VSS_IVOCPROC_CMD_CACHE_CALIBRATION_DATA;
891
892 /* get cal data */
893 get_vocproc_cal(&cal_data);
894 if (cal_data.num_cal_blocks == 0) {
895 pr_err("%s: No calibration data to send!\n", __func__);
896 goto done;
897 }
898
899 /* send cal to modem */
900 cmd_buf = kzalloc((sizeof(struct apr_hdr) + BUFFER_PAYLOAD_SIZE),
901 GFP_KERNEL);
902 if (!cmd_buf) {
903 pr_err("No memory is allocated.\n");
904 return -ENOMEM;
905 }
906 pr_debug("----- num_cal_blocks=%d\n", (s32)cal_data.num_cal_blocks);
907 cal_blk = cal_data.cal_blocks;
908 pr_debug(" cal_blk =%x\n", (uint32_t)cal_data.cal_blocks);
909
910 for (; index < cal_data.num_cal_blocks; index++) {
Ben Rombergerb7603232011-11-23 17:16:27 -0800911 cal_size_per_network = atomic_read(&cal_blk[index].cal_size);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700912 if (cal_size_per_network >= BUFFER_PAYLOAD_SIZE)
913 pr_err("Cal size is too big\n");
914 pr_debug(" cal size =%d\n", cal_size_per_network);
Ben Rombergerb7603232011-11-23 17:16:27 -0800915 cal_data_per_network =
916 (u32 *)atomic_read(&cal_blk[index].cal_kvaddr);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700917 pr_debug(" cal data=%x\n", (uint32_t)cal_data_per_network);
918
919 cvp_cal_cmd_hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
920 cal_size_per_network);
921 memcpy(cmd_buf, &cvp_cal_cmd_hdr, APR_HDR_SIZE);
922 memcpy(cmd_buf + (APR_HDR_SIZE / sizeof(*cmd_buf)),
923 cal_data_per_network, cal_size_per_network);
924 pr_debug("Send cvp cal\n");
925 v->cvp_state = CMD_STATUS_FAIL;
926 pr_info("%s: CVP calib\n", __func__);
927 ret = apr_send_pkt(apr_cvp, cmd_buf);
928 if (ret < 0) {
929 pr_err("Fail: sending cvp cal, idx=%d\n", index);
930 continue;
931 }
932 ret = wait_event_timeout(v->cvp_wait,
933 (v->cvp_state == CMD_STATUS_SUCCESS),
934 msecs_to_jiffies(TIMEOUT_MS));
935 if (!ret) {
936 pr_err("%s: wait_event timeout\n", __func__);
937 return -EINVAL;
938 }
939 }
940 kfree(cmd_buf);
941done:
942 return 0;
943}
944
945static int voice_send_cvp_vol_tbl_to_modem(struct voice_data *v)
946{
947 struct apr_hdr cvp_vol_cal_cmd_hdr;
948 uint32_t *cmd_buf;
949 struct acdb_cal_data cal_data;
Ben Rombergerb7603232011-11-23 17:16:27 -0800950 struct acdb_atomic_cal_block *cal_blk;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700951 int32_t cal_size_per_network;
952 uint32_t *cal_data_per_network;
953 int index = 0;
954 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -0700955 void *apr_cvp = voice_get_apr_cvp();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700956 u16 cvp_handle = voice_get_cvp_handle(v);
957
958
959 /* fill the header */
960 cvp_vol_cal_cmd_hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
961 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
962 cvp_vol_cal_cmd_hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
963 sizeof(cvp_vol_cal_cmd_hdr) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -0700964 cvp_vol_cal_cmd_hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700965 cvp_vol_cal_cmd_hdr.dest_port = cvp_handle;
966 cvp_vol_cal_cmd_hdr.token = 0;
967 cvp_vol_cal_cmd_hdr.opcode =
968 VSS_IVOCPROC_CMD_CACHE_VOLUME_CALIBRATION_TABLE;
969
970 /* get cal data */
971 get_vocvol_cal(&cal_data);
972 if (cal_data.num_cal_blocks == 0) {
973 pr_err("%s: No calibration data to send!\n", __func__);
974 goto done;
975 }
976
977 /* send cal to modem */
978 cmd_buf = kzalloc((sizeof(struct apr_hdr) + BUFFER_PAYLOAD_SIZE),
979 GFP_KERNEL);
980 if (!cmd_buf) {
981 pr_err("No memory is allocated.\n");
982 return -ENOMEM;
983 }
984 pr_debug("----- num_cal_blocks=%d\n", (s32)cal_data.num_cal_blocks);
985 cal_blk = cal_data.cal_blocks;
986 pr_debug("Cal_blk =%x\n", (uint32_t)cal_data.cal_blocks);
987
988 for (; index < cal_data.num_cal_blocks; index++) {
Ben Rombergerb7603232011-11-23 17:16:27 -0800989 cal_size_per_network = atomic_read(&cal_blk[index].cal_size);
990 cal_data_per_network =
991 (u32 *)atomic_read(&cal_blk[index].cal_kvaddr);
Ben Rombergerb4f562a2011-07-13 19:57:54 -0700992
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700993 pr_debug("Cal size =%d, index=%d\n", cal_size_per_network,
994 index);
995 pr_debug("Cal data=%x\n", (uint32_t)cal_data_per_network);
996 cvp_vol_cal_cmd_hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
Ben Rombergerc1bb79e2012-01-13 21:48:35 -0800997 cal_size_per_network);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700998 memcpy(cmd_buf, &cvp_vol_cal_cmd_hdr, APR_HDR_SIZE);
Ben Rombergerc1bb79e2012-01-13 21:48:35 -0800999 memcpy(cmd_buf + (APR_HDR_SIZE / sizeof(uint32_t)),
1000 cal_data_per_network, cal_size_per_network);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001001 pr_debug("Send vol table\n");
1002
1003 v->cvp_state = CMD_STATUS_FAIL;
1004 ret = apr_send_pkt(apr_cvp, cmd_buf);
1005 if (ret < 0) {
1006 pr_err("Fail: sending cvp vol cal, idx=%d\n", index);
1007 continue;
1008 }
1009 ret = wait_event_timeout(v->cvp_wait,
1010 (v->cvp_state == CMD_STATUS_SUCCESS),
1011 msecs_to_jiffies(TIMEOUT_MS));
1012 if (!ret) {
1013 pr_err("%s: wait_event timeout\n", __func__);
1014 return -EINVAL;
1015 }
1016 }
1017 kfree(cmd_buf);
1018done:
1019 return 0;
1020}
1021
1022static int voice_set_dtx(struct voice_data *v)
1023{
1024 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001025 void *apr_cvs = voice_get_apr_cvs();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001026 u16 cvs_handle = voice_get_cvs_handle(v);
1027
1028 /* Set DTX */
1029 struct cvs_set_enc_dtx_mode_cmd cvs_set_dtx = {
1030 .hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1031 APR_HDR_LEN(APR_HDR_SIZE),
1032 APR_PKT_VER),
1033 .hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1034 sizeof(cvs_set_dtx) - APR_HDR_SIZE),
Neema Shetty90189b82011-06-27 14:58:37 -07001035 .hdr.src_port = v->session_id,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001036 .hdr.dest_port = cvs_handle,
1037 .hdr.token = 0,
1038 .hdr.opcode = VSS_ISTREAM_CMD_SET_ENC_DTX_MODE,
Neema Shetty90189b82011-06-27 14:58:37 -07001039 .dtx_mode.enable = common.mvs_info.dtx_mode,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001040 };
1041
Neema Shetty90189b82011-06-27 14:58:37 -07001042 pr_debug("%s: Setting DTX %d\n", __func__, common.mvs_info.dtx_mode);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001043
1044 v->cvs_state = CMD_STATUS_FAIL;
1045
1046 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_dtx);
1047 if (ret < 0) {
1048 pr_err("%s: Error %d sending SET_DTX\n", __func__, ret);
1049
1050 goto done;
1051 }
1052
1053 ret = wait_event_timeout(v->cvs_wait,
1054 (v->cvs_state == CMD_STATUS_SUCCESS),
1055 msecs_to_jiffies(TIMEOUT_MS));
1056 if (!ret) {
1057 pr_err("%s: wait_event timeout\n", __func__);
1058
1059 ret = -EINVAL;
1060 }
1061
1062done:
1063 return ret;
1064}
1065
1066static int voice_config_cvs_vocoder(struct voice_data *v)
1067{
1068 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001069 void *apr_cvs = voice_get_apr_cvs();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001070 u16 cvs_handle = voice_get_cvs_handle(v);
1071
1072 /* Set media type. */
1073 struct cvs_set_media_type_cmd cvs_set_media_cmd;
1074
1075 pr_info("%s: Setting media type\n", __func__);
1076
1077 cvs_set_media_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1078 APR_HDR_LEN(APR_HDR_SIZE),
1079 APR_PKT_VER);
1080 cvs_set_media_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1081 sizeof(cvs_set_media_cmd) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001082 cvs_set_media_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001083 cvs_set_media_cmd.hdr.dest_port = cvs_handle;
1084 cvs_set_media_cmd.hdr.token = 0;
1085 cvs_set_media_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_MEDIA_TYPE;
Neema Shetty90189b82011-06-27 14:58:37 -07001086 cvs_set_media_cmd.media_type.tx_media_id = common.mvs_info.media_type;
1087 cvs_set_media_cmd.media_type.rx_media_id = common.mvs_info.media_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001088
1089 v->cvs_state = CMD_STATUS_FAIL;
1090
1091 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_media_cmd);
1092 if (ret < 0) {
1093 pr_err("%s: Error %d sending SET_MEDIA_TYPE\n",
1094 __func__, ret);
1095
1096 goto done;
1097 }
1098
1099 ret = wait_event_timeout(v->cvs_wait,
1100 (v->cvs_state == CMD_STATUS_SUCCESS),
1101 msecs_to_jiffies(TIMEOUT_MS));
1102 if (!ret) {
1103 pr_err("%s: wait_event timeout\n", __func__);
1104
1105 ret = -EINVAL;
1106 goto done;
1107 }
1108
1109 /* Set encoder properties. */
Neema Shetty90189b82011-06-27 14:58:37 -07001110 switch (common.mvs_info.media_type) {
Chaithanya Krishna Bacharaju68993b52011-10-18 08:41:30 +05301111 case VSS_MEDIA_ID_13K_MODEM:
Chaithanya Krishna Bacharaju2f2e8a52011-10-17 14:54:07 +05301112 case VSS_MEDIA_ID_4GV_NB_MODEM:
1113 case VSS_MEDIA_ID_4GV_WB_MODEM:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001114 case VSS_MEDIA_ID_EVRC_MODEM: {
1115 struct cvs_set_cdma_enc_minmax_rate_cmd cvs_set_cdma_rate;
1116
Chaithanya Krishna Bacharaju2f2e8a52011-10-17 14:54:07 +05301117 pr_info("%s: Setting CDMA min-max rate\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001118
1119 cvs_set_cdma_rate.hdr.hdr_field =
1120 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1121 APR_HDR_LEN(APR_HDR_SIZE),
1122 APR_PKT_VER);
1123 cvs_set_cdma_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1124 sizeof(cvs_set_cdma_rate) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001125 cvs_set_cdma_rate.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001126 cvs_set_cdma_rate.hdr.dest_port = cvs_handle;
1127 cvs_set_cdma_rate.hdr.token = 0;
1128 cvs_set_cdma_rate.hdr.opcode =
1129 VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE;
Chaithanya Krishna Bacharaju2f2e8a52011-10-17 14:54:07 +05301130 cvs_set_cdma_rate.cdma_rate.min_rate =
1131 common.mvs_info.q_min_max_rate.min_rate;
1132 cvs_set_cdma_rate.cdma_rate.max_rate =
1133 common.mvs_info.q_min_max_rate.max_rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001134
1135 v->cvs_state = CMD_STATUS_FAIL;
1136
1137 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_cdma_rate);
1138 if (ret < 0) {
Chaithanya Krishna Bacharaju2f2e8a52011-10-17 14:54:07 +05301139 pr_err("%s: Error %d sending CDMA_SET_ENC_MINMAX_RATE\n",
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001140 __func__, ret);
1141
1142 goto done;
1143 }
1144
1145 ret = wait_event_timeout(v->cvs_wait,
1146 (v->cvs_state == CMD_STATUS_SUCCESS),
1147 msecs_to_jiffies(TIMEOUT_MS));
1148 if (!ret) {
1149 pr_err("%s: wait_event timeout\n", __func__);
1150
1151 ret = -EINVAL;
1152 goto done;
1153 }
1154
Chaithanya Krishna Bacharaju2f2e8a52011-10-17 14:54:07 +05301155 if ((common.mvs_info.media_type == VSS_MEDIA_ID_4GV_NB_MODEM) ||
1156 (common.mvs_info.media_type == VSS_MEDIA_ID_4GV_WB_MODEM))
1157 ret = voice_set_dtx(v);
1158
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001159 break;
1160 }
1161
1162 case VSS_MEDIA_ID_AMR_NB_MODEM: {
1163 struct cvs_set_amr_enc_rate_cmd cvs_set_amr_rate;
1164
1165 pr_info("%s: Setting AMR rate\n", __func__);
1166
1167 cvs_set_amr_rate.hdr.hdr_field =
1168 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1169 APR_HDR_LEN(APR_HDR_SIZE),
1170 APR_PKT_VER);
1171 cvs_set_amr_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1172 sizeof(cvs_set_amr_rate) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001173 cvs_set_amr_rate.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001174 cvs_set_amr_rate.hdr.dest_port = cvs_handle;
1175 cvs_set_amr_rate.hdr.token = 0;
1176 cvs_set_amr_rate.hdr.opcode =
1177 VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE;
Neema Shetty90189b82011-06-27 14:58:37 -07001178 cvs_set_amr_rate.amr_rate.mode = common.mvs_info.rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001179
1180 v->cvs_state = CMD_STATUS_FAIL;
1181
1182 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_amr_rate);
1183 if (ret < 0) {
1184 pr_err("%s: Error %d sending SET_AMR_RATE\n",
1185 __func__, ret);
1186
1187 goto done;
1188 }
1189
1190 ret = wait_event_timeout(v->cvs_wait,
1191 (v->cvs_state == CMD_STATUS_SUCCESS),
1192 msecs_to_jiffies(TIMEOUT_MS));
1193 if (!ret) {
1194 pr_err("%s: wait_event timeout\n", __func__);
1195
1196 ret = -EINVAL;
1197 goto done;
1198 }
1199
1200 ret = voice_set_dtx(v);
1201
1202 break;
1203 }
1204
1205 case VSS_MEDIA_ID_AMR_WB_MODEM: {
1206 struct cvs_set_amrwb_enc_rate_cmd cvs_set_amrwb_rate;
1207
1208 pr_info("%s: Setting AMR WB rate\n", __func__);
1209
1210 cvs_set_amrwb_rate.hdr.hdr_field =
1211 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1212 APR_HDR_LEN(APR_HDR_SIZE),
1213 APR_PKT_VER);
1214 cvs_set_amrwb_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1215 sizeof(cvs_set_amrwb_rate) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001216 cvs_set_amrwb_rate.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001217 cvs_set_amrwb_rate.hdr.dest_port = cvs_handle;
1218 cvs_set_amrwb_rate.hdr.token = 0;
1219 cvs_set_amrwb_rate.hdr.opcode =
1220 VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE;
Neema Shetty90189b82011-06-27 14:58:37 -07001221 cvs_set_amrwb_rate.amrwb_rate.mode = common.mvs_info.rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001222
1223 v->cvs_state = CMD_STATUS_FAIL;
1224
1225 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_amrwb_rate);
1226 if (ret < 0) {
1227 pr_err("%s: Error %d sending SET_AMRWB_RATE\n",
1228 __func__, ret);
1229
1230 goto done;
1231 }
1232
1233 ret = wait_event_timeout(v->cvs_wait,
1234 (v->cvs_state == CMD_STATUS_SUCCESS),
1235 msecs_to_jiffies(TIMEOUT_MS));
1236 if (!ret) {
1237 pr_err("%s: wait_event timeout\n", __func__);
1238
1239 ret = -EINVAL;
1240 goto done;
1241 }
1242
1243 ret = voice_set_dtx(v);
1244
1245 break;
1246 }
1247
Chaithanya Krishna Bacharaju68993b52011-10-18 08:41:30 +05301248 case VSS_MEDIA_ID_EFR_MODEM:
1249 case VSS_MEDIA_ID_FR_MODEM:
1250 case VSS_MEDIA_ID_HR_MODEM:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001251 case VSS_MEDIA_ID_G729:
1252 case VSS_MEDIA_ID_G711_ALAW:
1253 case VSS_MEDIA_ID_G711_MULAW: {
1254 ret = voice_set_dtx(v);
1255
1256 break;
1257 }
1258
1259 default: {
1260 /* Do nothing. */
1261 }
1262 }
1263
1264done:
1265 return ret;
1266}
1267
1268static int voice_send_start_voice_cmd(struct voice_data *v)
1269{
1270 struct apr_hdr mvm_start_voice_cmd;
1271 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001272 void *apr_mvm = voice_get_apr_mvm();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001273 u16 mvm_handle = voice_get_mvm_handle(v);
1274
1275 mvm_start_voice_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1276 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1277 mvm_start_voice_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1278 sizeof(mvm_start_voice_cmd) - APR_HDR_SIZE);
1279 pr_info("send mvm_start_voice_cmd pkt size = %d\n",
1280 mvm_start_voice_cmd.pkt_size);
Neema Shetty90189b82011-06-27 14:58:37 -07001281 mvm_start_voice_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001282 mvm_start_voice_cmd.dest_port = mvm_handle;
1283 mvm_start_voice_cmd.token = 0;
1284 mvm_start_voice_cmd.opcode = VSS_IMVM_CMD_START_VOICE;
1285
1286 v->mvm_state = CMD_STATUS_FAIL;
1287 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_start_voice_cmd);
1288 if (ret < 0) {
1289 pr_err("Fail in sending VSS_IMVM_CMD_START_VOICE\n");
1290 goto fail;
1291 }
1292 ret = wait_event_timeout(v->mvm_wait,
1293 (v->mvm_state == CMD_STATUS_SUCCESS),
1294 msecs_to_jiffies(TIMEOUT_MS));
1295 if (!ret) {
1296 pr_err("%s: wait_event timeout\n", __func__);
1297 goto fail;
1298 }
1299
1300 return 0;
1301fail:
1302 return -EINVAL;
1303}
1304
1305static int voice_disable_vocproc(struct voice_data *v)
1306{
1307 struct apr_hdr cvp_disable_cmd;
1308 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001309 void *apr_cvp = voice_get_apr_cvp();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001310 u16 cvp_handle = voice_get_cvp_handle(v);
1311
1312 /* disable vocproc and wait for respose */
1313 cvp_disable_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1314 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1315 cvp_disable_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1316 sizeof(cvp_disable_cmd) - APR_HDR_SIZE);
1317 pr_debug("cvp_disable_cmd pkt size = %d, cvp_handle=%d\n",
1318 cvp_disable_cmd.pkt_size, cvp_handle);
Neema Shetty90189b82011-06-27 14:58:37 -07001319 cvp_disable_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001320 cvp_disable_cmd.dest_port = cvp_handle;
1321 cvp_disable_cmd.token = 0;
1322 cvp_disable_cmd.opcode = VSS_IVOCPROC_CMD_DISABLE;
1323
1324 v->cvp_state = CMD_STATUS_FAIL;
1325 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_disable_cmd);
1326 if (ret < 0) {
1327 pr_err("Fail in sending VSS_IVOCPROC_CMD_DISABLE\n");
1328 goto fail;
1329 }
1330 ret = wait_event_timeout(v->cvp_wait,
1331 (v->cvp_state == CMD_STATUS_SUCCESS),
1332 msecs_to_jiffies(TIMEOUT_MS));
1333 if (!ret) {
1334 pr_err("%s: wait_event timeout\n", __func__);
1335 goto fail;
1336 }
Ben Rombergerfce8f512011-07-18 16:46:09 -07001337 rtac_remove_voice(v->cvs_handle);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001338
1339 return 0;
1340fail:
1341 return -EINVAL;
1342}
1343
1344static int voice_set_device(struct voice_data *v)
1345{
1346 struct cvp_set_device_cmd cvp_setdev_cmd;
1347 struct msm_snddev_info *dev_tx_info;
1348 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001349 void *apr_cvp = voice_get_apr_cvp();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001350 u16 cvp_handle = voice_get_cvp_handle(v);
1351
1352
1353 /* set device and wait for response */
1354 cvp_setdev_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1355 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1356 cvp_setdev_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1357 sizeof(cvp_setdev_cmd) - APR_HDR_SIZE);
1358 pr_debug(" send create cvp setdev, pkt size = %d\n",
1359 cvp_setdev_cmd.hdr.pkt_size);
Neema Shetty90189b82011-06-27 14:58:37 -07001360 cvp_setdev_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001361 cvp_setdev_cmd.hdr.dest_port = cvp_handle;
1362 cvp_setdev_cmd.hdr.token = 0;
1363 cvp_setdev_cmd.hdr.opcode = VSS_IVOCPROC_CMD_SET_DEVICE;
1364
1365 dev_tx_info = audio_dev_ctrl_find_dev(v->dev_tx.dev_id);
1366 if (IS_ERR(dev_tx_info)) {
1367 pr_err("bad dev_id %d\n", v->dev_tx.dev_id);
1368 goto fail;
1369 }
1370
1371 cvp_setdev_cmd.cvp_set_device.tx_topology_id =
1372 get_voice_tx_topology();
1373 if (cvp_setdev_cmd.cvp_set_device.tx_topology_id == 0) {
1374 if (dev_tx_info->channel_mode > 1)
1375 cvp_setdev_cmd.cvp_set_device.tx_topology_id =
1376 VSS_IVOCPROC_TOPOLOGY_ID_TX_DM_FLUENCE;
1377 else
1378 cvp_setdev_cmd.cvp_set_device.tx_topology_id =
1379 VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
1380 }
1381
1382 /* Use default topology if invalid value in ACDB */
1383 cvp_setdev_cmd.cvp_set_device.rx_topology_id =
1384 get_voice_rx_topology();
1385 if (cvp_setdev_cmd.cvp_set_device.rx_topology_id == 0)
1386 cvp_setdev_cmd.cvp_set_device.rx_topology_id =
1387 VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
1388 cvp_setdev_cmd.cvp_set_device.tx_port_id = v->dev_tx.dev_port_id;
1389 cvp_setdev_cmd.cvp_set_device.rx_port_id = v->dev_rx.dev_port_id;
1390 pr_info("topology=%d , tx_port_id=%d, rx_port_id=%d\n",
1391 cvp_setdev_cmd.cvp_set_device.tx_topology_id,
1392 cvp_setdev_cmd.cvp_set_device.tx_port_id,
1393 cvp_setdev_cmd.cvp_set_device.rx_port_id);
1394
1395 v->cvp_state = CMD_STATUS_FAIL;
1396 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_setdev_cmd);
1397 if (ret < 0) {
1398 pr_err("Fail in sending VOCPROC_FULL_CONTROL_SESSION\n");
1399 goto fail;
1400 }
1401 pr_debug("wait for cvp create session event\n");
1402 ret = wait_event_timeout(v->cvp_wait,
1403 (v->cvp_state == CMD_STATUS_SUCCESS),
1404 msecs_to_jiffies(TIMEOUT_MS));
1405 if (!ret) {
1406 pr_err("%s: wait_event timeout\n", __func__);
1407 goto fail;
1408 }
1409
1410 /* send cvs cal */
1411 voice_send_cvs_cal_to_modem(v);
1412
1413 /* send cvp cal */
1414 voice_send_cvp_cal_to_modem(v);
1415
1416 /* send cvp vol table cal */
1417 voice_send_cvp_vol_tbl_to_modem(v);
1418
1419 /* enable vocproc and wait for respose */
1420 voice_send_enable_vocproc_cmd(v);
1421
1422 /* send tty mode if tty device is used */
1423 voice_send_tty_mode_to_modem(v);
1424
Neema Shetty90189b82011-06-27 14:58:37 -07001425 if (is_voip_session(v->session_id))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001426 voice_send_netid_timing_cmd(v);
1427
Ben Rombergerfce8f512011-07-18 16:46:09 -07001428 rtac_add_voice(v->cvs_handle, v->cvp_handle,
Ben Rombergerc5d6a372011-09-22 18:01:49 -07001429 v->dev_rx.dev_port_id, v->dev_tx.dev_port_id,
1430 v->session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001431
1432 return 0;
1433fail:
1434 return -EINVAL;
1435}
1436
1437static int voice_send_stop_voice_cmd(struct voice_data *v)
1438{
1439 struct apr_hdr mvm_stop_voice_cmd;
1440 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001441 void *apr_mvm = voice_get_apr_mvm();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001442 u16 mvm_handle = voice_get_mvm_handle(v);
1443
1444 mvm_stop_voice_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1445 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1446 mvm_stop_voice_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1447 sizeof(mvm_stop_voice_cmd) - APR_HDR_SIZE);
1448 pr_info("send mvm_stop_voice_cmd pkt size = %d\n",
1449 mvm_stop_voice_cmd.pkt_size);
Neema Shetty90189b82011-06-27 14:58:37 -07001450 mvm_stop_voice_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001451 mvm_stop_voice_cmd.dest_port = mvm_handle;
1452 mvm_stop_voice_cmd.token = 0;
1453 mvm_stop_voice_cmd.opcode = VSS_IMVM_CMD_STOP_VOICE;
1454
1455 v->mvm_state = CMD_STATUS_FAIL;
1456 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_stop_voice_cmd);
1457 if (ret < 0) {
1458 pr_err("Fail in sending VSS_IMVM_CMD_STOP_VOICE\n");
1459 goto fail;
1460 }
1461 ret = wait_event_timeout(v->mvm_wait,
1462 (v->mvm_state == CMD_STATUS_SUCCESS),
1463 msecs_to_jiffies(TIMEOUT_MS));
1464 if (!ret) {
1465 pr_err("%s: wait_event timeout\n", __func__);
1466 goto fail;
1467 }
1468
1469 return 0;
1470fail:
1471 return -EINVAL;
1472}
1473
1474static int voice_setup_modem_voice(struct voice_data *v)
1475{
1476 struct cvp_create_full_ctl_session_cmd cvp_session_cmd;
1477 int ret = 0;
1478 struct msm_snddev_info *dev_tx_info;
Neema Shetty90189b82011-06-27 14:58:37 -07001479 void *apr_cvp = voice_get_apr_cvp();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001480
1481 /* create cvp session and wait for response */
1482 cvp_session_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1483 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1484 cvp_session_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1485 sizeof(cvp_session_cmd) - APR_HDR_SIZE);
1486 pr_info(" send create cvp session, pkt size = %d\n",
1487 cvp_session_cmd.hdr.pkt_size);
Neema Shetty90189b82011-06-27 14:58:37 -07001488 cvp_session_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001489 cvp_session_cmd.hdr.dest_port = 0;
1490 cvp_session_cmd.hdr.token = 0;
1491 cvp_session_cmd.hdr.opcode =
1492 VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION;
1493
1494 dev_tx_info = audio_dev_ctrl_find_dev(v->dev_tx.dev_id);
1495 if (IS_ERR(dev_tx_info)) {
1496 pr_err("bad dev_id %d\n", v->dev_tx.dev_id);
1497 goto fail;
1498 }
1499
1500 /* Use default topology if invalid value in ACDB */
1501 cvp_session_cmd.cvp_session.tx_topology_id =
1502 get_voice_tx_topology();
1503 if (cvp_session_cmd.cvp_session.tx_topology_id == 0) {
1504 if (dev_tx_info->channel_mode > 1)
1505 cvp_session_cmd.cvp_session.tx_topology_id =
1506 VSS_IVOCPROC_TOPOLOGY_ID_TX_DM_FLUENCE;
1507 else
1508 cvp_session_cmd.cvp_session.tx_topology_id =
1509 VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
1510 }
1511
1512 cvp_session_cmd.cvp_session.rx_topology_id =
1513 get_voice_rx_topology();
1514 if (cvp_session_cmd.cvp_session.rx_topology_id == 0)
1515 cvp_session_cmd.cvp_session.rx_topology_id =
1516 VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
1517
1518 cvp_session_cmd.cvp_session.direction = 2; /*tx and rx*/
1519 cvp_session_cmd.cvp_session.network_id = VSS_NETWORK_ID_DEFAULT;
1520 cvp_session_cmd.cvp_session.tx_port_id = v->dev_tx.dev_port_id;
1521 cvp_session_cmd.cvp_session.rx_port_id = v->dev_rx.dev_port_id;
1522 pr_info("topology=%d net_id=%d, dir=%d tx_port_id=%d, rx_port_id=%d\n",
1523 cvp_session_cmd.cvp_session.tx_topology_id,
1524 cvp_session_cmd.cvp_session.network_id,
1525 cvp_session_cmd.cvp_session.direction,
1526 cvp_session_cmd.cvp_session.tx_port_id,
1527 cvp_session_cmd.cvp_session.rx_port_id);
1528
1529 v->cvp_state = CMD_STATUS_FAIL;
1530 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_session_cmd);
1531 if (ret < 0) {
1532 pr_err("Fail in sending VOCPROC_FULL_CONTROL_SESSION\n");
1533 goto fail;
1534 }
1535 pr_debug("wait for cvp create session event\n");
1536 ret = wait_event_timeout(v->cvp_wait,
1537 (v->cvp_state == CMD_STATUS_SUCCESS),
1538 msecs_to_jiffies(TIMEOUT_MS));
1539 if (!ret) {
1540 pr_err("%s: wait_event timeout\n", __func__);
1541 goto fail;
1542 }
1543
1544 /* send cvs cal */
1545 voice_send_cvs_cal_to_modem(v);
1546
1547 /* send cvp cal */
1548 voice_send_cvp_cal_to_modem(v);
1549
1550 /* send cvp vol table cal */
1551 voice_send_cvp_vol_tbl_to_modem(v);
1552
1553 return 0;
1554
1555fail:
1556 return -EINVAL;
1557}
1558
1559static int voice_send_enable_vocproc_cmd(struct voice_data *v)
1560{
1561 int ret = 0;
1562 struct apr_hdr cvp_enable_cmd;
1563
1564 u16 cvp_handle = voice_get_cvp_handle(v);
Neema Shetty90189b82011-06-27 14:58:37 -07001565 void *apr_cvp = voice_get_apr_cvp();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001566
1567 /* enable vocproc and wait for respose */
1568 cvp_enable_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1569 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1570 cvp_enable_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1571 sizeof(cvp_enable_cmd) - APR_HDR_SIZE);
1572 pr_debug("cvp_enable_cmd pkt size = %d, cvp_handle=%d\n",
1573 cvp_enable_cmd.pkt_size, cvp_handle);
Neema Shetty90189b82011-06-27 14:58:37 -07001574 cvp_enable_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001575 cvp_enable_cmd.dest_port = cvp_handle;
1576 cvp_enable_cmd.token = 0;
1577 cvp_enable_cmd.opcode = VSS_IVOCPROC_CMD_ENABLE;
1578
1579 v->cvp_state = CMD_STATUS_FAIL;
1580 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_enable_cmd);
1581 if (ret < 0) {
1582 pr_err("Fail in sending VSS_IVOCPROC_CMD_ENABLE\n");
1583 goto fail;
1584 }
1585 ret = wait_event_timeout(v->cvp_wait,
1586 (v->cvp_state == CMD_STATUS_SUCCESS),
1587 msecs_to_jiffies(TIMEOUT_MS));
1588 if (!ret) {
1589 pr_err("%s: wait_event timeout\n", __func__);
1590 goto fail;
1591 }
1592
1593 return 0;
1594fail:
1595 return -EINVAL;
1596}
1597
1598static int voice_send_netid_timing_cmd(struct voice_data *v)
1599{
1600 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001601 void *apr_mvm = voice_get_apr_mvm();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001602 struct mvm_set_network_cmd mvm_set_network;
1603 struct mvm_set_voice_timing_cmd mvm_set_voice_timing;
1604 u16 mvm_handle = voice_get_mvm_handle(v);
1605
1606 ret = voice_config_cvs_vocoder(v);
1607 if (ret < 0) {
1608 pr_err("%s: Error %d configuring CVS voc",
1609 __func__, ret);
1610 goto fail;
1611 }
1612 /* Set network ID. */
1613 pr_debug("%s: Setting network ID\n", __func__);
1614
1615 mvm_set_network.hdr.hdr_field =
1616 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1617 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1618 mvm_set_network.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1619 sizeof(mvm_set_network) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001620 mvm_set_network.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001621 mvm_set_network.hdr.dest_port = mvm_handle;
1622 mvm_set_network.hdr.token = 0;
1623 mvm_set_network.hdr.opcode = VSS_ICOMMON_CMD_SET_NETWORK;
Neema Shetty90189b82011-06-27 14:58:37 -07001624 mvm_set_network.network.network_id = common.mvs_info.network_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001625
1626 v->mvm_state = CMD_STATUS_FAIL;
1627 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_network);
1628 if (ret < 0) {
1629 pr_err("%s: Error %d sending SET_NETWORK\n", __func__, ret);
1630 goto fail;
1631 }
1632
1633 ret = wait_event_timeout(v->mvm_wait,
1634 (v->mvm_state == CMD_STATUS_SUCCESS),
1635 msecs_to_jiffies(TIMEOUT_MS));
1636 if (!ret) {
1637 pr_err("%s: wait_event timeout\n", __func__);
1638 goto fail;
1639 }
1640
1641 /* Set voice timing. */
1642 pr_debug("%s: Setting voice timing\n", __func__);
1643
1644 mvm_set_voice_timing.hdr.hdr_field =
1645 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1646 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1647 mvm_set_voice_timing.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1648 sizeof(mvm_set_voice_timing) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001649 mvm_set_voice_timing.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001650 mvm_set_voice_timing.hdr.dest_port = mvm_handle;
1651 mvm_set_voice_timing.hdr.token = 0;
1652 mvm_set_voice_timing.hdr.opcode =
1653 VSS_ICOMMON_CMD_SET_VOICE_TIMING;
1654 mvm_set_voice_timing.timing.mode = 0;
1655 mvm_set_voice_timing.timing.enc_offset = 8000;
1656 mvm_set_voice_timing.timing.dec_req_offset = 3300;
1657 mvm_set_voice_timing.timing.dec_offset = 8300;
1658
1659 v->mvm_state = CMD_STATUS_FAIL;
1660
1661 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_voice_timing);
1662 if (ret < 0) {
1663 pr_err("%s: Error %d sending SET_TIMING\n", __func__, ret);
1664 goto fail;
1665 }
1666
1667 ret = wait_event_timeout(v->mvm_wait,
1668 (v->mvm_state == CMD_STATUS_SUCCESS),
1669 msecs_to_jiffies(TIMEOUT_MS));
1670 if (!ret) {
1671 pr_err("%s: wait_event timeout\n", __func__);
1672 goto fail;
1673 }
1674
1675 return 0;
1676fail:
1677 return -EINVAL;
1678}
1679
1680static int voice_attach_vocproc(struct voice_data *v)
1681{
1682 int ret = 0;
1683 struct mvm_attach_vocproc_cmd mvm_a_vocproc_cmd;
Neema Shetty90189b82011-06-27 14:58:37 -07001684 void *apr_mvm = voice_get_apr_mvm();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001685 u16 mvm_handle = voice_get_mvm_handle(v);
1686 u16 cvp_handle = voice_get_cvp_handle(v);
1687
1688 /* send enable vocproc */
1689 voice_send_enable_vocproc_cmd(v);
1690
1691 /* attach vocproc and wait for response */
1692 mvm_a_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1693 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1694 mvm_a_vocproc_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1695 sizeof(mvm_a_vocproc_cmd) - APR_HDR_SIZE);
1696 pr_info("send mvm_a_vocproc_cmd pkt size = %d\n",
1697 mvm_a_vocproc_cmd.hdr.pkt_size);
Neema Shetty90189b82011-06-27 14:58:37 -07001698 mvm_a_vocproc_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001699 mvm_a_vocproc_cmd.hdr.dest_port = mvm_handle;
1700 mvm_a_vocproc_cmd.hdr.token = 0;
Neema Shetty7e4a9b52011-07-26 15:24:51 -07001701 mvm_a_vocproc_cmd.hdr.opcode = VSS_ISTREAM_CMD_ATTACH_VOCPROC;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001702 mvm_a_vocproc_cmd.mvm_attach_cvp_handle.handle = cvp_handle;
1703
1704 v->mvm_state = CMD_STATUS_FAIL;
1705 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_a_vocproc_cmd);
1706 if (ret < 0) {
Neema Shetty7e4a9b52011-07-26 15:24:51 -07001707 pr_err("Fail in sending VSS_ISTREAM_CMD_ATTACH_VOCPROC\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001708 goto fail;
1709 }
1710 ret = wait_event_timeout(v->mvm_wait,
1711 (v->mvm_state == CMD_STATUS_SUCCESS),
1712 msecs_to_jiffies(TIMEOUT_MS));
1713 if (!ret) {
1714 pr_err("%s: wait_event timeout\n", __func__);
1715 goto fail;
1716 }
1717
1718 /* send tty mode if tty device is used */
1719 voice_send_tty_mode_to_modem(v);
1720
Neema Shetty90189b82011-06-27 14:58:37 -07001721 if (is_voip_session(v->session_id))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001722 voice_send_netid_timing_cmd(v);
1723
Ben Rombergerfce8f512011-07-18 16:46:09 -07001724 rtac_add_voice(v->cvs_handle, v->cvp_handle,
Ben Rombergerc5d6a372011-09-22 18:01:49 -07001725 v->dev_rx.dev_port_id, v->dev_tx.dev_port_id,
1726 v->session_id);
Ben Rombergerfce8f512011-07-18 16:46:09 -07001727
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001728 return 0;
1729fail:
1730 return -EINVAL;
1731}
1732
1733static int voice_destroy_modem_voice(struct voice_data *v)
1734{
1735 struct mvm_detach_vocproc_cmd mvm_d_vocproc_cmd;
1736 struct apr_hdr cvp_destroy_session_cmd;
1737 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001738 void *apr_mvm = voice_get_apr_mvm();
1739 void *apr_cvp = voice_get_apr_cvp();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001740 u16 mvm_handle = voice_get_mvm_handle(v);
1741 u16 cvp_handle = voice_get_cvp_handle(v);
1742
1743 /* detach VOCPROC and wait for response from mvm */
1744 mvm_d_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1745 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1746 mvm_d_vocproc_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1747 sizeof(mvm_d_vocproc_cmd) - APR_HDR_SIZE);
1748 pr_info("mvm_d_vocproc_cmd pkt size = %d\n",
1749 mvm_d_vocproc_cmd.hdr.pkt_size);
Neema Shetty90189b82011-06-27 14:58:37 -07001750 mvm_d_vocproc_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001751 mvm_d_vocproc_cmd.hdr.dest_port = mvm_handle;
1752 mvm_d_vocproc_cmd.hdr.token = 0;
Neema Shetty7e4a9b52011-07-26 15:24:51 -07001753 mvm_d_vocproc_cmd.hdr.opcode = VSS_ISTREAM_CMD_DETACH_VOCPROC;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001754 mvm_d_vocproc_cmd.mvm_detach_cvp_handle.handle = cvp_handle;
1755
1756 v->mvm_state = CMD_STATUS_FAIL;
1757 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_d_vocproc_cmd);
1758 if (ret < 0) {
Neema Shetty7e4a9b52011-07-26 15:24:51 -07001759 pr_err("Fail in sending VSS_ISTREAM_CMD_DETACH_VOCPROC\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001760 goto fail;
1761 }
1762 ret = wait_event_timeout(v->mvm_wait,
1763 (v->mvm_state == CMD_STATUS_SUCCESS),
1764 msecs_to_jiffies(TIMEOUT_MS));
1765 if (!ret) {
1766 pr_err("%s: wait_event timeout\n", __func__);
1767 goto fail;
1768 }
1769
1770 /* destrop cvp session */
1771 cvp_destroy_session_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1772 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1773 cvp_destroy_session_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1774 sizeof(cvp_destroy_session_cmd) - APR_HDR_SIZE);
1775 pr_info("cvp_destroy_session_cmd pkt size = %d\n",
1776 cvp_destroy_session_cmd.pkt_size);
Neema Shetty90189b82011-06-27 14:58:37 -07001777 cvp_destroy_session_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001778 cvp_destroy_session_cmd.dest_port = cvp_handle;
1779 cvp_destroy_session_cmd.token = 0;
1780 cvp_destroy_session_cmd.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
1781
1782 v->cvp_state = CMD_STATUS_FAIL;
1783 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_destroy_session_cmd);
1784 if (ret < 0) {
1785 pr_err("Fail in sending APRV2_IBASIC_CMD_DESTROY_SESSION\n");
1786 goto fail;
1787 }
1788 ret = wait_event_timeout(v->cvp_wait,
1789 (v->cvp_state == CMD_STATUS_SUCCESS),
1790 msecs_to_jiffies(TIMEOUT_MS));
1791 if (!ret) {
1792 pr_err("%s: wait_event timeout\n", __func__);
1793 goto fail;
1794 }
Ben Rombergerfce8f512011-07-18 16:46:09 -07001795 rtac_remove_voice(v->cvs_handle);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001796 cvp_handle = 0;
1797 voice_set_cvp_handle(v, cvp_handle);
1798
1799 return 0;
1800
1801fail:
1802 return -EINVAL;
1803}
1804
1805static int voice_send_mute_cmd_to_modem(struct voice_data *v)
1806{
1807 struct cvs_set_mute_cmd cvs_mute_cmd;
1808 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001809 void *apr_cvs = voice_get_apr_cvs();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001810 u16 cvs_handle = voice_get_cvs_handle(v);
1811
1812 /* send mute/unmute to cvs */
1813 cvs_mute_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1814 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1815 cvs_mute_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1816 sizeof(cvs_mute_cmd) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001817 cvs_mute_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001818 cvs_mute_cmd.hdr.dest_port = cvs_handle;
1819 cvs_mute_cmd.hdr.token = 0;
1820 cvs_mute_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_MUTE;
1821 cvs_mute_cmd.cvs_set_mute.direction = 0; /*tx*/
1822 cvs_mute_cmd.cvs_set_mute.mute_flag = v->dev_tx.mute;
1823
1824 pr_info(" mute value =%d\n", cvs_mute_cmd.cvs_set_mute.mute_flag);
1825 v->cvs_state = CMD_STATUS_FAIL;
1826 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_mute_cmd);
1827 if (ret < 0) {
1828 pr_err("Fail: send STREAM SET MUTE\n");
1829 goto fail;
1830 }
1831 ret = wait_event_timeout(v->cvs_wait,
1832 (v->cvs_state == CMD_STATUS_SUCCESS),
1833 msecs_to_jiffies(TIMEOUT_MS));
1834 if (!ret)
1835 pr_err("%s: wait_event timeout\n", __func__);
1836
1837fail:
1838 return 0;
1839}
1840
1841static int voice_send_vol_index_to_modem(struct voice_data *v)
1842{
1843 struct cvp_set_rx_volume_index_cmd cvp_vol_cmd;
1844 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001845 void *apr_cvp = voice_get_apr_cvp();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001846 u16 cvp_handle = voice_get_cvp_handle(v);
1847
1848 /* send volume index to cvp */
1849 cvp_vol_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1850 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1851 cvp_vol_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1852 sizeof(cvp_vol_cmd) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001853 cvp_vol_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001854 cvp_vol_cmd.hdr.dest_port = cvp_handle;
1855 cvp_vol_cmd.hdr.token = 0;
1856 cvp_vol_cmd.hdr.opcode =
1857 VSS_IVOCPROC_CMD_SET_RX_VOLUME_INDEX;
1858 cvp_vol_cmd.cvp_set_vol_idx.vol_index = v->dev_rx.volume;
1859 v->cvp_state = CMD_STATUS_FAIL;
1860 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_vol_cmd);
1861 if (ret < 0) {
1862 pr_err("Fail in sending RX VOL INDEX\n");
1863 return -EINVAL;
1864 }
1865 ret = wait_event_timeout(v->cvp_wait,
1866 (v->cvp_state == CMD_STATUS_SUCCESS),
1867 msecs_to_jiffies(TIMEOUT_MS));
1868 if (!ret) {
1869 pr_err("%s: wait_event timeout\n", __func__);
1870 return -EINVAL;
1871 }
1872 return 0;
1873}
1874
1875static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode)
1876{
1877 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001878 void *apr_cvs = voice_get_apr_cvs();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001879 u16 cvs_handle = voice_get_cvs_handle(v);
1880 struct cvs_start_record_cmd cvs_start_record;
1881
1882 pr_debug("%s: Start record %d\n", __func__, rec_mode);
1883
1884 cvs_start_record.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1885 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1886 cvs_start_record.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1887 sizeof(cvs_start_record) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001888 cvs_start_record.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001889 cvs_start_record.hdr.dest_port = cvs_handle;
1890 cvs_start_record.hdr.token = 0;
1891 cvs_start_record.hdr.opcode = VSS_ISTREAM_CMD_START_RECORD;
1892
1893 if (rec_mode == VOC_REC_UPLINK) {
1894 cvs_start_record.rec_mode.rx_tap_point = VSS_TAP_POINT_NONE;
1895 cvs_start_record.rec_mode.tx_tap_point =
1896 VSS_TAP_POINT_STREAM_END;
1897 } else if (rec_mode == VOC_REC_DOWNLINK) {
1898 cvs_start_record.rec_mode.rx_tap_point =
1899 VSS_TAP_POINT_STREAM_END;
1900 cvs_start_record.rec_mode.tx_tap_point = VSS_TAP_POINT_NONE;
1901 } else if (rec_mode == VOC_REC_BOTH) {
1902 cvs_start_record.rec_mode.rx_tap_point =
1903 VSS_TAP_POINT_STREAM_END;
1904 cvs_start_record.rec_mode.tx_tap_point =
1905 VSS_TAP_POINT_STREAM_END;
1906 } else {
1907 pr_err("%s: Invalid in-call rec_mode %d\n", __func__, rec_mode);
1908
1909 ret = -EINVAL;
1910 goto fail;
1911 }
1912
1913 v->cvs_state = CMD_STATUS_FAIL;
1914
1915 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_start_record);
1916 if (ret < 0) {
1917 pr_err("%s: Error %d sending START_RECORD\n", __func__, ret);
1918
1919 goto fail;
1920 }
1921
1922 ret = wait_event_timeout(v->cvs_wait,
1923 (v->cvs_state == CMD_STATUS_SUCCESS),
1924 msecs_to_jiffies(TIMEOUT_MS));
1925 if (!ret) {
1926 pr_err("%s: wait_event timeout\n", __func__);
1927
1928 goto fail;
1929 }
1930
1931 return 0;
1932
1933fail:
1934 return ret;
1935}
1936
1937static int voice_cvs_stop_record(struct voice_data *v)
1938{
1939 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07001940 void *apr_cvs = voice_get_apr_cvs();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001941 u16 cvs_handle = voice_get_cvs_handle(v);
1942 struct apr_hdr cvs_stop_record;
1943
1944 pr_debug("%s: Stop record\n", __func__);
1945
1946 cvs_stop_record.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1947 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1948 cvs_stop_record.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1949 sizeof(cvs_stop_record) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07001950 cvs_stop_record.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001951 cvs_stop_record.dest_port = cvs_handle;
1952 cvs_stop_record.token = 0;
1953 cvs_stop_record.opcode = VSS_ISTREAM_CMD_STOP_RECORD;
1954
1955 v->cvs_state = CMD_STATUS_FAIL;
1956
1957 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_stop_record);
1958 if (ret < 0) {
1959 pr_err("%s: Error %d sending STOP_RECORD\n", __func__, ret);
1960
1961 goto fail;
1962 }
1963
1964 ret = wait_event_timeout(v->cvs_wait,
1965 (v->cvs_state == CMD_STATUS_SUCCESS),
1966 msecs_to_jiffies(TIMEOUT_MS));
1967 if (!ret) {
1968 pr_err("%s: wait_event timeout\n", __func__);
1969
1970 goto fail;
1971 }
1972
1973 return 0;
1974
1975fail:
1976 return ret;
1977}
1978
1979int voice_start_record(uint32_t rec_mode, uint32_t set)
1980{
Neema Shetty90189b82011-06-27 14:58:37 -07001981 int ret = 0, i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001982 u16 cvs_handle;
1983
1984 pr_debug("%s: rec_mode %d, set %d\n", __func__, rec_mode, set);
1985
Neema Shetty90189b82011-06-27 14:58:37 -07001986 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
1987 struct voice_data *v = &common.voice[i];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001988
Neema Shetty90189b82011-06-27 14:58:37 -07001989 mutex_lock(&v->lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001990
Neema Shetty90189b82011-06-27 14:58:37 -07001991 cvs_handle = voice_get_cvs_handle(v);
1992
1993 if (cvs_handle != 0) {
1994 if (set)
1995 ret = voice_cvs_start_record(v, rec_mode);
1996 else
1997 ret = voice_cvs_stop_record(v);
1998 } else {
1999 /* Cache the value for later. */
2000 v->rec_info.pending = set;
2001 v->rec_info.rec_mode = rec_mode;
2002 }
2003
2004 mutex_unlock(&v->lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002005 }
2006
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002007 return ret;
2008}
2009
2010static int voice_cvs_start_playback(struct voice_data *v)
2011{
2012 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07002013 void *apr_cvs = voice_get_apr_cvs();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002014 u16 cvs_handle = voice_get_cvs_handle(v);
2015 struct apr_hdr cvs_start_playback;
2016
2017 pr_debug("%s: Start playback\n", __func__);
2018
2019 cvs_start_playback.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2020 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2021 cvs_start_playback.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2022 sizeof(cvs_start_playback) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07002023 cvs_start_playback.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002024 cvs_start_playback.dest_port = cvs_handle;
2025 cvs_start_playback.token = 0;
2026 cvs_start_playback.opcode = VSS_ISTREAM_CMD_START_PLAYBACK;
2027
2028 v->cvs_state = CMD_STATUS_FAIL;
2029
2030 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_start_playback);
2031 if (ret < 0) {
2032 pr_err("%s: Error %d sending START_PLAYBACK\n",
2033 __func__, ret);
2034
2035 goto fail;
2036 }
2037
2038 ret = wait_event_timeout(v->cvs_wait,
2039 (v->cvs_state == CMD_STATUS_SUCCESS),
2040 msecs_to_jiffies(TIMEOUT_MS));
2041 if (!ret) {
2042 pr_err("%s: wait_event timeout\n", __func__);
2043
2044 goto fail;
2045 }
2046
2047 v->music_info.playing = 1;
2048
2049 return 0;
2050
2051fail:
2052 return ret;
2053}
2054
2055static int voice_cvs_stop_playback(struct voice_data *v)
2056{
2057 int ret = 0;
Neema Shetty90189b82011-06-27 14:58:37 -07002058 void *apr_cvs = voice_get_apr_cvs();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002059 u16 cvs_handle = voice_get_cvs_handle(v);
2060 struct apr_hdr cvs_stop_playback;
2061
2062 pr_debug("%s: Stop playback\n", __func__);
2063
2064 if (v->music_info.playing) {
2065 cvs_stop_playback.hdr_field =
2066 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2067 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2068 cvs_stop_playback.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2069 sizeof(cvs_stop_playback) - APR_HDR_SIZE);
Neema Shetty90189b82011-06-27 14:58:37 -07002070 cvs_stop_playback.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002071 cvs_stop_playback.dest_port = cvs_handle;
2072 cvs_stop_playback.token = 0;
2073
2074 cvs_stop_playback.opcode = VSS_ISTREAM_CMD_STOP_PLAYBACK;
2075
2076 v->cvs_state = CMD_STATUS_FAIL;
2077
2078 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_stop_playback);
2079 if (ret < 0) {
2080 pr_err("%s: Error %d sending STOP_PLAYBACK\n",
2081 __func__, ret);
2082
2083 goto fail;
2084 }
2085
2086 ret = wait_event_timeout(v->cvs_wait,
2087 (v->cvs_state == CMD_STATUS_SUCCESS),
2088 msecs_to_jiffies(TIMEOUT_MS));
2089 if (!ret) {
2090 pr_err("%s: wait_event timeout\n", __func__);
2091
2092 goto fail;
2093 }
2094
2095 v->music_info.playing = 0;
2096 } else {
2097 pr_err("%s: Stop playback already sent\n", __func__);
2098 }
2099
2100 return 0;
2101
2102fail:
2103 return ret;
2104}
2105
2106int voice_start_playback(uint32_t set)
2107{
Neema Shetty90189b82011-06-27 14:58:37 -07002108 int ret = 0, i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002109 u16 cvs_handle;
2110
2111 pr_debug("%s: Start playback %d\n", __func__, set);
2112
Neema Shetty90189b82011-06-27 14:58:37 -07002113 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
2114 struct voice_data *v = &common.voice[i];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002115
Neema Shetty90189b82011-06-27 14:58:37 -07002116 mutex_lock(&v->lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002117
Neema Shetty90189b82011-06-27 14:58:37 -07002118 cvs_handle = voice_get_cvs_handle(v);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002119
Neema Shetty90189b82011-06-27 14:58:37 -07002120 if (cvs_handle != 0) {
2121 if (set)
2122 ret = voice_cvs_start_playback(v);
2123 else
2124 ret = voice_cvs_stop_playback(v);
2125 } else {
2126 /* Cache the value for later. */
2127 pr_debug("%s: Caching ICP value", __func__);
2128
2129 v->music_info.pending = set;
2130 }
2131
2132 mutex_unlock(&v->lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002133 }
2134
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002135 return ret;
2136}
2137
2138static void voice_auddev_cb_function(u32 evt_id,
2139 union auddev_evt_data *evt_payload,
2140 void *private_data)
2141{
Neema Shetty90189b82011-06-27 14:58:37 -07002142 struct common_data *c = private_data;
2143 struct voice_data *v = NULL;
2144
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002145 struct sidetone_cal sidetone_cal_data;
Neema Shetty90189b82011-06-27 14:58:37 -07002146 int rc = 0, i = 0;
Bharath Ramachandramurthyb9209472011-09-27 17:56:20 -07002147 int rc1 = 0;
2148
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002149 pr_info("auddev_cb_function, evt_id=%d,\n", evt_id);
Neema Shetty90189b82011-06-27 14:58:37 -07002150
2151 if (evt_payload == NULL) {
2152 pr_err("%s: evt_payload is NULL pointer\n", __func__);
2153 return;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002154 }
2155
2156 switch (evt_id) {
2157 case AUDDEV_EVT_START_VOICE:
Neema Shetty90189b82011-06-27 14:58:37 -07002158 v = voice_get_session(evt_payload->voice_session_id);
2159 if (v == NULL) {
2160 pr_err("%s: v is NULL\n", __func__);
2161 return;
2162 }
2163
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002164 mutex_lock(&v->lock);
2165
2166 if ((v->voc_state == VOC_INIT) ||
2167 (v->voc_state == VOC_RELEASE)) {
2168 v->v_call_status = VOICE_CALL_START;
2169 if ((v->dev_rx.enabled == VOICE_DEV_ENABLED)
2170 && (v->dev_tx.enabled == VOICE_DEV_ENABLED)) {
Neema Shetty90189b82011-06-27 14:58:37 -07002171 rc = voice_apr_register();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002172 if (rc < 0) {
2173 pr_err("%s: voice apr registration"
2174 "failed\n", __func__);
2175 mutex_unlock(&v->lock);
2176 return;
2177 }
Bharath Ramachandramurthyb9209472011-09-27 17:56:20 -07002178 rc1 = voice_create_mvm_cvs_session(v);
2179 if (rc1 < 0) {
2180 pr_err("%s: create mvm-cvs failed\n",
2181 __func__);
2182 msleep(100);
2183 rc = voice_apr_register();
2184 if (rc < 0) {
2185 mutex_unlock(&v->lock);
2186 pr_err("%s: voice apr regn"
2187 "failed\n", __func__);
2188 return;
2189 }
2190 rc1 = voice_create_mvm_cvs_session(v);
2191 if (rc1 < 0) {
2192 mutex_unlock(&v->lock);
2193 pr_err("%s:Retry mvmcvs "
2194 "failed\n",
2195 __func__);
2196 return;
2197 }
2198 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002199 voice_setup_modem_voice(v);
2200 voice_attach_vocproc(v);
2201 voice_send_start_voice_cmd(v);
2202 get_sidetone_cal(&sidetone_cal_data);
2203 msm_snddev_enable_sidetone(
2204 v->dev_rx.dev_id,
2205 sidetone_cal_data.enable,
2206 sidetone_cal_data.gain);
2207 v->voc_state = VOC_RUN;
2208
2209 /* Start in-call recording if command was
2210 * pending. */
2211 if (v->rec_info.pending) {
2212 voice_cvs_start_record(v,
2213 v->rec_info.rec_mode);
2214
2215 v->rec_info.pending = 0;
2216 }
2217
2218 /* Start in-call music delivery if command was
2219 * pending. */
2220 if (v->music_info.pending) {
2221 voice_cvs_start_playback(v);
2222
2223 v->music_info.pending = 0;
2224 }
2225 }
2226 }
2227
2228 mutex_unlock(&v->lock);
2229 break;
2230 case AUDDEV_EVT_DEV_CHG_VOICE:
Neema Shetty90189b82011-06-27 14:58:37 -07002231 /* Device change is applicable to all sessions. */
2232 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
2233 v = &c->voice[i];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002234
Neema Shetty90189b82011-06-27 14:58:37 -07002235 if (v->dev_rx.enabled == VOICE_DEV_ENABLED)
2236 msm_snddev_enable_sidetone(v->dev_rx.dev_id,
2237 0, 0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002238
Neema Shetty90189b82011-06-27 14:58:37 -07002239 v->dev_rx.enabled = VOICE_DEV_DISABLED;
2240 v->dev_tx.enabled = VOICE_DEV_DISABLED;
2241
2242 mutex_lock(&v->lock);
2243
2244 if (v->voc_state == VOC_RUN) {
2245 /* send cmd to modem to do voice device
2246 * change */
2247 voice_disable_vocproc(v);
2248 v->voc_state = VOC_CHANGE;
2249 }
2250
2251 mutex_unlock(&v->lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002252 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002253 break;
2254 case AUDDEV_EVT_DEV_RDY:
Neema Shetty90189b82011-06-27 14:58:37 -07002255 /* Device change is applicable to all sessions. */
2256 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
2257 v = &c->voice[i];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002258
Neema Shetty90189b82011-06-27 14:58:37 -07002259 mutex_lock(&v->lock);
2260
2261 if (v->voc_state == VOC_CHANGE) {
2262 /* get port Ids */
2263 if (evt_payload->voc_devinfo.dev_type ==
2264 DIR_RX) {
2265 v->dev_rx.dev_port_id =
2266 evt_payload->voc_devinfo.dev_port_id;
2267 v->dev_rx.sample =
2268 evt_payload->voc_devinfo.dev_sample;
2269 v->dev_rx.dev_id =
2270 evt_payload->voc_devinfo.dev_id;
2271 v->dev_rx.enabled = VOICE_DEV_ENABLED;
2272 } else {
2273 v->dev_tx.dev_port_id =
2274 evt_payload->voc_devinfo.dev_port_id;
2275 v->dev_tx.sample =
2276 evt_payload->voc_devinfo.dev_sample;
2277 v->dev_tx.enabled = VOICE_DEV_ENABLED;
2278 v->dev_tx.dev_id =
2279 evt_payload->voc_devinfo.dev_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002280 }
Neema Shetty90189b82011-06-27 14:58:37 -07002281 if ((v->dev_rx.enabled == VOICE_DEV_ENABLED) &&
2282 (v->dev_tx.enabled == VOICE_DEV_ENABLED)) {
2283 voice_set_device(v);
2284 get_sidetone_cal(&sidetone_cal_data);
2285 msm_snddev_enable_sidetone(
2286 v->dev_rx.dev_id,
2287 sidetone_cal_data.enable,
2288 sidetone_cal_data.gain);
2289 v->voc_state = VOC_RUN;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002290 }
Neema Shetty90189b82011-06-27 14:58:37 -07002291 } else if ((v->voc_state == VOC_INIT) ||
2292 (v->voc_state == VOC_RELEASE)) {
2293 /* get AFE ports */
2294 if (evt_payload->voc_devinfo.dev_type ==
2295 DIR_RX) {
2296 /* get rx port id */
2297 v->dev_rx.dev_port_id =
2298 evt_payload->voc_devinfo.dev_port_id;
2299 v->dev_rx.sample =
2300 evt_payload->voc_devinfo.dev_sample;
2301 v->dev_rx.dev_id =
2302 evt_payload->voc_devinfo.dev_id;
2303 v->dev_rx.enabled = VOICE_DEV_ENABLED;
2304 } else {
2305 /* get tx port id */
2306 v->dev_tx.dev_port_id =
2307 evt_payload->voc_devinfo.dev_port_id;
2308 v->dev_tx.sample =
2309 evt_payload->voc_devinfo.dev_sample;
2310 v->dev_tx.dev_id =
2311 evt_payload->voc_devinfo.dev_id;
2312 v->dev_tx.enabled = VOICE_DEV_ENABLED;
2313 }
2314 if ((v->dev_rx.enabled == VOICE_DEV_ENABLED) &&
2315 (v->dev_tx.enabled == VOICE_DEV_ENABLED) &&
2316 (v->v_call_status == VOICE_CALL_START)) {
2317 rc = voice_apr_register();
2318 if (rc < 0) {
2319 pr_err("%s: voice apr"
2320 "registration failed\n",
2321 __func__);
2322 mutex_unlock(&v->lock);
2323 return;
2324 }
2325 voice_create_mvm_cvs_session(v);
2326 voice_setup_modem_voice(v);
2327 voice_attach_vocproc(v);
2328 voice_send_start_voice_cmd(v);
2329 get_sidetone_cal(&sidetone_cal_data);
2330 msm_snddev_enable_sidetone(
2331 v->dev_rx.dev_id,
2332 sidetone_cal_data.enable,
2333 sidetone_cal_data.gain);
2334 v->voc_state = VOC_RUN;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002335
Neema Shetty90189b82011-06-27 14:58:37 -07002336 /* Start in-call recording if command
2337 * was pending. */
2338 if (v->rec_info.pending) {
2339 voice_cvs_start_record(v,
2340 v->rec_info.rec_mode);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002341
Neema Shetty90189b82011-06-27 14:58:37 -07002342 v->rec_info.pending = 0;
2343 }
2344
2345 /* Start in-call music delivery if
2346 * command was pending. */
2347 if (v->music_info.pending) {
2348 voice_cvs_start_playback(v);
2349
2350 v->music_info.pending = 0;
2351 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002352 }
2353 }
Neema Shetty90189b82011-06-27 14:58:37 -07002354
2355 mutex_unlock(&v->lock);
2356 }
2357 break;
2358 case AUDDEV_EVT_DEVICE_VOL_MUTE_CHG:
2359 v = voice_get_session(
2360 evt_payload->voc_vm_info.voice_session_id);
2361 if (v == NULL) {
2362 pr_err("%s: v is NULL\n", __func__);
2363 return;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002364 }
2365
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002366 /* cache the mute and volume index value */
Neema Shetty90189b82011-06-27 14:58:37 -07002367 if (evt_payload->voc_vm_info.dev_type == DIR_TX) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002368 v->dev_tx.mute =
2369 evt_payload->voc_vm_info.dev_vm_val.mute;
2370
2371 mutex_lock(&v->lock);
2372
2373 if (v->voc_state == VOC_RUN)
2374 voice_send_mute_cmd_to_modem(v);
2375
2376 mutex_unlock(&v->lock);
2377 } else {
Neema Shetty90189b82011-06-27 14:58:37 -07002378 v->dev_rx.volume =
2379 evt_payload->voc_vm_info.dev_vm_val.vol;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002380
2381 mutex_lock(&v->lock);
2382
2383 if (v->voc_state == VOC_RUN)
2384 voice_send_vol_index_to_modem(v);
2385
2386 mutex_unlock(&v->lock);
2387 }
2388 break;
2389 case AUDDEV_EVT_REL_PENDING:
Neema Shetty90189b82011-06-27 14:58:37 -07002390 /* Device change is applicable to all sessions. */
2391 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
2392 v = &c->voice[i];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002393
Neema Shetty90189b82011-06-27 14:58:37 -07002394 mutex_lock(&v->lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002395
Neema Shetty90189b82011-06-27 14:58:37 -07002396 if (v->voc_state == VOC_RUN) {
2397 voice_disable_vocproc(v);
2398 v->voc_state = VOC_CHANGE;
2399 }
2400
2401 mutex_unlock(&v->lock);
2402
2403 if (evt_payload->voc_devinfo.dev_type == DIR_RX)
2404 v->dev_rx.enabled = VOICE_DEV_DISABLED;
2405 else
2406 v->dev_tx.enabled = VOICE_DEV_DISABLED;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002407 }
2408
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002409 break;
2410 case AUDDEV_EVT_END_VOICE:
Neema Shetty90189b82011-06-27 14:58:37 -07002411 v = voice_get_session(evt_payload->voice_session_id);
2412 if (v == NULL) {
2413 pr_err("%s: v is NULL\n", __func__);
2414 return;
2415 }
2416
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002417 /* recover the tx mute and rx volume to the default values */
Neema Shetty90189b82011-06-27 14:58:37 -07002418 v->dev_tx.mute = c->default_mute_val;
2419 v->dev_rx.volume = c->default_vol_val;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002420 if (v->dev_rx.enabled == VOICE_DEV_ENABLED)
2421 msm_snddev_enable_sidetone(v->dev_rx.dev_id, 0, 0);
2422
2423 mutex_lock(&v->lock);
2424
2425 if (v->voc_state == VOC_RUN) {
2426 /* call stop modem voice */
2427 voice_send_stop_voice_cmd(v);
2428 voice_destroy_modem_voice(v);
2429 voice_destroy_mvm_cvs_session(v);
2430 v->voc_state = VOC_RELEASE;
2431 } else if (v->voc_state == VOC_CHANGE) {
2432 voice_send_stop_voice_cmd(v);
2433 voice_destroy_mvm_cvs_session(v);
2434 v->voc_state = VOC_RELEASE;
2435 }
2436
2437 mutex_unlock(&v->lock);
2438
2439 v->v_call_status = VOICE_CALL_END;
2440
2441 break;
2442 default:
2443 pr_err("UNKNOWN EVENT\n");
2444 }
2445 return;
2446}
2447EXPORT_SYMBOL(voice_auddev_cb_function);
2448
2449int voice_set_voc_path_full(uint32_t set)
2450{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002451 pr_info("%s: %d\n", __func__, set);
2452
Neema Shetty90189b82011-06-27 14:58:37 -07002453 mutex_lock(&common.common_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002454
Neema Shetty90189b82011-06-27 14:58:37 -07002455 if (set)
2456 common.voc_path = VOC_PATH_FULL;
2457 else
2458 common.voc_path = VOC_PATH_PASSIVE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002459
Neema Shetty90189b82011-06-27 14:58:37 -07002460 mutex_unlock(&common.common_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002461
Neema Shetty90189b82011-06-27 14:58:37 -07002462 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002463}
2464EXPORT_SYMBOL(voice_set_voc_path_full);
2465
2466void voice_register_mvs_cb(ul_cb_fn ul_cb,
2467 dl_cb_fn dl_cb,
2468 void *private_data)
2469{
Neema Shetty90189b82011-06-27 14:58:37 -07002470 common.mvs_info.ul_cb = ul_cb;
2471 common.mvs_info.dl_cb = dl_cb;
2472 common.mvs_info.private_data = private_data;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002473}
2474
2475void voice_config_vocoder(uint32_t media_type,
2476 uint32_t rate,
2477 uint32_t network_type,
Chaithanya Krishna Bacharaju2f2e8a52011-10-17 14:54:07 +05302478 uint32_t dtx_mode,
2479 struct q_min_max_rate q_min_max_rate)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002480{
Neema Shetty90189b82011-06-27 14:58:37 -07002481 common.mvs_info.media_type = media_type;
2482 common.mvs_info.rate = rate;
2483 common.mvs_info.network_type = network_type;
2484 common.mvs_info.dtx_mode = dtx_mode;
Chaithanya Krishna Bacharaju2f2e8a52011-10-17 14:54:07 +05302485 common.mvs_info.q_min_max_rate = q_min_max_rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002486}
2487
2488static int32_t modem_mvm_callback(struct apr_client_data *data, void *priv)
2489{
2490 uint32_t *ptr;
Neema Shetty90189b82011-06-27 14:58:37 -07002491 struct common_data *c = priv;
2492 struct voice_data *v = NULL;
2493 int i = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002494
Neema Shetty90189b82011-06-27 14:58:37 -07002495 pr_debug("%s: session_id 0x%x\n", __func__, data->dest_port);
2496
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002497 if (data->opcode == RESET_EVENTS) {
2498 pr_debug("%s:Reset event received in Voice service\n",
2499 __func__);
Neema Shetty90189b82011-06-27 14:58:37 -07002500 apr_reset(c->apr_mvm);
2501 c->apr_mvm = NULL;
2502 apr_reset(c->apr_q6_mvm);
2503 c->apr_q6_mvm = NULL;
2504
2505 /* Sub-system restart is applicable to all sessions. */
2506 for (i = 0; i < MAX_VOC_SESSIONS; i++)
2507 c->voice[i].mvm_handle = 0;
2508
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002509 return 0;
2510 }
2511
Swaminathan Sathappan71809462011-11-11 13:49:27 -08002512 v = voice_get_session(data->dest_port);
2513 if (v == NULL) {
2514 pr_err("%s: v is NULL\n", __func__);
2515 return -EINVAL;
2516 }
2517
2518 pr_debug("%s: common data 0x%x, session 0x%x\n",
2519 __func__, (unsigned int)c, (unsigned int)v);
2520 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
2521 data->payload_size, data->opcode);
2522
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002523 if (data->opcode == APR_BASIC_RSP_RESULT) {
2524 if (data->payload_size) {
2525 ptr = data->payload;
2526
2527 pr_info("%x %x\n", ptr[0], ptr[1]);
2528 /* ping mvm service ACK */
2529
2530 if (ptr[0] ==
2531 VSS_IMVM_CMD_CREATE_PASSIVE_CONTROL_SESSION ||
2532 ptr[0] ==
2533 VSS_IMVM_CMD_CREATE_FULL_CONTROL_SESSION) {
2534 /* Passive session is used for voice call
2535 * through modem. Full session is used for voice
2536 * call through Q6. */
2537 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2538 if (!ptr[1]) {
2539 pr_debug("%s: MVM handle is %d\n",
2540 __func__, data->src_port);
2541
2542 voice_set_mvm_handle(v, data->src_port);
2543 } else
2544 pr_info("got NACK for sending \
2545 MVM create session \n");
2546 v->mvm_state = CMD_STATUS_SUCCESS;
2547 wake_up(&v->mvm_wait);
2548 } else if (ptr[0] == VSS_IMVM_CMD_START_VOICE) {
2549 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2550 v->mvm_state = CMD_STATUS_SUCCESS;
2551 wake_up(&v->mvm_wait);
Neema Shetty7e4a9b52011-07-26 15:24:51 -07002552 } else if (ptr[0] == VSS_ISTREAM_CMD_ATTACH_VOCPROC) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002553 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2554 v->mvm_state = CMD_STATUS_SUCCESS;
2555 wake_up(&v->mvm_wait);
2556 } else if (ptr[0] == VSS_IMVM_CMD_STOP_VOICE) {
2557 v->mvm_state = CMD_STATUS_SUCCESS;
2558 wake_up(&v->mvm_wait);
Neema Shetty7e4a9b52011-07-26 15:24:51 -07002559 } else if (ptr[0] == VSS_ISTREAM_CMD_DETACH_VOCPROC) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002560 v->mvm_state = CMD_STATUS_SUCCESS;
2561 wake_up(&v->mvm_wait);
2562 } else if (ptr[0] == VSS_ISTREAM_CMD_SET_TTY_MODE) {
2563 v->mvm_state = CMD_STATUS_SUCCESS;
2564 wake_up(&v->mvm_wait);
2565 } else if (ptr[0] == APRV2_IBASIC_CMD_DESTROY_SESSION) {
2566 pr_debug("%s: DESTROY resp\n", __func__);
2567
2568 v->mvm_state = CMD_STATUS_SUCCESS;
2569 wake_up(&v->mvm_wait);
2570 } else if (ptr[0] == VSS_IMVM_CMD_ATTACH_STREAM) {
2571 pr_debug("%s: ATTACH_STREAM resp 0x%x\n",
2572 __func__, ptr[1]);
2573
2574 v->mvm_state = CMD_STATUS_SUCCESS;
2575 wake_up(&v->mvm_wait);
2576 } else if (ptr[0] == VSS_IMVM_CMD_DETACH_STREAM) {
2577 pr_debug("%s: DETACH_STREAM resp 0x%x\n",
2578 __func__, ptr[1]);
2579
2580 v->mvm_state = CMD_STATUS_SUCCESS;
2581 wake_up(&v->mvm_wait);
2582 } else if (ptr[0] == VSS_ICOMMON_CMD_SET_NETWORK) {
2583 pr_debug("%s: SET_NETWORK resp 0x%x\n",
2584 __func__, ptr[1]);
2585
2586 v->mvm_state = CMD_STATUS_SUCCESS;
2587 wake_up(&v->mvm_wait);
2588 } else if (ptr[0] == VSS_ICOMMON_CMD_SET_VOICE_TIMING) {
2589 pr_debug("%s: SET_VOICE_TIMING resp 0x%x\n",
2590 __func__, ptr[1]);
2591
2592 v->mvm_state = CMD_STATUS_SUCCESS;
2593 wake_up(&v->mvm_wait);
2594 } else
2595 pr_debug("%s: not match cmd = 0x%x\n",
2596 __func__, ptr[0]);
2597 }
2598 }
2599
2600 return 0;
2601}
2602
2603static int32_t modem_cvs_callback(struct apr_client_data *data, void *priv)
2604{
2605 uint32_t *ptr;
Neema Shetty90189b82011-06-27 14:58:37 -07002606 struct common_data *c = priv;
2607 struct voice_data *v = NULL;
2608 int i = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002609
Neema Shetty90189b82011-06-27 14:58:37 -07002610 pr_debug("%s: session_id 0x%x\n", __func__, data->dest_port);
2611
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002612 if (data->opcode == RESET_EVENTS) {
2613 pr_debug("%s:Reset event received in Voice service\n",
2614 __func__);
Neema Shetty90189b82011-06-27 14:58:37 -07002615 apr_reset(c->apr_cvs);
2616 c->apr_cvs = NULL;
2617 apr_reset(c->apr_q6_cvs);
2618 c->apr_q6_cvs = NULL;
2619
2620 /* Sub-system restart is applicable to all sessions. */
2621 for (i = 0; i < MAX_VOC_SESSIONS; i++)
2622 c->voice[i].cvs_handle = 0;
2623
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002624 return 0;
2625 }
2626
Swaminathan Sathappan71809462011-11-11 13:49:27 -08002627 v = voice_get_session(data->dest_port);
2628 if (v == NULL) {
2629 pr_err("%s: v is NULL\n", __func__);
2630 return -EINVAL;
2631 }
2632
2633 pr_debug("%s: common data 0x%x, session 0x%x\n",
2634 __func__, (unsigned int)c, (unsigned int)v);
2635 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
2636 data->payload_size, data->opcode);
2637
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002638 if (data->opcode == APR_BASIC_RSP_RESULT) {
2639 if (data->payload_size) {
2640 ptr = data->payload;
2641
2642 pr_info("%x %x\n", ptr[0], ptr[1]);
2643 /*response from modem CVS */
2644 if (ptr[0] ==
2645 VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION ||
2646 ptr[0] ==
2647 VSS_ISTREAM_CMD_CREATE_FULL_CONTROL_SESSION) {
2648 if (!ptr[1]) {
2649 pr_debug("%s: CVS handle is %d\n",
2650 __func__, data->src_port);
2651 voice_set_cvs_handle(v, data->src_port);
2652 } else
2653 pr_info("got NACK for sending \
2654 CVS create session \n");
2655 v->cvs_state = CMD_STATUS_SUCCESS;
2656 wake_up(&v->cvs_wait);
2657 } else if (ptr[0] ==
2658 VSS_ISTREAM_CMD_CACHE_CALIBRATION_DATA) {
2659 v->cvs_state = CMD_STATUS_SUCCESS;
2660 wake_up(&v->cvs_wait);
2661 } else if (ptr[0] ==
2662 VSS_ISTREAM_CMD_SET_MUTE) {
2663 v->cvs_state = CMD_STATUS_SUCCESS;
2664 wake_up(&v->cvs_wait);
2665 } else if (ptr[0] == VSS_ISTREAM_CMD_SET_MEDIA_TYPE) {
2666 pr_debug("%s: SET_MEDIA resp 0x%x\n",
2667 __func__, ptr[1]);
2668
2669 v->cvs_state = CMD_STATUS_SUCCESS;
2670 wake_up(&v->cvs_wait);
2671 } else if (ptr[0] ==
2672 VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE) {
2673 pr_debug("%s: SET_AMR_RATE resp 0x%x\n",
2674 __func__, ptr[1]);
2675
2676 v->cvs_state = CMD_STATUS_SUCCESS;
2677 wake_up(&v->cvs_wait);
2678 } else if (ptr[0] ==
2679 VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE) {
2680 pr_debug("%s: SET_AMR_WB_RATE resp 0x%x\n",
2681 __func__, ptr[1]);
2682
2683 v->cvs_state = CMD_STATUS_SUCCESS;
2684 wake_up(&v->cvs_wait);
2685 } else if (ptr[0] == VSS_ISTREAM_CMD_SET_ENC_DTX_MODE) {
2686 pr_debug("%s: SET_DTX resp 0x%x\n",
2687 __func__, ptr[1]);
2688
2689 v->cvs_state = CMD_STATUS_SUCCESS;
2690 wake_up(&v->cvs_wait);
2691 } else if (ptr[0] ==
2692 VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE) {
2693 pr_debug("%s: SET_CDMA_RATE resp 0x%x\n",
2694 __func__, ptr[1]);
2695
2696 v->cvs_state = CMD_STATUS_SUCCESS;
2697 wake_up(&v->cvs_wait);
2698 } else if (ptr[0] == APRV2_IBASIC_CMD_DESTROY_SESSION) {
2699 pr_debug("%s: DESTROY resp\n", __func__);
2700
2701 v->cvs_state = CMD_STATUS_SUCCESS;
2702 wake_up(&v->cvs_wait);
2703 } else if (ptr[0] == VSS_ISTREAM_CMD_START_RECORD) {
2704 pr_debug("%s: START_RECORD resp 0x%x\n",
2705 __func__, ptr[1]);
2706
2707 v->cvs_state = CMD_STATUS_SUCCESS;
2708 wake_up(&v->cvs_wait);
2709 } else if (ptr[0] == VSS_ISTREAM_CMD_STOP_RECORD) {
2710 pr_debug("%s: STOP_RECORD resp 0x%x\n",
2711 __func__, ptr[1]);
2712
2713 v->cvs_state = CMD_STATUS_SUCCESS;
2714 wake_up(&v->cvs_wait);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002715 } else if (ptr[0] == VOICE_CMD_SET_PARAM) {
2716 rtac_make_voice_callback(RTAC_CVS, ptr,
2717 data->payload_size);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002718 } else if (ptr[0] == VSS_ISTREAM_CMD_START_PLAYBACK) {
2719 pr_debug("%s: START_PLAYBACK resp 0x%x\n",
2720 __func__, ptr[1]);
2721
2722 v->cvs_state = CMD_STATUS_SUCCESS;
2723 wake_up(&v->cvs_wait);
2724 } else if (ptr[0] == VSS_ISTREAM_CMD_STOP_PLAYBACK) {
2725 pr_debug("%s: STOP_PLAYBACK resp 0x%x\n",
2726 __func__, ptr[1]);
2727
2728 v->cvs_state = CMD_STATUS_SUCCESS;
2729 wake_up(&v->cvs_wait);
2730 } else
2731 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2732 }
2733 } else if (data->opcode == VSS_ISTREAM_EVT_SEND_ENC_BUFFER) {
2734 uint32_t *voc_pkt = data->payload;
2735 uint32_t pkt_len = data->payload_size;
2736
Neema Shetty90189b82011-06-27 14:58:37 -07002737 if (voc_pkt != NULL && c->mvs_info.ul_cb != NULL) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002738 pr_debug("%s: Media type is 0x%x\n",
2739 __func__, voc_pkt[0]);
2740
2741 /* Remove media ID from payload. */
2742 voc_pkt++;
2743 pkt_len = pkt_len - 4;
2744
Neema Shetty90189b82011-06-27 14:58:37 -07002745 c->mvs_info.ul_cb((uint8_t *)voc_pkt,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002746 pkt_len,
Neema Shetty90189b82011-06-27 14:58:37 -07002747 c->mvs_info.private_data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002748 } else {
2749 pr_err("%s: voc_pkt is 0x%x ul_cb is 0x%x\n",
2750 __func__, (unsigned int)voc_pkt,
Neema Shetty90189b82011-06-27 14:58:37 -07002751 (unsigned int)c->mvs_info.ul_cb);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002752 }
2753 } else if (data->opcode == VSS_ISTREAM_EVT_SEND_DEC_BUFFER) {
2754 pr_debug("%s: Send dec buf resp\n", __func__);
2755 } else if (data->opcode == VSS_ISTREAM_EVT_REQUEST_DEC_BUFFER) {
2756 struct cvs_send_dec_buf_cmd send_dec_buf;
2757 int ret = 0;
2758 uint32_t pkt_len = 0;
2759
Neema Shetty90189b82011-06-27 14:58:37 -07002760 if (c->mvs_info.dl_cb != NULL) {
2761 send_dec_buf.dec_buf.media_id = c->mvs_info.media_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002762
Neema Shetty90189b82011-06-27 14:58:37 -07002763 c->mvs_info.dl_cb(
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002764 (uint8_t *)&send_dec_buf.dec_buf.packet_data,
2765 &pkt_len,
Neema Shetty90189b82011-06-27 14:58:37 -07002766 c->mvs_info.private_data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002767
2768 send_dec_buf.hdr.hdr_field =
2769 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2770 APR_HDR_LEN(APR_HDR_SIZE),
2771 APR_PKT_VER);
2772 send_dec_buf.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2773 sizeof(send_dec_buf.dec_buf.media_id) + pkt_len);
Neema Shetty90189b82011-06-27 14:58:37 -07002774 send_dec_buf.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002775 send_dec_buf.hdr.dest_port = voice_get_cvs_handle(v);
2776 send_dec_buf.hdr.token = 0;
2777 send_dec_buf.hdr.opcode =
2778 VSS_ISTREAM_EVT_SEND_DEC_BUFFER;
2779
Neema Shetty90189b82011-06-27 14:58:37 -07002780 ret = apr_send_pkt(voice_get_apr_cvs(),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002781 (uint32_t *) &send_dec_buf);
2782 if (ret < 0) {
2783 pr_err("%s: Error %d sending DEC_BUF\n",
2784 __func__, ret);
2785 goto fail;
2786 }
2787 } else {
2788 pr_err("%s: ul_cb is NULL\n", __func__);
2789 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002790 } else if (data->opcode == VOICE_EVT_GET_PARAM_ACK) {
2791 rtac_make_voice_callback(RTAC_CVS, data->payload,
2792 data->payload_size);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002793 } else {
2794 pr_debug("%s: Unknown opcode 0x%x\n", __func__, data->opcode);
2795 }
2796
2797fail:
2798 return 0;
2799}
2800
2801static int32_t modem_cvp_callback(struct apr_client_data *data, void *priv)
2802{
2803 uint32_t *ptr;
Neema Shetty90189b82011-06-27 14:58:37 -07002804 struct common_data *c = priv;
2805 struct voice_data *v = NULL;
2806 int i = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002807
Neema Shetty90189b82011-06-27 14:58:37 -07002808 pr_debug("%s: session_id 0x%x\n", __func__, data->dest_port);
2809
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002810 if (data->opcode == RESET_EVENTS) {
2811 pr_debug("%s:Reset event received in Voice service\n",
2812 __func__);
Neema Shetty90189b82011-06-27 14:58:37 -07002813 apr_reset(c->apr_cvp);
2814 c->apr_cvp = NULL;
2815 apr_reset(c->apr_q6_cvp);
2816 c->apr_q6_cvp = NULL;
2817
2818 /* Sub-system restart is applicable to all sessions. */
2819 for (i = 0; i < MAX_VOC_SESSIONS; i++)
2820 c->voice[i].cvp_handle = 0;
2821
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002822 return 0;
2823 }
2824
Swaminathan Sathappan71809462011-11-11 13:49:27 -08002825 v = voice_get_session(data->dest_port);
2826 if (v == NULL) {
2827 pr_err("%s: v is NULL\n", __func__);
2828 return -EINVAL;
2829 }
2830
2831 pr_debug("%s: common data 0x%x, session 0x%x\n",
2832 __func__, (unsigned int)c, (unsigned int)v);
2833 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
2834 data->payload_size, data->opcode);
2835
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002836 if (data->opcode == APR_BASIC_RSP_RESULT) {
2837 if (data->payload_size) {
2838 ptr = data->payload;
2839
2840 pr_info("%x %x\n", ptr[0], ptr[1]);
2841 /*response from modem CVP */
2842 if (ptr[0] ==
2843 VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION) {
2844 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2845 if (!ptr[1]) {
2846 voice_set_cvp_handle(v, data->src_port);
2847 pr_debug("cvphdl=%d\n", data->src_port);
2848 } else
2849 pr_info("got NACK from CVP create \
2850 session response\n");
2851 v->cvp_state = CMD_STATUS_SUCCESS;
2852 wake_up(&v->cvp_wait);
2853 } else if (ptr[0] ==
2854 VSS_IVOCPROC_CMD_CACHE_CALIBRATION_DATA) {
2855 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2856 v->cvp_state = CMD_STATUS_SUCCESS;
2857 wake_up(&v->cvp_wait);
2858 } else if (ptr[0] == VSS_IVOCPROC_CMD_SET_DEVICE) {
2859 v->cvp_state = CMD_STATUS_SUCCESS;
2860 wake_up(&v->cvp_wait);
2861 } else if (ptr[0] ==
2862 VSS_IVOCPROC_CMD_SET_RX_VOLUME_INDEX) {
2863 v->cvp_state = CMD_STATUS_SUCCESS;
2864 wake_up(&v->cvp_wait);
2865 } else if (ptr[0] == VSS_IVOCPROC_CMD_ENABLE) {
2866 v->cvp_state = CMD_STATUS_SUCCESS;
2867 wake_up(&v->cvp_wait);
2868 } else if (ptr[0] == VSS_IVOCPROC_CMD_DISABLE) {
2869 v->cvp_state = CMD_STATUS_SUCCESS;
2870 wake_up(&v->cvp_wait);
2871 } else if (ptr[0] == APRV2_IBASIC_CMD_DESTROY_SESSION) {
2872 v->cvp_state = CMD_STATUS_SUCCESS;
2873 wake_up(&v->cvp_wait);
2874 } else if (ptr[0] ==
2875 VSS_IVOCPROC_CMD_CACHE_VOLUME_CALIBRATION_TABLE
2876 ) {
2877
2878 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2879 v->cvp_state = CMD_STATUS_SUCCESS;
2880 wake_up(&v->cvp_wait);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002881 } else if (ptr[0] == VOICE_CMD_SET_PARAM) {
2882 rtac_make_voice_callback(RTAC_CVP, ptr,
2883 data->payload_size);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002884 } else
2885 pr_debug("%s: not match cmd = 0x%x\n",
2886 __func__, ptr[0]);
2887 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002888 } else if (data->opcode == VOICE_EVT_GET_PARAM_ACK) {
2889 rtac_make_voice_callback(RTAC_CVP, data->payload,
2890 data->payload_size);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002891 }
2892 return 0;
2893}
2894
2895
2896static int __init voice_init(void)
2897{
Neema Shetty90189b82011-06-27 14:58:37 -07002898 int rc = 0, i = 0;
2899
2900 memset(&common, 0, sizeof(struct common_data));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002901
2902 /* set default value */
Neema Shetty90189b82011-06-27 14:58:37 -07002903 common.default_mute_val = 1; /* default is mute */
2904 common.default_vol_val = 0;
2905 common.default_sample_val = 8000;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002906
Neema Shetty90189b82011-06-27 14:58:37 -07002907 common.voc_path = VOC_PATH_PASSIVE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002908
2909 /* Initialize MVS info. */
Neema Shetty90189b82011-06-27 14:58:37 -07002910 common.mvs_info.network_type = VSS_NETWORK_ID_DEFAULT;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002911
Neema Shetty90189b82011-06-27 14:58:37 -07002912 mutex_init(&common.common_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002913
Neema Shetty90189b82011-06-27 14:58:37 -07002914 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
2915 common.voice[i].session_id = SESSION_ID_BASE + i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002916
Neema Shetty90189b82011-06-27 14:58:37 -07002917 common.voice[i].dev_rx.volume = common.default_vol_val;
2918 common.voice[i].dev_tx.mute = common.default_mute_val;
2919
2920 common.voice[i].voc_state = VOC_INIT;
2921
2922 common.voice[i].rec_info.rec_mode = VOC_REC_NONE;
2923
2924 init_waitqueue_head(&common.voice[i].mvm_wait);
2925 init_waitqueue_head(&common.voice[i].cvs_wait);
2926 init_waitqueue_head(&common.voice[i].cvp_wait);
2927
2928 mutex_init(&common.voice[i].lock);
2929
2930 }
2931
2932 common.device_events = AUDDEV_EVT_DEV_CHG_VOICE |
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002933 AUDDEV_EVT_DEV_RDY |
2934 AUDDEV_EVT_REL_PENDING |
2935 AUDDEV_EVT_START_VOICE |
2936 AUDDEV_EVT_END_VOICE |
2937 AUDDEV_EVT_DEVICE_VOL_MUTE_CHG |
2938 AUDDEV_EVT_FREQ_CHG;
2939
2940 pr_debug("to register call back\n");
2941 /* register callback to auddev */
Neema Shetty90189b82011-06-27 14:58:37 -07002942 auddev_register_evt_listner(common.device_events, AUDDEV_CLNT_VOC,
2943 0, voice_auddev_cb_function, &common);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002944
2945 return rc;
2946}
2947
2948device_initcall(voice_init);