blob: de63fa093e6b6293cf74db8897589a5741d56e48 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
2 *
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
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070020#include <mach/qdsp6v2/audio_acdb.h>
Ben Romberger13b74ab2011-07-18 17:36:32 -070021#include <mach/qdsp6v2/rtac.h>
22
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070023#include "sound/apr_audio.h"
24#include "sound/q6afe.h"
Ben Romberger13b74ab2011-07-18 17:36:32 -070025
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070026#include "q6voice.h"
27
28#define TIMEOUT_MS 3000
29
30#define CMD_STATUS_SUCCESS 0
31#define CMD_STATUS_FAIL 1
32
33#define VOC_PATH_PASSIVE 0
34#define VOC_PATH_FULL 1
35
Neema Shetty2c07eb52011-08-21 20:33:52 -070036static struct common_data common;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070037
38static int voice_send_enable_vocproc_cmd(struct voice_data *v);
39static int voice_send_netid_timing_cmd(struct voice_data *v);
40static int voice_send_attach_vocproc_cmd(struct voice_data *v);
41static int voice_send_set_device_cmd(struct voice_data *v);
42static int voice_send_disable_vocproc_cmd(struct voice_data *v);
43static int voice_send_vol_index_cmd(struct voice_data *v);
Helen Zeng29eb7442011-06-20 11:06:29 -070044static int voice_send_cvp_map_memory_cmd(struct voice_data *v);
45static int voice_send_cvp_unmap_memory_cmd(struct voice_data *v);
46static int voice_send_cvs_map_memory_cmd(struct voice_data *v);
47static int voice_send_cvs_unmap_memory_cmd(struct voice_data *v);
48static int voice_send_cvs_register_cal_cmd(struct voice_data *v);
49static int voice_send_cvs_deregister_cal_cmd(struct voice_data *v);
50static int voice_send_cvp_register_cal_cmd(struct voice_data *v);
51static int voice_send_cvp_deregister_cal_cmd(struct voice_data *v);
52static int voice_send_cvp_register_vol_cal_table_cmd(struct voice_data *v);
53static int voice_send_cvp_deregister_vol_cal_table_cmd(struct voice_data *v);
Helen Zeng44d4d272011-08-10 14:49:20 -070054static int voice_send_set_widevoice_enable_cmd(struct voice_data *v);
Helen Zengbb49c702011-09-06 14:09:13 -070055static int voice_send_set_slowtalk_enable_cmd(struct voice_data *v);
Helen Zeng29eb7442011-06-20 11:06:29 -070056
Helen Zeng0705a5f2011-10-14 15:29:52 -070057static int voice_cvs_stop_playback(struct voice_data *v);
58static int voice_cvs_start_playback(struct voice_data *v);
Helen Zenge3d716a2011-10-14 16:32:16 -070059static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode);
60static int voice_cvs_stop_record(struct voice_data *v);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070061
62static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv);
63static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv);
64static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv);
65
66static u16 voice_get_mvm_handle(struct voice_data *v)
67{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070068 if (v == NULL) {
69 pr_err("%s: v is NULL\n", __func__);
Neema Shetty2c07eb52011-08-21 20:33:52 -070070 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070071 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070072
Neema Shetty2c07eb52011-08-21 20:33:52 -070073 pr_debug("%s: mvm_handle %d\n", __func__, v->mvm_handle);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070074
Neema Shetty2c07eb52011-08-21 20:33:52 -070075 return v->mvm_handle;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070076}
77
78static void voice_set_mvm_handle(struct voice_data *v, u16 mvm_handle)
79{
80 pr_debug("%s: mvm_handle %d\n", __func__, mvm_handle);
81 if (v == NULL) {
82 pr_err("%s: v is NULL\n", __func__);
83 return;
84 }
85
Neema Shetty2c07eb52011-08-21 20:33:52 -070086 v->mvm_handle = mvm_handle;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070087}
88
89static u16 voice_get_cvs_handle(struct voice_data *v)
90{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070091 if (v == NULL) {
92 pr_err("%s: v is NULL\n", __func__);
Neema Shetty2c07eb52011-08-21 20:33:52 -070093 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070094 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070095
Neema Shetty2c07eb52011-08-21 20:33:52 -070096 pr_debug("%s: cvs_handle %d\n", __func__, v->cvs_handle);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070097
Neema Shetty2c07eb52011-08-21 20:33:52 -070098 return v->cvs_handle;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070099}
100
101static void voice_set_cvs_handle(struct voice_data *v, u16 cvs_handle)
102{
103 pr_debug("%s: cvs_handle %d\n", __func__, cvs_handle);
104 if (v == NULL) {
105 pr_err("%s: v is NULL\n", __func__);
106 return;
107 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700108
109 v->cvs_handle = cvs_handle;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700110}
111
112static u16 voice_get_cvp_handle(struct voice_data *v)
113{
Neema Shetty2c07eb52011-08-21 20:33:52 -0700114 if (v == NULL) {
115 pr_err("%s: v is NULL\n", __func__);
116 return 0;
117 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700118
Neema Shetty2c07eb52011-08-21 20:33:52 -0700119 pr_debug("%s: cvp_handle %d\n", __func__, v->cvp_handle);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700120
Neema Shetty2c07eb52011-08-21 20:33:52 -0700121 return v->cvp_handle;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700122}
123
124static void voice_set_cvp_handle(struct voice_data *v, u16 cvp_handle)
125{
126 pr_debug("%s: cvp_handle %d\n", __func__, cvp_handle);
127 if (v == NULL) {
128 pr_err("%s: v is NULL\n", __func__);
129 return;
130 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700131
132 v->cvp_handle = cvp_handle;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700133}
134
Neema Shetty2c07eb52011-08-21 20:33:52 -0700135uint16_t voc_get_session_id(char *name)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700136{
Neema Shetty2c07eb52011-08-21 20:33:52 -0700137 u16 session_id = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700138
Neema Shetty2c07eb52011-08-21 20:33:52 -0700139 if (name != NULL) {
140 if (!strncmp(name, "Voice session", 13))
141 session_id = common.voice[VOC_PATH_PASSIVE].session_id;
142 else
143 session_id = common.voice[VOC_PATH_FULL].session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700144
Helen Zeng0f4c4e22011-09-29 14:25:43 -0700145 pr_debug("%s: %s has session id 0x%x\n", __func__, name,
146 session_id);
147 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700148
149 return session_id;
150}
151
152static struct voice_data *voice_get_session(u16 session_id)
153{
154 struct voice_data *v = NULL;
155
156 if ((session_id >= SESSION_ID_BASE) &&
157 (session_id < SESSION_ID_BASE + MAX_VOC_SESSIONS)) {
158 v = &common.voice[session_id - SESSION_ID_BASE];
159 }
160
161 pr_debug("%s: session_id 0x%x session handle 0x%x\n",
162 __func__, session_id, (unsigned int)v);
163
164 return v;
165}
166
167static bool is_voice_session(u16 session_id)
168{
169 return (session_id == common.voice[VOC_PATH_PASSIVE].session_id);
170}
171
172static bool is_voip_session(u16 session_id)
173{
174 return (session_id == common.voice[VOC_PATH_FULL].session_id);
175}
176
177static int voice_apr_register(void)
178{
179 pr_debug("%s\n", __func__);
180
181 mutex_lock(&common.common_lock);
182
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700183 /* register callback to APR */
Neema Shetty2c07eb52011-08-21 20:33:52 -0700184 if (common.apr_q6_mvm == NULL) {
185 pr_debug("%s: Start to register MVM callback\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700186
Neema Shetty2c07eb52011-08-21 20:33:52 -0700187 common.apr_q6_mvm = apr_register("ADSP", "MVM",
188 qdsp_mvm_callback,
189 0xFFFFFFFF, &common);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700190
Neema Shetty2c07eb52011-08-21 20:33:52 -0700191 if (common.apr_q6_mvm == NULL) {
192 pr_err("%s: Unable to register MVM\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700193 goto err;
194 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700195 }
196
Neema Shetty2c07eb52011-08-21 20:33:52 -0700197 if (common.apr_q6_cvs == NULL) {
198 pr_debug("%s: Start to register CVS callback\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700199
Neema Shetty2c07eb52011-08-21 20:33:52 -0700200 common.apr_q6_cvs = apr_register("ADSP", "CVS",
201 qdsp_cvs_callback,
202 0xFFFFFFFF, &common);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700203
Neema Shetty2c07eb52011-08-21 20:33:52 -0700204 if (common.apr_q6_cvs == NULL) {
205 pr_err("%s: Unable to register CVS\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700206 goto err;
207 }
Ben Romberger13b74ab2011-07-18 17:36:32 -0700208
Neema Shetty2c07eb52011-08-21 20:33:52 -0700209 rtac_set_voice_handle(RTAC_CVS, common.apr_q6_cvs);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700210 }
211
Neema Shetty2c07eb52011-08-21 20:33:52 -0700212 if (common.apr_q6_cvp == NULL) {
213 pr_debug("%s: Start to register CVP callback\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700214
Neema Shetty2c07eb52011-08-21 20:33:52 -0700215 common.apr_q6_cvp = apr_register("ADSP", "CVP",
216 qdsp_cvp_callback,
217 0xFFFFFFFF, &common);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700218
Neema Shetty2c07eb52011-08-21 20:33:52 -0700219 if (common.apr_q6_cvp == NULL) {
220 pr_err("%s: Unable to register CVP\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700221 goto err;
222 }
Ben Romberger13b74ab2011-07-18 17:36:32 -0700223
Neema Shetty2c07eb52011-08-21 20:33:52 -0700224 rtac_set_voice_handle(RTAC_CVP, common.apr_q6_cvp);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700225 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700226
227 mutex_unlock(&common.common_lock);
228
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700229 return 0;
230
231err:
Neema Shetty2c07eb52011-08-21 20:33:52 -0700232 if (common.apr_q6_cvs != NULL) {
233 apr_deregister(common.apr_q6_cvs);
234 common.apr_q6_cvs = NULL;
Ben Romberger13b74ab2011-07-18 17:36:32 -0700235 rtac_set_voice_handle(RTAC_CVS, NULL);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700236 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700237 if (common.apr_q6_mvm != NULL) {
238 apr_deregister(common.apr_q6_mvm);
239 common.apr_q6_mvm = NULL;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700240 }
241
Neema Shetty2c07eb52011-08-21 20:33:52 -0700242 mutex_unlock(&common.common_lock);
243
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700244 return -ENODEV;
245}
246
247static int voice_create_mvm_cvs_session(struct voice_data *v)
248{
249 int ret = 0;
Helen Zeng69b00962011-07-08 11:38:36 -0700250 struct mvm_create_ctl_session_cmd mvm_session_cmd;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700251 struct cvs_create_passive_ctl_session_cmd cvs_session_cmd;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700252 struct cvs_create_full_ctl_session_cmd cvs_full_ctl_cmd;
253 struct mvm_attach_stream_cmd attach_stream_cmd;
254 void *apr_mvm, *apr_cvs, *apr_cvp;
255 u16 mvm_handle, cvs_handle, cvp_handle;
256
257 if (v == NULL) {
258 pr_err("%s: v is NULL\n", __func__);
259 return -EINVAL;
260 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700261 apr_mvm = common.apr_q6_mvm;
262 apr_cvs = common.apr_q6_cvs;
263 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700264
265 if (!apr_mvm || !apr_cvs || !apr_cvp) {
266 pr_err("%s: apr_mvm or apr_cvs or apr_cvp is NULL\n", __func__);
267 return -EINVAL;
268 }
269 mvm_handle = voice_get_mvm_handle(v);
270 cvs_handle = voice_get_cvs_handle(v);
271 cvp_handle = voice_get_cvp_handle(v);
272
273 pr_debug("%s: mvm_hdl=%d, cvs_hdl=%d\n", __func__,
274 mvm_handle, cvs_handle);
275 /* send cmd to create mvm session and wait for response */
276
277 if (!mvm_handle) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700278 if (is_voice_session(v->session_id)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700279 mvm_session_cmd.hdr.hdr_field = APR_HDR_FIELD(
280 APR_MSG_TYPE_SEQ_CMD,
281 APR_HDR_LEN(APR_HDR_SIZE),
282 APR_PKT_VER);
283 mvm_session_cmd.hdr.pkt_size = APR_PKT_SIZE(
284 APR_HDR_SIZE,
285 sizeof(mvm_session_cmd) -
286 APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700287 pr_debug("%s: send mvm create session pkt size = %d\n",
288 __func__, mvm_session_cmd.hdr.pkt_size);
289 mvm_session_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700290 mvm_session_cmd.hdr.dest_port = 0;
291 mvm_session_cmd.hdr.token = 0;
292 mvm_session_cmd.hdr.opcode =
293 VSS_IMVM_CMD_CREATE_PASSIVE_CONTROL_SESSION;
Neema Shetty9ba987d2011-10-25 18:14:50 -0700294 strlcpy(mvm_session_cmd.mvm_session.name,
295 "default modem voice",
296 sizeof(mvm_session_cmd.mvm_session.name));
Helen Zeng69b00962011-07-08 11:38:36 -0700297
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700298 v->mvm_state = CMD_STATUS_FAIL;
299
300 ret = apr_send_pkt(apr_mvm,
301 (uint32_t *) &mvm_session_cmd);
302 if (ret < 0) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700303 pr_err("%s: Error sending MVM_CONTROL_SESSION\n",
304 __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700305 goto fail;
306 }
307 ret = wait_event_timeout(v->mvm_wait,
308 (v->mvm_state == CMD_STATUS_SUCCESS),
309 msecs_to_jiffies(TIMEOUT_MS));
310 if (!ret) {
311 pr_err("%s: wait_event timeout\n", __func__);
312 goto fail;
313 }
314 } else {
315 pr_debug("%s: creating MVM full ctrl\n", __func__);
Helen Zeng69b00962011-07-08 11:38:36 -0700316 mvm_session_cmd.hdr.hdr_field =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700317 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
318 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
Helen Zeng69b00962011-07-08 11:38:36 -0700319 mvm_session_cmd.hdr.pkt_size =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700320 APR_PKT_SIZE(APR_HDR_SIZE,
Helen Zeng69b00962011-07-08 11:38:36 -0700321 sizeof(mvm_session_cmd) -
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700322 APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700323 mvm_session_cmd.hdr.src_port = v->session_id;
Helen Zeng69b00962011-07-08 11:38:36 -0700324 mvm_session_cmd.hdr.dest_port = 0;
325 mvm_session_cmd.hdr.token = 0;
326 mvm_session_cmd.hdr.opcode =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700327 VSS_IMVM_CMD_CREATE_FULL_CONTROL_SESSION;
Neema Shetty9ba987d2011-10-25 18:14:50 -0700328 strlcpy(mvm_session_cmd.mvm_session.name,
329 "default voip",
330 sizeof(mvm_session_cmd.mvm_session.name));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700331
332 v->mvm_state = CMD_STATUS_FAIL;
333
334 ret = apr_send_pkt(apr_mvm,
Helen Zeng69b00962011-07-08 11:38:36 -0700335 (uint32_t *) &mvm_session_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700336 if (ret < 0) {
337 pr_err("Fail in sending MVM_CONTROL_SESSION\n");
338 goto fail;
339 }
340 ret = wait_event_timeout(v->mvm_wait,
341 (v->mvm_state == CMD_STATUS_SUCCESS),
342 msecs_to_jiffies(TIMEOUT_MS));
343 if (!ret) {
344 pr_err("%s: wait_event timeout\n", __func__);
345 goto fail;
346 }
347 }
348 /* Get the created MVM handle. */
349 mvm_handle = voice_get_mvm_handle(v);
350 }
351 /* send cmd to create cvs session */
352 if (!cvs_handle) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700353 if (is_voice_session(v->session_id)) {
354 pr_debug("%s: creating CVS passive session\n",
355 __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700356
357 cvs_session_cmd.hdr.hdr_field = APR_HDR_FIELD(
358 APR_MSG_TYPE_SEQ_CMD,
359 APR_HDR_LEN(APR_HDR_SIZE),
360 APR_PKT_VER);
361 cvs_session_cmd.hdr.pkt_size =
362 APR_PKT_SIZE(APR_HDR_SIZE,
363 sizeof(cvs_session_cmd) -
364 APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700365 cvs_session_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700366 cvs_session_cmd.hdr.dest_port = 0;
367 cvs_session_cmd.hdr.token = 0;
368 cvs_session_cmd.hdr.opcode =
369 VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION;
Neema Shetty9ba987d2011-10-25 18:14:50 -0700370 strlcpy(cvs_session_cmd.cvs_session.name,
371 "default modem voice",
372 sizeof(cvs_session_cmd.cvs_session.name));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700373
374 v->cvs_state = CMD_STATUS_FAIL;
375
376 ret = apr_send_pkt(apr_cvs,
377 (uint32_t *) &cvs_session_cmd);
378 if (ret < 0) {
379 pr_err("Fail in sending STREAM_CONTROL_SESSION\n");
380 goto fail;
381 }
382 ret = wait_event_timeout(v->cvs_wait,
383 (v->cvs_state == CMD_STATUS_SUCCESS),
384 msecs_to_jiffies(TIMEOUT_MS));
385 if (!ret) {
386 pr_err("%s: wait_event timeout\n", __func__);
387 goto fail;
388 }
389 /* Get the created CVS handle. */
390 cvs_handle = voice_get_cvs_handle(v);
391
392 } else {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700393 pr_debug("%s: creating CVS full session\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700394
395 cvs_full_ctl_cmd.hdr.hdr_field =
396 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
397 APR_HDR_LEN(APR_HDR_SIZE),
398 APR_PKT_VER);
399
400 cvs_full_ctl_cmd.hdr.pkt_size =
401 APR_PKT_SIZE(APR_HDR_SIZE,
402 sizeof(cvs_full_ctl_cmd) -
403 APR_HDR_SIZE);
404
Neema Shetty2c07eb52011-08-21 20:33:52 -0700405 cvs_full_ctl_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700406 cvs_full_ctl_cmd.hdr.dest_port = 0;
407 cvs_full_ctl_cmd.hdr.token = 0;
408 cvs_full_ctl_cmd.hdr.opcode =
409 VSS_ISTREAM_CMD_CREATE_FULL_CONTROL_SESSION;
410 cvs_full_ctl_cmd.cvs_session.direction = 2;
411 cvs_full_ctl_cmd.cvs_session.enc_media_type =
Neema Shetty2c07eb52011-08-21 20:33:52 -0700412 common.mvs_info.media_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700413 cvs_full_ctl_cmd.cvs_session.dec_media_type =
Neema Shetty2c07eb52011-08-21 20:33:52 -0700414 common.mvs_info.media_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700415 cvs_full_ctl_cmd.cvs_session.network_id =
Neema Shetty2c07eb52011-08-21 20:33:52 -0700416 common.mvs_info.network_type;
Neema Shetty9ba987d2011-10-25 18:14:50 -0700417 strlcpy(cvs_full_ctl_cmd.cvs_session.name,
418 "default q6 voice",
419 sizeof(cvs_full_ctl_cmd.cvs_session.name));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700420
421 v->cvs_state = CMD_STATUS_FAIL;
422
423 ret = apr_send_pkt(apr_cvs,
424 (uint32_t *) &cvs_full_ctl_cmd);
425
426 if (ret < 0) {
427 pr_err("%s: Err %d sending CREATE_FULL_CTRL\n",
428 __func__, ret);
429 goto fail;
430 }
431 ret = wait_event_timeout(v->cvs_wait,
432 (v->cvs_state == CMD_STATUS_SUCCESS),
433 msecs_to_jiffies(TIMEOUT_MS));
434 if (!ret) {
435 pr_err("%s: wait_event timeout\n", __func__);
436 goto fail;
437 }
438 /* Get the created CVS handle. */
439 cvs_handle = voice_get_cvs_handle(v);
440
441 /* Attach MVM to CVS. */
Neema Shetty2c07eb52011-08-21 20:33:52 -0700442 pr_debug("%s: Attach MVM to stream\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700443
444 attach_stream_cmd.hdr.hdr_field =
445 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
446 APR_HDR_LEN(APR_HDR_SIZE),
447 APR_PKT_VER);
448 attach_stream_cmd.hdr.pkt_size =
449 APR_PKT_SIZE(APR_HDR_SIZE,
450 sizeof(attach_stream_cmd) -
451 APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700452 attach_stream_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700453 attach_stream_cmd.hdr.dest_port = mvm_handle;
454 attach_stream_cmd.hdr.token = 0;
455 attach_stream_cmd.hdr.opcode =
456 VSS_IMVM_CMD_ATTACH_STREAM;
457 attach_stream_cmd.attach_stream.handle = cvs_handle;
458
459 v->mvm_state = CMD_STATUS_FAIL;
460 ret = apr_send_pkt(apr_mvm,
461 (uint32_t *) &attach_stream_cmd);
462 if (ret < 0) {
463 pr_err("%s: Error %d sending ATTACH_STREAM\n",
464 __func__, ret);
465 goto fail;
466 }
467 ret = wait_event_timeout(v->mvm_wait,
468 (v->mvm_state == CMD_STATUS_SUCCESS),
469 msecs_to_jiffies(TIMEOUT_MS));
470 if (!ret) {
471 pr_err("%s: wait_event timeout\n", __func__);
472 goto fail;
473 }
474 }
475 }
476 return 0;
477
478fail:
479 return -EINVAL;
480}
481
482static int voice_destroy_mvm_cvs_session(struct voice_data *v)
483{
484 int ret = 0;
485 struct mvm_detach_stream_cmd detach_stream;
486 struct apr_hdr mvm_destroy;
487 struct apr_hdr cvs_destroy;
488 void *apr_mvm, *apr_cvs;
489 u16 mvm_handle, cvs_handle;
490
491 if (v == NULL) {
492 pr_err("%s: v is NULL\n", __func__);
493 return -EINVAL;
494 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700495 apr_mvm = common.apr_q6_mvm;
496 apr_cvs = common.apr_q6_cvs;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700497
498 if (!apr_mvm || !apr_cvs) {
499 pr_err("%s: apr_mvm or apr_cvs is NULL\n", __func__);
500 return -EINVAL;
501 }
502 mvm_handle = voice_get_mvm_handle(v);
503 cvs_handle = voice_get_cvs_handle(v);
504
505 /* MVM, CVS sessions are destroyed only for Full control sessions. */
Neema Shetty2c07eb52011-08-21 20:33:52 -0700506 if (is_voip_session(v->session_id)) {
507 pr_debug("%s: MVM detach stream\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700508
509 /* Detach voice stream. */
510 detach_stream.hdr.hdr_field =
511 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
512 APR_HDR_LEN(APR_HDR_SIZE),
513 APR_PKT_VER);
514 detach_stream.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
515 sizeof(detach_stream) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700516 detach_stream.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700517 detach_stream.hdr.dest_port = mvm_handle;
518 detach_stream.hdr.token = 0;
519 detach_stream.hdr.opcode = VSS_IMVM_CMD_DETACH_STREAM;
520 detach_stream.detach_stream.handle = cvs_handle;
521
522 v->mvm_state = CMD_STATUS_FAIL;
523
524 ret = apr_send_pkt(apr_mvm, (uint32_t *) &detach_stream);
525 if (ret < 0) {
526 pr_err("%s: Error %d sending DETACH_STREAM\n",
527 __func__, ret);
528 goto fail;
529 }
530 ret = wait_event_timeout(v->mvm_wait,
531 (v->mvm_state == CMD_STATUS_SUCCESS),
532 msecs_to_jiffies(TIMEOUT_MS));
533 if (!ret) {
534 pr_err("%s: wait event timeout\n", __func__);
535 goto fail;
536 }
537 /* Destroy CVS. */
Neema Shetty2c07eb52011-08-21 20:33:52 -0700538 pr_debug("%s: CVS destroy session\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700539
540 cvs_destroy.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
541 APR_HDR_LEN(APR_HDR_SIZE),
542 APR_PKT_VER);
543 cvs_destroy.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
544 sizeof(cvs_destroy) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700545 cvs_destroy.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700546 cvs_destroy.dest_port = cvs_handle;
547 cvs_destroy.token = 0;
548 cvs_destroy.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
549
550 v->cvs_state = CMD_STATUS_FAIL;
551
552 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_destroy);
553 if (ret < 0) {
554 pr_err("%s: Error %d sending CVS DESTROY\n",
555 __func__, ret);
556 goto fail;
557 }
558 ret = wait_event_timeout(v->cvs_wait,
559 (v->cvs_state == CMD_STATUS_SUCCESS),
560 msecs_to_jiffies(TIMEOUT_MS));
561 if (!ret) {
562 pr_err("%s: wait event timeout\n", __func__);
563
564 goto fail;
565 }
566 cvs_handle = 0;
567 voice_set_cvs_handle(v, cvs_handle);
568
569 /* Destroy MVM. */
570 pr_debug("MVM destroy session\n");
571
572 mvm_destroy.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
573 APR_HDR_LEN(APR_HDR_SIZE),
574 APR_PKT_VER);
575 mvm_destroy.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
576 sizeof(mvm_destroy) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700577 mvm_destroy.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700578 mvm_destroy.dest_port = mvm_handle;
579 mvm_destroy.token = 0;
580 mvm_destroy.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
581
582 v->mvm_state = CMD_STATUS_FAIL;
583
584 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_destroy);
585 if (ret < 0) {
586 pr_err("%s: Error %d sending MVM DESTROY\n",
587 __func__, ret);
588
589 goto fail;
590 }
591 ret = wait_event_timeout(v->mvm_wait,
592 (v->mvm_state == CMD_STATUS_SUCCESS),
593 msecs_to_jiffies(TIMEOUT_MS));
594 if (!ret) {
595 pr_err("%s: wait event timeout\n", __func__);
596
597 goto fail;
598 }
599 mvm_handle = 0;
600 voice_set_mvm_handle(v, mvm_handle);
601 }
602 return 0;
603fail:
604 return -EINVAL;
605}
606
607static int voice_send_tty_mode_cmd(struct voice_data *v)
608{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700609 int ret = 0;
610 struct mvm_set_tty_mode_cmd mvm_tty_mode_cmd;
611 void *apr_mvm;
612 u16 mvm_handle;
613
614 if (v == NULL) {
615 pr_err("%s: v is NULL\n", __func__);
616 return -EINVAL;
617 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700618 apr_mvm = common.apr_q6_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700619
620 if (!apr_mvm) {
621 pr_err("%s: apr_mvm is NULL.\n", __func__);
622 return -EINVAL;
623 }
624 mvm_handle = voice_get_mvm_handle(v);
625
Helen Zengcc65b5b2011-07-06 19:14:48 -0700626 if (v->tty_mode) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700627 /* send tty mode cmd to mvm */
628 mvm_tty_mode_cmd.hdr.hdr_field = APR_HDR_FIELD(
629 APR_MSG_TYPE_SEQ_CMD,
630 APR_HDR_LEN(APR_HDR_SIZE),
631 APR_PKT_VER);
632 mvm_tty_mode_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
633 sizeof(mvm_tty_mode_cmd) -
634 APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700635 pr_debug("%s: pkt size = %d\n",
636 __func__, mvm_tty_mode_cmd.hdr.pkt_size);
637 mvm_tty_mode_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700638 mvm_tty_mode_cmd.hdr.dest_port = mvm_handle;
639 mvm_tty_mode_cmd.hdr.token = 0;
640 mvm_tty_mode_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_TTY_MODE;
Helen Zengcc65b5b2011-07-06 19:14:48 -0700641 mvm_tty_mode_cmd.tty_mode.mode = v->tty_mode;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700642 pr_debug("tty mode =%d\n", mvm_tty_mode_cmd.tty_mode.mode);
643
644 v->mvm_state = CMD_STATUS_FAIL;
645 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_tty_mode_cmd);
646 if (ret < 0) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700647 pr_err("%s: Error %d sending SET_TTY_MODE\n",
648 __func__, ret);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700649 goto fail;
650 }
651 ret = wait_event_timeout(v->mvm_wait,
652 (v->mvm_state == CMD_STATUS_SUCCESS),
653 msecs_to_jiffies(TIMEOUT_MS));
654 if (!ret) {
655 pr_err("%s: wait_event timeout\n", __func__);
656 goto fail;
657 }
658 }
659 return 0;
660fail:
661 return -EINVAL;
662}
663
664static int voice_config_cvs_vocoder(struct voice_data *v)
665{
666 int ret = 0;
667 void *apr_cvs;
668 u16 cvs_handle;
669 /* Set media type. */
670 struct cvs_set_media_type_cmd cvs_set_media_cmd;
671
672 if (v == NULL) {
673 pr_err("%s: v is NULL\n", __func__);
674 return -EINVAL;
675 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700676 apr_cvs = common.apr_q6_cvs;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700677
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 cvs_set_media_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
686 APR_HDR_LEN(APR_HDR_SIZE),
687 APR_PKT_VER);
688 cvs_set_media_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
689 sizeof(cvs_set_media_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700690 cvs_set_media_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700691 cvs_set_media_cmd.hdr.dest_port = cvs_handle;
692 cvs_set_media_cmd.hdr.token = 0;
693 cvs_set_media_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_MEDIA_TYPE;
Neema Shetty2c07eb52011-08-21 20:33:52 -0700694 cvs_set_media_cmd.media_type.tx_media_id = common.mvs_info.media_type;
695 cvs_set_media_cmd.media_type.rx_media_id = common.mvs_info.media_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700696
697 v->cvs_state = CMD_STATUS_FAIL;
698
699 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_media_cmd);
700 if (ret < 0) {
701 pr_err("%s: Error %d sending SET_MEDIA_TYPE\n",
702 __func__, ret);
703
704 goto fail;
705 }
706 ret = wait_event_timeout(v->cvs_wait,
707 (v->cvs_state == CMD_STATUS_SUCCESS),
708 msecs_to_jiffies(TIMEOUT_MS));
709 if (!ret) {
710 pr_err("%s: wait_event timeout\n", __func__);
711
712 goto fail;
713 }
714 /* Set encoder properties. */
Neema Shetty2c07eb52011-08-21 20:33:52 -0700715 switch (common.mvs_info.media_type) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700716 case VSS_MEDIA_ID_EVRC_MODEM: {
717 struct cvs_set_cdma_enc_minmax_rate_cmd cvs_set_cdma_rate;
718
719 pr_debug("Setting EVRC min-max rate\n");
720
721 cvs_set_cdma_rate.hdr.hdr_field =
722 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
723 APR_HDR_LEN(APR_HDR_SIZE),
724 APR_PKT_VER);
725 cvs_set_cdma_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
726 sizeof(cvs_set_cdma_rate) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700727 cvs_set_cdma_rate.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700728 cvs_set_cdma_rate.hdr.dest_port = cvs_handle;
729 cvs_set_cdma_rate.hdr.token = 0;
730 cvs_set_cdma_rate.hdr.opcode =
731 VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE;
Neema Shetty2c07eb52011-08-21 20:33:52 -0700732 cvs_set_cdma_rate.cdma_rate.min_rate = common.mvs_info.rate;
733 cvs_set_cdma_rate.cdma_rate.max_rate = common.mvs_info.rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700734
735 v->cvs_state = CMD_STATUS_FAIL;
736
737 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_cdma_rate);
738 if (ret < 0) {
739 pr_err("%s: Error %d sending SET_EVRC_MINMAX_RATE\n",
740 __func__, ret);
741 goto fail;
742 }
743 ret = wait_event_timeout(v->cvs_wait,
744 (v->cvs_state == CMD_STATUS_SUCCESS),
745 msecs_to_jiffies(TIMEOUT_MS));
746 if (!ret) {
747 pr_err("%s: wait_event timeout\n", __func__);
748
749 goto fail;
750 }
751 break;
752 }
753 case VSS_MEDIA_ID_AMR_NB_MODEM: {
754 struct cvs_set_amr_enc_rate_cmd cvs_set_amr_rate;
755 struct cvs_set_enc_dtx_mode_cmd cvs_set_dtx;
756
757 pr_debug("Setting AMR rate\n");
758
759 cvs_set_amr_rate.hdr.hdr_field =
760 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
761 APR_HDR_LEN(APR_HDR_SIZE),
762 APR_PKT_VER);
763 cvs_set_amr_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
764 sizeof(cvs_set_amr_rate) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700765 cvs_set_amr_rate.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700766 cvs_set_amr_rate.hdr.dest_port = cvs_handle;
767 cvs_set_amr_rate.hdr.token = 0;
768 cvs_set_amr_rate.hdr.opcode =
769 VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE;
Neema Shetty2c07eb52011-08-21 20:33:52 -0700770 cvs_set_amr_rate.amr_rate.mode = common.mvs_info.rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700771
772 v->cvs_state = CMD_STATUS_FAIL;
773
774 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_amr_rate);
775 if (ret < 0) {
776 pr_err("%s: Error %d sending SET_AMR_RATE\n",
777 __func__, ret);
778 goto fail;
779 }
780 ret = wait_event_timeout(v->cvs_wait,
781 (v->cvs_state == CMD_STATUS_SUCCESS),
782 msecs_to_jiffies(TIMEOUT_MS));
783 if (!ret) {
784 pr_err("%s: wait_event timeout\n", __func__);
785 goto fail;
786 }
787 /* Disable DTX */
788 pr_debug("Disabling DTX\n");
789
790 cvs_set_dtx.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
791 APR_HDR_LEN(APR_HDR_SIZE),
792 APR_PKT_VER);
793 cvs_set_dtx.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
794 sizeof(cvs_set_dtx) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700795 cvs_set_dtx.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700796 cvs_set_dtx.hdr.dest_port = cvs_handle;
797 cvs_set_dtx.hdr.token = 0;
798 cvs_set_dtx.hdr.opcode = VSS_ISTREAM_CMD_SET_ENC_DTX_MODE;
799 cvs_set_dtx.dtx_mode.enable = 0;
800
801 v->cvs_state = CMD_STATUS_FAIL;
802
803 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_dtx);
804 if (ret < 0) {
805 pr_err("%s: Error %d sending SET_DTX\n",
806 __func__, ret);
807 goto fail;
808 }
809 ret = wait_event_timeout(v->cvs_wait,
810 (v->cvs_state == CMD_STATUS_SUCCESS),
811 msecs_to_jiffies(TIMEOUT_MS));
812 if (!ret) {
813 pr_err("%s: wait_event timeout\n", __func__);
814 goto fail;
815 }
816 break;
817 }
818 case VSS_MEDIA_ID_AMR_WB_MODEM: {
819 struct cvs_set_amrwb_enc_rate_cmd cvs_set_amrwb_rate;
820 struct cvs_set_enc_dtx_mode_cmd cvs_set_dtx;
821
822 pr_debug("Setting AMR WB rate\n");
823
824 cvs_set_amrwb_rate.hdr.hdr_field =
825 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
826 APR_HDR_LEN(APR_HDR_SIZE),
827 APR_PKT_VER);
828 cvs_set_amrwb_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
829 sizeof(cvs_set_amrwb_rate) -
830 APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700831 cvs_set_amrwb_rate.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700832 cvs_set_amrwb_rate.hdr.dest_port = cvs_handle;
833 cvs_set_amrwb_rate.hdr.token = 0;
834 cvs_set_amrwb_rate.hdr.opcode =
835 VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE;
Neema Shetty2c07eb52011-08-21 20:33:52 -0700836 cvs_set_amrwb_rate.amrwb_rate.mode = common.mvs_info.rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700837
838 v->cvs_state = CMD_STATUS_FAIL;
839
840 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_amrwb_rate);
841 if (ret < 0) {
842 pr_err("%s: Error %d sending SET_AMRWB_RATE\n",
843 __func__, ret);
844 goto fail;
845 }
846 ret = wait_event_timeout(v->cvs_wait,
847 (v->cvs_state == CMD_STATUS_SUCCESS),
848 msecs_to_jiffies(TIMEOUT_MS));
849 if (!ret) {
850 pr_err("%s: wait_event timeout\n", __func__);
851 goto fail;
852 }
853 /* Disable DTX */
854 pr_debug("Disabling DTX\n");
855
856 cvs_set_dtx.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
857 APR_HDR_LEN(APR_HDR_SIZE),
858 APR_PKT_VER);
859 cvs_set_dtx.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
860 sizeof(cvs_set_dtx) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700861 cvs_set_dtx.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700862 cvs_set_dtx.hdr.dest_port = cvs_handle;
863 cvs_set_dtx.hdr.token = 0;
864 cvs_set_dtx.hdr.opcode = VSS_ISTREAM_CMD_SET_ENC_DTX_MODE;
865 cvs_set_dtx.dtx_mode.enable = 0;
866
867 v->cvs_state = CMD_STATUS_FAIL;
868
869 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_dtx);
870 if (ret < 0) {
871 pr_err("%s: Error %d sending SET_DTX\n",
872 __func__, ret);
873 goto fail;
874 }
875 ret = wait_event_timeout(v->cvs_wait,
876 (v->cvs_state == CMD_STATUS_SUCCESS),
877 msecs_to_jiffies(TIMEOUT_MS));
878 if (!ret) {
879 pr_err("%s: wait_event timeout\n", __func__);
880 goto fail;
881 }
882 break;
883 }
884 case VSS_MEDIA_ID_G729:
885 case VSS_MEDIA_ID_G711_ALAW:
886 case VSS_MEDIA_ID_G711_MULAW: {
887 struct cvs_set_enc_dtx_mode_cmd cvs_set_dtx;
888 /* Disable DTX */
889 pr_debug("Disabling DTX\n");
890
891 cvs_set_dtx.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
892 APR_HDR_LEN(APR_HDR_SIZE),
893 APR_PKT_VER);
894 cvs_set_dtx.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
895 sizeof(cvs_set_dtx) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700896 cvs_set_dtx.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700897 cvs_set_dtx.hdr.dest_port = cvs_handle;
898 cvs_set_dtx.hdr.token = 0;
899 cvs_set_dtx.hdr.opcode = VSS_ISTREAM_CMD_SET_ENC_DTX_MODE;
900 cvs_set_dtx.dtx_mode.enable = 0;
901
902 v->cvs_state = CMD_STATUS_FAIL;
903
904 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_dtx);
905 if (ret < 0) {
906 pr_err("%s: Error %d sending SET_DTX\n",
907 __func__, ret);
908 goto fail;
909 }
910 ret = wait_event_timeout(v->cvs_wait,
911 (v->cvs_state == CMD_STATUS_SUCCESS),
912 msecs_to_jiffies(TIMEOUT_MS));
913 if (!ret) {
914 pr_err("%s: wait_event timeout\n", __func__);
915 goto fail;
916 }
917 break;
918 }
919 default:
920 /* Do nothing. */
921 break;
922 }
923 return 0;
924
925fail:
926 return -EINVAL;
927}
928
929static int voice_send_start_voice_cmd(struct voice_data *v)
930{
931 struct apr_hdr mvm_start_voice_cmd;
932 int ret = 0;
933 void *apr_mvm;
934 u16 mvm_handle;
935
936 if (v == NULL) {
937 pr_err("%s: v is NULL\n", __func__);
938 return -EINVAL;
939 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700940 apr_mvm = common.apr_q6_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700941
942 if (!apr_mvm) {
943 pr_err("%s: apr_mvm is NULL.\n", __func__);
944 return -EINVAL;
945 }
946 mvm_handle = voice_get_mvm_handle(v);
947
948 mvm_start_voice_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
949 APR_HDR_LEN(APR_HDR_SIZE),
950 APR_PKT_VER);
951 mvm_start_voice_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
952 sizeof(mvm_start_voice_cmd) - APR_HDR_SIZE);
953 pr_debug("send mvm_start_voice_cmd pkt size = %d\n",
954 mvm_start_voice_cmd.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700955 mvm_start_voice_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700956 mvm_start_voice_cmd.dest_port = mvm_handle;
957 mvm_start_voice_cmd.token = 0;
958 mvm_start_voice_cmd.opcode = VSS_IMVM_CMD_START_VOICE;
959
960 v->mvm_state = CMD_STATUS_FAIL;
961 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_start_voice_cmd);
962 if (ret < 0) {
963 pr_err("Fail in sending VSS_IMVM_CMD_START_VOICE\n");
964 goto fail;
965 }
966 ret = wait_event_timeout(v->mvm_wait,
967 (v->mvm_state == CMD_STATUS_SUCCESS),
968 msecs_to_jiffies(TIMEOUT_MS));
969 if (!ret) {
970 pr_err("%s: wait_event timeout\n", __func__);
971 goto fail;
972 }
973 return 0;
974fail:
975 return -EINVAL;
976}
977
978static int voice_send_disable_vocproc_cmd(struct voice_data *v)
979{
980 struct apr_hdr cvp_disable_cmd;
981 int ret = 0;
982 void *apr_cvp;
983 u16 cvp_handle;
984
985 if (v == NULL) {
986 pr_err("%s: v is NULL\n", __func__);
987 return -EINVAL;
988 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700989 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700990
991 if (!apr_cvp) {
992 pr_err("%s: apr regist failed\n", __func__);
993 return -EINVAL;
994 }
995 cvp_handle = voice_get_cvp_handle(v);
996
997 /* disable vocproc and wait for respose */
998 cvp_disable_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
999 APR_HDR_LEN(APR_HDR_SIZE),
1000 APR_PKT_VER);
1001 cvp_disable_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1002 sizeof(cvp_disable_cmd) - APR_HDR_SIZE);
1003 pr_debug("cvp_disable_cmd pkt size = %d, cvp_handle=%d\n",
1004 cvp_disable_cmd.pkt_size, cvp_handle);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001005 cvp_disable_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001006 cvp_disable_cmd.dest_port = cvp_handle;
1007 cvp_disable_cmd.token = 0;
1008 cvp_disable_cmd.opcode = VSS_IVOCPROC_CMD_DISABLE;
1009
1010 v->cvp_state = CMD_STATUS_FAIL;
1011 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_disable_cmd);
1012 if (ret < 0) {
1013 pr_err("Fail in sending VSS_IVOCPROC_CMD_DISABLE\n");
1014 goto fail;
1015 }
1016 ret = wait_event_timeout(v->cvp_wait,
1017 (v->cvp_state == CMD_STATUS_SUCCESS),
1018 msecs_to_jiffies(TIMEOUT_MS));
1019 if (!ret) {
1020 pr_err("%s: wait_event timeout\n", __func__);
1021 goto fail;
1022 }
1023
1024 return 0;
1025fail:
1026 return -EINVAL;
1027}
1028
1029static int voice_send_set_device_cmd(struct voice_data *v)
1030{
1031 struct cvp_set_device_cmd cvp_setdev_cmd;
1032 int ret = 0;
1033 void *apr_cvp;
1034 u16 cvp_handle;
1035
1036 if (v == NULL) {
1037 pr_err("%s: v is NULL\n", __func__);
1038 return -EINVAL;
1039 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001040 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001041
1042 if (!apr_cvp) {
1043 pr_err("%s: apr_cvp is NULL.\n", __func__);
1044 return -EINVAL;
1045 }
1046 cvp_handle = voice_get_cvp_handle(v);
1047
1048 /* set device and wait for response */
1049 cvp_setdev_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1050 APR_HDR_LEN(APR_HDR_SIZE),
1051 APR_PKT_VER);
1052 cvp_setdev_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1053 sizeof(cvp_setdev_cmd) - APR_HDR_SIZE);
1054 pr_debug(" send create cvp setdev, pkt size = %d\n",
1055 cvp_setdev_cmd.hdr.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001056 cvp_setdev_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001057 cvp_setdev_cmd.hdr.dest_port = cvp_handle;
1058 cvp_setdev_cmd.hdr.token = 0;
1059 cvp_setdev_cmd.hdr.opcode = VSS_IVOCPROC_CMD_SET_DEVICE;
1060
1061 /* Use default topology if invalid value in ACDB */
1062 cvp_setdev_cmd.cvp_set_device.tx_topology_id =
1063 get_voice_tx_topology();
1064 if (cvp_setdev_cmd.cvp_set_device.tx_topology_id == 0)
1065 cvp_setdev_cmd.cvp_set_device.tx_topology_id =
1066 VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
1067
1068 cvp_setdev_cmd.cvp_set_device.rx_topology_id =
1069 get_voice_rx_topology();
1070 if (cvp_setdev_cmd.cvp_set_device.rx_topology_id == 0)
1071 cvp_setdev_cmd.cvp_set_device.rx_topology_id =
1072 VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
1073 cvp_setdev_cmd.cvp_set_device.tx_port_id = v->dev_tx.port_id;
1074 cvp_setdev_cmd.cvp_set_device.rx_port_id = v->dev_rx.port_id;
1075 pr_debug("topology=%d , tx_port_id=%d, rx_port_id=%d\n",
1076 cvp_setdev_cmd.cvp_set_device.tx_topology_id,
1077 cvp_setdev_cmd.cvp_set_device.tx_port_id,
1078 cvp_setdev_cmd.cvp_set_device.rx_port_id);
1079
1080 v->cvp_state = CMD_STATUS_FAIL;
1081 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_setdev_cmd);
1082 if (ret < 0) {
1083 pr_err("Fail in sending VOCPROC_FULL_CONTROL_SESSION\n");
1084 goto fail;
1085 }
1086 pr_debug("wait for cvp create session event\n");
1087 ret = wait_event_timeout(v->cvp_wait,
1088 (v->cvp_state == CMD_STATUS_SUCCESS),
1089 msecs_to_jiffies(TIMEOUT_MS));
1090 if (!ret) {
1091 pr_err("%s: wait_event timeout\n", __func__);
1092 goto fail;
1093 }
1094
1095 return 0;
1096fail:
1097 return -EINVAL;
1098}
1099
1100static int voice_send_stop_voice_cmd(struct voice_data *v)
1101{
1102 struct apr_hdr mvm_stop_voice_cmd;
1103 int ret = 0;
1104 void *apr_mvm;
1105 u16 mvm_handle;
1106
1107 if (v == NULL) {
1108 pr_err("%s: v is NULL\n", __func__);
1109 return -EINVAL;
1110 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001111 apr_mvm = common.apr_q6_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001112
1113 if (!apr_mvm) {
1114 pr_err("%s: apr_mvm is NULL.\n", __func__);
1115 return -EINVAL;
1116 }
1117 mvm_handle = voice_get_mvm_handle(v);
1118
1119 mvm_stop_voice_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1120 APR_HDR_LEN(APR_HDR_SIZE),
1121 APR_PKT_VER);
1122 mvm_stop_voice_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1123 sizeof(mvm_stop_voice_cmd) - APR_HDR_SIZE);
1124 pr_debug("send mvm_stop_voice_cmd pkt size = %d\n",
1125 mvm_stop_voice_cmd.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001126 mvm_stop_voice_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001127 mvm_stop_voice_cmd.dest_port = mvm_handle;
1128 mvm_stop_voice_cmd.token = 0;
1129 mvm_stop_voice_cmd.opcode = VSS_IMVM_CMD_STOP_VOICE;
1130
1131 v->mvm_state = CMD_STATUS_FAIL;
1132 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_stop_voice_cmd);
1133 if (ret < 0) {
1134 pr_err("Fail in sending VSS_IMVM_CMD_STOP_VOICE\n");
1135 goto fail;
1136 }
1137 ret = wait_event_timeout(v->mvm_wait,
1138 (v->mvm_state == CMD_STATUS_SUCCESS),
1139 msecs_to_jiffies(TIMEOUT_MS));
1140 if (!ret) {
1141 pr_err("%s: wait_event timeout\n", __func__);
1142 goto fail;
1143 }
1144
1145 return 0;
1146fail:
1147 return -EINVAL;
1148}
1149
Helen Zeng29eb7442011-06-20 11:06:29 -07001150static int voice_send_cvs_register_cal_cmd(struct voice_data *v)
1151{
1152 struct cvs_register_cal_data_cmd cvs_reg_cal_cmd;
1153 struct acdb_cal_block cal_block;
1154 int ret = 0;
1155 void *apr_cvs;
1156 u16 cvs_handle;
1157
1158 /* get the cvs cal data */
1159 get_all_vocstrm_cal(&cal_block);
1160 if (cal_block.cal_size == 0)
1161 goto fail;
1162
1163 if (v == NULL) {
1164 pr_err("%s: v is NULL\n", __func__);
1165 return -EINVAL;
1166 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001167 apr_cvs = common.apr_q6_cvs;
Helen Zeng29eb7442011-06-20 11:06:29 -07001168
1169 if (!apr_cvs) {
1170 pr_err("%s: apr_cvs is NULL.\n", __func__);
1171 return -EINVAL;
1172 }
1173 cvs_handle = voice_get_cvs_handle(v);
1174
1175 /* fill in the header */
1176 cvs_reg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1177 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1178 cvs_reg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1179 sizeof(cvs_reg_cal_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001180 cvs_reg_cal_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001181 cvs_reg_cal_cmd.hdr.dest_port = cvs_handle;
1182 cvs_reg_cal_cmd.hdr.token = 0;
1183 cvs_reg_cal_cmd.hdr.opcode = VSS_ISTREAM_CMD_REGISTER_CALIBRATION_DATA;
1184
1185 cvs_reg_cal_cmd.cvs_cal_data.phys_addr = cal_block.cal_paddr;
1186 cvs_reg_cal_cmd.cvs_cal_data.mem_size = cal_block.cal_size;
1187
1188 v->cvs_state = CMD_STATUS_FAIL;
1189 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_reg_cal_cmd);
1190 if (ret < 0) {
1191 pr_err("Fail: sending cvs cal,\n");
1192 goto fail;
1193 }
1194 ret = wait_event_timeout(v->cvs_wait,
1195 (v->cvs_state == CMD_STATUS_SUCCESS),
1196 msecs_to_jiffies(TIMEOUT_MS));
1197 if (!ret) {
1198 pr_err("%s: wait_event timeout\n", __func__);
1199 goto fail;
1200 }
1201 return 0;
1202fail:
1203 return -EINVAL;
1204
1205}
1206
1207static int voice_send_cvs_deregister_cal_cmd(struct voice_data *v)
1208{
1209 struct cvs_deregister_cal_data_cmd cvs_dereg_cal_cmd;
1210 struct acdb_cal_block cal_block;
1211 int ret = 0;
1212 void *apr_cvs;
1213 u16 cvs_handle;
1214
1215 get_all_vocstrm_cal(&cal_block);
1216 if (cal_block.cal_size == 0)
1217 return 0;
1218
1219 if (v == NULL) {
1220 pr_err("%s: v is NULL\n", __func__);
1221 return -EINVAL;
1222 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001223 apr_cvs = common.apr_q6_cvs;
Helen Zeng29eb7442011-06-20 11:06:29 -07001224
1225 if (!apr_cvs) {
1226 pr_err("%s: apr_cvs is NULL.\n", __func__);
1227 return -EINVAL;
1228 }
1229 cvs_handle = voice_get_cvs_handle(v);
1230
1231 /* fill in the header */
1232 cvs_dereg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1233 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1234 cvs_dereg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1235 sizeof(cvs_dereg_cal_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001236 cvs_dereg_cal_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001237 cvs_dereg_cal_cmd.hdr.dest_port = cvs_handle;
1238 cvs_dereg_cal_cmd.hdr.token = 0;
1239 cvs_dereg_cal_cmd.hdr.opcode =
1240 VSS_ISTREAM_CMD_DEREGISTER_CALIBRATION_DATA;
1241
1242 v->cvs_state = CMD_STATUS_FAIL;
1243 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_dereg_cal_cmd);
1244 if (ret < 0) {
1245 pr_err("Fail: sending cvs cal,\n");
1246 goto fail;
1247 }
1248 ret = wait_event_timeout(v->cvs_wait,
1249 (v->cvs_state == CMD_STATUS_SUCCESS),
1250 msecs_to_jiffies(TIMEOUT_MS));
1251 if (!ret) {
1252 pr_err("%s: wait_event timeout\n", __func__);
1253 goto fail;
1254 }
1255 return 0;
1256fail:
1257 return -EINVAL;
1258
1259}
1260
1261static int voice_send_cvp_map_memory_cmd(struct voice_data *v)
1262{
1263 struct vss_map_memory_cmd cvp_map_mem_cmd;
1264 struct acdb_cal_block cal_block;
1265 int ret = 0;
1266 void *apr_cvp;
1267 u16 cvp_handle;
1268
1269 /* get all cvp cal data */
1270 get_all_cvp_cal(&cal_block);
1271 if (cal_block.cal_size == 0)
1272 goto fail;
1273
1274 if (v == NULL) {
1275 pr_err("%s: v is NULL\n", __func__);
1276 return -EINVAL;
1277 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001278 apr_cvp = common.apr_q6_cvp;
Helen Zeng29eb7442011-06-20 11:06:29 -07001279
1280 if (!apr_cvp) {
1281 pr_err("%s: apr_cvp is NULL.\n", __func__);
1282 return -EINVAL;
1283 }
1284 cvp_handle = voice_get_cvp_handle(v);
1285
1286 /* fill in the header */
1287 cvp_map_mem_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1288 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1289 cvp_map_mem_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1290 sizeof(cvp_map_mem_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001291 cvp_map_mem_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001292 cvp_map_mem_cmd.hdr.dest_port = cvp_handle;
1293 cvp_map_mem_cmd.hdr.token = 0;
1294 cvp_map_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_MAP_MEMORY;
1295
1296 pr_debug("%s, phy_addr:%d, mem_size:%d\n", __func__,
1297 cal_block.cal_paddr, cal_block.cal_size);
1298 cvp_map_mem_cmd.vss_map_mem.phys_addr = cal_block.cal_paddr;
1299 cvp_map_mem_cmd.vss_map_mem.mem_size = cal_block.cal_size;
1300 cvp_map_mem_cmd.vss_map_mem.mem_pool_id =
1301 VSS_ICOMMON_MAP_MEMORY_SHMEM8_4K_POOL;
1302
1303 v->cvp_state = CMD_STATUS_FAIL;
1304 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_map_mem_cmd);
1305 if (ret < 0) {
1306 pr_err("Fail: sending cvp cal,\n");
1307 goto fail;
1308 }
1309 ret = wait_event_timeout(v->cvp_wait,
1310 (v->cvp_state == CMD_STATUS_SUCCESS),
1311 msecs_to_jiffies(TIMEOUT_MS));
1312 if (!ret) {
1313 pr_err("%s: wait_event timeout\n", __func__);
1314 goto fail;
1315 }
1316 return 0;
1317fail:
1318 return -EINVAL;
1319
1320}
1321
1322static int voice_send_cvp_unmap_memory_cmd(struct voice_data *v)
1323{
1324 struct vss_unmap_memory_cmd cvp_unmap_mem_cmd;
1325 struct acdb_cal_block cal_block;
1326 int ret = 0;
1327 void *apr_cvp;
1328 u16 cvp_handle;
1329
1330 get_all_cvp_cal(&cal_block);
1331 if (cal_block.cal_size == 0)
1332 return 0;
1333
1334 if (v == NULL) {
1335 pr_err("%s: v is NULL\n", __func__);
1336 return -EINVAL;
1337 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001338 apr_cvp = common.apr_q6_cvp;
Helen Zeng29eb7442011-06-20 11:06:29 -07001339
1340 if (!apr_cvp) {
1341 pr_err("%s: apr_cvp is NULL.\n", __func__);
1342 return -EINVAL;
1343 }
1344 cvp_handle = voice_get_cvp_handle(v);
1345
1346 /* fill in the header */
1347 cvp_unmap_mem_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1348 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1349 cvp_unmap_mem_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1350 sizeof(cvp_unmap_mem_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001351 cvp_unmap_mem_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001352 cvp_unmap_mem_cmd.hdr.dest_port = cvp_handle;
1353 cvp_unmap_mem_cmd.hdr.token = 0;
1354 cvp_unmap_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_UNMAP_MEMORY;
1355
1356 cvp_unmap_mem_cmd.vss_unmap_mem.phys_addr = cal_block.cal_paddr;
1357
1358 v->cvp_state = CMD_STATUS_FAIL;
1359 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_unmap_mem_cmd);
1360 if (ret < 0) {
1361 pr_err("Fail: sending cvp cal,\n");
1362 goto fail;
1363 }
1364 ret = wait_event_timeout(v->cvp_wait,
1365 (v->cvp_state == CMD_STATUS_SUCCESS),
1366 msecs_to_jiffies(TIMEOUT_MS));
1367 if (!ret) {
1368 pr_err("%s: wait_event timeout\n", __func__);
1369 goto fail;
1370 }
1371 return 0;
1372fail:
1373 return -EINVAL;
1374
1375}
1376
1377static int voice_send_cvs_map_memory_cmd(struct voice_data *v)
1378{
1379 struct vss_map_memory_cmd cvs_map_mem_cmd;
1380 struct acdb_cal_block cal_block;
1381 int ret = 0;
1382 void *apr_cvs;
1383 u16 cvs_handle;
1384
1385 /* get all cvs cal data */
1386 get_all_vocstrm_cal(&cal_block);
1387 if (cal_block.cal_size == 0)
1388 goto fail;
1389
1390 if (v == NULL) {
1391 pr_err("%s: v is NULL\n", __func__);
1392 return -EINVAL;
1393 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001394 apr_cvs = common.apr_q6_cvs;
Helen Zeng29eb7442011-06-20 11:06:29 -07001395
1396 if (!apr_cvs) {
1397 pr_err("%s: apr_cvs is NULL.\n", __func__);
1398 return -EINVAL;
1399 }
1400 cvs_handle = voice_get_cvs_handle(v);
1401
1402 /* fill in the header */
1403 cvs_map_mem_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1404 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1405 cvs_map_mem_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1406 sizeof(cvs_map_mem_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001407 cvs_map_mem_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001408 cvs_map_mem_cmd.hdr.dest_port = cvs_handle;
1409 cvs_map_mem_cmd.hdr.token = 0;
1410 cvs_map_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_MAP_MEMORY;
1411
1412 pr_debug("%s, phys_addr: %d, mem_size: %d\n", __func__,
1413 cal_block.cal_paddr, cal_block.cal_size);
1414 cvs_map_mem_cmd.vss_map_mem.phys_addr = cal_block.cal_paddr;
1415 cvs_map_mem_cmd.vss_map_mem.mem_size = cal_block.cal_size;
1416 cvs_map_mem_cmd.vss_map_mem.mem_pool_id =
1417 VSS_ICOMMON_MAP_MEMORY_SHMEM8_4K_POOL;
1418
1419 v->cvs_state = CMD_STATUS_FAIL;
1420 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_map_mem_cmd);
1421 if (ret < 0) {
1422 pr_err("Fail: sending cvs cal,\n");
1423 goto fail;
1424 }
1425 ret = wait_event_timeout(v->cvs_wait,
1426 (v->cvs_state == CMD_STATUS_SUCCESS),
1427 msecs_to_jiffies(TIMEOUT_MS));
1428 if (!ret) {
1429 pr_err("%s: wait_event timeout\n", __func__);
1430 goto fail;
1431 }
1432 return 0;
1433fail:
1434 return -EINVAL;
1435
1436}
1437
1438static int voice_send_cvs_unmap_memory_cmd(struct voice_data *v)
1439{
1440 struct vss_unmap_memory_cmd cvs_unmap_mem_cmd;
1441 struct acdb_cal_block cal_block;
1442 int ret = 0;
1443 void *apr_cvs;
1444 u16 cvs_handle;
1445
1446 get_all_vocstrm_cal(&cal_block);
1447 if (cal_block.cal_size == 0)
1448 return 0;
1449
1450 if (v == NULL) {
1451 pr_err("%s: v is NULL\n", __func__);
1452 return -EINVAL;
1453 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001454 apr_cvs = common.apr_q6_cvs;
Helen Zeng29eb7442011-06-20 11:06:29 -07001455
1456 if (!apr_cvs) {
1457 pr_err("%s: apr_cvs is NULL.\n", __func__);
1458 return -EINVAL;
1459 }
1460 cvs_handle = voice_get_cvs_handle(v);
1461
1462 /* fill in the header */
1463 cvs_unmap_mem_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1464 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1465 cvs_unmap_mem_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1466 sizeof(cvs_unmap_mem_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001467 cvs_unmap_mem_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001468 cvs_unmap_mem_cmd.hdr.dest_port = cvs_handle;
1469 cvs_unmap_mem_cmd.hdr.token = 0;
1470 cvs_unmap_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_UNMAP_MEMORY;
1471
1472 cvs_unmap_mem_cmd.vss_unmap_mem.phys_addr = cal_block.cal_paddr;
1473
1474 v->cvs_state = CMD_STATUS_FAIL;
1475 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_unmap_mem_cmd);
1476 if (ret < 0) {
1477 pr_err("Fail: sending cvs cal,\n");
1478 goto fail;
1479 }
1480 ret = wait_event_timeout(v->cvs_wait,
1481 (v->cvs_state == CMD_STATUS_SUCCESS),
1482 msecs_to_jiffies(TIMEOUT_MS));
1483 if (!ret) {
1484 pr_err("%s: wait_event timeout\n", __func__);
1485 goto fail;
1486 }
1487 return 0;
1488fail:
1489 return -EINVAL;
1490
1491}
1492
1493static int voice_send_cvp_register_cal_cmd(struct voice_data *v)
1494{
1495 struct cvp_register_cal_data_cmd cvp_reg_cal_cmd;
1496 struct acdb_cal_block cal_block;
1497 int ret = 0;
1498 void *apr_cvp;
1499 u16 cvp_handle;
1500
1501 /* get the cvp cal data */
1502 get_all_vocproc_cal(&cal_block);
1503 if (cal_block.cal_size == 0)
1504 goto fail;
1505
1506 if (v == NULL) {
1507 pr_err("%s: v is NULL\n", __func__);
1508 return -EINVAL;
1509 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001510 apr_cvp = common.apr_q6_cvp;
Helen Zeng29eb7442011-06-20 11:06:29 -07001511
1512 if (!apr_cvp) {
1513 pr_err("%s: apr_cvp is NULL.\n", __func__);
1514 return -EINVAL;
1515 }
1516 cvp_handle = voice_get_cvp_handle(v);
1517
1518 /* fill in the header */
1519 cvp_reg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1520 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1521 cvp_reg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1522 sizeof(cvp_reg_cal_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001523 cvp_reg_cal_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001524 cvp_reg_cal_cmd.hdr.dest_port = cvp_handle;
1525 cvp_reg_cal_cmd.hdr.token = 0;
1526 cvp_reg_cal_cmd.hdr.opcode = VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA;
1527
1528 cvp_reg_cal_cmd.cvp_cal_data.phys_addr = cal_block.cal_paddr;
1529 cvp_reg_cal_cmd.cvp_cal_data.mem_size = cal_block.cal_size;
1530
1531 v->cvp_state = CMD_STATUS_FAIL;
1532 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_reg_cal_cmd);
1533 if (ret < 0) {
1534 pr_err("Fail: sending cvp cal,\n");
1535 goto fail;
1536 }
1537 ret = wait_event_timeout(v->cvp_wait,
1538 (v->cvp_state == CMD_STATUS_SUCCESS),
1539 msecs_to_jiffies(TIMEOUT_MS));
1540 if (!ret) {
1541 pr_err("%s: wait_event timeout\n", __func__);
1542 goto fail;
1543 }
1544 return 0;
1545fail:
1546 return -EINVAL;
1547
1548}
1549
1550static int voice_send_cvp_deregister_cal_cmd(struct voice_data *v)
1551{
1552 struct cvp_deregister_cal_data_cmd cvp_dereg_cal_cmd;
1553 struct acdb_cal_block cal_block;
1554 int ret = 0;
1555 void *apr_cvp;
1556 u16 cvp_handle;
1557
1558 get_all_vocproc_cal(&cal_block);
1559 if (cal_block.cal_size == 0)
1560 return 0;
1561
1562 if (v == NULL) {
1563 pr_err("%s: v is NULL\n", __func__);
1564 return -EINVAL;
1565 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001566 apr_cvp = common.apr_q6_cvp;
Helen Zeng29eb7442011-06-20 11:06:29 -07001567
1568 if (!apr_cvp) {
1569 pr_err("%s: apr_cvp is NULL.\n", __func__);
1570 return -EINVAL;
1571 }
1572 cvp_handle = voice_get_cvp_handle(v);
1573
1574 /* fill in the header */
1575 cvp_dereg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1576 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1577 cvp_dereg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1578 sizeof(cvp_dereg_cal_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001579 cvp_dereg_cal_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001580 cvp_dereg_cal_cmd.hdr.dest_port = cvp_handle;
1581 cvp_dereg_cal_cmd.hdr.token = 0;
1582 cvp_dereg_cal_cmd.hdr.opcode =
1583 VSS_IVOCPROC_CMD_DEREGISTER_CALIBRATION_DATA;
1584
1585 v->cvp_state = CMD_STATUS_FAIL;
1586 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_dereg_cal_cmd);
1587 if (ret < 0) {
1588 pr_err("Fail: sending cvp cal,\n");
1589 goto fail;
1590 }
1591 ret = wait_event_timeout(v->cvp_wait,
1592 (v->cvp_state == CMD_STATUS_SUCCESS),
1593 msecs_to_jiffies(TIMEOUT_MS));
1594 if (!ret) {
1595 pr_err("%s: wait_event timeout\n", __func__);
1596 goto fail;
1597 }
1598 return 0;
1599fail:
1600 return -EINVAL;
1601
1602}
1603
1604static int voice_send_cvp_register_vol_cal_table_cmd(struct voice_data *v)
1605{
1606 struct cvp_register_vol_cal_table_cmd cvp_reg_cal_tbl_cmd;
1607 struct acdb_cal_block cal_block;
1608 int ret = 0;
1609 void *apr_cvp;
1610 u16 cvp_handle;
1611
1612 /* get the cvp vol cal data */
1613 get_all_vocvol_cal(&cal_block);
1614 if (cal_block.cal_size == 0)
1615 goto fail;
1616
1617 if (v == NULL) {
1618 pr_err("%s: v is NULL\n", __func__);
1619 return -EINVAL;
1620 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001621 apr_cvp = common.apr_q6_cvp;
Helen Zeng29eb7442011-06-20 11:06:29 -07001622
1623 if (!apr_cvp) {
1624 pr_err("%s: apr_cvp is NULL.\n", __func__);
1625 return -EINVAL;
1626 }
1627 cvp_handle = voice_get_cvp_handle(v);
1628
1629 /* fill in the header */
1630 cvp_reg_cal_tbl_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1631 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1632 cvp_reg_cal_tbl_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1633 sizeof(cvp_reg_cal_tbl_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001634 cvp_reg_cal_tbl_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001635 cvp_reg_cal_tbl_cmd.hdr.dest_port = cvp_handle;
1636 cvp_reg_cal_tbl_cmd.hdr.token = 0;
1637 cvp_reg_cal_tbl_cmd.hdr.opcode =
1638 VSS_IVOCPROC_CMD_REGISTER_VOLUME_CAL_TABLE;
1639
1640 cvp_reg_cal_tbl_cmd.cvp_vol_cal_tbl.phys_addr = cal_block.cal_paddr;
1641 cvp_reg_cal_tbl_cmd.cvp_vol_cal_tbl.mem_size = cal_block.cal_size;
1642
1643 v->cvp_state = CMD_STATUS_FAIL;
1644 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_reg_cal_tbl_cmd);
1645 if (ret < 0) {
1646 pr_err("Fail: sending cvp cal table,\n");
1647 goto fail;
1648 }
1649 ret = wait_event_timeout(v->cvp_wait,
1650 (v->cvp_state == CMD_STATUS_SUCCESS),
1651 msecs_to_jiffies(TIMEOUT_MS));
1652 if (!ret) {
1653 pr_err("%s: wait_event timeout\n", __func__);
1654 goto fail;
1655 }
1656 return 0;
1657fail:
1658 return -EINVAL;
1659
1660}
1661
1662static int voice_send_cvp_deregister_vol_cal_table_cmd(struct voice_data *v)
1663{
1664 struct cvp_deregister_vol_cal_table_cmd cvp_dereg_cal_tbl_cmd;
1665 struct acdb_cal_block cal_block;
1666 int ret = 0;
1667 void *apr_cvp;
1668 u16 cvp_handle;
1669
1670 get_all_vocvol_cal(&cal_block);
1671 if (cal_block.cal_size == 0)
1672 return 0;
1673
1674 if (v == NULL) {
1675 pr_err("%s: v is NULL\n", __func__);
1676 return -EINVAL;
1677 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001678 apr_cvp = common.apr_q6_cvp;
Helen Zeng29eb7442011-06-20 11:06:29 -07001679
1680 if (!apr_cvp) {
1681 pr_err("%s: apr_cvp is NULL.\n", __func__);
1682 return -EINVAL;
1683 }
1684 cvp_handle = voice_get_cvp_handle(v);
1685
1686 /* fill in the header */
1687 cvp_dereg_cal_tbl_cmd.hdr.hdr_field = APR_HDR_FIELD(
1688 APR_MSG_TYPE_SEQ_CMD,
1689 APR_HDR_LEN(APR_HDR_SIZE),
1690 APR_PKT_VER);
1691 cvp_dereg_cal_tbl_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1692 sizeof(cvp_dereg_cal_tbl_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001693 cvp_dereg_cal_tbl_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001694 cvp_dereg_cal_tbl_cmd.hdr.dest_port = cvp_handle;
1695 cvp_dereg_cal_tbl_cmd.hdr.token = 0;
1696 cvp_dereg_cal_tbl_cmd.hdr.opcode =
1697 VSS_IVOCPROC_CMD_DEREGISTER_VOLUME_CAL_TABLE;
1698
1699 v->cvp_state = CMD_STATUS_FAIL;
1700 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_dereg_cal_tbl_cmd);
1701 if (ret < 0) {
1702 pr_err("Fail: sending cvp cal table,\n");
1703 goto fail;
1704 }
1705 ret = wait_event_timeout(v->cvp_wait,
1706 (v->cvp_state == CMD_STATUS_SUCCESS),
1707 msecs_to_jiffies(TIMEOUT_MS));
1708 if (!ret) {
1709 pr_err("%s: wait_event timeout\n", __func__);
1710 goto fail;
1711 }
1712 return 0;
1713fail:
1714 return -EINVAL;
1715
1716}
Neema Shetty2c07eb52011-08-21 20:33:52 -07001717
Helen Zeng44d4d272011-08-10 14:49:20 -07001718static int voice_send_set_widevoice_enable_cmd(struct voice_data *v)
1719{
1720 struct mvm_set_widevoice_enable_cmd mvm_set_wv_cmd;
1721 int ret = 0;
1722 void *apr_mvm;
1723 u16 mvm_handle;
1724
1725 if (v == NULL) {
1726 pr_err("%s: v is NULL\n", __func__);
1727 return -EINVAL;
1728 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001729 apr_mvm = common.apr_q6_mvm;
Helen Zeng44d4d272011-08-10 14:49:20 -07001730
1731 if (!apr_mvm) {
1732 pr_err("%s: apr_mvm is NULL.\n", __func__);
1733 return -EINVAL;
1734 }
1735 mvm_handle = voice_get_mvm_handle(v);
1736
1737 /* fill in the header */
1738 mvm_set_wv_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1739 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1740 mvm_set_wv_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1741 sizeof(mvm_set_wv_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001742 mvm_set_wv_cmd.hdr.src_port = v->session_id;
Helen Zeng44d4d272011-08-10 14:49:20 -07001743 mvm_set_wv_cmd.hdr.dest_port = mvm_handle;
1744 mvm_set_wv_cmd.hdr.token = 0;
1745 mvm_set_wv_cmd.hdr.opcode = VSS_IWIDEVOICE_CMD_SET_WIDEVOICE;
1746
1747 mvm_set_wv_cmd.vss_set_wv.enable = v->wv_enable;
1748
1749 v->mvm_state = CMD_STATUS_FAIL;
1750 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_wv_cmd);
1751 if (ret < 0) {
1752 pr_err("Fail: sending mvm set widevoice enable,\n");
1753 goto fail;
1754 }
1755 ret = wait_event_timeout(v->mvm_wait,
1756 (v->mvm_state == CMD_STATUS_SUCCESS),
1757 msecs_to_jiffies(TIMEOUT_MS));
1758 if (!ret) {
1759 pr_err("%s: wait_event timeout\n", __func__);
1760 goto fail;
1761 }
1762 return 0;
1763fail:
1764 return -EINVAL;
1765}
1766
Helen Zengbb49c702011-09-06 14:09:13 -07001767static int voice_send_set_slowtalk_enable_cmd(struct voice_data *v)
1768{
1769 struct cvs_set_slowtalk_enable_cmd cvs_set_st_cmd;
1770 int ret = 0;
1771 void *apr_cvs;
1772 u16 cvs_handle;
1773
1774 if (v == NULL) {
1775 pr_err("%s: v is NULL\n", __func__);
1776 return -EINVAL;
1777 }
1778 apr_cvs = common.apr_q6_cvs;
1779
1780 if (!apr_cvs) {
1781 pr_err("%s: apr_cvs is NULL.\n", __func__);
1782 return -EINVAL;
1783 }
1784 cvs_handle = voice_get_cvs_handle(v);
1785
1786 /* fill in the header */
1787 cvs_set_st_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1788 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1789 cvs_set_st_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1790 sizeof(cvs_set_st_cmd) - APR_HDR_SIZE);
1791 cvs_set_st_cmd.hdr.src_port = v->session_id;
1792 cvs_set_st_cmd.hdr.dest_port = cvs_handle;
1793 cvs_set_st_cmd.hdr.token = 0;
1794 cvs_set_st_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_UI_PROPERTY;
1795
1796 cvs_set_st_cmd.vss_set_st.module_id = MODULE_ID_VOICE_MODULE_ST;
1797 cvs_set_st_cmd.vss_set_st.param_id = VOICE_PARAM_MOD_ENABLE;
1798 cvs_set_st_cmd.vss_set_st.param_size = MOD_ENABLE_PARAM_LEN;
1799 cvs_set_st_cmd.vss_set_st.reserved = 0;
1800 cvs_set_st_cmd.vss_set_st.enable = v->st_enable;
1801 cvs_set_st_cmd.vss_set_st.reserved_field = 0;
1802
1803 v->cvs_state = CMD_STATUS_FAIL;
1804 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_st_cmd);
1805 if (ret < 0) {
1806 pr_err("Fail: sending cvs set slowtalk enable,\n");
1807 goto fail;
1808 }
1809 ret = wait_event_timeout(v->cvs_wait,
1810 (v->cvs_state == CMD_STATUS_SUCCESS),
1811 msecs_to_jiffies(TIMEOUT_MS));
1812 if (!ret) {
1813 pr_err("%s: wait_event timeout\n", __func__);
1814 goto fail;
1815 }
1816 return 0;
1817fail:
1818 return -EINVAL;
1819}
1820
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001821static int voice_setup_vocproc(struct voice_data *v)
1822{
1823 struct cvp_create_full_ctl_session_cmd cvp_session_cmd;
1824 int ret = 0;
1825 void *apr_cvp;
1826 if (v == NULL) {
1827 pr_err("%s: v is NULL\n", __func__);
1828 return -EINVAL;
1829 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001830 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001831
1832 if (!apr_cvp) {
1833 pr_err("%s: apr_cvp is NULL.\n", __func__);
1834 return -EINVAL;
1835 }
1836
1837 /* create cvp session and wait for response */
1838 cvp_session_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1839 APR_HDR_LEN(APR_HDR_SIZE),
1840 APR_PKT_VER);
1841 cvp_session_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1842 sizeof(cvp_session_cmd) - APR_HDR_SIZE);
1843 pr_debug(" send create cvp session, pkt size = %d\n",
1844 cvp_session_cmd.hdr.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001845 cvp_session_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001846 cvp_session_cmd.hdr.dest_port = 0;
1847 cvp_session_cmd.hdr.token = 0;
1848 cvp_session_cmd.hdr.opcode =
1849 VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION;
1850
1851 /* Use default topology if invalid value in ACDB */
1852 cvp_session_cmd.cvp_session.tx_topology_id =
1853 get_voice_tx_topology();
1854 if (cvp_session_cmd.cvp_session.tx_topology_id == 0)
1855 cvp_session_cmd.cvp_session.tx_topology_id =
1856 VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
1857
1858 cvp_session_cmd.cvp_session.rx_topology_id =
1859 get_voice_rx_topology();
1860 if (cvp_session_cmd.cvp_session.rx_topology_id == 0)
1861 cvp_session_cmd.cvp_session.rx_topology_id =
1862 VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
1863
1864 cvp_session_cmd.cvp_session.direction = 2; /*tx and rx*/
1865 cvp_session_cmd.cvp_session.network_id = VSS_NETWORK_ID_DEFAULT;
1866 cvp_session_cmd.cvp_session.tx_port_id = v->dev_tx.port_id;
1867 cvp_session_cmd.cvp_session.rx_port_id = v->dev_rx.port_id;
1868
1869 pr_debug("topology=%d net_id=%d, dir=%d tx_port_id=%d, rx_port_id=%d\n",
1870 cvp_session_cmd.cvp_session.tx_topology_id,
1871 cvp_session_cmd.cvp_session.network_id,
1872 cvp_session_cmd.cvp_session.direction,
1873 cvp_session_cmd.cvp_session.tx_port_id,
1874 cvp_session_cmd.cvp_session.rx_port_id);
1875
1876 v->cvp_state = CMD_STATUS_FAIL;
1877 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_session_cmd);
1878 if (ret < 0) {
1879 pr_err("Fail in sending VOCPROC_FULL_CONTROL_SESSION\n");
1880 goto fail;
1881 }
1882 ret = wait_event_timeout(v->cvp_wait,
1883 (v->cvp_state == CMD_STATUS_SUCCESS),
1884 msecs_to_jiffies(TIMEOUT_MS));
1885 if (!ret) {
1886 pr_err("%s: wait_event timeout\n", __func__);
1887 goto fail;
1888 }
1889
Helen Zeng29eb7442011-06-20 11:06:29 -07001890 /* send cvs cal */
1891 ret = voice_send_cvs_map_memory_cmd(v);
1892 if (!ret)
1893 voice_send_cvs_register_cal_cmd(v);
1894
1895 /* send cvp and vol cal */
1896 ret = voice_send_cvp_map_memory_cmd(v);
1897 if (!ret) {
1898 voice_send_cvp_register_cal_cmd(v);
1899 voice_send_cvp_register_vol_cal_table_cmd(v);
1900 }
1901
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001902 /* enable vocproc */
1903 ret = voice_send_enable_vocproc_cmd(v);
1904 if (ret < 0)
1905 goto fail;
1906
1907 /* attach vocproc */
1908 ret = voice_send_attach_vocproc_cmd(v);
1909 if (ret < 0)
1910 goto fail;
1911
1912 /* send tty mode if tty device is used */
1913 voice_send_tty_mode_cmd(v);
1914
Helen Zeng44d4d272011-08-10 14:49:20 -07001915 /* enable widevoice if wv_enable is set */
1916 if (v->wv_enable)
1917 voice_send_set_widevoice_enable_cmd(v);
1918
Helen Zengbb49c702011-09-06 14:09:13 -07001919 /* enable slowtalk if st_enable is set */
1920 if (v->st_enable)
1921 voice_send_set_slowtalk_enable_cmd(v);
1922
Neema Shetty2c07eb52011-08-21 20:33:52 -07001923 if (is_voip_session(v->session_id))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001924 voice_send_netid_timing_cmd(v);
1925
Helen Zenge3d716a2011-10-14 16:32:16 -07001926 /* Start in-call music delivery if this feature is enabled */
Helen Zeng0705a5f2011-10-14 15:29:52 -07001927 if (v->music_info.play_enable)
1928 voice_cvs_start_playback(v);
1929
Helen Zenge3d716a2011-10-14 16:32:16 -07001930 /* Start in-call recording if this feature is enabled */
1931 if (v->rec_info.rec_enable)
1932 voice_cvs_start_record(v, v->rec_info.rec_mode);
1933
Ben Romberger13b74ab2011-07-18 17:36:32 -07001934 rtac_add_voice(voice_get_cvs_handle(v),
1935 voice_get_cvp_handle(v),
Ben Rombergerc5d6a372011-09-22 18:01:49 -07001936 v->dev_rx.port_id, v->dev_tx.port_id,
1937 v->session_id);
Ben Romberger13b74ab2011-07-18 17:36:32 -07001938
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001939 return 0;
1940
1941fail:
1942 return -EINVAL;
1943}
1944
1945static int voice_send_enable_vocproc_cmd(struct voice_data *v)
1946{
1947 int ret = 0;
1948 struct apr_hdr cvp_enable_cmd;
1949 void *apr_cvp;
1950 u16 cvp_handle;
1951
1952 if (v == NULL) {
1953 pr_err("%s: v is NULL\n", __func__);
1954 return -EINVAL;
1955 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001956 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001957
1958 if (!apr_cvp) {
1959 pr_err("%s: apr_cvp is NULL.\n", __func__);
1960 return -EINVAL;
1961 }
1962 cvp_handle = voice_get_cvp_handle(v);
1963
1964 /* enable vocproc and wait for respose */
1965 cvp_enable_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1966 APR_HDR_LEN(APR_HDR_SIZE),
1967 APR_PKT_VER);
1968 cvp_enable_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1969 sizeof(cvp_enable_cmd) - APR_HDR_SIZE);
1970 pr_debug("cvp_enable_cmd pkt size = %d, cvp_handle=%d\n",
1971 cvp_enable_cmd.pkt_size, cvp_handle);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001972 cvp_enable_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001973 cvp_enable_cmd.dest_port = cvp_handle;
1974 cvp_enable_cmd.token = 0;
1975 cvp_enable_cmd.opcode = VSS_IVOCPROC_CMD_ENABLE;
1976
1977 v->cvp_state = CMD_STATUS_FAIL;
1978 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_enable_cmd);
1979 if (ret < 0) {
1980 pr_err("Fail in sending VSS_IVOCPROC_CMD_ENABLE\n");
1981 goto fail;
1982 }
1983 ret = wait_event_timeout(v->cvp_wait,
1984 (v->cvp_state == CMD_STATUS_SUCCESS),
1985 msecs_to_jiffies(TIMEOUT_MS));
1986 if (!ret) {
1987 pr_err("%s: wait_event timeout\n", __func__);
1988 goto fail;
1989 }
1990
1991 return 0;
1992fail:
1993 return -EINVAL;
1994}
1995
1996static int voice_send_netid_timing_cmd(struct voice_data *v)
1997{
1998 int ret = 0;
1999 void *apr_mvm;
2000 u16 mvm_handle;
2001 struct mvm_set_network_cmd mvm_set_network;
2002 struct mvm_set_voice_timing_cmd mvm_set_voice_timing;
2003
2004 if (v == NULL) {
2005 pr_err("%s: v is NULL\n", __func__);
2006 return -EINVAL;
2007 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07002008 apr_mvm = common.apr_q6_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002009
2010 if (!apr_mvm) {
2011 pr_err("%s: apr_mvm is NULL.\n", __func__);
2012 return -EINVAL;
2013 }
2014 mvm_handle = voice_get_mvm_handle(v);
2015
2016 ret = voice_config_cvs_vocoder(v);
2017 if (ret < 0) {
2018 pr_err("%s: Error %d configuring CVS voc",
2019 __func__, ret);
2020 goto fail;
2021 }
2022 /* Set network ID. */
2023 pr_debug("Setting network ID\n");
2024
2025 mvm_set_network.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2026 APR_HDR_LEN(APR_HDR_SIZE),
2027 APR_PKT_VER);
2028 mvm_set_network.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2029 sizeof(mvm_set_network) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002030 mvm_set_network.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002031 mvm_set_network.hdr.dest_port = mvm_handle;
2032 mvm_set_network.hdr.token = 0;
2033 mvm_set_network.hdr.opcode = VSS_ICOMMON_CMD_SET_NETWORK;
Neema Shetty2c07eb52011-08-21 20:33:52 -07002034 mvm_set_network.network.network_id = common.mvs_info.network_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002035
2036 v->mvm_state = CMD_STATUS_FAIL;
2037 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_network);
2038 if (ret < 0) {
2039 pr_err("%s: Error %d sending SET_NETWORK\n", __func__, ret);
2040 goto fail;
2041 }
2042
2043 ret = wait_event_timeout(v->mvm_wait,
2044 (v->mvm_state == CMD_STATUS_SUCCESS),
2045 msecs_to_jiffies(TIMEOUT_MS));
2046 if (!ret) {
2047 pr_err("%s: wait_event timeout\n", __func__);
2048 goto fail;
2049 }
2050
2051 /* Set voice timing. */
2052 pr_debug("Setting voice timing\n");
2053
2054 mvm_set_voice_timing.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2055 APR_HDR_LEN(APR_HDR_SIZE),
2056 APR_PKT_VER);
2057 mvm_set_voice_timing.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2058 sizeof(mvm_set_voice_timing) -
2059 APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002060 mvm_set_voice_timing.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002061 mvm_set_voice_timing.hdr.dest_port = mvm_handle;
2062 mvm_set_voice_timing.hdr.token = 0;
2063 mvm_set_voice_timing.hdr.opcode = VSS_ICOMMON_CMD_SET_VOICE_TIMING;
2064 mvm_set_voice_timing.timing.mode = 0;
2065 mvm_set_voice_timing.timing.enc_offset = 8000;
2066 mvm_set_voice_timing.timing.dec_req_offset = 3300;
2067 mvm_set_voice_timing.timing.dec_offset = 8300;
2068
2069 v->mvm_state = CMD_STATUS_FAIL;
2070
2071 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_voice_timing);
2072 if (ret < 0) {
2073 pr_err("%s: Error %d sending SET_TIMING\n", __func__, ret);
2074 goto fail;
2075 }
2076
2077 ret = wait_event_timeout(v->mvm_wait,
2078 (v->mvm_state == CMD_STATUS_SUCCESS),
2079 msecs_to_jiffies(TIMEOUT_MS));
2080 if (!ret) {
2081 pr_err("%s: wait_event timeout\n", __func__);
2082 goto fail;
2083 }
2084
2085 return 0;
2086fail:
2087 return -EINVAL;
2088}
2089
2090static int voice_send_attach_vocproc_cmd(struct voice_data *v)
2091{
2092 int ret = 0;
2093 struct mvm_attach_vocproc_cmd mvm_a_vocproc_cmd;
2094 void *apr_mvm;
2095 u16 mvm_handle, cvp_handle;
2096
2097 if (v == NULL) {
2098 pr_err("%s: v is NULL\n", __func__);
2099 return -EINVAL;
2100 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07002101 apr_mvm = common.apr_q6_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002102
2103 if (!apr_mvm) {
2104 pr_err("%s: apr_mvm is NULL.\n", __func__);
2105 return -EINVAL;
2106 }
2107 mvm_handle = voice_get_mvm_handle(v);
2108 cvp_handle = voice_get_cvp_handle(v);
2109
2110 /* attach vocproc and wait for response */
2111 mvm_a_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2112 APR_HDR_LEN(APR_HDR_SIZE),
2113 APR_PKT_VER);
2114 mvm_a_vocproc_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2115 sizeof(mvm_a_vocproc_cmd) - APR_HDR_SIZE);
2116 pr_debug("send mvm_a_vocproc_cmd pkt size = %d\n",
2117 mvm_a_vocproc_cmd.hdr.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002118 mvm_a_vocproc_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002119 mvm_a_vocproc_cmd.hdr.dest_port = mvm_handle;
2120 mvm_a_vocproc_cmd.hdr.token = 0;
Helen Zeng69b00962011-07-08 11:38:36 -07002121 mvm_a_vocproc_cmd.hdr.opcode = VSS_IMVM_CMD_ATTACH_VOCPROC;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002122 mvm_a_vocproc_cmd.mvm_attach_cvp_handle.handle = cvp_handle;
2123
2124 v->mvm_state = CMD_STATUS_FAIL;
2125 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_a_vocproc_cmd);
2126 if (ret < 0) {
Helen Zeng69b00962011-07-08 11:38:36 -07002127 pr_err("Fail in sending VSS_IMVM_CMD_ATTACH_VOCPROC\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002128 goto fail;
2129 }
2130 ret = wait_event_timeout(v->mvm_wait,
2131 (v->mvm_state == CMD_STATUS_SUCCESS),
2132 msecs_to_jiffies(TIMEOUT_MS));
2133 if (!ret) {
2134 pr_err("%s: wait_event timeout\n", __func__);
2135 goto fail;
2136 }
2137
2138 return 0;
2139fail:
2140 return -EINVAL;
2141}
2142
2143static int voice_destroy_vocproc(struct voice_data *v)
2144{
2145 struct mvm_detach_vocproc_cmd mvm_d_vocproc_cmd;
2146 struct apr_hdr cvp_destroy_session_cmd;
2147 int ret = 0;
2148 void *apr_mvm, *apr_cvp;
2149 u16 mvm_handle, cvp_handle;
2150
2151 if (v == NULL) {
2152 pr_err("%s: v is NULL\n", __func__);
2153 return -EINVAL;
2154 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07002155 apr_mvm = common.apr_q6_mvm;
2156 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002157
2158 if (!apr_mvm || !apr_cvp) {
2159 pr_err("%s: apr_mvm or apr_cvp is NULL.\n", __func__);
2160 return -EINVAL;
2161 }
2162 mvm_handle = voice_get_mvm_handle(v);
2163 cvp_handle = voice_get_cvp_handle(v);
2164
Helen Zenge3d716a2011-10-14 16:32:16 -07002165 /* stop playback or recording */
Helen Zeng0705a5f2011-10-14 15:29:52 -07002166 v->music_info.force = 1;
2167 voice_cvs_stop_playback(v);
Helen Zenge3d716a2011-10-14 16:32:16 -07002168 voice_cvs_stop_record(v);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002169 /* send stop voice cmd */
2170 voice_send_stop_voice_cmd(v);
2171
2172 /* detach VOCPROC and wait for response from mvm */
2173 mvm_d_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2174 APR_HDR_LEN(APR_HDR_SIZE),
2175 APR_PKT_VER);
2176 mvm_d_vocproc_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2177 sizeof(mvm_d_vocproc_cmd) - APR_HDR_SIZE);
2178 pr_debug("mvm_d_vocproc_cmd pkt size = %d\n",
2179 mvm_d_vocproc_cmd.hdr.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002180 mvm_d_vocproc_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002181 mvm_d_vocproc_cmd.hdr.dest_port = mvm_handle;
2182 mvm_d_vocproc_cmd.hdr.token = 0;
Helen Zeng69b00962011-07-08 11:38:36 -07002183 mvm_d_vocproc_cmd.hdr.opcode = VSS_IMVM_CMD_DETACH_VOCPROC;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002184 mvm_d_vocproc_cmd.mvm_detach_cvp_handle.handle = cvp_handle;
2185
2186 v->mvm_state = CMD_STATUS_FAIL;
2187 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_d_vocproc_cmd);
2188 if (ret < 0) {
Helen Zeng69b00962011-07-08 11:38:36 -07002189 pr_err("Fail in sending VSS_IMVM_CMD_DETACH_VOCPROC\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002190 goto fail;
2191 }
2192 ret = wait_event_timeout(v->mvm_wait,
2193 (v->mvm_state == CMD_STATUS_SUCCESS),
2194 msecs_to_jiffies(TIMEOUT_MS));
2195 if (!ret) {
2196 pr_err("%s: wait_event timeout\n", __func__);
2197 goto fail;
2198 }
2199
Helen Zeng29eb7442011-06-20 11:06:29 -07002200 /* deregister cvp and vol cal */
2201 voice_send_cvp_deregister_vol_cal_table_cmd(v);
2202 voice_send_cvp_deregister_cal_cmd(v);
2203 voice_send_cvp_unmap_memory_cmd(v);
2204
2205 /* deregister cvs cal */
2206 voice_send_cvs_deregister_cal_cmd(v);
2207 voice_send_cvs_unmap_memory_cmd(v);
2208
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002209 /* destrop cvp session */
2210 cvp_destroy_session_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2211 APR_HDR_LEN(APR_HDR_SIZE),
2212 APR_PKT_VER);
2213 cvp_destroy_session_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2214 sizeof(cvp_destroy_session_cmd) - APR_HDR_SIZE);
2215 pr_debug("cvp_destroy_session_cmd pkt size = %d\n",
2216 cvp_destroy_session_cmd.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002217 cvp_destroy_session_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002218 cvp_destroy_session_cmd.dest_port = cvp_handle;
2219 cvp_destroy_session_cmd.token = 0;
2220 cvp_destroy_session_cmd.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
2221
2222 v->cvp_state = CMD_STATUS_FAIL;
2223 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_destroy_session_cmd);
2224 if (ret < 0) {
2225 pr_err("Fail in sending APRV2_IBASIC_CMD_DESTROY_SESSION\n");
2226 goto fail;
2227 }
2228 ret = wait_event_timeout(v->cvp_wait,
2229 (v->cvp_state == CMD_STATUS_SUCCESS),
2230 msecs_to_jiffies(TIMEOUT_MS));
2231 if (!ret) {
2232 pr_err("%s: wait_event timeout\n", __func__);
2233 goto fail;
2234 }
2235
Ben Romberger13b74ab2011-07-18 17:36:32 -07002236 rtac_remove_voice(voice_get_cvs_handle(v));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002237 cvp_handle = 0;
2238 voice_set_cvp_handle(v, cvp_handle);
2239
2240 return 0;
2241
2242fail:
2243 return -EINVAL;
2244}
2245
2246static int voice_send_mute_cmd(struct voice_data *v)
2247{
2248 struct cvs_set_mute_cmd cvs_mute_cmd;
2249 int ret = 0;
2250 void *apr_cvs;
2251 u16 cvs_handle;
2252
2253 if (v == NULL) {
2254 pr_err("%s: v is NULL\n", __func__);
2255 return -EINVAL;
2256 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07002257 apr_cvs = common.apr_q6_cvs;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002258
2259 if (!apr_cvs) {
2260 pr_err("%s: apr_cvs is NULL.\n", __func__);
2261 return -EINVAL;
2262 }
2263 cvs_handle = voice_get_cvs_handle(v);
2264
2265 /* send mute/unmute to cvs */
2266 cvs_mute_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2267 APR_HDR_LEN(APR_HDR_SIZE),
2268 APR_PKT_VER);
2269 cvs_mute_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2270 sizeof(cvs_mute_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002271 cvs_mute_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002272 cvs_mute_cmd.hdr.dest_port = cvs_handle;
2273 cvs_mute_cmd.hdr.token = 0;
2274 cvs_mute_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_MUTE;
2275 cvs_mute_cmd.cvs_set_mute.direction = 0; /*tx*/
2276 cvs_mute_cmd.cvs_set_mute.mute_flag = v->dev_tx.mute;
2277
2278 pr_info(" mute value =%d\n", cvs_mute_cmd.cvs_set_mute.mute_flag);
2279 v->cvs_state = CMD_STATUS_FAIL;
2280 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_mute_cmd);
2281 if (ret < 0) {
2282 pr_err("Fail: send STREAM SET MUTE\n");
2283 goto fail;
2284 }
2285 ret = wait_event_timeout(v->cvs_wait,
2286 (v->cvs_state == CMD_STATUS_SUCCESS),
2287 msecs_to_jiffies(TIMEOUT_MS));
2288 if (!ret)
2289 pr_err("%s: wait_event timeout\n", __func__);
2290
2291 return 0;
2292fail:
2293 return -EINVAL;
2294}
2295
2296static int voice_send_vol_index_cmd(struct voice_data *v)
2297{
2298 struct cvp_set_rx_volume_index_cmd cvp_vol_cmd;
2299 int ret = 0;
2300 void *apr_cvp;
2301 u16 cvp_handle;
2302 if (v == NULL) {
2303 pr_err("%s: v is NULL\n", __func__);
2304 return -EINVAL;
2305 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07002306 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002307
2308 if (!apr_cvp) {
2309 pr_err("%s: apr_cvp is NULL.\n", __func__);
2310 return -EINVAL;
2311 }
2312 cvp_handle = voice_get_cvp_handle(v);
2313
2314 /* send volume index to cvp */
2315 cvp_vol_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2316 APR_HDR_LEN(APR_HDR_SIZE),
2317 APR_PKT_VER);
2318 cvp_vol_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2319 sizeof(cvp_vol_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002320 cvp_vol_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002321 cvp_vol_cmd.hdr.dest_port = cvp_handle;
2322 cvp_vol_cmd.hdr.token = 0;
2323 cvp_vol_cmd.hdr.opcode = VSS_IVOCPROC_CMD_SET_RX_VOLUME_INDEX;
2324 cvp_vol_cmd.cvp_set_vol_idx.vol_index = v->dev_rx.volume;
2325 v->cvp_state = CMD_STATUS_FAIL;
2326 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_vol_cmd);
2327 if (ret < 0) {
2328 pr_err("Fail in sending RX VOL INDEX\n");
2329 return -EINVAL;
2330 }
2331 ret = wait_event_timeout(v->cvp_wait,
2332 (v->cvp_state == CMD_STATUS_SUCCESS),
2333 msecs_to_jiffies(TIMEOUT_MS));
2334 if (!ret) {
2335 pr_err("%s: wait_event timeout\n", __func__);
2336 return -EINVAL;
2337 }
2338 return 0;
2339}
2340
Helen Zenge3d716a2011-10-14 16:32:16 -07002341static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode)
2342{
2343 int ret = 0;
2344 void *apr_cvs;
2345 u16 cvs_handle;
2346
2347 struct cvs_start_record_cmd cvs_start_record;
2348
2349 if (v == NULL) {
2350 pr_err("%s: v is NULL\n", __func__);
2351 return -EINVAL;
2352 }
2353 apr_cvs = common.apr_q6_cvs;
2354
2355 if (!apr_cvs) {
2356 pr_err("%s: apr_cvs is NULL.\n", __func__);
2357 return -EINVAL;
2358 }
2359
2360 cvs_handle = voice_get_cvs_handle(v);
2361
2362 if (!v->rec_info.recording) {
2363 cvs_start_record.hdr.hdr_field = APR_HDR_FIELD(
2364 APR_MSG_TYPE_SEQ_CMD,
2365 APR_HDR_LEN(APR_HDR_SIZE),
2366 APR_PKT_VER);
2367 cvs_start_record.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2368 sizeof(cvs_start_record) - APR_HDR_SIZE);
2369 cvs_start_record.hdr.src_port = v->session_id;
2370 cvs_start_record.hdr.dest_port = cvs_handle;
2371 cvs_start_record.hdr.token = 0;
2372 cvs_start_record.hdr.opcode = VSS_ISTREAM_CMD_START_RECORD;
2373
2374 if (rec_mode == VOC_REC_UPLINK) {
2375 cvs_start_record.rec_mode.rx_tap_point =
2376 VSS_TAP_POINT_NONE;
2377 cvs_start_record.rec_mode.tx_tap_point =
2378 VSS_TAP_POINT_STREAM_END;
2379 } else if (rec_mode == VOC_REC_DOWNLINK) {
2380 cvs_start_record.rec_mode.rx_tap_point =
2381 VSS_TAP_POINT_STREAM_END;
2382 cvs_start_record.rec_mode.tx_tap_point =
2383 VSS_TAP_POINT_NONE;
2384 } else if (rec_mode == VOC_REC_BOTH) {
2385 cvs_start_record.rec_mode.rx_tap_point =
2386 VSS_TAP_POINT_STREAM_END;
2387 cvs_start_record.rec_mode.tx_tap_point =
2388 VSS_TAP_POINT_STREAM_END;
2389 } else {
2390 pr_err("%s: Invalid in-call rec_mode %d\n", __func__,
2391 rec_mode);
2392
2393 ret = -EINVAL;
2394 goto fail;
2395 }
2396
2397 v->cvs_state = CMD_STATUS_FAIL;
2398
2399 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_start_record);
2400 if (ret < 0) {
2401 pr_err("%s: Error %d sending START_RECORD\n", __func__,
2402 ret);
2403
2404 goto fail;
2405 }
2406
2407 ret = wait_event_timeout(v->cvs_wait,
2408 (v->cvs_state == CMD_STATUS_SUCCESS),
2409 msecs_to_jiffies(TIMEOUT_MS));
2410
2411 if (!ret) {
2412 pr_err("%s: wait_event timeout\n", __func__);
2413
2414 goto fail;
2415 }
2416 v->rec_info.recording = 1;
2417 } else {
2418 pr_debug("%s: Start record already sent\n", __func__);
2419 }
2420
2421 return 0;
2422
2423fail:
2424 return ret;
2425}
2426
2427static int voice_cvs_stop_record(struct voice_data *v)
2428{
2429 int ret = 0;
2430 void *apr_cvs;
2431 u16 cvs_handle;
2432 struct apr_hdr cvs_stop_record;
2433
2434 if (v == NULL) {
2435 pr_err("%s: v is NULL\n", __func__);
2436 return -EINVAL;
2437 }
2438 apr_cvs = common.apr_q6_cvs;
2439
2440 if (!apr_cvs) {
2441 pr_err("%s: apr_cvs is NULL.\n", __func__);
2442 return -EINVAL;
2443 }
2444
2445 cvs_handle = voice_get_cvs_handle(v);
2446
2447 if (v->rec_info.recording) {
2448 cvs_stop_record.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2449 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2450 cvs_stop_record.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2451 sizeof(cvs_stop_record) - APR_HDR_SIZE);
2452 cvs_stop_record.src_port = v->session_id;
2453 cvs_stop_record.dest_port = cvs_handle;
2454 cvs_stop_record.token = 0;
2455 cvs_stop_record.opcode = VSS_ISTREAM_CMD_STOP_RECORD;
2456
2457 v->cvs_state = CMD_STATUS_FAIL;
2458
2459 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_stop_record);
2460 if (ret < 0) {
2461 pr_err("%s: Error %d sending STOP_RECORD\n",
2462 __func__, ret);
2463
2464 goto fail;
2465 }
2466
2467 ret = wait_event_timeout(v->cvs_wait,
2468 (v->cvs_state == CMD_STATUS_SUCCESS),
2469 msecs_to_jiffies(TIMEOUT_MS));
2470 if (!ret) {
2471 pr_err("%s: wait_event timeout\n", __func__);
2472
2473 goto fail;
2474 }
2475 v->rec_info.recording = 0;
2476 } else {
2477 pr_debug("%s: Stop record already sent\n", __func__);
2478 }
2479
2480 return 0;
2481
2482fail:
2483
2484 return ret;
2485}
2486
2487int voc_start_record(uint32_t port_id, uint32_t set)
2488{
2489 int ret = 0;
2490 int rec_mode = 0;
2491 u16 cvs_handle;
2492 int i, rec_set = 0;
2493
2494 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
2495 struct voice_data *v = &common.voice[i];
2496 pr_debug("%s: i:%d port_id: %d, set: %d\n",
2497 __func__, i, port_id, set);
2498
2499 mutex_lock(&v->lock);
2500 rec_mode = v->rec_info.rec_mode;
2501 rec_set = set;
2502 if (set) {
2503 if ((v->rec_route_state.ul_flag != 0) &&
2504 (v->rec_route_state.dl_flag != 0)) {
2505 pr_debug("%s: i=%d, rec mode already set.\n",
2506 __func__, i);
2507 mutex_unlock(&v->lock);
2508 if (i < MAX_VOC_SESSIONS)
2509 continue;
2510 else
2511 return 0;
2512 }
2513
2514 if (port_id == VOICE_RECORD_TX) {
2515 if ((v->rec_route_state.ul_flag == 0)
2516 && (v->rec_route_state.dl_flag == 0)) {
2517 rec_mode = VOC_REC_UPLINK;
2518 v->rec_route_state.ul_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.ul_flag = 1;
2524 }
2525 } else if (port_id == VOICE_RECORD_RX) {
2526 if ((v->rec_route_state.ul_flag == 0)
2527 && (v->rec_route_state.dl_flag == 0)) {
2528 rec_mode = VOC_REC_DOWNLINK;
2529 v->rec_route_state.dl_flag = 1;
2530 } else if ((v->rec_route_state.ul_flag != 0)
2531 && (v->rec_route_state.dl_flag == 0)) {
2532 voice_cvs_stop_record(v);
2533 rec_mode = VOC_REC_BOTH;
2534 v->rec_route_state.dl_flag = 1;
2535 }
2536 }
2537 rec_set = 1;
2538 } else {
2539 if ((v->rec_route_state.ul_flag == 0) &&
2540 (v->rec_route_state.dl_flag == 0)) {
2541 pr_debug("%s: i=%d, rec already stops.\n",
2542 __func__, i);
2543 mutex_unlock(&v->lock);
2544 if (i < MAX_VOC_SESSIONS)
2545 continue;
2546 else
2547 return 0;
2548 }
2549
2550 if (port_id == VOICE_RECORD_TX) {
2551 if ((v->rec_route_state.ul_flag != 0)
2552 && (v->rec_route_state.dl_flag == 0)) {
2553 v->rec_route_state.ul_flag = 0;
2554 rec_set = 0;
2555 } else if ((v->rec_route_state.ul_flag != 0)
2556 && (v->rec_route_state.dl_flag != 0)) {
2557 voice_cvs_stop_record(v);
2558 v->rec_route_state.ul_flag = 0;
2559 rec_mode = VOC_REC_DOWNLINK;
2560 rec_set = 1;
2561 }
2562 } else if (port_id == VOICE_RECORD_RX) {
2563 if ((v->rec_route_state.ul_flag == 0)
2564 && (v->rec_route_state.dl_flag != 0)) {
2565 v->rec_route_state.dl_flag = 0;
2566 rec_set = 0;
2567 } else if ((v->rec_route_state.ul_flag != 0)
2568 && (v->rec_route_state.dl_flag != 0)) {
2569 voice_cvs_stop_record(v);
2570 v->rec_route_state.dl_flag = 0;
2571 rec_mode = VOC_REC_UPLINK;
2572 rec_set = 1;
2573 }
2574 }
2575 }
2576 pr_debug("%s: i=%d, mode =%d, set =%d\n", __func__,
2577 i, rec_mode, rec_set);
2578 cvs_handle = voice_get_cvs_handle(v);
2579
2580 if (cvs_handle != 0) {
2581 if (rec_set)
2582 ret = voice_cvs_start_record(v, rec_mode);
2583 else
2584 ret = voice_cvs_stop_record(v);
2585 }
2586
2587 /* Cache the value */
2588 v->rec_info.rec_enable = rec_set;
2589 v->rec_info.rec_mode = rec_mode;
2590
2591 mutex_unlock(&v->lock);
2592 }
2593
2594 return ret;
2595}
2596
Helen Zeng0705a5f2011-10-14 15:29:52 -07002597static int voice_cvs_start_playback(struct voice_data *v)
2598{
2599 int ret = 0;
2600 struct apr_hdr cvs_start_playback;
2601 void *apr_cvs;
2602 u16 cvs_handle;
2603
2604 if (v == NULL) {
2605 pr_err("%s: v is NULL\n", __func__);
2606 return -EINVAL;
2607 }
2608 apr_cvs = common.apr_q6_cvs;
2609
2610 if (!apr_cvs) {
2611 pr_err("%s: apr_cvs is NULL.\n", __func__);
2612 return -EINVAL;
2613 }
2614
2615 cvs_handle = voice_get_cvs_handle(v);
2616
2617 if (!v->music_info.playing && v->music_info.count) {
2618 cvs_start_playback.hdr_field = APR_HDR_FIELD(
2619 APR_MSG_TYPE_SEQ_CMD,
2620 APR_HDR_LEN(APR_HDR_SIZE),
2621 APR_PKT_VER);
2622 cvs_start_playback.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2623 sizeof(cvs_start_playback) - APR_HDR_SIZE);
2624 cvs_start_playback.src_port = v->session_id;
2625 cvs_start_playback.dest_port = cvs_handle;
2626 cvs_start_playback.token = 0;
2627 cvs_start_playback.opcode = VSS_ISTREAM_CMD_START_PLAYBACK;
2628
2629 v->cvs_state = CMD_STATUS_FAIL;
2630
2631 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_start_playback);
2632
2633 if (ret < 0) {
2634 pr_err("%s: Error %d sending START_PLAYBACK\n",
2635 __func__, ret);
2636
2637 goto fail;
2638 }
2639
2640 ret = wait_event_timeout(v->cvs_wait,
2641 (v->cvs_state == CMD_STATUS_SUCCESS),
2642 msecs_to_jiffies(TIMEOUT_MS));
2643 if (!ret) {
2644 pr_err("%s: wait_event timeout\n", __func__);
2645
2646 goto fail;
2647 }
2648
2649 v->music_info.playing = 1;
2650 } else {
2651 pr_debug("%s: Start playback already sent\n", __func__);
2652 }
2653
2654 return 0;
2655
2656fail:
2657 return ret;
2658}
2659
2660static int voice_cvs_stop_playback(struct voice_data *v)
2661{
2662 int ret = 0;
2663 struct apr_hdr cvs_stop_playback;
2664 void *apr_cvs;
2665 u16 cvs_handle;
2666
2667 if (v == NULL) {
2668 pr_err("%s: v is NULL\n", __func__);
2669 return -EINVAL;
2670 }
2671 apr_cvs = common.apr_q6_cvs;
2672
2673 if (!apr_cvs) {
2674 pr_err("%s: apr_cvs is NULL.\n", __func__);
2675 return -EINVAL;
2676 }
2677
2678 cvs_handle = voice_get_cvs_handle(v);
2679
2680 if (v->music_info.playing && ((!v->music_info.count) ||
2681 (v->music_info.force))) {
2682 cvs_stop_playback.hdr_field =
2683 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2684 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2685 cvs_stop_playback.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2686 sizeof(cvs_stop_playback) - APR_HDR_SIZE);
2687 cvs_stop_playback.src_port = v->session_id;
2688 cvs_stop_playback.dest_port = cvs_handle;
2689 cvs_stop_playback.token = 0;
2690
2691 cvs_stop_playback.opcode = VSS_ISTREAM_CMD_STOP_PLAYBACK;
2692
2693 v->cvs_state = CMD_STATUS_FAIL;
2694
2695 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_stop_playback);
2696 if (ret < 0) {
2697 pr_err("%s: Error %d sending STOP_PLAYBACK\n",
2698 __func__, ret);
2699
2700
2701 goto fail;
2702 }
2703
2704 ret = wait_event_timeout(v->cvs_wait,
2705 (v->cvs_state == CMD_STATUS_SUCCESS),
2706 msecs_to_jiffies(TIMEOUT_MS));
2707 if (!ret) {
2708 pr_err("%s: wait_event timeout\n", __func__);
2709
2710 goto fail;
2711 }
2712
2713 v->music_info.playing = 0;
2714 v->music_info.force = 0;
2715 } else {
2716 pr_debug("%s: Stop playback already sent\n", __func__);
2717 }
2718
2719 return 0;
2720
2721fail:
2722 return ret;
2723}
2724
2725int voc_start_playback(uint32_t set)
2726{
2727 int ret = 0;
2728 u16 cvs_handle;
2729 int i;
2730
2731
2732 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
2733 struct voice_data *v = &common.voice[i];
2734
2735 mutex_lock(&v->lock);
2736 v->music_info.play_enable = set;
2737 if (set)
2738 v->music_info.count++;
2739 else
2740 v->music_info.count--;
2741 pr_debug("%s: music_info count =%d\n", __func__,
2742 v->music_info.count);
2743
2744 cvs_handle = voice_get_cvs_handle(v);
2745 if (cvs_handle != 0) {
2746 if (set)
2747 ret = voice_cvs_start_playback(v);
2748 else
2749 ret = voice_cvs_stop_playback(v);
2750 }
2751
2752 mutex_unlock(&v->lock);
2753 }
2754
2755 return ret;
2756}
2757
Neema Shetty2c07eb52011-08-21 20:33:52 -07002758int voc_disable_cvp(uint16_t session_id)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002759{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002760 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002761 int ret = 0;
2762
Neema Shetty2c07eb52011-08-21 20:33:52 -07002763 if (v == NULL) {
2764 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2765
2766 return -EINVAL;
2767 }
2768
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002769 mutex_lock(&v->lock);
2770
2771 if (v->voc_state == VOC_RUN) {
Laxminath Kasam5b9cf0f2011-12-09 15:24:20 +05302772 if (v->dev_tx.port_id != RT_PROXY_PORT_001_TX &&
2773 v->dev_rx.port_id != RT_PROXY_PORT_001_RX)
2774 afe_sidetone(v->dev_tx.port_id, v->dev_rx.port_id,
2775 0, 0);
Ben Romberger13b74ab2011-07-18 17:36:32 -07002776
2777 rtac_remove_voice(voice_get_cvs_handle(v));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002778 /* send cmd to dsp to disable vocproc */
2779 ret = voice_send_disable_vocproc_cmd(v);
2780 if (ret < 0) {
2781 pr_err("%s: disable vocproc failed\n", __func__);
2782 goto fail;
2783 }
Helen Zeng29eb7442011-06-20 11:06:29 -07002784
2785 /* deregister cvp and vol cal */
2786 voice_send_cvp_deregister_vol_cal_table_cmd(v);
2787 voice_send_cvp_deregister_cal_cmd(v);
2788 voice_send_cvp_unmap_memory_cmd(v);
2789
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002790 v->voc_state = VOC_CHANGE;
2791 }
2792
2793fail: mutex_unlock(&v->lock);
2794
2795 return ret;
2796}
2797
Neema Shetty2c07eb52011-08-21 20:33:52 -07002798int voc_enable_cvp(uint16_t session_id)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002799{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002800 struct voice_data *v = voice_get_session(session_id);
Helen Zengbd58e2c2011-07-01 16:24:31 -07002801 struct sidetone_cal sidetone_cal_data;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002802 int ret = 0;
2803
Neema Shetty2c07eb52011-08-21 20:33:52 -07002804 if (v == NULL) {
2805 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2806
2807 return -EINVAL;
2808 }
2809
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002810 mutex_lock(&v->lock);
2811
2812 if (v->voc_state == VOC_CHANGE) {
2813 ret = voice_send_set_device_cmd(v);
2814 if (ret < 0) {
2815 pr_err("%s: set device failed\n", __func__);
2816 goto fail;
2817 }
Helen Zeng29eb7442011-06-20 11:06:29 -07002818 /* send cvp and vol cal */
2819 ret = voice_send_cvp_map_memory_cmd(v);
2820 if (!ret) {
2821 voice_send_cvp_register_cal_cmd(v);
2822 voice_send_cvp_register_vol_cal_table_cmd(v);
2823 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002824 ret = voice_send_enable_vocproc_cmd(v);
2825 if (ret < 0) {
Neema Shetty2c07eb52011-08-21 20:33:52 -07002826 pr_err("%s: enable vocproc failed\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002827 goto fail;
Helen Zengcc65b5b2011-07-06 19:14:48 -07002828
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002829 }
Helen Zengcc65b5b2011-07-06 19:14:48 -07002830 /* send tty mode if tty device is used */
2831 voice_send_tty_mode_cmd(v);
2832
Helen Zeng44d4d272011-08-10 14:49:20 -07002833 /* enable widevoice if wv_enable is set */
2834 if (v->wv_enable)
2835 voice_send_set_widevoice_enable_cmd(v);
2836
Helen Zengbb49c702011-09-06 14:09:13 -07002837 /* enable slowtalk */
2838 if (v->st_enable)
2839 voice_send_set_slowtalk_enable_cmd(v);
2840
Helen Zengbd58e2c2011-07-01 16:24:31 -07002841 get_sidetone_cal(&sidetone_cal_data);
Laxminath Kasam5b9cf0f2011-12-09 15:24:20 +05302842 if (v->dev_tx.port_id != RT_PROXY_PORT_001_TX &&
2843 v->dev_rx.port_id != RT_PROXY_PORT_001_RX) {
2844 ret = afe_sidetone(v->dev_tx.port_id,
2845 v->dev_rx.port_id,
2846 sidetone_cal_data.enable,
2847 sidetone_cal_data.gain);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002848
Laxminath Kasam5b9cf0f2011-12-09 15:24:20 +05302849 if (ret < 0)
2850 pr_err("%s: AFE command sidetone failed\n",
2851 __func__);
2852 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002853
Ben Romberger13b74ab2011-07-18 17:36:32 -07002854 rtac_add_voice(voice_get_cvs_handle(v),
2855 voice_get_cvp_handle(v),
Ben Rombergerc5d6a372011-09-22 18:01:49 -07002856 v->dev_rx.port_id, v->dev_tx.port_id,
2857 v->session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002858 v->voc_state = VOC_RUN;
2859 }
2860
2861fail:
2862 mutex_unlock(&v->lock);
2863
2864 return ret;
2865}
2866
Neema Shetty2c07eb52011-08-21 20:33:52 -07002867int voc_set_tx_mute(uint16_t session_id, uint32_t dir, uint32_t mute)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002868{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002869 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002870 int ret = 0;
2871
Neema Shetty2c07eb52011-08-21 20:33:52 -07002872 if (v == NULL) {
2873 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2874
2875 return -EINVAL;
2876 }
2877
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002878 mutex_lock(&v->lock);
2879
2880 v->dev_tx.mute = mute;
2881
2882 if (v->voc_state == VOC_RUN)
2883 ret = voice_send_mute_cmd(v);
2884
2885 mutex_unlock(&v->lock);
2886
2887 return ret;
2888}
2889
Neema Shetty2c07eb52011-08-21 20:33:52 -07002890int voc_set_tty_mode(uint16_t session_id, uint8_t tty_mode)
Helen Zengcc65b5b2011-07-06 19:14:48 -07002891{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002892 struct voice_data *v = voice_get_session(session_id);
Helen Zengcc65b5b2011-07-06 19:14:48 -07002893 int ret = 0;
2894
Neema Shetty2c07eb52011-08-21 20:33:52 -07002895 if (v == NULL) {
2896 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2897
2898 return -EINVAL;
2899 }
2900
Helen Zengcc65b5b2011-07-06 19:14:48 -07002901 mutex_lock(&v->lock);
2902
2903 v->tty_mode = tty_mode;
2904
2905 mutex_unlock(&v->lock);
2906
2907 return ret;
2908}
2909
Neema Shetty2c07eb52011-08-21 20:33:52 -07002910uint8_t voc_get_tty_mode(uint16_t session_id)
Helen Zengcc65b5b2011-07-06 19:14:48 -07002911{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002912 struct voice_data *v = voice_get_session(session_id);
Helen Zengcc65b5b2011-07-06 19:14:48 -07002913 int ret = 0;
2914
Neema Shetty2c07eb52011-08-21 20:33:52 -07002915 if (v == NULL) {
2916 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2917
2918 return -EINVAL;
2919 }
2920
Helen Zengcc65b5b2011-07-06 19:14:48 -07002921 mutex_lock(&v->lock);
2922
2923 ret = v->tty_mode;
2924
2925 mutex_unlock(&v->lock);
2926
2927 return ret;
2928}
2929
Neema Shetty2c07eb52011-08-21 20:33:52 -07002930int voc_set_widevoice_enable(uint16_t session_id, uint32_t wv_enable)
Helen Zeng44d4d272011-08-10 14:49:20 -07002931{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002932 struct voice_data *v = voice_get_session(session_id);
Helen Zengb73acce2011-09-15 18:23:01 -07002933 u16 mvm_handle;
Helen Zeng44d4d272011-08-10 14:49:20 -07002934 int ret = 0;
2935
Neema Shetty2c07eb52011-08-21 20:33:52 -07002936 if (v == NULL) {
2937 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2938
2939 return -EINVAL;
2940 }
2941
Helen Zeng44d4d272011-08-10 14:49:20 -07002942 mutex_lock(&v->lock);
2943
2944 v->wv_enable = wv_enable;
2945
Helen Zengb73acce2011-09-15 18:23:01 -07002946 mvm_handle = voice_get_mvm_handle(v);
2947
2948 if (mvm_handle != 0)
2949 voice_send_set_widevoice_enable_cmd(v);
2950
Helen Zeng44d4d272011-08-10 14:49:20 -07002951 mutex_unlock(&v->lock);
2952
2953 return ret;
2954}
2955
Neema Shetty2c07eb52011-08-21 20:33:52 -07002956uint32_t voc_get_widevoice_enable(uint16_t session_id)
Helen Zeng44d4d272011-08-10 14:49:20 -07002957{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002958 struct voice_data *v = voice_get_session(session_id);
Helen Zeng44d4d272011-08-10 14:49:20 -07002959 int ret = 0;
2960
Neema Shetty2c07eb52011-08-21 20:33:52 -07002961 if (v == NULL) {
2962 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2963
2964 return -EINVAL;
2965 }
2966
Helen Zeng44d4d272011-08-10 14:49:20 -07002967 mutex_lock(&v->lock);
2968
2969 ret = v->wv_enable;
2970
2971 mutex_unlock(&v->lock);
2972
2973 return ret;
2974}
2975
Helen Zengbb49c702011-09-06 14:09:13 -07002976int voc_set_slowtalk_enable(uint16_t session_id, uint32_t st_enable)
2977{
2978 struct voice_data *v = voice_get_session(session_id);
2979 int ret = 0;
2980
2981 if (v == NULL) {
2982 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2983
2984 return -EINVAL;
2985 }
2986
2987 mutex_lock(&v->lock);
2988
2989 v->st_enable = st_enable;
2990
2991 if (v->voc_state == VOC_RUN)
2992 ret = voice_send_set_slowtalk_enable_cmd(v);
2993
2994 mutex_unlock(&v->lock);
2995
2996 return ret;
2997}
2998
2999uint32_t voc_get_slowtalk_enable(uint16_t session_id)
3000{
3001 struct voice_data *v = voice_get_session(session_id);
3002 int ret = 0;
3003
3004 if (v == NULL) {
3005 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3006
3007 return -EINVAL;
3008 }
3009
3010 mutex_lock(&v->lock);
3011
3012 ret = v->st_enable;
3013
3014 mutex_unlock(&v->lock);
3015
3016 return ret;
3017}
3018
Neema Shetty2c07eb52011-08-21 20:33:52 -07003019int voc_set_rx_vol_index(uint16_t session_id, uint32_t dir, uint32_t vol_idx)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003020{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003021 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003022 int ret = 0;
3023
Neema Shetty2c07eb52011-08-21 20:33:52 -07003024 if (v == NULL) {
3025 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3026
3027 return -EINVAL;
3028 }
3029
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003030 mutex_lock(&v->lock);
3031
3032 v->dev_rx.volume = vol_idx;
3033
3034 if (v->voc_state == VOC_RUN)
3035 ret = voice_send_vol_index_cmd(v);
3036
3037 mutex_unlock(&v->lock);
3038
3039 return ret;
3040}
3041
Neema Shetty2c07eb52011-08-21 20:33:52 -07003042int voc_set_rxtx_port(uint16_t session_id, uint32_t port_id, uint32_t dev_type)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003043{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003044 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003045
Neema Shetty2c07eb52011-08-21 20:33:52 -07003046 if (v == NULL) {
3047 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3048
3049 return -EINVAL;
3050 }
3051
3052 pr_debug("%s: port_id=%d, type=%d\n", __func__, port_id, dev_type);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003053
3054 mutex_lock(&v->lock);
3055
3056 if (dev_type == DEV_RX)
3057 v->dev_rx.port_id = port_id;
3058 else
3059 v->dev_tx.port_id = port_id;
3060
3061 mutex_unlock(&v->lock);
3062
Neema Shetty2c07eb52011-08-21 20:33:52 -07003063 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003064}
3065
Neema Shetty2c07eb52011-08-21 20:33:52 -07003066int voc_set_route_flag(uint16_t session_id, uint8_t path_dir, uint8_t set)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003067{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003068 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003069
Neema Shetty2c07eb52011-08-21 20:33:52 -07003070 if (v == NULL) {
3071 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3072
3073 return -EINVAL;
3074 }
3075
3076 pr_debug("%s: path_dir=%d, set=%d\n", __func__, path_dir, set);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003077
3078 mutex_lock(&v->lock);
3079
3080 if (path_dir == RX_PATH)
3081 v->voc_route_state.rx_route_flag = set;
3082 else
3083 v->voc_route_state.tx_route_flag = set;
3084
3085 mutex_unlock(&v->lock);
3086
Neema Shetty2c07eb52011-08-21 20:33:52 -07003087 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003088}
3089
Neema Shetty2c07eb52011-08-21 20:33:52 -07003090uint8_t voc_get_route_flag(uint16_t session_id, uint8_t path_dir)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003091{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003092 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003093 int ret = 0;
3094
Neema Shetty2c07eb52011-08-21 20:33:52 -07003095 if (v == NULL) {
3096 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3097
3098 return 0;
3099 }
3100
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003101 mutex_lock(&v->lock);
3102
3103 if (path_dir == RX_PATH)
3104 ret = v->voc_route_state.rx_route_flag;
3105 else
3106 ret = v->voc_route_state.tx_route_flag;
3107
3108 mutex_unlock(&v->lock);
3109
3110 return ret;
3111}
3112
Neema Shetty2c07eb52011-08-21 20:33:52 -07003113int voc_end_voice_call(uint16_t session_id)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003114{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003115 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003116 int ret = 0;
3117
Neema Shetty2c07eb52011-08-21 20:33:52 -07003118 if (v == NULL) {
3119 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3120
3121 return -EINVAL;
3122 }
3123
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003124 mutex_lock(&v->lock);
3125
3126 if (v->voc_state == VOC_RUN) {
Laxminath Kasam5b9cf0f2011-12-09 15:24:20 +05303127 if (v->dev_tx.port_id != RT_PROXY_PORT_001_TX &&
3128 v->dev_rx.port_id != RT_PROXY_PORT_001_RX)
3129 afe_sidetone(v->dev_tx.port_id, v->dev_rx.port_id,
3130 0, 0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003131 ret = voice_destroy_vocproc(v);
3132 if (ret < 0)
3133 pr_err("%s: destroy voice failed\n", __func__);
3134 voice_destroy_mvm_cvs_session(v);
3135
3136 v->voc_state = VOC_RELEASE;
3137 }
3138 mutex_unlock(&v->lock);
3139 return ret;
3140}
3141
Neema Shetty2c07eb52011-08-21 20:33:52 -07003142int voc_start_voice_call(uint16_t session_id)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003143{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003144 struct voice_data *v = voice_get_session(session_id);
Helen Zengbd58e2c2011-07-01 16:24:31 -07003145 struct sidetone_cal sidetone_cal_data;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003146 int ret = 0;
3147
Neema Shetty2c07eb52011-08-21 20:33:52 -07003148 if (v == NULL) {
3149 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3150
3151 return -EINVAL;
3152 }
3153
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003154 mutex_lock(&v->lock);
3155
3156 if ((v->voc_state == VOC_INIT) ||
3157 (v->voc_state == VOC_RELEASE)) {
Neema Shetty2c07eb52011-08-21 20:33:52 -07003158 ret = voice_apr_register();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003159 if (ret < 0) {
3160 pr_err("%s: apr register failed\n", __func__);
3161 goto fail;
3162 }
3163 ret = voice_create_mvm_cvs_session(v);
3164 if (ret < 0) {
3165 pr_err("create mvm and cvs failed\n");
3166 goto fail;
3167 }
3168 ret = voice_setup_vocproc(v);
3169 if (ret < 0) {
3170 pr_err("setup voice failed\n");
3171 goto fail;
3172 }
3173 ret = voice_send_start_voice_cmd(v);
3174 if (ret < 0) {
3175 pr_err("start voice failed\n");
3176 goto fail;
3177 }
Helen Zengbd58e2c2011-07-01 16:24:31 -07003178 get_sidetone_cal(&sidetone_cal_data);
Laxminath Kasam5b9cf0f2011-12-09 15:24:20 +05303179 if (v->dev_tx.port_id != RT_PROXY_PORT_001_TX &&
3180 v->dev_rx.port_id != RT_PROXY_PORT_001_RX) {
3181 ret = afe_sidetone(v->dev_tx.port_id,
Helen Zengbd58e2c2011-07-01 16:24:31 -07003182 v->dev_rx.port_id,
3183 sidetone_cal_data.enable,
3184 sidetone_cal_data.gain);
Laxminath Kasam5b9cf0f2011-12-09 15:24:20 +05303185 if (ret < 0)
3186 pr_err("AFE command sidetone failed\n");
3187 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003188
3189 v->voc_state = VOC_RUN;
3190 }
3191
3192fail: mutex_unlock(&v->lock);
3193 return ret;
3194}
3195
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003196void voc_register_mvs_cb(ul_cb_fn ul_cb,
3197 dl_cb_fn dl_cb,
3198 void *private_data)
3199{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003200 common.mvs_info.ul_cb = ul_cb;
3201 common.mvs_info.dl_cb = dl_cb;
3202 common.mvs_info.private_data = private_data;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003203}
3204
3205void voc_config_vocoder(uint32_t media_type,
3206 uint32_t rate,
3207 uint32_t network_type)
3208{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003209 common.mvs_info.media_type = media_type;
3210 common.mvs_info.rate = rate;
3211 common.mvs_info.network_type = network_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003212}
3213
3214static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv)
3215{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003216 uint32_t *ptr = NULL;
3217 struct common_data *c = NULL;
3218 struct voice_data *v = NULL;
Neema Shetty07477582011-09-02 17:35:44 -07003219 int i = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003220
3221 if ((data == NULL) || (priv == NULL)) {
3222 pr_err("%s: data or priv is NULL\n", __func__);
3223 return -EINVAL;
3224 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07003225
3226 c = priv;
3227
3228 pr_debug("%s: session_id 0x%x\n", __func__, data->dest_port);
3229
3230 v = voice_get_session(data->dest_port);
3231 if (v == NULL) {
3232 pr_err("%s: v is NULL\n", __func__);
3233
3234 return -EINVAL;
3235 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003236
3237 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
3238 data->payload_size, data->opcode);
3239
Neema Shetty07477582011-09-02 17:35:44 -07003240 if (data->opcode == RESET_EVENTS) {
3241 pr_debug("%s: Reset event received in Voice service\n",
3242 __func__);
3243
3244 apr_reset(c->apr_q6_mvm);
3245 c->apr_q6_mvm = NULL;
3246
3247 /* Sub-system restart is applicable to all sessions. */
3248 for (i = 0; i < MAX_VOC_SESSIONS; i++)
3249 c->voice[i].mvm_handle = 0;
3250
3251 return 0;
3252 }
3253
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003254 if (data->opcode == APR_BASIC_RSP_RESULT) {
3255 if (data->payload_size) {
3256 ptr = data->payload;
3257
3258 pr_info("%x %x\n", ptr[0], ptr[1]);
3259 /* ping mvm service ACK */
3260 switch (ptr[0]) {
3261 case VSS_IMVM_CMD_CREATE_PASSIVE_CONTROL_SESSION:
3262 case VSS_IMVM_CMD_CREATE_FULL_CONTROL_SESSION:
3263 /* Passive session is used for CS call
3264 * Full session is used for VoIP call. */
3265 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
3266 if (!ptr[1]) {
3267 pr_debug("%s: MVM handle is %d\n",
3268 __func__, data->src_port);
3269 voice_set_mvm_handle(v, data->src_port);
3270 } else
3271 pr_err("got NACK for sending \
3272 MVM create session \n");
3273 v->mvm_state = CMD_STATUS_SUCCESS;
3274 wake_up(&v->mvm_wait);
3275 break;
3276 case VSS_IMVM_CMD_START_VOICE:
Helen Zeng69b00962011-07-08 11:38:36 -07003277 case VSS_IMVM_CMD_ATTACH_VOCPROC:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003278 case VSS_IMVM_CMD_STOP_VOICE:
Helen Zeng69b00962011-07-08 11:38:36 -07003279 case VSS_IMVM_CMD_DETACH_VOCPROC:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003280 case VSS_ISTREAM_CMD_SET_TTY_MODE:
3281 case APRV2_IBASIC_CMD_DESTROY_SESSION:
3282 case VSS_IMVM_CMD_ATTACH_STREAM:
3283 case VSS_IMVM_CMD_DETACH_STREAM:
3284 case VSS_ICOMMON_CMD_SET_NETWORK:
3285 case VSS_ICOMMON_CMD_SET_VOICE_TIMING:
Helen Zeng44d4d272011-08-10 14:49:20 -07003286 case VSS_IWIDEVOICE_CMD_SET_WIDEVOICE:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003287 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
3288 v->mvm_state = CMD_STATUS_SUCCESS;
3289 wake_up(&v->mvm_wait);
3290 break;
3291 default:
3292 pr_debug("%s: not match cmd = 0x%x\n",
3293 __func__, ptr[0]);
3294 break;
3295 }
3296 }
3297 }
3298
3299 return 0;
3300}
3301
3302static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv)
3303{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003304 uint32_t *ptr = NULL;
3305 struct common_data *c = NULL;
3306 struct voice_data *v = NULL;
Neema Shetty07477582011-09-02 17:35:44 -07003307 int i = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003308
3309 if ((data == NULL) || (priv == NULL)) {
3310 pr_err("%s: data or priv is NULL\n", __func__);
3311 return -EINVAL;
3312 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07003313
3314 c = priv;
3315
3316 pr_debug("%s: session_id 0x%x\n", __func__, data->dest_port);
3317
3318 v = voice_get_session(data->dest_port);
3319 if (v == NULL) {
3320 pr_err("%s: v is NULL\n", __func__);
3321
3322 return -EINVAL;
3323 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003324
3325 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
3326 data->payload_size, data->opcode);
3327
Neema Shetty07477582011-09-02 17:35:44 -07003328 if (data->opcode == RESET_EVENTS) {
3329 pr_debug("%s: Reset event received in Voice service\n",
3330 __func__);
3331
3332 apr_reset(c->apr_q6_cvs);
3333 c->apr_q6_cvs = NULL;
3334
3335 /* Sub-system restart is applicable to all sessions. */
3336 for (i = 0; i < MAX_VOC_SESSIONS; i++)
3337 c->voice[i].cvs_handle = 0;
3338
3339 return 0;
3340 }
3341
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003342 if (data->opcode == APR_BASIC_RSP_RESULT) {
3343 if (data->payload_size) {
3344 ptr = data->payload;
3345
3346 pr_info("%x %x\n", ptr[0], ptr[1]);
3347 /*response from CVS */
3348 switch (ptr[0]) {
3349 case VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION:
3350 case VSS_ISTREAM_CMD_CREATE_FULL_CONTROL_SESSION:
3351 if (!ptr[1]) {
3352 pr_debug("%s: CVS handle is %d\n",
3353 __func__, data->src_port);
3354 voice_set_cvs_handle(v, data->src_port);
3355 } else
3356 pr_err("got NACK for sending \
3357 CVS create session \n");
3358 v->cvs_state = CMD_STATUS_SUCCESS;
3359 wake_up(&v->cvs_wait);
3360 break;
3361 case VSS_ISTREAM_CMD_SET_MUTE:
3362 case VSS_ISTREAM_CMD_SET_MEDIA_TYPE:
3363 case VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE:
3364 case VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE:
3365 case VSS_ISTREAM_CMD_SET_ENC_DTX_MODE:
3366 case VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE:
3367 case APRV2_IBASIC_CMD_DESTROY_SESSION:
Helen Zeng29eb7442011-06-20 11:06:29 -07003368 case VSS_ISTREAM_CMD_REGISTER_CALIBRATION_DATA:
3369 case VSS_ISTREAM_CMD_DEREGISTER_CALIBRATION_DATA:
3370 case VSS_ICOMMON_CMD_MAP_MEMORY:
3371 case VSS_ICOMMON_CMD_UNMAP_MEMORY:
Helen Zengbb49c702011-09-06 14:09:13 -07003372 case VSS_ICOMMON_CMD_SET_UI_PROPERTY:
Helen Zeng0705a5f2011-10-14 15:29:52 -07003373 case VSS_ISTREAM_CMD_START_PLAYBACK:
3374 case VSS_ISTREAM_CMD_STOP_PLAYBACK:
Helen Zenge3d716a2011-10-14 16:32:16 -07003375 case VSS_ISTREAM_CMD_START_RECORD:
3376 case VSS_ISTREAM_CMD_STOP_RECORD:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003377 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
3378 v->cvs_state = CMD_STATUS_SUCCESS;
3379 wake_up(&v->cvs_wait);
3380 break;
Ben Romberger13b74ab2011-07-18 17:36:32 -07003381 case VOICE_CMD_SET_PARAM:
3382 rtac_make_voice_callback(RTAC_CVS, ptr,
3383 data->payload_size);
3384 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003385 default:
3386 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
3387 break;
3388 }
3389 }
3390 } else if (data->opcode == VSS_ISTREAM_EVT_SEND_ENC_BUFFER) {
3391 uint32_t *voc_pkt = data->payload;
3392 uint32_t pkt_len = data->payload_size;
3393
Neema Shetty2c07eb52011-08-21 20:33:52 -07003394 if (voc_pkt != NULL && c->mvs_info.ul_cb != NULL) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003395 pr_debug("%s: Media type is 0x%x\n",
3396 __func__, voc_pkt[0]);
3397
3398 /* Remove media ID from payload. */
3399 voc_pkt++;
3400 pkt_len = pkt_len - 4;
3401
Neema Shetty2c07eb52011-08-21 20:33:52 -07003402 c->mvs_info.ul_cb((uint8_t *)voc_pkt,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003403 pkt_len,
Neema Shetty2c07eb52011-08-21 20:33:52 -07003404 c->mvs_info.private_data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003405 } else
3406 pr_err("%s: voc_pkt is 0x%x ul_cb is 0x%x\n",
3407 __func__, (unsigned int)voc_pkt,
Neema Shetty2c07eb52011-08-21 20:33:52 -07003408 (unsigned int) c->mvs_info.ul_cb);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003409 } else if (data->opcode == VSS_ISTREAM_EVT_REQUEST_DEC_BUFFER) {
3410 struct cvs_send_dec_buf_cmd send_dec_buf;
3411 int ret = 0;
3412 uint32_t pkt_len = 0;
3413
Neema Shetty2c07eb52011-08-21 20:33:52 -07003414 if (c->mvs_info.dl_cb != NULL) {
3415 send_dec_buf.dec_buf.media_id = c->mvs_info.media_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003416
Neema Shetty2c07eb52011-08-21 20:33:52 -07003417 c->mvs_info.dl_cb(
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003418 (uint8_t *)&send_dec_buf.dec_buf.packet_data,
3419 &pkt_len,
Neema Shetty2c07eb52011-08-21 20:33:52 -07003420 c->mvs_info.private_data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003421
3422 send_dec_buf.hdr.hdr_field =
3423 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
3424 APR_HDR_LEN(APR_HDR_SIZE),
3425 APR_PKT_VER);
3426 send_dec_buf.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
3427 sizeof(send_dec_buf.dec_buf.media_id) + pkt_len);
Neema Shetty2c07eb52011-08-21 20:33:52 -07003428 send_dec_buf.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003429 send_dec_buf.hdr.dest_port = voice_get_cvs_handle(v);
3430 send_dec_buf.hdr.token = 0;
3431 send_dec_buf.hdr.opcode =
3432 VSS_ISTREAM_EVT_SEND_DEC_BUFFER;
3433
Neema Shetty2c07eb52011-08-21 20:33:52 -07003434 ret = apr_send_pkt(c->apr_q6_cvs,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003435 (uint32_t *) &send_dec_buf);
3436 if (ret < 0) {
3437 pr_err("%s: Error %d sending DEC_BUF\n",
3438 __func__, ret);
3439 goto fail;
3440 }
3441 } else
3442 pr_debug("%s: dl_cb is NULL\n", __func__);
Ben Romberger13b74ab2011-07-18 17:36:32 -07003443 } else if (data->opcode == VSS_ISTREAM_EVT_SEND_DEC_BUFFER) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003444 pr_debug("Send dec buf resp\n");
Ben Romberger13b74ab2011-07-18 17:36:32 -07003445 } else if (data->opcode == VOICE_EVT_GET_PARAM_ACK) {
3446 rtac_make_voice_callback(RTAC_CVS, data->payload,
3447 data->payload_size);
3448 } else
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003449 pr_debug("Unknown opcode 0x%x\n", data->opcode);
3450
3451fail:
3452 return 0;
3453}
3454
3455static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv)
3456{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003457 uint32_t *ptr = NULL;
3458 struct common_data *c = NULL;
3459 struct voice_data *v = NULL;
Neema Shetty07477582011-09-02 17:35:44 -07003460 int i = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003461
3462 if ((data == NULL) || (priv == NULL)) {
3463 pr_err("%s: data or priv is NULL\n", __func__);
3464 return -EINVAL;
3465 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07003466
3467 c = priv;
3468
3469 v = voice_get_session(data->dest_port);
3470 if (v == NULL) {
3471 pr_err("%s: v is NULL\n", __func__);
3472
3473 return -EINVAL;
3474 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003475
3476 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
3477 data->payload_size, data->opcode);
3478
Neema Shetty07477582011-09-02 17:35:44 -07003479 if (data->opcode == RESET_EVENTS) {
3480 pr_debug("%s: Reset event received in Voice service\n",
3481 __func__);
3482
3483 apr_reset(c->apr_q6_cvp);
3484 c->apr_q6_cvp = NULL;
3485
3486 /* Sub-system restart is applicable to all sessions. */
3487 for (i = 0; i < MAX_VOC_SESSIONS; i++)
3488 c->voice[i].cvp_handle = 0;
3489
3490 return 0;
3491 }
3492
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003493 if (data->opcode == APR_BASIC_RSP_RESULT) {
3494 if (data->payload_size) {
3495 ptr = data->payload;
3496
3497 pr_info("%x %x\n", ptr[0], ptr[1]);
3498
3499 switch (ptr[0]) {
3500 case VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION:
3501 /*response from CVP */
3502 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
3503 if (!ptr[1]) {
3504 voice_set_cvp_handle(v, data->src_port);
3505 pr_debug("cvphdl=%d\n", data->src_port);
3506 } else
3507 pr_err("got NACK from CVP create \
3508 session response\n");
3509 v->cvp_state = CMD_STATUS_SUCCESS;
3510 wake_up(&v->cvp_wait);
3511 break;
3512 case VSS_IVOCPROC_CMD_SET_DEVICE:
3513 case VSS_IVOCPROC_CMD_SET_RX_VOLUME_INDEX:
3514 case VSS_IVOCPROC_CMD_ENABLE:
3515 case VSS_IVOCPROC_CMD_DISABLE:
3516 case APRV2_IBASIC_CMD_DESTROY_SESSION:
Helen Zeng29eb7442011-06-20 11:06:29 -07003517 case VSS_IVOCPROC_CMD_REGISTER_VOLUME_CAL_TABLE:
3518 case VSS_IVOCPROC_CMD_DEREGISTER_VOLUME_CAL_TABLE:
3519 case VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA:
3520 case VSS_IVOCPROC_CMD_DEREGISTER_CALIBRATION_DATA:
3521 case VSS_ICOMMON_CMD_MAP_MEMORY:
3522 case VSS_ICOMMON_CMD_UNMAP_MEMORY:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003523 v->cvp_state = CMD_STATUS_SUCCESS;
3524 wake_up(&v->cvp_wait);
3525 break;
Ben Romberger13b74ab2011-07-18 17:36:32 -07003526 case VOICE_CMD_SET_PARAM:
3527 rtac_make_voice_callback(RTAC_CVP, ptr,
3528 data->payload_size);
3529 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003530 default:
3531 pr_debug("%s: not match cmd = 0x%x\n",
3532 __func__, ptr[0]);
3533 break;
3534 }
3535 }
Ben Romberger13b74ab2011-07-18 17:36:32 -07003536 } else if (data->opcode == VOICE_EVT_GET_PARAM_ACK) {
3537 rtac_make_voice_callback(RTAC_CVP, data->payload,
3538 data->payload_size);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003539 }
3540 return 0;
3541}
3542
3543
3544static int __init voice_init(void)
3545{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003546 int rc = 0, i = 0;
3547
3548 memset(&common, 0, sizeof(struct common_data));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003549
3550 /* set default value */
Neema Shetty2c07eb52011-08-21 20:33:52 -07003551 common.default_mute_val = 1; /* default is mute */
3552 common.default_vol_val = 0;
3553 common.default_sample_val = 8000;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003554
3555 /* Initialize MVS info. */
Neema Shetty2c07eb52011-08-21 20:33:52 -07003556 common.mvs_info.network_type = VSS_NETWORK_ID_DEFAULT;
3557
3558 mutex_init(&common.common_lock);
3559
3560 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
3561 common.voice[i].session_id = SESSION_ID_BASE + i;
3562
3563 /* initialize dev_rx and dev_tx */
3564 common.voice[i].dev_rx.volume = common.default_vol_val;
3565 common.voice[i].dev_tx.mute = common.default_mute_val;
3566
3567 common.voice[i].dev_tx.port_id = 1;
3568 common.voice[i].dev_rx.port_id = 0;
3569 common.voice[i].sidetone_gain = 0x512;
3570
3571 common.voice[i].voc_state = VOC_INIT;
3572
3573 init_waitqueue_head(&common.voice[i].mvm_wait);
3574 init_waitqueue_head(&common.voice[i].cvs_wait);
3575 init_waitqueue_head(&common.voice[i].cvp_wait);
3576
3577 mutex_init(&common.voice[i].lock);
3578 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003579
3580 return rc;
3581}
3582
3583device_initcall(voice_init);