summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaxminath Kasam <lkasam@codeaurora.org>2014-01-27 21:12:01 +0530
committerMichael Bohan <mbohan@codeaurora.org>2014-02-05 09:34:16 -0800
commit12e440969b99c7923ffe338b4f8f470bb50ee13b (patch)
treedbca17e3ca1eb1d9e0040eca12c5d1d83547ece9
parent8fbc5da8a7d6276e0f2445e1c74e98da4808cab1 (diff)
ASoC: msm8x16-wcd: 8x16 codec driver
In 8x16 target, codec interfaces are through SPMI, I2S and AHB. Add support to configure codec for audio device usecases using these interfaces. Change-Id: I4df6535080d0077637a2e748c11f8f8a724bb110 Signed-off-by: Laxminath Kasam <lkasam@codeaurora.org>
-rw-r--r--Documentation/devicetree/bindings/sound/taiko_codec.txt96
-rw-r--r--drivers/soc/qcom/qdsp6v2/apr_v3.c8
-rw-r--r--sound/soc/codecs/Kconfig3
-rw-r--r--sound/soc/codecs/Makefile2
-rw-r--r--sound/soc/codecs/msm8x16-wcd-tables.c732
-rw-r--r--sound/soc/codecs/msm8x16-wcd.c3075
-rw-r--r--sound/soc/codecs/msm8x16-wcd.h157
-rw-r--r--sound/soc/codecs/msm8x16_wcd_registers.h517
8 files changed, 4586 insertions, 4 deletions
diff --git a/Documentation/devicetree/bindings/sound/taiko_codec.txt b/Documentation/devicetree/bindings/sound/taiko_codec.txt
index c5ac3cec7445..6a5cd22c5c93 100644
--- a/Documentation/devicetree/bindings/sound/taiko_codec.txt
+++ b/Documentation/devicetree/bindings/sound/taiko_codec.txt
@@ -313,3 +313,99 @@ i2c@f9925000 {
reg = <0x55>;
};
};
+
+Tombak audio CODEC in SPMI mode
+
+ - compatible = "qcom,wcd-spmi";
+ - reg: represents the slave base address provided to the peripheral.
+ - interrupt-parent : The parent interrupt controller.
+ - interrupts: List of interrupts in given SPMI peripheral.
+ - interrupt-names: Names specificed to above list of interrupts in same
+ order.
+
+ - cdc-vdda-cp-supply: phandle of cp supply's regulator device tree node.
+ - qcom,cdc-vdda-cp-voltage: cp supply's voltage level min and max in mV.
+ - qcom,cdc-vdda-cp-current: cp supply's max current in mA.
+
+ - cdc-vdda-h-supply: phandle of vdda-h supply's regulator device tree node.
+ - qcom,cdc-vdda-h-voltage: vdda-h supply's voltage level min and max in mV.
+ - qcom,cdc-vdda-h-current: vdda-h supply's max current in mA.
+
+ - cdc-vdd-px-supply: phandle of vdd-px supply's regulator device tree node.
+ - qcom,cdc-vdd-px-voltage: vdd-px supply's voltage level min and max in mV.
+ - qcom,cdc-vdd-px-current: vdd-px supply's max current in mA.
+
+ - cdc-vdd-pa-supply: phandle of vdd-pa supply's regulator device tree node.
+ - qcom,cdc-vdd-pa-voltage: vdd-pa supply's voltage level min and max in mV.
+ - qcom,cdc-vdd-pa-current: vdd-pa supply's max current in mA.
+
+ - cdc-vdd-mic-bias-supply: phandle of mic-bias supply's regulator device tree
+ node.
+ - qcom,cdc-vdd-mic-bias-voltage: mic-bias supply's voltage level min and max
+ in mV.
+ - qcom,cdc-vdd-mic-bias-current: mic-bias supply's max current in mA.
+
+ - qcom,cdc-mclk-clk-rate: Specifies the master clock rate in Hz required for
+ codec.
+
+ - qcom,cdc-static-supplies: List of supplies to be enabled prior to codec
+ hardware probe. Supplies in this list will be
+ stay enabled.
+
+Optional properties:
+
+ - qcom,cdc-on-demand-supplies: List of supplies which can be enabled
+ dynamically.
+ Supplies in this list are off by default.
+
+Example:
+msm8x16_wcd_codec@f000{
+ compatible = "qcom,wcd-spmi";
+ reg = <0xf000 0x100>;
+ interrupt-parent = <&spmi_bus>;
+ interrupts = <0x1 0xf0 0x0>,
+ <0x1 0xf0 0x1>,
+ <0x1 0xf0 0x2>,
+ <0x1 0xf0 0x3>,
+ <0x1 0xf0 0x4>,
+ <0x1 0xf0 0x5>,
+ <0x1 0xf0 0x6>,
+ <0x1 0xf0 0x7>;
+ interrupt-names = "spk_cnp_int",
+ "spk_clip_int",
+ "spk_ocp_int",
+ "ins_rem_det1",
+ "but_rel_det",
+ "but_press_det",
+ "ins_rem_det",
+ "mbhc_int";
+
+ cdc-vdda-cp-supply = <&pm8916_s4>;
+ qcom,cdc-vdda-cp-voltage = <1800000 2200000>;
+ qcom,cdc-vdda-cp-current = <770000>;
+
+ cdc-vdda-h-supply = <&pm8916_l5>;
+ qcom,cdc-vdda-h-voltage = <1800000 1800000>;
+ qcom,cdc-vdda-h-current = <20000>;
+
+ cdc-vdd-px-supply = <&pm8916_s4>;
+ qcom,cdc-vdd-px-voltage = <1800000 2200000>;
+ qcom,cdc-vdd-px-current = <770000>;
+
+ cdc-vdd-pa-supply = <&pm8916_l5>;
+ qcom,cdc-vdd-pa-voltage = <1800000 1800000>;
+ qcom,cdc-vdd-pa-current = <5000>;
+
+ cdc-vdd-mic-bias-supply = <&pm8916_l13>;
+ qcom,cdc-vdd-mic-bias-voltage = <3075000 3075000>;
+ qcom,cdc-vdd-mic-bias-current = <25000>;
+
+ qcom,cdc-mclk-clk-rate = <9600000>;
+
+ qcom,cdc-static-supplies = "cdc-vdda-h",
+ "cdc-vdd-px",
+ "cdc-vdd-pa",
+ "cdc-vdda-cp";
+
+ qcom,cdc-on-demand-supplies = "cdc-vdd-mic-bias";
+};
diff --git a/drivers/soc/qcom/qdsp6v2/apr_v3.c b/drivers/soc/qcom/qdsp6v2/apr_v3.c
index bbef6a5af809..84eba7765439 100644
--- a/drivers/soc/qcom/qdsp6v2/apr_v3.c
+++ b/drivers/soc/qcom/qdsp6v2/apr_v3.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, The Linux Foundation. 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
@@ -15,9 +15,9 @@
#include <linux/uaccess.h>
#include <linux/spinlock.h>
#include <linux/kernel.h>
-#include <mach/qdsp6v2/apr.h>
-#include <mach/qdsp6v2/apr_tal.h>
-#include <mach/qdsp6v2/dsp_debug.h>
+#include <linux/qdsp6v2/apr.h>
+#include <linux/qdsp6v2/apr_tal.h>
+#include <linux/qdsp6v2/dsp_debug.h>
#define DEST_ID APR_DEST_MODEM
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index a9c362545323..6ff812efac6e 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -371,6 +371,9 @@ config SND_SOC_WCD9XXX
config SND_SOC_MSM8X10_WCD
tristate
+config SND_SOC_MSM8X16_WCD
+ tristate
+
config SND_SOC_WL1273
tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index e7ef6cff2e6e..25a94db08536 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -71,6 +71,7 @@ snd-soc-wcd9320-objs := wcd9320.o wcd9320-tables.o
snd-soc-wcd9306-objs := wcd9306.o wcd9306-tables.o
snd-soc-wcd9xxx-objs := wcd9xxx-resmgr.o wcd9xxx-mbhc.o wcd9xxx-common.o
snd-soc-msm8x10-wcd-objs := msm8x10-wcd.o msm8x10-wcd-tables.o wcd9xxx-common.o
+snd-soc-msm8x16-wcd-objs := msm8x16-wcd.o msm8x16-wcd-tables.o
snd-soc-wl1273-objs := wl1273.o
snd-soc-wm-adsp-objs := wm_adsp.o
snd-soc-wm0010-objs := wm0010.o
@@ -203,6 +204,7 @@ obj-$(CONFIG_SND_SOC_WCD9320) += snd-soc-wcd9320.o
obj-$(CONFIG_SND_SOC_WCD9306) += snd-soc-wcd9306.o
obj-$(CONFIG_SND_SOC_MSM8X10_WCD) += snd-soc-msm8x10-wcd.o wcd9xxx-resmgr.o wcd9xxx-mbhc.o
obj-$(CONFIG_SND_SOC_WCD9XXX) += snd-soc-wcd9xxx.o
+obj-$(CONFIG_SND_SOC_MSM8X16_WCD) += snd-soc-msm8x16-wcd.o msm8916-wcd-irq.o
obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o
obj-$(CONFIG_SND_SOC_WM0010) += snd-soc-wm0010.o
obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o
diff --git a/sound/soc/codecs/msm8x16-wcd-tables.c b/sound/soc/codecs/msm8x16-wcd-tables.c
new file mode 100644
index 000000000000..edc631ea83ea
--- /dev/null
+++ b/sound/soc/codecs/msm8x16-wcd-tables.c
@@ -0,0 +1,732 @@
+/* Copyright (c) 2014, The Linux Foundation. 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 <msm8x16_wcd_registers.h>
+#include "msm8x16-wcd.h"
+
+const u8 msm8x16_wcd_reg_readable[MSM8X16_WCD_CACHE_SIZE] = {
+ [MSM8X16_WCD_A_DIGITAL_REVISION1] = 1,
+ [MSM8X16_WCD_A_DIGITAL_REVISION2] = 1,
+ [MSM8X16_WCD_A_DIGITAL_PERPH_TYPE] = 1,
+ [MSM8X16_WCD_A_DIGITAL_PERPH_SUBTYPE] = 1,
+ [MSM8X16_WCD_A_DIGITAL_INT_RT_STS] = 1,
+ [MSM8X16_WCD_A_DIGITAL_INT_SET_TYPE] = 1,
+ [MSM8X16_WCD_A_DIGITAL_INT_POLARITY_HIGH] = 1,
+ [MSM8X16_WCD_A_DIGITAL_INT_POLARITY_LOW] = 1,
+ [MSM8X16_WCD_A_DIGITAL_INT_EN_SET] = 1,
+ [MSM8X16_WCD_A_DIGITAL_INT_EN_CLR] = 1,
+ [MSM8X16_WCD_A_DIGITAL_INT_LATCHED_STS] = 1,
+ [MSM8X16_WCD_A_DIGITAL_INT_PENDING_STS] = 1,
+ [MSM8X16_WCD_A_DIGITAL_INT_MID_SEL] = 1,
+ [MSM8X16_WCD_A_DIGITAL_INT_PRIORITY] = 1,
+ [MSM8X16_WCD_A_DIGITAL_GPIO_MODE] = 1,
+ [MSM8X16_WCD_A_DIGITAL_PIN_CTL_OE] = 1,
+ [MSM8X16_WCD_A_DIGITAL_PIN_CTL_DATA] = 1,
+ [MSM8X16_WCD_A_DIGITAL_PIN_STATUS] = 1,
+ [MSM8X16_WCD_A_DIGITAL_HDRIVE_CTL] = 1,
+ [MSM8X16_WCD_A_DIGITAL_CDC_RST_CTL] = 1,
+ [MSM8X16_WCD_A_DIGITAL_CDC_TOP_CLK_CTL] = 1,
+ [MSM8X16_WCD_A_DIGITAL_CDC_ANA_CLK_CTL] = 1,
+ [MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL] = 1,
+ [MSM8X16_WCD_A_DIGITAL_CDC_CONN_TX1_CTL] = 1,
+ [MSM8X16_WCD_A_DIGITAL_CDC_CONN_TX2_CTL] = 1,
+ [MSM8X16_WCD_A_DIGITAL_CDC_CONN_HPHR_DAC_CTL] = 1,
+ [MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX1_CTL] = 1,
+ [MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX2_CTL] = 1,
+ [MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX3_CTL] = 1,
+ [MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX_LB_CTL] = 1,
+ [MSM8X16_WCD_A_DIGITAL_CDC_RX_CTL1] = 1,
+ [MSM8X16_WCD_A_DIGITAL_CDC_RX_CTL2] = 1,
+ [MSM8X16_WCD_A_DIGITAL_CDC_RX_CTL3] = 1,
+ [MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA0] = 1,
+ [MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA1] = 1,
+ [MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA2] = 1,
+ [MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA3] = 1,
+ [MSM8X16_WCD_A_DIGITAL_DIG_DEBUG_CTL] = 1,
+ [MSM8X16_WCD_A_DIGITAL_SPARE_0] = 1,
+ [MSM8X16_WCD_A_DIGITAL_SPARE_1] = 1,
+ [MSM8X16_WCD_A_DIGITAL_SPARE_2] = 1,
+ [MSM8X16_WCD_A_ANALOG_REVISION1] = 1,
+ [MSM8X16_WCD_A_ANALOG_REVISION2] = 1,
+ [MSM8X16_WCD_A_ANALOG_REVISION3] = 1,
+ [MSM8X16_WCD_A_ANALOG_REVISION4] = 1,
+ [MSM8X16_WCD_A_ANALOG_PERPH_TYPE] = 1,
+ [MSM8X16_WCD_A_ANALOG_PERPH_SUBTYPE] = 1,
+ [MSM8X16_WCD_A_ANALOG_INT_RT_STS] = 1,
+ [MSM8X16_WCD_A_ANALOG_INT_SET_TYPE] = 1,
+ [MSM8X16_WCD_A_ANALOG_INT_POLARITY_HIGH] = 1,
+ [MSM8X16_WCD_A_ANALOG_INT_POLARITY_LOW] = 1,
+ [MSM8X16_WCD_A_ANALOG_INT_EN_SET] = 1,
+ [MSM8X16_WCD_A_ANALOG_INT_EN_CLR] = 1,
+ [MSM8X16_WCD_A_ANALOG_INT_LATCHED_STS] = 1,
+ [MSM8X16_WCD_A_ANALOG_INT_PENDING_STS] = 1,
+ [MSM8X16_WCD_A_ANALOG_INT_MID_SEL] = 1,
+ [MSM8X16_WCD_A_ANALOG_INT_PRIORITY] = 1,
+ [MSM8X16_WCD_A_ANALOG_MICB_1_EN] = 1,
+ [MSM8X16_WCD_A_ANALOG_MICB_1_VAL] = 1,
+ [MSM8X16_WCD_A_ANALOG_MICB_1_CTL] = 1,
+ [MSM8X16_WCD_A_ANALOG_MICB_1_INT_RBIAS] = 1,
+ [MSM8X16_WCD_A_ANALOG_MICB_2_EN] = 1,
+ [MSM8X16_WCD_A_ANALOG_MBHC_DET_CTL_1] = 1,
+ [MSM8X16_WCD_A_ANALOG_MBHC_DET_CTL_2] = 1,
+ [MSM8X16_WCD_A_ANALOG_MBHC_FSM_CTL] = 1,
+ [MSM8X16_WCD_A_ANALOG_MBHC_DBNC_TIMER] = 1,
+ [MSM8X16_WCD_A_ANALOG_MBHC_BTN0_ZDETL_CTL] = 1,
+ [MSM8X16_WCD_A_ANALOG_MBHC_BTN1_ZDETM_CTL] = 1,
+ [MSM8X16_WCD_A_ANALOG_MBHC_BTN2_ZDETH_CTL] = 1,
+ [MSM8X16_WCD_A_ANALOG_MBHC_BTN3_CTL] = 1,
+ [MSM8X16_WCD_A_ANALOG_MBHC_BTN4_CTL] = 1,
+ [MSM8X16_WCD_A_ANALOG_MBHC_BTN_RESULT] = 1,
+ [MSM8X16_WCD_A_ANALOG_MBHC_ZDET_ELECT_RESULT] = 1,
+ [MSM8X16_WCD_A_ANALOG_TX_1_EN] = 1,
+ [MSM8X16_WCD_A_ANALOG_TX_2_EN] = 1,
+ [MSM8X16_WCD_A_ANALOG_TX_1_2_TEST_CTL_1] = 1,
+ [MSM8X16_WCD_A_ANALOG_TX_1_2_TEST_CTL_2] = 1,
+ [MSM8X16_WCD_A_ANALOG_TX_1_2_ATEST_CTL] = 1,
+ [MSM8X16_WCD_A_ANALOG_TX_1_2_OPAMP_BIAS] = 1,
+ [MSM8X16_WCD_A_ANALOG_TX_1_2_TXFE_CLKDIV] = 1,
+ [MSM8X16_WCD_A_ANALOG_TX_3_EN] = 1,
+ [MSM8X16_WCD_A_ANALOG_NCP_EN] = 1,
+ [MSM8X16_WCD_A_ANALOG_NCP_CLK] = 1,
+ [MSM8X16_WCD_A_ANALOG_NCP_DEGLITCH] = 1,
+ [MSM8X16_WCD_A_ANALOG_NCP_FBCTRL] = 1,
+ [MSM8X16_WCD_A_ANALOG_NCP_BIAS] = 1,
+ [MSM8X16_WCD_A_ANALOG_NCP_VCTRL] = 1,
+ [MSM8X16_WCD_A_ANALOG_NCP_TEST] = 1,
+ [MSM8X16_WCD_A_ANALOG_RX_CLOCK_DIVIDER] = 1,
+ [MSM8X16_WCD_A_ANALOG_RX_COM_OCP_CTL] = 1,
+ [MSM8X16_WCD_A_ANALOG_RX_COM_OCP_COUNT] = 1,
+ [MSM8X16_WCD_A_ANALOG_RX_COM_BIAS_DAC] = 1,
+ [MSM8X16_WCD_A_ANALOG_RX_HPH_BIAS_PA] = 1,
+ [MSM8X16_WCD_A_ANALOG_RX_HPH_BIAS_LDO_OCP] = 1,
+ [MSM8X16_WCD_A_ANALOG_RX_HPH_BIAS_CNP] = 1,
+ [MSM8X16_WCD_A_ANALOG_RX_HPH_CNP_EN] = 1,
+ [MSM8X16_WCD_A_ANALOG_RX_HPH_CNP_WG_CTL] = 1,
+ [MSM8X16_WCD_A_ANALOG_RX_HPH_CNP_WG_TIME] = 1,
+ [MSM8X16_WCD_A_ANALOG_RX_HPH_L_TEST] = 1,
+ [MSM8X16_WCD_A_ANALOG_RX_HPH_L_PA_DAC_CTL] = 1,
+ [MSM8X16_WCD_A_ANALOG_RX_HPH_R_TEST] = 1,
+ [MSM8X16_WCD_A_ANALOG_RX_HPH_R_PA_DAC_CTL] = 1,
+ [MSM8X16_WCD_A_ANALOG_RX_EAR_CTL] = 1,
+ [MSM8X16_WCD_A_ANALOG_RX_ATEST] = 1,
+ [MSM8X16_WCD_A_ANALOG_RX_HPH_STATUS] = 1,
+ [MSM8X16_WCD_A_ANALOG_RX_EAR_STATUS] = 1,
+ [MSM8X16_WCD_A_ANALOG_SPKR_DAC_CTL] = 1,
+ [MSM8X16_WCD_A_ANALOG_SPKR_DRV_CLIP_DET] = 1,
+ [MSM8X16_WCD_A_ANALOG_SPKR_DRV_CTL] = 1,
+ [MSM8X16_WCD_A_ANALOG_SPKR_ANA_BIAS_SET] = 1,
+ [MSM8X16_WCD_A_ANALOG_SPKR_OCP_CTL] = 1,
+ [MSM8X16_WCD_A_ANALOG_SPKR_PWRSTG_CTL] = 1,
+ [MSM8X16_WCD_A_ANALOG_SPKR_DRV_MISC] = 1,
+ [MSM8X16_WCD_A_ANALOG_SPKR_DRV_DBG] = 1,
+ [MSM8X16_WCD_A_ANALOG_CURRENT_LIMIT] = 1,
+ [MSM8X16_WCD_A_ANALOG_OUTPUT_VOLTAGE] = 1,
+ [MSM8X16_WCD_A_ANALOG_BYPASS_MODE] = 1,
+ [MSM8X16_WCD_A_ANALOG_BOOST_EN_CTL] = 1,
+ [MSM8X16_WCD_A_ANALOG_SLOPE_COMP_IP_ZERO] = 1,
+ [MSM8X16_WCD_A_ANALOG_RDSON_MAX_DUTY_CYCLE] = 1,
+ [MSM8X16_WCD_A_ANALOG_BOOST_TEST1_1] = 1,
+ [MSM8X16_WCD_A_ANALOG_BOOST_TEST_2] = 1,
+ [MSM8X16_WCD_A_ANALOG_SPKR_SAR_STATUS] = 1,
+ [MSM8X16_WCD_A_ANALOG_SPKR_DRV_STATUS] = 1,
+ [MSM8X16_WCD_A_ANALOG_PBUS_ADD_CSR] = 1,
+ [MSM8X16_WCD_A_ANALOG_PBUS_ADD_SEL] = 1,
+ [MSM8X16_WCD_A_CDC_CLK_RX_RESET_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_CLK_TX_RESET_B1_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_CLK_DMIC_B1_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_CLK_RX_I2S_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_CLK_TX_I2S_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_CLK_OTHR_RESET_B1_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_CLK_TX_CLK_EN_B1_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_CLK_OTHR_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_CLK_RX_B1_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_CLK_MCLK_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_CLK_PDM_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_CLK_SD_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_RX1_B1_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_RX2_B1_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_RX3_B1_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_RX1_B2_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_RX2_B2_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_RX3_B2_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_RX1_B3_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_RX2_B3_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_RX3_B3_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_RX1_B4_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_RX2_B4_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_RX3_B4_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_RX1_B5_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_RX2_B5_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_RX3_B5_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_RX1_B6_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_RX2_B6_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_RX3_B6_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_RX1_VOL_CTL_B1_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_RX2_VOL_CTL_B1_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_RX3_VOL_CTL_B1_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_RX1_VOL_CTL_B2_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_RX2_VOL_CTL_B2_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_RX3_VOL_CTL_B2_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_TOP_GAIN_UPDATE] = 1,
+ [MSM8X16_WCD_A_CDC_TOP_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_DEBUG_DESER1_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_DEBUG_DESER2_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_DEBUG_B1_CTL_CFG] = 1,
+ [MSM8X16_WCD_A_CDC_DEBUG_B2_CTL_CFG] = 1,
+ [MSM8X16_WCD_A_CDC_DEBUG_B3_CTL_CFG] = 1,
+ [MSM8X16_WCD_A_CDC_IIR1_GAIN_B1_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_IIR2_GAIN_B1_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_IIR1_GAIN_B2_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_IIR2_GAIN_B2_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_IIR1_GAIN_B3_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_IIR2_GAIN_B3_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_IIR1_GAIN_B4_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_IIR2_GAIN_B4_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_IIR1_GAIN_B5_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_IIR2_GAIN_B5_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_IIR1_GAIN_B6_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_IIR2_GAIN_B6_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_IIR1_GAIN_B7_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_IIR2_GAIN_B7_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_IIR1_GAIN_B8_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_IIR2_GAIN_B8_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_IIR1_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_IIR2_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_IIR1_GAIN_TIMER_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_IIR2_GAIN_TIMER_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_IIR1_COEF_B1_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_IIR2_COEF_B1_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_IIR1_COEF_B2_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_IIR2_COEF_B2_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_CONN_RX1_B1_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_CONN_RX1_B2_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_CONN_RX1_B3_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_CONN_RX2_B1_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_CONN_RX2_B2_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_CONN_RX2_B3_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_CONN_RX3_B1_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_CONN_RX3_B2_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_CONN_TX_B1_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_CONN_EQ1_B1_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_CONN_EQ1_B2_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_CONN_EQ1_B3_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_CONN_EQ1_B4_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_CONN_EQ2_B1_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_CONN_EQ2_B2_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_CONN_EQ2_B3_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_CONN_EQ2_B4_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_CONN_TX_I2S_SD1_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_TX1_VOL_CTL_TIMER] = 1,
+ [MSM8X16_WCD_A_CDC_TX2_VOL_CTL_TIMER] = 1,
+ [MSM8X16_WCD_A_CDC_TX1_VOL_CTL_GAIN] = 1,
+ [MSM8X16_WCD_A_CDC_TX2_VOL_CTL_GAIN] = 1,
+ [MSM8X16_WCD_A_CDC_TX1_VOL_CTL_CFG] = 1,
+ [MSM8X16_WCD_A_CDC_TX2_VOL_CTL_CFG] = 1,
+ [MSM8X16_WCD_A_CDC_TX1_MUX_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_TX2_MUX_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_TX1_CLK_FS_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_TX2_CLK_FS_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_TX1_DMIC_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_TX2_DMIC_CTL] = 1,
+};
+
+const u8 msm8x16_wcd_reg_readonly[MSM8X16_WCD_CACHE_SIZE] = {
+ [MSM8X16_WCD_A_DIGITAL_REVISION1] = 1,
+ [MSM8X16_WCD_A_DIGITAL_REVISION2] = 1,
+ [MSM8X16_WCD_A_DIGITAL_PERPH_TYPE] = 1,
+ [MSM8X16_WCD_A_DIGITAL_PERPH_SUBTYPE] = 1,
+ [MSM8X16_WCD_A_DIGITAL_INT_RT_STS] = 1,
+ [MSM8X16_WCD_A_DIGITAL_INT_SET_TYPE] = 1,
+ [MSM8X16_WCD_A_DIGITAL_INT_POLARITY_HIGH] = 1,
+ [MSM8X16_WCD_A_DIGITAL_INT_POLARITY_LOW] = 1,
+ [MSM8X16_WCD_A_DIGITAL_INT_LATCHED_STS] = 1,
+ [MSM8X16_WCD_A_DIGITAL_INT_PENDING_STS] = 1,
+ [MSM8X16_WCD_A_DIGITAL_PIN_STATUS] = 1,
+ [MSM8X16_WCD_A_ANALOG_REVISION1] = 1,
+ [MSM8X16_WCD_A_ANALOG_REVISION2] = 1,
+ [MSM8X16_WCD_A_ANALOG_REVISION3] = 1,
+ [MSM8X16_WCD_A_ANALOG_REVISION4] = 1,
+ [MSM8X16_WCD_A_ANALOG_PERPH_TYPE] = 1,
+ [MSM8X16_WCD_A_ANALOG_PERPH_SUBTYPE] = 1,
+ [MSM8X16_WCD_A_ANALOG_INT_RT_STS] = 1,
+ [MSM8X16_WCD_A_ANALOG_INT_SET_TYPE] = 1,
+ [MSM8X16_WCD_A_ANALOG_INT_POLARITY_HIGH] = 1,
+ [MSM8X16_WCD_A_ANALOG_INT_POLARITY_LOW] = 1,
+ [MSM8X16_WCD_A_ANALOG_INT_LATCHED_STS] = 1,
+ [MSM8X16_WCD_A_ANALOG_INT_PENDING_STS] = 1,
+ [MSM8X16_WCD_A_ANALOG_MBHC_BTN_RESULT] = 1,
+ [MSM8X16_WCD_A_ANALOG_MBHC_ZDET_ELECT_RESULT] = 1,
+ [MSM8X16_WCD_A_ANALOG_RX_HPH_STATUS] = 1,
+ [MSM8X16_WCD_A_ANALOG_RX_EAR_STATUS] = 1,
+ [MSM8X16_WCD_A_ANALOG_SPKR_SAR_STATUS] = 1,
+ [MSM8X16_WCD_A_ANALOG_SPKR_DRV_STATUS] = 1,
+ [MSM8X16_WCD_A_CDC_RX1_B1_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_RX2_B1_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_RX3_B1_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_RX1_B6_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_RX2_B6_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_RX3_B6_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_TX1_VOL_CTL_CFG] = 1,
+ [MSM8X16_WCD_A_CDC_TX2_VOL_CTL_CFG] = 1,
+ [MSM8X16_WCD_A_CDC_IIR1_COEF_B1_CTL] = 1,
+ [MSM8X16_WCD_A_CDC_IIR2_COEF_B1_CTL] = 1,
+};
+const u8 msm8x16_wcd_reset_reg_defaults[MSM8X16_WCD_CACHE_SIZE] = {
+ [MSM8X16_WCD_A_DIGITAL_REVISION1] =
+ MSM8X16_WCD_A_DIGITAL_REVISION1__POR,
+ [MSM8X16_WCD_A_DIGITAL_REVISION2] =
+ MSM8X16_WCD_A_DIGITAL_REVISION2__POR,
+ [MSM8X16_WCD_A_DIGITAL_PERPH_TYPE] =
+ MSM8X16_WCD_A_DIGITAL_PERPH_TYPE__POR,
+ [MSM8X16_WCD_A_DIGITAL_PERPH_SUBTYPE] =
+ MSM8X16_WCD_A_DIGITAL_PERPH_SUBTYPE__POR,
+ [MSM8X16_WCD_A_DIGITAL_INT_RT_STS] =
+ MSM8X16_WCD_A_DIGITAL_INT_RT_STS__POR,
+ [MSM8X16_WCD_A_DIGITAL_INT_SET_TYPE] =
+ MSM8X16_WCD_A_DIGITAL_INT_SET_TYPE__POR,
+ [MSM8X16_WCD_A_DIGITAL_INT_POLARITY_HIGH] =
+ MSM8X16_WCD_A_DIGITAL_INT_POLARITY_HIGH__POR,
+ [MSM8X16_WCD_A_DIGITAL_INT_POLARITY_LOW] =
+ MSM8X16_WCD_A_DIGITAL_INT_POLARITY_LOW__POR,
+ [MSM8X16_WCD_A_DIGITAL_INT_LATCHED_CLR] =
+ MSM8X16_WCD_A_DIGITAL_INT_LATCHED_CLR__POR,
+ [MSM8X16_WCD_A_DIGITAL_INT_EN_SET] =
+ MSM8X16_WCD_A_DIGITAL_INT_EN_SET__POR,
+ [MSM8X16_WCD_A_DIGITAL_INT_EN_CLR] =
+ MSM8X16_WCD_A_DIGITAL_INT_EN_CLR__POR,
+ [MSM8X16_WCD_A_DIGITAL_INT_LATCHED_STS] =
+ MSM8X16_WCD_A_DIGITAL_INT_LATCHED_STS__POR,
+ [MSM8X16_WCD_A_DIGITAL_INT_PENDING_STS] =
+ MSM8X16_WCD_A_DIGITAL_INT_PENDING_STS__POR,
+ [MSM8X16_WCD_A_DIGITAL_INT_MID_SEL] =
+ MSM8X16_WCD_A_DIGITAL_INT_MID_SEL__POR,
+ [MSM8X16_WCD_A_DIGITAL_INT_PRIORITY] =
+ MSM8X16_WCD_A_DIGITAL_INT_PRIORITY__POR,
+ [MSM8X16_WCD_A_DIGITAL_GPIO_MODE] =
+ MSM8X16_WCD_A_DIGITAL_GPIO_MODE__POR,
+ [MSM8X16_WCD_A_DIGITAL_PIN_CTL_OE] =
+ MSM8X16_WCD_A_DIGITAL_PIN_CTL_OE__POR,
+ [MSM8X16_WCD_A_DIGITAL_PIN_CTL_DATA] =
+ MSM8X16_WCD_A_DIGITAL_PIN_CTL_DATA__POR,
+ [MSM8X16_WCD_A_DIGITAL_PIN_STATUS] =
+ MSM8X16_WCD_A_DIGITAL_PIN_STATUS__POR,
+ [MSM8X16_WCD_A_DIGITAL_HDRIVE_CTL] =
+ MSM8X16_WCD_A_DIGITAL_HDRIVE_CTL__POR,
+ [MSM8X16_WCD_A_DIGITAL_CDC_RST_CTL] =
+ MSM8X16_WCD_A_DIGITAL_CDC_RST_CTL__POR,
+ [MSM8X16_WCD_A_DIGITAL_CDC_TOP_CLK_CTL] =
+ MSM8X16_WCD_A_DIGITAL_CDC_TOP_CLK_CTL__POR,
+ [MSM8X16_WCD_A_DIGITAL_CDC_ANA_CLK_CTL] =
+ MSM8X16_WCD_A_DIGITAL_CDC_ANA_CLK_CTL__POR,
+ [MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL] =
+ MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL__POR,
+ [MSM8X16_WCD_A_DIGITAL_CDC_CONN_TX1_CTL] =
+ MSM8X16_WCD_A_DIGITAL_CDC_CONN_TX1_CTL__POR,
+ [MSM8X16_WCD_A_DIGITAL_CDC_CONN_TX2_CTL] =
+ MSM8X16_WCD_A_DIGITAL_CDC_CONN_TX2_CTL__POR,
+ [MSM8X16_WCD_A_DIGITAL_CDC_CONN_HPHR_DAC_CTL] =
+ MSM8X16_WCD_A_DIGITAL_CDC_CONN_HPHR_DAC_CTL__POR,
+ [MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX1_CTL] =
+ MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX1_CTL__POR,
+ [MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX2_CTL] =
+ MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX2_CTL__POR,
+ [MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX3_CTL] =
+ MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX3_CTL__POR,
+ [MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX_LB_CTL] =
+ MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX_LB_CTL__POR,
+ [MSM8X16_WCD_A_DIGITAL_CDC_RX_CTL1] =
+ MSM8X16_WCD_A_DIGITAL_CDC_RX_CTL1__POR,
+ [MSM8X16_WCD_A_DIGITAL_CDC_RX_CTL2] =
+ MSM8X16_WCD_A_DIGITAL_CDC_RX_CTL2__POR,
+ [MSM8X16_WCD_A_DIGITAL_CDC_RX_CTL3] =
+ MSM8X16_WCD_A_DIGITAL_CDC_RX_CTL3__POR,
+ [MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA0] =
+ MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA0__POR,
+ [MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA1] =
+ MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA1__POR,
+ [MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA2] =
+ MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA2__POR,
+ [MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA3] =
+ MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA3__POR,
+ [MSM8X16_WCD_A_DIGITAL_SPARE_0] =
+ MSM8X16_WCD_A_DIGITAL_SPARE_0__POR,
+ [MSM8X16_WCD_A_DIGITAL_SPARE_1] =
+ MSM8X16_WCD_A_DIGITAL_SPARE_1__POR,
+ [MSM8X16_WCD_A_DIGITAL_SPARE_2] =
+ MSM8X16_WCD_A_DIGITAL_SPARE_2__POR,
+ [MSM8X16_WCD_A_ANALOG_REVISION1] =
+ MSM8X16_WCD_A_ANALOG_REVISION1__POR,
+ [MSM8X16_WCD_A_ANALOG_REVISION2] =
+ MSM8X16_WCD_A_ANALOG_REVISION2__POR,
+ [MSM8X16_WCD_A_ANALOG_REVISION3] =
+ MSM8X16_WCD_A_ANALOG_REVISION3__POR,
+ [MSM8X16_WCD_A_ANALOG_REVISION4] =
+ MSM8X16_WCD_A_ANALOG_REVISION4__POR,
+ [MSM8X16_WCD_A_ANALOG_PERPH_TYPE] =
+ MSM8X16_WCD_A_ANALOG_PERPH_TYPE__POR,
+ [MSM8X16_WCD_A_ANALOG_PERPH_SUBTYPE] =
+ MSM8X16_WCD_A_ANALOG_PERPH_SUBTYPE__POR,
+ [MSM8X16_WCD_A_ANALOG_INT_RT_STS] =
+ MSM8X16_WCD_A_ANALOG_INT_RT_STS__POR,
+ [MSM8X16_WCD_A_ANALOG_INT_SET_TYPE] =
+ MSM8X16_WCD_A_ANALOG_INT_SET_TYPE__POR,
+ [MSM8X16_WCD_A_ANALOG_INT_POLARITY_HIGH] =
+ MSM8X16_WCD_A_ANALOG_INT_POLARITY_HIGH__POR,
+ [MSM8X16_WCD_A_ANALOG_INT_POLARITY_LOW] =
+ MSM8X16_WCD_A_ANALOG_INT_POLARITY_LOW__POR,
+ [MSM8X16_WCD_A_ANALOG_INT_LATCHED_CLR] =
+ MSM8X16_WCD_A_ANALOG_INT_LATCHED_CLR__POR,
+ [MSM8X16_WCD_A_ANALOG_INT_EN_SET] =
+ MSM8X16_WCD_A_ANALOG_INT_EN_SET__POR,
+ [MSM8X16_WCD_A_ANALOG_INT_EN_CLR] =
+ MSM8X16_WCD_A_ANALOG_INT_EN_CLR__POR,
+ [MSM8X16_WCD_A_ANALOG_INT_LATCHED_STS] =
+ MSM8X16_WCD_A_ANALOG_INT_LATCHED_STS__POR,
+ [MSM8X16_WCD_A_ANALOG_INT_PENDING_STS] =
+ MSM8X16_WCD_A_ANALOG_INT_PENDING_STS__POR,
+ [MSM8X16_WCD_A_ANALOG_INT_MID_SEL] =
+ MSM8X16_WCD_A_ANALOG_INT_MID_SEL__POR,
+ [MSM8X16_WCD_A_ANALOG_INT_PRIORITY] =
+ MSM8X16_WCD_A_ANALOG_INT_PRIORITY__POR,
+ [MSM8X16_WCD_A_ANALOG_MICB_1_EN] =
+ MSM8X16_WCD_A_ANALOG_MICB_1_EN__POR,
+ [MSM8X16_WCD_A_ANALOG_MICB_1_VAL] =
+ MSM8X16_WCD_A_ANALOG_MICB_1_VAL__POR,
+ [MSM8X16_WCD_A_ANALOG_MICB_1_CTL] =
+ MSM8X16_WCD_A_ANALOG_MICB_1_CTL__POR,
+ [MSM8X16_WCD_A_ANALOG_MICB_1_INT_RBIAS] =
+ MSM8X16_WCD_A_ANALOG_MICB_1_INT_RBIAS__POR,
+ [MSM8X16_WCD_A_ANALOG_MICB_2_EN] =
+ MSM8X16_WCD_A_ANALOG_MICB_2_EN__POR,
+ [MSM8X16_WCD_A_ANALOG_MBHC_DET_CTL_1] =
+ MSM8X16_WCD_A_ANALOG_MBHC_DET_CTL_1__POR,
+ [MSM8X16_WCD_A_ANALOG_MBHC_DET_CTL_2] =
+ MSM8X16_WCD_A_ANALOG_MBHC_DET_CTL_2__POR,
+ [MSM8X16_WCD_A_ANALOG_MBHC_FSM_CTL] =
+ MSM8X16_WCD_A_ANALOG_MBHC_FSM_CTL__POR,
+ [MSM8X16_WCD_A_ANALOG_MBHC_DBNC_TIMER] =
+ MSM8X16_WCD_A_ANALOG_MBHC_DBNC_TIMER__POR,
+ [MSM8X16_WCD_A_ANALOG_MBHC_BTN0_ZDETL_CTL] =
+ MSM8X16_WCD_A_ANALOG_MBHC_BTN0_ZDETL_CTL__POR,
+ [MSM8X16_WCD_A_ANALOG_MBHC_BTN1_ZDETM_CTL] =
+ MSM8X16_WCD_A_ANALOG_MBHC_BTN1_ZDETM_CTL__POR,
+ [MSM8X16_WCD_A_ANALOG_MBHC_BTN2_ZDETH_CTL] =
+ MSM8X16_WCD_A_ANALOG_MBHC_BTN2_ZDETH_CTL__POR,
+ [MSM8X16_WCD_A_ANALOG_MBHC_BTN3_CTL] =
+ MSM8X16_WCD_A_ANALOG_MBHC_BTN3_CTL__POR,
+ [MSM8X16_WCD_A_ANALOG_MBHC_BTN4_CTL] =
+ MSM8X16_WCD_A_ANALOG_MBHC_BTN4_CTL__POR,
+ [MSM8X16_WCD_A_ANALOG_MBHC_BTN_RESULT] =
+ MSM8X16_WCD_A_ANALOG_MBHC_BTN_RESULT__POR,
+ [MSM8X16_WCD_A_ANALOG_MBHC_ZDET_ELECT_RESULT] =
+ MSM8X16_WCD_A_ANALOG_MBHC_ZDET_ELECT_RESULT__POR,
+ [MSM8X16_WCD_A_ANALOG_TX_1_EN] =
+ MSM8X16_WCD_A_ANALOG_TX_1_EN__POR,
+ [MSM8X16_WCD_A_ANALOG_TX_2_EN] =
+ MSM8X16_WCD_A_ANALOG_TX_2_EN__POR,
+ [MSM8X16_WCD_A_ANALOG_TX_1_2_TEST_CTL_1] =
+ MSM8X16_WCD_A_ANALOG_TX_1_2_TEST_CTL_1__POR,
+ [MSM8X16_WCD_A_ANALOG_TX_1_2_TEST_CTL_2] =
+ MSM8X16_WCD_A_ANALOG_TX_1_2_TEST_CTL_2__POR,
+ [MSM8X16_WCD_A_ANALOG_TX_1_2_ATEST_CTL] =
+ MSM8X16_WCD_A_ANALOG_TX_1_2_ATEST_CTL__POR,
+ [MSM8X16_WCD_A_ANALOG_TX_1_2_OPAMP_BIAS] =
+ MSM8X16_WCD_A_ANALOG_TX_1_2_OPAMP_BIAS__POR,
+ [MSM8X16_WCD_A_ANALOG_TX_1_2_TXFE_CLKDIV] =
+ MSM8X16_WCD_A_ANALOG_TX_1_2_TXFE_CLKDIV__POR,
+ [MSM8X16_WCD_A_ANALOG_TX_3_EN] =
+ MSM8X16_WCD_A_ANALOG_TX_3_EN__POR,
+ [MSM8X16_WCD_A_ANALOG_NCP_EN] =
+ MSM8X16_WCD_A_ANALOG_NCP_EN__POR,
+ [MSM8X16_WCD_A_ANALOG_NCP_CLK] =
+ MSM8X16_WCD_A_ANALOG_NCP_CLK__POR,
+ [MSM8X16_WCD_A_ANALOG_NCP_DEGLITCH] =
+ MSM8X16_WCD_A_ANALOG_NCP_DEGLITCH__POR,
+ [MSM8X16_WCD_A_ANALOG_NCP_FBCTRL] =
+ MSM8X16_WCD_A_ANALOG_NCP_FBCTRL__POR,
+ [MSM8X16_WCD_A_ANALOG_NCP_BIAS] =
+ MSM8X16_WCD_A_ANALOG_NCP_BIAS__POR,
+ [MSM8X16_WCD_A_ANALOG_NCP_VCTRL] =
+ MSM8X16_WCD_A_ANALOG_NCP_VCTRL__POR,
+ [MSM8X16_WCD_A_ANALOG_NCP_TEST] =
+ MSM8X16_WCD_A_ANALOG_NCP_TEST__POR,
+ [MSM8X16_WCD_A_ANALOG_RX_CLOCK_DIVIDER] =
+ MSM8X16_WCD_A_ANALOG_RX_CLOCK_DIVIDER__POR,
+ [MSM8X16_WCD_A_ANALOG_RX_COM_OCP_CTL] =
+ MSM8X16_WCD_A_ANALOG_RX_COM_OCP_CTL__POR,
+ [MSM8X16_WCD_A_ANALOG_RX_COM_OCP_COUNT] =
+ MSM8X16_WCD_A_ANALOG_RX_COM_OCP_COUNT__POR,
+ [MSM8X16_WCD_A_ANALOG_RX_COM_BIAS_DAC] =
+ MSM8X16_WCD_A_ANALOG_RX_COM_BIAS_DAC__POR,
+ [MSM8X16_WCD_A_ANALOG_RX_HPH_BIAS_PA] =
+ MSM8X16_WCD_A_ANALOG_RX_HPH_BIAS_PA__POR,
+ [MSM8X16_WCD_A_ANALOG_RX_HPH_BIAS_LDO_OCP] =
+ MSM8X16_WCD_A_ANALOG_RX_HPH_BIAS_LDO_OCP__POR,
+ [MSM8X16_WCD_A_ANALOG_RX_HPH_BIAS_CNP] =
+ MSM8X16_WCD_A_ANALOG_RX_HPH_BIAS_CNP__POR,
+ [MSM8X16_WCD_A_ANALOG_RX_HPH_CNP_EN] =
+ MSM8X16_WCD_A_ANALOG_RX_HPH_CNP_EN__POR,
+ [MSM8X16_WCD_A_ANALOG_RX_HPH_CNP_WG_CTL] =
+ MSM8X16_WCD_A_ANALOG_RX_HPH_CNP_WG_CTL__POR,
+ [MSM8X16_WCD_A_ANALOG_RX_HPH_CNP_WG_TIME] =
+ MSM8X16_WCD_A_ANALOG_RX_HPH_CNP_WG_TIME__POR,
+ [MSM8X16_WCD_A_ANALOG_RX_HPH_L_TEST] =
+ MSM8X16_WCD_A_ANALOG_RX_HPH_L_TEST__POR,
+ [MSM8X16_WCD_A_ANALOG_RX_HPH_L_PA_DAC_CTL] =
+ MSM8X16_WCD_A_ANALOG_RX_HPH_L_PA_DAC_CTL__POR,
+ [MSM8X16_WCD_A_ANALOG_RX_HPH_R_TEST] =
+ MSM8X16_WCD_A_ANALOG_RX_HPH_R_TEST__POR,
+ [MSM8X16_WCD_A_ANALOG_RX_HPH_R_PA_DAC_CTL] =
+ MSM8X16_WCD_A_ANALOG_RX_HPH_R_PA_DAC_CTL__POR,
+ [MSM8X16_WCD_A_ANALOG_RX_EAR_CTL] =
+ MSM8X16_WCD_A_ANALOG_RX_EAR_CTL___POR,
+ [MSM8X16_WCD_A_ANALOG_RX_ATEST] =
+ MSM8X16_WCD_A_ANALOG_RX_ATEST__POR,
+ [MSM8X16_WCD_A_ANALOG_RX_HPH_STATUS] =
+ MSM8X16_WCD_A_ANALOG_RX_HPH_STATUS__POR,
+ [MSM8X16_WCD_A_ANALOG_RX_EAR_STATUS] =
+ MSM8X16_WCD_A_ANALOG_RX_EAR_STATUS__POR,
+ [MSM8X16_WCD_A_ANALOG_SPKR_DAC_CTL] =
+ MSM8X16_WCD_A_ANALOG_SPKR_DAC_CTL__POR,
+ [MSM8X16_WCD_A_ANALOG_SPKR_DRV_CLIP_DET] =
+ MSM8X16_WCD_A_ANALOG_SPKR_DRV_CLIP_DET__POR,
+ [MSM8X16_WCD_A_ANALOG_SPKR_DRV_CTL] =
+ MSM8X16_WCD_A_ANALOG_SPKR_DRV_CTL__POR,
+ [MSM8X16_WCD_A_ANALOG_SPKR_ANA_BIAS_SET] =
+ MSM8X16_WCD_A_ANALOG_SPKR_ANA_BIAS_SET__POR,
+ [MSM8X16_WCD_A_ANALOG_SPKR_OCP_CTL] =
+ MSM8X16_WCD_A_ANALOG_SPKR_OCP_CTL__POR,
+ [MSM8X16_WCD_A_ANALOG_SPKR_PWRSTG_CTL] =
+ MSM8X16_WCD_A_ANALOG_SPKR_PWRSTG_CTL__POR,
+ [MSM8X16_WCD_A_ANALOG_SPKR_DRV_MISC] =
+ MSM8X16_WCD_A_ANALOG_SPKR_DRV_MISC__POR,
+ [MSM8X16_WCD_A_ANALOG_SPKR_DRV_DBG] =
+ MSM8X16_WCD_A_ANALOG_SPKR_DRV_DBG__POR,
+ [MSM8X16_WCD_A_ANALOG_CURRENT_LIMIT] =
+ MSM8X16_WCD_A_ANALOG_CURRENT_LIMIT__POR,
+ [MSM8X16_WCD_A_ANALOG_OUTPUT_VOLTAGE] =
+ MSM8X16_WCD_A_ANALOG_OUTPUT_VOLTAGE__POR,
+ [MSM8X16_WCD_A_ANALOG_BYPASS_MODE] =
+ MSM8X16_WCD_A_ANALOG_BYPASS_MODE__POR,
+ [MSM8X16_WCD_A_ANALOG_BOOST_EN_CTL] =
+ MSM8X16_WCD_A_ANALOG_BOOST_EN_CTL__POR,
+ [MSM8X16_WCD_A_ANALOG_SLOPE_COMP_IP_ZERO] =
+ MSM8X16_WCD_A_ANALOG_SLOPE_COMP_IP_ZERO__POR,
+ [MSM8X16_WCD_A_ANALOG_RDSON_MAX_DUTY_CYCLE] =
+ MSM8X16_WCD_A_ANALOG_RDSON_MAX_DUTY_CYCLE__POR,
+ [MSM8X16_WCD_A_ANALOG_BOOST_TEST1_1] =
+ MSM8X16_WCD_A_ANALOG_BOOST_TEST1_1__POR,
+ [MSM8X16_WCD_A_ANALOG_BOOST_TEST_2] =
+ MSM8X16_WCD_A_ANALOG_BOOST_TEST_2__POR,
+ [MSM8X16_WCD_A_ANALOG_SPKR_SAR_STATUS] =
+ MSM8X16_WCD_A_ANALOG_SPKR_SAR_STATUS__POR,
+ [MSM8X16_WCD_A_ANALOG_SPKR_DRV_STATUS] =
+ MSM8X16_WCD_A_ANALOG_SPKR_DRV_STATUS__POR,
+ [MSM8X16_WCD_A_ANALOG_PBUS_ADD_CSR] =
+ MSM8X16_WCD_A_ANALOG_PBUS_ADD_CSR__POR,
+ [MSM8X16_WCD_A_ANALOG_PBUS_ADD_SEL] =
+ MSM8X16_WCD_A_ANALOG_PBUS_ADD_SEL__POR,
+ [MSM8X16_WCD_A_CDC_CLK_RX_RESET_CTL] =
+ MSM8X16_WCD_A_CDC_CLK_RX_RESET_CTL__POR,
+ [MSM8X16_WCD_A_CDC_CLK_TX_RESET_B1_CTL] =
+ MSM8X16_WCD_A_CDC_CLK_TX_RESET_B1_CTL__POR,
+ [MSM8X16_WCD_A_CDC_CLK_DMIC_B1_CTL] =
+ MSM8X16_WCD_A_CDC_CLK_DMIC_B1_CTL__POR,
+ [MSM8X16_WCD_A_CDC_CLK_RX_I2S_CTL] =
+ MSM8X16_WCD_A_CDC_CLK_RX_I2S_CTL__POR,
+ [MSM8X16_WCD_A_CDC_CLK_TX_I2S_CTL] =
+ MSM8X16_WCD_A_CDC_CLK_TX_I2S_CTL__POR,
+ [MSM8X16_WCD_A_CDC_CLK_OTHR_RESET_B1_CTL] =
+ MSM8X16_WCD_A_CDC_CLK_OTHR_RESET_B1_CTL__POR,
+ [MSM8X16_WCD_A_CDC_CLK_TX_CLK_EN_B1_CTL] =
+ MSM8X16_WCD_A_CDC_CLK_TX_CLK_EN_B1_CTL__POR,
+ [MSM8X16_WCD_A_CDC_CLK_OTHR_CTL] =
+ MSM8X16_WCD_A_CDC_CLK_OTHR_CTL__POR,
+ [MSM8X16_WCD_A_CDC_CLK_RX_B1_CTL] =
+ MSM8X16_WCD_A_CDC_CLK_RX_B1_CTL__POR,
+ [MSM8X16_WCD_A_CDC_CLK_MCLK_CTL] =
+ MSM8X16_WCD_A_CDC_CLK_MCLK_CTL__POR,
+ [MSM8X16_WCD_A_CDC_CLK_PDM_CTL] =
+ MSM8X16_WCD_A_CDC_CLK_PDM_CTL__POR,
+ [MSM8X16_WCD_A_CDC_CLK_SD_CTL] =
+ MSM8X16_WCD_A_CDC_CLK_SD_CTL__POR,
+ [MSM8X16_WCD_A_CDC_RX1_B1_CTL] =
+ MSM8X16_WCD_A_CDC_RX1_B1_CTL__POR,
+ [MSM8X16_WCD_A_CDC_RX2_B1_CTL] =
+ MSM8X16_WCD_A_CDC_RX2_B1_CTL__POR,
+ [MSM8X16_WCD_A_CDC_RX3_B1_CTL] =
+ MSM8X16_WCD_A_CDC_RX3_B1_CTL__POR,
+ [MSM8X16_WCD_A_CDC_RX1_B2_CTL] =
+ MSM8X16_WCD_A_CDC_RX1_B2_CTL__POR,
+ [MSM8X16_WCD_A_CDC_RX2_B2_CTL] =
+ MSM8X16_WCD_A_CDC_RX2_B2_CTL__POR,
+ [MSM8X16_WCD_A_CDC_RX3_B2_CTL] =
+ MSM8X16_WCD_A_CDC_RX3_B2_CTL__POR,
+ [MSM8X16_WCD_A_CDC_RX1_B3_CTL] =
+ MSM8X16_WCD_A_CDC_RX1_B3_CTL__POR,
+ [MSM8X16_WCD_A_CDC_RX2_B3_CTL] =
+ MSM8X16_WCD_A_CDC_RX2_B3_CTL__POR,
+ [MSM8X16_WCD_A_CDC_RX3_B3_CTL] =
+ MSM8X16_WCD_A_CDC_RX3_B3_CTL__POR,
+ [MSM8X16_WCD_A_CDC_RX1_B4_CTL] =
+ MSM8X16_WCD_A_CDC_RX1_B4_CTL__POR,
+ [MSM8X16_WCD_A_CDC_RX2_B4_CTL] =
+ MSM8X16_WCD_A_CDC_RX2_B4_CTL__POR,
+ [MSM8X16_WCD_A_CDC_RX3_B4_CTL] =
+ MSM8X16_WCD_A_CDC_RX3_B4_CTL__POR,
+ [MSM8X16_WCD_A_CDC_RX1_B5_CTL] =
+ MSM8X16_WCD_A_CDC_RX1_B5_CTL__POR,
+ [MSM8X16_WCD_A_CDC_RX2_B5_CTL] =
+ MSM8X16_WCD_A_CDC_RX2_B5_CTL__POR,
+ [MSM8X16_WCD_A_CDC_RX3_B5_CTL] =
+ MSM8X16_WCD_A_CDC_RX3_B5_CTL__POR,
+ [MSM8X16_WCD_A_CDC_RX1_B6_CTL] =
+ MSM8X16_WCD_A_CDC_RX1_B6_CTL__POR,
+ [MSM8X16_WCD_A_CDC_RX2_B6_CTL] =
+ MSM8X16_WCD_A_CDC_RX2_B6_CTL__POR,
+ [MSM8X16_WCD_A_CDC_RX3_B6_CTL] =
+ MSM8X16_WCD_A_CDC_RX3_B6_CTL__POR,
+ [MSM8X16_WCD_A_CDC_RX1_VOL_CTL_B1_CTL] =
+ MSM8X16_WCD_A_CDC_RX1_VOL_CTL_B1_CTL__POR,
+ [MSM8X16_WCD_A_CDC_RX2_VOL_CTL_B1_CTL] =
+ MSM8X16_WCD_A_CDC_RX2_VOL_CTL_B1_CTL__POR,
+ [MSM8X16_WCD_A_CDC_RX3_VOL_CTL_B1_CTL] =
+ MSM8X16_WCD_A_CDC_RX3_VOL_CTL_B1_CTL__POR,
+ [MSM8X16_WCD_A_CDC_RX1_VOL_CTL_B2_CTL] =
+ MSM8X16_WCD_A_CDC_RX1_VOL_CTL_B2_CTL__POR,
+ [MSM8X16_WCD_A_CDC_RX2_VOL_CTL_B2_CTL] =
+ MSM8X16_WCD_A_CDC_RX2_VOL_CTL_B2_CTL__POR,
+ [MSM8X16_WCD_A_CDC_RX3_VOL_CTL_B2_CTL] =
+ MSM8X16_WCD_A_CDC_RX3_VOL_CTL_B2_CTL__POR,
+ [MSM8X16_WCD_A_CDC_TOP_GAIN_UPDATE] =
+ MSM8X16_WCD_A_CDC_TOP_GAIN_UPDATE__POR,
+ [MSM8X16_WCD_A_CDC_TOP_CTL] =
+ MSM8X16_WCD_A_CDC_TOP_CTL__POR,
+ [MSM8X16_WCD_A_CDC_DEBUG_DESER1_CTL] =
+ MSM8X16_WCD_A_CDC_DEBUG_DESER1_CTL__POR,
+ [MSM8X16_WCD_A_CDC_DEBUG_DESER2_CTL] =
+ MSM8X16_WCD_A_CDC_DEBUG_DESER2_CTL__POR,
+ [MSM8X16_WCD_A_CDC_DEBUG_B1_CTL_CFG] =
+ MSM8X16_WCD_A_CDC_DEBUG_B1_CTL__POR,
+ [MSM8X16_WCD_A_CDC_DEBUG_B2_CTL_CFG] =
+ MSM8X16_WCD_A_CDC_DEBUG_B2_CTL__POR,
+ [MSM8X16_WCD_A_CDC_DEBUG_B3_CTL_CFG] =
+ MSM8X16_WCD_A_CDC_DEBUG_B3_CTL__POR,
+ [MSM8X16_WCD_A_CDC_IIR1_GAIN_B1_CTL] =
+ MSM8X16_WCD_A_CDC_IIR1_GAIN_B1_CTL__POR,
+ [MSM8X16_WCD_A_CDC_IIR2_GAIN_B1_CTL] =
+ MSM8X16_WCD_A_CDC_IIR2_GAIN_B1_CTL__POR,
+ [MSM8X16_WCD_A_CDC_IIR1_GAIN_B2_CTL] =
+ MSM8X16_WCD_A_CDC_IIR1_GAIN_B2_CTL__POR,
+ [MSM8X16_WCD_A_CDC_IIR2_GAIN_B2_CTL] =
+ MSM8X16_WCD_A_CDC_IIR2_GAIN_B2_CTL__POR,
+ [MSM8X16_WCD_A_CDC_IIR1_GAIN_B3_CTL] =
+ MSM8X16_WCD_A_CDC_IIR1_GAIN_B3_CTL__POR,
+ [MSM8X16_WCD_A_CDC_IIR2_GAIN_B3_CTL] =
+ MSM8X16_WCD_A_CDC_IIR2_GAIN_B3_CTL__POR,
+ [MSM8X16_WCD_A_CDC_IIR1_GAIN_B4_CTL] =
+ MSM8X16_WCD_A_CDC_IIR1_GAIN_B4_CTL__POR,
+ [MSM8X16_WCD_A_CDC_IIR2_GAIN_B4_CTL] =
+ MSM8X16_WCD_A_CDC_IIR2_GAIN_B4_CTL__POR,
+ [MSM8X16_WCD_A_CDC_IIR1_GAIN_B5_CTL] =
+ MSM8X16_WCD_A_CDC_IIR1_GAIN_B5_CTL__POR,
+ [MSM8X16_WCD_A_CDC_IIR2_GAIN_B5_CTL] =
+ MSM8X16_WCD_A_CDC_IIR2_GAIN_B5_CTL__POR,
+ [MSM8X16_WCD_A_CDC_IIR1_GAIN_B6_CTL] =
+ MSM8X16_WCD_A_CDC_IIR1_GAIN_B6_CTL__POR,
+ [MSM8X16_WCD_A_CDC_IIR2_GAIN_B6_CTL] =
+ MSM8X16_WCD_A_CDC_IIR2_GAIN_B6_CTL__POR,
+ [MSM8X16_WCD_A_CDC_IIR1_GAIN_B7_CTL] =
+ MSM8X16_WCD_A_CDC_IIR1_GAIN_B7_CTL__POR,
+ [MSM8X16_WCD_A_CDC_IIR2_GAIN_B7_CTL] =
+ MSM8X16_WCD_A_CDC_IIR2_GAIN_B7_CTL__POR,
+ [MSM8X16_WCD_A_CDC_IIR1_GAIN_B8_CTL] =
+ MSM8X16_WCD_A_CDC_IIR1_GAIN_B8_CTL__POR,
+ [MSM8X16_WCD_A_CDC_IIR2_GAIN_B8_CTL] =
+ MSM8X16_WCD_A_CDC_IIR2_GAIN_B8_CTL__POR,
+ [MSM8X16_WCD_A_CDC_IIR1_CTL] =
+ MSM8X16_WCD_A_CDC_IIR1_CTL__POR,
+ [MSM8X16_WCD_A_CDC_IIR2_CTL] =
+ MSM8X16_WCD_A_CDC_IIR2_CTL__POR,
+ [MSM8X16_WCD_A_CDC_IIR1_GAIN_TIMER_CTL] =
+ MSM8X16_WCD_A_CDC_IIR1_GAIN_TIMER_CTL__POR,
+ [MSM8X16_WCD_A_CDC_IIR2_GAIN_TIMER_CTL] =
+ MSM8X16_WCD_A_CDC_IIR2_GAIN_TIMER_CTL__POR,
+ [MSM8X16_WCD_A_CDC_IIR1_COEF_B1_CTL] =
+ MSM8X16_WCD_A_CDC_IIR1_COEF_B1_CTL__POR,
+ [MSM8X16_WCD_A_CDC_IIR2_COEF_B1_CTL] =
+ MSM8X16_WCD_A_CDC_IIR2_COEF_B1_CTL__POR,
+ [MSM8X16_WCD_A_CDC_IIR1_COEF_B2_CTL] =
+ MSM8X16_WCD_A_CDC_IIR1_COEF_B2_CTL__POR,
+ [MSM8X16_WCD_A_CDC_IIR2_COEF_B2_CTL] =
+ MSM8X16_WCD_A_CDC_IIR2_COEF_B2_CTL__POR,
+ [MSM8X16_WCD_A_CDC_CONN_RX1_B1_CTL] =
+ MSM8X16_WCD_A_CDC_CONN_RX1_B1_CTL__POR,
+ [MSM8X16_WCD_A_CDC_CONN_RX1_B2_CTL] =
+ MSM8X16_WCD_A_CDC_CONN_RX1_B2_CTL__POR,
+ [MSM8X16_WCD_A_CDC_CONN_RX1_B3_CTL] =
+ MSM8X16_WCD_A_CDC_CONN_RX1_B3_CTL__POR,
+ [MSM8X16_WCD_A_CDC_CONN_RX2_B1_CTL] =
+ MSM8X16_WCD_A_CDC_CONN_RX2_B1_CTL__POR,
+ [MSM8X16_WCD_A_CDC_CONN_RX2_B2_CTL] =
+ MSM8X16_WCD_A_CDC_CONN_RX2_B2_CTL__POR,
+ [MSM8X16_WCD_A_CDC_CONN_RX2_B3_CTL] =
+ MSM8X16_WCD_A_CDC_CONN_RX2_B3_CTL__POR,
+ [MSM8X16_WCD_A_CDC_CONN_RX3_B1_CTL] =
+ MSM8X16_WCD_A_CDC_CONN_RX3_B1_CTL__POR,
+ [MSM8X16_WCD_A_CDC_CONN_RX3_B2_CTL] =
+ MSM8X16_WCD_A_CDC_CONN_RX3_B2_CTL__POR,
+ [MSM8X16_WCD_A_CDC_CONN_TX_B1_CTL] =
+ MSM8X16_WCD_A_CDC_CONN_TX_B1_CTL__POR,
+ [MSM8X16_WCD_A_CDC_CONN_EQ1_B1_CTL] =
+ MSM8X16_WCD_A_CDC_CONN_EQ1_B1_CTL__POR,
+ [MSM8X16_WCD_A_CDC_CONN_EQ1_B2_CTL] =
+ MSM8X16_WCD_A_CDC_CONN_EQ1_B2_CTL__POR,
+ [MSM8X16_WCD_A_CDC_CONN_EQ1_B3_CTL] =
+ MSM8X16_WCD_A_CDC_CONN_EQ1_B3_CTL__POR,
+ [MSM8X16_WCD_A_CDC_CONN_EQ1_B4_CTL] =
+ MSM8X16_WCD_A_CDC_CONN_EQ1_B4_CTL__POR,
+ [MSM8X16_WCD_A_CDC_CONN_EQ2_B1_CTL] =
+ MSM8X16_WCD_A_CDC_CONN_EQ2_B1_CTL__POR,
+ [MSM8X16_WCD_A_CDC_CONN_EQ2_B2_CTL] =
+ MSM8X16_WCD_A_CDC_CONN_EQ2_B2_CTL__POR,
+ [MSM8X16_WCD_A_CDC_CONN_EQ2_B3_CTL] =
+ MSM8X16_WCD_A_CDC_CONN_EQ2_B3_CTL__POR,
+ [MSM8X16_WCD_A_CDC_CONN_EQ2_B4_CTL] =
+ MSM8X16_WCD_A_CDC_CONN_EQ2_B4_CTL__POR,
+ [MSM8X16_WCD_A_CDC_CONN_TX_I2S_SD1_CTL] =
+ MSM8X16_WCD_A_CDC_CONN_TX_I2S_SD1_CTL__POR,
+ [MSM8X16_WCD_A_CDC_TX1_VOL_CTL_TIMER] =
+ MSM8X16_WCD_A_CDC_TX1_VOL_CTL_TIMER__POR,
+ [MSM8X16_WCD_A_CDC_TX2_VOL_CTL_TIMER] =
+ MSM8X16_WCD_A_CDC_TX2_VOL_CTL_TIMER__POR,
+ [MSM8X16_WCD_A_CDC_TX1_VOL_CTL_GAIN] =
+ MSM8X16_WCD_A_CDC_TX1_VOL_CTL_GAIN__POR,
+ [MSM8X16_WCD_A_CDC_TX2_VOL_CTL_GAIN] =
+ MSM8X16_WCD_A_CDC_TX2_VOL_CTL_GAIN__POR,
+ [MSM8X16_WCD_A_CDC_TX1_VOL_CTL_CFG] =
+ MSM8X16_WCD_A_CDC_TX1_VOL_CTL_CFG__POR,
+ [MSM8X16_WCD_A_CDC_TX2_VOL_CTL_CFG] =
+ MSM8X16_WCD_A_CDC_TX2_VOL_CTL_CFG__POR,
+ [MSM8X16_WCD_A_CDC_TX1_MUX_CTL] =
+ MSM8X16_WCD_A_CDC_TX1_MUX_CTL__POR,
+ [MSM8X16_WCD_A_CDC_TX2_MUX_CTL] =
+ MSM8X16_WCD_A_CDC_TX2_MUX_CTL__POR,
+ [MSM8X16_WCD_A_CDC_TX1_CLK_FS_CTL] =
+ MSM8X16_WCD_A_CDC_TX1_CLK_FS_CTL__POR,
+ [MSM8X16_WCD_A_CDC_TX2_CLK_FS_CTL] =
+ MSM8X16_WCD_A_CDC_TX2_CLK_FS_CTL__POR,
+ [MSM8X16_WCD_A_CDC_TX1_DMIC_CTL] =
+ MSM8X16_WCD_A_CDC_TX1_DMIC_CTL__POR,
+ [MSM8X16_WCD_A_CDC_TX2_DMIC_CTL] =
+ MSM8X16_WCD_A_CDC_TX2_DMIC_CTL__POR,
+};
diff --git a/sound/soc/codecs/msm8x16-wcd.c b/sound/soc/codecs/msm8x16-wcd.c
new file mode 100644
index 000000000000..40aa618cfdf4
--- /dev/null
+++ b/sound/soc/codecs/msm8x16-wcd.c
@@ -0,0 +1,3075 @@
+/* Copyright (c) 2014, The Linux Foundation. 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/init.h>
+#include <linux/firmware.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/device.h>
+#include <linux/printk.h>
+#include <linux/ratelimit.h>
+#include <linux/debugfs.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/pm_runtime.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <linux/spmi.h>
+#include <linux/of_gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/mfd/wcd9xxx/pdata.h>
+#include <linux/qdsp6v2/apr.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/tlv.h>
+#include <mach/subsystem_notif.h>
+#include "msm8x16-wcd.h"
+#include "msm8916-wcd-irq.h"
+#include "msm8x16_wcd_registers.h"
+#include "../msm/qdsp6v2/q6core.h"
+
+#define MSM8X16_WCD_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000)
+#define MSM8X16_WCD_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
+
+#define NUM_DECIMATORS 2
+#define NUM_INTERPOLATORS 3
+#define BITS_PER_REG 8
+#define MSM8X16_WCD_TX_PORT_NUMBER 4
+
+#define MSM8X16_WCD_I2S_MASTER_MODE_MASK 0x08
+#define MSM8X16_DIGITAL_CODEC_BASE_ADDR 0x771C000
+#define TOMBAK_CORE_0_SPMI_ADDR 0xf000
+#define TOMBAK_CORE_1_SPMI_ADDR 0xf100
+
+#define CODEC_DT_MAX_PROP_SIZE 40
+#define MAX_ON_DEMAND_SUPPLY_NAME_LENGTH 64
+#define TOMBAK_MCLK_CLK_9P6MHZ 9600000
+
+enum {
+ AIF1_PB = 0,
+ AIF1_CAP,
+ NUM_CODEC_DAIS,
+};
+
+enum {
+ RX_MIX1_INP_SEL_ZERO = 0,
+ RX_MIX1_INP_SEL_IIR1,
+ RX_MIX1_INP_SEL_IIR2,
+ RX_MIX1_INP_SEL_RX1,
+ RX_MIX1_INP_SEL_RX2,
+ RX_MIX1_INP_SEL_RX3,
+};
+
+static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
+static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1);
+static struct snd_soc_dai_driver msm8x16_wcd_i2s_dai[];
+
+#define MSM8X16_WCD_ACQUIRE_LOCK(x) \
+ mutex_lock_nested(&x, SINGLE_DEPTH_NESTING);
+
+#define MSM8X16_WCD_RELEASE_LOCK(x) mutex_unlock(&x);
+
+
+/* Codec supports 2 IIR filters */
+enum {
+ IIR1 = 0,
+ IIR2,
+ IIR_MAX,
+};
+
+/* Codec supports 5 bands */
+enum {
+ BAND1 = 0,
+ BAND2,
+ BAND3,
+ BAND4,
+ BAND5,
+ BAND_MAX,
+};
+
+enum {
+ ON_DEMAND_MICBIAS = 0,
+ ON_DEMAND_SUPPLIES_MAX,
+};
+
+struct hpf_work {
+ struct msm8x16_wcd_priv *msm8x16_wcd;
+ u32 decimator;
+ u8 tx_hpf_cut_of_freq;
+ struct delayed_work dwork;
+};
+
+static struct hpf_work tx_hpf_work[NUM_DECIMATORS];
+
+struct on_demand_supply {
+ struct regulator *supply;
+ atomic_t ref;
+};
+
+static char on_demand_supply_name[][MAX_ON_DEMAND_SUPPLY_NAME_LENGTH] = {
+ "cdc-vdd-mic-bias",
+};
+
+struct msm8x16_wcd_priv {
+ struct snd_soc_codec *codec;
+ u32 adc_count;
+ u32 rx_bias_count;
+ s32 dmic_1_2_clk_cnt;
+ bool mclk_enabled;
+ bool clock_active;
+ bool config_mode_active;
+ struct on_demand_supply on_demand_list[ON_DEMAND_SUPPLIES_MAX];
+ /* resmgr module */
+ /*struct wcd9xxx_resmgr resmgr;*/
+ /* mbhc module */
+ /*struct wcd9xxx_mbhc mbhc; */
+};
+
+static unsigned long rx_digital_gain_reg[] = {
+ MSM8X16_WCD_A_CDC_RX1_VOL_CTL_B2_CTL,
+ MSM8X16_WCD_A_CDC_RX2_VOL_CTL_B2_CTL,
+ MSM8X16_WCD_A_CDC_RX3_VOL_CTL_B2_CTL,
+};
+
+static unsigned long tx_digital_gain_reg[] = {
+ MSM8X16_WCD_A_CDC_TX1_VOL_CTL_GAIN,
+ MSM8X16_WCD_A_CDC_TX2_VOL_CTL_GAIN,
+};
+
+enum {
+ MSM8X16_WCD_SPMI_DIGITAL = 0,
+ MSM8X16_WCD_SPMI_ANALOG,
+ MAX_MSM8X16_WCD_DEVICE
+};
+
+struct msm8x16_wcd_spmi {
+ struct spmi_device *spmi;
+ int base;
+};
+
+static int msm8x16_wcd_dt_parse_vreg_info(struct device *dev,
+ struct msm8x16_wcd_regulator *vreg,
+ const char *vreg_name, bool ondemand);
+static struct msm8x16_wcd_pdata *msm8x16_wcd_populate_dt_pdata(
+ struct device *dev);
+
+struct msm8x16_wcd_spmi msm8x16_wcd_modules[MAX_MSM8X16_WCD_DEVICE];
+
+static void *modem_state_notifier;
+
+static struct snd_soc_codec *registered_codec;
+#define ADSP_STATE_READY_TIMEOUT_MS 2000
+
+static int get_spmi_msm8x16_wcd_device_info(u16 *reg,
+ struct msm8x16_wcd_spmi **msm8x16_wcd)
+{
+ int rtn = 0;
+ int value = ((*reg & 0x0f00) >> 8) & 0x000f;
+
+ *reg = *reg - (value * 0x100);
+ switch (value) {
+ case 0:
+ case 1:
+ *msm8x16_wcd = &msm8x16_wcd_modules[value];
+ break;
+ default:
+ rtn = -EINVAL;
+ break;
+ }
+ return rtn;
+}
+
+static int msm8x16_wcd_ahb_write_device(u16 reg, u8 *value, u32 bytes)
+{
+ u32 temp = ((u32)(*value)) & 0x000000FF;
+ u32 offset = (((u32)(reg)) ^ 0x00000400) & 0x00000FFF;
+
+ iowrite32(temp, ioremap(MSM8X16_DIGITAL_CODEC_BASE_ADDR + offset, 4));
+ return 0;
+}
+
+static int msm8x16_wcd_ahb_read_device(u16 reg, u32 bytes, u8 *value)
+{
+ u32 temp;
+ u32 offset = (((u32)(reg)) ^ 0x00000400) & 0x00000FFF;
+
+ temp = ioread32(ioremap(MSM8X16_DIGITAL_CODEC_BASE_ADDR +
+ offset, 4));
+ *value = (u8)temp;
+ return 0;
+}
+
+static int msm8x16_wcd_spmi_write_device(u16 reg, u8 *value, u32 bytes)
+{
+
+ int ret;
+ struct msm8x16_wcd_spmi *wcd = NULL;
+
+ ret = get_spmi_msm8x16_wcd_device_info(&reg, &wcd);
+ if (ret) {
+ pr_err("%s: Invalid register address\n", __func__);
+ return ret;
+ }
+
+ if (wcd == NULL) {
+ pr_err("%s: Failed to get device info\n", __func__);
+ return -ENODEV;
+ }
+ ret = spmi_ext_register_writel(wcd->spmi->ctrl, wcd->spmi->sid,
+ wcd->base + reg, value, bytes);
+ if (ret)
+ pr_err("Unable to write to addr=%x, ret(%d)\n", reg, ret);
+ /* Try again if the write fails */
+ if (ret != 0) {
+ usleep(10);
+ ret = spmi_ext_register_writel(wcd->spmi->ctrl, wcd->spmi->sid,
+ wcd->base + reg, value, 1);
+ if (ret != 0) {
+ pr_err("failed to write the device\n");
+ return ret;
+ }
+ }
+ pr_debug("write sucess register = %x val = %x\n", reg, *value);
+ return 0;
+}
+
+
+int msm8x16_wcd_spmi_read_device(u16 reg, u32 bytes, u8 *dest)
+{
+ int ret = 0;
+ struct msm8x16_wcd_spmi *wcd = NULL;
+
+ ret = get_spmi_msm8x16_wcd_device_info(&reg, &wcd);
+ if (ret) {
+ pr_err("%s: Invalid register address\n", __func__);
+ return ret;
+ }
+
+ if (wcd == NULL) {
+ pr_err("%s: Failed to get device info\n", __func__);
+ return -ENODEV;
+ }
+
+ ret = spmi_ext_register_readl(wcd->spmi->ctrl, wcd->spmi->sid,
+ wcd->base + reg, dest, bytes);
+ if (ret != 0) {
+ pr_err("failed to read the device\n");
+ return ret;
+ }
+ pr_debug("%s: reg 0x%x = 0x%x\n", __func__, reg, *dest);
+ return 0;
+}
+
+int msm8x16_wcd_spmi_read(unsigned short reg, int bytes, void *dest)
+{
+ return msm8x16_wcd_spmi_read_device(reg, bytes, dest);
+}
+
+int msm8x16_wcd_spmi_write(unsigned short reg, int bytes, void *src)
+{
+ return msm8x16_wcd_spmi_write_device(reg, src, bytes);
+}
+
+static int __msm8x16_wcd_reg_read(struct msm8x16_wcd *msm8x16_wcd,
+ unsigned short reg)
+{
+ int ret = -EINVAL;
+ u8 temp;
+
+ mutex_lock(&msm8x16_wcd->io_lock);
+ if (MSM8X16_WCD_IS_TOMBAK_REG(reg))
+ ret = msm8x16_wcd_spmi_read(reg, 1, &temp);
+ else if (MSM8X16_WCD_IS_DIGITAL_REG(reg))
+ ret = msm8x16_wcd_ahb_read_device(reg, 1, &temp);
+ mutex_unlock(&msm8x16_wcd->io_lock);
+
+ if (ret < 0) {
+ dev_err(msm8x16_wcd->dev,
+ "%s: codec read failed for reg 0x%x\n",
+ __func__, reg);
+ return ret;
+ } else {
+ dev_dbg(msm8x16_wcd->dev, "Read 0x%02x from 0x%x\n",
+ temp, reg);
+ }
+
+ return temp;
+}
+
+static int __msm8x16_wcd_reg_write(struct msm8x16_wcd *msm8x16_wcd,
+ unsigned short reg, u8 val)
+{
+ int ret = -EINVAL;
+
+ mutex_lock(&msm8x16_wcd->io_lock);
+ if (MSM8X16_WCD_IS_TOMBAK_REG(reg))
+ ret = msm8x16_wcd_spmi_write(reg, 1, &val);
+ else if (MSM8X16_WCD_IS_DIGITAL_REG(reg))
+ ret = msm8x16_wcd_ahb_write_device(reg, &val, 1);
+ mutex_unlock(&msm8x16_wcd->io_lock);
+
+ return ret;
+}
+
+static int msm8x16_wcd_volatile(struct snd_soc_codec *codec, unsigned int reg)
+{
+ dev_dbg(codec->dev, "%s: reg 0x%x\n", __func__, reg);
+
+ return msm8x16_wcd_reg_readonly[reg];
+}
+
+static int msm8x16_wcd_readable(struct snd_soc_codec *ssc, unsigned int reg)
+{
+ return msm8x16_wcd_reg_readable[reg];
+}
+
+static int msm8x16_wcd_write(struct snd_soc_codec *codec, unsigned int reg,
+ unsigned int value)
+{
+ int ret;
+
+ dev_dbg(codec->dev, "%s: Write from reg 0x%x\n", __func__, reg);
+ if (reg == SND_SOC_NOPM)
+ return 0;
+
+ BUG_ON(reg > MSM8X16_WCD_MAX_REGISTER);
+
+ if (!msm8x16_wcd_volatile(codec, reg)) {
+ ret = snd_soc_cache_write(codec, reg, value);
+ if (ret != 0)
+ dev_err(codec->dev, "Cache write to %x failed: %d\n",
+ reg, ret);
+ }
+
+ return __msm8x16_wcd_reg_write(codec->control_data, reg, (u8)value);
+}
+
+static unsigned int msm8x16_wcd_read(struct snd_soc_codec *codec,
+ unsigned int reg)
+{
+ unsigned int val;
+ int ret;
+
+ dev_dbg(codec->dev, "%s: Read from reg 0x%x\n", __func__, reg);
+ if (reg == SND_SOC_NOPM)
+ return 0;
+
+ BUG_ON(reg > MSM8X16_WCD_MAX_REGISTER);
+
+ if (!msm8x16_wcd_volatile(codec, reg) &&
+ msm8x16_wcd_readable(codec, reg) &&
+ reg < codec->driver->reg_cache_size) {
+ ret = snd_soc_cache_read(codec, reg, &val);
+ if (ret >= 0) {
+ return val;
+ } else
+ dev_err(codec->dev, "Cache read from %x failed: %d\n",
+ reg, ret);
+ }
+
+ val = __msm8x16_wcd_reg_read(codec->control_data, reg);
+ return val;
+}
+
+
+static int msm8x16_wcd_dt_parse_vreg_info(struct device *dev,
+ struct msm8x16_wcd_regulator *vreg, const char *vreg_name,
+ bool ondemand)
+{
+ int len, ret = 0;
+ const __be32 *prop;
+ char prop_name[CODEC_DT_MAX_PROP_SIZE];
+ struct device_node *regnode = NULL;
+ u32 prop_val;
+
+ snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE, "%s-supply",
+ vreg_name);
+ regnode = of_parse_phandle(dev->of_node, prop_name, 0);
+
+ if (!regnode) {
+ dev_err(dev, "Looking up %s property in node %s failed\n",
+ prop_name, dev->of_node->full_name);
+ return -ENODEV;
+ }
+
+ dev_dbg(dev, "Looking up %s property in node %s\n",
+ prop_name, dev->of_node->full_name);
+
+ vreg->name = vreg_name;
+ vreg->ondemand = ondemand;
+
+ snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
+ "qcom,%s-voltage", vreg_name);
+ prop = of_get_property(dev->of_node, prop_name, &len);
+
+ if (!prop || (len != (2 * sizeof(__be32)))) {
+ dev_err(dev, "%s %s property\n",
+ prop ? "invalid format" : "no", prop_name);
+ return -EINVAL;
+ } else {
+ vreg->min_uv = be32_to_cpup(&prop[0]);
+ vreg->max_uv = be32_to_cpup(&prop[1]);
+ }
+
+ snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
+ "qcom,%s-current", vreg_name);
+
+ ret = of_property_read_u32(dev->of_node, prop_name, &prop_val);
+ if (ret) {
+ dev_err(dev, "Looking up %s property in node %s failed",
+ prop_name, dev->of_node->full_name);
+ return -EFAULT;
+ }
+ vreg->optimum_ua = prop_val;
+
+ dev_dbg(dev, "%s: vol=[%d %d]uV, curr=[%d]uA, ond %d\n\n", vreg->name,
+ vreg->min_uv, vreg->max_uv, vreg->optimum_ua, vreg->ondemand);
+ return 0;
+}
+
+static struct msm8x16_wcd_pdata *msm8x16_wcd_populate_dt_pdata(
+ struct device *dev)
+{
+ struct msm8x16_wcd_pdata *pdata;
+ int ret, static_cnt, ond_cnt, idx, i;
+ const char *name = NULL;
+ const char *static_prop_name = "qcom,cdc-static-supplies";
+ const char *ond_prop_name = "qcom,cdc-on-demand-supplies";
+
+ pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata) {
+ dev_err(dev, "could not allocate memory for platform data\n");
+ return NULL;
+ }
+
+ static_cnt = of_property_count_strings(dev->of_node, static_prop_name);
+ if (IS_ERR_VALUE(static_cnt)) {
+ dev_err(dev, "%s: Failed to get static supplies %d\n", __func__,
+ static_cnt);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ /* On-demand supply list is an optional property */
+ ond_cnt = of_property_count_strings(dev->of_node, ond_prop_name);
+ if (IS_ERR_VALUE(ond_cnt))
+ ond_cnt = 0;
+
+ BUG_ON(static_cnt <= 0 || ond_cnt < 0);
+ if ((static_cnt + ond_cnt) > ARRAY_SIZE(pdata->regulator)) {
+ dev_err(dev, "%s: Num of supplies %u > max supported %u\n",
+ __func__, static_cnt, ARRAY_SIZE(pdata->regulator));
+ ret = -EINVAL;
+ goto err;
+ }
+
+ for (idx = 0; idx < static_cnt; idx++) {
+ ret = of_property_read_string_index(dev->of_node,
+ static_prop_name, idx,
+ &name);
+ if (ret) {
+ dev_err(dev, "%s: of read string %s idx %d error %d\n",
+ __func__, static_prop_name, idx, ret);
+ goto err;
+ }
+
+ dev_dbg(dev, "%s: Found static cdc supply %s\n", __func__,
+ name);
+ ret = msm8x16_wcd_dt_parse_vreg_info(dev,
+ &pdata->regulator[idx],
+ name, false);
+ if (ret) {
+ dev_err(dev, "%s:err parsing vreg for %s idx %d\n",
+ __func__, name, idx);
+ goto err;
+ }
+ }
+
+ for (i = 0; i < ond_cnt; i++, idx++) {
+ ret = of_property_read_string_index(dev->of_node, ond_prop_name,
+ i, &name);
+ if (ret) {
+ dev_err(dev, "%s: err parsing on_demand for %s idx %d\n",
+ __func__, ond_prop_name, i);
+ goto err;
+ }
+
+ dev_dbg(dev, "%s: Found on-demand cdc supply %s\n", __func__,
+ name);
+ ret = msm8x16_wcd_dt_parse_vreg_info(dev,
+ &pdata->regulator[idx],
+ name, true);
+ if (ret) {
+ dev_err(dev, "%s: err parsing vreg on_demand for %s idx %d\n",
+ __func__, name, idx);
+ goto err;
+ }
+ }
+
+ return pdata;
+err:
+ devm_kfree(dev, pdata);
+ dev_err(dev, "%s: Failed to populate DT data ret = %d\n",
+ __func__, ret);
+ return NULL;
+}
+
+static int msm8x16_wcd_codec_enable_on_demand_supply(
+ struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ int ret = 0;
+ struct snd_soc_codec *codec = w->codec;
+ struct msm8x16_wcd_priv *msm8x16_wcd = snd_soc_codec_get_drvdata(codec);
+ struct on_demand_supply *supply;
+
+ if (w->shift >= ON_DEMAND_SUPPLIES_MAX) {
+ dev_err(codec->dev, "%s: error index > MAX Demand supplies",
+ __func__);
+ ret = -EINVAL;
+ goto out;
+ }
+ dev_dbg(codec->dev, "%s: supply: %s event: %d ref: %d\n",
+ __func__, on_demand_supply_name[w->shift], event,
+ atomic_read(&msm8x16_wcd->on_demand_list[w->shift].ref));
+
+ supply = &msm8x16_wcd->on_demand_list[w->shift];
+ WARN_ONCE(!supply->supply, "%s isn't defined\n",
+ on_demand_supply_name[w->shift]);
+ if (!supply->supply) {
+ dev_err(codec->dev, "%s: err supply not present ond for %d",
+ __func__, w->shift);
+ goto out;
+ }
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ if (atomic_inc_return(&supply->ref) == 1)
+ ret = regulator_enable(supply->supply);
+ if (ret)
+ dev_err(codec->dev, "%s: Failed to enable %s\n",
+ __func__,
+ on_demand_supply_name[w->shift]);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ if (atomic_read(&supply->ref) == 0) {
+ dev_dbg(codec->dev, "%s: %s supply has been disabled.\n",
+ __func__, on_demand_supply_name[w->shift]);
+ goto out;
+ }
+ if (atomic_dec_return(&supply->ref) == 0)
+ ret = regulator_disable(supply->supply);
+ if (ret)
+ dev_err(codec->dev, "%s: Failed to disable %s\n",
+ __func__,
+ on_demand_supply_name[w->shift]);
+ break;
+ default:
+ break;
+ }
+out:
+ return ret;
+}
+
+static int msm8x16_wcd_codec_enable_charge_pump(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ dev_dbg(codec->dev, "%s: event = %d\n", __func__, event);
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL, 0x40, 0x40);
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_ANALOG_NCP_EN, 0x10, 0x10);
+ usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS);
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL, 0x40, 0x00);
+ break;
+ }
+ return 0;
+}
+
+static int msm8x16_wcd_pa_gain_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ u8 ear_pa_gain;
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+
+ ear_pa_gain = snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_RX_EAR_CTL);
+
+ ear_pa_gain = (ear_pa_gain >> 5) & 0x1;
+
+ if (ear_pa_gain == 0x00) {
+ ucontrol->value.integer.value[0] = 0;
+ } else if (ear_pa_gain == 0x01) {
+ ucontrol->value.integer.value[0] = 1;
+ } else {
+ dev_err(codec->dev, "%s: ERROR: Unsupported Ear Gain = 0x%x\n",
+ __func__, ear_pa_gain);
+ return -EINVAL;
+ }
+
+ ucontrol->value.integer.value[0] = ear_pa_gain;
+ dev_dbg(codec->dev, "%s: ear_pa_gain = 0x%x\n", __func__, ear_pa_gain);
+ return 0;
+}
+
+static int msm8x16_wcd_pa_gain_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ u8 ear_pa_gain;
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+
+ dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+
+ switch (ucontrol->value.integer.value[0]) {
+ case 0:
+ ear_pa_gain = 0x00;
+ break;
+ case 1:
+ ear_pa_gain = 0x20;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_RX_EAR_CTL,
+ 0x20, ear_pa_gain);
+ return 0;
+}
+
+static int msm8x16_wcd_get_iir_enable_audio_mixer(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ int iir_idx = ((struct soc_multi_mixer_control *)
+ kcontrol->private_value)->reg;
+ int band_idx = ((struct soc_multi_mixer_control *)
+ kcontrol->private_value)->shift;
+
+ ucontrol->value.integer.value[0] =
+ (snd_soc_read(codec,
+ (MSM8X16_WCD_A_CDC_IIR1_CTL + 64 * iir_idx)) &
+ (1 << band_idx)) != 0;
+
+ dev_dbg(codec->dev, "%s: IIR #%d band #%d enable %d\n", __func__,
+ iir_idx, band_idx,
+ (uint32_t)ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm8x16_wcd_put_iir_enable_audio_mixer(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ int iir_idx = ((struct soc_multi_mixer_control *)
+ kcontrol->private_value)->reg;
+ int band_idx = ((struct soc_multi_mixer_control *)
+ kcontrol->private_value)->shift;
+ int value = ucontrol->value.integer.value[0];
+
+ /* Mask first 5 bits, 6-8 are reserved */
+ snd_soc_update_bits(codec,
+ (MSM8X16_WCD_A_CDC_IIR1_CTL + 64 * iir_idx),
+ (1 << band_idx), (value << band_idx));
+
+ dev_dbg(codec->dev, "%s: IIR #%d band #%d enable %d\n", __func__,
+ iir_idx, band_idx,
+ ((snd_soc_read(codec,
+ (MSM8X16_WCD_A_CDC_IIR1_CTL + 64 * iir_idx)) &
+ (1 << band_idx)) != 0));
+
+ return 0;
+}
+static uint32_t get_iir_band_coeff(struct snd_soc_codec *codec,
+ int iir_idx, int band_idx,
+ int coeff_idx)
+{
+ uint32_t value = 0;
+
+ /* Address does not automatically update if reading */
+ snd_soc_write(codec,
+ (MSM8X16_WCD_A_CDC_IIR1_COEF_B1_CTL + 64 * iir_idx),
+ ((band_idx * BAND_MAX + coeff_idx)
+ * sizeof(uint32_t)) & 0x7F);
+
+ value |= snd_soc_read(codec,
+ (MSM8X16_WCD_A_CDC_IIR1_COEF_B2_CTL + 64 * iir_idx));
+
+ snd_soc_write(codec,
+ (MSM8X16_WCD_A_CDC_IIR1_COEF_B1_CTL + 64 * iir_idx),
+ ((band_idx * BAND_MAX + coeff_idx)
+ * sizeof(uint32_t) + 1) & 0x7F);
+
+ value |= (snd_soc_read(codec,
+ (MSM8X16_WCD_A_CDC_IIR1_COEF_B2_CTL + 64 * iir_idx)) << 8);
+
+ snd_soc_write(codec,
+ (MSM8X16_WCD_A_CDC_IIR1_COEF_B1_CTL + 64 * iir_idx),
+ ((band_idx * BAND_MAX + coeff_idx)
+ * sizeof(uint32_t) + 2) & 0x7F);
+
+ value |= (snd_soc_read(codec,
+ (MSM8X16_WCD_A_CDC_IIR1_COEF_B2_CTL + 64 * iir_idx)) << 16);
+
+ snd_soc_write(codec,
+ (MSM8X16_WCD_A_CDC_IIR1_COEF_B1_CTL + 64 * iir_idx),
+ ((band_idx * BAND_MAX + coeff_idx)
+ * sizeof(uint32_t) + 3) & 0x7F);
+
+ /* Mask bits top 2 bits since they are reserved */
+ value |= ((snd_soc_read(codec, (MSM8X16_WCD_A_CDC_IIR1_COEF_B2_CTL
+ + 64 * iir_idx)) & 0x3f) << 24);
+
+ return value;
+
+}
+
+static int msm8x16_wcd_get_iir_band_audio_mixer(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ int iir_idx = ((struct soc_multi_mixer_control *)
+ kcontrol->private_value)->reg;
+ int band_idx = ((struct soc_multi_mixer_control *)
+ kcontrol->private_value)->shift;
+
+ ucontrol->value.integer.value[0] =
+ get_iir_band_coeff(codec, iir_idx, band_idx, 0);
+ ucontrol->value.integer.value[1] =
+ get_iir_band_coeff(codec, iir_idx, band_idx, 1);
+ ucontrol->value.integer.value[2] =
+ get_iir_band_coeff(codec, iir_idx, band_idx, 2);
+ ucontrol->value.integer.value[3] =
+ get_iir_band_coeff(codec, iir_idx, band_idx, 3);
+ ucontrol->value.integer.value[4] =
+ get_iir_band_coeff(codec, iir_idx, band_idx, 4);
+
+ dev_dbg(codec->dev, "%s: IIR #%d band #%d b0 = 0x%x\n"
+ "%s: IIR #%d band #%d b1 = 0x%x\n"
+ "%s: IIR #%d band #%d b2 = 0x%x\n"
+ "%s: IIR #%d band #%d a1 = 0x%x\n"
+ "%s: IIR #%d band #%d a2 = 0x%x\n",
+ __func__, iir_idx, band_idx,
+ (uint32_t)ucontrol->value.integer.value[0],
+ __func__, iir_idx, band_idx,
+ (uint32_t)ucontrol->value.integer.value[1],
+ __func__, iir_idx, band_idx,
+ (uint32_t)ucontrol->value.integer.value[2],
+ __func__, iir_idx, band_idx,
+ (uint32_t)ucontrol->value.integer.value[3],
+ __func__, iir_idx, band_idx,
+ (uint32_t)ucontrol->value.integer.value[4]);
+ return 0;
+}
+
+static void set_iir_band_coeff(struct snd_soc_codec *codec,
+ int iir_idx, int band_idx,
+ uint32_t value)
+{
+ snd_soc_write(codec,
+ (MSM8X16_WCD_A_CDC_IIR1_COEF_B2_CTL + 64 * iir_idx),
+ (value & 0xFF));
+
+ snd_soc_write(codec,
+ (MSM8X16_WCD_A_CDC_IIR1_COEF_B2_CTL + 64 * iir_idx),
+ (value >> 8) & 0xFF);
+
+ snd_soc_write(codec,
+ (MSM8X16_WCD_A_CDC_IIR1_COEF_B2_CTL + 64 * iir_idx),
+ (value >> 16) & 0xFF);
+
+ /* Mask top 2 bits, 7-8 are reserved */
+ snd_soc_write(codec,
+ (MSM8X16_WCD_A_CDC_IIR1_COEF_B2_CTL + 64 * iir_idx),
+ (value >> 24) & 0x3F);
+
+}
+
+static int msm8x16_wcd_put_iir_band_audio_mixer(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ int iir_idx = ((struct soc_multi_mixer_control *)
+ kcontrol->private_value)->reg;
+ int band_idx = ((struct soc_multi_mixer_control *)
+ kcontrol->private_value)->shift;
+
+ /* Mask top bit it is reserved */
+ /* Updates addr automatically for each B2 write */
+ snd_soc_write(codec,
+ (MSM8X16_WCD_A_CDC_IIR1_COEF_B1_CTL + 64 * iir_idx),
+ (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F);
+
+
+ set_iir_band_coeff(codec, iir_idx, band_idx,
+ ucontrol->value.integer.value[0]);
+ set_iir_band_coeff(codec, iir_idx, band_idx,
+ ucontrol->value.integer.value[1]);
+ set_iir_band_coeff(codec, iir_idx, band_idx,
+ ucontrol->value.integer.value[2]);
+ set_iir_band_coeff(codec, iir_idx, band_idx,
+ ucontrol->value.integer.value[3]);
+ set_iir_band_coeff(codec, iir_idx, band_idx,
+ ucontrol->value.integer.value[4]);
+
+ dev_dbg(codec->dev, "%s: IIR #%d band #%d b0 = 0x%x\n"
+ "%s: IIR #%d band #%d b1 = 0x%x\n"
+ "%s: IIR #%d band #%d b2 = 0x%x\n"
+ "%s: IIR #%d band #%d a1 = 0x%x\n"
+ "%s: IIR #%d band #%d a2 = 0x%x\n",
+ __func__, iir_idx, band_idx,
+ get_iir_band_coeff(codec, iir_idx, band_idx, 0),
+ __func__, iir_idx, band_idx,
+ get_iir_band_coeff(codec, iir_idx, band_idx, 1),
+ __func__, iir_idx, band_idx,
+ get_iir_band_coeff(codec, iir_idx, band_idx, 2),
+ __func__, iir_idx, band_idx,
+ get_iir_band_coeff(codec, iir_idx, band_idx, 3),
+ __func__, iir_idx, band_idx,
+ get_iir_band_coeff(codec, iir_idx, band_idx, 4));
+ return 0;
+}
+
+static const char * const msm8x16_wcd_ear_pa_gain_text[] = {
+ "POS_6_DB", "POS_1P5_DB"};
+static const struct soc_enum msm8x16_wcd_ear_pa_gain_enum[] = {
+ SOC_ENUM_SINGLE_EXT(2, msm8x16_wcd_ear_pa_gain_text),
+};
+
+/*cut of frequency for high pass filter*/
+static const char * const cf_text[] = {
+ "MIN_3DB_4Hz", "MIN_3DB_75Hz", "MIN_3DB_150Hz"
+};
+
+static const struct soc_enum cf_dec1_enum =
+ SOC_ENUM_SINGLE(MSM8X16_WCD_A_CDC_TX1_MUX_CTL, 4, 3, cf_text);
+
+static const struct soc_enum cf_dec2_enum =
+ SOC_ENUM_SINGLE(MSM8X16_WCD_A_CDC_TX2_MUX_CTL, 4, 3, cf_text);
+
+static const struct soc_enum cf_rxmix1_enum =
+ SOC_ENUM_SINGLE(MSM8X16_WCD_A_CDC_RX1_B4_CTL, 0, 3, cf_text);
+
+static const struct soc_enum cf_rxmix2_enum =
+ SOC_ENUM_SINGLE(MSM8X16_WCD_A_CDC_RX2_B4_CTL, 0, 3, cf_text);
+
+static const struct soc_enum cf_rxmix3_enum =
+ SOC_ENUM_SINGLE(MSM8X16_WCD_A_CDC_RX3_B4_CTL, 0, 3, cf_text);
+
+static const struct snd_kcontrol_new msm8x16_wcd_snd_controls[] = {
+
+ SOC_ENUM_EXT("EAR PA Gain", msm8x16_wcd_ear_pa_gain_enum[0],
+ msm8x16_wcd_pa_gain_get, msm8x16_wcd_pa_gain_put),
+
+ SOC_SINGLE_SX_TLV("RX1 Digital Volume",
+ MSM8X16_WCD_A_CDC_RX1_VOL_CTL_B2_CTL,
+ 0, -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("RX2 Digital Volume",
+ MSM8X16_WCD_A_CDC_RX2_VOL_CTL_B2_CTL,
+ 0, -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("RX3 Digital Volume",
+ MSM8X16_WCD_A_CDC_RX3_VOL_CTL_B2_CTL,
+ 0, -84, 40, digital_gain),
+
+ SOC_SINGLE_SX_TLV("DEC1 Volume",
+ MSM8X16_WCD_A_CDC_TX1_VOL_CTL_GAIN,
+ 0, -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("DEC2 Volume",
+ MSM8X16_WCD_A_CDC_TX2_VOL_CTL_GAIN,
+ 0, -84, 40, digital_gain),
+
+ SOC_SINGLE_SX_TLV("IIR1 INP1 Volume",
+ MSM8X16_WCD_A_CDC_IIR1_GAIN_B1_CTL,
+ 0, -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("IIR1 INP2 Volume",
+ MSM8X16_WCD_A_CDC_IIR1_GAIN_B2_CTL,
+ 0, -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("IIR1 INP3 Volume",
+ MSM8X16_WCD_A_CDC_IIR1_GAIN_B3_CTL,
+ 0, -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("IIR1 INP4 Volume",
+ MSM8X16_WCD_A_CDC_IIR1_GAIN_B4_CTL,
+ 0, -84, 40, digital_gain),
+
+ SOC_SINGLE("MICBIAS1 CAPLESS Switch",
+ MSM8X16_WCD_A_ANALOG_MICB_1_EN, 4, 1, 1),
+
+ SOC_ENUM("TX1 HPF cut off", cf_dec1_enum),
+ SOC_ENUM("TX2 HPF cut off", cf_dec2_enum),
+
+ SOC_SINGLE("TX1 HPF Switch",
+ MSM8X16_WCD_A_CDC_TX1_MUX_CTL, 3, 1, 0),
+ SOC_SINGLE("TX2 HPF Switch",
+ MSM8X16_WCD_A_CDC_TX2_MUX_CTL, 3, 1, 0),
+
+ SOC_SINGLE("RX1 HPF Switch",
+ MSM8X16_WCD_A_CDC_RX1_B5_CTL, 2, 1, 0),
+ SOC_SINGLE("RX2 HPF Switch",
+ MSM8X16_WCD_A_CDC_RX2_B5_CTL, 2, 1, 0),
+ SOC_SINGLE("RX3 HPF Switch",
+ MSM8X16_WCD_A_CDC_RX3_B5_CTL, 2, 1, 0),
+
+ SOC_ENUM("RX1 HPF cut off", cf_rxmix1_enum),
+ SOC_ENUM("RX2 HPF cut off", cf_rxmix2_enum),
+ SOC_ENUM("RX3 HPF cut off", cf_rxmix3_enum),
+
+ SOC_SINGLE_EXT("IIR1 Enable Band1", IIR1, BAND1, 1, 0,
+ msm8x16_wcd_get_iir_enable_audio_mixer,
+ msm8x16_wcd_put_iir_enable_audio_mixer),
+ SOC_SINGLE_EXT("IIR1 Enable Band2", IIR1, BAND2, 1, 0,
+ msm8x16_wcd_get_iir_enable_audio_mixer,
+ msm8x16_wcd_put_iir_enable_audio_mixer),
+ SOC_SINGLE_EXT("IIR1 Enable Band3", IIR1, BAND3, 1, 0,
+ msm8x16_wcd_get_iir_enable_audio_mixer,
+ msm8x16_wcd_put_iir_enable_audio_mixer),
+ SOC_SINGLE_EXT("IIR1 Enable Band4", IIR1, BAND4, 1, 0,
+ msm8x16_wcd_get_iir_enable_audio_mixer,
+ msm8x16_wcd_put_iir_enable_audio_mixer),
+ SOC_SINGLE_EXT("IIR1 Enable Band5", IIR1, BAND5, 1, 0,
+ msm8x16_wcd_get_iir_enable_audio_mixer,
+ msm8x16_wcd_put_iir_enable_audio_mixer),
+ SOC_SINGLE_EXT("IIR2 Enable Band1", IIR2, BAND1, 1, 0,
+ msm8x16_wcd_get_iir_enable_audio_mixer,
+ msm8x16_wcd_put_iir_enable_audio_mixer),
+ SOC_SINGLE_EXT("IIR2 Enable Band2", IIR2, BAND2, 1, 0,
+ msm8x16_wcd_get_iir_enable_audio_mixer,
+ msm8x16_wcd_put_iir_enable_audio_mixer),
+ SOC_SINGLE_EXT("IIR2 Enable Band3", IIR2, BAND3, 1, 0,
+ msm8x16_wcd_get_iir_enable_audio_mixer,
+ msm8x16_wcd_put_iir_enable_audio_mixer),
+ SOC_SINGLE_EXT("IIR2 Enable Band4", IIR2, BAND4, 1, 0,
+ msm8x16_wcd_get_iir_enable_audio_mixer,
+ msm8x16_wcd_put_iir_enable_audio_mixer),
+ SOC_SINGLE_EXT("IIR2 Enable Band5", IIR2, BAND5, 1, 0,
+ msm8x16_wcd_get_iir_enable_audio_mixer,
+ msm8x16_wcd_put_iir_enable_audio_mixer),
+
+ SOC_SINGLE_MULTI_EXT("IIR1 Band1", IIR1, BAND1, 255, 0, 5,
+ msm8x16_wcd_get_iir_band_audio_mixer,
+ msm8x16_wcd_put_iir_band_audio_mixer),
+ SOC_SINGLE_MULTI_EXT("IIR1 Band2", IIR1, BAND2, 255, 0, 5,
+ msm8x16_wcd_get_iir_band_audio_mixer,
+ msm8x16_wcd_put_iir_band_audio_mixer),
+ SOC_SINGLE_MULTI_EXT("IIR1 Band3", IIR1, BAND3, 255, 0, 5,
+ msm8x16_wcd_get_iir_band_audio_mixer,
+ msm8x16_wcd_put_iir_band_audio_mixer),
+ SOC_SINGLE_MULTI_EXT("IIR1 Band4", IIR1, BAND4, 255, 0, 5,
+ msm8x16_wcd_get_iir_band_audio_mixer,
+ msm8x16_wcd_put_iir_band_audio_mixer),
+ SOC_SINGLE_MULTI_EXT("IIR1 Band5", IIR1, BAND5, 255, 0, 5,
+ msm8x16_wcd_get_iir_band_audio_mixer,
+ msm8x16_wcd_put_iir_band_audio_mixer),
+ SOC_SINGLE_MULTI_EXT("IIR2 Band1", IIR2, BAND1, 255, 0, 5,
+ msm8x16_wcd_get_iir_band_audio_mixer,
+ msm8x16_wcd_put_iir_band_audio_mixer),
+ SOC_SINGLE_MULTI_EXT("IIR2 Band2", IIR2, BAND2, 255, 0, 5,
+ msm8x16_wcd_get_iir_band_audio_mixer,
+ msm8x16_wcd_put_iir_band_audio_mixer),
+ SOC_SINGLE_MULTI_EXT("IIR2 Band3", IIR2, BAND3, 255, 0, 5,
+ msm8x16_wcd_get_iir_band_audio_mixer,
+ msm8x16_wcd_put_iir_band_audio_mixer),
+ SOC_SINGLE_MULTI_EXT("IIR2 Band4", IIR2, BAND4, 255, 0, 5,
+ msm8x16_wcd_get_iir_band_audio_mixer,
+ msm8x16_wcd_put_iir_band_audio_mixer),
+ SOC_SINGLE_MULTI_EXT("IIR2 Band5", IIR2, BAND5, 255, 0, 5,
+ msm8x16_wcd_get_iir_band_audio_mixer,
+ msm8x16_wcd_put_iir_band_audio_mixer),
+
+};
+
+static const char * const rx_mix1_text[] = {
+ "ZERO", "IIR1", "IIR2", "RX1", "RX2", "RX3"
+};
+
+static const char * const rx_mix2_text[] = {
+ "ZERO", "IIR1", "IIR2"
+};
+
+static const char * const dec_mux_text[] = {
+ "ZERO", "ADC1", "ADC2", "ADC3", "DMIC1", "DMIC2"
+};
+
+static const char * const adc2_mux_text[] = {
+ "ZERO", "INP2", "INP3"
+};
+
+static const char * const rdac2_mux_text[] = {
+ "ZERO", "RX2", "RX1"
+};
+
+static const char * const iir1_inp1_text[] = {
+ "ZERO", "DEC1", "DEC2", "RX1", "RX2", "RX3"
+};
+
+static const struct soc_enum adc2_enum =
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(adc2_mux_text), adc2_mux_text);
+
+/* RX1 MIX1 */
+static const struct soc_enum rx_mix1_inp1_chain_enum =
+ SOC_ENUM_SINGLE(MSM8X16_WCD_A_CDC_CONN_RX1_B1_CTL,
+ 0, 6, rx_mix1_text);
+
+static const struct soc_enum rx_mix1_inp2_chain_enum =
+ SOC_ENUM_SINGLE(MSM8X16_WCD_A_CDC_CONN_RX1_B1_CTL,
+ 3, 6, rx_mix1_text);
+
+static const struct soc_enum rx_mix1_inp3_chain_enum =
+ SOC_ENUM_SINGLE(MSM8X16_WCD_A_CDC_CONN_RX1_B2_CTL,
+ 0, 6, rx_mix1_text);
+
+/* RX1 MIX2 */
+static const struct soc_enum rx_mix2_inp1_chain_enum =
+ SOC_ENUM_SINGLE(MSM8X16_WCD_A_CDC_CONN_RX1_B3_CTL,
+ 0, 3, rx_mix2_text);
+
+/* RX2 MIX1 */
+static const struct soc_enum rx2_mix1_inp1_chain_enum =
+ SOC_ENUM_SINGLE(MSM8X16_WCD_A_CDC_CONN_RX2_B1_CTL,
+ 0, 6, rx_mix1_text);
+
+static const struct soc_enum rx2_mix1_inp2_chain_enum =
+ SOC_ENUM_SINGLE(MSM8X16_WCD_A_CDC_CONN_RX2_B1_CTL,
+ 3, 6, rx_mix1_text);
+
+static const struct soc_enum rx2_mix1_inp3_chain_enum =
+ SOC_ENUM_SINGLE(MSM8X16_WCD_A_CDC_CONN_RX2_B1_CTL,
+ 0, 6, rx_mix1_text);
+
+/* RX2 MIX2 */
+static const struct soc_enum rx2_mix2_inp1_chain_enum =
+ SOC_ENUM_SINGLE(MSM8X16_WCD_A_CDC_CONN_RX2_B3_CTL,
+ 0, 3, rx_mix2_text);
+
+/* RX3 MIX1 */
+static const struct soc_enum rx3_mix1_inp1_chain_enum =
+ SOC_ENUM_SINGLE(MSM8X16_WCD_A_CDC_CONN_RX3_B1_CTL,
+ 0, 6, rx_mix1_text);
+
+static const struct soc_enum rx3_mix1_inp2_chain_enum =
+ SOC_ENUM_SINGLE(MSM8X16_WCD_A_CDC_CONN_RX3_B1_CTL,
+ 3, 6, rx_mix1_text);
+
+static const struct soc_enum rx3_mix1_inp3_chain_enum =
+ SOC_ENUM_SINGLE(MSM8X16_WCD_A_CDC_CONN_RX3_B1_CTL,
+ 0, 6, rx_mix1_text);
+
+/* DEC */
+static const struct soc_enum dec1_mux_enum =
+ SOC_ENUM_SINGLE(MSM8X16_WCD_A_CDC_CONN_TX_B1_CTL,
+ 0, 6, dec_mux_text);
+
+static const struct soc_enum dec2_mux_enum =
+ SOC_ENUM_SINGLE(MSM8X16_WCD_A_CDC_CONN_TX_B1_CTL,
+ 3, 6, dec_mux_text);
+
+static const struct soc_enum rdac2_mux_enum =
+ SOC_ENUM_SINGLE(MSM8X16_WCD_A_DIGITAL_CDC_CONN_HPHR_DAC_CTL,
+ 0, 3, rdac2_mux_text);
+
+static const struct soc_enum iir1_inp1_mux_enum =
+ SOC_ENUM_SINGLE(MSM8X16_WCD_A_CDC_CONN_EQ1_B1_CTL,
+ 0, 6, iir1_inp1_text);
+
+static const struct snd_kcontrol_new rx_mix1_inp1_mux =
+ SOC_DAPM_ENUM("RX1 MIX1 INP1 Mux", rx_mix1_inp1_chain_enum);
+
+static const struct snd_kcontrol_new rx_mix1_inp2_mux =
+ SOC_DAPM_ENUM("RX1 MIX1 INP2 Mux", rx_mix1_inp2_chain_enum);
+
+static const struct snd_kcontrol_new rx_mix1_inp3_mux =
+ SOC_DAPM_ENUM("RX1 MIX1 INP3 Mux", rx_mix1_inp3_chain_enum);
+
+static const struct snd_kcontrol_new rx2_mix1_inp1_mux =
+ SOC_DAPM_ENUM("RX2 MIX1 INP1 Mux", rx2_mix1_inp1_chain_enum);
+
+static const struct snd_kcontrol_new rx2_mix1_inp2_mux =
+ SOC_DAPM_ENUM("RX2 MIX1 INP2 Mux", rx2_mix1_inp2_chain_enum);
+
+static const struct snd_kcontrol_new rx2_mix1_inp3_mux =
+ SOC_DAPM_ENUM("RX2 MIX1 INP3 Mux", rx2_mix1_inp3_chain_enum);
+
+static const struct snd_kcontrol_new rx3_mix1_inp1_mux =
+ SOC_DAPM_ENUM("RX3 MIX1 INP1 Mux", rx3_mix1_inp1_chain_enum);
+
+static const struct snd_kcontrol_new rx3_mix1_inp2_mux =
+ SOC_DAPM_ENUM("RX3 MIX1 INP2 Mux", rx3_mix1_inp2_chain_enum);
+
+static const struct snd_kcontrol_new rx3_mix1_inp3_mux =
+ SOC_DAPM_ENUM("RX3 MIX1 INP3 Mux", rx3_mix1_inp3_chain_enum);
+
+static const struct snd_kcontrol_new rx1_mix2_inp1_mux =
+ SOC_DAPM_ENUM("RX1 MIX2 INP1 Mux", rx_mix2_inp1_chain_enum);
+
+static const struct snd_kcontrol_new rx2_mix2_inp1_mux =
+ SOC_DAPM_ENUM("RX2 MIX2 INP1 Mux", rx2_mix2_inp1_chain_enum);
+
+static const struct snd_kcontrol_new tx_adc2_mux =
+ SOC_DAPM_ENUM("ADC2 MUX Mux", adc2_enum);
+
+static int msm8x16_wcd_put_dec_enum(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_dapm_widget *w = wlist->widgets[0];
+ struct snd_soc_codec *codec = w->codec;
+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+ unsigned int dec_mux, decimator;
+ char *dec_name = NULL;
+ char *widget_name = NULL;
+ char *temp;
+ u16 tx_mux_ctl_reg;
+ u8 adc_dmic_sel = 0x0;
+ int ret = 0;
+
+ if (ucontrol->value.enumerated.item[0] > e->max - 1) {
+ dev_err(codec->dev, "%s: Invalid enum value: %d\n",
+ __func__, ucontrol->value.enumerated.item[0]);
+ return -EINVAL;
+ }
+ dec_mux = ucontrol->value.enumerated.item[0];
+
+ widget_name = kstrndup(w->name, 15, GFP_KERNEL);
+ if (!widget_name) {
+ dev_err(codec->dev, "%s: failed to copy string\n",
+ __func__);
+ return -ENOMEM;
+ }
+ temp = widget_name;
+
+ dec_name = strsep(&widget_name, " ");
+ widget_name = temp;
+ if (!dec_name) {
+ dev_err(codec->dev, "%s: Invalid decimator = %s\n",
+ __func__, w->name);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = kstrtouint(strpbrk(dec_name, "12"), 10, &decimator);
+ if (ret < 0) {
+ dev_err(codec->dev, "%s: Invalid decimator = %s\n",
+ __func__, dec_name);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ dev_dbg(w->dapm->dev, "%s(): widget = %s decimator = %u dec_mux = %u\n"
+ , __func__, w->name, decimator, dec_mux);
+
+ switch (decimator) {
+ case 1:
+ case 2:
+ if ((dec_mux == 4) || (dec_mux == 5))
+ adc_dmic_sel = 0x1;
+ else
+ adc_dmic_sel = 0x0;
+ break;
+ default:
+ dev_err(codec->dev, "%s: Invalid Decimator = %u\n",
+ __func__, decimator);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ tx_mux_ctl_reg =
+ MSM8X16_WCD_A_CDC_TX1_MUX_CTL + 32 * (decimator - 1);
+
+ snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x1, adc_dmic_sel);
+
+ ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
+
+out:
+ kfree(widget_name);
+ return ret;
+}
+
+#define MSM8X16_WCD_DEC_ENUM(xname, xenum) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+ .info = snd_soc_info_enum_double, \
+ .get = snd_soc_dapm_get_enum_double, \
+ .put = msm8x16_wcd_put_dec_enum, \
+ .private_value = (unsigned long)&xenum }
+
+static const struct snd_kcontrol_new dec1_mux =
+ MSM8X16_WCD_DEC_ENUM("DEC1 MUX Mux", dec1_mux_enum);
+
+static const struct snd_kcontrol_new dec2_mux =
+ MSM8X16_WCD_DEC_ENUM("DEC2 MUX Mux", dec2_mux_enum);
+
+static const struct snd_kcontrol_new rdac2_mux =
+ MSM8X16_WCD_DEC_ENUM("RDAC2 MUX Mux", rdac2_mux_enum);
+
+static const struct snd_kcontrol_new iir1_inp1_mux =
+ SOC_DAPM_ENUM("IIR1 INP1 Mux", iir1_inp1_mux_enum);
+
+static const struct snd_kcontrol_new ear_pa_switch[] = {
+ SOC_DAPM_SINGLE("Switch",
+ MSM8X16_WCD_A_ANALOG_RX_EAR_CTL, 5, 1, 0)
+};
+
+static const struct snd_kcontrol_new hphl_switch[] = {
+ SOC_DAPM_SINGLE("Switch",
+ MSM8X16_WCD_A_ANALOG_RX_HPH_L_PA_DAC_CTL, 7, 1, 0)
+};
+
+static const struct snd_kcontrol_new hphr_switch[] = {
+ SOC_DAPM_SINGLE("Switch",
+ MSM8X16_WCD_A_ANALOG_RX_HPH_R_PA_DAC_CTL, 7, 1, 0)
+};
+
+static const struct snd_kcontrol_new spkr_switch[] = {
+ SOC_DAPM_SINGLE("Switch",
+ MSM8X16_WCD_A_ANALOG_SPKR_DAC_CTL, 7, 1, 0)
+};
+
+static void msm8x16_wcd_codec_enable_adc_block(struct snd_soc_codec *codec,
+ int enable)
+{
+ struct msm8x16_wcd_priv *wcd8x16 = snd_soc_codec_get_drvdata(codec);
+
+ dev_dbg(codec->dev, "%s %d\n", __func__, enable);
+
+ if (enable) {
+ wcd8x16->adc_count++;
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_DIGITAL_CDC_ANA_CLK_CTL,
+ 0x20, 0x20);
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL,
+ 0x10, 0x10);
+ } else {
+ wcd8x16->adc_count--;
+ if (!wcd8x16->adc_count) {
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL,
+ 0x10, 0x00);
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_DIGITAL_CDC_ANA_CLK_CTL,
+ 0x20, 0x0);
+ }
+ }
+}
+
+static int msm8x16_wcd_codec_enable_adc(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ u16 adc_reg;
+ u8 init_bit_shift;
+
+ dev_dbg(codec->dev, "%s %d\n", __func__, event);
+
+ adc_reg = MSM8X16_WCD_A_ANALOG_TX_1_2_TEST_CTL_2;
+
+ if (w->reg == MSM8X16_WCD_A_ANALOG_TX_1_EN)
+ init_bit_shift = 5;
+ else if ((w->reg == MSM8X16_WCD_A_ANALOG_TX_2_EN) ||
+ (w->reg == MSM8X16_WCD_A_ANALOG_TX_3_EN))
+ init_bit_shift = 4;
+ else {
+ dev_err(codec->dev, "%s: Error, invalid adc register\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ msm8x16_wcd_codec_enable_adc_block(codec, 1);
+ snd_soc_update_bits(codec, adc_reg, 1 << init_bit_shift,
+ 1 << init_bit_shift);
+ usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS);
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ snd_soc_update_bits(codec, adc_reg, 1 << init_bit_shift, 0x00);
+ usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ msm8x16_wcd_codec_enable_adc_block(codec, 0);
+ break;
+ }
+ return 0;
+}
+
+static int msm8x16_wcd_codec_enable_spk_pa(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ dev_dbg(w->codec->dev, "%s %d %s\n", __func__, event, w->name);
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x10);
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_ANALOG_SPKR_PWRSTG_CTL, 0x01, 0x01);
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_ANALOG_RX_COM_BIAS_DAC, 0x80, 0x80);
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_ANALOG_SPKR_DAC_CTL, 0x10, 0x10);
+ usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS);
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_ANALOG_SPKR_PWRSTG_CTL, 0xE0, 0xE0);
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS);
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_ANALOG_SPKR_DAC_CTL, 0x10, 0x00);
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_CDC_RX3_B6_CTL, 0x01, 0x00);
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_CDC_RX3_B6_CTL, 0x01, 0x01);
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_CDC_RX3_B6_CTL, 0x01, 0x00);
+ msleep(20);
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_CDC_RX3_B6_CTL, 0x01, 0x01);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_ANALOG_SPKR_PWRSTG_CTL, 0xE0, 0x00);
+ usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS);
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_ANALOG_SPKR_PWRSTG_CTL, 0x01, 0x00);
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_ANALOG_RX_COM_BIAS_DAC, 0x80, 0x00);
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x00);
+ break;
+ }
+ return 0;
+}
+
+static int msm8x16_wcd_codec_enable_dig_clk(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ dev_err(w->codec->dev, "%s %d %s\n", __func__, event, w->name);
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ snd_soc_update_bits(codec, w->reg,
+ 1<<w->shift, 1<<w->shift);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ snd_soc_update_bits(codec, w->reg,
+ 1<<w->shift, 0x00);
+ break;
+ }
+ return 0;
+}
+
+static int msm8x16_wcd_codec_enable_dmic(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ struct msm8x16_wcd_priv *msm8x16_wcd = snd_soc_codec_get_drvdata(codec);
+ u8 dmic_clk_en;
+ u16 dmic_clk_reg;
+ s32 *dmic_clk_cnt;
+ unsigned int dmic;
+ int ret;
+
+ ret = kstrtouint(strpbrk(w->name, "12"), 10, &dmic);
+ if (ret < 0) {
+ dev_err(codec->dev,
+ "%s: Invalid DMIC line on the codec\n", __func__);
+ return -EINVAL;
+ }
+
+ switch (dmic) {
+ case 1:
+ case 2:
+ dmic_clk_en = 0x01;
+ dmic_clk_cnt = &(msm8x16_wcd->dmic_1_2_clk_cnt);
+ dmic_clk_reg = MSM8X16_WCD_A_CDC_CLK_DMIC_B1_CTL;
+ dev_dbg(codec->dev,
+ "%s() event %d DMIC%d dmic_1_2_clk_cnt %d\n",
+ __func__, event, dmic, *dmic_clk_cnt);
+ break;
+ default:
+ dev_err(codec->dev, "%s: Invalid DMIC Selection\n", __func__);
+ return -EINVAL;
+ }
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ (*dmic_clk_cnt)++;
+ if (*dmic_clk_cnt == 1) {
+ snd_soc_update_bits(codec, dmic_clk_reg,
+ 0x0E, 0x02);
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_CDC_TX1_DMIC_CTL, 0x07, 0x01);
+ snd_soc_update_bits(codec, dmic_clk_reg,
+ dmic_clk_en, dmic_clk_en);
+ }
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ (*dmic_clk_cnt)--;
+ if (*dmic_clk_cnt == 0)
+ snd_soc_update_bits(codec, dmic_clk_reg,
+ dmic_clk_en, 0);
+ break;
+ }
+ return 0;
+}
+
+static int msm8x16_wcd_codec_enable_micbias(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ u16 micb_int_reg;
+ char *internal1_text = "Internal1";
+ char *internal2_text = "Internal2";
+ char *internal3_text = "Internal3";
+
+ dev_dbg(codec->dev, "%s %d\n", __func__, event);
+ switch (w->reg) {
+ case MSM8X16_WCD_A_ANALOG_MICB_1_EN:
+ micb_int_reg = MSM8X16_WCD_A_ANALOG_MICB_1_INT_RBIAS;
+ break;
+ default:
+ dev_err(codec->dev,
+ "%s: Error, invalid micbias register 0x%x\n",
+ __func__, w->reg);
+ return -EINVAL;
+ }
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ if (strnstr(w->name, internal1_text, 30))
+ snd_soc_update_bits(codec, micb_int_reg, 0x80, 0x80);
+ else if (strnstr(w->name, internal2_text, 30))
+ snd_soc_update_bits(codec, micb_int_reg, 0x10, 0x10);
+ else if (strnstr(w->name, internal3_text, 30))
+ snd_soc_update_bits(codec, micb_int_reg, 0x2, 0x2);
+ snd_soc_update_bits(codec, w->reg, 0x1, 0x0);
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ usleep_range(20000, 20100);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ if (strnstr(w->name, internal1_text, 30))
+ snd_soc_update_bits(codec, micb_int_reg, 0x80, 0x00);
+ else if (strnstr(w->name, internal2_text, 30))
+ snd_soc_update_bits(codec, micb_int_reg, 0x10, 0x00);
+ else if (strnstr(w->name, internal3_text, 30))
+ snd_soc_update_bits(codec, micb_int_reg, 0x2, 0x0);
+
+ snd_soc_update_bits(codec, w->reg, 0x1, 0x1);
+ break;
+ }
+ return 0;
+}
+
+static void tx_hpf_corner_freq_callback(struct work_struct *work)
+{
+ struct delayed_work *hpf_delayed_work;
+ struct hpf_work *hpf_work;
+ struct msm8x16_wcd_priv *msm8x16_wcd;
+ struct snd_soc_codec *codec;
+ u16 tx_mux_ctl_reg;
+ u8 hpf_cut_of_freq;
+
+ hpf_delayed_work = to_delayed_work(work);
+ hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork);
+ msm8x16_wcd = hpf_work->msm8x16_wcd;
+ codec = hpf_work->msm8x16_wcd->codec;
+ hpf_cut_of_freq = hpf_work->tx_hpf_cut_of_freq;
+
+ tx_mux_ctl_reg = MSM8X16_WCD_A_CDC_TX1_MUX_CTL +
+ (hpf_work->decimator - 1) * 32;
+
+ dev_dbg(codec->dev, "%s(): decimator %u hpf_cut_of_freq 0x%x\n",
+ __func__, hpf_work->decimator, (unsigned int)hpf_cut_of_freq);
+
+ snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30, hpf_cut_of_freq << 4);
+}
+
+
+#define TX_MUX_CTL_CUT_OFF_FREQ_MASK 0x30
+#define CF_MIN_3DB_4HZ 0x0
+#define CF_MIN_3DB_75HZ 0x1
+#define CF_MIN_3DB_150HZ 0x2
+
+static int msm8x16_wcd_codec_enable_dec(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ unsigned int decimator;
+ char *dec_name = NULL;
+ char *widget_name = NULL;
+ char *temp;
+ int ret = 0;
+ u16 dec_reset_reg, tx_vol_ctl_reg, tx_mux_ctl_reg;
+ u8 dec_hpf_cut_of_freq;
+ int offset;
+
+ dev_dbg(codec->dev, "%s %d\n", __func__, event);
+
+ widget_name = kstrndup(w->name, 15, GFP_KERNEL);
+ if (!widget_name)
+ return -ENOMEM;
+ temp = widget_name;
+
+ dec_name = strsep(&widget_name, " ");
+ widget_name = temp;
+ if (!dec_name) {
+ dev_err(codec->dev,
+ "%s: Invalid decimator = %s\n", __func__, w->name);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = kstrtouint(strpbrk(dec_name, "12"), 10, &decimator);
+ if (ret < 0) {
+ dev_err(codec->dev,
+ "%s: Invalid decimator = %s\n", __func__, dec_name);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ dev_dbg(codec->dev,
+ "%s(): widget = %s dec_name = %s decimator = %u\n", __func__,
+ w->name, dec_name, decimator);
+
+ if (w->reg == MSM8X16_WCD_A_CDC_CLK_TX_CLK_EN_B1_CTL) {
+ dec_reset_reg = MSM8X16_WCD_A_CDC_CLK_TX_RESET_B1_CTL;
+ offset = 0;
+ } else {
+ dev_err(codec->dev, "%s: Error, incorrect dec\n", __func__);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ tx_vol_ctl_reg = MSM8X16_WCD_A_CDC_TX1_VOL_CTL_CFG +
+ 32 * (decimator - 1);
+ tx_mux_ctl_reg = MSM8X16_WCD_A_CDC_TX1_MUX_CTL +
+ 32 * (decimator - 1);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ /* Enableable TX digital mute */
+ snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x01);
+
+ dec_hpf_cut_of_freq = snd_soc_read(codec, tx_mux_ctl_reg);
+
+ dec_hpf_cut_of_freq = (dec_hpf_cut_of_freq & 0x30) >> 4;
+
+ tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq =
+ dec_hpf_cut_of_freq;
+
+ if ((dec_hpf_cut_of_freq != CF_MIN_3DB_150HZ)) {
+
+ /* set cut of freq to CF_MIN_3DB_150HZ (0x1); */
+ snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30,
+ CF_MIN_3DB_150HZ << 4);
+ }
+
+ /* enable HPF */
+ snd_soc_update_bits(codec, tx_mux_ctl_reg , 0x08, 0x00);
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ /* Disable TX digital mute */
+ snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x00);
+
+ if (tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq !=
+ CF_MIN_3DB_150HZ) {
+
+ schedule_delayed_work(&tx_hpf_work[decimator - 1].dwork,
+ msecs_to_jiffies(300));
+ }
+ /* apply the digital gain after the decimator is enabled*/
+ if ((w->shift) < ARRAY_SIZE(tx_digital_gain_reg))
+ snd_soc_write(codec,
+ tx_digital_gain_reg[w->shift + offset],
+ snd_soc_read(codec,
+ tx_digital_gain_reg[w->shift + offset])
+ );
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x01);
+ snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x00);
+ msleep(20);
+ snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x01);
+ snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x08, 0x08);
+ cancel_delayed_work_sync(&tx_hpf_work[decimator - 1].dwork);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ snd_soc_update_bits(codec, dec_reset_reg, 1 << w->shift,
+ 1 << w->shift);
+ snd_soc_update_bits(codec, dec_reset_reg, 1 << w->shift, 0x0);
+ snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x08, 0x08);
+ snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30,
+ (tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq) << 4);
+ snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x00);
+ break;
+ }
+out:
+ kfree(widget_name);
+ return ret;
+}
+
+static int msm8x16_wcd_codec_enable_interpolator(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_CDC_RX1_B6_CTL + (w->shift*0x20),
+ 0x01, 0x01);
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ /* apply the digital gain after the interpolator is enabled*/
+ if ((w->shift) < ARRAY_SIZE(rx_digital_gain_reg))
+ snd_soc_write(codec,
+ rx_digital_gain_reg[w->shift],
+ snd_soc_read(codec,
+ rx_digital_gain_reg[w->shift])
+ );
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_CDC_CLK_RX_RESET_CTL,
+ 1 << w->shift, 1 << w->shift);
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_CDC_CLK_RX_RESET_CTL,
+ 1 << w->shift, 0x0);
+ }
+ return 0;
+}
+
+
+/* The register address is the same as other codec so it can use resmgr */
+static int msm8x16_wcd_codec_enable_rx_bias(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ dev_dbg(codec->dev, "%s %d\n", __func__, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_RX_COM_BIAS_DAC,
+ 0x80, 0x80);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_RX_COM_BIAS_DAC,
+ 0x80, 0x00);
+ break;
+ }
+ return 0;
+}
+
+static int msm8x16_wcd_hphl_dac_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_ANALOG_RX_HPH_L_PA_DAC_CTL, 0x02, 0x02);
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL, 0x01, 0x01);
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_DIGITAL_CDC_ANA_CLK_CTL, 0x02, 0x02);
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_ANALOG_RX_HPH_L_PA_DAC_CTL, 0x02, 0x00);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_DIGITAL_CDC_ANA_CLK_CTL, 0x02, 0x00);
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL, 0x01, 0x00);
+ break;
+ }
+ return 0;
+}
+
+static int msm8x16_wcd_hphr_dac_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_ANALOG_RX_HPH_R_PA_DAC_CTL, 0x02, 0x02);
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL, 0x02, 0x02);
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_DIGITAL_CDC_ANA_CLK_CTL, 0x01, 0x01);
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_ANALOG_RX_HPH_R_PA_DAC_CTL, 0x02, 0x00);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_DIGITAL_CDC_ANA_CLK_CTL, 0x01, 0x00);
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL, 0x02, 0x00);
+ break;
+ }
+ return 0;
+}
+
+static int msm8x16_wcd_hph_pa_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ dev_dbg(codec->dev, "%s: %s event = %d\n", __func__, w->name, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ /* Let MBHC module know PA is turning on
+ wcd9xxx_resmgr_notifier_call(&msm8x16_wcd->resmgr, e_pre_on); */
+ break;
+
+ case SND_SOC_DAPM_POST_PMU:
+ usleep_range(4000, 4100);
+ if (w->shift == 5)
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_CDC_RX1_B6_CTL, 0x01, 0x00);
+ else if (w->shift == 4)
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_CDC_RX2_B6_CTL, 0x01, 0x00);
+ usleep_range(10000, 10100);
+ break;
+
+ case SND_SOC_DAPM_PRE_PMD:
+ if (w->shift == 5) {
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_CDC_RX1_B6_CTL, 0x01, 0x01);
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_CDC_RX1_B6_CTL, 0x01, 0x00);
+ msleep(20);
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_CDC_RX1_B6_CTL, 0x01, 0x01);
+ } else if (w->shift == 4) {
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_CDC_RX2_B6_CTL, 0x01, 0x01);
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_CDC_RX2_B6_CTL, 0x01, 0x00);
+ msleep(20);
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_CDC_RX2_B6_CTL, 0x01, 0x01);
+ }
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ usleep_range(4000, 4100);
+ /* Let MBHC module know PA turned off
+ wcd9xxx_resmgr_notifier_call(&msm8x16_wcd->resmgr,
+ e_post_off); */
+
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_ANALOG_NCP_EN, 0x11, 0x10);
+ usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS);
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL, 0x40, 0x40);
+ dev_dbg(codec->dev,
+ "%s: sleep 10 ms after %s PA disable.\n", __func__,
+ w->name);
+ usleep_range(10000, 10100);
+ break;
+ }
+ return 0;
+}
+
+static const struct snd_soc_dapm_route audio_map[] = {
+ {"RX_I2S_CLK", NULL, "CDC_CONN"},
+ {"I2S RX1", NULL, "RX_I2S_CLK"},
+ {"I2S RX2", NULL, "RX_I2S_CLK"},
+ {"I2S RX3", NULL, "RX_I2S_CLK"},
+
+ {"I2S TX1", NULL, "TX_I2S_CLK"},
+ {"I2S TX2", NULL, "TX_I2S_CLK"},
+
+ {"I2S TX1", NULL, "DEC1 MUX"},
+ {"I2S TX2", NULL, "DEC2 MUX"},
+
+ /* RDAC Connections */
+ {"HPHR DAC", NULL, "RDAC2 MUX"},
+ {"RDAC2 MUX", "RX1", "RX1 CHAIN"},
+ {"RDAC2 MUX", "RX2", "RX2 CHAIN"},
+
+ /* Earpiece (RX MIX1) */
+ {"EAR", NULL, "EAR_S"},
+ {"EAR_S", "Switch", "EAR PA"},
+ {"EAR PA", NULL, "RX_BIAS"},
+ {"EAR PA", NULL, "HPHL DAC"},
+ {"EAR PA", NULL, "HPHR DAC"},
+
+ /* Headset (RX MIX1 and RX MIX2) */
+ {"HEADPHONE", NULL, "HPHL PA"},
+ {"HEADPHONE", NULL, "HPHR PA"},
+
+ {"HPHL PA", NULL, "HPHL"},
+ {"HPHR PA", NULL, "HPHR"},
+ {"HPHL", "Switch", "HPHL DAC"},
+ {"HPHR", "Switch", "HPHR DAC"},
+ {"HPHL PA", NULL, "CP"},
+ {"HPHL PA", NULL, "RX_BIAS"},
+ {"HPHR PA", NULL, "CP"},
+ {"HPHR PA", NULL, "RX_BIAS"},
+ {"HPHL DAC", NULL, "RX1 CHAIN"},
+
+ {"SPK_OUT", NULL, "SPK PA"},
+ {"SPK PA", NULL, "RX_BIAS"},
+ {"SPK PA", NULL, "SPK DAC"},
+ {"SPK DAC", "Switch", "RX3 CHAIN"},
+
+ {"RX1 CHAIN", NULL, "RX1 CLK"},
+ {"RX2 CHAIN", NULL, "RX2 CLK"},
+ {"RX3 CHAIN", NULL, "RX3 CLK"},
+ {"RX1 CHAIN", NULL, "RX1 MIX2"},
+ {"RX2 CHAIN", NULL, "RX2 MIX2"},
+ {"RX1 CHAIN", NULL, "RX1 MIX1"},
+ {"RX2 CHAIN", NULL, "RX2 MIX1"},
+ {"RX3 CHAIN", NULL, "RX3 MIX1"},
+
+ {"RX1 MIX1", NULL, "RX1 MIX1 INP1"},
+ {"RX1 MIX1", NULL, "RX1 MIX1 INP2"},
+ {"RX1 MIX1", NULL, "RX1 MIX1 INP3"},
+ {"RX2 MIX1", NULL, "RX2 MIX1 INP1"},
+ {"RX2 MIX1", NULL, "RX2 MIX1 INP2"},
+ {"RX3 MIX1", NULL, "RX3 MIX1 INP1"},
+ {"RX3 MIX1", NULL, "RX3 MIX1 INP2"},
+ {"RX1 MIX2", NULL, "RX1 MIX2 INP1"},
+ {"RX2 MIX2", NULL, "RX2 MIX2 INP1"},
+
+ {"RX1 MIX1 INP1", "RX1", "I2S RX1"},
+ {"RX1 MIX1 INP1", "RX2", "I2S RX2"},
+ {"RX1 MIX1 INP1", "RX3", "I2S RX3"},
+ {"RX1 MIX1 INP1", "IIR1", "IIR1"},
+ {"RX1 MIX1 INP2", "RX1", "I2S RX1"},
+ {"RX1 MIX1 INP2", "RX2", "I2S RX2"},
+ {"RX1 MIX1 INP2", "RX3", "I2S RX3"},
+ {"RX1 MIX1 INP2", "IIR1", "IIR1"},
+ {"RX1 MIX1 INP3", "RX1", "I2S RX1"},
+ {"RX1 MIX1 INP3", "RX2", "I2S RX2"},
+ {"RX1 MIX1 INP3", "RX3", "I2S RX3"},
+
+ {"RX2 MIX1 INP1", "RX1", "I2S RX1"},
+ {"RX2 MIX1 INP1", "RX2", "I2S RX2"},
+ {"RX2 MIX1 INP1", "RX3", "I2S RX3"},
+ {"RX2 MIX1 INP1", "IIR1", "IIR1"},
+ {"RX2 MIX1 INP2", "RX1", "I2S RX1"},
+ {"RX2 MIX1 INP2", "RX2", "I2S RX2"},
+ {"RX2 MIX1 INP2", "RX3", "I2S RX3"},
+ {"RX2 MIX1 INP2", "IIR1", "IIR1"},
+
+ {"RX3 MIX1 INP1", "RX1", "I2S RX1"},
+ {"RX3 MIX1 INP1", "RX2", "I2S RX2"},
+ {"RX3 MIX1 INP1", "RX3", "I2S RX3"},
+ {"RX3 MIX1 INP1", "IIR1", "IIR1"},
+ {"RX3 MIX1 INP2", "RX1", "I2S RX1"},
+ {"RX3 MIX1 INP2", "RX2", "I2S RX2"},
+ {"RX3 MIX1 INP2", "RX3", "I2S RX3"},
+ {"RX3 MIX1 INP2", "IIR1", "IIR1"},
+
+ {"RX1 MIX2 INP1", "IIR1", "IIR1"},
+ {"RX2 MIX2 INP1", "IIR1", "IIR1"},
+
+ /* Decimator Inputs */
+ {"DEC1 MUX", "DMIC1", "DMIC1"},
+ {"DEC1 MUX", "DMIC2", "DMIC2"},
+ {"DEC1 MUX", "ADC1", "ADC1"},
+ {"DEC1 MUX", "ADC2", "ADC2"},
+ {"DEC1 MUX", "ADC3", "ADC3"},
+ {"DEC1 MUX", NULL, "CDC_CONN"},
+
+ {"DEC2 MUX", "DMIC1", "DMIC1"},
+ {"DEC2 MUX", "DMIC2", "DMIC2"},
+ {"DEC2 MUX", "ADC1", "ADC1"},
+ {"DEC2 MUX", "ADC2", "ADC2"},
+ {"DEC2 MUX", "ADC3", "ADC3"},
+ {"DEC2 MUX", NULL, "CDC_CONN"},
+
+ /* ADC Connections */
+ {"ADC2", NULL, "ADC2 MUX"},
+ {"ADC3", NULL, "ADC2 MUX"},
+ {"ADC2 MUX", "INP2", "ADC2_INP2"},
+ {"ADC2 MUX", "INP3", "ADC2_INP3"},
+
+ {"ADC1", NULL, "AMIC1"},
+ {"ADC2_INP2", NULL, "AMIC2"},
+ {"ADC2_INP3", NULL, "AMIC3"},
+
+ /* TODO: Fix this */
+ {"IIR1", NULL, "IIR1 INP1 MUX"},
+ {"IIR1 INP1 MUX", "DEC1", "DEC1 MUX"},
+ {"IIR1 INP1 MUX", "DEC2", "DEC2 MUX"},
+ {"MIC BIAS Internal1", NULL, "INT_LDO_H"},
+ {"MIC BIAS Internal2", NULL, "INT_LDO_H"},
+ {"MIC BIAS External", NULL, "INT_LDO_H"},
+ {"MIC BIAS Internal1", NULL, "MICBIAS_REGULATOR"},
+ {"MIC BIAS Internal2", NULL, "MICBIAS_REGULATOR"},
+ {"MIC BIAS External", NULL, "MICBIAS_REGULATOR"},
+};
+
+static int msm8x16_wcd_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ dev_dbg(dai->codec->dev, "%s(): substream = %s stream = %d\n",
+ __func__,
+ substream->name, substream->stream);
+ return 0;
+}
+
+static void msm8x16_wcd_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ dev_dbg(dai->codec->dev,
+ "%s(): substream = %s stream = %d\n" , __func__,
+ substream->name, substream->stream);
+}
+
+static int msm8x16_wcd_codec_enable_clock_block(struct snd_soc_codec *codec,
+ int enable)
+{
+ if (enable) {
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_ANALOG_MASTER_BIAS_CTL, 0x30, 0x30);
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_CDC_CLK_MCLK_CTL, 0x01, 0x01);
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_CDC_CLK_PDM_CTL, 0x03, 0x03);
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_DIGITAL_CDC_RST_CTL, 0x80, 0x80);
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_DIGITAL_CDC_TOP_CLK_CTL, 0x0C, 0x0C);
+ } else {
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_DIGITAL_CDC_TOP_CLK_CTL, 0x0C, 0x00);
+ snd_soc_update_bits(codec, MSM8X16_WCD_A_CDC_CLK_PDM_CTL,
+ 0x03, 0x00);
+ }
+ return 0;
+}
+
+int msm8x16_wcd_mclk_enable(struct snd_soc_codec *codec,
+ int mclk_enable, bool dapm)
+{
+ struct msm8x16_wcd_priv *msm8x16_wcd = snd_soc_codec_get_drvdata(codec);
+
+ dev_dbg(codec->dev, "%s: mclk_enable = %u, dapm = %d\n",
+ __func__, mclk_enable, dapm);
+ if (mclk_enable) {
+ msm8x16_wcd->mclk_enabled = true;
+ msm8x16_wcd_codec_enable_clock_block(codec, 1);
+ } else {
+ if (!msm8x16_wcd->mclk_enabled) {
+ dev_err(codec->dev, "Error, MCLK already diabled\n");
+ return -EINVAL;
+ }
+ msm8x16_wcd->mclk_enabled = false;
+ msm8x16_wcd_codec_enable_clock_block(codec, 0);
+ }
+ return 0;
+}
+
+static int msm8x16_wcd_set_dai_sysclk(struct snd_soc_dai *dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ dev_dbg(dai->codec->dev, "%s\n", __func__);
+ return 0;
+}
+
+static int msm8x16_wcd_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+ dev_dbg(dai->codec->dev, "%s\n", __func__);
+ return 0;
+}
+
+static int msm8x16_wcd_set_channel_map(struct snd_soc_dai *dai,
+ unsigned int tx_num, unsigned int *tx_slot,
+ unsigned int rx_num, unsigned int *rx_slot)
+
+{
+ dev_dbg(dai->codec->dev, "%s\n", __func__);
+ return 0;
+}
+
+static int msm8x16_wcd_get_channel_map(struct snd_soc_dai *dai,
+ unsigned int *tx_num, unsigned int *tx_slot,
+ unsigned int *rx_num, unsigned int *rx_slot)
+
+{
+ dev_dbg(dai->codec->dev, "%s\n", __func__);
+ return 0;
+}
+
+static int msm8x16_wcd_set_interpolator_rate(struct snd_soc_dai *dai,
+ u8 rx_fs_rate_reg_val, u32 sample_rate)
+{
+ return 0;
+}
+
+static int msm8x16_wcd_set_decimator_rate(struct snd_soc_dai *dai,
+ u8 tx_fs_rate_reg_val, u32 sample_rate)
+{
+ return 0;
+}
+
+static int msm8x16_wcd_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ u8 tx_fs_rate, rx_fs_rate;
+ int ret;
+
+ dev_dbg(dai->codec->dev,
+ "%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
+ dai->name, dai->id, params_rate(params),
+ params_channels(params));
+
+ switch (params_rate(params)) {
+ case 8000:
+ tx_fs_rate = 0x00;
+ rx_fs_rate = 0x00;
+ break;
+ case 16000:
+ tx_fs_rate = 0x01;
+ rx_fs_rate = 0x20;
+ break;
+ case 32000:
+ tx_fs_rate = 0x02;
+ rx_fs_rate = 0x40;
+ break;
+ case 48000:
+ tx_fs_rate = 0x03;
+ rx_fs_rate = 0x60;
+ break;
+ case 96000:
+ tx_fs_rate = 0x04;
+ rx_fs_rate = 0x80;
+ break;
+ case 192000:
+ tx_fs_rate = 0x05;
+ rx_fs_rate = 0xA0;
+ break;
+ default:
+ dev_err(dai->codec->dev,
+ "%s: Invalid sampling rate %d\n", __func__,
+ params_rate(params));
+ return -EINVAL;
+ }
+
+ switch (substream->stream) {
+ case SNDRV_PCM_STREAM_CAPTURE:
+ ret = msm8x16_wcd_set_decimator_rate(dai, tx_fs_rate,
+ params_rate(params));
+ if (ret < 0) {
+ dev_err(dai->codec->dev,
+ "%s: set decimator rate failed %d\n", __func__,
+ ret);
+ return ret;
+ }
+ break;
+ case SNDRV_PCM_STREAM_PLAYBACK:
+ ret = msm8x16_wcd_set_interpolator_rate(dai, rx_fs_rate,
+ params_rate(params));
+ if (ret < 0) {
+ dev_err(dai->codec->dev,
+ "%s: set decimator rate failed %d\n", __func__,
+ ret);
+ return ret;
+ }
+ break;
+ default:
+ dev_err(dai->codec->dev,
+ "%s: Invalid stream type %d\n", __func__,
+ substream->stream);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct snd_soc_dai_ops msm8x16_wcd_dai_ops = {
+ .startup = msm8x16_wcd_startup,
+ .shutdown = msm8x16_wcd_shutdown,
+ .hw_params = msm8x16_wcd_hw_params,
+ .set_sysclk = msm8x16_wcd_set_dai_sysclk,
+ .set_fmt = msm8x16_wcd_set_dai_fmt,
+ .set_channel_map = msm8x16_wcd_set_channel_map,
+ .get_channel_map = msm8x16_wcd_get_channel_map,
+};
+
+static struct snd_soc_dai_driver msm8x16_wcd_i2s_dai[] = {
+ {
+ .name = "msm8x16_wcd_i2s_rx1",
+ .id = AIF1_PB,
+ .playback = {
+ .stream_name = "AIF1 Playback",
+ .rates = MSM8X16_WCD_RATES,
+ .formats = MSM8X16_WCD_FORMATS,
+ .rate_max = 192000,
+ .rate_min = 8000,
+ .channels_min = 1,
+ .channels_max = 3,
+ },
+ .ops = &msm8x16_wcd_dai_ops,
+ },
+ {
+ .name = "msm8x16_wcd_i2s_tx1",
+ .id = AIF1_CAP,
+ .capture = {
+ .stream_name = "AIF1 Capture",
+ .rates = MSM8X16_WCD_RATES,
+ .formats = MSM8X16_WCD_FORMATS,
+ .rate_max = 192000,
+ .rate_min = 8000,
+ .channels_min = 1,
+ .channels_max = 4,
+ },
+ .ops = &msm8x16_wcd_dai_ops,
+ },
+};
+
+static int msm8x16_wcd_codec_enable_rx_chain(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ dev_dbg(w->codec->dev,
+ "%s: PMU:Sleeping 20ms after disabling mute\n",
+ __func__);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ dev_dbg(w->codec->dev,
+ "%s: PMD:Sleeping 20ms after disabling mute\n",
+ __func__);
+ snd_soc_update_bits(codec, w->reg,
+ 1 << w->shift, 0x00);
+ msleep(20);
+ break;
+ }
+ return 0;
+}
+
+static int msm8x16_wcd_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ dev_dbg(w->codec->dev,
+ "%s: Sleeping 20ms after select EAR PA\n",
+ __func__);
+ snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_RX_EAR_CTL,
+ 0x80, 0x80);
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ dev_dbg(w->codec->dev,
+ "%s: Sleeping 20ms after enabling EAR PA\n",
+ __func__);
+ snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_RX_EAR_CTL,
+ 0x40, 0x40);
+ usleep_range(7000, 7100);
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_CDC_RX1_B6_CTL, 0x01, 0x00);
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_CDC_RX1_B6_CTL, 0x01, 0x01);
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_CDC_RX1_B6_CTL, 0x01, 0x00);
+ msleep(20);
+ snd_soc_update_bits(codec,
+ MSM8X16_WCD_A_CDC_RX1_B6_CTL, 0x01, 0x01);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ dev_dbg(w->codec->dev,
+ "%s: Sleeping 20ms after disabling EAR PA\n",
+ __func__);
+ snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_RX_EAR_CTL,
+ 0xC0, 0x00);
+ usleep_range(7000, 7100);
+ break;
+ }
+ return 0;
+}
+
+static const struct snd_soc_dapm_widget msm8x16_wcd_dapm_widgets[] = {
+ /*RX stuff */
+ SND_SOC_DAPM_OUTPUT("EAR"),
+
+ SND_SOC_DAPM_PGA_E("EAR PA", MSM8X16_WCD_A_ANALOG_RX_EAR_CTL,
+ 7, 0, NULL, 0, msm8x16_wcd_codec_enable_ear_pa,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MIXER("EAR_S", SND_SOC_NOPM, 0, 0,
+ ear_pa_switch, ARRAY_SIZE(ear_pa_switch)),
+
+ SND_SOC_DAPM_AIF_IN("I2S RX1", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
+
+ SND_SOC_DAPM_AIF_IN("I2S RX2", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
+
+ SND_SOC_DAPM_AIF_IN("I2S RX3", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
+
+ SND_SOC_DAPM_SUPPLY("INT_LDO_H", SND_SOC_NOPM, 1, 0, NULL, 0),
+
+ SND_SOC_DAPM_OUTPUT("HEADPHONE"),
+ SND_SOC_DAPM_PGA_E("HPHL PA", MSM8X16_WCD_A_ANALOG_RX_HPH_CNP_EN,
+ 5, 0, NULL, 0,
+ msm8x16_wcd_hph_pa_event, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD |
+ SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MIXER("HPHL", SND_SOC_NOPM, 0, 0,
+ hphl_switch, ARRAY_SIZE(hphl_switch)),
+
+ SND_SOC_DAPM_MIXER_E("HPHL DAC",
+ MSM8X16_WCD_A_ANALOG_RX_HPH_L_PA_DAC_CTL, 3, 0, NULL,
+ 0, msm8x16_wcd_hphl_dac_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_PGA_E("HPHR PA", MSM8X16_WCD_A_ANALOG_RX_HPH_CNP_EN,
+ 4, 0, NULL, 0,
+ msm8x16_wcd_hph_pa_event, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD |
+ SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MIXER("HPHR", SND_SOC_NOPM, 0, 0,
+ hphr_switch, ARRAY_SIZE(hphr_switch)),
+
+ SND_SOC_DAPM_MIXER_E("HPHR DAC",
+ MSM8X16_WCD_A_ANALOG_RX_HPH_R_PA_DAC_CTL, 3, 0, NULL,
+ 0, msm8x16_wcd_hphr_dac_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MIXER("SPK DAC", SND_SOC_NOPM, 0, 0,
+ spkr_switch, ARRAY_SIZE(spkr_switch)),
+
+ /* Speaker */
+ SND_SOC_DAPM_OUTPUT("SPK_OUT"),
+
+ SND_SOC_DAPM_PGA_E("SPK PA", MSM8X16_WCD_A_ANALOG_SPKR_DRV_CTL,
+ 7, 0 , NULL, 0, msm8x16_wcd_codec_enable_spk_pa,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MIXER_E("RX1 MIX1",
+ MSM8X16_WCD_A_CDC_CLK_RX_B1_CTL, 0, 0, NULL, 0,
+ msm8x16_wcd_codec_enable_interpolator,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MIXER_E("RX2 MIX1",
+ MSM8X16_WCD_A_CDC_CLK_RX_B1_CTL, 1, 0, NULL, 0,
+ msm8x16_wcd_codec_enable_interpolator,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MIXER_E("RX1 MIX2",
+ MSM8X16_WCD_A_CDC_CLK_RX_B1_CTL, 0, 0, NULL,
+ 0, msm8x16_wcd_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MIXER_E("RX2 MIX2",
+ MSM8X16_WCD_A_CDC_CLK_RX_B1_CTL, 1, 0, NULL,
+ 0, msm8x16_wcd_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MIXER_E("RX3 MIX1",
+ MSM8X16_WCD_A_CDC_CLK_RX_B1_CTL, 2, 0, NULL,
+ 0, msm8x16_wcd_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_SUPPLY("RX1 CLK", MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL,
+ 0, 0, msm8x16_wcd_codec_enable_dig_clk, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_SUPPLY("RX2 CLK", MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL,
+ 1, 0, msm8x16_wcd_codec_enable_dig_clk, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_SUPPLY("RX3 CLK", MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL,
+ 2, 0, msm8x16_wcd_codec_enable_dig_clk, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MIXER_E("RX1 CHAIN", MSM8X16_WCD_A_CDC_RX1_B6_CTL, 0, 0,
+ NULL, 0,
+ msm8x16_wcd_codec_enable_rx_chain,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MIXER_E("RX2 CHAIN", MSM8X16_WCD_A_CDC_RX2_B6_CTL, 0, 0,
+ NULL, 0,
+ msm8x16_wcd_codec_enable_rx_chain,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MIXER_E("RX3 CHAIN", MSM8X16_WCD_A_CDC_RX3_B6_CTL, 0, 0,
+ NULL, 0,
+ msm8x16_wcd_codec_enable_rx_chain,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX("RX1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
+ &rx_mix1_inp1_mux),
+ SND_SOC_DAPM_MUX("RX1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
+ &rx_mix1_inp2_mux),
+ SND_SOC_DAPM_MUX("RX1 MIX1 INP3", SND_SOC_NOPM, 0, 0,
+ &rx_mix1_inp3_mux),
+
+ SND_SOC_DAPM_MUX("RX2 MIX1 INP1", SND_SOC_NOPM, 0, 0,
+ &rx2_mix1_inp1_mux),
+ SND_SOC_DAPM_MUX("RX2 MIX1 INP2", SND_SOC_NOPM, 0, 0,
+ &rx2_mix1_inp2_mux),
+ SND_SOC_DAPM_MUX("RX2 MIX1 INP3", SND_SOC_NOPM, 0, 0,
+ &rx2_mix1_inp3_mux),
+
+ SND_SOC_DAPM_MUX("RX3 MIX1 INP1", SND_SOC_NOPM, 0, 0,
+ &rx3_mix1_inp1_mux),
+ SND_SOC_DAPM_MUX("RX3 MIX1 INP2", SND_SOC_NOPM, 0, 0,
+ &rx3_mix1_inp2_mux),
+ SND_SOC_DAPM_MUX("RX3 MIX1 INP3", SND_SOC_NOPM, 0, 0,
+ &rx3_mix1_inp3_mux),
+
+ SND_SOC_DAPM_MUX("RX1 MIX2 INP1", SND_SOC_NOPM, 0, 0,
+ &rx1_mix2_inp1_mux),
+ SND_SOC_DAPM_MUX("RX2 MIX2 INP1", SND_SOC_NOPM, 0, 0,
+ &rx2_mix2_inp1_mux),
+
+ SND_SOC_DAPM_SUPPLY("MICBIAS_REGULATOR", SND_SOC_NOPM,
+ ON_DEMAND_MICBIAS, 0,
+ msm8x16_wcd_codec_enable_on_demand_supply,
+ SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_SUPPLY("CP", MSM8X16_WCD_A_ANALOG_NCP_EN, 0, 0,
+ msm8x16_wcd_codec_enable_charge_pump, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_SUPPLY("RX_BIAS", MSM8X16_WCD_A_ANALOG_RX_COM_BIAS_DAC,
+ 0, 0,
+ msm8x16_wcd_codec_enable_rx_bias, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ /* TX */
+
+ SND_SOC_DAPM_SUPPLY("CDC_CONN", MSM8X16_WCD_A_CDC_CLK_OTHR_CTL,
+ 2, 0, NULL, 0),
+
+
+ SND_SOC_DAPM_INPUT("AMIC1"),
+ SND_SOC_DAPM_MICBIAS_E("MIC BIAS Internal1",
+ MSM8X16_WCD_A_ANALOG_MICB_1_EN, 7, 0,
+ msm8x16_wcd_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MICBIAS_E("MIC BIAS Internal2",
+ MSM8X16_WCD_A_ANALOG_MICB_1_EN, 7, 0,
+ msm8x16_wcd_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MICBIAS_E("MIC BIAS Internal3",
+ MSM8X16_WCD_A_ANALOG_MICB_1_EN, 7, 0,
+ msm8x16_wcd_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_ADC_E("ADC1", NULL, MSM8X16_WCD_A_ANALOG_TX_1_EN, 7, 0,
+ msm8x16_wcd_codec_enable_adc, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_ADC_E("ADC2_INP2",
+ NULL, MSM8X16_WCD_A_ANALOG_TX_2_EN, 7, 0,
+ msm8x16_wcd_codec_enable_adc, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_ADC_E("ADC2_INP3",
+ NULL, MSM8X16_WCD_A_ANALOG_TX_3_EN, 7, 0,
+ msm8x16_wcd_codec_enable_adc, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MIXER("ADC2", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("ADC3", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_MUX("ADC2 MUX", SND_SOC_NOPM, 0, 0,
+ &tx_adc2_mux),
+
+ SND_SOC_DAPM_MICBIAS("MIC BIAS External",
+ MSM8X16_WCD_A_ANALOG_MICB_1_EN, 7, 0),
+
+ SND_SOC_DAPM_INPUT("AMIC3"),
+
+ SND_SOC_DAPM_MUX_E("DEC1 MUX",
+ MSM8X16_WCD_A_CDC_CLK_TX_CLK_EN_B1_CTL, 0, 0,
+ &dec1_mux, msm8x16_wcd_codec_enable_dec,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX_E("DEC2 MUX",
+ MSM8X16_WCD_A_CDC_CLK_TX_CLK_EN_B1_CTL, 1, 0,
+ &dec2_mux, msm8x16_wcd_codec_enable_dec,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX("RDAC2 MUX", SND_SOC_NOPM, 0, 0, &rdac2_mux),
+
+ SND_SOC_DAPM_INPUT("AMIC2"),
+
+ SND_SOC_DAPM_AIF_OUT("I2S TX1", "AIF1 Capture", 0, SND_SOC_NOPM,
+ 0, 0),
+ SND_SOC_DAPM_AIF_OUT("I2S TX2", "AIF1 Capture", 0, SND_SOC_NOPM,
+ 0, 0),
+ SND_SOC_DAPM_AIF_OUT("I2S TX3", "AIF1 Capture", 0, SND_SOC_NOPM,
+ 0, 0),
+
+ /* Digital Mic Inputs */
+ SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0,
+ msm8x16_wcd_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 0,
+ msm8x16_wcd_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ /* Sidetone */
+ SND_SOC_DAPM_MUX("IIR1 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp1_mux),
+ SND_SOC_DAPM_PGA("IIR1",
+ MSM8X16_WCD_A_CDC_CLK_SD_CTL, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_SUPPLY("RX_I2S_CLK",
+ MSM8X16_WCD_A_CDC_CLK_RX_I2S_CTL, 4, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("TX_I2S_CLK",
+ MSM8X16_WCD_A_CDC_CLK_TX_I2S_CTL, 4, 0, NULL, 0),
+};
+
+static const struct msm8x16_wcd_reg_mask_val msm8x16_wcd_reg_defaults[] = {
+ /*
+ MSM8X16_WCD_REG_VAL(MSM8X16_WCD_A_ANALOG_RX_EAR_CTL, 0x05),
+ MSM8X16_WCD_REG_VAL(MSM8X16_WCD_A_CDC_RX1_B5_CTL, 0x78),
+ MSM8X16_WCD_REG_VAL(MSM8X16_WCD_A_CDC_RX2_B5_CTL, 0x78),
+ MSM8X16_WCD_REG_VAL(MSM8X16_WCD_A_CDC_RX3_B5_CTL, 0x78),
+ MSM8X16_WCD_REG_VAL(MSM8X16_WCD_A_CDC_RX1_B6_CTL, 0xA0),
+ MSM8X16_WCD_REG_VAL(MSM8X16_WCD_A_CDC_RX2_B6_CTL, 0xA0),
+ MSM8X16_WCD_REG_VAL(MSM8X16_WCD_A_CDC_RX3_B6_CTL, 0x80),
+ MSM8X16_WCD_REG_VAL(MSM8X16_WCD_A_ANALOG_RX_HPH_BIAS_PA, 0x7A),
+ MSM8X16_WCD_REG_VAL(MSM8X16_WCD_A_RX_EAR_BIAS_PA, 0x76),
+ MSM8X16_WCD_REG_VAL(MSM8X16_WCD_A_BIAS_CURR_CTL_2, 0x04),
+ MSM8X16_WCD_REG_VAL(MSM8X16_WCD_A_MICB_CFILT_1_VAL, 0x60),
+ MSM8X16_WCD_REG_VAL(MSM8X16_WCD_A_ANALOG_MICB_1_EN, 0x83),
+ MSM8X16_WCD_REG_VAL(MSM8X16_WCD_A_ANALOG_TX_1_EN, 0x32),
+ MSM8X16_WCD_REG_VAL(MSM8X16_WCD_A_ANALOG_TX_2_EN, 0x32),
+ MSM8X16_WCD_REG_VAL(MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL, 0x10),
+ */
+};
+
+static void msm8x16_wcd_update_reg_defaults(struct snd_soc_codec *codec)
+{
+ u32 i;
+
+ for (i = 0; i < ARRAY_SIZE(msm8x16_wcd_reg_defaults); i++)
+ snd_soc_write(codec, msm8x16_wcd_reg_defaults[i].reg,
+ msm8x16_wcd_reg_defaults[i].val);
+}
+
+static const struct msm8x16_wcd_reg_mask_val
+ msm8x16_wcd_codec_reg_init_val[] = {
+/*
+ * Initialize current threshold to 350MA
+ * number of wait and run cycles to 4096
+ *
+ {MSM8X16_WCD_A_ANALOG_RX_COM_OCP_CTL, 0xE1, 0x61},
+ {MSM8X16_WCD_A_ANALOG_RX_COM_OCP_COUNT, 0xFF, 0xFF},
+
+ * Initialize gain registers to use register gain *
+
+ *enable HPF filter for TX paths *
+ {MSM8X16_WCD_A_CDC_TX1_MUX_CTL, 0x8, 0x0},
+ {MSM8X16_WCD_A_CDC_TX2_MUX_CTL, 0x8, 0x0},
+
+ * config Decimator for DMIC CLK_MODE_1(3.2Mhz@9.6Mhz mclk) *
+ {MSM8X16_WCD_A_CDC_TX1_DMIC_CTL, 0x7, 0x1},
+ {MSM8X16_WCD_A_CDC_TX2_DMIC_CTL, 0x7, 0x1},
+
+ * config DMIC clk to CLK_MODE_1 (3.2Mhz@9.6Mhz mclk) *
+ {MSM8X16_WCD_A_CDC_CLK_DMIC_B1_CTL, 0xEE, 0x22},
+
+ * Disable REF_EN for MSM8X16_WCD_A_ANALOG_SPKR_DAC_CTL *
+ {MSM8X16_WCD_A_ANALOG_SPKR_DAC_CTL, 0x04, 0x00},
+*/
+};
+
+static void msm8x16_wcd_codec_init_reg(struct snd_soc_codec *codec)
+{
+ u32 i;
+
+ for (i = 0; i < ARRAY_SIZE(msm8x16_wcd_codec_reg_init_val); i++)
+ snd_soc_update_bits(codec,
+ msm8x16_wcd_codec_reg_init_val[i].reg,
+ msm8x16_wcd_codec_reg_init_val[i].mask,
+ msm8x16_wcd_codec_reg_init_val[i].val);
+}
+
+static int msm8x16_wcd_bringup(struct snd_soc_codec *codec)
+{
+ snd_soc_write(codec, MSM8X16_WCD_A_DIGITAL_PERPH_RESET_CTL4, 0x01);
+ snd_soc_write(codec, MSM8X16_WCD_A_ANALOG_PERPH_RESET_CTL4, 0x01);
+ return 0;
+}
+
+static struct regulator *wcd8x16_wcd_codec_find_regulator(
+ const struct msm8x16_wcd *msm8x16,
+ const char *name)
+{
+ int i;
+
+ for (i = 0; i < msm8x16->num_of_supplies; i++) {
+ if (msm8x16->supplies[i].supply &&
+ !strcmp(msm8x16->supplies[i].supply, name))
+ return msm8x16->supplies[i].consumer;
+ }
+
+ dev_err(msm8x16->dev, "Error: regulator not found\n");
+ return NULL;
+}
+static int msm8x16_wcd_device_down(struct snd_soc_codec *codec)
+{
+ dev_dbg(codec->dev, "%s: device down!\n", __func__);
+
+ msm8x16_wcd_write(codec, MSM8X16_WCD_A_DIGITAL_PERPH_RESET_CTL4, 0x1);
+ msm8x16_wcd_write(codec, MSM8X16_WCD_A_ANALOG_PERPH_RESET_CTL4, 0x1);
+ snd_soc_card_change_online_state(codec->card, 0);
+ return 0;
+}
+
+static int msm8x16_wcd_device_up(struct snd_soc_codec *codec)
+{
+ dev_dbg(codec->dev, "%s: device up!\n", __func__);
+
+ snd_soc_card_change_online_state(codec->card, 1);
+ /* delay is required to make sure sound card state updated */
+ usleep_range(5000, 5100);
+
+ mutex_lock(&codec->mutex);
+
+ msm8x16_wcd_bringup(codec);
+ msm8x16_wcd_codec_init_reg(codec);
+ msm8x16_wcd_update_reg_defaults(codec);
+
+ mutex_unlock(&codec->mutex);
+
+ return 0;
+}
+
+static int modem_state_callback(struct notifier_block *nb, unsigned long value,
+ void *priv)
+{
+ bool timedout;
+ unsigned long timeout;
+ static bool booted_once;
+
+ if (value == SUBSYS_BEFORE_SHUTDOWN)
+ msm8x16_wcd_device_down(registered_codec);
+ else if (value == SUBSYS_AFTER_POWERUP) {
+
+ if (!booted_once) {
+ booted_once = true;
+ return NOTIFY_OK;
+ }
+ dev_dbg(registered_codec->dev,
+ "ADSP is about to power up. bring up codec\n");
+
+ timeout = jiffies +
+ msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS);
+ while (!(timedout = time_after(jiffies, timeout))) {
+ if (!q6core_is_adsp_ready()) {
+ dev_dbg(registered_codec->dev,
+ "ADSP isn't ready\n");
+ } else {
+ dev_dbg(registered_codec->dev,
+ "ADSP is ready\n");
+ msm8x16_wcd_device_up(registered_codec);
+ break;
+ }
+ }
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block modem_state_notifier_block = {
+ .notifier_call = modem_state_callback,
+ .priority = -INT_MAX,
+};
+
+static int msm8x16_wcd_codec_probe(struct snd_soc_codec *codec)
+{
+ struct msm8x16_wcd_priv *msm8x16_wcd_priv;
+ struct msm8x16_wcd *msm8x16_wcd;
+ int i;
+
+ dev_dbg(codec->dev, "%s()\n", __func__);
+
+ msm8x16_wcd_priv = kzalloc(sizeof(struct msm8x16_wcd_priv), GFP_KERNEL);
+ if (!msm8x16_wcd_priv) {
+ dev_err(codec->dev, "Failed to allocate private data\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < NUM_DECIMATORS; i++) {
+ tx_hpf_work[i].msm8x16_wcd = msm8x16_wcd_priv;
+ tx_hpf_work[i].decimator = i + 1;
+ INIT_DELAYED_WORK(&tx_hpf_work[i].dwork,
+ tx_hpf_corner_freq_callback);
+ }
+
+ codec->control_data = dev_get_drvdata(codec->dev);
+ snd_soc_codec_set_drvdata(codec, msm8x16_wcd_priv);
+ msm8x16_wcd_priv->codec = codec;
+
+ /* codec resmgr module init */
+ msm8x16_wcd = codec->control_data;
+
+ msm8x16_wcd_bringup(codec);
+ msm8x16_wcd_codec_init_reg(codec);
+ msm8x16_wcd_update_reg_defaults(codec);
+
+ wcd9xxx_spmi_set_codec(codec);
+
+ msm8x16_wcd_priv->on_demand_list[ON_DEMAND_MICBIAS].supply =
+ wcd8x16_wcd_codec_find_regulator(
+ codec->control_data,
+ on_demand_supply_name[ON_DEMAND_MICBIAS]);
+ atomic_set(&msm8x16_wcd_priv->on_demand_list[ON_DEMAND_MICBIAS].ref, 0);
+
+ msm8x16_wcd_priv->mclk_enabled = false;
+ msm8x16_wcd_priv->clock_active = false;
+ msm8x16_wcd_priv->config_mode_active = false;
+
+ registered_codec = codec;
+ modem_state_notifier =
+ subsys_notif_register_notifier("modem",
+ &modem_state_notifier_block);
+ if (!modem_state_notifier) {
+ dev_err(codec->dev, "Failed to register modem state notifier\n"
+ );
+ registered_codec = NULL;
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+static int msm8x16_wcd_codec_remove(struct snd_soc_codec *codec)
+{
+ struct msm8x16_wcd_priv *msm8x16_wcd = snd_soc_codec_get_drvdata(codec);
+
+ msm8x16_wcd->on_demand_list[ON_DEMAND_MICBIAS].supply = NULL;
+ atomic_set(&msm8x16_wcd->on_demand_list[ON_DEMAND_MICBIAS].ref, 0);
+
+ return 0;
+}
+
+static struct snd_soc_codec_driver soc_codec_dev_msm8x16_wcd = {
+ .probe = msm8x16_wcd_codec_probe,
+ .remove = msm8x16_wcd_codec_remove,
+
+ .read = msm8x16_wcd_read,
+ .write = msm8x16_wcd_write,
+
+ .readable_register = msm8x16_wcd_readable,
+ .volatile_register = msm8x16_wcd_volatile,
+
+ .reg_cache_size = MSM8X16_WCD_CACHE_SIZE,
+ .reg_cache_default = msm8x16_wcd_reset_reg_defaults,
+ .reg_word_size = 1,
+
+ .controls = msm8x16_wcd_snd_controls,
+ .num_controls = ARRAY_SIZE(msm8x16_wcd_snd_controls),
+ .dapm_widgets = msm8x16_wcd_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(msm8x16_wcd_dapm_widgets),
+ .dapm_routes = audio_map,
+ .num_dapm_routes = ARRAY_SIZE(audio_map),
+};
+
+static int msm8x16_wcd_init_supplies(struct msm8x16_wcd *msm8x16,
+ struct msm8x16_wcd_pdata *pdata)
+{
+ int ret;
+ int i;
+
+ msm8x16->supplies = kzalloc(sizeof(struct regulator_bulk_data) *
+ ARRAY_SIZE(pdata->regulator),
+ GFP_KERNEL);
+ if (!msm8x16->supplies) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ msm8x16->num_of_supplies = 0;
+
+ if (ARRAY_SIZE(pdata->regulator) > MAX_REGULATOR) {
+ dev_err(msm8x16->dev, "%s: Array Size out of bound\n",
+ __func__);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(pdata->regulator); i++) {
+ if (pdata->regulator[i].name) {
+ msm8x16->supplies[i].supply = pdata->regulator[i].name;
+ msm8x16->num_of_supplies++;
+ }
+ }
+
+ ret = regulator_bulk_get(msm8x16->dev, msm8x16->num_of_supplies,
+ msm8x16->supplies);
+ if (ret != 0) {
+ dev_err(msm8x16->dev, "Failed to get supplies: err = %d\n",
+ ret);
+ goto err_supplies;
+ }
+
+ for (i = 0; i < msm8x16->num_of_supplies; i++) {
+ if (regulator_count_voltages(msm8x16->supplies[i].consumer) <=
+ 0)
+ continue;
+
+ ret = regulator_set_voltage(msm8x16->supplies[i].consumer,
+ pdata->regulator[i].min_uv,
+ pdata->regulator[i].max_uv);
+ if (ret) {
+ dev_err(msm8x16->dev, "Setting regulator voltage failed for regulator %s err = %d\n",
+ msm8x16->supplies[i].supply, ret);
+ goto err_get;
+ }
+
+ ret = regulator_set_optimum_mode(msm8x16->supplies[i].consumer,
+ pdata->regulator[i].optimum_ua);
+ if (ret < 0) {
+ dev_err(msm8x16->dev, "Setting regulator optimum mode failed for regulator %s err = %d\n",
+ msm8x16->supplies[i].supply, ret);
+ goto err_get;
+ } else {
+ ret = 0;
+ }
+ }
+
+ return ret;
+
+err_get:
+ regulator_bulk_free(msm8x16->num_of_supplies, msm8x16->supplies);
+err_supplies:
+ kfree(msm8x16->supplies);
+err:
+ return ret;
+}
+
+static int msm8x16_wcd_enable_static_supplies(struct msm8x16_wcd *msm8x16,
+ struct msm8x16_wcd_pdata *pdata)
+{
+ int i;
+ int ret = 0;
+
+ for (i = 0; i < msm8x16->num_of_supplies; i++) {
+ if (pdata->regulator[i].ondemand)
+ continue;
+ ret = regulator_enable(msm8x16->supplies[i].consumer);
+ if (ret) {
+ dev_err(msm8x16->dev, "Failed to enable %s\n",
+ msm8x16->supplies[i].supply);
+ break;
+ } else {
+ dev_dbg(msm8x16->dev, "Enabled regulator %s\n",
+ msm8x16->supplies[i].supply);
+ }
+ }
+
+ while (ret && --i)
+ if (!pdata->regulator[i].ondemand)
+ regulator_disable(msm8x16->supplies[i].consumer);
+
+ return ret;
+}
+
+
+
+static void msm8x16_wcd_disable_supplies(struct msm8x16_wcd *msm8x16,
+ struct msm8x16_wcd_pdata *pdata)
+{
+ int i;
+
+ regulator_bulk_disable(msm8x16->num_of_supplies,
+ msm8x16->supplies);
+ for (i = 0; i < msm8x16->num_of_supplies; i++) {
+ if (regulator_count_voltages(msm8x16->supplies[i].consumer) <=
+ 0)
+ continue;
+ regulator_set_voltage(msm8x16->supplies[i].consumer, 0,
+ pdata->regulator[i].max_uv);
+ regulator_set_optimum_mode(msm8x16->supplies[i].consumer, 0);
+ }
+ regulator_bulk_free(msm8x16->num_of_supplies, msm8x16->supplies);
+ kfree(msm8x16->supplies);
+}
+
+static int msm8x16_wcd_clk_init(void)
+{
+ /* Div-2 */
+ iowrite32(0x3, ioremap(MSM8X16_TOMBAK_LPASS_DIGCODEC_CFG_RCGR, 4));
+ iowrite32(0x0, ioremap(MSM8X16_TOMBAK_LPASS_DIGCODEC_M, 4));
+ iowrite32(0x0, ioremap(MSM8X16_TOMBAK_LPASS_DIGCODEC_N, 4));
+ iowrite32(0x0, ioremap(MSM8X16_TOMBAK_LPASS_DIGCODEC_D, 4));
+ /* Digital codec clock enable */
+ iowrite32(0x1, ioremap(MSM8X16_TOMBAK_LPASS_DIGCODEC_CBCR, 4));
+ /* Set the update bit to make the settings go through */
+ iowrite32(0x1, ioremap(MSM8X16_TOMBAK_LPASS_DIGCODEC_CMD_RCGR, 4));
+ usleep_range(100, 200);
+ return 0;
+}
+
+static int msm8x16_wcd_device_init(struct msm8x16_wcd *msm8x16)
+{
+ mutex_init(&msm8x16->io_lock);
+ msm8x16_wcd_clk_init();
+ return 0;
+}
+
+static int msm8x16_wcd_spmi_probe(struct spmi_device *spmi)
+{
+ int ret = 0;
+ struct msm8x16_wcd *msm8x16 = NULL;
+ struct msm8x16_wcd_pdata *pdata;
+ struct resource *wcd_resource;
+ enum apr_subsys_state modem_state;
+
+ dev_dbg(&spmi->dev, "%s(%d):slave ID = 0x%x\n",
+ __func__, __LINE__, spmi->sid);
+
+ wcd_resource = spmi_get_resource(spmi, NULL, IORESOURCE_MEM, 0);
+ if (!wcd_resource) {
+ dev_err(&spmi->dev, "Unable to get Tombak base address\n");
+ return -ENXIO;
+ }
+
+ switch (wcd_resource->start) {
+ case TOMBAK_CORE_0_SPMI_ADDR:
+ msm8x16_wcd_modules[0].spmi = spmi;
+ msm8x16_wcd_modules[0].base = (spmi->sid << 16) +
+ wcd_resource->start;
+ wcd9xxx_spmi_set_dev(msm8x16_wcd_modules[0].spmi, 0);
+ break;
+ case TOMBAK_CORE_1_SPMI_ADDR:
+ msm8x16_wcd_modules[1].spmi = spmi;
+ msm8x16_wcd_modules[1].base = (spmi->sid << 16) +
+ wcd_resource->start;
+ wcd9xxx_spmi_set_dev(msm8x16_wcd_modules[1].spmi, 1);
+ if (wcd9xxx_spmi_irq_init()) {
+ dev_err(&spmi->dev,
+ "%s: irq initialization failed\n", __func__);
+ } else {
+ dev_dbg(&spmi->dev,
+ "%s: irq initialization passed\n", __func__);
+ }
+ goto rtn;
+ default:
+ ret = -EINVAL;
+ goto rtn;
+ }
+
+ /* Note we need to check Modem state */
+ modem_state = apr_get_modem_state();
+ if ((modem_state == APR_SUBSYS_DOWN) &&
+ (wcd_resource->start == TOMBAK_CORE_0_SPMI_ADDR)) {
+ dev_dbg(&spmi->dev, "defering %s, modem_state %d\n",
+ __func__, modem_state);
+ return -EPROBE_DEFER;
+ } else
+ dev_dbg(&spmi->dev, "Modem is ready\n");
+
+ dev_dbg(&spmi->dev, "%s(%d):start addr = 0x%x\n",
+ __func__, __LINE__, wcd_resource->start);
+
+ if (wcd_resource->start != TOMBAK_CORE_0_SPMI_ADDR)
+ goto rtn;
+
+ dev_set_name(&spmi->dev, "%s", MSM8X16_CODEC_NAME);
+ if (spmi->dev.of_node) {
+ dev_dbg(&spmi->dev, "%s:Platform data from device tree\n",
+ __func__);
+ pdata = msm8x16_wcd_populate_dt_pdata(&spmi->dev);
+ spmi->dev.platform_data = pdata;
+ } else {
+ dev_dbg(&spmi->dev, "%s:Platform data from board file\n",
+ __func__);
+ pdata = spmi->dev.platform_data;
+ }
+
+ msm8x16 = kzalloc(sizeof(struct msm8x16_wcd), GFP_KERNEL);
+ if (msm8x16 == NULL) {
+ dev_err(&spmi->dev,
+ "%s: error, allocation failed\n", __func__);
+ ret = -ENOMEM;
+ goto rtn;
+ }
+
+ msm8x16->dev = &spmi->dev;
+ msm8x16->read_dev = __msm8x16_wcd_reg_read;
+ msm8x16->write_dev = __msm8x16_wcd_reg_write;
+ ret = msm8x16_wcd_init_supplies(msm8x16, pdata);
+ if (ret) {
+ dev_err(&spmi->dev, "%s: Fail to enable Codec supplies\n",
+ __func__);
+ goto err_codec;
+ }
+
+ ret = msm8x16_wcd_enable_static_supplies(msm8x16, pdata);
+ if (ret) {
+ dev_err(&spmi->dev,
+ "%s: Fail to enable Codec pre-reset supplies\n",
+ __func__);
+ goto err_codec;
+ }
+ usleep_range(5, 6);
+
+ ret = msm8x16_wcd_device_init(msm8x16);
+ if (ret) {
+ dev_err(&spmi->dev,
+ "%s:msm8x16_wcd_device_init failed with error %d\n",
+ __func__, ret);
+ goto err_supplies;
+ }
+ dev_set_drvdata(&spmi->dev, msm8x16);
+
+ ret = snd_soc_register_codec(&spmi->dev, &soc_codec_dev_msm8x16_wcd,
+ msm8x16_wcd_i2s_dai,
+ ARRAY_SIZE(msm8x16_wcd_i2s_dai));
+ if (ret) {
+ dev_err(&spmi->dev,
+ "%s:snd_soc_register_codec failed with error %d\n",
+ __func__, ret);
+ } else {
+ goto rtn;
+ }
+
+err_supplies:
+ msm8x16_wcd_disable_supplies(msm8x16, pdata);
+err_codec:
+ kfree(msm8x16);
+rtn:
+ return ret;
+}
+
+static void msm8x16_wcd_device_exit(struct msm8x16_wcd *msm8x16)
+{
+ mutex_destroy(&msm8x16->io_lock);
+ kfree(msm8x16);
+}
+
+static int msm8x16_wcd_spmi_remove(struct spmi_device *spmi)
+{
+ struct msm8x16_wcd *msm8x16 = dev_get_drvdata(&spmi->dev);
+
+ msm8x16_wcd_device_exit(msm8x16);
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int msm8x16_wcd_spmi_resume(struct spmi_device *spmi)
+{
+ struct resource *wcd_resource;
+
+ wcd_resource = spmi_get_resource(spmi, NULL, IORESOURCE_MEM, 0);
+ if (!wcd_resource) {
+ dev_err(&spmi->dev, "Unable to get CDC SPMI resource\n");
+ return -ENXIO;
+ }
+
+ if (wcd_resource->start == TOMBAK_CORE_0_SPMI_ADDR)
+ return wcd9xxx_spmi_resume();
+ return 0;
+}
+
+static int msm8x16_wcd_spmi_suspend(struct spmi_device *spmi,
+ pm_message_t pmesg)
+{
+ struct resource *wcd_resource;
+
+ wcd_resource = spmi_get_resource(spmi, NULL, IORESOURCE_MEM, 0);
+ if (!wcd_resource) {
+ dev_err(&spmi->dev, "Unable to get CDC SPMI resource\n");
+ return -ENXIO;
+ }
+
+ if (wcd_resource->start == TOMBAK_CORE_0_SPMI_ADDR)
+ return wcd9xxx_spmi_suspend(pmesg);
+ return 0;
+}
+#endif
+
+static struct spmi_device_id msm8x16_wcd_spmi_id_table[] = {
+ {"wcd-spmi", MSM8X16_WCD_SPMI_DIGITAL},
+ {"wcd-spmi", MSM8X16_WCD_SPMI_ANALOG},
+ {}
+};
+
+static struct of_device_id msm8x16_wcd_spmi_of_match[] = {
+ { .compatible = "qcom,wcd-spmi",},
+ { },
+};
+
+static struct spmi_driver wcd_spmi_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "wcd-spmi-core",
+ .of_match_table = msm8x16_wcd_spmi_of_match
+ },
+#ifdef CONFIG_PM
+ .suspend = msm8x16_wcd_spmi_suspend,
+ .resume = msm8x16_wcd_spmi_resume,
+#endif
+ .id_table = msm8x16_wcd_spmi_id_table,
+ .probe = msm8x16_wcd_spmi_probe,
+ .remove = msm8x16_wcd_spmi_remove,
+};
+
+static int __init msm8x16_wcd_codec_init(void)
+{
+ spmi_driver_register(&wcd_spmi_driver);
+ return 0;
+}
+module_init(msm8x16_wcd_codec_init);
+
+static void __exit msm8x16_wcd_codec_exit(void)
+{
+ spmi_driver_unregister(&wcd_spmi_driver);
+}
+module_exit(msm8x16_wcd_codec_exit);
+
+MODULE_DESCRIPTION("MSM8x16 Audio codec driver");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, msm8x16_wcd_spmi_id_table);
+
diff --git a/sound/soc/codecs/msm8x16-wcd.h b/sound/soc/codecs/msm8x16-wcd.h
new file mode 100644
index 000000000000..899238661691
--- /dev/null
+++ b/sound/soc/codecs/msm8x16-wcd.h
@@ -0,0 +1,157 @@
+/* Copyright (c) 2014, The Linux Foundation. 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 MSM8X16_WCD_H
+#define MSM8X16_WCD_H
+
+#include <sound/soc.h>
+#include <sound/jack.h>
+#include <linux/mfd/wcd9xxx/pdata.h>
+
+#define MSM8X16_WCD_NUM_REGISTERS 0x6FF
+#define MSM8X16_WCD_MAX_REGISTER (MSM8X16_WCD_NUM_REGISTERS-1)
+#define MSM8X16_WCD_CACHE_SIZE MSM8X16_WCD_NUM_REGISTERS
+#define MSM8X16_WCD_NUM_IRQ_REGS 2
+#define MAX_REGULATOR 7
+#define MSM8X16_WCD_REG_VAL(reg, val) {reg, 0, val}
+#define MSM8X16_TOMBAK_LPASS_AUDIO_CORE_DIG_CODEC_CLK_SEL 0xFE03B004
+#define MSM8X16_TOMBAK_LPASS_DIGCODEC_CMD_RCGR 0x0181C09C
+#define MSM8X16_TOMBAK_LPASS_DIGCODEC_CFG_RCGR 0x0181C0A0
+#define MSM8X16_TOMBAK_LPASS_DIGCODEC_M 0x0181C0A4
+#define MSM8X16_TOMBAK_LPASS_DIGCODEC_N 0x0181C0A8
+#define MSM8X16_TOMBAK_LPASS_DIGCODEC_D 0x0181C0AC
+#define MSM8X16_TOMBAK_LPASS_DIGCODEC_CBCR 0x0181C0B0
+#define MSM8X16_TOMBAK_LPASS_DIGCODEC_AHB_CBCR 0x0181C0B4
+
+#define MSM8X16_CODEC_NAME "msm8x16_wcd_codec"
+
+#define MSM8X16_WCD_IS_DIGITAL_REG(reg) \
+ (((reg >= 0x400) && (reg <= 0x6FF)) ? 1 : 0)
+#define MSM8X16_WCD_IS_TOMBAK_REG(reg) \
+ (((reg >= 0x000) && (reg <= 0x1FF)) ? 1 : 0)
+extern const u8 msm8x16_wcd_reg_readable[MSM8X16_WCD_CACHE_SIZE];
+extern const u8 msm8x16_wcd_reg_readonly[MSM8X16_WCD_CACHE_SIZE];
+extern const u8 msm8x16_wcd_reset_reg_defaults[MSM8X16_WCD_CACHE_SIZE];
+
+enum msm8x16_wcd_pid_current {
+ MSM8X16_WCD_PID_MIC_2P5_UA,
+ MSM8X16_WCD_PID_MIC_5_UA,
+ MSM8X16_WCD_PID_MIC_10_UA,
+ MSM8X16_WCD_PID_MIC_20_UA,
+};
+
+struct msm8x16_wcd_reg_mask_val {
+ u16 reg;
+ u8 mask;
+ u8 val;
+};
+
+enum msm8x16_wcd_mbhc_analog_pwr_cfg {
+ MSM8X16_WCD_ANALOG_PWR_COLLAPSED = 0,
+ MSM8X16_WCD_ANALOG_PWR_ON,
+ MSM8X16_WCD_NUM_ANALOG_PWR_CONFIGS,
+};
+
+/* Number of input and output I2S port */
+enum {
+ MSM8X16_WCD_RX1 = 0,
+ MSM8X16_WCD_RX2,
+ MSM8X16_WCD_RX3,
+ MSM8X16_WCD_RX_MAX,
+};
+
+enum {
+ MSM8X16_WCD_TX1 = 0,
+ MSM8X16_WCD_TX2,
+ MSM8X16_WCD_TX3,
+ MSM8X16_WCD_TX4,
+ MSM8X16_WCD_TX_MAX,
+};
+
+enum {
+ /* INTR_REG 0 - Digital Periph */
+ MSM8X16_WCD_IRQ_SPKR_CNP = 0,
+ MSM8X16_WCD_IRQ_SPKR_CLIP,
+ MSM8X16_WCD_IRQ_SPKR_OCP,
+ MSM8X16_WCD_IRQ_MBHC_INSREM_DET1,
+ MSM8X16_WCD_IRQ_MBHC_RELEASE,
+ MSM8X16_WCD_IRQ_MBHC_PRESS,
+ MSM8X16_WCD_IRQ_MBHC_INSREM_DET,
+ MSM8X16_WCD_IRQ_MBHC_HS_DET,
+ /* INTR_REG 1 - Analog Periph */
+ MSM8X16_WCD_IRQ_EAR_OCP,
+ MSM8X16_WCD_IRQ_HPHR_OCP,
+ MSM8X16_WCD_IRQ_HPHL_OCP,
+ MSM8X16_WCD_IRQ_EAR_CNP,
+ MSM8X16_WCD_IRQ_HPHR_CNP,
+ MSM8X16_WCD_IRQ_HPHL_CNP,
+ MSM8X16_WCD_NUM_IRQS,
+};
+
+/*
+ * The delay list is per codec HW specification.
+ * Please add delay in the list in the future instead
+ * of magic number
+ */
+enum {
+ CODEC_DELAY_1_MS = 1000,
+ CODEC_DELAY_1_1_MS = 1100,
+};
+
+struct msm8x16_wcd_regulator {
+ const char *name;
+ int min_uv;
+ int max_uv;
+ int optimum_ua;
+ bool ondemand;
+ struct regulator *regulator;
+};
+
+struct msm8x16_wcd_pdata {
+ int irq;
+ int irq_base;
+ int num_irqs;
+ int reset_gpio;
+ void *msm8x16_wcd_ahb_base_vaddr;
+ struct wcd9xxx_micbias_setting micbias;
+ struct msm8x16_wcd_regulator regulator[MAX_REGULATOR];
+ u32 mclk_rate;
+};
+
+enum msm8x16_wcd_micbias_num {
+ MSM8X16_WCD_MICBIAS1 = 0,
+};
+
+struct msm8x16_wcd {
+ struct device *dev;
+ struct mutex io_lock;
+ u8 version;
+
+ int reset_gpio;
+ int (*read_dev)(struct msm8x16_wcd *msm8x16,
+ unsigned short reg);
+ int (*write_dev)(struct msm8x16_wcd *msm8x16,
+ unsigned short reg, u8 val);
+
+ u32 num_of_supplies;
+ struct regulator_bulk_data *supplies;
+
+ u8 idbyte[4];
+
+ int num_irqs;
+ u32 mclk_rate;
+};
+
+extern int msm8x16_wcd_mclk_enable(struct snd_soc_codec *codec, int mclk_enable,
+ bool dapm);
+
+#endif
+
diff --git a/sound/soc/codecs/msm8x16_wcd_registers.h b/sound/soc/codecs/msm8x16_wcd_registers.h
new file mode 100644
index 000000000000..7407247f40ef
--- /dev/null
+++ b/sound/soc/codecs/msm8x16_wcd_registers.h
@@ -0,0 +1,517 @@
+ /* Copyright (c) 2014, The Linux Foundation. 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 MSM8X16_WCD_REGISTERS_H
+#define MSM8X16_WCD_REGISTERS_H
+
+#define MSM8X16_WCD_A_DIGITAL_REVISION1 (0x000)
+#define MSM8X16_WCD_A_DIGITAL_REVISION1__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_REVISION2 (0x001)
+#define MSM8X16_WCD_A_DIGITAL_REVISION2__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_PERPH_TYPE (0x004)
+#define MSM8X16_WCD_A_DIGITAL_PERPH_TYPE__POR (0x23)
+#define MSM8X16_WCD_A_DIGITAL_PERPH_SUBTYPE (0x005)
+#define MSM8X16_WCD_A_DIGITAL_PERPH_SUBTYPE__POR (0x01)
+#define MSM8X16_WCD_A_DIGITAL_INT_RT_STS (0x010)
+#define MSM8X16_WCD_A_DIGITAL_INT_RT_STS__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_INT_SET_TYPE (0x011)
+#define MSM8X16_WCD_A_DIGITAL_INT_SET_TYPE__POR (0xFF)
+#define MSM8X16_WCD_A_DIGITAL_INT_POLARITY_HIGH (0x012)
+#define MSM8X16_WCD_A_DIGITAL_INT_POLARITY_HIGH__POR (0xFF)
+#define MSM8X16_WCD_A_DIGITAL_INT_POLARITY_LOW (0x013)
+#define MSM8X16_WCD_A_DIGITAL_INT_POLARITY_LOW__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_INT_LATCHED_CLR (0x014)
+#define MSM8X16_WCD_A_DIGITAL_INT_LATCHED_CLR__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_INT_EN_SET (0x015)
+#define MSM8X16_WCD_A_DIGITAL_INT_EN_SET__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_INT_EN_CLR (0x016)
+#define MSM8X16_WCD_A_DIGITAL_INT_EN_CLR__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_INT_LATCHED_STS (0x018)
+#define MSM8X16_WCD_A_DIGITAL_INT_LATCHED_STS__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_INT_PENDING_STS (0x019)
+#define MSM8X16_WCD_A_DIGITAL_INT_PENDING_STS__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_INT_MID_SEL (0x01A)
+#define MSM8X16_WCD_A_DIGITAL_INT_MID_SEL__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_INT_PRIORITY (0x01B)
+#define MSM8X16_WCD_A_DIGITAL_INT_PRIORITY__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_GPIO_MODE (0x040)
+#define MSM8X16_WCD_A_DIGITAL_GPIO_MODE__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_PIN_CTL_OE (0x041)
+#define MSM8X16_WCD_A_DIGITAL_PIN_CTL_OE__POR (0x01)
+#define MSM8X16_WCD_A_DIGITAL_PIN_CTL_DATA (0x042)
+#define MSM8X16_WCD_A_DIGITAL_PIN_CTL_DATA__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_PIN_STATUS (0x043)
+#define MSM8X16_WCD_A_DIGITAL_PIN_STATUS__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_HDRIVE_CTL (0x044)
+#define MSM8X16_WCD_A_DIGITAL_HDRIVE_CTL__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_CDC_RST_CTL (0x046)
+#define MSM8X16_WCD_A_DIGITAL_CDC_RST_CTL__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_CDC_TOP_CLK_CTL (0x048)
+#define MSM8X16_WCD_A_DIGITAL_CDC_TOP_CLK_CTL__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_CDC_ANA_CLK_CTL (0x049)
+#define MSM8X16_WCD_A_DIGITAL_CDC_ANA_CLK_CTL__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL (0x04A)
+#define MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_CDC_CONN_TX1_CTL (0x050)
+#define MSM8X16_WCD_A_DIGITAL_CDC_CONN_TX1_CTL__POR (0x02)
+#define MSM8X16_WCD_A_DIGITAL_CDC_CONN_TX2_CTL (0x051)
+#define MSM8X16_WCD_A_DIGITAL_CDC_CONN_TX2_CTL__POR (0x02)
+#define MSM8X16_WCD_A_DIGITAL_CDC_CONN_HPHR_DAC_CTL (0x052)
+#define MSM8X16_WCD_A_DIGITAL_CDC_CONN_HPHR_DAC_CTL__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX1_CTL (0x053)
+#define MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX1_CTL__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX2_CTL (0x054)
+#define MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX2_CTL__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX3_CTL (0x055)
+#define MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX3_CTL__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX_LB_CTL (0x056)
+#define MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX_LB_CTL__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_CDC_RX_CTL1 (0x058)
+#define MSM8X16_WCD_A_DIGITAL_CDC_RX_CTL1__POR (0x7C)
+#define MSM8X16_WCD_A_DIGITAL_CDC_RX_CTL2 (0x059)
+#define MSM8X16_WCD_A_DIGITAL_CDC_RX_CTL2__POR (0x7C)
+#define MSM8X16_WCD_A_DIGITAL_CDC_RX_CTL3 (0x05A)
+#define MSM8X16_WCD_A_DIGITAL_CDC_RX_CTL3__POR (0x7C)
+#define MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA0 (0x05B)
+#define MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA0__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA1 (0x05C)
+#define MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA1__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA2 (0x05D)
+#define MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA2__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA3 (0x05E)
+#define MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA3__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_DIG_DEBUG_CTL (0x068)
+#define MSM8X16_WCD_A_DIGITAL_DIG_DEBUG_CTL__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_DIG_DEBUG_EN (0x069)
+#define MSM8X16_WCD_A_DIGITAL_DIG_DEBUG_EN__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_SPARE_0 (0x070)
+#define MSM8X16_WCD_A_DIGITAL_SPARE_0__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_SPARE_1 (0x071)
+#define MSM8X16_WCD_A_DIGITAL_SPARE_1__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_SPARE_2 (0x072)
+#define MSM8X16_WCD_A_DIGITAL_SPARE_2__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_SEC_ACCESS (0x0D0)
+#define MSM8X16_WCD_A_DIGITAL_SEC_ACCESS__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_PERPH_RESET_CTL1 (0x0D8)
+#define MSM8X16_WCD_A_DIGITAL_PERPH_RESET_CTL1__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_PERPH_RESET_CTL2 (0x0D9)
+#define MSM8X16_WCD_A_DIGITAL_PERPH_RESET_CTL2__POR (0x01)
+#define MSM8X16_WCD_A_DIGITAL_PERPH_RESET_CTL3 (0x0DA)
+#define MSM8X16_WCD_A_DIGITAL_PERPH_RESET_CTL3__POR (0x05)
+#define MSM8X16_WCD_A_DIGITAL_PERPH_RESET_CTL4 (0x0DB)
+#define MSM8X16_WCD_A_DIGITAL_PERPH_RESET_CTL4__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_INT_TEST1 (0x0E0)
+#define MSM8X16_WCD_A_DIGITAL_INT_TEST1__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_INT_TEST_VAL (0x0E1)
+#define MSM8X16_WCD_A_DIGITAL_INT_TEST_VAL__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_TRIM_NUM (0x0F0)
+#define MSM8X16_WCD_A_DIGITAL_TRIM_NUM__POR (0x00)
+#define MSM8X16_WCD_A_DIGITAL_TRIM_CTRL (0x0F1)
+#define MSM8X16_WCD_A_DIGITAL_TRIM_CTRL__POR (0x00)
+
+#define MSM8X16_WCD_A_ANALOG_REVISION1 (0x100)
+#define MSM8X16_WCD_A_ANALOG_REVISION1__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_REVISION2 (0x101)
+#define MSM8X16_WCD_A_ANALOG_REVISION2__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_REVISION3 (0x102)
+#define MSM8X16_WCD_A_ANALOG_REVISION3__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_REVISION4 (0x103)
+#define MSM8X16_WCD_A_ANALOG_REVISION4__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_PERPH_TYPE (0x104)
+#define MSM8X16_WCD_A_ANALOG_PERPH_TYPE__POR (0x23)
+#define MSM8X16_WCD_A_ANALOG_PERPH_SUBTYPE (0x105)
+#define MSM8X16_WCD_A_ANALOG_PERPH_SUBTYPE__POR (0x09)
+#define MSM8X16_WCD_A_ANALOG_INT_RT_STS (0x110)
+#define MSM8X16_WCD_A_ANALOG_INT_RT_STS__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_INT_SET_TYPE (0x111)
+#define MSM8X16_WCD_A_ANALOG_INT_SET_TYPE__POR (0x3F)
+#define MSM8X16_WCD_A_ANALOG_INT_POLARITY_HIGH (0x112)
+#define MSM8X16_WCD_A_ANALOG_INT_POLARITY_HIGH__POR (0x3F)
+#define MSM8X16_WCD_A_ANALOG_INT_POLARITY_LOW (0x113)
+#define MSM8X16_WCD_A_ANALOG_INT_POLARITY_LOW__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_INT_LATCHED_CLR (0x114)
+#define MSM8X16_WCD_A_ANALOG_INT_LATCHED_CLR__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_INT_EN_SET (0x115)
+#define MSM8X16_WCD_A_ANALOG_INT_EN_SET__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_INT_EN_CLR (0x116)
+#define MSM8X16_WCD_A_ANALOG_INT_EN_CLR__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_INT_LATCHED_STS (0x118)
+#define MSM8X16_WCD_A_ANALOG_INT_LATCHED_STS__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_INT_PENDING_STS (0x119)
+#define MSM8X16_WCD_A_ANALOG_INT_PENDING_STS__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_INT_MID_SEL (0x11A)
+#define MSM8X16_WCD_A_ANALOG_INT_MID_SEL__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_INT_PRIORITY (0x11B)
+#define MSM8X16_WCD_A_ANALOG_INT_PRIORITY__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_MICB_1_EN (0x140)
+#define MSM8X16_WCD_A_ANALOG_MICB_1_EN__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_MICB_1_VAL (0x141)
+#define MSM8X16_WCD_A_ANALOG_MICB_1_VAL__POR (0x20)
+#define MSM8X16_WCD_A_ANALOG_MICB_1_CTL (0x142)
+#define MSM8X16_WCD_A_ANALOG_MICB_1_CTL__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_MICB_1_INT_RBIAS (0x143)
+#define MSM8X16_WCD_A_ANALOG_MICB_1_INT_RBIAS__POR (0x49)
+#define MSM8X16_WCD_A_ANALOG_MICB_2_EN (0x144)
+#define MSM8X16_WCD_A_ANALOG_MICB_2_EN__POR (0x20)
+#define MSM8X16_WCD_A_ANALOG_TX_1_2_ATEST_CTL_2 (0x145)
+#define MSM8X16_WCD_A_ANALOG_TX_1_2_ATEST_CTL_2__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_MASTER_BIAS_CTL (0x146)
+#define MSM8X16_WCD_A_ANALOG_MASTER_BIAS_CTL__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_MBHC_DET_CTL_1 (0x147)
+#define MSM8X16_WCD_A_ANALOG_MBHC_DET_CTL_1__POR (0x35)
+#define MSM8X16_WCD_A_ANALOG_MBHC_DET_CTL_2 (0x150)
+#define MSM8X16_WCD_A_ANALOG_MBHC_DET_CTL_2__POR (0x08)
+#define MSM8X16_WCD_A_ANALOG_MBHC_FSM_CTL (0x151)
+#define MSM8X16_WCD_A_ANALOG_MBHC_FSM_CTL__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_MBHC_DBNC_TIMER (0x152)
+#define MSM8X16_WCD_A_ANALOG_MBHC_DBNC_TIMER__POR (0x98)
+#define MSM8X16_WCD_A_ANALOG_MBHC_BTN0_ZDETL_CTL (0x153)
+#define MSM8X16_WCD_A_ANALOG_MBHC_BTN0_ZDETL_CTL__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_MBHC_BTN1_ZDETM_CTL (0x154)
+#define MSM8X16_WCD_A_ANALOG_MBHC_BTN1_ZDETM_CTL__POR (0x20)
+#define MSM8X16_WCD_A_ANALOG_MBHC_BTN2_ZDETH_CTL (0x155)
+#define MSM8X16_WCD_A_ANALOG_MBHC_BTN2_ZDETH_CTL__POR (0x40)
+#define MSM8X16_WCD_A_ANALOG_MBHC_BTN3_CTL (0x156)
+#define MSM8X16_WCD_A_ANALOG_MBHC_BTN3_CTL__POR (0x61)
+#define MSM8X16_WCD_A_ANALOG_MBHC_BTN4_CTL (0x157)
+#define MSM8X16_WCD_A_ANALOG_MBHC_BTN4_CTL__POR (0x80)
+#define MSM8X16_WCD_A_ANALOG_MBHC_BTN_RESULT (0x158)
+#define MSM8X16_WCD_A_ANALOG_MBHC_BTN_RESULT__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_MBHC_ZDET_ELECT_RESULT (0x159)
+#define MSM8X16_WCD_A_ANALOG_MBHC_ZDET_ELECT_RESULT__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_TX_1_EN (0x160)
+#define MSM8X16_WCD_A_ANALOG_TX_1_EN__POR (0x03)
+#define MSM8X16_WCD_A_ANALOG_TX_2_EN (0x161)
+#define MSM8X16_WCD_A_ANALOG_TX_2_EN__POR (0x03)
+#define MSM8X16_WCD_A_ANALOG_TX_1_2_TEST_CTL_1 (0x162)
+#define MSM8X16_WCD_A_ANALOG_TX_1_2_TEST_CTL_1__POR (0xBF)
+#define MSM8X16_WCD_A_ANALOG_TX_1_2_TEST_CTL_2 (0x163)
+#define MSM8X16_WCD_A_ANALOG_TX_1_2_TEST_CTL_2__POR (0x8C)
+#define MSM8X16_WCD_A_ANALOG_TX_1_2_ATEST_CTL (0x164)
+#define MSM8X16_WCD_A_ANALOG_TX_1_2_ATEST_CTL__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_TX_1_2_OPAMP_BIAS (0x165)
+#define MSM8X16_WCD_A_ANALOG_TX_1_2_OPAMP_BIAS__POR (0x6B)
+#define MSM8X16_WCD_A_ANALOG_TX_1_2_TXFE_CLKDIV (0x166)
+#define MSM8X16_WCD_A_ANALOG_TX_1_2_TXFE_CLKDIV__POR (0x51)
+#define MSM8X16_WCD_A_ANALOG_TX_3_EN (0x167)
+#define MSM8X16_WCD_A_ANALOG_TX_3_EN__POR (0x02)
+#define MSM8X16_WCD_A_ANALOG_NCP_EN (0x180)
+#define MSM8X16_WCD_A_ANALOG_NCP_EN__POR (0x26)
+#define MSM8X16_WCD_A_ANALOG_NCP_CLK (0x181)
+#define MSM8X16_WCD_A_ANALOG_NCP_CLK__POR (0x23)
+#define MSM8X16_WCD_A_ANALOG_NCP_DEGLITCH (0x182)
+#define MSM8X16_WCD_A_ANALOG_NCP_DEGLITCH__POR (0x5B)
+#define MSM8X16_WCD_A_ANALOG_NCP_FBCTRL (0x183)
+#define MSM8X16_WCD_A_ANALOG_NCP_FBCTRL__POR (0x08)
+#define MSM8X16_WCD_A_ANALOG_NCP_BIAS (0x184)
+#define MSM8X16_WCD_A_ANALOG_NCP_BIAS__POR (0x29)
+#define MSM8X16_WCD_A_ANALOG_NCP_VCTRL (0x185)
+#define MSM8X16_WCD_A_ANALOG_NCP_VCTRL__POR (0x24)
+#define MSM8X16_WCD_A_ANALOG_NCP_TEST (0x186)
+#define MSM8X16_WCD_A_ANALOG_NCP_TEST__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_NCP_CLIM_ADDR (0x187)
+#define MSM8X16_WCD_A_ANALOG_NCP_CLIM_ADDR__POR (0xD5)
+#define MSM8X16_WCD_A_ANALOG_RX_CLOCK_DIVIDER (0x190)
+#define MSM8X16_WCD_A_ANALOG_RX_CLOCK_DIVIDER__POR (0xE8)
+#define MSM8X16_WCD_A_ANALOG_RX_COM_OCP_CTL (0x191)
+#define MSM8X16_WCD_A_ANALOG_RX_COM_OCP_CTL__POR (0xCF)
+#define MSM8X16_WCD_A_ANALOG_RX_COM_OCP_COUNT (0x192)
+#define MSM8X16_WCD_A_ANALOG_RX_COM_OCP_COUNT__POR (0x6E)
+#define MSM8X16_WCD_A_ANALOG_RX_COM_BIAS_DAC (0x193)
+#define MSM8X16_WCD_A_ANALOG_RX_COM_BIAS_DAC__POR (0x10)
+#define MSM8X16_WCD_A_ANALOG_RX_HPH_BIAS_PA (0x194)
+#define MSM8X16_WCD_A_ANALOG_RX_HPH_BIAS_PA__POR (0x5A)
+#define MSM8X16_WCD_A_ANALOG_RX_HPH_BIAS_LDO_OCP (0x195)
+#define MSM8X16_WCD_A_ANALOG_RX_HPH_BIAS_LDO_OCP__POR (0x69)
+#define MSM8X16_WCD_A_ANALOG_RX_HPH_BIAS_CNP (0x196)
+#define MSM8X16_WCD_A_ANALOG_RX_HPH_BIAS_CNP__POR (0x29)
+#define MSM8X16_WCD_A_ANALOG_RX_HPH_CNP_EN (0x197)
+#define MSM8X16_WCD_A_ANALOG_RX_HPH_CNP_EN__POR (0x80)
+#define MSM8X16_WCD_A_ANALOG_RX_HPH_CNP_WG_CTL (0x198)
+#define MSM8X16_WCD_A_ANALOG_RX_HPH_CNP_WG_CTL__POR (0xDA)
+#define MSM8X16_WCD_A_ANALOG_RX_HPH_CNP_WG_TIME (0x199)
+#define MSM8X16_WCD_A_ANALOG_RX_HPH_CNP_WG_TIME__POR (0x16)
+#define MSM8X16_WCD_A_ANALOG_RX_HPH_L_TEST (0x19A)
+#define MSM8X16_WCD_A_ANALOG_RX_HPH_L_TEST__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_RX_HPH_L_PA_DAC_CTL (0x19B)
+#define MSM8X16_WCD_A_ANALOG_RX_HPH_L_PA_DAC_CTL__POR (0x20)
+#define MSM8X16_WCD_A_ANALOG_RX_HPH_R_TEST (0x19C)
+#define MSM8X16_WCD_A_ANALOG_RX_HPH_R_TEST__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_RX_HPH_R_PA_DAC_CTL (0x19D)
+#define MSM8X16_WCD_A_ANALOG_RX_HPH_R_PA_DAC_CTL__POR (0x20)
+#define MSM8X16_WCD_A_ANALOG_RX_EAR_CTL (0x19E)
+#define MSM8X16_WCD_A_ANALOG_RX_EAR_CTL___POR (0x12)
+#define MSM8X16_WCD_A_ANALOG_RX_ATEST (0x19F)
+#define MSM8X16_WCD_A_ANALOG_RX_ATEST__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_RX_HPH_STATUS (0x1A0)
+#define MSM8X16_WCD_A_ANALOG_RX_HPH_STATUS__POR (0x0C)
+#define MSM8X16_WCD_A_ANALOG_RX_EAR_STATUS (0x1A1)
+#define MSM8X16_WCD_A_ANALOG_RX_EAR_STATUS__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_SPKR_DAC_CTL (0x1B0)
+#define MSM8X16_WCD_A_ANALOG_SPKR_DAC_CTL__POR (0x83)
+#define MSM8X16_WCD_A_ANALOG_SPKR_DRV_CLIP_DET (0x1B1)
+#define MSM8X16_WCD_A_ANALOG_SPKR_DRV_CLIP_DET__POR (0x91)
+#define MSM8X16_WCD_A_ANALOG_SPKR_DRV_CTL (0x1B2)
+#define MSM8X16_WCD_A_ANALOG_SPKR_DRV_CTL__POR (0x29)
+#define MSM8X16_WCD_A_ANALOG_SPKR_ANA_BIAS_SET (0x1B3)
+#define MSM8X16_WCD_A_ANALOG_SPKR_ANA_BIAS_SET__POR (0x4D)
+#define MSM8X16_WCD_A_ANALOG_SPKR_OCP_CTL (0x1B4)
+#define MSM8X16_WCD_A_ANALOG_SPKR_OCP_CTL__POR (0xA1)
+#define MSM8X16_WCD_A_ANALOG_SPKR_PWRSTG_CTL (0x1B5)
+#define MSM8X16_WCD_A_ANALOG_SPKR_PWRSTG_CTL__POR (0x1E)
+#define MSM8X16_WCD_A_ANALOG_SPKR_DRV_MISC (0x1B6)
+#define MSM8X16_WCD_A_ANALOG_SPKR_DRV_MISC__POR (0xCB)
+#define MSM8X16_WCD_A_ANALOG_SPKR_DRV_DBG (0x1B7)
+#define MSM8X16_WCD_A_ANALOG_SPKR_DRV_DBG__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_CURRENT_LIMIT (0x1C0)
+#define MSM8X16_WCD_A_ANALOG_CURRENT_LIMIT__POR (0x02)
+#define MSM8X16_WCD_A_ANALOG_OUTPUT_VOLTAGE (0x1C1)
+#define MSM8X16_WCD_A_ANALOG_OUTPUT_VOLTAGE__POR (0x14)
+#define MSM8X16_WCD_A_ANALOG_BYPASS_MODE (0x1C2)
+#define MSM8X16_WCD_A_ANALOG_BYPASS_MODE__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_BOOST_EN_CTL (0x1C3)
+#define MSM8X16_WCD_A_ANALOG_BOOST_EN_CTL__POR (0x1F)
+#define MSM8X16_WCD_A_ANALOG_SLOPE_COMP_IP_ZERO (0x1C4)
+#define MSM8X16_WCD_A_ANALOG_SLOPE_COMP_IP_ZERO__POR (0x8C)
+#define MSM8X16_WCD_A_ANALOG_RDSON_MAX_DUTY_CYCLE (0x1C5)
+#define MSM8X16_WCD_A_ANALOG_RDSON_MAX_DUTY_CYCLE__POR (0xC0)
+#define MSM8X16_WCD_A_ANALOG_BOOST_TEST1_1 (0x1C6)
+#define MSM8X16_WCD_A_ANALOG_BOOST_TEST1_1__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_BOOST_TEST_2 (0x1C7)
+#define MSM8X16_WCD_A_ANALOG_BOOST_TEST_2__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_SPKR_SAR_STATUS (0x1C8)
+#define MSM8X16_WCD_A_ANALOG_SPKR_SAR_STATUS__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_SPKR_DRV_STATUS (0x1C9)
+#define MSM8X16_WCD_A_ANALOG_SPKR_DRV_STATUS__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_PBUS_ADD_CSR (0x1CE)
+#define MSM8X16_WCD_A_ANALOG_PBUS_ADD_CSR__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_PBUS_ADD_SEL (0x1CF)
+#define MSM8X16_WCD_A_ANALOG_PBUS_ADD_SEL__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_SEC_ACCESS (0x1D0)
+#define MSM8X16_WCD_A_ANALOG_SEC_ACCESS__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_PERPH_RESET_CTL1 (0x1D8)
+#define MSM8X16_WCD_A_ANALOG_PERPH_RESET_CTL1__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_PERPH_RESET_CTL2 (0x1D9)
+#define MSM8X16_WCD_A_ANALOG_PERPH_RESET_CTL2__POR (0x01)
+#define MSM8X16_WCD_A_ANALOG_PERPH_RESET_CTL3 (0x1DA)
+#define MSM8X16_WCD_A_ANALOG_PERPH_RESET_CTL3__POR (0x05)
+#define MSM8X16_WCD_A_ANALOG_PERPH_RESET_CTL4 (0x1DB)
+#define MSM8X16_WCD_A_ANALOG_PERPH_RESET_CTL4__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_INT_TEST1 (0x1E0)
+#define MSM8X16_WCD_A_ANALOG_INT_TEST1__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_INT_TEST_VAL (0x1E1)
+#define MSM8X16_WCD_A_ANALOG_INT_TEST_VAL__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_TRIM_NUM (0x1F0)
+#define MSM8X16_WCD_A_ANALOG_TRIM_NUM__POR (0x04)
+#define MSM8X16_WCD_A_ANALOG_TRIM_CTRL1 (0x1F1)
+#define MSM8X16_WCD_A_ANALOG_TRIM_CTRL1__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_TRIM_CTRL2 (0x1F2)
+#define MSM8X16_WCD_A_ANALOG_TRIM_CTRL2__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_TRIM_CTRL3 (0x1F3)
+#define MSM8X16_WCD_A_ANALOG_TRIM_CTRL3__POR (0x00)
+#define MSM8X16_WCD_A_ANALOG_TRIM_CTRL4 (0x1F4)
+#define MSM8X16_WCD_A_ANALOG_TRIM_CTRL4__POR (0x00)
+
+#define MSM8X16_WCD_A_CDC_CLK_RX_RESET_CTL (0x400)
+#define MSM8X16_WCD_A_CDC_CLK_RX_RESET_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_CLK_TX_RESET_B1_CTL (0x404)
+#define MSM8X16_WCD_A_CDC_CLK_TX_RESET_B1_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_CLK_DMIC_B1_CTL (0x408)
+#define MSM8X16_WCD_A_CDC_CLK_DMIC_B1_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_CLK_RX_I2S_CTL (0x40C)
+#define MSM8X16_WCD_A_CDC_CLK_RX_I2S_CTL__POR (0x13)
+#define MSM8X16_WCD_A_CDC_CLK_TX_I2S_CTL (0x410)
+#define MSM8X16_WCD_A_CDC_CLK_TX_I2S_CTL__POR (0x13)
+#define MSM8X16_WCD_A_CDC_CLK_OTHR_RESET_B1_CTL (0x414)
+#define MSM8X16_WCD_A_CDC_CLK_OTHR_RESET_B1_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_CLK_TX_CLK_EN_B1_CTL (0x418)
+#define MSM8X16_WCD_A_CDC_CLK_TX_CLK_EN_B1_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_CLK_OTHR_CTL (0x41C)
+#define MSM8X16_WCD_A_CDC_CLK_OTHR_CTL__POR (0x04)
+#define MSM8X16_WCD_A_CDC_CLK_RX_B1_CTL (0x420)
+#define MSM8X16_WCD_A_CDC_CLK_RX_B1_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_CLK_MCLK_CTL (0x424)
+#define MSM8X16_WCD_A_CDC_CLK_MCLK_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_CLK_PDM_CTL (0x428)
+#define MSM8X16_WCD_A_CDC_CLK_PDM_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_CLK_SD_CTL (0x42C)
+#define MSM8X16_WCD_A_CDC_CLK_SD_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_RX1_B1_CTL (0x440)
+#define MSM8X16_WCD_A_CDC_RX1_B1_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_RX2_B1_CTL (0x460)
+#define MSM8X16_WCD_A_CDC_RX2_B1_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_RX3_B1_CTL (0x480)
+#define MSM8X16_WCD_A_CDC_RX3_B1_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_RX1_B2_CTL (0x444)
+#define MSM8X16_WCD_A_CDC_RX1_B2_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_RX2_B2_CTL (0x464)
+#define MSM8X16_WCD_A_CDC_RX2_B2_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_RX3_B2_CTL (0x484)
+#define MSM8X16_WCD_A_CDC_RX3_B2_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_RX1_B3_CTL (0x448)
+#define MSM8X16_WCD_A_CDC_RX1_B3_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_RX2_B3_CTL (0x468)
+#define MSM8X16_WCD_A_CDC_RX2_B3_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_RX3_B3_CTL (0x488)
+#define MSM8X16_WCD_A_CDC_RX3_B3_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_RX1_B4_CTL (0x44C)
+#define MSM8X16_WCD_A_CDC_RX1_B4_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_RX2_B4_CTL (0x46C)
+#define MSM8X16_WCD_A_CDC_RX2_B4_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_RX3_B4_CTL (0x48C)
+#define MSM8X16_WCD_A_CDC_RX3_B4_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_RX1_B5_CTL (0x450)
+#define MSM8X16_WCD_A_CDC_RX1_B5_CTL__POR (0x68)
+#define MSM8X16_WCD_A_CDC_RX2_B5_CTL (0x470)
+#define MSM8X16_WCD_A_CDC_RX2_B5_CTL__POR (0x68)
+#define MSM8X16_WCD_A_CDC_RX3_B5_CTL (0x490)
+#define MSM8X16_WCD_A_CDC_RX3_B5_CTL__POR (0x68)
+#define MSM8X16_WCD_A_CDC_RX1_B6_CTL (0x454)
+#define MSM8X16_WCD_A_CDC_RX1_B6_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_RX2_B6_CTL (0x474)
+#define MSM8X16_WCD_A_CDC_RX2_B6_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_RX3_B6_CTL (0x494)
+#define MSM8X16_WCD_A_CDC_RX3_B6_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_RX1_VOL_CTL_B1_CTL (0x458)
+#define MSM8X16_WCD_A_CDC_RX1_VOL_CTL_B1_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_RX2_VOL_CTL_B1_CTL (0x478)
+#define MSM8X16_WCD_A_CDC_RX2_VOL_CTL_B1_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_RX3_VOL_CTL_B1_CTL (0x498)
+#define MSM8X16_WCD_A_CDC_RX3_VOL_CTL_B1_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_RX1_VOL_CTL_B2_CTL (0x45C)
+#define MSM8X16_WCD_A_CDC_RX1_VOL_CTL_B2_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_RX2_VOL_CTL_B2_CTL (0x47C)
+#define MSM8X16_WCD_A_CDC_RX2_VOL_CTL_B2_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_RX3_VOL_CTL_B2_CTL (0x49C)
+#define MSM8X16_WCD_A_CDC_RX3_VOL_CTL_B2_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_TOP_GAIN_UPDATE (0x4A0)
+#define MSM8X16_WCD_A_CDC_TOP_GAIN_UPDATE__POR (0x00)
+#define MSM8X16_WCD_A_CDC_TOP_CTL (0x4A4)
+#define MSM8X16_WCD_A_CDC_TOP_CTL__POR (0x01)
+#define MSM8X16_WCD_A_CDC_DEBUG_DESER1_CTL (0x4E0)
+#define MSM8X16_WCD_A_CDC_DEBUG_DESER1_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_DEBUG_DESER2_CTL (0x4E4)
+#define MSM8X16_WCD_A_CDC_DEBUG_DESER2_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_DEBUG_B1_CTL_CFG (0x4E8)
+#define MSM8X16_WCD_A_CDC_DEBUG_B1_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_DEBUG_B2_CTL_CFG (0x4EC)
+#define MSM8X16_WCD_A_CDC_DEBUG_B2_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_DEBUG_B3_CTL_CFG (0x4F0)
+#define MSM8X16_WCD_A_CDC_DEBUG_B3_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_IIR1_GAIN_B1_CTL (0x500)
+#define MSM8X16_WCD_A_CDC_IIR1_GAIN_B1_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_IIR2_GAIN_B1_CTL (0x540)
+#define MSM8X16_WCD_A_CDC_IIR2_GAIN_B1_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_IIR1_GAIN_B2_CTL (0x504)
+#define MSM8X16_WCD_A_CDC_IIR1_GAIN_B2_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_IIR2_GAIN_B2_CTL (0x544)
+#define MSM8X16_WCD_A_CDC_IIR2_GAIN_B2_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_IIR1_GAIN_B3_CTL (0x508)
+#define MSM8X16_WCD_A_CDC_IIR1_GAIN_B3_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_IIR2_GAIN_B3_CTL (0x548)
+#define MSM8X16_WCD_A_CDC_IIR2_GAIN_B3_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_IIR1_GAIN_B4_CTL (0x50C)
+#define MSM8X16_WCD_A_CDC_IIR1_GAIN_B4_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_IIR2_GAIN_B4_CTL (0x54C)
+#define MSM8X16_WCD_A_CDC_IIR2_GAIN_B4_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_IIR1_GAIN_B5_CTL (0x510)
+#define MSM8X16_WCD_A_CDC_IIR1_GAIN_B5_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_IIR2_GAIN_B5_CTL (0x550)
+#define MSM8X16_WCD_A_CDC_IIR2_GAIN_B5_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_IIR1_GAIN_B6_CTL (0x514)
+#define MSM8X16_WCD_A_CDC_IIR1_GAIN_B6_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_IIR2_GAIN_B6_CTL (0x554)
+#define MSM8X16_WCD_A_CDC_IIR2_GAIN_B6_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_IIR1_GAIN_B7_CTL (0x518)
+#define MSM8X16_WCD_A_CDC_IIR1_GAIN_B7_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_IIR2_GAIN_B7_CTL (0x558)
+#define MSM8X16_WCD_A_CDC_IIR2_GAIN_B7_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_IIR1_GAIN_B8_CTL (0x51C)
+#define MSM8X16_WCD_A_CDC_IIR1_GAIN_B8_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_IIR2_GAIN_B8_CTL (0x55C)
+#define MSM8X16_WCD_A_CDC_IIR2_GAIN_B8_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_IIR1_CTL (0x520)
+#define MSM8X16_WCD_A_CDC_IIR1_CTL__POR (0x40)
+#define MSM8X16_WCD_A_CDC_IIR2_CTL (0x560)
+#define MSM8X16_WCD_A_CDC_IIR2_CTL__POR (0x40)
+#define MSM8X16_WCD_A_CDC_IIR1_GAIN_TIMER_CTL (0x524)
+#define MSM8X16_WCD_A_CDC_IIR1_GAIN_TIMER_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_IIR2_GAIN_TIMER_CTL (0x564)
+#define MSM8X16_WCD_A_CDC_IIR2_GAIN_TIMER_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_IIR1_COEF_B1_CTL (0x528)
+#define MSM8X16_WCD_A_CDC_IIR1_COEF_B1_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_IIR2_COEF_B1_CTL (0x568)
+#define MSM8X16_WCD_A_CDC_IIR2_COEF_B1_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_IIR1_COEF_B2_CTL (0x52C)
+#define MSM8X16_WCD_A_CDC_IIR1_COEF_B2_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_IIR2_COEF_B2_CTL (0x56C)
+#define MSM8X16_WCD_A_CDC_IIR2_COEF_B2_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_CONN_RX1_B1_CTL (0x580)
+#define MSM8X16_WCD_A_CDC_CONN_RX1_B1_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_CONN_RX1_B2_CTL (0x584)
+#define MSM8X16_WCD_A_CDC_CONN_RX1_B2_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_CONN_RX1_B3_CTL (0x588)
+#define MSM8X16_WCD_A_CDC_CONN_RX1_B3_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_CONN_RX2_B1_CTL (0x58C)
+#define MSM8X16_WCD_A_CDC_CONN_RX2_B1_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_CONN_RX2_B2_CTL (0x590)
+#define MSM8X16_WCD_A_CDC_CONN_RX2_B2_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_CONN_RX2_B3_CTL (0x594)
+#define MSM8X16_WCD_A_CDC_CONN_RX2_B3_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_CONN_RX3_B1_CTL (0x598)
+#define MSM8X16_WCD_A_CDC_CONN_RX3_B1_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_CONN_RX3_B2_CTL (0x59C)
+#define MSM8X16_WCD_A_CDC_CONN_RX3_B2_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_CONN_TX_B1_CTL (0x5A0)
+#define MSM8X16_WCD_A_CDC_CONN_TX_B1_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_CONN_EQ1_B1_CTL (0x5A8)
+#define MSM8X16_WCD_A_CDC_CONN_EQ1_B1_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_CONN_EQ1_B2_CTL (0x5AC)
+#define MSM8X16_WCD_A_CDC_CONN_EQ1_B2_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_CONN_EQ1_B3_CTL (0x5B0)
+#define MSM8X16_WCD_A_CDC_CONN_EQ1_B3_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_CONN_EQ1_B4_CTL (0x5B4)
+#define MSM8X16_WCD_A_CDC_CONN_EQ1_B4_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_CONN_EQ2_B1_CTL (0x5B8)
+#define MSM8X16_WCD_A_CDC_CONN_EQ2_B1_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_CONN_EQ2_B2_CTL (0x5BC)
+#define MSM8X16_WCD_A_CDC_CONN_EQ2_B2_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_CONN_EQ2_B3_CTL (0x5C0)
+#define MSM8X16_WCD_A_CDC_CONN_EQ2_B3_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_CONN_EQ2_B4_CTL (0x5C4)
+#define MSM8X16_WCD_A_CDC_CONN_EQ2_B4_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_CONN_TX_I2S_SD1_CTL (0x5C8)
+#define MSM8X16_WCD_A_CDC_CONN_TX_I2S_SD1_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_TX1_VOL_CTL_TIMER (0x680)
+#define MSM8X16_WCD_A_CDC_TX1_VOL_CTL_TIMER__POR (0x00)
+#define MSM8X16_WCD_A_CDC_TX2_VOL_CTL_TIMER (0x6A0)
+#define MSM8X16_WCD_A_CDC_TX2_VOL_CTL_TIMER__POR (0x00)
+#define MSM8X16_WCD_A_CDC_TX1_VOL_CTL_GAIN (0x684)
+#define MSM8X16_WCD_A_CDC_TX1_VOL_CTL_GAIN__POR (0x00)
+#define MSM8X16_WCD_A_CDC_TX2_VOL_CTL_GAIN (0x6A4)
+#define MSM8X16_WCD_A_CDC_TX2_VOL_CTL_GAIN__POR (0x00)
+#define MSM8X16_WCD_A_CDC_TX1_VOL_CTL_CFG (0x688)
+#define MSM8X16_WCD_A_CDC_TX1_VOL_CTL_CFG__POR (0x00)
+#define MSM8X16_WCD_A_CDC_TX2_VOL_CTL_CFG (0x6A8)
+#define MSM8X16_WCD_A_CDC_TX2_VOL_CTL_CFG__POR (0x00)
+#define MSM8X16_WCD_A_CDC_TX1_MUX_CTL (0x68C)
+#define MSM8X16_WCD_A_CDC_TX1_MUX_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_TX2_MUX_CTL (0x6AC)
+#define MSM8X16_WCD_A_CDC_TX2_MUX_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_TX1_CLK_FS_CTL (0x690)
+#define MSM8X16_WCD_A_CDC_TX1_CLK_FS_CTL__POR (0x03)
+#define MSM8X16_WCD_A_CDC_TX2_CLK_FS_CTL (0x6B0)
+#define MSM8X16_WCD_A_CDC_TX2_CLK_FS_CTL__POR (0x03)
+#define MSM8X16_WCD_A_CDC_TX1_DMIC_CTL (0x694)
+#define MSM8X16_WCD_A_CDC_TX1_DMIC_CTL__POR (0x00)
+#define MSM8X16_WCD_A_CDC_TX2_DMIC_CTL (0x6B4)
+#define MSM8X16_WCD_A_CDC_TX2_DMIC_CTL__POR (0x00)
+#endif