blob: 3b46a50ccf9406e56ae066fce33fa05d36c1bb91 [file] [log] [blame]
Helen Zeng4e531942011-12-17 21:14:40 -08001/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12#include <linux/slab.h>
13#include <linux/kthread.h>
14#include <linux/kernel.h>
15#include <linux/module.h>
16#include <linux/uaccess.h>
17#include <linux/wait.h>
18#include <linux/mutex.h>
Ben Romberger13b74ab2011-07-18 17:36:32 -070019
Swaminathan Sathappan2fea0da2011-12-21 12:20:53 -080020#include <asm/mach-types.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070021#include <mach/qdsp6v2/audio_acdb.h>
Ben Romberger13b74ab2011-07-18 17:36:32 -070022#include <mach/qdsp6v2/rtac.h>
23
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070024#include "sound/apr_audio.h"
25#include "sound/q6afe.h"
Ben Romberger13b74ab2011-07-18 17:36:32 -070026
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070027#include "q6voice.h"
28
29#define TIMEOUT_MS 3000
30
31#define CMD_STATUS_SUCCESS 0
32#define CMD_STATUS_FAIL 1
33
34#define VOC_PATH_PASSIVE 0
35#define VOC_PATH_FULL 1
36
Helen Zeng6e64dba2012-03-08 18:30:11 -080037/* CVP CAL Size: 245760 = 240 * 1024 */
38#define CVP_CAL_SIZE 245760
39/* CVS CAL Size: 49152 = 48 * 1024 */
40#define CVS_CAL_SIZE 49152
41
Neema Shetty2c07eb52011-08-21 20:33:52 -070042static struct common_data common;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070043
44static int voice_send_enable_vocproc_cmd(struct voice_data *v);
45static int voice_send_netid_timing_cmd(struct voice_data *v);
46static int voice_send_attach_vocproc_cmd(struct voice_data *v);
47static int voice_send_set_device_cmd(struct voice_data *v);
48static int voice_send_disable_vocproc_cmd(struct voice_data *v);
49static int voice_send_vol_index_cmd(struct voice_data *v);
Helen Zeng29eb7442011-06-20 11:06:29 -070050static int voice_send_cvp_map_memory_cmd(struct voice_data *v);
51static int voice_send_cvp_unmap_memory_cmd(struct voice_data *v);
52static int voice_send_cvs_map_memory_cmd(struct voice_data *v);
53static int voice_send_cvs_unmap_memory_cmd(struct voice_data *v);
54static int voice_send_cvs_register_cal_cmd(struct voice_data *v);
55static int voice_send_cvs_deregister_cal_cmd(struct voice_data *v);
56static int voice_send_cvp_register_cal_cmd(struct voice_data *v);
57static int voice_send_cvp_deregister_cal_cmd(struct voice_data *v);
58static int voice_send_cvp_register_vol_cal_table_cmd(struct voice_data *v);
59static int voice_send_cvp_deregister_vol_cal_table_cmd(struct voice_data *v);
Helen Zeng44d4d272011-08-10 14:49:20 -070060static int voice_send_set_widevoice_enable_cmd(struct voice_data *v);
Helen Zeng4e531942011-12-17 21:14:40 -080061static int voice_send_set_pp_enable_cmd(struct voice_data *v,
62 uint32_t module_id, int enable);
Helen Zeng0705a5f2011-10-14 15:29:52 -070063static int voice_cvs_stop_playback(struct voice_data *v);
64static int voice_cvs_start_playback(struct voice_data *v);
Helen Zenge3d716a2011-10-14 16:32:16 -070065static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode);
66static int voice_cvs_stop_record(struct voice_data *v);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070067
68static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv);
69static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv);
70static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv);
71
72static u16 voice_get_mvm_handle(struct voice_data *v)
73{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070074 if (v == NULL) {
75 pr_err("%s: v is NULL\n", __func__);
Neema Shetty2c07eb52011-08-21 20:33:52 -070076 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070077 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070078
Neema Shetty2c07eb52011-08-21 20:33:52 -070079 pr_debug("%s: mvm_handle %d\n", __func__, v->mvm_handle);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070080
Neema Shetty2c07eb52011-08-21 20:33:52 -070081 return v->mvm_handle;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070082}
83
84static void voice_set_mvm_handle(struct voice_data *v, u16 mvm_handle)
85{
86 pr_debug("%s: mvm_handle %d\n", __func__, mvm_handle);
87 if (v == NULL) {
88 pr_err("%s: v is NULL\n", __func__);
89 return;
90 }
91
Neema Shetty2c07eb52011-08-21 20:33:52 -070092 v->mvm_handle = mvm_handle;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070093}
94
95static u16 voice_get_cvs_handle(struct voice_data *v)
96{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070097 if (v == NULL) {
98 pr_err("%s: v is NULL\n", __func__);
Neema Shetty2c07eb52011-08-21 20:33:52 -070099 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700100 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700101
Neema Shetty2c07eb52011-08-21 20:33:52 -0700102 pr_debug("%s: cvs_handle %d\n", __func__, v->cvs_handle);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700103
Neema Shetty2c07eb52011-08-21 20:33:52 -0700104 return v->cvs_handle;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700105}
106
107static void voice_set_cvs_handle(struct voice_data *v, u16 cvs_handle)
108{
109 pr_debug("%s: cvs_handle %d\n", __func__, cvs_handle);
110 if (v == NULL) {
111 pr_err("%s: v is NULL\n", __func__);
112 return;
113 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700114
115 v->cvs_handle = cvs_handle;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700116}
117
118static u16 voice_get_cvp_handle(struct voice_data *v)
119{
Neema Shetty2c07eb52011-08-21 20:33:52 -0700120 if (v == NULL) {
121 pr_err("%s: v is NULL\n", __func__);
122 return 0;
123 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700124
Neema Shetty2c07eb52011-08-21 20:33:52 -0700125 pr_debug("%s: cvp_handle %d\n", __func__, v->cvp_handle);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700126
Neema Shetty2c07eb52011-08-21 20:33:52 -0700127 return v->cvp_handle;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700128}
129
130static void voice_set_cvp_handle(struct voice_data *v, u16 cvp_handle)
131{
132 pr_debug("%s: cvp_handle %d\n", __func__, cvp_handle);
133 if (v == NULL) {
134 pr_err("%s: v is NULL\n", __func__);
135 return;
136 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700137
138 v->cvp_handle = cvp_handle;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700139}
140
Neema Shetty2c07eb52011-08-21 20:33:52 -0700141uint16_t voc_get_session_id(char *name)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700142{
Neema Shetty2c07eb52011-08-21 20:33:52 -0700143 u16 session_id = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700144
Neema Shetty2c07eb52011-08-21 20:33:52 -0700145 if (name != NULL) {
146 if (!strncmp(name, "Voice session", 13))
147 session_id = common.voice[VOC_PATH_PASSIVE].session_id;
148 else
149 session_id = common.voice[VOC_PATH_FULL].session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700150
Helen Zeng0f4c4e22011-09-29 14:25:43 -0700151 pr_debug("%s: %s has session id 0x%x\n", __func__, name,
152 session_id);
153 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700154
155 return session_id;
156}
157
158static struct voice_data *voice_get_session(u16 session_id)
159{
160 struct voice_data *v = NULL;
161
162 if ((session_id >= SESSION_ID_BASE) &&
163 (session_id < SESSION_ID_BASE + MAX_VOC_SESSIONS)) {
164 v = &common.voice[session_id - SESSION_ID_BASE];
165 }
166
167 pr_debug("%s: session_id 0x%x session handle 0x%x\n",
168 __func__, session_id, (unsigned int)v);
169
170 return v;
171}
172
173static bool is_voice_session(u16 session_id)
174{
175 return (session_id == common.voice[VOC_PATH_PASSIVE].session_id);
176}
177
178static bool is_voip_session(u16 session_id)
179{
180 return (session_id == common.voice[VOC_PATH_FULL].session_id);
181}
182
183static int voice_apr_register(void)
184{
185 pr_debug("%s\n", __func__);
186
187 mutex_lock(&common.common_lock);
188
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700189 /* register callback to APR */
Neema Shetty2c07eb52011-08-21 20:33:52 -0700190 if (common.apr_q6_mvm == NULL) {
191 pr_debug("%s: Start to register MVM callback\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700192
Neema Shetty2c07eb52011-08-21 20:33:52 -0700193 common.apr_q6_mvm = apr_register("ADSP", "MVM",
194 qdsp_mvm_callback,
195 0xFFFFFFFF, &common);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700196
Neema Shetty2c07eb52011-08-21 20:33:52 -0700197 if (common.apr_q6_mvm == NULL) {
198 pr_err("%s: Unable to register MVM\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700199 goto err;
200 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700201 }
202
Neema Shetty2c07eb52011-08-21 20:33:52 -0700203 if (common.apr_q6_cvs == NULL) {
204 pr_debug("%s: Start to register CVS callback\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700205
Neema Shetty2c07eb52011-08-21 20:33:52 -0700206 common.apr_q6_cvs = apr_register("ADSP", "CVS",
207 qdsp_cvs_callback,
208 0xFFFFFFFF, &common);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700209
Neema Shetty2c07eb52011-08-21 20:33:52 -0700210 if (common.apr_q6_cvs == NULL) {
211 pr_err("%s: Unable to register CVS\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700212 goto err;
213 }
Ben Romberger13b74ab2011-07-18 17:36:32 -0700214
Neema Shetty2c07eb52011-08-21 20:33:52 -0700215 rtac_set_voice_handle(RTAC_CVS, common.apr_q6_cvs);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700216 }
217
Neema Shetty2c07eb52011-08-21 20:33:52 -0700218 if (common.apr_q6_cvp == NULL) {
219 pr_debug("%s: Start to register CVP callback\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700220
Neema Shetty2c07eb52011-08-21 20:33:52 -0700221 common.apr_q6_cvp = apr_register("ADSP", "CVP",
222 qdsp_cvp_callback,
223 0xFFFFFFFF, &common);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700224
Neema Shetty2c07eb52011-08-21 20:33:52 -0700225 if (common.apr_q6_cvp == NULL) {
226 pr_err("%s: Unable to register CVP\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700227 goto err;
228 }
Ben Romberger13b74ab2011-07-18 17:36:32 -0700229
Neema Shetty2c07eb52011-08-21 20:33:52 -0700230 rtac_set_voice_handle(RTAC_CVP, common.apr_q6_cvp);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700231 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700232
233 mutex_unlock(&common.common_lock);
234
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700235 return 0;
236
237err:
Neema Shetty2c07eb52011-08-21 20:33:52 -0700238 if (common.apr_q6_cvs != NULL) {
239 apr_deregister(common.apr_q6_cvs);
240 common.apr_q6_cvs = NULL;
Ben Romberger13b74ab2011-07-18 17:36:32 -0700241 rtac_set_voice_handle(RTAC_CVS, NULL);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700242 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700243 if (common.apr_q6_mvm != NULL) {
244 apr_deregister(common.apr_q6_mvm);
245 common.apr_q6_mvm = NULL;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700246 }
247
Neema Shetty2c07eb52011-08-21 20:33:52 -0700248 mutex_unlock(&common.common_lock);
249
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700250 return -ENODEV;
251}
252
253static int voice_create_mvm_cvs_session(struct voice_data *v)
254{
255 int ret = 0;
Helen Zeng69b00962011-07-08 11:38:36 -0700256 struct mvm_create_ctl_session_cmd mvm_session_cmd;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700257 struct cvs_create_passive_ctl_session_cmd cvs_session_cmd;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700258 struct cvs_create_full_ctl_session_cmd cvs_full_ctl_cmd;
259 struct mvm_attach_stream_cmd attach_stream_cmd;
260 void *apr_mvm, *apr_cvs, *apr_cvp;
261 u16 mvm_handle, cvs_handle, cvp_handle;
262
263 if (v == NULL) {
264 pr_err("%s: v is NULL\n", __func__);
265 return -EINVAL;
266 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700267 apr_mvm = common.apr_q6_mvm;
268 apr_cvs = common.apr_q6_cvs;
269 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700270
271 if (!apr_mvm || !apr_cvs || !apr_cvp) {
272 pr_err("%s: apr_mvm or apr_cvs or apr_cvp is NULL\n", __func__);
273 return -EINVAL;
274 }
275 mvm_handle = voice_get_mvm_handle(v);
276 cvs_handle = voice_get_cvs_handle(v);
277 cvp_handle = voice_get_cvp_handle(v);
278
279 pr_debug("%s: mvm_hdl=%d, cvs_hdl=%d\n", __func__,
280 mvm_handle, cvs_handle);
281 /* send cmd to create mvm session and wait for response */
282
283 if (!mvm_handle) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700284 if (is_voice_session(v->session_id)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700285 mvm_session_cmd.hdr.hdr_field = APR_HDR_FIELD(
286 APR_MSG_TYPE_SEQ_CMD,
287 APR_HDR_LEN(APR_HDR_SIZE),
288 APR_PKT_VER);
289 mvm_session_cmd.hdr.pkt_size = APR_PKT_SIZE(
290 APR_HDR_SIZE,
291 sizeof(mvm_session_cmd) -
292 APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700293 pr_debug("%s: send mvm create session pkt size = %d\n",
294 __func__, mvm_session_cmd.hdr.pkt_size);
295 mvm_session_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700296 mvm_session_cmd.hdr.dest_port = 0;
297 mvm_session_cmd.hdr.token = 0;
298 mvm_session_cmd.hdr.opcode =
299 VSS_IMVM_CMD_CREATE_PASSIVE_CONTROL_SESSION;
Neema Shetty9ba987d2011-10-25 18:14:50 -0700300 strlcpy(mvm_session_cmd.mvm_session.name,
301 "default modem voice",
302 sizeof(mvm_session_cmd.mvm_session.name));
Helen Zeng69b00962011-07-08 11:38:36 -0700303
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700304 v->mvm_state = CMD_STATUS_FAIL;
305
306 ret = apr_send_pkt(apr_mvm,
307 (uint32_t *) &mvm_session_cmd);
308 if (ret < 0) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700309 pr_err("%s: Error sending MVM_CONTROL_SESSION\n",
310 __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700311 goto fail;
312 }
313 ret = wait_event_timeout(v->mvm_wait,
314 (v->mvm_state == CMD_STATUS_SUCCESS),
315 msecs_to_jiffies(TIMEOUT_MS));
316 if (!ret) {
317 pr_err("%s: wait_event timeout\n", __func__);
318 goto fail;
319 }
320 } else {
321 pr_debug("%s: creating MVM full ctrl\n", __func__);
Helen Zeng69b00962011-07-08 11:38:36 -0700322 mvm_session_cmd.hdr.hdr_field =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700323 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
324 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
Helen Zeng69b00962011-07-08 11:38:36 -0700325 mvm_session_cmd.hdr.pkt_size =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700326 APR_PKT_SIZE(APR_HDR_SIZE,
Helen Zeng69b00962011-07-08 11:38:36 -0700327 sizeof(mvm_session_cmd) -
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700328 APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700329 mvm_session_cmd.hdr.src_port = v->session_id;
Helen Zeng69b00962011-07-08 11:38:36 -0700330 mvm_session_cmd.hdr.dest_port = 0;
331 mvm_session_cmd.hdr.token = 0;
332 mvm_session_cmd.hdr.opcode =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700333 VSS_IMVM_CMD_CREATE_FULL_CONTROL_SESSION;
Neema Shetty9ba987d2011-10-25 18:14:50 -0700334 strlcpy(mvm_session_cmd.mvm_session.name,
335 "default voip",
336 sizeof(mvm_session_cmd.mvm_session.name));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700337
338 v->mvm_state = CMD_STATUS_FAIL;
339
340 ret = apr_send_pkt(apr_mvm,
Helen Zeng69b00962011-07-08 11:38:36 -0700341 (uint32_t *) &mvm_session_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700342 if (ret < 0) {
343 pr_err("Fail in sending MVM_CONTROL_SESSION\n");
344 goto fail;
345 }
346 ret = wait_event_timeout(v->mvm_wait,
347 (v->mvm_state == CMD_STATUS_SUCCESS),
348 msecs_to_jiffies(TIMEOUT_MS));
349 if (!ret) {
350 pr_err("%s: wait_event timeout\n", __func__);
351 goto fail;
352 }
353 }
354 /* Get the created MVM handle. */
355 mvm_handle = voice_get_mvm_handle(v);
356 }
357 /* send cmd to create cvs session */
358 if (!cvs_handle) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700359 if (is_voice_session(v->session_id)) {
360 pr_debug("%s: creating CVS passive session\n",
361 __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700362
363 cvs_session_cmd.hdr.hdr_field = APR_HDR_FIELD(
364 APR_MSG_TYPE_SEQ_CMD,
365 APR_HDR_LEN(APR_HDR_SIZE),
366 APR_PKT_VER);
367 cvs_session_cmd.hdr.pkt_size =
368 APR_PKT_SIZE(APR_HDR_SIZE,
369 sizeof(cvs_session_cmd) -
370 APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700371 cvs_session_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700372 cvs_session_cmd.hdr.dest_port = 0;
373 cvs_session_cmd.hdr.token = 0;
374 cvs_session_cmd.hdr.opcode =
375 VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION;
Neema Shetty9ba987d2011-10-25 18:14:50 -0700376 strlcpy(cvs_session_cmd.cvs_session.name,
377 "default modem voice",
378 sizeof(cvs_session_cmd.cvs_session.name));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700379
380 v->cvs_state = CMD_STATUS_FAIL;
381
382 ret = apr_send_pkt(apr_cvs,
383 (uint32_t *) &cvs_session_cmd);
384 if (ret < 0) {
385 pr_err("Fail in sending STREAM_CONTROL_SESSION\n");
386 goto fail;
387 }
388 ret = wait_event_timeout(v->cvs_wait,
389 (v->cvs_state == CMD_STATUS_SUCCESS),
390 msecs_to_jiffies(TIMEOUT_MS));
391 if (!ret) {
392 pr_err("%s: wait_event timeout\n", __func__);
393 goto fail;
394 }
395 /* Get the created CVS handle. */
396 cvs_handle = voice_get_cvs_handle(v);
397
398 } else {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700399 pr_debug("%s: creating CVS full session\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700400
401 cvs_full_ctl_cmd.hdr.hdr_field =
402 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
403 APR_HDR_LEN(APR_HDR_SIZE),
404 APR_PKT_VER);
405
406 cvs_full_ctl_cmd.hdr.pkt_size =
407 APR_PKT_SIZE(APR_HDR_SIZE,
408 sizeof(cvs_full_ctl_cmd) -
409 APR_HDR_SIZE);
410
Neema Shetty2c07eb52011-08-21 20:33:52 -0700411 cvs_full_ctl_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700412 cvs_full_ctl_cmd.hdr.dest_port = 0;
413 cvs_full_ctl_cmd.hdr.token = 0;
414 cvs_full_ctl_cmd.hdr.opcode =
415 VSS_ISTREAM_CMD_CREATE_FULL_CONTROL_SESSION;
416 cvs_full_ctl_cmd.cvs_session.direction = 2;
417 cvs_full_ctl_cmd.cvs_session.enc_media_type =
Neema Shetty2c07eb52011-08-21 20:33:52 -0700418 common.mvs_info.media_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700419 cvs_full_ctl_cmd.cvs_session.dec_media_type =
Neema Shetty2c07eb52011-08-21 20:33:52 -0700420 common.mvs_info.media_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700421 cvs_full_ctl_cmd.cvs_session.network_id =
Neema Shetty2c07eb52011-08-21 20:33:52 -0700422 common.mvs_info.network_type;
Neema Shetty9ba987d2011-10-25 18:14:50 -0700423 strlcpy(cvs_full_ctl_cmd.cvs_session.name,
424 "default q6 voice",
425 sizeof(cvs_full_ctl_cmd.cvs_session.name));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700426
427 v->cvs_state = CMD_STATUS_FAIL;
428
429 ret = apr_send_pkt(apr_cvs,
430 (uint32_t *) &cvs_full_ctl_cmd);
431
432 if (ret < 0) {
433 pr_err("%s: Err %d sending CREATE_FULL_CTRL\n",
434 __func__, ret);
435 goto fail;
436 }
437 ret = wait_event_timeout(v->cvs_wait,
438 (v->cvs_state == CMD_STATUS_SUCCESS),
439 msecs_to_jiffies(TIMEOUT_MS));
440 if (!ret) {
441 pr_err("%s: wait_event timeout\n", __func__);
442 goto fail;
443 }
444 /* Get the created CVS handle. */
445 cvs_handle = voice_get_cvs_handle(v);
446
447 /* Attach MVM to CVS. */
Neema Shetty2c07eb52011-08-21 20:33:52 -0700448 pr_debug("%s: Attach MVM to stream\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700449
450 attach_stream_cmd.hdr.hdr_field =
451 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
452 APR_HDR_LEN(APR_HDR_SIZE),
453 APR_PKT_VER);
454 attach_stream_cmd.hdr.pkt_size =
455 APR_PKT_SIZE(APR_HDR_SIZE,
456 sizeof(attach_stream_cmd) -
457 APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700458 attach_stream_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700459 attach_stream_cmd.hdr.dest_port = mvm_handle;
460 attach_stream_cmd.hdr.token = 0;
461 attach_stream_cmd.hdr.opcode =
462 VSS_IMVM_CMD_ATTACH_STREAM;
463 attach_stream_cmd.attach_stream.handle = cvs_handle;
464
465 v->mvm_state = CMD_STATUS_FAIL;
466 ret = apr_send_pkt(apr_mvm,
467 (uint32_t *) &attach_stream_cmd);
468 if (ret < 0) {
469 pr_err("%s: Error %d sending ATTACH_STREAM\n",
470 __func__, ret);
471 goto fail;
472 }
473 ret = wait_event_timeout(v->mvm_wait,
474 (v->mvm_state == CMD_STATUS_SUCCESS),
475 msecs_to_jiffies(TIMEOUT_MS));
476 if (!ret) {
477 pr_err("%s: wait_event timeout\n", __func__);
478 goto fail;
479 }
480 }
481 }
482 return 0;
483
484fail:
485 return -EINVAL;
486}
487
488static int voice_destroy_mvm_cvs_session(struct voice_data *v)
489{
490 int ret = 0;
491 struct mvm_detach_stream_cmd detach_stream;
492 struct apr_hdr mvm_destroy;
493 struct apr_hdr cvs_destroy;
494 void *apr_mvm, *apr_cvs;
495 u16 mvm_handle, cvs_handle;
496
497 if (v == NULL) {
498 pr_err("%s: v is NULL\n", __func__);
499 return -EINVAL;
500 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700501 apr_mvm = common.apr_q6_mvm;
502 apr_cvs = common.apr_q6_cvs;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700503
504 if (!apr_mvm || !apr_cvs) {
505 pr_err("%s: apr_mvm or apr_cvs is NULL\n", __func__);
506 return -EINVAL;
507 }
508 mvm_handle = voice_get_mvm_handle(v);
509 cvs_handle = voice_get_cvs_handle(v);
510
511 /* MVM, CVS sessions are destroyed only for Full control sessions. */
Neema Shetty2c07eb52011-08-21 20:33:52 -0700512 if (is_voip_session(v->session_id)) {
513 pr_debug("%s: MVM detach stream\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700514
515 /* Detach voice stream. */
516 detach_stream.hdr.hdr_field =
517 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
518 APR_HDR_LEN(APR_HDR_SIZE),
519 APR_PKT_VER);
520 detach_stream.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
521 sizeof(detach_stream) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700522 detach_stream.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700523 detach_stream.hdr.dest_port = mvm_handle;
524 detach_stream.hdr.token = 0;
525 detach_stream.hdr.opcode = VSS_IMVM_CMD_DETACH_STREAM;
526 detach_stream.detach_stream.handle = cvs_handle;
527
528 v->mvm_state = CMD_STATUS_FAIL;
529
530 ret = apr_send_pkt(apr_mvm, (uint32_t *) &detach_stream);
531 if (ret < 0) {
532 pr_err("%s: Error %d sending DETACH_STREAM\n",
533 __func__, ret);
534 goto fail;
535 }
536 ret = wait_event_timeout(v->mvm_wait,
537 (v->mvm_state == CMD_STATUS_SUCCESS),
538 msecs_to_jiffies(TIMEOUT_MS));
539 if (!ret) {
540 pr_err("%s: wait event timeout\n", __func__);
541 goto fail;
542 }
543 /* Destroy CVS. */
Neema Shetty2c07eb52011-08-21 20:33:52 -0700544 pr_debug("%s: CVS destroy session\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700545
546 cvs_destroy.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
547 APR_HDR_LEN(APR_HDR_SIZE),
548 APR_PKT_VER);
549 cvs_destroy.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
550 sizeof(cvs_destroy) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700551 cvs_destroy.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700552 cvs_destroy.dest_port = cvs_handle;
553 cvs_destroy.token = 0;
554 cvs_destroy.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
555
556 v->cvs_state = CMD_STATUS_FAIL;
557
558 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_destroy);
559 if (ret < 0) {
560 pr_err("%s: Error %d sending CVS DESTROY\n",
561 __func__, ret);
562 goto fail;
563 }
564 ret = wait_event_timeout(v->cvs_wait,
565 (v->cvs_state == CMD_STATUS_SUCCESS),
566 msecs_to_jiffies(TIMEOUT_MS));
567 if (!ret) {
568 pr_err("%s: wait event timeout\n", __func__);
569
570 goto fail;
571 }
572 cvs_handle = 0;
573 voice_set_cvs_handle(v, cvs_handle);
574
575 /* Destroy MVM. */
576 pr_debug("MVM destroy session\n");
577
578 mvm_destroy.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
579 APR_HDR_LEN(APR_HDR_SIZE),
580 APR_PKT_VER);
581 mvm_destroy.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
582 sizeof(mvm_destroy) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700583 mvm_destroy.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700584 mvm_destroy.dest_port = mvm_handle;
585 mvm_destroy.token = 0;
586 mvm_destroy.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
587
588 v->mvm_state = CMD_STATUS_FAIL;
589
590 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_destroy);
591 if (ret < 0) {
592 pr_err("%s: Error %d sending MVM DESTROY\n",
593 __func__, ret);
594
595 goto fail;
596 }
597 ret = wait_event_timeout(v->mvm_wait,
598 (v->mvm_state == CMD_STATUS_SUCCESS),
599 msecs_to_jiffies(TIMEOUT_MS));
600 if (!ret) {
601 pr_err("%s: wait event timeout\n", __func__);
602
603 goto fail;
604 }
605 mvm_handle = 0;
606 voice_set_mvm_handle(v, mvm_handle);
607 }
608 return 0;
609fail:
610 return -EINVAL;
611}
612
613static int voice_send_tty_mode_cmd(struct voice_data *v)
614{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700615 int ret = 0;
616 struct mvm_set_tty_mode_cmd mvm_tty_mode_cmd;
617 void *apr_mvm;
618 u16 mvm_handle;
619
620 if (v == NULL) {
621 pr_err("%s: v is NULL\n", __func__);
622 return -EINVAL;
623 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700624 apr_mvm = common.apr_q6_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700625
626 if (!apr_mvm) {
627 pr_err("%s: apr_mvm is NULL.\n", __func__);
628 return -EINVAL;
629 }
630 mvm_handle = voice_get_mvm_handle(v);
631
Helen Zengcc65b5b2011-07-06 19:14:48 -0700632 if (v->tty_mode) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700633 /* send tty mode cmd to mvm */
634 mvm_tty_mode_cmd.hdr.hdr_field = APR_HDR_FIELD(
635 APR_MSG_TYPE_SEQ_CMD,
636 APR_HDR_LEN(APR_HDR_SIZE),
637 APR_PKT_VER);
638 mvm_tty_mode_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
639 sizeof(mvm_tty_mode_cmd) -
640 APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700641 pr_debug("%s: pkt size = %d\n",
642 __func__, mvm_tty_mode_cmd.hdr.pkt_size);
643 mvm_tty_mode_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700644 mvm_tty_mode_cmd.hdr.dest_port = mvm_handle;
645 mvm_tty_mode_cmd.hdr.token = 0;
646 mvm_tty_mode_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_TTY_MODE;
Helen Zengcc65b5b2011-07-06 19:14:48 -0700647 mvm_tty_mode_cmd.tty_mode.mode = v->tty_mode;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700648 pr_debug("tty mode =%d\n", mvm_tty_mode_cmd.tty_mode.mode);
649
650 v->mvm_state = CMD_STATUS_FAIL;
651 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_tty_mode_cmd);
652 if (ret < 0) {
Neema Shetty2c07eb52011-08-21 20:33:52 -0700653 pr_err("%s: Error %d sending SET_TTY_MODE\n",
654 __func__, ret);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700655 goto fail;
656 }
657 ret = wait_event_timeout(v->mvm_wait,
658 (v->mvm_state == CMD_STATUS_SUCCESS),
659 msecs_to_jiffies(TIMEOUT_MS));
660 if (!ret) {
661 pr_err("%s: wait_event timeout\n", __func__);
662 goto fail;
663 }
664 }
665 return 0;
666fail:
667 return -EINVAL;
668}
669
Helen Zengff97bec2012-02-20 14:30:50 -0800670static int voice_set_dtx(struct voice_data *v)
671{
672 int ret = 0;
673 void *apr_cvs;
674 u16 cvs_handle;
675 struct cvs_set_enc_dtx_mode_cmd cvs_set_dtx;
676
677 if (v == NULL) {
678 pr_err("%s: v is NULL\n", __func__);
679 return -EINVAL;
680 }
681 apr_cvs = common.apr_q6_cvs;
682
683 if (!apr_cvs) {
684 pr_err("%s: apr_cvs is NULL.\n", __func__);
685 return -EINVAL;
686 }
687
688 cvs_handle = voice_get_cvs_handle(v);
689
690 /* Set DTX */
691 cvs_set_dtx.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
692 APR_HDR_LEN(APR_HDR_SIZE),
693 APR_PKT_VER);
694 cvs_set_dtx.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
695 sizeof(cvs_set_dtx) - APR_HDR_SIZE);
696 cvs_set_dtx.hdr.src_port = v->session_id;
697 cvs_set_dtx.hdr.dest_port = cvs_handle;
698 cvs_set_dtx.hdr.token = 0;
699 cvs_set_dtx.hdr.opcode = VSS_ISTREAM_CMD_SET_ENC_DTX_MODE;
700 cvs_set_dtx.dtx_mode.enable = common.mvs_info.dtx_mode;
701
702 pr_debug("%s: Setting DTX %d\n", __func__, common.mvs_info.dtx_mode);
703
704 v->cvs_state = CMD_STATUS_FAIL;
705
706 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_dtx);
707 if (ret < 0) {
708 pr_err("%s: Error %d sending SET_DTX\n", __func__, ret);
709 return -EINVAL;
710 }
711
712 ret = wait_event_timeout(v->cvs_wait,
713 (v->cvs_state == CMD_STATUS_SUCCESS),
714 msecs_to_jiffies(TIMEOUT_MS));
715 if (!ret) {
716 pr_err("%s: wait_event timeout\n", __func__);
717 return -EINVAL;
718 }
719
720 return 0;
721}
722
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700723static int voice_config_cvs_vocoder(struct voice_data *v)
724{
725 int ret = 0;
726 void *apr_cvs;
727 u16 cvs_handle;
728 /* Set media type. */
729 struct cvs_set_media_type_cmd cvs_set_media_cmd;
730
731 if (v == NULL) {
732 pr_err("%s: v is NULL\n", __func__);
733 return -EINVAL;
734 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700735 apr_cvs = common.apr_q6_cvs;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700736
737 if (!apr_cvs) {
738 pr_err("%s: apr_cvs is NULL.\n", __func__);
739 return -EINVAL;
740 }
741
742 cvs_handle = voice_get_cvs_handle(v);
743
744 cvs_set_media_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
745 APR_HDR_LEN(APR_HDR_SIZE),
746 APR_PKT_VER);
747 cvs_set_media_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
748 sizeof(cvs_set_media_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700749 cvs_set_media_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700750 cvs_set_media_cmd.hdr.dest_port = cvs_handle;
751 cvs_set_media_cmd.hdr.token = 0;
752 cvs_set_media_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_MEDIA_TYPE;
Neema Shetty2c07eb52011-08-21 20:33:52 -0700753 cvs_set_media_cmd.media_type.tx_media_id = common.mvs_info.media_type;
754 cvs_set_media_cmd.media_type.rx_media_id = common.mvs_info.media_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700755
756 v->cvs_state = CMD_STATUS_FAIL;
757
758 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_media_cmd);
759 if (ret < 0) {
760 pr_err("%s: Error %d sending SET_MEDIA_TYPE\n",
761 __func__, ret);
762
763 goto fail;
764 }
765 ret = wait_event_timeout(v->cvs_wait,
766 (v->cvs_state == CMD_STATUS_SUCCESS),
767 msecs_to_jiffies(TIMEOUT_MS));
768 if (!ret) {
769 pr_err("%s: wait_event timeout\n", __func__);
770
771 goto fail;
772 }
773 /* Set encoder properties. */
Neema Shetty2c07eb52011-08-21 20:33:52 -0700774 switch (common.mvs_info.media_type) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700775 case VSS_MEDIA_ID_EVRC_MODEM: {
776 struct cvs_set_cdma_enc_minmax_rate_cmd cvs_set_cdma_rate;
777
778 pr_debug("Setting EVRC min-max rate\n");
779
780 cvs_set_cdma_rate.hdr.hdr_field =
781 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
782 APR_HDR_LEN(APR_HDR_SIZE),
783 APR_PKT_VER);
784 cvs_set_cdma_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
785 sizeof(cvs_set_cdma_rate) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700786 cvs_set_cdma_rate.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700787 cvs_set_cdma_rate.hdr.dest_port = cvs_handle;
788 cvs_set_cdma_rate.hdr.token = 0;
789 cvs_set_cdma_rate.hdr.opcode =
790 VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE;
Neema Shetty2c07eb52011-08-21 20:33:52 -0700791 cvs_set_cdma_rate.cdma_rate.min_rate = common.mvs_info.rate;
792 cvs_set_cdma_rate.cdma_rate.max_rate = common.mvs_info.rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700793
794 v->cvs_state = CMD_STATUS_FAIL;
795
796 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_cdma_rate);
797 if (ret < 0) {
798 pr_err("%s: Error %d sending SET_EVRC_MINMAX_RATE\n",
799 __func__, ret);
800 goto fail;
801 }
802 ret = wait_event_timeout(v->cvs_wait,
803 (v->cvs_state == CMD_STATUS_SUCCESS),
804 msecs_to_jiffies(TIMEOUT_MS));
805 if (!ret) {
806 pr_err("%s: wait_event timeout\n", __func__);
807
808 goto fail;
809 }
810 break;
811 }
812 case VSS_MEDIA_ID_AMR_NB_MODEM: {
813 struct cvs_set_amr_enc_rate_cmd cvs_set_amr_rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700814
815 pr_debug("Setting AMR rate\n");
816
817 cvs_set_amr_rate.hdr.hdr_field =
818 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
819 APR_HDR_LEN(APR_HDR_SIZE),
820 APR_PKT_VER);
821 cvs_set_amr_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
822 sizeof(cvs_set_amr_rate) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700823 cvs_set_amr_rate.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700824 cvs_set_amr_rate.hdr.dest_port = cvs_handle;
825 cvs_set_amr_rate.hdr.token = 0;
826 cvs_set_amr_rate.hdr.opcode =
827 VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE;
Neema Shetty2c07eb52011-08-21 20:33:52 -0700828 cvs_set_amr_rate.amr_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_amr_rate);
833 if (ret < 0) {
834 pr_err("%s: Error %d sending SET_AMR_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 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700845
Helen Zengff97bec2012-02-20 14:30:50 -0800846 ret = voice_set_dtx(v);
847 if (ret < 0)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700848 goto fail;
Helen Zengff97bec2012-02-20 14:30:50 -0800849
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700850 break;
851 }
852 case VSS_MEDIA_ID_AMR_WB_MODEM: {
853 struct cvs_set_amrwb_enc_rate_cmd cvs_set_amrwb_rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700854
855 pr_debug("Setting AMR WB rate\n");
856
857 cvs_set_amrwb_rate.hdr.hdr_field =
858 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
859 APR_HDR_LEN(APR_HDR_SIZE),
860 APR_PKT_VER);
861 cvs_set_amrwb_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
862 sizeof(cvs_set_amrwb_rate) -
863 APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700864 cvs_set_amrwb_rate.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700865 cvs_set_amrwb_rate.hdr.dest_port = cvs_handle;
866 cvs_set_amrwb_rate.hdr.token = 0;
867 cvs_set_amrwb_rate.hdr.opcode =
868 VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE;
Neema Shetty2c07eb52011-08-21 20:33:52 -0700869 cvs_set_amrwb_rate.amrwb_rate.mode = common.mvs_info.rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700870
871 v->cvs_state = CMD_STATUS_FAIL;
872
873 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_amrwb_rate);
874 if (ret < 0) {
875 pr_err("%s: Error %d sending SET_AMRWB_RATE\n",
876 __func__, ret);
877 goto fail;
878 }
879 ret = wait_event_timeout(v->cvs_wait,
880 (v->cvs_state == CMD_STATUS_SUCCESS),
881 msecs_to_jiffies(TIMEOUT_MS));
882 if (!ret) {
883 pr_err("%s: wait_event timeout\n", __func__);
884 goto fail;
885 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700886
Helen Zengff97bec2012-02-20 14:30:50 -0800887 ret = voice_set_dtx(v);
888 if (ret < 0)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700889 goto fail;
Helen Zengff97bec2012-02-20 14:30:50 -0800890
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700891 break;
892 }
893 case VSS_MEDIA_ID_G729:
894 case VSS_MEDIA_ID_G711_ALAW:
895 case VSS_MEDIA_ID_G711_MULAW: {
Helen Zengff97bec2012-02-20 14:30:50 -0800896 ret = voice_set_dtx(v);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700897
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700898 break;
899 }
900 default:
901 /* Do nothing. */
902 break;
903 }
904 return 0;
905
906fail:
907 return -EINVAL;
908}
909
910static int voice_send_start_voice_cmd(struct voice_data *v)
911{
912 struct apr_hdr mvm_start_voice_cmd;
913 int ret = 0;
914 void *apr_mvm;
915 u16 mvm_handle;
916
917 if (v == NULL) {
918 pr_err("%s: v is NULL\n", __func__);
919 return -EINVAL;
920 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700921 apr_mvm = common.apr_q6_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700922
923 if (!apr_mvm) {
924 pr_err("%s: apr_mvm is NULL.\n", __func__);
925 return -EINVAL;
926 }
927 mvm_handle = voice_get_mvm_handle(v);
928
929 mvm_start_voice_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
930 APR_HDR_LEN(APR_HDR_SIZE),
931 APR_PKT_VER);
932 mvm_start_voice_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
933 sizeof(mvm_start_voice_cmd) - APR_HDR_SIZE);
934 pr_debug("send mvm_start_voice_cmd pkt size = %d\n",
935 mvm_start_voice_cmd.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700936 mvm_start_voice_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700937 mvm_start_voice_cmd.dest_port = mvm_handle;
938 mvm_start_voice_cmd.token = 0;
939 mvm_start_voice_cmd.opcode = VSS_IMVM_CMD_START_VOICE;
940
941 v->mvm_state = CMD_STATUS_FAIL;
942 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_start_voice_cmd);
943 if (ret < 0) {
944 pr_err("Fail in sending VSS_IMVM_CMD_START_VOICE\n");
945 goto fail;
946 }
947 ret = wait_event_timeout(v->mvm_wait,
948 (v->mvm_state == CMD_STATUS_SUCCESS),
949 msecs_to_jiffies(TIMEOUT_MS));
950 if (!ret) {
951 pr_err("%s: wait_event timeout\n", __func__);
952 goto fail;
953 }
954 return 0;
955fail:
956 return -EINVAL;
957}
958
959static int voice_send_disable_vocproc_cmd(struct voice_data *v)
960{
961 struct apr_hdr cvp_disable_cmd;
962 int ret = 0;
963 void *apr_cvp;
964 u16 cvp_handle;
965
966 if (v == NULL) {
967 pr_err("%s: v is NULL\n", __func__);
968 return -EINVAL;
969 }
Neema Shetty2c07eb52011-08-21 20:33:52 -0700970 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700971
972 if (!apr_cvp) {
973 pr_err("%s: apr regist failed\n", __func__);
974 return -EINVAL;
975 }
976 cvp_handle = voice_get_cvp_handle(v);
977
978 /* disable vocproc and wait for respose */
979 cvp_disable_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
980 APR_HDR_LEN(APR_HDR_SIZE),
981 APR_PKT_VER);
982 cvp_disable_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
983 sizeof(cvp_disable_cmd) - APR_HDR_SIZE);
984 pr_debug("cvp_disable_cmd pkt size = %d, cvp_handle=%d\n",
985 cvp_disable_cmd.pkt_size, cvp_handle);
Neema Shetty2c07eb52011-08-21 20:33:52 -0700986 cvp_disable_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700987 cvp_disable_cmd.dest_port = cvp_handle;
988 cvp_disable_cmd.token = 0;
989 cvp_disable_cmd.opcode = VSS_IVOCPROC_CMD_DISABLE;
990
991 v->cvp_state = CMD_STATUS_FAIL;
992 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_disable_cmd);
993 if (ret < 0) {
994 pr_err("Fail in sending VSS_IVOCPROC_CMD_DISABLE\n");
995 goto fail;
996 }
997 ret = wait_event_timeout(v->cvp_wait,
998 (v->cvp_state == CMD_STATUS_SUCCESS),
999 msecs_to_jiffies(TIMEOUT_MS));
1000 if (!ret) {
1001 pr_err("%s: wait_event timeout\n", __func__);
1002 goto fail;
1003 }
1004
1005 return 0;
1006fail:
1007 return -EINVAL;
1008}
1009
1010static int voice_send_set_device_cmd(struct voice_data *v)
1011{
1012 struct cvp_set_device_cmd cvp_setdev_cmd;
1013 int ret = 0;
1014 void *apr_cvp;
1015 u16 cvp_handle;
1016
1017 if (v == NULL) {
1018 pr_err("%s: v is NULL\n", __func__);
1019 return -EINVAL;
1020 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001021 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001022
1023 if (!apr_cvp) {
1024 pr_err("%s: apr_cvp is NULL.\n", __func__);
1025 return -EINVAL;
1026 }
1027 cvp_handle = voice_get_cvp_handle(v);
1028
1029 /* set device and wait for response */
1030 cvp_setdev_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1031 APR_HDR_LEN(APR_HDR_SIZE),
1032 APR_PKT_VER);
1033 cvp_setdev_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1034 sizeof(cvp_setdev_cmd) - APR_HDR_SIZE);
1035 pr_debug(" send create cvp setdev, pkt size = %d\n",
1036 cvp_setdev_cmd.hdr.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001037 cvp_setdev_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001038 cvp_setdev_cmd.hdr.dest_port = cvp_handle;
1039 cvp_setdev_cmd.hdr.token = 0;
1040 cvp_setdev_cmd.hdr.opcode = VSS_IVOCPROC_CMD_SET_DEVICE;
1041
1042 /* Use default topology if invalid value in ACDB */
1043 cvp_setdev_cmd.cvp_set_device.tx_topology_id =
1044 get_voice_tx_topology();
1045 if (cvp_setdev_cmd.cvp_set_device.tx_topology_id == 0)
1046 cvp_setdev_cmd.cvp_set_device.tx_topology_id =
1047 VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
1048
1049 cvp_setdev_cmd.cvp_set_device.rx_topology_id =
1050 get_voice_rx_topology();
1051 if (cvp_setdev_cmd.cvp_set_device.rx_topology_id == 0)
1052 cvp_setdev_cmd.cvp_set_device.rx_topology_id =
1053 VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
1054 cvp_setdev_cmd.cvp_set_device.tx_port_id = v->dev_tx.port_id;
1055 cvp_setdev_cmd.cvp_set_device.rx_port_id = v->dev_rx.port_id;
1056 pr_debug("topology=%d , tx_port_id=%d, rx_port_id=%d\n",
1057 cvp_setdev_cmd.cvp_set_device.tx_topology_id,
1058 cvp_setdev_cmd.cvp_set_device.tx_port_id,
1059 cvp_setdev_cmd.cvp_set_device.rx_port_id);
1060
1061 v->cvp_state = CMD_STATUS_FAIL;
1062 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_setdev_cmd);
1063 if (ret < 0) {
1064 pr_err("Fail in sending VOCPROC_FULL_CONTROL_SESSION\n");
1065 goto fail;
1066 }
1067 pr_debug("wait for cvp create session event\n");
1068 ret = wait_event_timeout(v->cvp_wait,
1069 (v->cvp_state == CMD_STATUS_SUCCESS),
1070 msecs_to_jiffies(TIMEOUT_MS));
1071 if (!ret) {
1072 pr_err("%s: wait_event timeout\n", __func__);
1073 goto fail;
1074 }
1075
1076 return 0;
1077fail:
1078 return -EINVAL;
1079}
1080
1081static int voice_send_stop_voice_cmd(struct voice_data *v)
1082{
1083 struct apr_hdr mvm_stop_voice_cmd;
1084 int ret = 0;
1085 void *apr_mvm;
1086 u16 mvm_handle;
1087
1088 if (v == NULL) {
1089 pr_err("%s: v is NULL\n", __func__);
1090 return -EINVAL;
1091 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001092 apr_mvm = common.apr_q6_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001093
1094 if (!apr_mvm) {
1095 pr_err("%s: apr_mvm is NULL.\n", __func__);
1096 return -EINVAL;
1097 }
1098 mvm_handle = voice_get_mvm_handle(v);
1099
1100 mvm_stop_voice_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1101 APR_HDR_LEN(APR_HDR_SIZE),
1102 APR_PKT_VER);
1103 mvm_stop_voice_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1104 sizeof(mvm_stop_voice_cmd) - APR_HDR_SIZE);
1105 pr_debug("send mvm_stop_voice_cmd pkt size = %d\n",
1106 mvm_stop_voice_cmd.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001107 mvm_stop_voice_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001108 mvm_stop_voice_cmd.dest_port = mvm_handle;
1109 mvm_stop_voice_cmd.token = 0;
1110 mvm_stop_voice_cmd.opcode = VSS_IMVM_CMD_STOP_VOICE;
1111
1112 v->mvm_state = CMD_STATUS_FAIL;
1113 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_stop_voice_cmd);
1114 if (ret < 0) {
1115 pr_err("Fail in sending VSS_IMVM_CMD_STOP_VOICE\n");
1116 goto fail;
1117 }
1118 ret = wait_event_timeout(v->mvm_wait,
1119 (v->mvm_state == CMD_STATUS_SUCCESS),
1120 msecs_to_jiffies(TIMEOUT_MS));
1121 if (!ret) {
1122 pr_err("%s: wait_event timeout\n", __func__);
1123 goto fail;
1124 }
1125
1126 return 0;
1127fail:
1128 return -EINVAL;
1129}
1130
Helen Zeng29eb7442011-06-20 11:06:29 -07001131static int voice_send_cvs_register_cal_cmd(struct voice_data *v)
1132{
1133 struct cvs_register_cal_data_cmd cvs_reg_cal_cmd;
1134 struct acdb_cal_block cal_block;
1135 int ret = 0;
1136 void *apr_cvs;
1137 u16 cvs_handle;
Helen Zeng6e64dba2012-03-08 18:30:11 -08001138 uint32_t cal_paddr;
Helen Zeng29eb7442011-06-20 11:06:29 -07001139
1140 /* get the cvs cal data */
1141 get_all_vocstrm_cal(&cal_block);
1142 if (cal_block.cal_size == 0)
1143 goto fail;
1144
1145 if (v == NULL) {
1146 pr_err("%s: v is NULL\n", __func__);
1147 return -EINVAL;
1148 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001149 apr_cvs = common.apr_q6_cvs;
Helen Zeng29eb7442011-06-20 11:06:29 -07001150
1151 if (!apr_cvs) {
1152 pr_err("%s: apr_cvs is NULL.\n", __func__);
1153 return -EINVAL;
1154 }
Helen Zeng6e64dba2012-03-08 18:30:11 -08001155
1156 if (is_voip_session(v->session_id)) {
1157 if (common.cvs_cal.buf) {
1158 cal_paddr = common.cvs_cal.phy;
1159
1160 memcpy(common.cvs_cal.buf,
1161 (void *) cal_block.cal_kvaddr,
1162 cal_block.cal_size);
1163 } else {
1164 return -EINVAL;
1165 }
1166 } else {
1167 cal_paddr = cal_block.cal_paddr;
1168 }
1169
Helen Zeng29eb7442011-06-20 11:06:29 -07001170 cvs_handle = voice_get_cvs_handle(v);
1171
1172 /* fill in the header */
1173 cvs_reg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1174 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1175 cvs_reg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1176 sizeof(cvs_reg_cal_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001177 cvs_reg_cal_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001178 cvs_reg_cal_cmd.hdr.dest_port = cvs_handle;
1179 cvs_reg_cal_cmd.hdr.token = 0;
1180 cvs_reg_cal_cmd.hdr.opcode = VSS_ISTREAM_CMD_REGISTER_CALIBRATION_DATA;
1181
Helen Zeng6e64dba2012-03-08 18:30:11 -08001182 cvs_reg_cal_cmd.cvs_cal_data.phys_addr = cal_paddr;
Helen Zeng29eb7442011-06-20 11:06:29 -07001183 cvs_reg_cal_cmd.cvs_cal_data.mem_size = cal_block.cal_size;
1184
1185 v->cvs_state = CMD_STATUS_FAIL;
1186 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_reg_cal_cmd);
1187 if (ret < 0) {
1188 pr_err("Fail: sending cvs cal,\n");
1189 goto fail;
1190 }
1191 ret = wait_event_timeout(v->cvs_wait,
1192 (v->cvs_state == CMD_STATUS_SUCCESS),
1193 msecs_to_jiffies(TIMEOUT_MS));
1194 if (!ret) {
1195 pr_err("%s: wait_event timeout\n", __func__);
1196 goto fail;
1197 }
1198 return 0;
1199fail:
1200 return -EINVAL;
1201
1202}
1203
1204static int voice_send_cvs_deregister_cal_cmd(struct voice_data *v)
1205{
1206 struct cvs_deregister_cal_data_cmd cvs_dereg_cal_cmd;
1207 struct acdb_cal_block cal_block;
1208 int ret = 0;
1209 void *apr_cvs;
1210 u16 cvs_handle;
1211
1212 get_all_vocstrm_cal(&cal_block);
1213 if (cal_block.cal_size == 0)
1214 return 0;
1215
1216 if (v == NULL) {
1217 pr_err("%s: v is NULL\n", __func__);
1218 return -EINVAL;
1219 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001220 apr_cvs = common.apr_q6_cvs;
Helen Zeng29eb7442011-06-20 11:06:29 -07001221
1222 if (!apr_cvs) {
1223 pr_err("%s: apr_cvs is NULL.\n", __func__);
1224 return -EINVAL;
1225 }
1226 cvs_handle = voice_get_cvs_handle(v);
1227
1228 /* fill in the header */
1229 cvs_dereg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1230 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1231 cvs_dereg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1232 sizeof(cvs_dereg_cal_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001233 cvs_dereg_cal_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001234 cvs_dereg_cal_cmd.hdr.dest_port = cvs_handle;
1235 cvs_dereg_cal_cmd.hdr.token = 0;
1236 cvs_dereg_cal_cmd.hdr.opcode =
1237 VSS_ISTREAM_CMD_DEREGISTER_CALIBRATION_DATA;
1238
1239 v->cvs_state = CMD_STATUS_FAIL;
1240 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_dereg_cal_cmd);
1241 if (ret < 0) {
1242 pr_err("Fail: sending cvs cal,\n");
1243 goto fail;
1244 }
1245 ret = wait_event_timeout(v->cvs_wait,
1246 (v->cvs_state == CMD_STATUS_SUCCESS),
1247 msecs_to_jiffies(TIMEOUT_MS));
1248 if (!ret) {
1249 pr_err("%s: wait_event timeout\n", __func__);
1250 goto fail;
1251 }
1252 return 0;
1253fail:
1254 return -EINVAL;
1255
1256}
1257
1258static int voice_send_cvp_map_memory_cmd(struct voice_data *v)
1259{
1260 struct vss_map_memory_cmd cvp_map_mem_cmd;
1261 struct acdb_cal_block cal_block;
1262 int ret = 0;
1263 void *apr_cvp;
1264 u16 cvp_handle;
Helen Zeng6e64dba2012-03-08 18:30:11 -08001265 uint32_t cal_paddr;
Helen Zeng29eb7442011-06-20 11:06:29 -07001266
1267 /* get all cvp cal data */
1268 get_all_cvp_cal(&cal_block);
1269 if (cal_block.cal_size == 0)
1270 goto fail;
1271
1272 if (v == NULL) {
1273 pr_err("%s: v is NULL\n", __func__);
1274 return -EINVAL;
1275 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001276 apr_cvp = common.apr_q6_cvp;
Helen Zeng29eb7442011-06-20 11:06:29 -07001277
1278 if (!apr_cvp) {
1279 pr_err("%s: apr_cvp is NULL.\n", __func__);
1280 return -EINVAL;
1281 }
Helen Zeng6e64dba2012-03-08 18:30:11 -08001282
1283 if (is_voip_session(v->session_id)) {
1284 if (common.cvp_cal.buf)
1285 cal_paddr = common.cvp_cal.phy;
1286 else
1287 return -EINVAL;
1288 } else {
1289 cal_paddr = cal_block.cal_paddr;
1290 }
Helen Zeng29eb7442011-06-20 11:06:29 -07001291 cvp_handle = voice_get_cvp_handle(v);
1292
1293 /* fill in the header */
1294 cvp_map_mem_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1295 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1296 cvp_map_mem_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1297 sizeof(cvp_map_mem_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001298 cvp_map_mem_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001299 cvp_map_mem_cmd.hdr.dest_port = cvp_handle;
1300 cvp_map_mem_cmd.hdr.token = 0;
1301 cvp_map_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_MAP_MEMORY;
1302
Helen Zeng6e64dba2012-03-08 18:30:11 -08001303 pr_debug("%s, phy_addr:0x%x, mem_size:%d\n", __func__,
1304 cal_paddr, cal_block.cal_size);
1305 cvp_map_mem_cmd.vss_map_mem.phys_addr = cal_paddr;
Helen Zeng29eb7442011-06-20 11:06:29 -07001306 cvp_map_mem_cmd.vss_map_mem.mem_size = cal_block.cal_size;
1307 cvp_map_mem_cmd.vss_map_mem.mem_pool_id =
1308 VSS_ICOMMON_MAP_MEMORY_SHMEM8_4K_POOL;
1309
1310 v->cvp_state = CMD_STATUS_FAIL;
1311 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_map_mem_cmd);
1312 if (ret < 0) {
1313 pr_err("Fail: sending cvp cal,\n");
1314 goto fail;
1315 }
1316 ret = wait_event_timeout(v->cvp_wait,
1317 (v->cvp_state == CMD_STATUS_SUCCESS),
1318 msecs_to_jiffies(TIMEOUT_MS));
1319 if (!ret) {
1320 pr_err("%s: wait_event timeout\n", __func__);
1321 goto fail;
1322 }
1323 return 0;
1324fail:
1325 return -EINVAL;
1326
1327}
1328
1329static int voice_send_cvp_unmap_memory_cmd(struct voice_data *v)
1330{
1331 struct vss_unmap_memory_cmd cvp_unmap_mem_cmd;
1332 struct acdb_cal_block cal_block;
1333 int ret = 0;
1334 void *apr_cvp;
1335 u16 cvp_handle;
Helen Zeng6e64dba2012-03-08 18:30:11 -08001336 uint32_t cal_paddr;
Helen Zeng29eb7442011-06-20 11:06:29 -07001337
1338 get_all_cvp_cal(&cal_block);
1339 if (cal_block.cal_size == 0)
1340 return 0;
1341
1342 if (v == NULL) {
1343 pr_err("%s: v is NULL\n", __func__);
1344 return -EINVAL;
1345 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001346 apr_cvp = common.apr_q6_cvp;
Helen Zeng29eb7442011-06-20 11:06:29 -07001347
1348 if (!apr_cvp) {
1349 pr_err("%s: apr_cvp is NULL.\n", __func__);
1350 return -EINVAL;
1351 }
Helen Zeng6e64dba2012-03-08 18:30:11 -08001352
1353 if (is_voip_session(v->session_id))
1354 cal_paddr = common.cvp_cal.phy;
1355 else
1356 cal_paddr = cal_block.cal_paddr;
1357
Helen Zeng29eb7442011-06-20 11:06:29 -07001358 cvp_handle = voice_get_cvp_handle(v);
1359
1360 /* fill in the header */
1361 cvp_unmap_mem_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1362 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1363 cvp_unmap_mem_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1364 sizeof(cvp_unmap_mem_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001365 cvp_unmap_mem_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001366 cvp_unmap_mem_cmd.hdr.dest_port = cvp_handle;
1367 cvp_unmap_mem_cmd.hdr.token = 0;
1368 cvp_unmap_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_UNMAP_MEMORY;
1369
Helen Zeng6e64dba2012-03-08 18:30:11 -08001370 cvp_unmap_mem_cmd.vss_unmap_mem.phys_addr = cal_paddr;
Helen Zeng29eb7442011-06-20 11:06:29 -07001371
1372 v->cvp_state = CMD_STATUS_FAIL;
1373 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_unmap_mem_cmd);
1374 if (ret < 0) {
1375 pr_err("Fail: sending cvp cal,\n");
1376 goto fail;
1377 }
1378 ret = wait_event_timeout(v->cvp_wait,
1379 (v->cvp_state == CMD_STATUS_SUCCESS),
1380 msecs_to_jiffies(TIMEOUT_MS));
1381 if (!ret) {
1382 pr_err("%s: wait_event timeout\n", __func__);
1383 goto fail;
1384 }
1385 return 0;
1386fail:
1387 return -EINVAL;
1388
1389}
1390
1391static int voice_send_cvs_map_memory_cmd(struct voice_data *v)
1392{
1393 struct vss_map_memory_cmd cvs_map_mem_cmd;
1394 struct acdb_cal_block cal_block;
1395 int ret = 0;
1396 void *apr_cvs;
1397 u16 cvs_handle;
Helen Zeng6e64dba2012-03-08 18:30:11 -08001398 uint32_t cal_paddr;
Helen Zeng29eb7442011-06-20 11:06:29 -07001399
1400 /* get all cvs cal data */
1401 get_all_vocstrm_cal(&cal_block);
1402 if (cal_block.cal_size == 0)
1403 goto fail;
1404
1405 if (v == NULL) {
1406 pr_err("%s: v is NULL\n", __func__);
1407 return -EINVAL;
1408 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001409 apr_cvs = common.apr_q6_cvs;
Helen Zeng29eb7442011-06-20 11:06:29 -07001410
1411 if (!apr_cvs) {
1412 pr_err("%s: apr_cvs is NULL.\n", __func__);
1413 return -EINVAL;
1414 }
Helen Zeng6e64dba2012-03-08 18:30:11 -08001415
1416 if (is_voip_session(v->session_id)) {
1417 if (common.cvs_cal.buf)
1418 cal_paddr = common.cvs_cal.phy;
1419 else
1420 return -EINVAL;
1421 } else {
1422 cal_paddr = cal_block.cal_paddr;
1423 }
1424
Helen Zeng29eb7442011-06-20 11:06:29 -07001425 cvs_handle = voice_get_cvs_handle(v);
1426
1427 /* fill in the header */
1428 cvs_map_mem_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1429 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1430 cvs_map_mem_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1431 sizeof(cvs_map_mem_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001432 cvs_map_mem_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001433 cvs_map_mem_cmd.hdr.dest_port = cvs_handle;
1434 cvs_map_mem_cmd.hdr.token = 0;
1435 cvs_map_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_MAP_MEMORY;
1436
Helen Zeng6e64dba2012-03-08 18:30:11 -08001437 pr_debug("%s, phys_addr: 0x%x, mem_size: %d\n", __func__,
1438 cal_paddr, cal_block.cal_size);
1439 cvs_map_mem_cmd.vss_map_mem.phys_addr = cal_paddr;
Helen Zeng29eb7442011-06-20 11:06:29 -07001440 cvs_map_mem_cmd.vss_map_mem.mem_size = cal_block.cal_size;
1441 cvs_map_mem_cmd.vss_map_mem.mem_pool_id =
1442 VSS_ICOMMON_MAP_MEMORY_SHMEM8_4K_POOL;
1443
1444 v->cvs_state = CMD_STATUS_FAIL;
1445 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_map_mem_cmd);
1446 if (ret < 0) {
1447 pr_err("Fail: sending cvs cal,\n");
1448 goto fail;
1449 }
1450 ret = wait_event_timeout(v->cvs_wait,
1451 (v->cvs_state == CMD_STATUS_SUCCESS),
1452 msecs_to_jiffies(TIMEOUT_MS));
1453 if (!ret) {
1454 pr_err("%s: wait_event timeout\n", __func__);
1455 goto fail;
1456 }
1457 return 0;
1458fail:
1459 return -EINVAL;
1460
1461}
1462
1463static int voice_send_cvs_unmap_memory_cmd(struct voice_data *v)
1464{
1465 struct vss_unmap_memory_cmd cvs_unmap_mem_cmd;
1466 struct acdb_cal_block cal_block;
1467 int ret = 0;
1468 void *apr_cvs;
1469 u16 cvs_handle;
Helen Zeng6e64dba2012-03-08 18:30:11 -08001470 uint32_t cal_paddr;
Helen Zeng29eb7442011-06-20 11:06:29 -07001471
1472 get_all_vocstrm_cal(&cal_block);
1473 if (cal_block.cal_size == 0)
1474 return 0;
1475
1476 if (v == NULL) {
1477 pr_err("%s: v is NULL\n", __func__);
1478 return -EINVAL;
1479 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001480 apr_cvs = common.apr_q6_cvs;
Helen Zeng29eb7442011-06-20 11:06:29 -07001481
1482 if (!apr_cvs) {
1483 pr_err("%s: apr_cvs is NULL.\n", __func__);
1484 return -EINVAL;
1485 }
Helen Zeng6e64dba2012-03-08 18:30:11 -08001486
1487 if (is_voip_session(v->session_id))
1488 cal_paddr = common.cvs_cal.phy;
1489 else
1490 cal_paddr = cal_block.cal_paddr;
1491
Helen Zeng29eb7442011-06-20 11:06:29 -07001492 cvs_handle = voice_get_cvs_handle(v);
1493
1494 /* fill in the header */
1495 cvs_unmap_mem_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1496 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1497 cvs_unmap_mem_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1498 sizeof(cvs_unmap_mem_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001499 cvs_unmap_mem_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001500 cvs_unmap_mem_cmd.hdr.dest_port = cvs_handle;
1501 cvs_unmap_mem_cmd.hdr.token = 0;
1502 cvs_unmap_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_UNMAP_MEMORY;
1503
Helen Zeng6e64dba2012-03-08 18:30:11 -08001504 cvs_unmap_mem_cmd.vss_unmap_mem.phys_addr = cal_paddr;
Helen Zeng29eb7442011-06-20 11:06:29 -07001505
1506 v->cvs_state = CMD_STATUS_FAIL;
1507 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_unmap_mem_cmd);
1508 if (ret < 0) {
1509 pr_err("Fail: sending cvs cal,\n");
1510 goto fail;
1511 }
1512 ret = wait_event_timeout(v->cvs_wait,
1513 (v->cvs_state == CMD_STATUS_SUCCESS),
1514 msecs_to_jiffies(TIMEOUT_MS));
1515 if (!ret) {
1516 pr_err("%s: wait_event timeout\n", __func__);
1517 goto fail;
1518 }
1519 return 0;
1520fail:
1521 return -EINVAL;
1522
1523}
1524
1525static int voice_send_cvp_register_cal_cmd(struct voice_data *v)
1526{
1527 struct cvp_register_cal_data_cmd cvp_reg_cal_cmd;
1528 struct acdb_cal_block cal_block;
1529 int ret = 0;
1530 void *apr_cvp;
1531 u16 cvp_handle;
Helen Zeng6e64dba2012-03-08 18:30:11 -08001532 uint32_t cal_paddr;
Helen Zeng29eb7442011-06-20 11:06:29 -07001533
1534 /* get the cvp cal data */
1535 get_all_vocproc_cal(&cal_block);
1536 if (cal_block.cal_size == 0)
1537 goto fail;
1538
1539 if (v == NULL) {
1540 pr_err("%s: v is NULL\n", __func__);
1541 return -EINVAL;
1542 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001543 apr_cvp = common.apr_q6_cvp;
Helen Zeng29eb7442011-06-20 11:06:29 -07001544
1545 if (!apr_cvp) {
1546 pr_err("%s: apr_cvp is NULL.\n", __func__);
1547 return -EINVAL;
1548 }
Helen Zeng6e64dba2012-03-08 18:30:11 -08001549
1550 if (is_voip_session(v->session_id)) {
1551 if (common.cvp_cal.buf) {
1552 cal_paddr = common.cvp_cal.phy;
1553
1554 memcpy(common.cvp_cal.buf,
1555 (void *)cal_block.cal_kvaddr,
1556 cal_block.cal_size);
1557 } else {
1558 return -EINVAL;
1559 }
1560 } else {
1561 cal_paddr = cal_block.cal_paddr;
1562 }
1563
Helen Zeng29eb7442011-06-20 11:06:29 -07001564 cvp_handle = voice_get_cvp_handle(v);
1565
1566 /* fill in the header */
1567 cvp_reg_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_reg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1570 sizeof(cvp_reg_cal_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001571 cvp_reg_cal_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001572 cvp_reg_cal_cmd.hdr.dest_port = cvp_handle;
1573 cvp_reg_cal_cmd.hdr.token = 0;
1574 cvp_reg_cal_cmd.hdr.opcode = VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA;
1575
Helen Zeng6e64dba2012-03-08 18:30:11 -08001576 cvp_reg_cal_cmd.cvp_cal_data.phys_addr = cal_paddr;
Helen Zeng29eb7442011-06-20 11:06:29 -07001577 cvp_reg_cal_cmd.cvp_cal_data.mem_size = cal_block.cal_size;
1578
1579 v->cvp_state = CMD_STATUS_FAIL;
1580 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_reg_cal_cmd);
1581 if (ret < 0) {
1582 pr_err("Fail: sending cvp cal,\n");
1583 goto fail;
1584 }
1585 ret = wait_event_timeout(v->cvp_wait,
1586 (v->cvp_state == CMD_STATUS_SUCCESS),
1587 msecs_to_jiffies(TIMEOUT_MS));
1588 if (!ret) {
1589 pr_err("%s: wait_event timeout\n", __func__);
1590 goto fail;
1591 }
1592 return 0;
1593fail:
1594 return -EINVAL;
1595
1596}
1597
1598static int voice_send_cvp_deregister_cal_cmd(struct voice_data *v)
1599{
1600 struct cvp_deregister_cal_data_cmd cvp_dereg_cal_cmd;
1601 struct acdb_cal_block cal_block;
1602 int ret = 0;
1603 void *apr_cvp;
1604 u16 cvp_handle;
1605
1606 get_all_vocproc_cal(&cal_block);
1607 if (cal_block.cal_size == 0)
1608 return 0;
1609
1610 if (v == NULL) {
1611 pr_err("%s: v is NULL\n", __func__);
1612 return -EINVAL;
1613 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001614 apr_cvp = common.apr_q6_cvp;
Helen Zeng29eb7442011-06-20 11:06:29 -07001615
1616 if (!apr_cvp) {
1617 pr_err("%s: apr_cvp is NULL.\n", __func__);
1618 return -EINVAL;
1619 }
1620 cvp_handle = voice_get_cvp_handle(v);
1621
1622 /* fill in the header */
1623 cvp_dereg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1624 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1625 cvp_dereg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1626 sizeof(cvp_dereg_cal_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001627 cvp_dereg_cal_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001628 cvp_dereg_cal_cmd.hdr.dest_port = cvp_handle;
1629 cvp_dereg_cal_cmd.hdr.token = 0;
1630 cvp_dereg_cal_cmd.hdr.opcode =
1631 VSS_IVOCPROC_CMD_DEREGISTER_CALIBRATION_DATA;
1632
1633 v->cvp_state = CMD_STATUS_FAIL;
1634 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_dereg_cal_cmd);
1635 if (ret < 0) {
1636 pr_err("Fail: sending cvp cal,\n");
1637 goto fail;
1638 }
1639 ret = wait_event_timeout(v->cvp_wait,
1640 (v->cvp_state == CMD_STATUS_SUCCESS),
1641 msecs_to_jiffies(TIMEOUT_MS));
1642 if (!ret) {
1643 pr_err("%s: wait_event timeout\n", __func__);
1644 goto fail;
1645 }
1646 return 0;
1647fail:
1648 return -EINVAL;
1649
1650}
1651
1652static int voice_send_cvp_register_vol_cal_table_cmd(struct voice_data *v)
1653{
1654 struct cvp_register_vol_cal_table_cmd cvp_reg_cal_tbl_cmd;
Helen Zeng6e64dba2012-03-08 18:30:11 -08001655 struct acdb_cal_block vol_block;
1656 struct acdb_cal_block voc_block;
Helen Zeng29eb7442011-06-20 11:06:29 -07001657 int ret = 0;
1658 void *apr_cvp;
1659 u16 cvp_handle;
Helen Zeng6e64dba2012-03-08 18:30:11 -08001660 uint32_t cal_paddr;
Helen Zeng29eb7442011-06-20 11:06:29 -07001661
1662 /* get the cvp vol cal data */
Helen Zeng6e64dba2012-03-08 18:30:11 -08001663 get_all_vocvol_cal(&vol_block);
1664 get_all_vocproc_cal(&voc_block);
1665
1666 if (vol_block.cal_size == 0)
Helen Zeng29eb7442011-06-20 11:06:29 -07001667 goto fail;
1668
1669 if (v == NULL) {
1670 pr_err("%s: v is NULL\n", __func__);
1671 return -EINVAL;
1672 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001673 apr_cvp = common.apr_q6_cvp;
Helen Zeng29eb7442011-06-20 11:06:29 -07001674
1675 if (!apr_cvp) {
1676 pr_err("%s: apr_cvp is NULL.\n", __func__);
1677 return -EINVAL;
1678 }
Helen Zeng6e64dba2012-03-08 18:30:11 -08001679
1680 if (is_voip_session(v->session_id)) {
1681 if (common.cvp_cal.buf) {
1682 cal_paddr = common.cvp_cal.phy + voc_block.cal_size;
1683
1684 memcpy(common.cvp_cal.buf + voc_block.cal_size,
1685 (void *) vol_block.cal_kvaddr,
1686 vol_block.cal_size);
1687 } else {
1688 return -EINVAL;
1689 }
1690 } else {
1691 cal_paddr = vol_block.cal_paddr;
1692 }
1693
Helen Zeng29eb7442011-06-20 11:06:29 -07001694 cvp_handle = voice_get_cvp_handle(v);
1695
1696 /* fill in the header */
1697 cvp_reg_cal_tbl_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1698 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1699 cvp_reg_cal_tbl_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1700 sizeof(cvp_reg_cal_tbl_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001701 cvp_reg_cal_tbl_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001702 cvp_reg_cal_tbl_cmd.hdr.dest_port = cvp_handle;
1703 cvp_reg_cal_tbl_cmd.hdr.token = 0;
1704 cvp_reg_cal_tbl_cmd.hdr.opcode =
1705 VSS_IVOCPROC_CMD_REGISTER_VOLUME_CAL_TABLE;
1706
Helen Zeng6e64dba2012-03-08 18:30:11 -08001707 cvp_reg_cal_tbl_cmd.cvp_vol_cal_tbl.phys_addr = cal_paddr;
1708 cvp_reg_cal_tbl_cmd.cvp_vol_cal_tbl.mem_size = vol_block.cal_size;
Helen Zeng29eb7442011-06-20 11:06:29 -07001709
1710 v->cvp_state = CMD_STATUS_FAIL;
1711 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_reg_cal_tbl_cmd);
1712 if (ret < 0) {
1713 pr_err("Fail: sending cvp cal table,\n");
1714 goto fail;
1715 }
1716 ret = wait_event_timeout(v->cvp_wait,
1717 (v->cvp_state == CMD_STATUS_SUCCESS),
1718 msecs_to_jiffies(TIMEOUT_MS));
1719 if (!ret) {
1720 pr_err("%s: wait_event timeout\n", __func__);
1721 goto fail;
1722 }
1723 return 0;
1724fail:
1725 return -EINVAL;
1726
1727}
1728
1729static int voice_send_cvp_deregister_vol_cal_table_cmd(struct voice_data *v)
1730{
1731 struct cvp_deregister_vol_cal_table_cmd cvp_dereg_cal_tbl_cmd;
1732 struct acdb_cal_block cal_block;
1733 int ret = 0;
1734 void *apr_cvp;
1735 u16 cvp_handle;
1736
1737 get_all_vocvol_cal(&cal_block);
1738 if (cal_block.cal_size == 0)
1739 return 0;
1740
1741 if (v == NULL) {
1742 pr_err("%s: v is NULL\n", __func__);
1743 return -EINVAL;
1744 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001745 apr_cvp = common.apr_q6_cvp;
Helen Zeng29eb7442011-06-20 11:06:29 -07001746
1747 if (!apr_cvp) {
1748 pr_err("%s: apr_cvp is NULL.\n", __func__);
1749 return -EINVAL;
1750 }
1751 cvp_handle = voice_get_cvp_handle(v);
1752
1753 /* fill in the header */
1754 cvp_dereg_cal_tbl_cmd.hdr.hdr_field = APR_HDR_FIELD(
1755 APR_MSG_TYPE_SEQ_CMD,
1756 APR_HDR_LEN(APR_HDR_SIZE),
1757 APR_PKT_VER);
1758 cvp_dereg_cal_tbl_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1759 sizeof(cvp_dereg_cal_tbl_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001760 cvp_dereg_cal_tbl_cmd.hdr.src_port = v->session_id;
Helen Zeng29eb7442011-06-20 11:06:29 -07001761 cvp_dereg_cal_tbl_cmd.hdr.dest_port = cvp_handle;
1762 cvp_dereg_cal_tbl_cmd.hdr.token = 0;
1763 cvp_dereg_cal_tbl_cmd.hdr.opcode =
1764 VSS_IVOCPROC_CMD_DEREGISTER_VOLUME_CAL_TABLE;
1765
1766 v->cvp_state = CMD_STATUS_FAIL;
1767 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_dereg_cal_tbl_cmd);
1768 if (ret < 0) {
1769 pr_err("Fail: sending cvp cal table,\n");
1770 goto fail;
1771 }
1772 ret = wait_event_timeout(v->cvp_wait,
1773 (v->cvp_state == CMD_STATUS_SUCCESS),
1774 msecs_to_jiffies(TIMEOUT_MS));
1775 if (!ret) {
1776 pr_err("%s: wait_event timeout\n", __func__);
1777 goto fail;
1778 }
1779 return 0;
1780fail:
1781 return -EINVAL;
1782
1783}
Neema Shetty2c07eb52011-08-21 20:33:52 -07001784
Helen Zeng44d4d272011-08-10 14:49:20 -07001785static int voice_send_set_widevoice_enable_cmd(struct voice_data *v)
1786{
1787 struct mvm_set_widevoice_enable_cmd mvm_set_wv_cmd;
1788 int ret = 0;
1789 void *apr_mvm;
1790 u16 mvm_handle;
1791
1792 if (v == NULL) {
1793 pr_err("%s: v is NULL\n", __func__);
1794 return -EINVAL;
1795 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001796 apr_mvm = common.apr_q6_mvm;
Helen Zeng44d4d272011-08-10 14:49:20 -07001797
1798 if (!apr_mvm) {
1799 pr_err("%s: apr_mvm is NULL.\n", __func__);
1800 return -EINVAL;
1801 }
1802 mvm_handle = voice_get_mvm_handle(v);
1803
1804 /* fill in the header */
1805 mvm_set_wv_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1806 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1807 mvm_set_wv_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1808 sizeof(mvm_set_wv_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001809 mvm_set_wv_cmd.hdr.src_port = v->session_id;
Helen Zeng44d4d272011-08-10 14:49:20 -07001810 mvm_set_wv_cmd.hdr.dest_port = mvm_handle;
1811 mvm_set_wv_cmd.hdr.token = 0;
1812 mvm_set_wv_cmd.hdr.opcode = VSS_IWIDEVOICE_CMD_SET_WIDEVOICE;
1813
1814 mvm_set_wv_cmd.vss_set_wv.enable = v->wv_enable;
1815
1816 v->mvm_state = CMD_STATUS_FAIL;
1817 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_wv_cmd);
1818 if (ret < 0) {
1819 pr_err("Fail: sending mvm set widevoice enable,\n");
1820 goto fail;
1821 }
1822 ret = wait_event_timeout(v->mvm_wait,
1823 (v->mvm_state == CMD_STATUS_SUCCESS),
1824 msecs_to_jiffies(TIMEOUT_MS));
1825 if (!ret) {
1826 pr_err("%s: wait_event timeout\n", __func__);
1827 goto fail;
1828 }
1829 return 0;
1830fail:
1831 return -EINVAL;
1832}
1833
Helen Zeng4e531942011-12-17 21:14:40 -08001834static int voice_send_set_pp_enable_cmd(struct voice_data *v,
1835 uint32_t module_id, int enable)
Helen Zengbb49c702011-09-06 14:09:13 -07001836{
Helen Zeng4e531942011-12-17 21:14:40 -08001837 struct cvs_set_pp_enable_cmd cvs_set_pp_cmd;
Helen Zengbb49c702011-09-06 14:09:13 -07001838 int ret = 0;
1839 void *apr_cvs;
1840 u16 cvs_handle;
1841
1842 if (v == NULL) {
1843 pr_err("%s: v is NULL\n", __func__);
1844 return -EINVAL;
1845 }
1846 apr_cvs = common.apr_q6_cvs;
1847
1848 if (!apr_cvs) {
1849 pr_err("%s: apr_cvs is NULL.\n", __func__);
1850 return -EINVAL;
1851 }
1852 cvs_handle = voice_get_cvs_handle(v);
1853
1854 /* fill in the header */
Helen Zeng4e531942011-12-17 21:14:40 -08001855 cvs_set_pp_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
Helen Zengbb49c702011-09-06 14:09:13 -07001856 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
Helen Zeng4e531942011-12-17 21:14:40 -08001857 cvs_set_pp_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1858 sizeof(cvs_set_pp_cmd) - APR_HDR_SIZE);
1859 cvs_set_pp_cmd.hdr.src_port = v->session_id;
1860 cvs_set_pp_cmd.hdr.dest_port = cvs_handle;
1861 cvs_set_pp_cmd.hdr.token = 0;
1862 cvs_set_pp_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_UI_PROPERTY;
Helen Zengbb49c702011-09-06 14:09:13 -07001863
Helen Zeng4e531942011-12-17 21:14:40 -08001864 cvs_set_pp_cmd.vss_set_pp.module_id = module_id;
1865 cvs_set_pp_cmd.vss_set_pp.param_id = VOICE_PARAM_MOD_ENABLE;
1866 cvs_set_pp_cmd.vss_set_pp.param_size = MOD_ENABLE_PARAM_LEN;
1867 cvs_set_pp_cmd.vss_set_pp.reserved = 0;
1868 cvs_set_pp_cmd.vss_set_pp.enable = enable;
1869 cvs_set_pp_cmd.vss_set_pp.reserved_field = 0;
1870 pr_debug("voice_send_set_pp_enable_cmd, module_id=%d, enable=%d\n",
1871 module_id, enable);
Helen Zengbb49c702011-09-06 14:09:13 -07001872
1873 v->cvs_state = CMD_STATUS_FAIL;
Helen Zeng4e531942011-12-17 21:14:40 -08001874 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_pp_cmd);
Helen Zengbb49c702011-09-06 14:09:13 -07001875 if (ret < 0) {
1876 pr_err("Fail: sending cvs set slowtalk enable,\n");
1877 goto fail;
1878 }
1879 ret = wait_event_timeout(v->cvs_wait,
1880 (v->cvs_state == CMD_STATUS_SUCCESS),
1881 msecs_to_jiffies(TIMEOUT_MS));
1882 if (!ret) {
1883 pr_err("%s: wait_event timeout\n", __func__);
1884 goto fail;
1885 }
1886 return 0;
1887fail:
1888 return -EINVAL;
1889}
1890
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001891static int voice_setup_vocproc(struct voice_data *v)
1892{
1893 struct cvp_create_full_ctl_session_cmd cvp_session_cmd;
1894 int ret = 0;
1895 void *apr_cvp;
1896 if (v == NULL) {
1897 pr_err("%s: v is NULL\n", __func__);
1898 return -EINVAL;
1899 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07001900 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001901
1902 if (!apr_cvp) {
1903 pr_err("%s: apr_cvp is NULL.\n", __func__);
1904 return -EINVAL;
1905 }
1906
1907 /* create cvp session and wait for response */
1908 cvp_session_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1909 APR_HDR_LEN(APR_HDR_SIZE),
1910 APR_PKT_VER);
1911 cvp_session_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1912 sizeof(cvp_session_cmd) - APR_HDR_SIZE);
1913 pr_debug(" send create cvp session, pkt size = %d\n",
1914 cvp_session_cmd.hdr.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -07001915 cvp_session_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001916 cvp_session_cmd.hdr.dest_port = 0;
1917 cvp_session_cmd.hdr.token = 0;
1918 cvp_session_cmd.hdr.opcode =
1919 VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION;
1920
1921 /* Use default topology if invalid value in ACDB */
1922 cvp_session_cmd.cvp_session.tx_topology_id =
1923 get_voice_tx_topology();
1924 if (cvp_session_cmd.cvp_session.tx_topology_id == 0)
1925 cvp_session_cmd.cvp_session.tx_topology_id =
1926 VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
1927
1928 cvp_session_cmd.cvp_session.rx_topology_id =
1929 get_voice_rx_topology();
1930 if (cvp_session_cmd.cvp_session.rx_topology_id == 0)
1931 cvp_session_cmd.cvp_session.rx_topology_id =
1932 VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
1933
1934 cvp_session_cmd.cvp_session.direction = 2; /*tx and rx*/
1935 cvp_session_cmd.cvp_session.network_id = VSS_NETWORK_ID_DEFAULT;
1936 cvp_session_cmd.cvp_session.tx_port_id = v->dev_tx.port_id;
1937 cvp_session_cmd.cvp_session.rx_port_id = v->dev_rx.port_id;
1938
1939 pr_debug("topology=%d net_id=%d, dir=%d tx_port_id=%d, rx_port_id=%d\n",
1940 cvp_session_cmd.cvp_session.tx_topology_id,
1941 cvp_session_cmd.cvp_session.network_id,
1942 cvp_session_cmd.cvp_session.direction,
1943 cvp_session_cmd.cvp_session.tx_port_id,
1944 cvp_session_cmd.cvp_session.rx_port_id);
1945
1946 v->cvp_state = CMD_STATUS_FAIL;
1947 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_session_cmd);
1948 if (ret < 0) {
1949 pr_err("Fail in sending VOCPROC_FULL_CONTROL_SESSION\n");
1950 goto fail;
1951 }
1952 ret = wait_event_timeout(v->cvp_wait,
1953 (v->cvp_state == CMD_STATUS_SUCCESS),
1954 msecs_to_jiffies(TIMEOUT_MS));
1955 if (!ret) {
1956 pr_err("%s: wait_event timeout\n", __func__);
1957 goto fail;
1958 }
1959
Helen Zeng29eb7442011-06-20 11:06:29 -07001960 /* send cvs cal */
1961 ret = voice_send_cvs_map_memory_cmd(v);
1962 if (!ret)
1963 voice_send_cvs_register_cal_cmd(v);
1964
1965 /* send cvp and vol cal */
1966 ret = voice_send_cvp_map_memory_cmd(v);
1967 if (!ret) {
1968 voice_send_cvp_register_cal_cmd(v);
1969 voice_send_cvp_register_vol_cal_table_cmd(v);
1970 }
1971
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001972 /* enable vocproc */
1973 ret = voice_send_enable_vocproc_cmd(v);
1974 if (ret < 0)
1975 goto fail;
1976
1977 /* attach vocproc */
1978 ret = voice_send_attach_vocproc_cmd(v);
1979 if (ret < 0)
1980 goto fail;
1981
1982 /* send tty mode if tty device is used */
1983 voice_send_tty_mode_cmd(v);
1984
Helen Zeng44d4d272011-08-10 14:49:20 -07001985 /* enable widevoice if wv_enable is set */
1986 if (v->wv_enable)
1987 voice_send_set_widevoice_enable_cmd(v);
1988
Helen Zengbb49c702011-09-06 14:09:13 -07001989 /* enable slowtalk if st_enable is set */
1990 if (v->st_enable)
Helen Zeng4e531942011-12-17 21:14:40 -08001991 voice_send_set_pp_enable_cmd(v, MODULE_ID_VOICE_MODULE_ST,
1992 v->st_enable);
1993 if (v->fens_enable)
1994 voice_send_set_pp_enable_cmd(v, MODULE_ID_VOICE_MODULE_FENS,
1995 v->fens_enable);
Helen Zengbb49c702011-09-06 14:09:13 -07001996
Neema Shetty2c07eb52011-08-21 20:33:52 -07001997 if (is_voip_session(v->session_id))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001998 voice_send_netid_timing_cmd(v);
1999
Helen Zenge3d716a2011-10-14 16:32:16 -07002000 /* Start in-call music delivery if this feature is enabled */
Helen Zeng0705a5f2011-10-14 15:29:52 -07002001 if (v->music_info.play_enable)
2002 voice_cvs_start_playback(v);
2003
Helen Zenge3d716a2011-10-14 16:32:16 -07002004 /* Start in-call recording if this feature is enabled */
2005 if (v->rec_info.rec_enable)
2006 voice_cvs_start_record(v, v->rec_info.rec_mode);
2007
Ben Romberger13b74ab2011-07-18 17:36:32 -07002008 rtac_add_voice(voice_get_cvs_handle(v),
2009 voice_get_cvp_handle(v),
Ben Rombergerc5d6a372011-09-22 18:01:49 -07002010 v->dev_rx.port_id, v->dev_tx.port_id,
2011 v->session_id);
Ben Romberger13b74ab2011-07-18 17:36:32 -07002012
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002013 return 0;
2014
2015fail:
2016 return -EINVAL;
2017}
2018
2019static int voice_send_enable_vocproc_cmd(struct voice_data *v)
2020{
2021 int ret = 0;
2022 struct apr_hdr cvp_enable_cmd;
2023 void *apr_cvp;
2024 u16 cvp_handle;
2025
2026 if (v == NULL) {
2027 pr_err("%s: v is NULL\n", __func__);
2028 return -EINVAL;
2029 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07002030 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002031
2032 if (!apr_cvp) {
2033 pr_err("%s: apr_cvp is NULL.\n", __func__);
2034 return -EINVAL;
2035 }
2036 cvp_handle = voice_get_cvp_handle(v);
2037
2038 /* enable vocproc and wait for respose */
2039 cvp_enable_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2040 APR_HDR_LEN(APR_HDR_SIZE),
2041 APR_PKT_VER);
2042 cvp_enable_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2043 sizeof(cvp_enable_cmd) - APR_HDR_SIZE);
2044 pr_debug("cvp_enable_cmd pkt size = %d, cvp_handle=%d\n",
2045 cvp_enable_cmd.pkt_size, cvp_handle);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002046 cvp_enable_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002047 cvp_enable_cmd.dest_port = cvp_handle;
2048 cvp_enable_cmd.token = 0;
2049 cvp_enable_cmd.opcode = VSS_IVOCPROC_CMD_ENABLE;
2050
2051 v->cvp_state = CMD_STATUS_FAIL;
2052 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_enable_cmd);
2053 if (ret < 0) {
2054 pr_err("Fail in sending VSS_IVOCPROC_CMD_ENABLE\n");
2055 goto fail;
2056 }
2057 ret = wait_event_timeout(v->cvp_wait,
2058 (v->cvp_state == CMD_STATUS_SUCCESS),
2059 msecs_to_jiffies(TIMEOUT_MS));
2060 if (!ret) {
2061 pr_err("%s: wait_event timeout\n", __func__);
2062 goto fail;
2063 }
2064
2065 return 0;
2066fail:
2067 return -EINVAL;
2068}
2069
2070static int voice_send_netid_timing_cmd(struct voice_data *v)
2071{
2072 int ret = 0;
2073 void *apr_mvm;
2074 u16 mvm_handle;
2075 struct mvm_set_network_cmd mvm_set_network;
2076 struct mvm_set_voice_timing_cmd mvm_set_voice_timing;
2077
2078 if (v == NULL) {
2079 pr_err("%s: v is NULL\n", __func__);
2080 return -EINVAL;
2081 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07002082 apr_mvm = common.apr_q6_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002083
2084 if (!apr_mvm) {
2085 pr_err("%s: apr_mvm is NULL.\n", __func__);
2086 return -EINVAL;
2087 }
2088 mvm_handle = voice_get_mvm_handle(v);
2089
2090 ret = voice_config_cvs_vocoder(v);
2091 if (ret < 0) {
2092 pr_err("%s: Error %d configuring CVS voc",
2093 __func__, ret);
2094 goto fail;
2095 }
2096 /* Set network ID. */
2097 pr_debug("Setting network ID\n");
2098
2099 mvm_set_network.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2100 APR_HDR_LEN(APR_HDR_SIZE),
2101 APR_PKT_VER);
2102 mvm_set_network.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2103 sizeof(mvm_set_network) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002104 mvm_set_network.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002105 mvm_set_network.hdr.dest_port = mvm_handle;
2106 mvm_set_network.hdr.token = 0;
2107 mvm_set_network.hdr.opcode = VSS_ICOMMON_CMD_SET_NETWORK;
Neema Shetty2c07eb52011-08-21 20:33:52 -07002108 mvm_set_network.network.network_id = common.mvs_info.network_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002109
2110 v->mvm_state = CMD_STATUS_FAIL;
2111 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_network);
2112 if (ret < 0) {
2113 pr_err("%s: Error %d sending SET_NETWORK\n", __func__, ret);
2114 goto fail;
2115 }
2116
2117 ret = wait_event_timeout(v->mvm_wait,
2118 (v->mvm_state == CMD_STATUS_SUCCESS),
2119 msecs_to_jiffies(TIMEOUT_MS));
2120 if (!ret) {
2121 pr_err("%s: wait_event timeout\n", __func__);
2122 goto fail;
2123 }
2124
2125 /* Set voice timing. */
2126 pr_debug("Setting voice timing\n");
2127
2128 mvm_set_voice_timing.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2129 APR_HDR_LEN(APR_HDR_SIZE),
2130 APR_PKT_VER);
2131 mvm_set_voice_timing.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2132 sizeof(mvm_set_voice_timing) -
2133 APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002134 mvm_set_voice_timing.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002135 mvm_set_voice_timing.hdr.dest_port = mvm_handle;
2136 mvm_set_voice_timing.hdr.token = 0;
2137 mvm_set_voice_timing.hdr.opcode = VSS_ICOMMON_CMD_SET_VOICE_TIMING;
2138 mvm_set_voice_timing.timing.mode = 0;
2139 mvm_set_voice_timing.timing.enc_offset = 8000;
Swaminathan Sathappan2fea0da2011-12-21 12:20:53 -08002140 if (machine_is_apq8064_sim()) {
2141 pr_debug("%s: Machine is apq8064 sim\n", __func__);
2142 mvm_set_voice_timing.timing.dec_req_offset = 0;
2143 mvm_set_voice_timing.timing.dec_offset = 18000;
2144 } else {
2145 mvm_set_voice_timing.timing.dec_req_offset = 3300;
2146 mvm_set_voice_timing.timing.dec_offset = 8300;
2147 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002148
2149 v->mvm_state = CMD_STATUS_FAIL;
2150
2151 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_voice_timing);
2152 if (ret < 0) {
2153 pr_err("%s: Error %d sending SET_TIMING\n", __func__, ret);
2154 goto fail;
2155 }
2156
2157 ret = wait_event_timeout(v->mvm_wait,
2158 (v->mvm_state == CMD_STATUS_SUCCESS),
2159 msecs_to_jiffies(TIMEOUT_MS));
2160 if (!ret) {
2161 pr_err("%s: wait_event timeout\n", __func__);
2162 goto fail;
2163 }
2164
2165 return 0;
2166fail:
2167 return -EINVAL;
2168}
2169
2170static int voice_send_attach_vocproc_cmd(struct voice_data *v)
2171{
2172 int ret = 0;
2173 struct mvm_attach_vocproc_cmd mvm_a_vocproc_cmd;
2174 void *apr_mvm;
2175 u16 mvm_handle, cvp_handle;
2176
2177 if (v == NULL) {
2178 pr_err("%s: v is NULL\n", __func__);
2179 return -EINVAL;
2180 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07002181 apr_mvm = common.apr_q6_mvm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002182
2183 if (!apr_mvm) {
2184 pr_err("%s: apr_mvm is NULL.\n", __func__);
2185 return -EINVAL;
2186 }
2187 mvm_handle = voice_get_mvm_handle(v);
2188 cvp_handle = voice_get_cvp_handle(v);
2189
2190 /* attach vocproc and wait for response */
2191 mvm_a_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2192 APR_HDR_LEN(APR_HDR_SIZE),
2193 APR_PKT_VER);
2194 mvm_a_vocproc_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2195 sizeof(mvm_a_vocproc_cmd) - APR_HDR_SIZE);
2196 pr_debug("send mvm_a_vocproc_cmd pkt size = %d\n",
2197 mvm_a_vocproc_cmd.hdr.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002198 mvm_a_vocproc_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002199 mvm_a_vocproc_cmd.hdr.dest_port = mvm_handle;
2200 mvm_a_vocproc_cmd.hdr.token = 0;
Helen Zeng69b00962011-07-08 11:38:36 -07002201 mvm_a_vocproc_cmd.hdr.opcode = VSS_IMVM_CMD_ATTACH_VOCPROC;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002202 mvm_a_vocproc_cmd.mvm_attach_cvp_handle.handle = cvp_handle;
2203
2204 v->mvm_state = CMD_STATUS_FAIL;
2205 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_a_vocproc_cmd);
2206 if (ret < 0) {
Helen Zeng69b00962011-07-08 11:38:36 -07002207 pr_err("Fail in sending VSS_IMVM_CMD_ATTACH_VOCPROC\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002208 goto fail;
2209 }
2210 ret = wait_event_timeout(v->mvm_wait,
2211 (v->mvm_state == CMD_STATUS_SUCCESS),
2212 msecs_to_jiffies(TIMEOUT_MS));
2213 if (!ret) {
2214 pr_err("%s: wait_event timeout\n", __func__);
2215 goto fail;
2216 }
2217
2218 return 0;
2219fail:
2220 return -EINVAL;
2221}
2222
2223static int voice_destroy_vocproc(struct voice_data *v)
2224{
2225 struct mvm_detach_vocproc_cmd mvm_d_vocproc_cmd;
2226 struct apr_hdr cvp_destroy_session_cmd;
2227 int ret = 0;
2228 void *apr_mvm, *apr_cvp;
2229 u16 mvm_handle, cvp_handle;
2230
2231 if (v == NULL) {
2232 pr_err("%s: v is NULL\n", __func__);
2233 return -EINVAL;
2234 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07002235 apr_mvm = common.apr_q6_mvm;
2236 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002237
2238 if (!apr_mvm || !apr_cvp) {
2239 pr_err("%s: apr_mvm or apr_cvp is NULL.\n", __func__);
2240 return -EINVAL;
2241 }
2242 mvm_handle = voice_get_mvm_handle(v);
2243 cvp_handle = voice_get_cvp_handle(v);
2244
Helen Zenge3d716a2011-10-14 16:32:16 -07002245 /* stop playback or recording */
Helen Zeng0705a5f2011-10-14 15:29:52 -07002246 v->music_info.force = 1;
2247 voice_cvs_stop_playback(v);
Helen Zenge3d716a2011-10-14 16:32:16 -07002248 voice_cvs_stop_record(v);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002249 /* send stop voice cmd */
2250 voice_send_stop_voice_cmd(v);
2251
2252 /* detach VOCPROC and wait for response from mvm */
2253 mvm_d_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2254 APR_HDR_LEN(APR_HDR_SIZE),
2255 APR_PKT_VER);
2256 mvm_d_vocproc_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2257 sizeof(mvm_d_vocproc_cmd) - APR_HDR_SIZE);
2258 pr_debug("mvm_d_vocproc_cmd pkt size = %d\n",
2259 mvm_d_vocproc_cmd.hdr.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002260 mvm_d_vocproc_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002261 mvm_d_vocproc_cmd.hdr.dest_port = mvm_handle;
2262 mvm_d_vocproc_cmd.hdr.token = 0;
Helen Zeng69b00962011-07-08 11:38:36 -07002263 mvm_d_vocproc_cmd.hdr.opcode = VSS_IMVM_CMD_DETACH_VOCPROC;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002264 mvm_d_vocproc_cmd.mvm_detach_cvp_handle.handle = cvp_handle;
2265
2266 v->mvm_state = CMD_STATUS_FAIL;
2267 ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_d_vocproc_cmd);
2268 if (ret < 0) {
Helen Zeng69b00962011-07-08 11:38:36 -07002269 pr_err("Fail in sending VSS_IMVM_CMD_DETACH_VOCPROC\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002270 goto fail;
2271 }
2272 ret = wait_event_timeout(v->mvm_wait,
2273 (v->mvm_state == CMD_STATUS_SUCCESS),
2274 msecs_to_jiffies(TIMEOUT_MS));
2275 if (!ret) {
2276 pr_err("%s: wait_event timeout\n", __func__);
2277 goto fail;
2278 }
2279
Helen Zeng29eb7442011-06-20 11:06:29 -07002280 /* deregister cvp and vol cal */
2281 voice_send_cvp_deregister_vol_cal_table_cmd(v);
2282 voice_send_cvp_deregister_cal_cmd(v);
2283 voice_send_cvp_unmap_memory_cmd(v);
2284
2285 /* deregister cvs cal */
2286 voice_send_cvs_deregister_cal_cmd(v);
2287 voice_send_cvs_unmap_memory_cmd(v);
2288
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002289 /* destrop cvp session */
2290 cvp_destroy_session_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2291 APR_HDR_LEN(APR_HDR_SIZE),
2292 APR_PKT_VER);
2293 cvp_destroy_session_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2294 sizeof(cvp_destroy_session_cmd) - APR_HDR_SIZE);
2295 pr_debug("cvp_destroy_session_cmd pkt size = %d\n",
2296 cvp_destroy_session_cmd.pkt_size);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002297 cvp_destroy_session_cmd.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002298 cvp_destroy_session_cmd.dest_port = cvp_handle;
2299 cvp_destroy_session_cmd.token = 0;
2300 cvp_destroy_session_cmd.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
2301
2302 v->cvp_state = CMD_STATUS_FAIL;
2303 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_destroy_session_cmd);
2304 if (ret < 0) {
2305 pr_err("Fail in sending APRV2_IBASIC_CMD_DESTROY_SESSION\n");
2306 goto fail;
2307 }
2308 ret = wait_event_timeout(v->cvp_wait,
2309 (v->cvp_state == CMD_STATUS_SUCCESS),
2310 msecs_to_jiffies(TIMEOUT_MS));
2311 if (!ret) {
2312 pr_err("%s: wait_event timeout\n", __func__);
2313 goto fail;
2314 }
2315
Ben Romberger13b74ab2011-07-18 17:36:32 -07002316 rtac_remove_voice(voice_get_cvs_handle(v));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002317 cvp_handle = 0;
2318 voice_set_cvp_handle(v, cvp_handle);
2319
2320 return 0;
2321
2322fail:
2323 return -EINVAL;
2324}
2325
2326static int voice_send_mute_cmd(struct voice_data *v)
2327{
2328 struct cvs_set_mute_cmd cvs_mute_cmd;
2329 int ret = 0;
2330 void *apr_cvs;
2331 u16 cvs_handle;
2332
2333 if (v == NULL) {
2334 pr_err("%s: v is NULL\n", __func__);
2335 return -EINVAL;
2336 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07002337 apr_cvs = common.apr_q6_cvs;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002338
2339 if (!apr_cvs) {
2340 pr_err("%s: apr_cvs is NULL.\n", __func__);
2341 return -EINVAL;
2342 }
2343 cvs_handle = voice_get_cvs_handle(v);
2344
2345 /* send mute/unmute to cvs */
2346 cvs_mute_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2347 APR_HDR_LEN(APR_HDR_SIZE),
2348 APR_PKT_VER);
2349 cvs_mute_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2350 sizeof(cvs_mute_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002351 cvs_mute_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002352 cvs_mute_cmd.hdr.dest_port = cvs_handle;
2353 cvs_mute_cmd.hdr.token = 0;
2354 cvs_mute_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_MUTE;
2355 cvs_mute_cmd.cvs_set_mute.direction = 0; /*tx*/
2356 cvs_mute_cmd.cvs_set_mute.mute_flag = v->dev_tx.mute;
2357
2358 pr_info(" mute value =%d\n", cvs_mute_cmd.cvs_set_mute.mute_flag);
2359 v->cvs_state = CMD_STATUS_FAIL;
2360 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_mute_cmd);
2361 if (ret < 0) {
2362 pr_err("Fail: send STREAM SET MUTE\n");
2363 goto fail;
2364 }
2365 ret = wait_event_timeout(v->cvs_wait,
2366 (v->cvs_state == CMD_STATUS_SUCCESS),
2367 msecs_to_jiffies(TIMEOUT_MS));
2368 if (!ret)
2369 pr_err("%s: wait_event timeout\n", __func__);
2370
2371 return 0;
2372fail:
2373 return -EINVAL;
2374}
2375
Helen Zeng68656932011-11-02 18:08:23 -07002376static int voice_send_rx_device_mute_cmd(struct voice_data *v)
2377{
2378 struct cvp_set_mute_cmd cvp_mute_cmd;
2379 int ret = 0;
2380 void *apr_cvp;
2381 u16 cvp_handle;
2382 if (v == NULL) {
2383 pr_err("%s: v is NULL\n", __func__);
2384 return -EINVAL;
2385 }
2386 apr_cvp = common.apr_q6_cvp;
2387
2388 if (!apr_cvp) {
2389 pr_err("%s: apr_cvp is NULL.\n", __func__);
2390 return -EINVAL;
2391 }
2392 cvp_handle = voice_get_cvp_handle(v);
2393
2394 cvp_mute_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2395 APR_HDR_LEN(APR_HDR_SIZE),
2396 APR_PKT_VER);
2397 cvp_mute_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2398 sizeof(cvp_mute_cmd) - APR_HDR_SIZE);
2399 cvp_mute_cmd.hdr.src_port = v->session_id;
2400 cvp_mute_cmd.hdr.dest_port = cvp_handle;
2401 cvp_mute_cmd.hdr.token = 0;
2402 cvp_mute_cmd.hdr.opcode = VSS_IVOCPROC_CMD_SET_MUTE;
2403 cvp_mute_cmd.cvp_set_mute.direction = 1;
2404 cvp_mute_cmd.cvp_set_mute.mute_flag = v->dev_rx.mute;
2405 v->cvp_state = CMD_STATUS_FAIL;
2406 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_mute_cmd);
2407 if (ret < 0) {
2408 pr_err("Fail in sending RX device mute cmd\n");
2409 return -EINVAL;
2410 }
2411 ret = wait_event_timeout(v->cvp_wait,
2412 (v->cvp_state == CMD_STATUS_SUCCESS),
2413 msecs_to_jiffies(TIMEOUT_MS));
2414 if (!ret) {
2415 pr_err("%s: wait_event timeout\n", __func__);
2416 return -EINVAL;
2417 }
2418 return 0;
2419}
2420
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002421static int voice_send_vol_index_cmd(struct voice_data *v)
2422{
2423 struct cvp_set_rx_volume_index_cmd cvp_vol_cmd;
2424 int ret = 0;
2425 void *apr_cvp;
2426 u16 cvp_handle;
2427 if (v == NULL) {
2428 pr_err("%s: v is NULL\n", __func__);
2429 return -EINVAL;
2430 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07002431 apr_cvp = common.apr_q6_cvp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002432
2433 if (!apr_cvp) {
2434 pr_err("%s: apr_cvp is NULL.\n", __func__);
2435 return -EINVAL;
2436 }
2437 cvp_handle = voice_get_cvp_handle(v);
2438
2439 /* send volume index to cvp */
2440 cvp_vol_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2441 APR_HDR_LEN(APR_HDR_SIZE),
2442 APR_PKT_VER);
2443 cvp_vol_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2444 sizeof(cvp_vol_cmd) - APR_HDR_SIZE);
Neema Shetty2c07eb52011-08-21 20:33:52 -07002445 cvp_vol_cmd.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002446 cvp_vol_cmd.hdr.dest_port = cvp_handle;
2447 cvp_vol_cmd.hdr.token = 0;
2448 cvp_vol_cmd.hdr.opcode = VSS_IVOCPROC_CMD_SET_RX_VOLUME_INDEX;
2449 cvp_vol_cmd.cvp_set_vol_idx.vol_index = v->dev_rx.volume;
2450 v->cvp_state = CMD_STATUS_FAIL;
2451 ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_vol_cmd);
2452 if (ret < 0) {
2453 pr_err("Fail in sending RX VOL INDEX\n");
2454 return -EINVAL;
2455 }
2456 ret = wait_event_timeout(v->cvp_wait,
2457 (v->cvp_state == CMD_STATUS_SUCCESS),
2458 msecs_to_jiffies(TIMEOUT_MS));
2459 if (!ret) {
2460 pr_err("%s: wait_event timeout\n", __func__);
2461 return -EINVAL;
2462 }
2463 return 0;
2464}
2465
Helen Zenge3d716a2011-10-14 16:32:16 -07002466static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode)
2467{
2468 int ret = 0;
2469 void *apr_cvs;
2470 u16 cvs_handle;
2471
2472 struct cvs_start_record_cmd cvs_start_record;
2473
2474 if (v == NULL) {
2475 pr_err("%s: v is NULL\n", __func__);
2476 return -EINVAL;
2477 }
2478 apr_cvs = common.apr_q6_cvs;
2479
2480 if (!apr_cvs) {
2481 pr_err("%s: apr_cvs is NULL.\n", __func__);
2482 return -EINVAL;
2483 }
2484
2485 cvs_handle = voice_get_cvs_handle(v);
2486
2487 if (!v->rec_info.recording) {
2488 cvs_start_record.hdr.hdr_field = APR_HDR_FIELD(
2489 APR_MSG_TYPE_SEQ_CMD,
2490 APR_HDR_LEN(APR_HDR_SIZE),
2491 APR_PKT_VER);
2492 cvs_start_record.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2493 sizeof(cvs_start_record) - APR_HDR_SIZE);
2494 cvs_start_record.hdr.src_port = v->session_id;
2495 cvs_start_record.hdr.dest_port = cvs_handle;
2496 cvs_start_record.hdr.token = 0;
2497 cvs_start_record.hdr.opcode = VSS_ISTREAM_CMD_START_RECORD;
2498
2499 if (rec_mode == VOC_REC_UPLINK) {
2500 cvs_start_record.rec_mode.rx_tap_point =
2501 VSS_TAP_POINT_NONE;
2502 cvs_start_record.rec_mode.tx_tap_point =
2503 VSS_TAP_POINT_STREAM_END;
2504 } else if (rec_mode == VOC_REC_DOWNLINK) {
2505 cvs_start_record.rec_mode.rx_tap_point =
2506 VSS_TAP_POINT_STREAM_END;
2507 cvs_start_record.rec_mode.tx_tap_point =
2508 VSS_TAP_POINT_NONE;
2509 } else if (rec_mode == VOC_REC_BOTH) {
2510 cvs_start_record.rec_mode.rx_tap_point =
2511 VSS_TAP_POINT_STREAM_END;
2512 cvs_start_record.rec_mode.tx_tap_point =
2513 VSS_TAP_POINT_STREAM_END;
2514 } else {
2515 pr_err("%s: Invalid in-call rec_mode %d\n", __func__,
2516 rec_mode);
2517
2518 ret = -EINVAL;
2519 goto fail;
2520 }
2521
2522 v->cvs_state = CMD_STATUS_FAIL;
2523
2524 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_start_record);
2525 if (ret < 0) {
2526 pr_err("%s: Error %d sending START_RECORD\n", __func__,
2527 ret);
2528
2529 goto fail;
2530 }
2531
2532 ret = wait_event_timeout(v->cvs_wait,
2533 (v->cvs_state == CMD_STATUS_SUCCESS),
2534 msecs_to_jiffies(TIMEOUT_MS));
2535
2536 if (!ret) {
2537 pr_err("%s: wait_event timeout\n", __func__);
2538
2539 goto fail;
2540 }
2541 v->rec_info.recording = 1;
2542 } else {
2543 pr_debug("%s: Start record already sent\n", __func__);
2544 }
2545
2546 return 0;
2547
2548fail:
2549 return ret;
2550}
2551
2552static int voice_cvs_stop_record(struct voice_data *v)
2553{
2554 int ret = 0;
2555 void *apr_cvs;
2556 u16 cvs_handle;
2557 struct apr_hdr cvs_stop_record;
2558
2559 if (v == NULL) {
2560 pr_err("%s: v is NULL\n", __func__);
2561 return -EINVAL;
2562 }
2563 apr_cvs = common.apr_q6_cvs;
2564
2565 if (!apr_cvs) {
2566 pr_err("%s: apr_cvs is NULL.\n", __func__);
2567 return -EINVAL;
2568 }
2569
2570 cvs_handle = voice_get_cvs_handle(v);
2571
2572 if (v->rec_info.recording) {
2573 cvs_stop_record.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2574 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2575 cvs_stop_record.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2576 sizeof(cvs_stop_record) - APR_HDR_SIZE);
2577 cvs_stop_record.src_port = v->session_id;
2578 cvs_stop_record.dest_port = cvs_handle;
2579 cvs_stop_record.token = 0;
2580 cvs_stop_record.opcode = VSS_ISTREAM_CMD_STOP_RECORD;
2581
2582 v->cvs_state = CMD_STATUS_FAIL;
2583
2584 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_stop_record);
2585 if (ret < 0) {
2586 pr_err("%s: Error %d sending STOP_RECORD\n",
2587 __func__, ret);
2588
2589 goto fail;
2590 }
2591
2592 ret = wait_event_timeout(v->cvs_wait,
2593 (v->cvs_state == CMD_STATUS_SUCCESS),
2594 msecs_to_jiffies(TIMEOUT_MS));
2595 if (!ret) {
2596 pr_err("%s: wait_event timeout\n", __func__);
2597
2598 goto fail;
2599 }
2600 v->rec_info.recording = 0;
2601 } else {
2602 pr_debug("%s: Stop record already sent\n", __func__);
2603 }
2604
2605 return 0;
2606
2607fail:
2608
2609 return ret;
2610}
2611
2612int voc_start_record(uint32_t port_id, uint32_t set)
2613{
2614 int ret = 0;
2615 int rec_mode = 0;
2616 u16 cvs_handle;
2617 int i, rec_set = 0;
2618
2619 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
2620 struct voice_data *v = &common.voice[i];
2621 pr_debug("%s: i:%d port_id: %d, set: %d\n",
2622 __func__, i, port_id, set);
2623
2624 mutex_lock(&v->lock);
2625 rec_mode = v->rec_info.rec_mode;
2626 rec_set = set;
2627 if (set) {
2628 if ((v->rec_route_state.ul_flag != 0) &&
2629 (v->rec_route_state.dl_flag != 0)) {
2630 pr_debug("%s: i=%d, rec mode already set.\n",
2631 __func__, i);
2632 mutex_unlock(&v->lock);
2633 if (i < MAX_VOC_SESSIONS)
2634 continue;
2635 else
2636 return 0;
2637 }
2638
2639 if (port_id == VOICE_RECORD_TX) {
2640 if ((v->rec_route_state.ul_flag == 0)
2641 && (v->rec_route_state.dl_flag == 0)) {
2642 rec_mode = VOC_REC_UPLINK;
2643 v->rec_route_state.ul_flag = 1;
2644 } else if ((v->rec_route_state.ul_flag == 0)
2645 && (v->rec_route_state.dl_flag != 0)) {
2646 voice_cvs_stop_record(v);
2647 rec_mode = VOC_REC_BOTH;
2648 v->rec_route_state.ul_flag = 1;
2649 }
2650 } else if (port_id == VOICE_RECORD_RX) {
2651 if ((v->rec_route_state.ul_flag == 0)
2652 && (v->rec_route_state.dl_flag == 0)) {
2653 rec_mode = VOC_REC_DOWNLINK;
2654 v->rec_route_state.dl_flag = 1;
2655 } else if ((v->rec_route_state.ul_flag != 0)
2656 && (v->rec_route_state.dl_flag == 0)) {
2657 voice_cvs_stop_record(v);
2658 rec_mode = VOC_REC_BOTH;
2659 v->rec_route_state.dl_flag = 1;
2660 }
2661 }
2662 rec_set = 1;
2663 } else {
2664 if ((v->rec_route_state.ul_flag == 0) &&
2665 (v->rec_route_state.dl_flag == 0)) {
2666 pr_debug("%s: i=%d, rec already stops.\n",
2667 __func__, i);
2668 mutex_unlock(&v->lock);
2669 if (i < MAX_VOC_SESSIONS)
2670 continue;
2671 else
2672 return 0;
2673 }
2674
2675 if (port_id == VOICE_RECORD_TX) {
2676 if ((v->rec_route_state.ul_flag != 0)
2677 && (v->rec_route_state.dl_flag == 0)) {
2678 v->rec_route_state.ul_flag = 0;
2679 rec_set = 0;
2680 } else if ((v->rec_route_state.ul_flag != 0)
2681 && (v->rec_route_state.dl_flag != 0)) {
2682 voice_cvs_stop_record(v);
2683 v->rec_route_state.ul_flag = 0;
2684 rec_mode = VOC_REC_DOWNLINK;
2685 rec_set = 1;
2686 }
2687 } else if (port_id == VOICE_RECORD_RX) {
2688 if ((v->rec_route_state.ul_flag == 0)
2689 && (v->rec_route_state.dl_flag != 0)) {
2690 v->rec_route_state.dl_flag = 0;
2691 rec_set = 0;
2692 } else if ((v->rec_route_state.ul_flag != 0)
2693 && (v->rec_route_state.dl_flag != 0)) {
2694 voice_cvs_stop_record(v);
2695 v->rec_route_state.dl_flag = 0;
2696 rec_mode = VOC_REC_UPLINK;
2697 rec_set = 1;
2698 }
2699 }
2700 }
2701 pr_debug("%s: i=%d, mode =%d, set =%d\n", __func__,
2702 i, rec_mode, rec_set);
2703 cvs_handle = voice_get_cvs_handle(v);
2704
2705 if (cvs_handle != 0) {
2706 if (rec_set)
2707 ret = voice_cvs_start_record(v, rec_mode);
2708 else
2709 ret = voice_cvs_stop_record(v);
2710 }
2711
2712 /* Cache the value */
2713 v->rec_info.rec_enable = rec_set;
2714 v->rec_info.rec_mode = rec_mode;
2715
2716 mutex_unlock(&v->lock);
2717 }
2718
2719 return ret;
2720}
2721
Helen Zeng0705a5f2011-10-14 15:29:52 -07002722static int voice_cvs_start_playback(struct voice_data *v)
2723{
2724 int ret = 0;
2725 struct apr_hdr cvs_start_playback;
2726 void *apr_cvs;
2727 u16 cvs_handle;
2728
2729 if (v == NULL) {
2730 pr_err("%s: v is NULL\n", __func__);
2731 return -EINVAL;
2732 }
2733 apr_cvs = common.apr_q6_cvs;
2734
2735 if (!apr_cvs) {
2736 pr_err("%s: apr_cvs is NULL.\n", __func__);
2737 return -EINVAL;
2738 }
2739
2740 cvs_handle = voice_get_cvs_handle(v);
2741
2742 if (!v->music_info.playing && v->music_info.count) {
2743 cvs_start_playback.hdr_field = APR_HDR_FIELD(
2744 APR_MSG_TYPE_SEQ_CMD,
2745 APR_HDR_LEN(APR_HDR_SIZE),
2746 APR_PKT_VER);
2747 cvs_start_playback.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2748 sizeof(cvs_start_playback) - APR_HDR_SIZE);
2749 cvs_start_playback.src_port = v->session_id;
2750 cvs_start_playback.dest_port = cvs_handle;
2751 cvs_start_playback.token = 0;
2752 cvs_start_playback.opcode = VSS_ISTREAM_CMD_START_PLAYBACK;
2753
2754 v->cvs_state = CMD_STATUS_FAIL;
2755
2756 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_start_playback);
2757
2758 if (ret < 0) {
2759 pr_err("%s: Error %d sending START_PLAYBACK\n",
2760 __func__, ret);
2761
2762 goto fail;
2763 }
2764
2765 ret = wait_event_timeout(v->cvs_wait,
2766 (v->cvs_state == CMD_STATUS_SUCCESS),
2767 msecs_to_jiffies(TIMEOUT_MS));
2768 if (!ret) {
2769 pr_err("%s: wait_event timeout\n", __func__);
2770
2771 goto fail;
2772 }
2773
2774 v->music_info.playing = 1;
2775 } else {
2776 pr_debug("%s: Start playback already sent\n", __func__);
2777 }
2778
2779 return 0;
2780
2781fail:
2782 return ret;
2783}
2784
2785static int voice_cvs_stop_playback(struct voice_data *v)
2786{
2787 int ret = 0;
2788 struct apr_hdr cvs_stop_playback;
2789 void *apr_cvs;
2790 u16 cvs_handle;
2791
2792 if (v == NULL) {
2793 pr_err("%s: v is NULL\n", __func__);
2794 return -EINVAL;
2795 }
2796 apr_cvs = common.apr_q6_cvs;
2797
2798 if (!apr_cvs) {
2799 pr_err("%s: apr_cvs is NULL.\n", __func__);
2800 return -EINVAL;
2801 }
2802
2803 cvs_handle = voice_get_cvs_handle(v);
2804
2805 if (v->music_info.playing && ((!v->music_info.count) ||
2806 (v->music_info.force))) {
2807 cvs_stop_playback.hdr_field =
2808 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2809 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2810 cvs_stop_playback.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
2811 sizeof(cvs_stop_playback) - APR_HDR_SIZE);
2812 cvs_stop_playback.src_port = v->session_id;
2813 cvs_stop_playback.dest_port = cvs_handle;
2814 cvs_stop_playback.token = 0;
2815
2816 cvs_stop_playback.opcode = VSS_ISTREAM_CMD_STOP_PLAYBACK;
2817
2818 v->cvs_state = CMD_STATUS_FAIL;
2819
2820 ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_stop_playback);
2821 if (ret < 0) {
2822 pr_err("%s: Error %d sending STOP_PLAYBACK\n",
2823 __func__, ret);
2824
2825
2826 goto fail;
2827 }
2828
2829 ret = wait_event_timeout(v->cvs_wait,
2830 (v->cvs_state == CMD_STATUS_SUCCESS),
2831 msecs_to_jiffies(TIMEOUT_MS));
2832 if (!ret) {
2833 pr_err("%s: wait_event timeout\n", __func__);
2834
2835 goto fail;
2836 }
2837
2838 v->music_info.playing = 0;
2839 v->music_info.force = 0;
2840 } else {
2841 pr_debug("%s: Stop playback already sent\n", __func__);
2842 }
2843
2844 return 0;
2845
2846fail:
2847 return ret;
2848}
2849
2850int voc_start_playback(uint32_t set)
2851{
2852 int ret = 0;
2853 u16 cvs_handle;
2854 int i;
2855
2856
2857 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
2858 struct voice_data *v = &common.voice[i];
2859
2860 mutex_lock(&v->lock);
2861 v->music_info.play_enable = set;
2862 if (set)
2863 v->music_info.count++;
2864 else
2865 v->music_info.count--;
2866 pr_debug("%s: music_info count =%d\n", __func__,
2867 v->music_info.count);
2868
2869 cvs_handle = voice_get_cvs_handle(v);
2870 if (cvs_handle != 0) {
2871 if (set)
2872 ret = voice_cvs_start_playback(v);
2873 else
2874 ret = voice_cvs_stop_playback(v);
2875 }
2876
2877 mutex_unlock(&v->lock);
2878 }
2879
2880 return ret;
2881}
2882
Neema Shetty2c07eb52011-08-21 20:33:52 -07002883int voc_disable_cvp(uint16_t session_id)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002884{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002885 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002886 int ret = 0;
2887
Neema Shetty2c07eb52011-08-21 20:33:52 -07002888 if (v == NULL) {
2889 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2890
2891 return -EINVAL;
2892 }
2893
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002894 mutex_lock(&v->lock);
2895
2896 if (v->voc_state == VOC_RUN) {
Laxminath Kasam5b9cf0f2011-12-09 15:24:20 +05302897 if (v->dev_tx.port_id != RT_PROXY_PORT_001_TX &&
2898 v->dev_rx.port_id != RT_PROXY_PORT_001_RX)
2899 afe_sidetone(v->dev_tx.port_id, v->dev_rx.port_id,
2900 0, 0);
Ben Romberger13b74ab2011-07-18 17:36:32 -07002901
2902 rtac_remove_voice(voice_get_cvs_handle(v));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002903 /* send cmd to dsp to disable vocproc */
2904 ret = voice_send_disable_vocproc_cmd(v);
2905 if (ret < 0) {
2906 pr_err("%s: disable vocproc failed\n", __func__);
2907 goto fail;
2908 }
Helen Zeng29eb7442011-06-20 11:06:29 -07002909
2910 /* deregister cvp and vol cal */
2911 voice_send_cvp_deregister_vol_cal_table_cmd(v);
2912 voice_send_cvp_deregister_cal_cmd(v);
2913 voice_send_cvp_unmap_memory_cmd(v);
2914
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002915 v->voc_state = VOC_CHANGE;
2916 }
2917
2918fail: mutex_unlock(&v->lock);
2919
2920 return ret;
2921}
2922
Neema Shetty2c07eb52011-08-21 20:33:52 -07002923int voc_enable_cvp(uint16_t session_id)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002924{
Neema Shetty2c07eb52011-08-21 20:33:52 -07002925 struct voice_data *v = voice_get_session(session_id);
Helen Zengbd58e2c2011-07-01 16:24:31 -07002926 struct sidetone_cal sidetone_cal_data;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002927 int ret = 0;
2928
Neema Shetty2c07eb52011-08-21 20:33:52 -07002929 if (v == NULL) {
2930 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
2931
2932 return -EINVAL;
2933 }
2934
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002935 mutex_lock(&v->lock);
2936
2937 if (v->voc_state == VOC_CHANGE) {
2938 ret = voice_send_set_device_cmd(v);
2939 if (ret < 0) {
2940 pr_err("%s: set device failed\n", __func__);
2941 goto fail;
2942 }
Helen Zeng29eb7442011-06-20 11:06:29 -07002943 /* send cvp and vol cal */
2944 ret = voice_send_cvp_map_memory_cmd(v);
2945 if (!ret) {
2946 voice_send_cvp_register_cal_cmd(v);
2947 voice_send_cvp_register_vol_cal_table_cmd(v);
2948 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002949 ret = voice_send_enable_vocproc_cmd(v);
2950 if (ret < 0) {
Neema Shetty2c07eb52011-08-21 20:33:52 -07002951 pr_err("%s: enable vocproc failed\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002952 goto fail;
Helen Zengcc65b5b2011-07-06 19:14:48 -07002953
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002954 }
Helen Zengcc65b5b2011-07-06 19:14:48 -07002955 /* send tty mode if tty device is used */
2956 voice_send_tty_mode_cmd(v);
2957
Helen Zeng44d4d272011-08-10 14:49:20 -07002958 /* enable widevoice if wv_enable is set */
2959 if (v->wv_enable)
2960 voice_send_set_widevoice_enable_cmd(v);
2961
Helen Zengbb49c702011-09-06 14:09:13 -07002962 /* enable slowtalk */
2963 if (v->st_enable)
Helen Zeng4e531942011-12-17 21:14:40 -08002964 voice_send_set_pp_enable_cmd(v,
2965 MODULE_ID_VOICE_MODULE_ST,
2966 v->st_enable);
2967 /* enable FENS */
2968 if (v->fens_enable)
2969 voice_send_set_pp_enable_cmd(v,
2970 MODULE_ID_VOICE_MODULE_FENS,
2971 v->fens_enable);
Helen Zengbb49c702011-09-06 14:09:13 -07002972
Helen Zengbd58e2c2011-07-01 16:24:31 -07002973 get_sidetone_cal(&sidetone_cal_data);
Laxminath Kasam5b9cf0f2011-12-09 15:24:20 +05302974 if (v->dev_tx.port_id != RT_PROXY_PORT_001_TX &&
2975 v->dev_rx.port_id != RT_PROXY_PORT_001_RX) {
2976 ret = afe_sidetone(v->dev_tx.port_id,
2977 v->dev_rx.port_id,
2978 sidetone_cal_data.enable,
2979 sidetone_cal_data.gain);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002980
Laxminath Kasam5b9cf0f2011-12-09 15:24:20 +05302981 if (ret < 0)
2982 pr_err("%s: AFE command sidetone failed\n",
2983 __func__);
2984 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002985
Ben Romberger13b74ab2011-07-18 17:36:32 -07002986 rtac_add_voice(voice_get_cvs_handle(v),
2987 voice_get_cvp_handle(v),
Ben Rombergerc5d6a372011-09-22 18:01:49 -07002988 v->dev_rx.port_id, v->dev_tx.port_id,
2989 v->session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002990 v->voc_state = VOC_RUN;
2991 }
2992
2993fail:
2994 mutex_unlock(&v->lock);
2995
2996 return ret;
2997}
2998
Neema Shetty2c07eb52011-08-21 20:33:52 -07002999int voc_set_tx_mute(uint16_t session_id, uint32_t dir, uint32_t mute)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003000{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003001 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003002 int ret = 0;
3003
Neema Shetty2c07eb52011-08-21 20:33:52 -07003004 if (v == NULL) {
3005 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3006
3007 return -EINVAL;
3008 }
3009
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003010 mutex_lock(&v->lock);
3011
3012 v->dev_tx.mute = mute;
3013
3014 if (v->voc_state == VOC_RUN)
3015 ret = voice_send_mute_cmd(v);
3016
3017 mutex_unlock(&v->lock);
3018
3019 return ret;
3020}
3021
Helen Zeng68656932011-11-02 18:08:23 -07003022int voc_set_rx_device_mute(uint16_t session_id, uint32_t mute)
3023{
3024 struct voice_data *v = voice_get_session(session_id);
3025 int ret = 0;
3026
3027 if (v == NULL) {
3028 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3029
3030 return -EINVAL;
3031 }
3032
3033 mutex_lock(&v->lock);
3034
3035 v->dev_rx.mute = mute;
3036
3037 if (v->voc_state == VOC_RUN)
3038 ret = voice_send_rx_device_mute_cmd(v);
3039
3040 mutex_unlock(&v->lock);
3041
3042 return ret;
3043}
3044
3045int voc_get_rx_device_mute(uint16_t session_id)
3046{
3047 struct voice_data *v = voice_get_session(session_id);
3048 int ret = 0;
3049
3050 if (v == NULL) {
3051 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3052
3053 return -EINVAL;
3054 }
3055
3056 mutex_lock(&v->lock);
3057
3058 ret = v->dev_rx.mute;
3059
3060 mutex_unlock(&v->lock);
3061
3062 return ret;
3063}
3064
Neema Shetty2c07eb52011-08-21 20:33:52 -07003065int voc_set_tty_mode(uint16_t session_id, uint8_t tty_mode)
Helen Zengcc65b5b2011-07-06 19:14:48 -07003066{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003067 struct voice_data *v = voice_get_session(session_id);
Helen Zengcc65b5b2011-07-06 19:14:48 -07003068 int ret = 0;
3069
Neema Shetty2c07eb52011-08-21 20:33:52 -07003070 if (v == NULL) {
3071 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3072
3073 return -EINVAL;
3074 }
3075
Helen Zengcc65b5b2011-07-06 19:14:48 -07003076 mutex_lock(&v->lock);
3077
3078 v->tty_mode = tty_mode;
3079
3080 mutex_unlock(&v->lock);
3081
3082 return ret;
3083}
3084
Neema Shetty2c07eb52011-08-21 20:33:52 -07003085uint8_t voc_get_tty_mode(uint16_t session_id)
Helen Zengcc65b5b2011-07-06 19:14:48 -07003086{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003087 struct voice_data *v = voice_get_session(session_id);
Helen Zengcc65b5b2011-07-06 19:14:48 -07003088 int ret = 0;
3089
Neema Shetty2c07eb52011-08-21 20:33:52 -07003090 if (v == NULL) {
3091 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3092
3093 return -EINVAL;
3094 }
3095
Helen Zengcc65b5b2011-07-06 19:14:48 -07003096 mutex_lock(&v->lock);
3097
3098 ret = v->tty_mode;
3099
3100 mutex_unlock(&v->lock);
3101
3102 return ret;
3103}
3104
Neema Shetty2c07eb52011-08-21 20:33:52 -07003105int voc_set_widevoice_enable(uint16_t session_id, uint32_t wv_enable)
Helen Zeng44d4d272011-08-10 14:49:20 -07003106{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003107 struct voice_data *v = voice_get_session(session_id);
Helen Zengb73acce2011-09-15 18:23:01 -07003108 u16 mvm_handle;
Helen Zeng44d4d272011-08-10 14:49:20 -07003109 int ret = 0;
3110
Neema Shetty2c07eb52011-08-21 20:33:52 -07003111 if (v == NULL) {
3112 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3113
3114 return -EINVAL;
3115 }
3116
Helen Zeng44d4d272011-08-10 14:49:20 -07003117 mutex_lock(&v->lock);
3118
3119 v->wv_enable = wv_enable;
3120
Helen Zengb73acce2011-09-15 18:23:01 -07003121 mvm_handle = voice_get_mvm_handle(v);
3122
3123 if (mvm_handle != 0)
3124 voice_send_set_widevoice_enable_cmd(v);
3125
Helen Zeng44d4d272011-08-10 14:49:20 -07003126 mutex_unlock(&v->lock);
3127
3128 return ret;
3129}
3130
Neema Shetty2c07eb52011-08-21 20:33:52 -07003131uint32_t voc_get_widevoice_enable(uint16_t session_id)
Helen Zeng44d4d272011-08-10 14:49:20 -07003132{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003133 struct voice_data *v = voice_get_session(session_id);
Helen Zeng44d4d272011-08-10 14:49:20 -07003134 int ret = 0;
3135
Neema Shetty2c07eb52011-08-21 20:33:52 -07003136 if (v == NULL) {
3137 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3138
3139 return -EINVAL;
3140 }
3141
Helen Zeng44d4d272011-08-10 14:49:20 -07003142 mutex_lock(&v->lock);
3143
3144 ret = v->wv_enable;
3145
3146 mutex_unlock(&v->lock);
3147
3148 return ret;
3149}
3150
Helen Zeng4e531942011-12-17 21:14:40 -08003151int voc_set_pp_enable(uint16_t session_id, uint32_t module_id, uint32_t enable)
Helen Zengbb49c702011-09-06 14:09:13 -07003152{
3153 struct voice_data *v = voice_get_session(session_id);
3154 int ret = 0;
3155
3156 if (v == NULL) {
3157 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3158
3159 return -EINVAL;
3160 }
3161
3162 mutex_lock(&v->lock);
Helen Zeng4e531942011-12-17 21:14:40 -08003163 if (module_id == MODULE_ID_VOICE_MODULE_ST)
3164 v->st_enable = enable;
3165 else if (module_id == MODULE_ID_VOICE_MODULE_FENS)
3166 v->fens_enable = enable;
Helen Zengbb49c702011-09-06 14:09:13 -07003167
Helen Zeng4e531942011-12-17 21:14:40 -08003168 if (v->voc_state == VOC_RUN) {
3169 if (module_id == MODULE_ID_VOICE_MODULE_ST)
3170 ret = voice_send_set_pp_enable_cmd(v,
3171 MODULE_ID_VOICE_MODULE_ST,
3172 enable);
3173 else if (module_id == MODULE_ID_VOICE_MODULE_FENS)
3174 ret = voice_send_set_pp_enable_cmd(v,
3175 MODULE_ID_VOICE_MODULE_FENS,
3176 enable);
3177 }
Helen Zengbb49c702011-09-06 14:09:13 -07003178 mutex_unlock(&v->lock);
3179
3180 return ret;
3181}
3182
Helen Zeng4e531942011-12-17 21:14:40 -08003183int voc_get_pp_enable(uint16_t session_id, uint32_t module_id)
Helen Zengbb49c702011-09-06 14:09:13 -07003184{
3185 struct voice_data *v = voice_get_session(session_id);
3186 int ret = 0;
3187
3188 if (v == NULL) {
3189 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3190
3191 return -EINVAL;
3192 }
3193
3194 mutex_lock(&v->lock);
Helen Zeng4e531942011-12-17 21:14:40 -08003195 if (module_id == MODULE_ID_VOICE_MODULE_ST)
3196 ret = v->st_enable;
3197 else if (module_id == MODULE_ID_VOICE_MODULE_FENS)
3198 ret = v->fens_enable;
Helen Zengbb49c702011-09-06 14:09:13 -07003199
3200 mutex_unlock(&v->lock);
3201
3202 return ret;
3203}
3204
Neema Shetty2c07eb52011-08-21 20:33:52 -07003205int voc_set_rx_vol_index(uint16_t session_id, uint32_t dir, uint32_t vol_idx)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003206{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003207 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003208 int ret = 0;
3209
Neema Shetty2c07eb52011-08-21 20:33:52 -07003210 if (v == NULL) {
3211 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3212
3213 return -EINVAL;
3214 }
3215
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003216 mutex_lock(&v->lock);
3217
3218 v->dev_rx.volume = vol_idx;
3219
3220 if (v->voc_state == VOC_RUN)
3221 ret = voice_send_vol_index_cmd(v);
3222
3223 mutex_unlock(&v->lock);
3224
3225 return ret;
3226}
3227
Neema Shetty2c07eb52011-08-21 20:33:52 -07003228int voc_set_rxtx_port(uint16_t session_id, uint32_t port_id, uint32_t dev_type)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003229{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003230 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003231
Neema Shetty2c07eb52011-08-21 20:33:52 -07003232 if (v == NULL) {
3233 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3234
3235 return -EINVAL;
3236 }
3237
3238 pr_debug("%s: port_id=%d, type=%d\n", __func__, port_id, dev_type);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003239
3240 mutex_lock(&v->lock);
3241
3242 if (dev_type == DEV_RX)
3243 v->dev_rx.port_id = port_id;
3244 else
3245 v->dev_tx.port_id = port_id;
3246
3247 mutex_unlock(&v->lock);
3248
Neema Shetty2c07eb52011-08-21 20:33:52 -07003249 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003250}
3251
Neema Shetty2c07eb52011-08-21 20:33:52 -07003252int voc_set_route_flag(uint16_t session_id, uint8_t path_dir, uint8_t set)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003253{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003254 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003255
Neema Shetty2c07eb52011-08-21 20:33:52 -07003256 if (v == NULL) {
3257 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3258
3259 return -EINVAL;
3260 }
3261
3262 pr_debug("%s: path_dir=%d, set=%d\n", __func__, path_dir, set);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003263
3264 mutex_lock(&v->lock);
3265
3266 if (path_dir == RX_PATH)
3267 v->voc_route_state.rx_route_flag = set;
3268 else
3269 v->voc_route_state.tx_route_flag = set;
3270
3271 mutex_unlock(&v->lock);
3272
Neema Shetty2c07eb52011-08-21 20:33:52 -07003273 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003274}
3275
Neema Shetty2c07eb52011-08-21 20:33:52 -07003276uint8_t voc_get_route_flag(uint16_t session_id, uint8_t path_dir)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003277{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003278 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003279 int ret = 0;
3280
Neema Shetty2c07eb52011-08-21 20:33:52 -07003281 if (v == NULL) {
3282 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3283
3284 return 0;
3285 }
3286
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003287 mutex_lock(&v->lock);
3288
3289 if (path_dir == RX_PATH)
3290 ret = v->voc_route_state.rx_route_flag;
3291 else
3292 ret = v->voc_route_state.tx_route_flag;
3293
3294 mutex_unlock(&v->lock);
3295
3296 return ret;
3297}
3298
Neema Shetty2c07eb52011-08-21 20:33:52 -07003299int voc_end_voice_call(uint16_t session_id)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003300{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003301 struct voice_data *v = voice_get_session(session_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003302 int ret = 0;
3303
Neema Shetty2c07eb52011-08-21 20:33:52 -07003304 if (v == NULL) {
3305 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3306
3307 return -EINVAL;
3308 }
3309
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003310 mutex_lock(&v->lock);
3311
3312 if (v->voc_state == VOC_RUN) {
Laxminath Kasam5b9cf0f2011-12-09 15:24:20 +05303313 if (v->dev_tx.port_id != RT_PROXY_PORT_001_TX &&
3314 v->dev_rx.port_id != RT_PROXY_PORT_001_RX)
3315 afe_sidetone(v->dev_tx.port_id, v->dev_rx.port_id,
3316 0, 0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003317 ret = voice_destroy_vocproc(v);
3318 if (ret < 0)
3319 pr_err("%s: destroy voice failed\n", __func__);
3320 voice_destroy_mvm_cvs_session(v);
3321
3322 v->voc_state = VOC_RELEASE;
3323 }
3324 mutex_unlock(&v->lock);
3325 return ret;
3326}
3327
Neema Shetty2c07eb52011-08-21 20:33:52 -07003328int voc_start_voice_call(uint16_t session_id)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003329{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003330 struct voice_data *v = voice_get_session(session_id);
Helen Zengbd58e2c2011-07-01 16:24:31 -07003331 struct sidetone_cal sidetone_cal_data;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003332 int ret = 0;
3333
Neema Shetty2c07eb52011-08-21 20:33:52 -07003334 if (v == NULL) {
3335 pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
3336
3337 return -EINVAL;
3338 }
3339
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003340 mutex_lock(&v->lock);
3341
3342 if ((v->voc_state == VOC_INIT) ||
3343 (v->voc_state == VOC_RELEASE)) {
Neema Shetty2c07eb52011-08-21 20:33:52 -07003344 ret = voice_apr_register();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003345 if (ret < 0) {
3346 pr_err("%s: apr register failed\n", __func__);
3347 goto fail;
3348 }
3349 ret = voice_create_mvm_cvs_session(v);
3350 if (ret < 0) {
3351 pr_err("create mvm and cvs failed\n");
3352 goto fail;
3353 }
3354 ret = voice_setup_vocproc(v);
3355 if (ret < 0) {
3356 pr_err("setup voice failed\n");
3357 goto fail;
3358 }
3359 ret = voice_send_start_voice_cmd(v);
3360 if (ret < 0) {
3361 pr_err("start voice failed\n");
3362 goto fail;
3363 }
Helen Zengbd58e2c2011-07-01 16:24:31 -07003364 get_sidetone_cal(&sidetone_cal_data);
Laxminath Kasam5b9cf0f2011-12-09 15:24:20 +05303365 if (v->dev_tx.port_id != RT_PROXY_PORT_001_TX &&
3366 v->dev_rx.port_id != RT_PROXY_PORT_001_RX) {
3367 ret = afe_sidetone(v->dev_tx.port_id,
Helen Zengbd58e2c2011-07-01 16:24:31 -07003368 v->dev_rx.port_id,
3369 sidetone_cal_data.enable,
3370 sidetone_cal_data.gain);
Laxminath Kasam5b9cf0f2011-12-09 15:24:20 +05303371 if (ret < 0)
3372 pr_err("AFE command sidetone failed\n");
3373 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003374
3375 v->voc_state = VOC_RUN;
3376 }
3377
3378fail: mutex_unlock(&v->lock);
3379 return ret;
3380}
3381
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003382void voc_register_mvs_cb(ul_cb_fn ul_cb,
3383 dl_cb_fn dl_cb,
3384 void *private_data)
3385{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003386 common.mvs_info.ul_cb = ul_cb;
3387 common.mvs_info.dl_cb = dl_cb;
3388 common.mvs_info.private_data = private_data;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003389}
3390
3391void voc_config_vocoder(uint32_t media_type,
3392 uint32_t rate,
Helen Zengff97bec2012-02-20 14:30:50 -08003393 uint32_t network_type,
3394 uint32_t dtx_mode)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003395{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003396 common.mvs_info.media_type = media_type;
3397 common.mvs_info.rate = rate;
3398 common.mvs_info.network_type = network_type;
Helen Zengff97bec2012-02-20 14:30:50 -08003399 common.mvs_info.dtx_mode = dtx_mode;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003400}
3401
3402static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv)
3403{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003404 uint32_t *ptr = NULL;
3405 struct common_data *c = NULL;
3406 struct voice_data *v = NULL;
Neema Shetty07477582011-09-02 17:35:44 -07003407 int i = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003408
3409 if ((data == NULL) || (priv == NULL)) {
3410 pr_err("%s: data or priv is NULL\n", __func__);
3411 return -EINVAL;
3412 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07003413
3414 c = priv;
3415
3416 pr_debug("%s: session_id 0x%x\n", __func__, data->dest_port);
3417
3418 v = voice_get_session(data->dest_port);
3419 if (v == NULL) {
3420 pr_err("%s: v is NULL\n", __func__);
3421
3422 return -EINVAL;
3423 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003424
3425 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
3426 data->payload_size, data->opcode);
3427
Neema Shetty07477582011-09-02 17:35:44 -07003428 if (data->opcode == RESET_EVENTS) {
3429 pr_debug("%s: Reset event received in Voice service\n",
3430 __func__);
3431
3432 apr_reset(c->apr_q6_mvm);
3433 c->apr_q6_mvm = NULL;
3434
3435 /* Sub-system restart is applicable to all sessions. */
3436 for (i = 0; i < MAX_VOC_SESSIONS; i++)
3437 c->voice[i].mvm_handle = 0;
3438
3439 return 0;
3440 }
3441
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003442 if (data->opcode == APR_BASIC_RSP_RESULT) {
3443 if (data->payload_size) {
3444 ptr = data->payload;
3445
3446 pr_info("%x %x\n", ptr[0], ptr[1]);
3447 /* ping mvm service ACK */
3448 switch (ptr[0]) {
3449 case VSS_IMVM_CMD_CREATE_PASSIVE_CONTROL_SESSION:
3450 case VSS_IMVM_CMD_CREATE_FULL_CONTROL_SESSION:
3451 /* Passive session is used for CS call
3452 * Full session is used for VoIP call. */
3453 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
3454 if (!ptr[1]) {
3455 pr_debug("%s: MVM handle is %d\n",
3456 __func__, data->src_port);
3457 voice_set_mvm_handle(v, data->src_port);
3458 } else
3459 pr_err("got NACK for sending \
3460 MVM create session \n");
3461 v->mvm_state = CMD_STATUS_SUCCESS;
3462 wake_up(&v->mvm_wait);
3463 break;
3464 case VSS_IMVM_CMD_START_VOICE:
Helen Zeng69b00962011-07-08 11:38:36 -07003465 case VSS_IMVM_CMD_ATTACH_VOCPROC:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003466 case VSS_IMVM_CMD_STOP_VOICE:
Helen Zeng69b00962011-07-08 11:38:36 -07003467 case VSS_IMVM_CMD_DETACH_VOCPROC:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003468 case VSS_ISTREAM_CMD_SET_TTY_MODE:
3469 case APRV2_IBASIC_CMD_DESTROY_SESSION:
3470 case VSS_IMVM_CMD_ATTACH_STREAM:
3471 case VSS_IMVM_CMD_DETACH_STREAM:
3472 case VSS_ICOMMON_CMD_SET_NETWORK:
3473 case VSS_ICOMMON_CMD_SET_VOICE_TIMING:
Helen Zeng44d4d272011-08-10 14:49:20 -07003474 case VSS_IWIDEVOICE_CMD_SET_WIDEVOICE:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003475 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
3476 v->mvm_state = CMD_STATUS_SUCCESS;
3477 wake_up(&v->mvm_wait);
3478 break;
3479 default:
3480 pr_debug("%s: not match cmd = 0x%x\n",
3481 __func__, ptr[0]);
3482 break;
3483 }
3484 }
3485 }
3486
3487 return 0;
3488}
3489
3490static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv)
3491{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003492 uint32_t *ptr = NULL;
3493 struct common_data *c = NULL;
3494 struct voice_data *v = NULL;
Neema Shetty07477582011-09-02 17:35:44 -07003495 int i = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003496
3497 if ((data == NULL) || (priv == NULL)) {
3498 pr_err("%s: data or priv is NULL\n", __func__);
3499 return -EINVAL;
3500 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07003501
3502 c = priv;
3503
3504 pr_debug("%s: session_id 0x%x\n", __func__, data->dest_port);
3505
3506 v = voice_get_session(data->dest_port);
3507 if (v == NULL) {
3508 pr_err("%s: v is NULL\n", __func__);
3509
3510 return -EINVAL;
3511 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003512
3513 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
3514 data->payload_size, data->opcode);
3515
Neema Shetty07477582011-09-02 17:35:44 -07003516 if (data->opcode == RESET_EVENTS) {
3517 pr_debug("%s: Reset event received in Voice service\n",
3518 __func__);
3519
3520 apr_reset(c->apr_q6_cvs);
3521 c->apr_q6_cvs = NULL;
3522
3523 /* Sub-system restart is applicable to all sessions. */
3524 for (i = 0; i < MAX_VOC_SESSIONS; i++)
3525 c->voice[i].cvs_handle = 0;
3526
3527 return 0;
3528 }
3529
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003530 if (data->opcode == APR_BASIC_RSP_RESULT) {
3531 if (data->payload_size) {
3532 ptr = data->payload;
3533
3534 pr_info("%x %x\n", ptr[0], ptr[1]);
3535 /*response from CVS */
3536 switch (ptr[0]) {
3537 case VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION:
3538 case VSS_ISTREAM_CMD_CREATE_FULL_CONTROL_SESSION:
3539 if (!ptr[1]) {
3540 pr_debug("%s: CVS handle is %d\n",
3541 __func__, data->src_port);
3542 voice_set_cvs_handle(v, data->src_port);
3543 } else
3544 pr_err("got NACK for sending \
3545 CVS create session \n");
3546 v->cvs_state = CMD_STATUS_SUCCESS;
3547 wake_up(&v->cvs_wait);
3548 break;
3549 case VSS_ISTREAM_CMD_SET_MUTE:
3550 case VSS_ISTREAM_CMD_SET_MEDIA_TYPE:
3551 case VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE:
3552 case VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE:
3553 case VSS_ISTREAM_CMD_SET_ENC_DTX_MODE:
3554 case VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE:
3555 case APRV2_IBASIC_CMD_DESTROY_SESSION:
Helen Zeng29eb7442011-06-20 11:06:29 -07003556 case VSS_ISTREAM_CMD_REGISTER_CALIBRATION_DATA:
3557 case VSS_ISTREAM_CMD_DEREGISTER_CALIBRATION_DATA:
3558 case VSS_ICOMMON_CMD_MAP_MEMORY:
3559 case VSS_ICOMMON_CMD_UNMAP_MEMORY:
Helen Zengbb49c702011-09-06 14:09:13 -07003560 case VSS_ICOMMON_CMD_SET_UI_PROPERTY:
Helen Zeng0705a5f2011-10-14 15:29:52 -07003561 case VSS_ISTREAM_CMD_START_PLAYBACK:
3562 case VSS_ISTREAM_CMD_STOP_PLAYBACK:
Helen Zenge3d716a2011-10-14 16:32:16 -07003563 case VSS_ISTREAM_CMD_START_RECORD:
3564 case VSS_ISTREAM_CMD_STOP_RECORD:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003565 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
3566 v->cvs_state = CMD_STATUS_SUCCESS;
3567 wake_up(&v->cvs_wait);
3568 break;
Ben Romberger13b74ab2011-07-18 17:36:32 -07003569 case VOICE_CMD_SET_PARAM:
3570 rtac_make_voice_callback(RTAC_CVS, ptr,
3571 data->payload_size);
3572 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003573 default:
3574 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
3575 break;
3576 }
3577 }
3578 } else if (data->opcode == VSS_ISTREAM_EVT_SEND_ENC_BUFFER) {
3579 uint32_t *voc_pkt = data->payload;
3580 uint32_t pkt_len = data->payload_size;
3581
Neema Shetty2c07eb52011-08-21 20:33:52 -07003582 if (voc_pkt != NULL && c->mvs_info.ul_cb != NULL) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003583 pr_debug("%s: Media type is 0x%x\n",
3584 __func__, voc_pkt[0]);
3585
3586 /* Remove media ID from payload. */
3587 voc_pkt++;
3588 pkt_len = pkt_len - 4;
3589
Neema Shetty2c07eb52011-08-21 20:33:52 -07003590 c->mvs_info.ul_cb((uint8_t *)voc_pkt,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003591 pkt_len,
Neema Shetty2c07eb52011-08-21 20:33:52 -07003592 c->mvs_info.private_data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003593 } else
3594 pr_err("%s: voc_pkt is 0x%x ul_cb is 0x%x\n",
3595 __func__, (unsigned int)voc_pkt,
Neema Shetty2c07eb52011-08-21 20:33:52 -07003596 (unsigned int) c->mvs_info.ul_cb);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003597 } else if (data->opcode == VSS_ISTREAM_EVT_REQUEST_DEC_BUFFER) {
3598 struct cvs_send_dec_buf_cmd send_dec_buf;
3599 int ret = 0;
3600 uint32_t pkt_len = 0;
3601
Neema Shetty2c07eb52011-08-21 20:33:52 -07003602 if (c->mvs_info.dl_cb != NULL) {
3603 send_dec_buf.dec_buf.media_id = c->mvs_info.media_type;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003604
Neema Shetty2c07eb52011-08-21 20:33:52 -07003605 c->mvs_info.dl_cb(
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003606 (uint8_t *)&send_dec_buf.dec_buf.packet_data,
3607 &pkt_len,
Neema Shetty2c07eb52011-08-21 20:33:52 -07003608 c->mvs_info.private_data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003609
3610 send_dec_buf.hdr.hdr_field =
3611 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
3612 APR_HDR_LEN(APR_HDR_SIZE),
3613 APR_PKT_VER);
3614 send_dec_buf.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
3615 sizeof(send_dec_buf.dec_buf.media_id) + pkt_len);
Neema Shetty2c07eb52011-08-21 20:33:52 -07003616 send_dec_buf.hdr.src_port = v->session_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003617 send_dec_buf.hdr.dest_port = voice_get_cvs_handle(v);
3618 send_dec_buf.hdr.token = 0;
3619 send_dec_buf.hdr.opcode =
3620 VSS_ISTREAM_EVT_SEND_DEC_BUFFER;
3621
Neema Shetty2c07eb52011-08-21 20:33:52 -07003622 ret = apr_send_pkt(c->apr_q6_cvs,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003623 (uint32_t *) &send_dec_buf);
3624 if (ret < 0) {
3625 pr_err("%s: Error %d sending DEC_BUF\n",
3626 __func__, ret);
3627 goto fail;
3628 }
3629 } else
3630 pr_debug("%s: dl_cb is NULL\n", __func__);
Ben Romberger13b74ab2011-07-18 17:36:32 -07003631 } else if (data->opcode == VSS_ISTREAM_EVT_SEND_DEC_BUFFER) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003632 pr_debug("Send dec buf resp\n");
Ben Romberger13b74ab2011-07-18 17:36:32 -07003633 } else if (data->opcode == VOICE_EVT_GET_PARAM_ACK) {
3634 rtac_make_voice_callback(RTAC_CVS, data->payload,
3635 data->payload_size);
3636 } else
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003637 pr_debug("Unknown opcode 0x%x\n", data->opcode);
3638
3639fail:
3640 return 0;
3641}
3642
3643static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv)
3644{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003645 uint32_t *ptr = NULL;
3646 struct common_data *c = NULL;
3647 struct voice_data *v = NULL;
Neema Shetty07477582011-09-02 17:35:44 -07003648 int i = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003649
3650 if ((data == NULL) || (priv == NULL)) {
3651 pr_err("%s: data or priv is NULL\n", __func__);
3652 return -EINVAL;
3653 }
Neema Shetty2c07eb52011-08-21 20:33:52 -07003654
3655 c = priv;
3656
3657 v = voice_get_session(data->dest_port);
3658 if (v == NULL) {
3659 pr_err("%s: v is NULL\n", __func__);
3660
3661 return -EINVAL;
3662 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003663
3664 pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
3665 data->payload_size, data->opcode);
3666
Neema Shetty07477582011-09-02 17:35:44 -07003667 if (data->opcode == RESET_EVENTS) {
3668 pr_debug("%s: Reset event received in Voice service\n",
3669 __func__);
3670
3671 apr_reset(c->apr_q6_cvp);
3672 c->apr_q6_cvp = NULL;
3673
3674 /* Sub-system restart is applicable to all sessions. */
3675 for (i = 0; i < MAX_VOC_SESSIONS; i++)
3676 c->voice[i].cvp_handle = 0;
3677
3678 return 0;
3679 }
3680
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003681 if (data->opcode == APR_BASIC_RSP_RESULT) {
3682 if (data->payload_size) {
3683 ptr = data->payload;
3684
3685 pr_info("%x %x\n", ptr[0], ptr[1]);
3686
3687 switch (ptr[0]) {
3688 case VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION:
3689 /*response from CVP */
3690 pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
3691 if (!ptr[1]) {
3692 voice_set_cvp_handle(v, data->src_port);
3693 pr_debug("cvphdl=%d\n", data->src_port);
3694 } else
3695 pr_err("got NACK from CVP create \
3696 session response\n");
3697 v->cvp_state = CMD_STATUS_SUCCESS;
3698 wake_up(&v->cvp_wait);
3699 break;
3700 case VSS_IVOCPROC_CMD_SET_DEVICE:
3701 case VSS_IVOCPROC_CMD_SET_RX_VOLUME_INDEX:
3702 case VSS_IVOCPROC_CMD_ENABLE:
3703 case VSS_IVOCPROC_CMD_DISABLE:
3704 case APRV2_IBASIC_CMD_DESTROY_SESSION:
Helen Zeng29eb7442011-06-20 11:06:29 -07003705 case VSS_IVOCPROC_CMD_REGISTER_VOLUME_CAL_TABLE:
3706 case VSS_IVOCPROC_CMD_DEREGISTER_VOLUME_CAL_TABLE:
3707 case VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA:
3708 case VSS_IVOCPROC_CMD_DEREGISTER_CALIBRATION_DATA:
3709 case VSS_ICOMMON_CMD_MAP_MEMORY:
3710 case VSS_ICOMMON_CMD_UNMAP_MEMORY:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003711 v->cvp_state = CMD_STATUS_SUCCESS;
3712 wake_up(&v->cvp_wait);
3713 break;
Ben Romberger13b74ab2011-07-18 17:36:32 -07003714 case VOICE_CMD_SET_PARAM:
3715 rtac_make_voice_callback(RTAC_CVP, ptr,
3716 data->payload_size);
3717 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003718 default:
3719 pr_debug("%s: not match cmd = 0x%x\n",
3720 __func__, ptr[0]);
3721 break;
3722 }
3723 }
Ben Romberger13b74ab2011-07-18 17:36:32 -07003724 } else if (data->opcode == VOICE_EVT_GET_PARAM_ACK) {
3725 rtac_make_voice_callback(RTAC_CVP, data->payload,
3726 data->payload_size);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003727 }
3728 return 0;
3729}
3730
3731
3732static int __init voice_init(void)
3733{
Neema Shetty2c07eb52011-08-21 20:33:52 -07003734 int rc = 0, i = 0;
Helen Zeng6e64dba2012-03-08 18:30:11 -08003735 int len;
Neema Shetty2c07eb52011-08-21 20:33:52 -07003736
3737 memset(&common, 0, sizeof(struct common_data));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003738
Helen Zeng6e64dba2012-03-08 18:30:11 -08003739 /* Allocate memory for VoIP calibration */
3740 common.client = msm_ion_client_create(UINT_MAX, "voip_client");
3741 if (IS_ERR_OR_NULL((void *)common.client)) {
3742 pr_err("%s: ION create client for Voip failed\n", __func__);
3743 goto cont;
3744 }
3745 common.cvp_cal.handle = ion_alloc(common.client, CVP_CAL_SIZE, SZ_4K,
3746 ION_HEAP(ION_AUDIO_HEAP_ID));
3747 if (IS_ERR_OR_NULL((void *) common.cvp_cal.handle)) {
3748 pr_err("%s: ION memory allocation for CVP failed\n",
3749 __func__);
3750 ion_client_destroy(common.client);
3751 goto cont;
3752 }
3753
3754 rc = ion_phys(common.client, common.cvp_cal.handle,
3755 (ion_phys_addr_t *)&common.cvp_cal.phy, (size_t *)&len);
3756 if (rc) {
3757 pr_err("%s: ION Get Physical for cvp failed, rc = %d\n",
3758 __func__, rc);
3759 ion_free(common.client, common.cvp_cal.handle);
3760 ion_client_destroy(common.client);
3761 goto cont;
3762 }
3763
3764 common.cvp_cal.buf = ion_map_kernel(common.client,
3765 common.cvp_cal.handle, 0);
3766 if (IS_ERR_OR_NULL((void *) common.cvp_cal.buf)) {
3767 pr_err("%s: ION memory mapping for cvp failed\n", __func__);
3768 common.cvp_cal.buf = NULL;
3769 ion_free(common.client, common.cvp_cal.handle);
3770 ion_client_destroy(common.client);
3771 goto cont;
3772 }
3773 memset((void *)common.cvp_cal.buf, 0, CVP_CAL_SIZE);
3774
3775 common.cvs_cal.handle = ion_alloc(common.client, CVS_CAL_SIZE, SZ_4K,
3776 ION_HEAP(ION_AUDIO_HEAP_ID));
3777 if (IS_ERR_OR_NULL((void *) common.cvs_cal.handle)) {
3778 pr_err("%s: ION memory allocation for CVS failed\n",
3779 __func__);
3780 goto cont;
3781 }
3782
3783 rc = ion_phys(common.client, common.cvs_cal.handle,
3784 (ion_phys_addr_t *)&common.cvs_cal.phy, (size_t *)&len);
3785 if (rc) {
3786 pr_err("%s: ION Get Physical for cvs failed, rc = %d\n",
3787 __func__, rc);
3788 ion_free(common.client, common.cvs_cal.handle);
3789 goto cont;
3790 }
3791
3792 common.cvs_cal.buf = ion_map_kernel(common.client,
3793 common.cvs_cal.handle, 0);
3794 if (IS_ERR_OR_NULL((void *) common.cvs_cal.buf)) {
3795 pr_err("%s: ION memory mapping for cvs failed\n", __func__);
3796 common.cvs_cal.buf = NULL;
3797 ion_free(common.client, common.cvs_cal.handle);
3798 goto cont;
3799 }
3800 memset((void *)common.cvs_cal.buf, 0, CVS_CAL_SIZE);
3801cont:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003802 /* set default value */
Neema Shetty2c07eb52011-08-21 20:33:52 -07003803 common.default_mute_val = 1; /* default is mute */
3804 common.default_vol_val = 0;
3805 common.default_sample_val = 8000;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003806
3807 /* Initialize MVS info. */
Neema Shetty2c07eb52011-08-21 20:33:52 -07003808 common.mvs_info.network_type = VSS_NETWORK_ID_DEFAULT;
3809
3810 mutex_init(&common.common_lock);
3811
3812 for (i = 0; i < MAX_VOC_SESSIONS; i++) {
3813 common.voice[i].session_id = SESSION_ID_BASE + i;
3814
3815 /* initialize dev_rx and dev_tx */
3816 common.voice[i].dev_rx.volume = common.default_vol_val;
Helen Zeng68656932011-11-02 18:08:23 -07003817 common.voice[i].dev_rx.mute = 0;
Neema Shetty2c07eb52011-08-21 20:33:52 -07003818 common.voice[i].dev_tx.mute = common.default_mute_val;
3819
3820 common.voice[i].dev_tx.port_id = 1;
3821 common.voice[i].dev_rx.port_id = 0;
3822 common.voice[i].sidetone_gain = 0x512;
3823
3824 common.voice[i].voc_state = VOC_INIT;
3825
3826 init_waitqueue_head(&common.voice[i].mvm_wait);
3827 init_waitqueue_head(&common.voice[i].cvs_wait);
3828 init_waitqueue_head(&common.voice[i].cvp_wait);
3829
3830 mutex_init(&common.voice[i].lock);
3831 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003832
3833 return rc;
3834}
3835
3836device_initcall(voice_init);