blob: 84ef8355a1c3ffa9de20b3e689a1e1eebba5a398 [file] [log] [blame]
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
14#include <linux/fs.h>
15#include <linux/module.h>
16#include <linux/miscdevice.h>
17#include <linux/slab.h>
18#include <linux/uaccess.h>
19#include <linux/mutex.h>
20#include <linux/sched.h>
21#include <linux/msm_audio_calibration.h>
22#include <linux/atomic.h>
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053023#include <linux/compat.h>
Laxminath Kasam605b42f2017-08-01 22:02:15 +053024#include <dsp/msm_audio_ion.h>
25#include <dsp/rtac.h>
26#include <dsp/q6asm-v2.h>
27#include <dsp/q6afe-v2.h>
28#include <dsp/q6adm-v2.h>
29#include <dsp/apr_audio-v2.h>
30#include <dsp/q6voice.h>
31#include "adsp_err.h"
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053032
33
34/* Max size of payload (buf size - apr header) */
35#define MAX_PAYLOAD_SIZE 4076
36#define RTAC_MAX_ACTIVE_VOICE_COMBOS 2
37#define RTAC_MAX_ACTIVE_POPP 8
38#define RTAC_BUF_SIZE 163840
39
40#define TIMEOUT_MS 1000
41
42struct rtac_cal_block_data rtac_cal[MAX_RTAC_BLOCKS] = {
43/* ADM_RTAC_CAL */
44 {{RTAC_BUF_SIZE, 0, 0, 0}, {0, 0, 0} },
45/* ASM_RTAC_CAL */
46 {{RTAC_BUF_SIZE, 0, 0, 0}, {0, 0, 0} },
47/* VOICE_RTAC_CAL */
48 {{RTAC_BUF_SIZE, 0, 0, 0}, {0, 0, 0} },
49/* AFE_RTAC_CAL */
50 {{RTAC_BUF_SIZE, 0, 0, 0}, {0, 0, 0} }
51};
52
53struct rtac_common_data {
54 atomic_t usage_count;
55 atomic_t apr_err_code;
56};
57
58static struct rtac_common_data rtac_common;
59
60/* APR data */
61struct rtac_apr_data {
62 void *apr_handle;
63 atomic_t cmd_state;
64 wait_queue_head_t cmd_wait;
65};
66
67static struct rtac_apr_data rtac_adm_apr_data;
68static struct rtac_apr_data rtac_asm_apr_data[ASM_ACTIVE_STREAMS_ALLOWED + 1];
69static struct rtac_apr_data rtac_afe_apr_data;
70static struct rtac_apr_data rtac_voice_apr_data[RTAC_VOICE_MODES];
71
72/* ADM info & APR */
73static struct rtac_adm rtac_adm_data;
74static u32 *rtac_adm_buffer;
75
76
77/* ASM APR */
78static u32 *rtac_asm_buffer;
79
80static u32 *rtac_afe_buffer;
81
82/* Voice info & APR */
83struct rtac_voice_data_t {
84 uint32_t tx_topology_id;
85 uint32_t rx_topology_id;
86 uint32_t tx_afe_topology;
87 uint32_t rx_afe_topology;
88 uint32_t tx_afe_port;
89 uint32_t rx_afe_port;
90 uint16_t cvs_handle;
91 uint16_t cvp_handle;
92 uint32_t tx_acdb_id;
93 uint32_t rx_acdb_id;
94};
95
96struct rtac_voice {
97 uint32_t num_of_voice_combos;
98 struct rtac_voice_data_t voice[RTAC_MAX_ACTIVE_VOICE_COMBOS];
99};
100
101struct rtac_afe_user_data {
102 uint32_t buf_size;
103 uint32_t cmd_size;
104 uint32_t port_id;
105 union {
106 struct rtac_afe_set {
107 struct afe_port_cmd_set_param_v2 cmd;
108 struct afe_port_param_data_v2 data;
109 } rtac_afe_set;
110 struct rtac_afe_get {
111 struct afe_port_cmd_get_param_v2 cmd;
112 struct afe_port_param_data_v2 data;
113 } rtac_afe_get;
114 };
115} __packed;
116
117static struct rtac_voice rtac_voice_data;
118static u32 *rtac_voice_buffer;
119static u32 voice_session_id[RTAC_MAX_ACTIVE_VOICE_COMBOS];
120
121
122struct mutex rtac_adm_mutex;
123struct mutex rtac_adm_apr_mutex;
124struct mutex rtac_asm_apr_mutex;
125struct mutex rtac_voice_mutex;
126struct mutex rtac_voice_apr_mutex;
127struct mutex rtac_afe_apr_mutex;
128
129int rtac_clear_mapping(uint32_t cal_type)
130{
131 int result = 0;
132
133 pr_debug("%s\n", __func__);
134
135 if (cal_type >= MAX_RTAC_BLOCKS) {
136 pr_debug("%s: invalid cal type %d\n", __func__, cal_type);
137 result = -EINVAL;
138 goto done;
139 }
140
141 rtac_cal[cal_type].map_data.map_handle = 0;
142done:
143 return result;
144}
145
146int rtac_allocate_cal_buffer(uint32_t cal_type)
147{
148 int result = 0;
149 size_t len;
150
151 pr_debug("%s\n", __func__);
152
153 if (cal_type >= MAX_RTAC_BLOCKS) {
154 pr_err("%s: cal_type %d is invalid!\n",
155 __func__, cal_type);
156 result = -EINVAL;
157 goto done;
158 }
159
160 if (rtac_cal[cal_type].cal_data.paddr != 0) {
161 pr_err("%s: memory already allocated! cal_type %d, paddr 0x%pK\n",
162 __func__, cal_type, &rtac_cal[cal_type].cal_data.paddr);
163 result = -EPERM;
164 goto done;
165 }
166
167 result = msm_audio_ion_alloc("rtac_client",
168 &rtac_cal[cal_type].map_data.ion_client,
169 &rtac_cal[cal_type].map_data.ion_handle,
170 rtac_cal[cal_type].map_data.map_size,
171 &rtac_cal[cal_type].cal_data.paddr,
172 &len,
173 &rtac_cal[cal_type].cal_data.kvaddr);
174 if (result < 0) {
175 pr_err("%s: ION create client for RTAC failed\n",
176 __func__);
177 goto done;
178 }
179
180 pr_debug("%s: cal_type %d, paddr 0x%pK, kvaddr 0x%pK, map_size 0x%x\n",
181 __func__, cal_type,
182 &rtac_cal[cal_type].cal_data.paddr,
183 rtac_cal[cal_type].cal_data.kvaddr,
184 rtac_cal[cal_type].map_data.map_size);
185done:
186 return result;
187}
188
189int rtac_free_cal_buffer(uint32_t cal_type)
190{
191 int result = 0;
192
193 pr_debug("%s\n", __func__);
194
195 if (cal_type >= MAX_RTAC_BLOCKS) {
196 pr_err("%s: cal_type %d is invalid!\n",
197 __func__, cal_type);
198 result = -EINVAL;
199 goto done;
200 }
201
202 if (rtac_cal[cal_type].map_data.ion_client == NULL) {
203 pr_debug("%s: cal_type %d not allocated!\n",
204 __func__, cal_type);
205 goto done;
206 }
207
208 result = msm_audio_ion_free(rtac_cal[cal_type].map_data.ion_client,
209 rtac_cal[cal_type].map_data.ion_handle);
210 if (result < 0) {
211 pr_err("%s: ION free for RTAC failed! cal_type %d, paddr 0x%pK\n",
212 __func__, cal_type, &rtac_cal[cal_type].cal_data.paddr);
213 goto done;
214 }
215
216 rtac_cal[cal_type].map_data.map_handle = 0;
217 rtac_cal[cal_type].map_data.ion_client = NULL;
218 rtac_cal[cal_type].map_data.ion_handle = NULL;
219 rtac_cal[cal_type].cal_data.size = 0;
220 rtac_cal[cal_type].cal_data.kvaddr = 0;
221 rtac_cal[cal_type].cal_data.paddr = 0;
222done:
223 return result;
224}
225
226int rtac_map_cal_buffer(uint32_t cal_type)
227{
228 int result = 0;
229
230 pr_debug("%s\n", __func__);
231
232 if (cal_type >= MAX_RTAC_BLOCKS) {
233 pr_err("%s: cal_type %d is invalid!\n",
234 __func__, cal_type);
235 result = -EINVAL;
236 goto done;
237 }
238
239 if (rtac_cal[cal_type].map_data.map_handle != 0) {
240 pr_err("%s: already mapped cal_type %d\n",
241 __func__, cal_type);
242 result = -EPERM;
243 goto done;
244 }
245
246 if (rtac_cal[cal_type].cal_data.paddr == 0) {
247 pr_err("%s: physical address is NULL cal_type %d\n",
248 __func__, cal_type);
249 result = -EPERM;
250 goto done;
251 }
252
253 switch (cal_type) {
254 case ADM_RTAC_CAL:
255 result = adm_map_rtac_block(&rtac_cal[cal_type]);
256 break;
257 case ASM_RTAC_CAL:
258 result = q6asm_map_rtac_block(&rtac_cal[cal_type]);
259 break;
260 case VOICE_RTAC_CAL:
261 result = voc_map_rtac_block(&rtac_cal[cal_type]);
262 break;
263 case AFE_RTAC_CAL:
264 result = afe_map_rtac_block(&rtac_cal[cal_type]);
265 break;
266 }
267 if (result < 0) {
268 pr_err("%s: map RTAC failed! cal_type %d\n",
269 __func__, cal_type);
270 goto done;
271 }
272done:
273 return result;
274}
275
276int rtac_unmap_cal_buffer(uint32_t cal_type)
277{
278 int result = 0;
279
280 pr_debug("%s\n", __func__);
281
282 if (cal_type >= MAX_RTAC_BLOCKS) {
283 pr_err("%s: cal_type %d is invalid!\n",
284 __func__, cal_type);
285 result = -EINVAL;
286 goto done;
287 }
288
289 if (rtac_cal[cal_type].map_data.map_handle == 0) {
290 pr_debug("%s: nothing to unmap cal_type %d\n",
291 __func__, cal_type);
292 goto done;
293 }
294
295 switch (cal_type) {
296 case ADM_RTAC_CAL:
297 result = adm_unmap_rtac_block(
298 &rtac_cal[cal_type].map_data.map_handle);
299 break;
300 case ASM_RTAC_CAL:
301 result = q6asm_unmap_rtac_block(
302 &rtac_cal[cal_type].map_data.map_handle);
303 break;
304 case VOICE_RTAC_CAL:
305 result = voc_unmap_rtac_block(
306 &rtac_cal[cal_type].map_data.map_handle);
307 break;
308 case AFE_RTAC_CAL:
309 result = afe_unmap_rtac_block(
310 &rtac_cal[cal_type].map_data.map_handle);
311 break;
312 }
313 if (result < 0) {
314 pr_err("%s: unmap RTAC failed! cal_type %d\n",
315 __func__, cal_type);
316 goto done;
317 }
318done:
319 return result;
320}
321
322static int rtac_open(struct inode *inode, struct file *f)
323{
324 int result = 0;
325
326 pr_debug("%s\n", __func__);
327
328 atomic_inc(&rtac_common.usage_count);
329 return result;
330}
331
332static int rtac_release(struct inode *inode, struct file *f)
333{
334 int result = 0;
335 int result2 = 0;
336 int i;
337
338 pr_debug("%s\n", __func__);
339
340 atomic_dec(&rtac_common.usage_count);
341 pr_debug("%s: ref count %d!\n", __func__,
342 atomic_read(&rtac_common.usage_count));
343
344 if (atomic_read(&rtac_common.usage_count) > 0)
345 goto done;
346
347 for (i = 0; i < MAX_RTAC_BLOCKS; i++) {
348 result2 = rtac_unmap_cal_buffer(i);
349 if (result2 < 0) {
350 pr_err("%s: unmap buffer failed! error %d!\n",
351 __func__, result2);
352 result = result2;
353 }
354
355 result2 = rtac_free_cal_buffer(i);
356 if (result2 < 0) {
357 pr_err("%s: free buffer failed! error %d!\n",
358 __func__, result2);
359 result = result2;
360 }
361 }
362done:
363 return result;
364}
365
366
367/* ADM Info */
368void add_popp(u32 dev_idx, u32 port_id, u32 popp_id)
369{
370 u32 i = 0;
371
372 for (; i < rtac_adm_data.device[dev_idx].num_of_popp; i++)
373 if (rtac_adm_data.device[dev_idx].popp[i].popp == popp_id)
374 goto done;
375
376 if (rtac_adm_data.device[dev_idx].num_of_popp ==
377 RTAC_MAX_ACTIVE_POPP) {
378 pr_err("%s, Max POPP!\n", __func__);
379 goto done;
380 }
381 rtac_adm_data.device[dev_idx].popp[
382 rtac_adm_data.device[dev_idx].num_of_popp].popp = popp_id;
383 rtac_adm_data.device[dev_idx].popp[
384 rtac_adm_data.device[dev_idx].num_of_popp].popp_topology =
385 q6asm_get_asm_topology(popp_id);
386 rtac_adm_data.device[dev_idx].popp[
387 rtac_adm_data.device[dev_idx].num_of_popp++].app_type =
388 q6asm_get_asm_app_type(popp_id);
389
390 pr_debug("%s: popp_id = %d, popp topology = 0x%x, popp app type = 0x%x\n",
391 __func__,
392 rtac_adm_data.device[dev_idx].popp[
393 rtac_adm_data.device[dev_idx].num_of_popp - 1].popp,
394 rtac_adm_data.device[dev_idx].popp[
395 rtac_adm_data.device[dev_idx].num_of_popp - 1].popp_topology,
396 rtac_adm_data.device[dev_idx].popp[
397 rtac_adm_data.device[dev_idx].num_of_popp - 1].app_type);
398done:
399 return;
400}
401
402void rtac_update_afe_topology(u32 port_id)
403{
404 u32 i = 0;
405
406 mutex_lock(&rtac_adm_mutex);
407 for (i = 0; i < rtac_adm_data.num_of_dev; i++) {
408 if (rtac_adm_data.device[i].afe_port == port_id) {
409 rtac_adm_data.device[i].afe_topology =
410 afe_get_topology(port_id);
411 pr_debug("%s: port_id = 0x%x topology_id = 0x%x copp_id = %d\n",
412 __func__, port_id,
413 rtac_adm_data.device[i].afe_topology,
414 rtac_adm_data.device[i].copp);
415 }
416 }
417 mutex_unlock(&rtac_adm_mutex);
418}
419
420void rtac_add_adm_device(u32 port_id, u32 copp_id, u32 path_id, u32 popp_id,
421 u32 app_type, u32 acdb_id)
422{
423 u32 i = 0;
424
425 pr_debug("%s: num rtac devices %d port_id = %d, copp_id = %d\n",
426 __func__, rtac_adm_data.num_of_dev, port_id, copp_id);
427
428 mutex_lock(&rtac_adm_mutex);
429 if (rtac_adm_data.num_of_dev == RTAC_MAX_ACTIVE_DEVICES) {
430 pr_err("%s, Can't add anymore RTAC devices!\n", __func__);
431 goto done;
432 }
433
434 /* Check if device already added */
435 if (rtac_adm_data.num_of_dev != 0) {
436 for (; i < rtac_adm_data.num_of_dev; i++) {
437 if (rtac_adm_data.device[i].afe_port == port_id &&
438 rtac_adm_data.device[i].copp == copp_id) {
439 add_popp(i, port_id, popp_id);
440 goto done;
441 }
442 if (rtac_adm_data.device[i].num_of_popp ==
443 RTAC_MAX_ACTIVE_POPP) {
444 pr_err("%s, Max POPP!\n", __func__);
445 goto done;
446 }
447 }
448 }
449
450 /* Add device */
451 rtac_adm_data.num_of_dev++;
452
453 rtac_adm_data.device[i].topology_id =
454 adm_get_topology_for_port_from_copp_id(port_id, copp_id);
455 rtac_adm_data.device[i].afe_topology =
456 afe_get_topology(port_id);
457 rtac_adm_data.device[i].afe_port = port_id;
458 rtac_adm_data.device[i].copp = copp_id;
459 rtac_adm_data.device[i].app_type = app_type;
460 rtac_adm_data.device[i].acdb_dev_id = acdb_id;
461 rtac_adm_data.device[i].popp[
462 rtac_adm_data.device[i].num_of_popp].popp = popp_id;
463 rtac_adm_data.device[i].popp[
464 rtac_adm_data.device[i].num_of_popp].popp_topology =
465 q6asm_get_asm_topology(popp_id);
466 rtac_adm_data.device[i].popp[
467 rtac_adm_data.device[i].num_of_popp++].app_type =
468 q6asm_get_asm_app_type(popp_id);
469
470 pr_debug("%s: topology = 0x%x, afe_topology = 0x%x, port_id = %d, copp_id = %d, app id = 0x%x, acdb id = %d, popp_id = %d, popp topology = 0x%x, popp app type = 0x%x\n",
471 __func__,
472 rtac_adm_data.device[i].topology_id,
473 rtac_adm_data.device[i].afe_topology,
474 rtac_adm_data.device[i].afe_port,
475 rtac_adm_data.device[i].copp,
476 rtac_adm_data.device[i].app_type,
477 rtac_adm_data.device[i].acdb_dev_id,
478 rtac_adm_data.device[i].popp[
479 rtac_adm_data.device[i].num_of_popp - 1].popp,
480 rtac_adm_data.device[i].popp[
481 rtac_adm_data.device[i].num_of_popp - 1].popp_topology,
482 rtac_adm_data.device[i].popp[
483 rtac_adm_data.device[i].num_of_popp - 1].app_type);
484done:
485 mutex_unlock(&rtac_adm_mutex);
486}
487
488static void shift_adm_devices(u32 dev_idx)
489{
490 for (; dev_idx < rtac_adm_data.num_of_dev; dev_idx++) {
491 memcpy(&rtac_adm_data.device[dev_idx],
492 &rtac_adm_data.device[dev_idx + 1],
493 sizeof(rtac_adm_data.device[dev_idx]));
494 memset(&rtac_adm_data.device[dev_idx + 1], 0,
495 sizeof(rtac_adm_data.device[dev_idx]));
496 }
497}
498
499static void shift_popp(u32 copp_idx, u32 popp_idx)
500{
501 for (; popp_idx < rtac_adm_data.device[copp_idx].num_of_popp;
502 popp_idx++) {
503 memcpy(&rtac_adm_data.device[copp_idx].popp[popp_idx].popp,
504 &rtac_adm_data.device[copp_idx].popp[popp_idx + 1].
505 popp, sizeof(uint32_t));
506 memcpy(&rtac_adm_data.device[copp_idx].popp[popp_idx].
507 popp_topology,
508 &rtac_adm_data.device[copp_idx].popp[popp_idx + 1].
509 popp_topology,
510 sizeof(uint32_t));
511 memset(&rtac_adm_data.device[copp_idx].popp[popp_idx + 1].
512 popp, 0, sizeof(uint32_t));
513 memset(&rtac_adm_data.device[copp_idx].popp[popp_idx + 1].
514 popp_topology, 0, sizeof(uint32_t));
515 }
516}
517
518void rtac_remove_adm_device(u32 port_id, u32 copp_id)
519{
520 s32 i;
521
522 pr_debug("%s: num rtac devices %d port_id = %d, copp_id = %d\n",
523 __func__, rtac_adm_data.num_of_dev, port_id, copp_id);
524
525 mutex_lock(&rtac_adm_mutex);
526 /* look for device */
527 for (i = 0; i < rtac_adm_data.num_of_dev; i++) {
528 if (rtac_adm_data.device[i].afe_port == port_id &&
529 rtac_adm_data.device[i].copp == copp_id) {
530 memset(&rtac_adm_data.device[i], 0,
531 sizeof(rtac_adm_data.device[i]));
532 rtac_adm_data.num_of_dev--;
533
534 if (rtac_adm_data.num_of_dev >= 1) {
535 shift_adm_devices(i);
536 break;
537 }
538 }
539 }
540
541 mutex_unlock(&rtac_adm_mutex);
542}
543
544void rtac_remove_popp_from_adm_devices(u32 popp_id)
545{
546 s32 i, j;
547
548 pr_debug("%s: popp_id = %d\n", __func__, popp_id);
549
550 mutex_lock(&rtac_adm_mutex);
551 for (i = 0; i < rtac_adm_data.num_of_dev; i++) {
552 for (j = 0; j < rtac_adm_data.device[i].num_of_popp; j++) {
553 if (rtac_adm_data.device[i].popp[j].popp ==
554 popp_id) {
555 rtac_adm_data.device[i].popp[j].popp = 0;
556 rtac_adm_data.device[i].popp[j].
557 popp_topology = 0;
558 rtac_adm_data.device[i].num_of_popp--;
559 shift_popp(i, j);
560 }
561 }
562 }
563 mutex_unlock(&rtac_adm_mutex);
564}
565
566
567/* Voice Info */
568static void set_rtac_voice_data(int idx, u32 cvs_handle, u32 cvp_handle,
569 u32 rx_afe_port, u32 tx_afe_port,
570 u32 rx_acdb_id, u32 tx_acdb_id,
571 u32 session_id)
572{
573 rtac_voice_data.voice[idx].tx_topology_id =
574 voice_get_topology(CVP_VOC_TX_TOPOLOGY_CAL);
575 rtac_voice_data.voice[idx].rx_topology_id =
576 voice_get_topology(CVP_VOC_RX_TOPOLOGY_CAL);
577 rtac_voice_data.voice[idx].tx_afe_topology =
578 afe_get_topology(tx_afe_port);
579 rtac_voice_data.voice[idx].rx_afe_topology =
580 afe_get_topology(rx_afe_port);
581 rtac_voice_data.voice[idx].tx_afe_port = tx_afe_port;
582 rtac_voice_data.voice[idx].rx_afe_port = rx_afe_port;
583 rtac_voice_data.voice[idx].tx_acdb_id = tx_acdb_id;
584 rtac_voice_data.voice[idx].rx_acdb_id = rx_acdb_id;
585 rtac_voice_data.voice[idx].cvs_handle = cvs_handle;
586 rtac_voice_data.voice[idx].cvp_handle = cvp_handle;
587 pr_debug("%s\n%s: %x\n%s: %d %s: %d\n%s: %d %s: %d\n %s: %d\n %s: %d\n%s: %d %s: %d\n%s",
588 "<---- Voice Data Info ---->", "Session id", session_id,
589 "cvs_handle", cvs_handle, "cvp_handle", cvp_handle,
590 "rx_afe_topology", rtac_voice_data.voice[idx].rx_afe_topology,
591 "tx_afe_topology", rtac_voice_data.voice[idx].tx_afe_topology,
592 "rx_afe_port", rx_afe_port, "tx_afe_port", tx_afe_port,
593 "rx_acdb_id", rx_acdb_id, "tx_acdb_id", tx_acdb_id,
594 "<-----------End----------->");
595
596 /* Store session ID for voice RTAC */
597 voice_session_id[idx] = session_id;
598}
599
600void rtac_add_voice(u32 cvs_handle, u32 cvp_handle, u32 rx_afe_port,
601 u32 tx_afe_port, u32 rx_acdb_id, u32 tx_acdb_id,
602 u32 session_id)
603{
604 u32 i = 0;
605
606 pr_debug("%s\n", __func__);
607 mutex_lock(&rtac_voice_mutex);
608
609 if (rtac_voice_data.num_of_voice_combos ==
610 RTAC_MAX_ACTIVE_VOICE_COMBOS) {
611 pr_err("%s, Can't add anymore RTAC devices!\n", __func__);
612 goto done;
613 }
614
615 /* Check if device already added */
616 if (rtac_voice_data.num_of_voice_combos != 0) {
617 for (; i < rtac_voice_data.num_of_voice_combos; i++) {
618 if (rtac_voice_data.voice[i].cvs_handle ==
619 cvs_handle) {
620 set_rtac_voice_data(i, cvs_handle, cvp_handle,
621 rx_afe_port, tx_afe_port, rx_acdb_id,
622 tx_acdb_id, session_id);
623 goto done;
624 }
625 }
626 }
627
628 /* Add device */
629 rtac_voice_data.num_of_voice_combos++;
630 set_rtac_voice_data(i, cvs_handle, cvp_handle,
631 rx_afe_port, tx_afe_port,
632 rx_acdb_id, tx_acdb_id,
633 session_id);
634done:
635 mutex_unlock(&rtac_voice_mutex);
636}
637
638static void shift_voice_devices(u32 idx)
639{
640 for (; idx < rtac_voice_data.num_of_voice_combos - 1; idx++) {
641 memcpy(&rtac_voice_data.voice[idx],
642 &rtac_voice_data.voice[idx + 1],
643 sizeof(rtac_voice_data.voice[idx]));
644 voice_session_id[idx] = voice_session_id[idx + 1];
645 }
646}
647
648void rtac_remove_voice(u32 cvs_handle)
649{
650 u32 i = 0;
651
652 pr_debug("%s\n", __func__);
653
654 mutex_lock(&rtac_voice_mutex);
655 /* look for device */
656 for (i = 0; i < rtac_voice_data.num_of_voice_combos; i++) {
657 if (rtac_voice_data.voice[i].cvs_handle == cvs_handle) {
658 shift_voice_devices(i);
659 rtac_voice_data.num_of_voice_combos--;
660 memset(&rtac_voice_data.voice[
661 rtac_voice_data.num_of_voice_combos], 0,
662 sizeof(rtac_voice_data.voice
663 [rtac_voice_data.num_of_voice_combos]));
664 voice_session_id[rtac_voice_data.num_of_voice_combos]
665 = 0;
666 break;
667 }
668 }
669 mutex_unlock(&rtac_voice_mutex);
670}
671
672static u32 get_voice_session_id_cvs(u32 cvs_handle)
673{
674 u32 i;
675
676 for (i = 0; i < rtac_voice_data.num_of_voice_combos; i++) {
677 if (rtac_voice_data.voice[i].cvs_handle == cvs_handle)
678 return voice_session_id[i];
679 }
680
681 pr_err("%s: No voice index for CVS handle %d found returning 0\n",
682 __func__, cvs_handle);
683 return 0;
684}
685
686static u32 get_voice_session_id_cvp(u32 cvp_handle)
687{
688 u32 i;
689
690 for (i = 0; i < rtac_voice_data.num_of_voice_combos; i++) {
691 if (rtac_voice_data.voice[i].cvp_handle == cvp_handle)
692 return voice_session_id[i];
693 }
694
695 pr_err("%s: No voice index for CVP handle %d found returning 0\n",
696 __func__, cvp_handle);
697 return 0;
698}
699
700static int get_voice_index(u32 mode, u32 handle)
701{
702 if (mode == RTAC_CVP)
703 return voice_get_idx_for_session(
704 get_voice_session_id_cvp(handle));
705 if (mode == RTAC_CVS)
706 return voice_get_idx_for_session(
707 get_voice_session_id_cvs(handle));
708
709 pr_err("%s: Invalid mode %d, returning 0\n",
710 __func__, mode);
711 return 0;
712}
713
714
715/* ADM APR */
716void rtac_set_adm_handle(void *handle)
717{
718 pr_debug("%s: handle = %pK\n", __func__, handle);
719
720 mutex_lock(&rtac_adm_apr_mutex);
721 rtac_adm_apr_data.apr_handle = handle;
722 mutex_unlock(&rtac_adm_apr_mutex);
723}
724
725bool rtac_make_adm_callback(uint32_t *payload, u32 payload_size)
726{
727 pr_debug("%s:cmd_state = %d\n", __func__,
728 atomic_read(&rtac_adm_apr_data.cmd_state));
729 if (atomic_read(&rtac_adm_apr_data.cmd_state) != 1)
730 return false;
731
732 pr_debug("%s\n", __func__);
733 if (payload_size == sizeof(uint32_t))
734 atomic_set(&rtac_common.apr_err_code, payload[0]);
735 else if (payload_size == (2*sizeof(uint32_t)))
736 atomic_set(&rtac_common.apr_err_code, payload[1]);
737
738 atomic_set(&rtac_adm_apr_data.cmd_state, 0);
739 wake_up(&rtac_adm_apr_data.cmd_wait);
740 return true;
741}
742
743int send_adm_apr(void *buf, u32 opcode)
744{
745 s32 result;
746 u32 user_buf_size = 0;
747 u32 bytes_returned = 0;
748 u32 copp_id;
749 u32 payload_size;
750 u32 data_size = 0;
751 int copp_idx;
752 int port_idx;
753 struct apr_hdr adm_params;
754
755 pr_debug("%s\n", __func__);
756
757 if (rtac_cal[ADM_RTAC_CAL].map_data.ion_handle == NULL) {
758 result = rtac_allocate_cal_buffer(ADM_RTAC_CAL);
759 if (result < 0) {
760 pr_err("%s: allocate buffer failed!",
761 __func__);
762 goto done;
763 }
764 }
765
766 if (rtac_cal[ADM_RTAC_CAL].map_data.map_handle == 0) {
767 result = rtac_map_cal_buffer(ADM_RTAC_CAL);
768 if (result < 0) {
769 pr_err("%s: map buffer failed!",
770 __func__);
771 goto done;
772 }
773 }
774
775 if (copy_from_user(&user_buf_size, (void *)buf,
776 sizeof(user_buf_size))) {
777 pr_err("%s: Copy from user failed! buf = 0x%pK\n",
778 __func__, buf);
779 goto done;
780 }
781 if (user_buf_size <= 0) {
782 pr_err("%s: Invalid buffer size = %d\n",
783 __func__, user_buf_size);
784 goto done;
785 }
786
787 if (copy_from_user(&payload_size, buf + sizeof(u32), sizeof(u32))) {
788 pr_err("%s: Could not copy payload size from user buffer\n",
789 __func__);
790 goto done;
791 }
792
793 if (copy_from_user(&copp_id, buf + 2 * sizeof(u32), sizeof(u32))) {
794 pr_err("%s: Could not copy port id from user buffer\n",
795 __func__);
796 goto done;
797 }
798
799 if (adm_get_indexes_from_copp_id(copp_id, &copp_idx, &port_idx) != 0) {
800 pr_err("%s: Copp Id-%d is not active\n", __func__, copp_id);
801 goto done;
802 }
803
804 mutex_lock(&rtac_adm_apr_mutex);
805 if (rtac_adm_apr_data.apr_handle == NULL) {
806 pr_err("%s: APR not initialized\n", __func__);
807 result = -EINVAL;
808 goto err;
809 }
810
811 if (opcode == ADM_CMD_SET_PP_PARAMS_V5) {
812 /* set payload size to in-band payload */
813 /* set data size to actual out of band payload size */
814 data_size = payload_size - 4 * sizeof(u32);
815 if (data_size > rtac_cal[ADM_RTAC_CAL].map_data.map_size) {
816 pr_err("%s: Invalid data size = %d\n",
817 __func__, data_size);
818 result = -EINVAL;
819 goto err;
820 }
821 payload_size = 4 * sizeof(u32);
822
823 /* Copy buffer to out-of-band payload */
824 if (copy_from_user((void *)
825 rtac_cal[ADM_RTAC_CAL].cal_data.kvaddr,
826 buf + 7 * sizeof(u32), data_size)) {
827 pr_err("%s: Could not copy payload from user buffer\n",
828 __func__);
829 result = -EINVAL;
830 goto err;
831 }
832 /* set payload size in packet */
833 rtac_adm_buffer[8] = data_size;
834 } else {
835 if (payload_size > MAX_PAYLOAD_SIZE) {
836 pr_err("%s: Invalid payload size = %d\n",
837 __func__, payload_size);
838 result = -EINVAL;
839 goto err;
840 }
841
842 /* Copy buffer to in-band payload */
843 if (copy_from_user(rtac_adm_buffer +
844 sizeof(adm_params)/sizeof(u32),
845 buf + 3 * sizeof(u32), payload_size)) {
846 pr_err("%s: Could not copy payload from user buffer\n",
847 __func__);
848 result = -EINVAL;
849 goto err;
850 }
851 }
852
853 /* Pack header */
854 adm_params.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
855 APR_HDR_LEN(20), APR_PKT_VER);
856 adm_params.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
857 payload_size);
858 adm_params.src_svc = APR_SVC_ADM;
859 adm_params.src_domain = APR_DOMAIN_APPS;
860 adm_params.src_port = copp_id;
861 adm_params.dest_svc = APR_SVC_ADM;
862 adm_params.dest_domain = APR_DOMAIN_ADSP;
863 adm_params.dest_port = copp_id;
864 adm_params.token = port_idx << 16 | copp_idx;
865 adm_params.opcode = opcode;
866
867 /* fill for out-of-band */
868 rtac_adm_buffer[5] =
869 lower_32_bits(rtac_cal[ADM_RTAC_CAL].cal_data.paddr);
870 rtac_adm_buffer[6] =
871 msm_audio_populate_upper_32_bits(
872 rtac_cal[ADM_RTAC_CAL].cal_data.paddr);
873 rtac_adm_buffer[7] = rtac_cal[ADM_RTAC_CAL].map_data.map_handle;
874
875 memcpy(rtac_adm_buffer, &adm_params, sizeof(adm_params));
876 atomic_set(&rtac_adm_apr_data.cmd_state, 1);
877
878 pr_debug("%s: Sending RTAC command ioctl 0x%x, paddr 0x%pK\n",
879 __func__, opcode,
880 &rtac_cal[ADM_RTAC_CAL].cal_data.paddr);
881
882 result = apr_send_pkt(rtac_adm_apr_data.apr_handle,
883 (uint32_t *)rtac_adm_buffer);
884 if (result < 0) {
885 pr_err("%s: Set params failed copp = %d\n", __func__, copp_id);
886 goto err;
887 }
888 /* Wait for the callback */
889 result = wait_event_timeout(rtac_adm_apr_data.cmd_wait,
890 (atomic_read(&rtac_adm_apr_data.cmd_state) == 0),
891 msecs_to_jiffies(TIMEOUT_MS));
892 if (!result) {
893 pr_err("%s: Set params timed out copp = %d\n", __func__,
894 copp_id);
895 goto err;
896 }
897 if (atomic_read(&rtac_common.apr_err_code)) {
898 pr_err("%s: DSP returned error code = [%s], opcode = 0x%x\n",
899 __func__, adsp_err_get_err_str(atomic_read(
900 &rtac_common.apr_err_code)),
901 opcode);
902 result = adsp_err_get_lnx_err_code(
903 atomic_read(
904 &rtac_common.apr_err_code));
905 goto err;
906 }
907
908 if (opcode == ADM_CMD_GET_PP_PARAMS_V5) {
909 bytes_returned = ((u32 *)rtac_cal[ADM_RTAC_CAL].cal_data.
910 kvaddr)[2] + 3 * sizeof(u32);
911
kunleiz9c429502017-09-18 16:10:19 +0800912 if (bytes_returned > rtac_cal[ADM_RTAC_CAL].
913 map_data.map_size) {
914 pr_err("%s: Invalid data size = %d\n",
915 __func__, bytes_returned);
916 result = -EINVAL;
917 goto err;
918 }
919
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530920 if (bytes_returned > user_buf_size) {
921 pr_err("%s: User buf not big enough, size = 0x%x, returned size = 0x%x\n",
922 __func__, user_buf_size, bytes_returned);
923 result = -EINVAL;
924 goto err;
925 }
926
927 if (copy_to_user(buf, (void *)
928 rtac_cal[ADM_RTAC_CAL].cal_data.kvaddr,
929 bytes_returned)) {
930 pr_err("%s: Could not copy buffer to user,size = %d\n",
931 __func__, bytes_returned);
932 result = -EINVAL;
933 goto err;
934 }
935 } else {
936 bytes_returned = data_size;
937 }
938 mutex_unlock(&rtac_adm_apr_mutex);
939done:
940 return bytes_returned;
941err:
942 mutex_unlock(&rtac_adm_apr_mutex);
943 return result;
944}
945
946
947/* ASM APR */
948void rtac_set_asm_handle(u32 session_id, void *handle)
949{
950 pr_debug("%s\n", __func__);
951
952 mutex_lock(&rtac_asm_apr_mutex);
953 rtac_asm_apr_data[session_id].apr_handle = handle;
954 mutex_unlock(&rtac_asm_apr_mutex);
955}
956
957bool rtac_make_asm_callback(u32 session_id, uint32_t *payload,
958 u32 payload_size)
959{
960 if (atomic_read(&rtac_asm_apr_data[session_id].cmd_state) != 1)
961 return false;
962
963 pr_debug("%s\n", __func__);
964 if (payload_size == sizeof(uint32_t))
965 atomic_set(&rtac_common.apr_err_code, payload[0]);
966 else if (payload_size == (2*sizeof(uint32_t)))
967 atomic_set(&rtac_common.apr_err_code, payload[1]);
968
969 atomic_set(&rtac_asm_apr_data[session_id].cmd_state, 0);
970 wake_up(&rtac_asm_apr_data[session_id].cmd_wait);
971 return true;
972}
973
974int send_rtac_asm_apr(void *buf, u32 opcode)
975{
976 s32 result;
977 u32 user_buf_size = 0;
978 u32 bytes_returned = 0;
979 u32 session_id = 0;
980 u32 payload_size;
981 u32 data_size = 0;
982 struct apr_hdr asm_params;
983
984 pr_debug("%s\n", __func__);
985
986 if (rtac_cal[ASM_RTAC_CAL].map_data.ion_handle == NULL) {
987 result = rtac_allocate_cal_buffer(ASM_RTAC_CAL);
988 if (result < 0) {
989 pr_err("%s: allocate buffer failed!",
990 __func__);
991 goto done;
992 }
993 }
994
995 if (rtac_cal[ASM_RTAC_CAL].map_data.map_handle == 0) {
996 result = rtac_map_cal_buffer(ASM_RTAC_CAL);
997 if (result < 0) {
998 pr_err("%s: map buffer failed!",
999 __func__);
1000 goto done;
1001 }
1002 }
1003
1004 if (copy_from_user(&user_buf_size, (void *)buf,
1005 sizeof(user_buf_size))) {
1006 pr_err("%s: Copy from user failed! buf = 0x%pK\n",
1007 __func__, buf);
1008 goto done;
1009 }
1010 if (user_buf_size <= 0) {
1011 pr_err("%s: Invalid buffer size = %d\n",
1012 __func__, user_buf_size);
1013 goto done;
1014 }
1015
1016 if (copy_from_user(&payload_size, buf + sizeof(u32), sizeof(u32))) {
1017 pr_err("%s: Could not copy payload size from user buffer\n",
1018 __func__);
1019 goto done;
1020 }
1021
1022 if (copy_from_user(&session_id, buf + 2 * sizeof(u32), sizeof(u32))) {
1023 pr_err("%s: Could not copy session id from user buffer\n",
1024 __func__);
1025 goto done;
1026 }
1027 if (session_id >= (ASM_ACTIVE_STREAMS_ALLOWED + 1)) {
1028 pr_err("%s: Invalid Session = %d\n", __func__, session_id);
1029 goto done;
1030 }
1031
1032 mutex_lock(&rtac_asm_apr_mutex);
1033 if (rtac_asm_apr_data[session_id].apr_handle == NULL) {
1034 pr_err("%s: APR not initialized\n", __func__);
1035 result = -EINVAL;
1036 goto err;
1037 }
1038
1039 if (opcode == ASM_STREAM_CMD_SET_PP_PARAMS_V2) {
1040 /* set payload size to in-band payload */
1041 /* set data size to actual out of band payload size */
1042 data_size = payload_size - 4 * sizeof(u32);
1043 if (data_size > rtac_cal[ASM_RTAC_CAL].map_data.map_size) {
1044 pr_err("%s: Invalid data size = %d\n",
1045 __func__, data_size);
1046 result = -EINVAL;
1047 goto err;
1048 }
1049 payload_size = 4 * sizeof(u32);
1050
1051 /* Copy buffer to out-of-band payload */
1052 if (copy_from_user((void *)
1053 rtac_cal[ASM_RTAC_CAL].cal_data.kvaddr,
1054 buf + 7 * sizeof(u32), data_size)) {
1055 pr_err("%s: Could not copy payload from user buffer\n",
1056 __func__);
1057 result = -EINVAL;
1058 goto err;
1059 }
1060 /* set payload size in packet */
1061 rtac_asm_buffer[8] = data_size;
1062
1063 } else {
1064 if (payload_size > MAX_PAYLOAD_SIZE) {
1065 pr_err("%s: Invalid payload size = %d\n",
1066 __func__, payload_size);
1067 result = -EINVAL;
1068 goto err;
1069 }
1070
1071 /* Copy buffer to in-band payload */
1072 if (copy_from_user(rtac_asm_buffer +
1073 sizeof(asm_params)/sizeof(u32),
1074 buf + 3 * sizeof(u32), payload_size)) {
1075 pr_err("%s: Could not copy payload from user buffer\n",
1076 __func__);
1077 result = -EINVAL;
1078 goto err;
1079 }
1080 }
1081
1082 /* Pack header */
1083 asm_params.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1084 APR_HDR_LEN(20), APR_PKT_VER);
1085 asm_params.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1086 payload_size);
1087 asm_params.src_svc = q6asm_get_apr_service_id(session_id);
1088 asm_params.src_domain = APR_DOMAIN_APPS;
1089 asm_params.src_port = (session_id << 8) | 0x0001;
1090 asm_params.dest_svc = APR_SVC_ASM;
1091 asm_params.dest_domain = APR_DOMAIN_ADSP;
1092 asm_params.dest_port = (session_id << 8) | 0x0001;
1093 asm_params.token = session_id;
1094 asm_params.opcode = opcode;
1095
1096 /* fill for out-of-band */
1097 rtac_asm_buffer[5] =
1098 lower_32_bits(rtac_cal[ASM_RTAC_CAL].cal_data.paddr);
1099 rtac_asm_buffer[6] =
1100 msm_audio_populate_upper_32_bits(
1101 rtac_cal[ASM_RTAC_CAL].cal_data.paddr);
1102 rtac_asm_buffer[7] = rtac_cal[ASM_RTAC_CAL].map_data.map_handle;
1103
1104 memcpy(rtac_asm_buffer, &asm_params, sizeof(asm_params));
1105 atomic_set(&rtac_asm_apr_data[session_id].cmd_state, 1);
1106
1107 pr_debug("%s: Sending RTAC command ioctl 0x%x, paddr 0x%pK\n",
1108 __func__, opcode,
1109 &rtac_cal[ASM_RTAC_CAL].cal_data.paddr);
1110
1111 result = apr_send_pkt(rtac_asm_apr_data[session_id].apr_handle,
1112 (uint32_t *)rtac_asm_buffer);
1113 if (result < 0) {
1114 pr_err("%s: Set params failed session = %d\n",
1115 __func__, session_id);
1116 goto err;
1117 }
1118
1119 /* Wait for the callback */
1120 result = wait_event_timeout(rtac_asm_apr_data[session_id].cmd_wait,
1121 (atomic_read(&rtac_asm_apr_data[session_id].cmd_state) == 0),
1122 5 * HZ);
1123 if (!result) {
1124 pr_err("%s: Set params timed out session = %d\n",
1125 __func__, session_id);
1126 goto err;
1127 }
1128 if (atomic_read(&rtac_common.apr_err_code)) {
1129 pr_err("%s: DSP returned error code = [%s], opcode = 0x%x\n",
1130 __func__, adsp_err_get_err_str(atomic_read(
1131 &rtac_common.apr_err_code)),
1132 opcode);
1133 result = adsp_err_get_lnx_err_code(
1134 atomic_read(
1135 &rtac_common.apr_err_code));
1136 goto err;
1137 }
1138
1139 if (opcode == ASM_STREAM_CMD_GET_PP_PARAMS_V2) {
1140 bytes_returned = ((u32 *)rtac_cal[ASM_RTAC_CAL].cal_data.
1141 kvaddr)[2] + 3 * sizeof(u32);
1142
kunleiz9c429502017-09-18 16:10:19 +08001143 if (bytes_returned > rtac_cal[ASM_RTAC_CAL].
1144 map_data.map_size) {
1145 pr_err("%s: Invalid data size = %d\n",
1146 __func__, bytes_returned);
1147 result = -EINVAL;
1148 goto err;
1149 }
1150
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301151 if (bytes_returned > user_buf_size) {
1152 pr_err("%s: User buf not big enough, size = 0x%x, returned size = 0x%x\n",
1153 __func__, user_buf_size, bytes_returned);
1154 result = -EINVAL;
1155 goto err;
1156 }
1157
1158 if (copy_to_user(buf, (void *)
1159 rtac_cal[ASM_RTAC_CAL].cal_data.kvaddr,
1160 bytes_returned)) {
1161 pr_err("%s: Could not copy buffer to user,size = %d\n",
1162 __func__, bytes_returned);
1163 result = -EINVAL;
1164 goto err;
1165 }
1166 } else {
1167 bytes_returned = data_size;
1168 }
1169 mutex_unlock(&rtac_asm_apr_mutex);
1170done:
1171 return bytes_returned;
1172err:
1173 mutex_unlock(&rtac_asm_apr_mutex);
1174 return result;
1175}
1176
1177/* AFE APR */
1178void rtac_set_afe_handle(void *handle)
1179{
1180 mutex_lock(&rtac_afe_apr_mutex);
1181 rtac_afe_apr_data.apr_handle = handle;
1182 mutex_unlock(&rtac_afe_apr_mutex);
1183}
1184
1185bool rtac_make_afe_callback(uint32_t *payload, uint32_t payload_size)
1186{
1187 pr_debug("%s:cmd_state = %d\n", __func__,
1188 atomic_read(&rtac_afe_apr_data.cmd_state));
1189 if (atomic_read(&rtac_afe_apr_data.cmd_state) != 1)
1190 return false;
1191
1192 if (payload_size == sizeof(uint32_t))
1193 atomic_set(&rtac_common.apr_err_code, payload[0]);
1194 else if (payload_size == (2*sizeof(uint32_t)))
1195 atomic_set(&rtac_common.apr_err_code, payload[1]);
1196
1197 atomic_set(&rtac_afe_apr_data.cmd_state, 0);
1198 wake_up(&rtac_afe_apr_data.cmd_wait);
1199 return true;
1200}
1201
1202static int fill_afe_apr_hdr(struct apr_hdr *apr_hdr, uint32_t port,
1203 uint32_t opcode, uint32_t apr_msg_size)
1204{
1205 if (apr_hdr == NULL) {
1206 pr_err("%s: invalid APR pointer", __func__);
1207 return -EINVAL;
1208 }
1209
1210 apr_hdr->hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1211 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1212 apr_hdr->pkt_size = apr_msg_size;
1213 apr_hdr->src_svc = APR_SVC_AFE;
1214 apr_hdr->src_domain = APR_DOMAIN_APPS;
1215 apr_hdr->src_port = 0;
1216 apr_hdr->dest_svc = APR_SVC_AFE;
1217 apr_hdr->dest_domain = APR_DOMAIN_ADSP;
1218 apr_hdr->dest_port = 0;
1219 apr_hdr->token = port;
1220 apr_hdr->opcode = opcode;
1221
1222 return 0;
1223
1224}
1225static int send_rtac_afe_apr(void *buf, uint32_t opcode)
1226{
1227 int32_t result;
1228 uint32_t bytes_returned = 0;
1229 uint32_t port_index = 0;
1230 uint32_t apr_msg_size = 0;
1231 struct rtac_afe_user_data user_afe_buf;
1232
1233 pr_debug("%s\n", __func__);
1234
1235 if (rtac_cal[AFE_RTAC_CAL].map_data.ion_handle == NULL) {
1236 result = rtac_allocate_cal_buffer(AFE_RTAC_CAL);
1237 if (result < 0) {
1238 pr_err("%s: allocate buffer failed! ret = %d\n",
1239 __func__, result);
1240 goto done;
1241 }
1242 }
1243
1244 if (rtac_cal[AFE_RTAC_CAL].map_data.map_handle == 0) {
1245 result = rtac_map_cal_buffer(AFE_RTAC_CAL);
1246 if (result < 0) {
1247 pr_err("%s: map buffer failed! ret = %d\n",
1248 __func__, result);
1249 goto done;
1250 }
1251 }
1252
1253 if (copy_from_user(&user_afe_buf, (void *)buf,
1254 sizeof(struct rtac_afe_user_data))) {
1255 pr_err("%s: Copy from user failed! buf = 0x%pK\n",
1256 __func__, buf);
1257 goto done;
1258 }
1259
1260 if (user_afe_buf.buf_size <= 0) {
1261 pr_err("%s: Invalid buffer size = %d\n",
1262 __func__, user_afe_buf.buf_size);
1263 goto done;
1264 }
1265
1266 port_index = q6audio_get_port_index(user_afe_buf.port_id);
1267 if (port_index >= AFE_MAX_PORTS) {
1268 pr_err("%s: Invalid AFE port = 0x%x\n",
1269 __func__, user_afe_buf.port_id);
1270 goto done;
1271 }
1272
1273 mutex_lock(&rtac_afe_apr_mutex);
1274 if (rtac_afe_apr_data.apr_handle == NULL) {
1275 pr_err("%s: APR not initialized\n", __func__);
1276 result = -EINVAL;
1277 goto err;
1278 }
1279 if (opcode == AFE_PORT_CMD_SET_PARAM_V2) {
1280 struct afe_port_cmd_set_param_v2 *afe_set_apr_msg;
1281
1282 /* set data size to actual out of band payload size */
1283 if (user_afe_buf.rtac_afe_set.cmd.payload_size >
1284 rtac_cal[AFE_RTAC_CAL].map_data.map_size) {
1285 pr_err("%s: Invalid data size = %d\n",
1286 __func__,
1287 user_afe_buf.rtac_afe_set.cmd.payload_size);
1288 result = -EINVAL;
1289 goto err;
1290 }
1291
1292 /* Copy buffer to out-of-band payload */
1293 if (copy_from_user((void *)
1294 rtac_cal[AFE_RTAC_CAL].cal_data.kvaddr,
1295 buf+offsetof(struct rtac_afe_user_data,
1296 rtac_afe_set.data),
1297 user_afe_buf.rtac_afe_set.cmd.payload_size)) {
1298 pr_err("%s: Could not copy payload from user buffer\n",
1299 __func__);
1300 result = -EINVAL;
1301 goto err;
1302 }
1303
1304 /* Copy AFE APR Message */
1305 afe_set_apr_msg = (struct afe_port_cmd_set_param_v2 *)
1306 ((u8 *)rtac_afe_buffer +
1307 sizeof(struct apr_hdr));
1308 if (copy_from_user((void *)
1309 afe_set_apr_msg,
1310 buf + offsetof(struct rtac_afe_user_data,
1311 rtac_afe_set.cmd),
1312 sizeof(struct afe_port_cmd_set_param_v2))) {
1313 pr_err("%s: Could not copy payload from user buffer\n",
1314 __func__);
1315 result = -EINVAL;
1316 goto err;
1317 }
1318
1319 afe_set_apr_msg->payload_address_lsw =
1320 lower_32_bits(rtac_cal[AFE_RTAC_CAL].cal_data.paddr);
1321 afe_set_apr_msg->payload_address_msw =
1322 msm_audio_populate_upper_32_bits(
1323 rtac_cal[AFE_RTAC_CAL].cal_data.paddr);
1324 afe_set_apr_msg->mem_map_handle =
1325 rtac_cal[AFE_RTAC_CAL].map_data.map_handle;
1326
1327 apr_msg_size = sizeof(struct apr_hdr) +
1328 sizeof(struct afe_port_cmd_set_param_v2);
1329
1330 } else {
1331 struct afe_port_cmd_get_param_v2 *afe_get_apr_msg;
1332
1333 if (user_afe_buf.cmd_size > MAX_PAYLOAD_SIZE) {
1334 pr_err("%s: Invalid payload size = %d\n",
1335 __func__, user_afe_buf.cmd_size);
1336 result = -EINVAL;
1337 goto err;
1338 }
1339
1340 /* Copy buffer to in-band payload */
1341 afe_get_apr_msg = (struct afe_port_cmd_get_param_v2 *)
1342 ((u8 *) rtac_afe_buffer +
1343 sizeof(struct apr_hdr));
1344 if (copy_from_user((void *)afe_get_apr_msg,
1345 buf+offsetof(struct rtac_afe_user_data,
1346 rtac_afe_get.cmd),
1347 sizeof(struct afe_port_cmd_get_param_v2))) {
1348 pr_err("%s: Could not copy payload from user buffer\n",
1349 __func__);
1350 result = -EINVAL;
1351 goto err;
1352 }
1353
1354 afe_get_apr_msg->payload_address_lsw =
1355 lower_32_bits(rtac_cal[AFE_RTAC_CAL].cal_data.paddr);
1356 afe_get_apr_msg->payload_address_msw =
1357 msm_audio_populate_upper_32_bits(
1358 rtac_cal[AFE_RTAC_CAL].cal_data.paddr);
1359 afe_get_apr_msg->mem_map_handle =
1360 rtac_cal[AFE_RTAC_CAL].map_data.map_handle;
1361 afe_get_apr_msg->payload_size -= sizeof(struct apr_hdr);
1362 apr_msg_size = sizeof(struct apr_hdr) +
1363 sizeof(struct afe_port_cmd_get_param_v2);
1364 }
1365
1366 fill_afe_apr_hdr((struct apr_hdr *) rtac_afe_buffer,
1367 port_index, opcode, apr_msg_size);
1368
1369 atomic_set(&rtac_afe_apr_data.cmd_state, 1);
1370
1371 pr_debug("%s: Sending RTAC command ioctl 0x%x, paddr 0x%pK\n",
1372 __func__, opcode,
1373 &rtac_cal[AFE_RTAC_CAL].cal_data.paddr);
1374
1375 result = apr_send_pkt(rtac_afe_apr_data.apr_handle,
1376 (uint32_t *)rtac_afe_buffer);
1377 if (result < 0) {
1378 pr_err("%s: Set params failed port = 0x%x, ret = %d\n",
1379 __func__, user_afe_buf.port_id, result);
1380 goto err;
1381 }
1382 /* Wait for the callback */
1383 result = wait_event_timeout(rtac_afe_apr_data.cmd_wait,
1384 (atomic_read(&rtac_afe_apr_data.cmd_state) == 0),
1385 msecs_to_jiffies(TIMEOUT_MS));
1386 if (!result) {
1387 pr_err("%s: Set params timed out port = 0x%x, ret = %d\n",
1388 __func__, user_afe_buf.port_id, result);
1389 goto err;
1390 }
1391 if (atomic_read(&rtac_common.apr_err_code)) {
1392 pr_err("%s: DSP returned error code = [%s], opcode = 0x%x\n",
1393 __func__, adsp_err_get_err_str(atomic_read(
1394 &rtac_common.apr_err_code)),
1395 opcode);
1396 result = adsp_err_get_lnx_err_code(
1397 atomic_read(
1398 &rtac_common.apr_err_code));
1399 goto err;
1400 }
1401
1402 if (opcode == AFE_PORT_CMD_GET_PARAM_V2) {
1403 struct afe_port_param_data_v2 *get_resp;
1404
1405 get_resp = (struct afe_port_param_data_v2 *)
1406 rtac_cal[AFE_RTAC_CAL].cal_data.kvaddr;
1407
1408 bytes_returned = get_resp->param_size +
1409 sizeof(struct afe_port_param_data_v2);
1410
kunleiz9c429502017-09-18 16:10:19 +08001411 if (bytes_returned > rtac_cal[AFE_RTAC_CAL].
1412 map_data.map_size) {
1413 pr_err("%s: Invalid data size = %d\n",
1414 __func__, bytes_returned);
1415 result = -EINVAL;
1416 goto err;
1417 }
1418
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301419 if (bytes_returned > user_afe_buf.buf_size) {
1420 pr_err("%s: user size = 0x%x, returned size = 0x%x\n",
1421 __func__, user_afe_buf.buf_size,
1422 bytes_returned);
1423 result = -EINVAL;
1424 goto err;
1425 }
1426
1427 if (copy_to_user(buf, (void *)
1428 rtac_cal[AFE_RTAC_CAL].cal_data.kvaddr,
1429 bytes_returned)) {
1430 pr_err("%s: Could not copy buffer to user,size = %d\n",
1431 __func__, bytes_returned);
1432 result = -EINVAL;
1433 goto err;
1434 }
1435 } else {
1436 bytes_returned = user_afe_buf.rtac_afe_set.cmd.payload_size;
1437 }
1438 mutex_unlock(&rtac_afe_apr_mutex);
1439done:
1440 return bytes_returned;
1441err:
1442 mutex_unlock(&rtac_afe_apr_mutex);
1443 return result;
1444}
1445
1446/* Voice APR */
1447void rtac_set_voice_handle(u32 mode, void *handle)
1448{
1449 pr_debug("%s\n", __func__);
1450
1451 mutex_lock(&rtac_voice_apr_mutex);
1452 rtac_voice_apr_data[mode].apr_handle = handle;
1453 mutex_unlock(&rtac_voice_apr_mutex);
1454}
1455
1456bool rtac_make_voice_callback(u32 mode, uint32_t *payload, u32 payload_size)
1457{
1458 if ((atomic_read(&rtac_voice_apr_data[mode].cmd_state) != 1) ||
1459 (mode >= RTAC_VOICE_MODES))
1460 return false;
1461
1462 pr_debug("%s\n", __func__);
1463 if (payload_size == sizeof(uint32_t))
1464 atomic_set(&rtac_common.apr_err_code, payload[0]);
1465 else if (payload_size == (2*sizeof(uint32_t)))
1466 atomic_set(&rtac_common.apr_err_code, payload[1]);
1467
1468 atomic_set(&rtac_voice_apr_data[mode].cmd_state, 0);
1469 wake_up(&rtac_voice_apr_data[mode].cmd_wait);
1470 return true;
1471}
1472
1473int send_voice_apr(u32 mode, void *buf, u32 opcode)
1474{
1475 s32 result;
1476 u32 user_buf_size = 0;
1477 u32 bytes_returned = 0;
1478 u32 payload_size;
1479 u32 dest_port;
1480 u32 data_size = 0;
1481 struct apr_hdr voice_params;
1482
1483 pr_debug("%s\n", __func__);
1484
1485 if (rtac_cal[VOICE_RTAC_CAL].map_data.ion_handle == NULL) {
1486 result = rtac_allocate_cal_buffer(VOICE_RTAC_CAL);
1487 if (result < 0) {
1488 pr_err("%s: allocate buffer failed!",
1489 __func__);
1490 goto done;
1491 }
1492 }
1493
1494 if (rtac_cal[VOICE_RTAC_CAL].map_data.map_handle == 0) {
1495 result = rtac_map_cal_buffer(VOICE_RTAC_CAL);
1496 if (result < 0) {
1497 pr_err("%s: map buffer failed!",
1498 __func__);
1499 goto done;
1500 }
1501 }
1502
1503 if (copy_from_user(&user_buf_size, (void *)buf,
1504 sizeof(user_buf_size))) {
1505 pr_err("%s: Copy from user failed! buf = 0x%pK\n",
1506 __func__, buf);
1507 goto done;
1508 }
1509 if (user_buf_size <= 0) {
1510 pr_err("%s: Invalid buffer size = %d\n",
1511 __func__, user_buf_size);
1512 goto done;
1513 }
1514
1515 if (copy_from_user(&payload_size, buf + sizeof(u32), sizeof(u32))) {
1516 pr_err("%s: Could not copy payload size from user buffer\n",
1517 __func__);
1518 goto done;
1519 }
1520
1521 if (copy_from_user(&dest_port, buf + 2 * sizeof(u32), sizeof(u32))) {
1522 pr_err("%s: Could not copy port id from user buffer\n",
1523 __func__);
1524 goto done;
1525 }
1526
1527 if ((mode != RTAC_CVP) && (mode != RTAC_CVS)) {
1528 pr_err("%s: Invalid Mode for APR, mode = %d\n",
1529 __func__, mode);
1530 goto done;
1531 }
1532
1533 mutex_lock(&rtac_voice_apr_mutex);
1534 if (rtac_voice_apr_data[mode].apr_handle == NULL) {
1535 pr_err("%s: APR not initialized\n", __func__);
1536 result = -EINVAL;
1537 goto err;
1538 }
1539
1540 if (opcode == VSS_ICOMMON_CMD_SET_PARAM_V2) {
1541 /* set payload size to in-band payload */
1542 /* set data size to actual out of band payload size */
1543 data_size = payload_size - 4 * sizeof(u32);
1544 if (data_size > rtac_cal[VOICE_RTAC_CAL].map_data.map_size) {
1545 pr_err("%s: Invalid data size = %d\n",
1546 __func__, data_size);
1547 result = -EINVAL;
1548 goto err;
1549 }
1550 payload_size = 4 * sizeof(u32);
1551
1552 /* Copy buffer to out-of-band payload */
1553 if (copy_from_user((void *)
1554 rtac_cal[VOICE_RTAC_CAL].cal_data.kvaddr,
1555 buf + 7 * sizeof(u32), data_size)) {
1556 pr_err("%s: Could not copy payload from user buffer\n",
1557 __func__);
1558 result = -EINVAL;
1559 goto err;
1560 }
1561 /* set payload size in packet */
1562 rtac_voice_buffer[8] = data_size;
1563 } else {
1564 if (payload_size > MAX_PAYLOAD_SIZE) {
1565 pr_err("%s: Invalid payload size = %d\n",
1566 __func__, payload_size);
1567 result = -EINVAL;
1568 goto err;
1569 }
1570
1571 /* Copy buffer to in-band payload */
1572 if (copy_from_user(rtac_voice_buffer +
1573 sizeof(voice_params)/sizeof(u32),
1574 buf + 3 * sizeof(u32), payload_size)) {
1575 pr_err("%s: Could not copy payload from user buffer\n",
1576 __func__);
1577 result = -EINVAL;
1578 goto err;
1579 }
1580 }
1581
1582 /* Pack header */
1583 voice_params.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1584 APR_HDR_LEN(20), APR_PKT_VER);
1585 voice_params.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1586 payload_size);
1587 voice_params.src_svc = 0;
1588 voice_params.src_domain = APR_DOMAIN_APPS;
1589 voice_params.src_port = get_voice_index(mode, dest_port);
1590 voice_params.dest_svc = 0;
1591 voice_params.dest_domain = APR_DOMAIN_MODEM;
1592 voice_params.dest_port = (u16)dest_port;
1593 voice_params.token = (opcode == VSS_ICOMMON_CMD_SET_PARAM_V2) ?
1594 VOC_RTAC_SET_PARAM_TOKEN :
1595 0;
1596 voice_params.opcode = opcode;
1597
1598 /* fill for out-of-band */
1599 rtac_voice_buffer[5] = rtac_cal[VOICE_RTAC_CAL].map_data.map_handle;
1600 rtac_voice_buffer[6] =
1601 lower_32_bits(rtac_cal[VOICE_RTAC_CAL].cal_data.paddr);
1602 rtac_voice_buffer[7] =
1603 msm_audio_populate_upper_32_bits(
1604 rtac_cal[VOICE_RTAC_CAL].cal_data.paddr);
1605
1606 memcpy(rtac_voice_buffer, &voice_params, sizeof(voice_params));
1607 atomic_set(&rtac_voice_apr_data[mode].cmd_state, 1);
1608
1609 pr_debug("%s: Sending RTAC command ioctl 0x%x, paddr 0x%pK\n",
1610 __func__, opcode,
1611 &rtac_cal[VOICE_RTAC_CAL].cal_data.paddr);
1612
1613 result = apr_send_pkt(rtac_voice_apr_data[mode].apr_handle,
1614 (uint32_t *)rtac_voice_buffer);
1615 if (result < 0) {
1616 pr_err("%s: apr_send_pkt failed opcode = %x\n",
1617 __func__, opcode);
1618 goto err;
1619 }
1620 /* Wait for the callback */
1621 result = wait_event_timeout(rtac_voice_apr_data[mode].cmd_wait,
1622 (atomic_read(&rtac_voice_apr_data[mode].cmd_state) == 0),
1623 msecs_to_jiffies(TIMEOUT_MS));
1624 if (!result) {
1625 pr_err("%s: apr_send_pkt timed out opcode = %x\n",
1626 __func__, opcode);
1627 goto err;
1628 }
1629 if (atomic_read(&rtac_common.apr_err_code)) {
1630 pr_err("%s: DSP returned error code = [%s], opcode = 0x%x\n",
1631 __func__, adsp_err_get_err_str(atomic_read(
1632 &rtac_common.apr_err_code)),
1633 opcode);
1634 result = adsp_err_get_lnx_err_code(
1635 atomic_read(
1636 &rtac_common.apr_err_code));
1637 goto err;
1638 }
1639
1640 if (opcode == VSS_ICOMMON_CMD_GET_PARAM_V2) {
1641 bytes_returned = ((u32 *)rtac_cal[VOICE_RTAC_CAL].cal_data.
1642 kvaddr)[2] + 3 * sizeof(u32);
1643
kunleiz9c429502017-09-18 16:10:19 +08001644 if (bytes_returned > rtac_cal[VOICE_RTAC_CAL].
1645 map_data.map_size) {
1646 pr_err("%s: Invalid data size = %d\n",
1647 __func__, bytes_returned);
1648 result = -EINVAL;
1649 goto err;
1650 }
1651
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301652 if (bytes_returned > user_buf_size) {
1653 pr_err("%s: User buf not big enough, size = 0x%x, returned size = 0x%x\n",
1654 __func__, user_buf_size, bytes_returned);
1655 result = -EINVAL;
1656 goto err;
1657 }
1658
1659 if (copy_to_user(buf, (void *)
1660 rtac_cal[VOICE_RTAC_CAL].cal_data.kvaddr,
1661 bytes_returned)) {
1662 pr_err("%s: Could not copy buffer to user, size = %d\n",
1663 __func__, bytes_returned);
1664 result = -EINVAL;
1665 goto err;
1666 }
1667 } else {
1668 bytes_returned = data_size;
1669 }
1670 mutex_unlock(&rtac_voice_apr_mutex);
1671done:
1672 return bytes_returned;
1673err:
1674 mutex_unlock(&rtac_voice_apr_mutex);
1675 return result;
1676}
1677
1678void get_rtac_adm_data(struct rtac_adm *adm_data)
1679{
1680 mutex_lock(&rtac_adm_mutex);
1681 memcpy(adm_data, &rtac_adm_data, sizeof(struct rtac_adm));
1682 mutex_unlock(&rtac_adm_mutex);
1683}
1684
1685
1686static long rtac_ioctl_shared(struct file *f,
1687 unsigned int cmd, void *arg)
1688{
1689 int result = 0;
1690
1691 if (!arg) {
1692 pr_err("%s: No data sent to driver!\n", __func__);
1693 result = -EFAULT;
1694 goto done;
1695 }
1696
1697 switch (cmd) {
1698 case AUDIO_GET_RTAC_ADM_INFO: {
1699 mutex_lock(&rtac_adm_mutex);
1700 if (copy_to_user((void *)arg, &rtac_adm_data,
1701 sizeof(rtac_adm_data))) {
1702 pr_err("%s: copy_to_user failed for AUDIO_GET_RTAC_ADM_INFO\n",
1703 __func__);
1704 mutex_unlock(&rtac_adm_mutex);
1705 return -EFAULT;
1706 }
1707 result = sizeof(rtac_adm_data);
1708 mutex_unlock(&rtac_adm_mutex);
1709 break;
1710 }
1711 case AUDIO_GET_RTAC_VOICE_INFO: {
1712 mutex_lock(&rtac_voice_mutex);
1713 if (copy_to_user((void *)arg, &rtac_voice_data,
1714 sizeof(rtac_voice_data))) {
1715 pr_err("%s: copy_to_user failed for AUDIO_GET_RTAC_VOICE_INFO\n",
1716 __func__);
1717 mutex_unlock(&rtac_voice_mutex);
1718 return -EFAULT;
1719 }
1720 result = sizeof(rtac_voice_data);
1721 mutex_unlock(&rtac_voice_mutex);
1722 break;
1723 }
1724
1725 case AUDIO_GET_RTAC_ADM_CAL:
1726 result = send_adm_apr((void *)arg, ADM_CMD_GET_PP_PARAMS_V5);
1727 break;
1728 case AUDIO_SET_RTAC_ADM_CAL:
1729 result = send_adm_apr((void *)arg, ADM_CMD_SET_PP_PARAMS_V5);
1730 break;
1731 case AUDIO_GET_RTAC_ASM_CAL:
1732 result = send_rtac_asm_apr((void *)arg,
1733 ASM_STREAM_CMD_GET_PP_PARAMS_V2);
1734 break;
1735 case AUDIO_SET_RTAC_ASM_CAL:
1736 result = send_rtac_asm_apr((void *)arg,
1737 ASM_STREAM_CMD_SET_PP_PARAMS_V2);
1738 break;
1739 case AUDIO_GET_RTAC_CVS_CAL:
1740 result = send_voice_apr(RTAC_CVS, (void *) arg,
1741 VSS_ICOMMON_CMD_GET_PARAM_V2);
1742 break;
1743 case AUDIO_SET_RTAC_CVS_CAL:
1744 result = send_voice_apr(RTAC_CVS, (void *) arg,
1745 VSS_ICOMMON_CMD_SET_PARAM_V2);
1746 break;
1747 case AUDIO_GET_RTAC_CVP_CAL:
1748 result = send_voice_apr(RTAC_CVP, (void *) arg,
1749 VSS_ICOMMON_CMD_GET_PARAM_V2);
1750 break;
1751 case AUDIO_SET_RTAC_CVP_CAL:
1752 result = send_voice_apr(RTAC_CVP, (void *) arg,
1753 VSS_ICOMMON_CMD_SET_PARAM_V2);
1754 break;
1755 case AUDIO_GET_RTAC_AFE_CAL:
1756 result = send_rtac_afe_apr((void *)arg,
1757 AFE_PORT_CMD_GET_PARAM_V2);
1758 break;
1759 case AUDIO_SET_RTAC_AFE_CAL:
1760 result = send_rtac_afe_apr((void *)arg,
1761 AFE_PORT_CMD_SET_PARAM_V2);
1762 break;
1763 default:
1764 pr_err("%s: Invalid IOCTL, command = %d!\n",
1765 __func__, cmd);
1766 result = -EINVAL;
1767 }
1768done:
1769 return result;
1770}
1771
1772static long rtac_ioctl(struct file *f,
1773 unsigned int cmd, unsigned long arg)
1774{
1775 int result = 0;
1776
1777 if (!arg) {
1778 pr_err("%s: No data sent to driver!\n", __func__);
1779 result = -EFAULT;
1780 } else {
1781 result = rtac_ioctl_shared(f, cmd, (void __user *)arg);
1782 }
1783
1784 return result;
1785}
1786
1787#ifdef CONFIG_COMPAT
1788#define AUDIO_GET_RTAC_ADM_INFO_32 _IOR(CAL_IOCTL_MAGIC, 207, compat_uptr_t)
1789#define AUDIO_GET_RTAC_VOICE_INFO_32 _IOR(CAL_IOCTL_MAGIC, 208, compat_uptr_t)
1790#define AUDIO_GET_RTAC_ADM_CAL_32 _IOWR(CAL_IOCTL_MAGIC, 209, compat_uptr_t)
1791#define AUDIO_SET_RTAC_ADM_CAL_32 _IOWR(CAL_IOCTL_MAGIC, 210, compat_uptr_t)
1792#define AUDIO_GET_RTAC_ASM_CAL_32 _IOWR(CAL_IOCTL_MAGIC, 211, compat_uptr_t)
1793#define AUDIO_SET_RTAC_ASM_CAL_32 _IOWR(CAL_IOCTL_MAGIC, 212, compat_uptr_t)
1794#define AUDIO_GET_RTAC_CVS_CAL_32 _IOWR(CAL_IOCTL_MAGIC, 213, compat_uptr_t)
1795#define AUDIO_SET_RTAC_CVS_CAL_32 _IOWR(CAL_IOCTL_MAGIC, 214, compat_uptr_t)
1796#define AUDIO_GET_RTAC_CVP_CAL_32 _IOWR(CAL_IOCTL_MAGIC, 215, compat_uptr_t)
1797#define AUDIO_SET_RTAC_CVP_CAL_32 _IOWR(CAL_IOCTL_MAGIC, 216, compat_uptr_t)
1798#define AUDIO_GET_RTAC_AFE_CAL_32 _IOWR(CAL_IOCTL_MAGIC, 217, compat_uptr_t)
1799#define AUDIO_SET_RTAC_AFE_CAL_32 _IOWR(CAL_IOCTL_MAGIC, 218, compat_uptr_t)
1800
1801static long rtac_compat_ioctl(struct file *f,
1802 unsigned int cmd, unsigned long arg)
1803{
1804 int result = 0;
1805
1806 if (!arg) {
1807 pr_err("%s: No data sent to driver!\n", __func__);
1808 result = -EINVAL;
1809 goto done;
1810 }
1811
1812 switch (cmd) {
1813 case AUDIO_GET_RTAC_ADM_INFO_32:
1814 cmd = AUDIO_GET_RTAC_ADM_INFO;
1815 goto process;
1816 case AUDIO_GET_RTAC_VOICE_INFO_32:
1817 cmd = AUDIO_GET_RTAC_VOICE_INFO;
1818 goto process;
1819 case AUDIO_GET_RTAC_AFE_CAL_32:
1820 cmd = AUDIO_GET_RTAC_AFE_CAL;
1821 goto process;
1822 case AUDIO_SET_RTAC_AFE_CAL_32:
1823 cmd = AUDIO_SET_RTAC_AFE_CAL;
1824 goto process;
1825 case AUDIO_GET_RTAC_ADM_CAL_32:
1826 cmd = AUDIO_GET_RTAC_ADM_CAL;
1827 goto process;
1828 case AUDIO_SET_RTAC_ADM_CAL_32:
1829 cmd = AUDIO_SET_RTAC_ADM_CAL;
1830 goto process;
1831 case AUDIO_GET_RTAC_ASM_CAL_32:
1832 cmd = AUDIO_GET_RTAC_ASM_CAL;
1833 goto process;
1834 case AUDIO_SET_RTAC_ASM_CAL_32:
1835 cmd = AUDIO_SET_RTAC_ASM_CAL;
1836 goto process;
1837 case AUDIO_GET_RTAC_CVS_CAL_32:
1838 cmd = AUDIO_GET_RTAC_CVS_CAL;
1839 goto process;
1840 case AUDIO_SET_RTAC_CVS_CAL_32:
1841 cmd = AUDIO_SET_RTAC_CVS_CAL;
1842 goto process;
1843 case AUDIO_GET_RTAC_CVP_CAL_32:
1844 cmd = AUDIO_GET_RTAC_CVP_CAL;
1845 goto process;
1846 case AUDIO_SET_RTAC_CVP_CAL_32:
1847 cmd = AUDIO_SET_RTAC_CVP_CAL;
1848process:
1849 result = rtac_ioctl_shared(f, cmd, compat_ptr(arg));
1850 break;
1851 default:
1852 result = -EINVAL;
1853 pr_err("%s: Invalid IOCTL, command = %d!\n",
1854 __func__, cmd);
1855 break;
1856 }
1857done:
1858 return result;
1859}
1860#else
1861#define rtac_compat_ioctl NULL
1862#endif
1863
1864static const struct file_operations rtac_fops = {
1865 .owner = THIS_MODULE,
1866 .open = rtac_open,
1867 .release = rtac_release,
1868 .unlocked_ioctl = rtac_ioctl,
1869 .compat_ioctl = rtac_compat_ioctl,
1870};
1871
1872struct miscdevice rtac_misc = {
1873 .minor = MISC_DYNAMIC_MINOR,
1874 .name = "msm_rtac",
1875 .fops = &rtac_fops,
1876};
1877
1878static int __init rtac_init(void)
1879{
1880 int i = 0;
1881
1882 /* Driver */
1883 atomic_set(&rtac_common.usage_count, 0);
1884 atomic_set(&rtac_common.apr_err_code, 0);
1885
1886 /* ADM */
1887 memset(&rtac_adm_data, 0, sizeof(rtac_adm_data));
1888 rtac_adm_apr_data.apr_handle = NULL;
1889 atomic_set(&rtac_adm_apr_data.cmd_state, 0);
1890 init_waitqueue_head(&rtac_adm_apr_data.cmd_wait);
1891 mutex_init(&rtac_adm_mutex);
1892 mutex_init(&rtac_adm_apr_mutex);
1893
1894 rtac_adm_buffer = kzalloc(
1895 rtac_cal[ADM_RTAC_CAL].map_data.map_size, GFP_KERNEL);
1896 if (rtac_adm_buffer == NULL)
1897 goto nomem;
1898
1899 /* ASM */
1900 for (i = 0; i < ASM_ACTIVE_STREAMS_ALLOWED+1; i++) {
1901 rtac_asm_apr_data[i].apr_handle = NULL;
1902 atomic_set(&rtac_asm_apr_data[i].cmd_state, 0);
1903 init_waitqueue_head(&rtac_asm_apr_data[i].cmd_wait);
1904 }
1905 mutex_init(&rtac_asm_apr_mutex);
1906
1907 rtac_asm_buffer = kzalloc(
1908 rtac_cal[ASM_RTAC_CAL].map_data.map_size, GFP_KERNEL);
1909 if (rtac_asm_buffer == NULL) {
1910 kzfree(rtac_adm_buffer);
1911 goto nomem;
1912 }
1913
1914 /* AFE */
1915 rtac_afe_apr_data.apr_handle = NULL;
1916 atomic_set(&rtac_afe_apr_data.cmd_state, 0);
1917 init_waitqueue_head(&rtac_afe_apr_data.cmd_wait);
1918 mutex_init(&rtac_afe_apr_mutex);
1919
1920 rtac_afe_buffer = kzalloc(
1921 rtac_cal[AFE_RTAC_CAL].map_data.map_size, GFP_KERNEL);
1922 if (rtac_afe_buffer == NULL) {
1923 kzfree(rtac_adm_buffer);
1924 kzfree(rtac_asm_buffer);
1925 goto nomem;
1926 }
1927
1928 /* Voice */
1929 memset(&rtac_voice_data, 0, sizeof(rtac_voice_data));
1930 for (i = 0; i < RTAC_VOICE_MODES; i++) {
1931 rtac_voice_apr_data[i].apr_handle = NULL;
1932 atomic_set(&rtac_voice_apr_data[i].cmd_state, 0);
1933 init_waitqueue_head(&rtac_voice_apr_data[i].cmd_wait);
1934 }
1935 mutex_init(&rtac_voice_mutex);
1936 mutex_init(&rtac_voice_apr_mutex);
1937
1938 rtac_voice_buffer = kzalloc(
1939 rtac_cal[VOICE_RTAC_CAL].map_data.map_size, GFP_KERNEL);
1940 if (rtac_voice_buffer == NULL) {
1941 kzfree(rtac_adm_buffer);
1942 kzfree(rtac_asm_buffer);
1943 kzfree(rtac_afe_buffer);
1944 goto nomem;
1945 }
1946
1947 return misc_register(&rtac_misc);
1948nomem:
1949 return -ENOMEM;
1950}
1951
1952module_init(rtac_init);
1953
1954MODULE_DESCRIPTION("SoC QDSP6v2 Real-Time Audio Calibration driver");
1955MODULE_LICENSE("GPL v2");