blob: 0376f34a1519a69a1d3652bf707bb3676fcb7501 [file] [log] [blame]
Helen Zeng4e531942011-12-17 21:14:40 -08001/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12#include <linux/slab.h>
13#include <linux/kthread.h>
14#include <linux/kernel.h>
15#include <linux/module.h>
16#include <linux/uaccess.h>
17#include <linux/wait.h>
18#include <linux/mutex.h>
Ben Romberger13b74ab2011-07-18 17:36:32 -070019
Swaminathan Sathappan2fea0da2011-12-21 12:20:53 -080020#include <asm/mach-types.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070021#include <mach/qdsp6v2/audio_acdb.h>
Ben Romberger13b74ab2011-07-18 17:36:32 -070022#include <mach/qdsp6v2/rtac.h>
23
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070024#include "sound/apr_audio.h"
25#include "sound/q6afe.h"
Ben Romberger13b74ab2011-07-18 17:36:32 -070026
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070027#include "q6voice.h"
28
29#define TIMEOUT_MS 3000
30
31#define CMD_STATUS_SUCCESS 0
32#define CMD_STATUS_FAIL 1
33
34#define VOC_PATH_PASSIVE 0
35#define VOC_PATH_FULL 1
36
Neema Shetty2c07eb52011-08-21 20:33:52 -070037static struct common_data common;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070038
39static int voice_send_enable_vocproc_cmd(struct voice_data *v);
40static int voice_send_netid_timing_cmd(struct voice_data *v);
41static int voice_send_attach_vocproc_cmd(struct voice_data *v);
42static int voice_send_set_device_cmd(struct voice_data *v);
43static int voice_send_disable_vocproc_cmd(struct voice_data *v);
44static int voice_send_vol_index_cmd(struct voice_data *v);
Helen Zeng29eb7442011-06-20 11:06:29 -070045static int voice_send_cvp_map_memory_cmd(struct voice_data *v);
46static int voice_send_cvp_unmap_memory_cmd(struct voice_data *v);
47static int voice_send_cvs_map_memory_cmd(struct voice_data *v);
48static int voice_send_cvs_unmap_memory_cmd(struct voice_data *v);
49static int voice_send_cvs_register_cal_cmd(struct voice_data *v);
50static int voice_send_cvs_deregister_cal_cmd(struct voice_data *v);
51static int voice_send_cvp_register_cal_cmd(struct voice_data *v);
52static int voice_send_cvp_deregister_cal_cmd(struct voice_data *v);
53static int voice_send_cvp_register_vol_cal_table_cmd(struct voice_data *v);
54static int voice_send_cvp_deregister_vol_cal_table_cmd(struct voice_data *v);
Helen Zeng44d4d272011-08-10 14:49:20 -070055static int voice_send_set_widevoice_enable_cmd(struct voice_data *v);
Helen Zeng4e531942011-12-17 21:14:40 -080056static int voice_send_set_pp_enable_cmd(struct voice_data *v,
57 uint32_t module_id, int enable);
Helen Zeng0705a5f2011-10-14 15:29:52 -070058static int voice_cvs_stop_playback(struct voice_data *v);
59static int voice_cvs_start_playback(struct voice_data *v);
Helen Zenge3d716a2011-10-14 16:32:16 -070060static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode);
61static int voice_cvs_stop_record(struct voice_data *v);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070062
63static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv);
64static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv);
65static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv);
66
67static u16 voice_get_mvm_handle(struct voice_data *v)
68{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070069 if (v == NULL) {
70 pr_err("%s: v is NULL\n", __func__);
Neema Shetty2c07eb52011-08-21 20:33:52 -070071 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070072 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070073
Neema Shetty2c07eb52011-08-21 20:33:52 -070074 pr_debug("%s: mvm_handle %d\n", __func__, v->mvm_handle);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070075
Neema Shetty2c07eb52011-08-21 20:33:52 -070076 return v->mvm_handle;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070077}
78
79static void voice_set_mvm_handle(struct voice_data *v, u16 mvm_handle)
80{
81 pr_debug("%s: mvm_handle %d\n", __func__, mvm_handle);
82 if (v == NULL) {
83 pr_err("%s: v is NULL\n", __func__);
84 return;
85 }
86
Neema Shetty2c07eb52011-08-21 20:33:52 -070087 v->mvm_handle = mvm_handle;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070088}
89
90static u16 voice_get_cvs_handle(struct voice_data *v)
91{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070092 if (v == NULL) {
93 pr_err("%s: v is NULL\n", __func__);
Neema Shetty2c07eb52011-08-21 20:33:52 -070094 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070095 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070096
Neema Shetty2c07eb52011-08-21 20:33:52 -070097 pr_debug("%s: cvs_handle %d\n", __func__, v->cvs_handle);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070098
Neema Shetty2c07eb52011-08-21 20:33:52 -070099 return v->cvs_handle;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700100}
101
102static void voice_set_cvs_handle(struct voice_data *v, u16 cvs_handle)
103{
104 pr_debug("%s: cvs_handle %d\n", __func__, cvs_handle);
105 if (v == NULL) {
106 pr_err("%s: v is NULL\n", __func__);
107 return;
108 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700109
110 v->cvs_handle = cvs_handle;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700111}
112
113static u16 voice_get_cvp_handle(struct voice_data *v)
114{
Neema Shetty2c07eb52011-08-21 20:33:52 -0700115 if (v == NULL) {
116 pr_err("%s: v is NULL\n", __func__);
117 return 0;
118 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700119
Neema Shetty2c07eb52011-08-21 20:33:52 -0700120 pr_debug("%s: cvp_handle %d\n", __func__, v->cvp_handle);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700121
Neema Shetty2c07eb52011-08-21 20:33:52 -0700122 return v->cvp_handle;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700123}
124
125static void voice_set_cvp_handle(struct voice_data *v, u16 cvp_handle)
126{
127 pr_debug("%s: cvp_handle %d\n", __func__, cvp_handle);
128 if (v == NULL) {
129 pr_err("%s: v is NULL\n", __func__);
130 return;
131 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700132
133 v->cvp_handle = cvp_handle;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700134}
135
Neema Shetty2c07eb52011-08-21 20:33:52 -0700136uint16_t voc_get_session_id(char *name)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700137{
Neema Shetty2c07eb52011-08-21 20:33:52 -0700138 u16 session_id = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700139
Neema Shetty2c07eb52011-08-21 20:33:52 -0700140 if (name != NULL) {
141 if (!strncmp(name, "Voice session", 13))
142 session_id = common.voice[VOC_PATH_PASSIVE].session_id;
143 else
144 session_id = common.voice[VOC_PATH_FULL].session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700145
Helen Zeng0f4c4e22011-09-29 14:25:43 -0700146 pr_debug("%s: %s has session id 0x%x\n", __func__, name,
147 session_id);
148 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700149
150 return session_id;
151}
152
153static struct voice_data *voice_get_session(u16 session_id)
154{
155 struct voice_data *v = NULL;
156
157 if ((session_id >= SESSION_ID_BASE) &&
158 (session_id < SESSION_ID_BASE + MAX_VOC_SESSIONS)) {
159 v = &common.voice[session_id - SESSION_ID_BASE];
160 }
161
162 pr_debug("%s: session_id 0x%x session handle 0x%x\n",
163 __func__, session_id, (unsigned int)v);
164
165 return v;
166}
167
168static bool is_voice_session(u16 session_id)
169{
170 return (session_id == common.voice[VOC_PATH_PASSIVE].session_id);
171}
172
173static bool is_voip_session(u16 session_id)
174{
175 return (session_id == common.voice[VOC_PATH_FULL].session_id);
176}
177
178static int voice_apr_register(void)
179{
180 pr_debug("%s\n", __func__);
181
182 mutex_lock(&common.common_lock);
183
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700184 /* register callback to APR */
Neema Shetty2c07eb52011-08-21 20:33:52 -0700185 if (common.apr_q6_mvm == NULL) {
186 pr_debug("%s: Start to register MVM callback\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700187
Neema Shetty2c07eb52011-08-21 20:33:52 -0700188 common.apr_q6_mvm = apr_register("ADSP", "MVM",
189 qdsp_mvm_callback,
190 0xFFFFFFFF, &common);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700191
Neema Shetty2c07eb52011-08-21 20:33:52 -0700192 if (common.apr_q6_mvm == NULL) {
193 pr_err("%s: Unable to register MVM\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700194 goto err;
195 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700196 }
197
Neema Shetty2c07eb52011-08-21 20:33:52 -0700198 if (common.apr_q6_cvs == NULL) {
199 pr_debug("%s: Start to register CVS callback\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700200
Neema Shetty2c07eb52011-08-21 20:33:52 -0700201 common.apr_q6_cvs = apr_register("ADSP", "CVS",
202 qdsp_cvs_callback,
203 0xFFFFFFFF, &common);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700204
Neema Shetty2c07eb52011-08-21 20:33:52 -0700205 if (common.apr_q6_cvs == NULL) {
206 pr_err("%s: Unable to register CVS\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700207 goto err;
208 }
Ben Romberger13b74ab2011-07-18 17:36:32 -0700209
Neema Shetty2c07eb52011-08-21 20:33:52 -0700210 rtac_set_voice_handle(RTAC_CVS, common.apr_q6_cvs);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700211 }
212
Neema Shetty2c07eb52011-08-21 20:33:52 -0700213 if (common.apr_q6_cvp == NULL) {
214 pr_debug("%s: Start to register CVP callback\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700215
Neema Shetty2c07eb52011-08-21 20:33:52 -0700216 common.apr_q6_cvp = apr_register("ADSP", "CVP",
217 qdsp_cvp_callback,
218 0xFFFFFFFF, &common);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700219
Neema Shetty2c07eb52011-08-21 20:33:52 -0700220 if (common.apr_q6_cvp == NULL) {
221 pr_err("%s: Unable to register CVP\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700222 goto err;
223 }
Ben Romberger13b74ab2011-07-18 17:36:32 -0700224
Neema Shetty2c07eb52011-08-21 20:33:52 -0700225 rtac_set_voice_handle(RTAC_CVP, common.apr_q6_cvp);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700226 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700227
228 mutex_unlock(&common.common_lock);
229
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700230 return 0;
231
232err:
Neema Shetty2c07eb52011-08-21 20:33:52 -0700233 if (common.apr_q6_cvs != NULL) {
234 apr_deregister(common.apr_q6_cvs);
235 common.apr_q6_cvs = NULL;
Ben Romberger13b74ab2011-07-18 17:36:32 -0700236 rtac_set_voice_handle(RTAC_CVS, NULL);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700237 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700238 if (common.apr_q6_mvm != NULL) {
239 apr_deregister(common.apr_q6_mvm);
240 common.apr_q6_mvm = NULL;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700241 }
242
Neema Shetty2c07eb52011-08-21 20:33:52 -0700243 mutex_unlock(&common.common_lock);
244
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700245 return -ENODEV;
246}
247
248static int voice_create_mvm_cvs_session(struct voice_data *v)
249{
250 int ret = 0;
Helen Zeng69b00962011-07-08 11:38:36 -0700251 struct mvm_create_ctl_session_cmd mvm_session_cmd;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700252 struct cvs_create_passive_ctl_session_cmd cvs_session_cmd;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700253 struct cvs_create_full_ctl_session_cmd cvs_full_ctl_cmd;
254 struct mvm_attach_stream_cmd attach_stream_cmd;
255 void *apr_mvm, *apr_cvs, *apr_cvp;
256 u16 mvm_handle, cvs_handle, cvp_handle;
257
258 if (v == NULL) {
259 pr_err("%s: v is NULL\n", __func__);
260 return -EINVAL;
261 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700262 apr_mvm = common.apr_q6_mvm;
263 apr_cvs = common.apr_q6_cvs;
264 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700265
266 if (!apr_mvm || !apr_cvs || !apr_cvp) {
267 pr_err("%s: apr_mvm or apr_cvs or apr_cvp is NULL\n", __func__);
268 return -EINVAL;
269 }
270 mvm_handle = voice_get_mvm_handle(v);
271 cvs_handle = voice_get_cvs_handle(v);
272 cvp_handle = voice_get_cvp_handle(v);
273
274 pr_debug("%s: mvm_hdl=%d, cvs_hdl=%d\n", __func__,
275 mvm_handle, cvs_handle);
276 /* send cmd to create mvm session and wait for response */
277
278 if (!mvm_handle) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700279 if (is_voice_session(v->session_id)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700280 mvm_session_cmd.hdr.hdr_field = APR_HDR_FIELD(
281 APR_MSG_TYPE_SEQ_CMD,
282 APR_HDR_LEN(APR_HDR_SIZE),
283 APR_PKT_VER);
284 mvm_session_cmd.hdr.pkt_size = APR_PKT_SIZE(
285 APR_HDR_SIZE,
286 sizeof(mvm_session_cmd) -
287 APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700288 pr_debug("%s: send mvm create session pkt size = %d\n",
289 __func__, mvm_session_cmd.hdr.pkt_size);
290 mvm_session_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700291 mvm_session_cmd.hdr.dest_port = 0;
292 mvm_session_cmd.hdr.token = 0;
293 mvm_session_cmd.hdr.opcode =
294 VSS_IMVM_CMD_CREATE_PASSIVE_CONTROL_SESSION;
Neema Shetty9ba987d2011-10-25 18:14:50 -0700295 strlcpy(mvm_session_cmd.mvm_session.name,
296 "default modem voice",
297 sizeof(mvm_session_cmd.mvm_session.name));
Helen Zeng69b00962011-07-08 11:38:36 -0700298
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700299 v->mvm_state = CMD_STATUS_FAIL;
300
301 ret = apr_send_pkt(apr_mvm,
302 (uint32_t *) &mvm_session_cmd);
303 if (ret < 0) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700304 pr_err("%s: Error sending MVM_CONTROL_SESSION\n",
305 __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700306 goto fail;
307 }
308 ret = wait_event_timeout(v->mvm_wait,
309 (v->mvm_state == CMD_STATUS_SUCCESS),
310 msecs_to_jiffies(TIMEOUT_MS));
311 if (!ret) {
312 pr_err("%s: wait_event timeout\n", __func__);
313 goto fail;
314 }
315 } else {
316 pr_debug("%s: creating MVM full ctrl\n", __func__);
Helen Zeng69b00962011-07-08 11:38:36 -0700317 mvm_session_cmd.hdr.hdr_field =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700318 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
319 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
Helen Zeng69b00962011-07-08 11:38:36 -0700320 mvm_session_cmd.hdr.pkt_size =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700321 APR_PKT_SIZE(APR_HDR_SIZE,
Helen Zeng69b00962011-07-08 11:38:36 -0700322 sizeof(mvm_session_cmd) -
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700323 APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700324 mvm_session_cmd.hdr.src_port = v->session_id;
Helen Zeng69b00962011-07-08 11:38:36 -0700325 mvm_session_cmd.hdr.dest_port = 0;
326 mvm_session_cmd.hdr.token = 0;
327 mvm_session_cmd.hdr.opcode =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700328 VSS_IMVM_CMD_CREATE_FULL_CONTROL_SESSION;
Neema Shetty9ba987d2011-10-25 18:14:50 -0700329 strlcpy(mvm_session_cmd.mvm_session.name,
330 "default voip",
331 sizeof(mvm_session_cmd.mvm_session.name));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700332
333 v->mvm_state = CMD_STATUS_FAIL;
334
335 ret = apr_send_pkt(apr_mvm,
Helen Zeng69b00962011-07-08 11:38:36 -0700336 (uint32_t *) &mvm_session_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700337 if (ret < 0) {
338 pr_err("Fail in sending MVM_CONTROL_SESSION\n");
339 goto fail;
340 }
341 ret = wait_event_timeout(v->mvm_wait,
342 (v->mvm_state == CMD_STATUS_SUCCESS),
343 msecs_to_jiffies(TIMEOUT_MS));
344 if (!ret) {
345 pr_err("%s: wait_event timeout\n", __func__);
346 goto fail;
347 }
348 }
349 /* Get the created MVM handle. */
350 mvm_handle = voice_get_mvm_handle(v);
351 }
352 /* send cmd to create cvs session */
353 if (!cvs_handle) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700354 if (is_voice_session(v->session_id)) {
355 pr_debug("%s: creating CVS passive session\n",
356 __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700357
358 cvs_session_cmd.hdr.hdr_field = APR_HDR_FIELD(
359 APR_MSG_TYPE_SEQ_CMD,
360 APR_HDR_LEN(APR_HDR_SIZE),
361 APR_PKT_VER);
362 cvs_session_cmd.hdr.pkt_size =
363 APR_PKT_SIZE(APR_HDR_SIZE,
364 sizeof(cvs_session_cmd) -
365 APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700366 cvs_session_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700367 cvs_session_cmd.hdr.dest_port = 0;
368 cvs_session_cmd.hdr.token = 0;
369 cvs_session_cmd.hdr.opcode =
370 VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION;
Neema Shetty9ba987d2011-10-25 18:14:50 -0700371 strlcpy(cvs_session_cmd.cvs_session.name,
372 "default modem voice",
373 sizeof(cvs_session_cmd.cvs_session.name));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700374
375 v->cvs_state = CMD_STATUS_FAIL;
376
377 ret = apr_send_pkt(apr_cvs,
378 (uint32_t *) &cvs_session_cmd);
379 if (ret < 0) {
380 pr_err("Fail in sending STREAM_CONTROL_SESSION\n");
381 goto fail;
382 }
383 ret = wait_event_timeout(v->cvs_wait,
384 (v->cvs_state == CMD_STATUS_SUCCESS),
385 msecs_to_jiffies(TIMEOUT_MS));
386 if (!ret) {
387 pr_err("%s: wait_event timeout\n", __func__);
388 goto fail;
389 }
390 /* Get the created CVS handle. */
391 cvs_handle = voice_get_cvs_handle(v);
392
393 } else {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700394 pr_debug("%s: creating CVS full session\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700395
396 cvs_full_ctl_cmd.hdr.hdr_field =
397 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
398 APR_HDR_LEN(APR_HDR_SIZE),
399 APR_PKT_VER);
400
401 cvs_full_ctl_cmd.hdr.pkt_size =
402 APR_PKT_SIZE(APR_HDR_SIZE,
403 sizeof(cvs_full_ctl_cmd) -
404 APR_HDR_SIZE);
405
Neema Shetty2c07eb52011-08-21 20:33:52 -0700406 cvs_full_ctl_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700407 cvs_full_ctl_cmd.hdr.dest_port = 0;
408 cvs_full_ctl_cmd.hdr.token = 0;
409 cvs_full_ctl_cmd.hdr.opcode =
410 VSS_ISTREAM_CMD_CREATE_FULL_CONTROL_SESSION;
411 cvs_full_ctl_cmd.cvs_session.direction = 2;
412 cvs_full_ctl_cmd.cvs_session.enc_media_type =
Neema Shetty2c07eb52011-08-21 20:33:52 -0700413 common.mvs_info.media_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700414 cvs_full_ctl_cmd.cvs_session.dec_media_type =
Neema Shetty2c07eb52011-08-21 20:33:52 -0700415 common.mvs_info.media_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700416 cvs_full_ctl_cmd.cvs_session.network_id =
Neema Shetty2c07eb52011-08-21 20:33:52 -0700417 common.mvs_info.network_type;
Neema Shetty9ba987d2011-10-25 18:14:50 -0700418 strlcpy(cvs_full_ctl_cmd.cvs_session.name,
419 "default q6 voice",
420 sizeof(cvs_full_ctl_cmd.cvs_session.name));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700421
422 v->cvs_state = CMD_STATUS_FAIL;
423
424 ret = apr_send_pkt(apr_cvs,
425 (uint32_t *) &cvs_full_ctl_cmd);
426
427 if (ret < 0) {
428 pr_err("%s: Err %d sending CREATE_FULL_CTRL\n",
429 __func__, ret);
430 goto fail;
431 }
432 ret = wait_event_timeout(v->cvs_wait,
433 (v->cvs_state == CMD_STATUS_SUCCESS),
434 msecs_to_jiffies(TIMEOUT_MS));
435 if (!ret) {
436 pr_err("%s: wait_event timeout\n", __func__);
437 goto fail;
438 }
439 /* Get the created CVS handle. */
440 cvs_handle = voice_get_cvs_handle(v);
441
442 /* Attach MVM to CVS. */
Neema Shetty2c07eb52011-08-21 20:33:52 -0700443 pr_debug("%s: Attach MVM to stream\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700444
445 attach_stream_cmd.hdr.hdr_field =
446 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
447 APR_HDR_LEN(APR_HDR_SIZE),
448 APR_PKT_VER);
449 attach_stream_cmd.hdr.pkt_size =
450 APR_PKT_SIZE(APR_HDR_SIZE,
451 sizeof(attach_stream_cmd) -
452 APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700453 attach_stream_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700454 attach_stream_cmd.hdr.dest_port = mvm_handle;
455 attach_stream_cmd.hdr.token = 0;
456 attach_stream_cmd.hdr.opcode =
457 VSS_IMVM_CMD_ATTACH_STREAM;
458 attach_stream_cmd.attach_stream.handle = cvs_handle;
459
460 v->mvm_state = CMD_STATUS_FAIL;
461 ret = apr_send_pkt(apr_mvm,
462 (uint32_t *) &attach_stream_cmd);
463 if (ret < 0) {
464 pr_err("%s: Error %d sending ATTACH_STREAM\n",
465 __func__, ret);
466 goto fail;
467 }
468 ret = wait_event_timeout(v->mvm_wait,
469 (v->mvm_state == CMD_STATUS_SUCCESS),
470 msecs_to_jiffies(TIMEOUT_MS));
471 if (!ret) {
472 pr_err("%s: wait_event timeout\n", __func__);
473 goto fail;
474 }
475 }
476 }
477 return 0;
478
479fail:
480 return -EINVAL;
481}
482
483static int voice_destroy_mvm_cvs_session(struct voice_data *v)
484{
485 int ret = 0;
486 struct mvm_detach_stream_cmd detach_stream;
487 struct apr_hdr mvm_destroy;
488 struct apr_hdr cvs_destroy;
489 void *apr_mvm, *apr_cvs;
490 u16 mvm_handle, cvs_handle;
491
492 if (v == NULL) {
493 pr_err("%s: v is NULL\n", __func__);
494 return -EINVAL;
495 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700496 apr_mvm = common.apr_q6_mvm;
497 apr_cvs = common.apr_q6_cvs;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700498
499 if (!apr_mvm || !apr_cvs) {
500 pr_err("%s: apr_mvm or apr_cvs is NULL\n", __func__);
501 return -EINVAL;
502 }
503 mvm_handle = voice_get_mvm_handle(v);
504 cvs_handle = voice_get_cvs_handle(v);
505
506 /* MVM, CVS sessions are destroyed only for Full control sessions. */
Neema Shetty2c07eb52011-08-21 20:33:52 -0700507 if (is_voip_session(v->session_id)) {
508 pr_debug("%s: MVM detach stream\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700509
510 /* Detach voice stream. */
511 detach_stream.hdr.hdr_field =
512 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
513 APR_HDR_LEN(APR_HDR_SIZE),
514 APR_PKT_VER);
515 detach_stream.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
516 sizeof(detach_stream) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700517 detach_stream.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700518 detach_stream.hdr.dest_port = mvm_handle;
519 detach_stream.hdr.token = 0;
520 detach_stream.hdr.opcode = VSS_IMVM_CMD_DETACH_STREAM;
521 detach_stream.detach_stream.handle = cvs_handle;
522
523 v->mvm_state = CMD_STATUS_FAIL;
524
525 ret = apr_send_pkt(apr_mvm, (uint32_t *) &detach_stream);
526 if (ret < 0) {
527 pr_err("%s: Error %d sending DETACH_STREAM\n",
528 __func__, ret);
529 goto fail;
530 }
531 ret = wait_event_timeout(v->mvm_wait,
532 (v->mvm_state == CMD_STATUS_SUCCESS),
533 msecs_to_jiffies(TIMEOUT_MS));
534 if (!ret) {
535 pr_err("%s: wait event timeout\n", __func__);
536 goto fail;
537 }
538 /* Destroy CVS. */
Neema Shetty2c07eb52011-08-21 20:33:52 -0700539 pr_debug("%s: CVS destroy session\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700540
541 cvs_destroy.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
542 APR_HDR_LEN(APR_HDR_SIZE),
543 APR_PKT_VER);
544 cvs_destroy.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
545 sizeof(cvs_destroy) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700546 cvs_destroy.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700547 cvs_destroy.dest_port = cvs_handle;
548 cvs_destroy.token = 0;
549 cvs_destroy.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
550
551 v->cvs_state = CMD_STATUS_FAIL;
552
553 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_destroy);
554 if (ret < 0) {
555 pr_err("%s: Error %d sending CVS DESTROY\n",
556 __func__, ret);
557 goto fail;
558 }
559 ret = wait_event_timeout(v->cvs_wait,
560 (v->cvs_state == CMD_STATUS_SUCCESS),
561 msecs_to_jiffies(TIMEOUT_MS));
562 if (!ret) {
563 pr_err("%s: wait event timeout\n", __func__);
564
565 goto fail;
566 }
567 cvs_handle = 0;
568 voice_set_cvs_handle(v, cvs_handle);
569
570 /* Destroy MVM. */
571 pr_debug("MVM destroy session\n");
572
573 mvm_destroy.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
574 APR_HDR_LEN(APR_HDR_SIZE),
575 APR_PKT_VER);
576 mvm_destroy.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
577 sizeof(mvm_destroy) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700578 mvm_destroy.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700579 mvm_destroy.dest_port = mvm_handle;
580 mvm_destroy.token = 0;
581 mvm_destroy.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
582
583 v->mvm_state = CMD_STATUS_FAIL;
584
585 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_destroy);
586 if (ret < 0) {
587 pr_err("%s: Error %d sending MVM DESTROY\n",
588 __func__, ret);
589
590 goto fail;
591 }
592 ret = wait_event_timeout(v->mvm_wait,
593 (v->mvm_state == CMD_STATUS_SUCCESS),
594 msecs_to_jiffies(TIMEOUT_MS));
595 if (!ret) {
596 pr_err("%s: wait event timeout\n", __func__);
597
598 goto fail;
599 }
600 mvm_handle = 0;
601 voice_set_mvm_handle(v, mvm_handle);
602 }
603 return 0;
604fail:
605 return -EINVAL;
606}
607
608static int voice_send_tty_mode_cmd(struct voice_data *v)
609{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700610 int ret = 0;
611 struct mvm_set_tty_mode_cmd mvm_tty_mode_cmd;
612 void *apr_mvm;
613 u16 mvm_handle;
614
615 if (v == NULL) {
616 pr_err("%s: v is NULL\n", __func__);
617 return -EINVAL;
618 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700619 apr_mvm = common.apr_q6_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700620
621 if (!apr_mvm) {
622 pr_err("%s: apr_mvm is NULL.\n", __func__);
623 return -EINVAL;
624 }
625 mvm_handle = voice_get_mvm_handle(v);
626
Helen Zengcc65b5b2011-07-06 19:14:48 -0700627 if (v->tty_mode) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700628 /* send tty mode cmd to mvm */
629 mvm_tty_mode_cmd.hdr.hdr_field = APR_HDR_FIELD(
630 APR_MSG_TYPE_SEQ_CMD,
631 APR_HDR_LEN(APR_HDR_SIZE),
632 APR_PKT_VER);
633 mvm_tty_mode_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
634 sizeof(mvm_tty_mode_cmd) -
635 APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700636 pr_debug("%s: pkt size = %d\n",
637 __func__, mvm_tty_mode_cmd.hdr.pkt_size);
638 mvm_tty_mode_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700639 mvm_tty_mode_cmd.hdr.dest_port = mvm_handle;
640 mvm_tty_mode_cmd.hdr.token = 0;
641 mvm_tty_mode_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_TTY_MODE;
Helen Zengcc65b5b2011-07-06 19:14:48 -0700642 mvm_tty_mode_cmd.tty_mode.mode = v->tty_mode;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700643 pr_debug("tty mode =%d\n", mvm_tty_mode_cmd.tty_mode.mode);
644
645 v->mvm_state = CMD_STATUS_FAIL;
646 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_tty_mode_cmd);
647 if (ret < 0) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700648 pr_err("%s: Error %d sending SET_TTY_MODE\n",
649 __func__, ret);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700650 goto fail;
651 }
652 ret = wait_event_timeout(v->mvm_wait,
653 (v->mvm_state == CMD_STATUS_SUCCESS),
654 msecs_to_jiffies(TIMEOUT_MS));
655 if (!ret) {
656 pr_err("%s: wait_event timeout\n", __func__);
657 goto fail;
658 }
659 }
660 return 0;
661fail:
662 return -EINVAL;
663}
664
Helen Zengff97bec2012-02-20 14:30:50 -0800665static int voice_set_dtx(struct voice_data *v)
666{
667 int ret = 0;
668 void *apr_cvs;
669 u16 cvs_handle;
670 struct cvs_set_enc_dtx_mode_cmd cvs_set_dtx;
671
672 if (v == NULL) {
673 pr_err("%s: v is NULL\n", __func__);
674 return -EINVAL;
675 }
676 apr_cvs = common.apr_q6_cvs;
677
678 if (!apr_cvs) {
679 pr_err("%s: apr_cvs is NULL.\n", __func__);
680 return -EINVAL;
681 }
682
683 cvs_handle = voice_get_cvs_handle(v);
684
685 /* Set DTX */
686 cvs_set_dtx.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
687 APR_HDR_LEN(APR_HDR_SIZE),
688 APR_PKT_VER);
689 cvs_set_dtx.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
690 sizeof(cvs_set_dtx) - APR_HDR_SIZE);
691 cvs_set_dtx.hdr.src_port = v->session_id;
692 cvs_set_dtx.hdr.dest_port = cvs_handle;
693 cvs_set_dtx.hdr.token = 0;
694 cvs_set_dtx.hdr.opcode = VSS_ISTREAM_CMD_SET_ENC_DTX_MODE;
695 cvs_set_dtx.dtx_mode.enable = common.mvs_info.dtx_mode;
696
697 pr_debug("%s: Setting DTX %d\n", __func__, common.mvs_info.dtx_mode);
698
699 v->cvs_state = CMD_STATUS_FAIL;
700
701 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_dtx);
702 if (ret < 0) {
703 pr_err("%s: Error %d sending SET_DTX\n", __func__, ret);
704 return -EINVAL;
705 }
706
707 ret = wait_event_timeout(v->cvs_wait,
708 (v->cvs_state == CMD_STATUS_SUCCESS),
709 msecs_to_jiffies(TIMEOUT_MS));
710 if (!ret) {
711 pr_err("%s: wait_event timeout\n", __func__);
712 return -EINVAL;
713 }
714
715 return 0;
716}
717
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700718static int voice_config_cvs_vocoder(struct voice_data *v)
719{
720 int ret = 0;
721 void *apr_cvs;
722 u16 cvs_handle;
723 /* Set media type. */
724 struct cvs_set_media_type_cmd cvs_set_media_cmd;
725
726 if (v == NULL) {
727 pr_err("%s: v is NULL\n", __func__);
728 return -EINVAL;
729 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700730 apr_cvs = common.apr_q6_cvs;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700731
732 if (!apr_cvs) {
733 pr_err("%s: apr_cvs is NULL.\n", __func__);
734 return -EINVAL;
735 }
736
737 cvs_handle = voice_get_cvs_handle(v);
738
739 cvs_set_media_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
740 APR_HDR_LEN(APR_HDR_SIZE),
741 APR_PKT_VER);
742 cvs_set_media_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
743 sizeof(cvs_set_media_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700744 cvs_set_media_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700745 cvs_set_media_cmd.hdr.dest_port = cvs_handle;
746 cvs_set_media_cmd.hdr.token = 0;
747 cvs_set_media_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_MEDIA_TYPE;
Neema Shetty2c07eb52011-08-21 20:33:52 -0700748 cvs_set_media_cmd.media_type.tx_media_id = common.mvs_info.media_type;
749 cvs_set_media_cmd.media_type.rx_media_id = common.mvs_info.media_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700750
751 v->cvs_state = CMD_STATUS_FAIL;
752
753 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_media_cmd);
754 if (ret < 0) {
755 pr_err("%s: Error %d sending SET_MEDIA_TYPE\n",
756 __func__, ret);
757
758 goto fail;
759 }
760 ret = wait_event_timeout(v->cvs_wait,
761 (v->cvs_state == CMD_STATUS_SUCCESS),
762 msecs_to_jiffies(TIMEOUT_MS));
763 if (!ret) {
764 pr_err("%s: wait_event timeout\n", __func__);
765
766 goto fail;
767 }
768 /* Set encoder properties. */
Neema Shetty2c07eb52011-08-21 20:33:52 -0700769 switch (common.mvs_info.media_type) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700770 case VSS_MEDIA_ID_EVRC_MODEM: {
771 struct cvs_set_cdma_enc_minmax_rate_cmd cvs_set_cdma_rate;
772
773 pr_debug("Setting EVRC min-max rate\n");
774
775 cvs_set_cdma_rate.hdr.hdr_field =
776 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
777 APR_HDR_LEN(APR_HDR_SIZE),
778 APR_PKT_VER);
779 cvs_set_cdma_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
780 sizeof(cvs_set_cdma_rate) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700781 cvs_set_cdma_rate.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700782 cvs_set_cdma_rate.hdr.dest_port = cvs_handle;
783 cvs_set_cdma_rate.hdr.token = 0;
784 cvs_set_cdma_rate.hdr.opcode =
785 VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE;
Neema Shetty2c07eb52011-08-21 20:33:52 -0700786 cvs_set_cdma_rate.cdma_rate.min_rate = common.mvs_info.rate;
787 cvs_set_cdma_rate.cdma_rate.max_rate = common.mvs_info.rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700788
789 v->cvs_state = CMD_STATUS_FAIL;
790
791 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_cdma_rate);
792 if (ret < 0) {
793 pr_err("%s: Error %d sending SET_EVRC_MINMAX_RATE\n",
794 __func__, ret);
795 goto fail;
796 }
797 ret = wait_event_timeout(v->cvs_wait,
798 (v->cvs_state == CMD_STATUS_SUCCESS),
799 msecs_to_jiffies(TIMEOUT_MS));
800 if (!ret) {
801 pr_err("%s: wait_event timeout\n", __func__);
802
803 goto fail;
804 }
805 break;
806 }
807 case VSS_MEDIA_ID_AMR_NB_MODEM: {
808 struct cvs_set_amr_enc_rate_cmd cvs_set_amr_rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700809
810 pr_debug("Setting AMR rate\n");
811
812 cvs_set_amr_rate.hdr.hdr_field =
813 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
814 APR_HDR_LEN(APR_HDR_SIZE),
815 APR_PKT_VER);
816 cvs_set_amr_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
817 sizeof(cvs_set_amr_rate) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700818 cvs_set_amr_rate.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700819 cvs_set_amr_rate.hdr.dest_port = cvs_handle;
820 cvs_set_amr_rate.hdr.token = 0;
821 cvs_set_amr_rate.hdr.opcode =
822 VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE;
Neema Shetty2c07eb52011-08-21 20:33:52 -0700823 cvs_set_amr_rate.amr_rate.mode = common.mvs_info.rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700824
825 v->cvs_state = CMD_STATUS_FAIL;
826
827 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_amr_rate);
828 if (ret < 0) {
829 pr_err("%s: Error %d sending SET_AMR_RATE\n",
830 __func__, ret);
831 goto fail;
832 }
833 ret = wait_event_timeout(v->cvs_wait,
834 (v->cvs_state == CMD_STATUS_SUCCESS),
835 msecs_to_jiffies(TIMEOUT_MS));
836 if (!ret) {
837 pr_err("%s: wait_event timeout\n", __func__);
838 goto fail;
839 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700840
Helen Zengff97bec2012-02-20 14:30:50 -0800841 ret = voice_set_dtx(v);
842 if (ret < 0)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700843 goto fail;
Helen Zengff97bec2012-02-20 14:30:50 -0800844
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700845 break;
846 }
847 case VSS_MEDIA_ID_AMR_WB_MODEM: {
848 struct cvs_set_amrwb_enc_rate_cmd cvs_set_amrwb_rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700849
850 pr_debug("Setting AMR WB rate\n");
851
852 cvs_set_amrwb_rate.hdr.hdr_field =
853 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
854 APR_HDR_LEN(APR_HDR_SIZE),
855 APR_PKT_VER);
856 cvs_set_amrwb_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
857 sizeof(cvs_set_amrwb_rate) -
858 APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700859 cvs_set_amrwb_rate.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700860 cvs_set_amrwb_rate.hdr.dest_port = cvs_handle;
861 cvs_set_amrwb_rate.hdr.token = 0;
862 cvs_set_amrwb_rate.hdr.opcode =
863 VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE;
Neema Shetty2c07eb52011-08-21 20:33:52 -0700864 cvs_set_amrwb_rate.amrwb_rate.mode = common.mvs_info.rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700865
866 v->cvs_state = CMD_STATUS_FAIL;
867
868 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_amrwb_rate);
869 if (ret < 0) {
870 pr_err("%s: Error %d sending SET_AMRWB_RATE\n",
871 __func__, ret);
872 goto fail;
873 }
874 ret = wait_event_timeout(v->cvs_wait,
875 (v->cvs_state == CMD_STATUS_SUCCESS),
876 msecs_to_jiffies(TIMEOUT_MS));
877 if (!ret) {
878 pr_err("%s: wait_event timeout\n", __func__);
879 goto fail;
880 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700881
Helen Zengff97bec2012-02-20 14:30:50 -0800882 ret = voice_set_dtx(v);
883 if (ret < 0)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700884 goto fail;
Helen Zengff97bec2012-02-20 14:30:50 -0800885
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700886 break;
887 }
888 case VSS_MEDIA_ID_G729:
889 case VSS_MEDIA_ID_G711_ALAW:
890 case VSS_MEDIA_ID_G711_MULAW: {
Helen Zengff97bec2012-02-20 14:30:50 -0800891 ret = voice_set_dtx(v);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700892
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700893 break;
894 }
895 default:
896 /* Do nothing. */
897 break;
898 }
899 return 0;
900
901fail:
902 return -EINVAL;
903}
904
905static int voice_send_start_voice_cmd(struct voice_data *v)
906{
907 struct apr_hdr mvm_start_voice_cmd;
908 int ret = 0;
909 void *apr_mvm;
910 u16 mvm_handle;
911
912 if (v == NULL) {
913 pr_err("%s: v is NULL\n", __func__);
914 return -EINVAL;
915 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700916 apr_mvm = common.apr_q6_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700917
918 if (!apr_mvm) {
919 pr_err("%s: apr_mvm is NULL.\n", __func__);
920 return -EINVAL;
921 }
922 mvm_handle = voice_get_mvm_handle(v);
923
924 mvm_start_voice_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
925 APR_HDR_LEN(APR_HDR_SIZE),
926 APR_PKT_VER);
927 mvm_start_voice_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
928 sizeof(mvm_start_voice_cmd) - APR_HDR_SIZE);
929 pr_debug("send mvm_start_voice_cmd pkt size = %d\n",
930 mvm_start_voice_cmd.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700931 mvm_start_voice_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700932 mvm_start_voice_cmd.dest_port = mvm_handle;
933 mvm_start_voice_cmd.token = 0;
934 mvm_start_voice_cmd.opcode = VSS_IMVM_CMD_START_VOICE;
935
936 v->mvm_state = CMD_STATUS_FAIL;
937 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_start_voice_cmd);
938 if (ret < 0) {
939 pr_err("Fail in sending VSS_IMVM_CMD_START_VOICE\n");
940 goto fail;
941 }
942 ret = wait_event_timeout(v->mvm_wait,
943 (v->mvm_state == CMD_STATUS_SUCCESS),
944 msecs_to_jiffies(TIMEOUT_MS));
945 if (!ret) {
946 pr_err("%s: wait_event timeout\n", __func__);
947 goto fail;
948 }
949 return 0;
950fail:
951 return -EINVAL;
952}
953
954static int voice_send_disable_vocproc_cmd(struct voice_data *v)
955{
956 struct apr_hdr cvp_disable_cmd;
957 int ret = 0;
958 void *apr_cvp;
959 u16 cvp_handle;
960
961 if (v == NULL) {
962 pr_err("%s: v is NULL\n", __func__);
963 return -EINVAL;
964 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700965 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700966
967 if (!apr_cvp) {
968 pr_err("%s: apr regist failed\n", __func__);
969 return -EINVAL;
970 }
971 cvp_handle = voice_get_cvp_handle(v);
972
973 /* disable vocproc and wait for respose */
974 cvp_disable_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
975 APR_HDR_LEN(APR_HDR_SIZE),
976 APR_PKT_VER);
977 cvp_disable_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
978 sizeof(cvp_disable_cmd) - APR_HDR_SIZE);
979 pr_debug("cvp_disable_cmd pkt size = %d, cvp_handle=%d\n",
980 cvp_disable_cmd.pkt_size, cvp_handle);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700981 cvp_disable_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700982 cvp_disable_cmd.dest_port = cvp_handle;
983 cvp_disable_cmd.token = 0;
984 cvp_disable_cmd.opcode = VSS_IVOCPROC_CMD_DISABLE;
985
986 v->cvp_state = CMD_STATUS_FAIL;
987 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_disable_cmd);
988 if (ret < 0) {
989 pr_err("Fail in sending VSS_IVOCPROC_CMD_DISABLE\n");
990 goto fail;
991 }
992 ret = wait_event_timeout(v->cvp_wait,
993 (v->cvp_state == CMD_STATUS_SUCCESS),
994 msecs_to_jiffies(TIMEOUT_MS));
995 if (!ret) {
996 pr_err("%s: wait_event timeout\n", __func__);
997 goto fail;
998 }
999
1000 return 0;
1001fail:
1002 return -EINVAL;
1003}
1004
1005static int voice_send_set_device_cmd(struct voice_data *v)
1006{
1007 struct cvp_set_device_cmd cvp_setdev_cmd;
1008 int ret = 0;
1009 void *apr_cvp;
1010 u16 cvp_handle;
1011
1012 if (v == NULL) {
1013 pr_err("%s: v is NULL\n", __func__);
1014 return -EINVAL;
1015 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001016 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001017
1018 if (!apr_cvp) {
1019 pr_err("%s: apr_cvp is NULL.\n", __func__);
1020 return -EINVAL;
1021 }
1022 cvp_handle = voice_get_cvp_handle(v);
1023
1024 /* set device and wait for response */
1025 cvp_setdev_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1026 APR_HDR_LEN(APR_HDR_SIZE),
1027 APR_PKT_VER);
1028 cvp_setdev_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1029 sizeof(cvp_setdev_cmd) - APR_HDR_SIZE);
1030 pr_debug(" send create cvp setdev, pkt size = %d\n",
1031 cvp_setdev_cmd.hdr.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001032 cvp_setdev_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001033 cvp_setdev_cmd.hdr.dest_port = cvp_handle;
1034 cvp_setdev_cmd.hdr.token = 0;
1035 cvp_setdev_cmd.hdr.opcode = VSS_IVOCPROC_CMD_SET_DEVICE;
1036
1037 /* Use default topology if invalid value in ACDB */
1038 cvp_setdev_cmd.cvp_set_device.tx_topology_id =
1039 get_voice_tx_topology();
1040 if (cvp_setdev_cmd.cvp_set_device.tx_topology_id == 0)
1041 cvp_setdev_cmd.cvp_set_device.tx_topology_id =
1042 VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
1043
1044 cvp_setdev_cmd.cvp_set_device.rx_topology_id =
1045 get_voice_rx_topology();
1046 if (cvp_setdev_cmd.cvp_set_device.rx_topology_id == 0)
1047 cvp_setdev_cmd.cvp_set_device.rx_topology_id =
1048 VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
1049 cvp_setdev_cmd.cvp_set_device.tx_port_id = v->dev_tx.port_id;
1050 cvp_setdev_cmd.cvp_set_device.rx_port_id = v->dev_rx.port_id;
1051 pr_debug("topology=%d , tx_port_id=%d, rx_port_id=%d\n",
1052 cvp_setdev_cmd.cvp_set_device.tx_topology_id,
1053 cvp_setdev_cmd.cvp_set_device.tx_port_id,
1054 cvp_setdev_cmd.cvp_set_device.rx_port_id);
1055
1056 v->cvp_state = CMD_STATUS_FAIL;
1057 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_setdev_cmd);
1058 if (ret < 0) {
1059 pr_err("Fail in sending VOCPROC_FULL_CONTROL_SESSION\n");
1060 goto fail;
1061 }
1062 pr_debug("wait for cvp create session event\n");
1063 ret = wait_event_timeout(v->cvp_wait,
1064 (v->cvp_state == CMD_STATUS_SUCCESS),
1065 msecs_to_jiffies(TIMEOUT_MS));
1066 if (!ret) {
1067 pr_err("%s: wait_event timeout\n", __func__);
1068 goto fail;
1069 }
1070
1071 return 0;
1072fail:
1073 return -EINVAL;
1074}
1075
1076static int voice_send_stop_voice_cmd(struct voice_data *v)
1077{
1078 struct apr_hdr mvm_stop_voice_cmd;
1079 int ret = 0;
1080 void *apr_mvm;
1081 u16 mvm_handle;
1082
1083 if (v == NULL) {
1084 pr_err("%s: v is NULL\n", __func__);
1085 return -EINVAL;
1086 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001087 apr_mvm = common.apr_q6_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001088
1089 if (!apr_mvm) {
1090 pr_err("%s: apr_mvm is NULL.\n", __func__);
1091 return -EINVAL;
1092 }
1093 mvm_handle = voice_get_mvm_handle(v);
1094
1095 mvm_stop_voice_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1096 APR_HDR_LEN(APR_HDR_SIZE),
1097 APR_PKT_VER);
1098 mvm_stop_voice_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1099 sizeof(mvm_stop_voice_cmd) - APR_HDR_SIZE);
1100 pr_debug("send mvm_stop_voice_cmd pkt size = %d\n",
1101 mvm_stop_voice_cmd.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001102 mvm_stop_voice_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001103 mvm_stop_voice_cmd.dest_port = mvm_handle;
1104 mvm_stop_voice_cmd.token = 0;
1105 mvm_stop_voice_cmd.opcode = VSS_IMVM_CMD_STOP_VOICE;
1106
1107 v->mvm_state = CMD_STATUS_FAIL;
1108 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_stop_voice_cmd);
1109 if (ret < 0) {
1110 pr_err("Fail in sending VSS_IMVM_CMD_STOP_VOICE\n");
1111 goto fail;
1112 }
1113 ret = wait_event_timeout(v->mvm_wait,
1114 (v->mvm_state == CMD_STATUS_SUCCESS),
1115 msecs_to_jiffies(TIMEOUT_MS));
1116 if (!ret) {
1117 pr_err("%s: wait_event timeout\n", __func__);
1118 goto fail;
1119 }
1120
1121 return 0;
1122fail:
1123 return -EINVAL;
1124}
1125
Helen Zeng29eb7442011-06-20 11:06:29 -07001126static int voice_send_cvs_register_cal_cmd(struct voice_data *v)
1127{
1128 struct cvs_register_cal_data_cmd cvs_reg_cal_cmd;
1129 struct acdb_cal_block cal_block;
1130 int ret = 0;
1131 void *apr_cvs;
1132 u16 cvs_handle;
1133
1134 /* get the cvs cal data */
1135 get_all_vocstrm_cal(&cal_block);
1136 if (cal_block.cal_size == 0)
1137 goto fail;
1138
1139 if (v == NULL) {
1140 pr_err("%s: v is NULL\n", __func__);
1141 return -EINVAL;
1142 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001143 apr_cvs = common.apr_q6_cvs;
Helen Zeng29eb7442011-06-20 11:06:29 -07001144
1145 if (!apr_cvs) {
1146 pr_err("%s: apr_cvs is NULL.\n", __func__);
1147 return -EINVAL;
1148 }
1149 cvs_handle = voice_get_cvs_handle(v);
1150
1151 /* fill in the header */
1152 cvs_reg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1153 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1154 cvs_reg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1155 sizeof(cvs_reg_cal_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001156 cvs_reg_cal_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001157 cvs_reg_cal_cmd.hdr.dest_port = cvs_handle;
1158 cvs_reg_cal_cmd.hdr.token = 0;
1159 cvs_reg_cal_cmd.hdr.opcode = VSS_ISTREAM_CMD_REGISTER_CALIBRATION_DATA;
1160
1161 cvs_reg_cal_cmd.cvs_cal_data.phys_addr = cal_block.cal_paddr;
1162 cvs_reg_cal_cmd.cvs_cal_data.mem_size = cal_block.cal_size;
1163
1164 v->cvs_state = CMD_STATUS_FAIL;
1165 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_reg_cal_cmd);
1166 if (ret < 0) {
1167 pr_err("Fail: sending cvs cal,\n");
1168 goto fail;
1169 }
1170 ret = wait_event_timeout(v->cvs_wait,
1171 (v->cvs_state == CMD_STATUS_SUCCESS),
1172 msecs_to_jiffies(TIMEOUT_MS));
1173 if (!ret) {
1174 pr_err("%s: wait_event timeout\n", __func__);
1175 goto fail;
1176 }
1177 return 0;
1178fail:
1179 return -EINVAL;
1180
1181}
1182
1183static int voice_send_cvs_deregister_cal_cmd(struct voice_data *v)
1184{
1185 struct cvs_deregister_cal_data_cmd cvs_dereg_cal_cmd;
1186 struct acdb_cal_block cal_block;
1187 int ret = 0;
1188 void *apr_cvs;
1189 u16 cvs_handle;
1190
1191 get_all_vocstrm_cal(&cal_block);
1192 if (cal_block.cal_size == 0)
1193 return 0;
1194
1195 if (v == NULL) {
1196 pr_err("%s: v is NULL\n", __func__);
1197 return -EINVAL;
1198 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001199 apr_cvs = common.apr_q6_cvs;
Helen Zeng29eb7442011-06-20 11:06:29 -07001200
1201 if (!apr_cvs) {
1202 pr_err("%s: apr_cvs is NULL.\n", __func__);
1203 return -EINVAL;
1204 }
1205 cvs_handle = voice_get_cvs_handle(v);
1206
1207 /* fill in the header */
1208 cvs_dereg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1209 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1210 cvs_dereg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1211 sizeof(cvs_dereg_cal_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001212 cvs_dereg_cal_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001213 cvs_dereg_cal_cmd.hdr.dest_port = cvs_handle;
1214 cvs_dereg_cal_cmd.hdr.token = 0;
1215 cvs_dereg_cal_cmd.hdr.opcode =
1216 VSS_ISTREAM_CMD_DEREGISTER_CALIBRATION_DATA;
1217
1218 v->cvs_state = CMD_STATUS_FAIL;
1219 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_dereg_cal_cmd);
1220 if (ret < 0) {
1221 pr_err("Fail: sending cvs cal,\n");
1222 goto fail;
1223 }
1224 ret = wait_event_timeout(v->cvs_wait,
1225 (v->cvs_state == CMD_STATUS_SUCCESS),
1226 msecs_to_jiffies(TIMEOUT_MS));
1227 if (!ret) {
1228 pr_err("%s: wait_event timeout\n", __func__);
1229 goto fail;
1230 }
1231 return 0;
1232fail:
1233 return -EINVAL;
1234
1235}
1236
1237static int voice_send_cvp_map_memory_cmd(struct voice_data *v)
1238{
1239 struct vss_map_memory_cmd cvp_map_mem_cmd;
1240 struct acdb_cal_block cal_block;
1241 int ret = 0;
1242 void *apr_cvp;
1243 u16 cvp_handle;
1244
1245 /* get all cvp cal data */
1246 get_all_cvp_cal(&cal_block);
1247 if (cal_block.cal_size == 0)
1248 goto fail;
1249
1250 if (v == NULL) {
1251 pr_err("%s: v is NULL\n", __func__);
1252 return -EINVAL;
1253 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001254 apr_cvp = common.apr_q6_cvp;
Helen Zeng29eb7442011-06-20 11:06:29 -07001255
1256 if (!apr_cvp) {
1257 pr_err("%s: apr_cvp is NULL.\n", __func__);
1258 return -EINVAL;
1259 }
1260 cvp_handle = voice_get_cvp_handle(v);
1261
1262 /* fill in the header */
1263 cvp_map_mem_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1264 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1265 cvp_map_mem_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1266 sizeof(cvp_map_mem_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001267 cvp_map_mem_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001268 cvp_map_mem_cmd.hdr.dest_port = cvp_handle;
1269 cvp_map_mem_cmd.hdr.token = 0;
1270 cvp_map_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_MAP_MEMORY;
1271
1272 pr_debug("%s, phy_addr:%d, mem_size:%d\n", __func__,
1273 cal_block.cal_paddr, cal_block.cal_size);
1274 cvp_map_mem_cmd.vss_map_mem.phys_addr = cal_block.cal_paddr;
1275 cvp_map_mem_cmd.vss_map_mem.mem_size = cal_block.cal_size;
1276 cvp_map_mem_cmd.vss_map_mem.mem_pool_id =
1277 VSS_ICOMMON_MAP_MEMORY_SHMEM8_4K_POOL;
1278
1279 v->cvp_state = CMD_STATUS_FAIL;
1280 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_map_mem_cmd);
1281 if (ret < 0) {
1282 pr_err("Fail: sending cvp cal,\n");
1283 goto fail;
1284 }
1285 ret = wait_event_timeout(v->cvp_wait,
1286 (v->cvp_state == CMD_STATUS_SUCCESS),
1287 msecs_to_jiffies(TIMEOUT_MS));
1288 if (!ret) {
1289 pr_err("%s: wait_event timeout\n", __func__);
1290 goto fail;
1291 }
1292 return 0;
1293fail:
1294 return -EINVAL;
1295
1296}
1297
1298static int voice_send_cvp_unmap_memory_cmd(struct voice_data *v)
1299{
1300 struct vss_unmap_memory_cmd cvp_unmap_mem_cmd;
1301 struct acdb_cal_block cal_block;
1302 int ret = 0;
1303 void *apr_cvp;
1304 u16 cvp_handle;
1305
1306 get_all_cvp_cal(&cal_block);
1307 if (cal_block.cal_size == 0)
1308 return 0;
1309
1310 if (v == NULL) {
1311 pr_err("%s: v is NULL\n", __func__);
1312 return -EINVAL;
1313 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001314 apr_cvp = common.apr_q6_cvp;
Helen Zeng29eb7442011-06-20 11:06:29 -07001315
1316 if (!apr_cvp) {
1317 pr_err("%s: apr_cvp is NULL.\n", __func__);
1318 return -EINVAL;
1319 }
1320 cvp_handle = voice_get_cvp_handle(v);
1321
1322 /* fill in the header */
1323 cvp_unmap_mem_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1324 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1325 cvp_unmap_mem_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1326 sizeof(cvp_unmap_mem_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001327 cvp_unmap_mem_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001328 cvp_unmap_mem_cmd.hdr.dest_port = cvp_handle;
1329 cvp_unmap_mem_cmd.hdr.token = 0;
1330 cvp_unmap_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_UNMAP_MEMORY;
1331
1332 cvp_unmap_mem_cmd.vss_unmap_mem.phys_addr = cal_block.cal_paddr;
1333
1334 v->cvp_state = CMD_STATUS_FAIL;
1335 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_unmap_mem_cmd);
1336 if (ret < 0) {
1337 pr_err("Fail: sending cvp cal,\n");
1338 goto fail;
1339 }
1340 ret = wait_event_timeout(v->cvp_wait,
1341 (v->cvp_state == CMD_STATUS_SUCCESS),
1342 msecs_to_jiffies(TIMEOUT_MS));
1343 if (!ret) {
1344 pr_err("%s: wait_event timeout\n", __func__);
1345 goto fail;
1346 }
1347 return 0;
1348fail:
1349 return -EINVAL;
1350
1351}
1352
1353static int voice_send_cvs_map_memory_cmd(struct voice_data *v)
1354{
1355 struct vss_map_memory_cmd cvs_map_mem_cmd;
1356 struct acdb_cal_block cal_block;
1357 int ret = 0;
1358 void *apr_cvs;
1359 u16 cvs_handle;
1360
1361 /* get all cvs cal data */
1362 get_all_vocstrm_cal(&cal_block);
1363 if (cal_block.cal_size == 0)
1364 goto fail;
1365
1366 if (v == NULL) {
1367 pr_err("%s: v is NULL\n", __func__);
1368 return -EINVAL;
1369 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001370 apr_cvs = common.apr_q6_cvs;
Helen Zeng29eb7442011-06-20 11:06:29 -07001371
1372 if (!apr_cvs) {
1373 pr_err("%s: apr_cvs is NULL.\n", __func__);
1374 return -EINVAL;
1375 }
1376 cvs_handle = voice_get_cvs_handle(v);
1377
1378 /* fill in the header */
1379 cvs_map_mem_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1380 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1381 cvs_map_mem_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1382 sizeof(cvs_map_mem_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001383 cvs_map_mem_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001384 cvs_map_mem_cmd.hdr.dest_port = cvs_handle;
1385 cvs_map_mem_cmd.hdr.token = 0;
1386 cvs_map_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_MAP_MEMORY;
1387
1388 pr_debug("%s, phys_addr: %d, mem_size: %d\n", __func__,
1389 cal_block.cal_paddr, cal_block.cal_size);
1390 cvs_map_mem_cmd.vss_map_mem.phys_addr = cal_block.cal_paddr;
1391 cvs_map_mem_cmd.vss_map_mem.mem_size = cal_block.cal_size;
1392 cvs_map_mem_cmd.vss_map_mem.mem_pool_id =
1393 VSS_ICOMMON_MAP_MEMORY_SHMEM8_4K_POOL;
1394
1395 v->cvs_state = CMD_STATUS_FAIL;
1396 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_map_mem_cmd);
1397 if (ret < 0) {
1398 pr_err("Fail: sending cvs cal,\n");
1399 goto fail;
1400 }
1401 ret = wait_event_timeout(v->cvs_wait,
1402 (v->cvs_state == CMD_STATUS_SUCCESS),
1403 msecs_to_jiffies(TIMEOUT_MS));
1404 if (!ret) {
1405 pr_err("%s: wait_event timeout\n", __func__);
1406 goto fail;
1407 }
1408 return 0;
1409fail:
1410 return -EINVAL;
1411
1412}
1413
1414static int voice_send_cvs_unmap_memory_cmd(struct voice_data *v)
1415{
1416 struct vss_unmap_memory_cmd cvs_unmap_mem_cmd;
1417 struct acdb_cal_block cal_block;
1418 int ret = 0;
1419 void *apr_cvs;
1420 u16 cvs_handle;
1421
1422 get_all_vocstrm_cal(&cal_block);
1423 if (cal_block.cal_size == 0)
1424 return 0;
1425
1426 if (v == NULL) {
1427 pr_err("%s: v is NULL\n", __func__);
1428 return -EINVAL;
1429 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001430 apr_cvs = common.apr_q6_cvs;
Helen Zeng29eb7442011-06-20 11:06:29 -07001431
1432 if (!apr_cvs) {
1433 pr_err("%s: apr_cvs is NULL.\n", __func__);
1434 return -EINVAL;
1435 }
1436 cvs_handle = voice_get_cvs_handle(v);
1437
1438 /* fill in the header */
1439 cvs_unmap_mem_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1440 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1441 cvs_unmap_mem_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1442 sizeof(cvs_unmap_mem_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001443 cvs_unmap_mem_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001444 cvs_unmap_mem_cmd.hdr.dest_port = cvs_handle;
1445 cvs_unmap_mem_cmd.hdr.token = 0;
1446 cvs_unmap_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_UNMAP_MEMORY;
1447
1448 cvs_unmap_mem_cmd.vss_unmap_mem.phys_addr = cal_block.cal_paddr;
1449
1450 v->cvs_state = CMD_STATUS_FAIL;
1451 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_unmap_mem_cmd);
1452 if (ret < 0) {
1453 pr_err("Fail: sending cvs cal,\n");
1454 goto fail;
1455 }
1456 ret = wait_event_timeout(v->cvs_wait,
1457 (v->cvs_state == CMD_STATUS_SUCCESS),
1458 msecs_to_jiffies(TIMEOUT_MS));
1459 if (!ret) {
1460 pr_err("%s: wait_event timeout\n", __func__);
1461 goto fail;
1462 }
1463 return 0;
1464fail:
1465 return -EINVAL;
1466
1467}
1468
1469static int voice_send_cvp_register_cal_cmd(struct voice_data *v)
1470{
1471 struct cvp_register_cal_data_cmd cvp_reg_cal_cmd;
1472 struct acdb_cal_block cal_block;
1473 int ret = 0;
1474 void *apr_cvp;
1475 u16 cvp_handle;
1476
1477 /* get the cvp cal data */
1478 get_all_vocproc_cal(&cal_block);
1479 if (cal_block.cal_size == 0)
1480 goto fail;
1481
1482 if (v == NULL) {
1483 pr_err("%s: v is NULL\n", __func__);
1484 return -EINVAL;
1485 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001486 apr_cvp = common.apr_q6_cvp;
Helen Zeng29eb7442011-06-20 11:06:29 -07001487
1488 if (!apr_cvp) {
1489 pr_err("%s: apr_cvp is NULL.\n", __func__);
1490 return -EINVAL;
1491 }
1492 cvp_handle = voice_get_cvp_handle(v);
1493
1494 /* fill in the header */
1495 cvp_reg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1496 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1497 cvp_reg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1498 sizeof(cvp_reg_cal_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001499 cvp_reg_cal_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001500 cvp_reg_cal_cmd.hdr.dest_port = cvp_handle;
1501 cvp_reg_cal_cmd.hdr.token = 0;
1502 cvp_reg_cal_cmd.hdr.opcode = VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA;
1503
1504 cvp_reg_cal_cmd.cvp_cal_data.phys_addr = cal_block.cal_paddr;
1505 cvp_reg_cal_cmd.cvp_cal_data.mem_size = cal_block.cal_size;
1506
1507 v->cvp_state = CMD_STATUS_FAIL;
1508 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_reg_cal_cmd);
1509 if (ret < 0) {
1510 pr_err("Fail: sending cvp cal,\n");
1511 goto fail;
1512 }
1513 ret = wait_event_timeout(v->cvp_wait,
1514 (v->cvp_state == CMD_STATUS_SUCCESS),
1515 msecs_to_jiffies(TIMEOUT_MS));
1516 if (!ret) {
1517 pr_err("%s: wait_event timeout\n", __func__);
1518 goto fail;
1519 }
1520 return 0;
1521fail:
1522 return -EINVAL;
1523
1524}
1525
1526static int voice_send_cvp_deregister_cal_cmd(struct voice_data *v)
1527{
1528 struct cvp_deregister_cal_data_cmd cvp_dereg_cal_cmd;
1529 struct acdb_cal_block cal_block;
1530 int ret = 0;
1531 void *apr_cvp;
1532 u16 cvp_handle;
1533
1534 get_all_vocproc_cal(&cal_block);
1535 if (cal_block.cal_size == 0)
1536 return 0;
1537
1538 if (v == NULL) {
1539 pr_err("%s: v is NULL\n", __func__);
1540 return -EINVAL;
1541 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001542 apr_cvp = common.apr_q6_cvp;
Helen Zeng29eb7442011-06-20 11:06:29 -07001543
1544 if (!apr_cvp) {
1545 pr_err("%s: apr_cvp is NULL.\n", __func__);
1546 return -EINVAL;
1547 }
1548 cvp_handle = voice_get_cvp_handle(v);
1549
1550 /* fill in the header */
1551 cvp_dereg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1552 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1553 cvp_dereg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1554 sizeof(cvp_dereg_cal_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001555 cvp_dereg_cal_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001556 cvp_dereg_cal_cmd.hdr.dest_port = cvp_handle;
1557 cvp_dereg_cal_cmd.hdr.token = 0;
1558 cvp_dereg_cal_cmd.hdr.opcode =
1559 VSS_IVOCPROC_CMD_DEREGISTER_CALIBRATION_DATA;
1560
1561 v->cvp_state = CMD_STATUS_FAIL;
1562 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_dereg_cal_cmd);
1563 if (ret < 0) {
1564 pr_err("Fail: sending cvp cal,\n");
1565 goto fail;
1566 }
1567 ret = wait_event_timeout(v->cvp_wait,
1568 (v->cvp_state == CMD_STATUS_SUCCESS),
1569 msecs_to_jiffies(TIMEOUT_MS));
1570 if (!ret) {
1571 pr_err("%s: wait_event timeout\n", __func__);
1572 goto fail;
1573 }
1574 return 0;
1575fail:
1576 return -EINVAL;
1577
1578}
1579
1580static int voice_send_cvp_register_vol_cal_table_cmd(struct voice_data *v)
1581{
1582 struct cvp_register_vol_cal_table_cmd cvp_reg_cal_tbl_cmd;
1583 struct acdb_cal_block cal_block;
1584 int ret = 0;
1585 void *apr_cvp;
1586 u16 cvp_handle;
1587
1588 /* get the cvp vol cal data */
1589 get_all_vocvol_cal(&cal_block);
1590 if (cal_block.cal_size == 0)
1591 goto fail;
1592
1593 if (v == NULL) {
1594 pr_err("%s: v is NULL\n", __func__);
1595 return -EINVAL;
1596 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001597 apr_cvp = common.apr_q6_cvp;
Helen Zeng29eb7442011-06-20 11:06:29 -07001598
1599 if (!apr_cvp) {
1600 pr_err("%s: apr_cvp is NULL.\n", __func__);
1601 return -EINVAL;
1602 }
1603 cvp_handle = voice_get_cvp_handle(v);
1604
1605 /* fill in the header */
1606 cvp_reg_cal_tbl_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1607 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1608 cvp_reg_cal_tbl_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1609 sizeof(cvp_reg_cal_tbl_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001610 cvp_reg_cal_tbl_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001611 cvp_reg_cal_tbl_cmd.hdr.dest_port = cvp_handle;
1612 cvp_reg_cal_tbl_cmd.hdr.token = 0;
1613 cvp_reg_cal_tbl_cmd.hdr.opcode =
1614 VSS_IVOCPROC_CMD_REGISTER_VOLUME_CAL_TABLE;
1615
1616 cvp_reg_cal_tbl_cmd.cvp_vol_cal_tbl.phys_addr = cal_block.cal_paddr;
1617 cvp_reg_cal_tbl_cmd.cvp_vol_cal_tbl.mem_size = cal_block.cal_size;
1618
1619 v->cvp_state = CMD_STATUS_FAIL;
1620 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_reg_cal_tbl_cmd);
1621 if (ret < 0) {
1622 pr_err("Fail: sending cvp cal table,\n");
1623 goto fail;
1624 }
1625 ret = wait_event_timeout(v->cvp_wait,
1626 (v->cvp_state == CMD_STATUS_SUCCESS),
1627 msecs_to_jiffies(TIMEOUT_MS));
1628 if (!ret) {
1629 pr_err("%s: wait_event timeout\n", __func__);
1630 goto fail;
1631 }
1632 return 0;
1633fail:
1634 return -EINVAL;
1635
1636}
1637
1638static int voice_send_cvp_deregister_vol_cal_table_cmd(struct voice_data *v)
1639{
1640 struct cvp_deregister_vol_cal_table_cmd cvp_dereg_cal_tbl_cmd;
1641 struct acdb_cal_block cal_block;
1642 int ret = 0;
1643 void *apr_cvp;
1644 u16 cvp_handle;
1645
1646 get_all_vocvol_cal(&cal_block);
1647 if (cal_block.cal_size == 0)
1648 return 0;
1649
1650 if (v == NULL) {
1651 pr_err("%s: v is NULL\n", __func__);
1652 return -EINVAL;
1653 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001654 apr_cvp = common.apr_q6_cvp;
Helen Zeng29eb7442011-06-20 11:06:29 -07001655
1656 if (!apr_cvp) {
1657 pr_err("%s: apr_cvp is NULL.\n", __func__);
1658 return -EINVAL;
1659 }
1660 cvp_handle = voice_get_cvp_handle(v);
1661
1662 /* fill in the header */
1663 cvp_dereg_cal_tbl_cmd.hdr.hdr_field = APR_HDR_FIELD(
1664 APR_MSG_TYPE_SEQ_CMD,
1665 APR_HDR_LEN(APR_HDR_SIZE),
1666 APR_PKT_VER);
1667 cvp_dereg_cal_tbl_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1668 sizeof(cvp_dereg_cal_tbl_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001669 cvp_dereg_cal_tbl_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001670 cvp_dereg_cal_tbl_cmd.hdr.dest_port = cvp_handle;
1671 cvp_dereg_cal_tbl_cmd.hdr.token = 0;
1672 cvp_dereg_cal_tbl_cmd.hdr.opcode =
1673 VSS_IVOCPROC_CMD_DEREGISTER_VOLUME_CAL_TABLE;
1674
1675 v->cvp_state = CMD_STATUS_FAIL;
1676 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_dereg_cal_tbl_cmd);
1677 if (ret < 0) {
1678 pr_err("Fail: sending cvp cal table,\n");
1679 goto fail;
1680 }
1681 ret = wait_event_timeout(v->cvp_wait,
1682 (v->cvp_state == CMD_STATUS_SUCCESS),
1683 msecs_to_jiffies(TIMEOUT_MS));
1684 if (!ret) {
1685 pr_err("%s: wait_event timeout\n", __func__);
1686 goto fail;
1687 }
1688 return 0;
1689fail:
1690 return -EINVAL;
1691
1692}
Neema Shetty2c07eb52011-08-21 20:33:52 -07001693
Helen Zeng44d4d272011-08-10 14:49:20 -07001694static int voice_send_set_widevoice_enable_cmd(struct voice_data *v)
1695{
1696 struct mvm_set_widevoice_enable_cmd mvm_set_wv_cmd;
1697 int ret = 0;
1698 void *apr_mvm;
1699 u16 mvm_handle;
1700
1701 if (v == NULL) {
1702 pr_err("%s: v is NULL\n", __func__);
1703 return -EINVAL;
1704 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001705 apr_mvm = common.apr_q6_mvm;
Helen Zeng44d4d272011-08-10 14:49:20 -07001706
1707 if (!apr_mvm) {
1708 pr_err("%s: apr_mvm is NULL.\n", __func__);
1709 return -EINVAL;
1710 }
1711 mvm_handle = voice_get_mvm_handle(v);
1712
1713 /* fill in the header */
1714 mvm_set_wv_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1715 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1716 mvm_set_wv_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1717 sizeof(mvm_set_wv_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001718 mvm_set_wv_cmd.hdr.src_port = v->session_id;
Helen Zeng44d4d272011-08-10 14:49:20 -07001719 mvm_set_wv_cmd.hdr.dest_port = mvm_handle;
1720 mvm_set_wv_cmd.hdr.token = 0;
1721 mvm_set_wv_cmd.hdr.opcode = VSS_IWIDEVOICE_CMD_SET_WIDEVOICE;
1722
1723 mvm_set_wv_cmd.vss_set_wv.enable = v->wv_enable;
1724
1725 v->mvm_state = CMD_STATUS_FAIL;
1726 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_wv_cmd);
1727 if (ret < 0) {
1728 pr_err("Fail: sending mvm set widevoice enable,\n");
1729 goto fail;
1730 }
1731 ret = wait_event_timeout(v->mvm_wait,
1732 (v->mvm_state == CMD_STATUS_SUCCESS),
1733 msecs_to_jiffies(TIMEOUT_MS));
1734 if (!ret) {
1735 pr_err("%s: wait_event timeout\n", __func__);
1736 goto fail;
1737 }
1738 return 0;
1739fail:
1740 return -EINVAL;
1741}
1742
Helen Zeng4e531942011-12-17 21:14:40 -08001743static int voice_send_set_pp_enable_cmd(struct voice_data *v,
1744 uint32_t module_id, int enable)
Helen Zengbb49c702011-09-06 14:09:13 -07001745{
Helen Zeng4e531942011-12-17 21:14:40 -08001746 struct cvs_set_pp_enable_cmd cvs_set_pp_cmd;
Helen Zengbb49c702011-09-06 14:09:13 -07001747 int ret = 0;
1748 void *apr_cvs;
1749 u16 cvs_handle;
1750
1751 if (v == NULL) {
1752 pr_err("%s: v is NULL\n", __func__);
1753 return -EINVAL;
1754 }
1755 apr_cvs = common.apr_q6_cvs;
1756
1757 if (!apr_cvs) {
1758 pr_err("%s: apr_cvs is NULL.\n", __func__);
1759 return -EINVAL;
1760 }
1761 cvs_handle = voice_get_cvs_handle(v);
1762
1763 /* fill in the header */
Helen Zeng4e531942011-12-17 21:14:40 -08001764 cvs_set_pp_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
Helen Zengbb49c702011-09-06 14:09:13 -07001765 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
Helen Zeng4e531942011-12-17 21:14:40 -08001766 cvs_set_pp_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1767 sizeof(cvs_set_pp_cmd) - APR_HDR_SIZE);
1768 cvs_set_pp_cmd.hdr.src_port = v->session_id;
1769 cvs_set_pp_cmd.hdr.dest_port = cvs_handle;
1770 cvs_set_pp_cmd.hdr.token = 0;
1771 cvs_set_pp_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_UI_PROPERTY;
Helen Zengbb49c702011-09-06 14:09:13 -07001772
Helen Zeng4e531942011-12-17 21:14:40 -08001773 cvs_set_pp_cmd.vss_set_pp.module_id = module_id;
1774 cvs_set_pp_cmd.vss_set_pp.param_id = VOICE_PARAM_MOD_ENABLE;
1775 cvs_set_pp_cmd.vss_set_pp.param_size = MOD_ENABLE_PARAM_LEN;
1776 cvs_set_pp_cmd.vss_set_pp.reserved = 0;
1777 cvs_set_pp_cmd.vss_set_pp.enable = enable;
1778 cvs_set_pp_cmd.vss_set_pp.reserved_field = 0;
1779 pr_debug("voice_send_set_pp_enable_cmd, module_id=%d, enable=%d\n",
1780 module_id, enable);
Helen Zengbb49c702011-09-06 14:09:13 -07001781
1782 v->cvs_state = CMD_STATUS_FAIL;
Helen Zeng4e531942011-12-17 21:14:40 -08001783 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_pp_cmd);
Helen Zengbb49c702011-09-06 14:09:13 -07001784 if (ret < 0) {
1785 pr_err("Fail: sending cvs set slowtalk enable,\n");
1786 goto fail;
1787 }
1788 ret = wait_event_timeout(v->cvs_wait,
1789 (v->cvs_state == CMD_STATUS_SUCCESS),
1790 msecs_to_jiffies(TIMEOUT_MS));
1791 if (!ret) {
1792 pr_err("%s: wait_event timeout\n", __func__);
1793 goto fail;
1794 }
1795 return 0;
1796fail:
1797 return -EINVAL;
1798}
1799
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001800static int voice_setup_vocproc(struct voice_data *v)
1801{
1802 struct cvp_create_full_ctl_session_cmd cvp_session_cmd;
1803 int ret = 0;
1804 void *apr_cvp;
1805 if (v == NULL) {
1806 pr_err("%s: v is NULL\n", __func__);
1807 return -EINVAL;
1808 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001809 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001810
1811 if (!apr_cvp) {
1812 pr_err("%s: apr_cvp is NULL.\n", __func__);
1813 return -EINVAL;
1814 }
1815
1816 /* create cvp session and wait for response */
1817 cvp_session_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1818 APR_HDR_LEN(APR_HDR_SIZE),
1819 APR_PKT_VER);
1820 cvp_session_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1821 sizeof(cvp_session_cmd) - APR_HDR_SIZE);
1822 pr_debug(" send create cvp session, pkt size = %d\n",
1823 cvp_session_cmd.hdr.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001824 cvp_session_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001825 cvp_session_cmd.hdr.dest_port = 0;
1826 cvp_session_cmd.hdr.token = 0;
1827 cvp_session_cmd.hdr.opcode =
1828 VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION;
1829
1830 /* Use default topology if invalid value in ACDB */
1831 cvp_session_cmd.cvp_session.tx_topology_id =
1832 get_voice_tx_topology();
1833 if (cvp_session_cmd.cvp_session.tx_topology_id == 0)
1834 cvp_session_cmd.cvp_session.tx_topology_id =
1835 VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
1836
1837 cvp_session_cmd.cvp_session.rx_topology_id =
1838 get_voice_rx_topology();
1839 if (cvp_session_cmd.cvp_session.rx_topology_id == 0)
1840 cvp_session_cmd.cvp_session.rx_topology_id =
1841 VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
1842
1843 cvp_session_cmd.cvp_session.direction = 2; /*tx and rx*/
1844 cvp_session_cmd.cvp_session.network_id = VSS_NETWORK_ID_DEFAULT;
1845 cvp_session_cmd.cvp_session.tx_port_id = v->dev_tx.port_id;
1846 cvp_session_cmd.cvp_session.rx_port_id = v->dev_rx.port_id;
1847
1848 pr_debug("topology=%d net_id=%d, dir=%d tx_port_id=%d, rx_port_id=%d\n",
1849 cvp_session_cmd.cvp_session.tx_topology_id,
1850 cvp_session_cmd.cvp_session.network_id,
1851 cvp_session_cmd.cvp_session.direction,
1852 cvp_session_cmd.cvp_session.tx_port_id,
1853 cvp_session_cmd.cvp_session.rx_port_id);
1854
1855 v->cvp_state = CMD_STATUS_FAIL;
1856 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_session_cmd);
1857 if (ret < 0) {
1858 pr_err("Fail in sending VOCPROC_FULL_CONTROL_SESSION\n");
1859 goto fail;
1860 }
1861 ret = wait_event_timeout(v->cvp_wait,
1862 (v->cvp_state == CMD_STATUS_SUCCESS),
1863 msecs_to_jiffies(TIMEOUT_MS));
1864 if (!ret) {
1865 pr_err("%s: wait_event timeout\n", __func__);
1866 goto fail;
1867 }
1868
Helen Zeng29eb7442011-06-20 11:06:29 -07001869 /* send cvs cal */
1870 ret = voice_send_cvs_map_memory_cmd(v);
1871 if (!ret)
1872 voice_send_cvs_register_cal_cmd(v);
1873
1874 /* send cvp and vol cal */
1875 ret = voice_send_cvp_map_memory_cmd(v);
1876 if (!ret) {
1877 voice_send_cvp_register_cal_cmd(v);
1878 voice_send_cvp_register_vol_cal_table_cmd(v);
1879 }
1880
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001881 /* enable vocproc */
1882 ret = voice_send_enable_vocproc_cmd(v);
1883 if (ret < 0)
1884 goto fail;
1885
1886 /* attach vocproc */
1887 ret = voice_send_attach_vocproc_cmd(v);
1888 if (ret < 0)
1889 goto fail;
1890
1891 /* send tty mode if tty device is used */
1892 voice_send_tty_mode_cmd(v);
1893
Helen Zeng44d4d272011-08-10 14:49:20 -07001894 /* enable widevoice if wv_enable is set */
1895 if (v->wv_enable)
1896 voice_send_set_widevoice_enable_cmd(v);
1897
Helen Zengbb49c702011-09-06 14:09:13 -07001898 /* enable slowtalk if st_enable is set */
1899 if (v->st_enable)
Helen Zeng4e531942011-12-17 21:14:40 -08001900 voice_send_set_pp_enable_cmd(v, MODULE_ID_VOICE_MODULE_ST,
1901 v->st_enable);
1902 if (v->fens_enable)
1903 voice_send_set_pp_enable_cmd(v, MODULE_ID_VOICE_MODULE_FENS,
1904 v->fens_enable);
Helen Zengbb49c702011-09-06 14:09:13 -07001905
Neema Shetty2c07eb52011-08-21 20:33:52 -07001906 if (is_voip_session(v->session_id))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001907 voice_send_netid_timing_cmd(v);
1908
Helen Zenge3d716a2011-10-14 16:32:16 -07001909 /* Start in-call music delivery if this feature is enabled */
Helen Zeng0705a5f2011-10-14 15:29:52 -07001910 if (v->music_info.play_enable)
1911 voice_cvs_start_playback(v);
1912
Helen Zenge3d716a2011-10-14 16:32:16 -07001913 /* Start in-call recording if this feature is enabled */
1914 if (v->rec_info.rec_enable)
1915 voice_cvs_start_record(v, v->rec_info.rec_mode);
1916
Ben Romberger13b74ab2011-07-18 17:36:32 -07001917 rtac_add_voice(voice_get_cvs_handle(v),
1918 voice_get_cvp_handle(v),
Ben Rombergerc5d6a372011-09-22 18:01:49 -07001919 v->dev_rx.port_id, v->dev_tx.port_id,
1920 v->session_id);
Ben Romberger13b74ab2011-07-18 17:36:32 -07001921
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001922 return 0;
1923
1924fail:
1925 return -EINVAL;
1926}
1927
1928static int voice_send_enable_vocproc_cmd(struct voice_data *v)
1929{
1930 int ret = 0;
1931 struct apr_hdr cvp_enable_cmd;
1932 void *apr_cvp;
1933 u16 cvp_handle;
1934
1935 if (v == NULL) {
1936 pr_err("%s: v is NULL\n", __func__);
1937 return -EINVAL;
1938 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001939 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001940
1941 if (!apr_cvp) {
1942 pr_err("%s: apr_cvp is NULL.\n", __func__);
1943 return -EINVAL;
1944 }
1945 cvp_handle = voice_get_cvp_handle(v);
1946
1947 /* enable vocproc and wait for respose */
1948 cvp_enable_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1949 APR_HDR_LEN(APR_HDR_SIZE),
1950 APR_PKT_VER);
1951 cvp_enable_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1952 sizeof(cvp_enable_cmd) - APR_HDR_SIZE);
1953 pr_debug("cvp_enable_cmd pkt size = %d, cvp_handle=%d\n",
1954 cvp_enable_cmd.pkt_size, cvp_handle);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001955 cvp_enable_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001956 cvp_enable_cmd.dest_port = cvp_handle;
1957 cvp_enable_cmd.token = 0;
1958 cvp_enable_cmd.opcode = VSS_IVOCPROC_CMD_ENABLE;
1959
1960 v->cvp_state = CMD_STATUS_FAIL;
1961 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_enable_cmd);
1962 if (ret < 0) {
1963 pr_err("Fail in sending VSS_IVOCPROC_CMD_ENABLE\n");
1964 goto fail;
1965 }
1966 ret = wait_event_timeout(v->cvp_wait,
1967 (v->cvp_state == CMD_STATUS_SUCCESS),
1968 msecs_to_jiffies(TIMEOUT_MS));
1969 if (!ret) {
1970 pr_err("%s: wait_event timeout\n", __func__);
1971 goto fail;
1972 }
1973
1974 return 0;
1975fail:
1976 return -EINVAL;
1977}
1978
1979static int voice_send_netid_timing_cmd(struct voice_data *v)
1980{
1981 int ret = 0;
1982 void *apr_mvm;
1983 u16 mvm_handle;
1984 struct mvm_set_network_cmd mvm_set_network;
1985 struct mvm_set_voice_timing_cmd mvm_set_voice_timing;
1986
1987 if (v == NULL) {
1988 pr_err("%s: v is NULL\n", __func__);
1989 return -EINVAL;
1990 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001991 apr_mvm = common.apr_q6_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001992
1993 if (!apr_mvm) {
1994 pr_err("%s: apr_mvm is NULL.\n", __func__);
1995 return -EINVAL;
1996 }
1997 mvm_handle = voice_get_mvm_handle(v);
1998
1999 ret = voice_config_cvs_vocoder(v);
2000 if (ret < 0) {
2001 pr_err("%s: Error %d configuring CVS voc",
2002 __func__, ret);
2003 goto fail;
2004 }
2005 /* Set network ID. */
2006 pr_debug("Setting network ID\n");
2007
2008 mvm_set_network.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2009 APR_HDR_LEN(APR_HDR_SIZE),
2010 APR_PKT_VER);
2011 mvm_set_network.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2012 sizeof(mvm_set_network) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002013 mvm_set_network.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002014 mvm_set_network.hdr.dest_port = mvm_handle;
2015 mvm_set_network.hdr.token = 0;
2016 mvm_set_network.hdr.opcode = VSS_ICOMMON_CMD_SET_NETWORK;
Neema Shetty2c07eb52011-08-21 20:33:52 -07002017 mvm_set_network.network.network_id = common.mvs_info.network_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002018
2019 v->mvm_state = CMD_STATUS_FAIL;
2020 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_network);
2021 if (ret < 0) {
2022 pr_err("%s: Error %d sending SET_NETWORK\n", __func__, ret);
2023 goto fail;
2024 }
2025
2026 ret = wait_event_timeout(v->mvm_wait,
2027 (v->mvm_state == CMD_STATUS_SUCCESS),
2028 msecs_to_jiffies(TIMEOUT_MS));
2029 if (!ret) {
2030 pr_err("%s: wait_event timeout\n", __func__);
2031 goto fail;
2032 }
2033
2034 /* Set voice timing. */
2035 pr_debug("Setting voice timing\n");
2036
2037 mvm_set_voice_timing.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2038 APR_HDR_LEN(APR_HDR_SIZE),
2039 APR_PKT_VER);
2040 mvm_set_voice_timing.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2041 sizeof(mvm_set_voice_timing) -
2042 APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002043 mvm_set_voice_timing.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002044 mvm_set_voice_timing.hdr.dest_port = mvm_handle;
2045 mvm_set_voice_timing.hdr.token = 0;
2046 mvm_set_voice_timing.hdr.opcode = VSS_ICOMMON_CMD_SET_VOICE_TIMING;
2047 mvm_set_voice_timing.timing.mode = 0;
2048 mvm_set_voice_timing.timing.enc_offset = 8000;
Swaminathan Sathappan2fea0da2011-12-21 12:20:53 -08002049 if (machine_is_apq8064_sim()) {
2050 pr_debug("%s: Machine is apq8064 sim\n", __func__);
2051 mvm_set_voice_timing.timing.dec_req_offset = 0;
2052 mvm_set_voice_timing.timing.dec_offset = 18000;
2053 } else {
2054 mvm_set_voice_timing.timing.dec_req_offset = 3300;
2055 mvm_set_voice_timing.timing.dec_offset = 8300;
2056 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002057
2058 v->mvm_state = CMD_STATUS_FAIL;
2059
2060 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_voice_timing);
2061 if (ret < 0) {
2062 pr_err("%s: Error %d sending SET_TIMING\n", __func__, ret);
2063 goto fail;
2064 }
2065
2066 ret = wait_event_timeout(v->mvm_wait,
2067 (v->mvm_state == CMD_STATUS_SUCCESS),
2068 msecs_to_jiffies(TIMEOUT_MS));
2069 if (!ret) {
2070 pr_err("%s: wait_event timeout\n", __func__);
2071 goto fail;
2072 }
2073
2074 return 0;
2075fail:
2076 return -EINVAL;
2077}
2078
2079static int voice_send_attach_vocproc_cmd(struct voice_data *v)
2080{
2081 int ret = 0;
2082 struct mvm_attach_vocproc_cmd mvm_a_vocproc_cmd;
2083 void *apr_mvm;
2084 u16 mvm_handle, cvp_handle;
2085
2086 if (v == NULL) {
2087 pr_err("%s: v is NULL\n", __func__);
2088 return -EINVAL;
2089 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07002090 apr_mvm = common.apr_q6_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002091
2092 if (!apr_mvm) {
2093 pr_err("%s: apr_mvm is NULL.\n", __func__);
2094 return -EINVAL;
2095 }
2096 mvm_handle = voice_get_mvm_handle(v);
2097 cvp_handle = voice_get_cvp_handle(v);
2098
2099 /* attach vocproc and wait for response */
2100 mvm_a_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2101 APR_HDR_LEN(APR_HDR_SIZE),
2102 APR_PKT_VER);
2103 mvm_a_vocproc_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2104 sizeof(mvm_a_vocproc_cmd) - APR_HDR_SIZE);
2105 pr_debug("send mvm_a_vocproc_cmd pkt size = %d\n",
2106 mvm_a_vocproc_cmd.hdr.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002107 mvm_a_vocproc_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002108 mvm_a_vocproc_cmd.hdr.dest_port = mvm_handle;
2109 mvm_a_vocproc_cmd.hdr.token = 0;
Helen Zeng69b00962011-07-08 11:38:36 -07002110 mvm_a_vocproc_cmd.hdr.opcode = VSS_IMVM_CMD_ATTACH_VOCPROC;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002111 mvm_a_vocproc_cmd.mvm_attach_cvp_handle.handle = cvp_handle;
2112
2113 v->mvm_state = CMD_STATUS_FAIL;
2114 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_a_vocproc_cmd);
2115 if (ret < 0) {
Helen Zeng69b00962011-07-08 11:38:36 -07002116 pr_err("Fail in sending VSS_IMVM_CMD_ATTACH_VOCPROC\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002117 goto fail;
2118 }
2119 ret = wait_event_timeout(v->mvm_wait,
2120 (v->mvm_state == CMD_STATUS_SUCCESS),
2121 msecs_to_jiffies(TIMEOUT_MS));
2122 if (!ret) {
2123 pr_err("%s: wait_event timeout\n", __func__);
2124 goto fail;
2125 }
2126
2127 return 0;
2128fail:
2129 return -EINVAL;
2130}
2131
2132static int voice_destroy_vocproc(struct voice_data *v)
2133{
2134 struct mvm_detach_vocproc_cmd mvm_d_vocproc_cmd;
2135 struct apr_hdr cvp_destroy_session_cmd;
2136 int ret = 0;
2137 void *apr_mvm, *apr_cvp;
2138 u16 mvm_handle, cvp_handle;
2139
2140 if (v == NULL) {
2141 pr_err("%s: v is NULL\n", __func__);
2142 return -EINVAL;
2143 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07002144 apr_mvm = common.apr_q6_mvm;
2145 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002146
2147 if (!apr_mvm || !apr_cvp) {
2148 pr_err("%s: apr_mvm or apr_cvp is NULL.\n", __func__);
2149 return -EINVAL;
2150 }
2151 mvm_handle = voice_get_mvm_handle(v);
2152 cvp_handle = voice_get_cvp_handle(v);
2153
Helen Zenge3d716a2011-10-14 16:32:16 -07002154 /* stop playback or recording */
Helen Zeng0705a5f2011-10-14 15:29:52 -07002155 v->music_info.force = 1;
2156 voice_cvs_stop_playback(v);
Helen Zenge3d716a2011-10-14 16:32:16 -07002157 voice_cvs_stop_record(v);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002158 /* send stop voice cmd */
2159 voice_send_stop_voice_cmd(v);
2160
2161 /* detach VOCPROC and wait for response from mvm */
2162 mvm_d_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2163 APR_HDR_LEN(APR_HDR_SIZE),
2164 APR_PKT_VER);
2165 mvm_d_vocproc_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2166 sizeof(mvm_d_vocproc_cmd) - APR_HDR_SIZE);
2167 pr_debug("mvm_d_vocproc_cmd pkt size = %d\n",
2168 mvm_d_vocproc_cmd.hdr.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002169 mvm_d_vocproc_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002170 mvm_d_vocproc_cmd.hdr.dest_port = mvm_handle;
2171 mvm_d_vocproc_cmd.hdr.token = 0;
Helen Zeng69b00962011-07-08 11:38:36 -07002172 mvm_d_vocproc_cmd.hdr.opcode = VSS_IMVM_CMD_DETACH_VOCPROC;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002173 mvm_d_vocproc_cmd.mvm_detach_cvp_handle.handle = cvp_handle;
2174
2175 v->mvm_state = CMD_STATUS_FAIL;
2176 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_d_vocproc_cmd);
2177 if (ret < 0) {
Helen Zeng69b00962011-07-08 11:38:36 -07002178 pr_err("Fail in sending VSS_IMVM_CMD_DETACH_VOCPROC\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002179 goto fail;
2180 }
2181 ret = wait_event_timeout(v->mvm_wait,
2182 (v->mvm_state == CMD_STATUS_SUCCESS),
2183 msecs_to_jiffies(TIMEOUT_MS));
2184 if (!ret) {
2185 pr_err("%s: wait_event timeout\n", __func__);
2186 goto fail;
2187 }
2188
Helen Zeng29eb7442011-06-20 11:06:29 -07002189 /* deregister cvp and vol cal */
2190 voice_send_cvp_deregister_vol_cal_table_cmd(v);
2191 voice_send_cvp_deregister_cal_cmd(v);
2192 voice_send_cvp_unmap_memory_cmd(v);
2193
2194 /* deregister cvs cal */
2195 voice_send_cvs_deregister_cal_cmd(v);
2196 voice_send_cvs_unmap_memory_cmd(v);
2197
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002198 /* destrop cvp session */
2199 cvp_destroy_session_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2200 APR_HDR_LEN(APR_HDR_SIZE),
2201 APR_PKT_VER);
2202 cvp_destroy_session_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2203 sizeof(cvp_destroy_session_cmd) - APR_HDR_SIZE);
2204 pr_debug("cvp_destroy_session_cmd pkt size = %d\n",
2205 cvp_destroy_session_cmd.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002206 cvp_destroy_session_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002207 cvp_destroy_session_cmd.dest_port = cvp_handle;
2208 cvp_destroy_session_cmd.token = 0;
2209 cvp_destroy_session_cmd.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
2210
2211 v->cvp_state = CMD_STATUS_FAIL;
2212 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_destroy_session_cmd);
2213 if (ret < 0) {
2214 pr_err("Fail in sending APRV2_IBASIC_CMD_DESTROY_SESSION\n");
2215 goto fail;
2216 }
2217 ret = wait_event_timeout(v->cvp_wait,
2218 (v->cvp_state == CMD_STATUS_SUCCESS),
2219 msecs_to_jiffies(TIMEOUT_MS));
2220 if (!ret) {
2221 pr_err("%s: wait_event timeout\n", __func__);
2222 goto fail;
2223 }
2224
Ben Romberger13b74ab2011-07-18 17:36:32 -07002225 rtac_remove_voice(voice_get_cvs_handle(v));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002226 cvp_handle = 0;
2227 voice_set_cvp_handle(v, cvp_handle);
2228
2229 return 0;
2230
2231fail:
2232 return -EINVAL;
2233}
2234
2235static int voice_send_mute_cmd(struct voice_data *v)
2236{
2237 struct cvs_set_mute_cmd cvs_mute_cmd;
2238 int ret = 0;
2239 void *apr_cvs;
2240 u16 cvs_handle;
2241
2242 if (v == NULL) {
2243 pr_err("%s: v is NULL\n", __func__);
2244 return -EINVAL;
2245 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07002246 apr_cvs = common.apr_q6_cvs;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002247
2248 if (!apr_cvs) {
2249 pr_err("%s: apr_cvs is NULL.\n", __func__);
2250 return -EINVAL;
2251 }
2252 cvs_handle = voice_get_cvs_handle(v);
2253
2254 /* send mute/unmute to cvs */
2255 cvs_mute_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2256 APR_HDR_LEN(APR_HDR_SIZE),
2257 APR_PKT_VER);
2258 cvs_mute_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2259 sizeof(cvs_mute_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002260 cvs_mute_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002261 cvs_mute_cmd.hdr.dest_port = cvs_handle;
2262 cvs_mute_cmd.hdr.token = 0;
2263 cvs_mute_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_MUTE;
2264 cvs_mute_cmd.cvs_set_mute.direction = 0; /*tx*/
2265 cvs_mute_cmd.cvs_set_mute.mute_flag = v->dev_tx.mute;
2266
2267 pr_info(" mute value =%d\n", cvs_mute_cmd.cvs_set_mute.mute_flag);
2268 v->cvs_state = CMD_STATUS_FAIL;
2269 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_mute_cmd);
2270 if (ret < 0) {
2271 pr_err("Fail: send STREAM SET MUTE\n");
2272 goto fail;
2273 }
2274 ret = wait_event_timeout(v->cvs_wait,
2275 (v->cvs_state == CMD_STATUS_SUCCESS),
2276 msecs_to_jiffies(TIMEOUT_MS));
2277 if (!ret)
2278 pr_err("%s: wait_event timeout\n", __func__);
2279
2280 return 0;
2281fail:
2282 return -EINVAL;
2283}
2284
Helen Zeng68656932011-11-02 18:08:23 -07002285static int voice_send_rx_device_mute_cmd(struct voice_data *v)
2286{
2287 struct cvp_set_mute_cmd cvp_mute_cmd;
2288 int ret = 0;
2289 void *apr_cvp;
2290 u16 cvp_handle;
2291 if (v == NULL) {
2292 pr_err("%s: v is NULL\n", __func__);
2293 return -EINVAL;
2294 }
2295 apr_cvp = common.apr_q6_cvp;
2296
2297 if (!apr_cvp) {
2298 pr_err("%s: apr_cvp is NULL.\n", __func__);
2299 return -EINVAL;
2300 }
2301 cvp_handle = voice_get_cvp_handle(v);
2302
2303 cvp_mute_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2304 APR_HDR_LEN(APR_HDR_SIZE),
2305 APR_PKT_VER);
2306 cvp_mute_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2307 sizeof(cvp_mute_cmd) - APR_HDR_SIZE);
2308 cvp_mute_cmd.hdr.src_port = v->session_id;
2309 cvp_mute_cmd.hdr.dest_port = cvp_handle;
2310 cvp_mute_cmd.hdr.token = 0;
2311 cvp_mute_cmd.hdr.opcode = VSS_IVOCPROC_CMD_SET_MUTE;
2312 cvp_mute_cmd.cvp_set_mute.direction = 1;
2313 cvp_mute_cmd.cvp_set_mute.mute_flag = v->dev_rx.mute;
2314 v->cvp_state = CMD_STATUS_FAIL;
2315 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_mute_cmd);
2316 if (ret < 0) {
2317 pr_err("Fail in sending RX device mute cmd\n");
2318 return -EINVAL;
2319 }
2320 ret = wait_event_timeout(v->cvp_wait,
2321 (v->cvp_state == CMD_STATUS_SUCCESS),
2322 msecs_to_jiffies(TIMEOUT_MS));
2323 if (!ret) {
2324 pr_err("%s: wait_event timeout\n", __func__);
2325 return -EINVAL;
2326 }
2327 return 0;
2328}
2329
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002330static int voice_send_vol_index_cmd(struct voice_data *v)
2331{
2332 struct cvp_set_rx_volume_index_cmd cvp_vol_cmd;
2333 int ret = 0;
2334 void *apr_cvp;
2335 u16 cvp_handle;
2336 if (v == NULL) {
2337 pr_err("%s: v is NULL\n", __func__);
2338 return -EINVAL;
2339 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07002340 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002341
2342 if (!apr_cvp) {
2343 pr_err("%s: apr_cvp is NULL.\n", __func__);
2344 return -EINVAL;
2345 }
2346 cvp_handle = voice_get_cvp_handle(v);
2347
2348 /* send volume index to cvp */
2349 cvp_vol_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2350 APR_HDR_LEN(APR_HDR_SIZE),
2351 APR_PKT_VER);
2352 cvp_vol_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2353 sizeof(cvp_vol_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002354 cvp_vol_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002355 cvp_vol_cmd.hdr.dest_port = cvp_handle;
2356 cvp_vol_cmd.hdr.token = 0;
2357 cvp_vol_cmd.hdr.opcode = VSS_IVOCPROC_CMD_SET_RX_VOLUME_INDEX;
2358 cvp_vol_cmd.cvp_set_vol_idx.vol_index = v->dev_rx.volume;
2359 v->cvp_state = CMD_STATUS_FAIL;
2360 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_vol_cmd);
2361 if (ret < 0) {
2362 pr_err("Fail in sending RX VOL INDEX\n");
2363 return -EINVAL;
2364 }
2365 ret = wait_event_timeout(v->cvp_wait,
2366 (v->cvp_state == CMD_STATUS_SUCCESS),
2367 msecs_to_jiffies(TIMEOUT_MS));
2368 if (!ret) {
2369 pr_err("%s: wait_event timeout\n", __func__);
2370 return -EINVAL;
2371 }
2372 return 0;
2373}
2374
Helen Zenge3d716a2011-10-14 16:32:16 -07002375static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode)
2376{
2377 int ret = 0;
2378 void *apr_cvs;
2379 u16 cvs_handle;
2380
2381 struct cvs_start_record_cmd cvs_start_record;
2382
2383 if (v == NULL) {
2384 pr_err("%s: v is NULL\n", __func__);
2385 return -EINVAL;
2386 }
2387 apr_cvs = common.apr_q6_cvs;
2388
2389 if (!apr_cvs) {
2390 pr_err("%s: apr_cvs is NULL.\n", __func__);
2391 return -EINVAL;
2392 }
2393
2394 cvs_handle = voice_get_cvs_handle(v);
2395
2396 if (!v->rec_info.recording) {
2397 cvs_start_record.hdr.hdr_field = APR_HDR_FIELD(
2398 APR_MSG_TYPE_SEQ_CMD,
2399 APR_HDR_LEN(APR_HDR_SIZE),
2400 APR_PKT_VER);
2401 cvs_start_record.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2402 sizeof(cvs_start_record) - APR_HDR_SIZE);
2403 cvs_start_record.hdr.src_port = v->session_id;
2404 cvs_start_record.hdr.dest_port = cvs_handle;
2405 cvs_start_record.hdr.token = 0;
2406 cvs_start_record.hdr.opcode = VSS_ISTREAM_CMD_START_RECORD;
2407
2408 if (rec_mode == VOC_REC_UPLINK) {
2409 cvs_start_record.rec_mode.rx_tap_point =
2410 VSS_TAP_POINT_NONE;
2411 cvs_start_record.rec_mode.tx_tap_point =
2412 VSS_TAP_POINT_STREAM_END;
2413 } else if (rec_mode == VOC_REC_DOWNLINK) {
2414 cvs_start_record.rec_mode.rx_tap_point =
2415 VSS_TAP_POINT_STREAM_END;
2416 cvs_start_record.rec_mode.tx_tap_point =
2417 VSS_TAP_POINT_NONE;
2418 } else if (rec_mode == VOC_REC_BOTH) {
2419 cvs_start_record.rec_mode.rx_tap_point =
2420 VSS_TAP_POINT_STREAM_END;
2421 cvs_start_record.rec_mode.tx_tap_point =
2422 VSS_TAP_POINT_STREAM_END;
2423 } else {
2424 pr_err("%s: Invalid in-call rec_mode %d\n", __func__,
2425 rec_mode);
2426
2427 ret = -EINVAL;
2428 goto fail;
2429 }
2430
2431 v->cvs_state = CMD_STATUS_FAIL;
2432
2433 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_start_record);
2434 if (ret < 0) {
2435 pr_err("%s: Error %d sending START_RECORD\n", __func__,
2436 ret);
2437
2438 goto fail;
2439 }
2440
2441 ret = wait_event_timeout(v->cvs_wait,
2442 (v->cvs_state == CMD_STATUS_SUCCESS),
2443 msecs_to_jiffies(TIMEOUT_MS));
2444
2445 if (!ret) {
2446 pr_err("%s: wait_event timeout\n", __func__);
2447
2448 goto fail;
2449 }
2450 v->rec_info.recording = 1;
2451 } else {
2452 pr_debug("%s: Start record already sent\n", __func__);
2453 }
2454
2455 return 0;
2456
2457fail:
2458 return ret;
2459}
2460
2461static int voice_cvs_stop_record(struct voice_data *v)
2462{
2463 int ret = 0;
2464 void *apr_cvs;
2465 u16 cvs_handle;
2466 struct apr_hdr cvs_stop_record;
2467
2468 if (v == NULL) {
2469 pr_err("%s: v is NULL\n", __func__);
2470 return -EINVAL;
2471 }
2472 apr_cvs = common.apr_q6_cvs;
2473
2474 if (!apr_cvs) {
2475 pr_err("%s: apr_cvs is NULL.\n", __func__);
2476 return -EINVAL;
2477 }
2478
2479 cvs_handle = voice_get_cvs_handle(v);
2480
2481 if (v->rec_info.recording) {
2482 cvs_stop_record.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2483 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2484 cvs_stop_record.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2485 sizeof(cvs_stop_record) - APR_HDR_SIZE);
2486 cvs_stop_record.src_port = v->session_id;
2487 cvs_stop_record.dest_port = cvs_handle;
2488 cvs_stop_record.token = 0;
2489 cvs_stop_record.opcode = VSS_ISTREAM_CMD_STOP_RECORD;
2490
2491 v->cvs_state = CMD_STATUS_FAIL;
2492
2493 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_stop_record);
2494 if (ret < 0) {
2495 pr_err("%s: Error %d sending STOP_RECORD\n",
2496 __func__, ret);
2497
2498 goto fail;
2499 }
2500
2501 ret = wait_event_timeout(v->cvs_wait,
2502 (v->cvs_state == CMD_STATUS_SUCCESS),
2503 msecs_to_jiffies(TIMEOUT_MS));
2504 if (!ret) {
2505 pr_err("%s: wait_event timeout\n", __func__);
2506
2507 goto fail;
2508 }
2509 v->rec_info.recording = 0;
2510 } else {
2511 pr_debug("%s: Stop record already sent\n", __func__);
2512 }
2513
2514 return 0;
2515
2516fail:
2517
2518 return ret;
2519}
2520
2521int voc_start_record(uint32_t port_id, uint32_t set)
2522{
2523 int ret = 0;
2524 int rec_mode = 0;
2525 u16 cvs_handle;
2526 int i, rec_set = 0;
2527
2528 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
2529 struct voice_data *v = &common.voice[i];
2530 pr_debug("%s: i:%d port_id: %d, set: %d\n",
2531 __func__, i, port_id, set);
2532
2533 mutex_lock(&v->lock);
2534 rec_mode = v->rec_info.rec_mode;
2535 rec_set = set;
2536 if (set) {
2537 if ((v->rec_route_state.ul_flag != 0) &&
2538 (v->rec_route_state.dl_flag != 0)) {
2539 pr_debug("%s: i=%d, rec mode already set.\n",
2540 __func__, i);
2541 mutex_unlock(&v->lock);
2542 if (i < MAX_VOC_SESSIONS)
2543 continue;
2544 else
2545 return 0;
2546 }
2547
2548 if (port_id == VOICE_RECORD_TX) {
2549 if ((v->rec_route_state.ul_flag == 0)
2550 && (v->rec_route_state.dl_flag == 0)) {
2551 rec_mode = VOC_REC_UPLINK;
2552 v->rec_route_state.ul_flag = 1;
2553 } else if ((v->rec_route_state.ul_flag == 0)
2554 && (v->rec_route_state.dl_flag != 0)) {
2555 voice_cvs_stop_record(v);
2556 rec_mode = VOC_REC_BOTH;
2557 v->rec_route_state.ul_flag = 1;
2558 }
2559 } else if (port_id == VOICE_RECORD_RX) {
2560 if ((v->rec_route_state.ul_flag == 0)
2561 && (v->rec_route_state.dl_flag == 0)) {
2562 rec_mode = VOC_REC_DOWNLINK;
2563 v->rec_route_state.dl_flag = 1;
2564 } else if ((v->rec_route_state.ul_flag != 0)
2565 && (v->rec_route_state.dl_flag == 0)) {
2566 voice_cvs_stop_record(v);
2567 rec_mode = VOC_REC_BOTH;
2568 v->rec_route_state.dl_flag = 1;
2569 }
2570 }
2571 rec_set = 1;
2572 } else {
2573 if ((v->rec_route_state.ul_flag == 0) &&
2574 (v->rec_route_state.dl_flag == 0)) {
2575 pr_debug("%s: i=%d, rec already stops.\n",
2576 __func__, i);
2577 mutex_unlock(&v->lock);
2578 if (i < MAX_VOC_SESSIONS)
2579 continue;
2580 else
2581 return 0;
2582 }
2583
2584 if (port_id == VOICE_RECORD_TX) {
2585 if ((v->rec_route_state.ul_flag != 0)
2586 && (v->rec_route_state.dl_flag == 0)) {
2587 v->rec_route_state.ul_flag = 0;
2588 rec_set = 0;
2589 } else if ((v->rec_route_state.ul_flag != 0)
2590 && (v->rec_route_state.dl_flag != 0)) {
2591 voice_cvs_stop_record(v);
2592 v->rec_route_state.ul_flag = 0;
2593 rec_mode = VOC_REC_DOWNLINK;
2594 rec_set = 1;
2595 }
2596 } else if (port_id == VOICE_RECORD_RX) {
2597 if ((v->rec_route_state.ul_flag == 0)
2598 && (v->rec_route_state.dl_flag != 0)) {
2599 v->rec_route_state.dl_flag = 0;
2600 rec_set = 0;
2601 } else if ((v->rec_route_state.ul_flag != 0)
2602 && (v->rec_route_state.dl_flag != 0)) {
2603 voice_cvs_stop_record(v);
2604 v->rec_route_state.dl_flag = 0;
2605 rec_mode = VOC_REC_UPLINK;
2606 rec_set = 1;
2607 }
2608 }
2609 }
2610 pr_debug("%s: i=%d, mode =%d, set =%d\n", __func__,
2611 i, rec_mode, rec_set);
2612 cvs_handle = voice_get_cvs_handle(v);
2613
2614 if (cvs_handle != 0) {
2615 if (rec_set)
2616 ret = voice_cvs_start_record(v, rec_mode);
2617 else
2618 ret = voice_cvs_stop_record(v);
2619 }
2620
2621 /* Cache the value */
2622 v->rec_info.rec_enable = rec_set;
2623 v->rec_info.rec_mode = rec_mode;
2624
2625 mutex_unlock(&v->lock);
2626 }
2627
2628 return ret;
2629}
2630
Helen Zeng0705a5f2011-10-14 15:29:52 -07002631static int voice_cvs_start_playback(struct voice_data *v)
2632{
2633 int ret = 0;
2634 struct apr_hdr cvs_start_playback;
2635 void *apr_cvs;
2636 u16 cvs_handle;
2637
2638 if (v == NULL) {
2639 pr_err("%s: v is NULL\n", __func__);
2640 return -EINVAL;
2641 }
2642 apr_cvs = common.apr_q6_cvs;
2643
2644 if (!apr_cvs) {
2645 pr_err("%s: apr_cvs is NULL.\n", __func__);
2646 return -EINVAL;
2647 }
2648
2649 cvs_handle = voice_get_cvs_handle(v);
2650
2651 if (!v->music_info.playing && v->music_info.count) {
2652 cvs_start_playback.hdr_field = APR_HDR_FIELD(
2653 APR_MSG_TYPE_SEQ_CMD,
2654 APR_HDR_LEN(APR_HDR_SIZE),
2655 APR_PKT_VER);
2656 cvs_start_playback.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2657 sizeof(cvs_start_playback) - APR_HDR_SIZE);
2658 cvs_start_playback.src_port = v->session_id;
2659 cvs_start_playback.dest_port = cvs_handle;
2660 cvs_start_playback.token = 0;
2661 cvs_start_playback.opcode = VSS_ISTREAM_CMD_START_PLAYBACK;
2662
2663 v->cvs_state = CMD_STATUS_FAIL;
2664
2665 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_start_playback);
2666
2667 if (ret < 0) {
2668 pr_err("%s: Error %d sending START_PLAYBACK\n",
2669 __func__, ret);
2670
2671 goto fail;
2672 }
2673
2674 ret = wait_event_timeout(v->cvs_wait,
2675 (v->cvs_state == CMD_STATUS_SUCCESS),
2676 msecs_to_jiffies(TIMEOUT_MS));
2677 if (!ret) {
2678 pr_err("%s: wait_event timeout\n", __func__);
2679
2680 goto fail;
2681 }
2682
2683 v->music_info.playing = 1;
2684 } else {
2685 pr_debug("%s: Start playback already sent\n", __func__);
2686 }
2687
2688 return 0;
2689
2690fail:
2691 return ret;
2692}
2693
2694static int voice_cvs_stop_playback(struct voice_data *v)
2695{
2696 int ret = 0;
2697 struct apr_hdr cvs_stop_playback;
2698 void *apr_cvs;
2699 u16 cvs_handle;
2700
2701 if (v == NULL) {
2702 pr_err("%s: v is NULL\n", __func__);
2703 return -EINVAL;
2704 }
2705 apr_cvs = common.apr_q6_cvs;
2706
2707 if (!apr_cvs) {
2708 pr_err("%s: apr_cvs is NULL.\n", __func__);
2709 return -EINVAL;
2710 }
2711
2712 cvs_handle = voice_get_cvs_handle(v);
2713
2714 if (v->music_info.playing && ((!v->music_info.count) ||
2715 (v->music_info.force))) {
2716 cvs_stop_playback.hdr_field =
2717 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2718 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2719 cvs_stop_playback.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2720 sizeof(cvs_stop_playback) - APR_HDR_SIZE);
2721 cvs_stop_playback.src_port = v->session_id;
2722 cvs_stop_playback.dest_port = cvs_handle;
2723 cvs_stop_playback.token = 0;
2724
2725 cvs_stop_playback.opcode = VSS_ISTREAM_CMD_STOP_PLAYBACK;
2726
2727 v->cvs_state = CMD_STATUS_FAIL;
2728
2729 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_stop_playback);
2730 if (ret < 0) {
2731 pr_err("%s: Error %d sending STOP_PLAYBACK\n",
2732 __func__, ret);
2733
2734
2735 goto fail;
2736 }
2737
2738 ret = wait_event_timeout(v->cvs_wait,
2739 (v->cvs_state == CMD_STATUS_SUCCESS),
2740 msecs_to_jiffies(TIMEOUT_MS));
2741 if (!ret) {
2742 pr_err("%s: wait_event timeout\n", __func__);
2743
2744 goto fail;
2745 }
2746
2747 v->music_info.playing = 0;
2748 v->music_info.force = 0;
2749 } else {
2750 pr_debug("%s: Stop playback already sent\n", __func__);
2751 }
2752
2753 return 0;
2754
2755fail:
2756 return ret;
2757}
2758
2759int voc_start_playback(uint32_t set)
2760{
2761 int ret = 0;
2762 u16 cvs_handle;
2763 int i;
2764
2765
2766 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
2767 struct voice_data *v = &common.voice[i];
2768
2769 mutex_lock(&v->lock);
2770 v->music_info.play_enable = set;
2771 if (set)
2772 v->music_info.count++;
2773 else
2774 v->music_info.count--;
2775 pr_debug("%s: music_info count =%d\n", __func__,
2776 v->music_info.count);
2777
2778 cvs_handle = voice_get_cvs_handle(v);
2779 if (cvs_handle != 0) {
2780 if (set)
2781 ret = voice_cvs_start_playback(v);
2782 else
2783 ret = voice_cvs_stop_playback(v);
2784 }
2785
2786 mutex_unlock(&v->lock);
2787 }
2788
2789 return ret;
2790}
2791
Neema Shetty2c07eb52011-08-21 20:33:52 -07002792int voc_disable_cvp(uint16_t session_id)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002793{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002794 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002795 int ret = 0;
2796
Neema Shetty2c07eb52011-08-21 20:33:52 -07002797 if (v == NULL) {
2798 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2799
2800 return -EINVAL;
2801 }
2802
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002803 mutex_lock(&v->lock);
2804
2805 if (v->voc_state == VOC_RUN) {
Laxminath Kasam5b9cf0f2011-12-09 15:24:20 +05302806 if (v->dev_tx.port_id != RT_PROXY_PORT_001_TX &&
2807 v->dev_rx.port_id != RT_PROXY_PORT_001_RX)
2808 afe_sidetone(v->dev_tx.port_id, v->dev_rx.port_id,
2809 0, 0);
Ben Romberger13b74ab2011-07-18 17:36:32 -07002810
2811 rtac_remove_voice(voice_get_cvs_handle(v));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002812 /* send cmd to dsp to disable vocproc */
2813 ret = voice_send_disable_vocproc_cmd(v);
2814 if (ret < 0) {
2815 pr_err("%s: disable vocproc failed\n", __func__);
2816 goto fail;
2817 }
Helen Zeng29eb7442011-06-20 11:06:29 -07002818
2819 /* deregister cvp and vol cal */
2820 voice_send_cvp_deregister_vol_cal_table_cmd(v);
2821 voice_send_cvp_deregister_cal_cmd(v);
2822 voice_send_cvp_unmap_memory_cmd(v);
2823
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002824 v->voc_state = VOC_CHANGE;
2825 }
2826
2827fail: mutex_unlock(&v->lock);
2828
2829 return ret;
2830}
2831
Neema Shetty2c07eb52011-08-21 20:33:52 -07002832int voc_enable_cvp(uint16_t session_id)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002833{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002834 struct voice_data *v = voice_get_session(session_id);
Helen Zengbd58e2c2011-07-01 16:24:31 -07002835 struct sidetone_cal sidetone_cal_data;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002836 int ret = 0;
2837
Neema Shetty2c07eb52011-08-21 20:33:52 -07002838 if (v == NULL) {
2839 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2840
2841 return -EINVAL;
2842 }
2843
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002844 mutex_lock(&v->lock);
2845
2846 if (v->voc_state == VOC_CHANGE) {
2847 ret = voice_send_set_device_cmd(v);
2848 if (ret < 0) {
2849 pr_err("%s: set device failed\n", __func__);
2850 goto fail;
2851 }
Helen Zeng29eb7442011-06-20 11:06:29 -07002852 /* send cvp and vol cal */
2853 ret = voice_send_cvp_map_memory_cmd(v);
2854 if (!ret) {
2855 voice_send_cvp_register_cal_cmd(v);
2856 voice_send_cvp_register_vol_cal_table_cmd(v);
2857 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002858 ret = voice_send_enable_vocproc_cmd(v);
2859 if (ret < 0) {
Neema Shetty2c07eb52011-08-21 20:33:52 -07002860 pr_err("%s: enable vocproc failed\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002861 goto fail;
Helen Zengcc65b5b2011-07-06 19:14:48 -07002862
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002863 }
Helen Zengcc65b5b2011-07-06 19:14:48 -07002864 /* send tty mode if tty device is used */
2865 voice_send_tty_mode_cmd(v);
2866
Helen Zeng44d4d272011-08-10 14:49:20 -07002867 /* enable widevoice if wv_enable is set */
2868 if (v->wv_enable)
2869 voice_send_set_widevoice_enable_cmd(v);
2870
Helen Zengbb49c702011-09-06 14:09:13 -07002871 /* enable slowtalk */
2872 if (v->st_enable)
Helen Zeng4e531942011-12-17 21:14:40 -08002873 voice_send_set_pp_enable_cmd(v,
2874 MODULE_ID_VOICE_MODULE_ST,
2875 v->st_enable);
2876 /* enable FENS */
2877 if (v->fens_enable)
2878 voice_send_set_pp_enable_cmd(v,
2879 MODULE_ID_VOICE_MODULE_FENS,
2880 v->fens_enable);
Helen Zengbb49c702011-09-06 14:09:13 -07002881
Helen Zengbd58e2c2011-07-01 16:24:31 -07002882 get_sidetone_cal(&sidetone_cal_data);
Laxminath Kasam5b9cf0f2011-12-09 15:24:20 +05302883 if (v->dev_tx.port_id != RT_PROXY_PORT_001_TX &&
2884 v->dev_rx.port_id != RT_PROXY_PORT_001_RX) {
2885 ret = afe_sidetone(v->dev_tx.port_id,
2886 v->dev_rx.port_id,
2887 sidetone_cal_data.enable,
2888 sidetone_cal_data.gain);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002889
Laxminath Kasam5b9cf0f2011-12-09 15:24:20 +05302890 if (ret < 0)
2891 pr_err("%s: AFE command sidetone failed\n",
2892 __func__);
2893 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002894
Ben Romberger13b74ab2011-07-18 17:36:32 -07002895 rtac_add_voice(voice_get_cvs_handle(v),
2896 voice_get_cvp_handle(v),
Ben Rombergerc5d6a372011-09-22 18:01:49 -07002897 v->dev_rx.port_id, v->dev_tx.port_id,
2898 v->session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002899 v->voc_state = VOC_RUN;
2900 }
2901
2902fail:
2903 mutex_unlock(&v->lock);
2904
2905 return ret;
2906}
2907
Neema Shetty2c07eb52011-08-21 20:33:52 -07002908int voc_set_tx_mute(uint16_t session_id, uint32_t dir, uint32_t mute)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002909{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002910 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002911 int ret = 0;
2912
Neema Shetty2c07eb52011-08-21 20:33:52 -07002913 if (v == NULL) {
2914 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2915
2916 return -EINVAL;
2917 }
2918
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002919 mutex_lock(&v->lock);
2920
2921 v->dev_tx.mute = mute;
2922
2923 if (v->voc_state == VOC_RUN)
2924 ret = voice_send_mute_cmd(v);
2925
2926 mutex_unlock(&v->lock);
2927
2928 return ret;
2929}
2930
Helen Zeng68656932011-11-02 18:08:23 -07002931int voc_set_rx_device_mute(uint16_t session_id, uint32_t mute)
2932{
2933 struct voice_data *v = voice_get_session(session_id);
2934 int ret = 0;
2935
2936 if (v == NULL) {
2937 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2938
2939 return -EINVAL;
2940 }
2941
2942 mutex_lock(&v->lock);
2943
2944 v->dev_rx.mute = mute;
2945
2946 if (v->voc_state == VOC_RUN)
2947 ret = voice_send_rx_device_mute_cmd(v);
2948
2949 mutex_unlock(&v->lock);
2950
2951 return ret;
2952}
2953
2954int voc_get_rx_device_mute(uint16_t session_id)
2955{
2956 struct voice_data *v = voice_get_session(session_id);
2957 int ret = 0;
2958
2959 if (v == NULL) {
2960 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2961
2962 return -EINVAL;
2963 }
2964
2965 mutex_lock(&v->lock);
2966
2967 ret = v->dev_rx.mute;
2968
2969 mutex_unlock(&v->lock);
2970
2971 return ret;
2972}
2973
Neema Shetty2c07eb52011-08-21 20:33:52 -07002974int voc_set_tty_mode(uint16_t session_id, uint8_t tty_mode)
Helen Zengcc65b5b2011-07-06 19:14:48 -07002975{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002976 struct voice_data *v = voice_get_session(session_id);
Helen Zengcc65b5b2011-07-06 19:14:48 -07002977 int ret = 0;
2978
Neema Shetty2c07eb52011-08-21 20:33:52 -07002979 if (v == NULL) {
2980 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2981
2982 return -EINVAL;
2983 }
2984
Helen Zengcc65b5b2011-07-06 19:14:48 -07002985 mutex_lock(&v->lock);
2986
2987 v->tty_mode = tty_mode;
2988
2989 mutex_unlock(&v->lock);
2990
2991 return ret;
2992}
2993
Neema Shetty2c07eb52011-08-21 20:33:52 -07002994uint8_t voc_get_tty_mode(uint16_t session_id)
Helen Zengcc65b5b2011-07-06 19:14:48 -07002995{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002996 struct voice_data *v = voice_get_session(session_id);
Helen Zengcc65b5b2011-07-06 19:14:48 -07002997 int ret = 0;
2998
Neema Shetty2c07eb52011-08-21 20:33:52 -07002999 if (v == NULL) {
3000 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3001
3002 return -EINVAL;
3003 }
3004
Helen Zengcc65b5b2011-07-06 19:14:48 -07003005 mutex_lock(&v->lock);
3006
3007 ret = v->tty_mode;
3008
3009 mutex_unlock(&v->lock);
3010
3011 return ret;
3012}
3013
Neema Shetty2c07eb52011-08-21 20:33:52 -07003014int voc_set_widevoice_enable(uint16_t session_id, uint32_t wv_enable)
Helen Zeng44d4d272011-08-10 14:49:20 -07003015{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003016 struct voice_data *v = voice_get_session(session_id);
Helen Zengb73acce2011-09-15 18:23:01 -07003017 u16 mvm_handle;
Helen Zeng44d4d272011-08-10 14:49:20 -07003018 int ret = 0;
3019
Neema Shetty2c07eb52011-08-21 20:33:52 -07003020 if (v == NULL) {
3021 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3022
3023 return -EINVAL;
3024 }
3025
Helen Zeng44d4d272011-08-10 14:49:20 -07003026 mutex_lock(&v->lock);
3027
3028 v->wv_enable = wv_enable;
3029
Helen Zengb73acce2011-09-15 18:23:01 -07003030 mvm_handle = voice_get_mvm_handle(v);
3031
3032 if (mvm_handle != 0)
3033 voice_send_set_widevoice_enable_cmd(v);
3034
Helen Zeng44d4d272011-08-10 14:49:20 -07003035 mutex_unlock(&v->lock);
3036
3037 return ret;
3038}
3039
Neema Shetty2c07eb52011-08-21 20:33:52 -07003040uint32_t voc_get_widevoice_enable(uint16_t session_id)
Helen Zeng44d4d272011-08-10 14:49:20 -07003041{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003042 struct voice_data *v = voice_get_session(session_id);
Helen Zeng44d4d272011-08-10 14:49:20 -07003043 int ret = 0;
3044
Neema Shetty2c07eb52011-08-21 20:33:52 -07003045 if (v == NULL) {
3046 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3047
3048 return -EINVAL;
3049 }
3050
Helen Zeng44d4d272011-08-10 14:49:20 -07003051 mutex_lock(&v->lock);
3052
3053 ret = v->wv_enable;
3054
3055 mutex_unlock(&v->lock);
3056
3057 return ret;
3058}
3059
Helen Zeng4e531942011-12-17 21:14:40 -08003060int voc_set_pp_enable(uint16_t session_id, uint32_t module_id, uint32_t enable)
Helen Zengbb49c702011-09-06 14:09:13 -07003061{
3062 struct voice_data *v = voice_get_session(session_id);
3063 int ret = 0;
3064
3065 if (v == NULL) {
3066 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3067
3068 return -EINVAL;
3069 }
3070
3071 mutex_lock(&v->lock);
Helen Zeng4e531942011-12-17 21:14:40 -08003072 if (module_id == MODULE_ID_VOICE_MODULE_ST)
3073 v->st_enable = enable;
3074 else if (module_id == MODULE_ID_VOICE_MODULE_FENS)
3075 v->fens_enable = enable;
Helen Zengbb49c702011-09-06 14:09:13 -07003076
Helen Zeng4e531942011-12-17 21:14:40 -08003077 if (v->voc_state == VOC_RUN) {
3078 if (module_id == MODULE_ID_VOICE_MODULE_ST)
3079 ret = voice_send_set_pp_enable_cmd(v,
3080 MODULE_ID_VOICE_MODULE_ST,
3081 enable);
3082 else if (module_id == MODULE_ID_VOICE_MODULE_FENS)
3083 ret = voice_send_set_pp_enable_cmd(v,
3084 MODULE_ID_VOICE_MODULE_FENS,
3085 enable);
3086 }
Helen Zengbb49c702011-09-06 14:09:13 -07003087 mutex_unlock(&v->lock);
3088
3089 return ret;
3090}
3091
Helen Zeng4e531942011-12-17 21:14:40 -08003092int voc_get_pp_enable(uint16_t session_id, uint32_t module_id)
Helen Zengbb49c702011-09-06 14:09:13 -07003093{
3094 struct voice_data *v = voice_get_session(session_id);
3095 int ret = 0;
3096
3097 if (v == NULL) {
3098 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3099
3100 return -EINVAL;
3101 }
3102
3103 mutex_lock(&v->lock);
Helen Zeng4e531942011-12-17 21:14:40 -08003104 if (module_id == MODULE_ID_VOICE_MODULE_ST)
3105 ret = v->st_enable;
3106 else if (module_id == MODULE_ID_VOICE_MODULE_FENS)
3107 ret = v->fens_enable;
Helen Zengbb49c702011-09-06 14:09:13 -07003108
3109 mutex_unlock(&v->lock);
3110
3111 return ret;
3112}
3113
Neema Shetty2c07eb52011-08-21 20:33:52 -07003114int voc_set_rx_vol_index(uint16_t session_id, uint32_t dir, uint32_t vol_idx)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003115{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003116 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003117 int ret = 0;
3118
Neema Shetty2c07eb52011-08-21 20:33:52 -07003119 if (v == NULL) {
3120 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3121
3122 return -EINVAL;
3123 }
3124
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003125 mutex_lock(&v->lock);
3126
3127 v->dev_rx.volume = vol_idx;
3128
3129 if (v->voc_state == VOC_RUN)
3130 ret = voice_send_vol_index_cmd(v);
3131
3132 mutex_unlock(&v->lock);
3133
3134 return ret;
3135}
3136
Neema Shetty2c07eb52011-08-21 20:33:52 -07003137int voc_set_rxtx_port(uint16_t session_id, uint32_t port_id, uint32_t dev_type)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003138{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003139 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003140
Neema Shetty2c07eb52011-08-21 20:33:52 -07003141 if (v == NULL) {
3142 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3143
3144 return -EINVAL;
3145 }
3146
3147 pr_debug("%s: port_id=%d, type=%d\n", __func__, port_id, dev_type);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003148
3149 mutex_lock(&v->lock);
3150
3151 if (dev_type == DEV_RX)
3152 v->dev_rx.port_id = port_id;
3153 else
3154 v->dev_tx.port_id = port_id;
3155
3156 mutex_unlock(&v->lock);
3157
Neema Shetty2c07eb52011-08-21 20:33:52 -07003158 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003159}
3160
Neema Shetty2c07eb52011-08-21 20:33:52 -07003161int voc_set_route_flag(uint16_t session_id, uint8_t path_dir, uint8_t set)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003162{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003163 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003164
Neema Shetty2c07eb52011-08-21 20:33:52 -07003165 if (v == NULL) {
3166 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3167
3168 return -EINVAL;
3169 }
3170
3171 pr_debug("%s: path_dir=%d, set=%d\n", __func__, path_dir, set);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003172
3173 mutex_lock(&v->lock);
3174
3175 if (path_dir == RX_PATH)
3176 v->voc_route_state.rx_route_flag = set;
3177 else
3178 v->voc_route_state.tx_route_flag = set;
3179
3180 mutex_unlock(&v->lock);
3181
Neema Shetty2c07eb52011-08-21 20:33:52 -07003182 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003183}
3184
Neema Shetty2c07eb52011-08-21 20:33:52 -07003185uint8_t voc_get_route_flag(uint16_t session_id, uint8_t path_dir)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003186{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003187 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003188 int ret = 0;
3189
Neema Shetty2c07eb52011-08-21 20:33:52 -07003190 if (v == NULL) {
3191 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3192
3193 return 0;
3194 }
3195
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003196 mutex_lock(&v->lock);
3197
3198 if (path_dir == RX_PATH)
3199 ret = v->voc_route_state.rx_route_flag;
3200 else
3201 ret = v->voc_route_state.tx_route_flag;
3202
3203 mutex_unlock(&v->lock);
3204
3205 return ret;
3206}
3207
Neema Shetty2c07eb52011-08-21 20:33:52 -07003208int voc_end_voice_call(uint16_t session_id)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003209{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003210 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003211 int ret = 0;
3212
Neema Shetty2c07eb52011-08-21 20:33:52 -07003213 if (v == NULL) {
3214 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3215
3216 return -EINVAL;
3217 }
3218
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003219 mutex_lock(&v->lock);
3220
3221 if (v->voc_state == VOC_RUN) {
Laxminath Kasam5b9cf0f2011-12-09 15:24:20 +05303222 if (v->dev_tx.port_id != RT_PROXY_PORT_001_TX &&
3223 v->dev_rx.port_id != RT_PROXY_PORT_001_RX)
3224 afe_sidetone(v->dev_tx.port_id, v->dev_rx.port_id,
3225 0, 0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003226 ret = voice_destroy_vocproc(v);
3227 if (ret < 0)
3228 pr_err("%s: destroy voice failed\n", __func__);
3229 voice_destroy_mvm_cvs_session(v);
3230
3231 v->voc_state = VOC_RELEASE;
3232 }
3233 mutex_unlock(&v->lock);
3234 return ret;
3235}
3236
Neema Shetty2c07eb52011-08-21 20:33:52 -07003237int voc_start_voice_call(uint16_t session_id)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003238{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003239 struct voice_data *v = voice_get_session(session_id);
Helen Zengbd58e2c2011-07-01 16:24:31 -07003240 struct sidetone_cal sidetone_cal_data;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003241 int ret = 0;
3242
Neema Shetty2c07eb52011-08-21 20:33:52 -07003243 if (v == NULL) {
3244 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3245
3246 return -EINVAL;
3247 }
3248
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003249 mutex_lock(&v->lock);
3250
3251 if ((v->voc_state == VOC_INIT) ||
3252 (v->voc_state == VOC_RELEASE)) {
Neema Shetty2c07eb52011-08-21 20:33:52 -07003253 ret = voice_apr_register();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003254 if (ret < 0) {
3255 pr_err("%s: apr register failed\n", __func__);
3256 goto fail;
3257 }
3258 ret = voice_create_mvm_cvs_session(v);
3259 if (ret < 0) {
3260 pr_err("create mvm and cvs failed\n");
3261 goto fail;
3262 }
3263 ret = voice_setup_vocproc(v);
3264 if (ret < 0) {
3265 pr_err("setup voice failed\n");
3266 goto fail;
3267 }
3268 ret = voice_send_start_voice_cmd(v);
3269 if (ret < 0) {
3270 pr_err("start voice failed\n");
3271 goto fail;
3272 }
Helen Zengbd58e2c2011-07-01 16:24:31 -07003273 get_sidetone_cal(&sidetone_cal_data);
Laxminath Kasam5b9cf0f2011-12-09 15:24:20 +05303274 if (v->dev_tx.port_id != RT_PROXY_PORT_001_TX &&
3275 v->dev_rx.port_id != RT_PROXY_PORT_001_RX) {
3276 ret = afe_sidetone(v->dev_tx.port_id,
Helen Zengbd58e2c2011-07-01 16:24:31 -07003277 v->dev_rx.port_id,
3278 sidetone_cal_data.enable,
3279 sidetone_cal_data.gain);
Laxminath Kasam5b9cf0f2011-12-09 15:24:20 +05303280 if (ret < 0)
3281 pr_err("AFE command sidetone failed\n");
3282 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003283
3284 v->voc_state = VOC_RUN;
3285 }
3286
3287fail: mutex_unlock(&v->lock);
3288 return ret;
3289}
3290
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003291void voc_register_mvs_cb(ul_cb_fn ul_cb,
3292 dl_cb_fn dl_cb,
3293 void *private_data)
3294{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003295 common.mvs_info.ul_cb = ul_cb;
3296 common.mvs_info.dl_cb = dl_cb;
3297 common.mvs_info.private_data = private_data;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003298}
3299
3300void voc_config_vocoder(uint32_t media_type,
3301 uint32_t rate,
Helen Zengff97bec2012-02-20 14:30:50 -08003302 uint32_t network_type,
3303 uint32_t dtx_mode)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003304{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003305 common.mvs_info.media_type = media_type;
3306 common.mvs_info.rate = rate;
3307 common.mvs_info.network_type = network_type;
Helen Zengff97bec2012-02-20 14:30:50 -08003308 common.mvs_info.dtx_mode = dtx_mode;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003309}
3310
3311static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv)
3312{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003313 uint32_t *ptr = NULL;
3314 struct common_data *c = NULL;
3315 struct voice_data *v = NULL;
Neema Shetty07477582011-09-02 17:35:44 -07003316 int i = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003317
3318 if ((data == NULL) || (priv == NULL)) {
3319 pr_err("%s: data or priv is NULL\n", __func__);
3320 return -EINVAL;
3321 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07003322
3323 c = priv;
3324
3325 pr_debug("%s: session_id 0x%x\n", __func__, data->dest_port);
3326
3327 v = voice_get_session(data->dest_port);
3328 if (v == NULL) {
3329 pr_err("%s: v is NULL\n", __func__);
3330
3331 return -EINVAL;
3332 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003333
3334 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
3335 data->payload_size, data->opcode);
3336
Neema Shetty07477582011-09-02 17:35:44 -07003337 if (data->opcode == RESET_EVENTS) {
3338 pr_debug("%s: Reset event received in Voice service\n",
3339 __func__);
3340
3341 apr_reset(c->apr_q6_mvm);
3342 c->apr_q6_mvm = NULL;
3343
3344 /* Sub-system restart is applicable to all sessions. */
3345 for (i = 0; i < MAX_VOC_SESSIONS; i++)
3346 c->voice[i].mvm_handle = 0;
3347
3348 return 0;
3349 }
3350
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003351 if (data->opcode == APR_BASIC_RSP_RESULT) {
3352 if (data->payload_size) {
3353 ptr = data->payload;
3354
3355 pr_info("%x %x\n", ptr[0], ptr[1]);
3356 /* ping mvm service ACK */
3357 switch (ptr[0]) {
3358 case VSS_IMVM_CMD_CREATE_PASSIVE_CONTROL_SESSION:
3359 case VSS_IMVM_CMD_CREATE_FULL_CONTROL_SESSION:
3360 /* Passive session is used for CS call
3361 * Full session is used for VoIP call. */
3362 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
3363 if (!ptr[1]) {
3364 pr_debug("%s: MVM handle is %d\n",
3365 __func__, data->src_port);
3366 voice_set_mvm_handle(v, data->src_port);
3367 } else
3368 pr_err("got NACK for sending \
3369 MVM create session \n");
3370 v->mvm_state = CMD_STATUS_SUCCESS;
3371 wake_up(&v->mvm_wait);
3372 break;
3373 case VSS_IMVM_CMD_START_VOICE:
Helen Zeng69b00962011-07-08 11:38:36 -07003374 case VSS_IMVM_CMD_ATTACH_VOCPROC:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003375 case VSS_IMVM_CMD_STOP_VOICE:
Helen Zeng69b00962011-07-08 11:38:36 -07003376 case VSS_IMVM_CMD_DETACH_VOCPROC:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003377 case VSS_ISTREAM_CMD_SET_TTY_MODE:
3378 case APRV2_IBASIC_CMD_DESTROY_SESSION:
3379 case VSS_IMVM_CMD_ATTACH_STREAM:
3380 case VSS_IMVM_CMD_DETACH_STREAM:
3381 case VSS_ICOMMON_CMD_SET_NETWORK:
3382 case VSS_ICOMMON_CMD_SET_VOICE_TIMING:
Helen Zeng44d4d272011-08-10 14:49:20 -07003383 case VSS_IWIDEVOICE_CMD_SET_WIDEVOICE:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003384 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
3385 v->mvm_state = CMD_STATUS_SUCCESS;
3386 wake_up(&v->mvm_wait);
3387 break;
3388 default:
3389 pr_debug("%s: not match cmd = 0x%x\n",
3390 __func__, ptr[0]);
3391 break;
3392 }
3393 }
3394 }
3395
3396 return 0;
3397}
3398
3399static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv)
3400{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003401 uint32_t *ptr = NULL;
3402 struct common_data *c = NULL;
3403 struct voice_data *v = NULL;
Neema Shetty07477582011-09-02 17:35:44 -07003404 int i = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003405
3406 if ((data == NULL) || (priv == NULL)) {
3407 pr_err("%s: data or priv is NULL\n", __func__);
3408 return -EINVAL;
3409 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07003410
3411 c = priv;
3412
3413 pr_debug("%s: session_id 0x%x\n", __func__, data->dest_port);
3414
3415 v = voice_get_session(data->dest_port);
3416 if (v == NULL) {
3417 pr_err("%s: v is NULL\n", __func__);
3418
3419 return -EINVAL;
3420 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003421
3422 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
3423 data->payload_size, data->opcode);
3424
Neema Shetty07477582011-09-02 17:35:44 -07003425 if (data->opcode == RESET_EVENTS) {
3426 pr_debug("%s: Reset event received in Voice service\n",
3427 __func__);
3428
3429 apr_reset(c->apr_q6_cvs);
3430 c->apr_q6_cvs = NULL;
3431
3432 /* Sub-system restart is applicable to all sessions. */
3433 for (i = 0; i < MAX_VOC_SESSIONS; i++)
3434 c->voice[i].cvs_handle = 0;
3435
3436 return 0;
3437 }
3438
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003439 if (data->opcode == APR_BASIC_RSP_RESULT) {
3440 if (data->payload_size) {
3441 ptr = data->payload;
3442
3443 pr_info("%x %x\n", ptr[0], ptr[1]);
3444 /*response from CVS */
3445 switch (ptr[0]) {
3446 case VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION:
3447 case VSS_ISTREAM_CMD_CREATE_FULL_CONTROL_SESSION:
3448 if (!ptr[1]) {
3449 pr_debug("%s: CVS handle is %d\n",
3450 __func__, data->src_port);
3451 voice_set_cvs_handle(v, data->src_port);
3452 } else
3453 pr_err("got NACK for sending \
3454 CVS create session \n");
3455 v->cvs_state = CMD_STATUS_SUCCESS;
3456 wake_up(&v->cvs_wait);
3457 break;
3458 case VSS_ISTREAM_CMD_SET_MUTE:
3459 case VSS_ISTREAM_CMD_SET_MEDIA_TYPE:
3460 case VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE:
3461 case VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE:
3462 case VSS_ISTREAM_CMD_SET_ENC_DTX_MODE:
3463 case VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE:
3464 case APRV2_IBASIC_CMD_DESTROY_SESSION:
Helen Zeng29eb7442011-06-20 11:06:29 -07003465 case VSS_ISTREAM_CMD_REGISTER_CALIBRATION_DATA:
3466 case VSS_ISTREAM_CMD_DEREGISTER_CALIBRATION_DATA:
3467 case VSS_ICOMMON_CMD_MAP_MEMORY:
3468 case VSS_ICOMMON_CMD_UNMAP_MEMORY:
Helen Zengbb49c702011-09-06 14:09:13 -07003469 case VSS_ICOMMON_CMD_SET_UI_PROPERTY:
Helen Zeng0705a5f2011-10-14 15:29:52 -07003470 case VSS_ISTREAM_CMD_START_PLAYBACK:
3471 case VSS_ISTREAM_CMD_STOP_PLAYBACK:
Helen Zenge3d716a2011-10-14 16:32:16 -07003472 case VSS_ISTREAM_CMD_START_RECORD:
3473 case VSS_ISTREAM_CMD_STOP_RECORD:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003474 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
3475 v->cvs_state = CMD_STATUS_SUCCESS;
3476 wake_up(&v->cvs_wait);
3477 break;
Ben Romberger13b74ab2011-07-18 17:36:32 -07003478 case VOICE_CMD_SET_PARAM:
3479 rtac_make_voice_callback(RTAC_CVS, ptr,
3480 data->payload_size);
3481 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003482 default:
3483 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
3484 break;
3485 }
3486 }
3487 } else if (data->opcode == VSS_ISTREAM_EVT_SEND_ENC_BUFFER) {
3488 uint32_t *voc_pkt = data->payload;
3489 uint32_t pkt_len = data->payload_size;
3490
Neema Shetty2c07eb52011-08-21 20:33:52 -07003491 if (voc_pkt != NULL && c->mvs_info.ul_cb != NULL) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003492 pr_debug("%s: Media type is 0x%x\n",
3493 __func__, voc_pkt[0]);
3494
3495 /* Remove media ID from payload. */
3496 voc_pkt++;
3497 pkt_len = pkt_len - 4;
3498
Neema Shetty2c07eb52011-08-21 20:33:52 -07003499 c->mvs_info.ul_cb((uint8_t *)voc_pkt,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003500 pkt_len,
Neema Shetty2c07eb52011-08-21 20:33:52 -07003501 c->mvs_info.private_data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003502 } else
3503 pr_err("%s: voc_pkt is 0x%x ul_cb is 0x%x\n",
3504 __func__, (unsigned int)voc_pkt,
Neema Shetty2c07eb52011-08-21 20:33:52 -07003505 (unsigned int) c->mvs_info.ul_cb);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003506 } else if (data->opcode == VSS_ISTREAM_EVT_REQUEST_DEC_BUFFER) {
3507 struct cvs_send_dec_buf_cmd send_dec_buf;
3508 int ret = 0;
3509 uint32_t pkt_len = 0;
3510
Neema Shetty2c07eb52011-08-21 20:33:52 -07003511 if (c->mvs_info.dl_cb != NULL) {
3512 send_dec_buf.dec_buf.media_id = c->mvs_info.media_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003513
Neema Shetty2c07eb52011-08-21 20:33:52 -07003514 c->mvs_info.dl_cb(
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003515 (uint8_t *)&send_dec_buf.dec_buf.packet_data,
3516 &pkt_len,
Neema Shetty2c07eb52011-08-21 20:33:52 -07003517 c->mvs_info.private_data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003518
3519 send_dec_buf.hdr.hdr_field =
3520 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
3521 APR_HDR_LEN(APR_HDR_SIZE),
3522 APR_PKT_VER);
3523 send_dec_buf.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
3524 sizeof(send_dec_buf.dec_buf.media_id) + pkt_len);
Neema Shetty2c07eb52011-08-21 20:33:52 -07003525 send_dec_buf.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003526 send_dec_buf.hdr.dest_port = voice_get_cvs_handle(v);
3527 send_dec_buf.hdr.token = 0;
3528 send_dec_buf.hdr.opcode =
3529 VSS_ISTREAM_EVT_SEND_DEC_BUFFER;
3530
Neema Shetty2c07eb52011-08-21 20:33:52 -07003531 ret = apr_send_pkt(c->apr_q6_cvs,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003532 (uint32_t *) &send_dec_buf);
3533 if (ret < 0) {
3534 pr_err("%s: Error %d sending DEC_BUF\n",
3535 __func__, ret);
3536 goto fail;
3537 }
3538 } else
3539 pr_debug("%s: dl_cb is NULL\n", __func__);
Ben Romberger13b74ab2011-07-18 17:36:32 -07003540 } else if (data->opcode == VSS_ISTREAM_EVT_SEND_DEC_BUFFER) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003541 pr_debug("Send dec buf resp\n");
Ben Romberger13b74ab2011-07-18 17:36:32 -07003542 } else if (data->opcode == VOICE_EVT_GET_PARAM_ACK) {
3543 rtac_make_voice_callback(RTAC_CVS, data->payload,
3544 data->payload_size);
3545 } else
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003546 pr_debug("Unknown opcode 0x%x\n", data->opcode);
3547
3548fail:
3549 return 0;
3550}
3551
3552static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv)
3553{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003554 uint32_t *ptr = NULL;
3555 struct common_data *c = NULL;
3556 struct voice_data *v = NULL;
Neema Shetty07477582011-09-02 17:35:44 -07003557 int i = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003558
3559 if ((data == NULL) || (priv == NULL)) {
3560 pr_err("%s: data or priv is NULL\n", __func__);
3561 return -EINVAL;
3562 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07003563
3564 c = priv;
3565
3566 v = voice_get_session(data->dest_port);
3567 if (v == NULL) {
3568 pr_err("%s: v is NULL\n", __func__);
3569
3570 return -EINVAL;
3571 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003572
3573 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
3574 data->payload_size, data->opcode);
3575
Neema Shetty07477582011-09-02 17:35:44 -07003576 if (data->opcode == RESET_EVENTS) {
3577 pr_debug("%s: Reset event received in Voice service\n",
3578 __func__);
3579
3580 apr_reset(c->apr_q6_cvp);
3581 c->apr_q6_cvp = NULL;
3582
3583 /* Sub-system restart is applicable to all sessions. */
3584 for (i = 0; i < MAX_VOC_SESSIONS; i++)
3585 c->voice[i].cvp_handle = 0;
3586
3587 return 0;
3588 }
3589
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003590 if (data->opcode == APR_BASIC_RSP_RESULT) {
3591 if (data->payload_size) {
3592 ptr = data->payload;
3593
3594 pr_info("%x %x\n", ptr[0], ptr[1]);
3595
3596 switch (ptr[0]) {
3597 case VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION:
3598 /*response from CVP */
3599 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
3600 if (!ptr[1]) {
3601 voice_set_cvp_handle(v, data->src_port);
3602 pr_debug("cvphdl=%d\n", data->src_port);
3603 } else
3604 pr_err("got NACK from CVP create \
3605 session response\n");
3606 v->cvp_state = CMD_STATUS_SUCCESS;
3607 wake_up(&v->cvp_wait);
3608 break;
3609 case VSS_IVOCPROC_CMD_SET_DEVICE:
3610 case VSS_IVOCPROC_CMD_SET_RX_VOLUME_INDEX:
3611 case VSS_IVOCPROC_CMD_ENABLE:
3612 case VSS_IVOCPROC_CMD_DISABLE:
3613 case APRV2_IBASIC_CMD_DESTROY_SESSION:
Helen Zeng29eb7442011-06-20 11:06:29 -07003614 case VSS_IVOCPROC_CMD_REGISTER_VOLUME_CAL_TABLE:
3615 case VSS_IVOCPROC_CMD_DEREGISTER_VOLUME_CAL_TABLE:
3616 case VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA:
3617 case VSS_IVOCPROC_CMD_DEREGISTER_CALIBRATION_DATA:
3618 case VSS_ICOMMON_CMD_MAP_MEMORY:
3619 case VSS_ICOMMON_CMD_UNMAP_MEMORY:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003620 v->cvp_state = CMD_STATUS_SUCCESS;
3621 wake_up(&v->cvp_wait);
3622 break;
Ben Romberger13b74ab2011-07-18 17:36:32 -07003623 case VOICE_CMD_SET_PARAM:
3624 rtac_make_voice_callback(RTAC_CVP, ptr,
3625 data->payload_size);
3626 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003627 default:
3628 pr_debug("%s: not match cmd = 0x%x\n",
3629 __func__, ptr[0]);
3630 break;
3631 }
3632 }
Ben Romberger13b74ab2011-07-18 17:36:32 -07003633 } else if (data->opcode == VOICE_EVT_GET_PARAM_ACK) {
3634 rtac_make_voice_callback(RTAC_CVP, data->payload,
3635 data->payload_size);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003636 }
3637 return 0;
3638}
3639
3640
3641static int __init voice_init(void)
3642{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003643 int rc = 0, i = 0;
3644
3645 memset(&common, 0, sizeof(struct common_data));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003646
3647 /* set default value */
Neema Shetty2c07eb52011-08-21 20:33:52 -07003648 common.default_mute_val = 1; /* default is mute */
3649 common.default_vol_val = 0;
3650 common.default_sample_val = 8000;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003651
3652 /* Initialize MVS info. */
Neema Shetty2c07eb52011-08-21 20:33:52 -07003653 common.mvs_info.network_type = VSS_NETWORK_ID_DEFAULT;
3654
3655 mutex_init(&common.common_lock);
3656
3657 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
3658 common.voice[i].session_id = SESSION_ID_BASE + i;
3659
3660 /* initialize dev_rx and dev_tx */
3661 common.voice[i].dev_rx.volume = common.default_vol_val;
Helen Zeng68656932011-11-02 18:08:23 -07003662 common.voice[i].dev_rx.mute = 0;
Neema Shetty2c07eb52011-08-21 20:33:52 -07003663 common.voice[i].dev_tx.mute = common.default_mute_val;
3664
3665 common.voice[i].dev_tx.port_id = 1;
3666 common.voice[i].dev_rx.port_id = 0;
3667 common.voice[i].sidetone_gain = 0x512;
3668
3669 common.voice[i].voc_state = VOC_INIT;
3670
3671 init_waitqueue_head(&common.voice[i].mvm_wait);
3672 init_waitqueue_head(&common.voice[i].cvs_wait);
3673 init_waitqueue_head(&common.voice[i].cvp_wait);
3674
3675 mutex_init(&common.voice[i].lock);
3676 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003677
3678 return rc;
3679}
3680
3681device_initcall(voice_init);