Merge remote-tracking branch 'quic/tmp-49d7613' into msm-3.4
Change-Id: I5ff7d85df0192eb8813f9b94440010a3b3f4a61c
Signed-off-by: Sridhar Parasuram <sridhar@codeaurora.org>
diff --git a/Documentation/devicetree/bindings/fb/mdss-mdp.txt b/Documentation/devicetree/bindings/fb/mdss-mdp.txt
index e4045373..0f31a38 100644
--- a/Documentation/devicetree/bindings/fb/mdss-mdp.txt
+++ b/Documentation/devicetree/bindings/fb/mdss-mdp.txt
@@ -10,7 +10,88 @@
- reg-names : names to refer to register sets related to this device
- interrupts : Interrupt associated with MDSS.
- vdd-supply : Phandle for vdd regulator device node.
+- qcom,mdss-pipe-vig-off: Array of offset for MDP source surface pipes of
+ type VIG, the offsets are calculated from
+ register "mdp_phys" defined in reg property.
+ The number of offsets defined here should
+ reflect the amount of VIG pipes that can be
+ active in MDP for this configuration.
+- qcom,mdss-pipe-vig-fetch-id: Array of shared memory pool fetch ids
+ corresponding to the VIG pipe offsets defined in
+ previous property, the amount of fetch ids
+ defined should match the number of offsets
+ defined in property: qcom,mdss-pipe-vig-off
+- qcom,mdss-pipe-rgb-off: Array of offsets for MDP source surface pipes of
+ type RGB, the offsets are calculated from
+ register "mdp_phys" defined in reg property.
+ The number of offsets defined here should
+ reflect the amount of RGB pipes that can be
+ active in MDP for this configuration.
+- qcom,mdss-pipe-rgb-fetch-id: Array of shared memory pool fetch ids
+ corresponding to the RGB pipe offsets defined in
+ previous property, the amount of fetch ids
+ defined should match the number of offsets
+ defined in property: qcom,mdss-pipe-rgb-off
+- qcom,mdss-pipe-dma-off: Array of offsets for MDP source surface pipes of
+ type DMA, the offsets are calculated from
+ register "mdp_phys" defined in reg property.
+ The number of offsets defined here should
+ reflect the amount of DMA pipes that can be
+ active in MDP for this configuration.
+- qcom,mdss-pipe-dma-fetch-id: Array of shared memory pool fetch ids
+ corresponding to the DMA pipe offsets defined in
+ previous property, the amount of fetch ids
+ defined should match the number of offsets
+ defined in property: qcom,mdss-pipe-dma-off
+- qcom,mdss-ctl-off: Array of offset addresses for the available ctl
+ hw blocks within MDP, these offsets are
+ calculated from register "mdp_phys" defined in
+ reg property. The number of ctl offsets defined
+ here should reflect the number of control paths
+ that can be configured concurrently on MDP for
+ this configuration.
+- qcom,mdss-wb-off: Array of offset addresses for the progammable
+ writeback blocks within MDP. The number of
+ offsets defined should match the number of ctl
+ blocks defined in property: qcom,mdss-ctl-off
+- qcom,mdss-mixer-intf-off: Array of offset addresses for the available
+ mixer blocks that can drive data to panel
+ interfaces.
+ These offsets are be calculated from register
+ "mdp_phys" defined in reg property.
+ The number of offsets defined should reflect the
+ amount of mixers that can drive data to a panel
+ interface.
+- qcom,mdss-dspp-off: Array of offset addresses for the available dspp
+ blocks. These offsets are calculated from
+ regsiter "mdp_phys" defined in reg property.
+ The number of dspp blocks should match the
+ number of mixers driving data to interface
+ defined in property: qcom,mdss-mixer-intf-off
+- qcom,mdss-mixer-wb-off: Array of offset addresses for the available
+ mixer blocks that can be drive data to writeback
+ block. These offsets will be calculated from
+ register "mdp_phys" defined in reg property.
+ The number of writeback mixer offsets defined
+ should reflect the number of mixers that can
+ drive data to a writeback block.
+- qcom,mdss-intf-off: Array of offset addresses for the available MDP
+ video interface blocks that can drive data to a
+ panel controller through timing engine.
+ The offsets are calculated from "mdp_phys"
+ defined in reg property. The number of offsets
+ defiend should reflect the number of progammable
+ interface blocks avaialble in hardware.
+Optional properties:
+- qcom,vbif-settings : Array with key-value pairs of constant VBIF register
+ settings used to setup MDSS QoS for optimum performance.
+ The key used should be offset from "vbif_phys" register
+ defined in reg property.
+- qcom,mdp-settings : Array with key-value pairs of constant MDP register
+ settings used to setup MDSS QoS for best performance.
+ The key used should be offset from "mdp_phys" register
+ defined in reg property.
Optional subnodes:
Child nodes representing the frame buffer virtual devices.
@@ -30,6 +111,30 @@
interrupts = <0 72 0>;
vdd-supply = <&gdsc_mdss>;
+ qcom,vbif-settings = <0x0004 0x00000001>,
+ <0x00D8 0x00000707>;
+ qcom,mdp-settings = <0x02E0 0x000000AA>,
+ <0x02E4 0x00000055>;
+ qcom,mdss-pipe-vig-off = <0x00001200 0x00001600
+ 0x00001A00>;
+ qcom,mdss-pipe-rgb-off = <0x00001E00 0x00002200
+ 0x00002600>;
+ qcom,mdss-pipe-dma-off = <0x00002A00 0x00002E00>;
+ qcom,mdss-pipe-vig-fetch-id = <1 4 7>;
+ qcom,mdss-pipe-rgb-fetch-id = <16 17 18>;
+ qcom,mdss-pipe-dma-fetch-id = <10 13>;
+
+ qcom,mdss-ctl-off = <0x00000600 0x00000700 0x00000800
+ 0x00000900 0x0000A00>;
+ qcom,mdss-mixer-intf-off = <0x00003200 0x00003600
+ 0x00003A00>;
+ qcom,mdss-mixer-wb-off = <0x00003E00 0x00004200>;
+ qcom,mdss-dspp-off = <0x00004600 0x00004A00 0x00004E00>;
+ qcom,mdss-wb-off = <0x00011100 0x00013100 0x00015100
+ 0x00017100 0x00019100>;
+ qcom,mdss-intf-off = <0x00021100 0x00021300
+ 0x00021500 0x00021700>;
+
mdss_fb0: qcom,mdss_fb_primary {
cell-index = <0>;
compatible = "qcom,mdss-fb";
diff --git a/Documentation/devicetree/bindings/media/video/msm-vidc.txt b/Documentation/devicetree/bindings/media/video/msm-vidc.txt
index 6b1deb6..cd14056 100644
--- a/Documentation/devicetree/bindings/media/video/msm-vidc.txt
+++ b/Documentation/devicetree/bindings/media/video/msm-vidc.txt
@@ -3,24 +3,34 @@
Required properties:
- compatible : one of:
- "qcom,msm-vidc"
-- hfi : supported Host-Firmware Interface, one of:
+- qcom,hfi : supported Host-Firmware Interface, one of:
- "venus"
- "q6"
Optional properties:
- reg : offset and length of the register set for the device.
- interrupts : should contain the vidc interrupt.
-- vidc-cp-map : start and size of device virtual address range for secure buffers.
- Video hardware uses this address range to identify if the buffers are secure
- or non-secure.
-- vidc-ns-map : start and size of device virtual address range for non-secure buffers.
- Video hardware uses this address range to identify if the buffers are secure
- or non-secure.
-- load-freq-tbl : load (in macroblocks/sec) and corresponding vcodec clock
- required for optimal performance in descending order.
-- reg-presets : list of offset-value pairs for registers to be written. The
- offsets are from the base offset specified in 'reg'. This is mainly used
- for QoS, vbif, etc. presets for video.
+- qcom,vidc-cp-map : start and size of device virtual address range for
+ secure buffers. Video hardware uses this address range to identify if
+ the buffers are secure or non-secure.
+- qcom,vidc-ns-map : start and size of device virtual address range for
+ non-secure buffers. Video hardware uses this address range to identify
+ if the buffers are secure or non-secure.
+- qcom,load-freq-tbl : load (in macroblocks/sec) and corresponding vcodec
+ clock required for optimal performance in descending order.
+- qcom,reg-presets : list of offset-value pairs for registers to be written.
+ The offsets are from the base offset specified in 'reg'. This is mainly
+ used for QoS, vbif, etc. presets for video.
+- qcom,bus-ports : number of bus ports supported by venus to access
+ ddr/ocmem.
+- qcom,enc-ocmem-ab-ib : list of bus vectors (ab, ib pair) for ocmem
+ bandwidth request by different video encoder usecases.
+- qcom,dec-ocmem-ab-ib : list of bus vectors(ab, ib pair) for ocmem
+ bandwidth request by different video decoder usecases.
+- qcom,enc-ddr-ab-ib : list of bus vectors(ab,ib pair) for ddr bandwidth
+ request by different video encoder usecases.
+- qcom,dec-ddr-ab-ib : list of bus vectors(ab, ib pair) for ddr bandwidth
+ request by different video decoder usecases.
Example:
@@ -29,15 +39,24 @@
compatible = "qcom,msm-vidc";
reg = <0xfdc00000 0xff000>;
interrupts = <0 44 0>;
- vidc-cp-map = <0x1000000 0x40000000>;
- vidc-ns-map = <0x40000000 0x40000000>;
- load-freq-tbl = <979200 410000000>,
+ qcom,vidc-cp-map = <0x1000000 0x40000000>;
+ qcom,vidc-ns-map = <0x40000000 0x40000000>;
+ qcom,load-freq-tbl = <979200 410000000>,
<560145 266670000>,
<421161 200000000>,
<243000 133330000>,
<108000 100000000>,
<36000 50000000>;
- hfi = "venus";
- reg-presets = <0x80004 0x1>,
+ qcom,hfi = "venus";
+ qcom,reg-presets = <0x80004 0x1>,
<0x80178 0x00001FFF>;
+ qcom,bus-ports = <1>;
+ qcom,enc-ocmem-ab-ib = <0 0>,
+ <138200 1222000>;
+ qcom,dec-ocmem-ab-ib = <0 0>,
+ <176900 1556640>;
+ qcom,enc-ddr-ab-ib = <0 0>,
+ <60000 664950>;
+ qcom,dec-ddr-ab-ib = <0 0>,
+ <110000 909000>;
};
diff --git a/arch/arm/boot/dts/msm8226-gpu.dtsi b/arch/arm/boot/dts/msm8226-gpu.dtsi
new file mode 100644
index 0000000..76e934e
--- /dev/null
+++ b/arch/arm/boot/dts/msm8226-gpu.dtsi
@@ -0,0 +1,62 @@
+/* Copyright (c) 2013, 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/ "msm8974-gpu.dtsi"
+
+&msm_gpu {
+ qcom,chipid = <0x03000510>;
+
+ qcom,msm-bus,vectors-KBps =
+ <26 512 0 0>, <89 604 0 0>,
+ <26 512 0 1600000>, <89 604 0 6400000>,
+ <26 512 0 3200000>, <89 604 0 12800000>,
+ <26 512 0 4264000>, <89 604 0 12800000>;
+
+ /* GDSC oxili regulators */
+ vddcx-supply = "\0";
+ vdd-supply = <&gdsc_oxili_cx>;
+
+ qcom,gpu-pwrlevels {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ compatible = "qcom,gpu-pwrlevels";
+
+ qcom,gpu-pwrlevel@0 {
+ reg = <0>;
+ qcom,gpu-freq = <450000000>;
+ qcom,bus-freq = <3>;
+ qcom,io-fraction = <0>;
+ };
+
+ qcom,gpu-pwrlevel@1 {
+ reg = <1>;
+ qcom,gpu-freq = <320000000>;
+ qcom,bus-freq = <2>;
+ qcom,io-fraction = <33>;
+ };
+
+ qcom,gpu-pwrlevel@2 {
+ reg = <2>;
+ qcom,gpu-freq = <200000000>;
+ qcom,bus-freq = <1>;
+ qcom,io-fraction = <100>;
+ };
+
+ qcom,gpu-pwrlevel@3 {
+ reg = <3>;
+ qcom,gpu-freq = <19000000>;
+ qcom,bus-freq = <0>;
+ qcom,io-fraction = <0>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/msm8226.dtsi b/arch/arm/boot/dts/msm8226.dtsi
index 708ab23..cb33a40 100644
--- a/arch/arm/boot/dts/msm8226.dtsi
+++ b/arch/arm/boot/dts/msm8226.dtsi
@@ -16,6 +16,7 @@
/include/ "msm8226-iommu.dtsi"
/include/ "msm8226-pm.dtsi"
/include/ "msm8226-smp2p.dtsi"
+/include/ "msm8226-gpu.dtsi"
/ {
model = "Qualcomm MSM 8226";
diff --git a/arch/arm/boot/dts/msm8974-cdp.dtsi b/arch/arm/boot/dts/msm8974-cdp.dtsi
index c3df71a..6b902d7 100644
--- a/arch/arm/boot/dts/msm8974-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8974-cdp.dtsi
@@ -202,21 +202,6 @@
startup-delay-us = <17000>;
enable-active-high;
};
-
- hsic@f9a00000 {
- compatible = "qcom,hsic-host";
- reg = <0xf9a00000 0x400>;
- interrupts = <0 136 0>;
- interrupt-names = "core_irq";
- HSIC_VDDCX-supply = <&pm8841_s2>;
- HSIC_GDSC-supply = <&gdsc_usb_hsic>;
- hsic,strobe-gpio = <&msmgpio 144 0x00>;
- hsic,data-gpio = <&msmgpio 145 0x00>;
- hsic,ignore-cal-pad-config;
- hsic,strobe-pad-offset = <0x2050>;
- hsic,data-pad-offset = <0x2054>;
- };
-
};
&spmi_bus {
diff --git a/arch/arm/boot/dts/msm8974-fluid.dtsi b/arch/arm/boot/dts/msm8974-fluid.dtsi
index 42d2b12..a6086f0 100644
--- a/arch/arm/boot/dts/msm8974-fluid.dtsi
+++ b/arch/arm/boot/dts/msm8974-fluid.dtsi
@@ -118,6 +118,7 @@
avcc_12-supply = <&pm8941_l2>;
smps3a-supply = <&pm8941_s3>;
vdda-supply = <&pm8941_l12>;
+ qcom,hdmi-tx-map = <&mdss_hdmi_tx>;
};
isa1200@48 {
diff --git a/arch/arm/boot/dts/msm8974-mdss.dtsi b/arch/arm/boot/dts/msm8974-mdss.dtsi
index 246286e..0b95419 100644
--- a/arch/arm/boot/dts/msm8974-mdss.dtsi
+++ b/arch/arm/boot/dts/msm8974-mdss.dtsi
@@ -11,7 +11,7 @@
*/
/ {
- qcom,mdss_mdp@fd900000 {
+ mdss_mdp: qcom,mdss_mdp@fd900000 {
compatible = "qcom,mdss_mdp";
reg = <0xfd900000 0x22100>,
<0xfd924000 0x1000>;
@@ -19,6 +19,37 @@
interrupts = <0 72 0>;
vdd-supply = <&gdsc_mdss>;
+ qcom,mdss-pipe-vig-off = <0x00001200 0x00001600
+ 0x00001A00>;
+ qcom,mdss-pipe-rgb-off = <0x00001E00 0x00002200
+ 0x00002600>;
+ qcom,mdss-pipe-dma-off = <0x00002A00 0x00002E00>;
+ qcom,mdss-pipe-vig-fetch-id = <1 4 7>;
+ qcom,mdss-pipe-rgb-fetch-id = <16 17 18>;
+ qcom,mdss-pipe-dma-fetch-id = <10 13>;
+
+ qcom,mdss-ctl-off = <0x00000600 0x00000700 0x00000800
+ 0x00000900 0x0000A00>;
+ qcom,mdss-mixer-intf-off = <0x00003200 0x00003600
+ 0x00003A00>;
+ qcom,mdss-mixer-wb-off = <0x00003E00 0x00004200>;
+ qcom,mdss-dspp-off = <0x00004600 0x00004A00 0x00004E00>;
+ qcom,mdss-wb-off = <0x00011100 0x00013100 0x00015100
+ 0x00017100 0x00019100>;
+ qcom,mdss-intf-off = <0x00021100 0x00021300
+ 0x00021500 0x00021700>;
+
+ qcom,vbif-settings = <0x0004 0x00000001>,
+ <0x00D8 0x00000707>,
+ <0x00F0 0x00000030>,
+ <0x0124 0x00000001>,
+ <0x0178 0x00000FFF>,
+ <0x017C 0x0FFF0FFF>,
+ <0x0160 0x22222222>,
+ <0x0164 0x00002222>;
+ qcom,mdp-settings = <0x02E0 0x000000AA>,
+ <0x02E4 0x00000055>;
+
mdss_fb0: qcom,mdss_fb_primary {
cell-index = <0>;
compatible = "qcom,mdss-fb";
@@ -59,7 +90,7 @@
qcom,mdss-fb-map = <&mdss_fb0>;
};
- qcom,hdmi_tx@fd922100 {
+ mdss_hdmi_tx: qcom,hdmi_tx@fd922100 {
cell-index = <0>;
compatible = "qcom,hdmi-tx";
reg = <0xfd922100 0x35C>,
diff --git a/arch/arm/boot/dts/msm8974-pm.dtsi b/arch/arm/boot/dts/msm8974-pm.dtsi
index 6773ab8..f9b9e33 100644
--- a/arch/arm/boot/dts/msm8974-pm.dtsi
+++ b/arch/arm/boot/dts/msm8974-pm.dtsi
@@ -185,7 +185,7 @@
reg = <0x0>;
qcom,mode = <0>; /* MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT */
qcom,xo = <1>; /* ON */
- qcom,l2 = <2>; /* Retention */
+ qcom,l2 = <3>; /* ACTIVE */
qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
qcom,vdd-mem-lower-bound = <950000>; /* NORMAL */
qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
@@ -202,7 +202,7 @@
reg = <0x1>;
qcom,mode = <4>; /* MSM_PM_SLEEP_MODE_RETENTION*/
qcom,xo = <1>; /* ON */
- qcom,l2 = <2>; /* Retention */
+ qcom,l2 = <3>; /* ACTIVE */
qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
qcom,vdd-mem-lower-bound = <950000>; /* NORMAL */
qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
@@ -215,11 +215,12 @@
qcom,time-overhead = <105>;
};
+
qcom,lpm-level@2 {
reg = <0x2>;
qcom,mode = <2>; /* MSM_PM_SLEEP_MODE_STANDALONE_POWER_COLLAPSE */
qcom,xo = <1>; /* ON */
- qcom,l2 = <2>; /* Retention */
+ qcom,l2 = <3>; /* ACTIVE */
qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
qcom,vdd-mem-lower-bound = <950000>; /* NORMAL */
qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
@@ -253,7 +254,7 @@
reg = <0x4>;
qcom,mode = <3>; /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
qcom,xo = <1>; /* ON */
- qcom,l2 = <1>; /* GDHS */
+ qcom,l2 = <0>; /* OFF */
qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
qcom,vdd-mem-lower-bound = <950000>; /* SVS SOC */
qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
@@ -283,9 +284,24 @@
qcom,lpm-level@6 {
reg = <0x6>;
+ qcom,mode = <3>; /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
+ qcom,xo = <0>; /* OFF */
+ qcom,l2 = <0>; /* OFF */
+ qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
+ qcom,vdd-mem-lower-bound = <950000>; /* NORMAL */
+ qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
+ qcom,vdd-dig-lower-bound = <4>; /* NORMAL */
+ qcom,latency-us = <10300>;
+ qcom,ss-power = <63>;
+ qcom,energy-overhead = <2128000>;
+ qcom,time-overhead = <18200>;
+ };
+
+ qcom,lpm-level@7 {
+ reg = <0x7>;
qcom,mode= <3>; /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
qcom,xo = <0>; /* OFF */
- qcom,l2 = <1>; /* GDHS */
+ qcom,l2 = <0>; /* OFF */
qcom,vdd-mem-upper-bound = <950000>; /* NORMAL */
qcom,vdd-mem-lower-bound = <950000>; /* SVS SOC */
qcom,vdd-dig-upper-bound = <4>; /* NORMAL */
@@ -296,8 +312,8 @@
qcom,time-overhead = <27000>;
};
- qcom,lpm-level@7 {
- reg = <0x7>;
+ qcom,lpm-level@8 {
+ reg = <0x8>;
qcom,mode= <3>; /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
qcom,xo = <0>; /* OFF */
qcom,l2 = <0>; /* OFF */
diff --git a/arch/arm/boot/dts/msm8974-v2.dtsi b/arch/arm/boot/dts/msm8974-v2.dtsi
index d777e3d..09f559d 100644
--- a/arch/arm/boot/dts/msm8974-v2.dtsi
+++ b/arch/arm/boot/dts/msm8974-v2.dtsi
@@ -48,3 +48,14 @@
/* Turbo */
<26 512 0 7464000>, <89 604 0 6400000>;
};
+
+&mdss_mdp {
+ qcom,vbif-settings = <0x0004 0x00000001>;
+ qcom,mdp-settings = <0x02E0 0x000000A9>,
+ <0x02E4 0x00000055>;
+
+ qcom,mdss-wb-off = <0x00011100 0x00011500
+ 0x00011900 0x00011D00 0x00012100>;
+ qcom,mdss-intf-off = <0x00012500 0x00012700
+ 0x00012900 0x00012b00>;
+};
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index e67464a..b63b50f 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -65,14 +65,14 @@
compatible = "qcom,msm-vidc";
reg = <0xfdc00000 0xff000>;
interrupts = <0 44 0>;
- vidc-cp-map = <0x1000000 0x3f000000>;
- vidc-ns-map = <0x40000000 0x40000000>;
- load-freq-tbl = <979200 410000000>,
+ qcom,vidc-cp-map = <0x1000000 0x3f000000>;
+ qcom,vidc-ns-map = <0x40000000 0x40000000>;
+ qcom,load-freq-tbl = <979200 410000000>,
<783360 410000000>,
<489600 266670000>,
<244800 133330000>;
- hfi = "venus";
- reg-presets = <0x80004 0x1>,
+ qcom,hfi = "venus";
+ qcom,reg-presets = <0x80004 0x1>,
<0x80178 0x00001FFF>,
<0x8017c 0x1FFF1FFF>,
<0x800b0 0x10101001>,
@@ -91,6 +91,35 @@
<0x80124 0x00000001>,
<0xE0020 0x5555556>,
<0xE0024 0x0>;
+ qcom,bus-ports = <1>;
+ qcom,enc-ocmem-ab-ib = <0 0>,
+ <138200 1222000>,
+ <414700 1222000>,
+ <940000 2444000>,
+ <1880000 2444000>,
+ <3008000 3910400>,
+ <3760000 4888000>;
+ qcom,dec-ocmem-ab-ib = <0 0>,
+ <176900 1556640>,
+ <456200 1556640>,
+ <864800 1556640>,
+ <1729600 3113280>,
+ <2767360 4981248>,
+ <3459200 6226560>;
+ qcom,enc-ddr-ab-ib = <0 0>,
+ <60000 664950>,
+ <181000 664950>,
+ <403000 664950>,
+ <806000 1329900>,
+ <1289600 2127840>,
+ <161200 6400000>;
+ qcom,dec-ddr-ab-ib = <0 0>,
+ <110000 909000>,
+ <268000 909000>,
+ <505000 909000>,
+ <1010000 1818000>,
+ <1616000 2908800>,
+ <2020000 6400000>;
};
qcom,wfd {
diff --git a/arch/arm/configs/msm8974-perf_defconfig b/arch/arm/configs/msm8974-perf_defconfig
index 5f3e89b..bd7c1a0 100644
--- a/arch/arm/configs/msm8974-perf_defconfig
+++ b/arch/arm/configs/msm8974-perf_defconfig
@@ -458,3 +458,4 @@
CONFIG_SW_SYNC=y
CONFIG_MOBICORE_SUPPORT=m
CONFIG_MOBICORE_API=m
+CONFIG_DEFAULT_ROW=y
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index 19c673e..2f2e0b3 100644
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -475,3 +475,4 @@
CONFIG_CRYPTO_DEV_QCE=m
CONFIG_CRYPTO_DEV_QCEDEV=m
CONFIG_CRC_CCITT=y
+CONFIG_DEFAULT_ROW=y
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index 4f32543..887f7cc 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -824,6 +824,7 @@
static DEFINE_CLK_BRANCH_VOTER(cxo_pil_mss_clk, &cxo_clk_src.c);
static DEFINE_CLK_BRANCH_VOTER(cxo_wlan_clk, &cxo_clk_src.c);
static DEFINE_CLK_BRANCH_VOTER(cxo_pil_pronto_clk, &cxo_clk_src.c);
+static DEFINE_CLK_BRANCH_VOTER(cxo_dwc3_clk, &cxo_clk_src.c);
static struct clk_freq_tbl ftbl_gcc_usb30_master_clk[] = {
F(125000000, gpll0, 1, 5, 24),
@@ -5279,6 +5280,7 @@
CLK_LOOKUP("xo", cxo_pil_mss_clk.c, "fc880000.qcom,mss"),
CLK_LOOKUP("xo", cxo_wlan_clk.c, "fb000000.qcom,wcnss-wlan"),
CLK_LOOKUP("xo", cxo_pil_pronto_clk.c, "fb21b000.qcom,pronto"),
+ CLK_LOOKUP("xo", cxo_dwc3_clk.c, "msm_dwc3"),
CLK_LOOKUP("measure", measure_clk.c, "debug"),
diff --git a/arch/arm/mach-msm/iommu_domains.c b/arch/arm/mach-msm/iommu_domains.c
index dc67403..ff9d86f 100644
--- a/arch/arm/mach-msm/iommu_domains.c
+++ b/arch/arm/mach-msm/iommu_domains.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2013, 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
@@ -474,7 +474,7 @@
const struct device_node *node)
{
unsigned int ret_val = 0;
- unsigned int i;
+ unsigned int i, j;
struct msm_iova_layout l;
struct msm_iova_partition *part = 0;
struct iommu_domain *domain = 0;
@@ -512,9 +512,9 @@
goto free_mem;
}
- for (i = 0; i < l.npartitions * 2; i += 2) {
- part[i].start = addr_array[i];
- part[i].size = addr_array[i+1];
+ for (i = 0, j = 0; j < l.npartitions * 2; i++, j += 2) {
+ part[i].start = addr_array[j];
+ part[i].size = addr_array[j+1];
}
} else {
l.npartitions = 1;
diff --git a/arch/arm/mach-msm/socinfo.c b/arch/arm/mach-msm/socinfo.c
index 5bc4933..19e48759 100644
--- a/arch/arm/mach-msm/socinfo.c
+++ b/arch/arm/mach-msm/socinfo.c
@@ -246,6 +246,7 @@
[117] = MSM_CPU_8930,
[118] = MSM_CPU_8930,
[119] = MSM_CPU_8930,
+ [179] = MSM_CPU_8930,
/* 8627 IDs */
[120] = MSM_CPU_8627,
@@ -301,6 +302,7 @@
[143] = MSM_CPU_8930AA,
[144] = MSM_CPU_8930AA,
[160] = MSM_CPU_8930AA,
+ [180] = MSM_CPU_8930AA,
/* 8226 IDs */
[145] = MSM_CPU_8226,
@@ -319,6 +321,7 @@
[155] = MSM_CPU_8930AB,
[156] = MSM_CPU_8930AB,
[157] = MSM_CPU_8930AB,
+ [181] = MSM_CPU_8930AB,
/* 8625Q IDs */
[168] = MSM_CPU_8625Q,
diff --git a/block/test-iosched.c b/block/test-iosched.c
index 23c9581..c4cfb17 100644
--- a/block/test-iosched.c
+++ b/block/test-iosched.c
@@ -576,7 +576,7 @@
return ret;
}
- __blk_run_queue(td->req_q);
+ blk_run_queue(td->req_q);
return 0;
}
@@ -800,7 +800,7 @@
* Wakeup the queue thread to fetch FS requests that might got
* postponded due to the test
*/
- __blk_run_queue(ptd->req_q);
+ blk_run_queue(ptd->req_q);
if (ptd->ignore_round)
test_pr_info(
diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c
index 2bc0de3..23dd5a1 100644
--- a/drivers/char/diag/diag_dci.c
+++ b/drivers/char/diag/diag_dci.c
@@ -152,7 +152,8 @@
uint16_t event_id, event_id_packet;
uint8_t *event_mask_ptr, byte_mask, payload_len;
uint8_t event_data[MAX_EVENT_SIZE], timestamp[8];
- int i, byte_index, bit_index, length, temp_len;
+ unsigned int byte_index;
+ int i, bit_index, length, temp_len;
int total_event_len, payload_len_field, timestamp_len;
struct diag_dci_client_tbl *entry;
@@ -227,7 +228,8 @@
{
uint16_t log_code, item_num;
uint8_t equip_id, *log_mask_ptr, byte_mask;
- int i, byte_index, found = 0;
+ unsigned int byte_index;
+ int i, found = 0;
struct diag_dci_client_tbl *entry;
log_code = *(uint16_t *)(buf+6);
@@ -385,6 +387,10 @@
/* remove UID from user space pkt before sending to peripheral */
buf = buf + 4;
+ if (len > APPS_BUF_SIZE - 10) {
+ pr_err("diag: dci: buffer overwrite possible since payload bigger than buf size\n");
+ return -EIO;
+ }
len = len - 4;
mutex_lock(&driver->dci_mutex);
/* prepare DCI packet */
@@ -396,7 +402,6 @@
driver->req_tracking_tbl[index].tag;
for (i = 0; i < len; i++)
driver->apps_dci_buf[i+9] = *(buf+i);
-
driver->apps_dci_buf[9+len] = CONTROL_CHAR; /* end */
for (i = 0; i < NUM_SMD_DCI_CHANNELS; i++) {
@@ -448,12 +453,12 @@
{
unsigned char *temp = buf;
uint16_t subsys_cmd_code, log_code, item_num;
- int subsys_id, cmd_code, i, ret = -1, index = -1, found = 0;
+ int subsys_id, cmd_code, ret = -1, index = -1, found = 0, read_len = 0;
struct diag_master_table entry;
- int count, set_mask, num_codes, byte_index, bit_index, event_id;
+ int count, set_mask, num_codes, bit_index, event_id, offset = 0, i;
+ unsigned int byte_index;
uint8_t equip_id, *log_mask_ptr, *head_log_mask_ptr, byte_mask;
uint8_t *event_mask_ptr;
- int offset = 0;
if (!driver->smd_dci[MODEM_DATA].ch) {
pr_err("diag: DCI smd channel for peripheral %d not valid for dci updates\n",
@@ -529,19 +534,30 @@
}
/* Extract each log code and put in client table */
temp += 4;
+ read_len += 4;
set_mask = *(int *)temp;
temp += 4;
+ read_len += 4;
num_codes = *(int *)temp;
temp += 4;
+ read_len += 4;
head_log_mask_ptr = driver->dci_client_tbl[i].dci_log_mask;
pr_debug("diag: head of dci log mask %p\n", head_log_mask_ptr);
count = 0; /* iterator for extracting log codes */
while (count < num_codes) {
+ if (read_len >= USER_SPACE_DATA) {
+ pr_err("diag: dci: Log type, possible buffer overflow\n");
+ return -EIO;
+ }
log_code = *(uint16_t *)temp;
equip_id = LOG_GET_EQUIP_ID(log_code);
item_num = LOG_GET_ITEM_NUM(log_code);
byte_index = item_num/8 + 2;
+ if (byte_index >= (DCI_MAX_ITEMS_PER_LOG_CODE+2)) {
+ pr_err("diag: dci: Log type, invalid byte index\n");
+ return ret;
+ }
byte_mask = 0x01 << (item_num % 8);
/*
* Parse through log mask table and find
@@ -550,7 +566,7 @@
log_mask_ptr = head_log_mask_ptr;
found = 0;
offset = 0;
- while (log_mask_ptr) {
+ while (log_mask_ptr && (offset < DCI_LOG_MASK_SIZE)) {
if (*log_mask_ptr == equip_id) {
found = 1;
pr_debug("diag: find equip id = %x at %p\n",
@@ -578,6 +594,7 @@
offset, byte_index,
byte_mask);
temp += 2;
+ read_len += 2;
count++;
ret = DIAG_DCI_NO_ERROR;
}
@@ -600,17 +617,28 @@
}
/* Extract each log code and put in client table */
temp += 4;
+ read_len += 4;
set_mask = *(int *)temp;
temp += 4;
+ read_len += 4;
num_codes = *(int *)temp;
temp += 4;
+ read_len += 4;
event_mask_ptr = driver->dci_client_tbl[i].dci_event_mask;
pr_debug("diag: head of dci event mask %p\n", event_mask_ptr);
count = 0; /* iterator for extracting log codes */
while (count < num_codes) {
+ if (read_len >= USER_SPACE_DATA) {
+ pr_err("diag: dci: Event type, possible buffer overflow\n");
+ return -EIO;
+ }
event_id = *(int *)temp;
byte_index = event_id/8;
+ if (byte_index >= DCI_EVENT_MASK_SIZE) {
+ pr_err("diag: dci: Event type, invalid byte index\n");
+ return ret;
+ }
bit_index = event_id % 8;
byte_mask = 0x1 << bit_index;
/*
@@ -624,6 +652,7 @@
/* add to cumulative mask */
update_dci_cumulative_event_mask(byte_index, byte_mask);
temp += sizeof(int);
+ read_len += sizeof(int);
count++;
ret = DIAG_DCI_NO_ERROR;
}
@@ -704,7 +733,7 @@
return ret;
}
-void update_dci_cumulative_log_mask(int offset, int byte_index,
+void update_dci_cumulative_log_mask(int offset, unsigned int byte_index,
uint8_t byte_mask)
{
int i;
diff --git a/drivers/char/diag/diag_dci.h b/drivers/char/diag/diag_dci.h
index 69d393b..56d1b91 100644
--- a/drivers/char/diag/diag_dci.h
+++ b/drivers/char/diag/diag_dci.h
@@ -88,7 +88,7 @@
void extract_dci_pkt_rsp(unsigned char *buf);
/* DCI Log streaming functions */
void create_dci_log_mask_tbl(unsigned char *tbl_buf);
-void update_dci_cumulative_log_mask(int offset, int byte_index,
+void update_dci_cumulative_log_mask(int offset, unsigned int byte_index,
uint8_t byte_mask);
int diag_send_dci_log_mask(smd_channel_t *ch);
void extract_dci_log(unsigned char *buf);
diff --git a/drivers/char/diag/diag_masks.c b/drivers/char/diag/diag_masks.c
index e8567db..0c93101 100644
--- a/drivers/char/diag/diag_masks.c
+++ b/drivers/char/diag/diag_masks.c
@@ -525,6 +525,10 @@
*(int *)(driver->apps_rsp_buf + 4) = 0x3; /* op. ID */
*(int *)(driver->apps_rsp_buf + 8) = 0x0; /* success */
payload_length = 8 + ((*(int *)(buf + 4)) + 7)/8;
+ if (payload_length > APPS_BUF_SIZE - 12) {
+ pr_err("diag: log masks: buffer overflow\n");
+ return -EIO;
+ }
for (i = 0; i < payload_length; i++)
*(int *)(driver->apps_rsp_buf+12+i) = *(buf+i);
@@ -608,6 +612,10 @@
rt_last_ssid) {
rt_mask_size = 4 * (rt_last_ssid -
rt_first_ssid + 1);
+ if (rt_mask_size > APPS_BUF_SIZE - 8) {
+ pr_err("diag: rt masks: buffer overflow\n");
+ return -EIO;
+ }
memcpy(driver->apps_rsp_buf+8,
rt_mask_ptr, rt_mask_size);
encode_rsp_and_send(8+rt_mask_size-1);
@@ -621,7 +629,17 @@
else if ((*buf == 0x7d) && (*(buf+1) == 0x4)) {
ssid_first = *(uint16_t *)(buf + 2);
ssid_last = *(uint16_t *)(buf + 4);
+ if (ssid_last < ssid_first) {
+ pr_err("diag: Invalid msg mask ssid values, first: %d, last: %d\n",
+ ssid_first, ssid_last);
+ return -EIO;
+ }
ssid_range = 4 * (ssid_last - ssid_first + 1);
+ if (ssid_range > APPS_BUF_SIZE - 8) {
+ pr_err("diag: Not enough space for message mask, ssid_range: %d\n",
+ ssid_range);
+ return -EIO;
+ }
pr_debug("diag: received mask update for ssid_first = %d, ssid_last = %d",
ssid_first, ssid_last);
diag_update_msg_mask(ssid_first, ssid_last , buf + 8);
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index 8b0640d..13e52df 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -153,7 +153,7 @@
/* Return the buffer to the pool */
diagmem_free(driver, (unsigned char *)
(diag_hsic[j].hsic_buf_tbl[i].
- buf), POOL_TYPE_HSIC);
+ buf), j+POOL_TYPE_HSIC);
diag_hsic[j].hsic_buf_tbl[i].buf = 0;
}
diag_hsic[j].hsic_buf_tbl[i].length = 0;
@@ -490,7 +490,7 @@
/* Return the buffer to the pool */
diagmem_free(driver,
(unsigned char *)(hsic_buf_tbl[i].buf),
- POOL_TYPE_HSIC);
+ index+POOL_TYPE_HSIC);
/* Call the write complete function */
diagfwd_write_complete_hsic(NULL, index);
@@ -691,8 +691,10 @@
return -ENOMEM;
}
if (copy_from_user(dci_params, (void *)ioarg,
- sizeof(struct diag_dci_client_tbl)))
+ sizeof(struct diag_dci_client_tbl))) {
+ kfree(dci_params);
return -EFAULT;
+ }
mutex_lock(&driver->dci_mutex);
if (!(driver->num_dci_client))
for (i = 0; i < NUM_SMD_DCI_CHANNELS; i++)
@@ -724,8 +726,8 @@
break;
}
}
- mutex_unlock(&driver->dci_mutex);
kfree(dci_params);
+ mutex_unlock(&driver->dci_mutex);
return driver->dci_client_id;
} else if (iocmd == DIAG_IOCTL_DCI_DEINIT) {
success = -1;
@@ -1197,6 +1199,10 @@
if (pkt_type == USER_SPACE_DATA_TYPE) {
err = copy_from_user(driver->user_space_data, buf + 4,
payload_size);
+ if (err) {
+ pr_err("diag: copy failed for user space data\n");
+ return -EIO;
+ }
/* Check for proc_type */
remote_proc = diag_get_remote(*(int *)driver->user_space_data);
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index 4ec222b..7f4edd1 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -611,13 +611,15 @@
int packet_type = 1, i, cmd_code;
unsigned char *temp = buf;
int data_type;
+ int mask_ret;
#if defined(CONFIG_DIAG_OVER_USB)
unsigned char *ptr;
#endif
/* Check if the command is a supported mask command */
- if (diag_process_apps_masks(buf, len) == 0)
- return 0;
+ mask_ret = diag_process_apps_masks(buf, len);
+ if (mask_ret <= 0)
+ return mask_ret;
/* Check for registered clients and forward packet to apropriate proc */
cmd_code = (int)(*(char *)buf);
@@ -991,10 +993,16 @@
ret = diag_hdlc_decode(&hdlc);
- if (ret)
+ if (hdlc.dest_idx < 3) {
+ pr_err("diag: Integer underflow in hdlc processing\n");
+ return;
+ }
+ if (ret) {
type = diag_process_apps_pkt(driver->hdlc_buf,
hdlc.dest_idx - 3);
- else if (driver->debug_flag) {
+ if (type < 0)
+ return;
+ } else if (driver->debug_flag) {
printk(KERN_ERR "Packet dropped due to bad HDLC coding/CRC"
" errors or partial packet received, packet"
" length = %d\n", len);
diff --git a/drivers/crypto/msm/qcrypto.c b/drivers/crypto/msm/qcrypto.c
index 6115c7e..7e063ca 100644
--- a/drivers/crypto/msm/qcrypto.c
+++ b/drivers/crypto/msm/qcrypto.c
@@ -2313,13 +2313,12 @@
struct qcrypto_sha_ctx *sha_ctx = crypto_tfm_ctx(req->base.tfm);
struct crypto_priv *cp = sha_ctx->cp;
struct qcrypto_sha_req_ctx *rctx = ahash_request_ctx(req);
- uint32_t total, len, i, num_sg;
+ uint32_t total, len, num_sg;
+ struct scatterlist *sg_last;
uint8_t *k_src = NULL;
uint32_t sha_pad_len = 0;
- uint32_t end_src = 0;
uint32_t trailing_buf_len = 0;
- uint32_t nbytes, index = 0;
- uint32_t saved_length = 0;
+ uint32_t nbytes;
uint32_t offset = 0;
uint32_t bytes = 0;
@@ -2330,8 +2329,6 @@
len = req->nbytes;
if (total <= sha_block_size) {
- i = 0;
-
k_src = &sha_ctx->trailing_buf[sha_ctx->trailing_buf_len];
num_sg = qcrypto_count_sg(req->src, len);
bytes = sg_copy_to_buffer(req->src, num_sg, k_src, len);
@@ -2364,22 +2361,14 @@
num_sg = qcrypto_count_sg(req->src, req->nbytes);
len = sha_ctx->trailing_buf_len;
- i = 0;
+ sg_last = req->src;
while (len < nbytes) {
- if ((len + req->src[i].length) > nbytes)
+ if ((len + sg_last->length) > nbytes)
break;
- len += req->src[i].length;
- i++;
+ len += sg_last->length;
+ sg_last = scatterwalk_sg_next(sg_last);
}
-
- end_src = i;
- if (len < nbytes) {
- saved_length = req->src[i].length;
- index = i;
- req->src[i].length = (nbytes - len);
- }
-
if (sha_ctx->trailing_buf_len) {
if (cp->ce_support.aligned_only) {
sha_ctx->sg = kzalloc(sizeof(struct scatterlist),
@@ -2399,17 +2388,16 @@
memcpy(rctx->data2, sha_ctx->tmp_tbuf,
sha_ctx->trailing_buf_len);
memcpy((rctx->data2 + sha_ctx->trailing_buf_len),
- rctx->data, req->src[i-1].length);
+ rctx->data, req->src->length);
kfree(rctx->data);
rctx->data = rctx->data2;
sg_set_buf(&sha_ctx->sg[0], rctx->data,
(sha_ctx->trailing_buf_len +
- req->src[i-1].length));
+ req->src->length));
req->src = sha_ctx->sg;
sg_mark_end(&sha_ctx->sg[0]);
-
} else {
- sg_mark_end(&req->src[end_src]);
+ sg_mark_end(sg_last);
sha_ctx->sg = kzalloc(2 * (sizeof(struct scatterlist)),
GFP_KERNEL);
if (sha_ctx->sg == NULL) {
@@ -2425,11 +2413,9 @@
req->src = sha_ctx->sg;
}
} else
- sg_mark_end(&req->src[end_src]);
+ sg_mark_end(sg_last);
req->nbytes = nbytes;
- if (saved_length > 0)
- rctx->src[index].length = saved_length;
sha_ctx->trailing_buf_len = trailing_buf_len;
ret = _qcrypto_queue_req(cp, &req->base);
diff --git a/drivers/gpu/msm/a3xx_reg.h b/drivers/gpu/msm/a3xx_reg.h
index e85e2cc..0127735 100644
--- a/drivers/gpu/msm/a3xx_reg.h
+++ b/drivers/gpu/msm/a3xx_reg.h
@@ -541,6 +541,7 @@
#define A320_RBBM_CLOCK_CTL_DEFAULT 0xBFFFFFFF
#define A330_RBBM_CLOCK_CTL_DEFAULT 0xAAAAAAAE
#define A330v2_RBBM_CLOCK_CTL_DEFAULT 0xBFFCFFFF
+#define A305B_RBBM_CLOCK_CTL_DEFAULT 0xAAAAAAAA
#define A330_RBBM_GPR0_CTL_DEFAULT 0x0AE2B8AE
#define A330v2_RBBM_GPR0_CTL_DEFAULT 0x00000000
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 407bbb3..c495890 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -192,7 +192,7 @@
"a225_pm4.fw", "a225_pfp.fw", &adreno_a2xx_gpudev,
1536, 768, 3, SZ_512K, 0x225011, 0x225002 },
/* A3XX doesn't use the pix_shader_start */
- { ADRENO_REV_A305, 3, 0, 5, ANY_ID,
+ { ADRENO_REV_A305, 3, 0, 5, 0,
"a300_pm4.fw", "a300_pfp.fw", &adreno_a3xx_gpudev,
512, 0, 2, SZ_256K, 0x3FF037, 0x3FF016 },
/* A3XX doesn't use the pix_shader_start */
@@ -202,6 +202,9 @@
{ ADRENO_REV_A330, 3, 3, 0, ANY_ID,
"a330_pm4.fw", "a330_pfp.fw", &adreno_a3xx_gpudev,
512, 0, 2, SZ_1M, NO_VER, NO_VER },
+ { ADRENO_REV_A305B, 3, 0, 5, 0x10,
+ "a330_pm4.fw", "a330_pfp.fw", &adreno_a3xx_gpudev,
+ 512, 0, 2, SZ_128K, NO_VER, NO_VER },
};
static irqreturn_t adreno_irq_handler(struct kgsl_device *device)
@@ -1108,7 +1111,8 @@
static int
adreno_ocmem_gmem_malloc(struct adreno_device *adreno_dev)
{
- if (!adreno_is_a330(adreno_dev))
+ if (!(adreno_is_a330(adreno_dev) ||
+ adreno_is_a305b(adreno_dev)))
return 0;
/* OCMEM is only needed once, do not support consective allocation */
@@ -1129,7 +1133,8 @@
static void
adreno_ocmem_gmem_free(struct adreno_device *adreno_dev)
{
- if (!adreno_is_a330(adreno_dev))
+ if (!(adreno_is_a330(adreno_dev) ||
+ adreno_is_a305b(adreno_dev)))
return;
if (adreno_dev->ocmem_hdl == NULL)
@@ -2290,6 +2295,7 @@
unsigned int curr_reg_val[hang_detect_regs_count];
unsigned int hang_detected = 1;
unsigned int i;
+ static unsigned long next_hang_detect_time;
if (!adreno_dev->fast_hang_detect)
return 0;
@@ -2313,6 +2319,18 @@
return 0;
}
+ /*
+ * Time interval between hang detection should be KGSL_TIMEOUT_PART
+ * or more, if next hang detection is requested < KGSL_TIMEOUT_PART
+ * from the last time do nothing.
+ */
+ if ((next_hang_detect_time) &&
+ (time_before(jiffies, next_hang_detect_time)))
+ return 0;
+ else
+ next_hang_detect_time = (jiffies +
+ msecs_to_jiffies(KGSL_TIMEOUT_PART-1));
+
for (i = 0; i < hang_detect_regs_count; i++) {
if (hang_detect_regs[i] == 0)
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index bbaaec6..cc6eb16 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2008-2013, 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
@@ -72,6 +72,7 @@
ADRENO_REV_A305 = 305,
ADRENO_REV_A320 = 320,
ADRENO_REV_A330 = 330,
+ ADRENO_REV_A305B = 335,
};
struct adreno_gpudev;
@@ -265,6 +266,11 @@
return (adreno_dev->gpurev == ADRENO_REV_A305);
}
+static inline int adreno_is_a305b(struct adreno_device *adreno_dev)
+{
+ return (adreno_dev->gpurev == ADRENO_REV_A305B);
+}
+
static inline int adreno_is_a320(struct adreno_device *adreno_dev)
{
return (adreno_dev->gpurev == ADRENO_REV_A320);
diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c
index d13c200..bbe97de 100644
--- a/drivers/gpu/msm/adreno_a3xx.c
+++ b/drivers/gpu/msm/adreno_a3xx.c
@@ -456,6 +456,8 @@
return A330v2_RBBM_CLOCK_CTL_DEFAULT;
else if (adreno_is_a330(adreno_dev))
return A330_RBBM_CLOCK_CTL_DEFAULT;
+ else if (adreno_is_a305b(adreno_dev))
+ return A305B_RBBM_CLOCK_CTL_DEFAULT;
BUG_ON(1);
}
@@ -2761,6 +2763,11 @@
{0, 0},
};
+static struct a3xx_vbif_data a305b_vbif[] = {
+ { A3XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x0003 },
+ {0, 0},
+};
+
static struct a3xx_vbif_data a320_vbif[] = {
/* Set up 16 deep read/write request queues */
{ A3XX_VBIF_IN_RD_LIM_CONF0, 0x10101010 },
@@ -2840,6 +2847,7 @@
/* A330v2 needs to be ahead of A330 so the right device matches */
{ adreno_is_a330v2, a330v2_vbif },
{ adreno_is_a330, a330_vbif },
+ { adreno_is_a305b, a305b_vbif },
};
static void a3xx_start(struct adreno_device *adreno_dev)
@@ -2901,7 +2909,8 @@
A330_RBBM_GPR0_CTL_DEFAULT);
/* Set the OCMEM base address for A330 */
- if (adreno_is_a330(adreno_dev)) {
+ if (adreno_is_a330(adreno_dev) ||
+ adreno_is_a305b(adreno_dev)) {
adreno_regwrite(device, A3XX_RB_GMEM_BASE_ADDR,
(unsigned int)(adreno_dev->ocmem_base >> 14));
}
diff --git a/drivers/gpu/msm/adreno_a3xx_snapshot.c b/drivers/gpu/msm/adreno_a3xx_snapshot.c
index c3f0ae6..58e3126 100644
--- a/drivers/gpu/msm/adreno_a3xx_snapshot.c
+++ b/drivers/gpu/msm/adreno_a3xx_snapshot.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -214,7 +214,8 @@
int i, size;
/* The size of the ROQ buffer is core dependent */
- size = adreno_is_a330(adreno_dev) ?
+ size = (adreno_is_a330(adreno_dev) ||
+ adreno_is_a305b(adreno_dev)) ?
A330_CP_ROQ_SIZE : A320_CP_ROQ_SIZE;
if (remain < DEBUG_SECTION_SZ(size)) {
@@ -287,7 +288,8 @@
* like CP are larger
*/
- dwords = adreno_is_a330(adreno_dev) ?
+ dwords = (adreno_is_a330(adreno_dev) ||
+ adreno_is_a305b(adreno_dev)) ?
block->dwords : 0x40;
size = (dwords * sizeof(unsigned int)) + sizeof(*header);
@@ -447,7 +449,7 @@
/* Store relevant registers in list to snapshot */
_snapshot_a3xx_regs(regs, &list);
_snapshot_hlsq_regs(regs, &list, adreno_dev);
- if (adreno_is_a330(adreno_dev))
+ if (adreno_is_a330(adreno_dev) || adreno_is_a305b(adreno_dev))
_snapshot_a330_regs(regs, &list);
/* Master set of (non debug) registers */
@@ -458,7 +460,8 @@
/*
* CP_STATE_DEBUG indexed registers - 20 on 305 and 320 and 46 on A330
*/
- size = adreno_is_a330(adreno_dev) ? 0x2E : 0x14;
+ size = (adreno_is_a330(adreno_dev) ||
+ adreno_is_a305b(adreno_dev)) ? 0x2E : 0x14;
snapshot = kgsl_snapshot_indexed_registers(device, snapshot,
remain, REG_CP_STATE_DEBUG_INDEX,
@@ -503,7 +506,8 @@
KGSL_SNAPSHOT_SECTION_DEBUG, snapshot, remain,
a3xx_snapshot_cp_roq, NULL);
- if (adreno_is_a330(adreno_dev)) {
+ if (adreno_is_a330(adreno_dev) ||
+ adreno_is_a305b(adreno_dev)) {
snapshot = kgsl_snapshot_add_section(device,
KGSL_SNAPSHOT_SECTION_DEBUG, snapshot, remain,
a330_snapshot_cp_merciu, NULL);
diff --git a/drivers/gpu/msm/adreno_postmortem.c b/drivers/gpu/msm/adreno_postmortem.c
index d81d72e..2b9c286 100644
--- a/drivers/gpu/msm/adreno_postmortem.c
+++ b/drivers/gpu/msm/adreno_postmortem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2013, 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
@@ -912,7 +912,8 @@
adreno_dump_regs(device, a3xx_registers,
a3xx_registers_count);
- if (adreno_is_a330(adreno_dev))
+ if (adreno_is_a330(adreno_dev) ||
+ adreno_is_a305b(adreno_dev))
adreno_dump_regs(device, a330_registers,
a330_registers_count);
}
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 2e807ac..1d56a0a 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 2010 Samsung Electronics Co.Ltd
* Author: Joonyoung Shim <jy0922.shim@samsung.com>
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, 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 as published by the
@@ -27,7 +27,12 @@
#include <linux/regulator/consumer.h>
#include <linux/string.h>
#include <linux/of_gpio.h>
-#if defined(CONFIG_HAS_EARLYSUSPEND)
+
+#if defined(CONFIG_FB)
+#include <linux/notifier.h>
+#include <linux/fb.h>
+
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
#include <linux/earlysuspend.h>
/* Early-suspend level */
#define MXT_SUSPEND_LEVEL 1
@@ -356,7 +361,9 @@
struct regulator *vcc_ana;
struct regulator *vcc_dig;
struct regulator *vcc_i2c;
-#if defined(CONFIG_HAS_EARLYSUSPEND)
+#if defined(CONFIG_FB)
+ struct notifier_block fb_notif;
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
struct early_suspend early_suspend;
#endif
@@ -2330,24 +2337,8 @@
return 0;
}
-#if defined(CONFIG_HAS_EARLYSUSPEND)
-static void mxt_early_suspend(struct early_suspend *h)
-{
- struct mxt_data *data = container_of(h, struct mxt_data, early_suspend);
-
- mxt_suspend(&data->client->dev);
-}
-
-static void mxt_late_resume(struct early_suspend *h)
-{
- struct mxt_data *data = container_of(h, struct mxt_data, early_suspend);
-
- mxt_resume(&data->client->dev);
-}
-#endif
-
static const struct dev_pm_ops mxt_pm_ops = {
-#ifndef CONFIG_HAS_EARLYSUSPEND
+#if (!defined(CONFIG_FB) && !defined(CONFIG_HAS_EARLYSUSPEND))
.suspend = mxt_suspend,
.resume = mxt_resume,
#endif
@@ -2627,6 +2618,43 @@
}
#endif
+#if defined(CONFIG_FB)
+static int fb_notifier_callback(struct notifier_block *self,
+ unsigned long event, void *data)
+{
+ struct fb_event *evdata = data;
+ int *blank;
+ struct mxt_data *mxt_dev_data =
+ container_of(self, struct mxt_data, fb_notif);
+
+ if (evdata && evdata->data && event == FB_EVENT_BLANK && mxt_dev_data &&
+ mxt_dev_data->client) {
+ blank = evdata->data;
+ if (*blank == FB_BLANK_UNBLANK)
+ mxt_resume(&mxt_dev_data->client->dev);
+ else if (*blank == FB_BLANK_POWERDOWN)
+ mxt_suspend(&mxt_dev_data->client->dev);
+ }
+
+ return 0;
+}
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
+static void mxt_early_suspend(struct early_suspend *h)
+{
+ struct mxt_data *data = container_of(h, struct mxt_data,
+ early_suspend);
+ mxt_suspend(&data->client->dev);
+}
+
+static void mxt_late_resume(struct early_suspend *h)
+{
+ struct mxt_data *data = container_of(h, struct mxt_data,
+ early_suspend);
+ mxt_resume(&data->client->dev);
+}
+
+#endif
+
static int __devinit mxt_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -2794,7 +2822,15 @@
if (error)
goto err_unregister_device;
-#if defined(CONFIG_HAS_EARLYSUSPEND)
+#if defined(CONFIG_FB)
+ data->fb_notif.notifier_call = fb_notifier_callback;
+
+ error = fb_register_client(&data->fb_notif);
+
+ if (error)
+ dev_err(&client->dev, "Unable to register fb_notifier: %d\n",
+ error);
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN +
MXT_SUSPEND_LEVEL;
data->early_suspend.suspend = mxt_early_suspend;
@@ -2842,7 +2878,10 @@
sysfs_remove_group(&client->dev.kobj, &mxt_attr_group);
free_irq(data->irq, data);
input_unregister_device(data->input_dev);
-#if defined(CONFIG_HAS_EARLYSUSPEND)
+#if defined(CONFIG_FB)
+ if (fb_unregister_client(&data->fb_notif))
+ dev_err(&client->dev, "Error occurred while unregistering fb_notifier.\n");
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
unregister_early_suspend(&data->early_suspend);
#endif
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
index b745d8b..81c6626 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
@@ -11,6 +11,7 @@
*/
#include <linux/module.h>
+#include <linux/platform_device.h>
#include <mach/iommu.h>
#include "msm_isp32.h"
@@ -188,10 +189,9 @@
return;
}
-static void msm_vfe32_process_violation_irq(struct vfe_device *vfe_dev)
+static void msm_vfe32_process_violation_status(struct vfe_device *vfe_dev)
{
- uint32_t violation_status;
- violation_status = msm_camera_io_r(vfe_dev->vfe_base + 0x48);
+ uint32_t violation_status = vfe_dev->error_info.violation_status;
if (!violation_status)
return;
@@ -247,63 +247,58 @@
pr_err("%s: realign buf cr violation\n", __func__);
}
-static void msm_vfe32_process_error_irq(struct vfe_device *vfe_dev,
- uint32_t irq_status0, uint32_t irq_status1)
+static void msm_vfe32_process_error_status(struct vfe_device *vfe_dev)
{
- uint32_t camif_status;
- if (!(irq_status1 & 0x7FFFFF))
- return;
+ uint32_t error_status1 = vfe_dev->error_info.error_mask1;
- if (irq_status1 & BIT(0)) {
- camif_status = msm_camera_io_r(vfe_dev->vfe_base + 0x204);
+ if (error_status1 & BIT(0))
pr_err("%s: camif error status: 0x%x\n",
- __func__, camif_status);
- }
- if (irq_status1 & BIT(1))
+ __func__, vfe_dev->error_info.camif_status);
+ if (error_status1 & BIT(1))
pr_err("%s: stats bhist overwrite\n", __func__);
- if (irq_status1 & BIT(2))
+ if (error_status1 & BIT(2))
pr_err("%s: stats cs overwrite\n", __func__);
- if (irq_status1 & BIT(3))
+ if (error_status1 & BIT(3))
pr_err("%s: stats ihist overwrite\n", __func__);
- if (irq_status1 & BIT(4))
+ if (error_status1 & BIT(4))
pr_err("%s: realign buf y overflow\n", __func__);
- if (irq_status1 & BIT(5))
+ if (error_status1 & BIT(5))
pr_err("%s: realign buf cb overflow\n", __func__);
- if (irq_status1 & BIT(6))
+ if (error_status1 & BIT(6))
pr_err("%s: realign buf cr overflow\n", __func__);
- if (irq_status1 & BIT(7)) {
+ if (error_status1 & BIT(7)) {
pr_err("%s: violation\n", __func__);
- msm_vfe32_process_violation_irq(vfe_dev);
+ msm_vfe32_process_violation_status(vfe_dev);
}
- if (irq_status1 & BIT(8))
+ if (error_status1 & BIT(8))
pr_err("%s: image master 0 bus overflow\n", __func__);
- if (irq_status1 & BIT(9))
+ if (error_status1 & BIT(9))
pr_err("%s: image master 1 bus overflow\n", __func__);
- if (irq_status1 & BIT(10))
+ if (error_status1 & BIT(10))
pr_err("%s: image master 2 bus overflow\n", __func__);
- if (irq_status1 & BIT(11))
+ if (error_status1 & BIT(11))
pr_err("%s: image master 3 bus overflow\n", __func__);
- if (irq_status1 & BIT(12))
+ if (error_status1 & BIT(12))
pr_err("%s: image master 4 bus overflow\n", __func__);
- if (irq_status1 & BIT(13))
+ if (error_status1 & BIT(13))
pr_err("%s: image master 5 bus overflow\n", __func__);
- if (irq_status1 & BIT(14))
+ if (error_status1 & BIT(14))
pr_err("%s: image master 6 bus overflow\n", __func__);
- if (irq_status1 & BIT(15))
+ if (error_status1 & BIT(15))
pr_err("%s: status ae/bg bus overflow\n", __func__);
- if (irq_status1 & BIT(16))
+ if (error_status1 & BIT(16))
pr_err("%s: status af/bf bus overflow\n", __func__);
- if (irq_status1 & BIT(17))
+ if (error_status1 & BIT(17))
pr_err("%s: status awb bus overflow\n", __func__);
- if (irq_status1 & BIT(18))
+ if (error_status1 & BIT(18))
pr_err("%s: status rs bus overflow\n", __func__);
- if (irq_status1 & BIT(19))
+ if (error_status1 & BIT(19))
pr_err("%s: status cs bus overflow\n", __func__);
- if (irq_status1 & BIT(20))
+ if (error_status1 & BIT(20))
pr_err("%s: status ihist bus overflow\n", __func__);
- if (irq_status1 & BIT(21))
+ if (error_status1 & BIT(21))
pr_err("%s: status skin bhist bus overflow\n", __func__);
- if (irq_status1 & BIT(22))
+ if (error_status1 & BIT(22))
pr_err("%s: axi error\n", __func__);
}
@@ -315,6 +310,14 @@
msm_camera_io_w(*irq_status0, vfe_dev->vfe_base + 0x24);
msm_camera_io_w(*irq_status1, vfe_dev->vfe_base + 0x28);
msm_camera_io_w_mb(1, vfe_dev->vfe_base + 0x18);
+
+ if (*irq_status1 & BIT(0))
+ vfe_dev->error_info.camif_status =
+ msm_camera_io_r(vfe_dev->vfe_base + 0x204);
+
+ if (*irq_status1 & BIT(7))
+ vfe_dev->error_info.violation_status |=
+ msm_camera_io_r(vfe_dev->vfe_base + 0x7B4);
}
static void msm_vfe32_process_reg_update(struct vfe_device *vfe_dev,
@@ -327,6 +330,7 @@
msm_isp_axi_stream_update(vfe_dev);
msm_isp_update_framedrop_reg(vfe_dev);
+ msm_isp_update_error_frame_count(vfe_dev);
return;
}
@@ -819,6 +823,13 @@
return rc;
}
+static void msm_vfe32_get_error_mask(uint32_t *error_mask0,
+ uint32_t *error_mask1)
+{
+ *error_mask0 = 0x00000000;
+ *error_mask1 = 0x007FFFFF;
+}
+
struct msm_vfe_axi_hardware_info msm_vfe32_axi_hw_info = {
.num_wm = 7,
.num_comp_mask = 3,
@@ -849,7 +860,6 @@
.process_camif_irq = msm_vfe32_process_camif_irq,
.process_reset_irq = msm_vfe32_process_reset_irq,
.process_halt_irq = msm_vfe32_process_halt_irq,
- .process_error_irq = msm_vfe32_process_error_irq,
.process_reg_update = msm_vfe32_process_reg_update,
.process_axi_irq = msm_isp_process_axi_irq,
.process_stats_irq = msm_vfe32_process_stats_irq,
@@ -885,6 +895,8 @@
.init_hw_reg = msm_vfe32_init_hardware_reg,
.release_hw = msm_vfe32_release_hardware,
.get_platform_data = msm_vfe32_get_platform_data,
+ .get_error_mask = msm_vfe32_get_error_mask,
+ .process_error_status = msm_vfe32_process_error_status,
},
.stats_ops = {
.get_stats_idx = msm_vfe32_get_stats_idx,
diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
index 2061a59..50e685a 100644
--- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
+++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
@@ -49,7 +49,7 @@
{
if (!ispif->enb_dump_reg)
return;
- msm_camera_io_dump(ispif->base+0x100, 0x250);
+ msm_camera_io_dump(ispif->base, 0x250);
}
static inline int msm_ispif_is_intf_valid(uint32_t csid_version,
@@ -166,9 +166,10 @@
}
rc = clk_set_rate(ispif->ispif_clk[intftype], csid);
- if (rc)
+ if (rc) {
pr_err("%s: clk_set_rate failed %d\n", __func__, rc);
- return;
+ return;
+ }
}
data = msm_camera_io_r(ispif->base + ISPIF_INPUT_SEL_ADDR +
diff --git a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
index 0d0baa5..47eccfa 100644
--- a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
@@ -703,7 +703,7 @@
const char *hfi_name = NULL;
if (np) {
- rc = of_property_read_string(np, "hfi", &hfi_name);
+ rc = of_property_read_string(np, "qcom,hfi", &hfi_name);
if (rc) {
dprintk(VIDC_ERR,
"Failed to read hfi from device tree\n");
@@ -749,7 +749,7 @@
int num_elements = 0;
struct platform_device *pdev = res->pdev;
- num_elements = get_u32_array_num_elements(pdev, "load-freq-tbl");
+ num_elements = get_u32_array_num_elements(pdev, "qcom,load-freq-tbl");
if (num_elements == 0) {
dprintk(VIDC_ERR, "no elements in frequency table\n");
return rc;
@@ -765,7 +765,8 @@
}
if (of_property_read_u32_array(pdev->dev.of_node,
- "load-freq-tbl", (u32 *)res->load_freq_tbl, num_elements * 2)) {
+ "qcom,load-freq-tbl", (u32 *)res->load_freq_tbl,
+ num_elements * 2)) {
dprintk(VIDC_ERR, "Failed to read frequency table\n");
msm_vidc_free_freq_table(res);
return -EINVAL;
@@ -782,8 +783,8 @@
int i;
struct platform_device *pdev = res->pdev;
char *names[MAX_MAP] = {
- [CP_MAP] = "vidc-cp-map",
- [NS_MAP] = "vidc-ns-map",
+ [CP_MAP] = "qcom,vidc-cp-map",
+ [NS_MAP] = "qcom,vidc-ns-map",
};
char *contexts[MAX_MAP] = {
[CP_MAP] = "venus_cp",
@@ -833,7 +834,7 @@
int rc = 0;
reg_set = &res->reg_set;
- reg_set->count = get_u32_array_num_elements(pdev, "reg-presets");
+ reg_set->count = get_u32_array_num_elements(pdev, "qcom,reg-presets");
if (reg_set->count == 0) {
dprintk(VIDC_DBG, "no elements in reg set\n");
return rc;
@@ -847,7 +848,7 @@
return -ENOMEM;
}
- if (of_property_read_u32_array(pdev->dev.of_node, "reg-presets",
+ if (of_property_read_u32_array(pdev->dev.of_node, "qcom,reg-presets",
(u32 *)reg_set->reg_tbl, reg_set->count * 2)) {
dprintk(VIDC_ERR, "Failed to read register table\n");
msm_vidc_free_reg_table(res);
@@ -962,7 +963,7 @@
size = pdata->iommu_table[MSM_VIDC_V4L2_IOMMU_MAP_CP][1];
res->iommu_maps[CP_MAP] = (struct msm_vidc_iommu_info) {
.addr_range = {(u32) start, (u32) size},
- .name = "vidc-cp-map",
+ .name = "qcom,vidc-cp-map",
.ctx = "venus_cp",
};
@@ -970,7 +971,7 @@
size = pdata->iommu_table[MSM_VIDC_V4L2_IOMMU_MAP_NS][1];
res->iommu_maps[NS_MAP] = (struct msm_vidc_iommu_info) {
.addr_range = {(u32) start, (u32) size},
- .name = "vidc-ns-map",
+ .name = "qcom,vidc-ns-map",
.ctx = "venus_ns",
};
return rc;
diff --git a/drivers/mfd/wcd9xxx-core.c b/drivers/mfd/wcd9xxx-core.c
index 8953475..a4cb12e 100644
--- a/drivers/mfd/wcd9xxx-core.c
+++ b/drivers/mfd/wcd9xxx-core.c
@@ -296,21 +296,37 @@
struct mfd_cell *dev;
int size;
int num_irqs;
+ int version; /* -1 to retrive version from chip version register */
+ enum wcd9xxx_slim_slave_addr_type slim_slave_type;
} wcd9xxx_codecs[] = {
- {{0x2, 0x0, 0x0, 0x1}, tabla_devs, ARRAY_SIZE(tabla_devs),
- TABLA_NUM_IRQS},
- {{0x1, 0x0, 0x0, 0x1}, tabla1x_devs, ARRAY_SIZE(tabla1x_devs),
- TABLA_NUM_IRQS},
- {{0x0, 0x0, 0x2, 0x1}, taiko_devs, ARRAY_SIZE(taiko_devs),
- TAIKO_NUM_IRQS},
- {{0x0, 0x0, 0x3, 0x1}, tapan_devs, ARRAY_SIZE(tapan_devs),
- TAPAN_NUM_IRQS},
- {{0x0, 0x0, 0x0, 0x1}, sitar_devs, ARRAY_SIZE(sitar_devs),
- SITAR_NUM_IRQS},
- {{0x1, 0x0, 0x1, 0x1}, sitar_devs, ARRAY_SIZE(sitar_devs),
- SITAR_NUM_IRQS},
- {{0x2, 0x0, 0x1, 0x1}, sitar_devs, ARRAY_SIZE(sitar_devs),
- SITAR_NUM_IRQS},
+ {
+ {0x2, 0x0, 0x0, 0x1}, tabla_devs, ARRAY_SIZE(tabla_devs),
+ TABLA_NUM_IRQS, -1, WCD9XXX_SLIM_SLAVE_ADDR_TYPE_TABLA
+ },
+ {
+ {0x1, 0x0, 0x0, 0x1}, tabla1x_devs, ARRAY_SIZE(tabla1x_devs),
+ TABLA_NUM_IRQS, -1, WCD9XXX_SLIM_SLAVE_ADDR_TYPE_TABLA
+ },
+ { /* wcd9320 version 1 */
+ {0x0, 0x0, 0x2, 0x1}, taiko_devs, ARRAY_SIZE(taiko_devs),
+ TAIKO_NUM_IRQS, 1, WCD9XXX_SLIM_SLAVE_ADDR_TYPE_TAIKO
+ },
+ {
+ {0x0, 0x0, 0x3, 0x1}, tapan_devs, ARRAY_SIZE(tapan_devs),
+ TAPAN_NUM_IRQS, -1, WCD9XXX_SLIM_SLAVE_ADDR_TYPE_TAIKO
+ },
+ {
+ {0x0, 0x0, 0x0, 0x1}, sitar_devs, ARRAY_SIZE(sitar_devs),
+ SITAR_NUM_IRQS, -1, WCD9XXX_SLIM_SLAVE_ADDR_TYPE_TABLA
+ },
+ {
+ {0x1, 0x0, 0x1, 0x1}, sitar_devs, ARRAY_SIZE(sitar_devs),
+ SITAR_NUM_IRQS, -1, WCD9XXX_SLIM_SLAVE_ADDR_TYPE_TABLA
+ },
+ {
+ {0x2, 0x0, 0x1, 0x1}, sitar_devs, ARRAY_SIZE(sitar_devs),
+ SITAR_NUM_IRQS, -1, WCD9XXX_SLIM_SLAVE_ADDR_TYPE_TABLA
+ },
};
static void wcd9xxx_bring_up(struct wcd9xxx *wcd9xxx)
@@ -393,6 +409,10 @@
*wcd9xxx_dev = wcd9xxx_codecs[i].dev;
*wcd9xxx_dev_size = wcd9xxx_codecs[i].size;
*wcd9xxx_dev_num_irqs = wcd9xxx_codecs[i].num_irqs;
+ wcd9xxx->slim_slave_type =
+ wcd9xxx_codecs[i].slim_slave_type;
+ if (wcd9xxx_codecs[i].version > -1)
+ wcd9xxx->version = wcd9xxx_codecs[i].version;
break;
}
i++;
diff --git a/drivers/mfd/wcd9xxx-slimslave.c b/drivers/mfd/wcd9xxx-slimslave.c
index 546e252..0bce766 100644
--- a/drivers/mfd/wcd9xxx-slimslave.c
+++ b/drivers/mfd/wcd9xxx-slimslave.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -14,8 +14,6 @@
#include <linux/mfd/wcd9xxx/wcd9xxx-slimslave.h>
#include <linux/mfd/wcd9xxx/wcd9xxx_registers.h>
-#define WCD9XXX_CHIP_ID_TAIKO 0x00000201
-
struct wcd9xxx_slim_sch {
u16 rx_port_ch_reg_base;
u16 port_tx_cfg_reg_base;
@@ -33,22 +31,15 @@
static int wcd9xxx_configure_ports(struct wcd9xxx *wcd9xxx)
{
- int i;
- u32 id;
- for (i = 0; i < 4; i++)
- ((u8 *)&id)[i] = wcd9xxx_reg_read(wcd9xxx,
- WCD9XXX_A_CHIP_ID_BYTE_0 + i);
- id = cpu_to_be32(id);
- pr_debug("%s: chip id 0x%08x\n", __func__, id);
- if (id != WCD9XXX_CHIP_ID_TAIKO) {
- sh_ch.rx_port_ch_reg_base = 0x180 ;
+ if (wcd9xxx->slim_slave_type == WCD9XXX_SLIM_SLAVE_ADDR_TYPE_TABLA) {
+ sh_ch.rx_port_ch_reg_base = 0x180;
sh_ch.port_rx_cfg_reg_base = 0x040;
sh_ch.port_tx_cfg_reg_base = 0x040;
} else {
sh_ch.rx_port_ch_reg_base =
0x180 - (TAIKO_SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS * 4);
sh_ch.port_rx_cfg_reg_base =
- 0x040 - TAIKO_SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS ;
+ 0x040 - TAIKO_SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS;
sh_ch.port_tx_cfg_reg_base = 0x050;
}
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 9bcb5ba..9ee19ab 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -1853,6 +1853,9 @@
!IS_ALIGNED(blk_rq_sectors(cur), 8))
goto no_packed;
+ if (cur->cmd_flags & REQ_FUA)
+ goto no_packed;
+
max_blk_count = min(card->host->max_blk_count,
card->host->max_req_size >> 9);
if (unlikely(max_blk_count > 0xffff))
@@ -1892,6 +1895,12 @@
break;
}
+ if (next->cmd_flags & REQ_FUA) {
+ MMC_BLK_UPDATE_STOP_REASON(stats, FUA);
+ put_back = 1;
+ break;
+ }
+
if (rq_data_dir(cur) != rq_data_dir(next)) {
MMC_BLK_UPDATE_STOP_REASON(stats, WRONG_DATA_DIR);
put_back = 1;
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c
index 931ddb0..8b7e0bd 100644
--- a/drivers/mmc/core/debugfs.c
+++ b/drivers/mmc/core/debugfs.c
@@ -491,6 +491,13 @@
pack_stats->pack_stop_reason[RANDOM]);
strlcat(ubuf, temp_buf, cnt);
}
+ if (pack_stats->pack_stop_reason[FUA]) {
+ snprintf(temp_buf, TEMP_BUF_SIZE,
+ "%s: %d times: fua request\n",
+ mmc_hostname(card->host),
+ pack_stats->pack_stop_reason[FUA]);
+ strlcat(ubuf, temp_buf, cnt);
+ }
spin_unlock(&pack_stats->lock);
diff --git a/drivers/mmc/host/msm_sdcc.h b/drivers/mmc/host/msm_sdcc.h
index 877120c..4eceb47 100644
--- a/drivers/mmc/host/msm_sdcc.h
+++ b/drivers/mmc/host/msm_sdcc.h
@@ -503,7 +503,7 @@
MSMSDCC_DATA_PEND_FOR_CMD53 |
MSMSDCC_TESTBUS_DEBUG;
- if (step == 0x2b)
+ if ((step == 0x2b) || (step == 0x38))
host->hw_caps |= MSMSDCC_SW_RST_CFG_BROKEN;
}
diff --git a/drivers/platform/msm/ssbi.c b/drivers/platform/msm/ssbi.c
index f646e1f..a08eb48 100644
--- a/drivers/platform/msm/ssbi.c
+++ b/drivers/platform/msm/ssbi.c
@@ -1,7 +1,7 @@
/* Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
* Copyright (c) 2010, Google Inc.
*
- * Original authors: The Linux Foundation
+ * Original authors: Code Aurora Forum
*
* Author: Dima Zavin <dima@android.com>
* - Largely rewritten from original to not be an i2c driver.
diff --git a/drivers/power/qpnp-bms.c b/drivers/power/qpnp-bms.c
index 11f4e26..85a310a 100644
--- a/drivers/power/qpnp-bms.c
+++ b/drivers/power/qpnp-bms.c
@@ -1518,13 +1518,13 @@
pr_debug("FCC = %duAh, UUC = %duAh forcing soc = 0\n",
params.fcc_uah,
params.uuc_uah);
- soc = 0;
- } else {
- soc = DIV_ROUND_CLOSEST((remaining_usable_charge_uah * 100),
- (params.fcc_uah
- - params.uuc_uah));
+ new_calculated_soc = 0;
+ goto done_calculating;
}
+ soc = DIV_ROUND_CLOSEST((remaining_usable_charge_uah * 100),
+ (params.fcc_uah - params.uuc_uah));
+
if (chip->first_time_calc_soc && soc < 0) {
/*
* first time calcualtion and the pon ocv is too low resulting
@@ -1598,6 +1598,7 @@
new_calculated_soc = clamp_soc_based_on_voltage(chip,
new_calculated_soc);
+done_calculating:
if (new_calculated_soc != chip->calculated_soc
&& chip->bms_psy.name != NULL) {
power_supply_changed(&chip->bms_psy);
diff --git a/drivers/switch/switch_class.c b/drivers/switch/switch_class.c
index e05fc25..f9cf2b4 100644
--- a/drivers/switch/switch_class.c
+++ b/drivers/switch/switch_class.c
@@ -151,8 +151,8 @@
{
device_remove_file(sdev->dev, &dev_attr_name);
device_remove_file(sdev->dev, &dev_attr_state);
- device_destroy(switch_class, MKDEV(0, sdev->index));
dev_set_drvdata(sdev->dev, NULL);
+ device_destroy(switch_class, MKDEV(0, sdev->index));
}
EXPORT_SYMBOL_GPL(switch_dev_unregister);
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index ad3b9cb..0011a1a 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -38,7 +38,6 @@
#include <mach/rpm-regulator.h>
#include <mach/rpm-regulator-smd.h>
-#include <mach/msm_xo.h>
#include <mach/msm_bus.h>
#include <mach/clk.h>
@@ -160,7 +159,7 @@
u8 ep_num_mapping[DBM_MAX_EPS];
const struct usb_ep_ops *original_ep_ops[DWC3_ENDPOINTS_NUM];
struct list_head req_complete_list;
- struct msm_xo_voter *xo_handle;
+ struct clk *xo_clk;
struct clk *ref_clk;
struct clk *core_clk;
struct clk *iface_clk;
@@ -1637,13 +1636,9 @@
clk_disable_unprepare(mdwc->core_clk);
clk_disable_unprepare(mdwc->iface_clk);
- if (!host_bus_suspend) {
- /* USB PHY no more requires TCXO */
- ret = msm_xo_mode_vote(mdwc->xo_handle, MSM_XO_MODE_OFF);
- if (ret)
- dev_err(mdwc->dev, "%s failed to devote XO buffer%d\n",
- __func__, ret);
- }
+ /* USB PHY no more requires TCXO */
+ if (!host_bus_suspend)
+ clk_disable_unprepare(mdwc->xo_clk);
if (mdwc->bus_perf_client) {
ret = msm_bus_scale_client_update_request(
@@ -1698,7 +1693,7 @@
if (!host_bus_suspend) {
/* Vote for TCXO while waking up USB HSPHY */
- ret = msm_xo_mode_vote(mdwc->xo_handle, MSM_XO_MODE_ON);
+ ret = clk_prepare_enable(mdwc->xo_clk);
if (ret)
dev_err(mdwc->dev, "%s failed to vote TCXO buffer%d\n",
__func__, ret);
@@ -2189,18 +2184,18 @@
INIT_WORK(&msm->restart_usb_work, dwc3_restart_usb_work);
INIT_DELAYED_WORK(&msm->init_adc_work, dwc3_init_adc_work);
- msm->xo_handle = msm_xo_get(MSM_XO_TCXO_D0, "usb");
- if (IS_ERR(msm->xo_handle)) {
+ msm->xo_clk = clk_get(&pdev->dev, "xo");
+ if (IS_ERR(msm->xo_clk)) {
dev_err(&pdev->dev, "%s unable to get TCXO buffer handle\n",
__func__);
- return PTR_ERR(msm->xo_handle);
+ return PTR_ERR(msm->xo_clk);
}
- ret = msm_xo_mode_vote(msm->xo_handle, MSM_XO_MODE_ON);
+ ret = clk_prepare_enable(msm->xo_clk);
if (ret) {
dev_err(&pdev->dev, "%s failed to vote for TCXO buffer%d\n",
__func__, ret);
- goto free_xo_handle;
+ goto put_xo;
}
/*
@@ -2211,7 +2206,7 @@
if (IS_ERR(msm->core_clk)) {
dev_err(&pdev->dev, "failed to get core_clk\n");
ret = PTR_ERR(msm->core_clk);
- goto free_xo_handle;
+ goto disable_xo;
}
clk_set_rate(msm->core_clk, 125000000);
clk_prepare_enable(msm->core_clk);
@@ -2539,8 +2534,10 @@
clk_disable_unprepare(msm->iface_clk);
disable_core_clk:
clk_disable_unprepare(msm->core_clk);
-free_xo_handle:
- msm_xo_put(msm->xo_handle);
+disable_xo:
+ clk_disable_unprepare(msm->xo_clk);
+put_xo:
+ clk_put(msm->xo_clk);
return ret;
}
@@ -2575,7 +2572,8 @@
clk_disable_unprepare(msm->sleep_clk);
clk_disable_unprepare(msm->hsphy_sleep_clk);
clk_disable_unprepare(msm->ref_clk);
- msm_xo_put(msm->xo_handle);
+ clk_disable_unprepare(msm->xo_clk);
+ clk_put(msm->xo_clk);
return 0;
}
diff --git a/drivers/usb/gadget/qcom_maemo.c b/drivers/usb/gadget/qcom_maemo.c
index 878a297..2fb8be0 100644
--- a/drivers/usb/gadget/qcom_maemo.c
+++ b/drivers/usb/gadget/qcom_maemo.c
@@ -6,7 +6,7 @@
* Copyright (C) 2009 Samsung Electronics
* Copyright (c) 2010, The Linux Foundation. All rights reserved.
*
- * This program from the The Linux Foundation is free software; you can
+ * This program from The Linux Foundation is free software; you can
* redistribute it and/or modify it under the GNU General Public License
* version 2 and only version 2 as published by the Free Software Foundation.
* The original work available from [git.kernel.org ] is subject to the
diff --git a/drivers/usb/gadget/u_sdio.c b/drivers/usb/gadget/u_sdio.c
index 4c5083d..a0cdde2 100644
--- a/drivers/usb/gadget/u_sdio.c
+++ b/drivers/usb/gadget/u_sdio.c
@@ -7,7 +7,7 @@
* Copyright (C) 2008 by Nokia Corporation
* Copyright (c) 2011, The Linux Foundation. All rights reserved.
*
- * This program from the The Linux Foundation is free software; you can
+ * This program from The Linux Foundation is free software; you can
* redistribute it and/or modify it under the GNU General Public License
* version 2 and only version 2 as published by the Free Software Foundation.
* The original work available from [kernel.org] is subject to the notice below.
diff --git a/drivers/video/msm/hdmi_msm.c b/drivers/video/msm/hdmi_msm.c
index eae24f6..fa57992 100644
--- a/drivers/video/msm/hdmi_msm.c
+++ b/drivers/video/msm/hdmi_msm.c
@@ -4492,6 +4492,7 @@
cancel_work_sync(&hdmi_msm_state->hdcp_reauth_work);
cancel_work_sync(&hdmi_msm_state->hdcp_work);
del_timer_sync(&hdmi_msm_state->hdcp_timer);
+ hdmi_msm_state->reauth = FALSE;
hdcp_deauthenticate();
}
diff --git a/drivers/video/msm/mdp_hw40.c b/drivers/video/msm/mdp_hw40.c
index 3290ab9..a642c9b 100644
--- a/drivers/video/msm/mdp_hw40.c
+++ b/drivers/video/msm/mdp_hw40.c
@@ -2,7 +2,7 @@
* Copyright (C) 2010 Google, Inc.
* Author: Dima Zavin <dima@android.com>
*
- * Based on code from The Linux Foundation.
+ * Based on code from Code Aurora Forum.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/video/msm/mdss/mdss.h b/drivers/video/msm/mdss/mdss.h
index 086874e..5070b03 100644
--- a/drivers/video/msm/mdss/mdss.h
+++ b/drivers/video/msm/mdss/mdss.h
@@ -51,6 +51,11 @@
int domain_idx;
};
+struct mdss_hw_settings {
+ char __iomem *reg;
+ u32 val;
+};
+
struct mdss_data_type {
u32 rev;
u32 mdp_rev;
@@ -84,8 +89,25 @@
u32 smp_mb_cnt;
u32 smp_mb_size;
- u32 *pipe_type_map;
- u32 *mixer_type_map;
+
+ struct mdss_hw_settings *hw_settings;
+
+ struct mdss_mdp_pipe *vig_pipes;
+ struct mdss_mdp_pipe *rgb_pipes;
+ struct mdss_mdp_pipe *dma_pipes;
+ u32 nvig_pipes;
+ u32 nrgb_pipes;
+ u32 ndma_pipes;
+ struct mdss_mdp_mixer *mixer_intf;
+ struct mdss_mdp_mixer *mixer_wb;
+ u32 nmixers_intf;
+ u32 nmixers_wb;
+ struct mdss_mdp_ctl *ctl_off;
+ u32 nctl;
+ struct mdss_mdp_dp_intf *dp_off;
+ u32 ndp;
+ void *video_intf;
+ u32 nintf;
struct ion_client *iclient;
int iommu_attached;
diff --git a/drivers/video/msm/mdss/mdss_hdmi_tx.c b/drivers/video/msm/mdss/mdss_hdmi_tx.c
index 75a6586..b6dec99 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_tx.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_tx.c
@@ -34,7 +34,7 @@
#define DRV_NAME "hdmi-tx"
#define COMPATIBLE_NAME "qcom,hdmi-tx"
-#define DEFAULT_VIDEO_RESOLUTION HDMI_VFRMT_1920x1080p60_16_9
+#define DEFAULT_VIDEO_RESOLUTION HDMI_VFRMT_640x480p60_4_3
/* HDMI PHY/PLL bit field macros */
#define SW_RESET BIT(2)
diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c
index 38e9560..31b80b1 100644
--- a/drivers/video/msm/mdss/mdss_mdp.c
+++ b/drivers/video/msm/mdss/mdss_mdp.c
@@ -57,25 +57,6 @@
static DEFINE_MUTEX(mdp_clk_lock);
static DEFINE_MUTEX(mdp_suspend_mutex);
-u32 mdss_mdp_pipe_type_map[MDSS_MDP_MAX_SSPP] = {
- MDSS_MDP_PIPE_TYPE_VIG,
- MDSS_MDP_PIPE_TYPE_VIG,
- MDSS_MDP_PIPE_TYPE_VIG,
- MDSS_MDP_PIPE_TYPE_RGB,
- MDSS_MDP_PIPE_TYPE_RGB,
- MDSS_MDP_PIPE_TYPE_RGB,
- MDSS_MDP_PIPE_TYPE_DMA,
- MDSS_MDP_PIPE_TYPE_DMA,
-};
-
-u32 mdss_mdp_mixer_type_map[MDSS_MDP_MAX_LAYERMIXER] = {
- MDSS_MDP_MIXER_TYPE_INTF,
- MDSS_MDP_MIXER_TYPE_INTF,
- MDSS_MDP_MIXER_TYPE_INTF,
- MDSS_MDP_MIXER_TYPE_WRITEBACK,
- MDSS_MDP_MIXER_TYPE_WRITEBACK,
-};
-
#define MDP_BUS_VECTOR_ENTRY(ab_val, ib_val) \
{ \
.src = MSM_BUS_MASTER_MDP_PORT0, \
@@ -131,6 +112,15 @@
struct mdss_hw *mdss_irq_handlers[MDSS_MAX_HW_BLK];
static int mdss_mdp_register_early_suspend(struct mdss_data_type *mdata);
+static int mdss_mdp_parse_dt(struct platform_device *pdev);
+static int mdss_mdp_parse_dt_pipe(struct platform_device *pdev);
+static int mdss_mdp_parse_dt_mixer(struct platform_device *pdev);
+static int mdss_mdp_parse_dt_ctl(struct platform_device *pdev);
+static int mdss_mdp_parse_dt_video_intf(struct platform_device *pdev);
+static int mdss_mdp_parse_dt_handler(struct platform_device *pdev,
+ char *prop_name, u32 *offsets, int len);
+static int mdss_mdp_parse_dt_prop_len(struct platform_device *pdev,
+ char *prop_name);
static inline int mdss_irq_dispatch(u32 hw_ndx, int irq, void *ptr)
{
@@ -788,20 +778,18 @@
static int mdss_hw_init(struct mdss_data_type *mdata)
{
- char *base = mdata->vbif_base;
-
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
- /* Setup VBIF QoS settings*/
- MDSS_MDP_REG_WRITE(0x2E0, 0x000000AA);
- MDSS_MDP_REG_WRITE(0x2E4, 0x00000055);
- writel_relaxed(0x00000001, base + 0x004);
- writel_relaxed(0x00000707, base + 0x0D8);
- writel_relaxed(0x00000030, base + 0x0F0);
- writel_relaxed(0x00000001, base + 0x124);
- writel_relaxed(0x00000FFF, base + 0x178);
- writel_relaxed(0x0FFF0FFF, base + 0x17C);
- writel_relaxed(0x22222222, base + 0x160);
- writel_relaxed(0x00002222, base + 0x164);
+ mdata->rev = MDSS_MDP_REG_READ(MDSS_REG_HW_VERSION);
+ mdata->mdp_rev = MDSS_MDP_REG_READ(MDSS_MDP_REG_HW_VERSION);
+
+ if (mdata->hw_settings) {
+ struct mdss_hw_settings *hws = mdata->hw_settings;
+
+ while (hws->reg) {
+ writel_relaxed(hws->val, hws->reg);
+ hws++;
+ }
+ }
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
pr_debug("MDP hw init done\n");
@@ -832,15 +820,8 @@
INIT_DELAYED_WORK(&mdata->clk_ctrl_worker,
mdss_mdp_clk_ctrl_workqueue_handler);
- mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
- mdata->rev = MDSS_MDP_REG_READ(MDSS_REG_HW_VERSION);
- mdata->mdp_rev = MDSS_MDP_REG_READ(MDSS_MDP_REG_HW_VERSION);
- mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
-
mdata->smp_mb_cnt = MDSS_MDP_SMP_MMB_BLOCKS;
mdata->smp_mb_size = MDSS_MDP_SMP_MMB_SIZE;
- mdata->pipe_type_map = mdss_mdp_pipe_type_map;
- mdata->mixer_type_map = mdss_mdp_mixer_type_map;
pr_info("mdss_revision=%x\n", mdata->rev);
pr_info("mdp_hw_revision=%x\n", mdata->mdp_rev);
@@ -931,6 +912,13 @@
}
mdata->irq = res->start;
+ /*populate hw iomem base info from device tree*/
+ rc = mdss_mdp_parse_dt(pdev);
+ if (rc) {
+ pr_err("unable to parse device tree\n");
+ goto probe_done;
+ }
+
rc = mdss_mdp_res_init(mdata);
if (rc) {
pr_err("unable to initialize mdss mdp resources\n");
@@ -966,6 +954,395 @@
return rc;
}
+static void mdss_mdp_parse_dt_regs_array(const u32 *arr, char __iomem *hw_base,
+ struct mdss_hw_settings *hws, int count)
+{
+ u32 len, reg;
+ int i;
+
+ if (!arr)
+ return;
+
+ for (i = 0, len = count * 2; i < len; i += 2) {
+ reg = be32_to_cpu(arr[i]);
+ hws->reg = hw_base + reg;
+ hws->val = be32_to_cpu(arr[i + 1]);
+ pr_debug("reg: 0x%04x=0x%08x\n", reg, hws->val);
+ hws++;
+ }
+}
+
+int mdss_mdp_parse_dt_hw_settings(struct platform_device *pdev)
+{
+ struct mdss_data_type *mdata = platform_get_drvdata(pdev);
+ struct mdss_hw_settings *hws;
+ const u32 *vbif_arr, *mdp_arr;
+ int vbif_len, mdp_len;
+
+ vbif_arr = of_get_property(pdev->dev.of_node, "qcom,vbif-settings",
+ &vbif_len);
+ if (!vbif_arr || (mdp_len & 1)) {
+ pr_warn("MDSS VBIF settings not found\n");
+ vbif_len = 0;
+ }
+ vbif_len /= 2 * sizeof(u32);
+
+ mdp_arr = of_get_property(pdev->dev.of_node, "qcom,mdp-settings",
+ &mdp_len);
+ if (!mdp_arr || (mdp_len & 1)) {
+ pr_warn("MDSS MDP settings not found\n");
+ mdp_len = 0;
+ }
+ mdp_len /= 2 * sizeof(u32);
+
+ if ((mdp_len + vbif_len) == 0)
+ return 0;
+
+ hws = devm_kzalloc(&pdev->dev, sizeof(*hws) * (vbif_len + mdp_len + 1),
+ GFP_KERNEL);
+ if (!hws)
+ return -ENOMEM;
+
+ mdss_mdp_parse_dt_regs_array(vbif_arr, mdata->vbif_base, hws, vbif_len);
+ mdss_mdp_parse_dt_regs_array(mdp_arr, mdata->mdp_base,
+ hws + vbif_len, mdp_len);
+
+ mdata->hw_settings = hws;
+
+ return 0;
+}
+
+static int mdss_mdp_parse_dt(struct platform_device *pdev)
+{
+ int rc;
+
+ rc = mdss_mdp_parse_dt_hw_settings(pdev);
+ if (rc) {
+ pr_err("Error in device tree : hw settings\n");
+ return rc;
+ }
+
+ rc = mdss_mdp_parse_dt_pipe(pdev);
+ if (rc) {
+ pr_err("Error in device tree : pipes\n");
+ return rc;
+ }
+
+ rc = mdss_mdp_parse_dt_mixer(pdev);
+ if (rc) {
+ pr_err("Error in device tree : mixers\n");
+ return rc;
+ }
+
+ rc = mdss_mdp_parse_dt_ctl(pdev);
+ if (rc) {
+ pr_err("Error in device tree : ctl\n");
+ return rc;
+ }
+
+ rc = mdss_mdp_parse_dt_video_intf(pdev);
+ if (rc) {
+ pr_err("Error in device tree : ctl\n");
+ return rc;
+ }
+
+ return 0;
+}
+
+
+static int mdss_mdp_parse_dt_pipe(struct platform_device *pdev)
+{
+ u32 npipes, off;
+ int rc = 0;
+ u32 nids = 0;
+ u32 *offsets = NULL, *ftch_id = NULL;
+
+ struct mdss_data_type *mdata = platform_get_drvdata(pdev);
+
+ mdata->nvig_pipes = mdss_mdp_parse_dt_prop_len(pdev,
+ "qcom,mdss-pipe-vig-off");
+ mdata->nrgb_pipes = mdss_mdp_parse_dt_prop_len(pdev,
+ "qcom,mdss-pipe-rgb-off");
+ mdata->ndma_pipes = mdss_mdp_parse_dt_prop_len(pdev,
+ "qcom,mdss-pipe-dma-off");
+
+ nids += mdss_mdp_parse_dt_prop_len(pdev,
+ "qcom,mdss-pipe-vig-fetch-id");
+ nids += mdss_mdp_parse_dt_prop_len(pdev,
+ "qcom,mdss-pipe-rgb-fetch-id");
+ nids += mdss_mdp_parse_dt_prop_len(pdev,
+ "qcom,mdss-pipe-dma-fetch-id");
+
+ npipes = mdata->nvig_pipes + mdata->nrgb_pipes + mdata->ndma_pipes;
+
+ if (npipes != nids) {
+ pr_err("device tree err: unequal number of pipes and smp ids");
+ return -EINVAL;
+ }
+
+ offsets = kzalloc(sizeof(u32) * npipes, GFP_KERNEL);
+ if (!offsets) {
+ pr_err("no mem assigned: kzalloc fail\n");
+ return -ENOMEM;
+ }
+
+ ftch_id = kzalloc(sizeof(u32) * nids, GFP_KERNEL);
+ if (!ftch_id) {
+ pr_err("no mem assigned: kzalloc fail\n");
+ rc = -ENOMEM;
+ goto ftch_alloc_fail;
+ }
+
+ rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-vig-fetch-id",
+ ftch_id, mdata->nvig_pipes);
+ if (rc)
+ goto parse_done;
+
+ rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-vig-off",
+ offsets, mdata->nvig_pipes);
+ if (rc)
+ goto parse_done;
+
+ rc = mdss_mdp_pipe_addr_setup(mdata, offsets, ftch_id,
+ MDSS_MDP_PIPE_TYPE_VIG, MDSS_MDP_SSPP_VIG0, mdata->nvig_pipes);
+ if (rc)
+ goto parse_done;
+
+ rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-rgb-fetch-id",
+ ftch_id + mdata->nvig_pipes, mdata->nrgb_pipes);
+ if (rc)
+ goto parse_done;
+
+ rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-rgb-off",
+ offsets + mdata->nvig_pipes, mdata->nrgb_pipes);
+ if (rc)
+ goto parse_done;
+
+ rc = mdss_mdp_pipe_addr_setup(mdata, offsets + mdata->nvig_pipes,
+ ftch_id + mdata->nvig_pipes, MDSS_MDP_PIPE_TYPE_RGB,
+ MDSS_MDP_SSPP_RGB0, mdata->nrgb_pipes);
+ if (rc)
+ goto parse_done;
+
+ off = mdata->nvig_pipes + mdata->nrgb_pipes;
+
+ rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-dma-fetch-id",
+ ftch_id + off, mdata->ndma_pipes);
+ if (rc)
+ goto parse_done;
+
+ rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-dma-off",
+ offsets + off, mdata->ndma_pipes);
+ if (rc)
+ goto parse_done;
+
+ rc = mdss_mdp_pipe_addr_setup(mdata, offsets + off, ftch_id + off,
+ MDSS_MDP_PIPE_TYPE_DMA, MDSS_MDP_SSPP_DMA0, mdata->ndma_pipes);
+ if (rc)
+ goto parse_done;
+
+parse_done:
+ kfree(ftch_id);
+ftch_alloc_fail:
+ kfree(offsets);
+ return rc;
+}
+
+static int mdss_mdp_parse_dt_mixer(struct platform_device *pdev)
+{
+
+ u32 nmixers, ndspp;
+ int rc = 0;
+ u32 *mixer_offsets = NULL, *dspp_offsets = NULL;
+
+ struct mdss_data_type *mdata = platform_get_drvdata(pdev);
+
+ mdata->nmixers_intf = mdss_mdp_parse_dt_prop_len(pdev,
+ "qcom,mdss-mixer-intf-off");
+ mdata->nmixers_wb = mdss_mdp_parse_dt_prop_len(pdev,
+ "qcom,mdss-mixer-wb-off");
+ ndspp = mdss_mdp_parse_dt_prop_len(pdev,
+ "qcom,mdss-dspp-off");
+ nmixers = mdata->nmixers_intf + mdata->nmixers_wb;
+
+ if (mdata->nmixers_intf != ndspp) {
+ pr_err("device tree err: unequal no of dspp and intf mixers\n");
+ return -EINVAL;
+ }
+
+ mixer_offsets = kzalloc(sizeof(u32) * nmixers, GFP_KERNEL);
+ if (!mixer_offsets) {
+ pr_err("no mem assigned: kzalloc fail\n");
+ return -ENOMEM;
+ }
+
+ dspp_offsets = kzalloc(sizeof(u32) * ndspp, GFP_KERNEL);
+ if (!dspp_offsets) {
+ pr_err("no mem assigned: kzalloc fail\n");
+ rc = -ENOMEM;
+ goto dspp_alloc_fail;
+ }
+
+ rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-mixer-intf-off",
+ mixer_offsets, mdata->nmixers_intf);
+ if (rc)
+ goto parse_done;
+
+ rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-mixer-wb-off",
+ mixer_offsets + mdata->nmixers_intf, mdata->nmixers_wb);
+ if (rc)
+ goto parse_done;
+
+ rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-dspp-off",
+ dspp_offsets, ndspp);
+ if (rc)
+ goto parse_done;
+
+ rc = mdss_mdp_mixer_addr_setup(mdata, mixer_offsets,
+ dspp_offsets, MDSS_MDP_MIXER_TYPE_INTF,
+ mdata->nmixers_intf);
+ if (rc)
+ goto parse_done;
+
+ rc = mdss_mdp_mixer_addr_setup(mdata, mixer_offsets +
+ mdata->nmixers_intf, NULL,
+ MDSS_MDP_MIXER_TYPE_WRITEBACK, mdata->nmixers_wb);
+ if (rc)
+ goto parse_done;
+
+parse_done:
+ kfree(dspp_offsets);
+dspp_alloc_fail:
+ kfree(mixer_offsets);
+
+ return rc;
+}
+
+static int mdss_mdp_parse_dt_ctl(struct platform_device *pdev)
+{
+ u32 nwb;
+ int rc = 0;
+ u32 *ctl_offsets = NULL, *wb_offsets = NULL;
+
+ struct mdss_data_type *mdata = platform_get_drvdata(pdev);
+
+ mdata->nctl = mdss_mdp_parse_dt_prop_len(pdev,
+ "qcom,mdss-ctl-off");
+ nwb = mdss_mdp_parse_dt_prop_len(pdev,
+ "qcom,mdss-wb-off");
+
+ if (mdata->nctl != nwb) {
+ pr_err("device tree err: unequal number of ctl and wb\n");
+ rc = -EINVAL;
+ goto parse_done;
+ }
+
+ ctl_offsets = kzalloc(sizeof(u32) * mdata->nctl, GFP_KERNEL);
+ if (!ctl_offsets) {
+ pr_err("no more mem for ctl offsets\n");
+ return -ENOMEM;
+ }
+
+ wb_offsets = kzalloc(sizeof(u32) * nwb, GFP_KERNEL);
+ if (!wb_offsets) {
+ pr_err("no more mem for writeback offsets\n");
+ rc = -ENOMEM;
+ goto wb_alloc_fail;
+ }
+
+ rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-ctl-off",
+ ctl_offsets, mdata->nctl);
+ if (rc)
+ goto parse_done;
+
+ rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-wb-off",
+ wb_offsets, nwb);
+ if (rc)
+ goto parse_done;
+
+ rc = mdss_mdp_ctl_addr_setup(mdata, ctl_offsets, wb_offsets,
+ mdata->nctl);
+ if (rc)
+ goto parse_done;
+
+parse_done:
+ kfree(wb_offsets);
+wb_alloc_fail:
+ kfree(ctl_offsets);
+
+ return rc;
+}
+
+static int mdss_mdp_parse_dt_video_intf(struct platform_device *pdev)
+{
+ struct mdss_data_type *mdata = platform_get_drvdata(pdev);
+ u32 count;
+ u32 *offsets;
+ int rc;
+
+
+ count = mdss_mdp_parse_dt_prop_len(pdev, "qcom,mdss-intf-off");
+ if (count == 0)
+ return -EINVAL;
+
+ offsets = kzalloc(sizeof(u32) * count, GFP_KERNEL);
+ if (!offsets) {
+ pr_err("no mem assigned for video intf\n");
+ return -ENOMEM;
+ }
+
+ rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-intf-off",
+ offsets, count);
+ if (rc)
+ goto parse_fail;
+
+ rc = mdss_mdp_video_addr_setup(mdata, offsets, count);
+ if (rc)
+ pr_err("unable to setup video interfaces\n");
+
+parse_fail:
+ kfree(offsets);
+
+ return rc;
+}
+
+static int mdss_mdp_parse_dt_handler(struct platform_device *pdev,
+ char *prop_name, u32 *offsets, int len)
+{
+ int rc;
+ rc = of_property_read_u32_array(pdev->dev.of_node, prop_name,
+ offsets, len);
+ if (rc) {
+ pr_err("Error from prop %s : u32 array read\n", prop_name);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int mdss_mdp_parse_dt_prop_len(struct platform_device *pdev,
+ char *prop_name)
+{
+ int len = 0;
+
+ of_find_property(pdev->dev.of_node, prop_name, &len);
+
+ if (len < 1) {
+ pr_err("Error from prop %s : spec error in device tree\n",
+ prop_name);
+ return 0;
+ }
+
+ len = len/sizeof(u32);
+
+ return len;
+}
+
+struct mdss_data_type *mdss_mdp_get_mdata()
+{
+ return mdss_res;
+}
+
static void mdss_mdp_footswitch_ctrl(struct mdss_data_type *mdata, int on)
{
mutex_lock(&mdp_suspend_mutex);
diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h
index acd54af..30b7695 100644
--- a/drivers/video/msm/mdss/mdss_mdp.h
+++ b/drivers/video/msm/mdss/mdss_mdp.h
@@ -112,6 +112,8 @@
struct mdss_mdp_ctl {
u32 num;
+ char __iomem *base;
+ char __iomem *wb_base;
u32 ref_cnt;
int power_on;
@@ -131,7 +133,6 @@
u32 bus_ib_quota;
u32 clk_rate;
- char __iomem *base;
struct mdss_data_type *mdata;
struct msm_fb_data_type *mfd;
struct mdss_mdp_mixer *mixer_left;
@@ -153,9 +154,9 @@
u32 num;
u32 ref_cnt;
char __iomem *base;
+ char __iomem *dspp_base;
u8 type;
u8 params_changed;
-
u16 width;
u16 height;
u8 cursor_enabled;
@@ -236,6 +237,7 @@
u32 type;
u32 ndx;
char __iomem *base;
+ u32 ftch_id;
atomic_t ref_cnt;
u32 play_cnt;
@@ -306,9 +308,12 @@
unsigned long mdss_mdp_get_clk_rate(u32 clk_idx);
int mdss_mdp_vsync_clk_enable(int enable);
void mdss_mdp_clk_ctrl(int enable, int isr);
+struct mdss_data_type *mdss_mdp_get_mdata(void);
int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd);
int mdss_mdp_overlay_vsync_ctrl(struct msm_fb_data_type *mfd, int en);
+int mdss_mdp_video_addr_setup(struct mdss_data_type *mdata,
+ u32 *offsets, u32 count);
int mdss_mdp_video_start(struct mdss_mdp_ctl *ctl);
int mdss_mdp_writeback_start(struct mdss_mdp_ctl *ctl);
int mdss_mdp_overlay_kickoff(struct mdss_mdp_ctl *ctl);
@@ -358,13 +363,19 @@
struct mdp_histogram_data *hist, u32 *hist_data_addr);
void mdss_mdp_hist_intr_done(u32 isr);
-struct mdss_mdp_pipe *mdss_mdp_pipe_alloc_pnum(
- struct mdss_mdp_mixer *mixer, u32 pnum);
-struct mdss_mdp_pipe *mdss_mdp_pipe_alloc(
- struct mdss_mdp_mixer *mixer, u32 type);
-struct mdss_mdp_pipe *mdss_mdp_pipe_get(u32 ndx);
+struct mdss_mdp_pipe *mdss_mdp_pipe_alloc(struct mdss_mdp_mixer *mixer,
+ u32 type);
+struct mdss_mdp_pipe *mdss_mdp_pipe_get(struct mdss_data_type *mdata, u32 ndx);
int mdss_mdp_pipe_map(struct mdss_mdp_pipe *pipe);
void mdss_mdp_pipe_unmap(struct mdss_mdp_pipe *pipe);
+struct mdss_mdp_pipe *mdss_mdp_pipe_alloc_dma(struct mdss_mdp_mixer *mixer);
+
+int mdss_mdp_pipe_addr_setup(struct mdss_data_type *mdata, u32 *offsets,
+ u32 *ftch_y_id, u32 type, u32 num_base, u32 len);
+int mdss_mdp_mixer_addr_setup(struct mdss_data_type *mdata, u32 *mixer_offsets,
+ u32 *dspp_offsets, u32 type, u32 len);
+int mdss_mdp_ctl_addr_setup(struct mdss_data_type *mdata, u32 *ctl_offsets,
+ u32 *wb_offsets, u32 len);
int mdss_mdp_pipe_destroy(struct mdss_mdp_pipe *pipe);
int mdss_mdp_pipe_queue_data(struct mdss_mdp_pipe *pipe,
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index 2ecd4b6..63a1aa4 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -38,8 +38,6 @@
#define MDSS_MDP_PERF_UPDATE_ALL -1
static DEFINE_MUTEX(mdss_mdp_ctl_lock);
-static struct mdss_mdp_ctl mdss_mdp_ctl_list[MDSS_MDP_MAX_CTL];
-static struct mdss_mdp_mixer mdss_mdp_mixer_list[MDSS_MDP_MAX_LAYERMIXER];
static inline void mdp_mixer_write(struct mdss_mdp_mixer *mixer,
u32 reg, u32 val)
@@ -47,7 +45,7 @@
writel_relaxed(val, mixer->base + reg);
}
-static int mdss_mdp_ctl_perf_commit(u32 flags)
+static int mdss_mdp_ctl_perf_commit(struct mdss_data_type *mdata, u32 flags)
{
struct mdss_mdp_ctl *ctl;
int cnum;
@@ -60,8 +58,8 @@
}
mutex_lock(&mdss_mdp_ctl_lock);
- for (cnum = 0; cnum < MDSS_MDP_MAX_CTL; cnum++) {
- ctl = &mdss_mdp_ctl_list[cnum];
+ for (cnum = 0; cnum < mdata->nctl; cnum++) {
+ ctl = mdata->ctl_off + cnum;
if (ctl->power_on) {
bus_ab_quota += ctl->bus_ab_quota;
bus_ib_quota += ctl->bus_ib_quota;
@@ -239,19 +237,16 @@
int cnum;
mutex_lock(&mdss_mdp_ctl_lock);
- for (cnum = 0; cnum < MDSS_MDP_MAX_CTL; cnum++) {
- if (mdss_mdp_ctl_list[cnum].ref_cnt == 0) {
- ctl = &mdss_mdp_ctl_list[cnum];
- ctl->num = cnum;
+ for (cnum = 0; cnum < mdata->nctl; cnum++) {
+ ctl = mdata->ctl_off + cnum;
+ if (ctl->ref_cnt == 0) {
ctl->ref_cnt++;
ctl->mdata = mdata;
- ctl->base = mdata->mdp_base +
- MDSS_MDP_REG_CTL_OFFSET(cnum);
mutex_init(&ctl->lock);
-
pr_debug("alloc ctl_num=%d\n", ctl->num);
break;
}
+ ctl = NULL;
}
mutex_unlock(&mdss_mdp_ctl_lock);
@@ -271,8 +266,7 @@
}
mutex_lock(&mdss_mdp_ctl_lock);
- if (--ctl->ref_cnt == 0)
- memset(ctl, 0, sizeof(*ctl));
+ ctl->ref_cnt--;
mutex_unlock(&mdss_mdp_ctl_lock);
return 0;
@@ -282,27 +276,47 @@
struct mdss_mdp_ctl *ctl, u32 type)
{
struct mdss_mdp_mixer *mixer = NULL;
- int mnum;
+ u32 nmixers_intf;
+ u32 nmixers_wb;
+ u32 i;
+ u32 nmixers;
+ struct mdss_mdp_mixer *mixer_pool = NULL;
if (!ctl || !ctl->mdata)
return NULL;
mutex_lock(&mdss_mdp_ctl_lock);
- for (mnum = 0; mnum < MDSS_MDP_MAX_LAYERMIXER; mnum++) {
- if (type == ctl->mdata->mixer_type_map[mnum] &&
- mdss_mdp_mixer_list[mnum].ref_cnt == 0) {
- mixer = &mdss_mdp_mixer_list[mnum];
- mixer->num = mnum;
+ nmixers_intf = ctl->mdata->nmixers_intf;
+ nmixers_wb = ctl->mdata->nmixers_wb;
+
+ switch (type) {
+
+ case MDSS_MDP_MIXER_TYPE_INTF:
+ mixer_pool = ctl->mdata->mixer_intf;
+ nmixers = nmixers_intf;
+ break;
+
+ case MDSS_MDP_MIXER_TYPE_WRITEBACK:
+ mixer_pool = ctl->mdata->mixer_wb;
+ nmixers = nmixers_wb;
+ break;
+
+ default:
+ nmixers = 0;
+ pr_err("invalid pipe type %d\n", type);
+ break;
+ }
+
+ for (i = 0; i < nmixers; i++) {
+ mixer = mixer_pool + i;
+ if (mixer->ref_cnt == 0) {
mixer->ref_cnt++;
mixer->params_changed++;
- mixer->type = type;
- mixer->base = ctl->mdata->mdp_base +
- MDSS_MDP_REG_LM_OFFSET(mnum);
mixer->ctl = ctl;
-
- pr_debug("mixer_num=%d\n", mixer->num);
+ pr_debug("alloc mixer num%d\n", mixer->num);
break;
}
+ mixer = NULL;
}
mutex_unlock(&mdss_mdp_ctl_lock);
@@ -322,8 +336,7 @@
}
mutex_lock(&mdss_mdp_ctl_lock);
- if (--mixer->ref_cnt == 0)
- memset(mixer, 0, sizeof(*mixer));
+ mixer->ref_cnt--;
mutex_unlock(&mdss_mdp_ctl_lock);
return 0;
@@ -345,11 +358,11 @@
mixer->rotator_mode = rotator;
switch (mixer->num) {
- case MDSS_MDP_LAYERMIXER3:
+ case MDSS_MDP_WB_LAYERMIXER0:
ctl->opmode = (rotator ? MDSS_MDP_CTL_OP_ROT0_MODE :
MDSS_MDP_CTL_OP_WB0_MODE);
break;
- case MDSS_MDP_LAYERMIXER4:
+ case MDSS_MDP_WB_LAYERMIXER1:
ctl->opmode = (rotator ? MDSS_MDP_CTL_OP_ROT1_MODE :
MDSS_MDP_CTL_OP_WB1_MODE);
break;
@@ -390,7 +403,7 @@
mdss_mdp_mixer_free(mixer);
mdss_mdp_ctl_free(ctl);
- mdss_mdp_ctl_perf_commit(MDSS_MDP_PERF_UPDATE_ALL);
+ mdss_mdp_ctl_perf_commit(ctl->mdata, MDSS_MDP_PERF_UPDATE_ALL);
return 0;
}
@@ -476,6 +489,7 @@
ctl->mixer_right->height = height;
} else if (ctl->mixer_right) {
mdss_mdp_mixer_free(ctl->mixer_right);
+ ctl->mixer_right = NULL;
}
if (ctl->mixer_right) {
@@ -666,10 +680,13 @@
mdss_mdp_ctl_free(sctl);
} else if (ctl->mixer_right) {
mdss_mdp_mixer_free(ctl->mixer_right);
+ ctl->mixer_right = NULL;
}
- if (ctl->mixer_left)
+ if (ctl->mixer_left) {
mdss_mdp_mixer_free(ctl->mixer_left);
+ ctl->mixer_left = NULL;
+ }
mdss_mdp_ctl_free(ctl);
return 0;
@@ -828,7 +845,7 @@
mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_LAYER(
ctl->mixer_right->num), 0);
}
- mdss_mdp_ctl_perf_commit(MDSS_MDP_PERF_UPDATE_ALL);
+ mdss_mdp_ctl_perf_commit(ctl->mdata, MDSS_MDP_PERF_UPDATE_ALL);
}
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
@@ -938,6 +955,76 @@
return 0;
}
+int mdss_mdp_mixer_addr_setup(struct mdss_data_type *mdata,
+ u32 *mixer_offsets, u32 *dspp_offsets, u32 type, u32 len)
+{
+ struct mdss_mdp_mixer *head;
+ u32 i;
+ int rc = 0;
+
+ head = devm_kzalloc(&mdata->pdev->dev, sizeof(struct mdss_mdp_mixer) *
+ len, GFP_KERNEL);
+
+ if (!head) {
+ pr_err("unable to setup mixer type=%d :kzalloc fail\n",
+ type);
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < len; i++) {
+ head[i].type = type;
+ head[i].base = mdata->mdp_base + mixer_offsets[i];
+ head[i].ref_cnt = 0;
+ head[i].num = i;
+ if (type == MDSS_MDP_MIXER_TYPE_INTF)
+ head[i].dspp_base = mdata->mdp_base + dspp_offsets[i];
+ }
+
+ switch (type) {
+
+ case MDSS_MDP_MIXER_TYPE_INTF:
+ mdata->mixer_intf = head;
+ break;
+
+ case MDSS_MDP_MIXER_TYPE_WRITEBACK:
+ mdata->mixer_wb = head;
+ break;
+
+ default:
+ pr_err("Invalid mixer type=%d\n", type);
+ rc = -EINVAL;
+ break;
+ }
+
+ return rc;
+}
+
+int mdss_mdp_ctl_addr_setup(struct mdss_data_type *mdata,
+ u32 *ctl_offsets, u32 *wb_offsets, u32 len)
+{
+ struct mdss_mdp_ctl *head;
+ u32 i;
+
+ head = devm_kzalloc(&mdata->pdev->dev, sizeof(struct mdss_mdp_ctl) *
+ len, GFP_KERNEL);
+
+ if (!head) {
+ pr_err("unable to setup ctl and wb: kzalloc fail\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < len; i++) {
+ head[i].num = i;
+ head[i].base = (mdata->mdp_base) + ctl_offsets[i];
+ head[i].wb_base = (mdata->mdp_base) + wb_offsets[i];
+ head[i].ref_cnt = 0;
+ }
+
+ mdata->ctl_off = head;
+
+ return 0;
+}
+
struct mdss_mdp_mixer *mdss_mdp_mixer_get(struct mdss_mdp_ctl *ctl, int mux)
{
struct mdss_mdp_mixer *mixer = NULL;
@@ -1096,7 +1183,7 @@
}
if (perf_update == MDSS_MDP_PERF_UPDATE_EARLY)
- mdss_mdp_ctl_perf_commit(update_flags);
+ mdss_mdp_ctl_perf_commit(ctl->mdata, update_flags);
if (mixer1_changed)
mdss_mdp_mixer_update(ctl->mixer_left);
@@ -1132,7 +1219,7 @@
ctl->play_cnt++;
if (perf_update == MDSS_MDP_PERF_UPDATE_LATE)
- mdss_mdp_ctl_perf_commit(update_flags);
+ mdss_mdp_ctl_perf_commit(ctl->mdata, update_flags);
done:
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
@@ -1146,10 +1233,12 @@
{
int i;
struct mdss_mdp_ctl *ctl;
+ struct mdss_data_type *mdata;
u32 mixer_cnt = 0;
mutex_lock(&mdss_mdp_ctl_lock);
- for (i = 0; i < MDSS_MDP_MAX_CTL; i++) {
- ctl = &mdss_mdp_ctl_list[i];
+ mdata = mdss_mdp_get_mdata();
+ for (i = 0; i < mdata->nctl; i++) {
+ ctl = mdata->ctl_off + i;
if ((ctl->power_on) && (ctl->mfd) &&
(ctl->mfd->index == fb_num)) {
if (ctl->mixer_left) {
diff --git a/drivers/video/msm/mdss/mdss_mdp_hwio.h b/drivers/video/msm/mdss/mdss_mdp_hwio.h
index 0d530b5..1c5c4b8 100644
--- a/drivers/video/msm/mdss/mdss_mdp_hwio.h
+++ b/drivers/video/msm/mdss/mdss_mdp_hwio.h
@@ -21,6 +21,9 @@
#define ENHIST_LUT_ENTRIES 256
#define HIST_V_SIZE 256
+#define MDSS_MDP_HW_REV_100 0x10000000
+#define MDSS_MDP_HW_REV_102 0x10020000
+
#define MDSS_REG_HW_VERSION 0x0
#define MDSS_REG_HW_INTR_STATUS 0x10
@@ -222,13 +225,17 @@
#define MDSS_MDP_NUM_REG_MIXERS 3
#define MDSS_MDP_NUM_WB_MIXERS 2
-enum mdss_mdp_mixer_index {
- MDSS_MDP_LAYERMIXER0,
- MDSS_MDP_LAYERMIXER1,
- MDSS_MDP_LAYERMIXER2,
- MDSS_MDP_LAYERMIXER3,
- MDSS_MDP_LAYERMIXER4,
- MDSS_MDP_MAX_LAYERMIXER
+enum mdss_mdp_mixer_intf_index {
+ MDSS_MDP_INTF_LAYERMIXER0,
+ MDSS_MDP_INTF_LAYERMIXER1,
+ MDSS_MDP_INTF_LAYERMIXER2,
+ MDSS_MDP_INTF_MAX_LAYERMIXER,
+};
+
+enum mdss_mdp_mixer_wb_index {
+ MDSS_MDP_WB_LAYERMIXER0,
+ MDSS_MDP_WB_LAYERMIXER1,
+ MDSS_MDP_WB_MAX_LAYERMIXER,
};
enum mdss_mdp_stage_index {
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_video.c b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
index 0cba9c3..1aea4e0 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_video.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -38,9 +38,8 @@
u32 hsync_skew;
};
-#define MAX_SESSIONS 3
struct mdss_mdp_video_ctx {
- u32 pp_num;
+ u32 intf_num;
char __iomem *base;
u32 intf_type;
u8 ref_cnt;
@@ -53,14 +52,36 @@
mdp_vsync_handler_t vsync_handler;
};
-struct mdss_mdp_video_ctx mdss_mdp_video_ctx_list[MAX_SESSIONS];
-
static inline void mdp_video_write(struct mdss_mdp_video_ctx *ctx,
u32 reg, u32 val)
{
writel_relaxed(val, ctx->base + reg);
}
+int mdss_mdp_video_addr_setup(struct mdss_data_type *mdata,
+ u32 *offsets, u32 count)
+{
+ struct mdss_mdp_video_ctx *head;
+ u32 i;
+
+ head = devm_kzalloc(&mdata->pdev->dev,
+ sizeof(struct mdss_mdp_video_ctx) * count, GFP_KERNEL);
+ if (!head)
+ return -ENOMEM;
+
+ for (i = 0; i < count; i++) {
+ head[i].base = mdata->mdp_base + offsets[i];
+ pr_debug("adding Video Intf #%d offset=0x%x virt=%p\n", i,
+ offsets[i], head[i].base);
+ head[i].ref_cnt = 0;
+ head[i].intf_num = i + MDSS_MDP_INTF0;
+ }
+
+ mdata->video_intf = head;
+ mdata->nintf = count;
+ return 0;
+}
+
static int mdss_mdp_video_timegen_setup(struct mdss_mdp_video_ctx *ctx,
struct intf_timing_params *p)
{
@@ -228,10 +249,8 @@
mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_INTF_VSYNC, ctl->intf_num,
NULL, NULL);
- mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_PING_PONG_COMP, ctx->pp_num,
- NULL, NULL);
- memset(ctx, 0, sizeof(*ctx));
+ ctx->ref_cnt--;
return 0;
}
@@ -301,12 +320,14 @@
int mdss_mdp_video_start(struct mdss_mdp_ctl *ctl)
{
+ struct mdss_data_type *mdata;
struct mdss_panel_info *pinfo;
struct mdss_mdp_video_ctx *ctx;
struct mdss_mdp_mixer *mixer;
struct intf_timing_params itp = {0};
int i;
+ mdata = ctl->mdata;
pinfo = &ctl->panel_data->panel_info;
mixer = mdss_mdp_mixer_get(ctl, MDSS_MDP_MIXER_MUX_LEFT);
@@ -315,23 +336,23 @@
return -ENODEV;
}
+ i = ctl->intf_num - MDSS_MDP_INTF0;
+ if (i < mdata->nintf) {
+ ctx = ((struct mdss_mdp_video_ctx *) mdata->video_intf) + i;
+ if (ctx->ref_cnt) {
+ pr_err("Intf %d already in use\n", ctl->intf_num);
+ return -EBUSY;
+ }
+ pr_debug("video Intf #%d base=%p", ctx->intf_num, ctx->base);
+ ctx->ref_cnt++;
+ } else {
+ pr_err("Invalid intf number: %d\n", ctl->intf_num);
+ return -EINVAL;
+ }
+
pr_debug("start ctl=%u\n", ctl->num);
- for (i = 0; i < MAX_SESSIONS; i++) {
- ctx = &mdss_mdp_video_ctx_list[i];
- if (ctx->ref_cnt == 0) {
- ctx->ref_cnt++;
- break;
- }
- }
- if (i == MAX_SESSIONS) {
- pr_err("too many sessions\n");
- return -ENOMEM;
- }
ctl->priv_data = ctx;
- ctx->base = ctl->mdata->mdp_base +
- MDSS_MDP_REG_INTF_OFFSET(ctl->intf_num);
- ctx->pp_num = mixer->num;
ctx->intf_type = ctl->intf_type;
init_completion(&ctx->vsync_comp);
spin_lock_init(&ctx->vsync_lock);
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c b/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
index ee95396..97428cd 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
@@ -109,6 +109,7 @@
struct mdss_mdp_format_params *fmt;
u32 dst_format, pattern, ystride0, ystride1, outsize, chroma_samp;
u32 opmode = ctx->opmode;
+ struct mdss_data_type *mdata;
pr_debug("wb_num=%d format=%d\n", ctx->wb_num, ctx->format);
@@ -162,8 +163,19 @@
}
if (fmt->fetch_planes != MDSS_MDP_PLANE_PLANAR) {
- pattern = (fmt->element[3] << 24) | (fmt->element[2] << 15) |
- (fmt->element[1] << 8) | (fmt->element[0] << 0);
+ mdata = mdss_mdp_get_mdata();
+ if (mdata && mdata->mdp_rev >= MDSS_MDP_HW_REV_102) {
+ pattern = (fmt->element[3] << 24) |
+ (fmt->element[2] << 16) |
+ (fmt->element[1] << 8) |
+ (fmt->element[0] << 0);
+ } else {
+ pattern = (fmt->element[3] << 24) |
+ (fmt->element[2] << 15) |
+ (fmt->element[1] << 8) |
+ (fmt->element[0] << 0);
+ }
+
dst_format |= (fmt->unpack_align_msb << 18) |
(fmt->unpack_tight << 17) |
((fmt->unpack_count - 1) << 12) |
@@ -356,7 +368,7 @@
}
ctl->priv_data = ctx;
ctx->wb_num = ctl->num; /* wb num should match ctl num */
- ctx->base = ctl->mdata->mdp_base + MDSS_MDP_REG_WB_OFFSET(ctx->wb_num);
+ ctx->base = ctl->wb_base;
ctx->initialized = false;
mdss_mdp_set_intr_callback(ctx->intr_type, ctx->intf_num,
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index c5ccbc9..283d3f0 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -39,7 +39,7 @@
{
struct mdss_mdp_pipe *pipe;
- pipe = mdss_mdp_pipe_get(req->id);
+ pipe = mdss_mdp_pipe_get(mfd->mdata, req->id);
if (IS_ERR_OR_NULL(pipe)) {
pr_err("invalid pipe ndx=%x\n", req->id);
return pipe ? PTR_ERR(pipe) : -ENODEV;
@@ -306,7 +306,7 @@
pipe->mfd = mfd;
pipe->play_cnt = 0;
} else {
- pipe = mdss_mdp_pipe_get(req->id);
+ pipe = mdss_mdp_pipe_get(mfd->mdata, req->id);
if (IS_ERR_OR_NULL(pipe)) {
pr_err("invalid pipe ndx=%x\n", req->id);
return pipe ? PTR_ERR(pipe) : -ENODEV;
@@ -518,7 +518,7 @@
pipe_ndx = BIT(i);
if (pipe_ndx & ndx) {
unset_ndx |= pipe_ndx;
- pipe = mdss_mdp_pipe_get(pipe_ndx);
+ pipe = mdss_mdp_pipe_get(mfd->mdata, pipe_ndx);
if (IS_ERR_OR_NULL(pipe)) {
pr_warn("unknown pipe ndx=%x\n", pipe_ndx);
continue;
@@ -659,7 +659,7 @@
int ret;
u32 flags;
- pipe = mdss_mdp_pipe_get(req->id);
+ pipe = mdss_mdp_pipe_get(mfd->mdata, req->id);
if (IS_ERR_OR_NULL(pipe)) {
pr_err("pipe ndx=%x doesn't exist\n", req->id);
return pipe ? PTR_ERR(pipe) : -ENODEV;
diff --git a/drivers/video/msm/mdss/mdss_mdp_pipe.c b/drivers/video/msm/mdss/mdss_mdp_pipe.c
index 7451a80..0a52561 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pipe.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pipe.c
@@ -25,8 +25,8 @@
static DEFINE_MUTEX(mdss_mdp_smp_lock);
static DECLARE_BITMAP(mdss_mdp_smp_mmb_pool, MDSS_MDP_SMP_MMB_BLOCKS);
-static struct mdss_mdp_pipe mdss_mdp_pipe_list[MDSS_MDP_MAX_SSPP];
-
+static struct mdss_mdp_pipe *mdss_mdp_pipe_search(struct mdss_data_type *mdata,
+ u32 ndx);
static int mdss_mdp_pipe_free(struct mdss_mdp_pipe *pipe);
static u32 mdss_mdp_smp_mmb_reserve(unsigned long *smp, size_t n)
@@ -119,42 +119,10 @@
static int mdss_mdp_smp_alloc(struct mdss_mdp_pipe *pipe)
{
- u32 client_id;
int i;
-
- switch (pipe->num) {
- case MDSS_MDP_SSPP_VIG0:
- client_id = MDSS_MDP_SMP_CLIENT_VIG0_FETCH_Y;
- break;
- case MDSS_MDP_SSPP_VIG1:
- client_id = MDSS_MDP_SMP_CLIENT_VIG1_FETCH_Y;
- break;
- case MDSS_MDP_SSPP_VIG2:
- client_id = MDSS_MDP_SMP_CLIENT_VIG2_FETCH_Y;
- break;
- case MDSS_MDP_SSPP_RGB0:
- client_id = MDSS_MDP_SMP_CLIENT_RGB0_FETCH;
- break;
- case MDSS_MDP_SSPP_RGB1:
- client_id = MDSS_MDP_SMP_CLIENT_RGB1_FETCH;
- break;
- case MDSS_MDP_SSPP_RGB2:
- client_id = MDSS_MDP_SMP_CLIENT_RGB2_FETCH;
- break;
- case MDSS_MDP_SSPP_DMA0:
- client_id = MDSS_MDP_SMP_CLIENT_DMA0_FETCH_Y;
- break;
- case MDSS_MDP_SSPP_DMA1:
- client_id = MDSS_MDP_SMP_CLIENT_DMA1_FETCH_Y;
- break;
- default:
- pr_err("no valid smp client for pnum=%d\n", pipe->num);
- return -EINVAL;
- }
-
mutex_lock(&mdss_mdp_smp_lock);
for (i = 0; i < pipe->src_planes.num_planes; i++)
- mdss_mdp_smp_mmb_set(client_id + i, &pipe->smp[i]);
+ mdss_mdp_smp_mmb_set(pipe->ftch_id + i, &pipe->smp[i]);
mutex_unlock(&mdss_mdp_smp_lock);
return 0;
}
@@ -179,88 +147,134 @@
return 0;
}
-static struct mdss_mdp_pipe *mdss_mdp_pipe_init(
- struct mdss_mdp_mixer *mixer, u32 pnum)
+static struct mdss_mdp_pipe *mdss_mdp_pipe_init(struct mdss_mdp_mixer *mixer,
+ u32 type)
{
- struct mdss_mdp_pipe *pipe = NULL;
+ struct mdss_mdp_pipe *pipe;
struct mdss_data_type *mdata;
+ struct mdss_mdp_pipe *pipe_pool = NULL;
+ u32 npipes;
+ u32 i;
if (!mixer || !mixer->ctl || !mixer->ctl->mdata)
return NULL;
mdata = mixer->ctl->mdata;
- pipe = &mdss_mdp_pipe_list[pnum];
- if (atomic_cmpxchg(&pipe->ref_cnt, 0, 1) == 0) {
- pipe->num = pnum;
- pipe->type = mdss_res->pipe_type_map[pnum];
- pipe->ndx = BIT(pnum);
- pipe->base = mdata->mdp_base + MDSS_MDP_REG_SSPP_OFFSET(pnum);
+ switch (type) {
+ case MDSS_MDP_PIPE_TYPE_VIG:
+ pipe_pool = mdata->vig_pipes;
+ npipes = mdata->nvig_pipes;
+ break;
+
+ case MDSS_MDP_PIPE_TYPE_RGB:
+ pipe_pool = mdata->rgb_pipes;
+ npipes = mdata->nrgb_pipes;
+ break;
+
+ case MDSS_MDP_PIPE_TYPE_DMA:
+ pipe_pool = mdata->dma_pipes;
+ npipes = mdata->ndma_pipes;
+ break;
+
+ default:
+ npipes = 0;
+ pr_err("invalid pipe type %d\n", type);
+ break;
+ }
+
+ for (i = 0; i < npipes; i++) {
+ pipe = pipe_pool + i;
+ if (atomic_cmpxchg(&pipe->ref_cnt, 0, 1) == 0) {
+ pipe->mixer = mixer;
+ break;
+ }
+ pipe = NULL;
+ }
+
+ if (pipe)
+ pr_debug("type=%x pnum=%d\n", pipe->type, pipe->num);
+ else
+ pr_err("no %d type pipes available\n", type);
+
+ return pipe;
+}
+
+struct mdss_mdp_pipe *mdss_mdp_pipe_alloc_dma(struct mdss_mdp_mixer *mixer)
+{
+ struct mdss_mdp_pipe *pipe = NULL;
+ struct mdss_data_type *mdata;
+ u32 pnum;
+
+ mutex_lock(&mdss_mdp_sspp_lock);
+ mdata = mixer->ctl->mdata;
+ pnum = mixer->num;
+
+ if (atomic_cmpxchg(&((mdata->dma_pipes[pnum]).ref_cnt), 0, 1) == 0) {
+ pipe = &mdata->dma_pipes[pnum];
pipe->mixer = mixer;
- pr_debug("ndx=%x pnum=%d\n", pipe->ndx, pipe->num);
-
- return pipe;
+ } else {
+ pr_err("DMA pnum%d\t not available\n", pnum);
}
- return NULL;
-}
-
-struct mdss_mdp_pipe *mdss_mdp_pipe_alloc_pnum(
- struct mdss_mdp_mixer *mixer, u32 pnum)
-{
- struct mdss_mdp_pipe *pipe = NULL;
- mutex_lock(&mdss_mdp_sspp_lock);
- if (mdss_res->pipe_type_map[pnum] != MDSS_MDP_PIPE_TYPE_UNUSED)
- pipe = mdss_mdp_pipe_init(mixer, pnum);
mutex_unlock(&mdss_mdp_sspp_lock);
return pipe;
}
-struct mdss_mdp_pipe *mdss_mdp_pipe_alloc(
- struct mdss_mdp_mixer *mixer, u32 type)
+struct mdss_mdp_pipe *mdss_mdp_pipe_alloc(struct mdss_mdp_mixer *mixer,
+ u32 type)
{
- struct mdss_mdp_pipe *pipe = NULL;
- int pnum;
-
+ struct mdss_mdp_pipe *pipe;
mutex_lock(&mdss_mdp_sspp_lock);
- for (pnum = 0; pnum < MDSS_MDP_MAX_SSPP; pnum++) {
- if (type == mdss_res->pipe_type_map[pnum]) {
- pipe = mdss_mdp_pipe_init(mixer, pnum);
- if (pipe)
- break;
- }
- }
+ pipe = mdss_mdp_pipe_init(mixer, type);
mutex_unlock(&mdss_mdp_sspp_lock);
-
return pipe;
}
-struct mdss_mdp_pipe *mdss_mdp_pipe_get(u32 ndx)
+struct mdss_mdp_pipe *mdss_mdp_pipe_get(struct mdss_data_type *mdata, u32 ndx)
{
struct mdss_mdp_pipe *pipe = NULL;
- int i;
if (!ndx)
return ERR_PTR(-EINVAL);
mutex_lock(&mdss_mdp_sspp_lock);
- for (i = 0; i < MDSS_MDP_MAX_SSPP; i++) {
- pipe = &mdss_mdp_pipe_list[i];
- if (ndx == pipe->ndx) {
- if (mdss_mdp_pipe_map(pipe))
- pipe = ERR_PTR(-EACCES);
- break;
- }
- }
+
+ pipe = mdss_mdp_pipe_search(mdata, ndx);
+ if (!pipe)
+ return ERR_PTR(-EINVAL);
+
+ if (mdss_mdp_pipe_map(pipe))
+ return ERR_PTR(-EACCES);
+
mutex_unlock(&mdss_mdp_sspp_lock);
- if (i == MDSS_MDP_MAX_SSPP)
- return ERR_PTR(-ENODEV);
-
return pipe;
}
+static struct mdss_mdp_pipe *mdss_mdp_pipe_search(struct mdss_data_type *mdata,
+ u32 ndx)
+{
+ u32 i;
+ for (i = 0; i < mdata->nvig_pipes; i++) {
+ if (mdata->vig_pipes[i].ndx == ndx)
+ return &mdata->vig_pipes[i];
+ }
+
+ for (i = 0; i < mdata->nrgb_pipes; i++) {
+ if (mdata->rgb_pipes[i].ndx == ndx)
+ return &mdata->rgb_pipes[i];
+ }
+
+ for (i = 0; i < mdata->ndma_pipes; i++) {
+ if (mdata->dma_pipes[i].ndx == ndx)
+ return &mdata->dma_pipes[i];
+ }
+
+ return NULL;
+}
+
static int mdss_mdp_pipe_free(struct mdss_mdp_pipe *pipe)
{
pr_debug("ndx=%x pnum=%d ref_cnt=%d\n", pipe->ndx, pipe->num,
@@ -617,6 +631,53 @@
}
}
+int mdss_mdp_pipe_addr_setup(struct mdss_data_type *mdata, u32 *offsets,
+ u32 *ftch_id, u32 type, u32 num_base, u32 len)
+{
+ struct mdss_mdp_pipe *head;
+ u32 i;
+ int rc = 0;
+
+ head = devm_kzalloc(&mdata->pdev->dev, sizeof(struct mdss_mdp_pipe) *
+ len, GFP_KERNEL);
+
+ if (!head) {
+ pr_err("unable to setup pipe type=%d :devm_kzalloc fail\n",
+ type);
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < len; i++) {
+ head[i].type = type;
+ head[i].ftch_id = ftch_id[i];
+ head[i].num = i + num_base;
+ head[i].ndx = BIT(i + num_base);
+ head[i].base = mdata->mdp_base + offsets[i];
+ }
+
+ switch (type) {
+
+ case MDSS_MDP_PIPE_TYPE_VIG:
+ mdata->vig_pipes = head;
+ break;
+
+ case MDSS_MDP_PIPE_TYPE_RGB:
+ mdata->rgb_pipes = head;
+ break;
+
+ case MDSS_MDP_PIPE_TYPE_DMA:
+ mdata->dma_pipes = head;
+ break;
+
+ default:
+ pr_err("Invalid pipe type=%d\n", type);
+ rc = -EINVAL;
+ break;
+ }
+
+ return rc;
+}
+
static int mdss_mdp_src_addr_setup(struct mdss_mdp_pipe *pipe,
struct mdss_mdp_data *data)
{
diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c
index c14b2c2..ee48f31 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pp.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pp.c
@@ -887,7 +887,7 @@
{
int i;
u32 mixer_cnt;
- u32 mixer_id[MDSS_MDP_MAX_LAYERMIXER];
+ u32 mixer_id[MDSS_MDP_INTF_MAX_LAYERMIXER];
mixer_cnt = mdss_mdp_get_ctl_mixers(disp_num, mixer_id);
if (!mixer_cnt)
@@ -1599,7 +1599,7 @@
struct pp_hist_col_info *hist_info;
int i, ret = 0;
u32 disp_num, dspp_num = 0;
- u32 mixer_cnt, mixer_id[MDSS_MDP_MAX_LAYERMIXER];
+ u32 mixer_cnt, mixer_id[MDSS_MDP_INTF_MAX_LAYERMIXER];
unsigned long flag;
if ((req->block < MDP_LOGICAL_BLOCK_DISP_0) ||
@@ -1667,7 +1667,7 @@
int i, ret = 0;
u32 dspp_num, disp_num, ctl_base, done_bit;
struct pp_hist_col_info *hist_info;
- u32 mixer_cnt, mixer_id[MDSS_MDP_MAX_LAYERMIXER];
+ u32 mixer_cnt, mixer_id[MDSS_MDP_INTF_MAX_LAYERMIXER];
unsigned long flag;
if ((block < MDP_LOGICAL_BLOCK_DISP_0) ||
@@ -1726,7 +1726,7 @@
u32 timeout, v_base;
struct pp_hist_col_info *hist_info;
u32 dspp_num, disp_num, ctl_base;
- u32 mixer_cnt, mixer_id[MDSS_MDP_MAX_LAYERMIXER];
+ u32 mixer_cnt, mixer_id[MDSS_MDP_INTF_MAX_LAYERMIXER];
unsigned long flag;
if ((hist->block < MDP_LOGICAL_BLOCK_DISP_0) ||
diff --git a/drivers/video/msm/mdss/mdss_mdp_rotator.c b/drivers/video/msm/mdss/mdss_mdp_rotator.c
index 0ee336a..8bff5cb 100644
--- a/drivers/video/msm/mdss/mdss_mdp_rotator.c
+++ b/drivers/video/msm/mdss/mdss_mdp_rotator.c
@@ -70,25 +70,13 @@
{
struct mdss_mdp_mixer *mixer;
struct mdss_mdp_pipe *pipe = NULL;
- int pnum;
mixer = mdss_mdp_wb_mixer_alloc(1);
if (!mixer)
return NULL;
- switch (mixer->num) {
- case MDSS_MDP_LAYERMIXER3:
- pnum = MDSS_MDP_SSPP_DMA0;
- break;
- case MDSS_MDP_LAYERMIXER4:
- pnum = MDSS_MDP_SSPP_DMA1;
- break;
- default:
- goto done;
- }
+ pipe = mdss_mdp_pipe_alloc_dma(mixer);
- pipe = mdss_mdp_pipe_alloc_pnum(mixer, pnum);
-done:
if (!pipe)
mdss_mdp_wb_mixer_destroy(mixer);
diff --git a/include/linux/mfd/wcd9xxx/core.h b/include/linux/mfd/wcd9xxx/core.h
index 458f060..3ebf091 100644
--- a/include/linux/mfd/wcd9xxx/core.h
+++ b/include/linux/mfd/wcd9xxx/core.h
@@ -36,11 +36,14 @@
#define SITAR_IS_1P1(ver) \
((ver == SITAR_VERSION_1P1) ? 1 : 0)
-
-#define TAIKO_VERSION_1_0 0
+#define TAIKO_VERSION_1_0 1
#define TAIKO_IS_1_0(ver) \
((ver == TAIKO_VERSION_1_0) ? 1 : 0)
+enum wcd9xxx_slim_slave_addr_type {
+ WCD9XXX_SLIM_SLAVE_ADDR_TYPE_TABLA,
+ WCD9XXX_SLIM_SLAVE_ADDR_TYPE_TAIKO,
+};
enum {
/* INTR_REG 0 */
@@ -186,6 +189,8 @@
struct wcd9xxx_ch *rx_chs;
struct wcd9xxx_ch *tx_chs;
u32 mclk_rate;
+
+ enum wcd9xxx_slim_slave_addr_type slim_slave_type;
};
int wcd9xxx_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg);
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index b362d7a..d683856 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -199,6 +199,7 @@
THRESHOLD,
LARGE_SEC_ALIGN,
RANDOM,
+ FUA,
MAX_REASONS,
};
diff --git a/include/linux/test-iosched.h b/include/linux/test-iosched.h
index 3690160..89d3b30 100644
--- a/include/linux/test-iosched.h
+++ b/include/linux/test-iosched.h
@@ -23,7 +23,7 @@
/*
* Patterns definitions for read/write requests data
*/
-#define TEST_PATTERN_SEQUENTIAL -1
+#define TEST_PATTERN_SEQUENTIAL 0x12345678
#define TEST_PATTERN_5A 0x5A5A5A5A
#define TEST_PATTERN_FF 0xFFFFFFFF
#define TEST_NO_PATTERN 0xDEADBEEF
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index df34213..155585a 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -298,6 +298,9 @@
config SND_SOC_WCD9306
tristate
+config SND_SOC_MSM8X10_WCD
+ tristate
+
config SND_SOC_WL1273
tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 11338aa..0f14dc3 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -52,7 +52,8 @@
snd-soc-wcd9310-objs := wcd9310.o wcd9310-tables.o
snd-soc-cs8427-objs := cs8427.o
snd-soc-wcd9320-objs := wcd9xxx-resmgr.o wcd9320.o wcd9320-tables.o wcd9xxx-mbhc.o
-snd-soc-wcd9306-objs := wcd9xxx-resmgr.o wcd9306.o wcd9306-tables.o wcd9xxx-mbhc.o
+snd-soc-wcd9306-objs := wcd9306.o wcd9306-tables.o
+snd-soc-msm8x10-wcd-objs := msm8x10-wcd.o msm8x10-wcd-tables.o
snd-soc-wl1273-objs := wl1273.o
snd-soc-wm1250-ev1-objs := wm1250-ev1.o
snd-soc-wm2000-objs := wm2000.o
@@ -163,7 +164,8 @@
obj-$(CONFIG_SND_SOC_WCD9310) += snd-soc-wcd9310.o
obj-$(CONFIG_SND_SOC_CS8427) += snd-soc-cs8427.o
obj-$(CONFIG_SND_SOC_WCD9320) += snd-soc-wcd9320.o
-obj-$(CONFIG_SND_SOC_WCD9306) += snd-soc-wcd9306.o
+obj-$(CONFIG_SND_SOC_WCD9306) += snd-soc-wcd9306.o wcd9xxx-resmgr.o wcd9xxx-mbhc.o
+obj-$(CONFIG_SND_SOC_MSM8X10_WCD) += snd-soc-msm8x10-wcd.o wcd9xxx-resmgr.o
obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o
obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o
obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o
diff --git a/sound/soc/codecs/msm8x10-wcd-tables.c b/sound/soc/codecs/msm8x10-wcd-tables.c
new file mode 100644
index 0000000..7e0263d
--- /dev/null
+++ b/sound/soc/codecs/msm8x10-wcd-tables.c
@@ -0,0 +1,794 @@
+/* Copyright (c) 2013, 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 <msm8x10_wcd_registers.h>
+#include "msm8x10-wcd.h"
+
+const u8 msm8x10_wcd_reg_readable[MSM8X10_WCD_CACHE_SIZE] = {
+ [MSM8X10_WCD_A_CHIP_CTL] = 1,
+ [MSM8X10_WCD_A_CHIP_STATUS] = 1,
+ [MSM8X10_WCD_A_CDC_TLMM_MODE_SELECT] = 1,
+ [MSM8X10_WCD_A_MODE_LOCK] = 0,
+ [MSM8X10_WCD_A_CHIP_ID_BYTE_0] = 1,
+ [MSM8X10_WCD_A_CHIP_ID_BYTE_1] = 1,
+ [MSM8X10_WCD_A_CHIP_ID_BYTE_2] = 1,
+ [MSM8X10_WCD_A_CHIP_ID_BYTE_3] = 1,
+ [MSM8X10_WCD_A_CHIP_VERSION] = 1,
+ [MSM8X10_WCD_A_ANALOG_SLAVE_ID] = 1,
+ [MSM8X10_WCD_A_PIN_CTL_OE] = 1,
+ [MSM8X10_WCD_A_PIN_CTL_DATA] = 1,
+ [MSM8X10_WCD_A_PIN_STATUS] = 1,
+ [MSM8X10_WCD_A_HDRIVE_CTL] = 1,
+ [MSM8X10_WCD_A_HDRIVE_I2C_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_RST_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_TOP_CLK_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_ANA_CLK_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_DIG_CLK_CTL] = 1,
+ [MSM8X10_WCD_A_PROCESS_MONITOR_CTL0] = 1,
+ [MSM8X10_WCD_A_PROCESS_MONITOR_CTL1] = 1,
+ [MSM8X10_WCD_A_PROCESS_MONITOR_CTL2] = 1,
+ [MSM8X10_WCD_A_PROCESS_MONITOR_CTL3] = 1,
+ [MSM8X10_WCD_A_QFUSE_CTL] = 1,
+ [MSM8X10_WCD_A_QFUSE_STATUS] = 1,
+ [MSM8X10_WCD_A_QFUSE_DATA_OUT0] = 1,
+ [MSM8X10_WCD_A_QFUSE_DATA_OUT1] = 1,
+ [MSM8X10_WCD_A_QFUSE_DATA_OUT2] = 1,
+ [MSM8X10_WCD_A_QFUSE_DATA_OUT3] = 1,
+ [MSM8X10_WCD_A_CDC_CONN_TX1_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CONN_TX2_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CONN_HPHR_DAC_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CONN_LO_DAC_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CONN_RX1_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CONN_RX2_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CONN_RX3_CTL] = 1,
+ [MSM8X10_WCD_A_DIGITAL_DEBUG_CTL] = 1,
+ [MSM8X10_WCD_A_ANALOG_DEBUG_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_RX1_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_RX2_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_RX3_CTL] = 1,
+ [MSM8X10_WCD_A_DEM_BYPASS_DATA0] = 1,
+ [MSM8X10_WCD_A_DEM_BYPASS_DATA1] = 1,
+ [MSM8X10_WCD_A_DEM_BYPASS_DATA2] = 1,
+ [MSM8X10_WCD_A_DEM_BYPASS_DATA3] = 1,
+ [MSM8X10_WCD_A_SPARE_0] = 1,
+ [MSM8X10_WCD_A_SPARE_1] = 1,
+ [MSM8X10_WCD_A_SPARE_2] = 1,
+ [MSM8X10_WCD_A_INTR_MODE] = 1,
+ [MSM8X10_WCD_A_INTR_MASK0] = 1,
+ [MSM8X10_WCD_A_INTR_MASK1] = 1,
+ [MSM8X10_WCD_A_INTR_MASK2] = 1,
+ [MSM8X10_WCD_A_INTR_STATUS0] = 1,
+ [MSM8X10_WCD_A_INTR_STATUS1] = 1,
+ [MSM8X10_WCD_A_INTR_STATUS2] = 1,
+ [MSM8X10_WCD_A_INTR_CLEAR0] = 0,
+ [MSM8X10_WCD_A_INTR_CLEAR1] = 0,
+ [MSM8X10_WCD_A_INTR_CLEAR2] = 0,
+ [MSM8X10_WCD_A_INTR_TEST0] = 1,
+ [MSM8X10_WCD_A_INTR_TEST1] = 1,
+ [MSM8X10_WCD_A_INTR_TEST2] = 1,
+ [MSM8X10_WCD_A_INTR_SET0] = 1,
+ [MSM8X10_WCD_A_INTR_SET1] = 1,
+ [MSM8X10_WCD_A_INTR_SET2] = 1,
+ [MSM8X10_WCD_A_CDC_MBHC_EN_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_MBHC_FIR_B1_CFG] = 1,
+ [MSM8X10_WCD_A_CDC_MBHC_FIR_B2_CFG] = 1,
+ [MSM8X10_WCD_A_CDC_MBHC_TIMER_B1_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_MBHC_TIMER_B2_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_MBHC_TIMER_B3_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_MBHC_TIMER_B4_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_MBHC_TIMER_B5_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_MBHC_TIMER_B6_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_MBHC_B1_STATUS] = 1,
+ [MSM8X10_WCD_A_CDC_MBHC_B2_STATUS] = 1,
+ [MSM8X10_WCD_A_CDC_MBHC_B3_STATUS] = 1,
+ [MSM8X10_WCD_A_CDC_MBHC_B4_STATUS] = 1,
+ [MSM8X10_WCD_A_CDC_MBHC_B5_STATUS] = 1,
+ [MSM8X10_WCD_A_CDC_MBHC_B1_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_MBHC_B2_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_MBHC_VOLT_B1_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_MBHC_VOLT_B2_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_MBHC_VOLT_B3_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_MBHC_VOLT_B4_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_MBHC_VOLT_B5_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_MBHC_VOLT_B6_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_MBHC_VOLT_B7_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_MBHC_VOLT_B8_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_MBHC_VOLT_B9_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_MBHC_VOLT_B10_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_MBHC_VOLT_B11_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_MBHC_VOLT_B12_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_MBHC_CLK_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_MBHC_INT_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_MBHC_DEBUG_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_MBHC_SPARE] = 1,
+ [MSM8X10_WCD_A_BIAS_REF_CTL] = 1,
+ [MSM8X10_WCD_A_BIAS_CENTRAL_BG_CTL] = 1,
+ [MSM8X10_WCD_A_BIAS_PRECHRG_CTL] = 1,
+ [MSM8X10_WCD_A_BIAS_CURR_CTL_1] = 1,
+ [MSM8X10_WCD_A_BIAS_CURR_CTL_2] = 1,
+ [MSM8X10_WCD_A_BIAS_OSC_BG_CTL] = 1,
+ [MSM8X10_WCD_A_MICB_CFILT_1_CTL] = 1,
+ [MSM8X10_WCD_A_MICB_CFILT_1_VAL] = 1,
+ [MSM8X10_WCD_A_MICB_CFILT_1_PRECHRG] = 1,
+ [MSM8X10_WCD_A_MICB_1_CTL] = 1,
+ [MSM8X10_WCD_A_MICB_1_INT_RBIAS] = 1,
+ [MSM8X10_WCD_A_MICB_1_MBHC] = 1,
+ [MSM8X10_WCD_A_MBHC_INSERT_DETECT] = 1,
+ [MSM8X10_WCD_A_MBHC_INSERT_DET_STATUS] = 1,
+ [MSM8X10_WCD_A_TX_COM_BIAS] = 1,
+ [MSM8X10_WCD_A_MBHC_SCALING_MUX_1] = 1,
+ [MSM8X10_WCD_A_MBHC_SCALING_MUX_2] = 1,
+ [MSM8X10_WCD_A_RESERVED_MAD_ANA_CTRL] = 1,
+ [MSM8X10_WCD_A_TX_SUP_SWITCH_CTRL_1] = 1,
+ [MSM8X10_WCD_A_TX_SUP_SWITCH_CTRL_2] = 1,
+ [MSM8X10_WCD_A_TX_1_EN] = 1,
+ [MSM8X10_WCD_A_TX_2_EN] = 1,
+ [MSM8X10_WCD_A_TX_1_2_ADC_CH1] = 1,
+ [MSM8X10_WCD_A_TX_1_2_ADC_CH2] = 1,
+ [MSM8X10_WCD_A_TX_1_2_ATEST_REFCTRL] = 1,
+ [MSM8X10_WCD_A_TX_1_2_TEST_CTL] = 1,
+ [MSM8X10_WCD_A_TX_1_2_TEST_BLOCK_EN] = 1,
+ [MSM8X10_WCD_A_TX_1_2_TXFE_CLKDIV] = 1,
+ [MSM8X10_WCD_A_TX_1_2_SAR_ERR_CH1] = 1,
+ [MSM8X10_WCD_A_TX_1_2_SAR_ERR_CH2] = 1,
+ [MSM8X10_WCD_A_TX_3_EN] = 1,
+ [MSM8X10_WCD_A_TX_1_2_TEST_EN] = 1,
+ [MSM8X10_WCD_A_TX_7_MBHC_EN_ATEST_CTRL] = 1,
+ [MSM8X10_WCD_A_TX_7_MBHC_SAR_ERR] = 1,
+ [MSM8X10_WCD_A_CP_EN] = 1,
+ [MSM8X10_WCD_A_CP_CLK] = 1,
+ [MSM8X10_WCD_A_CP_STATIC] = 1,
+ [MSM8X10_WCD_A_CP_DCC1] = 1,
+ [MSM8X10_WCD_A_CP_DCC3] = 1,
+ [MSM8X10_WCD_A_CP_ATEST] = 1,
+ [MSM8X10_WCD_A_CP_DTEST] = 1,
+ [MSM8X10_WCD_A_RX_AUX_SW_CTL] = 1,
+ [MSM8X10_WCD_A_RX_PA_AUX_IN_CONN] = 1,
+ [MSM8X10_WCD_A_RX_COM_TIMER_DIV] = 1,
+ [MSM8X10_WCD_A_RX_COM_OCP_CTL] = 1,
+ [MSM8X10_WCD_A_RX_COM_OCP_COUNT] = 1,
+ [MSM8X10_WCD_A_RX_COM_DAC_CTL] = 1,
+ [MSM8X10_WCD_A_RX_COM_BIAS] = 1,
+ [MSM8X10_WCD_A_RX_HPH_AUTO_CHOP] = 1,
+ [MSM8X10_WCD_A_RX_HPH_CHOP_CTL] = 1,
+ [MSM8X10_WCD_A_RX_HPH_BIAS_PA] = 1,
+ [MSM8X10_WCD_A_RX_HPH_BIAS_LDO] = 1,
+ [MSM8X10_WCD_A_RX_HPH_BIAS_CNP] = 1,
+ [MSM8X10_WCD_A_RX_HPH_BIAS_WG_OCP] = 1,
+ [MSM8X10_WCD_A_RX_HPH_OCP_CTL] = 1,
+ [MSM8X10_WCD_A_RX_HPH_CNP_EN] = 1,
+ [MSM8X10_WCD_A_RX_HPH_CNP_WG_CTL] = 1,
+ [MSM8X10_WCD_A_RX_HPH_CNP_WG_TIME] = 1,
+ [MSM8X10_WCD_A_RX_HPH_L_GAIN] = 1,
+ [MSM8X10_WCD_A_RX_HPH_L_TEST] = 1,
+ [MSM8X10_WCD_A_RX_HPH_L_PA_CTL] = 1,
+ [MSM8X10_WCD_A_RX_HPH_L_DAC_CTL] = 1,
+ [MSM8X10_WCD_A_RX_HPH_L_ATEST] = 1,
+ [MSM8X10_WCD_A_RX_HPH_L_STATUS] = 1,
+ [MSM8X10_WCD_A_RX_HPH_R_GAIN] = 1,
+ [MSM8X10_WCD_A_RX_HPH_R_TEST] = 1,
+ [MSM8X10_WCD_A_RX_HPH_R_PA_CTL] = 1,
+ [MSM8X10_WCD_A_RX_HPH_R_DAC_CTL] = 1,
+ [MSM8X10_WCD_A_RX_HPH_R_ATEST] = 1,
+ [MSM8X10_WCD_A_RX_HPH_R_STATUS] = 1,
+ [MSM8X10_WCD_A_RX_EAR_BIAS_PA] = 1,
+ [MSM8X10_WCD_A_RX_EAR_BIAS_CMBUFF] = 1,
+ [MSM8X10_WCD_A_RX_EAR_EN] = 1,
+ [MSM8X10_WCD_A_RX_EAR_GAIN] = 1,
+ [MSM8X10_WCD_A_RX_EAR_CMBUFF] = 1,
+ [MSM8X10_WCD_A_RX_EAR_ICTL] = 1,
+ [MSM8X10_WCD_A_RX_EAR_CCOMP] = 1,
+ [MSM8X10_WCD_A_RX_EAR_VCM] = 1,
+ [MSM8X10_WCD_A_RX_EAR_CNP] = 1,
+ [MSM8X10_WCD_A_RX_EAR_DAC_CTL_ATEST] = 1,
+ [MSM8X10_WCD_A_RX_EAR_STATUS] = 1,
+ [MSM8X10_WCD_A_RX_LINE_BIAS_PA] = 1,
+ [MSM8X10_WCD_A_RX_BUCK_BIAS1] = 1,
+ [MSM8X10_WCD_A_RX_BUCK_BIAS2] = 1,
+ [MSM8X10_WCD_A_RX_LINE_COM] = 1,
+ [MSM8X10_WCD_A_RX_LINE_CNP_EN] = 1,
+ [MSM8X10_WCD_A_RX_LINE_CNP_WG_CTL] = 1,
+ [MSM8X10_WCD_A_RX_LINE_CNP_WG_TIME] = 1,
+ [MSM8X10_WCD_A_RX_LINE_1_GAIN] = 1,
+ [MSM8X10_WCD_A_RX_LINE_1_TEST] = 1,
+ [MSM8X10_WCD_A_RX_LINE_1_DAC_CTL] = 1,
+ [MSM8X10_WCD_A_RX_LINE_1_STATUS] = 1,
+ [MSM8X10_WCD_A_RX_LINE_CNP_DBG] = 1,
+ [MSM8X10_WCD_A_SPKR_DRV_EN] = 1,
+ [MSM8X10_WCD_A_SPKR_DRV_GAIN] = 1,
+ [MSM8X10_WCD_A_SPKR_DRV_DAC_CTL] = 1,
+ [MSM8X10_WCD_A_SPKR_DRV_OCP_CTL] = 1,
+ [MSM8X10_WCD_A_SPKR_DRV_CLIP_DET] = 1,
+ [MSM8X10_WCD_A_SPKR_DRV_IEC] = 1,
+ [MSM8X10_WCD_A_SPKR_DRV_DBG_DAC] = 1,
+ [MSM8X10_WCD_A_SPKR_DRV_DBG_PA] = 1,
+ [MSM8X10_WCD_A_SPKR_DRV_DBG_PWRSTG] = 1,
+ [MSM8X10_WCD_A_SPKR_DRV_BIAS_LDO] = 1,
+ [MSM8X10_WCD_A_SPKR_DRV_BIAS_INT] = 1,
+ [MSM8X10_WCD_A_SPKR_DRV_BIAS_PA] = 1,
+ [MSM8X10_WCD_A_SPKR_DRV_STATUS_OCP] = 1,
+ [MSM8X10_WCD_A_SPKR_DRV_STATUS_PA] = 1,
+ [MSM8X10_WCD_A_RC_OSC_FREQ] = 1,
+ [MSM8X10_WCD_A_RC_OSC_TEST] = 1,
+ [MSM8X10_WCD_A_RC_OSC_STATUS] = 1,
+ [MSM8X10_WCD_A_RC_OSC_TUNER] = 1,
+ [MSM8X10_WCD_A_MBHC_HPH] = 1,
+ [MSM8X10_WCD_A_CDC_CLK_RX_RESET_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CLK_TX_RESET_B1_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CLK_DMIC_B1_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CLK_RX_I2S_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CLK_TX_I2S_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CLK_OTHR_RESET_B1_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CLK_TX_CLK_EN_B1_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CLK_OTHR_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CLK_RX_B1_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CLK_MCLK_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CLK_PDM_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CLK_SD_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_RX1_B1_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_RX2_B1_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_RX3_B1_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_RX1_B2_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_RX2_B2_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_RX3_B2_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_RX1_B3_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_RX2_B3_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_RX3_B3_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_RX1_B4_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_RX2_B4_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_RX3_B4_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_RX1_B5_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_RX2_B5_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_RX3_B5_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_RX1_B6_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_RX2_B6_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_RX3_B6_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_RX1_VOL_CTL_B1_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_RX2_VOL_CTL_B1_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_RX3_VOL_CTL_B1_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_RX1_VOL_CTL_B2_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_RX2_VOL_CTL_B2_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_RX3_VOL_CTL_B2_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B1_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B2_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B3_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B4_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CLSG_GAIN_THRESH_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CLSG_TIMER_B1_CFG] = 1,
+ [MSM8X10_WCD_A_CDC_CLSG_TIMER_B2_CFG] = 1,
+ [MSM8X10_WCD_A_CDC_CLSG_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_TX1_VOL_CTL_TIMER] = 1,
+ [MSM8X10_WCD_A_CDC_TX2_VOL_CTL_TIMER] = 1,
+ [MSM8X10_WCD_A_CDC_TX1_VOL_CTL_GAIN] = 1,
+ [MSM8X10_WCD_A_CDC_TX2_VOL_CTL_GAIN] = 1,
+ [MSM8X10_WCD_A_CDC_TX1_VOL_CTL_CFG] = 1,
+ [MSM8X10_WCD_A_CDC_TX2_VOL_CTL_CFG] = 1,
+ [MSM8X10_WCD_A_CDC_TX1_MUX_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_TX2_MUX_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_TX1_CLK_FS_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_TX2_CLK_FS_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_TX1_DMIC_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_TX2_DMIC_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_IIR1_GAIN_B1_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_IIR2_GAIN_B1_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_IIR1_GAIN_B2_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_IIR2_GAIN_B2_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_IIR1_GAIN_B3_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_IIR2_GAIN_B3_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_IIR1_GAIN_B4_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_IIR2_GAIN_B4_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_IIR1_GAIN_B5_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_IIR2_GAIN_B5_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_IIR1_GAIN_B6_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_IIR2_GAIN_B6_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_IIR1_GAIN_B7_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_IIR2_GAIN_B7_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_IIR1_GAIN_B8_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_IIR2_GAIN_B8_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_IIR1_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_IIR2_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_IIR1_GAIN_TIMER_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_IIR2_GAIN_TIMER_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_IIR1_COEF_B1_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_IIR2_COEF_B1_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_IIR1_COEF_B2_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_IIR2_COEF_B2_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CONN_RX1_B1_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CONN_RX1_B2_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CONN_RX1_B3_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CONN_RX2_B1_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CONN_RX2_B2_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CONN_RX2_B3_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CONN_RX3_B1_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CONN_RX3_B2_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CONN_TX_B1_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CONN_EQ1_B1_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CONN_EQ1_B2_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CONN_EQ1_B3_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CONN_EQ1_B4_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CONN_EQ2_B1_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CONN_EQ2_B2_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CONN_EQ2_B3_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CONN_EQ2_B4_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_CONN_TX_I2S_SD1_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_TOP_GAIN_UPDATE] = 1,
+ [MSM8X10_WCD_A_CDC_TOP_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_DEBUG_DESER1_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_DEBUG_DESER2_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_DEBUG_B1_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_DEBUG_B2_CTL] = 1,
+ [MSM8X10_WCD_A_CDC_DEBUG_B3_CTL] = 1,
+};
+
+const u8 msm8x10_wcd_reset_reg_defaults[MSM8X10_WCD_CACHE_SIZE] = {
+ [MSM8X10_WCD_A_CHIP_CTL] = MSM8X10_WCD_A_CHIP_CTL__POR,
+ [MSM8X10_WCD_A_CHIP_STATUS] = MSM8X10_WCD_A_CHIP_STATUS__POR,
+ [MSM8X10_WCD_A_CDC_TLMM_MODE_SELECT] =
+ MSM8X10_WCD_A_CDC_TLMM_MODE_SELECT__POR,
+ [MSM8X10_WCD_A_MODE_LOCK] = MSM8X10_WCD_A_MODE_LOCK__POR,
+ [MSM8X10_WCD_A_CHIP_ID_BYTE_0] = MSM8X10_WCD_A_CHIP_ID_BYTE_0__POR,
+ [MSM8X10_WCD_A_CHIP_ID_BYTE_1] = MSM8X10_WCD_A_CHIP_ID_BYTE_1__POR,
+ [MSM8X10_WCD_A_CHIP_ID_BYTE_2] = MSM8X10_WCD_A_CHIP_ID_BYTE_2__POR,
+ [MSM8X10_WCD_A_CHIP_ID_BYTE_3] = MSM8X10_WCD_A_CHIP_ID_BYTE_3__POR,
+ [MSM8X10_WCD_A_CHIP_VERSION] = MSM8X10_WCD_A_CHIP_VERSION__POR,
+ [MSM8X10_WCD_A_ANALOG_SLAVE_ID] = MSM8X10_WCD_A_ANALOG_SLAVE_ID__POR,
+ [MSM8X10_WCD_A_PIN_CTL_OE] = MSM8X10_WCD_A_PIN_CTL_OE__POR,
+ [MSM8X10_WCD_A_PIN_CTL_DATA] = MSM8X10_WCD_A_PIN_CTL_DATA__POR,
+ [MSM8X10_WCD_A_PIN_STATUS] = MSM8X10_WCD_A_PIN_STATUS__POR,
+ [MSM8X10_WCD_A_HDRIVE_CTL] = MSM8X10_WCD_A_HDRIVE_CTL__POR,
+ [MSM8X10_WCD_A_HDRIVE_I2C_CTL] = MSM8X10_WCD_A_HDRIVE_I2C_CTL__POR,
+ [MSM8X10_WCD_A_CDC_RST_CTL] = MSM8X10_WCD_A_CDC_RST_CTL__POR,
+ [MSM8X10_WCD_A_CDC_TOP_CLK_CTL] = MSM8X10_WCD_A_CDC_TOP_CLK_CTL__POR,
+ [MSM8X10_WCD_A_CDC_ANA_CLK_CTL] = MSM8X10_WCD_A_CDC_ANA_CLK_CTL__POR,
+ [MSM8X10_WCD_A_CDC_DIG_CLK_CTL] = MSM8X10_WCD_A_CDC_DIG_CLK_CTL__POR,
+ [MSM8X10_WCD_A_PROCESS_MONITOR_CTL0] =
+ MSM8X10_WCD_A_PROCESS_MONITOR_CTL0__POR,
+ [MSM8X10_WCD_A_PROCESS_MONITOR_CTL1] =
+ MSM8X10_WCD_A_PROCESS_MONITOR_CTL1__POR,
+ [MSM8X10_WCD_A_PROCESS_MONITOR_CTL2] =
+ MSM8X10_WCD_A_PROCESS_MONITOR_CTL2__POR,
+ [MSM8X10_WCD_A_PROCESS_MONITOR_CTL3] =
+ MSM8X10_WCD_A_PROCESS_MONITOR_CTL3__POR,
+ [MSM8X10_WCD_A_QFUSE_CTL] = MSM8X10_WCD_A_QFUSE_CTL__POR,
+ [MSM8X10_WCD_A_QFUSE_STATUS] = MSM8X10_WCD_A_QFUSE_STATUS__POR,
+ [MSM8X10_WCD_A_QFUSE_DATA_OUT0] = MSM8X10_WCD_A_QFUSE_DATA_OUT0__POR,
+ [MSM8X10_WCD_A_QFUSE_DATA_OUT1] = MSM8X10_WCD_A_QFUSE_DATA_OUT1__POR,
+ [MSM8X10_WCD_A_QFUSE_DATA_OUT2] = MSM8X10_WCD_A_QFUSE_DATA_OUT2__POR,
+ [MSM8X10_WCD_A_QFUSE_DATA_OUT3] = MSM8X10_WCD_A_QFUSE_DATA_OUT3__POR,
+ [MSM8X10_WCD_A_CDC_CONN_TX1_CTL] = MSM8X10_WCD_A_CDC_CONN_TX1_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CONN_TX2_CTL] = MSM8X10_WCD_A_CDC_CONN_TX2_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CONN_HPHR_DAC_CTL] =
+ MSM8X10_WCD_A_CDC_CONN_HPHR_DAC_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CONN_LO_DAC_CTL] =
+ MSM8X10_WCD_A_CDC_CONN_LO_DAC_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CONN_RX1_CTL] = MSM8X10_WCD_A_CDC_CONN_RX1_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CONN_RX2_CTL] = MSM8X10_WCD_A_CDC_CONN_RX2_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CONN_RX3_CTL] = MSM8X10_WCD_A_CDC_CONN_RX3_CTL__POR,
+ [MSM8X10_WCD_A_DIGITAL_DEBUG_CTL] =
+ MSM8X10_WCD_A_DIGITAL_DEBUG_CTL__POR,
+ [MSM8X10_WCD_A_ANALOG_DEBUG_CTL] = MSM8X10_WCD_A_ANALOG_DEBUG_CTL__POR,
+ [MSM8X10_WCD_A_CDC_RX1_CTL] = MSM8X10_WCD_A_CDC_RX1_CTL__POR,
+ [MSM8X10_WCD_A_CDC_RX2_CTL] = MSM8X10_WCD_A_CDC_RX2_CTL__POR,
+ [MSM8X10_WCD_A_CDC_RX3_CTL] = MSM8X10_WCD_A_CDC_RX3_CTL__POR,
+ [MSM8X10_WCD_A_DEM_BYPASS_DATA0] = MSM8X10_WCD_A_DEM_BYPASS_DATA0__POR,
+ [MSM8X10_WCD_A_DEM_BYPASS_DATA1] = MSM8X10_WCD_A_DEM_BYPASS_DATA1__POR,
+ [MSM8X10_WCD_A_DEM_BYPASS_DATA2] = MSM8X10_WCD_A_DEM_BYPASS_DATA2__POR,
+ [MSM8X10_WCD_A_DEM_BYPASS_DATA3] = MSM8X10_WCD_A_DEM_BYPASS_DATA3__POR,
+ [MSM8X10_WCD_A_SPARE_0] = MSM8X10_WCD_A_SPARE_0__POR,
+ [MSM8X10_WCD_A_SPARE_1] = MSM8X10_WCD_A_SPARE_1__POR,
+ [MSM8X10_WCD_A_SPARE_2] = MSM8X10_WCD_A_SPARE_2__POR,
+ [MSM8X10_WCD_A_INTR_MODE] = MSM8X10_WCD_A_INTR_MODE__POR,
+ [MSM8X10_WCD_A_INTR_MASK0] = MSM8X10_WCD_A_INTR_MASK0__POR,
+ [MSM8X10_WCD_A_INTR_MASK1] = MSM8X10_WCD_A_INTR_MASK1__POR,
+ [MSM8X10_WCD_A_INTR_MASK2] = MSM8X10_WCD_A_INTR_MASK2__POR,
+ [MSM8X10_WCD_A_INTR_STATUS0] = MSM8X10_WCD_A_INTR_STATUS0__POR,
+ [MSM8X10_WCD_A_INTR_STATUS1] = MSM8X10_WCD_A_INTR_STATUS1__POR,
+ [MSM8X10_WCD_A_INTR_STATUS2] = MSM8X10_WCD_A_INTR_STATUS2__POR,
+ [MSM8X10_WCD_A_INTR_CLEAR0] = MSM8X10_WCD_A_INTR_CLEAR0__POR,
+ [MSM8X10_WCD_A_INTR_CLEAR1] = MSM8X10_WCD_A_INTR_CLEAR1__POR,
+ [MSM8X10_WCD_A_INTR_CLEAR2] = MSM8X10_WCD_A_INTR_CLEAR2__POR,
+ [MSM8X10_WCD_A_INTR_TEST0] = MSM8X10_WCD_A_INTR_TEST0__POR,
+ [MSM8X10_WCD_A_INTR_TEST1] = MSM8X10_WCD_A_INTR_TEST1__POR,
+ [MSM8X10_WCD_A_INTR_TEST2] = MSM8X10_WCD_A_INTR_TEST2__POR,
+ [MSM8X10_WCD_A_INTR_SET0] = MSM8X10_WCD_A_INTR_SET0__POR,
+ [MSM8X10_WCD_A_INTR_SET1] = MSM8X10_WCD_A_INTR_SET1__POR,
+ [MSM8X10_WCD_A_INTR_SET2] = MSM8X10_WCD_A_INTR_SET2__POR,
+ [MSM8X10_WCD_A_CDC_MBHC_EN_CTL] = MSM8X10_WCD_A_CDC_MBHC_EN_CTL__POR,
+ [MSM8X10_WCD_A_CDC_MBHC_FIR_B1_CFG] =
+ MSM8X10_WCD_A_CDC_MBHC_FIR_B1_CFG__POR,
+ [MSM8X10_WCD_A_CDC_MBHC_FIR_B2_CFG] =
+ MSM8X10_WCD_A_CDC_MBHC_FIR_B2_CFG__POR,
+ [MSM8X10_WCD_A_CDC_MBHC_TIMER_B1_CTL] =
+ MSM8X10_WCD_A_CDC_MBHC_TIMER_B1_CTL__POR,
+ [MSM8X10_WCD_A_CDC_MBHC_TIMER_B2_CTL] =
+ MSM8X10_WCD_A_CDC_MBHC_TIMER_B2_CTL__POR,
+ [MSM8X10_WCD_A_CDC_MBHC_TIMER_B3_CTL] =
+ MSM8X10_WCD_A_CDC_MBHC_TIMER_B3_CTL__POR,
+ [MSM8X10_WCD_A_CDC_MBHC_TIMER_B4_CTL] =
+ MSM8X10_WCD_A_CDC_MBHC_TIMER_B4_CTL__POR,
+ [MSM8X10_WCD_A_CDC_MBHC_TIMER_B5_CTL] =
+ MSM8X10_WCD_A_CDC_MBHC_TIMER_B5_CTL__POR,
+ [MSM8X10_WCD_A_CDC_MBHC_TIMER_B6_CTL] =
+ MSM8X10_WCD_A_CDC_MBHC_TIMER_B6_CTL__POR,
+ [MSM8X10_WCD_A_CDC_MBHC_B1_STATUS] =
+ MSM8X10_WCD_A_CDC_MBHC_B1_STATUS__POR,
+ [MSM8X10_WCD_A_CDC_MBHC_B2_STATUS] =
+ MSM8X10_WCD_A_CDC_MBHC_B2_STATUS__POR,
+ [MSM8X10_WCD_A_CDC_MBHC_B3_STATUS] =
+ MSM8X10_WCD_A_CDC_MBHC_B3_STATUS__POR,
+ [MSM8X10_WCD_A_CDC_MBHC_B4_STATUS] =
+ MSM8X10_WCD_A_CDC_MBHC_B4_STATUS__POR,
+ [MSM8X10_WCD_A_CDC_MBHC_B5_STATUS] =
+ MSM8X10_WCD_A_CDC_MBHC_B5_STATUS__POR,
+ [MSM8X10_WCD_A_CDC_MBHC_B1_CTL] = MSM8X10_WCD_A_CDC_MBHC_B1_CTL__POR,
+ [MSM8X10_WCD_A_CDC_MBHC_B2_CTL] = MSM8X10_WCD_A_CDC_MBHC_B2_CTL__POR,
+ [MSM8X10_WCD_A_CDC_MBHC_VOLT_B1_CTL] =
+ MSM8X10_WCD_A_CDC_MBHC_VOLT_B1_CTL__POR,
+ [MSM8X10_WCD_A_CDC_MBHC_VOLT_B2_CTL] =
+ MSM8X10_WCD_A_CDC_MBHC_VOLT_B2_CTL__POR,
+ [MSM8X10_WCD_A_CDC_MBHC_VOLT_B3_CTL] =
+ MSM8X10_WCD_A_CDC_MBHC_VOLT_B3_CTL__POR,
+ [MSM8X10_WCD_A_CDC_MBHC_VOLT_B4_CTL] =
+ MSM8X10_WCD_A_CDC_MBHC_VOLT_B4_CTL__POR,
+ [MSM8X10_WCD_A_CDC_MBHC_VOLT_B5_CTL] =
+ MSM8X10_WCD_A_CDC_MBHC_VOLT_B5_CTL__POR,
+ [MSM8X10_WCD_A_CDC_MBHC_VOLT_B6_CTL] =
+ MSM8X10_WCD_A_CDC_MBHC_VOLT_B6_CTL__POR,
+ [MSM8X10_WCD_A_CDC_MBHC_VOLT_B7_CTL] =
+ MSM8X10_WCD_A_CDC_MBHC_VOLT_B7_CTL__POR,
+ [MSM8X10_WCD_A_CDC_MBHC_VOLT_B8_CTL] =
+ MSM8X10_WCD_A_CDC_MBHC_VOLT_B8_CTL__POR,
+ [MSM8X10_WCD_A_CDC_MBHC_VOLT_B9_CTL] =
+ MSM8X10_WCD_A_CDC_MBHC_VOLT_B9_CTL__POR,
+ [MSM8X10_WCD_A_CDC_MBHC_VOLT_B10_CTL] =
+ MSM8X10_WCD_A_CDC_MBHC_VOLT_B10_CTL__POR,
+ [MSM8X10_WCD_A_CDC_MBHC_VOLT_B11_CTL] =
+ MSM8X10_WCD_A_CDC_MBHC_VOLT_B11_CTL__POR,
+ [MSM8X10_WCD_A_CDC_MBHC_VOLT_B12_CTL] =
+ MSM8X10_WCD_A_CDC_MBHC_VOLT_B12_CTL__POR,
+ [MSM8X10_WCD_A_CDC_MBHC_CLK_CTL] = MSM8X10_WCD_A_CDC_MBHC_CLK_CTL__POR,
+ [MSM8X10_WCD_A_CDC_MBHC_INT_CTL] = MSM8X10_WCD_A_CDC_MBHC_INT_CTL__POR,
+ [MSM8X10_WCD_A_CDC_MBHC_DEBUG_CTL] =
+ MSM8X10_WCD_A_CDC_MBHC_DEBUG_CTL__POR,
+ [MSM8X10_WCD_A_CDC_MBHC_SPARE] = MSM8X10_WCD_A_CDC_MBHC_SPARE__POR,
+ [MSM8X10_WCD_A_BIAS_REF_CTL] = MSM8X10_WCD_A_BIAS_REF_CTL__POR,
+ [MSM8X10_WCD_A_BIAS_CENTRAL_BG_CTL] =
+ MSM8X10_WCD_A_BIAS_CENTRAL_BG_CTL__POR,
+ [MSM8X10_WCD_A_BIAS_PRECHRG_CTL] = MSM8X10_WCD_A_BIAS_PRECHRG_CTL__POR,
+ [MSM8X10_WCD_A_BIAS_CURR_CTL_1] = MSM8X10_WCD_A_BIAS_CURR_CTL_1__POR,
+ [MSM8X10_WCD_A_BIAS_CURR_CTL_2] = MSM8X10_WCD_A_BIAS_CURR_CTL_2__POR,
+ [MSM8X10_WCD_A_BIAS_OSC_BG_CTL] = MSM8X10_WCD_A_BIAS_OSC_BG_CTL__POR,
+ [MSM8X10_WCD_A_MICB_CFILT_1_CTL] = MSM8X10_WCD_A_MICB_CFILT_1_CTL__POR,
+ [MSM8X10_WCD_A_MICB_CFILT_1_VAL] = MSM8X10_WCD_A_MICB_CFILT_1_VAL__POR,
+ [MSM8X10_WCD_A_MICB_CFILT_1_PRECHRG] =
+ MSM8X10_WCD_A_MICB_CFILT_1_PRECHRG__POR,
+ [MSM8X10_WCD_A_MICB_1_CTL] = MSM8X10_WCD_A_MICB_1_CTL__POR,
+ [MSM8X10_WCD_A_MICB_1_INT_RBIAS] = MSM8X10_WCD_A_MICB_1_INT_RBIAS__POR,
+ [MSM8X10_WCD_A_MICB_1_MBHC] = MSM8X10_WCD_A_MICB_1_MBHC__POR,
+ [MSM8X10_WCD_A_MBHC_INSERT_DETECT] =
+ MSM8X10_WCD_A_MBHC_INSERT_DETECT__POR,
+ [MSM8X10_WCD_A_MBHC_INSERT_DET_STATUS] =
+ MSM8X10_WCD_A_MBHC_INSERT_DET_STATUS__POR,
+ [MSM8X10_WCD_A_TX_COM_BIAS] = MSM8X10_WCD_A_TX_COM_BIAS__POR,
+ [MSM8X10_WCD_A_MBHC_SCALING_MUX_1] =
+ MSM8X10_WCD_A_MBHC_SCALING_MUX_1__POR,
+ [MSM8X10_WCD_A_MBHC_SCALING_MUX_2] =
+ MSM8X10_WCD_A_MBHC_SCALING_MUX_2__POR,
+ [MSM8X10_WCD_A_RESERVED_MAD_ANA_CTRL] =
+ MSM8X10_WCD_A_RESERVED_MAD_ANA_CTRL__POR,
+ [MSM8X10_WCD_A_TX_SUP_SWITCH_CTRL_1] =
+ MSM8X10_WCD_A_TX_SUP_SWITCH_CTRL_1__POR,
+ [MSM8X10_WCD_A_TX_SUP_SWITCH_CTRL_2] =
+ MSM8X10_WCD_A_TX_SUP_SWITCH_CTRL_2__POR,
+ [MSM8X10_WCD_A_TX_1_EN] = MSM8X10_WCD_A_TX_1_EN__POR,
+ [MSM8X10_WCD_A_TX_2_EN] = MSM8X10_WCD_A_TX_2_EN__POR,
+ [MSM8X10_WCD_A_TX_1_2_ADC_CH1] = MSM8X10_WCD_A_TX_1_2_ADC_CH1__POR,
+ [MSM8X10_WCD_A_TX_1_2_ADC_CH2] = MSM8X10_WCD_A_TX_1_2_ADC_CH2__POR,
+ [MSM8X10_WCD_A_TX_1_2_ATEST_REFCTRL] =
+ MSM8X10_WCD_A_TX_1_2_ATEST_REFCTRL__POR,
+ [MSM8X10_WCD_A_TX_1_2_TEST_CTL] =
+ MSM8X10_WCD_A_TX_1_2_TEST_CTL__POR,
+ [MSM8X10_WCD_A_TX_1_2_TEST_BLOCK_EN] =
+ MSM8X10_WCD_A_TX_1_2_TEST_BLOCK_EN__POR,
+ [MSM8X10_WCD_A_TX_1_2_TXFE_CLKDIV] =
+ MSM8X10_WCD_A_TX_1_2_TXFE_CLKDIV__POR,
+ [MSM8X10_WCD_A_TX_1_2_SAR_ERR_CH1] =
+ MSM8X10_WCD_A_TX_1_2_SAR_ERR_CH1__POR,
+ [MSM8X10_WCD_A_TX_1_2_SAR_ERR_CH2] =
+ MSM8X10_WCD_A_TX_1_2_SAR_ERR_CH2__POR,
+ [MSM8X10_WCD_A_TX_3_EN] = MSM8X10_WCD_A_TX_3_EN__POR,
+ [MSM8X10_WCD_A_TX_1_2_TEST_EN] = MSM8X10_WCD_A_TX_1_2_TEST_EN__POR,
+ [MSM8X10_WCD_A_TX_7_MBHC_EN_ATEST_CTRL] =
+ MSM8X10_WCD_A_TX_7_MBHC_EN_ATEST_CTRL__POR,
+ [MSM8X10_WCD_A_TX_7_MBHC_SAR_ERR] =
+ MSM8X10_WCD_A_TX_7_MBHC_SAR_ERR__POR,
+ [MSM8X10_WCD_A_CP_EN] = MSM8X10_WCD_A_CP_EN__POR,
+ [MSM8X10_WCD_A_CP_CLK] = MSM8X10_WCD_A_CP_CLK__POR,
+ [MSM8X10_WCD_A_CP_STATIC] = MSM8X10_WCD_A_CP_STATIC__POR,
+ [MSM8X10_WCD_A_CP_DCC1] = MSM8X10_WCD_A_CP_DCC1__POR,
+ [MSM8X10_WCD_A_CP_DCC3] = MSM8X10_WCD_A_CP_DCC3__POR,
+ [MSM8X10_WCD_A_CP_ATEST] = MSM8X10_WCD_A_CP_ATEST__POR,
+ [MSM8X10_WCD_A_CP_DTEST] = MSM8X10_WCD_A_CP_DTEST__POR,
+ [MSM8X10_WCD_A_RX_AUX_SW_CTL] = MSM8X10_WCD_A_RX_AUX_SW_CTL__POR,
+ [MSM8X10_WCD_A_RX_PA_AUX_IN_CONN] =
+ MSM8X10_WCD_A_RX_PA_AUX_IN_CONN__POR,
+ [MSM8X10_WCD_A_RX_COM_TIMER_DIV] = MSM8X10_WCD_A_RX_COM_TIMER_DIV__POR,
+ [MSM8X10_WCD_A_RX_COM_OCP_CTL] = MSM8X10_WCD_A_RX_COM_OCP_CTL__POR,
+ [MSM8X10_WCD_A_RX_COM_OCP_COUNT] = MSM8X10_WCD_A_RX_COM_OCP_COUNT__POR,
+ [MSM8X10_WCD_A_RX_COM_DAC_CTL] = MSM8X10_WCD_A_RX_COM_DAC_CTL__POR,
+ [MSM8X10_WCD_A_RX_COM_BIAS] = MSM8X10_WCD_A_RX_COM_BIAS__POR,
+ [MSM8X10_WCD_A_RX_HPH_AUTO_CHOP] = MSM8X10_WCD_A_RX_HPH_AUTO_CHOP__POR,
+ [MSM8X10_WCD_A_RX_HPH_CHOP_CTL] = MSM8X10_WCD_A_RX_HPH_CHOP_CTL__POR,
+ [MSM8X10_WCD_A_RX_HPH_BIAS_PA] = MSM8X10_WCD_A_RX_HPH_BIAS_PA__POR,
+ [MSM8X10_WCD_A_RX_HPH_BIAS_LDO] = MSM8X10_WCD_A_RX_HPH_BIAS_LDO__POR,
+ [MSM8X10_WCD_A_RX_HPH_BIAS_CNP] = MSM8X10_WCD_A_RX_HPH_BIAS_CNP__POR,
+ [MSM8X10_WCD_A_RX_HPH_BIAS_WG_OCP] =
+ MSM8X10_WCD_A_RX_HPH_BIAS_WG_OCP__POR,
+ [MSM8X10_WCD_A_RX_HPH_OCP_CTL] = MSM8X10_WCD_A_RX_HPH_OCP_CTL__POR,
+ [MSM8X10_WCD_A_RX_HPH_CNP_EN] = MSM8X10_WCD_A_RX_HPH_CNP_EN__POR,
+ [MSM8X10_WCD_A_RX_HPH_CNP_WG_CTL] =
+ MSM8X10_WCD_A_RX_HPH_CNP_WG_CTL__POR,
+ [MSM8X10_WCD_A_RX_HPH_CNP_WG_TIME] =
+ MSM8X10_WCD_A_RX_HPH_CNP_WG_TIME__POR,
+ [MSM8X10_WCD_A_RX_HPH_L_GAIN] = MSM8X10_WCD_A_RX_HPH_L_GAIN__POR,
+ [MSM8X10_WCD_A_RX_HPH_L_TEST] = MSM8X10_WCD_A_RX_HPH_L_TEST__POR,
+ [MSM8X10_WCD_A_RX_HPH_L_PA_CTL] = MSM8X10_WCD_A_RX_HPH_L_PA_CTL__POR,
+ [MSM8X10_WCD_A_RX_HPH_L_DAC_CTL] =
+ MSM8X10_WCD_A_RX_HPH_L_DAC_CTL__POR,
+ [MSM8X10_WCD_A_RX_HPH_L_ATEST] = MSM8X10_WCD_A_RX_HPH_L_ATEST__POR,
+ [MSM8X10_WCD_A_RX_HPH_L_STATUS] = MSM8X10_WCD_A_RX_HPH_L_STATUS__POR,
+ [MSM8X10_WCD_A_RX_HPH_R_GAIN] = MSM8X10_WCD_A_RX_HPH_R_GAIN__POR,
+ [MSM8X10_WCD_A_RX_HPH_R_TEST] = MSM8X10_WCD_A_RX_HPH_R_TEST__POR,
+ [MSM8X10_WCD_A_RX_HPH_R_PA_CTL] = MSM8X10_WCD_A_RX_HPH_R_PA_CTL__POR,
+ [MSM8X10_WCD_A_RX_HPH_R_DAC_CTL] = MSM8X10_WCD_A_RX_HPH_R_DAC_CTL__POR,
+ [MSM8X10_WCD_A_RX_HPH_R_ATEST] = MSM8X10_WCD_A_RX_HPH_R_ATEST__POR,
+ [MSM8X10_WCD_A_RX_HPH_R_STATUS] = MSM8X10_WCD_A_RX_HPH_R_STATUS__POR,
+ [MSM8X10_WCD_A_RX_EAR_BIAS_PA] = MSM8X10_WCD_A_RX_EAR_BIAS_PA__POR,
+ [MSM8X10_WCD_A_RX_EAR_BIAS_CMBUFF] =
+ MSM8X10_WCD_A_RX_EAR_BIAS_CMBUFF__POR,
+ [MSM8X10_WCD_A_RX_EAR_EN] = MSM8X10_WCD_A_RX_EAR_EN__POR,
+ [MSM8X10_WCD_A_RX_EAR_GAIN] = MSM8X10_WCD_A_RX_EAR_GAIN__POR,
+ [MSM8X10_WCD_A_RX_EAR_CMBUFF] = MSM8X10_WCD_A_RX_EAR_CMBUFF__POR,
+ [MSM8X10_WCD_A_RX_EAR_ICTL] = MSM8X10_WCD_A_RX_EAR_ICTL__POR,
+ [MSM8X10_WCD_A_RX_EAR_CCOMP] = MSM8X10_WCD_A_RX_EAR_CCOMP__POR,
+ [MSM8X10_WCD_A_RX_EAR_VCM] = MSM8X10_WCD_A_RX_EAR_VCM__POR,
+ [MSM8X10_WCD_A_RX_EAR_CNP] = MSM8X10_WCD_A_RX_EAR_CNP__POR,
+ [MSM8X10_WCD_A_RX_EAR_DAC_CTL_ATEST] =
+ MSM8X10_WCD_A_RX_EAR_DAC_CTL_ATEST__POR,
+ [MSM8X10_WCD_A_RX_EAR_STATUS] = MSM8X10_WCD_A_RX_EAR_STATUS__POR,
+ [MSM8X10_WCD_A_RX_LINE_BIAS_PA] =
+ MSM8X10_WCD_A_RX_LINE_BIAS_PA__POR,
+ [MSM8X10_WCD_A_RX_BUCK_BIAS1] = MSM8X10_WCD_A_RX_BUCK_BIAS1__POR,
+ [MSM8X10_WCD_A_RX_BUCK_BIAS2] = MSM8X10_WCD_A_RX_BUCK_BIAS2__POR,
+ [MSM8X10_WCD_A_RX_LINE_COM] = MSM8X10_WCD_A_RX_LINE_COM__POR,
+ [MSM8X10_WCD_A_RX_LINE_CNP_EN] = MSM8X10_WCD_A_RX_LINE_CNP_EN__POR,
+ [MSM8X10_WCD_A_RX_LINE_CNP_WG_CTL] =
+ MSM8X10_WCD_A_RX_LINE_CNP_WG_CTL__POR,
+ [MSM8X10_WCD_A_RX_LINE_CNP_WG_TIME] =
+ MSM8X10_WCD_A_RX_LINE_CNP_WG_TIME__POR,
+ [MSM8X10_WCD_A_RX_LINE_1_GAIN] = MSM8X10_WCD_A_RX_LINE_1_GAIN__POR,
+ [MSM8X10_WCD_A_RX_LINE_1_TEST] = MSM8X10_WCD_A_RX_LINE_1_TEST__POR,
+ [MSM8X10_WCD_A_RX_LINE_1_DAC_CTL] =
+ MSM8X10_WCD_A_RX_LINE_1_DAC_CTL__POR,
+ [MSM8X10_WCD_A_RX_LINE_1_STATUS] =
+ MSM8X10_WCD_A_RX_LINE_1_STATUS__POR,
+ [MSM8X10_WCD_A_RX_LINE_CNP_DBG] = MSM8X10_WCD_A_RX_LINE_CNP_DBG__POR,
+ [MSM8X10_WCD_A_SPKR_DRV_EN] = MSM8X10_WCD_A_SPKR_DRV_EN__POR,
+ [MSM8X10_WCD_A_SPKR_DRV_GAIN] = MSM8X10_WCD_A_SPKR_DRV_GAIN__POR,
+ [MSM8X10_WCD_A_SPKR_DRV_DAC_CTL] = MSM8X10_WCD_A_SPKR_DRV_DAC_CTL__POR,
+ [MSM8X10_WCD_A_SPKR_DRV_OCP_CTL] = MSM8X10_WCD_A_SPKR_DRV_OCP_CTL__POR,
+ [MSM8X10_WCD_A_SPKR_DRV_CLIP_DET] =
+ MSM8X10_WCD_A_SPKR_DRV_CLIP_DET__POR,
+ [MSM8X10_WCD_A_SPKR_DRV_IEC] = MSM8X10_WCD_A_SPKR_DRV_IEC__POR,
+ [MSM8X10_WCD_A_SPKR_DRV_DBG_DAC] = MSM8X10_WCD_A_SPKR_DRV_DBG_DAC__POR,
+ [MSM8X10_WCD_A_SPKR_DRV_DBG_PA] = MSM8X10_WCD_A_SPKR_DRV_DBG_PA__POR,
+ [MSM8X10_WCD_A_SPKR_DRV_DBG_PWRSTG] =
+ MSM8X10_WCD_A_SPKR_DRV_DBG_PWRSTG__POR,
+ [MSM8X10_WCD_A_SPKR_DRV_BIAS_LDO] =
+ MSM8X10_WCD_A_SPKR_DRV_BIAS_LDO__POR,
+ [MSM8X10_WCD_A_SPKR_DRV_BIAS_INT] =
+ MSM8X10_WCD_A_SPKR_DRV_BIAS_INT__POR,
+ [MSM8X10_WCD_A_SPKR_DRV_BIAS_PA] = MSM8X10_WCD_A_SPKR_DRV_BIAS_PA__POR,
+ [MSM8X10_WCD_A_SPKR_DRV_STATUS_OCP] =
+ MSM8X10_WCD_A_SPKR_DRV_STATUS_OCP__POR,
+ [MSM8X10_WCD_A_SPKR_DRV_STATUS_PA] =
+ MSM8X10_WCD_A_SPKR_DRV_STATUS_PA__POR,
+ [MSM8X10_WCD_A_RC_OSC_FREQ] = MSM8X10_WCD_A_RC_OSC_FREQ__POR,
+ [MSM8X10_WCD_A_RC_OSC_TEST] = MSM8X10_WCD_A_RC_OSC_TEST__POR,
+ [MSM8X10_WCD_A_RC_OSC_STATUS] = MSM8X10_WCD_A_RC_OSC_STATUS__POR,
+ [MSM8X10_WCD_A_RC_OSC_TUNER] = MSM8X10_WCD_A_RC_OSC_TUNER__POR,
+ [MSM8X10_WCD_A_MBHC_HPH] = MSM8X10_WCD_A_MBHC_HPH__POR,
+ [MSM8X10_WCD_A_CDC_CLK_RX_RESET_CTL] =
+ MSM8X10_WCD_A_CDC_CLK_RX_RESET_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CLK_TX_RESET_B1_CTL] =
+ MSM8X10_WCD_A_CDC_CLK_TX_RESET_B1_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CLK_DMIC_B1_CTL] =
+ MSM8X10_WCD_A_CDC_CLK_DMIC_B1_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CLK_RX_I2S_CTL] =
+ MSM8X10_WCD_A_CDC_CLK_RX_I2S_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CLK_TX_I2S_CTL] =
+ MSM8X10_WCD_A_CDC_CLK_TX_I2S_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CLK_OTHR_RESET_B1_CTL] =
+ MSM8X10_WCD_A_CDC_CLK_OTHR_RESET_B1_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CLK_TX_CLK_EN_B1_CTL] =
+ MSM8X10_WCD_A_CDC_CLK_TX_CLK_EN_B1_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CLK_OTHR_CTL] = MSM8X10_WCD_A_CDC_CLK_OTHR_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CLK_RX_B1_CTL] =
+ MSM8X10_WCD_A_CDC_CLK_RX_B1_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CLK_MCLK_CTL] = MSM8X10_WCD_A_CDC_CLK_MCLK_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CLK_PDM_CTL] = MSM8X10_WCD_A_CDC_CLK_PDM_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CLK_SD_CTL] = MSM8X10_WCD_A_CDC_CLK_SD_CTL__POR,
+ [MSM8X10_WCD_A_CDC_RX1_B1_CTL] = MSM8X10_WCD_A_CDC_RX1_B1_CTL__POR,
+ [MSM8X10_WCD_A_CDC_RX2_B1_CTL] = MSM8X10_WCD_A_CDC_RX2_B1_CTL__POR,
+ [MSM8X10_WCD_A_CDC_RX3_B1_CTL] = MSM8X10_WCD_A_CDC_RX3_B1_CTL__POR,
+ [MSM8X10_WCD_A_CDC_RX1_B2_CTL] = MSM8X10_WCD_A_CDC_RX1_B2_CTL__POR,
+ [MSM8X10_WCD_A_CDC_RX2_B2_CTL] = MSM8X10_WCD_A_CDC_RX2_B2_CTL__POR,
+ [MSM8X10_WCD_A_CDC_RX3_B2_CTL] = MSM8X10_WCD_A_CDC_RX3_B2_CTL__POR,
+ [MSM8X10_WCD_A_CDC_RX1_B3_CTL] = MSM8X10_WCD_A_CDC_RX1_B3_CTL__POR,
+ [MSM8X10_WCD_A_CDC_RX2_B3_CTL] = MSM8X10_WCD_A_CDC_RX2_B3_CTL__POR,
+ [MSM8X10_WCD_A_CDC_RX3_B3_CTL] = MSM8X10_WCD_A_CDC_RX3_B3_CTL__POR,
+ [MSM8X10_WCD_A_CDC_RX1_B4_CTL] = MSM8X10_WCD_A_CDC_RX1_B4_CTL__POR,
+ [MSM8X10_WCD_A_CDC_RX2_B4_CTL] = MSM8X10_WCD_A_CDC_RX2_B4_CTL__POR,
+ [MSM8X10_WCD_A_CDC_RX3_B4_CTL] = MSM8X10_WCD_A_CDC_RX3_B4_CTL__POR,
+ [MSM8X10_WCD_A_CDC_RX1_B5_CTL] = MSM8X10_WCD_A_CDC_RX1_B5_CTL__POR,
+ [MSM8X10_WCD_A_CDC_RX2_B5_CTL] = MSM8X10_WCD_A_CDC_RX2_B5_CTL__POR,
+ [MSM8X10_WCD_A_CDC_RX3_B5_CTL] = MSM8X10_WCD_A_CDC_RX3_B5_CTL__POR,
+ [MSM8X10_WCD_A_CDC_RX1_B6_CTL] = MSM8X10_WCD_A_CDC_RX1_B6_CTL__POR,
+ [MSM8X10_WCD_A_CDC_RX2_B6_CTL] = MSM8X10_WCD_A_CDC_RX2_B6_CTL__POR,
+ [MSM8X10_WCD_A_CDC_RX3_B6_CTL] = MSM8X10_WCD_A_CDC_RX3_B6_CTL__POR,
+ [MSM8X10_WCD_A_CDC_RX1_VOL_CTL_B1_CTL] =
+ MSM8X10_WCD_A_CDC_RX1_VOL_CTL_B1_CTL__POR,
+ [MSM8X10_WCD_A_CDC_RX2_VOL_CTL_B1_CTL] =
+ MSM8X10_WCD_A_CDC_RX2_VOL_CTL_B1_CTL__POR,
+ [MSM8X10_WCD_A_CDC_RX3_VOL_CTL_B1_CTL] =
+ MSM8X10_WCD_A_CDC_RX3_VOL_CTL_B1_CTL__POR,
+ [MSM8X10_WCD_A_CDC_RX1_VOL_CTL_B2_CTL] =
+ MSM8X10_WCD_A_CDC_RX1_VOL_CTL_B2_CTL__POR,
+ [MSM8X10_WCD_A_CDC_RX2_VOL_CTL_B2_CTL] =
+ MSM8X10_WCD_A_CDC_RX2_VOL_CTL_B2_CTL__POR,
+ [MSM8X10_WCD_A_CDC_RX3_VOL_CTL_B2_CTL] =
+ MSM8X10_WCD_A_CDC_RX3_VOL_CTL_B2_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B1_CTL] =
+ MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B1_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B2_CTL] =
+ MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B2_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B3_CTL] =
+ MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B3_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B4_CTL] =
+ MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B4_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CLSG_GAIN_THRESH_CTL] =
+ MSM8X10_WCD_A_CDC_CLSG_GAIN_THRESH_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CLSG_TIMER_B1_CFG] =
+ MSM8X10_WCD_A_CDC_CLSG_TIMER_B1_CFG__POR,
+ [MSM8X10_WCD_A_CDC_CLSG_TIMER_B2_CFG] =
+ MSM8X10_WCD_A_CDC_CLSG_TIMER_B2_CFG__POR,
+ [MSM8X10_WCD_A_CDC_CLSG_CTL] = MSM8X10_WCD_A_CDC_CLSG_CTL__POR,
+ [MSM8X10_WCD_A_CDC_TX1_VOL_CTL_TIMER] =
+ MSM8X10_WCD_A_CDC_TX1_VOL_CTL_TIMER__POR,
+ [MSM8X10_WCD_A_CDC_TX2_VOL_CTL_TIMER] =
+ MSM8X10_WCD_A_CDC_TX2_VOL_CTL_TIMER__POR,
+ [MSM8X10_WCD_A_CDC_TX1_VOL_CTL_GAIN] =
+ MSM8X10_WCD_A_CDC_TX1_VOL_CTL_GAIN__POR,
+ [MSM8X10_WCD_A_CDC_TX2_VOL_CTL_GAIN] =
+ MSM8X10_WCD_A_CDC_TX2_VOL_CTL_GAIN__POR,
+ [MSM8X10_WCD_A_CDC_TX1_VOL_CTL_CFG] =
+ MSM8X10_WCD_A_CDC_TX1_VOL_CTL_CFG__POR,
+ [MSM8X10_WCD_A_CDC_TX2_VOL_CTL_CFG] =
+ MSM8X10_WCD_A_CDC_TX2_VOL_CTL_CFG__POR,
+ [MSM8X10_WCD_A_CDC_TX1_MUX_CTL] =
+ MSM8X10_WCD_A_CDC_TX1_MUX_CTL__POR,
+ [MSM8X10_WCD_A_CDC_TX2_MUX_CTL] =
+ MSM8X10_WCD_A_CDC_TX2_MUX_CTL__POR,
+ [MSM8X10_WCD_A_CDC_TX1_CLK_FS_CTL] =
+ MSM8X10_WCD_A_CDC_TX1_CLK_FS_CTL__POR,
+ [MSM8X10_WCD_A_CDC_TX2_CLK_FS_CTL] =
+ MSM8X10_WCD_A_CDC_TX2_CLK_FS_CTL__POR,
+ [MSM8X10_WCD_A_CDC_TX1_DMIC_CTL] =
+ MSM8X10_WCD_A_CDC_TX1_DMIC_CTL__POR,
+ [MSM8X10_WCD_A_CDC_TX2_DMIC_CTL] =
+ MSM8X10_WCD_A_CDC_TX2_DMIC_CTL__POR,
+ [MSM8X10_WCD_A_CDC_IIR1_GAIN_B1_CTL] =
+ MSM8X10_WCD_A_CDC_IIR1_GAIN_B1_CTL__POR,
+ [MSM8X10_WCD_A_CDC_IIR2_GAIN_B1_CTL] =
+ MSM8X10_WCD_A_CDC_IIR2_GAIN_B1_CTL__POR,
+ [MSM8X10_WCD_A_CDC_IIR1_GAIN_B2_CTL] =
+ MSM8X10_WCD_A_CDC_IIR1_GAIN_B2_CTL__POR,
+ [MSM8X10_WCD_A_CDC_IIR2_GAIN_B2_CTL] =
+ MSM8X10_WCD_A_CDC_IIR2_GAIN_B2_CTL__POR,
+ [MSM8X10_WCD_A_CDC_IIR1_GAIN_B3_CTL] =
+ MSM8X10_WCD_A_CDC_IIR1_GAIN_B3_CTL__POR,
+ [MSM8X10_WCD_A_CDC_IIR2_GAIN_B3_CTL] =
+ MSM8X10_WCD_A_CDC_IIR2_GAIN_B3_CTL__POR,
+ [MSM8X10_WCD_A_CDC_IIR1_GAIN_B4_CTL] =
+ MSM8X10_WCD_A_CDC_IIR1_GAIN_B4_CTL__POR,
+ [MSM8X10_WCD_A_CDC_IIR2_GAIN_B4_CTL] =
+ MSM8X10_WCD_A_CDC_IIR2_GAIN_B4_CTL__POR,
+ [MSM8X10_WCD_A_CDC_IIR1_GAIN_B5_CTL] =
+ MSM8X10_WCD_A_CDC_IIR1_GAIN_B5_CTL__POR,
+ [MSM8X10_WCD_A_CDC_IIR2_GAIN_B5_CTL] =
+ MSM8X10_WCD_A_CDC_IIR2_GAIN_B5_CTL__POR,
+ [MSM8X10_WCD_A_CDC_IIR1_GAIN_B6_CTL] =
+ MSM8X10_WCD_A_CDC_IIR1_GAIN_B6_CTL__POR,
+ [MSM8X10_WCD_A_CDC_IIR2_GAIN_B6_CTL] =
+ MSM8X10_WCD_A_CDC_IIR2_GAIN_B6_CTL__POR,
+ [MSM8X10_WCD_A_CDC_IIR1_GAIN_B7_CTL] =
+ MSM8X10_WCD_A_CDC_IIR1_GAIN_B7_CTL__POR,
+ [MSM8X10_WCD_A_CDC_IIR2_GAIN_B7_CTL] =
+ MSM8X10_WCD_A_CDC_IIR2_GAIN_B7_CTL__POR,
+ [MSM8X10_WCD_A_CDC_IIR1_GAIN_B8_CTL] =
+ MSM8X10_WCD_A_CDC_IIR1_GAIN_B8_CTL__POR,
+ [MSM8X10_WCD_A_CDC_IIR2_GAIN_B8_CTL] =
+ MSM8X10_WCD_A_CDC_IIR2_GAIN_B8_CTL__POR,
+ [MSM8X10_WCD_A_CDC_IIR1_CTL] = MSM8X10_WCD_A_CDC_IIR1_CTL__POR,
+ [MSM8X10_WCD_A_CDC_IIR2_CTL] = MSM8X10_WCD_A_CDC_IIR2_CTL__POR,
+ [MSM8X10_WCD_A_CDC_IIR1_GAIN_TIMER_CTL] =
+ MSM8X10_WCD_A_CDC_IIR1_GAIN_TIMER_CTL__POR,
+ [MSM8X10_WCD_A_CDC_IIR2_GAIN_TIMER_CTL] =
+ MSM8X10_WCD_A_CDC_IIR2_GAIN_TIMER_CTL__POR,
+ [MSM8X10_WCD_A_CDC_IIR1_COEF_B1_CTL] =
+ MSM8X10_WCD_A_CDC_IIR1_COEF_B1_CTL__POR,
+ [MSM8X10_WCD_A_CDC_IIR2_COEF_B1_CTL] =
+ MSM8X10_WCD_A_CDC_IIR2_COEF_B1_CTL__POR,
+ [MSM8X10_WCD_A_CDC_IIR1_COEF_B2_CTL] =
+ MSM8X10_WCD_A_CDC_IIR1_COEF_B2_CTL__POR,
+ [MSM8X10_WCD_A_CDC_IIR2_COEF_B2_CTL] =
+ MSM8X10_WCD_A_CDC_IIR2_COEF_B2_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CONN_RX1_B1_CTL] =
+ MSM8X10_WCD_A_CDC_CONN_RX1_B1_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CONN_RX1_B2_CTL] =
+ MSM8X10_WCD_A_CDC_CONN_RX1_B2_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CONN_RX1_B3_CTL] =
+ MSM8X10_WCD_A_CDC_CONN_RX1_B3_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CONN_RX2_B1_CTL] =
+ MSM8X10_WCD_A_CDC_CONN_RX2_B1_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CONN_RX2_B2_CTL] =
+ MSM8X10_WCD_A_CDC_CONN_RX2_B2_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CONN_RX2_B3_CTL] =
+ MSM8X10_WCD_A_CDC_CONN_RX2_B3_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CONN_RX3_B1_CTL] =
+ MSM8X10_WCD_A_CDC_CONN_RX3_B1_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CONN_RX3_B2_CTL] =
+ MSM8X10_WCD_A_CDC_CONN_RX3_B2_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CONN_TX_B1_CTL] =
+ MSM8X10_WCD_A_CDC_CONN_TX_B1_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CONN_EQ1_B1_CTL] =
+ MSM8X10_WCD_A_CDC_CONN_EQ1_B1_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CONN_EQ1_B2_CTL] =
+ MSM8X10_WCD_A_CDC_CONN_EQ1_B2_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CONN_EQ1_B3_CTL] =
+ MSM8X10_WCD_A_CDC_CONN_EQ1_B3_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CONN_EQ1_B4_CTL] =
+ MSM8X10_WCD_A_CDC_CONN_EQ1_B4_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CONN_EQ2_B1_CTL] =
+ MSM8X10_WCD_A_CDC_CONN_EQ2_B1_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CONN_EQ2_B2_CTL] =
+ MSM8X10_WCD_A_CDC_CONN_EQ2_B2_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CONN_EQ2_B3_CTL] =
+ MSM8X10_WCD_A_CDC_CONN_EQ2_B3_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CONN_EQ2_B4_CTL] =
+ MSM8X10_WCD_A_CDC_CONN_EQ2_B4_CTL__POR,
+ [MSM8X10_WCD_A_CDC_CONN_TX_I2S_SD1_CTL] =
+ MSM8X10_WCD_A_CDC_CONN_TX_I2S_SD1_CTL__POR,
+ [MSM8X10_WCD_A_CDC_TOP_GAIN_UPDATE] =
+ MSM8X10_WCD_A_CDC_TOP_GAIN_UPDATE__POR,
+ [MSM8X10_WCD_A_CDC_TOP_CTL] = MSM8X10_WCD_A_CDC_TOP_CTL__POR,
+ [MSM8X10_WCD_A_CDC_DEBUG_DESER1_CTL] =
+ MSM8X10_WCD_A_CDC_DEBUG_DESER1_CTL__POR,
+ [MSM8X10_WCD_A_CDC_DEBUG_DESER2_CTL] =
+ MSM8X10_WCD_A_CDC_DEBUG_DESER2_CTL__POR,
+ [MSM8X10_WCD_A_CDC_DEBUG_B1_CTL] =
+ MSM8X10_WCD_A_CDC_DEBUG_B1_CTL__POR,
+ [MSM8X10_WCD_A_CDC_DEBUG_B2_CTL] =
+ MSM8X10_WCD_A_CDC_DEBUG_B2_CTL__POR,
+ [MSM8X10_WCD_A_CDC_DEBUG_B3_CTL] =
+ MSM8X10_WCD_A_CDC_DEBUG_B3_CTL__POR,
+};
diff --git a/sound/soc/codecs/msm8x10-wcd.c b/sound/soc/codecs/msm8x10-wcd.c
new file mode 100644
index 0000000..08aa176
--- /dev/null
+++ b/sound/soc/codecs/msm8x10-wcd.c
@@ -0,0 +1,2453 @@
+/* Copyright (c) 2013, 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/i2c.h>
+#include <linux/of_gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/mfd/wcd9xxx/core.h>
+#include <linux/mfd/wcd9xxx/pdata.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/tlv.h>
+#include "msm8x10-wcd.h"
+#include "wcd9xxx-resmgr.h"
+#include "msm8x10_wcd_registers.h"
+
+#define MSM8X10_WCD_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000)
+
+#define NUM_DECIMATORS 2
+#define NUM_INTERPOLATORS 3
+#define BITS_PER_REG 8
+#define MSM8X10_WCD_TX_PORT_NUMBER 4
+
+#define MSM8X10_WCD_I2S_MASTER_MODE_MASK 0x08
+#define MSM8X10_DINO_CODEC_BASE_ADDR 0xFE043000
+
+#define MAX_MSM8X10_WCD_DEVICE 2
+#define CODEC_DT_MAX_PROP_SIZE 40
+#define MSM8X10_WCD_I2C_GSBI_SLAVE_ID "2-000d"
+
+enum {
+ MSM8X10_WCD_I2C_TOP_LEVEL = 0,
+ MSM8X10_WCD_I2C_ANALOG,
+ MSM8X10_WCD_I2C_DIGITAL_1,
+ MSM8X10_WCD_I2C_DIGITAL_2,
+};
+
+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(line_gain, 0, 7, 1);
+static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1);
+static struct snd_soc_dai_driver msm8x10_wcd_i2s_dai[];
+static const DECLARE_TLV_DB_SCALE(aux_pga_gain, 0, 2, 0);
+
+/* Codec supports 2 IIR filters */
+enum {
+ IIR1 = 0,
+ IIR2,
+ IIR_MAX,
+};
+/* Codec supports 5 bands */
+enum {
+ BAND1 = 0,
+ BAND2,
+ BAND3,
+ BAND4,
+ BAND5,
+ BAND_MAX,
+};
+
+struct hpf_work {
+ struct msm8x10_wcd_priv *msm8x10_wcd;
+ u32 decimator;
+ u8 tx_hpf_cut_of_freq;
+ struct delayed_work dwork;
+};
+
+static struct hpf_work tx_hpf_work[NUM_DECIMATORS];
+
+struct msm8x10_wcd_priv {
+ struct snd_soc_codec *codec;
+ u32 adc_count;
+ u32 rx_bias_count;
+ s32 dmic_1_2_clk_cnt;
+
+ /* resmgr module */
+ struct wcd9xxx_resmgr resmgr;
+ /* mbhc module */
+ struct wcd9xxx_mbhc mbhc;
+};
+
+
+static unsigned short rx_digital_gain_reg[] = {
+ MSM8X10_WCD_A_CDC_RX1_VOL_CTL_B2_CTL,
+ MSM8X10_WCD_A_CDC_RX2_VOL_CTL_B2_CTL,
+ MSM8X10_WCD_A_CDC_RX3_VOL_CTL_B2_CTL,
+};
+
+static unsigned short tx_digital_gain_reg[] = {
+ MSM8X10_WCD_A_CDC_TX1_VOL_CTL_GAIN,
+ MSM8X10_WCD_A_CDC_TX2_VOL_CTL_GAIN,
+};
+
+struct msm8x10_wcd_i2c {
+ struct i2c_client *client;
+ struct i2c_msg xfer_msg[2];
+ struct mutex xfer_lock;
+ int mod_id;
+};
+
+/* need to re-visit*/
+static char *msm8x10_wcd_supplies[] = {
+ "cdc-vdd-mic-bias", "cdc-vdda-h", "cdc-vdd-1p2", "cdc-vdd-px",
+ "cdc-vdda-cp",
+};
+
+static int msm8x10_wcd_dt_parse_vreg_info(struct device *dev,
+ struct msm8x10_wcd_regulator *vreg, const char *vreg_name);
+static int msm8x10_wcd_dt_parse_micbias_info(struct device *dev,
+ struct msm8x10_wcd_micbias_setting *micbias);
+static struct msm8x10_wcd_pdata *msm8x10_wcd_populate_dt_pdata(
+ struct device *dev);
+
+struct msm8x10_wcd_i2c msm8x10_wcd_modules[MAX_MSM8X10_WCD_DEVICE];
+
+
+static int get_i2c_msm8x10_wcd_device_info(u16 reg,
+ struct msm8x10_wcd_i2c **msm8x10_wcd)
+{
+ int rtn = 0;
+ int value = ((reg & 0x0f00) >> 8) & 0x000f;
+ pr_debug("%s: reg(0x%x) value(%d)\n", __func__, reg, value);
+ switch (value) {
+ case 0:
+ case 1:
+ *msm8x10_wcd = &msm8x10_wcd_modules[value];
+ break;
+ default:
+ rtn = -EINVAL;
+ break;
+ }
+ return rtn;
+}
+
+static int msm8x10_wcd_abh_write_device(u16 reg, u8 *value, u32 bytes)
+{
+ u32 temp = ((u32)(*value)) & 0x000000FF;
+ u32 offset = (((u32)(reg)) ^ 0x00000400) & 0x00000FFF;
+ iowrite32(temp, ioremap(MSM8X10_DINO_CODEC_BASE_ADDR + offset, 4));
+ return 0;
+}
+
+static int msm8x10_wcd_abh_read_device(u16 reg, u32 bytes, u8 *value)
+{
+ u32 offset = (((u32)(reg)) ^ 0x00000400) & 0x00000FFF;
+ *value = (u8)ioread32(ioremap(MSM8X10_DINO_CODEC_BASE_ADDR +
+ offset, 4));
+ return 0;
+}
+
+static int msm8x10_wcd_i2c_write_device(u16 reg, u8 *value, u32 bytes)
+{
+
+ struct i2c_msg *msg;
+ int ret;
+ u8 reg_addr = 0;
+ u8 data[bytes + 1];
+ struct msm8x10_wcd_i2c *msm8x10_wcd;
+
+ ret = get_i2c_msm8x10_wcd_device_info(reg, &msm8x10_wcd);
+ if (!ret) {
+ pr_err("%s: Invalid register address\n", __func__);
+ return ret;
+ }
+
+ if (msm8x10_wcd == NULL || msm8x10_wcd->client == NULL) {
+ pr_err("%s: Failed to get device info\n", __func__);
+ return -ENODEV;
+ }
+ reg_addr = (u8)reg;
+ msg = &msm8x10_wcd->xfer_msg[0];
+ msg->addr = msm8x10_wcd->client->addr;
+ msg->len = bytes + 1;
+ msg->flags = 0;
+ data[0] = reg;
+ data[1] = *value;
+ msg->buf = data;
+ ret = i2c_transfer(msm8x10_wcd->client->adapter,
+ msm8x10_wcd->xfer_msg, 1);
+ /* Try again if the write fails */
+ if (ret != 1) {
+ ret = i2c_transfer(msm8x10_wcd->client->adapter,
+ msm8x10_wcd->xfer_msg, 1);
+ if (ret != 1) {
+ pr_err("failed to write the device\n");
+ return ret;
+ }
+ }
+ pr_debug("write sucess register = %x val = %x\n", reg, data[1]);
+ return 0;
+}
+
+
+int msm8x10_wcd_i2c_read_device(u32 reg, u32 bytes, u8 *dest)
+{
+ struct i2c_msg *msg;
+ int ret = 0;
+ u8 reg_addr = 0;
+ struct msm8x10_wcd_i2c *msm8x10_wcd;
+ u8 i = 0;
+
+ ret = get_i2c_msm8x10_wcd_device_info(reg, &msm8x10_wcd);
+ if (!ret) {
+ pr_err("%s: Invalid register address\n", __func__);
+ return ret;
+ }
+
+ if (msm8x10_wcd == NULL || msm8x10_wcd->client == NULL) {
+ pr_err("%s: Failed to get device info\n", __func__);
+ return -ENODEV;
+ }
+
+ for (i = 0; i < bytes; i++) {
+ reg_addr = (u8)reg++;
+ msg = &msm8x10_wcd->xfer_msg[0];
+ msg->addr = msm8x10_wcd->client->addr;
+ msg->len = 1;
+ msg->flags = 0;
+ msg->buf = ®_addr;
+
+ msg = &msm8x10_wcd->xfer_msg[1];
+ msg->addr = msm8x10_wcd->client->addr;
+ msg->len = 1;
+ msg->flags = I2C_M_RD;
+ msg->buf = dest++;
+ ret = i2c_transfer(msm8x10_wcd->client->adapter,
+ msm8x10_wcd->xfer_msg, 2);
+
+ /* Try again if read fails first time */
+ if (ret != 2) {
+ ret = i2c_transfer(msm8x10_wcd->client->adapter,
+ msm8x10_wcd->xfer_msg, 2);
+ if (ret != 2) {
+ pr_err("failed to read msm8x10_wcd register\n");
+ return ret;
+ }
+ }
+ }
+ return 0;
+}
+
+static int msm8x10_wcd_reg_read(struct msm8x10_wcd *msm8x10_wcd, u16 reg)
+{
+ u8 val;
+ int ret = -EINVAL;
+
+ /* check if use I2C interface for Helicon or AHB for Dino*/
+ mutex_lock(&msm8x10_wcd->io_lock);
+ if (MSM8X10_WCD_IS_HELICON_REG(reg))
+ ret = msm8x10_wcd_i2c_read_device(reg, 1, &val);
+ else if (MSM8X10_WCD_IS_DINO_REG(reg))
+ ret = msm8x10_wcd_abh_read_device(reg, 1, &val);
+ mutex_unlock(&msm8x10_wcd->io_lock);
+
+ if (ret < 0)
+ return ret;
+ else
+ return val;
+}
+
+
+static int msm8x10_wcd_reg_write(struct msm8x10_wcd *msm8x10_wcd, u16 reg,
+ u8 val)
+{
+ int ret = -EINVAL;
+
+ /* check if use I2C interface for Helicon or AHB for Dino*/
+ mutex_lock(&msm8x10_wcd->io_lock);
+ if (MSM8X10_WCD_IS_HELICON_REG(reg))
+ ret = msm8x10_wcd_i2c_write_device(reg, &val, 1);
+ else if (MSM8X10_WCD_IS_DINO_REG(reg))
+ ret = msm8x10_wcd_abh_write_device(reg, &val, 1);
+ mutex_unlock(&msm8x10_wcd->io_lock);
+
+ return ret;
+}
+
+static bool msm8x10_wcd_is_digital_gain_register(unsigned int reg)
+{
+ bool rtn = false;
+ switch (reg) {
+ case MSM8X10_WCD_A_CDC_RX1_VOL_CTL_B2_CTL:
+ case MSM8X10_WCD_A_CDC_RX2_VOL_CTL_B2_CTL:
+ case MSM8X10_WCD_A_CDC_RX3_VOL_CTL_B2_CTL:
+ case MSM8X10_WCD_A_CDC_TX1_VOL_CTL_GAIN:
+ case MSM8X10_WCD_A_CDC_TX2_VOL_CTL_GAIN:
+ rtn = true;
+ break;
+ default:
+ break;
+ }
+ return rtn;
+}
+
+static int msm8x10_wcd_volatile(struct snd_soc_codec *ssc, unsigned int reg)
+{
+ /* Registers lower than 0x100 are top level registers which can be
+ * written by the Taiko core driver.
+ */
+
+ if ((reg >= MSM8X10_WCD_A_CDC_MBHC_EN_CTL) || (reg < 0x100))
+ return 1;
+
+ /* IIR Coeff registers are not cacheable */
+ if ((reg >= MSM8X10_WCD_A_CDC_IIR1_COEF_B1_CTL) &&
+ (reg <= MSM8X10_WCD_A_CDC_IIR2_COEF_B2_CTL))
+ return 1;
+
+ /* Digital gain register is not cacheable so we have to write
+ * the setting even it is the same
+ */
+ if (msm8x10_wcd_is_digital_gain_register(reg))
+ return 1;
+
+ /* HPH status registers */
+ if (reg == MSM8X10_WCD_A_RX_HPH_L_STATUS ||
+ reg == MSM8X10_WCD_A_RX_HPH_R_STATUS)
+ return 1;
+
+ if (reg == MSM8X10_WCD_A_MBHC_INSERT_DET_STATUS)
+ return 1;
+
+ return 0;
+}
+
+static int msm8x10_wcd_readable(struct snd_soc_codec *ssc, unsigned int reg)
+{
+ return msm8x10_wcd_reg_readable[reg];
+}
+
+static int msm8x10_wcd_write(struct snd_soc_codec *codec, unsigned int reg,
+ unsigned int value)
+{
+ int ret;
+
+ if (reg == SND_SOC_NOPM)
+ return 0;
+
+ BUG_ON(reg > MSM8X10_WCD_MAX_REGISTER);
+
+ if (!msm8x10_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 msm8x10_wcd_reg_write(codec->control_data, reg, value);
+}
+static unsigned int msm8x10_wcd_read(struct snd_soc_codec *codec,
+ unsigned int reg)
+{
+ unsigned int val;
+ int ret;
+
+ if (reg == SND_SOC_NOPM)
+ return 0;
+
+ BUG_ON(reg > MSM8X10_WCD_MAX_REGISTER);
+
+ if (!msm8x10_wcd_volatile(codec, reg) &&
+ msm8x10_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 = msm8x10_wcd_reg_read(codec->control_data, reg);
+ return val;
+}
+
+
+static int msm8x10_wcd_dt_parse_vreg_info(struct device *dev,
+ struct msm8x10_wcd_regulator *vreg, const char *vreg_name)
+{
+ 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",
+ prop_name, dev->of_node->full_name);
+ return -ENODEV;
+ }
+ vreg->name = vreg_name;
+
+ 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 -ENODEV;
+ } 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 -ENODEV;
+ }
+ vreg->optimum_uA = prop_val;
+
+ dev_info(dev, "%s: vol=[%d %d]uV, curr=[%d]uA\n", vreg->name,
+ vreg->min_uV, vreg->max_uV, vreg->optimum_uA);
+ return 0;
+}
+
+static int msm8x10_wcd_dt_parse_micbias_info(struct device *dev,
+ struct msm8x10_wcd_micbias_setting *micbias)
+{
+ int ret = 0;
+ char prop_name[CODEC_DT_MAX_PROP_SIZE];
+ u32 prop_val;
+
+ snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
+ "qcom,cdc-micbias-ldoh-v");
+ 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 -ENODEV;
+ }
+ micbias->ldoh_v = (u8)prop_val;
+
+ snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
+ "qcom,cdc-micbias-cfilt1-mv");
+ ret = of_property_read_u32(dev->of_node, prop_name,
+ &micbias->cfilt1_mv);
+ if (ret) {
+ dev_err(dev, "Looking up %s property in node %s failed",
+ prop_name, dev->of_node->full_name);
+ return -ENODEV;
+ }
+
+ snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
+ "qcom,cdc-micbias1-cfilt-sel");
+ 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 -ENODEV;
+ }
+ micbias->bias1_cfilt_sel = (u8)prop_val;
+
+ /* micbias external cap */
+ micbias->bias1_cap_mode =
+ (of_property_read_bool(dev->of_node, "qcom,cdc-micbias1-ext-cap") ?
+ MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP);
+
+ dev_dbg(dev, "ldoh_v %u cfilt1_mv %u\n",
+ (u32)micbias->ldoh_v, (u32)micbias->cfilt1_mv);
+ dev_dbg(dev, "bias1_cfilt_sel %u\n", (u32)micbias->bias1_cfilt_sel);
+ dev_dbg(dev, "bias1_ext_cap %d\n", micbias->bias1_cap_mode);
+
+ return 0;
+}
+
+static struct msm8x10_wcd_pdata *msm8x10_wcd_populate_dt_pdata(
+ struct device *dev)
+{
+ struct msm8x10_wcd_pdata *pdata;
+ int ret, i;
+ char **codec_supplies;
+ u32 num_of_supplies = 0;
+
+ pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata) {
+ dev_err(dev, "could not allocate memory for platform data\n");
+ return NULL;
+ }
+ if ((!strcmp(dev_name(dev), MSM8X10_WCD_I2C_GSBI_SLAVE_ID))) {
+ codec_supplies = msm8x10_wcd_supplies;
+ num_of_supplies = ARRAY_SIZE(msm8x10_wcd_supplies);
+ } else {
+ dev_err(dev, "%s unsupported device %s\n",
+ __func__, dev_name(dev));
+ goto err;
+ }
+
+ if (num_of_supplies > ARRAY_SIZE(pdata->regulator)) {
+ dev_err(dev, "%s: Num of supplies %u > max supported %u\n",
+ __func__, num_of_supplies, ARRAY_SIZE(pdata->regulator));
+
+ goto err;
+ }
+
+ for (i = 0; i < num_of_supplies; i++) {
+ ret = msm8x10_wcd_dt_parse_vreg_info(dev, &pdata->regulator[i],
+ codec_supplies[i]);
+ if (ret)
+ goto err;
+ }
+
+ ret = msm8x10_wcd_dt_parse_micbias_info(dev, &pdata->micbias);
+ if (ret)
+ goto err;
+
+ pdata->reset_gpio = of_get_named_gpio(dev->of_node,
+ "qcom,cdc-reset-gpio", 0);
+ if (pdata->reset_gpio < 0) {
+ dev_err(dev, "Looking up %s property in node %s failed %d\n",
+ "qcom, cdc-reset-gpio", dev->of_node->full_name,
+ pdata->reset_gpio);
+ goto err;
+ }
+ dev_dbg(dev, "%s: reset gpio %d", __func__, pdata->reset_gpio);
+ return pdata;
+err:
+ devm_kfree(dev, pdata);
+ return NULL;
+}
+
+static int msm8x10_wcd_codec_enable_charge_pump(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ pr_debug("%s %d\n", __func__, event);
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ /* Enable charge pump clock*/
+ snd_soc_update_bits(codec, MSM8X10_WCD_A_CDC_CLK_OTHR_CTL,
+ 0x01, 0x01);
+ snd_soc_update_bits(codec, MSM8X10_WCD_A_CDC_CLSG_CTL,
+ 0x08, 0x08);
+ usleep_range(200, 300);
+ snd_soc_update_bits(codec, MSM8X10_WCD_A_CP_STATIC,
+ 0x10, 0x00);
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ snd_soc_update_bits(codec,
+ MSM8X10_WCD_A_CDC_CLK_OTHR_RESET_B1_CTL,
+ 0x01, 0x01);
+ usleep_range(20, 100);
+ snd_soc_update_bits(codec,
+ MSM8X10_WCD_A_CP_STATIC, 0x08, 0x08);
+ snd_soc_update_bits(codec,
+ MSM8X10_WCD_A_CP_STATIC, 0x10, 0x10);
+ snd_soc_update_bits(codec,
+ MSM8X10_WCD_A_CDC_CLSG_CTL, 0x08, 0x00);
+ snd_soc_update_bits(codec,
+ MSM8X10_WCD_A_CDC_CLK_OTHR_CTL, 0x01,
+ 0x00);
+ snd_soc_update_bits(codec,
+ MSM8X10_WCD_A_CP_STATIC, 0x08, 0x00);
+ break;
+ }
+ return 0;
+}
+
+static int msm8x10_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, MSM8X10_WCD_A_RX_EAR_GAIN);
+
+ ear_pa_gain = ear_pa_gain >> 5;
+
+ if (ear_pa_gain == 0x00) {
+ ucontrol->value.integer.value[0] = 0;
+ } else if (ear_pa_gain == 0x04) {
+ ucontrol->value.integer.value[0] = 1;
+ } else {
+ pr_err("%s: ERROR: Unsupported Ear Gain = 0x%x\n",
+ __func__, ear_pa_gain);
+ return -EINVAL;
+ }
+
+ pr_debug("%s: ear_pa_gain = 0x%x\n", __func__, ear_pa_gain);
+
+ return 0;
+}
+
+static int msm8x10_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);
+
+ pr_debug("%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 = 0x80;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ snd_soc_update_bits(codec, MSM8X10_WCD_A_RX_EAR_GAIN,
+ 0xE0, ear_pa_gain);
+ return 0;
+}
+
+static int msm8x10_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,
+ (MSM8X10_WCD_A_CDC_IIR1_CTL + 64 * iir_idx)) &
+ (1 << band_idx);
+
+ pr_debug("%s: IIR #%d band #%d enable %d\n", __func__,
+ iir_idx, band_idx,
+ (uint32_t)ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm8x10_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, (MSM8X10_WCD_A_CDC_IIR1_CTL + 64 * iir_idx),
+ (1 << band_idx), (value << band_idx));
+
+ pr_debug("%s: IIR #%d band #%d enable %d\n", __func__,
+ iir_idx, band_idx, value);
+ return 0;
+}
+static uint32_t get_iir_band_coeff(struct snd_soc_codec *codec,
+ int iir_idx, int band_idx,
+ int coeff_idx)
+{
+ /* Address does not automatically update if reading */
+ snd_soc_write(codec,
+ (MSM8X10_WCD_A_CDC_IIR1_COEF_B1_CTL + 64 * iir_idx),
+ (band_idx * BAND_MAX + coeff_idx) & 0x1F);
+
+ /* Mask bits top 2 bits since they are reserved */
+ return ((snd_soc_read(codec,
+ (MSM8X10_WCD_A_CDC_IIR1_COEF_B2_CTL + 64 * iir_idx)) << 24)) &
+ 0x3FFFFFFF;
+}
+
+static int msm8x10_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);
+
+ pr_debug("%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,
+ int coeff_idx, uint32_t value)
+{
+ /* Mask top 3 bits, 6-8 are reserved */
+ /* Update address manually each time */
+ snd_soc_write(codec,
+ (MSM8X10_WCD_A_CDC_IIR1_COEF_B1_CTL + 64 * iir_idx),
+ (band_idx * BAND_MAX + coeff_idx) & 0x1F);
+
+ /* Mask top 2 bits, 7-8 are reserved */
+ snd_soc_write(codec,
+ (MSM8X10_WCD_A_CDC_IIR1_COEF_B2_CTL + 64 * iir_idx),
+ (value >> 24) & 0x3F);
+
+}
+
+static int msm8x10_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;
+
+ set_iir_band_coeff(codec, iir_idx, band_idx, 0,
+ ucontrol->value.integer.value[0]);
+ set_iir_band_coeff(codec, iir_idx, band_idx, 1,
+ ucontrol->value.integer.value[1]);
+ set_iir_band_coeff(codec, iir_idx, band_idx, 2,
+ ucontrol->value.integer.value[2]);
+ set_iir_band_coeff(codec, iir_idx, band_idx, 3,
+ ucontrol->value.integer.value[3]);
+ set_iir_band_coeff(codec, iir_idx, band_idx, 4,
+ ucontrol->value.integer.value[4]);
+
+ pr_debug("%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 msm8x10_wcd_ear_pa_gain_text[] = {
+ "POS_6_DB", "POS_2_DB"};
+static const struct soc_enum msm8x10_wcd_ear_pa_gain_enum[] = {
+ SOC_ENUM_SINGLE_EXT(2, msm8x10_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(MSM8X10_WCD_A_CDC_TX1_MUX_CTL, 4, 3, cf_text);
+
+static const struct soc_enum cf_dec2_enum =
+ SOC_ENUM_SINGLE(MSM8X10_WCD_A_CDC_TX2_MUX_CTL, 4, 3, cf_text);
+
+static const struct soc_enum cf_rxmix1_enum =
+ SOC_ENUM_SINGLE(MSM8X10_WCD_A_CDC_RX1_B4_CTL, 0, 3, cf_text);
+
+static const struct soc_enum cf_rxmix2_enum =
+ SOC_ENUM_SINGLE(MSM8X10_WCD_A_CDC_RX2_B4_CTL, 0, 3, cf_text);
+
+static const struct soc_enum cf_rxmix3_enum =
+ SOC_ENUM_SINGLE(MSM8X10_WCD_A_CDC_RX3_B4_CTL, 0, 3, cf_text);
+
+static const struct snd_kcontrol_new msm8x10_wcd_snd_controls[] = {
+
+ SOC_ENUM_EXT("EAR PA Gain", msm8x10_wcd_ear_pa_gain_enum[0],
+ msm8x10_wcd_pa_gain_get, msm8x10_wcd_pa_gain_put),
+
+ SOC_SINGLE_TLV("LINEOUT1 Volume", MSM8X10_WCD_A_RX_LINE_1_GAIN,
+ 0, 12, 1, line_gain),
+
+ SOC_SINGLE_TLV("HPHL Volume", MSM8X10_WCD_A_RX_HPH_L_GAIN,
+ 0, 12, 1, line_gain),
+ SOC_SINGLE_TLV("HPHR Volume", MSM8X10_WCD_A_RX_HPH_R_GAIN,
+ 0, 12, 1, line_gain),
+
+ SOC_SINGLE_SX_TLV("RX1 Digital Volume",
+ MSM8X10_WCD_A_CDC_RX1_VOL_CTL_B2_CTL,
+ 0, -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("RX2 Digital Volume",
+ MSM8X10_WCD_A_CDC_RX2_VOL_CTL_B2_CTL,
+ 0, -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("RX3 Digital Volume",
+ MSM8X10_WCD_A_CDC_RX3_VOL_CTL_B2_CTL,
+ 0, -84, 40, digital_gain),
+
+ SOC_SINGLE_SX_TLV("DEC1 Volume",
+ MSM8X10_WCD_A_CDC_TX1_VOL_CTL_GAIN,
+ 0, -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("DEC2 Volume",
+ MSM8X10_WCD_A_CDC_TX2_VOL_CTL_GAIN,
+ 0, -84, 40, digital_gain),
+
+ SOC_SINGLE_SX_TLV("IIR1 INP1 Volume",
+ MSM8X10_WCD_A_CDC_IIR1_GAIN_B1_CTL,
+ 0, -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("IIR1 INP2 Volume",
+ MSM8X10_WCD_A_CDC_IIR1_GAIN_B2_CTL,
+ 0, -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("IIR1 INP3 Volume",
+ MSM8X10_WCD_A_CDC_IIR1_GAIN_B3_CTL,
+ 0, -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("IIR1 INP4 Volume",
+ MSM8X10_WCD_A_CDC_IIR1_GAIN_B4_CTL,
+ 0, -84, 40, digital_gain),
+
+ SOC_SINGLE("MICBIAS1 CAPLESS Switch",
+ MSM8X10_WCD_A_MICB_1_CTL, 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", MSM8X10_WCD_A_CDC_TX1_MUX_CTL, 3, 1, 0),
+ SOC_SINGLE("TX2 HPF Switch", MSM8X10_WCD_A_CDC_TX2_MUX_CTL, 3, 1, 0),
+
+ SOC_SINGLE("RX1 HPF Switch", MSM8X10_WCD_A_CDC_RX1_B5_CTL, 2, 1, 0),
+ SOC_SINGLE("RX2 HPF Switch", MSM8X10_WCD_A_CDC_RX2_B5_CTL, 2, 1, 0),
+ SOC_SINGLE("RX3 HPF Switch", MSM8X10_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,
+ msm8x10_wcd_get_iir_enable_audio_mixer,
+ msm8x10_wcd_put_iir_enable_audio_mixer),
+ SOC_SINGLE_EXT("IIR1 Enable Band2", IIR1, BAND2, 1, 0,
+ msm8x10_wcd_get_iir_enable_audio_mixer,
+ msm8x10_wcd_put_iir_enable_audio_mixer),
+ SOC_SINGLE_EXT("IIR1 Enable Band3", IIR1, BAND3, 1, 0,
+ msm8x10_wcd_get_iir_enable_audio_mixer,
+ msm8x10_wcd_put_iir_enable_audio_mixer),
+ SOC_SINGLE_EXT("IIR1 Enable Band4", IIR1, BAND4, 1, 0,
+ msm8x10_wcd_get_iir_enable_audio_mixer,
+ msm8x10_wcd_put_iir_enable_audio_mixer),
+ SOC_SINGLE_EXT("IIR1 Enable Band5", IIR1, BAND5, 1, 0,
+ msm8x10_wcd_get_iir_enable_audio_mixer,
+ msm8x10_wcd_put_iir_enable_audio_mixer),
+ SOC_SINGLE_EXT("IIR2 Enable Band1", IIR2, BAND1, 1, 0,
+ msm8x10_wcd_get_iir_enable_audio_mixer,
+ msm8x10_wcd_put_iir_enable_audio_mixer),
+ SOC_SINGLE_EXT("IIR2 Enable Band2", IIR2, BAND2, 1, 0,
+ msm8x10_wcd_get_iir_enable_audio_mixer,
+ msm8x10_wcd_put_iir_enable_audio_mixer),
+ SOC_SINGLE_EXT("IIR2 Enable Band3", IIR2, BAND3, 1, 0,
+ msm8x10_wcd_get_iir_enable_audio_mixer,
+ msm8x10_wcd_put_iir_enable_audio_mixer),
+ SOC_SINGLE_EXT("IIR2 Enable Band4", IIR2, BAND4, 1, 0,
+ msm8x10_wcd_get_iir_enable_audio_mixer,
+ msm8x10_wcd_put_iir_enable_audio_mixer),
+ SOC_SINGLE_EXT("IIR2 Enable Band5", IIR2, BAND5, 1, 0,
+ msm8x10_wcd_get_iir_enable_audio_mixer,
+ msm8x10_wcd_put_iir_enable_audio_mixer),
+
+ SOC_SINGLE_MULTI_EXT("IIR1 Band1", IIR1, BAND1, 255, 0, 5,
+ msm8x10_wcd_get_iir_band_audio_mixer,
+ msm8x10_wcd_put_iir_band_audio_mixer),
+ SOC_SINGLE_MULTI_EXT("IIR1 Band2", IIR1, BAND2, 255, 0, 5,
+ msm8x10_wcd_get_iir_band_audio_mixer,
+ msm8x10_wcd_put_iir_band_audio_mixer),
+ SOC_SINGLE_MULTI_EXT("IIR1 Band3", IIR1, BAND3, 255, 0, 5,
+ msm8x10_wcd_get_iir_band_audio_mixer,
+ msm8x10_wcd_put_iir_band_audio_mixer),
+ SOC_SINGLE_MULTI_EXT("IIR1 Band4", IIR1, BAND4, 255, 0, 5,
+ msm8x10_wcd_get_iir_band_audio_mixer,
+ msm8x10_wcd_put_iir_band_audio_mixer),
+ SOC_SINGLE_MULTI_EXT("IIR1 Band5", IIR1, BAND5, 255, 0, 5,
+ msm8x10_wcd_get_iir_band_audio_mixer,
+ msm8x10_wcd_put_iir_band_audio_mixer),
+ SOC_SINGLE_MULTI_EXT("IIR2 Band1", IIR2, BAND1, 255, 0, 5,
+ msm8x10_wcd_get_iir_band_audio_mixer,
+ msm8x10_wcd_put_iir_band_audio_mixer),
+ SOC_SINGLE_MULTI_EXT("IIR2 Band2", IIR2, BAND2, 255, 0, 5,
+ msm8x10_wcd_get_iir_band_audio_mixer,
+ msm8x10_wcd_put_iir_band_audio_mixer),
+ SOC_SINGLE_MULTI_EXT("IIR2 Band3", IIR2, BAND3, 255, 0, 5,
+ msm8x10_wcd_get_iir_band_audio_mixer,
+ msm8x10_wcd_put_iir_band_audio_mixer),
+ SOC_SINGLE_MULTI_EXT("IIR2 Band4", IIR2, BAND4, 255, 0, 5,
+ msm8x10_wcd_get_iir_band_audio_mixer,
+ msm8x10_wcd_put_iir_band_audio_mixer),
+ SOC_SINGLE_MULTI_EXT("IIR2 Band5", IIR2, BAND5, 255, 0, 5,
+ msm8x10_wcd_get_iir_band_audio_mixer,
+ msm8x10_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", "DMIC1", "DMIC2"
+};
+
+
+static const char * const anc_mux_text[] = {
+ "ZERO", "ADC1", "ADC2", "ADC3", "ADC4", "ADC5", "ADC6", "ADC_MB",
+ "RSVD_1", "DMIC1", "DMIC2", "DMIC3", "DMIC4", "DMIC5", "DMIC6"
+};
+
+static const char * const anc1_fb_mux_text[] = {
+ "ZERO", "EAR_HPH_L", "EAR_LINE_1",
+};
+
+static const char * const iir1_inp1_text[] = {
+ "ZERO", "DEC1", "DEC2", "RX1", "RX2", "RX3"
+};
+
+static const struct soc_enum rx_mix1_inp1_chain_enum =
+ SOC_ENUM_SINGLE(MSM8X10_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(MSM8X10_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(MSM8X10_WCD_A_CDC_CONN_RX1_B2_CTL, 0, 6, rx_mix1_text);
+
+static const struct soc_enum rx2_mix1_inp1_chain_enum =
+ SOC_ENUM_SINGLE(MSM8X10_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(MSM8X10_WCD_A_CDC_CONN_RX2_B1_CTL, 3, 6, rx_mix1_text);
+
+static const struct soc_enum rx3_mix1_inp1_chain_enum =
+ SOC_ENUM_SINGLE(MSM8X10_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(MSM8X10_WCD_A_CDC_CONN_RX3_B1_CTL, 3, 6, rx_mix1_text);
+
+static const struct soc_enum rx1_mix2_inp1_chain_enum =
+ SOC_ENUM_SINGLE(MSM8X10_WCD_A_CDC_CONN_RX1_B3_CTL, 0, 3, rx_mix2_text);
+
+static const struct soc_enum rx2_mix2_inp1_chain_enum =
+ SOC_ENUM_SINGLE(MSM8X10_WCD_A_CDC_CONN_RX2_B3_CTL, 0, 3, rx_mix2_text);
+
+static const struct soc_enum dec1_mux_enum =
+ SOC_ENUM_SINGLE(MSM8X10_WCD_A_CDC_CONN_TX_B1_CTL, 0, 5, dec_mux_text);
+
+static const struct soc_enum dec2_mux_enum =
+ SOC_ENUM_SINGLE(MSM8X10_WCD_A_CDC_CONN_TX_B1_CTL, 3, 5, dec_mux_text);
+
+static const struct soc_enum iir1_inp1_mux_enum =
+ SOC_ENUM_SINGLE(MSM8X10_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 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 rx1_mix2_inp1_mux =
+ SOC_DAPM_ENUM("RX1 MIX2 INP1 Mux", rx1_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 int msm8x10_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)
+ return -EINVAL;
+
+ dec_mux = ucontrol->value.enumerated.item[0];
+
+ 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) {
+ pr_err("%s: Invalid decimator = %s\n", __func__, w->name);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = kstrtouint(strpbrk(dec_name, "12"), 10, &decimator);
+ if (ret < 0) {
+ pr_err("%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 == 1)
+ adc_dmic_sel = 0x1;
+ else
+ adc_dmic_sel = 0x0;
+ break;
+ default:
+ pr_err("%s: Invalid Decimator = %u\n", __func__, decimator);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ tx_mux_ctl_reg = MSM8X10_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 MSM8X10_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 = msm8x10_wcd_put_dec_enum, \
+ .private_value = (unsigned long)&xenum }
+
+static const struct snd_kcontrol_new dec1_mux =
+ MSM8X10_WCD_DEC_ENUM("DEC1 MUX Mux", dec1_mux_enum);
+
+static const struct snd_kcontrol_new dec2_mux =
+ MSM8X10_WCD_DEC_ENUM("DEC2 MUX Mux", dec2_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 dac1_switch[] = {
+ SOC_DAPM_SINGLE("Switch", MSM8X10_WCD_A_RX_EAR_EN, 5, 1, 0)
+};
+static const struct snd_kcontrol_new hphl_switch[] = {
+ SOC_DAPM_SINGLE("Switch", MSM8X10_WCD_A_RX_HPH_L_DAC_CTL, 6, 1, 0)
+};
+
+/* virtual port entries */
+static int slim_tx_mixer_get(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 *widget = wlist->widgets[0];
+
+ ucontrol->value.integer.value[0] = widget->value;
+ return 0;
+}
+
+static int slim_tx_mixer_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return 0;
+}
+
+static int slim_rx_mux_get(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 *widget = wlist->widgets[0];
+
+ ucontrol->value.enumerated.item[0] = widget->value;
+ return 0;
+}
+
+static int slim_rx_mux_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return 0;
+}
+
+
+static const char *const slim_rx_mux_text[] = {
+ "ZERO", "AIF1_PB"
+};
+
+static const struct soc_enum slim_rx_mux_enum =
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(slim_rx_mux_text), slim_rx_mux_text);
+
+static const struct snd_kcontrol_new slim_rx_mux[MSM8X10_WCD_RX_MAX] = {
+ SOC_DAPM_ENUM_EXT("I2S RX1 Mux", slim_rx_mux_enum,
+ slim_rx_mux_get, slim_rx_mux_put),
+ SOC_DAPM_ENUM_EXT("I2S RX2 Mux", slim_rx_mux_enum,
+ slim_rx_mux_get, slim_rx_mux_put),
+ SOC_DAPM_ENUM_EXT("I2S RX3 Mux", slim_rx_mux_enum,
+ slim_rx_mux_get, slim_rx_mux_put),
+};
+
+static const struct snd_kcontrol_new aif_cap_mixer[] = {
+ SOC_SINGLE_EXT("I2S TX1", SND_SOC_NOPM, MSM8X10_WCD_TX1, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("I2S TX2", SND_SOC_NOPM, MSM8X10_WCD_TX2, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("I2S TX3", SND_SOC_NOPM, MSM8X10_WCD_TX3, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("I2S TX4", SND_SOC_NOPM, MSM8X10_WCD_TX4, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+};
+
+
+static void msm8x10_wcd_codec_enable_adc_block(struct snd_soc_codec *codec,
+ int enable)
+{
+ struct msm8x10_wcd_priv *taiko = snd_soc_codec_get_drvdata(codec);
+
+ pr_debug("%s %d\n", __func__, enable);
+
+ if (enable) {
+ taiko->adc_count++;
+ snd_soc_update_bits(codec,
+ MSM8X10_WCD_A_CDC_ANA_CLK_CTL,
+ 0x20, 0x20);
+ } else {
+ taiko->adc_count--;
+ if (!taiko->adc_count)
+ snd_soc_update_bits(codec,
+ MSM8X10_WCD_A_CDC_ANA_CLK_CTL,
+ 0x20, 0x0);
+ }
+}
+
+static int msm8x10_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;
+
+ pr_debug("%s %d\n", __func__, event);
+ adc_reg = MSM8X10_WCD_A_TX_1_2_TEST_CTL;
+
+ if (w->reg == MSM8X10_WCD_A_TX_1_EN)
+ init_bit_shift = 7;
+ else if (adc_reg == MSM8X10_WCD_A_TX_2_EN)
+ init_bit_shift = 6;
+ else {
+ pr_err("%s: Error, invalid adc register\n", __func__);
+ return -EINVAL;
+ }
+
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ msm8x10_wcd_codec_enable_adc_block(codec, 1);
+ snd_soc_update_bits(codec, adc_reg, 1 << init_bit_shift,
+ 1 << init_bit_shift);
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+
+ snd_soc_update_bits(codec, adc_reg, 1 << init_bit_shift, 0x00);
+
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ msm8x10_wcd_codec_enable_adc_block(codec, 0);
+ break;
+ }
+ return 0;
+}
+
+static int msm8x10_wcd_codec_enable_lineout(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ u16 lineout_gain_reg;
+
+ pr_debug("%s %d %s\n", __func__, event, w->name);
+
+ switch (w->shift) {
+ case 0:
+ lineout_gain_reg = MSM8X10_WCD_A_RX_LINE_1_GAIN;
+ break;
+ default:
+ pr_err("%s: Error, incorrect lineout register value\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ snd_soc_update_bits(codec, lineout_gain_reg, 0x40, 0x40);
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ pr_debug("%s: sleeping 16 ms after %s PA turn on\n",
+ __func__, w->name);
+ usleep_range(16000, 16100);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ snd_soc_update_bits(codec, lineout_gain_reg, 0x40, 0x00);
+ break;
+ }
+ return 0;
+}
+
+static int msm8x10_wcd_codec_enable_spk_pa(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ pr_debug("%s %d %s\n", __func__, event, w->name);
+ return 0;
+}
+
+static int msm8x10_wcd_codec_enable_dmic(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ struct msm8x10_wcd_priv *msm8x10_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) {
+ pr_err("%s: Invalid DMIC line on the codec\n", __func__);
+ return -EINVAL;
+ }
+
+ switch (dmic) {
+ case 1:
+ case 2:
+ dmic_clk_en = 0x01;
+ dmic_clk_cnt = &(msm8x10_wcd->dmic_1_2_clk_cnt);
+ dmic_clk_reg = MSM8X10_WCD_A_CDC_CLK_DMIC_B1_CTL;
+ pr_debug("%s() event %d DMIC%d dmic_1_2_clk_cnt %d\n",
+ __func__, event, dmic, *dmic_clk_cnt);
+ break;
+ default:
+ pr_err("%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,
+ 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;
+}
+
+/* re-vistit later*/
+static int msm8x10_wcd_codec_enable_micbias(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ struct msm8x10_wcd_priv *msm8x10_wcd = snd_soc_codec_get_drvdata(codec);
+ u16 micb_int_reg;
+ u8 cfilt_sel_val = 0;
+ char *internal1_text = "Internal1";
+ char *internal2_text = "Internal2";
+ char *internal3_text = "Internal3";
+ enum wcd9xxx_notify_event e_post_off, e_pre_on, e_post_on;
+
+ pr_debug("%s %d\n", __func__, event);
+ switch (w->reg) {
+ case MSM8X10_WCD_A_MICB_1_CTL:
+ micb_int_reg = MSM8X10_WCD_A_MICB_1_INT_RBIAS;
+ cfilt_sel_val =
+ msm8x10_wcd->resmgr.pdata->micbias.bias1_cfilt_sel;
+ e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_1_ON;
+ e_post_on = WCD9XXX_EVENT_POST_MICBIAS_1_ON;
+ e_post_off = WCD9XXX_EVENT_POST_MICBIAS_1_OFF;
+ break;
+ default:
+ pr_err("%s: Error, invalid micbias register\n", __func__);
+ return -EINVAL;
+ }
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ /* Let MBHC module know so micbias switch to be off */
+ wcd9xxx_resmgr_notifier_call(&msm8x10_wcd->resmgr, e_pre_on);
+
+ /* Get cfilt */
+ wcd9xxx_resmgr_cfilt_get(&msm8x10_wcd->resmgr, cfilt_sel_val);
+
+ if (strnstr(w->name, internal1_text, 30))
+ snd_soc_update_bits(codec, micb_int_reg, 0xE0, 0xE0);
+ else if (strnstr(w->name, internal2_text, 30))
+ snd_soc_update_bits(codec, micb_int_reg, 0x1C, 0x1C);
+ else if (strnstr(w->name, internal3_text, 30))
+ snd_soc_update_bits(codec, micb_int_reg, 0x3, 0x3);
+
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ usleep_range(20000, 20100);
+ /* Let MBHC module know so micbias is on */
+ wcd9xxx_resmgr_notifier_call(&msm8x10_wcd->resmgr, e_post_on);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ /* Let MBHC module know so micbias switch to be off */
+ wcd9xxx_resmgr_notifier_call(&msm8x10_wcd->resmgr, e_post_off);
+
+ 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);
+
+ /* Put cfilt */
+ wcd9xxx_resmgr_cfilt_put(&msm8x10_wcd->resmgr, cfilt_sel_val);
+ break;
+ }
+
+ return 0;
+}
+
+#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 msm8x10_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;
+
+ pr_debug("%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) {
+ pr_err("%s: Invalid decimator = %s\n", __func__, w->name);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = kstrtouint(strpbrk(dec_name, "12"), 10, &decimator);
+ if (ret < 0) {
+ pr_err("%s: Invalid decimator = %s\n", __func__, dec_name);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ pr_debug("%s(): widget = %s dec_name = %s decimator = %u\n", __func__,
+ w->name, dec_name, decimator);
+
+ if (w->reg == MSM8X10_WCD_A_CDC_CLK_TX_CLK_EN_B1_CTL) {
+ dec_reset_reg = MSM8X10_WCD_A_CDC_CLK_TX_RESET_B1_CTL;
+ offset = 0;
+ } else {
+ pr_err("%s: Error, incorrect dec\n", __func__);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ tx_vol_ctl_reg = MSM8X10_WCD_A_CDC_TX1_VOL_CTL_CFG +
+ 32 * (decimator - 1);
+ tx_mux_ctl_reg = MSM8X10_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);
+
+ 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);
+
+ 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);
+ cancel_delayed_work_sync(&tx_hpf_work[decimator - 1].dwork);
+ break;
+
+ case SND_SOC_DAPM_POST_PMD:
+
+ 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);
+
+ break;
+ }
+out:
+ kfree(widget_name);
+ return ret;
+}
+
+static int msm8x10_wcd_codec_enable_interpolator(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ pr_debug("%s %d %s\n", __func__, event, w->name);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ snd_soc_update_bits(codec, MSM8X10_WCD_A_CDC_CLK_RX_RESET_CTL,
+ 1 << w->shift, 1 << w->shift);
+ snd_soc_update_bits(codec, MSM8X10_WCD_A_CDC_CLK_RX_RESET_CTL,
+ 1 << w->shift, 0x0);
+ 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;
+ }
+ return 0;
+}
+
+
+/* The register address is the same as other codec so it can use resmgr*/
+static int msm8x10_wcd_codec_enable_rx_bias(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ struct msm8x10_wcd_priv *msm8x10_wcd = snd_soc_codec_get_drvdata(codec);
+
+ pr_debug("%s %d\n", __func__, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ wcd9xxx_resmgr_enable_rx_bias(&msm8x10_wcd->resmgr, 1);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ wcd9xxx_resmgr_enable_rx_bias(&msm8x10_wcd->resmgr, 0);
+ break;
+ }
+ return 0;
+}
+static int msm8x10_wcd_hphr_dac_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ pr_debug("%s %s %d\n", __func__, w->name, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ snd_soc_update_bits(codec, w->reg, 0x40, 0x40);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ snd_soc_update_bits(codec, w->reg, 0x40, 0x00);
+ break;
+ }
+ return 0;
+}
+
+static int msm8x10_wcd_hph_pa_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ struct msm8x10_wcd_priv *msm8x10_wcd = snd_soc_codec_get_drvdata(codec);
+ enum wcd9xxx_notify_event e_pre_on, e_post_off;
+
+ pr_debug("%s: %s event = %d\n", __func__, w->name, event);
+ if (w->shift == 5) {
+ e_pre_on = WCD9XXX_EVENT_PRE_HPHR_PA_ON;
+ e_post_off = WCD9XXX_EVENT_POST_HPHR_PA_OFF;
+ } else if (w->shift == 4) {
+ e_pre_on = WCD9XXX_EVENT_PRE_HPHL_PA_ON;
+ e_post_off = WCD9XXX_EVENT_POST_HPHL_PA_OFF;
+ } else {
+ pr_err("%s: Invalid w->shift %d\n", __func__, w->shift);
+ return -EINVAL;
+ }
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ /* Let MBHC module know PA is turning on */
+ wcd9xxx_resmgr_notifier_call(&msm8x10_wcd->resmgr, e_pre_on);
+ break;
+
+ case SND_SOC_DAPM_POST_PMU:
+ usleep_range(10000, 10100);
+ break;
+
+ case SND_SOC_DAPM_POST_PMD:
+ /* Let MBHC module know PA turned off */
+ wcd9xxx_resmgr_notifier_call(&msm8x10_wcd->resmgr, e_post_off);
+
+ /*
+ * schedule work is required because at the time HPH PA DAPM
+ * event callback is called by DAPM framework, CODEC dapm mutex
+ * would have been locked while snd_soc_jack_report also
+ * attempts to acquire same lock.
+ */
+ pr_debug("%s: sleep 10 ms after %s PA disable.\n", __func__,
+ w->name);
+ usleep_range(10000, 10100);
+ break;
+ }
+ return 0;
+}
+
+static int msm8x10_wcd_lineout_dac_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ pr_debug("%s %s %d\n", __func__, w->name, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ snd_soc_update_bits(codec, w->reg, 0x40, 0x40);
+ break;
+
+ case SND_SOC_DAPM_POST_PMD:
+ snd_soc_update_bits(codec, w->reg, 0x40, 0x00);
+ break;
+ }
+ return 0;
+}
+
+static int msm8x10_wcd_spk_dac_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ pr_debug("%s %s %d\n", __func__, w->name, event);
+ return 0;
+}
+
+static const struct snd_soc_dapm_route audio_i2s_map[] = {
+};
+
+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 TX3", NULL, "TX_I2S_CLK"},
+ {"I2S TX4", NULL, "TX_I2S_CLK"},
+
+ {"AIF1 CAP", NULL, "AIF1_CAP Mixer"},
+
+ {"AIF1_CAP Mixer", "I2S TX1", "I2S TX1 MUX"},
+ {"AIF1_CAP Mixer", "I2S TX2", "I2S TX2 MUX"},
+ {"AIF1_CAP Mixer", "I2S TX3", "I2S TX3 MUX"},
+ {"AIF1_CAP Mixer", "I2S TX4", "I2S TX4 MUX"},
+
+ {"I2S TX1 MUX", NULL, "DEC1 MUX"},
+ {"I2S TX2 MUX", NULL, "DEC2 MUX"},
+ {"I2S TX3 MUX", NULL, "RX1 MIX1"},
+ {"I2S TX4 MUX", "RMIX2", "RX1 MIX2"},
+ {"I2S TX4 MUX", "RMIX3", "RX1 MIX3"},
+
+ /* Earpiece (RX MIX1) */
+ {"EAR", NULL, "EAR PA"},
+ {"EAR PA", NULL, "DAC1"},
+ {"DAC1", NULL, "CP"},
+
+ /* Headset (RX MIX1 and RX MIX2) */
+ {"HEADPHONE", NULL, "HPHL"},
+ {"HEADPHONE", NULL, "HPHR"},
+
+ {"HPHL", NULL, "HPHL DAC"},
+
+ {"HPHR", NULL, "HPHR DAC"},
+ {"HPHR_PA_MIXER", NULL, "HPHR DAC"},
+
+ {"HPHL DAC", NULL, "CP"},
+
+ {"HPHR DAC", NULL, "CP"},
+
+ {"DAC1", "Switch", "RX1 CHAIN"},
+ {"HPHL DAC", "Switch", "RX1 CHAIN"},
+ {"HPHR DAC", NULL, "RX2 CHAIN"},
+
+ {"LINEOUT1", NULL, "LINEOUT1 PA"},
+ {"SPK_OUT", NULL, "SPK PA"},
+
+ {"LINEOUT1 PA", NULL, "CP"},
+ {"LINEOUT1 PA", NULL, "LINEOUT1 DAC"},
+
+ {"LINEOUT1 DAC", "RX2 INPUT", "RX2 MIX1"},
+ {"LINEOUT1 DAC", "RX3 INPUT", "RX3 MIX1"},
+
+ {"SPK PA", NULL, "SPK DAC"},
+ {"SPK DAC", NULL, "RX7 MIX2"},
+
+ {"RX1 CHAIN", NULL, "RX1 MIX2"},
+ {"RX2 CHAIN", NULL, "RX2 MIX2"},
+
+ {"LINEOUT1 DAC", NULL, "RX_BIAS"},
+ {"SPK DAC", NULL, "RX_BIAS"},
+
+ {"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 MIX1"},
+ {"RX1 MIX2", NULL, "RX1 MIX2 INP1"},
+ {"RX1 MIX2", NULL, "RX1 MIX2 INP2"},
+ {"RX2 MIX2", NULL, "RX2 MIX1"},
+ {"RX2 MIX2", NULL, "RX2 MIX2 INP1"},
+ {"RX2 MIX2", NULL, "RX2 MIX2 INP2"},
+
+ {"I2S RX1 MUX", "AIF1_PB", "AIF1 PB"},
+ {"I2S RX2 MUX", "AIF1_PB", "AIF1 PB"},
+ {"I2S RX3 MUX", "AIF1_PB", "AIF1 PB"},
+
+ {"I2S RX1", NULL, "I2S RX1 MUX"},
+ {"I2S RX2", NULL, "I2S RX2 MUX"},
+ {"I2S RX3", NULL, "I2S RX3 MUX"},
+
+ {"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"},
+
+ /* Decimator Inputs */
+ {"DEC1 MUX", "DMIC1", "DMIC1"},
+ {"DEC1 MUX", "DMIC2", "DMIC2"},
+ {"DEC1 MUX", "ADC1", "ADC1"},
+ {"DEC1 MUX", "ADC2", "ADC2"},
+ {"DEC1 MUX", NULL, "CDC_CONN"},
+
+ {"DEC2 MUX", "DMIC1", "DMIC1"},
+ {"DEC2 MUX", "DMIC2", "DMIC2"},
+ {"DEC2 MUX", "ADC1", "ADC1"},
+ {"DEC2 MUX", "ADC2", "ADC2"},
+ {"DEC2 MUX", NULL, "CDC_CONN"},
+
+ /* ADC Connections */
+ {"ADC1", NULL, "AMIC1"},
+ {"ADC2", NULL, "AMIC2"},
+
+ {"IIR1", NULL, "IIR1 INP1 MUX"},
+ {"IIR1 INP1 MUX", "DEC1", "DEC1 MUX"},
+ {"IIR1 INP1 MUX", "DEC2", "DEC2 MUX"},
+
+ /* There is no LDO_H in Helicon */
+ {"MIC BIAS1 Internal1", NULL, "LDO_H"},
+ {"MIC BIAS1 Internal2", NULL, "LDO_H"},
+ {"MIC BIAS1 External", NULL, "LDO_H"},
+};
+
+
+#define MSM8X10_WCD_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
+
+
+static int msm8x10_wcd_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct msm8x10_wcd *msm8x10_wcd_core =
+ dev_get_drvdata(dai->codec->dev);
+ pr_debug("%s(): substream = %s stream = %d\n" , __func__,
+ substream->name, substream->stream);
+ if ((msm8x10_wcd_core != NULL) &&
+ (msm8x10_wcd_core->dev != NULL))
+ pm_runtime_get_sync(msm8x10_wcd_core->dev);
+
+ return 0;
+}
+
+static void msm8x10_wcd_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct msm8x10_wcd *msm8x10_wcd_core =
+ dev_get_drvdata(dai->codec->dev);
+ pr_debug("%s(): substream = %s stream = %d\n" , __func__,
+ substream->name, substream->stream);
+ if ((msm8x10_wcd_core != NULL) &&
+ (msm8x10_wcd_core->dev != NULL)) {
+ pm_runtime_mark_last_busy(msm8x10_wcd_core->dev);
+ pm_runtime_put(msm8x10_wcd_core->dev);
+ }
+}
+
+/* working here*/
+int msm8x10_wcd_mclk_enable(struct snd_soc_codec *codec,
+ int mclk_enable, bool dapm)
+{
+ struct msm8x10_wcd_priv *msm8x10_wcd = snd_soc_codec_get_drvdata(codec);
+
+ pr_debug("%s: mclk_enable = %u, dapm = %d\n", __func__, mclk_enable,
+ dapm);
+
+ WCD9XXX_BCL_LOCK(&msm8x10_wcd->resmgr);
+ if (mclk_enable) {
+ wcd9xxx_resmgr_get_bandgap(&msm8x10_wcd->resmgr,
+ WCD9XXX_BANDGAP_AUDIO_MODE);
+ wcd9xxx_resmgr_get_clk_block(&msm8x10_wcd->resmgr,
+ WCD9XXX_CLK_MCLK);
+ } else {
+ /* Put clock and BG */
+ wcd9xxx_resmgr_put_clk_block(&msm8x10_wcd->resmgr,
+ WCD9XXX_CLK_MCLK);
+ wcd9xxx_resmgr_put_bandgap(&msm8x10_wcd->resmgr,
+ WCD9XXX_BANDGAP_AUDIO_MODE);
+ }
+ WCD9XXX_BCL_UNLOCK(&msm8x10_wcd->resmgr);
+
+ return 0;
+}
+
+static int msm8x10_wcd_set_dai_sysclk(struct snd_soc_dai *dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ pr_debug("%s\n", __func__);
+ return 0;
+}
+
+static int msm8x10_wcd_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+ pr_debug("%s\n", __func__);
+ return 0;
+}
+
+static int msm8x10_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)
+
+{
+ pr_debug("%s\n", __func__);
+
+ return 0;
+}
+
+static int msm8x10_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)
+
+{
+ pr_debug("%s\n", __func__);
+ return 0;
+}
+
+static int msm8x10_wcd_set_interpolator_rate(struct snd_soc_dai *dai,
+ u8 rx_fs_rate_reg_val, u32 sample_rate)
+{
+ return 0;
+}
+
+static int msm8x10_wcd_set_decimator_rate(struct snd_soc_dai *dai,
+ u8 tx_fs_rate_reg_val, u32 sample_rate)
+{
+ return 0;
+}
+
+static int msm8x10_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;
+
+ pr_debug("%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:
+ pr_err("%s: Invalid sampling rate %d\n", __func__,
+ params_rate(params));
+ return -EINVAL;
+ }
+
+ switch (substream->stream) {
+ case SNDRV_PCM_STREAM_CAPTURE:
+ ret = msm8x10_wcd_set_decimator_rate(dai, tx_fs_rate,
+ params_rate(params));
+ if (ret < 0) {
+ pr_err("%s: set decimator rate failed %d\n", __func__,
+ ret);
+ return ret;
+ }
+
+
+ break;
+
+ case SNDRV_PCM_STREAM_PLAYBACK:
+ ret = msm8x10_wcd_set_interpolator_rate(dai, rx_fs_rate,
+ params_rate(params));
+ if (ret < 0) {
+ pr_err("%s: set decimator rate failed %d\n", __func__,
+ ret);
+ return ret;
+ }
+
+ break;
+ default:
+ pr_err("%s: Invalid stream type %d\n", __func__,
+ substream->stream);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct snd_soc_dai_ops msm8x10_wcd_dai_ops = {
+ .startup = msm8x10_wcd_startup,
+ .shutdown = msm8x10_wcd_shutdown,
+ .hw_params = msm8x10_wcd_hw_params,
+ .set_sysclk = msm8x10_wcd_set_dai_sysclk,
+ .set_fmt = msm8x10_wcd_set_dai_fmt,
+ .set_channel_map = msm8x10_wcd_set_channel_map,
+ .get_channel_map = msm8x10_wcd_get_channel_map,
+};
+
+static struct snd_soc_dai_driver msm8x10_wcd_i2s_dai[] = {
+ {
+ .name = "msm8x10_wcd_i2s_rx1",
+ .id = AIF1_PB,
+ .playback = {
+ .stream_name = "AIF1 Playback",
+ .rates = MSM8X10_WCD_RATES,
+ .formats = MSM8X10_WCD_FORMATS,
+ .rate_max = 192000,
+ .rate_min = 8000,
+ .channels_min = 1,
+ .channels_max = 4,
+ },
+ .ops = &msm8x10_wcd_dai_ops,
+ },
+ {
+ .name = "msm8x10_wcd_i2s_tx1",
+ .id = AIF1_CAP,
+ .capture = {
+ .stream_name = "AIF1 Capture",
+ .rates = MSM8X10_WCD_RATES,
+ .formats = MSM8X10_WCD_FORMATS,
+ .rate_max = 192000,
+ .rate_min = 8000,
+ .channels_min = 1,
+ .channels_max = 4,
+ },
+ .ops = &msm8x10_wcd_dai_ops,
+ },
+};
+
+static int msm8x10_wcd_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ pr_debug("%s: Sleeping 20ms after enabling EAR PA\n",
+ __func__);
+ msleep(20);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ pr_debug("%s: Sleeping 20ms after disabling EAR PA\n",
+ __func__);
+ msleep(20);
+ break;
+ }
+ return 0;
+}
+
+/* Todo: Have seperate dapm widgets for I2S and Slimbus.
+ * Might Need to have callbacks registered only for slimbus
+ */
+static const struct snd_soc_dapm_widget msm8x10_wcd_dapm_widgets[] = {
+ /*RX stuff */
+ SND_SOC_DAPM_OUTPUT("EAR"),
+
+ SND_SOC_DAPM_PGA_E("EAR PA", MSM8X10_WCD_A_RX_EAR_EN, 4, 0, NULL, 0,
+ msm8x10_wcd_codec_enable_ear_pa, SND_SOC_DAPM_POST_PMU),
+
+ SND_SOC_DAPM_MIXER("DAC1", MSM8X10_WCD_A_RX_EAR_EN, 6, 0, dac1_switch,
+ ARRAY_SIZE(dac1_switch)),
+
+ SND_SOC_DAPM_AIF_IN("AIF1 PB", "AIF1 Playback", 0, SND_SOC_NOPM,
+ AIF1_PB, 0),
+
+ SND_SOC_DAPM_MUX("I2S RX1 MUX", SND_SOC_NOPM, MSM8X10_WCD_RX1, 0,
+ &slim_rx_mux[MSM8X10_WCD_RX1]),
+ SND_SOC_DAPM_MUX("I2S RX2 MUX", SND_SOC_NOPM, MSM8X10_WCD_RX2, 0,
+ &slim_rx_mux[MSM8X10_WCD_RX2]),
+ SND_SOC_DAPM_MUX("I2S RX3 MUX", SND_SOC_NOPM, MSM8X10_WCD_RX3, 0,
+ &slim_rx_mux[MSM8X10_WCD_RX3]),
+
+ SND_SOC_DAPM_MIXER("I2S RX1", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I2S RX2", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I2S RX3", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I2S RX4", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I2S RX5", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ /* Headphone */
+ SND_SOC_DAPM_OUTPUT("HEADPHONE"),
+ SND_SOC_DAPM_PGA_E("HPHL", MSM8X10_WCD_A_RX_HPH_CNP_EN,
+ 5, 0, NULL, 0,
+ msm8x10_wcd_hph_pa_event, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MIXER("HPHL DAC", MSM8X10_WCD_A_RX_HPH_L_DAC_CTL,
+ 7, 0,
+ hphl_switch, ARRAY_SIZE(hphl_switch)),
+
+ SND_SOC_DAPM_PGA_E("HPHR", MSM8X10_WCD_A_RX_HPH_CNP_EN,
+ 4, 0, NULL, 0,
+ msm8x10_wcd_hph_pa_event, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_DAC_E("HPHR DAC", NULL, MSM8X10_WCD_A_RX_HPH_R_DAC_CTL,
+ 7, 0,
+ msm8x10_wcd_hphr_dac_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ /* Speaker */
+ SND_SOC_DAPM_OUTPUT("LINEOUT1"),
+ SND_SOC_DAPM_OUTPUT("SPK_OUT"),
+
+ SND_SOC_DAPM_PGA_E("LINEOUT1 PA", MSM8X10_WCD_A_RX_LINE_CNP_EN,
+ 0, 0, NULL, 0, msm8x10_wcd_codec_enable_lineout,
+ SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_PGA_E("SPK PA", MSM8X10_WCD_A_SPKR_DRV_EN,
+ 7, 0 , NULL, 0, msm8x10_wcd_codec_enable_spk_pa,
+ SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_DAC_E("LINEOUT1 DAC", NULL,
+ MSM8X10_WCD_A_RX_LINE_1_DAC_CTL, 7, 0,
+ msm8x10_wcd_lineout_dac_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_DAC_E("SPK DAC", NULL, SND_SOC_NOPM, 0, 0,
+ msm8x10_wcd_spk_dac_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MIXER("RX1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("RX2 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_MIXER_E("RX1 MIX2",
+ MSM8X10_WCD_A_CDC_CLK_RX_B1_CTL, 0, 0, NULL,
+ 0, msm8x10_wcd_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU),
+ SND_SOC_DAPM_MIXER_E("RX2 MIX2",
+ MSM8X10_WCD_A_CDC_CLK_RX_B1_CTL, 1, 0, NULL,
+ 0, msm8x10_wcd_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU),
+ SND_SOC_DAPM_MIXER_E("RX3 MIX1",
+ MSM8X10_WCD_A_CDC_CLK_RX_B1_CTL, 2, 0, NULL,
+ 0, msm8x10_wcd_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU),
+
+ SND_SOC_DAPM_MIXER("RX1 CHAIN", MSM8X10_WCD_A_CDC_RX1_B6_CTL,
+ 5, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("RX2 CHAIN", MSM8X10_WCD_A_CDC_RX2_B6_CTL,
+ 5, 0, NULL, 0),
+
+ 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("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("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("CP", MSM8X10_WCD_A_CP_EN, 0, 0,
+ msm8x10_wcd_codec_enable_charge_pump, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+
+ SND_SOC_DAPM_SUPPLY("RX_BIAS", SND_SOC_NOPM, 0, 0,
+ msm8x10_wcd_codec_enable_rx_bias, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ /* TX */
+
+ SND_SOC_DAPM_SUPPLY("CDC_CONN", MSM8X10_WCD_A_CDC_CLK_OTHR_CTL,
+ 2, 0, NULL, 0),
+
+
+ SND_SOC_DAPM_INPUT("AMIC1"),
+ SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 External",
+ MSM8X10_WCD_A_MICB_1_CTL, 7, 0,
+ msm8x10_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 BIAS1 Internal1",
+ MSM8X10_WCD_A_MICB_1_CTL, 7, 0,
+ msm8x10_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 BIAS1 Internal2",
+ MSM8X10_WCD_A_MICB_1_CTL, 7, 0,
+ msm8x10_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, MSM8X10_WCD_A_TX_1_EN, 7, 0,
+ msm8x10_wcd_codec_enable_adc, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_ADC_E("ADC1", NULL, MSM8X10_WCD_A_TX_2_EN, 7, 0,
+ msm8x10_wcd_codec_enable_adc, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_INPUT("AMIC3"),
+
+ SND_SOC_DAPM_MUX_E("DEC1 MUX",
+ MSM8X10_WCD_A_CDC_CLK_TX_CLK_EN_B1_CTL, 0, 0,
+ &dec1_mux, msm8x10_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",
+ MSM8X10_WCD_A_CDC_CLK_TX_CLK_EN_B1_CTL, 1, 0,
+ &dec2_mux, msm8x10_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_INPUT("AMIC2"),
+ SND_SOC_DAPM_AIF_OUT("AIF1 CAP", "AIF1 Capture", 0, SND_SOC_NOPM,
+ AIF1_CAP, 0),
+
+ SND_SOC_DAPM_MIXER("AIF1_CAP Mixer", SND_SOC_NOPM, AIF1_CAP, 0,
+ aif_cap_mixer, ARRAY_SIZE(aif_cap_mixer)),
+
+ /* Digital Mic Inputs */
+ SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0,
+ msm8x10_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,
+ msm8x10_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", MSM8X10_WCD_A_CDC_CLK_SD_CTL, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_SUPPLY("RX_I2S_CLK", MSM8X10_WCD_A_CDC_CLK_RX_I2S_CTL,
+ 4, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("TX_I2S_CLK", MSM8X10_WCD_A_CDC_CLK_TX_I2S_CTL, 4,
+ 0, NULL, 0),
+};
+
+static const struct msm8x10_wcd_reg_mask_val msm8x10_wcd_reg_defaults[] = {
+
+ /* set MCLk to 9.6 */
+ MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_CHIP_CTL, 0x0A),
+
+ /* EAR PA deafults */
+ MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_RX_EAR_CMBUFF, 0x05),
+
+ /* RX deafults */
+ MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_CDC_RX1_B5_CTL, 0x78),
+ MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_CDC_RX2_B5_CTL, 0x78),
+ MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_CDC_RX3_B5_CTL, 0x78),
+
+ /* RX1 and RX2 defaults */
+ MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_CDC_RX1_B6_CTL, 0xA0),
+ MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_CDC_RX2_B6_CTL, 0xA0),
+
+ /* RX3 to RX7 defaults */
+ MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_CDC_RX3_B6_CTL, 0x80),
+
+ /* Reduce HPH DAC bias to 70% */
+ MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_RX_HPH_BIAS_PA, 0x7A),
+ /*Reduce EAR DAC bias to 70% */
+ MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_RX_EAR_BIAS_PA, 0x76),
+ /* Reduce LINE DAC bias to 70% */
+ MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_RX_LINE_BIAS_PA, 0x78),
+
+
+ /* Disable TX7 internal biasing path which can cause leakage */
+ MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_TX_SUP_SWITCH_CTRL_1, 0xBF),
+};
+
+static void msm8x10_wcd_update_reg_defaults(struct snd_soc_codec *codec)
+{
+ u32 i;
+
+ for (i = 0; i < ARRAY_SIZE(msm8x10_wcd_reg_defaults); i++)
+ snd_soc_write(codec, msm8x10_wcd_reg_defaults[i].reg,
+ msm8x10_wcd_reg_defaults[i].val);
+}
+
+static const struct msm8x10_wcd_reg_mask_val
+ msm8x10_wcd_codec_reg_init_val[] = {
+ /* Initialize current threshold to 350MA
+ * number of wait and run cycles to 4096
+ */
+ {MSM8X10_WCD_A_RX_HPH_OCP_CTL, 0xE1, 0x61},
+ {MSM8X10_WCD_A_RX_COM_OCP_COUNT, 0xFF, 0xFF},
+
+ /* Initialize gain registers to use register gain */
+ {MSM8X10_WCD_A_RX_HPH_L_GAIN, 0x20, 0x20},
+ {MSM8X10_WCD_A_RX_HPH_R_GAIN, 0x20, 0x20},
+ {MSM8X10_WCD_A_RX_LINE_1_GAIN, 0x20, 0x20},
+
+ /*enable HPF filter for TX paths */
+ {MSM8X10_WCD_A_CDC_TX1_MUX_CTL, 0x8, 0x0},
+ {MSM8X10_WCD_A_CDC_TX2_MUX_CTL, 0x8, 0x0},
+
+ /* config Decimator for DMIC CLK_MODE_1(3.2Mhz@9.6Mhz mclk) */
+ {MSM8X10_WCD_A_CDC_TX1_DMIC_CTL, 0x7, 0x1},
+ {MSM8X10_WCD_A_CDC_TX2_DMIC_CTL, 0x7, 0x1},
+
+ /* config DMIC clk to CLK_MODE_1 (3.2Mhz@9.6Mhz mclk) */
+ {MSM8X10_WCD_A_CDC_CLK_DMIC_B1_CTL, 0xEE, 0x22},
+
+};
+
+static void msm8x10_wcd_codec_init_reg(struct snd_soc_codec *codec)
+{
+ u32 i;
+
+ for (i = 0; i < ARRAY_SIZE(msm8x10_wcd_codec_reg_init_val); i++)
+ snd_soc_update_bits(codec,
+ msm8x10_wcd_codec_reg_init_val[i].reg,
+ msm8x10_wcd_codec_reg_init_val[i].mask,
+ msm8x10_wcd_codec_reg_init_val[i].val);
+}
+
+int msm8x10_wcd_hs_detect(struct snd_soc_codec *codec,
+ struct msm8x10_wcd_mbhc_config *mbhc_cfg)
+{
+ return 0;
+}
+EXPORT_SYMBOL_GPL(msm8x10_wcd_hs_detect);
+
+static int msm8x10_wcd_codec_probe(struct snd_soc_codec *codec)
+{
+ msm8x10_wcd_codec_init_reg(codec);
+
+ msm8x10_wcd_update_reg_defaults(codec);
+
+ dev_dbg(codec->dev, "%s()\n", __func__);
+
+ return 0;
+}
+
+static int msm8x10_wcd_codec_remove(struct snd_soc_codec *codec)
+{
+ return 0;
+}
+
+static struct snd_soc_codec_driver soc_codec_dev_msm8x10_wcd = {
+ .probe = msm8x10_wcd_codec_probe,
+ .remove = msm8x10_wcd_codec_remove,
+
+ .read = msm8x10_wcd_read,
+ .write = msm8x10_wcd_write,
+
+ .readable_register = msm8x10_wcd_readable,
+ .volatile_register = msm8x10_wcd_volatile,
+
+ .reg_cache_size = MSM8X10_WCD_CACHE_SIZE,
+ .reg_cache_default = msm8x10_wcd_reset_reg_defaults,
+ .reg_word_size = 1,
+
+ .controls = msm8x10_wcd_snd_controls,
+ .num_controls = ARRAY_SIZE(msm8x10_wcd_snd_controls),
+ .dapm_widgets = msm8x10_wcd_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(msm8x10_wcd_dapm_widgets),
+ .dapm_routes = audio_map,
+ .num_dapm_routes = ARRAY_SIZE(audio_map),
+};
+
+static int __devinit msm8x10_wcd_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int ret;
+ struct msm8x10_wcd_pdata *pdata;
+ if (client->dev.of_node) {
+ dev_dbg(&client->dev, "%s:Platform data from device tree\n",
+ __func__);
+ pdata = msm8x10_wcd_populate_dt_pdata(&client->dev);
+ client->dev.platform_data = pdata;
+ } else {
+ dev_dbg(&client->dev, "%s:Platform data from board file\n",
+ __func__);
+ pdata = client->dev.platform_data;
+ }
+
+ ret = snd_soc_register_codec(&client->dev,
+ &soc_codec_dev_msm8x10_wcd,
+ msm8x10_wcd_i2s_dai, ARRAY_SIZE(msm8x10_wcd_i2s_dai));
+ dev_dbg(&client->dev, "%s:ret = 0x%x\n", __func__, ret);
+
+ return ret;
+}
+
+static int __devexit msm8x10_wcd_i2c_remove(struct i2c_client *client)
+{
+ return 0;
+}
+
+static struct i2c_device_id msm8x10_wcd_id_table[] = {
+ {"msm8x10-wcd-i2c", MSM8X10_WCD_I2C_TOP_LEVEL},
+ {"msm8x10-wcd-i2c", MSM8X10_WCD_I2C_ANALOG},
+ {"msm8x10-wcd-i2c", MSM8X10_WCD_I2C_DIGITAL_1},
+ {"msm8x10-wcd-i2c", MSM8X10_WCD_I2C_DIGITAL_2},
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, msm8x10_wcd_id_table);
+
+static struct of_device_id msm8x10_wcd_of_match[] = {
+ { .compatible = "qcom,msm8x10-wcd-i2c",},
+ { },
+};
+
+
+static struct i2c_driver msm8x10_wcd_i2c_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "msm8x10-wcd-i2c-core",
+ .of_match_table = msm8x10_wcd_of_match
+ },
+ .id_table = msm8x10_wcd_id_table,
+ .probe = msm8x10_wcd_i2c_probe,
+ .remove = __devexit_p(msm8x10_wcd_i2c_remove),
+};
+
+static int __init msm8x10_wcd_codec_init(void)
+{
+ int ret;
+
+ pr_debug("%s:\n", __func__);
+ ret = i2c_add_driver(&msm8x10_wcd_i2c_driver);
+ if (ret != 0)
+ pr_err("%s: Failed to add msm8x10 wcd I2C driver - error code %d\n",
+ __func__, ret);
+ return ret;
+}
+
+static void __exit msm8x10_wcd_codec_exit(void)
+{
+ i2c_del_driver(&msm8x10_wcd_i2c_driver);
+}
+
+
+module_init(msm8x10_wcd_codec_init);
+module_exit(msm8x10_wcd_codec_exit);
+
+MODULE_DESCRIPTION("MSM8x10 Audio codec driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/msm8x10-wcd.h b/sound/soc/codecs/msm8x10-wcd.h
new file mode 100644
index 0000000..f30e8e7
--- /dev/null
+++ b/sound/soc/codecs/msm8x10-wcd.h
@@ -0,0 +1,229 @@
+/* Copyright (c) 2013, 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 MSM8X10_WCD_H
+#define MSM8X10_WCD_H
+
+#include <sound/soc.h>
+#include <sound/jack.h>
+#include "wcd9xxx-mbhc.h"
+#include "wcd9xxx-resmgr.h"
+
+#define MSM8X10_WCD_NUM_REGISTERS 0x600
+#define MSM8X10_WCD_MAX_REGISTER (MSM8X10_WCD_NUM_REGISTERS-1)
+#define MSM8X10_WCD_CACHE_SIZE MSM8X10_WCD_NUM_REGISTERS
+#define MSM8X10_WCD_NUM_IRQ_REGS 3
+#define MAX_REGULATOR 7
+#define MSM8X10_WCD_REG_VAL(reg, val) {reg, 0, val}
+
+#define MSM8X10_WCD_IS_DINO_REG(reg) \
+ (((reg >= 0x400) && (reg <= 0x5FF)) ? 1 : 0)
+#define MSM8X10_WCD_IS_HELICON_REG(reg) \
+ (((reg >= 0x000) && (reg <= 0x1FF)) ? 1 : 0)
+extern const u8 msm8x10_wcd_reg_readable[MSM8X10_WCD_CACHE_SIZE];
+extern const u8 msm8x10_wcd_reset_reg_defaults[MSM8X10_WCD_CACHE_SIZE];
+struct msm8x10_wcd_codec_dai_data {
+ u32 rate;
+ u32 *ch_num;
+ u32 ch_act;
+ u32 ch_tot;
+};
+
+enum msm8x10_wcd_pid_current {
+ MSM8X10_WCD_PID_MIC_2P5_UA,
+ MSM8X10_WCD_PID_MIC_5_UA,
+ MSM8X10_WCD_PID_MIC_10_UA,
+ MSM8X10_WCD_PID_MIC_20_UA,
+};
+
+struct msm8x10_wcd_reg_mask_val {
+ u16 reg;
+ u8 mask;
+ u8 val;
+};
+
+enum msm8x10_wcd_mbhc_analog_pwr_cfg {
+ MSM8X10_WCD_ANALOG_PWR_COLLAPSED = 0,
+ MSM8X10_WCD_ANALOG_PWR_ON,
+ MSM8X10_WCD_NUM_ANALOG_PWR_CONFIGS,
+};
+
+/* Number of input and output Slimbus port */
+enum {
+ MSM8X10_WCD_RX1 = 0,
+ MSM8X10_WCD_RX2,
+ MSM8X10_WCD_RX3,
+ MSM8X10_WCD_RX_MAX,
+};
+
+enum {
+ MSM8X10_WCD_TX1 = 0,
+ MSM8X10_WCD_TX2,
+ MSM8X10_WCD_TX3,
+ MSM8X10_WCD_TX4,
+ MSM8X10_WCD_TX_MAX,
+};
+
+
+enum {
+ /* INTR_REG 0 */
+ MSM8X10_WCD_IRQ_RESERVED_0 = 0,
+ MSM8X10_WCD_IRQ_MBHC_REMOVAL,
+ MSM8X10_WCD_IRQ_MBHC_SHORT_TERM,
+ MSM8X10_WCD_IRQ_MBHC_PRESS,
+ MSM8X10_WCD_IRQ_MBHC_RELEASE,
+ MSM8X10_WCD_IRQ_MBHC_POTENTIAL,
+ MSM8X10_WCD_IRQ_MBHC_INSERTION,
+ MSM8X10_WCD_IRQ_MBHC_HS_DET,
+ /* INTR_REG 1 */
+ MSM8X10_WCD_IRQ_PA_STARTUP,
+ MSM8X10_WCD_IRQ_BG_PRECHARGE,
+ MSM8X10_WCD_IRQ_RESERVED_1,
+ MSM8X10_WCD_IRQ_EAR_PA_OCPL_FAULT,
+ MSM8X10_WCD_IRQ_EAR_PA_STARTUP,
+ MSM8X10_WCD_IRQ_SPKR_PA_OCPL_FAULT,
+ MSM8X10_WCD_IRQ_SPKR_CLIP_FAULT,
+ MSM8X10_WCD_IRQ_RESERVED_2,
+ /* INTR_REG 2 */
+ MSM8X10_WCD_IRQ_HPH_L_PA_STARTUP,
+ MSM8X10_WCD_IRQ_HPH_R_PA_STARTUP,
+ MSM8X10_WCD_IRQ_HPH_PA_OCPL_FAULT,
+ MSM8X10_WCD_IRQ_HPH_PA_OCPR_FAULT,
+ MSM8X10_WCD_IRQ_RESERVED_3,
+ MSM8X10_WCD_IRQ_RESERVED_4,
+ MSM8X10_WCD_IRQ_RESERVED_5,
+ MSM8X10_WCD_IRQ_RESERVED_6,
+ MSM8X10_WCD_NUM_IRQS,
+};
+
+
+/* Each micbias can be assigned to one of three cfilters
+ * Vbatt_min >= .15V + ldoh_v
+ * ldoh_v >= .15v + cfiltx_mv
+ * If ldoh_v = 1.95 160 mv < cfiltx_mv < 1800 mv
+ * If ldoh_v = 2.35 200 mv < cfiltx_mv < 2200 mv
+ * If ldoh_v = 2.75 240 mv < cfiltx_mv < 2600 mv
+ * If ldoh_v = 2.85 250 mv < cfiltx_mv < 2700 mv
+ */
+
+struct msm8x10_wcd_micbias_setting {
+ u8 ldoh_v;
+ u32 cfilt1_mv; /* in mv */
+ /* Different WCD9xxx series codecs may not
+ * have 4 mic biases. If a codec has fewer
+ * mic biases, some of these properties will
+ * not be used.
+ */
+ u8 bias1_cfilt_sel;
+ u8 bias1_cap_mode;
+};
+
+struct msm8x10_wcd_ocp_setting {
+ unsigned int use_pdata:1; /* 0 - use sys default as recommended */
+ unsigned int num_attempts:4; /* up to 15 attempts */
+ unsigned int run_time:4; /* in duty cycle */
+ unsigned int wait_time:4; /* in duty cycle */
+ unsigned int hph_ocp_limit:3; /* Headphone OCP current limit */
+};
+
+
+struct msm8x10_wcd_regulator {
+ const char *name;
+ int min_uV;
+ int max_uV;
+ int optimum_uA;
+ struct regulator *regulator;
+};
+
+struct msm8x10_wcd_pdata {
+ int irq;
+ int irq_base;
+ int num_irqs;
+ int reset_gpio;
+ void *msm8x10_wcd_ahb_base_vaddr;
+ struct msm8x10_wcd_micbias_setting micbias;
+ struct msm8x10_wcd_ocp_setting ocp;
+ struct msm8x10_wcd_regulator regulator[MAX_REGULATOR];
+ u32 mclk_rate;
+};
+
+
+enum msm8x10_wcd_micbias_num {
+ MSM8X10_WCD_MICBIAS1 = 0,
+};
+
+struct msm8x10_wcd_mbhc_config {
+ struct snd_soc_jack *headset_jack;
+ struct snd_soc_jack *button_jack;
+ bool read_fw_bin;
+ /* void* calibration contains:
+ * struct msm8x10_wcd_mbhc_general_cfg generic;
+ * struct msm8x10_wcd_mbhc_plug_detect_cfg plug_det;
+ * struct msm8x10_wcd_mbhc_plug_type_cfg plug_type;
+ * struct msm8x10_wcd_mbhc_btn_detect_cfg btn_det;
+ * struct msm8x10_wcd_mbhc_imped_detect_cfg imped_det;
+ * Note: various size depends on btn_det->num_btn
+ */
+ void *calibration;
+ enum msm8x10_wcd_micbias_num micbias;
+ int (*mclk_cb_fn) (struct snd_soc_codec*, int, bool);
+ unsigned int mclk_rate;
+ unsigned int gpio;
+ unsigned int gpio_irq;
+ int gpio_level_insert;
+ bool detect_extn_cable;
+ /* swap_gnd_mic returns true if extern GND/MIC swap switch toggled */
+ bool (*swap_gnd_mic) (struct snd_soc_codec *);
+};
+
+
+enum msm8x10_wcd_pm_state {
+ MSM8X10_WCD_PM_SLEEPABLE,
+ MSM8X10_WCD_PM_AWAKE,
+ MSM8X10_WCD_PM_ASLEEP,
+};
+
+struct msm8x10_wcd {
+ struct device *dev;
+ struct mutex io_lock;
+ struct mutex xfer_lock;
+ struct mutex irq_lock;
+ u8 version;
+
+ int reset_gpio;
+
+ u32 num_of_supplies;
+ struct regulator_bulk_data *supplies;
+
+ enum msm8x10_wcd_pm_state pm_state;
+ struct mutex pm_lock;
+ /* pm_wq notifies change of pm_state */
+ wait_queue_head_t pm_wq;
+ struct pm_qos_request pm_qos_req;
+ int wlock_holders;
+
+ u8 idbyte[4];
+
+ unsigned int irq_base;
+ unsigned int irq;
+ u8 irq_masks_cur[MSM8X10_WCD_NUM_IRQ_REGS];
+ u8 irq_masks_cache[MSM8X10_WCD_NUM_IRQ_REGS];
+ bool irq_level_high[MSM8X10_WCD_NUM_IRQS];
+ int num_irqs;
+ u32 mclk_rate;
+};
+
+extern int msm8x10_wcd_mclk_enable(struct snd_soc_codec *codec, int mclk_enable,
+ bool dapm);
+extern int msm8x10_wcd_hs_detect(struct snd_soc_codec *codec,
+ struct msm8x10_wcd_mbhc_config *mbhc_cfg);
+
+#endif
diff --git a/sound/soc/codecs/msm8x10_wcd_registers.h b/sound/soc/codecs/msm8x10_wcd_registers.h
new file mode 100644
index 0000000..684c402
--- /dev/null
+++ b/sound/soc/codecs/msm8x10_wcd_registers.h
@@ -0,0 +1,637 @@
+ /* Copyright (c) 2013, 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.
+ */
+#define MSM8X10_WCD_A_CHIP_CTL (0x000)
+#define MSM8X10_WCD_A_CHIP_CTL__POR (0x04)
+#define MSM8X10_WCD_A_CHIP_STATUS (0x001)
+#define MSM8X10_WCD_A_CHIP_STATUS__POR (0x00)
+#define MSM8X10_WCD_A_CDC_TLMM_MODE_SELECT (0x002)
+#define MSM8X10_WCD_A_CDC_TLMM_MODE_SELECT__POR (0x00)
+#define MSM8X10_WCD_A_MODE_LOCK (0x003)
+#define MSM8X10_WCD_A_MODE_LOCK__POR (0x00)
+#define MSM8X10_WCD_A_CHIP_ID_BYTE_0 (0x004)
+#define MSM8X10_WCD_A_CHIP_ID_BYTE_0__POR (0x00)
+#define MSM8X10_WCD_A_CHIP_ID_BYTE_1 (0x005)
+#define MSM8X10_WCD_A_CHIP_ID_BYTE_1__POR (0x00)
+#define MSM8X10_WCD_A_CHIP_ID_BYTE_2 (0x006)
+#define MSM8X10_WCD_A_CHIP_ID_BYTE_2__POR (0x04)
+#define MSM8X10_WCD_A_CHIP_ID_BYTE_3 (0x007)
+#define MSM8X10_WCD_A_CHIP_ID_BYTE_3__POR (0x01)
+#define MSM8X10_WCD_A_CHIP_VERSION (0x008)
+#define MSM8X10_WCD_A_CHIP_VERSION__POR (0x00)
+#define MSM8X10_WCD_A_ANALOG_SLAVE_ID (0x00C)
+#define MSM8X10_WCD_A_ANALOG_SLAVE_ID__POR (0x77)
+#define MSM8X10_WCD_A_PIN_CTL_OE (0x010)
+#define MSM8X10_WCD_A_PIN_CTL_OE__POR (0x07)
+#define MSM8X10_WCD_A_PIN_CTL_DATA (0x012)
+#define MSM8X10_WCD_A_PIN_CTL_DATA__POR (0x00)
+#define MSM8X10_WCD_A_PIN_STATUS (0x014)
+#define MSM8X10_WCD_A_PIN_STATUS__POR (0x00)
+#define MSM8X10_WCD_A_HDRIVE_CTL (0x018)
+#define MSM8X10_WCD_A_HDRIVE_CTL__POR (0x01)
+#define MSM8X10_WCD_A_HDRIVE_I2C_CTL (0x019)
+#define MSM8X10_WCD_A_HDRIVE_I2C_CTL__POR (0x01)
+#define MSM8X10_WCD_A_CDC_RST_CTL (0x020)
+#define MSM8X10_WCD_A_CDC_RST_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_TOP_CLK_CTL (0x022)
+#define MSM8X10_WCD_A_CDC_TOP_CLK_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_ANA_CLK_CTL (0x023)
+#define MSM8X10_WCD_A_CDC_ANA_CLK_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_DIG_CLK_CTL (0x024)
+#define MSM8X10_WCD_A_CDC_DIG_CLK_CTL__POR (0x00)
+#define MSM8X10_WCD_A_PROCESS_MONITOR_CTL0 (0x030)
+#define MSM8X10_WCD_A_PROCESS_MONITOR_CTL0__POR (0x80)
+#define MSM8X10_WCD_A_PROCESS_MONITOR_CTL1 (0x031)
+#define MSM8X10_WCD_A_PROCESS_MONITOR_CTL1__POR (0x00)
+#define MSM8X10_WCD_A_PROCESS_MONITOR_CTL2 (0x032)
+#define MSM8X10_WCD_A_PROCESS_MONITOR_CTL2__POR (0x00)
+#define MSM8X10_WCD_A_PROCESS_MONITOR_CTL3 (0x033)
+#define MSM8X10_WCD_A_PROCESS_MONITOR_CTL3__POR (0x01)
+#define MSM8X10_WCD_A_QFUSE_CTL (0x034)
+#define MSM8X10_WCD_A_QFUSE_CTL__POR (0x00)
+#define MSM8X10_WCD_A_QFUSE_STATUS (0x035)
+#define MSM8X10_WCD_A_QFUSE_STATUS__POR (0x00)
+#define MSM8X10_WCD_A_QFUSE_DATA_OUT0 (0x036)
+#define MSM8X10_WCD_A_QFUSE_DATA_OUT0__POR (0x00)
+#define MSM8X10_WCD_A_QFUSE_DATA_OUT1 (0x037)
+#define MSM8X10_WCD_A_QFUSE_DATA_OUT1__POR (0x00)
+#define MSM8X10_WCD_A_QFUSE_DATA_OUT2 (0x038)
+#define MSM8X10_WCD_A_QFUSE_DATA_OUT2__POR (0x00)
+#define MSM8X10_WCD_A_QFUSE_DATA_OUT3 (0x039)
+#define MSM8X10_WCD_A_QFUSE_DATA_OUT3__POR (0x00)
+#define MSM8X10_WCD_A_CDC_CONN_TX1_CTL (0x040)
+#define MSM8X10_WCD_A_CDC_CONN_TX1_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_CONN_TX2_CTL (0x041)
+#define MSM8X10_WCD_A_CDC_CONN_TX2_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_CONN_HPHR_DAC_CTL (0x042)
+#define MSM8X10_WCD_A_CDC_CONN_HPHR_DAC_CTL__POR (0x01)
+#define MSM8X10_WCD_A_CDC_CONN_LO_DAC_CTL (0x043)
+#define MSM8X10_WCD_A_CDC_CONN_LO_DAC_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_CONN_RX1_CTL (0x044)
+#define MSM8X10_WCD_A_CDC_CONN_RX1_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_CONN_RX2_CTL (0x045)
+#define MSM8X10_WCD_A_CDC_CONN_RX2_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_CONN_RX3_CTL (0x046)
+#define MSM8X10_WCD_A_CDC_CONN_RX3_CTL__POR (0x00)
+#define MSM8X10_WCD_A_DIGITAL_DEBUG_CTL (0x048)
+#define MSM8X10_WCD_A_DIGITAL_DEBUG_CTL__POR (0x00)
+#define MSM8X10_WCD_A_ANALOG_DEBUG_CTL (0x049)
+#define MSM8X10_WCD_A_ANALOG_DEBUG_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_RX1_CTL (0x050)
+#define MSM8X10_WCD_A_CDC_RX1_CTL__POR (0x7C)
+#define MSM8X10_WCD_A_CDC_RX2_CTL (0x058)
+#define MSM8X10_WCD_A_CDC_RX2_CTL__POR (0x7C)
+#define MSM8X10_WCD_A_CDC_RX3_CTL (0x060)
+#define MSM8X10_WCD_A_CDC_RX3_CTL__POR (0x7C)
+#define MSM8X10_WCD_A_DEM_BYPASS_DATA0 (0x070)
+#define MSM8X10_WCD_A_DEM_BYPASS_DATA0__POR (0x00)
+#define MSM8X10_WCD_A_DEM_BYPASS_DATA1 (0x071)
+#define MSM8X10_WCD_A_DEM_BYPASS_DATA1__POR (0x00)
+#define MSM8X10_WCD_A_DEM_BYPASS_DATA2 (0x072)
+#define MSM8X10_WCD_A_DEM_BYPASS_DATA2__POR (0x00)
+#define MSM8X10_WCD_A_DEM_BYPASS_DATA3 (0x073)
+#define MSM8X10_WCD_A_DEM_BYPASS_DATA3__POR (0x00)
+#define MSM8X10_WCD_A_SPARE_0 (0x080)
+#define MSM8X10_WCD_A_SPARE_0__POR (0x00)
+#define MSM8X10_WCD_A_SPARE_1 (0x082)
+#define MSM8X10_WCD_A_SPARE_1__POR (0x00)
+#define MSM8X10_WCD_A_SPARE_2 (0x084)
+#define MSM8X10_WCD_A_SPARE_2__POR (0x00)
+#define MSM8X10_WCD_A_INTR_MODE (0x090)
+#define MSM8X10_WCD_A_INTR_MODE__POR (0x00)
+#define MSM8X10_WCD_A_INTR_MASK0 (0x094)
+#define MSM8X10_WCD_A_INTR_MASK0__POR (0xFF)
+#define MSM8X10_WCD_A_INTR_MASK1 (0x095)
+#define MSM8X10_WCD_A_INTR_MASK1__POR (0xFF)
+#define MSM8X10_WCD_A_INTR_MASK2 (0x096)
+#define MSM8X10_WCD_A_INTR_MASK2__POR (0x3F)
+#define MSM8X10_WCD_A_INTR_STATUS0 (0x098)
+#define MSM8X10_WCD_A_INTR_STATUS0__POR (0x00)
+#define MSM8X10_WCD_A_INTR_STATUS1 (0x099)
+#define MSM8X10_WCD_A_INTR_STATUS1__POR (0x00)
+#define MSM8X10_WCD_A_INTR_STATUS2 (0x09A)
+#define MSM8X10_WCD_A_INTR_STATUS2__POR (0x00)
+#define MSM8X10_WCD_A_INTR_CLEAR0 (0x09C)
+#define MSM8X10_WCD_A_INTR_CLEAR0__POR (0x00)
+#define MSM8X10_WCD_A_INTR_CLEAR1 (0x09D)
+#define MSM8X10_WCD_A_INTR_CLEAR1__POR (0x00)
+#define MSM8X10_WCD_A_INTR_CLEAR2 (0x09E)
+#define MSM8X10_WCD_A_INTR_CLEAR2__POR (0x00)
+#define MSM8X10_WCD_A_INTR_TEST0 (0x0A4)
+#define MSM8X10_WCD_A_INTR_TEST0__POR (0x00)
+#define MSM8X10_WCD_A_INTR_TEST1 (0x0A5)
+#define MSM8X10_WCD_A_INTR_TEST1__POR (0x00)
+#define MSM8X10_WCD_A_INTR_TEST2 (0x0A6)
+#define MSM8X10_WCD_A_INTR_TEST2__POR (0x00)
+#define MSM8X10_WCD_A_INTR_SET0 (0x0A8)
+#define MSM8X10_WCD_A_INTR_SET0__POR (0x00)
+#define MSM8X10_WCD_A_INTR_SET1 (0x0A9)
+#define MSM8X10_WCD_A_INTR_SET1__POR (0x00)
+#define MSM8X10_WCD_A_INTR_SET2 (0x0AA)
+#define MSM8X10_WCD_A_INTR_SET2__POR (0x00)
+#define MSM8X10_WCD_A_CDC_MBHC_EN_CTL (0x0C0)
+#define MSM8X10_WCD_A_CDC_MBHC_EN_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_MBHC_FIR_B1_CFG (0x0C1)
+#define MSM8X10_WCD_A_CDC_MBHC_FIR_B1_CFG__POR (0x00)
+#define MSM8X10_WCD_A_CDC_MBHC_FIR_B2_CFG (0x0C2)
+#define MSM8X10_WCD_A_CDC_MBHC_FIR_B2_CFG__POR (0x06)
+#define MSM8X10_WCD_A_CDC_MBHC_TIMER_B1_CTL (0x0C3)
+#define MSM8X10_WCD_A_CDC_MBHC_TIMER_B1_CTL__POR (0x03)
+#define MSM8X10_WCD_A_CDC_MBHC_TIMER_B2_CTL (0x0C4)
+#define MSM8X10_WCD_A_CDC_MBHC_TIMER_B2_CTL__POR (0x09)
+#define MSM8X10_WCD_A_CDC_MBHC_TIMER_B3_CTL (0x0C5)
+#define MSM8X10_WCD_A_CDC_MBHC_TIMER_B3_CTL__POR (0x1E)
+#define MSM8X10_WCD_A_CDC_MBHC_TIMER_B4_CTL (0x0C6)
+#define MSM8X10_WCD_A_CDC_MBHC_TIMER_B4_CTL__POR (0x45)
+#define MSM8X10_WCD_A_CDC_MBHC_TIMER_B5_CTL (0x0C7)
+#define MSM8X10_WCD_A_CDC_MBHC_TIMER_B5_CTL__POR (0x04)
+#define MSM8X10_WCD_A_CDC_MBHC_TIMER_B6_CTL (0x0C8)
+#define MSM8X10_WCD_A_CDC_MBHC_TIMER_B6_CTL__POR (0x78)
+#define MSM8X10_WCD_A_CDC_MBHC_B1_STATUS (0x0C9)
+#define MSM8X10_WCD_A_CDC_MBHC_B1_STATUS__POR (0x00)
+#define MSM8X10_WCD_A_CDC_MBHC_B2_STATUS (0x0CA)
+#define MSM8X10_WCD_A_CDC_MBHC_B2_STATUS__POR (0x00)
+#define MSM8X10_WCD_A_CDC_MBHC_B3_STATUS (0x0CB)
+#define MSM8X10_WCD_A_CDC_MBHC_B3_STATUS__POR (0x00)
+#define MSM8X10_WCD_A_CDC_MBHC_B4_STATUS (0x0CC)
+#define MSM8X10_WCD_A_CDC_MBHC_B4_STATUS__POR (0x00)
+#define MSM8X10_WCD_A_CDC_MBHC_B5_STATUS (0x0CD)
+#define MSM8X10_WCD_A_CDC_MBHC_B5_STATUS__POR (0x00)
+#define MSM8X10_WCD_A_CDC_MBHC_B1_CTL (0x0CE)
+#define MSM8X10_WCD_A_CDC_MBHC_B1_CTL__POR (0xC0)
+#define MSM8X10_WCD_A_CDC_MBHC_B2_CTL (0x0CF)
+#define MSM8X10_WCD_A_CDC_MBHC_B2_CTL__POR (0x5D)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B1_CTL (0x0D0)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B1_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B2_CTL (0x0D1)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B2_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B3_CTL (0x0D2)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B3_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B4_CTL (0x0D3)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B4_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B5_CTL (0x0D4)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B5_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B6_CTL (0x0D5)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B6_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B7_CTL (0x0D6)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B7_CTL__POR (0xFF)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B8_CTL (0x0D7)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B8_CTL__POR (0x07)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B9_CTL (0x0D8)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B9_CTL__POR (0xFF)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B10_CTL (0x0D9)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B10_CTL__POR (0x7F)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B11_CTL (0x0DA)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B11_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B12_CTL (0x0DB)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B12_CTL__POR (0x80)
+#define MSM8X10_WCD_A_CDC_MBHC_CLK_CTL (0x0DC)
+#define MSM8X10_WCD_A_CDC_MBHC_CLK_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_MBHC_INT_CTL (0x0DD)
+#define MSM8X10_WCD_A_CDC_MBHC_INT_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_MBHC_DEBUG_CTL (0x0DE)
+#define MSM8X10_WCD_A_CDC_MBHC_DEBUG_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_MBHC_SPARE (0x0DF)
+#define MSM8X10_WCD_A_CDC_MBHC_SPARE__POR (0x00)
+#define MSM8X10_WCD_A_BIAS_REF_CTL (0x100)
+#define MSM8X10_WCD_A_BIAS_REF_CTL__POR (0x1C)
+#define MSM8X10_WCD_A_BIAS_CENTRAL_BG_CTL (0x101)
+#define MSM8X10_WCD_A_BIAS_CENTRAL_BG_CTL__POR (0x50)
+#define MSM8X10_WCD_A_BIAS_PRECHRG_CTL (0x102)
+#define MSM8X10_WCD_A_BIAS_PRECHRG_CTL__POR (0x07)
+#define MSM8X10_WCD_A_BIAS_CURR_CTL_1 (0x103)
+#define MSM8X10_WCD_A_BIAS_CURR_CTL_1__POR (0x52)
+#define MSM8X10_WCD_A_BIAS_CURR_CTL_2 (0x104)
+#define MSM8X10_WCD_A_BIAS_CURR_CTL_2__POR (0x00)
+#define MSM8X10_WCD_A_BIAS_OSC_BG_CTL (0x105)
+#define MSM8X10_WCD_A_BIAS_OSC_BG_CTL__POR (0x16)
+#define MSM8X10_WCD_A_MICB_CFILT_1_CTL (0x128)
+#define MSM8X10_WCD_A_MICB_CFILT_1_CTL__POR (0x40)
+#define MSM8X10_WCD_A_MICB_CFILT_1_VAL (0x129)
+#define MSM8X10_WCD_A_MICB_CFILT_1_VAL__POR (0x80)
+#define MSM8X10_WCD_A_MICB_CFILT_1_PRECHRG (0x12A)
+#define MSM8X10_WCD_A_MICB_CFILT_1_PRECHRG__POR (0x00)
+#define MSM8X10_WCD_A_MICB_1_CTL (0x12B)
+#define MSM8X10_WCD_A_MICB_1_CTL__POR (0x02)
+#define MSM8X10_WCD_A_MICB_1_INT_RBIAS (0x12C)
+#define MSM8X10_WCD_A_MICB_1_INT_RBIAS__POR (0x00)
+#define MSM8X10_WCD_A_MICB_1_MBHC (0x12D)
+#define MSM8X10_WCD_A_MICB_1_MBHC__POR (0x00)
+#define MSM8X10_WCD_A_MBHC_INSERT_DETECT (0x14A)
+#define MSM8X10_WCD_A_MBHC_INSERT_DETECT__POR (0x00)
+#define MSM8X10_WCD_A_MBHC_INSERT_DET_STATUS (0x14B)
+#define MSM8X10_WCD_A_MBHC_INSERT_DET_STATUS__POR (0x00)
+#define MSM8X10_WCD_A_TX_COM_BIAS (0x14C)
+#define MSM8X10_WCD_A_TX_COM_BIAS__POR (0xF0)
+#define MSM8X10_WCD_A_MBHC_SCALING_MUX_1 (0x14E)
+#define MSM8X10_WCD_A_MBHC_SCALING_MUX_1__POR (0x00)
+#define MSM8X10_WCD_A_MBHC_SCALING_MUX_2 (0x14F)
+#define MSM8X10_WCD_A_MBHC_SCALING_MUX_2__POR (0x80)
+#define MSM8X10_WCD_A_RESERVED_MAD_ANA_CTRL (0x150)
+#define MSM8X10_WCD_A_RESERVED_MAD_ANA_CTRL__POR (0xF1)
+#define MSM8X10_WCD_A_TX_SUP_SWITCH_CTRL_1 (0x151)
+#define MSM8X10_WCD_A_TX_SUP_SWITCH_CTRL_1__POR (0x00)
+#define MSM8X10_WCD_A_TX_SUP_SWITCH_CTRL_2 (0x152)
+#define MSM8X10_WCD_A_TX_SUP_SWITCH_CTRL_2__POR (0x80)
+#define MSM8X10_WCD_A_TX_1_EN (0x153)
+#define MSM8X10_WCD_A_TX_1_EN__POR (0x02)
+#define MSM8X10_WCD_A_TX_2_EN (0x154)
+#define MSM8X10_WCD_A_TX_2_EN__POR (0x02)
+#define MSM8X10_WCD_A_TX_1_2_ADC_CH1 (0x155)
+#define MSM8X10_WCD_A_TX_1_2_ADC_CH1__POR (0x44)
+#define MSM8X10_WCD_A_TX_1_2_ADC_CH2 (0x156)
+#define MSM8X10_WCD_A_TX_1_2_ADC_CH2__POR (0x44)
+#define MSM8X10_WCD_A_TX_1_2_ATEST_REFCTRL (0x157)
+#define MSM8X10_WCD_A_TX_1_2_ATEST_REFCTRL__POR (0x00)
+#define MSM8X10_WCD_A_TX_1_2_TEST_CTL (0x158)
+#define MSM8X10_WCD_A_TX_1_2_TEST_CTL__POR (0x38)
+#define MSM8X10_WCD_A_TX_1_2_TEST_BLOCK_EN (0x159)
+#define MSM8X10_WCD_A_TX_1_2_TEST_BLOCK_EN__POR (0xFC)
+#define MSM8X10_WCD_A_TX_1_2_TXFE_CLKDIV (0x15A)
+#define MSM8X10_WCD_A_TX_1_2_TXFE_CLKDIV__POR (0x55)
+#define MSM8X10_WCD_A_TX_1_2_SAR_ERR_CH1 (0x15B)
+#define MSM8X10_WCD_A_TX_1_2_SAR_ERR_CH1__POR (0x00)
+#define MSM8X10_WCD_A_TX_1_2_SAR_ERR_CH2 (0x15C)
+#define MSM8X10_WCD_A_TX_1_2_SAR_ERR_CH2__POR (0x00)
+#define MSM8X10_WCD_A_TX_3_EN (0x15D)
+#define MSM8X10_WCD_A_TX_3_EN__POR (0x00)
+#define MSM8X10_WCD_A_TX_1_2_TEST_EN (0x15E)
+#define MSM8X10_WCD_A_TX_1_2_TEST_EN__POR (0xCC)
+#define MSM8X10_WCD_A_TX_7_MBHC_EN_ATEST_CTRL (0x171)
+#define MSM8X10_WCD_A_TX_7_MBHC_EN_ATEST_CTRL__POR (0x10)
+#define MSM8X10_WCD_A_TX_7_MBHC_SAR_ERR (0x175)
+#define MSM8X10_WCD_A_TX_7_MBHC_SAR_ERR__POR (0x00)
+#define MSM8X10_WCD_A_CP_EN (0x192)
+#define MSM8X10_WCD_A_CP_EN__POR (0xE6)
+#define MSM8X10_WCD_A_CP_CLK (0x193)
+#define MSM8X10_WCD_A_CP_CLK__POR (0x29)
+#define MSM8X10_WCD_A_CP_STATIC (0x194)
+#define MSM8X10_WCD_A_CP_STATIC__POR (0x10)
+#define MSM8X10_WCD_A_CP_DCC1 (0x195)
+#define MSM8X10_WCD_A_CP_DCC1__POR (0x52)
+#define MSM8X10_WCD_A_CP_DCC3 (0x196)
+#define MSM8X10_WCD_A_CP_DCC3__POR (0x01)
+#define MSM8X10_WCD_A_CP_ATEST (0x197)
+#define MSM8X10_WCD_A_CP_ATEST__POR (0x00)
+#define MSM8X10_WCD_A_CP_DTEST (0x198)
+#define MSM8X10_WCD_A_CP_DTEST__POR (0x00)
+#define MSM8X10_WCD_A_RX_AUX_SW_CTL (0x19B)
+#define MSM8X10_WCD_A_RX_AUX_SW_CTL__POR (0x00)
+#define MSM8X10_WCD_A_RX_PA_AUX_IN_CONN (0x19C)
+#define MSM8X10_WCD_A_RX_PA_AUX_IN_CONN__POR (0x00)
+#define MSM8X10_WCD_A_RX_COM_TIMER_DIV (0x19E)
+#define MSM8X10_WCD_A_RX_COM_TIMER_DIV__POR (0xE8)
+#define MSM8X10_WCD_A_RX_COM_OCP_CTL (0x19F)
+#define MSM8X10_WCD_A_RX_COM_OCP_CTL__POR (0x1F)
+#define MSM8X10_WCD_A_RX_COM_OCP_COUNT (0x1A0)
+#define MSM8X10_WCD_A_RX_COM_OCP_COUNT__POR (0x77)
+#define MSM8X10_WCD_A_RX_COM_DAC_CTL (0x1A1)
+#define MSM8X10_WCD_A_RX_COM_DAC_CTL__POR (0x00)
+#define MSM8X10_WCD_A_RX_COM_BIAS (0x1A2)
+#define MSM8X10_WCD_A_RX_COM_BIAS__POR (0x00)
+#define MSM8X10_WCD_A_RX_HPH_AUTO_CHOP (0x1A4)
+#define MSM8X10_WCD_A_RX_HPH_AUTO_CHOP__POR (0x38)
+#define MSM8X10_WCD_A_RX_HPH_CHOP_CTL (0x1A5)
+#define MSM8X10_WCD_A_RX_HPH_CHOP_CTL__POR (0x34)
+#define MSM8X10_WCD_A_RX_HPH_BIAS_PA (0x1A6)
+#define MSM8X10_WCD_A_RX_HPH_BIAS_PA__POR (0x5A)
+#define MSM8X10_WCD_A_RX_HPH_BIAS_LDO (0x1A7)
+#define MSM8X10_WCD_A_RX_HPH_BIAS_LDO__POR (0x87)
+#define MSM8X10_WCD_A_RX_HPH_BIAS_CNP (0x1A8)
+#define MSM8X10_WCD_A_RX_HPH_BIAS_CNP__POR (0x8A)
+#define MSM8X10_WCD_A_RX_HPH_BIAS_WG_OCP (0x1A9)
+#define MSM8X10_WCD_A_RX_HPH_BIAS_WG_OCP__POR (0x2A)
+#define MSM8X10_WCD_A_RX_HPH_OCP_CTL (0x1AA)
+#define MSM8X10_WCD_A_RX_HPH_OCP_CTL__POR (0x69)
+#define MSM8X10_WCD_A_RX_HPH_CNP_EN (0x1AB)
+#define MSM8X10_WCD_A_RX_HPH_CNP_EN__POR (0x80)
+#define MSM8X10_WCD_A_RX_HPH_CNP_WG_CTL (0x1AC)
+#define MSM8X10_WCD_A_RX_HPH_CNP_WG_CTL__POR (0xDE)
+#define MSM8X10_WCD_A_RX_HPH_CNP_WG_TIME (0x1AD)
+#define MSM8X10_WCD_A_RX_HPH_CNP_WG_TIME__POR (0x15)
+#define MSM8X10_WCD_A_RX_HPH_L_GAIN (0x1AE)
+#define MSM8X10_WCD_A_RX_HPH_L_GAIN__POR (0x00)
+#define MSM8X10_WCD_A_RX_HPH_L_TEST (0x1AF)
+#define MSM8X10_WCD_A_RX_HPH_L_TEST__POR (0x00)
+#define MSM8X10_WCD_A_RX_HPH_L_PA_CTL (0x1B0)
+#define MSM8X10_WCD_A_RX_HPH_L_PA_CTL__POR (0x40)
+#define MSM8X10_WCD_A_RX_HPH_L_DAC_CTL (0x1B1)
+#define MSM8X10_WCD_A_RX_HPH_L_DAC_CTL__POR (0x00)
+#define MSM8X10_WCD_A_RX_HPH_L_ATEST (0x1B2)
+#define MSM8X10_WCD_A_RX_HPH_L_ATEST__POR (0x00)
+#define MSM8X10_WCD_A_RX_HPH_L_STATUS (0x1B3)
+#define MSM8X10_WCD_A_RX_HPH_L_STATUS__POR (0x00)
+#define MSM8X10_WCD_A_RX_HPH_R_GAIN (0x1B4)
+#define MSM8X10_WCD_A_RX_HPH_R_GAIN__POR (0x00)
+#define MSM8X10_WCD_A_RX_HPH_R_TEST (0x1B5)
+#define MSM8X10_WCD_A_RX_HPH_R_TEST__POR (0x00)
+#define MSM8X10_WCD_A_RX_HPH_R_PA_CTL (0x1B6)
+#define MSM8X10_WCD_A_RX_HPH_R_PA_CTL__POR (0x40)
+#define MSM8X10_WCD_A_RX_HPH_R_DAC_CTL (0x1B7)
+#define MSM8X10_WCD_A_RX_HPH_R_DAC_CTL__POR (0x00)
+#define MSM8X10_WCD_A_RX_HPH_R_ATEST (0x1B8)
+#define MSM8X10_WCD_A_RX_HPH_R_ATEST__POR (0x00)
+#define MSM8X10_WCD_A_RX_HPH_R_STATUS (0x1B9)
+#define MSM8X10_WCD_A_RX_HPH_R_STATUS__POR (0x00)
+#define MSM8X10_WCD_A_RX_EAR_BIAS_PA (0x1BA)
+#define MSM8X10_WCD_A_RX_EAR_BIAS_PA__POR (0x56)
+#define MSM8X10_WCD_A_RX_EAR_BIAS_CMBUFF (0x1BB)
+#define MSM8X10_WCD_A_RX_EAR_BIAS_CMBUFF__POR (0xA0)
+#define MSM8X10_WCD_A_RX_EAR_EN (0x1BC)
+#define MSM8X10_WCD_A_RX_EAR_EN__POR (0x00)
+#define MSM8X10_WCD_A_RX_EAR_GAIN (0x1BD)
+#define MSM8X10_WCD_A_RX_EAR_GAIN__POR (0x02)
+#define MSM8X10_WCD_A_RX_EAR_CMBUFF (0x1BE)
+#define MSM8X10_WCD_A_RX_EAR_CMBUFF__POR (0x05)
+#define MSM8X10_WCD_A_RX_EAR_ICTL (0x1BF)
+#define MSM8X10_WCD_A_RX_EAR_ICTL__POR (0x40)
+#define MSM8X10_WCD_A_RX_EAR_CCOMP (0x1C0)
+#define MSM8X10_WCD_A_RX_EAR_CCOMP__POR (0x08)
+#define MSM8X10_WCD_A_RX_EAR_VCM (0x1C1)
+#define MSM8X10_WCD_A_RX_EAR_VCM__POR (0x03)
+#define MSM8X10_WCD_A_RX_EAR_CNP (0x1C2)
+#define MSM8X10_WCD_A_RX_EAR_CNP__POR (0xF2)
+#define MSM8X10_WCD_A_RX_EAR_DAC_CTL_ATEST (0x1C3)
+#define MSM8X10_WCD_A_RX_EAR_DAC_CTL_ATEST__POR (0x00)
+#define MSM8X10_WCD_A_RX_EAR_STATUS (0x1C5)
+#define MSM8X10_WCD_A_RX_EAR_STATUS__POR (0x04)
+#define MSM8X10_WCD_A_RX_LINE_BIAS_PA (0x1C6)
+#define MSM8X10_WCD_A_RX_LINE_BIAS_PA__POR (0x58)
+#define MSM8X10_WCD_A_RX_BUCK_BIAS1 (0x1C7)
+#define MSM8X10_WCD_A_RX_BUCK_BIAS1__POR (0x42)
+#define MSM8X10_WCD_A_RX_BUCK_BIAS2 (0x1C8)
+#define MSM8X10_WCD_A_RX_BUCK_BIAS2__POR (0x84)
+#define MSM8X10_WCD_A_RX_LINE_COM (0x1C9)
+#define MSM8X10_WCD_A_RX_LINE_COM__POR (0x80)
+#define MSM8X10_WCD_A_RX_LINE_CNP_EN (0x1CA)
+#define MSM8X10_WCD_A_RX_LINE_CNP_EN__POR (0x00)
+#define MSM8X10_WCD_A_RX_LINE_CNP_WG_CTL (0x1CB)
+#define MSM8X10_WCD_A_RX_LINE_CNP_WG_CTL__POR (0x00)
+#define MSM8X10_WCD_A_RX_LINE_CNP_WG_TIME (0x1CC)
+#define MSM8X10_WCD_A_RX_LINE_CNP_WG_TIME__POR (0x04)
+#define MSM8X10_WCD_A_RX_LINE_1_GAIN (0x1CD)
+#define MSM8X10_WCD_A_RX_LINE_1_GAIN__POR (0x00)
+#define MSM8X10_WCD_A_RX_LINE_1_TEST (0x1CE)
+#define MSM8X10_WCD_A_RX_LINE_1_TEST__POR (0x00)
+#define MSM8X10_WCD_A_RX_LINE_1_DAC_CTL (0x1CF)
+#define MSM8X10_WCD_A_RX_LINE_1_DAC_CTL__POR (0x00)
+#define MSM8X10_WCD_A_RX_LINE_1_STATUS (0x1D0)
+#define MSM8X10_WCD_A_RX_LINE_1_STATUS__POR (0x00)
+#define MSM8X10_WCD_A_RX_LINE_CNP_DBG (0x1DD)
+#define MSM8X10_WCD_A_RX_LINE_CNP_DBG__POR (0x00)
+#define MSM8X10_WCD_A_SPKR_DRV_EN (0x1DF)
+#define MSM8X10_WCD_A_SPKR_DRV_EN__POR (0x6F)
+#define MSM8X10_WCD_A_SPKR_DRV_GAIN (0x1E0)
+#define MSM8X10_WCD_A_SPKR_DRV_GAIN__POR (0x00)
+#define MSM8X10_WCD_A_SPKR_DRV_DAC_CTL (0x1E1)
+#define MSM8X10_WCD_A_SPKR_DRV_DAC_CTL__POR (0x04)
+#define MSM8X10_WCD_A_SPKR_DRV_OCP_CTL (0x1E2)
+#define MSM8X10_WCD_A_SPKR_DRV_OCP_CTL__POR (0x98)
+#define MSM8X10_WCD_A_SPKR_DRV_CLIP_DET (0x1E3)
+#define MSM8X10_WCD_A_SPKR_DRV_CLIP_DET__POR (0x01)
+#define MSM8X10_WCD_A_SPKR_DRV_IEC (0x1E4)
+#define MSM8X10_WCD_A_SPKR_DRV_IEC__POR (0x00)
+#define MSM8X10_WCD_A_SPKR_DRV_DBG_DAC (0x1E5)
+#define MSM8X10_WCD_A_SPKR_DRV_DBG_DAC__POR (0x05)
+#define MSM8X10_WCD_A_SPKR_DRV_DBG_PA (0x1E6)
+#define MSM8X10_WCD_A_SPKR_DRV_DBG_PA__POR (0x18)
+#define MSM8X10_WCD_A_SPKR_DRV_DBG_PWRSTG (0x1E7)
+#define MSM8X10_WCD_A_SPKR_DRV_DBG_PWRSTG__POR (0x00)
+#define MSM8X10_WCD_A_SPKR_DRV_BIAS_LDO (0x1E8)
+#define MSM8X10_WCD_A_SPKR_DRV_BIAS_LDO__POR (0x45)
+#define MSM8X10_WCD_A_SPKR_DRV_BIAS_INT (0x1E9)
+#define MSM8X10_WCD_A_SPKR_DRV_BIAS_INT__POR (0xA5)
+#define MSM8X10_WCD_A_SPKR_DRV_BIAS_PA (0x1EA)
+#define MSM8X10_WCD_A_SPKR_DRV_BIAS_PA__POR (0x55)
+#define MSM8X10_WCD_A_SPKR_DRV_STATUS_OCP (0x1EB)
+#define MSM8X10_WCD_A_SPKR_DRV_STATUS_OCP__POR (0x00)
+#define MSM8X10_WCD_A_SPKR_DRV_STATUS_PA (0x1EC)
+#define MSM8X10_WCD_A_SPKR_DRV_STATUS_PA__POR (0x00)
+#define MSM8X10_WCD_A_RC_OSC_FREQ (0x1FA)
+#define MSM8X10_WCD_A_RC_OSC_FREQ__POR (0x46)
+#define MSM8X10_WCD_A_RC_OSC_TEST (0x1FB)
+#define MSM8X10_WCD_A_RC_OSC_TEST__POR (0x0A)
+#define MSM8X10_WCD_A_RC_OSC_STATUS (0x1FC)
+#define MSM8X10_WCD_A_RC_OSC_STATUS__POR (0x18)
+#define MSM8X10_WCD_A_RC_OSC_TUNER (0x1FD)
+#define MSM8X10_WCD_A_RC_OSC_TUNER__POR (0x00)
+#define MSM8X10_WCD_A_MBHC_HPH (0x1FE)
+#define MSM8X10_WCD_A_MBHC_HPH__POR (0x44)
+#define MSM8X10_WCD_A_CDC_CLK_RX_RESET_CTL (0x400)
+#define MSM8X10_WCD_A_CDC_CLK_RX_RESET_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_CLK_TX_RESET_B1_CTL (0x404)
+#define MSM8X10_WCD_A_CDC_CLK_TX_RESET_B1_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_CLK_DMIC_B1_CTL (0x408)
+#define MSM8X10_WCD_A_CDC_CLK_DMIC_B1_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_CLK_RX_I2S_CTL (0x40C)
+#define MSM8X10_WCD_A_CDC_CLK_RX_I2S_CTL__POR (0x10)
+#define MSM8X10_WCD_A_CDC_CLK_TX_I2S_CTL (0x410)
+#define MSM8X10_WCD_A_CDC_CLK_TX_I2S_CTL__POR (0x10)
+#define MSM8X10_WCD_A_CDC_CLK_OTHR_RESET_B1_CTL (0x414)
+#define MSM8X10_WCD_A_CDC_CLK_OTHR_RESET_B1_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_CLK_TX_CLK_EN_B1_CTL (0x418)
+#define MSM8X10_WCD_A_CDC_CLK_TX_CLK_EN_B1_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_CLK_OTHR_CTL (0x41C)
+#define MSM8X10_WCD_A_CDC_CLK_OTHR_CTL__POR (0x04)
+#define MSM8X10_WCD_A_CDC_CLK_RX_B1_CTL (0x420)
+#define MSM8X10_WCD_A_CDC_CLK_RX_B1_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_CLK_MCLK_CTL (0x424)
+#define MSM8X10_WCD_A_CDC_CLK_MCLK_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_CLK_PDM_CTL (0x428)
+#define MSM8X10_WCD_A_CDC_CLK_PDM_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_CLK_SD_CTL (0x42C)
+#define MSM8X10_WCD_A_CDC_CLK_SD_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_RX1_B1_CTL (0x440)
+#define MSM8X10_WCD_A_CDC_RX1_B1_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_RX2_B1_CTL (0x460)
+#define MSM8X10_WCD_A_CDC_RX2_B1_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_RX3_B1_CTL (0x480)
+#define MSM8X10_WCD_A_CDC_RX3_B1_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_RX1_B2_CTL (0x444)
+#define MSM8X10_WCD_A_CDC_RX1_B2_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_RX2_B2_CTL (0x464)
+#define MSM8X10_WCD_A_CDC_RX2_B2_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_RX3_B2_CTL (0x484)
+#define MSM8X10_WCD_A_CDC_RX3_B2_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_RX1_B3_CTL (0x448)
+#define MSM8X10_WCD_A_CDC_RX1_B3_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_RX2_B3_CTL (0x468)
+#define MSM8X10_WCD_A_CDC_RX2_B3_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_RX3_B3_CTL (0x488)
+#define MSM8X10_WCD_A_CDC_RX3_B3_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_RX1_B4_CTL (0x44C)
+#define MSM8X10_WCD_A_CDC_RX1_B4_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_RX2_B4_CTL (0x46C)
+#define MSM8X10_WCD_A_CDC_RX2_B4_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_RX3_B4_CTL (0x48C)
+#define MSM8X10_WCD_A_CDC_RX3_B4_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_RX1_B5_CTL (0x450)
+#define MSM8X10_WCD_A_CDC_RX1_B5_CTL__POR (0x68)
+#define MSM8X10_WCD_A_CDC_RX2_B5_CTL (0x470)
+#define MSM8X10_WCD_A_CDC_RX2_B5_CTL__POR (0x68)
+#define MSM8X10_WCD_A_CDC_RX3_B5_CTL (0x490)
+#define MSM8X10_WCD_A_CDC_RX3_B5_CTL__POR (0x68)
+#define MSM8X10_WCD_A_CDC_RX1_B6_CTL (0x454)
+#define MSM8X10_WCD_A_CDC_RX1_B6_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_RX2_B6_CTL (0x474)
+#define MSM8X10_WCD_A_CDC_RX2_B6_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_RX3_B6_CTL (0x494)
+#define MSM8X10_WCD_A_CDC_RX3_B6_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_RX1_VOL_CTL_B1_CTL (0x458)
+#define MSM8X10_WCD_A_CDC_RX1_VOL_CTL_B1_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_RX2_VOL_CTL_B1_CTL (0x478)
+#define MSM8X10_WCD_A_CDC_RX2_VOL_CTL_B1_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_RX3_VOL_CTL_B1_CTL (0x498)
+#define MSM8X10_WCD_A_CDC_RX3_VOL_CTL_B1_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_RX1_VOL_CTL_B2_CTL (0x45C)
+#define MSM8X10_WCD_A_CDC_RX1_VOL_CTL_B2_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_RX2_VOL_CTL_B2_CTL (0x47C)
+#define MSM8X10_WCD_A_CDC_RX2_VOL_CTL_B2_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_RX3_VOL_CTL_B2_CTL (0x49C)
+#define MSM8X10_WCD_A_CDC_RX3_VOL_CTL_B2_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B1_CTL (0x4A0)
+#define MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B1_CTL__POR (0x07)
+#define MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B2_CTL (0x4A4)
+#define MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B2_CTL__POR (0x13)
+#define MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B3_CTL (0x4A8)
+#define MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B3_CTL__POR (0x1B)
+#define MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B4_CTL (0x4AC)
+#define MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B4_CTL__POR (0x7F)
+#define MSM8X10_WCD_A_CDC_CLSG_GAIN_THRESH_CTL (0x4B0)
+#define MSM8X10_WCD_A_CDC_CLSG_GAIN_THRESH_CTL__POR (0x26)
+#define MSM8X10_WCD_A_CDC_CLSG_TIMER_B1_CFG (0x4B4)
+#define MSM8X10_WCD_A_CDC_CLSG_TIMER_B1_CFG__POR (0x0A)
+#define MSM8X10_WCD_A_CDC_CLSG_TIMER_B2_CFG (0x4B8)
+#define MSM8X10_WCD_A_CDC_CLSG_TIMER_B2_CFG__POR (0x00)
+#define MSM8X10_WCD_A_CDC_CLSG_CTL (0x4BC)
+#define MSM8X10_WCD_A_CDC_CLSG_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_TX1_VOL_CTL_TIMER (0x4C0)
+#define MSM8X10_WCD_A_CDC_TX1_VOL_CTL_TIMER__POR (0x00)
+#define MSM8X10_WCD_A_CDC_TX2_VOL_CTL_TIMER (0x4E0)
+#define MSM8X10_WCD_A_CDC_TX2_VOL_CTL_TIMER__POR (0x00)
+#define MSM8X10_WCD_A_CDC_TX1_VOL_CTL_GAIN (0x4C4)
+#define MSM8X10_WCD_A_CDC_TX1_VOL_CTL_GAIN__POR (0x00)
+#define MSM8X10_WCD_A_CDC_TX2_VOL_CTL_GAIN (0x4E4)
+#define MSM8X10_WCD_A_CDC_TX2_VOL_CTL_GAIN__POR (0x00)
+#define MSM8X10_WCD_A_CDC_TX1_VOL_CTL_CFG (0x4C8)
+#define MSM8X10_WCD_A_CDC_TX1_VOL_CTL_CFG__POR (0x00)
+#define MSM8X10_WCD_A_CDC_TX2_VOL_CTL_CFG (0x4E8)
+#define MSM8X10_WCD_A_CDC_TX2_VOL_CTL_CFG__POR (0x00)
+#define MSM8X10_WCD_A_CDC_TX1_MUX_CTL (0x4CC)
+#define MSM8X10_WCD_A_CDC_TX1_MUX_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_TX2_MUX_CTL (0x4EC)
+#define MSM8X10_WCD_A_CDC_TX2_MUX_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_TX1_CLK_FS_CTL (0x4D0)
+#define MSM8X10_WCD_A_CDC_TX1_CLK_FS_CTL__POR (0x03)
+#define MSM8X10_WCD_A_CDC_TX2_CLK_FS_CTL (0x4F0)
+#define MSM8X10_WCD_A_CDC_TX2_CLK_FS_CTL__POR (0x03)
+#define MSM8X10_WCD_A_CDC_TX1_DMIC_CTL (0x4D4)
+#define MSM8X10_WCD_A_CDC_TX1_DMIC_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_TX2_DMIC_CTL (0x4F4)
+#define MSM8X10_WCD_A_CDC_TX2_DMIC_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_IIR1_GAIN_B1_CTL (0x500)
+#define MSM8X10_WCD_A_CDC_IIR1_GAIN_B1_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_IIR2_GAIN_B1_CTL (0x540)
+#define MSM8X10_WCD_A_CDC_IIR2_GAIN_B1_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_IIR1_GAIN_B2_CTL (0x504)
+#define MSM8X10_WCD_A_CDC_IIR1_GAIN_B2_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_IIR2_GAIN_B2_CTL (0x544)
+#define MSM8X10_WCD_A_CDC_IIR2_GAIN_B2_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_IIR1_GAIN_B3_CTL (0x508)
+#define MSM8X10_WCD_A_CDC_IIR1_GAIN_B3_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_IIR2_GAIN_B3_CTL (0x548)
+#define MSM8X10_WCD_A_CDC_IIR2_GAIN_B3_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_IIR1_GAIN_B4_CTL (0x50C)
+#define MSM8X10_WCD_A_CDC_IIR1_GAIN_B4_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_IIR2_GAIN_B4_CTL (0x54C)
+#define MSM8X10_WCD_A_CDC_IIR2_GAIN_B4_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_IIR1_GAIN_B5_CTL (0x510)
+#define MSM8X10_WCD_A_CDC_IIR1_GAIN_B5_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_IIR2_GAIN_B5_CTL (0x550)
+#define MSM8X10_WCD_A_CDC_IIR2_GAIN_B5_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_IIR1_GAIN_B6_CTL (0x514)
+#define MSM8X10_WCD_A_CDC_IIR1_GAIN_B6_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_IIR2_GAIN_B6_CTL (0x554)
+#define MSM8X10_WCD_A_CDC_IIR2_GAIN_B6_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_IIR1_GAIN_B7_CTL (0x518)
+#define MSM8X10_WCD_A_CDC_IIR1_GAIN_B7_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_IIR2_GAIN_B7_CTL (0x558)
+#define MSM8X10_WCD_A_CDC_IIR2_GAIN_B7_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_IIR1_GAIN_B8_CTL (0x51C)
+#define MSM8X10_WCD_A_CDC_IIR1_GAIN_B8_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_IIR2_GAIN_B8_CTL (0x55C)
+#define MSM8X10_WCD_A_CDC_IIR2_GAIN_B8_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_IIR1_CTL (0x520)
+#define MSM8X10_WCD_A_CDC_IIR1_CTL__POR (0x40)
+#define MSM8X10_WCD_A_CDC_IIR2_CTL (0x560)
+#define MSM8X10_WCD_A_CDC_IIR2_CTL__POR (0x40)
+#define MSM8X10_WCD_A_CDC_IIR1_GAIN_TIMER_CTL (0x524)
+#define MSM8X10_WCD_A_CDC_IIR1_GAIN_TIMER_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_IIR2_GAIN_TIMER_CTL (0x564)
+#define MSM8X10_WCD_A_CDC_IIR2_GAIN_TIMER_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_IIR1_COEF_B1_CTL (0x528)
+#define MSM8X10_WCD_A_CDC_IIR1_COEF_B1_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_IIR2_COEF_B1_CTL (0x568)
+#define MSM8X10_WCD_A_CDC_IIR2_COEF_B1_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_IIR1_COEF_B2_CTL (0x52C)
+#define MSM8X10_WCD_A_CDC_IIR1_COEF_B2_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_IIR2_COEF_B2_CTL (0x56C)
+#define MSM8X10_WCD_A_CDC_IIR2_COEF_B2_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_CONN_RX1_B1_CTL (0x580)
+#define MSM8X10_WCD_A_CDC_CONN_RX1_B1_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_CONN_RX1_B2_CTL (0x584)
+#define MSM8X10_WCD_A_CDC_CONN_RX1_B2_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_CONN_RX1_B3_CTL (0x588)
+#define MSM8X10_WCD_A_CDC_CONN_RX1_B3_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_CONN_RX2_B1_CTL (0x58C)
+#define MSM8X10_WCD_A_CDC_CONN_RX2_B1_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_CONN_RX2_B2_CTL (0x590)
+#define MSM8X10_WCD_A_CDC_CONN_RX2_B2_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_CONN_RX2_B3_CTL (0x594)
+#define MSM8X10_WCD_A_CDC_CONN_RX2_B3_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_CONN_RX3_B1_CTL (0x598)
+#define MSM8X10_WCD_A_CDC_CONN_RX3_B1_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_CONN_RX3_B2_CTL (0x59C)
+#define MSM8X10_WCD_A_CDC_CONN_RX3_B2_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_CONN_TX_B1_CTL (0x5A4)
+#define MSM8X10_WCD_A_CDC_CONN_TX_B1_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_CONN_EQ1_B1_CTL (0x5A8)
+#define MSM8X10_WCD_A_CDC_CONN_EQ1_B1_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_CONN_EQ1_B2_CTL (0x5AC)
+#define MSM8X10_WCD_A_CDC_CONN_EQ1_B2_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_CONN_EQ1_B3_CTL (0x5B0)
+#define MSM8X10_WCD_A_CDC_CONN_EQ1_B3_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_CONN_EQ1_B4_CTL (0x5B4)
+#define MSM8X10_WCD_A_CDC_CONN_EQ1_B4_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_CONN_EQ2_B1_CTL (0x5B8)
+#define MSM8X10_WCD_A_CDC_CONN_EQ2_B1_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_CONN_EQ2_B2_CTL (0x5BC)
+#define MSM8X10_WCD_A_CDC_CONN_EQ2_B2_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_CONN_EQ2_B3_CTL (0x5C0)
+#define MSM8X10_WCD_A_CDC_CONN_EQ2_B3_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_CONN_EQ2_B4_CTL (0x5C4)
+#define MSM8X10_WCD_A_CDC_CONN_EQ2_B4_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_CONN_TX_I2S_SD1_CTL (0x5C8)
+#define MSM8X10_WCD_A_CDC_CONN_TX_I2S_SD1_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_TOP_GAIN_UPDATE (0x5D0)
+#define MSM8X10_WCD_A_CDC_TOP_GAIN_UPDATE__POR (0x00)
+#define MSM8X10_WCD_A_CDC_TOP_CTL (0x5D8)
+#define MSM8X10_WCD_A_CDC_TOP_CTL__POR (0x01)
+#define MSM8X10_WCD_A_CDC_DEBUG_DESER1_CTL (0x5E0)
+#define MSM8X10_WCD_A_CDC_DEBUG_DESER1_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_DEBUG_DESER2_CTL (0x5E4)
+#define MSM8X10_WCD_A_CDC_DEBUG_DESER2_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_DEBUG_B1_CTL (0x5E8)
+#define MSM8X10_WCD_A_CDC_DEBUG_B1_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_DEBUG_B2_CTL (0x5EC)
+#define MSM8X10_WCD_A_CDC_DEBUG_B2_CTL__POR (0x00)
+#define MSM8X10_WCD_A_CDC_DEBUG_B3_CTL (0x5F0)
+#define MSM8X10_WCD_A_CDC_DEBUG_B3_CTL__POR (0x00)