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