blob: 85378beef4bf7161e909d5ca16f0ad4128519034 [file] [log] [blame]
Duy Truong790f06d2013-02-13 16:38:12 -08001/* Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002 *
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>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070019#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>
Santosh Mardifdc227a2011-07-11 17:20:34 +053024#include <linux/debugfs.h>
25#include <linux/memory_alloc.h>
26#include <linux/mfd/marimba.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070027#include <mach/dal.h>
Santosh Mardifdc227a2011-07-11 17:20:34 +053028#include <mach/iommu.h>
29#include <mach/iommu_domains.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070030#include <mach/qdsp5v2/audio_dev_ctl.h>
31#include <mach/qdsp5v2/audpp.h>
Kalyani polepeddyaeea8bf2011-10-20 10:51:07 +053032#include <mach/socinfo.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070033#include <mach/qdsp5v2/audpreproc.h>
34#include <mach/qdsp5v2/qdsp5audppcmdi.h>
35#include <mach/qdsp5v2/qdsp5audpreproccmdi.h>
36#include <mach/qdsp5v2/qdsp5audpreprocmsg.h>
37#include <mach/qdsp5v2/qdsp5audppmsg.h>
38#include <mach/qdsp5v2/afe.h>
39#include <mach/qdsp5v2/audio_acdbi.h>
40#include <mach/qdsp5v2/acdb_commands.h>
41#include <mach/qdsp5v2/audio_acdb_def.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070042#include <mach/debug_mm.h>
Santosh Mardifdc227a2011-07-11 17:20:34 +053043#include <mach/msm_memtypes.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070044
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 PBE_BUF_SIZE (33*1024)
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/*below macro is used to align the session info received from
58Devctl driver with the state mentioned as not to alter the
59Existing code*/
60#define AUDREC_OFFSET 2
61/* rpc table index */
62enum {
63 ACDB_DalACDB_ioctl = DALDEVICE_FIRST_DEVICE_API_IDX
64};
65
66enum {
67 CAL_DATA_READY = 0x1,
68 AUDPP_READY = 0x2,
69 AUDREC0_READY = 0x4,
70 AUDREC1_READY = 0x8,
71 AUDREC2_READY = 0x10,
72};
73
74
75struct acdb_data {
76 void *handle;
77
78 u32 phys_addr;
79 u8 *virt_addr;
80
81 struct task_struct *cb_thread_task;
82 struct auddev_evt_audcal_info *device_info;
83
84 u32 acdb_state;
85 struct audpp_event_callback audpp_cb;
86 struct audpreproc_event_callback audpreproc_cb;
87
88 struct audpp_cmd_cfg_object_params_pcm *pp_iir;
89 struct audpp_cmd_cfg_cal_gain *calib_gain_rx;
90 struct audpp_cmd_cfg_pbe *pbe_block;
91 struct audpp_cmd_cfg_object_params_mbadrc *pp_mbadrc;
92 struct audpreproc_cmd_cfg_agc_params *preproc_agc;
93 struct audpreproc_cmd_cfg_iir_tuning_filter_params *preproc_iir;
94 struct audpreproc_cmd_cfg_cal_gain *calib_gain_tx;
95 struct acdb_mbadrc_block mbadrc_block;
96 struct audpreproc_cmd_cfg_lvnv_param preproc_lvnv;
97
98 wait_queue_head_t wait;
99 struct mutex acdb_mutex;
100 u32 device_cb_compl;
101 u32 audpp_cb_compl;
102 u32 preproc_cb_compl;
103 u8 preproc_stream_id;
104 u8 audrec_applied;
105 u32 multiple_sessions;
106 u32 cur_tx_session;
107 struct acdb_result acdb_result;
108 u16 *pbe_extbuff;
109 u16 *pbe_enable_flag;
110 u32 fluence_extbuff;
111 u8 *fluence_extbuff_virt;
Laura Abbott61399692012-04-30 14:25:46 -0700112 void *map_v_fluence;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700113
114 struct acdb_pbe_block *pbe_blk;
115
116 spinlock_t dsp_lock;
117 int dec_id;
118 struct audpp_cmd_cfg_object_params_eqalizer eq;
119 /*status to enable or disable the fluence*/
120 int fleuce_feature_status[MAX_AUDREC_SESSIONS];
121 struct audrec_session_info session_info;
122 /*pmem info*/
123 int pmem_fd;
124 unsigned long paddr;
125 unsigned long kvaddr;
126 unsigned long pmem_len;
127 struct file *file;
128 /* pmem for get acdb blk */
129 unsigned long get_blk_paddr;
130 u8 *get_blk_kvaddr;
Laura Abbott61399692012-04-30 14:25:46 -0700131 void *map_v_get_blk;
Kalyani polepeddyaeea8bf2011-10-20 10:51:07 +0530132 char *build_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700133};
134
135static struct acdb_data acdb_data;
136
137struct acdb_cache_node {
138 u32 node_status;
139 s32 stream_id;
140 u32 phys_addr_acdb_values;
Laura Abbott61399692012-04-30 14:25:46 -0700141 void *map_v_addr;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700142 u8 *virt_addr_acdb_values;
143 struct auddev_evt_audcal_info device_info;
144};
145
146/*for RX devices acdb values are applied based on copp ID so
147the depth of tx cache is MAX number of COPP supported in the system*/
148struct acdb_cache_node acdb_cache_rx[MAX_COPP_NODE_SUPPORTED];
149
150/*for TX devices acdb values are applied based on AUDREC session and
151the depth of the tx cache is define by number of AUDREC sessions supported*/
152struct acdb_cache_node acdb_cache_tx[MAX_AUDREC_SESSIONS];
153
154/*Audrec session info includes Attributes Sampling frequency and enc_id */
155struct audrec_session_info session_info[MAX_AUDREC_SESSIONS];
156#ifdef CONFIG_DEBUG_FS
157
158#define RTC_MAX_TIMEOUT 500 /* 500 ms */
159#define PMEM_RTC_ACDB_QUERY_MEM 4096
160#define EXTRACT_HIGH_WORD(x) ((x & 0xFFFF0000)>>16)
161#define EXTRACT_LOW_WORD(x) (0x0000FFFF & x)
162#define ACDB_RTC_TX 0xF1
163#define ACDB_RTC_RX 0x1F
164
165
166static u32 acdb_audpp_entry[][4] = {
167
168 { ABID_AUDIO_RTC_VOLUME_PAN_RX,\
169 IID_AUDIO_RTC_VOLUME_PAN_PARAMETERS,\
170 AUDPP_CMD_VOLUME_PAN,\
171 ACDB_RTC_RX
172 },
173 { ABID_AUDIO_IIR_RX,\
174 IID_AUDIO_IIR_COEFF,\
175 AUDPP_CMD_IIR_TUNING_FILTER,
176 ACDB_RTC_RX
177 },
178 { ABID_AUDIO_RTC_EQUALIZER_PARAMETERS,\
179 IID_AUDIO_RTC_EQUALIZER_PARAMETERS,\
180 AUDPP_CMD_EQUALIZER,\
181 ACDB_RTC_RX
182 },
183 { ABID_AUDIO_RTC_SPA,\
184 IID_AUDIO_RTC_SPA_PARAMETERS,\
185 AUDPP_CMD_SPECTROGRAM,
186 ACDB_RTC_RX
187 },
188 { ABID_AUDIO_STF_RX,\
189 IID_AUDIO_IIR_COEFF,\
190 AUDPP_CMD_SIDECHAIN_TUNING_FILTER,\
191 ACDB_RTC_RX
192 },
193 {
194 ABID_AUDIO_MBADRC_RX,\
195 IID_AUDIO_RTC_MBADRC_PARAMETERS,\
196 AUDPP_CMD_MBADRC,\
197 ACDB_RTC_RX
198 },
199 {
200 ABID_AUDIO_AGC_TX,\
201 IID_AUDIO_AGC_PARAMETERS,\
202 AUDPREPROC_CMD_CFG_AGC_PARAMS,\
203 ACDB_RTC_TX
204 },
205 {
206 ABID_AUDIO_AGC_TX,\
207 IID_AUDIO_RTC_AGC_PARAMETERS,\
208 AUDPREPROC_CMD_CFG_AGC_PARAMS,\
209 ACDB_RTC_TX
210 },
211 {
212 ABID_AUDIO_NS_TX,\
213 IID_NS_PARAMETERS,\
214 AUDPREPROC_CMD_CFG_NS_PARAMS,\
215 ACDB_RTC_TX
216 },
217 {
218 ABID_AUDIO_IIR_TX,\
219 IID_AUDIO_RTC_TX_IIR_COEFF,\
220 AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS,\
221 ACDB_RTC_TX
222 },
223 {
224 ABID_AUDIO_IIR_TX,\
225 IID_AUDIO_IIR_COEFF,\
226 AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS,\
227 ACDB_RTC_TX
228 }
229 /*Any new entries should be added here*/
230};
231
232static struct dentry *get_set_abid_dentry;
233static struct dentry *get_set_abid_data_dentry;
234
235struct rtc_acdb_pmem {
236 u8 *viraddr;
237 int32_t phys;
Laura Abbott61399692012-04-30 14:25:46 -0700238 void *map_v_rtc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700239};
240
241struct rtc_acdb_data {
242 u32 acdb_id;
243 u32 cmd_id;
244 u32 set_abid;
245 u32 set_iid;
246 u32 abid;
247 u32 err;
248 bool valid_abid;
249 u32 tx_rx_ctl;
250 struct rtc_acdb_pmem rtc_read;
251 struct rtc_acdb_pmem rtc_write;
252 wait_queue_head_t wait;
253};
254
255struct get_abid {
256 u32 cmd_id;
257 u32 acdb_id;
258 u32 set_abid;
259 u32 set_iid;
260};
261
262struct acdb_block_mbadrc_rtc {
263 u16 enable;
264 u16 num_bands;
265 u16 down_samp_level;
266 u16 adrc_delay;
267 u16 ext_buf_size;
268 u16 ext_partition;
269 u16 ext_buf_msw;
270 u16 ext_buf_lsw;
271 struct adrc_config adrc_band[AUDPP_MAX_MBADRC_BANDS];
272 signed int ExtBuff[196];
273} __attribute__((packed));
274
275enum {
276 ACDB_RTC_SUCCESS,
277 ACDB_RTC_ERR_INVALID_DEVICE,
278 ACDB_RTC_ERR_DEVICE_INACTIVE,
279 ACDB_RTC_ERR_INVALID_ABID,
280 ACDB_RTC_DSP_FAILURE,
281 ACDB_RTC_DSP_FEATURE_NOT_AVAILABLE,
282 ACDB_RTC_ERR_INVALID_LEN,
283 ACDB_RTC_ERR_UNKNOWN_FAILURE,
284 ACDB_RTC_PENDING_RESPONSE,
285 ACDB_RTC_INIT_FAILURE,
286};
287
288static struct rtc_acdb_data rtc_acdb;
289
290static int rtc_getsetabid_dbg_open(struct inode *inode, struct file *file)
291{
292 file->private_data = inode->i_private;
293 MM_INFO("GET-SET ABID Open debug intf %s\n",
294 (char *) file->private_data);
295 return 0;
296}
297
298static bool get_feature_id(u32 set_abid, u32 iid, unsigned short *feature_id)
299{
300 bool ret_value = false;
301 int i = 0;
302
303 for (; i < (sizeof(acdb_audpp_entry) / sizeof(acdb_audpp_entry[0]));\
304 i++) {
305 if (acdb_audpp_entry[i][0] == set_abid &&
306 acdb_audpp_entry[i][1] == iid) {
307 *feature_id = acdb_audpp_entry[i][2];
308 rtc_acdb.tx_rx_ctl = acdb_audpp_entry[i][3];
309 ret_value = true;
310 break;
311 }
312 }
313 return ret_value;
314}
315static ssize_t rtc_getsetabid_dbg_write(struct file *filp,
316 const char __user *ubuf,
317 size_t cnt, loff_t *ppos)
318{
319 struct get_abid write_abid;
320 unsigned short feat_id = 0;
321 rtc_acdb.valid_abid = false;
322
323 if (copy_from_user(&write_abid, \
324 (void *)ubuf, sizeof(struct get_abid))) {
325 MM_ERR("ACDB DATA WRITE - INVALID READ LEN\n");
326 rtc_acdb.err = ACDB_RTC_ERR_INVALID_LEN;
327 return cnt;
328 }
329 MM_INFO("SET ABID : Cmd ID: %d Device:%d ABID:%d IID : %d cnt: %d\n",\
330 write_abid.cmd_id, write_abid.acdb_id,
331 write_abid.set_abid, write_abid.set_iid, cnt);
332 if (write_abid.acdb_id > ACDB_ID_MAX ||
333 write_abid.acdb_id < ACDB_ID_HANDSET_SPKR){
334 rtc_acdb.err = ACDB_RTC_ERR_INVALID_DEVICE;
335 return cnt;
336 }
337 if (!is_dev_opened(write_abid.acdb_id)) {
338 rtc_acdb.err = ACDB_RTC_ERR_DEVICE_INACTIVE;
339 return cnt;
340 }
341 rtc_acdb.err = ACDB_RTC_ERR_INVALID_ABID;
342 rtc_acdb.abid = write_abid.set_abid;
343 if (get_feature_id(write_abid.set_abid, \
344 write_abid.set_iid, &feat_id)) {
345 rtc_acdb.err = ACDB_RTC_SUCCESS;
346 rtc_acdb.cmd_id = write_abid.cmd_id;
347 rtc_acdb.acdb_id = write_abid.acdb_id;
348 rtc_acdb.set_abid = feat_id;
349 rtc_acdb.valid_abid = true;
350 rtc_acdb.set_iid = write_abid.set_iid;
351 }
352 return cnt;
353}
354static ssize_t rtc_getsetabid_dbg_read(struct file *file, char __user *buf,
355 size_t count, loff_t *ppos)
356{
357 static char buffer[1024];
358 int n = 0;
359 u32 msg = rtc_acdb.err;
360 memcpy(buffer, &rtc_acdb.cmd_id, sizeof(struct get_abid));
361 memcpy(buffer+16, &msg, 4);
362 n = 20;
363 MM_INFO("SET ABID : Cmd ID: %x Device:%x ABID:%x IID : %x Err: %d\n",\
364 rtc_acdb.cmd_id, rtc_acdb.acdb_id, rtc_acdb.set_abid,\
365 rtc_acdb.set_iid, rtc_acdb.err);
366 return simple_read_from_buffer(buf, count, ppos, buffer, n);
367}
368
369static int rtc_getsetabid_data_dbg_open(struct inode *inode, struct file *file)
370{
371 file->private_data = inode->i_private;
372 MM_INFO("GET-SET ABID DATA Open debug intf %s\n",
373 (char *) file->private_data);
374 return 0;
375}
376
377void acdb_rtc_set_err(u32 ErrCode)
378{
379 if (rtc_acdb.err == ACDB_RTC_PENDING_RESPONSE) {
380 if (ErrCode == 0xFFFF) {
381 rtc_acdb.err = ACDB_RTC_SUCCESS;
382 MM_INFO("RTC READ SUCCESS---\n");
383 } else if (ErrCode == 0) {
384 rtc_acdb.err = ACDB_RTC_DSP_FAILURE;
385 MM_INFO("RTC READ FAIL---\n");
386 } else if (ErrCode == 1) {
387 rtc_acdb.err = ACDB_RTC_DSP_FEATURE_NOT_AVAILABLE;
388 MM_INFO("RTC READ FEAT UNAVAILABLE---\n");
389 } else {
390 rtc_acdb.err = ACDB_RTC_DSP_FAILURE;
391 MM_ERR("RTC Err CODE---\n");
392 }
393 } else {
394 rtc_acdb.err = ACDB_RTC_DSP_FAILURE;
395 MM_ERR("RTC Err code Invalid State\n");
396 }
397 wake_up(&rtc_acdb.wait);
398}
399static ssize_t rtc_getsetabid_data_dbg_read(struct file *file,
400 char __user *buf, size_t count,
401 loff_t *ppos)
402{
403 static char buffer[PMEM_RTC_ACDB_QUERY_MEM];
404 int rc, n = 0;
405 int counter = 0;
406 struct rtc_acdb_pmem *rtc_read = &rtc_acdb.rtc_read;
407 memset(&buffer, 0, PMEM_RTC_ACDB_QUERY_MEM);
408
409 if (rtc_acdb.valid_abid != true) {
410 MM_ERR("ACDB DATA READ ---INVALID ABID\n");
411 n = 0;
412 rtc_acdb.err = ACDB_RTC_ERR_INVALID_ABID;
413 } else {
414 if (PMEM_RTC_ACDB_QUERY_MEM < count) {
415 MM_ERR("ACDB DATA READ ---\
416 INVALID READ LEN %x\n", count);
417 n = 0;
418 rtc_acdb.err = ACDB_RTC_ERR_INVALID_LEN;
419 } else {
420 rtc_acdb.err = ACDB_RTC_PENDING_RESPONSE;
421 if (rtc_read->viraddr != NULL) {
422 memset(rtc_read->viraddr,
423 0, PMEM_RTC_ACDB_QUERY_MEM);
424 }
425 if (rtc_acdb.tx_rx_ctl == ACDB_RTC_RX) {
426 struct rtc_audpp_read_data rtc_read_cmd;
427 rtc_read_cmd.cmd_id =
428 AUDPP_CMD_PP_FEAT_QUERY_PARAMS;
429 rtc_read_cmd.obj_id =
430 AUDPP_CMD_COPP_STREAM;
431 rtc_read_cmd.route_id =
432 acdb_data.device_info->dev_id;
433 rtc_read_cmd.feature_id = rtc_acdb.set_abid;
434 rtc_read_cmd.extbufsizemsw =
435 EXTRACT_HIGH_WORD(\
436 PMEM_RTC_ACDB_QUERY_MEM);
437 rtc_read_cmd.extbufsizelsw =
438 EXTRACT_LOW_WORD(\
439 PMEM_RTC_ACDB_QUERY_MEM);
440 rtc_read_cmd.extpart = 0x0000;
441 rtc_read_cmd.extbufstartmsw =
442 EXTRACT_HIGH_WORD(rtc_read->phys);
443 rtc_read_cmd.extbufstartlsw =
444 EXTRACT_LOW_WORD(rtc_read->phys);
445 rc = audpp_send_queue2(&rtc_read_cmd,
446 sizeof(rtc_read_cmd));
447 MM_INFO("ACDB READ Command RC --->%x\
448 Route ID=%x\n", rc,\
449 acdb_data.device_info->dev_id);
450 } else if (rtc_acdb.tx_rx_ctl == ACDB_RTC_TX) {
451 struct rtc_audpreproc_read_data rtc_audpreproc;
452 rtc_audpreproc.cmd_id =
453 AUDPREPROC_CMD_FEAT_QUERY_PARAMS;
454 rtc_audpreproc.stream_id =
455 acdb_data.preproc_stream_id;
456 rtc_audpreproc.feature_id = rtc_acdb.set_abid;
457 rtc_audpreproc.extbufsizemsw =
458 EXTRACT_HIGH_WORD(\
459 PMEM_RTC_ACDB_QUERY_MEM);
460 rtc_audpreproc.extbufsizelsw =
461 EXTRACT_LOW_WORD(\
462 PMEM_RTC_ACDB_QUERY_MEM);
463 rtc_audpreproc.extpart = 0x0000;
464 rtc_audpreproc.extbufstartmsw =
465 EXTRACT_HIGH_WORD(rtc_read->phys);
466 rtc_audpreproc.extbufstartlsw =
467 EXTRACT_LOW_WORD(rtc_read->phys);
468 rc = audpreproc_send_preproccmdqueue(
469 &rtc_audpreproc,\
470 sizeof(rtc_audpreproc));
471 MM_INFO("ACDB READ Command RC --->%x,\
472 stream_id %x\n", rc,\
473 acdb_data.preproc_stream_id);
474 }
475 rc = wait_event_timeout(rtc_acdb.wait,
476 (rtc_acdb.err !=
477 ACDB_RTC_PENDING_RESPONSE),
478 msecs_to_jiffies(RTC_MAX_TIMEOUT));
479 MM_INFO("ACDB READ ACK Count = %x Err = %x\n",
480 count, rtc_acdb.err);
481 {
482 if (rtc_acdb.err == ACDB_RTC_SUCCESS
483 && rtc_read->viraddr != NULL) {
484 memcpy(buffer, rtc_read->viraddr, count);
485 n = count;
486 while (counter < count) {
487 MM_DBG("%x", \
488 rtc_read->viraddr[counter]);
489 counter++;
490 }
491 }
492 }
493 }
494 }
495 return simple_read_from_buffer(buf, count, ppos, buffer, n);
496}
497
498static bool acdb_set_tx_rtc(const char *ubuf, size_t writecount)
499{
500 struct audpreproc_cmd_cfg_iir_tuning_filter_params *preproc_iir;
501 struct audpreproc_cmd_cfg_agc_params *preproc_agc;
502 struct audpreproc_cmd_cfg_ns_params *preproc_ns;
503 s32 result = 0;
504 bool retval = false;
505 unsigned short iircmdsize =
506 sizeof(struct audpreproc_cmd_cfg_iir_tuning_filter_params);
507 unsigned short iircmdid = AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS;
508
509 rtc_acdb.err = ACDB_RTC_ERR_UNKNOWN_FAILURE;
510
511 switch (rtc_acdb.set_abid) {
512
513 case AUDPREPROC_CMD_CFG_AGC_PARAMS:
514 case AUDPREPROC_CMD_CFG_AGC_PARAMS_2:
515 {
516 preproc_agc = kmalloc(sizeof(\
517 struct audpreproc_cmd_cfg_agc_params),\
518 GFP_KERNEL);
519 if ((sizeof(struct audpreproc_cmd_cfg_agc_params) -\
520 (2*sizeof(unsigned short)))
521 < writecount) {
522 MM_ERR("ACDB DATA WRITE --\
523 AGC TX writecount > DSP struct\n");
524 } else {
525 if (preproc_agc != NULL) {
526 char *base; unsigned short offset;
527 unsigned short *offset_addr;
528 base = (char *)preproc_agc;
529 offset = offsetof(struct \
530 audpreproc_cmd_cfg_agc_params,\
531 tx_agc_param_mask);
532 offset_addr = (unsigned short *)(base + offset);
533 if ((copy_from_user(offset_addr,\
534 (void *)ubuf, writecount)) == 0x00) {
535 preproc_agc->cmd_id =
536 AUDPREPROC_CMD_CFG_AGC_PARAMS;
537 preproc_agc->stream_id =
538 acdb_data.preproc_stream_id;
539 result = audpreproc_dsp_set_agc(
540 preproc_agc,
541 sizeof(struct \
542 audpreproc_cmd_cfg_agc_params));
543 if (result) {
544 MM_ERR("ACDB=> Failed to \
545 send AGC data to \
546 preproc)\n");
547 } else {
548 retval = true;
549 }
550 } else {
551 MM_ERR("ACDB DATA WRITE ---\
552 GC Tx copy_from_user Fail\n");
553 }
554 } else {
555 MM_ERR("ACDB DATA WRITE --\
556 AGC TX kalloc Failed LEN\n");
557 }
558 }
559 if (preproc_agc != NULL)
560 kfree(preproc_agc);
561 break;
562 }
563 case AUDPREPROC_CMD_CFG_NS_PARAMS:
564 {
565
566 preproc_ns = kmalloc(sizeof(struct \
567 audpreproc_cmd_cfg_ns_params),\
568 GFP_KERNEL);
569 if ((sizeof(struct audpreproc_cmd_cfg_ns_params) -\
570 (2 * sizeof(unsigned short)))
571 < writecount) {
572 MM_ERR("ACDB DATA WRITE --\
573 NS TX writecount > DSP struct\n");
574 } else {
575 if (preproc_ns != NULL) {
576 char *base; unsigned short offset;
577 unsigned short *offset_addr;
578 base = (char *)preproc_ns;
579 offset = offsetof(struct \
580 audpreproc_cmd_cfg_ns_params,\
581 ec_mode_new);
582 offset_addr = (unsigned short *)(base + offset);
583 if ((copy_from_user(offset_addr,\
584 (void *)ubuf, writecount)) == 0x00) {
585 preproc_ns->cmd_id =
586 AUDPREPROC_CMD_CFG_NS_PARAMS;
587 preproc_ns->stream_id =
588 acdb_data.preproc_stream_id;
589 result = audpreproc_dsp_set_ns(
590 preproc_ns,
591 sizeof(struct \
592 audpreproc_cmd_cfg_ns_params));
593 if (result) {
594 MM_ERR("ACDB=> Failed to send \
595 NS data to preproc\n");
596 } else {
597 retval = true;
598 }
599 } else {
600 MM_ERR("ACDB DATA WRITE ---NS Tx \
601 copy_from_user Fail\n");
602 }
603 } else {
604 MM_ERR("ACDB DATA WRITE --NS TX\
605 kalloc Failed LEN\n");
606 }
607 }
608 if (preproc_ns != NULL)
609 kfree(preproc_ns);
610 break;
611 }
612 case AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS:
613 {
614
615 preproc_iir = kmalloc(sizeof(struct \
616 audpreproc_cmd_cfg_iir_tuning_filter_params),\
617 GFP_KERNEL);
618 if ((sizeof(struct \
619 audpreproc_cmd_cfg_iir_tuning_filter_params)-\
620 (2 * sizeof(unsigned short)))
621 < writecount) {
622 MM_ERR("ACDB DATA WRITE --IIR TX writecount\
623 > DSP struct\n");
624 } else {
625 if (preproc_iir != NULL) {
626 char *base; unsigned short offset;
627 unsigned short *offset_addr;
628 base = (char *)preproc_iir;
629 offset = offsetof(struct \
630 audpreproc_cmd_cfg_iir_tuning_filter_params,\
631 active_flag);
632 offset_addr = (unsigned short *)(base + \
633 offset);
634 if ((copy_from_user(offset_addr,\
635 (void *)ubuf, writecount)) == 0x00) {
636 preproc_iir->cmd_id = iircmdid;
637 preproc_iir->stream_id =
638 acdb_data.preproc_stream_id;
639 result = audpreproc_dsp_set_iir(\
640 preproc_iir,
641 iircmdsize);
642 if (result) {
643 MM_ERR("ACDB=> Failed to send\
644 IIR data to preproc\n");
645 } else {
646 retval = true;
647 }
648 } else {
649 MM_ERR("ACDB DATA WRITE ---IIR Tx \
650 copy_from_user Fail\n");
651 }
652 } else {
653 MM_ERR("ACDB DATA WRITE --IIR TX kalloc \
654 Failed LEN\n");
655 }
656 }
657 if (preproc_iir != NULL)
658 kfree(preproc_iir);
659 break;
660 }
661 }
662 return retval;
663}
664
665static bool acdb_set_rx_rtc(const char *ubuf, size_t writecount)
666{
667
668 struct audpp_cmd_cfg_object_params_volpan *volpan_config;
669 struct audpp_cmd_cfg_object_params_mbadrc *mbadrc_config;
670 struct acdb_block_mbadrc_rtc *acdb_mbadrc_rtc;
671 struct audpp_cmd_cfg_object_params_sidechain *stf_config;
672 struct audpp_cmd_cfg_object_params_spectram *spa_config;
673 struct audpp_cmd_cfg_object_params_eqalizer *eq_config;
674 struct audpp_cmd_cfg_object_params_pcm *iir_config;
675 unsigned short temp_spa[34];
676 struct rtc_acdb_pmem *rtc_write = &rtc_acdb.rtc_write;
677 s32 result = 0;
678 bool retval = false;
679
680 switch (rtc_acdb.set_abid) {
681 case AUDPP_CMD_VOLUME_PAN:
682 {
683 volpan_config = kmalloc(sizeof(struct \
684 audpp_cmd_cfg_object_params_volpan),\
685 GFP_KERNEL);
686 if ((sizeof(struct audpp_cmd_cfg_object_params_volpan) -\
687 sizeof(struct audpp_cmd_cfg_object_params_common))
688 < writecount) {
689 MM_ERR("ACDB DATA WRITE --\
690 VolPan writecount > DSP struct\n");
691 } else {
692 if (volpan_config != NULL) {
693 char *base; unsigned short offset;
694 unsigned short *offset_addr;
695 base = (char *)volpan_config;
696 offset = offsetof(struct \
697 audpp_cmd_cfg_object_params_volpan,\
698 volume);
699 offset_addr = (unsigned short *)(base+offset);
700 if ((copy_from_user(offset_addr,\
701 (void *)ubuf, writecount)) == 0x00) {
702 MM_ERR("ACDB RX WRITE DATA:\
703 AUDPP_CMD_VOLUME_PAN\n");
704 result = audpp_set_volume_and_pan(
705 acdb_data.device_info->dev_id,\
706 volpan_config->volume,
707 volpan_config->pan,
708 COPP);
709 if (result) {
710 MM_ERR("ACDB=> Failed to \
711 send VOLPAN data to"
712 " postproc\n");
713 } else {
714 retval = true;
715 }
716 } else {
717 MM_ERR("ACDB DATA WRITE ---\
718 copy_from_user Fail\n");
719 }
720 } else {
721 MM_ERR("ACDB DATA WRITE --\
722 Vol Pan kalloc Failed LEN\n");
723 }
724 }
725 if (volpan_config != NULL)
726 kfree(volpan_config);
727 break;
728 }
729
730 case AUDPP_CMD_IIR_TUNING_FILTER:
731 {
732 iir_config = kmalloc(sizeof(struct \
733 audpp_cmd_cfg_object_params_pcm),\
734 GFP_KERNEL);
735 if ((sizeof(struct audpp_cmd_cfg_object_params_pcm) -\
736 sizeof(struct audpp_cmd_cfg_object_params_common))
737 < writecount) {
738 MM_ERR("ACDB DATA WRITE --\
739 IIR RX writecount > DSP struct\n");
740 } else {
741 if (iir_config != NULL) {
742 char *base; unsigned short offset;
743 unsigned short *offset_addr;
744 base = (char *)iir_config;
745 offset = offsetof(struct \
746 audpp_cmd_cfg_object_params_pcm,\
747 active_flag);
748 offset_addr = (unsigned short *)(base+offset);
749 if ((copy_from_user(offset_addr,\
750 (void *)ubuf, writecount)) == 0x00) {
751
752 iir_config->common.cmd_id =
753 AUDPP_CMD_CFG_OBJECT_PARAMS;
754 iir_config->common.stream =
755 AUDPP_CMD_COPP_STREAM;
756 iir_config->common.stream_id = 0;
757 iir_config->common.obj_cfg =
758 AUDPP_CMD_OBJ0_UPDATE;
759 iir_config->common.command_type = 0;
760 MM_ERR("ACDB RX WRITE DATA:\
761 AUDPP_CMD_IIR_TUNING_FILTER\n");
762 result = audpp_dsp_set_rx_iir(
763 acdb_data.device_info->dev_id,
764 iir_config->active_flag,\
765 iir_config, COPP);
766 if (result) {
767 MM_ERR("ACDB=> Failed to send\
768 IIR data to\
769 postproc\n");
770 } else {
771 retval = true;
772 }
773 } else {
774 MM_ERR("ACDB DATA WRITE ---\
775 IIR Rx copy_from_user Fail\n");
776 }
777 } else {
778 MM_ERR("ACDB DATA WRITE --\
779 acdb_iir_block kalloc Failed LEN\n");
780 }
781 }
782 if (iir_config != NULL)
783 kfree(iir_config);
784 break;
785 }
786 case AUDPP_CMD_EQUALIZER:
787 {
788 eq_config = kmalloc(sizeof(struct \
789 audpp_cmd_cfg_object_params_eqalizer),\
790 GFP_KERNEL);
791 if ((sizeof(struct audpp_cmd_cfg_object_params_eqalizer) -\
792 sizeof(struct audpp_cmd_cfg_object_params_common))
793 < writecount) {
794 MM_ERR("ACDB DATA WRITE --\
795 EQ RX writecount > DSP struct\n");
796 } else {
797 if (eq_config != NULL) {
798 char *base; unsigned short offset;
799 unsigned short *offset_addr;
800 base = (char *)eq_config;
801 offset = offsetof(struct \
802 audpp_cmd_cfg_object_params_eqalizer,\
803 eq_flag);
804 offset_addr = (unsigned short *)(base+offset);
805 if ((copy_from_user(offset_addr,\
806 (void *)ubuf, writecount)) == 0x00) {
807 eq_config->common.cmd_id =
808 AUDPP_CMD_CFG_OBJECT_PARAMS;
809 eq_config->common.stream =
810 AUDPP_CMD_COPP_STREAM;
811 eq_config->common.stream_id = 0;
812 eq_config->common.obj_cfg =
813 AUDPP_CMD_OBJ0_UPDATE;
814 eq_config->common.command_type = 0;
815 MM_ERR("ACDB RX WRITE\
816 DATA:AUDPP_CMD_EQUALIZER\n");
817 result = audpp_dsp_set_eq(
818 acdb_data.device_info->dev_id,
819 eq_config->eq_flag,\
820 eq_config,
821 COPP);
822 if (result) {
823 MM_ERR("ACDB=> Failed to \
824 send EQ data to postproc\n");
825 } else {
826 retval = true;
827 }
828 } else {
829 MM_ERR("ACDB DATA WRITE ---\
830 EQ Rx copy_from_user Fail\n");
831 }
832 } else {
833 MM_ERR("ACDB DATA WRITE --\
834 EQ kalloc Failed LEN\n");
835 }
836 }
837 if (eq_config != NULL)
838 kfree(eq_config);
839 break;
840 }
841
842 case AUDPP_CMD_SPECTROGRAM:
843 {
844 spa_config = kmalloc(sizeof(struct \
845 audpp_cmd_cfg_object_params_spectram),\
846 GFP_KERNEL);
847 if ((sizeof(struct audpp_cmd_cfg_object_params_spectram)-\
848 sizeof(struct \
849 audpp_cmd_cfg_object_params_common))
850 < (2 * sizeof(unsigned short))) {
851 MM_ERR("ACDB DATA WRITE --SPA \
852 RX writecount > DSP struct\n");
853 } else {
854 if (spa_config != NULL) {
855 if ((copy_from_user(&temp_spa[0],\
856 (void *)ubuf,
857 (34 * sizeof(unsigned short))))
858 == 0x00) {
859 spa_config->common.cmd_id =
860 AUDPP_CMD_CFG_OBJECT_PARAMS;
861 spa_config->common.stream =
862 AUDPP_CMD_COPP_STREAM;
863 spa_config->common.stream_id = 0;
864 spa_config->common.obj_cfg =
865 AUDPP_CMD_OBJ0_UPDATE;
866 spa_config->common.command_type = 0;
867 spa_config->sample_interval =
868 temp_spa[0];
869 spa_config->num_coeff = temp_spa[1];
870 MM_ERR("ACDB RX WRITE DATA:\
871 AUDPP_CMD_SPECTROGRAM\n");
872 result = audpp_dsp_set_spa(
873 acdb_data.device_info->dev_id,\
874 spa_config, COPP);
875 if (result) {
876 MM_ERR("ACDB=> Failed to \
877 send SPA data \
878 to postproc\n");
879 } else {
880 retval = true;
881 }
882 } else {
883 MM_ERR("ACDB DATA WRITE \
884 ---SPA Rx copy_from_user\
885 Fail\n");
886 }
887 } else {
888 MM_ERR("ACDB DATA WRITE --\
889 SPA kalloc Failed LEN\n");
890 }
891 }
892 if (spa_config != NULL)
893 kfree(spa_config);
894 break;
895 }
896 case AUDPP_CMD_MBADRC:
897 {
898 acdb_mbadrc_rtc = kmalloc(sizeof(struct \
899 acdb_block_mbadrc_rtc),\
900 GFP_KERNEL);
901 mbadrc_config = kmalloc(sizeof(struct \
902 audpp_cmd_cfg_object_params_mbadrc),\
903 GFP_KERNEL);
904 if (mbadrc_config != NULL && acdb_mbadrc_rtc != NULL) {
905 if ((copy_from_user(acdb_mbadrc_rtc,\
906 (void *)ubuf,
907 sizeof(struct acdb_block_mbadrc_rtc)))
908 == 0x00) {
909 mbadrc_config->common.cmd_id =
910 AUDPP_CMD_CFG_OBJECT_PARAMS;
911 mbadrc_config->common.stream =
912 AUDPP_CMD_COPP_STREAM;
913 mbadrc_config->common.stream_id = 0;
914 mbadrc_config->common.obj_cfg =
915 AUDPP_CMD_OBJ0_UPDATE;
916 mbadrc_config->common.command_type = 0;
917 mbadrc_config->enable =
918 acdb_mbadrc_rtc->enable;
919 mbadrc_config->num_bands =
920 acdb_mbadrc_rtc->num_bands;
921 mbadrc_config->down_samp_level =
922 acdb_mbadrc_rtc->down_samp_level;
923 mbadrc_config->adrc_delay =
924 acdb_mbadrc_rtc->adrc_delay;
925 memcpy(mbadrc_config->adrc_band,\
926 acdb_mbadrc_rtc->adrc_band,\
927 AUDPP_MAX_MBADRC_BANDS *\
928 sizeof(struct adrc_config));
929 if (mbadrc_config->num_bands > 1) {
930 mbadrc_config->ext_buf_size =
931 (97 * 2) + (33 * 2 * \
932 (mbadrc_config->num_bands - 2));
933 }
934 mbadrc_config->ext_partition = 0;
935 mbadrc_config->ext_buf_lsw =
936 (u16) EXTRACT_LOW_WORD(\
937 rtc_write->phys);
938 mbadrc_config->ext_buf_msw =
939 (u16) EXTRACT_HIGH_WORD(\
940 rtc_write->phys);
941 memcpy(rtc_write->viraddr,
942 acdb_mbadrc_rtc->ExtBuff,
943 (196*sizeof(signed int)));
944 result = audpp_dsp_set_mbadrc(
945 acdb_data.device_info->dev_id,
946 mbadrc_config->enable,
947 mbadrc_config, COPP);
948 if (result) {
949 MM_ERR("ACDB=> Failed to \
950 Send MBADRC data \
951 to postproc\n");
952 } else {
953 retval = true;
954 }
955 } else {
956 MM_ERR("ACDB DATA WRITE ---\
957 MBADRC Rx copy_from_user Fail\n");
958 }
959 } else {
960 MM_ERR("ACDB DATA WRITE --MBADRC kalloc Failed LEN\n");
961 }
962 if (mbadrc_config != NULL)
963 kfree(mbadrc_config);
964 if (acdb_mbadrc_rtc != NULL)
965 kfree(acdb_mbadrc_rtc);
966 break;
967 }
968 case AUDPP_CMD_SIDECHAIN_TUNING_FILTER:
969 {
970 stf_config = kmalloc(sizeof(struct \
971 audpp_cmd_cfg_object_params_sidechain),\
972 GFP_KERNEL);
973 if ((sizeof(struct audpp_cmd_cfg_object_params_sidechain) -\
974 sizeof(struct audpp_cmd_cfg_object_params_common))
975 < writecount) {
976 MM_ERR("ACDB DATA WRITE --\
977 STF RX writecount > DSP struct\n");
978 } else {
979 if (stf_config != NULL) {
980 char *base; unsigned short offset;
981 unsigned short *offset_addr;
982 base = (char *)stf_config;
983 offset = offsetof(struct \
984 audpp_cmd_cfg_object_params_sidechain,\
985 active_flag);
986 offset_addr = (unsigned short *)(base+offset);
987 if ((copy_from_user(offset_addr,\
988 (void *)ubuf, writecount)) == 0x00) {
989 stf_config->common.cmd_id =
990 AUDPP_CMD_CFG_OBJECT_PARAMS;
991 stf_config->common.stream =
992 AUDPP_CMD_COPP_STREAM;
993 stf_config->common.stream_id = 0;
994 stf_config->common.obj_cfg =
995 AUDPP_CMD_OBJ0_UPDATE;
996 stf_config->common.command_type = 0;
997 MM_ERR("ACDB RX WRITE DATA:\
998 AUDPP_CMD_SIDECHAIN_TUNING_FILTER\n");
999 result = audpp_dsp_set_stf(
1000 acdb_data.device_info->dev_id,\
1001 stf_config->active_flag,\
1002 stf_config, COPP);
1003 if (result) {
1004 MM_ERR("ACDB=> Failed to send \
1005 STF data to postproc\n");
1006 } else {
1007 retval = true;
1008 }
1009 } else {
1010 MM_ERR("ACDB DATA WRITE ---\
1011 STF Rx copy_from_user Fail\n");
1012 }
1013 } else {
1014 MM_ERR("ACDB DATA WRITE \
1015 STF kalloc Failed LEN\n");
1016 }
1017 }
1018 if (stf_config != NULL)
1019 kfree(stf_config);
1020 break;
1021 }
1022 }
1023 return retval;
1024}
1025static ssize_t rtc_getsetabid_data_dbg_write(struct file *filp,
1026 const char __user *ubuf,
1027 size_t cnt, loff_t *ppos)
1028{
1029 if (rtc_acdb.valid_abid != true) {
1030 MM_INFO("ACDB DATA READ ---INVALID ABID\n");
1031 rtc_acdb.err = ACDB_RTC_ERR_INVALID_ABID;
1032 } else {
1033 if (rtc_acdb.tx_rx_ctl == ACDB_RTC_RX) {
1034 if (acdb_set_rx_rtc(ubuf, cnt)) {
1035 rtc_acdb.err = ACDB_RTC_SUCCESS;
1036 } else {
1037 rtc_acdb.err = ACDB_RTC_ERR_UNKNOWN_FAILURE;
1038 cnt = 0;
1039 }
1040 } else if (rtc_acdb.tx_rx_ctl == ACDB_RTC_TX) {
1041 if (acdb_set_tx_rtc(ubuf, cnt)) {
1042 rtc_acdb.err = ACDB_RTC_SUCCESS;
1043 } else {
1044 rtc_acdb.err = ACDB_RTC_ERR_UNKNOWN_FAILURE;
1045 cnt = 0;
1046 }
1047 }
1048 }
1049 return cnt;
1050}
1051
1052
1053static const struct file_operations rtc_acdb_data_debug_fops = {
1054 .open = rtc_getsetabid_data_dbg_open,
1055 .write = rtc_getsetabid_data_dbg_write,
1056 .read = rtc_getsetabid_data_dbg_read
1057};
1058
1059static const struct file_operations rtc_acdb_debug_fops = {
1060 .open = rtc_getsetabid_dbg_open,
1061 .write = rtc_getsetabid_dbg_write,
1062 .read = rtc_getsetabid_dbg_read
1063};
1064
1065static void rtc_acdb_deinit(void)
1066{
1067 struct rtc_acdb_pmem *rtc_read = &rtc_acdb.rtc_read;
1068 struct rtc_acdb_pmem *rtc_write = &rtc_acdb.rtc_write;
1069 if (get_set_abid_dentry) {
1070 MM_DBG("GetSet ABID remove debugfs\n");
1071 debugfs_remove(get_set_abid_dentry);
1072 }
1073
1074 if (get_set_abid_data_dentry) {
1075 MM_DBG("GetSet ABID remove debugfs\n");
1076 debugfs_remove(get_set_abid_data_dentry);
1077 }
1078 rtc_acdb.abid = 0;
1079 rtc_acdb.acdb_id = 0;
1080 rtc_acdb.cmd_id = 0;
1081 rtc_acdb.err = 1;
1082 rtc_acdb.set_abid = 0;
1083 rtc_acdb.set_iid = 0;
1084 rtc_acdb.tx_rx_ctl = 0;
1085 rtc_acdb.valid_abid = false;
1086
1087 if (rtc_read->viraddr != NULL || ((void *)rtc_read->phys) != NULL) {
Laura Abbott61399692012-04-30 14:25:46 -07001088 iounmap(rtc_read->map_v_rtc);
Santosh Mardifdc227a2011-07-11 17:20:34 +05301089 free_contiguous_memory_by_paddr(rtc_read->phys);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001090 }
1091 if (rtc_write->viraddr != NULL || ((void *)rtc_write->phys) != NULL) {
Laura Abbott61399692012-04-30 14:25:46 -07001092 iounmap(rtc_write->map_v_rtc);
Santosh Mardifdc227a2011-07-11 17:20:34 +05301093 free_contiguous_memory_by_paddr(rtc_write->phys);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001094 }
1095}
1096
1097static bool rtc_acdb_init(void)
1098{
1099 struct rtc_acdb_pmem *rtc_read = &rtc_acdb.rtc_read;
1100 struct rtc_acdb_pmem *rtc_write = &rtc_acdb.rtc_write;
1101 s32 result = 0;
1102 char name[sizeof "get_set_abid"+1];
1103 char name1[sizeof "get_set_abid_data"+1];
1104 rtc_acdb.abid = 0;
1105 rtc_acdb.acdb_id = 0;
1106 rtc_acdb.cmd_id = 0;
1107 rtc_acdb.err = 1;
1108 rtc_acdb.set_abid = 0;
1109 rtc_acdb.set_iid = 0;
1110 rtc_acdb.valid_abid = false;
1111 rtc_acdb.tx_rx_ctl = 0;
Kalyani polepeddyaeea8bf2011-10-20 10:51:07 +05301112 if (acdb_data.build_id[17] == '1') {
1113 snprintf(name, sizeof name, "get_set_abid");
1114 get_set_abid_dentry = debugfs_create_file(name,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001115 S_IFREG | S_IRUGO | S_IWUGO,
1116 NULL, NULL, &rtc_acdb_debug_fops);
Kalyani polepeddyaeea8bf2011-10-20 10:51:07 +05301117 if (IS_ERR(get_set_abid_dentry)) {
1118 MM_ERR("SET GET ABID debugfs_create_file failed\n");
1119 return false;
1120 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001121
Kalyani polepeddyaeea8bf2011-10-20 10:51:07 +05301122 snprintf(name1, sizeof name1, "get_set_abid_data");
1123 get_set_abid_data_dentry = debugfs_create_file(name1,
1124 S_IFREG | S_IRUGO | S_IWUGO,
1125 NULL, NULL,
1126 &rtc_acdb_data_debug_fops);
1127 if (IS_ERR(get_set_abid_data_dentry)) {
1128 MM_ERR("SET GET ABID DATA"
1129 " debugfs_create_file failed\n");
1130 return false;
1131 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001132 }
1133
Santosh Mardifdc227a2011-07-11 17:20:34 +05301134 rtc_read->phys = allocate_contiguous_ebi_nomap(PMEM_RTC_ACDB_QUERY_MEM,
1135 SZ_4K);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001136
Santosh Mardifdc227a2011-07-11 17:20:34 +05301137 if (!rtc_read->phys) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001138 MM_ERR("ACDB Cannot allocate physical memory\n");
1139 result = -ENOMEM;
1140 goto error;
1141 }
Laura Abbott61399692012-04-30 14:25:46 -07001142 rtc_read->map_v_rtc = ioremap(rtc_read->phys,
1143 PMEM_RTC_ACDB_QUERY_MEM);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001144
Santosh Mardifdc227a2011-07-11 17:20:34 +05301145 if (IS_ERR(rtc_read->map_v_rtc)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001146 MM_ERR("ACDB Could not map physical address\n");
1147 result = -ENOMEM;
1148 goto error;
1149 }
Laura Abbott61399692012-04-30 14:25:46 -07001150 rtc_read->viraddr = rtc_read->map_v_rtc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001151 memset(rtc_read->viraddr, 0, PMEM_RTC_ACDB_QUERY_MEM);
1152
Santosh Mardifdc227a2011-07-11 17:20:34 +05301153 rtc_write->phys = allocate_contiguous_ebi_nomap(PMEM_RTC_ACDB_QUERY_MEM,
1154 SZ_4K);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001155
Santosh Mardifdc227a2011-07-11 17:20:34 +05301156 if (!rtc_write->phys) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001157 MM_ERR("ACDB Cannot allocate physical memory\n");
1158 result = -ENOMEM;
1159 goto error;
1160 }
Laura Abbott61399692012-04-30 14:25:46 -07001161 rtc_write->map_v_rtc = ioremap(rtc_write->phys,
1162 PMEM_RTC_ACDB_QUERY_MEM);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001163
Santosh Mardifdc227a2011-07-11 17:20:34 +05301164 if (IS_ERR(rtc_write->map_v_rtc)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001165 MM_ERR("ACDB Could not map physical address\n");
1166 result = -ENOMEM;
1167 goto error;
1168 }
Laura Abbott61399692012-04-30 14:25:46 -07001169 rtc_write->viraddr = rtc_write->map_v_rtc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001170 memset(rtc_write->viraddr, 0, PMEM_RTC_ACDB_QUERY_MEM);
1171 init_waitqueue_head(&rtc_acdb.wait);
1172 return true;
1173error:
1174 MM_DBG("INIT RTC FAILED REMOVING RTC DEBUG FS\n");
1175 if (get_set_abid_dentry) {
1176 MM_DBG("GetSet ABID remove debugfs\n");
1177 debugfs_remove(get_set_abid_dentry);
1178 }
1179
1180 if (get_set_abid_data_dentry) {
1181 MM_DBG("GetSet ABID remove debugfs\n");
1182 debugfs_remove(get_set_abid_data_dentry);
1183 }
1184 if (rtc_read->viraddr != NULL || ((void *)rtc_read->phys) != NULL) {
Laura Abbott61399692012-04-30 14:25:46 -07001185 iounmap(rtc_read->map_v_rtc);
Santosh Mardifdc227a2011-07-11 17:20:34 +05301186 free_contiguous_memory_by_paddr(rtc_read->phys);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001187 }
1188 if (rtc_write->viraddr != NULL || ((void *)rtc_write->phys) != NULL) {
Laura Abbott61399692012-04-30 14:25:46 -07001189 iounmap(rtc_write->map_v_rtc);
Santosh Mardifdc227a2011-07-11 17:20:34 +05301190 free_contiguous_memory_by_paddr(rtc_write->phys);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001191 }
1192 return false;
1193}
1194#endif /*CONFIG_DEBUG_FS*/
1195static s32 acdb_set_calibration_blk(unsigned long arg)
1196{
1197 struct acdb_cmd_device acdb_cmd;
1198 s32 result = 0;
1199
1200 MM_DBG("acdb_set_calibration_blk\n");
1201 if (copy_from_user(&acdb_cmd, (struct acdb_cmd_device *)arg,
1202 sizeof(acdb_cmd))) {
1203 MM_ERR("Failed copy command struct from user in"
1204 "acdb_set_calibration_blk\n");
1205 return -EFAULT;
1206 }
1207 acdb_cmd.phys_buf = (u32 *)acdb_data.paddr;
1208
1209 MM_DBG("acdb_cmd.phys_buf %x\n", (u32)acdb_cmd.phys_buf);
1210
1211 result = dalrpc_fcn_8(ACDB_DalACDB_ioctl, acdb_data.handle,
1212 (const void *)&acdb_cmd, sizeof(acdb_cmd),
1213 &acdb_data.acdb_result,
1214 sizeof(acdb_data.acdb_result));
1215
1216 if (result < 0) {
1217 MM_ERR("ACDB=> Device Set RPC failure"
1218 " result = %d\n", result);
1219 return -EINVAL;
1220 } else {
1221 MM_ERR("ACDB=> Device Set RPC success\n");
1222 if (acdb_data.acdb_result.result == ACDB_RES_SUCCESS)
1223 MM_DBG("ACDB_SET_DEVICE Success\n");
1224 else if (acdb_data.acdb_result.result == ACDB_RES_FAILURE)
1225 MM_ERR("ACDB_SET_DEVICE Failure\n");
1226 else if (acdb_data.acdb_result.result == ACDB_RES_BADPARM)
1227 MM_ERR("ACDB_SET_DEVICE BadParams\n");
1228 else
1229 MM_ERR("Unknown error\n");
1230 }
1231 return result;
1232}
1233
1234static s32 acdb_get_calibration_blk(unsigned long arg)
1235{
1236 s32 result = 0;
1237 struct acdb_cmd_device acdb_cmd;
1238
1239 MM_DBG("acdb_get_calibration_blk\n");
1240
1241 if (copy_from_user(&acdb_cmd, (struct acdb_cmd_device *)arg,
1242 sizeof(acdb_cmd))) {
1243 MM_ERR("Failed copy command struct from user in"
1244 "acdb_get_calibration_blk\n");
1245 return -EFAULT;
1246 }
1247 acdb_cmd.phys_buf = (u32 *)acdb_data.paddr;
1248 MM_ERR("acdb_cmd.phys_buf %x\n", (u32)acdb_cmd.phys_buf);
1249
1250 result = dalrpc_fcn_8(ACDB_DalACDB_ioctl, acdb_data.handle,
1251 (const void *)&acdb_cmd, sizeof(acdb_cmd),
1252 &acdb_data.acdb_result,
1253 sizeof(acdb_data.acdb_result));
1254
1255 if (result < 0) {
1256 MM_ERR("ACDB=> Device Get RPC failure"
1257 " result = %d\n", result);
1258 return -EINVAL;
1259 } else {
1260 MM_ERR("ACDB=> Device Get RPC Success\n");
1261 if (acdb_data.acdb_result.result == ACDB_RES_SUCCESS)
1262 MM_DBG("ACDB_GET_DEVICE Success\n");
1263 else if (acdb_data.acdb_result.result == ACDB_RES_FAILURE)
1264 MM_ERR("ACDB_GET_DEVICE Failure\n");
1265 else if (acdb_data.acdb_result.result == ACDB_RES_BADPARM)
1266 MM_ERR("ACDB_GET_DEVICE BadParams\n");
1267 else
1268 MM_ERR("Unknown error\n");
1269 }
1270 return result;
1271}
1272
1273static int audio_acdb_open(struct inode *inode, struct file *file)
1274{
1275 MM_DBG("%s\n", __func__);
1276 return 0;
1277}
1278static int audio_acdb_release(struct inode *inode, struct file *file)
1279{
1280 MM_DBG("%s\n", __func__);
1281 return 0;
1282}
1283
1284static long audio_acdb_ioctl(struct file *file, unsigned int cmd,
1285 unsigned long arg)
1286{
1287 int rc = 0;
1288 unsigned long flags = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001289
1290 MM_DBG("%s\n", __func__);
1291
1292 switch (cmd) {
1293 case AUDIO_SET_EQ:
1294 MM_DBG("IOCTL SET_EQ_CONFIG\n");
1295 if (copy_from_user(&acdb_data.eq.num_bands, (void *) arg,
1296 sizeof(acdb_data.eq) -
1297 (AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN + 2))) {
1298 rc = -EFAULT;
1299 break;
1300 }
1301 spin_lock_irqsave(&acdb_data.dsp_lock, flags);
1302 acdb_data.dec_id = 0;
1303 rc = audpp_dsp_set_eq(acdb_data.dec_id, 1,
1304 &acdb_data.eq, COPP);
1305 if (rc < 0)
1306 MM_ERR("AUDPP returned err =%d\n", rc);
1307 spin_unlock_irqrestore(&acdb_data.dsp_lock, flags);
1308 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001309 case AUDIO_SET_ACDB_BLK:
1310 MM_DBG("IOCTL AUDIO_SET_ACDB_BLK\n");
1311 rc = acdb_set_calibration_blk(arg);
1312 break;
1313 case AUDIO_GET_ACDB_BLK:
1314 MM_DBG("IOiCTL AUDIO_GET_ACDB_BLK\n");
1315 rc = acdb_get_calibration_blk(arg);
1316 break;
1317 default:
1318 MM_DBG("Unknown IOCTL%d\n", cmd);
1319 rc = -EINVAL;
1320 }
1321 return rc;
1322}
1323
1324static const struct file_operations acdb_fops = {
1325 .owner = THIS_MODULE,
1326 .open = audio_acdb_open,
1327 .release = audio_acdb_release,
1328 .llseek = no_llseek,
1329 .unlocked_ioctl = audio_acdb_ioctl
1330};
1331
1332struct miscdevice acdb_misc = {
1333 .minor = MISC_DYNAMIC_MINOR,
1334 .name = "msm_acdb",
1335 .fops = &acdb_fops,
1336};
1337
1338static s32 acdb_get_calibration(void)
1339{
1340 struct acdb_cmd_get_device_table acdb_cmd;
1341 s32 result = 0;
1342 u32 iterations = 0;
1343
1344 MM_DBG("acdb state = %d\n", acdb_data.acdb_state);
1345
1346 acdb_cmd.command_id = ACDB_GET_DEVICE_TABLE;
1347 acdb_cmd.device_id = acdb_data.device_info->acdb_id;
1348 acdb_cmd.network_id = 0x0108B153;
1349 acdb_cmd.sample_rate_id = acdb_data.device_info->sample_rate;
1350 acdb_cmd.total_bytes = ACDB_BUF_SIZE;
1351 acdb_cmd.phys_buf = (u32 *)acdb_data.phys_addr;
1352 MM_DBG("device_id = %d, sampling_freq = %d\n",
1353 acdb_cmd.device_id, acdb_cmd.sample_rate_id);
1354
1355 do {
1356 result = dalrpc_fcn_8(ACDB_DalACDB_ioctl, acdb_data.handle,
1357 (const void *)&acdb_cmd, sizeof(acdb_cmd),
1358 &acdb_data.acdb_result,
1359 sizeof(acdb_data.acdb_result));
1360
1361 if (result < 0) {
1362 MM_ERR("ACDB=> Device table RPC failure"
1363 " result = %d\n", result);
1364 goto error;
1365 }
1366 /*following check is introduced to handle boot up race
1367 condition between AUDCAL SW peers running on apps
1368 and modem (ACDB_RES_BADSTATE indicates modem AUDCAL SW is
1369 not in initialized sate) we need to retry to get ACDB
1370 values*/
1371 if (acdb_data.acdb_result.result == ACDB_RES_BADSTATE) {
1372 msleep(500);
1373 iterations++;
1374 } else if (acdb_data.acdb_result.result == ACDB_RES_SUCCESS) {
1375 MM_DBG("Modem query for acdb values is successful"
1376 " (iterations = %d)\n", iterations);
1377 acdb_data.acdb_state |= CAL_DATA_READY;
1378 return result;
1379 } else {
1380 MM_ERR("ACDB=> modem failed to fill acdb values,"
1381 " reuslt = %d, (iterations = %d)\n",
1382 acdb_data.acdb_result.result,
1383 iterations);
1384 goto error;
1385 }
1386 } while (iterations < MAX_RETRY);
1387 MM_ERR("ACDB=> AUDCAL SW on modem is not in intiailized state (%d)\n",
1388 acdb_data.acdb_result.result);
1389error:
1390 result = -EINVAL;
1391 return result;
1392}
1393
1394s32 acdb_get_calibration_data(struct acdb_get_block *get_block)
1395{
1396 s32 result = -EINVAL;
1397 struct acdb_cmd_device acdb_cmd;
1398 struct acdb_result acdb_result;
1399
1400 MM_DBG("acdb_get_calibration_data\n");
1401
1402 acdb_cmd.command_id = ACDB_GET_DEVICE;
1403 acdb_cmd.network_id = 0x0108B153;
1404 acdb_cmd.device_id = get_block->acdb_id;
1405 acdb_cmd.sample_rate_id = get_block->sample_rate_id;
1406 acdb_cmd.interface_id = get_block->interface_id;
1407 acdb_cmd.algorithm_block_id = get_block->algorithm_block_id;
1408 acdb_cmd.total_bytes = get_block->total_bytes;
1409 acdb_cmd.phys_buf = (u32 *)acdb_data.get_blk_paddr;
1410
1411 result = dalrpc_fcn_8(ACDB_DalACDB_ioctl, acdb_data.handle,
1412 (const void *)&acdb_cmd, sizeof(acdb_cmd),
1413 &acdb_result,
1414 sizeof(acdb_result));
1415
1416 if (result < 0) {
1417 MM_ERR("ACDB=> Device Get RPC failure"
1418 " result = %d\n", result);
1419 goto err_state;
1420 } else {
1421 MM_DBG("ACDB=> Device Get RPC Success\n");
1422 if (acdb_result.result == ACDB_RES_SUCCESS) {
1423 MM_DBG("ACDB_GET_DEVICE Success\n");
1424 result = 0;
1425 memcpy(get_block->buf_ptr, acdb_data.get_blk_kvaddr,
1426 get_block->total_bytes);
1427 } else if (acdb_result.result == ACDB_RES_FAILURE)
1428 MM_ERR("ACDB_GET_DEVICE Failure\n");
1429 else if (acdb_result.result == ACDB_RES_BADPARM)
1430 MM_ERR("ACDB_GET_DEVICE BadParams\n");
1431 else
1432 MM_ERR("Unknown error\n");
1433 }
1434err_state:
1435 return result;
1436}
1437EXPORT_SYMBOL(acdb_get_calibration_data);
1438
1439static u8 check_device_info_already_present(
1440 struct auddev_evt_audcal_info audcal_info,
1441 struct acdb_cache_node *acdb_cache_free_node)
1442{
1443 if ((audcal_info.dev_id ==
1444 acdb_cache_free_node->device_info.dev_id) &&
1445 (audcal_info.sample_rate ==
1446 acdb_cache_free_node->device_info.\
1447 sample_rate) &&
1448 (audcal_info.acdb_id ==
1449 acdb_cache_free_node->device_info.acdb_id)) {
1450 MM_DBG("acdb values are already present\n");
1451 /*if acdb state is not set for CAL_DATA_READY and node status
1452 is filled, acdb state should be updated with CAL_DATA_READY
1453 state*/
1454 acdb_data.acdb_state |= CAL_DATA_READY;
1455 /*checking for cache node status if it is not filled then the
1456 acdb values are not cleaned from node so update node status
1457 with acdb value filled*/
1458 if ((acdb_cache_free_node->node_status != ACDB_VALUES_FILLED) &&
Santosh Mardie9185852011-09-08 10:38:31 +05301459 ((audcal_info.dev_type & RX_DEVICE) == 1)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001460 MM_DBG("device was released earlier\n");
1461 acdb_cache_free_node->node_status = ACDB_VALUES_FILLED;
1462 return 2; /*node is presnet but status as not filled*/
1463 }
1464 return 1; /*node is present but status as filled*/
1465 }
1466 MM_DBG("copying device info into node\n");
1467 /*as device information is not present in cache copy
1468 the current device information into the node*/
1469 memcpy(&acdb_cache_free_node->device_info,
1470 &audcal_info, sizeof(audcal_info));
1471 return 0; /*cant find the node*/
1472}
1473
1474static struct acdb_iir_block *get_audpp_irr_block(void)
1475{
1476 struct header *prs_hdr;
1477 u32 index = 0;
1478
1479 while (index < acdb_data.acdb_result.used_bytes) {
1480 prs_hdr = (struct header *)(acdb_data.virt_addr + index);
1481 if (prs_hdr->dbor_signature == DBOR_SIGNATURE) {
1482 if (prs_hdr->abid == ABID_AUDIO_IIR_RX) {
1483 if (prs_hdr->iid == IID_AUDIO_IIR_COEFF)
1484 return (struct acdb_iir_block *)
1485 (acdb_data.virt_addr + index
1486 + sizeof(struct header));
1487 } else {
1488 index += prs_hdr->data_len +
1489 sizeof(struct header);
1490 }
1491 } else {
1492 break;
1493 }
1494 }
1495 return NULL;
1496}
1497
1498
1499static s32 acdb_fill_audpp_iir(void)
1500{
1501 struct acdb_iir_block *acdb_iir;
1502 s32 i = 0;
1503
1504 acdb_iir = get_audpp_irr_block();
1505 if (acdb_iir == NULL) {
1506 MM_ERR("unable to find audpp iir block returning\n");
1507 return -1;
1508 }
1509 memset(acdb_data.pp_iir, 0, sizeof(*acdb_data.pp_iir));
1510
1511 acdb_data.pp_iir->common.cmd_id = AUDPP_CMD_CFG_OBJECT_PARAMS;
1512 acdb_data.pp_iir->common.stream = AUDPP_CMD_COPP_STREAM;
1513 acdb_data.pp_iir->common.stream_id = 0;
1514 acdb_data.pp_iir->common.obj_cfg = AUDPP_CMD_OBJ0_UPDATE;
1515 acdb_data.pp_iir->common.command_type = 0;
1516
1517 acdb_data.pp_iir->active_flag = acdb_iir->enable_flag;
1518 acdb_data.pp_iir->num_bands = acdb_iir->stage_count;
1519 for (; i < acdb_iir->stage_count; i++) {
1520 acdb_data.pp_iir->params_filter.filter_4_params.
1521 numerator_filter[i].numerator_b0_filter_lsw =
1522 acdb_iir->stages[i].b0_lo;
1523 acdb_data.pp_iir->params_filter.filter_4_params.
1524 numerator_filter[i].numerator_b0_filter_msw =
1525 acdb_iir->stages[i].b0_hi;
1526 acdb_data.pp_iir->params_filter.filter_4_params.
1527 numerator_filter[i].numerator_b1_filter_lsw =
1528 acdb_iir->stages[i].b1_lo;
1529 acdb_data.pp_iir->params_filter.filter_4_params.
1530 numerator_filter[i].numerator_b1_filter_msw =
1531 acdb_iir->stages[i].b1_hi;
1532 acdb_data.pp_iir->params_filter.filter_4_params.
1533 numerator_filter[i].numerator_b2_filter_lsw =
1534 acdb_iir->stages[i].b2_lo;
1535 acdb_data.pp_iir->params_filter.filter_4_params.
1536 numerator_filter[i].numerator_b2_filter_msw =
1537 acdb_iir->stages[i].b2_hi;
1538 acdb_data.pp_iir->params_filter.filter_4_params.
1539 denominator_filter[i].denominator_a0_filter_lsw =
1540 acdb_iir->stages_a[i].a1_lo;
1541 acdb_data.pp_iir->params_filter.filter_4_params.
1542 denominator_filter[i].denominator_a0_filter_msw =
1543 acdb_iir->stages_a[i].a1_hi;
1544 acdb_data.pp_iir->params_filter.filter_4_params.
1545 denominator_filter[i].denominator_a1_filter_lsw =
1546 acdb_iir->stages_a[i].a2_lo;
1547 acdb_data.pp_iir->params_filter.filter_4_params.
1548 denominator_filter[i].denominator_a1_filter_msw =
1549 acdb_iir->stages_a[i].a2_hi;
1550 acdb_data.pp_iir->params_filter.filter_4_params.
1551 shift_factor_filter[i].shift_factor_0 =
1552 acdb_iir->shift_factor[i];
1553 acdb_data.pp_iir->params_filter.filter_4_params.pan_filter[i].
1554 pan_filter_0 = acdb_iir->pan[i];
1555 }
1556 return 0;
1557}
1558
1559static void extract_mbadrc(u32 *phy_addr, struct header *prs_hdr, u32 *index)
1560{
1561 if (prs_hdr->iid == IID_MBADRC_EXT_BUFF) {
1562 MM_DBG("Got IID = IID_MBADRC_EXT_BUFF\n");
1563 *phy_addr = acdb_data.phys_addr + *index +
1564 sizeof(struct header);
1565 memcpy(acdb_data.mbadrc_block.ext_buf,
1566 (acdb_data.virt_addr + *index +
1567 sizeof(struct header)), 196*2);
1568 MM_DBG("phy_addr = %x\n", *phy_addr);
1569 *index += prs_hdr->data_len + sizeof(struct header);
1570 } else if (prs_hdr->iid == IID_MBADRC_BAND_CONFIG) {
1571 MM_DBG("Got IID == IID_MBADRC_BAND_CONFIG\n");
1572 memcpy(acdb_data.mbadrc_block.band_config, (acdb_data.virt_addr
1573 + *index + sizeof(struct header)),
1574 sizeof(struct mbadrc_band_config_type) *
1575 acdb_data.mbadrc_block.parameters.\
1576 mbadrc_num_bands);
1577 *index += prs_hdr->data_len + sizeof(struct header);
1578 } else if (prs_hdr->iid == IID_MBADRC_PARAMETERS) {
1579 struct mbadrc_parameter *tmp;
1580 tmp = (struct mbadrc_parameter *)(acdb_data.virt_addr + *index
1581 + sizeof(struct header));
1582 MM_DBG("Got IID == IID_MBADRC_PARAMETERS\n");
1583 acdb_data.mbadrc_block.parameters.mbadrc_enable =
1584 tmp->mbadrc_enable;
1585 acdb_data.mbadrc_block.parameters.mbadrc_num_bands =
1586 tmp->mbadrc_num_bands;
1587 acdb_data.mbadrc_block.parameters.mbadrc_down_sample_level =
1588 tmp->mbadrc_down_sample_level;
1589 acdb_data.mbadrc_block.parameters.mbadrc_delay =
1590 tmp->mbadrc_delay;
1591 *index += prs_hdr->data_len + sizeof(struct header);
1592 }
1593}
1594
1595static void get_audpp_mbadrc_block(u32 *phy_addr)
1596{
1597 struct header *prs_hdr;
1598 u32 index = 0;
1599
1600 while (index < acdb_data.acdb_result.used_bytes) {
1601 prs_hdr = (struct header *)(acdb_data.virt_addr + index);
1602
1603 if (prs_hdr->dbor_signature == DBOR_SIGNATURE) {
1604 if (prs_hdr->abid == ABID_AUDIO_MBADRC_RX) {
1605 if ((prs_hdr->iid == IID_MBADRC_EXT_BUFF)
1606 || (prs_hdr->iid ==
1607 IID_MBADRC_BAND_CONFIG)
1608 || (prs_hdr->iid ==
1609 IID_MBADRC_PARAMETERS)) {
1610 extract_mbadrc(phy_addr, prs_hdr,
1611 &index);
1612 }
1613 } else {
1614 index += prs_hdr->data_len +
1615 sizeof(struct header);
1616 }
1617 } else {
1618 break;
1619 }
1620 }
1621}
1622
1623static s32 acdb_fill_audpp_mbadrc(void)
1624{
1625 u32 mbadrc_phys_addr = -1;
1626 get_audpp_mbadrc_block(&mbadrc_phys_addr);
1627 if (IS_ERR_VALUE(mbadrc_phys_addr)) {
1628 MM_ERR("failed to get mbadrc block\n");
1629 return -1;
1630 }
1631
1632 memset(acdb_data.pp_mbadrc, 0, sizeof(*acdb_data.pp_mbadrc));
1633
1634 acdb_data.pp_mbadrc->common.cmd_id = AUDPP_CMD_CFG_OBJECT_PARAMS;
1635 acdb_data.pp_mbadrc->common.stream = AUDPP_CMD_COPP_STREAM;
1636 acdb_data.pp_mbadrc->common.stream_id = 0;
1637 acdb_data.pp_mbadrc->common.obj_cfg = AUDPP_CMD_OBJ0_UPDATE;
1638 acdb_data.pp_mbadrc->common.command_type = 0;
1639
1640 acdb_data.pp_mbadrc->enable = acdb_data.mbadrc_block.\
1641 parameters.mbadrc_enable;
1642 acdb_data.pp_mbadrc->num_bands =
1643 acdb_data.mbadrc_block.\
1644 parameters.mbadrc_num_bands;
1645 acdb_data.pp_mbadrc->down_samp_level =
1646 acdb_data.mbadrc_block.parameters.\
1647 mbadrc_down_sample_level;
1648 acdb_data.pp_mbadrc->adrc_delay =
1649 acdb_data.mbadrc_block.parameters.\
1650 mbadrc_delay;
1651
1652 if (acdb_data.mbadrc_block.parameters.mbadrc_num_bands > 1)
1653 acdb_data.pp_mbadrc->ext_buf_size = (97 * 2) +
1654 (33 * 2 * (acdb_data.mbadrc_block.parameters.\
1655 mbadrc_num_bands - 2));
1656
1657 acdb_data.pp_mbadrc->ext_partition = 0;
1658 acdb_data.pp_mbadrc->ext_buf_lsw = (u16)(mbadrc_phys_addr\
1659 & 0xFFFF);
1660 acdb_data.pp_mbadrc->ext_buf_msw = (u16)((mbadrc_phys_addr\
1661 & 0xFFFF0000) >> 16);
1662 memcpy(acdb_data.pp_mbadrc->adrc_band, acdb_data.mbadrc_block.\
1663 band_config,
1664 sizeof(struct mbadrc_band_config_type) *
1665 acdb_data.mbadrc_block.parameters.mbadrc_num_bands);
1666 return 0;
1667}
1668
1669static struct acdb_calib_gain_rx *get_audpp_cal_gain(void)
1670{
1671 struct header *prs_hdr;
1672 u32 index = 0;
1673
1674 while (index < acdb_data.acdb_result.used_bytes) {
1675 prs_hdr = (struct header *)(acdb_data.virt_addr + index);
1676 if (prs_hdr->dbor_signature == DBOR_SIGNATURE) {
1677 if (prs_hdr->abid == ABID_AUDIO_CALIBRATION_GAIN_RX) {
1678 if (prs_hdr->iid ==
1679 IID_AUDIO_CALIBRATION_GAIN_RX) {
1680 MM_DBG("Got audpp_calib_gain_rx"
1681 " block\n");
1682 return (struct acdb_calib_gain_rx *)
1683 (acdb_data.virt_addr + index
1684 + sizeof(struct header));
1685 }
1686 } else {
1687 index += prs_hdr->data_len +
1688 sizeof(struct header);
1689 }
1690 } else {
1691 break;
1692 }
1693 }
1694 return NULL;
1695}
1696
1697static s32 acdb_fill_audpp_cal_gain(void)
1698{
1699 struct acdb_calib_gain_rx *acdb_calib_gain_rx = NULL;
1700
1701 acdb_calib_gain_rx = get_audpp_cal_gain();
1702 if (acdb_calib_gain_rx == NULL) {
1703 MM_ERR("unable to find audpp"
1704 " calibration gain block returning\n");
1705 return -1;
1706 }
1707 MM_DBG("Calibration value"
1708 " for calib_gain_rx %d\n", acdb_calib_gain_rx->audppcalgain);
1709 memset(acdb_data.calib_gain_rx, 0, sizeof(*acdb_data.calib_gain_rx));
1710
1711 acdb_data.calib_gain_rx->common.cmd_id = AUDPP_CMD_CFG_OBJECT_PARAMS;
1712 acdb_data.calib_gain_rx->common.stream = AUDPP_CMD_COPP_STREAM;
1713 acdb_data.calib_gain_rx->common.stream_id = 0;
1714 acdb_data.calib_gain_rx->common.obj_cfg = AUDPP_CMD_OBJ0_UPDATE;
1715 acdb_data.calib_gain_rx->common.command_type = 0;
1716
1717 acdb_data.calib_gain_rx->audppcalgain =
1718 acdb_calib_gain_rx->audppcalgain;
1719 return 0;
1720}
1721
1722static void extract_pbe_block(struct header *prs_hdr, u32 *index)
1723{
1724 if (prs_hdr->iid == IID_AUDIO_PBE_RX_ENABLE_FLAG) {
1725 MM_DBG("Got IID = IID_AUDIO_PBE_RX_ENABLE\n");
1726 acdb_data.pbe_enable_flag = (u16 *)(acdb_data.virt_addr +
1727 *index +
1728 sizeof(struct header));
1729 *index += prs_hdr->data_len + sizeof(struct header);
1730 } else if (prs_hdr->iid == IID_PBE_CONFIG_PARAMETERS) {
1731 MM_DBG("Got IID == IID_PBE_CONFIG_PARAMETERS\n");
1732 acdb_data.pbe_blk = (struct acdb_pbe_block *)
1733 (acdb_data.virt_addr + *index
1734 + sizeof(struct header));
1735 *index += prs_hdr->data_len + sizeof(struct header);
1736 }
1737}
1738
1739static s32 get_audpp_pbe_block(void)
1740{
1741 struct header *prs_hdr;
1742 u32 index = 0;
1743 s32 result = -1;
1744
1745 while (index < acdb_data.acdb_result.used_bytes) {
1746 prs_hdr = (struct header *)(acdb_data.virt_addr + index);
1747
1748 if (prs_hdr->dbor_signature == DBOR_SIGNATURE) {
1749 if (prs_hdr->abid == ABID_AUDIO_PBE_RX) {
1750 if ((prs_hdr->iid == IID_PBE_CONFIG_PARAMETERS)
1751 || (prs_hdr->iid ==
1752 IID_AUDIO_PBE_RX_ENABLE_FLAG)) {
1753 extract_pbe_block(prs_hdr, &index);
1754 result = 0;
1755 }
1756 } else {
1757 index += prs_hdr->data_len +
1758 sizeof(struct header);
1759 }
1760 } else {
1761 break;
1762 }
1763 }
1764 return result;
1765}
1766
1767static s32 acdb_fill_audpp_pbe(void)
1768{
1769 s32 result = -1;
1770
1771 result = get_audpp_pbe_block();
1772 if (IS_ERR_VALUE(result))
1773 return result;
1774 memset(acdb_data.pbe_block, 0, sizeof(*acdb_data.pbe_block));
1775
1776 acdb_data.pbe_block->common.cmd_id = AUDPP_CMD_CFG_OBJECT_PARAMS;
1777 acdb_data.pbe_block->common.stream = AUDPP_CMD_COPP_STREAM;
1778 acdb_data.pbe_block->common.stream_id = 0;
1779 acdb_data.pbe_block->common.obj_cfg = AUDPP_CMD_OBJ0_UPDATE;
1780 acdb_data.pbe_block->common.command_type = 0;
1781 acdb_data.pbe_block->pbe_enable = *acdb_data.pbe_enable_flag;
1782
1783 acdb_data.pbe_block->realbassmix = acdb_data.pbe_blk->realbassmix;
1784 acdb_data.pbe_block->basscolorcontrol =
1785 acdb_data.pbe_blk->basscolorcontrol;
1786 acdb_data.pbe_block->mainchaindelay = acdb_data.pbe_blk->mainchaindelay;
1787 acdb_data.pbe_block->xoverfltorder = acdb_data.pbe_blk->xoverfltorder;
1788 acdb_data.pbe_block->bandpassfltorder =
1789 acdb_data.pbe_blk->bandpassfltorder;
1790 acdb_data.pbe_block->adrcdelay = acdb_data.pbe_blk->adrcdelay;
1791 acdb_data.pbe_block->downsamplelevel =
1792 acdb_data.pbe_blk->downsamplelevel;
1793 acdb_data.pbe_block->comprmstav = acdb_data.pbe_blk->comprmstav;
1794 acdb_data.pbe_block->expthreshold = acdb_data.pbe_blk->expthreshold;
1795 acdb_data.pbe_block->expslope = acdb_data.pbe_blk->expslope;
1796 acdb_data.pbe_block->compthreshold = acdb_data.pbe_blk->compthreshold;
1797 acdb_data.pbe_block->compslope = acdb_data.pbe_blk->compslope;
1798 acdb_data.pbe_block->cpmpattack_lsw = acdb_data.pbe_blk->cpmpattack_lsw;
1799 acdb_data.pbe_block->compattack_msw = acdb_data.pbe_blk->compattack_msw;
1800 acdb_data.pbe_block->comprelease_lsw =
1801 acdb_data.pbe_blk->comprelease_lsw;
1802 acdb_data.pbe_block->comprelease_msw =
1803 acdb_data.pbe_blk->comprelease_msw;
1804 acdb_data.pbe_block->compmakeupgain = acdb_data.pbe_blk->compmakeupgain;
1805 acdb_data.pbe_block->baselimthreshold =
1806 acdb_data.pbe_blk->baselimthreshold;
1807 acdb_data.pbe_block->highlimthreshold =
1808 acdb_data.pbe_blk->highlimthreshold;
1809 acdb_data.pbe_block->basslimmakeupgain =
1810 acdb_data.pbe_blk->basslimmakeupgain;
1811 acdb_data.pbe_block->highlimmakeupgain =
1812 acdb_data.pbe_blk->highlimmakeupgain;
1813 acdb_data.pbe_block->limbassgrc = acdb_data.pbe_blk->limbassgrc;
1814 acdb_data.pbe_block->limhighgrc = acdb_data.pbe_blk->limhighgrc;
1815 acdb_data.pbe_block->limdelay = acdb_data.pbe_blk->limdelay;
1816 memcpy(acdb_data.pbe_block->filter_coeffs,
1817 acdb_data.pbe_blk->filter_coeffs, sizeof(u16)*90);
1818 acdb_data.pbe_block->extpartition = 0;
1819 acdb_data.pbe_block->extbuffsize_lsw = PBE_BUF_SIZE;
1820 acdb_data.pbe_block->extbuffsize_msw = 0;
1821 acdb_data.pbe_block->extbuffstart_lsw = ((u32)acdb_data.pbe_extbuff
1822 & 0xFFFF);
1823 acdb_data.pbe_block->extbuffstart_msw = (((u32)acdb_data.pbe_extbuff
1824 & 0xFFFF0000) >> 16);
1825 return 0;
1826}
1827
1828
1829static s32 acdb_calibrate_audpp(void)
1830{
1831 s32 result = 0;
1832
1833 result = acdb_fill_audpp_iir();
1834 if (!IS_ERR_VALUE(result)) {
1835 result = audpp_dsp_set_rx_iir(acdb_data.device_info->dev_id,
1836 acdb_data.pp_iir->active_flag,
1837 acdb_data.pp_iir, COPP);
1838 if (result) {
1839 MM_ERR("ACDB=> Failed to send IIR data to postproc\n");
1840 result = -EINVAL;
1841 goto done;
1842 } else
1843 MM_DBG("AUDPP is calibrated with IIR parameters"
1844 " for COPP ID %d\n",
1845 acdb_data.device_info->dev_id);
1846 }
1847 result = acdb_fill_audpp_mbadrc();
1848 if (!IS_ERR_VALUE(result)) {
1849 result = audpp_dsp_set_mbadrc(acdb_data.device_info->dev_id,
1850 acdb_data.pp_mbadrc->enable,
1851 acdb_data.pp_mbadrc, COPP);
1852 if (result) {
1853 MM_ERR("ACDB=> Failed to send MBADRC data to"
1854 " postproc\n");
1855 result = -EINVAL;
1856 goto done;
1857 } else
1858 MM_DBG("AUDPP is calibrated with MBADRC parameters"
1859 " for COPP ID %d\n",
1860 acdb_data.device_info->dev_id);
1861 }
1862 result = acdb_fill_audpp_cal_gain();
1863 if (!(IS_ERR_VALUE(result))) {
1864 result = audpp_dsp_set_gain_rx(acdb_data.device_info->dev_id,
1865 acdb_data.calib_gain_rx, COPP);
1866 if (result) {
1867 MM_ERR("ACDB=> Failed to send gain_rx"
1868 " data to postproc\n");
1869 result = -EINVAL;
1870 goto done;
1871 } else
1872 MM_DBG("AUDPP is calibrated with calib_gain_rx\n");
1873 }
1874 result = acdb_fill_audpp_pbe();
1875 if (!(IS_ERR_VALUE(result))) {
1876 result = audpp_dsp_set_pbe(acdb_data.device_info->dev_id,
1877 acdb_data.pbe_block->pbe_enable,
1878 acdb_data.pbe_block, COPP);
1879 if (result) {
1880 MM_ERR("ACDB=> Failed to send pbe block"
1881 "data to postproc\n");
1882 result = -EINVAL;
1883 goto done;
1884 }
1885 MM_DBG("AUDPP is calibarted with PBE\n");
1886 }
1887done:
1888 return result;
1889}
1890
1891static struct acdb_agc_block *get_audpreproc_agc_block(void)
1892{
1893 struct header *prs_hdr;
1894 u32 index = 0;
1895
1896 while (index < acdb_data.acdb_result.used_bytes) {
1897 prs_hdr = (struct header *)(acdb_data.virt_addr + index);
1898 if (prs_hdr->dbor_signature == DBOR_SIGNATURE) {
1899 if (prs_hdr->abid == ABID_AUDIO_AGC_TX) {
1900 if (prs_hdr->iid == IID_AUDIO_AGC_PARAMETERS) {
1901 MM_DBG("GOT ABID_AUDIO_AGC_TX\n");
1902 return (struct acdb_agc_block *)
1903 (acdb_data.virt_addr + index
1904 + sizeof(struct header));
1905 }
1906 } else {
1907 index += prs_hdr->data_len +
1908 sizeof(struct header);
1909 }
1910 } else {
1911 break;
1912 }
1913 }
1914 return NULL;
1915}
1916
1917static s32 acdb_fill_audpreproc_agc(void)
1918{
1919 struct acdb_agc_block *acdb_agc;
1920
1921 acdb_agc = get_audpreproc_agc_block();
1922 if (!acdb_agc) {
1923 MM_DBG("unable to find preproc agc parameters winding up\n");
1924 return -1;
1925 }
1926 memset(acdb_data.preproc_agc, 0, sizeof(*acdb_data.preproc_agc));
1927 acdb_data.preproc_agc->cmd_id = AUDPREPROC_CMD_CFG_AGC_PARAMS;
1928 acdb_data.preproc_agc->stream_id = acdb_data.preproc_stream_id;
1929 /* 0xFE00 to configure all parameters */
1930 acdb_data.preproc_agc->tx_agc_param_mask = 0xFFFF;
1931
1932 if (acdb_agc->enable_status)
1933 acdb_data.preproc_agc->tx_agc_enable_flag =
1934 AUDPREPROC_CMD_TX_AGC_ENA_FLAG_ENA;
1935 else
1936 acdb_data.preproc_agc->tx_agc_enable_flag =
1937 AUDPREPROC_CMD_TX_AGC_ENA_FLAG_DIS;
1938
1939 acdb_data.preproc_agc->comp_rlink_static_gain =
1940 acdb_agc->comp_rlink_static_gain;
1941 acdb_data.preproc_agc->comp_rlink_aig_flag =
1942 acdb_agc->comp_rlink_aig_flag;
1943 acdb_data.preproc_agc->expander_rlink_th =
1944 acdb_agc->exp_rlink_threshold;
1945 acdb_data.preproc_agc->expander_rlink_slope =
1946 acdb_agc->exp_rlink_slope;
1947 acdb_data.preproc_agc->compressor_rlink_th =
1948 acdb_agc->comp_rlink_threshold;
1949 acdb_data.preproc_agc->compressor_rlink_slope =
1950 acdb_agc->comp_rlink_slope;
1951
1952 /* 0xFFF0 to configure all parameters */
1953 acdb_data.preproc_agc->tx_adc_agc_param_mask = 0xFFFF;
1954
1955 acdb_data.preproc_agc->comp_rlink_aig_attackk =
1956 acdb_agc->comp_rlink_aig_attack_k;
1957 acdb_data.preproc_agc->comp_rlink_aig_leak_down =
1958 acdb_agc->comp_rlink_aig_leak_down;
1959 acdb_data.preproc_agc->comp_rlink_aig_leak_up =
1960 acdb_agc->comp_rlink_aig_leak_up;
1961 acdb_data.preproc_agc->comp_rlink_aig_max =
1962 acdb_agc->comp_rlink_aig_max;
1963 acdb_data.preproc_agc->comp_rlink_aig_min =
1964 acdb_agc->comp_rlink_aig_min;
1965 acdb_data.preproc_agc->comp_rlink_aig_releasek =
1966 acdb_agc->comp_rlink_aig_release_k;
1967 acdb_data.preproc_agc->comp_rlink_aig_leakrate_fast =
1968 acdb_agc->comp_rlink_aig_sm_leak_rate_fast;
1969 acdb_data.preproc_agc->comp_rlink_aig_leakrate_slow =
1970 acdb_agc->comp_rlink_aig_sm_leak_rate_slow;
1971 acdb_data.preproc_agc->comp_rlink_attackk_msw =
1972 acdb_agc->comp_rlink_attack_k_msw;
1973 acdb_data.preproc_agc->comp_rlink_attackk_lsw =
1974 acdb_agc->comp_rlink_attack_k_lsw;
1975 acdb_data.preproc_agc->comp_rlink_delay =
1976 acdb_agc->comp_rlink_delay;
1977 acdb_data.preproc_agc->comp_rlink_releasek_msw =
1978 acdb_agc->comp_rlink_release_k_msw;
1979 acdb_data.preproc_agc->comp_rlink_releasek_lsw =
1980 acdb_agc->comp_rlink_release_k_lsw;
1981 acdb_data.preproc_agc->comp_rlink_rms_tav =
1982 acdb_agc->comp_rlink_rms_trav;
1983 return 0;
1984}
1985
1986static struct acdb_iir_block *get_audpreproc_irr_block(void)
1987{
1988
1989 struct header *prs_hdr;
1990 u32 index = 0;
1991
1992 while (index < acdb_data.acdb_result.used_bytes) {
1993 prs_hdr = (struct header *)(acdb_data.virt_addr + index);
1994
1995 if (prs_hdr->dbor_signature == DBOR_SIGNATURE) {
1996 if (prs_hdr->abid == ABID_AUDIO_IIR_TX) {
1997 if (prs_hdr->iid == IID_AUDIO_IIR_COEFF)
1998 return (struct acdb_iir_block *)
1999 (acdb_data.virt_addr + index
2000 + sizeof(struct header));
2001 } else {
2002 index += prs_hdr->data_len +
2003 sizeof(struct header);
2004 }
2005 } else {
2006 break;
2007 }
2008 }
2009 return NULL;
2010}
2011
2012
2013static s32 acdb_fill_audpreproc_iir(void)
2014{
2015 struct acdb_iir_block *acdb_iir;
2016
2017
2018 acdb_iir = get_audpreproc_irr_block();
2019 if (!acdb_iir) {
2020 MM_DBG("unable to find preproc iir parameters winding up\n");
2021 return -1;
2022 }
2023 memset(acdb_data.preproc_iir, 0, sizeof(*acdb_data.preproc_iir));
2024
2025 acdb_data.preproc_iir->cmd_id =
2026 AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS;
2027 acdb_data.preproc_iir->stream_id = acdb_data.preproc_stream_id;
2028 acdb_data.preproc_iir->active_flag = acdb_iir->enable_flag;
2029 acdb_data.preproc_iir->num_bands = acdb_iir->stage_count;
2030
2031 acdb_data.preproc_iir->numerator_coeff_b0_filter0_lsw =
2032 acdb_iir->stages[0].b0_lo;
2033 acdb_data.preproc_iir->numerator_coeff_b0_filter0_msw =
2034 acdb_iir->stages[0].b0_hi;
2035 acdb_data.preproc_iir->numerator_coeff_b1_filter0_lsw =
2036 acdb_iir->stages[0].b1_lo;
2037 acdb_data.preproc_iir->numerator_coeff_b1_filter0_msw =
2038 acdb_iir->stages[0].b1_hi;
2039 acdb_data.preproc_iir->numerator_coeff_b2_filter0_lsw =
2040 acdb_iir->stages[0].b2_lo;
2041 acdb_data.preproc_iir->numerator_coeff_b2_filter0_msw =
2042 acdb_iir->stages[0].b2_hi;
2043
2044 acdb_data.preproc_iir->numerator_coeff_b0_filter1_lsw =
2045 acdb_iir->stages[1].b0_lo;
2046 acdb_data.preproc_iir->numerator_coeff_b0_filter1_msw =
2047 acdb_iir->stages[1].b0_hi;
2048 acdb_data.preproc_iir->numerator_coeff_b1_filter1_lsw =
2049 acdb_iir->stages[1].b1_lo;
2050 acdb_data.preproc_iir->numerator_coeff_b1_filter1_msw =
2051 acdb_iir->stages[1].b1_hi;
2052 acdb_data.preproc_iir->numerator_coeff_b2_filter1_lsw =
2053 acdb_iir->stages[1].b2_lo;
2054 acdb_data.preproc_iir->numerator_coeff_b2_filter1_msw =
2055 acdb_iir->stages[1].b2_hi;
2056
2057 acdb_data.preproc_iir->numerator_coeff_b0_filter2_lsw =
2058 acdb_iir->stages[2].b0_lo;
2059 acdb_data.preproc_iir->numerator_coeff_b0_filter2_msw =
2060 acdb_iir->stages[2].b0_hi;
2061 acdb_data.preproc_iir->numerator_coeff_b1_filter2_lsw =
2062 acdb_iir->stages[2].b1_lo;
2063 acdb_data.preproc_iir->numerator_coeff_b1_filter2_msw =
2064 acdb_iir->stages[2].b1_hi;
2065 acdb_data.preproc_iir->numerator_coeff_b2_filter2_lsw =
2066 acdb_iir->stages[2].b2_lo;
2067 acdb_data.preproc_iir->numerator_coeff_b2_filter2_msw =
2068 acdb_iir->stages[2].b2_hi;
2069
2070 acdb_data.preproc_iir->numerator_coeff_b0_filter3_lsw =
2071 acdb_iir->stages[3].b0_lo;
2072 acdb_data.preproc_iir->numerator_coeff_b0_filter3_msw =
2073 acdb_iir->stages[3].b0_hi;
2074 acdb_data.preproc_iir->numerator_coeff_b1_filter3_lsw =
2075 acdb_iir->stages[3].b1_lo;
2076 acdb_data.preproc_iir->numerator_coeff_b1_filter3_msw =
2077 acdb_iir->stages[3].b1_hi;
2078 acdb_data.preproc_iir->numerator_coeff_b2_filter3_lsw =
2079 acdb_iir->stages[3].b2_lo;
2080 acdb_data.preproc_iir->numerator_coeff_b2_filter3_msw =
2081 acdb_iir->stages[3].b2_hi;
2082
2083 acdb_data.preproc_iir->denominator_coeff_a0_filter0_lsw =
2084 acdb_iir->stages_a[0].a1_lo;
2085 acdb_data.preproc_iir->denominator_coeff_a0_filter0_msw =
2086 acdb_iir->stages_a[0].a1_hi;
2087 acdb_data.preproc_iir->denominator_coeff_a1_filter0_lsw =
2088 acdb_iir->stages_a[0].a2_lo;
2089 acdb_data.preproc_iir->denominator_coeff_a1_filter0_msw =
2090 acdb_iir->stages_a[0].a2_hi;
2091
2092 acdb_data.preproc_iir->denominator_coeff_a0_filter1_lsw =
2093 acdb_iir->stages_a[1].a1_lo;
2094 acdb_data.preproc_iir->denominator_coeff_a0_filter1_msw =
2095 acdb_iir->stages_a[1].a1_hi;
2096 acdb_data.preproc_iir->denominator_coeff_a1_filter1_lsw =
2097 acdb_iir->stages_a[1].a2_lo;
2098 acdb_data.preproc_iir->denominator_coeff_a1_filter1_msw =
2099 acdb_iir->stages_a[1].a2_hi;
2100
2101 acdb_data.preproc_iir->denominator_coeff_a0_filter2_lsw =
2102 acdb_iir->stages_a[2].a1_lo;
2103 acdb_data.preproc_iir->denominator_coeff_a0_filter2_msw =
2104 acdb_iir->stages_a[2].a1_hi;
2105 acdb_data.preproc_iir->denominator_coeff_a1_filter2_lsw =
2106 acdb_iir->stages_a[2].a2_lo;
2107 acdb_data.preproc_iir->denominator_coeff_a1_filter2_msw =
2108 acdb_iir->stages_a[2].a2_hi;
2109
2110 acdb_data.preproc_iir->denominator_coeff_a0_filter3_lsw =
2111 acdb_iir->stages_a[3].a1_lo;
2112 acdb_data.preproc_iir->denominator_coeff_a0_filter3_msw =
2113 acdb_iir->stages_a[3].a1_hi;
2114 acdb_data.preproc_iir->denominator_coeff_a1_filter3_lsw =
2115 acdb_iir->stages_a[3].a2_lo;
2116 acdb_data.preproc_iir->denominator_coeff_a1_filter3_msw =
2117 acdb_iir->stages_a[3].a2_hi;
2118
2119 acdb_data.preproc_iir->shift_factor_filter0 =
2120 acdb_iir->shift_factor[0];
2121 acdb_data.preproc_iir->shift_factor_filter1 =
2122 acdb_iir->shift_factor[1];
2123 acdb_data.preproc_iir->shift_factor_filter2 =
2124 acdb_iir->shift_factor[2];
2125 acdb_data.preproc_iir->shift_factor_filter3 =
2126 acdb_iir->shift_factor[3];
2127
2128 acdb_data.preproc_iir->pan_of_filter0 =
2129 acdb_iir->pan[0];
2130 acdb_data.preproc_iir->pan_of_filter1 =
2131 acdb_iir->pan[1];
2132 acdb_data.preproc_iir->pan_of_filter2 =
2133 acdb_iir->pan[2];
2134 acdb_data.preproc_iir->pan_of_filter3 =
2135 acdb_iir->pan[3];
2136 return 0;
2137}
2138
2139static struct acdb_calib_gain_tx *get_audpreproc_cal_gain(void)
2140{
2141 struct header *prs_hdr;
2142 u32 index = 0;
2143
2144 while (index < acdb_data.acdb_result.used_bytes) {
2145 prs_hdr = (struct header *)(acdb_data.virt_addr + index);
2146 if (prs_hdr->dbor_signature == DBOR_SIGNATURE) {
2147 if (prs_hdr->abid == ABID_AUDIO_CALIBRATION_GAIN_TX) {
2148 if (prs_hdr->iid ==
2149 IID_AUDIO_CALIBRATION_GAIN_TX) {
2150 MM_DBG("Got audpreproc_calib_gain_tx"
2151 " block\n");
2152 return (struct acdb_calib_gain_tx *)
2153 (acdb_data.virt_addr + index
2154 + sizeof(struct header));
2155 }
2156 } else {
2157 index += prs_hdr->data_len +
2158 sizeof(struct header);
2159 }
2160 } else {
2161 break;
2162 }
2163 }
2164 return NULL;
2165}
2166
2167static s32 acdb_fill_audpreproc_cal_gain(void)
2168{
2169 struct acdb_calib_gain_tx *acdb_calib_gain_tx = NULL;
2170
2171 acdb_calib_gain_tx = get_audpreproc_cal_gain();
2172 if (acdb_calib_gain_tx == NULL) {
2173 MM_ERR("unable to find audpreproc"
2174 " calibration block returning\n");
2175 return -1;
2176 }
2177 MM_DBG("Calibration value"
2178 " for calib_gain_tx %d\n", acdb_calib_gain_tx->audprecalgain);
2179 memset(acdb_data.calib_gain_tx, 0, sizeof(*acdb_data.calib_gain_tx));
2180
2181 acdb_data.calib_gain_tx->cmd_id =
2182 AUDPREPROC_CMD_CFG_CAL_GAIN_PARAMS;
2183 acdb_data.calib_gain_tx->stream_id = acdb_data.preproc_stream_id;
2184 acdb_data.calib_gain_tx->audprecalgain =
2185 acdb_calib_gain_tx->audprecalgain;
2186 return 0;
2187}
2188
2189static struct acdb_rmc_block *get_rmc_blk(void)
2190{
2191 struct header *prs_hdr;
2192 u32 index = 0;
2193
2194 while (index < acdb_data.acdb_result.used_bytes) {
2195 prs_hdr = (struct header *)(acdb_data.virt_addr + index);
2196 if (prs_hdr->dbor_signature == DBOR_SIGNATURE) {
2197 if (prs_hdr->abid == ABID_AUDIO_RMC_TX) {
2198 if (prs_hdr->iid ==
2199 IID_AUDIO_RMC_PARAM) {
2200 MM_DBG("Got afe_rmc block\n");
2201 return (struct acdb_rmc_block *)
2202 (acdb_data.virt_addr + index
2203 + sizeof(struct header));
2204 }
2205 } else {
2206 index += prs_hdr->data_len +
2207 sizeof(struct header);
2208 }
2209 } else {
2210 break;
2211 }
2212 }
2213 return NULL;
2214}
2215
2216struct acdb_fluence_block *get_audpp_fluence_block(void)
2217{
2218 struct header *prs_hdr;
2219 u32 index = 0;
2220
2221 while (index < acdb_data.acdb_result.used_bytes) {
2222 prs_hdr = (struct header *)(acdb_data.virt_addr + index);
2223
2224 if (prs_hdr->dbor_signature == DBOR_SIGNATURE) {
2225 if (prs_hdr->abid == ABID_AUDIO_FLUENCE_TX) {
2226 if (prs_hdr->iid == IID_AUDIO_FLUENCE_TX) {
2227 MM_DBG("got fluence block\n");
2228 return (struct acdb_fluence_block *)
2229 (acdb_data.virt_addr + index
2230 + sizeof(struct header));
2231 }
2232 } else {
2233 index += prs_hdr->data_len +
2234 sizeof(struct header);
2235 }
2236 } else {
2237 break;
2238 }
2239 }
2240 return NULL;
2241}
2242
2243static s32 acdb_fill_audpreproc_fluence(void)
2244{
2245 struct acdb_fluence_block *fluence_block = NULL;
2246 fluence_block = get_audpp_fluence_block();
2247 if (!fluence_block) {
2248 MM_ERR("error in finding fluence block\n");
2249 return -EPERM;
2250 }
2251 memset(&acdb_data.preproc_lvnv, 0, sizeof(
2252 struct audpreproc_cmd_cfg_lvnv_param));
2253 memcpy(acdb_data.fluence_extbuff_virt,
2254 &fluence_block->cs_tuningMode,
2255 (sizeof(struct acdb_fluence_block) -
2256 sizeof(fluence_block->csmode)));
2257 acdb_data.preproc_lvnv.cmd_id = AUDPREPROC_CMD_CFG_LVNV_PARMS;
2258 acdb_data.preproc_lvnv.stream_id = acdb_data.preproc_stream_id;
2259 acdb_data.preproc_lvnv.cs_mode = fluence_block->csmode;
2260 acdb_data.preproc_lvnv.lvnv_ext_buf_size = FLUENCE_BUF_SIZE;
2261 acdb_data.preproc_lvnv.lvnv_ext_buf_start_lsw =\
2262 ((u32)(acdb_data.fluence_extbuff)\
2263 & 0x0000FFFF);
2264 acdb_data.preproc_lvnv.lvnv_ext_buf_start_msw =\
2265 (((u32)acdb_data.fluence_extbuff\
2266 & 0xFFFF0000) >> 16);
2267 return 0;
2268}
2269
2270s32 acdb_calibrate_audpreproc(void)
2271{
2272 s32 result = 0;
2273 struct acdb_rmc_block *acdb_rmc = NULL;
2274
2275 result = acdb_fill_audpreproc_agc();
2276 if (!IS_ERR_VALUE(result)) {
2277 result = audpreproc_dsp_set_agc(acdb_data.preproc_agc, sizeof(
2278 struct audpreproc_cmd_cfg_agc_params));
2279 if (result) {
2280 MM_ERR("ACDB=> Failed to send AGC data to preproc)\n");
2281 result = -EINVAL;
2282 goto done;
2283 } else
2284 MM_DBG("AUDPREC is calibrated with AGC parameters"
2285 " for COPP ID %d and AUDREC session %d\n",
2286 acdb_data.device_info->dev_id,
2287 acdb_data.preproc_stream_id);
2288 }
2289 result = acdb_fill_audpreproc_iir();
2290 if (!IS_ERR_VALUE(result)) {
2291 result = audpreproc_dsp_set_iir(acdb_data.preproc_iir,
2292 sizeof(struct\
2293 audpreproc_cmd_cfg_iir_tuning_filter_params));
2294 if (result) {
2295 MM_ERR("ACDB=> Failed to send IIR data to preproc\n");
2296 result = -EINVAL;
2297 goto done;
2298 } else
2299 MM_DBG("audpreproc is calibrated with iir parameters"
2300 " for COPP ID %d and AUREC session %d\n",
2301 acdb_data.device_info->dev_id,
2302 acdb_data.preproc_stream_id);
2303 }
2304 result = acdb_fill_audpreproc_cal_gain();
2305 if (!(IS_ERR_VALUE(result))) {
2306 result = audpreproc_dsp_set_gain_tx(acdb_data.calib_gain_tx,
2307 sizeof(struct audpreproc_cmd_cfg_cal_gain));
2308 if (result) {
2309 MM_ERR("ACDB=> Failed to send calib_gain_tx"
2310 " data to preproc\n");
2311 result = -EINVAL;
2312 goto done;
2313 } else
2314 MM_DBG("AUDPREPROC is calibrated"
2315 " with calib_gain_tx\n");
2316 }
Kalyani polepeddyaeea8bf2011-10-20 10:51:07 +05302317 if (acdb_data.build_id[17] != '0') {
2318 acdb_rmc = get_rmc_blk();
2319 if (acdb_rmc != NULL) {
2320 result = afe_config_rmc_block(acdb_rmc);
2321 if (result) {
2322 MM_ERR("ACDB=> Failed to send rmc"
2323 " data to afe\n");
2324 result = -EINVAL;
2325 goto done;
2326 } else
2327 MM_DBG("AFE is calibrated with rmc params\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002328 } else
Kalyani polepeddyaeea8bf2011-10-20 10:51:07 +05302329 MM_DBG("RMC block was not found\n");
2330 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002331 if (!acdb_data.fleuce_feature_status[acdb_data.preproc_stream_id]) {
2332 result = acdb_fill_audpreproc_fluence();
2333 if (!(IS_ERR_VALUE(result))) {
2334 result = audpreproc_dsp_set_lvnv(
2335 &acdb_data.preproc_lvnv,
2336 sizeof(struct\
2337 audpreproc_cmd_cfg_lvnv_param));
2338 if (result) {
2339 MM_ERR("ACDB=> Failed to send lvnv "
2340 "data to preproc\n");
2341 result = -EINVAL;
2342 goto done;
2343 } else
2344 MM_DBG("AUDPREPROC is calibrated"
2345 " with lvnv parameters\n");
2346 } else
2347 MM_ERR("fluence block is not found\n");
2348 } else
2349 MM_DBG("fluence block override\n");
2350done:
2351 return result;
2352}
2353
2354static s32 acdb_send_calibration(void)
2355{
2356 s32 result = 0;
2357
2358 if ((acdb_data.device_info->dev_type & RX_DEVICE) == 1) {
2359 result = acdb_calibrate_audpp();
2360 if (result)
2361 goto done;
2362 } else if ((acdb_data.device_info->dev_type & TX_DEVICE) == 2) {
2363 result = acdb_calibrate_audpreproc();
2364 if (result)
2365 goto done;
2366 if (acdb_data.preproc_stream_id == 0)
2367 acdb_data.audrec_applied |= AUDREC0_READY;
2368 else if (acdb_data.preproc_stream_id == 1)
2369 acdb_data.audrec_applied |= AUDREC1_READY;
2370 else if (acdb_data.preproc_stream_id == 2)
2371 acdb_data.audrec_applied |= AUDREC2_READY;
2372 MM_DBG("acdb_data.audrec_applied = %x\n",
2373 acdb_data.audrec_applied);
2374 }
2375done:
2376 return result;
2377}
2378
2379static u8 check_tx_acdb_values_cached(void)
2380{
2381 u8 stream_id = acdb_data.preproc_stream_id;
2382
2383 if ((acdb_data.device_info->dev_id ==
2384 acdb_cache_tx[stream_id].device_info.dev_id) &&
2385 (acdb_data.device_info->sample_rate ==
2386 acdb_cache_tx[stream_id].device_info.sample_rate) &&
2387 (acdb_data.device_info->acdb_id ==
2388 acdb_cache_tx[stream_id].device_info.acdb_id) &&
2389 (acdb_cache_tx[stream_id].node_status ==
2390 ACDB_VALUES_FILLED))
2391 return 0;
2392 else
2393 return 1;
2394}
2395
2396static void handle_tx_device_ready_callback(void)
2397{
2398 u8 i = 0;
2399 u8 ret = 0;
2400 u8 acdb_value_apply = 0;
2401 u8 result = 0;
2402 u8 stream_id = acdb_data.preproc_stream_id;
2403
2404 if (acdb_data.multiple_sessions) {
2405 for (i = 0; i < MAX_AUDREC_SESSIONS; i++) {
2406 /*check is to exclude copying acdb values in the
2407 current node pointed by acdb_data structure*/
2408 if (acdb_cache_tx[i].phys_addr_acdb_values !=
2409 acdb_data.phys_addr) {
2410 ret = check_device_info_already_present(\
2411 *acdb_data.device_info,
2412 &acdb_cache_tx[i]);
2413 if (ret) {
2414 memcpy((char *)acdb_cache_tx[i].\
2415 virt_addr_acdb_values,
2416 (char *)acdb_data.virt_addr,
2417 ACDB_BUF_SIZE);
2418 acdb_cache_tx[i].node_status =
2419 ACDB_VALUES_FILLED;
2420 }
2421 }
2422 }
2423 acdb_data.multiple_sessions = 0;
2424 }
2425 /*check wheather AUDREC enabled before device call backs*/
2426 if ((acdb_data.acdb_state & AUDREC0_READY) &&
2427 !(acdb_data.audrec_applied & AUDREC0_READY)) {
2428 MM_DBG("AUDREC0 already enabled apply acdb values\n");
2429 acdb_value_apply |= AUDREC0_READY;
2430 } else if ((acdb_data.acdb_state & AUDREC1_READY) &&
2431 !(acdb_data.audrec_applied & AUDREC1_READY)) {
2432 MM_DBG("AUDREC1 already enabled apply acdb values\n");
2433 acdb_value_apply |= AUDREC1_READY;
2434 } else if ((acdb_data.acdb_state & AUDREC2_READY) &&
2435 !(acdb_data.audrec_applied & AUDREC2_READY)) {
2436 MM_DBG("AUDREC2 already enabled apply acdb values\n");
2437 acdb_value_apply |= AUDREC2_READY;
2438 }
2439 if (acdb_value_apply) {
2440 if (session_info[stream_id].sampling_freq)
2441 acdb_data.device_info->sample_rate =
2442 session_info[stream_id].sampling_freq;
2443 result = check_tx_acdb_values_cached();
2444 if (result) {
2445 result = acdb_get_calibration();
2446 if (result < 0) {
2447 MM_ERR("Not able to get calibration"
2448 " data continue\n");
2449 return;
2450 }
2451 }
2452 acdb_cache_tx[stream_id].node_status = ACDB_VALUES_FILLED;
2453 acdb_send_calibration();
2454 }
2455}
2456
2457static struct acdb_cache_node *get_acdb_values_from_cache_tx(u32 stream_id)
2458{
2459 MM_DBG("searching node with stream_id %d\n", stream_id);
2460 if ((acdb_cache_tx[stream_id].stream_id == stream_id) &&
2461 (acdb_cache_tx[stream_id].node_status ==
2462 ACDB_VALUES_NOT_FILLED)) {
2463 return &acdb_cache_tx[stream_id];
2464 }
2465 MM_DBG("Error! in finding node\n");
2466 return NULL;
2467}
2468
2469static void update_acdb_data_struct(struct acdb_cache_node *cur_node)
2470{
2471 if (cur_node) {
2472 acdb_data.device_info = &cur_node->device_info;
2473 acdb_data.virt_addr = cur_node->virt_addr_acdb_values;
2474 acdb_data.phys_addr = cur_node->phys_addr_acdb_values;
2475 } else
2476 MM_ERR("error in curent node\n");
2477}
2478
2479static void send_acdb_values_for_active_devices(void)
2480{
2481 u32 i = 0;
2482 for (i = 0; i < MAX_COPP_NODE_SUPPORTED; i++) {
2483 if (acdb_cache_rx[i].node_status ==
2484 ACDB_VALUES_FILLED) {
2485 update_acdb_data_struct(&acdb_cache_rx[i]);
2486 if (acdb_data.acdb_state & CAL_DATA_READY)
2487 acdb_send_calibration();
2488 }
2489 }
2490}
2491
2492static s32 initialize_rpc(void)
2493{
2494 s32 result = 0;
2495
2496 result = daldevice_attach(DALDEVICEID_ACDB, ACDB_PORT_NAME,
2497 ACDB_CPU, &acdb_data.handle);
2498
2499 if (result) {
2500 MM_ERR("ACDB=> Device Attach failed\n");
2501 result = -ENODEV;
2502 goto done;
2503 }
2504done:
2505 return result;
2506}
2507
2508static u32 allocate_memory_acdb_cache_tx(void)
2509{
2510 u32 result = 0;
2511 u32 i = 0;
2512 u32 err = 0;
2513 /*initialize local cache */
2514 for (i = 0; i < MAX_AUDREC_SESSIONS; i++) {
2515 acdb_cache_tx[i].phys_addr_acdb_values =
Santosh Mardifdc227a2011-07-11 17:20:34 +05302516 allocate_contiguous_ebi_nomap(ACDB_BUF_SIZE,
2517 SZ_4K);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002518
Santosh Mardifdc227a2011-07-11 17:20:34 +05302519 if (!acdb_cache_tx[i].phys_addr_acdb_values) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002520 MM_ERR("ACDB=> Cannot allocate physical memory\n");
2521 result = -ENOMEM;
2522 goto error;
2523 }
Laura Abbott61399692012-04-30 14:25:46 -07002524 acdb_cache_tx[i].map_v_addr = ioremap(
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002525 acdb_cache_tx[i].phys_addr_acdb_values,
Laura Abbott61399692012-04-30 14:25:46 -07002526 ACDB_BUF_SIZE);
Santosh Mardifdc227a2011-07-11 17:20:34 +05302527 if (IS_ERR(acdb_cache_tx[i].map_v_addr)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002528 MM_ERR("ACDB=> Could not map physical address\n");
2529 result = -ENOMEM;
Santosh Mardifdc227a2011-07-11 17:20:34 +05302530 free_contiguous_memory_by_paddr(
2531 acdb_cache_tx[i].phys_addr_acdb_values);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002532 goto error;
2533 }
Santosh Mardifdc227a2011-07-11 17:20:34 +05302534 acdb_cache_tx[i].virt_addr_acdb_values =
Laura Abbott61399692012-04-30 14:25:46 -07002535 acdb_cache_tx[i].map_v_addr;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002536 memset(acdb_cache_tx[i].virt_addr_acdb_values, 0,
2537 ACDB_BUF_SIZE);
2538 }
2539 return result;
2540error:
2541 for (err = 0; err < i; err++) {
Laura Abbott61399692012-04-30 14:25:46 -07002542 iounmap(acdb_cache_tx[err].map_v_addr);
Santosh Mardifdc227a2011-07-11 17:20:34 +05302543 free_contiguous_memory_by_paddr(
2544 acdb_cache_tx[err].phys_addr_acdb_values);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002545 }
2546 return result;
2547}
2548
2549static u32 allocate_memory_acdb_cache_rx(void)
2550{
2551 u32 result = 0;
2552 u32 i = 0;
2553 u32 err = 0;
2554
2555 /*initialize local cache */
2556 for (i = 0; i < MAX_COPP_NODE_SUPPORTED; i++) {
2557 acdb_cache_rx[i].phys_addr_acdb_values =
Santosh Mardifdc227a2011-07-11 17:20:34 +05302558 allocate_contiguous_ebi_nomap(
2559 ACDB_BUF_SIZE, SZ_4K);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002560
Santosh Mardifdc227a2011-07-11 17:20:34 +05302561 if (!acdb_cache_rx[i].phys_addr_acdb_values) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002562 MM_ERR("ACDB=> Can not allocate physical memory\n");
2563 result = -ENOMEM;
2564 goto error;
2565 }
Santosh Mardifdc227a2011-07-11 17:20:34 +05302566 acdb_cache_rx[i].map_v_addr =
Laura Abbott61399692012-04-30 14:25:46 -07002567 ioremap(acdb_cache_rx[i].phys_addr_acdb_values,
2568 ACDB_BUF_SIZE);
Santosh Mardifdc227a2011-07-11 17:20:34 +05302569 if (IS_ERR(acdb_cache_rx[i].map_v_addr)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002570 MM_ERR("ACDB=> Could not map physical address\n");
2571 result = -ENOMEM;
Santosh Mardifdc227a2011-07-11 17:20:34 +05302572 free_contiguous_memory_by_paddr(
2573 acdb_cache_rx[i].phys_addr_acdb_values);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002574 goto error;
2575 }
Santosh Mardifdc227a2011-07-11 17:20:34 +05302576 acdb_cache_rx[i].virt_addr_acdb_values =
Laura Abbott61399692012-04-30 14:25:46 -07002577 acdb_cache_rx[i].map_v_addr;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002578 memset(acdb_cache_rx[i].virt_addr_acdb_values, 0,
2579 ACDB_BUF_SIZE);
2580 }
2581 return result;
2582error:
2583 for (err = 0; err < i; err++) {
Laura Abbott61399692012-04-30 14:25:46 -07002584 iounmap(acdb_cache_rx[err].map_v_addr);
Santosh Mardifdc227a2011-07-11 17:20:34 +05302585 free_contiguous_memory_by_paddr(
2586 acdb_cache_rx[err].phys_addr_acdb_values);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002587 }
2588 return result;
2589}
2590
2591static u32 allocate_memory_acdb_get_blk(void)
2592{
2593 u32 result = 0;
Santosh Mardifdc227a2011-07-11 17:20:34 +05302594 acdb_data.get_blk_paddr = allocate_contiguous_ebi_nomap(
2595 ACDB_BUF_SIZE, SZ_4K);
2596 if (!acdb_data.get_blk_paddr) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002597 MM_ERR("ACDB=> Cannot allocate physical memory\n");
2598 result = -ENOMEM;
2599 goto error;
2600 }
Laura Abbott61399692012-04-30 14:25:46 -07002601 acdb_data.map_v_get_blk = ioremap(acdb_data.get_blk_paddr,
2602 ACDB_BUF_SIZE);
Santosh Mardifdc227a2011-07-11 17:20:34 +05302603 if (IS_ERR(acdb_data.map_v_get_blk)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002604 MM_ERR("ACDB=> Could not map physical address\n");
2605 result = -ENOMEM;
Santosh Mardifdc227a2011-07-11 17:20:34 +05302606 free_contiguous_memory_by_paddr(
2607 acdb_data.get_blk_paddr);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002608 goto error;
2609 }
Laura Abbott61399692012-04-30 14:25:46 -07002610 acdb_data.get_blk_kvaddr = acdb_data.map_v_get_blk;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002611 memset(acdb_data.get_blk_kvaddr, 0, ACDB_BUF_SIZE);
2612error:
2613 return result;
2614}
2615
2616static void free_memory_acdb_cache_rx(void)
2617{
2618 u32 i = 0;
2619
2620 for (i = 0; i < MAX_COPP_NODE_SUPPORTED; i++) {
Laura Abbott61399692012-04-30 14:25:46 -07002621 iounmap(acdb_cache_rx[i].map_v_addr);
Santosh Mardifdc227a2011-07-11 17:20:34 +05302622 free_contiguous_memory_by_paddr(
2623 acdb_cache_rx[i].phys_addr_acdb_values);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002624 }
2625}
2626
2627static void free_memory_acdb_cache_tx(void)
2628{
2629 u32 i = 0;
2630
2631 for (i = 0; i < MAX_AUDREC_SESSIONS; i++) {
Laura Abbott61399692012-04-30 14:25:46 -07002632 iounmap(acdb_cache_tx[i].map_v_addr);
Santosh Mardifdc227a2011-07-11 17:20:34 +05302633 free_contiguous_memory_by_paddr(
2634 acdb_cache_tx[i].phys_addr_acdb_values);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002635 }
2636}
2637
2638static void free_memory_acdb_get_blk(void)
2639{
Laura Abbott61399692012-04-30 14:25:46 -07002640 iounmap(acdb_data.map_v_get_blk);
Santosh Mardifdc227a2011-07-11 17:20:34 +05302641 free_contiguous_memory_by_paddr(acdb_data.get_blk_paddr);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002642}
2643
2644static s32 initialize_memory(void)
2645{
2646 s32 result = 0;
2647
2648 result = allocate_memory_acdb_get_blk();
2649 if (result < 0) {
2650 MM_ERR("memory allocation for get blk failed\n");
2651 goto done;
2652 }
2653
2654 result = allocate_memory_acdb_cache_rx();
2655 if (result < 0) {
2656 MM_ERR("memory allocation for rx cache is failed\n");
2657 free_memory_acdb_get_blk();
2658 goto done;
2659 }
2660 result = allocate_memory_acdb_cache_tx();
2661 if (result < 0) {
2662 MM_ERR("memory allocation for tx cache is failed\n");
2663 free_memory_acdb_get_blk();
2664 free_memory_acdb_cache_rx();
2665 goto done;
2666 }
2667 acdb_data.pp_iir = kmalloc(sizeof(*acdb_data.pp_iir),
2668 GFP_KERNEL);
2669 if (acdb_data.pp_iir == NULL) {
2670 MM_ERR("ACDB=> Could not allocate postproc iir memory\n");
2671 free_memory_acdb_get_blk();
2672 free_memory_acdb_cache_rx();
2673 free_memory_acdb_cache_tx();
2674 result = -ENOMEM;
2675 goto done;
2676 }
2677
2678 acdb_data.pp_mbadrc = kmalloc(sizeof(*acdb_data.pp_mbadrc), GFP_KERNEL);
2679 if (acdb_data.pp_mbadrc == NULL) {
2680 MM_ERR("ACDB=> Could not allocate postproc mbadrc memory\n");
2681 free_memory_acdb_get_blk();
2682 free_memory_acdb_cache_rx();
2683 free_memory_acdb_cache_tx();
2684 kfree(acdb_data.pp_iir);
2685 result = -ENOMEM;
2686 goto done;
2687 }
2688 acdb_data.calib_gain_rx = kmalloc(sizeof(*acdb_data.calib_gain_rx),
2689 GFP_KERNEL);
2690 if (acdb_data.calib_gain_rx == NULL) {
2691 MM_ERR("ACDB=> Could not allocate"
2692 " postproc calib_gain_rx memory\n");
2693 free_memory_acdb_get_blk();
2694 free_memory_acdb_cache_rx();
2695 free_memory_acdb_cache_tx();
2696 kfree(acdb_data.pp_iir);
2697 kfree(acdb_data.pp_mbadrc);
2698 result = -ENOMEM;
2699 goto done;
2700 }
2701
2702 acdb_data.preproc_agc = kmalloc(sizeof(*acdb_data.preproc_agc),
2703 GFP_KERNEL);
2704 if (acdb_data.preproc_agc == NULL) {
2705 MM_ERR("ACDB=> Could not allocate preproc agc memory\n");
2706 free_memory_acdb_get_blk();
2707 free_memory_acdb_cache_rx();
2708 free_memory_acdb_cache_tx();
2709 kfree(acdb_data.pp_iir);
2710 kfree(acdb_data.pp_mbadrc);
2711 kfree(acdb_data.calib_gain_rx);
2712 result = -ENOMEM;
2713 goto done;
2714 }
2715
2716 acdb_data.preproc_iir = kmalloc(sizeof(*acdb_data.preproc_iir),
2717 GFP_KERNEL);
2718 if (acdb_data.preproc_iir == NULL) {
2719 MM_ERR("ACDB=> Could not allocate preproc iir memory\n");
2720 free_memory_acdb_get_blk();
2721 free_memory_acdb_cache_rx();
2722 free_memory_acdb_cache_tx();
2723 kfree(acdb_data.pp_iir);
2724 kfree(acdb_data.pp_mbadrc);
2725 kfree(acdb_data.calib_gain_rx);
2726 kfree(acdb_data.preproc_agc);
2727 result = -ENOMEM;
2728 goto done;
2729 }
2730 acdb_data.calib_gain_tx = kmalloc(sizeof(*acdb_data.calib_gain_tx),
2731 GFP_KERNEL);
2732 if (acdb_data.calib_gain_tx == NULL) {
2733 MM_ERR("ACDB=> Could not allocate"
2734 " preproc calib_gain_tx memory\n");
2735 free_memory_acdb_get_blk();
2736 free_memory_acdb_cache_rx();
2737 free_memory_acdb_cache_tx();
2738 kfree(acdb_data.pp_iir);
2739 kfree(acdb_data.pp_mbadrc);
2740 kfree(acdb_data.calib_gain_rx);
2741 kfree(acdb_data.preproc_agc);
2742 kfree(acdb_data.preproc_iir);
2743 result = -ENOMEM;
2744 goto done;
2745 }
2746 acdb_data.pbe_block = kmalloc(sizeof(*acdb_data.pbe_block),
2747 GFP_KERNEL);
2748 if (acdb_data.pbe_block == NULL) {
2749 MM_ERR("ACDB=> Could not allocate pbe_block memory\n");
2750 free_memory_acdb_get_blk();
2751 free_memory_acdb_cache_rx();
2752 free_memory_acdb_cache_tx();
2753 kfree(acdb_data.pp_iir);
2754 kfree(acdb_data.pp_mbadrc);
2755 kfree(acdb_data.calib_gain_rx);
2756 kfree(acdb_data.preproc_agc);
2757 kfree(acdb_data.preproc_iir);
2758 kfree(acdb_data.calib_gain_tx);
2759 result = -ENOMEM;
2760 goto done;
2761 }
Santosh Mardifdc227a2011-07-11 17:20:34 +05302762 acdb_data.pbe_extbuff = (u16 *) allocate_contiguous_ebi_nomap(
2763 PBE_BUF_SIZE, SZ_4K);
2764 if (!acdb_data.pbe_extbuff) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002765 MM_ERR("ACDB=> Cannot allocate physical memory\n");
2766 free_memory_acdb_get_blk();
2767 free_memory_acdb_cache_rx();
2768 free_memory_acdb_cache_tx();
2769 kfree(acdb_data.pp_iir);
2770 kfree(acdb_data.pp_mbadrc);
2771 kfree(acdb_data.calib_gain_rx);
2772 kfree(acdb_data.preproc_agc);
2773 kfree(acdb_data.preproc_iir);
2774 kfree(acdb_data.calib_gain_tx);
2775 kfree(acdb_data.pbe_block);
2776 result = -ENOMEM;
2777 goto done;
2778 }
Santosh Mardifdc227a2011-07-11 17:20:34 +05302779 acdb_data.fluence_extbuff = allocate_contiguous_ebi_nomap(
2780 FLUENCE_BUF_SIZE, SZ_4K);
2781 if (!acdb_data.fluence_extbuff) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002782 MM_ERR("ACDB=> cannot allocate physical memory for "
2783 "fluence block\n");
2784 free_memory_acdb_get_blk();
2785 free_memory_acdb_cache_rx();
2786 free_memory_acdb_cache_tx();
2787 kfree(acdb_data.pp_iir);
2788 kfree(acdb_data.pp_mbadrc);
2789 kfree(acdb_data.calib_gain_rx);
2790 kfree(acdb_data.preproc_agc);
2791 kfree(acdb_data.preproc_iir);
2792 kfree(acdb_data.calib_gain_tx);
2793 kfree(acdb_data.pbe_block);
Santosh Mardifdc227a2011-07-11 17:20:34 +05302794 free_contiguous_memory_by_paddr((int32_t)acdb_data.pbe_extbuff);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002795 result = -ENOMEM;
2796 goto done;
2797 }
Laura Abbott61399692012-04-30 14:25:46 -07002798 acdb_data.map_v_fluence = ioremap(
Santosh Mardifdc227a2011-07-11 17:20:34 +05302799 acdb_data.fluence_extbuff,
Laura Abbott61399692012-04-30 14:25:46 -07002800 FLUENCE_BUF_SIZE);
Santosh Mardifdc227a2011-07-11 17:20:34 +05302801 if (IS_ERR(acdb_data.map_v_fluence)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002802 MM_ERR("ACDB=> Could not map physical address\n");
2803 free_memory_acdb_get_blk();
2804 free_memory_acdb_cache_rx();
2805 free_memory_acdb_cache_tx();
2806 kfree(acdb_data.pp_iir);
2807 kfree(acdb_data.pp_mbadrc);
2808 kfree(acdb_data.calib_gain_rx);
2809 kfree(acdb_data.preproc_agc);
2810 kfree(acdb_data.preproc_iir);
2811 kfree(acdb_data.calib_gain_tx);
2812 kfree(acdb_data.pbe_block);
Santosh Mardifdc227a2011-07-11 17:20:34 +05302813 free_contiguous_memory_by_paddr(
2814 (int32_t)acdb_data.pbe_extbuff);
2815 free_contiguous_memory_by_paddr(
2816 (int32_t)acdb_data.fluence_extbuff);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002817 result = -ENOMEM;
2818 goto done;
Santosh Mardifdc227a2011-07-11 17:20:34 +05302819 } else
2820 acdb_data.fluence_extbuff_virt =
Laura Abbott61399692012-04-30 14:25:46 -07002821 acdb_data.map_v_fluence;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002822done:
2823 return result;
2824}
2825
2826static u32 free_acdb_cache_node(union auddev_evt_data *evt)
2827{
2828 u32 session_id;
2829 if ((evt->audcal_info.dev_type & TX_DEVICE) == 2) {
2830 /*Second argument to find_first_bit should be maximum number
2831 of bits interested
2832 */
2833 session_id = find_first_bit(
2834 (unsigned long *)&(evt->audcal_info.sessions),
2835 sizeof(evt->audcal_info.sessions) * 8);
2836 MM_DBG("freeing node %d for tx device", session_id);
2837 acdb_cache_tx[session_id].
2838 node_status = ACDB_VALUES_NOT_FILLED;
2839 } else {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002840 MM_DBG("freeing rx cache node %d\n",
2841 evt->audcal_info.dev_id);
2842 acdb_cache_rx[evt->audcal_info.dev_id].
2843 node_status = ACDB_VALUES_NOT_FILLED;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002844 }
2845 return 0;
2846}
2847
2848static u8 check_device_change(struct auddev_evt_audcal_info audcal_info)
2849{
2850 if (!acdb_data.device_info) {
2851 MM_ERR("not pointing to previous valid device detail\n");
2852 return 1; /*device info will not be pointing to*/
2853 /* valid device when acdb driver comes up*/
2854 }
2855 if ((audcal_info.dev_id == acdb_data.device_info->dev_id) &&
2856 (audcal_info.sample_rate ==
2857 acdb_data.device_info->sample_rate) &&
2858 (audcal_info.acdb_id == acdb_data.device_info->acdb_id)) {
2859 return 0;
2860 }
2861 return 1;
2862}
2863
2864static void device_cb(u32 evt_id, union auddev_evt_data *evt, void *private)
2865{
2866 struct auddev_evt_audcal_info audcal_info;
2867 struct acdb_cache_node *acdb_cache_free_node = NULL;
2868 u32 stream_id = 0;
2869 u8 ret = 0;
2870 u8 count = 0;
2871 u8 i = 0;
2872 u8 device_change = 0;
2873
2874 if (!((evt_id == AUDDEV_EVT_DEV_RDY) ||
2875 (evt_id == AUDDEV_EVT_DEV_RLS))) {
2876 goto done;
2877 }
2878 /*if session value is zero it indicates that device call back is for
2879 voice call we will drop the request as acdb values for voice call is
2880 not applied from acdb driver*/
2881 if (!evt->audcal_info.sessions) {
2882 MM_DBG("no active sessions and call back is for"
2883 " voice call\n");
2884 goto done;
2885 }
2886 if (evt_id == AUDDEV_EVT_DEV_RLS) {
2887 MM_DBG("got release command for dev %d\n",
2888 evt->audcal_info.dev_id);
2889 acdb_data.acdb_state &= ~CAL_DATA_READY;
2890 free_acdb_cache_node(evt);
2891 /*reset the applied flag for the session routed to the device*/
2892 acdb_data.audrec_applied &= ~(evt->audcal_info.sessions
2893 << AUDREC_OFFSET);
2894 goto done;
2895 }
2896 if (((evt->audcal_info.dev_type & RX_DEVICE) == 1) &&
2897 (evt->audcal_info.acdb_id == PSEUDO_ACDB_ID)) {
2898 MM_INFO("device cb is for rx device with pseudo acdb id\n");
2899 goto done;
2900 }
2901 audcal_info = evt->audcal_info;
2902 MM_DBG("dev_id = %d\n", audcal_info.dev_id);
2903 MM_DBG("sample_rate = %d\n", audcal_info.sample_rate);
2904 MM_DBG("acdb_id = %d\n", audcal_info.acdb_id);
2905 MM_DBG("sessions = %d\n", audcal_info.sessions);
2906 MM_DBG("acdb_state = %x\n", acdb_data.acdb_state);
2907 mutex_lock(&acdb_data.acdb_mutex);
2908 device_change = check_device_change(audcal_info);
2909 if (!device_change) {
2910 if ((audcal_info.dev_type & TX_DEVICE) == 2) {
2911 if (!(acdb_data.acdb_state & AUDREC0_READY))
2912 acdb_data.audrec_applied &= ~AUDREC0_READY;
2913 if (!(acdb_data.acdb_state & AUDREC1_READY))
2914 acdb_data.audrec_applied &= ~AUDREC1_READY;
2915 if (!(acdb_data.acdb_state & AUDREC2_READY))
2916 acdb_data.audrec_applied &= ~AUDREC2_READY;
2917 acdb_data.acdb_state &= ~CAL_DATA_READY;
2918 goto update_cache;
2919 }
2920 } else
2921 /* state is updated to querry the modem for values */
2922 acdb_data.acdb_state &= ~CAL_DATA_READY;
2923
2924update_cache:
2925 if ((audcal_info.dev_type & TX_DEVICE) == 2) {
2926 /*loop is to take care of use case:- multiple Audrec
2927 sessions are routed before enabling the device in this use
2928 case we will get the sessions value as bits set for all the
2929 sessions routed before device enable, so we should take care
2930 of copying device info to all the sessions*/
2931 for (i = 0; i < MAX_AUDREC_SESSIONS; i++) {
2932 stream_id = ((audcal_info.sessions >> i) & 0x01);
2933 if (stream_id) {
2934 acdb_cache_free_node = &acdb_cache_tx[i];
2935 ret = check_device_info_already_present(
2936 audcal_info,
2937 acdb_cache_free_node);
2938 acdb_cache_free_node->stream_id = i;
2939 acdb_data.cur_tx_session = i;
2940 count++;
2941 }
2942 }
2943 if (count > 1)
2944 acdb_data.multiple_sessions = 1;
2945 } else {
2946 acdb_cache_free_node = &acdb_cache_rx[audcal_info.dev_id];
2947 ret = check_device_info_already_present(audcal_info,
2948 acdb_cache_free_node);
2949 if (ret == 1) {
2950 MM_DBG("got device ready call back for another "
2951 "audplay task sessions on same COPP\n");
2952 /*stream_id is used to keep track of number of active*/
2953 /*sessions active on this device*/
2954 acdb_cache_free_node->stream_id++;
2955 mutex_unlock(&acdb_data.acdb_mutex);
2956 goto done;
2957 }
2958 acdb_cache_free_node->stream_id++;
2959 }
2960 update_acdb_data_struct(acdb_cache_free_node);
2961 acdb_data.device_cb_compl = 1;
2962 mutex_unlock(&acdb_data.acdb_mutex);
2963 wake_up(&acdb_data.wait);
2964done:
2965 return;
2966}
2967
2968
2969static s32 register_device_cb(void)
2970{
2971 s32 result = 0;
2972
2973 result = auddev_register_evt_listner((AUDDEV_EVT_DEV_RDY
2974 | AUDDEV_EVT_DEV_RLS),
2975 AUDDEV_CLNT_AUDIOCAL, 0, device_cb, (void *)&acdb_data);
2976
2977 if (result) {
2978 MM_ERR("ACDB=> Could not register device callback\n");
2979 result = -ENODEV;
2980 goto done;
2981 }
2982done:
2983 return result;
2984}
2985
2986static void audpp_cb(void *private, u32 id, u16 *msg)
2987{
2988 MM_DBG("\n");
2989 if (id != AUDPP_MSG_CFG_MSG)
2990 goto done;
2991
2992 if (msg[0] == AUDPP_MSG_ENA_DIS) {
Santosh Mardie9185852011-09-08 10:38:31 +05302993 if (--acdb_cache_rx[acdb_data.\
2994 device_info->dev_id].stream_id <= 0) {
2995 acdb_data.acdb_state &= ~AUDPP_READY;
2996 acdb_cache_rx[acdb_data.device_info->dev_id]\
2997 .stream_id = 0;
2998 MM_DBG("AUDPP_MSG_ENA_DIS\n");
2999 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003000 goto done;
3001 }
3002
3003 acdb_data.acdb_state |= AUDPP_READY;
3004 acdb_data.audpp_cb_compl = 1;
3005 wake_up(&acdb_data.wait);
3006done:
3007 return;
3008}
3009
3010static s8 handle_audpreproc_cb(void)
3011{
3012 struct acdb_cache_node *acdb_cached_values;
3013 s8 result = 0;
3014 u8 stream_id = acdb_data.preproc_stream_id;
3015 acdb_data.preproc_cb_compl = 0;
3016 acdb_cached_values = get_acdb_values_from_cache_tx(stream_id);
3017 if (acdb_cached_values == NULL) {
3018 MM_DBG("ERROR: to get chached acdb values\n");
3019 return -EPERM;
3020 }
3021 update_acdb_data_struct(acdb_cached_values);
3022 if (acdb_data.device_info->dev_id == PSEUDO_ACDB_ID) {
3023 MM_INFO("audpreproc is routed to pseudo device\n");
3024 return result;
3025 }
Kalyani polepeddyaeea8bf2011-10-20 10:51:07 +05303026 if (acdb_data.build_id[17] == '1') {
3027 if (session_info[stream_id].sampling_freq)
3028 acdb_data.device_info->sample_rate =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003029 session_info[stream_id].sampling_freq;
Kalyani polepeddyaeea8bf2011-10-20 10:51:07 +05303030 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003031 if (!(acdb_data.acdb_state & CAL_DATA_READY)) {
3032 result = check_tx_acdb_values_cached();
3033 if (result) {
3034 result = acdb_get_calibration();
3035 if (result < 0) {
3036 MM_ERR("failed to get calibration data\n");
3037 return result;
3038 }
3039 }
3040 acdb_cached_values->node_status = ACDB_VALUES_FILLED;
3041 }
3042 return result;
3043}
3044
3045void fluence_feature_update(int enable, int stream_id)
3046{
3047 MM_INFO("Fluence feature over ride with = %d\n", enable);
3048 acdb_data.fleuce_feature_status[stream_id] = enable;
3049}
3050EXPORT_SYMBOL(fluence_feature_update);
3051
3052static void audpreproc_cb(void *private, u32 id, void *msg)
3053{
3054 struct audpreproc_cmd_enc_cfg_done_msg *tmp;
3055 u8 result = 0;
3056 int stream_id = 0;
3057 if (id != AUDPREPROC_CMD_ENC_CFG_DONE_MSG)
3058 goto done;
3059
3060 tmp = (struct audpreproc_cmd_enc_cfg_done_msg *)msg;
3061 acdb_data.preproc_stream_id = tmp->stream_id;
3062 stream_id = acdb_data.preproc_stream_id;
3063 get_audrec_session_info(stream_id, &session_info[stream_id]);
3064 MM_DBG("rec_enc_type = %x\n", tmp->rec_enc_type);
3065 if ((tmp->rec_enc_type & 0x8000) ==
3066 AUD_PREPROC_CONFIG_DISABLED) {
3067 if (acdb_data.preproc_stream_id == 0) {
3068 acdb_data.acdb_state &= ~AUDREC0_READY;
3069 acdb_data.audrec_applied &= ~AUDREC0_READY;
3070 } else if (acdb_data.preproc_stream_id == 1) {
3071 acdb_data.acdb_state &= ~AUDREC1_READY;
3072 acdb_data.audrec_applied &= ~AUDREC1_READY;
3073 } else if (acdb_data.preproc_stream_id == 2) {
3074 acdb_data.acdb_state &= ~AUDREC2_READY;
3075 acdb_data.audrec_applied &= ~AUDREC2_READY;
3076 }
3077 acdb_data.fleuce_feature_status[stream_id] = 0;
3078 acdb_cache_tx[tmp->stream_id].node_status =\
3079 ACDB_VALUES_NOT_FILLED;
3080 acdb_data.acdb_state &= ~CAL_DATA_READY;
3081 goto done;
3082 }
3083 /*Following check is added to make sure that device info
3084 is updated. audpre proc layer enabled without device
3085 callback at this scenario we should not access
3086 device information
3087 */
Kalyani polepeddyaeea8bf2011-10-20 10:51:07 +05303088 if (acdb_data.build_id[17] != '0') {
3089 if (acdb_data.device_info &&
3090 session_info[stream_id].sampling_freq) {
3091 acdb_data.device_info->sample_rate =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003092 session_info[stream_id].sampling_freq;
Kalyani polepeddyaeea8bf2011-10-20 10:51:07 +05303093 result = check_tx_acdb_values_cached();
3094 if (!result) {
3095 MM_INFO("acdb values for the stream is" \
3096 " querried from modem");
3097 acdb_data.acdb_state |= CAL_DATA_READY;
3098 } else {
3099 acdb_data.acdb_state &= ~CAL_DATA_READY;
3100 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003101 }
3102 }
3103 if (acdb_data.preproc_stream_id == 0)
3104 acdb_data.acdb_state |= AUDREC0_READY;
3105 else if (acdb_data.preproc_stream_id == 1)
3106 acdb_data.acdb_state |= AUDREC1_READY;
3107 else if (acdb_data.preproc_stream_id == 2)
3108 acdb_data.acdb_state |= AUDREC2_READY;
3109 acdb_data.preproc_cb_compl = 1;
3110 MM_DBG("acdb_data.acdb_state = %x\n", acdb_data.acdb_state);
3111 wake_up(&acdb_data.wait);
3112done:
3113 return;
3114}
3115
3116static s32 register_audpp_cb(void)
3117{
3118 s32 result = 0;
3119
3120 acdb_data.audpp_cb.fn = audpp_cb;
3121 acdb_data.audpp_cb.private = NULL;
3122 result = audpp_register_event_callback(&acdb_data.audpp_cb);
3123 if (result) {
3124 MM_ERR("ACDB=> Could not register audpp callback\n");
3125 result = -ENODEV;
3126 goto done;
3127 }
3128done:
3129 return result;
3130}
3131
3132static s32 register_audpreproc_cb(void)
3133{
3134 s32 result = 0;
3135
3136 acdb_data.audpreproc_cb.fn = audpreproc_cb;
3137 acdb_data.audpreproc_cb.private = NULL;
3138 result = audpreproc_register_event_callback(&acdb_data.audpreproc_cb);
3139 if (result) {
3140 MM_ERR("ACDB=> Could not register audpreproc callback\n");
3141 result = -ENODEV;
3142 goto done;
3143 }
3144
3145done:
3146 return result;
3147}
3148
3149static s32 acdb_initialize_data(void)
3150{
3151 s32 result = 0;
3152
3153 mutex_init(&acdb_data.acdb_mutex);
3154
3155 result = initialize_rpc();
3156 if (result)
3157 goto err;
3158
3159 result = initialize_memory();
3160 if (result)
3161 goto err1;
3162
3163 result = register_device_cb();
3164 if (result)
3165 goto err2;
3166
3167 result = register_audpp_cb();
3168 if (result)
3169 goto err3;
3170
3171 result = register_audpreproc_cb();
3172 if (result)
3173 goto err4;
3174
Kalyani polepeddyaeea8bf2011-10-20 10:51:07 +05303175
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003176 return result;
3177
3178err4:
3179 result = audpreproc_unregister_event_callback(&acdb_data.audpreproc_cb);
3180 if (result)
3181 MM_ERR("ACDB=> Could not unregister audpreproc callback\n");
3182err3:
3183 result = audpp_unregister_event_callback(&acdb_data.audpp_cb);
3184 if (result)
3185 MM_ERR("ACDB=> Could not unregister audpp callback\n");
3186err2:
3187 result = auddev_unregister_evt_listner(AUDDEV_CLNT_AUDIOCAL, 0);
3188 if (result)
3189 MM_ERR("ACDB=> Could not unregister device callback\n");
3190err1:
3191 daldevice_detach(acdb_data.handle);
3192 acdb_data.handle = NULL;
3193err:
3194 return result;
3195}
3196
3197static s32 initialize_modem_acdb(void)
3198{
3199 struct acdb_cmd_init_adie acdb_cmd;
3200 u8 codec_type = -1;
3201 s32 result = 0;
3202 u8 iterations = 0;
3203
3204 codec_type = adie_get_detected_codec_type();
3205 if (codec_type == MARIMBA_ID)
3206 acdb_cmd.adie_type = ACDB_CURRENT_ADIE_MODE_MARIMBA;
3207 else if (codec_type == TIMPANI_ID)
3208 acdb_cmd.adie_type = ACDB_CURRENT_ADIE_MODE_TIMPANI;
3209 else
3210 acdb_cmd.adie_type = ACDB_CURRENT_ADIE_MODE_UNKNOWN;
3211 acdb_cmd.command_id = ACDB_CMD_INITIALIZE_FOR_ADIE;
3212 do {
3213 /*Initialize ACDB software on modem based on codec type*/
3214 result = dalrpc_fcn_8(ACDB_DalACDB_ioctl, acdb_data.handle,
3215 (const void *)&acdb_cmd, sizeof(acdb_cmd),
3216 &acdb_data.acdb_result,
3217 sizeof(acdb_data.acdb_result));
3218 if (result < 0) {
3219 MM_ERR("ACDB=> RPC failure result = %d\n", result);
3220 goto error;
3221 }
3222 /*following check is introduced to handle boot up race
3223 condition between AUDCAL SW peers running on apps
3224 and modem (ACDB_RES_BADSTATE indicates modem AUDCAL SW is
3225 not in initialized sate) we need to retry to get ACDB
3226 initialized*/
3227 if (acdb_data.acdb_result.result == ACDB_RES_BADSTATE) {
3228 msleep(500);
3229 iterations++;
3230 } else if (acdb_data.acdb_result.result == ACDB_RES_SUCCESS) {
3231 MM_DBG("Modem ACDB SW initialized ((iterations = %d)\n",
3232 iterations);
3233 return result;
3234 } else {
3235 MM_ERR("ACDB=> Modem ACDB SW failed to initialize"
3236 " reuslt = %d, (iterations = %d)\n",
3237 acdb_data.acdb_result.result,
3238 iterations);
3239 goto error;
3240 }
3241 } while (iterations < MAX_RETRY);
3242 MM_ERR("ACDB=> AUDCAL SW on modem is not in intiailized state (%d)\n",
3243 acdb_data.acdb_result.result);
3244error:
3245 result = -EINVAL;
3246 return result;
3247}
3248
3249static s32 acdb_calibrate_device(void *data)
3250{
3251 s32 result = 0;
3252
3253 /* initialize driver */
3254 result = acdb_initialize_data();
3255 if (result)
3256 goto done;
Kalyani polepeddyaeea8bf2011-10-20 10:51:07 +05303257 if (acdb_data.build_id[17] != '0') {
3258 result = initialize_modem_acdb();
3259 if (result < 0)
3260 MM_ERR("failed to initialize modem ACDB\n");
3261 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003262
3263 while (!kthread_should_stop()) {
3264 MM_DBG("Waiting for call back events\n");
3265 wait_event_interruptible(acdb_data.wait,
3266 (acdb_data.device_cb_compl
3267 | acdb_data.audpp_cb_compl
3268 | acdb_data.preproc_cb_compl));
3269 mutex_lock(&acdb_data.acdb_mutex);
3270 if (acdb_data.device_cb_compl) {
3271 acdb_data.device_cb_compl = 0;
3272 if (!(acdb_data.acdb_state & CAL_DATA_READY)) {
3273 if ((acdb_data.device_info->dev_type
3274 & RX_DEVICE) == 1) {
3275 /*we need to get calibration values
3276 only for RX device as resampler
3277 moved to start of the pre - proc chain
3278 tx calibration value will be based on
3279 sampling frequency what audrec is
3280 configured, calibration values for tx
3281 device are fetch in audpreproc
3282 callback*/
3283 result = acdb_get_calibration();
3284 if (result < 0) {
3285 mutex_unlock(
3286 &acdb_data.acdb_mutex);
3287 MM_ERR("Not able to get "
3288 "calibration "
3289 "data continue\n");
3290 continue;
3291 }
3292 }
3293 }
3294 MM_DBG("acdb state = %d\n",
3295 acdb_data.acdb_state);
3296 if ((acdb_data.device_info->dev_type & TX_DEVICE) == 2)
3297 handle_tx_device_ready_callback();
3298 else {
3299 acdb_cache_rx[acdb_data.device_info->dev_id]\
3300 .node_status =
3301 ACDB_VALUES_FILLED;
3302 if (acdb_data.acdb_state &
3303 AUDPP_READY) {
3304 MM_DBG("AUDPP already enabled "
3305 "apply acdb values\n");
3306 goto apply;
3307 }
3308 }
3309 }
3310
3311 if (!(acdb_data.audpp_cb_compl ||
3312 acdb_data.preproc_cb_compl)) {
3313 MM_DBG("need to wait for either AUDPP / AUDPREPROC "
3314 "Event\n");
3315 mutex_unlock(&acdb_data.acdb_mutex);
3316 continue;
3317 } else {
3318 MM_DBG("got audpp / preproc call back\n");
3319 if (acdb_data.audpp_cb_compl) {
3320 send_acdb_values_for_active_devices();
3321 acdb_data.audpp_cb_compl = 0;
3322 mutex_unlock(&acdb_data.acdb_mutex);
3323 continue;
3324 } else {
3325 result = handle_audpreproc_cb();
3326 if (result < 0) {
3327 mutex_unlock(&acdb_data.acdb_mutex);
3328 continue;
3329 }
3330 }
3331 }
3332apply:
3333 if (acdb_data.acdb_state & CAL_DATA_READY)
3334 result = acdb_send_calibration();
3335
3336 mutex_unlock(&acdb_data.acdb_mutex);
3337 }
3338done:
3339 return 0;
3340}
3341
3342static int __init acdb_init(void)
3343{
3344
3345 s32 result = 0;
3346
3347 memset(&acdb_data, 0, sizeof(acdb_data));
3348 spin_lock_init(&acdb_data.dsp_lock);
3349 acdb_data.cb_thread_task = kthread_run(acdb_calibrate_device,
3350 NULL, "acdb_cb_thread");
3351
3352 if (IS_ERR(acdb_data.cb_thread_task)) {
3353 MM_ERR("ACDB=> Could not register cb thread\n");
3354 result = -ENODEV;
3355 goto err;
3356 }
Kalyani polepeddyaeea8bf2011-10-20 10:51:07 +05303357
3358 acdb_data.build_id = socinfo_get_build_id();
3359 MM_INFO("build id used is = %s\n", acdb_data.build_id);
3360
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003361#ifdef CONFIG_DEBUG_FS
3362 /*This is RTC specific INIT used only with debugfs*/
3363 if (!rtc_acdb_init())
3364 MM_ERR("RTC ACDB=>INIT Failure\n");
3365
3366#endif
3367 init_waitqueue_head(&acdb_data.wait);
3368
3369 return misc_register(&acdb_misc);
3370err:
3371 return result;
3372}
3373
3374static void __exit acdb_exit(void)
3375{
3376 s32 result = 0;
3377 u32 i = 0;
3378
3379 result = auddev_unregister_evt_listner(AUDDEV_CLNT_AUDIOCAL, 0);
3380 if (result)
3381 MM_ERR("ACDB=> Could not unregister device callback\n");
3382
3383 result = audpp_unregister_event_callback(&acdb_data.audpp_cb);
3384 if (result)
3385 MM_ERR("ACDB=> Could not unregister audpp callback\n");
3386
3387 result = audpreproc_unregister_event_callback(&acdb_data.\
3388 audpreproc_cb);
3389 if (result)
3390 MM_ERR("ACDB=> Could not unregister audpreproc callback\n");
3391
3392 result = kthread_stop(acdb_data.cb_thread_task);
3393 if (result)
3394 MM_ERR("ACDB=> Could not stop kthread\n");
3395
3396 free_memory_acdb_get_blk();
3397
3398 for (i = 0; i < MAX_COPP_NODE_SUPPORTED; i++) {
3399 if (i < MAX_AUDREC_SESSIONS) {
Laura Abbott61399692012-04-30 14:25:46 -07003400 iounmap(acdb_cache_tx[i].map_v_addr);
Santosh Mardifdc227a2011-07-11 17:20:34 +05303401 free_contiguous_memory_by_paddr(
3402 acdb_cache_tx[i].phys_addr_acdb_values);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003403 }
Laura Abbott61399692012-04-30 14:25:46 -07003404 iounmap(acdb_cache_rx[i].map_v_addr);
Santosh Mardifdc227a2011-07-11 17:20:34 +05303405 free_contiguous_memory_by_paddr(
3406 acdb_cache_rx[i].phys_addr_acdb_values);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003407 }
3408 kfree(acdb_data.device_info);
3409 kfree(acdb_data.pp_iir);
3410 kfree(acdb_data.pp_mbadrc);
3411 kfree(acdb_data.preproc_agc);
3412 kfree(acdb_data.preproc_iir);
Santosh Mardifdc227a2011-07-11 17:20:34 +05303413 free_contiguous_memory_by_paddr(
3414 (int32_t)acdb_data.pbe_extbuff);
Laura Abbott61399692012-04-30 14:25:46 -07003415 iounmap(acdb_data.map_v_fluence);
Santosh Mardifdc227a2011-07-11 17:20:34 +05303416 free_contiguous_memory_by_paddr(
3417 (int32_t)acdb_data.fluence_extbuff);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003418 mutex_destroy(&acdb_data.acdb_mutex);
3419 memset(&acdb_data, 0, sizeof(acdb_data));
3420 #ifdef CONFIG_DEBUG_FS
3421 rtc_acdb_deinit();
3422 #endif
3423}
3424
3425late_initcall(acdb_init);
3426module_exit(acdb_exit);
3427
3428MODULE_DESCRIPTION("MSM 7x30 Audio ACDB driver");
3429MODULE_LICENSE("GPL v2");