blob: ecfef5b6de8de8f6dffdb9e880c74d601df1a6bc [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;
Helen Zeng69b00962011-07-08 11:38:36 -0700290 strncpy(mvm_session_cmd.mvm_session.name,
291 "default modem voice", SESSION_NAME_LEN);
292
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700293 v->mvm_state = CMD_STATUS_FAIL;
294
295 ret = apr_send_pkt(apr_mvm,
296 (uint32_t *) &mvm_session_cmd);
297 if (ret < 0) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700298 pr_err("%s: Error sending MVM_CONTROL_SESSION\n",
299 __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700300 goto fail;
301 }
302 ret = wait_event_timeout(v->mvm_wait,
303 (v->mvm_state == CMD_STATUS_SUCCESS),
304 msecs_to_jiffies(TIMEOUT_MS));
305 if (!ret) {
306 pr_err("%s: wait_event timeout\n", __func__);
307 goto fail;
308 }
309 } else {
310 pr_debug("%s: creating MVM full ctrl\n", __func__);
Helen Zeng69b00962011-07-08 11:38:36 -0700311 mvm_session_cmd.hdr.hdr_field =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700312 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
313 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
Helen Zeng69b00962011-07-08 11:38:36 -0700314 mvm_session_cmd.hdr.pkt_size =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700315 APR_PKT_SIZE(APR_HDR_SIZE,
Helen Zeng69b00962011-07-08 11:38:36 -0700316 sizeof(mvm_session_cmd) -
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700317 APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700318 mvm_session_cmd.hdr.src_port = v->session_id;
Helen Zeng69b00962011-07-08 11:38:36 -0700319 mvm_session_cmd.hdr.dest_port = 0;
320 mvm_session_cmd.hdr.token = 0;
321 mvm_session_cmd.hdr.opcode =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700322 VSS_IMVM_CMD_CREATE_FULL_CONTROL_SESSION;
Helen Zeng69b00962011-07-08 11:38:36 -0700323 strncpy(mvm_session_cmd.mvm_session.name,
324 "default voip", SESSION_NAME_LEN);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700325
326 v->mvm_state = CMD_STATUS_FAIL;
327
328 ret = apr_send_pkt(apr_mvm,
Helen Zeng69b00962011-07-08 11:38:36 -0700329 (uint32_t *) &mvm_session_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700330 if (ret < 0) {
331 pr_err("Fail in sending MVM_CONTROL_SESSION\n");
332 goto fail;
333 }
334 ret = wait_event_timeout(v->mvm_wait,
335 (v->mvm_state == CMD_STATUS_SUCCESS),
336 msecs_to_jiffies(TIMEOUT_MS));
337 if (!ret) {
338 pr_err("%s: wait_event timeout\n", __func__);
339 goto fail;
340 }
341 }
342 /* Get the created MVM handle. */
343 mvm_handle = voice_get_mvm_handle(v);
344 }
345 /* send cmd to create cvs session */
346 if (!cvs_handle) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700347 if (is_voice_session(v->session_id)) {
348 pr_debug("%s: creating CVS passive session\n",
349 __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700350
351 cvs_session_cmd.hdr.hdr_field = APR_HDR_FIELD(
352 APR_MSG_TYPE_SEQ_CMD,
353 APR_HDR_LEN(APR_HDR_SIZE),
354 APR_PKT_VER);
355 cvs_session_cmd.hdr.pkt_size =
356 APR_PKT_SIZE(APR_HDR_SIZE,
357 sizeof(cvs_session_cmd) -
358 APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700359 cvs_session_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700360 cvs_session_cmd.hdr.dest_port = 0;
361 cvs_session_cmd.hdr.token = 0;
362 cvs_session_cmd.hdr.opcode =
363 VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION;
364 strncpy(cvs_session_cmd.cvs_session.name,
Helen Zeng69b00962011-07-08 11:38:36 -0700365 "default modem voice", SESSION_NAME_LEN);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700366
367 v->cvs_state = CMD_STATUS_FAIL;
368
369 ret = apr_send_pkt(apr_cvs,
370 (uint32_t *) &cvs_session_cmd);
371 if (ret < 0) {
372 pr_err("Fail in sending STREAM_CONTROL_SESSION\n");
373 goto fail;
374 }
375 ret = wait_event_timeout(v->cvs_wait,
376 (v->cvs_state == CMD_STATUS_SUCCESS),
377 msecs_to_jiffies(TIMEOUT_MS));
378 if (!ret) {
379 pr_err("%s: wait_event timeout\n", __func__);
380 goto fail;
381 }
382 /* Get the created CVS handle. */
383 cvs_handle = voice_get_cvs_handle(v);
384
385 } else {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700386 pr_debug("%s: creating CVS full session\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700387
388 cvs_full_ctl_cmd.hdr.hdr_field =
389 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
390 APR_HDR_LEN(APR_HDR_SIZE),
391 APR_PKT_VER);
392
393 cvs_full_ctl_cmd.hdr.pkt_size =
394 APR_PKT_SIZE(APR_HDR_SIZE,
395 sizeof(cvs_full_ctl_cmd) -
396 APR_HDR_SIZE);
397
Neema Shetty2c07eb52011-08-21 20:33:52 -0700398 cvs_full_ctl_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700399 cvs_full_ctl_cmd.hdr.dest_port = 0;
400 cvs_full_ctl_cmd.hdr.token = 0;
401 cvs_full_ctl_cmd.hdr.opcode =
402 VSS_ISTREAM_CMD_CREATE_FULL_CONTROL_SESSION;
403 cvs_full_ctl_cmd.cvs_session.direction = 2;
404 cvs_full_ctl_cmd.cvs_session.enc_media_type =
Neema Shetty2c07eb52011-08-21 20:33:52 -0700405 common.mvs_info.media_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700406 cvs_full_ctl_cmd.cvs_session.dec_media_type =
Neema Shetty2c07eb52011-08-21 20:33:52 -0700407 common.mvs_info.media_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700408 cvs_full_ctl_cmd.cvs_session.network_id =
Neema Shetty2c07eb52011-08-21 20:33:52 -0700409 common.mvs_info.network_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700410 strncpy(cvs_full_ctl_cmd.cvs_session.name,
411 "default q6 voice", 16);
412
413 v->cvs_state = CMD_STATUS_FAIL;
414
415 ret = apr_send_pkt(apr_cvs,
416 (uint32_t *) &cvs_full_ctl_cmd);
417
418 if (ret < 0) {
419 pr_err("%s: Err %d sending CREATE_FULL_CTRL\n",
420 __func__, ret);
421 goto fail;
422 }
423 ret = wait_event_timeout(v->cvs_wait,
424 (v->cvs_state == CMD_STATUS_SUCCESS),
425 msecs_to_jiffies(TIMEOUT_MS));
426 if (!ret) {
427 pr_err("%s: wait_event timeout\n", __func__);
428 goto fail;
429 }
430 /* Get the created CVS handle. */
431 cvs_handle = voice_get_cvs_handle(v);
432
433 /* Attach MVM to CVS. */
Neema Shetty2c07eb52011-08-21 20:33:52 -0700434 pr_debug("%s: Attach MVM to stream\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700435
436 attach_stream_cmd.hdr.hdr_field =
437 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
438 APR_HDR_LEN(APR_HDR_SIZE),
439 APR_PKT_VER);
440 attach_stream_cmd.hdr.pkt_size =
441 APR_PKT_SIZE(APR_HDR_SIZE,
442 sizeof(attach_stream_cmd) -
443 APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700444 attach_stream_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700445 attach_stream_cmd.hdr.dest_port = mvm_handle;
446 attach_stream_cmd.hdr.token = 0;
447 attach_stream_cmd.hdr.opcode =
448 VSS_IMVM_CMD_ATTACH_STREAM;
449 attach_stream_cmd.attach_stream.handle = cvs_handle;
450
451 v->mvm_state = CMD_STATUS_FAIL;
452 ret = apr_send_pkt(apr_mvm,
453 (uint32_t *) &attach_stream_cmd);
454 if (ret < 0) {
455 pr_err("%s: Error %d sending ATTACH_STREAM\n",
456 __func__, ret);
457 goto fail;
458 }
459 ret = wait_event_timeout(v->mvm_wait,
460 (v->mvm_state == CMD_STATUS_SUCCESS),
461 msecs_to_jiffies(TIMEOUT_MS));
462 if (!ret) {
463 pr_err("%s: wait_event timeout\n", __func__);
464 goto fail;
465 }
466 }
467 }
468 return 0;
469
470fail:
471 return -EINVAL;
472}
473
474static int voice_destroy_mvm_cvs_session(struct voice_data *v)
475{
476 int ret = 0;
477 struct mvm_detach_stream_cmd detach_stream;
478 struct apr_hdr mvm_destroy;
479 struct apr_hdr cvs_destroy;
480 void *apr_mvm, *apr_cvs;
481 u16 mvm_handle, cvs_handle;
482
483 if (v == NULL) {
484 pr_err("%s: v is NULL\n", __func__);
485 return -EINVAL;
486 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700487 apr_mvm = common.apr_q6_mvm;
488 apr_cvs = common.apr_q6_cvs;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700489
490 if (!apr_mvm || !apr_cvs) {
491 pr_err("%s: apr_mvm or apr_cvs is NULL\n", __func__);
492 return -EINVAL;
493 }
494 mvm_handle = voice_get_mvm_handle(v);
495 cvs_handle = voice_get_cvs_handle(v);
496
497 /* MVM, CVS sessions are destroyed only for Full control sessions. */
Neema Shetty2c07eb52011-08-21 20:33:52 -0700498 if (is_voip_session(v->session_id)) {
499 pr_debug("%s: MVM detach stream\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700500
501 /* Detach voice stream. */
502 detach_stream.hdr.hdr_field =
503 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
504 APR_HDR_LEN(APR_HDR_SIZE),
505 APR_PKT_VER);
506 detach_stream.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
507 sizeof(detach_stream) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700508 detach_stream.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700509 detach_stream.hdr.dest_port = mvm_handle;
510 detach_stream.hdr.token = 0;
511 detach_stream.hdr.opcode = VSS_IMVM_CMD_DETACH_STREAM;
512 detach_stream.detach_stream.handle = cvs_handle;
513
514 v->mvm_state = CMD_STATUS_FAIL;
515
516 ret = apr_send_pkt(apr_mvm, (uint32_t *) &detach_stream);
517 if (ret < 0) {
518 pr_err("%s: Error %d sending DETACH_STREAM\n",
519 __func__, ret);
520 goto fail;
521 }
522 ret = wait_event_timeout(v->mvm_wait,
523 (v->mvm_state == CMD_STATUS_SUCCESS),
524 msecs_to_jiffies(TIMEOUT_MS));
525 if (!ret) {
526 pr_err("%s: wait event timeout\n", __func__);
527 goto fail;
528 }
529 /* Destroy CVS. */
Neema Shetty2c07eb52011-08-21 20:33:52 -0700530 pr_debug("%s: CVS destroy session\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700531
532 cvs_destroy.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
533 APR_HDR_LEN(APR_HDR_SIZE),
534 APR_PKT_VER);
535 cvs_destroy.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
536 sizeof(cvs_destroy) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700537 cvs_destroy.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700538 cvs_destroy.dest_port = cvs_handle;
539 cvs_destroy.token = 0;
540 cvs_destroy.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
541
542 v->cvs_state = CMD_STATUS_FAIL;
543
544 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_destroy);
545 if (ret < 0) {
546 pr_err("%s: Error %d sending CVS DESTROY\n",
547 __func__, ret);
548 goto fail;
549 }
550 ret = wait_event_timeout(v->cvs_wait,
551 (v->cvs_state == CMD_STATUS_SUCCESS),
552 msecs_to_jiffies(TIMEOUT_MS));
553 if (!ret) {
554 pr_err("%s: wait event timeout\n", __func__);
555
556 goto fail;
557 }
558 cvs_handle = 0;
559 voice_set_cvs_handle(v, cvs_handle);
560
561 /* Destroy MVM. */
562 pr_debug("MVM destroy session\n");
563
564 mvm_destroy.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
565 APR_HDR_LEN(APR_HDR_SIZE),
566 APR_PKT_VER);
567 mvm_destroy.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
568 sizeof(mvm_destroy) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700569 mvm_destroy.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700570 mvm_destroy.dest_port = mvm_handle;
571 mvm_destroy.token = 0;
572 mvm_destroy.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
573
574 v->mvm_state = CMD_STATUS_FAIL;
575
576 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_destroy);
577 if (ret < 0) {
578 pr_err("%s: Error %d sending MVM DESTROY\n",
579 __func__, ret);
580
581 goto fail;
582 }
583 ret = wait_event_timeout(v->mvm_wait,
584 (v->mvm_state == CMD_STATUS_SUCCESS),
585 msecs_to_jiffies(TIMEOUT_MS));
586 if (!ret) {
587 pr_err("%s: wait event timeout\n", __func__);
588
589 goto fail;
590 }
591 mvm_handle = 0;
592 voice_set_mvm_handle(v, mvm_handle);
593 }
594 return 0;
595fail:
596 return -EINVAL;
597}
598
599static int voice_send_tty_mode_cmd(struct voice_data *v)
600{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700601 int ret = 0;
602 struct mvm_set_tty_mode_cmd mvm_tty_mode_cmd;
603 void *apr_mvm;
604 u16 mvm_handle;
605
606 if (v == NULL) {
607 pr_err("%s: v is NULL\n", __func__);
608 return -EINVAL;
609 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700610 apr_mvm = common.apr_q6_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700611
612 if (!apr_mvm) {
613 pr_err("%s: apr_mvm is NULL.\n", __func__);
614 return -EINVAL;
615 }
616 mvm_handle = voice_get_mvm_handle(v);
617
Helen Zengcc65b5b2011-07-06 19:14:48 -0700618 if (v->tty_mode) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700619 /* send tty mode cmd to mvm */
620 mvm_tty_mode_cmd.hdr.hdr_field = APR_HDR_FIELD(
621 APR_MSG_TYPE_SEQ_CMD,
622 APR_HDR_LEN(APR_HDR_SIZE),
623 APR_PKT_VER);
624 mvm_tty_mode_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
625 sizeof(mvm_tty_mode_cmd) -
626 APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700627 pr_debug("%s: pkt size = %d\n",
628 __func__, mvm_tty_mode_cmd.hdr.pkt_size);
629 mvm_tty_mode_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700630 mvm_tty_mode_cmd.hdr.dest_port = mvm_handle;
631 mvm_tty_mode_cmd.hdr.token = 0;
632 mvm_tty_mode_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_TTY_MODE;
Helen Zengcc65b5b2011-07-06 19:14:48 -0700633 mvm_tty_mode_cmd.tty_mode.mode = v->tty_mode;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700634 pr_debug("tty mode =%d\n", mvm_tty_mode_cmd.tty_mode.mode);
635
636 v->mvm_state = CMD_STATUS_FAIL;
637 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_tty_mode_cmd);
638 if (ret < 0) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700639 pr_err("%s: Error %d sending SET_TTY_MODE\n",
640 __func__, ret);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700641 goto fail;
642 }
643 ret = wait_event_timeout(v->mvm_wait,
644 (v->mvm_state == CMD_STATUS_SUCCESS),
645 msecs_to_jiffies(TIMEOUT_MS));
646 if (!ret) {
647 pr_err("%s: wait_event timeout\n", __func__);
648 goto fail;
649 }
650 }
651 return 0;
652fail:
653 return -EINVAL;
654}
655
656static int voice_config_cvs_vocoder(struct voice_data *v)
657{
658 int ret = 0;
659 void *apr_cvs;
660 u16 cvs_handle;
661 /* Set media type. */
662 struct cvs_set_media_type_cmd cvs_set_media_cmd;
663
664 if (v == NULL) {
665 pr_err("%s: v is NULL\n", __func__);
666 return -EINVAL;
667 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700668 apr_cvs = common.apr_q6_cvs;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700669
670 if (!apr_cvs) {
671 pr_err("%s: apr_cvs is NULL.\n", __func__);
672 return -EINVAL;
673 }
674
675 cvs_handle = voice_get_cvs_handle(v);
676
677 cvs_set_media_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
678 APR_HDR_LEN(APR_HDR_SIZE),
679 APR_PKT_VER);
680 cvs_set_media_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
681 sizeof(cvs_set_media_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700682 cvs_set_media_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700683 cvs_set_media_cmd.hdr.dest_port = cvs_handle;
684 cvs_set_media_cmd.hdr.token = 0;
685 cvs_set_media_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_MEDIA_TYPE;
Neema Shetty2c07eb52011-08-21 20:33:52 -0700686 cvs_set_media_cmd.media_type.tx_media_id = common.mvs_info.media_type;
687 cvs_set_media_cmd.media_type.rx_media_id = common.mvs_info.media_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700688
689 v->cvs_state = CMD_STATUS_FAIL;
690
691 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_media_cmd);
692 if (ret < 0) {
693 pr_err("%s: Error %d sending SET_MEDIA_TYPE\n",
694 __func__, ret);
695
696 goto fail;
697 }
698 ret = wait_event_timeout(v->cvs_wait,
699 (v->cvs_state == CMD_STATUS_SUCCESS),
700 msecs_to_jiffies(TIMEOUT_MS));
701 if (!ret) {
702 pr_err("%s: wait_event timeout\n", __func__);
703
704 goto fail;
705 }
706 /* Set encoder properties. */
Neema Shetty2c07eb52011-08-21 20:33:52 -0700707 switch (common.mvs_info.media_type) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700708 case VSS_MEDIA_ID_EVRC_MODEM: {
709 struct cvs_set_cdma_enc_minmax_rate_cmd cvs_set_cdma_rate;
710
711 pr_debug("Setting EVRC min-max rate\n");
712
713 cvs_set_cdma_rate.hdr.hdr_field =
714 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
715 APR_HDR_LEN(APR_HDR_SIZE),
716 APR_PKT_VER);
717 cvs_set_cdma_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
718 sizeof(cvs_set_cdma_rate) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700719 cvs_set_cdma_rate.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700720 cvs_set_cdma_rate.hdr.dest_port = cvs_handle;
721 cvs_set_cdma_rate.hdr.token = 0;
722 cvs_set_cdma_rate.hdr.opcode =
723 VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE;
Neema Shetty2c07eb52011-08-21 20:33:52 -0700724 cvs_set_cdma_rate.cdma_rate.min_rate = common.mvs_info.rate;
725 cvs_set_cdma_rate.cdma_rate.max_rate = common.mvs_info.rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700726
727 v->cvs_state = CMD_STATUS_FAIL;
728
729 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_cdma_rate);
730 if (ret < 0) {
731 pr_err("%s: Error %d sending SET_EVRC_MINMAX_RATE\n",
732 __func__, ret);
733 goto fail;
734 }
735 ret = wait_event_timeout(v->cvs_wait,
736 (v->cvs_state == CMD_STATUS_SUCCESS),
737 msecs_to_jiffies(TIMEOUT_MS));
738 if (!ret) {
739 pr_err("%s: wait_event timeout\n", __func__);
740
741 goto fail;
742 }
743 break;
744 }
745 case VSS_MEDIA_ID_AMR_NB_MODEM: {
746 struct cvs_set_amr_enc_rate_cmd cvs_set_amr_rate;
747 struct cvs_set_enc_dtx_mode_cmd cvs_set_dtx;
748
749 pr_debug("Setting AMR rate\n");
750
751 cvs_set_amr_rate.hdr.hdr_field =
752 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
753 APR_HDR_LEN(APR_HDR_SIZE),
754 APR_PKT_VER);
755 cvs_set_amr_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
756 sizeof(cvs_set_amr_rate) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700757 cvs_set_amr_rate.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700758 cvs_set_amr_rate.hdr.dest_port = cvs_handle;
759 cvs_set_amr_rate.hdr.token = 0;
760 cvs_set_amr_rate.hdr.opcode =
761 VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE;
Neema Shetty2c07eb52011-08-21 20:33:52 -0700762 cvs_set_amr_rate.amr_rate.mode = common.mvs_info.rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700763
764 v->cvs_state = CMD_STATUS_FAIL;
765
766 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_amr_rate);
767 if (ret < 0) {
768 pr_err("%s: Error %d sending SET_AMR_RATE\n",
769 __func__, ret);
770 goto fail;
771 }
772 ret = wait_event_timeout(v->cvs_wait,
773 (v->cvs_state == CMD_STATUS_SUCCESS),
774 msecs_to_jiffies(TIMEOUT_MS));
775 if (!ret) {
776 pr_err("%s: wait_event timeout\n", __func__);
777 goto fail;
778 }
779 /* Disable DTX */
780 pr_debug("Disabling DTX\n");
781
782 cvs_set_dtx.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
783 APR_HDR_LEN(APR_HDR_SIZE),
784 APR_PKT_VER);
785 cvs_set_dtx.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
786 sizeof(cvs_set_dtx) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700787 cvs_set_dtx.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700788 cvs_set_dtx.hdr.dest_port = cvs_handle;
789 cvs_set_dtx.hdr.token = 0;
790 cvs_set_dtx.hdr.opcode = VSS_ISTREAM_CMD_SET_ENC_DTX_MODE;
791 cvs_set_dtx.dtx_mode.enable = 0;
792
793 v->cvs_state = CMD_STATUS_FAIL;
794
795 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_dtx);
796 if (ret < 0) {
797 pr_err("%s: Error %d sending SET_DTX\n",
798 __func__, ret);
799 goto fail;
800 }
801 ret = wait_event_timeout(v->cvs_wait,
802 (v->cvs_state == CMD_STATUS_SUCCESS),
803 msecs_to_jiffies(TIMEOUT_MS));
804 if (!ret) {
805 pr_err("%s: wait_event timeout\n", __func__);
806 goto fail;
807 }
808 break;
809 }
810 case VSS_MEDIA_ID_AMR_WB_MODEM: {
811 struct cvs_set_amrwb_enc_rate_cmd cvs_set_amrwb_rate;
812 struct cvs_set_enc_dtx_mode_cmd cvs_set_dtx;
813
814 pr_debug("Setting AMR WB rate\n");
815
816 cvs_set_amrwb_rate.hdr.hdr_field =
817 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
818 APR_HDR_LEN(APR_HDR_SIZE),
819 APR_PKT_VER);
820 cvs_set_amrwb_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
821 sizeof(cvs_set_amrwb_rate) -
822 APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700823 cvs_set_amrwb_rate.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700824 cvs_set_amrwb_rate.hdr.dest_port = cvs_handle;
825 cvs_set_amrwb_rate.hdr.token = 0;
826 cvs_set_amrwb_rate.hdr.opcode =
827 VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE;
Neema Shetty2c07eb52011-08-21 20:33:52 -0700828 cvs_set_amrwb_rate.amrwb_rate.mode = common.mvs_info.rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700829
830 v->cvs_state = CMD_STATUS_FAIL;
831
832 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_amrwb_rate);
833 if (ret < 0) {
834 pr_err("%s: Error %d sending SET_AMRWB_RATE\n",
835 __func__, ret);
836 goto fail;
837 }
838 ret = wait_event_timeout(v->cvs_wait,
839 (v->cvs_state == CMD_STATUS_SUCCESS),
840 msecs_to_jiffies(TIMEOUT_MS));
841 if (!ret) {
842 pr_err("%s: wait_event timeout\n", __func__);
843 goto fail;
844 }
845 /* Disable DTX */
846 pr_debug("Disabling DTX\n");
847
848 cvs_set_dtx.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
849 APR_HDR_LEN(APR_HDR_SIZE),
850 APR_PKT_VER);
851 cvs_set_dtx.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
852 sizeof(cvs_set_dtx) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700853 cvs_set_dtx.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700854 cvs_set_dtx.hdr.dest_port = cvs_handle;
855 cvs_set_dtx.hdr.token = 0;
856 cvs_set_dtx.hdr.opcode = VSS_ISTREAM_CMD_SET_ENC_DTX_MODE;
857 cvs_set_dtx.dtx_mode.enable = 0;
858
859 v->cvs_state = CMD_STATUS_FAIL;
860
861 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_dtx);
862 if (ret < 0) {
863 pr_err("%s: Error %d sending SET_DTX\n",
864 __func__, ret);
865 goto fail;
866 }
867 ret = wait_event_timeout(v->cvs_wait,
868 (v->cvs_state == CMD_STATUS_SUCCESS),
869 msecs_to_jiffies(TIMEOUT_MS));
870 if (!ret) {
871 pr_err("%s: wait_event timeout\n", __func__);
872 goto fail;
873 }
874 break;
875 }
876 case VSS_MEDIA_ID_G729:
877 case VSS_MEDIA_ID_G711_ALAW:
878 case VSS_MEDIA_ID_G711_MULAW: {
879 struct cvs_set_enc_dtx_mode_cmd cvs_set_dtx;
880 /* Disable DTX */
881 pr_debug("Disabling DTX\n");
882
883 cvs_set_dtx.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
884 APR_HDR_LEN(APR_HDR_SIZE),
885 APR_PKT_VER);
886 cvs_set_dtx.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
887 sizeof(cvs_set_dtx) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700888 cvs_set_dtx.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700889 cvs_set_dtx.hdr.dest_port = cvs_handle;
890 cvs_set_dtx.hdr.token = 0;
891 cvs_set_dtx.hdr.opcode = VSS_ISTREAM_CMD_SET_ENC_DTX_MODE;
892 cvs_set_dtx.dtx_mode.enable = 0;
893
894 v->cvs_state = CMD_STATUS_FAIL;
895
896 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_dtx);
897 if (ret < 0) {
898 pr_err("%s: Error %d sending SET_DTX\n",
899 __func__, ret);
900 goto fail;
901 }
902 ret = wait_event_timeout(v->cvs_wait,
903 (v->cvs_state == CMD_STATUS_SUCCESS),
904 msecs_to_jiffies(TIMEOUT_MS));
905 if (!ret) {
906 pr_err("%s: wait_event timeout\n", __func__);
907 goto fail;
908 }
909 break;
910 }
911 default:
912 /* Do nothing. */
913 break;
914 }
915 return 0;
916
917fail:
918 return -EINVAL;
919}
920
921static int voice_send_start_voice_cmd(struct voice_data *v)
922{
923 struct apr_hdr mvm_start_voice_cmd;
924 int ret = 0;
925 void *apr_mvm;
926 u16 mvm_handle;
927
928 if (v == NULL) {
929 pr_err("%s: v is NULL\n", __func__);
930 return -EINVAL;
931 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700932 apr_mvm = common.apr_q6_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700933
934 if (!apr_mvm) {
935 pr_err("%s: apr_mvm is NULL.\n", __func__);
936 return -EINVAL;
937 }
938 mvm_handle = voice_get_mvm_handle(v);
939
940 mvm_start_voice_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
941 APR_HDR_LEN(APR_HDR_SIZE),
942 APR_PKT_VER);
943 mvm_start_voice_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
944 sizeof(mvm_start_voice_cmd) - APR_HDR_SIZE);
945 pr_debug("send mvm_start_voice_cmd pkt size = %d\n",
946 mvm_start_voice_cmd.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700947 mvm_start_voice_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700948 mvm_start_voice_cmd.dest_port = mvm_handle;
949 mvm_start_voice_cmd.token = 0;
950 mvm_start_voice_cmd.opcode = VSS_IMVM_CMD_START_VOICE;
951
952 v->mvm_state = CMD_STATUS_FAIL;
953 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_start_voice_cmd);
954 if (ret < 0) {
955 pr_err("Fail in sending VSS_IMVM_CMD_START_VOICE\n");
956 goto fail;
957 }
958 ret = wait_event_timeout(v->mvm_wait,
959 (v->mvm_state == CMD_STATUS_SUCCESS),
960 msecs_to_jiffies(TIMEOUT_MS));
961 if (!ret) {
962 pr_err("%s: wait_event timeout\n", __func__);
963 goto fail;
964 }
965 return 0;
966fail:
967 return -EINVAL;
968}
969
970static int voice_send_disable_vocproc_cmd(struct voice_data *v)
971{
972 struct apr_hdr cvp_disable_cmd;
973 int ret = 0;
974 void *apr_cvp;
975 u16 cvp_handle;
976
977 if (v == NULL) {
978 pr_err("%s: v is NULL\n", __func__);
979 return -EINVAL;
980 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700981 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700982
983 if (!apr_cvp) {
984 pr_err("%s: apr regist failed\n", __func__);
985 return -EINVAL;
986 }
987 cvp_handle = voice_get_cvp_handle(v);
988
989 /* disable vocproc and wait for respose */
990 cvp_disable_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
991 APR_HDR_LEN(APR_HDR_SIZE),
992 APR_PKT_VER);
993 cvp_disable_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
994 sizeof(cvp_disable_cmd) - APR_HDR_SIZE);
995 pr_debug("cvp_disable_cmd pkt size = %d, cvp_handle=%d\n",
996 cvp_disable_cmd.pkt_size, cvp_handle);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700997 cvp_disable_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700998 cvp_disable_cmd.dest_port = cvp_handle;
999 cvp_disable_cmd.token = 0;
1000 cvp_disable_cmd.opcode = VSS_IVOCPROC_CMD_DISABLE;
1001
1002 v->cvp_state = CMD_STATUS_FAIL;
1003 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_disable_cmd);
1004 if (ret < 0) {
1005 pr_err("Fail in sending VSS_IVOCPROC_CMD_DISABLE\n");
1006 goto fail;
1007 }
1008 ret = wait_event_timeout(v->cvp_wait,
1009 (v->cvp_state == CMD_STATUS_SUCCESS),
1010 msecs_to_jiffies(TIMEOUT_MS));
1011 if (!ret) {
1012 pr_err("%s: wait_event timeout\n", __func__);
1013 goto fail;
1014 }
1015
1016 return 0;
1017fail:
1018 return -EINVAL;
1019}
1020
1021static int voice_send_set_device_cmd(struct voice_data *v)
1022{
1023 struct cvp_set_device_cmd cvp_setdev_cmd;
1024 int ret = 0;
1025 void *apr_cvp;
1026 u16 cvp_handle;
1027
1028 if (v == NULL) {
1029 pr_err("%s: v is NULL\n", __func__);
1030 return -EINVAL;
1031 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001032 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001033
1034 if (!apr_cvp) {
1035 pr_err("%s: apr_cvp is NULL.\n", __func__);
1036 return -EINVAL;
1037 }
1038 cvp_handle = voice_get_cvp_handle(v);
1039
1040 /* set device and wait for response */
1041 cvp_setdev_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1042 APR_HDR_LEN(APR_HDR_SIZE),
1043 APR_PKT_VER);
1044 cvp_setdev_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1045 sizeof(cvp_setdev_cmd) - APR_HDR_SIZE);
1046 pr_debug(" send create cvp setdev, pkt size = %d\n",
1047 cvp_setdev_cmd.hdr.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001048 cvp_setdev_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001049 cvp_setdev_cmd.hdr.dest_port = cvp_handle;
1050 cvp_setdev_cmd.hdr.token = 0;
1051 cvp_setdev_cmd.hdr.opcode = VSS_IVOCPROC_CMD_SET_DEVICE;
1052
1053 /* Use default topology if invalid value in ACDB */
1054 cvp_setdev_cmd.cvp_set_device.tx_topology_id =
1055 get_voice_tx_topology();
1056 if (cvp_setdev_cmd.cvp_set_device.tx_topology_id == 0)
1057 cvp_setdev_cmd.cvp_set_device.tx_topology_id =
1058 VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
1059
1060 cvp_setdev_cmd.cvp_set_device.rx_topology_id =
1061 get_voice_rx_topology();
1062 if (cvp_setdev_cmd.cvp_set_device.rx_topology_id == 0)
1063 cvp_setdev_cmd.cvp_set_device.rx_topology_id =
1064 VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
1065 cvp_setdev_cmd.cvp_set_device.tx_port_id = v->dev_tx.port_id;
1066 cvp_setdev_cmd.cvp_set_device.rx_port_id = v->dev_rx.port_id;
1067 pr_debug("topology=%d , tx_port_id=%d, rx_port_id=%d\n",
1068 cvp_setdev_cmd.cvp_set_device.tx_topology_id,
1069 cvp_setdev_cmd.cvp_set_device.tx_port_id,
1070 cvp_setdev_cmd.cvp_set_device.rx_port_id);
1071
1072 v->cvp_state = CMD_STATUS_FAIL;
1073 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_setdev_cmd);
1074 if (ret < 0) {
1075 pr_err("Fail in sending VOCPROC_FULL_CONTROL_SESSION\n");
1076 goto fail;
1077 }
1078 pr_debug("wait for cvp create session event\n");
1079 ret = wait_event_timeout(v->cvp_wait,
1080 (v->cvp_state == CMD_STATUS_SUCCESS),
1081 msecs_to_jiffies(TIMEOUT_MS));
1082 if (!ret) {
1083 pr_err("%s: wait_event timeout\n", __func__);
1084 goto fail;
1085 }
1086
1087 return 0;
1088fail:
1089 return -EINVAL;
1090}
1091
1092static int voice_send_stop_voice_cmd(struct voice_data *v)
1093{
1094 struct apr_hdr mvm_stop_voice_cmd;
1095 int ret = 0;
1096 void *apr_mvm;
1097 u16 mvm_handle;
1098
1099 if (v == NULL) {
1100 pr_err("%s: v is NULL\n", __func__);
1101 return -EINVAL;
1102 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001103 apr_mvm = common.apr_q6_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001104
1105 if (!apr_mvm) {
1106 pr_err("%s: apr_mvm is NULL.\n", __func__);
1107 return -EINVAL;
1108 }
1109 mvm_handle = voice_get_mvm_handle(v);
1110
1111 mvm_stop_voice_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1112 APR_HDR_LEN(APR_HDR_SIZE),
1113 APR_PKT_VER);
1114 mvm_stop_voice_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1115 sizeof(mvm_stop_voice_cmd) - APR_HDR_SIZE);
1116 pr_debug("send mvm_stop_voice_cmd pkt size = %d\n",
1117 mvm_stop_voice_cmd.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001118 mvm_stop_voice_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001119 mvm_stop_voice_cmd.dest_port = mvm_handle;
1120 mvm_stop_voice_cmd.token = 0;
1121 mvm_stop_voice_cmd.opcode = VSS_IMVM_CMD_STOP_VOICE;
1122
1123 v->mvm_state = CMD_STATUS_FAIL;
1124 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_stop_voice_cmd);
1125 if (ret < 0) {
1126 pr_err("Fail in sending VSS_IMVM_CMD_STOP_VOICE\n");
1127 goto fail;
1128 }
1129 ret = wait_event_timeout(v->mvm_wait,
1130 (v->mvm_state == CMD_STATUS_SUCCESS),
1131 msecs_to_jiffies(TIMEOUT_MS));
1132 if (!ret) {
1133 pr_err("%s: wait_event timeout\n", __func__);
1134 goto fail;
1135 }
1136
1137 return 0;
1138fail:
1139 return -EINVAL;
1140}
1141
Helen Zeng29eb7442011-06-20 11:06:29 -07001142static int voice_send_cvs_register_cal_cmd(struct voice_data *v)
1143{
1144 struct cvs_register_cal_data_cmd cvs_reg_cal_cmd;
1145 struct acdb_cal_block cal_block;
1146 int ret = 0;
1147 void *apr_cvs;
1148 u16 cvs_handle;
1149
1150 /* get the cvs cal data */
1151 get_all_vocstrm_cal(&cal_block);
1152 if (cal_block.cal_size == 0)
1153 goto fail;
1154
1155 if (v == NULL) {
1156 pr_err("%s: v is NULL\n", __func__);
1157 return -EINVAL;
1158 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001159 apr_cvs = common.apr_q6_cvs;
Helen Zeng29eb7442011-06-20 11:06:29 -07001160
1161 if (!apr_cvs) {
1162 pr_err("%s: apr_cvs is NULL.\n", __func__);
1163 return -EINVAL;
1164 }
1165 cvs_handle = voice_get_cvs_handle(v);
1166
1167 /* fill in the header */
1168 cvs_reg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1169 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1170 cvs_reg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1171 sizeof(cvs_reg_cal_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001172 cvs_reg_cal_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001173 cvs_reg_cal_cmd.hdr.dest_port = cvs_handle;
1174 cvs_reg_cal_cmd.hdr.token = 0;
1175 cvs_reg_cal_cmd.hdr.opcode = VSS_ISTREAM_CMD_REGISTER_CALIBRATION_DATA;
1176
1177 cvs_reg_cal_cmd.cvs_cal_data.phys_addr = cal_block.cal_paddr;
1178 cvs_reg_cal_cmd.cvs_cal_data.mem_size = cal_block.cal_size;
1179
1180 v->cvs_state = CMD_STATUS_FAIL;
1181 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_reg_cal_cmd);
1182 if (ret < 0) {
1183 pr_err("Fail: sending cvs cal,\n");
1184 goto fail;
1185 }
1186 ret = wait_event_timeout(v->cvs_wait,
1187 (v->cvs_state == CMD_STATUS_SUCCESS),
1188 msecs_to_jiffies(TIMEOUT_MS));
1189 if (!ret) {
1190 pr_err("%s: wait_event timeout\n", __func__);
1191 goto fail;
1192 }
1193 return 0;
1194fail:
1195 return -EINVAL;
1196
1197}
1198
1199static int voice_send_cvs_deregister_cal_cmd(struct voice_data *v)
1200{
1201 struct cvs_deregister_cal_data_cmd cvs_dereg_cal_cmd;
1202 struct acdb_cal_block cal_block;
1203 int ret = 0;
1204 void *apr_cvs;
1205 u16 cvs_handle;
1206
1207 get_all_vocstrm_cal(&cal_block);
1208 if (cal_block.cal_size == 0)
1209 return 0;
1210
1211 if (v == NULL) {
1212 pr_err("%s: v is NULL\n", __func__);
1213 return -EINVAL;
1214 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001215 apr_cvs = common.apr_q6_cvs;
Helen Zeng29eb7442011-06-20 11:06:29 -07001216
1217 if (!apr_cvs) {
1218 pr_err("%s: apr_cvs is NULL.\n", __func__);
1219 return -EINVAL;
1220 }
1221 cvs_handle = voice_get_cvs_handle(v);
1222
1223 /* fill in the header */
1224 cvs_dereg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1225 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1226 cvs_dereg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1227 sizeof(cvs_dereg_cal_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001228 cvs_dereg_cal_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001229 cvs_dereg_cal_cmd.hdr.dest_port = cvs_handle;
1230 cvs_dereg_cal_cmd.hdr.token = 0;
1231 cvs_dereg_cal_cmd.hdr.opcode =
1232 VSS_ISTREAM_CMD_DEREGISTER_CALIBRATION_DATA;
1233
1234 v->cvs_state = CMD_STATUS_FAIL;
1235 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_dereg_cal_cmd);
1236 if (ret < 0) {
1237 pr_err("Fail: sending cvs cal,\n");
1238 goto fail;
1239 }
1240 ret = wait_event_timeout(v->cvs_wait,
1241 (v->cvs_state == CMD_STATUS_SUCCESS),
1242 msecs_to_jiffies(TIMEOUT_MS));
1243 if (!ret) {
1244 pr_err("%s: wait_event timeout\n", __func__);
1245 goto fail;
1246 }
1247 return 0;
1248fail:
1249 return -EINVAL;
1250
1251}
1252
1253static int voice_send_cvp_map_memory_cmd(struct voice_data *v)
1254{
1255 struct vss_map_memory_cmd cvp_map_mem_cmd;
1256 struct acdb_cal_block cal_block;
1257 int ret = 0;
1258 void *apr_cvp;
1259 u16 cvp_handle;
1260
1261 /* get all cvp cal data */
1262 get_all_cvp_cal(&cal_block);
1263 if (cal_block.cal_size == 0)
1264 goto fail;
1265
1266 if (v == NULL) {
1267 pr_err("%s: v is NULL\n", __func__);
1268 return -EINVAL;
1269 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001270 apr_cvp = common.apr_q6_cvp;
Helen Zeng29eb7442011-06-20 11:06:29 -07001271
1272 if (!apr_cvp) {
1273 pr_err("%s: apr_cvp is NULL.\n", __func__);
1274 return -EINVAL;
1275 }
1276 cvp_handle = voice_get_cvp_handle(v);
1277
1278 /* fill in the header */
1279 cvp_map_mem_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1280 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1281 cvp_map_mem_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1282 sizeof(cvp_map_mem_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001283 cvp_map_mem_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001284 cvp_map_mem_cmd.hdr.dest_port = cvp_handle;
1285 cvp_map_mem_cmd.hdr.token = 0;
1286 cvp_map_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_MAP_MEMORY;
1287
1288 pr_debug("%s, phy_addr:%d, mem_size:%d\n", __func__,
1289 cal_block.cal_paddr, cal_block.cal_size);
1290 cvp_map_mem_cmd.vss_map_mem.phys_addr = cal_block.cal_paddr;
1291 cvp_map_mem_cmd.vss_map_mem.mem_size = cal_block.cal_size;
1292 cvp_map_mem_cmd.vss_map_mem.mem_pool_id =
1293 VSS_ICOMMON_MAP_MEMORY_SHMEM8_4K_POOL;
1294
1295 v->cvp_state = CMD_STATUS_FAIL;
1296 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_map_mem_cmd);
1297 if (ret < 0) {
1298 pr_err("Fail: sending cvp cal,\n");
1299 goto fail;
1300 }
1301 ret = wait_event_timeout(v->cvp_wait,
1302 (v->cvp_state == CMD_STATUS_SUCCESS),
1303 msecs_to_jiffies(TIMEOUT_MS));
1304 if (!ret) {
1305 pr_err("%s: wait_event timeout\n", __func__);
1306 goto fail;
1307 }
1308 return 0;
1309fail:
1310 return -EINVAL;
1311
1312}
1313
1314static int voice_send_cvp_unmap_memory_cmd(struct voice_data *v)
1315{
1316 struct vss_unmap_memory_cmd cvp_unmap_mem_cmd;
1317 struct acdb_cal_block cal_block;
1318 int ret = 0;
1319 void *apr_cvp;
1320 u16 cvp_handle;
1321
1322 get_all_cvp_cal(&cal_block);
1323 if (cal_block.cal_size == 0)
1324 return 0;
1325
1326 if (v == NULL) {
1327 pr_err("%s: v is NULL\n", __func__);
1328 return -EINVAL;
1329 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001330 apr_cvp = common.apr_q6_cvp;
Helen Zeng29eb7442011-06-20 11:06:29 -07001331
1332 if (!apr_cvp) {
1333 pr_err("%s: apr_cvp is NULL.\n", __func__);
1334 return -EINVAL;
1335 }
1336 cvp_handle = voice_get_cvp_handle(v);
1337
1338 /* fill in the header */
1339 cvp_unmap_mem_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1340 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1341 cvp_unmap_mem_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1342 sizeof(cvp_unmap_mem_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001343 cvp_unmap_mem_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001344 cvp_unmap_mem_cmd.hdr.dest_port = cvp_handle;
1345 cvp_unmap_mem_cmd.hdr.token = 0;
1346 cvp_unmap_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_UNMAP_MEMORY;
1347
1348 cvp_unmap_mem_cmd.vss_unmap_mem.phys_addr = cal_block.cal_paddr;
1349
1350 v->cvp_state = CMD_STATUS_FAIL;
1351 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_unmap_mem_cmd);
1352 if (ret < 0) {
1353 pr_err("Fail: sending cvp cal,\n");
1354 goto fail;
1355 }
1356 ret = wait_event_timeout(v->cvp_wait,
1357 (v->cvp_state == CMD_STATUS_SUCCESS),
1358 msecs_to_jiffies(TIMEOUT_MS));
1359 if (!ret) {
1360 pr_err("%s: wait_event timeout\n", __func__);
1361 goto fail;
1362 }
1363 return 0;
1364fail:
1365 return -EINVAL;
1366
1367}
1368
1369static int voice_send_cvs_map_memory_cmd(struct voice_data *v)
1370{
1371 struct vss_map_memory_cmd cvs_map_mem_cmd;
1372 struct acdb_cal_block cal_block;
1373 int ret = 0;
1374 void *apr_cvs;
1375 u16 cvs_handle;
1376
1377 /* get all cvs cal data */
1378 get_all_vocstrm_cal(&cal_block);
1379 if (cal_block.cal_size == 0)
1380 goto fail;
1381
1382 if (v == NULL) {
1383 pr_err("%s: v is NULL\n", __func__);
1384 return -EINVAL;
1385 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001386 apr_cvs = common.apr_q6_cvs;
Helen Zeng29eb7442011-06-20 11:06:29 -07001387
1388 if (!apr_cvs) {
1389 pr_err("%s: apr_cvs is NULL.\n", __func__);
1390 return -EINVAL;
1391 }
1392 cvs_handle = voice_get_cvs_handle(v);
1393
1394 /* fill in the header */
1395 cvs_map_mem_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1396 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1397 cvs_map_mem_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1398 sizeof(cvs_map_mem_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001399 cvs_map_mem_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001400 cvs_map_mem_cmd.hdr.dest_port = cvs_handle;
1401 cvs_map_mem_cmd.hdr.token = 0;
1402 cvs_map_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_MAP_MEMORY;
1403
1404 pr_debug("%s, phys_addr: %d, mem_size: %d\n", __func__,
1405 cal_block.cal_paddr, cal_block.cal_size);
1406 cvs_map_mem_cmd.vss_map_mem.phys_addr = cal_block.cal_paddr;
1407 cvs_map_mem_cmd.vss_map_mem.mem_size = cal_block.cal_size;
1408 cvs_map_mem_cmd.vss_map_mem.mem_pool_id =
1409 VSS_ICOMMON_MAP_MEMORY_SHMEM8_4K_POOL;
1410
1411 v->cvs_state = CMD_STATUS_FAIL;
1412 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_map_mem_cmd);
1413 if (ret < 0) {
1414 pr_err("Fail: sending cvs cal,\n");
1415 goto fail;
1416 }
1417 ret = wait_event_timeout(v->cvs_wait,
1418 (v->cvs_state == CMD_STATUS_SUCCESS),
1419 msecs_to_jiffies(TIMEOUT_MS));
1420 if (!ret) {
1421 pr_err("%s: wait_event timeout\n", __func__);
1422 goto fail;
1423 }
1424 return 0;
1425fail:
1426 return -EINVAL;
1427
1428}
1429
1430static int voice_send_cvs_unmap_memory_cmd(struct voice_data *v)
1431{
1432 struct vss_unmap_memory_cmd cvs_unmap_mem_cmd;
1433 struct acdb_cal_block cal_block;
1434 int ret = 0;
1435 void *apr_cvs;
1436 u16 cvs_handle;
1437
1438 get_all_vocstrm_cal(&cal_block);
1439 if (cal_block.cal_size == 0)
1440 return 0;
1441
1442 if (v == NULL) {
1443 pr_err("%s: v is NULL\n", __func__);
1444 return -EINVAL;
1445 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001446 apr_cvs = common.apr_q6_cvs;
Helen Zeng29eb7442011-06-20 11:06:29 -07001447
1448 if (!apr_cvs) {
1449 pr_err("%s: apr_cvs is NULL.\n", __func__);
1450 return -EINVAL;
1451 }
1452 cvs_handle = voice_get_cvs_handle(v);
1453
1454 /* fill in the header */
1455 cvs_unmap_mem_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1456 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1457 cvs_unmap_mem_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1458 sizeof(cvs_unmap_mem_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001459 cvs_unmap_mem_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001460 cvs_unmap_mem_cmd.hdr.dest_port = cvs_handle;
1461 cvs_unmap_mem_cmd.hdr.token = 0;
1462 cvs_unmap_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_UNMAP_MEMORY;
1463
1464 cvs_unmap_mem_cmd.vss_unmap_mem.phys_addr = cal_block.cal_paddr;
1465
1466 v->cvs_state = CMD_STATUS_FAIL;
1467 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_unmap_mem_cmd);
1468 if (ret < 0) {
1469 pr_err("Fail: sending cvs cal,\n");
1470 goto fail;
1471 }
1472 ret = wait_event_timeout(v->cvs_wait,
1473 (v->cvs_state == CMD_STATUS_SUCCESS),
1474 msecs_to_jiffies(TIMEOUT_MS));
1475 if (!ret) {
1476 pr_err("%s: wait_event timeout\n", __func__);
1477 goto fail;
1478 }
1479 return 0;
1480fail:
1481 return -EINVAL;
1482
1483}
1484
1485static int voice_send_cvp_register_cal_cmd(struct voice_data *v)
1486{
1487 struct cvp_register_cal_data_cmd cvp_reg_cal_cmd;
1488 struct acdb_cal_block cal_block;
1489 int ret = 0;
1490 void *apr_cvp;
1491 u16 cvp_handle;
1492
1493 /* get the cvp cal data */
1494 get_all_vocproc_cal(&cal_block);
1495 if (cal_block.cal_size == 0)
1496 goto fail;
1497
1498 if (v == NULL) {
1499 pr_err("%s: v is NULL\n", __func__);
1500 return -EINVAL;
1501 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001502 apr_cvp = common.apr_q6_cvp;
Helen Zeng29eb7442011-06-20 11:06:29 -07001503
1504 if (!apr_cvp) {
1505 pr_err("%s: apr_cvp is NULL.\n", __func__);
1506 return -EINVAL;
1507 }
1508 cvp_handle = voice_get_cvp_handle(v);
1509
1510 /* fill in the header */
1511 cvp_reg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1512 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1513 cvp_reg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1514 sizeof(cvp_reg_cal_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001515 cvp_reg_cal_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001516 cvp_reg_cal_cmd.hdr.dest_port = cvp_handle;
1517 cvp_reg_cal_cmd.hdr.token = 0;
1518 cvp_reg_cal_cmd.hdr.opcode = VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA;
1519
1520 cvp_reg_cal_cmd.cvp_cal_data.phys_addr = cal_block.cal_paddr;
1521 cvp_reg_cal_cmd.cvp_cal_data.mem_size = cal_block.cal_size;
1522
1523 v->cvp_state = CMD_STATUS_FAIL;
1524 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_reg_cal_cmd);
1525 if (ret < 0) {
1526 pr_err("Fail: sending cvp cal,\n");
1527 goto fail;
1528 }
1529 ret = wait_event_timeout(v->cvp_wait,
1530 (v->cvp_state == CMD_STATUS_SUCCESS),
1531 msecs_to_jiffies(TIMEOUT_MS));
1532 if (!ret) {
1533 pr_err("%s: wait_event timeout\n", __func__);
1534 goto fail;
1535 }
1536 return 0;
1537fail:
1538 return -EINVAL;
1539
1540}
1541
1542static int voice_send_cvp_deregister_cal_cmd(struct voice_data *v)
1543{
1544 struct cvp_deregister_cal_data_cmd cvp_dereg_cal_cmd;
1545 struct acdb_cal_block cal_block;
1546 int ret = 0;
1547 void *apr_cvp;
1548 u16 cvp_handle;
1549
1550 get_all_vocproc_cal(&cal_block);
1551 if (cal_block.cal_size == 0)
1552 return 0;
1553
1554 if (v == NULL) {
1555 pr_err("%s: v is NULL\n", __func__);
1556 return -EINVAL;
1557 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001558 apr_cvp = common.apr_q6_cvp;
Helen Zeng29eb7442011-06-20 11:06:29 -07001559
1560 if (!apr_cvp) {
1561 pr_err("%s: apr_cvp is NULL.\n", __func__);
1562 return -EINVAL;
1563 }
1564 cvp_handle = voice_get_cvp_handle(v);
1565
1566 /* fill in the header */
1567 cvp_dereg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1568 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1569 cvp_dereg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1570 sizeof(cvp_dereg_cal_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001571 cvp_dereg_cal_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001572 cvp_dereg_cal_cmd.hdr.dest_port = cvp_handle;
1573 cvp_dereg_cal_cmd.hdr.token = 0;
1574 cvp_dereg_cal_cmd.hdr.opcode =
1575 VSS_IVOCPROC_CMD_DEREGISTER_CALIBRATION_DATA;
1576
1577 v->cvp_state = CMD_STATUS_FAIL;
1578 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_dereg_cal_cmd);
1579 if (ret < 0) {
1580 pr_err("Fail: sending cvp cal,\n");
1581 goto fail;
1582 }
1583 ret = wait_event_timeout(v->cvp_wait,
1584 (v->cvp_state == CMD_STATUS_SUCCESS),
1585 msecs_to_jiffies(TIMEOUT_MS));
1586 if (!ret) {
1587 pr_err("%s: wait_event timeout\n", __func__);
1588 goto fail;
1589 }
1590 return 0;
1591fail:
1592 return -EINVAL;
1593
1594}
1595
1596static int voice_send_cvp_register_vol_cal_table_cmd(struct voice_data *v)
1597{
1598 struct cvp_register_vol_cal_table_cmd cvp_reg_cal_tbl_cmd;
1599 struct acdb_cal_block cal_block;
1600 int ret = 0;
1601 void *apr_cvp;
1602 u16 cvp_handle;
1603
1604 /* get the cvp vol cal data */
1605 get_all_vocvol_cal(&cal_block);
1606 if (cal_block.cal_size == 0)
1607 goto fail;
1608
1609 if (v == NULL) {
1610 pr_err("%s: v is NULL\n", __func__);
1611 return -EINVAL;
1612 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001613 apr_cvp = common.apr_q6_cvp;
Helen Zeng29eb7442011-06-20 11:06:29 -07001614
1615 if (!apr_cvp) {
1616 pr_err("%s: apr_cvp is NULL.\n", __func__);
1617 return -EINVAL;
1618 }
1619 cvp_handle = voice_get_cvp_handle(v);
1620
1621 /* fill in the header */
1622 cvp_reg_cal_tbl_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1623 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1624 cvp_reg_cal_tbl_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1625 sizeof(cvp_reg_cal_tbl_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001626 cvp_reg_cal_tbl_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001627 cvp_reg_cal_tbl_cmd.hdr.dest_port = cvp_handle;
1628 cvp_reg_cal_tbl_cmd.hdr.token = 0;
1629 cvp_reg_cal_tbl_cmd.hdr.opcode =
1630 VSS_IVOCPROC_CMD_REGISTER_VOLUME_CAL_TABLE;
1631
1632 cvp_reg_cal_tbl_cmd.cvp_vol_cal_tbl.phys_addr = cal_block.cal_paddr;
1633 cvp_reg_cal_tbl_cmd.cvp_vol_cal_tbl.mem_size = cal_block.cal_size;
1634
1635 v->cvp_state = CMD_STATUS_FAIL;
1636 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_reg_cal_tbl_cmd);
1637 if (ret < 0) {
1638 pr_err("Fail: sending cvp cal table,\n");
1639 goto fail;
1640 }
1641 ret = wait_event_timeout(v->cvp_wait,
1642 (v->cvp_state == CMD_STATUS_SUCCESS),
1643 msecs_to_jiffies(TIMEOUT_MS));
1644 if (!ret) {
1645 pr_err("%s: wait_event timeout\n", __func__);
1646 goto fail;
1647 }
1648 return 0;
1649fail:
1650 return -EINVAL;
1651
1652}
1653
1654static int voice_send_cvp_deregister_vol_cal_table_cmd(struct voice_data *v)
1655{
1656 struct cvp_deregister_vol_cal_table_cmd cvp_dereg_cal_tbl_cmd;
1657 struct acdb_cal_block cal_block;
1658 int ret = 0;
1659 void *apr_cvp;
1660 u16 cvp_handle;
1661
1662 get_all_vocvol_cal(&cal_block);
1663 if (cal_block.cal_size == 0)
1664 return 0;
1665
1666 if (v == NULL) {
1667 pr_err("%s: v is NULL\n", __func__);
1668 return -EINVAL;
1669 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001670 apr_cvp = common.apr_q6_cvp;
Helen Zeng29eb7442011-06-20 11:06:29 -07001671
1672 if (!apr_cvp) {
1673 pr_err("%s: apr_cvp is NULL.\n", __func__);
1674 return -EINVAL;
1675 }
1676 cvp_handle = voice_get_cvp_handle(v);
1677
1678 /* fill in the header */
1679 cvp_dereg_cal_tbl_cmd.hdr.hdr_field = APR_HDR_FIELD(
1680 APR_MSG_TYPE_SEQ_CMD,
1681 APR_HDR_LEN(APR_HDR_SIZE),
1682 APR_PKT_VER);
1683 cvp_dereg_cal_tbl_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1684 sizeof(cvp_dereg_cal_tbl_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001685 cvp_dereg_cal_tbl_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001686 cvp_dereg_cal_tbl_cmd.hdr.dest_port = cvp_handle;
1687 cvp_dereg_cal_tbl_cmd.hdr.token = 0;
1688 cvp_dereg_cal_tbl_cmd.hdr.opcode =
1689 VSS_IVOCPROC_CMD_DEREGISTER_VOLUME_CAL_TABLE;
1690
1691 v->cvp_state = CMD_STATUS_FAIL;
1692 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_dereg_cal_tbl_cmd);
1693 if (ret < 0) {
1694 pr_err("Fail: sending cvp cal table,\n");
1695 goto fail;
1696 }
1697 ret = wait_event_timeout(v->cvp_wait,
1698 (v->cvp_state == CMD_STATUS_SUCCESS),
1699 msecs_to_jiffies(TIMEOUT_MS));
1700 if (!ret) {
1701 pr_err("%s: wait_event timeout\n", __func__);
1702 goto fail;
1703 }
1704 return 0;
1705fail:
1706 return -EINVAL;
1707
1708}
Neema Shetty2c07eb52011-08-21 20:33:52 -07001709
Helen Zeng44d4d272011-08-10 14:49:20 -07001710static int voice_send_set_widevoice_enable_cmd(struct voice_data *v)
1711{
1712 struct mvm_set_widevoice_enable_cmd mvm_set_wv_cmd;
1713 int ret = 0;
1714 void *apr_mvm;
1715 u16 mvm_handle;
1716
1717 if (v == NULL) {
1718 pr_err("%s: v is NULL\n", __func__);
1719 return -EINVAL;
1720 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001721 apr_mvm = common.apr_q6_mvm;
Helen Zeng44d4d272011-08-10 14:49:20 -07001722
1723 if (!apr_mvm) {
1724 pr_err("%s: apr_mvm is NULL.\n", __func__);
1725 return -EINVAL;
1726 }
1727 mvm_handle = voice_get_mvm_handle(v);
1728
1729 /* fill in the header */
1730 mvm_set_wv_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1731 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1732 mvm_set_wv_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1733 sizeof(mvm_set_wv_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001734 mvm_set_wv_cmd.hdr.src_port = v->session_id;
Helen Zeng44d4d272011-08-10 14:49:20 -07001735 mvm_set_wv_cmd.hdr.dest_port = mvm_handle;
1736 mvm_set_wv_cmd.hdr.token = 0;
1737 mvm_set_wv_cmd.hdr.opcode = VSS_IWIDEVOICE_CMD_SET_WIDEVOICE;
1738
1739 mvm_set_wv_cmd.vss_set_wv.enable = v->wv_enable;
1740
1741 v->mvm_state = CMD_STATUS_FAIL;
1742 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_wv_cmd);
1743 if (ret < 0) {
1744 pr_err("Fail: sending mvm set widevoice enable,\n");
1745 goto fail;
1746 }
1747 ret = wait_event_timeout(v->mvm_wait,
1748 (v->mvm_state == CMD_STATUS_SUCCESS),
1749 msecs_to_jiffies(TIMEOUT_MS));
1750 if (!ret) {
1751 pr_err("%s: wait_event timeout\n", __func__);
1752 goto fail;
1753 }
1754 return 0;
1755fail:
1756 return -EINVAL;
1757}
1758
Helen Zengbb49c702011-09-06 14:09:13 -07001759static int voice_send_set_slowtalk_enable_cmd(struct voice_data *v)
1760{
1761 struct cvs_set_slowtalk_enable_cmd cvs_set_st_cmd;
1762 int ret = 0;
1763 void *apr_cvs;
1764 u16 cvs_handle;
1765
1766 if (v == NULL) {
1767 pr_err("%s: v is NULL\n", __func__);
1768 return -EINVAL;
1769 }
1770 apr_cvs = common.apr_q6_cvs;
1771
1772 if (!apr_cvs) {
1773 pr_err("%s: apr_cvs is NULL.\n", __func__);
1774 return -EINVAL;
1775 }
1776 cvs_handle = voice_get_cvs_handle(v);
1777
1778 /* fill in the header */
1779 cvs_set_st_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1780 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1781 cvs_set_st_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1782 sizeof(cvs_set_st_cmd) - APR_HDR_SIZE);
1783 cvs_set_st_cmd.hdr.src_port = v->session_id;
1784 cvs_set_st_cmd.hdr.dest_port = cvs_handle;
1785 cvs_set_st_cmd.hdr.token = 0;
1786 cvs_set_st_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_UI_PROPERTY;
1787
1788 cvs_set_st_cmd.vss_set_st.module_id = MODULE_ID_VOICE_MODULE_ST;
1789 cvs_set_st_cmd.vss_set_st.param_id = VOICE_PARAM_MOD_ENABLE;
1790 cvs_set_st_cmd.vss_set_st.param_size = MOD_ENABLE_PARAM_LEN;
1791 cvs_set_st_cmd.vss_set_st.reserved = 0;
1792 cvs_set_st_cmd.vss_set_st.enable = v->st_enable;
1793 cvs_set_st_cmd.vss_set_st.reserved_field = 0;
1794
1795 v->cvs_state = CMD_STATUS_FAIL;
1796 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_st_cmd);
1797 if (ret < 0) {
1798 pr_err("Fail: sending cvs set slowtalk enable,\n");
1799 goto fail;
1800 }
1801 ret = wait_event_timeout(v->cvs_wait,
1802 (v->cvs_state == CMD_STATUS_SUCCESS),
1803 msecs_to_jiffies(TIMEOUT_MS));
1804 if (!ret) {
1805 pr_err("%s: wait_event timeout\n", __func__);
1806 goto fail;
1807 }
1808 return 0;
1809fail:
1810 return -EINVAL;
1811}
1812
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001813static int voice_setup_vocproc(struct voice_data *v)
1814{
1815 struct cvp_create_full_ctl_session_cmd cvp_session_cmd;
1816 int ret = 0;
1817 void *apr_cvp;
1818 if (v == NULL) {
1819 pr_err("%s: v is NULL\n", __func__);
1820 return -EINVAL;
1821 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001822 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001823
1824 if (!apr_cvp) {
1825 pr_err("%s: apr_cvp is NULL.\n", __func__);
1826 return -EINVAL;
1827 }
1828
1829 /* create cvp session and wait for response */
1830 cvp_session_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1831 APR_HDR_LEN(APR_HDR_SIZE),
1832 APR_PKT_VER);
1833 cvp_session_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1834 sizeof(cvp_session_cmd) - APR_HDR_SIZE);
1835 pr_debug(" send create cvp session, pkt size = %d\n",
1836 cvp_session_cmd.hdr.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001837 cvp_session_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001838 cvp_session_cmd.hdr.dest_port = 0;
1839 cvp_session_cmd.hdr.token = 0;
1840 cvp_session_cmd.hdr.opcode =
1841 VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION;
1842
1843 /* Use default topology if invalid value in ACDB */
1844 cvp_session_cmd.cvp_session.tx_topology_id =
1845 get_voice_tx_topology();
1846 if (cvp_session_cmd.cvp_session.tx_topology_id == 0)
1847 cvp_session_cmd.cvp_session.tx_topology_id =
1848 VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
1849
1850 cvp_session_cmd.cvp_session.rx_topology_id =
1851 get_voice_rx_topology();
1852 if (cvp_session_cmd.cvp_session.rx_topology_id == 0)
1853 cvp_session_cmd.cvp_session.rx_topology_id =
1854 VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
1855
1856 cvp_session_cmd.cvp_session.direction = 2; /*tx and rx*/
1857 cvp_session_cmd.cvp_session.network_id = VSS_NETWORK_ID_DEFAULT;
1858 cvp_session_cmd.cvp_session.tx_port_id = v->dev_tx.port_id;
1859 cvp_session_cmd.cvp_session.rx_port_id = v->dev_rx.port_id;
1860
1861 pr_debug("topology=%d net_id=%d, dir=%d tx_port_id=%d, rx_port_id=%d\n",
1862 cvp_session_cmd.cvp_session.tx_topology_id,
1863 cvp_session_cmd.cvp_session.network_id,
1864 cvp_session_cmd.cvp_session.direction,
1865 cvp_session_cmd.cvp_session.tx_port_id,
1866 cvp_session_cmd.cvp_session.rx_port_id);
1867
1868 v->cvp_state = CMD_STATUS_FAIL;
1869 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_session_cmd);
1870 if (ret < 0) {
1871 pr_err("Fail in sending VOCPROC_FULL_CONTROL_SESSION\n");
1872 goto fail;
1873 }
1874 ret = wait_event_timeout(v->cvp_wait,
1875 (v->cvp_state == CMD_STATUS_SUCCESS),
1876 msecs_to_jiffies(TIMEOUT_MS));
1877 if (!ret) {
1878 pr_err("%s: wait_event timeout\n", __func__);
1879 goto fail;
1880 }
1881
Helen Zeng29eb7442011-06-20 11:06:29 -07001882 /* send cvs cal */
1883 ret = voice_send_cvs_map_memory_cmd(v);
1884 if (!ret)
1885 voice_send_cvs_register_cal_cmd(v);
1886
1887 /* send cvp and vol cal */
1888 ret = voice_send_cvp_map_memory_cmd(v);
1889 if (!ret) {
1890 voice_send_cvp_register_cal_cmd(v);
1891 voice_send_cvp_register_vol_cal_table_cmd(v);
1892 }
1893
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001894 /* enable vocproc */
1895 ret = voice_send_enable_vocproc_cmd(v);
1896 if (ret < 0)
1897 goto fail;
1898
1899 /* attach vocproc */
1900 ret = voice_send_attach_vocproc_cmd(v);
1901 if (ret < 0)
1902 goto fail;
1903
1904 /* send tty mode if tty device is used */
1905 voice_send_tty_mode_cmd(v);
1906
Helen Zeng44d4d272011-08-10 14:49:20 -07001907 /* enable widevoice if wv_enable is set */
1908 if (v->wv_enable)
1909 voice_send_set_widevoice_enable_cmd(v);
1910
Helen Zengbb49c702011-09-06 14:09:13 -07001911 /* enable slowtalk if st_enable is set */
1912 if (v->st_enable)
1913 voice_send_set_slowtalk_enable_cmd(v);
1914
Neema Shetty2c07eb52011-08-21 20:33:52 -07001915 if (is_voip_session(v->session_id))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001916 voice_send_netid_timing_cmd(v);
1917
Ben Romberger13b74ab2011-07-18 17:36:32 -07001918 rtac_add_voice(voice_get_cvs_handle(v),
1919 voice_get_cvp_handle(v),
Ben Rombergerc5d6a372011-09-22 18:01:49 -07001920 v->dev_rx.port_id, v->dev_tx.port_id,
1921 v->session_id);
Ben Romberger13b74ab2011-07-18 17:36:32 -07001922
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001923 return 0;
1924
1925fail:
1926 return -EINVAL;
1927}
1928
1929static int voice_send_enable_vocproc_cmd(struct voice_data *v)
1930{
1931 int ret = 0;
1932 struct apr_hdr cvp_enable_cmd;
1933 void *apr_cvp;
1934 u16 cvp_handle;
1935
1936 if (v == NULL) {
1937 pr_err("%s: v is NULL\n", __func__);
1938 return -EINVAL;
1939 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001940 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001941
1942 if (!apr_cvp) {
1943 pr_err("%s: apr_cvp is NULL.\n", __func__);
1944 return -EINVAL;
1945 }
1946 cvp_handle = voice_get_cvp_handle(v);
1947
1948 /* enable vocproc and wait for respose */
1949 cvp_enable_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1950 APR_HDR_LEN(APR_HDR_SIZE),
1951 APR_PKT_VER);
1952 cvp_enable_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1953 sizeof(cvp_enable_cmd) - APR_HDR_SIZE);
1954 pr_debug("cvp_enable_cmd pkt size = %d, cvp_handle=%d\n",
1955 cvp_enable_cmd.pkt_size, cvp_handle);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001956 cvp_enable_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001957 cvp_enable_cmd.dest_port = cvp_handle;
1958 cvp_enable_cmd.token = 0;
1959 cvp_enable_cmd.opcode = VSS_IVOCPROC_CMD_ENABLE;
1960
1961 v->cvp_state = CMD_STATUS_FAIL;
1962 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_enable_cmd);
1963 if (ret < 0) {
1964 pr_err("Fail in sending VSS_IVOCPROC_CMD_ENABLE\n");
1965 goto fail;
1966 }
1967 ret = wait_event_timeout(v->cvp_wait,
1968 (v->cvp_state == CMD_STATUS_SUCCESS),
1969 msecs_to_jiffies(TIMEOUT_MS));
1970 if (!ret) {
1971 pr_err("%s: wait_event timeout\n", __func__);
1972 goto fail;
1973 }
1974
1975 return 0;
1976fail:
1977 return -EINVAL;
1978}
1979
1980static int voice_send_netid_timing_cmd(struct voice_data *v)
1981{
1982 int ret = 0;
1983 void *apr_mvm;
1984 u16 mvm_handle;
1985 struct mvm_set_network_cmd mvm_set_network;
1986 struct mvm_set_voice_timing_cmd mvm_set_voice_timing;
1987
1988 if (v == NULL) {
1989 pr_err("%s: v is NULL\n", __func__);
1990 return -EINVAL;
1991 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001992 apr_mvm = common.apr_q6_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001993
1994 if (!apr_mvm) {
1995 pr_err("%s: apr_mvm is NULL.\n", __func__);
1996 return -EINVAL;
1997 }
1998 mvm_handle = voice_get_mvm_handle(v);
1999
2000 ret = voice_config_cvs_vocoder(v);
2001 if (ret < 0) {
2002 pr_err("%s: Error %d configuring CVS voc",
2003 __func__, ret);
2004 goto fail;
2005 }
2006 /* Set network ID. */
2007 pr_debug("Setting network ID\n");
2008
2009 mvm_set_network.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2010 APR_HDR_LEN(APR_HDR_SIZE),
2011 APR_PKT_VER);
2012 mvm_set_network.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2013 sizeof(mvm_set_network) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002014 mvm_set_network.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002015 mvm_set_network.hdr.dest_port = mvm_handle;
2016 mvm_set_network.hdr.token = 0;
2017 mvm_set_network.hdr.opcode = VSS_ICOMMON_CMD_SET_NETWORK;
Neema Shetty2c07eb52011-08-21 20:33:52 -07002018 mvm_set_network.network.network_id = common.mvs_info.network_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002019
2020 v->mvm_state = CMD_STATUS_FAIL;
2021 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_network);
2022 if (ret < 0) {
2023 pr_err("%s: Error %d sending SET_NETWORK\n", __func__, ret);
2024 goto fail;
2025 }
2026
2027 ret = wait_event_timeout(v->mvm_wait,
2028 (v->mvm_state == CMD_STATUS_SUCCESS),
2029 msecs_to_jiffies(TIMEOUT_MS));
2030 if (!ret) {
2031 pr_err("%s: wait_event timeout\n", __func__);
2032 goto fail;
2033 }
2034
2035 /* Set voice timing. */
2036 pr_debug("Setting voice timing\n");
2037
2038 mvm_set_voice_timing.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2039 APR_HDR_LEN(APR_HDR_SIZE),
2040 APR_PKT_VER);
2041 mvm_set_voice_timing.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2042 sizeof(mvm_set_voice_timing) -
2043 APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002044 mvm_set_voice_timing.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002045 mvm_set_voice_timing.hdr.dest_port = mvm_handle;
2046 mvm_set_voice_timing.hdr.token = 0;
2047 mvm_set_voice_timing.hdr.opcode = VSS_ICOMMON_CMD_SET_VOICE_TIMING;
2048 mvm_set_voice_timing.timing.mode = 0;
2049 mvm_set_voice_timing.timing.enc_offset = 8000;
2050 mvm_set_voice_timing.timing.dec_req_offset = 3300;
2051 mvm_set_voice_timing.timing.dec_offset = 8300;
2052
2053 v->mvm_state = CMD_STATUS_FAIL;
2054
2055 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_voice_timing);
2056 if (ret < 0) {
2057 pr_err("%s: Error %d sending SET_TIMING\n", __func__, ret);
2058 goto fail;
2059 }
2060
2061 ret = wait_event_timeout(v->mvm_wait,
2062 (v->mvm_state == CMD_STATUS_SUCCESS),
2063 msecs_to_jiffies(TIMEOUT_MS));
2064 if (!ret) {
2065 pr_err("%s: wait_event timeout\n", __func__);
2066 goto fail;
2067 }
2068
2069 return 0;
2070fail:
2071 return -EINVAL;
2072}
2073
2074static int voice_send_attach_vocproc_cmd(struct voice_data *v)
2075{
2076 int ret = 0;
2077 struct mvm_attach_vocproc_cmd mvm_a_vocproc_cmd;
2078 void *apr_mvm;
2079 u16 mvm_handle, cvp_handle;
2080
2081 if (v == NULL) {
2082 pr_err("%s: v is NULL\n", __func__);
2083 return -EINVAL;
2084 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07002085 apr_mvm = common.apr_q6_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002086
2087 if (!apr_mvm) {
2088 pr_err("%s: apr_mvm is NULL.\n", __func__);
2089 return -EINVAL;
2090 }
2091 mvm_handle = voice_get_mvm_handle(v);
2092 cvp_handle = voice_get_cvp_handle(v);
2093
2094 /* attach vocproc and wait for response */
2095 mvm_a_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2096 APR_HDR_LEN(APR_HDR_SIZE),
2097 APR_PKT_VER);
2098 mvm_a_vocproc_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2099 sizeof(mvm_a_vocproc_cmd) - APR_HDR_SIZE);
2100 pr_debug("send mvm_a_vocproc_cmd pkt size = %d\n",
2101 mvm_a_vocproc_cmd.hdr.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002102 mvm_a_vocproc_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002103 mvm_a_vocproc_cmd.hdr.dest_port = mvm_handle;
2104 mvm_a_vocproc_cmd.hdr.token = 0;
Helen Zeng69b00962011-07-08 11:38:36 -07002105 mvm_a_vocproc_cmd.hdr.opcode = VSS_IMVM_CMD_ATTACH_VOCPROC;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002106 mvm_a_vocproc_cmd.mvm_attach_cvp_handle.handle = cvp_handle;
2107
2108 v->mvm_state = CMD_STATUS_FAIL;
2109 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_a_vocproc_cmd);
2110 if (ret < 0) {
Helen Zeng69b00962011-07-08 11:38:36 -07002111 pr_err("Fail in sending VSS_IMVM_CMD_ATTACH_VOCPROC\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002112 goto fail;
2113 }
2114 ret = wait_event_timeout(v->mvm_wait,
2115 (v->mvm_state == CMD_STATUS_SUCCESS),
2116 msecs_to_jiffies(TIMEOUT_MS));
2117 if (!ret) {
2118 pr_err("%s: wait_event timeout\n", __func__);
2119 goto fail;
2120 }
2121
2122 return 0;
2123fail:
2124 return -EINVAL;
2125}
2126
2127static int voice_destroy_vocproc(struct voice_data *v)
2128{
2129 struct mvm_detach_vocproc_cmd mvm_d_vocproc_cmd;
2130 struct apr_hdr cvp_destroy_session_cmd;
2131 int ret = 0;
2132 void *apr_mvm, *apr_cvp;
2133 u16 mvm_handle, cvp_handle;
2134
2135 if (v == NULL) {
2136 pr_err("%s: v is NULL\n", __func__);
2137 return -EINVAL;
2138 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07002139 apr_mvm = common.apr_q6_mvm;
2140 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002141
2142 if (!apr_mvm || !apr_cvp) {
2143 pr_err("%s: apr_mvm or apr_cvp is NULL.\n", __func__);
2144 return -EINVAL;
2145 }
2146 mvm_handle = voice_get_mvm_handle(v);
2147 cvp_handle = voice_get_cvp_handle(v);
2148
2149 /* send stop voice cmd */
2150 voice_send_stop_voice_cmd(v);
2151
2152 /* detach VOCPROC and wait for response from mvm */
2153 mvm_d_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2154 APR_HDR_LEN(APR_HDR_SIZE),
2155 APR_PKT_VER);
2156 mvm_d_vocproc_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2157 sizeof(mvm_d_vocproc_cmd) - APR_HDR_SIZE);
2158 pr_debug("mvm_d_vocproc_cmd pkt size = %d\n",
2159 mvm_d_vocproc_cmd.hdr.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002160 mvm_d_vocproc_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002161 mvm_d_vocproc_cmd.hdr.dest_port = mvm_handle;
2162 mvm_d_vocproc_cmd.hdr.token = 0;
Helen Zeng69b00962011-07-08 11:38:36 -07002163 mvm_d_vocproc_cmd.hdr.opcode = VSS_IMVM_CMD_DETACH_VOCPROC;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002164 mvm_d_vocproc_cmd.mvm_detach_cvp_handle.handle = cvp_handle;
2165
2166 v->mvm_state = CMD_STATUS_FAIL;
2167 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_d_vocproc_cmd);
2168 if (ret < 0) {
Helen Zeng69b00962011-07-08 11:38:36 -07002169 pr_err("Fail in sending VSS_IMVM_CMD_DETACH_VOCPROC\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002170 goto fail;
2171 }
2172 ret = wait_event_timeout(v->mvm_wait,
2173 (v->mvm_state == CMD_STATUS_SUCCESS),
2174 msecs_to_jiffies(TIMEOUT_MS));
2175 if (!ret) {
2176 pr_err("%s: wait_event timeout\n", __func__);
2177 goto fail;
2178 }
2179
Helen Zeng29eb7442011-06-20 11:06:29 -07002180 /* deregister cvp and vol cal */
2181 voice_send_cvp_deregister_vol_cal_table_cmd(v);
2182 voice_send_cvp_deregister_cal_cmd(v);
2183 voice_send_cvp_unmap_memory_cmd(v);
2184
2185 /* deregister cvs cal */
2186 voice_send_cvs_deregister_cal_cmd(v);
2187 voice_send_cvs_unmap_memory_cmd(v);
2188
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002189 /* destrop cvp session */
2190 cvp_destroy_session_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2191 APR_HDR_LEN(APR_HDR_SIZE),
2192 APR_PKT_VER);
2193 cvp_destroy_session_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2194 sizeof(cvp_destroy_session_cmd) - APR_HDR_SIZE);
2195 pr_debug("cvp_destroy_session_cmd pkt size = %d\n",
2196 cvp_destroy_session_cmd.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002197 cvp_destroy_session_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002198 cvp_destroy_session_cmd.dest_port = cvp_handle;
2199 cvp_destroy_session_cmd.token = 0;
2200 cvp_destroy_session_cmd.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
2201
2202 v->cvp_state = CMD_STATUS_FAIL;
2203 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_destroy_session_cmd);
2204 if (ret < 0) {
2205 pr_err("Fail in sending APRV2_IBASIC_CMD_DESTROY_SESSION\n");
2206 goto fail;
2207 }
2208 ret = wait_event_timeout(v->cvp_wait,
2209 (v->cvp_state == CMD_STATUS_SUCCESS),
2210 msecs_to_jiffies(TIMEOUT_MS));
2211 if (!ret) {
2212 pr_err("%s: wait_event timeout\n", __func__);
2213 goto fail;
2214 }
2215
Ben Romberger13b74ab2011-07-18 17:36:32 -07002216 rtac_remove_voice(voice_get_cvs_handle(v));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002217 cvp_handle = 0;
2218 voice_set_cvp_handle(v, cvp_handle);
2219
2220 return 0;
2221
2222fail:
2223 return -EINVAL;
2224}
2225
2226static int voice_send_mute_cmd(struct voice_data *v)
2227{
2228 struct cvs_set_mute_cmd cvs_mute_cmd;
2229 int ret = 0;
2230 void *apr_cvs;
2231 u16 cvs_handle;
2232
2233 if (v == NULL) {
2234 pr_err("%s: v is NULL\n", __func__);
2235 return -EINVAL;
2236 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07002237 apr_cvs = common.apr_q6_cvs;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002238
2239 if (!apr_cvs) {
2240 pr_err("%s: apr_cvs is NULL.\n", __func__);
2241 return -EINVAL;
2242 }
2243 cvs_handle = voice_get_cvs_handle(v);
2244
2245 /* send mute/unmute to cvs */
2246 cvs_mute_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2247 APR_HDR_LEN(APR_HDR_SIZE),
2248 APR_PKT_VER);
2249 cvs_mute_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2250 sizeof(cvs_mute_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002251 cvs_mute_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002252 cvs_mute_cmd.hdr.dest_port = cvs_handle;
2253 cvs_mute_cmd.hdr.token = 0;
2254 cvs_mute_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_MUTE;
2255 cvs_mute_cmd.cvs_set_mute.direction = 0; /*tx*/
2256 cvs_mute_cmd.cvs_set_mute.mute_flag = v->dev_tx.mute;
2257
2258 pr_info(" mute value =%d\n", cvs_mute_cmd.cvs_set_mute.mute_flag);
2259 v->cvs_state = CMD_STATUS_FAIL;
2260 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_mute_cmd);
2261 if (ret < 0) {
2262 pr_err("Fail: send STREAM SET MUTE\n");
2263 goto fail;
2264 }
2265 ret = wait_event_timeout(v->cvs_wait,
2266 (v->cvs_state == CMD_STATUS_SUCCESS),
2267 msecs_to_jiffies(TIMEOUT_MS));
2268 if (!ret)
2269 pr_err("%s: wait_event timeout\n", __func__);
2270
2271 return 0;
2272fail:
2273 return -EINVAL;
2274}
2275
2276static int voice_send_vol_index_cmd(struct voice_data *v)
2277{
2278 struct cvp_set_rx_volume_index_cmd cvp_vol_cmd;
2279 int ret = 0;
2280 void *apr_cvp;
2281 u16 cvp_handle;
2282 if (v == NULL) {
2283 pr_err("%s: v is NULL\n", __func__);
2284 return -EINVAL;
2285 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07002286 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002287
2288 if (!apr_cvp) {
2289 pr_err("%s: apr_cvp is NULL.\n", __func__);
2290 return -EINVAL;
2291 }
2292 cvp_handle = voice_get_cvp_handle(v);
2293
2294 /* send volume index to cvp */
2295 cvp_vol_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2296 APR_HDR_LEN(APR_HDR_SIZE),
2297 APR_PKT_VER);
2298 cvp_vol_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2299 sizeof(cvp_vol_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002300 cvp_vol_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002301 cvp_vol_cmd.hdr.dest_port = cvp_handle;
2302 cvp_vol_cmd.hdr.token = 0;
2303 cvp_vol_cmd.hdr.opcode = VSS_IVOCPROC_CMD_SET_RX_VOLUME_INDEX;
2304 cvp_vol_cmd.cvp_set_vol_idx.vol_index = v->dev_rx.volume;
2305 v->cvp_state = CMD_STATUS_FAIL;
2306 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_vol_cmd);
2307 if (ret < 0) {
2308 pr_err("Fail in sending RX VOL INDEX\n");
2309 return -EINVAL;
2310 }
2311 ret = wait_event_timeout(v->cvp_wait,
2312 (v->cvp_state == CMD_STATUS_SUCCESS),
2313 msecs_to_jiffies(TIMEOUT_MS));
2314 if (!ret) {
2315 pr_err("%s: wait_event timeout\n", __func__);
2316 return -EINVAL;
2317 }
2318 return 0;
2319}
2320
Neema Shetty2c07eb52011-08-21 20:33:52 -07002321int voc_disable_cvp(uint16_t session_id)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002322{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002323 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002324 int ret = 0;
2325
Neema Shetty2c07eb52011-08-21 20:33:52 -07002326 if (v == NULL) {
2327 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2328
2329 return -EINVAL;
2330 }
2331
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002332 mutex_lock(&v->lock);
2333
2334 if (v->voc_state == VOC_RUN) {
2335 afe_sidetone(v->dev_tx.port_id, v->dev_rx.port_id, 0, 0);
Ben Romberger13b74ab2011-07-18 17:36:32 -07002336
2337 rtac_remove_voice(voice_get_cvs_handle(v));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002338 /* send cmd to dsp to disable vocproc */
2339 ret = voice_send_disable_vocproc_cmd(v);
2340 if (ret < 0) {
2341 pr_err("%s: disable vocproc failed\n", __func__);
2342 goto fail;
2343 }
Helen Zeng29eb7442011-06-20 11:06:29 -07002344
2345 /* deregister cvp and vol cal */
2346 voice_send_cvp_deregister_vol_cal_table_cmd(v);
2347 voice_send_cvp_deregister_cal_cmd(v);
2348 voice_send_cvp_unmap_memory_cmd(v);
2349
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002350 v->voc_state = VOC_CHANGE;
2351 }
2352
2353fail: mutex_unlock(&v->lock);
2354
2355 return ret;
2356}
2357
Neema Shetty2c07eb52011-08-21 20:33:52 -07002358int voc_enable_cvp(uint16_t session_id)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002359{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002360 struct voice_data *v = voice_get_session(session_id);
Helen Zengbd58e2c2011-07-01 16:24:31 -07002361 struct sidetone_cal sidetone_cal_data;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002362 int ret = 0;
2363
Neema Shetty2c07eb52011-08-21 20:33:52 -07002364 if (v == NULL) {
2365 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2366
2367 return -EINVAL;
2368 }
2369
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002370 mutex_lock(&v->lock);
2371
2372 if (v->voc_state == VOC_CHANGE) {
2373 ret = voice_send_set_device_cmd(v);
2374 if (ret < 0) {
2375 pr_err("%s: set device failed\n", __func__);
2376 goto fail;
2377 }
Helen Zeng29eb7442011-06-20 11:06:29 -07002378 /* send cvp and vol cal */
2379 ret = voice_send_cvp_map_memory_cmd(v);
2380 if (!ret) {
2381 voice_send_cvp_register_cal_cmd(v);
2382 voice_send_cvp_register_vol_cal_table_cmd(v);
2383 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002384 ret = voice_send_enable_vocproc_cmd(v);
2385 if (ret < 0) {
Neema Shetty2c07eb52011-08-21 20:33:52 -07002386 pr_err("%s: enable vocproc failed\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002387 goto fail;
Helen Zengcc65b5b2011-07-06 19:14:48 -07002388
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002389 }
Helen Zengcc65b5b2011-07-06 19:14:48 -07002390 /* send tty mode if tty device is used */
2391 voice_send_tty_mode_cmd(v);
2392
Helen Zeng44d4d272011-08-10 14:49:20 -07002393 /* enable widevoice if wv_enable is set */
2394 if (v->wv_enable)
2395 voice_send_set_widevoice_enable_cmd(v);
2396
Helen Zengbb49c702011-09-06 14:09:13 -07002397 /* enable slowtalk */
2398 if (v->st_enable)
2399 voice_send_set_slowtalk_enable_cmd(v);
2400
Helen Zengbd58e2c2011-07-01 16:24:31 -07002401 get_sidetone_cal(&sidetone_cal_data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002402 ret = afe_sidetone(v->dev_tx.port_id, v->dev_rx.port_id,
Helen Zengbd58e2c2011-07-01 16:24:31 -07002403 sidetone_cal_data.enable,
2404 sidetone_cal_data.gain);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002405
2406 if (ret < 0)
Neema Shetty2c07eb52011-08-21 20:33:52 -07002407 pr_err("%s: AFE command sidetone failed\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002408
Ben Romberger13b74ab2011-07-18 17:36:32 -07002409 rtac_add_voice(voice_get_cvs_handle(v),
2410 voice_get_cvp_handle(v),
Ben Rombergerc5d6a372011-09-22 18:01:49 -07002411 v->dev_rx.port_id, v->dev_tx.port_id,
2412 v->session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002413 v->voc_state = VOC_RUN;
2414 }
2415
2416fail:
2417 mutex_unlock(&v->lock);
2418
2419 return ret;
2420}
2421
Neema Shetty2c07eb52011-08-21 20:33:52 -07002422int voc_set_tx_mute(uint16_t session_id, uint32_t dir, uint32_t mute)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002423{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002424 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002425 int ret = 0;
2426
Neema Shetty2c07eb52011-08-21 20:33:52 -07002427 if (v == NULL) {
2428 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2429
2430 return -EINVAL;
2431 }
2432
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002433 mutex_lock(&v->lock);
2434
2435 v->dev_tx.mute = mute;
2436
2437 if (v->voc_state == VOC_RUN)
2438 ret = voice_send_mute_cmd(v);
2439
2440 mutex_unlock(&v->lock);
2441
2442 return ret;
2443}
2444
Neema Shetty2c07eb52011-08-21 20:33:52 -07002445int voc_set_tty_mode(uint16_t session_id, uint8_t tty_mode)
Helen Zengcc65b5b2011-07-06 19:14:48 -07002446{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002447 struct voice_data *v = voice_get_session(session_id);
Helen Zengcc65b5b2011-07-06 19:14:48 -07002448 int ret = 0;
2449
Neema Shetty2c07eb52011-08-21 20:33:52 -07002450 if (v == NULL) {
2451 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2452
2453 return -EINVAL;
2454 }
2455
Helen Zengcc65b5b2011-07-06 19:14:48 -07002456 mutex_lock(&v->lock);
2457
2458 v->tty_mode = tty_mode;
2459
2460 mutex_unlock(&v->lock);
2461
2462 return ret;
2463}
2464
Neema Shetty2c07eb52011-08-21 20:33:52 -07002465uint8_t voc_get_tty_mode(uint16_t session_id)
Helen Zengcc65b5b2011-07-06 19:14:48 -07002466{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002467 struct voice_data *v = voice_get_session(session_id);
Helen Zengcc65b5b2011-07-06 19:14:48 -07002468 int ret = 0;
2469
Neema Shetty2c07eb52011-08-21 20:33:52 -07002470 if (v == NULL) {
2471 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2472
2473 return -EINVAL;
2474 }
2475
Helen Zengcc65b5b2011-07-06 19:14:48 -07002476 mutex_lock(&v->lock);
2477
2478 ret = v->tty_mode;
2479
2480 mutex_unlock(&v->lock);
2481
2482 return ret;
2483}
2484
Neema Shetty2c07eb52011-08-21 20:33:52 -07002485int voc_set_widevoice_enable(uint16_t session_id, uint32_t wv_enable)
Helen Zeng44d4d272011-08-10 14:49:20 -07002486{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002487 struct voice_data *v = voice_get_session(session_id);
Helen Zengb73acce2011-09-15 18:23:01 -07002488 u16 mvm_handle;
Helen Zeng44d4d272011-08-10 14:49:20 -07002489 int ret = 0;
2490
Neema Shetty2c07eb52011-08-21 20:33:52 -07002491 if (v == NULL) {
2492 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2493
2494 return -EINVAL;
2495 }
2496
Helen Zeng44d4d272011-08-10 14:49:20 -07002497 mutex_lock(&v->lock);
2498
2499 v->wv_enable = wv_enable;
2500
Helen Zengb73acce2011-09-15 18:23:01 -07002501 mvm_handle = voice_get_mvm_handle(v);
2502
2503 if (mvm_handle != 0)
2504 voice_send_set_widevoice_enable_cmd(v);
2505
Helen Zeng44d4d272011-08-10 14:49:20 -07002506 mutex_unlock(&v->lock);
2507
2508 return ret;
2509}
2510
Neema Shetty2c07eb52011-08-21 20:33:52 -07002511uint32_t voc_get_widevoice_enable(uint16_t session_id)
Helen Zeng44d4d272011-08-10 14:49:20 -07002512{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002513 struct voice_data *v = voice_get_session(session_id);
Helen Zeng44d4d272011-08-10 14:49:20 -07002514 int ret = 0;
2515
Neema Shetty2c07eb52011-08-21 20:33:52 -07002516 if (v == NULL) {
2517 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2518
2519 return -EINVAL;
2520 }
2521
Helen Zeng44d4d272011-08-10 14:49:20 -07002522 mutex_lock(&v->lock);
2523
2524 ret = v->wv_enable;
2525
2526 mutex_unlock(&v->lock);
2527
2528 return ret;
2529}
2530
Helen Zengbb49c702011-09-06 14:09:13 -07002531int voc_set_slowtalk_enable(uint16_t session_id, uint32_t st_enable)
2532{
2533 struct voice_data *v = voice_get_session(session_id);
2534 int ret = 0;
2535
2536 if (v == NULL) {
2537 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2538
2539 return -EINVAL;
2540 }
2541
2542 mutex_lock(&v->lock);
2543
2544 v->st_enable = st_enable;
2545
2546 if (v->voc_state == VOC_RUN)
2547 ret = voice_send_set_slowtalk_enable_cmd(v);
2548
2549 mutex_unlock(&v->lock);
2550
2551 return ret;
2552}
2553
2554uint32_t voc_get_slowtalk_enable(uint16_t session_id)
2555{
2556 struct voice_data *v = voice_get_session(session_id);
2557 int ret = 0;
2558
2559 if (v == NULL) {
2560 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2561
2562 return -EINVAL;
2563 }
2564
2565 mutex_lock(&v->lock);
2566
2567 ret = v->st_enable;
2568
2569 mutex_unlock(&v->lock);
2570
2571 return ret;
2572}
2573
Neema Shetty2c07eb52011-08-21 20:33:52 -07002574int voc_set_rx_vol_index(uint16_t session_id, uint32_t dir, uint32_t vol_idx)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002575{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002576 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002577 int ret = 0;
2578
Neema Shetty2c07eb52011-08-21 20:33:52 -07002579 if (v == NULL) {
2580 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2581
2582 return -EINVAL;
2583 }
2584
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002585 mutex_lock(&v->lock);
2586
2587 v->dev_rx.volume = vol_idx;
2588
2589 if (v->voc_state == VOC_RUN)
2590 ret = voice_send_vol_index_cmd(v);
2591
2592 mutex_unlock(&v->lock);
2593
2594 return ret;
2595}
2596
Neema Shetty2c07eb52011-08-21 20:33:52 -07002597int voc_set_rxtx_port(uint16_t session_id, uint32_t port_id, uint32_t dev_type)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002598{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002599 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002600
Neema Shetty2c07eb52011-08-21 20:33:52 -07002601 if (v == NULL) {
2602 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2603
2604 return -EINVAL;
2605 }
2606
2607 pr_debug("%s: port_id=%d, type=%d\n", __func__, port_id, dev_type);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002608
2609 mutex_lock(&v->lock);
2610
2611 if (dev_type == DEV_RX)
2612 v->dev_rx.port_id = port_id;
2613 else
2614 v->dev_tx.port_id = port_id;
2615
2616 mutex_unlock(&v->lock);
2617
Neema Shetty2c07eb52011-08-21 20:33:52 -07002618 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002619}
2620
Neema Shetty2c07eb52011-08-21 20:33:52 -07002621int voc_set_route_flag(uint16_t session_id, uint8_t path_dir, uint8_t set)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002622{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002623 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002624
Neema Shetty2c07eb52011-08-21 20:33:52 -07002625 if (v == NULL) {
2626 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2627
2628 return -EINVAL;
2629 }
2630
2631 pr_debug("%s: path_dir=%d, set=%d\n", __func__, path_dir, set);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002632
2633 mutex_lock(&v->lock);
2634
2635 if (path_dir == RX_PATH)
2636 v->voc_route_state.rx_route_flag = set;
2637 else
2638 v->voc_route_state.tx_route_flag = set;
2639
2640 mutex_unlock(&v->lock);
2641
Neema Shetty2c07eb52011-08-21 20:33:52 -07002642 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002643}
2644
Neema Shetty2c07eb52011-08-21 20:33:52 -07002645uint8_t voc_get_route_flag(uint16_t session_id, uint8_t path_dir)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002646{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002647 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002648 int ret = 0;
2649
Neema Shetty2c07eb52011-08-21 20:33:52 -07002650 if (v == NULL) {
2651 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2652
2653 return 0;
2654 }
2655
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002656 mutex_lock(&v->lock);
2657
2658 if (path_dir == RX_PATH)
2659 ret = v->voc_route_state.rx_route_flag;
2660 else
2661 ret = v->voc_route_state.tx_route_flag;
2662
2663 mutex_unlock(&v->lock);
2664
2665 return ret;
2666}
2667
Neema Shetty2c07eb52011-08-21 20:33:52 -07002668int voc_end_voice_call(uint16_t session_id)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002669{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002670 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002671 int ret = 0;
2672
Neema Shetty2c07eb52011-08-21 20:33:52 -07002673 if (v == NULL) {
2674 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2675
2676 return -EINVAL;
2677 }
2678
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002679 mutex_lock(&v->lock);
2680
2681 if (v->voc_state == VOC_RUN) {
Helen Zengbd58e2c2011-07-01 16:24:31 -07002682 afe_sidetone(v->dev_tx.port_id, v->dev_rx.port_id, 0, 0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002683 ret = voice_destroy_vocproc(v);
2684 if (ret < 0)
2685 pr_err("%s: destroy voice failed\n", __func__);
2686 voice_destroy_mvm_cvs_session(v);
2687
2688 v->voc_state = VOC_RELEASE;
2689 }
2690 mutex_unlock(&v->lock);
2691 return ret;
2692}
2693
Neema Shetty2c07eb52011-08-21 20:33:52 -07002694int voc_start_voice_call(uint16_t session_id)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002695{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002696 struct voice_data *v = voice_get_session(session_id);
Helen Zengbd58e2c2011-07-01 16:24:31 -07002697 struct sidetone_cal sidetone_cal_data;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002698 int ret = 0;
2699
Neema Shetty2c07eb52011-08-21 20:33:52 -07002700 if (v == NULL) {
2701 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2702
2703 return -EINVAL;
2704 }
2705
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002706 mutex_lock(&v->lock);
2707
2708 if ((v->voc_state == VOC_INIT) ||
2709 (v->voc_state == VOC_RELEASE)) {
Neema Shetty2c07eb52011-08-21 20:33:52 -07002710 ret = voice_apr_register();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002711 if (ret < 0) {
2712 pr_err("%s: apr register failed\n", __func__);
2713 goto fail;
2714 }
2715 ret = voice_create_mvm_cvs_session(v);
2716 if (ret < 0) {
2717 pr_err("create mvm and cvs failed\n");
2718 goto fail;
2719 }
2720 ret = voice_setup_vocproc(v);
2721 if (ret < 0) {
2722 pr_err("setup voice failed\n");
2723 goto fail;
2724 }
2725 ret = voice_send_start_voice_cmd(v);
2726 if (ret < 0) {
2727 pr_err("start voice failed\n");
2728 goto fail;
2729 }
Helen Zengbd58e2c2011-07-01 16:24:31 -07002730 get_sidetone_cal(&sidetone_cal_data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002731 ret = afe_sidetone(v->dev_tx.port_id,
Helen Zengbd58e2c2011-07-01 16:24:31 -07002732 v->dev_rx.port_id,
2733 sidetone_cal_data.enable,
2734 sidetone_cal_data.gain);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002735 if (ret < 0)
2736 pr_err("AFE command sidetone failed\n");
2737
2738 v->voc_state = VOC_RUN;
2739 }
2740
2741fail: mutex_unlock(&v->lock);
2742 return ret;
2743}
2744
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002745void voc_register_mvs_cb(ul_cb_fn ul_cb,
2746 dl_cb_fn dl_cb,
2747 void *private_data)
2748{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002749 common.mvs_info.ul_cb = ul_cb;
2750 common.mvs_info.dl_cb = dl_cb;
2751 common.mvs_info.private_data = private_data;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002752}
2753
2754void voc_config_vocoder(uint32_t media_type,
2755 uint32_t rate,
2756 uint32_t network_type)
2757{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002758 common.mvs_info.media_type = media_type;
2759 common.mvs_info.rate = rate;
2760 common.mvs_info.network_type = network_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002761}
2762
2763static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv)
2764{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002765 uint32_t *ptr = NULL;
2766 struct common_data *c = NULL;
2767 struct voice_data *v = NULL;
Neema Shetty07477582011-09-02 17:35:44 -07002768 int i = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002769
2770 if ((data == NULL) || (priv == NULL)) {
2771 pr_err("%s: data or priv is NULL\n", __func__);
2772 return -EINVAL;
2773 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07002774
2775 c = priv;
2776
2777 pr_debug("%s: session_id 0x%x\n", __func__, data->dest_port);
2778
2779 v = voice_get_session(data->dest_port);
2780 if (v == NULL) {
2781 pr_err("%s: v is NULL\n", __func__);
2782
2783 return -EINVAL;
2784 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002785
2786 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
2787 data->payload_size, data->opcode);
2788
Neema Shetty07477582011-09-02 17:35:44 -07002789 if (data->opcode == RESET_EVENTS) {
2790 pr_debug("%s: Reset event received in Voice service\n",
2791 __func__);
2792
2793 apr_reset(c->apr_q6_mvm);
2794 c->apr_q6_mvm = NULL;
2795
2796 /* Sub-system restart is applicable to all sessions. */
2797 for (i = 0; i < MAX_VOC_SESSIONS; i++)
2798 c->voice[i].mvm_handle = 0;
2799
2800 return 0;
2801 }
2802
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002803 if (data->opcode == APR_BASIC_RSP_RESULT) {
2804 if (data->payload_size) {
2805 ptr = data->payload;
2806
2807 pr_info("%x %x\n", ptr[0], ptr[1]);
2808 /* ping mvm service ACK */
2809 switch (ptr[0]) {
2810 case VSS_IMVM_CMD_CREATE_PASSIVE_CONTROL_SESSION:
2811 case VSS_IMVM_CMD_CREATE_FULL_CONTROL_SESSION:
2812 /* Passive session is used for CS call
2813 * Full session is used for VoIP call. */
2814 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2815 if (!ptr[1]) {
2816 pr_debug("%s: MVM handle is %d\n",
2817 __func__, data->src_port);
2818 voice_set_mvm_handle(v, data->src_port);
2819 } else
2820 pr_err("got NACK for sending \
2821 MVM create session \n");
2822 v->mvm_state = CMD_STATUS_SUCCESS;
2823 wake_up(&v->mvm_wait);
2824 break;
2825 case VSS_IMVM_CMD_START_VOICE:
Helen Zeng69b00962011-07-08 11:38:36 -07002826 case VSS_IMVM_CMD_ATTACH_VOCPROC:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002827 case VSS_IMVM_CMD_STOP_VOICE:
Helen Zeng69b00962011-07-08 11:38:36 -07002828 case VSS_IMVM_CMD_DETACH_VOCPROC:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002829 case VSS_ISTREAM_CMD_SET_TTY_MODE:
2830 case APRV2_IBASIC_CMD_DESTROY_SESSION:
2831 case VSS_IMVM_CMD_ATTACH_STREAM:
2832 case VSS_IMVM_CMD_DETACH_STREAM:
2833 case VSS_ICOMMON_CMD_SET_NETWORK:
2834 case VSS_ICOMMON_CMD_SET_VOICE_TIMING:
Helen Zeng44d4d272011-08-10 14:49:20 -07002835 case VSS_IWIDEVOICE_CMD_SET_WIDEVOICE:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002836 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2837 v->mvm_state = CMD_STATUS_SUCCESS;
2838 wake_up(&v->mvm_wait);
2839 break;
2840 default:
2841 pr_debug("%s: not match cmd = 0x%x\n",
2842 __func__, ptr[0]);
2843 break;
2844 }
2845 }
2846 }
2847
2848 return 0;
2849}
2850
2851static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv)
2852{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002853 uint32_t *ptr = NULL;
2854 struct common_data *c = NULL;
2855 struct voice_data *v = NULL;
Neema Shetty07477582011-09-02 17:35:44 -07002856 int i = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002857
2858 if ((data == NULL) || (priv == NULL)) {
2859 pr_err("%s: data or priv is NULL\n", __func__);
2860 return -EINVAL;
2861 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07002862
2863 c = priv;
2864
2865 pr_debug("%s: session_id 0x%x\n", __func__, data->dest_port);
2866
2867 v = voice_get_session(data->dest_port);
2868 if (v == NULL) {
2869 pr_err("%s: v is NULL\n", __func__);
2870
2871 return -EINVAL;
2872 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002873
2874 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
2875 data->payload_size, data->opcode);
2876
Neema Shetty07477582011-09-02 17:35:44 -07002877 if (data->opcode == RESET_EVENTS) {
2878 pr_debug("%s: Reset event received in Voice service\n",
2879 __func__);
2880
2881 apr_reset(c->apr_q6_cvs);
2882 c->apr_q6_cvs = NULL;
2883
2884 /* Sub-system restart is applicable to all sessions. */
2885 for (i = 0; i < MAX_VOC_SESSIONS; i++)
2886 c->voice[i].cvs_handle = 0;
2887
2888 return 0;
2889 }
2890
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002891 if (data->opcode == APR_BASIC_RSP_RESULT) {
2892 if (data->payload_size) {
2893 ptr = data->payload;
2894
2895 pr_info("%x %x\n", ptr[0], ptr[1]);
2896 /*response from CVS */
2897 switch (ptr[0]) {
2898 case VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION:
2899 case VSS_ISTREAM_CMD_CREATE_FULL_CONTROL_SESSION:
2900 if (!ptr[1]) {
2901 pr_debug("%s: CVS handle is %d\n",
2902 __func__, data->src_port);
2903 voice_set_cvs_handle(v, data->src_port);
2904 } else
2905 pr_err("got NACK for sending \
2906 CVS create session \n");
2907 v->cvs_state = CMD_STATUS_SUCCESS;
2908 wake_up(&v->cvs_wait);
2909 break;
2910 case VSS_ISTREAM_CMD_SET_MUTE:
2911 case VSS_ISTREAM_CMD_SET_MEDIA_TYPE:
2912 case VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE:
2913 case VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE:
2914 case VSS_ISTREAM_CMD_SET_ENC_DTX_MODE:
2915 case VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE:
2916 case APRV2_IBASIC_CMD_DESTROY_SESSION:
Helen Zeng29eb7442011-06-20 11:06:29 -07002917 case VSS_ISTREAM_CMD_REGISTER_CALIBRATION_DATA:
2918 case VSS_ISTREAM_CMD_DEREGISTER_CALIBRATION_DATA:
2919 case VSS_ICOMMON_CMD_MAP_MEMORY:
2920 case VSS_ICOMMON_CMD_UNMAP_MEMORY:
Helen Zengbb49c702011-09-06 14:09:13 -07002921 case VSS_ICOMMON_CMD_SET_UI_PROPERTY:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002922 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2923 v->cvs_state = CMD_STATUS_SUCCESS;
2924 wake_up(&v->cvs_wait);
2925 break;
Ben Romberger13b74ab2011-07-18 17:36:32 -07002926 case VOICE_CMD_SET_PARAM:
2927 rtac_make_voice_callback(RTAC_CVS, ptr,
2928 data->payload_size);
2929 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002930 default:
2931 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
2932 break;
2933 }
2934 }
2935 } else if (data->opcode == VSS_ISTREAM_EVT_SEND_ENC_BUFFER) {
2936 uint32_t *voc_pkt = data->payload;
2937 uint32_t pkt_len = data->payload_size;
2938
Neema Shetty2c07eb52011-08-21 20:33:52 -07002939 if (voc_pkt != NULL && c->mvs_info.ul_cb != NULL) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002940 pr_debug("%s: Media type is 0x%x\n",
2941 __func__, voc_pkt[0]);
2942
2943 /* Remove media ID from payload. */
2944 voc_pkt++;
2945 pkt_len = pkt_len - 4;
2946
Neema Shetty2c07eb52011-08-21 20:33:52 -07002947 c->mvs_info.ul_cb((uint8_t *)voc_pkt,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002948 pkt_len,
Neema Shetty2c07eb52011-08-21 20:33:52 -07002949 c->mvs_info.private_data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002950 } else
2951 pr_err("%s: voc_pkt is 0x%x ul_cb is 0x%x\n",
2952 __func__, (unsigned int)voc_pkt,
Neema Shetty2c07eb52011-08-21 20:33:52 -07002953 (unsigned int) c->mvs_info.ul_cb);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002954 } else if (data->opcode == VSS_ISTREAM_EVT_REQUEST_DEC_BUFFER) {
2955 struct cvs_send_dec_buf_cmd send_dec_buf;
2956 int ret = 0;
2957 uint32_t pkt_len = 0;
2958
Neema Shetty2c07eb52011-08-21 20:33:52 -07002959 if (c->mvs_info.dl_cb != NULL) {
2960 send_dec_buf.dec_buf.media_id = c->mvs_info.media_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002961
Neema Shetty2c07eb52011-08-21 20:33:52 -07002962 c->mvs_info.dl_cb(
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002963 (uint8_t *)&send_dec_buf.dec_buf.packet_data,
2964 &pkt_len,
Neema Shetty2c07eb52011-08-21 20:33:52 -07002965 c->mvs_info.private_data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002966
2967 send_dec_buf.hdr.hdr_field =
2968 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2969 APR_HDR_LEN(APR_HDR_SIZE),
2970 APR_PKT_VER);
2971 send_dec_buf.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2972 sizeof(send_dec_buf.dec_buf.media_id) + pkt_len);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002973 send_dec_buf.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002974 send_dec_buf.hdr.dest_port = voice_get_cvs_handle(v);
2975 send_dec_buf.hdr.token = 0;
2976 send_dec_buf.hdr.opcode =
2977 VSS_ISTREAM_EVT_SEND_DEC_BUFFER;
2978
Neema Shetty2c07eb52011-08-21 20:33:52 -07002979 ret = apr_send_pkt(c->apr_q6_cvs,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002980 (uint32_t *) &send_dec_buf);
2981 if (ret < 0) {
2982 pr_err("%s: Error %d sending DEC_BUF\n",
2983 __func__, ret);
2984 goto fail;
2985 }
2986 } else
2987 pr_debug("%s: dl_cb is NULL\n", __func__);
Ben Romberger13b74ab2011-07-18 17:36:32 -07002988 } else if (data->opcode == VSS_ISTREAM_EVT_SEND_DEC_BUFFER) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002989 pr_debug("Send dec buf resp\n");
Ben Romberger13b74ab2011-07-18 17:36:32 -07002990 } else if (data->opcode == VOICE_EVT_GET_PARAM_ACK) {
2991 rtac_make_voice_callback(RTAC_CVS, data->payload,
2992 data->payload_size);
2993 } else
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002994 pr_debug("Unknown opcode 0x%x\n", data->opcode);
2995
2996fail:
2997 return 0;
2998}
2999
3000static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv)
3001{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003002 uint32_t *ptr = NULL;
3003 struct common_data *c = NULL;
3004 struct voice_data *v = NULL;
Neema Shetty07477582011-09-02 17:35:44 -07003005 int i = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003006
3007 if ((data == NULL) || (priv == NULL)) {
3008 pr_err("%s: data or priv is NULL\n", __func__);
3009 return -EINVAL;
3010 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07003011
3012 c = priv;
3013
3014 v = voice_get_session(data->dest_port);
3015 if (v == NULL) {
3016 pr_err("%s: v is NULL\n", __func__);
3017
3018 return -EINVAL;
3019 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003020
3021 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
3022 data->payload_size, data->opcode);
3023
Neema Shetty07477582011-09-02 17:35:44 -07003024 if (data->opcode == RESET_EVENTS) {
3025 pr_debug("%s: Reset event received in Voice service\n",
3026 __func__);
3027
3028 apr_reset(c->apr_q6_cvp);
3029 c->apr_q6_cvp = NULL;
3030
3031 /* Sub-system restart is applicable to all sessions. */
3032 for (i = 0; i < MAX_VOC_SESSIONS; i++)
3033 c->voice[i].cvp_handle = 0;
3034
3035 return 0;
3036 }
3037
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003038 if (data->opcode == APR_BASIC_RSP_RESULT) {
3039 if (data->payload_size) {
3040 ptr = data->payload;
3041
3042 pr_info("%x %x\n", ptr[0], ptr[1]);
3043
3044 switch (ptr[0]) {
3045 case VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION:
3046 /*response from CVP */
3047 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
3048 if (!ptr[1]) {
3049 voice_set_cvp_handle(v, data->src_port);
3050 pr_debug("cvphdl=%d\n", data->src_port);
3051 } else
3052 pr_err("got NACK from CVP create \
3053 session response\n");
3054 v->cvp_state = CMD_STATUS_SUCCESS;
3055 wake_up(&v->cvp_wait);
3056 break;
3057 case VSS_IVOCPROC_CMD_SET_DEVICE:
3058 case VSS_IVOCPROC_CMD_SET_RX_VOLUME_INDEX:
3059 case VSS_IVOCPROC_CMD_ENABLE:
3060 case VSS_IVOCPROC_CMD_DISABLE:
3061 case APRV2_IBASIC_CMD_DESTROY_SESSION:
Helen Zeng29eb7442011-06-20 11:06:29 -07003062 case VSS_IVOCPROC_CMD_REGISTER_VOLUME_CAL_TABLE:
3063 case VSS_IVOCPROC_CMD_DEREGISTER_VOLUME_CAL_TABLE:
3064 case VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA:
3065 case VSS_IVOCPROC_CMD_DEREGISTER_CALIBRATION_DATA:
3066 case VSS_ICOMMON_CMD_MAP_MEMORY:
3067 case VSS_ICOMMON_CMD_UNMAP_MEMORY:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003068 v->cvp_state = CMD_STATUS_SUCCESS;
3069 wake_up(&v->cvp_wait);
3070 break;
Ben Romberger13b74ab2011-07-18 17:36:32 -07003071 case VOICE_CMD_SET_PARAM:
3072 rtac_make_voice_callback(RTAC_CVP, ptr,
3073 data->payload_size);
3074 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003075 default:
3076 pr_debug("%s: not match cmd = 0x%x\n",
3077 __func__, ptr[0]);
3078 break;
3079 }
3080 }
Ben Romberger13b74ab2011-07-18 17:36:32 -07003081 } else if (data->opcode == VOICE_EVT_GET_PARAM_ACK) {
3082 rtac_make_voice_callback(RTAC_CVP, data->payload,
3083 data->payload_size);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003084 }
3085 return 0;
3086}
3087
3088
3089static int __init voice_init(void)
3090{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003091 int rc = 0, i = 0;
3092
3093 memset(&common, 0, sizeof(struct common_data));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003094
3095 /* set default value */
Neema Shetty2c07eb52011-08-21 20:33:52 -07003096 common.default_mute_val = 1; /* default is mute */
3097 common.default_vol_val = 0;
3098 common.default_sample_val = 8000;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003099
3100 /* Initialize MVS info. */
Neema Shetty2c07eb52011-08-21 20:33:52 -07003101 common.mvs_info.network_type = VSS_NETWORK_ID_DEFAULT;
3102
3103 mutex_init(&common.common_lock);
3104
3105 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
3106 common.voice[i].session_id = SESSION_ID_BASE + i;
3107
3108 /* initialize dev_rx and dev_tx */
3109 common.voice[i].dev_rx.volume = common.default_vol_val;
3110 common.voice[i].dev_tx.mute = common.default_mute_val;
3111
3112 common.voice[i].dev_tx.port_id = 1;
3113 common.voice[i].dev_rx.port_id = 0;
3114 common.voice[i].sidetone_gain = 0x512;
3115
3116 common.voice[i].voc_state = VOC_INIT;
3117
3118 init_waitqueue_head(&common.voice[i].mvm_wait);
3119 init_waitqueue_head(&common.voice[i].cvs_wait);
3120 init_waitqueue_head(&common.voice[i].cvp_wait);
3121
3122 mutex_init(&common.voice[i].lock);
3123 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003124
3125 return rc;
3126}
3127
3128device_initcall(voice_init);