blob: 7819395344fdcd97191539c9b1d081c084680afd [file] [log] [blame]
Manish Dewanganfafafaf2013-01-02 17:43:56 +05301/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
Manish Dewanganca859722012-07-09 18:21:42 +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#include <linux/module.h>
14#include <linux/miscdevice.h>
15#include <linux/kthread.h>
16#include <linux/wait.h>
17#include <linux/mutex.h>
18#include <linux/io.h>
19#include <linux/android_pmem.h>
20#include <linux/delay.h>
21#include <linux/dma-mapping.h>
22#include <linux/uaccess.h>
23#include <linux/msm_audio.h>
24#include <linux/slab.h>
25#include <linux/debugfs.h>
26#include <linux/memory_alloc.h>
27#include <linux/mfd/marimba.h>
28#include <mach/dal.h>
29#include <mach/iommu.h>
30#include <mach/iommu_domains.h>
31#include <mach/socinfo.h>
32#include <mach/qdsp5/qdsp5audpp.h>
33#include <mach/qdsp5/qdsp5audpreproc.h>
34#include <mach/qdsp5/qdsp5audppcmdi.h>
35#include <mach/qdsp5/qdsp5audpreproccmdi.h>
36#include <mach/qdsp5/qdsp5audpreprocmsg.h>
37#include <mach/qdsp5/qdsp5audppmsg.h>
38#include <mach/qdsp5/audio_acdbi.h>
39#include <mach/qdsp5/acdb_commands.h>
40#include <mach/qdsp5/audio_acdb_def.h>
41#include <mach/debug_mm.h>
42#include <mach/msm_memtypes.h>
43
44#include "audmgr.h"
45
46/* this is the ACDB device ID */
47#define DALDEVICEID_ACDB 0x02000069
48#define ACDB_PORT_NAME "DAL00"
49#define ACDB_CPU SMD_APPS_MODEM
50#define ACDB_BUF_SIZE 4096
51#define FLUENCE_BUF_SIZE 498
52
53#define ACDB_VALUES_NOT_FILLED 0
54#define ACDB_VALUES_FILLED 1
55#define MAX_RETRY 10
56
57#define COMMON_OBJ_ID 6
58
59/*below macro is used to align the session info received from
60Devctl driver with the state mentioned as not to alter the
61Existing code*/
62#define AUDREC_OFFSET 2
63/* rpc table index */
64enum {
65 ACDB_DAL_IOCTL = DALDEVICE_FIRST_DEVICE_API_IDX
66};
67
68enum {
69 CAL_DATA_READY = 0x1,
70 AUDPP_READY = 0x2,
71 AUDREC_READY = 0x4,
72};
73
74struct acdb_data {
75 void *handle;
76
77 u32 phys_addr;
78 u8 *virt_addr;
79
80 struct task_struct *cb_thread_task;
81 struct device_info_callback dev_cb;
82
83 u32 acdb_state;
84 struct audpp_event_callback audpp_cb;
85 struct audpreproc_event_callback audpreproc_cb;
86 struct dev_evt_msg *device_info;
87
88 audpp_cmd_cfg_object_params_pcm *pp_iir;
89 audpp_cmd_cfg_object_params_mbadrc *pp_mbadrc;
90 audpreproc_cmd_cfg_agc_params *preproc_agc;
91 audpreproc_cmd_cfg_iir_tuning_filter_params *preproc_iir;
92 audpreproc_cmd_cfg_ns_params *preproc_ns;
93 struct acdb_mbadrc_block mbadrc_block;
94
95 wait_queue_head_t wait;
96 struct mutex acdb_mutex;
97 u32 device_cb_compl;
98 u32 audpp_cb_compl;
99 u32 preproc_cb_compl;
Sriranjan Srikantam87a6c292013-01-25 16:39:58 +0530100 u32 audpp_cb_reenable_compl;
Manish Dewanganca859722012-07-09 18:21:42 +0530101 u8 preproc_stream_id;
102 u8 audrec_applied;
103 u32 multiple_sessions;
104 u32 cur_tx_session;
105 struct acdb_result acdb_result;
Sriranjan Srikantam87a6c292013-01-25 16:39:58 +0530106 uint32_t audpp_disabled_features;
Manish Dewanganca859722012-07-09 18:21:42 +0530107
108 spinlock_t dsp_lock;
109 int dec_id;
110 audpp_cmd_cfg_object_params_eqalizer eq;
111 struct audrec_session_info session_info;
112 /*pmem info*/
113 int pmem_fd;
114 unsigned long paddr;
115 unsigned long kvaddr;
116 unsigned long pmem_len;
117 struct file *file;
118 /* pmem for get acdb blk */
119 unsigned long get_blk_paddr;
120 u8 *get_blk_kvaddr;
121 void *map_v_get_blk;
122};
123
124static struct acdb_data acdb_data;
125
126struct acdb_cache_node {
127 u32 node_status;
128 s32 stream_id;
129 u32 phys_addr_acdb_values;
130 void *map_v_addr;
131 u8 *virt_addr_acdb_values;
132 struct dev_evt_msg device_info;
133};
134
135struct acdb_cache_node acdb_cache_rx;
136
137/*for TX devices acdb values are applied based on AUDREC session and
138the depth of the tx cache is define by number of AUDREC sessions supported*/
139struct acdb_cache_node acdb_cache_tx;
140
141/*Audrec session info includes Attributes Sampling frequency and enc_id */
142struct audrec_session_info session_info;
143#ifdef CONFIG_DEBUG_FS
144
145#define RTC_MAX_TIMEOUT 500 /* 500 ms */
146#define PMEM_RTC_ACDB_QUERY_MEM 4096
147#define EXTRACT_HIGH_WORD(x) ((x & 0xFFFF0000)>>16)
148#define EXTRACT_LOW_WORD(x) (0x0000FFFF & x)
149#define ACDB_RTC_TX 0xF1
150#define ACDB_RTC_RX 0x1F
151
152
153static u32 acdb_audpp_entry[][4] = {
154
155 {
156 ABID_AUDIO_RTC_VOLUME_PAN_RX,\
157 IID_AUDIO_RTC_VOLUME_PAN_PARAMETERS,\
158 AUDPP_CMD_VOLUME_PAN,\
159 ACDB_RTC_RX
160 },
161 {
162 ABID_AUDIO_IIR_RX,\
163 IID_AUDIO_IIR_COEFF,\
164 AUDPP_CMD_IIR_TUNING_FILTER,
165 ACDB_RTC_RX
166 },
167 {
168 ABID_AUDIO_RTC_EQUALIZER_PARAMETERS,\
169 IID_AUDIO_RTC_EQUALIZER_PARAMETERS,\
170 AUDPP_CMD_EQUALIZER,\
171 ACDB_RTC_RX
172 },
173 {
174 ABID_AUDIO_RTC_SPA,\
175 IID_AUDIO_RTC_SPA_PARAMETERS,\
176 AUDPP_CMD_SPECTROGRAM,
177 ACDB_RTC_RX
178 },
179 {
180 ABID_AUDIO_STF_RX,\
181 IID_AUDIO_IIR_COEFF,\
182 AUDPP_CMD_SIDECHAIN_TUNING_FILTER,\
183 ACDB_RTC_RX
184 },
185 {
186 ABID_AUDIO_MBADRC_RX,\
187 IID_AUDIO_RTC_MBADRC_PARAMETERS,\
188 AUDPP_CMD_MBADRC,\
189 ACDB_RTC_RX
190 },
191 {
192 ABID_AUDIO_AGC_TX,\
193 IID_AUDIO_AGC_PARAMETERS,\
194 AUDPREPROC_CMD_CFG_AGC_PARAMS,\
195 ACDB_RTC_TX
196 },
197 {
198 ABID_AUDIO_AGC_TX,\
199 IID_AUDIO_RTC_AGC_PARAMETERS,\
200 AUDPREPROC_CMD_CFG_AGC_PARAMS,\
201 ACDB_RTC_TX
202 },
203 {
204 ABID_AUDIO_NS_TX,\
205 IID_NS_PARAMETERS,\
206 AUDPREPROC_CMD_CFG_NS_PARAMS,\
207 ACDB_RTC_TX
208 },
209 {
210 ABID_AUDIO_IIR_TX,\
211 IID_AUDIO_RTC_TX_IIR_COEFF,\
212 AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS,\
213 ACDB_RTC_TX
214 },
215 {
216 ABID_AUDIO_IIR_TX,\
217 IID_AUDIO_IIR_COEFF,\
218 AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS,\
219 ACDB_RTC_TX
220 }
221 /*Any new entries should be added here*/
222};
223
224static struct dentry *get_set_abid_dentry;
225static struct dentry *get_set_abid_data_dentry;
226
227struct rtc_acdb_pmem {
228 u8 *viraddr;
229 int32_t phys;
230 void *map_v_rtc;
231};
232
233struct rtc_acdb_data {
234 u32 acdb_id;
235 u32 cmd_id;
236 u32 set_abid;
237 u32 set_iid;
238 u32 abid;
239 u32 err;
240 bool valid_abid;
241 u32 tx_rx_ctl;
242 struct rtc_acdb_pmem rtc_read;
243 struct rtc_acdb_pmem rtc_write;
244 wait_queue_head_t wait;
245};
246
247struct get_abid {
248 u32 cmd_id;
249 u32 acdb_id;
250 u32 set_abid;
251 u32 set_iid;
252};
253
254struct acdb_block_mbadrc_rtc {
255 u16 enable;
256 u16 num_bands;
257 u16 down_samp_level;
258 u16 adrc_delay;
259 u16 ext_buf_size;
260 u16 ext_partition;
261 u16 ext_buf_msw;
262 u16 ext_buf_lsw;
263 struct adrc_config adrc_band[AUDPP_MAX_MBADRC_BANDS];
264 signed int ext_buff[196];
265} __packed;
266
267enum {
268 ACDB_RTC_SUCCESS,
269 ACDB_RTC_ERR_INVALID_DEVICE,
270 ACDB_RTC_ERR_DEVICE_INACTIVE,
271 ACDB_RTC_ERR_INVALID_ABID,
272 ACDB_RTC_DSP_FAILURE,
273 ACDB_RTC_DSP_FEATURE_NOT_AVAILABLE,
274 ACDB_RTC_ERR_INVALID_LEN,
275 ACDB_RTC_ERR_UNKNOWN_FAILURE,
276 ACDB_RTC_PENDING_RESPONSE,
277 ACDB_RTC_INIT_FAILURE,
278};
279
280static struct rtc_acdb_data rtc_acdb;
281
282static int rtc_getsetabid_dbg_open(struct inode *inode, struct file *file)
283{
284 file->private_data = inode->i_private;
285 MM_DBG("GET-SET ABID Open debug intf %s\n",\
286 (char *) file->private_data);
287 return 0;
288}
289
290static bool get_feature_id(u32 set_abid, u32 iid, unsigned short *feature_id)
291{
292 bool ret_value = false;
293 int i = 0;
294
295 for (; i < (sizeof(acdb_audpp_entry) / sizeof(acdb_audpp_entry[0]));\
296 i++) {
297 if (acdb_audpp_entry[i][0] == set_abid &&
298 acdb_audpp_entry[i][1] == iid) {
299 *feature_id = acdb_audpp_entry[i][2];
300 rtc_acdb.tx_rx_ctl = acdb_audpp_entry[i][3];
301 ret_value = true;
302 break;
303 }
304 }
305 return ret_value;
306}
307static ssize_t rtc_getsetabid_dbg_write(struct file *filp,
308 const char __user *ubuf,
309 size_t cnt, loff_t *ppos)
310{
311 struct get_abid write_abid;
312 unsigned short feat_id = 0;
313 rtc_acdb.valid_abid = false;
314
315 if (copy_from_user(&write_abid, \
316 (void *)ubuf, sizeof(struct get_abid))) {
317 MM_ERR("ACDB DATA WRITE - INVALID READ LEN\n");
318 rtc_acdb.err = ACDB_RTC_ERR_INVALID_LEN;
319 return cnt;
320 }
321 MM_DBG("SET ABID : Cmd ID: %d Device:%d ABID:%d IID : %d cnt: %d\n",\
322 write_abid.cmd_id, write_abid.acdb_id,\
323 write_abid.set_abid, write_abid.set_iid, cnt);
324 if (write_abid.acdb_id > ACDB_ID_MAX ||
325 write_abid.acdb_id < ACDB_ID_HANDSET_SPKR){
326 rtc_acdb.err = ACDB_RTC_ERR_INVALID_DEVICE;
327 return cnt;
328 }
329
330 rtc_acdb.err = ACDB_RTC_ERR_INVALID_ABID;
331 rtc_acdb.abid = write_abid.set_abid;
332 if (get_feature_id(write_abid.set_abid, \
333 write_abid.set_iid, &feat_id)) {
334 rtc_acdb.err = ACDB_RTC_SUCCESS;
335 rtc_acdb.cmd_id = write_abid.cmd_id;
336 rtc_acdb.acdb_id = write_abid.acdb_id;
337 rtc_acdb.set_abid = feat_id;
338 rtc_acdb.valid_abid = true;
339 rtc_acdb.set_iid = write_abid.set_iid;
340 }
341 return cnt;
342}
343static ssize_t rtc_getsetabid_dbg_read(struct file *file, char __user *buf,
344 size_t count, loff_t *ppos)
345{
346 static char buffer[1024];
347 int n = 0;
348 u32 msg = rtc_acdb.err;
349 memcpy(buffer, &rtc_acdb.cmd_id, sizeof(struct get_abid));
350 memcpy(buffer+16, &msg, 4);
351 n = 20;
352 MM_INFO("SET ABID : Cmd ID: %x Device:%x ABID:%x IID : %x Err: %d\n",\
353 rtc_acdb.cmd_id, rtc_acdb.acdb_id, rtc_acdb.set_abid,\
354 rtc_acdb.set_iid, rtc_acdb.err);
355 return simple_read_from_buffer(buf, count, ppos, buffer, n);
356}
357
358static int rtc_getsetabid_data_dbg_open(struct inode *inode, struct file *file)
359{
360 file->private_data = inode->i_private;
361 MM_INFO("GET-SET ABID DATA Open debug intf %s\n",
362 (char *) file->private_data);
363 return 0;
364}
365
366void acdb_rtc_set_err(u32 err_code)
367{
368 if (rtc_acdb.err == ACDB_RTC_PENDING_RESPONSE) {
369 if (err_code == 0xFFFF) {
370 rtc_acdb.err = ACDB_RTC_SUCCESS;
371 MM_INFO("RTC READ SUCCESS---\n");
372 } else if (err_code == 0) {
373 rtc_acdb.err = ACDB_RTC_DSP_FAILURE;
374 MM_INFO("RTC READ FAIL---\n");
375 } else if (err_code == 1) {
376 rtc_acdb.err = ACDB_RTC_DSP_FEATURE_NOT_AVAILABLE;
377 MM_INFO("RTC READ FEAT UNAVAILABLE---\n");
378 } else {
379 rtc_acdb.err = ACDB_RTC_DSP_FAILURE;
380 MM_INFO("RTC Err CODE---\n");
381 }
382 } else {
383 rtc_acdb.err = ACDB_RTC_DSP_FAILURE;
384 MM_ERR("RTC Err code Invalid State\n");
385 }
386 wake_up(&rtc_acdb.wait);
387}
388
389static ssize_t rtc_getsetabid_data_dbg_read(struct file *file,
390 char __user *buf, size_t count,
391 loff_t *ppos)
392{
393 static char buffer[PMEM_RTC_ACDB_QUERY_MEM];
394 int rc, n = 0;
395 int counter = 0;
396 struct rtc_acdb_pmem *rtc_read = &rtc_acdb.rtc_read;
397 memset(&buffer, 0, PMEM_RTC_ACDB_QUERY_MEM);
398
399 if (rtc_acdb.valid_abid != true) {
400 MM_ERR("ACDB DATA READ ---INVALID ABID\n");
401 n = 0;
402 rtc_acdb.err = ACDB_RTC_ERR_INVALID_ABID;
403 } else {
404 if (PMEM_RTC_ACDB_QUERY_MEM < count) {
405 MM_ERR("ACDB DATA READ ---"\
406 "INVALID READ LEN %x\n", count);
407 n = 0;
408 rtc_acdb.err = ACDB_RTC_ERR_INVALID_LEN;
409 } else {
410 rtc_acdb.err = ACDB_RTC_PENDING_RESPONSE;
411 if (rtc_read->viraddr != NULL) {
412 memset(rtc_read->viraddr,
413 0, PMEM_RTC_ACDB_QUERY_MEM);
414 }
415 if (rtc_acdb.tx_rx_ctl == ACDB_RTC_RX) {
416 struct rtc_audpp_read_data rtc_read_cmd;
417 rtc_read_cmd.cmd_id =
418 AUDPP_CMD_PP_FEAT_QUERY_PARAMS;
419 rtc_read_cmd.obj_id =
420 AUDPP_CMD_COPP_STREAM;
421 rtc_read_cmd.feature_id = rtc_acdb.set_abid;
422 rtc_read_cmd.extbufsizemsw =
423 EXTRACT_HIGH_WORD(\
424 PMEM_RTC_ACDB_QUERY_MEM);
425 rtc_read_cmd.extbufsizelsw =
426 EXTRACT_LOW_WORD(\
427 PMEM_RTC_ACDB_QUERY_MEM);
428 rtc_read_cmd.extpart = 0x0000;
429 rtc_read_cmd.extbufstartmsw =
430 EXTRACT_HIGH_WORD(rtc_read->phys);
431 rtc_read_cmd.extbufstartlsw =
432 EXTRACT_LOW_WORD(rtc_read->phys);
433 rc = audpp_send_queue2(&rtc_read_cmd,
434 sizeof(rtc_read_cmd));
435 } else if (rtc_acdb.tx_rx_ctl == ACDB_RTC_TX) {
436 struct rtc_audpreproc_read_data rtc_audpreproc;
437 rtc_audpreproc.cmd_id =
438 AUDPREPROC_CMD_FEAT_QUERY_PARAMS;
439 rtc_audpreproc.feature_id = rtc_acdb.set_abid;
440 /*AUDREC1 is used for pcm recording */
441 rtc_audpreproc.stream_id = 1;
442 rtc_audpreproc.extbufsizemsw =
443 EXTRACT_HIGH_WORD(\
444 PMEM_RTC_ACDB_QUERY_MEM);
445 rtc_audpreproc.extbufsizelsw =
446 EXTRACT_LOW_WORD(\
447 PMEM_RTC_ACDB_QUERY_MEM);
448 rtc_audpreproc.extpart = 0x0000;
449 rtc_audpreproc.extbufstartmsw =
450 EXTRACT_HIGH_WORD(rtc_read->phys);
451 rtc_audpreproc.extbufstartlsw =
452 EXTRACT_LOW_WORD(rtc_read->phys);
453 rc = audpreproc_send_preproccmdqueue(
454 &rtc_audpreproc,\
455 sizeof(rtc_audpreproc));
456 MM_INFO("ACDB READ Command RC --->%x,"\
457 "stream_id %x\n", rc,
458 acdb_data.preproc_stream_id);
459 }
460 rc = wait_event_timeout(rtc_acdb.wait,
461 (rtc_acdb.err !=
462 ACDB_RTC_PENDING_RESPONSE),
463 msecs_to_jiffies(RTC_MAX_TIMEOUT));
464 MM_INFO("ACDB READ ACK Count = %x Err = %x\n",
465 count, rtc_acdb.err);
466 {
467 if (rtc_acdb.err == ACDB_RTC_SUCCESS
468 && rtc_read->viraddr != NULL) {
469 memcpy(buffer, rtc_read->viraddr, count);
470 n = count;
471 while (counter < count) {
472 MM_DBG("%x", \
473 rtc_read->viraddr[counter]);
474 counter++;
475 }
476 }
477 }
478 }
479 }
480 return simple_read_from_buffer(buf, count, ppos, buffer, n);
481}
482
483static bool acdb_set_tx_rtc(const char *ubuf, size_t writecount)
484{
485 audpreproc_cmd_cfg_iir_tuning_filter_params *preproc_iir;
486 audpreproc_cmd_cfg_agc_params *preproc_agc;
487 audpreproc_cmd_cfg_ns_params *preproc_ns;
488 s32 result = 0;
489 bool retval = false;
490 unsigned short iircmdsize =
491 sizeof(audpreproc_cmd_cfg_iir_tuning_filter_params);
492 unsigned short iircmdid = AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS;
493
494 rtc_acdb.err = ACDB_RTC_ERR_UNKNOWN_FAILURE;
495
496 switch (rtc_acdb.set_abid) {
497
498 case AUDPREPROC_CMD_CFG_AGC_PARAMS:
499 {
500 preproc_agc = kmalloc(sizeof(\
501 audpreproc_cmd_cfg_agc_params),\
502 GFP_KERNEL);
503 if ((sizeof(audpreproc_cmd_cfg_agc_params) -\
504 (sizeof(unsigned short)))
505 < writecount) {
506 MM_ERR("ACDB DATA WRITE --"\
507 "AGC TX writecount > DSP struct\n");
508 } else {
509 if (preproc_agc != NULL) {
510 char *base; unsigned short offset;
511 unsigned short *offset_addr;
512 base = (char *)preproc_agc;
513 offset = offsetof(\
514 audpreproc_cmd_cfg_agc_params,\
515 tx_agc_param_mask);
516 offset_addr = (unsigned short *)(base + offset);
517 if ((copy_from_user(offset_addr,\
518 (void *)ubuf, writecount)) == 0x00) {
519 preproc_agc->cmd_id =
520 AUDPREPROC_CMD_CFG_AGC_PARAMS;
521
522 result = audpreproc_dsp_set_agc(
523 preproc_agc,
524 sizeof(\
525 audpreproc_cmd_cfg_agc_params));
526 if (result) {
527 MM_ERR("ACDB=> Failed to "\
528 "send AGC data to "\
529 "preproc)\n");
530 } else {
531 retval = true;
532 }
533 } else {
534 MM_ERR("ACDB DATA WRITE ---"\
535 "GC Tx copy_from_user Fail\n");
536 }
537 } else {
538 MM_ERR("ACDB DATA WRITE --"\
539 "AGC TX kalloc Failed LEN\n");
540 }
541 }
542 if (preproc_agc != NULL)
543 kfree(preproc_agc);
544 break;
545 }
546 case AUDPREPROC_CMD_CFG_NS_PARAMS:
547 {
548
549 preproc_ns = kmalloc(sizeof(\
550 audpreproc_cmd_cfg_ns_params),\
551 GFP_KERNEL);
552 if ((sizeof(audpreproc_cmd_cfg_ns_params) -\
553 (sizeof(unsigned short)))
554 < writecount) {
555 MM_ERR("ACDB DATA WRITE --"\
556 "NS TX writecount > DSP struct\n");
557 } else {
558 if (preproc_ns != NULL) {
559 char *base; unsigned short offset;
560 unsigned short *offset_addr;
561 base = (char *)preproc_ns;
562 offset = offsetof(\
563 audpreproc_cmd_cfg_ns_params,\
564 ec_mode_new);
565 offset_addr = (unsigned short *)(base + offset);
566 if ((copy_from_user(offset_addr,\
567 (void *)ubuf, writecount)) == 0x00) {
568 preproc_ns->cmd_id =
569 AUDPREPROC_CMD_CFG_NS_PARAMS;
570 result = audpreproc_dsp_set_ns(
571 preproc_ns,
572 sizeof(\
573 audpreproc_cmd_cfg_ns_params));
574 if (result) {
575 MM_ERR("ACDB=> Failed to send "\
576 "NS data to preproc\n");
577 } else {
578 retval = true;
579 }
580 } else {
581 MM_ERR("ACDB DATA WRITE ---NS Tx "\
582 "copy_from_user Fail\n");
583 }
584 } else {
585 MM_ERR("ACDB DATA WRITE --NS TX "\
586 "kalloc Failed LEN\n");
587 }
588 }
589 if (preproc_ns != NULL)
590 kfree(preproc_ns);
591 break;
592 }
593 case AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS:
594 {
595
596 preproc_iir = kmalloc(sizeof(\
597 audpreproc_cmd_cfg_iir_tuning_filter_params),\
598 GFP_KERNEL);
599 if ((sizeof(\
600 audpreproc_cmd_cfg_iir_tuning_filter_params)-\
601 (sizeof(unsigned short)))
602 < writecount) {
603 MM_ERR("ACDB DATA WRITE --IIR TX writecount "\
604 "> DSP struct\n");
605 } else {
606 if (preproc_iir != NULL) {
607 char *base; unsigned short offset;
608 unsigned short *offset_addr;
609 base = (char *)preproc_iir;
610 offset = offsetof(\
611 audpreproc_cmd_cfg_iir_tuning_filter_params,\
612 active_flag);
613 offset_addr = (unsigned short *)(base + \
614 offset);
615 if ((copy_from_user(offset_addr,\
616 (void *)ubuf, writecount)) == 0x00) {
617 preproc_iir->cmd_id = iircmdid;
618 result = audpreproc_dsp_set_iir(\
619 preproc_iir,
620 iircmdsize);
621 if (result) {
622 MM_ERR("ACDB=> Failed to send "\
623 "IIR data to preproc\n");
624 } else {
625 retval = true;
626 }
627 } else {
628 MM_ERR("ACDB DATA WRITE ---IIR Tx "\
629 "copy_from_user Fail\n");
630 }
631 } else {
632 MM_ERR("ACDB DATA WRITE --IIR TX kalloc "\
633 "Failed LEN\n");
634 }
635 }
636 if (preproc_iir != NULL)
637 kfree(preproc_iir);
638 break;
639 }
640 }
641 return retval;
642}
643
644static bool acdb_set_rx_rtc(const char *ubuf, size_t writecount)
645{
646
647 audpp_cmd_cfg_object_params_volume *volpan_config;
648 audpp_cmd_cfg_object_params_mbadrc *mbadrc_config;
649 struct acdb_block_mbadrc_rtc *acdb_mbadrc_rtc;
650 audpp_cmd_cfg_object_params_eqalizer *eq_config;
651 audpp_cmd_cfg_object_params_pcm *iir_config;
652 struct rtc_acdb_pmem *rtc_write = &rtc_acdb.rtc_write;
653 s32 result = 0;
654 bool retval = false;
655
656 switch (rtc_acdb.set_abid) {
657 case AUDPP_CMD_VOLUME_PAN:
658 {
659 volpan_config = kmalloc(sizeof(\
660 audpp_cmd_cfg_object_params_volume),\
661 GFP_KERNEL);
662 if ((sizeof(audpp_cmd_cfg_object_params_volume) -\
663 sizeof(audpp_cmd_cfg_object_params_common))
664 < writecount) {
665 MM_ERR("ACDB DATA WRITE -- "\
666 "VolPan writecount > DSP struct\n");
667 } else {
668 if (volpan_config != NULL) {
669 char *base; unsigned short offset;
670 unsigned short *offset_addr;
671 base = (char *)volpan_config;
672 offset = offsetof(\
673 audpp_cmd_cfg_object_params_volume,\
674 volume);
675 offset_addr = (unsigned short *)(base+offset);
676 if ((copy_from_user(offset_addr,\
677 (void *)ubuf, writecount)) == 0x00) {
678 MM_ERR("ACDB RX WRITE DATA: "\
679 "AUDPP_CMD_VOLUME_PAN\n");
680 result = audpp_set_volume_and_pan(
681 COMMON_OBJ_ID,
682 volpan_config->volume,
683 volpan_config->pan);
684 if (result) {
685 MM_ERR("ACDB=> Failed to "\
686 "send VOLPAN data to"
687 " postproc\n");
688 } else {
689 retval = true;
690 }
691 } else {
692 MM_ERR("ACDB DATA WRITE ---"\
693 "copy_from_user Fail\n");
694 }
695 } else {
696 MM_ERR("ACDB DATA WRITE --"\
697 "Vol Pan kalloc Failed LEN\n");
698 }
699 }
700 if (volpan_config != NULL)
701 kfree(volpan_config);
702 break;
703 }
704
705 case AUDPP_CMD_IIR_TUNING_FILTER:
706 {
707 iir_config = kmalloc(sizeof(\
708 audpp_cmd_cfg_object_params_pcm),\
709 GFP_KERNEL);
710 if ((sizeof(audpp_cmd_cfg_object_params_pcm) -\
711 sizeof(audpp_cmd_cfg_object_params_common))
712 < writecount) {
713 MM_ERR("ACDB DATA WRITE --"\
714 "IIR RX writecount > DSP struct\n");
715 } else {
716 if (iir_config != NULL) {
717 char *base; unsigned short offset;
718 unsigned short *offset_addr;
719 base = (char *)iir_config;
720 offset = offsetof(\
721 audpp_cmd_cfg_object_params_pcm,\
722 active_flag);
723 offset_addr = (unsigned short *)(base+offset);
724 if ((copy_from_user(offset_addr,\
725 (void *)ubuf, writecount)) == 0x00) {
726 MM_ERR("ACDB RX WRITE DATA:"\
727 "AUDPP_CMD_IIR_TUNING_FILTER\n");
728 result = audpp_dsp_set_rx_iir(
729 COMMON_OBJ_ID,
730 iir_config->active_flag,\
731 iir_config);
732 if (result) {
733 MM_ERR("ACDB=> Failed to send"\
734 "IIR data to"\
735 "postproc\n");
736 } else {
737 retval = true;
738 }
739 } else {
740 MM_ERR("ACDB DATA WRITE ---"\
741 "IIR Rx copy_from_user Fail\n");
742 }
743 } else {
744 MM_ERR("ACDB DATA WRITE --"\
745 "acdb_iir_block kalloc Failed LEN\n");
746 }
747 }
748 if (iir_config != NULL)
749 kfree(iir_config);
750 break;
751 }
752 case AUDPP_CMD_EQUALIZER:
753 {
754 eq_config = kmalloc(sizeof(\
755 audpp_cmd_cfg_object_params_eqalizer),\
756 GFP_KERNEL);
757 if ((sizeof(audpp_cmd_cfg_object_params_eqalizer) -\
758 sizeof(audpp_cmd_cfg_object_params_common))
759 < writecount) {
760 MM_ERR("ACDB DATA WRITE --"\
761 "EQ RX writecount > DSP struct\n");
762 } else {
763 if (eq_config != NULL) {
764 char *base; unsigned short offset;
765 unsigned short *offset_addr;
766 base = (char *)eq_config;
767 offset = offsetof(\
768 audpp_cmd_cfg_object_params_eqalizer,\
769 eq_flag);
770 offset_addr = (unsigned short *)(base+offset);
771 if ((copy_from_user(offset_addr,\
772 (void *)ubuf, writecount)) == 0x00) {
773 MM_ERR("ACDB RX WRITE"\
774 "DATA:AUDPP_CMD_EQUALIZER\n");
775 result = audpp_dsp_set_eq(
776 COMMON_OBJ_ID,
777 eq_config->eq_flag,\
778 eq_config);
779 if (result) {
780 MM_ERR("ACDB=> Failed to "\
781 "send EQ data to postproc\n");
782 } else {
783 retval = true;
784 }
785 } else {
786 MM_ERR("ACDB DATA WRITE ---"\
787 "EQ Rx copy_from_user Fail\n");
788 }
789 } else {
790 MM_ERR("ACDB DATA WRITE --"\
791 "EQ kalloc Failed LEN\n");
792 }
793 }
794 if (eq_config != NULL)
795 kfree(eq_config);
796 break;
797 }
798
799 case AUDPP_CMD_MBADRC:
800 {
801 acdb_mbadrc_rtc = kmalloc(sizeof(struct \
802 acdb_block_mbadrc_rtc),\
803 GFP_KERNEL);
804 mbadrc_config = kmalloc(sizeof(\
805 audpp_cmd_cfg_object_params_mbadrc),\
806 GFP_KERNEL);
807 if (mbadrc_config != NULL && acdb_mbadrc_rtc != NULL) {
808 if ((copy_from_user(acdb_mbadrc_rtc,\
809 (void *)ubuf,
810 sizeof(struct acdb_block_mbadrc_rtc)))
811 == 0x00) {
812
813 memset(mbadrc_config, 0,
814 sizeof(\
815 audpp_cmd_cfg_object_params_mbadrc));
816
817 mbadrc_config->enable =
818 acdb_mbadrc_rtc->enable;
819 mbadrc_config->num_bands =
820 acdb_mbadrc_rtc->num_bands;
821 mbadrc_config->down_samp_level =
822 acdb_mbadrc_rtc->down_samp_level;
823 mbadrc_config->adrc_delay =
824 acdb_mbadrc_rtc->adrc_delay;
825 memcpy(mbadrc_config->adrc_band,\
826 acdb_mbadrc_rtc->adrc_band,\
827 AUDPP_MAX_MBADRC_BANDS *\
828 sizeof(struct adrc_config));
829 if (mbadrc_config->num_bands > 1) {
830 mbadrc_config->ext_buf_size =
831 (97 * 2) + (33 * 2 * \
832 (mbadrc_config->num_bands - 2));
833 }
834 mbadrc_config->ext_partition = 0;
835 mbadrc_config->ext_buf_lsw =
836 (u16) EXTRACT_LOW_WORD(\
837 rtc_write->phys);
838 mbadrc_config->ext_buf_msw =
839 (u16) EXTRACT_HIGH_WORD(\
840 rtc_write->phys);
841 memcpy(rtc_write->viraddr,
842 acdb_mbadrc_rtc->ext_buff,
843 (196*sizeof(signed int)));
844 result = audpp_dsp_set_mbadrc(
845 COMMON_OBJ_ID,
846 mbadrc_config->enable,
847 mbadrc_config);
848 if (result) {
849 MM_ERR("ACDB=> Failed to "\
850 "Send MBADRC data "\
851 "to postproc\n");
852 } else {
853 retval = true;
854 }
855 } else {
856 MM_ERR("ACDB DATA WRITE ---"\
857 "MBADRC Rx copy_from_user Fail\n");
858 }
859 } else {
860 MM_ERR("ACDB DATA WRITE --MBADRC kalloc Failed LEN\n");
861 }
862 if (mbadrc_config != NULL)
863 kfree(mbadrc_config);
864 if (acdb_mbadrc_rtc != NULL)
865 kfree(acdb_mbadrc_rtc);
866 break;
867 }
868 }
869 return retval;
870}
871static ssize_t rtc_getsetabid_data_dbg_write(struct file *filp,
872 const char __user *ubuf,
873 size_t cnt, loff_t *ppos)
874{
875 if (rtc_acdb.valid_abid != true) {
876 MM_INFO("ACDB DATA READ ---INVALID ABID\n");
877 rtc_acdb.err = ACDB_RTC_ERR_INVALID_ABID;
878 } else {
879 if (rtc_acdb.tx_rx_ctl == ACDB_RTC_RX) {
880 if (acdb_set_rx_rtc(ubuf, cnt)) {
881 rtc_acdb.err = ACDB_RTC_SUCCESS;
882 } else {
883 rtc_acdb.err = ACDB_RTC_ERR_UNKNOWN_FAILURE;
884 cnt = 0;
885 }
886 } else if (rtc_acdb.tx_rx_ctl == ACDB_RTC_TX) {
887 if (acdb_set_tx_rtc(ubuf, cnt)) {
888 rtc_acdb.err = ACDB_RTC_SUCCESS;
889 } else {
890 rtc_acdb.err = ACDB_RTC_ERR_UNKNOWN_FAILURE;
891 cnt = 0;
892 }
893 }
894 }
895 return cnt;
896}
897
898
899static const struct file_operations rtc_acdb_data_debug_fops = {
900 .open = rtc_getsetabid_data_dbg_open,
901 .write = rtc_getsetabid_data_dbg_write,
902 .read = rtc_getsetabid_data_dbg_read
903};
904
905static const struct file_operations rtc_acdb_debug_fops = {
906 .open = rtc_getsetabid_dbg_open,
907 .write = rtc_getsetabid_dbg_write,
908 .read = rtc_getsetabid_dbg_read
909};
910
911static void rtc_acdb_deinit(void)
912{
913 struct rtc_acdb_pmem *rtc_read = &rtc_acdb.rtc_read;
914 struct rtc_acdb_pmem *rtc_write = &rtc_acdb.rtc_write;
915 if (get_set_abid_dentry) {
916 MM_DBG("GetSet ABID remove debugfs\n");
917 debugfs_remove(get_set_abid_dentry);
918 }
919
920 if (get_set_abid_data_dentry) {
921 MM_DBG("GetSet ABID remove debugfs\n");
922 debugfs_remove(get_set_abid_data_dentry);
923 }
924 rtc_acdb.abid = 0;
925 rtc_acdb.acdb_id = 0;
926 rtc_acdb.cmd_id = 0;
927 rtc_acdb.err = 1;
928 rtc_acdb.set_abid = 0;
929 rtc_acdb.set_iid = 0;
930 rtc_acdb.tx_rx_ctl = 0;
931 rtc_acdb.valid_abid = false;
932
933 if (rtc_read->viraddr != NULL || ((void *)rtc_read->phys) != NULL) {
934 iounmap(rtc_read->map_v_rtc);
935 free_contiguous_memory_by_paddr(rtc_read->phys);
936 }
937 if (rtc_write->viraddr != NULL || ((void *)rtc_write->phys) != NULL) {
938 iounmap(rtc_write->map_v_rtc);
939 free_contiguous_memory_by_paddr(rtc_write->phys);
940 }
941}
942
943static bool rtc_acdb_init(void)
944{
945 struct rtc_acdb_pmem *rtc_read = &rtc_acdb.rtc_read;
946 struct rtc_acdb_pmem *rtc_write = &rtc_acdb.rtc_write;
947 s32 result = 0;
948 char name[sizeof "get_set_abid"+1];
949 char name1[sizeof "get_set_abid_data"+1];
950 rtc_acdb.abid = 0;
951 rtc_acdb.acdb_id = 0;
952 rtc_acdb.cmd_id = 0;
953 rtc_acdb.err = 1;
954 rtc_acdb.set_abid = 0;
955 rtc_acdb.set_iid = 0;
956 rtc_acdb.valid_abid = false;
957 rtc_acdb.tx_rx_ctl = 0;
958
959 snprintf(name, sizeof name, "get_set_abid");
960 get_set_abid_dentry = debugfs_create_file(name,
961 S_IFREG | S_IRUGO | S_IWUGO,
962 NULL, NULL, &rtc_acdb_debug_fops);
963 if (IS_ERR(get_set_abid_dentry)) {
964 MM_ERR("SET GET ABID debugfs_create_file failed\n");
965 return false;
966 }
967
968 snprintf(name1, sizeof name1, "get_set_abid_data");
969 get_set_abid_data_dentry = debugfs_create_file(name1,
970 S_IFREG | S_IRUGO | S_IWUGO,
971 NULL, NULL,
972 &rtc_acdb_data_debug_fops);
973 if (IS_ERR(get_set_abid_data_dentry)) {
974 MM_ERR("SET GET ABID DATA"\
975 " debugfs_create_file failed\n");
976 return false;
977 }
978
979 rtc_read->phys = allocate_contiguous_ebi_nomap(PMEM_RTC_ACDB_QUERY_MEM,
980 SZ_4K);
981
982 if (!rtc_read->phys) {
983 MM_ERR("ACDB Cannot allocate physical memory\n");
984 result = -ENOMEM;
985 goto error;
986 }
987 rtc_read->map_v_rtc = ioremap(rtc_read->phys,
988 PMEM_RTC_ACDB_QUERY_MEM);
989
990 if (IS_ERR(rtc_read->map_v_rtc)) {
991 MM_ERR("ACDB Could not map physical address\n");
992 result = -ENOMEM;
993 goto error;
994 }
995 rtc_read->viraddr = rtc_read->map_v_rtc;
996 memset(rtc_read->viraddr, 0, PMEM_RTC_ACDB_QUERY_MEM);
997
998 rtc_write->phys = allocate_contiguous_ebi_nomap(PMEM_RTC_ACDB_QUERY_MEM,
999 SZ_4K);
1000
1001 if (!rtc_write->phys) {
1002 MM_ERR("ACDB Cannot allocate physical memory\n");
1003 result = -ENOMEM;
1004 goto error;
1005 }
1006 rtc_write->map_v_rtc = ioremap(rtc_write->phys,
1007 PMEM_RTC_ACDB_QUERY_MEM);
1008
1009 if (IS_ERR(rtc_write->map_v_rtc)) {
1010 MM_ERR("ACDB Could not map physical address\n");
1011 result = -ENOMEM;
1012 goto error;
1013 }
1014 rtc_write->viraddr = rtc_write->map_v_rtc;
1015 memset(rtc_write->viraddr, 0, PMEM_RTC_ACDB_QUERY_MEM);
1016 init_waitqueue_head(&rtc_acdb.wait);
1017 return true;
1018error:
1019 MM_DBG("INIT RTC FAILED REMOVING RTC DEBUG FS\n");
1020 if (get_set_abid_dentry) {
1021 MM_DBG("GetSet ABID remove debugfs\n");
1022 debugfs_remove(get_set_abid_dentry);
1023 }
1024
1025 if (get_set_abid_data_dentry) {
1026 MM_DBG("GetSet ABID remove debugfs\n");
1027 debugfs_remove(get_set_abid_data_dentry);
1028 }
1029 if (rtc_read->viraddr != NULL || ((void *)rtc_read->phys) != NULL) {
1030 iounmap(rtc_read->map_v_rtc);
1031 free_contiguous_memory_by_paddr(rtc_read->phys);
1032 }
1033 if (rtc_write->viraddr != NULL || ((void *)rtc_write->phys) != NULL) {
1034 iounmap(rtc_write->map_v_rtc);
1035 free_contiguous_memory_by_paddr(rtc_write->phys);
1036 }
1037 return false;
1038}
1039#else
1040void acdb_rtc_set_err(u32 err_code)
1041{
1042 return 0
1043}
1044#endif /*CONFIG_DEBUG_FS*/
1045static s32 acdb_set_calibration_blk(unsigned long arg)
1046{
1047 struct acdb_cmd_device acdb_cmd;
1048 s32 result = 0;
1049
1050 MM_DBG("acdb_set_calibration_blk\n");
1051 if (copy_from_user(&acdb_cmd, (struct acdb_cmd_device *)arg,
1052 sizeof(acdb_cmd))) {
1053 MM_ERR("Failed copy command struct from user in"\
1054 "acdb_set_calibration_blk\n");
1055 return -EFAULT;
1056 }
1057 acdb_cmd.phys_buf = (u32 *)acdb_data.paddr;
1058
1059 MM_DBG("acdb_cmd.phys_buf %x\n", (u32)acdb_cmd.phys_buf);
1060
1061 result = dalrpc_fcn_8(ACDB_DAL_IOCTL, acdb_data.handle,
1062 (const void *)&acdb_cmd, sizeof(acdb_cmd),
1063 &acdb_data.acdb_result,
1064 sizeof(acdb_data.acdb_result));
1065
1066 if (result < 0) {
1067 MM_ERR("ACDB=> Device Set RPC failure"\
1068 " result = %d\n", result);
1069 return -EINVAL;
1070 } else {
1071 MM_ERR("ACDB=> Device Set RPC success\n");
1072 if (acdb_data.acdb_result.result == ACDB_RES_SUCCESS)
1073 MM_DBG("ACDB_SET_DEVICE Success\n");
1074 else if (acdb_data.acdb_result.result == ACDB_RES_FAILURE)
1075 MM_ERR("ACDB_SET_DEVICE Failure\n");
1076 else if (acdb_data.acdb_result.result == ACDB_RES_BADPARM)
1077 MM_ERR("ACDB_SET_DEVICE BadParams\n");
1078 else
1079 MM_ERR("Unknown error\n");
1080 }
1081 return result;
1082}
1083
1084static s32 acdb_get_calibration_blk(unsigned long arg)
1085{
1086 s32 result = 0;
1087 struct acdb_cmd_device acdb_cmd;
1088
1089 MM_DBG("acdb_get_calibration_blk\n");
1090
1091 if (copy_from_user(&acdb_cmd, (struct acdb_cmd_device *)arg,
1092 sizeof(acdb_cmd))) {
1093 MM_ERR("Failed copy command struct from user in"\
1094 "acdb_get_calibration_blk\n");
1095 return -EFAULT;
1096 }
1097 acdb_cmd.phys_buf = (u32 *)acdb_data.paddr;
1098 MM_ERR("acdb_cmd.phys_buf %x\n", (u32)acdb_cmd.phys_buf);
1099
1100 result = dalrpc_fcn_8(ACDB_DAL_IOCTL, acdb_data.handle,
1101 (const void *)&acdb_cmd, sizeof(acdb_cmd),
1102 &acdb_data.acdb_result,
1103 sizeof(acdb_data.acdb_result));
1104
1105 if (result < 0) {
1106 MM_ERR("ACDB=> Device Get RPC failure"\
1107 " result = %d\n", result);
1108 return -EINVAL;
1109 } else {
1110 MM_ERR("ACDB=> Device Get RPC Success\n");
1111 if (acdb_data.acdb_result.result == ACDB_RES_SUCCESS)
1112 MM_DBG("ACDB_GET_DEVICE Success\n");
1113 else if (acdb_data.acdb_result.result == ACDB_RES_FAILURE)
1114 MM_ERR("ACDB_GET_DEVICE Failure\n");
1115 else if (acdb_data.acdb_result.result == ACDB_RES_BADPARM)
1116 MM_ERR("ACDB_GET_DEVICE BadParams\n");
1117 else
1118 MM_ERR("Unknown error\n");
1119 }
1120 return result;
1121}
1122
1123static int audio_acdb_open(struct inode *inode, struct file *file)
1124{
1125 MM_DBG("%s\n", __func__);
1126 return 0;
1127}
1128static int audio_acdb_release(struct inode *inode, struct file *file)
1129{
1130 MM_DBG("%s\n", __func__);
1131 return 0;
1132}
1133
1134static long audio_acdb_ioctl(struct file *file, unsigned int cmd,
1135 unsigned long arg)
1136{
1137 int rc = 0;
1138 unsigned long flags = 0;
1139 struct msm_audio_pmem_info info;
1140
1141 MM_DBG("%s\n", __func__);
1142
1143 switch (cmd) {
1144 case AUDIO_SET_EQ:
1145 MM_DBG("IOCTL SET_EQ_CONFIG\n");
1146 if (copy_from_user(&acdb_data.eq.num_bands, (void *) arg,
1147 sizeof(acdb_data.eq) -
1148 (AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN + 2))) {
1149 rc = -EFAULT;
1150 break;
1151 }
1152 spin_lock_irqsave(&acdb_data.dsp_lock, flags);
1153 rc = audpp_dsp_set_eq(COMMON_OBJ_ID, 1,
1154 &acdb_data.eq);
1155 if (rc < 0)
1156 MM_ERR("AUDPP returned err =%d\n", rc);
1157 spin_unlock_irqrestore(&acdb_data.dsp_lock, flags);
1158 break;
1159 case AUDIO_REGISTER_PMEM:
1160 MM_DBG("AUDIO_REGISTER_PMEM\n");
1161 if (copy_from_user(&info, (void *) arg, sizeof(info))) {
1162 MM_ERR("Cannot copy from user\n");
1163 return -EFAULT;
1164 }
1165 rc = get_pmem_file(info.fd, &acdb_data.paddr,
1166 &acdb_data.kvaddr,
1167 &acdb_data.pmem_len,
1168 &acdb_data.file);
1169 if (rc == 0)
1170 acdb_data.pmem_fd = info.fd;
1171 break;
1172 case AUDIO_DEREGISTER_PMEM:
1173 if (acdb_data.pmem_fd)
1174 put_pmem_file(acdb_data.file);
1175 break;
1176 case AUDIO_SET_ACDB_BLK:
1177 MM_DBG("IOCTL AUDIO_SET_ACDB_BLK\n");
1178 rc = acdb_set_calibration_blk(arg);
1179 break;
1180 case AUDIO_GET_ACDB_BLK:
1181 MM_DBG("IOiCTL AUDIO_GET_ACDB_BLK\n");
1182 rc = acdb_get_calibration_blk(arg);
1183 break;
1184 default:
1185 MM_DBG("Unknown IOCTL%d\n", cmd);
1186 rc = -EINVAL;
1187 }
1188 return rc;
1189}
1190
1191static const struct file_operations acdb_fops = {
1192 .owner = THIS_MODULE,
1193 .open = audio_acdb_open,
1194 .release = audio_acdb_release,
1195 .llseek = no_llseek,
1196 .unlocked_ioctl = audio_acdb_ioctl
1197};
1198
1199struct miscdevice acdb_misc = {
1200 .minor = MISC_DYNAMIC_MINOR,
1201 .name = "msm_acdb",
1202 .fops = &acdb_fops,
1203};
1204
1205static s32 acdb_get_calibration(void)
1206{
1207 struct acdb_cmd_get_device_table acdb_cmd;
1208 s32 result = 0;
1209 u32 iterations = 0;
1210
1211 MM_DBG("acdb state = %d\n", acdb_data.acdb_state);
1212
1213 acdb_cmd.command_id = ACDB_GET_DEVICE_TABLE;
1214 acdb_cmd.device_id = acdb_data.device_info->acdb_id;
1215 acdb_cmd.network_id = 0x0108B153;
1216 acdb_cmd.sample_rate_id = acdb_data.device_info->sample_rate;
1217 acdb_cmd.total_bytes = ACDB_BUF_SIZE;
1218 acdb_cmd.phys_buf = (u32 *)acdb_data.phys_addr;
1219 MM_DBG("device_id = %d, sampling_freq = %d\n",
1220 acdb_cmd.device_id, acdb_cmd.sample_rate_id);
1221
1222 do {
1223 result = dalrpc_fcn_8(ACDB_DAL_IOCTL, acdb_data.handle,
1224 (const void *)&acdb_cmd, sizeof(acdb_cmd),
1225 &acdb_data.acdb_result,
1226 sizeof(acdb_data.acdb_result));
1227
1228 if (result < 0) {
1229 MM_ERR("ACDB=> Device table RPC failure"\
1230 " result = %d\n", result);
1231 goto error;
1232 }
1233 /*following check is introduced to handle boot up race
1234 condition between AUDCAL SW peers running on apps
1235 and modem (ACDB_RES_BADSTATE indicates modem AUDCAL SW is
1236 not in initialized sate) we need to retry to get ACDB
1237 values*/
1238 if (acdb_data.acdb_result.result == ACDB_RES_BADSTATE) {
1239 msleep(500);
1240 iterations++;
1241 } else if (acdb_data.acdb_result.result == ACDB_RES_SUCCESS) {
1242 MM_DBG("Modem query for acdb values is successful"\
1243 " (iterations = %d)\n", iterations);
1244 acdb_data.acdb_state |= CAL_DATA_READY;
1245 return result;
1246 } else {
1247 MM_ERR("ACDB=> modem failed to fill acdb values,"\
1248 " reuslt = %d, (iterations = %d)\n",
1249 acdb_data.acdb_result.result,
1250 iterations);
1251 goto error;
1252 }
1253 } while (iterations < MAX_RETRY);
1254 MM_ERR("ACDB=> AUDCAL SW on modem is not in intiailized state (%d)\n",
1255 acdb_data.acdb_result.result);
1256error:
1257 result = -EINVAL;
1258 return result;
1259}
1260
1261s32 acdb_get_calibration_data(struct acdb_get_block *get_block)
1262{
1263 s32 result = -EINVAL;
1264 struct acdb_cmd_device acdb_cmd;
1265 struct acdb_result acdb_result;
1266
1267 MM_DBG("acdb_get_calibration_data\n");
1268
1269 acdb_cmd.command_id = ACDB_GET_DEVICE;
1270 acdb_cmd.network_id = 0x0108B153;
1271 acdb_cmd.device_id = get_block->acdb_id;
1272 acdb_cmd.sample_rate_id = get_block->sample_rate_id;
1273 acdb_cmd.interface_id = get_block->interface_id;
1274 acdb_cmd.algorithm_block_id = get_block->algorithm_block_id;
1275 acdb_cmd.total_bytes = get_block->total_bytes;
1276 acdb_cmd.phys_buf = (u32 *)acdb_data.get_blk_paddr;
1277
1278 result = dalrpc_fcn_8(ACDB_DAL_IOCTL, acdb_data.handle,
1279 (const void *)&acdb_cmd, sizeof(acdb_cmd),
1280 &acdb_result,
1281 sizeof(acdb_result));
1282
1283 if (result < 0) {
1284 MM_ERR("ACDB=> Device Get RPC failure"\
1285 " result = %d\n", result);
1286 goto err_state;
1287 } else {
1288 MM_DBG("ACDB=> Device Get RPC Success\n");
1289 if (acdb_result.result == ACDB_RES_SUCCESS) {
1290 MM_DBG("ACDB_GET_DEVICE Success\n");
1291 result = 0;
1292 memcpy(get_block->buf_ptr, acdb_data.get_blk_kvaddr,
1293 get_block->total_bytes);
1294 } else if (acdb_result.result == ACDB_RES_FAILURE)
1295 MM_ERR("ACDB_GET_DEVICE Failure\n");
1296 else if (acdb_result.result == ACDB_RES_BADPARM)
1297 MM_ERR("ACDB_GET_DEVICE BadParams\n");
1298 else
1299 MM_ERR("Unknown error\n");
1300 }
1301err_state:
1302 return result;
1303}
1304EXPORT_SYMBOL(acdb_get_calibration_data);
1305
Manish Dewanganfafafaf2013-01-02 17:43:56 +05301306int is_acdb_enabled()
1307{
1308 if (acdb_data.handle != NULL)
1309 return 1;
1310 else
1311 return 0;
1312}
1313EXPORT_SYMBOL(is_acdb_enabled);
1314
Manish Dewanganca859722012-07-09 18:21:42 +05301315static u8 check_device_info_already_present(
1316 struct dev_evt_msg device_info,
1317 struct acdb_cache_node *acdb_cache_free_node)
1318{
1319 if ((device_info.sample_rate ==
1320 acdb_cache_free_node->device_info.\
1321 sample_rate) &&
1322 (device_info.acdb_id ==
1323 acdb_cache_free_node->device_info.acdb_id)) {
1324 MM_DBG("acdb values are already present\n");
1325 /*if acdb state is not set for CAL_DATA_READY and node status
1326 is filled, acdb state should be updated with CAL_DATA_READY
1327 state*/
1328 acdb_data.acdb_state |= CAL_DATA_READY;
1329 return 1; /*node is present but status as filled*/
1330 }
1331 MM_DBG("copying device info into node\n");
1332 /*as device information is not present in cache copy
1333 the current device information into the node*/
1334 memcpy(&acdb_cache_free_node->device_info,
1335 &device_info, sizeof(device_info));
1336 return 0; /*cant find the node*/
1337}
1338
1339static struct acdb_iir_block *get_audpp_irr_block(void)
1340{
1341 struct header *prs_hdr;
1342 u32 index = 0;
1343
1344 while (index < acdb_data.acdb_result.used_bytes) {
1345 prs_hdr = (struct header *)(acdb_data.virt_addr + index);
1346 if (prs_hdr->dbor_signature == DBOR_SIGNATURE) {
1347 if (prs_hdr->abid == ABID_AUDIO_IIR_RX) {
1348 if (prs_hdr->iid == IID_AUDIO_IIR_COEFF)
1349 return (struct acdb_iir_block *)
1350 (acdb_data.virt_addr + index
1351 + sizeof(struct header));
1352 } else {
1353 index += prs_hdr->data_len +
1354 sizeof(struct header);
1355 }
1356 } else {
1357 break;
1358 }
1359 }
1360 return NULL;
1361}
1362
1363
1364static s32 acdb_fill_audpp_iir(void)
1365{
1366 struct acdb_iir_block *acdb_iir;
1367 s32 i = 0;
1368
1369 acdb_iir = get_audpp_irr_block();
1370 if (acdb_iir == NULL) {
1371 MM_ERR("unable to find audpp iir block returning\n");
1372 return -EINVAL;
1373 }
1374 memset(acdb_data.pp_iir, 0, sizeof(*acdb_data.pp_iir));
1375
1376 acdb_data.pp_iir->active_flag = acdb_iir->enable_flag;
1377 acdb_data.pp_iir->num_bands = acdb_iir->stage_count;
1378 for (; i < acdb_iir->stage_count; i++) {
1379 acdb_data.pp_iir->params_filter.filter_4_params.
1380 numerator_filter[i].numerator_b0_filter_lsw =
1381 acdb_iir->stages[i].b0_lo;
1382 acdb_data.pp_iir->params_filter.filter_4_params.
1383 numerator_filter[i].numerator_b0_filter_msw =
1384 acdb_iir->stages[i].b0_hi;
1385 acdb_data.pp_iir->params_filter.filter_4_params.
1386 numerator_filter[i].numerator_b1_filter_lsw =
1387 acdb_iir->stages[i].b1_lo;
1388 acdb_data.pp_iir->params_filter.filter_4_params.
1389 numerator_filter[i].numerator_b1_filter_msw =
1390 acdb_iir->stages[i].b1_hi;
1391 acdb_data.pp_iir->params_filter.filter_4_params.
1392 numerator_filter[i].numerator_b2_filter_lsw =
1393 acdb_iir->stages[i].b2_lo;
1394 acdb_data.pp_iir->params_filter.filter_4_params.
1395 numerator_filter[i].numerator_b2_filter_msw =
1396 acdb_iir->stages[i].b2_hi;
1397 acdb_data.pp_iir->params_filter.filter_4_params.
1398 denominator_filter[i].denominator_a0_filter_lsw =
1399 acdb_iir->stages_a[i].a1_lo;
1400 acdb_data.pp_iir->params_filter.filter_4_params.
1401 denominator_filter[i].denominator_a0_filter_msw =
1402 acdb_iir->stages_a[i].a1_hi;
1403 acdb_data.pp_iir->params_filter.filter_4_params.
1404 denominator_filter[i].denominator_a1_filter_lsw =
1405 acdb_iir->stages_a[i].a2_lo;
1406 acdb_data.pp_iir->params_filter.filter_4_params.
1407 denominator_filter[i].denominator_a1_filter_msw =
1408 acdb_iir->stages_a[i].a2_hi;
1409 acdb_data.pp_iir->params_filter.filter_4_params.
1410 shift_factor_filter[i].shift_factor_0 =
1411 acdb_iir->shift_factor[i];
1412 acdb_data.pp_iir->params_filter.filter_4_params.pan_filter[i].
1413 pan_filter_0 = acdb_iir->pan[i];
1414 }
1415 return 0;
1416}
1417
1418static void extract_mbadrc(u32 *phy_addr, struct header *prs_hdr, u32 *index)
1419{
1420 if (prs_hdr->iid == IID_MBADRC_EXT_BUFF) {
1421 MM_DBG("Got IID = IID_MBADRC_EXT_BUFF\n");
1422 *phy_addr = acdb_data.phys_addr + *index +
1423 sizeof(struct header);
1424 memcpy(acdb_data.mbadrc_block.ext_buf,
1425 (acdb_data.virt_addr + *index +
1426 sizeof(struct header)), 196*2);
1427 MM_DBG("phy_addr = %x\n", *phy_addr);
1428 *index += prs_hdr->data_len + sizeof(struct header);
1429 } else if (prs_hdr->iid == IID_MBADRC_BAND_CONFIG) {
1430 MM_DBG("Got IID == IID_MBADRC_BAND_CONFIG\n");
1431 memcpy(acdb_data.mbadrc_block.band_config, (acdb_data.virt_addr
1432 + *index + sizeof(struct header)),
1433 sizeof(struct mbadrc_band_config_type) *
1434 acdb_data.mbadrc_block.parameters.\
1435 mbadrc_num_bands);
1436 *index += prs_hdr->data_len + sizeof(struct header);
1437 } else if (prs_hdr->iid == IID_MBADRC_PARAMETERS) {
1438 struct mbadrc_parameter *tmp;
1439 tmp = (struct mbadrc_parameter *)(acdb_data.virt_addr + *index
1440 + sizeof(struct header));
1441 MM_DBG("Got IID == IID_MBADRC_PARAMETERS");
1442 acdb_data.mbadrc_block.parameters.mbadrc_enable =
1443 tmp->mbadrc_enable;
1444 acdb_data.mbadrc_block.parameters.mbadrc_num_bands =
1445 tmp->mbadrc_num_bands;
1446 acdb_data.mbadrc_block.parameters.mbadrc_down_sample_level =
1447 tmp->mbadrc_down_sample_level;
1448 acdb_data.mbadrc_block.parameters.mbadrc_delay =
1449 tmp->mbadrc_delay;
1450 *index += prs_hdr->data_len + sizeof(struct header);
1451 }
1452}
1453
1454static void get_audpp_mbadrc_block(u32 *phy_addr)
1455{
1456 struct header *prs_hdr;
1457 u32 index = 0;
1458
1459 while (index < acdb_data.acdb_result.used_bytes) {
1460 prs_hdr = (struct header *)(acdb_data.virt_addr + index);
1461
1462 if (prs_hdr->dbor_signature == DBOR_SIGNATURE) {
1463 if (prs_hdr->abid == ABID_AUDIO_MBADRC_RX) {
1464 if ((prs_hdr->iid == IID_MBADRC_EXT_BUFF)
1465 || (prs_hdr->iid ==
1466 IID_MBADRC_BAND_CONFIG)
1467 || (prs_hdr->iid ==
1468 IID_MBADRC_PARAMETERS)) {
1469 extract_mbadrc(phy_addr, prs_hdr,
1470 &index);
1471 }
1472 } else {
1473 index += prs_hdr->data_len +
1474 sizeof(struct header);
1475 }
1476 } else {
1477 break;
1478 }
1479 }
1480}
1481
1482static s32 acdb_fill_audpp_mbadrc(void)
1483{
1484 u32 mbadrc_phys_addr = -1;
1485 get_audpp_mbadrc_block(&mbadrc_phys_addr);
1486 if (IS_ERR_VALUE(mbadrc_phys_addr)) {
1487 MM_ERR("failed to get mbadrc block\n");
1488 return -EINVAL;
1489 }
1490
1491 memset(acdb_data.pp_mbadrc, 0, sizeof(*acdb_data.pp_mbadrc));
1492
1493 acdb_data.pp_mbadrc->enable = acdb_data.mbadrc_block.\
1494 parameters.mbadrc_enable;
1495 acdb_data.pp_mbadrc->num_bands =
1496 acdb_data.mbadrc_block.\
1497 parameters.mbadrc_num_bands;
1498 acdb_data.pp_mbadrc->down_samp_level =
1499 acdb_data.mbadrc_block.parameters.\
1500 mbadrc_down_sample_level;
1501 acdb_data.pp_mbadrc->adrc_delay =
1502 acdb_data.mbadrc_block.parameters.\
1503 mbadrc_delay;
1504
1505 if (acdb_data.mbadrc_block.parameters.mbadrc_num_bands > 1)
1506 acdb_data.pp_mbadrc->ext_buf_size = (97 * 2) +
1507 (33 * 2 * (acdb_data.mbadrc_block.parameters.\
1508 mbadrc_num_bands - 2));
1509
1510 acdb_data.pp_mbadrc->ext_partition = 0;
1511 acdb_data.pp_mbadrc->ext_buf_lsw = (u16)(mbadrc_phys_addr\
1512 & 0xFFFF);
1513 acdb_data.pp_mbadrc->ext_buf_msw = (u16)((mbadrc_phys_addr\
1514 & 0xFFFF0000) >> 16);
1515 memcpy(acdb_data.pp_mbadrc->adrc_band, acdb_data.mbadrc_block.\
1516 band_config,
1517 sizeof(struct mbadrc_band_config_type) *
1518 acdb_data.mbadrc_block.parameters.mbadrc_num_bands);
1519 return 0;
1520}
1521
1522static s32 acdb_calibrate_audpp(void)
1523{
1524 s32 result = 0;
1525
1526 result = acdb_fill_audpp_iir();
1527 if (!IS_ERR_VALUE(result)) {
1528 result = audpp_dsp_set_rx_iir(COMMON_OBJ_ID,
1529 acdb_data.pp_iir->active_flag,
1530 acdb_data.pp_iir);
1531 if (result) {
1532 MM_ERR("ACDB=> Failed to send IIR data to postproc\n");
1533 result = -EINVAL;
1534 goto done;
1535 } else
Chaithanya Krishna Bacharaju4fa5ab02013-01-07 11:43:56 +05301536 MM_DBG("AUDPP is calibrated with IIR parameters\n");
Manish Dewanganca859722012-07-09 18:21:42 +05301537 }
1538 result = acdb_fill_audpp_mbadrc();
1539 if (!IS_ERR_VALUE(result)) {
1540 result = audpp_dsp_set_mbadrc(COMMON_OBJ_ID,
1541 acdb_data.pp_mbadrc->enable,
1542 acdb_data.pp_mbadrc);
1543 if (result) {
1544 MM_ERR("ACDB=> Failed to send MBADRC data to"\
1545 " postproc\n");
1546 result = -EINVAL;
1547 goto done;
1548 } else
1549 MM_DBG("AUDPP is calibrated with MBADRC parameters");
1550 }
1551done:
1552 return result;
1553}
1554
Sriranjan Srikantam87a6c292013-01-25 16:39:58 +05301555static s32 acdb_re_enable_audpp(void)
1556{
1557 s32 result = 0;
1558
1559 if ((acdb_data.audpp_disabled_features &
1560 (1 << AUDPP_CMD_IIR_TUNING_FILTER))
1561 == (1 << AUDPP_CMD_IIR_TUNING_FILTER)) {
1562 result = audpp_dsp_set_rx_iir(COMMON_OBJ_ID,
1563 acdb_data.pp_iir->active_flag,
1564 acdb_data.pp_iir);
1565 if (result) {
1566 MM_ERR("ACDB=> Failed to send IIR data to postproc\n");
1567 result = -EINVAL;
1568 } else {
1569 MM_DBG("Re-enable IIR parameters");
1570 }
1571 }
1572 if ((acdb_data.audpp_disabled_features & (1 << AUDPP_CMD_MBADRC))
1573 == (1 << AUDPP_CMD_MBADRC)) {
1574 result = audpp_dsp_set_mbadrc(COMMON_OBJ_ID,
1575 acdb_data.pp_mbadrc->enable,
1576 acdb_data.pp_mbadrc);
1577 if (result) {
1578 MM_ERR("ACDB=> Failed to send MBADRC data to"\
1579 " postproc\n");
1580 result = -EINVAL;
1581 } else {
1582 MM_DBG("Re-enable MBADRC parameters");
1583 }
1584 }
1585 acdb_data.audpp_disabled_features = 0;
1586 return result;
1587}
1588
Manish Dewanganca859722012-07-09 18:21:42 +05301589static struct acdb_agc_block *get_audpreproc_agc_block(void)
1590{
1591 struct header *prs_hdr;
1592 u32 index = 0;
1593
1594 while (index < acdb_data.acdb_result.used_bytes) {
1595 prs_hdr = (struct header *)(acdb_data.virt_addr + index);
1596 if (prs_hdr->dbor_signature == DBOR_SIGNATURE) {
1597 if (prs_hdr->abid == ABID_AUDIO_AGC_TX) {
1598 if (prs_hdr->iid == IID_AUDIO_AGC_PARAMETERS) {
1599 MM_DBG("GOT ABID_AUDIO_AGC_TX\n");
1600 return (struct acdb_agc_block *)
1601 (acdb_data.virt_addr + index
1602 + sizeof(struct header));
1603 }
1604 } else {
1605 index += prs_hdr->data_len +
1606 sizeof(struct header);
1607 }
1608 } else {
1609 break;
1610 }
1611 }
1612 return NULL;
1613}
1614
1615static s32 acdb_fill_audpreproc_agc(void)
1616{
1617 struct acdb_agc_block *acdb_agc;
1618
1619 acdb_agc = get_audpreproc_agc_block();
1620 if (!acdb_agc) {
1621 MM_DBG("unable to find preproc agc parameters winding up\n");
1622 return -EINVAL;
1623 }
1624 memset(acdb_data.preproc_agc, 0, sizeof(*acdb_data.preproc_agc));
1625 acdb_data.preproc_agc->cmd_id = AUDPREPROC_CMD_CFG_AGC_PARAMS;
1626 /* 0xFE00 to configure all parameters */
1627 acdb_data.preproc_agc->tx_agc_param_mask = 0xFFFF;
1628 if (acdb_agc->enable_status)
1629 acdb_data.preproc_agc->tx_agc_enable_flag =
1630 AUDPREPROC_CMD_TX_AGC_ENA_FLAG_ENA;
1631 else
1632 acdb_data.preproc_agc->tx_agc_enable_flag =
1633 AUDPREPROC_CMD_TX_AGC_ENA_FLAG_DIS;
1634
1635 acdb_data.preproc_agc->comp_rlink_static_gain =
1636 acdb_agc->comp_rlink_static_gain;
1637 acdb_data.preproc_agc->comp_rlink_aig_flag =
1638 acdb_agc->comp_rlink_aig_flag;
1639 acdb_data.preproc_agc->expander_rlink_th =
1640 acdb_agc->exp_rlink_threshold;
1641 acdb_data.preproc_agc->expander_rlink_slope =
1642 acdb_agc->exp_rlink_slope;
1643 acdb_data.preproc_agc->compressor_rlink_th =
1644 acdb_agc->comp_rlink_threshold;
1645 acdb_data.preproc_agc->compressor_rlink_slope =
1646 acdb_agc->comp_rlink_slope;
1647
1648 /* 0xFFF0 to configure all parameters */
1649 acdb_data.preproc_agc->tx_adc_agc_param_mask = 0xFFFF;
1650
1651 acdb_data.preproc_agc->comp_rlink_aig_attackk =
1652 acdb_agc->comp_rlink_aig_attack_k;
1653 acdb_data.preproc_agc->comp_rlink_aig_leak_down =
1654 acdb_agc->comp_rlink_aig_leak_down;
1655 acdb_data.preproc_agc->comp_rlink_aig_leak_up =
1656 acdb_agc->comp_rlink_aig_leak_up;
1657 acdb_data.preproc_agc->comp_rlink_aig_max =
1658 acdb_agc->comp_rlink_aig_max;
1659 acdb_data.preproc_agc->comp_rlink_aig_min =
1660 acdb_agc->comp_rlink_aig_min;
1661 acdb_data.preproc_agc->comp_rlink_aig_releasek =
1662 acdb_agc->comp_rlink_aig_release_k;
1663 acdb_data.preproc_agc->comp_rlink_aig_leakrate_fast =
1664 acdb_agc->comp_rlink_aig_sm_leak_rate_fast;
1665 acdb_data.preproc_agc->comp_rlink_aig_leakrate_slow =
1666 acdb_agc->comp_rlink_aig_sm_leak_rate_slow;
1667 acdb_data.preproc_agc->comp_rlink_attackk_msw =
1668 acdb_agc->comp_rlink_attack_k_msw;
1669 acdb_data.preproc_agc->comp_rlink_attackk_lsw =
1670 acdb_agc->comp_rlink_attack_k_lsw;
1671 acdb_data.preproc_agc->comp_rlink_delay =
1672 acdb_agc->comp_rlink_delay;
1673 acdb_data.preproc_agc->comp_rlink_releasek_msw =
1674 acdb_agc->comp_rlink_release_k_msw;
1675 acdb_data.preproc_agc->comp_rlink_releasek_lsw =
1676 acdb_agc->comp_rlink_release_k_lsw;
1677 acdb_data.preproc_agc->comp_rlink_rms_tav =
1678 acdb_agc->comp_rlink_rms_trav;
1679 return 0;
1680}
1681
1682static struct acdb_iir_block *get_audpreproc_irr_block(void)
1683{
1684
1685 struct header *prs_hdr;
1686 u32 index = 0;
1687
1688 while (index < acdb_data.acdb_result.used_bytes) {
1689 prs_hdr = (struct header *)(acdb_data.virt_addr + index);
1690
1691 if (prs_hdr->dbor_signature == DBOR_SIGNATURE) {
1692 if (prs_hdr->abid == ABID_AUDIO_IIR_TX) {
1693 if (prs_hdr->iid == IID_AUDIO_IIR_COEFF)
1694 return (struct acdb_iir_block *)
1695 (acdb_data.virt_addr + index
1696 + sizeof(struct header));
1697 } else {
1698 index += prs_hdr->data_len +
1699 sizeof(struct header);
1700 }
1701 } else {
1702 break;
1703 }
1704 }
1705 return NULL;
1706}
1707
1708
1709static s32 acdb_fill_audpreproc_iir(void)
1710{
1711 struct acdb_iir_block *acdb_iir;
1712
1713
1714 acdb_iir = get_audpreproc_irr_block();
1715 if (!acdb_iir) {
1716 MM_DBG("unable to find preproc iir parameters winding up\n");
1717 return -EINVAL;
1718 }
1719 memset(acdb_data.preproc_iir, 0, sizeof(*acdb_data.preproc_iir));
1720
1721 acdb_data.preproc_iir->cmd_id =
1722 AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS;
1723 acdb_data.preproc_iir->active_flag = acdb_iir->enable_flag;
1724 acdb_data.preproc_iir->num_bands = acdb_iir->stage_count;
1725
1726 acdb_data.preproc_iir->numerator_coeff_b0_filter0_lsw =
1727 acdb_iir->stages[0].b0_lo;
1728 acdb_data.preproc_iir->numerator_coeff_b0_filter0_msw =
1729 acdb_iir->stages[0].b0_hi;
1730 acdb_data.preproc_iir->numerator_coeff_b1_filter0_lsw =
1731 acdb_iir->stages[0].b1_lo;
1732 acdb_data.preproc_iir->numerator_coeff_b1_filter0_msw =
1733 acdb_iir->stages[0].b1_hi;
1734 acdb_data.preproc_iir->numerator_coeff_b2_filter0_lsw =
1735 acdb_iir->stages[0].b2_lo;
1736 acdb_data.preproc_iir->numerator_coeff_b2_filter0_msw =
1737 acdb_iir->stages[0].b2_hi;
1738
1739 acdb_data.preproc_iir->numerator_coeff_b0_filter1_lsw =
1740 acdb_iir->stages[1].b0_lo;
1741 acdb_data.preproc_iir->numerator_coeff_b0_filter1_msw =
1742 acdb_iir->stages[1].b0_hi;
1743 acdb_data.preproc_iir->numerator_coeff_b1_filter1_lsw =
1744 acdb_iir->stages[1].b1_lo;
1745 acdb_data.preproc_iir->numerator_coeff_b1_filter1_msw =
1746 acdb_iir->stages[1].b1_hi;
1747 acdb_data.preproc_iir->numerator_coeff_b2_filter1_lsw =
1748 acdb_iir->stages[1].b2_lo;
1749 acdb_data.preproc_iir->numerator_coeff_b2_filter1_msw =
1750 acdb_iir->stages[1].b2_hi;
1751
1752 acdb_data.preproc_iir->numerator_coeff_b0_filter2_lsw =
1753 acdb_iir->stages[2].b0_lo;
1754 acdb_data.preproc_iir->numerator_coeff_b0_filter2_msw =
1755 acdb_iir->stages[2].b0_hi;
1756 acdb_data.preproc_iir->numerator_coeff_b1_filter2_lsw =
1757 acdb_iir->stages[2].b1_lo;
1758 acdb_data.preproc_iir->numerator_coeff_b1_filter2_msw =
1759 acdb_iir->stages[2].b1_hi;
1760 acdb_data.preproc_iir->numerator_coeff_b2_filter2_lsw =
1761 acdb_iir->stages[2].b2_lo;
1762 acdb_data.preproc_iir->numerator_coeff_b2_filter2_msw =
1763 acdb_iir->stages[2].b2_hi;
1764
1765 acdb_data.preproc_iir->numerator_coeff_b0_filter3_lsw =
1766 acdb_iir->stages[3].b0_lo;
1767 acdb_data.preproc_iir->numerator_coeff_b0_filter3_msw =
1768 acdb_iir->stages[3].b0_hi;
1769 acdb_data.preproc_iir->numerator_coeff_b1_filter3_lsw =
1770 acdb_iir->stages[3].b1_lo;
1771 acdb_data.preproc_iir->numerator_coeff_b1_filter3_msw =
1772 acdb_iir->stages[3].b1_hi;
1773 acdb_data.preproc_iir->numerator_coeff_b2_filter3_lsw =
1774 acdb_iir->stages[3].b2_lo;
1775 acdb_data.preproc_iir->numerator_coeff_b2_filter3_msw =
1776 acdb_iir->stages[3].b2_hi;
1777
1778 acdb_data.preproc_iir->denominator_coeff_a0_filter0_lsw =
1779 acdb_iir->stages_a[0].a1_lo;
1780 acdb_data.preproc_iir->denominator_coeff_a0_filter0_msw =
1781 acdb_iir->stages_a[0].a1_hi;
1782 acdb_data.preproc_iir->denominator_coeff_a1_filter0_lsw =
1783 acdb_iir->stages_a[0].a2_lo;
1784 acdb_data.preproc_iir->denominator_coeff_a1_filter0_msw =
1785 acdb_iir->stages_a[0].a2_hi;
1786
1787 acdb_data.preproc_iir->denominator_coeff_a0_filter1_lsw =
1788 acdb_iir->stages_a[1].a1_lo;
1789 acdb_data.preproc_iir->denominator_coeff_a0_filter1_msw =
1790 acdb_iir->stages_a[1].a1_hi;
1791 acdb_data.preproc_iir->denominator_coeff_a1_filter1_lsw =
1792 acdb_iir->stages_a[1].a2_lo;
1793 acdb_data.preproc_iir->denominator_coeff_a1_filter1_msw =
1794 acdb_iir->stages_a[1].a2_hi;
1795
1796 acdb_data.preproc_iir->denominator_coeff_a0_filter2_lsw =
1797 acdb_iir->stages_a[2].a1_lo;
1798 acdb_data.preproc_iir->denominator_coeff_a0_filter2_msw =
1799 acdb_iir->stages_a[2].a1_hi;
1800 acdb_data.preproc_iir->denominator_coeff_a1_filter2_lsw =
1801 acdb_iir->stages_a[2].a2_lo;
1802 acdb_data.preproc_iir->denominator_coeff_a1_filter2_msw =
1803 acdb_iir->stages_a[2].a2_hi;
1804
1805 acdb_data.preproc_iir->denominator_coeff_a0_filter3_lsw =
1806 acdb_iir->stages_a[3].a1_lo;
1807 acdb_data.preproc_iir->denominator_coeff_a0_filter3_msw =
1808 acdb_iir->stages_a[3].a1_hi;
1809 acdb_data.preproc_iir->denominator_coeff_a1_filter3_lsw =
1810 acdb_iir->stages_a[3].a2_lo;
1811 acdb_data.preproc_iir->denominator_coeff_a1_filter3_msw =
1812 acdb_iir->stages_a[3].a2_hi;
1813
1814 acdb_data.preproc_iir->shift_factor_filter0 =
1815 acdb_iir->shift_factor[0];
1816 acdb_data.preproc_iir->shift_factor_filter1 =
1817 acdb_iir->shift_factor[1];
1818 acdb_data.preproc_iir->shift_factor_filter2 =
1819 acdb_iir->shift_factor[2];
1820 acdb_data.preproc_iir->shift_factor_filter3 =
1821 acdb_iir->shift_factor[3];
1822
1823 acdb_data.preproc_iir->channel_selected0 =
1824 acdb_iir->pan[0];
1825 acdb_data.preproc_iir->channel_selected1 =
1826 acdb_iir->pan[1];
1827 acdb_data.preproc_iir->channel_selected2 =
1828 acdb_iir->pan[2];
1829 acdb_data.preproc_iir->channel_selected3 =
1830 acdb_iir->pan[3];
1831 return 0;
1832}
1833
1834static struct acdb_ns_tx_block *get_audpreproc_ns_block(void)
1835{
1836
1837 struct header *prs_hdr;
1838 u32 index = 0;
1839
1840 while (index < acdb_data.acdb_result.used_bytes) {
1841 prs_hdr = (struct header *)(acdb_data.virt_addr + index);
1842
1843 if (prs_hdr->dbor_signature == DBOR_SIGNATURE) {
1844 if (prs_hdr->abid == ABID_AUDIO_NS_TX) {
1845 if (prs_hdr->iid == IID_NS_PARAMETERS)
1846 return (struct acdb_ns_tx_block *)
1847 (acdb_data.virt_addr + index
1848 + sizeof(struct header));
1849 } else {
1850 index += prs_hdr->data_len +
1851 sizeof(struct header);
1852 }
1853 } else {
1854 break;
1855 }
1856 }
1857 return NULL;
1858}
1859
1860static s32 acdb_fill_audpreproc_ns(void)
1861{
1862 struct acdb_ns_tx_block *acdb_ns;
1863 /* TO DO: do we enable_status_filled */
1864 acdb_ns = get_audpreproc_ns_block();
1865 if (!acdb_ns) {
1866 MM_DBG("unable to find preproc ns parameters winding up\n");
1867 return -EINVAL;
1868 }
1869 memset(acdb_data.preproc_ns, 0, sizeof(*acdb_data.preproc_ns));
1870 acdb_data.preproc_ns->cmd_id = AUDPREPROC_CMD_CFG_NS_PARAMS;
1871
1872 acdb_data.preproc_ns->ec_mode_new = acdb_ns->ec_mode_new;
1873 acdb_data.preproc_ns->dens_gamma_n = acdb_ns->dens_gamma_n;
1874 acdb_data.preproc_ns->dens_nfe_block_size =
1875 acdb_ns->dens_nfe_block_size;
1876 acdb_data.preproc_ns->dens_limit_ns = acdb_ns->dens_limit_ns;
1877 acdb_data.preproc_ns->dens_limit_ns_d = acdb_ns->dens_limit_ns_d;
1878 acdb_data.preproc_ns->wb_gamma_e = acdb_ns->wb_gamma_e;
1879 acdb_data.preproc_ns->wb_gamma_n = acdb_ns->wb_gamma_n;
1880
1881 return 0;
1882}
1883
1884s32 acdb_calibrate_audpreproc(void)
1885{
1886 s32 result = 0;
1887
1888 result = acdb_fill_audpreproc_agc();
1889 if (!IS_ERR_VALUE(result)) {
1890 result = audpreproc_dsp_set_agc(acdb_data.preproc_agc, sizeof(
1891 audpreproc_cmd_cfg_agc_params));
1892 if (result) {
1893 MM_ERR("ACDB=> Failed to send AGC data to preproc)\n");
1894 result = -EINVAL;
1895 goto done;
1896 } else
1897 MM_DBG("AUDPREC is calibrated with AGC parameters");
1898 }
1899 result = acdb_fill_audpreproc_iir();
1900 if (!IS_ERR_VALUE(result)) {
1901 result = audpreproc_dsp_set_iir(acdb_data.preproc_iir,
1902 sizeof(\
1903 audpreproc_cmd_cfg_iir_tuning_filter_params));
1904 if (result) {
1905 MM_ERR("ACDB=> Failed to send IIR data to preproc\n");
1906 result = -EINVAL;
1907 goto done;
1908 } else
1909 MM_DBG("audpreproc is calibrated with iir parameters");
1910 }
1911
1912 result = acdb_fill_audpreproc_ns();
1913 if (!IS_ERR_VALUE(result)) {
1914 result = audpreproc_dsp_set_ns(acdb_data.preproc_ns,
1915 sizeof(\
1916 audpreproc_cmd_cfg_ns_params));
1917 if (result) {
1918 MM_ERR("ACDB=> Failed to send NS data to preproc\n");
1919 result = -EINVAL;
1920 goto done;
1921 } else
1922 MM_DBG("audpreproc is calibrated with NS parameters");
1923 }
1924done:
1925 return result;
1926}
1927
1928static s32 acdb_send_calibration(void)
1929{
1930 s32 result = 0;
1931
1932 if (acdb_data.device_info->dev_type.rx_device) {
1933 result = acdb_calibrate_audpp();
1934 if (result)
1935 goto done;
1936 } else if (acdb_data.device_info->dev_type.tx_device) {
1937 result = acdb_calibrate_audpreproc();
1938 if (result)
1939 goto done;
1940 acdb_data.audrec_applied |= AUDREC_READY;
1941 MM_DBG("acdb_data.audrec_applied = %x\n",
1942 acdb_data.audrec_applied);
1943 }
1944done:
1945 return result;
1946}
1947
1948static u8 check_tx_acdb_values_cached(void)
1949{
1950 if ((acdb_data.device_info->sample_rate ==
1951 acdb_cache_tx.device_info.sample_rate) &&
1952 (acdb_data.device_info->acdb_id ==
1953 acdb_cache_tx.device_info.acdb_id) &&
1954 (acdb_cache_tx.node_status ==
1955 ACDB_VALUES_FILLED))
1956 return 0;
1957 else
1958 return 1;
1959}
1960
1961static void handle_tx_device_ready_callback(void)
1962{
1963 u8 acdb_value_apply = 0;
1964 u8 result = 0;
1965
1966 /*check wheather AUDREC enabled before device call backs*/
1967 if ((acdb_data.acdb_state & AUDREC_READY) &&
1968 !(acdb_data.audrec_applied & AUDREC_READY)) {
1969 MM_DBG("AUDREC already enabled apply acdb values\n");
1970 acdb_value_apply |= AUDREC_READY;
1971 }
1972 if (acdb_value_apply) {
1973 if (session_info.sampling_freq)
1974 acdb_data.device_info->sample_rate =
1975 session_info.sampling_freq;
1976 result = check_tx_acdb_values_cached();
1977 if (result) {
1978 result = acdb_get_calibration();
1979 if (result < 0) {
1980 MM_ERR("Not able to get calibration"\
1981 " data continue\n");
1982 return;
1983 }
1984 }
1985 acdb_cache_tx.node_status = ACDB_VALUES_FILLED;
1986 acdb_send_calibration();
1987 }
1988}
1989
1990static struct acdb_cache_node *get_acdb_values_from_cache_tx(u32 stream_id)
1991{
1992 MM_DBG("searching node with stream_id");
1993 if ((acdb_cache_tx.stream_id == stream_id) &&
1994 (acdb_cache_tx.node_status ==
1995 ACDB_VALUES_NOT_FILLED)) {
1996 return &acdb_cache_tx;
1997 }
1998 MM_DBG("Error! in finding node\n");
1999 return NULL;
2000}
2001
2002static void update_acdb_data_struct(struct acdb_cache_node *cur_node)
2003{
2004 if (cur_node) {
2005 acdb_data.device_info = &cur_node->device_info;
2006 acdb_data.virt_addr = cur_node->virt_addr_acdb_values;
2007 acdb_data.phys_addr = cur_node->phys_addr_acdb_values;
2008 } else
2009 MM_ERR("error in curent node\n");
2010}
2011
2012static void send_acdb_values_for_active_devices(void)
2013{
2014 if (acdb_cache_rx.node_status ==
2015 ACDB_VALUES_FILLED) {
2016 update_acdb_data_struct(&acdb_cache_rx);
2017 if (acdb_data.acdb_state & CAL_DATA_READY)
2018 acdb_send_calibration();
2019 }
2020}
2021
2022static s32 initialize_rpc(void)
2023{
2024 s32 result = 0;
2025
2026 result = daldevice_attach(DALDEVICEID_ACDB, ACDB_PORT_NAME,
2027 ACDB_CPU, &acdb_data.handle);
2028
2029 if (result) {
2030 MM_ERR("ACDB=> Device Attach failed\n");
2031 result = -ENODEV;
2032 goto done;
2033 }
2034done:
2035 return result;
2036}
2037
2038static u32 allocate_memory_acdb_cache_tx(void)
2039{
2040 u32 result = 0;
2041 /*initialize local cache */
2042 acdb_cache_tx.phys_addr_acdb_values =
2043 allocate_contiguous_ebi_nomap(ACDB_BUF_SIZE,
2044 SZ_4K);
2045
2046 if (!acdb_cache_tx.phys_addr_acdb_values) {
2047 MM_ERR("ACDB=> Cannot allocate physical memory\n");
2048 result = -ENOMEM;
2049 goto error;
2050 }
2051 acdb_cache_tx.map_v_addr = ioremap(
2052 acdb_cache_tx.phys_addr_acdb_values,
2053 ACDB_BUF_SIZE);
2054 if (IS_ERR(acdb_cache_tx.map_v_addr)) {
2055 MM_ERR("ACDB=> Could not map physical address\n");
2056 result = -ENOMEM;
2057 free_contiguous_memory_by_paddr(
2058 acdb_cache_tx.phys_addr_acdb_values);
2059 goto error;
2060 }
2061 acdb_cache_tx.virt_addr_acdb_values =
2062 acdb_cache_tx.map_v_addr;
2063 memset(acdb_cache_tx.virt_addr_acdb_values, 0,
2064 ACDB_BUF_SIZE);
2065 return result;
2066error:
2067 iounmap(acdb_cache_tx.map_v_addr);
2068 free_contiguous_memory_by_paddr(
2069 acdb_cache_tx.phys_addr_acdb_values);
2070 return result;
2071}
2072
2073static u32 allocate_memory_acdb_cache_rx(void)
2074{
2075 u32 result = 0;
2076
2077 /*initialize local cache */
2078 acdb_cache_rx.phys_addr_acdb_values =
2079 allocate_contiguous_ebi_nomap(
2080 ACDB_BUF_SIZE, SZ_4K);
2081
2082 if (!acdb_cache_rx.phys_addr_acdb_values) {
2083 MM_ERR("ACDB=> Can not allocate physical memory\n");
2084 result = -ENOMEM;
2085 goto error;
2086 }
2087 acdb_cache_rx.map_v_addr =
2088 ioremap(acdb_cache_rx.phys_addr_acdb_values,
2089 ACDB_BUF_SIZE);
2090 if (IS_ERR(acdb_cache_rx.map_v_addr)) {
2091 MM_ERR("ACDB=> Could not map physical address\n");
2092 result = -ENOMEM;
2093 free_contiguous_memory_by_paddr(
2094 acdb_cache_rx.phys_addr_acdb_values);
2095 goto error;
2096 }
2097 acdb_cache_rx.virt_addr_acdb_values =
2098 acdb_cache_rx.map_v_addr;
2099 memset(acdb_cache_rx.virt_addr_acdb_values, 0,
2100 ACDB_BUF_SIZE);
2101 return result;
2102error:
2103 iounmap(acdb_cache_rx.map_v_addr);
2104 free_contiguous_memory_by_paddr(
2105 acdb_cache_rx.phys_addr_acdb_values);
2106 return result;
2107}
2108
2109static u32 allocate_memory_acdb_get_blk(void)
2110{
2111 u32 result = 0;
2112 acdb_data.get_blk_paddr = allocate_contiguous_ebi_nomap(
2113 ACDB_BUF_SIZE, SZ_4K);
2114 if (!acdb_data.get_blk_paddr) {
2115 MM_ERR("ACDB=> Cannot allocate physical memory\n");
2116 result = -ENOMEM;
2117 goto error;
2118 }
2119 acdb_data.map_v_get_blk = ioremap(acdb_data.get_blk_paddr,
2120 ACDB_BUF_SIZE);
2121 if (IS_ERR(acdb_data.map_v_get_blk)) {
2122 MM_ERR("ACDB=> Could not map physical address\n");
2123 result = -ENOMEM;
2124 free_contiguous_memory_by_paddr(
2125 acdb_data.get_blk_paddr);
2126 goto error;
2127 }
2128 acdb_data.get_blk_kvaddr = acdb_data.map_v_get_blk;
2129 memset(acdb_data.get_blk_kvaddr, 0, ACDB_BUF_SIZE);
2130error:
2131 return result;
2132}
2133
2134static void free_memory_acdb_cache_rx(void)
2135{
2136 iounmap(acdb_cache_rx.map_v_addr);
2137 free_contiguous_memory_by_paddr(
2138 acdb_cache_rx.phys_addr_acdb_values);
2139}
2140
2141static void free_memory_acdb_cache_tx(void)
2142{
2143
2144 iounmap(acdb_cache_tx.map_v_addr);
2145 free_contiguous_memory_by_paddr(
2146 acdb_cache_tx.phys_addr_acdb_values);
2147}
2148
2149static void free_memory_acdb_get_blk(void)
2150{
2151 iounmap(acdb_data.map_v_get_blk);
2152 free_contiguous_memory_by_paddr(acdb_data.get_blk_paddr);
2153}
2154
2155static s32 initialize_memory(void)
2156{
2157 s32 result = 0;
2158
2159 result = allocate_memory_acdb_get_blk();
2160 if (result < 0) {
2161 MM_ERR("memory allocation for get blk failed\n");
2162 goto done;
2163 }
2164
2165 result = allocate_memory_acdb_cache_rx();
2166 if (result < 0) {
2167 MM_ERR("memory allocation for rx cache is failed\n");
2168 free_memory_acdb_get_blk();
2169 goto done;
2170 }
2171 result = allocate_memory_acdb_cache_tx();
2172 if (result < 0) {
2173 MM_ERR("memory allocation for tx cache is failed\n");
2174 free_memory_acdb_get_blk();
2175 free_memory_acdb_cache_rx();
2176 goto done;
2177 }
2178 acdb_data.pp_iir = kmalloc(sizeof(*acdb_data.pp_iir),
2179 GFP_KERNEL);
2180 if (acdb_data.pp_iir == NULL) {
2181 MM_ERR("ACDB=> Could not allocate postproc iir memory\n");
2182 free_memory_acdb_get_blk();
2183 free_memory_acdb_cache_rx();
2184 free_memory_acdb_cache_tx();
2185 result = -ENOMEM;
2186 goto done;
2187 }
2188
2189 acdb_data.pp_mbadrc = kmalloc(sizeof(*acdb_data.pp_mbadrc), GFP_KERNEL);
2190 if (acdb_data.pp_mbadrc == NULL) {
2191 MM_ERR("ACDB=> Could not allocate postproc mbadrc memory\n");
2192 free_memory_acdb_get_blk();
2193 free_memory_acdb_cache_rx();
2194 free_memory_acdb_cache_tx();
2195 kfree(acdb_data.pp_iir);
2196 result = -ENOMEM;
2197 goto done;
2198 }
2199
2200 acdb_data.preproc_agc = kmalloc(sizeof(*acdb_data.preproc_agc),
2201 GFP_KERNEL);
2202 if (acdb_data.preproc_agc == NULL) {
2203 MM_ERR("ACDB=> Could not allocate preproc agc memory\n");
2204 free_memory_acdb_get_blk();
2205 free_memory_acdb_cache_rx();
2206 free_memory_acdb_cache_tx();
2207 kfree(acdb_data.pp_iir);
2208 kfree(acdb_data.pp_mbadrc);
2209 result = -ENOMEM;
2210 goto done;
2211 }
2212
2213 acdb_data.preproc_iir = kmalloc(sizeof(*acdb_data.preproc_iir),
2214 GFP_KERNEL);
2215 if (acdb_data.preproc_iir == NULL) {
2216 MM_ERR("ACDB=> Could not allocate preproc iir memory\n");
2217 free_memory_acdb_get_blk();
2218 free_memory_acdb_cache_rx();
2219 free_memory_acdb_cache_tx();
2220 kfree(acdb_data.pp_iir);
2221 kfree(acdb_data.pp_mbadrc);
2222 kfree(acdb_data.preproc_agc);
2223 result = -ENOMEM;
2224 goto done;
2225 }
2226
2227 acdb_data.preproc_ns = kmalloc(sizeof(*acdb_data.preproc_ns),
2228 GFP_KERNEL);
2229 if (acdb_data.preproc_ns == NULL) {
2230 MM_ERR("ACDB=> Could not allocate preproc ns memory\n");
2231 free_memory_acdb_get_blk();
2232 free_memory_acdb_cache_rx();
2233 free_memory_acdb_cache_tx();
2234 kfree(acdb_data.pp_iir);
2235 kfree(acdb_data.pp_mbadrc);
2236 kfree(acdb_data.preproc_agc);
2237 kfree(acdb_data.preproc_iir);
2238 result = -ENOMEM;
2239 goto done;
2240 }
2241done:
2242 return result;
2243}
2244
2245static u8 check_device_change(struct dev_evt_msg device_info)
2246{
2247 if (!acdb_data.device_info) {
2248 MM_ERR("not pointing to previous valid device detail\n");
2249 return 1; /*device info will not be pointing to*/
2250 /* valid device when acdb driver comes up*/
2251 }
2252 if ((device_info.sample_rate ==
2253 acdb_data.device_info->sample_rate) &&
2254 (device_info.acdb_id == acdb_data.device_info->acdb_id)) {
2255 return 0;
2256 }
2257 return 1;
2258}
2259
2260static void device_cb(struct dev_evt_msg *evt, void *private)
2261{
2262 struct cad_device_info_type dev_type;
2263 struct acdb_cache_node *acdb_cache_free_node = NULL;
2264 u32 session_id = 0;
2265 u8 ret = 0;
2266 u8 device_change = 0;
2267
2268 /*if session value is zero it indicates that device call back is for
2269 voice call we will drop the request as acdb values for voice call is
2270 not applied from acdb driver*/
2271 if (!evt->session_info) {
2272 MM_DBG("no active sessions and call back is for"\
2273 " voice call\n");
2274 goto done;
2275 }
2276
2277 if ((evt->dev_type.rx_device) &&
2278 (evt->acdb_id == PSEUDO_ACDB_ID)) {
2279 MM_INFO("device cb is for rx device with pseudo acdb id\n");
2280 goto done;
2281 }
2282 dev_type = evt->dev_type;
2283 MM_DBG("sample_rate = %d\n", evt->sample_rate);
2284 MM_DBG("acdb_id = %d\n", evt->acdb_id);
2285 MM_DBG("sessions = %d\n", evt->session_info);
2286 MM_DBG("acdb_state = %x\n", acdb_data.acdb_state);
2287 mutex_lock(&acdb_data.acdb_mutex);
2288 device_change = check_device_change(*evt);
2289 if (!device_change) {
2290 if (dev_type.tx_device) {
2291 if (!(acdb_data.acdb_state & AUDREC_READY))
2292 acdb_data.audrec_applied &= ~AUDREC_READY;
2293
2294 acdb_data.acdb_state &= ~CAL_DATA_READY;
2295 goto update_cache;
2296 }
2297 } else
2298 /* state is updated to query the modem for values */
2299 acdb_data.acdb_state &= ~CAL_DATA_READY;
2300
2301update_cache:
2302 if (dev_type.tx_device) {
2303 /*Only one recording session possible*/
2304 session_id = 0;
2305 acdb_cache_free_node = &acdb_cache_tx;
2306 ret = check_device_info_already_present(
2307 *evt,
2308 acdb_cache_free_node);
2309 acdb_cache_free_node->stream_id = session_id;
2310 acdb_data.cur_tx_session = session_id;
2311 } else {
2312 acdb_cache_free_node = &acdb_cache_rx;
2313 ret = check_device_info_already_present(*evt,
2314 acdb_cache_free_node);
2315 if (ret == 1) {
2316 MM_DBG("got device ready call back for another "\
2317 "audplay task sessions on same COPP\n");
Manish Dewanganca859722012-07-09 18:21:42 +05302318 mutex_unlock(&acdb_data.acdb_mutex);
2319 goto done;
2320 }
Manish Dewanganca859722012-07-09 18:21:42 +05302321 }
2322 update_acdb_data_struct(acdb_cache_free_node);
2323 acdb_data.device_cb_compl = 1;
2324 mutex_unlock(&acdb_data.acdb_mutex);
2325 wake_up(&acdb_data.wait);
2326done:
2327 return;
2328}
2329
2330static s32 register_device_cb(void)
2331{
2332 s32 result = 0;
2333 acdb_data.dev_cb.func = device_cb;
2334 acdb_data.dev_cb.private = (void *)&acdb_data;
2335
2336 result = audmgr_register_device_info_callback(&acdb_data.dev_cb);
2337
2338 if (result) {
2339 MM_ERR("ACDB=> Could not register device callback\n");
2340 result = -ENODEV;
2341 goto done;
2342 }
2343done:
2344 return result;
2345}
2346
2347static void audpp_cb(void *private, u32 id, u16 *msg)
2348{
2349 MM_DBG("\n");
Sriranjan Srikantam87a6c292013-01-25 16:39:58 +05302350
2351 if (id == AUDPP_MSG_PP_DISABLE_FEEDBACK) {
2352 acdb_data.audpp_disabled_features |=
2353 ((uint32_t)(msg[AUDPP_DISABLE_FEATS_MSW] << 16) |
2354 msg[AUDPP_DISABLE_FEATS_LSW]);
2355 MM_INFO("AUDPP disable feedback: %x",
2356 acdb_data.audpp_disabled_features);
2357 goto done;
2358 } else if (id == AUDPP_MSG_PP_FEATS_RE_ENABLE) {
2359 MM_INFO("AUDPP re-enable messaage: %x",
2360 acdb_data.audpp_disabled_features);
2361 acdb_data.audpp_cb_reenable_compl = 1;
2362 wake_up(&acdb_data.wait);
2363 return;
2364 }
2365
Manish Dewanganca859722012-07-09 18:21:42 +05302366 if (id != AUDPP_MSG_CFG_MSG)
2367 goto done;
2368
2369 if (msg[0] == AUDPP_MSG_ENA_DIS) {
2370 if (--acdb_cache_rx.stream_id <= 0) {
2371 acdb_data.acdb_state &= ~AUDPP_READY;
2372 acdb_cache_rx.stream_id = 0;
2373 MM_DBG("AUDPP_MSG_ENA_DIS\n");
2374 }
2375 goto done;
2376 }
Chaithanya Krishna Bacharaju4fa5ab02013-01-07 11:43:56 +05302377 /*stream_id is used to keep track of number of active*/
2378 /*sessions active on this device*/
2379 acdb_cache_rx.stream_id++;
Manish Dewanganca859722012-07-09 18:21:42 +05302380
2381 acdb_data.acdb_state |= AUDPP_READY;
2382 acdb_data.audpp_cb_compl = 1;
2383 wake_up(&acdb_data.wait);
2384done:
2385 return;
2386}
2387
2388static s8 handle_audpreproc_cb(void)
2389{
2390 struct acdb_cache_node *acdb_cached_values;
2391 s8 result = 0;
2392 u8 stream_id = acdb_data.preproc_stream_id;
2393 acdb_data.preproc_cb_compl = 0;
2394 acdb_cached_values = get_acdb_values_from_cache_tx(stream_id);
2395 if (acdb_cached_values == NULL) {
2396 MM_DBG("ERROR: to get chached acdb values\n");
2397 return -EPERM;
2398 }
2399 update_acdb_data_struct(acdb_cached_values);
2400
2401 if (session_info.sampling_freq)
2402 acdb_data.device_info->sample_rate =
2403 session_info.sampling_freq;
2404
2405 if (!(acdb_data.acdb_state & CAL_DATA_READY)) {
2406 result = check_tx_acdb_values_cached();
2407 if (result) {
2408 result = acdb_get_calibration();
2409 if (result < 0) {
2410 MM_ERR("failed to get calibration data\n");
2411 return result;
2412 }
2413 }
2414 acdb_cached_values->node_status = ACDB_VALUES_FILLED;
2415 }
2416 return result;
2417}
2418
2419static void audpreproc_cb(void *private, u32 id, void *event_data)
2420{
2421 u8 result = 0;
2422 uint16_t *msg = event_data;
2423 int stream_id = 0; /* Only single tunnel mode recording supported */
2424 if (id != AUDPREPROC_MSG_CMD_CFG_DONE_MSG)
2425 goto done;
2426
2427 acdb_data.preproc_stream_id = stream_id;
2428 get_audrec_session_info(&session_info);
2429 MM_DBG("status_flag = %x\n", msg[0]);
2430 if (msg[0] == AUDPREPROC_MSG_STATUS_FLAG_DIS) {
2431 acdb_data.acdb_state &= ~AUDREC_READY;
2432 acdb_cache_tx.node_status =\
2433 ACDB_VALUES_NOT_FILLED;
2434 acdb_data.acdb_state &= ~CAL_DATA_READY;
2435 goto done;
2436 }
2437 /*Following check is added to make sure that device info
2438 is updated. audpre proc layer enabled without device
2439 callback at this scenario we should not access
2440 device information
2441 */
2442 if (acdb_data.device_info &&
2443 session_info.sampling_freq) {
2444 acdb_data.device_info->sample_rate =
2445 session_info.sampling_freq;
2446 result = check_tx_acdb_values_cached();
2447 if (!result) {
2448 MM_INFO("acdb values for the stream is" \
2449 " querried from modem");
2450 acdb_data.acdb_state |= CAL_DATA_READY;
2451 } else {
2452 acdb_data.acdb_state &= ~CAL_DATA_READY;
2453 }
2454 }
2455 acdb_data.acdb_state |= AUDREC_READY;
2456
2457 acdb_data.preproc_cb_compl = 1;
2458 MM_DBG("acdb_data.acdb_state = %x\n", acdb_data.acdb_state);
2459 wake_up(&acdb_data.wait);
2460done:
2461 return;
2462}
2463
2464static s32 register_audpp_cb(void)
2465{
2466 s32 result = 0;
2467
2468 acdb_data.audpp_cb.fn = audpp_cb;
2469 acdb_data.audpp_cb.private = NULL;
2470 result = audpp_register_event_callback(&acdb_data.audpp_cb);
2471 if (result) {
2472 MM_ERR("ACDB=> Could not register audpp callback\n");
2473 result = -ENODEV;
2474 goto done;
2475 }
2476done:
2477 return result;
2478}
2479
2480static s32 register_audpreproc_cb(void)
2481{
2482 s32 result = 0;
2483
2484 acdb_data.audpreproc_cb.fn = audpreproc_cb;
2485 acdb_data.audpreproc_cb.private = NULL;
2486 result = audpreproc_register_event_callback(&acdb_data.audpreproc_cb);
2487 if (result) {
2488 MM_ERR("ACDB=> Could not register audpreproc callback\n");
2489 result = -ENODEV;
2490 goto done;
2491 }
2492
2493done:
2494 return result;
2495}
2496
2497static s32 acdb_initialize_data(void)
2498{
2499 s32 result = 0;
2500
2501 mutex_init(&acdb_data.acdb_mutex);
2502
2503 result = initialize_rpc();
2504 if (result)
2505 goto err;
2506
2507 result = initialize_memory();
2508 if (result)
2509 goto err1;
2510
2511 result = register_device_cb();
2512 if (result)
2513 goto err2;
2514
2515 result = register_audpp_cb();
2516 if (result)
2517 goto err3;
2518
2519 result = register_audpreproc_cb();
2520 if (result)
2521 goto err4;
2522
2523
2524 return result;
2525
2526err4:
2527 result = audpreproc_unregister_event_callback(&acdb_data.audpreproc_cb);
2528 if (result)
2529 MM_ERR("ACDB=> Could not unregister audpreproc callback\n");
2530err3:
2531 result = audpp_unregister_event_callback(&acdb_data.audpp_cb);
2532 if (result)
2533 MM_ERR("ACDB=> Could not unregister audpp callback\n");
2534err2:
2535 result = audmgr_deregister_device_info_callback(&acdb_data.dev_cb);
2536 if (result)
2537 MM_ERR("ACDB=> Could not unregister device callback\n");
2538err1:
2539 daldevice_detach(acdb_data.handle);
2540 acdb_data.handle = NULL;
2541err:
2542 return result;
2543}
2544
2545static s32 acdb_calibrate_device(void *data)
2546{
2547 s32 result = 0;
2548
2549 /* initialize driver */
2550 result = acdb_initialize_data();
2551 if (result)
2552 goto done;
2553
2554 while (!kthread_should_stop()) {
2555 MM_DBG("Waiting for call back events\n");
2556 wait_event_interruptible(acdb_data.wait,
2557 (acdb_data.device_cb_compl
2558 | acdb_data.audpp_cb_compl
Sriranjan Srikantam87a6c292013-01-25 16:39:58 +05302559 | acdb_data.audpp_cb_reenable_compl
Manish Dewanganca859722012-07-09 18:21:42 +05302560 | acdb_data.preproc_cb_compl));
2561 mutex_lock(&acdb_data.acdb_mutex);
2562 if (acdb_data.device_cb_compl) {
2563 acdb_data.device_cb_compl = 0;
2564 if (!(acdb_data.acdb_state & CAL_DATA_READY)) {
2565 if (acdb_data.device_info->dev_type.rx_device) {
2566 /*we need to get calibration values
2567 only for RX device as resampler
2568 moved to start of the pre - proc chain
2569 tx calibration value will be based on
2570 sampling frequency what audrec is
2571 configured, calibration values for tx
2572 device are fetch in audpreproc
2573 callback*/
2574 result = acdb_get_calibration();
2575 if (result < 0) {
2576 mutex_unlock(
2577 &acdb_data.acdb_mutex);
2578 MM_ERR("Not able to get "\
2579 "calibration "\
2580 "data continue\n");
2581 continue;
2582 }
2583 }
2584 }
2585 MM_DBG("acdb state = %d\n",
2586 acdb_data.acdb_state);
2587 if (acdb_data.device_info->dev_type.tx_device)
2588 handle_tx_device_ready_callback();
2589 else {
Sriranjan Srikantam87a6c292013-01-25 16:39:58 +05302590 if (acdb_data.audpp_cb_reenable_compl) {
2591 MM_INFO("Reset disabled feature flag");
2592 acdb_data.audpp_disabled_features = 0;
2593 acdb_data.audpp_cb_reenable_compl = 0;
2594 }
Manish Dewanganca859722012-07-09 18:21:42 +05302595 acdb_cache_rx.node_status =\
2596 ACDB_VALUES_FILLED;
2597 if (acdb_data.acdb_state &
2598 AUDPP_READY) {
2599 MM_DBG("AUDPP already enabled "\
2600 "apply acdb values\n");
2601 goto apply;
2602 }
2603 }
2604 }
2605
2606 if (!(acdb_data.audpp_cb_compl ||
Sriranjan Srikantam87a6c292013-01-25 16:39:58 +05302607 acdb_data.audpp_cb_reenable_compl ||
Manish Dewanganca859722012-07-09 18:21:42 +05302608 acdb_data.preproc_cb_compl)) {
2609 MM_DBG("need to wait for either AUDPP / AUDPREPROC "\
2610 "Event\n");
2611 mutex_unlock(&acdb_data.acdb_mutex);
2612 continue;
2613 } else {
2614 MM_DBG("got audpp / preproc call back\n");
2615 if (acdb_data.audpp_cb_compl) {
Sriranjan Srikantam87a6c292013-01-25 16:39:58 +05302616 if (acdb_data.audpp_cb_reenable_compl) {
2617 MM_INFO("Reset disabled feature flag");
2618 acdb_data.audpp_disabled_features = 0;
2619 acdb_data.audpp_cb_reenable_compl = 0;
2620 }
Manish Dewanganca859722012-07-09 18:21:42 +05302621 send_acdb_values_for_active_devices();
2622 acdb_data.audpp_cb_compl = 0;
2623 mutex_unlock(&acdb_data.acdb_mutex);
2624 continue;
Sriranjan Srikantam87a6c292013-01-25 16:39:58 +05302625 } else if (acdb_data.audpp_cb_reenable_compl) {
2626 acdb_re_enable_audpp();
2627 acdb_data.audpp_disabled_features = 0;
2628 acdb_data.audpp_cb_reenable_compl = 0;
2629 mutex_unlock(&acdb_data.acdb_mutex);
2630 continue;
Manish Dewanganca859722012-07-09 18:21:42 +05302631 } else {
2632 result = handle_audpreproc_cb();
2633 if (result < 0) {
2634 mutex_unlock(&acdb_data.acdb_mutex);
2635 continue;
2636 }
2637 }
2638 }
2639apply:
2640 if (acdb_data.acdb_state & CAL_DATA_READY)
2641 result = acdb_send_calibration();
2642
2643 mutex_unlock(&acdb_data.acdb_mutex);
2644 }
2645done:
2646 return 0;
2647}
2648
2649static int __init acdb_init(void)
2650{
2651
2652 s32 result = 0;
2653
2654 memset(&acdb_data, 0, sizeof(acdb_data));
2655 spin_lock_init(&acdb_data.dsp_lock);
Manish Dewanganc240c582012-11-05 14:06:20 +05302656 init_waitqueue_head(&acdb_data.wait);
Manish Dewanganca859722012-07-09 18:21:42 +05302657 acdb_data.cb_thread_task = kthread_run(acdb_calibrate_device,
2658 NULL, "acdb_cb_thread");
2659
2660 if (IS_ERR(acdb_data.cb_thread_task)) {
2661 MM_ERR("ACDB=> Could not register cb thread\n");
2662 result = -ENODEV;
2663 goto err;
2664 }
2665
2666#ifdef CONFIG_DEBUG_FS
2667 /*This is RTC specific INIT used only with debugfs*/
2668 if (!rtc_acdb_init())
2669 MM_ERR("RTC ACDB=>INIT Failure\n");
2670
2671#endif
Manish Dewanganca859722012-07-09 18:21:42 +05302672
2673 return misc_register(&acdb_misc);
2674err:
2675 return result;
2676}
2677
2678static void __exit acdb_exit(void)
2679{
2680 s32 result = 0;
2681
2682 result = audmgr_deregister_device_info_callback(&acdb_data.dev_cb);
2683 if (result)
2684 MM_ERR("ACDB=> Could not unregister device callback\n");
2685
2686 result = audpp_unregister_event_callback(&acdb_data.audpp_cb);
2687 if (result)
2688 MM_ERR("ACDB=> Could not unregister audpp callback\n");
2689
2690 result = audpreproc_unregister_event_callback(&acdb_data.\
2691 audpreproc_cb);
2692 if (result)
2693 MM_ERR("ACDB=> Could not unregister audpreproc callback\n");
2694
2695 result = kthread_stop(acdb_data.cb_thread_task);
2696 if (result)
2697 MM_ERR("ACDB=> Could not stop kthread\n");
2698
2699 free_memory_acdb_get_blk();
2700
2701 iounmap(acdb_cache_tx.map_v_addr);
2702 free_contiguous_memory_by_paddr(
2703 acdb_cache_tx.phys_addr_acdb_values);
2704 iounmap(acdb_cache_rx.map_v_addr);
2705 free_contiguous_memory_by_paddr(
2706 acdb_cache_rx.phys_addr_acdb_values);
2707 kfree(acdb_data.device_info);
2708 kfree(acdb_data.pp_iir);
2709 kfree(acdb_data.pp_mbadrc);
2710 kfree(acdb_data.preproc_agc);
2711 kfree(acdb_data.preproc_iir);
2712 kfree(acdb_data.preproc_ns);
2713 mutex_destroy(&acdb_data.acdb_mutex);
2714 memset(&acdb_data, 0, sizeof(acdb_data));
2715 #ifdef CONFIG_DEBUG_FS
2716 rtc_acdb_deinit();
2717 #endif
2718}
2719
2720late_initcall(acdb_init);
2721module_exit(acdb_exit);
2722
2723MODULE_DESCRIPTION("MSM 8x25 Audio ACDB driver");
2724MODULE_LICENSE("GPL v2");