blob: 532d92bdf96e27d3857404efab5cff94bc08a4b1 [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
665static int voice_config_cvs_vocoder(struct voice_data *v)
666{
667 int ret = 0;
668 void *apr_cvs;
669 u16 cvs_handle;
670 /* Set media type. */
671 struct cvs_set_media_type_cmd cvs_set_media_cmd;
672
673 if (v == NULL) {
674 pr_err("%s: v is NULL\n", __func__);
675 return -EINVAL;
676 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700677 apr_cvs = common.apr_q6_cvs;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700678
679 if (!apr_cvs) {
680 pr_err("%s: apr_cvs is NULL.\n", __func__);
681 return -EINVAL;
682 }
683
684 cvs_handle = voice_get_cvs_handle(v);
685
686 cvs_set_media_cmd.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_media_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
690 sizeof(cvs_set_media_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700691 cvs_set_media_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700692 cvs_set_media_cmd.hdr.dest_port = cvs_handle;
693 cvs_set_media_cmd.hdr.token = 0;
694 cvs_set_media_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_MEDIA_TYPE;
Neema Shetty2c07eb52011-08-21 20:33:52 -0700695 cvs_set_media_cmd.media_type.tx_media_id = common.mvs_info.media_type;
696 cvs_set_media_cmd.media_type.rx_media_id = common.mvs_info.media_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700697
698 v->cvs_state = CMD_STATUS_FAIL;
699
700 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_media_cmd);
701 if (ret < 0) {
702 pr_err("%s: Error %d sending SET_MEDIA_TYPE\n",
703 __func__, ret);
704
705 goto fail;
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
713 goto fail;
714 }
715 /* Set encoder properties. */
Neema Shetty2c07eb52011-08-21 20:33:52 -0700716 switch (common.mvs_info.media_type) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700717 case VSS_MEDIA_ID_EVRC_MODEM: {
718 struct cvs_set_cdma_enc_minmax_rate_cmd cvs_set_cdma_rate;
719
720 pr_debug("Setting EVRC min-max rate\n");
721
722 cvs_set_cdma_rate.hdr.hdr_field =
723 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
724 APR_HDR_LEN(APR_HDR_SIZE),
725 APR_PKT_VER);
726 cvs_set_cdma_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
727 sizeof(cvs_set_cdma_rate) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700728 cvs_set_cdma_rate.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700729 cvs_set_cdma_rate.hdr.dest_port = cvs_handle;
730 cvs_set_cdma_rate.hdr.token = 0;
731 cvs_set_cdma_rate.hdr.opcode =
732 VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE;
Neema Shetty2c07eb52011-08-21 20:33:52 -0700733 cvs_set_cdma_rate.cdma_rate.min_rate = common.mvs_info.rate;
734 cvs_set_cdma_rate.cdma_rate.max_rate = common.mvs_info.rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700735
736 v->cvs_state = CMD_STATUS_FAIL;
737
738 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_cdma_rate);
739 if (ret < 0) {
740 pr_err("%s: Error %d sending SET_EVRC_MINMAX_RATE\n",
741 __func__, ret);
742 goto fail;
743 }
744 ret = wait_event_timeout(v->cvs_wait,
745 (v->cvs_state == CMD_STATUS_SUCCESS),
746 msecs_to_jiffies(TIMEOUT_MS));
747 if (!ret) {
748 pr_err("%s: wait_event timeout\n", __func__);
749
750 goto fail;
751 }
752 break;
753 }
754 case VSS_MEDIA_ID_AMR_NB_MODEM: {
755 struct cvs_set_amr_enc_rate_cmd cvs_set_amr_rate;
756 struct cvs_set_enc_dtx_mode_cmd cvs_set_dtx;
757
758 pr_debug("Setting AMR rate\n");
759
760 cvs_set_amr_rate.hdr.hdr_field =
761 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
762 APR_HDR_LEN(APR_HDR_SIZE),
763 APR_PKT_VER);
764 cvs_set_amr_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
765 sizeof(cvs_set_amr_rate) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700766 cvs_set_amr_rate.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700767 cvs_set_amr_rate.hdr.dest_port = cvs_handle;
768 cvs_set_amr_rate.hdr.token = 0;
769 cvs_set_amr_rate.hdr.opcode =
770 VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE;
Neema Shetty2c07eb52011-08-21 20:33:52 -0700771 cvs_set_amr_rate.amr_rate.mode = common.mvs_info.rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700772
773 v->cvs_state = CMD_STATUS_FAIL;
774
775 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_amr_rate);
776 if (ret < 0) {
777 pr_err("%s: Error %d sending SET_AMR_RATE\n",
778 __func__, ret);
779 goto fail;
780 }
781 ret = wait_event_timeout(v->cvs_wait,
782 (v->cvs_state == CMD_STATUS_SUCCESS),
783 msecs_to_jiffies(TIMEOUT_MS));
784 if (!ret) {
785 pr_err("%s: wait_event timeout\n", __func__);
786 goto fail;
787 }
788 /* Disable DTX */
789 pr_debug("Disabling DTX\n");
790
791 cvs_set_dtx.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
792 APR_HDR_LEN(APR_HDR_SIZE),
793 APR_PKT_VER);
794 cvs_set_dtx.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
795 sizeof(cvs_set_dtx) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700796 cvs_set_dtx.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700797 cvs_set_dtx.hdr.dest_port = cvs_handle;
798 cvs_set_dtx.hdr.token = 0;
799 cvs_set_dtx.hdr.opcode = VSS_ISTREAM_CMD_SET_ENC_DTX_MODE;
800 cvs_set_dtx.dtx_mode.enable = 0;
801
802 v->cvs_state = CMD_STATUS_FAIL;
803
804 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_dtx);
805 if (ret < 0) {
806 pr_err("%s: Error %d sending SET_DTX\n",
807 __func__, ret);
808 goto fail;
809 }
810 ret = wait_event_timeout(v->cvs_wait,
811 (v->cvs_state == CMD_STATUS_SUCCESS),
812 msecs_to_jiffies(TIMEOUT_MS));
813 if (!ret) {
814 pr_err("%s: wait_event timeout\n", __func__);
815 goto fail;
816 }
817 break;
818 }
819 case VSS_MEDIA_ID_AMR_WB_MODEM: {
820 struct cvs_set_amrwb_enc_rate_cmd cvs_set_amrwb_rate;
821 struct cvs_set_enc_dtx_mode_cmd cvs_set_dtx;
822
823 pr_debug("Setting AMR WB rate\n");
824
825 cvs_set_amrwb_rate.hdr.hdr_field =
826 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
827 APR_HDR_LEN(APR_HDR_SIZE),
828 APR_PKT_VER);
829 cvs_set_amrwb_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
830 sizeof(cvs_set_amrwb_rate) -
831 APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700832 cvs_set_amrwb_rate.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700833 cvs_set_amrwb_rate.hdr.dest_port = cvs_handle;
834 cvs_set_amrwb_rate.hdr.token = 0;
835 cvs_set_amrwb_rate.hdr.opcode =
836 VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE;
Neema Shetty2c07eb52011-08-21 20:33:52 -0700837 cvs_set_amrwb_rate.amrwb_rate.mode = common.mvs_info.rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700838
839 v->cvs_state = CMD_STATUS_FAIL;
840
841 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_amrwb_rate);
842 if (ret < 0) {
843 pr_err("%s: Error %d sending SET_AMRWB_RATE\n",
844 __func__, ret);
845 goto fail;
846 }
847 ret = wait_event_timeout(v->cvs_wait,
848 (v->cvs_state == CMD_STATUS_SUCCESS),
849 msecs_to_jiffies(TIMEOUT_MS));
850 if (!ret) {
851 pr_err("%s: wait_event timeout\n", __func__);
852 goto fail;
853 }
854 /* Disable DTX */
855 pr_debug("Disabling DTX\n");
856
857 cvs_set_dtx.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
858 APR_HDR_LEN(APR_HDR_SIZE),
859 APR_PKT_VER);
860 cvs_set_dtx.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
861 sizeof(cvs_set_dtx) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700862 cvs_set_dtx.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700863 cvs_set_dtx.hdr.dest_port = cvs_handle;
864 cvs_set_dtx.hdr.token = 0;
865 cvs_set_dtx.hdr.opcode = VSS_ISTREAM_CMD_SET_ENC_DTX_MODE;
866 cvs_set_dtx.dtx_mode.enable = 0;
867
868 v->cvs_state = CMD_STATUS_FAIL;
869
870 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_dtx);
871 if (ret < 0) {
872 pr_err("%s: Error %d sending SET_DTX\n",
873 __func__, ret);
874 goto fail;
875 }
876 ret = wait_event_timeout(v->cvs_wait,
877 (v->cvs_state == CMD_STATUS_SUCCESS),
878 msecs_to_jiffies(TIMEOUT_MS));
879 if (!ret) {
880 pr_err("%s: wait_event timeout\n", __func__);
881 goto fail;
882 }
883 break;
884 }
885 case VSS_MEDIA_ID_G729:
886 case VSS_MEDIA_ID_G711_ALAW:
887 case VSS_MEDIA_ID_G711_MULAW: {
888 struct cvs_set_enc_dtx_mode_cmd cvs_set_dtx;
889 /* Disable DTX */
890 pr_debug("Disabling DTX\n");
891
892 cvs_set_dtx.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
893 APR_HDR_LEN(APR_HDR_SIZE),
894 APR_PKT_VER);
895 cvs_set_dtx.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
896 sizeof(cvs_set_dtx) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700897 cvs_set_dtx.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700898 cvs_set_dtx.hdr.dest_port = cvs_handle;
899 cvs_set_dtx.hdr.token = 0;
900 cvs_set_dtx.hdr.opcode = VSS_ISTREAM_CMD_SET_ENC_DTX_MODE;
901 cvs_set_dtx.dtx_mode.enable = 0;
902
903 v->cvs_state = CMD_STATUS_FAIL;
904
905 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_dtx);
906 if (ret < 0) {
907 pr_err("%s: Error %d sending SET_DTX\n",
908 __func__, ret);
909 goto fail;
910 }
911 ret = wait_event_timeout(v->cvs_wait,
912 (v->cvs_state == CMD_STATUS_SUCCESS),
913 msecs_to_jiffies(TIMEOUT_MS));
914 if (!ret) {
915 pr_err("%s: wait_event timeout\n", __func__);
916 goto fail;
917 }
918 break;
919 }
920 default:
921 /* Do nothing. */
922 break;
923 }
924 return 0;
925
926fail:
927 return -EINVAL;
928}
929
930static int voice_send_start_voice_cmd(struct voice_data *v)
931{
932 struct apr_hdr mvm_start_voice_cmd;
933 int ret = 0;
934 void *apr_mvm;
935 u16 mvm_handle;
936
937 if (v == NULL) {
938 pr_err("%s: v is NULL\n", __func__);
939 return -EINVAL;
940 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700941 apr_mvm = common.apr_q6_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700942
943 if (!apr_mvm) {
944 pr_err("%s: apr_mvm is NULL.\n", __func__);
945 return -EINVAL;
946 }
947 mvm_handle = voice_get_mvm_handle(v);
948
949 mvm_start_voice_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
950 APR_HDR_LEN(APR_HDR_SIZE),
951 APR_PKT_VER);
952 mvm_start_voice_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
953 sizeof(mvm_start_voice_cmd) - APR_HDR_SIZE);
954 pr_debug("send mvm_start_voice_cmd pkt size = %d\n",
955 mvm_start_voice_cmd.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700956 mvm_start_voice_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700957 mvm_start_voice_cmd.dest_port = mvm_handle;
958 mvm_start_voice_cmd.token = 0;
959 mvm_start_voice_cmd.opcode = VSS_IMVM_CMD_START_VOICE;
960
961 v->mvm_state = CMD_STATUS_FAIL;
962 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_start_voice_cmd);
963 if (ret < 0) {
964 pr_err("Fail in sending VSS_IMVM_CMD_START_VOICE\n");
965 goto fail;
966 }
967 ret = wait_event_timeout(v->mvm_wait,
968 (v->mvm_state == CMD_STATUS_SUCCESS),
969 msecs_to_jiffies(TIMEOUT_MS));
970 if (!ret) {
971 pr_err("%s: wait_event timeout\n", __func__);
972 goto fail;
973 }
974 return 0;
975fail:
976 return -EINVAL;
977}
978
979static int voice_send_disable_vocproc_cmd(struct voice_data *v)
980{
981 struct apr_hdr cvp_disable_cmd;
982 int ret = 0;
983 void *apr_cvp;
984 u16 cvp_handle;
985
986 if (v == NULL) {
987 pr_err("%s: v is NULL\n", __func__);
988 return -EINVAL;
989 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700990 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700991
992 if (!apr_cvp) {
993 pr_err("%s: apr regist failed\n", __func__);
994 return -EINVAL;
995 }
996 cvp_handle = voice_get_cvp_handle(v);
997
998 /* disable vocproc and wait for respose */
999 cvp_disable_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1000 APR_HDR_LEN(APR_HDR_SIZE),
1001 APR_PKT_VER);
1002 cvp_disable_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1003 sizeof(cvp_disable_cmd) - APR_HDR_SIZE);
1004 pr_debug("cvp_disable_cmd pkt size = %d, cvp_handle=%d\n",
1005 cvp_disable_cmd.pkt_size, cvp_handle);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001006 cvp_disable_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001007 cvp_disable_cmd.dest_port = cvp_handle;
1008 cvp_disable_cmd.token = 0;
1009 cvp_disable_cmd.opcode = VSS_IVOCPROC_CMD_DISABLE;
1010
1011 v->cvp_state = CMD_STATUS_FAIL;
1012 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_disable_cmd);
1013 if (ret < 0) {
1014 pr_err("Fail in sending VSS_IVOCPROC_CMD_DISABLE\n");
1015 goto fail;
1016 }
1017 ret = wait_event_timeout(v->cvp_wait,
1018 (v->cvp_state == CMD_STATUS_SUCCESS),
1019 msecs_to_jiffies(TIMEOUT_MS));
1020 if (!ret) {
1021 pr_err("%s: wait_event timeout\n", __func__);
1022 goto fail;
1023 }
1024
1025 return 0;
1026fail:
1027 return -EINVAL;
1028}
1029
1030static int voice_send_set_device_cmd(struct voice_data *v)
1031{
1032 struct cvp_set_device_cmd cvp_setdev_cmd;
1033 int ret = 0;
1034 void *apr_cvp;
1035 u16 cvp_handle;
1036
1037 if (v == NULL) {
1038 pr_err("%s: v is NULL\n", __func__);
1039 return -EINVAL;
1040 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001041 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001042
1043 if (!apr_cvp) {
1044 pr_err("%s: apr_cvp is NULL.\n", __func__);
1045 return -EINVAL;
1046 }
1047 cvp_handle = voice_get_cvp_handle(v);
1048
1049 /* set device and wait for response */
1050 cvp_setdev_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1051 APR_HDR_LEN(APR_HDR_SIZE),
1052 APR_PKT_VER);
1053 cvp_setdev_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1054 sizeof(cvp_setdev_cmd) - APR_HDR_SIZE);
1055 pr_debug(" send create cvp setdev, pkt size = %d\n",
1056 cvp_setdev_cmd.hdr.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001057 cvp_setdev_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001058 cvp_setdev_cmd.hdr.dest_port = cvp_handle;
1059 cvp_setdev_cmd.hdr.token = 0;
1060 cvp_setdev_cmd.hdr.opcode = VSS_IVOCPROC_CMD_SET_DEVICE;
1061
1062 /* Use default topology if invalid value in ACDB */
1063 cvp_setdev_cmd.cvp_set_device.tx_topology_id =
1064 get_voice_tx_topology();
1065 if (cvp_setdev_cmd.cvp_set_device.tx_topology_id == 0)
1066 cvp_setdev_cmd.cvp_set_device.tx_topology_id =
1067 VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
1068
1069 cvp_setdev_cmd.cvp_set_device.rx_topology_id =
1070 get_voice_rx_topology();
1071 if (cvp_setdev_cmd.cvp_set_device.rx_topology_id == 0)
1072 cvp_setdev_cmd.cvp_set_device.rx_topology_id =
1073 VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
1074 cvp_setdev_cmd.cvp_set_device.tx_port_id = v->dev_tx.port_id;
1075 cvp_setdev_cmd.cvp_set_device.rx_port_id = v->dev_rx.port_id;
1076 pr_debug("topology=%d , tx_port_id=%d, rx_port_id=%d\n",
1077 cvp_setdev_cmd.cvp_set_device.tx_topology_id,
1078 cvp_setdev_cmd.cvp_set_device.tx_port_id,
1079 cvp_setdev_cmd.cvp_set_device.rx_port_id);
1080
1081 v->cvp_state = CMD_STATUS_FAIL;
1082 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_setdev_cmd);
1083 if (ret < 0) {
1084 pr_err("Fail in sending VOCPROC_FULL_CONTROL_SESSION\n");
1085 goto fail;
1086 }
1087 pr_debug("wait for cvp create session event\n");
1088 ret = wait_event_timeout(v->cvp_wait,
1089 (v->cvp_state == CMD_STATUS_SUCCESS),
1090 msecs_to_jiffies(TIMEOUT_MS));
1091 if (!ret) {
1092 pr_err("%s: wait_event timeout\n", __func__);
1093 goto fail;
1094 }
1095
1096 return 0;
1097fail:
1098 return -EINVAL;
1099}
1100
1101static int voice_send_stop_voice_cmd(struct voice_data *v)
1102{
1103 struct apr_hdr mvm_stop_voice_cmd;
1104 int ret = 0;
1105 void *apr_mvm;
1106 u16 mvm_handle;
1107
1108 if (v == NULL) {
1109 pr_err("%s: v is NULL\n", __func__);
1110 return -EINVAL;
1111 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001112 apr_mvm = common.apr_q6_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001113
1114 if (!apr_mvm) {
1115 pr_err("%s: apr_mvm is NULL.\n", __func__);
1116 return -EINVAL;
1117 }
1118 mvm_handle = voice_get_mvm_handle(v);
1119
1120 mvm_stop_voice_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1121 APR_HDR_LEN(APR_HDR_SIZE),
1122 APR_PKT_VER);
1123 mvm_stop_voice_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1124 sizeof(mvm_stop_voice_cmd) - APR_HDR_SIZE);
1125 pr_debug("send mvm_stop_voice_cmd pkt size = %d\n",
1126 mvm_stop_voice_cmd.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001127 mvm_stop_voice_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001128 mvm_stop_voice_cmd.dest_port = mvm_handle;
1129 mvm_stop_voice_cmd.token = 0;
1130 mvm_stop_voice_cmd.opcode = VSS_IMVM_CMD_STOP_VOICE;
1131
1132 v->mvm_state = CMD_STATUS_FAIL;
1133 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_stop_voice_cmd);
1134 if (ret < 0) {
1135 pr_err("Fail in sending VSS_IMVM_CMD_STOP_VOICE\n");
1136 goto fail;
1137 }
1138 ret = wait_event_timeout(v->mvm_wait,
1139 (v->mvm_state == CMD_STATUS_SUCCESS),
1140 msecs_to_jiffies(TIMEOUT_MS));
1141 if (!ret) {
1142 pr_err("%s: wait_event timeout\n", __func__);
1143 goto fail;
1144 }
1145
1146 return 0;
1147fail:
1148 return -EINVAL;
1149}
1150
Helen Zeng29eb7442011-06-20 11:06:29 -07001151static int voice_send_cvs_register_cal_cmd(struct voice_data *v)
1152{
1153 struct cvs_register_cal_data_cmd cvs_reg_cal_cmd;
1154 struct acdb_cal_block cal_block;
1155 int ret = 0;
1156 void *apr_cvs;
1157 u16 cvs_handle;
1158
1159 /* get the cvs cal data */
1160 get_all_vocstrm_cal(&cal_block);
1161 if (cal_block.cal_size == 0)
1162 goto fail;
1163
1164 if (v == NULL) {
1165 pr_err("%s: v is NULL\n", __func__);
1166 return -EINVAL;
1167 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001168 apr_cvs = common.apr_q6_cvs;
Helen Zeng29eb7442011-06-20 11:06:29 -07001169
1170 if (!apr_cvs) {
1171 pr_err("%s: apr_cvs is NULL.\n", __func__);
1172 return -EINVAL;
1173 }
1174 cvs_handle = voice_get_cvs_handle(v);
1175
1176 /* fill in the header */
1177 cvs_reg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1178 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1179 cvs_reg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1180 sizeof(cvs_reg_cal_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001181 cvs_reg_cal_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001182 cvs_reg_cal_cmd.hdr.dest_port = cvs_handle;
1183 cvs_reg_cal_cmd.hdr.token = 0;
1184 cvs_reg_cal_cmd.hdr.opcode = VSS_ISTREAM_CMD_REGISTER_CALIBRATION_DATA;
1185
1186 cvs_reg_cal_cmd.cvs_cal_data.phys_addr = cal_block.cal_paddr;
1187 cvs_reg_cal_cmd.cvs_cal_data.mem_size = cal_block.cal_size;
1188
1189 v->cvs_state = CMD_STATUS_FAIL;
1190 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_reg_cal_cmd);
1191 if (ret < 0) {
1192 pr_err("Fail: sending cvs cal,\n");
1193 goto fail;
1194 }
1195 ret = wait_event_timeout(v->cvs_wait,
1196 (v->cvs_state == CMD_STATUS_SUCCESS),
1197 msecs_to_jiffies(TIMEOUT_MS));
1198 if (!ret) {
1199 pr_err("%s: wait_event timeout\n", __func__);
1200 goto fail;
1201 }
1202 return 0;
1203fail:
1204 return -EINVAL;
1205
1206}
1207
1208static int voice_send_cvs_deregister_cal_cmd(struct voice_data *v)
1209{
1210 struct cvs_deregister_cal_data_cmd cvs_dereg_cal_cmd;
1211 struct acdb_cal_block cal_block;
1212 int ret = 0;
1213 void *apr_cvs;
1214 u16 cvs_handle;
1215
1216 get_all_vocstrm_cal(&cal_block);
1217 if (cal_block.cal_size == 0)
1218 return 0;
1219
1220 if (v == NULL) {
1221 pr_err("%s: v is NULL\n", __func__);
1222 return -EINVAL;
1223 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001224 apr_cvs = common.apr_q6_cvs;
Helen Zeng29eb7442011-06-20 11:06:29 -07001225
1226 if (!apr_cvs) {
1227 pr_err("%s: apr_cvs is NULL.\n", __func__);
1228 return -EINVAL;
1229 }
1230 cvs_handle = voice_get_cvs_handle(v);
1231
1232 /* fill in the header */
1233 cvs_dereg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1234 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1235 cvs_dereg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1236 sizeof(cvs_dereg_cal_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001237 cvs_dereg_cal_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001238 cvs_dereg_cal_cmd.hdr.dest_port = cvs_handle;
1239 cvs_dereg_cal_cmd.hdr.token = 0;
1240 cvs_dereg_cal_cmd.hdr.opcode =
1241 VSS_ISTREAM_CMD_DEREGISTER_CALIBRATION_DATA;
1242
1243 v->cvs_state = CMD_STATUS_FAIL;
1244 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_dereg_cal_cmd);
1245 if (ret < 0) {
1246 pr_err("Fail: sending cvs cal,\n");
1247 goto fail;
1248 }
1249 ret = wait_event_timeout(v->cvs_wait,
1250 (v->cvs_state == CMD_STATUS_SUCCESS),
1251 msecs_to_jiffies(TIMEOUT_MS));
1252 if (!ret) {
1253 pr_err("%s: wait_event timeout\n", __func__);
1254 goto fail;
1255 }
1256 return 0;
1257fail:
1258 return -EINVAL;
1259
1260}
1261
1262static int voice_send_cvp_map_memory_cmd(struct voice_data *v)
1263{
1264 struct vss_map_memory_cmd cvp_map_mem_cmd;
1265 struct acdb_cal_block cal_block;
1266 int ret = 0;
1267 void *apr_cvp;
1268 u16 cvp_handle;
1269
1270 /* get all cvp cal data */
1271 get_all_cvp_cal(&cal_block);
1272 if (cal_block.cal_size == 0)
1273 goto fail;
1274
1275 if (v == NULL) {
1276 pr_err("%s: v is NULL\n", __func__);
1277 return -EINVAL;
1278 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001279 apr_cvp = common.apr_q6_cvp;
Helen Zeng29eb7442011-06-20 11:06:29 -07001280
1281 if (!apr_cvp) {
1282 pr_err("%s: apr_cvp is NULL.\n", __func__);
1283 return -EINVAL;
1284 }
1285 cvp_handle = voice_get_cvp_handle(v);
1286
1287 /* fill in the header */
1288 cvp_map_mem_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1289 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1290 cvp_map_mem_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1291 sizeof(cvp_map_mem_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001292 cvp_map_mem_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001293 cvp_map_mem_cmd.hdr.dest_port = cvp_handle;
1294 cvp_map_mem_cmd.hdr.token = 0;
1295 cvp_map_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_MAP_MEMORY;
1296
1297 pr_debug("%s, phy_addr:%d, mem_size:%d\n", __func__,
1298 cal_block.cal_paddr, cal_block.cal_size);
1299 cvp_map_mem_cmd.vss_map_mem.phys_addr = cal_block.cal_paddr;
1300 cvp_map_mem_cmd.vss_map_mem.mem_size = cal_block.cal_size;
1301 cvp_map_mem_cmd.vss_map_mem.mem_pool_id =
1302 VSS_ICOMMON_MAP_MEMORY_SHMEM8_4K_POOL;
1303
1304 v->cvp_state = CMD_STATUS_FAIL;
1305 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_map_mem_cmd);
1306 if (ret < 0) {
1307 pr_err("Fail: sending cvp cal,\n");
1308 goto fail;
1309 }
1310 ret = wait_event_timeout(v->cvp_wait,
1311 (v->cvp_state == CMD_STATUS_SUCCESS),
1312 msecs_to_jiffies(TIMEOUT_MS));
1313 if (!ret) {
1314 pr_err("%s: wait_event timeout\n", __func__);
1315 goto fail;
1316 }
1317 return 0;
1318fail:
1319 return -EINVAL;
1320
1321}
1322
1323static int voice_send_cvp_unmap_memory_cmd(struct voice_data *v)
1324{
1325 struct vss_unmap_memory_cmd cvp_unmap_mem_cmd;
1326 struct acdb_cal_block cal_block;
1327 int ret = 0;
1328 void *apr_cvp;
1329 u16 cvp_handle;
1330
1331 get_all_cvp_cal(&cal_block);
1332 if (cal_block.cal_size == 0)
1333 return 0;
1334
1335 if (v == NULL) {
1336 pr_err("%s: v is NULL\n", __func__);
1337 return -EINVAL;
1338 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001339 apr_cvp = common.apr_q6_cvp;
Helen Zeng29eb7442011-06-20 11:06:29 -07001340
1341 if (!apr_cvp) {
1342 pr_err("%s: apr_cvp is NULL.\n", __func__);
1343 return -EINVAL;
1344 }
1345 cvp_handle = voice_get_cvp_handle(v);
1346
1347 /* fill in the header */
1348 cvp_unmap_mem_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1349 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1350 cvp_unmap_mem_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1351 sizeof(cvp_unmap_mem_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001352 cvp_unmap_mem_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001353 cvp_unmap_mem_cmd.hdr.dest_port = cvp_handle;
1354 cvp_unmap_mem_cmd.hdr.token = 0;
1355 cvp_unmap_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_UNMAP_MEMORY;
1356
1357 cvp_unmap_mem_cmd.vss_unmap_mem.phys_addr = cal_block.cal_paddr;
1358
1359 v->cvp_state = CMD_STATUS_FAIL;
1360 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_unmap_mem_cmd);
1361 if (ret < 0) {
1362 pr_err("Fail: sending cvp cal,\n");
1363 goto fail;
1364 }
1365 ret = wait_event_timeout(v->cvp_wait,
1366 (v->cvp_state == CMD_STATUS_SUCCESS),
1367 msecs_to_jiffies(TIMEOUT_MS));
1368 if (!ret) {
1369 pr_err("%s: wait_event timeout\n", __func__);
1370 goto fail;
1371 }
1372 return 0;
1373fail:
1374 return -EINVAL;
1375
1376}
1377
1378static int voice_send_cvs_map_memory_cmd(struct voice_data *v)
1379{
1380 struct vss_map_memory_cmd cvs_map_mem_cmd;
1381 struct acdb_cal_block cal_block;
1382 int ret = 0;
1383 void *apr_cvs;
1384 u16 cvs_handle;
1385
1386 /* get all cvs cal data */
1387 get_all_vocstrm_cal(&cal_block);
1388 if (cal_block.cal_size == 0)
1389 goto fail;
1390
1391 if (v == NULL) {
1392 pr_err("%s: v is NULL\n", __func__);
1393 return -EINVAL;
1394 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001395 apr_cvs = common.apr_q6_cvs;
Helen Zeng29eb7442011-06-20 11:06:29 -07001396
1397 if (!apr_cvs) {
1398 pr_err("%s: apr_cvs is NULL.\n", __func__);
1399 return -EINVAL;
1400 }
1401 cvs_handle = voice_get_cvs_handle(v);
1402
1403 /* fill in the header */
1404 cvs_map_mem_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1405 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1406 cvs_map_mem_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1407 sizeof(cvs_map_mem_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001408 cvs_map_mem_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001409 cvs_map_mem_cmd.hdr.dest_port = cvs_handle;
1410 cvs_map_mem_cmd.hdr.token = 0;
1411 cvs_map_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_MAP_MEMORY;
1412
1413 pr_debug("%s, phys_addr: %d, mem_size: %d\n", __func__,
1414 cal_block.cal_paddr, cal_block.cal_size);
1415 cvs_map_mem_cmd.vss_map_mem.phys_addr = cal_block.cal_paddr;
1416 cvs_map_mem_cmd.vss_map_mem.mem_size = cal_block.cal_size;
1417 cvs_map_mem_cmd.vss_map_mem.mem_pool_id =
1418 VSS_ICOMMON_MAP_MEMORY_SHMEM8_4K_POOL;
1419
1420 v->cvs_state = CMD_STATUS_FAIL;
1421 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_map_mem_cmd);
1422 if (ret < 0) {
1423 pr_err("Fail: sending cvs cal,\n");
1424 goto fail;
1425 }
1426 ret = wait_event_timeout(v->cvs_wait,
1427 (v->cvs_state == CMD_STATUS_SUCCESS),
1428 msecs_to_jiffies(TIMEOUT_MS));
1429 if (!ret) {
1430 pr_err("%s: wait_event timeout\n", __func__);
1431 goto fail;
1432 }
1433 return 0;
1434fail:
1435 return -EINVAL;
1436
1437}
1438
1439static int voice_send_cvs_unmap_memory_cmd(struct voice_data *v)
1440{
1441 struct vss_unmap_memory_cmd cvs_unmap_mem_cmd;
1442 struct acdb_cal_block cal_block;
1443 int ret = 0;
1444 void *apr_cvs;
1445 u16 cvs_handle;
1446
1447 get_all_vocstrm_cal(&cal_block);
1448 if (cal_block.cal_size == 0)
1449 return 0;
1450
1451 if (v == NULL) {
1452 pr_err("%s: v is NULL\n", __func__);
1453 return -EINVAL;
1454 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001455 apr_cvs = common.apr_q6_cvs;
Helen Zeng29eb7442011-06-20 11:06:29 -07001456
1457 if (!apr_cvs) {
1458 pr_err("%s: apr_cvs is NULL.\n", __func__);
1459 return -EINVAL;
1460 }
1461 cvs_handle = voice_get_cvs_handle(v);
1462
1463 /* fill in the header */
1464 cvs_unmap_mem_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1465 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1466 cvs_unmap_mem_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1467 sizeof(cvs_unmap_mem_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001468 cvs_unmap_mem_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001469 cvs_unmap_mem_cmd.hdr.dest_port = cvs_handle;
1470 cvs_unmap_mem_cmd.hdr.token = 0;
1471 cvs_unmap_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_UNMAP_MEMORY;
1472
1473 cvs_unmap_mem_cmd.vss_unmap_mem.phys_addr = cal_block.cal_paddr;
1474
1475 v->cvs_state = CMD_STATUS_FAIL;
1476 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_unmap_mem_cmd);
1477 if (ret < 0) {
1478 pr_err("Fail: sending cvs cal,\n");
1479 goto fail;
1480 }
1481 ret = wait_event_timeout(v->cvs_wait,
1482 (v->cvs_state == CMD_STATUS_SUCCESS),
1483 msecs_to_jiffies(TIMEOUT_MS));
1484 if (!ret) {
1485 pr_err("%s: wait_event timeout\n", __func__);
1486 goto fail;
1487 }
1488 return 0;
1489fail:
1490 return -EINVAL;
1491
1492}
1493
1494static int voice_send_cvp_register_cal_cmd(struct voice_data *v)
1495{
1496 struct cvp_register_cal_data_cmd cvp_reg_cal_cmd;
1497 struct acdb_cal_block cal_block;
1498 int ret = 0;
1499 void *apr_cvp;
1500 u16 cvp_handle;
1501
1502 /* get the cvp cal data */
1503 get_all_vocproc_cal(&cal_block);
1504 if (cal_block.cal_size == 0)
1505 goto fail;
1506
1507 if (v == NULL) {
1508 pr_err("%s: v is NULL\n", __func__);
1509 return -EINVAL;
1510 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001511 apr_cvp = common.apr_q6_cvp;
Helen Zeng29eb7442011-06-20 11:06:29 -07001512
1513 if (!apr_cvp) {
1514 pr_err("%s: apr_cvp is NULL.\n", __func__);
1515 return -EINVAL;
1516 }
1517 cvp_handle = voice_get_cvp_handle(v);
1518
1519 /* fill in the header */
1520 cvp_reg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1521 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1522 cvp_reg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1523 sizeof(cvp_reg_cal_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001524 cvp_reg_cal_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001525 cvp_reg_cal_cmd.hdr.dest_port = cvp_handle;
1526 cvp_reg_cal_cmd.hdr.token = 0;
1527 cvp_reg_cal_cmd.hdr.opcode = VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA;
1528
1529 cvp_reg_cal_cmd.cvp_cal_data.phys_addr = cal_block.cal_paddr;
1530 cvp_reg_cal_cmd.cvp_cal_data.mem_size = cal_block.cal_size;
1531
1532 v->cvp_state = CMD_STATUS_FAIL;
1533 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_reg_cal_cmd);
1534 if (ret < 0) {
1535 pr_err("Fail: sending cvp cal,\n");
1536 goto fail;
1537 }
1538 ret = wait_event_timeout(v->cvp_wait,
1539 (v->cvp_state == CMD_STATUS_SUCCESS),
1540 msecs_to_jiffies(TIMEOUT_MS));
1541 if (!ret) {
1542 pr_err("%s: wait_event timeout\n", __func__);
1543 goto fail;
1544 }
1545 return 0;
1546fail:
1547 return -EINVAL;
1548
1549}
1550
1551static int voice_send_cvp_deregister_cal_cmd(struct voice_data *v)
1552{
1553 struct cvp_deregister_cal_data_cmd cvp_dereg_cal_cmd;
1554 struct acdb_cal_block cal_block;
1555 int ret = 0;
1556 void *apr_cvp;
1557 u16 cvp_handle;
1558
1559 get_all_vocproc_cal(&cal_block);
1560 if (cal_block.cal_size == 0)
1561 return 0;
1562
1563 if (v == NULL) {
1564 pr_err("%s: v is NULL\n", __func__);
1565 return -EINVAL;
1566 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001567 apr_cvp = common.apr_q6_cvp;
Helen Zeng29eb7442011-06-20 11:06:29 -07001568
1569 if (!apr_cvp) {
1570 pr_err("%s: apr_cvp is NULL.\n", __func__);
1571 return -EINVAL;
1572 }
1573 cvp_handle = voice_get_cvp_handle(v);
1574
1575 /* fill in the header */
1576 cvp_dereg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1577 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1578 cvp_dereg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1579 sizeof(cvp_dereg_cal_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001580 cvp_dereg_cal_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001581 cvp_dereg_cal_cmd.hdr.dest_port = cvp_handle;
1582 cvp_dereg_cal_cmd.hdr.token = 0;
1583 cvp_dereg_cal_cmd.hdr.opcode =
1584 VSS_IVOCPROC_CMD_DEREGISTER_CALIBRATION_DATA;
1585
1586 v->cvp_state = CMD_STATUS_FAIL;
1587 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_dereg_cal_cmd);
1588 if (ret < 0) {
1589 pr_err("Fail: sending cvp cal,\n");
1590 goto fail;
1591 }
1592 ret = wait_event_timeout(v->cvp_wait,
1593 (v->cvp_state == CMD_STATUS_SUCCESS),
1594 msecs_to_jiffies(TIMEOUT_MS));
1595 if (!ret) {
1596 pr_err("%s: wait_event timeout\n", __func__);
1597 goto fail;
1598 }
1599 return 0;
1600fail:
1601 return -EINVAL;
1602
1603}
1604
1605static int voice_send_cvp_register_vol_cal_table_cmd(struct voice_data *v)
1606{
1607 struct cvp_register_vol_cal_table_cmd cvp_reg_cal_tbl_cmd;
1608 struct acdb_cal_block cal_block;
1609 int ret = 0;
1610 void *apr_cvp;
1611 u16 cvp_handle;
1612
1613 /* get the cvp vol cal data */
1614 get_all_vocvol_cal(&cal_block);
1615 if (cal_block.cal_size == 0)
1616 goto fail;
1617
1618 if (v == NULL) {
1619 pr_err("%s: v is NULL\n", __func__);
1620 return -EINVAL;
1621 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001622 apr_cvp = common.apr_q6_cvp;
Helen Zeng29eb7442011-06-20 11:06:29 -07001623
1624 if (!apr_cvp) {
1625 pr_err("%s: apr_cvp is NULL.\n", __func__);
1626 return -EINVAL;
1627 }
1628 cvp_handle = voice_get_cvp_handle(v);
1629
1630 /* fill in the header */
1631 cvp_reg_cal_tbl_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1632 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1633 cvp_reg_cal_tbl_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1634 sizeof(cvp_reg_cal_tbl_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001635 cvp_reg_cal_tbl_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001636 cvp_reg_cal_tbl_cmd.hdr.dest_port = cvp_handle;
1637 cvp_reg_cal_tbl_cmd.hdr.token = 0;
1638 cvp_reg_cal_tbl_cmd.hdr.opcode =
1639 VSS_IVOCPROC_CMD_REGISTER_VOLUME_CAL_TABLE;
1640
1641 cvp_reg_cal_tbl_cmd.cvp_vol_cal_tbl.phys_addr = cal_block.cal_paddr;
1642 cvp_reg_cal_tbl_cmd.cvp_vol_cal_tbl.mem_size = cal_block.cal_size;
1643
1644 v->cvp_state = CMD_STATUS_FAIL;
1645 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_reg_cal_tbl_cmd);
1646 if (ret < 0) {
1647 pr_err("Fail: sending cvp cal table,\n");
1648 goto fail;
1649 }
1650 ret = wait_event_timeout(v->cvp_wait,
1651 (v->cvp_state == CMD_STATUS_SUCCESS),
1652 msecs_to_jiffies(TIMEOUT_MS));
1653 if (!ret) {
1654 pr_err("%s: wait_event timeout\n", __func__);
1655 goto fail;
1656 }
1657 return 0;
1658fail:
1659 return -EINVAL;
1660
1661}
1662
1663static int voice_send_cvp_deregister_vol_cal_table_cmd(struct voice_data *v)
1664{
1665 struct cvp_deregister_vol_cal_table_cmd cvp_dereg_cal_tbl_cmd;
1666 struct acdb_cal_block cal_block;
1667 int ret = 0;
1668 void *apr_cvp;
1669 u16 cvp_handle;
1670
1671 get_all_vocvol_cal(&cal_block);
1672 if (cal_block.cal_size == 0)
1673 return 0;
1674
1675 if (v == NULL) {
1676 pr_err("%s: v is NULL\n", __func__);
1677 return -EINVAL;
1678 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001679 apr_cvp = common.apr_q6_cvp;
Helen Zeng29eb7442011-06-20 11:06:29 -07001680
1681 if (!apr_cvp) {
1682 pr_err("%s: apr_cvp is NULL.\n", __func__);
1683 return -EINVAL;
1684 }
1685 cvp_handle = voice_get_cvp_handle(v);
1686
1687 /* fill in the header */
1688 cvp_dereg_cal_tbl_cmd.hdr.hdr_field = APR_HDR_FIELD(
1689 APR_MSG_TYPE_SEQ_CMD,
1690 APR_HDR_LEN(APR_HDR_SIZE),
1691 APR_PKT_VER);
1692 cvp_dereg_cal_tbl_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1693 sizeof(cvp_dereg_cal_tbl_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001694 cvp_dereg_cal_tbl_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001695 cvp_dereg_cal_tbl_cmd.hdr.dest_port = cvp_handle;
1696 cvp_dereg_cal_tbl_cmd.hdr.token = 0;
1697 cvp_dereg_cal_tbl_cmd.hdr.opcode =
1698 VSS_IVOCPROC_CMD_DEREGISTER_VOLUME_CAL_TABLE;
1699
1700 v->cvp_state = CMD_STATUS_FAIL;
1701 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_dereg_cal_tbl_cmd);
1702 if (ret < 0) {
1703 pr_err("Fail: sending cvp cal table,\n");
1704 goto fail;
1705 }
1706 ret = wait_event_timeout(v->cvp_wait,
1707 (v->cvp_state == CMD_STATUS_SUCCESS),
1708 msecs_to_jiffies(TIMEOUT_MS));
1709 if (!ret) {
1710 pr_err("%s: wait_event timeout\n", __func__);
1711 goto fail;
1712 }
1713 return 0;
1714fail:
1715 return -EINVAL;
1716
1717}
Neema Shetty2c07eb52011-08-21 20:33:52 -07001718
Helen Zeng44d4d272011-08-10 14:49:20 -07001719static int voice_send_set_widevoice_enable_cmd(struct voice_data *v)
1720{
1721 struct mvm_set_widevoice_enable_cmd mvm_set_wv_cmd;
1722 int ret = 0;
1723 void *apr_mvm;
1724 u16 mvm_handle;
1725
1726 if (v == NULL) {
1727 pr_err("%s: v is NULL\n", __func__);
1728 return -EINVAL;
1729 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001730 apr_mvm = common.apr_q6_mvm;
Helen Zeng44d4d272011-08-10 14:49:20 -07001731
1732 if (!apr_mvm) {
1733 pr_err("%s: apr_mvm is NULL.\n", __func__);
1734 return -EINVAL;
1735 }
1736 mvm_handle = voice_get_mvm_handle(v);
1737
1738 /* fill in the header */
1739 mvm_set_wv_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1740 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1741 mvm_set_wv_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1742 sizeof(mvm_set_wv_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001743 mvm_set_wv_cmd.hdr.src_port = v->session_id;
Helen Zeng44d4d272011-08-10 14:49:20 -07001744 mvm_set_wv_cmd.hdr.dest_port = mvm_handle;
1745 mvm_set_wv_cmd.hdr.token = 0;
1746 mvm_set_wv_cmd.hdr.opcode = VSS_IWIDEVOICE_CMD_SET_WIDEVOICE;
1747
1748 mvm_set_wv_cmd.vss_set_wv.enable = v->wv_enable;
1749
1750 v->mvm_state = CMD_STATUS_FAIL;
1751 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_wv_cmd);
1752 if (ret < 0) {
1753 pr_err("Fail: sending mvm set widevoice enable,\n");
1754 goto fail;
1755 }
1756 ret = wait_event_timeout(v->mvm_wait,
1757 (v->mvm_state == CMD_STATUS_SUCCESS),
1758 msecs_to_jiffies(TIMEOUT_MS));
1759 if (!ret) {
1760 pr_err("%s: wait_event timeout\n", __func__);
1761 goto fail;
1762 }
1763 return 0;
1764fail:
1765 return -EINVAL;
1766}
1767
Helen Zeng4e531942011-12-17 21:14:40 -08001768static int voice_send_set_pp_enable_cmd(struct voice_data *v,
1769 uint32_t module_id, int enable)
Helen Zengbb49c702011-09-06 14:09:13 -07001770{
Helen Zeng4e531942011-12-17 21:14:40 -08001771 struct cvs_set_pp_enable_cmd cvs_set_pp_cmd;
Helen Zengbb49c702011-09-06 14:09:13 -07001772 int ret = 0;
1773 void *apr_cvs;
1774 u16 cvs_handle;
1775
1776 if (v == NULL) {
1777 pr_err("%s: v is NULL\n", __func__);
1778 return -EINVAL;
1779 }
1780 apr_cvs = common.apr_q6_cvs;
1781
1782 if (!apr_cvs) {
1783 pr_err("%s: apr_cvs is NULL.\n", __func__);
1784 return -EINVAL;
1785 }
1786 cvs_handle = voice_get_cvs_handle(v);
1787
1788 /* fill in the header */
Helen Zeng4e531942011-12-17 21:14:40 -08001789 cvs_set_pp_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
Helen Zengbb49c702011-09-06 14:09:13 -07001790 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
Helen Zeng4e531942011-12-17 21:14:40 -08001791 cvs_set_pp_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1792 sizeof(cvs_set_pp_cmd) - APR_HDR_SIZE);
1793 cvs_set_pp_cmd.hdr.src_port = v->session_id;
1794 cvs_set_pp_cmd.hdr.dest_port = cvs_handle;
1795 cvs_set_pp_cmd.hdr.token = 0;
1796 cvs_set_pp_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_UI_PROPERTY;
Helen Zengbb49c702011-09-06 14:09:13 -07001797
Helen Zeng4e531942011-12-17 21:14:40 -08001798 cvs_set_pp_cmd.vss_set_pp.module_id = module_id;
1799 cvs_set_pp_cmd.vss_set_pp.param_id = VOICE_PARAM_MOD_ENABLE;
1800 cvs_set_pp_cmd.vss_set_pp.param_size = MOD_ENABLE_PARAM_LEN;
1801 cvs_set_pp_cmd.vss_set_pp.reserved = 0;
1802 cvs_set_pp_cmd.vss_set_pp.enable = enable;
1803 cvs_set_pp_cmd.vss_set_pp.reserved_field = 0;
1804 pr_debug("voice_send_set_pp_enable_cmd, module_id=%d, enable=%d\n",
1805 module_id, enable);
Helen Zengbb49c702011-09-06 14:09:13 -07001806
1807 v->cvs_state = CMD_STATUS_FAIL;
Helen Zeng4e531942011-12-17 21:14:40 -08001808 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_pp_cmd);
Helen Zengbb49c702011-09-06 14:09:13 -07001809 if (ret < 0) {
1810 pr_err("Fail: sending cvs set slowtalk enable,\n");
1811 goto fail;
1812 }
1813 ret = wait_event_timeout(v->cvs_wait,
1814 (v->cvs_state == CMD_STATUS_SUCCESS),
1815 msecs_to_jiffies(TIMEOUT_MS));
1816 if (!ret) {
1817 pr_err("%s: wait_event timeout\n", __func__);
1818 goto fail;
1819 }
1820 return 0;
1821fail:
1822 return -EINVAL;
1823}
1824
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001825static int voice_setup_vocproc(struct voice_data *v)
1826{
1827 struct cvp_create_full_ctl_session_cmd cvp_session_cmd;
1828 int ret = 0;
1829 void *apr_cvp;
1830 if (v == NULL) {
1831 pr_err("%s: v is NULL\n", __func__);
1832 return -EINVAL;
1833 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001834 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001835
1836 if (!apr_cvp) {
1837 pr_err("%s: apr_cvp is NULL.\n", __func__);
1838 return -EINVAL;
1839 }
1840
1841 /* create cvp session and wait for response */
1842 cvp_session_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1843 APR_HDR_LEN(APR_HDR_SIZE),
1844 APR_PKT_VER);
1845 cvp_session_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1846 sizeof(cvp_session_cmd) - APR_HDR_SIZE);
1847 pr_debug(" send create cvp session, pkt size = %d\n",
1848 cvp_session_cmd.hdr.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001849 cvp_session_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001850 cvp_session_cmd.hdr.dest_port = 0;
1851 cvp_session_cmd.hdr.token = 0;
1852 cvp_session_cmd.hdr.opcode =
1853 VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION;
1854
1855 /* Use default topology if invalid value in ACDB */
1856 cvp_session_cmd.cvp_session.tx_topology_id =
1857 get_voice_tx_topology();
1858 if (cvp_session_cmd.cvp_session.tx_topology_id == 0)
1859 cvp_session_cmd.cvp_session.tx_topology_id =
1860 VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
1861
1862 cvp_session_cmd.cvp_session.rx_topology_id =
1863 get_voice_rx_topology();
1864 if (cvp_session_cmd.cvp_session.rx_topology_id == 0)
1865 cvp_session_cmd.cvp_session.rx_topology_id =
1866 VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
1867
1868 cvp_session_cmd.cvp_session.direction = 2; /*tx and rx*/
1869 cvp_session_cmd.cvp_session.network_id = VSS_NETWORK_ID_DEFAULT;
1870 cvp_session_cmd.cvp_session.tx_port_id = v->dev_tx.port_id;
1871 cvp_session_cmd.cvp_session.rx_port_id = v->dev_rx.port_id;
1872
1873 pr_debug("topology=%d net_id=%d, dir=%d tx_port_id=%d, rx_port_id=%d\n",
1874 cvp_session_cmd.cvp_session.tx_topology_id,
1875 cvp_session_cmd.cvp_session.network_id,
1876 cvp_session_cmd.cvp_session.direction,
1877 cvp_session_cmd.cvp_session.tx_port_id,
1878 cvp_session_cmd.cvp_session.rx_port_id);
1879
1880 v->cvp_state = CMD_STATUS_FAIL;
1881 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_session_cmd);
1882 if (ret < 0) {
1883 pr_err("Fail in sending VOCPROC_FULL_CONTROL_SESSION\n");
1884 goto fail;
1885 }
1886 ret = wait_event_timeout(v->cvp_wait,
1887 (v->cvp_state == CMD_STATUS_SUCCESS),
1888 msecs_to_jiffies(TIMEOUT_MS));
1889 if (!ret) {
1890 pr_err("%s: wait_event timeout\n", __func__);
1891 goto fail;
1892 }
1893
Helen Zeng29eb7442011-06-20 11:06:29 -07001894 /* send cvs cal */
1895 ret = voice_send_cvs_map_memory_cmd(v);
1896 if (!ret)
1897 voice_send_cvs_register_cal_cmd(v);
1898
1899 /* send cvp and vol cal */
1900 ret = voice_send_cvp_map_memory_cmd(v);
1901 if (!ret) {
1902 voice_send_cvp_register_cal_cmd(v);
1903 voice_send_cvp_register_vol_cal_table_cmd(v);
1904 }
1905
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001906 /* enable vocproc */
1907 ret = voice_send_enable_vocproc_cmd(v);
1908 if (ret < 0)
1909 goto fail;
1910
1911 /* attach vocproc */
1912 ret = voice_send_attach_vocproc_cmd(v);
1913 if (ret < 0)
1914 goto fail;
1915
1916 /* send tty mode if tty device is used */
1917 voice_send_tty_mode_cmd(v);
1918
Helen Zeng44d4d272011-08-10 14:49:20 -07001919 /* enable widevoice if wv_enable is set */
1920 if (v->wv_enable)
1921 voice_send_set_widevoice_enable_cmd(v);
1922
Helen Zengbb49c702011-09-06 14:09:13 -07001923 /* enable slowtalk if st_enable is set */
1924 if (v->st_enable)
Helen Zeng4e531942011-12-17 21:14:40 -08001925 voice_send_set_pp_enable_cmd(v, MODULE_ID_VOICE_MODULE_ST,
1926 v->st_enable);
1927 if (v->fens_enable)
1928 voice_send_set_pp_enable_cmd(v, MODULE_ID_VOICE_MODULE_FENS,
1929 v->fens_enable);
Helen Zengbb49c702011-09-06 14:09:13 -07001930
Neema Shetty2c07eb52011-08-21 20:33:52 -07001931 if (is_voip_session(v->session_id))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001932 voice_send_netid_timing_cmd(v);
1933
Helen Zenge3d716a2011-10-14 16:32:16 -07001934 /* Start in-call music delivery if this feature is enabled */
Helen Zeng0705a5f2011-10-14 15:29:52 -07001935 if (v->music_info.play_enable)
1936 voice_cvs_start_playback(v);
1937
Helen Zenge3d716a2011-10-14 16:32:16 -07001938 /* Start in-call recording if this feature is enabled */
1939 if (v->rec_info.rec_enable)
1940 voice_cvs_start_record(v, v->rec_info.rec_mode);
1941
Ben Romberger13b74ab2011-07-18 17:36:32 -07001942 rtac_add_voice(voice_get_cvs_handle(v),
1943 voice_get_cvp_handle(v),
Ben Rombergerc5d6a372011-09-22 18:01:49 -07001944 v->dev_rx.port_id, v->dev_tx.port_id,
1945 v->session_id);
Ben Romberger13b74ab2011-07-18 17:36:32 -07001946
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001947 return 0;
1948
1949fail:
1950 return -EINVAL;
1951}
1952
1953static int voice_send_enable_vocproc_cmd(struct voice_data *v)
1954{
1955 int ret = 0;
1956 struct apr_hdr cvp_enable_cmd;
1957 void *apr_cvp;
1958 u16 cvp_handle;
1959
1960 if (v == NULL) {
1961 pr_err("%s: v is NULL\n", __func__);
1962 return -EINVAL;
1963 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001964 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001965
1966 if (!apr_cvp) {
1967 pr_err("%s: apr_cvp is NULL.\n", __func__);
1968 return -EINVAL;
1969 }
1970 cvp_handle = voice_get_cvp_handle(v);
1971
1972 /* enable vocproc and wait for respose */
1973 cvp_enable_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1974 APR_HDR_LEN(APR_HDR_SIZE),
1975 APR_PKT_VER);
1976 cvp_enable_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1977 sizeof(cvp_enable_cmd) - APR_HDR_SIZE);
1978 pr_debug("cvp_enable_cmd pkt size = %d, cvp_handle=%d\n",
1979 cvp_enable_cmd.pkt_size, cvp_handle);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001980 cvp_enable_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001981 cvp_enable_cmd.dest_port = cvp_handle;
1982 cvp_enable_cmd.token = 0;
1983 cvp_enable_cmd.opcode = VSS_IVOCPROC_CMD_ENABLE;
1984
1985 v->cvp_state = CMD_STATUS_FAIL;
1986 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_enable_cmd);
1987 if (ret < 0) {
1988 pr_err("Fail in sending VSS_IVOCPROC_CMD_ENABLE\n");
1989 goto fail;
1990 }
1991 ret = wait_event_timeout(v->cvp_wait,
1992 (v->cvp_state == CMD_STATUS_SUCCESS),
1993 msecs_to_jiffies(TIMEOUT_MS));
1994 if (!ret) {
1995 pr_err("%s: wait_event timeout\n", __func__);
1996 goto fail;
1997 }
1998
1999 return 0;
2000fail:
2001 return -EINVAL;
2002}
2003
2004static int voice_send_netid_timing_cmd(struct voice_data *v)
2005{
2006 int ret = 0;
2007 void *apr_mvm;
2008 u16 mvm_handle;
2009 struct mvm_set_network_cmd mvm_set_network;
2010 struct mvm_set_voice_timing_cmd mvm_set_voice_timing;
2011
2012 if (v == NULL) {
2013 pr_err("%s: v is NULL\n", __func__);
2014 return -EINVAL;
2015 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07002016 apr_mvm = common.apr_q6_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002017
2018 if (!apr_mvm) {
2019 pr_err("%s: apr_mvm is NULL.\n", __func__);
2020 return -EINVAL;
2021 }
2022 mvm_handle = voice_get_mvm_handle(v);
2023
2024 ret = voice_config_cvs_vocoder(v);
2025 if (ret < 0) {
2026 pr_err("%s: Error %d configuring CVS voc",
2027 __func__, ret);
2028 goto fail;
2029 }
2030 /* Set network ID. */
2031 pr_debug("Setting network ID\n");
2032
2033 mvm_set_network.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2034 APR_HDR_LEN(APR_HDR_SIZE),
2035 APR_PKT_VER);
2036 mvm_set_network.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2037 sizeof(mvm_set_network) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002038 mvm_set_network.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002039 mvm_set_network.hdr.dest_port = mvm_handle;
2040 mvm_set_network.hdr.token = 0;
2041 mvm_set_network.hdr.opcode = VSS_ICOMMON_CMD_SET_NETWORK;
Neema Shetty2c07eb52011-08-21 20:33:52 -07002042 mvm_set_network.network.network_id = common.mvs_info.network_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002043
2044 v->mvm_state = CMD_STATUS_FAIL;
2045 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_network);
2046 if (ret < 0) {
2047 pr_err("%s: Error %d sending SET_NETWORK\n", __func__, ret);
2048 goto fail;
2049 }
2050
2051 ret = wait_event_timeout(v->mvm_wait,
2052 (v->mvm_state == CMD_STATUS_SUCCESS),
2053 msecs_to_jiffies(TIMEOUT_MS));
2054 if (!ret) {
2055 pr_err("%s: wait_event timeout\n", __func__);
2056 goto fail;
2057 }
2058
2059 /* Set voice timing. */
2060 pr_debug("Setting voice timing\n");
2061
2062 mvm_set_voice_timing.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2063 APR_HDR_LEN(APR_HDR_SIZE),
2064 APR_PKT_VER);
2065 mvm_set_voice_timing.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2066 sizeof(mvm_set_voice_timing) -
2067 APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002068 mvm_set_voice_timing.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002069 mvm_set_voice_timing.hdr.dest_port = mvm_handle;
2070 mvm_set_voice_timing.hdr.token = 0;
2071 mvm_set_voice_timing.hdr.opcode = VSS_ICOMMON_CMD_SET_VOICE_TIMING;
2072 mvm_set_voice_timing.timing.mode = 0;
2073 mvm_set_voice_timing.timing.enc_offset = 8000;
Swaminathan Sathappan2fea0da2011-12-21 12:20:53 -08002074 if (machine_is_apq8064_sim()) {
2075 pr_debug("%s: Machine is apq8064 sim\n", __func__);
2076 mvm_set_voice_timing.timing.dec_req_offset = 0;
2077 mvm_set_voice_timing.timing.dec_offset = 18000;
2078 } else {
2079 mvm_set_voice_timing.timing.dec_req_offset = 3300;
2080 mvm_set_voice_timing.timing.dec_offset = 8300;
2081 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002082
2083 v->mvm_state = CMD_STATUS_FAIL;
2084
2085 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_voice_timing);
2086 if (ret < 0) {
2087 pr_err("%s: Error %d sending SET_TIMING\n", __func__, ret);
2088 goto fail;
2089 }
2090
2091 ret = wait_event_timeout(v->mvm_wait,
2092 (v->mvm_state == CMD_STATUS_SUCCESS),
2093 msecs_to_jiffies(TIMEOUT_MS));
2094 if (!ret) {
2095 pr_err("%s: wait_event timeout\n", __func__);
2096 goto fail;
2097 }
2098
2099 return 0;
2100fail:
2101 return -EINVAL;
2102}
2103
2104static int voice_send_attach_vocproc_cmd(struct voice_data *v)
2105{
2106 int ret = 0;
2107 struct mvm_attach_vocproc_cmd mvm_a_vocproc_cmd;
2108 void *apr_mvm;
2109 u16 mvm_handle, cvp_handle;
2110
2111 if (v == NULL) {
2112 pr_err("%s: v is NULL\n", __func__);
2113 return -EINVAL;
2114 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07002115 apr_mvm = common.apr_q6_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002116
2117 if (!apr_mvm) {
2118 pr_err("%s: apr_mvm is NULL.\n", __func__);
2119 return -EINVAL;
2120 }
2121 mvm_handle = voice_get_mvm_handle(v);
2122 cvp_handle = voice_get_cvp_handle(v);
2123
2124 /* attach vocproc and wait for response */
2125 mvm_a_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2126 APR_HDR_LEN(APR_HDR_SIZE),
2127 APR_PKT_VER);
2128 mvm_a_vocproc_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2129 sizeof(mvm_a_vocproc_cmd) - APR_HDR_SIZE);
2130 pr_debug("send mvm_a_vocproc_cmd pkt size = %d\n",
2131 mvm_a_vocproc_cmd.hdr.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002132 mvm_a_vocproc_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002133 mvm_a_vocproc_cmd.hdr.dest_port = mvm_handle;
2134 mvm_a_vocproc_cmd.hdr.token = 0;
Helen Zeng69b00962011-07-08 11:38:36 -07002135 mvm_a_vocproc_cmd.hdr.opcode = VSS_IMVM_CMD_ATTACH_VOCPROC;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002136 mvm_a_vocproc_cmd.mvm_attach_cvp_handle.handle = cvp_handle;
2137
2138 v->mvm_state = CMD_STATUS_FAIL;
2139 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_a_vocproc_cmd);
2140 if (ret < 0) {
Helen Zeng69b00962011-07-08 11:38:36 -07002141 pr_err("Fail in sending VSS_IMVM_CMD_ATTACH_VOCPROC\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002142 goto fail;
2143 }
2144 ret = wait_event_timeout(v->mvm_wait,
2145 (v->mvm_state == CMD_STATUS_SUCCESS),
2146 msecs_to_jiffies(TIMEOUT_MS));
2147 if (!ret) {
2148 pr_err("%s: wait_event timeout\n", __func__);
2149 goto fail;
2150 }
2151
2152 return 0;
2153fail:
2154 return -EINVAL;
2155}
2156
2157static int voice_destroy_vocproc(struct voice_data *v)
2158{
2159 struct mvm_detach_vocproc_cmd mvm_d_vocproc_cmd;
2160 struct apr_hdr cvp_destroy_session_cmd;
2161 int ret = 0;
2162 void *apr_mvm, *apr_cvp;
2163 u16 mvm_handle, cvp_handle;
2164
2165 if (v == NULL) {
2166 pr_err("%s: v is NULL\n", __func__);
2167 return -EINVAL;
2168 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07002169 apr_mvm = common.apr_q6_mvm;
2170 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002171
2172 if (!apr_mvm || !apr_cvp) {
2173 pr_err("%s: apr_mvm or apr_cvp is NULL.\n", __func__);
2174 return -EINVAL;
2175 }
2176 mvm_handle = voice_get_mvm_handle(v);
2177 cvp_handle = voice_get_cvp_handle(v);
2178
Helen Zenge3d716a2011-10-14 16:32:16 -07002179 /* stop playback or recording */
Helen Zeng0705a5f2011-10-14 15:29:52 -07002180 v->music_info.force = 1;
2181 voice_cvs_stop_playback(v);
Helen Zenge3d716a2011-10-14 16:32:16 -07002182 voice_cvs_stop_record(v);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002183 /* send stop voice cmd */
2184 voice_send_stop_voice_cmd(v);
2185
2186 /* detach VOCPROC and wait for response from mvm */
2187 mvm_d_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2188 APR_HDR_LEN(APR_HDR_SIZE),
2189 APR_PKT_VER);
2190 mvm_d_vocproc_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2191 sizeof(mvm_d_vocproc_cmd) - APR_HDR_SIZE);
2192 pr_debug("mvm_d_vocproc_cmd pkt size = %d\n",
2193 mvm_d_vocproc_cmd.hdr.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002194 mvm_d_vocproc_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002195 mvm_d_vocproc_cmd.hdr.dest_port = mvm_handle;
2196 mvm_d_vocproc_cmd.hdr.token = 0;
Helen Zeng69b00962011-07-08 11:38:36 -07002197 mvm_d_vocproc_cmd.hdr.opcode = VSS_IMVM_CMD_DETACH_VOCPROC;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002198 mvm_d_vocproc_cmd.mvm_detach_cvp_handle.handle = cvp_handle;
2199
2200 v->mvm_state = CMD_STATUS_FAIL;
2201 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_d_vocproc_cmd);
2202 if (ret < 0) {
Helen Zeng69b00962011-07-08 11:38:36 -07002203 pr_err("Fail in sending VSS_IMVM_CMD_DETACH_VOCPROC\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002204 goto fail;
2205 }
2206 ret = wait_event_timeout(v->mvm_wait,
2207 (v->mvm_state == CMD_STATUS_SUCCESS),
2208 msecs_to_jiffies(TIMEOUT_MS));
2209 if (!ret) {
2210 pr_err("%s: wait_event timeout\n", __func__);
2211 goto fail;
2212 }
2213
Helen Zeng29eb7442011-06-20 11:06:29 -07002214 /* deregister cvp and vol cal */
2215 voice_send_cvp_deregister_vol_cal_table_cmd(v);
2216 voice_send_cvp_deregister_cal_cmd(v);
2217 voice_send_cvp_unmap_memory_cmd(v);
2218
2219 /* deregister cvs cal */
2220 voice_send_cvs_deregister_cal_cmd(v);
2221 voice_send_cvs_unmap_memory_cmd(v);
2222
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002223 /* destrop cvp session */
2224 cvp_destroy_session_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2225 APR_HDR_LEN(APR_HDR_SIZE),
2226 APR_PKT_VER);
2227 cvp_destroy_session_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2228 sizeof(cvp_destroy_session_cmd) - APR_HDR_SIZE);
2229 pr_debug("cvp_destroy_session_cmd pkt size = %d\n",
2230 cvp_destroy_session_cmd.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002231 cvp_destroy_session_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002232 cvp_destroy_session_cmd.dest_port = cvp_handle;
2233 cvp_destroy_session_cmd.token = 0;
2234 cvp_destroy_session_cmd.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
2235
2236 v->cvp_state = CMD_STATUS_FAIL;
2237 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_destroy_session_cmd);
2238 if (ret < 0) {
2239 pr_err("Fail in sending APRV2_IBASIC_CMD_DESTROY_SESSION\n");
2240 goto fail;
2241 }
2242 ret = wait_event_timeout(v->cvp_wait,
2243 (v->cvp_state == CMD_STATUS_SUCCESS),
2244 msecs_to_jiffies(TIMEOUT_MS));
2245 if (!ret) {
2246 pr_err("%s: wait_event timeout\n", __func__);
2247 goto fail;
2248 }
2249
Ben Romberger13b74ab2011-07-18 17:36:32 -07002250 rtac_remove_voice(voice_get_cvs_handle(v));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002251 cvp_handle = 0;
2252 voice_set_cvp_handle(v, cvp_handle);
2253
2254 return 0;
2255
2256fail:
2257 return -EINVAL;
2258}
2259
2260static int voice_send_mute_cmd(struct voice_data *v)
2261{
2262 struct cvs_set_mute_cmd cvs_mute_cmd;
2263 int ret = 0;
2264 void *apr_cvs;
2265 u16 cvs_handle;
2266
2267 if (v == NULL) {
2268 pr_err("%s: v is NULL\n", __func__);
2269 return -EINVAL;
2270 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07002271 apr_cvs = common.apr_q6_cvs;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002272
2273 if (!apr_cvs) {
2274 pr_err("%s: apr_cvs is NULL.\n", __func__);
2275 return -EINVAL;
2276 }
2277 cvs_handle = voice_get_cvs_handle(v);
2278
2279 /* send mute/unmute to cvs */
2280 cvs_mute_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2281 APR_HDR_LEN(APR_HDR_SIZE),
2282 APR_PKT_VER);
2283 cvs_mute_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2284 sizeof(cvs_mute_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002285 cvs_mute_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002286 cvs_mute_cmd.hdr.dest_port = cvs_handle;
2287 cvs_mute_cmd.hdr.token = 0;
2288 cvs_mute_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_MUTE;
2289 cvs_mute_cmd.cvs_set_mute.direction = 0; /*tx*/
2290 cvs_mute_cmd.cvs_set_mute.mute_flag = v->dev_tx.mute;
2291
2292 pr_info(" mute value =%d\n", cvs_mute_cmd.cvs_set_mute.mute_flag);
2293 v->cvs_state = CMD_STATUS_FAIL;
2294 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_mute_cmd);
2295 if (ret < 0) {
2296 pr_err("Fail: send STREAM SET MUTE\n");
2297 goto fail;
2298 }
2299 ret = wait_event_timeout(v->cvs_wait,
2300 (v->cvs_state == CMD_STATUS_SUCCESS),
2301 msecs_to_jiffies(TIMEOUT_MS));
2302 if (!ret)
2303 pr_err("%s: wait_event timeout\n", __func__);
2304
2305 return 0;
2306fail:
2307 return -EINVAL;
2308}
2309
2310static int voice_send_vol_index_cmd(struct voice_data *v)
2311{
2312 struct cvp_set_rx_volume_index_cmd cvp_vol_cmd;
2313 int ret = 0;
2314 void *apr_cvp;
2315 u16 cvp_handle;
2316 if (v == NULL) {
2317 pr_err("%s: v is NULL\n", __func__);
2318 return -EINVAL;
2319 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07002320 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002321
2322 if (!apr_cvp) {
2323 pr_err("%s: apr_cvp is NULL.\n", __func__);
2324 return -EINVAL;
2325 }
2326 cvp_handle = voice_get_cvp_handle(v);
2327
2328 /* send volume index to cvp */
2329 cvp_vol_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2330 APR_HDR_LEN(APR_HDR_SIZE),
2331 APR_PKT_VER);
2332 cvp_vol_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2333 sizeof(cvp_vol_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002334 cvp_vol_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002335 cvp_vol_cmd.hdr.dest_port = cvp_handle;
2336 cvp_vol_cmd.hdr.token = 0;
2337 cvp_vol_cmd.hdr.opcode = VSS_IVOCPROC_CMD_SET_RX_VOLUME_INDEX;
2338 cvp_vol_cmd.cvp_set_vol_idx.vol_index = v->dev_rx.volume;
2339 v->cvp_state = CMD_STATUS_FAIL;
2340 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_vol_cmd);
2341 if (ret < 0) {
2342 pr_err("Fail in sending RX VOL INDEX\n");
2343 return -EINVAL;
2344 }
2345 ret = wait_event_timeout(v->cvp_wait,
2346 (v->cvp_state == CMD_STATUS_SUCCESS),
2347 msecs_to_jiffies(TIMEOUT_MS));
2348 if (!ret) {
2349 pr_err("%s: wait_event timeout\n", __func__);
2350 return -EINVAL;
2351 }
2352 return 0;
2353}
2354
Helen Zenge3d716a2011-10-14 16:32:16 -07002355static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode)
2356{
2357 int ret = 0;
2358 void *apr_cvs;
2359 u16 cvs_handle;
2360
2361 struct cvs_start_record_cmd cvs_start_record;
2362
2363 if (v == NULL) {
2364 pr_err("%s: v is NULL\n", __func__);
2365 return -EINVAL;
2366 }
2367 apr_cvs = common.apr_q6_cvs;
2368
2369 if (!apr_cvs) {
2370 pr_err("%s: apr_cvs is NULL.\n", __func__);
2371 return -EINVAL;
2372 }
2373
2374 cvs_handle = voice_get_cvs_handle(v);
2375
2376 if (!v->rec_info.recording) {
2377 cvs_start_record.hdr.hdr_field = APR_HDR_FIELD(
2378 APR_MSG_TYPE_SEQ_CMD,
2379 APR_HDR_LEN(APR_HDR_SIZE),
2380 APR_PKT_VER);
2381 cvs_start_record.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2382 sizeof(cvs_start_record) - APR_HDR_SIZE);
2383 cvs_start_record.hdr.src_port = v->session_id;
2384 cvs_start_record.hdr.dest_port = cvs_handle;
2385 cvs_start_record.hdr.token = 0;
2386 cvs_start_record.hdr.opcode = VSS_ISTREAM_CMD_START_RECORD;
2387
2388 if (rec_mode == VOC_REC_UPLINK) {
2389 cvs_start_record.rec_mode.rx_tap_point =
2390 VSS_TAP_POINT_NONE;
2391 cvs_start_record.rec_mode.tx_tap_point =
2392 VSS_TAP_POINT_STREAM_END;
2393 } else if (rec_mode == VOC_REC_DOWNLINK) {
2394 cvs_start_record.rec_mode.rx_tap_point =
2395 VSS_TAP_POINT_STREAM_END;
2396 cvs_start_record.rec_mode.tx_tap_point =
2397 VSS_TAP_POINT_NONE;
2398 } else if (rec_mode == VOC_REC_BOTH) {
2399 cvs_start_record.rec_mode.rx_tap_point =
2400 VSS_TAP_POINT_STREAM_END;
2401 cvs_start_record.rec_mode.tx_tap_point =
2402 VSS_TAP_POINT_STREAM_END;
2403 } else {
2404 pr_err("%s: Invalid in-call rec_mode %d\n", __func__,
2405 rec_mode);
2406
2407 ret = -EINVAL;
2408 goto fail;
2409 }
2410
2411 v->cvs_state = CMD_STATUS_FAIL;
2412
2413 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_start_record);
2414 if (ret < 0) {
2415 pr_err("%s: Error %d sending START_RECORD\n", __func__,
2416 ret);
2417
2418 goto fail;
2419 }
2420
2421 ret = wait_event_timeout(v->cvs_wait,
2422 (v->cvs_state == CMD_STATUS_SUCCESS),
2423 msecs_to_jiffies(TIMEOUT_MS));
2424
2425 if (!ret) {
2426 pr_err("%s: wait_event timeout\n", __func__);
2427
2428 goto fail;
2429 }
2430 v->rec_info.recording = 1;
2431 } else {
2432 pr_debug("%s: Start record already sent\n", __func__);
2433 }
2434
2435 return 0;
2436
2437fail:
2438 return ret;
2439}
2440
2441static int voice_cvs_stop_record(struct voice_data *v)
2442{
2443 int ret = 0;
2444 void *apr_cvs;
2445 u16 cvs_handle;
2446 struct apr_hdr cvs_stop_record;
2447
2448 if (v == NULL) {
2449 pr_err("%s: v is NULL\n", __func__);
2450 return -EINVAL;
2451 }
2452 apr_cvs = common.apr_q6_cvs;
2453
2454 if (!apr_cvs) {
2455 pr_err("%s: apr_cvs is NULL.\n", __func__);
2456 return -EINVAL;
2457 }
2458
2459 cvs_handle = voice_get_cvs_handle(v);
2460
2461 if (v->rec_info.recording) {
2462 cvs_stop_record.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2463 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2464 cvs_stop_record.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2465 sizeof(cvs_stop_record) - APR_HDR_SIZE);
2466 cvs_stop_record.src_port = v->session_id;
2467 cvs_stop_record.dest_port = cvs_handle;
2468 cvs_stop_record.token = 0;
2469 cvs_stop_record.opcode = VSS_ISTREAM_CMD_STOP_RECORD;
2470
2471 v->cvs_state = CMD_STATUS_FAIL;
2472
2473 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_stop_record);
2474 if (ret < 0) {
2475 pr_err("%s: Error %d sending STOP_RECORD\n",
2476 __func__, ret);
2477
2478 goto fail;
2479 }
2480
2481 ret = wait_event_timeout(v->cvs_wait,
2482 (v->cvs_state == CMD_STATUS_SUCCESS),
2483 msecs_to_jiffies(TIMEOUT_MS));
2484 if (!ret) {
2485 pr_err("%s: wait_event timeout\n", __func__);
2486
2487 goto fail;
2488 }
2489 v->rec_info.recording = 0;
2490 } else {
2491 pr_debug("%s: Stop record already sent\n", __func__);
2492 }
2493
2494 return 0;
2495
2496fail:
2497
2498 return ret;
2499}
2500
2501int voc_start_record(uint32_t port_id, uint32_t set)
2502{
2503 int ret = 0;
2504 int rec_mode = 0;
2505 u16 cvs_handle;
2506 int i, rec_set = 0;
2507
2508 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
2509 struct voice_data *v = &common.voice[i];
2510 pr_debug("%s: i:%d port_id: %d, set: %d\n",
2511 __func__, i, port_id, set);
2512
2513 mutex_lock(&v->lock);
2514 rec_mode = v->rec_info.rec_mode;
2515 rec_set = set;
2516 if (set) {
2517 if ((v->rec_route_state.ul_flag != 0) &&
2518 (v->rec_route_state.dl_flag != 0)) {
2519 pr_debug("%s: i=%d, rec mode already set.\n",
2520 __func__, i);
2521 mutex_unlock(&v->lock);
2522 if (i < MAX_VOC_SESSIONS)
2523 continue;
2524 else
2525 return 0;
2526 }
2527
2528 if (port_id == VOICE_RECORD_TX) {
2529 if ((v->rec_route_state.ul_flag == 0)
2530 && (v->rec_route_state.dl_flag == 0)) {
2531 rec_mode = VOC_REC_UPLINK;
2532 v->rec_route_state.ul_flag = 1;
2533 } else if ((v->rec_route_state.ul_flag == 0)
2534 && (v->rec_route_state.dl_flag != 0)) {
2535 voice_cvs_stop_record(v);
2536 rec_mode = VOC_REC_BOTH;
2537 v->rec_route_state.ul_flag = 1;
2538 }
2539 } else if (port_id == VOICE_RECORD_RX) {
2540 if ((v->rec_route_state.ul_flag == 0)
2541 && (v->rec_route_state.dl_flag == 0)) {
2542 rec_mode = VOC_REC_DOWNLINK;
2543 v->rec_route_state.dl_flag = 1;
2544 } else if ((v->rec_route_state.ul_flag != 0)
2545 && (v->rec_route_state.dl_flag == 0)) {
2546 voice_cvs_stop_record(v);
2547 rec_mode = VOC_REC_BOTH;
2548 v->rec_route_state.dl_flag = 1;
2549 }
2550 }
2551 rec_set = 1;
2552 } else {
2553 if ((v->rec_route_state.ul_flag == 0) &&
2554 (v->rec_route_state.dl_flag == 0)) {
2555 pr_debug("%s: i=%d, rec already stops.\n",
2556 __func__, i);
2557 mutex_unlock(&v->lock);
2558 if (i < MAX_VOC_SESSIONS)
2559 continue;
2560 else
2561 return 0;
2562 }
2563
2564 if (port_id == VOICE_RECORD_TX) {
2565 if ((v->rec_route_state.ul_flag != 0)
2566 && (v->rec_route_state.dl_flag == 0)) {
2567 v->rec_route_state.ul_flag = 0;
2568 rec_set = 0;
2569 } else if ((v->rec_route_state.ul_flag != 0)
2570 && (v->rec_route_state.dl_flag != 0)) {
2571 voice_cvs_stop_record(v);
2572 v->rec_route_state.ul_flag = 0;
2573 rec_mode = VOC_REC_DOWNLINK;
2574 rec_set = 1;
2575 }
2576 } else if (port_id == VOICE_RECORD_RX) {
2577 if ((v->rec_route_state.ul_flag == 0)
2578 && (v->rec_route_state.dl_flag != 0)) {
2579 v->rec_route_state.dl_flag = 0;
2580 rec_set = 0;
2581 } else if ((v->rec_route_state.ul_flag != 0)
2582 && (v->rec_route_state.dl_flag != 0)) {
2583 voice_cvs_stop_record(v);
2584 v->rec_route_state.dl_flag = 0;
2585 rec_mode = VOC_REC_UPLINK;
2586 rec_set = 1;
2587 }
2588 }
2589 }
2590 pr_debug("%s: i=%d, mode =%d, set =%d\n", __func__,
2591 i, rec_mode, rec_set);
2592 cvs_handle = voice_get_cvs_handle(v);
2593
2594 if (cvs_handle != 0) {
2595 if (rec_set)
2596 ret = voice_cvs_start_record(v, rec_mode);
2597 else
2598 ret = voice_cvs_stop_record(v);
2599 }
2600
2601 /* Cache the value */
2602 v->rec_info.rec_enable = rec_set;
2603 v->rec_info.rec_mode = rec_mode;
2604
2605 mutex_unlock(&v->lock);
2606 }
2607
2608 return ret;
2609}
2610
Helen Zeng0705a5f2011-10-14 15:29:52 -07002611static int voice_cvs_start_playback(struct voice_data *v)
2612{
2613 int ret = 0;
2614 struct apr_hdr cvs_start_playback;
2615 void *apr_cvs;
2616 u16 cvs_handle;
2617
2618 if (v == NULL) {
2619 pr_err("%s: v is NULL\n", __func__);
2620 return -EINVAL;
2621 }
2622 apr_cvs = common.apr_q6_cvs;
2623
2624 if (!apr_cvs) {
2625 pr_err("%s: apr_cvs is NULL.\n", __func__);
2626 return -EINVAL;
2627 }
2628
2629 cvs_handle = voice_get_cvs_handle(v);
2630
2631 if (!v->music_info.playing && v->music_info.count) {
2632 cvs_start_playback.hdr_field = APR_HDR_FIELD(
2633 APR_MSG_TYPE_SEQ_CMD,
2634 APR_HDR_LEN(APR_HDR_SIZE),
2635 APR_PKT_VER);
2636 cvs_start_playback.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2637 sizeof(cvs_start_playback) - APR_HDR_SIZE);
2638 cvs_start_playback.src_port = v->session_id;
2639 cvs_start_playback.dest_port = cvs_handle;
2640 cvs_start_playback.token = 0;
2641 cvs_start_playback.opcode = VSS_ISTREAM_CMD_START_PLAYBACK;
2642
2643 v->cvs_state = CMD_STATUS_FAIL;
2644
2645 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_start_playback);
2646
2647 if (ret < 0) {
2648 pr_err("%s: Error %d sending START_PLAYBACK\n",
2649 __func__, ret);
2650
2651 goto fail;
2652 }
2653
2654 ret = wait_event_timeout(v->cvs_wait,
2655 (v->cvs_state == CMD_STATUS_SUCCESS),
2656 msecs_to_jiffies(TIMEOUT_MS));
2657 if (!ret) {
2658 pr_err("%s: wait_event timeout\n", __func__);
2659
2660 goto fail;
2661 }
2662
2663 v->music_info.playing = 1;
2664 } else {
2665 pr_debug("%s: Start playback already sent\n", __func__);
2666 }
2667
2668 return 0;
2669
2670fail:
2671 return ret;
2672}
2673
2674static int voice_cvs_stop_playback(struct voice_data *v)
2675{
2676 int ret = 0;
2677 struct apr_hdr cvs_stop_playback;
2678 void *apr_cvs;
2679 u16 cvs_handle;
2680
2681 if (v == NULL) {
2682 pr_err("%s: v is NULL\n", __func__);
2683 return -EINVAL;
2684 }
2685 apr_cvs = common.apr_q6_cvs;
2686
2687 if (!apr_cvs) {
2688 pr_err("%s: apr_cvs is NULL.\n", __func__);
2689 return -EINVAL;
2690 }
2691
2692 cvs_handle = voice_get_cvs_handle(v);
2693
2694 if (v->music_info.playing && ((!v->music_info.count) ||
2695 (v->music_info.force))) {
2696 cvs_stop_playback.hdr_field =
2697 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2698 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2699 cvs_stop_playback.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2700 sizeof(cvs_stop_playback) - APR_HDR_SIZE);
2701 cvs_stop_playback.src_port = v->session_id;
2702 cvs_stop_playback.dest_port = cvs_handle;
2703 cvs_stop_playback.token = 0;
2704
2705 cvs_stop_playback.opcode = VSS_ISTREAM_CMD_STOP_PLAYBACK;
2706
2707 v->cvs_state = CMD_STATUS_FAIL;
2708
2709 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_stop_playback);
2710 if (ret < 0) {
2711 pr_err("%s: Error %d sending STOP_PLAYBACK\n",
2712 __func__, ret);
2713
2714
2715 goto fail;
2716 }
2717
2718 ret = wait_event_timeout(v->cvs_wait,
2719 (v->cvs_state == CMD_STATUS_SUCCESS),
2720 msecs_to_jiffies(TIMEOUT_MS));
2721 if (!ret) {
2722 pr_err("%s: wait_event timeout\n", __func__);
2723
2724 goto fail;
2725 }
2726
2727 v->music_info.playing = 0;
2728 v->music_info.force = 0;
2729 } else {
2730 pr_debug("%s: Stop playback already sent\n", __func__);
2731 }
2732
2733 return 0;
2734
2735fail:
2736 return ret;
2737}
2738
2739int voc_start_playback(uint32_t set)
2740{
2741 int ret = 0;
2742 u16 cvs_handle;
2743 int i;
2744
2745
2746 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
2747 struct voice_data *v = &common.voice[i];
2748
2749 mutex_lock(&v->lock);
2750 v->music_info.play_enable = set;
2751 if (set)
2752 v->music_info.count++;
2753 else
2754 v->music_info.count--;
2755 pr_debug("%s: music_info count =%d\n", __func__,
2756 v->music_info.count);
2757
2758 cvs_handle = voice_get_cvs_handle(v);
2759 if (cvs_handle != 0) {
2760 if (set)
2761 ret = voice_cvs_start_playback(v);
2762 else
2763 ret = voice_cvs_stop_playback(v);
2764 }
2765
2766 mutex_unlock(&v->lock);
2767 }
2768
2769 return ret;
2770}
2771
Neema Shetty2c07eb52011-08-21 20:33:52 -07002772int voc_disable_cvp(uint16_t session_id)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002773{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002774 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002775 int ret = 0;
2776
Neema Shetty2c07eb52011-08-21 20:33:52 -07002777 if (v == NULL) {
2778 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2779
2780 return -EINVAL;
2781 }
2782
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002783 mutex_lock(&v->lock);
2784
2785 if (v->voc_state == VOC_RUN) {
Laxminath Kasam5b9cf0f2011-12-09 15:24:20 +05302786 if (v->dev_tx.port_id != RT_PROXY_PORT_001_TX &&
2787 v->dev_rx.port_id != RT_PROXY_PORT_001_RX)
2788 afe_sidetone(v->dev_tx.port_id, v->dev_rx.port_id,
2789 0, 0);
Ben Romberger13b74ab2011-07-18 17:36:32 -07002790
2791 rtac_remove_voice(voice_get_cvs_handle(v));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002792 /* send cmd to dsp to disable vocproc */
2793 ret = voice_send_disable_vocproc_cmd(v);
2794 if (ret < 0) {
2795 pr_err("%s: disable vocproc failed\n", __func__);
2796 goto fail;
2797 }
Helen Zeng29eb7442011-06-20 11:06:29 -07002798
2799 /* deregister cvp and vol cal */
2800 voice_send_cvp_deregister_vol_cal_table_cmd(v);
2801 voice_send_cvp_deregister_cal_cmd(v);
2802 voice_send_cvp_unmap_memory_cmd(v);
2803
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002804 v->voc_state = VOC_CHANGE;
2805 }
2806
2807fail: mutex_unlock(&v->lock);
2808
2809 return ret;
2810}
2811
Neema Shetty2c07eb52011-08-21 20:33:52 -07002812int voc_enable_cvp(uint16_t session_id)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002813{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002814 struct voice_data *v = voice_get_session(session_id);
Helen Zengbd58e2c2011-07-01 16:24:31 -07002815 struct sidetone_cal sidetone_cal_data;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002816 int ret = 0;
2817
Neema Shetty2c07eb52011-08-21 20:33:52 -07002818 if (v == NULL) {
2819 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2820
2821 return -EINVAL;
2822 }
2823
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002824 mutex_lock(&v->lock);
2825
2826 if (v->voc_state == VOC_CHANGE) {
2827 ret = voice_send_set_device_cmd(v);
2828 if (ret < 0) {
2829 pr_err("%s: set device failed\n", __func__);
2830 goto fail;
2831 }
Helen Zeng29eb7442011-06-20 11:06:29 -07002832 /* send cvp and vol cal */
2833 ret = voice_send_cvp_map_memory_cmd(v);
2834 if (!ret) {
2835 voice_send_cvp_register_cal_cmd(v);
2836 voice_send_cvp_register_vol_cal_table_cmd(v);
2837 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002838 ret = voice_send_enable_vocproc_cmd(v);
2839 if (ret < 0) {
Neema Shetty2c07eb52011-08-21 20:33:52 -07002840 pr_err("%s: enable vocproc failed\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002841 goto fail;
Helen Zengcc65b5b2011-07-06 19:14:48 -07002842
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002843 }
Helen Zengcc65b5b2011-07-06 19:14:48 -07002844 /* send tty mode if tty device is used */
2845 voice_send_tty_mode_cmd(v);
2846
Helen Zeng44d4d272011-08-10 14:49:20 -07002847 /* enable widevoice if wv_enable is set */
2848 if (v->wv_enable)
2849 voice_send_set_widevoice_enable_cmd(v);
2850
Helen Zengbb49c702011-09-06 14:09:13 -07002851 /* enable slowtalk */
2852 if (v->st_enable)
Helen Zeng4e531942011-12-17 21:14:40 -08002853 voice_send_set_pp_enable_cmd(v,
2854 MODULE_ID_VOICE_MODULE_ST,
2855 v->st_enable);
2856 /* enable FENS */
2857 if (v->fens_enable)
2858 voice_send_set_pp_enable_cmd(v,
2859 MODULE_ID_VOICE_MODULE_FENS,
2860 v->fens_enable);
Helen Zengbb49c702011-09-06 14:09:13 -07002861
Helen Zengbd58e2c2011-07-01 16:24:31 -07002862 get_sidetone_cal(&sidetone_cal_data);
Laxminath Kasam5b9cf0f2011-12-09 15:24:20 +05302863 if (v->dev_tx.port_id != RT_PROXY_PORT_001_TX &&
2864 v->dev_rx.port_id != RT_PROXY_PORT_001_RX) {
2865 ret = afe_sidetone(v->dev_tx.port_id,
2866 v->dev_rx.port_id,
2867 sidetone_cal_data.enable,
2868 sidetone_cal_data.gain);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002869
Laxminath Kasam5b9cf0f2011-12-09 15:24:20 +05302870 if (ret < 0)
2871 pr_err("%s: AFE command sidetone failed\n",
2872 __func__);
2873 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002874
Ben Romberger13b74ab2011-07-18 17:36:32 -07002875 rtac_add_voice(voice_get_cvs_handle(v),
2876 voice_get_cvp_handle(v),
Ben Rombergerc5d6a372011-09-22 18:01:49 -07002877 v->dev_rx.port_id, v->dev_tx.port_id,
2878 v->session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002879 v->voc_state = VOC_RUN;
2880 }
2881
2882fail:
2883 mutex_unlock(&v->lock);
2884
2885 return ret;
2886}
2887
Neema Shetty2c07eb52011-08-21 20:33:52 -07002888int voc_set_tx_mute(uint16_t session_id, uint32_t dir, uint32_t mute)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002889{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002890 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002891 int ret = 0;
2892
Neema Shetty2c07eb52011-08-21 20:33:52 -07002893 if (v == NULL) {
2894 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2895
2896 return -EINVAL;
2897 }
2898
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002899 mutex_lock(&v->lock);
2900
2901 v->dev_tx.mute = mute;
2902
2903 if (v->voc_state == VOC_RUN)
2904 ret = voice_send_mute_cmd(v);
2905
2906 mutex_unlock(&v->lock);
2907
2908 return ret;
2909}
2910
Neema Shetty2c07eb52011-08-21 20:33:52 -07002911int voc_set_tty_mode(uint16_t session_id, uint8_t tty_mode)
Helen Zengcc65b5b2011-07-06 19:14:48 -07002912{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002913 struct voice_data *v = voice_get_session(session_id);
Helen Zengcc65b5b2011-07-06 19:14:48 -07002914 int ret = 0;
2915
Neema Shetty2c07eb52011-08-21 20:33:52 -07002916 if (v == NULL) {
2917 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2918
2919 return -EINVAL;
2920 }
2921
Helen Zengcc65b5b2011-07-06 19:14:48 -07002922 mutex_lock(&v->lock);
2923
2924 v->tty_mode = tty_mode;
2925
2926 mutex_unlock(&v->lock);
2927
2928 return ret;
2929}
2930
Neema Shetty2c07eb52011-08-21 20:33:52 -07002931uint8_t voc_get_tty_mode(uint16_t session_id)
Helen Zengcc65b5b2011-07-06 19:14:48 -07002932{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002933 struct voice_data *v = voice_get_session(session_id);
Helen Zengcc65b5b2011-07-06 19:14:48 -07002934 int ret = 0;
2935
Neema Shetty2c07eb52011-08-21 20:33:52 -07002936 if (v == NULL) {
2937 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2938
2939 return -EINVAL;
2940 }
2941
Helen Zengcc65b5b2011-07-06 19:14:48 -07002942 mutex_lock(&v->lock);
2943
2944 ret = v->tty_mode;
2945
2946 mutex_unlock(&v->lock);
2947
2948 return ret;
2949}
2950
Neema Shetty2c07eb52011-08-21 20:33:52 -07002951int voc_set_widevoice_enable(uint16_t session_id, uint32_t wv_enable)
Helen Zeng44d4d272011-08-10 14:49:20 -07002952{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002953 struct voice_data *v = voice_get_session(session_id);
Helen Zengb73acce2011-09-15 18:23:01 -07002954 u16 mvm_handle;
Helen Zeng44d4d272011-08-10 14:49:20 -07002955 int ret = 0;
2956
Neema Shetty2c07eb52011-08-21 20:33:52 -07002957 if (v == NULL) {
2958 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2959
2960 return -EINVAL;
2961 }
2962
Helen Zeng44d4d272011-08-10 14:49:20 -07002963 mutex_lock(&v->lock);
2964
2965 v->wv_enable = wv_enable;
2966
Helen Zengb73acce2011-09-15 18:23:01 -07002967 mvm_handle = voice_get_mvm_handle(v);
2968
2969 if (mvm_handle != 0)
2970 voice_send_set_widevoice_enable_cmd(v);
2971
Helen Zeng44d4d272011-08-10 14:49:20 -07002972 mutex_unlock(&v->lock);
2973
2974 return ret;
2975}
2976
Neema Shetty2c07eb52011-08-21 20:33:52 -07002977uint32_t voc_get_widevoice_enable(uint16_t session_id)
Helen Zeng44d4d272011-08-10 14:49:20 -07002978{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002979 struct voice_data *v = voice_get_session(session_id);
Helen Zeng44d4d272011-08-10 14:49:20 -07002980 int ret = 0;
2981
Neema Shetty2c07eb52011-08-21 20:33:52 -07002982 if (v == NULL) {
2983 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2984
2985 return -EINVAL;
2986 }
2987
Helen Zeng44d4d272011-08-10 14:49:20 -07002988 mutex_lock(&v->lock);
2989
2990 ret = v->wv_enable;
2991
2992 mutex_unlock(&v->lock);
2993
2994 return ret;
2995}
2996
Helen Zeng4e531942011-12-17 21:14:40 -08002997int voc_set_pp_enable(uint16_t session_id, uint32_t module_id, uint32_t enable)
Helen Zengbb49c702011-09-06 14:09:13 -07002998{
2999 struct voice_data *v = voice_get_session(session_id);
3000 int ret = 0;
3001
3002 if (v == NULL) {
3003 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3004
3005 return -EINVAL;
3006 }
3007
3008 mutex_lock(&v->lock);
Helen Zeng4e531942011-12-17 21:14:40 -08003009 if (module_id == MODULE_ID_VOICE_MODULE_ST)
3010 v->st_enable = enable;
3011 else if (module_id == MODULE_ID_VOICE_MODULE_FENS)
3012 v->fens_enable = enable;
Helen Zengbb49c702011-09-06 14:09:13 -07003013
Helen Zeng4e531942011-12-17 21:14:40 -08003014 if (v->voc_state == VOC_RUN) {
3015 if (module_id == MODULE_ID_VOICE_MODULE_ST)
3016 ret = voice_send_set_pp_enable_cmd(v,
3017 MODULE_ID_VOICE_MODULE_ST,
3018 enable);
3019 else if (module_id == MODULE_ID_VOICE_MODULE_FENS)
3020 ret = voice_send_set_pp_enable_cmd(v,
3021 MODULE_ID_VOICE_MODULE_FENS,
3022 enable);
3023 }
Helen Zengbb49c702011-09-06 14:09:13 -07003024 mutex_unlock(&v->lock);
3025
3026 return ret;
3027}
3028
Helen Zeng4e531942011-12-17 21:14:40 -08003029int voc_get_pp_enable(uint16_t session_id, uint32_t module_id)
Helen Zengbb49c702011-09-06 14:09:13 -07003030{
3031 struct voice_data *v = voice_get_session(session_id);
3032 int ret = 0;
3033
3034 if (v == NULL) {
3035 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3036
3037 return -EINVAL;
3038 }
3039
3040 mutex_lock(&v->lock);
Helen Zeng4e531942011-12-17 21:14:40 -08003041 if (module_id == MODULE_ID_VOICE_MODULE_ST)
3042 ret = v->st_enable;
3043 else if (module_id == MODULE_ID_VOICE_MODULE_FENS)
3044 ret = v->fens_enable;
Helen Zengbb49c702011-09-06 14:09:13 -07003045
3046 mutex_unlock(&v->lock);
3047
3048 return ret;
3049}
3050
Neema Shetty2c07eb52011-08-21 20:33:52 -07003051int voc_set_rx_vol_index(uint16_t session_id, uint32_t dir, uint32_t vol_idx)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003052{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003053 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003054 int ret = 0;
3055
Neema Shetty2c07eb52011-08-21 20:33:52 -07003056 if (v == NULL) {
3057 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3058
3059 return -EINVAL;
3060 }
3061
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003062 mutex_lock(&v->lock);
3063
3064 v->dev_rx.volume = vol_idx;
3065
3066 if (v->voc_state == VOC_RUN)
3067 ret = voice_send_vol_index_cmd(v);
3068
3069 mutex_unlock(&v->lock);
3070
3071 return ret;
3072}
3073
Neema Shetty2c07eb52011-08-21 20:33:52 -07003074int voc_set_rxtx_port(uint16_t session_id, uint32_t port_id, uint32_t dev_type)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003075{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003076 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003077
Neema Shetty2c07eb52011-08-21 20:33:52 -07003078 if (v == NULL) {
3079 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3080
3081 return -EINVAL;
3082 }
3083
3084 pr_debug("%s: port_id=%d, type=%d\n", __func__, port_id, dev_type);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003085
3086 mutex_lock(&v->lock);
3087
3088 if (dev_type == DEV_RX)
3089 v->dev_rx.port_id = port_id;
3090 else
3091 v->dev_tx.port_id = port_id;
3092
3093 mutex_unlock(&v->lock);
3094
Neema Shetty2c07eb52011-08-21 20:33:52 -07003095 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003096}
3097
Neema Shetty2c07eb52011-08-21 20:33:52 -07003098int voc_set_route_flag(uint16_t session_id, uint8_t path_dir, uint8_t set)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003099{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003100 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003101
Neema Shetty2c07eb52011-08-21 20:33:52 -07003102 if (v == NULL) {
3103 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3104
3105 return -EINVAL;
3106 }
3107
3108 pr_debug("%s: path_dir=%d, set=%d\n", __func__, path_dir, set);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003109
3110 mutex_lock(&v->lock);
3111
3112 if (path_dir == RX_PATH)
3113 v->voc_route_state.rx_route_flag = set;
3114 else
3115 v->voc_route_state.tx_route_flag = set;
3116
3117 mutex_unlock(&v->lock);
3118
Neema Shetty2c07eb52011-08-21 20:33:52 -07003119 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003120}
3121
Neema Shetty2c07eb52011-08-21 20:33:52 -07003122uint8_t voc_get_route_flag(uint16_t session_id, uint8_t path_dir)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003123{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003124 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003125 int ret = 0;
3126
Neema Shetty2c07eb52011-08-21 20:33:52 -07003127 if (v == NULL) {
3128 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3129
3130 return 0;
3131 }
3132
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003133 mutex_lock(&v->lock);
3134
3135 if (path_dir == RX_PATH)
3136 ret = v->voc_route_state.rx_route_flag;
3137 else
3138 ret = v->voc_route_state.tx_route_flag;
3139
3140 mutex_unlock(&v->lock);
3141
3142 return ret;
3143}
3144
Neema Shetty2c07eb52011-08-21 20:33:52 -07003145int voc_end_voice_call(uint16_t session_id)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003146{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003147 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003148 int ret = 0;
3149
Neema Shetty2c07eb52011-08-21 20:33:52 -07003150 if (v == NULL) {
3151 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3152
3153 return -EINVAL;
3154 }
3155
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003156 mutex_lock(&v->lock);
3157
3158 if (v->voc_state == VOC_RUN) {
Laxminath Kasam5b9cf0f2011-12-09 15:24:20 +05303159 if (v->dev_tx.port_id != RT_PROXY_PORT_001_TX &&
3160 v->dev_rx.port_id != RT_PROXY_PORT_001_RX)
3161 afe_sidetone(v->dev_tx.port_id, v->dev_rx.port_id,
3162 0, 0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003163 ret = voice_destroy_vocproc(v);
3164 if (ret < 0)
3165 pr_err("%s: destroy voice failed\n", __func__);
3166 voice_destroy_mvm_cvs_session(v);
3167
3168 v->voc_state = VOC_RELEASE;
3169 }
3170 mutex_unlock(&v->lock);
3171 return ret;
3172}
3173
Neema Shetty2c07eb52011-08-21 20:33:52 -07003174int voc_start_voice_call(uint16_t session_id)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003175{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003176 struct voice_data *v = voice_get_session(session_id);
Helen Zengbd58e2c2011-07-01 16:24:31 -07003177 struct sidetone_cal sidetone_cal_data;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003178 int ret = 0;
3179
Neema Shetty2c07eb52011-08-21 20:33:52 -07003180 if (v == NULL) {
3181 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3182
3183 return -EINVAL;
3184 }
3185
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003186 mutex_lock(&v->lock);
3187
3188 if ((v->voc_state == VOC_INIT) ||
3189 (v->voc_state == VOC_RELEASE)) {
Neema Shetty2c07eb52011-08-21 20:33:52 -07003190 ret = voice_apr_register();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003191 if (ret < 0) {
3192 pr_err("%s: apr register failed\n", __func__);
3193 goto fail;
3194 }
3195 ret = voice_create_mvm_cvs_session(v);
3196 if (ret < 0) {
3197 pr_err("create mvm and cvs failed\n");
3198 goto fail;
3199 }
3200 ret = voice_setup_vocproc(v);
3201 if (ret < 0) {
3202 pr_err("setup voice failed\n");
3203 goto fail;
3204 }
3205 ret = voice_send_start_voice_cmd(v);
3206 if (ret < 0) {
3207 pr_err("start voice failed\n");
3208 goto fail;
3209 }
Helen Zengbd58e2c2011-07-01 16:24:31 -07003210 get_sidetone_cal(&sidetone_cal_data);
Laxminath Kasam5b9cf0f2011-12-09 15:24:20 +05303211 if (v->dev_tx.port_id != RT_PROXY_PORT_001_TX &&
3212 v->dev_rx.port_id != RT_PROXY_PORT_001_RX) {
3213 ret = afe_sidetone(v->dev_tx.port_id,
Helen Zengbd58e2c2011-07-01 16:24:31 -07003214 v->dev_rx.port_id,
3215 sidetone_cal_data.enable,
3216 sidetone_cal_data.gain);
Laxminath Kasam5b9cf0f2011-12-09 15:24:20 +05303217 if (ret < 0)
3218 pr_err("AFE command sidetone failed\n");
3219 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003220
3221 v->voc_state = VOC_RUN;
3222 }
3223
3224fail: mutex_unlock(&v->lock);
3225 return ret;
3226}
3227
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003228void voc_register_mvs_cb(ul_cb_fn ul_cb,
3229 dl_cb_fn dl_cb,
3230 void *private_data)
3231{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003232 common.mvs_info.ul_cb = ul_cb;
3233 common.mvs_info.dl_cb = dl_cb;
3234 common.mvs_info.private_data = private_data;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003235}
3236
3237void voc_config_vocoder(uint32_t media_type,
3238 uint32_t rate,
3239 uint32_t network_type)
3240{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003241 common.mvs_info.media_type = media_type;
3242 common.mvs_info.rate = rate;
3243 common.mvs_info.network_type = network_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003244}
3245
3246static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv)
3247{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003248 uint32_t *ptr = NULL;
3249 struct common_data *c = NULL;
3250 struct voice_data *v = NULL;
Neema Shetty07477582011-09-02 17:35:44 -07003251 int i = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003252
3253 if ((data == NULL) || (priv == NULL)) {
3254 pr_err("%s: data or priv is NULL\n", __func__);
3255 return -EINVAL;
3256 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07003257
3258 c = priv;
3259
3260 pr_debug("%s: session_id 0x%x\n", __func__, data->dest_port);
3261
3262 v = voice_get_session(data->dest_port);
3263 if (v == NULL) {
3264 pr_err("%s: v is NULL\n", __func__);
3265
3266 return -EINVAL;
3267 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003268
3269 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
3270 data->payload_size, data->opcode);
3271
Neema Shetty07477582011-09-02 17:35:44 -07003272 if (data->opcode == RESET_EVENTS) {
3273 pr_debug("%s: Reset event received in Voice service\n",
3274 __func__);
3275
3276 apr_reset(c->apr_q6_mvm);
3277 c->apr_q6_mvm = NULL;
3278
3279 /* Sub-system restart is applicable to all sessions. */
3280 for (i = 0; i < MAX_VOC_SESSIONS; i++)
3281 c->voice[i].mvm_handle = 0;
3282
3283 return 0;
3284 }
3285
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003286 if (data->opcode == APR_BASIC_RSP_RESULT) {
3287 if (data->payload_size) {
3288 ptr = data->payload;
3289
3290 pr_info("%x %x\n", ptr[0], ptr[1]);
3291 /* ping mvm service ACK */
3292 switch (ptr[0]) {
3293 case VSS_IMVM_CMD_CREATE_PASSIVE_CONTROL_SESSION:
3294 case VSS_IMVM_CMD_CREATE_FULL_CONTROL_SESSION:
3295 /* Passive session is used for CS call
3296 * Full session is used for VoIP call. */
3297 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
3298 if (!ptr[1]) {
3299 pr_debug("%s: MVM handle is %d\n",
3300 __func__, data->src_port);
3301 voice_set_mvm_handle(v, data->src_port);
3302 } else
3303 pr_err("got NACK for sending \
3304 MVM create session \n");
3305 v->mvm_state = CMD_STATUS_SUCCESS;
3306 wake_up(&v->mvm_wait);
3307 break;
3308 case VSS_IMVM_CMD_START_VOICE:
Helen Zeng69b00962011-07-08 11:38:36 -07003309 case VSS_IMVM_CMD_ATTACH_VOCPROC:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003310 case VSS_IMVM_CMD_STOP_VOICE:
Helen Zeng69b00962011-07-08 11:38:36 -07003311 case VSS_IMVM_CMD_DETACH_VOCPROC:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003312 case VSS_ISTREAM_CMD_SET_TTY_MODE:
3313 case APRV2_IBASIC_CMD_DESTROY_SESSION:
3314 case VSS_IMVM_CMD_ATTACH_STREAM:
3315 case VSS_IMVM_CMD_DETACH_STREAM:
3316 case VSS_ICOMMON_CMD_SET_NETWORK:
3317 case VSS_ICOMMON_CMD_SET_VOICE_TIMING:
Helen Zeng44d4d272011-08-10 14:49:20 -07003318 case VSS_IWIDEVOICE_CMD_SET_WIDEVOICE:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003319 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
3320 v->mvm_state = CMD_STATUS_SUCCESS;
3321 wake_up(&v->mvm_wait);
3322 break;
3323 default:
3324 pr_debug("%s: not match cmd = 0x%x\n",
3325 __func__, ptr[0]);
3326 break;
3327 }
3328 }
3329 }
3330
3331 return 0;
3332}
3333
3334static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv)
3335{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003336 uint32_t *ptr = NULL;
3337 struct common_data *c = NULL;
3338 struct voice_data *v = NULL;
Neema Shetty07477582011-09-02 17:35:44 -07003339 int i = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003340
3341 if ((data == NULL) || (priv == NULL)) {
3342 pr_err("%s: data or priv is NULL\n", __func__);
3343 return -EINVAL;
3344 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07003345
3346 c = priv;
3347
3348 pr_debug("%s: session_id 0x%x\n", __func__, data->dest_port);
3349
3350 v = voice_get_session(data->dest_port);
3351 if (v == NULL) {
3352 pr_err("%s: v is NULL\n", __func__);
3353
3354 return -EINVAL;
3355 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003356
3357 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
3358 data->payload_size, data->opcode);
3359
Neema Shetty07477582011-09-02 17:35:44 -07003360 if (data->opcode == RESET_EVENTS) {
3361 pr_debug("%s: Reset event received in Voice service\n",
3362 __func__);
3363
3364 apr_reset(c->apr_q6_cvs);
3365 c->apr_q6_cvs = NULL;
3366
3367 /* Sub-system restart is applicable to all sessions. */
3368 for (i = 0; i < MAX_VOC_SESSIONS; i++)
3369 c->voice[i].cvs_handle = 0;
3370
3371 return 0;
3372 }
3373
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003374 if (data->opcode == APR_BASIC_RSP_RESULT) {
3375 if (data->payload_size) {
3376 ptr = data->payload;
3377
3378 pr_info("%x %x\n", ptr[0], ptr[1]);
3379 /*response from CVS */
3380 switch (ptr[0]) {
3381 case VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION:
3382 case VSS_ISTREAM_CMD_CREATE_FULL_CONTROL_SESSION:
3383 if (!ptr[1]) {
3384 pr_debug("%s: CVS handle is %d\n",
3385 __func__, data->src_port);
3386 voice_set_cvs_handle(v, data->src_port);
3387 } else
3388 pr_err("got NACK for sending \
3389 CVS create session \n");
3390 v->cvs_state = CMD_STATUS_SUCCESS;
3391 wake_up(&v->cvs_wait);
3392 break;
3393 case VSS_ISTREAM_CMD_SET_MUTE:
3394 case VSS_ISTREAM_CMD_SET_MEDIA_TYPE:
3395 case VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE:
3396 case VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE:
3397 case VSS_ISTREAM_CMD_SET_ENC_DTX_MODE:
3398 case VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE:
3399 case APRV2_IBASIC_CMD_DESTROY_SESSION:
Helen Zeng29eb7442011-06-20 11:06:29 -07003400 case VSS_ISTREAM_CMD_REGISTER_CALIBRATION_DATA:
3401 case VSS_ISTREAM_CMD_DEREGISTER_CALIBRATION_DATA:
3402 case VSS_ICOMMON_CMD_MAP_MEMORY:
3403 case VSS_ICOMMON_CMD_UNMAP_MEMORY:
Helen Zengbb49c702011-09-06 14:09:13 -07003404 case VSS_ICOMMON_CMD_SET_UI_PROPERTY:
Helen Zeng0705a5f2011-10-14 15:29:52 -07003405 case VSS_ISTREAM_CMD_START_PLAYBACK:
3406 case VSS_ISTREAM_CMD_STOP_PLAYBACK:
Helen Zenge3d716a2011-10-14 16:32:16 -07003407 case VSS_ISTREAM_CMD_START_RECORD:
3408 case VSS_ISTREAM_CMD_STOP_RECORD:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003409 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
3410 v->cvs_state = CMD_STATUS_SUCCESS;
3411 wake_up(&v->cvs_wait);
3412 break;
Ben Romberger13b74ab2011-07-18 17:36:32 -07003413 case VOICE_CMD_SET_PARAM:
3414 rtac_make_voice_callback(RTAC_CVS, ptr,
3415 data->payload_size);
3416 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003417 default:
3418 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
3419 break;
3420 }
3421 }
3422 } else if (data->opcode == VSS_ISTREAM_EVT_SEND_ENC_BUFFER) {
3423 uint32_t *voc_pkt = data->payload;
3424 uint32_t pkt_len = data->payload_size;
3425
Neema Shetty2c07eb52011-08-21 20:33:52 -07003426 if (voc_pkt != NULL && c->mvs_info.ul_cb != NULL) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003427 pr_debug("%s: Media type is 0x%x\n",
3428 __func__, voc_pkt[0]);
3429
3430 /* Remove media ID from payload. */
3431 voc_pkt++;
3432 pkt_len = pkt_len - 4;
3433
Neema Shetty2c07eb52011-08-21 20:33:52 -07003434 c->mvs_info.ul_cb((uint8_t *)voc_pkt,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003435 pkt_len,
Neema Shetty2c07eb52011-08-21 20:33:52 -07003436 c->mvs_info.private_data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003437 } else
3438 pr_err("%s: voc_pkt is 0x%x ul_cb is 0x%x\n",
3439 __func__, (unsigned int)voc_pkt,
Neema Shetty2c07eb52011-08-21 20:33:52 -07003440 (unsigned int) c->mvs_info.ul_cb);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003441 } else if (data->opcode == VSS_ISTREAM_EVT_REQUEST_DEC_BUFFER) {
3442 struct cvs_send_dec_buf_cmd send_dec_buf;
3443 int ret = 0;
3444 uint32_t pkt_len = 0;
3445
Neema Shetty2c07eb52011-08-21 20:33:52 -07003446 if (c->mvs_info.dl_cb != NULL) {
3447 send_dec_buf.dec_buf.media_id = c->mvs_info.media_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003448
Neema Shetty2c07eb52011-08-21 20:33:52 -07003449 c->mvs_info.dl_cb(
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003450 (uint8_t *)&send_dec_buf.dec_buf.packet_data,
3451 &pkt_len,
Neema Shetty2c07eb52011-08-21 20:33:52 -07003452 c->mvs_info.private_data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003453
3454 send_dec_buf.hdr.hdr_field =
3455 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
3456 APR_HDR_LEN(APR_HDR_SIZE),
3457 APR_PKT_VER);
3458 send_dec_buf.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
3459 sizeof(send_dec_buf.dec_buf.media_id) + pkt_len);
Neema Shetty2c07eb52011-08-21 20:33:52 -07003460 send_dec_buf.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003461 send_dec_buf.hdr.dest_port = voice_get_cvs_handle(v);
3462 send_dec_buf.hdr.token = 0;
3463 send_dec_buf.hdr.opcode =
3464 VSS_ISTREAM_EVT_SEND_DEC_BUFFER;
3465
Neema Shetty2c07eb52011-08-21 20:33:52 -07003466 ret = apr_send_pkt(c->apr_q6_cvs,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003467 (uint32_t *) &send_dec_buf);
3468 if (ret < 0) {
3469 pr_err("%s: Error %d sending DEC_BUF\n",
3470 __func__, ret);
3471 goto fail;
3472 }
3473 } else
3474 pr_debug("%s: dl_cb is NULL\n", __func__);
Ben Romberger13b74ab2011-07-18 17:36:32 -07003475 } else if (data->opcode == VSS_ISTREAM_EVT_SEND_DEC_BUFFER) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003476 pr_debug("Send dec buf resp\n");
Ben Romberger13b74ab2011-07-18 17:36:32 -07003477 } else if (data->opcode == VOICE_EVT_GET_PARAM_ACK) {
3478 rtac_make_voice_callback(RTAC_CVS, data->payload,
3479 data->payload_size);
3480 } else
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003481 pr_debug("Unknown opcode 0x%x\n", data->opcode);
3482
3483fail:
3484 return 0;
3485}
3486
3487static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv)
3488{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003489 uint32_t *ptr = NULL;
3490 struct common_data *c = NULL;
3491 struct voice_data *v = NULL;
Neema Shetty07477582011-09-02 17:35:44 -07003492 int i = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003493
3494 if ((data == NULL) || (priv == NULL)) {
3495 pr_err("%s: data or priv is NULL\n", __func__);
3496 return -EINVAL;
3497 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07003498
3499 c = priv;
3500
3501 v = voice_get_session(data->dest_port);
3502 if (v == NULL) {
3503 pr_err("%s: v is NULL\n", __func__);
3504
3505 return -EINVAL;
3506 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003507
3508 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
3509 data->payload_size, data->opcode);
3510
Neema Shetty07477582011-09-02 17:35:44 -07003511 if (data->opcode == RESET_EVENTS) {
3512 pr_debug("%s: Reset event received in Voice service\n",
3513 __func__);
3514
3515 apr_reset(c->apr_q6_cvp);
3516 c->apr_q6_cvp = NULL;
3517
3518 /* Sub-system restart is applicable to all sessions. */
3519 for (i = 0; i < MAX_VOC_SESSIONS; i++)
3520 c->voice[i].cvp_handle = 0;
3521
3522 return 0;
3523 }
3524
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003525 if (data->opcode == APR_BASIC_RSP_RESULT) {
3526 if (data->payload_size) {
3527 ptr = data->payload;
3528
3529 pr_info("%x %x\n", ptr[0], ptr[1]);
3530
3531 switch (ptr[0]) {
3532 case VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION:
3533 /*response from CVP */
3534 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
3535 if (!ptr[1]) {
3536 voice_set_cvp_handle(v, data->src_port);
3537 pr_debug("cvphdl=%d\n", data->src_port);
3538 } else
3539 pr_err("got NACK from CVP create \
3540 session response\n");
3541 v->cvp_state = CMD_STATUS_SUCCESS;
3542 wake_up(&v->cvp_wait);
3543 break;
3544 case VSS_IVOCPROC_CMD_SET_DEVICE:
3545 case VSS_IVOCPROC_CMD_SET_RX_VOLUME_INDEX:
3546 case VSS_IVOCPROC_CMD_ENABLE:
3547 case VSS_IVOCPROC_CMD_DISABLE:
3548 case APRV2_IBASIC_CMD_DESTROY_SESSION:
Helen Zeng29eb7442011-06-20 11:06:29 -07003549 case VSS_IVOCPROC_CMD_REGISTER_VOLUME_CAL_TABLE:
3550 case VSS_IVOCPROC_CMD_DEREGISTER_VOLUME_CAL_TABLE:
3551 case VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA:
3552 case VSS_IVOCPROC_CMD_DEREGISTER_CALIBRATION_DATA:
3553 case VSS_ICOMMON_CMD_MAP_MEMORY:
3554 case VSS_ICOMMON_CMD_UNMAP_MEMORY:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003555 v->cvp_state = CMD_STATUS_SUCCESS;
3556 wake_up(&v->cvp_wait);
3557 break;
Ben Romberger13b74ab2011-07-18 17:36:32 -07003558 case VOICE_CMD_SET_PARAM:
3559 rtac_make_voice_callback(RTAC_CVP, ptr,
3560 data->payload_size);
3561 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003562 default:
3563 pr_debug("%s: not match cmd = 0x%x\n",
3564 __func__, ptr[0]);
3565 break;
3566 }
3567 }
Ben Romberger13b74ab2011-07-18 17:36:32 -07003568 } else if (data->opcode == VOICE_EVT_GET_PARAM_ACK) {
3569 rtac_make_voice_callback(RTAC_CVP, data->payload,
3570 data->payload_size);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003571 }
3572 return 0;
3573}
3574
3575
3576static int __init voice_init(void)
3577{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003578 int rc = 0, i = 0;
3579
3580 memset(&common, 0, sizeof(struct common_data));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003581
3582 /* set default value */
Neema Shetty2c07eb52011-08-21 20:33:52 -07003583 common.default_mute_val = 1; /* default is mute */
3584 common.default_vol_val = 0;
3585 common.default_sample_val = 8000;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003586
3587 /* Initialize MVS info. */
Neema Shetty2c07eb52011-08-21 20:33:52 -07003588 common.mvs_info.network_type = VSS_NETWORK_ID_DEFAULT;
3589
3590 mutex_init(&common.common_lock);
3591
3592 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
3593 common.voice[i].session_id = SESSION_ID_BASE + i;
3594
3595 /* initialize dev_rx and dev_tx */
3596 common.voice[i].dev_rx.volume = common.default_vol_val;
3597 common.voice[i].dev_tx.mute = common.default_mute_val;
3598
3599 common.voice[i].dev_tx.port_id = 1;
3600 common.voice[i].dev_rx.port_id = 0;
3601 common.voice[i].sidetone_gain = 0x512;
3602
3603 common.voice[i].voc_state = VOC_INIT;
3604
3605 init_waitqueue_head(&common.voice[i].mvm_wait);
3606 init_waitqueue_head(&common.voice[i].cvs_wait);
3607 init_waitqueue_head(&common.voice[i].cvp_wait);
3608
3609 mutex_init(&common.voice[i].lock);
3610 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003611
3612 return rc;
3613}
3614
3615device_initcall(voice_init);