blob: 456ac5773d64917162fd6d2628951b0e93dc9e1e [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
912 if (bytes_returned > user_buf_size) {
913 pr_err("%s: User buf not big enough, size = 0x%x, returned size = 0x%x\n",
914 __func__, user_buf_size, bytes_returned);
915 result = -EINVAL;
916 goto err;
917 }
918
919 if (copy_to_user(buf, (void *)
920 rtac_cal[ADM_RTAC_CAL].cal_data.kvaddr,
921 bytes_returned)) {
922 pr_err("%s: Could not copy buffer to user,size = %d\n",
923 __func__, bytes_returned);
924 result = -EINVAL;
925 goto err;
926 }
927 } else {
928 bytes_returned = data_size;
929 }
930 mutex_unlock(&rtac_adm_apr_mutex);
931done:
932 return bytes_returned;
933err:
934 mutex_unlock(&rtac_adm_apr_mutex);
935 return result;
936}
937
938
939/* ASM APR */
940void rtac_set_asm_handle(u32 session_id, void *handle)
941{
942 pr_debug("%s\n", __func__);
943
944 mutex_lock(&rtac_asm_apr_mutex);
945 rtac_asm_apr_data[session_id].apr_handle = handle;
946 mutex_unlock(&rtac_asm_apr_mutex);
947}
948
949bool rtac_make_asm_callback(u32 session_id, uint32_t *payload,
950 u32 payload_size)
951{
952 if (atomic_read(&rtac_asm_apr_data[session_id].cmd_state) != 1)
953 return false;
954
955 pr_debug("%s\n", __func__);
956 if (payload_size == sizeof(uint32_t))
957 atomic_set(&rtac_common.apr_err_code, payload[0]);
958 else if (payload_size == (2*sizeof(uint32_t)))
959 atomic_set(&rtac_common.apr_err_code, payload[1]);
960
961 atomic_set(&rtac_asm_apr_data[session_id].cmd_state, 0);
962 wake_up(&rtac_asm_apr_data[session_id].cmd_wait);
963 return true;
964}
965
966int send_rtac_asm_apr(void *buf, u32 opcode)
967{
968 s32 result;
969 u32 user_buf_size = 0;
970 u32 bytes_returned = 0;
971 u32 session_id = 0;
972 u32 payload_size;
973 u32 data_size = 0;
974 struct apr_hdr asm_params;
975
976 pr_debug("%s\n", __func__);
977
978 if (rtac_cal[ASM_RTAC_CAL].map_data.ion_handle == NULL) {
979 result = rtac_allocate_cal_buffer(ASM_RTAC_CAL);
980 if (result < 0) {
981 pr_err("%s: allocate buffer failed!",
982 __func__);
983 goto done;
984 }
985 }
986
987 if (rtac_cal[ASM_RTAC_CAL].map_data.map_handle == 0) {
988 result = rtac_map_cal_buffer(ASM_RTAC_CAL);
989 if (result < 0) {
990 pr_err("%s: map buffer failed!",
991 __func__);
992 goto done;
993 }
994 }
995
996 if (copy_from_user(&user_buf_size, (void *)buf,
997 sizeof(user_buf_size))) {
998 pr_err("%s: Copy from user failed! buf = 0x%pK\n",
999 __func__, buf);
1000 goto done;
1001 }
1002 if (user_buf_size <= 0) {
1003 pr_err("%s: Invalid buffer size = %d\n",
1004 __func__, user_buf_size);
1005 goto done;
1006 }
1007
1008 if (copy_from_user(&payload_size, buf + sizeof(u32), sizeof(u32))) {
1009 pr_err("%s: Could not copy payload size from user buffer\n",
1010 __func__);
1011 goto done;
1012 }
1013
1014 if (copy_from_user(&session_id, buf + 2 * sizeof(u32), sizeof(u32))) {
1015 pr_err("%s: Could not copy session id from user buffer\n",
1016 __func__);
1017 goto done;
1018 }
1019 if (session_id >= (ASM_ACTIVE_STREAMS_ALLOWED + 1)) {
1020 pr_err("%s: Invalid Session = %d\n", __func__, session_id);
1021 goto done;
1022 }
1023
1024 mutex_lock(&rtac_asm_apr_mutex);
1025 if (rtac_asm_apr_data[session_id].apr_handle == NULL) {
1026 pr_err("%s: APR not initialized\n", __func__);
1027 result = -EINVAL;
1028 goto err;
1029 }
1030
1031 if (opcode == ASM_STREAM_CMD_SET_PP_PARAMS_V2) {
1032 /* set payload size to in-band payload */
1033 /* set data size to actual out of band payload size */
1034 data_size = payload_size - 4 * sizeof(u32);
1035 if (data_size > rtac_cal[ASM_RTAC_CAL].map_data.map_size) {
1036 pr_err("%s: Invalid data size = %d\n",
1037 __func__, data_size);
1038 result = -EINVAL;
1039 goto err;
1040 }
1041 payload_size = 4 * sizeof(u32);
1042
1043 /* Copy buffer to out-of-band payload */
1044 if (copy_from_user((void *)
1045 rtac_cal[ASM_RTAC_CAL].cal_data.kvaddr,
1046 buf + 7 * sizeof(u32), data_size)) {
1047 pr_err("%s: Could not copy payload from user buffer\n",
1048 __func__);
1049 result = -EINVAL;
1050 goto err;
1051 }
1052 /* set payload size in packet */
1053 rtac_asm_buffer[8] = data_size;
1054
1055 } else {
1056 if (payload_size > MAX_PAYLOAD_SIZE) {
1057 pr_err("%s: Invalid payload size = %d\n",
1058 __func__, payload_size);
1059 result = -EINVAL;
1060 goto err;
1061 }
1062
1063 /* Copy buffer to in-band payload */
1064 if (copy_from_user(rtac_asm_buffer +
1065 sizeof(asm_params)/sizeof(u32),
1066 buf + 3 * sizeof(u32), payload_size)) {
1067 pr_err("%s: Could not copy payload from user buffer\n",
1068 __func__);
1069 result = -EINVAL;
1070 goto err;
1071 }
1072 }
1073
1074 /* Pack header */
1075 asm_params.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1076 APR_HDR_LEN(20), APR_PKT_VER);
1077 asm_params.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1078 payload_size);
1079 asm_params.src_svc = q6asm_get_apr_service_id(session_id);
1080 asm_params.src_domain = APR_DOMAIN_APPS;
1081 asm_params.src_port = (session_id << 8) | 0x0001;
1082 asm_params.dest_svc = APR_SVC_ASM;
1083 asm_params.dest_domain = APR_DOMAIN_ADSP;
1084 asm_params.dest_port = (session_id << 8) | 0x0001;
1085 asm_params.token = session_id;
1086 asm_params.opcode = opcode;
1087
1088 /* fill for out-of-band */
1089 rtac_asm_buffer[5] =
1090 lower_32_bits(rtac_cal[ASM_RTAC_CAL].cal_data.paddr);
1091 rtac_asm_buffer[6] =
1092 msm_audio_populate_upper_32_bits(
1093 rtac_cal[ASM_RTAC_CAL].cal_data.paddr);
1094 rtac_asm_buffer[7] = rtac_cal[ASM_RTAC_CAL].map_data.map_handle;
1095
1096 memcpy(rtac_asm_buffer, &asm_params, sizeof(asm_params));
1097 atomic_set(&rtac_asm_apr_data[session_id].cmd_state, 1);
1098
1099 pr_debug("%s: Sending RTAC command ioctl 0x%x, paddr 0x%pK\n",
1100 __func__, opcode,
1101 &rtac_cal[ASM_RTAC_CAL].cal_data.paddr);
1102
1103 result = apr_send_pkt(rtac_asm_apr_data[session_id].apr_handle,
1104 (uint32_t *)rtac_asm_buffer);
1105 if (result < 0) {
1106 pr_err("%s: Set params failed session = %d\n",
1107 __func__, session_id);
1108 goto err;
1109 }
1110
1111 /* Wait for the callback */
1112 result = wait_event_timeout(rtac_asm_apr_data[session_id].cmd_wait,
1113 (atomic_read(&rtac_asm_apr_data[session_id].cmd_state) == 0),
1114 5 * HZ);
1115 if (!result) {
1116 pr_err("%s: Set params timed out session = %d\n",
1117 __func__, session_id);
1118 goto err;
1119 }
1120 if (atomic_read(&rtac_common.apr_err_code)) {
1121 pr_err("%s: DSP returned error code = [%s], opcode = 0x%x\n",
1122 __func__, adsp_err_get_err_str(atomic_read(
1123 &rtac_common.apr_err_code)),
1124 opcode);
1125 result = adsp_err_get_lnx_err_code(
1126 atomic_read(
1127 &rtac_common.apr_err_code));
1128 goto err;
1129 }
1130
1131 if (opcode == ASM_STREAM_CMD_GET_PP_PARAMS_V2) {
1132 bytes_returned = ((u32 *)rtac_cal[ASM_RTAC_CAL].cal_data.
1133 kvaddr)[2] + 3 * sizeof(u32);
1134
1135 if (bytes_returned > user_buf_size) {
1136 pr_err("%s: User buf not big enough, size = 0x%x, returned size = 0x%x\n",
1137 __func__, user_buf_size, bytes_returned);
1138 result = -EINVAL;
1139 goto err;
1140 }
1141
1142 if (copy_to_user(buf, (void *)
1143 rtac_cal[ASM_RTAC_CAL].cal_data.kvaddr,
1144 bytes_returned)) {
1145 pr_err("%s: Could not copy buffer to user,size = %d\n",
1146 __func__, bytes_returned);
1147 result = -EINVAL;
1148 goto err;
1149 }
1150 } else {
1151 bytes_returned = data_size;
1152 }
1153 mutex_unlock(&rtac_asm_apr_mutex);
1154done:
1155 return bytes_returned;
1156err:
1157 mutex_unlock(&rtac_asm_apr_mutex);
1158 return result;
1159}
1160
1161/* AFE APR */
1162void rtac_set_afe_handle(void *handle)
1163{
1164 mutex_lock(&rtac_afe_apr_mutex);
1165 rtac_afe_apr_data.apr_handle = handle;
1166 mutex_unlock(&rtac_afe_apr_mutex);
1167}
1168
1169bool rtac_make_afe_callback(uint32_t *payload, uint32_t payload_size)
1170{
1171 pr_debug("%s:cmd_state = %d\n", __func__,
1172 atomic_read(&rtac_afe_apr_data.cmd_state));
1173 if (atomic_read(&rtac_afe_apr_data.cmd_state) != 1)
1174 return false;
1175
1176 if (payload_size == sizeof(uint32_t))
1177 atomic_set(&rtac_common.apr_err_code, payload[0]);
1178 else if (payload_size == (2*sizeof(uint32_t)))
1179 atomic_set(&rtac_common.apr_err_code, payload[1]);
1180
1181 atomic_set(&rtac_afe_apr_data.cmd_state, 0);
1182 wake_up(&rtac_afe_apr_data.cmd_wait);
1183 return true;
1184}
1185
1186static int fill_afe_apr_hdr(struct apr_hdr *apr_hdr, uint32_t port,
1187 uint32_t opcode, uint32_t apr_msg_size)
1188{
1189 if (apr_hdr == NULL) {
1190 pr_err("%s: invalid APR pointer", __func__);
1191 return -EINVAL;
1192 }
1193
1194 apr_hdr->hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1195 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1196 apr_hdr->pkt_size = apr_msg_size;
1197 apr_hdr->src_svc = APR_SVC_AFE;
1198 apr_hdr->src_domain = APR_DOMAIN_APPS;
1199 apr_hdr->src_port = 0;
1200 apr_hdr->dest_svc = APR_SVC_AFE;
1201 apr_hdr->dest_domain = APR_DOMAIN_ADSP;
1202 apr_hdr->dest_port = 0;
1203 apr_hdr->token = port;
1204 apr_hdr->opcode = opcode;
1205
1206 return 0;
1207
1208}
1209static int send_rtac_afe_apr(void *buf, uint32_t opcode)
1210{
1211 int32_t result;
1212 uint32_t bytes_returned = 0;
1213 uint32_t port_index = 0;
1214 uint32_t apr_msg_size = 0;
1215 struct rtac_afe_user_data user_afe_buf;
1216
1217 pr_debug("%s\n", __func__);
1218
1219 if (rtac_cal[AFE_RTAC_CAL].map_data.ion_handle == NULL) {
1220 result = rtac_allocate_cal_buffer(AFE_RTAC_CAL);
1221 if (result < 0) {
1222 pr_err("%s: allocate buffer failed! ret = %d\n",
1223 __func__, result);
1224 goto done;
1225 }
1226 }
1227
1228 if (rtac_cal[AFE_RTAC_CAL].map_data.map_handle == 0) {
1229 result = rtac_map_cal_buffer(AFE_RTAC_CAL);
1230 if (result < 0) {
1231 pr_err("%s: map buffer failed! ret = %d\n",
1232 __func__, result);
1233 goto done;
1234 }
1235 }
1236
1237 if (copy_from_user(&user_afe_buf, (void *)buf,
1238 sizeof(struct rtac_afe_user_data))) {
1239 pr_err("%s: Copy from user failed! buf = 0x%pK\n",
1240 __func__, buf);
1241 goto done;
1242 }
1243
1244 if (user_afe_buf.buf_size <= 0) {
1245 pr_err("%s: Invalid buffer size = %d\n",
1246 __func__, user_afe_buf.buf_size);
1247 goto done;
1248 }
1249
1250 port_index = q6audio_get_port_index(user_afe_buf.port_id);
1251 if (port_index >= AFE_MAX_PORTS) {
1252 pr_err("%s: Invalid AFE port = 0x%x\n",
1253 __func__, user_afe_buf.port_id);
1254 goto done;
1255 }
1256
1257 mutex_lock(&rtac_afe_apr_mutex);
1258 if (rtac_afe_apr_data.apr_handle == NULL) {
1259 pr_err("%s: APR not initialized\n", __func__);
1260 result = -EINVAL;
1261 goto err;
1262 }
1263 if (opcode == AFE_PORT_CMD_SET_PARAM_V2) {
1264 struct afe_port_cmd_set_param_v2 *afe_set_apr_msg;
1265
1266 /* set data size to actual out of band payload size */
1267 if (user_afe_buf.rtac_afe_set.cmd.payload_size >
1268 rtac_cal[AFE_RTAC_CAL].map_data.map_size) {
1269 pr_err("%s: Invalid data size = %d\n",
1270 __func__,
1271 user_afe_buf.rtac_afe_set.cmd.payload_size);
1272 result = -EINVAL;
1273 goto err;
1274 }
1275
1276 /* Copy buffer to out-of-band payload */
1277 if (copy_from_user((void *)
1278 rtac_cal[AFE_RTAC_CAL].cal_data.kvaddr,
1279 buf+offsetof(struct rtac_afe_user_data,
1280 rtac_afe_set.data),
1281 user_afe_buf.rtac_afe_set.cmd.payload_size)) {
1282 pr_err("%s: Could not copy payload from user buffer\n",
1283 __func__);
1284 result = -EINVAL;
1285 goto err;
1286 }
1287
1288 /* Copy AFE APR Message */
1289 afe_set_apr_msg = (struct afe_port_cmd_set_param_v2 *)
1290 ((u8 *)rtac_afe_buffer +
1291 sizeof(struct apr_hdr));
1292 if (copy_from_user((void *)
1293 afe_set_apr_msg,
1294 buf + offsetof(struct rtac_afe_user_data,
1295 rtac_afe_set.cmd),
1296 sizeof(struct afe_port_cmd_set_param_v2))) {
1297 pr_err("%s: Could not copy payload from user buffer\n",
1298 __func__);
1299 result = -EINVAL;
1300 goto err;
1301 }
1302
1303 afe_set_apr_msg->payload_address_lsw =
1304 lower_32_bits(rtac_cal[AFE_RTAC_CAL].cal_data.paddr);
1305 afe_set_apr_msg->payload_address_msw =
1306 msm_audio_populate_upper_32_bits(
1307 rtac_cal[AFE_RTAC_CAL].cal_data.paddr);
1308 afe_set_apr_msg->mem_map_handle =
1309 rtac_cal[AFE_RTAC_CAL].map_data.map_handle;
1310
1311 apr_msg_size = sizeof(struct apr_hdr) +
1312 sizeof(struct afe_port_cmd_set_param_v2);
1313
1314 } else {
1315 struct afe_port_cmd_get_param_v2 *afe_get_apr_msg;
1316
1317 if (user_afe_buf.cmd_size > MAX_PAYLOAD_SIZE) {
1318 pr_err("%s: Invalid payload size = %d\n",
1319 __func__, user_afe_buf.cmd_size);
1320 result = -EINVAL;
1321 goto err;
1322 }
1323
1324 /* Copy buffer to in-band payload */
1325 afe_get_apr_msg = (struct afe_port_cmd_get_param_v2 *)
1326 ((u8 *) rtac_afe_buffer +
1327 sizeof(struct apr_hdr));
1328 if (copy_from_user((void *)afe_get_apr_msg,
1329 buf+offsetof(struct rtac_afe_user_data,
1330 rtac_afe_get.cmd),
1331 sizeof(struct afe_port_cmd_get_param_v2))) {
1332 pr_err("%s: Could not copy payload from user buffer\n",
1333 __func__);
1334 result = -EINVAL;
1335 goto err;
1336 }
1337
1338 afe_get_apr_msg->payload_address_lsw =
1339 lower_32_bits(rtac_cal[AFE_RTAC_CAL].cal_data.paddr);
1340 afe_get_apr_msg->payload_address_msw =
1341 msm_audio_populate_upper_32_bits(
1342 rtac_cal[AFE_RTAC_CAL].cal_data.paddr);
1343 afe_get_apr_msg->mem_map_handle =
1344 rtac_cal[AFE_RTAC_CAL].map_data.map_handle;
1345 afe_get_apr_msg->payload_size -= sizeof(struct apr_hdr);
1346 apr_msg_size = sizeof(struct apr_hdr) +
1347 sizeof(struct afe_port_cmd_get_param_v2);
1348 }
1349
1350 fill_afe_apr_hdr((struct apr_hdr *) rtac_afe_buffer,
1351 port_index, opcode, apr_msg_size);
1352
1353 atomic_set(&rtac_afe_apr_data.cmd_state, 1);
1354
1355 pr_debug("%s: Sending RTAC command ioctl 0x%x, paddr 0x%pK\n",
1356 __func__, opcode,
1357 &rtac_cal[AFE_RTAC_CAL].cal_data.paddr);
1358
1359 result = apr_send_pkt(rtac_afe_apr_data.apr_handle,
1360 (uint32_t *)rtac_afe_buffer);
1361 if (result < 0) {
1362 pr_err("%s: Set params failed port = 0x%x, ret = %d\n",
1363 __func__, user_afe_buf.port_id, result);
1364 goto err;
1365 }
1366 /* Wait for the callback */
1367 result = wait_event_timeout(rtac_afe_apr_data.cmd_wait,
1368 (atomic_read(&rtac_afe_apr_data.cmd_state) == 0),
1369 msecs_to_jiffies(TIMEOUT_MS));
1370 if (!result) {
1371 pr_err("%s: Set params timed out port = 0x%x, ret = %d\n",
1372 __func__, user_afe_buf.port_id, result);
1373 goto err;
1374 }
1375 if (atomic_read(&rtac_common.apr_err_code)) {
1376 pr_err("%s: DSP returned error code = [%s], opcode = 0x%x\n",
1377 __func__, adsp_err_get_err_str(atomic_read(
1378 &rtac_common.apr_err_code)),
1379 opcode);
1380 result = adsp_err_get_lnx_err_code(
1381 atomic_read(
1382 &rtac_common.apr_err_code));
1383 goto err;
1384 }
1385
1386 if (opcode == AFE_PORT_CMD_GET_PARAM_V2) {
1387 struct afe_port_param_data_v2 *get_resp;
1388
1389 get_resp = (struct afe_port_param_data_v2 *)
1390 rtac_cal[AFE_RTAC_CAL].cal_data.kvaddr;
1391
1392 bytes_returned = get_resp->param_size +
1393 sizeof(struct afe_port_param_data_v2);
1394
1395 if (bytes_returned > user_afe_buf.buf_size) {
1396 pr_err("%s: user size = 0x%x, returned size = 0x%x\n",
1397 __func__, user_afe_buf.buf_size,
1398 bytes_returned);
1399 result = -EINVAL;
1400 goto err;
1401 }
1402
1403 if (copy_to_user(buf, (void *)
1404 rtac_cal[AFE_RTAC_CAL].cal_data.kvaddr,
1405 bytes_returned)) {
1406 pr_err("%s: Could not copy buffer to user,size = %d\n",
1407 __func__, bytes_returned);
1408 result = -EINVAL;
1409 goto err;
1410 }
1411 } else {
1412 bytes_returned = user_afe_buf.rtac_afe_set.cmd.payload_size;
1413 }
1414 mutex_unlock(&rtac_afe_apr_mutex);
1415done:
1416 return bytes_returned;
1417err:
1418 mutex_unlock(&rtac_afe_apr_mutex);
1419 return result;
1420}
1421
1422/* Voice APR */
1423void rtac_set_voice_handle(u32 mode, void *handle)
1424{
1425 pr_debug("%s\n", __func__);
1426
1427 mutex_lock(&rtac_voice_apr_mutex);
1428 rtac_voice_apr_data[mode].apr_handle = handle;
1429 mutex_unlock(&rtac_voice_apr_mutex);
1430}
1431
1432bool rtac_make_voice_callback(u32 mode, uint32_t *payload, u32 payload_size)
1433{
1434 if ((atomic_read(&rtac_voice_apr_data[mode].cmd_state) != 1) ||
1435 (mode >= RTAC_VOICE_MODES))
1436 return false;
1437
1438 pr_debug("%s\n", __func__);
1439 if (payload_size == sizeof(uint32_t))
1440 atomic_set(&rtac_common.apr_err_code, payload[0]);
1441 else if (payload_size == (2*sizeof(uint32_t)))
1442 atomic_set(&rtac_common.apr_err_code, payload[1]);
1443
1444 atomic_set(&rtac_voice_apr_data[mode].cmd_state, 0);
1445 wake_up(&rtac_voice_apr_data[mode].cmd_wait);
1446 return true;
1447}
1448
1449int send_voice_apr(u32 mode, void *buf, u32 opcode)
1450{
1451 s32 result;
1452 u32 user_buf_size = 0;
1453 u32 bytes_returned = 0;
1454 u32 payload_size;
1455 u32 dest_port;
1456 u32 data_size = 0;
1457 struct apr_hdr voice_params;
1458
1459 pr_debug("%s\n", __func__);
1460
1461 if (rtac_cal[VOICE_RTAC_CAL].map_data.ion_handle == NULL) {
1462 result = rtac_allocate_cal_buffer(VOICE_RTAC_CAL);
1463 if (result < 0) {
1464 pr_err("%s: allocate buffer failed!",
1465 __func__);
1466 goto done;
1467 }
1468 }
1469
1470 if (rtac_cal[VOICE_RTAC_CAL].map_data.map_handle == 0) {
1471 result = rtac_map_cal_buffer(VOICE_RTAC_CAL);
1472 if (result < 0) {
1473 pr_err("%s: map buffer failed!",
1474 __func__);
1475 goto done;
1476 }
1477 }
1478
1479 if (copy_from_user(&user_buf_size, (void *)buf,
1480 sizeof(user_buf_size))) {
1481 pr_err("%s: Copy from user failed! buf = 0x%pK\n",
1482 __func__, buf);
1483 goto done;
1484 }
1485 if (user_buf_size <= 0) {
1486 pr_err("%s: Invalid buffer size = %d\n",
1487 __func__, user_buf_size);
1488 goto done;
1489 }
1490
1491 if (copy_from_user(&payload_size, buf + sizeof(u32), sizeof(u32))) {
1492 pr_err("%s: Could not copy payload size from user buffer\n",
1493 __func__);
1494 goto done;
1495 }
1496
1497 if (copy_from_user(&dest_port, buf + 2 * sizeof(u32), sizeof(u32))) {
1498 pr_err("%s: Could not copy port id from user buffer\n",
1499 __func__);
1500 goto done;
1501 }
1502
1503 if ((mode != RTAC_CVP) && (mode != RTAC_CVS)) {
1504 pr_err("%s: Invalid Mode for APR, mode = %d\n",
1505 __func__, mode);
1506 goto done;
1507 }
1508
1509 mutex_lock(&rtac_voice_apr_mutex);
1510 if (rtac_voice_apr_data[mode].apr_handle == NULL) {
1511 pr_err("%s: APR not initialized\n", __func__);
1512 result = -EINVAL;
1513 goto err;
1514 }
1515
1516 if (opcode == VSS_ICOMMON_CMD_SET_PARAM_V2) {
1517 /* set payload size to in-band payload */
1518 /* set data size to actual out of band payload size */
1519 data_size = payload_size - 4 * sizeof(u32);
1520 if (data_size > rtac_cal[VOICE_RTAC_CAL].map_data.map_size) {
1521 pr_err("%s: Invalid data size = %d\n",
1522 __func__, data_size);
1523 result = -EINVAL;
1524 goto err;
1525 }
1526 payload_size = 4 * sizeof(u32);
1527
1528 /* Copy buffer to out-of-band payload */
1529 if (copy_from_user((void *)
1530 rtac_cal[VOICE_RTAC_CAL].cal_data.kvaddr,
1531 buf + 7 * sizeof(u32), data_size)) {
1532 pr_err("%s: Could not copy payload from user buffer\n",
1533 __func__);
1534 result = -EINVAL;
1535 goto err;
1536 }
1537 /* set payload size in packet */
1538 rtac_voice_buffer[8] = data_size;
1539 } else {
1540 if (payload_size > MAX_PAYLOAD_SIZE) {
1541 pr_err("%s: Invalid payload size = %d\n",
1542 __func__, payload_size);
1543 result = -EINVAL;
1544 goto err;
1545 }
1546
1547 /* Copy buffer to in-band payload */
1548 if (copy_from_user(rtac_voice_buffer +
1549 sizeof(voice_params)/sizeof(u32),
1550 buf + 3 * sizeof(u32), payload_size)) {
1551 pr_err("%s: Could not copy payload from user buffer\n",
1552 __func__);
1553 result = -EINVAL;
1554 goto err;
1555 }
1556 }
1557
1558 /* Pack header */
1559 voice_params.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1560 APR_HDR_LEN(20), APR_PKT_VER);
1561 voice_params.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
1562 payload_size);
1563 voice_params.src_svc = 0;
1564 voice_params.src_domain = APR_DOMAIN_APPS;
1565 voice_params.src_port = get_voice_index(mode, dest_port);
1566 voice_params.dest_svc = 0;
1567 voice_params.dest_domain = APR_DOMAIN_MODEM;
1568 voice_params.dest_port = (u16)dest_port;
1569 voice_params.token = (opcode == VSS_ICOMMON_CMD_SET_PARAM_V2) ?
1570 VOC_RTAC_SET_PARAM_TOKEN :
1571 0;
1572 voice_params.opcode = opcode;
1573
1574 /* fill for out-of-band */
1575 rtac_voice_buffer[5] = rtac_cal[VOICE_RTAC_CAL].map_data.map_handle;
1576 rtac_voice_buffer[6] =
1577 lower_32_bits(rtac_cal[VOICE_RTAC_CAL].cal_data.paddr);
1578 rtac_voice_buffer[7] =
1579 msm_audio_populate_upper_32_bits(
1580 rtac_cal[VOICE_RTAC_CAL].cal_data.paddr);
1581
1582 memcpy(rtac_voice_buffer, &voice_params, sizeof(voice_params));
1583 atomic_set(&rtac_voice_apr_data[mode].cmd_state, 1);
1584
1585 pr_debug("%s: Sending RTAC command ioctl 0x%x, paddr 0x%pK\n",
1586 __func__, opcode,
1587 &rtac_cal[VOICE_RTAC_CAL].cal_data.paddr);
1588
1589 result = apr_send_pkt(rtac_voice_apr_data[mode].apr_handle,
1590 (uint32_t *)rtac_voice_buffer);
1591 if (result < 0) {
1592 pr_err("%s: apr_send_pkt failed opcode = %x\n",
1593 __func__, opcode);
1594 goto err;
1595 }
1596 /* Wait for the callback */
1597 result = wait_event_timeout(rtac_voice_apr_data[mode].cmd_wait,
1598 (atomic_read(&rtac_voice_apr_data[mode].cmd_state) == 0),
1599 msecs_to_jiffies(TIMEOUT_MS));
1600 if (!result) {
1601 pr_err("%s: apr_send_pkt timed out opcode = %x\n",
1602 __func__, opcode);
1603 goto err;
1604 }
1605 if (atomic_read(&rtac_common.apr_err_code)) {
1606 pr_err("%s: DSP returned error code = [%s], opcode = 0x%x\n",
1607 __func__, adsp_err_get_err_str(atomic_read(
1608 &rtac_common.apr_err_code)),
1609 opcode);
1610 result = adsp_err_get_lnx_err_code(
1611 atomic_read(
1612 &rtac_common.apr_err_code));
1613 goto err;
1614 }
1615
1616 if (opcode == VSS_ICOMMON_CMD_GET_PARAM_V2) {
1617 bytes_returned = ((u32 *)rtac_cal[VOICE_RTAC_CAL].cal_data.
1618 kvaddr)[2] + 3 * sizeof(u32);
1619
1620 if (bytes_returned > user_buf_size) {
1621 pr_err("%s: User buf not big enough, size = 0x%x, returned size = 0x%x\n",
1622 __func__, user_buf_size, bytes_returned);
1623 result = -EINVAL;
1624 goto err;
1625 }
1626
1627 if (copy_to_user(buf, (void *)
1628 rtac_cal[VOICE_RTAC_CAL].cal_data.kvaddr,
1629 bytes_returned)) {
1630 pr_err("%s: Could not copy buffer to user, size = %d\n",
1631 __func__, bytes_returned);
1632 result = -EINVAL;
1633 goto err;
1634 }
1635 } else {
1636 bytes_returned = data_size;
1637 }
1638 mutex_unlock(&rtac_voice_apr_mutex);
1639done:
1640 return bytes_returned;
1641err:
1642 mutex_unlock(&rtac_voice_apr_mutex);
1643 return result;
1644}
1645
1646void get_rtac_adm_data(struct rtac_adm *adm_data)
1647{
1648 mutex_lock(&rtac_adm_mutex);
1649 memcpy(adm_data, &rtac_adm_data, sizeof(struct rtac_adm));
1650 mutex_unlock(&rtac_adm_mutex);
1651}
1652
1653
1654static long rtac_ioctl_shared(struct file *f,
1655 unsigned int cmd, void *arg)
1656{
1657 int result = 0;
1658
1659 if (!arg) {
1660 pr_err("%s: No data sent to driver!\n", __func__);
1661 result = -EFAULT;
1662 goto done;
1663 }
1664
1665 switch (cmd) {
1666 case AUDIO_GET_RTAC_ADM_INFO: {
1667 mutex_lock(&rtac_adm_mutex);
1668 if (copy_to_user((void *)arg, &rtac_adm_data,
1669 sizeof(rtac_adm_data))) {
1670 pr_err("%s: copy_to_user failed for AUDIO_GET_RTAC_ADM_INFO\n",
1671 __func__);
1672 mutex_unlock(&rtac_adm_mutex);
1673 return -EFAULT;
1674 }
1675 result = sizeof(rtac_adm_data);
1676 mutex_unlock(&rtac_adm_mutex);
1677 break;
1678 }
1679 case AUDIO_GET_RTAC_VOICE_INFO: {
1680 mutex_lock(&rtac_voice_mutex);
1681 if (copy_to_user((void *)arg, &rtac_voice_data,
1682 sizeof(rtac_voice_data))) {
1683 pr_err("%s: copy_to_user failed for AUDIO_GET_RTAC_VOICE_INFO\n",
1684 __func__);
1685 mutex_unlock(&rtac_voice_mutex);
1686 return -EFAULT;
1687 }
1688 result = sizeof(rtac_voice_data);
1689 mutex_unlock(&rtac_voice_mutex);
1690 break;
1691 }
1692
1693 case AUDIO_GET_RTAC_ADM_CAL:
1694 result = send_adm_apr((void *)arg, ADM_CMD_GET_PP_PARAMS_V5);
1695 break;
1696 case AUDIO_SET_RTAC_ADM_CAL:
1697 result = send_adm_apr((void *)arg, ADM_CMD_SET_PP_PARAMS_V5);
1698 break;
1699 case AUDIO_GET_RTAC_ASM_CAL:
1700 result = send_rtac_asm_apr((void *)arg,
1701 ASM_STREAM_CMD_GET_PP_PARAMS_V2);
1702 break;
1703 case AUDIO_SET_RTAC_ASM_CAL:
1704 result = send_rtac_asm_apr((void *)arg,
1705 ASM_STREAM_CMD_SET_PP_PARAMS_V2);
1706 break;
1707 case AUDIO_GET_RTAC_CVS_CAL:
1708 result = send_voice_apr(RTAC_CVS, (void *) arg,
1709 VSS_ICOMMON_CMD_GET_PARAM_V2);
1710 break;
1711 case AUDIO_SET_RTAC_CVS_CAL:
1712 result = send_voice_apr(RTAC_CVS, (void *) arg,
1713 VSS_ICOMMON_CMD_SET_PARAM_V2);
1714 break;
1715 case AUDIO_GET_RTAC_CVP_CAL:
1716 result = send_voice_apr(RTAC_CVP, (void *) arg,
1717 VSS_ICOMMON_CMD_GET_PARAM_V2);
1718 break;
1719 case AUDIO_SET_RTAC_CVP_CAL:
1720 result = send_voice_apr(RTAC_CVP, (void *) arg,
1721 VSS_ICOMMON_CMD_SET_PARAM_V2);
1722 break;
1723 case AUDIO_GET_RTAC_AFE_CAL:
1724 result = send_rtac_afe_apr((void *)arg,
1725 AFE_PORT_CMD_GET_PARAM_V2);
1726 break;
1727 case AUDIO_SET_RTAC_AFE_CAL:
1728 result = send_rtac_afe_apr((void *)arg,
1729 AFE_PORT_CMD_SET_PARAM_V2);
1730 break;
1731 default:
1732 pr_err("%s: Invalid IOCTL, command = %d!\n",
1733 __func__, cmd);
1734 result = -EINVAL;
1735 }
1736done:
1737 return result;
1738}
1739
1740static long rtac_ioctl(struct file *f,
1741 unsigned int cmd, unsigned long arg)
1742{
1743 int result = 0;
1744
1745 if (!arg) {
1746 pr_err("%s: No data sent to driver!\n", __func__);
1747 result = -EFAULT;
1748 } else {
1749 result = rtac_ioctl_shared(f, cmd, (void __user *)arg);
1750 }
1751
1752 return result;
1753}
1754
1755#ifdef CONFIG_COMPAT
1756#define AUDIO_GET_RTAC_ADM_INFO_32 _IOR(CAL_IOCTL_MAGIC, 207, compat_uptr_t)
1757#define AUDIO_GET_RTAC_VOICE_INFO_32 _IOR(CAL_IOCTL_MAGIC, 208, compat_uptr_t)
1758#define AUDIO_GET_RTAC_ADM_CAL_32 _IOWR(CAL_IOCTL_MAGIC, 209, compat_uptr_t)
1759#define AUDIO_SET_RTAC_ADM_CAL_32 _IOWR(CAL_IOCTL_MAGIC, 210, compat_uptr_t)
1760#define AUDIO_GET_RTAC_ASM_CAL_32 _IOWR(CAL_IOCTL_MAGIC, 211, compat_uptr_t)
1761#define AUDIO_SET_RTAC_ASM_CAL_32 _IOWR(CAL_IOCTL_MAGIC, 212, compat_uptr_t)
1762#define AUDIO_GET_RTAC_CVS_CAL_32 _IOWR(CAL_IOCTL_MAGIC, 213, compat_uptr_t)
1763#define AUDIO_SET_RTAC_CVS_CAL_32 _IOWR(CAL_IOCTL_MAGIC, 214, compat_uptr_t)
1764#define AUDIO_GET_RTAC_CVP_CAL_32 _IOWR(CAL_IOCTL_MAGIC, 215, compat_uptr_t)
1765#define AUDIO_SET_RTAC_CVP_CAL_32 _IOWR(CAL_IOCTL_MAGIC, 216, compat_uptr_t)
1766#define AUDIO_GET_RTAC_AFE_CAL_32 _IOWR(CAL_IOCTL_MAGIC, 217, compat_uptr_t)
1767#define AUDIO_SET_RTAC_AFE_CAL_32 _IOWR(CAL_IOCTL_MAGIC, 218, compat_uptr_t)
1768
1769static long rtac_compat_ioctl(struct file *f,
1770 unsigned int cmd, unsigned long arg)
1771{
1772 int result = 0;
1773
1774 if (!arg) {
1775 pr_err("%s: No data sent to driver!\n", __func__);
1776 result = -EINVAL;
1777 goto done;
1778 }
1779
1780 switch (cmd) {
1781 case AUDIO_GET_RTAC_ADM_INFO_32:
1782 cmd = AUDIO_GET_RTAC_ADM_INFO;
1783 goto process;
1784 case AUDIO_GET_RTAC_VOICE_INFO_32:
1785 cmd = AUDIO_GET_RTAC_VOICE_INFO;
1786 goto process;
1787 case AUDIO_GET_RTAC_AFE_CAL_32:
1788 cmd = AUDIO_GET_RTAC_AFE_CAL;
1789 goto process;
1790 case AUDIO_SET_RTAC_AFE_CAL_32:
1791 cmd = AUDIO_SET_RTAC_AFE_CAL;
1792 goto process;
1793 case AUDIO_GET_RTAC_ADM_CAL_32:
1794 cmd = AUDIO_GET_RTAC_ADM_CAL;
1795 goto process;
1796 case AUDIO_SET_RTAC_ADM_CAL_32:
1797 cmd = AUDIO_SET_RTAC_ADM_CAL;
1798 goto process;
1799 case AUDIO_GET_RTAC_ASM_CAL_32:
1800 cmd = AUDIO_GET_RTAC_ASM_CAL;
1801 goto process;
1802 case AUDIO_SET_RTAC_ASM_CAL_32:
1803 cmd = AUDIO_SET_RTAC_ASM_CAL;
1804 goto process;
1805 case AUDIO_GET_RTAC_CVS_CAL_32:
1806 cmd = AUDIO_GET_RTAC_CVS_CAL;
1807 goto process;
1808 case AUDIO_SET_RTAC_CVS_CAL_32:
1809 cmd = AUDIO_SET_RTAC_CVS_CAL;
1810 goto process;
1811 case AUDIO_GET_RTAC_CVP_CAL_32:
1812 cmd = AUDIO_GET_RTAC_CVP_CAL;
1813 goto process;
1814 case AUDIO_SET_RTAC_CVP_CAL_32:
1815 cmd = AUDIO_SET_RTAC_CVP_CAL;
1816process:
1817 result = rtac_ioctl_shared(f, cmd, compat_ptr(arg));
1818 break;
1819 default:
1820 result = -EINVAL;
1821 pr_err("%s: Invalid IOCTL, command = %d!\n",
1822 __func__, cmd);
1823 break;
1824 }
1825done:
1826 return result;
1827}
1828#else
1829#define rtac_compat_ioctl NULL
1830#endif
1831
1832static const struct file_operations rtac_fops = {
1833 .owner = THIS_MODULE,
1834 .open = rtac_open,
1835 .release = rtac_release,
1836 .unlocked_ioctl = rtac_ioctl,
1837 .compat_ioctl = rtac_compat_ioctl,
1838};
1839
1840struct miscdevice rtac_misc = {
1841 .minor = MISC_DYNAMIC_MINOR,
1842 .name = "msm_rtac",
1843 .fops = &rtac_fops,
1844};
1845
1846static int __init rtac_init(void)
1847{
1848 int i = 0;
1849
1850 /* Driver */
1851 atomic_set(&rtac_common.usage_count, 0);
1852 atomic_set(&rtac_common.apr_err_code, 0);
1853
1854 /* ADM */
1855 memset(&rtac_adm_data, 0, sizeof(rtac_adm_data));
1856 rtac_adm_apr_data.apr_handle = NULL;
1857 atomic_set(&rtac_adm_apr_data.cmd_state, 0);
1858 init_waitqueue_head(&rtac_adm_apr_data.cmd_wait);
1859 mutex_init(&rtac_adm_mutex);
1860 mutex_init(&rtac_adm_apr_mutex);
1861
1862 rtac_adm_buffer = kzalloc(
1863 rtac_cal[ADM_RTAC_CAL].map_data.map_size, GFP_KERNEL);
1864 if (rtac_adm_buffer == NULL)
1865 goto nomem;
1866
1867 /* ASM */
1868 for (i = 0; i < ASM_ACTIVE_STREAMS_ALLOWED+1; i++) {
1869 rtac_asm_apr_data[i].apr_handle = NULL;
1870 atomic_set(&rtac_asm_apr_data[i].cmd_state, 0);
1871 init_waitqueue_head(&rtac_asm_apr_data[i].cmd_wait);
1872 }
1873 mutex_init(&rtac_asm_apr_mutex);
1874
1875 rtac_asm_buffer = kzalloc(
1876 rtac_cal[ASM_RTAC_CAL].map_data.map_size, GFP_KERNEL);
1877 if (rtac_asm_buffer == NULL) {
1878 kzfree(rtac_adm_buffer);
1879 goto nomem;
1880 }
1881
1882 /* AFE */
1883 rtac_afe_apr_data.apr_handle = NULL;
1884 atomic_set(&rtac_afe_apr_data.cmd_state, 0);
1885 init_waitqueue_head(&rtac_afe_apr_data.cmd_wait);
1886 mutex_init(&rtac_afe_apr_mutex);
1887
1888 rtac_afe_buffer = kzalloc(
1889 rtac_cal[AFE_RTAC_CAL].map_data.map_size, GFP_KERNEL);
1890 if (rtac_afe_buffer == NULL) {
1891 kzfree(rtac_adm_buffer);
1892 kzfree(rtac_asm_buffer);
1893 goto nomem;
1894 }
1895
1896 /* Voice */
1897 memset(&rtac_voice_data, 0, sizeof(rtac_voice_data));
1898 for (i = 0; i < RTAC_VOICE_MODES; i++) {
1899 rtac_voice_apr_data[i].apr_handle = NULL;
1900 atomic_set(&rtac_voice_apr_data[i].cmd_state, 0);
1901 init_waitqueue_head(&rtac_voice_apr_data[i].cmd_wait);
1902 }
1903 mutex_init(&rtac_voice_mutex);
1904 mutex_init(&rtac_voice_apr_mutex);
1905
1906 rtac_voice_buffer = kzalloc(
1907 rtac_cal[VOICE_RTAC_CAL].map_data.map_size, GFP_KERNEL);
1908 if (rtac_voice_buffer == NULL) {
1909 kzfree(rtac_adm_buffer);
1910 kzfree(rtac_asm_buffer);
1911 kzfree(rtac_afe_buffer);
1912 goto nomem;
1913 }
1914
1915 return misc_register(&rtac_misc);
1916nomem:
1917 return -ENOMEM;
1918}
1919
1920module_init(rtac_init);
1921
1922MODULE_DESCRIPTION("SoC QDSP6v2 Real-Time Audio Calibration driver");
1923MODULE_LICENSE("GPL v2");