Merge "ASoC: msm8960: Fix button detection voltage thresholds" into msm-3.4
diff --git a/Documentation/devicetree/bindings/leds/leds-qpnp.txt b/Documentation/devicetree/bindings/leds/leds-qpnp.txt
new file mode 100644
index 0000000..51bf9e6
--- /dev/null
+++ b/Documentation/devicetree/bindings/leds/leds-qpnp.txt
@@ -0,0 +1,57 @@
+Qualcomm QPNP Leds
+
+QPNP (Qualcomm Plug N Play) LEDs driver is used for
+controlling LEDs that are part of PMIC on Qualcomm reference
+platforms. The PMIC is connected to Host processor via
+SPMI bus. This driver supports various LED modules such as
+WLED (white LED), RGB LED and flash LED. The first version of
+the driver supports WLED and other features are added in the
+next versions.
+
+Required Properties:
+- compatible	: should be "qcom,leds-qpnp"
+
+Each LED module is represented as a node of "leds-qpnp". This
+node will furthur contain the type of LED supported and its
+properties.
+
+Required properties:
+- qcom,id		: must be one of values supported in enum qpnp_led
+- qcom,label		: type of led that will be used, ie "wled"
+- qcom,max-current	: maximum current that the LED can sustain
+= qcom,name		: name the led will be called by in sysfs entry
+
+WLED is primarily used as display backlight. Display subsystem uses
+LED triggers for WLED to control the brightness as needed.
+
+Optional properties for WLED:
+- qcom,num-strings: number of wled strings supported
+- qcom,ovp_val: over voltage protection threshold,
+		follows enum wled_ovp_threshold
+- qcom,boost_curr_lim: boot currnet limit, follows enum wled_current_bost_limit
+- qcom,ctrl_delay_us: delay in activation of led
+- qcom,dig_mod_gen_en: digital module generator
+- qcom,cs_out_en: current sink output enable
+- qcom,op_fdbck: selection of output as feedback for the boost
+- qcom,cp_select: high pole capacitance
+- linux,default-trigger: trigger the led from external modules such as display
+- qcom,default-state:  default state of the led, should be "on" or "off"
+
+Example:
+
+	qcom,leds@d800 {
+			compatible = "qcom,leds-qpnp";
+			reg = <0xD800 0x100>;
+			linux,default-trigger = "bkl-trigger"
+			qcom,label = "wled";
+			qcom,cs-out-en;
+			qcom,op-fdbck;
+			qcom,default-state "off";
+			qcom,max-current = <25>;
+			qcom,ctrl-delay-us = <0>;
+			qcom,boost-curr-lim = <3>;
+			qcom,cp-sel = <0>;
+			qcom,switch-freq = <2>;
+			qcom,ovp-val = <2>;
+			qcom,num-strings = <1>;
+	}
diff --git a/arch/arm/mach-msm/board-8974-gpiomux.c b/arch/arm/mach-msm/board-8974-gpiomux.c
index 8aafeb5..a2087e4 100644
--- a/arch/arm/mach-msm/board-8974-gpiomux.c
+++ b/arch/arm/mach-msm/board-8974-gpiomux.c
@@ -206,6 +206,155 @@
 	},
 };
 
+static struct gpiomux_setting cam_settings[] = {
+	{
+		.func = GPIOMUX_FUNC_1, /*active 1*/
+		.drv = GPIOMUX_DRV_2MA,
+		.pull = GPIOMUX_PULL_NONE,
+	},
+
+	{
+		.func = GPIOMUX_FUNC_1, /*suspend*/
+		.drv = GPIOMUX_DRV_2MA,
+		.pull = GPIOMUX_PULL_DOWN,
+	},
+
+	{
+		.func = GPIOMUX_FUNC_1, /*i2c suspend*/
+		.drv = GPIOMUX_DRV_2MA,
+		.pull = GPIOMUX_PULL_KEEPER,
+	},
+};
+
+static struct msm_gpiomux_config msm_sensor_configs[] __initdata = {
+	{
+		.gpio = 15, /* CAM_MCLK0 */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[0],
+			[GPIOMUX_SUSPENDED] = &cam_settings[1],
+		},
+	},
+	{
+		.gpio = 16, /* CAM_MCLK1 */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[0],
+			[GPIOMUX_SUSPENDED] = &cam_settings[1],
+		},
+	},
+	{
+		.gpio = 17, /* CAM_MCLK2 */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[0],
+			[GPIOMUX_SUSPENDED] = &cam_settings[1],
+		},
+	},
+	{
+		.gpio = 18, /* WEBCAM1_RESET_N / CAM_MCLK3 */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[0],
+			[GPIOMUX_SUSPENDED] = &cam_settings[1],
+		},
+	},
+	{
+		.gpio = 19, /* CCI_I2C_SDA0 */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[0],
+			[GPIOMUX_SUSPENDED] = &cam_settings[2],
+		},
+	},
+	{
+		.gpio = 20, /* CCI_I2C_SCL0 */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[0],
+			[GPIOMUX_SUSPENDED] = &cam_settings[2],
+		},
+	},
+	{
+		.gpio = 21, /* CCI_I2C_SDA1 */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[0],
+			[GPIOMUX_SUSPENDED] = &cam_settings[2],
+		},
+	},
+	{
+		.gpio = 22, /* CCI_I2C_SCL1 */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[0],
+			[GPIOMUX_SUSPENDED] = &cam_settings[2],
+		},
+	},
+	{
+		.gpio = 23, /* FLASH_LED_EN */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[0],
+			[GPIOMUX_SUSPENDED] = &cam_settings[1],
+		},
+	},
+	{
+		.gpio = 24, /* FLASH_LED_NOW */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[0],
+			[GPIOMUX_SUSPENDED] = &cam_settings[1],
+		},
+	},
+	{
+		.gpio = 25, /* WEBCAM2_RESET_N */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[0],
+			[GPIOMUX_SUSPENDED] = &cam_settings[1],
+		},
+	},
+	{
+		.gpio = 26, /* CAM_IRQ */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[0],
+			[GPIOMUX_SUSPENDED] = &cam_settings[1],
+		},
+	},
+	{
+		.gpio = 27, /* OIS_SYNC */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[0],
+			[GPIOMUX_SUSPENDED] = &cam_settings[1],
+		},
+	},
+	{
+		.gpio = 28, /* WEBCAM1_STANDBY */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[0],
+			[GPIOMUX_SUSPENDED] = &cam_settings[1],
+		},
+	},
+	{
+		.gpio = 89, /* CAM1_STANDBY_N */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[0],
+			[GPIOMUX_SUSPENDED] = &cam_settings[1],
+		},
+	},
+	{
+		.gpio = 90, /* CAM1_RST_N */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[0],
+			[GPIOMUX_SUSPENDED] = &cam_settings[1],
+		},
+	},
+	{
+		.gpio = 91, /* CAM2_STANDBY_N */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[0],
+			[GPIOMUX_SUSPENDED] = &cam_settings[1],
+		},
+	},
+	{
+		.gpio = 92, /* CAM2_RST_N */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[0],
+			[GPIOMUX_SUSPENDED] = &cam_settings[1],
+		},
+	},
+};
+
 void __init msm_8974_init_gpiomux(void)
 {
 	int rc;
@@ -225,4 +374,6 @@
 			ARRAY_SIZE(msm8974_slimbus_config));
 
 	msm_gpiomux_install(msm_touch_configs, ARRAY_SIZE(msm_touch_configs));
+
+	msm_gpiomux_install(msm_sensor_configs, ARRAY_SIZE(msm_sensor_configs));
 }
diff --git a/arch/arm/mach-msm/board-msm7627a-camera.c b/arch/arm/mach-msm/board-msm7627a-camera.c
index 59b3162..d1d85fc 100644
--- a/arch/arm/mach-msm/board-msm7627a-camera.c
+++ b/arch/arm/mach-msm/board-msm7627a-camera.c
@@ -396,7 +396,7 @@
 		sensor_board_info_ov8825.num_vreg = 0;
 
 	}
-	if (machine_is_msm8625_evb()
+	if (machine_is_msm8625_evb() || machine_is_msm7627a_evb()
 			|| machine_is_msm8625_evt()) {
 		sensor_board_info_ov7692.cam_vreg =
 			ov7692_gpio_vreg;
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index fac3b1c..e21a645 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -5113,27 +5113,26 @@
 	CLK_LOOKUP("csi_src_clk", csi0_clk_src.c,	"fda08000.qcom,csid"),
 	CLK_LOOKUP("csi_phy_clk", camss_csi0phy_clk.c,	"fda08000.qcom,csid"),
 	CLK_LOOKUP("csi_clk", camss_csi0_clk.c,		"fda08000.qcom,csid"),
+	CLK_LOOKUP("csi_pix_clk", camss_csi0pix_clk.c,	"fda08000.qcom,csid"),
+	CLK_LOOKUP("csi_rdi_clk", camss_csi0rdi_clk.c,	"fda08000.qcom,csid"),
 	CLK_LOOKUP("csi_ahb_clk", camss_csi1_ahb_clk.c,	"fda08400.qcom,csid"),
 	CLK_LOOKUP("csi_src_clk", csi1_clk_src.c,	"fda08400.qcom,csid"),
 	CLK_LOOKUP("csi_phy_clk", camss_csi1phy_clk.c,	"fda08400.qcom,csid"),
 	CLK_LOOKUP("csi_clk", camss_csi1_clk.c,		"fda08400.qcom,csid"),
+	CLK_LOOKUP("csi_pix_clk", camss_csi1pix_clk.c,	"fda08400.qcom,csid"),
+	CLK_LOOKUP("csi_rdi_clk", camss_csi1rdi_clk.c,	"fda08400.qcom,csid"),
 	CLK_LOOKUP("csi_ahb_clk", camss_csi2_ahb_clk.c,	"fda08800.qcom,csid"),
 	CLK_LOOKUP("csi_src_clk", csi2_clk_src.c,	"fda08800.qcom,csid"),
 	CLK_LOOKUP("csi_phy_clk", camss_csi2phy_clk.c,	"fda08800.qcom,csid"),
 	CLK_LOOKUP("csi_clk", camss_csi2_clk.c,		"fda08800.qcom,csid"),
+	CLK_LOOKUP("csi_pix_clk", camss_csi2pix_clk.c,	"fda08800.qcom,csid"),
+	CLK_LOOKUP("csi_rdi_clk", camss_csi2rdi_clk.c,	"fda08800.qcom,csid"),
 	CLK_LOOKUP("csi_ahb_clk", camss_csi3_ahb_clk.c,	"fda08c00.qcom,csid"),
 	CLK_LOOKUP("csi_src_clk", csi3_clk_src.c,	"fda08c00.qcom,csid"),
 	CLK_LOOKUP("csi_phy_clk", camss_csi3phy_clk.c,	"fda08c00.qcom,csid"),
 	CLK_LOOKUP("csi_clk", camss_csi3_clk.c,		"fda08c00.qcom,csid"),
-	/* ISPIF clocks */
-	CLK_LOOKUP("csi0_pix_clk", camss_csi0pix_clk.c,	"fda0a000.qcom,ispif"),
-	CLK_LOOKUP("csi0_rdi_clk", camss_csi0rdi_clk.c,	"fda0a000.qcom,ispif"),
-	CLK_LOOKUP("csi1_pix_clk", camss_csi1pix_clk.c,	"fda0a000.qcom,ispif"),
-	CLK_LOOKUP("csi1_rdi_clk", camss_csi1rdi_clk.c,	"fda0a000.qcom,ispif"),
-	CLK_LOOKUP("csi2_pix_clk", camss_csi2pix_clk.c,	"fda0a000.qcom,ispif"),
-	CLK_LOOKUP("csi2_rdi_clk", camss_csi2rdi_clk.c,	"fda0a000.qcom,ispif"),
-	CLK_LOOKUP("csi3_pix_clk", camss_csi3pix_clk.c,	"fda0a000.qcom,ispif"),
-	CLK_LOOKUP("csi3_rdi_clk", camss_csi3rdi_clk.c,	"fda0a000.qcom,ispif"),
+	CLK_LOOKUP("csi_pix_clk", camss_csi3pix_clk.c,	"fda08c00.qcom,csid"),
+	CLK_LOOKUP("csi_rdi_clk", camss_csi3rdi_clk.c,	"fda08c00.qcom,csid"),
 	/*VFE clocks*/
 	CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
 					"fda10000.qcom,vfe"),
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index e7d652b..0331919 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -1851,6 +1851,7 @@
 	/* Part number for 1.2GHz part */
 	case 0x773:
 	case 0x774:
+	case 0x779:
 	case 0x781:
 	case 0x8D1:
 		cpu = MSM8625A;
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index 0511225..0867c1d 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -308,6 +308,19 @@
 	uint16_t i2c_queue;
 };
 
+enum msm_camera_i2c_cmd_type {
+	MSM_CAMERA_I2C_CMD_WRITE,
+	MSM_CAMERA_I2C_CMD_POLL,
+};
+
+struct msm_camera_i2c_reg_conf {
+	uint16_t reg_addr;
+	uint16_t reg_data;
+	enum msm_camera_i2c_data_type dt;
+	enum msm_camera_i2c_cmd_type cmd_type;
+	int16_t mask;
+};
+
 struct msm_camera_cci_i2c_write_cfg {
 	struct msm_camera_i2c_reg_conf *reg_conf_tbl;
 	enum msm_camera_i2c_reg_addr_type addr_type;
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 89648fe..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_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.c b/arch/arm/mach-msm/qdsp5/audmgr.c
index 231a28c..666323b 100644
--- a/arch/arm/mach-msm/qdsp5/audmgr.c
+++ b/arch/arm/mach-msm/qdsp5/audmgr.c
@@ -3,7 +3,7 @@
  * interface to "audmgr" service on the baseband cpu
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 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
@@ -35,6 +35,10 @@
 #define STATE_ENABLED   3
 #define STATE_DISABLING 4
 #define STATE_ERROR	5
+#define MAX_DEVICE_INFO_CALLBACK 1
+#define SESSION_VOICE 0
+#define SESSION_PLAYBACK 1
+#define SESSION_RECORDING 2
 
 /* store information used across complete audmgr sessions */
 struct audmgr_global {
@@ -42,6 +46,9 @@
 	struct msm_rpc_endpoint *ept;
 	struct task_struct *task;
 	uint32_t rpc_version;
+	int cad;
+	struct device_info_callback *device_cb[MAX_DEVICE_INFO_CALLBACK];
+
 };
 static DEFINE_MUTEX(audmgr_lock);
 
@@ -49,6 +56,59 @@
 	.lock = &audmgr_lock,
 };
 
