blob: c899b2a52595a28b03e63c20d1c49f9bec469a29 [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
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070057
58static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv);
59static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv);
60static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv);
61
62static u16 voice_get_mvm_handle(struct voice_data *v)
63{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070064 if (v == NULL) {
65 pr_err("%s: v is NULL\n", __func__);
Neema Shetty2c07eb52011-08-21 20:33:52 -070066 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070067 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070068
Neema Shetty2c07eb52011-08-21 20:33:52 -070069 pr_debug("%s: mvm_handle %d\n", __func__, v->mvm_handle);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070070
Neema Shetty2c07eb52011-08-21 20:33:52 -070071 return v->mvm_handle;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070072}
73
74static void voice_set_mvm_handle(struct voice_data *v, u16 mvm_handle)
75{
76 pr_debug("%s: mvm_handle %d\n", __func__, mvm_handle);
77 if (v == NULL) {
78 pr_err("%s: v is NULL\n", __func__);
79 return;
80 }
81
Neema Shetty2c07eb52011-08-21 20:33:52 -070082 v->mvm_handle = mvm_handle;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070083}
84
85static u16 voice_get_cvs_handle(struct voice_data *v)
86{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070087 if (v == NULL) {
88 pr_err("%s: v is NULL\n", __func__);
Neema Shetty2c07eb52011-08-21 20:33:52 -070089 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070090 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070091
Neema Shetty2c07eb52011-08-21 20:33:52 -070092 pr_debug("%s: cvs_handle %d\n", __func__, v->cvs_handle);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070093
Neema Shetty2c07eb52011-08-21 20:33:52 -070094 return v->cvs_handle;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070095}
96
97static void voice_set_cvs_handle(struct voice_data *v, u16 cvs_handle)
98{
99 pr_debug("%s: cvs_handle %d\n", __func__, cvs_handle);
100 if (v == NULL) {
101 pr_err("%s: v is NULL\n", __func__);
102 return;
103 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700104
105 v->cvs_handle = cvs_handle;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700106}
107
108static u16 voice_get_cvp_handle(struct voice_data *v)
109{
Neema Shetty2c07eb52011-08-21 20:33:52 -0700110 if (v == NULL) {
111 pr_err("%s: v is NULL\n", __func__);
112 return 0;
113 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700114
Neema Shetty2c07eb52011-08-21 20:33:52 -0700115 pr_debug("%s: cvp_handle %d\n", __func__, v->cvp_handle);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700116
Neema Shetty2c07eb52011-08-21 20:33:52 -0700117 return v->cvp_handle;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700118}
119
120static void voice_set_cvp_handle(struct voice_data *v, u16 cvp_handle)
121{
122 pr_debug("%s: cvp_handle %d\n", __func__, cvp_handle);
123 if (v == NULL) {
124 pr_err("%s: v is NULL\n", __func__);
125 return;
126 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700127
128 v->cvp_handle = cvp_handle;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700129}
130
Neema Shetty2c07eb52011-08-21 20:33:52 -0700131uint16_t voc_get_session_id(char *name)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700132{
Neema Shetty2c07eb52011-08-21 20:33:52 -0700133 u16 session_id = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700134
Neema Shetty2c07eb52011-08-21 20:33:52 -0700135 if (name != NULL) {
136 if (!strncmp(name, "Voice session", 13))
137 session_id = common.voice[VOC_PATH_PASSIVE].session_id;
138 else
139 session_id = common.voice[VOC_PATH_FULL].session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700140
Helen Zeng0f4c4e22011-09-29 14:25:43 -0700141 pr_debug("%s: %s has session id 0x%x\n", __func__, name,
142 session_id);
143 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700144
145 return session_id;
146}
147
148static struct voice_data *voice_get_session(u16 session_id)
149{
150 struct voice_data *v = NULL;
151
152 if ((session_id >= SESSION_ID_BASE) &&
153 (session_id < SESSION_ID_BASE + MAX_VOC_SESSIONS)) {
154 v = &common.voice[session_id - SESSION_ID_BASE];
155 }
156
157 pr_debug("%s: session_id 0x%x session handle 0x%x\n",
158 __func__, session_id, (unsigned int)v);
159
160 return v;
161}
162
163static bool is_voice_session(u16 session_id)
164{
165 return (session_id == common.voice[VOC_PATH_PASSIVE].session_id);
166}
167
168static bool is_voip_session(u16 session_id)
169{
170 return (session_id == common.voice[VOC_PATH_FULL].session_id);
171}
172
173static int voice_apr_register(void)
174{
175 pr_debug("%s\n", __func__);
176
177 mutex_lock(&common.common_lock);
178
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700179 /* register callback to APR */
Neema Shetty2c07eb52011-08-21 20:33:52 -0700180 if (common.apr_q6_mvm == NULL) {
181 pr_debug("%s: Start to register MVM callback\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700182
Neema Shetty2c07eb52011-08-21 20:33:52 -0700183 common.apr_q6_mvm = apr_register("ADSP", "MVM",
184 qdsp_mvm_callback,
185 0xFFFFFFFF, &common);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700186
Neema Shetty2c07eb52011-08-21 20:33:52 -0700187 if (common.apr_q6_mvm == NULL) {
188 pr_err("%s: Unable to register MVM\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700189 goto err;
190 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700191 }
192
Neema Shetty2c07eb52011-08-21 20:33:52 -0700193 if (common.apr_q6_cvs == NULL) {
194 pr_debug("%s: Start to register CVS callback\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700195
Neema Shetty2c07eb52011-08-21 20:33:52 -0700196 common.apr_q6_cvs = apr_register("ADSP", "CVS",
197 qdsp_cvs_callback,
198 0xFFFFFFFF, &common);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700199
Neema Shetty2c07eb52011-08-21 20:33:52 -0700200 if (common.apr_q6_cvs == NULL) {
201 pr_err("%s: Unable to register CVS\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700202 goto err;
203 }
Ben Romberger13b74ab2011-07-18 17:36:32 -0700204
Neema Shetty2c07eb52011-08-21 20:33:52 -0700205 rtac_set_voice_handle(RTAC_CVS, common.apr_q6_cvs);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700206 }
207
Neema Shetty2c07eb52011-08-21 20:33:52 -0700208 if (common.apr_q6_cvp == NULL) {
209 pr_debug("%s: Start to register CVP callback\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700210
Neema Shetty2c07eb52011-08-21 20:33:52 -0700211 common.apr_q6_cvp = apr_register("ADSP", "CVP",
212 qdsp_cvp_callback,
213 0xFFFFFFFF, &common);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700214
Neema Shetty2c07eb52011-08-21 20:33:52 -0700215 if (common.apr_q6_cvp == NULL) {
216 pr_err("%s: Unable to register CVP\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700217 goto err;
218 }
Ben Romberger13b74ab2011-07-18 17:36:32 -0700219
Neema Shetty2c07eb52011-08-21 20:33:52 -0700220 rtac_set_voice_handle(RTAC_CVP, common.apr_q6_cvp);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700221 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700222
223 mutex_unlock(&common.common_lock);
224
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700225 return 0;
226
227err:
Neema Shetty2c07eb52011-08-21 20:33:52 -0700228 if (common.apr_q6_cvs != NULL) {
229 apr_deregister(common.apr_q6_cvs);
230 common.apr_q6_cvs = NULL;
Ben Romberger13b74ab2011-07-18 17:36:32 -0700231 rtac_set_voice_handle(RTAC_CVS, NULL);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700232 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700233 if (common.apr_q6_mvm != NULL) {
234 apr_deregister(common.apr_q6_mvm);
235 common.apr_q6_mvm = NULL;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700236 }
237
Neema Shetty2c07eb52011-08-21 20:33:52 -0700238 mutex_unlock(&common.common_lock);
239
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700240 return -ENODEV;
241}
242
243static int voice_create_mvm_cvs_session(struct voice_data *v)
244{
245 int ret = 0;
Helen Zeng69b00962011-07-08 11:38:36 -0700246 struct mvm_create_ctl_session_cmd mvm_session_cmd;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700247 struct cvs_create_passive_ctl_session_cmd cvs_session_cmd;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700248 struct cvs_create_full_ctl_session_cmd cvs_full_ctl_cmd;
249 struct mvm_attach_stream_cmd attach_stream_cmd;
250 void *apr_mvm, *apr_cvs, *apr_cvp;
251 u16 mvm_handle, cvs_handle, cvp_handle;
252
253 if (v == NULL) {
254 pr_err("%s: v is NULL\n", __func__);
255 return -EINVAL;
256 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700257 apr_mvm = common.apr_q6_mvm;
258 apr_cvs = common.apr_q6_cvs;
259 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700260
261 if (!apr_mvm || !apr_cvs || !apr_cvp) {
262 pr_err("%s: apr_mvm or apr_cvs or apr_cvp is NULL\n", __func__);
263 return -EINVAL;
264 }
265 mvm_handle = voice_get_mvm_handle(v);
266 cvs_handle = voice_get_cvs_handle(v);
267 cvp_handle = voice_get_cvp_handle(v);
268
269 pr_debug("%s: mvm_hdl=%d, cvs_hdl=%d\n", __func__,
270 mvm_handle, cvs_handle);
271 /* send cmd to create mvm session and wait for response */
272
273 if (!mvm_handle) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700274 if (is_voice_session(v->session_id)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700275 mvm_session_cmd.hdr.hdr_field = APR_HDR_FIELD(
276 APR_MSG_TYPE_SEQ_CMD,
277 APR_HDR_LEN(APR_HDR_SIZE),
278 APR_PKT_VER);
279 mvm_session_cmd.hdr.pkt_size = APR_PKT_SIZE(
280 APR_HDR_SIZE,
281 sizeof(mvm_session_cmd) -
282 APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700283 pr_debug("%s: send mvm create session pkt size = %d\n",
284 __func__, mvm_session_cmd.hdr.pkt_size);
285 mvm_session_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700286 mvm_session_cmd.hdr.dest_port = 0;
287 mvm_session_cmd.hdr.token = 0;
288 mvm_session_cmd.hdr.opcode =
289 VSS_IMVM_CMD_CREATE_PASSIVE_CONTROL_SESSION;
Neema Shetty9ba987d2011-10-25 18:14:50 -0700290 strlcpy(mvm_session_cmd.mvm_session.name,
291 "default modem voice",
292 sizeof(mvm_session_cmd.mvm_session.name));
Helen Zeng69b00962011-07-08 11:38:36 -0700293
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700294 v->mvm_state = CMD_STATUS_FAIL;
295
296 ret = apr_send_pkt(apr_mvm,
297 (uint32_t *) &mvm_session_cmd);
298 if (ret < 0) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700299 pr_err("%s: Error sending MVM_CONTROL_SESSION\n",
300 __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700301 goto fail;
302 }
303 ret = wait_event_timeout(v->mvm_wait,
304 (v->mvm_state == CMD_STATUS_SUCCESS),
305 msecs_to_jiffies(TIMEOUT_MS));
306 if (!ret) {
307 pr_err("%s: wait_event timeout\n", __func__);
308 goto fail;
309 }
310 } else {
311 pr_debug("%s: creating MVM full ctrl\n", __func__);
Helen Zeng69b00962011-07-08 11:38:36 -0700312 mvm_session_cmd.hdr.hdr_field =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700313 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
314 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
Helen Zeng69b00962011-07-08 11:38:36 -0700315 mvm_session_cmd.hdr.pkt_size =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700316 APR_PKT_SIZE(APR_HDR_SIZE,
Helen Zeng69b00962011-07-08 11:38:36 -0700317 sizeof(mvm_session_cmd) -
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700318 APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700319 mvm_session_cmd.hdr.src_port = v->session_id;
Helen Zeng69b00962011-07-08 11:38:36 -0700320 mvm_session_cmd.hdr.dest_port = 0;
321 mvm_session_cmd.hdr.token = 0;
322 mvm_session_cmd.hdr.opcode =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700323 VSS_IMVM_CMD_CREATE_FULL_CONTROL_SESSION;
Neema Shetty9ba987d2011-10-25 18:14:50 -0700324 strlcpy(mvm_session_cmd.mvm_session.name,
325 "default voip",
326 sizeof(mvm_session_cmd.mvm_session.name));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700327
328 v->mvm_state = CMD_STATUS_FAIL;
329
330 ret = apr_send_pkt(apr_mvm,
Helen Zeng69b00962011-07-08 11:38:36 -0700331 (uint32_t *) &mvm_session_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700332 if (ret < 0) {
333 pr_err("Fail in sending MVM_CONTROL_SESSION\n");
334 goto fail;
335 }
336 ret = wait_event_timeout(v->mvm_wait,
337 (v->mvm_state == CMD_STATUS_SUCCESS),
338 msecs_to_jiffies(TIMEOUT_MS));
339 if (!ret) {
340 pr_err("%s: wait_event timeout\n", __func__);
341 goto fail;
342 }
343 }
344 /* Get the created MVM handle. */
345 mvm_handle = voice_get_mvm_handle(v);
346 }
347 /* send cmd to create cvs session */
348 if (!cvs_handle) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700349 if (is_voice_session(v->session_id)) {
350 pr_debug("%s: creating CVS passive session\n",
351 __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700352
353 cvs_session_cmd.hdr.hdr_field = APR_HDR_FIELD(
354 APR_MSG_TYPE_SEQ_CMD,
355 APR_HDR_LEN(APR_HDR_SIZE),
356 APR_PKT_VER);
357 cvs_session_cmd.hdr.pkt_size =
358 APR_PKT_SIZE(APR_HDR_SIZE,
359 sizeof(cvs_session_cmd) -
360 APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700361 cvs_session_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700362 cvs_session_cmd.hdr.dest_port = 0;
363 cvs_session_cmd.hdr.token = 0;
364 cvs_session_cmd.hdr.opcode =
365 VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION;
Neema Shetty9ba987d2011-10-25 18:14:50 -0700366 strlcpy(cvs_session_cmd.cvs_session.name,
367 "default modem voice",
368 sizeof(cvs_session_cmd.cvs_session.name));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700369
370 v->cvs_state = CMD_STATUS_FAIL;
371
372 ret = apr_send_pkt(apr_cvs,
373 (uint32_t *) &cvs_session_cmd);
374 if (ret < 0) {
375 pr_err("Fail in sending STREAM_CONTROL_SESSION\n");
376 goto fail;
377 }
378 ret = wait_event_timeout(v->cvs_wait,
379 (v->cvs_state == CMD_STATUS_SUCCESS),
380 msecs_to_jiffies(TIMEOUT_MS));
381 if (!ret) {
382 pr_err("%s: wait_event timeout\n", __func__);
383 goto fail;
384 }
385 /* Get the created CVS handle. */
386 cvs_handle = voice_get_cvs_handle(v);
387
388 } else {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700389 pr_debug("%s: creating CVS full session\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700390
391 cvs_full_ctl_cmd.hdr.hdr_field =
392 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
393 APR_HDR_LEN(APR_HDR_SIZE),
394 APR_PKT_VER);
395
396 cvs_full_ctl_cmd.hdr.pkt_size =
397 APR_PKT_SIZE(APR_HDR_SIZE,
398 sizeof(cvs_full_ctl_cmd) -
399 APR_HDR_SIZE);
400
Neema Shetty2c07eb52011-08-21 20:33:52 -0700401 cvs_full_ctl_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700402 cvs_full_ctl_cmd.hdr.dest_port = 0;
403 cvs_full_ctl_cmd.hdr.token = 0;
404 cvs_full_ctl_cmd.hdr.opcode =
405 VSS_ISTREAM_CMD_CREATE_FULL_CONTROL_SESSION;
406 cvs_full_ctl_cmd.cvs_session.direction = 2;
407 cvs_full_ctl_cmd.cvs_session.enc_media_type =
Neema Shetty2c07eb52011-08-21 20:33:52 -0700408 common.mvs_info.media_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700409 cvs_full_ctl_cmd.cvs_session.dec_media_type =
Neema Shetty2c07eb52011-08-21 20:33:52 -0700410 common.mvs_info.media_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700411 cvs_full_ctl_cmd.cvs_session.network_id =
Neema Shetty2c07eb52011-08-21 20:33:52 -0700412 common.mvs_info.network_type;
Neema Shetty9ba987d2011-10-25 18:14:50 -0700413 strlcpy(cvs_full_ctl_cmd.cvs_session.name,
414 "default q6 voice",
415 sizeof(cvs_full_ctl_cmd.cvs_session.name));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700416
417 v->cvs_state = CMD_STATUS_FAIL;
418
419 ret = apr_send_pkt(apr_cvs,
420 (uint32_t *) &cvs_full_ctl_cmd);
421
422 if (ret < 0) {
423 pr_err("%s: Err %d sending CREATE_FULL_CTRL\n",
424 __func__, ret);
425 goto fail;
426 }
427 ret = wait_event_timeout(v->cvs_wait,
428 (v->cvs_state == CMD_STATUS_SUCCESS),
429 msecs_to_jiffies(TIMEOUT_MS));
430 if (!ret) {
431 pr_err("%s: wait_event timeout\n", __func__);
432 goto fail;
433 }
434 /* Get the created CVS handle. */
435 cvs_handle = voice_get_cvs_handle(v);
436
437 /* Attach MVM to CVS. */
Neema Shetty2c07eb52011-08-21 20:33:52 -0700438 pr_debug("%s: Attach MVM to stream\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700439
440 attach_stream_cmd.hdr.hdr_field =
441 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
442 APR_HDR_LEN(APR_HDR_SIZE),
443 APR_PKT_VER);
444 attach_stream_cmd.hdr.pkt_size =
445 APR_PKT_SIZE(APR_HDR_SIZE,
446 sizeof(attach_stream_cmd) -
447 APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700448 attach_stream_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700449 attach_stream_cmd.hdr.dest_port = mvm_handle;
450 attach_stream_cmd.hdr.token = 0;
451 attach_stream_cmd.hdr.opcode =
452 VSS_IMVM_CMD_ATTACH_STREAM;
453 attach_stream_cmd.attach_stream.handle = cvs_handle;
454
455 v->mvm_state = CMD_STATUS_FAIL;
456 ret = apr_send_pkt(apr_mvm,
457 (uint32_t *) &attach_stream_cmd);
458 if (ret < 0) {
459 pr_err("%s: Error %d sending ATTACH_STREAM\n",
460 __func__, ret);
461 goto fail;
462 }
463 ret = wait_event_timeout(v->mvm_wait,
464 (v->mvm_state == CMD_STATUS_SUCCESS),
465 msecs_to_jiffies(TIMEOUT_MS));
466 if (!ret) {
467 pr_err("%s: wait_event timeout\n", __func__);
468 goto fail;
469 }
470 }
471 }
472 return 0;
473
474fail:
475 return -EINVAL;
476}
477
478static int voice_destroy_mvm_cvs_session(struct voice_data *v)
479{
480 int ret = 0;
481 struct mvm_detach_stream_cmd detach_stream;
482 struct apr_hdr mvm_destroy;
483 struct apr_hdr cvs_destroy;
484 void *apr_mvm, *apr_cvs;
485 u16 mvm_handle, cvs_handle;
486
487 if (v == NULL) {
488 pr_err("%s: v is NULL\n", __func__);
489 return -EINVAL;
490 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700491 apr_mvm = common.apr_q6_mvm;
492 apr_cvs = common.apr_q6_cvs;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700493
494 if (!apr_mvm || !apr_cvs) {
495 pr_err("%s: apr_mvm or apr_cvs is NULL\n", __func__);
496 return -EINVAL;
497 }
498 mvm_handle = voice_get_mvm_handle(v);
499 cvs_handle = voice_get_cvs_handle(v);
500
501 /* MVM, CVS sessions are destroyed only for Full control sessions. */
Neema Shetty2c07eb52011-08-21 20:33:52 -0700502 if (is_voip_session(v->session_id)) {
503 pr_debug("%s: MVM detach stream\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700504
505 /* Detach voice stream. */
506 detach_stream.hdr.hdr_field =
507 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
508 APR_HDR_LEN(APR_HDR_SIZE),
509 APR_PKT_VER);
510 detach_stream.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
511 sizeof(detach_stream) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700512 detach_stream.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700513 detach_stream.hdr.dest_port = mvm_handle;
514 detach_stream.hdr.token = 0;
515 detach_stream.hdr.opcode = VSS_IMVM_CMD_DETACH_STREAM;
516 detach_stream.detach_stream.handle = cvs_handle;
517
518 v->mvm_state = CMD_STATUS_FAIL;
519
520 ret = apr_send_pkt(apr_mvm, (uint32_t *) &detach_stream);
521 if (ret < 0) {
522 pr_err("%s: Error %d sending DETACH_STREAM\n",
523 __func__, ret);
524 goto fail;
525 }
526 ret = wait_event_timeout(v->mvm_wait,
527 (v->mvm_state == CMD_STATUS_SUCCESS),
528 msecs_to_jiffies(TIMEOUT_MS));
529 if (!ret) {
530 pr_err("%s: wait event timeout\n", __func__);
531 goto fail;
532 }
533 /* Destroy CVS. */
Neema Shetty2c07eb52011-08-21 20:33:52 -0700534 pr_debug("%s: CVS destroy session\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700535
536 cvs_destroy.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
537 APR_HDR_LEN(APR_HDR_SIZE),
538 APR_PKT_VER);
539 cvs_destroy.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
540 sizeof(cvs_destroy) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700541 cvs_destroy.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700542 cvs_destroy.dest_port = cvs_handle;
543 cvs_destroy.token = 0;
544 cvs_destroy.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
545
546 v->cvs_state = CMD_STATUS_FAIL;
547
548 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_destroy);
549 if (ret < 0) {
550 pr_err("%s: Error %d sending CVS DESTROY\n",
551 __func__, ret);
552 goto fail;
553 }
554 ret = wait_event_timeout(v->cvs_wait,
555 (v->cvs_state == CMD_STATUS_SUCCESS),
556 msecs_to_jiffies(TIMEOUT_MS));
557 if (!ret) {
558 pr_err("%s: wait event timeout\n", __func__);
559
560 goto fail;
561 }
562 cvs_handle = 0;
563 voice_set_cvs_handle(v, cvs_handle);
564
565 /* Destroy MVM. */
566 pr_debug("MVM destroy session\n");
567
568 mvm_destroy.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
569 APR_HDR_LEN(APR_HDR_SIZE),
570 APR_PKT_VER);
571 mvm_destroy.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
572 sizeof(mvm_destroy) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700573 mvm_destroy.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700574 mvm_destroy.dest_port = mvm_handle;
575 mvm_destroy.token = 0;
576 mvm_destroy.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
577
578 v->mvm_state = CMD_STATUS_FAIL;
579
580 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_destroy);
581 if (ret < 0) {
582 pr_err("%s: Error %d sending MVM DESTROY\n",
583 __func__, ret);
584
585 goto fail;
586 }
587 ret = wait_event_timeout(v->mvm_wait,
588 (v->mvm_state == CMD_STATUS_SUCCESS),
589 msecs_to_jiffies(TIMEOUT_MS));
590 if (!ret) {
591 pr_err("%s: wait event timeout\n", __func__);
592
593 goto fail;
594 }
595 mvm_handle = 0;
596 voice_set_mvm_handle(v, mvm_handle);
597 }
598 return 0;
599fail:
600 return -EINVAL;
601}
602
603static int voice_send_tty_mode_cmd(struct voice_data *v)
604{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700605 int ret = 0;
606 struct mvm_set_tty_mode_cmd mvm_tty_mode_cmd;
607 void *apr_mvm;
608 u16 mvm_handle;
609
610 if (v == NULL) {
611 pr_err("%s: v is NULL\n", __func__);
612 return -EINVAL;
613 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700614 apr_mvm = common.apr_q6_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700615
616 if (!apr_mvm) {
617 pr_err("%s: apr_mvm is NULL.\n", __func__);
618 return -EINVAL;
619 }
620 mvm_handle = voice_get_mvm_handle(v);
621
Helen Zengcc65b5b2011-07-06 19:14:48 -0700622 if (v->tty_mode) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700623 /* send tty mode cmd to mvm */
624 mvm_tty_mode_cmd.hdr.hdr_field = APR_HDR_FIELD(
625 APR_MSG_TYPE_SEQ_CMD,
626 APR_HDR_LEN(APR_HDR_SIZE),
627 APR_PKT_VER);
628 mvm_tty_mode_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
629 sizeof(mvm_tty_mode_cmd) -
630 APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700631 pr_debug("%s: pkt size = %d\n",
632 __func__, mvm_tty_mode_cmd.hdr.pkt_size);
633 mvm_tty_mode_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700634 mvm_tty_mode_cmd.hdr.dest_port = mvm_handle;
635 mvm_tty_mode_cmd.hdr.token = 0;
636 mvm_tty_mode_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_TTY_MODE;
Helen Zengcc65b5b2011-07-06 19:14:48 -0700637 mvm_tty_mode_cmd.tty_mode.mode = v->tty_mode;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700638 pr_debug("tty mode =%d\n", mvm_tty_mode_cmd.tty_mode.mode);
639
640 v->mvm_state = CMD_STATUS_FAIL;
641 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_tty_mode_cmd);
642 if (ret < 0) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700643 pr_err("%s: Error %d sending SET_TTY_MODE\n",
644 __func__, ret);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700645 goto fail;
646 }
647 ret = wait_event_timeout(v->mvm_wait,
648 (v->mvm_state == CMD_STATUS_SUCCESS),
649 msecs_to_jiffies(TIMEOUT_MS));
650 if (!ret) {
651 pr_err("%s: wait_event timeout\n", __func__);
652 goto fail;
653 }
654 }
655 return 0;
656fail:
657 return -EINVAL;
658}
659
660static int voice_config_cvs_vocoder(struct voice_data *v)
661{
662 int ret = 0;
663 void *apr_cvs;
664 u16 cvs_handle;
665 /* Set media type. */
666 struct cvs_set_media_type_cmd cvs_set_media_cmd;
667
668 if (v == NULL) {
669 pr_err("%s: v is NULL\n", __func__);
670 return -EINVAL;
671 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700672 apr_cvs = common.apr_q6_cvs;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700673
674 if (!apr_cvs) {
675 pr_err("%s: apr_cvs is NULL.\n", __func__);
676 return -EINVAL;
677 }
678
679 cvs_handle = voice_get_cvs_handle(v);
680
681 cvs_set_media_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
682 APR_HDR_LEN(APR_HDR_SIZE),
683 APR_PKT_VER);
684 cvs_set_media_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
685 sizeof(cvs_set_media_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700686 cvs_set_media_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700687 cvs_set_media_cmd.hdr.dest_port = cvs_handle;
688 cvs_set_media_cmd.hdr.token = 0;
689 cvs_set_media_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_MEDIA_TYPE;
Neema Shetty2c07eb52011-08-21 20:33:52 -0700690 cvs_set_media_cmd.media_type.tx_media_id = common.mvs_info.media_type;
691 cvs_set_media_cmd.media_type.rx_media_id = common.mvs_info.media_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700692
693 v->cvs_state = CMD_STATUS_FAIL;
694
695 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_media_cmd);
696 if (ret < 0) {
697 pr_err("%s: Error %d sending SET_MEDIA_TYPE\n",
698 __func__, ret);
699
700 goto fail;
701 }
702 ret = wait_event_timeout(v->cvs_wait,
703 (v->cvs_state == CMD_STATUS_SUCCESS),
704 msecs_to_jiffies(TIMEOUT_MS));
705 if (!ret) {
706 pr_err("%s: wait_event timeout\n", __func__);
707
708 goto fail;
709 }
710 /* Set encoder properties. */
Neema Shetty2c07eb52011-08-21 20:33:52 -0700711 switch (common.mvs_info.media_type) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700712 case VSS_MEDIA_ID_EVRC_MODEM: {
713 struct cvs_set_cdma_enc_minmax_rate_cmd cvs_set_cdma_rate;
714
715 pr_debug("Setting EVRC min-max rate\n");
716
717 cvs_set_cdma_rate.hdr.hdr_field =
718 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
719 APR_HDR_LEN(APR_HDR_SIZE),
720 APR_PKT_VER);
721 cvs_set_cdma_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
722 sizeof(cvs_set_cdma_rate) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700723 cvs_set_cdma_rate.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700724 cvs_set_cdma_rate.hdr.dest_port = cvs_handle;
725 cvs_set_cdma_rate.hdr.token = 0;
726 cvs_set_cdma_rate.hdr.opcode =
727 VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE;
Neema Shetty2c07eb52011-08-21 20:33:52 -0700728 cvs_set_cdma_rate.cdma_rate.min_rate = common.mvs_info.rate;
729 cvs_set_cdma_rate.cdma_rate.max_rate = common.mvs_info.rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700730
731 v->cvs_state = CMD_STATUS_FAIL;
732
733 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_cdma_rate);
734 if (ret < 0) {
735 pr_err("%s: Error %d sending SET_EVRC_MINMAX_RATE\n",
736 __func__, ret);
737 goto fail;
738 }
739 ret = wait_event_timeout(v->cvs_wait,
740 (v->cvs_state == CMD_STATUS_SUCCESS),
741 msecs_to_jiffies(TIMEOUT_MS));
742 if (!ret) {
743 pr_err("%s: wait_event timeout\n", __func__);
744
745 goto fail;
746 }
747 break;
748 }
749 case VSS_MEDIA_ID_AMR_NB_MODEM: {
750 struct cvs_set_amr_enc_rate_cmd cvs_set_amr_rate;
751 struct cvs_set_enc_dtx_mode_cmd cvs_set_dtx;
752
753 pr_debug("Setting AMR rate\n");
754
755 cvs_set_amr_rate.hdr.hdr_field =
756 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
757 APR_HDR_LEN(APR_HDR_SIZE),
758 APR_PKT_VER);
759 cvs_set_amr_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
760 sizeof(cvs_set_amr_rate) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700761 cvs_set_amr_rate.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700762 cvs_set_amr_rate.hdr.dest_port = cvs_handle;
763 cvs_set_amr_rate.hdr.token = 0;
764 cvs_set_amr_rate.hdr.opcode =
765 VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE;
Neema Shetty2c07eb52011-08-21 20:33:52 -0700766 cvs_set_amr_rate.amr_rate.mode = common.mvs_info.rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700767
768 v->cvs_state = CMD_STATUS_FAIL;
769
770 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_amr_rate);
771 if (ret < 0) {
772 pr_err("%s: Error %d sending SET_AMR_RATE\n",
773 __func__, ret);
774 goto fail;
775 }
776 ret = wait_event_timeout(v->cvs_wait,
777 (v->cvs_state == CMD_STATUS_SUCCESS),
778 msecs_to_jiffies(TIMEOUT_MS));
779 if (!ret) {
780 pr_err("%s: wait_event timeout\n", __func__);
781 goto fail;
782 }
783 /* Disable DTX */
784 pr_debug("Disabling DTX\n");
785
786 cvs_set_dtx.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
787 APR_HDR_LEN(APR_HDR_SIZE),
788 APR_PKT_VER);
789 cvs_set_dtx.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
790 sizeof(cvs_set_dtx) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700791 cvs_set_dtx.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700792 cvs_set_dtx.hdr.dest_port = cvs_handle;
793 cvs_set_dtx.hdr.token = 0;
794 cvs_set_dtx.hdr.opcode = VSS_ISTREAM_CMD_SET_ENC_DTX_MODE;
795 cvs_set_dtx.dtx_mode.enable = 0;
796
797 v->cvs_state = CMD_STATUS_FAIL;
798
799 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_dtx);
800 if (ret < 0) {
801 pr_err("%s: Error %d sending SET_DTX\n",
802 __func__, ret);
803 goto fail;
804 }
805 ret = wait_event_timeout(v->cvs_wait,
806 (v->cvs_state == CMD_STATUS_SUCCESS),
807 msecs_to_jiffies(TIMEOUT_MS));
808 if (!ret) {
809 pr_err("%s: wait_event timeout\n", __func__);
810 goto fail;
811 }
812 break;
813 }
814 case VSS_MEDIA_ID_AMR_WB_MODEM: {
815 struct cvs_set_amrwb_enc_rate_cmd cvs_set_amrwb_rate;
816 struct cvs_set_enc_dtx_mode_cmd cvs_set_dtx;
817
818 pr_debug("Setting AMR WB rate\n");
819
820 cvs_set_amrwb_rate.hdr.hdr_field =
821 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
822 APR_HDR_LEN(APR_HDR_SIZE),
823 APR_PKT_VER);
824 cvs_set_amrwb_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
825 sizeof(cvs_set_amrwb_rate) -
826 APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700827 cvs_set_amrwb_rate.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700828 cvs_set_amrwb_rate.hdr.dest_port = cvs_handle;
829 cvs_set_amrwb_rate.hdr.token = 0;
830 cvs_set_amrwb_rate.hdr.opcode =
831 VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE;
Neema Shetty2c07eb52011-08-21 20:33:52 -0700832 cvs_set_amrwb_rate.amrwb_rate.mode = common.mvs_info.rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700833
834 v->cvs_state = CMD_STATUS_FAIL;
835
836 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_amrwb_rate);
837 if (ret < 0) {
838 pr_err("%s: Error %d sending SET_AMRWB_RATE\n",
839 __func__, ret);
840 goto fail;
841 }
842 ret = wait_event_timeout(v->cvs_wait,
843 (v->cvs_state == CMD_STATUS_SUCCESS),
844 msecs_to_jiffies(TIMEOUT_MS));
845 if (!ret) {
846 pr_err("%s: wait_event timeout\n", __func__);
847 goto fail;
848 }
849 /* Disable DTX */
850 pr_debug("Disabling DTX\n");
851
852 cvs_set_dtx.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
853 APR_HDR_LEN(APR_HDR_SIZE),
854 APR_PKT_VER);
855 cvs_set_dtx.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
856 sizeof(cvs_set_dtx) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700857 cvs_set_dtx.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700858 cvs_set_dtx.hdr.dest_port = cvs_handle;
859 cvs_set_dtx.hdr.token = 0;
860 cvs_set_dtx.hdr.opcode = VSS_ISTREAM_CMD_SET_ENC_DTX_MODE;
861 cvs_set_dtx.dtx_mode.enable = 0;
862
863 v->cvs_state = CMD_STATUS_FAIL;
864
865 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_dtx);
866 if (ret < 0) {
867 pr_err("%s: Error %d sending SET_DTX\n",
868 __func__, ret);
869 goto fail;
870 }
871 ret = wait_event_timeout(v->cvs_wait,
872 (v->cvs_state == CMD_STATUS_SUCCESS),
873 msecs_to_jiffies(TIMEOUT_MS));
874 if (!ret) {
875 pr_err("%s: wait_event timeout\n", __func__);
876 goto fail;
877 }
878 break;
879 }
880 case VSS_MEDIA_ID_G729:
881 case VSS_MEDIA_ID_G711_ALAW:
882 case VSS_MEDIA_ID_G711_MULAW: {
883 struct cvs_set_enc_dtx_mode_cmd cvs_set_dtx;
884 /* Disable DTX */
885 pr_debug("Disabling DTX\n");
886
887 cvs_set_dtx.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
888 APR_HDR_LEN(APR_HDR_SIZE),
889 APR_PKT_VER);
890 cvs_set_dtx.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
891 sizeof(cvs_set_dtx) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700892 cvs_set_dtx.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700893 cvs_set_dtx.hdr.dest_port = cvs_handle;
894 cvs_set_dtx.hdr.token = 0;
895 cvs_set_dtx.hdr.opcode = VSS_ISTREAM_CMD_SET_ENC_DTX_MODE;
896 cvs_set_dtx.dtx_mode.enable = 0;
897
898 v->cvs_state = CMD_STATUS_FAIL;
899
900 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_dtx);
901 if (ret < 0) {
902 pr_err("%s: Error %d sending SET_DTX\n",
903 __func__, ret);
904 goto fail;
905 }
906 ret = wait_event_timeout(v->cvs_wait,
907 (v->cvs_state == CMD_STATUS_SUCCESS),
908 msecs_to_jiffies(TIMEOUT_MS));
909 if (!ret) {
910 pr_err("%s: wait_event timeout\n", __func__);
911 goto fail;
912 }
913 break;
914 }
915 default:
916 /* Do nothing. */
917 break;
918 }
919 return 0;
920
921fail:
922 return -EINVAL;
923}
924
925static int voice_send_start_voice_cmd(struct voice_data *v)
926{
927 struct apr_hdr mvm_start_voice_cmd;
928 int ret = 0;
929 void *apr_mvm;
930 u16 mvm_handle;
931
932 if (v == NULL) {
933 pr_err("%s: v is NULL\n", __func__);
934 return -EINVAL;
935 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700936 apr_mvm = common.apr_q6_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700937
938 if (!apr_mvm) {
939 pr_err("%s: apr_mvm is NULL.\n", __func__);
940 return -EINVAL;
941 }
942 mvm_handle = voice_get_mvm_handle(v);
943
944 mvm_start_voice_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
945 APR_HDR_LEN(APR_HDR_SIZE),
946 APR_PKT_VER);
947 mvm_start_voice_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
948 sizeof(mvm_start_voice_cmd) - APR_HDR_SIZE);
949 pr_debug("send mvm_start_voice_cmd pkt size = %d\n",
950 mvm_start_voice_cmd.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700951 mvm_start_voice_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700952 mvm_start_voice_cmd.dest_port = mvm_handle;
953 mvm_start_voice_cmd.token = 0;
954 mvm_start_voice_cmd.opcode = VSS_IMVM_CMD_START_VOICE;
955
956 v->mvm_state = CMD_STATUS_FAIL;
957 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_start_voice_cmd);
958 if (ret < 0) {
959 pr_err("Fail in sending VSS_IMVM_CMD_START_VOICE\n");
960 goto fail;
961 }
962 ret = wait_event_timeout(v->mvm_wait,
963 (v->mvm_state == CMD_STATUS_SUCCESS),
964 msecs_to_jiffies(TIMEOUT_MS));
965 if (!ret) {
966 pr_err("%s: wait_event timeout\n", __func__);
967 goto fail;
968 }
969 return 0;
970fail:
971 return -EINVAL;
972}
973
974static int voice_send_disable_vocproc_cmd(struct voice_data *v)
975{
976 struct apr_hdr cvp_disable_cmd;
977 int ret = 0;
978 void *apr_cvp;
979 u16 cvp_handle;
980
981 if (v == NULL) {
982 pr_err("%s: v is NULL\n", __func__);
983 return -EINVAL;
984 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700985 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700986
987 if (!apr_cvp) {
988 pr_err("%s: apr regist failed\n", __func__);
989 return -EINVAL;
990 }
991 cvp_handle = voice_get_cvp_handle(v);
992
993 /* disable vocproc and wait for respose */
994 cvp_disable_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
995 APR_HDR_LEN(APR_HDR_SIZE),
996 APR_PKT_VER);
997 cvp_disable_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
998 sizeof(cvp_disable_cmd) - APR_HDR_SIZE);
999 pr_debug("cvp_disable_cmd pkt size = %d, cvp_handle=%d\n",
1000 cvp_disable_cmd.pkt_size, cvp_handle);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001001 cvp_disable_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001002 cvp_disable_cmd.dest_port = cvp_handle;
1003 cvp_disable_cmd.token = 0;
1004 cvp_disable_cmd.opcode = VSS_IVOCPROC_CMD_DISABLE;
1005
1006 v->cvp_state = CMD_STATUS_FAIL;
1007 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_disable_cmd);
1008 if (ret < 0) {
1009 pr_err("Fail in sending VSS_IVOCPROC_CMD_DISABLE\n");
1010 goto fail;
1011 }
1012 ret = wait_event_timeout(v->cvp_wait,
1013 (v->cvp_state == CMD_STATUS_SUCCESS),
1014 msecs_to_jiffies(TIMEOUT_MS));
1015 if (!ret) {
1016 pr_err("%s: wait_event timeout\n", __func__);
1017 goto fail;
1018 }
1019
1020 return 0;
1021fail:
1022 return -EINVAL;
1023}
1024
1025static int voice_send_set_device_cmd(struct voice_data *v)
1026{
1027 struct cvp_set_device_cmd cvp_setdev_cmd;
1028 int ret = 0;
1029 void *apr_cvp;
1030 u16 cvp_handle;
1031
1032 if (v == NULL) {
1033 pr_err("%s: v is NULL\n", __func__);
1034 return -EINVAL;
1035 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001036 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001037
1038 if (!apr_cvp) {
1039 pr_err("%s: apr_cvp is NULL.\n", __func__);
1040 return -EINVAL;
1041 }
1042 cvp_handle = voice_get_cvp_handle(v);
1043
1044 /* set device and wait for response */
1045 cvp_setdev_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1046 APR_HDR_LEN(APR_HDR_SIZE),
1047 APR_PKT_VER);
1048 cvp_setdev_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1049 sizeof(cvp_setdev_cmd) - APR_HDR_SIZE);
1050 pr_debug(" send create cvp setdev, pkt size = %d\n",
1051 cvp_setdev_cmd.hdr.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001052 cvp_setdev_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001053 cvp_setdev_cmd.hdr.dest_port = cvp_handle;
1054 cvp_setdev_cmd.hdr.token = 0;
1055 cvp_setdev_cmd.hdr.opcode = VSS_IVOCPROC_CMD_SET_DEVICE;
1056
1057 /* Use default topology if invalid value in ACDB */
1058 cvp_setdev_cmd.cvp_set_device.tx_topology_id =
1059 get_voice_tx_topology();
1060 if (cvp_setdev_cmd.cvp_set_device.tx_topology_id == 0)
1061 cvp_setdev_cmd.cvp_set_device.tx_topology_id =
1062 VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
1063
1064 cvp_setdev_cmd.cvp_set_device.rx_topology_id =
1065 get_voice_rx_topology();
1066 if (cvp_setdev_cmd.cvp_set_device.rx_topology_id == 0)
1067 cvp_setdev_cmd.cvp_set_device.rx_topology_id =
1068 VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
1069 cvp_setdev_cmd.cvp_set_device.tx_port_id = v->dev_tx.port_id;
1070 cvp_setdev_cmd.cvp_set_device.rx_port_id = v->dev_rx.port_id;
1071 pr_debug("topology=%d , tx_port_id=%d, rx_port_id=%d\n",
1072 cvp_setdev_cmd.cvp_set_device.tx_topology_id,
1073 cvp_setdev_cmd.cvp_set_device.tx_port_id,
1074 cvp_setdev_cmd.cvp_set_device.rx_port_id);
1075
1076 v->cvp_state = CMD_STATUS_FAIL;
1077 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_setdev_cmd);
1078 if (ret < 0) {
1079 pr_err("Fail in sending VOCPROC_FULL_CONTROL_SESSION\n");
1080 goto fail;
1081 }
1082 pr_debug("wait for cvp create session event\n");
1083 ret = wait_event_timeout(v->cvp_wait,
1084 (v->cvp_state == CMD_STATUS_SUCCESS),
1085 msecs_to_jiffies(TIMEOUT_MS));
1086 if (!ret) {
1087 pr_err("%s: wait_event timeout\n", __func__);
1088 goto fail;
1089 }
1090
1091 return 0;
1092fail:
1093 return -EINVAL;
1094}
1095
1096static int voice_send_stop_voice_cmd(struct voice_data *v)
1097{
1098 struct apr_hdr mvm_stop_voice_cmd;
1099 int ret = 0;
1100 void *apr_mvm;
1101 u16 mvm_handle;
1102
1103 if (v == NULL) {
1104 pr_err("%s: v is NULL\n", __func__);
1105 return -EINVAL;
1106 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001107 apr_mvm = common.apr_q6_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001108
1109 if (!apr_mvm) {
1110 pr_err("%s: apr_mvm is NULL.\n", __func__);
1111 return -EINVAL;
1112 }
1113 mvm_handle = voice_get_mvm_handle(v);
1114
1115 mvm_stop_voice_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1116 APR_HDR_LEN(APR_HDR_SIZE),
1117 APR_PKT_VER);
1118 mvm_stop_voice_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1119 sizeof(mvm_stop_voice_cmd) - APR_HDR_SIZE);
1120 pr_debug("send mvm_stop_voice_cmd pkt size = %d\n",
1121 mvm_stop_voice_cmd.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001122 mvm_stop_voice_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001123 mvm_stop_voice_cmd.dest_port = mvm_handle;
1124 mvm_stop_voice_cmd.token = 0;
1125 mvm_stop_voice_cmd.opcode = VSS_IMVM_CMD_STOP_VOICE;
1126
1127 v->mvm_state = CMD_STATUS_FAIL;
1128 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_stop_voice_cmd);
1129 if (ret < 0) {
1130 pr_err("Fail in sending VSS_IMVM_CMD_STOP_VOICE\n");
1131 goto fail;
1132 }
1133 ret = wait_event_timeout(v->mvm_wait,
1134 (v->mvm_state == CMD_STATUS_SUCCESS),
1135 msecs_to_jiffies(TIMEOUT_MS));
1136 if (!ret) {
1137 pr_err("%s: wait_event timeout\n", __func__);
1138 goto fail;
1139 }
1140
1141 return 0;
1142fail:
1143 return -EINVAL;
1144}
1145
Helen Zeng29eb7442011-06-20 11:06:29 -07001146static int voice_send_cvs_register_cal_cmd(struct voice_data *v)
1147{
1148 struct cvs_register_cal_data_cmd cvs_reg_cal_cmd;
1149 struct acdb_cal_block cal_block;
1150 int ret = 0;
1151 void *apr_cvs;
1152 u16 cvs_handle;
1153
1154 /* get the cvs cal data */
1155 get_all_vocstrm_cal(&cal_block);
1156 if (cal_block.cal_size == 0)
1157 goto fail;
1158
1159 if (v == NULL) {
1160 pr_err("%s: v is NULL\n", __func__);
1161 return -EINVAL;
1162 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001163 apr_cvs = common.apr_q6_cvs;
Helen Zeng29eb7442011-06-20 11:06:29 -07001164
1165 if (!apr_cvs) {
1166 pr_err("%s: apr_cvs is NULL.\n", __func__);
1167 return -EINVAL;
1168 }
1169 cvs_handle = voice_get_cvs_handle(v);
1170
1171 /* fill in the header */
1172 cvs_reg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1173 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1174 cvs_reg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1175 sizeof(cvs_reg_cal_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001176 cvs_reg_cal_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001177 cvs_reg_cal_cmd.hdr.dest_port = cvs_handle;
1178 cvs_reg_cal_cmd.hdr.token = 0;
1179 cvs_reg_cal_cmd.hdr.opcode = VSS_ISTREAM_CMD_REGISTER_CALIBRATION_DATA;
1180
1181 cvs_reg_cal_cmd.cvs_cal_data.phys_addr = cal_block.cal_paddr;
1182 cvs_reg_cal_cmd.cvs_cal_data.mem_size = cal_block.cal_size;
1183
1184 v->cvs_state = CMD_STATUS_FAIL;
1185 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_reg_cal_cmd);
1186 if (ret < 0) {
1187 pr_err("Fail: sending cvs cal,\n");
1188 goto fail;
1189 }
1190 ret = wait_event_timeout(v->cvs_wait,
1191 (v->cvs_state == CMD_STATUS_SUCCESS),
1192 msecs_to_jiffies(TIMEOUT_MS));
1193 if (!ret) {
1194 pr_err("%s: wait_event timeout\n", __func__);
1195 goto fail;
1196 }
1197 return 0;
1198fail:
1199 return -EINVAL;
1200
1201}
1202
1203static int voice_send_cvs_deregister_cal_cmd(struct voice_data *v)
1204{
1205 struct cvs_deregister_cal_data_cmd cvs_dereg_cal_cmd;
1206 struct acdb_cal_block cal_block;
1207 int ret = 0;
1208 void *apr_cvs;
1209 u16 cvs_handle;
1210
1211 get_all_vocstrm_cal(&cal_block);
1212 if (cal_block.cal_size == 0)
1213 return 0;
1214
1215 if (v == NULL) {
1216 pr_err("%s: v is NULL\n", __func__);
1217 return -EINVAL;
1218 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001219 apr_cvs = common.apr_q6_cvs;
Helen Zeng29eb7442011-06-20 11:06:29 -07001220
1221 if (!apr_cvs) {
1222 pr_err("%s: apr_cvs is NULL.\n", __func__);
1223 return -EINVAL;
1224 }
1225 cvs_handle = voice_get_cvs_handle(v);
1226
1227 /* fill in the header */
1228 cvs_dereg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1229 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1230 cvs_dereg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1231 sizeof(cvs_dereg_cal_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001232 cvs_dereg_cal_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001233 cvs_dereg_cal_cmd.hdr.dest_port = cvs_handle;
1234 cvs_dereg_cal_cmd.hdr.token = 0;
1235 cvs_dereg_cal_cmd.hdr.opcode =
1236 VSS_ISTREAM_CMD_DEREGISTER_CALIBRATION_DATA;
1237
1238 v->cvs_state = CMD_STATUS_FAIL;
1239 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_dereg_cal_cmd);
1240 if (ret < 0) {
1241 pr_err("Fail: sending cvs cal,\n");
1242 goto fail;
1243 }
1244 ret = wait_event_timeout(v->cvs_wait,
1245 (v->cvs_state == CMD_STATUS_SUCCESS),
1246 msecs_to_jiffies(TIMEOUT_MS));
1247 if (!ret) {
1248 pr_err("%s: wait_event timeout\n", __func__);
1249 goto fail;
1250 }
1251 return 0;
1252fail:
1253 return -EINVAL;
1254
1255}
1256
1257static int voice_send_cvp_map_memory_cmd(struct voice_data *v)
1258{
1259 struct vss_map_memory_cmd cvp_map_mem_cmd;
1260 struct acdb_cal_block cal_block;
1261 int ret = 0;
1262 void *apr_cvp;
1263 u16 cvp_handle;
1264
1265 /* get all cvp cal data */
1266 get_all_cvp_cal(&cal_block);
1267 if (cal_block.cal_size == 0)
1268 goto fail;
1269
1270 if (v == NULL) {
1271 pr_err("%s: v is NULL\n", __func__);
1272 return -EINVAL;
1273 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001274 apr_cvp = common.apr_q6_cvp;
Helen Zeng29eb7442011-06-20 11:06:29 -07001275
1276 if (!apr_cvp) {
1277 pr_err("%s: apr_cvp is NULL.\n", __func__);
1278 return -EINVAL;
1279 }
1280 cvp_handle = voice_get_cvp_handle(v);
1281
1282 /* fill in the header */
1283 cvp_map_mem_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1284 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1285 cvp_map_mem_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1286 sizeof(cvp_map_mem_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001287 cvp_map_mem_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001288 cvp_map_mem_cmd.hdr.dest_port = cvp_handle;
1289 cvp_map_mem_cmd.hdr.token = 0;
1290 cvp_map_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_MAP_MEMORY;
1291
1292 pr_debug("%s, phy_addr:%d, mem_size:%d\n", __func__,
1293 cal_block.cal_paddr, cal_block.cal_size);
1294 cvp_map_mem_cmd.vss_map_mem.phys_addr = cal_block.cal_paddr;
1295 cvp_map_mem_cmd.vss_map_mem.mem_size = cal_block.cal_size;
1296 cvp_map_mem_cmd.vss_map_mem.mem_pool_id =
1297 VSS_ICOMMON_MAP_MEMORY_SHMEM8_4K_POOL;
1298
1299 v->cvp_state = CMD_STATUS_FAIL;
1300 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_map_mem_cmd);
1301 if (ret < 0) {
1302 pr_err("Fail: sending cvp cal,\n");
1303 goto fail;
1304 }
1305 ret = wait_event_timeout(v->cvp_wait,
1306 (v->cvp_state == CMD_STATUS_SUCCESS),
1307 msecs_to_jiffies(TIMEOUT_MS));
1308 if (!ret) {
1309 pr_err("%s: wait_event timeout\n", __func__);
1310 goto fail;
1311 }
1312 return 0;
1313fail:
1314 return -EINVAL;
1315
1316}
1317
1318static int voice_send_cvp_unmap_memory_cmd(struct voice_data *v)
1319{
1320 struct vss_unmap_memory_cmd cvp_unmap_mem_cmd;
1321 struct acdb_cal_block cal_block;
1322 int ret = 0;
1323 void *apr_cvp;
1324 u16 cvp_handle;
1325
1326 get_all_cvp_cal(&cal_block);
1327 if (cal_block.cal_size == 0)
1328 return 0;
1329
1330 if (v == NULL) {
1331 pr_err("%s: v is NULL\n", __func__);
1332 return -EINVAL;
1333 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001334 apr_cvp = common.apr_q6_cvp;
Helen Zeng29eb7442011-06-20 11:06:29 -07001335
1336 if (!apr_cvp) {
1337 pr_err("%s: apr_cvp is NULL.\n", __func__);
1338 return -EINVAL;
1339 }
1340 cvp_handle = voice_get_cvp_handle(v);
1341
1342 /* fill in the header */
1343 cvp_unmap_mem_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1344 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1345 cvp_unmap_mem_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1346 sizeof(cvp_unmap_mem_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001347 cvp_unmap_mem_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001348 cvp_unmap_mem_cmd.hdr.dest_port = cvp_handle;
1349 cvp_unmap_mem_cmd.hdr.token = 0;
1350 cvp_unmap_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_UNMAP_MEMORY;
1351
1352 cvp_unmap_mem_cmd.vss_unmap_mem.phys_addr = cal_block.cal_paddr;
1353
1354 v->cvp_state = CMD_STATUS_FAIL;
1355 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_unmap_mem_cmd);
1356 if (ret < 0) {
1357 pr_err("Fail: sending cvp cal,\n");
1358 goto fail;
1359 }
1360 ret = wait_event_timeout(v->cvp_wait,
1361 (v->cvp_state == CMD_STATUS_SUCCESS),
1362 msecs_to_jiffies(TIMEOUT_MS));
1363 if (!ret) {
1364 pr_err("%s: wait_event timeout\n", __func__);
1365 goto fail;
1366 }
1367 return 0;
1368fail:
1369 return -EINVAL;
1370
1371}
1372
1373static int voice_send_cvs_map_memory_cmd(struct voice_data *v)
1374{
1375 struct vss_map_memory_cmd cvs_map_mem_cmd;
1376 struct acdb_cal_block cal_block;
1377 int ret = 0;
1378 void *apr_cvs;
1379 u16 cvs_handle;
1380
1381 /* get all cvs cal data */
1382 get_all_vocstrm_cal(&cal_block);
1383 if (cal_block.cal_size == 0)
1384 goto fail;
1385
1386 if (v == NULL) {
1387 pr_err("%s: v is NULL\n", __func__);
1388 return -EINVAL;
1389 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001390 apr_cvs = common.apr_q6_cvs;
Helen Zeng29eb7442011-06-20 11:06:29 -07001391
1392 if (!apr_cvs) {
1393 pr_err("%s: apr_cvs is NULL.\n", __func__);
1394 return -EINVAL;
1395 }
1396 cvs_handle = voice_get_cvs_handle(v);
1397
1398 /* fill in the header */
1399 cvs_map_mem_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1400 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1401 cvs_map_mem_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1402 sizeof(cvs_map_mem_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001403 cvs_map_mem_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001404 cvs_map_mem_cmd.hdr.dest_port = cvs_handle;
1405 cvs_map_mem_cmd.hdr.token = 0;
1406 cvs_map_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_MAP_MEMORY;
1407
1408 pr_debug("%s, phys_addr: %d, mem_size: %d\n", __func__,
1409 cal_block.cal_paddr, cal_block.cal_size);
1410 cvs_map_mem_cmd.vss_map_mem.phys_addr = cal_block.cal_paddr;
1411 cvs_map_mem_cmd.vss_map_mem.mem_size = cal_block.cal_size;
1412 cvs_map_mem_cmd.vss_map_mem.mem_pool_id =
1413 VSS_ICOMMON_MAP_MEMORY_SHMEM8_4K_POOL;
1414
1415 v->cvs_state = CMD_STATUS_FAIL;
1416 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_map_mem_cmd);
1417 if (ret < 0) {
1418 pr_err("Fail: sending cvs cal,\n");
1419 goto fail;
1420 }
1421 ret = wait_event_timeout(v->cvs_wait,
1422 (v->cvs_state == CMD_STATUS_SUCCESS),
1423 msecs_to_jiffies(TIMEOUT_MS));
1424 if (!ret) {
1425 pr_err("%s: wait_event timeout\n", __func__);
1426 goto fail;
1427 }
1428 return 0;
1429fail:
1430 return -EINVAL;
1431
1432}
1433
1434static int voice_send_cvs_unmap_memory_cmd(struct voice_data *v)
1435{
1436 struct vss_unmap_memory_cmd cvs_unmap_mem_cmd;
1437 struct acdb_cal_block cal_block;
1438 int ret = 0;
1439 void *apr_cvs;
1440 u16 cvs_handle;
1441
1442 get_all_vocstrm_cal(&cal_block);
1443 if (cal_block.cal_size == 0)
1444 return 0;
1445
1446 if (v == NULL) {
1447 pr_err("%s: v is NULL\n", __func__);
1448 return -EINVAL;
1449 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001450 apr_cvs = common.apr_q6_cvs;
Helen Zeng29eb7442011-06-20 11:06:29 -07001451
1452 if (!apr_cvs) {
1453 pr_err("%s: apr_cvs is NULL.\n", __func__);
1454 return -EINVAL;
1455 }
1456 cvs_handle = voice_get_cvs_handle(v);
1457
1458 /* fill in the header */
1459 cvs_unmap_mem_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1460 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1461 cvs_unmap_mem_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1462 sizeof(cvs_unmap_mem_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001463 cvs_unmap_mem_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001464 cvs_unmap_mem_cmd.hdr.dest_port = cvs_handle;
1465 cvs_unmap_mem_cmd.hdr.token = 0;
1466 cvs_unmap_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_UNMAP_MEMORY;
1467
1468 cvs_unmap_mem_cmd.vss_unmap_mem.phys_addr = cal_block.cal_paddr;
1469
1470 v->cvs_state = CMD_STATUS_FAIL;
1471 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_unmap_mem_cmd);
1472 if (ret < 0) {
1473 pr_err("Fail: sending cvs cal,\n");
1474 goto fail;
1475 }
1476 ret = wait_event_timeout(v->cvs_wait,
1477 (v->cvs_state == CMD_STATUS_SUCCESS),
1478 msecs_to_jiffies(TIMEOUT_MS));
1479 if (!ret) {
1480 pr_err("%s: wait_event timeout\n", __func__);
1481 goto fail;
1482 }
1483 return 0;
1484fail:
1485 return -EINVAL;
1486
1487}
1488
1489static int voice_send_cvp_register_cal_cmd(struct voice_data *v)
1490{
1491 struct cvp_register_cal_data_cmd cvp_reg_cal_cmd;
1492 struct acdb_cal_block cal_block;
1493 int ret = 0;
1494 void *apr_cvp;
1495 u16 cvp_handle;
1496
1497 /* get the cvp cal data */
1498 get_all_vocproc_cal(&cal_block);
1499 if (cal_block.cal_size == 0)
1500 goto fail;
1501
1502 if (v == NULL) {
1503 pr_err("%s: v is NULL\n", __func__);
1504 return -EINVAL;
1505 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001506 apr_cvp = common.apr_q6_cvp;
Helen Zeng29eb7442011-06-20 11:06:29 -07001507
1508 if (!apr_cvp) {
1509 pr_err("%s: apr_cvp is NULL.\n", __func__);
1510 return -EINVAL;
1511 }
1512 cvp_handle = voice_get_cvp_handle(v);
1513
1514 /* fill in the header */
1515 cvp_reg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1516 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1517 cvp_reg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1518 sizeof(cvp_reg_cal_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001519 cvp_reg_cal_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001520 cvp_reg_cal_cmd.hdr.dest_port = cvp_handle;
1521 cvp_reg_cal_cmd.hdr.token = 0;
1522 cvp_reg_cal_cmd.hdr.opcode = VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA;
1523
1524 cvp_reg_cal_cmd.cvp_cal_data.phys_addr = cal_block.cal_paddr;
1525 cvp_reg_cal_cmd.cvp_cal_data.mem_size = cal_block.cal_size;
1526
1527 v->cvp_state = CMD_STATUS_FAIL;
1528 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_reg_cal_cmd);
1529 if (ret < 0) {
1530 pr_err("Fail: sending cvp cal,\n");
1531 goto fail;
1532 }
1533 ret = wait_event_timeout(v->cvp_wait,
1534 (v->cvp_state == CMD_STATUS_SUCCESS),
1535 msecs_to_jiffies(TIMEOUT_MS));
1536 if (!ret) {
1537 pr_err("%s: wait_event timeout\n", __func__);
1538 goto fail;
1539 }
1540 return 0;
1541fail:
1542 return -EINVAL;
1543
1544}
1545
1546static int voice_send_cvp_deregister_cal_cmd(struct voice_data *v)
1547{
1548 struct cvp_deregister_cal_data_cmd cvp_dereg_cal_cmd;
1549 struct acdb_cal_block cal_block;
1550 int ret = 0;
1551 void *apr_cvp;
1552 u16 cvp_handle;
1553
1554 get_all_vocproc_cal(&cal_block);
1555 if (cal_block.cal_size == 0)
1556 return 0;
1557
1558 if (v == NULL) {
1559 pr_err("%s: v is NULL\n", __func__);
1560 return -EINVAL;
1561 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001562 apr_cvp = common.apr_q6_cvp;
Helen Zeng29eb7442011-06-20 11:06:29 -07001563
1564 if (!apr_cvp) {
1565 pr_err("%s: apr_cvp is NULL.\n", __func__);
1566 return -EINVAL;
1567 }
1568 cvp_handle = voice_get_cvp_handle(v);
1569
1570 /* fill in the header */
1571 cvp_dereg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1572 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1573 cvp_dereg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1574 sizeof(cvp_dereg_cal_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001575 cvp_dereg_cal_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001576 cvp_dereg_cal_cmd.hdr.dest_port = cvp_handle;
1577 cvp_dereg_cal_cmd.hdr.token = 0;
1578 cvp_dereg_cal_cmd.hdr.opcode =
1579 VSS_IVOCPROC_CMD_DEREGISTER_CALIBRATION_DATA;
1580
1581 v->cvp_state = CMD_STATUS_FAIL;
1582 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_dereg_cal_cmd);
1583 if (ret < 0) {
1584 pr_err("Fail: sending cvp cal,\n");
1585 goto fail;
1586 }
1587 ret = wait_event_timeout(v->cvp_wait,
1588 (v->cvp_state == CMD_STATUS_SUCCESS),
1589 msecs_to_jiffies(TIMEOUT_MS));
1590 if (!ret) {
1591 pr_err("%s: wait_event timeout\n", __func__);
1592 goto fail;
1593 }
1594 return 0;
1595fail:
1596 return -EINVAL;
1597
1598}
1599
1600static int voice_send_cvp_register_vol_cal_table_cmd(struct voice_data *v)
1601{
1602 struct cvp_register_vol_cal_table_cmd cvp_reg_cal_tbl_cmd;
1603 struct acdb_cal_block cal_block;
1604 int ret = 0;
1605 void *apr_cvp;
1606 u16 cvp_handle;
1607
1608 /* get the cvp vol cal data */
1609 get_all_vocvol_cal(&cal_block);
1610 if (cal_block.cal_size == 0)
1611 goto fail;
1612
1613 if (v == NULL) {
1614 pr_err("%s: v is NULL\n", __func__);
1615 return -EINVAL;
1616 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001617 apr_cvp = common.apr_q6_cvp;
Helen Zeng29eb7442011-06-20 11:06:29 -07001618
1619 if (!apr_cvp) {
1620 pr_err("%s: apr_cvp is NULL.\n", __func__);
1621 return -EINVAL;
1622 }
1623 cvp_handle = voice_get_cvp_handle(v);
1624
1625 /* fill in the header */
1626 cvp_reg_cal_tbl_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1627 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1628 cvp_reg_cal_tbl_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1629 sizeof(cvp_reg_cal_tbl_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001630 cvp_reg_cal_tbl_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001631 cvp_reg_cal_tbl_cmd.hdr.dest_port = cvp_handle;
1632 cvp_reg_cal_tbl_cmd.hdr.token = 0;
1633 cvp_reg_cal_tbl_cmd.hdr.opcode =
1634 VSS_IVOCPROC_CMD_REGISTER_VOLUME_CAL_TABLE;
1635
1636 cvp_reg_cal_tbl_cmd.cvp_vol_cal_tbl.phys_addr = cal_block.cal_paddr;
1637 cvp_reg_cal_tbl_cmd.cvp_vol_cal_tbl.mem_size = cal_block.cal_size;
1638
1639 v->cvp_state = CMD_STATUS_FAIL;
1640 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_reg_cal_tbl_cmd);
1641 if (ret < 0) {
1642 pr_err("Fail: sending cvp cal table,\n");
1643 goto fail;
1644 }
1645 ret = wait_event_timeout(v->cvp_wait,
1646 (v->cvp_state == CMD_STATUS_SUCCESS),
1647 msecs_to_jiffies(TIMEOUT_MS));
1648 if (!ret) {
1649 pr_err("%s: wait_event timeout\n", __func__);
1650 goto fail;
1651 }
1652 return 0;
1653fail:
1654 return -EINVAL;
1655
1656}
1657
1658static int voice_send_cvp_deregister_vol_cal_table_cmd(struct voice_data *v)
1659{
1660 struct cvp_deregister_vol_cal_table_cmd cvp_dereg_cal_tbl_cmd;
1661 struct acdb_cal_block cal_block;
1662 int ret = 0;
1663 void *apr_cvp;
1664 u16 cvp_handle;
1665
1666 get_all_vocvol_cal(&cal_block);
1667 if (cal_block.cal_size == 0)
1668 return 0;
1669
1670 if (v == NULL) {
1671 pr_err("%s: v is NULL\n", __func__);
1672 return -EINVAL;
1673 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001674 apr_cvp = common.apr_q6_cvp;
Helen Zeng29eb7442011-06-20 11:06:29 -07001675
1676 if (!apr_cvp) {
1677 pr_err("%s: apr_cvp is NULL.\n", __func__);
1678 return -EINVAL;
1679 }
1680 cvp_handle = voice_get_cvp_handle(v);
1681
1682 /* fill in the header */
1683 cvp_dereg_cal_tbl_cmd.hdr.hdr_field = APR_HDR_FIELD(
1684 APR_MSG_TYPE_SEQ_CMD,
1685 APR_HDR_LEN(APR_HDR_SIZE),
1686 APR_PKT_VER);
1687 cvp_dereg_cal_tbl_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1688 sizeof(cvp_dereg_cal_tbl_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001689 cvp_dereg_cal_tbl_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001690 cvp_dereg_cal_tbl_cmd.hdr.dest_port = cvp_handle;
1691 cvp_dereg_cal_tbl_cmd.hdr.token = 0;
1692 cvp_dereg_cal_tbl_cmd.hdr.opcode =
1693 VSS_IVOCPROC_CMD_DEREGISTER_VOLUME_CAL_TABLE;
1694
1695 v->cvp_state = CMD_STATUS_FAIL;
1696 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_dereg_cal_tbl_cmd);
1697 if (ret < 0) {
1698 pr_err("Fail: sending cvp cal table,\n");
1699 goto fail;
1700 }
1701 ret = wait_event_timeout(v->cvp_wait,
1702 (v->cvp_state == CMD_STATUS_SUCCESS),
1703 msecs_to_jiffies(TIMEOUT_MS));
1704 if (!ret) {
1705 pr_err("%s: wait_event timeout\n", __func__);
1706 goto fail;
1707 }
1708 return 0;
1709fail:
1710 return -EINVAL;
1711
1712}
Neema Shetty2c07eb52011-08-21 20:33:52 -07001713
Helen Zeng44d4d272011-08-10 14:49:20 -07001714static int voice_send_set_widevoice_enable_cmd(struct voice_data *v)
1715{
1716 struct mvm_set_widevoice_enable_cmd mvm_set_wv_cmd;
1717 int ret = 0;
1718 void *apr_mvm;
1719 u16 mvm_handle;
1720
1721 if (v == NULL) {
1722 pr_err("%s: v is NULL\n", __func__);
1723 return -EINVAL;
1724 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001725 apr_mvm = common.apr_q6_mvm;
Helen Zeng44d4d272011-08-10 14:49:20 -07001726
1727 if (!apr_mvm) {
1728 pr_err("%s: apr_mvm is NULL.\n", __func__);
1729 return -EINVAL;
1730 }
1731 mvm_handle = voice_get_mvm_handle(v);
1732
1733 /* fill in the header */
1734 mvm_set_wv_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1735 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1736 mvm_set_wv_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1737 sizeof(mvm_set_wv_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001738 mvm_set_wv_cmd.hdr.src_port = v->session_id;
Helen Zeng44d4d272011-08-10 14:49:20 -07001739 mvm_set_wv_cmd.hdr.dest_port = mvm_handle;
1740 mvm_set_wv_cmd.hdr.token = 0;
1741 mvm_set_wv_cmd.hdr.opcode = VSS_IWIDEVOICE_CMD_SET_WIDEVOICE;
1742
1743 mvm_set_wv_cmd.vss_set_wv.enable = v->wv_enable;
1744
1745 v->mvm_state = CMD_STATUS_FAIL;
1746 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_wv_cmd);
1747 if (ret < 0) {
1748 pr_err("Fail: sending mvm set widevoice enable,\n");
1749 goto fail;
1750 }
1751 ret = wait_event_timeout(v->mvm_wait,
1752 (v->mvm_state == CMD_STATUS_SUCCESS),
1753 msecs_to_jiffies(TIMEOUT_MS));
1754 if (!ret) {
1755 pr_err("%s: wait_event timeout\n", __func__);
1756 goto fail;
1757 }
1758 return 0;
1759fail:
1760 return -EINVAL;
1761}
1762
Helen Zengbb49c702011-09-06 14:09:13 -07001763static int voice_send_set_slowtalk_enable_cmd(struct voice_data *v)
1764{
1765 struct cvs_set_slowtalk_enable_cmd cvs_set_st_cmd;
1766 int ret = 0;
1767 void *apr_cvs;
1768 u16 cvs_handle;
1769
1770 if (v == NULL) {
1771 pr_err("%s: v is NULL\n", __func__);
1772 return -EINVAL;
1773 }
1774 apr_cvs = common.apr_q6_cvs;
1775
1776 if (!apr_cvs) {
1777 pr_err("%s: apr_cvs is NULL.\n", __func__);
1778 return -EINVAL;
1779 }
1780 cvs_handle = voice_get_cvs_handle(v);
1781
1782 /* fill in the header */
1783 cvs_set_st_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1784 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1785 cvs_set_st_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1786 sizeof(cvs_set_st_cmd) - APR_HDR_SIZE);
1787 cvs_set_st_cmd.hdr.src_port = v->session_id;
1788 cvs_set_st_cmd.hdr.dest_port = cvs_handle;
1789 cvs_set_st_cmd.hdr.token = 0;
1790 cvs_set_st_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_UI_PROPERTY;
1791
1792 cvs_set_st_cmd.vss_set_st.module_id = MODULE_ID_VOICE_MODULE_ST;
1793 cvs_set_st_cmd.vss_set_st.param_id = VOICE_PARAM_MOD_ENABLE;
1794 cvs_set_st_cmd.vss_set_st.param_size = MOD_ENABLE_PARAM_LEN;
1795 cvs_set_st_cmd.vss_set_st.reserved = 0;
1796 cvs_set_st_cmd.vss_set_st.enable = v->st_enable;
1797 cvs_set_st_cmd.vss_set_st.reserved_field = 0;
1798
1799 v->cvs_state = CMD_STATUS_FAIL;
1800 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_st_cmd);
1801 if (ret < 0) {
1802 pr_err("Fail: sending cvs set slowtalk enable,\n");
1803 goto fail;
1804 }
1805 ret = wait_event_timeout(v->cvs_wait,
1806 (v->cvs_state == CMD_STATUS_SUCCESS),
1807 msecs_to_jiffies(TIMEOUT_MS));
1808 if (!ret) {
1809 pr_err("%s: wait_event timeout\n", __func__);
1810 goto fail;
1811 }
1812 return 0;
1813fail:
1814 return -EINVAL;
1815}
1816
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001817static int voice_setup_vocproc(struct voice_data *v)
1818{
1819 struct cvp_create_full_ctl_session_cmd cvp_session_cmd;
1820 int ret = 0;
1821 void *apr_cvp;
1822 if (v == NULL) {
1823 pr_err("%s: v is NULL\n", __func__);
1824 return -EINVAL;
1825 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001826 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001827
1828 if (!apr_cvp) {
1829 pr_err("%s: apr_cvp is NULL.\n", __func__);
1830 return -EINVAL;
1831 }
1832
1833 /* create cvp session and wait for response */
1834 cvp_session_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1835 APR_HDR_LEN(APR_HDR_SIZE),
1836 APR_PKT_VER);
1837 cvp_session_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1838 sizeof(cvp_session_cmd) - APR_HDR_SIZE);
1839 pr_debug(" send create cvp session, pkt size = %d\n",
1840 cvp_session_cmd.hdr.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001841 cvp_session_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001842 cvp_session_cmd.hdr.dest_port = 0;
1843 cvp_session_cmd.hdr.token = 0;
1844 cvp_session_cmd.hdr.opcode =
1845 VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION;
1846
1847 /* Use default topology if invalid value in ACDB */
1848 cvp_session_cmd.cvp_session.tx_topology_id =
1849 get_voice_tx_topology();
1850 if (cvp_session_cmd.cvp_session.tx_topology_id == 0)
1851 cvp_session_cmd.cvp_session.tx_topology_id =
1852 VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
1853
1854 cvp_session_cmd.cvp_session.rx_topology_id =
1855 get_voice_rx_topology();
1856 if (cvp_session_cmd.cvp_session.rx_topology_id == 0)
1857 cvp_session_cmd.cvp_session.rx_topology_id =
1858 VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
1859
1860 cvp_session_cmd.cvp_session.direction = 2; /*tx and rx*/
1861 cvp_session_cmd.cvp_session.network_id = VSS_NETWORK_ID_DEFAULT;
1862 cvp_session_cmd.cvp_session.tx_port_id = v->dev_tx.port_id;
1863 cvp_session_cmd.cvp_session.rx_port_id = v->dev_rx.port_id;
1864
1865 pr_debug("topology=%d net_id=%d, dir=%d tx_port_id=%d, rx_port_id=%d\n",
1866 cvp_session_cmd.cvp_session.tx_topology_id,
1867 cvp_session_cmd.cvp_session.network_id,
1868 cvp_session_cmd.cvp_session.direction,
1869 cvp_session_cmd.cvp_session.tx_port_id,
1870 cvp_session_cmd.cvp_session.rx_port_id);
1871
1872 v->cvp_state = CMD_STATUS_FAIL;
1873 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_session_cmd);
1874 if (ret < 0) {
1875 pr_err("Fail in sending VOCPROC_FULL_CONTROL_SESSION\n");
1876 goto fail;
1877 }
1878 ret = wait_event_timeout(v->cvp_wait,
1879 (v->cvp_state == CMD_STATUS_SUCCESS),
1880 msecs_to_jiffies(TIMEOUT_MS));
1881 if (!ret) {
1882 pr_err("%s: wait_event timeout\n", __func__);
1883 goto fail;
1884 }
1885
Helen Zeng29eb7442011-06-20 11:06:29 -07001886 /* send cvs cal */
1887 ret = voice_send_cvs_map_memory_cmd(v);
1888 if (!ret)
1889 voice_send_cvs_register_cal_cmd(v);
1890
1891 /* send cvp and vol cal */
1892 ret = voice_send_cvp_map_memory_cmd(v);
1893 if (!ret) {
1894 voice_send_cvp_register_cal_cmd(v);
1895 voice_send_cvp_register_vol_cal_table_cmd(v);
1896 }
1897
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001898 /* enable vocproc */
1899 ret = voice_send_enable_vocproc_cmd(v);
1900 if (ret < 0)
1901 goto fail;
1902
1903 /* attach vocproc */
1904 ret = voice_send_attach_vocproc_cmd(v);
1905 if (ret < 0)
1906 goto fail;
1907
1908 /* send tty mode if tty device is used */
1909 voice_send_tty_mode_cmd(v);
1910
Helen Zeng44d4d272011-08-10 14:49:20 -07001911 /* enable widevoice if wv_enable is set */
1912 if (v->wv_enable)
1913 voice_send_set_widevoice_enable_cmd(v);
1914
Helen Zengbb49c702011-09-06 14:09:13 -07001915 /* enable slowtalk if st_enable is set */
1916 if (v->st_enable)
1917 voice_send_set_slowtalk_enable_cmd(v);
1918
Neema Shetty2c07eb52011-08-21 20:33:52 -07001919 if (is_voip_session(v->session_id))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001920 voice_send_netid_timing_cmd(v);
1921
Ben Romberger13b74ab2011-07-18 17:36:32 -07001922 rtac_add_voice(voice_get_cvs_handle(v),
1923 voice_get_cvp_handle(v),
Ben Rombergerc5d6a372011-09-22 18:01:49 -07001924 v->dev_rx.port_id, v->dev_tx.port_id,
1925 v->session_id);
Ben Romberger13b74ab2011-07-18 17:36:32 -07001926
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001927 return 0;
1928
1929fail:
1930 return -EINVAL;
1931}
1932
1933static int voice_send_enable_vocproc_cmd(struct voice_data *v)
1934{
1935 int ret = 0;
1936 struct apr_hdr cvp_enable_cmd;
1937 void *apr_cvp;
1938 u16 cvp_handle;
1939
1940 if (v == NULL) {
1941 pr_err("%s: v is NULL\n", __func__);
1942 return -EINVAL;
1943 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001944 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001945
1946 if (!apr_cvp) {
1947 pr_err("%s: apr_cvp is NULL.\n", __func__);
1948 return -EINVAL;
1949 }
1950 cvp_handle = voice_get_cvp_handle(v);
1951
1952 /* enable vocproc and wait for respose */
1953 cvp_enable_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1954 APR_HDR_LEN(APR_HDR_SIZE),
1955 APR_PKT_VER);
1956 cvp_enable_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1957 sizeof(cvp_enable_cmd) - APR_HDR_SIZE);
1958 pr_debug("cvp_enable_cmd pkt size = %d, cvp_handle=%d\n",
1959 cvp_enable_cmd.pkt_size, cvp_handle);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001960 cvp_enable_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001961 cvp_enable_cmd.dest_port = cvp_handle;
1962 cvp_enable_cmd.token = 0;
1963 cvp_enable_cmd.opcode = VSS_IVOCPROC_CMD_ENABLE;
1964
1965 v->cvp_state = CMD_STATUS_FAIL;
1966 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_enable_cmd);
1967 if (ret < 0) {
1968 pr_err("Fail in sending VSS_IVOCPROC_CMD_ENABLE\n");
1969 goto fail;
1970 }
1971 ret = wait_event_timeout(v->cvp_wait,
1972 (v->cvp_state == CMD_STATUS_SUCCESS),
1973 msecs_to_jiffies(TIMEOUT_MS));
1974 if (!ret) {
1975 pr_err("%s: wait_event timeout\n", __func__);
1976 goto fail;
1977 }
1978
1979 return 0;
1980fail:
1981 return -EINVAL;
1982}
1983
1984static int voice_send_netid_timing_cmd(struct voice_data *v)
1985{
1986 int ret = 0;
1987 void *apr_mvm;
1988 u16 mvm_handle;
1989 struct mvm_set_network_cmd mvm_set_network;
1990 struct mvm_set_voice_timing_cmd mvm_set_voice_timing;
1991
1992 if (v == NULL) {
1993 pr_err("%s: v is NULL\n", __func__);
1994 return -EINVAL;
1995 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001996 apr_mvm = common.apr_q6_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001997
1998 if (!apr_mvm) {
1999 pr_err("%s: apr_mvm is NULL.\n", __func__);
2000 return -EINVAL;
2001 }
2002 mvm_handle = voice_get_mvm_handle(v);
2003
2004 ret = voice_config_cvs_vocoder(v);
2005 if (ret < 0) {
2006 pr_err("%s: Error %d configuring CVS voc",
2007 __func__, ret);
2008 goto fail;
2009 }
2010 /* Set network ID. */
2011 pr_debug("Setting network ID\n");
2012
2013 mvm_set_network.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2014 APR_HDR_LEN(APR_HDR_SIZE),
2015 APR_PKT_VER);
2016 mvm_set_network.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2017 sizeof(mvm_set_network) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002018 mvm_set_network.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002019 mvm_set_network.hdr.dest_port = mvm_handle;
2020 mvm_set_network.hdr.token = 0;
2021 mvm_set_network.hdr.opcode = VSS_ICOMMON_CMD_SET_NETWORK;
Neema Shetty2c07eb52011-08-21 20:33:52 -07002022 mvm_set_network.network.network_id = common.mvs_info.network_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002023
2024 v->mvm_state = CMD_STATUS_FAIL;
2025 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_network);
2026 if (ret < 0) {
2027 pr_err("%s: Error %d sending SET_NETWORK\n", __func__, ret);
2028 goto fail;
2029 }
2030
2031 ret = wait_event_timeout(v->mvm_wait,
2032 (v->mvm_state == CMD_STATUS_SUCCESS),
2033 msecs_to_jiffies(TIMEOUT_MS));
2034 if (!ret) {
2035 pr_err("%s: wait_event timeout\n", __func__);
2036 goto fail;
2037 }
2038
2039 /* Set voice timing. */
2040 pr_debug("Setting voice timing\n");
2041
2042 mvm_set_voice_timing.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2043 APR_HDR_LEN(APR_HDR_SIZE),
2044 APR_PKT_VER);
2045 mvm_set_voice_timing.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2046 sizeof(mvm_set_voice_timing) -
2047 APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002048 mvm_set_voice_timing.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002049 mvm_set_voice_timing.hdr.dest_port = mvm_handle;
2050 mvm_set_voice_timing.hdr.token = 0;
2051 mvm_set_voice_timing.hdr.opcode = VSS_ICOMMON_CMD_SET_VOICE_TIMING;
2052 mvm_set_voice_timing.timing.mode = 0;
2053 mvm_set_voice_timing.timing.enc_offset = 8000;
2054 mvm_set_voice_timing.timing.dec_req_offset = 3300;
2055 mvm_set_voice_timing.timing.dec_offset = 8300;
2056
2057 v->mvm_state = CMD_STATUS_FAIL;
2058
2059 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_voice_timing);
2060 if (ret < 0) {
2061 pr_err("%s: Error %d sending SET_TIMING\n", __func__, ret);
2062 goto fail;
2063 }
2064
2065 ret = wait_event_timeout(v->mvm_wait,
2066 (v->mvm_state == CMD_STATUS_SUCCESS),
2067 msecs_to_jiffies(TIMEOUT_MS));
2068 if (!ret) {
2069 pr_err("%s: wait_event timeout\n", __func__);
2070 goto fail;
2071 }
2072
2073 return 0;
2074fail:
2075 return -EINVAL;
2076}
2077
2078static int voice_send_attach_vocproc_cmd(struct voice_data *v)
2079{
2080 int ret = 0;
2081 struct mvm_attach_vocproc_cmd mvm_a_vocproc_cmd;
2082 void *apr_mvm;
2083 u16 mvm_handle, cvp_handle;
2084
2085 if (v == NULL) {
2086 pr_err("%s: v is NULL\n", __func__);
2087 return -EINVAL;
2088 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07002089 apr_mvm = common.apr_q6_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002090
2091 if (!apr_mvm) {
2092 pr_err("%s: apr_mvm is NULL.\n", __func__);
2093 return -EINVAL;
2094 }
2095 mvm_handle = voice_get_mvm_handle(v);
2096 cvp_handle = voice_get_cvp_handle(v);
2097
2098 /* attach vocproc and wait for response */
2099 mvm_a_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2100 APR_HDR_LEN(APR_HDR_SIZE),
2101 APR_PKT_VER);
2102 mvm_a_vocproc_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2103 sizeof(mvm_a_vocproc_cmd) - APR_HDR_SIZE);
2104 pr_debug("send mvm_a_vocproc_cmd pkt size = %d\n",
2105 mvm_a_vocproc_cmd.hdr.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002106 mvm_a_vocproc_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002107 mvm_a_vocproc_cmd.hdr.dest_port = mvm_handle;
2108 mvm_a_vocproc_cmd.hdr.token = 0;
Helen Zeng69b00962011-07-08 11:38:36 -07002109 mvm_a_vocproc_cmd.hdr.opcode = VSS_IMVM_CMD_ATTACH_VOCPROC;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002110 mvm_a_vocproc_cmd.mvm_attach_cvp_handle.handle = cvp_handle;
2111
2112 v->mvm_state = CMD_STATUS_FAIL;
2113 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_a_vocproc_cmd);
2114 if (ret < 0) {
Helen Zeng69b00962011-07-08 11:38:36 -07002115 pr_err("Fail in sending VSS_IMVM_CMD_ATTACH_VOCPROC\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002116 goto fail;
2117 }
2118 ret = wait_event_timeout(v->mvm_wait,
2119 (v->mvm_state == CMD_STATUS_SUCCESS),
2120 msecs_to_jiffies(TIMEOUT_MS));
2121 if (!ret) {
2122 pr_err("%s: wait_event timeout\n", __func__);
2123 goto fail;
2124 }
2125
2126 return 0;
2127fail:
2128 return -EINVAL;
2129}
2130
2131static int voice_destroy_vocproc(struct voice_data *v)
2132{
2133 struct mvm_detach_vocproc_cmd mvm_d_vocproc_cmd;
2134 struct apr_hdr cvp_destroy_session_cmd;
2135 int ret = 0;
2136 void *apr_mvm, *apr_cvp;
2137 u16 mvm_handle, cvp_handle;
2138
2139 if (v == NULL) {
2140 pr_err("%s: v is NULL\n", __func__);
2141 return -EINVAL;
2142 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07002143 apr_mvm = common.apr_q6_mvm;
2144 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002145
2146 if (!apr_mvm || !apr_cvp) {
2147 pr_err("%s: apr_mvm or apr_cvp is NULL.\n", __func__);
2148 return -EINVAL;
2149 }
2150 mvm_handle = voice_get_mvm_handle(v);
2151 cvp_handle = voice_get_cvp_handle(v);
2152
2153 /* send stop voice cmd */
2154 voice_send_stop_voice_cmd(v);
2155
2156 /* detach VOCPROC and wait for response from mvm */
2157 mvm_d_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2158 APR_HDR_LEN(APR_HDR_SIZE),
2159 APR_PKT_VER);
2160 mvm_d_vocproc_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2161 sizeof(mvm_d_vocproc_cmd) - APR_HDR_SIZE);
2162 pr_debug("mvm_d_vocproc_cmd pkt size = %d\n",
2163 mvm_d_vocproc_cmd.hdr.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002164 mvm_d_vocproc_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002165 mvm_d_vocproc_cmd.hdr.dest_port = mvm_handle;
2166 mvm_d_vocproc_cmd.hdr.token = 0;
Helen Zeng69b00962011-07-08 11:38:36 -07002167 mvm_d_vocproc_cmd.hdr.opcode = VSS_IMVM_CMD_DETACH_VOCPROC;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002168 mvm_d_vocproc_cmd.mvm_detach_cvp_handle.handle = cvp_handle;
2169
2170 v->mvm_state = CMD_STATUS_FAIL;
2171 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_d_vocproc_cmd);
2172 if (ret < 0) {
Helen Zeng69b00962011-07-08 11:38:36 -07002173 pr_err("Fail in sending VSS_IMVM_CMD_DETACH_VOCPROC\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002174 goto fail;
2175 }
2176 ret = wait_event_timeout(v->mvm_wait,
2177 (v->mvm_state == CMD_STATUS_SUCCESS),
2178 msecs_to_jiffies(TIMEOUT_MS));
2179 if (!ret) {
2180 pr_err("%s: wait_event timeout\n", __func__);
2181 goto fail;
2182 }
2183
Helen Zeng29eb7442011-06-20 11:06:29 -07002184 /* deregister cvp and vol cal */
2185 voice_send_cvp_deregister_vol_cal_table_cmd(v);
2186 voice_send_cvp_deregister_cal_cmd(v);
2187 voice_send_cvp_unmap_memory_cmd(v);
2188
2189 /* deregister cvs cal */
2190 voice_send_cvs_deregister_cal_cmd(v);
2191 voice_send_cvs_unmap_memory_cmd(v);
2192
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002193 /* destrop cvp session */
2194 cvp_destroy_session_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2195 APR_HDR_LEN(APR_HDR_SIZE),
2196 APR_PKT_VER);
2197 cvp_destroy_session_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2198 sizeof(cvp_destroy_session_cmd) - APR_HDR_SIZE);
2199 pr_debug("cvp_destroy_session_cmd pkt size = %d\n",
2200 cvp_destroy_session_cmd.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002201 cvp_destroy_session_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002202 cvp_destroy_session_cmd.dest_port = cvp_handle;
2203 cvp_destroy_session_cmd.token = 0;
2204 cvp_destroy_session_cmd.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
2205
2206 v->cvp_state = CMD_STATUS_FAIL;
2207 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_destroy_session_cmd);
2208 if (ret < 0) {
2209 pr_err("Fail in sending APRV2_IBASIC_CMD_DESTROY_SESSION\n");
2210 goto fail;
2211 }
2212 ret = wait_event_timeout(v->cvp_wait,
2213 (v->cvp_state == CMD_STATUS_SUCCESS),
2214 msecs_to_jiffies(TIMEOUT_MS));
2215 if (!ret) {
2216 pr_err("%s: wait_event timeout\n", __func__);
2217 goto fail;
2218 }
2219
Ben Romberger13b74ab2011-07-18 17:36:32 -07002220 rtac_remove_voice(voice_get_cvs_handle(v));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002221 cvp_handle = 0;
2222 voice_set_cvp_handle(v, cvp_handle);
2223
2224 return 0;
2225
2226fail:
2227 return -EINVAL;
2228}
2229
2230static int voice_send_mute_cmd(struct voice_data *v)
2231{
2232 struct cvs_set_mute_cmd cvs_mute_cmd;
2233 int ret = 0;
2234 void *apr_cvs;
2235 u16 cvs_handle;
2236
2237 if (v == NULL) {
2238 pr_err("%s: v is NULL\n", __func__);
2239 return -EINVAL;
2240 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07002241 apr_cvs = common.apr_q6_cvs;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002242
2243 if (!apr_cvs) {
2244 pr_err("%s: apr_cvs is NULL.\n", __func__);
2245 return -EINVAL;
2246 }
2247 cvs_handle = voice_get_cvs_handle(v);
2248
2249 /* send mute/unmute to cvs */
2250 cvs_mute_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2251 APR_HDR_LEN(APR_HDR_SIZE),
2252 APR_PKT_VER);
2253 cvs_mute_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2254 sizeof(cvs_mute_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002255 cvs_mute_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002256 cvs_mute_cmd.hdr.dest_port = cvs_handle;
2257 cvs_mute_cmd.hdr.token = 0;
2258 cvs_mute_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_MUTE;
2259 cvs_mute_cmd.cvs_set_mute.direction = 0; /*tx*/
2260 cvs_mute_cmd.cvs_set_mute.mute_flag = v->dev_tx.mute;
2261
2262 pr_info(" mute value =%d\n", cvs_mute_cmd.cvs_set_mute.mute_flag);
2263 v->cvs_state = CMD_STATUS_FAIL;
2264 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_mute_cmd);
2265 if (ret < 0) {
2266 pr_err("Fail: send STREAM SET MUTE\n");
2267 goto fail;
2268 }
2269 ret = wait_event_timeout(v->cvs_wait,
2270 (v->cvs_state == CMD_STATUS_SUCCESS),
2271 msecs_to_jiffies(TIMEOUT_MS));
2272 if (!ret)
2273 pr_err("%s: wait_event timeout\n", __func__);
2274
2275 return 0;
2276fail:
2277 return -EINVAL;
2278}
2279
2280static int voice_send_vol_index_cmd(struct voice_data *v)
2281{
2282 struct cvp_set_rx_volume_index_cmd cvp_vol_cmd;
2283 int ret = 0;
2284 void *apr_cvp;
2285 u16 cvp_handle;
2286 if (v == NULL) {
2287 pr_err("%s: v is NULL\n", __func__);
2288 return -EINVAL;
2289 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07002290 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002291
2292 if (!apr_cvp) {
2293 pr_err("%s: apr_cvp is NULL.\n", __func__);
2294 return -EINVAL;
2295 }
2296 cvp_handle = voice_get_cvp_handle(v);
2297
2298 /* send volume index to cvp */
2299 cvp_vol_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2300 APR_HDR_LEN(APR_HDR_SIZE),
2301 APR_PKT_VER);
2302 cvp_vol_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2303 sizeof(cvp_vol_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002304 cvp_vol_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002305 cvp_vol_cmd.hdr.dest_port = cvp_handle;
2306 cvp_vol_cmd.hdr.token = 0;
2307 cvp_vol_cmd.hdr.opcode = VSS_IVOCPROC_CMD_SET_RX_VOLUME_INDEX;
2308 cvp_vol_cmd.cvp_set_vol_idx.vol_index = v->dev_rx.volume;
2309 v->cvp_state = CMD_STATUS_FAIL;
2310 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_vol_cmd);
2311 if (ret < 0) {
2312 pr_err("Fail in sending RX VOL INDEX\n");
2313 return -EINVAL;
2314 }
2315 ret = wait_event_timeout(v->cvp_wait,
2316 (v->cvp_state == CMD_STATUS_SUCCESS),
2317 msecs_to_jiffies(TIMEOUT_MS));
2318 if (!ret) {
2319 pr_err("%s: wait_event timeout\n", __func__);
2320 return -EINVAL;
2321 }
2322 return 0;
2323}
2324
Neema Shetty2c07eb52011-08-21 20:33:52 -07002325int voc_disable_cvp(uint16_t session_id)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002326{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002327 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002328 int ret = 0;
2329
Neema Shetty2c07eb52011-08-21 20:33:52 -07002330 if (v == NULL) {
2331 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2332
2333 return -EINVAL;
2334 }
2335
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002336 mutex_lock(&v->lock);
2337
2338 if (v->voc_state == VOC_RUN) {
Laxminath Kasam5b9cf0f2011-12-09 15:24:20 +05302339 if (v->dev_tx.port_id != RT_PROXY_PORT_001_TX &&
2340 v->dev_rx.port_id != RT_PROXY_PORT_001_RX)
2341 afe_sidetone(v->dev_tx.port_id, v->dev_rx.port_id,
2342 0, 0);
Ben Romberger13b74ab2011-07-18 17:36:32 -07002343
2344 rtac_remove_voice(voice_get_cvs_handle(v));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002345 /* send cmd to dsp to disable vocproc */
2346 ret = voice_send_disable_vocproc_cmd(v);
2347 if (ret < 0) {
2348 pr_err("%s: disable vocproc failed\n", __func__);
2349 goto fail;
2350 }
Helen Zeng29eb7442011-06-20 11:06:29 -07002351
2352 /* deregister cvp and vol cal */
2353 voice_send_cvp_deregister_vol_cal_table_cmd(v);
2354 voice_send_cvp_deregister_cal_cmd(v);
2355 voice_send_cvp_unmap_memory_cmd(v);
2356
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002357 v->voc_state = VOC_CHANGE;
2358 }
2359
2360fail: mutex_unlock(&v->lock);
2361
2362 return ret;
2363}
2364
Neema Shetty2c07eb52011-08-21 20:33:52 -07002365int voc_enable_cvp(uint16_t session_id)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002366{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002367 struct voice_data *v = voice_get_session(session_id);
Helen Zengbd58e2c2011-07-01 16:24:31 -07002368 struct sidetone_cal sidetone_cal_data;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002369 int ret = 0;
2370
Neema Shetty2c07eb52011-08-21 20:33:52 -07002371 if (v == NULL) {
2372 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2373
2374 return -EINVAL;
2375 }
2376
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002377 mutex_lock(&v->lock);
2378
2379 if (v->voc_state == VOC_CHANGE) {
2380 ret = voice_send_set_device_cmd(v);
2381 if (ret < 0) {
2382 pr_err("%s: set device failed\n", __func__);
2383 goto fail;
2384 }
Helen Zeng29eb7442011-06-20 11:06:29 -07002385 /* send cvp and vol cal */
2386 ret = voice_send_cvp_map_memory_cmd(v);
2387 if (!ret) {
2388 voice_send_cvp_register_cal_cmd(v);
2389 voice_send_cvp_register_vol_cal_table_cmd(v);
2390 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002391 ret = voice_send_enable_vocproc_cmd(v);
2392 if (ret < 0) {
Neema Shetty2c07eb52011-08-21 20:33:52 -07002393 pr_err("%s: enable vocproc failed\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002394 goto fail;
Helen Zengcc65b5b2011-07-06 19:14:48 -07002395
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002396 }
Helen Zengcc65b5b2011-07-06 19:14:48 -07002397 /* send tty mode if tty device is used */
2398 voice_send_tty_mode_cmd(v);
2399
Helen Zeng44d4d272011-08-10 14:49:20 -07002400 /* enable widevoice if wv_enable is set */
2401 if (v->wv_enable)
2402 voice_send_set_widevoice_enable_cmd(v);
2403
Helen Zengbb49c702011-09-06 14:09:13 -07002404 /* enable slowtalk */
2405 if (v->st_enable)
2406 voice_send_set_slowtalk_enable_cmd(v);
2407
Helen Zengbd58e2c2011-07-01 16:24:31 -07002408 get_sidetone_cal(&sidetone_cal_data);
Laxminath Kasam5b9cf0f2011-12-09 15:24:20 +05302409 if (v->dev_tx.port_id != RT_PROXY_PORT_001_TX &&
2410 v->dev_rx.port_id != RT_PROXY_PORT_001_RX) {
2411 ret = afe_sidetone(v->dev_tx.port_id,
2412 v->dev_rx.port_id,
2413 sidetone_cal_data.enable,
2414 sidetone_cal_data.gain);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002415
Laxminath Kasam5b9cf0f2011-12-09 15:24:20 +05302416 if (ret < 0)
2417 pr_err("%s: AFE command sidetone failed\n",
2418 __func__);
2419 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002420
Ben Romberger13b74ab2011-07-18 17:36:32 -07002421 rtac_add_voice(voice_get_cvs_handle(v),
2422 voice_get_cvp_handle(v),
Ben Rombergerc5d6a372011-09-22 18:01:49 -07002423 v->dev_rx.port_id, v->dev_tx.port_id,
2424 v->session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002425 v->voc_state = VOC_RUN;
2426 }
2427
2428fail:
2429 mutex_unlock(&v->lock);
2430
2431 return ret;
2432}
2433
Neema Shetty2c07eb52011-08-21 20:33:52 -07002434int voc_set_tx_mute(uint16_t session_id, uint32_t dir, uint32_t mute)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002435{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002436 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002437 int ret = 0;
2438
Neema Shetty2c07eb52011-08-21 20:33:52 -07002439 if (v == NULL) {
2440 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2441
2442 return -EINVAL;
2443 }
2444
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002445 mutex_lock(&v->lock);
2446
2447 v->dev_tx.mute = mute;
2448
2449 if (v->voc_state == VOC_RUN)
2450 ret = voice_send_mute_cmd(v);
2451
2452 mutex_unlock(&v->lock);
2453
2454 return ret;
2455}
2456
Neema Shetty2c07eb52011-08-21 20:33:52 -07002457int voc_set_tty_mode(uint16_t session_id, uint8_t tty_mode)
Helen Zengcc65b5b2011-07-06 19:14:48 -07002458{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002459 struct voice_data *v = voice_get_session(session_id);
Helen Zengcc65b5b2011-07-06 19:14:48 -07002460 int ret = 0;
2461
Neema Shetty2c07eb52011-08-21 20:33:52 -07002462 if (v == NULL) {
2463 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2464
2465 return -EINVAL;
2466 }
2467
Helen Zengcc65b5b2011-07-06 19:14:48 -07002468 mutex_lock(&v->lock);
2469
2470 v->tty_mode = tty_mode;
2471
2472 mutex_unlock(&v->lock);
2473
2474 return ret;
2475}
2476
Neema Shetty2c07eb52011-08-21 20:33:52 -07002477uint8_t voc_get_tty_mode(uint16_t session_id)
Helen Zengcc65b5b2011-07-06 19:14:48 -07002478{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002479 struct voice_data *v = voice_get_session(session_id);
Helen Zengcc65b5b2011-07-06 19:14:48 -07002480 int ret = 0;
2481
Neema Shetty2c07eb52011-08-21 20:33:52 -07002482 if (v == NULL) {
2483 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2484
2485 return -EINVAL;
2486 }
2487
Helen Zengcc65b5b2011-07-06 19:14:48 -07002488 mutex_lock(&v->lock);
2489
2490 ret = v->tty_mode;
2491
2492 mutex_unlock(&v->lock);
2493
2494 return ret;
2495}
2496
Neema Shetty2c07eb52011-08-21 20:33:52 -07002497int voc_set_widevoice_enable(uint16_t session_id, uint32_t wv_enable)
Helen Zeng44d4d272011-08-10 14:49:20 -07002498{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002499 struct voice_data *v = voice_get_session(session_id);
Helen Zengb73acce2011-09-15 18:23:01 -07002500 u16 mvm_handle;
Helen Zeng44d4d272011-08-10 14:49:20 -07002501 int ret = 0;
2502
Neema Shetty2c07eb52011-08-21 20:33:52 -07002503 if (v == NULL) {
2504 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2505
2506 return -EINVAL;
2507 }
2508
Helen Zeng44d4d272011-08-10 14:49:20 -07002509 mutex_lock(&v->lock);
2510
2511 v->wv_enable = wv_enable;
2512
Helen Zengb73acce2011-09-15 18:23:01 -07002513 mvm_handle = voice_get_mvm_handle(v);
2514
2515 if (mvm_handle != 0)
2516 voice_send_set_widevoice_enable_cmd(v);
2517
Helen Zeng44d4d272011-08-10 14:49:20 -07002518 mutex_unlock(&v->lock);
2519
2520 return ret;
2521}
2522
Neema Shetty2c07eb52011-08-21 20:33:52 -07002523uint32_t voc_get_widevoice_enable(uint16_t session_id)
Helen Zeng44d4d272011-08-10 14:49:20 -07002524{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002525 struct voice_data *v = voice_get_session(session_id);
Helen Zeng44d4d272011-08-10 14:49:20 -07002526 int ret = 0;
2527
Neema Shetty2c07eb52011-08-21 20:33:52 -07002528 if (v == NULL) {
2529 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2530
2531 return -EINVAL;
2532 }
2533
Helen Zeng44d4d272011-08-10 14:49:20 -07002534 mutex_lock(&v->lock);
2535
2536 ret = v->wv_enable;
2537
2538 mutex_unlock(&v->lock);
2539
2540 return ret;
2541}
2542
Helen Zengbb49c702011-09-06 14:09:13 -07002543int voc_set_slowtalk_enable(uint16_t session_id, uint32_t st_enable)
2544{
2545 struct voice_data *v = voice_get_session(session_id);
2546 int ret = 0;
2547
2548 if (v == NULL) {
2549 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2550
2551 return -EINVAL;
2552 }
2553
2554 mutex_lock(&v->lock);
2555
2556 v->st_enable = st_enable;
2557
2558 if (v->voc_state == VOC_RUN)
2559 ret = voice_send_set_slowtalk_enable_cmd(v);
2560
2561 mutex_unlock(&v->lock);
2562
2563 return ret;
2564}
2565
2566uint32_t voc_get_slowtalk_enable(uint16_t session_id)
2567{
2568 struct voice_data *v = voice_get_session(session_id);
2569 int ret = 0;
2570
2571 if (v == NULL) {
2572 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2573
2574 return -EINVAL;
2575 }
2576
2577 mutex_lock(&v->lock);
2578
2579 ret = v->st_enable;
2580
2581 mutex_unlock(&v->lock);
2582
2583 return ret;
2584}
2585
Neema Shetty2c07eb52011-08-21 20:33:52 -07002586int voc_set_rx_vol_index(uint16_t session_id, uint32_t dir, uint32_t vol_idx)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002587{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002588 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002589 int ret = 0;
2590
Neema Shetty2c07eb52011-08-21 20:33:52 -07002591 if (v == NULL) {
2592 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2593
2594 return -EINVAL;
2595 }
2596
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002597 mutex_lock(&v->lock);
2598
2599 v->dev_rx.volume = vol_idx;
2600
2601 if (v->voc_state == VOC_RUN)
2602 ret = voice_send_vol_index_cmd(v);
2603
2604 mutex_unlock(&v->lock);
2605
2606 return ret;
2607}
2608
Neema Shetty2c07eb52011-08-21 20:33:52 -07002609int voc_set_rxtx_port(uint16_t session_id, uint32_t port_id, uint32_t dev_type)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002610{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002611 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002612
Neema Shetty2c07eb52011-08-21 20:33:52 -07002613 if (v == NULL) {
2614 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2615
2616 return -EINVAL;
2617 }
2618
2619 pr_debug("%s: port_id=%d, type=%d\n", __func__, port_id, dev_type);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002620
2621 mutex_lock(&v->lock);
2622
2623 if (dev_type == DEV_RX)
2624 v->dev_rx.port_id = port_id;
2625 else
2626 v->dev_tx.port_id = port_id;
2627
2628 mutex_unlock(&v->lock);
2629
Neema Shetty2c07eb52011-08-21 20:33:52 -07002630 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002631}
2632
Neema Shetty2c07eb52011-08-21 20:33:52 -07002633int voc_set_route_flag(uint16_t session_id, uint8_t path_dir, uint8_t set)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002634{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002635 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002636
Neema Shetty2c07eb52011-08-21 20:33:52 -07002637 if (v == NULL) {
2638 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2639
2640 return -EINVAL;
2641 }
2642
2643 pr_debug("%s: path_dir=%d, set=%d\n", __func__, path_dir, set);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002644
2645 mutex_lock(&v->lock);
2646
2647 if (path_dir == RX_PATH)
2648 v->voc_route_state.rx_route_flag = set;
2649 else
2650 v->voc_route_state.tx_route_flag = set;
2651
2652 mutex_unlock(&v->lock);
2653
Neema Shetty2c07eb52011-08-21 20:33:52 -07002654 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002655}
2656
Neema Shetty2c07eb52011-08-21 20:33:52 -07002657uint8_t voc_get_route_flag(uint16_t session_id, uint8_t path_dir)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002658{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002659 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002660 int ret = 0;
2661
Neema Shetty2c07eb52011-08-21 20:33:52 -07002662 if (v == NULL) {
2663 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2664
2665 return 0;
2666 }
2667
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002668 mutex_lock(&v->lock);
2669
2670 if (path_dir == RX_PATH)
2671 ret = v->voc_route_state.rx_route_flag;
2672 else
2673 ret = v->voc_route_state.tx_route_flag;
2674
2675 mutex_unlock(&v->lock);
2676
2677 return ret;
2678}
2679
Neema Shetty2c07eb52011-08-21 20:33:52 -07002680int voc_end_voice_call(uint16_t session_id)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002681{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002682 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002683 int ret = 0;
2684
Neema Shetty2c07eb52011-08-21 20:33:52 -07002685 if (v == NULL) {
2686 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2687
2688 return -EINVAL;
2689 }
2690
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002691 mutex_lock(&v->lock);
2692
2693 if (v->voc_state == VOC_RUN) {
Laxminath Kasam5b9cf0f2011-12-09 15:24:20 +05302694 if (v->dev_tx.port_id != RT_PROXY_PORT_001_TX &&
2695 v->dev_rx.port_id != RT_PROXY_PORT_001_RX)
2696 afe_sidetone(v->dev_tx.port_id, v->dev_rx.port_id,
2697 0, 0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002698 ret = voice_destroy_vocproc(v);
2699 if (ret < 0)
2700 pr_err("%s: destroy voice failed\n", __func__);
2701 voice_destroy_mvm_cvs_session(v);
2702
2703 v->voc_state = VOC_RELEASE;
2704 }
2705 mutex_unlock(&v->lock);
2706 return ret;
2707}
2708
Neema Shetty2c07eb52011-08-21 20:33:52 -07002709int voc_start_voice_call(uint16_t session_id)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002710{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002711 struct voice_data *v = voice_get_session(session_id);
Helen Zengbd58e2c2011-07-01 16:24:31 -07002712 struct sidetone_cal sidetone_cal_data;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002713 int ret = 0;
2714
Neema Shetty2c07eb52011-08-21 20:33:52 -07002715 if (v == NULL) {
2716 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2717
2718 return -EINVAL;
2719 }
2720
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002721 mutex_lock(&v->lock);
2722
2723 if ((v->voc_state == VOC_INIT) ||
2724 (v->voc_state == VOC_RELEASE)) {
Neema Shetty2c07eb52011-08-21 20:33:52 -07002725 ret = voice_apr_register();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002726 if (ret < 0) {
2727 pr_err("%s: apr register failed\n", __func__);
2728 goto fail;
2729 }
2730 ret = voice_create_mvm_cvs_session(v);
2731 if (ret < 0) {
2732 pr_err("create mvm and cvs failed\n");
2733 goto fail;
2734 }
2735 ret = voice_setup_vocproc(v);
2736 if (ret < 0) {
2737 pr_err("setup voice failed\n");
2738 goto fail;
2739 }
2740 ret = voice_send_start_voice_cmd(v);
2741 if (ret < 0) {
2742 pr_err("start voice failed\n");
2743 goto fail;
2744 }
Helen Zengbd58e2c2011-07-01 16:24:31 -07002745 get_sidetone_cal(&sidetone_cal_data);
Laxminath Kasam5b9cf0f2011-12-09 15:24:20 +05302746 if (v->dev_tx.port_id != RT_PROXY_PORT_001_TX &&
2747 v->dev_rx.port_id != RT_PROXY_PORT_001_RX) {
2748 ret = afe_sidetone(v->dev_tx.port_id,
Helen Zengbd58e2c2011-07-01 16:24:31 -07002749 v->dev_rx.port_id,
2750 sidetone_cal_data.enable,
2751 sidetone_cal_data.gain);
Laxminath Kasam5b9cf0f2011-12-09 15:24:20 +05302752 if (ret < 0)
2753 pr_err("AFE command sidetone failed\n");
2754 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002755
2756 v->voc_state = VOC_RUN;
2757 }
2758
2759fail: mutex_unlock(&v->lock);
2760 return ret;
2761}
2762
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002763void voc_register_mvs_cb(ul_cb_fn ul_cb,
2764 dl_cb_fn dl_cb,
2765 void *private_data)
2766{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002767 common.mvs_info.ul_cb = ul_cb;
2768 common.mvs_info.dl_cb = dl_cb;
2769 common.mvs_info.private_data = private_data;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002770}
2771
2772void voc_config_vocoder(uint32_t media_type,
2773 uint32_t rate,
2774 uint32_t network_type)
2775{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002776 common.mvs_info.media_type = media_type;
2777 common.mvs_info.rate = rate;
2778 common.mvs_info.network_type = network_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002779}
2780
2781static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv)
2782{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002783 uint32_t *ptr = NULL;
2784 struct common_data *c = NULL;
2785 struct voice_data *v = NULL;
Neema Shetty07477582011-09-02 17:35:44 -07002786 int i = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002787
2788 if ((data == NULL) || (priv == NULL)) {
2789 pr_err("%s: data or priv is NULL\n", __func__);
2790 return -EINVAL;
2791 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07002792
2793 c = priv;
2794
2795 pr_debug("%s: session_id 0x%x\n", __func__, data->dest_port);
2796
2797 v = voice_get_session(data->dest_port);
2798 if (v == NULL) {
2799 pr_err("%s: v is NULL\n", __func__);
2800
2801 return -EINVAL;
2802 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002803
2804 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
2805 data->payload_size, data->opcode);
2806
Neema Shetty07477582011-09-02 17:35:44 -07002807 if (data->opcode == RESET_EVENTS) {
2808 pr_debug("%s: Reset event received in Voice service\n",
2809 __func__);
2810
2811 apr_reset(c->apr_q6_mvm);
2812 c->apr_q6_mvm = NULL;
2813
2814 /* Sub-system restart is applicable to all sessions. */
2815 for (i = 0; i < MAX_VOC_SESSIONS; i++)
2816 c->voice[i].mvm_handle = 0;
2817
2818 return 0;
2819 }
2820
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002821 if (data->opcode == APR_BASIC_RSP_RESULT) {
2822 if (data->payload_size) {
2823 ptr = data->payload;
2824
2825 pr_info("%x %x\n", ptr[0], ptr[1]);
2826 /* ping mvm service ACK */
2827 switch (ptr[0]) {
2828 case VSS_IMVM_CMD_CREATE_PASSIVE_CONTROL_SESSION:
2829 case VSS_IMVM_CMD_CREATE_FULL_CONTROL_SESSION:
2830 /* Passive session is used for CS call
2831 * Full session is used for VoIP call. */
2832 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2833 if (!ptr[1]) {
2834 pr_debug("%s: MVM handle is %d\n",
2835 __func__, data->src_port);
2836 voice_set_mvm_handle(v, data->src_port);
2837 } else
2838 pr_err("got NACK for sending \
2839 MVM create session \n");
2840 v->mvm_state = CMD_STATUS_SUCCESS;
2841 wake_up(&v->mvm_wait);
2842 break;
2843 case VSS_IMVM_CMD_START_VOICE:
Helen Zeng69b00962011-07-08 11:38:36 -07002844 case VSS_IMVM_CMD_ATTACH_VOCPROC:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002845 case VSS_IMVM_CMD_STOP_VOICE:
Helen Zeng69b00962011-07-08 11:38:36 -07002846 case VSS_IMVM_CMD_DETACH_VOCPROC:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002847 case VSS_ISTREAM_CMD_SET_TTY_MODE:
2848 case APRV2_IBASIC_CMD_DESTROY_SESSION:
2849 case VSS_IMVM_CMD_ATTACH_STREAM:
2850 case VSS_IMVM_CMD_DETACH_STREAM:
2851 case VSS_ICOMMON_CMD_SET_NETWORK:
2852 case VSS_ICOMMON_CMD_SET_VOICE_TIMING:
Helen Zeng44d4d272011-08-10 14:49:20 -07002853 case VSS_IWIDEVOICE_CMD_SET_WIDEVOICE:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002854 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2855 v->mvm_state = CMD_STATUS_SUCCESS;
2856 wake_up(&v->mvm_wait);
2857 break;
2858 default:
2859 pr_debug("%s: not match cmd = 0x%x\n",
2860 __func__, ptr[0]);
2861 break;
2862 }
2863 }
2864 }
2865
2866 return 0;
2867}
2868
2869static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv)
2870{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002871 uint32_t *ptr = NULL;
2872 struct common_data *c = NULL;
2873 struct voice_data *v = NULL;
Neema Shetty07477582011-09-02 17:35:44 -07002874 int i = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002875
2876 if ((data == NULL) || (priv == NULL)) {
2877 pr_err("%s: data or priv is NULL\n", __func__);
2878 return -EINVAL;
2879 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07002880
2881 c = priv;
2882
2883 pr_debug("%s: session_id 0x%x\n", __func__, data->dest_port);
2884
2885 v = voice_get_session(data->dest_port);
2886 if (v == NULL) {
2887 pr_err("%s: v is NULL\n", __func__);
2888
2889 return -EINVAL;
2890 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002891
2892 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
2893 data->payload_size, data->opcode);
2894
Neema Shetty07477582011-09-02 17:35:44 -07002895 if (data->opcode == RESET_EVENTS) {
2896 pr_debug("%s: Reset event received in Voice service\n",
2897 __func__);
2898
2899 apr_reset(c->apr_q6_cvs);
2900 c->apr_q6_cvs = NULL;
2901
2902 /* Sub-system restart is applicable to all sessions. */
2903 for (i = 0; i < MAX_VOC_SESSIONS; i++)
2904 c->voice[i].cvs_handle = 0;
2905
2906 return 0;
2907 }
2908
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002909 if (data->opcode == APR_BASIC_RSP_RESULT) {
2910 if (data->payload_size) {
2911 ptr = data->payload;
2912
2913 pr_info("%x %x\n", ptr[0], ptr[1]);
2914 /*response from CVS */
2915 switch (ptr[0]) {
2916 case VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION:
2917 case VSS_ISTREAM_CMD_CREATE_FULL_CONTROL_SESSION:
2918 if (!ptr[1]) {
2919 pr_debug("%s: CVS handle is %d\n",
2920 __func__, data->src_port);
2921 voice_set_cvs_handle(v, data->src_port);
2922 } else
2923 pr_err("got NACK for sending \
2924 CVS create session \n");
2925 v->cvs_state = CMD_STATUS_SUCCESS;
2926 wake_up(&v->cvs_wait);
2927 break;
2928 case VSS_ISTREAM_CMD_SET_MUTE:
2929 case VSS_ISTREAM_CMD_SET_MEDIA_TYPE:
2930 case VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE:
2931 case VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE:
2932 case VSS_ISTREAM_CMD_SET_ENC_DTX_MODE:
2933 case VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE:
2934 case APRV2_IBASIC_CMD_DESTROY_SESSION:
Helen Zeng29eb7442011-06-20 11:06:29 -07002935 case VSS_ISTREAM_CMD_REGISTER_CALIBRATION_DATA:
2936 case VSS_ISTREAM_CMD_DEREGISTER_CALIBRATION_DATA:
2937 case VSS_ICOMMON_CMD_MAP_MEMORY:
2938 case VSS_ICOMMON_CMD_UNMAP_MEMORY:
Helen Zengbb49c702011-09-06 14:09:13 -07002939 case VSS_ICOMMON_CMD_SET_UI_PROPERTY:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002940 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2941 v->cvs_state = CMD_STATUS_SUCCESS;
2942 wake_up(&v->cvs_wait);
2943 break;
Ben Romberger13b74ab2011-07-18 17:36:32 -07002944 case VOICE_CMD_SET_PARAM:
2945 rtac_make_voice_callback(RTAC_CVS, ptr,
2946 data->payload_size);
2947 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002948 default:
2949 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2950 break;
2951 }
2952 }
2953 } else if (data->opcode == VSS_ISTREAM_EVT_SEND_ENC_BUFFER) {
2954 uint32_t *voc_pkt = data->payload;
2955 uint32_t pkt_len = data->payload_size;
2956
Neema Shetty2c07eb52011-08-21 20:33:52 -07002957 if (voc_pkt != NULL && c->mvs_info.ul_cb != NULL) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002958 pr_debug("%s: Media type is 0x%x\n",
2959 __func__, voc_pkt[0]);
2960
2961 /* Remove media ID from payload. */
2962 voc_pkt++;
2963 pkt_len = pkt_len - 4;
2964
Neema Shetty2c07eb52011-08-21 20:33:52 -07002965 c->mvs_info.ul_cb((uint8_t *)voc_pkt,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002966 pkt_len,
Neema Shetty2c07eb52011-08-21 20:33:52 -07002967 c->mvs_info.private_data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002968 } else
2969 pr_err("%s: voc_pkt is 0x%x ul_cb is 0x%x\n",
2970 __func__, (unsigned int)voc_pkt,
Neema Shetty2c07eb52011-08-21 20:33:52 -07002971 (unsigned int) c->mvs_info.ul_cb);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002972 } else if (data->opcode == VSS_ISTREAM_EVT_REQUEST_DEC_BUFFER) {
2973 struct cvs_send_dec_buf_cmd send_dec_buf;
2974 int ret = 0;
2975 uint32_t pkt_len = 0;
2976
Neema Shetty2c07eb52011-08-21 20:33:52 -07002977 if (c->mvs_info.dl_cb != NULL) {
2978 send_dec_buf.dec_buf.media_id = c->mvs_info.media_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002979
Neema Shetty2c07eb52011-08-21 20:33:52 -07002980 c->mvs_info.dl_cb(
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002981 (uint8_t *)&send_dec_buf.dec_buf.packet_data,
2982 &pkt_len,
Neema Shetty2c07eb52011-08-21 20:33:52 -07002983 c->mvs_info.private_data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002984
2985 send_dec_buf.hdr.hdr_field =
2986 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2987 APR_HDR_LEN(APR_HDR_SIZE),
2988 APR_PKT_VER);
2989 send_dec_buf.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2990 sizeof(send_dec_buf.dec_buf.media_id) + pkt_len);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002991 send_dec_buf.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002992 send_dec_buf.hdr.dest_port = voice_get_cvs_handle(v);
2993 send_dec_buf.hdr.token = 0;
2994 send_dec_buf.hdr.opcode =
2995 VSS_ISTREAM_EVT_SEND_DEC_BUFFER;
2996
Neema Shetty2c07eb52011-08-21 20:33:52 -07002997 ret = apr_send_pkt(c->apr_q6_cvs,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002998 (uint32_t *) &send_dec_buf);
2999 if (ret < 0) {
3000 pr_err("%s: Error %d sending DEC_BUF\n",
3001 __func__, ret);
3002 goto fail;
3003 }
3004 } else
3005 pr_debug("%s: dl_cb is NULL\n", __func__);
Ben Romberger13b74ab2011-07-18 17:36:32 -07003006 } else if (data->opcode == VSS_ISTREAM_EVT_SEND_DEC_BUFFER) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003007 pr_debug("Send dec buf resp\n");
Ben Romberger13b74ab2011-07-18 17:36:32 -07003008 } else if (data->opcode == VOICE_EVT_GET_PARAM_ACK) {
3009 rtac_make_voice_callback(RTAC_CVS, data->payload,
3010 data->payload_size);
3011 } else
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003012 pr_debug("Unknown opcode 0x%x\n", data->opcode);
3013
3014fail:
3015 return 0;
3016}
3017
3018static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv)
3019{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003020 uint32_t *ptr = NULL;
3021 struct common_data *c = NULL;
3022 struct voice_data *v = NULL;
Neema Shetty07477582011-09-02 17:35:44 -07003023 int i = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003024
3025 if ((data == NULL) || (priv == NULL)) {
3026 pr_err("%s: data or priv is NULL\n", __func__);
3027 return -EINVAL;
3028 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07003029
3030 c = priv;
3031
3032 v = voice_get_session(data->dest_port);
3033 if (v == NULL) {
3034 pr_err("%s: v is NULL\n", __func__);
3035
3036 return -EINVAL;
3037 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003038
3039 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
3040 data->payload_size, data->opcode);
3041
Neema Shetty07477582011-09-02 17:35:44 -07003042 if (data->opcode == RESET_EVENTS) {
3043 pr_debug("%s: Reset event received in Voice service\n",
3044 __func__);
3045
3046 apr_reset(c->apr_q6_cvp);
3047 c->apr_q6_cvp = NULL;
3048
3049 /* Sub-system restart is applicable to all sessions. */
3050 for (i = 0; i < MAX_VOC_SESSIONS; i++)
3051 c->voice[i].cvp_handle = 0;
3052
3053 return 0;
3054 }
3055
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003056 if (data->opcode == APR_BASIC_RSP_RESULT) {
3057 if (data->payload_size) {
3058 ptr = data->payload;
3059
3060 pr_info("%x %x\n", ptr[0], ptr[1]);
3061
3062 switch (ptr[0]) {
3063 case VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION:
3064 /*response from CVP */
3065 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
3066 if (!ptr[1]) {
3067 voice_set_cvp_handle(v, data->src_port);
3068 pr_debug("cvphdl=%d\n", data->src_port);
3069 } else
3070 pr_err("got NACK from CVP create \
3071 session response\n");
3072 v->cvp_state = CMD_STATUS_SUCCESS;
3073 wake_up(&v->cvp_wait);
3074 break;
3075 case VSS_IVOCPROC_CMD_SET_DEVICE:
3076 case VSS_IVOCPROC_CMD_SET_RX_VOLUME_INDEX:
3077 case VSS_IVOCPROC_CMD_ENABLE:
3078 case VSS_IVOCPROC_CMD_DISABLE:
3079 case APRV2_IBASIC_CMD_DESTROY_SESSION:
Helen Zeng29eb7442011-06-20 11:06:29 -07003080 case VSS_IVOCPROC_CMD_REGISTER_VOLUME_CAL_TABLE:
3081 case VSS_IVOCPROC_CMD_DEREGISTER_VOLUME_CAL_TABLE:
3082 case VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA:
3083 case VSS_IVOCPROC_CMD_DEREGISTER_CALIBRATION_DATA:
3084 case VSS_ICOMMON_CMD_MAP_MEMORY:
3085 case VSS_ICOMMON_CMD_UNMAP_MEMORY:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003086 v->cvp_state = CMD_STATUS_SUCCESS;
3087 wake_up(&v->cvp_wait);
3088 break;
Ben Romberger13b74ab2011-07-18 17:36:32 -07003089 case VOICE_CMD_SET_PARAM:
3090 rtac_make_voice_callback(RTAC_CVP, ptr,
3091 data->payload_size);
3092 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003093 default:
3094 pr_debug("%s: not match cmd = 0x%x\n",
3095 __func__, ptr[0]);
3096 break;
3097 }
3098 }
Ben Romberger13b74ab2011-07-18 17:36:32 -07003099 } else if (data->opcode == VOICE_EVT_GET_PARAM_ACK) {
3100 rtac_make_voice_callback(RTAC_CVP, data->payload,
3101 data->payload_size);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003102 }
3103 return 0;
3104}
3105
3106
3107static int __init voice_init(void)
3108{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003109 int rc = 0, i = 0;
3110
3111 memset(&common, 0, sizeof(struct common_data));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003112
3113 /* set default value */
Neema Shetty2c07eb52011-08-21 20:33:52 -07003114 common.default_mute_val = 1; /* default is mute */
3115 common.default_vol_val = 0;
3116 common.default_sample_val = 8000;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003117
3118 /* Initialize MVS info. */
Neema Shetty2c07eb52011-08-21 20:33:52 -07003119 common.mvs_info.network_type = VSS_NETWORK_ID_DEFAULT;
3120
3121 mutex_init(&common.common_lock);
3122
3123 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
3124 common.voice[i].session_id = SESSION_ID_BASE + i;
3125
3126 /* initialize dev_rx and dev_tx */
3127 common.voice[i].dev_rx.volume = common.default_vol_val;
3128 common.voice[i].dev_tx.mute = common.default_mute_val;
3129
3130 common.voice[i].dev_tx.port_id = 1;
3131 common.voice[i].dev_rx.port_id = 0;
3132 common.voice[i].sidetone_gain = 0x512;
3133
3134 common.voice[i].voc_state = VOC_INIT;
3135
3136 init_waitqueue_head(&common.voice[i].mvm_wait);
3137 init_waitqueue_head(&common.voice[i].cvs_wait);
3138 init_waitqueue_head(&common.voice[i].cvp_wait);
3139
3140 mutex_init(&common.voice[i].lock);
3141 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003142
3143 return rc;
3144}
3145
3146device_initcall(voice_init);