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