Merge changes I62675981,I714beeaf,Icca721b3,I9ee58aae into msm-3.4
* changes:
qdsp5: audio: Add Acdb and RTC support for 8x25
qdsp5: audio: Remove audpp and audrec definitions from audmgr driver
qdsp5: audio: Update encoder drivers to use preproc driver functions
qdsp5: audio: Move preproc functionality to audio preproc driver
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/acdb_commands.h b/arch/arm/mach-msm/include/mach/qdsp5/acdb_commands.h
new file mode 100644
index 0000000..188af9f
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/qdsp5/acdb_commands.h
@@ -0,0 +1,303 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef _MACH_QDSP5_V2_ACDB_COMMANDS_H
+#define _MACH_QDSP5_V2_ACDB_COMMANDS_H
+
+#define ACDB_VOICE_NETWORK_ID_DEFAULT 0x00010037
+#define ACDB_INITIALISING 0
+#define ACDB_READY 1
+
+
+/* 4KB */
+#define ACDB_PAGE_SIZE 0x1000
+
+#define ACDB_CDMA_NB 0x0108b153
+#define ACDB_CDMA_WB 0x0108b154
+#define ACDB_GSM_NB 0x0108b155
+#define ACDB_GSM_WB 0x0108b156
+#define ACDB_WCDMA_NB 0x0108b157
+#define ACDB_WCDMA_WB 0x0108b158
+
+
+/* ACDB commands */
+
+
+/* struct acdb_cmd_install_device */
+#define ACDB_INSTALL_DEVICE 0x0108d245
+
+/* struct acdb_cmd_install_device */
+#define ACDB_UNINSTALL_DEVICE 0x0108d246
+
+/* struct acdb_cmd_device */
+#define ACDB_GET_DEVICE 0x0108bb92
+
+/* struct acdb_cmd_device */
+#define ACDB_SET_DEVICE 0x0108bb93
+
+/* struct acdb_cmd_get_device_table */
+#define ACDB_GET_DEVICE_TABLE 0x0108bb97
+
+/* struct acdb_cmd_get_device_capabilities */
+#define ACDB_GET_DEVICE_CAPABILITIES 0x0108f5ca
+
+/* struct acdb_cmd_get_device_info */
+#define ACDB_GET_DEVICE_INFO 0x0108f5cb
+
+/*command to intitialize ACDB based on codec type*/
+#define ACDB_CMD_INITIALIZE_FOR_ADIE 0x00011283
+
+
+/* ACDB Error codes */
+
+#define ACDB_RES_SUCCESS 0
+#define ACDB_RES_FAILURE -1
+#define ACDB_RES_BADPARM -2
+#define ACDB_RES_BADSTATE -3
+
+#define TGTVERS_MSM7x30_BRING_UP 0x00010064
+
+
+
+/* Algorithm Aspect IDs */
+
+#define IID_ENABLE_FLAG 0x0108b6b9
+
+
+#define IID_ENABLE_FLAG_SIZE 1
+#define IID_ECHO_CANCELLER_VERSION_SIZE 2
+#define IID_ECHO_CANCELLER_MODE_SIZE 2
+#define IID_ECHO_CANCELLER_NOISE_SUPPRESSOR_ENABLE_SIZE 1
+#define IID_ECHO_CANCELLER_PARAMETERS_SIZE 32
+#define IID_ECHO_CANCELLER_NEXTGEN_NB_PARAMETERS_SIZE (38 * 2)
+#define IID_ECHO_CANCELLER_NEXTGEN_WB_PARAMETERS_SIZE (38 * 2)
+#define IID_FLUENCE_PARAMETERS_SIZE 486
+#define IID_AFE_VOLUME_CONTROL_SIZE 6
+#define IID_GAIN_SIZE 2
+#define IID_VOICE_FIR_FILTER_SIZE 14
+#define IID_VOICE_IIR_FILTER_SIZE 114
+#define IID_RX_DBM_OFFSET_SIZE 2
+#define IID_AGC_SIZE 36
+#define IID_AVC_SIZE 80
+
+#define IID_AUDIO_IIR_COEFF_SIZE 100
+#define IID_MBADRC_PARAMETERS_SIZE 8
+#define IID_MBADRC_EXT_BUFF_SIZE 392
+#define IID_MBADRC_BAND_CONFIG_SIZE 100
+#define IID_QAFX_PARAMETERS_SIZE 2
+#define IID_QCONCERT_PARAMETERS_SIZE 2
+#define IID_AUDIO_AGC_PARAMETERS_SIZE 42
+#define IID_NS_PARAMETERS_SIZE 14
+
+#define IID_ECHO_CANCELLER_VERSION 0x00010042
+#define IID_ECHO_CANCELLER_MODE 0x00010043
+#define IID_ECHO_CANCELLER_NOISE_SUPPRESSOR_ENABLE 0x00010044
+#define IID_ECHO_CANCELLER_PARAMETERS 0x00010045
+#define IID_ECHO_CANCELLER_NEXTGEN_NB_PARAMETERS 0x00010046
+#define IID_ECHO_CANCELLER_NEXTGEN_WB_PARAMETERS 0x00010047
+#define IID_FLUENCE_PARAMETERS 0x00010048
+#define IID_AFE_VOLUME_CONTROL 0x00010049
+#define IID_GAIN 0x0001004A
+#define IID_VOICE_FIR_FILTER 0x0001004B
+#define IID_VOICE_IIR_FILTER 0x0001004C
+#define IID_AGC 0x0001004E
+#define IID_AVC 0x0001004F
+#define ABID_SIDETONE_GAIN 0x00010050
+#define ABID_TX_VOICE_GAIN 0x00010051
+#define ABID_TX_DTMF_GAIN 0x00010052
+#define ABID_CODEC_TX_GAIN 0x00010053
+#define ABID_HSSD 0x00010054
+#define ABID_TX_AGC 0x00010055
+#define ABID_TX_VOICE_FIR 0x00010056
+#define ABID_TX_VOICE_IIR 0x00010057
+#define ABID_ECHO_CANCELLER 0x00010058
+#define ABID_ECHO_CANCELLER_NB_LVHF 0x00010059
+#define ABID_ECHO_CANCELLER_WB_LVHF 0x0001005A
+#define ABID_FLUENCE 0x0001005B
+#define ABID_CODEC_RX_GAIN 0x0001005C
+#define ABID_RX_DBM_OFFSET 0x0001005D
+#define ABID_RX_AGC 0x0001005E
+#define ABID_AVC 0x0001005F
+#define ABID_RX_VOICE_FIR 0x00010060
+#define ABID_RX_VOICE_IIR 0x00010061
+#define ABID_AFE_VOL_CTRL 0x00010067
+
+
+/* AUDIO IDs */
+#define ABID_AUDIO_AGC_TX 0x00010068
+#define ABID_AUDIO_NS_TX 0x00010069
+#define ABID_VOICE_NS 0x0001006A
+#define ABID_AUDIO_IIR_TX 0x0001006B
+#define ABID_AUDIO_IIR_RX 0x0001006C
+#define ABID_AUDIO_MBADRC_RX 0x0001006E
+#define ABID_AUDIO_QAFX_RX 0x0001006F
+#define ABID_AUDIO_QCONCERT_RX 0x00010070
+#define ABID_AUDIO_STF_RX 0x00010071
+#define ABID_AUDIO_CALIBRATION_GAIN_RX 0x00011162
+#define ABID_AUDIO_CALIBRATION_GAIN_TX 0x00011149
+#define ABID_AUDIO_PBE_RX 0x00011197
+#define ABID_AUDIO_RMC_TX 0x00011226
+#define ABID_AUDIO_FLUENCE_TX 0x00011244
+
+
+#define IID_AUDIO_AGC_PARAMETERS 0x0001007E
+#define IID_NS_PARAMETERS 0x00010072
+#define IID_AUDIO_IIR_COEFF 0x00010073
+#define IID_MBADRC_EXT_BUFF 0x00010075
+#define IID_MBADRC_BAND_CONFIG 0x00010076
+#define IID_MBADRC_PARAMETERS 0x00010077
+#define IID_QAFX_PARAMETERS 0x00010079
+#define IID_QCONCERT_PARAMETERS 0x0001007A
+#define IID_STF_COEFF 0x0001007B
+#define IID_AUDIO_CALIBRATION_GAIN_RX 0x00011163
+#define IID_AUDIO_CALIBRATION_GAIN_TX 0x00011171
+#define IID_PBE_CONFIG_PARAMETERS 0x00011198
+#define IID_AUDIO_PBE_RX_ENABLE_FLAG 0x00011199
+#define IID_AUDIO_RMC_PARAM 0x00011227
+#define IID_AUDIO_FLUENCE_TX 0x00011245
+
+
+#define TOPID_RX_TOPOLOGY_1 0x00010062
+#define TOPID_TX_TOPOLOGY_1 0x00010063
+#define AFERID_INT_SINK 0x00010065
+#define AFERID_INT_SOURCE 0x00010066
+#define AFERID_NO_SINK 0x00000000
+#define AFERID_NULL_SINK 0x0108ea92
+
+
+struct acdb_cmd_install_device {
+ u32 command_id;
+ u32 device_id;
+ u32 topology_id;
+ u32 afe_routing_id;
+ u32 cad_routing_id; /* see "Sample Rate Bit Mask" below */
+ u32 sample_rate_mask;
+
+ /* represents device direction: Tx, Rx (aux pga - loopback) */
+ u8 device_type;
+ u8 channel_config; /* Mono or Stereo */
+ u32 adie_codec_path_id;
+};
+
+
+struct acdb_cmd_get_device_capabilities {
+ u32 command_id;
+ u32 total_bytes; /* Length in bytes allocated for buffer */
+ u32 *phys_buf; /* Physical Address of data */
+};
+
+
+struct acdb_cmd_get_device_info {
+ u32 command_id;
+ u32 device_id;
+ u32 total_bytes; /* Length in bytes allocated for buffer */
+ u32 *phys_buf; /* Physical Address of data */
+};
+
+struct acdb_cmd_device {
+ u32 command_id;
+ u32 device_id;
+ u32 network_id;
+ u32 sample_rate_id; /* Actual sample rate value */
+ u32 interface_id; /* See interface id's above */
+ u32 algorithm_block_id; /* See enumerations above */
+ u32 total_bytes; /* Length in bytes used by buffer */
+ u32 *phys_buf; /* Physical Address of data */
+};
+
+struct acdb_cmd_get_device_table {
+ u32 command_id;
+ u32 device_id;
+ u32 network_id;
+ u32 sample_rate_id; /* Actual sample rate value */
+ u32 total_bytes; /* Length in bytes used by buffer */
+ u32 *phys_buf; /* Physical Address of data */
+};
+
+struct acdb_result {
+ /* This field is populated in response to the */
+ /* ACDB_GET_DEVICE_CAPABILITIES command and indicates the total */
+ /* devices whose capabilities are copied to the physical memory. */
+ u32 total_devices;
+ u32 *buf; /* Physical Address of data */
+ u32 used_bytes; /* The size in bytes of the data */
+ u32 result; /* See ACDB Error codes above */
+};
+
+struct acdb_device_capability {
+ u32 device_id;
+ u32 sample_rate_mask; /* See "Sample Rate Bit Mask" below */
+};
+
+struct acdb_dev_info {
+ u32 cad_routing_id;
+ u32 sample_rate_mask; /* See "Sample Rate Bit Mask" below */
+ u32 adsp_device_id; /* QDSP6 device ID */
+ u32 device_type; /* Tx, Rx (aux pga - loopback) */
+ u32 channel_config; /* Mono or Stereo */
+ s32 min_volume; /* Min volume (mB) */
+ s32 max_volume; /* Max volume (mB) */
+};
+
+/*structure is used to intialize ACDB software on modem
+based on adie type detected*/
+struct acdb_cmd_init_adie {
+ u32 command_id;
+ u32 adie_type;
+};
+
+#define ACDB_CURRENT_ADIE_MODE_UNKNOWN 0
+#define ACDB_CURRENT_ADIE_MODE_TIMPANI 1
+#define ACDB_CURRENT_ADIE_MODE_MARIMBA 2
+
+/* Sample Rate Bit Mask */
+
+/* AUX PGA devices will have a sample rate mask of 0xFFFFFFFF */
+/* 8kHz 0x00000001 */
+/* 11.025kHz 0x00000002 */
+/* 12kHz 0x00000004 */
+/* 16kHz 0x00000008 */
+/* 22.5kHz 0x00000010 */
+/* 24kHz 0x00000020 */
+/* 32kHz 0x00000040 */
+/* 44.1kHz 0x00000080 */
+/* 48kHz 0x00000100 */
+
+
+/* Device type enumeration */
+enum {
+ RX_DEVICE = 1,
+ TX_DEVICE,
+ AUXPGA_DEVICE,
+ DEVICE_TYPE_MAX
+};
+
+#ifdef CONFIG_DEBUG_FS
+/*These are ABID used for RTC*/
+#define ABID_AUDIO_RTC_MBADRC_RX 0x0001118A
+#define ABID_AUDIO_RTC_VOLUME_PAN_RX 0x0001118C
+#define ABID_AUDIO_RTC_SPA 0x0001118E
+#define ABID_AUDIO_RTC_EQUALIZER_PARAMETERS 0x0001119F
+
+/*These are IID used for RTC*/
+#define IID_AUDIO_RTC_MBADRC_PARAMETERS 0x0001118B
+#define IID_AUDIO_RTC_VOLUME_PAN_PARAMETERS 0x0001118D
+#define IID_AUDIO_RTC_SPA_PARAMETERS 0x0001118F
+#define IID_AUDIO_RTC_EQUALIZER_PARAMETERS 0x0001119E
+#define IID_AUDIO_RTC_AGC_PARAMETERS 0x000111A7
+#define IID_AUDIO_RTC_TX_IIR_COEFF 0x000111A8
+
+#endif
+
+
+#endif
+
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/audio_acdb_def.h b/arch/arm/mach-msm/include/mach/qdsp5/audio_acdb_def.h
new file mode 100644
index 0000000..e1fc0cd
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/qdsp5/audio_acdb_def.h
@@ -0,0 +1,51 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef _MACH_QDSP5_V2_AUDIO_ACDB_DEF_H
+#define _MACH_QDSP5_V2_AUDIO_ACDB_DEF_H
+
+/* Define ACDB device ID */
+#define ACDB_ID_HANDSET_SPKR 1
+#define ACDB_ID_HANDSET_MIC 2
+#define ACDB_ID_HEADSET_MIC 3
+#define ACDB_ID_HEADSET_SPKR_MONO 4
+#define ACDB_ID_HEADSET_SPKR_STEREO 5
+#define ACDB_ID_SPKR_PHONE_MIC 6
+#define ACDB_ID_SPKR_PHONE_MONO 7
+#define ACDB_ID_SPKR_PHONE_STEREO 8
+#define ACDB_ID_BT_SCO_MIC 9
+#define ACDB_ID_BT_SCO_SPKR 0x0A
+#define ACDB_ID_BT_A2DP_SPKR 0x0B
+#define ACDB_ID_BT_A2DP_TX 0x10
+#define ACDB_ID_TTY_HEADSET_MIC 0x0C
+#define ACDB_ID_TTY_HEADSET_SPKR 0x0D
+#define ACDB_ID_HEADSET_MONO_PLUS_SPKR_MONO_RX 0x11
+#define ACDB_ID_HEADSET_STEREO_PLUS_SPKR_STEREO_RX 0x14
+#define ACDB_ID_FM_TX_LOOPBACK 0x17
+#define ACDB_ID_FM_TX 0x18
+#define ACDB_ID_LP_FM_SPKR_PHONE_STEREO_RX 0x19
+#define ACDB_ID_LP_FM_HEADSET_SPKR_STEREO_RX 0x1A
+#define ACDB_ID_I2S_RX 0x20
+#define ACDB_ID_SPKR_PHONE_MIC_BROADSIDE 0x2B
+#define ACDB_ID_HANDSET_MIC_BROADSIDE 0x2C
+#define ACDB_ID_SPKR_PHONE_MIC_ENDFIRE 0x2D
+#define ACDB_ID_HANDSET_MIC_ENDFIRE 0x2E
+#define ACDB_ID_I2S_TX 0x30
+#define ACDB_ID_HDMI 0x40
+#define ACDB_ID_FM_RX 0x4F
+/*Replace the max device ID,if any new device is added Specific to RTC only*/
+#define ACDB_ID_MAX ACDB_ID_FM_RX
+
+/* ID used for virtual devices */
+#define PSEUDO_ACDB_ID 0xFFFF
+
+#endif /* _MACH_QDSP5_V2_AUDIO_ACDB_DEF_H */
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/audio_acdbi.h b/arch/arm/mach-msm/include/mach/qdsp5/audio_acdbi.h
new file mode 100644
index 0000000..5bad4fa
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/qdsp5/audio_acdbi.h
@@ -0,0 +1,132 @@
+/* Copyright (c) 2012 Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef _MACH_QDSP5_V2_AUDIO_ACDBI_H
+#define _MACH_QDSP5_V2_AUDIO_ACDBI_H
+
+#define DBOR_SIGNATURE 0x524F4244
+
+void acdb_rtc_set_err(u32 err_code);
+
+
+struct header {
+ u32 dbor_signature;
+ u32 abid;
+ u32 iid;
+ u32 data_len;
+};
+
+enum {
+ ACDB_AGC_BLOCK = 197,
+ ACDB_IIR_BLOCK = 245,
+ ACDB_MBADRC_BLOCK = 343
+};
+
+/* Structure to query for acdb parameter */
+struct acdb_get_block {
+ u32 acdb_id;
+ u32 sample_rate_id; /* Actual sample rate value */
+ u32 interface_id; /* Interface id's */
+ u32 algorithm_block_id; /* Algorithm block id */
+ u32 total_bytes; /* Length in bytes used by buffer for
+ configuration */
+ u32 *buf_ptr; /* Address for storing configuration
+ data */
+};
+
+struct acdb_agc_block {
+ u16 enable_status;
+ u16 comp_rlink_static_gain;
+ u16 comp_rlink_aig_flag;
+ u16 exp_rlink_threshold;
+ u16 exp_rlink_slope;
+ u16 comp_rlink_threshold;
+ u16 comp_rlink_slope;
+ u16 comp_rlink_aig_attack_k;
+ u16 comp_rlink_aig_leak_down;
+ u16 comp_rlink_aig_leak_up;
+ u16 comp_rlink_aig_max;
+ u16 comp_rlink_aig_min;
+ u16 comp_rlink_aig_release_k;
+ u16 comp_rlink_aig_sm_leak_rate_fast;
+ u16 comp_rlink_aig_sm_leak_rate_slow;
+ u16 comp_rlink_attack_k_msw;
+ u16 comp_rlink_attack_k_lsw;
+ u16 comp_rlink_delay;
+ u16 comp_rlink_release_k_msw;
+ u16 comp_rlink_release_k_lsw;
+ u16 comp_rlink_rms_trav;
+};
+
+
+struct iir_coeff_type {
+ u16 b0_lo;
+ u16 b0_hi;
+ u16 b1_lo;
+ u16 b1_hi;
+ u16 b2_lo;
+ u16 b2_hi;
+};
+
+struct iir_coeff_stage_a {
+ u16 a1_lo;
+ u16 a1_hi;
+ u16 a2_lo;
+ u16 a2_hi;
+};
+
+struct acdb_iir_block {
+ u16 enable_flag;
+ u16 stage_count;
+ struct iir_coeff_type stages[4];
+ struct iir_coeff_stage_a stages_a[4];
+ u16 shift_factor[4];
+ u16 pan[4];
+};
+
+struct mbadrc_band_config_type {
+ u16 mbadrc_sub_band_enable;
+ u16 mbadrc_sub_mute;
+ u16 mbadrc_comp_rms_tav;
+ u16 mbadrc_comp_threshold;
+ u16 mbadrc_comp_slop;
+ u16 mbadrc_comp_attack_msw;
+ u16 mbadrc_comp_attack_lsw;
+ u16 mbadrc_comp_release_msw;
+ u16 mbadrc_comp_release_lsw;
+ u16 mbadrc_make_up_gain;
+};
+
+struct mbadrc_parameter {
+ u16 mbadrc_enable;
+ u16 mbadrc_num_bands;
+ u16 mbadrc_down_sample_level;
+ u16 mbadrc_delay;
+};
+
+struct acdb_mbadrc_block {
+ u16 ext_buf[196];
+ struct mbadrc_band_config_type band_config[5];
+ struct mbadrc_parameter parameters;
+};
+
+struct acdb_ns_tx_block {
+ unsigned short ec_mode_new;
+ unsigned short dens_gamma_n;
+ unsigned short dens_nfe_block_size;
+ unsigned short dens_limit_ns;
+ unsigned short dens_limit_ns_d;
+ unsigned short wb_gamma_e;
+ unsigned short wb_gamma_n;
+};
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpp.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpp.h
new file mode 100644
index 0000000..bbd82a0
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpp.h
@@ -0,0 +1,93 @@
+/*arch/arm/mach-msm/qdsp5audpp.h
+ *
+ * Copyright (C) 2008 Google, Inc.
+ * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+*/
+
+#ifndef _MACH_QDSP5_AUDPP_H
+#define _MACH_QDSP5_AUDPP_H
+
+#include <mach/qdsp5/qdsp5audppcmdi.h>
+
+typedef void (*audpp_event_func)(void *private, unsigned id, uint16_t *msg);
+
+/* worst case delay of 1sec for response */
+#define MSM_AUD_DECODER_WAIT_MS 1000
+#define MSM_AUD_MODE_TUNNEL 0x00000100
+#define MSM_AUD_MODE_NONTUNNEL 0x00000200
+#define MSM_AUD_DECODER_MASK 0x0000FFFF
+#define MSM_AUD_OP_MASK 0xFFFF0000
+
+/*Playback mode*/
+#define NON_TUNNEL_MODE_PLAYBACK 1
+#define TUNNEL_MODE_PLAYBACK 0
+
+enum msm_aud_decoder_state {
+ MSM_AUD_DECODER_STATE_NONE = 0,
+ MSM_AUD_DECODER_STATE_FAILURE = 1,
+ MSM_AUD_DECODER_STATE_SUCCESS = 2,
+ MSM_AUD_DECODER_STATE_CLOSE = 3,
+};
+
+int audpp_adec_alloc(unsigned dec_attrb, const char **module_name,
+ unsigned *queueid);
+void audpp_adec_free(int decid);
+
+struct audpp_event_callback {
+ audpp_event_func fn;
+ void *private;
+};
+
+int audpp_register_event_callback(struct audpp_event_callback *eh);
+int audpp_unregister_event_callback(struct audpp_event_callback *eh);
+int is_audpp_enable(void);
+
+int audpp_enable(int id, audpp_event_func func, void *private);
+void audpp_disable(int id, void *private);
+
+int audpp_send_queue1(void *cmd, unsigned len);
+int audpp_send_queue2(void *cmd, unsigned len);
+int audpp_send_queue3(void *cmd, unsigned len);
+
+int audpp_set_volume_and_pan(unsigned id, unsigned volume, int pan);
+int audpp_pause(unsigned id, int pause);
+int audpp_flush(unsigned id);
+void audpp_avsync(int id, unsigned rate);
+unsigned audpp_avsync_sample_count(int id);
+unsigned audpp_avsync_byte_count(int id);
+int audpp_dsp_set_mbadrc(unsigned id, unsigned enable,
+ audpp_cmd_cfg_object_params_mbadrc *mbadrc);
+int audpp_dsp_set_eq(unsigned id, unsigned enable,
+ audpp_cmd_cfg_object_params_eqalizer *eq);
+int audpp_dsp_set_rx_iir(unsigned id, unsigned enable,
+ audpp_cmd_cfg_object_params_pcm *iir);
+
+int audpp_dsp_set_rx_srs_trumedia_g
+ (struct audpp_cmd_cfg_object_params_srstm_g *srstm);
+int audpp_dsp_set_rx_srs_trumedia_w
+ (struct audpp_cmd_cfg_object_params_srstm_w *srstm);
+int audpp_dsp_set_rx_srs_trumedia_c
+ (struct audpp_cmd_cfg_object_params_srstm_c *srstm);
+int audpp_dsp_set_rx_srs_trumedia_h
+ (struct audpp_cmd_cfg_object_params_srstm_h *srstm);
+int audpp_dsp_set_rx_srs_trumedia_p
+ (struct audpp_cmd_cfg_object_params_srstm_p *srstm);
+int audpp_dsp_set_rx_srs_trumedia_l
+ (struct audpp_cmd_cfg_object_params_srstm_l *srstm);
+
+int audpp_dsp_set_vol_pan(unsigned id,
+ audpp_cmd_cfg_object_params_volume *vol_pan);
+int audpp_dsp_set_qconcert_plus(unsigned id, unsigned enable,
+ audpp_cmd_cfg_object_params_qconcert *qconcert_plus);
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audppcmdi.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audppcmdi.h
index 3115299..de30c65 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audppcmdi.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audppcmdi.h
@@ -530,6 +530,18 @@
unsigned short arm_to_dsp_buf_len;
} __attribute__((packed)) audpp_cmd_pcm_intf_send_buffer;
+#define AUDPP_CMD_PP_FEAT_QUERY_PARAMS 0x0003
+
+struct rtc_audpp_read_data {
+ unsigned short cmd_id;
+ unsigned short obj_id;
+ unsigned short feature_id;
+ unsigned short extbufsizemsw;
+ unsigned short extbufsizelsw;
+ unsigned short extpart;
+ unsigned short extbufstartmsw;
+ unsigned short extbufstartlsw;
+} __packed ;
/*
* Commands Related to uPAudPPCmd3Queue
@@ -564,6 +576,8 @@
#define AUDPP_CMD_COMMON_CFG_UPDATE 0x8000
#define AUDPP_CMD_COMMON_CFG_DONT_UPDATE 0x0000
+#define AUDPP_CMD_COPP_STREAM 0x0006
+
typedef struct {
unsigned short cmd_id;
unsigned short obj0_cfg;
@@ -580,6 +594,7 @@
* Command Structure to configure post processing params (Volume)
*/
+#define AUDPP_CMD_VOLUME_PAN 0
#define AUDPP_CMD_CFG_OBJECT_PARAMS_VOLUME_LEN \
sizeof(audpp_cmd_cfg_object_params_volume)
@@ -645,6 +660,7 @@
pan pan_filter[4];
} __attribute__((packed)) filter_4;
+#define AUDPP_CMD_IIR_TUNING_FILTER 1
#define AUDPP_CMD_CFG_OBJECT_PARAMS_PCM_LEN \
sizeof(audpp_cmd_cfg_object_params_pcm)
@@ -666,6 +682,7 @@
* Command Structure to configure post processing parameters (equalizer)
*/
+#define AUDPP_CMD_EQUALIZER 2
#define AUDPP_CMD_CFG_OBJECT_PARAMS_EQALIZER_LEN \
sizeof(audpp_cmd_cfg_object_params_eqalizer)
@@ -787,6 +804,7 @@
* Command Structure to configure post processing parameters (ADRC)
*/
+#define AUDPP_CMD_ADRC 3
#define AUDPP_CMD_CFG_OBJECT_PARAMS_ADRC_LEN \
sizeof(audpp_cmd_cfg_object_params_adrc)
@@ -794,6 +812,7 @@
#define AUDPP_CMD_ADRC_FLAG_DIS 0x0000
#define AUDPP_CMD_ADRC_FLAG_ENA -1
+#define AUDPP_CMD_MBADRC 10
#define AUDPP_MAX_MBADRC_BANDS 5
#define AUDPP_MBADRC_EXTERNAL_BUF_SIZE 196
@@ -839,6 +858,7 @@
* Command Structure to configure post processing parameters(Spectrum Analizer)
*/
+#define AUDPP_CMD_SPECTROGRAM 4
#define AUDPP_CMD_CFG_OBJECT_PARAMS_SPECTRAM_LEN \
sizeof(audpp_cmd_cfg_object_params_spectram)
@@ -853,6 +873,7 @@
* Command Structure to configure post processing parameters (QConcert)
*/
+#define AUDPP_CMD_QCONCERT 5
#define AUDPP_CMD_CFG_OBJECT_PARAMS_QCONCERT_LEN \
sizeof(audpp_cmd_cfg_object_params_qconcert)
@@ -899,6 +920,7 @@
* Command Structure to configure post processing parameters (Side Chain)
*/
+#define AUDPP_CMD_SIDECHAIN_TUNING_FILTER 6
#define AUDPP_CMD_CFG_OBJECT_PARAMS_SIDECHAIN_LEN \
sizeof(audpp_cmd_cfg_object_params_sidechain)
@@ -923,6 +945,7 @@
* Command Structure to configure post processing parameters (QAFX)
*/
+#define AUDPP_CMD_QAFX 8
#define AUDPP_CMD_CFG_OBJECT_PARAMS_QAFX_LEN \
sizeof(audpp_cmd_cfg_object_params_qafx)
@@ -1046,6 +1069,8 @@
audpp_cmd_cfg_object_params_common common;
unsigned short v[SRS_PARAMS_MAX_L];
} __packed;
+#define AUDPP_CMD_SAMPLING_FREQUENCY 7
+#define AUDPP_CMD_QRUMBLE 9
#endif /* QDSP5AUDPPCMDI_H */
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audppmsg.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audppmsg.h
index 0ba8261..fef4c35 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audppmsg.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audppmsg.h
@@ -2,29 +2,29 @@
#define QDSP5AUDPPMSG_H
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
-
- Q D S P 5 A U D I O P O S T P R O C E S S I N G M S G
-
-GENERAL DESCRIPTION
- Messages sent by AUDPPTASK to ARM
-
-REFERENCES
- None
-
-EXTERNALIZED FUNCTIONS
- None
-
-Copyright (c) 1992-2009, Code Aurora Forum. All rights reserved.
-
-This software is licensed under the terms of the GNU General Public
-License version 2, as published by the Free Software Foundation, and
-may be copied, distributed, and modified under those terms.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
+*
+* Q D S P 5 A U D I O P O S T P R O C E S S I N G M S G
+*
+* GENERAL DESCRIPTION
+* Messages sent by AUDPPTASK to ARM
+*
+* REFERENCES
+* None
+*
+* EXTERNALIZED FUNCTIONS
+* None
+*
+* Copyright (c) 1992-2009, 2012 Code Aurora Forum. All rights reserved.
+*
+* This software is licensed under the terms of the GNU General Public
+* License version 2, as published by the Free Software Foundation, and
+* may be copied, distributed, and modified under those terms.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
/*===========================================================================
@@ -318,4 +318,5 @@
#define ADSP_MESSAGE_ID 0xFFFF
+#define AUDPP_MSG_FEAT_QUERY_DM_DONE 0x000b
#endif /* QDSP5AUDPPMSG_H */
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreproc.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreproc.h
index 234c4ac..5c7c5dc 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreproc.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreproc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -25,9 +25,49 @@
#define MSM_ADSP_ENC_MODE_TUNNEL 24
#define MSM_ADSP_ENC_MODE_NON_TUNNEL 25
+/* event callback routine prototype*/
+typedef void (*audpreproc_event_func)(void *private, unsigned id, void *msg);
+
+struct audpreproc_event_callback {
+ audpreproc_event_func fn;
+ void *private;
+};
+
+/*holds audrec information*/
+struct audrec_session_info {
+ int session_id;
+ int sampling_freq;
+};
+
/* Exported common api's from audpreproc layer */
int audpreproc_aenc_alloc(unsigned enc_type, const char **module_name,
unsigned *queue_id);
void audpreproc_aenc_free(int enc_id);
+int audpreproc_enable(int enc_id, audpreproc_event_func func, void *private);
+void audpreproc_disable(int enc_id, void *private);
+
+int audpreproc_unregister_event_callback(struct audpreproc_event_callback *ecb);
+
+int audpreproc_register_event_callback(struct audpreproc_event_callback *ecb);
+
+int audpreproc_update_audrec_info(struct audrec_session_info
+ *audrec_session_info);
+int get_audrec_session_info(struct audrec_session_info *info);
+
+int audpreproc_dsp_set_agc(audpreproc_cmd_cfg_agc_params *agc,
+ unsigned len);
+int audpreproc_dsp_set_ns(audpreproc_cmd_cfg_ns_params *ns,
+ unsigned len);
+int audpreproc_dsp_set_iir(audpreproc_cmd_cfg_iir_tuning_filter_params *iir,
+ unsigned len);
+
+int audpreproc_send_preproccmdqueue(void *cmd, unsigned len);
+typedef void (*audrec_event_func)(void *private, unsigned id, uint16_t *msg);
+int audrectask_enable(unsigned enc_type, audrec_event_func func, void *private);
+void audrectask_disable(unsigned enc_type, void *private);
+
+int audrectask_send_cmdqueue(void *cmd, unsigned len);
+int audrectask_send_bitstreamqueue(void *cmd, unsigned len);
+
#endif /* QDSP5AUDPREPROC_H */
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreproccmdi.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreproccmdi.h
index 8efc916..a38d224 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreproccmdi.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreproccmdi.h
@@ -2,30 +2,30 @@
#define QDSP5AUDPREPROCCMDI_H
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
-
- A U D I O P R E P R O C E S S I N G I N T E R N A L C O M M A N D S
-
-GENERAL DESCRIPTION
- This file contains defintions of format blocks of commands
- that are accepted by AUDPREPROC Task
-
-REFERENCES
- None
-
-EXTERNALIZED FUNCTIONS
- None
-
-Copyright (c) 1992-2009, Code Aurora Forum. All rights reserved.
-
-This software is licensed under the terms of the GNU General Public
-License version 2, as published by the Free Software Foundation, and
-may be copied, distributed, and modified under those terms.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
+*
+* A U D I O P R E P R O C E S S I N G I N T E R N A L C O M M A N D S
+*
+* GENERAL DESCRIPTION
+* This file contains defintions of format blocks of commands
+* that are accepted by AUDPREPROC Task
+*
+* REFERENCES
+* None
+*
+* EXTERNALIZED FUNCTIONS
+* None
+*
+* Copyright (c) 1992-2009, 2012 Code Aurora Forum. All rights reserved.
+*
+* This software is licensed under the terms of the GNU General Public
+* License version 2, as published by the Free Software Foundation, and
+* may be copied, distributed, and modified under those terms.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
/*===========================================================================
@@ -84,29 +84,29 @@
typedef struct {
unsigned short cmd_id;
unsigned short tx_agc_param_mask;
- unsigned short tx_agc_enable_flag;
- unsigned short static_gain;
- signed short adaptive_gain_flag;
- unsigned short expander_th;
- unsigned short expander_slope;
- unsigned short compressor_th;
- unsigned short compressor_slope;
- unsigned short param_mask;
- unsigned short aig_attackk;
- unsigned short aig_leak_down;
- unsigned short aig_leak_up;
- unsigned short aig_max;
- unsigned short aig_min;
- unsigned short aig_releasek;
- unsigned short aig_leakrate_fast;
- unsigned short aig_leakrate_slow;
- unsigned short attackk_msw;
- unsigned short attackk_lsw;
- unsigned short delay;
- unsigned short releasek_msw;
- unsigned short releasek_lsw;
- unsigned short rms_tav;
-} __attribute__((packed)) audpreproc_cmd_cfg_agc_params;
+ signed short tx_agc_enable_flag;
+ unsigned short comp_rlink_static_gain;
+ signed short comp_rlink_aig_flag;
+ unsigned short expander_rlink_th;
+ unsigned short expander_rlink_slope;
+ unsigned short compressor_rlink_th;
+ unsigned short compressor_rlink_slope;
+ unsigned short tx_adc_agc_param_mask;
+ unsigned short comp_rlink_aig_attackk;
+ unsigned short comp_rlink_aig_leak_down;
+ unsigned short comp_rlink_aig_leak_up;
+ unsigned short comp_rlink_aig_max;
+ unsigned short comp_rlink_aig_min;
+ unsigned short comp_rlink_aig_releasek;
+ unsigned short comp_rlink_aig_leakrate_fast;
+ unsigned short comp_rlink_aig_leakrate_slow;
+ unsigned short comp_rlink_attackk_msw;
+ unsigned short comp_rlink_attackk_lsw;
+ unsigned short comp_rlink_delay;
+ unsigned short comp_rlink_releasek_msw;
+ unsigned short comp_rlink_releasek_lsw;
+ unsigned short comp_rlink_rms_tav;
+} __packed audpreproc_cmd_cfg_agc_params;
/*
@@ -253,4 +253,16 @@
unsigned short channel_selected3;
} __attribute__((packed))audpreproc_cmd_cfg_iir_tuning_filter_params;
+#define AUDPREPROC_CMD_FEAT_QUERY_PARAMS 0x0004
+
+struct rtc_audpreproc_read_data {
+ unsigned short cmd_id;
+ unsigned short stream_id;
+ unsigned short feature_id;
+ unsigned short extbufsizemsw;
+ unsigned short extbufsizelsw;
+ unsigned short extpart;
+ unsigned short extbufstartmsw;
+ unsigned short extbufstartlsw;
+} __packed ;
#endif
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreprocmsg.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreprocmsg.h
index 0696066..d299995 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreprocmsg.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreprocmsg.h
@@ -2,30 +2,30 @@
#define QDSP5AUDPREPROCMSG_H
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
-
- A U D I O P R E P R O C E S S I N G M E S S A G E S
-
-GENERAL DESCRIPTION
- This file contains defintions of format blocks of messages
- that are rcvd by AUDPREPROC Task
-
-REFERENCES
- None
-
-EXTERNALIZED FUNCTIONS
- None
-
-Copyright (c) 1992-2009, Code Aurora Forum. All rights reserved.
-
-This software is licensed under the terms of the GNU General Public
-License version 2, as published by the Free Software Foundation, and
-may be copied, distributed, and modified under those terms.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
+*
+* A U D I O P R E P R O C E S S I N G M E S S A G E S
+*
+* GENERAL DESCRIPTION
+* This file contains defintions of format blocks of messages
+* that are rcvd by AUDPREPROC Task
+*
+* REFERENCES
+* None
+*
+* EXTERNALIZED FUNCTIONS
+* None
+*
+* Copyright (c) 1992-2009, 2012 Code Aurora Forum. All rights reserved.
+*
+* This software is licensed under the terms of the GNU General Public
+* License version 2, as published by the Free Software Foundation, and
+* may be copied, distributed, and modified under those terms.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
/*===========================================================================
@@ -82,4 +82,5 @@
unsigned short err_index;
} __attribute__((packed)) audpreproc_msg_error_msg_id;
+#define AUDPREPROC_MSG_FEAT_QUERY_DM_DONE 0x0003
#endif
diff --git a/arch/arm/mach-msm/qdsp5/Makefile b/arch/arm/mach-msm/qdsp5/Makefile
index a857159..f4fe052 100644
--- a/arch/arm/mach-msm/qdsp5/Makefile
+++ b/arch/arm/mach-msm/qdsp5/Makefile
@@ -14,7 +14,7 @@
obj-y += audio_out.o audio_mp3.o audmgr.o audpp.o audrec.o audpreproc.o
obj-y += audio_evrc.o audio_qcelp.o audio_amrnb.o audio_aac.o audio_amrnb_in.o
obj-y += audio_wma.o audio_voicememo.o audio_pcm.o audio_amrwb.o audio_wmapro.o
-obj-y += snd.o snd_cad.o snd_adie.o
+obj-y += snd.o snd_cad.o snd_adie.o audio_acdb.o
obj-$(CONFIG_ARCH_MSM7X27A) += audio_fm.o
obj-$(CONFIG_ARCH_MSM7X27A) += audio_mvs.o
obj-$(CONFIG_ARCH_MSM7X27A) += audio_lpa.o audio_ac3.o
diff --git a/arch/arm/mach-msm/qdsp5/audio_aac.c b/arch/arm/mach-msm/qdsp5/audio_aac.c
index 15e0590..01e529f 100644
--- a/arch/arm/mach-msm/qdsp5/audio_aac.c
+++ b/arch/arm/mach-msm/qdsp5/audio_aac.c
@@ -41,6 +41,7 @@
#include <mach/iommu_domains.h>
#include <mach/qdsp5/qdsp5audppcmdi.h>
#include <mach/qdsp5/qdsp5audppmsg.h>
+#include <mach/qdsp5/qdsp5audpp.h>
#include <mach/qdsp5/qdsp5audplaycmdi.h>
#include <mach/qdsp5/qdsp5audplaymsg.h>
#include <mach/qdsp5/qdsp5rmtcmdi.h>
diff --git a/arch/arm/mach-msm/qdsp5/audio_aac_in.c b/arch/arm/mach-msm/qdsp5/audio_aac_in.c
index 99e10a4..4a35939 100644
--- a/arch/arm/mach-msm/qdsp5/audio_aac_in.c
+++ b/arch/arm/mach-msm/qdsp5/audio_aac_in.c
@@ -109,7 +109,6 @@
int out_frame_cnt;
struct msm_adsp_module *audrec;
- struct msm_adsp_module *audpre;
/* configuration to use on next enable */
@@ -150,6 +149,8 @@
struct ion_client *client;
struct ion_handle *input_buff_handle;
struct ion_handle *output_buff_handle;
+
+ struct audrec_session_info session_info; /*audrec session info*/
};
struct audio_frame {
@@ -273,6 +274,31 @@
return temp;
}
+/* ------------------- dsp --------------------- */
+static void audpre_dsp_event(void *data, unsigned id, void *event_data)
+{
+
+ uint16_t *msg = event_data;
+
+ if (!msg)
+ return;
+
+ switch (id) {
+ case AUDPREPROC_MSG_CMD_CFG_DONE_MSG:
+ MM_DBG("type %d, status_flag %d\n",\
+ msg[0], msg[1]);
+ break;
+ case AUDPREPROC_MSG_ERROR_MSG_ID:
+ MM_INFO("err_index %d\n", msg[0]);
+ break;
+ case ADSP_MESSAGE_ID:
+ MM_DBG("Received ADSP event: module enable(audpreproctask)\n");
+ break;
+ default:
+ MM_ERR("unknown event %d\n", id);
+ }
+}
+
/* must be called with audio->lock held */
static int audaac_in_enable(struct audio_aac_in *audio)
{
@@ -293,16 +319,24 @@
if (rc < 0)
return rc;
- if (msm_adsp_enable(audio->audpre)) {
+ if (audpreproc_enable(audio->enc_id,
+ &audpre_dsp_event, audio)) {
+ MM_ERR("msm_adsp_enable(audpreproc) failed\n");
audmgr_disable(&audio->audmgr);
- MM_ERR("msm_adsp_enable(audpre) failed\n");
return -ENODEV;
}
+
+ /*update aurec session info in audpreproc layer*/
+ audio->session_info.session_id = audio->enc_id;
+ audio->session_info.sampling_freq =
+ convert_samp_index(audio->samp_rate);
+ audpreproc_update_audrec_info(&audio->session_info);
}
+
if (msm_adsp_enable(audio->audrec)) {
if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) {
+ audpreproc_disable(audio->enc_id, audio);
audmgr_disable(&audio->audmgr);
- msm_adsp_disable(audio->audpre);
}
MM_ERR("msm_adsp_enable(audrec) failed\n");
return -ENODEV;
@@ -328,36 +362,17 @@
wake_up(&audio->wait);
msm_adsp_disable(audio->audrec);
if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) {
- msm_adsp_disable(audio->audpre);
+ audpreproc_disable(audio->enc_id, audio);
+ /*reset the sampling frequency information at
+ audpreproc layer*/
+ audio->session_info.sampling_freq = 0;
+ audpreproc_update_audrec_info(&audio->session_info);
audmgr_disable(&audio->audmgr);
}
}
return 0;
}
-/* ------------------- dsp --------------------- */
-static void audpre_dsp_event(void *data, unsigned id, size_t len,
- void (*getevent)(void *ptr, size_t len))
-{
- uint16_t msg[2];
- getevent(msg, sizeof(msg));
-
- switch (id) {
- case AUDPREPROC_MSG_CMD_CFG_DONE_MSG:
- MM_DBG("type %d, status_flag %d\n", msg[0], msg[1]);
- break;
- case AUDPREPROC_MSG_ERROR_MSG_ID:
- MM_ERR("err_index %d\n", msg[0]);
- break;
- case ADSP_MESSAGE_ID:
- MM_DBG("Received ADSP event: module enable(audpreproctask)\n");
- break;
- default:
- MM_ERR("unknown event %d\n", id);
- }
-}
-
-
static void audaac_in_get_dsp_frames(struct audio_aac_in *audio)
{
struct audio_frame *frame;
@@ -596,11 +611,7 @@
}
}
-struct msm_adsp_ops audpre_aac_adsp_ops = {
- .event = audpre_dsp_event,
-};
-
-struct msm_adsp_ops audrec_aac_adsp_ops = {
+static struct msm_adsp_ops audrec_aac_adsp_ops = {
.event = audrec_dsp_event,
};
@@ -1241,12 +1252,9 @@
audaac_in_flush(audio);
msm_adsp_put(audio->audrec);
- if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL)
- msm_adsp_put(audio->audpre);
audpreproc_aenc_free(audio->enc_id);
audio->audrec = NULL;
- audio->audpre = NULL;
audio->opened = 0;
if ((audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) && \
@@ -1342,16 +1350,6 @@
goto done;
}
- if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) {
- rc = msm_adsp_get("AUDPREPROCTASK", &audio->audpre,
- &audpre_aac_adsp_ops, audio);
- if (rc) {
- msm_adsp_put(audio->audrec);
- audpreproc_aenc_free(audio->enc_id);
- goto done;
- }
- }
-
audio->dsp_cnt = 0;
audio->stopped = 0;
audio->wflush = 0;
@@ -1493,8 +1491,6 @@
ion_client_destroy(client);
client_create_error:
msm_adsp_put(audio->audrec);
- if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL)
- msm_adsp_put(audio->audpre);
audpreproc_aenc_free(audio->enc_id);
mutex_unlock(&audio->lock);
diff --git a/arch/arm/mach-msm/qdsp5/audio_ac3.c b/arch/arm/mach-msm/qdsp5/audio_ac3.c
index ee085c5..c0e2059 100644
--- a/arch/arm/mach-msm/qdsp5/audio_ac3.c
+++ b/arch/arm/mach-msm/qdsp5/audio_ac3.c
@@ -44,6 +44,7 @@
#include <mach/iommu_domains.h>
#include <mach/qdsp5/qdsp5audppcmdi.h>
#include <mach/qdsp5/qdsp5audppmsg.h>
+#include <mach/qdsp5/qdsp5audpp.h>
#include <mach/qdsp5/qdsp5audplaycmdi.h>
#include <mach/qdsp5/qdsp5audplaymsg.h>
#include <mach/qdsp5/qdsp5rmtcmdi.h>
diff --git a/arch/arm/mach-msm/qdsp5/audio_acdb.c b/arch/arm/mach-msm/qdsp5/audio_acdb.c
new file mode 100644
index 0000000..16f23f4
--- /dev/null
+++ b/arch/arm/mach-msm/qdsp5/audio_acdb.c
@@ -0,0 +1,2646 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/module.h>
+#include <linux/miscdevice.h>
+#include <linux/kthread.h>
+#include <linux/wait.h>
+#include <linux/mutex.h>
+#include <linux/io.h>
+#include <linux/android_pmem.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/uaccess.h>
+#include <linux/msm_audio.h>
+#include <linux/slab.h>
+#include <linux/debugfs.h>
+#include <linux/memory_alloc.h>
+#include <linux/mfd/marimba.h>
+#include <mach/dal.h>
+#include <mach/iommu.h>
+#include <mach/iommu_domains.h>
+#include <mach/socinfo.h>
+#include <mach/qdsp5/qdsp5audpp.h>
+#include <mach/qdsp5/qdsp5audpreproc.h>
+#include <mach/qdsp5/qdsp5audppcmdi.h>
+#include <mach/qdsp5/qdsp5audpreproccmdi.h>
+#include <mach/qdsp5/qdsp5audpreprocmsg.h>
+#include <mach/qdsp5/qdsp5audppmsg.h>
+#include <mach/qdsp5/audio_acdbi.h>
+#include <mach/qdsp5/acdb_commands.h>
+#include <mach/qdsp5/audio_acdb_def.h>
+#include <mach/debug_mm.h>
+#include <mach/msm_memtypes.h>
+
+#include "audmgr.h"
+
+/* this is the ACDB device ID */
+#define DALDEVICEID_ACDB 0x02000069
+#define ACDB_PORT_NAME "DAL00"
+#define ACDB_CPU SMD_APPS_MODEM
+#define ACDB_BUF_SIZE 4096
+#define FLUENCE_BUF_SIZE 498
+
+#define ACDB_VALUES_NOT_FILLED 0
+#define ACDB_VALUES_FILLED 1
+#define MAX_RETRY 10
+
+#define COMMON_OBJ_ID 6
+
+/*below macro is used to align the session info received from
+Devctl driver with the state mentioned as not to alter the
+Existing code*/
+#define AUDREC_OFFSET 2
+/* rpc table index */
+enum {
+ ACDB_DAL_IOCTL = DALDEVICE_FIRST_DEVICE_API_IDX
+};
+
+enum {
+ CAL_DATA_READY = 0x1,
+ AUDPP_READY = 0x2,
+ AUDREC_READY = 0x4,
+};
+
+struct acdb_data {
+ void *handle;
+
+ u32 phys_addr;
+ u8 *virt_addr;
+
+ struct task_struct *cb_thread_task;
+ struct device_info_callback dev_cb;
+
+ u32 acdb_state;
+ struct audpp_event_callback audpp_cb;
+ struct audpreproc_event_callback audpreproc_cb;
+ struct dev_evt_msg *device_info;
+
+ audpp_cmd_cfg_object_params_pcm *pp_iir;
+ audpp_cmd_cfg_object_params_mbadrc *pp_mbadrc;
+ audpreproc_cmd_cfg_agc_params *preproc_agc;
+ audpreproc_cmd_cfg_iir_tuning_filter_params *preproc_iir;
+ audpreproc_cmd_cfg_ns_params *preproc_ns;
+ struct acdb_mbadrc_block mbadrc_block;
+
+ wait_queue_head_t wait;
+ struct mutex acdb_mutex;
+ u32 device_cb_compl;
+ u32 audpp_cb_compl;
+ u32 preproc_cb_compl;
+ u8 preproc_stream_id;
+ u8 audrec_applied;
+ u32 multiple_sessions;
+ u32 cur_tx_session;
+ struct acdb_result acdb_result;
+
+ spinlock_t dsp_lock;
+ int dec_id;
+ audpp_cmd_cfg_object_params_eqalizer eq;
+ struct audrec_session_info session_info;
+ /*pmem info*/
+ int pmem_fd;
+ unsigned long paddr;
+ unsigned long kvaddr;
+ unsigned long pmem_len;
+ struct file *file;
+ /* pmem for get acdb blk */
+ unsigned long get_blk_paddr;
+ u8 *get_blk_kvaddr;
+ void *map_v_get_blk;
+};
+
+static struct acdb_data acdb_data;
+
+struct acdb_cache_node {
+ u32 node_status;
+ s32 stream_id;
+ u32 phys_addr_acdb_values;
+ void *map_v_addr;
+ u8 *virt_addr_acdb_values;
+ struct dev_evt_msg device_info;
+};
+
+struct acdb_cache_node acdb_cache_rx;
+
+/*for TX devices acdb values are applied based on AUDREC session and
+the depth of the tx cache is define by number of AUDREC sessions supported*/
+struct acdb_cache_node acdb_cache_tx;
+
+/*Audrec session info includes Attributes Sampling frequency and enc_id */
+struct audrec_session_info session_info;
+#ifdef CONFIG_DEBUG_FS
+
+#define RTC_MAX_TIMEOUT 500 /* 500 ms */
+#define PMEM_RTC_ACDB_QUERY_MEM 4096
+#define EXTRACT_HIGH_WORD(x) ((x & 0xFFFF0000)>>16)
+#define EXTRACT_LOW_WORD(x) (0x0000FFFF & x)
+#define ACDB_RTC_TX 0xF1
+#define ACDB_RTC_RX 0x1F
+
+
+static u32 acdb_audpp_entry[][4] = {
+
+ {
+ ABID_AUDIO_RTC_VOLUME_PAN_RX,\
+ IID_AUDIO_RTC_VOLUME_PAN_PARAMETERS,\
+ AUDPP_CMD_VOLUME_PAN,\
+ ACDB_RTC_RX
+ },
+ {
+ ABID_AUDIO_IIR_RX,\
+ IID_AUDIO_IIR_COEFF,\
+ AUDPP_CMD_IIR_TUNING_FILTER,
+ ACDB_RTC_RX
+ },
+ {
+ ABID_AUDIO_RTC_EQUALIZER_PARAMETERS,\
+ IID_AUDIO_RTC_EQUALIZER_PARAMETERS,\
+ AUDPP_CMD_EQUALIZER,\
+ ACDB_RTC_RX
+ },
+ {
+ ABID_AUDIO_RTC_SPA,\
+ IID_AUDIO_RTC_SPA_PARAMETERS,\
+ AUDPP_CMD_SPECTROGRAM,
+ ACDB_RTC_RX
+ },
+ {
+ ABID_AUDIO_STF_RX,\
+ IID_AUDIO_IIR_COEFF,\
+ AUDPP_CMD_SIDECHAIN_TUNING_FILTER,\
+ ACDB_RTC_RX
+ },
+ {
+ ABID_AUDIO_MBADRC_RX,\
+ IID_AUDIO_RTC_MBADRC_PARAMETERS,\
+ AUDPP_CMD_MBADRC,\
+ ACDB_RTC_RX
+ },
+ {
+ ABID_AUDIO_AGC_TX,\
+ IID_AUDIO_AGC_PARAMETERS,\
+ AUDPREPROC_CMD_CFG_AGC_PARAMS,\
+ ACDB_RTC_TX
+ },
+ {
+ ABID_AUDIO_AGC_TX,\
+ IID_AUDIO_RTC_AGC_PARAMETERS,\
+ AUDPREPROC_CMD_CFG_AGC_PARAMS,\
+ ACDB_RTC_TX
+ },
+ {
+ ABID_AUDIO_NS_TX,\
+ IID_NS_PARAMETERS,\
+ AUDPREPROC_CMD_CFG_NS_PARAMS,\
+ ACDB_RTC_TX
+ },
+ {
+ ABID_AUDIO_IIR_TX,\
+ IID_AUDIO_RTC_TX_IIR_COEFF,\
+ AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS,\
+ ACDB_RTC_TX
+ },
+ {
+ ABID_AUDIO_IIR_TX,\
+ IID_AUDIO_IIR_COEFF,\
+ AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS,\
+ ACDB_RTC_TX
+ }
+ /*Any new entries should be added here*/
+};
+
+static struct dentry *get_set_abid_dentry;
+static struct dentry *get_set_abid_data_dentry;
+
+struct rtc_acdb_pmem {
+ u8 *viraddr;
+ int32_t phys;
+ void *map_v_rtc;
+};
+
+struct rtc_acdb_data {
+ u32 acdb_id;
+ u32 cmd_id;
+ u32 set_abid;
+ u32 set_iid;
+ u32 abid;
+ u32 err;
+ bool valid_abid;
+ u32 tx_rx_ctl;
+ struct rtc_acdb_pmem rtc_read;
+ struct rtc_acdb_pmem rtc_write;
+ wait_queue_head_t wait;
+};
+
+struct get_abid {
+ u32 cmd_id;
+ u32 acdb_id;
+ u32 set_abid;
+ u32 set_iid;
+};
+
+struct acdb_block_mbadrc_rtc {
+ u16 enable;
+ u16 num_bands;
+ u16 down_samp_level;
+ u16 adrc_delay;
+ u16 ext_buf_size;
+ u16 ext_partition;
+ u16 ext_buf_msw;
+ u16 ext_buf_lsw;
+ struct adrc_config adrc_band[AUDPP_MAX_MBADRC_BANDS];
+ signed int ext_buff[196];
+} __packed;
+
+enum {
+ ACDB_RTC_SUCCESS,
+ ACDB_RTC_ERR_INVALID_DEVICE,
+ ACDB_RTC_ERR_DEVICE_INACTIVE,
+ ACDB_RTC_ERR_INVALID_ABID,
+ ACDB_RTC_DSP_FAILURE,
+ ACDB_RTC_DSP_FEATURE_NOT_AVAILABLE,
+ ACDB_RTC_ERR_INVALID_LEN,
+ ACDB_RTC_ERR_UNKNOWN_FAILURE,
+ ACDB_RTC_PENDING_RESPONSE,
+ ACDB_RTC_INIT_FAILURE,
+};
+
+static struct rtc_acdb_data rtc_acdb;
+
+static int rtc_getsetabid_dbg_open(struct inode *inode, struct file *file)
+{
+ file->private_data = inode->i_private;
+ MM_DBG("GET-SET ABID Open debug intf %s\n",\
+ (char *) file->private_data);
+ return 0;
+}
+
+static bool get_feature_id(u32 set_abid, u32 iid, unsigned short *feature_id)
+{
+ bool ret_value = false;
+ int i = 0;
+
+ for (; i < (sizeof(acdb_audpp_entry) / sizeof(acdb_audpp_entry[0]));\
+ i++) {
+ if (acdb_audpp_entry[i][0] == set_abid &&
+ acdb_audpp_entry[i][1] == iid) {
+ *feature_id = acdb_audpp_entry[i][2];
+ rtc_acdb.tx_rx_ctl = acdb_audpp_entry[i][3];
+ ret_value = true;
+ break;
+ }
+ }
+ return ret_value;
+}
+static ssize_t rtc_getsetabid_dbg_write(struct file *filp,
+ const char __user *ubuf,
+ size_t cnt, loff_t *ppos)
+{
+ struct get_abid write_abid;
+ unsigned short feat_id = 0;
+ rtc_acdb.valid_abid = false;
+
+ if (copy_from_user(&write_abid, \
+ (void *)ubuf, sizeof(struct get_abid))) {
+ MM_ERR("ACDB DATA WRITE - INVALID READ LEN\n");
+ rtc_acdb.err = ACDB_RTC_ERR_INVALID_LEN;
+ return cnt;
+ }
+ MM_DBG("SET ABID : Cmd ID: %d Device:%d ABID:%d IID : %d cnt: %d\n",\
+ write_abid.cmd_id, write_abid.acdb_id,\
+ write_abid.set_abid, write_abid.set_iid, cnt);
+ if (write_abid.acdb_id > ACDB_ID_MAX ||
+ write_abid.acdb_id < ACDB_ID_HANDSET_SPKR){
+ rtc_acdb.err = ACDB_RTC_ERR_INVALID_DEVICE;
+ return cnt;
+ }
+
+ rtc_acdb.err = ACDB_RTC_ERR_INVALID_ABID;
+ rtc_acdb.abid = write_abid.set_abid;
+ if (get_feature_id(write_abid.set_abid, \
+ write_abid.set_iid, &feat_id)) {
+ rtc_acdb.err = ACDB_RTC_SUCCESS;
+ rtc_acdb.cmd_id = write_abid.cmd_id;
+ rtc_acdb.acdb_id = write_abid.acdb_id;
+ rtc_acdb.set_abid = feat_id;
+ rtc_acdb.valid_abid = true;
+ rtc_acdb.set_iid = write_abid.set_iid;
+ }
+ return cnt;
+}
+static ssize_t rtc_getsetabid_dbg_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ static char buffer[1024];
+ int n = 0;
+ u32 msg = rtc_acdb.err;
+ memcpy(buffer, &rtc_acdb.cmd_id, sizeof(struct get_abid));
+ memcpy(buffer+16, &msg, 4);
+ n = 20;
+ MM_INFO("SET ABID : Cmd ID: %x Device:%x ABID:%x IID : %x Err: %d\n",\
+ rtc_acdb.cmd_id, rtc_acdb.acdb_id, rtc_acdb.set_abid,\
+ rtc_acdb.set_iid, rtc_acdb.err);
+ return simple_read_from_buffer(buf, count, ppos, buffer, n);
+}
+
+static int rtc_getsetabid_data_dbg_open(struct inode *inode, struct file *file)
+{
+ file->private_data = inode->i_private;
+ MM_INFO("GET-SET ABID DATA Open debug intf %s\n",
+ (char *) file->private_data);
+ return 0;
+}
+
+void acdb_rtc_set_err(u32 err_code)
+{
+ if (rtc_acdb.err == ACDB_RTC_PENDING_RESPONSE) {
+ if (err_code == 0xFFFF) {
+ rtc_acdb.err = ACDB_RTC_SUCCESS;
+ MM_INFO("RTC READ SUCCESS---\n");
+ } else if (err_code == 0) {
+ rtc_acdb.err = ACDB_RTC_DSP_FAILURE;
+ MM_INFO("RTC READ FAIL---\n");
+ } else if (err_code == 1) {
+ rtc_acdb.err = ACDB_RTC_DSP_FEATURE_NOT_AVAILABLE;
+ MM_INFO("RTC READ FEAT UNAVAILABLE---\n");
+ } else {
+ rtc_acdb.err = ACDB_RTC_DSP_FAILURE;
+ MM_INFO("RTC Err CODE---\n");
+ }
+ } else {
+ rtc_acdb.err = ACDB_RTC_DSP_FAILURE;
+ MM_ERR("RTC Err code Invalid State\n");
+ }
+ wake_up(&rtc_acdb.wait);
+}
+
+static ssize_t rtc_getsetabid_data_dbg_read(struct file *file,
+ char __user *buf, size_t count,
+ loff_t *ppos)
+{
+ static char buffer[PMEM_RTC_ACDB_QUERY_MEM];
+ int rc, n = 0;
+ int counter = 0;
+ struct rtc_acdb_pmem *rtc_read = &rtc_acdb.rtc_read;
+ memset(&buffer, 0, PMEM_RTC_ACDB_QUERY_MEM);
+
+ if (rtc_acdb.valid_abid != true) {
+ MM_ERR("ACDB DATA READ ---INVALID ABID\n");
+ n = 0;
+ rtc_acdb.err = ACDB_RTC_ERR_INVALID_ABID;
+ } else {
+ if (PMEM_RTC_ACDB_QUERY_MEM < count) {
+ MM_ERR("ACDB DATA READ ---"\
+ "INVALID READ LEN %x\n", count);
+ n = 0;
+ rtc_acdb.err = ACDB_RTC_ERR_INVALID_LEN;
+ } else {
+ rtc_acdb.err = ACDB_RTC_PENDING_RESPONSE;
+ if (rtc_read->viraddr != NULL) {
+ memset(rtc_read->viraddr,
+ 0, PMEM_RTC_ACDB_QUERY_MEM);
+ }
+ if (rtc_acdb.tx_rx_ctl == ACDB_RTC_RX) {
+ struct rtc_audpp_read_data rtc_read_cmd;
+ rtc_read_cmd.cmd_id =
+ AUDPP_CMD_PP_FEAT_QUERY_PARAMS;
+ rtc_read_cmd.obj_id =
+ AUDPP_CMD_COPP_STREAM;
+ rtc_read_cmd.feature_id = rtc_acdb.set_abid;
+ rtc_read_cmd.extbufsizemsw =
+ EXTRACT_HIGH_WORD(\
+ PMEM_RTC_ACDB_QUERY_MEM);
+ rtc_read_cmd.extbufsizelsw =
+ EXTRACT_LOW_WORD(\
+ PMEM_RTC_ACDB_QUERY_MEM);
+ rtc_read_cmd.extpart = 0x0000;
+ rtc_read_cmd.extbufstartmsw =
+ EXTRACT_HIGH_WORD(rtc_read->phys);
+ rtc_read_cmd.extbufstartlsw =
+ EXTRACT_LOW_WORD(rtc_read->phys);
+ rc = audpp_send_queue2(&rtc_read_cmd,
+ sizeof(rtc_read_cmd));
+ } else if (rtc_acdb.tx_rx_ctl == ACDB_RTC_TX) {
+ struct rtc_audpreproc_read_data rtc_audpreproc;
+ rtc_audpreproc.cmd_id =
+ AUDPREPROC_CMD_FEAT_QUERY_PARAMS;
+ rtc_audpreproc.feature_id = rtc_acdb.set_abid;
+ /*AUDREC1 is used for pcm recording */
+ rtc_audpreproc.stream_id = 1;
+ rtc_audpreproc.extbufsizemsw =
+ EXTRACT_HIGH_WORD(\
+ PMEM_RTC_ACDB_QUERY_MEM);
+ rtc_audpreproc.extbufsizelsw =
+ EXTRACT_LOW_WORD(\
+ PMEM_RTC_ACDB_QUERY_MEM);
+ rtc_audpreproc.extpart = 0x0000;
+ rtc_audpreproc.extbufstartmsw =
+ EXTRACT_HIGH_WORD(rtc_read->phys);
+ rtc_audpreproc.extbufstartlsw =
+ EXTRACT_LOW_WORD(rtc_read->phys);
+ rc = audpreproc_send_preproccmdqueue(
+ &rtc_audpreproc,\
+ sizeof(rtc_audpreproc));
+ MM_INFO("ACDB READ Command RC --->%x,"\
+ "stream_id %x\n", rc,
+ acdb_data.preproc_stream_id);
+ }
+ rc = wait_event_timeout(rtc_acdb.wait,
+ (rtc_acdb.err !=
+ ACDB_RTC_PENDING_RESPONSE),
+ msecs_to_jiffies(RTC_MAX_TIMEOUT));
+ MM_INFO("ACDB READ ACK Count = %x Err = %x\n",
+ count, rtc_acdb.err);
+ {
+ if (rtc_acdb.err == ACDB_RTC_SUCCESS
+ && rtc_read->viraddr != NULL) {
+ memcpy(buffer, rtc_read->viraddr, count);
+ n = count;
+ while (counter < count) {
+ MM_DBG("%x", \
+ rtc_read->viraddr[counter]);
+ counter++;
+ }
+ }
+ }
+ }
+ }
+ return simple_read_from_buffer(buf, count, ppos, buffer, n);
+}
+
+static bool acdb_set_tx_rtc(const char *ubuf, size_t writecount)
+{
+ audpreproc_cmd_cfg_iir_tuning_filter_params *preproc_iir;
+ audpreproc_cmd_cfg_agc_params *preproc_agc;
+ audpreproc_cmd_cfg_ns_params *preproc_ns;
+ s32 result = 0;
+ bool retval = false;
+ unsigned short iircmdsize =
+ sizeof(audpreproc_cmd_cfg_iir_tuning_filter_params);
+ unsigned short iircmdid = AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS;
+
+ rtc_acdb.err = ACDB_RTC_ERR_UNKNOWN_FAILURE;
+
+ switch (rtc_acdb.set_abid) {
+
+ case AUDPREPROC_CMD_CFG_AGC_PARAMS:
+ {
+ preproc_agc = kmalloc(sizeof(\
+ audpreproc_cmd_cfg_agc_params),\
+ GFP_KERNEL);
+ if ((sizeof(audpreproc_cmd_cfg_agc_params) -\
+ (sizeof(unsigned short)))
+ < writecount) {
+ MM_ERR("ACDB DATA WRITE --"\
+ "AGC TX writecount > DSP struct\n");
+ } else {
+ if (preproc_agc != NULL) {
+ char *base; unsigned short offset;
+ unsigned short *offset_addr;
+ base = (char *)preproc_agc;
+ offset = offsetof(\
+ audpreproc_cmd_cfg_agc_params,\
+ tx_agc_param_mask);
+ offset_addr = (unsigned short *)(base + offset);
+ if ((copy_from_user(offset_addr,\
+ (void *)ubuf, writecount)) == 0x00) {
+ preproc_agc->cmd_id =
+ AUDPREPROC_CMD_CFG_AGC_PARAMS;
+
+ result = audpreproc_dsp_set_agc(
+ preproc_agc,
+ sizeof(\
+ audpreproc_cmd_cfg_agc_params));
+ if (result) {
+ MM_ERR("ACDB=> Failed to "\
+ "send AGC data to "\
+ "preproc)\n");
+ } else {
+ retval = true;
+ }
+ } else {
+ MM_ERR("ACDB DATA WRITE ---"\
+ "GC Tx copy_from_user Fail\n");
+ }
+ } else {
+ MM_ERR("ACDB DATA WRITE --"\
+ "AGC TX kalloc Failed LEN\n");
+ }
+ }
+ if (preproc_agc != NULL)
+ kfree(preproc_agc);
+ break;
+ }
+ case AUDPREPROC_CMD_CFG_NS_PARAMS:
+ {
+
+ preproc_ns = kmalloc(sizeof(\
+ audpreproc_cmd_cfg_ns_params),\
+ GFP_KERNEL);
+ if ((sizeof(audpreproc_cmd_cfg_ns_params) -\
+ (sizeof(unsigned short)))
+ < writecount) {
+ MM_ERR("ACDB DATA WRITE --"\
+ "NS TX writecount > DSP struct\n");
+ } else {
+ if (preproc_ns != NULL) {
+ char *base; unsigned short offset;
+ unsigned short *offset_addr;
+ base = (char *)preproc_ns;
+ offset = offsetof(\
+ audpreproc_cmd_cfg_ns_params,\
+ ec_mode_new);
+ offset_addr = (unsigned short *)(base + offset);
+ if ((copy_from_user(offset_addr,\
+ (void *)ubuf, writecount)) == 0x00) {
+ preproc_ns->cmd_id =
+ AUDPREPROC_CMD_CFG_NS_PARAMS;
+ result = audpreproc_dsp_set_ns(
+ preproc_ns,
+ sizeof(\
+ audpreproc_cmd_cfg_ns_params));
+ if (result) {
+ MM_ERR("ACDB=> Failed to send "\
+ "NS data to preproc\n");
+ } else {
+ retval = true;
+ }
+ } else {
+ MM_ERR("ACDB DATA WRITE ---NS Tx "\
+ "copy_from_user Fail\n");
+ }
+ } else {
+ MM_ERR("ACDB DATA WRITE --NS TX "\
+ "kalloc Failed LEN\n");
+ }
+ }
+ if (preproc_ns != NULL)
+ kfree(preproc_ns);
+ break;
+ }
+ case AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS:
+ {
+
+ preproc_iir = kmalloc(sizeof(\
+ audpreproc_cmd_cfg_iir_tuning_filter_params),\
+ GFP_KERNEL);
+ if ((sizeof(\
+ audpreproc_cmd_cfg_iir_tuning_filter_params)-\
+ (sizeof(unsigned short)))
+ < writecount) {
+ MM_ERR("ACDB DATA WRITE --IIR TX writecount "\
+ "> DSP struct\n");
+ } else {
+ if (preproc_iir != NULL) {
+ char *base; unsigned short offset;
+ unsigned short *offset_addr;
+ base = (char *)preproc_iir;
+ offset = offsetof(\
+ audpreproc_cmd_cfg_iir_tuning_filter_params,\
+ active_flag);
+ offset_addr = (unsigned short *)(base + \
+ offset);
+ if ((copy_from_user(offset_addr,\
+ (void *)ubuf, writecount)) == 0x00) {
+ preproc_iir->cmd_id = iircmdid;
+ result = audpreproc_dsp_set_iir(\
+ preproc_iir,
+ iircmdsize);
+ if (result) {
+ MM_ERR("ACDB=> Failed to send "\
+ "IIR data to preproc\n");
+ } else {
+ retval = true;
+ }
+ } else {
+ MM_ERR("ACDB DATA WRITE ---IIR Tx "\
+ "copy_from_user Fail\n");
+ }
+ } else {
+ MM_ERR("ACDB DATA WRITE --IIR TX kalloc "\
+ "Failed LEN\n");
+ }
+ }
+ if (preproc_iir != NULL)
+ kfree(preproc_iir);
+ break;
+ }
+ }
+ return retval;
+}
+
+static bool acdb_set_rx_rtc(const char *ubuf, size_t writecount)
+{
+
+ audpp_cmd_cfg_object_params_volume *volpan_config;
+ audpp_cmd_cfg_object_params_mbadrc *mbadrc_config;
+ struct acdb_block_mbadrc_rtc *acdb_mbadrc_rtc;
+ audpp_cmd_cfg_object_params_eqalizer *eq_config;
+ audpp_cmd_cfg_object_params_pcm *iir_config;
+ struct rtc_acdb_pmem *rtc_write = &rtc_acdb.rtc_write;
+ s32 result = 0;
+ bool retval = false;
+
+ switch (rtc_acdb.set_abid) {
+ case AUDPP_CMD_VOLUME_PAN:
+ {
+ volpan_config = kmalloc(sizeof(\
+ audpp_cmd_cfg_object_params_volume),\
+ GFP_KERNEL);
+ if ((sizeof(audpp_cmd_cfg_object_params_volume) -\
+ sizeof(audpp_cmd_cfg_object_params_common))
+ < writecount) {
+ MM_ERR("ACDB DATA WRITE -- "\
+ "VolPan writecount > DSP struct\n");
+ } else {
+ if (volpan_config != NULL) {
+ char *base; unsigned short offset;
+ unsigned short *offset_addr;
+ base = (char *)volpan_config;
+ offset = offsetof(\
+ audpp_cmd_cfg_object_params_volume,\
+ volume);
+ offset_addr = (unsigned short *)(base+offset);
+ if ((copy_from_user(offset_addr,\
+ (void *)ubuf, writecount)) == 0x00) {
+ MM_ERR("ACDB RX WRITE DATA: "\
+ "AUDPP_CMD_VOLUME_PAN\n");
+ result = audpp_set_volume_and_pan(
+ COMMON_OBJ_ID,
+ volpan_config->volume,
+ volpan_config->pan);
+ if (result) {
+ MM_ERR("ACDB=> Failed to "\
+ "send VOLPAN data to"
+ " postproc\n");
+ } else {
+ retval = true;
+ }
+ } else {
+ MM_ERR("ACDB DATA WRITE ---"\
+ "copy_from_user Fail\n");
+ }
+ } else {
+ MM_ERR("ACDB DATA WRITE --"\
+ "Vol Pan kalloc Failed LEN\n");
+ }
+ }
+ if (volpan_config != NULL)
+ kfree(volpan_config);
+ break;
+ }
+
+ case AUDPP_CMD_IIR_TUNING_FILTER:
+ {
+ iir_config = kmalloc(sizeof(\
+ audpp_cmd_cfg_object_params_pcm),\
+ GFP_KERNEL);
+ if ((sizeof(audpp_cmd_cfg_object_params_pcm) -\
+ sizeof(audpp_cmd_cfg_object_params_common))
+ < writecount) {
+ MM_ERR("ACDB DATA WRITE --"\
+ "IIR RX writecount > DSP struct\n");
+ } else {
+ if (iir_config != NULL) {
+ char *base; unsigned short offset;
+ unsigned short *offset_addr;
+ base = (char *)iir_config;
+ offset = offsetof(\
+ audpp_cmd_cfg_object_params_pcm,\
+ active_flag);
+ offset_addr = (unsigned short *)(base+offset);
+ if ((copy_from_user(offset_addr,\
+ (void *)ubuf, writecount)) == 0x00) {
+ MM_ERR("ACDB RX WRITE DATA:"\
+ "AUDPP_CMD_IIR_TUNING_FILTER\n");
+ result = audpp_dsp_set_rx_iir(
+ COMMON_OBJ_ID,
+ iir_config->active_flag,\
+ iir_config);
+ if (result) {
+ MM_ERR("ACDB=> Failed to send"\
+ "IIR data to"\
+ "postproc\n");
+ } else {
+ retval = true;
+ }
+ } else {
+ MM_ERR("ACDB DATA WRITE ---"\
+ "IIR Rx copy_from_user Fail\n");
+ }
+ } else {
+ MM_ERR("ACDB DATA WRITE --"\
+ "acdb_iir_block kalloc Failed LEN\n");
+ }
+ }
+ if (iir_config != NULL)
+ kfree(iir_config);
+ break;
+ }
+ case AUDPP_CMD_EQUALIZER:
+ {
+ eq_config = kmalloc(sizeof(\
+ audpp_cmd_cfg_object_params_eqalizer),\
+ GFP_KERNEL);
+ if ((sizeof(audpp_cmd_cfg_object_params_eqalizer) -\
+ sizeof(audpp_cmd_cfg_object_params_common))
+ < writecount) {
+ MM_ERR("ACDB DATA WRITE --"\
+ "EQ RX writecount > DSP struct\n");
+ } else {
+ if (eq_config != NULL) {
+ char *base; unsigned short offset;
+ unsigned short *offset_addr;
+ base = (char *)eq_config;
+ offset = offsetof(\
+ audpp_cmd_cfg_object_params_eqalizer,\
+ eq_flag);
+ offset_addr = (unsigned short *)(base+offset);
+ if ((copy_from_user(offset_addr,\
+ (void *)ubuf, writecount)) == 0x00) {
+ MM_ERR("ACDB RX WRITE"\
+ "DATA:AUDPP_CMD_EQUALIZER\n");
+ result = audpp_dsp_set_eq(
+ COMMON_OBJ_ID,
+ eq_config->eq_flag,\
+ eq_config);
+ if (result) {
+ MM_ERR("ACDB=> Failed to "\
+ "send EQ data to postproc\n");
+ } else {
+ retval = true;
+ }
+ } else {
+ MM_ERR("ACDB DATA WRITE ---"\
+ "EQ Rx copy_from_user Fail\n");
+ }
+ } else {
+ MM_ERR("ACDB DATA WRITE --"\
+ "EQ kalloc Failed LEN\n");
+ }
+ }
+ if (eq_config != NULL)
+ kfree(eq_config);
+ break;
+ }
+
+ case AUDPP_CMD_MBADRC:
+ {
+ acdb_mbadrc_rtc = kmalloc(sizeof(struct \
+ acdb_block_mbadrc_rtc),\
+ GFP_KERNEL);
+ mbadrc_config = kmalloc(sizeof(\
+ audpp_cmd_cfg_object_params_mbadrc),\
+ GFP_KERNEL);
+ if (mbadrc_config != NULL && acdb_mbadrc_rtc != NULL) {
+ if ((copy_from_user(acdb_mbadrc_rtc,\
+ (void *)ubuf,
+ sizeof(struct acdb_block_mbadrc_rtc)))
+ == 0x00) {
+
+ memset(mbadrc_config, 0,
+ sizeof(\
+ audpp_cmd_cfg_object_params_mbadrc));
+
+ mbadrc_config->enable =
+ acdb_mbadrc_rtc->enable;
+ mbadrc_config->num_bands =
+ acdb_mbadrc_rtc->num_bands;
+ mbadrc_config->down_samp_level =
+ acdb_mbadrc_rtc->down_samp_level;
+ mbadrc_config->adrc_delay =
+ acdb_mbadrc_rtc->adrc_delay;
+ memcpy(mbadrc_config->adrc_band,\
+ acdb_mbadrc_rtc->adrc_band,\
+ AUDPP_MAX_MBADRC_BANDS *\
+ sizeof(struct adrc_config));
+ if (mbadrc_config->num_bands > 1) {
+ mbadrc_config->ext_buf_size =
+ (97 * 2) + (33 * 2 * \
+ (mbadrc_config->num_bands - 2));
+ }
+ mbadrc_config->ext_partition = 0;
+ mbadrc_config->ext_buf_lsw =
+ (u16) EXTRACT_LOW_WORD(\
+ rtc_write->phys);
+ mbadrc_config->ext_buf_msw =
+ (u16) EXTRACT_HIGH_WORD(\
+ rtc_write->phys);
+ memcpy(rtc_write->viraddr,
+ acdb_mbadrc_rtc->ext_buff,
+ (196*sizeof(signed int)));
+ result = audpp_dsp_set_mbadrc(
+ COMMON_OBJ_ID,
+ mbadrc_config->enable,
+ mbadrc_config);
+ if (result) {
+ MM_ERR("ACDB=> Failed to "\
+ "Send MBADRC data "\
+ "to postproc\n");
+ } else {
+ retval = true;
+ }
+ } else {
+ MM_ERR("ACDB DATA WRITE ---"\
+ "MBADRC Rx copy_from_user Fail\n");
+ }
+ } else {
+ MM_ERR("ACDB DATA WRITE --MBADRC kalloc Failed LEN\n");
+ }
+ if (mbadrc_config != NULL)
+ kfree(mbadrc_config);
+ if (acdb_mbadrc_rtc != NULL)
+ kfree(acdb_mbadrc_rtc);
+ break;
+ }
+ }
+ return retval;
+}
+static ssize_t rtc_getsetabid_data_dbg_write(struct file *filp,
+ const char __user *ubuf,
+ size_t cnt, loff_t *ppos)
+{
+ if (rtc_acdb.valid_abid != true) {
+ MM_INFO("ACDB DATA READ ---INVALID ABID\n");
+ rtc_acdb.err = ACDB_RTC_ERR_INVALID_ABID;
+ } else {
+ if (rtc_acdb.tx_rx_ctl == ACDB_RTC_RX) {
+ if (acdb_set_rx_rtc(ubuf, cnt)) {
+ rtc_acdb.err = ACDB_RTC_SUCCESS;
+ } else {
+ rtc_acdb.err = ACDB_RTC_ERR_UNKNOWN_FAILURE;
+ cnt = 0;
+ }
+ } else if (rtc_acdb.tx_rx_ctl == ACDB_RTC_TX) {
+ if (acdb_set_tx_rtc(ubuf, cnt)) {
+ rtc_acdb.err = ACDB_RTC_SUCCESS;
+ } else {
+ rtc_acdb.err = ACDB_RTC_ERR_UNKNOWN_FAILURE;
+ cnt = 0;
+ }
+ }
+ }
+ return cnt;
+}
+
+
+static const struct file_operations rtc_acdb_data_debug_fops = {
+ .open = rtc_getsetabid_data_dbg_open,
+ .write = rtc_getsetabid_data_dbg_write,
+ .read = rtc_getsetabid_data_dbg_read
+};
+
+static const struct file_operations rtc_acdb_debug_fops = {
+ .open = rtc_getsetabid_dbg_open,
+ .write = rtc_getsetabid_dbg_write,
+ .read = rtc_getsetabid_dbg_read
+};
+
+static void rtc_acdb_deinit(void)
+{
+ struct rtc_acdb_pmem *rtc_read = &rtc_acdb.rtc_read;
+ struct rtc_acdb_pmem *rtc_write = &rtc_acdb.rtc_write;
+ if (get_set_abid_dentry) {
+ MM_DBG("GetSet ABID remove debugfs\n");
+ debugfs_remove(get_set_abid_dentry);
+ }
+
+ if (get_set_abid_data_dentry) {
+ MM_DBG("GetSet ABID remove debugfs\n");
+ debugfs_remove(get_set_abid_data_dentry);
+ }
+ rtc_acdb.abid = 0;
+ rtc_acdb.acdb_id = 0;
+ rtc_acdb.cmd_id = 0;
+ rtc_acdb.err = 1;
+ rtc_acdb.set_abid = 0;
+ rtc_acdb.set_iid = 0;
+ rtc_acdb.tx_rx_ctl = 0;
+ rtc_acdb.valid_abid = false;
+
+ if (rtc_read->viraddr != NULL || ((void *)rtc_read->phys) != NULL) {
+ iounmap(rtc_read->map_v_rtc);
+ free_contiguous_memory_by_paddr(rtc_read->phys);
+ }
+ if (rtc_write->viraddr != NULL || ((void *)rtc_write->phys) != NULL) {
+ iounmap(rtc_write->map_v_rtc);
+ free_contiguous_memory_by_paddr(rtc_write->phys);
+ }
+}
+
+static bool rtc_acdb_init(void)
+{
+ struct rtc_acdb_pmem *rtc_read = &rtc_acdb.rtc_read;
+ struct rtc_acdb_pmem *rtc_write = &rtc_acdb.rtc_write;
+ s32 result = 0;
+ char name[sizeof "get_set_abid"+1];
+ char name1[sizeof "get_set_abid_data"+1];
+ rtc_acdb.abid = 0;
+ rtc_acdb.acdb_id = 0;
+ rtc_acdb.cmd_id = 0;
+ rtc_acdb.err = 1;
+ rtc_acdb.set_abid = 0;
+ rtc_acdb.set_iid = 0;
+ rtc_acdb.valid_abid = false;
+ rtc_acdb.tx_rx_ctl = 0;
+
+ snprintf(name, sizeof name, "get_set_abid");
+ get_set_abid_dentry = debugfs_create_file(name,
+ S_IFREG | S_IRUGO | S_IWUGO,
+ NULL, NULL, &rtc_acdb_debug_fops);
+ if (IS_ERR(get_set_abid_dentry)) {
+ MM_ERR("SET GET ABID debugfs_create_file failed\n");
+ return false;
+ }
+
+ snprintf(name1, sizeof name1, "get_set_abid_data");
+ get_set_abid_data_dentry = debugfs_create_file(name1,
+ S_IFREG | S_IRUGO | S_IWUGO,
+ NULL, NULL,
+ &rtc_acdb_data_debug_fops);
+ if (IS_ERR(get_set_abid_data_dentry)) {
+ MM_ERR("SET GET ABID DATA"\
+ " debugfs_create_file failed\n");
+ return false;
+ }
+
+ rtc_read->phys = allocate_contiguous_ebi_nomap(PMEM_RTC_ACDB_QUERY_MEM,
+ SZ_4K);
+
+ if (!rtc_read->phys) {
+ MM_ERR("ACDB Cannot allocate physical memory\n");
+ result = -ENOMEM;
+ goto error;
+ }
+ rtc_read->map_v_rtc = ioremap(rtc_read->phys,
+ PMEM_RTC_ACDB_QUERY_MEM);
+
+ if (IS_ERR(rtc_read->map_v_rtc)) {
+ MM_ERR("ACDB Could not map physical address\n");
+ result = -ENOMEM;
+ goto error;
+ }
+ rtc_read->viraddr = rtc_read->map_v_rtc;
+ memset(rtc_read->viraddr, 0, PMEM_RTC_ACDB_QUERY_MEM);
+
+ rtc_write->phys = allocate_contiguous_ebi_nomap(PMEM_RTC_ACDB_QUERY_MEM,
+ SZ_4K);
+
+ if (!rtc_write->phys) {
+ MM_ERR("ACDB Cannot allocate physical memory\n");
+ result = -ENOMEM;
+ goto error;
+ }
+ rtc_write->map_v_rtc = ioremap(rtc_write->phys,
+ PMEM_RTC_ACDB_QUERY_MEM);
+
+ if (IS_ERR(rtc_write->map_v_rtc)) {
+ MM_ERR("ACDB Could not map physical address\n");
+ result = -ENOMEM;
+ goto error;
+ }
+ rtc_write->viraddr = rtc_write->map_v_rtc;
+ memset(rtc_write->viraddr, 0, PMEM_RTC_ACDB_QUERY_MEM);
+ init_waitqueue_head(&rtc_acdb.wait);
+ return true;
+error:
+ MM_DBG("INIT RTC FAILED REMOVING RTC DEBUG FS\n");
+ if (get_set_abid_dentry) {
+ MM_DBG("GetSet ABID remove debugfs\n");
+ debugfs_remove(get_set_abid_dentry);
+ }
+
+ if (get_set_abid_data_dentry) {
+ MM_DBG("GetSet ABID remove debugfs\n");
+ debugfs_remove(get_set_abid_data_dentry);
+ }
+ if (rtc_read->viraddr != NULL || ((void *)rtc_read->phys) != NULL) {
+ iounmap(rtc_read->map_v_rtc);
+ free_contiguous_memory_by_paddr(rtc_read->phys);
+ }
+ if (rtc_write->viraddr != NULL || ((void *)rtc_write->phys) != NULL) {
+ iounmap(rtc_write->map_v_rtc);
+ free_contiguous_memory_by_paddr(rtc_write->phys);
+ }
+ return false;
+}
+#else
+void acdb_rtc_set_err(u32 err_code)
+{
+ return 0
+}
+#endif /*CONFIG_DEBUG_FS*/
+static s32 acdb_set_calibration_blk(unsigned long arg)
+{
+ struct acdb_cmd_device acdb_cmd;
+ s32 result = 0;
+
+ MM_DBG("acdb_set_calibration_blk\n");
+ if (copy_from_user(&acdb_cmd, (struct acdb_cmd_device *)arg,
+ sizeof(acdb_cmd))) {
+ MM_ERR("Failed copy command struct from user in"\
+ "acdb_set_calibration_blk\n");
+ return -EFAULT;
+ }
+ acdb_cmd.phys_buf = (u32 *)acdb_data.paddr;
+
+ MM_DBG("acdb_cmd.phys_buf %x\n", (u32)acdb_cmd.phys_buf);
+
+ result = dalrpc_fcn_8(ACDB_DAL_IOCTL, acdb_data.handle,
+ (const void *)&acdb_cmd, sizeof(acdb_cmd),
+ &acdb_data.acdb_result,
+ sizeof(acdb_data.acdb_result));
+
+ if (result < 0) {
+ MM_ERR("ACDB=> Device Set RPC failure"\
+ " result = %d\n", result);
+ return -EINVAL;
+ } else {
+ MM_ERR("ACDB=> Device Set RPC success\n");
+ if (acdb_data.acdb_result.result == ACDB_RES_SUCCESS)
+ MM_DBG("ACDB_SET_DEVICE Success\n");
+ else if (acdb_data.acdb_result.result == ACDB_RES_FAILURE)
+ MM_ERR("ACDB_SET_DEVICE Failure\n");
+ else if (acdb_data.acdb_result.result == ACDB_RES_BADPARM)
+ MM_ERR("ACDB_SET_DEVICE BadParams\n");
+ else
+ MM_ERR("Unknown error\n");
+ }
+ return result;
+}
+
+static s32 acdb_get_calibration_blk(unsigned long arg)
+{
+ s32 result = 0;
+ struct acdb_cmd_device acdb_cmd;
+
+ MM_DBG("acdb_get_calibration_blk\n");
+
+ if (copy_from_user(&acdb_cmd, (struct acdb_cmd_device *)arg,
+ sizeof(acdb_cmd))) {
+ MM_ERR("Failed copy command struct from user in"\
+ "acdb_get_calibration_blk\n");
+ return -EFAULT;
+ }
+ acdb_cmd.phys_buf = (u32 *)acdb_data.paddr;
+ MM_ERR("acdb_cmd.phys_buf %x\n", (u32)acdb_cmd.phys_buf);
+
+ result = dalrpc_fcn_8(ACDB_DAL_IOCTL, acdb_data.handle,
+ (const void *)&acdb_cmd, sizeof(acdb_cmd),
+ &acdb_data.acdb_result,
+ sizeof(acdb_data.acdb_result));
+
+ if (result < 0) {
+ MM_ERR("ACDB=> Device Get RPC failure"\
+ " result = %d\n", result);
+ return -EINVAL;
+ } else {
+ MM_ERR("ACDB=> Device Get RPC Success\n");
+ if (acdb_data.acdb_result.result == ACDB_RES_SUCCESS)
+ MM_DBG("ACDB_GET_DEVICE Success\n");
+ else if (acdb_data.acdb_result.result == ACDB_RES_FAILURE)
+ MM_ERR("ACDB_GET_DEVICE Failure\n");
+ else if (acdb_data.acdb_result.result == ACDB_RES_BADPARM)
+ MM_ERR("ACDB_GET_DEVICE BadParams\n");
+ else
+ MM_ERR("Unknown error\n");
+ }
+ return result;
+}
+
+static int audio_acdb_open(struct inode *inode, struct file *file)
+{
+ MM_DBG("%s\n", __func__);
+ return 0;
+}
+static int audio_acdb_release(struct inode *inode, struct file *file)
+{
+ MM_DBG("%s\n", __func__);
+ return 0;
+}
+
+static long audio_acdb_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ int rc = 0;
+ unsigned long flags = 0;
+ struct msm_audio_pmem_info info;
+
+ MM_DBG("%s\n", __func__);
+
+ switch (cmd) {
+ case AUDIO_SET_EQ:
+ MM_DBG("IOCTL SET_EQ_CONFIG\n");
+ if (copy_from_user(&acdb_data.eq.num_bands, (void *) arg,
+ sizeof(acdb_data.eq) -
+ (AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN + 2))) {
+ rc = -EFAULT;
+ break;
+ }
+ spin_lock_irqsave(&acdb_data.dsp_lock, flags);
+ rc = audpp_dsp_set_eq(COMMON_OBJ_ID, 1,
+ &acdb_data.eq);
+ if (rc < 0)
+ MM_ERR("AUDPP returned err =%d\n", rc);
+ spin_unlock_irqrestore(&acdb_data.dsp_lock, flags);
+ break;
+ case AUDIO_REGISTER_PMEM:
+ MM_DBG("AUDIO_REGISTER_PMEM\n");
+ if (copy_from_user(&info, (void *) arg, sizeof(info))) {
+ MM_ERR("Cannot copy from user\n");
+ return -EFAULT;
+ }
+ rc = get_pmem_file(info.fd, &acdb_data.paddr,
+ &acdb_data.kvaddr,
+ &acdb_data.pmem_len,
+ &acdb_data.file);
+ if (rc == 0)
+ acdb_data.pmem_fd = info.fd;
+ break;
+ case AUDIO_DEREGISTER_PMEM:
+ if (acdb_data.pmem_fd)
+ put_pmem_file(acdb_data.file);
+ break;
+ case AUDIO_SET_ACDB_BLK:
+ MM_DBG("IOCTL AUDIO_SET_ACDB_BLK\n");
+ rc = acdb_set_calibration_blk(arg);
+ break;
+ case AUDIO_GET_ACDB_BLK:
+ MM_DBG("IOiCTL AUDIO_GET_ACDB_BLK\n");
+ rc = acdb_get_calibration_blk(arg);
+ break;
+ default:
+ MM_DBG("Unknown IOCTL%d\n", cmd);
+ rc = -EINVAL;
+ }
+ return rc;
+}
+
+static const struct file_operations acdb_fops = {
+ .owner = THIS_MODULE,
+ .open = audio_acdb_open,
+ .release = audio_acdb_release,
+ .llseek = no_llseek,
+ .unlocked_ioctl = audio_acdb_ioctl
+};
+
+struct miscdevice acdb_misc = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "msm_acdb",
+ .fops = &acdb_fops,
+};
+
+static s32 acdb_get_calibration(void)
+{
+ struct acdb_cmd_get_device_table acdb_cmd;
+ s32 result = 0;
+ u32 iterations = 0;
+
+ MM_DBG("acdb state = %d\n", acdb_data.acdb_state);
+
+ acdb_cmd.command_id = ACDB_GET_DEVICE_TABLE;
+ acdb_cmd.device_id = acdb_data.device_info->acdb_id;
+ acdb_cmd.network_id = 0x0108B153;
+ acdb_cmd.sample_rate_id = acdb_data.device_info->sample_rate;
+ acdb_cmd.total_bytes = ACDB_BUF_SIZE;
+ acdb_cmd.phys_buf = (u32 *)acdb_data.phys_addr;
+ MM_DBG("device_id = %d, sampling_freq = %d\n",
+ acdb_cmd.device_id, acdb_cmd.sample_rate_id);
+
+ do {
+ result = dalrpc_fcn_8(ACDB_DAL_IOCTL, acdb_data.handle,
+ (const void *)&acdb_cmd, sizeof(acdb_cmd),
+ &acdb_data.acdb_result,
+ sizeof(acdb_data.acdb_result));
+
+ if (result < 0) {
+ MM_ERR("ACDB=> Device table RPC failure"\
+ " result = %d\n", result);
+ goto error;
+ }
+ /*following check is introduced to handle boot up race
+ condition between AUDCAL SW peers running on apps
+ and modem (ACDB_RES_BADSTATE indicates modem AUDCAL SW is
+ not in initialized sate) we need to retry to get ACDB
+ values*/
+ if (acdb_data.acdb_result.result == ACDB_RES_BADSTATE) {
+ msleep(500);
+ iterations++;
+ } else if (acdb_data.acdb_result.result == ACDB_RES_SUCCESS) {
+ MM_DBG("Modem query for acdb values is successful"\
+ " (iterations = %d)\n", iterations);
+ acdb_data.acdb_state |= CAL_DATA_READY;
+ return result;
+ } else {
+ MM_ERR("ACDB=> modem failed to fill acdb values,"\
+ " reuslt = %d, (iterations = %d)\n",
+ acdb_data.acdb_result.result,
+ iterations);
+ goto error;
+ }
+ } while (iterations < MAX_RETRY);
+ MM_ERR("ACDB=> AUDCAL SW on modem is not in intiailized state (%d)\n",
+ acdb_data.acdb_result.result);
+error:
+ result = -EINVAL;
+ return result;
+}
+
+s32 acdb_get_calibration_data(struct acdb_get_block *get_block)
+{
+ s32 result = -EINVAL;
+ struct acdb_cmd_device acdb_cmd;
+ struct acdb_result acdb_result;
+
+ MM_DBG("acdb_get_calibration_data\n");
+
+ acdb_cmd.command_id = ACDB_GET_DEVICE;
+ acdb_cmd.network_id = 0x0108B153;
+ acdb_cmd.device_id = get_block->acdb_id;
+ acdb_cmd.sample_rate_id = get_block->sample_rate_id;
+ acdb_cmd.interface_id = get_block->interface_id;
+ acdb_cmd.algorithm_block_id = get_block->algorithm_block_id;
+ acdb_cmd.total_bytes = get_block->total_bytes;
+ acdb_cmd.phys_buf = (u32 *)acdb_data.get_blk_paddr;
+
+ result = dalrpc_fcn_8(ACDB_DAL_IOCTL, acdb_data.handle,
+ (const void *)&acdb_cmd, sizeof(acdb_cmd),
+ &acdb_result,
+ sizeof(acdb_result));
+
+ if (result < 0) {
+ MM_ERR("ACDB=> Device Get RPC failure"\
+ " result = %d\n", result);
+ goto err_state;
+ } else {
+ MM_DBG("ACDB=> Device Get RPC Success\n");
+ if (acdb_result.result == ACDB_RES_SUCCESS) {
+ MM_DBG("ACDB_GET_DEVICE Success\n");
+ result = 0;
+ memcpy(get_block->buf_ptr, acdb_data.get_blk_kvaddr,
+ get_block->total_bytes);
+ } else if (acdb_result.result == ACDB_RES_FAILURE)
+ MM_ERR("ACDB_GET_DEVICE Failure\n");
+ else if (acdb_result.result == ACDB_RES_BADPARM)
+ MM_ERR("ACDB_GET_DEVICE BadParams\n");
+ else
+ MM_ERR("Unknown error\n");
+ }
+err_state:
+ return result;
+}
+EXPORT_SYMBOL(acdb_get_calibration_data);
+
+static u8 check_device_info_already_present(
+ struct dev_evt_msg device_info,
+ struct acdb_cache_node *acdb_cache_free_node)
+{
+ if ((device_info.sample_rate ==
+ acdb_cache_free_node->device_info.\
+ sample_rate) &&
+ (device_info.acdb_id ==
+ acdb_cache_free_node->device_info.acdb_id)) {
+ MM_DBG("acdb values are already present\n");
+ /*if acdb state is not set for CAL_DATA_READY and node status
+ is filled, acdb state should be updated with CAL_DATA_READY
+ state*/
+ acdb_data.acdb_state |= CAL_DATA_READY;
+ return 1; /*node is present but status as filled*/
+ }
+ MM_DBG("copying device info into node\n");
+ /*as device information is not present in cache copy
+ the current device information into the node*/
+ memcpy(&acdb_cache_free_node->device_info,
+ &device_info, sizeof(device_info));
+ return 0; /*cant find the node*/
+}
+
+static struct acdb_iir_block *get_audpp_irr_block(void)
+{
+ struct header *prs_hdr;
+ u32 index = 0;
+
+ while (index < acdb_data.acdb_result.used_bytes) {
+ prs_hdr = (struct header *)(acdb_data.virt_addr + index);
+ if (prs_hdr->dbor_signature == DBOR_SIGNATURE) {
+ if (prs_hdr->abid == ABID_AUDIO_IIR_RX) {
+ if (prs_hdr->iid == IID_AUDIO_IIR_COEFF)
+ return (struct acdb_iir_block *)
+ (acdb_data.virt_addr + index
+ + sizeof(struct header));
+ } else {
+ index += prs_hdr->data_len +
+ sizeof(struct header);
+ }
+ } else {
+ break;
+ }
+ }
+ return NULL;
+}
+
+
+static s32 acdb_fill_audpp_iir(void)
+{
+ struct acdb_iir_block *acdb_iir;
+ s32 i = 0;
+
+ acdb_iir = get_audpp_irr_block();
+ if (acdb_iir == NULL) {
+ MM_ERR("unable to find audpp iir block returning\n");
+ return -EINVAL;
+ }
+ memset(acdb_data.pp_iir, 0, sizeof(*acdb_data.pp_iir));
+
+ acdb_data.pp_iir->active_flag = acdb_iir->enable_flag;
+ acdb_data.pp_iir->num_bands = acdb_iir->stage_count;
+ for (; i < acdb_iir->stage_count; i++) {
+ acdb_data.pp_iir->params_filter.filter_4_params.
+ numerator_filter[i].numerator_b0_filter_lsw =
+ acdb_iir->stages[i].b0_lo;
+ acdb_data.pp_iir->params_filter.filter_4_params.
+ numerator_filter[i].numerator_b0_filter_msw =
+ acdb_iir->stages[i].b0_hi;
+ acdb_data.pp_iir->params_filter.filter_4_params.
+ numerator_filter[i].numerator_b1_filter_lsw =
+ acdb_iir->stages[i].b1_lo;
+ acdb_data.pp_iir->params_filter.filter_4_params.
+ numerator_filter[i].numerator_b1_filter_msw =
+ acdb_iir->stages[i].b1_hi;
+ acdb_data.pp_iir->params_filter.filter_4_params.
+ numerator_filter[i].numerator_b2_filter_lsw =
+ acdb_iir->stages[i].b2_lo;
+ acdb_data.pp_iir->params_filter.filter_4_params.
+ numerator_filter[i].numerator_b2_filter_msw =
+ acdb_iir->stages[i].b2_hi;
+ acdb_data.pp_iir->params_filter.filter_4_params.
+ denominator_filter[i].denominator_a0_filter_lsw =
+ acdb_iir->stages_a[i].a1_lo;
+ acdb_data.pp_iir->params_filter.filter_4_params.
+ denominator_filter[i].denominator_a0_filter_msw =
+ acdb_iir->stages_a[i].a1_hi;
+ acdb_data.pp_iir->params_filter.filter_4_params.
+ denominator_filter[i].denominator_a1_filter_lsw =
+ acdb_iir->stages_a[i].a2_lo;
+ acdb_data.pp_iir->params_filter.filter_4_params.
+ denominator_filter[i].denominator_a1_filter_msw =
+ acdb_iir->stages_a[i].a2_hi;
+ acdb_data.pp_iir->params_filter.filter_4_params.
+ shift_factor_filter[i].shift_factor_0 =
+ acdb_iir->shift_factor[i];
+ acdb_data.pp_iir->params_filter.filter_4_params.pan_filter[i].
+ pan_filter_0 = acdb_iir->pan[i];
+ }
+ return 0;
+}
+
+static void extract_mbadrc(u32 *phy_addr, struct header *prs_hdr, u32 *index)
+{
+ if (prs_hdr->iid == IID_MBADRC_EXT_BUFF) {
+ MM_DBG("Got IID = IID_MBADRC_EXT_BUFF\n");
+ *phy_addr = acdb_data.phys_addr + *index +
+ sizeof(struct header);
+ memcpy(acdb_data.mbadrc_block.ext_buf,
+ (acdb_data.virt_addr + *index +
+ sizeof(struct header)), 196*2);
+ MM_DBG("phy_addr = %x\n", *phy_addr);
+ *index += prs_hdr->data_len + sizeof(struct header);
+ } else if (prs_hdr->iid == IID_MBADRC_BAND_CONFIG) {
+ MM_DBG("Got IID == IID_MBADRC_BAND_CONFIG\n");
+ memcpy(acdb_data.mbadrc_block.band_config, (acdb_data.virt_addr
+ + *index + sizeof(struct header)),
+ sizeof(struct mbadrc_band_config_type) *
+ acdb_data.mbadrc_block.parameters.\
+ mbadrc_num_bands);
+ *index += prs_hdr->data_len + sizeof(struct header);
+ } else if (prs_hdr->iid == IID_MBADRC_PARAMETERS) {
+ struct mbadrc_parameter *tmp;
+ tmp = (struct mbadrc_parameter *)(acdb_data.virt_addr + *index
+ + sizeof(struct header));
+ MM_DBG("Got IID == IID_MBADRC_PARAMETERS");
+ acdb_data.mbadrc_block.parameters.mbadrc_enable =
+ tmp->mbadrc_enable;
+ acdb_data.mbadrc_block.parameters.mbadrc_num_bands =
+ tmp->mbadrc_num_bands;
+ acdb_data.mbadrc_block.parameters.mbadrc_down_sample_level =
+ tmp->mbadrc_down_sample_level;
+ acdb_data.mbadrc_block.parameters.mbadrc_delay =
+ tmp->mbadrc_delay;
+ *index += prs_hdr->data_len + sizeof(struct header);
+ }
+}
+
+static void get_audpp_mbadrc_block(u32 *phy_addr)
+{
+ struct header *prs_hdr;
+ u32 index = 0;
+
+ while (index < acdb_data.acdb_result.used_bytes) {
+ prs_hdr = (struct header *)(acdb_data.virt_addr + index);
+
+ if (prs_hdr->dbor_signature == DBOR_SIGNATURE) {
+ if (prs_hdr->abid == ABID_AUDIO_MBADRC_RX) {
+ if ((prs_hdr->iid == IID_MBADRC_EXT_BUFF)
+ || (prs_hdr->iid ==
+ IID_MBADRC_BAND_CONFIG)
+ || (prs_hdr->iid ==
+ IID_MBADRC_PARAMETERS)) {
+ extract_mbadrc(phy_addr, prs_hdr,
+ &index);
+ }
+ } else {
+ index += prs_hdr->data_len +
+ sizeof(struct header);
+ }
+ } else {
+ break;
+ }
+ }
+}
+
+static s32 acdb_fill_audpp_mbadrc(void)
+{
+ u32 mbadrc_phys_addr = -1;
+ get_audpp_mbadrc_block(&mbadrc_phys_addr);
+ if (IS_ERR_VALUE(mbadrc_phys_addr)) {
+ MM_ERR("failed to get mbadrc block\n");
+ return -EINVAL;
+ }
+
+ memset(acdb_data.pp_mbadrc, 0, sizeof(*acdb_data.pp_mbadrc));
+
+ acdb_data.pp_mbadrc->enable = acdb_data.mbadrc_block.\
+ parameters.mbadrc_enable;
+ acdb_data.pp_mbadrc->num_bands =
+ acdb_data.mbadrc_block.\
+ parameters.mbadrc_num_bands;
+ acdb_data.pp_mbadrc->down_samp_level =
+ acdb_data.mbadrc_block.parameters.\
+ mbadrc_down_sample_level;
+ acdb_data.pp_mbadrc->adrc_delay =
+ acdb_data.mbadrc_block.parameters.\
+ mbadrc_delay;
+
+ if (acdb_data.mbadrc_block.parameters.mbadrc_num_bands > 1)
+ acdb_data.pp_mbadrc->ext_buf_size = (97 * 2) +
+ (33 * 2 * (acdb_data.mbadrc_block.parameters.\
+ mbadrc_num_bands - 2));
+
+ acdb_data.pp_mbadrc->ext_partition = 0;
+ acdb_data.pp_mbadrc->ext_buf_lsw = (u16)(mbadrc_phys_addr\
+ & 0xFFFF);
+ acdb_data.pp_mbadrc->ext_buf_msw = (u16)((mbadrc_phys_addr\
+ & 0xFFFF0000) >> 16);
+ memcpy(acdb_data.pp_mbadrc->adrc_band, acdb_data.mbadrc_block.\
+ band_config,
+ sizeof(struct mbadrc_band_config_type) *
+ acdb_data.mbadrc_block.parameters.mbadrc_num_bands);
+ return 0;
+}
+
+static s32 acdb_calibrate_audpp(void)
+{
+ s32 result = 0;
+
+ result = acdb_fill_audpp_iir();
+ if (!IS_ERR_VALUE(result)) {
+ result = audpp_dsp_set_rx_iir(COMMON_OBJ_ID,
+ acdb_data.pp_iir->active_flag,
+ acdb_data.pp_iir);
+ if (result) {
+ MM_ERR("ACDB=> Failed to send IIR data to postproc\n");
+ result = -EINVAL;
+ goto done;
+ } else
+ MM_DBG("AUDPP is calibrated with IIR parameters");
+ }
+ result = acdb_fill_audpp_mbadrc();
+ if (!IS_ERR_VALUE(result)) {
+ result = audpp_dsp_set_mbadrc(COMMON_OBJ_ID,
+ acdb_data.pp_mbadrc->enable,
+ acdb_data.pp_mbadrc);
+ if (result) {
+ MM_ERR("ACDB=> Failed to send MBADRC data to"\
+ " postproc\n");
+ result = -EINVAL;
+ goto done;
+ } else
+ MM_DBG("AUDPP is calibrated with MBADRC parameters");
+ }
+done:
+ return result;
+}
+
+static struct acdb_agc_block *get_audpreproc_agc_block(void)
+{
+ struct header *prs_hdr;
+ u32 index = 0;
+
+ while (index < acdb_data.acdb_result.used_bytes) {
+ prs_hdr = (struct header *)(acdb_data.virt_addr + index);
+ if (prs_hdr->dbor_signature == DBOR_SIGNATURE) {
+ if (prs_hdr->abid == ABID_AUDIO_AGC_TX) {
+ if (prs_hdr->iid == IID_AUDIO_AGC_PARAMETERS) {
+ MM_DBG("GOT ABID_AUDIO_AGC_TX\n");
+ return (struct acdb_agc_block *)
+ (acdb_data.virt_addr + index
+ + sizeof(struct header));
+ }
+ } else {
+ index += prs_hdr->data_len +
+ sizeof(struct header);
+ }
+ } else {
+ break;
+ }
+ }
+ return NULL;
+}
+
+static s32 acdb_fill_audpreproc_agc(void)
+{
+ struct acdb_agc_block *acdb_agc;
+
+ acdb_agc = get_audpreproc_agc_block();
+ if (!acdb_agc) {
+ MM_DBG("unable to find preproc agc parameters winding up\n");
+ return -EINVAL;
+ }
+ memset(acdb_data.preproc_agc, 0, sizeof(*acdb_data.preproc_agc));
+ acdb_data.preproc_agc->cmd_id = AUDPREPROC_CMD_CFG_AGC_PARAMS;
+ /* 0xFE00 to configure all parameters */
+ acdb_data.preproc_agc->tx_agc_param_mask = 0xFFFF;
+ if (acdb_agc->enable_status)
+ acdb_data.preproc_agc->tx_agc_enable_flag =
+ AUDPREPROC_CMD_TX_AGC_ENA_FLAG_ENA;
+ else
+ acdb_data.preproc_agc->tx_agc_enable_flag =
+ AUDPREPROC_CMD_TX_AGC_ENA_FLAG_DIS;
+
+ acdb_data.preproc_agc->comp_rlink_static_gain =
+ acdb_agc->comp_rlink_static_gain;
+ acdb_data.preproc_agc->comp_rlink_aig_flag =
+ acdb_agc->comp_rlink_aig_flag;
+ acdb_data.preproc_agc->expander_rlink_th =
+ acdb_agc->exp_rlink_threshold;
+ acdb_data.preproc_agc->expander_rlink_slope =
+ acdb_agc->exp_rlink_slope;
+ acdb_data.preproc_agc->compressor_rlink_th =
+ acdb_agc->comp_rlink_threshold;
+ acdb_data.preproc_agc->compressor_rlink_slope =
+ acdb_agc->comp_rlink_slope;
+
+ /* 0xFFF0 to configure all parameters */
+ acdb_data.preproc_agc->tx_adc_agc_param_mask = 0xFFFF;
+
+ acdb_data.preproc_agc->comp_rlink_aig_attackk =
+ acdb_agc->comp_rlink_aig_attack_k;
+ acdb_data.preproc_agc->comp_rlink_aig_leak_down =
+ acdb_agc->comp_rlink_aig_leak_down;
+ acdb_data.preproc_agc->comp_rlink_aig_leak_up =
+ acdb_agc->comp_rlink_aig_leak_up;
+ acdb_data.preproc_agc->comp_rlink_aig_max =
+ acdb_agc->comp_rlink_aig_max;
+ acdb_data.preproc_agc->comp_rlink_aig_min =
+ acdb_agc->comp_rlink_aig_min;
+ acdb_data.preproc_agc->comp_rlink_aig_releasek =
+ acdb_agc->comp_rlink_aig_release_k;
+ acdb_data.preproc_agc->comp_rlink_aig_leakrate_fast =
+ acdb_agc->comp_rlink_aig_sm_leak_rate_fast;
+ acdb_data.preproc_agc->comp_rlink_aig_leakrate_slow =
+ acdb_agc->comp_rlink_aig_sm_leak_rate_slow;
+ acdb_data.preproc_agc->comp_rlink_attackk_msw =
+ acdb_agc->comp_rlink_attack_k_msw;
+ acdb_data.preproc_agc->comp_rlink_attackk_lsw =
+ acdb_agc->comp_rlink_attack_k_lsw;
+ acdb_data.preproc_agc->comp_rlink_delay =
+ acdb_agc->comp_rlink_delay;
+ acdb_data.preproc_agc->comp_rlink_releasek_msw =
+ acdb_agc->comp_rlink_release_k_msw;
+ acdb_data.preproc_agc->comp_rlink_releasek_lsw =
+ acdb_agc->comp_rlink_release_k_lsw;
+ acdb_data.preproc_agc->comp_rlink_rms_tav =
+ acdb_agc->comp_rlink_rms_trav;
+ return 0;
+}
+
+static struct acdb_iir_block *get_audpreproc_irr_block(void)
+{
+
+ struct header *prs_hdr;
+ u32 index = 0;
+
+ while (index < acdb_data.acdb_result.used_bytes) {
+ prs_hdr = (struct header *)(acdb_data.virt_addr + index);
+
+ if (prs_hdr->dbor_signature == DBOR_SIGNATURE) {
+ if (prs_hdr->abid == ABID_AUDIO_IIR_TX) {
+ if (prs_hdr->iid == IID_AUDIO_IIR_COEFF)
+ return (struct acdb_iir_block *)
+ (acdb_data.virt_addr + index
+ + sizeof(struct header));
+ } else {
+ index += prs_hdr->data_len +
+ sizeof(struct header);
+ }
+ } else {
+ break;
+ }
+ }
+ return NULL;
+}
+
+
+static s32 acdb_fill_audpreproc_iir(void)
+{
+ struct acdb_iir_block *acdb_iir;
+
+
+ acdb_iir = get_audpreproc_irr_block();
+ if (!acdb_iir) {
+ MM_DBG("unable to find preproc iir parameters winding up\n");
+ return -EINVAL;
+ }
+ memset(acdb_data.preproc_iir, 0, sizeof(*acdb_data.preproc_iir));
+
+ acdb_data.preproc_iir->cmd_id =
+ AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS;
+ acdb_data.preproc_iir->active_flag = acdb_iir->enable_flag;
+ acdb_data.preproc_iir->num_bands = acdb_iir->stage_count;
+
+ acdb_data.preproc_iir->numerator_coeff_b0_filter0_lsw =
+ acdb_iir->stages[0].b0_lo;
+ acdb_data.preproc_iir->numerator_coeff_b0_filter0_msw =
+ acdb_iir->stages[0].b0_hi;
+ acdb_data.preproc_iir->numerator_coeff_b1_filter0_lsw =
+ acdb_iir->stages[0].b1_lo;
+ acdb_data.preproc_iir->numerator_coeff_b1_filter0_msw =
+ acdb_iir->stages[0].b1_hi;
+ acdb_data.preproc_iir->numerator_coeff_b2_filter0_lsw =
+ acdb_iir->stages[0].b2_lo;
+ acdb_data.preproc_iir->numerator_coeff_b2_filter0_msw =
+ acdb_iir->stages[0].b2_hi;
+
+ acdb_data.preproc_iir->numerator_coeff_b0_filter1_lsw =
+ acdb_iir->stages[1].b0_lo;
+ acdb_data.preproc_iir->numerator_coeff_b0_filter1_msw =
+ acdb_iir->stages[1].b0_hi;
+ acdb_data.preproc_iir->numerator_coeff_b1_filter1_lsw =
+ acdb_iir->stages[1].b1_lo;
+ acdb_data.preproc_iir->numerator_coeff_b1_filter1_msw =
+ acdb_iir->stages[1].b1_hi;
+ acdb_data.preproc_iir->numerator_coeff_b2_filter1_lsw =
+ acdb_iir->stages[1].b2_lo;
+ acdb_data.preproc_iir->numerator_coeff_b2_filter1_msw =
+ acdb_iir->stages[1].b2_hi;
+
+ acdb_data.preproc_iir->numerator_coeff_b0_filter2_lsw =
+ acdb_iir->stages[2].b0_lo;
+ acdb_data.preproc_iir->numerator_coeff_b0_filter2_msw =
+ acdb_iir->stages[2].b0_hi;
+ acdb_data.preproc_iir->numerator_coeff_b1_filter2_lsw =
+ acdb_iir->stages[2].b1_lo;
+ acdb_data.preproc_iir->numerator_coeff_b1_filter2_msw =
+ acdb_iir->stages[2].b1_hi;
+ acdb_data.preproc_iir->numerator_coeff_b2_filter2_lsw =
+ acdb_iir->stages[2].b2_lo;
+ acdb_data.preproc_iir->numerator_coeff_b2_filter2_msw =
+ acdb_iir->stages[2].b2_hi;
+
+ acdb_data.preproc_iir->numerator_coeff_b0_filter3_lsw =
+ acdb_iir->stages[3].b0_lo;
+ acdb_data.preproc_iir->numerator_coeff_b0_filter3_msw =
+ acdb_iir->stages[3].b0_hi;
+ acdb_data.preproc_iir->numerator_coeff_b1_filter3_lsw =
+ acdb_iir->stages[3].b1_lo;
+ acdb_data.preproc_iir->numerator_coeff_b1_filter3_msw =
+ acdb_iir->stages[3].b1_hi;
+ acdb_data.preproc_iir->numerator_coeff_b2_filter3_lsw =
+ acdb_iir->stages[3].b2_lo;
+ acdb_data.preproc_iir->numerator_coeff_b2_filter3_msw =
+ acdb_iir->stages[3].b2_hi;
+
+ acdb_data.preproc_iir->denominator_coeff_a0_filter0_lsw =
+ acdb_iir->stages_a[0].a1_lo;
+ acdb_data.preproc_iir->denominator_coeff_a0_filter0_msw =
+ acdb_iir->stages_a[0].a1_hi;
+ acdb_data.preproc_iir->denominator_coeff_a1_filter0_lsw =
+ acdb_iir->stages_a[0].a2_lo;
+ acdb_data.preproc_iir->denominator_coeff_a1_filter0_msw =
+ acdb_iir->stages_a[0].a2_hi;
+
+ acdb_data.preproc_iir->denominator_coeff_a0_filter1_lsw =
+ acdb_iir->stages_a[1].a1_lo;
+ acdb_data.preproc_iir->denominator_coeff_a0_filter1_msw =
+ acdb_iir->stages_a[1].a1_hi;
+ acdb_data.preproc_iir->denominator_coeff_a1_filter1_lsw =
+ acdb_iir->stages_a[1].a2_lo;
+ acdb_data.preproc_iir->denominator_coeff_a1_filter1_msw =
+ acdb_iir->stages_a[1].a2_hi;
+
+ acdb_data.preproc_iir->denominator_coeff_a0_filter2_lsw =
+ acdb_iir->stages_a[2].a1_lo;
+ acdb_data.preproc_iir->denominator_coeff_a0_filter2_msw =
+ acdb_iir->stages_a[2].a1_hi;
+ acdb_data.preproc_iir->denominator_coeff_a1_filter2_lsw =
+ acdb_iir->stages_a[2].a2_lo;
+ acdb_data.preproc_iir->denominator_coeff_a1_filter2_msw =
+ acdb_iir->stages_a[2].a2_hi;
+
+ acdb_data.preproc_iir->denominator_coeff_a0_filter3_lsw =
+ acdb_iir->stages_a[3].a1_lo;
+ acdb_data.preproc_iir->denominator_coeff_a0_filter3_msw =
+ acdb_iir->stages_a[3].a1_hi;
+ acdb_data.preproc_iir->denominator_coeff_a1_filter3_lsw =
+ acdb_iir->stages_a[3].a2_lo;
+ acdb_data.preproc_iir->denominator_coeff_a1_filter3_msw =
+ acdb_iir->stages_a[3].a2_hi;
+
+ acdb_data.preproc_iir->shift_factor_filter0 =
+ acdb_iir->shift_factor[0];
+ acdb_data.preproc_iir->shift_factor_filter1 =
+ acdb_iir->shift_factor[1];
+ acdb_data.preproc_iir->shift_factor_filter2 =
+ acdb_iir->shift_factor[2];
+ acdb_data.preproc_iir->shift_factor_filter3 =
+ acdb_iir->shift_factor[3];
+
+ acdb_data.preproc_iir->channel_selected0 =
+ acdb_iir->pan[0];
+ acdb_data.preproc_iir->channel_selected1 =
+ acdb_iir->pan[1];
+ acdb_data.preproc_iir->channel_selected2 =
+ acdb_iir->pan[2];
+ acdb_data.preproc_iir->channel_selected3 =
+ acdb_iir->pan[3];
+ return 0;
+}
+
+static struct acdb_ns_tx_block *get_audpreproc_ns_block(void)
+{
+
+ struct header *prs_hdr;
+ u32 index = 0;
+
+ while (index < acdb_data.acdb_result.used_bytes) {
+ prs_hdr = (struct header *)(acdb_data.virt_addr + index);
+
+ if (prs_hdr->dbor_signature == DBOR_SIGNATURE) {
+ if (prs_hdr->abid == ABID_AUDIO_NS_TX) {
+ if (prs_hdr->iid == IID_NS_PARAMETERS)
+ return (struct acdb_ns_tx_block *)
+ (acdb_data.virt_addr + index
+ + sizeof(struct header));
+ } else {
+ index += prs_hdr->data_len +
+ sizeof(struct header);
+ }
+ } else {
+ break;
+ }
+ }
+ return NULL;
+}
+
+static s32 acdb_fill_audpreproc_ns(void)
+{
+ struct acdb_ns_tx_block *acdb_ns;
+ /* TO DO: do we enable_status_filled */
+ acdb_ns = get_audpreproc_ns_block();
+ if (!acdb_ns) {
+ MM_DBG("unable to find preproc ns parameters winding up\n");
+ return -EINVAL;
+ }
+ memset(acdb_data.preproc_ns, 0, sizeof(*acdb_data.preproc_ns));
+ acdb_data.preproc_ns->cmd_id = AUDPREPROC_CMD_CFG_NS_PARAMS;
+
+ acdb_data.preproc_ns->ec_mode_new = acdb_ns->ec_mode_new;
+ acdb_data.preproc_ns->dens_gamma_n = acdb_ns->dens_gamma_n;
+ acdb_data.preproc_ns->dens_nfe_block_size =
+ acdb_ns->dens_nfe_block_size;
+ acdb_data.preproc_ns->dens_limit_ns = acdb_ns->dens_limit_ns;
+ acdb_data.preproc_ns->dens_limit_ns_d = acdb_ns->dens_limit_ns_d;
+ acdb_data.preproc_ns->wb_gamma_e = acdb_ns->wb_gamma_e;
+ acdb_data.preproc_ns->wb_gamma_n = acdb_ns->wb_gamma_n;
+
+ return 0;
+}
+
+s32 acdb_calibrate_audpreproc(void)
+{
+ s32 result = 0;
+
+ result = acdb_fill_audpreproc_agc();
+ if (!IS_ERR_VALUE(result)) {
+ result = audpreproc_dsp_set_agc(acdb_data.preproc_agc, sizeof(
+ audpreproc_cmd_cfg_agc_params));
+ if (result) {
+ MM_ERR("ACDB=> Failed to send AGC data to preproc)\n");
+ result = -EINVAL;
+ goto done;
+ } else
+ MM_DBG("AUDPREC is calibrated with AGC parameters");
+ }
+ result = acdb_fill_audpreproc_iir();
+ if (!IS_ERR_VALUE(result)) {
+ result = audpreproc_dsp_set_iir(acdb_data.preproc_iir,
+ sizeof(\
+ audpreproc_cmd_cfg_iir_tuning_filter_params));
+ if (result) {
+ MM_ERR("ACDB=> Failed to send IIR data to preproc\n");
+ result = -EINVAL;
+ goto done;
+ } else
+ MM_DBG("audpreproc is calibrated with iir parameters");
+ }
+
+ result = acdb_fill_audpreproc_ns();
+ if (!IS_ERR_VALUE(result)) {
+ result = audpreproc_dsp_set_ns(acdb_data.preproc_ns,
+ sizeof(\
+ audpreproc_cmd_cfg_ns_params));
+ if (result) {
+ MM_ERR("ACDB=> Failed to send NS data to preproc\n");
+ result = -EINVAL;
+ goto done;
+ } else
+ MM_DBG("audpreproc is calibrated with NS parameters");
+ }
+done:
+ return result;
+}
+
+static s32 acdb_send_calibration(void)
+{
+ s32 result = 0;
+
+ if (acdb_data.device_info->dev_type.rx_device) {
+ result = acdb_calibrate_audpp();
+ if (result)
+ goto done;
+ } else if (acdb_data.device_info->dev_type.tx_device) {
+ result = acdb_calibrate_audpreproc();
+ if (result)
+ goto done;
+ acdb_data.audrec_applied |= AUDREC_READY;
+ MM_DBG("acdb_data.audrec_applied = %x\n",
+ acdb_data.audrec_applied);
+ }
+done:
+ return result;
+}
+
+static u8 check_tx_acdb_values_cached(void)
+{
+ if ((acdb_data.device_info->sample_rate ==
+ acdb_cache_tx.device_info.sample_rate) &&
+ (acdb_data.device_info->acdb_id ==
+ acdb_cache_tx.device_info.acdb_id) &&
+ (acdb_cache_tx.node_status ==
+ ACDB_VALUES_FILLED))
+ return 0;
+ else
+ return 1;
+}
+
+static void handle_tx_device_ready_callback(void)
+{
+ u8 acdb_value_apply = 0;
+ u8 result = 0;
+
+ /*check wheather AUDREC enabled before device call backs*/
+ if ((acdb_data.acdb_state & AUDREC_READY) &&
+ !(acdb_data.audrec_applied & AUDREC_READY)) {
+ MM_DBG("AUDREC already enabled apply acdb values\n");
+ acdb_value_apply |= AUDREC_READY;
+ }
+ if (acdb_value_apply) {
+ if (session_info.sampling_freq)
+ acdb_data.device_info->sample_rate =
+ session_info.sampling_freq;
+ result = check_tx_acdb_values_cached();
+ if (result) {
+ result = acdb_get_calibration();
+ if (result < 0) {
+ MM_ERR("Not able to get calibration"\
+ " data continue\n");
+ return;
+ }
+ }
+ acdb_cache_tx.node_status = ACDB_VALUES_FILLED;
+ acdb_send_calibration();
+ }
+}
+
+static struct acdb_cache_node *get_acdb_values_from_cache_tx(u32 stream_id)
+{
+ MM_DBG("searching node with stream_id");
+ if ((acdb_cache_tx.stream_id == stream_id) &&
+ (acdb_cache_tx.node_status ==
+ ACDB_VALUES_NOT_FILLED)) {
+ return &acdb_cache_tx;
+ }
+ MM_DBG("Error! in finding node\n");
+ return NULL;
+}
+
+static void update_acdb_data_struct(struct acdb_cache_node *cur_node)
+{
+ if (cur_node) {
+ acdb_data.device_info = &cur_node->device_info;
+ acdb_data.virt_addr = cur_node->virt_addr_acdb_values;
+ acdb_data.phys_addr = cur_node->phys_addr_acdb_values;
+ } else
+ MM_ERR("error in curent node\n");
+}
+
+static void send_acdb_values_for_active_devices(void)
+{
+ if (acdb_cache_rx.node_status ==
+ ACDB_VALUES_FILLED) {
+ update_acdb_data_struct(&acdb_cache_rx);
+ if (acdb_data.acdb_state & CAL_DATA_READY)
+ acdb_send_calibration();
+ }
+}
+
+static s32 initialize_rpc(void)
+{
+ s32 result = 0;
+
+ result = daldevice_attach(DALDEVICEID_ACDB, ACDB_PORT_NAME,
+ ACDB_CPU, &acdb_data.handle);
+
+ if (result) {
+ MM_ERR("ACDB=> Device Attach failed\n");
+ result = -ENODEV;
+ goto done;
+ }
+done:
+ return result;
+}
+
+static u32 allocate_memory_acdb_cache_tx(void)
+{
+ u32 result = 0;
+ /*initialize local cache */
+ acdb_cache_tx.phys_addr_acdb_values =
+ allocate_contiguous_ebi_nomap(ACDB_BUF_SIZE,
+ SZ_4K);
+
+ if (!acdb_cache_tx.phys_addr_acdb_values) {
+ MM_ERR("ACDB=> Cannot allocate physical memory\n");
+ result = -ENOMEM;
+ goto error;
+ }
+ acdb_cache_tx.map_v_addr = ioremap(
+ acdb_cache_tx.phys_addr_acdb_values,
+ ACDB_BUF_SIZE);
+ if (IS_ERR(acdb_cache_tx.map_v_addr)) {
+ MM_ERR("ACDB=> Could not map physical address\n");
+ result = -ENOMEM;
+ free_contiguous_memory_by_paddr(
+ acdb_cache_tx.phys_addr_acdb_values);
+ goto error;
+ }
+ acdb_cache_tx.virt_addr_acdb_values =
+ acdb_cache_tx.map_v_addr;
+ memset(acdb_cache_tx.virt_addr_acdb_values, 0,
+ ACDB_BUF_SIZE);
+ return result;
+error:
+ iounmap(acdb_cache_tx.map_v_addr);
+ free_contiguous_memory_by_paddr(
+ acdb_cache_tx.phys_addr_acdb_values);
+ return result;
+}
+
+static u32 allocate_memory_acdb_cache_rx(void)
+{
+ u32 result = 0;
+
+ /*initialize local cache */
+ acdb_cache_rx.phys_addr_acdb_values =
+ allocate_contiguous_ebi_nomap(
+ ACDB_BUF_SIZE, SZ_4K);
+
+ if (!acdb_cache_rx.phys_addr_acdb_values) {
+ MM_ERR("ACDB=> Can not allocate physical memory\n");
+ result = -ENOMEM;
+ goto error;
+ }
+ acdb_cache_rx.map_v_addr =
+ ioremap(acdb_cache_rx.phys_addr_acdb_values,
+ ACDB_BUF_SIZE);
+ if (IS_ERR(acdb_cache_rx.map_v_addr)) {
+ MM_ERR("ACDB=> Could not map physical address\n");
+ result = -ENOMEM;
+ free_contiguous_memory_by_paddr(
+ acdb_cache_rx.phys_addr_acdb_values);
+ goto error;
+ }
+ acdb_cache_rx.virt_addr_acdb_values =
+ acdb_cache_rx.map_v_addr;
+ memset(acdb_cache_rx.virt_addr_acdb_values, 0,
+ ACDB_BUF_SIZE);
+ return result;
+error:
+ iounmap(acdb_cache_rx.map_v_addr);
+ free_contiguous_memory_by_paddr(
+ acdb_cache_rx.phys_addr_acdb_values);
+ return result;
+}
+
+static u32 allocate_memory_acdb_get_blk(void)
+{
+ u32 result = 0;
+ acdb_data.get_blk_paddr = allocate_contiguous_ebi_nomap(
+ ACDB_BUF_SIZE, SZ_4K);
+ if (!acdb_data.get_blk_paddr) {
+ MM_ERR("ACDB=> Cannot allocate physical memory\n");
+ result = -ENOMEM;
+ goto error;
+ }
+ acdb_data.map_v_get_blk = ioremap(acdb_data.get_blk_paddr,
+ ACDB_BUF_SIZE);
+ if (IS_ERR(acdb_data.map_v_get_blk)) {
+ MM_ERR("ACDB=> Could not map physical address\n");
+ result = -ENOMEM;
+ free_contiguous_memory_by_paddr(
+ acdb_data.get_blk_paddr);
+ goto error;
+ }
+ acdb_data.get_blk_kvaddr = acdb_data.map_v_get_blk;
+ memset(acdb_data.get_blk_kvaddr, 0, ACDB_BUF_SIZE);
+error:
+ return result;
+}
+
+static void free_memory_acdb_cache_rx(void)
+{
+ iounmap(acdb_cache_rx.map_v_addr);
+ free_contiguous_memory_by_paddr(
+ acdb_cache_rx.phys_addr_acdb_values);
+}
+
+static void free_memory_acdb_cache_tx(void)
+{
+
+ iounmap(acdb_cache_tx.map_v_addr);
+ free_contiguous_memory_by_paddr(
+ acdb_cache_tx.phys_addr_acdb_values);
+}
+
+static void free_memory_acdb_get_blk(void)
+{
+ iounmap(acdb_data.map_v_get_blk);
+ free_contiguous_memory_by_paddr(acdb_data.get_blk_paddr);
+}
+
+static s32 initialize_memory(void)
+{
+ s32 result = 0;
+
+ result = allocate_memory_acdb_get_blk();
+ if (result < 0) {
+ MM_ERR("memory allocation for get blk failed\n");
+ goto done;
+ }
+
+ result = allocate_memory_acdb_cache_rx();
+ if (result < 0) {
+ MM_ERR("memory allocation for rx cache is failed\n");
+ free_memory_acdb_get_blk();
+ goto done;
+ }
+ result = allocate_memory_acdb_cache_tx();
+ if (result < 0) {
+ MM_ERR("memory allocation for tx cache is failed\n");
+ free_memory_acdb_get_blk();
+ free_memory_acdb_cache_rx();
+ goto done;
+ }
+ acdb_data.pp_iir = kmalloc(sizeof(*acdb_data.pp_iir),
+ GFP_KERNEL);
+ if (acdb_data.pp_iir == NULL) {
+ MM_ERR("ACDB=> Could not allocate postproc iir memory\n");
+ free_memory_acdb_get_blk();
+ free_memory_acdb_cache_rx();
+ free_memory_acdb_cache_tx();
+ result = -ENOMEM;
+ goto done;
+ }
+
+ acdb_data.pp_mbadrc = kmalloc(sizeof(*acdb_data.pp_mbadrc), GFP_KERNEL);
+ if (acdb_data.pp_mbadrc == NULL) {
+ MM_ERR("ACDB=> Could not allocate postproc mbadrc memory\n");
+ free_memory_acdb_get_blk();
+ free_memory_acdb_cache_rx();
+ free_memory_acdb_cache_tx();
+ kfree(acdb_data.pp_iir);
+ result = -ENOMEM;
+ goto done;
+ }
+
+ acdb_data.preproc_agc = kmalloc(sizeof(*acdb_data.preproc_agc),
+ GFP_KERNEL);
+ if (acdb_data.preproc_agc == NULL) {
+ MM_ERR("ACDB=> Could not allocate preproc agc memory\n");
+ free_memory_acdb_get_blk();
+ free_memory_acdb_cache_rx();
+ free_memory_acdb_cache_tx();
+ kfree(acdb_data.pp_iir);
+ kfree(acdb_data.pp_mbadrc);
+ result = -ENOMEM;
+ goto done;
+ }
+
+ acdb_data.preproc_iir = kmalloc(sizeof(*acdb_data.preproc_iir),
+ GFP_KERNEL);
+ if (acdb_data.preproc_iir == NULL) {
+ MM_ERR("ACDB=> Could not allocate preproc iir memory\n");
+ free_memory_acdb_get_blk();
+ free_memory_acdb_cache_rx();
+ free_memory_acdb_cache_tx();
+ kfree(acdb_data.pp_iir);
+ kfree(acdb_data.pp_mbadrc);
+ kfree(acdb_data.preproc_agc);
+ result = -ENOMEM;
+ goto done;
+ }
+
+ acdb_data.preproc_ns = kmalloc(sizeof(*acdb_data.preproc_ns),
+ GFP_KERNEL);
+ if (acdb_data.preproc_ns == NULL) {
+ MM_ERR("ACDB=> Could not allocate preproc ns memory\n");
+ free_memory_acdb_get_blk();
+ free_memory_acdb_cache_rx();
+ free_memory_acdb_cache_tx();
+ kfree(acdb_data.pp_iir);
+ kfree(acdb_data.pp_mbadrc);
+ kfree(acdb_data.preproc_agc);
+ kfree(acdb_data.preproc_iir);
+ result = -ENOMEM;
+ goto done;
+ }
+done:
+ return result;
+}
+
+static u8 check_device_change(struct dev_evt_msg device_info)
+{
+ if (!acdb_data.device_info) {
+ MM_ERR("not pointing to previous valid device detail\n");
+ return 1; /*device info will not be pointing to*/
+ /* valid device when acdb driver comes up*/
+ }
+ if ((device_info.sample_rate ==
+ acdb_data.device_info->sample_rate) &&
+ (device_info.acdb_id == acdb_data.device_info->acdb_id)) {
+ return 0;
+ }
+ return 1;
+}
+
+static void device_cb(struct dev_evt_msg *evt, void *private)
+{
+ struct cad_device_info_type dev_type;
+ struct acdb_cache_node *acdb_cache_free_node = NULL;
+ u32 session_id = 0;
+ u8 ret = 0;
+ u8 device_change = 0;
+
+ /*if session value is zero it indicates that device call back is for
+ voice call we will drop the request as acdb values for voice call is
+ not applied from acdb driver*/
+ if (!evt->session_info) {
+ MM_DBG("no active sessions and call back is for"\
+ " voice call\n");
+ goto done;
+ }
+
+ if ((evt->dev_type.rx_device) &&
+ (evt->acdb_id == PSEUDO_ACDB_ID)) {
+ MM_INFO("device cb is for rx device with pseudo acdb id\n");
+ goto done;
+ }
+ dev_type = evt->dev_type;
+ MM_DBG("sample_rate = %d\n", evt->sample_rate);
+ MM_DBG("acdb_id = %d\n", evt->acdb_id);
+ MM_DBG("sessions = %d\n", evt->session_info);
+ MM_DBG("acdb_state = %x\n", acdb_data.acdb_state);
+ mutex_lock(&acdb_data.acdb_mutex);
+ device_change = check_device_change(*evt);
+ if (!device_change) {
+ if (dev_type.tx_device) {
+ if (!(acdb_data.acdb_state & AUDREC_READY))
+ acdb_data.audrec_applied &= ~AUDREC_READY;
+
+ acdb_data.acdb_state &= ~CAL_DATA_READY;
+ goto update_cache;
+ }
+ } else
+ /* state is updated to query the modem for values */
+ acdb_data.acdb_state &= ~CAL_DATA_READY;
+
+update_cache:
+ if (dev_type.tx_device) {
+ /*Only one recording session possible*/
+ session_id = 0;
+ acdb_cache_free_node = &acdb_cache_tx;
+ ret = check_device_info_already_present(
+ *evt,
+ acdb_cache_free_node);
+ acdb_cache_free_node->stream_id = session_id;
+ acdb_data.cur_tx_session = session_id;
+ } else {
+ acdb_cache_free_node = &acdb_cache_rx;
+ ret = check_device_info_already_present(*evt,
+ acdb_cache_free_node);
+ if (ret == 1) {
+ MM_DBG("got device ready call back for another "\
+ "audplay task sessions on same COPP\n");
+ /*stream_id is used to keep track of number of active*/
+ /*sessions active on this device*/
+ acdb_cache_free_node->stream_id++;
+ mutex_unlock(&acdb_data.acdb_mutex);
+ goto done;
+ }
+ acdb_cache_free_node->stream_id++;
+ }
+ update_acdb_data_struct(acdb_cache_free_node);
+ acdb_data.device_cb_compl = 1;
+ mutex_unlock(&acdb_data.acdb_mutex);
+ wake_up(&acdb_data.wait);
+done:
+ return;
+}
+
+static s32 register_device_cb(void)
+{
+ s32 result = 0;
+ acdb_data.dev_cb.func = device_cb;
+ acdb_data.dev_cb.private = (void *)&acdb_data;
+
+ result = audmgr_register_device_info_callback(&acdb_data.dev_cb);
+
+ if (result) {
+ MM_ERR("ACDB=> Could not register device callback\n");
+ result = -ENODEV;
+ goto done;
+ }
+done:
+ return result;
+}
+
+static void audpp_cb(void *private, u32 id, u16 *msg)
+{
+ MM_DBG("\n");
+ if (id != AUDPP_MSG_CFG_MSG)
+ goto done;
+
+ if (msg[0] == AUDPP_MSG_ENA_DIS) {
+ if (--acdb_cache_rx.stream_id <= 0) {
+ acdb_data.acdb_state &= ~AUDPP_READY;
+ acdb_cache_rx.stream_id = 0;
+ MM_DBG("AUDPP_MSG_ENA_DIS\n");
+ }
+ goto done;
+ }
+
+ acdb_data.acdb_state |= AUDPP_READY;
+ acdb_data.audpp_cb_compl = 1;
+ wake_up(&acdb_data.wait);
+done:
+ return;
+}
+
+static s8 handle_audpreproc_cb(void)
+{
+ struct acdb_cache_node *acdb_cached_values;
+ s8 result = 0;
+ u8 stream_id = acdb_data.preproc_stream_id;
+ acdb_data.preproc_cb_compl = 0;
+ acdb_cached_values = get_acdb_values_from_cache_tx(stream_id);
+ if (acdb_cached_values == NULL) {
+ MM_DBG("ERROR: to get chached acdb values\n");
+ return -EPERM;
+ }
+ update_acdb_data_struct(acdb_cached_values);
+
+ if (session_info.sampling_freq)
+ acdb_data.device_info->sample_rate =
+ session_info.sampling_freq;
+
+ if (!(acdb_data.acdb_state & CAL_DATA_READY)) {
+ result = check_tx_acdb_values_cached();
+ if (result) {
+ result = acdb_get_calibration();
+ if (result < 0) {
+ MM_ERR("failed to get calibration data\n");
+ return result;
+ }
+ }
+ acdb_cached_values->node_status = ACDB_VALUES_FILLED;
+ }
+ return result;
+}
+
+static void audpreproc_cb(void *private, u32 id, void *event_data)
+{
+ u8 result = 0;
+ uint16_t *msg = event_data;
+ int stream_id = 0; /* Only single tunnel mode recording supported */
+ if (id != AUDPREPROC_MSG_CMD_CFG_DONE_MSG)
+ goto done;
+
+ acdb_data.preproc_stream_id = stream_id;
+ get_audrec_session_info(&session_info);
+ MM_DBG("status_flag = %x\n", msg[0]);
+ if (msg[0] == AUDPREPROC_MSG_STATUS_FLAG_DIS) {
+ acdb_data.acdb_state &= ~AUDREC_READY;
+ acdb_cache_tx.node_status =\
+ ACDB_VALUES_NOT_FILLED;
+ acdb_data.acdb_state &= ~CAL_DATA_READY;
+ goto done;
+ }
+ /*Following check is added to make sure that device info
+ is updated. audpre proc layer enabled without device
+ callback at this scenario we should not access
+ device information
+ */
+ if (acdb_data.device_info &&
+ session_info.sampling_freq) {
+ acdb_data.device_info->sample_rate =
+ session_info.sampling_freq;
+ result = check_tx_acdb_values_cached();
+ if (!result) {
+ MM_INFO("acdb values for the stream is" \
+ " querried from modem");
+ acdb_data.acdb_state |= CAL_DATA_READY;
+ } else {
+ acdb_data.acdb_state &= ~CAL_DATA_READY;
+ }
+ }
+ acdb_data.acdb_state |= AUDREC_READY;
+
+ acdb_data.preproc_cb_compl = 1;
+ MM_DBG("acdb_data.acdb_state = %x\n", acdb_data.acdb_state);
+ wake_up(&acdb_data.wait);
+done:
+ return;
+}
+
+static s32 register_audpp_cb(void)
+{
+ s32 result = 0;
+
+ acdb_data.audpp_cb.fn = audpp_cb;
+ acdb_data.audpp_cb.private = NULL;
+ result = audpp_register_event_callback(&acdb_data.audpp_cb);
+ if (result) {
+ MM_ERR("ACDB=> Could not register audpp callback\n");
+ result = -ENODEV;
+ goto done;
+ }
+done:
+ return result;
+}
+
+static s32 register_audpreproc_cb(void)
+{
+ s32 result = 0;
+
+ acdb_data.audpreproc_cb.fn = audpreproc_cb;
+ acdb_data.audpreproc_cb.private = NULL;
+ result = audpreproc_register_event_callback(&acdb_data.audpreproc_cb);
+ if (result) {
+ MM_ERR("ACDB=> Could not register audpreproc callback\n");
+ result = -ENODEV;
+ goto done;
+ }
+
+done:
+ return result;
+}
+
+static s32 acdb_initialize_data(void)
+{
+ s32 result = 0;
+
+ mutex_init(&acdb_data.acdb_mutex);
+
+ result = initialize_rpc();
+ if (result)
+ goto err;
+
+ result = initialize_memory();
+ if (result)
+ goto err1;
+
+ result = register_device_cb();
+ if (result)
+ goto err2;
+
+ result = register_audpp_cb();
+ if (result)
+ goto err3;
+
+ result = register_audpreproc_cb();
+ if (result)
+ goto err4;
+
+
+ return result;
+
+err4:
+ result = audpreproc_unregister_event_callback(&acdb_data.audpreproc_cb);
+ if (result)
+ MM_ERR("ACDB=> Could not unregister audpreproc callback\n");
+err3:
+ result = audpp_unregister_event_callback(&acdb_data.audpp_cb);
+ if (result)
+ MM_ERR("ACDB=> Could not unregister audpp callback\n");
+err2:
+ result = audmgr_deregister_device_info_callback(&acdb_data.dev_cb);
+ if (result)
+ MM_ERR("ACDB=> Could not unregister device callback\n");
+err1:
+ daldevice_detach(acdb_data.handle);
+ acdb_data.handle = NULL;
+err:
+ return result;
+}
+
+static s32 acdb_calibrate_device(void *data)
+{
+ s32 result = 0;
+
+ /* initialize driver */
+ result = acdb_initialize_data();
+ if (result)
+ goto done;
+
+ while (!kthread_should_stop()) {
+ MM_DBG("Waiting for call back events\n");
+ wait_event_interruptible(acdb_data.wait,
+ (acdb_data.device_cb_compl
+ | acdb_data.audpp_cb_compl
+ | acdb_data.preproc_cb_compl));
+ mutex_lock(&acdb_data.acdb_mutex);
+ if (acdb_data.device_cb_compl) {
+ acdb_data.device_cb_compl = 0;
+ if (!(acdb_data.acdb_state & CAL_DATA_READY)) {
+ if (acdb_data.device_info->dev_type.rx_device) {
+ /*we need to get calibration values
+ only for RX device as resampler
+ moved to start of the pre - proc chain
+ tx calibration value will be based on
+ sampling frequency what audrec is
+ configured, calibration values for tx
+ device are fetch in audpreproc
+ callback*/
+ result = acdb_get_calibration();
+ if (result < 0) {
+ mutex_unlock(
+ &acdb_data.acdb_mutex);
+ MM_ERR("Not able to get "\
+ "calibration "\
+ "data continue\n");
+ continue;
+ }
+ }
+ }
+ MM_DBG("acdb state = %d\n",
+ acdb_data.acdb_state);
+ if (acdb_data.device_info->dev_type.tx_device)
+ handle_tx_device_ready_callback();
+ else {
+ acdb_cache_rx.node_status =\
+ ACDB_VALUES_FILLED;
+ if (acdb_data.acdb_state &
+ AUDPP_READY) {
+ MM_DBG("AUDPP already enabled "\
+ "apply acdb values\n");
+ goto apply;
+ }
+ }
+ }
+
+ if (!(acdb_data.audpp_cb_compl ||
+ acdb_data.preproc_cb_compl)) {
+ MM_DBG("need to wait for either AUDPP / AUDPREPROC "\
+ "Event\n");
+ mutex_unlock(&acdb_data.acdb_mutex);
+ continue;
+ } else {
+ MM_DBG("got audpp / preproc call back\n");
+ if (acdb_data.audpp_cb_compl) {
+ send_acdb_values_for_active_devices();
+ acdb_data.audpp_cb_compl = 0;
+ mutex_unlock(&acdb_data.acdb_mutex);
+ continue;
+ } else {
+ result = handle_audpreproc_cb();
+ if (result < 0) {
+ mutex_unlock(&acdb_data.acdb_mutex);
+ continue;
+ }
+ }
+ }
+apply:
+ if (acdb_data.acdb_state & CAL_DATA_READY)
+ result = acdb_send_calibration();
+
+ mutex_unlock(&acdb_data.acdb_mutex);
+ }
+done:
+ return 0;
+}
+
+static int __init acdb_init(void)
+{
+
+ s32 result = 0;
+
+ memset(&acdb_data, 0, sizeof(acdb_data));
+ spin_lock_init(&acdb_data.dsp_lock);
+ acdb_data.cb_thread_task = kthread_run(acdb_calibrate_device,
+ NULL, "acdb_cb_thread");
+
+ if (IS_ERR(acdb_data.cb_thread_task)) {
+ MM_ERR("ACDB=> Could not register cb thread\n");
+ result = -ENODEV;
+ goto err;
+ }
+
+#ifdef CONFIG_DEBUG_FS
+ /*This is RTC specific INIT used only with debugfs*/
+ if (!rtc_acdb_init())
+ MM_ERR("RTC ACDB=>INIT Failure\n");
+
+#endif
+ init_waitqueue_head(&acdb_data.wait);
+
+ return misc_register(&acdb_misc);
+err:
+ return result;
+}
+
+static void __exit acdb_exit(void)
+{
+ s32 result = 0;
+
+ result = audmgr_deregister_device_info_callback(&acdb_data.dev_cb);
+ if (result)
+ MM_ERR("ACDB=> Could not unregister device callback\n");
+
+ result = audpp_unregister_event_callback(&acdb_data.audpp_cb);
+ if (result)
+ MM_ERR("ACDB=> Could not unregister audpp callback\n");
+
+ result = audpreproc_unregister_event_callback(&acdb_data.\
+ audpreproc_cb);
+ if (result)
+ MM_ERR("ACDB=> Could not unregister audpreproc callback\n");
+
+ result = kthread_stop(acdb_data.cb_thread_task);
+ if (result)
+ MM_ERR("ACDB=> Could not stop kthread\n");
+
+ free_memory_acdb_get_blk();
+
+ iounmap(acdb_cache_tx.map_v_addr);
+ free_contiguous_memory_by_paddr(
+ acdb_cache_tx.phys_addr_acdb_values);
+ iounmap(acdb_cache_rx.map_v_addr);
+ free_contiguous_memory_by_paddr(
+ acdb_cache_rx.phys_addr_acdb_values);
+ kfree(acdb_data.device_info);
+ kfree(acdb_data.pp_iir);
+ kfree(acdb_data.pp_mbadrc);
+ kfree(acdb_data.preproc_agc);
+ kfree(acdb_data.preproc_iir);
+ kfree(acdb_data.preproc_ns);
+ mutex_destroy(&acdb_data.acdb_mutex);
+ memset(&acdb_data, 0, sizeof(acdb_data));
+ #ifdef CONFIG_DEBUG_FS
+ rtc_acdb_deinit();
+ #endif
+}
+
+late_initcall(acdb_init);
+module_exit(acdb_exit);
+
+MODULE_DESCRIPTION("MSM 8x25 Audio ACDB driver");
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-msm/qdsp5/audio_amrnb.c b/arch/arm/mach-msm/qdsp5/audio_amrnb.c
index 45fa045..7e6c9ce 100644
--- a/arch/arm/mach-msm/qdsp5/audio_amrnb.c
+++ b/arch/arm/mach-msm/qdsp5/audio_amrnb.c
@@ -51,6 +51,7 @@
#include <mach/qdsp5/qdsp5audppmsg.h>
#include <mach/qdsp5/qdsp5audplaycmdi.h>
#include <mach/qdsp5/qdsp5audplaymsg.h>
+#include <mach/qdsp5/qdsp5audpp.h>
#include <mach/qdsp5/qdsp5rmtcmdi.h>
#include <mach/debug_mm.h>
#include <mach/msm_memtypes.h>
diff --git a/arch/arm/mach-msm/qdsp5/audio_amrnb_in.c b/arch/arm/mach-msm/qdsp5/audio_amrnb_in.c
index 39578c1..05ad373 100644
--- a/arch/arm/mach-msm/qdsp5/audio_amrnb_in.c
+++ b/arch/arm/mach-msm/qdsp5/audio_amrnb_in.c
@@ -114,8 +114,6 @@
uint32_t out_frame_cnt;
struct msm_adsp_module *audrec;
- struct msm_adsp_module *audpre;
-
/* configuration to use on next enable */
uint32_t samp_rate;
@@ -154,6 +152,7 @@
struct ion_client *client;
struct ion_handle *input_buff_handle;
+ struct audrec_session_info session_info; /*audrec session info*/
};
struct audio_frame {
@@ -232,6 +231,30 @@
}
}
+/* ------------------- dsp --------------------- */
+static void audpre_dsp_event(void *data, unsigned id, void *event_data)
+{
+
+ uint16_t *msg = event_data;
+
+ if (!msg)
+ return;
+
+ switch (id) {
+ case AUDPREPROC_MSG_CMD_CFG_DONE_MSG:
+ MM_DBG("type %d, status_flag %d\n",\
+ msg[0], msg[1]);
+ break;
+ case AUDPREPROC_MSG_ERROR_MSG_ID:
+ MM_INFO("err_index %d\n", msg[0]);
+ break;
+ case ADSP_MESSAGE_ID:
+ MM_DBG("Received ADSP event: module enable(audpreproctask)\n");
+ break;
+ default:
+ MM_ERR("unknown event %d\n", id);
+ }
+}
/* must be called with audio->lock held */
static int audamrnb_in_enable(struct audio_amrnb_in *audio)
{
@@ -252,16 +275,23 @@
if (rc < 0)
return rc;
- if (msm_adsp_enable(audio->audpre)) {
+ if (audpreproc_enable(audio->enc_id,
+ &audpre_dsp_event, audio)) {
+ MM_ERR("msm_adsp_enable(audpreproc) failed\n");
audmgr_disable(&audio->audmgr);
- MM_ERR("msm_adsp_enable(audpre) failed\n");
return -ENODEV;
}
+ /*update aurec session info in audpreproc layer*/
+ audio->session_info.session_id = audio->enc_id;
+ audio->session_info.sampling_freq =
+ convert_samp_index(audio->samp_rate);
+ audpreproc_update_audrec_info(&audio->session_info);
}
+
if (msm_adsp_enable(audio->audrec)) {
if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) {
+ audpreproc_disable(audio->enc_id, audio);
audmgr_disable(&audio->audmgr);
- msm_adsp_disable(audio->audpre);
}
MM_ERR("msm_adsp_enable(audrec) failed\n");
return -ENODEV;
@@ -286,35 +316,17 @@
audio->running == 0, 1*HZ);
msm_adsp_disable(audio->audrec);
if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) {
- msm_adsp_disable(audio->audpre);
+ /*reset the sampling frequency information at
+ audpreproc layer*/
+ audio->session_info.sampling_freq = 0;
+ audpreproc_update_audrec_info(&audio->session_info);
+ audpreproc_disable(audio->enc_id, audio);
audmgr_disable(&audio->audmgr);
}
}
return 0;
}
-/* ------------------- dsp --------------------- */
-static void audpre_dsp_event(void *data, unsigned id, size_t len,
- void (*getevent)(void *ptr, size_t len))
-{
- uint16_t msg[2];
- getevent(msg, sizeof(msg));
-
- switch (id) {
- case AUDPREPROC_MSG_CMD_CFG_DONE_MSG:
- MM_DBG("type %d, status_flag %d\n", msg[0], msg[1]);
- break;
- case AUDPREPROC_MSG_ERROR_MSG_ID:
- MM_ERR("err_index %d\n", msg[0]);
- break;
- case ADSP_MESSAGE_ID:
- MM_DBG("Received ADSP event: module enable(audpreproctask)\n");
- break;
- default:
- MM_ERR("unknown event %d\n", id);
- }
-}
-
static void audamrnb_in_get_dsp_frames(struct audio_amrnb_in *audio)
{
struct audio_frame *frame;
@@ -555,10 +567,6 @@
}
}
-struct msm_adsp_ops audpre_amrnb_adsp_ops = {
- .event = audpre_dsp_event,
-};
-
struct msm_adsp_ops audrec_amrnb_adsp_ops = {
.event = audrec_dsp_event,
};
@@ -1201,12 +1209,8 @@
audamrnb_in_flush(audio);
msm_adsp_put(audio->audrec);
- if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL)
- msm_adsp_put(audio->audpre);
-
audpreproc_aenc_free(audio->enc_id);
audio->audrec = NULL;
- audio->audpre = NULL;
audio->opened = 0;
if ((audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) && \
(audio->out_data)) {
@@ -1304,15 +1308,6 @@
goto done;
}
- if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) {
- rc = msm_adsp_get("AUDPREPROCTASK", &audio->audpre,
- &audpre_amrnb_adsp_ops, audio);
- if (rc) {
- msm_adsp_put(audio->audrec);
- audpreproc_aenc_free(audio->enc_id);
- goto done;
- }
- }
audio->dsp_cnt = 0;
audio->stopped = 0;
audio->wflush = 0;
@@ -1414,8 +1409,6 @@
dma_free_coherent(NULL, dma_size, audio->data, audio->phys);
evt_error:
msm_adsp_put(audio->audrec);
- if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL)
- msm_adsp_put(audio->audpre);
audpreproc_aenc_free(audio->enc_id);
mutex_unlock(&audio->lock);
diff --git a/arch/arm/mach-msm/qdsp5/audio_amrwb.c b/arch/arm/mach-msm/qdsp5/audio_amrwb.c
index 66b9354..f18aca7 100644
--- a/arch/arm/mach-msm/qdsp5/audio_amrwb.c
+++ b/arch/arm/mach-msm/qdsp5/audio_amrwb.c
@@ -48,6 +48,7 @@
#include <mach/iommu_domains.h>
#include <mach/qdsp5/qdsp5audppcmdi.h>
#include <mach/qdsp5/qdsp5audppmsg.h>
+#include <mach/qdsp5/qdsp5audpp.h>
#include <mach/qdsp5/qdsp5audplaycmdi.h>
#include <mach/qdsp5/qdsp5audplaymsg.h>
#include <mach/qdsp5/qdsp5rmtcmdi.h>
diff --git a/arch/arm/mach-msm/qdsp5/audio_evrc.c b/arch/arm/mach-msm/qdsp5/audio_evrc.c
index 1d4148a..7aeadac 100644
--- a/arch/arm/mach-msm/qdsp5/audio_evrc.c
+++ b/arch/arm/mach-msm/qdsp5/audio_evrc.c
@@ -43,6 +43,7 @@
#include <mach/iommu_domains.h>
#include <mach/qdsp5/qdsp5audppcmdi.h>
#include <mach/qdsp5/qdsp5audppmsg.h>
+#include <mach/qdsp5/qdsp5audpp.h>
#include <mach/qdsp5/qdsp5audplaycmdi.h>
#include <mach/qdsp5/qdsp5audplaymsg.h>
#include <mach/qdsp5/qdsp5rmtcmdi.h>
diff --git a/arch/arm/mach-msm/qdsp5/audio_evrc_in.c b/arch/arm/mach-msm/qdsp5/audio_evrc_in.c
index e955c4b..3310743 100644
--- a/arch/arm/mach-msm/qdsp5/audio_evrc_in.c
+++ b/arch/arm/mach-msm/qdsp5/audio_evrc_in.c
@@ -111,7 +111,6 @@
int out_frame_cnt;
struct msm_adsp_module *audrec;
- struct msm_adsp_module *audpre;
/* configuration to use on next enable */
@@ -154,6 +153,8 @@
struct ion_client *client;
struct ion_handle *input_buff_handle;
struct ion_handle *output_buff_handle;
+
+ struct audrec_session_info session_info; /*audrec session info*/
};
struct audio_frame {
@@ -232,6 +233,32 @@
}
}
+/* ------------------- dsp --------------------- */
+static void audpre_dsp_event(void *data, unsigned id, void *event_data)
+{
+
+ uint16_t *msg = event_data;
+
+ if (!msg)
+ return;
+
+ switch (id) {
+ case AUDPREPROC_MSG_CMD_CFG_DONE_MSG:
+ MM_DBG("type %d, status_flag %d\n",\
+ msg[0], msg[1]);
+ break;
+ case AUDPREPROC_MSG_ERROR_MSG_ID:
+ MM_INFO("err_index %d\n", msg[0]);
+ break;
+ case ADSP_MESSAGE_ID:
+ MM_DBG("Received ADSP event: module enable(audpreproctask)\n");
+ break;
+ default:
+ MM_ERR("unknown event %d\n", id);
+ }
+}
+
+
/* must be called with audio->lock held */
static int audevrc_in_enable(struct audio_evrc_in *audio)
{
@@ -252,16 +279,24 @@
if (rc < 0)
return rc;
- if (msm_adsp_enable(audio->audpre)) {
+ if (audpreproc_enable(audio->enc_id,
+ &audpre_dsp_event, audio)) {
+ MM_ERR("msm_adsp_enable(audpreproc) failed\n");
audmgr_disable(&audio->audmgr);
- MM_ERR("msm_adsp_enable(audpre) failed\n");
return -ENODEV;
}
+
+ /*update aurec session info in audpreproc layer*/
+ audio->session_info.session_id = audio->enc_id;
+ audio->session_info.sampling_freq =
+ convert_samp_index(audio->samp_rate);
+ audpreproc_update_audrec_info(&audio->session_info);
}
+
if (msm_adsp_enable(audio->audrec)) {
if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) {
+ audpreproc_disable(audio->enc_id, audio);
audmgr_disable(&audio->audmgr);
- msm_adsp_disable(audio->audpre);
}
MM_ERR("msm_adsp_enable(audrec) failed\n");
return -ENODEV;
@@ -288,35 +323,17 @@
wake_up(&audio->wait);
msm_adsp_disable(audio->audrec);
if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) {
- msm_adsp_disable(audio->audpre);
+ audpreproc_disable(audio->enc_id, audio);
+ /*reset the sampling frequency information at
+ audpreproc layer*/
+ audio->session_info.sampling_freq = 0;
+ audpreproc_update_audrec_info(&audio->session_info);
audmgr_disable(&audio->audmgr);
}
}
return 0;
}
-/* ------------------- dsp --------------------- */
-static void audpre_dsp_event(void *data, unsigned id, size_t len,
- void (*getevent)(void *ptr, size_t len))
-{
- uint16_t msg[2];
- getevent(msg, sizeof(msg));
-
- switch (id) {
- case AUDPREPROC_MSG_CMD_CFG_DONE_MSG:
- MM_DBG("type %d, status_flag %d\n", msg[0], msg[1]);
- break;
- case AUDPREPROC_MSG_ERROR_MSG_ID:
- MM_ERR("err_index %d\n", msg[0]);
- break;
- case ADSP_MESSAGE_ID:
- MM_DBG("Received ADSP event: module enable(audpreproctask)\n");
- break;
- default:
- MM_ERR("unknown event %d\n", id);
- }
-}
-
static void audevrc_in_get_dsp_frames(struct audio_evrc_in *audio)
{
struct audio_frame *frame;
@@ -557,10 +574,6 @@
}
}
-static struct msm_adsp_ops audpre_evrc_adsp_ops = {
- .event = audpre_dsp_event,
-};
-
static struct msm_adsp_ops audrec_evrc_adsp_ops = {
.event = audrec_dsp_event,
};
@@ -1186,12 +1199,8 @@
audevrc_in_flush(audio);
msm_adsp_put(audio->audrec);
- if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL)
- msm_adsp_put(audio->audpre);
-
audpreproc_aenc_free(audio->enc_id);
audio->audrec = NULL;
- audio->audpre = NULL;
audio->opened = 0;
if ((audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) && \
(audio->out_data)) {
@@ -1282,16 +1291,6 @@
goto done;
}
- if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) {
- rc = msm_adsp_get("AUDPREPROCTASK", &audio->audpre,
- &audpre_evrc_adsp_ops, audio);
- if (rc) {
- msm_adsp_put(audio->audrec);
- audpreproc_aenc_free(audio->enc_id);
- goto done;
- }
- }
-
audio->dsp_cnt = 0;
audio->stopped = 0;
audio->wflush = 0;
@@ -1429,8 +1428,6 @@
ion_client_destroy(client);
client_create_error:
msm_adsp_put(audio->audrec);
- if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL)
- msm_adsp_put(audio->audpre);
audpreproc_aenc_free(audio->enc_id);
mutex_unlock(&audio->lock);
diff --git a/arch/arm/mach-msm/qdsp5/audio_lpa.c b/arch/arm/mach-msm/qdsp5/audio_lpa.c
index fe7b270..6cbb981a3 100644
--- a/arch/arm/mach-msm/qdsp5/audio_lpa.c
+++ b/arch/arm/mach-msm/qdsp5/audio_lpa.c
@@ -48,6 +48,7 @@
#include <mach/iommu_domains.h>
#include <mach/qdsp5/qdsp5audppcmdi.h>
#include <mach/qdsp5/qdsp5audppmsg.h>
+#include <mach/qdsp5/qdsp5audpp.h>
#include <mach/qdsp5/qdsp5audplaycmdi.h>
#include <mach/qdsp5/qdsp5audplaymsg.h>
#include <mach/qdsp5/qdsp5rmtcmdi.h>
diff --git a/arch/arm/mach-msm/qdsp5/audio_mp3.c b/arch/arm/mach-msm/qdsp5/audio_mp3.c
index 427dc8f..167de9c 100644
--- a/arch/arm/mach-msm/qdsp5/audio_mp3.c
+++ b/arch/arm/mach-msm/qdsp5/audio_mp3.c
@@ -42,6 +42,7 @@
#include <mach/msm_memtypes.h>
#include <mach/qdsp5/qdsp5audppcmdi.h>
#include <mach/qdsp5/qdsp5audppmsg.h>
+#include <mach/qdsp5/qdsp5audpp.h>
#include <mach/qdsp5/qdsp5audplaycmdi.h>
#include <mach/qdsp5/qdsp5audplaymsg.h>
#include <mach/qdsp5/qdsp5rmtcmdi.h>
diff --git a/arch/arm/mach-msm/qdsp5/audio_out.c b/arch/arm/mach-msm/qdsp5/audio_out.c
index 0c8034c..6f3bf91 100644
--- a/arch/arm/mach-msm/qdsp5/audio_out.c
+++ b/arch/arm/mach-msm/qdsp5/audio_out.c
@@ -41,6 +41,7 @@
#include <mach/qdsp5/qdsp5audppcmdi.h>
#include <mach/qdsp5/qdsp5audppmsg.h>
+#include <mach/qdsp5/qdsp5audpp.h>
#include <mach/htc_pwrsink.h>
#include <mach/debug_mm.h>
diff --git a/arch/arm/mach-msm/qdsp5/audio_pcm.c b/arch/arm/mach-msm/qdsp5/audio_pcm.c
index 880de09..3a92e0c 100644
--- a/arch/arm/mach-msm/qdsp5/audio_pcm.c
+++ b/arch/arm/mach-msm/qdsp5/audio_pcm.c
@@ -48,6 +48,7 @@
#include <mach/iommu_domains.h>
#include <mach/qdsp5/qdsp5audppcmdi.h>
#include <mach/qdsp5/qdsp5audppmsg.h>
+#include <mach/qdsp5/qdsp5audpp.h>
#include <mach/qdsp5/qdsp5audplaycmdi.h>
#include <mach/qdsp5/qdsp5audplaymsg.h>
#include <mach/qdsp5/qdsp5rmtcmdi.h>
diff --git a/arch/arm/mach-msm/qdsp5/audio_pcm_in.c b/arch/arm/mach-msm/qdsp5/audio_pcm_in.c
index 716dbd2..4dcbc7b 100644
--- a/arch/arm/mach-msm/qdsp5/audio_pcm_in.c
+++ b/arch/arm/mach-msm/qdsp5/audio_pcm_in.c
@@ -75,7 +75,6 @@
struct mutex read_lock;
wait_queue_head_t wait;
- struct msm_adsp_module *audpre;
struct msm_adsp_module *audrec;
const char *module_name;
unsigned queue_ids;
@@ -105,6 +104,7 @@
int enabled;
int running;
int stopped; /* set when stopped, cleared on flush */
+ struct audrec_session_info session_info; /*audrec session info*/
/* audpre settings */
int tx_agc_enable;
@@ -176,6 +176,32 @@
}
}
+/* ------------------- dsp --------------------- */
+static void audpre_dsp_event(void *data, unsigned id, void *event_data)
+{
+
+ uint16_t *msg = event_data;
+
+ if (!msg)
+ return;
+
+ switch (id) {
+ case AUDPREPROC_MSG_CMD_CFG_DONE_MSG:
+ MM_DBG("type %d, status_flag %d\n",\
+ msg[0], msg[1]);
+ break;
+ case AUDPREPROC_MSG_ERROR_MSG_ID:
+ MM_INFO("err_index %d\n", msg[0]);
+ break;
+ case ADSP_MESSAGE_ID:
+ MM_DBG("Received ADSP event: module enable(audpreproctask)\n");
+ break;
+ default:
+ MM_ERR("unknown event %d\n", id);
+ }
+}
+
+
/* must be called with audio->lock held */
static int audpcm_in_enable(struct audio_in *audio)
{
@@ -195,14 +221,15 @@
if (rc < 0)
return rc;
- if (msm_adsp_enable(audio->audpre)) {
- MM_ERR("msm_adsp_enable(audpre) failed\n");
+ if (audpreproc_enable(audio->enc_id, &audpre_dsp_event, audio)) {
+ MM_ERR("msm_adsp_enable(audpreproc) failed\n");
audmgr_disable(&audio->audmgr);
return -ENODEV;
}
+
if (msm_adsp_enable(audio->audrec)) {
+ audpreproc_disable(audio->enc_id, audio);
audmgr_disable(&audio->audmgr);
- msm_adsp_disable(audio->audpre);
MM_ERR("msm_adsp_enable(audrec) failed\n");
return -ENODEV;
}
@@ -210,6 +237,12 @@
audio->enabled = 1;
audpcm_in_dsp_enable(audio, 1);
+ /*update aurec session info in audpreproc layer*/
+ audio->session_info.session_id = audio->enc_id;
+ audio->session_info.sampling_freq =
+ convert_samp_index(audio->samp_rate);
+ audpreproc_update_audrec_info(&audio->session_info);
+
return 0;
}
@@ -225,34 +258,15 @@
wake_up(&audio->wait);
msm_adsp_disable(audio->audrec);
- msm_adsp_disable(audio->audpre);
+ audpreproc_disable(audio->enc_id, audio);
+ /*reset the sampling frequency information at audpreproc layer*/
+ audio->session_info.sampling_freq = 0;
+ audpreproc_update_audrec_info(&audio->session_info);
audmgr_disable(&audio->audmgr);
}
return 0;
}
-/* ------------------- dsp --------------------- */
-static void audpre_dsp_event(void *data, unsigned id, size_t len,
- void (*getevent)(void *ptr, size_t len))
-{
- uint16_t msg[2];
- getevent(msg, sizeof(msg));
-
- switch (id) {
- case AUDPREPROC_MSG_CMD_CFG_DONE_MSG:
- MM_INFO("type %d, status_flag %d\n", msg[0], msg[1]);
- break;
- case AUDPREPROC_MSG_ERROR_MSG_ID:
- MM_ERR("err_index %d\n", msg[0]);
- break;
- case ADSP_MESSAGE_ID:
- MM_DBG("Received ADSP event: module enable(audpreproctask)\n");
- break;
- default:
- MM_ERR("unknown event %d\n", id);
- }
-}
-
struct audio_frame {
uint16_t count_low;
uint16_t count_high;
@@ -360,18 +374,10 @@
}
}
-static struct msm_adsp_ops audpre_adsp_ops = {
- .event = audpre_dsp_event,
-};
-
static struct msm_adsp_ops audrec_adsp_ops = {
.event = audrec_dsp_event,
};
-
-#define audio_send_queue_pre(audio, cmd, len) \
- msm_adsp_write(audio->audpre, QDSP_uPAudPreProcCmdQueue, cmd, len)
-
#define audio_send_queue_recbs(audio, cmd, len) \
msm_adsp_write(audio->audrec, ((audio->queue_ids & 0xFFFF0000) >> 16),\
cmd, len)
@@ -399,7 +405,7 @@
audio->tx_agc_cfg.tx_agc_enable_flag =
AUDPREPROC_CMD_TX_AGC_ENA_FLAG_ENA;
/* cmd.param_mask = 0xFFF0 from sample code */
- audio->tx_agc_cfg.param_mask =
+ audio->tx_agc_cfg.tx_agc_param_mask =
(1 << AUDPREPROC_CMD_PARAM_MASK_RMS_TAY) |
(1 << AUDPREPROC_CMD_PARAM_MASK_RELEASEK) |
(1 << AUDPREPROC_CMD_PARAM_MASK_DELAY) |
@@ -420,7 +426,7 @@
}
cmd = audio->tx_agc_cfg;
- return audio_send_queue_pre(audio, &cmd, sizeof(cmd));
+ return audpreproc_dsp_set_agc(&cmd, sizeof(cmd));
}
static int audio_enable_tx_agc(struct audio_in *audio, int enable)
@@ -466,7 +472,7 @@
}
cmd = audio->ns_cfg;
- return audio_send_queue_pre(audio, &cmd, sizeof(cmd));
+ return audpreproc_dsp_set_ns(&cmd, sizeof(cmd));
}
static int audio_enable_ns(struct audio_in *audio, int enable)
@@ -495,7 +501,7 @@
cmd = audio->iir_cfg;
- return audio_send_queue_pre(audio, &cmd, sizeof(cmd));
+ return audpreproc_dsp_set_iir(&cmd, sizeof(cmd));
}
static int audio_enable_iir(struct audio_in *audio, int enable)
@@ -762,9 +768,7 @@
audpcm_in_flush(audio);
audpreproc_aenc_free(audio->enc_id);
msm_adsp_put(audio->audrec);
- msm_adsp_put(audio->audpre);
audio->audrec = NULL;
- audio->audpre = NULL;
audio->opened = 0;
if (audio->data) {
ion_unmap_kernel(audio->client, audio->output_buff_handle);
@@ -824,14 +828,6 @@
goto done;
}
- rc = msm_adsp_get("AUDPREPROCTASK", &audio->audpre,
- &audpre_adsp_ops, audio);
- if (rc) {
- msm_adsp_put(audio->audrec);
- audpreproc_aenc_free(audio->enc_id);
- goto done;
- }
-
audio->dsp_cnt = 0;
audio->stopped = 0;
@@ -899,7 +895,6 @@
ion_client_destroy(client);
client_create_error:
msm_adsp_put(audio->audrec);
- msm_adsp_put(audio->audpre);
audpreproc_aenc_free(audio->enc_id);
mutex_unlock(&audio->lock);
return rc;
diff --git a/arch/arm/mach-msm/qdsp5/audio_qcelp.c b/arch/arm/mach-msm/qdsp5/audio_qcelp.c
index dc257cd..e1a6299 100644
--- a/arch/arm/mach-msm/qdsp5/audio_qcelp.c
+++ b/arch/arm/mach-msm/qdsp5/audio_qcelp.c
@@ -44,6 +44,7 @@
#include <mach/iommu_domains.h>
#include <mach/qdsp5/qdsp5audppcmdi.h>
#include <mach/qdsp5/qdsp5audppmsg.h>
+#include <mach/qdsp5/qdsp5audpp.h>
#include <mach/qdsp5/qdsp5audplaycmdi.h>
#include <mach/qdsp5/qdsp5audplaymsg.h>
#include <mach/qdsp5/qdsp5rmtcmdi.h>
diff --git a/arch/arm/mach-msm/qdsp5/audio_qcelp_in.c b/arch/arm/mach-msm/qdsp5/audio_qcelp_in.c
index 99a169d..57ae772 100644
--- a/arch/arm/mach-msm/qdsp5/audio_qcelp_in.c
+++ b/arch/arm/mach-msm/qdsp5/audio_qcelp_in.c
@@ -112,7 +112,6 @@
int out_frame_cnt;
struct msm_adsp_module *audrec;
- struct msm_adsp_module *audpre;
/* configuration to use on next enable */
@@ -155,6 +154,8 @@
struct ion_client *client;
struct ion_handle *input_buff_handle;
struct ion_handle *output_buff_handle;
+
+ struct audrec_session_info session_info; /*audrec session info*/
};
struct audio_frame {
@@ -233,6 +234,32 @@
}
}
+/* ------------------- dsp --------------------- */
+static void audpre_dsp_event(void *data, unsigned id, void *event_data)
+{
+
+ uint16_t *msg = event_data;
+
+ if (!msg)
+ return;
+
+ switch (id) {
+ case AUDPREPROC_MSG_CMD_CFG_DONE_MSG:
+ MM_DBG("type %d, status_flag %d\n",\
+ msg[0], msg[1]);
+ break;
+ case AUDPREPROC_MSG_ERROR_MSG_ID:
+ MM_INFO("err_index %d\n", msg[0]);
+ break;
+ case ADSP_MESSAGE_ID:
+ MM_DBG("Received ADSP event: module enable(audpreproctask)\n");
+ break;
+ default:
+ MM_ERR("unknown event %d\n", id);
+ }
+}
+
+
/* must be called with audio->lock held */
static int audqcelp_in_enable(struct audio_qcelp_in *audio)
{
@@ -253,16 +280,23 @@
if (rc < 0)
return rc;
- if (msm_adsp_enable(audio->audpre)) {
+ if (audpreproc_enable(audio->enc_id,
+ &audpre_dsp_event, audio)) {
+ MM_ERR("msm_adsp_enable(audpreproc) failed\n");
audmgr_disable(&audio->audmgr);
- MM_ERR("msm_adsp_enable(audpre) failed\n");
return -ENODEV;
}
+
+ /*update aurec session info in audpreproc layer*/
+ audio->session_info.session_id = audio->enc_id;
+ audio->session_info.sampling_freq =
+ convert_samp_index(audio->samp_rate);
+ audpreproc_update_audrec_info(&audio->session_info);
}
if (msm_adsp_enable(audio->audrec)) {
if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) {
+ audpreproc_disable(audio->enc_id, audio);
audmgr_disable(&audio->audmgr);
- msm_adsp_disable(audio->audpre);
}
MM_ERR("msm_adsp_enable(audrec) failed\n");
return -ENODEV;
@@ -288,35 +322,17 @@
wake_up(&audio->wait);
msm_adsp_disable(audio->audrec);
if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) {
- msm_adsp_disable(audio->audpre);
+ audpreproc_disable(audio->enc_id, audio);
audmgr_disable(&audio->audmgr);
+ /*reset the sampling frequency information at
+ audpreproc layer*/
+ audio->session_info.sampling_freq = 0;
+ audpreproc_update_audrec_info(&audio->session_info);
}
}
return 0;
}
-/* ------------------- dsp --------------------- */
-static void audpre_dsp_event(void *data, unsigned id, size_t len,
- void (*getevent)(void *ptr, size_t len))
-{
- uint16_t msg[2];
- getevent(msg, sizeof(msg));
-
- switch (id) {
- case AUDPREPROC_MSG_CMD_CFG_DONE_MSG:
- MM_DBG("type %d, status_flag %d\n", msg[0], msg[1]);
- break;
- case AUDPREPROC_MSG_ERROR_MSG_ID:
- MM_ERR("err_index %d\n", msg[0]);
- break;
- case ADSP_MESSAGE_ID:
- MM_DBG("Received ADSP event: module enable(audpreproctask)\n");
- break;
- default:
- MM_ERR("unknown event %d\n", id);
- }
-}
-
static void audqcelp_in_get_dsp_frames(struct audio_qcelp_in *audio)
{
struct audio_frame *frame;
@@ -557,10 +573,6 @@
}
}
-static struct msm_adsp_ops audpre_qcelp_adsp_ops = {
- .event = audpre_dsp_event,
-};
-
static struct msm_adsp_ops audrec_qcelp_adsp_ops = {
.event = audrec_dsp_event,
};
@@ -1187,12 +1199,8 @@
audqcelp_in_flush(audio);
msm_adsp_put(audio->audrec);
- if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL)
- msm_adsp_put(audio->audpre);
-
audpreproc_aenc_free(audio->enc_id);
audio->audrec = NULL;
- audio->audpre = NULL;
audio->opened = 0;
if ((audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) && \
@@ -1285,16 +1293,6 @@
goto done;
}
- if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) {
- rc = msm_adsp_get("AUDPREPROCTASK", &audio->audpre,
- &audpre_qcelp_adsp_ops, audio);
- if (rc) {
- msm_adsp_put(audio->audrec);
- audpreproc_aenc_free(audio->enc_id);
- goto done;
- }
- }
-
audio->dsp_cnt = 0;
audio->stopped = 0;
audio->wflush = 0;
@@ -1434,8 +1432,6 @@
ion_client_destroy(client);
client_create_error:
msm_adsp_put(audio->audrec);
- if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL)
- msm_adsp_put(audio->audpre);
audpreproc_aenc_free(audio->enc_id);
mutex_unlock(&audio->lock);
diff --git a/arch/arm/mach-msm/qdsp5/audio_wma.c b/arch/arm/mach-msm/qdsp5/audio_wma.c
index e28e704..276c9d4 100644
--- a/arch/arm/mach-msm/qdsp5/audio_wma.c
+++ b/arch/arm/mach-msm/qdsp5/audio_wma.c
@@ -48,6 +48,7 @@
#include <mach/iommu_domains.h>
#include <mach/qdsp5/qdsp5audppcmdi.h>
#include <mach/qdsp5/qdsp5audppmsg.h>
+#include <mach/qdsp5/qdsp5audpp.h>
#include <mach/qdsp5/qdsp5audplaycmdi.h>
#include <mach/qdsp5/qdsp5audplaymsg.h>
#include <mach/qdsp5/qdsp5rmtcmdi.h>
diff --git a/arch/arm/mach-msm/qdsp5/audio_wmapro.c b/arch/arm/mach-msm/qdsp5/audio_wmapro.c
index 87afcf0..b881c59 100644
--- a/arch/arm/mach-msm/qdsp5/audio_wmapro.c
+++ b/arch/arm/mach-msm/qdsp5/audio_wmapro.c
@@ -45,6 +45,7 @@
#include <mach/msm_adsp.h>
#include <mach/qdsp5/qdsp5audppcmdi.h>
#include <mach/qdsp5/qdsp5audppmsg.h>
+#include <mach/qdsp5/qdsp5audpp.h>
#include <mach/qdsp5/qdsp5audplaycmdi.h>
#include <mach/qdsp5/qdsp5audplaymsg.h>
#include <mach/qdsp5/qdsp5rmtcmdi.h>
diff --git a/arch/arm/mach-msm/qdsp5/audmgr.h b/arch/arm/mach-msm/qdsp5/audmgr.h
index 493306b..15dd954 100644
--- a/arch/arm/mach-msm/qdsp5/audmgr.h
+++ b/arch/arm/mach-msm/qdsp5/audmgr.h
@@ -237,82 +237,4 @@
int audmgr_close(struct audmgr *am);
int audmgr_enable(struct audmgr *am, struct audmgr_config *cfg);
int audmgr_disable(struct audmgr *am);
-
-typedef void (*audpp_event_func)(void *private, unsigned id, uint16_t *msg);
-typedef void (*audrec_event_func)(void *private, unsigned id, uint16_t *msg);
-
-/* worst case delay of 1sec for response */
-#define MSM_AUD_DECODER_WAIT_MS 1000
-#define MSM_AUD_MODE_TUNNEL 0x00000100
-#define MSM_AUD_MODE_NONTUNNEL 0x00000200
-#define MSM_AUD_DECODER_MASK 0x0000FFFF
-#define MSM_AUD_OP_MASK 0xFFFF0000
-
-/*Playback mode*/
-#define NON_TUNNEL_MODE_PLAYBACK 1
-#define TUNNEL_MODE_PLAYBACK 0
-
-enum msm_aud_decoder_state {
- MSM_AUD_DECODER_STATE_NONE = 0,
- MSM_AUD_DECODER_STATE_FAILURE = 1,
- MSM_AUD_DECODER_STATE_SUCCESS = 2,
- MSM_AUD_DECODER_STATE_CLOSE = 3,
-};
-
-int audpp_adec_alloc(unsigned dec_attrb, const char **module_name,
- unsigned *queueid);
-void audpp_adec_free(int decid);
-
-struct audpp_event_callback {
- audpp_event_func fn;
- void *private;
-};
-
-int audpp_register_event_callback(struct audpp_event_callback *eh);
-int audpp_unregister_event_callback(struct audpp_event_callback *eh);
-int is_audpp_enable(void);
-
-int audpp_enable(int id, audpp_event_func func, void *private);
-void audpp_disable(int id, void *private);
-
-int audpp_send_queue1(void *cmd, unsigned len);
-int audpp_send_queue2(void *cmd, unsigned len);
-int audpp_send_queue3(void *cmd, unsigned len);
-
-int audpp_set_volume_and_pan(unsigned id, unsigned volume, int pan);
-int audpp_pause(unsigned id, int pause);
-int audpp_flush(unsigned id);
-void audpp_avsync(int id, unsigned rate);
-unsigned audpp_avsync_sample_count(int id);
-unsigned audpp_avsync_byte_count(int id);
-int audpp_dsp_set_mbadrc(unsigned id, unsigned enable,
- audpp_cmd_cfg_object_params_mbadrc *mbadrc);
-int audpp_dsp_set_eq(unsigned id, unsigned enable,
- audpp_cmd_cfg_object_params_eqalizer *eq);
-int audpp_dsp_set_rx_iir(unsigned id, unsigned enable,
- audpp_cmd_cfg_object_params_pcm *iir);
-
-int audpp_dsp_set_rx_srs_trumedia_g
- (struct audpp_cmd_cfg_object_params_srstm_g *srstm);
-int audpp_dsp_set_rx_srs_trumedia_w
- (struct audpp_cmd_cfg_object_params_srstm_w *srstm);
-int audpp_dsp_set_rx_srs_trumedia_c
- (struct audpp_cmd_cfg_object_params_srstm_c *srstm);
-int audpp_dsp_set_rx_srs_trumedia_h
- (struct audpp_cmd_cfg_object_params_srstm_h *srstm);
-int audpp_dsp_set_rx_srs_trumedia_p
- (struct audpp_cmd_cfg_object_params_srstm_p *srstm);
-int audpp_dsp_set_rx_srs_trumedia_l
- (struct audpp_cmd_cfg_object_params_srstm_l *srstm);
-
-int audpp_dsp_set_vol_pan(unsigned id,
- audpp_cmd_cfg_object_params_volume *vol_pan);
-int audpp_dsp_set_qconcert_plus(unsigned id, unsigned enable,
- audpp_cmd_cfg_object_params_qconcert *qconcert_plus);
-int audrectask_enable(unsigned enc_type, audrec_event_func func, void *private);
-void audrectask_disable(unsigned enc_type, void *private);
-
-int audrectask_send_cmdqueue(void *cmd, unsigned len);
-int audrectask_send_bitstreamqueue(void *cmd, unsigned len);
-
#endif
diff --git a/arch/arm/mach-msm/qdsp5/audmgr_new.h b/arch/arm/mach-msm/qdsp5/audmgr_new.h
index 2453022..20e27f1 100644
--- a/arch/arm/mach-msm/qdsp5/audmgr_new.h
+++ b/arch/arm/mach-msm/qdsp5/audmgr_new.h
@@ -1,6 +1,6 @@
/* arch/arm/mach-msm/qdsp5/audmgr.h
*
- * Copyright 2008 (c) Code Aurora Forum. All rights reserved.
+ * Copyright 2008,2012 (c) Code Aurora Forum. All rights reserved.
* Copyright (C) 2008 Google, Inc.
*
* This software is licensed under the terms of the GNU General Public
@@ -194,21 +194,4 @@
int audmgr_close(struct audmgr *am);
int audmgr_enable(struct audmgr *am, struct audmgr_config *cfg);
int audmgr_disable(struct audmgr *am);
-
-typedef void (*audpp_event_func)(void *private, unsigned id, uint16_t *msg);
-
-int audpp_enable(int id, audpp_event_func func, void *private);
-void audpp_disable(int id, void *private);
-
-int audpp_send_queue1(void *cmd, unsigned len);
-int audpp_send_queue2(void *cmd, unsigned len);
-int audpp_send_queue3(void *cmd, unsigned len);
-
-int audpp_set_volume_and_pan(unsigned id, unsigned volume, int pan);
-int audpp_pause(unsigned id, int pause);
-int audpp_flush(unsigned id);
-void audpp_avsync(int id, unsigned rate);
-unsigned audpp_avsync_sample_count(int id);
-unsigned audpp_avsync_byte_count(int id);
-
#endif
diff --git a/arch/arm/mach-msm/qdsp5/audpp.c b/arch/arm/mach-msm/qdsp5/audpp.c
index 1616ad0..b4ead5c 100644
--- a/arch/arm/mach-msm/qdsp5/audpp.c
+++ b/arch/arm/mach-msm/qdsp5/audpp.c
@@ -34,6 +34,8 @@
#include <mach/qdsp5/qdsp5audppcmdi.h>
#include <mach/qdsp5/qdsp5audppmsg.h>
+#include <mach/qdsp5/qdsp5audpp.h>
+#include <mach/qdsp5v2/audio_acdbi.h>
#include <mach/debug_mm.h>
#include "evlog.h"
@@ -85,19 +87,7 @@
#define AUDPP_CMD_IIR_FLAG_DIS 0x0000
#define AUDPP_CMD_IIR_FLAG_ENA -1
-#define AUDPP_CMD_VOLUME_PAN 0
-#define AUDPP_CMD_IIR_TUNING_FILTER 1
-#define AUDPP_CMD_EQUALIZER 2
-#define AUDPP_CMD_ADRC 3
-#define AUDPP_CMD_SPECTROGRAM 4
-#define AUDPP_CMD_QCONCERT 5
-#define AUDPP_CMD_SIDECHAIN_TUNING_FILTER 6
-#define AUDPP_CMD_SAMPLING_FREQUENCY 7
-#define AUDPP_CMD_QAFX 8
-#define AUDPP_CMD_QRUMBLE 9
-#define AUDPP_CMD_MBADRC 10
-
-#define MAX_EVENT_CALLBACK_CLIENTS 1
+#define MAX_EVENT_CALLBACK_CLIENTS 2
#define AUDPP_CONCURRENCY_DEFAULT 6 /* All non tunnel mode */
#define AUDPP_MAX_DECODER_CNT 5
@@ -335,6 +325,11 @@
case ADSP_MESSAGE_ID:
MM_DBG("Received ADSP event: module enable/disable(audpptask)");
break;
+ case AUDPP_MSG_FEAT_QUERY_DM_DONE:
+ MM_INFO(" RTC ACK --> %x %x %x\n", msg[0],\
+ msg[1], msg[2]);
+ acdb_rtc_set_err(msg[2]);
+ break;
default:
MM_ERR("unhandled msg id %x\n", id);
}
diff --git a/arch/arm/mach-msm/qdsp5/audpreproc.c b/arch/arm/mach-msm/qdsp5/audpreproc.c
index 230429f..92e54f8 100644
--- a/arch/arm/mach-msm/qdsp5/audpreproc.c
+++ b/arch/arm/mach-msm/qdsp5/audpreproc.c
@@ -1,7 +1,7 @@
/*
* Common code to deal with the AUDPREPROC dsp task (audio preprocessing)
*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* Based on the audpp layer in arch/arm/mach-msm/qdsp5/audpp.c
*
@@ -23,6 +23,8 @@
#include <mach/debug_mm.h>
#include <mach/qdsp5/qdsp5audpreproc.h>
#include <mach/qdsp5/qdsp5audreccmdi.h>
+#include <mach/qdsp5v2/audio_acdbi.h>
+
static DEFINE_MUTEX(audpreproc_lock);
@@ -56,6 +58,9 @@
(1<<AUDREC_CMD_TYPE_0_INDEX_QCELP))
#endif
+#define MAX_ENC_COUNT 2
+#define MAX_EVENT_CALLBACK_CLIENTS 2
+
struct msm_adspenc_database {
unsigned num_enc;
struct msm_adspenc_info *enc_info_list;
@@ -90,15 +95,237 @@
struct audpreproc_state {
struct msm_adsp_module *mod;
+ audpreproc_event_func func[MAX_ENC_COUNT];
+ void *private[MAX_ENC_COUNT];
struct mutex *lock;
unsigned open_count;
unsigned enc_inuse;
+ struct audpreproc_event_callback *cb_tbl[MAX_EVENT_CALLBACK_CLIENTS];
};
+static struct audrec_session_info session_info;
+
static struct audpreproc_state the_audpreproc_state = {
.lock = &audpreproc_lock,
};
+/* DSP preproc event handler */
+static void audpreproc_dsp_event(void *data, unsigned id, size_t len,
+ void (*getevent)(void *ptr, size_t len))
+{
+ struct audpreproc_state *audpreproc = data;
+ uint16_t msg[2];
+ MM_ERR("audpreproc_dsp_event %id", id);
+
+ getevent(msg, sizeof(msg));
+
+ switch (id) {
+ case AUDPREPROC_MSG_CMD_CFG_DONE_MSG:
+ MM_DBG("type %d, status_flag %d\n", msg[0], msg[1]);
+ if (audpreproc->func[0])
+ audpreproc->func[0](
+ audpreproc->private[0], id,
+ &msg);
+ break;
+ case AUDPREPROC_MSG_ERROR_MSG_ID:
+ MM_INFO("err_index %d\n", msg[0]);
+ if (audpreproc->func[0])
+ audpreproc->func[0](
+ audpreproc->private[0], id,
+ &msg);
+ break;
+ case ADSP_MESSAGE_ID:
+ MM_DBG("Received ADSP event: module enable(audpreproctask)\n");
+ if (audpreproc->func[0])
+ audpreproc->func[0](
+ audpreproc->private[0], id,
+ &msg);
+ break;
+ case AUDPREPROC_MSG_FEAT_QUERY_DM_DONE:
+ {
+ uint16_t msg[3];
+ getevent(msg, sizeof(msg));
+ MM_INFO("RTC ACK --> %x %x %x\n", msg[0], msg[1], msg[2]);
+ acdb_rtc_set_err(msg[2]);
+ }
+ break;
+ default:
+ MM_ERR("unknown event %d\n", id);
+ }
+ return;
+}
+
+static struct msm_adsp_ops adsp_ops = {
+ .event = audpreproc_dsp_event,
+};
+
+/* EXPORTED API's */
+int audpreproc_enable(int enc_id, audpreproc_event_func func, void *private)
+{
+ struct audpreproc_state *audpreproc = &the_audpreproc_state;
+ int res = 0;
+ uint16_t msg[2];
+ int n = 0;
+ MM_DBG("audpreproc_enable %d\n", enc_id);
+
+ if (enc_id < 0 || enc_id > (MAX_ENC_COUNT - 1))
+ return -EINVAL;
+
+ mutex_lock(audpreproc->lock);
+ if (audpreproc->func[enc_id]) {
+ res = -EBUSY;
+ goto out;
+ }
+
+ audpreproc->func[enc_id] = func;
+ audpreproc->private[enc_id] = private;
+
+ /* First client to enable preproc task */
+ if (audpreproc->open_count++ == 0) {
+ MM_DBG("Get AUDPREPROCTASK\n");
+ res = msm_adsp_get("AUDPREPROCTASK", &audpreproc->mod,
+ &adsp_ops, audpreproc);
+ if (res < 0) {
+ MM_ERR("Can not get AUDPREPROCTASK\n");
+ audpreproc->open_count = 0;
+ audpreproc->func[enc_id] = NULL;
+ audpreproc->private[enc_id] = NULL;
+ goto out;
+ }
+ if (msm_adsp_enable(audpreproc->mod)) {
+ audpreproc->open_count = 0;
+ audpreproc->func[enc_id] = NULL;
+ audpreproc->private[enc_id] = NULL;
+ msm_adsp_put(audpreproc->mod);
+ audpreproc->mod = NULL;
+ res = -ENODEV;
+ goto out;
+ }
+ }
+ msg[0] = AUDPREPROC_MSG_STATUS_FLAG_ENA;
+ /* Generate audpre enabled message for registered clients */
+ for (n = 0; n < MAX_EVENT_CALLBACK_CLIENTS; ++n) {
+ if (audpreproc->cb_tbl[n] &&
+ audpreproc->cb_tbl[n]->fn) {
+ audpreproc->cb_tbl[n]->fn( \
+ audpreproc->cb_tbl[n]->private,\
+ AUDPREPROC_MSG_CMD_CFG_DONE_MSG,
+ (void *) &msg);
+ }
+ }
+ res = 0;
+out:
+ mutex_unlock(audpreproc->lock);
+ return res;
+}
+EXPORT_SYMBOL(audpreproc_enable);
+
+
+void audpreproc_disable(int enc_id, void *private)
+{
+ struct audpreproc_state *audpreproc = &the_audpreproc_state;
+ uint16_t msg[2];
+ int n = 0;
+
+ if (enc_id < 0 || enc_id > (MAX_ENC_COUNT - 1))
+ return;
+
+ mutex_lock(audpreproc->lock);
+ if (!audpreproc->func[enc_id])
+ goto out;
+ if (audpreproc->private[enc_id] != private)
+ goto out;
+
+ audpreproc->func[enc_id] = NULL;
+ audpreproc->private[enc_id] = NULL;
+
+ /* Last client then disable preproc task */
+ if (--audpreproc->open_count == 0) {
+ msm_adsp_disable(audpreproc->mod);
+ MM_DBG("Put AUDPREPROCTASK\n");
+ msm_adsp_put(audpreproc->mod);
+ audpreproc->mod = NULL;
+ }
+ msg[0] = AUDPREPROC_MSG_STATUS_FLAG_DIS;
+ /* Generate audpre enabled message for registered clients */
+ for (n = 0; n < MAX_EVENT_CALLBACK_CLIENTS; ++n) {
+ if (audpreproc->cb_tbl[n] &&
+ audpreproc->cb_tbl[n]->fn) {
+ audpreproc->cb_tbl[n]->fn( \
+ audpreproc->cb_tbl[n]->private,\
+ AUDPREPROC_MSG_CMD_CFG_DONE_MSG,
+ (void *) &msg);
+ }
+ }
+out:
+ mutex_unlock(audpreproc->lock);
+ return;
+}
+EXPORT_SYMBOL(audpreproc_disable);
+
+int audpreproc_update_audrec_info(
+ struct audrec_session_info *audrec_session_info)
+{
+ if (!audrec_session_info) {
+ MM_ERR("error in audrec session info address\n");
+ return -EINVAL;
+ }
+ if (audrec_session_info->session_id < MAX_ENC_COUNT) {
+ memcpy(&session_info,
+ audrec_session_info,
+ sizeof(struct audrec_session_info));
+ return 0;
+ }
+ return -EINVAL;
+}
+EXPORT_SYMBOL(audpreproc_update_audrec_info);
+
+int get_audrec_session_info(struct audrec_session_info *info)
+{
+ if (!info) {
+ MM_ERR("error in audrec session info address\n");
+ return -EINVAL;
+ }
+
+ if (the_audpreproc_state.open_count == 0) {
+ MM_ERR("No aud pre session active\n");
+ return -EINVAL;
+ }
+
+ memcpy(info, &session_info, sizeof(struct audrec_session_info));
+
+ return 0;
+}
+EXPORT_SYMBOL(get_audrec_session_info);
+
+int audpreproc_register_event_callback(struct audpreproc_event_callback *ecb)
+{
+ struct audpreproc_state *audpreproc = &the_audpreproc_state;
+ int i;
+
+ for (i = 0; i < MAX_EVENT_CALLBACK_CLIENTS; ++i) {
+ if (NULL == audpreproc->cb_tbl[i]) {
+ audpreproc->cb_tbl[i] = ecb;
+ return 0;
+ }
+ }
+ return -EINVAL;
+}
+EXPORT_SYMBOL(audpreproc_register_event_callback);
+
+int audpreproc_unregister_event_callback(struct audpreproc_event_callback *ecb)
+{
+ struct audpreproc_state *audpreproc = &the_audpreproc_state;
+ int i;
+
+ for (i = 0; i < MAX_EVENT_CALLBACK_CLIENTS; ++i) {
+ if (ecb == audpreproc->cb_tbl[i]) {
+ audpreproc->cb_tbl[i] = NULL;
+ return 0;
+ }
+ }
+ return -EINVAL;
+}
/* enc_type = supported encode format *
* like pcm, aac, sbc, evrc, qcelp, amrnb etc ... *
*/
@@ -167,3 +394,37 @@
}
EXPORT_SYMBOL(audpreproc_aenc_free);
+
+int audpreproc_dsp_set_agc(
+ audpreproc_cmd_cfg_agc_params *agc_cfg,
+ unsigned len)
+{
+ return msm_adsp_write(the_audpreproc_state.mod,
+ QDSP_uPAudPreProcCmdQueue, agc_cfg, len);
+}
+EXPORT_SYMBOL(audpreproc_dsp_set_agc);
+
+int audpreproc_dsp_set_ns(
+ audpreproc_cmd_cfg_ns_params *ns_cfg,
+ unsigned len)
+{
+ return msm_adsp_write(the_audpreproc_state.mod,
+ QDSP_uPAudPreProcCmdQueue, ns_cfg, len);
+}
+EXPORT_SYMBOL(audpreproc_dsp_set_ns);
+
+int audpreproc_dsp_set_iir(
+ audpreproc_cmd_cfg_iir_tuning_filter_params *iir_cfg,
+ unsigned len)
+{
+ return msm_adsp_write(the_audpreproc_state.mod,
+ QDSP_uPAudPreProcCmdQueue, iir_cfg, len);
+}
+EXPORT_SYMBOL(audpreproc_dsp_set_iir);
+
+int audpreproc_send_preproccmdqueue(void *cmd, unsigned len)
+{
+ return msm_adsp_write(the_audpreproc_state.mod,
+ QDSP_uPAudPreProcCmdQueue, cmd, len);
+}
+EXPORT_SYMBOL(audpreproc_send_preproccmdqueue);
diff --git a/arch/arm/mach-msm/qdsp5/audrec.c b/arch/arm/mach-msm/qdsp5/audrec.c
index d5cb168..e238e32 100644
--- a/arch/arm/mach-msm/qdsp5/audrec.c
+++ b/arch/arm/mach-msm/qdsp5/audrec.c
@@ -2,7 +2,7 @@
*
* common code to deal with the AUDREC dsp task (audio recording)
*
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009,2012 Code Aurora Forum. All rights reserved.
*
* Based on the audpp layer in arch/arm/mach-msm/qdsp5/audpp.c
*
@@ -34,6 +34,7 @@
#include <mach/qdsp5/qdsp5audreccmdi.h>
#include <mach/qdsp5/qdsp5audrecmsg.h>
+#include <mach/qdsp5/qdsp5audpreproc.h>
#include "audmgr.h"
#include <mach/debug_mm.h>
diff --git a/arch/arm/mach-msm/qdsp5/snd_cad.c b/arch/arm/mach-msm/qdsp5/snd_cad.c
index e0ab781..c0efa3b 100644
--- a/arch/arm/mach-msm/qdsp5/snd_cad.c
+++ b/arch/arm/mach-msm/qdsp5/snd_cad.c
@@ -29,6 +29,7 @@
#include <mach/board.h>
#include <mach/msm_rpcrouter.h>
#include <mach/debug_mm.h>
+#include <linux/debugfs.h>
struct snd_cad_ctxt {
struct mutex lock;
@@ -59,6 +60,7 @@
#define SND_CAD_SET_DEVICE_PROC 40
#define SND_CAD_SET_VOLUME_PROC 39
+#define MAX_SND_ACTIVE_DEVICE 2
struct rpc_cad_set_device_args {
struct cad_devices_type device;
@@ -90,6 +92,111 @@
struct cad_endpoint *get_cad_endpoints(int *size);
+#ifdef CONFIG_DEBUG_FS
+static struct dentry *dentry;
+
+static int rtc_getdevice_dbg_open(struct inode *inode, struct file *file)
+{
+ file->private_data = inode->i_private;
+ MM_INFO("debug intf %s\n", (char *) file->private_data);
+ return 0;
+}
+
+static ssize_t rtc_getdevice_dbg_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ int n = 0;
+ static char *buffer;
+ static char *swap_buf;
+ const int debug_bufmax = 1024;
+ int swap_count = 0;
+ int rc = 0;
+ int dev_count = 0;
+ int dev_id = 0;
+ struct msm_cad_endpoints *msm_cad_epts = the_snd.cad_epts;
+ struct cad_endpoint *cad_epts;
+
+ buffer = kmalloc(sizeof(char) * 1024, GFP_KERNEL);
+ if (buffer == NULL) {
+ MM_ERR("Memory allocation failed for buffer failed\n");
+ return -EFAULT;
+ }
+
+ swap_buf = kmalloc(sizeof(char) * 1024, GFP_KERNEL);
+ if (swap_buf == NULL) {
+ MM_ERR("Memory allocation failed for swap buffer failed\n");
+ kfree(buffer);
+ return -EFAULT;
+ }
+
+ if (msm_cad_epts->num <= 0) {
+ dev_count = 0;
+ n = scnprintf(buffer, debug_bufmax, "DEV_NO:0x%x\n",
+ msm_cad_epts->num);
+ } else {
+ for (dev_id = 0; dev_id < msm_cad_epts->num; dev_id++) {
+ cad_epts = &msm_cad_epts->endpoints[dev_id];
+ if (IS_ERR(cad_epts)) {
+ MM_ERR("invalid snd endpoint for dev_id %d\n",
+ dev_id);
+ rc = PTR_ERR(cad_epts);
+ continue;
+ }
+
+ if ((cad_epts->id != curr_dev.tx_dev) &&
+ (cad_epts->id != curr_dev.rx_dev))
+ continue;
+
+ n += scnprintf(swap_buf + n, debug_bufmax - n,
+ "ACDB_ID:0x%x;CAPB:0x%x\n",
+ cad_epts->id,
+ cad_epts->capability);
+ dev_count++;
+ MM_DBG("RTC Get Device %x Capb %x Dev Count %x\n",
+ dev_id, cad_epts->capability,
+ dev_count);
+
+ }
+ }
+ swap_count = scnprintf(buffer, debug_bufmax, \
+ "DEV_NO:0x%x\n", dev_count);
+
+ memcpy(buffer+swap_count, swap_buf, n*sizeof(char));
+ n = n+swap_count;
+
+ buffer[n] = 0;
+ rc = simple_read_from_buffer(buf, count, ppos, buffer, n);
+ kfree(buffer);
+ kfree(swap_buf);
+ return rc;
+}
+
+static const struct file_operations rtc_acdb_debug_fops = {
+ .open = rtc_getdevice_dbg_open,
+ .read = rtc_getdevice_dbg_read
+};
+
+static int rtc_debugfs_create_entry(void)
+{
+ int rc = 0;
+ char name[sizeof "rtc_get_device"+1];
+
+ snprintf(name, sizeof name, "rtc_get_device");
+ dentry = debugfs_create_file(name, S_IFREG | S_IRUGO,
+ NULL, NULL, &rtc_acdb_debug_fops);
+ if (IS_ERR(dentry)) {
+ MM_ERR("debugfs_create_file failed\n");
+ rc = PTR_ERR(dentry);
+ }
+ return rc;
+}
+#else
+static int rtc_debugfs_create_entry()
+{
+ return 0;
+}
+#endif
+
static inline int check_mute(int mute)
{
return (mute == SND_MUTE_MUTED ||
@@ -468,6 +575,16 @@
misc_deregister(&snd_cad_misc);
}
+#ifdef CONFIG_DEBUG_FS
+ rc = rtc_debugfs_create_entry();
+ if (rc) {
+ device_remove_file(snd_cad_misc.this_device,
+ &dev_attr_volume);
+ device_remove_file(snd_cad_misc.this_device,
+ &dev_attr_device);
+ misc_deregister(&snd_cad_misc);
+ }
+#endif
return rc;
}
diff --git a/sound/soc/msm/msm-pcm.h b/sound/soc/msm/msm-pcm.h
index 6e1325b..867116a 100644
--- a/sound/soc/msm/msm-pcm.h
+++ b/sound/soc/msm/msm-pcm.h
@@ -27,7 +27,7 @@
#include <mach/qdsp5/qdsp5audrecmsg.h>
#include <mach/qdsp5/qdsp5audpreproccmdi.h>
#include <mach/qdsp5/qdsp5audpreprocmsg.h>
-
+#include <mach/qdsp5/qdsp5audpp.h>
#include <../arch/arm/mach-msm/qdsp5/adsp.h>
#include <../arch/arm/mach-msm/qdsp5/audmgr.h>