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