blob: 965211de3ca4ba582e74510c7fc35981d0bea2d6 [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) {
2339 afe_sidetone(v->dev_tx.port_id, v->dev_rx.port_id, 0, 0);
Ben Romberger13b74ab2011-07-18 17:36:32 -07002340
2341 rtac_remove_voice(voice_get_cvs_handle(v));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002342 /* send cmd to dsp to disable vocproc */
2343 ret = voice_send_disable_vocproc_cmd(v);
2344 if (ret < 0) {
2345 pr_err("%s: disable vocproc failed\n", __func__);
2346 goto fail;
2347 }
Helen Zeng29eb7442011-06-20 11:06:29 -07002348
2349 /* deregister cvp and vol cal */
2350 voice_send_cvp_deregister_vol_cal_table_cmd(v);
2351 voice_send_cvp_deregister_cal_cmd(v);
2352 voice_send_cvp_unmap_memory_cmd(v);
2353
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002354 v->voc_state = VOC_CHANGE;
2355 }
2356
2357fail: mutex_unlock(&v->lock);
2358
2359 return ret;
2360}
2361
Neema Shetty2c07eb52011-08-21 20:33:52 -07002362int voc_enable_cvp(uint16_t session_id)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002363{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002364 struct voice_data *v = voice_get_session(session_id);
Helen Zengbd58e2c2011-07-01 16:24:31 -07002365 struct sidetone_cal sidetone_cal_data;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002366 int ret = 0;
2367
Neema Shetty2c07eb52011-08-21 20:33:52 -07002368 if (v == NULL) {
2369 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2370
2371 return -EINVAL;
2372 }
2373
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002374 mutex_lock(&v->lock);
2375
2376 if (v->voc_state == VOC_CHANGE) {
2377 ret = voice_send_set_device_cmd(v);
2378 if (ret < 0) {
2379 pr_err("%s: set device failed\n", __func__);
2380 goto fail;
2381 }
Helen Zeng29eb7442011-06-20 11:06:29 -07002382 /* send cvp and vol cal */
2383 ret = voice_send_cvp_map_memory_cmd(v);
2384 if (!ret) {
2385 voice_send_cvp_register_cal_cmd(v);
2386 voice_send_cvp_register_vol_cal_table_cmd(v);
2387 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002388 ret = voice_send_enable_vocproc_cmd(v);
2389 if (ret < 0) {
Neema Shetty2c07eb52011-08-21 20:33:52 -07002390 pr_err("%s: enable vocproc failed\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002391 goto fail;
Helen Zengcc65b5b2011-07-06 19:14:48 -07002392
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002393 }
Helen Zengcc65b5b2011-07-06 19:14:48 -07002394 /* send tty mode if tty device is used */
2395 voice_send_tty_mode_cmd(v);
2396
Helen Zeng44d4d272011-08-10 14:49:20 -07002397 /* enable widevoice if wv_enable is set */
2398 if (v->wv_enable)
2399 voice_send_set_widevoice_enable_cmd(v);
2400
Helen Zengbb49c702011-09-06 14:09:13 -07002401 /* enable slowtalk */
2402 if (v->st_enable)
2403 voice_send_set_slowtalk_enable_cmd(v);
2404
Helen Zengbd58e2c2011-07-01 16:24:31 -07002405 get_sidetone_cal(&sidetone_cal_data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002406 ret = afe_sidetone(v->dev_tx.port_id, v->dev_rx.port_id,
Helen Zengbd58e2c2011-07-01 16:24:31 -07002407 sidetone_cal_data.enable,
2408 sidetone_cal_data.gain);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002409
2410 if (ret < 0)
Neema Shetty2c07eb52011-08-21 20:33:52 -07002411 pr_err("%s: AFE command sidetone failed\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002412
Ben Romberger13b74ab2011-07-18 17:36:32 -07002413 rtac_add_voice(voice_get_cvs_handle(v),
2414 voice_get_cvp_handle(v),
Ben Rombergerc5d6a372011-09-22 18:01:49 -07002415 v->dev_rx.port_id, v->dev_tx.port_id,
2416 v->session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002417 v->voc_state = VOC_RUN;
2418 }
2419
2420fail:
2421 mutex_unlock(&v->lock);
2422
2423 return ret;
2424}
2425
Neema Shetty2c07eb52011-08-21 20:33:52 -07002426int voc_set_tx_mute(uint16_t session_id, uint32_t dir, uint32_t mute)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002427{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002428 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002429 int ret = 0;
2430
Neema Shetty2c07eb52011-08-21 20:33:52 -07002431 if (v == NULL) {
2432 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2433
2434 return -EINVAL;
2435 }
2436
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002437 mutex_lock(&v->lock);
2438
2439 v->dev_tx.mute = mute;
2440
2441 if (v->voc_state == VOC_RUN)
2442 ret = voice_send_mute_cmd(v);
2443
2444 mutex_unlock(&v->lock);
2445
2446 return ret;
2447}
2448
Neema Shetty2c07eb52011-08-21 20:33:52 -07002449int voc_set_tty_mode(uint16_t session_id, uint8_t tty_mode)
Helen Zengcc65b5b2011-07-06 19:14:48 -07002450{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002451 struct voice_data *v = voice_get_session(session_id);
Helen Zengcc65b5b2011-07-06 19:14:48 -07002452 int ret = 0;
2453
Neema Shetty2c07eb52011-08-21 20:33:52 -07002454 if (v == NULL) {
2455 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2456
2457 return -EINVAL;
2458 }
2459
Helen Zengcc65b5b2011-07-06 19:14:48 -07002460 mutex_lock(&v->lock);
2461
2462 v->tty_mode = tty_mode;
2463
2464 mutex_unlock(&v->lock);
2465
2466 return ret;
2467}
2468
Neema Shetty2c07eb52011-08-21 20:33:52 -07002469uint8_t voc_get_tty_mode(uint16_t session_id)
Helen Zengcc65b5b2011-07-06 19:14:48 -07002470{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002471 struct voice_data *v = voice_get_session(session_id);
Helen Zengcc65b5b2011-07-06 19:14:48 -07002472 int ret = 0;
2473
Neema Shetty2c07eb52011-08-21 20:33:52 -07002474 if (v == NULL) {
2475 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2476
2477 return -EINVAL;
2478 }
2479
Helen Zengcc65b5b2011-07-06 19:14:48 -07002480 mutex_lock(&v->lock);
2481
2482 ret = v->tty_mode;
2483
2484 mutex_unlock(&v->lock);
2485
2486 return ret;
2487}
2488
Neema Shetty2c07eb52011-08-21 20:33:52 -07002489int voc_set_widevoice_enable(uint16_t session_id, uint32_t wv_enable)
Helen Zeng44d4d272011-08-10 14:49:20 -07002490{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002491 struct voice_data *v = voice_get_session(session_id);
Helen Zengb73acce2011-09-15 18:23:01 -07002492 u16 mvm_handle;
Helen Zeng44d4d272011-08-10 14:49:20 -07002493 int ret = 0;
2494
Neema Shetty2c07eb52011-08-21 20:33:52 -07002495 if (v == NULL) {
2496 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2497
2498 return -EINVAL;
2499 }
2500
Helen Zeng44d4d272011-08-10 14:49:20 -07002501 mutex_lock(&v->lock);
2502
2503 v->wv_enable = wv_enable;
2504
Helen Zengb73acce2011-09-15 18:23:01 -07002505 mvm_handle = voice_get_mvm_handle(v);
2506
2507 if (mvm_handle != 0)
2508 voice_send_set_widevoice_enable_cmd(v);
2509
Helen Zeng44d4d272011-08-10 14:49:20 -07002510 mutex_unlock(&v->lock);
2511
2512 return ret;
2513}
2514
Neema Shetty2c07eb52011-08-21 20:33:52 -07002515uint32_t voc_get_widevoice_enable(uint16_t session_id)
Helen Zeng44d4d272011-08-10 14:49:20 -07002516{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002517 struct voice_data *v = voice_get_session(session_id);
Helen Zeng44d4d272011-08-10 14:49:20 -07002518 int ret = 0;
2519
Neema Shetty2c07eb52011-08-21 20:33:52 -07002520 if (v == NULL) {
2521 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2522
2523 return -EINVAL;
2524 }
2525
Helen Zeng44d4d272011-08-10 14:49:20 -07002526 mutex_lock(&v->lock);
2527
2528 ret = v->wv_enable;
2529
2530 mutex_unlock(&v->lock);
2531
2532 return ret;
2533}
2534
Helen Zengbb49c702011-09-06 14:09:13 -07002535int voc_set_slowtalk_enable(uint16_t session_id, uint32_t st_enable)
2536{
2537 struct voice_data *v = voice_get_session(session_id);
2538 int ret = 0;
2539
2540 if (v == NULL) {
2541 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2542
2543 return -EINVAL;
2544 }
2545
2546 mutex_lock(&v->lock);
2547
2548 v->st_enable = st_enable;
2549
2550 if (v->voc_state == VOC_RUN)
2551 ret = voice_send_set_slowtalk_enable_cmd(v);
2552
2553 mutex_unlock(&v->lock);
2554
2555 return ret;
2556}
2557
2558uint32_t voc_get_slowtalk_enable(uint16_t session_id)
2559{
2560 struct voice_data *v = voice_get_session(session_id);
2561 int ret = 0;
2562
2563 if (v == NULL) {
2564 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2565
2566 return -EINVAL;
2567 }
2568
2569 mutex_lock(&v->lock);
2570
2571 ret = v->st_enable;
2572
2573 mutex_unlock(&v->lock);
2574
2575 return ret;
2576}
2577
Neema Shetty2c07eb52011-08-21 20:33:52 -07002578int voc_set_rx_vol_index(uint16_t session_id, uint32_t dir, uint32_t vol_idx)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002579{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002580 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002581 int ret = 0;
2582
Neema Shetty2c07eb52011-08-21 20:33:52 -07002583 if (v == NULL) {
2584 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2585
2586 return -EINVAL;
2587 }
2588
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002589 mutex_lock(&v->lock);
2590
2591 v->dev_rx.volume = vol_idx;
2592
2593 if (v->voc_state == VOC_RUN)
2594 ret = voice_send_vol_index_cmd(v);
2595
2596 mutex_unlock(&v->lock);
2597
2598 return ret;
2599}
2600
Neema Shetty2c07eb52011-08-21 20:33:52 -07002601int voc_set_rxtx_port(uint16_t session_id, uint32_t port_id, uint32_t dev_type)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002602{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002603 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002604
Neema Shetty2c07eb52011-08-21 20:33:52 -07002605 if (v == NULL) {
2606 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2607
2608 return -EINVAL;
2609 }
2610
2611 pr_debug("%s: port_id=%d, type=%d\n", __func__, port_id, dev_type);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002612
2613 mutex_lock(&v->lock);
2614
2615 if (dev_type == DEV_RX)
2616 v->dev_rx.port_id = port_id;
2617 else
2618 v->dev_tx.port_id = port_id;
2619
2620 mutex_unlock(&v->lock);
2621
Neema Shetty2c07eb52011-08-21 20:33:52 -07002622 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002623}
2624
Neema Shetty2c07eb52011-08-21 20:33:52 -07002625int voc_set_route_flag(uint16_t session_id, uint8_t path_dir, uint8_t set)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002626{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002627 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002628
Neema Shetty2c07eb52011-08-21 20:33:52 -07002629 if (v == NULL) {
2630 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2631
2632 return -EINVAL;
2633 }
2634
2635 pr_debug("%s: path_dir=%d, set=%d\n", __func__, path_dir, set);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002636
2637 mutex_lock(&v->lock);
2638
2639 if (path_dir == RX_PATH)
2640 v->voc_route_state.rx_route_flag = set;
2641 else
2642 v->voc_route_state.tx_route_flag = set;
2643
2644 mutex_unlock(&v->lock);
2645
Neema Shetty2c07eb52011-08-21 20:33:52 -07002646 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002647}
2648
Neema Shetty2c07eb52011-08-21 20:33:52 -07002649uint8_t voc_get_route_flag(uint16_t session_id, uint8_t path_dir)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002650{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002651 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002652 int ret = 0;
2653
Neema Shetty2c07eb52011-08-21 20:33:52 -07002654 if (v == NULL) {
2655 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2656
2657 return 0;
2658 }
2659
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002660 mutex_lock(&v->lock);
2661
2662 if (path_dir == RX_PATH)
2663 ret = v->voc_route_state.rx_route_flag;
2664 else
2665 ret = v->voc_route_state.tx_route_flag;
2666
2667 mutex_unlock(&v->lock);
2668
2669 return ret;
2670}
2671
Neema Shetty2c07eb52011-08-21 20:33:52 -07002672int voc_end_voice_call(uint16_t session_id)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002673{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002674 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002675 int ret = 0;
2676
Neema Shetty2c07eb52011-08-21 20:33:52 -07002677 if (v == NULL) {
2678 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2679
2680 return -EINVAL;
2681 }
2682
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002683 mutex_lock(&v->lock);
2684
2685 if (v->voc_state == VOC_RUN) {
Helen Zengbd58e2c2011-07-01 16:24:31 -07002686 afe_sidetone(v->dev_tx.port_id, v->dev_rx.port_id, 0, 0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002687 ret = voice_destroy_vocproc(v);
2688 if (ret < 0)
2689 pr_err("%s: destroy voice failed\n", __func__);
2690 voice_destroy_mvm_cvs_session(v);
2691
2692 v->voc_state = VOC_RELEASE;
2693 }
2694 mutex_unlock(&v->lock);
2695 return ret;
2696}
2697
Neema Shetty2c07eb52011-08-21 20:33:52 -07002698int voc_start_voice_call(uint16_t session_id)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002699{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002700 struct voice_data *v = voice_get_session(session_id);
Helen Zengbd58e2c2011-07-01 16:24:31 -07002701 struct sidetone_cal sidetone_cal_data;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002702 int ret = 0;
2703
Neema Shetty2c07eb52011-08-21 20:33:52 -07002704 if (v == NULL) {
2705 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2706
2707 return -EINVAL;
2708 }
2709
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002710 mutex_lock(&v->lock);
2711
2712 if ((v->voc_state == VOC_INIT) ||
2713 (v->voc_state == VOC_RELEASE)) {
Neema Shetty2c07eb52011-08-21 20:33:52 -07002714 ret = voice_apr_register();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002715 if (ret < 0) {
2716 pr_err("%s: apr register failed\n", __func__);
2717 goto fail;
2718 }
2719 ret = voice_create_mvm_cvs_session(v);
2720 if (ret < 0) {
2721 pr_err("create mvm and cvs failed\n");
2722 goto fail;
2723 }
2724 ret = voice_setup_vocproc(v);
2725 if (ret < 0) {
2726 pr_err("setup voice failed\n");
2727 goto fail;
2728 }
2729 ret = voice_send_start_voice_cmd(v);
2730 if (ret < 0) {
2731 pr_err("start voice failed\n");
2732 goto fail;
2733 }
Helen Zengbd58e2c2011-07-01 16:24:31 -07002734 get_sidetone_cal(&sidetone_cal_data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002735 ret = afe_sidetone(v->dev_tx.port_id,
Helen Zengbd58e2c2011-07-01 16:24:31 -07002736 v->dev_rx.port_id,
2737 sidetone_cal_data.enable,
2738 sidetone_cal_data.gain);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002739 if (ret < 0)
2740 pr_err("AFE command sidetone failed\n");
2741
2742 v->voc_state = VOC_RUN;
2743 }
2744
2745fail: mutex_unlock(&v->lock);
2746 return ret;
2747}
2748
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002749void voc_register_mvs_cb(ul_cb_fn ul_cb,
2750 dl_cb_fn dl_cb,
2751 void *private_data)
2752{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002753 common.mvs_info.ul_cb = ul_cb;
2754 common.mvs_info.dl_cb = dl_cb;
2755 common.mvs_info.private_data = private_data;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002756}
2757
2758void voc_config_vocoder(uint32_t media_type,
2759 uint32_t rate,
2760 uint32_t network_type)
2761{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002762 common.mvs_info.media_type = media_type;
2763 common.mvs_info.rate = rate;
2764 common.mvs_info.network_type = network_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002765}
2766
2767static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv)
2768{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002769 uint32_t *ptr = NULL;
2770 struct common_data *c = NULL;
2771 struct voice_data *v = NULL;
Neema Shetty07477582011-09-02 17:35:44 -07002772 int i = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002773
2774 if ((data == NULL) || (priv == NULL)) {
2775 pr_err("%s: data or priv is NULL\n", __func__);
2776 return -EINVAL;
2777 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07002778
2779 c = priv;
2780
2781 pr_debug("%s: session_id 0x%x\n", __func__, data->dest_port);
2782
2783 v = voice_get_session(data->dest_port);
2784 if (v == NULL) {
2785 pr_err("%s: v is NULL\n", __func__);
2786
2787 return -EINVAL;
2788 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002789
2790 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
2791 data->payload_size, data->opcode);
2792
Neema Shetty07477582011-09-02 17:35:44 -07002793 if (data->opcode == RESET_EVENTS) {
2794 pr_debug("%s: Reset event received in Voice service\n",
2795 __func__);
2796
2797 apr_reset(c->apr_q6_mvm);
2798 c->apr_q6_mvm = NULL;
2799
2800 /* Sub-system restart is applicable to all sessions. */
2801 for (i = 0; i < MAX_VOC_SESSIONS; i++)
2802 c->voice[i].mvm_handle = 0;
2803
2804 return 0;
2805 }
2806
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002807 if (data->opcode == APR_BASIC_RSP_RESULT) {
2808 if (data->payload_size) {
2809 ptr = data->payload;
2810
2811 pr_info("%x %x\n", ptr[0], ptr[1]);
2812 /* ping mvm service ACK */
2813 switch (ptr[0]) {
2814 case VSS_IMVM_CMD_CREATE_PASSIVE_CONTROL_SESSION:
2815 case VSS_IMVM_CMD_CREATE_FULL_CONTROL_SESSION:
2816 /* Passive session is used for CS call
2817 * Full session is used for VoIP call. */
2818 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2819 if (!ptr[1]) {
2820 pr_debug("%s: MVM handle is %d\n",
2821 __func__, data->src_port);
2822 voice_set_mvm_handle(v, data->src_port);
2823 } else
2824 pr_err("got NACK for sending \
2825 MVM create session \n");
2826 v->mvm_state = CMD_STATUS_SUCCESS;
2827 wake_up(&v->mvm_wait);
2828 break;
2829 case VSS_IMVM_CMD_START_VOICE:
Helen Zeng69b00962011-07-08 11:38:36 -07002830 case VSS_IMVM_CMD_ATTACH_VOCPROC:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002831 case VSS_IMVM_CMD_STOP_VOICE:
Helen Zeng69b00962011-07-08 11:38:36 -07002832 case VSS_IMVM_CMD_DETACH_VOCPROC:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002833 case VSS_ISTREAM_CMD_SET_TTY_MODE:
2834 case APRV2_IBASIC_CMD_DESTROY_SESSION:
2835 case VSS_IMVM_CMD_ATTACH_STREAM:
2836 case VSS_IMVM_CMD_DETACH_STREAM:
2837 case VSS_ICOMMON_CMD_SET_NETWORK:
2838 case VSS_ICOMMON_CMD_SET_VOICE_TIMING:
Helen Zeng44d4d272011-08-10 14:49:20 -07002839 case VSS_IWIDEVOICE_CMD_SET_WIDEVOICE:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002840 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2841 v->mvm_state = CMD_STATUS_SUCCESS;
2842 wake_up(&v->mvm_wait);
2843 break;
2844 default:
2845 pr_debug("%s: not match cmd = 0x%x\n",
2846 __func__, ptr[0]);
2847 break;
2848 }
2849 }
2850 }
2851
2852 return 0;
2853}
2854
2855static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv)
2856{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002857 uint32_t *ptr = NULL;
2858 struct common_data *c = NULL;
2859 struct voice_data *v = NULL;
Neema Shetty07477582011-09-02 17:35:44 -07002860 int i = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002861
2862 if ((data == NULL) || (priv == NULL)) {
2863 pr_err("%s: data or priv is NULL\n", __func__);
2864 return -EINVAL;
2865 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07002866
2867 c = priv;
2868
2869 pr_debug("%s: session_id 0x%x\n", __func__, data->dest_port);
2870
2871 v = voice_get_session(data->dest_port);
2872 if (v == NULL) {
2873 pr_err("%s: v is NULL\n", __func__);
2874
2875 return -EINVAL;
2876 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002877
2878 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
2879 data->payload_size, data->opcode);
2880
Neema Shetty07477582011-09-02 17:35:44 -07002881 if (data->opcode == RESET_EVENTS) {
2882 pr_debug("%s: Reset event received in Voice service\n",
2883 __func__);
2884
2885 apr_reset(c->apr_q6_cvs);
2886 c->apr_q6_cvs = NULL;
2887
2888 /* Sub-system restart is applicable to all sessions. */
2889 for (i = 0; i < MAX_VOC_SESSIONS; i++)
2890 c->voice[i].cvs_handle = 0;
2891
2892 return 0;
2893 }
2894
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002895 if (data->opcode == APR_BASIC_RSP_RESULT) {
2896 if (data->payload_size) {
2897 ptr = data->payload;
2898
2899 pr_info("%x %x\n", ptr[0], ptr[1]);
2900 /*response from CVS */
2901 switch (ptr[0]) {
2902 case VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION:
2903 case VSS_ISTREAM_CMD_CREATE_FULL_CONTROL_SESSION:
2904 if (!ptr[1]) {
2905 pr_debug("%s: CVS handle is %d\n",
2906 __func__, data->src_port);
2907 voice_set_cvs_handle(v, data->src_port);
2908 } else
2909 pr_err("got NACK for sending \
2910 CVS create session \n");
2911 v->cvs_state = CMD_STATUS_SUCCESS;
2912 wake_up(&v->cvs_wait);
2913 break;
2914 case VSS_ISTREAM_CMD_SET_MUTE:
2915 case VSS_ISTREAM_CMD_SET_MEDIA_TYPE:
2916 case VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE:
2917 case VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE:
2918 case VSS_ISTREAM_CMD_SET_ENC_DTX_MODE:
2919 case VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE:
2920 case APRV2_IBASIC_CMD_DESTROY_SESSION:
Helen Zeng29eb7442011-06-20 11:06:29 -07002921 case VSS_ISTREAM_CMD_REGISTER_CALIBRATION_DATA:
2922 case VSS_ISTREAM_CMD_DEREGISTER_CALIBRATION_DATA:
2923 case VSS_ICOMMON_CMD_MAP_MEMORY:
2924 case VSS_ICOMMON_CMD_UNMAP_MEMORY:
Helen Zengbb49c702011-09-06 14:09:13 -07002925 case VSS_ICOMMON_CMD_SET_UI_PROPERTY:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002926 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2927 v->cvs_state = CMD_STATUS_SUCCESS;
2928 wake_up(&v->cvs_wait);
2929 break;
Ben Romberger13b74ab2011-07-18 17:36:32 -07002930 case VOICE_CMD_SET_PARAM:
2931 rtac_make_voice_callback(RTAC_CVS, ptr,
2932 data->payload_size);
2933 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002934 default:
2935 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2936 break;
2937 }
2938 }
2939 } else if (data->opcode == VSS_ISTREAM_EVT_SEND_ENC_BUFFER) {
2940 uint32_t *voc_pkt = data->payload;
2941 uint32_t pkt_len = data->payload_size;
2942
Neema Shetty2c07eb52011-08-21 20:33:52 -07002943 if (voc_pkt != NULL && c->mvs_info.ul_cb != NULL) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002944 pr_debug("%s: Media type is 0x%x\n",
2945 __func__, voc_pkt[0]);
2946
2947 /* Remove media ID from payload. */
2948 voc_pkt++;
2949 pkt_len = pkt_len - 4;
2950
Neema Shetty2c07eb52011-08-21 20:33:52 -07002951 c->mvs_info.ul_cb((uint8_t *)voc_pkt,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002952 pkt_len,
Neema Shetty2c07eb52011-08-21 20:33:52 -07002953 c->mvs_info.private_data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002954 } else
2955 pr_err("%s: voc_pkt is 0x%x ul_cb is 0x%x\n",
2956 __func__, (unsigned int)voc_pkt,
Neema Shetty2c07eb52011-08-21 20:33:52 -07002957 (unsigned int) c->mvs_info.ul_cb);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002958 } else if (data->opcode == VSS_ISTREAM_EVT_REQUEST_DEC_BUFFER) {
2959 struct cvs_send_dec_buf_cmd send_dec_buf;
2960 int ret = 0;
2961 uint32_t pkt_len = 0;
2962
Neema Shetty2c07eb52011-08-21 20:33:52 -07002963 if (c->mvs_info.dl_cb != NULL) {
2964 send_dec_buf.dec_buf.media_id = c->mvs_info.media_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002965
Neema Shetty2c07eb52011-08-21 20:33:52 -07002966 c->mvs_info.dl_cb(
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002967 (uint8_t *)&send_dec_buf.dec_buf.packet_data,
2968 &pkt_len,
Neema Shetty2c07eb52011-08-21 20:33:52 -07002969 c->mvs_info.private_data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002970
2971 send_dec_buf.hdr.hdr_field =
2972 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2973 APR_HDR_LEN(APR_HDR_SIZE),
2974 APR_PKT_VER);
2975 send_dec_buf.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2976 sizeof(send_dec_buf.dec_buf.media_id) + pkt_len);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002977 send_dec_buf.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002978 send_dec_buf.hdr.dest_port = voice_get_cvs_handle(v);
2979 send_dec_buf.hdr.token = 0;
2980 send_dec_buf.hdr.opcode =
2981 VSS_ISTREAM_EVT_SEND_DEC_BUFFER;
2982
Neema Shetty2c07eb52011-08-21 20:33:52 -07002983 ret = apr_send_pkt(c->apr_q6_cvs,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002984 (uint32_t *) &send_dec_buf);
2985 if (ret < 0) {
2986 pr_err("%s: Error %d sending DEC_BUF\n",
2987 __func__, ret);
2988 goto fail;
2989 }
2990 } else
2991 pr_debug("%s: dl_cb is NULL\n", __func__);
Ben Romberger13b74ab2011-07-18 17:36:32 -07002992 } else if (data->opcode == VSS_ISTREAM_EVT_SEND_DEC_BUFFER) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002993 pr_debug("Send dec buf resp\n");
Ben Romberger13b74ab2011-07-18 17:36:32 -07002994 } else if (data->opcode == VOICE_EVT_GET_PARAM_ACK) {
2995 rtac_make_voice_callback(RTAC_CVS, data->payload,
2996 data->payload_size);
2997 } else
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002998 pr_debug("Unknown opcode 0x%x\n", data->opcode);
2999
3000fail:
3001 return 0;
3002}
3003
3004static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv)
3005{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003006 uint32_t *ptr = NULL;
3007 struct common_data *c = NULL;
3008 struct voice_data *v = NULL;
Neema Shetty07477582011-09-02 17:35:44 -07003009 int i = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003010
3011 if ((data == NULL) || (priv == NULL)) {
3012 pr_err("%s: data or priv is NULL\n", __func__);
3013 return -EINVAL;
3014 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07003015
3016 c = priv;
3017
3018 v = voice_get_session(data->dest_port);
3019 if (v == NULL) {
3020 pr_err("%s: v is NULL\n", __func__);
3021
3022 return -EINVAL;
3023 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003024
3025 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
3026 data->payload_size, data->opcode);
3027
Neema Shetty07477582011-09-02 17:35:44 -07003028 if (data->opcode == RESET_EVENTS) {
3029 pr_debug("%s: Reset event received in Voice service\n",
3030 __func__);
3031
3032 apr_reset(c->apr_q6_cvp);
3033 c->apr_q6_cvp = NULL;
3034
3035 /* Sub-system restart is applicable to all sessions. */
3036 for (i = 0; i < MAX_VOC_SESSIONS; i++)
3037 c->voice[i].cvp_handle = 0;
3038
3039 return 0;
3040 }
3041
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003042 if (data->opcode == APR_BASIC_RSP_RESULT) {
3043 if (data->payload_size) {
3044 ptr = data->payload;
3045
3046 pr_info("%x %x\n", ptr[0], ptr[1]);
3047
3048 switch (ptr[0]) {
3049 case VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION:
3050 /*response from CVP */
3051 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
3052 if (!ptr[1]) {
3053 voice_set_cvp_handle(v, data->src_port);
3054 pr_debug("cvphdl=%d\n", data->src_port);
3055 } else
3056 pr_err("got NACK from CVP create \
3057 session response\n");
3058 v->cvp_state = CMD_STATUS_SUCCESS;
3059 wake_up(&v->cvp_wait);
3060 break;
3061 case VSS_IVOCPROC_CMD_SET_DEVICE:
3062 case VSS_IVOCPROC_CMD_SET_RX_VOLUME_INDEX:
3063 case VSS_IVOCPROC_CMD_ENABLE:
3064 case VSS_IVOCPROC_CMD_DISABLE:
3065 case APRV2_IBASIC_CMD_DESTROY_SESSION:
Helen Zeng29eb7442011-06-20 11:06:29 -07003066 case VSS_IVOCPROC_CMD_REGISTER_VOLUME_CAL_TABLE:
3067 case VSS_IVOCPROC_CMD_DEREGISTER_VOLUME_CAL_TABLE:
3068 case VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA:
3069 case VSS_IVOCPROC_CMD_DEREGISTER_CALIBRATION_DATA:
3070 case VSS_ICOMMON_CMD_MAP_MEMORY:
3071 case VSS_ICOMMON_CMD_UNMAP_MEMORY:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003072 v->cvp_state = CMD_STATUS_SUCCESS;
3073 wake_up(&v->cvp_wait);
3074 break;
Ben Romberger13b74ab2011-07-18 17:36:32 -07003075 case VOICE_CMD_SET_PARAM:
3076 rtac_make_voice_callback(RTAC_CVP, ptr,
3077 data->payload_size);
3078 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003079 default:
3080 pr_debug("%s: not match cmd = 0x%x\n",
3081 __func__, ptr[0]);
3082 break;
3083 }
3084 }
Ben Romberger13b74ab2011-07-18 17:36:32 -07003085 } else if (data->opcode == VOICE_EVT_GET_PARAM_ACK) {
3086 rtac_make_voice_callback(RTAC_CVP, data->payload,
3087 data->payload_size);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003088 }
3089 return 0;
3090}
3091
3092
3093static int __init voice_init(void)
3094{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003095 int rc = 0, i = 0;
3096
3097 memset(&common, 0, sizeof(struct common_data));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003098
3099 /* set default value */
Neema Shetty2c07eb52011-08-21 20:33:52 -07003100 common.default_mute_val = 1; /* default is mute */
3101 common.default_vol_val = 0;
3102 common.default_sample_val = 8000;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003103
3104 /* Initialize MVS info. */
Neema Shetty2c07eb52011-08-21 20:33:52 -07003105 common.mvs_info.network_type = VSS_NETWORK_ID_DEFAULT;
3106
3107 mutex_init(&common.common_lock);
3108
3109 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
3110 common.voice[i].session_id = SESSION_ID_BASE + i;
3111
3112 /* initialize dev_rx and dev_tx */
3113 common.voice[i].dev_rx.volume = common.default_vol_val;
3114 common.voice[i].dev_tx.mute = common.default_mute_val;
3115
3116 common.voice[i].dev_tx.port_id = 1;
3117 common.voice[i].dev_rx.port_id = 0;
3118 common.voice[i].sidetone_gain = 0x512;
3119
3120 common.voice[i].voc_state = VOC_INIT;
3121
3122 init_waitqueue_head(&common.voice[i].mvm_wait);
3123 init_waitqueue_head(&common.voice[i].cvs_wait);
3124 init_waitqueue_head(&common.voice[i].cvp_wait);
3125
3126 mutex_init(&common.voice[i].lock);
3127 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003128
3129 return rc;
3130}
3131
3132device_initcall(voice_init);