+static void audmgr_rpc_connect(struct audmgr_global *amg)
+{
+	amg->cad = 0;
+	amg->ept = msm_rpc_connect_compatible(AUDMGR_PROG,
+			AUDMGR_VERS_COMP_VER3,
+			MSM_RPC_UNINTERRUPTIBLE);
+	if (IS_ERR(amg->ept)) {
+		MM_DBG("connect failed with current VERS"\
+				"= %x, trying again with  Cad API\n",
+				AUDMGR_VERS_COMP_VER3);
+		amg->ept = msm_rpc_connect_compatible(AUDMGR_PROG,
+				AUDMGR_VERS_COMP_VER4,
+				MSM_RPC_UNINTERRUPTIBLE);
+		if (IS_ERR(amg->ept)) {
+			amg->ept = msm_rpc_connect_compatible(AUDMGR_PROG,
+					AUDMGR_VERS_COMP_VER2,
+					MSM_RPC_UNINTERRUPTIBLE);
+			if (IS_ERR(amg->ept)) {
+				MM_ERR("connect failed with current VERS" \
+					"= %x, trying again with another API\n",
+					AUDMGR_VERS_COMP_VER2);
+				amg->ept = msm_rpc_connect_compatible(
+						AUDMGR_PROG,
+						AUDMGR_VERS_COMP,
+						MSM_RPC_UNINTERRUPTIBLE);
+				if (IS_ERR(amg->ept)) {
+					MM_ERR("connect failed with current" \
+						"VERS=%x, trying again with" \
+						"another API\n",
+						AUDMGR_VERS_COMP);
+					amg->ept = msm_rpc_connect(AUDMGR_PROG,
+						AUDMGR_VERS,
+						MSM_RPC_UNINTERRUPTIBLE);
+					amg->rpc_version = AUDMGR_VERS;
+				} else
+					amg->rpc_version = AUDMGR_VERS_COMP;
+			} else
+				amg->rpc_version = AUDMGR_VERS_COMP_VER2;
+		} else {
+			amg->rpc_version = AUDMGR_VERS_COMP_VER4;
+			amg->cad = 1;
+		}
+	} else
+		amg->rpc_version = AUDMGR_VERS_COMP_VER3;
+
+	if (IS_ERR(amg->ept)) {
+		amg->ept = NULL;
+		MM_ERR("failed to connect to audmgr svc\n");
+	}
+
+	return;
+}
+
 static void rpc_ack(struct msm_rpc_endpoint *ept, uint32_t xid)
 {
 	uint32_t rep[6];
@@ -64,34 +124,45 @@
 }
 
 static void process_audmgr_callback(struct audmgr_global *amg,
-				   struct rpc_audmgr_cb_func_ptr *args,
-				   int len)
+				   void *args, int len)
 {
 	struct audmgr *am;
+	int i = 0;
+	struct rpc_audmgr_cb_device_info *temp;
 
-	/* Allow only if complete arguments recevied */
-	if (len < (sizeof(struct rpc_audmgr_cb_func_ptr)))
+	/* Allow only if complete arguments recevied*/
+	if (len < MIN_RPC_DATA_LENGTH)
 		return;
 
 	/* Allow only if valid argument */
-	if (be32_to_cpu(args->set_to_one) != 1)
+	if (be32_to_cpu(((struct rpc_audmgr_cb_common *)args)->set_to_one) != 1)
 		return;
 
-	am = (struct audmgr *) be32_to_cpu(args->client_data);
-
-	if (!am)
-		return;
-
-	switch (be32_to_cpu(args->status)) {
+	switch (be32_to_cpu(((struct rpc_audmgr_cb_common *)args)->status)) {
 	case RPC_AUDMGR_STATUS_READY:
-		am->handle = be32_to_cpu(args->u.handle);
+		am = (struct audmgr *) be32_to_cpu(
+			((struct rpc_audmgr_cb_ready *)args)->client_data);
+		if (!am)
+			return;
+		am->handle = be32_to_cpu(
+				((struct rpc_audmgr_cb_ready *)args)->u.handle);
 		MM_INFO("rpc READY handle=0x%08x\n", am->handle);
 		break;
 	case RPC_AUDMGR_STATUS_CODEC_CONFIG: {
-		uint32_t volume;
-		volume = be32_to_cpu(args->u.volume);
-		MM_INFO("rpc CODEC_CONFIG volume=0x%08x\n", volume);
-		am->state = STATE_ENABLED;
+		MM_INFO("rpc CODEC_CONFIG\n");
+		am = (struct audmgr *) be32_to_cpu(
+			((struct rpc_audmgr_cb_ready *)args)->client_data);
+		if (!am)
+			return;
+		if (am->state != STATE_ENABLED)
+			am->state = STATE_ENABLED;
+		while ((amg->device_cb[i] != NULL) &&
+				(i < MAX_DEVICE_INFO_CALLBACK) &&
+				(amg->cad)) {
+			amg->device_cb[i]->func(&(am->evt),
+					amg->device_cb[i]->private);
+			i++;
+		}
 		wake_up(&am->wait);
 		break;
 	}
@@ -109,14 +180,51 @@
 		break;
 	case RPC_AUDMGR_STATUS_DISABLED:
 		MM_ERR("DISABLED\n");
+		am = (struct audmgr *) be32_to_cpu(
+			((struct rpc_audmgr_cb_ready *)args)->client_data);
+		if (!am)
+			return;
 		am->state = STATE_DISABLED;
 		wake_up(&am->wait);
 		break;
 	case RPC_AUDMGR_STATUS_ERROR:
 		MM_ERR("ERROR?\n");
+		am = (struct audmgr *) be32_to_cpu(
+			((struct rpc_audmgr_cb_ready *)args)->client_data);
+		if (!am)
+			return;
 		am->state = STATE_ERROR;
 		wake_up(&am->wait);
 		break;
+	case RPC_AUDMGR_STATUS_DEVICE_INFO:
+		MM_INFO("rpc DEVICE_INFO\n");
+		if (!amg->cad)
+			break;
+		temp = (struct rpc_audmgr_cb_device_info *)args;
+		am = (struct audmgr *) be32_to_cpu(temp->client_data);
+		if (!am)
+			return;
+		if (am->evt.session_info == SESSION_PLAYBACK) {
+			am->evt.dev_type.rx_device =
+					be32_to_cpu(temp->d.rx_device);
+			am->evt.dev_type.tx_device = 0;
+			am->evt.acdb_id = am->evt.dev_type.rx_device;
+		} else if (am->evt.session_info == SESSION_RECORDING) {
+			am->evt.dev_type.rx_device = 0;
+			am->evt.dev_type.tx_device =
+					be32_to_cpu(temp->d.tx_device);
+			am->evt.acdb_id = am->evt.dev_type.tx_device;
+		}
+		am->evt.dev_type.ear_mute =
+					be32_to_cpu(temp->d.ear_mute);
+		am->evt.dev_type.mic_mute =
+					be32_to_cpu(temp->d.mic_mute);
+		am->evt.dev_type.volume =
+					be32_to_cpu(temp->d.volume);
+		break;
+	case RPC_AUDMGR_STATUS_DEVICE_CONFIG:
+		MM_ERR("rpc DEVICE_CONFIG\n");
+		break;
 	default:
 		break;
 	}
@@ -201,6 +309,36 @@
 	return 0;
 }
 
+static unsigned convert_samp_index(unsigned index)
+{
+	switch (index) {
+	case RPC_AUD_DEF_SAMPLE_RATE_48000:	return 48000;
+	case RPC_AUD_DEF_SAMPLE_RATE_44100:	return 44100;
+	case RPC_AUD_DEF_SAMPLE_RATE_32000:	return 32000;
+	case RPC_AUD_DEF_SAMPLE_RATE_24000:	return 24000;
+	case RPC_AUD_DEF_SAMPLE_RATE_22050:	return 22050;
+	case RPC_AUD_DEF_SAMPLE_RATE_16000:	return 16000;
+	case RPC_AUD_DEF_SAMPLE_RATE_12000:	return 12000;
+	case RPC_AUD_DEF_SAMPLE_RATE_11025:	return 11025;
+	case RPC_AUD_DEF_SAMPLE_RATE_8000:	return 8000;
+	default:				return 11025;
+	}
+}
+
+static void get_current_session_info(struct audmgr *am,
+				struct audmgr_config *cfg)
+{
+	if (cfg->def_method == RPC_AUD_DEF_METHOD_PLAYBACK ||
+	   (cfg->def_method == RPC_AUD_DEF_METHOD_HOST_PCM && cfg->rx_rate)) {
+		am->evt.session_info = SESSION_PLAYBACK; /* playback */
+		am->evt.sample_rate = convert_samp_index(cfg->rx_rate);
+	} else if (cfg->def_method == RPC_AUD_DEF_METHOD_RECORD) {
+		am->evt.session_info = SESSION_RECORDING; /* recording */
+		am->evt.sample_rate = convert_samp_index(cfg->tx_rate);
+	} else
+		am->evt.session_info = SESSION_VOICE;
+}
+
 struct audmgr_enable_msg {
 	struct rpc_request_hdr hdr;
 	struct rpc_audmgr_enable_client_args args;
@@ -223,39 +361,7 @@
 
 	/* connect to audmgr end point and polling thread only once */
 	if (amg->ept == NULL) {
-		amg->ept = msm_rpc_connect_compatible(AUDMGR_PROG,
-				AUDMGR_VERS_COMP_VER3,
-				MSM_RPC_UNINTERRUPTIBLE);
-		if (IS_ERR(amg->ept)) {
-			MM_ERR("connect failed with current VERS \
-				= %x, trying again with another API\n",
-				AUDMGR_VERS_COMP_VER3);
-			amg->ept = msm_rpc_connect_compatible(AUDMGR_PROG,
-					AUDMGR_VERS_COMP_VER2,
-					MSM_RPC_UNINTERRUPTIBLE);
-			if (IS_ERR(amg->ept)) {
-				MM_ERR("connect failed with current VERS \
-					= %x, trying again with another API\n",
-					AUDMGR_VERS_COMP_VER2);
-				amg->ept = msm_rpc_connect_compatible(
-						AUDMGR_PROG,
-						AUDMGR_VERS_COMP,
-						MSM_RPC_UNINTERRUPTIBLE);
-				if (IS_ERR(amg->ept)) {
-					MM_ERR("connect failed with current \
-					VERS=%x, trying again with another \
-					API\n", AUDMGR_VERS_COMP);
-					amg->ept = msm_rpc_connect(AUDMGR_PROG,
-						AUDMGR_VERS,
-						MSM_RPC_UNINTERRUPTIBLE);
-					amg->rpc_version = AUDMGR_VERS;
-				} else
-					amg->rpc_version = AUDMGR_VERS_COMP;
-			} else
-				amg->rpc_version = AUDMGR_VERS_COMP_VER2;
-		} else
-			amg->rpc_version = AUDMGR_VERS_COMP_VER3;
-
+		audmgr_rpc_connect(amg);
 		if (IS_ERR(amg->ept)) {
 			rc = PTR_ERR(amg->ept);
 			amg->ept = NULL;
@@ -312,6 +418,7 @@
 	msg.args.cb_func = cpu_to_be32(0x11111111);
 	msg.args.client_data = cpu_to_be32((int)am);
 
+	get_current_session_info(am, cfg);
 	msm_rpc_setup_req(&msg.hdr, AUDMGR_PROG, amg->rpc_version,
 			  AUDMGR_ENABLE_CLIENT);
 
@@ -326,6 +433,7 @@
 	if (am->state == STATE_ENABLED)
 		return 0;
 
+	am->evt.session_info = -1;
 	MM_ERR("unexpected state %d while enabling?!\n", am->state);
 	return -ENODEV;
 }
@@ -341,6 +449,7 @@
 		return 0;
 
 	MM_INFO("session 0x%08x\n", (int) am);
+	am->evt.session_info = -1;
 	msg.handle = cpu_to_be32(am->handle);
 	msm_rpc_setup_req(&msg.hdr, AUDMGR_PROG, amg->rpc_version,
 			  AUDMGR_DISABLE_CLIENT);
@@ -363,3 +472,33 @@
 	return -ENODEV;
 }
 EXPORT_SYMBOL(audmgr_disable);
+
+int audmgr_register_device_info_callback(struct device_info_callback *dcb)
+{
+	struct audmgr_global *amg = &the_audmgr_state;
+	int i;
+
+	for (i = 0; i < MAX_DEVICE_INFO_CALLBACK; i++) {
+		if (NULL == amg->device_cb[i]) {
+			amg->device_cb[i] = dcb;
+			return 0;
+		}
+	}
+	return -EINVAL;
+}
+EXPORT_SYMBOL(audmgr_register_device_info_callback);
+
+int audmgr_deregister_device_info_callback(struct device_info_callback *dcb)
+{
+	struct audmgr_global *amg = &the_audmgr_state;
+	int i;
+
+	for (i = 0; i < MAX_DEVICE_INFO_CALLBACK; i++) {
+		if (dcb == amg->device_cb[i]) {
+			amg->device_cb[i] = NULL;
+			return 0;
+		}
+	}
+	return -EINVAL;
+}
+EXPORT_SYMBOL(audmgr_deregister_device_info_callback);
diff --git a/arch/arm/mach-msm/qdsp5/audmgr.h b/arch/arm/mach-msm/qdsp5/audmgr.h
index 3d8c560..15dd954 100644
--- a/arch/arm/mach-msm/qdsp5/audmgr.h
+++ b/arch/arm/mach-msm/qdsp5/audmgr.h
@@ -125,6 +125,9 @@
 	RPC_AUDMGR_STATUS_VOLUME_CHANGE,
 	RPC_AUDMGR_STATUS_DISABLED,
 	RPC_AUDMGR_STATUS_ERROR,
+	RPC_AUDMGR_STATUS_DEVICE_CONFIG,
+	RPC_AUDMGR_STATUS_DEVICE_INFO
+
 };
 
 struct rpc_audmgr_enable_client_args {
@@ -148,6 +151,7 @@
 #define AUDMGR_GET_RX_SAMPLE_RATE		8
 #define AUDMGR_GET_TX_SAMPLE_RATE		9
 #define AUDMGR_SET_DEVICE_MODE			10
+#define MIN_RPC_DATA_LENGTH 16
 
 #define AUDMGR_PROG_VERS "rs30000013:0x7feccbff"
 #define AUDMGR_PROG 0x30000013
@@ -155,8 +159,17 @@
 #define AUDMGR_VERS_COMP 0x00010001
 #define AUDMGR_VERS_COMP_VER2 0x00020001
 #define AUDMGR_VERS_COMP_VER3 0x00030001
+#define AUDMGR_VERS_COMP_VER4 0x00040001
 
-struct rpc_audmgr_cb_func_ptr {
+struct cad_device_info_type {
+	uint32_t rx_device;
+	uint32_t tx_device;
+	uint32_t ear_mute;
+	uint32_t mic_mute;
+	uint32_t volume;
+};
+
+struct rpc_audmgr_cb_common {
 	uint32_t cb_id; /* cb_func */
 	uint32_t status; /* Audmgr status */
 	uint32_t set_to_one;  /* Pointer status (1 = valid, 0  = invalid) */
@@ -165,6 +178,10 @@
 	   disc = AUDMGR_STATUS_CODEC_CONFIG => data = volume
 	   disc = AUDMGR_STATUS_DISABLED => data =status_disabled
 	   disc = AUDMGR_STATUS_VOLUME_CHANGE => data = volume_change */
+};
+
+struct rpc_audmgr_cb_ready {
+	struct rpc_audmgr_cb_common c_data;
 	union {
 		uint32_t handle;
 		uint32_t volume;
@@ -174,18 +191,35 @@
 	uint32_t client_data;
 };
 
+struct rpc_audmgr_cb_device_info {
+	struct rpc_audmgr_cb_common c_data;
+	struct cad_device_info_type d;
+	uint32_t client_data;
+};
+
 #define AUDMGR_CB_FUNC_PTR			1
 #define AUDMGR_OPR_LSTNR_CB_FUNC_PTR		2
 #define AUDMGR_CODEC_LSTR_FUNC_PTR		3
 
-#define AUDMGR_CB_PROG_VERS "rs31000013:0xf8e3e2d9"
-#define AUDMGR_CB_PROG 0x31000013
-#define AUDMGR_CB_VERS 0xf8e3e2d9
+struct dev_evt_msg {
+	struct cad_device_info_type dev_type;
+	uint32_t acdb_id;
+	int session_info;
+	uint32_t sample_rate;
+};
+
+typedef void (*device_info_func)(struct dev_evt_msg *evt_msg, void *private);
+
+struct device_info_callback {
+	device_info_func func;
+	void *private;
+};
 
 struct audmgr {
 	wait_queue_head_t wait;
 	uint32_t handle;
 	int state;
+	struct dev_evt_msg evt;
 };
 
 struct audmgr_config {
@@ -196,86 +230,11 @@
 	uint32_t snd_method;
 };
 
+int audmgr_register_device_info_callback(struct device_info_callback *dcb);
+int audmgr_deregister_device_info_callback(struct device_info_callback *dcb);
+
 int audmgr_open(struct audmgr *am);
 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
new file mode 100644
index 0000000..c0efa3b
--- /dev/null
+++ b/arch/arm/mach-msm/qdsp5/snd_cad.c
@@ -0,0 +1,607 @@
+/* arch/arm/mach-msm/qdsp5/snd_cad.c
+ *
+ * interface to "snd" service on the baseband cpu
+ * This code also borrows from snd.c, which is
+ * Copyright (C) 2008 HTC Corporation
+ * Copyright (c) 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.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/uaccess.h>
+#include <linux/kthread.h>
+#include <linux/delay.h>
+#include <linux/msm_audio.h>
+#include <linux/seq_file.h>
+#include <asm/atomic.h>
+#include <asm/ioctls.h>
+#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;
+	int opened;
+	struct msm_rpc_endpoint *ept;
+	struct msm_cad_endpoints *cad_epts;
+};
+
+struct snd_cad_sys_ctxt {
+	struct mutex lock;
+	struct msm_rpc_endpoint *ept;
+};
+
+struct snd_curr_dev_info {
+	int rx_dev;
+	int tx_dev;
+};
+
+static struct snd_cad_sys_ctxt the_snd_cad_sys;
+
+static struct snd_cad_ctxt the_snd;
+static struct snd_curr_dev_info curr_dev;
+
+#define RPC_SND_PROG	0x30000002
+#define RPC_SND_CB_PROG	0x31000002
+
+#define RPC_SND_VERS	0x00030003
+
+#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;
+	uint32_t ear_mute;
+	uint32_t mic_mute;
+
+	uint32_t cb_func;
+	uint32_t client_data;
+};
+
+struct rpc_cad_set_volume_args {
+	struct cad_devices_type device;
+	uint32_t method;
+	uint32_t volume;
+
+	uint32_t cb_func;
+	uint32_t client_data;
+};
+
+struct snd_cad_set_device_msg {
+	struct rpc_request_hdr hdr;
+	struct rpc_cad_set_device_args args;
+};
+
+struct snd_cad_set_volume_msg {
+	struct rpc_request_hdr hdr;
+	struct rpc_cad_set_volume_args args;
+};
+
+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 ||
+		mute == SND_MUTE_UNMUTED) ? 0 : -EINVAL;
+}
+
+static int get_endpoint(struct snd_cad_ctxt *snd, unsigned long arg)
+{
+	int rc = 0, index;
+	struct msm_cad_endpoint ept;
+
+	if (copy_from_user(&ept, (void __user *)arg, sizeof(ept))) {
+		MM_ERR("cad_ioctl get endpoint: invalid read pointer\n");
+		return -EFAULT;
+	}
+
+	index = ept.id;
+	if (index < 0 || index >= snd->cad_epts->num) {
+		MM_ERR("snd_ioctl get endpoint: invalid index!\n");
+		return -EINVAL;
+	}
+
+	ept.id = snd->cad_epts->endpoints[index].id;
+	strlcpy(ept.name,
+		snd->cad_epts->endpoints[index].name,
+		sizeof(ept.name));
+
+	if (copy_to_user((void __user *)arg, &ept, sizeof(ept))) {
+		MM_ERR("snd_ioctl get endpoint: invalid write pointer\n");
+		rc = -EFAULT;
+	}
+
+	return rc;
+}
+
+static long snd_cad_ioctl(struct file *file, unsigned int cmd,
+		unsigned long arg)
+{
+	struct snd_cad_set_device_msg dmsg;
+	struct snd_cad_set_volume_msg vmsg;
+
+	struct msm_cad_device_config dev;
+	struct msm_cad_volume_config vol;
+	struct snd_cad_ctxt *snd = file->private_data;
+	int rc = 0;
+
+	mutex_lock(&snd->lock);
+	switch (cmd) {
+	case SND_SET_DEVICE:
+		if (copy_from_user(&dev, (void __user *) arg, sizeof(dev))) {
+			MM_ERR("set device: invalid pointer\n");
+			rc = -EFAULT;
+			break;
+		}
+
+		dmsg.args.device.rx_device = cpu_to_be32(dev.device.rx_device);
+		dmsg.args.device.tx_device = cpu_to_be32(dev.device.tx_device);
+		dmsg.args.device.pathtype = cpu_to_be32(dev.device.pathtype);
+		dmsg.args.ear_mute = cpu_to_be32(dev.ear_mute);
+		dmsg.args.mic_mute = cpu_to_be32(dev.mic_mute);
+		if (check_mute(dev.ear_mute) < 0 ||
+				check_mute(dev.mic_mute) < 0) {
+			MM_ERR("set device: invalid mute status\n");
+			rc = -EINVAL;
+			break;
+		}
+		dmsg.args.cb_func = -1;
+		dmsg.args.client_data = 0;
+		curr_dev.tx_dev = dev.device.tx_device;
+		curr_dev.rx_dev = dev.device.rx_device;
+		MM_ERR("snd_cad_set_device %d %d %d %d\n", dev.device.rx_device,
+			dev.device.tx_device, dev.ear_mute, dev.mic_mute);
+
+		rc = msm_rpc_call(snd->ept,
+			SND_CAD_SET_DEVICE_PROC,
+			&dmsg, sizeof(dmsg), 5 * HZ);
+		break;
+
+	case SND_SET_VOLUME:
+		if (copy_from_user(&vol, (void __user *) arg, sizeof(vol))) {
+			MM_ERR("set volume: invalid pointer\n");
+			rc = -EFAULT;
+			break;
+		}
+
+		vmsg.args.device.rx_device = cpu_to_be32(dev.device.rx_device);
+		vmsg.args.device.tx_device = cpu_to_be32(dev.device.tx_device);
+		vmsg.args.method = cpu_to_be32(vol.method);
+		if (vol.method != SND_METHOD_VOICE) {
+			MM_ERR("set volume: invalid method\n");
+			rc = -EINVAL;
+			break;
+		}
+
+		vmsg.args.volume = cpu_to_be32(vol.volume);
+		vmsg.args.cb_func = -1;
+		vmsg.args.client_data = 0;
+
+		MM_ERR("snd_cad_set_volume %d %d %d %d\n", vol.device.rx_device,
+				vol.device.tx_device, vol.method, vol.volume);
+
+		rc = msm_rpc_call(snd->ept,
+			SND_CAD_SET_VOLUME_PROC,
+			&vmsg, sizeof(vmsg), 5 * HZ);
+
+		break;
+
+	case SND_GET_NUM_ENDPOINTS:
+		if (copy_to_user((void __user *)arg,
+				&snd->cad_epts->num, sizeof(unsigned))) {
+			MM_ERR("get endpoint: invalid pointer\n");
+			rc = -EFAULT;
+		}
+		break;
+
+	case SND_GET_ENDPOINT:
+		rc = get_endpoint(snd, arg);
+		break;
+
+	default:
+		MM_ERR("unknown command\n");
+		rc = -EINVAL;
+		break;
+	}
+	mutex_unlock(&snd->lock);
+
+	return rc;
+}
+
+static int snd_cad_release(struct inode *inode, struct file *file)
+{
+	struct snd_cad_ctxt *snd = file->private_data;
+	int rc;
+
+	mutex_lock(&snd->lock);
+	rc = msm_rpc_close(snd->ept);
+	if (rc < 0)
+		MM_ERR("msm_rpc_close failed\n");
+	snd->ept = NULL;
+	snd->opened = 0;
+	mutex_unlock(&snd->lock);
+	return 0;
+}
+static int snd_cad_sys_release(void)
+{
+	struct snd_cad_sys_ctxt *snd_cad_sys = &the_snd_cad_sys;
+	int rc = 0;
+
+	mutex_lock(&snd_cad_sys->lock);
+	rc = msm_rpc_close(snd_cad_sys->ept);
+	if (rc < 0)
+		MM_ERR("msm_rpc_close failed\n");
+	snd_cad_sys->ept = NULL;
+	mutex_unlock(&snd_cad_sys->lock);
+	return rc;
+}
+static int snd_cad_open(struct inode *inode, struct file *file)
+{
+	struct snd_cad_ctxt *snd = &the_snd;
+	int rc = 0;
+
+	mutex_lock(&snd->lock);
+	if (snd->opened == 0) {
+		if (snd->ept == NULL) {
+			snd->ept = msm_rpc_connect_compatible(RPC_SND_PROG,
+					RPC_SND_VERS, 0);
+			if (IS_ERR(snd->ept)) {
+				rc = PTR_ERR(snd->ept);
+				snd->ept = NULL;
+				MM_ERR("cad connect failed with VERS %x\n",
+					RPC_SND_VERS);
+				goto err;
+			}
+		}
+		file->private_data = snd;
+		snd->opened = 1;
+	} else {
+		MM_ERR("snd already opened\n");
+		rc = -EBUSY;
+	}
+
+err:
+	mutex_unlock(&snd->lock);
+	return rc;
+}
+static int snd_cad_sys_open(void)
+{
+	struct snd_cad_sys_ctxt *snd_cad_sys = &the_snd_cad_sys;
+	int rc = 0;
+
+	mutex_lock(&snd_cad_sys->lock);
+	if (snd_cad_sys->ept == NULL) {
+		snd_cad_sys->ept = msm_rpc_connect_compatible(RPC_SND_PROG,
+			RPC_SND_VERS, 0);
+		if (IS_ERR(snd_cad_sys->ept)) {
+			rc = PTR_ERR(snd_cad_sys->ept);
+			snd_cad_sys->ept = NULL;
+			MM_ERR("func %s : cad connect failed with VERS %x\n",
+				__func__, RPC_SND_VERS);
+			goto err;
+		}
+	} else
+		MM_DBG("snd already opened\n");
+err:
+	mutex_unlock(&snd_cad_sys->lock);
+	return rc;
+}
+
+static const struct file_operations snd_cad_fops = {
+	.owner		= THIS_MODULE,
+	.open		= snd_cad_open,
+	.release	= snd_cad_release,
+	.unlocked_ioctl	= snd_cad_ioctl,
+};
+
+struct miscdevice snd_cad_misc = {
+	.minor	= MISC_DYNAMIC_MINOR,
+	.name	= "msm_cad",
+	.fops	= &snd_cad_fops,
+};
+
+static long snd_cad_vol_enable(const char *arg)
+{
+	struct snd_cad_sys_ctxt *snd_cad_sys = &the_snd_cad_sys;
+	struct snd_cad_set_volume_msg vmsg;
+	struct msm_cad_volume_config vol;
+	int rc = 0;
+
+	rc = sscanf(arg, "%d %d %d %d", &vol.device.rx_device,
+			&vol.device.tx_device, &vol.method, &vol.volume);
+	if (rc != 4) {
+		MM_ERR("Invalid arguments. Usage: <rx_device> <tx_device>" \
+			"method> <volume>\n");
+		rc = -EINVAL;
+		return rc;
+	}
+
+	vmsg.args.device.rx_device = cpu_to_be32(vol.device.rx_device);
+	vmsg.args.device.tx_device = cpu_to_be32(vol.device.tx_device);
+	vmsg.args.method = cpu_to_be32(vol.method);
+	if (vol.method != SND_METHOD_VOICE) {
+		MM_ERR("snd_cad_ioctl set volume: invalid method\n");
+		rc = -EINVAL;
+		return rc;
+	}
+
+	vmsg.args.volume = cpu_to_be32(vol.volume);
+	vmsg.args.cb_func = -1;
+	vmsg.args.client_data = 0;
+
+	MM_DBG("snd_cad_set_volume %d %d %d %d\n", vol.device.rx_device,
+			vol.device.rx_device, vol.method, vol.volume);
+
+	rc = msm_rpc_call(snd_cad_sys->ept,
+		SND_CAD_SET_VOLUME_PROC,
+		&vmsg, sizeof(vmsg), 5 * HZ);
+	return rc;
+}
+
+static long snd_cad_dev_enable(const char *arg)
+{
+	struct snd_cad_sys_ctxt *snd_cad_sys = &the_snd_cad_sys;
+	struct snd_cad_set_device_msg dmsg;
+	struct msm_cad_device_config dev;
+	int rc = 0;
+
+
+	rc = sscanf(arg, "%d %d %d %d", &dev.device.rx_device,
+			&dev.device.tx_device, &dev.ear_mute, &dev.mic_mute);
+	if (rc != 4) {
+		MM_ERR("Invalid arguments. Usage: <rx_device> <tx_device> "\
+			"<ear_mute> <mic_mute>\n");
+		rc = -EINVAL;
+		return rc;
+	}
+	dmsg.args.device.rx_device = cpu_to_be32(dev.device.rx_device);
+	dmsg.args.device.tx_device = cpu_to_be32(dev.device.tx_device);
+	dmsg.args.device.pathtype = cpu_to_be32(CAD_DEVICE_PATH_RX_TX);
+	dmsg.args.ear_mute = cpu_to_be32(dev.ear_mute);
+	dmsg.args.mic_mute = cpu_to_be32(dev.mic_mute);
+	if (check_mute(dev.ear_mute) < 0 ||
+			check_mute(dev.mic_mute) < 0) {
+		MM_ERR("snd_cad_ioctl set device: invalid mute status\n");
+		rc = -EINVAL;
+		return rc;
+	}
+	dmsg.args.cb_func = -1;
+	dmsg.args.client_data = 0;
+	curr_dev.tx_dev = dev.device.tx_device;
+	curr_dev.rx_dev = dev.device.rx_device;
+
+	MM_INFO("snd_cad_set_device %d %d %d %d\n", dev.device.rx_device,
+			dev.device.tx_device, dev.ear_mute, dev.mic_mute);
+
+	rc = msm_rpc_call(snd_cad_sys->ept,
+		SND_CAD_SET_DEVICE_PROC,
+		&dmsg, sizeof(dmsg), 5 * HZ);
+	return rc;
+}
+
+static ssize_t snd_cad_dev_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	ssize_t status;
+	struct snd_cad_sys_ctxt *snd_cad_sys = &the_snd_cad_sys;
+	int rc = 0;
+
+	rc = snd_cad_sys_open();
+	if (rc)
+		return rc;
+
+	mutex_lock(&snd_cad_sys->lock);
+	status = snd_cad_dev_enable(buf);
+	mutex_unlock(&snd_cad_sys->lock);
+
+	rc = snd_cad_sys_release();
+	if (rc)
+		return rc;
+
+	return status ? : size;
+}
+
+static ssize_t snd_cad_vol_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	ssize_t status;
+	struct snd_cad_sys_ctxt *snd_cad_sys = &the_snd_cad_sys;
+	int rc = 0;
+
+	rc = snd_cad_sys_open();
+	if (rc)
+		return rc;
+
+	mutex_lock(&snd_cad_sys->lock);
+	status = snd_cad_vol_enable(buf);
+	mutex_unlock(&snd_cad_sys->lock);
+
+	rc = snd_cad_sys_release();
+	if (rc)
+		return rc;
+
+	return status ? : size;
+}
+
+static DEVICE_ATTR(device, S_IWUSR | S_IRUGO,
+		NULL, snd_cad_dev_store);
+
+static DEVICE_ATTR(volume, S_IWUSR | S_IRUGO,
+		NULL, snd_cad_vol_store);
+
+static int snd_cad_probe(struct platform_device *pdev)
+{
+	struct snd_cad_ctxt *snd = &the_snd;
+	struct snd_cad_sys_ctxt *snd_cad_sys = &the_snd_cad_sys;
+	int rc = 0;
+
+	mutex_init(&snd->lock);
+	mutex_init(&snd_cad_sys->lock);
+	snd_cad_sys->ept = NULL;
+	snd->cad_epts =
+			(struct msm_cad_endpoints *)pdev->dev.platform_data;
+	rc = misc_register(&snd_cad_misc);
+	if (rc)
+		return rc;
+
+	rc = device_create_file(snd_cad_misc.this_device, &dev_attr_device);
+	if (rc) {
+		misc_deregister(&snd_cad_misc);
+		return rc;
+	}
+
+	rc = device_create_file(snd_cad_misc.this_device, &dev_attr_volume);
+	if (rc) {
+		device_remove_file(snd_cad_misc.this_device,
+						&dev_attr_device);
+		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;
+}
+
+static struct platform_driver snd_cad_plat_driver = {
+	.probe = snd_cad_probe,
+	.driver = {
+		.name = "msm_cad",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init snd_cad_init(void)
+{
+	return platform_driver_register(&snd_cad_plat_driver);
+}
+
+module_init(snd_cad_init);
+
+MODULE_DESCRIPTION("MSM CAD SND driver");
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-msm/socinfo.c b/arch/arm/mach-msm/socinfo.c
index 8e0113c..b9f8bff 100644
--- a/arch/arm/mach-msm/socinfo.c
+++ b/arch/arm/mach-msm/socinfo.c
@@ -246,6 +246,7 @@
 	[127] = MSM_CPU_8625,
 	[128] = MSM_CPU_8625,
 	[129] = MSM_CPU_8625,
+	[137] = MSM_CPU_8625,
 
 	/* 8064 MPQ ID */
 	[130] = MSM_CPU_8064,
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 9240605..26e8496 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -307,6 +307,16 @@
 	  This option enables support for LEDs connected to the PCA9633
 	  LED driver chip accessed via the I2C bus.
 
+config LEDS_QPNP
+	tristate "Support for QPNP LEDs"
+	depends on SPMI && OF_SPMI
+	help
+	  This driver supports the leds functionality of Qualcomm PNP PMIC.  It
+	  includes RGB Leds, WLED and Flash Led.
+
+	  To compile this driver as a module, choose M here: the module will
+	  be called leds-qpnp.
+
 config LEDS_WM831X_STATUS
 	tristate "LED support for status LEDs on WM831x PMICs"
 	depends on LEDS_CLASS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 8edd465..c688898 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -19,6 +19,7 @@
 obj-$(CONFIG_LEDS_SUNFIRE)		+= leds-sunfire.o
 obj-$(CONFIG_LEDS_PCA9532)		+= leds-pca9532.o
 obj-$(CONFIG_LEDS_PM8XXX)		+= leds-pm8xxx.o
+obj-$(CONFIG_LEDS_QPNP)			+= leds-qpnp.o
 obj-$(CONFIG_LEDS_GPIO_REGISTER)	+= leds-gpio-register.o
 obj-$(CONFIG_LEDS_GPIO)			+= leds-gpio.o
 obj-$(CONFIG_LEDS_LP3944)		+= leds-lp3944.o
diff --git a/drivers/leds/leds-qpnp.c b/drivers/leds/leds-qpnp.c
new file mode 100644
index 0000000..f42fb5e
--- /dev/null
+++ b/drivers/leds/leds-qpnp.c
@@ -0,0 +1,725 @@
+
+/* 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/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/leds.h>
+#include <linux/err.h>
+#include <linux/of_platform.h>
+#include <linux/of_device.h>
+#include <linux/spmi.h>
+
+#define WLED_MOD_EN_REG(base, n)	(base + 0x60 + n*0x10)
+#define WLED_IDAC_DLY_REG(base, n)	(WLED_MOD_EN_REG(base, n) + 0x01)
+#define WLED_FULL_SCALE_REG(base, n)	(WLED_IDAC_DLY_REG(base, n) + 0x01)
+
+/* wled control registers */
+#define WLED_BRIGHTNESS_CNTL_LSB(base, n)	(base + 0x40 + 2*n)
+#define WLED_BRIGHTNESS_CNTL_MSB(base, n)	(base + 0x41 + 2*n)
+#define WLED_MOD_CTRL_REG(base)			(base + 0x46)
+#define WLED_SYNC_REG(base)			(base + 0x47)
+#define WLED_FDBCK_CTRL_REG(base)		(base + 0x48)
+#define WLED_SWITCHING_FREQ_REG(base)		(base + 0x4C)
+#define WLED_OVP_CFG_REG(base)			(base + 0x4D)
+#define WLED_BOOST_LIMIT_REG(base)		(base + 0x4E)
+#define WLED_CURR_SINK_REG(base)		(base + 0x4F)
+#define WLED_HIGH_POLE_CAP_REG(base)		(base + 0x58)
+#define WLED_CURR_SINK_MASK		0xE0
+#define WLED_CURR_SINK_SHFT		0x05
+#define WLED_SWITCH_FREQ_MASK		0x02
+#define WLED_OVP_VAL_MASK		0x03
+#define WLED_OVP_VAL_BIT_SHFT		0x00
+#define WLED_BOOST_LIMIT_MASK		0x07
+#define WLED_BOOST_LIMIT_BIT_SHFT	0x00
+#define WLED_BOOST_ON			0x80
+#define WLED_BOOST_OFF			0x00
+#define WLED_EN_MASK			0x80
+#define WLED_NO_MASK			0x00
+#define WLED_CP_SELECT_MAX		0x03
+#define WLED_CP_SELECT_MASK		0x02
+#define WLED_USE_EXT_GEN_MOD_SRC	0x01
+#define WLED_CTL_DLY_STEP		200
+#define WLED_CTL_DLY_MAX		1400
+#define WLED_MAX_CURR			25
+#define WLED_MSB_MASK			0x0F
+#define WLED_MAX_CURR_MASK		0x19
+#define WLED_OP_FDBCK_MASK		0x07
+#define WLED_OP_FDBCK_BIT_SHFT		0x00
+
+#define WLED_MAX_LEVEL			255
+#define WLED_8_BIT_MASK			0xFF
+#define WLED_4_BIT_MASK			0x0F
+#define WLED_8_BIT_SHFT			0x08
+#define WLED_MAX_DUTY_CYCLE		0xFFF
+
+#define WLED_SYNC_VAL			0x07
+#define WLED_SYNC_RESET_VAL		0x00
+
+#define WLED_TRIGGER_DEFAULT		"none"
+#define WLED_FLAGS_DEFAULT		0x00
+#define WLED_DEFAULT_STRINGS		0x01
+#define WLED_DEFAULT_OVP_VAL		0x02
+#define WLED_BOOST_LIM_DEFAULT		0x03
+#define WLED_CP_SEL_DEFAULT		0x00
+#define WLED_CTRL_DLY_DEFAULT		0x00
+#define WLED_SWITCH_FREQ_DEFAULT	0x02
+
+/**
+ * enum qpnp_leds - QPNP supported led ids
+ * @QPNP_ID_WLED - White led backlight
+ */
+enum qpnp_leds {
+	QPNP_ID_WLED,
+};
+
+/* current boost limit */
+enum wled_current_boost_limit {
+	WLED_CURR_LIMIT_105mA,
+	WLED_CURR_LIMIT_385mA,
+	WLED_CURR_LIMIT_525mA,
+	WLED_CURR_LIMIT_805mA,
+	WLED_CURR_LIMIT_980mA,
+	WLED_CURR_LIMIT_1260mA,
+	WLED_CURR_LIMIT_1400mA,
+	WLED_CURR_LIMIT_1680mA,
+};
+
+/* over voltage protection threshold */
+enum wled_ovp_threshold {
+	WLED_OVP_35V,
+	WLED_OVP_32V,
+	WLED_OVP_29V,
+	WLED_OVP_37V,
+};
+
+/* switch frquency */
+enum wled_switch_freq {
+	WLED_800kHz = 0,
+	WLED_960kHz,
+	WLED_1600kHz,
+	WLED_3200kHz,
+};
+
+static u8 wled_debug_regs[] = {
+	/* common registers */
+	0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4d, 0x4e, 0x4f,
+	0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+	/* LED1 */
+	0x60, 0x61, 0x62, 0x63, 0x66,
+	/* LED1 */
+	0x70, 0x71, 0x72, 0x73, 0x76,
+	/* LED1 */
+	0x80, 0x81, 0x82, 0x83, 0x86,
+};
+
+/**
+ *  wled_config_data - wled configuration data
+ *  @num_strings - number of wled strings supported
+ *  @ovp_val - over voltage protection threshold
+ *  @boost_curr_lim - boot current limit
+ *  @cp_select - high pole capacitance
+ *  @ctrl_delay_us - delay in activation of led
+ *  @dig_mod_gen_en - digital module generator
+ *  @cs_out_en - current sink output enable
+ *  @op_fdbck - selection of output as feedback for the boost
+ */
+struct wled_config_data {
+	u8	num_strings;
+	u8	ovp_val;
+	u8	boost_curr_lim;
+	u8	cp_select;
+	u8	ctrl_delay_us;
+	u8	switch_freq;
+	bool	dig_mod_gen_en;
+	bool	cs_out_en;
+	bool	op_fdbck;
+};
+
+/**
+ * struct qpnp_led_data - internal led data structure
+ * @led_classdev - led class device
+ * @id - led index
+ * @base_reg - base register given in device tree
+ * @lock - to protect the transactions
+ * @reg - cached value of led register
+ * @max_current - maximum current supported by LED
+ * @default_on - true: default state max, false, default state 0
+ */
+struct qpnp_led_data {
+	struct led_classdev	cdev;
+	struct spmi_device	*spmi_dev;
+	int			id;
+	u16			base;
+	u8			reg;
+	struct mutex		lock;
+	struct wled_config_data *wled_cfg;
+	int			max_current;
+	bool			default_on;
+};
+
+static int
+qpnp_led_masked_write(struct qpnp_led_data *led, u16 addr, u8 mask, u8 val)
+{
+	int rc;
+	u8 reg;
+
+	rc = spmi_ext_register_readl(led->spmi_dev->ctrl, led->spmi_dev->sid,
+		addr, &reg, 1);
+	if (rc) {
+		dev_err(&led->spmi_dev->dev,
+			"Unable to read from addr=%x, rc(%d)\n", addr, rc);
+	}
+
+	reg &= ~mask;
+	reg |= val;
+
+	rc = spmi_ext_register_writel(led->spmi_dev->ctrl, led->spmi_dev->sid,
+		addr, &reg, 1);
+	if (rc)
+		dev_err(&led->spmi_dev->dev,
+			"Unable to write to addr=%x, rc(%d)\n", addr, rc);
+	return rc;
+}
+
+static int qpnp_wled_set(struct qpnp_led_data *led)
+{
+	int rc, duty;
+	u8 level, val, i, num_wled_strings;
+
+	level = led->cdev.brightness;
+
+	if (level > WLED_MAX_LEVEL)
+		level = WLED_MAX_LEVEL;
+	if (level == 0) {
+		val = WLED_BOOST_OFF;
+		rc = spmi_ext_register_writel(led->spmi_dev->ctrl,
+			led->spmi_dev->sid, WLED_MOD_CTRL_REG(led->base),
+			&val, 1);
+		if (rc) {
+			dev_err(&led->spmi_dev->dev,
+				"WLED write ctrl reg failed(%d)\n", rc);
+			return rc;
+		}
+	} else {
+		val = WLED_BOOST_ON;
+		rc = spmi_ext_register_writel(led->spmi_dev->ctrl,
+			led->spmi_dev->sid, WLED_MOD_CTRL_REG(led->base),
+			&val, 1);
+		if (rc) {
+			dev_err(&led->spmi_dev->dev,
+				"WLED write ctrl reg failed(%d)\n", rc);
+			return rc;
+		}
+	}
+
+	duty = (WLED_MAX_DUTY_CYCLE * level) / WLED_MAX_LEVEL;
+
+	num_wled_strings = led->wled_cfg->num_strings;
+
+	/* program brightness control registers */
+	for (i = 0; i < num_wled_strings; i++) {
+		rc = qpnp_led_masked_write(led,
+			WLED_BRIGHTNESS_CNTL_MSB(led->base, i), WLED_MSB_MASK,
+			(duty >> WLED_8_BIT_SHFT) & WLED_4_BIT_MASK);
+		if (rc) {
+			dev_err(&led->spmi_dev->dev,
+				"WLED set brightness MSB failed(%d)\n", rc);
+			return rc;
+		}
+		val = duty & WLED_8_BIT_MASK;
+		rc = spmi_ext_register_writel(led->spmi_dev->ctrl,
+			led->spmi_dev->sid,
+			WLED_BRIGHTNESS_CNTL_LSB(led->base, i), &val, 1);
+		if (rc) {
+			dev_err(&led->spmi_dev->dev,
+				"WLED set brightness LSB failed(%d)\n", rc);
+			return rc;
+		}
+	}
+
+	/* sync */
+	val = WLED_SYNC_VAL;
+	rc = spmi_ext_register_writel(led->spmi_dev->ctrl, led->spmi_dev->sid,
+		WLED_SYNC_REG(led->base), &val, 1);
+	if (rc) {
+		dev_err(&led->spmi_dev->dev,
+				"WLED set sync reg failed(%d)\n", rc);
+		return rc;
+	}
+
+	val = WLED_SYNC_RESET_VAL;
+	rc = spmi_ext_register_writel(led->spmi_dev->ctrl, led->spmi_dev->sid,
+		WLED_SYNC_REG(led->base), &val, 1);
+	if (rc) {
+		dev_err(&led->spmi_dev->dev,
+				"WLED reset sync reg failed(%d)\n", rc);
+		return rc;
+	}
+	return 0;
+}
+
+static void qpnp_wled_dump_regs(struct qpnp_led_data *led)
+{
+	int i;
+	u8 val;
+
+	pr_debug("===== WLED register dump start =====\n");
+	for (i = 0; i < ARRAY_SIZE(wled_debug_regs); i++) {
+		spmi_ext_register_readl(led->spmi_dev->ctrl,
+					led->spmi_dev->sid,
+					led->base + wled_debug_regs[i],
+					&val, sizeof(val));
+		pr_debug("0x%x = 0x%x\n", led->base + wled_debug_regs[i], val);
+	}
+	pr_debug("===== WLED register dump end =====\n");
+}
+
+static void qpnp_led_set(struct led_classdev *led_cdev,
+				enum led_brightness value)
+{
+	int rc;
+	struct qpnp_led_data *led;
+
+	led = container_of(led_cdev, struct qpnp_led_data, cdev);
+
+	if (value < LED_OFF || value > led->cdev.max_brightness) {
+		dev_err(led->cdev.dev, "Invalid brightness value\n");
+		return;
+	}
+
+	mutex_lock(&led->lock);
+	led->cdev.brightness = value;
+
+	switch (led->id) {
+	case QPNP_ID_WLED:
+		rc = qpnp_wled_set(led);
+		if (rc < 0)
+			dev_err(led->cdev.dev,
+				"WLED set brightness failed (%d)\n", rc);
+		break;
+	default:
+		dev_err(led->cdev.dev, "Invalid LED(%d)\n", led->id);
+		break;
+	}
+	mutex_unlock(&led->lock);
+}
+
+static int __devinit qpnp_led_set_max_brightness(struct qpnp_led_data *led)
+{
+	switch (led->id) {
+	case QPNP_ID_WLED:
+		led->cdev.max_brightness = WLED_MAX_LEVEL;
+		break;
+	default:
+		dev_err(led->cdev.dev, "Invalid LED(%d)\n", led->id);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static enum led_brightness qpnp_led_get(struct led_classdev *led_cdev)
+{
+	struct qpnp_led_data *led;
+
+	led = container_of(led_cdev, struct qpnp_led_data, cdev);
+
+	return led->cdev.brightness;
+}
+
+static int __devinit qpnp_wled_init(struct qpnp_led_data *led)
+{
+	int rc, i;
+	u8 num_wled_strings;
+
+	num_wled_strings = led->wled_cfg->num_strings;
+
+	/* verify ranges */
+	if (led->wled_cfg->ovp_val > WLED_OVP_37V) {
+		dev_err(&led->spmi_dev->dev, "Invalid ovp value\n");
+		return -EINVAL;
+	}
+
+	if (led->wled_cfg->boost_curr_lim > WLED_CURR_LIMIT_1680mA) {
+		dev_err(&led->spmi_dev->dev, "Invalid boost current limit\n");
+		return -EINVAL;
+	}
+
+	if (led->wled_cfg->cp_select > WLED_CP_SELECT_MAX) {
+		dev_err(&led->spmi_dev->dev, "Invalid pole capacitance\n");
+		return -EINVAL;
+	}
+
+	if ((led->max_current > WLED_MAX_CURR)) {
+		dev_err(&led->spmi_dev->dev, "Invalid max current\n");
+		return -EINVAL;
+	}
+
+	if ((led->wled_cfg->ctrl_delay_us % WLED_CTL_DLY_STEP) ||
+		(led->wled_cfg->ctrl_delay_us > WLED_CTL_DLY_MAX)) {
+		dev_err(&led->spmi_dev->dev, "Invalid control delay\n");
+		return -EINVAL;
+	}
+
+	/* program over voltage protection threshold */
+	rc = qpnp_led_masked_write(led, WLED_OVP_CFG_REG(led->base),
+		WLED_OVP_VAL_MASK,
+		(led->wled_cfg->ovp_val << WLED_OVP_VAL_BIT_SHFT));
+	if (rc) {
+		dev_err(&led->spmi_dev->dev,
+				"WLED OVP reg write failed(%d)\n", rc);
+		return rc;
+	}
+
+	/* program current boost limit */
+	rc = qpnp_led_masked_write(led, WLED_BOOST_LIMIT_REG(led->base),
+		WLED_BOOST_LIMIT_MASK, led->wled_cfg->boost_curr_lim);
+	if (rc) {
+		dev_err(&led->spmi_dev->dev,
+				"WLED boost limit reg write failed(%d)\n", rc);
+		return rc;
+	}
+
+	/* program output feedback */
+	rc = qpnp_led_masked_write(led, WLED_FDBCK_CTRL_REG(led->base),
+		WLED_OP_FDBCK_MASK,
+		(led->wled_cfg->op_fdbck << WLED_OP_FDBCK_BIT_SHFT));
+	if (rc) {
+		dev_err(&led->spmi_dev->dev,
+				"WLED fdbck ctrl reg write failed(%d)\n", rc);
+		return rc;
+	}
+
+	/* program switch frequency */
+	rc = qpnp_led_masked_write(led, WLED_SWITCHING_FREQ_REG(led->base),
+		WLED_SWITCH_FREQ_MASK, led->wled_cfg->switch_freq);
+	if (rc) {
+		dev_err(&led->spmi_dev->dev,
+				"WLED switch freq reg write failed(%d)\n", rc);
+		return rc;
+	}
+
+	/* program current sink */
+	if (led->wled_cfg->cs_out_en) {
+		rc = qpnp_led_masked_write(led, WLED_CURR_SINK_REG(led->base),
+			WLED_CURR_SINK_MASK,
+			(led->wled_cfg->num_strings << WLED_CURR_SINK_SHFT));
+		if (rc) {
+			dev_err(&led->spmi_dev->dev,
+				"WLED curr sink reg write failed(%d)\n", rc);
+			return rc;
+		}
+	}
+
+	/* program high pole capacitance */
+	rc = qpnp_led_masked_write(led, WLED_HIGH_POLE_CAP_REG(led->base),
+		WLED_CP_SELECT_MASK, led->wled_cfg->cp_select);
+	if (rc) {
+		dev_err(&led->spmi_dev->dev,
+				"WLED pole cap reg write failed(%d)\n", rc);
+		return rc;
+	}
+
+	/* program modulator, current mod src and cabc */
+	for (i = 0; i < num_wled_strings; i++) {
+		rc = qpnp_led_masked_write(led, WLED_MOD_EN_REG(led->base, i),
+			WLED_NO_MASK, WLED_EN_MASK);
+		if (rc) {
+			dev_err(&led->spmi_dev->dev,
+				"WLED mod enable reg write failed(%d)\n", rc);
+			return rc;
+		}
+
+		if (led->wled_cfg->dig_mod_gen_en) {
+			rc = qpnp_led_masked_write(led,
+				WLED_MOD_EN_REG(led->base, i),
+				WLED_NO_MASK, WLED_USE_EXT_GEN_MOD_SRC);
+			if (rc) {
+				dev_err(&led->spmi_dev->dev,
+				"WLED dig mod en reg write failed(%d)\n", rc);
+			}
+		}
+
+		rc = qpnp_led_masked_write(led,
+			WLED_FULL_SCALE_REG(led->base, i), WLED_MAX_CURR_MASK,
+			led->max_current);
+		if (rc) {
+			dev_err(&led->spmi_dev->dev,
+				"WLED max current reg write failed(%d)\n", rc);
+			return rc;
+		}
+
+	}
+
+	/* dump wled registers */
+	qpnp_wled_dump_regs(led);
+
+	return 0;
+}
+
+static int __devinit qpnp_led_initialize(struct qpnp_led_data *led)
+{
+	int rc;
+
+	switch (led->id) {
+	case QPNP_ID_WLED:
+		rc = qpnp_wled_init(led);
+		if (rc)
+			dev_err(led->cdev.dev,
+				"WLED initialize failed(%d)\n", rc);
+		break;
+	default:
+		dev_err(led->cdev.dev, "Invalid LED(%d)\n", led->id);
+		rc = -EINVAL;
+	}
+
+	return rc;
+}
+
+/*
+ * Handlers for alternative sources of platform_data
+ */
+static int __devinit qpnp_get_config_wled(struct qpnp_led_data *led,
+				struct device_node *node)
+{
+	u32 val;
+	int rc;
+	const char *temp_string;
+
+	led->id = QPNP_ID_WLED;
+
+	led->wled_cfg = devm_kzalloc(&led->spmi_dev->dev,
+				sizeof(struct wled_config_data), GFP_KERNEL);
+	if (!led->wled_cfg) {
+		dev_err(&led->spmi_dev->dev, "Unable to allocate memory\n");
+		return -ENOMEM;
+	}
+
+	led->cdev.default_trigger = WLED_TRIGGER_DEFAULT;
+	rc = of_property_read_string(node, "linux,default-trigger",
+		&temp_string);
+	if (!rc)
+		led->cdev.default_trigger = temp_string;
+	else if (rc != -EINVAL)
+		return rc;
+
+
+	led->cdev.flags = WLED_FLAGS_DEFAULT;
+	rc = of_property_read_u32(node, "qcom,flags", &val);
+	if (!rc)
+		led->cdev.flags = (int) val;
+	else if (rc != -EINVAL)
+		return rc;
+
+	led->default_on = true;
+	rc = of_property_read_string(node, "qcom,default-state",
+		&temp_string);
+	if (!rc) {
+		if (!strncmp(temp_string, "off", sizeof("off")))
+			led->default_on = false;
+	} else if (rc != -EINVAL)
+		return rc;
+
+	led->wled_cfg->num_strings = WLED_DEFAULT_STRINGS;
+	rc = of_property_read_u32(node, "qcom,num-strings", &val);
+	if (!rc)
+		led->wled_cfg->num_strings = (u8) val;
+	else if (rc != -EINVAL)
+		return rc;
+
+	led->wled_cfg->ovp_val = WLED_DEFAULT_OVP_VAL;
+	rc = of_property_read_u32(node, "qcom,ovp-val", &val);
+	if (!rc)
+		led->wled_cfg->ovp_val = (u8) val;
+	else if (rc != -EINVAL)
+		return rc;
+
+	led->wled_cfg->boost_curr_lim = WLED_BOOST_LIM_DEFAULT;
+	rc = of_property_read_u32(node, "qcom,boost-curr-lim", &val);
+	if (!rc)
+		led->wled_cfg->boost_curr_lim = (u8) val;
+	else if (rc != -EINVAL)
+		return rc;
+
+	led->wled_cfg->cp_select = WLED_CP_SEL_DEFAULT;
+	rc = of_property_read_u32(node, "qcom,cp-sel", &val);
+	if (!rc)
+		led->wled_cfg->cp_select = (u8) val;
+	else if (rc != -EINVAL)
+		return rc;
+
+	led->wled_cfg->ctrl_delay_us = WLED_CTRL_DLY_DEFAULT;
+	rc = of_property_read_u32(node, "qcom,ctrl-delay-us", &val);
+	if (!rc)
+		led->wled_cfg->ctrl_delay_us = (u8) val;
+	else if (rc != -EINVAL)
+		return rc;
+
+	led->wled_cfg->switch_freq = WLED_SWITCH_FREQ_DEFAULT;
+	rc = of_property_read_u32(node, "qcom,switch-freq", &val);
+	if (!rc)
+		led->wled_cfg->switch_freq = (u8) val;
+	else if (rc != -EINVAL)
+		return rc;
+
+	led->wled_cfg->dig_mod_gen_en =
+		of_property_read_bool(node, "qcom,dig-mod-gen-en");
+
+	led->wled_cfg->cs_out_en =
+		of_property_read_bool(node, "qcom,cs-out-en");
+
+	led->wled_cfg->op_fdbck =
+		of_property_read_bool(node, "qcom,op-fdbck");
+
+	return 0;
+}
+
+static int __devinit qpnp_leds_probe(struct spmi_device *spmi)
+{
+	struct qpnp_led_data *led;
+	struct resource *led_resource;
+	struct device_node *node;
+	int rc;
+	const char *led_label;
+
+	led = devm_kzalloc(&spmi->dev, (sizeof(struct qpnp_led_data)),
+		GFP_KERNEL);
+	if (!led) {
+		dev_err(&spmi->dev, "Unable to allocate memory\n");
+		return -ENOMEM;
+	}
+
+	led->spmi_dev = spmi;
+
+	led_resource = spmi_get_resource(spmi, NULL, IORESOURCE_MEM, 0);
+	if (!led_resource) {
+		dev_err(&spmi->dev, "Unable to get LED base address\n");
+		return -ENXIO;
+	}
+	led->base = led_resource->start;
+
+	dev_set_drvdata(&spmi->dev, led);
+
+	node = led->spmi_dev->dev.of_node;
+	if (node == NULL)
+		return -ENODEV;
+
+	rc = of_property_read_string(node, "qcom,label", &led_label);
+	if (rc < 0) {
+		dev_err(&led->spmi_dev->dev,
+			"Failure reading label, rc = %d\n", rc);
+		return rc;
+	}
+
+	rc = of_property_read_string(node, "qcom,name", &led->cdev.name);
+	if (rc < 0) {
+		dev_err(&led->spmi_dev->dev,
+			"Failure reading led name, rc = %d\n", rc);
+		return rc;
+	}
+
+	rc = of_property_read_u32(node, "qcom,max-current", &led->max_current);
+	if (rc < 0) {
+		dev_err(&led->spmi_dev->dev,
+			"Failure reading max_current, rc =  %d\n", rc);
+		return rc;
+	}
+
+	led->cdev.brightness_set    = qpnp_led_set;
+	led->cdev.brightness_get    = qpnp_led_get;
+	led->cdev.brightness	= LED_OFF;
+
+	if (strncmp(led_label, "wled", sizeof("wled")) == 0) {
+		rc = qpnp_get_config_wled(led, node);
+		if (rc < 0) {
+			dev_err(&led->spmi_dev->dev,
+				"Unable to read wled config data\n");
+			return rc;
+		}
+	} else {
+		dev_err(&led->spmi_dev->dev, "No LED matching label\n");
+		return -EINVAL;
+	}
+
+	mutex_init(&led->lock);
+
+	rc =  qpnp_led_initialize(led);
+	if (rc < 0)
+		goto fail_id_check;
+
+	rc = qpnp_led_set_max_brightness(led);
+	if (rc < 0)
+		goto fail_id_check;
+
+
+	rc = led_classdev_register(&spmi->dev, &led->cdev);
+	if (rc) {
+		dev_err(&spmi->dev, "unable to register led %d,rc=%d\n",
+					 led->id, rc);
+		goto fail_id_check;
+	}
+
+	/* configure default state */
+	if (led->default_on)
+		led->cdev.brightness = led->cdev.max_brightness;
+
+	qpnp_led_set(&led->cdev, led->cdev.brightness);
+
+	return 0;
+
+fail_id_check:
+	mutex_destroy(&led->lock);
+	led_classdev_unregister(&led->cdev);
+	return rc;
+}
+
+static int __devexit qpnp_leds_remove(struct spmi_device *spmi)
+{
+	struct qpnp_led_data *led  = dev_get_drvdata(&spmi->dev);
+
+	mutex_destroy(&led->lock);
+	led_classdev_unregister(&led->cdev);
+
+	return 0;
+}
+static struct of_device_id spmi_match_table[] = {
+	{	.compatible = "qcom,leds-qpnp",
+	}
+};
+
+static struct spmi_driver qpnp_leds_driver = {
+	.driver		= {
+		.name	= "qcom,leds-qpnp",
+		.of_match_table = spmi_match_table,
+	},
+	.probe		= qpnp_leds_probe,
+	.remove		= __devexit_p(qpnp_leds_remove),
+};
+
+static int __init qpnp_led_init(void)
+{
+	return spmi_driver_register(&qpnp_leds_driver);
+}
+module_init(qpnp_led_init);
+
+static void __exit qpnp_led_exit(void)
+{
+	spmi_driver_unregister(&qpnp_leds_driver);
+}
+module_exit(qpnp_led_exit);
+
+MODULE_DESCRIPTION("QPNP LEDs driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("leds:leds-qpnp");
diff --git a/drivers/media/video/msm/cci/msm_cci.c b/drivers/media/video/msm/cci/msm_cci.c
index ad3cc6a..3caa580 100644
--- a/drivers/media/video/msm/cci/msm_cci.c
+++ b/drivers/media/video/msm/cci/msm_cci.c
@@ -24,11 +24,10 @@
 #include "msm_cam_cci_hwreg.h"
 
 #define V4L2_IDENT_CCI 50005
-#define CCI_I2C_QUEUE_0_SIZE 2
+#define CCI_I2C_QUEUE_0_SIZE 64
 #define CCI_I2C_QUEUE_1_SIZE 16
 
-#undef CDBG
-#define CDBG pr_debug
+#define CCI_TIMEOUT msecs_to_jiffies(100)
 
 static void msm_cci_set_clk_param(struct cci_device *cci_dev)
 {
@@ -127,8 +126,9 @@
 		msm_camera_io_w(reg_val, cci_dev->base + CCI_QUEUE_START_ADDR);
 		CDBG("%s line %d wait_for_completion_interruptible\n",
 			__func__, __LINE__);
-		wait_for_completion_interruptible(&cci_dev->
-			cci_master_info[master].reset_complete);
+		wait_for_completion_interruptible_timeout(&cci_dev->
+			cci_master_info[master].reset_complete, CCI_TIMEOUT);
+
 		rc = cci_dev->cci_master_info[master].status;
 		if (rc < 0)
 			pr_err("%s failed rc %d\n", __func__, rc);
@@ -234,6 +234,9 @@
 	read_cfg = &c_ctrl->cfg.cci_i2c_read_cfg;
 	mutex_lock(&cci_dev->cci_master_info[master].mutex);
 	CDBG("%s master %d, queue %d\n", __func__, master, queue);
+	CDBG("%s set param sid 0x%x retries %d id_map %d\n", __func__,
+		c_ctrl->cci_info->sid, c_ctrl->cci_info->retries,
+		c_ctrl->cci_info->id_map);
 	val = CCI_I2C_SET_PARAM_CMD | c_ctrl->cci_info->sid << 4 |
 		c_ctrl->cci_info->retries << 16 |
 		c_ctrl->cci_info->id_map << 18;
@@ -285,9 +288,8 @@
 
 	val = 1 << ((master * 2) + queue);
 	msm_camera_io_w(val, cci_dev->base + CCI_QUEUE_START_ADDR);
-
-	wait_for_completion_interruptible(&cci_dev->
-		cci_master_info[master].reset_complete);
+	wait_for_completion_interruptible_timeout(&cci_dev->
+		cci_master_info[master].reset_complete, CCI_TIMEOUT);
 
 	read_bytes = (read_cfg->num_byte / 4) + 1;
 	index = 0;
@@ -328,6 +330,9 @@
 	cci_dev = v4l2_get_subdevdata(sd);
 	master = c_ctrl->cci_info->cci_i2c_master;
 	CDBG("%s master %d, queue %d\n", __func__, master, queue);
+	CDBG("%s set param sid 0x%x retries %d id_map %d\n", __func__,
+		c_ctrl->cci_info->sid, c_ctrl->cci_info->retries,
+		c_ctrl->cci_info->id_map);
 	mutex_lock(&cci_dev->cci_master_info[master].mutex);
 	val = CCI_I2C_SET_PARAM_CMD | c_ctrl->cci_info->sid << 4 |
 		c_ctrl->cci_info->retries << 16 |
@@ -366,7 +371,7 @@
 
 	val = msm_camera_io_r(cci_dev->base + CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR +
 		master * 0x200 + queue * 0x100);
-	CDBG("%s line %d size of queue %d\n", __func__, __LINE__, val);
+	CDBG("%s:%d cur word count %d\n", __func__, __LINE__, val);
 	CDBG("%s:%d CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR\n", __func__, __LINE__);
 	msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR +
 		master * 0x200 + queue * 0x100);
@@ -378,8 +383,9 @@
 
 	CDBG("%s line %d wait_for_completion_interruptible\n",
 		__func__, __LINE__);
-	wait_for_completion_interruptible(&cci_dev->
-		cci_master_info[master].reset_complete);
+	wait_for_completion_interruptible_timeout(&cci_dev->
+		cci_master_info[master].reset_complete, CCI_TIMEOUT);
+
 ERROR:
 	mutex_unlock(&cci_dev->cci_master_info[master].mutex);
 	return rc;
@@ -395,7 +401,10 @@
 }
 
 static struct msm_cam_clk_info cci_clk_info[] = {
-	{"cci_clk_src", 19200000},
+	{"camss_top_ahb_clk", -1},
+	{"cci_src_clk", 19200000},
+	{"cci_ahb_clk", -1},
+	{"cci_clk", -1},
 };
 
 static int32_t msm_cci_init(struct v4l2_subdev *sd)
@@ -411,7 +420,7 @@
 	rc = msm_cam_clk_enable(&cci_dev->pdev->dev, cci_clk_info,
 		cci_dev->cci_clk, ARRAY_SIZE(cci_clk_info), 1);
 	if (rc < 0) {
-		CDBG("%s: regulator enable failed\n", __func__);
+		CDBG("%s: clk enable failed\n", __func__);
 		goto clk_enable_failed;
 	}
 
@@ -421,8 +430,9 @@
 	cci_dev->cci_master_info[MASTER_0].reset_pending = TRUE;
 	msm_camera_io_w(0xFFFFFFFF, cci_dev->base + CCI_RESET_CMD_ADDR);
 	msm_camera_io_w(0x1, cci_dev->base + CCI_RESET_CMD_ADDR);
-	wait_for_completion_interruptible(&cci_dev->cci_master_info[MASTER_0].
-		reset_complete);
+	wait_for_completion_interruptible_timeout(
+		&cci_dev->cci_master_info[MASTER_0].reset_complete,
+		CCI_TIMEOUT);
 	msm_cci_set_clk_param(cci_dev);
 	msm_camera_io_w(0xFFFFFFFF, cci_dev->base + CCI_IRQ_MASK_0_ADDR);
 	msm_camera_io_w(0xFFFFFFFF, cci_dev->base + CCI_IRQ_CLEAR_0_ADDR);
@@ -535,6 +545,12 @@
 		cci_dev->cci_master_info[MASTER_1].reset_pending = TRUE;
 		msm_camera_io_w(CCI_M1_RESET_RMSK,
 			cci_dev->base + CCI_RESET_CMD_ADDR);
+	} else {
+		pr_err("%s unhandled irq 0x%x\n", __func__, irq);
+		cci_dev->cci_master_info[MASTER_0].status = 0;
+		complete(&cci_dev->cci_master_info[MASTER_0].reset_complete);
+		cci_dev->cci_master_info[MASTER_1].status = 0;
+		complete(&cci_dev->cci_master_info[MASTER_1].reset_complete);
 	}
 	return IRQ_HANDLED;
 }
@@ -686,11 +702,6 @@
 		goto cci_release_mem;
 	}
 
-	CDBG("%s line %d cci irq start %d end %d\n", __func__,
-		__LINE__,
-		new_cci_dev->irq->start,
-		new_cci_dev->irq->end);
-
 	new_cci_dev->pdev = pdev;
 	msm_cci_initialize_cci_params(new_cci_dev);
 
diff --git a/drivers/media/video/msm/csi/include/csi2.0/msm_csid_hwreg.h b/drivers/media/video/msm/csi/include/csi2.0/msm_csid_hwreg.h
index c79748c..b66bee0 100644
--- a/drivers/media/video/msm/csi/include/csi2.0/msm_csid_hwreg.h
+++ b/drivers/media/video/msm/csi/include/csi2.0/msm_csid_hwreg.h
@@ -47,5 +47,6 @@
 #define CSID_RST_STB_ALL                            0x7FFF
 #define CSID_DL_INPUT_SEL_SHIFT                     0x2
 #define CSID_PHY_SEL_SHIFT                          0x17
+#define CSID_VERSION                                0x02000011
 
 #endif
diff --git a/drivers/media/video/msm/csi/include/csi2.0/msm_csiphy_hwreg.h b/drivers/media/video/msm/csi/include/csi2.0/msm_csiphy_hwreg.h
index 93d1fc4..2e83101 100644
--- a/drivers/media/video/msm/csi/include/csi2.0/msm_csiphy_hwreg.h
+++ b/drivers/media/video/msm/csi/include/csi2.0/msm_csiphy_hwreg.h
@@ -28,6 +28,7 @@
 #define MIPI_CSIPHY_LNCK_MISC1_ADDR              0x128
 #define MIPI_CSIPHY_GLBL_RESET_ADDR              0x140
 #define MIPI_CSIPHY_GLBL_PWR_CFG_ADDR            0x144
+#define MIPI_CSIPHY_GLBL_IRQ_CMD_ADDR            0x164
 #define MIPI_CSIPHY_INTERRUPT_STATUS0_ADDR       0x180
 #define MIPI_CSIPHY_INTERRUPT_MASK0_ADDR         0x1A0
 #define MIPI_CSIPHY_INTERRUPT_MASK_VAL           0x6F
@@ -37,5 +38,6 @@
 #define MIPI_CSIPHY_MODE_CONFIG_SHIFT            0x4
 #define MIPI_CSIPHY_GLBL_T_INIT_CFG0_ADDR        0x1E0
 #define MIPI_CSIPHY_T_WAKEUP_CFG0_ADDR           0x1E8
+#define CSIPHY_VERSION                           0x0
 
 #endif
diff --git a/drivers/media/video/msm/csi/include/csi2.0/msm_ispif_hwreg.h b/drivers/media/video/msm/csi/include/csi2.0/msm_ispif_hwreg.h
index ae842b2..d37d67e 100644
--- a/drivers/media/video/msm/csi/include/csi2.0/msm_ispif_hwreg.h
+++ b/drivers/media/video/msm/csi/include/csi2.0/msm_ispif_hwreg.h
@@ -64,6 +64,9 @@
 #define MISC_LOGIC_RST_STB           1
 #define STROBED_RST_EN               0
 
+#define ISPIF_RST_CMD_MASK           0xFE0F1FFF
+#define ISPIF_RST_CMD_1_MASK         0xFC0F1FF9
+
 #define PIX_INTF_0_OVERFLOW_IRQ      12
 #define RAW_INTF_0_OVERFLOW_IRQ      25
 #define RAW_INTF_1_OVERFLOW_IRQ      25
diff --git a/drivers/media/video/msm/csi/include/csi3.0/msm_csid_hwreg.h b/drivers/media/video/msm/csi/include/csi3.0/msm_csid_hwreg.h
index 27d5a06..ca21238 100644
--- a/drivers/media/video/msm/csi/include/csi3.0/msm_csid_hwreg.h
+++ b/drivers/media/video/msm/csi/include/csi3.0/msm_csid_hwreg.h
@@ -47,5 +47,6 @@
 #define CSID_RST_STB_ALL                            0x7FFF
 #define CSID_DL_INPUT_SEL_SHIFT                     0x4
 #define CSID_PHY_SEL_SHIFT                          0x17
+#define CSID_VERSION                                0x30000000
 
 #endif
diff --git a/drivers/media/video/msm/csi/include/csi3.0/msm_csiphy_hwreg.h b/drivers/media/video/msm/csi/include/csi3.0/msm_csiphy_hwreg.h
index 79791bd..4e640e3 100644
--- a/drivers/media/video/msm/csi/include/csi3.0/msm_csiphy_hwreg.h
+++ b/drivers/media/video/msm/csi/include/csi3.0/msm_csiphy_hwreg.h
@@ -27,15 +27,17 @@
 #define MIPI_CSIPHY_LNCK_MISC1_ADDR              0x128
 #define MIPI_CSIPHY_GLBL_RESET_ADDR              0x140
 #define MIPI_CSIPHY_GLBL_PWR_CFG_ADDR            0x144
+#define MIPI_CSIPHY_GLBL_IRQ_CMD_ADDR            0x164
 #define MIPI_CSIPHY_HW_VERSION_ADDR              0x188
 #define MIPI_CSIPHY_INTERRUPT_STATUS0_ADDR       0x18C
 #define MIPI_CSIPHY_INTERRUPT_MASK0_ADDR         0x1AC
 #define MIPI_CSIPHY_INTERRUPT_MASK_VAL           0x3F
-#define MIPI_CSIPHY_INTERRUPT_MASK_ADDR          0x1B0
+#define MIPI_CSIPHY_INTERRUPT_MASK_ADDR          0x1AC
 #define MIPI_CSIPHY_INTERRUPT_CLEAR0_ADDR        0x1CC
-#define MIPI_CSIPHY_INTERRUPT_CLEAR_ADDR         0x1D0
+#define MIPI_CSIPHY_INTERRUPT_CLEAR_ADDR         0x1CC
 #define MIPI_CSIPHY_MODE_CONFIG_SHIFT            0x4
 #define MIPI_CSIPHY_GLBL_T_INIT_CFG0_ADDR        0x1EC
 #define MIPI_CSIPHY_T_WAKEUP_CFG0_ADDR           0x1F4
+#define CSIPHY_VERSION                           0x10
 
 #endif
diff --git a/drivers/media/video/msm/csi/include/csi3.0/msm_ispif_hwreg.h b/drivers/media/video/msm/csi/include/csi3.0/msm_ispif_hwreg.h
index 5b13cc5..7c09c4f 100644
--- a/drivers/media/video/msm/csi/include/csi3.0/msm_ispif_hwreg.h
+++ b/drivers/media/video/msm/csi/include/csi3.0/msm_ispif_hwreg.h
@@ -78,6 +78,9 @@
 #define MISC_LOGIC_RST_STB           1
 #define STROBED_RST_EN               0
 
+#define ISPIF_RST_CMD_MASK           0xFE0F1FFF
+#define ISPIF_RST_CMD_1_MASK         0xFC0F1FF9
+
 #define PIX_INTF_0_OVERFLOW_IRQ      12
 #define RAW_INTF_0_OVERFLOW_IRQ      25
 #define RAW_INTF_1_OVERFLOW_IRQ      25
diff --git a/drivers/media/video/msm/csi/msm_csid.c b/drivers/media/video/msm/csi/msm_csid.c
index 8f6a98b..7996ed1 100644
--- a/drivers/media/video/msm/csi/msm_csid.c
+++ b/drivers/media/video/msm/csi/msm_csid.c
@@ -22,6 +22,8 @@
 #include "msm_cam_server.h"
 
 #define V4L2_IDENT_CSID                            50002
+#define CSID_VERSION_V2                      0x02000011
+#define CSID_VERSION_V3                      0x30000000
 
 #define DBG_CSID 0
 
@@ -160,17 +162,30 @@
 	return 0;
 }
 
-static struct msm_cam_clk_info csid_clk_info[] = {
+static struct msm_cam_clk_info csid_8960_clk_info[] = {
 	{"csi_src_clk", 177780000},
 	{"csi_clk", -1},
 	{"csi_phy_clk", -1},
 	{"csi_pclk", -1},
 };
 
-static struct camera_vreg_t csid_vreg_info[] = {
+static struct msm_cam_clk_info csid_8974_clk_info[] = {
+	{"csi_ahb_clk", -1},
+	{"csi_src_clk", 200000000},
+	{"csi_clk", -1},
+	{"csi_phy_clk", -1},
+	{"csi_pix_clk", -1},
+	{"csi_rdi_clk", -1},
+};
+
+static struct camera_vreg_t csid_8960_vreg_info[] = {
 	{"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
 };
 
+static struct camera_vreg_t csid_8974_vreg_info[] = {
+	{"mipi_csi_vdd", REG_LDO, 1800000, 1800000, 12000},
+};
+
 static int msm_csid_init(struct csid_device *csid_dev, uint32_t *csid_version)
 {
 	int rc = 0;
@@ -188,25 +203,54 @@
 		return rc;
 	}
 
-	rc = msm_camera_config_vreg(&csid_dev->pdev->dev, csid_vreg_info,
-		ARRAY_SIZE(csid_vreg_info), NULL, 0, &csid_dev->csi_vdd, 1);
-	if (rc < 0) {
-		pr_err("%s: regulator on failed\n", __func__);
-		goto vreg_config_failed;
-	}
+	if (CSID_VERSION <= CSID_VERSION_V2) {
+		rc = msm_camera_config_vreg(&csid_dev->pdev->dev,
+			csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
+			NULL, 0, &csid_dev->csi_vdd, 1);
+		if (rc < 0) {
+			pr_err("%s: regulator on failed\n", __func__);
+			goto vreg_config_failed;
+		}
 
-	rc = msm_camera_enable_vreg(&csid_dev->pdev->dev, csid_vreg_info,
-		ARRAY_SIZE(csid_vreg_info), NULL, 0, &csid_dev->csi_vdd, 1);
-	if (rc < 0) {
-		pr_err("%s: regulator enable failed\n", __func__);
-		goto vreg_enable_failed;
-	}
+		rc = msm_camera_enable_vreg(&csid_dev->pdev->dev,
+			csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
+			NULL, 0, &csid_dev->csi_vdd, 1);
+		if (rc < 0) {
+			pr_err("%s: regulator enable failed\n", __func__);
+			goto vreg_enable_failed;
+		}
 
-	rc = msm_cam_clk_enable(&csid_dev->pdev->dev, csid_clk_info,
-		csid_dev->csid_clk, ARRAY_SIZE(csid_clk_info), 1);
-	if (rc < 0) {
-		pr_err("%s: regulator enable failed\n", __func__);
-		goto clk_enable_failed;
+		rc = msm_cam_clk_enable(&csid_dev->pdev->dev,
+			csid_8960_clk_info, csid_dev->csid_clk,
+			ARRAY_SIZE(csid_8960_clk_info), 1);
+		if (rc < 0) {
+			pr_err("%s: regulator enable failed\n", __func__);
+			goto clk_enable_failed;
+		}
+	} else if (CSID_VERSION == CSID_VERSION_V3) {
+		rc = msm_camera_config_vreg(&csid_dev->pdev->dev,
+			csid_8974_vreg_info, ARRAY_SIZE(csid_8974_vreg_info),
+			NULL, 0, &csid_dev->csi_vdd, 1);
+		if (rc < 0) {
+			pr_err("%s: regulator on failed\n", __func__);
+			goto vreg_config_failed;
+		}
+
+		rc = msm_camera_enable_vreg(&csid_dev->pdev->dev,
+			csid_8974_vreg_info, ARRAY_SIZE(csid_8974_vreg_info),
+			NULL, 0, &csid_dev->csi_vdd, 1);
+		if (rc < 0) {
+			pr_err("%s: regulator enable failed\n", __func__);
+			goto vreg_enable_failed;
+		}
+
+		rc = msm_cam_clk_enable(&csid_dev->pdev->dev,
+			csid_8974_clk_info, csid_dev->csid_clk,
+			ARRAY_SIZE(csid_8974_clk_info), 1);
+		if (rc < 0) {
+			pr_err("%s: regulator enable failed\n", __func__);
+			goto clk_enable_failed;
+		}
 	}
 
 	csid_dev->hw_version =
@@ -221,11 +265,25 @@
 	return rc;
 
 clk_enable_failed:
-	msm_camera_enable_vreg(&csid_dev->pdev->dev, csid_vreg_info,
-		ARRAY_SIZE(csid_vreg_info), NULL, 0, &csid_dev->csi_vdd, 0);
+	if (CSID_VERSION <= CSID_VERSION_V2) {
+		msm_camera_enable_vreg(&csid_dev->pdev->dev,
+			csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
+			NULL, 0, &csid_dev->csi_vdd, 0);
+	} else if (CSID_VERSION == CSID_VERSION_V3) {
+		msm_camera_enable_vreg(&csid_dev->pdev->dev,
+			csid_8974_vreg_info, ARRAY_SIZE(csid_8974_vreg_info),
+			NULL, 0, &csid_dev->csi_vdd, 0);
+	}
 vreg_enable_failed:
-	msm_camera_config_vreg(&csid_dev->pdev->dev, csid_vreg_info,
-		ARRAY_SIZE(csid_vreg_info), NULL, 0, &csid_dev->csi_vdd, 0);
+	if (CSID_VERSION <= CSID_VERSION_V2) {
+		msm_camera_config_vreg(&csid_dev->pdev->dev,
+			csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
+			NULL, 0, &csid_dev->csi_vdd, 0);
+	} else if (CSID_VERSION == CSID_VERSION_V3) {
+		msm_camera_config_vreg(&csid_dev->pdev->dev,
+			csid_8974_vreg_info, ARRAY_SIZE(csid_8974_vreg_info),
+			NULL, 0, &csid_dev->csi_vdd, 0);
+	}
 vreg_config_failed:
 	iounmap(csid_dev->base);
 	csid_dev->base = NULL;
@@ -242,14 +300,29 @@
 
 	disable_irq(csid_dev->irq->start);
 
-	msm_cam_clk_enable(&csid_dev->pdev->dev, csid_clk_info,
-		csid_dev->csid_clk, ARRAY_SIZE(csid_clk_info), 0);
+	if (csid_dev->hw_version <= CSID_VERSION_V2) {
+		msm_cam_clk_enable(&csid_dev->pdev->dev, csid_8960_clk_info,
+			csid_dev->csid_clk, ARRAY_SIZE(csid_8960_clk_info), 0);
 
-	msm_camera_enable_vreg(&csid_dev->pdev->dev, csid_vreg_info,
-		ARRAY_SIZE(csid_vreg_info), NULL, 0, &csid_dev->csi_vdd, 0);
+		msm_camera_enable_vreg(&csid_dev->pdev->dev,
+			csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
+			NULL, 0, &csid_dev->csi_vdd, 0);
 
-	msm_camera_config_vreg(&csid_dev->pdev->dev, csid_vreg_info,
-		ARRAY_SIZE(csid_vreg_info), NULL, 0, &csid_dev->csi_vdd, 0);
+		msm_camera_config_vreg(&csid_dev->pdev->dev,
+			csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
+			NULL, 0, &csid_dev->csi_vdd, 0);
+	} else if (csid_dev->hw_version == CSID_VERSION_V3) {
+		msm_cam_clk_enable(&csid_dev->pdev->dev, csid_8974_clk_info,
+			csid_dev->csid_clk, ARRAY_SIZE(csid_8974_clk_info), 0);
+
+		msm_camera_enable_vreg(&csid_dev->pdev->dev,
+			csid_8974_vreg_info, ARRAY_SIZE(csid_8974_vreg_info),
+			NULL, 0, &csid_dev->csi_vdd, 0);
+
+		msm_camera_config_vreg(&csid_dev->pdev->dev,
+			csid_8974_vreg_info, ARRAY_SIZE(csid_8974_vreg_info),
+			NULL, 0, &csid_dev->csi_vdd, 0);
+	}
 
 	iounmap(csid_dev->base);
 	csid_dev->base = NULL;
diff --git a/drivers/media/video/msm/csi/msm_csiphy.c b/drivers/media/video/msm/csi/msm_csiphy.c
index 4e07b6a..3113295 100644
--- a/drivers/media/video/msm/csi/msm_csiphy.c
+++ b/drivers/media/video/msm/csi/msm_csiphy.c
@@ -78,6 +78,7 @@
 			csiphybase + MIPI_CSIPHY_GLBL_RESET_ADDR);
 	}
 
+	lane_mask &= 0x1f;
 	while (lane_mask & 0x1f) {
 		if (!(lane_mask & 0x1)) {
 			j++;
@@ -105,18 +106,23 @@
 	int i;
 	struct csiphy_device *csiphy_dev = data;
 
-	for (i = 0; i < 5; i++) {
+	for (i = 0; i < 8; i++) {
 		irq = msm_camera_io_r(
 			csiphy_dev->base +
 			MIPI_CSIPHY_INTERRUPT_STATUS0_ADDR + 0x4*i);
 		msm_camera_io_w(irq,
 			csiphy_dev->base +
 			MIPI_CSIPHY_INTERRUPT_CLEAR0_ADDR + 0x4*i);
-		CDBG("%s MIPI_CSIPHY%d_INTERRUPT_STATUS%d = 0x%x\n",
+		pr_err("%s MIPI_CSIPHY%d_INTERRUPT_STATUS%d = 0x%x\n",
 			 __func__, csiphy_dev->pdev->id, i, irq);
+		msm_camera_io_w(0x1, csiphy_dev->base +
+			MIPI_CSIPHY_GLBL_IRQ_CMD_ADDR);
+		msm_camera_io_w(0x0, csiphy_dev->base +
+			MIPI_CSIPHY_GLBL_IRQ_CMD_ADDR);
+		msm_camera_io_w(0x0,
+			csiphy_dev->base +
+			MIPI_CSIPHY_INTERRUPT_CLEAR0_ADDR + 0x4*i);
 	}
-	msm_camera_io_w(0x1, csiphy_dev->base + 0x164);
-	msm_camera_io_w(0x0, csiphy_dev->base + 0x164);
 	return IRQ_HANDLED;
 }
 
@@ -136,11 +142,17 @@
 	return 0;
 }
 
-static struct msm_cam_clk_info csiphy_clk_info[] = {
+static struct msm_cam_clk_info csiphy_8960_clk_info[] = {
 	{"csiphy_timer_src_clk", 177780000},
 	{"csiphy_timer_clk", -1},
 };
 
+static struct msm_cam_clk_info csiphy_8974_clk_info[] = {
+	{"ispif_ahb_clk", -1},
+	{"csiphy_timer_src_clk", 200000000},
+	{"csiphy_timer_clk", -1},
+};
+
 static int msm_csiphy_init(struct csiphy_device *csiphy_dev)
 {
 	int rc = 0;
@@ -165,8 +177,14 @@
 		return rc;
 	}
 
-	rc = msm_cam_clk_enable(&csiphy_dev->pdev->dev, csiphy_clk_info,
-			csiphy_dev->csiphy_clk, ARRAY_SIZE(csiphy_clk_info), 1);
+	if (CSIPHY_VERSION != CSIPHY_VERSION_V3)
+		rc = msm_cam_clk_enable(&csiphy_dev->pdev->dev,
+			csiphy_8960_clk_info, csiphy_dev->csiphy_clk,
+			ARRAY_SIZE(csiphy_8960_clk_info), 1);
+	else
+		rc = msm_cam_clk_enable(&csiphy_dev->pdev->dev,
+			csiphy_8974_clk_info, csiphy_dev->csiphy_clk,
+			ARRAY_SIZE(csiphy_8974_clk_info), 1);
 
 	if (rc < 0) {
 		pr_err("%s: csiphy clk enable failed\n", __func__);
@@ -235,8 +253,14 @@
 #if DBG_CSIPHY
 	disable_irq(csiphy_dev->irq->start);
 #endif
-	msm_cam_clk_enable(&csiphy_dev->pdev->dev, csiphy_clk_info,
-		csiphy_dev->csiphy_clk, ARRAY_SIZE(csiphy_clk_info), 0);
+	if (CSIPHY_VERSION != CSIPHY_VERSION_V3)
+		msm_cam_clk_enable(&csiphy_dev->pdev->dev,
+			csiphy_8960_clk_info, csiphy_dev->csiphy_clk,
+			ARRAY_SIZE(csiphy_8960_clk_info), 0);
+	else
+		msm_cam_clk_enable(&csiphy_dev->pdev->dev,
+			csiphy_8974_clk_info, csiphy_dev->csiphy_clk,
+			ARRAY_SIZE(csiphy_8974_clk_info), 0);
 
 	iounmap(csiphy_dev->base);
 	csiphy_dev->base = NULL;
@@ -317,7 +341,6 @@
 	int rc = 0;
 	struct msm_cam_subdev_info sd_info;
 
-	CDBG("%s: device id = %d\n", __func__, pdev->id);
 	new_csiphy_dev = kzalloc(sizeof(struct csiphy_device), GFP_KERNEL);
 	if (!new_csiphy_dev) {
 		pr_err("%s: no enough memory\n", __func__);
@@ -337,6 +360,7 @@
 	if (pdev->dev.of_node)
 		of_property_read_u32((&pdev->dev)->of_node,
 			"cell-index", &pdev->id);
+	CDBG("%s: device id = %d\n", __func__, pdev->id);
 
 	new_csiphy_dev->mem = platform_get_resource_byname(pdev,
 					IORESOURCE_MEM, "csiphy");
diff --git a/drivers/media/video/msm/csi/msm_csiphy.h b/drivers/media/video/msm/csi/msm_csiphy.h
index 01eacb6..4b2e68e 100644
--- a/drivers/media/video/msm/csi/msm_csiphy.h
+++ b/drivers/media/video/msm/csi/msm_csiphy.h
@@ -30,7 +30,7 @@
 	struct mutex mutex;
 	uint32_t hw_version;
 
-	struct clk *csiphy_clk[2];
+	struct clk *csiphy_clk[3];
 	uint8_t ref_count;
 	uint16_t lane_mask[MAX_CSIPHY];
 };
diff --git a/drivers/media/video/msm/csi/msm_ispif.c b/drivers/media/video/msm/csi/msm_ispif.c
index 479fc028..ab97138 100644
--- a/drivers/media/video/msm/csi/msm_ispif.c
+++ b/drivers/media/video/msm/csi/msm_ispif.c
@@ -37,7 +37,6 @@
 {
 	int rc = 0;
 	uint32_t data = (0x1 << STROBED_RST_EN);
-	uint32_t data1 = (0x1 << STROBED_RST_EN);
 	uint16_t intfnum = 0, mask = intfmask;
 
 	while (mask != 0) {
@@ -48,49 +47,29 @@
 		}
 		switch (intfnum) {
 		case PIX0:
-			if (vfe_intf == VFE0)
-				data |= (0x1 << PIX_0_VFE_RST_STB) |
-					(0x1 << PIX_0_CSID_RST_STB);
-			else
-				data1 |= (0x1 << PIX_0_VFE_RST_STB) |
-					(0x1 << PIX_0_CSID_RST_STB);
+			data |= (0x1 << PIX_0_VFE_RST_STB) |
+				(0x1 << PIX_0_CSID_RST_STB);
 			ispif->pix_sof_count = 0;
 			break;
 
 		case RDI0:
-			if (vfe_intf == VFE0)
-				data |= (0x1 << RDI_0_VFE_RST_STB) |
-					(0x1 << RDI_0_CSID_RST_STB);
-			else
-				data1 |= (0x1 << RDI_0_VFE_RST_STB) |
-					(0x1 << RDI_0_CSID_RST_STB);
+			data |= (0x1 << RDI_0_VFE_RST_STB) |
+				(0x1 << RDI_0_CSID_RST_STB);
 			break;
 
 		case PIX1:
-			if (vfe_intf == VFE0)
-				data |= (0x1 << PIX_1_VFE_RST_STB) |
-					(0x1 << PIX_1_CSID_RST_STB);
-			else
-				data1 |= (0x1 << PIX_1_VFE_RST_STB) |
-					(0x1 << PIX_1_CSID_RST_STB);
+			data |= (0x1 << PIX_1_VFE_RST_STB) |
+				(0x1 << PIX_1_CSID_RST_STB);
 			break;
 
 		case RDI1:
-			if (vfe_intf == VFE0)
-				data |= (0x1 << RDI_1_VFE_RST_STB) |
-					(0x1 << RDI_1_CSID_RST_STB);
-			else
-				data1 |= (0x1 << RDI_1_VFE_RST_STB) |
-					(0x1 << RDI_1_CSID_RST_STB);
+			data |= (0x1 << RDI_1_VFE_RST_STB) |
+				(0x1 << RDI_1_CSID_RST_STB);
 			break;
 
 		case RDI2:
-			if (vfe_intf == VFE0)
-				data |= (0x1 << RDI_2_VFE_RST_STB) |
-					(0x1 << RDI_2_CSID_RST_STB);
-			else
-				data1 |= (0x1 << RDI_2_VFE_RST_STB) |
-					(0x1 << RDI_2_CSID_RST_STB);
+			data |= (0x1 << RDI_2_VFE_RST_STB) |
+				(0x1 << RDI_2_CSID_RST_STB);
 			break;
 
 		default:
@@ -100,43 +79,26 @@
 		mask >>= 1;
 		intfnum++;
 	}	/*end while */
-	msm_camera_io_w(data, ispif->base + ISPIF_RST_CMD_ADDR);
-	rc = wait_for_completion_interruptible(&ispif->reset_complete);
-	if (ispif->csid_version >= CSID_VERSION_V3 && data1 > 0x1) {
-		msm_camera_io_w(data1,
-			ispif->base + ISPIF_RST_CMD_1_ADDR);
-		rc = wait_for_completion_interruptible(&ispif->
-			reset_complete);
+	if (data > 0x1) {
+		if (vfe_intf == VFE0)
+			msm_camera_io_w(data, ispif->base + ISPIF_RST_CMD_ADDR);
+		else
+			msm_camera_io_w(data, ispif->base +
+				ISPIF_RST_CMD_1_ADDR);
+		rc = wait_for_completion_interruptible(&ispif->reset_complete);
 	}
-
 	return rc;
 }
 
 static int msm_ispif_reset(struct ispif_device *ispif)
 {
 	int rc = 0;
-	uint32_t data = (0x1 << STROBED_RST_EN) |
-		(0x1 << SW_REG_RST_STB) |
-		(0x1 << MISC_LOGIC_RST_STB) |
-		(0x1 << PIX_0_VFE_RST_STB) |
-		(0x1 << PIX_0_CSID_RST_STB) |
-		(0x1 << RDI_0_VFE_RST_STB) |
-		(0x1 << RDI_0_CSID_RST_STB) |
-		(0x1 << RDI_1_VFE_RST_STB) |
-		(0x1 << RDI_1_CSID_RST_STB);
-
-	if (ispif->csid_version >= CSID_VERSION_V2)
-		data |= (0x1 << PIX_1_VFE_RST_STB) |
-			(0x1 << PIX_1_CSID_RST_STB) |
-			(0x1 << RDI_2_VFE_RST_STB) |
-			(0x1 << RDI_2_CSID_RST_STB);
 	ispif->pix_sof_count = 0;
-	msm_camera_io_w(data, ispif->base + ISPIF_RST_CMD_ADDR);
+	msm_camera_io_w(ISPIF_RST_CMD_MASK, ispif->base + ISPIF_RST_CMD_ADDR);
+	if (ispif->csid_version == CSID_VERSION_V3)
+		msm_camera_io_w(ISPIF_RST_CMD_1_MASK, ispif->base +
+				ISPIF_RST_CMD_1_ADDR);
 	rc = wait_for_completion_interruptible(&ispif->reset_complete);
-	if (ispif->csid_version >= CSID_VERSION_V3) {
-		msm_camera_io_w(data, ispif->base + ISPIF_RST_CMD_1_ADDR);
-		rc = wait_for_completion_interruptible(&ispif->reset_complete);
-	}
 	return rc;
 }
 
@@ -155,15 +117,15 @@
 	int rc = 0;
 	uint32_t data;
 
-	if (ispif->ispif_clk[intftype] == NULL) {
-		pr_err("%s: ispif NULL clk\n", __func__);
-		return;
+	if (ispif->csid_version <= CSID_VERSION_V2) {
+		if (ispif->ispif_clk[intftype] == NULL) {
+			pr_err("%s: ispif NULL clk\n", __func__);
+			return;
+		}
+		rc = clk_set_rate(ispif->ispif_clk[intftype], csid);
+		if (rc < 0)
+			pr_err("%s: clk_set_rate failed %d\n", __func__, rc);
 	}
-
-	rc = clk_set_rate(ispif->ispif_clk[intftype], csid);
-	if (rc < 0)
-		pr_err("%s: clk_set_rate failed %d\n", __func__, rc);
-
 	data = msm_camera_io_r(ispif->base + ISPIF_INPUT_SEL_ADDR +
 		(0x200 * vfe_intf));
 	switch (intftype) {
@@ -566,7 +528,6 @@
 
 	struct ispif_isr_queue_cmd *qcmd = NULL;
 	struct ispif_device *ispif;
-	CDBG("=== ispif_do_tasklet start ===\n");
 
 	ispif = (struct ispif_device *)data;
 	while (atomic_read(&ispif_irq_cnt)) {
@@ -606,7 +567,6 @@
 		spin_unlock_irqrestore(&ispif_sof_lock, flags);
 		kfree(qcmd);
 	}
-	CDBG("=== ispif_do_tasklet end ===\n");
 }
 
 static void ispif_process_irq(struct ispif_device *ispif,
@@ -615,7 +575,6 @@
 	unsigned long flags;
 	struct ispif_isr_queue_cmd *qcmd;
 
-	CDBG("ispif_process_irq\n");
 	qcmd = kzalloc(sizeof(struct ispif_isr_queue_cmd),
 		GFP_ATOMIC);
 	if (!qcmd) {
@@ -646,6 +605,7 @@
 static inline void msm_ispif_read_irq_status(struct ispif_irq_status *out,
 	void *data)
 {
+	uint32_t status0 = 0, status1 = 0, status2 = 0;
 	struct ispif_device *ispif = (struct ispif_device *)data;
 	out->ispifIrqStatus0 = msm_camera_io_r(ispif->base +
 		ISPIF_IRQ_STATUS_ADDR);
@@ -660,8 +620,9 @@
 	msm_camera_io_w(out->ispifIrqStatus2,
 		ispif->base + ISPIF_IRQ_CLEAR_2_ADDR);
 
-	CDBG("%s: irq ispif->irq: Irq_status0 = 0x%x\n", __func__,
-		out->ispifIrqStatus0);
+	CDBG("%s: irq vfe0 Irq_status0 = 0x%x, 1 = 0x%x, 2 = 0x%x\n",
+		__func__, out->ispifIrqStatus0, out->ispifIrqStatus1,
+		out->ispifIrqStatus2);
 	if (out->ispifIrqStatus0 & ISPIF_IRQ_STATUS_MASK) {
 		if (out->ispifIrqStatus0 & (0x1 << RESET_DONE_IRQ))
 			complete(&ispif->reset_complete);
@@ -678,6 +639,22 @@
 			(out->ispifIrqStatus2 & ISPIF_IRQ_STATUS_RDI2_SOF_MASK))
 			ispif_process_irq(ispif, out);
 	}
+	if (ispif->csid_version == CSID_VERSION_V3) {
+		status0 = msm_camera_io_r(ispif->base +
+			ISPIF_IRQ_STATUS_ADDR + 0x200);
+		msm_camera_io_w(status0,
+			ispif->base + ISPIF_IRQ_CLEAR_ADDR + 0x200);
+		status1 = msm_camera_io_r(ispif->base +
+			ISPIF_IRQ_STATUS_1_ADDR + 0x200);
+		msm_camera_io_w(status1,
+			ispif->base + ISPIF_IRQ_CLEAR_1_ADDR + 0x200);
+		status2 = msm_camera_io_r(ispif->base +
+			ISPIF_IRQ_STATUS_2_ADDR + 0x200);
+		msm_camera_io_w(status2,
+			ispif->base + ISPIF_IRQ_CLEAR_2_ADDR + 0x200);
+		CDBG("%s: irq vfe1 Irq_status0 = 0x%x, 1 = 0x%x, 2 = 0x%x\n",
+			__func__, status0, status1, status2);
+	}
 	msm_camera_io_w(ISPIF_IRQ_GLOBAL_CLEAR_CMD, ispif->base +
 		ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR);
 }
@@ -689,7 +666,7 @@
 	return IRQ_HANDLED;
 }
 
-static struct msm_cam_clk_info ispif_clk_info[] = {
+static struct msm_cam_clk_info ispif_8960_clk_info[] = {
 	{"csi_pix_clk", 0},
 	{"csi_rdi_clk", 0},
 	{"csi_pix1_clk", 0},
@@ -712,14 +689,14 @@
 		ispif_do_tasklet, (unsigned long)ispif);
 
 	ispif->csid_version = *csid_version;
-	if (ispif->csid_version >= CSID_VERSION_V2) {
-		rc = msm_cam_clk_enable(&ispif->pdev->dev, ispif_clk_info,
-			ispif->ispif_clk, ARRAY_SIZE(ispif_clk_info), 1);
+	if (ispif->csid_version < CSID_VERSION_V2) {
+		rc = msm_cam_clk_enable(&ispif->pdev->dev, ispif_8960_clk_info,
+			ispif->ispif_clk, 2, 1);
 		if (rc < 0)
 			return rc;
-	} else {
-		rc = msm_cam_clk_enable(&ispif->pdev->dev, ispif_clk_info,
-			ispif->ispif_clk, 2, 1);
+	} else if (ispif->csid_version == CSID_VERSION_V2) {
+		rc = msm_cam_clk_enable(&ispif->pdev->dev, ispif_8960_clk_info,
+			ispif->ispif_clk, ARRAY_SIZE(ispif_8960_clk_info), 1);
 		if (rc < 0)
 			return rc;
 	}
@@ -733,12 +710,13 @@
 	free_irq(ispif->irq->start, ispif);
 	tasklet_kill(&ispif->ispif_tasklet);
 
-	if (ispif->csid_version == CSID_VERSION_V2)
-		msm_cam_clk_enable(&ispif->pdev->dev, ispif_clk_info,
-			ispif->ispif_clk, ARRAY_SIZE(ispif_clk_info), 0);
-	else
-		msm_cam_clk_enable(&ispif->pdev->dev, ispif_clk_info,
+	if (ispif->csid_version < CSID_VERSION_V2) {
+		msm_cam_clk_enable(&ispif->pdev->dev, ispif_8960_clk_info,
 			ispif->ispif_clk, 2, 0);
+	} else if (ispif->csid_version == CSID_VERSION_V2) {
+		msm_cam_clk_enable(&ispif->pdev->dev, ispif_8960_clk_info,
+			ispif->ispif_clk, ARRAY_SIZE(ispif_8960_clk_info), 0);
+	}
 }
 
 static long msm_ispif_cmd(struct v4l2_subdev *sd, void *arg)
diff --git a/drivers/media/video/msm/io/msm_camera_i2c.c b/drivers/media/video/msm/io/msm_camera_i2c.c
index d05f1f2..27ebac5 100644
--- a/drivers/media/video/msm/io/msm_camera_i2c.c
+++ b/drivers/media/video/msm/io/msm_camera_i2c.c
@@ -84,6 +84,7 @@
 		cci_ctrl.cci_info = client->cci_client;
 		cci_ctrl.cfg.cci_i2c_write_cfg.reg_conf_tbl = &reg_conf_tbl;
 		cci_ctrl.cfg.cci_i2c_write_cfg.data_type = data_type;
+		cci_ctrl.cfg.cci_i2c_write_cfg.addr_type = client->addr_type;
 		cci_ctrl.cfg.cci_i2c_write_cfg.size = 1;
 		rc = v4l2_subdev_call(client->cci_client->cci_subdev,
 				core, ioctl, VIDIOC_MSM_CCI_CFG, &cci_ctrl);
@@ -381,6 +382,7 @@
 		cci_ctrl.cci_info = client->cci_client;
 		cci_ctrl.cfg.cci_i2c_write_cfg.reg_conf_tbl = reg_conf_tbl;
 		cci_ctrl.cfg.cci_i2c_write_cfg.data_type = data_type;
+		cci_ctrl.cfg.cci_i2c_write_cfg.addr_type = client->addr_type;
 		cci_ctrl.cfg.cci_i2c_write_cfg.size = size;
 		rc = v4l2_subdev_call(client->cci_client->cci_subdev,
 				core, ioctl, VIDIOC_MSM_CCI_CFG, &cci_ctrl);
diff --git a/drivers/media/video/msm/io/msm_camera_i2c.h b/drivers/media/video/msm/io/msm_camera_i2c.h
index 605efff..35b3bd4 100644
--- a/drivers/media/video/msm/io/msm_camera_i2c.h
+++ b/drivers/media/video/msm/io/msm_camera_i2c.h
@@ -27,19 +27,6 @@
 #define S_I2C_DBG(fmt, args...) CDBG(fmt, ##args)
 #endif
 
-enum msm_camera_i2c_cmd_type {
-	MSM_CAMERA_I2C_CMD_WRITE,
-	MSM_CAMERA_I2C_CMD_POLL,
-};
-
-struct msm_camera_i2c_reg_conf {
-	uint16_t reg_addr;
-	uint16_t reg_data;
-	enum msm_camera_i2c_data_type dt;
-	enum msm_camera_i2c_cmd_type cmd_type;
-	int16_t mask;
-};
-
 struct msm_camera_i2c_client {
 	struct i2c_client *client;
 	struct msm_camera_cci_client *cci_client;
diff --git a/drivers/media/video/msm/msm.c b/drivers/media/video/msm/msm.c
index 0d15f75..98b2372 100644
--- a/drivers/media/video/msm/msm.c
+++ b/drivers/media/video/msm/msm.c
@@ -1278,11 +1278,21 @@
 {
 	int rc = -ENOMEM;
 	struct video_device *pvdev = NULL;
-	struct i2c_client *client = v4l2_get_subdevdata(pcam->sensor_sdev);
+	struct i2c_client *client = NULL;
+	struct platform_device *pdev = NULL;
 	D("%s\n", __func__);
 
 	/* first register the v4l2 device */
-	pcam->v4l2_dev.dev = &client->dev;
+	if (pcam->sensor_sdev->flags & V4L2_SUBDEV_FL_IS_I2C) {
+		client = v4l2_get_subdevdata(pcam->sensor_sdev);
+		pcam->v4l2_dev.dev = &client->dev;
+		pcam->media_dev.dev = &client->dev;
+	} else {
+		pdev = v4l2_get_subdevdata(pcam->sensor_sdev);
+		pcam->v4l2_dev.dev = &pdev->dev;
+		pcam->media_dev.dev = &pdev->dev;
+	}
+
 	rc = v4l2_device_register(pcam->v4l2_dev.dev, &pcam->v4l2_dev);
 	if (rc < 0)
 		return -EINVAL;
@@ -1299,7 +1309,6 @@
 
 	strlcpy(pcam->media_dev.model, QCAMERA_NAME,
 			sizeof(pcam->media_dev.model));
-	pcam->media_dev.dev = &client->dev;
 	rc = media_device_register(&pcam->media_dev);
 	pvdev->v4l2_dev = &pcam->v4l2_dev;
 	pcam->v4l2_dev.mdev = &pcam->media_dev;
@@ -1358,7 +1367,7 @@
 
 	D("%s called\n", __func__);
 
-	if (!actuator_info)
+	if (!actuator_info || !actuator_info->board_info)
 		goto probe_fail;
 
 	adapter = i2c_get_adapter(actuator_info->bus_id);
@@ -1401,7 +1410,7 @@
 
 	D("%s called\n", __func__);
 
-	if (!eeprom_info)
+	if (!eeprom_info || !eeprom_info->board_info)
 		goto probe_fail;
 
 	adapter = i2c_get_adapter(eeprom_info->bus_id);
diff --git a/drivers/media/video/msm/msm_mctl.c b/drivers/media/video/msm/msm_mctl.c
index fac1ffd..0711ca5 100644
--- a/drivers/media/video/msm/msm_mctl.c
+++ b/drivers/media/video/msm/msm_mctl.c
@@ -1601,12 +1601,20 @@
 {
 	int rc = -EINVAL;
 	struct video_device *pvdev = NULL;
-	struct i2c_client *client = v4l2_get_subdevdata(pcam->sensor_sdev);
-
+	struct i2c_client *client = NULL;
+	struct platform_device *pdev = NULL;
 	D("%s\n", __func__);
 
 	/* first register the v4l2 device */
-	pcam->mctl_node.v4l2_dev.dev = &client->dev;
+	if (pcam->sensor_sdev->flags & V4L2_SUBDEV_FL_IS_I2C) {
+		client = v4l2_get_subdevdata(pcam->sensor_sdev);
+		pcam->mctl_node.v4l2_dev.dev = &client->dev;
+	} else {
+		pdev = v4l2_get_subdevdata(pcam->sensor_sdev);
+		pcam->mctl_node.v4l2_dev.dev = &pdev->dev;
+	}
+
+	/* first register the v4l2 device */
 	rc = v4l2_device_register(pcam->mctl_node.v4l2_dev.dev,
 				&pcam->mctl_node.v4l2_dev);
 	if (rc < 0)
diff --git a/drivers/media/video/msm/sensors/msm_sensor.c b/drivers/media/video/msm/sensors/msm_sensor.c
index 69584d5..6c03002 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.c
+++ b/drivers/media/video/msm/sensors/msm_sensor.c
@@ -9,7 +9,8 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  */
-
+#include <mach/msm_bus.h>
+#include <mach/msm_bus_board.h>
 #include "msm_sensor.h"
 #include "msm_sensor_common.h"
 #include "msm.h"
@@ -274,6 +275,7 @@
 	}
 	return rc;
 }
+
 int32_t msm_sensor_setting(struct msm_sensor_ctrl_t *s_ctrl,
 			int update_type, int res)
 {
@@ -562,10 +564,15 @@
 	return rc;
 }
 
-static struct msm_cam_clk_info cam_clk_info[] = {
+static struct msm_cam_clk_info cam_8960_clk_info[] = {
 	{"cam_clk", MSM_SENSOR_MCLK_24HZ},
 };
 
+static struct msm_cam_clk_info cam_8974_clk_info[] = {
+	{"cam_src_clk", 19200000},
+	{"cam_clk", -1},
+};
+
 int32_t msm_sensor_enable_i2c_mux(struct msm_camera_i2c_conf *i2c_conf)
 {
 	struct v4l2_subdev *i2c_mux_sd =
@@ -710,7 +717,8 @@
 }
 
 static int32_t msm_sensor_init_gpio_common_tbl_data(struct device_node *of_node,
-	struct msm_camera_gpio_conf *gconf)
+	struct msm_camera_gpio_conf *gconf, uint16_t *gpio_array,
+	uint16_t gpio_array_size)
 {
 	int32_t rc = 0, i = 0;
 	uint32_t count = 0;
@@ -720,9 +728,14 @@
 		return 0;
 
 	count /= sizeof(uint32_t);
-
-	if (!count)
+	if (!count) {
+		pr_err("%s gpio_common_tbl_num 0\n", __func__);
 		return 0;
+	} else if (count > gpio_array_size) {
+		pr_err("%s gpio common tbl size exceeds gpio array\n",
+			__func__);
+		return -EFAULT;
+	}
 
 	val_array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
 	if (!val_array) {
@@ -746,7 +759,12 @@
 		goto ERROR2;
 	}
 	for (i = 0; i < count; i++) {
-		gconf->cam_gpio_common_tbl[i].gpio = val_array[i];
+		if (val_array[i] >= gpio_array_size) {
+			pr_err("%s gpio common tbl index %d invalid\n",
+				__func__, val_array[i]);
+			return -EINVAL;
+		}
+		gconf->cam_gpio_common_tbl[i].gpio = gpio_array[val_array[i]];
 		CDBG("%s cam_gpio_common_tbl[%d].gpio = %d\n", __func__, i,
 			gconf->cam_gpio_common_tbl[i].gpio);
 	}
@@ -787,7 +805,8 @@
 }
 
 static int32_t msm_sensor_init_gpio_req_tbl_data(struct device_node *of_node,
-	struct msm_camera_gpio_conf *gconf)
+	struct msm_camera_gpio_conf *gconf, uint16_t *gpio_array,
+	uint16_t gpio_array_size)
 {
 	int32_t rc = 0, i = 0;
 	uint32_t count = 0;
@@ -797,9 +816,10 @@
 		return 0;
 
 	count /= sizeof(uint32_t);
-
-	if (!count)
+	if (!count) {
+		pr_err("%s gpio_req_tbl_num 0\n", __func__);
 		return 0;
+	}
 
 	val_array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
 	if (!val_array) {
@@ -823,7 +843,12 @@
 		goto ERROR2;
 	}
 	for (i = 0; i < count; i++) {
-		gconf->cam_gpio_req_tbl[i].gpio = val_array[i];
+		if (val_array[i] >= gpio_array_size) {
+			pr_err("%s gpio req tbl index %d invalid\n",
+				__func__, val_array[i]);
+			return -EINVAL;
+		}
+		gconf->cam_gpio_req_tbl[i].gpio = gpio_array[val_array[i]];
 		CDBG("%s cam_gpio_req_tbl[%d].gpio = %d\n", __func__, i,
 			gconf->cam_gpio_req_tbl[i].gpio);
 	}
@@ -864,7 +889,8 @@
 }
 
 static int32_t msm_sensor_init_gpio_set_tbl_data(struct device_node *of_node,
-	struct msm_camera_gpio_conf *gconf)
+	struct msm_camera_gpio_conf *gconf, uint16_t *gpio_array,
+	uint16_t gpio_array_size)
 {
 	int32_t rc = 0, i = 0;
 	uint32_t count = 0;
@@ -874,9 +900,10 @@
 		return 0;
 
 	count /= sizeof(uint32_t);
-
-	if (!count)
+	if (!count) {
+		pr_err("%s gpio_set_tbl_num 0\n", __func__);
 		return 0;
+	}
 
 	val_array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
 	if (!val_array) {
@@ -900,7 +927,12 @@
 		goto ERROR2;
 	}
 	for (i = 0; i < count; i++) {
-		gconf->cam_gpio_set_tbl[i].gpio = val_array[i];
+		if (val_array[i] >= gpio_array_size) {
+			pr_err("%s gpio set tbl index %d invalid\n",
+				__func__, val_array[i]);
+			return -EINVAL;
+		}
+		gconf->cam_gpio_set_tbl[i].gpio = gpio_array[val_array[i]];
 		CDBG("%s cam_gpio_set_tbl[%d].gpio = %d\n", __func__, i,
 			gconf->cam_gpio_set_tbl[i].gpio);
 	}
@@ -941,7 +973,8 @@
 }
 
 static int32_t msm_sensor_init_gpio_tlmm_tbl_data(struct device_node *of_node,
-	struct msm_camera_gpio_conf *gconf)
+	struct msm_camera_gpio_conf *gconf, uint16_t *gpio_array,
+	uint16_t gpio_array_size)
 {
 	int32_t rc = 0, i = 0;
 	uint32_t count = 0;
@@ -992,7 +1025,12 @@
 		goto ERROR4;
 	}
 	for (i = 0; i < count; i++) {
-		tlmm_cfg[i].gpio = val_array[i];
+		if (val_array[i] >= gpio_array_size) {
+			pr_err("%s gpio set tbl index %d invalid\n",
+				__func__, val_array[i]);
+			return -EINVAL;
+		}
+		tlmm_cfg[i].gpio = gpio_array[val_array[i]];
 		CDBG("%s tlmm_cfg[%d].gpio = %d\n", __func__, i,
 			tlmm_cfg[i].gpio);
 	}
@@ -1184,12 +1222,14 @@
 static int32_t msm_sensor_init_sensor_data(struct platform_device *pdev,
 	struct msm_sensor_ctrl_t *s_ctrl)
 {
-	int32_t rc = 0;
+	int32_t rc = 0, i = 0;
 	uint32_t val = 0;
 	struct device_node *of_node = pdev->dev.of_node;
 	struct msm_camera_sensor_platform_info *pinfo = NULL;
 	struct msm_camera_gpio_conf *gconf = NULL;
 	struct msm_camera_sensor_info *sensordata = NULL;
+	uint16_t *gpio_array = NULL;
+	uint16_t gpio_array_size = 0;
 
 	s_ctrl->sensordata = kzalloc(sizeof(struct msm_camera_sensor_info),
 		GFP_KERNEL);
@@ -1199,6 +1239,7 @@
 	}
 
 	sensordata = s_ctrl->sensordata;
+
 	rc = of_property_read_string(of_node, "sensor_name",
 		&sensordata->sensor_name);
 	CDBG("%s sensor_name %s, rc %d\n", __func__,
@@ -1276,36 +1317,57 @@
 		goto ERROR5;
 	}
 
-	rc = msm_sensor_init_gpio_common_tbl_data(of_node, gconf);
-	if (rc < 0) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		goto ERROR5;
-	}
+	gpio_array_size = of_gpio_count(of_node);
+	CDBG("%s gpio count %d\n", __func__, gpio_array_size);
 
-	rc = msm_sensor_init_gpio_req_tbl_data(of_node, gconf);
-	if (rc < 0) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		goto ERROR6;
-	}
+	if (gpio_array_size) {
+		gpio_array = kzalloc(sizeof(uint16_t) * gpio_array_size,
+			GFP_KERNEL);
+		if (!gpio_array) {
+			pr_err("%s failed %d\n", __func__, __LINE__);
+			goto ERROR5;
+		}
+		for (i = 0; i < gpio_array_size; i++) {
+			gpio_array[i] = of_get_gpio(of_node, i);
+			CDBG("%s gpio_array[%d] = %d\n", __func__, i,
+				gpio_array[i]);
+		}
 
-	rc = msm_sensor_init_gpio_set_tbl_data(of_node, gconf);
-	if (rc < 0) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		goto ERROR7;
-	}
+		rc = msm_sensor_init_gpio_common_tbl_data(of_node, gconf,
+			gpio_array, gpio_array_size);
+		if (rc < 0) {
+			pr_err("%s failed %d\n", __func__, __LINE__);
+			goto ERROR5;
+		}
 
-	rc = msm_sensor_init_gpio_tlmm_tbl_data(of_node, gconf);
-	if (rc < 0) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		goto ERROR8;
-	}
+		rc = msm_sensor_init_gpio_req_tbl_data(of_node, gconf,
+			gpio_array, gpio_array_size);
+		if (rc < 0) {
+			pr_err("%s failed %d\n", __func__, __LINE__);
+			goto ERROR6;
+		}
 
+		rc = msm_sensor_init_gpio_set_tbl_data(of_node, gconf,
+			gpio_array, gpio_array_size);
+		if (rc < 0) {
+			pr_err("%s failed %d\n", __func__, __LINE__);
+			goto ERROR7;
+		}
+
+		rc = msm_sensor_init_gpio_tlmm_tbl_data(of_node, gconf,
+			gpio_array, gpio_array_size);
+		if (rc < 0) {
+			pr_err("%s failed %d\n", __func__, __LINE__);
+			goto ERROR8;
+		}
+	}
 	rc = msm_sensor_init_actuator_data(of_node, sensordata);
 	if (rc < 0) {
 		pr_err("%s failed %d\n", __func__, __LINE__);
 		goto ERROR9;
 	}
 
+	kfree(gpio_array);
 	return rc;
 
 ERROR9:
@@ -1334,6 +1396,7 @@
 	kfree(s_ctrl->sensordata->flash_data);
 ERROR1:
 	kfree(s_ctrl->sensordata);
+	kfree(gpio_array);
 	return rc;
 }
 
@@ -1365,7 +1428,11 @@
 {
 	int32_t rc = 0;
 	struct msm_camera_sensor_info *data = s_ctrl->sensordata;
-	CDBG("%s: %d\n", __func__, __LINE__);
+	struct device *dev = NULL;
+	if (s_ctrl->sensor_device_type == MSM_SENSOR_PLATFORM_DEVICE)
+		dev = &s_ctrl->pdev->dev;
+	else
+		dev = &s_ctrl->sensor_i2c_client->client->dev;
 	s_ctrl->reg_ptr = kzalloc(sizeof(struct regulator *)
 			* data->sensor_platform_info->num_vreg, GFP_KERNEL);
 	if (!s_ctrl->reg_ptr) {
@@ -1380,23 +1447,23 @@
 		goto request_gpio_failed;
 	}
 
-	rc = msm_camera_config_vreg(&s_ctrl->sensor_i2c_client->client->dev,
-			s_ctrl->sensordata->sensor_platform_info->cam_vreg,
-			s_ctrl->sensordata->sensor_platform_info->num_vreg,
-			s_ctrl->vreg_seq,
-			s_ctrl->num_vreg_seq,
-			s_ctrl->reg_ptr, 1);
+	rc = msm_camera_config_vreg(dev,
+		s_ctrl->sensordata->sensor_platform_info->cam_vreg,
+		s_ctrl->sensordata->sensor_platform_info->num_vreg,
+		s_ctrl->vreg_seq,
+		s_ctrl->num_vreg_seq,
+		s_ctrl->reg_ptr, 1);
 	if (rc < 0) {
 		pr_err("%s: regulator on failed\n", __func__);
 		goto config_vreg_failed;
 	}
 
-	rc = msm_camera_enable_vreg(&s_ctrl->sensor_i2c_client->client->dev,
-			s_ctrl->sensordata->sensor_platform_info->cam_vreg,
-			s_ctrl->sensordata->sensor_platform_info->num_vreg,
-			s_ctrl->vreg_seq,
-			s_ctrl->num_vreg_seq,
-			s_ctrl->reg_ptr, 1);
+	rc = msm_camera_enable_vreg(dev,
+		s_ctrl->sensordata->sensor_platform_info->cam_vreg,
+		s_ctrl->sensordata->sensor_platform_info->num_vreg,
+		s_ctrl->vreg_seq,
+		s_ctrl->num_vreg_seq,
+		s_ctrl->reg_ptr, 1);
 	if (rc < 0) {
 		pr_err("%s: enable regulator failed\n", __func__);
 		goto enable_vreg_failed;
@@ -1408,14 +1475,23 @@
 		goto config_gpio_failed;
 	}
 
-	if (s_ctrl->clk_rate != 0)
-		cam_clk_info->clk_rate = s_ctrl->clk_rate;
+	if (s_ctrl->sensor_device_type == MSM_SENSOR_I2C_DEVICE) {
+		if (s_ctrl->clk_rate != 0)
+			cam_8960_clk_info->clk_rate = s_ctrl->clk_rate;
 
-	rc = msm_cam_clk_enable(&s_ctrl->sensor_i2c_client->client->dev,
-		cam_clk_info, &s_ctrl->cam_clk, ARRAY_SIZE(cam_clk_info), 1);
-	if (rc < 0) {
-		pr_err("%s: clk enable failed\n", __func__);
-		goto enable_clk_failed;
+		rc = msm_cam_clk_enable(dev, cam_8960_clk_info,
+			s_ctrl->cam_clk, ARRAY_SIZE(cam_8960_clk_info), 1);
+		if (rc < 0) {
+			pr_err("%s: clk enable failed\n", __func__);
+			goto enable_clk_failed;
+		}
+	} else {
+		rc = msm_cam_clk_enable(dev, cam_8974_clk_info,
+			s_ctrl->cam_clk, ARRAY_SIZE(cam_8974_clk_info), 1);
+		if (rc < 0) {
+			pr_err("%s: clk enable failed\n", __func__);
+			goto enable_clk_failed;
+		}
 	}
 
 	if (!s_ctrl->power_seq_delay)
@@ -1433,7 +1509,7 @@
 		data->sensor_platform_info->i2c_conf->use_i2c_mux)
 		msm_sensor_enable_i2c_mux(data->sensor_platform_info->i2c_conf);
 
-	if (s_ctrl->sensor_i2c_client->cci_client) {
+	if (s_ctrl->sensor_device_type == MSM_SENSOR_PLATFORM_DEVICE) {
 		rc = msm_sensor_cci_util(s_ctrl->sensor_i2c_client,
 			MSM_CCI_INIT);
 		if (rc < 0) {
@@ -1452,7 +1528,7 @@
 enable_clk_failed:
 		msm_camera_config_gpio_table(data, 0);
 config_gpio_failed:
-	msm_camera_enable_vreg(&s_ctrl->sensor_i2c_client->client->dev,
+	msm_camera_enable_vreg(dev,
 			s_ctrl->sensordata->sensor_platform_info->cam_vreg,
 			s_ctrl->sensordata->sensor_platform_info->num_vreg,
 			s_ctrl->vreg_seq,
@@ -1460,7 +1536,7 @@
 			s_ctrl->reg_ptr, 0);
 
 enable_vreg_failed:
-	msm_camera_config_vreg(&s_ctrl->sensor_i2c_client->client->dev,
+	msm_camera_config_vreg(dev,
 		s_ctrl->sensordata->sensor_platform_info->cam_vreg,
 		s_ctrl->sensordata->sensor_platform_info->num_vreg,
 		s_ctrl->vreg_seq,
@@ -1476,8 +1552,12 @@
 int32_t msm_sensor_power_down(struct msm_sensor_ctrl_t *s_ctrl)
 {
 	struct msm_camera_sensor_info *data = s_ctrl->sensordata;
-	CDBG("%s\n", __func__);
-	if (s_ctrl->sensor_i2c_client->cci_client) {
+	struct device *dev = NULL;
+	if (s_ctrl->sensor_device_type == MSM_SENSOR_PLATFORM_DEVICE)
+		dev = &s_ctrl->pdev->dev;
+	else
+		dev = &s_ctrl->sensor_i2c_client->client->dev;
+	if (s_ctrl->sensor_device_type == MSM_SENSOR_PLATFORM_DEVICE) {
 		msm_sensor_cci_util(s_ctrl->sensor_i2c_client,
 			MSM_CCI_RELEASE);
 	}
@@ -1489,16 +1569,20 @@
 
 	if (data->sensor_platform_info->ext_power_ctrl != NULL)
 		data->sensor_platform_info->ext_power_ctrl(0);
-	msm_cam_clk_enable(&s_ctrl->sensor_i2c_client->client->dev,
-		cam_clk_info, &s_ctrl->cam_clk, ARRAY_SIZE(cam_clk_info), 0);
+	if (s_ctrl->sensor_device_type == MSM_SENSOR_I2C_DEVICE)
+		msm_cam_clk_enable(dev, cam_8960_clk_info, s_ctrl->cam_clk,
+			ARRAY_SIZE(cam_8960_clk_info), 0);
+	else
+		msm_cam_clk_enable(dev, cam_8974_clk_info, s_ctrl->cam_clk,
+			ARRAY_SIZE(cam_8974_clk_info), 0);
 	msm_camera_config_gpio_table(data, 0);
-	msm_camera_enable_vreg(&s_ctrl->sensor_i2c_client->client->dev,
+	msm_camera_enable_vreg(dev,
 		s_ctrl->sensordata->sensor_platform_info->cam_vreg,
 		s_ctrl->sensordata->sensor_platform_info->num_vreg,
 		s_ctrl->vreg_seq,
 		s_ctrl->num_vreg_seq,
 		s_ctrl->reg_ptr, 0);
-	msm_camera_config_vreg(&s_ctrl->sensor_i2c_client->client->dev,
+	msm_camera_config_vreg(dev,
 		s_ctrl->sensordata->sensor_platform_info->cam_vreg,
 		s_ctrl->sensordata->sensor_platform_info->num_vreg,
 		s_ctrl->vreg_seq,
@@ -1547,6 +1631,7 @@
 	}
 
 	s_ctrl = (struct msm_sensor_ctrl_t *)(id->driver_data);
+	s_ctrl->sensor_device_type = MSM_SENSOR_I2C_DEVICE;
 	if (s_ctrl->sensor_i2c_client != NULL) {
 		s_ctrl->sensor_i2c_client->client = client;
 		if (s_ctrl->sensor_i2c_addr != 0)
@@ -1632,6 +1717,7 @@
 			return rc;
 		}
 	}
+	s_ctrl->sensor_device_type = MSM_SENSOR_PLATFORM_DEVICE;
 	s_ctrl->sensor_i2c_client->cci_client = kzalloc(sizeof(
 		struct msm_camera_cci_client), GFP_KERNEL);
 	if (!s_ctrl->sensor_i2c_client->cci_client) {
@@ -1657,7 +1743,7 @@
 	s_ctrl->sensor_i2c_client->cci_client->cci_i2c_master = MASTER_0;
 	s_ctrl->sensor_i2c_client->cci_client->sid =
 		s_ctrl->sensor_i2c_addr >> 1;
-	s_ctrl->sensor_i2c_client->cci_client->retries = 0;
+	s_ctrl->sensor_i2c_client->cci_client->retries = 3;
 	s_ctrl->sensor_i2c_client->cci_client->id_map = 0;
 
 	rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
diff --git a/drivers/media/video/msm/sensors/msm_sensor.h b/drivers/media/video/msm/sensors/msm_sensor.h
index 8e66251..7dd0602 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.h
+++ b/drivers/media/video/msm/sensors/msm_sensor.h
@@ -24,6 +24,7 @@
 #include <linux/uaccess.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/of_gpio.h>
 #include <linux/gpio.h>
 #include <mach/camera.h>
 #include <media/msm_camera.h>
diff --git a/drivers/media/video/msm/sensors/msm_sensor_bayer.c b/drivers/media/video/msm/sensors/msm_sensor_bayer.c
index 4c380c7..c867867 100644
--- a/drivers/media/video/msm/sensors/msm_sensor_bayer.c
+++ b/drivers/media/video/msm/sensors/msm_sensor_bayer.c
@@ -324,7 +324,7 @@
 			break;
 		}
 		rc = msm_cam_clk_enable(&s_ctrl->sensor_i2c_client->client->dev,
-			clk_info, &s_ctrl->cam_clk,
+			clk_info, s_ctrl->cam_clk,
 			clk_setting.num_clk_info,
 			clk_setting.enable);
 		kfree(clk_info);
@@ -470,7 +470,7 @@
 
 			rc = msm_cam_clk_enable(
 				&s_ctrl->sensor_i2c_client->client->dev,
-				cam_clk_info, &s_ctrl->cam_clk,
+				cam_clk_info, s_ctrl->cam_clk,
 				ARRAY_SIZE(cam_clk_info), 1);
 			if (rc < 0) {
 				pr_err("%s: clk enable failed\n", __func__);
@@ -523,7 +523,7 @@
 			break;
 		case CONFIG_CLK:
 			msm_cam_clk_enable(&s_ctrl->sensor_i2c_client->client->
-				dev, cam_clk_info, &s_ctrl->cam_clk,
+				dev, cam_clk_info, s_ctrl->cam_clk,
 				ARRAY_SIZE(cam_clk_info), 0);
 			break;
 		case ENABLE_GPIO:
@@ -594,7 +594,7 @@
 			break;
 		case CONFIG_CLK:
 			msm_cam_clk_enable(&s_ctrl->sensor_i2c_client->client->
-				dev, cam_clk_info, &s_ctrl->cam_clk,
+				dev, cam_clk_info, s_ctrl->cam_clk,
 				ARRAY_SIZE(cam_clk_info), 0);
 			break;
 		case ENABLE_GPIO:
diff --git a/drivers/media/video/msm/sensors/msm_sensor_common.h b/drivers/media/video/msm/sensors/msm_sensor_common.h
index 3b135e1..79fe52e 100644
--- a/drivers/media/video/msm/sensors/msm_sensor_common.h
+++ b/drivers/media/video/msm/sensors/msm_sensor_common.h
@@ -23,6 +23,7 @@
 #include <linux/types.h>
 #include <linux/uaccess.h>
 #include <linux/gpio.h>
+#include <linux/of_gpio.h>
 #include <mach/camera.h>
 #include <media/msm_camera.h>
 #include <media/v4l2-subdev.h>
@@ -101,6 +102,11 @@
 	uint8_t num_conf;
 };
 
+enum msm_sensor_device_type_t {
+	MSM_SENSOR_I2C_DEVICE,
+	MSM_SENSOR_PLATFORM_DEVICE,
+};
+
 struct v4l2_subdev_info {
 	enum v4l2_mbus_pixelcode code;
 	enum v4l2_colorspace colorspace;
@@ -177,6 +183,7 @@
 	int num_vreg_seq;
 	struct msm_camera_power_seq_t *power_seq;
 	int num_power_seq;
+	enum msm_sensor_device_type_t sensor_device_type;
 
 	struct msm_sensor_output_reg_addr_t *sensor_output_reg_addr;
 	struct msm_sensor_id_info_t *sensor_id_info;
@@ -201,7 +208,7 @@
 	struct v4l2_subdev_ops *sensor_v4l2_subdev_ops;
 	struct msm_sensor_fn_t *func_tbl;
 	struct regulator **reg_ptr;
-	struct clk *cam_clk;
+	struct clk *cam_clk[2];
 	long clk_rate;
 	enum msm_sensor_state sensor_state;
 	/* Number of frames to delay after start / stop stream in Q10 format.
diff --git a/drivers/media/video/msm_vidc/msm_smem.c b/drivers/media/video/msm_vidc/msm_smem.c
index 16fb14d..b7b12cb 100644
--- a/drivers/media/video/msm_vidc/msm_smem.c
+++ b/drivers/media/video/msm_vidc/msm_smem.c
@@ -36,7 +36,7 @@
 	pr_debug("\n In %s  domain: %d, Partition: %d\n",
 		__func__, domain_num, partition_num);
 	rc = ion_map_iommu(clnt, hndl, domain_num, partition_num, align,
-			0, iova, buffer_size, flags, 0);
+			0, iova, buffer_size, UNCACHED, 0);
 	if (rc)
 		pr_err("ion_map_iommu failed(%d).domain: %d,partition: %d\n",
 				rc, domain_num, partition_num);
@@ -217,21 +217,11 @@
 static int ion_mem_clean_invalidate(struct smem_client *clt,
 	struct msm_smem *mem)
 {
-	unsigned long ionflag;
-	int rc;
-	rc = ion_handle_get_flags(clt->clnt, mem->smem_priv, &ionflag);
-	if (rc) {
-		pr_err("Failed to get ion flags: %p, %p\n",
-			clt, mem->smem_priv);
-		goto fail_get_flags;
-	}
-	if (ionflag == CACHED) {
-		pr_err("Flushing the caches\n");
-		rc = msm_ion_do_cache_op(clt->clnt, mem->smem_priv, mem->kvaddr,
-				mem->size, ION_IOC_CLEAN_INV_CACHES);
-	}
-fail_get_flags:
-	return rc;
+	/*
+	 * Note: We're always mapping into iommu as uncached
+	 * as a result we don't need to flush/clean anything
+	 */
+	return 0;
 }
 
 int msm_smem_clean_invalidate(void *clt, struct msm_smem *mem)
diff --git a/drivers/media/video/msm_vidc/msm_vdec.c b/drivers/media/video/msm_vidc/msm_vdec.c
index 7f83625..cae486f 100644
--- a/drivers/media/video/msm_vidc/msm_vdec.c
+++ b/drivers/media/video/msm_vidc/msm_vdec.c
@@ -156,11 +156,23 @@
 static u32 get_frame_size_nv12(int plane,
 					u32 height, u32 width)
 {
-	int luma_stride = ALIGN(width, 32);
-	int luma_slice = ALIGN(height, 32);
-	int chroma_stride = ALIGN(roundup(width, 2)/2, 32);
-	int chroma_slice = ALIGN(roundup(height, 2)/2, 32);
-	return (luma_stride * luma_slice) + (chroma_stride * chroma_slice) * 2;
+	int size;
+	int luma_h, luma_w, luma_stride, luma_scanl, luma_size;
+	int chroma_h, chroma_w, chroma_stride, chroma_scanl, chroma_size;
+
+	luma_w = width;
+	luma_h = height;
+
+	chroma_w = luma_w;
+	chroma_h = luma_h/2;
+	NV12_IL_CALC_Y_STRIDE(luma_stride, luma_w, 32);
+	NV12_IL_CALC_Y_BUFHEIGHT(luma_scanl, luma_h, 32);
+	NV12_IL_CALC_UV_STRIDE(chroma_stride, chroma_w, 32);
+	NV12_IL_CALC_UV_BUFHEIGHT(chroma_scanl, luma_h, 32);
+	NV12_IL_CALC_BUF_SIZE(size, luma_size, luma_stride,
+		luma_scanl, chroma_size, chroma_stride, chroma_scanl, 32);
+	size = ALIGN(size, SZ_4K);
+	return size;
 }
 static u32 get_frame_size_nv21(int plane,
 					u32 height, u32 width)
diff --git a/drivers/media/video/msm_vidc/msm_venc.c b/drivers/media/video/msm_vidc/msm_venc.c
index 50303d6..74f1415 100644
--- a/drivers/media/video/msm_vidc/msm_venc.c
+++ b/drivers/media/video/msm_vidc/msm_venc.c
@@ -449,7 +449,23 @@
 
 static u32 get_frame_size_nv12(int plane, u32 height, u32 width)
 {
-	return ((height + 31) & (~31)) * ((width + 31) & (~31)) * 3/2;
+	int size;
+	int luma_h, luma_w, luma_stride, luma_scanl, luma_size;
+	int chroma_h, chroma_w, chroma_stride, chroma_scanl, chroma_size;
+
+	luma_w = width;
+	luma_h = height;
+
+	chroma_w = luma_w;
+	chroma_h = luma_h/2;
+	NV12_IL_CALC_Y_STRIDE(luma_stride, luma_w, 32);
+	NV12_IL_CALC_Y_BUFHEIGHT(luma_scanl, luma_h, 32);
+	NV12_IL_CALC_UV_STRIDE(chroma_stride, chroma_w, 32);
+	NV12_IL_CALC_UV_BUFHEIGHT(chroma_scanl, luma_h, 32);
+	NV12_IL_CALC_BUF_SIZE(size, luma_size, luma_stride,
+		luma_scanl, chroma_size, chroma_stride, chroma_scanl, 32);
+	size = ALIGN(size, SZ_4K);
+	return size;
 }
 
 static u32 get_frame_size_nv21(int plane, u32 height, u32 width)
diff --git a/drivers/media/video/msm_vidc/msm_vidc_internal.h b/drivers/media/video/msm_vidc/msm_vidc_internal.h
index 630f383..d01b1d1 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_internal.h
+++ b/drivers/media/video/msm_vidc/msm_vidc_internal.h
@@ -47,6 +47,32 @@
 #define SESSION_MSG_INDEX(__msg) (__msg - SESSION_MSG_START)
 
 #define MAX_NAME_LENGTH 64
+
+#define NV12_IL_CALC_Y_STRIDE(stride, frame_width, stride_multiple) \
+	{ stride = (frame_width + stride_multiple - 1) & \
+	(0xffffffff - (stride_multiple - 1)); }
+
+#define NV12_IL_CALC_Y_BUFHEIGHT(buf_height, frame_height,\
+	min_buf_height_multiple) \
+	{ buf_height = (frame_height + min_buf_height_multiple - 1) & \
+	(0xffffffff - (min_buf_height_multiple - 1)); }
+
+#define NV12_IL_CALC_UV_STRIDE(stride, frame_width, stride_multiple) \
+	{ stride = ((((frame_width + 1) >> 1) + stride_multiple - 1) & \
+	(0xffffffff - (stride_multiple - 1))) << 1; }
+
+#define NV12_IL_CALC_UV_BUFHEIGHT(buf_height, frame_height,\
+	min_buf_height_multiple) \
+	{ buf_height = ((((frame_height + 1) >> 1) + \
+	min_buf_height_multiple - 1) & (0xffffffff - \
+	(min_buf_height_multiple - 1))); }
+
+#define NV12_IL_CALC_BUF_SIZE(buf_size, y_buf_size, y_stride, \
+	y_buf_height, uv_buf_size, uv_stride, uv_buf_height, uv_alignment) \
+	{ y_buf_size = (y_stride * y_buf_height); \
+	uv_buf_size = (uv_stride * uv_buf_height) + uv_alignment; \
+	buf_size = y_buf_size + uv_buf_size; }
+
 enum vidc_ports {
 	OUTPUT_PORT,
 	CAPTURE_PORT,
diff --git a/drivers/mfd/wcd9xxx-core.c b/drivers/mfd/wcd9xxx-core.c
index 05707fd..b56f081 100644
--- a/drivers/mfd/wcd9xxx-core.c
+++ b/drivers/mfd/wcd9xxx-core.c
@@ -338,18 +338,26 @@
 			WCD9XXX_A_CHIP_VERSION) & 0x1F;
 	pr_info("%s : Codec version %u initialized\n",
 		__func__, wcd9xxx->version);
+	pr_info("idbyte_0[%08x] idbyte_1[%08x] idbyte_2[%08x] idbyte_3[%08x]\n",
+		wcd9xxx->idbyte_0, wcd9xxx->idbyte_1,
+		wcd9xxx->idbyte_2, wcd9xxx->idbyte_3);
 
-	if (wcd9xxx->idbyte_0 == 0x2) {
+	if (wcd9xxx->idbyte_0 == 0x2 && wcd9xxx->idbyte_1 == 0x0 &&
+		   wcd9xxx->idbyte_2 == 0x0 && wcd9xxx->idbyte_3 == 0x1) {
 		wcd9xxx_dev = tabla_devs;
 		wcd9xxx_dev_size = ARRAY_SIZE(tabla_devs);
-	} else if (wcd9xxx->idbyte_0 == 0x1) {
+	} else if (wcd9xxx->idbyte_0 == 0x1 && wcd9xxx->idbyte_1 == 0x0 &&
+		   wcd9xxx->idbyte_2 == 0x0 && wcd9xxx->idbyte_3 == 0x1) {
 		wcd9xxx_dev = tabla1x_devs;
 		wcd9xxx_dev_size = ARRAY_SIZE(tabla1x_devs);
 	} else if (wcd9xxx->idbyte_0 == 0x0 && wcd9xxx->idbyte_1 == 0x0 &&
 		   wcd9xxx->idbyte_2 == 0x2 && wcd9xxx->idbyte_3 == 0x1) {
 		wcd9xxx_dev = taiko_devs;
 		wcd9xxx_dev_size = ARRAY_SIZE(taiko_devs);
-	} else if (wcd9xxx->idbyte_0 == 0x0) {
+	} else if ((wcd9xxx->idbyte_0 == 0x0 && wcd9xxx->idbyte_1 == 0x0 &&
+		   wcd9xxx->idbyte_2 == 0x0 && wcd9xxx->idbyte_3 == 0x1) ||
+		   (wcd9xxx->idbyte_0 == 0x1 && wcd9xxx->idbyte_1 == 0x0 &&
+		   wcd9xxx->idbyte_2 == 0x1 && wcd9xxx->idbyte_3 == 0x1)) {
 		wcd9xxx_dev = sitar_devs;
 		wcd9xxx_dev_size = ARRAY_SIZE(sitar_devs);
 	}
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h
index 69d71d9..84f148f 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h
@@ -230,7 +230,6 @@
 			[DDL_MAX_NUM_BFRS_FOR_SLICE_BATCH];
 	u32 num_output_frames;
 	u32 out_frm_next_frmindex;
-	u32  first_output_frame_tag;
 };
 struct ddl_mp2_datadumpenabletype {
 	u32 userdatadump_enable;
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
index b047505..c3d20cf 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
@@ -1801,27 +1801,11 @@
 		vidc_sm_get_frame_tags(&ddl->shared_mem
 			[ddl->command_channel],
 			&output_frame->ip_frm_tag, &bottom_frame_tag);
-
-		if (start_bfr_idx == 0) {
-			encoder->batch_frame.first_output_frame_tag =
-				output_frame->ip_frm_tag;
-			DDL_MSG_LOW("%s: first_output_frame_tag[0x%x]",
-				__func__, output_frame->ip_frm_tag);
-			if (!output_frame->ip_frm_tag) {
-				DDL_MSG_ERROR("%s: first_output_frame_tag "\
-					"is zero", __func__);
-			}
+		if (!output_frame->ip_frm_tag) {
+			DDL_MSG_ERROR("%s: zero frame tag rcvd, index = %d",
+				__func__, index);
+			output_frame->ip_frm_tag = (u32)ddl->client_data;
 		}
-		if (output_frame->ip_frm_tag !=
-			encoder->batch_frame.first_output_frame_tag) {
-			DDL_MSG_ERROR("%s: output_frame->ip_frm_tag[0x%x] is "\
-				"not equal to the first_output_frame_tag[0x%x]\n",
-				__func__, output_frame->ip_frm_tag,
-				encoder->batch_frame.first_output_frame_tag);
-			output_frame->ip_frm_tag =
-				encoder->batch_frame.first_output_frame_tag;
-		}
-
 		ddl_get_encoded_frame(output_frame,
 				encoder->codec.codec,
 				encoder->enc_frame_info.enc_frame);
@@ -1904,27 +1888,11 @@
 		vidc_sm_get_frame_tags(&ddl->shared_mem
 			[ddl->command_channel],
 			&output_frame->ip_frm_tag, &bottom_frame_tag);
-
-		if (start_bfr_idx == 0) {
-			encoder->batch_frame.first_output_frame_tag =
-				output_frame->ip_frm_tag;
-			DDL_MSG_LOW("%s: first_output_frame_tag[0x%x]",
-				__func__, output_frame->ip_frm_tag);
-			if (!output_frame->ip_frm_tag) {
-				DDL_MSG_ERROR("%s: first_output_frame_tag "\
-					"is zero", __func__);
-			}
+		if (!output_frame->ip_frm_tag) {
+			DDL_MSG_ERROR("%s: zero frame tag rcvd, index = %d",
+				__func__, index);
+			output_frame->ip_frm_tag = (u32)ddl->client_data;
 		}
-		if (output_frame->ip_frm_tag !=
-			encoder->batch_frame.first_output_frame_tag) {
-			DDL_MSG_ERROR("%s: output_frame->ip_frm_tag[0x%x] is "\
-				"not equal to the first_output_frame_tag[0x%x]\n",
-				__func__, output_frame->ip_frm_tag,
-				encoder->batch_frame.first_output_frame_tag);
-			output_frame->ip_frm_tag =
-				encoder->batch_frame.first_output_frame_tag;
-		}
-
 		ddl_get_encoded_frame(output_frame,
 				encoder->codec.codec,
 				encoder->enc_frame_info.enc_frame);
@@ -1995,8 +1963,9 @@
 				&output_frame->ip_frm_tag,
 				&bottom_frame_tag);
 		if (!output_frame->ip_frm_tag) {
-			DDL_MSG_ERROR("%s: output frame tag is zero",
-				__func__);
+			DDL_MSG_ERROR("%s: zero frame tag rcvd, index = %d",
+				__func__, index);
+			output_frame->ip_frm_tag = (u32)ddl->client_data;
 		}
 		ddl_get_encoded_frame(
 				output_frame,
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
index d1f6e07..4072b02 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
@@ -867,7 +867,6 @@
 	DDL_MEMSET(encoder->batch_frame.slice_batch_in.align_virtual_addr, 0,
 		sizeof(struct vidc_1080p_enc_slice_batch_in_param));
 	encoder->batch_frame.out_frm_next_frmindex = 0;
-	encoder->batch_frame.first_output_frame_tag = 0;
 	bitstream_size = encoder->batch_frame.output_frame[0].vcd_frm.alloc_len;
 	encoder->output_buf_req.sz = bitstream_size;
 	y_addr = DDL_OFFSET(ddl_context->dram_base_b.align_physical_addr,
diff --git a/include/linux/msm_audio.h b/include/linux/msm_audio.h
index f2a39e4..4eb8a65 100644
--- a/include/linux/msm_audio.h
+++ b/include/linux/msm_audio.h
@@ -222,6 +222,28 @@
 
 #define SND_SET_DEVICE _IOW(SND_IOCTL_MAGIC, 2, struct msm_device_config *)
 
+enum cad_device_path_type {
+	CAD_DEVICE_PATH_RX,	/*For Decoding session*/
+	CAD_DEVICE_PATH_TX,	/* For Encoding session*/
+	CAD_DEVICE_PATH_RX_TX, /* For Voice call */
+	CAD_DEVICE_PATH_LB,	/* For loopback (FM Analog)*/
+	CAD_DEVICE_PATH_MAX
+};
+
+struct cad_devices_type {
+	uint32_t rx_device;
+	uint32_t tx_device;
+	enum cad_device_path_type pathtype;
+};
+
+struct msm_cad_device_config {
+	struct cad_devices_type device;
+	uint32_t ear_mute;
+	uint32_t mic_mute;
+};
+
+#define CAD_SET_DEVICE _IOW(SND_IOCTL_MAGIC, 2, struct msm_cad_device_config *)
+
 #define SND_METHOD_VOICE 0
 
 struct msm_snd_volume_config {
@@ -232,6 +254,14 @@
 
 #define SND_SET_VOLUME _IOW(SND_IOCTL_MAGIC, 3, struct msm_snd_volume_config *)
 
+struct msm_cad_volume_config {
+	struct cad_devices_type device;
+	uint32_t method;
+	uint32_t volume;
+};
+
+#define CAD_SET_VOLUME _IOW(SND_IOCTL_MAGIC, 3, struct msm_cad_volume_config *)
+
 /* Returns the number of SND endpoints supported. */
 
 #define SND_GET_NUM_ENDPOINTS _IOR(SND_IOCTL_MAGIC, 4, unsigned *)
@@ -254,6 +284,24 @@
 #define SND_AVC_CTL _IOW(SND_IOCTL_MAGIC, 6, unsigned *)
 #define SND_AGC_CTL _IOW(SND_IOCTL_MAGIC, 7, unsigned *)
 
+/*return the number of CAD endpoints supported. */
+
+#define CAD_GET_NUM_ENDPOINTS _IOR(SND_IOCTL_MAGIC, 4, unsigned *)
+
+struct msm_cad_endpoint {
+	int id; /* input and output */
+	char name[64]; /* output only */
+};
+
+/* Takes an index between 0 and one less than the number returned by
+ * SND_GET_NUM_ENDPOINTS, and returns the CAD index and name of a
+ * CAD endpoint.  On input, the .id field contains the number of the
+ * endpoint, and on exit it contains the SND index, while .name contains
+ * the description of the endpoint.
+ */
+
+#define CAD_GET_ENDPOINT _IOWR(SND_IOCTL_MAGIC, 5, struct msm_cad_endpoint *)
+
 struct msm_audio_pcm_config {
 	uint32_t pcm_feedback;	/* 0 - disable > 0 - enable */
 	uint32_t buffer_count;	/* Number of buffers to allocate */
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index 80334c4..bd97b86 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -1339,7 +1339,7 @@
 };
 
 struct csi_lane_params_t {
-	uint8_t csi_lane_assign;
+	uint16_t csi_lane_assign;
 	uint8_t csi_lane_mask;
 	uint8_t csi_if;
 	uint8_t csid_core[2];
diff --git a/sound/soc/codecs/wcd9304.c b/sound/soc/codecs/wcd9304.c
index 32565bc..67572c3 100644
--- a/sound/soc/codecs/wcd9304.c
+++ b/sound/soc/codecs/wcd9304.c
@@ -2414,7 +2414,7 @@
 		snd_soc_write(codec, SITAR_A_BIAS_CENTRAL_BG_CTL, 0x50);
 		if (SITAR_IS_1P0(sitar_core->version))
 			snd_soc_update_bits(codec, SITAR_A_LDO_H_MODE_1,
-								0xFF, 0x65);
+								0xF3, 0x61);
 		usleep_range(1000, 1000);
 	} else {
 		pr_err("%s: Error, Invalid bandgap settings\n", __func__);
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>