Merge "power: pm8921-bms: fix the mutex usage"
diff --git a/Documentation/devicetree/bindings/arm/msm/bcl.txt b/Documentation/devicetree/bindings/arm/msm/bcl.txt
new file mode 100644
index 0000000..e11a817
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/bcl.txt
@@ -0,0 +1,15 @@
+* Battery Current Limit
+
+This Battery Current Limit device, provides an interface to detect and notify
+interested applications when the SOC is drawing current in excess of the limits
+specified.
+
+The device tree parameters for bcl are:
+
+Required parameters:
+- compatible: Must be "qcom,bcl"
+
+Example:
+ qcom,bcl {
+ compatible = "qcom,bcl";
+ };
diff --git a/Documentation/devicetree/bindings/arm/msm/mpm_counter.txt b/Documentation/devicetree/bindings/arm/msm/mpm_counter.txt
new file mode 100644
index 0000000..e62b9ec
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/mpm_counter.txt
@@ -0,0 +1,17 @@
+* MSM Timetick counter (mpm-v2)
+
+The MPM provides a timetick that starts when the device is powered up and
+is not reset by any of the boot loaders or the HLOS. The MPM timetick counter
+driver provides an api to get this value.
+
+The required nodes for the MPM timetick counter driver are:
+
+- compatible: "qcom,mpm-counter"
+- reg: Specifies the physical address of the timetick count register.
+
+Example:
+ qcom,mpm-counter@fc4a3000 {
+ compatible = "qcom,mpm-counter";
+ reg = <0xfc4a3000 0x1000>;
+ };
+
diff --git a/Documentation/devicetree/bindings/pil/pil-q6v5-mss.txt b/Documentation/devicetree/bindings/pil/pil-q6v5-mss.txt
index b1f6717..8f602b6 100644
--- a/Documentation/devicetree/bindings/pil/pil-q6v5-mss.txt
+++ b/Documentation/devicetree/bindings/pil/pil-q6v5-mss.txt
@@ -21,8 +21,6 @@
images and self-authentication is not desired;
<1> if the hardware requires self-authenticating images.
- qcom,is-loadable: if PIL is required to load the modem image
-- qcom,gpio-err-fatal: GPIO used by the modem to indicate error fatal to the apps.
-- qcom,gpio-force-stop: GPIO used by the apps to force the modem to shutdown.
Optional properties:
- vdd_pll-supply: Reference to the regulator that supplies the PLL's rail.
@@ -46,10 +44,4 @@
qcom,is-loadable;
qcom,firmware-name = "mba";
qcom,pil-self-auth = <1>;
-
- /* GPIO inputs from mss */
- gpio_err_fatal = <&smp2pgpio_ssr_smp2p_1_in 0 0>;
-
- /* GPIO output to mss */
- gpio_force_stop = <&smp2pgpio_ssr_smp2p_1_out 0 0>;
};
diff --git a/Documentation/devicetree/bindings/power/qpnp-charger.txt b/Documentation/devicetree/bindings/power/qpnp-charger.txt
index 03b01ee..a868b75 100644
--- a/Documentation/devicetree/bindings/power/qpnp-charger.txt
+++ b/Documentation/devicetree/bindings/power/qpnp-charger.txt
@@ -34,6 +34,8 @@
system thermal mitigation level.
Parent node optional properties:
+- qcom,chg-maxinput-usb-ma: Maximum input current USB.
+- qcom,chg-maxinput-dc-ma: Maximum input current DC.
- qcom,chg-charging-disabled: Set this property to disable charging
by default. This can then be overriden
writing the the module parameter
diff --git a/Documentation/devicetree/bindings/thermal/tsens.txt b/Documentation/devicetree/bindings/thermal/tsens.txt
index 0682cd1..67a986b 100644
--- a/Documentation/devicetree/bindings/thermal/tsens.txt
+++ b/Documentation/devicetree/bindings/thermal/tsens.txt
@@ -29,6 +29,11 @@
sensor used to compute the offset. Slope is represented
as ADC code/DegC and the value is multipled by a factor
of 1000.
+- qcom,calib-mode : Calibration masks to use to abstract the offset data from efuse.
+ Select from the following strings.
+ "fuse_map1" : Used for 8974/9x25 fuse calibration map.
+ "fuse_map2" : Used for 8x26 fuse calibration map.
+ "fuse_map3" : Used for 8x10 fuse calibration map.
Optional properties:
- qcom,calibration-less-mode : If present the pre-characterized data for offsets
@@ -45,6 +50,7 @@
interrupts = <0 184 0>;
qcom,calibration-less-mode;
qcom,sensors = <11>;
- qcom,slope = <1134 1122 1142 1123 1176 1176 1176 1186 1176
- 1176>;
+ qcom,slope = <3200 3200 3200 3200 3200 3200 3200 3200 3200
+ 3200>;
+ qcom,calib-mode = "fuse_map1";
};
diff --git a/arch/arm/boot/dts/msm-pm8226.dtsi b/arch/arm/boot/dts/msm-pm8226.dtsi
index 94db3ea..ce4513b 100644
--- a/arch/arm/boot/dts/msm-pm8226.dtsi
+++ b/arch/arm/boot/dts/msm-pm8226.dtsi
@@ -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
@@ -15,4 +15,400 @@
#size-cells = <0>;
interrupt-controller;
#interrupt-cells = <3>;
+
+ qcom,pm8226@0 {
+ spmi-slave-container;
+ reg = <0x0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ pm8226_gpios: gpios {
+ spmi-dev-container;
+ compatible = "qcom,qpnp-pin";
+ gpio-controller;
+ #gpio-cells = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ label = "pm8226-gpio";
+
+ gpio@c000 {
+ reg = <0xc000 0x100>;
+ qcom,pin-num = <1>;
+ };
+
+ gpio@c100 {
+ reg = <0xc100 0x100>;
+ qcom,pin-num = <2>;
+ };
+
+ gpio@c200 {
+ reg = <0xc200 0x100>;
+ qcom,pin-num = <3>;
+ };
+
+ gpio@c300 {
+ reg = <0xc300 0x100>;
+ qcom,pin-num = <4>;
+ };
+
+ gpio@c400 {
+ reg = <0xc400 0x100>;
+ qcom,pin-num = <5>;
+ };
+
+ gpio@c500 {
+ reg = <0xc500 0x100>;
+ qcom,pin-num = <6>;
+ };
+
+ gpio@c600 {
+ reg = <0xc600 0x100>;
+ qcom,pin-num = <7>;
+ };
+
+ gpio@c700 {
+ reg = <0xc700 0x100>;
+ qcom,pin-num = <8>;
+ };
+ };
+
+ pm8226_mpps: mpps {
+ spmi-dev-container;
+ compatible = "qcom,qpnp-pin";
+ gpio-controller;
+ #gpio-cells = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ label = "pm8226-mpp";
+
+ mpp@a000 {
+ reg = <0xa000 0x100>;
+ qcom,pin-num = <1>;
+ };
+
+ mpp@a100 {
+ reg = <0xa100 0x100>;
+ qcom,pin-num = <2>;
+ };
+
+ mpp@a200 {
+ reg = <0xa200 0x100>;
+ qcom,pin-num = <3>;
+ };
+
+ mpp@a300 {
+ reg = <0xa300 0x100>;
+ qcom,pin-num = <4>;
+ };
+
+ mpp@a400 {
+ reg = <0xa400 0x100>;
+ qcom,pin-num = <5>;
+ };
+
+ mpp@a500 {
+ reg = <0xa500 0x100>;
+ qcom,pin-num = <6>;
+ };
+
+ mpp@a600 {
+ reg = <0xa600 0x100>;
+ qcom,pin-num = <7>;
+ };
+
+ mpp@a700 {
+ reg = <0xa700 0x100>;
+ qcom,pin-num = <8>;
+ };
+ };
+ };
+
+ qcom,pm8226@1 {
+ spmi-slave-container;
+ reg = <0x1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ regulator@1400 {
+ regulator-name = "8226_s1";
+ spmi-dev-container;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "qcom,qpnp-regulator";
+ reg = <0x1400 0x300>;
+ status = "disabled";
+
+ qcom,ctl@1400 {
+ reg = <0x1400 0x100>;
+ };
+ qcom,ps@1500 {
+ reg = <0x1500 0x100>;
+ };
+ qcom,freq@1600 {
+ reg = <0x1600 0x100>;
+ };
+ };
+
+ regulator@1700 {
+ regulator-name = "8226_s2";
+ spmi-dev-container;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "qcom,qpnp-regulator";
+ reg = <0x1700 0x300>;
+ status = "disabled";
+
+ qcom,ctl@1700 {
+ reg = <0x1700 0x100>;
+ };
+ qcom,ps@1800 {
+ reg = <0x1800 0x100>;
+ };
+ qcom,freq@1900 {
+ reg = <0x1900 0x100>;
+ };
+ };
+
+ regulator@1a00 {
+ regulator-name = "8226_s3";
+ spmi-dev-container;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "qcom,qpnp-regulator";
+ reg = <0x1a00 0x300>;
+ status = "disabled";
+
+ qcom,ctl@1a00 {
+ reg = <0x1a00 0x100>;
+ };
+ qcom,ps@1b00 {
+ reg = <0x1b00 0x100>;
+ };
+ qcom,freq@1c00 {
+ reg = <0x1c00 0x100>;
+ };
+ };
+
+ regulator@1d00 {
+ regulator-name = "8226_s4";
+ spmi-dev-container;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "qcom,qpnp-regulator";
+ reg = <0x1d00 0x300>;
+ status = "disabled";
+
+ qcom,ctl@1d00 {
+ reg = <0x1d00 0x100>;
+ };
+ qcom,ps@1e00 {
+ reg = <0x1e00 0x100>;
+ };
+ qcom,freq@1f00 {
+ reg = <0x1f00 0x100>;
+ };
+ };
+
+ regulator@2000 {
+ regulator-name = "8226_s5";
+ spmi-dev-container;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "qcom,qpnp-regulator";
+ reg = <0x2000 0x300>;
+ status = "disabled";
+
+ qcom,ctl@2000 {
+ reg = <0x2000 0x100>;
+ };
+ qcom,ps@2100 {
+ reg = <0x2100 0x100>;
+ };
+ qcom,freq@2200 {
+ reg = <0x2200 0x100>;
+ };
+ };
+
+ regulator@4000 {
+ regulator-name = "8226_l1";
+ reg = <0x4000 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@4100 {
+ regulator-name = "8226_l2";
+ reg = <0x4100 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@4200 {
+ regulator-name = "8226_l3";
+ reg = <0x4200 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@4300 {
+ regulator-name = "8226_l4";
+ reg = <0x4300 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@4400 {
+ regulator-name = "8226_l5";
+ reg = <0x4400 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@4500 {
+ regulator-name = "8226_l6";
+ reg = <0x4500 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@4600 {
+ regulator-name = "8226_l7";
+ reg = <0x4600 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@4700 {
+ regulator-name = "8226_l8";
+ reg = <0x4700 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@4800 {
+ regulator-name = "8226_l9";
+ reg = <0x4800 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@4900 {
+ regulator-name = "8226_l10";
+ reg = <0x4900 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@4b00 {
+ regulator-name = "8226_l12";
+ reg = <0x4b00 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@4d00 {
+ regulator-name = "8226_l14";
+ reg = <0x4d00 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@4e00 {
+ regulator-name = "8226_l15";
+ reg = <0x4e00 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@4f00 {
+ regulator-name = "8226_l16";
+ reg = <0x4f00 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@5000 {
+ regulator-name = "8226_l17";
+ reg = <0x5000 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@5100 {
+ regulator-name = "8226_l18";
+ reg = <0x5100 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@5200 {
+ regulator-name = "8226_l19";
+ reg = <0x5200 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@5300 {
+ regulator-name = "8226_l20";
+ reg = <0x5300 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@5400 {
+ regulator-name = "8226_l21";
+ reg = <0x5400 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@5500 {
+ regulator-name = "8226_l22";
+ reg = <0x5500 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@5600 {
+ regulator-name = "8226_l23";
+ reg = <0x5600 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@5700 {
+ regulator-name = "8226_l24";
+ reg = <0x5700 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@5900 {
+ regulator-name = "8226_l26";
+ reg = <0x5900 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@5a00 {
+ regulator-name = "8226_l27";
+ reg = <0x5a00 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@5b00 {
+ regulator-name = "8226_l28";
+ reg = <0x5b00 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@8000 {
+ regulator-name = "8226_lvs1";
+ reg = <0x8000 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+ };
};
diff --git a/arch/arm/boot/dts/msm8226-bus.dtsi b/arch/arm/boot/dts/msm8226-bus.dtsi
new file mode 100644
index 0000000..28d0840
--- /dev/null
+++ b/arch/arm/boot/dts/msm8226-bus.dtsi
@@ -0,0 +1,1126 @@
+/* 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.
+ */
+
+/ {
+ msm-mmss-noc@fc478000 {
+ compatible = "msm-bus-fabric";
+ reg = <0xfc478000 0x00004000>;
+ cell-id = <2048>;
+ label = "msm_mmss_noc";
+ qcom,fabclk-dual = "bus_clk";
+ qcom,fabclk-active = "bus_a_clk";
+ qcom,ntieredslaves = <0>;
+ qcom,qos-freq = <4800>;
+ qcom,hw-sel = "NoC";
+ qcom,rpm-en;
+
+ mas-gfx3d {
+ cell-id = <26>;
+ label = "mas-gfx3d";
+ qcom,masterp = <2>;
+ qcom,tier = <2>;
+ qcom,hw-sel = "NoC";
+ qcom,perm-mode = "Bypass";
+ qcom,mode = "Bypass";
+ qcom,ws = <10000>;
+ qcom,qport = <2>;
+ qcom,mas-hw-id = <6>;
+ };
+
+ mas-jpeg {
+ cell-id = <62>;
+ label = "mas-jpeg";
+ qcom,masterp = <4>;
+ qcom,tier = <2>;
+ qcom,hw-sel = "NoC";
+ qcom,perm-mode = "Bypass";
+ qcom,mode = "Bypass";
+ qcom,qport = <0>;
+ qcom,ws = <10000>;
+ qcom,mas-hw-id = <7>;
+ };
+
+ mas-mdp-port0 {
+ cell-id = <22>;
+ label = "mas-mdp-port0";
+ qcom,masterp = <5>;
+ qcom,tier = <2>;
+ qcom,hw-sel = "NoC";
+ qcom,perm-mode = "Bypass";
+ qcom,mode = "Bypass";
+ qcom,qport = <1>;
+ qcom,ws = <10000>;
+ qcom,mas-hw-id = <8>;
+ };
+
+ mas-video-p0 {
+ cell-id = <63>;
+ label = "mas-video-p0";
+ qcom,masterp = <6>;
+ qcom,tier = <2>;
+ qcom,hw-sel = "NoC";
+ qcom,perm-mode = "Bypass";
+ qcom,mode = "Bypass";
+ qcom,ws = <10000>;
+ qcom,qport = <4>;
+ qcom,mas-hw-id = <9>;
+ };
+
+ mas-vfe {
+ cell-id = <29>;
+ label = "mas-vfe";
+ qcom,masterp = <16>;
+ qcom,tier = <2>;
+ qcom,hw-sel = "NoC";
+ qcom,perm-mode = "Bypass";
+ qcom,mode = "Bypass";
+ qcom,ws = <10000>;
+ qcom,qport = <6>;
+ qcom,mas-hw-id = <11>;
+ };
+
+ fab-cnoc {
+ cell-id = <5120>;
+ label = "fab-cnoc";
+ qcom,gateway;
+ qcom,masterp = <0 1>;
+ qcom,buswidth = <16>;
+ qcom,hw-sel = "RPM";
+ qcom,mas-hw-id = <4>;
+ };
+
+ fab-bimc {
+ cell-id = <0>;
+ label = "fab-bimc";
+ qcom,gateway;
+ qcom,slavep = <16>;
+ qcom,buswidth = <16>;
+ qcom,hw-sel = "NoC";
+ qcom,slv-hw-id = <16>;
+ };
+
+ slv-camera-cfg {
+ cell-id = <589>;
+ label = "slv-camera-cfg";
+ qcom,slavep = <0>;
+ qcom,tier = <2>;
+ qcom,buswidth = <16>;
+ qcom,hw-sel = "NoC";
+ qcom,slv-hw-id = <3>;
+ };
+
+ slv-display-cfg {
+ cell-id = <590>;
+ label = "slv-display-cfg";
+ qcom,slavep = <1>;
+ qcom,tier = <2>;
+ qcom,buswidth = <16>;
+ qcom,hw-sel = "NoC";
+ qcom,slv-hw-id = <4>;
+ };
+
+ slv-ocmem-cfg {
+ cell-id = <591>;
+ label = "slv-ocmem-cfg";
+ qcom,slavep = <2>;
+ qcom,tier = <2>;
+ qcom,buswidth = <16>;
+ qcom,hw-sel = "NoC";
+ qcom,slv-hw-id = <5>;
+ };
+
+ slv-cpr-cfg {
+ cell-id = <592>;
+ label = "slv-cpr-cfg";
+ qcom,slavep = <3>;
+ qcom,tier = <2>;
+ qcom,buswidth = <16>;
+ qcom,hw-sel = "NoC";
+ qcom,slv-hw-id = <6>;
+ };
+
+ slv-cpr-xpu-cfg {
+ cell-id = <593>;
+ label = "slv-cpr-xpu-cfg";
+ qcom,slavep = <4>;
+ qcom,tier = <2>;
+ qcom,buswidth = <16>;
+ qcom,hw-sel = "NoC";
+ qcom,slv-hw-id = <7>;
+ };
+
+ slv-misc-cfg {
+ cell-id = <594>;
+ label = "slv-misc-cfg";
+ qcom,slavep = <6>;
+ qcom,tier = <2>;
+ qcom,buswidth = <16>;
+ qcom,hw-sel = "NoC";
+ qcom,slv-hw-id = <8>;
+ };
+
+ slv-misc-xpu-cfg {
+ cell-id = <595>;
+ label = "slv-misc-xpu-cfg";
+ qcom,slavep = <7>;
+ qcom,tier = <2>;
+ qcom,buswidth = <16>;
+ qcom,hw-sel = "NoC";
+ qcom,slv-hw-id = <9>;
+ };
+
+ slv-venus-cfg {
+ cell-id = <596>;
+ label = "slv-venus-cfg";
+ qcom,slavep = <8>;
+ qcom,tier = <2>;
+ qcom,buswidth = <16>;
+ qcom,hw-sel = "NoC";
+ qcom,slv-hw-id = <10>;
+ };
+
+ slv-gfx3d-cfg {
+ cell-id = <598>;
+ label = "slv-gfx3d-cfg";
+ qcom,slavep = <9>;
+ qcom,tier = <2>;
+ qcom,buswidth = <16>;
+ qcom,hw-sel = "NoC";
+ qcom,slv-hw-id = <11>;
+ };
+
+ slv-mmss-clk-cfg {
+ cell-id = <599>;
+ label = "slv-mmss-clk-cfg";
+ qcom,slavep = <11>;
+ qcom,tier = <2>;
+ qcom,buswidth = <16>;
+ qcom,hw-sel = "NoC";
+ qcom,slv-hw-id = <12>;
+ };
+
+ slv-mmss-clk-xpu-cfg {
+ cell-id = <600>;
+ label = "slv-mmss-clk-xpu-cfg";
+ qcom,slavep = <12>;
+ qcom,tier = <2>;
+ qcom,buswidth = <16>;
+ qcom,hw-sel = "NoC";
+ qcom,slv-hw-id = <13>;
+ };
+
+ slv-mnoc-mpu-cfg {
+ cell-id = <601>;
+ label = "slv-mnoc-mpu-cfg";
+ qcom,slavep = <13>;
+ qcom,tier = <2>;
+ qcom,buswidth = <16>;
+ qcom,hw-sel = "NoC";
+ qcom,slv-hw-id = <14>;
+ };
+
+ slv-onoc-mpu-cfg {
+ cell-id = <602>;
+ label = "slv-onoc-mpu-cfg";
+ qcom,slavep = <14>;
+ qcom,tier = <2>;
+ qcom,buswidth = <16>;
+ qcom,hw-sel = "NoC";
+ qcom,slv-hw-id = <15>;
+ };
+
+ slv-service-mnoc {
+ cell-id = <603>;
+ label = "slv-service-mnoc";
+ qcom,slavep = <18>;
+ qcom,tier = <2>;
+ qcom,buswidth = <16>;
+ qcom,hw-sel = "NoC";
+ qcom,slv-hw-id = <17>;
+ };
+
+ };
+
+ msm-sys-noc@fc460000 {
+ compatible = "msm-bus-fabric";
+ reg = <0xfc460000 0x00004000>;
+ cell-id = <1024>;
+ label = "msm_sys_noc";
+ qcom,fabclk-dual = "bus_clk";
+ qcom,fabclk-active = "bus_a_clk";
+ qcom,ntieredslaves = <0>;
+ qcom,qos-freq = <4800>;
+ qcom,hw-sel = "NoC";
+ qcom,rpm-en;
+
+ mas-lpass-ahb {
+ cell-id = <52>;
+ label = "mas-lpass-ahb";
+ qcom,masterp = <0>;
+ qcom,tier = <2>;
+ qcom,qport = <0>;
+ qcom,mas-hw-id = <18>;
+ qcom,mode = "Fixed";
+ qcom,prio-rd = <2>;
+ qcom,prio-wr = <2>;
+ };
+
+ mas-qdss-bam {
+ cell-id = <53>;
+ label = "mas-qdss-bam";
+ qcom,masterp = <1>;
+ qcom,tier = <2>;
+ qcom,mode = "Fixed";
+ qcom,qport = <1>;
+ qcom,mas-hw-id = <19>;
+ };
+
+ mas-snoc-cfg {
+ cell-id = <54>;
+ label = "mas-snoc-cfg";
+ qcom,masterp = <2>;
+ qcom,tier = <2>;
+ qcom,mas-hw-id = <20>;
+ };
+
+ fab-bimc {
+ cell-id = <0>;
+ label= "fab-bimc";
+ qcom,gateway;
+ qcom,slavep = <7>;
+ qcom,masterp = <3>;
+ qcom,buswidth = <8>;
+ qcom,mas-hw-id = <21>;
+ qcom,slv-hw-id = <24>;
+ };
+
+ fab-cnoc {
+ cell-id = <5120>;
+ label = "fab-cnoc";
+ qcom,gateway;
+ qcom,slavep = <8>;
+ qcom,masterp = <4>;
+ qcom,buswidth = <8>;
+ qcom,mas-hw-id = <22>;
+ qcom,slv-hw-id = <25>;
+ };
+
+ fab-pnoc {
+ cell-id = <4096>;
+ label = "fab-pnoc";
+ qcom,gateway;
+ qcom,slavep = <10>;
+ qcom,masterp = <10>;
+ qcom,buswidth = <8>;
+ qcom,qport = <8>;
+ qcom,mas-hw-id = <29>;
+ qcom,slv-hw-id = <28>;
+ qcom,mode = "Fixed";
+ qcom,prio-rd = <2>;
+ qcom,prio-wr = <2>;
+ };
+
+ fab-ovnoc {
+ cell-id = <6144>;
+ label = "fab-ovnoc";
+ qcom,gateway;
+ qcom,buswidth = <8>;
+ qcom,mas-hw-id = <53>;
+ qcom,slv-hw-id = <77>;
+ };
+
+ mas-crypto-core0 {
+ cell-id = <55>;
+ label = "mas-crypto-core0";
+ qcom,masterp = <5>;
+ qcom,tier = <2>;
+ qcom,mode = "Fixed";
+/* qcom,qport = <2>;*/
+ qcom,mas-hw-id = <23>;
+ qcom,hw-sel = "NoC";
+ qcom,prio-rd = <1>;
+ qcom,prio-wr = <1>;
+ };
+
+ mas-lpass-proc {
+ cell-id = <11>;
+ label = "mas-lpass-proc";
+ qcom,masterp = <6>;
+ qcom,tier = <2>;
+ qcom,qport = <4>;
+ qcom,mas-hw-id = <25>;
+ qcom,mode = "Fixed";
+ qcom,prio-rd = <2>;
+ qcom,prio-wr = <2>;
+ };
+
+ mas-mss {
+ cell-id = <38>;
+ label = "mas-mss";
+ qcom,masterp = <7>;
+ qcom,tier = <2>;
+ qcom,mas-hw-id = <26>;
+ };
+
+ mas-mss-nav {
+ cell-id = <57>;
+ label = "mas-mss-nav";
+ qcom,masterp = <8>;
+ qcom,tier = <2>;
+ qcom,mas-hw-id = <27>;
+ };
+
+ mas-ocmem-dma {
+ cell-id = <58>;
+ label = "mas-ocmem-dma";
+ qcom,masterp = <9>;
+ qcom,tier = <2>;
+ qcom,mode = "Fixed";
+ qcom,qport = <7>;
+ qcom,mas-hw-id = <28>;
+ };
+
+ mas-wcss {
+ cell-id = <59>;
+ label = "mas-wcss";
+ qcom,masterp = <11>;
+ qcom,tier = <2>;
+ qcom,mas-hw-id = <30>;
+ };
+
+ mas-qdss-etr {
+ cell-id = <60>;
+ label = "mas-qdss-etr";
+ qcom,masterp = <12>;
+ qcom,tier = <2>;
+ qcom,qport = <10>;
+ qcom,mode = "Fixed";
+ qcom,mas-hw-id = <31>;
+ };
+
+ slv-ampss {
+ cell-id = <520>;
+ label = "slv-ampss";
+ qcom,slavep = <1>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <20>;
+ };
+
+ slv-lpass {
+ cell-id = <522>;
+ label = "slv-lpass";
+ qcom,slavep = <2>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <21>;
+ };
+
+ slv-wcss {
+ cell-id = <584>;
+ label = "slv-wcss";
+ qcom,slavep = <6>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <23>;
+ };
+
+ slv-ocimem {
+ cell-id = <585>;
+ label = "slv-ocimem";
+ qcom,slavep = <9>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <26>;
+ };
+
+ slv-service-snoc {
+ cell-id = <587>;
+ label = "slv-service-snoc";
+ qcom,slavep = <11>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <29>;
+ };
+
+ slv-qdss-stm {
+ cell-id = <588>;
+ label = "slv-qdss-stm";
+ qcom,slavep = <12>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <30>;
+ };
+
+ };
+
+ msm-periph-noc@fc468000 {
+ compatible = "msm-bus-fabric";
+ reg = <0xfc468000 0x00004000>;
+ cell-id = <4096>;
+ label = "msm_periph_noc";
+ qcom,fabclk-dual = "bus_clk";
+ qcom,fabclk-active = "bus_a_clk";
+ qcom,ntieredslaves = <0>;
+ qcom,hw-sel = "NoC";
+ qcom,rpm-en;
+
+ mas-pnoc-cfg {
+ cell-id = <88>;
+ label = "mas-pnoc-cfg";
+ qcom,masterp = <7>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,mas-hw-id = <43>;
+ };
+
+ mas-sdcc-1 {
+ cell-id = <78>;
+ label = "mas-sdcc-1";
+ qcom,masterp = <0>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,mas-hw-id = <33>;
+ };
+
+ mas-sdcc-3 {
+ cell-id = <79>;
+ label = "mas-sdcc-3";
+ qcom,masterp = <1>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,mas-hw-id = <34>;
+ };
+
+ mas-sdcc-2 {
+ cell-id = <81>;
+ label = "mas-sdcc-2";
+ qcom,masterp = <2>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,mas-hw-id = <35>;
+ };
+
+ mas-bam-dma {
+ cell-id = <83>;
+ label = "mas-bam-dma";
+ qcom,masterp = <3>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,mas-hw-id = <38>;
+ };
+
+ mas-usb-hsic {
+ cell-id = <85>;
+ label = "mas-usb-hsic";
+ qcom,masterp = <4>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,mas-hw-id = <40>;
+ };
+
+ mas-blsp-1 {
+ cell-id = <86>;
+ label = "mas-blsp-1";
+ qcom,masterp = <5>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,mas-hw-id = <41>;
+ };
+
+ mas-usb-hs {
+ cell-id = <87>;
+ label = "mas-usb-hs";
+ qcom,masterp = <6>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,mas-hw-id = <42>;
+ };
+
+ fab-snoc {
+ cell-id = <1024>;
+ label = "fab-snoc";
+ qcom,gateway;
+ qcom,slavep = <12>;
+ qcom,masterp = <8>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <45>;
+ qcom,mas-hw-id = <44>;
+ };
+
+ slv-sdcc-1 {
+ cell-id = <606>;
+ label = "slv-sdcc-1";
+ qcom,slavep = <0>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <31>;
+ };
+
+ slv-sdcc-3 {
+ cell-id = <607>;
+ label = "slv-sdcc-3";
+ qcom,slavep = <1>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <32>;
+ };
+
+ slv-sdcc-2 {
+ cell-id = <608>;
+ label = "slv-sdcc-2";
+ qcom,slavep = <2>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <33>;
+ };
+
+ slv-bam-dma {
+ cell-id = <610>;
+ label = "slv-bam-dma";
+ qcom,slavep = <3>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <36>;
+ };
+
+ slv-usb-hsic {
+ cell-id = <612>;
+ label = "slv-usb-hsic";
+ qcom,slavep = <4>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <38>;
+ };
+
+ slv-blsp-1 {
+ cell-id = <613>;
+ label = "slv-blsp-1";
+ qcom,slavep = <5>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <39>;
+ };
+
+ slv-usb-hs {
+ cell-id = <614>;
+ label = "slv-usb-hs";
+ qcom,slavep = <6>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <40>;
+ };
+
+ slv-pdm {
+ cell-id = <615>;
+ label = "slv-pdm";
+ qcom,slavep = <7>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <41>;
+ };
+
+ slv-periph-apu-cfg {
+ cell-id = <616>;
+ label = "slv-periph-apu-cfg";
+ qcom,slavep = <8>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <42>;
+ };
+
+ slv-pnoc-mpu-cfg {
+ cell-id = <617>;
+ label = "slv-pnoc-mpu-cfg";
+ qcom,slavep = <9>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <43>;
+ };
+
+ slv-prng {
+ cell-id = <618>;
+ label = "slv-prng";
+ qcom,slavep = <10>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <44>;
+ };
+
+ slv-service-pnoc {
+ cell-id = <619>;
+ label = "slv-service-pnoc";
+ qcom,slavep = <12>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <46>;
+ };
+
+ };
+
+ msm-config-noc@fc480000 {
+ compatible = "msm-bus-fabric";
+ reg = <0xfc480000 0x00004000>;
+ cell-id = <5120>;
+ label = "msm_config_noc";
+ qcom,fabclk-dual = "bus_clk";
+ qcom,fabclk-active = "bus_a_clk";
+ qcom,ntieredslaves = <0>;
+ qcom,hw-sel = "NoC";
+ qcom,rpm-en;
+
+ mas-rpm-inst {
+ cell-id = <72>;
+ label = "mas-rpm-inst";
+ qcom,masterp = <0>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,mas-hw-id = <45>;
+ };
+
+ mas-rpm-data {
+ cell-id = <73>;
+ label = "mas-rpm-data";
+ qcom,masterp = <1>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,mas-hw-id = <46>;
+ };
+
+ mas-rpm-sys {
+ cell-id = <74>;
+ label = "mas-rpm-sys";
+ qcom,masterp = <2>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,mas-hw-id = <47>;
+ };
+
+ mas-dehr {
+ cell-id = <75>;
+ label = "mas-dehr";
+ qcom,masterp = <3>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,mas-hw-id = <48>;
+ };
+
+ mas-qdss-dsp {
+ cell-id = <76>;
+ label = "mas-qdss-dap";
+ qcom,masterp = <4>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,mas-hw-id = <49>;
+ };
+
+ mas-spdm {
+ cell-id = <36>;
+ label = "mas-spdm";
+ qcom,masterp = <5>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,mas-hw-id = <50>;
+ };
+
+ mas-tic {
+ cell-id = <77>;
+ label = "mas-tic";
+ qcom,masterp = <6>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,mas-hw-id = <51>;
+ };
+
+ slv-clk-ctl {
+ cell-id = <620>;
+ label = "slv-clk-ctl";
+ qcom,slavep = <1>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <47>;
+ };
+
+ slv-cnoc-mss {
+ cell-id = <621>;
+ label = "slv-cnoc-mss";
+ qcom,slavep = <2>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <48>;
+ };
+
+ slv-security {
+ cell-id = <622>;
+ label = "slv-security";
+ qcom,slavep = <3>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <49>;
+ };
+
+ slv-tcsr {
+ cell-id = <623>;
+ label = "slv-tcsr";
+ qcom,slavep = <4>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <50>;
+ };
+
+ slv-tlmm {
+ cell-id = <624>;
+ label = "slv-tlmm";
+ qcom,slavep = <5>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <51>;
+ };
+
+ slv-crypto-0-cfg {
+ cell-id = <625>;
+ label = "slv-crypto-0-cfg";
+ qcom,slavep = <6>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <52>;
+ };
+
+ slv-imem-cfg {
+ cell-id = <627>;
+ label = "slv-imem-cfg";
+ qcom,slavep = <7>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <54>;
+ };
+
+ slv-message-ram {
+ cell-id = <628>;
+ label = "slv-message-ram";
+ qcom,slavep = <8>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <55>;
+ };
+
+ slv-bimc-cfg {
+ cell-id = <629>;
+ label = "slv-bimc-cfg";
+ qcom,slavep = <9>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <56>;
+ };
+
+ slv-boot-rom {
+ cell-id = <630>;
+ label = "slv-boot-rom";
+ qcom,slavep = <10>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <57>;
+ };
+
+ slv-pmic-arb {
+ cell-id = <632>;
+ label = "slv-pmic-arb";
+ qcom,slavep = <12>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <59>;
+ };
+
+ slv-spdm-wrapper {
+ cell-id = <633>;
+ label = "slv-spdm-wrapper";
+ qcom,slavep = <13>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <60>;
+ };
+
+ slv-dehr-cfg {
+ cell-id = <634>;
+ label = "slv-dehr-cfg";
+ qcom,slavep = <14>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <61>;
+ };
+
+ slv-mpm {
+ cell-id = <536>;
+ label = "slv-mpm";
+ qcom,slavep = <15>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <62>;
+ };
+
+ slv-qdss-cfg {
+ cell-id = <635>;
+ label = "slv-qdss-cfg";
+ qcom,slavep = <16>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <63>;
+ };
+
+ slv-rbcpr-cfg {
+ cell-id = <636>;
+ label = "slv-rbcpr-cfg";
+ qcom,slavep = <17>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <64>;
+ };
+
+ slv-rbcpr-qdss-apu-cfg {
+ cell-id = <637>;
+ label = "slv-rbcpr-qdss-apu-cfg";
+ qcom,slavep = <18>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <65>;
+ };
+
+ fab-snoc {
+ cell-id = <1024>;
+ label = "fab-snoc";
+ qcom,gateway;
+ qcom,slavep = <26>;
+ qcom,masterp = <7>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,mas-hw-id = <52>;
+ qcom,slv-hw-id = <75>;
+ };
+
+ slv-cnoc-mnoc-mmss-cfg {
+ cell-id = <631>;
+ label = "slv-cnoc-mnoc-mmss-cfg";
+ qcom,slavep = <11>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <58>;
+ };
+
+ slv-cnoc-mnoc-cfg {
+ cell-id = <640>;
+ label = "slv-cnoc-mnoc-cfg";
+ qcom,slavep = <19>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <66>;
+ };
+
+ slv-pnoc-cfg {
+ cell-id = <641>;
+ label = "slv-pnoc-cfg";
+ qcom,slavep = <21>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <69>;
+ };
+
+ slv-snoc-mpu-cfg {
+ cell-id = <638>;
+ label = "slv-snoc-mpu-cfg";
+ qcom,slavep = <20>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <67>;
+ };
+
+ slv-snoc-cfg {
+ cell-id = <642>;
+ label = "slv-snoc-cfg";
+ qcom,slavep = <22>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <70>;
+ };
+
+ slv-phy-apu-cfg {
+ cell-id = <644>;
+ label = "slv-phy-apu-cfg";
+ qcom,slavep = <23>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <72>;
+ };
+
+ slv-ebi1-phy-cfg {
+ cell-id = <645>;
+ label = "slv-ebi1-phy-cfg";
+ qcom,slavep = <24>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <73>;
+ };
+
+ slv-rpm {
+ cell-id = <534>;
+ label = "slv-rpm";
+ qcom,slavep = <25>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <74>;
+ };
+
+ slv-service-cnoc {
+ cell-id = <646>;
+ label = "slv-service-cnoc";
+ qcom,slavep = <27>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <76>;
+ };
+
+ };
+
+ msm-bimc@0xfc380000 {
+ compatible = "msm-bus-fabric";
+ reg = <0xfc380000 0x0006A000>;
+ cell-id = <0>;
+ label = "msm_bimc";
+ qcom,fabclk-dual = "mem_clk";
+ qcom,fabclk-active = "mem_a_clk";
+ qcom,ntieredslaves = <0>;
+ qcom,qos-freq = <4800>;
+ qcom,hw-sel = "BIMC";
+ qcom,rpm-en;
+
+ mas-ampss-m0 {
+ cell-id = <1>;
+ label = "mas-ampss-m0";
+ qcom,masterp = <0>;
+ qcom,tier = <2>;
+ qcom,hw-sel = "BIMC";
+ qcom,mode = "Fixed";
+ qcom,qport = <0>;
+ qcom,ws = <10000>;
+ qcom,mas-hw-id = <0>;
+ qcom,prio-rd = <1>;
+ qcom,prio-wr = <1>;
+ };
+
+ mas-mss-proc {
+ cell-id = <65>;
+ label = "mas-mss-proc";
+ qcom,masterp = <1>;
+ qcom,tier = <2>;
+ qcom,hw-sel = "RPM";
+ qcom,mas-hw-id = <1>;
+ };
+
+ fab-mmss-noc {
+ cell-id = <2048>;
+ label = "fab_mmss_noc";
+ qcom,gateway;
+ qcom,masterp = <2>;
+ qcom,qport = <2>;
+ qcom,buswidth = <8>;
+ qcom,ws = <10000>;
+ qcom,mas-hw-id = <2>;
+ qcom,hw-sel = "BIMC";
+ qcom,mode = "Bypass";
+ };
+
+ fab-snoc {
+ cell-id = <1024>;
+ label = "fab-snoc";
+ qcom,gateway;
+ qcom,slavep = <2>;
+ qcom,masterp = <4>;
+ qcom,qport = <4>;
+ qcom,buswidth = <8>;
+ qcom,ws = <10000>;
+ qcom,mas-hw-id = <3>;
+ qcom,slv-hw-id = <2>;
+ };
+
+ slv-ebi-ch0 {
+ cell-id = <512>;
+ label = "slv-ebi-ch0";
+ qcom,slavep = <0>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <0>;
+ qcom,mode = "Bypass";
+ };
+
+ slv-ampss-l2 {
+ cell-id = <514>;
+ label = "slv-ampss-l2";
+ qcom,slavep = <1>;
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,slv-hw-id = <1>;
+ };
+ };
+
+ msm-ocmem-vnoc@6144 {
+ compatible = "msm-bus-fabric";
+ reg = <0x6144 0x2>;
+ cell-id = <6144>;
+ label = "msm-ocmem-vnoc";
+ qcom,ntieredslaves = <0>;
+ qcom,hw-sel = "NoC";
+ qcom,rpm-en;
+ qcom,virt;
+
+ mas-v-ocmem-gfx3d {
+ cell-id = <89>;
+ label = "mas-v-ocmem-gfx3d";
+ qcom,tier = <2>;
+ qcom,buswidth = <8>;
+ qcom,mas-hw-id = <55>;
+ };
+
+ slv-ocmem {
+ cell-id = <604>;
+ label = "slv-ocmem";
+ qcom,slavep = <0 1>;
+ qcom,tier = <2>;
+ qcom,buswidth = <16>;
+ qcom,slv-hw-id = <18>;
+ qcom,slaveclk-dual = "ocmem_clk";
+ qcom,slaveclk-active = "ocmem_a_clk";
+ };
+
+ fab-snoc {
+ cell-id = <1024>;
+ label = "fab-snoc";
+ qcom,gateway;
+ qcom,buswidth = <32>;
+ qcom,ws = <10000>;
+ qcom,mas-hw-id = <57>;
+ qcom,slv-hw-id = <80>;
+ };
+
+ fab-onoc {
+ cell-id = <3072>;
+ label = "fab-onoc";
+ qcom,gateway;
+ qcom,buswidth = <16>;
+ qcom,ws = <10000>;
+ qcom,mas-hw-id = <56>;
+ qcom,slv-hw-id = <79>;
+ };
+
+ };
+};
+
+
diff --git a/arch/arm/boot/dts/msm8226-regulator.dtsi b/arch/arm/boot/dts/msm8226-regulator.dtsi
index f2269d5..50d2dba 100644
--- a/arch/arm/boot/dts/msm8226-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8226-regulator.dtsi
@@ -10,275 +10,300 @@
* GNU General Public License for more details.
*/
- /* Stub Regulators */
+/* Stub Regulators */
- / {
- pm8026_s1: regulator-s1 {
- compatible = "qcom,stub-regulator";
- regulator-name = "8026_s1";
- qcom,hpm-min-load = <100000>;
- regulator-min-microvolt = <1150000>;
- regulator-max-microvolt = <1150000>;
- };
-
+/ {
pm8026_s1_corner: regulator-s1-corner {
compatible = "qcom,stub-regulator";
- regulator-name = "8026_s1_corner";
+ regulator-name = "8226_s1_corner";
qcom,hpm-min-load = <100000>;
regulator-min-microvolt = <1>;
regulator-max-microvolt = <7>;
qcom,consumer-supplies = "vdd_dig", "";
};
+};
- pm8026_s2: regulator-s2 {
- compatible = "qcom,stub-regulator";
- regulator-name = "8026_s2";
- qcom,hpm-min-load = <100000>;
- regulator-min-microvolt = <1050000>;
- regulator-max-microvolt = <1050000>;
- };
+/* QPNP controlled regulators: */
- pm8026_s3: regulator-s3 {
- compatible = "qcom,stub-regulator";
- regulator-name = "8026_s3";
- qcom,hpm-min-load = <100000>;
- regulator-min-microvolt = <1300000>;
- regulator-max-microvolt = <1300000>;
- };
+&spmi_bus {
- pm8026_s4: regulator-s4 {
- compatible = "qcom,stub-regulator";
- regulator-name = "8026_s4";
- qcom,hpm-min-load = <100000>;
- regulator-min-microvolt = <2100000>;
- regulator-max-microvolt = <2100000>;
- };
+ qcom,pm8226@1 {
- pm8026_s5: regulator-s5 {
- compatible = "qcom,stub-regulator";
- regulator-name = "8026_s5";
- qcom,hpm-min-load = <100000>;
- regulator-min-microvolt = <1150000>;
- regulator-max-microvolt = <1150000>;
- };
+ pm8226_s1: regulator@1400 {
+ status = "okay";
+ regulator-name = "8226_s1";
+ qcom,enable-time = <500>;
+ qcom,system-load = <100000>;
+ regulator-always-on;
+ regulator-min-microvolt = <1287500>;
+ regulator-max-microvolt = <1287500>;
+ };
- pm8026_l1: regulator-l1 {
- compatible = "qcom,stub-regulator";
- regulator-name = "8026_l1";
- parent-supply = <&pm8026_s3>;
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1225000>;
- regulator-max-microvolt = <1225000>;
- };
+ pm8226_s2: regulator@1700 {
+ status = "okay";
+ regulator-name = "8226_s2";
+ qcom,enable-time = <500>;
+ qcom,system-load = <100000>;
+ regulator-always-on;
+ regulator-min-microvolt = <1150000>;
+ regulator-max-microvolt = <1150000>;
+ };
- pm8026_l2: regulator-l2 {
- compatible = "qcom,stub-regulator";
- regulator-name = "8026_l2";
- parent-supply = <&pm8026_s3>;
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1200000>;
- regulator-max-microvolt = <1200000>;
- };
+ pm8226_s3: regulator@1a00 {
+ status = "okay";
+ regulator-name = "8226_s3";
+ qcom,enable-time = <500>;
+ qcom,system-load = <100000>;
+ regulator-always-on;
+ regulator-min-microvolt = <1300000>;
+ regulator-max-microvolt = <1300000>;
+ };
- pm8026_l3: regulator-l3 {
- compatible = "qcom,stub-regulator";
- regulator-name = "8026_l3";
- parent-supply = <&pm8026_s3>;
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1150000>;
- regulator-max-microvolt = <1150000>;
- };
+ pm8226_s4: regulator@1d00 {
+ status = "okay";
+ regulator-name = "8226_s4";
+ qcom,enable-time = <500>;
+ qcom,system-load = <100000>;
+ regulator-always-on;
+ regulator-min-microvolt = <2100000>;
+ regulator-max-microvolt = <2100000>;
+ };
- pm8026_l4: regulator-l4 {
- compatible = "qcom,stub-regulator";
- regulator-name = "8026_l4";
- parent-supply = <&pm8026_s3>;
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1200000>;
- regulator-max-microvolt = <1200000>;
- };
+ pm8226_s5: regulator@2000 {
+ status = "okay";
+ regulator-name = "8226_s5";
+ qcom,enable-time = <500>;
+ regulator-min-microvolt = <1150000>;
+ regulator-max-microvolt = <1150000>;
+ };
- pm8026_l5: regulator-l5 {
- compatible = "qcom,stub-regulator";
- regulator-name = "8026_l5";
- parent-supply = <&pm8026_s3>;
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1200000>;
- regulator-max-microvolt = <1200000>;
- };
+ pm8226_l1: regulator@4000 {
+ status = "okay";
+ regulator-name = "8226_l1";
+ parent-supply = <&pm8226_s3>;
+ qcom,enable-time = <200>;
+ regulator-min-microvolt = <1225000>;
+ regulator-max-microvolt = <1225000>;
+ };
- pm8026_l6: regulator-l6 {
- compatible = "qcom,stub-regulator";
- regulator-name = "8026_l6";
- parent-supply = <&pm8026_s4>;
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
+ pm8226_l2: regulator@4100 {
+ status = "okay";
+ regulator-name = "8226_l2";
+ parent-supply = <&pm8226_s3>;
+ regulator-always-on;
+ qcom,enable-time = <200>;
+ qcom,system-load = <10000>;
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
- pm8026_l7: regulator-l7 {
- compatible = "qcom,stub-regulator";
- regulator-name = "8026_l7";
- parent-supply = <&pm8026_s4>;
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1850000>;
- regulator-max-microvolt = <1850000>;
- };
+ pm8226_l3: regulator@4200 {
+ status = "okay";
+ regulator-name = "8226_l3";
+ parent-supply = <&pm8226_s3>;
+ qcom,system-load = <10000>;
+ regulator-always-on;
+ qcom,enable-time = <200>;
+ regulator-min-microvolt = <1287500>;
+ regulator-max-microvolt = <1287500>;
+ };
- pm8026_l8: regulator-l8 {
- compatible = "qcom,stub-regulator";
- regulator-name = "8026_l8";
- parent-supply = <&pm8026_s4>;
- qcom,hpm-min-load = <5000>;
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- qcom,consumer-supplies = "vdd_sr2_pll", "";
- };
+ pm8226_l4: regulator@4300 {
+ status = "okay";
+ regulator-name = "8226_l4";
+ parent-supply = <&pm8226_s3>;
+ qcom,enable-time = <200>;
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
- pm8026_l9: regulator-l9 {
- compatible = "qcom,stub-regulator";
- regulator-name = "8026_l9";
- parent-supply = <&pm8026_s4>;
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <2050000>;
- regulator-max-microvolt = <2050000>;
- };
+ pm8226_l5: regulator@4400 {
+ status = "okay";
+ regulator-name = "8226_l5";
+ parent-supply = <&pm8226_s3>;
+ qcom,enable-time = <200>;
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
- pm8026_l10: regulator-l10 {
- compatible = "qcom,stub-regulator";
- regulator-name = "8026_l10";
- parent-supply = <&pm8026_s4>;
- qcom,hpm-min-load = <5000>;
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
+ pm8226_l6: regulator@4500 {
+ status = "okay";
+ regulator-name = "8226_l6";
+ parent-supply = <&pm8226_s4>;
+ qcom,system-load = <10000>;
+ regulator-always-on;
+ qcom,enable-time = <200>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
- pm8026_l12: regulator-l12 {
- compatible = "qcom,stub-regulator";
- regulator-name = "8026_l12";
- qcom,hpm-min-load = <5000>;
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
+ pm8226_l7: regulator@4600 {
+ status = "okay";
+ regulator-name = "8226_l7";
+ parent-supply = <&pm8226_s4>;
+ qcom,enable-time = <200>;
+ regulator-min-microvolt = <1850000>;
+ regulator-max-microvolt = <1850000>;
+ };
- pm8026_l14: regulator-l14 {
- compatible = "qcom,stub-regulator";
- regulator-name = "8026_l14";
- qcom,hpm-min-load = <5000>;
- regulator-min-microvolt = <2750000>;
- regulator-max-microvolt = <2750000>;
- };
+ pm8226_l8: regulator@4700 {
+ status = "okay";
+ regulator-name = "8226_l8";
+ parent-supply = <&pm8226_s4>;
+ qcom,enable-time = <200>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,consumer-supplies = "vdd_sr2_pll", "";
+ };
- pm8026_l15: regulator-l15 {
- compatible = "qcom,stub-regulator";
- regulator-name = "8026_l15";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <2800000>;
- regulator-max-microvolt = <2800000>;
- };
+ pm8226_l9: regulator@4800 {
+ status = "okay";
+ regulator-name = "8226_l9";
+ parent-supply = <&pm8226_s4>;
+ qcom,enable-time = <200>;
+ regulator-min-microvolt = <2050000>;
+ regulator-max-microvolt = <2050000>;
+ };
- pm8026_l16: regulator-l16 {
- compatible = "qcom,stub-regulator";
- regulator-name = "8026_l16";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <3000000>;
- regulator-max-microvolt = <3000000>;
- };
+ pm8226_l10: regulator@4900 {
+ status = "okay";
+ regulator-name = "8226_l10";
+ parent-supply = <&pm8226_s4>;
+ qcom,enable-time = <200>;
+ qcom,system-load = <5000>;
+ regulator-always-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
- pm8026_l17: regulator-l17 {
- compatible = "qcom,stub-regulator";
- regulator-name = "8026_l17";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <2950000>;
- regulator-max-microvolt = <2950000>;
- };
+ pm8226_l12: regulator@4b00 {
+ status = "okay";
+ regulator-name = "8226_l12";
+ qcom,enable-time = <200>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
- pm8026_l18: regulator-l18 {
- compatible = "qcom,stub-regulator";
- regulator-name = "8026_l18";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <2950000>;
- regulator-max-microvolt = <2950000>;
- };
+ pm8226_l14: regulator@4d00 {
+ status = "okay";
+ regulator-name = "8226_l14";
+ qcom,enable-time = <200>;
+ regulator-min-microvolt = <2750000>;
+ regulator-max-microvolt = <2750000>;
+ };
- pm8026_l19: regulator-l19 {
- compatible = "qcom,stub-regulator";
- regulator-name = "8026_l19";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <2850000>;
- regulator-max-microvolt = <2850000>;
- };
+ pm8226_l15: regulator@4e00 {
+ status = "okay";
+ regulator-name = "8226_l15";
+ qcom,enable-time = <200>;
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
- pm8026_l20: regulator-l20 {
- compatible = "qcom,stub-regulator";
- regulator-name = "8026_l20";
- qcom,hpm-min-load = <5000>;
- regulator-min-microvolt = <3075000>;
- regulator-max-microvolt = <3075000>;
- };
+ pm8226_l16: regulator@4f00 {
+ status = "okay";
+ regulator-name = "8226_l16";
+ qcom,enable-time = <200>;
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3300000>;
+ };
- pm8026_l21: regulator-l21 {
- compatible = "qcom,stub-regulator";
- regulator-name = "8026_l21";
- qcom,hpm-min-load = <5000>;
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <2950000>;
- };
+ pm8226_l17: regulator@5000 {
+ status = "okay";
+ regulator-name = "8226_l17";
+ qcom,enable-time = <200>;
+ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ };
- pm8026_l22: regulator-l22 {
- compatible = "qcom,stub-regulator";
- regulator-name = "8026_l22";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <2950000>;
- };
+ pm8226_l18: regulator@5100 {
+ status = "okay";
+ regulator-name = "8226_l18";
+ qcom,enable-time = <200>;
+ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ };
- pm8026_l23: regulator-l23 {
- compatible = "qcom,stub-regulator";
- regulator-name = "8026_l23";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <2950000>;
- };
+ pm8226_l19: regulator@5200 {
+ status = "okay";
+ regulator-name = "8226_l19";
+ qcom,enable-time = <200>;
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ };
- pm8026_l24: regulator-l24 {
- compatible = "qcom,stub-regulator";
- regulator-name = "8026_l24";
- parent-supply = <&pm8026_s3>;
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1300000>;
- regulator-max-microvolt = <1300000>;
- };
+ pm8226_l20: regulator@5300 {
+ status = "okay";
+ regulator-name = "8226_l20";
+ qcom,enable-time = <200>;
+ regulator-min-microvolt = <3075000>;
+ regulator-max-microvolt = <3075000>;
+ };
- pm8026_l26: regulator-l26 {
- compatible = "qcom,stub-regulator";
- regulator-name = "8026_l26";
- parent-supply = <&pm8026_s3>;
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1225000>;
- regulator-max-microvolt = <1225000>;
- };
+ pm8226_l21: regulator@5400 {
+ status = "okay";
+ regulator-name = "8226_l21";
+ qcom,enable-time = <200>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2950000>;
+ };
- pm8026_l27: regulator-l27 {
- compatible = "qcom,stub-regulator";
- regulator-name = "8026_l27";
- parent-supply = <&pm8026_s4>;
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <2050000>;
- regulator-max-microvolt = <2050000>;
- };
+ pm8226_l22: regulator@5500 {
+ status = "okay";
+ regulator-name = "8226_l22";
+ qcom,enable-time = <200>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2950000>;
+ };
- pm8026_l28: regulator-l28 {
- compatible = "qcom,stub-regulator";
- regulator-name = "8026_l28";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <2950000>;
- };
+ pm8226_l23: regulator@5600 {
+ status = "okay";
+ regulator-name = "8226_l23";
+ qcom,enable-time = <200>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2950000>;
+ };
- pm8026_lvs1: regulator-lvs1 {
- compatible = "qcom,stub-regulator";
- regulator-name = "8026_lvs1";
- parent-supply = <&pm8026_l6>;
+ pm8226_l24: regulator@5700 {
+ status = "okay";
+ regulator-name = "8226_l24";
+ parent-supply = <&pm8226_s3>;
+ qcom,enable-time = <200>;
+ regulator-min-microvolt = <1300000>;
+ regulator-max-microvolt = <1300000>;
+ };
+
+ pm8226_l26: regulator@5900 {
+ status = "okay";
+ regulator-name = "8226_l26";
+ parent-supply = <&pm8226_s3>;
+ qcom,enable-time = <200>;
+ regulator-min-microvolt = <1225000>;
+ regulator-max-microvolt = <1225000>;
+ };
+
+ pm8226_l27: regulator@5a00 {
+ status = "okay";
+ regulator-name = "8226_l27";
+ parent-supply = <&pm8226_s4>;
+ qcom,enable-time = <200>;
+ regulator-min-microvolt = <2050000>;
+ regulator-max-microvolt = <2050000>;
+ };
+
+ pm8226_l28: regulator@5b00 {
+ status = "okay";
+ regulator-name = "8226_l28";
+ qcom,enable-time = <200>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2950000>;
+ };
+
+ pm8226_lvs1: regulator@8000 {
+ status = "okay";
+ regulator-name = "8226_lvs1";
+ parent-supply = <&pm8226_l6>;
+ qcom,enable-time = <200>;
+ };
};
};
diff --git a/arch/arm/boot/dts/msm8226-sim.dts b/arch/arm/boot/dts/msm8226-sim.dts
index 9a0ec17..f9ab957 100644
--- a/arch/arm/boot/dts/msm8226-sim.dts
+++ b/arch/arm/boot/dts/msm8226-sim.dts
@@ -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
@@ -39,8 +39,8 @@
qcom,pad-drv-on = <0x7 0x4 0x4>; /* 16mA, 10mA, 10mA */
qcom,pad-drv-off = <0x0 0x0 0x0>; /* 2mA, 2mA, 2mA */
- vdd-supply = <&pm8026_l17>;
- vdd-io-supply = <&pm8026_l6>;
+ vdd-supply = <&pm8226_l17>;
+ vdd-io-supply = <&pm8226_l6>;
qcom,clk-rates = <400000 25000000 50000000 100000000 200000000>;
qcom,sup-voltages = <2950 2950>;
@@ -50,8 +50,8 @@
};
&sdcc2 {
- vdd-supply = <&pm8026_l18>;
- vdd-io-supply = <&pm8026_l21>;
+ vdd-supply = <&pm8226_l18>;
+ vdd-io-supply = <&pm8226_l21>;
qcom,vdd-voltage-level = <2950000 2950000>;
qcom,vdd-current-level = <9000 800000>;
@@ -74,3 +74,57 @@
status = "ok";
};
+
+&pm8226_gpios {
+ gpio@c000 { /* GPIO 1 */
+ };
+
+ gpio@c100 { /* GPIO 2 */
+ };
+
+ gpio@c200 { /* GPIO 3 */
+ };
+
+ gpio@c300 { /* GPIO 4 */
+ };
+
+ gpio@c400 { /* GPIO 5 */
+ };
+
+ gpio@c500 { /* GPIO 6 */
+ };
+
+ gpio@c600 { /* GPIO 7 */
+ };
+
+ gpio@c700 { /* GPIO 8 */
+ };
+};
+
+&pm8226_mpps {
+ mpp@a000 { /* MPP 1 */
+ };
+
+ mpp@a100 { /* MPP 2 */
+ };
+
+ mpp@a200 { /* MPP 3 */
+ };
+
+ mpp@a300 { /* MPP 4 */
+ };
+
+ mpp@a400 { /* MPP 5 */
+ };
+
+ mpp@a500 { /* MPP 6 */
+ };
+
+ mpp@a600 { /* MPP 7 */
+ };
+
+ mpp@a700 { /* MPP 8 */
+ };
+};
+
+
diff --git a/arch/arm/boot/dts/msm8226.dtsi b/arch/arm/boot/dts/msm8226.dtsi
index cb33a40..3ae69fd 100644
--- a/arch/arm/boot/dts/msm8226.dtsi
+++ b/arch/arm/boot/dts/msm8226.dtsi
@@ -17,6 +17,7 @@
/include/ "msm8226-pm.dtsi"
/include/ "msm8226-smp2p.dtsi"
/include/ "msm8226-gpu.dtsi"
+/include/ "msm8226-bus.dtsi"
/ {
model = "Qualcomm MSM 8226";
@@ -80,9 +81,9 @@
reg = <0xf9a55000 0x400>;
interrupts = <0 134 0>, <0 140 0>;
interrupt-names = "core_irq", "async_irq";
- HSUSB_VDDCX-supply = <&pm8026_s1>;
- HSUSB_1p8-supply = <&pm8026_l10>;
- HSUSB_3p3-supply = <&pm8026_l20>;
+ HSUSB_VDDCX-supply = <&pm8226_s1>;
+ HSUSB_1p8-supply = <&pm8226_l10>;
+ HSUSB_3p3-supply = <&pm8226_l20>;
qcom,hsusb-otg-phy-type = <2>;
qcom,hsusb-otg-mode = <1>;
@@ -122,23 +123,23 @@
17 18 19 20 21 22 23 24 25 26 27 28>;
qcom,cdc-reset-gpio = <&msmgpio 72 0>;
- cdc-vdd-buck-supply = <&pm8026_s4>;
+ cdc-vdd-buck-supply = <&pm8226_s4>;
qcom,cdc-vdd-buck-voltage = <2100000 2100000>;
qcom,cdc-vdd-buck-current = <650000>;
- cdc-vdd-h-supply = <&pm8026_l6>;
+ cdc-vdd-h-supply = <&pm8226_l6>;
qcom,cdc-vdd-h-voltage = <1800000 1800000>;
qcom,cdc-vdd-h-current = <25000>;
- cdc-vdd-px-supply = <&pm8026_l6>;
+ cdc-vdd-px-supply = <&pm8226_l6>;
qcom,cdc-vdd-px-voltage = <1800000 1800000>;
qcom,cdc-vdd-px-current = <25000>;
- cdc-vdd-a-1p2v-supply = <&pm8026_l4>;
+ cdc-vdd-a-1p2v-supply = <&pm8226_l4>;
qcom,cdc-vdd-a-1p2v-voltage = <1200000 1200000>;
qcom,cdc-vdd-a-1p2v-current = <10000>;
- cdc-vdd-cx-supply = <&pm8026_l4>;
+ cdc-vdd-cx-supply = <&pm8226_l4>;
qcom,cdc-vdd-cx-voltage = <1200000 1200000>;
qcom,cdc-vdd-cx-current = <10000>;
@@ -465,8 +466,8 @@
compatible = "qcom,acpuclk-a7";
reg = <0xf9011050 0x8>;
reg-names = "rcg_base";
- a7_cpu-supply = <&pm8026_s2>;
- a7_mem-supply = <&pm8026_l3>;
+ a7_cpu-supply = <&pm8226_s2>;
+ a7_mem-supply = <&pm8226_l3>;
};
qcom,ocmem@fdd00000 {
@@ -509,7 +510,7 @@
<0xfd485300 0xc>;
reg-names = "pmu_base", "clk_base", "halt_base";
interrupts = <0 149 1>;
- vdd_pronto_pll-supply = <&pm8026_l8>;
+ vdd_pronto_pll-supply = <&pm8226_l8>;
qcom,firmware-name = "wcnss";
};
@@ -528,6 +529,17 @@
compatible = "qcom,msm-mem-hole";
qcom,memblock-remove = <0x8100000 0x7e00000>; /* Address and Size of Hole */
};
+
+ tsens: tsens@fc4a8000 {
+ compatible = "qcom,msm-tsens";
+ reg = <0xfc4a8000 0x2000>,
+ <0xfc4b8000 0x1000>;
+ reg-names = "tsens_physical", "tsens_eeprom_physical";
+ interrupts = <0 184 0>;
+ qcom,sensors = <7>;
+ qcom,slope = <3200 3200 3200 3200 3200 3200 3200>;
+ qcom,calib-mode = "fuse_map2";
+ };
};
&gdsc_venus {
@@ -554,5 +566,5 @@
status = "ok";
};
-/include/ "msm8226-regulator.dtsi"
/include/ "msm-pm8226.dtsi"
+/include/ "msm8226-regulator.dtsi"
diff --git a/arch/arm/boot/dts/msm8974-cdp.dtsi b/arch/arm/boot/dts/msm8974-cdp.dtsi
index 6b902d7..16883ef 100644
--- a/arch/arm/boot/dts/msm8974-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8974-cdp.dtsi
@@ -45,6 +45,7 @@
atmel,panel-coords = <0 0 760 1424>;
atmel,display-coords = <0 0 720 1280>;
atmel,i2c-pull-up;
+ atmel,no-force-update;
atmel,cfg_1 {
atmel,family-id = <0x82>;
atmel,variant-id = <0x19>;
@@ -533,3 +534,11 @@
mpp@a300 { /* MPP 4 */
};
};
+
+&slim_msm {
+ taiko_codec {
+ qcom,cdc-micbias1-ext-cap;
+ qcom,cdc-micbias3-ext-cap;
+ qcom,cdc-micbias4-ext-cap;
+ };
+};
diff --git a/arch/arm/boot/dts/msm8974-fluid.dtsi b/arch/arm/boot/dts/msm8974-fluid.dtsi
index a6086f0..11c835f 100644
--- a/arch/arm/boot/dts/msm8974-fluid.dtsi
+++ b/arch/arm/boot/dts/msm8974-fluid.dtsi
@@ -40,6 +40,7 @@
atmel,panel-coords = <0 0 760 1424>;
atmel,display-coords = <0 0 720 1280>;
atmel,i2c-pull-up;
+ atmel,no-force-update;
atmel,cfg_1 {
atmel,family-id = <0x82>;
atmel,variant-id = <0x19>;
@@ -206,7 +207,10 @@
&slim_msm {
taiko_codec {
+ qcom,cdc-micbias1-ext-cap;
qcom,cdc-micbias2-ext-cap;
+ qcom,cdc-micbias3-ext-cap;
+ qcom,cdc-micbias4-ext-cap;
};
};
diff --git a/arch/arm/boot/dts/msm8974-gpu.dtsi b/arch/arm/boot/dts/msm8974-gpu.dtsi
index 2751d76..ef4f611 100644
--- a/arch/arm/boot/dts/msm8974-gpu.dtsi
+++ b/arch/arm/boot/dts/msm8974-gpu.dtsi
@@ -36,7 +36,7 @@
qcom,msm-bus,num-paths = <2>;
qcom,msm-bus,vectors-KBps =
<26 512 0 0>, <89 604 0 0>,
- <26 512 0 1600000>, <89 604 0 3000000>,
+ <26 512 0 2200000>, <89 604 0 3000000>,
<26 512 0 4000000>, <89 604 0 4500000>,
<26 512 0 6400000>, <89 604 0 7600000>;
diff --git a/arch/arm/boot/dts/msm8974-liquid.dtsi b/arch/arm/boot/dts/msm8974-liquid.dtsi
index fb17449..e97678a 100644
--- a/arch/arm/boot/dts/msm8974-liquid.dtsi
+++ b/arch/arm/boot/dts/msm8974-liquid.dtsi
@@ -265,8 +265,8 @@
hsic@f9a00000 {
compatible = "qcom,hsic-host";
reg = <0xf9a00000 0x400>;
- interrupts = <0 136 0>;
- interrupt-names = "core_irq";
+ interrupts = <0 136 0>, <0 148 0>;
+ interrupt-names = "core_irq", "async_irq";
HSIC_VDDCX-supply = <&pm8841_s2>;
HSIC_GDSC-supply = <&gdsc_usb_hsic>;
hsic,strobe-gpio = <&msmgpio 144 0x00>;
@@ -282,6 +282,14 @@
qcom,memory-reservation-size = <0x1000000>; /* size 16MB */
};
+&uart7 {
+ status = "ok";
+ qcom,tx-gpio = <&msmgpio 41 0x00>;
+ qcom,rx-gpio = <&msmgpio 42 0x00>;
+ qcom,cts-gpio = <&msmgpio 43 0x00>;
+ qcom,rfr-gpio = <&msmgpio 44 0x00>;
+};
+
&usb3 {
qcom,charging-disabled;
};
@@ -577,6 +585,7 @@
&slim_msm {
taiko_codec {
qcom,cdc-micbias2-ext-cap;
+ qcom,cdc-micbias3-ext-cap;
};
};
diff --git a/arch/arm/boot/dts/msm8974-mtp.dtsi b/arch/arm/boot/dts/msm8974-mtp.dtsi
index b2d320c..e21610b 100644
--- a/arch/arm/boot/dts/msm8974-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8974-mtp.dtsi
@@ -40,6 +40,7 @@
atmel,panel-coords = <0 0 760 1424>;
atmel,display-coords = <0 0 720 1280>;
atmel,i2c-pull-up;
+ atmel,no-force-update;
atmel,cfg_1 {
atmel,family-id = <0x82>;
atmel,variant-id = <0x19>;
@@ -511,7 +512,9 @@
&slim_msm {
taiko_codec {
+ qcom,cdc-micbias1-ext-cap;
qcom,cdc-micbias2-ext-cap;
+ qcom,cdc-micbias4-ext-cap;
};
};
diff --git a/arch/arm/boot/dts/msm8974-smp2p.dtsi b/arch/arm/boot/dts/msm8974-smp2p.dtsi
index 60f63a8..511f91f 100644
--- a/arch/arm/boot/dts/msm8974-smp2p.dtsi
+++ b/arch/arm/boot/dts/msm8974-smp2p.dtsi
@@ -103,29 +103,6 @@
gpios = <&smp2pgpio_smp2p_1_out 0 0>;
};
- /* SMP2P SSR Driver for inbound entry from modem. */
- smp2pgpio_ssr_smp2p_1_in: qcom,smp2pgpio-ssr-smp2p-1-in {
- compatible = "qcom,smp2pgpio";
- qcom,entry-name = "slave-kernel";
- qcom,remote-pid = <1>;
- qcom,is-inbound;
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- };
-
- /* SMP2P SSR Driver for outbound entry to modem */
- smp2pgpio_ssr_smp2p_1_out: qcom,smp2pgpio-ssr-smp2p-1-out {
- compatible = "qcom,smp2pgpio";
- qcom,entry-name = "master-kernel";
- qcom,remote-pid = <1>;
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- };
-
/* SMP2P Test Driver for adsp inbound */
smp2pgpio_smp2p_2_in: qcom,smp2pgpio-smp2p-2-in {
compatible = "qcom,smp2pgpio";
diff --git a/arch/arm/boot/dts/msm8974-pm.dtsi b/arch/arm/boot/dts/msm8974-v1-pm.dtsi
similarity index 100%
rename from arch/arm/boot/dts/msm8974-pm.dtsi
rename to arch/arm/boot/dts/msm8974-v1-pm.dtsi
diff --git a/arch/arm/boot/dts/msm8974-v1.dtsi b/arch/arm/boot/dts/msm8974-v1.dtsi
index eb69c51..7930547 100644
--- a/arch/arm/boot/dts/msm8974-v1.dtsi
+++ b/arch/arm/boot/dts/msm8974-v1.dtsi
@@ -18,6 +18,7 @@
/include/ "msm8974.dtsi"
/include/ "msm8974-v1-iommu.dtsi"
+/include/ "msm8974-v1-pm.dtsi"
/ {
android_usb@fc42b0c8 {
diff --git a/arch/arm/boot/dts/msm8974-v2-iommu.dtsi b/arch/arm/boot/dts/msm8974-v2-iommu.dtsi
index 500f1de..584869d 100644
--- a/arch/arm/boot/dts/msm8974-v2-iommu.dtsi
+++ b/arch/arm/boot/dts/msm8974-v2-iommu.dtsi
@@ -41,8 +41,8 @@
0x2034
0x2038>;
- qcom,iommu-bfb-data = <0x1FFFFFF
- 0x0
+ qcom,iommu-bfb-data = <0xFFFFFFFF
+ 0xFFFFFFFF
0x00000004
0x00000008
0x00000000
@@ -119,7 +119,7 @@
0x0
0x10
0x50
- 0x00002000
+ 0x0
0x00002804
0x00009614
0x0
@@ -233,7 +233,7 @@
0x0
0x20
0x78
- 0x00004000
+ 0x0
0x00003c08
0x0000b41e
0x0
diff --git a/arch/arm/boot/dts/msm8974-v2-pm.dtsi b/arch/arm/boot/dts/msm8974-v2-pm.dtsi
new file mode 100644
index 0000000..0ed55ff
--- /dev/null
+++ b/arch/arm/boot/dts/msm8974-v2-pm.dtsi
@@ -0,0 +1,426 @@
+/* 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/ "skeleton.dtsi"
+
+/ {
+ qcom,spm@f9089000 {
+ compatible = "qcom,spm-v2";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xf9089000 0x1000>;
+ qcom,core-id = <0>;
+ qcom,saw2-ver-reg = <0xfd0>;
+ qcom,saw2-cfg = <0x01>;
+ qcom,saw2-avs-ctl = <0>;
+ qcom,saw2-avs-hysteresis = <0>;
+ qcom,saw2-avs-limit = <0>;
+ qcom,saw2-avs-dly= <0>;
+ qcom,saw2-spm-dly= <0x20000400>;
+ qcom,saw2-spm-ctl = <0x1>;
+ qcom,saw2-spm-cmd-wfi = [03 0b 0f];
+ qcom,saw2-spm-cmd-ret = [42 1b 00 d0 03 d4 5b 0b 00 42 1b 0f];
+ qcom,saw2-spm-cmd-spc = [00 20 50 80 60 70 10 E0 03 6E 70 3B
+ E4 5B 82 2B 50 10 0B 30 06 26 30 0F];
+ qcom,saw2-spm-cmd-pc = [00 20 50 80 60 70 10 E0 07 6E 70 3B
+ E4 5B 82 2B 50 10 0B 30 06 26 30 0F];
+ };
+
+ qcom,spm@f9099000 {
+ compatible = "qcom,spm-v2";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xf9099000 0x1000>;
+ qcom,core-id = <1>;
+ qcom,saw2-ver-reg = <0xfd0>;
+ qcom,saw2-cfg = <0x01>;
+ qcom,saw2-avs-ctl = <0>;
+ qcom,saw2-avs-hysteresis = <0>;
+ qcom,saw2-avs-limit = <0>;
+ qcom,saw2-avs-dly= <0>;
+ qcom,saw2-spm-dly= <0x20000400>;
+ qcom,saw2-spm-ctl = <0x1>;
+ qcom,saw2-spm-cmd-wfi = [03 0b 0f];
+ qcom,saw2-spm-cmd-ret = [42 1b 00 d0 03 d4 5b 0b 00 42 1b 0f];
+ qcom,saw2-spm-cmd-spc = [00 20 50 80 60 70 10 E0 03 6E 70 3B
+ E4 5B 82 2B 50 10 0B 30 06 26 30 0F];
+ qcom,saw2-spm-cmd-pc = [00 20 50 80 60 70 10 E0 07 6E 70 3B
+ E4 5B 82 2B 50 10 0B 30 06 26 30 0F];
+ };
+
+ qcom,spm@f90a9000 {
+ compatible = "qcom,spm-v2";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xf90a9000 0x1000>;
+ qcom,core-id = <2>;
+ qcom,saw2-ver-reg = <0xfd0>;
+ qcom,saw2-cfg = <0x01>;
+ qcom,saw2-avs-ctl = <0>;
+ qcom,saw2-avs-hysteresis = <0>;
+ qcom,saw2-avs-limit = <0>;
+ qcom,saw2-avs-dly= <0>;
+ qcom,saw2-spm-dly= <0x20000400>;
+ qcom,saw2-spm-ctl = <0x1>;
+ qcom,saw2-spm-cmd-wfi = [03 0b 0f];
+ qcom,saw2-spm-cmd-ret = [42 1b 00 d0 03 d4 5b 0b 00 42 1b 0f];
+ qcom,saw2-spm-cmd-spc = [00 20 50 80 60 70 10 E0 03 6E 70 3B
+ E4 5B 82 2B 50 10 0B 30 06 26 30 0F];
+ qcom,saw2-spm-cmd-pc = [00 20 50 80 60 70 10 E0 07 6E 70 3B
+ E4 5B 82 2B 50 10 0B 30 06 26 30 0F];
+ };
+
+ qcom,spm@f90b9000 {
+ compatible = "qcom,spm-v2";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xf90b9000 0x1000>;
+ qcom,core-id = <3>;
+ qcom,saw2-ver-reg = <0xfd0>;
+ qcom,saw2-cfg = <0x01>;
+ qcom,saw2-avs-ctl = <0>;
+ qcom,saw2-avs-hysteresis = <0>;
+ qcom,saw2-avs-limit = <0>;
+ qcom,saw2-avs-dly= <0>;
+ qcom,saw2-spm-dly= <0x20000400>;
+ qcom,saw2-spm-ctl = <0x1>;
+ qcom,saw2-spm-cmd-wfi = [03 0b 0f];
+ qcom,saw2-spm-cmd-ret = [42 1b 00 d0 03 d4 5b 0b 00 42 1b 0f];
+ qcom,saw2-spm-cmd-spc = [00 20 50 80 60 70 10 E0 03 6E 70 3B
+ E4 5B 82 2B 50 10 0B 30 06 26 30 0F];
+ qcom,saw2-spm-cmd-pc = [00 20 50 80 60 70 10 E0 07 6E 70 3B
+ E4 5B 82 2B 50 10 0B 30 06 26 30 0F];
+ };
+
+ qcom,spm@f9012000 {
+ compatible = "qcom,spm-v2";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xf9012000 0x1000>;
+ qcom,core-id = <0xffff>; /* L2/APCS SAW */
+ qcom,saw2-ver-reg = <0xfd0>;
+ qcom,saw2-cfg = <0x14>;
+ qcom,saw2-avs-ctl = <0>;
+ qcom,saw2-avs-hysteresis = <0>;
+ qcom,saw2-avs-limit = <0>;
+ qcom,saw2-avs-dly= <0>;
+ qcom,saw2-spm-dly= <0x20000400>;
+ qcom,saw2-spm-ctl = <0x1>;
+ qcom,saw2-pmic-data0 = <0x02030080>;
+ qcom,saw2-pmic-data1 = <0x00030000>;
+ qcom,vctl-timeout-us = <50>;
+ qcom,vctl-port = <0x0>;
+ qcom,phase-port = <0x1>;
+ qcom,pfm-port = <0x2>;
+ qcom,saw2-spm-cmd-ret = [1f 00 20 03 22 00 0f];
+ qcom,saw2-spm-cmd-gdhs = [00 20 32 60 70 80 42 07 78 80 44 22 50
+ 3b 60 02 32 50 0f];
+ qcom,saw2-spm-cmd-pc = [00 10 32 60 70 80 b0 11 42 07 01 b0 78
+ 80 12 44 50 3b 60 02 32 50 0f];
+ };
+
+ qcom,lpm-resources {
+ compatible = "qcom,lpm-resources";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,lpm-resources@0 {
+ reg = <0x0>;
+ qcom,name = "vdd-dig";
+ qcom,resource-type = <0>;
+ qcom,type = <0x62706d73>; /* "smpb" */
+ qcom,id = <0x02>;
+ qcom,key = <0x6e726f63>; /* "corn" */
+ qcom,init-value = <5>; /* Super Turbo */
+ };
+
+ qcom,lpm-resources@1 {
+ reg = <0x1>;
+ qcom,name = "vdd-mem";
+ qcom,resource-type = <0>;
+ qcom,type = <0x62706d73>; /* "smpb" */
+ qcom,id = <0x01>;
+ qcom,key = <0x7675>; /* "uv" */
+ qcom,init-value = <1050000>; /* Super Turbo */
+ };
+
+ qcom,lpm-resources@2 {
+ reg = <0x2>;
+ qcom,name = "pxo";
+ qcom,resource-type = <0>;
+ qcom,type = <0x306b6c63>; /* "clk0" */
+ qcom,id = <0x00>;
+ qcom,key = <0x62616e45>; /* "Enab" */
+ qcom,init-value = <1>; /* On */
+ };
+
+ qcom,lpm-resources@3 {
+ reg = <0x3>;
+ qcom,name = "l2";
+ qcom,resource-type = <1>;
+ qcom,init-value = <2>; /* Retention */
+ };
+ };
+
+ qcom,lpm-levels {
+ compatible = "qcom,lpm-levels";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,lpm-level@0 {
+ reg = <0x0>;
+ qcom,mode = <0>; /* MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT */
+ qcom,xo = <1>; /* ON */
+ qcom,l2 = <2>; /* Retention */
+ 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,irqs-detectable;
+ qcom.gpios-detectable;
+ qcom,latency-us = <1>;
+ qcom,ss-power = <784>;
+ qcom,energy-overhead = <190000>;
+ qcom,time-overhead = <100>;
+ };
+
+ qcom,lpm-level@1 {
+ reg = <0x1>;
+ qcom,mode = <4>; /* MSM_PM_SLEEP_MODE_RETENTION*/
+ qcom,xo = <1>; /* ON */
+ qcom,l2 = <2>; /* Retention */
+ 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,irqs-detectable;
+ qcom.gpios-detectable;
+ qcom,latency-us = <75>;
+ qcom,ss-power = <735>;
+ qcom,energy-overhead = <77341>;
+ 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,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,irqs-detectable;
+ qcom.gpios-detectable;
+ qcom,latency-us = <95>;
+ qcom,ss-power = <725>;
+ qcom,energy-overhead = <99500>;
+ qcom,time-overhead = <130>;
+ };
+
+ qcom,lpm-level@3 {
+ reg = <0x3>;
+ qcom,mode = <3>; /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
+ qcom,xo = <1>; /* ON */
+ qcom,l2 = <1>; /* GDHS */
+ 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,irqs-detectable;
+ qcom.gpios-detectable;
+ qcom,latency-us = <2000>;
+ qcom,ss-power = <138>;
+ qcom,energy-overhead = <1208400>;
+ qcom,time-overhead = <3200>;
+ };
+
+ qcom,lpm-level@4 {
+ reg = <0x4>;
+ qcom,mode = <3>; /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
+ qcom,xo = <1>; /* ON */
+ qcom,l2 = <1>; /* GDHS */
+ qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
+ qcom,vdd-mem-lower-bound = <950000>; /* SVS SOC */
+ qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
+ qcom,vdd-dig-lower-bound = <3>; /* SVS SOC */
+ qcom,irqs-detectable;
+ qcom.gpios-detectable;
+ qcom,latency-us = <3000>;
+ qcom,ss-power = <110>;
+ qcom,energy-overhead = <1250300>;
+ qcom,time-overhead = <3500>;
+ };
+
+ qcom,lpm-level@5 {
+ reg = <0x5>;
+ qcom,mode = <3>; /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
+ qcom,xo = <0>; /* OFF */
+ qcom,l2 = <1>; /* GDHS */
+ 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 = <3000>;
+ qcom,ss-power = <68>;
+ qcom,energy-overhead = <1350200>;
+ qcom,time-overhead = <4000>;
+ };
+
+ qcom,lpm-level@6 {
+ reg = <0x6>;
+ qcom,mode= <3>; /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
+ qcom,xo = <0>; /* OFF */
+ qcom,l2 = <1>; /* GDHS */
+ qcom,vdd-mem-upper-bound = <950000>; /* NORMAL */
+ qcom,vdd-mem-lower-bound = <950000>; /* SVS SOC */
+ qcom,vdd-dig-upper-bound = <4>; /* NORMAL */
+ qcom,vdd-dig-lower-bound = <3>; /* SVS SOC */
+ qcom,latency-us = <18000>;
+ qcom,ss-power = <10>;
+ qcom,energy-overhead = <3202600>;
+ qcom,time-overhead = <27000>;
+ };
+
+ qcom,lpm-level@7 {
+ reg = <0x7>;
+ qcom,mode= <3>; /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
+ qcom,xo = <0>; /* OFF */
+ qcom,l2 = <0>; /* OFF */
+ qcom,vdd-mem-upper-bound = <950000>; /* SVS SOC */
+ qcom,vdd-mem-lower-bound = <675000>; /* RETENTION */
+ qcom,vdd-dig-upper-bound = <3>; /* SVS SOC */
+ qcom,vdd-dig-lower-bound = <1>; /* RETENTION */
+ qcom,latency-us = <20000>;
+ qcom,ss-power = <2>;
+ qcom,energy-overhead = <4252000>;
+ qcom,time-overhead = <32000>;
+ };
+ };
+
+ qcom,pm-boot {
+ compatible = "qcom,pm-boot";
+ qcom,mode = <0>; /* MSM_PM_BOOT_CONFIG_TZ */
+ };
+
+ qcom,mpm@fc4281d0 {
+ compatible = "qcom,mpm-v2";
+ reg = <0xfc4281d0 0x1000>, /* MSM_RPM_MPM_BASE 4K */
+ <0xf9011008 0x4>; /* MSM_APCS_GCC_BASE 4K */
+ reg-names = "vmpm", "ipc";
+ interrupts = <0 171 1>;
+
+ qcom,ipc-bit-offset = <1>;
+
+ qcom,gic-parent = <&intc>;
+ qcom,gic-map = <47 172>, /* usb2_hsic_async_wakeup_irq */
+ <53 104>, /* mdss_irq */
+ <62 222>, /* ee0_krait_hlos_spmi_periph_irq */
+ <0xff 57>, /* mss_to_apps_irq(0) */
+ <0xff 58>, /* mss_to_apps_irq(1) */
+ <0xff 59>, /* mss_to_apps_irq(2) */
+ <0xff 60>, /* mss_to_apps_irq(3) */
+ <0xff 173>, /* o_wcss_apss_smd_hi */
+ <0xff 174>, /* o_wcss_apss_smd_med */
+ <0xff 175>, /* o_wcss_apss_smd_low */
+ <0xff 176>, /* o_wcss_apss_smsm_irq */
+ <0xff 177>, /* o_wcss_apss_wlan_data_xfer_done */
+ <0xff 178>, /* o_wcss_apss_wlan_rx_data_avail */
+ <0xff 179>, /* o_wcss_apss_asic_intr
+
+ <0xff 188>, /* lpass_irq_out_apcs(0) */
+ <0xff 189>, /* lpass_irq_out_apcs(1) */
+ <0xff 190>, /* lpass_irq_out_apcs(2) */
+ <0xff 191>, /* lpass_irq_out_apcs(3) */
+ <0xff 192>, /* lpass_irq_out_apcs(4) */
+ <0xff 193>, /* lpass_irq_out_apcs(5) */
+ <0xff 194>, /* lpass_irq_out_apcs(6) */
+ <0xff 195>, /* lpass_irq_out_apcs(7) */
+ <0xff 196>, /* lpass_irq_out_apcs(8) */
+ <0xff 197>, /* lpass_irq_out_apcs(9) */
+ <0xff 200>, /* rpm_ipc(4) */
+ <0xff 201>, /* rpm_ipc(5) */
+ <0xff 202>, /* rpm_ipc(6) */
+ <0xff 203>, /* rpm_ipc(7) */
+ <0xff 204>, /* rpm_ipc(24) */
+ <0xff 205>, /* rpm_ipc(25) */
+ <0xff 206>, /* rpm_ipc(26) */
+ <0xff 207>, /* rpm_ipc(27) */
+ <0xff 240>; /* summary_irq_kpss */
+
+ qcom,gpio-parent = <&msmgpio>;
+ qcom,gpio-map = <3 102>,
+ <4 1 >,
+ <5 5 >,
+ <6 9 >,
+ <7 18>,
+ <8 20>,
+ <9 24>,
+ <10 27>,
+ <11 28>,
+ <12 34>,
+ <13 35>,
+ <14 37>,
+ <15 42>,
+ <16 44>,
+ <17 46>,
+ <18 50>,
+ <19 54>,
+ <20 59>,
+ <21 61>,
+ <22 62>,
+ <23 64>,
+ <24 65>,
+ <25 66>,
+ <26 67>,
+ <27 68>,
+ <28 71>,
+ <29 72>,
+ <30 73>,
+ <31 74>,
+ <32 75>,
+ <33 77>,
+ <34 79>,
+ <35 80>,
+ <36 82>,
+ <37 86>,
+ <38 92>,
+ <39 93>,
+ <40 95>;
+ };
+
+ qcom,pm-8x60@fe805664 {
+ compatible = "qcom,pm-8x60";
+ reg = <0xfe805664 0x40>;
+ qcom,pc-mode = <0>; /*MSM_PC_TZ_L2_INT */
+ qcom,use-sync-timer;
+ qcom,saw-turns-off-pll;
+ };
+
+ qcom,rpm-log@fc19dc00 {
+ compatible = "qcom,rpm-log";
+ reg = <0xfc19dc00 0x4000>;
+ qcom,rpm-addr-phys = <0xfc000000>;
+ qcom,offset-version = <4>;
+ qcom,offset-page-buffer-addr = <36>;
+ qcom,offset-log-len = <40>;
+ qcom,offset-log-len-mask = <44>;
+ qcom,offset-page-indices = <56>;
+ };
+
+ qcom,rpm-stats@0xfc19dbd0{
+ compatible = "qcom,rpm-stats";
+ reg = <0xfc19dbd0 0x1000>;
+ reg-names = "phys_addr_base";
+ qcom,sleep-stats-version = <2>;
+ };
+};
diff --git a/arch/arm/boot/dts/msm8974-v2.dtsi b/arch/arm/boot/dts/msm8974-v2.dtsi
index 09f559d..95a1de8 100644
--- a/arch/arm/boot/dts/msm8974-v2.dtsi
+++ b/arch/arm/boot/dts/msm8974-v2.dtsi
@@ -18,6 +18,7 @@
/include/ "msm8974.dtsi"
/include/ "msm8974-v2-iommu.dtsi"
+/include/ "msm8974-v2-pm.dtsi"
/ {
android_usb@fe8050c8 {
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index b63b50f..212812c 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -11,7 +11,6 @@
*/
/include/ "skeleton.dtsi"
-/include/ "msm8974-pm.dtsi"
/include/ "msm8974-camera.dtsi"
/include/ "msm8974-coresight.dtsi"
/include/ "msm-gdsc.dtsi"
@@ -61,6 +60,11 @@
clock-frequency = <19200000>;
};
+ qcom,mpm-counter@fc4a3000 {
+ compatible = "qcom,mpm-counter";
+ reg = <0xfc4a3000 0x1000>;
+ };
+
qcom,vidc@fdc00000 {
compatible = "qcom,msm-vidc";
reg = <0xfdc00000 0xff000>;
@@ -884,12 +888,6 @@
qcom,is-loadable;
qcom,firmware-name = "mba";
qcom,pil-self-auth = <1>;
-
- /* GPIO input from mss */
- qcom,gpio-err-fatal = <&smp2pgpio_ssr_smp2p_1_in 0 0>;
-
- /* GPIO output to mss */
- qcom,gpio-force-stop = <&smp2pgpio_ssr_smp2p_1_out 0 0>;
};
qcom,pronto@fb21b000 {
@@ -1044,6 +1042,7 @@
qcom,sensors = <11>;
qcom,slope = <3200 3200 3200 3200 3200 3200 3200 3200 3200
3200 3200>;
+ qcom,calib-mode = "fuse_map1";
};
qcom,msm-rtb {
@@ -1261,6 +1260,10 @@
qcom,irq-no-suspend;
};
};
+
+ qcom,bcl {
+ compatible = "qcom,bcl";
+ };
};
&gdsc_venus {
diff --git a/arch/arm/boot/dts/msm9625-pm.dtsi b/arch/arm/boot/dts/msm9625-pm.dtsi
index 793d27b..a735609 100644
--- a/arch/arm/boot/dts/msm9625-pm.dtsi
+++ b/arch/arm/boot/dts/msm9625-pm.dtsi
@@ -189,8 +189,38 @@
qcom,gic-parent = <&intc>;
qcom,gic-map = <47 172>, /* usb2_hsic_async_wakeup_irq */
- <62 222>, /* ee0_krait_hlos_spmi_periph_irq */
- <0xff 208>; /* summary_irq_kpss */
+ <41 180>, /* usb_async_wakeup_irq */
+ <62 222>, /* ee0_krait_hlos_spmi_periph_irq */
+ <0xff 57>, /* mss_to_apps_irq(0) */
+ <0xff 58>, /* mss_to_apps_irq(1) */
+ <0xff 59>, /* mss_to_apps_irq(2) */
+ <0xff 60>, /* mss_to_apps_irq(3) */
+ <0xff 173>, /* o_wcss_apss_smd_hi */
+ <0xff 174>, /* o_wcss_apss_smd_med */
+ <0xff 175>, /* o_wcss_apss_smd_lo */
+ <0xff 176>, /* o_wcss_apss_smsm_irq */
+ <0xff 177>, /* o_wcss_apss_wlan_data_xfer_done */
+ <0xff 178>, /* o_wcss_apss_wlan_rx_data_avail */
+ <0xff 179>, /* o_wcss_apss_asic_intr */
+ <0xff 188>, /* q6ss_irq_out(4) */
+ <0xff 189>, /* q6ss_irq_out(5) */
+ <0xff 190>, /* q6ss_irq_out(6) */
+ <0xff 191>, /* q6ss_irq_out(7) */
+ <0xff 192>, /* audio_out0_irq */
+ <0xff 193>, /* midi_arm_irq */
+ <0xff 194>, /* q6ss_wdog_exp_irq */
+ <0xff 195>, /* slimbus_core_ee1_irq */
+ <0xff 196>, /* bam_irq(1) */
+ <0xff 197>, /* qdss_irq_out(7) */
+ <0xff 200>, /* rpm_ipc(4) */
+ <0xff 201>, /* rpm_ipc(5) */
+ <0xff 202>, /* rpm_ipc(6) */
+ <0xff 203>, /* rpm_ipc(7) */
+ <0xff 204>, /* rpm_ipc(24) */
+ <0xff 205>, /* rpm_ipc(25) */
+ <0xff 206>, /* rpm_ipc(26) */
+ <0xff 207>, /* rpm_ipc(27) */
+ <0xff 240>; /* summary_irq_kpss */
qcom,gpio-parent = <&msmgpio>;
qcom,gpio-map = <4 1>,
diff --git a/arch/arm/boot/dts/msm9625.dtsi b/arch/arm/boot/dts/msm9625.dtsi
index 2bdd9fd..d5a33ee 100644
--- a/arch/arm/boot/dts/msm9625.dtsi
+++ b/arch/arm/boot/dts/msm9625.dtsi
@@ -379,6 +379,7 @@
interrupts = <0 184 0>;
qcom,sensors = <5>;
qcom,slope = <3200 3200 3200 3200 3200>;
+ qcom,calib-mode = "fuse_map1";
};
qcom,msm-rng@f9bff000 {
diff --git a/arch/arm/configs/msm8610_defconfig b/arch/arm/configs/msm8610_defconfig
index ac92e9d..2bf4630 100644
--- a/arch/arm/configs/msm8610_defconfig
+++ b/arch/arm/configs/msm8610_defconfig
@@ -139,9 +139,11 @@
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_QUP=y
CONFIG_WCD9306_CODEC=y
+CONFIG_GPIO_QPNP_PIN=y
# CONFIG_HWMON is not set
CONFIG_REGULATOR=y
CONFIG_REGULATOR_STUB=y
+CONFIG_REGULATOR_QPNP=y
CONFIG_ION=y
CONFIG_ION_MSM=y
CONFIG_FB=y
@@ -215,3 +217,5 @@
CONFIG_MSM_OCMEM_LOCAL_POWER_CTRL=y
CONFIG_MSM_OCMEM_DEBUG=y
CONFIG_MSM_OCMEM_NONSECURE=y
+CONFIG_THERMAL=y
+CONFIG_THERMAL_TSENS8974=y
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index 2f2e0b3..6780761 100644
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -308,6 +308,7 @@
CONFIG_SENSORS_QPNP_ADC_CURRENT=y
CONFIG_THERMAL=y
CONFIG_THERMAL_TSENS8974=y
+CONFIG_THERMAL_MONITOR=y
CONFIG_THERMAL_QPNP=y
CONFIG_THERMAL_QPNP_ADC_TM=y
CONFIG_WCD9320_CODEC=y
diff --git a/arch/arm/configs/msm9625_defconfig b/arch/arm/configs/msm9625_defconfig
index 540fdf6..0f93930 100644
--- a/arch/arm/configs/msm9625_defconfig
+++ b/arch/arm/configs/msm9625_defconfig
@@ -147,6 +147,7 @@
CONFIG_IP6_NF_RAW=y
CONFIG_BRIDGE_NF_EBTABLES=y
CONFIG_BRIDGE_EBT_BROUTE=y
+CONFIG_BRIDGE_EBT_T_FILTER=y
CONFIG_BRIDGE=y
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_HTB=y
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index ecea32b..cb5e712 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -411,3 +411,5 @@
obj-$(CONFIG_MSM_SMCMOD) += smcmod.o
obj-$(CONFIG_MSM_CPU_PWRCTL) += msm_cpu_pwrctl.o
+
+obj-$(CONFIG_ARCH_MSM8974) += msm_mpmctr.o
diff --git a/arch/arm/mach-msm/acpuclock-8974.c b/arch/arm/mach-msm/acpuclock-8974.c
index 6ba11b2..d8f5425 100644
--- a/arch/arm/mach-msm/acpuclock-8974.c
+++ b/arch/arm/mach-msm/acpuclock-8974.c
@@ -252,7 +252,15 @@
{ 0, { 0 } }
};
-static struct pvs_table pvs_tables[NUM_SPEED_BINS][NUM_PVS] __initdata = {
+static struct pvs_table pvs_v1[NUM_SPEED_BINS][NUM_PVS] __initdata = {
+ [0][0] = { acpu_freq_tbl_pvs0, sizeof(acpu_freq_tbl_pvs0) },
+ [0][1] = { acpu_freq_tbl_pvs1, sizeof(acpu_freq_tbl_pvs1) },
+ [0][2] = { acpu_freq_tbl_pvs2, sizeof(acpu_freq_tbl_pvs2) },
+ [0][3] = { acpu_freq_tbl_pvs3, sizeof(acpu_freq_tbl_pvs3) },
+ [0][4] = { acpu_freq_tbl_pvs4, sizeof(acpu_freq_tbl_pvs4) },
+};
+
+static struct pvs_table pvs_v2[NUM_SPEED_BINS][NUM_PVS] __initdata = {
[0][0] = { acpu_freq_tbl_pvs0, sizeof(acpu_freq_tbl_pvs0) },
[0][1] = { acpu_freq_tbl_pvs1, sizeof(acpu_freq_tbl_pvs1) },
[0][2] = { acpu_freq_tbl_pvs2, sizeof(acpu_freq_tbl_pvs2) },
@@ -269,7 +277,7 @@
.scalable = scalable,
.scalable_size = sizeof(scalable),
.hfpll_data = &hfpll_data,
- .pvs_tables = pvs_tables,
+ .pvs_tables = pvs_v2,
.l2_freq_tbl = l2_freq_tbl,
.l2_freq_tbl_size = sizeof(l2_freq_tbl),
.bus_scale = &bus_scale_data,
@@ -278,7 +286,7 @@
.stby_khz = 300000,
};
-static void __init apply_l2_workaround(void)
+static void __init apply_v1_l2_workaround(void)
{
static struct l2_level resticted_l2_tbl[] __initdata = {
[0] = { { 300000, PLL_0, 0, 0 }, LVL_LOW, 1050000, 0 },
@@ -290,7 +298,7 @@
for (s = 0; s < NUM_SPEED_BINS; s++)
for (p = 0; p < NUM_PVS; p++)
- for (l = pvs_tables[s][p].table; l && l->speed.khz; l++)
+ for (l = pvs_v1[s][p].table; l && l->speed.khz; l++)
l->l2_level = l->l2_level > 5 ? 1 : 0;
acpuclk_8974_params.l2_freq_tbl = resticted_l2_tbl;
@@ -305,9 +313,11 @@
* and 1497.6MHz (non-inclusive), or when vdd_mx is less than 1.05V.
* Restrict L2 operation to safe performance points on these devices.
*/
- if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) < 2 &&
- SOCINFO_VERSION_MINOR(socinfo_get_version()) < 2)
- apply_l2_workaround();
+ if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 1) {
+ acpuclk_8974_params.pvs_tables = pvs_v1;
+ if (SOCINFO_VERSION_MINOR(socinfo_get_version()) < 2)
+ apply_v1_l2_workaround();
+ }
return acpuclk_krait_init(&pdev->dev, &acpuclk_8974_params);
}
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index f115d79..a89ea61 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -2644,7 +2644,6 @@
&apq8064_device_hsusb_host,
&android_usb_device,
&msm_device_wcnss_wlan,
- &msm_device_iris_fm,
&apq8064_fmem_device,
#ifdef CONFIG_ANDROID_PMEM
#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
@@ -2695,8 +2694,6 @@
&msm_bus_8064_cpss_fpb,
&msm_pil_dsps,
&msm_8960_q6_lpass,
- &msm_pil_vidc,
- &msm_gss,
&apq8064_rtb_device,
&apq8064_dcvs_device,
&apq8064_msm_gov_device,
@@ -2726,9 +2723,6 @@
&apq8064_device_uart_gsbi1,
&apq8064_device_uart_gsbi4,
&msm_device_sps_apq8064,
-#ifdef CONFIG_MSM_ROTATOR
- &msm_rotator_device,
-#endif
&msm8064_pc_cntr,
};
@@ -3976,12 +3970,10 @@
apq8064_common_init();
ethernet_init();
- msm_rotator_set_split_iommu_domain();
fsm8064_ep_pcie_init();
platform_add_devices(ep_devices, ARRAY_SIZE(ep_devices));
spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
apq8064_init_gpu();
- platform_add_devices(apq8064_footswitch, apq8064_num_footswitch);
platform_device_register(&cdp_kp_pdev);
#ifdef CONFIG_MSM_CAMERA
apq8064_init_cam();
diff --git a/arch/arm/mach-msm/board-8226.c b/arch/arm/mach-msm/board-8226.c
index ea943f9..2b331d0 100644
--- a/arch/arm/mach-msm/board-8226.c
+++ b/arch/arm/mach-msm/board-8226.c
@@ -27,6 +27,7 @@
#ifdef CONFIG_ANDROID_PMEM
#include <linux/android_pmem.h>
#endif
+#include <linux/regulator/qpnp-regulator.h>
#include <asm/mach/map.h>
#include <asm/hardware/gic.h>
#include <asm/mach/arch.h>
@@ -104,6 +105,7 @@
msm_rpm_driver_init();
msm_lpmrs_module_init();
msm_spm_device_init();
+ qpnp_regulator_init();
if (machine_is_msm8226_rumi())
msm_clock_init(&msm8226_rumi_clock_init_data);
else
diff --git a/arch/arm/mach-msm/board-8974-gpiomux.c b/arch/arm/mach-msm/board-8974-gpiomux.c
index eb99073..b3cc9b7 100644
--- a/arch/arm/mach-msm/board-8974-gpiomux.c
+++ b/arch/arm/mach-msm/board-8974-gpiomux.c
@@ -258,12 +258,6 @@
.dir = GPIOMUX_OUT_HIGH,
};
-static struct gpiomux_setting mhl_active_2_cfg = {
- .func = GPIOMUX_FUNC_1,
- .drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_UP,
-};
-
static struct gpiomux_setting hdmi_suspend_cfg = {
.func = GPIOMUX_FUNC_GPIO,
.drv = GPIOMUX_DRV_2MA,
@@ -299,14 +293,6 @@
[GPIOMUX_ACTIVE] = &mhl_active_1_cfg,
},
},
- {
- /* mhl-sii8334 reset */
- .gpio = 8,
- .settings = {
- [GPIOMUX_SUSPENDED] = &mhl_suspend_config,
- [GPIOMUX_ACTIVE] = &mhl_active_2_cfg,
- },
- },
};
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index 887f7cc..d26b4b2 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -526,7 +526,6 @@
#define mm_gnd_source_val 6
#define gpll1_hsic_source_val 4
#define cxo_lpass_source_val 0
-#define lpapll0_lpass_source_val 1
#define gpll0_lpass_source_val 5
#define edppll_270_mm_source_val 4
#define edppll_350_mm_source_val 4
@@ -742,21 +741,6 @@
},
};
-static struct pll_vote_clk lpapll0_clk_src = {
- .en_reg = (void __iomem *)LPASS_LPA_PLL_VOTE_APPS_REG,
- .en_mask = BIT(0),
- .status_reg = (void __iomem *)LPAPLL_STATUS_REG,
- .status_mask = BIT(17),
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .parent = &cxo_clk_src.c,
- .rate = 491520000,
- .dbg_name = "lpapll0_clk_src",
- .ops = &clk_ops_pll_vote,
- CLK_INIT(lpapll0_clk_src.c),
- },
-};
-
static struct pll_vote_clk mmpll0_clk_src = {
.en_reg = (void __iomem *)MMSS_PLL_VOTE_APCS_REG,
.en_mask = BIT(0),
@@ -4350,411 +4334,6 @@
},
};
-static struct clk_freq_tbl ftbl_audio_core_slimbus_core_clock[] = {
- F_LPASS(24576000, lpapll0, 4, 1, 5),
- F_END
-};
-
-static struct rcg_clk audio_core_slimbus_core_clk_src = {
- .cmd_rcgr_reg = SLIMBUS_CMD_RCGR,
- .set_rate = set_rate_mnd,
- .freq_tbl = ftbl_audio_core_slimbus_core_clock,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_core_slimbus_core_clk_src",
- .ops = &clk_ops_rcg_mnd,
- VDD_DIG_FMAX_MAP2(LOW, 70000000, NOMINAL, 140000000),
- CLK_INIT(audio_core_slimbus_core_clk_src.c),
- },
-};
-
-static struct branch_clk audio_core_slimbus_core_clk = {
- .cbcr_reg = AUDIO_CORE_SLIMBUS_CORE_CBCR,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .parent = &audio_core_slimbus_core_clk_src.c,
- .dbg_name = "audio_core_slimbus_core_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_core_slimbus_core_clk.c),
- },
-};
-
-static struct branch_clk audio_core_slimbus_lfabif_clk = {
- .cbcr_reg = AUDIO_CORE_SLIMBUS_LFABIF_CBCR,
- .has_sibling = 1,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_core_slimbus_lfabif_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_core_slimbus_lfabif_clk.c),
- },
-};
-
-static struct clk_freq_tbl ftbl_audio_core_lpaif_clock[] = {
- F_LPASS( 512000, lpapll0, 16, 1, 60),
- F_LPASS( 768000, lpapll0, 16, 1, 40),
- F_LPASS( 1024000, lpapll0, 16, 1, 30),
- F_LPASS( 1536000, lpapll0, 16, 1, 20),
- F_LPASS( 2048000, lpapll0, 16, 1, 15),
- F_LPASS( 3072000, lpapll0, 16, 1, 10),
- F_LPASS( 4096000, lpapll0, 15, 1, 8),
- F_LPASS( 6144000, lpapll0, 10, 1, 8),
- F_LPASS( 8192000, lpapll0, 15, 1, 4),
- F_LPASS(12288000, lpapll0, 10, 1, 4),
- F_END
-};
-
-static struct rcg_clk audio_core_lpaif_codec_spkr_clk_src = {
- .cmd_rcgr_reg = LPAIF_SPKR_CMD_RCGR,
- .set_rate = set_rate_mnd,
- .freq_tbl = ftbl_audio_core_lpaif_clock,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_core_lpaif_codec_spkr_clk_src",
- .ops = &clk_ops_rcg_mnd,
- VDD_DIG_FMAX_MAP2(LOW, 12000000, NOMINAL, 25000000),
- CLK_INIT(audio_core_lpaif_codec_spkr_clk_src.c),
- },
-};
-
-static struct rcg_clk audio_core_lpaif_pri_clk_src = {
- .cmd_rcgr_reg = LPAIF_PRI_CMD_RCGR,
- .set_rate = set_rate_mnd,
- .freq_tbl = ftbl_audio_core_lpaif_clock,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_core_lpaif_pri_clk_src",
- .ops = &clk_ops_rcg_mnd,
- VDD_DIG_FMAX_MAP2(LOW, 12000000, NOMINAL, 25000000),
- CLK_INIT(audio_core_lpaif_pri_clk_src.c),
- },
-};
-
-static struct rcg_clk audio_core_lpaif_sec_clk_src = {
- .cmd_rcgr_reg = LPAIF_SEC_CMD_RCGR,
- .set_rate = set_rate_mnd,
- .freq_tbl = ftbl_audio_core_lpaif_clock,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_core_lpaif_sec_clk_src",
- .ops = &clk_ops_rcg_mnd,
- VDD_DIG_FMAX_MAP2(LOW, 12000000, NOMINAL, 25000000),
- CLK_INIT(audio_core_lpaif_sec_clk_src.c),
- },
-};
-
-static struct rcg_clk audio_core_lpaif_ter_clk_src = {
- .cmd_rcgr_reg = LPAIF_TER_CMD_RCGR,
- .set_rate = set_rate_mnd,
- .freq_tbl = ftbl_audio_core_lpaif_clock,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_core_lpaif_ter_clk_src",
- .ops = &clk_ops_rcg_mnd,
- VDD_DIG_FMAX_MAP2(LOW, 12000000, NOMINAL, 25000000),
- CLK_INIT(audio_core_lpaif_ter_clk_src.c),
- },
-};
-
-static struct rcg_clk audio_core_lpaif_quad_clk_src = {
- .cmd_rcgr_reg = LPAIF_QUAD_CMD_RCGR,
- .set_rate = set_rate_mnd,
- .freq_tbl = ftbl_audio_core_lpaif_clock,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_core_lpaif_quad_clk_src",
- .ops = &clk_ops_rcg_mnd,
- VDD_DIG_FMAX_MAP2(LOW, 12000000, NOMINAL, 25000000),
- CLK_INIT(audio_core_lpaif_quad_clk_src.c),
- },
-};
-
-static struct rcg_clk audio_core_lpaif_pcm0_clk_src = {
- .cmd_rcgr_reg = LPAIF_PCM0_CMD_RCGR,
- .set_rate = set_rate_mnd,
- .freq_tbl = ftbl_audio_core_lpaif_clock,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_core_lpaif_pcm0_clk_src",
- .ops = &clk_ops_rcg_mnd,
- VDD_DIG_FMAX_MAP2(LOW, 12000000, NOMINAL, 25000000),
- CLK_INIT(audio_core_lpaif_pcm0_clk_src.c),
- },
-};
-
-static struct rcg_clk audio_core_lpaif_pcm1_clk_src = {
- .cmd_rcgr_reg = LPAIF_PCM1_CMD_RCGR,
- .set_rate = set_rate_mnd,
- .freq_tbl = ftbl_audio_core_lpaif_clock,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_core_lpaif_pcm1_clk_src",
- .ops = &clk_ops_rcg_mnd,
- VDD_DIG_FMAX_MAP2(LOW, 12000000, NOMINAL, 25000000),
- CLK_INIT(audio_core_lpaif_pcm1_clk_src.c),
- },
-};
-
-struct rcg_clk audio_core_lpaif_pcmoe_clk_src = {
- .cmd_rcgr_reg = LPAIF_PCMOE_CMD_RCGR,
- .set_rate = set_rate_mnd,
- .freq_tbl = ftbl_audio_core_lpaif_clock,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_core_lpaif_pcmoe_clk_src",
- .ops = &clk_ops_rcg_mnd,
- VDD_DIG_FMAX_MAP1(LOW, 12290000),
- CLK_INIT(audio_core_lpaif_pcmoe_clk_src.c),
- },
-};
-
-static struct branch_clk audio_core_lpaif_codec_spkr_osr_clk = {
- .cbcr_reg = AUDIO_CORE_LPAIF_CODEC_SPKR_OSR_CBCR,
- .has_sibling = 1,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .parent = &audio_core_lpaif_codec_spkr_clk_src.c,
- .dbg_name = "audio_core_lpaif_codec_spkr_osr_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_core_lpaif_codec_spkr_osr_clk.c),
- },
-};
-
-static struct branch_clk audio_core_lpaif_codec_spkr_ebit_clk = {
- .cbcr_reg = AUDIO_CORE_LPAIF_CODEC_SPKR_EBIT_CBCR,
- .has_sibling = 1,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_core_lpaif_codec_spkr_ebit_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_core_lpaif_codec_spkr_ebit_clk.c),
- },
-};
-
-static struct branch_clk audio_core_lpaif_codec_spkr_ibit_clk = {
- .cbcr_reg = AUDIO_CORE_LPAIF_CODEC_SPKR_IBIT_CBCR,
- .has_sibling = 1,
- .max_div = 15,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .parent = &audio_core_lpaif_codec_spkr_clk_src.c,
- .dbg_name = "audio_core_lpaif_codec_spkr_ibit_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_core_lpaif_codec_spkr_ibit_clk.c),
- },
-};
-
-static struct branch_clk audio_core_lpaif_pri_osr_clk = {
- .cbcr_reg = AUDIO_CORE_LPAIF_PRI_OSR_CBCR,
- .has_sibling = 1,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .parent = &audio_core_lpaif_pri_clk_src.c,
- .dbg_name = "audio_core_lpaif_pri_osr_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_core_lpaif_pri_osr_clk.c),
- },
-};
-
-static struct branch_clk audio_core_lpaif_pri_ebit_clk = {
- .cbcr_reg = AUDIO_CORE_LPAIF_PRI_EBIT_CBCR,
- .has_sibling = 1,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_core_lpaif_pri_ebit_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_core_lpaif_pri_ebit_clk.c),
- },
-};
-
-static struct branch_clk audio_core_lpaif_pri_ibit_clk = {
- .cbcr_reg = AUDIO_CORE_LPAIF_PRI_IBIT_CBCR,
- .has_sibling = 1,
- .max_div = 15,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .parent = &audio_core_lpaif_pri_clk_src.c,
- .dbg_name = "audio_core_lpaif_pri_ibit_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_core_lpaif_pri_ibit_clk.c),
- },
-};
-
-static struct branch_clk audio_core_lpaif_sec_osr_clk = {
- .cbcr_reg = AUDIO_CORE_LPAIF_SEC_OSR_CBCR,
- .has_sibling = 1,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .parent = &audio_core_lpaif_sec_clk_src.c,
- .dbg_name = "audio_core_lpaif_sec_osr_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_core_lpaif_sec_osr_clk.c),
- },
-};
-
-static struct branch_clk audio_core_lpaif_sec_ebit_clk = {
- .cbcr_reg = AUDIO_CORE_LPAIF_SEC_EBIT_CBCR,
- .has_sibling = 1,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_core_lpaif_sec_ebit_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_core_lpaif_sec_ebit_clk.c),
- },
-};
-
-static struct branch_clk audio_core_lpaif_sec_ibit_clk = {
- .cbcr_reg = AUDIO_CORE_LPAIF_SEC_IBIT_CBCR,
- .has_sibling = 1,
- .max_div = 15,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .parent = &audio_core_lpaif_sec_clk_src.c,
- .dbg_name = "audio_core_lpaif_sec_ibit_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_core_lpaif_sec_ibit_clk.c),
- },
-};
-
-static struct branch_clk audio_core_lpaif_ter_osr_clk = {
- .cbcr_reg = AUDIO_CORE_LPAIF_TER_OSR_CBCR,
- .has_sibling = 1,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .parent = &audio_core_lpaif_ter_clk_src.c,
- .dbg_name = "audio_core_lpaif_ter_osr_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_core_lpaif_ter_osr_clk.c),
- },
-};
-
-static struct branch_clk audio_core_lpaif_ter_ebit_clk = {
- .cbcr_reg = AUDIO_CORE_LPAIF_TER_EBIT_CBCR,
- .has_sibling = 1,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_core_lpaif_ter_ebit_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_core_lpaif_ter_ebit_clk.c),
- },
-};
-
-static struct branch_clk audio_core_lpaif_ter_ibit_clk = {
- .cbcr_reg = AUDIO_CORE_LPAIF_TER_IBIT_CBCR,
- .has_sibling = 1,
- .max_div = 15,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .parent = &audio_core_lpaif_ter_clk_src.c,
- .dbg_name = "audio_core_lpaif_ter_ibit_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_core_lpaif_ter_ibit_clk.c),
- },
-};
-
-static struct branch_clk audio_core_lpaif_quad_osr_clk = {
- .cbcr_reg = AUDIO_CORE_LPAIF_QUAD_OSR_CBCR,
- .has_sibling = 1,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .parent = &audio_core_lpaif_quad_clk_src.c,
- .dbg_name = "audio_core_lpaif_quad_osr_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_core_lpaif_quad_osr_clk.c),
- },
-};
-
-static struct branch_clk audio_core_lpaif_quad_ebit_clk = {
- .cbcr_reg = AUDIO_CORE_LPAIF_QUAD_EBIT_CBCR,
- .has_sibling = 1,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_core_lpaif_quad_ebit_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_core_lpaif_quad_ebit_clk.c),
- },
-};
-
-static struct branch_clk audio_core_lpaif_quad_ibit_clk = {
- .cbcr_reg = AUDIO_CORE_LPAIF_QUAD_IBIT_CBCR,
- .has_sibling = 1,
- .max_div = 15,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .parent = &audio_core_lpaif_quad_clk_src.c,
- .dbg_name = "audio_core_lpaif_quad_ibit_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_core_lpaif_quad_ibit_clk.c),
- },
-};
-
-static struct branch_clk audio_core_lpaif_pcm0_ebit_clk = {
- .cbcr_reg = AUDIO_CORE_LPAIF_PCM0_EBIT_CBCR,
- .has_sibling = 1,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_core_lpaif_pcm0_ebit_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_core_lpaif_pcm0_ebit_clk.c),
- },
-};
-
-static struct branch_clk audio_core_lpaif_pcm0_ibit_clk = {
- .cbcr_reg = AUDIO_CORE_LPAIF_PCM0_IBIT_CBCR,
- .has_sibling = 1,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .parent = &audio_core_lpaif_pcm0_clk_src.c,
- .dbg_name = "audio_core_lpaif_pcm0_ibit_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_core_lpaif_pcm0_ibit_clk.c),
- },
-};
-
-static struct branch_clk audio_core_lpaif_pcm1_ebit_clk = {
- .cbcr_reg = AUDIO_CORE_LPAIF_PCM1_EBIT_CBCR,
- .has_sibling = 1,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .parent = &audio_core_lpaif_pcm1_clk_src.c,
- .dbg_name = "audio_core_lpaif_pcm1_ebit_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_core_lpaif_pcm1_ebit_clk.c),
- },
-};
-
-static struct branch_clk audio_core_lpaif_pcm1_ibit_clk = {
- .cbcr_reg = AUDIO_CORE_LPAIF_PCM1_IBIT_CBCR,
- .has_sibling = 1,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .parent = &audio_core_lpaif_pcm1_clk_src.c,
- .dbg_name = "audio_core_lpaif_pcm1_ibit_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_core_lpaif_pcm1_ibit_clk.c),
- },
-};
-
-struct branch_clk audio_core_lpaif_pcmoe_clk = {
- .cbcr_reg = AUDIO_CORE_LPAIF_PCM_DATA_OE_CBCR,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .parent = &audio_core_lpaif_pcmoe_clk_src.c,
- .dbg_name = "audio_core_lpaif_pcmoe_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_core_lpaif_pcmoe_clk.c),
- },
-};
-
static struct branch_clk q6ss_ahb_lfabif_clk = {
.cbcr_reg = LPASS_Q6SS_AHB_LFABIF_CBCR,
.has_sibling = 1,
@@ -4766,16 +4345,6 @@
},
};
-static struct branch_clk audio_core_ixfabric_clk = {
- .cbcr_reg = AUDIO_CORE_IXFABRIC_CBCR,
- .has_sibling = 1,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_core_ixfabric_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_core_ixfabric_clk.c),
- },
-};
static struct branch_clk gcc_lpass_q6_axi_clk = {
.cbcr_reg = LPASS_Q6_AXI_CBCR,
@@ -4811,17 +4380,6 @@
},
};
-static struct branch_clk audio_wrapper_br_clk = {
- .cbcr_reg = AUDIO_WRAPPER_BR_CBCR,
- .has_sibling = 1,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_wrapper_br_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_wrapper_br_clk.c),
- },
-};
-
static DEFINE_CLK_MEASURE(l2_m_clk);
static DEFINE_CLK_MEASURE(krait0_m_clk);
static DEFINE_CLK_MEASURE(krait1_m_clk);
@@ -5004,20 +4562,9 @@
{&mdss_hdmi_ahb_clk.c, MMSS_BASE, 0x0023},
{&mdss_pclk0_clk.c, MMSS_BASE, 0x0016},
{&mdss_pclk1_clk.c, MMSS_BASE, 0x0017},
- {&audio_core_lpaif_pri_clk_src.c, LPASS_BASE, 0x0017},
- {&audio_core_lpaif_sec_clk_src.c, LPASS_BASE, 0x0016},
- {&audio_core_lpaif_ter_clk_src.c, LPASS_BASE, 0x0015},
- {&audio_core_lpaif_quad_clk_src.c, LPASS_BASE, 0x0014},
- {&audio_core_lpaif_pcm0_clk_src.c, LPASS_BASE, 0x0013},
- {&audio_core_lpaif_pcm1_clk_src.c, LPASS_BASE, 0x0012},
- {&audio_core_lpaif_pcmoe_clk_src.c, LPASS_BASE, 0x000f},
- {&audio_core_slimbus_core_clk.c, LPASS_BASE, 0x003d},
- {&audio_core_slimbus_lfabif_clk.c, LPASS_BASE, 0x003e},
{&q6ss_xo_clk.c, LPASS_BASE, 0x002b},
{&q6ss_ahb_lfabif_clk.c, LPASS_BASE, 0x001e},
{&q6ss_ahbm_clk.c, LPASS_BASE, 0x001d},
- {&audio_core_ixfabric_clk.c, LPASS_BASE, 0x0059},
- {&audio_wrapper_br_clk.c, LPASS_BASE, 0x0022},
{&krait0_m_clk, APCS_BASE, M_ACPU0},
{&krait1_m_clk, APCS_BASE, M_ACPU1},
@@ -5590,6 +5137,20 @@
"fda20000.qcom,jpeg"),
CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
"fda24000.qcom,jpeg"),
+ CLK_LOOKUP("micro_iface_clk", camss_micro_ahb_clk.c,
+ "fda04000.qcom,cpp"),
+ CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
+ "fda04000.qcom,cpp"),
+ CLK_LOOKUP("cpp_iface_clk", camss_vfe_cpp_ahb_clk.c,
+ "fda04000.qcom,cpp"),
+ CLK_LOOKUP("cpp_core_clk", camss_vfe_cpp_clk.c, "fda04000.qcom,cpp"),
+ CLK_LOOKUP("cpp_bus_clk", camss_vfe_vfe_axi_clk.c, "fda04000.qcom,cpp"),
+ CLK_LOOKUP("vfe_clk_src", vfe0_clk_src.c, "fda04000.qcom,cpp"),
+ CLK_LOOKUP("camss_vfe_vfe_clk", camss_vfe_vfe0_clk.c,
+ "fda04000.qcom,cpp"),
+ CLK_LOOKUP("iface_clk", camss_vfe_vfe_ahb_clk.c, "fda04000.qcom,cpp"),
+
+
CLK_LOOKUP("iface_clk", camss_micro_ahb_clk.c, ""),
CLK_LOOKUP("iface_clk", camss_vfe_vfe_ahb_clk.c, "fda44000.qcom,iommu"),
CLK_LOOKUP("core_clk", camss_vfe_vfe_axi_clk.c, "fda44000.qcom,iommu"),
@@ -5625,57 +5186,6 @@
/* LPASS clocks */
- CLK_LOOKUP("bus_clk", audio_core_ixfabric_clk.c, ""),
- CLK_LOOKUP("core_clk", audio_core_slimbus_core_clk.c, "fe12f000.slim"),
- CLK_LOOKUP("iface_clk", audio_core_slimbus_lfabif_clk.c,
- "fe12f000.slim"),
- CLK_LOOKUP("core_clk", audio_core_lpaif_codec_spkr_clk_src.c, ""),
- CLK_LOOKUP("osr_clk", audio_core_lpaif_codec_spkr_osr_clk.c, ""),
- CLK_LOOKUP("ebit_clk", audio_core_lpaif_codec_spkr_ebit_clk.c, ""),
- CLK_LOOKUP("ibit_clk", audio_core_lpaif_codec_spkr_ibit_clk.c, ""),
- CLK_LOOKUP("core_clk", audio_core_lpaif_pri_clk_src.c, ""),
- CLK_LOOKUP("osr_clk", audio_core_lpaif_pri_osr_clk.c, ""),
- CLK_LOOKUP("ebit_clk", audio_core_lpaif_pri_ebit_clk.c, ""),
- CLK_LOOKUP("ibit_clk", audio_core_lpaif_pri_ibit_clk.c, ""),
- CLK_LOOKUP("core_clk", audio_core_lpaif_sec_clk_src.c, ""),
- CLK_LOOKUP("osr_clk", audio_core_lpaif_sec_osr_clk.c, ""),
- CLK_LOOKUP("ebit_clk", audio_core_lpaif_sec_ebit_clk.c, ""),
- CLK_LOOKUP("ibit_clk", audio_core_lpaif_sec_ibit_clk.c, ""),
- CLK_LOOKUP("core_clk", audio_core_lpaif_ter_clk_src.c, ""),
- CLK_LOOKUP("osr_clk", audio_core_lpaif_ter_osr_clk.c, ""),
- CLK_LOOKUP("ebit_clk", audio_core_lpaif_ter_ebit_clk.c, ""),
- CLK_LOOKUP("ibit_clk", audio_core_lpaif_ter_ibit_clk.c, ""),
- CLK_LOOKUP("core_clk", audio_core_lpaif_quad_clk_src.c,
- "msm-dai-q6-mi2s.3"),
- CLK_LOOKUP("osr_clk", audio_core_lpaif_quad_osr_clk.c,
- "msm-dai-q6-mi2s.3"),
- CLK_LOOKUP("ebit_clk", audio_core_lpaif_quad_ebit_clk.c,
- "msm-dai-q6-mi2s.3"),
- CLK_LOOKUP("ibit_clk", audio_core_lpaif_quad_ibit_clk.c,
- "msm-dai-q6-mi2s.3"),
- CLK_LOOKUP("pcm_clk", audio_core_lpaif_pcm0_clk_src.c,
- "msm-dai-q6.4106"),
- CLK_LOOKUP("ebit_clk", audio_core_lpaif_pcm0_ebit_clk.c, ""),
- CLK_LOOKUP("ibit_clk", audio_core_lpaif_pcm0_ibit_clk.c,
- "msm-dai-q6.4106"),
- CLK_LOOKUP("ibit_clk", audio_core_lpaif_pcm0_ibit_clk.c, ""),
- CLK_LOOKUP("core_clk", audio_core_lpaif_pcm1_clk_src.c, ""),
- CLK_LOOKUP("ebit_clk", audio_core_lpaif_pcm1_ebit_clk.c, ""),
- CLK_LOOKUP("ibit_clk", audio_core_lpaif_pcm1_ibit_clk.c, ""),
- CLK_LOOKUP("core_oe_src_clk", audio_core_lpaif_pcmoe_clk_src.c,
- "msm-dai-q6.4106"),
- CLK_LOOKUP("core_oe_clk", audio_core_lpaif_pcmoe_clk.c,
- "msm-dai-q6.4106"),
- CLK_LOOKUP("pcm_clk", audio_core_lpaif_pcm0_clk_src.c,
- "msm-dai-q6.4107"),
- CLK_LOOKUP("ibit_clk", audio_core_lpaif_pcm0_ibit_clk.c,
- "msm-dai-q6.4107"),
- CLK_LOOKUP("core_oe_src_clk", audio_core_lpaif_pcmoe_clk_src.c,
- "msm-dai-q6.4107"),
- CLK_LOOKUP("core_oe_clk", audio_core_lpaif_pcmoe_clk.c,
- "msm-dai-q6.4107"),
- CLK_LOOKUP("br_clk", audio_wrapper_br_clk.c, "fdd00000.qcom,ocmem"),
-
CLK_LOOKUP("bus_clk", gcc_mss_q6_bimc_axi_clk.c, "fc880000.qcom,mss"),
CLK_LOOKUP("iface_clk", gcc_mss_cfg_ahb_clk.c, "fc880000.qcom,mss"),
CLK_LOOKUP("mem_clk", gcc_boot_rom_ahb_clk.c, "fc880000.qcom,mss"),
@@ -5866,32 +5376,6 @@
.main_output_mask = BIT(0),
};
-static struct pll_config_regs lpapll0_regs __initdata = {
- .l_reg = (void __iomem *)LPAPLL_L_REG,
- .m_reg = (void __iomem *)LPAPLL_M_REG,
- .n_reg = (void __iomem *)LPAPLL_N_REG,
- .config_reg = (void __iomem *)LPAPLL_USER_CTL_REG,
- .mode_reg = (void __iomem *)LPAPLL_MODE_REG,
- .base = &virt_bases[LPASS_BASE],
-};
-
-/* LPAPLL0 at 491.52 MHz, main output enabled. */
-static struct pll_config lpapll0_config __initdata = {
- .l = 0x33,
- .m = 0x1,
- .n = 0x5,
- .vco_val = 0x0,
- .vco_mask = BM(21, 20),
- .pre_div_val = BVAL(14, 12, 0x1),
- .pre_div_mask = BM(14, 12),
- .post_div_val = 0x0,
- .post_div_mask = BM(9, 8),
- .mn_ena_val = BIT(24),
- .mn_ena_mask = BIT(24),
- .main_output_val = BIT(0),
- .main_output_mask = BIT(0),
-};
-
#define PWR_ON_MASK BIT(31)
#define EN_REST_WAIT_MASK (0xF << 20)
#define EN_FEW_WAIT_MASK (0xF << 16)
@@ -5908,8 +5392,7 @@
static void __init reg_init(void)
{
- u32 regval, status;
- int ret;
+ u32 regval;
configure_sr_hpm_lp_pll(&mmpll0_config, &mmpll0_regs, 1);
@@ -5920,7 +5403,6 @@
configure_sr_hpm_lp_pll(&mmpll1_config, &mmpll1_regs, 1);
configure_sr_hpm_lp_pll(&mmpll3_config, &mmpll3_regs, 0);
}
- configure_sr_hpm_lp_pll(&lpapll0_config, &lpapll0_regs, 1);
/* Vote for GPLL0 to turn on. Needed by acpuclock. */
regval = readl_relaxed(GCC_REG_BASE(APCS_GPLL_ENA_VOTE_REG));
@@ -5943,31 +5425,6 @@
* register.
*/
writel_relaxed(0x0, GCC_REG_BASE(APCS_CLOCK_SLEEP_ENA_VOTE));
-
- /*
- * TODO: The following sequence enables the LPASS audio core GDSC.
- * Remove when this becomes unnecessary.
- */
-
- /*
- * Disable HW trigger: collapse/restore occur based on registers writes.
- * Disable SW override: Use hardware state-machine for sequencing.
- */
- regval = readl_relaxed(LPASS_REG_BASE(AUDIO_CORE_GDSCR));
- regval &= ~(HW_CONTROL_MASK | SW_OVERRIDE_MASK);
-
- /* Configure wait time between states. */
- regval &= ~(EN_REST_WAIT_MASK | EN_FEW_WAIT_MASK | CLK_DIS_WAIT_MASK);
- regval |= EN_REST_WAIT_VAL | EN_FEW_WAIT_VAL | CLK_DIS_WAIT_VAL;
- writel_relaxed(regval, LPASS_REG_BASE(AUDIO_CORE_GDSCR));
-
- regval = readl_relaxed(LPASS_REG_BASE(AUDIO_CORE_GDSCR));
- regval &= ~BIT(0);
- writel_relaxed(regval, LPASS_REG_BASE(AUDIO_CORE_GDSCR));
-
- ret = readl_poll_timeout(LPASS_REG_BASE(AUDIO_CORE_GDSCR), status,
- status & PWR_ON_MASK, 50, GDSC_TIMEOUT_US);
- WARN(ret, "LPASS Audio Core GDSC did not power on.\n");
}
static void __init mdss_clock_setup(void)
@@ -6007,11 +5464,6 @@
*/
clk_prepare_enable(&cxo_a_clk_src.c);
- /* TODO: Temporarily enable a clock to allow access to LPASS core
- * registers.
- */
- clk_prepare_enable(&audio_core_ixfabric_clk.c);
-
/*
* TODO: Temporarily enable NOC configuration AHB clocks. Remove when
* the bus driver is ready.
@@ -6046,8 +5498,6 @@
clk_set_rate(&esc1_clk_src.c, esc1_clk_src.freq_tbl[0].freq_hz);
clk_set_rate(&hdmi_clk_src.c, hdmi_clk_src.freq_tbl[0].freq_hz);
clk_set_rate(&vsync_clk_src.c, vsync_clk_src.freq_tbl[0].freq_hz);
- clk_set_rate(&audio_core_slimbus_core_clk_src.c,
- audio_core_slimbus_core_clk_src.freq_tbl[0].freq_hz);
}
#define GCC_CC_PHYS 0xFC400000
diff --git a/arch/arm/mach-msm/clock-rpm.c b/arch/arm/mach-msm/clock-rpm.c
index c1cc27b..ee91a34 100644
--- a/arch/arm/mach-msm/clock-rpm.c
+++ b/arch/arm/mach-msm/clock-rpm.c
@@ -245,6 +245,14 @@
return rc;
}
+static int rpm_branch_clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ if (rate == clk->rate)
+ return 0;
+
+ return -EPERM;
+}
+
static unsigned long rpm_clk_get_rate(struct clk *clk)
{
struct rpm_clk *r = to_rpm_clk(clk);
@@ -335,6 +343,7 @@
struct clk_ops clk_ops_rpm_branch = {
.prepare = rpm_clk_prepare,
.unprepare = rpm_clk_unprepare,
+ .set_rate = rpm_branch_clk_set_rate,
.is_local = rpm_clk_is_local,
.handoff = rpm_clk_handoff,
};
diff --git a/arch/arm/mach-msm/cpuidle.c b/arch/arm/mach-msm/cpuidle.c
index 1e3f8a0..77c91b8 100644
--- a/arch/arm/mach-msm/cpuidle.c
+++ b/arch/arm/mach-msm/cpuidle.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -77,7 +77,9 @@
struct cpuidle_state_usage *st_usage = NULL;
cpu_pm_enter();
- pm_mode = msm_pm_idle_enter(dev, drv, index);
+
+ pm_mode = msm_pm_idle_prepare(dev, drv, index);
+ dev->last_residency = msm_pm_idle_enter(pm_mode);
for (i = 0; i < dev->state_count; i++) {
st_usage = &dev->states_usage[i];
if ((enum msm_pm_sleep_mode) cpuidle_get_statedata(st_usage)
diff --git a/arch/arm/mach-msm/include/mach/msm_bus_board.h b/arch/arm/mach-msm/include/mach/msm_bus_board.h
index 390160d..8fd3cfc 100644
--- a/arch/arm/mach-msm/include/mach/msm_bus_board.h
+++ b/arch/arm/mach-msm/include/mach/msm_bus_board.h
@@ -102,6 +102,10 @@
int msm_bus_board_rpm_get_il_ids(uint16_t *id);
int msm_bus_board_get_iid(int id);
+#ifdef CONFIG_ARCH_MSM8226
+#define NFAB 6
+#endif
+
/*
* These macros specify the convention followed for allocating
* ids to fabrics, masters and slaves for 8x60.
@@ -111,7 +115,6 @@
*/
#define FABRIC_ID_KEY 1024
#define SLAVE_ID_KEY ((FABRIC_ID_KEY) >> 1)
-#define NUM_FAB 5
#define MAX_FAB_KEY 7168 /* OR(All fabric ids) */
#define GET_FABID(id) ((id) & MAX_FAB_KEY)
@@ -300,7 +303,7 @@
MSM_BUS_MASTER_IPA,
MSM_BUS_MASTER_QPIC,
- MSM_BUS_MASTER_LAST = MSM_BUS_MASTER_QPIC,
+ MSM_BUS_MASTER_LAST,
MSM_BUS_SYSTEM_FPB_MASTER_SYSTEM =
MSM_BUS_SYSTEM_MASTER_SYSTEM_FPB,
@@ -457,7 +460,7 @@
MSM_BUS_SLAVE_IPS_CFG,
MSM_BUS_SLAVE_QPIC,
- MSM_BUS_SLAVE_LAST = MSM_BUS_SLAVE_QPIC,
+ MSM_BUS_SLAVE_LAST,
MSM_BUS_SYSTEM_FPB_SLAVE_SYSTEM =
MSM_BUS_SYSTEM_SLAVE_SYSTEM_FPB,
diff --git a/arch/arm/mach-msm/include/mach/msm_mpmctr.h b/arch/arm/mach-msm/include/mach/msm_mpmctr.h
new file mode 100644
index 0000000..d3d853f
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/msm_mpmctr.h
@@ -0,0 +1,21 @@
+/*
+ * 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 __MSM_MPMCTR_H__
+#define __MSM_MPMCTR_H__
+
+/*
+ * returns the count value of the mpm timetick.
+ */
+uint32_t msm_mpm_get_count(void);
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/ocmem.h b/arch/arm/mach-msm/include/mach/ocmem.h
index cd70457..92ae6b6 100644
--- a/arch/arm/mach-msm/include/mach/ocmem.h
+++ b/arch/arm/mach-msm/include/mach/ocmem.h
@@ -136,6 +136,9 @@
int ocmem_unmap(int client_id, struct ocmem_buf *buffer,
struct ocmem_map_list *list);
+int ocmem_drop(int client_id, struct ocmem_buf *buffer,
+ struct ocmem_map_list *list);
+
int ocmem_dump(int client_id, struct ocmem_buf *buffer,
unsigned long dst_phys_addr);
diff --git a/arch/arm/mach-msm/include/mach/ocmem_priv.h b/arch/arm/mach-msm/include/mach/ocmem_priv.h
index a4adfb8..abb5653 100644
--- a/arch/arm/mach-msm/include/mach/ocmem_priv.h
+++ b/arch/arm/mach-msm/include/mach/ocmem_priv.h
@@ -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
@@ -29,6 +29,16 @@
#define TO_OCMEM 0x0
#define TO_DDR 0x1
+#define OCMEM_SVC_ID 15
+#define OCMEM_LOCK_CMD_ID 0x1
+#define OCMEM_UNLOCK_CMD_ID 0x2
+#define OCMEM_ENABLE_DUMP_CMD_ID 0x3
+#define OCMEM_DISABLE_DUMP_CMD_ID 0x4
+
+#define OCMEM_SECURE_SVC_ID 12
+#define OCMEM_SECURE_CFG_ID 0x2
+#define OCMEM_SECURE_DEV_ID 0x5
+
struct ocmem_zone;
struct ocmem_zone_ops {
@@ -158,6 +168,8 @@
/* Request Power State */
unsigned power_state;
struct ocmem_eviction_data *edata;
+ /* Request that triggered eviction */
+ struct ocmem_req *e_handle;
};
struct ocmem_handle {
@@ -187,6 +199,10 @@
int ocmem_notifier_init(void);
int check_notifier(int);
const char *get_name(int);
+int get_tz_id(int);
+int ocmem_enable_sec_program(int);
+int ocmem_enable_dump(enum ocmem_client, unsigned long, unsigned long);
+int ocmem_disable_dump(enum ocmem_client, unsigned long, unsigned long);
int check_id(int);
int dispatch_notification(int, enum ocmem_notif_type, struct ocmem_buf *);
@@ -197,6 +213,7 @@
unsigned long, bool, bool);
int process_free(int, struct ocmem_handle *);
int process_xfer(int, struct ocmem_handle *, struct ocmem_map_list *, int);
+int process_drop(int, struct ocmem_handle *, struct ocmem_map_list *);
int process_evict(int);
int process_restore(int);
int process_shrink(int, struct ocmem_handle *, unsigned long);
diff --git a/arch/arm/mach-msm/krait-regulator.c b/arch/arm/mach-msm/krait-regulator.c
index 01be641..0c1e279 100644
--- a/arch/arm/mach-msm/krait-regulator.c
+++ b/arch/arm/mach-msm/krait-regulator.c
@@ -291,6 +291,11 @@
int krait_power_mdd_enable(int cpu_num, bool on)
{
+ /*
+ * Expected to be called when the cpu goes to retention mode as a part
+ * of idle power collapse. IT is guaranteed that cpu won't be put in
+ * retention while being hotplugged out
+ */
struct krait_power_vreg *kvreg = per_cpu(krait_vregs, cpu_num);
if (!on && kvreg->mode == LDO_MODE) {
@@ -298,7 +303,7 @@
return -EINVAL;
}
- if ((on && kvreg->mode == LDO_MODE) || (!on && kvreg->mode == HS_MODE))
+ if (on && kvreg->mode == LDO_MODE)
return 0;
__krait_power_mdd_enable(kvreg, on);
@@ -801,6 +806,8 @@
int rc;
mutex_lock(&pvreg->krait_power_vregs_lock);
+ if (kvreg->mode == LDO_MODE)
+ __krait_power_mdd_enable(kvreg, true);
kvreg->online = true;
rc = _get_optimum_mode(rdev, kvreg->uV, kvreg->uV, kvreg->load_uA);
if (rc < 0)
@@ -830,6 +837,8 @@
goto dis_err;
rc = _set_voltage(rdev, kvreg->uV, kvreg->uV);
+ if (kvreg->mode == LDO_MODE)
+ __krait_power_mdd_enable(kvreg, false);
dis_err:
mutex_unlock(&pvreg->krait_power_vregs_lock);
return rc;
@@ -894,8 +903,6 @@
/* setup the bandgap that configures the reference to the LDO */
writel_relaxed(0x00000190, kvreg->mdd_base + MDD_CONFIG_CTL);
- /* Enable MDD */
- writel_relaxed(0x00000002, kvreg->mdd_base + MDD_MODE);
mb();
}
diff --git a/arch/arm/mach-msm/lpm_levels.c b/arch/arm/mach-msm/lpm_levels.c
index 8571bda..dec62f0 100644
--- a/arch/arm/mach-msm/lpm_levels.c
+++ b/arch/arm/mach-msm/lpm_levels.c
@@ -57,6 +57,8 @@
bool from_idle, bool notify_rpm)
{
int ret = 0;
+ int debug_mask;
+ struct msm_rpmrs_limits *l = (struct msm_rpmrs_limits *)limits;
struct msm_lpm_sleep_data sleep_data;
sleep_data.limits = limits;
@@ -64,34 +66,28 @@
atomic_notifier_call_chain(&__get_cpu_var(lpm_notify_head),
MSM_LPM_STATE_ENTER, &sleep_data);
- if (notify_rpm) {
- int debug_mask;
- struct msm_rpmrs_limits *l = (struct msm_rpmrs_limits *)limits;
-
- ret = msm_rpm_enter_sleep();
- if (ret) {
- pr_warn("%s(): RPM failed to enter sleep err:%d\n",
- __func__, ret);
- goto bail;
- }
- if (from_idle)
- debug_mask = msm_lpm_lvl_dbg_msk &
- MSM_LPM_LVL_DBG_IDLE_LIMITS;
- else
- debug_mask = msm_lpm_lvl_dbg_msk &
- MSM_LPM_LVL_DBG_SUSPEND_LIMITS;
-
- if (debug_mask)
- pr_info("%s(): pxo:%d l2:%d mem:0x%x(0x%x) dig:0x%x(0x%x)\n",
- __func__, l->pxo, l->l2_cache,
- l->vdd_mem_lower_bound,
- l->vdd_mem_upper_bound,
- l->vdd_dig_lower_bound,
- l->vdd_dig_upper_bound);
-
- ret = msm_lpmrs_enter_sleep(sclk_count, l, from_idle,
- notify_rpm);
+ ret = msm_rpm_enter_sleep();
+ if (ret) {
+ pr_warn("%s(): RPM failed to enter sleep err:%d\n",
+ __func__, ret);
+ goto bail;
}
+ if (from_idle)
+ debug_mask = msm_lpm_lvl_dbg_msk &
+ MSM_LPM_LVL_DBG_IDLE_LIMITS;
+ else
+ debug_mask = msm_lpm_lvl_dbg_msk &
+ MSM_LPM_LVL_DBG_SUSPEND_LIMITS;
+
+ if (debug_mask)
+ pr_info("%s(): pxo:%d l2:%d mem:0x%x(0x%x) dig:0x%x(0x%x)\n",
+ __func__, l->pxo, l->l2_cache,
+ l->vdd_mem_lower_bound,
+ l->vdd_mem_upper_bound,
+ l->vdd_dig_lower_bound,
+ l->vdd_dig_upper_bound);
+
+ ret = msm_lpmrs_enter_sleep(sclk_count, l, from_idle, notify_rpm);
bail:
return ret;
}
diff --git a/arch/arm/mach-msm/msm_bus/Makefile b/arch/arm/mach-msm/msm_bus/Makefile
index e785c00..2ee07f3 100644
--- a/arch/arm/mach-msm/msm_bus/Makefile
+++ b/arch/arm/mach-msm/msm_bus/Makefile
@@ -14,4 +14,5 @@
obj-$(CONFIG_ARCH_MSM8930) += msm_bus_board_8930.o
obj-$(CONFIG_ARCH_MSM8974) += msm_bus_board_8974.o
obj-$(CONFIG_ARCH_MSM9625) += msm_bus_board_9625.o
+obj-$(CONFIG_ARCH_MSM8226) += msm_bus_id.o
obj-$(CONFIG_DEBUG_FS) += msm_bus_dbg.o
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c b/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c
index 0d28e9d..2c7ceab 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c
@@ -837,7 +837,7 @@
.probe = msm_bus_fabric_probe,
.remove = msm_bus_fabric_remove,
.driver = {
- .name = "msm-bus-fabric",
+ .name = "msm_bus_fabric",
.owner = THIS_MODULE,
.of_match_table = fabric_match,
},
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_id.c b/arch/arm/mach-msm/msm_bus/msm_bus_id.c
new file mode 100644
index 0000000..693c51e
--- /dev/null
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_id.c
@@ -0,0 +1,83 @@
+/* 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/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <mach/msm_bus.h>
+#include <mach/msm_bus_board.h>
+#include <mach/board.h>
+#include <mach/rpm.h>
+#include "msm_bus_core.h"
+#include "msm_bus_noc.h"
+#include "msm_bus_bimc.h"
+
+static uint32_t master_iids[MSM_BUS_MASTER_LAST];
+static uint32_t slave_iids[MSM_BUS_SLAVE_LAST - SLAVE_ID_KEY];
+
+static void msm_bus_assign_iids(struct msm_bus_fabric_registration
+ *fabreg, int fabid)
+{
+ int i;
+ for (i = 0; i < fabreg->len; i++) {
+ if (!fabreg->info[i].gateway) {
+ fabreg->info[i].priv_id = fabid + fabreg->info[i].id;
+ if (fabreg->info[i].id < SLAVE_ID_KEY) {
+ WARN(fabreg->info[i].id >= MSM_BUS_MASTER_LAST,
+ "id %d exceeds array size!\n",
+ fabreg->info[i].id);
+ master_iids[fabreg->info[i].id] =
+ fabreg->info[i].priv_id;
+ } else {
+ WARN((fabreg->info[i].id - SLAVE_ID_KEY) >=
+ (MSM_BUS_SLAVE_LAST - SLAVE_ID_KEY),
+ "id %d exceeds array size!\n",
+ fabreg->info[i].id);
+ slave_iids[fabreg->info[i].id - (SLAVE_ID_KEY)]
+ = fabreg->info[i].priv_id;
+ }
+ } else {
+ fabreg->info[i].priv_id = fabreg->info[i].id;
+ }
+ }
+}
+
+static int msm_bus_get_iid(int id)
+{
+ if ((id < SLAVE_ID_KEY && id >= MSM_BUS_MASTER_LAST) ||
+ id >= MSM_BUS_SLAVE_LAST) {
+ MSM_BUS_ERR("Cannot get iid. Invalid id %d passed\n", id);
+ return -EINVAL;
+ }
+
+ return CHECK_ID(((id < SLAVE_ID_KEY) ? master_iids[id] :
+ slave_iids[id - SLAVE_ID_KEY]), id);
+}
+
+
+static struct msm_bus_board_algorithm msm_bus_id_algo = {
+ .board_nfab = NFAB,
+ .get_iid = msm_bus_get_iid,
+ .assign_iids = msm_bus_assign_iids,
+};
+
+int msm_bus_board_rpm_get_il_ids(uint16_t *id)
+{
+ return -ENXIO;
+}
+
+void msm_bus_board_init(struct msm_bus_fabric_registration *pdata)
+{
+ pdata->board_algo = &msm_bus_id_algo;
+}
diff --git a/arch/arm/mach-msm/msm_mpmctr.c b/arch/arm/mach-msm/msm_mpmctr.c
new file mode 100644
index 0000000..4ab82ab
--- /dev/null
+++ b/arch/arm/mach-msm/msm_mpmctr.c
@@ -0,0 +1,99 @@
+/* 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/kernel.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/smp.h>
+#include <linux/clk.h>
+#include <linux/cpu.h>
+#include <linux/sched.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <mach/msm_mpmctr.h>
+
+static void __iomem *mpm_timer_base;
+
+uint32_t msm_mpm_get_count(void)
+{
+ uint32_t count;
+ if (!mpm_timer_base)
+ return 0;
+
+ count = __raw_readl_no_log(mpm_timer_base);
+ pr_debug("mpm sclk sync:(%u)", count);
+ return count;
+}
+EXPORT_SYMBOL(msm_mpm_get_count);
+
+static inline void msm_mpmctr_show_count(void)
+{
+ unsigned long long t;
+ unsigned long nsec_rem;
+
+ t = sched_clock();
+
+ nsec_rem = do_div(t, 1000000000)/1000;
+
+ printk(KERN_INFO "mpm_counter: [%5lu.%06lu]:(%u)\n",
+ (unsigned long)t, nsec_rem,
+ msm_mpm_get_count());
+
+}
+
+static struct of_device_id msm_mpmctr_of_match[] = {
+ {.compatible = "qcom,mpm-counter"},
+ {}
+};
+
+static struct platform_driver msm_mpmctr_driver = {
+ .driver = {
+ .name = "msm_mpctr",
+ .owner = THIS_MODULE,
+ .of_match_table = msm_mpmctr_of_match,
+ },
+};
+
+static int __init mpmctr_set_register(struct device_node *np)
+{
+ if (of_get_address(np, 0, NULL, NULL)) {
+ mpm_timer_base = of_iomap(np, 0);
+ if (!mpm_timer_base) {
+ pr_err("%s: cannot map timer base\n", __func__);
+ return -ENOMEM;
+ }
+ }
+ return 0;
+}
+
+static int __init msm_mpmctr_probe(struct platform_device *pdev)
+{
+ if (!pdev->dev.of_node)
+ return -ENODEV;
+
+ if (mpmctr_set_register(pdev->dev.of_node))
+ return -ENODEV;
+
+ msm_mpmctr_show_count();
+
+ return 0;
+}
+
+static int __init mpmctr_init(void)
+{
+ return platform_driver_probe(&msm_mpmctr_driver, msm_mpmctr_probe);
+}
+
+module_init(mpmctr_init)
diff --git a/arch/arm/mach-msm/no-pm.c b/arch/arm/mach-msm/no-pm.c
index a8d4fdb..0db6e68 100644
--- a/arch/arm/mach-msm/no-pm.c
+++ b/arch/arm/mach-msm/no-pm.c
@@ -37,11 +37,15 @@
void msm_pm_set_irq_extns(struct msm_pm_irq_calls *irq_calls) {}
-enum msm_pm_sleep_mode msm_pm_idle_enter(struct cpuidle_device *dev,
+int msm_pm_idle_prepare(struct cpuidle_device *dev,
struct cpuidle_driver *drv, int index)
{
return -ENOSYS;
}
-void msm_pm_enable_retention(bool enable) {}
+int msm_pm_idle_enter(enum msm_pm_sleep_mode sleep_mode)
+{
+ return -ENOSYS;
+}
+void msm_pm_enable_retention(bool enable) {}
diff --git a/arch/arm/mach-msm/ocmem.c b/arch/arm/mach-msm/ocmem.c
index 534cdc6..4685f02 100644
--- a/arch/arm/mach-msm/ocmem.c
+++ b/arch/arm/mach-msm/ocmem.c
@@ -381,27 +381,6 @@
pr_debug("ocmem: Disabled iface clock\n");
}
-/* Block-Remapper Clock Operations */
-int ocmem_enable_br_clock(void)
-{
- int ret;
-
- ret = clk_prepare_enable(ocmem_pdata->br_clk);
-
- if (ret) {
- pr_err("ocmem: Failed to enable br clock\n");
- return ret;
- }
- pr_debug("ocmem: Enabled br clock\n");
- return 0;
-}
-
-void ocmem_disable_br_clock(void)
-{
- clk_disable_unprepare(ocmem_pdata->br_clk);
- pr_debug("ocmem: Disabled br clock\n");
-}
-
static struct ocmem_plat_data * __devinit parse_dt_config
(struct platform_device *pdev)
{
@@ -714,7 +693,7 @@
}
/* Enable the ocmem graphics mpU as a workaround */
-/* This will be programmed by TZ after TZ support is integrated */
+#ifdef CONFIG_MSM_OCMEM_NONSECURE
static int ocmem_init_gfx_mpu(struct platform_device *pdev)
{
int rc;
@@ -735,6 +714,12 @@
ocmem_disable_core_clock();
return 0;
}
+#else
+static int ocmem_init_gfx_mpu(struct platform_device *pdev)
+{
+ return 0;
+}
+#endif /* CONFIG_MSM_OCMEM_NONSECURE */
static int __devinit ocmem_debugfs_init(struct platform_device *pdev)
{
@@ -762,7 +747,6 @@
struct device *dev = &pdev->dev;
struct clk *ocmem_core_clk = NULL;
struct clk *ocmem_iface_clk = NULL;
- struct clk *ocmem_br_clk = NULL;
if (!pdev->dev.of_node) {
dev_info(dev, "Missing Configuration in Device Tree\n");
@@ -799,19 +783,17 @@
if (IS_ERR_OR_NULL(ocmem_iface_clk))
ocmem_iface_clk = NULL;
- ocmem_br_clk = devm_clk_get(dev, "br_clk");
-
- if (IS_ERR(ocmem_br_clk)) {
- dev_err(dev, "Unable to get the BR clock\n");
- return PTR_ERR(ocmem_br_clk);
- }
ocmem_pdata->core_clk = ocmem_core_clk;
ocmem_pdata->iface_clk = ocmem_iface_clk;
- ocmem_pdata->br_clk = ocmem_br_clk;
platform_set_drvdata(pdev, ocmem_pdata);
+ /* Parameter to be updated based on TZ */
+ /* Allow the OCMEM CSR to be programmed */
+ if (ocmem_enable_sec_program(OCMEM_SECURE_DEV_ID))
+ return -EBUSY;
+
if (ocmem_debugfs_init(pdev))
return -EBUSY;
diff --git a/arch/arm/mach-msm/ocmem_api.c b/arch/arm/mach-msm/ocmem_api.c
index ef3cbae..16dd8b8 100644
--- a/arch/arm/mach-msm/ocmem_api.c
+++ b/arch/arm/mach-msm/ocmem_api.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
@@ -52,9 +52,10 @@
ret = process_free(id, handle);
mutex_unlock(&handle->handle_mutex);
- if (ret)
- return -EINVAL;
-
+ if (ret) {
+ pr_err("ocmem: Free failed for client %s\n", get_name(id));
+ return ret;
+ }
free_handle(handle);
return 0;
}
@@ -400,6 +401,40 @@
}
EXPORT_SYMBOL(ocmem_unmap);
+int ocmem_drop(int client_id, struct ocmem_buf *buffer,
+ struct ocmem_map_list *list)
+{
+ int ret = 0;
+ struct ocmem_handle *handle = NULL;
+
+ if (!check_id(client_id)) {
+ pr_err("ocmem: Invalid client id: %d\n", client_id);
+ return -EINVAL;
+ }
+
+ if (!zone_active(client_id)) {
+ pr_err("ocmem: Client id: %s (id: %d) not allowed to use OCMEM\n",
+ get_name(client_id), client_id);
+ return -EINVAL;
+ }
+
+ if (!buffer) {
+ pr_err("ocmem: Invalid buffer\n");
+ return -EINVAL;
+ }
+
+ if (pre_validate_chunk_list(list) != 0)
+ return -EINVAL;
+
+ handle = buffer_to_handle(buffer);
+ mutex_lock(&handle->handle_mutex);
+ ret = process_drop(client_id, handle, list);
+ mutex_unlock(&handle->handle_mutex);
+ return ret;
+}
+EXPORT_SYMBOL(ocmem_drop);
+
+
int ocmem_dump(int client_id, struct ocmem_buf *buffer,
unsigned long dst_phys_addr)
{
diff --git a/arch/arm/mach-msm/ocmem_core.c b/arch/arm/mach-msm/ocmem_core.c
index 612c9fa..4ea1de9 100644
--- a/arch/arm/mach-msm/ocmem_core.c
+++ b/arch/arm/mach-msm/ocmem_core.c
@@ -17,6 +17,7 @@
#include <mach/ocmem_priv.h>
#include <mach/rpm-smd.h>
+#include <mach/scm.h>
static unsigned num_regions;
static unsigned num_macros;
@@ -514,6 +515,23 @@
ocmem_clear(offset, len);
return 0;
}
+
+int ocmem_enable_sec_program(int sec_id)
+{
+ return 0;
+}
+
+int ocmem_enable_dump(enum ocmem_client id, unsigned long offset,
+ unsigned long len)
+{
+ return 0;
+}
+
+int ocmem_disable_dump(enum ocmem_client id, unsigned long offset,
+ unsigned long len)
+{
+ return 0;
+}
#else
static int ocmem_gfx_mpu_set(unsigned long offset, unsigned long len)
{
@@ -532,19 +550,117 @@
static int do_lock(enum ocmem_client id, unsigned long offset,
unsigned long len, enum region_mode mode)
{
- return 0;
+ int rc;
+ struct ocmem_tz_lock {
+ u32 id;
+ u32 offset;
+ u32 size;
+ } request;
+
+ request.id = get_tz_id(id);
+ request.offset = offset;
+ request.size = len;
+
+ rc = scm_call(OCMEM_SVC_ID, OCMEM_LOCK_CMD_ID, &request,
+ sizeof(request), NULL, 0);
+ if (rc)
+ pr_err("ocmem: Failed to lock region %s[%lx -- %lx] ret = %d\n",
+ get_name(id), offset, offset + len - 1, rc);
+ return rc;
}
static int do_unlock(enum ocmem_client id, unsigned long offset,
unsigned long len)
{
- return 0;
+ int rc;
+ struct ocmem_tz_unlock {
+ u32 id;
+ u32 offset;
+ u32 size;
+ } request;
+
+ request.id = get_tz_id(id);
+ request.offset = offset;
+ request.size = len;
+
+ rc = scm_call(OCMEM_SVC_ID, OCMEM_UNLOCK_CMD_ID, &request,
+ sizeof(request), NULL, 0);
+ if (rc)
+ pr_err("ocmem: Failed to unlock region %s[%lx -- %lx] ret = %d\n",
+ get_name(id), offset, offset + len - 1, rc);
+ return rc;
+}
+
+int ocmem_enable_dump(enum ocmem_client id, unsigned long offset,
+ unsigned long len)
+{
+ int rc;
+ struct ocmem_tz_en_dump {
+ u32 id;
+ u32 offset;
+ u32 size;
+ } request;
+
+ request.id = get_tz_id(id);
+ request.offset = offset;
+ request.size = len;
+
+ rc = scm_call(OCMEM_SVC_ID, OCMEM_ENABLE_DUMP_CMD_ID, &request,
+ sizeof(request), NULL, 0);
+ if (rc)
+ pr_err("ocmem: Failed to enable dump %s[%lx -- %lx] ret = %d\n",
+ get_name(id), offset, offset + len - 1, rc);
+ return rc;
+}
+
+int ocmem_disable_dump(enum ocmem_client id, unsigned long offset,
+ unsigned long len)
+{
+ int rc;
+ struct ocmem_tz_dis_dump {
+ u32 id;
+ u32 offset;
+ u32 size;
+ } request;
+
+ request.id = get_tz_id(id);
+ request.offset = offset;
+ request.size = len;
+
+ rc = scm_call(OCMEM_SVC_ID, OCMEM_DISABLE_DUMP_CMD_ID, &request,
+ sizeof(request), NULL, 0);
+ if (rc)
+ pr_err("ocmem: Failed to disable dump %s[%lx -- %lx] ret = %d\n",
+ get_name(id), offset, offset + len - 1, rc);
+ return rc;
+}
+
+int ocmem_enable_sec_program(int sec_id)
+{
+ int rc, scm_ret = 0;
+ struct msm_scm_sec_cfg {
+ unsigned int id;
+ unsigned int spare;
+ } cfg;
+
+ cfg.id = sec_id;
+
+ rc = scm_call(OCMEM_SECURE_SVC_ID, OCMEM_SECURE_CFG_ID, &cfg,
+ sizeof(cfg), &scm_ret, sizeof(scm_ret));
+
+ if (rc || scm_ret) {
+ pr_err("ocmem: Failed to enable secure programming\n");
+ return rc ? rc : -EINVAL;
+ }
+
+ return rc;
}
#endif /* CONFIG_MSM_OCMEM_NONSECURE */
int ocmem_lock(enum ocmem_client id, unsigned long offset, unsigned long len,
enum region_mode mode)
{
+ int rc = 0;
if (len < OCMEM_MIN_ALLOC) {
pr_err("ocmem: Invalid len %lx for lock\n", len);
@@ -561,27 +677,38 @@
commit_region_modes();
- do_lock(id, offset, len, mode);
+ rc = do_lock(id, offset, len, mode);
+ if (rc)
+ goto lock_fail;
mutex_unlock(®ion_ctrl_lock);
return 0;
-
+lock_fail:
+ switch_region_mode(offset, len, MODE_DEFAULT);
switch_region_fail:
+ ocmem_gfx_mpu_remove();
mutex_unlock(®ion_ctrl_lock);
return -EINVAL;
}
int ocmem_unlock(enum ocmem_client id, unsigned long offset, unsigned long len)
{
+ int rc = 0;
+
if (id == OCMEM_GRAPHICS)
ocmem_gfx_mpu_remove();
mutex_lock(®ion_ctrl_lock);
- do_unlock(id, offset, len);
+ rc = do_unlock(id, offset, len);
+ if (rc)
+ goto unlock_fail;
switch_region_mode(offset, len , MODE_DEFAULT);
commit_region_modes();
mutex_unlock(®ion_ctrl_lock);
return 0;
+unlock_fail:
+ mutex_unlock(®ion_ctrl_lock);
+ return -EINVAL;
}
#if defined(CONFIG_MSM_OCMEM_POWER_DISABLE)
@@ -598,9 +725,6 @@
if (rc < 0)
return rc;
- rc = ocmem_enable_br_clock();
- if (rc < 0)
- return rc;
return 0;
}
diff --git a/arch/arm/mach-msm/ocmem_rdm.c b/arch/arm/mach-msm/ocmem_rdm.c
index c0603d6..4190aea 100644
--- a/arch/arm/mach-msm/ocmem_rdm.c
+++ b/arch/arm/mach-msm/ocmem_rdm.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
@@ -296,10 +296,6 @@
init_completion(&dm_clear_event);
init_completion(&dm_transfer_event);
- /* Clear DM Mask */
- ocmem_write(DM_MASK_RESET, dm_base + DM_INTR_MASK);
- /* enable dm interrupts */
- ocmem_write(DM_INTR_RESET, dm_base + DM_INTR_CLR);
ocmem_disable_core_clock();
return 0;
}
diff --git a/arch/arm/mach-msm/ocmem_sched.c b/arch/arm/mach-msm/ocmem_sched.c
index 2cff74b..868fd1a 100644
--- a/arch/arm/mach-msm/ocmem_sched.c
+++ b/arch/arm/mach-msm/ocmem_sched.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
@@ -25,16 +25,19 @@
#include <mach/ocmem_priv.h>
enum request_states {
- R_FREE = 0x0, /* request is not allocated */
- R_PENDING, /* request has a pending operation */
- R_ALLOCATED, /* request has been allocated */
- R_MUST_GROW, /* request must grow as a part of pending operation */
- R_MUST_SHRINK, /* request must shrink as a part of pending operation */
- R_MUST_MAP, /* request must be mapped before being used */
- R_MUST_UNMAP, /* request must be unmapped when not being used */
- R_MAPPED, /* request is mapped and actively used by client */
- R_UNMAPPED, /* request is not mapped, so it's not in active use */
- R_EVICTED, /* request is evicted and must be restored */
+ R_FREE = 0x0, /* request is not allocated */
+ R_PENDING, /* request has a pending operation */
+ R_ALLOCATED, /* request has been allocated */
+ R_ENQUEUED, /* request has been enqueued for future retry */
+ R_MUST_GROW, /* request must grow as a part of pending operation */
+ R_MUST_SHRINK, /* request must shrink */
+ R_WF_SHRINK, /* shrink must be ack'ed by a client */
+ R_SHRUNK, /* request was shrunk */
+ R_MUST_MAP, /* request must be mapped before being used */
+ R_MUST_UNMAP, /* request must be unmapped when not being used */
+ R_MAPPED, /* request is mapped and actively used by client */
+ R_UNMAPPED, /* request is not mapped, so it's not in active use */
+ R_EVICTED, /* request is evicted and must be restored */
};
#define SET_STATE(x, val) (set_bit((val), &(x)->state))
@@ -109,6 +112,16 @@
OCMEM_SYSNOC = 3,
};
+enum ocmem_tz_client {
+ TZ_UNUSED = 0x0,
+ TZ_GRAPHICS,
+ TZ_VIDEO,
+ TZ_LP_AUDIO,
+ TZ_SENSORS,
+ TZ_OTHER_OS,
+ TZ_DEBUG,
+};
+
/**
* Primary OCMEM Arbitration Table
**/
@@ -117,20 +130,30 @@
int priority;
int mode;
int hw_interconnect;
+ int tz_id;
} ocmem_client_table[OCMEM_CLIENT_MAX] = {
- {OCMEM_GRAPHICS, PRIO_GFX, OCMEM_PERFORMANCE, OCMEM_PORT},
- {OCMEM_VIDEO, PRIO_VIDEO, OCMEM_PERFORMANCE, OCMEM_OCMEMNOC},
- {OCMEM_CAMERA, NO_PRIO, OCMEM_PERFORMANCE, OCMEM_OCMEMNOC},
- {OCMEM_HP_AUDIO, PRIO_HP_AUDIO, OCMEM_PASSIVE, OCMEM_BLOCKED},
- {OCMEM_VOICE, PRIO_VOICE, OCMEM_PASSIVE, OCMEM_BLOCKED},
- {OCMEM_LP_AUDIO, PRIO_LP_AUDIO, OCMEM_LOW_POWER, OCMEM_SYSNOC},
- {OCMEM_SENSORS, PRIO_SENSORS, OCMEM_LOW_POWER, OCMEM_SYSNOC},
- {OCMEM_OTHER_OS, PRIO_OTHER_OS, OCMEM_LOW_POWER, OCMEM_SYSNOC},
+ {OCMEM_GRAPHICS, PRIO_GFX, OCMEM_PERFORMANCE, OCMEM_PORT,
+ TZ_GRAPHICS},
+ {OCMEM_VIDEO, PRIO_VIDEO, OCMEM_PERFORMANCE, OCMEM_OCMEMNOC,
+ TZ_VIDEO},
+ {OCMEM_CAMERA, NO_PRIO, OCMEM_PERFORMANCE, OCMEM_OCMEMNOC,
+ TZ_UNUSED},
+ {OCMEM_HP_AUDIO, PRIO_HP_AUDIO, OCMEM_PASSIVE, OCMEM_BLOCKED,
+ TZ_UNUSED},
+ {OCMEM_VOICE, PRIO_VOICE, OCMEM_PASSIVE, OCMEM_BLOCKED,
+ TZ_UNUSED},
+ {OCMEM_LP_AUDIO, PRIO_LP_AUDIO, OCMEM_LOW_POWER, OCMEM_SYSNOC,
+ TZ_LP_AUDIO},
+ {OCMEM_SENSORS, PRIO_SENSORS, OCMEM_LOW_POWER, OCMEM_SYSNOC,
+ TZ_SENSORS},
+ {OCMEM_OTHER_OS, PRIO_OTHER_OS, OCMEM_LOW_POWER, OCMEM_SYSNOC,
+ TZ_OTHER_OS},
};
static struct rb_root sched_tree;
static struct mutex sched_mutex;
static struct mutex allocation_mutex;
+static struct mutex free_mutex;
/* A region represents a continuous interval in OCMEM address space */
struct ocmem_region {
@@ -225,6 +248,14 @@
WIDE_MODE : THIN_MODE;
}
+inline int get_tz_id(int id)
+{
+ if (!check_id(id))
+ return TZ_UNUSED;
+ else
+ return ocmem_client_table[id].tz_id;
+}
+
/* Returns the address that can be used by a device core to access OCMEM */
static unsigned long device_address(int id, unsigned long addr)
{
@@ -489,12 +520,21 @@
return TEST_STATE(req, R_MAPPED);
}
+static inline int is_pending_shrink(struct ocmem_req *req)
+{
+ return TEST_STATE(req, R_MUST_SHRINK) ||
+ TEST_STATE(req, R_WF_SHRINK);
+}
+
/* Must be called with sched_mutex held */
static int __sched_unmap(struct ocmem_req *req)
{
struct ocmem_req *matched_req = NULL;
struct ocmem_region *matched_region = NULL;
+ if (!TEST_STATE(req, R_MAPPED))
+ goto invalid_op_error;
+
matched_region = find_region_match(req->req_start, req->req_end);
matched_req = find_req_match(req->req_id, matched_region);
@@ -606,13 +646,6 @@
goto iface_clock_fail;
}
- if (is_remapped_access(req->owner)) {
- rc = ocmem_enable_br_clock();
-
- if (rc < 0)
- goto br_clock_fail;
- }
-
rc = ocmem_lock(req->owner, phys_to_offset(req->req_start), req->req_sz,
get_mode(req->owner));
@@ -636,9 +669,6 @@
process_map_fail:
ocmem_unlock(req->owner, phys_to_offset(req->req_start), req->req_sz);
lock_failed:
- if (is_remapped_access(req->owner))
- ocmem_disable_br_clock();
-br_clock_fail:
if (is_iface_access(req->owner))
ocmem_disable_iface_clock();
iface_clock_fail:
@@ -667,8 +697,6 @@
goto unlock_failed;
}
- if (is_remapped_access(req->owner))
- ocmem_disable_br_clock();
if (is_iface_access(req->owner))
ocmem_disable_iface_clock();
ocmem_disable_core_clock();
@@ -1036,8 +1064,8 @@
retry = false;
- pr_debug("ocmem: do_allocate: %s request size %lx\n",
- get_name(owner), sz);
+ pr_debug("ocmem: do_allocate: %s request %p size %lx\n",
+ get_name(owner), req, sz);
retry_next_step:
@@ -1158,14 +1186,34 @@
return OP_FAIL;
}
+/* Remove the request from eviction lists */
+static void cancel_restore(struct ocmem_req *e_handle,
+ struct ocmem_req *req)
+{
+ struct ocmem_eviction_data *edata = e_handle->edata;
+
+ if (!edata || !req)
+ return;
+
+ if (list_empty(&edata->req_list))
+ return;
+
+ list_del_init(&req->eviction_list);
+ req->e_handle = NULL;
+
+ return;
+}
+
static int sched_enqueue(struct ocmem_req *priv)
{
struct ocmem_req *next = NULL;
mutex_lock(&sched_queue_mutex);
+ SET_STATE(priv, R_ENQUEUED);
list_add_tail(&priv->sched_list, &sched_queue[priv->owner]);
pr_debug("enqueued req %p\n", priv);
list_for_each_entry(next, &sched_queue[priv->owner], sched_list) {
- pr_debug("pending requests for client %p\n", next);
+ pr_debug("pending request %p for client %s\n", next,
+ get_name(next->owner));
}
mutex_unlock(&sched_queue_mutex);
return 0;
@@ -1190,13 +1238,13 @@
list_for_each_entry_safe(req, next, &sched_queue[id], sched_list)
{
if (req == victim_req) {
- pr_debug("ocmem: Cancelling pending request %p\n",
- req);
- list_del(&req->sched_list);
- goto dequeue_done;
+ pr_debug("ocmem: Cancelling pending request %p for %s\n",
+ req, get_name(req->owner));
+ list_del_init(&victim_req->sched_list);
+ CLEAR_STATE(victim_req, R_ENQUEUED);
+ break;
}
}
-
dequeue_done:
mutex_unlock(&sched_queue_mutex);
return;
@@ -1218,7 +1266,8 @@
pr_debug("ocmem: Fetched pending request %p\n",
req);
list_del(&req->sched_list);
- break;
+ CLEAR_STATE(req, R_ENQUEUED);
+ break;
}
}
}
@@ -1412,37 +1461,70 @@
unsigned long offset = 0;
int rc = 0;
+ mutex_lock(&free_mutex);
+
if (is_blocked(id)) {
pr_err("Client %d cannot request free\n", id);
- return -EINVAL;
+ goto free_invalid;
}
req = handle_to_req(handle);
buffer = handle_to_buffer(handle);
- if (!req)
- return -EINVAL;
+ if (!req) {
+ pr_err("ocmem: No valid request to free\n");
+ goto free_invalid;
+ }
if (req->req_start != core_address(id, buffer->addr)) {
pr_err("Invalid buffer handle passed for free\n");
- return -EINVAL;
+ goto free_invalid;
}
- mutex_lock(&sched_mutex);
- sched_dequeue(req);
- mutex_unlock(&sched_mutex);
+ if (req->edata != NULL) {
+ pr_err("ocmem: Request %p(%2lx) yet to process eviction %p\n",
+ req, req->state, req->edata);
+ goto free_invalid;
+ }
+
+ if (is_pending_shrink(req)) {
+ pr_err("ocmem: Request %p(%2lx) yet to process eviction\n",
+ req, req->state);
+ goto pending_shrink;
+ }
+
+ /* Remove the request from any restore lists */
+ if (req->e_handle)
+ cancel_restore(req->e_handle, req);
+
+ /* Remove the request from any pending opreations */
+ if (TEST_STATE(req, R_ENQUEUED)) {
+ mutex_lock(&sched_mutex);
+ sched_dequeue(req);
+ mutex_unlock(&sched_mutex);
+ }
if (!TEST_STATE(req, R_FREE)) {
- rc = process_unmap(req, req->req_start, req->req_end);
- if (rc < 0)
- return -EINVAL;
+ if (TEST_STATE(req, R_MAPPED)) {
+ /* unmap the interval and clear the memory */
+ rc = process_unmap(req, req->req_start, req->req_end);
- rc = do_free(req);
- if (rc < 0)
- return -EINVAL;
+ if (rc < 0) {
+ pr_err("ocmem: Failed to unmap %p\n", req);
+ goto free_fail;
+ }
+
+ rc = do_free(req);
+ if (rc < 0) {
+ pr_err("ocmem: Failed to free %p\n", req);
+ goto free_fail;
+ }
+ } else
+ pr_debug("request %p was already shrunk to 0\n", req);
}
+ /* Turn off the memory */
if (req->req_sz != 0) {
offset = phys_to_offset(req->req_start);
@@ -1451,18 +1533,33 @@
if (rc < 0) {
pr_err("Failed to switch OFF memory macros\n");
- return -EINVAL;
+ goto free_fail;
}
}
+ if (!TEST_STATE(req, R_FREE)) {
+ /* free the allocation */
+ rc = do_free(req);
+ if (rc < 0)
+ return -EINVAL;
+ }
+
inc_ocmem_stat(zone_of(req), NR_FREES);
ocmem_destroy_req(req);
handle->req = NULL;
ocmem_schedule_pending();
+ mutex_unlock(&free_mutex);
return 0;
+free_fail:
+free_invalid:
+ mutex_unlock(&free_mutex);
+ return -EINVAL;
+pending_shrink:
+ mutex_unlock(&free_mutex);
+ return -EAGAIN;
}
static void ocmem_rdm_worker(struct work_struct *work)
@@ -1512,6 +1609,42 @@
return 0;
}
+int process_drop(int id, struct ocmem_handle *handle,
+ struct ocmem_map_list *list)
+{
+ struct ocmem_req *req = NULL;
+ struct ocmem_buf *buffer = NULL;
+ int rc = 0;
+
+ if (is_blocked(id)) {
+ pr_err("Client %d cannot request drop\n", id);
+ return -EINVAL;
+ }
+
+ if (is_tcm(id))
+ pr_err("Client %d cannot request drop\n", id);
+
+ req = handle_to_req(handle);
+ buffer = handle_to_buffer(handle);
+
+ if (!req)
+ return -EINVAL;
+
+ if (req->req_start != core_address(id, buffer->addr)) {
+ pr_err("Invalid buffer handle passed for drop\n");
+ return -EINVAL;
+ }
+
+ if (TEST_STATE(req, R_MAPPED)) {
+ rc = process_unmap(req, req->req_start, req->req_end);
+ if (rc < 0)
+ return -EINVAL;
+ } else
+ return -EINVAL;
+
+ return 0;
+}
+
int process_xfer_out(int id, struct ocmem_handle *handle,
struct ocmem_map_list *list)
{
@@ -1560,7 +1693,6 @@
goto transfer_in_error;
}
-
inc_ocmem_stat(zone_of(req), NR_TRANSFERS_TO_OCMEM);
rc = queue_transfer(req, handle, list, TO_OCMEM);
@@ -1593,16 +1725,23 @@
if (!req)
return -EINVAL;
+ mutex_lock(&free_mutex);
+
if (req->req_start != core_address(id, buffer->addr)) {
pr_err("Invalid buffer handle passed for shrink\n");
- return -EINVAL;
+ goto shrink_fail;
}
- edata = req->edata;
+ if (!req->e_handle) {
+ pr_err("Unable to find evicting request\n");
+ goto shrink_fail;
+ }
+
+ edata = req->e_handle->edata;
if (!edata) {
pr_err("Unable to find eviction data\n");
- return -EINVAL;
+ goto shrink_fail;
}
pr_debug("Found edata %p in request %p\n", edata, req);
@@ -1611,29 +1750,37 @@
if (size == 0) {
pr_debug("req %p being shrunk to zero\n", req);
- if (is_mapped(req))
+ if (is_mapped(req)) {
rc = process_unmap(req, req->req_start, req->req_end);
if (rc < 0)
- return -EINVAL;
+ goto shrink_fail;
+ }
rc = do_free(req);
if (rc < 0)
- return -EINVAL;
+ goto shrink_fail;
+ SET_STATE(req, R_FREE);
} else {
rc = do_shrink(req, size);
if (rc < 0)
- return -EINVAL;
+ goto shrink_fail;
}
- req->edata = NULL;
CLEAR_STATE(req, R_ALLOCATED);
- SET_STATE(req, R_FREE);
+ CLEAR_STATE(req, R_WF_SHRINK);
+ SET_STATE(req, R_SHRUNK);
if (atomic_dec_and_test(&edata->pending)) {
pr_debug("ocmem: All conflicting allocations were shrunk\n");
complete(&edata->completion);
}
+ mutex_unlock(&free_mutex);
return 0;
+shrink_fail:
+ pr_err("ocmem: Failed to shrink request %p of %s\n",
+ req, get_name(req->owner));
+ mutex_unlock(&free_mutex);
+ return -EINVAL;
}
int process_xfer(int id, struct ocmem_handle *handle,
@@ -1738,11 +1885,12 @@
if (needs_eviction) {
pr_debug("adding %p in region %p to eviction list\n",
e_req, tmp_region);
+ SET_STATE(e_req, R_MUST_SHRINK);
list_add_tail(
&e_req->eviction_list,
&edata->req_list);
atomic_inc(&edata->pending);
- e_req->edata = edata;
+ e_req->e_handle = req;
}
}
} else {
@@ -1752,9 +1900,7 @@
pr_debug("%d requests will be evicted\n", atomic_read(&edata->pending));
- if (!atomic_read(&edata->pending))
- return -EINVAL;
- return 0;
+ return atomic_read(&edata->pending);
}
static void trigger_eviction(struct ocmem_eviction_data *edata)
@@ -1776,8 +1922,10 @@
pr_debug("ocmem: Evicting request %p\n", req);
buffer.addr = req->req_start;
buffer.len = 0x0;
+ CLEAR_STATE(req, R_MUST_SHRINK);
dispatch_notification(req->owner, OCMEM_ALLOC_SHRINK,
&buffer);
+ SET_STATE(req, R_WF_SHRINK);
}
}
return;
@@ -1799,7 +1947,7 @@
rc = __evict_common(edata, NULL);
- if (rc < 0)
+ if (rc == 0)
goto skip_eviction;
trigger_eviction(edata);
@@ -1833,9 +1981,10 @@
edata->passive = false;
+ mutex_lock(&free_mutex);
rc = __evict_common(edata, req);
- if (rc < 0)
+ if (rc == 0)
goto skip_eviction;
trigger_eviction(edata);
@@ -1843,6 +1992,8 @@
pr_debug("ocmem: attaching eviction %p to request %p", edata, req);
req->edata = edata;
+ mutex_unlock(&free_mutex);
+
wait_for_completion(&edata->completion);
pr_debug("ocmem: eviction completed successfully\n");
@@ -1851,28 +2002,30 @@
skip_eviction:
pr_err("ocmem: Unable to run eviction\n");
free_eviction(edata);
- return -EINVAL;
+ req->edata = NULL;
+ mutex_unlock(&free_mutex);
+ return 0;
}
static int __restore_common(struct ocmem_eviction_data *edata)
{
struct ocmem_req *req = NULL;
- struct ocmem_req *next = NULL;
if (!edata)
return -EINVAL;
- list_for_each_entry_safe(req, next, &edata->req_list, eviction_list)
- {
- if (req) {
- pr_debug("ocmem: restoring evicted request %p\n",
- req);
- list_del(&req->eviction_list);
- req->op = SCHED_ALLOCATE;
- sched_enqueue(req);
- inc_ocmem_stat(zone_of(req), NR_RESTORES);
- }
+ while (!list_empty(&edata->req_list)) {
+ req = list_first_entry(&edata->req_list, struct ocmem_req,
+ eviction_list);
+ list_del_init(&req->eviction_list);
+ pr_debug("ocmem: restoring evicted request %p\n",
+ req);
+ req->edata = NULL;
+ req->e_handle = NULL;
+ req->op = SCHED_ALLOCATE;
+ inc_ocmem_stat(zone_of(req), NR_RESTORES);
+ sched_enqueue(req);
}
pr_debug("Scheduled all evicted regions\n");
@@ -1891,12 +2044,15 @@
if (!req->edata)
return 0;
+ mutex_lock(&free_mutex);
rc = __restore_common(req->edata);
+ mutex_unlock(&free_mutex);
if (rc < 0)
return -EINVAL;
free_eviction(req->edata);
+ req->edata = NULL;
return 0;
}
@@ -1908,7 +2064,9 @@
if (!edata)
return -EINVAL;
+ mutex_lock(&free_mutex);
rc = __restore_common(edata);
+ mutex_unlock(&free_mutex);
if (rc < 0) {
pr_err("Failed to restore evicted requests\n");
@@ -1994,6 +2152,7 @@
void __iomem *req_vaddr;
unsigned long offset = 0x0;
+ int rc = 0;
down_write(&req->rw_sem);
@@ -2004,12 +2163,23 @@
if (!req_vaddr)
goto err_do_dump;
+ rc = ocmem_enable_dump(req->owner, offset, req->req_sz);
+
+ if (rc < 0)
+ goto err_do_dump;
+
pr_debug("Dumping client %s buffer ocmem p: %lx (v: %p) to ddr %lx\n",
get_name(req->owner), req->req_start,
req_vaddr, addr);
memcpy((void *)addr, req_vaddr, req->req_sz);
+ rc = ocmem_disable_dump(req->owner, offset, req->req_sz);
+
+ if (rc < 0)
+ pr_err("Failed to secure request %p of %s after dump\n",
+ req, get_name(req->owner));
+
up_write(&req->rw_sem);
return 0;
err_do_dump:
@@ -2260,6 +2430,7 @@
sched_tree = RB_ROOT;
pdata = platform_get_drvdata(pdev);
mutex_init(&allocation_mutex);
+ mutex_init(&free_mutex);
mutex_init(&sched_mutex);
mutex_init(&sched_queue_mutex);
ocmem_vaddr = pdata->vbase;
diff --git a/arch/arm/mach-msm/pil-q6v5-mss.c b/arch/arm/mach-msm/pil-q6v5-mss.c
index e85831a..c1d4ab4 100644
--- a/arch/arm/mach-msm/pil-q6v5-mss.c
+++ b/arch/arm/mach-msm/pil-q6v5-mss.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -24,7 +24,6 @@
#include <linux/of.h>
#include <linux/regulator/consumer.h>
#include <linux/interrupt.h>
-#include <linux/of_gpio.h>
#include <mach/subsystem_restart.h>
#include <mach/clk.h>
@@ -88,8 +87,6 @@
bool crash_shutdown;
bool ignore_errors;
int is_loadable;
- int err_fatal_irq;
- int force_stop_gpio;
};
static int pbl_mba_boot_timeout_ms = 100;
@@ -445,17 +442,18 @@
subsystem_restart_dev(drv->subsys);
}
-static irqreturn_t modem_err_fatal_intr_handler(int irq, void *dev_id)
+static void smsm_state_cb(void *data, uint32_t old_state, uint32_t new_state)
{
- struct mba_data *drv = dev_id;
+ struct mba_data *drv = data;
- /* Ignore if we're the one that set the force stop GPIO */
+ /* Ignore if we're the one that set SMSM_RESET */
if (drv->crash_shutdown)
- return IRQ_HANDLED;
+ return;
- pr_err("Fatal error on the modem.\n");
- restart_modem(drv);
- return IRQ_HANDLED;
+ if (new_state & SMSM_RESET) {
+ pr_err("Probable fatal error on the modem.\n");
+ restart_modem(drv);
+ }
}
static int modem_shutdown(const struct subsys_desc *subsys)
@@ -495,7 +493,7 @@
{
struct mba_data *drv = subsys_to_drv(subsys);
drv->crash_shutdown = true;
- gpio_set_value(drv->force_stop_gpio, 1);
+ smsm_reset_modem(SMSM_RESET);
}
static struct ramdump_segment smem_segments[] = {
@@ -632,11 +630,10 @@
goto err_irq;
}
- ret = devm_request_irq(&pdev->dev, drv->err_fatal_irq,
- modem_err_fatal_intr_handler,
- IRQF_TRIGGER_RISING, "pil-mss", drv);
+ ret = smsm_state_cb_register(SMSM_MODEM_STATE, SMSM_RESET,
+ smsm_state_cb, drv);
if (ret < 0) {
- dev_err(&pdev->dev, "Unable to register SMP2P err fatal handler!\n");
+ dev_err(&pdev->dev, "Unable to register SMSM callback!\n");
goto err_irq;
}
@@ -646,11 +643,14 @@
ret = PTR_ERR(drv->adsp_state_notifier);
dev_err(&pdev->dev, "%s: Registration with the SSR notification driver failed (%d)",
__func__, ret);
- goto err_irq;
+ goto err_smsm;
}
return 0;
+err_smsm:
+ smsm_state_cb_deregister(SMSM_MODEM_STATE, SMSM_RESET, smsm_state_cb,
+ drv);
err_irq:
destroy_ramdump_device(drv->smem_ramdump_dev);
err_ramdump_smem:
@@ -759,7 +759,7 @@
static int __devinit pil_mss_driver_probe(struct platform_device *pdev)
{
struct mba_data *drv;
- int ret, err_fatal_gpio;
+ int ret;
drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
if (!drv)
@@ -774,22 +774,6 @@
return ret;
}
- /* Get the IRQ from the GPIO for registering inbound handler */
- err_fatal_gpio = of_get_named_gpio(pdev->dev.of_node,
- "qcom,gpio-err-fatal", 0);
- if (err_fatal_gpio < 0)
- return err_fatal_gpio;
-
- drv->err_fatal_irq = gpio_to_irq(err_fatal_gpio);
- if (drv->err_fatal_irq < 0)
- return drv->err_fatal_irq;
-
- /* Get the GPIO pin for writing the outbound bits: add more as needed */
- drv->force_stop_gpio = of_get_named_gpio(pdev->dev.of_node,
- "qcom,gpio-force-stop", 0);
- if (drv->force_stop_gpio < 0)
- return drv->force_stop_gpio;
-
return pil_subsys_init(drv, pdev);
}
@@ -799,6 +783,8 @@
subsys_notif_unregister_notifier(drv->adsp_state_notifier,
&adsp_state_notifier_block);
+ smsm_state_cb_deregister(SMSM_MODEM_STATE, SMSM_RESET,
+ smsm_state_cb, drv);
subsys_unregister(drv->subsys);
destroy_ramdump_device(drv->smem_ramdump_dev);
destroy_ramdump_device(drv->ramdump_dev);
diff --git a/arch/arm/mach-msm/pm-8x60.c b/arch/arm/mach-msm/pm-8x60.c
index f7f2fef..0b08238 100644
--- a/arch/arm/mach-msm/pm-8x60.c
+++ b/arch/arm/mach-msm/pm-8x60.c
@@ -479,6 +479,8 @@
}
}
+static void *msm_pm_idle_rs_limits;
+
static void msm_pm_swfi(void)
{
msm_pm_config_hw_before_swfi();
@@ -763,9 +765,8 @@
}
}
-static int msm_pm_idle_prepare(struct cpuidle_device *dev,
- struct cpuidle_driver *drv, int index,
- void **msm_pm_idle_rs_limits)
+int msm_pm_idle_prepare(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int index)
{
int i;
unsigned int power_usage = -1;
@@ -792,6 +793,7 @@
struct cpuidle_state_usage *st_usage = &dev->states_usage[i];
enum msm_pm_sleep_mode mode;
bool allow;
+ void *rs_limits = NULL;
uint32_t power;
int idx;
@@ -838,20 +840,17 @@
/* fall through */
if (pm_sleep_ops.lowest_limits)
- *msm_pm_idle_rs_limits =
- pm_sleep_ops.lowest_limits(
- true, mode,
- &time_param, &power);
+ rs_limits = pm_sleep_ops.lowest_limits(true,
+ mode, &time_param, &power);
if (MSM_PM_DEBUG_IDLE & msm_pm_debug_mask)
pr_info("CPU%u: %s: %s, latency %uus, "
"sleep %uus, limit %p\n",
dev->cpu, __func__, state->desc,
time_param.latency_us,
- time_param.sleep_us,
- *msm_pm_idle_rs_limits);
+ time_param.sleep_us, rs_limits);
- if (!*msm_pm_idle_rs_limits)
+ if (!rs_limits)
allow = false;
break;
@@ -871,6 +870,8 @@
ret = mode;
}
+ if (MSM_PM_SLEEP_MODE_POWER_COLLAPSE == mode)
+ msm_pm_idle_rs_limits = rs_limits;
}
}
@@ -884,27 +885,11 @@
return ret;
}
-enum msm_pm_sleep_mode msm_pm_idle_enter(struct cpuidle_device *dev,
- struct cpuidle_driver *drv, int index)
+int msm_pm_idle_enter(enum msm_pm_sleep_mode sleep_mode)
{
int64_t time;
+ int exit_stat;
bool collapsed = 1;
- int exit_stat = -1;
- enum msm_pm_sleep_mode sleep_mode;
- void *msm_pm_idle_rs_limits = NULL;
- int sleep_delay = 1;
- int ret = -ENODEV;
- int64_t timer_expiration = 0;
- int notify_rpm = false;
- bool timer_halted = false;
-
- sleep_mode = msm_pm_idle_prepare(dev, drv, index,
- &msm_pm_idle_rs_limits);
-
- if (!msm_pm_idle_rs_limits) {
- sleep_mode = MSM_PM_SLEEP_MODE_NOT_SELECTED;
- goto cpuidle_enter_bail;
- }
if (MSM_PM_DEBUG_IDLE & msm_pm_debug_mask)
pr_info("CPU%u: %s: mode %d\n",
@@ -912,80 +897,76 @@
time = ktime_to_ns(ktime_get());
- if (sleep_mode == MSM_PM_SLEEP_MODE_POWER_COLLAPSE) {
- notify_rpm = true;
+ switch (sleep_mode) {
+ case MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT:
+ msm_pm_swfi();
+ exit_stat = MSM_PM_STAT_IDLE_WFI;
+ break;
+
+ case MSM_PM_SLEEP_MODE_RETENTION:
+ msm_pm_retention();
+ exit_stat = MSM_PM_STAT_RETENTION;
+ break;
+
+ case MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE:
+ collapsed = msm_pm_power_collapse_standalone(true);
+ exit_stat = MSM_PM_STAT_IDLE_STANDALONE_POWER_COLLAPSE;
+ break;
+
+ case MSM_PM_SLEEP_MODE_POWER_COLLAPSE: {
+ int64_t timer_expiration = 0;
+ bool timer_halted = false;
+ uint32_t sleep_delay;
+ int ret = -ENODEV;
+ int notify_rpm =
+ (sleep_mode == MSM_PM_SLEEP_MODE_POWER_COLLAPSE);
timer_expiration = msm_pm_timer_enter_idle();
sleep_delay = (uint32_t) msm_pm_convert_and_cap_time(
timer_expiration, MSM_PM_SLEEP_TICK_LIMIT);
if (sleep_delay == 0) /* 0 would mean infinite time */
sleep_delay = 1;
- }
- if (pm_sleep_ops.enter_sleep)
- ret = pm_sleep_ops.enter_sleep(sleep_delay,
- msm_pm_idle_rs_limits,
- true, notify_rpm);
- if (!ret) {
+ if (MSM_PM_DEBUG_IDLE_CLK & msm_pm_debug_mask)
+ clock_debug_print_enabled();
- switch (sleep_mode) {
- case MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT:
- msm_pm_swfi();
- exit_stat = MSM_PM_STAT_IDLE_WFI;
- break;
-
- case MSM_PM_SLEEP_MODE_RETENTION:
- msm_pm_retention();
- exit_stat = MSM_PM_STAT_RETENTION;
- break;
-
- case MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE:
- collapsed = msm_pm_power_collapse_standalone(true);
- exit_stat = MSM_PM_STAT_IDLE_STANDALONE_POWER_COLLAPSE;
- break;
-
- case MSM_PM_SLEEP_MODE_POWER_COLLAPSE:
- if (MSM_PM_DEBUG_IDLE_CLK & msm_pm_debug_mask)
- clock_debug_print_enabled();
-
+ if (pm_sleep_ops.enter_sleep)
+ ret = pm_sleep_ops.enter_sleep(sleep_delay,
+ msm_pm_idle_rs_limits,
+ true, notify_rpm);
+ if (!ret) {
collapsed = msm_pm_power_collapse(true);
timer_halted = true;
- exit_stat = MSM_PM_STAT_IDLE_POWER_COLLAPSE;
- msm_pm_timer_exit_idle(timer_halted);
- break;
-
- case MSM_PM_SLEEP_MODE_NOT_SELECTED:
- goto cpuidle_enter_bail;
- break;
-
- default:
- __WARN();
- goto cpuidle_enter_bail;
- break;
+ if (pm_sleep_ops.exit_sleep)
+ pm_sleep_ops.exit_sleep(msm_pm_idle_rs_limits,
+ true, notify_rpm, collapsed);
}
- if (pm_sleep_ops.exit_sleep)
- pm_sleep_ops.exit_sleep(msm_pm_idle_rs_limits,
- true, notify_rpm, collapsed);
-
- time = ktime_to_ns(ktime_get()) - time;
- msm_pm_ftrace_lpm_exit(smp_processor_id(), sleep_mode,
- collapsed);
- if (exit_stat >= 0)
- msm_pm_add_stat(exit_stat, time);
- do_div(time, 1000);
- dev->last_residency = (int) time;
- return sleep_mode;
-
- } else if (sleep_mode == MSM_PM_SLEEP_MODE_POWER_COLLAPSE) {
msm_pm_timer_exit_idle(timer_halted);
- sleep_mode = MSM_PM_SLEEP_MODE_NOT_SELECTED;
- } else
- sleep_mode = MSM_PM_SLEEP_MODE_NOT_SELECTED;
+ exit_stat = MSM_PM_STAT_IDLE_POWER_COLLAPSE;
+ break;
+ }
+
+ case MSM_PM_SLEEP_MODE_NOT_SELECTED:
+ goto cpuidle_enter_bail;
+ break;
+
+ default:
+ __WARN();
+ goto cpuidle_enter_bail;
+ break;
+ }
+
+ time = ktime_to_ns(ktime_get()) - time;
+ msm_pm_add_stat(exit_stat, time);
+ msm_pm_ftrace_lpm_exit(smp_processor_id(), sleep_mode,
+ collapsed);
+
+ do_div(time, 1000);
+ return (int) time;
cpuidle_enter_bail:
- dev->last_residency = 0;
- return sleep_mode;
+ return 0;
}
void msm_pm_cpu_enter_lowpower(unsigned int cpu)
diff --git a/arch/arm/mach-msm/pm.h b/arch/arm/mach-msm/pm.h
index 43bb7de..399194a 100644
--- a/arch/arm/mach-msm/pm.h
+++ b/arch/arm/mach-msm/pm.h
@@ -108,9 +108,10 @@
};
void msm_pm_set_platform_data(struct msm_pm_platform_data *data, int count);
-enum msm_pm_sleep_mode msm_pm_idle_enter(struct cpuidle_device *dev,
+int msm_pm_idle_prepare(struct cpuidle_device *dev,
struct cpuidle_driver *drv, int index);
void msm_pm_set_irq_extns(struct msm_pm_irq_calls *irq_calls);
+int msm_pm_idle_enter(enum msm_pm_sleep_mode sleep_mode);
void msm_pm_cpu_enter_lowpower(unsigned int cpu);
void __init msm_pm_set_tz_retention_flag(unsigned int flag);
void msm_pm_enable_retention(bool enable);
diff --git a/arch/arm/mach-msm/qdsp5/audio_mvs.c b/arch/arm/mach-msm/qdsp5/audio_mvs.c
index 7d2766d..d1aba82 100644
--- a/arch/arm/mach-msm/qdsp5/audio_mvs.c
+++ b/arch/arm/mach-msm/qdsp5/audio_mvs.c
@@ -1734,6 +1734,7 @@
{
MM_DBG("\n");
+ wake_lock_destroy(&audio_mvs_info.suspend_lock);
misc_deregister(&audio_mvs_misc);
}
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
index 172c7eb..654f547 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
@@ -1317,6 +1317,8 @@
}
/* Flush DSP */
rc = audio_aio_flush(audio);
+ /* Flush input / Output buffer in software*/
+ audio_aio_ioport_reset(audio);
if (rc < 0) {
pr_err("%s[%p]:AUDIO_FLUSH interrupted\n",
__func__, audio);
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 4147b44..bf022ac 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -1170,10 +1170,10 @@
this_dbs_info->cur_policy = NULL;
if (!cpu)
input_unregister_handler(&dbs_input_handler);
- mutex_unlock(&dbs_mutex);
if (!dbs_enable)
sysfs_remove_group(cpufreq_global_kobject,
&dbs_attr_group);
+ mutex_unlock(&dbs_mutex);
break;
diff --git a/drivers/gpu/ion/Makefile b/drivers/gpu/ion/Makefile
index 51349f6..60a6b81 100644
--- a/drivers/gpu/ion/Makefile
+++ b/drivers/gpu/ion/Makefile
@@ -1,4 +1,4 @@
obj-$(CONFIG_ION) += ion.o ion_heap.o ion_system_heap.o ion_carveout_heap.o ion_iommu_heap.o ion_cp_heap.o
-obj-$(CONFIG_CMA) += ion_cma_heap.o
+obj-$(CONFIG_CMA) += ion_cma_heap.o ion_cma_secure_heap.o
obj-$(CONFIG_ION_TEGRA) += tegra/
obj-$(CONFIG_ION_MSM) += msm/
diff --git a/drivers/gpu/ion/ion_cma_secure_heap.c b/drivers/gpu/ion/ion_cma_secure_heap.c
new file mode 100644
index 0000000..2c0e5ae
--- /dev/null
+++ b/drivers/gpu/ion/ion_cma_secure_heap.c
@@ -0,0 +1,409 @@
+/*
+ * drivers/gpu/ion/ion_secure_cma_heap.c
+ *
+ * Copyright (C) Linaro 2012
+ * Author: <benjamin.gaignard@linaro.org> for ST-Ericsson.
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/ion.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/dma-mapping.h>
+#include <linux/msm_ion.h>
+#include <mach/iommu_domains.h>
+
+#include <asm/cacheflush.h>
+
+/* for ion_heap_ops structure */
+#include "ion_priv.h"
+#include "msm/ion_cp_common.h"
+
+#define ION_CMA_ALLOCATE_FAILED NULL
+
+struct ion_secure_cma_buffer_info {
+ /*
+ * This needs to come first for compatibility with the secure buffer API
+ */
+ struct ion_cp_buffer secure;
+ void *cpu_addr;
+ dma_addr_t handle;
+ struct sg_table *table;
+ bool is_cached;
+};
+
+static int cma_heap_has_outer_cache;
+/*
+ * Create scatter-list for the already allocated DMA buffer.
+ * This function could be replace by dma_common_get_sgtable
+ * as soon as it will avalaible.
+ */
+int ion_secure_cma_get_sgtable(struct device *dev, struct sg_table *sgt,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ struct page *page = virt_to_page(cpu_addr);
+ int ret;
+
+ ret = sg_alloc_table(sgt, 1, GFP_KERNEL);
+ if (unlikely(ret))
+ return ret;
+
+ sg_set_page(sgt->sgl, page, PAGE_ALIGN(size), 0);
+ sg_dma_address(sgt->sgl) = handle;
+ return 0;
+}
+
+/* ION CMA heap operations functions */
+static struct ion_secure_cma_buffer_info *__ion_secure_cma_allocate(
+ struct ion_heap *heap, struct ion_buffer *buffer,
+ unsigned long len, unsigned long align,
+ unsigned long flags)
+{
+ struct device *dev = heap->priv;
+ struct ion_secure_cma_buffer_info *info;
+
+ dev_dbg(dev, "Request buffer allocation len %ld\n", len);
+
+ info = kzalloc(sizeof(struct ion_secure_cma_buffer_info), GFP_KERNEL);
+ if (!info) {
+ dev_err(dev, "Can't allocate buffer info\n");
+ return ION_CMA_ALLOCATE_FAILED;
+ }
+
+ if (!ION_IS_CACHED(flags))
+ info->cpu_addr = dma_alloc_writecombine(dev, len,
+ &(info->handle), 0);
+ else
+ info->cpu_addr = dma_alloc_nonconsistent(dev, len,
+ &(info->handle), 0);
+
+ if (!info->cpu_addr) {
+ dev_err(dev, "Fail to allocate buffer\n");
+ goto err;
+ }
+
+ info->table = kmalloc(sizeof(struct sg_table), GFP_KERNEL);
+ if (!info->table) {
+ dev_err(dev, "Fail to allocate sg table\n");
+ goto err;
+ }
+
+ info->is_cached = ION_IS_CACHED(flags);
+
+ ion_secure_cma_get_sgtable(dev,
+ info->table, info->cpu_addr, info->handle, len);
+
+ info->secure.buffer = info->handle;
+
+ /* keep this for memory release */
+ buffer->priv_virt = info;
+ dev_dbg(dev, "Allocate buffer %p\n", buffer);
+ return info;
+
+err:
+ kfree(info);
+ return ION_CMA_ALLOCATE_FAILED;
+}
+
+static int ion_secure_cma_allocate(struct ion_heap *heap,
+ struct ion_buffer *buffer,
+ unsigned long len, unsigned long align,
+ unsigned long flags)
+{
+ unsigned long secure_allocation = flags & ION_SECURE;
+ struct ion_secure_cma_buffer_info *buf = NULL;
+
+ if (!secure_allocation) {
+ pr_err("%s: non-secure allocation disallowed from heap %s %lx\n",
+ __func__, heap->name, flags);
+ return -ENOMEM;
+ }
+
+ buf = __ion_secure_cma_allocate(heap, buffer, len, align, flags);
+
+ if (buf) {
+ buf->secure.want_delayed_unsecure = 0;
+ atomic_set(&buf->secure.secure_cnt, 0);
+ mutex_init(&buf->secure.lock);
+ buf->secure.is_secure = 1;
+ return 0;
+ } else {
+ return -ENOMEM;
+ }
+}
+
+
+static void ion_secure_cma_free(struct ion_buffer *buffer)
+{
+ struct device *dev = buffer->heap->priv;
+ struct ion_secure_cma_buffer_info *info = buffer->priv_virt;
+
+ dev_dbg(dev, "Release buffer %p\n", buffer);
+ /* release memory */
+ dma_free_coherent(dev, buffer->size, info->cpu_addr, info->handle);
+ /* release sg table */
+ kfree(info->table);
+ kfree(info);
+}
+
+static int ion_secure_cma_phys(struct ion_heap *heap, struct ion_buffer *buffer,
+ ion_phys_addr_t *addr, size_t *len)
+{
+ struct device *dev = heap->priv;
+ struct ion_secure_cma_buffer_info *info = buffer->priv_virt;
+
+ dev_dbg(dev, "Return buffer %p physical address 0x%x\n", buffer,
+ info->handle);
+
+ *addr = info->handle;
+ *len = buffer->size;
+
+ return 0;
+}
+
+struct sg_table *ion_secure_cma_heap_map_dma(struct ion_heap *heap,
+ struct ion_buffer *buffer)
+{
+ struct ion_secure_cma_buffer_info *info = buffer->priv_virt;
+
+ return info->table;
+}
+
+void ion_secure_cma_heap_unmap_dma(struct ion_heap *heap,
+ struct ion_buffer *buffer)
+{
+ return;
+}
+
+static int ion_secure_cma_mmap(struct ion_heap *mapper,
+ struct ion_buffer *buffer,
+ struct vm_area_struct *vma)
+{
+ return -EINVAL;
+}
+
+static void *ion_secure_cma_map_kernel(struct ion_heap *heap,
+ struct ion_buffer *buffer)
+{
+ struct ion_secure_cma_buffer_info *info = buffer->priv_virt;
+
+ atomic_inc(&info->secure.map_cnt);
+ return info->cpu_addr;
+}
+
+static void ion_secure_cma_unmap_kernel(struct ion_heap *heap,
+ struct ion_buffer *buffer)
+{
+ struct ion_secure_cma_buffer_info *info = buffer->priv_virt;
+
+ atomic_dec(&info->secure.map_cnt);
+ return;
+}
+
+int ion_secure_cma_map_iommu(struct ion_buffer *buffer,
+ struct ion_iommu_map *data,
+ unsigned int domain_num,
+ unsigned int partition_num,
+ unsigned long align,
+ unsigned long iova_length,
+ unsigned long flags)
+{
+ int ret = 0;
+ struct iommu_domain *domain;
+ unsigned long extra;
+ unsigned long extra_iova_addr;
+ struct ion_secure_cma_buffer_info *info = buffer->priv_virt;
+ struct sg_table *table = info->table;
+ int prot = IOMMU_WRITE | IOMMU_READ;
+
+ data->mapped_size = iova_length;
+
+ if (!msm_use_iommu()) {
+ data->iova_addr = info->handle;
+ return 0;
+ }
+
+ extra = iova_length - buffer->size;
+
+ ret = msm_allocate_iova_address(domain_num, partition_num,
+ data->mapped_size, align,
+ &data->iova_addr);
+
+ if (ret)
+ goto out;
+
+ domain = msm_get_iommu_domain(domain_num);
+
+ if (!domain) {
+ ret = -EINVAL;
+ goto out1;
+ }
+
+ ret = iommu_map_range(domain, data->iova_addr, table->sgl,
+ buffer->size, prot);
+
+ if (ret) {
+ pr_err("%s: could not map %lx in domain %p\n",
+ __func__, data->iova_addr, domain);
+ goto out1;
+ }
+
+ extra_iova_addr = data->iova_addr + buffer->size;
+ if (extra) {
+ unsigned long phys_addr = sg_phys(table->sgl);
+ ret = msm_iommu_map_extra(domain, extra_iova_addr, phys_addr,
+ extra, SZ_4K, prot);
+ if (ret)
+ goto out2;
+ }
+ return ret;
+
+out2:
+ iommu_unmap_range(domain, data->iova_addr, buffer->size);
+out1:
+ msm_free_iova_address(data->iova_addr, domain_num, partition_num,
+ data->mapped_size);
+out:
+ return ret;
+}
+
+
+void ion_secure_cma_unmap_iommu(struct ion_iommu_map *data)
+{
+ unsigned int domain_num;
+ unsigned int partition_num;
+ struct iommu_domain *domain;
+
+ if (!msm_use_iommu())
+ return;
+
+ domain_num = iommu_map_domain(data);
+ partition_num = iommu_map_partition(data);
+
+ domain = msm_get_iommu_domain(domain_num);
+
+ if (!domain) {
+ WARN(1, "Could not get domain %d. Corruption?\n", domain_num);
+ return;
+ }
+
+ iommu_unmap_range(domain, data->iova_addr, data->mapped_size);
+ msm_free_iova_address(data->iova_addr, domain_num, partition_num,
+ data->mapped_size);
+
+ return;
+}
+
+int ion_secure_cma_cache_ops(struct ion_heap *heap,
+ struct ion_buffer *buffer, void *vaddr,
+ unsigned int offset, unsigned int length,
+ unsigned int cmd)
+{
+ void (*outer_cache_op)(phys_addr_t, phys_addr_t);
+
+ switch (cmd) {
+ case ION_IOC_CLEAN_CACHES:
+ dmac_clean_range(vaddr, vaddr + length);
+ outer_cache_op = outer_clean_range;
+ break;
+ case ION_IOC_INV_CACHES:
+ dmac_inv_range(vaddr, vaddr + length);
+ outer_cache_op = outer_inv_range;
+ break;
+ case ION_IOC_CLEAN_INV_CACHES:
+ dmac_flush_range(vaddr, vaddr + length);
+ outer_cache_op = outer_flush_range;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (cma_heap_has_outer_cache) {
+ struct ion_secure_cma_buffer_info *info = buffer->priv_virt;
+
+ outer_cache_op(info->handle, info->handle + length);
+ }
+
+ return 0;
+}
+
+static int ion_secure_cma_print_debug(struct ion_heap *heap, struct seq_file *s,
+ const struct rb_root *mem_map)
+{
+ if (mem_map) {
+ struct rb_node *n;
+
+ seq_printf(s, "\nMemory Map\n");
+ seq_printf(s, "%16.s %14.s %14.s %14.s\n",
+ "client", "start address", "end address",
+ "size (hex)");
+
+ for (n = rb_first(mem_map); n; n = rb_next(n)) {
+ struct mem_map_data *data =
+ rb_entry(n, struct mem_map_data, node);
+ const char *client_name = "(null)";
+
+
+ if (data->client_name)
+ client_name = data->client_name;
+
+ seq_printf(s, "%16.s %14lx %14lx %14lu (%lx)\n",
+ client_name, data->addr,
+ data->addr_end,
+ data->size, data->size);
+ }
+ }
+ return 0;
+}
+
+static struct ion_heap_ops ion_secure_cma_ops = {
+ .allocate = ion_secure_cma_allocate,
+ .free = ion_secure_cma_free,
+ .map_dma = ion_secure_cma_heap_map_dma,
+ .unmap_dma = ion_secure_cma_heap_unmap_dma,
+ .phys = ion_secure_cma_phys,
+ .map_user = ion_secure_cma_mmap,
+ .map_kernel = ion_secure_cma_map_kernel,
+ .unmap_kernel = ion_secure_cma_unmap_kernel,
+ .map_iommu = ion_secure_cma_map_iommu,
+ .unmap_iommu = ion_secure_cma_unmap_iommu,
+ .cache_op = ion_secure_cma_cache_ops,
+ .print_debug = ion_secure_cma_print_debug,
+ .secure_buffer = ion_cp_secure_buffer,
+ .unsecure_buffer = ion_cp_unsecure_buffer,
+};
+
+struct ion_heap *ion_secure_cma_heap_create(struct ion_platform_heap *data)
+{
+ struct ion_heap *heap;
+
+ heap = kzalloc(sizeof(struct ion_heap), GFP_KERNEL);
+
+ if (!heap)
+ return ERR_PTR(-ENOMEM);
+
+ heap->ops = &ion_secure_cma_ops;
+ /* set device as private heaps data, later it will be
+ * used to make the link with reserved CMA memory */
+ heap->priv = data->priv;
+ heap->type = ION_HEAP_TYPE_SECURE_DMA;
+ cma_heap_has_outer_cache = data->has_outer_cache;
+ return heap;
+}
+
+void ion_secure_cma_heap_destroy(struct ion_heap *heap)
+{
+ kfree(heap);
+}
diff --git a/drivers/gpu/ion/ion_heap.c b/drivers/gpu/ion/ion_heap.c
index 98c1a8c..ff2b8dd 100644
--- a/drivers/gpu/ion/ion_heap.c
+++ b/drivers/gpu/ion/ion_heap.c
@@ -2,7 +2,7 @@
* drivers/gpu/ion/ion_heap.c
*
* Copyright (C) 2011 Google, Inc.
- * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -44,6 +44,10 @@
case ION_HEAP_TYPE_DMA:
heap = ion_cma_heap_create(heap_data);
break;
+
+ case ION_HEAP_TYPE_SECURE_DMA:
+ heap = ion_secure_cma_heap_create(heap_data);
+ break;
#endif
default:
pr_err("%s: Invalid heap type %d\n", __func__,
@@ -89,6 +93,9 @@
case ION_HEAP_TYPE_DMA:
ion_cma_heap_destroy(heap);
break;
+ case ION_HEAP_TYPE_SECURE_DMA:
+ ion_secure_cma_heap_destroy(heap);
+ break;
#endif
default:
pr_err("%s: Invalid heap type %d\n", __func__,
diff --git a/drivers/gpu/ion/ion_priv.h b/drivers/gpu/ion/ion_priv.h
index 2473dd2..77ecfa5 100644
--- a/drivers/gpu/ion/ion_priv.h
+++ b/drivers/gpu/ion/ion_priv.h
@@ -2,7 +2,7 @@
* drivers/gpu/ion/ion_priv.h
*
* Copyright (C) 2011 Google, Inc.
- * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -262,6 +262,9 @@
#ifdef CONFIG_CMA
struct ion_heap *ion_cma_heap_create(struct ion_platform_heap *);
void ion_cma_heap_destroy(struct ion_heap *);
+
+struct ion_heap *ion_secure_cma_heap_create(struct ion_platform_heap *);
+void ion_secure_cma_heap_destroy(struct ion_heap *);
#endif
struct ion_heap *msm_get_contiguous_heap(void);
diff --git a/drivers/gpu/ion/msm/msm_ion.c b/drivers/gpu/ion/msm/msm_ion.c
index fb365ba..b660968 100644
--- a/drivers/gpu/ion/msm/msm_ion.c
+++ b/drivers/gpu/ion/msm/msm_ion.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. 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 version 2 and
@@ -662,12 +662,14 @@
int ion_heap_allow_secure_allocation(enum ion_heap_type type)
{
- return type == ((enum ion_heap_type) ION_HEAP_TYPE_CP);
+ return type == ((enum ion_heap_type) ION_HEAP_TYPE_CP) ||
+ type == ((enum ion_heap_type) ION_HEAP_TYPE_SECURE_DMA);
}
int ion_heap_allow_handle_secure(enum ion_heap_type type)
{
- return type == ((enum ion_heap_type) ION_HEAP_TYPE_CP);
+ return type == ((enum ion_heap_type) ION_HEAP_TYPE_CP) ||
+ type == ((enum ion_heap_type) ION_HEAP_TYPE_SECURE_DMA);
}
int ion_heap_allow_heap_secure(enum ion_heap_type type)
diff --git a/drivers/gpu/msm/a3xx_reg.h b/drivers/gpu/msm/a3xx_reg.h
index 0127735..e245cfc 100644
--- a/drivers/gpu/msm/a3xx_reg.h
+++ b/drivers/gpu/msm/a3xx_reg.h
@@ -539,11 +539,11 @@
/* RBBM_CLOCK_CTL default value */
#define A305_RBBM_CLOCK_CTL_DEFAULT 0xAAAAAAAA
#define A320_RBBM_CLOCK_CTL_DEFAULT 0xBFFFFFFF
-#define A330_RBBM_CLOCK_CTL_DEFAULT 0xAAAAAAAE
+#define A330_RBBM_CLOCK_CTL_DEFAULT 0xBFFCFFFF
#define A330v2_RBBM_CLOCK_CTL_DEFAULT 0xBFFCFFFF
#define A305B_RBBM_CLOCK_CTL_DEFAULT 0xAAAAAAAA
-#define A330_RBBM_GPR0_CTL_DEFAULT 0x0AE2B8AE
+#define A330_RBBM_GPR0_CTL_DEFAULT 0x00000000
#define A330v2_RBBM_GPR0_CTL_DEFAULT 0x00000000
/* COUNTABLE FOR SP PERFCOUNTER */
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index c495890..a8384d5 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -160,10 +160,10 @@
/* size of gmem for gpu*/
unsigned int gmem_size;
/* version of pm4 microcode that supports sync_lock
- between CPU and GPU for SMMU-v1 programming */
+ between CPU and GPU for IOMMU-v0 programming */
unsigned int sync_lock_pm4_ver;
/* version of pfp microcode that supports sync_lock
- between CPU and GPU for SMMU-v1 programming */
+ between CPU and GPU for IOMMU-v0 programming */
unsigned int sync_lock_pfp_ver;
} adreno_gpulist[] = {
{ ADRENO_REV_A200, 0, 2, ANY_ID, ANY_ID,
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index df190ff..df8e1d0 100644
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -34,7 +34,7 @@
#include "z180.h"
-static struct kgsl_iommu_register_list kgsl_iommuv1_reg[KGSL_IOMMU_REG_MAX] = {
+static struct kgsl_iommu_register_list kgsl_iommuv0_reg[KGSL_IOMMU_REG_MAX] = {
{ 0, 0, 0 }, /* GLOBAL_BASE */
{ 0x10, 0x0003FFFF, 14 }, /* TTBR0 */
{ 0x14, 0x0003FFFF, 14 }, /* TTBR1 */
@@ -45,7 +45,7 @@
{ 0x818, 0, 0 }, /* V2PUR */
};
-static struct kgsl_iommu_register_list kgsl_iommuv2_reg[KGSL_IOMMU_REG_MAX] = {
+static struct kgsl_iommu_register_list kgsl_iommuv1_reg[KGSL_IOMMU_REG_MAX] = {
{ 0, 0, 0 }, /* GLOBAL_BASE */
{ 0x20, 0x00FFFFFF, 14 }, /* TTBR0 */
{ 0x28, 0x00FFFFFF, 14 }, /* TTBR1 */
@@ -1191,15 +1191,15 @@
if (status)
goto done;
- iommu->iommu_reg_list = kgsl_iommuv1_reg;
- iommu->ctx_offset = KGSL_IOMMU_CTX_OFFSET_V1;
+ iommu->iommu_reg_list = kgsl_iommuv0_reg;
+ iommu->ctx_offset = KGSL_IOMMU_CTX_OFFSET_V0;
if (msm_soc_version_supports_iommu_v0()) {
+ iommu->iommu_reg_list = kgsl_iommuv0_reg;
+ iommu->ctx_offset = KGSL_IOMMU_CTX_OFFSET_V0;
+ } else {
iommu->iommu_reg_list = kgsl_iommuv1_reg;
iommu->ctx_offset = KGSL_IOMMU_CTX_OFFSET_V1;
- } else {
- iommu->iommu_reg_list = kgsl_iommuv2_reg;
- iommu->ctx_offset = KGSL_IOMMU_CTX_OFFSET_V2;
}
/* A nop is required in an indirect buffer when switching
diff --git a/drivers/gpu/msm/kgsl_iommu.h b/drivers/gpu/msm/kgsl_iommu.h
index 25f0d45..bf40113 100644
--- a/drivers/gpu/msm/kgsl_iommu.h
+++ b/drivers/gpu/msm/kgsl_iommu.h
@@ -15,8 +15,8 @@
#include <mach/iommu.h>
-#define KGSL_IOMMU_CTX_OFFSET_V1 0
-#define KGSL_IOMMU_CTX_OFFSET_V2 0x8000
+#define KGSL_IOMMU_CTX_OFFSET_V0 0
+#define KGSL_IOMMU_CTX_OFFSET_V1 0x8000
#define KGSL_IOMMU_CTX_SHIFT 12
/* TLBLKCR feilds */
diff --git a/drivers/gpu/msm/kgsl_pwrscale_trustzone.c b/drivers/gpu/msm/kgsl_pwrscale_trustzone.c
index aa6861e..a647361 100644
--- a/drivers/gpu/msm/kgsl_pwrscale_trustzone.c
+++ b/drivers/gpu/msm/kgsl_pwrscale_trustzone.c
@@ -38,6 +38,10 @@
* per frame for 60fps content.
*/
#define FLOOR 5000
+/* CEILING is 50msec, larger than any standard
+ * frame length, but less than the idle timer.
+ */
+#define CEILING 50000
#define SWITCH_OFF 200
#define SWITCH_OFF_RESET_TH 40
#define SKIP_COUNTER 500
@@ -163,11 +167,18 @@
priv->no_switch_cnt = 0;
}
- idle = priv->bin.total_time - priv->bin.busy_time;
+ /* If there is an extended block of busy processing,
+ * increase frequency. Otherwise run the normal algorithm.
+ */
+ if (priv->bin.busy_time > CEILING) {
+ val = -1;
+ } else {
+ idle = priv->bin.total_time - priv->bin.busy_time;
+ idle = (idle > 0) ? idle : 0;
+ val = __secure_tz_entry(TZ_UPDATE_ID, idle, device->id);
+ }
priv->bin.total_time = 0;
priv->bin.busy_time = 0;
- idle = (idle > 0) ? idle : 0;
- val = __secure_tz_entry(TZ_UPDATE_ID, idle, device->id);
if (val)
kgsl_pwrctrl_pwrlevel_change(device,
pwr->active_pwrlevel + val);
diff --git a/drivers/gud/mobicore_driver/api.c b/drivers/gud/mobicore_driver/api.c
index 2506bc2..871f6cc 100644
--- a/drivers/gud/mobicore_driver/api.c
+++ b/drivers/gud/mobicore_driver/api.c
@@ -2,6 +2,7 @@
* MobiCore Driver Kernel Module.
*
* <-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/drivers/gud/mobicore_driver/debug.h b/drivers/gud/mobicore_driver/debug.h
index f166605..0195877 100644
--- a/drivers/gud/mobicore_driver/debug.h
+++ b/drivers/gud/mobicore_driver/debug.h
@@ -14,8 +14,7 @@
extern struct device *mcd;
#define MCDRV_DBG_ERROR(dev, txt, ...) \
- dev_err(dev, "[%d] %s() ### ERROR: " txt, \
- task_pid_vnr(current), \
+ dev_err(dev, "MobiCore %s() ### ERROR: " txt, \
__func__, \
##__VA_ARGS__)
@@ -32,15 +31,12 @@
#endif
#define MCDRV_DBG(dev, txt, ...) \
- dev_info(dev, "[%d on CPU%d] %s(): " txt, \
- task_pid_vnr(current), \
- raw_smp_processor_id(), \
+ dev_info(dev, "MobiCore %s(): " txt, \
__func__, \
##__VA_ARGS__)
#define MCDRV_DBG_WARN(dev, txt, ...) \
- dev_warn(dev, "[%d] %s() WARNING: " txt, \
- task_pid_vnr(current), \
+ dev_warn(dev, "MobiCore %s() WARNING: " txt, \
__func__, \
##__VA_ARGS__)
diff --git a/drivers/gud/mobicore_driver/fastcall.h b/drivers/gud/mobicore_driver/fastcall.h
index 9f360c1..d5f9abc 100644
--- a/drivers/gud/mobicore_driver/fastcall.h
+++ b/drivers/gud/mobicore_driver/fastcall.h
@@ -15,6 +15,15 @@
#include "debug.h"
+/* Use the arch_extension sec pseudo op before switching to secure world */
+#if defined(__GNUC__) && \
+ defined(__GNUC_MINOR__) && \
+ defined(__GNUC_PATCHLEVEL__) && \
+ ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)) \
+ >= 40502
+#define MC_ARCH_EXTENSION_SEC
+#endif
+
/*
* MobiCore SMCs
*/
@@ -93,16 +102,18 @@
*/
static inline long _smc(void *data)
{
+ int ret = 0;
union fc_generic fc_generic;
- memcpy(&fc_generic, data, sizeof(union fc_generic));
+
if (data == NULL)
return -EPERM;
+
#ifdef MC_SMC_FASTCALL
{
- int ret = 0;
- ret = smc_fastcall(data, sizeof(union fc_generic));
+ ret = smc_fastcall(data, sizeof(fc_generic));
}
#else
+ memcpy(&fc_generic, data, sizeof(union fc_generic));
{
/* SVC expect values in r0-r3 */
register u32 reg0 __asm__("r0") = fc_generic.as_in.cmd;
@@ -128,7 +139,7 @@
memcpy(data, &fc_generic, sizeof(union fc_generic));
}
#endif
- return 0;
+ return ret;
}
/*
diff --git a/drivers/gud/mobicore_driver/logging.c b/drivers/gud/mobicore_driver/logging.c
index 089b91c..4160292 100644
--- a/drivers/gud/mobicore_driver/logging.c
+++ b/drivers/gud/mobicore_driver/logging.c
@@ -5,6 +5,7 @@
* buffer and the Linux log
*
* <-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -51,17 +52,27 @@
uint32_t log_data; /* Value, if any */
};
+static bool prev_eol; /* Previous char was a EOL */
+static uint16_t prev_source; /* Previous Log source */
static uint32_t log_pos; /* MobiCore log previous position */
static struct mc_trace_buf *log_buf; /* MobiCore log buffer structure */
struct task_struct *log_thread; /* Log Thread task structure */
static char *log_line; /* Log Line buffer */
static uint32_t log_line_len; /* Log Line buffer current length */
+static int thread_err;
-static void log_eol(void)
+static void log_eol(uint16_t source)
{
if (!strnlen(log_line, LOG_LINE_SIZE))
return;
- dev_info(mcd, "%s\n", log_line);
+ prev_eol = true;
+ /* MobiCore Userspace */
+ if (prev_source)
+ dev_info(mcd, "%03x|%s\n", prev_source, log_line);
+ /* MobiCore kernel */
+ else
+ dev_info(mcd, "%s\n", log_line);
+
log_line_len = 0;
log_line[0] = 0;
}
@@ -70,53 +81,29 @@
* Collect chars in log_line buffer and output the buffer when it is full.
* No locking needed because only "mobicore_log" thread updates this buffer.
*/
-static void log_char(char ch)
+static void log_char(char ch, uint16_t source)
{
if (ch == '\n' || ch == '\r') {
- log_eol();
+ log_eol(source);
return;
}
- if (log_line_len >= LOG_LINE_SIZE - 1) {
- dev_info(mcd, "%s\n", log_line);
- log_line_len = 0;
- log_line[0] = 0;
- }
+ if (log_line_len >= LOG_LINE_SIZE - 1 || source != prev_source)
+ log_eol(source);
+
log_line[log_line_len] = ch;
log_line[log_line_len + 1] = 0;
log_line_len++;
-}
-
-/*
- * Put a string to the log line.
- */
-static void log_str(const char *s)
-{
- int i;
-
- for (i = 0; i < strnlen(s, LOG_LINE_SIZE); i++)
- log_char(s[i]);
-}
-
-static uint32_t process_v1log(void)
-{
- char *last_char = log_buf->buff + log_buf->write_pos;
- char *buff = log_buf->buff + log_pos;
- while (buff != last_char) {
- log_char(*(buff++));
- /* Wrap around */
- if (buff - (char *)log_buf >= log_size)
- buff = log_buf->buff;
- }
- return buff - log_buf->buff;
+ prev_eol = false;
+ prev_source = source;
}
static const uint8_t HEX2ASCII[16] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
-static void dbg_raw_nro(uint32_t format, uint32_t value)
+static void dbg_raw_nro(uint32_t format, uint32_t value, uint16_t source)
{
int digits = 1;
uint32_t base = (format & LOG_INTEGER_DECIMAL) ? 10 : 16;
@@ -139,17 +126,17 @@
if (width > digits) {
char ch = (base == 10) ? ' ' : '0';
while (width > digits) {
- log_char(ch);
+ log_char(ch, source);
width--;
}
}
if (negative)
- log_char('-');
+ log_char('-', source);
while (digits-- > 0) {
uint32_t d = value / digit_base;
- log_char(HEX2ASCII[d]);
+ log_char(HEX2ASCII[d], source);
value = value - d * digit_base;
digit_base /= base;
}
@@ -157,36 +144,32 @@
static void log_msg(struct logmsg_struct *msg)
{
- unsigned char msgtxt[5];
- int mpos = 0;
-
switch (msg->ctrl & LOG_TYPE_MASK) {
case LOG_TYPE_CHAR: {
uint32_t ch;
ch = msg->log_data;
while (ch != 0) {
- msgtxt[mpos++] = ch&0xFF;
+ log_char(ch & 0xFF, msg->source);
ch >>= 8;
}
- msgtxt[mpos] = 0;
- log_str(msgtxt);
break;
}
case LOG_TYPE_INTEGER: {
- dbg_raw_nro(msg->ctrl, msg->log_data);
+ dbg_raw_nro(msg->ctrl, msg->log_data, msg->source);
break;
}
default:
break;
}
if (msg->ctrl & LOG_EOL)
- log_eol();
+ log_eol(msg->source);
}
-static uint32_t process_v2log(void)
+static uint32_t process_log(void)
{
char *last_msg = log_buf->buff + log_buf->write_pos;
char *buff = log_buf->buff + log_pos;
+
while (buff != last_msg) {
log_msg((struct logmsg_struct *)buff);
buff += sizeof(struct logmsg_struct);
@@ -201,19 +184,19 @@
/* log_worker() - Worker thread processing the log_buf buffer. */
static int log_worker(void *p)
{
- if (log_buf == NULL)
- return -EFAULT;
+ int ret = 0;
+ if (log_buf == NULL) {
+ ret = -EFAULT;
+ goto err_kthread;
+ }
while (!kthread_should_stop()) {
if (log_buf->write_pos == log_pos)
schedule_timeout_interruptible(MAX_SCHEDULE_TIMEOUT);
switch (log_buf->version) {
- case 1:
- log_pos = process_v1log();
- break;
case 2:
- log_pos = process_v2log();
+ log_pos = process_log();
break;
default:
MCDRV_DBG_ERROR(mcd, "Unknown Mobicore log data");
@@ -222,11 +205,23 @@
* Stop the thread as we have no idea what
* happens next
*/
- return -EFAULT;
+ ret = -EFAULT;
+ goto err_kthread;
}
}
+err_kthread:
MCDRV_DBG(mcd, "Logging thread stopped!");
- return 0;
+ thread_err = ret;
+ /* Wait until the next kthread_stop() is called, if it was already
+ * called we just slip through, if there is an error signal it and
+ * wait to get the signal */
+ set_current_state(TASK_INTERRUPTIBLE);
+ while (!kthread_should_stop()) {
+ schedule();
+ set_current_state(TASK_INTERRUPTIBLE);
+ }
+ set_current_state(TASK_RUNNING);
+ return ret;
}
/*
@@ -239,6 +234,14 @@
if (log_thread == NULL || IS_ERR(log_thread))
return;
+ /* The thread itself is in some error condition so just get
+ * rid of it */
+ if (thread_err != 0) {
+ kthread_stop(log_thread);
+ log_thread = NULL;
+ return;
+ }
+
wake_up_process(log_thread);
}
@@ -258,6 +261,9 @@
log_thread = NULL;
log_line = NULL;
log_line_len = 0;
+ prev_eol = false;
+ prev_source = 0;
+ thread_err = 0;
/* Sanity check for the log size */
if (log_size < PAGE_SIZE)
@@ -271,11 +277,11 @@
return -ENOMEM;
}
- log_thread = kthread_create(log_worker, NULL, "mobicore_log");
+ log_thread = kthread_create(log_worker, NULL, "mc_log");
if (IS_ERR(log_thread)) {
MCDRV_DBG_ERROR(mcd, "MobiCore log thread creation failed!");
ret = -EFAULT;
- goto mobicore_log_setup_log_line;
+ goto err_free_line;
}
sched_setscheduler(log_thread, SCHED_IDLE, ¶m);
@@ -288,7 +294,7 @@
if (!log_buf) {
MCDRV_DBG_ERROR(mcd, "Failed to get page for logger!");
ret = -ENOMEM;
- goto mobicore_log_setup_kthread;
+ goto err_stop_kthread;
}
phys_log_buf = virt_to_phys(log_buf);
@@ -308,16 +314,17 @@
free_pages((unsigned long)log_buf, get_order(log_size));
log_buf = NULL;
ret = -EIO;
- goto mobicore_log_setup_kthread;
+ goto err_stop_kthread;
}
+ set_task_state(log_thread, TASK_INTERRUPTIBLE);
MCDRV_DBG(mcd, "fc_log Logger version %u\n", log_buf->version);
return 0;
-mobicore_log_setup_kthread:
+err_stop_kthread:
kthread_stop(log_thread);
log_thread = NULL;
-mobicore_log_setup_log_line:
+err_free_line:
kfree(log_line);
log_line = NULL;
return ret;
diff --git a/drivers/gud/mobicore_driver/main.c b/drivers/gud/mobicore_driver/main.c
index 1a745b3..3fc9e17 100644
--- a/drivers/gud/mobicore_driver/main.c
+++ b/drivers/gud/mobicore_driver/main.c
@@ -11,6 +11,7 @@
* fd = open(/dev/mobicore-user)
*
* <-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -81,7 +82,7 @@
}
/* Frees the memory associated with a buffer */
-static int free_buffer(struct mc_buffer *buffer)
+static int free_buffer(struct mc_buffer *buffer, bool unlock)
{
if (buffer->handle == 0)
return -EINVAL;
@@ -89,16 +90,15 @@
if (buffer->addr == 0)
return -EINVAL;
- if (!atomic_dec_and_test(&buffer->usage)) {
+ MCDRV_DBG_VERBOSE(mcd,
+ "handle=%u phys_addr=0x%p, virt_addr=0x%p len=%u\n",
+ buffer->handle, buffer->phys, buffer->addr, buffer->len);
- MCDRV_DBG_VERBOSE(mcd, "Could not free buffer h=%u",
- buffer->handle);
+ if (!atomic_dec_and_test(&buffer->usage)) {
+ MCDRV_DBG_VERBOSE(mcd, "Could not free %u", buffer->handle);
return 0;
}
- MCDRV_DBG(mcd, "handle=%u phys_addr=0x%p, virt_addr=0x%p\n",
- buffer->handle, buffer->phys, buffer->addr);
-
list_del(&buffer->list);
free_continguous_pages(buffer->addr, buffer->order);
@@ -106,6 +106,37 @@
return 0;
}
+static uint32_t mc_find_cont_wsm_addr(struct mc_instance *instance, void *uaddr,
+ uint32_t *addr, uint32_t len)
+{
+ int ret = 0;
+ struct mc_buffer *buffer;
+
+ if (WARN(!instance, "No instance data available"))
+ return -EFAULT;
+
+ mutex_lock(&instance->lock);
+
+ mutex_lock(&ctx.bufs_lock);
+
+ /* search for the given handle in the buffers list */
+ list_for_each_entry(buffer, &ctx.cont_bufs, list) {
+ if (buffer->uaddr == uaddr && buffer->len == len) {
+ *addr = (uint32_t)buffer->addr;
+ goto found;
+ }
+ }
+
+ /* Coundn't find the buffer */
+ ret = -EINVAL;
+
+found:
+ mutex_unlock(&ctx.bufs_lock);
+ mutex_unlock(&instance->lock);
+
+ return ret;
+}
+
static uint32_t mc_find_cont_wsm(struct mc_instance *instance, uint32_t handle,
uint32_t *phys, uint32_t *len)
{
@@ -152,10 +183,16 @@
* Returns 0 if no error
*
*/
-static int __free_buffer(struct mc_instance *instance, uint32_t handle)
+static int __free_buffer(struct mc_instance *instance, uint32_t handle,
+ bool unlock)
{
int ret = 0;
struct mc_buffer *buffer;
+ void *uaddr = NULL;
+ size_t len = 0;
+#ifndef MC_VM_UNMAP
+ struct mm_struct *mm = current->mm;
+#endif
if (WARN(!instance, "No instance data available"))
return -EFAULT;
@@ -163,6 +200,46 @@
mutex_lock(&ctx.bufs_lock);
/* search for the given handle in the buffers list */
list_for_each_entry(buffer, &ctx.cont_bufs, list) {
+ if (buffer->handle == handle) {
+ uaddr = buffer->uaddr;
+ len = buffer->len;
+ goto found_buffer;
+ }
+ }
+ goto err;
+found_buffer:
+ if (!is_daemon(instance) || buffer->instance != instance)
+ goto err;
+ mutex_unlock(&ctx.bufs_lock);
+ /* Only unmap if the request is comming from the user space and
+ * it hasn't already been unmapped */
+ if (unlock == false && uaddr != NULL)
+#ifndef MC_VM_UNMAP
+ /* do_munmap must be done with mm->mmap_sem taken */
+ down_write(&mm->mmap_sem);
+ ret = do_munmap(mm, (long unsigned int)uaddr, len);
+ if (ret < 0) {
+ /* Something is not right if we end up here, better not
+ * clean the buffer so we just leak memory instead of
+ * creating security issues */
+ MCDRV_DBG_ERROR(mcd, "Memory can't be unmapped\n");
+ }
+ up_write(&mm->mmap_sem);
+ if (ret < 0)
+ return -EINVAL;
+#else
+ if (vm_munmap((long unsigned int)uaddr, len) < 0) {
+ /* Something is not right if we end up here, better not
+ * clean the buffer so we just leak memory instead of
+ * creating security issues */
+ MCDRV_DBG_ERROR(mcd, "Memory can't be unmapped\n");
+ return -EINVAL;
+ }
+#endif
+
+ mutex_lock(&ctx.bufs_lock);
+ /* search for the given handle in the buffers list */
+ list_for_each_entry(buffer, &ctx.cont_bufs, list) {
if (buffer->handle == handle)
goto del_buffer;
}
@@ -170,7 +247,7 @@
goto err;
del_buffer:
- ret = free_buffer(buffer);
+ ret = free_buffer(buffer, unlock);
err:
mutex_unlock(&ctx.bufs_lock);
return ret;
@@ -185,7 +262,7 @@
mutex_lock(&instance->lock);
- ret = __free_buffer(instance, handle);
+ ret = __free_buffer(instance, handle, false);
mutex_unlock(&instance->lock);
return ret;
}
@@ -253,8 +330,8 @@
INIT_LIST_HEAD(&cbuffer->list);
list_add(&cbuffer->list, &ctx.cont_bufs);
- MCDRV_DBG(mcd,
- "allocated phys=0x%p - 0x%p, size=%ld, kvirt=0x%p, h=%d\n",
+ MCDRV_DBG_VERBOSE(mcd,
+ "allocated phys=0x%p - 0x%p, size=%ld, kvirt=0x%p, h=%d\n",
phys, (void *)((unsigned int)phys+allocated_size),
allocated_size, addr, cbuffer->handle);
*buffer = cbuffer;
@@ -332,6 +409,7 @@
int ret = 0;
struct mc_l2_table *table = NULL;
struct task_struct *task = current;
+ uint32_t kbuff = 0x0;
if (WARN(!instance, "No instance data available"))
return -EFAULT;
@@ -341,7 +419,12 @@
return -EINVAL;
}
- table = mc_alloc_l2_table(instance, task, (void *)buffer, len);
+ MCDRV_DBG_VERBOSE(mcd, "buffer: %p, len=%08x\n", (void *)buffer, len);
+
+ if (!mc_find_cont_wsm_addr(instance, (void *)buffer, &kbuff, len))
+ table = mc_alloc_l2_table(instance, NULL, (void *)kbuff, len);
+ else
+ table = mc_alloc_l2_table(instance, task, (void *)buffer, len);
if (IS_ERR(table)) {
MCDRV_DBG_ERROR(mcd, "new_used_l2_table() failed\n");
@@ -421,7 +504,7 @@
/* Not a l2 table, then it must be a buffer */
if (ret == -EINVAL) {
/* Call the non locking variant! */
- ret = __free_buffer(instance, handle);
+ ret = __free_buffer(instance, handle, true);
}
mutex_unlock(&instance->lock);
@@ -471,8 +554,8 @@
struct mc_buffer *buffer = 0;
int ret = 0;
- MCDRV_DBG(mcd, "enter (vma start=0x%p, size=%ld, mci=%p)\n",
- (void *)vmarea->vm_start, len, ctx.mci_base.phys);
+ MCDRV_DBG_VERBOSE(mcd, "enter (vma start=0x%p, size=%ld, mci=%p)\n",
+ (void *)vmarea->vm_start, len, ctx.mci_base.phys);
if (WARN(!instance, "No instance data available"))
return -EFAULT;
@@ -496,7 +579,8 @@
return -EINVAL;
found:
- vmarea->vm_flags |= VM_RESERVED;
+ buffer->uaddr = (void *)vmarea->vm_start;
+ vmarea->vm_flags |= VM_IO;
/*
* Convert kernel address to user address. Kernel address begins
* at PAGE_OFFSET, user address range is below PAGE_OFFSET.
@@ -507,6 +591,10 @@
pfn = (unsigned int)paddr >> PAGE_SHIFT;
ret = (int)remap_pfn_range(vmarea, vmarea->vm_start, pfn,
buffer->len, vmarea->vm_page_prot);
+ /* If the remap failed then don't mark this buffer as marked
+ * since the unmaping will also fail */
+ if (ret)
+ buffer->uaddr = NULL;
mutex_unlock(&ctx.bufs_lock);
} else {
if (!is_daemon(instance))
@@ -516,7 +604,7 @@
if (!paddr)
return -EFAULT;
- vmarea->vm_flags |= VM_RESERVED;
+ vmarea->vm_flags |= VM_IO;
/*
* Convert kernel address to user address. Kernel address begins
* at PAGE_OFFSET, user address range is below PAGE_OFFSET.
@@ -614,8 +702,8 @@
map.reused = 0;
if (copy_to_user(uarg, &map, sizeof(map)))
ret = -EFAULT;
-
- ret = 0;
+ else
+ ret = 0;
break;
}
default:
@@ -754,6 +842,13 @@
break;
}
+ case MC_IO_LOG_SETUP: {
+#ifdef MC_MEM_TRACES
+ ret = mobicore_log_setup();
+#endif
+ break;
+ }
+
/* The rest is handled commonly by user IOCTL */
default:
ret = mc_fd_user_ioctl(file, cmd, arg);
@@ -887,7 +982,7 @@
list_for_each_entry_safe(buffer, tmp, &ctx.cont_bufs, list) {
if (buffer->instance == instance) {
buffer->instance = NULL;
- free_buffer(buffer);
+ free_buffer(buffer, false);
}
}
mutex_unlock(&ctx.bufs_lock);
@@ -1097,10 +1192,6 @@
goto free_admin;
}
-#ifdef MC_MEM_TRACES
- mobicore_log_setup();
-#endif
-
/* initialize event counter for signaling of an IRQ to zero */
atomic_set(&ctx.isr_counter, 0);
@@ -1159,6 +1250,7 @@
module_init(mobicore_init);
module_exit(mobicore_exit);
MODULE_AUTHOR("Giesecke & Devrient GmbH");
+MODULE_AUTHOR("Trustonic Limited");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("MobiCore driver");
diff --git a/drivers/gud/mobicore_driver/main.h b/drivers/gud/mobicore_driver/main.h
index e23c516..2c316bc 100644
--- a/drivers/gud/mobicore_driver/main.h
+++ b/drivers/gud/mobicore_driver/main.h
@@ -27,7 +27,7 @@
/* Instance data for MobiCore Daemon and TLCs. */
struct mc_instance {
- /* Instance lock */
+ /* lock for the instance */
struct mutex lock;
/* unique handle */
unsigned int handle;
@@ -48,6 +48,8 @@
atomic_t usage;
/* virtual Kernel start address */
void *addr;
+ /* virtual Userspace start address */
+ void *uaddr;
/* physical start address */
void *phys;
/* order of number of pages */
diff --git a/drivers/gud/mobicore_driver/mem.c b/drivers/gud/mobicore_driver/mem.c
index da711ce..1fe351b 100644
--- a/drivers/gud/mobicore_driver/mem.c
+++ b/drivers/gud/mobicore_driver/mem.c
@@ -11,6 +11,7 @@
* which has to be created by the fd = open(/dev/mobicore) command.
*
* <-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -355,14 +356,6 @@
MCDRV_DBG_VERBOSE(mcd, "WSM addr=0x%p, len=0x%08x\n", wsm_buffer,
wsm_len);
- /*
- * Check if called from kernel space and if
- * wsm_buffer is actually vmalloced or not
- */
- if (task == NULL && !is_vmalloc_addr(wsm_buffer)) {
- MCDRV_DBG_ERROR(mcd, "WSM addr is not a vmalloc address");
- return -EINVAL;
- }
/* calculate page usage */
virt_addr_page = (void *)(((unsigned long)(wsm_buffer)) & PAGE_MASK);
@@ -405,6 +398,20 @@
return ret;
}
}
+ /* Request comes from kernel space(cont buffer) */
+ else if (task == NULL && !is_vmalloc_addr(wsm_buffer)) {
+ void *uaddr = wsm_buffer;
+ for (i = 0; i < nr_of_pages; i++) {
+ page = virt_to_page(uaddr);
+ if (!page) {
+ MCDRV_DBG_ERROR(mcd, "failed to map address");
+ return -EINVAL;
+ }
+ get_page(page);
+ l2table_as_array_of_pointers_to_page[i] = page;
+ uaddr += PAGE_SIZE;
+ }
+ }
/* Request comes from kernel space(vmalloc buffer) */
else {
void *uaddr = wsm_buffer;
diff --git a/drivers/gud/mobicore_driver/ops.c b/drivers/gud/mobicore_driver/ops.c
index 509b4e9..b44a842 100644
--- a/drivers/gud/mobicore_driver/ops.c
+++ b/drivers/gud/mobicore_driver/ops.c
@@ -11,6 +11,7 @@
* which has to be created by the fd = open(/dev/mobicore) command.
*
* <-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -20,6 +21,8 @@
#include <linux/kthread.h>
#include <linux/module.h>
#include <linux/device.h>
+#include <linux/workqueue.h>
+#include <linux/cpu.h>
#include "main.h"
#include "fastcall.h"
@@ -27,6 +30,29 @@
#include "mem.h"
#include "debug.h"
+struct fastcall_work_struct {
+ struct work_struct work;
+ void *data;
+};
+
+static void fastcall_work_func(struct work_struct *work)
+{
+ struct fastcall_work_struct *fc_work =
+ container_of(work, struct fastcall_work_struct, work);
+ _smc(fc_work->data);
+}
+
+void mc_fastcall(void *data)
+{
+ struct fastcall_work_struct work = {
+ .data = data,
+ };
+ INIT_WORK(&work.work, fastcall_work_func);
+ schedule_work_on(0, &work.work);
+
+ flush_work(&work.work);
+}
+
int mc_info(uint32_t ext_info_id, uint32_t *state, uint32_t *ext_info)
{
int ret = 0;
diff --git a/drivers/gud/mobicore_driver/ops.h b/drivers/gud/mobicore_driver/ops.h
index 673399f..efe5f05 100644
--- a/drivers/gud/mobicore_driver/ops.h
+++ b/drivers/gud/mobicore_driver/ops.h
@@ -22,9 +22,6 @@
int mc_init(uint32_t base, uint32_t nq_offset, uint32_t nq_length,
uint32_t mcp_offset, uint32_t mcp_length);
-static inline void mc_fastcall(void *data)
-{
- work_on_cpu(0, _smc, data);
-}
+void mc_fastcall(void *data);
#endif /* _MC_OPS_H_ */
diff --git a/drivers/gud/mobicore_driver/platforms/msm8960_surf_std/platform.h b/drivers/gud/mobicore_driver/platforms/msm8960_surf_std/platform.h
index 9efa026..7febcb6 100644
--- a/drivers/gud/mobicore_driver/platforms/msm8960_surf_std/platform.h
+++ b/drivers/gud/mobicore_driver/platforms/msm8960_surf_std/platform.h
@@ -3,6 +3,7 @@
* its internal structures and defines.
*
* <-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -35,6 +36,11 @@
}
/* Enable mobicore mem traces */
-#define MC_MEM_TRACES
+/* #define MC_MEM_TRACES */
+
+/* Enable the use of vm_unamp instead of the deprecated do_munmap
+ * and other 3.7 features
+ */
+#define MC_VM_UNMAP
#endif /* _MC_PLATFORM_H_ */
diff --git a/drivers/gud/mobicore_driver/public/mc_kernel_api.h b/drivers/gud/mobicore_driver/public/mc_kernel_api.h
index 7a038c4..cca0636 100644
--- a/drivers/gud/mobicore_driver/public/mc_kernel_api.h
+++ b/drivers/gud/mobicore_driver/public/mc_kernel_api.h
@@ -2,6 +2,7 @@
* Interface to be used by module MobiCoreKernelAPI.
*
* <-- Copyright Giesecke & Devrient GmbH 2010-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/drivers/gud/mobicore_driver/public/mc_linux.h b/drivers/gud/mobicore_driver/public/mc_linux.h
index 99b7769..bb95c26 100644
--- a/drivers/gud/mobicore_driver/public/mc_linux.h
+++ b/drivers/gud/mobicore_driver/public/mc_linux.h
@@ -11,6 +11,7 @@
* "insmod mcDrvModule.ko".
*
* <-- Copyright Giesecke & Devrient GmbH 2010-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -206,4 +207,9 @@
* Only available to the daemon */
#define MC_IO_RESOLVE_CONT_WSM _IOWR(MC_IOC_MAGIC, 16, struct mc_ioctl_execute)
+/*
+ * Setup the mem traces when called.
+ * Only available to the daemon */
+#define MC_IO_LOG_SETUP _IO(MC_IOC_MAGIC, 17)
+
#endif /* _MC_LINUX_H_ */
diff --git a/drivers/gud/mobicore_driver/public/version.h b/drivers/gud/mobicore_driver/public/version.h
index b08dd95..591ca3d 100644
--- a/drivers/gud/mobicore_driver/public/version.h
+++ b/drivers/gud/mobicore_driver/public/version.h
@@ -1,5 +1,6 @@
/*
* <-- Copyright Giesecke & Devrient GmbH 2010-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/drivers/gud/mobicore_kernelapi/include/mcinq.h b/drivers/gud/mobicore_kernelapi/include/mcinq.h
index b874925..34216a7 100644
--- a/drivers/gud/mobicore_kernelapi/include/mcinq.h
+++ b/drivers/gud/mobicore_kernelapi/include/mcinq.h
@@ -112,6 +112,6 @@
struct notification_queue_header hdr;
/* Notification elements. */
struct notification notification[MIN_NQ_ELEM];
-} ;
+};
#endif /* _MCINQ_H_ */
diff --git a/drivers/gud/mobicore_kernelapi/main.c b/drivers/gud/mobicore_kernelapi/main.c
index 50359b1..73de93a 100644
--- a/drivers/gud/mobicore_kernelapi/main.c
+++ b/drivers/gud/mobicore_kernelapi/main.c
@@ -139,13 +139,27 @@
static int __init mcapi_init(void)
{
+ /* struct netlink_kernel_cfg netlink_cfg; */
+
dev_set_name(mc_kapi, "mcapi");
dev_info(mc_kapi, "Mobicore API module initialized!\n");
+ /*
+ * netlink_cfg.groups = 0;
+ * netlink_cfg.flags = 0;
+ * netlink_cfg.input = mcapi_callback;
+ * netlink_cfg.cb_mutex = NULL;
+ * netlink_cfg.bind = NULL;
+ */
mod_ctx = kzalloc(sizeof(struct mc_kernelapi_ctx), GFP_KERNEL);
/* start kernel thread */
+
+ /*
+ * mod_ctx->sk = netlink_kernel_create(&init_net, MC_DAEMON_NETLINK,
+ * &netlink_cfg);
+ */
mod_ctx->sk = netlink_kernel_create(&init_net, MC_DAEMON_NETLINK, 0,
mcapi_callback, NULL, THIS_MODULE);
diff --git a/drivers/hwmon/qpnp-adc-current.c b/drivers/hwmon/qpnp-adc-current.c
index 11f351c..3fdc68f 100644
--- a/drivers/hwmon/qpnp-adc-current.c
+++ b/drivers/hwmon/qpnp-adc-current.c
@@ -125,6 +125,7 @@
#define QPNP_BIT_SHIFT_8 8
#define QPNP_RSENSE_MSB_SIGN_CHECK 0x80
#define QPNP_ADC_COMPLETION_TIMEOUT HZ
+#define QPNP_IADC_ERR_CHK_RATELIMIT 3
struct qpnp_iadc_drv {
struct qpnp_adc_drv *adc;
@@ -134,6 +135,9 @@
bool iadc_initialized;
int64_t die_temp_calib_offset;
struct delayed_work iadc_work;
+ struct mutex iadc_vadc_lock;
+ bool iadc_mode_sel;
+ uint32_t iadc_err_cnt;
struct sensor_device_attribute sens_attr[0];
};
@@ -292,7 +296,7 @@
}
static int32_t qpnp_iadc_configure(enum qpnp_iadc_channels channel,
- uint16_t *raw_code)
+ uint16_t *raw_code, uint32_t mode_sel)
{
struct qpnp_iadc_drv *iadc = qpnp_iadc;
u8 qpnp_iadc_mode_reg = 0, qpnp_iadc_ch_sel_reg = 0;
@@ -303,7 +307,11 @@
qpnp_iadc_dig_param_reg |= iadc->adc->amux_prop->decimation <<
QPNP_IADC_DEC_RATIO_SEL;
- qpnp_iadc_mode_reg |= QPNP_ADC_TRIM_EN;
+ if (iadc->iadc_mode_sel)
+ qpnp_iadc_mode_reg |= (QPNP_ADC_TRIM_EN | QPNP_VADC_SYNCH_EN);
+ else
+ qpnp_iadc_mode_reg |= QPNP_ADC_TRIM_EN;
+
qpnp_iadc_conv_req = QPNP_IADC_CONV_REQ;
rc = qpnp_iadc_write_reg(QPNP_IADC_MODE_CTL, qpnp_iadc_mode_reg);
@@ -403,8 +411,10 @@
uint8_t rslt_lsb, rslt_msb;
int32_t rc = 0;
uint16_t raw_data;
+ uint32_t mode_sel = 0;
- rc = qpnp_iadc_configure(GAIN_CALIBRATION_17P857MV, &raw_data);
+ rc = qpnp_iadc_configure(GAIN_CALIBRATION_17P857MV,
+ &raw_data, mode_sel);
if (rc < 0) {
pr_err("qpnp adc result read failed with %d\n", rc);
goto fail;
@@ -412,8 +422,8 @@
iadc->adc->calib.gain_raw = raw_data;
- rc = qpnp_iadc_configure(OFFSET_CALIBRATION_SHORT_CADC_LEADS,
- &raw_data);
+ rc = qpnp_iadc_configure(OFFSET_CALIBRATION_CSP2_CSN2,
+ &raw_data, mode_sel);
if (rc < 0) {
pr_err("qpnp adc result read failed with %d\n", rc);
goto fail;
@@ -470,12 +480,15 @@
mutex_lock(&iadc->adc->adc_lock);
rc = qpnp_iadc_calibrate_for_trim();
- if (rc)
+ if (rc) {
pr_err("periodic IADC calibration failed\n");
+ iadc->iadc_err_cnt++;
+ }
mutex_unlock(&iadc->adc->adc_lock);
- schedule_delayed_work(&iadc->iadc_work,
+ if (iadc->iadc_err_cnt < QPNP_IADC_ERR_CHK_RATELIMIT)
+ schedule_delayed_work(&iadc->iadc_work,
round_jiffies_relative(msecs_to_jiffies
(QPNP_IADC_CALIB_SECONDS)));
@@ -568,22 +581,24 @@
struct qpnp_iadc_result *result)
{
struct qpnp_iadc_drv *iadc = qpnp_iadc;
- int32_t rc, rsense_n_ohms, sign = 0, num;
+ int32_t rc, rsense_n_ohms, sign = 0, num, mode_sel = 0;
int64_t result_current;
uint16_t raw_data;
if (!iadc || !iadc->iadc_initialized)
return -EPROBE_DEFER;
- rc = qpnp_check_pmic_temp();
- if (rc) {
- pr_err("Error checking pmic therm temp\n");
- return rc;
+ if (!iadc->iadc_mode_sel) {
+ rc = qpnp_check_pmic_temp();
+ if (rc) {
+ pr_err("Error checking pmic therm temp\n");
+ return rc;
+ }
}
mutex_lock(&iadc->adc->adc_lock);
- rc = qpnp_iadc_configure(channel, &raw_data);
+ rc = qpnp_iadc_configure(channel, &raw_data, mode_sel);
if (rc < 0) {
pr_err("qpnp adc result read failed with %d\n", rc);
goto fail;
@@ -644,6 +659,50 @@
}
EXPORT_SYMBOL(qpnp_iadc_get_gain_and_offset);
+int32_t qpnp_iadc_vadc_sync_read(
+ enum qpnp_iadc_channels i_channel, struct qpnp_iadc_result *i_result,
+ enum qpnp_vadc_channels v_channel, struct qpnp_vadc_result *v_result)
+{
+ struct qpnp_iadc_drv *iadc = qpnp_iadc;
+ int rc = 0;
+
+ if (!iadc || !iadc->iadc_initialized)
+ return -EPROBE_DEFER;
+
+ mutex_lock(&iadc->iadc_vadc_lock);
+
+ rc = qpnp_check_pmic_temp();
+ if (rc) {
+ pr_err("PMIC die temp check failed\n");
+ goto fail;
+ }
+
+ iadc->iadc_mode_sel = true;
+
+ rc = qpnp_vadc_iadc_sync_request(v_channel);
+ if (rc) {
+ pr_err("Configuring VADC failed\n");
+ goto fail;
+ }
+
+ rc = qpnp_iadc_read(i_channel, i_result);
+ if (rc)
+ pr_err("Configuring IADC failed\n");
+ /* Intentional fall through to release VADC */
+
+ rc = qpnp_vadc_iadc_sync_complete_request(v_channel,
+ v_result);
+ if (rc)
+ pr_err("Releasing VADC failed\n");
+fail:
+ iadc->iadc_mode_sel = false;
+
+ mutex_unlock(&iadc->iadc_vadc_lock);
+
+ return rc;
+}
+EXPORT_SYMBOL(qpnp_iadc_vadc_sync_read);
+
static ssize_t qpnp_iadc_show(struct device *dev,
struct device_attribute *devattr, char *buf)
{
@@ -786,6 +845,8 @@
schedule_delayed_work(&iadc->iadc_work,
round_jiffies_relative(msecs_to_jiffies
(QPNP_IADC_CALIB_SECONDS)));
+ mutex_init(&iadc->iadc_vadc_lock);
+ iadc->iadc_err_cnt = 0;
iadc->iadc_initialized = true;
return 0;
@@ -801,6 +862,7 @@
struct device_node *child;
int i = 0;
+ mutex_destroy(&iadc->iadc_vadc_lock);
for_each_child_of_node(node, child) {
device_remove_file(&spmi->dev,
&iadc->sens_attr[i].dev_attr);
diff --git a/drivers/hwmon/qpnp-adc-voltage.c b/drivers/hwmon/qpnp-adc-voltage.c
index 3df19d7..edbde44 100644
--- a/drivers/hwmon/qpnp-adc-voltage.c
+++ b/drivers/hwmon/qpnp-adc-voltage.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
@@ -98,6 +98,7 @@
bool vadc_init_calib;
bool vadc_initialized;
int max_channels_available;
+ bool vadc_iadc_sync_lock;
struct sensor_device_attribute sens_attr[0];
};
@@ -304,11 +305,14 @@
if (rc)
return rc;
- /* Request conversion */
- rc = qpnp_vadc_write_reg(QPNP_VADC_CONV_REQ, QPNP_VADC_CONV_REQ_SET);
- if (rc < 0) {
- pr_err("Request conversion failed\n");
- return rc;
+ if (!vadc->vadc_iadc_sync_lock) {
+ /* Request conversion */
+ rc = qpnp_vadc_write_reg(QPNP_VADC_CONV_REQ,
+ QPNP_VADC_CONV_REQ_SET);
+ if (rc < 0) {
+ pr_err("Request conversion failed\n");
+ return rc;
+ }
}
return 0;
@@ -734,6 +738,121 @@
}
EXPORT_SYMBOL_GPL(qpnp_vadc_read);
+static void qpnp_vadc_lock(void)
+{
+ struct qpnp_vadc_drv *vadc = qpnp_vadc;
+
+ mutex_lock(&vadc->adc->adc_lock);
+}
+
+static void qpnp_vadc_unlock(void)
+{
+ struct qpnp_vadc_drv *vadc = qpnp_vadc;
+
+ mutex_unlock(&vadc->adc->adc_lock);
+}
+
+int32_t qpnp_vadc_iadc_sync_request(enum qpnp_vadc_channels channel)
+{
+ struct qpnp_vadc_drv *vadc = qpnp_vadc;
+ int rc = 0, dt_index = 0;
+
+ if (!vadc || !vadc->vadc_initialized)
+ return -EPROBE_DEFER;
+
+ qpnp_vadc_lock();
+
+ if (!vadc->vadc_init_calib) {
+ rc = qpnp_vadc_version_check();
+ if (rc)
+ goto fail;
+
+ rc = qpnp_vadc_calib_device();
+ if (rc) {
+ pr_err("Calibration failed\n");
+ goto fail;
+ } else
+ vadc->vadc_init_calib = true;
+ }
+
+ vadc->adc->amux_prop->amux_channel = channel;
+
+ while ((vadc->adc->adc_channels[dt_index].channel_num
+ != channel) && (dt_index < vadc->max_channels_available))
+ dt_index++;
+
+ if (dt_index >= vadc->max_channels_available) {
+ pr_err("not a valid VADC channel\n");
+ rc = -EINVAL;
+ goto fail;
+ }
+
+ vadc->adc->amux_prop->decimation =
+ vadc->adc->adc_channels[dt_index].adc_decimation;
+ vadc->adc->amux_prop->hw_settle_time =
+ vadc->adc->adc_channels[dt_index].hw_settle_time;
+ vadc->adc->amux_prop->fast_avg_setup =
+ vadc->adc->adc_channels[dt_index].fast_avg_setup;
+ vadc->adc->amux_prop->mode_sel = (ADC_OP_NORMAL_MODE
+ << QPNP_VADC_OP_MODE_SHIFT);
+ vadc->vadc_iadc_sync_lock = true;
+
+ rc = qpnp_vadc_configure(vadc->adc->amux_prop);
+ if (rc) {
+ pr_err("qpnp vadc configure failed with %d\n", rc);
+ goto fail;
+ }
+
+ return rc;
+fail:
+ vadc->vadc_iadc_sync_lock = false;
+ qpnp_vadc_unlock();
+ return rc;
+}
+EXPORT_SYMBOL(qpnp_vadc_iadc_sync_request);
+
+int32_t qpnp_vadc_iadc_sync_complete_request(enum qpnp_vadc_channels channel,
+ struct qpnp_vadc_result *result)
+{
+ struct qpnp_vadc_drv *vadc = qpnp_vadc;
+ int rc = 0, scale_type, amux_prescaling, dt_index = 0;
+
+ vadc->adc->amux_prop->amux_channel = channel;
+
+ while ((vadc->adc->adc_channels[dt_index].channel_num
+ != channel) && (dt_index < vadc->max_channels_available))
+ dt_index++;
+
+ rc = qpnp_vadc_read_conversion_result(&result->adc_code);
+ if (rc) {
+ pr_err("qpnp vadc read adc code failed with %d\n", rc);
+ goto fail;
+ }
+
+ amux_prescaling =
+ vadc->adc->adc_channels[dt_index].chan_path_prescaling;
+
+ vadc->adc->amux_prop->chan_prop->offset_gain_numerator =
+ qpnp_vadc_amux_scaling_ratio[amux_prescaling].num;
+ vadc->adc->amux_prop->chan_prop->offset_gain_denominator =
+ qpnp_vadc_amux_scaling_ratio[amux_prescaling].den;
+
+ scale_type = vadc->adc->adc_channels[dt_index].adc_scale_fn;
+ if (scale_type >= SCALE_NONE) {
+ rc = -EBADF;
+ goto fail;
+ }
+
+ vadc_scale_fn[scale_type].chan(result->adc_code,
+ vadc->adc->adc_prop, vadc->adc->amux_prop->chan_prop, result);
+
+fail:
+ vadc->vadc_iadc_sync_lock = false;
+ qpnp_vadc_unlock();
+ return rc;
+}
+EXPORT_SYMBOL(qpnp_vadc_iadc_sync_complete_request);
+
static ssize_t qpnp_adc_show(struct device *dev,
struct device_attribute *devattr, char *buf)
{
@@ -857,6 +976,7 @@
vadc->vadc_init_calib = false;
vadc->max_channels_available = count_adc_channel_list;
vadc->vadc_initialized = true;
+ vadc->vadc_iadc_sync_lock = false;
return 0;
fail:
diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
index 717f763..eaf3519 100644
--- a/drivers/i2c/busses/i2c-qup.c
+++ b/drivers/i2c/busses/i2c-qup.c
@@ -128,6 +128,7 @@
};
#define QUP_MAX_CLK_STATE_RETRIES 300
+#define DEFAULT_CLK_RATE (19200000)
static char const * const i2c_rsrcs[] = {"i2c_clk", "i2c_sda"};
@@ -1235,18 +1236,26 @@
dev->clk_ctl = 0;
dev->pos = 0;
+ if (dev->pdata->src_clk_rate <= 0) {
+ dev_info(&pdev->dev,
+ "No src_clk_rate specified in platfrom data or "
+ "qcom,i2c-src-freq in DT\n");
+ dev_info(&pdev->dev, "Using default clock rate %dHz\n",
+ DEFAULT_CLK_RATE);
+ dev->pdata->src_clk_rate = DEFAULT_CLK_RATE;
+ }
+
+ ret = clk_set_rate(dev->clk, dev->pdata->src_clk_rate);
+ if (ret)
+ dev_info(&pdev->dev, "clk_set_rate(core_clk, %dHz):%d\n",
+ dev->pdata->src_clk_rate, ret);
+
+ clk_prepare_enable(dev->clk);
+ clk_prepare_enable(dev->pclk);
/*
* If bootloaders leave a pending interrupt on certain GSBI's,
* then we reset the core before registering for interrupts.
*/
-
- if (dev->pdata->src_clk_rate > 0)
- clk_set_rate(dev->clk, dev->pdata->src_clk_rate);
- else
- dev->pdata->src_clk_rate = 19200000;
-
- clk_prepare_enable(dev->clk);
- clk_prepare_enable(dev->pclk);
writel_relaxed(1, dev->base + QUP_SW_RESET);
if (qup_i2c_poll_state(dev, 0, true) != 0)
goto err_reset_failed;
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 45c67c0..c78eec3 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -957,4 +957,46 @@
To compile this driver as a module, choose M here: the
module will be called gen_vkeys.
+config TOUCHSCREEN_SYNAPTICS_I2C_RMI4
+ tristate "Synaptics DSX I2C touchscreen"
+ depends on I2C
+ help
+ Say Y here if you have a Synaptics DSX I2C touchscreen
+ connected to your system.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called synaptics_i2c_rmi4.
+
+config TOUCHSCREEN_SYNAPTICS_DSX_RMI4_DEV
+ tristate "Synaptics I2C touchscreen rmi device"
+ depends on TOUCHSCREEN_SYNAPTICS_I2C_RMI4
+ help
+ This enables support for character device channel for Synaptics
+ RMI4 touchscreens.
+
+ Say Y here if you have a Synaptics DSX I2C touchscreen
+ connected to your system.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called synaptics_dsx_rmi4_dev.
+
+config TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE
+ tristate "Synaptics I2C touchscreen firmware update"
+ depends on TOUCHSCREEN_SYNAPTICS_I2C_RMI4
+ help
+ This enables support for firmware update for Synaptics RMI4
+ touchscreens.
+
+ Say Y here if you have a Synaptics DSX I2C touchscreen
+ connected to your system.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called synaptics_dsx_fw_update.
+
endif
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 42b25fe..ad43bbf 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -81,3 +81,6 @@
obj-$(CONFIG_TOUCHSCREEN_CY8C_TS) += cy8c_ts.o
obj-$(CONFIG_TOUCHSCREEN_CYTTSP_I2C_QC) += cyttsp-i2c-qc.o
obj-$(CONFIG_TOUCHSCREEN_FT5X06) += ft5x06_ts.o
+obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += synaptics_i2c_rmi4.o
+obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI4_DEV) += synaptics_rmi_dev.o
+obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE) += synaptics_fw_update.o
diff --git a/kernel/drivers/input/touchscreen/synaptics_fw_update.c b/drivers/input/touchscreen/synaptics_fw_update.c
similarity index 86%
rename from kernel/drivers/input/touchscreen/synaptics_fw_update.c
rename to drivers/input/touchscreen/synaptics_fw_update.c
index 4867d1f..c447231 100644
--- a/kernel/drivers/input/touchscreen/synaptics_fw_update.c
+++ b/drivers/input/touchscreen/synaptics_fw_update.c
@@ -30,7 +30,10 @@
#define DEBUG_FW_UPDATE
#define SHOW_PROGRESS
-#define FW_IMAGE_NAME "PR12345678.img"
+#define FW_IMAGE_NAME "PR1063486-s7301_00000000.img"
+#define MAX_FIRMWARE_ID_LEN 10
+#define FORCE_UPDATE false
+#define INSIDE_FIRMWARE_UPDATE
#define CHECKSUM_OFFSET 0x00
#define BOOTLOADER_VERSION_OFFSET 0x07
@@ -73,6 +76,12 @@
CMD_ENABLE_FLASH_PROG = 0xF,
};
+enum flash_area {
+ NONE,
+ UI_FIRMWARE,
+ CONFIG_AREA
+};
+
#define SLEEP_MODE_NORMAL (0x00)
#define SLEEP_MODE_SENSOR_SLEEP (0x01)
#define SLEEP_MODE_RESERVED0 (0x02)
@@ -81,9 +90,9 @@
#define ENABLE_WAIT_MS (1 * 1000)
#define WRITE_WAIT_MS (3 * 1000)
#define ERASE_WAIT_MS (5 * 1000)
+#define RESET_WAIT_MS (500)
-#define MIN_SLEEP_TIME_US 50
-#define MAX_SLEEP_TIME_US 100
+#define SLEEP_TIME_US 50
static ssize_t fwu_sysfs_show_image(struct file *data_file,
struct kobject *kobj, struct bin_attribute *attributes,
@@ -126,6 +135,9 @@
static ssize_t fwu_sysfs_disp_config_block_count_show(struct device *dev,
struct device_attribute *attr, char *buf);
+static ssize_t fwu_sysfs_config_id_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+
static int fwu_wait_for_idle(int timeout_ms);
struct image_header {
@@ -204,6 +216,7 @@
struct synaptics_rmi4_fwu_handle {
bool initialized;
+ bool force_update;
char product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE + 1];
unsigned int image_size;
unsigned int data_pos;
@@ -231,6 +244,8 @@
struct synaptics_rmi4_data *rmi4_data;
struct f34_flash_control flash_control;
struct f34_flash_properties flash_properties;
+ struct workqueue_struct *fwu_workqueue;
+ struct delayed_work fwu_work;
};
static struct bin_attribute dev_attr_data = {
@@ -277,6 +292,9 @@
__ATTR(dispconfigblockcount, S_IRUGO,
fwu_sysfs_disp_config_block_count_show,
synaptics_rmi4_store_error),
+ __ATTR(config_id, S_IRUGO,
+ fwu_sysfs_config_id_show,
+ synaptics_rmi4_store_error),
};
static struct synaptics_rmi4_fwu_handle *fwu;
@@ -313,53 +331,6 @@
return;
}
-static int fwu_check_version(void)
-{
- int retval;
- unsigned char firmware_id[4];
- unsigned char config_id[4];
- struct i2c_client *i2c_client = fwu->rmi4_data->i2c_client;
-
- /* device firmware id */
- retval = fwu->fn_ptr->read(fwu->rmi4_data,
- fwu->f01_fd.query_base_addr + 18,
- firmware_id,
- sizeof(firmware_id));
- if (retval < 0) {
- dev_err(&i2c_client->dev,
- "Failed to read firmware ID (code %d).\n", retval);
- return retval;
- }
- firmware_id[3] = 0;
-
- dev_info(&i2c_client->dev, "Device firmware ID%d\n",
- extract_uint(firmware_id));
-
- /* device config id */
- retval = fwu->fn_ptr->read(fwu->rmi4_data,
- fwu->f34_fd.ctrl_base_addr,
- config_id,
- sizeof(config_id));
- if (retval < 0) {
- dev_err(&i2c_client->dev,
- "Failed to read config ID (code %d).\n", retval);
- return retval;
- }
-
- dev_info(&i2c_client->dev,
- "Device config ID 0x%02X, 0x%02X, 0x%02X, 0x%02X\n",
- config_id[0], config_id[1], config_id[2], config_id[3]);
-
- /* .img config id */
- dev_info(&i2c_client->dev,
- ".img config ID 0x%02X, 0x%02X, 0x%02X, 0x%02X\n",
- fwu->config_data[0],
- fwu->config_data[1],
- fwu->config_data[2],
- fwu->config_data[3]);
- return 0;
-}
-
static int fwu_read_f01_device_status(struct f01_device_status *status)
{
int retval;
@@ -407,7 +378,7 @@
return retval;
}
- dev_info(&i2c_client->dev, "%s perm:%d, bl%d, display:%d\n",
+ dev_info(&i2c_client->dev, "%s perm:%d, bl:%d, display:%d\n",
__func__,
fwu->flash_properties.has_perm_config,
fwu->flash_properties.has_bl_config,
@@ -506,25 +477,13 @@
static int fwu_reset_device(void)
{
int retval;
- unsigned char reset = 0x01;
#ifdef DEBUG_FW_UPDATE
- dev_info(&fwu->rmi4_data->i2c_client->dev, "Reset device\n");
+ dev_info(&fwu->rmi4_data->i2c_client->dev,
+ "%s: Reset device\n",
+ __func__);
#endif
- retval = fwu->fn_ptr->write(fwu->rmi4_data,
- fwu->f01_fd.cmd_base_addr,
- &reset,
- sizeof(reset));
- if (retval < 0) {
- dev_err(&fwu->rmi4_data->i2c_client->dev,
- "%s: Failed to reset device (addr : 0x%02x)\n",
- __func__, fwu->f01_fd.cmd_base_addr);
- return retval;
- }
-
- fwu_wait_for_idle(WRITE_WAIT_MS);
-
retval = fwu->rmi4_data->reset_device(fwu->rmi4_data);
if (retval < 0) {
dev_err(&fwu->rmi4_data->i2c_client->dev,
@@ -539,37 +498,34 @@
{
int retval;
+ fwu->flash_control.data[0] = cmd;
retval = fwu->fn_ptr->write(fwu->rmi4_data,
fwu->addr_f34_flash_control,
- &cmd,
- sizeof(cmd));
+ fwu->flash_control.data,
+ sizeof(fwu->flash_control.data));
if (retval < 0) {
dev_err(&fwu->rmi4_data->i2c_client->dev,
"%s: Failed to write command 0x%02x\n",
- __func__, cmd);
+ __func__, fwu->flash_control.data[0]);
return retval;
}
return 0;
}
-static unsigned char fwu_check_flash_status(void)
-{
- fwu_read_f34_flash_status();
- return fwu->flash_control.status;
-}
-
static int fwu_wait_for_idle(int timeout_ms)
{
int count = 0;
- int timeout_count = ((timeout_ms * 1000) / MAX_SLEEP_TIME_US) + 1;
-
+ int timeout_count = ((timeout_ms * 1000) / SLEEP_TIME_US) + 1;
do {
- if (fwu_read_interrupt_status() > 0)
+ if (fwu->flash_control.command == 0x00)
return 0;
- usleep_range(MIN_SLEEP_TIME_US, MAX_SLEEP_TIME_US);
- count++;
- } while (count < timeout_count);
+ usleep_range(SLEEP_TIME_US, SLEEP_TIME_US + 100);
+ } while (count++ < timeout_count);
+
+ fwu_read_f34_flash_status();
+ if (fwu->flash_control.command == 0x00)
+ return 0;
dev_err(&fwu->rmi4_data->i2c_client->dev,
"%s: Timed out waiting for idle status\n",
@@ -578,6 +534,133 @@
return -ETIMEDOUT;
}
+static enum flash_area fwu_go_nogo(void)
+{
+ int retval = 0;
+ int index = 0;
+ int deviceFirmwareID;
+ int imageConfigID;
+ int deviceConfigID;
+ unsigned long imageFirmwareID;
+ unsigned char firmware_id[4];
+ unsigned char config_id[4];
+ char *strptr;
+ char *imagePR = kzalloc(sizeof(MAX_FIRMWARE_ID_LEN), GFP_KERNEL);
+ enum flash_area flash_area = NONE;
+ struct i2c_client *i2c_client = fwu->rmi4_data->i2c_client;
+ struct f01_device_status f01_device_status;
+
+ if (fwu->force_update) {
+ flash_area = UI_FIRMWARE;
+ goto exit;
+ }
+
+ retval = fwu_read_f01_device_status(&f01_device_status);
+ if (retval < 0) {
+ flash_area = NONE;
+ goto exit;
+ }
+
+ imagePR = kzalloc(sizeof(MAX_FIRMWARE_ID_LEN), GFP_KERNEL);
+
+ /* Force update firmware when device is in bootloader mode */
+ if (f01_device_status.flash_prog) {
+ dev_info(&i2c_client->dev,
+ "%s: In flash prog mode\n",
+ __func__);
+ flash_area = UI_FIRMWARE;
+ goto exit;
+ }
+
+
+ /* device firmware id */
+ retval = fwu->fn_ptr->read(fwu->rmi4_data,
+ fwu->f01_fd.query_base_addr + 18,
+ firmware_id,
+ sizeof(firmware_id));
+ if (retval < 0) {
+ dev_err(&i2c_client->dev,
+ "Failed to read firmware ID (code %d).\n", retval);
+ goto exit;
+ }
+ firmware_id[3] = 0;
+ deviceFirmwareID = extract_uint(firmware_id);
+
+ /* .img firmware id */
+ strptr = strstr(FW_IMAGE_NAME, "PR");
+ if (!strptr) {
+ dev_err(&i2c_client->dev,
+ "No valid PR number (PRxxxxxxx)" \
+ "found in image file name...\n");
+ goto exit;
+ }
+
+ strptr += 2;
+ while (strptr[index] >= '0' && strptr[index] <= '9') {
+ imagePR[index] = strptr[index];
+ index++;
+ }
+ imagePR[index] = 0;
+
+ retval = kstrtoul(imagePR, 10, &imageFirmwareID);
+ if (retval == -EINVAL) {
+ dev_err(&i2c_client->dev,
+ "invalid image firmware id...\n");
+ goto exit;
+ }
+
+ dev_info(&i2c_client->dev,
+ "Device firmware id %d, .img firmware id %d\n",
+ deviceFirmwareID,
+ (unsigned int)imageFirmwareID);
+ if (imageFirmwareID > deviceFirmwareID) {
+ flash_area = UI_FIRMWARE;
+ goto exit;
+ }
+
+ /* device config id */
+ retval = fwu->fn_ptr->read(fwu->rmi4_data,
+ fwu->f34_fd.ctrl_base_addr,
+ config_id,
+ sizeof(config_id));
+ if (retval < 0) {
+ dev_err(&i2c_client->dev,
+ "Failed to read config ID (code %d).\n", retval);
+ flash_area = NONE;
+ goto exit;
+ }
+ deviceConfigID = extract_uint(config_id);
+
+ dev_info(&i2c_client->dev,
+ "Device config ID 0x%02X, 0x%02X, 0x%02X, 0x%02X\n",
+ config_id[0], config_id[1], config_id[2], config_id[3]);
+
+ /* .img config id */
+ dev_info(&i2c_client->dev,
+ ".img config ID 0x%02X, 0x%02X, 0x%02X, 0x%02X\n",
+ fwu->config_data[0],
+ fwu->config_data[1],
+ fwu->config_data[2],
+ fwu->config_data[3]);
+ imageConfigID = extract_uint(fwu->config_data);
+
+ if (imageConfigID > deviceConfigID) {
+ flash_area = CONFIG_AREA;
+ goto exit;
+ }
+
+exit:
+ kfree(imagePR);
+ if (flash_area == NONE)
+ dev_info(&i2c_client->dev,
+ "Nothing needs to be updated\n");
+ else
+ dev_info(&i2c_client->dev,
+ "Update %s block\n",
+ flash_area == UI_FIRMWARE ? "UI FW" : "CONFIG");
+ return flash_area;
+}
+
static int fwu_scan_pdt(void)
{
int retval;
@@ -649,16 +732,25 @@
int retval;
unsigned char block_offset[] = {0, 0};
unsigned short block_num;
+ struct i2c_client *i2c_client = fwu->rmi4_data->i2c_client;
#ifdef SHOW_PROGRESS
unsigned int progress = (command == CMD_WRITE_CONFIG_BLOCK) ?
10 : 100;
#endif
+
+#ifdef DEBUG_FW_UPDATE
+ dev_info(&i2c_client->dev,
+ "%s: Start to update %s blocks\n",
+ __func__,
+ command == CMD_WRITE_CONFIG_BLOCK ?
+ "config" : "firmware");
+#endif
retval = fwu->fn_ptr->write(fwu->rmi4_data,
fwu->f34_fd.data_base_addr + BLOCK_NUMBER_OFFSET,
block_offset,
sizeof(block_offset));
if (retval < 0) {
- dev_err(&fwu->rmi4_data->i2c_client->dev,
+ dev_err(&i2c_client->dev,
"%s: Failed to write to block number registers\n",
__func__);
return retval;
@@ -667,20 +759,19 @@
for (block_num = 0; block_num < block_cnt; block_num++) {
#ifdef SHOW_PROGRESS
if (block_num % progress == 0)
- dev_info(&fwu->rmi4_data->i2c_client->dev,
- "%s: update %s %3d / %3d\n",
- __func__,
- command == CMD_WRITE_CONFIG_BLOCK ?
- "config" : "firmware",
- block_num,
- block_cnt);
+ dev_info(&i2c_client->dev,
+ "%s: update %s %3d / %3d\n",
+ __func__,
+ command == CMD_WRITE_CONFIG_BLOCK ?
+ "config" : "firmware",
+ block_num, block_cnt);
#endif
retval = fwu->fn_ptr->write(fwu->rmi4_data,
fwu->f34_fd.data_base_addr + BLOCK_DATA_OFFSET,
block_ptr,
fwu->block_size);
if (retval < 0) {
- dev_err(&fwu->rmi4_data->i2c_client->dev,
+ dev_err(&i2c_client->dev,
"%s: Failed to write block data (block %d)\n",
__func__, block_num);
return retval;
@@ -688,7 +779,7 @@
retval = fwu_write_f34_command(command);
if (retval < 0) {
- dev_err(&fwu->rmi4_data->i2c_client->dev,
+ dev_err(&i2c_client->dev,
"%s: Failed to write command for block %d\n",
__func__, block_num);
return retval;
@@ -696,30 +787,28 @@
retval = fwu_wait_for_idle(WRITE_WAIT_MS);
if (retval < 0) {
- dev_err(&fwu->rmi4_data->i2c_client->dev,
- "%s: Failed to wait for idle status \
- (block %d)\n",
- __func__, block_num);
+ dev_err(&i2c_client->dev,
+ "%s: Failed to wait for idle status (block %d)\n",
+ __func__, block_num);
return retval;
}
- retval = fwu_check_flash_status();
- if (retval != 0) {
- dev_err(&fwu->rmi4_data->i2c_client->dev,
- "%s: Flash block %d status %d\n",
+ if (fwu->flash_control.status != 0x00) {
+ dev_err(&i2c_client->dev,
+ "%s: Flash block %d failed, status 0x%02X\n",
__func__, block_num, retval);
- return -1;
+ return retval;
}
+
block_ptr += fwu->block_size;
}
#ifdef SHOW_PROGRESS
- dev_info(&fwu->rmi4_data->i2c_client->dev,
- "%s: update %s %3d / %3d\n",
- __func__,
- command == CMD_WRITE_CONFIG_BLOCK ?
- "config" : "firmware",
- block_cnt,
- block_cnt);
+ dev_info(&i2c_client->dev,
+ "%s: update %s %3d / %3d\n",
+ __func__,
+ command == CMD_WRITE_CONFIG_BLOCK ?
+ "config" : "firmware",
+ block_cnt, block_cnt);
#endif
return 0;
}
@@ -741,7 +830,10 @@
int retval;
#ifdef DEBUG_FW_UPDATE
- dev_info(&fwu->rmi4_data->i2c_client->dev, "Write bootloader ID\n");
+ dev_info(&fwu->rmi4_data->i2c_client->dev,
+ "Write bootloader ID 0x%02X 0x%02X\n",
+ fwu->bootloader_id[0],
+ fwu->bootloader_id[1]);
#endif
retval = fwu->fn_ptr->write(fwu->rmi4_data,
fwu->f34_fd.data_base_addr + BLOCK_DATA_OFFSET,
@@ -789,17 +881,6 @@
if (retval < 0)
return retval;
- retval = fwu_read_f01_device_status(&f01_device_status);
- if (retval < 0)
- return retval;
-
- if (!f01_device_status.flash_prog) {
- dev_err(&fwu->rmi4_data->i2c_client->dev,
- "%s: Program enabled bit not set\n",
- __func__);
- return -EINVAL;
- }
-
retval = fwu_scan_pdt();
if (retval < 0)
return retval;
@@ -879,9 +960,12 @@
if (retval < 0)
return retval;
- dev_dbg(&fwu->rmi4_data->i2c_client->dev,
- "%s: Idle status detected\n",
- __func__);
+ if (fwu->flash_control.status != 0x00) {
+ dev_err(&fwu->rmi4_data->i2c_client->dev,
+ "%s: Erase all command failed, status 0x%02X\n",
+ __func__, retval);
+ return -1;
+ }
if (fwu->firmware_data) {
retval = fwu_write_firmware();
@@ -900,90 +984,6 @@
return retval;
}
-static int fwu_start_reflash(void)
-{
- int retval;
- struct image_header header;
- const unsigned char *fw_image;
- const struct firmware *fw_entry = NULL;
- struct f01_device_status f01_device_status;
-
- pr_notice("%s: Start of reflash process\n", __func__);
-
- if (fwu->ext_data_source)
- fw_image = fwu->ext_data_source;
- else {
- dev_dbg(&fwu->rmi4_data->i2c_client->dev,
- "%s: Requesting firmware image %s\n",
- __func__, FW_IMAGE_NAME);
-
- retval = request_firmware(&fw_entry, FW_IMAGE_NAME,
- &fwu->rmi4_data->i2c_client->dev);
- if (retval != 0) {
- dev_err(&fwu->rmi4_data->i2c_client->dev,
- "%s: Firmware image %s not available\n",
- __func__, FW_IMAGE_NAME);
- retval = -EINVAL;
- goto exit;
- }
-
- dev_dbg(&fwu->rmi4_data->i2c_client->dev,
- "%s: Firmware image size = %d\n",
- __func__, fw_entry->size);
-
- fw_image = fw_entry->data;
- }
-
- parse_header(&header, fw_image);
-
- if (header.image_size)
- fwu->firmware_data = fw_image + FW_IMAGE_OFFSET;
- if (header.config_size) {
- fwu->config_data = fw_image + FW_IMAGE_OFFSET +
- header.image_size;
- }
-
- fwu->fn_ptr->enable(fwu->rmi4_data, false);
-
- fwu_check_version();
-
- retval = fwu_do_reflash();
- if (retval < 0) {
- dev_err(&fwu->rmi4_data->i2c_client->dev,
- "%s: Failed to do reflash\n",
- __func__);
- }
-
- /* reset device */
- fwu_reset_device();
-
- /* check device status */
- retval = fwu_read_f01_device_status(&f01_device_status);
- if (retval < 0)
- goto exit;
-
- dev_info(&fwu->rmi4_data->i2c_client->dev, "Device is in %s mode\n",
- f01_device_status.flash_prog == 1 ? "bootloader" : "UI");
- if (f01_device_status.flash_prog)
- dev_info(&fwu->rmi4_data->i2c_client->dev, "Flash status %d\n",
- f01_device_status.status_code);
-
- if (f01_device_status.flash_prog) {
- dev_info(&fwu->rmi4_data->i2c_client->dev,
- "%s: Device is in flash prog mode 0x%02X\n",
- __func__, f01_device_status.status_code);
- retval = 0;
- goto exit;
- }
- fwu->fn_ptr->enable(fwu->rmi4_data, true);
- if (fw_entry)
- release_firmware(fw_entry);
-
- pr_notice("%s: End of reflash process\n", __func__);
-exit:
- return retval;
-}
-
static int fwu_do_write_config(void)
{
int retval;
@@ -1205,6 +1205,110 @@
return retval;
}
+static int fwu_start_reflash(void)
+{
+ int retval;
+ struct image_header header;
+ const unsigned char *fw_image;
+ const struct firmware *fw_entry = NULL;
+ struct f01_device_status f01_device_status;
+ enum flash_area flash_area;
+
+ pr_notice("%s: Start of reflash process\n", __func__);
+
+ if (fwu->ext_data_source)
+ fw_image = fwu->ext_data_source;
+ else {
+ dev_dbg(&fwu->rmi4_data->i2c_client->dev,
+ "%s: Requesting firmware image %s\n",
+ __func__, FW_IMAGE_NAME);
+
+ retval = request_firmware(&fw_entry, FW_IMAGE_NAME,
+ &fwu->rmi4_data->i2c_client->dev);
+ if (retval != 0) {
+ dev_err(&fwu->rmi4_data->i2c_client->dev,
+ "%s: Firmware image %s not available\n",
+ __func__, FW_IMAGE_NAME);
+ retval = -EINVAL;
+ goto exit;
+ }
+
+ dev_dbg(&fwu->rmi4_data->i2c_client->dev,
+ "%s: Firmware image size = %d\n",
+ __func__, fw_entry->size);
+
+ fw_image = fw_entry->data;
+ }
+
+ parse_header(&header, fw_image);
+
+ if (header.image_size)
+ fwu->firmware_data = fw_image + FW_IMAGE_OFFSET;
+ if (header.config_size) {
+ fwu->config_data = fw_image + FW_IMAGE_OFFSET +
+ header.image_size;
+ }
+
+ if (fwu->ext_data_source)
+ flash_area = UI_FIRMWARE;
+ else
+ flash_area = fwu_go_nogo();
+
+ switch (flash_area) {
+ case NONE:
+ dev_info(&fwu->rmi4_data->i2c_client->dev,
+ "%s: No need to do reflash.\n",
+ __func__);
+ goto exit;
+ case UI_FIRMWARE:
+ retval = fwu_do_reflash();
+ break;
+ case CONFIG_AREA:
+ retval = fwu_do_write_config();
+ break;
+ default:
+ dev_err(&fwu->rmi4_data->i2c_client->dev,
+ "%s: Unknown flash area\n",
+ __func__);
+ goto exit;
+ }
+
+ if (retval < 0) {
+ dev_err(&fwu->rmi4_data->i2c_client->dev,
+ "%s: Failed to do reflash\n",
+ __func__);
+ }
+
+ /* reset device */
+ fwu_reset_device();
+
+ /* check device status */
+ retval = fwu_read_f01_device_status(&f01_device_status);
+ if (retval < 0)
+ goto exit;
+
+ dev_info(&fwu->rmi4_data->i2c_client->dev, "Device is in %s mode\n",
+ f01_device_status.flash_prog == 1 ? "bootloader" : "UI");
+ if (f01_device_status.flash_prog)
+ dev_info(&fwu->rmi4_data->i2c_client->dev, "Flash status %d\n",
+ f01_device_status.status_code);
+
+ if (f01_device_status.flash_prog) {
+ dev_info(&fwu->rmi4_data->i2c_client->dev,
+ "%s: Device is in flash prog mode 0x%02X\n",
+ __func__, f01_device_status.status_code);
+ retval = 0;
+ goto exit;
+ }
+
+ if (fw_entry)
+ release_firmware(fw_entry);
+
+ pr_notice("%s: End of reflash process\n", __func__);
+exit:
+ return retval;
+}
+
int synaptics_fw_updater(unsigned char *fw_data)
{
int retval;
@@ -1351,7 +1455,7 @@
int retval;
unsigned long config_area;
- retval = sstrtoul(buf, 10, &config_area);
+ retval = kstrtoul(buf, 10, &config_area);
if (retval)
return retval;
@@ -1367,7 +1471,7 @@
unsigned long size;
struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- retval = sstrtoul(buf, 10, &size);
+ retval = kstrtoul(buf, 10, &size);
if (retval)
return retval;
@@ -1422,6 +1526,20 @@
return snprintf(buf, PAGE_SIZE, "%u\n", fwu->disp_config_block_count);
}
+static ssize_t fwu_sysfs_config_id_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char config_id[8];
+ /* device config id */
+ fwu->fn_ptr->read(fwu->rmi4_data,
+ fwu->f34_fd.ctrl_base_addr,
+ config_id,
+ sizeof(config_id));
+
+ return snprintf(buf, PAGE_SIZE, "%d.%d.%d.%d\n",
+ config_id[0], config_id[1], config_id[2], config_id[3]);
+}
+
static void synaptics_rmi4_fwu_attn(struct synaptics_rmi4_data *rmi4_data,
unsigned char intr_mask)
{
@@ -1431,6 +1549,11 @@
return;
}
+static void synaptics_rmi4_fwu_work(struct work_struct *work)
+{
+ fwu_start_reflash();
+}
+
static int synaptics_rmi4_fwu_init(struct synaptics_rmi4_data *rmi4_data)
{
int retval;
@@ -1497,6 +1620,7 @@
goto exit_free_mem;
fwu->initialized = true;
+ fwu->force_update = FORCE_UPDATE;
retval = sysfs_create_bin_file(&rmi4_data->input_dev->dev.kobj,
&dev_attr_data);
@@ -1519,6 +1643,13 @@
}
}
+#ifdef INSIDE_FIRMWARE_UPDATE
+ fwu->fwu_workqueue = create_singlethread_workqueue("fwu_workqueue");
+ INIT_DELAYED_WORK(&fwu->fwu_work, synaptics_rmi4_fwu_work);
+ queue_delayed_work(fwu->fwu_workqueue,
+ &fwu->fwu_work,
+ msecs_to_jiffies(1000));
+#endif
return 0;
exit_remove_attrs:
@@ -1584,4 +1715,4 @@
MODULE_AUTHOR("Synaptics, Inc.");
MODULE_DESCRIPTION("RMI4 FW Update Module");
MODULE_LICENSE("GPL");
-MODULE_VERSION(SYNAPTICS_RMI4_DRIVER_VERSION);
+MODULE_VERSION(SYNAPTICS_RMI4_DRIVER_VERSION_STRING);
diff --git a/kernel/drivers/input/touchscreen/synaptics_i2c_rmi4.c b/drivers/input/touchscreen/synaptics_i2c_rmi4.c
similarity index 93%
rename from kernel/drivers/input/touchscreen/synaptics_i2c_rmi4.c
rename to drivers/input/touchscreen/synaptics_i2c_rmi4.c
index 8553022..c68f730 100644
--- a/kernel/drivers/input/touchscreen/synaptics_i2c_rmi4.c
+++ b/drivers/input/touchscreen/synaptics_i2c_rmi4.c
@@ -347,28 +347,32 @@
if (rmi4_data->button_0d_enabled == input)
return count;
- list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
- if (fhandler->fn_number == SYNAPTICS_RMI4_F1A) {
- ii = fhandler->intr_reg_num;
+ if (!list_empty(&rmi->support_fn_list)) {
+ list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
+ if (fhandler->fn_number == SYNAPTICS_RMI4_F1A) {
+ ii = fhandler->intr_reg_num;
- retval = synaptics_rmi4_i2c_read(rmi4_data,
- rmi4_data->f01_ctrl_base_addr + 1 + ii,
- &intr_enable,
- sizeof(intr_enable));
- if (retval < 0)
- return retval;
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ rmi4_data->f01_ctrl_base_addr +
+ 1 + ii,
+ &intr_enable,
+ sizeof(intr_enable));
+ if (retval < 0)
+ return retval;
- if (input == 1)
- intr_enable |= fhandler->intr_mask;
- else
- intr_enable &= ~fhandler->intr_mask;
+ if (input == 1)
+ intr_enable |= fhandler->intr_mask;
+ else
+ intr_enable &= ~fhandler->intr_mask;
- retval = synaptics_rmi4_i2c_write(rmi4_data,
- rmi4_data->f01_ctrl_base_addr + 1 + ii,
- &intr_enable,
- sizeof(intr_enable));
- if (retval < 0)
- return retval;
+ retval = synaptics_rmi4_i2c_write(rmi4_data,
+ rmi4_data->f01_ctrl_base_addr +
+ 1 + ii,
+ &intr_enable,
+ sizeof(intr_enable));
+ if (retval < 0)
+ return retval;
+ }
}
}
@@ -637,28 +641,22 @@
finger_status,
x, y, wx, wy);
-#ifdef TYPE_B_PROTOCOL
- input_report_abs(rmi4_data->input_dev,
- ABS_MT_POSITION_X, x);
- input_report_abs(rmi4_data->input_dev,
- ABS_MT_POSITION_Y, y);
-#ifdef REPORT_2D_W
- input_report_abs(rmi4_data->input_dev,
- ABS_MT_TOUCH_MAJOR, max(wx, wy));
- input_report_abs(rmi4_data->input_dev,
- ABS_MT_TOUCH_MINOR, min(wx, wy));
-#endif
-#else
+ input_report_key(rmi4_data->input_dev,
+ BTN_TOUCH, 1);
+ input_report_key(rmi4_data->input_dev,
+ BTN_TOOL_FINGER, 1);
input_report_abs(rmi4_data->input_dev,
ABS_MT_POSITION_X, x);
input_report_abs(rmi4_data->input_dev,
ABS_MT_POSITION_Y, y);
+
#ifdef REPORT_2D_W
input_report_abs(rmi4_data->input_dev,
ABS_MT_TOUCH_MAJOR, max(wx, wy));
input_report_abs(rmi4_data->input_dev,
ABS_MT_TOUCH_MINOR, min(wx, wy));
#endif
+#ifndef TYPE_B_PROTOCOL
input_mt_sync(rmi4_data->input_dev);
#endif
touch_count++;
@@ -853,12 +851,14 @@
* Traverse the function handler list and service the source(s)
* of the interrupt accordingly.
*/
- list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
- if (fhandler->num_of_data_sources) {
- if (fhandler->intr_mask &
- intr[fhandler->intr_reg_num]) {
- synaptics_rmi4_report_touch(rmi4_data,
- fhandler, &touch_count);
+ if (!list_empty(&rmi->support_fn_list)) {
+ list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
+ if (fhandler->num_of_data_sources) {
+ if (fhandler->intr_mask &
+ intr[fhandler->intr_reg_num]) {
+ synaptics_rmi4_report_touch(rmi4_data,
+ fhandler, &touch_count);
+ }
}
}
}
@@ -1088,8 +1088,8 @@
if (!pdata->capacitance_button_map) {
dev_err(&rmi4_data->i2c_client->dev,
- "%s: capacitance_button_map is \
- NULL in board file\n",
+ "%s: capacitance_button_map is" \
+ "NULL in board file\n",
__func__);
return -ENODEV;
} else if (!pdata->capacitance_button_map->map) {
@@ -1194,6 +1194,63 @@
return 0;
}
+
+ /**
+ * synaptics_rmi4_query_device_info()
+ *
+ * Called by synaptics_rmi4_query_device().
+ *
+ */
+static int synaptics_rmi4_query_device_info(
+ struct synaptics_rmi4_data *rmi4_data)
+{
+ int retval;
+ unsigned char f01_query[F01_STD_QUERY_LEN];
+ struct synaptics_rmi4_device_info *rmi = &(rmi4_data->rmi4_mod_info);
+
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ rmi4_data->f01_query_base_addr,
+ f01_query,
+ sizeof(f01_query));
+ if (retval < 0)
+ return retval;
+
+ /* RMI Version 4.0 currently supported */
+ rmi->version_major = 4;
+ rmi->version_minor = 0;
+
+ rmi->manufacturer_id = f01_query[0];
+ rmi->product_props = f01_query[1];
+ rmi->product_info[0] = f01_query[2] & MASK_7BIT;
+ rmi->product_info[1] = f01_query[3] & MASK_7BIT;
+ rmi->date_code[0] = f01_query[4] & MASK_5BIT;
+ rmi->date_code[1] = f01_query[5] & MASK_4BIT;
+ rmi->date_code[2] = f01_query[6] & MASK_5BIT;
+ rmi->tester_id = ((f01_query[7] & MASK_7BIT) << 8) |
+ (f01_query[8] & MASK_7BIT);
+ rmi->serial_number = ((f01_query[9] & MASK_7BIT) << 8) |
+ (f01_query[10] & MASK_7BIT);
+ memcpy(rmi->product_id_string, &f01_query[11], 10);
+
+ if (rmi->manufacturer_id != 1) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: Non-Synaptics device found, manufacturer ID = %d\n",
+ __func__, rmi->manufacturer_id);
+ }
+
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ rmi4_data->f01_query_base_addr + F01_BUID_ID_OFFSET,
+ rmi->build_id,
+ sizeof(rmi->build_id));
+ if (retval < 0) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: Failed to read firmware build id (code %d)\n",
+ __func__, retval);
+ return retval;
+ }
+ return retval;
+}
+
/**
* synaptics_rmi4_query_device()
*
@@ -1214,7 +1271,6 @@
unsigned char page_number;
unsigned char intr_count = 0;
unsigned char data_sources = 0;
- unsigned char f01_query[F01_STD_QUERY_LEN];
unsigned short pdt_entry_addr;
unsigned short intr_addr;
struct synaptics_rmi4_f01_device_status status;
@@ -1264,6 +1320,11 @@
rmi4_data->f01_cmd_base_addr =
rmi_fd.cmd_base_addr;
+ retval =
+ synaptics_rmi4_query_device_info(rmi4_data);
+ if (retval < 0)
+ return retval;
+
retval = synaptics_rmi4_i2c_read(rmi4_data,
rmi4_data->f01_data_base_addr,
status.data,
@@ -1277,7 +1338,17 @@
status.status_code);
goto flash_prog_mode;
}
- break;
+ break;
+
+ case SYNAPTICS_RMI4_F34:
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ rmi_fd.ctrl_base_addr,
+ rmi->config_id,
+ sizeof(rmi->config_id));
+ if (retval < 0)
+ return retval;
+ break;
+
case SYNAPTICS_RMI4_F11:
if (rmi_fd.intr_src_count == 0)
break;
@@ -1335,56 +1406,24 @@
"%s: Number of interrupt registers = %d\n",
__func__, rmi4_data->num_of_intr_regs);
- retval = synaptics_rmi4_i2c_read(rmi4_data,
- rmi4_data->f01_query_base_addr,
- f01_query,
- sizeof(f01_query));
- if (retval < 0)
- return retval;
-
- /* RMI Version 4.0 currently supported */
- rmi->version_major = 4;
- rmi->version_minor = 0;
-
- rmi->manufacturer_id = f01_query[0];
- rmi->product_props = f01_query[1];
- rmi->product_info[0] = f01_query[2] & MASK_7BIT;
- rmi->product_info[1] = f01_query[3] & MASK_7BIT;
- rmi->date_code[0] = f01_query[4] & MASK_5BIT;
- rmi->date_code[1] = f01_query[5] & MASK_4BIT;
- rmi->date_code[2] = f01_query[6] & MASK_5BIT;
- rmi->tester_id = ((f01_query[7] & MASK_7BIT) << 8) |
- (f01_query[8] & MASK_7BIT);
- rmi->serial_number = ((f01_query[9] & MASK_7BIT) << 8) |
- (f01_query[10] & MASK_7BIT);
- memcpy(rmi->product_id_string, &f01_query[11], 10);
-
- if (rmi->manufacturer_id != 1) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Non-Synaptics device found, manufacturer ID = %d\n",
- __func__, rmi->manufacturer_id);
- }
-
- retval = synaptics_rmi4_i2c_read(rmi4_data,
- rmi4_data->f01_query_base_addr + F01_BUID_ID_OFFSET,
- rmi->build_id,
- sizeof(rmi->build_id));
- if (retval < 0)
- return retval;
-
memset(rmi4_data->intr_mask, 0x00, sizeof(rmi4_data->intr_mask));
/*
* Map out the interrupt bit masks for the interrupt sources
* from the registered function handlers.
*/
- list_for_each_entry(fhandler, &rmi->support_fn_list, link)
- data_sources += fhandler->num_of_data_sources;
+ if (!list_empty(&rmi->support_fn_list)) {
+ list_for_each_entry(fhandler, &rmi->support_fn_list, link)
+ data_sources += fhandler->num_of_data_sources;
+ }
if (data_sources) {
- list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
- if (fhandler->num_of_data_sources) {
- rmi4_data->intr_mask[fhandler->intr_reg_num] |=
- fhandler->intr_mask;
+ if (!list_empty(&rmi->support_fn_list)) {
+ list_for_each_entry(fhandler,
+ &rmi->support_fn_list, link) {
+ if (fhandler->num_of_data_sources) {
+ rmi4_data->intr_mask[fhandler->intr_reg_num] |=
+ fhandler->intr_mask;
+ }
}
}
}
@@ -1430,12 +1469,14 @@
msleep(100);
- list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
- if (fhandler->fn_number == SYNAPTICS_RMI4_F1A)
- synaptics_rmi4_f1a_kfree(fhandler);
- else
- kfree(fhandler->data);
- kfree(fhandler);
+ if (!list_empty(&rmi->support_fn_list)) {
+ list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
+ if (fhandler->fn_number == SYNAPTICS_RMI4_F1A)
+ synaptics_rmi4_f1a_kfree(fhandler);
+ else
+ kfree(fhandler->data);
+ kfree(fhandler);
+ }
}
retval = synaptics_rmi4_query_device(rmi4_data);
@@ -1534,12 +1575,14 @@
exp_fhandler->inserted = false;
list_add_tail(&exp_fhandler->link, &exp_fn_list);
} else {
- list_for_each_entry(exp_fhandler, &exp_fn_list, link) {
- if (exp_fhandler->func_init == func_init) {
- exp_fhandler->inserted = false;
- exp_fhandler->func_init = NULL;
- exp_fhandler->func_attn = NULL;
- goto exit;
+ if (!list_empty(&exp_fn_list)) {
+ list_for_each_entry(exp_fhandler, &exp_fn_list, link) {
+ if (exp_fhandler->func_init == func_init) {
+ exp_fhandler->inserted = false;
+ exp_fhandler->func_init = NULL;
+ exp_fhandler->func_attn = NULL;
+ goto exit;
+ }
}
}
}
@@ -1611,7 +1654,7 @@
retval = -ENOMEM;
goto err_input_device;
}
-/*
+
if (platform_data->regulator_en) {
rmi4_data->regulator = regulator_get(&client->dev, "vdd");
if (IS_ERR(rmi4_data->regulator)) {
@@ -1623,7 +1666,7 @@
}
regulator_enable(rmi4_data->regulator);
}
-*/
+
rmi4_data->i2c_client = client;
rmi4_data->current_page = MASK_8BIT;
rmi4_data->board = platform_data;
@@ -1652,12 +1695,16 @@
rmi4_data->input_dev->name = DRIVER_NAME;
rmi4_data->input_dev->phys = INPUT_PHYS_NAME;
rmi4_data->input_dev->id.bustype = BUS_I2C;
+ rmi4_data->input_dev->id.product = SYNAPTICS_RMI4_DRIVER_PRODUCT;
+ rmi4_data->input_dev->id.version = SYNAPTICS_RMI4_DRIVER_VERSION;
rmi4_data->input_dev->dev.parent = &client->dev;
input_set_drvdata(rmi4_data->input_dev, rmi4_data);
set_bit(EV_SYN, rmi4_data->input_dev->evbit);
set_bit(EV_KEY, rmi4_data->input_dev->evbit);
set_bit(EV_ABS, rmi4_data->input_dev->evbit);
+ set_bit(BTN_TOUCH, rmi4_data->input_dev->keybit);
+ set_bit(BTN_TOOL_FINGER, rmi4_data->input_dev->keybit);
#ifdef INPUT_PROP_DIRECT
set_bit(INPUT_PROP_DIRECT, rmi4_data->input_dev->propbit);
@@ -1681,9 +1728,11 @@
#endif
f1a = NULL;
- list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
- if (fhandler->fn_number == SYNAPTICS_RMI4_F1A)
- f1a = fhandler->data;
+ if (!list_empty(&rmi->support_fn_list)) {
+ list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
+ if (fhandler->fn_number == SYNAPTICS_RMI4_F1A)
+ f1a = fhandler->data;
+ }
}
if (f1a) {
@@ -1724,17 +1773,6 @@
&rmi4_data->det_work,
msecs_to_jiffies(EXP_FN_DET_INTERVAL));
- if (platform_data->gpio_config) {
- retval = platform_data->gpio_config(platform_data->irq_gpio,
- true);
- if (retval < 0) {
- dev_err(&client->dev,
- "%s: Failed to configure GPIO\n",
- __func__);
- goto err_gpio;
- }
- }
-
rmi4_data->irq = gpio_to_irq(platform_data->irq_gpio);
retval = synaptics_rmi4_irq_enable(rmi4_data, true);
@@ -1765,7 +1803,6 @@
}
err_enable_irq:
-err_gpio:
input_unregister_device(rmi4_data->input_dev);
err_register_input:
@@ -1775,16 +1812,17 @@
regulator_put(rmi4_data->regulator);
}
- list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
- if (fhandler->fn_number == SYNAPTICS_RMI4_F1A)
- synaptics_rmi4_f1a_kfree(fhandler);
- else
- kfree(fhandler->data);
- kfree(fhandler);
+ if (!list_empty(&rmi->support_fn_list)) {
+ list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
+ if (fhandler->fn_number == SYNAPTICS_RMI4_F1A)
+ synaptics_rmi4_f1a_kfree(fhandler);
+ else
+ kfree(fhandler->data);
+ kfree(fhandler);
+ }
}
-/*
+
err_regulator:
-*/
input_free_device(rmi4_data->input_dev);
rmi4_data->input_dev = NULL;
@@ -1836,12 +1874,14 @@
regulator_put(rmi4_data->regulator);
}
- list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
- if (fhandler->fn_number == SYNAPTICS_RMI4_F1A)
- synaptics_rmi4_f1a_kfree(fhandler);
- else
- kfree(fhandler->data);
- kfree(fhandler);
+ if (!list_empty(&rmi->support_fn_list)) {
+ list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
+ if (fhandler->fn_number == SYNAPTICS_RMI4_F1A)
+ synaptics_rmi4_f1a_kfree(fhandler);
+ else
+ kfree(fhandler->data);
+ kfree(fhandler);
+ }
}
input_free_device(rmi4_data->input_dev);
@@ -2107,4 +2147,4 @@
MODULE_AUTHOR("Synaptics, Inc.");
MODULE_DESCRIPTION("Synaptics RMI4 I2C Touch Driver");
MODULE_LICENSE("GPL v2");
-MODULE_VERSION(SYNAPTICS_RMI4_DRIVER_VERSION);
+MODULE_VERSION(SYNAPTICS_RMI4_DRIVER_VERSION_STRING);
diff --git a/kernel/drivers/input/touchscreen/synaptics_i2c_rmi4.h b/drivers/input/touchscreen/synaptics_i2c_rmi4.h
similarity index 95%
rename from kernel/drivers/input/touchscreen/synaptics_i2c_rmi4.h
rename to drivers/input/touchscreen/synaptics_i2c_rmi4.h
index 7ee0a92..eb8d5f2 100644
--- a/kernel/drivers/input/touchscreen/synaptics_i2c_rmi4.h
+++ b/drivers/input/touchscreen/synaptics_i2c_rmi4.h
@@ -20,27 +20,17 @@
#ifndef _SYNAPTICS_DSX_RMI4_H_
#define _SYNAPTICS_DSX_RMI4_H_
-#define SYNAPTICS_RMI4_DRIVER_VERSION "DSX 1.0"
+#define SYNAPTICS_RMI4_DS4 0x0001
+#define SYNAPTICS_RMI4_DS5 0x0002
+#define SYNAPTICS_RMI4_DRIVER_PRODUCT SYNAPTICS_RMI4_DS4
+#define SYNAPTICS_RMI4_DRIVER_VERSION 0x1001
+#define SYNAPTICS_RMI4_DRIVER_VERSION_STRING "0x1001"
#include <linux/version.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38))
-#define KERNEL_ABOVE_2_6_38
-#endif
-
-#ifdef KERNEL_ABOVE_2_6_38
-#define sstrtoul(...) kstrtoul(__VA_ARGS__)
-#else
-#define sstrtoul(...) strict_strtoul(__VA_ARGS__)
-#endif
-
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 7, 0))
-#define KERNEL_ABOVE_3_7
-#endif
-
#define PDT_PROPS (0x00EF)
#define PDT_START (0x00E9)
#define PDT_END (0x000A)
@@ -158,6 +148,7 @@
unsigned short serial_number;
unsigned char product_id_string[SYNAPTICS_RMI4_PRODUCT_ID_SIZE + 1];
unsigned char build_id[SYNAPTICS_RMI4_BUILD_ID_SIZE];
+ unsigned char config_id[3];
struct list_head support_fn_list;
};
diff --git a/kernel/drivers/input/touchscreen/synaptics_rmi_dev.c b/drivers/input/touchscreen/synaptics_rmi_dev.c
similarity index 99%
rename from kernel/drivers/input/touchscreen/synaptics_rmi_dev.c
rename to drivers/input/touchscreen/synaptics_rmi_dev.c
index 7585780..fbb6f5e 100644
--- a/kernel/drivers/input/touchscreen/synaptics_rmi_dev.c
+++ b/drivers/input/touchscreen/synaptics_rmi_dev.c
@@ -707,4 +707,4 @@
MODULE_AUTHOR("Synaptics, Inc.");
MODULE_DESCRIPTION("RMI4 RMI_Dev Module");
MODULE_LICENSE("GPL");
-MODULE_VERSION(SYNAPTICS_RMI4_DRIVER_VERSION);
+MODULE_VERSION(SYNAPTICS_RMI4_DRIVER_VERSION_STRING);
diff --git a/drivers/leds/leds-qpnp.c b/drivers/leds/leds-qpnp.c
index bea6842..fb1882c 100644
--- a/drivers/leds/leds-qpnp.c
+++ b/drivers/leds/leds-qpnp.c
@@ -27,6 +27,7 @@
#define WLED_MOD_EN_REG(base, n) (base + 0x60 + n*0x10)
#define WLED_IDAC_DLY_REG(base, n) (WLED_MOD_EN_REG(base, n) + 0x01)
#define WLED_FULL_SCALE_REG(base, n) (WLED_IDAC_DLY_REG(base, n) + 0x01)
+#define WLED_MOD_SRC_SEL_REG(base, n) (WLED_FULL_SCALE_REG(base, n) + 0x01)
/* wled control registers */
#define WLED_BRIGHTNESS_CNTL_LSB(base, n) (base + 0x40 + 2*n)
@@ -83,7 +84,7 @@
#define FLASH_LED_1_CURR(base) (base + 0x43)
#define FLASH_CLAMP_CURR(base) (base + 0x44)
#define FLASH_LED_TMR_CTRL(base) (base + 0x48)
-#define FLASH_HEADROOM(base) (base + 0x49)
+#define FLASH_HEADROOM(base) (base + 0x4A)
#define FLASH_STARTUP_DELAY(base) (base + 0x4B)
#define FLASH_MASK_ENABLE(base) (base + 0x4C)
#define FLASH_VREG_OK_FORCE(base) (base + 0x4F)
@@ -111,7 +112,7 @@
#define FLASH_ENABLE_MODULE 0x80
#define FLASH_ENABLE_MODULE_MASK 0x80
#define FLASH_DISABLE_ALL 0x00
-#define FLASH_ENABLE_MASK 0x60
+#define FLASH_ENABLE_MASK 0xE0
#define FLASH_ENABLE_LED_0 0x40
#define FLASH_ENABLE_LED_1 0x20
#define FLASH_INIT_MASK 0xE0
@@ -454,6 +455,14 @@
/* Set led current */
if (val > 0) {
+ rc = qpnp_led_masked_write(led, FLASH_ENABLE_CONTROL(led->base),
+ FLASH_ENABLE_MODULE_MASK, FLASH_ENABLE_MODULE);
+ if (rc) {
+ dev_err(&led->spmi_dev->dev,
+ "Enable reg write failed(%d)\n", rc);
+ return rc;
+ }
+
rc = qpnp_led_masked_write(led, led->flash_cfg->current_addr,
FLASH_CURRENT_MASK, led->flash_cfg->current_prgm);
if (rc) {
@@ -487,6 +496,13 @@
"LED %d flash write failed(%d)\n", led->id, rc);
return rc;
}
+ rc = qpnp_led_masked_write(led, FLASH_VREG_OK_FORCE(led->base),
+ FLASH_VREG_MASK, FLASH_HW_VREG_OK);
+ if (rc) {
+ dev_err(&led->spmi_dev->dev,
+ "Vreg OK reg write failed(%d)\n", rc);
+ return rc;
+ }
} else {
rc = qpnp_led_masked_write(led, FLASH_ENABLE_CONTROL(led->base),
FLASH_ENABLE_MASK,
@@ -755,7 +771,7 @@
if (led->wled_cfg->dig_mod_gen_en) {
rc = qpnp_led_masked_write(led,
- WLED_MOD_EN_REG(led->base, i),
+ WLED_MOD_SRC_SEL_REG(led->base, i),
WLED_NO_MASK, WLED_USE_EXT_GEN_MOD_SRC);
if (rc) {
dev_err(&led->spmi_dev->dev,
@@ -883,7 +899,7 @@
}
rc = qpnp_led_masked_write(led, FLASH_ENABLE_CONTROL(led->base),
- FLASH_ENABLE_MODULE_MASK, FLASH_ENABLE_MODULE);
+ FLASH_ENABLE_MODULE_MASK, FLASH_DISABLE_ALL);
if (rc) {
dev_err(&led->spmi_dev->dev,
"Enable reg write failed(%d)\n", rc);
diff --git a/drivers/media/platform/msm/camera_v2/Makefile b/drivers/media/platform/msm/camera_v2/Makefile
index 25dfd37..a1c5ea5 100644
--- a/drivers/media/platform/msm/camera_v2/Makefile
+++ b/drivers/media/platform/msm/camera_v2/Makefile
@@ -2,7 +2,7 @@
ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor
ccflags-y += -Idrivers/media/platform/msm/camera_v2/codecs
ccflags-y += -Idrivers/media/platform/msm/camera_v2/isps
-ccflags-y += -Idrivers/media/platform/msm/camera_v2/pps
+ccflags-y += -Idrivers/media/platform/msm/camera_v2/pproc
ccflags-y += -Idrivers/media/platform/msm/camera_v2/msm_vb2
ccflags-y += -Idrivers/media/platform/msm/camera_v2/camera
ccflags-y += -Idrivers/media/platform/msm/camera_v2/jpeg_10
@@ -15,3 +15,4 @@
obj-$(CONFIG_MSMB_CAMERA) += ispif/
obj-$(CONFIG_MSMB_JPEG) += jpeg_10/
obj-$(CONFIG_MSMB_CAMERA) += msm_buf_mgr/
+obj-$(CONFIG_MSMB_CAMERA) += pproc/
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
index b8c507e..8ce8dbf 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
@@ -320,7 +320,8 @@
if (BUF_SRC(bufq->stream_id))
list_add_tail(&buf_info->list, &bufq->head);
else
- buf_mgr->vb2_ops->put_buf(buf_info->vb2_buf);
+ buf_mgr->vb2_ops->put_buf(buf_info->vb2_buf,
+ bufq->session_id, bufq->stream_id);
buf_info->state = MSM_ISP_BUFFER_STATE_QUEUED;
rc = 0;
break;
@@ -366,7 +367,8 @@
} else {
buf_info->vb2_buf->v4l2_buf.timestamp = *tv;
buf_info->vb2_buf->v4l2_buf.sequence = frame_id;
- buf_mgr->vb2_ops->buf_done(buf_info->vb2_buf);
+ buf_mgr->vb2_ops->buf_done(buf_info->vb2_buf,
+ bufq->session_id, bufq->stream_id);
}
}
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
index f6b97d4..d412435 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
@@ -184,6 +184,7 @@
struct msm_vfe_stats_hardware_info *stats_hw_info;
struct v4l2_subdev_internal_ops *subdev_internal_ops;
struct v4l2_subdev_ops *subdev_ops;
+ uint32_t dmi_reg_offset;
};
struct msm_vfe_axi_hardware_info {
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 a522bd6..750963c 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
@@ -919,6 +919,7 @@
.get_pingpong_status = msm_vfe32_get_pingpong_status,
},
},
+ .dmi_reg_offset = 0x5A0,
.axi_hw_info = &msm_vfe32_axi_hw_info,
.subdev_ops = &msm_vfe32_subdev_ops,
.subdev_internal_ops = &msm_vfe32_internal_ops,
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
index dba59d7..ed4aa7f 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
@@ -1302,6 +1302,7 @@
.get_pingpong_status = msm_vfe40_get_pingpong_status,
},
},
+ .dmi_reg_offset = 0x918,
.axi_hw_info = &msm_vfe40_axi_hw_info,
.stats_hw_info = &msm_vfe40_stats_hw_info,
.subdev_ops = &msm_vfe40_subdev_ops,
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
index 606ee89..ac3ce0a 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
@@ -35,6 +35,8 @@
stream_cfg_cmd->axi_stream_handle =
(++axi_data->stream_handle_cnt) << 8 | i;
+ memset(&axi_data->stream_info[i], 0,
+ sizeof(struct msm_vfe_axi_stream));
axi_data->stream_info[i].session_id = stream_cfg_cmd->session_id;
axi_data->stream_info[i].stream_id = stream_cfg_cmd->stream_id;
axi_data->stream_info[i].buf_divert = stream_cfg_cmd->buf_divert;
@@ -621,7 +623,6 @@
int i;
struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
uint32_t wm_reload_mask = 0x0, reg_update_mask = 0x1;
- int send_update_complete = 0;
for (i = 0; i < MAX_NUM_STREAM; i++) {
if (axi_data->stream_info[i].state == START_PENDING ||
axi_data->stream_info[i].state ==
@@ -631,9 +632,6 @@
&wm_reload_mask, ®_update_mask);
if (axi_data->stream_info[i].state == STOP_PENDING)
axi_data->stream_info[i].state = STOPPING;
- } else if (axi_data->stream_info[i].state == STOPPING) {
- send_update_complete = 1;
- axi_data->stream_info[i].state = INACTIVE;
}
}
/*Reload AXI*/
@@ -642,47 +640,31 @@
/*Reg update per src*/
vfe_dev->hw_info->vfe_ops.core_ops.
reg_update(vfe_dev, reg_update_mask);
- if (send_update_complete) {
+ if (vfe_dev->axi_data.stream_update) {
ISP_DBG("%s: send update complete\n", __func__);
vfe_dev->axi_data.stream_update = 0;
complete(&vfe_dev->stream_config_complete);
}
}
-int msm_isp_cfg_ping_pong_address(struct vfe_device *vfe_dev,
- struct msm_vfe_axi_stream *stream_info, uint32_t pingpong_status,
- struct timeval *tv)
+static void msm_isp_cfg_pong_address(struct vfe_device *vfe_dev,
+ struct msm_vfe_axi_stream *stream_info)
{
- int i, rc = -1;
- struct msm_isp_buffer *buf = NULL;
- struct msm_isp_event_data buf_event;
- uint32_t pingpong_bit = 0;
- uint32_t bufq_handle = stream_info->bufq_handle;
- uint32_t stream_idx = stream_info->stream_handle & 0xFF;
+ int i;
+ struct msm_isp_buffer *buf = stream_info->buf[1];
+ for (i = 0; i < stream_info->num_planes; i++)
+ vfe_dev->hw_info->vfe_ops.axi_ops.update_ping_pong_addr(
+ vfe_dev, stream_info->wm[i],
+ VFE_PING_FLAG, buf->mapped_info[i].paddr);
+ stream_info->buf[0] = buf;
+}
+static void msm_isp_get_done_buf(struct vfe_device *vfe_dev,
+ struct msm_vfe_axi_stream *stream_info, uint32_t pingpong_status,
+ struct msm_isp_buffer **done_buf)
+{
+ uint32_t pingpong_bit = 0, i;
pingpong_bit = (~(pingpong_status >> stream_info->wm[0]) & 0x1);
- rc = vfe_dev->buf_mgr->ops->get_buf(
- vfe_dev->buf_mgr, bufq_handle, &buf);
- if (rc < 0) {
- if (stream_info->stream_type == BURST_STREAM &&
- stream_info->num_burst_capture <= 1) {
- rc = 0;
- if (pingpong_bit)
- buf = stream_info->buf[0];
- else
- buf = stream_info->buf[1];
- } else {
- vfe_dev->error_info.
- stream_framedrop_count[stream_idx]++;
- return rc;
- }
- }
-
- if (buf->num_planes != stream_info->num_planes) {
- pr_err("%s: Invalid buffer\n", __func__);
- rc = -EINVAL;
- goto buf_error;
- }
for (i = 0; i < stream_info->num_planes; i++) {
if (pingpong_bit !=
(~(pingpong_status >> stream_info->wm[i]) & 0x1)) {
@@ -690,19 +672,58 @@
__func__, pingpong_status);
}
}
+ *done_buf = stream_info->buf[pingpong_bit];
+}
+
+static int msm_isp_cfg_ping_pong_address(struct vfe_device *vfe_dev,
+ struct msm_vfe_axi_stream *stream_info, uint32_t pingpong_status)
+{
+ int i, rc = -1;
+ struct msm_isp_buffer *buf = NULL;
+ uint32_t pingpong_bit = 0;
+ uint32_t bufq_handle = stream_info->bufq_handle;
+ uint32_t stream_idx = stream_info->stream_handle & 0xFF;
+
+ rc = vfe_dev->buf_mgr->ops->get_buf(
+ vfe_dev->buf_mgr, bufq_handle, &buf);
+ if (rc < 0) {
+ vfe_dev->error_info.
+ stream_framedrop_count[stream_idx]++;
+ return rc;
+ }
+
+ if (buf->num_planes != stream_info->num_planes) {
+ pr_err("%s: Invalid buffer\n", __func__);
+ rc = -EINVAL;
+ goto buf_error;
+ }
+
for (i = 0; i < stream_info->num_planes; i++)
vfe_dev->hw_info->vfe_ops.axi_ops.update_ping_pong_addr(
vfe_dev, stream_info->wm[i],
pingpong_status, buf->mapped_info[i].paddr);
- if (stream_info->buf[pingpong_bit] && tv) {
+ pingpong_bit = (~(pingpong_status >> stream_info->wm[0]) & 0x1);
+ stream_info->buf[pingpong_bit] = buf;
+ return 0;
+buf_error:
+ vfe_dev->buf_mgr->ops->put_buf(vfe_dev->buf_mgr,
+ buf->bufq_handle, buf->buf_idx);
+ return rc;
+}
+
+static void msm_isp_process_done_buf(struct vfe_device *vfe_dev,
+ struct msm_vfe_axi_stream *stream_info, struct msm_isp_buffer *buf,
+ struct timeval *tv)
+{
+ struct msm_isp_event_data buf_event;
+ uint32_t frame_id = vfe_dev->axi_data.
+ src_info[stream_info->stream_src].frame_id;
+ if (buf && tv) {
if (stream_info->buf_divert) {
vfe_dev->buf_mgr->ops->buf_divert(vfe_dev->buf_mgr,
- stream_info->buf[pingpong_bit]->bufq_handle,
- stream_info->buf[pingpong_bit]->buf_idx,
- tv, stream_info->frame_id);
-
- buf_event.frame_id = stream_info->frame_id;
+ buf->bufq_handle, buf->buf_idx, tv, frame_id);
+ buf_event.frame_id = frame_id;
buf_event.timestamp = *tv;
buf_event.u.buf_done.session_id =
stream_info->session_id;
@@ -710,24 +731,14 @@
stream_info->stream_id;
buf_event.u.buf_done.handle =
stream_info->bufq_handle;
- buf_event.u.buf_done.buf_idx =
- stream_info->buf[pingpong_bit]->buf_idx;
+ buf_event.u.buf_done.buf_idx = buf->buf_idx;
msm_isp_send_event(
vfe_dev, ISP_EVENT_BUF_DIVERT, &buf_event);
} else {
vfe_dev->buf_mgr->ops->buf_done(vfe_dev->buf_mgr,
- stream_info->buf[pingpong_bit]->bufq_handle,
- stream_info->buf[pingpong_bit]->buf_idx,
- tv, stream_info->frame_id);
+ buf->bufq_handle, buf->buf_idx, tv, frame_id);
}
}
-
- stream_info->buf[pingpong_bit] = buf;
- return 0;
-buf_error:
- vfe_dev->buf_mgr->ops->put_buf(vfe_dev->buf_mgr,
- buf->bufq_handle, buf->buf_idx);
- return rc;
}
enum msm_isp_camif_update_state
@@ -855,7 +866,6 @@
&axi_data->stream_info[
(stream_cfg_cmd->stream_handle[i] & 0xFF)];
-
if (stream_info->stream_src == RDI)
src_state =
axi_data->src_info[
@@ -869,9 +879,23 @@
if (stream_cfg_cmd->cmd == START_STREAM) {
/*Set address for both PING & PONG register */
rc = msm_isp_cfg_ping_pong_address(vfe_dev,
- stream_info, VFE_PING_FLAG, NULL);
- rc = msm_isp_cfg_ping_pong_address(vfe_dev,
- stream_info, VFE_PONG_FLAG, NULL);
+ stream_info, VFE_PONG_FLAG);
+ if (rc < 0) {
+ pr_err("%s: No buffer for start stream\n",
+ __func__);
+ return rc;
+ }
+ /* For burst stream of one capture, only one buffer
+ * is allocated. Duplicate ping buffer address to pong
+ * buffer to ensure hardware write to a valid address
+ */
+ if (stream_info->stream_type == BURST_STREAM &&
+ stream_info->num_burst_capture <= 1) {
+ msm_isp_cfg_pong_address(vfe_dev, stream_info);
+ } else {
+ rc = msm_isp_cfg_ping_pong_address(vfe_dev,
+ stream_info, VFE_PING_FLAG);
+ }
}
if (src_state && camif_update != DISABLE_CAMIF) {
/*On the fly stream start/stop */
@@ -888,7 +912,8 @@
}
if (!wait_for_complete) {
/*Reload AXI*/
- vfe_dev->hw_info->vfe_ops.axi_ops.
+ if (stream_cfg_cmd->cmd == START_STREAM)
+ vfe_dev->hw_info->vfe_ops.axi_ops.
reload_wm(vfe_dev, wm_reload_mask);
/*Reg update per src*/
vfe_dev->hw_info->vfe_ops.core_ops.
@@ -904,7 +929,8 @@
axi_data->stream_update = 1;
spin_unlock_irqrestore(&vfe_dev->shared_data_lock, flags);
/*Reload AXI*/
- vfe_dev->hw_info->vfe_ops.axi_ops.
+ if (stream_cfg_cmd->cmd == START_STREAM)
+ vfe_dev->hw_info->vfe_ops.axi_ops.
reload_wm(vfe_dev, wm_reload_mask);
/*Reg update per src*/
vfe_dev->hw_info->vfe_ops.core_ops.
@@ -956,7 +982,8 @@
uint32_t irq_status0, uint32_t irq_status1,
struct timeval *tv)
{
- int i;
+ int i, rc = 0;
+ struct msm_isp_buffer *done_buf = NULL;
uint32_t comp_mask = 0, wm_mask = 0;
uint32_t pingpong_status, stream_idx;
struct msm_vfe_axi_stream *stream_info;
@@ -988,8 +1015,18 @@
__func__,
stream_idx, stream_info->frame_id);
stream_info->frame_id++;
- msm_isp_cfg_ping_pong_address(vfe_dev,
- stream_info, pingpong_status, tv);
+ msm_isp_get_done_buf(vfe_dev, stream_info,
+ pingpong_status, &done_buf);
+ if (stream_info->stream_type ==
+ CONTINUOUS_STREAM ||
+ stream_info->num_burst_capture > 1) {
+ rc = msm_isp_cfg_ping_pong_address(
+ vfe_dev, stream_info,
+ pingpong_status);
+ }
+ if (done_buf && !rc)
+ msm_isp_process_done_buf(vfe_dev,
+ stream_info, done_buf, tv);
}
}
wm_mask &= ~(comp_info->stream_composite_mask);
@@ -1005,8 +1042,16 @@
stream_idx = axi_data->free_wm[i] & 0xFF;
stream_info = &axi_data->stream_info[stream_idx];
stream_info->frame_id++;
- msm_isp_cfg_ping_pong_address(vfe_dev,
- stream_info, pingpong_status, tv);
+ msm_isp_get_done_buf(vfe_dev, stream_info,
+ pingpong_status, &done_buf);
+ if (stream_info->stream_type == CONTINUOUS_STREAM ||
+ stream_info->num_burst_capture > 1) {
+ rc = msm_isp_cfg_ping_pong_address(vfe_dev,
+ stream_info, pingpong_status);
+ }
+ if (done_buf && !rc)
+ msm_isp_process_done_buf(vfe_dev,
+ stream_info, done_buf, tv);
}
}
return;
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h
index 0c64c19..9765ae2 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h
@@ -52,10 +52,6 @@
void msm_isp_axi_stream_update(struct vfe_device *vfe_dev);
-int msm_isp_cfg_ping_pong_address(struct vfe_device *vfe_dev,
- struct msm_vfe_axi_stream *stream_info, uint32_t pingpong_status,
- struct timeval *tv);
-
void msm_isp_update_framedrop_reg(struct vfe_device *vfe_dev);
void msm_isp_update_framedrop_count(struct vfe_device *vfe_dev);
void msm_isp_sof_notify(struct vfe_device *vfe_dev,
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
index ab8dc95..e181b53 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
@@ -219,15 +219,15 @@
lo_val1 = lo_val & 0x0000FFFF;
lo_val = (lo_val & 0xFFFF0000)>>16;
msm_camera_io_w(lo_val1, vfe_dev->vfe_base +
- 0x091C);
+ vfe_dev->hw_info->dmi_reg_offset + 0x4);
} else if (reg_cfg_cmd->cmd_type ==
VFE_WRITE_DMI_64BIT) {
hi_val = *hi_tbl_ptr++;
msm_camera_io_w(hi_val, vfe_dev->vfe_base +
- 0x0918);
+ vfe_dev->hw_info->dmi_reg_offset);
}
msm_camera_io_w(lo_val, vfe_dev->vfe_base +
- 0x091C);
+ vfe_dev->hw_info->dmi_reg_offset + 0x4);
}
break;
}
@@ -258,16 +258,16 @@
for (i = 0; i < reg_cfg_cmd->u.dmi_info.len/4; i++) {
if (reg_cfg_cmd->cmd_type == VFE_READ_DMI_64BIT) {
hi_val = msm_camera_io_r(vfe_dev->vfe_base +
- 0x0918);
+ vfe_dev->hw_info->dmi_reg_offset);
*hi_tbl_ptr++ = hi_val;
}
lo_val = msm_camera_io_r(vfe_dev->vfe_base +
- 0x091C);
+ vfe_dev->hw_info->dmi_reg_offset + 0x4);
if (reg_cfg_cmd->cmd_type == VFE_READ_DMI_16BIT) {
lo_val1 = msm_camera_io_r(vfe_dev->vfe_base +
- 0x091C);
+ vfe_dev->hw_info->dmi_reg_offset + 0x4);
lo_val |= lo_val1 << 16;
}
*lo_tbl_ptr++ = lo_val;
diff --git a/drivers/media/platform/msm/camera_v2/msm.c b/drivers/media/platform/msm/camera_v2/msm.c
index c908333..08a4566 100644
--- a/drivers/media/platform/msm/camera_v2/msm.c
+++ b/drivers/media/platform/msm/camera_v2/msm.c
@@ -66,17 +66,6 @@
int stream_id;
};
-struct msm_stream {
- struct list_head list;
-
- /* stream index per session, same
- * as stream_id but set through s_parm */
- unsigned int stream_id;
-
- /* vb2 buffer handling */
- struct vb2_queue *vb2_q;
-};
-
struct msm_v4l2_subdev {
/* FIXME: for session close and error handling such
* as daemon shutdown */
@@ -275,7 +264,7 @@
stream->stream_id = stream_id;
stream->vb2_q = q;
-
+ spin_lock_init(&stream->stream_lock);
msm_enqueue(&session->stream_q, &stream->list);
session->stream_q.len++;
diff --git a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c
index 7cae19f..a47d178 100644
--- a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c
+++ b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c
@@ -9,69 +9,101 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
-
#include "msm_generic_buf_mgr.h"
-struct msm_buf_mngr_device *msm_buf_mngr_dev;
+static struct msm_buf_mngr_device *msm_buf_mngr_dev;
static int msm_buf_mngr_get_buf(struct msm_buf_mngr_device *buf_mngr_dev,
- struct msm_buf_mngr_info *buf_info)
+ void __user *argp)
{
- struct vb2_buffer *vb2_buf = NULL;
- vb2_buf = buf_mngr_dev->vb2_ops.get_buf(buf_info->session_id,
+ struct msm_buf_mngr_info *buf_info =
+ (struct msm_buf_mngr_info *)argp;
+ struct msm_get_bufs *new_entry =
+ kzalloc(sizeof(struct msm_get_bufs), GFP_KERNEL);
+
+ if (!new_entry) {
+ pr_err("%s:No mem\n", __func__);
+ return -ENOMEM;
+ }
+ INIT_LIST_HEAD(&new_entry->entry);
+ new_entry->vb2_buf = buf_mngr_dev->vb2_ops.get_buf(buf_info->session_id,
buf_info->stream_id);
- buf_mngr_dev->bufs.vb2_buf = vb2_buf;
- list_add_tail(&buf_mngr_dev->bufs.list, &buf_mngr_dev->bufs.list);
- buf_info->index = vb2_buf->v4l2_buf.index;
+ if (!new_entry->vb2_buf) {
+ pr_err("%s:Get buf is null\n", __func__);
+ kfree(new_entry);
+ return -EINVAL;
+ }
+ list_add_tail(&new_entry->entry, &buf_mngr_dev->buf_qhead);
+ buf_info->index = new_entry->vb2_buf->v4l2_buf.index;
return 0;
}
static int msm_buf_mngr_buf_done(struct msm_buf_mngr_device *buf_mngr_dev,
struct msm_buf_mngr_info *buf_info)
{
- struct vb2_buffer *vb2_buf = NULL;
- list_for_each_entry(vb2_buf, &buf_mngr_dev->bufs.list, queued_entry) {
- if (vb2_buf->v4l2_buf.index == buf_info->index) {
- buf_mngr_dev->vb2_ops.put_buf(vb2_buf);
+ struct msm_get_bufs *bufs, *save;
+ int ret = -EINVAL;
+ list_for_each_entry_safe(bufs, save, &buf_mngr_dev->buf_qhead, entry) {
+ if (bufs->vb2_buf->v4l2_buf.index == buf_info->index) {
+ bufs->vb2_buf->v4l2_buf.sequence = buf_info->frame_id;
+ ret = buf_mngr_dev->vb2_ops.buf_done
+ (bufs->vb2_buf,
+ buf_info->session_id,
+ buf_info->stream_id);
+ list_del_init(&bufs->entry);
+ kfree(bufs);
break;
}
}
- return 0;
+ return ret;
}
+
static int msm_buf_mngr_put_buf(struct msm_buf_mngr_device *buf_mngr_dev,
struct msm_buf_mngr_info *buf_info)
{
- struct vb2_buffer *vb2_buf = NULL;
- list_for_each_entry(vb2_buf, &buf_mngr_dev->bufs.list, queued_entry) {
- if (vb2_buf->v4l2_buf.index == buf_info->index) {
- buf_mngr_dev->vb2_ops.buf_done(vb2_buf);
+ struct msm_get_bufs *bufs, *save;
+ int ret = -EINVAL;
+
+ list_for_each_entry_safe(bufs, save, &buf_mngr_dev->buf_qhead, entry) {
+ if (bufs->vb2_buf->v4l2_buf.index == buf_info->index) {
+ ret = buf_mngr_dev->vb2_ops.put_buf(bufs->vb2_buf,
+ buf_info->session_id, buf_info->stream_id);
+ list_del_init(&bufs->entry);
+ kfree(bufs);
break;
}
}
- return 0;
+ return ret;
}
static long msm_buf_mngr_subdev_ioctl(struct v4l2_subdev *sd,
unsigned int cmd, void *arg)
{
+ int rc = 0;
struct msm_buf_mngr_device *buf_mngr_dev = v4l2_get_subdevdata(sd);
-
void __user *argp = (void __user *)arg;
+
+ if (!buf_mngr_dev) {
+ pr_err("%s buf manager device NULL\n", __func__);
+ rc = -ENOMEM;
+ return rc;
+ }
+
switch (cmd) {
case VIDIOC_MSM_BUF_MNGR_GET_BUF:
- msm_buf_mngr_get_buf(buf_mngr_dev, argp);
+ rc = msm_buf_mngr_get_buf(buf_mngr_dev, argp);
break;
case VIDIOC_MSM_BUF_MNGR_BUF_DONE:
- msm_buf_mngr_buf_done(buf_mngr_dev, argp);
+ rc = msm_buf_mngr_buf_done(buf_mngr_dev, argp);
break;
case VIDIOC_MSM_BUF_MNGR_PUT_BUF:
- msm_buf_mngr_put_buf(buf_mngr_dev, argp);
+ rc = msm_buf_mngr_put_buf(buf_mngr_dev, argp);
break;
default:
return -ENOIOCTLCMD;
}
- return 0;
+ return rc;
}
static struct v4l2_subdev_core_ops msm_buf_mngr_subdev_core_ops = {
@@ -89,7 +121,6 @@
static int __init msm_buf_mngr_init(void)
{
int rc = 0;
-
msm_buf_mngr_dev = kzalloc(sizeof(*msm_buf_mngr_dev),
GFP_KERNEL);
if (WARN_ON(!msm_buf_mngr_dev)) {
@@ -115,8 +146,9 @@
}
v4l2_subdev_notify(&msm_buf_mngr_dev->subdev.sd, MSM_SD_NOTIFY_REQ_CB,
- &msm_buf_mngr_dev->vb2_ops);
+ &msm_buf_mngr_dev->vb2_ops);
+ INIT_LIST_HEAD(&msm_buf_mngr_dev->buf_qhead);
end:
return rc;
}
diff --git a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.h b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.h
index 35368fd..c38a424 100644
--- a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.h
+++ b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.h
@@ -25,14 +25,13 @@
#include "msm_sd.h"
struct msm_get_bufs {
- struct list_head list;
+ struct list_head entry;
struct vb2_buffer *vb2_buf;
};
struct msm_buf_mngr_device {
+ struct list_head buf_qhead;
struct msm_sd_subdev subdev;
struct msm_sd_req_vb2_q vb2_ops;
- struct msm_get_bufs bufs;
};
-
#endif
diff --git a/drivers/media/platform/msm/camera_v2/msm_sd.h b/drivers/media/platform/msm/camera_v2/msm_sd.h
index aaf3548..958e030 100644
--- a/drivers/media/platform/msm/camera_v2/msm_sd.h
+++ b/drivers/media/platform/msm/camera_v2/msm_sd.h
@@ -65,8 +65,10 @@
struct vb2_buffer *(*get_buf)(int session_id, unsigned int stream_id);
struct vb2_queue *(*get_vb2_queue)(int session_id,
unsigned int stream_id);
- int (*put_buf)(struct vb2_buffer *vb2_buf);
- int (*buf_done)(struct vb2_buffer *vb2_buf);
+ int (*put_buf)(struct vb2_buffer *vb2_buf, int session_id,
+ unsigned int stream_id);
+ int (*buf_done)(struct vb2_buffer *vb2_buf, int session_id,
+ unsigned int stream_id);
};
#define MSM_SD_NOTIFY_GET_SD 0x00000001
diff --git a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
index 8a572a6..6ea86ae 100644
--- a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
+++ b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
@@ -12,8 +12,6 @@
#include "msm_vb2.h"
-static spinlock_t vb2_buf_lock;
-
static int msm_vb2_queue_setup(struct vb2_queue *q,
const struct v4l2_format *fmt,
unsigned int *num_buffers, unsigned int *num_planes,
@@ -44,7 +42,6 @@
msm_vb2_buf = container_of(vb, struct msm_vb2_buffer, vb2_buf);
msm_vb2_buf->in_freeq = 0;
- spin_lock_init(&vb2_buf_lock);
return 0;
}
@@ -102,22 +99,23 @@
static struct vb2_buffer *msm_vb2_get_buf(int session_id,
unsigned int stream_id)
{
- struct vb2_queue *q;
+ struct msm_stream *stream;
struct vb2_buffer *vb2_buf = NULL;
struct msm_vb2_buffer *msm_vb2;
unsigned long flags;
- spin_lock_irqsave(&vb2_buf_lock, flags);
+ stream = msm_get_stream(session_id, stream_id);
+ if (!stream)
+ return NULL;
- q = msm_get_stream_vb2q(session_id, stream_id);
+ spin_lock_irqsave(&stream->stream_lock, flags);
- /*FIXME: need a check if stream on issue*/
- if (!q) {
+ if (!stream->vb2_q) {
pr_err("%s: stream q not available\n", __func__);
goto end;
}
- list_for_each_entry(vb2_buf, &(q->queued_list),
+ list_for_each_entry(vb2_buf, &(stream->vb2_q->queued_list),
queued_entry) {
if (vb2_buf->state != VB2_BUF_STATE_ACTIVE)
continue;
@@ -131,11 +129,12 @@
}
vb2_buf = NULL;
end:
- spin_unlock_irqrestore(&vb2_buf_lock, flags);
+ spin_unlock_irqrestore(&stream->stream_lock, flags);
return vb2_buf;
}
-static int msm_vb2_put_buf(struct vb2_buffer *vb)
+static int msm_vb2_put_buf(struct vb2_buffer *vb, int session_id,
+ unsigned int stream_id)
{
struct msm_vb2_buffer *msm_vb2;
int rc = 0;
@@ -155,13 +154,18 @@
return rc;
}
-static int msm_vb2_buf_done(struct vb2_buffer *vb)
+static int msm_vb2_buf_done(struct vb2_buffer *vb, int session_id,
+ unsigned int stream_id)
{
unsigned long flags;
struct msm_vb2_buffer *msm_vb2;
+ struct msm_stream *stream;
int rc = 0;
- spin_lock_irqsave(&vb2_buf_lock, flags);
+ stream = msm_get_stream(session_id, stream_id);
+ if (!stream)
+ return 0;
+ spin_lock_irqsave(&stream->stream_lock, flags);
if (vb) {
msm_vb2 =
container_of(vb, struct msm_vb2_buffer, vb2_buf);
@@ -176,7 +180,7 @@
rc = -EINVAL;
}
- spin_unlock_irqrestore(&vb2_buf_lock, flags);
+ spin_unlock_irqrestore(&stream->stream_lock, flags);
return rc;
}
diff --git a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.h b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.h
index 148d577..cecc85e 100644
--- a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.h
+++ b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.h
@@ -51,6 +51,17 @@
void *alloc_ctx;
};
+struct msm_stream {
+ struct list_head list;
+
+ /* stream index per session, same
+ * as stream_id but set through s_parm */
+ unsigned int stream_id;
+ /* vb2 buffer handling */
+ struct vb2_queue *vb2_q;
+ spinlock_t stream_lock;
+};
+
struct vb2_ops *msm_vb2_get_q_ops(void);
struct vb2_mem_ops *msm_vb2_get_q_mem_ops(void);
int msm_vb2_request_cb(struct msm_sd_req_vb2_q *req_sd);
diff --git a/drivers/media/platform/msm/camera_v2/pproc/Makefile b/drivers/media/platform/msm/camera_v2/pproc/Makefile
new file mode 100644
index 0000000..854e4e7
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/pproc/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_MSMB_CAMERA) += cpp/
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/Makefile b/drivers/media/platform/msm/camera_v2/pproc/cpp/Makefile
new file mode 100644
index 0000000..2f969d2
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/Makefile
@@ -0,0 +1,3 @@
+ccflags-y += -Idrivers/media/platform/msm/camera_v2
+ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/io
+obj-$(CONFIG_MSM_CPP) += msm_cpp.o
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
new file mode 100644
index 0000000..4b1b1c7
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
@@ -0,0 +1,1025 @@
+/* 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 pr_fmt(fmt) "MSM-CPP %s:%d " fmt, __func__, __LINE__
+
+
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/firmware.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/module.h>
+#include <linux/regulator/consumer.h>
+#include <linux/ion.h>
+#include <linux/proc_fs.h>
+#include <linux/debugfs.h>
+#include <linux/msm_ion.h>
+#include <linux/iommu.h>
+#include <mach/iommu_domains.h>
+#include <mach/iommu.h>
+#include <mach/vreg.h>
+#include <media/msm_isp.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-ioctl.h>
+#include <media/msmb_camera.h>
+#include <media/msmb_pproc.h>
+#include "msm_cpp.h"
+#include "msm_camera_io_util.h"
+
+#define MSM_CPP_DRV_NAME "msm_cpp"
+
+#define CONFIG_MSM_CPP_DBG 0
+
+#if CONFIG_MSM_CPP_DBG
+#define CPP_DBG(fmt, args...) pr_err(fmt, ##args)
+#else
+#define CPP_DBG(fmt, args...) pr_debug(fmt, ##args)
+#endif
+
+#define ERR_USER_COPY(to) pr_err("copy %s user\n", \
+ ((to) ? "to" : "from"))
+#define ERR_COPY_FROM_USER() ERR_USER_COPY(0)
+
+#define msm_dequeue(queue, member) ({ \
+ unsigned long flags; \
+ struct msm_device_queue *__q = (queue); \
+ struct msm_queue_cmd *qcmd = 0; \
+ spin_lock_irqsave(&__q->lock, flags); \
+ if (!list_empty(&__q->list)) { \
+ __q->len--; \
+ qcmd = list_first_entry(&__q->list, \
+ struct msm_queue_cmd, member); \
+ list_del_init(&qcmd->member); \
+ } \
+ spin_unlock_irqrestore(&__q->lock, flags); \
+ qcmd; \
+})
+
+static void msm_queue_init(struct msm_device_queue *queue, const char *name)
+{
+ CPP_DBG("E\n");
+ spin_lock_init(&queue->lock);
+ queue->len = 0;
+ queue->max = 0;
+ queue->name = name;
+ INIT_LIST_HEAD(&queue->list);
+ init_waitqueue_head(&queue->wait);
+}
+
+static void msm_enqueue(struct msm_device_queue *queue,
+ struct list_head *entry)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&queue->lock, flags);
+ queue->len++;
+ if (queue->len > queue->max) {
+ queue->max = queue->len;
+ pr_info("queue %s new max is %d\n", queue->name, queue->max);
+ }
+ list_add_tail(entry, &queue->list);
+ wake_up(&queue->wait);
+ CPP_DBG("woke up %s\n", queue->name);
+ spin_unlock_irqrestore(&queue->lock, flags);
+}
+
+static struct msm_cam_clk_info cpp_clk_info[] = {
+ {"camss_top_ahb_clk", -1},
+ {"vfe_clk_src", 266670000},
+ {"camss_vfe_vfe_clk", -1},
+ {"iface_clk", -1},
+ {"cpp_core_clk", 266670000},
+ {"cpp_iface_clk", -1},
+ {"cpp_bus_clk", -1},
+ {"micro_iface_clk", -1},
+};
+static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev);
+
+static void msm_cpp_write(u32 data, void __iomem *cpp_base)
+{
+ writel_relaxed((data), cpp_base + MSM_CPP_MICRO_FIFO_RX_DATA);
+}
+
+static uint32_t msm_cpp_read(void __iomem *cpp_base)
+{
+ uint32_t tmp, retry = 0;
+ do {
+ tmp = msm_camera_io_r(cpp_base + MSM_CPP_MICRO_FIFO_TX_STAT);
+ } while (((tmp & 0x2) == 0x0) && (retry++ < 10)) ;
+ if (retry < 10) {
+ tmp = msm_camera_io_r(cpp_base + MSM_CPP_MICRO_FIFO_TX_DATA);
+ CPP_DBG("Read data: 0%x\n", tmp);
+ } else {
+ CPP_DBG("Read failed\n");
+ tmp = 0xDEADBEEF;
+ }
+ return tmp;
+}
+
+static void msm_cpp_poll(void __iomem *cpp_base, u32 val)
+{
+ uint32_t tmp, retry = 0;
+ do {
+ usleep_range(1000, 2000);
+ tmp = msm_cpp_read(cpp_base);
+ if (tmp != 0xDEADBEEF)
+ CPP_DBG("poll: 0%x\n", tmp);
+ } while ((tmp != val) && (retry++ < MSM_CPP_POLL_RETRIES));
+ if (retry < MSM_CPP_POLL_RETRIES)
+ CPP_DBG("Poll finished\n");
+ else
+ pr_err("Poll failed: expect: 0x%x\n", val);
+}
+
+void cpp_release_ion_client(struct kref *ref)
+{
+ struct cpp_device *cpp_dev = container_of(ref,
+ struct cpp_device, refcount);
+ pr_err("Calling ion_client_destroy\n");
+ ion_client_destroy(cpp_dev->client);
+}
+
+static int cpp_init_mem(struct cpp_device *cpp_dev)
+{
+ int rc = 0;
+
+ kref_init(&cpp_dev->refcount);
+ kref_get(&cpp_dev->refcount);
+ cpp_dev->client = msm_ion_client_create(-1, "cpp");
+
+ CPP_DBG("E\n");
+ if (!cpp_dev->domain) {
+ pr_err("domain / iommu context not found\n");
+ return -ENODEV;
+ }
+
+ CPP_DBG("X\n");
+ return rc;
+}
+
+static void cpp_deinit_mem(struct cpp_device *cpp_dev)
+{
+ CPP_DBG("E\n");
+ kref_put(&cpp_dev->refcount, cpp_release_ion_client);
+ CPP_DBG("X\n");
+}
+
+static irqreturn_t msm_cpp_irq(int irq_num, void *data)
+{
+ uint32_t tx_level;
+ uint32_t irq_status;
+ uint32_t msg_id, cmd_len;
+ uint32_t i;
+ uint32_t tx_fifo[16];
+ struct cpp_device *cpp_dev = data;
+ irq_status = msm_camera_io_r(cpp_dev->base + MSM_CPP_MICRO_IRQGEN_STAT);
+ CPP_DBG("status: 0x%x\n", irq_status);
+ if (irq_status & 0x8) {
+ tx_level = msm_camera_io_r(cpp_dev->base +
+ MSM_CPP_MICRO_FIFO_TX_STAT) >> 2;
+ for (i = 0; i < tx_level; i++) {
+ tx_fifo[i] = msm_camera_io_r(cpp_dev->base +
+ MSM_CPP_MICRO_FIFO_TX_DATA);
+ }
+
+ for (i = 0; i < tx_level; i++) {
+ if (tx_fifo[i] == MSM_CPP_MSG_ID_CMD) {
+ cmd_len = tx_fifo[i+1];
+ msg_id = tx_fifo[i+2];
+ if (msg_id == MSM_CPP_MSG_ID_FRAME_ACK) {
+ CPP_DBG("Frame done!!\n");
+ msm_cpp_notify_frame_done(cpp_dev);
+ }
+ i += cmd_len + 2;
+ }
+ }
+ }
+ msm_camera_io_w(irq_status, cpp_dev->base + MSM_CPP_MICRO_IRQGEN_CLR);
+ return IRQ_HANDLED;
+}
+
+static int cpp_init_hardware(struct cpp_device *cpp_dev)
+{
+ int rc = 0;
+
+ if (cpp_dev->fs_cpp == NULL) {
+ cpp_dev->fs_cpp =
+ regulator_get(&cpp_dev->pdev->dev, "vdd");
+ if (IS_ERR(cpp_dev->fs_cpp)) {
+ pr_err("Regulator cpp vdd get failed %ld\n",
+ PTR_ERR(cpp_dev->fs_cpp));
+ cpp_dev->fs_cpp = NULL;
+ goto fs_failed;
+ } else if (regulator_enable(cpp_dev->fs_cpp)) {
+ pr_err("Regulator cpp vdd enable failed\n");
+ regulator_put(cpp_dev->fs_cpp);
+ cpp_dev->fs_cpp = NULL;
+ goto fs_failed;
+ }
+ }
+
+ rc = msm_cam_clk_enable(&cpp_dev->pdev->dev, cpp_clk_info,
+ cpp_dev->cpp_clk, ARRAY_SIZE(cpp_clk_info), 1);
+ if (rc < 0) {
+ pr_err("clk enable failed\n");
+ goto clk_failed;
+ }
+
+ cpp_dev->base = ioremap(cpp_dev->mem->start,
+ resource_size(cpp_dev->mem));
+ if (!cpp_dev->base) {
+ rc = -ENOMEM;
+ pr_err("ioremap failed\n");
+ goto remap_failed;
+ }
+
+ cpp_dev->vbif_base = ioremap(cpp_dev->vbif_mem->start,
+ resource_size(cpp_dev->vbif_mem));
+ if (!cpp_dev->vbif_base) {
+ rc = -ENOMEM;
+ pr_err("ioremap failed\n");
+ goto vbif_remap_failed;
+ }
+
+ if (cpp_dev->state != CPP_STATE_BOOT) {
+ rc = request_irq(cpp_dev->irq->start, msm_cpp_irq,
+ IRQF_TRIGGER_RISING, "cpp", cpp_dev);
+ if (rc < 0) {
+ pr_err("irq request fail\n");
+ rc = -EBUSY;
+ goto req_irq_fail;
+ }
+ }
+
+ msm_camera_io_w(0x1, cpp_dev->vbif_base + 0x4);
+
+ return rc;
+req_irq_fail:
+ iounmap(cpp_dev->vbif_base);
+vbif_remap_failed:
+ iounmap(cpp_dev->base);
+remap_failed:
+ msm_cam_clk_enable(&cpp_dev->pdev->dev, cpp_clk_info,
+ cpp_dev->cpp_clk, ARRAY_SIZE(cpp_clk_info), 0);
+clk_failed:
+ regulator_disable(cpp_dev->fs_cpp);
+ regulator_put(cpp_dev->fs_cpp);
+fs_failed:
+ return rc;
+}
+
+static void cpp_release_hardware(struct cpp_device *cpp_dev)
+{
+ if (cpp_dev->state != CPP_STATE_BOOT)
+ free_irq(cpp_dev->irq->start, cpp_dev);
+
+ iounmap(cpp_dev->base);
+ msm_cam_clk_enable(&cpp_dev->pdev->dev, cpp_clk_info,
+ cpp_dev->cpp_clk, ARRAY_SIZE(cpp_clk_info), 0);
+ if (0) {
+ regulator_disable(cpp_dev->fs_cpp);
+ regulator_put(cpp_dev->fs_cpp);
+ cpp_dev->fs_cpp = NULL;
+ }
+}
+
+static void cpp_load_fw(struct cpp_device *cpp_dev)
+{
+ uint32_t i;
+ uint32_t *ptr_bin = NULL;
+ int32_t rc = -EFAULT;
+ const struct firmware *fw = NULL;
+ char *fw_name_bin = "cpp_firmware_v1_1_1.fw";
+ struct device *dev = &cpp_dev->pdev->dev;
+
+ rc = request_firmware(&fw, fw_name_bin, dev);
+ if (rc) {
+ dev_err(dev, "Failed to locate blob %s from device %p, Error: %d\n",
+ fw_name_bin, dev, rc);
+ }
+
+ CPP_DBG("HW Ver:0x%x\n",
+ msm_camera_io_r(cpp_dev->base +
+ MSM_CPP_MICRO_HW_VERSION));
+
+ msm_camera_io_w(0x1, cpp_dev->base +
+ MSM_CPP_MICRO_BOOT_START);
+ /*Enable MC clock*/
+ msm_camera_io_w(0x1, cpp_dev->base +
+ MSM_CPP_MICRO_CLKEN_CTL);
+
+ msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_CMD);
+
+ /*Start firmware loading*/
+ msm_cpp_write(MSM_CPP_CMD_FW_LOAD, cpp_dev->base);
+ msm_cpp_write(MSM_CPP_END_ADDRESS, cpp_dev->base);
+ msm_cpp_write(MSM_CPP_START_ADDRESS, cpp_dev->base);
+ if (NULL != fw)
+ ptr_bin = (uint32_t *)fw->data;
+
+ for (i = 0; i < fw->size/4; i++) {
+ if (ptr_bin) {
+ msm_cpp_write(*ptr_bin, cpp_dev->base);
+ ptr_bin++;
+ }
+ }
+ if (fw)
+ release_firmware(fw);
+
+ msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_OK);
+ msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_CMD);
+
+ /*Trigger MC to jump to start address*/
+ msm_cpp_write(MSM_CPP_CMD_EXEC_JUMP, cpp_dev->base);
+ msm_cpp_write(MSM_CPP_JUMP_ADDRESS, cpp_dev->base);
+
+ msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_CMD);
+ msm_cpp_poll(cpp_dev->base, 0x1);
+ msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_JUMP_ACK);
+ msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_TRAILER);
+
+ /*Get Bootloader Version*/
+ msm_cpp_write(MSM_CPP_CMD_GET_BOOTLOADER_VER, cpp_dev->base);
+ pr_info("MC Bootloader Version: 0x%x\n",
+ msm_cpp_read(cpp_dev->base));
+
+ /*Get Firmware Version*/
+ msm_cpp_write(MSM_CPP_CMD_GET_FW_VER, cpp_dev->base);
+ msm_cpp_write(MSM_CPP_MSG_ID_CMD, cpp_dev->base);
+ msm_cpp_write(0x1, cpp_dev->base);
+ msm_cpp_write(MSM_CPP_CMD_GET_FW_VER, cpp_dev->base);
+ msm_cpp_write(MSM_CPP_MSG_ID_TRAILER, cpp_dev->base);
+
+ msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_CMD);
+ msm_cpp_poll(cpp_dev->base, 0x2);
+ msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_FW_VER);
+ pr_info("CPP FW Version: 0x%x\n", msm_cpp_read(cpp_dev->base));
+ msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_TRAILER);
+
+}
+
+static int cpp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+ uint32_t i;
+ struct cpp_device *cpp_dev = v4l2_get_subdevdata(sd);
+ CPP_DBG("E\n");
+
+ mutex_lock(&cpp_dev->mutex);
+ if (cpp_dev->cpp_open_cnt == MAX_ACTIVE_CPP_INSTANCE) {
+ pr_err("No free CPP instance\n");
+ mutex_unlock(&cpp_dev->mutex);
+ return -ENODEV;
+ }
+
+ for (i = 0; i < MAX_ACTIVE_CPP_INSTANCE; i++) {
+ if (cpp_dev->cpp_subscribe_list[i].active == 0) {
+ cpp_dev->cpp_subscribe_list[i].active = 1;
+ cpp_dev->cpp_subscribe_list[i].vfh = &fh->vfh;
+ break;
+ }
+ }
+ if (i == MAX_ACTIVE_CPP_INSTANCE) {
+ pr_err("No free instance\n");
+ mutex_unlock(&cpp_dev->mutex);
+ return -ENODEV;
+ }
+
+ CPP_DBG("open %d %p\n", i, &fh->vfh);
+ cpp_dev->cpp_open_cnt++;
+ if (cpp_dev->cpp_open_cnt == 1) {
+ cpp_init_hardware(cpp_dev);
+ cpp_init_mem(cpp_dev);
+ disable_irq(cpp_dev->irq->start);
+
+ cpp_load_fw(cpp_dev);
+
+ enable_irq(cpp_dev->irq->start);
+
+ msm_camera_io_w_mb(0x8, cpp_dev->base +
+ MSM_CPP_MICRO_IRQGEN_MASK);
+ msm_camera_io_w_mb(0xFFFF, cpp_dev->base +
+ MSM_CPP_MICRO_IRQGEN_CLR);
+ cpp_dev->state = CPP_STATE_IDLE;
+ }
+ mutex_unlock(&cpp_dev->mutex);
+ return 0;
+}
+
+static int cpp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+ uint32_t i;
+ struct cpp_device *cpp_dev = v4l2_get_subdevdata(sd);
+ mutex_lock(&cpp_dev->mutex);
+ for (i = 0; i < MAX_ACTIVE_CPP_INSTANCE; i++) {
+ if (cpp_dev->cpp_subscribe_list[i].vfh == &fh->vfh) {
+ cpp_dev->cpp_subscribe_list[i].active = 0;
+ cpp_dev->cpp_subscribe_list[i].vfh = NULL;
+ break;
+ }
+ }
+ if (i == MAX_ACTIVE_CPP_INSTANCE) {
+ pr_err("Invalid close\n");
+ mutex_unlock(&cpp_dev->mutex);
+ return -ENODEV;
+ }
+
+ CPP_DBG("close %d %p\n", i, &fh->vfh);
+ cpp_dev->cpp_open_cnt--;
+ if (cpp_dev->cpp_open_cnt == 0) {
+ msm_camera_io_w(0x0, cpp_dev->base + MSM_CPP_MICRO_CLKEN_CTL);
+ cpp_deinit_mem(cpp_dev);
+ cpp_release_hardware(cpp_dev);
+ cpp_dev->state = CPP_STATE_OFF;
+ }
+ mutex_unlock(&cpp_dev->mutex);
+ return 0;
+}
+
+static const struct v4l2_subdev_internal_ops msm_cpp_internal_ops = {
+ .open = cpp_open_node,
+ .close = cpp_close_node,
+};
+
+static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev)
+{
+ struct v4l2_event v4l2_evt;
+ struct msm_queue_cmd *frame_qcmd;
+ struct msm_queue_cmd *event_qcmd;
+ struct msm_cpp_frame_info_t *processed_frame;
+ struct msm_device_queue *queue = &cpp_dev->processing_q;
+
+ if (queue->len > 0) {
+ frame_qcmd = msm_dequeue(queue, list_frame);
+ processed_frame = frame_qcmd->command;
+ kfree(frame_qcmd);
+ event_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_ATOMIC);
+ if (!event_qcmd) {
+ pr_err("Insufficient memory. return");
+ return -ENOMEM;
+ }
+ atomic_set(&event_qcmd->on_heap, 1);
+ event_qcmd->command = processed_frame;
+ CPP_DBG("fid %d\n", processed_frame->frame_id);
+ msm_enqueue(&cpp_dev->eventData_q, &event_qcmd->list_eventdata);
+
+ v4l2_evt.id = processed_frame->inst_id;
+ v4l2_evt.type = V4L2_EVENT_CPP_FRAME_DONE;
+ v4l2_event_queue(cpp_dev->msm_sd.sd.devnode, &v4l2_evt);
+ }
+ return 0;
+}
+
+static int msm_cpp_send_frame_to_hardware(struct cpp_device *cpp_dev)
+{
+ uint32_t i;
+ struct msm_queue_cmd *frame_qcmd;
+ struct msm_cpp_frame_info_t *process_frame;
+ struct msm_device_queue *queue;
+
+ if (cpp_dev->processing_q.len < MAX_CPP_PROCESSING_FRAME) {
+ while (cpp_dev->processing_q.len < MAX_CPP_PROCESSING_FRAME) {
+ if (cpp_dev->realtime_q.len != 0) {
+ queue = &cpp_dev->realtime_q;
+ } else if (cpp_dev->offline_q.len != 0) {
+ queue = &cpp_dev->offline_q;
+ } else {
+ pr_debug("All frames queued\n");
+ break;
+ }
+ frame_qcmd = msm_dequeue(queue, list_frame);
+ process_frame = frame_qcmd->command;
+ msm_enqueue(&cpp_dev->processing_q,
+ &frame_qcmd->list_frame);
+ msm_cpp_write(0x6, cpp_dev->base);
+ for (i = 0; i < process_frame->msg_len; i++)
+ msm_cpp_write(process_frame->cpp_cmd_msg[i],
+ cpp_dev->base);
+ }
+ }
+ return 0;
+}
+
+static int msm_cpp_cfg(struct cpp_device *cpp_dev,
+ struct msm_camera_v4l2_ioctl_t *ioctl_ptr)
+{
+ int rc = 0;
+ struct msm_queue_cmd *frame_qcmd = NULL;
+ struct msm_cpp_frame_info_t *new_frame =
+ kzalloc(sizeof(struct msm_cpp_frame_info_t), GFP_KERNEL);
+ uint32_t *cpp_frame_msg;
+ struct ion_handle *src_ion_handle = NULL;
+ struct ion_handle *dest_ion_handle = NULL;
+ unsigned long len;
+ unsigned long in_phyaddr, out_phyaddr;
+ uint16_t num_stripes = 0;
+
+ int i = 0;
+ if (!new_frame) {
+ pr_err("Insufficient memory. return\n");
+ return -ENOMEM;
+ }
+
+ rc = (copy_from_user(new_frame, (void __user *)ioctl_ptr->ioctl_ptr,
+ sizeof(struct msm_cpp_frame_info_t)) ? -EFAULT : 0);
+ if (rc) {
+ ERR_COPY_FROM_USER();
+ rc = -EINVAL;
+ goto ERROR1;
+ }
+
+ cpp_frame_msg = kzalloc(sizeof(uint32_t)*new_frame->msg_len,
+ GFP_KERNEL);
+ if (!cpp_frame_msg) {
+ pr_err("Insufficient memory. return");
+ rc = -ENOMEM;
+ goto ERROR1;
+ }
+
+ rc = (copy_from_user(cpp_frame_msg,
+ (void __user *)new_frame->cpp_cmd_msg,
+ sizeof(uint32_t)*new_frame->msg_len) ? -EFAULT : 0);
+ if (rc) {
+ ERR_COPY_FROM_USER();
+ rc = -EINVAL;
+ goto ERROR2;
+ }
+
+ new_frame->cpp_cmd_msg = cpp_frame_msg;
+
+ CPP_DBG("CPP in_fd: %d out_fd: %d\n", new_frame->src_fd,
+ new_frame->dst_fd);
+
+ src_ion_handle = ion_import_dma_buf(cpp_dev->client,
+ new_frame->src_fd);
+ if (IS_ERR_OR_NULL(src_ion_handle)) {
+ pr_err("ION import failed\n");
+ rc = PTR_ERR(src_ion_handle);
+ goto ERROR2;
+ }
+ rc = ion_map_iommu(cpp_dev->client, src_ion_handle,
+ cpp_dev->domain_num, 0, SZ_4K, 0,
+ (unsigned long *)&in_phyaddr, &len, 0, 0);
+ if (rc < 0) {
+ pr_err("ION import failed\n");
+ rc = PTR_ERR(src_ion_handle);
+ goto ERROR3;
+ }
+
+ CPP_DBG("in phy addr: 0x%x len: %ld\n", (uint32_t) in_phyaddr, len);
+
+ dest_ion_handle = ion_import_dma_buf(cpp_dev->client,
+ new_frame->dst_fd);
+ if (IS_ERR_OR_NULL(dest_ion_handle)) {
+ pr_err("ION import failed\n");
+ rc = PTR_ERR(dest_ion_handle);
+ goto ERROR4;
+ }
+ rc = ion_map_iommu(cpp_dev->client, dest_ion_handle,
+ cpp_dev->domain_num, 0, SZ_4K, 0,
+ (unsigned long *)&out_phyaddr, &len, 0, 0);
+ if (rc < 0) {
+ rc = PTR_ERR(dest_ion_handle);
+ goto ERROR5;
+ }
+
+ CPP_DBG("out phy addr: 0x%x len: %ld\n", (uint32_t)out_phyaddr, len);
+
+ num_stripes = ((cpp_frame_msg[12] >> 20) & 0x3FF) +
+ ((cpp_frame_msg[12] >> 10) & 0x3FF) +
+ (cpp_frame_msg[12] & 0x3FF);
+
+ for (i = 0; i < num_stripes; i++) {
+ cpp_frame_msg[133 + i * 27] += (uint32_t) in_phyaddr;
+ cpp_frame_msg[139 + i * 27] += (uint32_t) out_phyaddr;
+ cpp_frame_msg[140 + i * 27] += (uint32_t) out_phyaddr;
+ cpp_frame_msg[141 + i * 27] += (uint32_t) out_phyaddr;
+ cpp_frame_msg[142 + i * 27] += (uint32_t) out_phyaddr;
+ }
+
+ frame_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
+ if (!frame_qcmd) {
+ pr_err("Insufficient memory. return\n");
+ rc = -ENOMEM;
+ goto ERROR6;
+ }
+
+ atomic_set(&frame_qcmd->on_heap, 1);
+ frame_qcmd->command = new_frame;
+ if (new_frame->frame_type == MSM_CPP_REALTIME_FRAME) {
+ msm_enqueue(&cpp_dev->realtime_q,
+ &frame_qcmd->list_frame);
+ } else if (new_frame->frame_type == MSM_CPP_OFFLINE_FRAME) {
+ msm_enqueue(&cpp_dev->offline_q,
+ &frame_qcmd->list_frame);
+ } else {
+ pr_err("Invalid frame type\n");
+ rc = -EINVAL;
+ goto ERROR7;
+ }
+ msm_cpp_send_frame_to_hardware(cpp_dev);
+ return rc;
+ERROR7:
+ kfree(frame_qcmd);
+ERROR6:
+ ion_unmap_iommu(cpp_dev->client, dest_ion_handle,
+ cpp_dev->domain_num, 0);
+ERROR5:
+ ion_free(cpp_dev->client, dest_ion_handle);
+ERROR4:
+ ion_unmap_iommu(cpp_dev->client, src_ion_handle,
+ cpp_dev->domain_num, 0);
+ERROR3:
+ ion_free(cpp_dev->client, src_ion_handle);
+ERROR2:
+ kfree(cpp_frame_msg);
+ERROR1:
+ kfree(new_frame);
+ return rc;
+
+}
+
+long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd,
+ unsigned int cmd, void *arg)
+{
+ struct cpp_device *cpp_dev = v4l2_get_subdevdata(sd);
+ struct msm_camera_v4l2_ioctl_t *ioctl_ptr = arg;
+ int rc = 0;
+
+ mutex_lock(&cpp_dev->mutex);
+ CPP_DBG("E cmd: %d\n", cmd);
+ switch (cmd) {
+ case VIDIOC_MSM_CPP_CFG:
+ rc = msm_cpp_cfg(cpp_dev, ioctl_ptr);
+ break;
+ case VIDIOC_MSM_CPP_GET_EVENTPAYLOAD: {
+ struct msm_device_queue *queue = &cpp_dev->eventData_q;
+ struct msm_queue_cmd *event_qcmd;
+ struct msm_cpp_frame_info_t *process_frame;
+ event_qcmd = msm_dequeue(queue, list_eventdata);
+ process_frame = event_qcmd->command;
+ CPP_DBG("fid %d\n", process_frame->frame_id);
+ if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
+ process_frame,
+ sizeof(struct msm_cpp_frame_info_t))) {
+ mutex_unlock(&cpp_dev->mutex);
+ return -EINVAL;
+ }
+ kfree(process_frame->cpp_cmd_msg);
+ kfree(process_frame);
+ kfree(event_qcmd);
+ break;
+ }
+ }
+ mutex_unlock(&cpp_dev->mutex);
+ CPP_DBG("X\n");
+ return 0;
+}
+
+int msm_cpp_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
+ struct v4l2_event_subscription *sub)
+{
+ CPP_DBG("Called\n");
+ return v4l2_event_subscribe(fh, sub, MAX_CPP_V4l2_EVENTS);
+}
+
+int msm_cpp_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
+ struct v4l2_event_subscription *sub)
+{
+ CPP_DBG("Called\n");
+ return v4l2_event_unsubscribe(fh, sub);
+}
+
+static struct v4l2_subdev_core_ops msm_cpp_subdev_core_ops = {
+ .ioctl = msm_cpp_subdev_ioctl,
+ .subscribe_event = msm_cpp_subscribe_event,
+ .unsubscribe_event = msm_cpp_unsubscribe_event,
+};
+
+static const struct v4l2_subdev_ops msm_cpp_subdev_ops = {
+ .core = &msm_cpp_subdev_core_ops,
+};
+
+static int msm_cpp_enable_debugfs(struct cpp_device *cpp_dev);
+
+static struct v4l2_file_operations msm_cpp_v4l2_subdev_fops;
+
+static long msm_cpp_subdev_do_ioctl(
+ struct file *file, unsigned int cmd, void *arg)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
+ struct v4l2_fh *vfh = file->private_data;
+
+ switch (cmd) {
+ case VIDIOC_DQEVENT:
+ if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS))
+ return -ENOIOCTLCMD;
+
+ return v4l2_event_dequeue(vfh, arg, file->f_flags & O_NONBLOCK);
+
+ case VIDIOC_SUBSCRIBE_EVENT:
+ return v4l2_subdev_call(sd, core, subscribe_event, vfh, arg);
+
+ case VIDIOC_UNSUBSCRIBE_EVENT:
+ return v4l2_subdev_call(sd, core, unsubscribe_event, vfh, arg);
+
+ case VIDIOC_MSM_CPP_GET_INST_INFO: {
+ uint32_t i;
+ struct cpp_device *cpp_dev = v4l2_get_subdevdata(sd);
+ struct msm_camera_v4l2_ioctl_t *ioctl_ptr = arg;
+ struct msm_cpp_frame_info_t inst_info;
+ for (i = 0; i < MAX_ACTIVE_CPP_INSTANCE; i++) {
+ if (cpp_dev->cpp_subscribe_list[i].vfh == vfh) {
+ inst_info.inst_id = i;
+ break;
+ }
+ }
+ if (copy_to_user(
+ (void __user *)ioctl_ptr->ioctl_ptr, &inst_info,
+ sizeof(struct msm_cpp_frame_info_t))) {
+ return -EINVAL;
+ }
+ }
+ break;
+ default:
+ return v4l2_subdev_call(sd, core, ioctl, cmd, arg);
+ }
+
+ return 0;
+}
+
+static long msm_cpp_subdev_fops_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ return video_usercopy(file, cmd, arg, msm_cpp_subdev_do_ioctl);
+}
+
+static int cpp_register_domain(void)
+{
+ struct msm_iova_partition cpp_fw_partition = {
+ .start = SZ_128K,
+ .size = SZ_2G - SZ_128K,
+ };
+ struct msm_iova_layout cpp_fw_layout = {
+ .partitions = &cpp_fw_partition,
+ .npartitions = 1,
+ .client_name = "camera_cpp",
+ .domain_flags = 0,
+ };
+
+ return msm_register_domain(&cpp_fw_layout);
+}
+
+static int __devinit cpp_probe(struct platform_device *pdev)
+{
+ struct cpp_device *cpp_dev;
+ int rc = 0;
+
+ cpp_dev = kzalloc(sizeof(struct cpp_device), GFP_KERNEL);
+ if (!cpp_dev) {
+ pr_err("no enough memory\n");
+ return -ENOMEM;
+ }
+
+ cpp_dev->cpp_clk = kzalloc(sizeof(struct clk *) *
+ ARRAY_SIZE(cpp_clk_info), GFP_KERNEL);
+ if (!cpp_dev->cpp_clk) {
+ pr_err("no enough memory\n");
+ rc = -ENOMEM;
+ goto ERROR1;
+ }
+
+ v4l2_subdev_init(&cpp_dev->msm_sd.sd, &msm_cpp_subdev_ops);
+ cpp_dev->msm_sd.sd.internal_ops = &msm_cpp_internal_ops;
+ snprintf(cpp_dev->msm_sd.sd.name, ARRAY_SIZE(cpp_dev->msm_sd.sd.name),
+ "cpp");
+ cpp_dev->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ cpp_dev->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_EVENTS;
+ v4l2_set_subdevdata(&cpp_dev->msm_sd.sd, cpp_dev);
+ platform_set_drvdata(pdev, &cpp_dev->msm_sd.sd);
+ mutex_init(&cpp_dev->mutex);
+
+ if (pdev->dev.of_node)
+ of_property_read_u32((&pdev->dev)->of_node,
+ "cell-index", &pdev->id);
+
+ cpp_dev->pdev = pdev;
+
+ cpp_dev->mem = platform_get_resource_byname(pdev,
+ IORESOURCE_MEM, "cpp");
+ if (!cpp_dev->mem) {
+ pr_err("no mem resource?\n");
+ rc = -ENODEV;
+ goto ERROR2;
+ }
+
+ cpp_dev->vbif_mem = platform_get_resource_byname(pdev,
+ IORESOURCE_MEM, "cpp_vbif");
+ if (!cpp_dev->vbif_mem) {
+ pr_err("no mem resource?\n");
+ rc = -ENODEV;
+ goto ERROR2;
+ }
+
+ cpp_dev->irq = platform_get_resource_byname(pdev,
+ IORESOURCE_IRQ, "cpp");
+ if (!cpp_dev->irq) {
+ pr_err("%s: no irq resource?\n", __func__);
+ rc = -ENODEV;
+ goto ERROR2;
+ }
+
+ cpp_dev->io = request_mem_region(cpp_dev->mem->start,
+ resource_size(cpp_dev->mem), pdev->name);
+ if (!cpp_dev->io) {
+ pr_err("%s: no valid mem region\n", __func__);
+ rc = -EBUSY;
+ goto ERROR2;
+ }
+
+ cpp_dev->domain_num = cpp_register_domain();
+ if (cpp_dev->domain_num < 0) {
+ pr_err("%s: could not register domain\n", __func__);
+ rc = -ENODEV;
+ goto ERROR3;
+ }
+
+ cpp_dev->domain =
+ msm_get_iommu_domain(cpp_dev->domain_num);
+ if (!cpp_dev->domain) {
+ pr_err("%s: cannot find domain\n", __func__);
+ rc = -ENODEV;
+ goto ERROR3;
+ }
+
+ cpp_dev->iommu_ctx = msm_iommu_get_ctx("cpp");
+ if (!cpp_dev->iommu_ctx) {
+ pr_err("%s: cannot get iommu_ctx\n", __func__);
+ rc = -ENODEV;
+ goto ERROR3;
+ }
+
+ media_entity_init(&cpp_dev->msm_sd.sd.entity, 0, NULL, 0);
+ cpp_dev->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+ cpp_dev->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_CPP;
+ cpp_dev->msm_sd.sd.entity.name = pdev->name;
+ msm_sd_register(&cpp_dev->msm_sd);
+ msm_cpp_v4l2_subdev_fops.owner = v4l2_subdev_fops.owner;
+ msm_cpp_v4l2_subdev_fops.open = v4l2_subdev_fops.open;
+ msm_cpp_v4l2_subdev_fops.unlocked_ioctl = msm_cpp_subdev_fops_ioctl;
+ msm_cpp_v4l2_subdev_fops.release = v4l2_subdev_fops.release;
+ msm_cpp_v4l2_subdev_fops.poll = v4l2_subdev_fops.poll;
+
+ cpp_dev->msm_sd.sd.devnode->fops = &msm_cpp_v4l2_subdev_fops;
+ cpp_dev->msm_sd.sd.entity.revision = cpp_dev->msm_sd.sd.devnode->num;
+ cpp_dev->state = CPP_STATE_BOOT;
+ cpp_init_hardware(cpp_dev);
+ iommu_attach_device(cpp_dev->domain, cpp_dev->iommu_ctx);
+
+ msm_camera_io_w(0x0, cpp_dev->base +
+ MSM_CPP_MICRO_IRQGEN_MASK);
+ msm_camera_io_w(0xFFFF, cpp_dev->base +
+ MSM_CPP_MICRO_IRQGEN_CLR);
+
+ cpp_release_hardware(cpp_dev);
+ cpp_dev->state = CPP_STATE_OFF;
+
+ msm_cpp_enable_debugfs(cpp_dev);
+ msm_queue_init(&cpp_dev->eventData_q, "eventdata");
+ msm_queue_init(&cpp_dev->offline_q, "frame");
+ msm_queue_init(&cpp_dev->realtime_q, "frame");
+ msm_queue_init(&cpp_dev->processing_q, "frame");
+ cpp_dev->cpp_open_cnt = 0;
+
+ return rc;
+
+ERROR3:
+ release_mem_region(cpp_dev->mem->start, resource_size(cpp_dev->mem));
+ERROR2:
+ kfree(cpp_dev->cpp_clk);
+ERROR1:
+ kfree(cpp_dev);
+ return rc;
+}
+
+static const struct of_device_id msm_cpp_dt_match[] = {
+ {.compatible = "qcom,cpp"},
+ {}
+};
+
+static int cpp_device_remove(struct platform_device *dev)
+{
+ struct v4l2_subdev *sd = platform_get_drvdata(dev);
+ struct cpp_device *cpp_dev;
+ if (!sd) {
+ pr_err("%s: Subdevice is NULL\n", __func__);
+ return 0;
+ }
+
+ cpp_dev = (struct cpp_device *)v4l2_get_subdevdata(sd);
+ if (!cpp_dev) {
+ pr_err("%s: cpp device is NULL\n", __func__);
+ return 0;
+ }
+
+ iommu_detach_device(cpp_dev->domain, cpp_dev->iommu_ctx);
+ msm_sd_unregister(&cpp_dev->msm_sd);
+ release_mem_region(cpp_dev->mem->start, resource_size(cpp_dev->mem));
+ mutex_destroy(&cpp_dev->mutex);
+ kfree(cpp_dev->cpp_clk);
+ kfree(cpp_dev);
+ return 0;
+}
+
+static struct platform_driver cpp_driver = {
+ .probe = cpp_probe,
+ .remove = cpp_device_remove,
+ .driver = {
+ .name = MSM_CPP_DRV_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = msm_cpp_dt_match,
+ },
+};
+
+static int __init msm_cpp_init_module(void)
+{
+ return platform_driver_register(&cpp_driver);
+}
+
+static void __exit msm_cpp_exit_module(void)
+{
+ platform_driver_unregister(&cpp_driver);
+}
+
+static int msm_cpp_debugfs_stream_s(void *data, u64 val)
+{
+ struct cpp_device *cpp_dev = data;
+ CPP_DBG("CPP processing frame E\n");
+ while (1) {
+ mutex_lock(&cpp_dev->mutex);
+ msm_cpp_notify_frame_done(cpp_dev);
+ msm_cpp_send_frame_to_hardware(cpp_dev);
+ mutex_unlock(&cpp_dev->mutex);
+ msleep(20);
+ }
+ CPP_DBG("CPP processing frame X\n");
+ return 0;
+}
+
+static int msm_cpp_debugfs_load_fw(void *data, u64 val)
+{
+ const struct firmware *fw = NULL;
+ struct cpp_device *cpp_dev = data;
+ int rc = 0;
+ CPP_DBG("%s\n", __func__);
+ rc = request_firmware(&fw, "FIRMWARE.bin", &cpp_dev->pdev->dev);
+ if (rc) {
+ pr_err("request_fw failed\n");
+ } else {
+ CPP_DBG("request ok\n");
+ release_firmware(fw);
+ }
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(cpp_debugfs_stream, NULL,
+ msm_cpp_debugfs_stream_s, "%llu\n");
+DEFINE_SIMPLE_ATTRIBUTE(cpp_debugfs_fw, NULL,
+ msm_cpp_debugfs_load_fw, "%llu\n");
+
+static int msm_cpp_enable_debugfs(struct cpp_device *cpp_dev)
+{
+ struct dentry *debugfs_base, *debugfs_test;
+ debugfs_base = debugfs_create_dir("msm_camera", NULL);
+ if (!debugfs_base)
+ return -ENOMEM;
+
+ debugfs_test = debugfs_create_file("test", S_IRUGO | S_IWUSR,
+ debugfs_base, (void *)cpp_dev, &cpp_debugfs_stream);
+ if (!debugfs_test) {
+ debugfs_remove(debugfs_base);
+ return -ENOMEM;
+ }
+
+ if (!debugfs_create_file("fw", S_IRUGO | S_IWUSR, debugfs_base,
+ (void *)cpp_dev, &cpp_debugfs_fw)) {
+ debugfs_remove(debugfs_test);
+ debugfs_remove(debugfs_base);
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+module_init(msm_cpp_init_module);
+module_exit(msm_cpp_exit_module);
+MODULE_DESCRIPTION("MSM CPP driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.h b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.h
new file mode 100644
index 0000000..8deff72
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.h
@@ -0,0 +1,155 @@
+/* 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 __MSM_CPP_H__
+#define __MSM_CPP_H__
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/list.h>
+#include <linux/platform_device.h>
+#include <media/v4l2-subdev.h>
+#include "msm_sd.h"
+
+#define MAX_ACTIVE_CPP_INSTANCE 8
+#define MAX_CPP_PROCESSING_FRAME 2
+#define MAX_CPP_V4l2_EVENTS 30
+
+#define MSM_CPP_MICRO_BASE 0x4000
+#define MSM_CPP_MICRO_HW_VERSION 0x0000
+#define MSM_CPP_MICRO_IRQGEN_STAT 0x0004
+#define MSM_CPP_MICRO_IRQGEN_CLR 0x0008
+#define MSM_CPP_MICRO_IRQGEN_MASK 0x000C
+#define MSM_CPP_MICRO_FIFO_TX_DATA 0x0010
+#define MSM_CPP_MICRO_FIFO_TX_STAT 0x0014
+#define MSM_CPP_MICRO_FIFO_RX_DATA 0x0018
+#define MSM_CPP_MICRO_FIFO_RX_STAT 0x001C
+#define MSM_CPP_MICRO_BOOT_START 0x0020
+#define MSM_CPP_MICRO_BOOT_LDORG 0x0024
+#define MSM_CPP_MICRO_CLKEN_CTL 0x0030
+
+#define MSM_CPP_CMD_GET_BOOTLOADER_VER 0x1
+#define MSM_CPP_CMD_FW_LOAD 0x2
+#define MSM_CPP_CMD_EXEC_JUMP 0x3
+#define MSM_CPP_CMD_RESET_HW 0x5
+#define MSM_CPP_CMD_PROCESS_FRAME 0x6
+#define MSM_CPP_CMD_FLUSH_STREAM 0x7
+#define MSM_CPP_CMD_CFG_MEM_PARAM 0x8
+#define MSM_CPP_CMD_ERROR_REQUEST 0x9
+#define MSM_CPP_CMD_GET_STATUS 0xA
+#define MSM_CPP_CMD_GET_FW_VER 0xB
+
+#define MSM_CPP_MSG_ID_CMD 0x3E646D63
+#define MSM_CPP_MSG_ID_OK 0x0A0A4B4F
+#define MSM_CPP_MSG_ID_TRAILER 0xABCDEFAA
+
+#define MSM_CPP_MSG_ID_JUMP_ACK 0x00000001
+#define MSM_CPP_MSG_ID_FRAME_ACK 0x00000002
+#define MSM_CPP_MSG_ID_FRAME_NACK 0x00000003
+#define MSM_CPP_MSG_ID_FLUSH_ACK 0x00000004
+#define MSM_CPP_MSG_ID_FLUSH_NACK 0x00000005
+#define MSM_CPP_MSG_ID_CFG_MEM_ACK 0x00000006
+#define MSM_CPP_MSG_ID_CFG_MEM_INV 0x00000007
+#define MSM_CPP_MSG_ID_ERROR_STATUS 0x00000008
+#define MSM_CPP_MSG_ID_INVALID_CMD 0x00000009
+#define MSM_CPP_MSG_ID_GEN_STATUS 0x0000000A
+#define MSM_CPP_MSG_ID_FLUSHED 0x0000000B
+#define MSM_CPP_MSG_ID_FW_VER 0x0000000C
+
+#define MSM_CPP_JUMP_ADDRESS 0x20
+#define MSM_CPP_START_ADDRESS 0x0
+#define MSM_CPP_END_ADDRESS 0x3F00
+
+#define MSM_CPP_POLL_RETRIES 20
+
+struct cpp_subscribe_info {
+ struct v4l2_fh *vfh;
+ uint32_t active;
+};
+
+enum cpp_state {
+ CPP_STATE_BOOT,
+ CPP_STATE_IDLE,
+ CPP_STATE_ACTIVE,
+ CPP_STATE_OFF,
+};
+
+enum msm_queue {
+ MSM_CAM_Q_CTRL, /* control command or control command status */
+ MSM_CAM_Q_VFE_EVT, /* adsp event */
+ MSM_CAM_Q_VFE_MSG, /* adsp message */
+ MSM_CAM_Q_V4L2_REQ, /* v4l2 request */
+ MSM_CAM_Q_VPE_MSG, /* vpe message */
+ MSM_CAM_Q_PP_MSG, /* pp message */
+};
+
+struct msm_queue_cmd {
+ struct list_head list_config;
+ struct list_head list_control;
+ struct list_head list_frame;
+ struct list_head list_pict;
+ struct list_head list_vpe_frame;
+ struct list_head list_eventdata;
+ enum msm_queue type;
+ void *command;
+ atomic_t on_heap;
+ struct timespec ts;
+ uint32_t error_code;
+ uint32_t trans_code;
+};
+
+struct msm_device_queue {
+ struct list_head list;
+ spinlock_t lock;
+ wait_queue_head_t wait;
+ int max;
+ int len;
+ const char *name;
+};
+
+struct cpp_device {
+ struct platform_device *pdev;
+ struct msm_sd_subdev msm_sd;
+ struct v4l2_subdev subdev;
+ struct resource *mem;
+ struct resource *irq;
+ struct resource *io;
+ struct resource *vbif_mem;
+ struct resource *vbif_io;
+ void __iomem *vbif_base;
+ void __iomem *base;
+ struct clk **cpp_clk;
+ struct regulator *fs_cpp;
+ struct mutex mutex;
+ enum cpp_state state;
+
+ int domain_num;
+ struct iommu_domain *domain;
+ struct device *iommu_ctx;
+ struct ion_client *client;
+ struct kref refcount;
+
+ struct cpp_subscribe_info cpp_subscribe_list[MAX_ACTIVE_CPP_INSTANCE];
+ uint32_t cpp_open_cnt;
+
+ struct msm_device_queue eventData_q; /* V4L2 Event Payload Queue */
+
+ /* Offline Frame Queue process when realtime queue is empty */
+ struct msm_device_queue offline_q;
+ /* Realtime Frame Queue process with highest priority */
+ struct msm_device_queue realtime_q;
+ /* Processing Queue
+ * store frame info for frames sent to microcontroller
+ */
+ struct msm_device_queue processing_q;
+};
+#endif /* __MSM_CPP_H__ */
diff --git a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c
index 2c9a0b8..4701f69 100644
--- a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c
+++ b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c
@@ -3455,11 +3455,15 @@
struct sdmx_buff_descr data_buff_desc[DMX_MAX_DECODER_BUFFER_NUM];
u32 data_buf_num = DMX_MAX_DECODER_BUFFER_NUM;
enum sdmx_buf_mode buf_mode;
+ enum sdmx_raw_out_format ts_out_format = SDMX_188_OUTPUT;
+ u32 filter_flags = 0;
feed = dvbdmx_feed->priv;
if (mpq_dmx_is_sec_feed(dvbdmx_feed)) {
feed->filter_type = SDMX_SECTION_FILTER;
+ if (dvbdmx_feed->feed.sec.check_crc)
+ filter_flags |= SDMX_FILTER_FLAG_VERIFY_SECTION_CRC;
MPQ_DVB_DBG_PRINT("%s: SDMX_SECTION_FILTER\n", __func__);
} else if (mpq_dmx_is_pcr_feed(dvbdmx_feed)) {
feed->filter_type = SDMX_PCR_FILTER;
@@ -3469,6 +3473,22 @@
MPQ_DVB_DBG_PRINT("%s: SDMX_SEPARATED_PES_FILTER\n", __func__);
} else if (mpq_dmx_is_rec_feed(dvbdmx_feed)) {
feed->filter_type = SDMX_RAW_FILTER;
+ switch (dvbdmx_feed->tsp_out_format) {
+ case (DMX_TSP_FORMAT_188):
+ ts_out_format = SDMX_188_OUTPUT;
+ break;
+ case (DMX_TSP_FORMAT_192_HEAD):
+ ts_out_format = SDMX_192_HEAD_OUTPUT;
+ break;
+ case (DMX_TSP_FORMAT_192_TAIL):
+ ts_out_format = SDMX_192_TAIL_OUTPUT;
+ break;
+ default:
+ MPQ_DVB_ERR_PRINT(
+ "%s: Unsupported TS output format %d\n",
+ __func__, dvbdmx_feed->tsp_out_format);
+ return -EINVAL;
+ }
MPQ_DVB_DBG_PRINT("%s: SDMX_RAW_FILTER\n", __func__);
} else {
feed->filter_type = SDMX_PES_FILTER;
@@ -3498,8 +3518,9 @@
feed->secondary_feed = 0;
MPQ_DVB_DBG_PRINT(
- "%s: Adding new sdmx filter, pid %d\n",
- __func__, dvbdmx_feed->pid);
+ "%s: Adding new sdmx filter, pid %d, flags=0x%X, ts_out_format=%d\n",
+ __func__, dvbdmx_feed->pid, filter_flags,
+ ts_out_format);
/* Meta-data initialization,
* Recording filters do no need meta-data buffers.
@@ -3534,7 +3555,9 @@
buf_mode,
data_buf_num,
data_buff_desc,
- &feed->sdmx_filter_handle);
+ &feed->sdmx_filter_handle,
+ ts_out_format,
+ filter_flags);
if (ret) {
MPQ_DVB_ERR_PRINT(
"%s: SDMX_add_filter failed. ret = %d\n",
@@ -3869,6 +3892,7 @@
{
int ret;
struct sdmx_metadata_header header;
+ struct sdmx_pes_counters counters;
struct dmx_data_ready data_event;
struct dmx_data_ready pes_event;
struct dvb_demux_feed *feed = mpq_feed->dvb_demux_feed;
@@ -3906,22 +3930,26 @@
while (sts->metadata_fill_count) {
if (dvb_ringbuffer_avail(&mpq_feed->metadata_buf) <
- sizeof(header)) {
+ (sizeof(header) + sizeof(counters))) {
MPQ_DVB_ERR_PRINT(
"%s: metadata_fill_count is %d but actual buffer has less than %d bytes\n",
__func__,
sts->metadata_fill_count,
- sizeof(header));
+ sizeof(header) + sizeof(counters));
break;
}
- dvb_ringbuffer_read(&mpq_feed->metadata_buf, (u8 *) &header,
+ dvb_ringbuffer_read(&mpq_feed->metadata_buf, (u8 *)&header,
sizeof(header));
MPQ_DVB_DBG_PRINT(
"%s: metadata header: start=%u, length=%u\n",
__func__, header.payload_start, header.payload_length);
sts->metadata_fill_count -= sizeof(header);
+ dvb_ringbuffer_read(&mpq_feed->metadata_buf, (u8 *)&counters,
+ sizeof(counters));
+ sts->metadata_fill_count -= sizeof(counters);
+
/* Notify new data in buffer */
data_event.status = DMX_OK;
data_event.data_length = header.payload_length;
@@ -3947,11 +3975,13 @@
pes_event.pes_end.pes_length_mismatch = 1;
if (sts->error_indicators & SDMX_FILTER_ERR_CONT_CNT_INVALID)
pes_event.pes_end.disc_indicator_set = 0;
- /* TODO: report these when SDMX returns them */
+
pes_event.pes_end.stc = 0;
- pes_event.pes_end.tei_counter = 0;
- pes_event.pes_end.cont_err_counter = 0;
- pes_event.pes_end.ts_packets_num = 0;
+ pes_event.pes_end.tei_counter = counters.transport_err_count;
+ pes_event.pes_end.cont_err_counter =
+ counters.continuity_err_count;
+ pes_event.pes_end.ts_packets_num =
+ counters.pes_ts_count;
ret = mpq_sdmx_check_ts_stall(mpq_demux, mpq_feed, sts, 0, 1);
if (ret) {
@@ -4024,6 +4054,7 @@
struct sdmx_filter_status *sts)
{
struct sdmx_metadata_header header;
+ struct sdmx_pes_counters counters;
int pes_header_offset;
struct ts_packet_header *ts_header;
struct ts_adaptation_field *ts_adapt;
@@ -4060,7 +4091,7 @@
struct mpq_adapter_video_meta_data meta_data;
pes_cnt++;
- /* Read header & metadata */
+ /* Read metadata header */
dvb_ringbuffer_read(&mpq_feed->metadata_buf, (u8 *)&header,
sizeof(header));
sts->metadata_fill_count -= sizeof(header);
@@ -4069,17 +4100,23 @@
__func__, header.payload_start, header.payload_length,
header.metadata_length);
- /* Read actual metadata */
+ /* Read metadata - PES counters */
+ dvb_ringbuffer_read(&mpq_feed->metadata_buf, (u8 *)&counters,
+ sizeof(counters));
+ sts->metadata_fill_count -= sizeof(counters);
+
+ /* Read metadata - TS & PES headers */
if (header.metadata_length < MAX_SDMX_METADATA_LENGTH)
dvb_ringbuffer_read(&mpq_feed->metadata_buf,
metadata_buf,
- header.metadata_length);
+ header.metadata_length - sizeof(counters));
else
MPQ_DVB_ERR_PRINT(
"%s: meta-data size=%d is too big for meta-data buffer=%d\n",
__func__, header.metadata_length,
MAX_SDMX_METADATA_LENGTH);
- sts->metadata_fill_count -= header.metadata_length;
+ sts->metadata_fill_count -=
+ (header.metadata_length - sizeof(counters));
ts_header = (struct ts_packet_header *)&metadata_buf[0];
if (1 == ts_header->adaptation_field_control) {
@@ -4119,6 +4156,16 @@
}
spin_lock(&mpq_feed->video_info.video_buffer_lock);
+
+ mpq_feed->video_info.tei_errs =
+ counters.transport_err_count;
+ mpq_feed->video_info.continuity_errs =
+ counters.continuity_err_count;
+ mpq_feed->video_info.ts_packets_num =
+ counters.pes_ts_count;
+ mpq_feed->video_info.ts_dropped_bytes =
+ counters.drop_count * mpq_demux->demux.ts_packet_size;
+
sbuf = mpq_feed->video_info.video_buffer;
if (sbuf == NULL) {
MPQ_DVB_ERR_PRINT(
diff --git a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_tspp_v1.c b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_tspp_v1.c
index 49f87ba..632e864 100644
--- a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_tspp_v1.c
+++ b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_tspp_v1.c
@@ -1433,8 +1433,8 @@
if (*channel_ref_count == 0) {
/* channel is not used any more, release it */
tspp_unregister_notification(0, channel_id);
- tspp_close_channel(0, channel_id);
tspp_close_stream(0, channel_id);
+ tspp_close_channel(0, channel_id);
atomic_set(data_cnt, 0);
if (allocation_mode == MPQ_DMX_TSPP_CONTIGUOUS_PHYS_ALLOC)
diff --git a/drivers/media/platform/msm/dvb/demux/mpq_sdmx.c b/drivers/media/platform/msm/dvb/demux/mpq_sdmx.c
index 0f91930..946b055 100644
--- a/drivers/media/platform/msm/dvb/demux/mpq_sdmx.c
+++ b/drivers/media/platform/msm/dvb/demux/mpq_sdmx.c
@@ -110,6 +110,8 @@
enum sdmx_filter filter_type;
struct sdmx_buff_descr meta_data_buf;
enum sdmx_buf_mode buffer_mode;
+ enum sdmx_raw_out_format ts_out_format;
+ u32 flags;
u32 num_data_bufs;
struct sdmx_buff_descr data_bufs[];
};
@@ -453,6 +455,9 @@
* @num_data_bufs: number of data buffers (use 1 for a ring buffer)
* @data_bufs: data buffers descriptors array
* @filter_handle: returned filter handle
+ * @ts_out_format: output format for raw filters
+ * @flags: optional flags for filter
+ * (currently only clear section CRC verification is supported)
*
* Return error code
*/
@@ -463,7 +468,9 @@
enum sdmx_buf_mode d_buf_mode,
u32 num_data_bufs,
struct sdmx_buff_descr *data_bufs,
- int *filter_handle)
+ int *filter_handle,
+ enum sdmx_raw_out_format ts_out_format,
+ u32 flags)
{
int res, cmd_len, rsp_len;
struct sdmx_add_filt_req *cmd;
@@ -493,6 +500,8 @@
cmd->session_handle = session_handle;
cmd->pid = (u32)pid;
cmd->filter_type = filterype;
+ cmd->ts_out_format = ts_out_format;
+ cmd->flags = flags;
if (meta_data_buf != NULL)
memcpy(&(cmd->meta_data_buf), meta_data_buf,
sizeof(struct sdmx_buff_descr));
diff --git a/drivers/media/platform/msm/dvb/demux/mpq_sdmx.h b/drivers/media/platform/msm/dvb/demux/mpq_sdmx.h
index ffb9046..0bd04e8 100644
--- a/drivers/media/platform/msm/dvb/demux/mpq_sdmx.h
+++ b/drivers/media/platform/msm/dvb/demux/mpq_sdmx.h
@@ -27,24 +27,26 @@
#define SDMX_FILTER_ERR_INVALID_SCRAMBLE_BITS BIT(3)
#define SDMX_FILTER_ERR_KL_IND_NOT_SET BIT(4)
#define SDMX_FILTER_ERR_CAS_DECRYPT_ERROR BIT(5)
-#define SDMX_FILTER_ERR_SEC_VERIF_GENERAL_FAIL BIT(6)
-#define SDMX_FILTER_ERR_SEC_VERIF_CRC32_FAIL BIT(7)
-#define SDMX_FILTER_ERR_SEC_INTERNAL_MALLOC_FAIL BIT(8)
-#define SDMX_FILTER_ERR_SEC_LEN_INVALID BIT(9)
-#define SDMX_FILTER_ERR_SEC_PUSI_PTR_INVALID BIT(10)
-#define SDMX_FILTER_ERR_TS_SYNC_BYTE_INVALID BIT(11)
-#define SDMX_FILTER_ERR_TS_TRANSPORT_ERR BIT(12)
-#define SDMX_FILTER_ERR_CONT_CNT_INVALID BIT(13)
-#define SDMX_FILTER_ERR_CONT_CNT_DUPLICATE BIT(14)
-#define SDMX_FILTER_ERR_INVALID_PES_HDR BIT(15)
-#define SDMX_FILTER_ERR_INVALID_PES_LEN BIT(16)
-#define SDMX_FILTER_ERR_INVALID_PES_ENCRYPTION BIT(17)
-#define SDMX_FILTER_ERR_SECURITY_FAULT BIT(18)
-#define SDMX_FILTER_ERR_IN_NS_BUFFER BIT(19)
+#define SDMX_FILTER_ERR_SEC_VERIF_CRC32_FAIL BIT(6)
+#define SDMX_FILTER_ERR_SEC_INTERNAL_MALLOC_FAIL BIT(7)
+#define SDMX_FILTER_ERR_SEC_LEN_INVALID BIT(8)
+#define SDMX_FILTER_ERR_SEC_PUSI_PTR_INVALID BIT(9)
+#define SDMX_FILTER_ERR_TS_SYNC_BYTE_INVALID BIT(10)
+#define SDMX_FILTER_ERR_TS_TRANSPORT_ERR BIT(11)
+#define SDMX_FILTER_ERR_CONT_CNT_INVALID BIT(12)
+#define SDMX_FILTER_ERR_CONT_CNT_DUPLICATE BIT(13)
+#define SDMX_FILTER_ERR_INVALID_PES_HDR BIT(14)
+#define SDMX_FILTER_ERR_INVALID_PES_LEN BIT(15)
+#define SDMX_FILTER_ERR_INVALID_PES_ENCRYPTION BIT(16)
+#define SDMX_FILTER_ERR_SECURITY_FAULT BIT(17)
+#define SDMX_FILTER_ERR_IN_NS_BUFFER BIT(18)
/* Filter-level status indicators */
#define SDMX_FILTER_STATUS_EOS BIT(0)
+/* Filter-level flags */
+#define SDMX_FILTER_FLAG_VERIFY_SECTION_CRC BIT(0)
+
#define SDMX_INVALID_SESSION_HANDLE (-1)
#define SDMX_INVALID_FILTER_HANDLE (-1)
@@ -103,6 +105,12 @@
SDMX_RAW_FILTER, /* Recording */
};
+enum sdmx_raw_out_format {
+ SDMX_188_OUTPUT,
+ SDMX_192_HEAD_OUTPUT,
+ SDMX_192_TAIL_OUTPUT
+};
+
struct sdmx_session_dbg_counters {
/* Total number of TS-packets input to SDMX. */
u32 ts_pkt_in;
@@ -130,6 +138,20 @@
u32 ts_pkt_key_not_ready;
};
+struct sdmx_pes_counters {
+ /* Number of TS packets with the TEI flag set */
+ u32 transport_err_count;
+
+ /* Number of TS packets with continuity counter errors */
+ u32 continuity_err_count;
+
+ /* Number of TS packets composing this PES frame */
+ u32 pes_ts_count;
+
+ /* Number of TS packets dropped due to full buffer */
+ u32 drop_count;
+};
+
struct sdmx_buff_descr {
/* Physical address where buffer starts */
void *base_addr;
@@ -204,7 +226,7 @@
int sdmx_add_filter(int session_handle, u16 pid, enum sdmx_filter filter_type,
struct sdmx_buff_descr *meta_data_buf, enum sdmx_buf_mode data_buf_mode,
u32 num_data_bufs, struct sdmx_buff_descr *data_bufs,
- int *filter_handle);
+ int *filter_handle, enum sdmx_raw_out_format ts_out_format, u32 flags);
int sdmx_remove_filter(int session_handle, int filter_handle);
diff --git a/drivers/media/platform/msm/vidc/hfi_packetization.c b/drivers/media/platform/msm/vidc/hfi_packetization.c
index 44e23ed..1cabc3e 100644
--- a/drivers/media/platform/msm/vidc/hfi_packetization.c
+++ b/drivers/media/platform/msm/vidc/hfi_packetization.c
@@ -39,6 +39,24 @@
return rc;
}
+int create_pkt_cmd_sys_idle_indicator(
+ struct hfi_cmd_sys_set_property_packet *pkt,
+ u32 enable)
+{
+ struct hfi_enable *hfi;
+ if (!pkt)
+ return -EINVAL;
+
+ pkt->size = sizeof(struct hfi_cmd_sys_set_property_packet) +
+ sizeof(struct hfi_enable) + sizeof(u32);
+ pkt->packet_type = HFI_CMD_SYS_SET_PROPERTY;
+ pkt->num_properties = 1;
+ pkt->rg_property_data[0] = HFI_PROPERTY_SYS_IDLE_INDICATOR;
+ hfi = (struct hfi_enable *) &pkt->rg_property_data[1];
+ hfi->enable = enable;
+ return 0;
+}
+
int create_pkt_set_cmd_sys_resource(
struct hfi_cmd_sys_set_resource_packet *pkt,
struct vidc_resource_hdr *resource_hdr,
diff --git a/drivers/media/platform/msm/vidc/hfi_packetization.h b/drivers/media/platform/msm/vidc/hfi_packetization.h
index b2c6e08..8c61a40 100644
--- a/drivers/media/platform/msm/vidc/hfi_packetization.h
+++ b/drivers/media/platform/msm/vidc/hfi_packetization.h
@@ -22,6 +22,10 @@
u32 arch_type);
int create_pkt_cmd_sys_pc_prep(struct hfi_cmd_sys_pc_prep_packet *pkt);
+int create_pkt_cmd_sys_idle_indicator(
+ struct hfi_cmd_sys_set_property_packet *pkt,
+ u32 enable);
+
int create_pkt_set_cmd_sys_resource(
struct hfi_cmd_sys_set_resource_packet *pkt,
struct vidc_resource_hdr *resource_hdr,
diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c
index f6a9949..709eafc 100644
--- a/drivers/media/platform/msm/vidc/hfi_response_handler.c
+++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c
@@ -823,19 +823,21 @@
callback(SESSION_GET_SEQ_HDR_DONE, &data_done);
}
-void hfi_process_msg_packet(
+u32 hfi_process_msg_packet(
msm_vidc_callback callback, u32 device_id,
struct vidc_hal_msg_pkt_hdr *msg_hdr)
{
+ u32 rc = 0;
if (!callback || !msg_hdr || msg_hdr->size <
VIDC_IFACEQ_MIN_PKT_SIZE) {
dprintk(VIDC_ERR, "hal_process_msg_packet:bad"
"packet/packet size: %d", msg_hdr->size);
- return;
+ rc = -EINVAL;
+ return rc;
}
dprintk(VIDC_INFO, "Received: 0x%x in ", msg_hdr->packet);
-
+ rc = (u32) msg_hdr->packet;
switch (msg_hdr->packet) {
case HFI_MSG_EVENT_NOTIFY:
hfi_process_event_notify(callback, device_id,
@@ -846,6 +848,8 @@
(struct hfi_msg_sys_init_done_packet *)
msg_hdr);
break;
+ case HFI_MSG_SYS_IDLE:
+ break;
case HFI_MSG_SYS_SESSION_INIT_DONE:
hfi_process_session_init_done(callback, device_id,
(struct hfi_msg_sys_session_init_done_packet *)
@@ -915,4 +919,5 @@
dprintk(VIDC_ERR, "UNKNOWN_MSG_TYPE : %d", msg_hdr->packet);
break;
}
+ return rc;
}
diff --git a/drivers/media/platform/msm/vidc/msm_smem.c b/drivers/media/platform/msm/vidc/msm_smem.c
index 8e2aa30..125c699 100644
--- a/drivers/media/platform/msm/vidc/msm_smem.c
+++ b/drivers/media/platform/msm/vidc/msm_smem.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
@@ -26,7 +26,7 @@
unsigned long align, unsigned long *iova,
unsigned long *buffer_size, int flags)
{
- int rc;
+ int rc = 0;
if (!iova || !buffer_size || !hndl || !clnt) {
dprintk(VIDC_ERR, "Invalid params: %p, %p, %p, %p\n",
clnt, hndl, iova, buffer_size);
@@ -71,6 +71,7 @@
struct ion_handle *hndl;
unsigned long iova = 0;
unsigned long buffer_size = 0;
+ unsigned long ionflags = 0;
int rc = 0;
int align = SZ_4K;
hndl = ion_import_dma_buf(client->clnt, fd);
@@ -84,7 +85,20 @@
mem->domain = domain;
mem->partition_num = partition;
mem->flags = flags;
-
+ rc = ion_handle_get_flags(client->clnt, hndl, &ionflags);
+ if (rc) {
+ dprintk(VIDC_ERR, "Failed to get ion flags: %d\n", rc);
+ goto fail_map;
+ }
+ if (ION_IS_CACHED(ionflags)) {
+ mem->kvaddr = ion_map_kernel(client->clnt, hndl);
+ if (!mem->kvaddr) {
+ dprintk(VIDC_ERR,
+ "Failed to map shared mem in kernel\n");
+ rc = -EIO;
+ goto fail_map;
+ }
+ }
if (flags & SMEM_SECURE)
align = ALIGN(align, SZ_1M);
@@ -103,7 +117,9 @@
mem->device_addr, mem->size);
return rc;
fail_device_address:
- ion_unmap_kernel(client->clnt, hndl);
+ if (mem->kvaddr)
+ ion_unmap_kernel(client->clnt, hndl);
+fail_map:
ion_free(client->clnt, hndl);
fail_import_fd:
return rc;
@@ -243,31 +259,79 @@
return mem;
}
-static int ion_mem_clean_invalidate(struct smem_client *clt,
- struct msm_smem *mem)
+static int ion_cache_operations(struct smem_client *client,
+ struct msm_smem *mem, enum smem_cache_ops cache_op)
{
- /*
- * Note: We're always mapping into iommu as uncached
- * as a result we don't need to flush/clean anything
- */
- return 0;
+ unsigned long ionflag = 0;
+ int rc = 0;
+ int msm_cache_ops = 0;
+ if (!mem || !client) {
+ dprintk(VIDC_ERR, "Invalid params: %p, %p\n",
+ mem, client);
+ return -EINVAL;
+ }
+ rc = ion_handle_get_flags(client->clnt, mem->smem_priv,
+ &ionflag);
+ if (rc) {
+ dprintk(VIDC_ERR,
+ "ion_handle_get_flags failed: %d\n", rc);
+ goto cache_op_failed;
+ }
+ if (ION_IS_CACHED(ionflag)) {
+ switch (cache_op) {
+ case SMEM_CACHE_CLEAN:
+ msm_cache_ops = ION_IOC_CLEAN_CACHES;
+ break;
+ case SMEM_CACHE_INVALIDATE:
+ msm_cache_ops = ION_IOC_INV_CACHES;
+ break;
+ case SMEM_CACHE_CLEAN_INVALIDATE:
+ msm_cache_ops = ION_IOC_CLEAN_INV_CACHES;
+ break;
+ default:
+ dprintk(VIDC_ERR, "cache operation not supported\n");
+ rc = -EINVAL;
+ goto cache_op_failed;
+ }
+ if (mem->kvaddr) {
+ rc = msm_ion_do_cache_op(client->clnt,
+ (struct ion_handle *)mem->smem_priv,
+ (unsigned long *) mem->kvaddr,
+ (unsigned long)mem->size,
+ msm_cache_ops);
+ if (rc) {
+ dprintk(VIDC_ERR,
+ "cache operation failed %d\n", rc);
+ goto cache_op_failed;
+ }
+ } else {
+ dprintk(VIDC_WARN,
+ "cache operation failed as no kernel mapping\n");
+ }
+ }
+cache_op_failed:
+ return rc;
}
-int msm_smem_clean_invalidate(void *clt, struct msm_smem *mem)
+int msm_smem_cache_operations(void *clt, struct msm_smem *mem,
+ enum smem_cache_ops cache_op)
{
struct smem_client *client = clt;
- int rc;
- if (!client || !mem) {
- dprintk(VIDC_ERR, "Invalid client/handle passed\n");
+ int rc = 0;
+ if (!client) {
+ dprintk(VIDC_ERR, "Invalid params: %p\n",
+ client);
return -EINVAL;
}
switch (client->mem_type) {
case SMEM_ION:
- rc = ion_mem_clean_invalidate(client, mem);
+ rc = ion_cache_operations(client, mem, cache_op);
+ if (rc)
+ dprintk(VIDC_ERR,
+ "Failed cache operations: %d\n", rc);
break;
default:
dprintk(VIDC_ERR, "Mem type not supported\n");
- rc = -EINVAL;
break;
}
return rc;
diff --git a/drivers/media/platform/msm/vidc/msm_smem.h b/drivers/media/platform/msm/vidc/msm_smem.h
index 6e40bef..d1c8293 100644
--- a/drivers/media/platform/msm/vidc/msm_smem.h
+++ b/drivers/media/platform/msm/vidc/msm_smem.h
@@ -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
@@ -37,6 +37,13 @@
void *smem_priv;
};
+enum smem_cache_ops {
+ SMEM_CACHE_CLEAN,
+ SMEM_CACHE_INVALIDATE,
+ SMEM_CACHE_CLEAN_INVALIDATE,
+};
+
+
void *msm_smem_new_client(enum smem_type mtype);
struct msm_smem *msm_smem_alloc(void *clt, size_t size, u32 align, u32 flags,
int domain, int partition, int map_kernel);
@@ -44,5 +51,6 @@
void msm_smem_delete_client(void *clt);
struct msm_smem *msm_smem_user_to_kernel(void *clt, int fd, u32 offset, int
domain, int partition, int flags);
-int msm_smem_clean_invalidate(void *clt, struct msm_smem *mem);
+int msm_smem_cache_operations(void *clt, struct msm_smem *mem,
+ enum smem_cache_ops);
#endif
diff --git a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
index 47eccfa..54047eb 100644
--- a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
@@ -54,6 +54,50 @@
struct list_head registered_bufs;
};
+struct master_slave {
+ int masters_ocmem[2];
+ int masters_ddr[2];
+ int slaves_ocmem[2];
+ int slaves_ddr[2];
+};
+
+struct bus_pdata_config {
+ int *masters;
+ int *slaves;
+ char *name;
+};
+
+static struct master_slave bus_vectors_masters_slaves = {
+ .masters_ocmem = {MSM_BUS_MASTER_VIDEO_P0_OCMEM,
+ MSM_BUS_MASTER_VIDEO_P1_OCMEM},
+ .masters_ddr = {MSM_BUS_MASTER_VIDEO_P0, MSM_BUS_MASTER_VIDEO_P1},
+ .slaves_ocmem = {MSM_BUS_SLAVE_OCMEM, MSM_BUS_SLAVE_OCMEM},
+ .slaves_ddr = {MSM_BUS_SLAVE_EBI_CH0, MSM_BUS_SLAVE_EBI_CH0},
+};
+
+static struct bus_pdata_config bus_pdata_config_vector[] = {
+{
+ .masters = bus_vectors_masters_slaves.masters_ocmem,
+ .slaves = bus_vectors_masters_slaves.slaves_ocmem,
+ .name = "qcom,enc-ocmem-ab-ib",
+},
+{
+ .masters = bus_vectors_masters_slaves.masters_ocmem,
+ .slaves = bus_vectors_masters_slaves.slaves_ocmem,
+ .name = "qcom,dec-ocmem-ab-ib",
+},
+{
+ .masters = bus_vectors_masters_slaves.masters_ddr,
+ .slaves = bus_vectors_masters_slaves.slaves_ddr,
+ .name = "qcom,enc-ddr-ab-ib",
+},
+{
+ .masters = bus_vectors_masters_slaves.masters_ddr,
+ .slaves = bus_vectors_masters_slaves.slaves_ddr,
+ .name = "qcom,dec-ddr-ab-ib",
+},
+};
+
static inline struct msm_vidc_inst *get_vidc_inst(struct file *filp, void *fh)
{
return container_of(filp->private_data,
@@ -137,10 +181,12 @@
err_invalid_input:
return ret;
}
-static u32 device_to_uvaddr(struct list_head *list, u32 device_addr)
+
+static struct buffer_info *device_to_uvaddr(
+ struct list_head *list, u32 device_addr)
{
- struct buffer_info *temp;
- u32 uvaddr = 0;
+ struct buffer_info *temp = NULL;
+ int found = 0;
int i;
if (!list || !device_addr) {
dprintk(VIDC_ERR, "Invalid input\n");
@@ -154,16 +200,16 @@
== device_addr) {
dprintk(VIDC_INFO,
"Found same fd buffer\n");
- uvaddr = temp->uvaddr[i];
+ found = 1;
break;
}
}
- if (uvaddr)
+ if (found)
break;
}
}
err_invalid_input:
- return uvaddr;
+ return temp;
}
static int msm_v4l2_open(struct file *filp)
@@ -500,9 +546,10 @@
b->m.planes[i].m.userptr = binfo->device_addr[i];
dprintk(VIDC_DBG, "Queueing device address = 0x%x\n",
binfo->device_addr[i]);
- if (binfo->handle[i]) {
- rc = msm_smem_clean_invalidate(v4l2_inst->mem_client,
- binfo->handle[i]);
+ if (binfo->handle[i] &&
+ (b->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)) {
+ rc = msm_smem_cache_operations(v4l2_inst->mem_client,
+ binfo->handle[i], SMEM_CACHE_CLEAN);
if (rc) {
dprintk(VIDC_ERR,
"Failed to clean caches: %d\n", rc);
@@ -522,6 +569,7 @@
int i;
struct msm_v4l2_vid_inst *v4l2_inst;
struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
+ struct buffer_info *buffer_info;
if (b->length > VIDEO_MAX_PLANES) {
dprintk(VIDC_ERR, "num planes exceed maximum: %d\n",
b->length);
@@ -541,9 +589,10 @@
!b->m.planes[i].m.userptr) {
continue;
}
- b->m.planes[i].m.userptr = device_to_uvaddr(
+ buffer_info = device_to_uvaddr(
&v4l2_inst->registered_bufs,
b->m.planes[i].m.userptr);
+ b->m.planes[i].m.userptr = buffer_info->uvaddr[i];
if (!b->m.planes[i].m.userptr) {
dprintk(VIDC_ERR,
"Failed to find user virtual address, 0x%lx, %d, %d\n",
@@ -551,6 +600,16 @@
rc = -EINVAL;
goto fail_dq_buf;
}
+ if (buffer_info->handle[i] &&
+ (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)) {
+ rc = msm_smem_cache_operations(v4l2_inst->mem_client,
+ buffer_info->handle[i], SMEM_CACHE_INVALIDATE);
+ if (rc) {
+ dprintk(VIDC_ERR,
+ "Failed to clean caches: %d\n", rc);
+ goto fail_dq_buf;
+ }
+ }
}
fail_dq_buf:
return rc;
@@ -743,6 +802,24 @@
res->reg_set.reg_tbl = NULL;
}
+static inline void msm_vidc_free_bus_vectors(
+ struct msm_vidc_platform_resources *res)
+{
+ int i, j;
+ if (res->bus_pdata) {
+ for (i = 0; i < ARRAY_SIZE(bus_pdata_config_vector); i++) {
+ for (j = 0; j < res->bus_pdata[i].num_usecases; j++) {
+ kfree(res->bus_pdata[i].usecase[j].vectors);
+ res->bus_pdata[i].usecase[j].vectors = NULL;
+ }
+ kfree(res->bus_pdata[i].usecase);
+ res->bus_pdata[i].usecase = NULL;
+ }
+ kfree(res->bus_pdata);
+ res->bus_pdata = NULL;
+ }
+}
+
static int msm_vidc_load_freq_table(struct msm_vidc_platform_resources *res)
{
int rc = 0;
@@ -864,6 +941,144 @@
return rc;
}
+static void msm_vidc_free_bus_vector(struct msm_bus_scale_pdata *bus_pdata)
+{
+ int i;
+ for (i = 0; i < bus_pdata->num_usecases; i++) {
+ kfree(bus_pdata->usecase[i].vectors);
+ bus_pdata->usecase[i].vectors = NULL;
+ }
+
+ kfree(bus_pdata->usecase);
+ bus_pdata->usecase = NULL;
+}
+
+static int msm_vidc_load_bus_vector(struct platform_device *pdev,
+ struct msm_bus_scale_pdata *bus_pdata, u32 num_ports,
+ struct bus_pdata_config *bus_pdata_config)
+{
+ struct bus_values {
+ u32 ab;
+ u32 ib;
+ };
+ struct bus_values *values;
+ int i, j;
+ int rc = 0;
+
+ values = kzalloc(sizeof(*values) * bus_pdata->num_usecases, GFP_KERNEL);
+ if (!values) {
+ dprintk(VIDC_ERR, "%s Failed to alloc bus_values\n", __func__);
+ rc = -ENOMEM;
+ goto err_mem_alloc;
+ }
+
+ if (of_property_read_u32_array(pdev->dev.of_node,
+ bus_pdata_config->name, (u32 *)values,
+ bus_pdata->num_usecases * (sizeof(*values)/sizeof(u32)))) {
+ dprintk(VIDC_ERR, "%s Failed to read bus values\n", __func__);
+ rc = -EINVAL;
+ goto err_parse_dt;
+ }
+
+ bus_pdata->usecase = kzalloc(sizeof(*bus_pdata->usecase) *
+ bus_pdata->num_usecases, GFP_KERNEL);
+ if (!bus_pdata->usecase) {
+ dprintk(VIDC_ERR,
+ "%s Failed to alloc bus_pdata usecase\n", __func__);
+ rc = -ENOMEM;
+ goto err_parse_dt;
+ }
+ bus_pdata->name = bus_pdata_config->name;
+ for (i = 0; i < bus_pdata->num_usecases; i++) {
+ bus_pdata->usecase[i].vectors = kzalloc(
+ sizeof(*bus_pdata->usecase[i].vectors) * num_ports,
+ GFP_KERNEL);
+ if (!bus_pdata->usecase) {
+ dprintk(VIDC_ERR,
+ "%s Failed to alloc bus_pdata usecase\n",
+ __func__);
+ break;
+ }
+ for (j = 0; j < num_ports; j++) {
+ bus_pdata->usecase[i].vectors[j].ab = (u64)values[i].ab
+ * 1000;
+ bus_pdata->usecase[i].vectors[j].ib = (u64)values[i].ib
+ * 1000;
+ bus_pdata->usecase[i].vectors[j].src =
+ bus_pdata_config->masters[j];
+ bus_pdata->usecase[i].vectors[j].dst =
+ bus_pdata_config->slaves[j];
+ dprintk(VIDC_DBG,
+ "ab = %llu, ib = %llu, src = %d, dst = %d\n",
+ bus_pdata->usecase[i].vectors[j].ab,
+ bus_pdata->usecase[i].vectors[j].ib,
+ bus_pdata->usecase[i].vectors[j].src,
+ bus_pdata->usecase[i].vectors[j].dst);
+ }
+ bus_pdata->usecase[i].num_paths = num_ports;
+ }
+ if (i < bus_pdata->num_usecases) {
+ for (--i; i >= 0; i--) {
+ kfree(bus_pdata->usecase[i].vectors);
+ bus_pdata->usecase[i].vectors = NULL;
+ }
+ kfree(bus_pdata->usecase);
+ bus_pdata->usecase = NULL;
+ rc = -EINVAL;
+ }
+err_parse_dt:
+ kfree(values);
+err_mem_alloc:
+ return rc;
+}
+
+static int msm_vidc_load_bus_vectors(struct msm_vidc_platform_resources *res)
+{
+ u32 num_ports = 0;
+ int rc = 0;
+ int i;
+ struct platform_device *pdev = res->pdev;
+ u32 num_bus_pdata = ARRAY_SIZE(bus_pdata_config_vector);
+
+ if (of_property_read_u32_array(pdev->dev.of_node, "qcom,bus-ports",
+ (u32 *)&num_ports, 1) || (num_ports == 0))
+ goto err_mem_alloc;
+
+ res->bus_pdata = kzalloc(sizeof(*res->bus_pdata) * num_bus_pdata,
+ GFP_KERNEL);
+ if (!res->bus_pdata) {
+ dprintk(VIDC_ERR, "Failed to alloc memory\n");
+ rc = -ENOMEM;
+ goto err_mem_alloc;
+ }
+ for (i = 0; i < num_bus_pdata; i++) {
+ res->bus_pdata[i].num_usecases = get_u32_array_num_elements(
+ pdev, bus_pdata_config_vector[i].name);
+ if (res->bus_pdata[i].num_usecases == 0) {
+ dprintk(VIDC_ERR, "no elements in %s\n",
+ bus_pdata_config_vector[i].name);
+ rc = -EINVAL;
+ break;
+ }
+
+ rc = msm_vidc_load_bus_vector(pdev, &res->bus_pdata[i],
+ num_ports, &bus_pdata_config_vector[i]);
+ if (rc) {
+ dprintk(VIDC_ERR,
+ "Failed to load bus vector: %d\n", i);
+ break;
+ }
+ }
+ if (i < num_bus_pdata) {
+ for (--i; i >= 0; i--)
+ msm_vidc_free_bus_vector(&res->bus_pdata[i]);
+ kfree(res->bus_pdata);
+ res->bus_pdata = NULL;
+ }
+err_mem_alloc:
+ return rc;
+}
+
static int read_platform_resources_from_dt(
struct msm_vidc_platform_resources *res)
{
@@ -900,8 +1115,16 @@
dprintk(VIDC_ERR, "Failed to load reg table: %d\n", rc);
goto err_load_reg_table;
}
+
+ rc = msm_vidc_load_bus_vectors(res);
+ if (rc) {
+ dprintk(VIDC_ERR, "Failed to load bus vectors: %d\n", rc);
+ goto err_load_bus_vectors;
+ }
return rc;
+err_load_bus_vectors:
+ msm_vidc_free_reg_table(res);
err_load_reg_table:
msm_vidc_free_iommu_maps(res);
err_load_iommu_maps:
@@ -1132,6 +1355,7 @@
msm_vidc_free_freq_table(&core->resources);
msm_vidc_free_iommu_maps(&core->resources);
msm_vidc_free_reg_table(&core->resources);
+ msm_vidc_free_bus_vectors(&core->resources);
kfree(core);
return rc;
}
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index 3c012e7..d43e5ba 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -987,7 +987,7 @@
rc = call_hfi_op(hdev, unset_ocmem, hdev->hfi_device_data);
if (rc) {
- dprintk(VIDC_ERR, "Failed to set OCMEM on driver\n");
+ dprintk(VIDC_INFO, "Failed to unset OCMEM on driver\n");
goto release_ocmem_failed;
}
rc = wait_for_completion_timeout(
@@ -1929,6 +1929,12 @@
rc = -ENOMEM;
goto err_no_mem;
}
+ rc = msm_smem_cache_operations(inst->mem_client,
+ handle, SMEM_CACHE_CLEAN);
+ if (rc) {
+ dprintk(VIDC_WARN,
+ "Failed to clean cache may cause undefined behavior\n");
+ }
binfo = kzalloc(sizeof(*binfo), GFP_KERNEL);
if (!binfo) {
dprintk(VIDC_ERR, "Out of memory\n");
@@ -2014,6 +2020,12 @@
rc = -ENOMEM;
goto err_no_mem;
}
+ rc = msm_smem_cache_operations(inst->mem_client,
+ handle, SMEM_CACHE_CLEAN);
+ if (rc) {
+ dprintk(VIDC_WARN,
+ "Failed to clean cache may cause undefined behavior\n");
+ }
binfo = kzalloc(sizeof(*binfo), GFP_KERNEL);
if (!binfo) {
dprintk(VIDC_ERR, "Out of memory\n");
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_debug.c b/drivers/media/platform/msm/vidc/msm_vidc_debug.c
index b713d8b..65542bc 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_debug.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_debug.c
@@ -18,6 +18,7 @@
int msm_vidc_debug = 0x3;
int msm_fw_debug = 0x18;
int msm_fw_debug_mode = 0x1;
+int msm_fw_low_power_mode = 0x1;
struct debug_buffer {
char ptr[MAX_DBG_BUF_SIZE];
@@ -159,6 +160,11 @@
dprintk(VIDC_ERR, "debugfs_create_file: fail\n");
goto failed_create_dir;
}
+ if (!debugfs_create_u32("fw_low_power_mode", S_IRUGO | S_IWUSR,
+ parent, &msm_fw_low_power_mode)) {
+ dprintk(VIDC_ERR, "debugfs_create_file: fail\n");
+ goto failed_create_dir;
+ }
failed_create_dir:
return dir;
}
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_debug.h b/drivers/media/platform/msm/vidc/msm_vidc_debug.h
index 07568ef..fb06af6 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_debug.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_debug.h
@@ -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
@@ -44,6 +44,7 @@
extern int msm_vidc_debug;
extern int msm_fw_debug;
extern int msm_fw_debug_mode;
+extern int msm_fw_low_power_mode;
#define dprintk(__level, __fmt, arg...) \
do { \
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_resources.h b/drivers/media/platform/msm/vidc/msm_vidc_resources.h
index ca8af9c..8fc6452 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_resources.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_resources.h
@@ -42,6 +42,7 @@
struct msm_vidc_iommu_info *iommu_maps;
uint32_t iommu_maps_size;
struct reg_set reg_set;
+ struct msm_bus_scale_pdata *bus_pdata;
struct platform_device *pdev;
};
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
index 7deef37..da44ec1 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -48,408 +48,6 @@
{0xFA181000, 0x1000},
};
-static struct msm_bus_vectors enc_ocmem_init_vectors[] = {
- {
- .src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
- .dst = MSM_BUS_SLAVE_OCMEM,
- .ab = 0,
- .ib = 0,
- },
-};
-
-static struct msm_bus_vectors enc_ocmem_perf1_vectors[] = {
- {
- .src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
- .dst = MSM_BUS_SLAVE_OCMEM,
- .ab = 138200000,
- .ib = 1222000000,
- },
-};
-
-static struct msm_bus_vectors enc_ocmem_perf2_vectors[] = {
- {
- .src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
- .dst = MSM_BUS_SLAVE_OCMEM,
- .ab = 414700000,
- .ib = 1222000000,
- },
-};
-
-static struct msm_bus_vectors enc_ocmem_perf3_vectors[] = {
- {
- .src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
- .dst = MSM_BUS_SLAVE_OCMEM,
- .ab = 940000000,
- .ib = 2444000000U,
- },
-};
-
-static struct msm_bus_vectors enc_ocmem_perf4_vectors[] = {
- {
- .src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
- .dst = MSM_BUS_SLAVE_OCMEM,
- .ab = 1880000000,
- .ib = 2444000000U,
- },
-};
-
-static struct msm_bus_vectors enc_ocmem_perf5_vectors[] = {
- {
- .src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
- .dst = MSM_BUS_SLAVE_OCMEM,
- .ab = 3008000000U,
- .ib = 3910400000U,
- },
-};
-
-static struct msm_bus_vectors enc_ocmem_perf6_vectors[] = {
- {
- .src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
- .dst = MSM_BUS_SLAVE_OCMEM,
- .ab = 3760000000U,
- .ib = 4888000000ULL,
- },
-};
-
-static struct msm_bus_vectors dec_ocmem_init_vectors[] = {
- {
- .src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
- .dst = MSM_BUS_SLAVE_OCMEM,
- .ab = 0,
- .ib = 0,
- },
-};
-
-static struct msm_bus_vectors dec_ocmem_perf1_vectors[] = {
- {
- .src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
- .dst = MSM_BUS_SLAVE_OCMEM,
- .ab = 176900000,
- .ib = 1556640000,
- },
-};
-
-static struct msm_bus_vectors dec_ocmem_perf2_vectors[] = {
- {
- .src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
- .dst = MSM_BUS_SLAVE_OCMEM,
- .ab = 456200000,
- .ib = 1556640000,
- },
-};
-
-static struct msm_bus_vectors dec_ocmem_perf3_vectors[] = {
- {
- .src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
- .dst = MSM_BUS_SLAVE_OCMEM,
- .ab = 864800000,
- .ib = 1556640000,
- },
-};
-
-static struct msm_bus_vectors dec_ocmem_perf4_vectors[] = {
- {
- .src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
- .dst = MSM_BUS_SLAVE_OCMEM,
- .ab = 1729600000,
- .ib = 3113280000U,
- },
-};
-
-static struct msm_bus_vectors dec_ocmem_perf5_vectors[] = {
- {
- .src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
- .dst = MSM_BUS_SLAVE_OCMEM,
- .ab = 2767360000U,
- .ib = 4981248000ULL,
- },
-};
-
-static struct msm_bus_vectors dec_ocmem_perf6_vectors[] = {
- {
- .src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
- .dst = MSM_BUS_SLAVE_OCMEM,
- .ab = 3459200000U,
- .ib = 6226560000ULL,
- },
-};
-
-static struct msm_bus_paths enc_ocmem_perf_vectors[] = {
- {
- ARRAY_SIZE(enc_ocmem_init_vectors),
- enc_ocmem_init_vectors,
- },
- {
- ARRAY_SIZE(enc_ocmem_perf1_vectors),
- enc_ocmem_perf1_vectors,
- },
- {
- ARRAY_SIZE(enc_ocmem_perf2_vectors),
- enc_ocmem_perf2_vectors,
- },
- {
- ARRAY_SIZE(enc_ocmem_perf3_vectors),
- enc_ocmem_perf3_vectors,
- },
- {
- ARRAY_SIZE(enc_ocmem_perf4_vectors),
- enc_ocmem_perf4_vectors,
- },
- {
- ARRAY_SIZE(enc_ocmem_perf5_vectors),
- enc_ocmem_perf5_vectors,
- },
- {
- ARRAY_SIZE(enc_ocmem_perf6_vectors),
- enc_ocmem_perf6_vectors,
- },
-};
-
-static struct msm_bus_paths dec_ocmem_perf_vectors[] = {
- {
- ARRAY_SIZE(dec_ocmem_init_vectors),
- dec_ocmem_init_vectors,
- },
- {
- ARRAY_SIZE(dec_ocmem_perf1_vectors),
- dec_ocmem_perf1_vectors,
- },
- {
- ARRAY_SIZE(dec_ocmem_perf2_vectors),
- dec_ocmem_perf2_vectors,
- },
- {
- ARRAY_SIZE(dec_ocmem_perf3_vectors),
- dec_ocmem_perf3_vectors,
- },
- {
- ARRAY_SIZE(dec_ocmem_perf4_vectors),
- dec_ocmem_perf4_vectors,
- },
- {
- ARRAY_SIZE(dec_ocmem_perf5_vectors),
- dec_ocmem_perf5_vectors,
- },
- {
- ARRAY_SIZE(dec_ocmem_perf6_vectors),
- dec_ocmem_perf6_vectors,
- },
-};
-
-
-static struct msm_bus_scale_pdata enc_ocmem_bus_data = {
- .usecase = enc_ocmem_perf_vectors,
- .num_usecases = ARRAY_SIZE(enc_ocmem_perf_vectors),
- .name = "msm_vidc_enc_ocmem",
-};
-
-static struct msm_bus_scale_pdata dec_ocmem_bus_data = {
- .usecase = dec_ocmem_perf_vectors,
- .num_usecases = ARRAY_SIZE(dec_ocmem_perf_vectors),
- .name = "msm_vidc_dec_ocmem",
-};
-
-static struct msm_bus_vectors enc_ddr_init_vectors[] = {
- {
- .src = MSM_BUS_MASTER_VIDEO_P0,
- .dst = MSM_BUS_SLAVE_EBI_CH0,
- .ab = 0,
- .ib = 0,
- },
-};
-
-
-static struct msm_bus_vectors enc_ddr_perf1_vectors[] = {
- {
- .src = MSM_BUS_MASTER_VIDEO_P0,
- .dst = MSM_BUS_SLAVE_EBI_CH0,
- .ab = 60000000,
- .ib = 664950000,
- },
-};
-
-static struct msm_bus_vectors enc_ddr_perf2_vectors[] = {
- {
- .src = MSM_BUS_MASTER_VIDEO_P0,
- .dst = MSM_BUS_SLAVE_EBI_CH0,
- .ab = 181000000,
- .ib = 664950000,
- },
-};
-
-static struct msm_bus_vectors enc_ddr_perf3_vectors[] = {
- {
- .src = MSM_BUS_MASTER_VIDEO_P0,
- .dst = MSM_BUS_SLAVE_EBI_CH0,
- .ab = 403000000,
- .ib = 664950000,
- },
-};
-
-static struct msm_bus_vectors enc_ddr_perf4_vectors[] = {
- {
- .src = MSM_BUS_MASTER_VIDEO_P0,
- .dst = MSM_BUS_SLAVE_EBI_CH0,
- .ab = 806000000,
- .ib = 1329900000,
- },
-};
-
-static struct msm_bus_vectors enc_ddr_perf5_vectors[] = {
- {
- .src = MSM_BUS_MASTER_VIDEO_P0,
- .dst = MSM_BUS_SLAVE_EBI_CH0,
- .ab = 1289600000,
- .ib = 2127840000U,
- },
-};
-
-static struct msm_bus_vectors enc_ddr_perf6_vectors[] = {
- {
- .src = MSM_BUS_MASTER_VIDEO_P0,
- .dst = MSM_BUS_SLAVE_EBI_CH0,
- .ab = 161200000,
- .ib = 6400000000ULL,
- },
-};
-
-static struct msm_bus_vectors dec_ddr_init_vectors[] = {
- {
- .src = MSM_BUS_MASTER_VIDEO_P0,
- .dst = MSM_BUS_SLAVE_EBI_CH0,
- .ab = 0,
- .ib = 0,
- },
-};
-
-static struct msm_bus_vectors dec_ddr_perf1_vectors[] = {
- {
- .src = MSM_BUS_MASTER_VIDEO_P0,
- .dst = MSM_BUS_SLAVE_EBI_CH0,
- .ab = 110000000,
- .ib = 909000000,
- },
-};
-
-static struct msm_bus_vectors dec_ddr_perf2_vectors[] = {
- {
- .src = MSM_BUS_MASTER_VIDEO_P0,
- .dst = MSM_BUS_SLAVE_EBI_CH0,
- .ab = 268000000,
- .ib = 909000000,
- },
-};
-
-static struct msm_bus_vectors dec_ddr_perf3_vectors[] = {
- {
- .src = MSM_BUS_MASTER_VIDEO_P0,
- .dst = MSM_BUS_SLAVE_EBI_CH0,
- .ab = 505000000,
- .ib = 909000000,
- },
-};
-
-static struct msm_bus_vectors dec_ddr_perf4_vectors[] = {
- {
- .src = MSM_BUS_MASTER_VIDEO_P0,
- .dst = MSM_BUS_SLAVE_EBI_CH0,
- .ab = 1010000000,
- .ib = 1818000000,
- },
-};
-
-static struct msm_bus_vectors dec_ddr_perf5_vectors[] = {
- {
- .src = MSM_BUS_MASTER_VIDEO_P0,
- .dst = MSM_BUS_SLAVE_EBI_CH0,
- .ab = 1616000000,
- .ib = 2908800000U,
- },
-};
-
-static struct msm_bus_vectors dec_ddr_perf6_vectors[] = {
- {
- .src = MSM_BUS_MASTER_VIDEO_P0,
- .dst = MSM_BUS_SLAVE_EBI_CH0,
- .ab = 2020000000U,
- .ib = 6400000000ULL,
- },
-};
-
-static struct msm_bus_paths enc_ddr_perf_vectors[] = {
- {
- ARRAY_SIZE(enc_ddr_init_vectors),
- enc_ddr_init_vectors,
- },
- {
- ARRAY_SIZE(enc_ddr_perf1_vectors),
- enc_ddr_perf1_vectors,
- },
- {
- ARRAY_SIZE(enc_ddr_perf2_vectors),
- enc_ddr_perf2_vectors,
- },
- {
- ARRAY_SIZE(enc_ddr_perf3_vectors),
- enc_ddr_perf3_vectors,
- },
- {
- ARRAY_SIZE(enc_ddr_perf4_vectors),
- enc_ddr_perf4_vectors,
- },
- {
- ARRAY_SIZE(enc_ddr_perf5_vectors),
- enc_ddr_perf5_vectors,
- },
- {
- ARRAY_SIZE(enc_ddr_perf6_vectors),
- enc_ddr_perf6_vectors,
- },
-};
-
-static struct msm_bus_paths dec_ddr_perf_vectors[] = {
- {
- ARRAY_SIZE(dec_ddr_init_vectors),
- dec_ddr_init_vectors,
- },
- {
- ARRAY_SIZE(dec_ddr_perf1_vectors),
- dec_ddr_perf1_vectors,
- },
- {
- ARRAY_SIZE(dec_ddr_perf2_vectors),
- dec_ddr_perf2_vectors,
- },
- {
- ARRAY_SIZE(dec_ddr_perf3_vectors),
- dec_ddr_perf3_vectors,
- },
- {
- ARRAY_SIZE(dec_ddr_perf4_vectors),
- dec_ddr_perf4_vectors,
- },
- {
- ARRAY_SIZE(dec_ddr_perf5_vectors),
- dec_ddr_perf5_vectors,
- },
- {
- ARRAY_SIZE(dec_ddr_perf6_vectors),
- dec_ddr_perf6_vectors,
- },
-};
-
-static struct msm_bus_scale_pdata enc_ddr_bus_data = {
- .usecase = enc_ddr_perf_vectors,
- .num_usecases = ARRAY_SIZE(enc_ddr_perf_vectors),
- .name = "msm_vidc_enc_ddr",
-};
-
-static struct msm_bus_scale_pdata dec_ddr_bus_data = {
- .usecase = dec_ddr_perf_vectors,
- .num_usecases = ARRAY_SIZE(dec_ddr_perf_vectors),
- .name = "msm_vidc_dec_ddr",
-};
-
#define TZBSP_MEM_PROTECT_VIDEO_VAR 0x8
struct tzbsp_memprot {
u32 cp_start;
@@ -755,20 +353,19 @@
rc = -ENOMEM;
goto fail_smem_alloc;
}
- rc = msm_smem_clean_invalidate(clnt, alloc);
- if (rc) {
- dprintk(VIDC_ERR, "NOTE: Failed to clean caches\n");
- goto fail_clean_cache;
- }
dprintk(VIDC_DBG, "venus_hfi_alloc:ptr=%p,size=%d",
alloc->kvaddr, size);
+ rc = msm_smem_cache_operations(clnt, alloc,
+ SMEM_CACHE_CLEAN);
+ if (rc) {
+ dprintk(VIDC_WARN, "Failed to clean cache\n");
+ dprintk(VIDC_WARN, "This may result in undefined behavior\n");
+ }
vmem->mem_size = alloc->size;
vmem->mem_data = alloc;
vmem->align_virtual_addr = (u8 *) alloc->kvaddr;
vmem->align_device_addr = (u8 *)alloc->device_addr;
return rc;
-fail_clean_cache:
- msm_smem_free(clnt, alloc);
fail_smem_alloc:
return rc;
}
@@ -814,6 +411,93 @@
rmb();
return rc;
}
+static inline void venus_hfi_clk_gating_on(struct venus_hfi_device *device,
+ enum vidc_clocks clk_level)
+{
+ int i;
+ struct venus_core_clock *cl;
+ if (!device) {
+ dprintk(VIDC_ERR, "Invalid params: %p\n", device);
+ return;
+ }
+ if (device->clocks_enabled == 0) {
+ dprintk(VIDC_DBG, "VCODEC clocks are already disabled");
+ goto already_disabled;
+ }
+ for (i = 0; i < clk_level; i++) {
+ cl = &device->resources.clock[i];
+ clk_disable_unprepare(cl->clk);
+ }
+already_disabled:
+ device->clocks_enabled = 0;
+}
+static inline int venus_hfi_clk_gating_off(struct venus_hfi_device *device,
+ enum vidc_clocks clk_level)
+{
+ int i;
+ struct venus_core_clock *cl;
+ int rc = 0;
+ if (!device) {
+ dprintk(VIDC_ERR, "Invalid params: %p\n", device);
+ return -EINVAL;
+ }
+ if (device->clocks_enabled == 1) {
+ dprintk(VIDC_DBG, "VCODEC clocks are already enabled");
+ goto already_enabled;
+ }
+ for (i = 0; i < clk_level; i++) {
+ cl = &device->resources.clock[i];
+ rc = clk_prepare_enable(cl->clk);
+ if (rc) {
+ dprintk(VIDC_ERR, "Failed to enable clocks\n");
+ goto fail_clk_enable;
+ } else {
+ dprintk(VIDC_DBG, "Clock: %s enabled\n", cl->name);
+ }
+ }
+already_enabled:
+ device->clocks_enabled = 1;
+ return rc;
+fail_clk_enable:
+ for (; i >= 0; i--) {
+ cl = &device->resources.clock[i];
+ clk_disable_unprepare(cl->clk);
+ }
+ return rc;
+}
+
+static unsigned long venus_hfi_get_clock_rate(struct venus_core_clock *clock,
+ int num_mbs_per_sec)
+{
+ int num_rows = clock->count;
+ struct load_freq_table *table = clock->load_freq_tbl;
+ unsigned long ret = table[num_rows-1].freq;
+ int i;
+ for (i = 0; i < num_rows; i++) {
+ if (num_mbs_per_sec > table[i].load)
+ break;
+ ret = table[i].freq;
+ }
+ dprintk(VIDC_PROF, "Required clock rate = %lu\n", ret);
+ return ret;
+}
+
+static int venus_hfi_scale_clocks(void *dev, int load)
+{
+ int rc = 0;
+ struct venus_hfi_device *device = dev;
+ device->load = load;
+ if (!device) {
+ dprintk(VIDC_ERR, "Invalid args: %p\n", device);
+ return -EINVAL;
+ }
+ rc = clk_set_rate(device->resources.clock[VCODEC_CLK].clk,
+ venus_hfi_get_clock_rate(&device->resources.clock[VCODEC_CLK],
+ load));
+ if (rc)
+ dprintk(VIDC_ERR, "Failed to set clock rate: %d\n", rc);
+ return rc;
+}
static int venus_hfi_iface_cmdq_write(struct venus_hfi_device *device,
void *pkt)
@@ -821,7 +505,6 @@
u32 rx_req_is_set = 0;
struct vidc_iface_q_info *q_info;
int result = -EPERM;
-
if (!device || !pkt) {
dprintk(VIDC_ERR, "Invalid Params");
return -EINVAL;
@@ -833,7 +516,16 @@
dprintk(VIDC_ERR, "cannot write to shared Q's");
goto err_q_write;
}
-
+ result = venus_hfi_clk_gating_off(device, VCODEC_CLK);
+ if (result) {
+ dprintk(VIDC_ERR, "VCODEC clock enable failed\n");
+ goto err_q_write;
+ }
+ result = venus_hfi_scale_clocks(device, device->load);
+ if (result) {
+ dprintk(VIDC_ERR, "VCODEC clock scaling failed\n");
+ goto err_q_write;
+ }
if (!venus_hfi_write_queue(q_info, (u8 *)pkt, &rx_req_is_set)) {
if (rx_req_is_set)
venus_hfi_write_register(
@@ -1218,6 +910,18 @@
return -ENOTEMPTY;
return 0;
}
+static int venus_hfi_sys_set_idle_message(struct venus_hfi_device *device,
+ int enable)
+{
+ u8 packet[VIDC_IFACEQ_VAR_SMALL_PKT_SIZE];
+ struct hfi_cmd_sys_set_property_packet *pkt =
+ (struct hfi_cmd_sys_set_property_packet *) &packet;
+ create_pkt_cmd_sys_idle_indicator(pkt, enable);
+ if (venus_hfi_iface_cmdq_write(device, pkt))
+ return -ENOTEMPTY;
+ return 0;
+}
+
static int venus_hfi_core_init(void *device)
{
@@ -1660,6 +1364,8 @@
goto err_session_init_fail;
if (venus_hfi_sys_set_debug(dev, msm_fw_debug))
dprintk(VIDC_ERR, "Setting fw_debug msg ON failed");
+ if (venus_hfi_sys_set_idle_message(dev, msm_fw_low_power_mode))
+ dprintk(VIDC_ERR, "Setting idle response ON failed");
return (void *) new_session;
err_session_init_fail:
@@ -2049,10 +1755,50 @@
device->callback(SYS_WATCHDOG_TIMEOUT, &cmd_done);
}
+static int venus_hfi_is_cmd_pending(struct venus_hfi_device *dev)
+{
+ struct hfi_queue_header *queue;
+ struct vidc_iface_q_info *q_info;
+ u32 write_ptr, read_ptr;
+ u32 rc = 0;
+ q_info = &dev->iface_queues[VIDC_IFACEQ_CMDQ_IDX];
+ if (!q_info)
+ dprintk(VIDC_ERR, "cannot read shared Q's");
+ queue = (struct hfi_queue_header *) q_info->q_hdr;
+ if (!queue) {
+ dprintk(VIDC_ERR, "queue not present");
+ return -ENOENT;
+ }
+ write_ptr = (u32)queue->qhdr_write_idx;
+ read_ptr = (u32)queue->qhdr_read_idx;
+ rc = read_ptr - write_ptr;
+ return rc;
+}
+
+static int venus_hfi_try_clk_gating(struct venus_hfi_device *device)
+{
+ int rc = 0;
+ u32 ctrl_status = 0;
+ if (!device) {
+ dprintk(VIDC_ERR, "invalid device");
+ return -ENODEV;
+ }
+ mutex_lock(&device->write_lock);
+ rc = venus_hfi_is_cmd_pending(device);
+ ctrl_status = venus_hfi_read_register(
+ device->hal_data->register_base_addr,
+ VIDC_CPU_CS_SCIACMDARG0);
+ if (((ctrl_status & VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK)
+ != 0) && !rc)
+ venus_hfi_clk_gating_on(device, VCODEC_CLK);
+ mutex_unlock(&device->write_lock);
+ return rc;
+}
+
static void venus_hfi_response_handler(struct venus_hfi_device *device)
{
u8 packet[VIDC_IFACEQ_MED_PKT_SIZE];
-
+ u32 rc = 0;
dprintk(VIDC_INFO, "#####venus_hfi_response_handler#####\n");
if (device) {
if ((device->intr_status &
@@ -2063,9 +1809,12 @@
}
while (!venus_hfi_iface_msgq_read(device, packet)) {
- hfi_process_msg_packet(device->callback,
+ rc = hfi_process_msg_packet(device->callback,
device->device_id,
(struct vidc_hal_msg_pkt_hdr *) packet);
+ if (rc == HFI_MSG_SYS_IDLE)
+ rc = venus_hfi_try_clk_gating(device);
+
}
while (!venus_hfi_iface_dbgq_read(device, packet)) {
struct hfi_msg_sys_debug_packet *pkt =
@@ -2233,50 +1982,45 @@
for (i = 0; i < VCODEC_MAX_CLKS; i++)
clk_put(device->resources.clock[i].clk);
}
-
-static unsigned long venus_hfi_get_clock_rate(struct venus_core_clock *clock,
- int num_mbs_per_sec)
+static inline void venus_hfi_disable_clks(struct venus_hfi_device *device)
{
- int num_rows = clock->count;
- struct load_freq_table *table = clock->load_freq_tbl;
- unsigned long ret = table[num_rows-1].freq;
int i;
- for (i = 0; i < num_rows; i++) {
- if (num_mbs_per_sec > table[i].load)
- break;
- ret = table[i].freq;
- }
- dprintk(VIDC_PROF, "Required clock rate = %lu\n", ret);
- return ret;
-}
-
-static int venus_hfi_scale_clocks(void *dev, int load)
-{
- int rc = 0;
- struct venus_hfi_device *device = dev;
+ struct venus_core_clock *cl;
if (!device) {
- dprintk(VIDC_ERR, "Invalid args: %p\n", device);
- return -EINVAL;
+ dprintk(VIDC_ERR, "Invalid params: %p\n", device);
+ return;
+ }
+ if (device->clocks_enabled) {
+ cl = &device->resources.clock[VCODEC_CLK];
+ clk_disable_unprepare(cl->clk);
}
- rc = clk_set_rate(device->resources.clock[VCODEC_CLK].clk,
- venus_hfi_get_clock_rate(&device->resources.clock[VCODEC_CLK],
- load));
- if (rc)
- dprintk(VIDC_ERR, "Failed to set clock rate: %d\n", rc);
- return rc;
+ for (i = VCODEC_CLK; i < VCODEC_MAX_CLKS; i++) {
+ cl = &device->resources.clock[i];
+ clk_disable_unprepare(cl->clk);
+ }
+ device->clocks_enabled = 0;
}
-
static inline int venus_hfi_enable_clks(struct venus_hfi_device *device)
{
- int i;
+ int i = 0;
struct venus_core_clock *cl;
int rc = 0;
if (!device) {
dprintk(VIDC_ERR, "Invalid params: %p\n", device);
return -EINVAL;
}
- for (i = 0; i < VCODEC_MAX_CLKS; i++) {
+ if (!device->clocks_enabled) {
+ cl = &device->resources.clock[VCODEC_CLK];
+ rc = clk_prepare_enable(cl->clk);
+ if (rc) {
+ dprintk(VIDC_ERR, "Failed to enable clocks\n");
+ goto fail_clk_enable;
+ } else {
+ dprintk(VIDC_DBG, "Clock: %s enabled\n", cl->name);
+ }
+ }
+ for (i = VCODEC_CLK; i < VCODEC_MAX_CLKS; i++) {
cl = &device->resources.clock[i];
rc = clk_prepare_enable(cl->clk);
if (rc) {
@@ -2286,6 +2030,7 @@
dprintk(VIDC_DBG, "Clock: %s enabled\n", cl->name);
}
}
+ device->clocks_enabled = 1;
return rc;
fail_clk_enable:
for (; i >= 0; i--) {
@@ -2294,21 +2039,6 @@
}
return rc;
}
-
-static inline void venus_hfi_disable_clks(struct venus_hfi_device *device)
-{
- int i;
- struct venus_core_clock *cl;
- if (!device) {
- dprintk(VIDC_ERR, "Invalid params: %p\n", device);
- return;
- }
- for (i = 0; i < VCODEC_MAX_CLKS; i++) {
- cl = &device->resources.clock[i];
- clk_disable_unprepare(cl->clk);
- }
-}
-
static int venus_hfi_register_iommu_domains(struct venus_hfi_device *device,
struct msm_vidc_platform_resources *res)
{
@@ -2403,31 +2133,31 @@
{
struct venus_bus_info *bus_info;
int rc = 0;
- if (!device)
+ if ((!device) || (!device->res->bus_pdata))
return -EINVAL;
bus_info = &device->resources.bus_info;
bus_info->ddr_handle[MSM_VIDC_ENCODER] =
- msm_bus_scale_register_client(&enc_ddr_bus_data);
+ msm_bus_scale_register_client(&device->res->bus_pdata[2]);
if (!bus_info->ddr_handle[MSM_VIDC_ENCODER]) {
dprintk(VIDC_ERR, "Failed to register bus scale client\n");
goto err_init_bus;
}
bus_info->ddr_handle[MSM_VIDC_DECODER] =
- msm_bus_scale_register_client(&dec_ddr_bus_data);
+ msm_bus_scale_register_client(&device->res->bus_pdata[3]);
if (!bus_info->ddr_handle[MSM_VIDC_DECODER]) {
dprintk(VIDC_ERR, "Failed to register bus scale client\n");
goto err_init_bus;
}
bus_info->ocmem_handle[MSM_VIDC_ENCODER] =
- msm_bus_scale_register_client(&enc_ocmem_bus_data);
+ msm_bus_scale_register_client(&device->res->bus_pdata[0]);
if (!bus_info->ocmem_handle[MSM_VIDC_ENCODER]) {
dprintk(VIDC_ERR, "Failed to register bus scale client\n");
goto err_init_bus;
}
bus_info->ocmem_handle[MSM_VIDC_DECODER] =
- msm_bus_scale_register_client(&dec_ocmem_bus_data);
+ msm_bus_scale_register_client(&device->res->bus_pdata[1]);
if (!bus_info->ocmem_handle[MSM_VIDC_DECODER]) {
dprintk(VIDC_ERR, "Failed to register bus scale client\n");
goto err_init_bus;
@@ -2553,17 +2283,25 @@
struct vidc_resource_hdr rhdr;
struct venus_hfi_device *device = dev;
int rc = 0;
- if (!device || !device->resources.ocmem.buf) {
+ if (!device) {
dprintk(VIDC_ERR, "%s Invalid params, device:%p\n",
__func__, device);
- return -EINVAL;
+ rc = -EINVAL;
+ goto ocmem_unset_failed;
}
+ if (!device->resources.ocmem.buf) {
+ dprintk(VIDC_INFO, "%s Trying to free OCMEM which is not set",
+ __func__);
+ rc = -EINVAL;
+ goto ocmem_unset_failed;
+ }
+
rhdr.resource_id = VIDC_RESOURCE_OCMEM;
rhdr.resource_handle = (u32) &device->resources.ocmem;
rc = venus_hfi_core_release_resource(device, &rhdr);
if (rc)
- dprintk(VIDC_ERR, "Failed to set OCMEM on driver\n");
-
+ dprintk(VIDC_ERR, "Failed to unset OCMEM on driver\n");
+ocmem_unset_failed:
return rc;
}
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.h b/drivers/media/platform/msm/vidc/venus_hfi.h
index 58314dd..2ffb9d4 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.h
+++ b/drivers/media/platform/msm/vidc/venus_hfi.h
@@ -175,6 +175,8 @@
struct list_head sess_head;
u32 intr_status;
u32 device_id;
+ u32 load;
+ u32 clocks_enabled;
struct mutex read_lock;
struct mutex write_lock;
msm_vidc_callback callback;
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi.h b/drivers/media/platform/msm/vidc/vidc_hfi.h
index f565d3b..75594b3 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi.h
@@ -830,7 +830,7 @@
extern struct hal_device_data hal_ctxt;
-void hfi_process_msg_packet(msm_vidc_callback callback,
+u32 hfi_process_msg_packet(msm_vidc_callback callback,
u32 device_id, struct vidc_hal_msg_pkt_hdr *msg_hdr);
#endif
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_io.h b/drivers/media/platform/msm/vidc/vidc_hfi_io.h
index 2bc8e6a..eeffe35 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_io.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_io.h
@@ -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
@@ -49,6 +49,7 @@
#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_SHFT 0x1
#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_STATUS_BMSK 0x1
#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_STATUS_SHFT 0x0
+#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK 0x40000000
/* HFI_QTBL_INFO */
#define VIDC_CPU_CS_SCIACMDARG1 (VIDC_CPU_CS_BASE_OFFS + 0x50)
diff --git a/drivers/misc/smsc_hub.c b/drivers/misc/smsc_hub.c
index 2ffe4ca..bc338a4 100644
--- a/drivers/misc/smsc_hub.c
+++ b/drivers/misc/smsc_hub.c
@@ -491,9 +491,7 @@
{
int ret = 0;
- if (!IS_ERR(smsc_hub->ref_clk)) {
- clk_disable_unprepare(smsc_hub->ref_clk);
- } else {
+ if (smsc_hub->xo_handle) {
ret = msm_xo_mode_vote(smsc_hub->xo_handle, MSM_XO_MODE_OFF);
if (ret) {
pr_err("%s: failed to devote for TCXO\n"
@@ -507,9 +505,7 @@
{
int ret = 0;
- if (!IS_ERR(smsc_hub->ref_clk)) {
- clk_prepare_enable(smsc_hub->ref_clk);
- } else {
+ if (smsc_hub->xo_handle) {
ret = msm_xo_mode_vote(smsc_hub->xo_handle, MSM_XO_MODE_ON);
if (ret) {
pr_err("%s: failed to vote for TCXO\n"
diff --git a/drivers/misc/tspp.c b/drivers/misc/tspp.c
index ef23871..9a53817 100644
--- a/drivers/misc/tspp.c
+++ b/drivers/misc/tspp.c
@@ -1319,10 +1319,12 @@
pr_err("tspp: error starting tsif0");
return -EBUSY;
}
- val = readl_relaxed(pdev->base + TSPP_CONTROL);
- writel_relaxed(val & ~TSPP_CONTROL_TSP_TSIF0_SRC_DIS,
- pdev->base + TSPP_CONTROL);
- wmb();
+ if (pdev->tsif[0].ref_count == 1) {
+ val = readl_relaxed(pdev->base + TSPP_CONTROL);
+ writel_relaxed(val & ~TSPP_CONTROL_TSP_TSIF0_SRC_DIS,
+ pdev->base + TSPP_CONTROL);
+ wmb();
+ }
break;
case TSPP_SOURCE_TSIF1:
if (tspp_config_gpios(pdev, channel->src, 1) != 0) {
@@ -1334,10 +1336,12 @@
pr_err("tspp: error starting tsif1");
return -EBUSY;
}
- val = readl_relaxed(pdev->base + TSPP_CONTROL);
- writel_relaxed(val & ~TSPP_CONTROL_TSP_TSIF1_SRC_DIS,
- pdev->base + TSPP_CONTROL);
- wmb();
+ if (pdev->tsif[1].ref_count == 1) {
+ val = readl_relaxed(pdev->base + TSPP_CONTROL);
+ writel_relaxed(val & ~TSPP_CONTROL_TSP_TSIF1_SRC_DIS,
+ pdev->base + TSPP_CONTROL);
+ wmb();
+ }
break;
case TSPP_SOURCE_MEM:
break;
@@ -1363,6 +1367,7 @@
int tspp_close_stream(u32 dev, u32 channel_id)
{
u32 val;
+ u32 prev_ref_count;
struct tspp_device *pdev;
struct tspp_channel *channel;
@@ -1379,23 +1384,30 @@
switch (channel->src) {
case TSPP_SOURCE_TSIF0:
+ prev_ref_count = pdev->tsif[0].ref_count;
tspp_stop_tsif(&pdev->tsif[0]);
if (tspp_config_gpios(pdev, channel->src, 0) != 0)
pr_err("tspp: error disabling tsif0 GPIOs\n");
- val = readl_relaxed(pdev->base + TSPP_CONTROL);
- writel_relaxed(val | TSPP_CONTROL_TSP_TSIF0_SRC_DIS,
- pdev->base + TSPP_CONTROL);
- wmb();
+ if (prev_ref_count == 1) {
+ val = readl_relaxed(pdev->base + TSPP_CONTROL);
+ writel_relaxed(val | TSPP_CONTROL_TSP_TSIF0_SRC_DIS,
+ pdev->base + TSPP_CONTROL);
+ wmb();
+ }
break;
case TSPP_SOURCE_TSIF1:
+ prev_ref_count = pdev->tsif[1].ref_count;
tspp_stop_tsif(&pdev->tsif[1]);
if (tspp_config_gpios(pdev, channel->src, 0) != 0)
pr_err("tspp: error disabling tsif0 GPIOs\n");
- val = readl_relaxed(pdev->base + TSPP_CONTROL);
- writel_relaxed(val | TSPP_CONTROL_TSP_TSIF1_SRC_DIS,
- pdev->base + TSPP_CONTROL);
+ if (prev_ref_count == 1) {
+ val = readl_relaxed(pdev->base + TSPP_CONTROL);
+ writel_relaxed(val | TSPP_CONTROL_TSP_TSIF1_SRC_DIS,
+ pdev->base + TSPP_CONTROL);
+ wmb();
+ }
break;
case TSPP_SOURCE_MEM:
break;
@@ -1595,9 +1607,6 @@
}
channel->filter_count = 0;
- /* stop the stream */
- tspp_close_stream(dev, channel->id);
-
/* disconnect the bam */
if (sps_disconnect(channel->pipe) != 0)
pr_warn("tspp: Error freeing sps endpoint (%i)", channel->id);
@@ -2435,7 +2444,7 @@
channel = filp->private_data;
dev = channel->pdev->pdev->id;
- if (!param1)
+ if ((param0 != TSPP_IOCTL_CLOSE_STREAM) && !param1)
return -EINVAL;
switch (param0) {
@@ -2502,6 +2511,9 @@
sizeof(struct tspp_buffer)) == 0)
rc = tspp_set_buffer_size(channel, &b);
break;
+ case TSPP_IOCTL_CLOSE_STREAM:
+ rc = tspp_close_stream(dev, channel->id);
+ break;
default:
pr_err("tspp: Unknown ioctl %i", param0);
}
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 2e78f33..a8e5c97 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -4325,6 +4325,69 @@
}
}
+/**
+ * msmsdcc_stop_request - stops ongoing request
+ * @mmc: MMC host, running the request
+ *
+ * Stops currently running request synchronously. All relevant request
+ * information is cleared.
+ */
+int msmsdcc_stop_request(struct mmc_host *mmc)
+{
+ struct msmsdcc_host *host = mmc_priv(mmc);
+ struct mmc_request *mrq;
+ unsigned long flags;
+ int rc = 0;
+
+ spin_lock_irqsave(&host->lock, flags);
+ mrq = host->curr.mrq;
+ if (mrq) {
+ msmsdcc_reset_and_restore(host);
+ /*
+ * Note: We are just taking care of SPS. We may also
+ * need to think about ADM (and PIO?) later if required.
+ */
+ if (host->sps.sg && is_sps_mode(host)) {
+ if (!mrq->data->host_cookie)
+ dma_unmap_sg(mmc_dev(host->mmc), host->sps.sg,
+ host->sps.num_ents, host->sps.dir);
+ host->sps.sg = NULL;
+ host->sps.busy = 0;
+ }
+
+ /*
+ * Clear current request information as current
+ * request has ended
+ */
+ memset(&host->curr, 0, sizeof(struct msmsdcc_curr_req));
+ del_timer(&host->req_tout_timer);
+ } else {
+ rc = -EINVAL;
+ }
+ spin_unlock_irqrestore(&host->lock, flags);
+
+ return rc;
+}
+
+/**
+ * msmsdcc_get_xfer_remain - returns number of bytes passed on bus
+ * @mmc: MMC host, running the request
+ *
+ * Returns the number of bytes passed for SPS transfer. 0 - for non-SPS
+ * transfer.
+ */
+unsigned int msmsdcc_get_xfer_remain(struct mmc_host *mmc)
+{
+ struct msmsdcc_host *host = mmc_priv(mmc);
+ u32 data_cnt = 0;
+
+ /* Currently, we don't support to stop the non-SPS transfer */
+ if (host->sps.busy && atomic_read(&host->clks_on))
+ data_cnt = readl_relaxed(host->base + MMCIDATACNT);
+
+ return data_cnt;
+}
+
static const struct mmc_host_ops msmsdcc_ops = {
.enable = msmsdcc_enable,
.disable = msmsdcc_disable,
@@ -4337,6 +4400,8 @@
.start_signal_voltage_switch = msmsdcc_switch_io_voltage,
.execute_tuning = msmsdcc_execute_tuning,
.hw_reset = msmsdcc_hw_reset,
+ .stop_request = msmsdcc_stop_request,
+ .get_xfer_remain = msmsdcc_get_xfer_remain,
};
static void msmsdcc_enable_status_gpio(struct msmsdcc_host *host)
diff --git a/drivers/net/wireless/wcnss/wcnss_vreg.c b/drivers/net/wireless/wcnss/wcnss_vreg.c
index 75c75a8..025410a 100644
--- a/drivers/net/wireless/wcnss/wcnss_vreg.c
+++ b/drivers/net/wireless/wcnss/wcnss_vreg.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. 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 version 2 and
@@ -40,6 +40,10 @@
#define RIVA_PMU_OFFSET 0x28
#define PRONTO_PMU_OFFSET 0x1004
+#define RIVA_SPARE_OFFSET 0x0b4
+#define PRONTO_SPARE_OFFSET 0x1088
+#define NVBIN_DLND_BIT BIT(25)
+
#define WCNSS_PMU_CFG_IRIS_XO_CFG BIT(3)
#define WCNSS_PMU_CFG_IRIS_XO_EN BIT(4)
#define WCNSS_PMU_CFG_GC_BUS_MUX_SEL_TOP BIT(5)
@@ -115,13 +119,16 @@
int rc = 0;
int size = 0;
int pmu_offset = 0;
+ int spare_offset = 0;
unsigned long wcnss_phys_addr;
void __iomem *pmu_conf_reg;
+ void __iomem *spare_reg;
struct clk *clk;
if (wcnss_hardware_type() == WCNSS_PRONTO_HW) {
wcnss_phys_addr = MSM_PRONTO_PHYS;
pmu_offset = PRONTO_PMU_OFFSET;
+ spare_offset = PRONTO_SPARE_OFFSET;
size = 0x3000;
clk = clk_get(dev, "xo");
@@ -132,6 +139,7 @@
} else {
wcnss_phys_addr = MSM_RIVA_PHYS;
pmu_offset = RIVA_PMU_OFFSET;
+ spare_offset = RIVA_SPARE_OFFSET;
size = SZ_256;
clk = clk_get(dev, "cxo");
@@ -147,6 +155,13 @@
pr_err("ioremap wcnss physical failed\n");
goto fail;
}
+
+ pr_debug("wcnss: Indicate NV bin download\n");
+ spare_reg = msm_wcnss_base + spare_offset;
+ reg = readl_relaxed(spare_reg);
+ reg |= NVBIN_DLND_BIT;
+ writel_relaxed(reg, spare_reg);
+
pmu_conf_reg = msm_wcnss_base + pmu_offset;
/* Enable IRIS XO */
diff --git a/drivers/net/wireless/wcnss/wcnss_wlan.c b/drivers/net/wireless/wcnss/wcnss_wlan.c
index 55b4192..439b1f8 100644
--- a/drivers/net/wireless/wcnss/wcnss_wlan.c
+++ b/drivers/net/wireless/wcnss/wcnss_wlan.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. 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 version 2 and
@@ -11,6 +11,7 @@
*/
#include <linux/module.h>
+#include <linux/firmware.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/platform_device.h>
@@ -75,13 +76,16 @@
#define WCNSS_CTRL_MSG_START 0x01000000
#define WCNSS_VERSION_REQ (WCNSS_CTRL_MSG_START + 0)
#define WCNSS_VERSION_RSP (WCNSS_CTRL_MSG_START + 1)
+#define WCNSS_NVBIN_DNLD_REQ (WCNSS_CTRL_MSG_START + 2)
+#define WCNSS_NVBIN_DNLD_RSP (WCNSS_CTRL_MSG_START + 3)
+
#define VALID_VERSION(version) \
((strncmp(version, "INVALID", WCNSS_VERSION_LEN)) ? 1 : 0)
struct smd_msg_hdr {
- unsigned int type;
- unsigned int len;
+ unsigned int msg_type;
+ unsigned int msg_len;
};
struct wcnss_version {
@@ -92,6 +96,57 @@
unsigned char revision;
};
+#define NVBIN_FILE "wlan/prima/WCNSS_qcom_wlan_nv.bin"
+
+/*
+ * On SMD channel 4K of maximum data can be transferred, including message
+ * header, so NV fragment size as next multiple of 1Kb is 3Kb.
+ */
+#define NV_FRAGMENT_SIZE 3072
+
+/* Macro to find the total number fragments of the NV bin Image */
+#define TOTALFRAGMENTS(x) (((x % NV_FRAGMENT_SIZE) == 0) ? \
+ (x / NV_FRAGMENT_SIZE) : ((x / NV_FRAGMENT_SIZE) + 1))
+
+struct nvbin_dnld_req_params {
+ /*
+ * Fragment sequence number of the NV bin Image. NV Bin Image
+ * might not fit into one message due to size limitation of
+ * the SMD channel FIFO so entire NV blob is chopped into
+ * multiple fragments starting with seqeunce number 0. The
+ * last fragment is indicated by marking is_last_fragment field
+ * to 1. At receiving side, NV blobs would be concatenated
+ * together without any padding bytes in between.
+ */
+ unsigned short frag_number;
+
+ /*
+ * When set to 1 it indicates that no more fragments will
+ * be sent. Receiver shall send back response message after
+ * the last fragment.
+ */
+ unsigned short is_last_fragment;
+
+ /* NV Image size (number of bytes) */
+ unsigned int nvbin_buffer_size;
+
+ /*
+ * Following the 'nvbin_buffer_size', there should be
+ * nvbin_buffer_size bytes of NV bin Image i.e.
+ * uint8[nvbin_buffer_size].
+ */
+};
+
+struct nvbin_dnld_req_msg {
+ /*
+ * Note: The length specified in nvbin_dnld_req_msg messages
+ * should be hdr.msg_len = sizeof(nvbin_dnld_req_msg) +
+ * nvbin_buffer_size.
+ */
+ struct smd_msg_hdr hdr;
+ struct nvbin_dnld_req_params dnld_req_params;
+};
+
static struct {
struct platform_device *pdev;
void *pil;
@@ -111,6 +166,7 @@
struct wcnss_wlan_config wlan_config;
struct delayed_work wcnss_work;
struct work_struct wcnssctrl_version_work;
+ struct work_struct wcnssctrl_nvbin_dnld_work;
struct work_struct wcnssctrl_rx_work;
struct wake_lock wcnss_wake_lock;
void __iomem *msm_wcnss_base;
@@ -404,7 +460,7 @@
void wcnss_flush_delayed_boot_votes()
{
- flush_delayed_work_sync(&penv->wcnss_work);
+ flush_delayed_work(&penv->wcnss_work);
}
EXPORT_SYMBOL(wcnss_flush_delayed_boot_votes);
@@ -678,7 +734,7 @@
ret = smd_write_avail(penv->smd_ch);
if (ret < len) {
pr_err("wcnss: no space available for smd frame\n");
- ret = -ENOSPC;
+ return -ENOSPC;
}
ret = smd_write(penv->smd_ch, data, len);
if (ret < len) {
@@ -695,6 +751,7 @@
unsigned char buf[WCNSS_MAX_FRAME_SIZE];
struct smd_msg_hdr *phdr;
struct wcnss_version *pversion;
+ int hw_type;
len = smd_read_avail(penv->smd_ch);
if (len > WCNSS_MAX_FRAME_SIZE) {
@@ -713,7 +770,7 @@
phdr = (struct smd_msg_hdr *)buf;
- switch (phdr->type) {
+ switch (phdr->msg_type) {
case WCNSS_VERSION_RSP:
pversion = (struct wcnss_version *)buf;
@@ -726,10 +783,38 @@
"%02x%02x%02x%02x", pversion->major, pversion->minor,
pversion->version, pversion->revision);
pr_info("wcnss: version %s\n", penv->wcnss_version);
+ /* schedule work to download nvbin to ccpu */
+ hw_type = wcnss_hardware_type();
+ switch (hw_type) {
+ case WCNSS_RIVA_HW:
+ /* supported only if riva major >= 1 and minor >= 4 */
+ if ((pversion->major >= 1) && (pversion->minor >= 4)) {
+ pr_info("wcnss: schedule dnld work for riva\n");
+ schedule_work(&penv->wcnssctrl_nvbin_dnld_work);
+ }
+ break;
+
+ case WCNSS_PRONTO_HW:
+ /* supported only if pronto major >= 1 and minor >= 4 */
+ if ((pversion->major >= 1) && (pversion->minor >= 4)) {
+ pr_info("wcnss: schedule dnld work for pronto\n");
+ schedule_work(&penv->wcnssctrl_nvbin_dnld_work);
+ }
+ break;
+
+ default:
+ pr_info("wcnss: unknown hw type (%d), will not schedule dnld work\n",
+ hw_type);
+ break;
+ }
+ break;
+
+ case WCNSS_NVBIN_DNLD_RSP:
+ pr_info("wcnss: received WCNSS_NVBIN_DNLD_RSP from ccpu\n");
break;
default:
- pr_err("wcnss: invalid message type %d\n", phdr->type);
+ pr_err("wcnss: invalid message type %d\n", phdr->msg_type);
}
return;
}
@@ -739,15 +824,126 @@
struct smd_msg_hdr smd_msg;
int ret = 0;
- smd_msg.type = WCNSS_VERSION_REQ;
- smd_msg.len = sizeof(smd_msg);
- ret = wcnss_smd_tx(&smd_msg, smd_msg.len);
+ smd_msg.msg_type = WCNSS_VERSION_REQ;
+ smd_msg.msg_len = sizeof(smd_msg);
+ ret = wcnss_smd_tx(&smd_msg, smd_msg.msg_len);
if (ret < 0)
pr_err("wcnss: smd tx failed\n");
return;
}
+static void wcnss_nvbin_dnld_req(struct work_struct *worker)
+{
+ int ret = 0;
+ struct nvbin_dnld_req_msg *dnld_req_msg;
+ unsigned short total_fragments = 0;
+ unsigned short count = 0;
+ unsigned short retry_count = 0;
+ unsigned short cur_frag_size = 0;
+ unsigned char *outbuffer = NULL;
+ const void *nv_blob_addr = NULL;
+ unsigned int nv_blob_size = 0;
+ const struct firmware *nv = NULL;
+ struct device *dev = NULL;
+
+ dev = wcnss_wlan_get_device();
+
+ ret = request_firmware(&nv, NVBIN_FILE, dev);
+
+ if (ret || !nv || !nv->data || !nv->size) {
+ pr_err("wcnss: wcnss_nvbin_dnld_req: request_firmware failed for %s\n",
+ NVBIN_FILE);
+ return;
+ }
+
+ /*
+ * First 4 bytes in nv blob is validity bitmap.
+ * We cannot validate nv, so skip those 4 bytes.
+ */
+ nv_blob_addr = nv->data + 4;
+ nv_blob_size = nv->size - 4;
+
+ total_fragments = TOTALFRAGMENTS(nv_blob_size);
+
+ pr_info("wcnss: NV bin size: %d, total_fragments: %d\n",
+ nv_blob_size, total_fragments);
+
+ /* get buffer for nv bin dnld req message */
+ outbuffer = kmalloc((sizeof(struct nvbin_dnld_req_msg) +
+ NV_FRAGMENT_SIZE), GFP_KERNEL);
+
+ if (NULL == outbuffer) {
+ pr_err("wcnss: wcnss_nvbin_dnld_req: failed to get buffer\n");
+ goto err_free_nv;
+ }
+
+ dnld_req_msg = (struct nvbin_dnld_req_msg *)outbuffer;
+
+ dnld_req_msg->hdr.msg_type = WCNSS_NVBIN_DNLD_REQ;
+
+ for (count = 0; count < total_fragments; count++) {
+ dnld_req_msg->dnld_req_params.frag_number = count;
+
+ if (count == (total_fragments - 1)) {
+ /* last fragment, take care of boundry condition */
+ cur_frag_size = nv_blob_size % NV_FRAGMENT_SIZE;
+ if (!cur_frag_size)
+ cur_frag_size = NV_FRAGMENT_SIZE;
+
+ dnld_req_msg->dnld_req_params.is_last_fragment = 1;
+ } else {
+ cur_frag_size = NV_FRAGMENT_SIZE;
+ dnld_req_msg->dnld_req_params.is_last_fragment = 0;
+ }
+
+ dnld_req_msg->dnld_req_params.nvbin_buffer_size =
+ cur_frag_size;
+
+ dnld_req_msg->hdr.msg_len =
+ sizeof(struct nvbin_dnld_req_msg) + cur_frag_size;
+
+ /* copy NV fragment */
+ memcpy((outbuffer + sizeof(struct nvbin_dnld_req_msg)),
+ (nv_blob_addr + count * NV_FRAGMENT_SIZE),
+ cur_frag_size);
+
+ ret = wcnss_smd_tx(outbuffer, dnld_req_msg->hdr.msg_len);
+
+ retry_count = 0;
+ while ((ret == -ENOSPC) && (retry_count <= 3)) {
+ pr_debug("wcnss: wcnss_nvbin_dnld_req: smd tx failed, ENOSPC\n");
+ pr_debug("fragment: %d, len: %d, TotFragments: %d, retry_count: %d\n",
+ count, dnld_req_msg->hdr.msg_len,
+ total_fragments, retry_count);
+
+ /* wait and try again */
+ msleep(20);
+ retry_count++;
+ ret = wcnss_smd_tx(outbuffer,
+ dnld_req_msg->hdr.msg_len);
+ }
+
+ if (ret < 0) {
+ pr_err("wcnss: wcnss_nvbin_dnld_req: smd tx failed\n");
+ pr_err("fragment %d, len: %d, TotFragments: %d, retry_count: %d\n",
+ count, dnld_req_msg->hdr.msg_len,
+ total_fragments, retry_count);
+ goto err_dnld;
+ }
+ }
+
+err_dnld:
+ /* free buffer */
+ kfree(outbuffer);
+
+err_free_nv:
+ /* release firmware */
+ release_firmware(nv);
+
+ return;
+}
+
static int
wcnss_trigger_config(struct platform_device *pdev)
{
@@ -832,6 +1028,7 @@
}
INIT_WORK(&penv->wcnssctrl_rx_work, wcnssctrl_rx_handler);
INIT_WORK(&penv->wcnssctrl_version_work, wcnss_send_version_req);
+ INIT_WORK(&penv->wcnssctrl_nvbin_dnld_work, wcnss_nvbin_dnld_req);
wake_lock_init(&penv->wcnss_wake_lock, WAKE_LOCK_SUSPEND, "wcnss");
diff --git a/drivers/power/battery_current_limit.c b/drivers/power/battery_current_limit.c
index d1750ec..ecda153 100644
--- a/drivers/power/battery_current_limit.c
+++ b/drivers/power/battery_current_limit.c
@@ -507,12 +507,18 @@
return 0;
}
+static struct of_device_id bcl_match_table[] = {
+ {.compatible = "qcom,bcl"},
+ {},
+};
+
static struct platform_driver bcl_driver = {
.probe = bcl_probe,
.remove = __devexit_p(bcl_remove),
.driver = {
.name = BCL_DEV_NAME,
.owner = THIS_MODULE,
+ .of_match_table = bcl_match_table,
},
};
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index e4ae96f..b3fd5bc 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -340,38 +340,65 @@
{
int rc;
unsigned long flags = 0;
+ u8 temp;
/* Disable LPM */
if (chip->lockup_lpm_wrkarnd) {
spin_lock_irqsave(&lpm_lock, flags);
/*
- * This write could have initiated right after a previous write.
- * Allow time to settle to go in to lpm from the previous write
+ * This delay is to prevent exit out of 32khz mode within
+ * 200uS. It could be that chg was removed just few uS before
+ * this gets called.
*/
udelay(200);
- rc = pm8921_chg_set_lpm(chip, 0);
- if (rc)
- goto lpm_err;
+ /* no clks */
+ temp = 0xD1;
+ rc = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp);
+ if (rc) {
+ pr_err("Error %d writing %d to CHG_TEST\n", rc, temp);
+ goto release_lpm_lock;
+ }
- /* Wait to come out of LPM */
+ /* force 19.2Mhz before reading */
+ temp = 0xD3;
+ rc = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp);
+ if (rc) {
+ pr_err("Error %d writing %d to CHG_TEST\n", rc, temp);
+ goto release_lpm_lock;
+ }
+
+ rc = pm8xxx_writeb(chip->dev->parent, addr, reg);
+ if (rc) {
+ pr_err("failed: addr=%03X, rc=%d\n", addr, rc);
+ goto release_lpm_lock;
+ }
+
+ /* no clks */
+ temp = 0xD1;
+ rc = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp);
+ if (rc) {
+ pr_err("Error %d writing %d to CHG_TEST\n", rc, temp);
+ goto release_lpm_lock;
+ }
+
+ /* switch to hw clk selection */
+ temp = 0xD0;
+ rc = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp);
+ if (rc) {
+ pr_err("Error %d writing %d to CHG_TEST\n", rc, temp);
+ goto release_lpm_lock;
+ }
+
udelay(200);
- }
- rc = pm8xxx_writeb(chip->dev->parent, addr, reg);
- if (rc) {
- pr_err("pm_chg_write failed: addr=%03X, rc=%d\n", addr, rc);
- goto lpm_err;
- }
-
- /* Enable LPM */
- if (chip->lockup_lpm_wrkarnd)
- rc = pm8921_chg_set_lpm(chip, 1);
-
-lpm_err:
- if (chip->lockup_lpm_wrkarnd)
+release_lpm_lock:
spin_unlock_irqrestore(&lpm_lock, flags);
-
+ } else {
+ rc = pm8xxx_writeb(chip->dev->parent, addr, reg);
+ if (rc)
+ pr_err("failed: addr=%03X, rc=%d\n", addr, rc);
+ }
return rc;
}
@@ -441,68 +468,175 @@
static int pm_chg_get_fsm_state(struct pm8921_chg_chip *chip)
{
u8 temp;
- int err, ret = 0;
+ unsigned long flags = 0;
+ int err = 0, ret = 0;
+
+ if (chip->lockup_lpm_wrkarnd) {
+ spin_lock_irqsave(&lpm_lock, flags);
+
+ /*
+ * This delay is to prevent exit out of 32khz mode within
+ * 200uS. It could be that chg was removed just few uS before
+ * this gets called.
+ */
+ udelay(200);
+ /* no clks */
+ temp = 0xD1;
+ err = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp);
+ if (err) {
+ pr_err("Error %d writing %d to CHG_TEST\n", err, temp);
+ goto err_out;
+ }
+
+ /* force 19.2Mhz before reading */
+ temp = 0xD3;
+ err = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp);
+ if (err) {
+ pr_err("Error %d writing %d to CHG_TEST\n", err, temp);
+ goto err_out;
+ }
+ }
temp = CAPTURE_FSM_STATE_CMD;
- err = pm_chg_write(chip, CHG_TEST, temp);
+ err = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp);
if (err) {
pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
- return err;
+ goto err_out;
}
temp = READ_BANK_7;
- err = pm_chg_write(chip, CHG_TEST, temp);
+ err = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp);
if (err) {
pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
- return err;
+ goto err_out;
}
err = pm8xxx_readb(chip->dev->parent, CHG_TEST, &temp);
if (err) {
pr_err("pm8xxx_readb fail: addr=%03X, rc=%d\n", CHG_TEST, err);
- return err;
+ goto err_out;
}
/* get the lower 4 bits */
ret = temp & 0xF;
temp = READ_BANK_4;
- err = pm_chg_write(chip, CHG_TEST, temp);
+ err = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp);
if (err) {
pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
- return err;
+ goto err_out;
}
err = pm8xxx_readb(chip->dev->parent, CHG_TEST, &temp);
if (err) {
pr_err("pm8xxx_readb fail: addr=%03X, rc=%d\n", CHG_TEST, err);
- return err;
+ goto err_out;
}
/* get the upper 1 bit */
ret |= (temp & 0x1) << 4;
+
+ if (chip->lockup_lpm_wrkarnd) {
+ /* no clks */
+ temp = 0xD1;
+ err = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp);
+ if (err) {
+ pr_err("Error %d writing %d to CHG_TEST\n", err, temp);
+ goto err_out;
+ }
+
+ /* switch to hw clk selection */
+ temp = 0xD0;
+ err = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp);
+ if (err) {
+ pr_err("Error %d writing %d to CHG_TEST\n", err, temp);
+ goto err_out;
+ }
+
+ udelay(200);
+ }
+
+err_out:
+ if (chip->lockup_lpm_wrkarnd)
+ spin_unlock_irqrestore(&lpm_lock, flags);
+ if (err)
+ return err;
+
return ret;
}
#define READ_BANK_6 0x60
static int pm_chg_get_regulation_loop(struct pm8921_chg_chip *chip)
{
- u8 temp;
- int err;
+ u8 temp, data;
+ unsigned long flags = 0;
+ int err = 0;
+
+ if (chip->lockup_lpm_wrkarnd) {
+ spin_lock_irqsave(&lpm_lock, flags);
+
+ /*
+ * This delay is to prevent exit out of 32khz mode within
+ * 200uS. It could be that chg was removed just few uS before
+ * this gets called.
+ */
+ udelay(200);
+ /* no clks */
+ temp = 0xD1;
+ err = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp);
+ if (err) {
+ pr_err("Error %d writing %d to CHG_TEST\n", err, temp);
+ goto err_out;
+ }
+
+ /* force 19.2Mhz before reading */
+ temp = 0xD3;
+ err = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp);
+ if (err) {
+ pr_err("Error %d writing %d to CHG_TEST\n", err, temp);
+ goto err_out;
+ }
+ }
temp = READ_BANK_6;
- err = pm_chg_write(chip, CHG_TEST, temp);
+ err = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp);
if (err) {
pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
- return err;
+ goto err_out;
}
- err = pm8xxx_readb(chip->dev->parent, CHG_TEST, &temp);
+ err = pm8xxx_readb(chip->dev->parent, CHG_TEST, &data);
if (err) {
pr_err("pm8xxx_readb fail: addr=%03X, rc=%d\n", CHG_TEST, err);
- return err;
+ goto err_out;
}
+ if (chip->lockup_lpm_wrkarnd) {
+ /* no clks */
+ temp = 0xD1;
+ err = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp);
+ if (err) {
+ pr_err("Error %d writing %d to CHG_TEST\n", err, temp);
+ goto err_out;
+ }
+
+ /* switch to hw clk selection */
+ temp = 0xD0;
+ err = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp);
+ if (err) {
+ pr_err("Error %d writing %d to CHG_TEST\n", err, temp);
+ goto err_out;
+ }
+
+ udelay(200);
+ }
+
+err_out:
+ if (chip->lockup_lpm_wrkarnd)
+ spin_unlock_irqrestore(&lpm_lock, flags);
+ if (err)
+ return err;
+
/* return the lower 4 bits */
- return temp & CHG_ALL_LOOPS;
+ return data & CHG_ALL_LOOPS;
}
#define CHG_USB_SUSPEND_BIT BIT(2)
diff --git a/drivers/power/qpnp-charger.c b/drivers/power/qpnp-charger.c
index 13ba50b..e2ba042 100644
--- a/drivers/power/qpnp-charger.c
+++ b/drivers/power/qpnp-charger.c
@@ -70,7 +70,7 @@
#define CHGR_CHG_WDOG_PET 0x64
#define CHGR_CHG_WDOG_EN 0x65
#define CHGR_IR_DROP_COMPEN 0x67
-#define CHGR_USB_IUSB_MAX 0x44
+#define CHGR_I_MAX_REG 0x44
#define CHGR_USB_USB_SUSP 0x47
#define CHGR_USB_USB_OTG_CTL 0x48
#define CHGR_USB_ENUM_T_STOP 0x4E
@@ -172,6 +172,8 @@
* @resume_voltage_mv: voltage at which the battery resumes charging
* @term_current: the charging based term current
* @safe_current: battery safety current setting
+ * @maxinput_usb_ma: Maximum Input current USB
+ * @maxinput_dc_ma: Maximum Input current DC
* @revision: PMIC revision
* @thermal_levels amount of thermal mitigation levels
* @thermal_mitigation thermal mitigation level values
@@ -196,6 +198,7 @@
u16 misc_base;
u16 freq_base;
unsigned int usbin_valid_irq;
+ unsigned int dcin_valid_irq;
unsigned int chg_done_irq;
unsigned int chg_failed_irq;
bool chg_done;
@@ -209,6 +212,8 @@
unsigned int min_voltage_mv;
unsigned int resume_voltage_mv;
unsigned int term_current;
+ unsigned int maxinput_usb_ma;
+ unsigned int maxinput_dc_ma;
unsigned int safe_current;
unsigned int revision;
unsigned int thermal_levels;
@@ -347,36 +352,73 @@
return (dcin_valid_rt_sts & DCIN_VALID_IRQ) ? 1 : 0;
}
-#define QPNP_CHG_IUSB_MAX_MIN_100 100
-#define QPNP_CHG_IUSB_MAX_MIN_150 150
-#define QPNP_CHG_IUSB_MAX_MIN_MA 200
-#define QPNP_CHG_IUSB_MAX_MAX_MA 2500
-#define QPNP_CHG_IUSB_MAX_STEP_MA 100
+#define QPNP_CHG_I_MAX_MIN_100 100
+#define QPNP_CHG_I_MAX_MIN_150 150
+#define QPNP_CHG_I_MAX_MIN_MA 200
+#define QPNP_CHG_I_MAX_MAX_MA 2500
+#define QPNP_CHG_I_MAXSTEP_MA 100
+static int
+qpnp_chg_idcmax_set(struct qpnp_chg_chip *chip, int mA)
+{
+ int rc = 0;
+ u8 dc = 0;
+
+ if (mA < QPNP_CHG_I_MAX_MIN_100
+ || mA > QPNP_CHG_I_MAX_MAX_MA) {
+ pr_err("bad mA=%d asked to set\n", mA);
+ return -EINVAL;
+ }
+
+ if (mA == QPNP_CHG_I_MAX_MIN_100) {
+ dc = 0x00;
+ pr_debug("current=%d setting %02x\n", mA, dc);
+ return qpnp_chg_write(chip, &dc,
+ chip->dc_chgpth_base + CHGR_I_MAX_REG, 1);
+ } else if (mA == QPNP_CHG_I_MAX_MIN_150) {
+ dc = 0x01;
+ pr_debug("current=%d setting %02x\n", mA, dc);
+ return qpnp_chg_write(chip, &dc,
+ chip->dc_chgpth_base + CHGR_I_MAX_REG, 1);
+ }
+
+ dc = mA / QPNP_CHG_I_MAXSTEP_MA;
+
+ pr_debug("current=%d setting 0x%x\n", mA, dc);
+ rc = qpnp_chg_write(chip, &dc,
+ chip->dc_chgpth_base + CHGR_I_MAX_REG, 1);
+
+ return rc;
+}
+
static int
qpnp_chg_iusbmax_set(struct qpnp_chg_chip *chip, int mA)
{
int rc = 0;
u8 usb_reg = 0, temp = 8;
- if (mA == QPNP_CHG_IUSB_MAX_MIN_100) {
- usb_reg = 0x00;
- pr_debug("current=%d setting %02x\n", mA, usb_reg);
- return qpnp_chg_write(chip, &usb_reg,
- chip->usb_chgpth_base + CHGR_USB_IUSB_MAX, 1);
- } else if (mA == QPNP_CHG_IUSB_MAX_MIN_150) {
- usb_reg = 0x01;
- pr_debug("current=%d setting %02x\n", mA, usb_reg);
- return qpnp_chg_write(chip, &usb_reg,
- chip->usb_chgpth_base + CHGR_USB_IUSB_MAX, 1);
- }
-
- if (mA < QPNP_CHG_IUSB_MAX_MIN_MA
- || mA > QPNP_CHG_IUSB_MAX_MAX_MA) {
+ if (mA < QPNP_CHG_I_MAX_MIN_100
+ || mA > QPNP_CHG_I_MAX_MAX_MA) {
pr_err("bad mA=%d asked to set\n", mA);
return -EINVAL;
}
- usb_reg = mA / QPNP_CHG_IUSB_MAX_STEP_MA;
+ if (mA == QPNP_CHG_I_MAX_MIN_100) {
+ usb_reg = 0x00;
+ pr_debug("current=%d setting %02x\n", mA, usb_reg);
+ return qpnp_chg_write(chip, &usb_reg,
+ chip->usb_chgpth_base + CHGR_I_MAX_REG, 1);
+ } else if (mA == QPNP_CHG_I_MAX_MIN_150) {
+ usb_reg = 0x01;
+ pr_debug("current=%d setting %02x\n", mA, usb_reg);
+ return qpnp_chg_write(chip, &usb_reg,
+ chip->usb_chgpth_base + CHGR_I_MAX_REG, 1);
+ }
+
+ /* Impose input current limit */
+ if (chip->maxinput_usb_ma)
+ mA = (chip->maxinput_usb_ma) <= mA ? chip->maxinput_usb_ma : mA;
+
+ usb_reg = mA / QPNP_CHG_I_MAXSTEP_MA;
if (chip->flags & CHG_FLAGS_VCP_WA) {
temp = 0xA5;
@@ -389,7 +431,7 @@
pr_debug("current=%d setting 0x%x\n", mA, usb_reg);
rc = qpnp_chg_write(chip, &usb_reg,
- chip->usb_chgpth_base + CHGR_USB_IUSB_MAX, 1);
+ chip->usb_chgpth_base + CHGR_I_MAX_REG, 1);
if (chip->flags & CHG_FLAGS_VCP_WA) {
temp = 0xA5;
@@ -439,6 +481,23 @@
return IRQ_HANDLED;
}
+static irqreturn_t
+qpnp_chg_dc_dcin_valid_irq_handler(int irq, void *_chip)
+{
+ struct qpnp_chg_chip *chip = _chip;
+ int dc_present;
+
+ dc_present = qpnp_chg_is_dc_chg_plugged_in(chip);
+ pr_debug("dcin-valid triggered: %d\n", dc_present);
+
+ if (chip->dc_present ^ dc_present) {
+ chip->dc_present = dc_present;
+ power_supply_changed(&chip->dc_psy);
+ }
+
+ return IRQ_HANDLED;
+}
+
#define CHGR_CHG_FAILED_BIT BIT(7)
static irqreturn_t
qpnp_chg_chgr_chg_failed_irq_handler(int irq, void *_chip)
@@ -857,12 +916,12 @@
chip->usb_psy->get_property(chip->usb_psy,
POWER_SUPPLY_PROP_CURRENT_MAX, &ret);
qpnp_chg_iusbmax_set(chip, ret.intval / 1000);
- if ((ret.intval / 1000) <= QPNP_CHG_IUSB_MAX_MIN_MA)
+ if ((ret.intval / 1000) <= QPNP_CHG_I_MAX_MIN_MA)
qpnp_chg_usb_suspend_enable(chip, 1);
else
qpnp_chg_usb_suspend_enable(chip, 0);
} else {
- qpnp_chg_iusbmax_set(chip, QPNP_CHG_IUSB_MAX_MIN_100);
+ qpnp_chg_iusbmax_set(chip, QPNP_CHG_I_MAX_MIN_100);
qpnp_chg_usb_suspend_enable(chip, 0);
}
@@ -1283,6 +1342,23 @@
break;
case SMBB_DC_CHGPTH_SUBTYPE:
+ chip->dcin_valid_irq = spmi_get_irq_byname(chip->spmi,
+ spmi_resource, "dcin-valid");
+ if (chip->dcin_valid_irq < 0) {
+ pr_err("Unable to get dcin irq\n");
+ return -ENXIO;
+ }
+ rc = devm_request_irq(chip->dev, chip->dcin_valid_irq,
+ qpnp_chg_dc_dcin_valid_irq_handler,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ "chg_dcin_valid", chip);
+ if (rc < 0) {
+ pr_err("Can't request %d dcinvalid for chg: %d\n",
+ chip->dcin_valid_irq, rc);
+ return -ENXIO;
+ }
+
+ enable_irq_wake(chip->dcin_valid_irq);
break;
case SMBB_BOOST_SUBTYPE:
break;
@@ -1394,6 +1470,33 @@
goto fail_chg_enable;
}
+ /* Get the ibatsafe property */
+ rc = of_property_read_u32(spmi->dev.of_node,
+ "qcom,chg-vbatdet-mv",
+ &chip->resume_voltage_mv);
+ if (rc) {
+ pr_err("Error reading vbatdet property %d\n", rc);
+ goto fail_chg_enable;
+ }
+
+ /* Get the maxinput-dc-ma property */
+ rc = of_property_read_u32(spmi->dev.of_node,
+ "qcom,chg-maxinput-dc-ma",
+ &chip->maxinput_dc_ma);
+ if (rc && rc != -EINVAL) {
+ pr_err("Error reading maxinput-dc-ma property %d\n", rc);
+ goto fail_chg_enable;
+ }
+
+ /* Get the maxinput-usb-ma property */
+ rc = of_property_read_u32(spmi->dev.of_node,
+ "qcom,chg-maxinput-usb-ma",
+ &chip->maxinput_usb_ma);
+ if (rc && rc != -EINVAL) {
+ pr_err("Error reading maxinput-usb-ma property %d\n", rc);
+ goto fail_chg_enable;
+ }
+
/* Get the charging-disabled property */
chip->charging_disabled = of_property_read_bool(spmi->dev.of_node,
"qcom,chg-charging-disabled");
@@ -1543,16 +1646,16 @@
chip->batt_psy.external_power_changed =
qpnp_batt_external_power_changed;
- rc = power_supply_register(chip->dev, &chip->dc_psy);
- if (rc < 0) {
- pr_err("power_supply_register usb failed rc = %d\n", rc);
- goto fail_chg_enable;
- }
-
rc = power_supply_register(chip->dev, &chip->batt_psy);
if (rc < 0) {
pr_err("power_supply_register batt failed rc = %d\n", rc);
- goto unregister_dc;
+ goto fail_chg_enable;
+ }
+
+ rc = power_supply_register(chip->dev, &chip->dc_psy);
+ if (rc < 0) {
+ pr_err("power_supply_register usb failed rc = %d\n", rc);
+ goto unregister_batt;
}
/* Turn on appropriate workaround flags */
@@ -1561,6 +1664,14 @@
power_supply_set_present(chip->usb_psy,
qpnp_chg_is_usb_chg_plugged_in(chip));
+ if (chip->maxinput_dc_ma) {
+ rc = qpnp_chg_idcmax_set(chip, chip->maxinput_dc_ma);
+ if (rc) {
+ pr_err("Error setting idcmax property %d\n", rc);
+ goto fail_chg_enable;
+ }
+ }
+
qpnp_chg_charge_en(chip, !chip->charging_disabled);
qpnp_chg_force_run_on_batt(chip, chip->charging_disabled);
@@ -1572,8 +1683,8 @@
get_prop_batt_health(chip));
return 0;
-unregister_dc:
- power_supply_unregister(&chip->dc_psy);
+unregister_batt:
+ power_supply_unregister(&chip->batt_psy);
fail_chg_enable:
kfree(chip->thermal_mitigation);
kfree(chip);
diff --git a/drivers/thermal/msm8974-tsens.c b/drivers/thermal/msm8974-tsens.c
index c2e1731..e37b3c4 100644
--- a/drivers/thermal/msm8974-tsens.c
+++ b/drivers/thermal/msm8974-tsens.c
@@ -69,6 +69,10 @@
#define TSENS_MAIN_CALIB_ADDR_RANGE 6
#define TSENS_BACKUP_CALIB_ADDR_RANGE 4
+#define TSENS_EEPROM_8X26_1(n) ((n) + 0x1c0)
+#define TSENS_EEPROM_8X26_2(n) ((n) + 0x444)
+#define TSENS_8X26_MAIN_CALIB_ADDR_RANGE 4
+
/* TSENS calibration Mask data */
#define TSENS_BASE1_MASK 0xff
#define TSENS0_POINT1_MASK 0x3f00
@@ -151,6 +155,41 @@
#define TSENS10_POINT2_MASK 0xfc0000
#define TSENS10_POINT2_BACKUP_MASK 0x3f000000
+#define TSENS_8X26_BASE0_MASK 0x1fe000
+#define TSENS0_8X26_POINT1_MASK 0x7f00000
+#define TSENS1_8X26_POINT1_MASK 0x3f
+#define TSENS2_8X26_POINT1_MASK 0xfc0
+#define TSENS3_8X26_POINT1_MASK 0x3f000
+#define TSENS4_8X26_POINT1_MASK 0xfc0000
+#define TSENS5_8X26_POINT1_MASK 0x3f000000
+#define TSENS6_8X26_POINT1_MASK 0x3f00000
+#define TSENS_8X26_TSENS_CAL_SEL 0xe0000000
+#define TSENS_8X26_BASE1_MASK 0xff
+#define TSENS0_8X26_POINT2_MASK 0x3f00
+#define TSENS1_8X26_POINT2_MASK 0xfc00
+#define TSENS2_8X26_POINT2_MASK 0x3f00000
+#define TSENS3_8X26_POINT2_MASK 0xfc000000
+#define TSENS4_8X26_POINT2_MASK 0xfc000000
+#define TSENS5_8X26_POINT2_MASK 0x3f00000
+#define TSENS6_8X26_POINT2_MASK 0x7e0000
+
+#define TSENS_8X26_CAL_SEL_SHIFT 29
+#define TSENS_8X26_BASE0_SHIFT 13
+#define TSENS0_8X26_POINT1_SHIFT 21
+#define TSENS2_8X26_POINT1_SHIFT 6
+#define TSENS3_8X26_POINT1_SHIFT 12
+#define TSENS4_8X26_POINT1_SHIFT 18
+#define TSENS5_8X26_POINT1_SHIFT 24
+#define TSENS6_8X26_POINT1_SHIFT 20
+
+#define TSENS0_8X26_POINT2_SHIFT 8
+#define TSENS1_8X26_POINT2_SHIFT 14
+#define TSENS2_8X26_POINT2_SHIFT 20
+#define TSENS3_8X26_POINT2_SHIFT 26
+#define TSENS4_8X26_POINT2_SHIFT 20
+#define TSENS5_8X26_POINT2_SHIFT 26
+#define TSENS6_8X26_POINT2_SHIFT 17
+
#define TSENS_BIT_APPEND 0x3
#define TSENS_CAL_DEGC_POINT1 30
#define TSENS_CAL_DEGC_POINT2 120
@@ -171,6 +210,13 @@
#define TSENS_QFPROM_BACKUP_REDUN_SEL 0xe0000000
#define TSENS_QFPROM_BACKUP_REDUN_SHIFT 29
+enum tsens_calib_fuse_map_type {
+ TSENS_CALIB_FUSE_MAP_8974 = 0,
+ TSENS_CALIB_FUSE_MAP_8X26,
+ TSENS_CALIB_FUSE_MAP_8X10,
+ TSENS_CALIB_FUSE_MAP_NUM,
+};
+
/* Trips: warm and cool */
enum tsens_trip_type {
TSENS_TRIP_WARM = 0,
@@ -203,6 +249,7 @@
struct resource *res_tsens_mem;
struct resource *res_calib_mem;
struct work_struct tsens_work;
+ uint32_t calib_mode;
struct tsens_tm_device_sensor sensor[0];
};
@@ -546,7 +593,162 @@
TSENS_UPPER_LOWER_INTERRUPT_CTRL(tmdev->tsens_addr));
}
-static int tsens_calib_sensors(void)
+static int tsens_calib_8x26_sensors(void)
+{
+ int i, tsens_base0_data = 0, tsens0_point1 = 0, tsens1_point1 = 0;
+ int tsens2_point1 = 0, tsens3_point1 = 0, tsens4_point1 = 0;
+ int tsens5_point1 = 0, tsens6_point1 = 0, tsens6_point2 = 0;
+ int tsens0_point2 = 0, tsens1_point2 = 0, tsens2_point2 = 0;
+ int tsens3_point2 = 0, tsens4_point2 = 0, tsens5_point2 = 0;
+ int tsens_base1_data = 0, tsens_calibration_mode = 0;
+ uint32_t calib_data[6];
+ uint32_t calib_tsens_point1_data[7], calib_tsens_point2_data[7];
+
+ if (tmdev->calibration_less_mode)
+ goto calibration_less_mode;
+
+ for (i = 0; i < TSENS_8X26_MAIN_CALIB_ADDR_RANGE; i++)
+ calib_data[i] = readl_relaxed(
+ (TSENS_EEPROM_8X26_1(tmdev->tsens_calib_addr))
+ + (i * TSENS_SN_ADDR_OFFSET));
+ calib_data[4] = readl_relaxed(
+ (TSENS_EEPROM_8X26_2(tmdev->tsens_calib_addr)));
+ calib_data[5] = readl_relaxed(
+ (TSENS_EEPROM_8X26_2(tmdev->tsens_calib_addr)) + 0x8);
+
+ tsens_calibration_mode = calib_data[5] & TSENS_8X26_TSENS_CAL_SEL;
+
+ if ((tsens_calibration_mode == TSENS_TWO_POINT_CALIB) ||
+ (tsens_calibration_mode == TSENS_ONE_POINT_CALIB_OPTION_2)) {
+ pr_debug("backup one point calibrationless mode\n");
+ tsens_base0_data = (calib_data[0] & TSENS_8X26_BASE0_MASK)
+ >> TSENS_8X26_BASE0_SHIFT;
+ tsens0_point1 = (calib_data[0] & TSENS0_8X26_POINT1_MASK) >>
+ TSENS0_8X26_POINT1_SHIFT;
+ tsens1_point1 = calib_data[1] & TSENS1_8X26_POINT1_MASK;
+ tsens2_point1 = (calib_data[1] & TSENS2_8X26_POINT1_MASK) >>
+ TSENS2_8X26_POINT1_SHIFT;
+ tsens3_point1 = (calib_data[1] & TSENS3_8X26_POINT1_MASK) >>
+ TSENS3_8X26_POINT1_SHIFT;
+ tsens4_point1 = (calib_data[1] & TSENS4_8X26_POINT1_MASK) >>
+ TSENS4_8X26_POINT1_SHIFT;
+ tsens5_point1 = (calib_data[1] & TSENS5_8X26_POINT1_MASK) >>
+ TSENS5_8X26_POINT1_SHIFT;
+ tsens6_point1 = (calib_data[2] & TSENS6_8X26_POINT1_MASK) >>
+ TSENS6_8X26_POINT1_SHIFT;
+ } else
+ goto calibration_less_mode;
+
+ if (tsens_calibration_mode == TSENS_TWO_POINT_CALIB) {
+ pr_debug("backup two point calibrationless mode\n");
+ tsens_base1_data = (calib_data[3] & TSENS_8X26_BASE1_MASK);
+ tsens0_point2 = (calib_data[3] & TSENS0_8X26_POINT2_MASK) >>
+ TSENS0_8X26_POINT2_SHIFT;
+ tsens1_point2 = (calib_data[3] & TSENS1_8X26_POINT2_MASK) >>
+ TSENS1_8X26_POINT2_SHIFT;
+ tsens2_point2 = (calib_data[3] & TSENS2_8X26_POINT2_MASK) >>
+ TSENS2_8X26_POINT2_SHIFT;
+ tsens3_point2 = (calib_data[3] & TSENS3_8X26_POINT2_MASK) >>
+ TSENS3_8X26_POINT2_SHIFT;
+ tsens4_point2 = (calib_data[4] & TSENS4_8X26_POINT2_MASK) >>
+ TSENS4_8X26_POINT2_SHIFT;
+ tsens5_point2 = (calib_data[4] & TSENS5_8X26_POINT2_MASK) >>
+ TSENS5_8X26_POINT2_SHIFT;
+ tsens6_point2 = (calib_data[5] & TSENS6_8X26_POINT2_MASK) >>
+ TSENS6_8X26_POINT2_SHIFT;
+ }
+
+ if (tsens_calibration_mode == 0) {
+calibration_less_mode:
+ pr_debug("TSENS is calibrationless mode\n");
+ for (i = 0; i < tmdev->tsens_num_sensor; i++)
+ calib_tsens_point2_data[i] = 780;
+ calib_tsens_point1_data[0] = 502;
+ calib_tsens_point1_data[1] = 509;
+ calib_tsens_point1_data[2] = 503;
+ calib_tsens_point1_data[3] = 509;
+ calib_tsens_point1_data[4] = 505;
+ calib_tsens_point1_data[5] = 509;
+ calib_tsens_point1_data[6] = 507;
+ goto compute_intercept_slope;
+ }
+
+ if ((tsens_calibration_mode == TSENS_ONE_POINT_CALIB_OPTION_2) ||
+ (tsens_calibration_mode == TSENS_TWO_POINT_CALIB)) {
+ pr_debug("one and two point calibration calculation\n");
+ calib_tsens_point1_data[0] =
+ ((((tsens_base0_data) + tsens0_point1) << 2) |
+ TSENS_BIT_APPEND);
+ calib_tsens_point1_data[1] =
+ ((((tsens_base0_data) + tsens1_point1) << 2) |
+ TSENS_BIT_APPEND);
+ calib_tsens_point1_data[2] =
+ ((((tsens_base0_data) + tsens2_point1) << 2) |
+ TSENS_BIT_APPEND);
+ calib_tsens_point1_data[3] =
+ ((((tsens_base0_data) + tsens3_point1) << 2) |
+ TSENS_BIT_APPEND);
+ calib_tsens_point1_data[4] =
+ ((((tsens_base0_data) + tsens4_point1) << 2) |
+ TSENS_BIT_APPEND);
+ calib_tsens_point1_data[5] =
+ ((((tsens_base0_data) + tsens5_point1) << 2) |
+ TSENS_BIT_APPEND);
+ calib_tsens_point1_data[6] =
+ ((((tsens_base0_data) + tsens6_point1) << 2) |
+ TSENS_BIT_APPEND);
+ }
+
+ if (tsens_calibration_mode == TSENS_TWO_POINT_CALIB) {
+ pr_debug("two point calibration calculation\n");
+ calib_tsens_point2_data[0] =
+ (((tsens_base1_data + tsens0_point2) << 2) |
+ TSENS_BIT_APPEND);
+ calib_tsens_point2_data[1] =
+ (((tsens_base1_data + tsens1_point2) << 2) |
+ TSENS_BIT_APPEND);
+ calib_tsens_point2_data[2] =
+ (((tsens_base1_data + tsens2_point2) << 2) |
+ TSENS_BIT_APPEND);
+ calib_tsens_point2_data[3] =
+ (((tsens_base1_data + tsens3_point2) << 2) |
+ TSENS_BIT_APPEND);
+ calib_tsens_point2_data[4] =
+ (((tsens_base1_data + tsens4_point2) << 2) |
+ TSENS_BIT_APPEND);
+ calib_tsens_point2_data[5] =
+ (((tsens_base1_data + tsens5_point2) << 2) |
+ TSENS_BIT_APPEND);
+ calib_tsens_point2_data[6] =
+ (((tsens_base1_data + tsens6_point2) << 2) |
+ TSENS_BIT_APPEND);
+ }
+
+compute_intercept_slope:
+ for (i = 0; i < tmdev->tsens_num_sensor; i++) {
+ int32_t num = 0, den = 0;
+ tmdev->sensor[i].calib_data_point2 = calib_tsens_point2_data[i];
+ tmdev->sensor[i].calib_data_point1 = calib_tsens_point1_data[i];
+ if (tsens_calibration_mode == TSENS_TWO_POINT_CALIB) {
+ /* slope (m) = adc_code2 - adc_code1 (y2 - y1)/
+ temp_120_degc - temp_30_degc (x2 - x1) */
+ num = tmdev->sensor[i].calib_data_point2 -
+ tmdev->sensor[i].calib_data_point1;
+ num *= tmdev->tsens_factor;
+ den = TSENS_CAL_DEGC_POINT2 - TSENS_CAL_DEGC_POINT1;
+ tmdev->sensor[i].slope_mul_tsens_factor = num/den;
+ }
+ tmdev->sensor[i].offset = (tmdev->sensor[i].calib_data_point1 *
+ tmdev->tsens_factor) - (TSENS_CAL_DEGC_POINT1 *
+ tmdev->sensor[i].slope_mul_tsens_factor);
+ INIT_WORK(&tmdev->sensor[i].work, notify_uspace_tsens_fn);
+ tmdev->prev_reading_avail = false;
+ }
+
+ return 0;
+}
+
+static int tsens_calib_8974_sensors(void)
{
int i, tsens_base1_data = 0, tsens0_point1 = 0, tsens1_point1 = 0;
int tsens2_point1 = 0, tsens3_point1 = 0, tsens4_point1 = 0;
@@ -877,12 +1079,30 @@
return 0;
}
+static int tsens_calib_sensors(void)
+{
+ int rc = 0;
+
+ if (!tmdev)
+ return -ENODEV;
+
+ if (tmdev->calib_mode == TSENS_CALIB_FUSE_MAP_8974)
+ rc = tsens_calib_8974_sensors();
+ else if (tmdev->calib_mode == TSENS_CALIB_FUSE_MAP_8X26)
+ rc = tsens_calib_8x26_sensors();
+ else
+ rc = -ENODEV;
+
+ return rc;
+}
+
static int get_device_tree_data(struct platform_device *pdev)
{
const struct device_node *of_node = pdev->dev.of_node;
struct resource *res_mem = NULL;
u32 *tsens_slope_data;
- u32 rc = 0, i, tsens_num_sensors;
+ u32 rc = 0, i, tsens_num_sensors, calib_type;
+ const char *tsens_calib_mode;
rc = of_property_read_u32(of_node,
"qcom,sensors", &tsens_num_sensors);
@@ -905,6 +1125,19 @@
return rc;
};
+ tsens_calib_mode = of_get_property(of_node,
+ "qcom,calib-mode", NULL);
+ if (!strncmp(tsens_calib_mode, "fuse_map1", 9))
+ calib_type = TSENS_CALIB_FUSE_MAP_8974;
+ else if (!strncmp(tsens_calib_mode, "fuse_map2", 9))
+ calib_type = TSENS_CALIB_FUSE_MAP_8X26;
+ else if (!strncmp(tsens_calib_mode, "fuse_map3", 9))
+ calib_type = TSENS_CALIB_FUSE_MAP_8X10;
+ else {
+ pr_err("%s: Invalid calibration property\n", __func__);
+ return -EINVAL;
+ }
+
tmdev = devm_kzalloc(&pdev->dev,
sizeof(struct tsens_tm_device) +
tsens_num_sensors *
@@ -921,6 +1154,7 @@
tmdev->tsens_num_sensor = tsens_num_sensors;
tmdev->calibration_less_mode = of_property_read_bool(of_node,
"qcom,calibration-less-mode");
+ tmdev->calib_mode = calib_type;
tmdev->tsens_irq = platform_get_irq(pdev, 0);
if (tmdev->tsens_irq < 0) {
@@ -1085,6 +1319,8 @@
for (i = 0; i < tmdev->tsens_num_sensor; i++)
thermal_zone_device_unregister(tmdev->sensor[i].tz_dev);
goto fail;
+ } else {
+ enable_irq_wake(tmdev->tsens_irq);
}
platform_set_drvdata(pdev, tmdev);
diff --git a/drivers/thermal/msm_thermal.c b/drivers/thermal/msm_thermal.c
index 0e3daeb..5aca48d 100644
--- a/drivers/thermal/msm_thermal.c
+++ b/drivers/thermal/msm_thermal.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
@@ -81,7 +81,7 @@
{
static int limit_init;
struct tsens_device tsens_dev;
- unsigned long temp = 0;
+ long temp = 0;
uint32_t max_freq = limited_max_freq;
int cpu = 0;
int ret = 0;
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c
index 4b6ba67..a27322e 100644
--- a/drivers/tty/serial/msm_serial_hs.c
+++ b/drivers/tty/serial/msm_serial_hs.c
@@ -1060,6 +1060,14 @@
}
if (!is_blsp_uart(msm_uport) && msm_uport->rx.flush != FLUSH_SHUTDOWN)
msm_uport->rx.flush = FLUSH_STOP;
+
+ /* During uart port close, due to spurious rx stale interrupt,
+ * the rx state machine is causing BUG_ON to be hit in
+ * msm_hs_shutdown causing kernel panic.
+ * Hence fixing the same by handling the rx state machine.
+ */
+ if (is_blsp_uart(msm_uport) && msm_uport->rx.flush == FLUSH_DATA_READY)
+ msm_uport->rx.flush = FLUSH_SHUTDOWN;
}
/* Transmit the next chunk of data */
diff --git a/drivers/usb/dwc3/debug.h b/drivers/usb/dwc3/debug.h
index 5894ee8..b156c5f 100644
--- a/drivers/usb/dwc3/debug.h
+++ b/drivers/usb/dwc3/debug.h
@@ -39,9 +39,24 @@
#include "core.h"
#ifdef CONFIG_DEBUG_FS
+extern void dbg_event(u8, const char*, int);
+extern void dbg_print(u8, const char*, int, const char*);
+extern void dbg_done(u8, const u32, int);
+extern void dbg_queue(u8, const struct usb_request*, int);
+extern void dbg_setup(u8, const struct usb_ctrlrequest*);
extern int dwc3_debugfs_init(struct dwc3 *);
extern void dwc3_debugfs_exit(struct dwc3 *);
#else
+static inline void dbg_event(u8, const char*, int)
+{ }
+static inline void dbg_print(u8, const char*, int, const char*)
+{ }
+static inline void dbg_done(u8, const u32, int)
+{ }
+static inline void dbg_queue(u8, const struct usb_request*, int)
+{ }
+static inline void dbg_setup(u8, const struct usb_ctrlrequest*)
+{ }
static inline int dwc3_debugfs_init(struct dwc3 *d)
{ return 0; }
static inline void dwc3_debugfs_exit(struct dwc3 *d)
diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c
index be4eff7..93504eb 100644
--- a/drivers/usb/dwc3/debugfs.c
+++ b/drivers/usb/dwc3/debugfs.c
@@ -36,6 +36,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/ptrace.h>
@@ -652,6 +653,382 @@
.release = single_release,
};
+static int ep_num;
+static ssize_t dwc3_store_ep_num(struct file *file, const char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ struct seq_file *s = file->private_data;
+ struct dwc3 *dwc = s->private;
+ char kbuf[10];
+ unsigned int num, dir;
+ unsigned long flags;
+
+ memset(kbuf, 0, 10);
+
+ if (copy_from_user(kbuf, ubuf, count > 10 ? 10 : count))
+ return -EFAULT;
+
+ if (sscanf(kbuf, "%u %u", &num, &dir) != 2)
+ return -EINVAL;
+
+ spin_lock_irqsave(&dwc->lock, flags);
+ ep_num = (num << 1) + dir;
+ spin_unlock_irqrestore(&dwc->lock, flags);
+
+ return count;
+}
+
+static int dwc3_ep_req_list_show(struct seq_file *s, void *unused)
+{
+ struct dwc3 *dwc = s->private;
+ struct dwc3_ep *dep;
+ struct dwc3_request *req = NULL;
+ struct list_head *ptr = NULL;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dwc->lock, flags);
+ dep = dwc->eps[ep_num];
+
+ seq_printf(s, "%s request list: flags: 0x%x\n", dep->name, dep->flags);
+ list_for_each(ptr, &dep->request_list) {
+ req = list_entry(ptr, struct dwc3_request, list);
+
+ seq_printf(s, "req:0x%p len: %d sts: %d dma:0x%x num_sgs: %d\n",
+ req, req->request.length, req->request.status,
+ req->request.dma, req->request.num_sgs);
+ }
+ spin_unlock_irqrestore(&dwc->lock, flags);
+
+ return 0;
+}
+
+static int dwc3_ep_req_list_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, dwc3_ep_req_list_show, inode->i_private);
+}
+
+static const struct file_operations dwc3_ep_req_list_fops = {
+ .open = dwc3_ep_req_list_open,
+ .write = dwc3_store_ep_num,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int dwc3_ep_queued_req_show(struct seq_file *s, void *unused)
+{
+ struct dwc3 *dwc = s->private;
+ struct dwc3_ep *dep;
+ struct dwc3_request *req = NULL;
+ struct list_head *ptr = NULL;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dwc->lock, flags);
+ dep = dwc->eps[ep_num];
+
+ seq_printf(s, "%s queued reqs to HW: flags:0x%x\n", dep->name,
+ dep->flags);
+ list_for_each(ptr, &dep->req_queued) {
+ req = list_entry(ptr, struct dwc3_request, list);
+
+ seq_printf(s, "req:0x%p len:%d sts:%d dma:%x nsg:%d trb:0x%p\n",
+ req, req->request.length, req->request.status,
+ req->request.dma, req->request.num_sgs, req->trb);
+ }
+ spin_unlock_irqrestore(&dwc->lock, flags);
+
+ return 0;
+}
+
+static int dwc3_ep_queued_req_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, dwc3_ep_queued_req_show, inode->i_private);
+}
+
+const struct file_operations dwc3_ep_req_queued_fops = {
+ .open = dwc3_ep_queued_req_open,
+ .write = dwc3_store_ep_num,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int dwc3_ep_trbs_show(struct seq_file *s, void *unused)
+{
+ struct dwc3 *dwc = s->private;
+ struct dwc3_ep *dep;
+ struct dwc3_trb *trb;
+ unsigned long flags;
+ int j;
+
+ if (!ep_num)
+ return 0;
+
+ spin_lock_irqsave(&dwc->lock, flags);
+ dep = dwc->eps[ep_num];
+
+ seq_printf(s, "%s trb pool: flags:0x%x freeslot:%d busyslot:%d\n",
+ dep->name, dep->flags, dep->free_slot, dep->busy_slot);
+ for (j = 0; j < DWC3_TRB_NUM; j++) {
+ trb = &dep->trb_pool[j];
+ seq_printf(s, "trb:0x%p bph:0x%x bpl:0x%x size:0x%x ctrl: %x\n",
+ trb, trb->bph, trb->bpl, trb->size, trb->ctrl);
+ }
+ spin_unlock_irqrestore(&dwc->lock, flags);
+
+ return 0;
+}
+
+static int dwc3_ep_trbs_list_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, dwc3_ep_trbs_show, inode->i_private);
+}
+
+const struct file_operations dwc3_ep_trb_list_fops = {
+ .open = dwc3_ep_trbs_list_open,
+ .write = dwc3_store_ep_num,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static unsigned int ep_addr_rxdbg_mask;
+module_param(ep_addr_rxdbg_mask, uint, S_IRUGO | S_IWUSR);
+static unsigned int ep_addr_txdbg_mask;
+module_param(ep_addr_txdbg_mask, uint, S_IRUGO | S_IWUSR);
+
+/* Maximum debug message length */
+#define DBG_DATA_MSG 64UL
+
+/* Maximum number of messages */
+#define DBG_DATA_MAX 128UL
+
+static struct {
+ char (buf[DBG_DATA_MAX])[DBG_DATA_MSG]; /* buffer */
+ unsigned idx; /* index */
+ unsigned tty; /* print to console? */
+ rwlock_t lck; /* lock */
+} dbg_dwc3_data = {
+ .idx = 0,
+ .tty = 0,
+ .lck = __RW_LOCK_UNLOCKED(lck)
+};
+
+/**
+ * dbg_dec: decrements debug event index
+ * @idx: buffer index
+ */
+static inline void __maybe_unused dbg_dec(unsigned *idx)
+{
+ *idx = (*idx - 1) % DBG_DATA_MAX;
+}
+
+/**
+ * dbg_inc: increments debug event index
+ * @idx: buffer index
+ */
+static inline void dbg_inc(unsigned *idx)
+{
+ *idx = (*idx + 1) % DBG_DATA_MAX;
+}
+
+#define TIME_BUF_LEN 20
+/*get_timestamp - returns time of day in us */
+static char *get_timestamp(char *tbuf)
+{
+ unsigned long long t;
+ unsigned long nanosec_rem;
+
+ t = cpu_clock(smp_processor_id());
+ nanosec_rem = do_div(t, 1000000000)/1000;
+ scnprintf(tbuf, TIME_BUF_LEN, "[%5lu.%06lu] ", (unsigned long)t,
+ nanosec_rem);
+ return tbuf;
+}
+
+static int allow_dbg_print(u8 ep_num)
+{
+ int dir, num;
+
+ /* allow bus wide events */
+ if (ep_num == 0xff)
+ return 1;
+
+ dir = ep_num & 0x1;
+ num = ep_num >> 1;
+ num = 1 << num;
+
+ if (dir && (num & ep_addr_txdbg_mask))
+ return 1;
+ if (!dir && (num & ep_addr_rxdbg_mask))
+ return 1;
+
+ return 0;
+}
+
+/**
+ * dbg_print: prints the common part of the event
+ * @addr: endpoint address
+ * @name: event name
+ * @status: status
+ * @extra: extra information
+ */
+void dbg_print(u8 ep_num, const char *name, int status, const char *extra)
+{
+ unsigned long flags;
+ char tbuf[TIME_BUF_LEN];
+
+ if (!allow_dbg_print(ep_num))
+ return;
+
+ write_lock_irqsave(&dbg_dwc3_data.lck, flags);
+
+ scnprintf(dbg_dwc3_data.buf[dbg_dwc3_data.idx], DBG_DATA_MSG,
+ "%s\t? %02X %-7.7s %4i ?\t%s\n",
+ get_timestamp(tbuf), ep_num, name, status, extra);
+
+ dbg_inc(&dbg_dwc3_data.idx);
+
+ write_unlock_irqrestore(&dbg_dwc3_data.lck, flags);
+
+ if (dbg_dwc3_data.tty != 0)
+ pr_notice("%s\t? %02X %-7.7s %4i ?\t%s\n",
+ get_timestamp(tbuf), ep_num, name, status, extra);
+}
+
+/**
+ * dbg_done: prints a DONE event
+ * @addr: endpoint address
+ * @td: transfer descriptor
+ * @status: status
+ */
+void dbg_done(u8 ep_num, const u32 count, int status)
+{
+ char msg[DBG_DATA_MSG];
+
+ if (!allow_dbg_print(ep_num))
+ return;
+
+ scnprintf(msg, sizeof(msg), "%d", count);
+ dbg_print(ep_num, "DONE", status, msg);
+}
+
+/**
+ * dbg_event: prints a generic event
+ * @addr: endpoint address
+ * @name: event name
+ * @status: status
+ */
+void dbg_event(u8 ep_num, const char *name, int status)
+{
+ if (!allow_dbg_print(ep_num))
+ return;
+
+ if (name != NULL)
+ dbg_print(ep_num, name, status, "");
+}
+
+/*
+ * dbg_queue: prints a QUEUE event
+ * @addr: endpoint address
+ * @req: USB request
+ * @status: status
+ */
+void dbg_queue(u8 ep_num, const struct usb_request *req, int status)
+{
+ char msg[DBG_DATA_MSG];
+
+ if (!allow_dbg_print(ep_num))
+ return;
+
+ if (req != NULL) {
+ scnprintf(msg, sizeof(msg),
+ "%d %d", !req->no_interrupt, req->length);
+ dbg_print(ep_num, "QUEUE", status, msg);
+ }
+}
+
+/**
+ * dbg_setup: prints a SETUP event
+ * @addr: endpoint address
+ * @req: setup request
+ */
+void dbg_setup(u8 ep_num, const struct usb_ctrlrequest *req)
+{
+ char msg[DBG_DATA_MSG];
+
+ if (!allow_dbg_print(ep_num))
+ return;
+
+ if (req != NULL) {
+ scnprintf(msg, sizeof(msg),
+ "%02X %02X %04X %04X %d", req->bRequestType,
+ req->bRequest, le16_to_cpu(req->wValue),
+ le16_to_cpu(req->wIndex), le16_to_cpu(req->wLength));
+ dbg_print(ep_num, "SETUP", 0, msg);
+ }
+}
+
+/**
+ * store_events: configure if events are going to be also printed to console
+ *
+ */
+static ssize_t dwc3_store_events(struct file *file,
+ const char __user *buf, size_t count, loff_t *ppos)
+{
+ unsigned tty;
+
+ if (buf == NULL) {
+ pr_err("[%s] EINVAL\n", __func__);
+ goto done;
+ }
+
+ if (sscanf(buf, "%u", &tty) != 1 || tty > 1) {
+ pr_err("<1|0>: enable|disable console log\n");
+ goto done;
+ }
+
+ dbg_dwc3_data.tty = tty;
+ pr_info("tty = %u", dbg_dwc3_data.tty);
+
+ done:
+ return count;
+}
+
+static int dwc3_gadget_data_events_show(struct seq_file *s, void *unused)
+{
+ unsigned long flags;
+ unsigned i;
+
+ read_lock_irqsave(&dbg_dwc3_data.lck, flags);
+
+ i = dbg_dwc3_data.idx;
+ if (strnlen(dbg_dwc3_data.buf[i], DBG_DATA_MSG))
+ seq_printf(s, "%s\n", dbg_dwc3_data.buf[i]);
+ for (dbg_inc(&i); i != dbg_dwc3_data.idx; dbg_inc(&i)) {
+ if (!strnlen(dbg_dwc3_data.buf[i], DBG_DATA_MSG))
+ continue;
+ seq_printf(s, "%s\n", dbg_dwc3_data.buf[i]);
+ }
+
+ read_unlock_irqrestore(&dbg_dwc3_data.lck, flags);
+
+ return 0;
+}
+
+static int dwc3_gadget_data_events_open(struct inode *inode, struct file *f)
+{
+ return single_open(f, dwc3_gadget_data_events_show, inode->i_private);
+}
+
+const struct file_operations dwc3_gadget_dbg_data_fops = {
+ .open = dwc3_gadget_data_events_open,
+ .read = seq_read,
+ .write = dwc3_store_events,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
int __devinit dwc3_debugfs_init(struct dwc3 *dwc)
{
struct dentry *root;
@@ -694,6 +1071,33 @@
goto err1;
}
+ file = debugfs_create_file("trbs", S_IRUGO | S_IWUSR, root,
+ dwc, &dwc3_ep_trb_list_fops);
+ if (!file) {
+ ret = -ENOMEM;
+ goto err1;
+ }
+
+ file = debugfs_create_file("requests", S_IRUGO | S_IWUSR, root,
+ dwc, &dwc3_ep_req_list_fops);
+ if (!file) {
+ ret = -ENOMEM;
+ goto err1;
+ }
+
+ file = debugfs_create_file("queued_reqs", S_IRUGO | S_IWUSR, root,
+ dwc, &dwc3_ep_req_queued_fops);
+ if (!file) {
+ ret = -ENOMEM;
+ goto err1;
+ }
+
+ file = debugfs_create_file("events", S_IRUGO | S_IWUSR, root,
+ dwc, &dwc3_gadget_dbg_data_fops);
+ if (!file) {
+ ret = -ENOMEM;
+ goto err1;
+ }
return 0;
err1:
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index 0011a1a..beba33f 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -165,6 +165,7 @@
struct clk *iface_clk;
struct clk *sleep_clk;
struct clk *hsphy_sleep_clk;
+ struct clk *utmi_clk;
struct regulator *hsusb_3p3;
struct regulator *hsusb_1p8;
struct regulator *hsusb_vddcx;
@@ -1636,9 +1637,12 @@
clk_disable_unprepare(mdwc->core_clk);
clk_disable_unprepare(mdwc->iface_clk);
- /* USB PHY no more requires TCXO */
- if (!host_bus_suspend)
+ if (!host_bus_suspend) {
+ clk_disable_unprepare(mdwc->utmi_clk);
+
+ /* USB PHY no more requires TCXO */
clk_disable_unprepare(mdwc->xo_clk);
+ }
if (mdwc->bus_perf_client) {
ret = msm_bus_scale_client_update_request(
@@ -1705,8 +1709,12 @@
dwc3_ssusb_ldo_enable(1);
dwc3_ssusb_config_vddcx(1);
- if (!host_bus_suspend)
+
+ if (!host_bus_suspend) {
dwc3_hsusb_config_vddcx(1);
+ clk_prepare_enable(mdwc->utmi_clk);
+ }
+
clk_prepare_enable(mdwc->ref_clk);
usleep_range(1000, 1200);
@@ -2235,15 +2243,22 @@
}
clk_prepare_enable(msm->hsphy_sleep_clk);
+ msm->utmi_clk = devm_clk_get(&pdev->dev, "utmi_clk");
+ if (IS_ERR(msm->utmi_clk)) {
+ dev_err(&pdev->dev, "failed to get utmi_clk\n");
+ ret = PTR_ERR(msm->utmi_clk);
+ goto disable_sleep_a_clk;
+ }
+ clk_prepare_enable(msm->utmi_clk);
+
msm->ref_clk = devm_clk_get(&pdev->dev, "ref_clk");
if (IS_ERR(msm->ref_clk)) {
dev_err(&pdev->dev, "failed to get ref_clk\n");
ret = PTR_ERR(msm->ref_clk);
- goto disable_sleep_a_clk;
+ goto disable_utmi_clk;
}
clk_prepare_enable(msm->ref_clk);
-
of_get_property(node, "qcom,vdd-voltage-level", &len);
if (len == sizeof(tmp)) {
of_property_read_u32_array(node, "qcom,vdd-voltage-level",
@@ -2526,6 +2541,8 @@
dwc3_ssusb_config_vddcx(0);
disable_ref_clk:
clk_disable_unprepare(msm->ref_clk);
+disable_utmi_clk:
+ clk_disable_unprepare(msm->utmi_clk);
disable_sleep_a_clk:
clk_disable_unprepare(msm->hsphy_sleep_clk);
disable_sleep_clk:
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index 1512513..a1d7a87 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -53,6 +53,7 @@
#include "core.h"
#include "gadget.h"
#include "io.h"
+#include "debug.h"
static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep);
static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
@@ -741,6 +742,7 @@
dwc->ep0_next_event = DWC3_EP0_NRDY_DATA;
}
+ dbg_setup(0x00, ctrl);
if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD)
ret = dwc3_ep0_std_request(dwc, ctrl);
else
@@ -849,6 +851,7 @@
if (status == DWC3_TRBSTS_SETUP_PENDING)
dev_dbg(dwc->dev, "Setup Pending received\n");
+ dbg_print(dep->number, "DONE", status, "STATUS");
dwc->ep0state = EP0_SETUP_PHASE;
dwc3_ep0_out_start(dwc);
}
@@ -931,6 +934,7 @@
req->request.length, DWC3_TRBCTL_CONTROL_DATA);
}
+ dbg_queue(dep->number, &req->request, ret);
WARN_ON(ret < 0);
}
@@ -948,13 +952,16 @@
static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep)
{
+ int ret;
if (dwc->resize_fifos) {
dev_dbg(dwc->dev, "starting to resize fifos\n");
dwc3_gadget_resize_tx_fifos(dwc);
dwc->resize_fifos = 0;
}
- WARN_ON(dwc3_ep0_start_control_status(dep));
+ ret = dwc3_ep0_start_control_status(dep);
+ dbg_print(dep->number, "QUEUE", ret, "STATUS");
+ WARN_ON(ret);
}
static void dwc3_ep0_do_control_status(struct dwc3 *dwc,
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 9fa1ab4..0664376 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -53,6 +53,7 @@
#include "core.h"
#include "gadget.h"
+#include "debug.h"
#include "io.h"
/**
@@ -276,6 +277,7 @@
req, dep->name, req->request.actual,
req->request.length, status);
+ dbg_done(dep->number, req->request.actual, req->request.status);
spin_unlock(&dwc->lock);
req->request.complete(&dep->endpoint, &req->request);
spin_lock(&dwc->lock);
@@ -690,6 +692,7 @@
spin_lock_irqsave(&dwc->lock, flags);
ret = __dwc3_gadget_ep_enable(dep, desc, ep->comp_desc, false);
+ dbg_event(dep->number, "ENABLE", ret);
spin_unlock_irqrestore(&dwc->lock, flags);
return ret;
@@ -722,6 +725,7 @@
spin_lock_irqsave(&dwc->lock, flags);
ret = __dwc3_gadget_ep_disable(dep);
+ dbg_event(dep->number, "DISABLE", ret);
spin_unlock_irqrestore(&dwc->lock, flags);
return ret;
@@ -929,6 +933,7 @@
if (last_one)
break;
}
+ dbg_queue(dep->number, &req->request, 0);
} else {
dma = req->request.dma;
length = req->request.length;
@@ -944,6 +949,7 @@
dwc3_prepare_one_trb(dep, req, dma, length,
last_one, false);
+ dbg_queue(dep->number, &req->request, 0);
if (last_one)
break;
}
@@ -985,6 +991,7 @@
}
if (!req) {
dep->flags |= DWC3_EP_PENDING_REQUEST;
+ dbg_event(dep->number, "NO REQ", 0);
return 0;
}
@@ -1057,6 +1064,7 @@
struct dwc3_ep *dep, u32 cur_uf)
{
u32 uf;
+ int ret;
dep->current_uf = cur_uf;
@@ -1070,7 +1078,9 @@
/* 4 micro frames in the future */
uf = cur_uf + dep->interval * 4;
- __dwc3_gadget_kick_transfer(dep, uf, 1);
+ ret = __dwc3_gadget_kick_transfer(dep, uf, 1);
+ if (ret < 0)
+ dbg_event(dep->number, "QUEUE", ret);
}
static void dwc3_gadget_start_isoc(struct dwc3 *dwc,
@@ -1156,9 +1166,11 @@
}
ret = __dwc3_gadget_kick_transfer(dep, 0, true);
- if (ret && ret != -EBUSY)
+ if (ret && ret != -EBUSY) {
+ dbg_event(dep->number, "QUEUE", ret);
dev_dbg(dwc->dev, "%s: failed to kick transfers\n",
dep->name);
+ }
}
/*
@@ -1172,9 +1184,11 @@
WARN_ON_ONCE(!dep->resource_index);
ret = __dwc3_gadget_kick_transfer(dep, dep->resource_index,
false);
- if (ret && ret != -EBUSY)
+ if (ret && ret != -EBUSY) {
+ dbg_event(dep->number, "QUEUE", ret);
dev_dbg(dwc->dev, "%s: failed to kick transfers\n",
dep->name);
+ }
}
return 0;
@@ -1191,7 +1205,10 @@
int ret;
+ spin_lock_irqsave(&dwc->lock, flags);
+
if (!dep->endpoint.desc) {
+ spin_unlock_irqrestore(&dwc->lock, flags);
dev_dbg(dwc->dev, "trying to queue request %p to disabled %s\n",
request, ep->name);
return -ESHUTDOWN;
@@ -1203,7 +1220,6 @@
WARN(!dep->direction && (request->length % ep->desc->wMaxPacketSize),
"trying to queue unaligned request (%d)\n", request->length);
- spin_lock_irqsave(&dwc->lock, flags);
ret = __dwc3_gadget_ep_queue(dep, req);
spin_unlock_irqrestore(&dwc->lock, flags);
@@ -1246,6 +1262,7 @@
}
out1:
+ dbg_event(dep->number, "DEQUEUE", 0);
/* giveback the request */
dwc3_gadget_giveback(dep, req, -ECONNRESET);
@@ -1303,6 +1320,7 @@
goto out;
}
+ dbg_event(dep->number, "HALT", value);
ret = __dwc3_gadget_ep_set_halt(dep, value);
out:
spin_unlock_irqrestore(&dwc->lock, flags);
@@ -1317,6 +1335,7 @@
unsigned long flags;
spin_lock_irqsave(&dwc->lock, flags);
+ dbg_event(dep->number, "WEDGE", 0);
dep->flags |= DWC3_EP_WEDGE;
spin_unlock_irqrestore(&dwc->lock, flags);
@@ -1910,6 +1929,8 @@
* request in the request_list.
*/
dep->flags |= DWC3_EP_MISSED_ISOC;
+ dbg_event(dep->number, "MISSED ISOC",
+ status);
} else {
dev_err(dwc->dev, "incomplete IN transfer %s\n",
dep->name);
@@ -2060,6 +2081,8 @@
ret = __dwc3_gadget_kick_transfer(dep, 0, 1);
if (!ret || ret == -EBUSY)
return;
+ else
+ dbg_event(dep->number, "QUEUE", ret);
dev_dbg(dwc->dev, "%s: failed to kick transfers\n",
dep->name);
@@ -2196,6 +2219,7 @@
reg &= ~DWC3_DCTL_INITU2ENA;
dwc3_writel(dwc->regs, DWC3_DCTL, reg);
+ dbg_event(0xFF, "DISCONNECT", 0);
dwc3_disconnect_gadget(dwc);
dwc->start_config_issued = false;
@@ -2269,6 +2293,7 @@
dwc3_gadget_disconnect_interrupt(dwc);
}
+ dbg_event(0xFF, "BUS RST", 0);
/* after reset -> Default State */
dwc->dev_state = DWC3_DEFAULT_STATE;
@@ -2435,6 +2460,7 @@
* implemented.
*/
+ dbg_event(0xFF, "WAKEUP", 0);
dwc->gadget_driver->resume(&dwc->gadget);
}
@@ -2490,9 +2516,12 @@
}
if (next == DWC3_LINK_STATE_U0) {
- if (dwc->link_state == DWC3_LINK_STATE_U3)
+ if (dwc->link_state == DWC3_LINK_STATE_U3) {
+ dbg_event(0xFF, "RESUME", 0);
dwc->gadget_driver->resume(&dwc->gadget);
+ }
} else if (next == DWC3_LINK_STATE_U3) {
+ dbg_event(0xFF, "SUSPEND", 0);
dwc->gadget_driver->suspend(&dwc->gadget);
}
@@ -2527,12 +2556,14 @@
dev_vdbg(dwc->dev, "Start of Periodic Frame\n");
break;
case DWC3_DEVICE_EVENT_ERRATIC_ERROR:
+ dbg_event(0xFF, "ERROR", 0);
dev_vdbg(dwc->dev, "Erratic Error\n");
break;
case DWC3_DEVICE_EVENT_CMD_CMPL:
dev_vdbg(dwc->dev, "Command Complete\n");
break;
case DWC3_DEVICE_EVENT_OVERFLOW:
+ dbg_event(0xFF, "OVERFL", 0);
dev_vdbg(dwc->dev, "Overflow\n");
/*
* Controllers prior to 2.30a revision has a bug where
@@ -2559,6 +2590,7 @@
* Add a warning message to indicate that this event is received
* which means that event buffer might have corrupted.
*/
+ dbg_event(0xFF, "TSTLMP", 0);
if (dwc->revision < DWC3_REVISION_230A)
dev_warn(dwc->dev, "Vendor Device Test LMP Received\n");
break;
diff --git a/drivers/usb/gadget/f_mbim.c b/drivers/usb/gadget/f_mbim.c
index daa981f..935a540 100644
--- a/drivers/usb/gadget/f_mbim.c
+++ b/drivers/usb/gadget/f_mbim.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
@@ -66,6 +66,7 @@
NCM_NOTIFY_NONE,
NCM_NOTIFY_CONNECT,
NCM_NOTIFY_SPEED,
+ NCM_NOTIFY_RESPONSE_AVAILABLE,
};
struct f_mbim {
@@ -571,6 +572,7 @@
return;
}
+ req->length = sizeof *event;
event = req->buf;
event->bmRequestType = USB_DIR_IN | USB_TYPE_CLASS
| USB_RECIP_INTERFACE;
@@ -581,7 +583,7 @@
spin_unlock_irqrestore(&dev->lock, flags);
ret = usb_ep_queue(dev->not_port.notify,
- dev->not_port.notify_req, GFP_ATOMIC);
+ req, GFP_ATOMIC);
if (ret) {
atomic_dec(&dev->not_port.notify_count);
pr_err("ep enqueue error %d\n", ret);
@@ -610,6 +612,13 @@
return 0;
}
+ if (dev->not_port.notify_state != NCM_NOTIFY_RESPONSE_AVAILABLE) {
+ pr_err("dev:%p state=%d, recover!!\n", dev,
+ dev->not_port.notify_state);
+ mbim_free_ctrl_pkt(cpkt);
+ return 0;
+ }
+
spin_lock_irqsave(&dev->lock, flags);
list_add_tail(&cpkt->list, &dev->cpkt_resp_q);
spin_unlock_irqrestore(&dev->lock, flags);
@@ -750,10 +759,18 @@
switch (mbim->not_port.notify_state) {
case NCM_NOTIFY_NONE:
+ if (atomic_read(&mbim->not_port.notify_count) > 0)
+ pr_err("Pending notifications in NCM_NOTIFY_NONE\n");
+ else
+ pr_debug("No pending notifications\n");
+
+ return;
+
+ case NCM_NOTIFY_RESPONSE_AVAILABLE:
pr_debug("Notification %02x sent\n", event->bNotificationType);
if (atomic_read(&mbim->not_port.notify_count) <= 0) {
- pr_debug("notify_none: done");
+ pr_debug("notify_response_avaliable: done");
return;
}
@@ -778,7 +795,7 @@
pr_info("notify connect %s\n",
mbim->is_open ? "true" : "false");
- mbim->not_port.notify_state = NCM_NOTIFY_NONE;
+ mbim->not_port.notify_state = NCM_NOTIFY_RESPONSE_AVAILABLE;
break;
case NCM_NOTIFY_SPEED:
@@ -830,7 +847,7 @@
*/
pr_debug("dev:%p\n", mbim);
- mbim->not_port.notify_state = NCM_NOTIFY_SPEED;
+ mbim->not_port.notify_state = NCM_NOTIFY_RESPONSE_AVAILABLE;
mbim_do_notify(mbim);
}
@@ -1365,6 +1382,8 @@
pr_info("SET DEVICE OFFLINE");
atomic_set(&mbim->online, 0);
+ mbim->not_port.notify_state = NCM_NOTIFY_NONE;
+
mbim_clear_queues(mbim);
mbim_reset_function_queue(mbim);
@@ -1674,7 +1693,7 @@
}
while (list_empty(&dev->cpkt_req_q)) {
- pr_err("Requests list is empty. Wait.\n");
+ pr_debug("Requests list is empty. Wait.\n");
ret = wait_event_interruptible(dev->read_wq,
!list_empty(&dev->cpkt_req_q));
if (ret < 0) {
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c
index 2b8118b..2d974ab 100644
--- a/drivers/usb/gadget/u_ether.c
+++ b/drivers/usb/gadget/u_ether.c
@@ -610,11 +610,13 @@
unsigned long flags;
struct usb_ep *in;
u16 cdc_filter;
+ bool multi_pkt_xfer = false;
spin_lock_irqsave(&dev->lock, flags);
if (dev->port_usb) {
in = dev->port_usb->in_ep;
cdc_filter = dev->port_usb->cdc_filter;
+ multi_pkt_xfer = dev->port_usb->multi_pkt_xfer;
} else {
in = NULL;
cdc_filter = 0;
@@ -627,7 +629,7 @@
}
/* Allocate memory for tx_reqs to support multi packet transfer */
- if (dev->port_usb->multi_pkt_xfer && !dev->tx_req_bufsize)
+ if (multi_pkt_xfer && !dev->tx_req_bufsize)
alloc_tx_buffer(dev);
/* apply outgoing CDC or RNDIS filters */
@@ -690,7 +692,7 @@
dev->tx_skb_hold_count++;
spin_unlock_irqrestore(&dev->req_lock, flags);
- if (dev->port_usb->multi_pkt_xfer) {
+ if (multi_pkt_xfer) {
memcpy(req->buf + req->length, skb->data, skb->len);
req->length = req->length + skb->len;
length = req->length;
@@ -762,7 +764,7 @@
}
if (retval) {
- if (!dev->port_usb->multi_pkt_xfer)
+ if (!multi_pkt_xfer)
dev_kfree_skb_any(skb);
drop:
dev->net->stats.tx_dropped++;
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 24f3cb1..a09b1ab 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -842,7 +842,7 @@
u32 __iomem *status_reg = &ehci->regs->port_status[
(wIndex & 0xff) - 1];
u32 __iomem *hostpc_reg = NULL;
- u32 temp, temp1, status, cmd = 0;
+ u32 temp, temp1, status;
unsigned long flags;
int retval = 0;
unsigned selector;
@@ -1221,31 +1221,13 @@
ehci->reset_done [wIndex] = jiffies
+ msecs_to_jiffies (50);
}
-
- if (ehci->reset_sof_bug && (temp & PORT_RESET)) {
- cmd = ehci_readl(ehci, &ehci->regs->command);
- cmd &= ~CMD_RUN;
- ehci_writel(ehci, cmd, &ehci->regs->command);
- if (handshake(ehci, &ehci->regs->status,
- STS_HALT, STS_HALT, 16 * 125))
- ehci_info(ehci,
- "controller halt failed\n");
- }
- ehci_writel(ehci, temp, status_reg);
- if (ehci->reset_sof_bug && (temp & PORT_RESET)
- && hcd->driver->enable_ulpi_control) {
- hcd->driver->enable_ulpi_control(hcd,
- PORT_RESET);
+ if (ehci->reset_sof_bug && (temp & PORT_RESET) &&
+ hcd->driver->reset_sof_bug_handler) {
spin_unlock_irqrestore(&ehci->lock, flags);
- usleep_range(50000, 55000);
- if (handshake(ehci, status_reg,
- PORT_RESET, 0, 10 * 1000))
- ehci_info(ehci,
- "failed to clear reset\n");
+ hcd->driver->reset_sof_bug_handler(hcd, temp);
spin_lock_irqsave(&ehci->lock, flags);
- hcd->driver->disable_ulpi_control(hcd);
- cmd |= CMD_RUN;
- ehci_writel(ehci, cmd, &ehci->regs->command);
+ } else {
+ ehci_writel(ehci, temp, status_reg);
}
break;
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index fc4d1b6..a559ccf 100644
--- a/drivers/usb/host/ehci-msm-hsic.c
+++ b/drivers/usb/host/ehci-msm-hsic.c
@@ -101,6 +101,8 @@
struct completion rt_completion;
int resume_status;
int resume_again;
+ int bus_reset;
+ int reset_again;
struct pm_qos_request pm_qos_req_dma;
};
@@ -430,7 +432,7 @@
}
-static int ulpi_read(struct msm_hsic_hcd *mehci, u32 reg)
+static int __maybe_unused ulpi_read(struct msm_hsic_hcd *mehci, u32 reg)
{
struct usb_hcd *hcd = hsic_to_hcd(mehci);
int cnt = 0;
@@ -501,37 +503,6 @@
return 0;
}
-#define HSIC_DBG1 0X38
-#define ULPI_MANUAL_ENABLE BIT(4)
-#define ULPI_LINESTATE_DATA BIT(5)
-#define ULPI_LINESTATE_STROBE BIT(6)
-static void ehci_msm_enable_ulpi_control(struct usb_hcd *hcd, u32 linestate)
-{
- struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
- int val;
-
- switch (linestate) {
- case PORT_RESET:
- val = ulpi_read(mehci, HSIC_DBG1);
- val |= ULPI_MANUAL_ENABLE;
- val &= ~(ULPI_LINESTATE_DATA | ULPI_LINESTATE_STROBE);
- ulpi_write(mehci, val, HSIC_DBG1);
- break;
- default:
- pr_info("%s: Unknown linestate:%0x\n", __func__, linestate);
- }
-}
-
-static void ehci_msm_disable_ulpi_control(struct usb_hcd *hcd)
-{
- struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
- int val;
-
- val = ulpi_read(mehci, HSIC_DBG1);
- val &= ~ULPI_MANUAL_ENABLE;
- ulpi_write(mehci, val, HSIC_DBG1);
-}
-
static int msm_hsic_config_gpios(struct msm_hsic_hcd *mehci, int gpio_en)
{
int rc = 0;
@@ -955,6 +926,26 @@
__func__, ret);
}
+static int msm_hsic_reset_done(struct usb_hcd *hcd)
+{
+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+ u32 __iomem *status_reg = &ehci->regs->port_status[0];
+ int ret;
+
+ ehci_writel(ehci, ehci_readl(ehci, status_reg) & ~(PORT_RWC_BITS |
+ PORT_RESET), status_reg);
+
+ ret = handshake(ehci, status_reg, PORT_RESET, 0, 1 * 1000);
+
+ if (ret)
+ pr_err("reset handshake failed in %s\n", __func__);
+ else
+ ehci_writel(ehci, ehci_readl(ehci, &ehci->regs->command) |
+ CMD_RUN, &ehci->regs->command);
+
+ return ret;
+}
+
#define STS_GPTIMER0_INTERRUPT BIT(24)
static irqreturn_t msm_hsic_irq(struct usb_hcd *hcd)
{
@@ -982,16 +973,28 @@
if (status & STS_GPTIMER0_INTERRUPT) {
int timeleft;
- dbg_log_event(NULL, "FPR: gpt0_isr", 0);
+ dbg_log_event(NULL, "FPR: gpt0_isr", mehci->bus_reset);
timeleft = GPT_CNT(ehci_readl(ehci,
&mehci->timer->gptimer1_ctrl));
if (timeleft) {
- ehci_writel(ehci, ehci_readl(ehci,
- &ehci->regs->command) | CMD_RUN,
- &ehci->regs->command);
- } else
- mehci->resume_again = 1;
+ if (mehci->bus_reset) {
+ ret = msm_hsic_reset_done(hcd);
+ if (ret) {
+ mehci->reset_again = 1;
+ dbg_log_event(NULL, "RESET: fail", 0);
+ }
+ } else {
+ ehci_writel(ehci, ehci_readl(ehci,
+ &ehci->regs->command) | CMD_RUN,
+ &ehci->regs->command);
+ }
+ } else {
+ if (mehci->bus_reset)
+ mehci->reset_again = 1;
+ else
+ mehci->resume_again = 1;
+ }
dbg_log_event(NULL, "FPR: timeleft", timeleft);
@@ -1047,6 +1050,83 @@
#ifdef CONFIG_PM
+#define RESET_RETRY_LIMIT 3
+#define RESET_SIGNAL_TIME_SOF_USEC (50 * 1000)
+#define RESET_SIGNAL_TIME_USEC (20 * 1000)
+static void ehci_hsic_reset_sof_bug_handler(struct usb_hcd *hcd, u32 val)
+{
+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+ struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
+ struct msm_hsic_host_platform_data *pdata = mehci->dev->platform_data;
+ u32 __iomem *status_reg = &ehci->regs->port_status[0];
+ unsigned long flags;
+ int retries = 0, ret, cnt = RESET_SIGNAL_TIME_USEC;
+
+ if (pdata && pdata->swfi_latency)
+ pm_qos_update_request(&mehci->pm_qos_req_dma,
+ pdata->swfi_latency + 1);
+
+ mehci->bus_reset = 1;
+retry:
+ retries++;
+ dbg_log_event(NULL, "RESET: start", retries);
+ pr_debug("reset begin %d\n", retries);
+ mehci->reset_again = 0;
+ spin_lock_irqsave(&ehci->lock, flags);
+ ehci_writel(ehci, val, status_reg);
+ ehci_writel(ehci, GPT_LD(RESET_SIGNAL_TIME_USEC - 1),
+ &mehci->timer->gptimer0_ld);
+ ehci_writel(ehci, GPT_RESET | GPT_RUN,
+ &mehci->timer->gptimer0_ctrl);
+ ehci_writel(ehci, INTR_MASK | STS_GPTIMER0_INTERRUPT,
+ &ehci->regs->intr_enable);
+
+ ehci_writel(ehci, GPT_LD(RESET_SIGNAL_TIME_SOF_USEC - 1),
+ &mehci->timer->gptimer1_ld);
+ ehci_writel(ehci, GPT_RESET | GPT_RUN,
+ &mehci->timer->gptimer1_ctrl);
+
+ spin_unlock_irqrestore(&ehci->lock, flags);
+ wait_for_completion(&mehci->gpt0_completion);
+
+ if (!mehci->reset_again)
+ goto done;
+
+ if (handshake(ehci, status_reg, PORT_RESET, 0, 10 * 1000)) {
+ pr_err("reset handshake fatal error\n");
+ dbg_log_event(NULL, "RESET: fatal", retries);
+ goto fail;
+ }
+
+ if (retries < RESET_RETRY_LIMIT)
+ goto retry;
+
+ /* complete reset in tight loop */
+ pr_info("RESET in tight loop\n");
+ dbg_log_event(NULL, "RESET: tight", 0);
+
+ spin_lock_irqsave(&ehci->lock, flags);
+ ehci_writel(ehci, val, status_reg);
+ while (cnt--)
+ udelay(1);
+ ret = msm_hsic_reset_done(hcd);
+ spin_unlock_irqrestore(&ehci->lock, flags);
+ if (ret) {
+ pr_err("RESET in tight loop failed\n");
+ dbg_log_event(NULL, "RESET: tight failed", 0);
+ goto fail;
+ }
+
+done:
+ dbg_log_event(NULL, "RESET: done", retries);
+ pr_debug("reset completed\n");
+fail:
+ mehci->bus_reset = 0;
+ if (pdata && pdata->swfi_latency)
+ pm_qos_update_request(&mehci->pm_qos_req_dma,
+ PM_QOS_DEFAULT_VALUE);
+}
+
static int ehci_hsic_bus_suspend(struct usb_hcd *hcd)
{
struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
@@ -1321,10 +1401,8 @@
.log_urb = dbg_log_event,
.dump_regs = dump_hsic_regs,
- .enable_ulpi_control = ehci_msm_enable_ulpi_control,
- .disable_ulpi_control = ehci_msm_disable_ulpi_control,
-
.set_autosuspend_delay = ehci_msm_set_autosuspend_delay,
+ .reset_sof_bug_handler = ehci_hsic_reset_sof_bug_handler,
};
static int msm_hsic_init_clocks(struct msm_hsic_hcd *mehci, u32 init)
@@ -1933,6 +2011,12 @@
struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
struct msm_hsic_host_platform_data *pdata = mehci->dev->platform_data;
+ /* If the device was removed no need to call pm_runtime_disable */
+ if (pdev->dev.power.power_state.event != PM_EVENT_INVALID)
+ pm_runtime_disable(&pdev->dev);
+
+ pm_runtime_set_suspended(&pdev->dev);
+
/* Remove the HCD prior to releasing our resources. */
usb_remove_hcd(hcd);
@@ -1966,12 +2050,6 @@
ehci_hsic_msm_debugfs_cleanup();
device_init_wakeup(&pdev->dev, 0);
- /* If the device was removed no need to call pm_runtime_disable */
- if (pdev->dev.power.power_state.event != PM_EVENT_INVALID)
- pm_runtime_disable(&pdev->dev);
-
- pm_runtime_set_suspended(&pdev->dev);
-
destroy_workqueue(ehci_wq);
msm_hsic_config_gpios(mehci, 0);
diff --git a/drivers/video/msm/mdss/mdss.h b/drivers/video/msm/mdss/mdss.h
index 5070b03..b6882b8 100644
--- a/drivers/video/msm/mdss/mdss.h
+++ b/drivers/video/msm/mdss/mdss.h
@@ -57,13 +57,12 @@
};
struct mdss_data_type {
- u32 rev;
u32 mdp_rev;
struct clk *mdp_clk[MDSS_MAX_CLK];
struct regulator *fs;
struct workqueue_struct *clk_ctrl_wq;
- struct delayed_work clk_ctrl_worker;
+ struct work_struct clk_ctrl_worker;
struct platform_device *pdev;
char __iomem *mdp_base;
size_t mdp_reg_size;
@@ -80,6 +79,7 @@
u32 suspend;
u32 timeout;
+ atomic_t clk_ref;
u8 clk_ena;
u8 fs_ena;
u8 vsync_ena;
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
index 00a8aa5..198e2a2 100644
--- a/drivers/video/msm/mdss/mdss_fb.c
+++ b/drivers/video/msm/mdss/mdss_fb.c
@@ -618,6 +618,12 @@
static int mdss_fb_blank(int blank_mode, struct fb_info *info)
{
struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+ if (blank_mode == FB_BLANK_POWERDOWN) {
+ struct fb_event event;
+ event.info = info;
+ event.data = &blank_mode;
+ fb_notifier_call_chain(FB_EVENT_BLANK, &event);
+ }
mdss_fb_pan_idle(mfd);
if (mfd->op_enable == 0) {
if (blank_mode == FB_BLANK_UNBLANK)
@@ -1037,16 +1043,23 @@
void mdss_fb_wait_for_fence(struct msm_fb_data_type *mfd)
{
- int i, ret;
+ int i, ret = 0;
/* buf sync */
for (i = 0; i < mfd->acq_fen_cnt; i++) {
ret = sync_fence_wait(mfd->acq_fen[i], WAIT_FENCE_TIMEOUT);
- sync_fence_put(mfd->acq_fen[i]);
if (ret < 0) {
pr_err("%s: sync_fence_wait failed! ret = %x\n",
__func__, ret);
break;
}
+ sync_fence_put(mfd->acq_fen[i]);
+ }
+
+ if (ret < 0) {
+ while (i < mfd->acq_fen_cnt) {
+ sync_fence_put(mfd->acq_fen[i]);
+ i++;
+ }
}
mfd->acq_fen_cnt = 0;
}
@@ -1199,8 +1212,6 @@
pinfo->lcdc.h_back_porch = var->left_margin;
pinfo->lcdc.h_pulse_width = var->hsync_len;
pinfo->clk_rate = var->pixclock;
- /* todo: find how to pass CEA vic through framebuffer APIs */
- pinfo->vic = var->reserved[3];
}
static void mdss_fb_commit_wq_handler(struct work_struct *work)
@@ -1597,6 +1608,26 @@
return ret;
}
+static int mdss_fb_set_metadata(struct msm_fb_data_type *mfd,
+ struct msmfb_metadata *metadata)
+{
+ int ret = 0;
+ switch (metadata->op) {
+ case metadata_op_vic:
+ if (mfd->panel_info)
+ mfd->panel_info->vic =
+ metadata->data.video_info_code;
+ else
+ ret = -EINVAL;
+ break;
+ default:
+ pr_warn("unsupported request to MDP META IOCTL\n");
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
static int mdss_fb_get_metadata(struct msm_fb_data_type *mfd,
struct msmfb_metadata *metadata)
{
@@ -1709,6 +1740,13 @@
ret = mdss_fb_display_commit(info, argp);
break;
+ case MSMFB_METADATA_SET:
+ ret = copy_from_user(&metadata, argp, sizeof(metadata));
+ if (ret)
+ return ret;
+ ret = mdss_fb_set_metadata(mfd, &metadata);
+ break;
+
case MSMFB_METADATA_GET:
ret = copy_from_user(&metadata, argp, sizeof(metadata));
if (ret)
diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c
index 31b80b1..308ae87 100644
--- a/drivers/video/msm/mdss/mdss_mdp.c
+++ b/drivers/video/msm/mdss/mdss_mdp.c
@@ -27,6 +27,7 @@
#include <linux/iommu.h>
#include <linux/of.h>
#include <linux/of_address.h>
+#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
#include <linux/memory_alloc.h>
@@ -55,7 +56,6 @@
static DEFINE_SPINLOCK(mdp_lock);
static DEFINE_MUTEX(mdp_clk_lock);
-static DEFINE_MUTEX(mdp_suspend_mutex);
#define MDP_BUS_VECTOR_ENTRY(ab_val, ib_val) \
{ \
@@ -111,7 +111,7 @@
static DEFINE_SPINLOCK(mdss_lock);
struct mdss_hw *mdss_irq_handlers[MDSS_MAX_HW_BLK];
-static int mdss_mdp_register_early_suspend(struct mdss_data_type *mdata);
+static void mdss_mdp_footswitch_ctrl(struct mdss_data_type *mdata, int on);
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);
@@ -514,15 +514,19 @@
return clk_rate;
}
-static void mdss_mdp_clk_ctrl_update(int enable)
+static void mdss_mdp_clk_ctrl_update(struct mdss_data_type *mdata)
{
- if (mdss_res->clk_ena == enable)
- return;
-
- pr_debug("MDP CLKS %s\n", (enable ? "Enable" : "Disable"));
+ int enable;
mutex_lock(&mdp_clk_lock);
- mdss_res->clk_ena = enable;
+ enable = atomic_read(&mdata->clk_ref) > 0;
+ if (mdata->clk_ena == enable) {
+ mutex_unlock(&mdp_clk_lock);
+ return;
+ }
+ mdata->clk_ena = enable;
+
+ pr_debug("MDP CLKS %s\n", (enable ? "Enable" : "Disable"));
mb();
mdss_mdp_clk_update(MDSS_CLK_AHB, enable);
@@ -530,7 +534,7 @@
mdss_mdp_clk_update(MDSS_CLK_MDP_CORE, enable);
mdss_mdp_clk_update(MDSS_CLK_MDP_LUT, enable);
- if (mdss_res->vsync_ena)
+ if (mdata->vsync_ena)
mdss_mdp_clk_update(MDSS_CLK_MDP_VSYNC, enable);
mutex_unlock(&mdp_clk_lock);
@@ -538,65 +542,37 @@
static void mdss_mdp_clk_ctrl_workqueue_handler(struct work_struct *work)
{
- mdss_mdp_clk_ctrl(MDP_BLOCK_MASTER_OFF, false);
+ struct mdss_data_type *mdata;
+
+ mdata = container_of(work, struct mdss_data_type, clk_ctrl_worker);
+ mdss_mdp_clk_ctrl_update(mdata);
}
void mdss_mdp_clk_ctrl(int enable, int isr)
{
- static atomic_t clk_ref = ATOMIC_INIT(0);
- static DEFINE_MUTEX(clk_ctrl_lock);
- int force_off = 0;
+ struct mdss_data_type *mdata = mdss_res;
- pr_debug("clk enable=%d isr=%d clk_ref=%d\n", enable, isr,
- atomic_read(&clk_ref));
- /*
- * It is assumed that if isr = TRUE then start = OFF
- * if start = ON when isr = TRUE it could happen that the usercontext
- * could turn off the clocks while the interrupt is updating the
- * power to ON
- */
- WARN_ON(isr == true && enable);
+ pr_debug("clk enable=%d isr=%d ref= %d\n", enable, isr,
+ atomic_read(&mdata->clk_ref));
if (enable == MDP_BLOCK_POWER_ON) {
- atomic_inc(&clk_ref);
- } else if (!atomic_add_unless(&clk_ref, -1, 0)) {
- if (enable == MDP_BLOCK_MASTER_OFF) {
- pr_debug("master power-off req\n");
- force_off = 1;
- } else {
- WARN(1, "too many mdp clock off call\n");
- }
- }
+ BUG_ON(isr);
- WARN_ON(enable == MDP_BLOCK_MASTER_OFF && !force_off);
-
- if (isr) {
- /* if it's power off send workqueue to turn off clocks */
- if (mdss_res->clk_ena && !atomic_read(&clk_ref))
- queue_delayed_work(mdss_res->clk_ctrl_wq,
- &mdss_res->clk_ctrl_worker,
- mdss_res->timeout);
+ if (atomic_inc_return(&mdata->clk_ref) == 1)
+ mdss_mdp_clk_ctrl_update(mdata);
} else {
- mutex_lock(&clk_ctrl_lock);
- if (delayed_work_pending(&mdss_res->clk_ctrl_worker))
- cancel_delayed_work(&mdss_res->clk_ctrl_worker);
+ BUG_ON(atomic_read(&mdata->clk_ref) == 0);
- if (atomic_read(&clk_ref)) {
- mdss_mdp_clk_ctrl_update(true);
- } else if (mdss_res->clk_ena) {
- mutex_lock(&mdp_suspend_mutex);
- if (force_off || mdss_res->suspend) {
- mdss_mdp_clk_ctrl_update(false);
- } else {
- /* send workqueue to turn off mdp power */
- queue_delayed_work(mdss_res->clk_ctrl_wq,
- &mdss_res->clk_ctrl_worker,
- mdss_res->timeout);
- }
- mutex_unlock(&mdp_suspend_mutex);
+ if (atomic_dec_and_test(&mdata->clk_ref)) {
+ if (isr)
+ queue_work(mdata->clk_ctrl_wq,
+ &mdata->clk_ctrl_worker);
+ else
+ mdss_mdp_clk_ctrl_update(mdata);
}
- mutex_unlock(&clk_ctrl_lock);
}
+
+
}
static inline int mdss_mdp_irq_clk_register(struct mdss_data_type *mdata,
@@ -636,8 +612,7 @@
pr_err("unable to get gdsc regulator\n");
return -EINVAL;
}
- regulator_enable(mdata->fs);
- mdata->fs_ena = true;
+ mdata->fs_ena = false;
if (mdss_mdp_irq_clk_register(mdata, "bus_clk", MDSS_CLK_AXI) ||
mdss_mdp_irq_clk_register(mdata, "iface_clk", MDSS_CLK_AHB) ||
@@ -697,7 +672,7 @@
int i;
if (!mdata->iommu_attached) {
- pr_warn("mdp iommu already dettached\n");
+ pr_debug("mdp iommu already dettached\n");
return 0;
}
@@ -778,9 +753,12 @@
static int mdss_hw_init(struct mdss_data_type *mdata)
{
+ int i, j;
+ char *offset;
+
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);
+ pr_info_once("MDP Rev=%x\n", mdata->mdp_rev);
if (mdata->hw_settings) {
struct mdss_hw_settings *hws = mdata->hw_settings;
@@ -790,6 +768,16 @@
hws++;
}
}
+
+ for (i = 0; i < mdata->nmixers_intf; i++) {
+ offset = mdata->mixer_intf[i].dspp_base +
+ MDSS_MDP_REG_DSPP_HIST_LUT_BASE;
+ for (j = 0; j < ENHIST_LUT_ENTRIES; j++)
+ writel_relaxed(j, offset);
+
+ /* swap */
+ writel_relaxed(i, offset + 4);
+ }
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
pr_debug("MDP hw init done\n");
@@ -817,14 +805,11 @@
return rc;
mdata->clk_ctrl_wq = create_singlethread_workqueue("mdp_clk_wq");
- INIT_DELAYED_WORK(&mdata->clk_ctrl_worker,
- mdss_mdp_clk_ctrl_workqueue_handler);
+ INIT_WORK(&mdata->clk_ctrl_worker, mdss_mdp_clk_ctrl_workqueue_handler);
mdata->smp_mb_cnt = MDSS_MDP_SMP_MMB_BLOCKS;
mdata->smp_mb_size = MDSS_MDP_SMP_MMB_SIZE;
- pr_info("mdss_revision=%x\n", mdata->rev);
- pr_info("mdp_hw_revision=%x\n", mdata->mdp_rev);
mdata->iclient = msm_ion_client_create(-1, mdata->pdev->name);
if (IS_ERR_OR_NULL(mdata->iclient)) {
@@ -834,10 +819,6 @@
}
rc = mdss_iommu_init(mdata);
- if (!IS_ERR_VALUE(rc))
- mdss_iommu_attach(mdata);
-
- rc = mdss_hw_init(mdata);
return rc;
}
@@ -935,15 +916,16 @@
goto probe_done;
}
- rc = mdss_mdp_register_early_suspend(mdata);
+ rc = mdss_mdp_debug_init(mdata);
if (rc) {
- pr_err("unable to register early suspend\n");
+ pr_err("unable to initialize mdp debugging\n");
goto probe_done;
}
- rc = mdss_mdp_debug_init(mdata);
- if (rc)
- pr_err("unable to initialize mdp debugging\n");
+ pm_runtime_set_suspended(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+ if (!pm_runtime_enabled(&pdev->dev))
+ mdss_mdp_footswitch_ctrl(mdata, true);
probe_done:
if (IS_ERR_VALUE(rc)) {
@@ -1345,16 +1327,14 @@
static void mdss_mdp_footswitch_ctrl(struct mdss_data_type *mdata, int on)
{
- mutex_lock(&mdp_suspend_mutex);
- if (!mdata->suspend || !mdata->fs) {
- mutex_unlock(&mdp_suspend_mutex);
+ if (!mdata->fs)
return;
- }
if (on && !mdata->fs_ena) {
pr_debug("Enable MDP FS\n");
regulator_enable(mdata->fs);
mdss_iommu_attach(mdata);
+ mdss_hw_init(mdata);
mdata->fs_ena = true;
} else if (!on && mdata->fs_ena) {
pr_debug("Disable MDP FS\n");
@@ -1362,7 +1342,6 @@
regulator_disable(mdata->fs);
mdata->fs_ena = false;
}
- mutex_unlock(&mdp_suspend_mutex);
}
static inline int mdss_mdp_suspend_sub(struct mdss_data_type *mdata)
@@ -1375,22 +1354,6 @@
return ret;
}
- cancel_delayed_work(&mdata->clk_ctrl_worker);
-
- flush_workqueue(mdata->clk_ctrl_wq);
-
- mdss_mdp_clk_ctrl(MDP_BLOCK_MASTER_OFF, false);
-
- mutex_lock(&mdp_suspend_mutex);
- mdata->suspend = true;
- mutex_unlock(&mdp_suspend_mutex);
-
- if (mdata->clk_ena) {
- pr_err("MDP suspend failed\n");
- return -EBUSY;
- }
- mdss_mdp_footswitch_ctrl(mdata, false);
-
pr_debug("suspend done\n");
return 0;
@@ -1400,11 +1363,6 @@
{
int ret = 0;
- mdss_mdp_footswitch_ctrl(mdata, true);
- mutex_lock(&mdp_suspend_mutex);
- mdata->suspend = false;
- mutex_unlock(&mdp_suspend_mutex);
- mdss_hw_init(mdata);
ret = mdss_fb_resume_all();
if (IS_ERR_VALUE(ret))
pr_err("Unable to resume all fb panels (%d)\n", ret);
@@ -1414,7 +1372,37 @@
return ret;
}
-#if defined(CONFIG_PM) && !defined(CONFIG_HAS_EARLYSUSPEND)
+#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
+static int mdss_mdp_pm_suspend(struct device *dev)
+{
+ struct mdss_data_type *mdata;
+
+ mdata = dev_get_drvdata(dev);
+ if (!mdata)
+ return -ENODEV;
+
+ dev_dbg(dev, "display pm suspend\n");
+
+ return mdss_mdp_suspend_sub(mdata);
+}
+
+static int mdss_mdp_pm_resume(struct device *dev)
+{
+ struct mdss_data_type *mdata;
+
+ mdata = dev_get_drvdata(dev);
+ if (!mdata)
+ return -ENODEV;
+
+ dev_dbg(dev, "display pm resume\n");
+
+ return mdss_mdp_resume_sub(mdata);
+}
+
+#define mdss_mdp_suspend NULL
+#define mdss_mdp_resume NULL
+#else
static int mdss_mdp_suspend(struct platform_device *pdev, pm_message_t state)
{
struct mdss_data_type *mdata = platform_get_drvdata(pdev);
@@ -1422,7 +1410,7 @@
if (!mdata)
return -ENODEV;
- pr_debug("display suspend\n");
+ dev_dbg(&pdev->dev, "display suspend\n");
return mdss_mdp_suspend_sub(mdata);
}
@@ -1434,62 +1422,63 @@
if (!mdata)
return -ENODEV;
- pr_debug("display resume\n");
+ dev_dbg(&pdev->dev, "display resume\n");
return mdss_mdp_resume_sub(mdata);
}
-#else
-#define mdss_mdp_suspend NULL
-#define mdss_mdp_resume NULL
#endif
-#ifdef CONFIG_HAS_EARLYSUSPEND
-static void mdss_mdp_early_suspend(struct early_suspend *h)
+#ifdef CONFIG_PM_RUNTIME
+static int mdss_mdp_runtime_resume(struct device *dev)
{
- struct mdss_data_type *mdata;
- mdata = container_of(h, struct mdss_data_type, early_suspend);
+ struct mdss_data_type *mdata = dev_get_drvdata(dev);
+ if (!mdata)
+ return -ENODEV;
- pr_debug("display early suspend\n");
+ dev_dbg(dev, "pm_runtime: resuming...\n");
- mdss_mdp_suspend_sub(mdata);
-}
-
-static void mdss_mdp_late_resume(struct early_suspend *h)
-{
- struct mdss_data_type *mdata;
- mdata = container_of(h, struct mdss_data_type, early_suspend);
-
- pr_debug("display early resume\n");
-
- mdss_mdp_resume_sub(mdata);
-}
-
-static int mdss_mdp_register_early_suspend(struct mdss_data_type *mdata)
-{
- mdata->early_suspend.suspend = mdss_mdp_early_suspend;
- mdata->early_suspend.resume = mdss_mdp_late_resume;
- mdata->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;
- register_early_suspend(&mdata->early_suspend);
+ mdss_mdp_footswitch_ctrl(mdata, true);
return 0;
}
-static int mdss_mdp_remove_early_suspend(struct mdss_data_type *mdata)
+static int mdss_mdp_runtime_idle(struct device *dev)
{
- unregister_early_suspend(&mdata->early_suspend);
+ struct mdss_data_type *mdata = dev_get_drvdata(dev);
+ if (!mdata)
+ return -ENODEV;
+
+ dev_dbg(dev, "pm_runtime: idling...\n");
+
+ flush_workqueue(mdata->clk_ctrl_wq);
return 0;
}
-#else
-static int mdss_mdp_register_early_suspend(struct mdss_data_type *mdata)
+
+static int mdss_mdp_runtime_suspend(struct device *dev)
{
- return 0;
-}
-static int mdss_mdp_remove_early_suspend(struct mdss_data_type *mdata)
-{
+ struct mdss_data_type *mdata = dev_get_drvdata(dev);
+ if (!mdata)
+ return -ENODEV;
+ dev_dbg(dev, "pm_runtime: suspending...\n");
+
+ if (mdata->clk_ena) {
+ pr_err("MDP suspend failed\n");
+ return -EBUSY;
+ }
+ mdss_mdp_footswitch_ctrl(mdata, false);
+
return 0;
}
#endif
+#endif
+
+static const struct dev_pm_ops mdss_mdp_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(mdss_mdp_pm_suspend, mdss_mdp_pm_resume)
+ SET_RUNTIME_PM_OPS(mdss_mdp_runtime_suspend,
+ mdss_mdp_runtime_resume,
+ mdss_mdp_runtime_idle)
+};
static int mdss_mdp_remove(struct platform_device *pdev)
{
@@ -1499,7 +1488,6 @@
pm_runtime_disable(&pdev->dev);
mdss_mdp_pp_term(&pdev->dev);
mdss_mdp_bus_scale_unregister(mdata);
- mdss_mdp_remove_early_suspend(mdata);
mdss_debugfs_remove(mdata);
return 0;
}
@@ -1523,6 +1511,7 @@
*/
.name = "mdp",
.of_match_table = mdss_mdp_dt_match,
+ .pm = &mdss_mdp_pm_ops,
},
};
diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h
index 30b7695..455f725 100644
--- a/drivers/video/msm/mdss/mdss_mdp.h
+++ b/drivers/video/msm/mdss/mdss_mdp.h
@@ -66,7 +66,6 @@
#endif
enum mdss_mdp_block_power_state {
- MDP_BLOCK_MASTER_OFF = -1,
MDP_BLOCK_POWER_OFF = 0,
MDP_BLOCK_POWER_ON = 1,
};
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index 63a1aa4..0f52125 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -267,6 +267,13 @@
mutex_lock(&mdss_mdp_ctl_lock);
ctl->ref_cnt--;
+ ctl->mixer_left = NULL;
+ ctl->mixer_right = NULL;
+ ctl->power_on = false;
+ ctl->start_fnc = NULL;
+ ctl->stop_fnc = NULL;
+ ctl->prepare_fnc = NULL;
+ ctl->display_fnc = NULL;
mutex_unlock(&mdss_mdp_ctl_lock);
return 0;
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_video.c b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
index 1aea4e0..0d4037c 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_video.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
@@ -251,6 +251,7 @@
NULL, NULL);
ctx->ref_cnt--;
+ ctl->priv_data = NULL;
return 0;
}
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index 283d3f0..5e9659f 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -18,6 +18,7 @@
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/module.h>
+#include <linux/pm_runtime.h>
#include <linux/uaccess.h>
#include <mach/iommu_domains.h>
@@ -84,11 +85,7 @@
return -EOVERFLOW;
}
- if (req->flags & MDSS_MDP_ROT_ONLY) {
- /* dst res should match src res in rotation only mode*/
- req->dst_rect.w = req->src_rect.w;
- req->dst_rect.h = req->src_rect.h;
- } else {
+ if (!(req->flags & MDSS_MDP_ROT_ONLY)) {
u32 dst_w, dst_h;
if ((CHECK_BOUNDS(req->dst_rect.x, req->dst_rect.w, xres) ||
@@ -418,25 +415,28 @@
int num_planes,
u32 flags)
{
- int i;
+ int i, rc = 0;
+
+ if ((num_planes <= 0) || (num_planes > MAX_PLANES))
+ return -EINVAL;
memset(data, 0, sizeof(*data));
for (i = 0; i < num_planes; i++) {
data->p[i].flags = flags;
- mdss_mdp_get_img(&planes[i], &data->p[i]);
- if (data->p[0].len == 0)
+ rc = mdss_mdp_get_img(&planes[i], &data->p[i]);
+ if (rc) {
+ pr_err("failed to map buf p=%d flags=%x\n", i, flags);
+ while (i > 0) {
+ i--;
+ mdss_mdp_put_img(&data->p[i]);
+ }
break;
+ }
}
- if (i != num_planes) {
- for (; i >= 0; i--)
- mdss_mdp_put_img(&data->p[i]);
- return -ENOMEM;
- }
+ data->num_planes = i;
- data->num_planes = num_planes;
-
- return 0;
+ return rc;
}
static inline int mdss_mdp_overlay_free_buf(struct mdss_mdp_data *data)
@@ -479,9 +479,22 @@
int mdss_mdp_overlay_kickoff(struct mdss_mdp_ctl *ctl)
{
struct msm_fb_data_type *mfd = ctl->mfd;
+ struct mdss_mdp_pipe *pipe;
int ret;
mutex_lock(&mfd->ov_lock);
+ mutex_lock(&mfd->lock);
+ list_for_each_entry(pipe, &mfd->pipes_used, used_list) {
+ if (pipe->params_changed || pipe->back_buf.num_planes) {
+ ret = mdss_mdp_pipe_queue_data(pipe, &pipe->back_buf);
+ if (IS_ERR_VALUE(ret)) {
+ pr_warn("Unable to queue data for pnum=%d\n",
+ pipe->num);
+ mdss_mdp_overlay_free_buf(&pipe->back_buf);
+ }
+ }
+ }
+ mutex_unlock(&mfd->lock);
if (mfd->kickoff_fnc)
ret = mfd->kickoff_fnc(ctl);
@@ -580,6 +593,13 @@
unset_ndx |= pipe->ndx;
cnt++;
}
+
+ if (cnt == 0 && !list_empty(&mfd->pipes_cleanup)) {
+ pr_warn("overlay release on fb%d called without commit!",
+ mfd->index);
+ cnt++;
+ }
+
mutex_unlock(&mfd->lock);
if (unset_ndx) {
@@ -628,32 +648,29 @@
ret = mdss_mdp_overlay_get_buf(mfd, &src_data, &req->data, 1, flgs);
if (ret) {
pr_err("src_data pmem error\n");
- goto rotate_done;
+ return ret;
}
ret = mdss_mdp_overlay_get_buf(mfd, &dst_data, &req->dst_data, 1, flgs);
if (ret) {
pr_err("dst_data pmem error\n");
- goto rotate_done;
+ goto dst_buf_fail;
}
ret = mdss_mdp_rotator_queue(rot, &src_data, &dst_data);
- if (ret) {
+ if (ret)
pr_err("rotator queue error session id=%x\n", req->id);
- goto rotate_done;
- }
-rotate_done:
mdss_mdp_overlay_free_buf(&dst_data);
+dst_buf_fail:
mdss_mdp_overlay_free_buf(&src_data);
- return 0;
+ return ret;
}
static int mdss_mdp_overlay_queue(struct msm_fb_data_type *mfd,
struct msmfb_overlay_data *req)
{
- struct mdss_mdp_ctl *ctl;
struct mdss_mdp_pipe *pipe;
struct mdss_mdp_data *src_data;
int ret;
@@ -679,12 +696,7 @@
ret = mdss_mdp_overlay_get_buf(mfd, src_data, &req->data, 1, flags);
if (IS_ERR_VALUE(ret)) {
pr_err("src_data pmem error\n");
- } else {
- ret = mdss_mdp_pipe_queue_data(pipe, src_data);
- if (IS_ERR_VALUE(ret))
- mdss_mdp_overlay_free_buf(src_data);
}
- ctl = pipe->mixer->ctl;
mdss_mdp_pipe_unmap(pipe);
return ret;
@@ -1291,12 +1303,16 @@
mfd->ctl = ctl;
}
+ pm_runtime_get_sync(&mfd->pdev->dev);
+
rc = mdss_mdp_ctl_start(mfd->ctl);
if (rc == 0) {
atomic_inc(&ov_active_panels);
} else {
mdss_mdp_ctl_destroy(mfd->ctl);
mfd->ctl = NULL;
+
+ pm_runtime_put(&mfd->pdev->dev);
}
return rc;
@@ -1329,6 +1345,8 @@
if (atomic_dec_return(&ov_active_panels) == 0)
mdss_mdp_rotator_release_all();
+
+ pm_runtime_put(&mfd->pdev->dev);
}
return rc;
@@ -1369,6 +1387,9 @@
return rc;
}
+ pm_runtime_set_suspended(&mfd->pdev->dev);
+ pm_runtime_enable(&mfd->pdev->dev);
+
kobject_uevent(&dev->kobj, KOBJ_ADD);
pr_debug("vsync kobject_uevent(KOBJ_ADD)\n");
diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c
index ee48f31..851d608 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pp.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pp.c
@@ -844,9 +844,6 @@
int mdss_mdp_pp_init(struct device *dev)
{
int ret = 0;
- int i;
- u32 offset;
- uint32_t data[ENHIST_LUT_ENTRIES];
mutex_lock(&mdss_pp_mutex);
if (!mdss_pp_res) {
@@ -856,20 +853,6 @@
pr_err("%s mdss_pp_res allocation failed!", __func__);
ret = -ENOMEM;
}
-
- for (i = 0; i < ENHIST_LUT_ENTRIES; i++)
- data[i] = i;
-
- mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
- /* Initialize Histogram LUT for all DSPPs */
- for (i = 0; i < MDSS_MDP_MAX_DSPP; i++) {
- offset = MDSS_MDP_REG_DSPP_OFFSET(i) +
- MDSS_MDP_REG_DSPP_HIST_LUT_BASE;
- mdss_pp_res->enhist_disp_cfg[i].data = data;
- pp_update_hist_lut(offset,
- &mdss_pp_res->enhist_disp_cfg[i]);
- }
- mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
}
mutex_unlock(&mdss_pp_mutex);
return ret;
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 1e49be4..7b3823e 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -23,6 +23,7 @@
#define ___GFP_REPEAT 0x400u
#define ___GFP_NOFAIL 0x800u
#define ___GFP_NORETRY 0x1000u
+#define ___GFP_CMA 0x2000u
#define ___GFP_COMP 0x4000u
#define ___GFP_ZERO 0x8000u
#define ___GFP_NOMEMALLOC 0x10000u
@@ -51,7 +52,9 @@
#define __GFP_HIGHMEM ((__force gfp_t)___GFP_HIGHMEM)
#define __GFP_DMA32 ((__force gfp_t)___GFP_DMA32)
#define __GFP_MOVABLE ((__force gfp_t)___GFP_MOVABLE) /* Page is movable */
-#define GFP_ZONEMASK (__GFP_DMA|__GFP_HIGHMEM|__GFP_DMA32|__GFP_MOVABLE)
+#define __GFP_CMA ((__force gfp_t)___GFP_CMA)
+#define GFP_ZONEMASK (__GFP_DMA|__GFP_HIGHMEM|__GFP_DMA32|__GFP_MOVABLE| \
+ __GFP_CMA)
/*
* Action modifiers - doesn't change the zoning
*
@@ -124,7 +127,7 @@
#endif
/* This mask makes up all the page movable related flags */
-#define GFP_MOVABLE_MASK (__GFP_RECLAIMABLE|__GFP_MOVABLE)
+#define GFP_MOVABLE_MASK (__GFP_RECLAIMABLE|__GFP_MOVABLE|__GFP_CMA)
/* Control page allocator reclaim behavior */
#define GFP_RECLAIM_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_FS|\
@@ -157,8 +160,14 @@
return MIGRATE_UNMOVABLE;
/* Group based on mobility */
+#ifndef CONFIG_CMA
return (((gfp_flags & __GFP_MOVABLE) != 0) << 1) |
((gfp_flags & __GFP_RECLAIMABLE) != 0);
+#else
+ return (((gfp_flags & __GFP_MOVABLE) != 0) << 1) |
+ (((gfp_flags & __GFP_CMA) != 0) << 1) |
+ ((gfp_flags & __GFP_RECLAIMABLE) != 0);
+#endif
}
#ifdef CONFIG_HIGHMEM
diff --git a/include/linux/highmem.h b/include/linux/highmem.h
index d3999b4..c737eb7 100644
--- a/include/linux/highmem.h
+++ b/include/linux/highmem.h
@@ -211,9 +211,24 @@
alloc_zeroed_user_highpage_movable(struct vm_area_struct *vma,
unsigned long vaddr)
{
+#ifndef CONFIG_CMA
return __alloc_zeroed_user_highpage(__GFP_MOVABLE, vma, vaddr);
+#else
+ return __alloc_zeroed_user_highpage(__GFP_MOVABLE|__GFP_CMA, vma,
+ vaddr);
+#endif
}
+#ifdef CONFIG_CMA
+static inline struct page *
+alloc_zeroed_user_highpage_movable_cma(struct vm_area_struct *vma,
+ unsigned long vaddr)
+{
+ return __alloc_zeroed_user_highpage(__GFP_MOVABLE|__GFP_CMA, vma,
+ vaddr);
+}
+#endif
+
static inline void clear_highpage(struct page *page)
{
void *kaddr = kmap_atomic(page);
diff --git a/kernel/include/linux/input/synaptics_dsx.h b/include/linux/input/synaptics_dsx.h
similarity index 100%
rename from kernel/include/linux/input/synaptics_dsx.h
rename to include/linux/input/synaptics_dsx.h
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 90980b7..6e12694 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -390,6 +390,7 @@
* process to make sure that the system is not starved.
*/
unsigned long min_cma_pages;
+ bool cma_alloc;
#endif
struct free_area free_area[MAX_ORDER];
diff --git a/include/linux/msm_ion.h b/include/linux/msm_ion.h
index ffa819f..409bcc8 100644
--- a/include/linux/msm_ion.h
+++ b/include/linux/msm_ion.h
@@ -22,6 +22,7 @@
ION_HEAP_TYPE_MSM_START = ION_HEAP_TYPE_CUSTOM + 1,
ION_HEAP_TYPE_IOMMU = ION_HEAP_TYPE_MSM_START,
ION_HEAP_TYPE_CP,
+ ION_HEAP_TYPE_SECURE_DMA,
};
/**
diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h
index 72febbb..3ec966b 100644
--- a/include/linux/msm_mdp.h
+++ b/include/linux/msm_mdp.h
@@ -577,10 +577,12 @@
} data;
};
+#define FB_METADATA_VIDEO_INFO_CODE_SUPPORT 1
enum {
metadata_op_none,
metadata_op_base_blend,
metadata_op_frame_rate,
+ metadata_op_vic,
metadata_op_max
};
@@ -594,6 +596,7 @@
union {
struct mdp_blend_cfg blend_cfg;
uint32_t panel_frame_rate;
+ uint32_t video_info_code;
} data;
};
diff --git a/include/linux/qpnp/qpnp-adc.h b/include/linux/qpnp/qpnp-adc.h
index a3347c4..1849cee 100644
--- a/include/linux/qpnp/qpnp-adc.h
+++ b/include/linux/qpnp/qpnp-adc.h
@@ -1149,6 +1149,23 @@
*/
int32_t qpnp_adc_usb_scaler(struct qpnp_adc_tm_usbid_param *param,
uint32_t *low_threshold, uint32_t *high_threshold);
+/**
+ * qpnp_vadc_iadc_sync_request() - Performs Voltage ADC read and
+ * locks the peripheral. When performing simultaneous
+ * voltage and current request the VADC peripheral is
+ * prepared for conversion and the IADC sync conversion
+ * is done from the IADC peripheral.
+ * @channel: Input channel to perform the voltage ADC read.
+ */
+int32_t qpnp_vadc_iadc_sync_request(enum qpnp_vadc_channels channel);
+/**
+ * qpnp_vadc_iadc_sync_complete_request() - Reads the ADC result and
+ * unlocks the peripheral.
+ * @result: Structure pointer of type adc_chan_result
+ * in which the ADC read results are stored.
+ */
+int32_t qpnp_vadc_iadc_sync_complete_request(
+ enum qpnp_vadc_channels channel, struct qpnp_vadc_result *result);
#else
static inline int32_t qpnp_vadc_read(uint32_t channel,
struct qpnp_vadc_result *result)
@@ -1218,6 +1235,13 @@
static inline int32_t qpnp_adc_tm_scale_voltage_therm_pu2(
uint32_t reg, int64_t *result)
{ return -ENXIO; }
+static inline int32_t qpnp_vadc_iadc_sync_request(
+ enum qpnp_vadc_channels channel)
+{ return -ENXIO; }
+static inline int32_t qpnp_vadc_iadc_sync_complete_request(
+ enum qpnp_vadc_channels channel,
+ struct qpnp_vadc_result *result)
+{ return -ENXIO; }
#endif
/* Public API */
@@ -1226,7 +1250,7 @@
/**
* qpnp_iadc_read() - Performs ADC read on the current channel.
* @channel: Input channel to perform the ADC read.
- * @result: Current across rsens in mV.
+ * @result: Current across rsense in mA.
*/
int32_t qpnp_iadc_read(enum qpnp_iadc_channels channel,
struct qpnp_iadc_result *result);
@@ -1245,7 +1269,6 @@
* type qpnp_iadc_calib.
*/
int32_t qpnp_iadc_get_gain_and_offset(struct qpnp_iadc_calib *result);
-
/**
* qpnp_iadc_is_ready() - Clients can use this API to check if the
* device is ready to use.
@@ -1253,15 +1276,34 @@
* has not occured.
*/
int32_t qpnp_iadc_is_ready(void);
+/**
+ * qpnp_iadc_vadc_sync_read() - Performs synchronous VADC and IADC read.
+ * The api is to be used only by the BMS to perform
+ * simultaneous VADC and IADC measurement for battery voltage
+ * and current.
+ * @i_channel: Input battery current channel to perform the IADC read.
+ * @i_result: Current across the rsense in mA.
+ * @v_channel: Input battery voltage channel to perform VADC read.
+ * @v_result: Voltage on the vbatt channel with units in mV.
+ */
+int32_t qpnp_iadc_vadc_sync_read(
+ enum qpnp_iadc_channels i_channel, struct qpnp_iadc_result *i_result,
+ enum qpnp_vadc_channels v_channel, struct qpnp_vadc_result *v_result);
#else
static inline int32_t qpnp_iadc_read(enum qpnp_iadc_channels channel,
struct qpnp_iadc_result *result)
{ return -ENXIO; }
+static inline int32_t qpnp_iadc_get_rsense(int32_t *rsense)
+{ return -ENXIO; }
static inline int32_t qpnp_iadc_get_gain_and_offset(struct qpnp_iadc_calib
*result)
{ return -ENXIO; }
static inline int32_t qpnp_iadc_is_ready(void)
{ return -ENXIO; }
+static inline int32_t qpnp_iadc_vadc_sync_read(
+ enum qpnp_iadc_channels i_channel, struct qpnp_iadc_result *i_result,
+ enum qpnp_vadc_channels v_channel, struct qpnp_vadc_result *v_result)
+{ return -ENXIO; }
#endif
/* Public API */
@@ -1323,8 +1365,6 @@
{ return -ENXIO; }
static inline int32_t qpnp_adc_tm_is_ready(void)
{ return -ENXIO; }
-static inline int32_t qpnp_iadc_get_rsense(int32_t *rsense)
-{ return -ENXIO; }
#endif
#endif
diff --git a/include/linux/tspp.h b/include/linux/tspp.h
index 551fbb0..c790c28 100644
--- a/include/linux/tspp.h
+++ b/include/linux/tspp.h
@@ -88,5 +88,7 @@
_IOW(TSPP_IOCTL_BASE, 5, struct tspp_system_keys)
#define TSPP_IOCTL_BUFFER_SIZE \
_IOW(TSPP_IOCTL_BASE, 6, struct tspp_buffer)
+#define TSPP_IOCTL_CLOSE_STREAM \
+ _IO(TSPP_IOCTL_BASE, 7)
#endif /* _TSPP_H_ */
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
index 268aa48..4fb20f6 100644
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
@@ -349,9 +349,8 @@
/* to log submission/completion events*/
void (*log_urb)(struct urb *urb, char *event, unsigned extra);
void (*dump_regs)(struct usb_hcd *);
- void (*enable_ulpi_control)(struct usb_hcd *hcd, u32 linestate);
- void (*disable_ulpi_control)(struct usb_hcd *hcd);
void (*set_autosuspend_delay)(struct usb_device *);
+ void (*reset_sof_bug_handler)(struct usb_hcd *hcd, u32 val);
};
extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb);
diff --git a/include/media/Kbuild b/include/media/Kbuild
index 060047f..16786a9 100644
--- a/include/media/Kbuild
+++ b/include/media/Kbuild
@@ -14,3 +14,4 @@
header-y += msmb_isp.h
header-y += msmb_ispif.h
header-y += msmb_generic_buf_mgr.h
+header-y += msmb_pproc.h
diff --git a/include/media/msmb_generic_buf_mgr.h b/include/media/msmb_generic_buf_mgr.h
index 8981a3f..13844a3 100644
--- a/include/media/msmb_generic_buf_mgr.h
+++ b/include/media/msmb_generic_buf_mgr.h
@@ -1,19 +1,21 @@
#ifndef __MEDIA_MSMB_BUF_MNGR_H__
#define __MEDIA_MSMB_BUF_MNGR_H__
-#define VIDIOC_MSM_BUF_MNGR_GET_BUF \
- _IOWR('V', BASE_VIDIOC_PRIVATE + 33, struct msm_buf_mngr_info *)
-
-#define VIDIOC_MSM_BUF_MNGR_PUT_BUF \
- _IOWR('V', BASE_VIDIOC_PRIVATE + 34, struct msm_buf_mngr_info *)
-
-#define VIDIOC_MSM_BUF_MNGR_BUF_DONE \
- _IOWR('V', BASE_VIDIOC_PRIVATE + 35, struct msm_buf_mngr_info *)
-
struct msm_buf_mngr_info {
uint32_t session_id;
uint32_t stream_id;
+ uint32_t frame_id;
uint32_t index;
};
+
+#define VIDIOC_MSM_BUF_MNGR_GET_BUF \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 33, struct msm_buf_mngr_info)
+
+#define VIDIOC_MSM_BUF_MNGR_PUT_BUF \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 34, struct msm_buf_mngr_info)
+
+#define VIDIOC_MSM_BUF_MNGR_BUF_DONE \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 35, struct msm_buf_mngr_info)
+
#endif
diff --git a/include/media/msmb_pproc.h b/include/media/msmb_pproc.h
new file mode 100644
index 0000000..939c4e3
--- /dev/null
+++ b/include/media/msmb_pproc.h
@@ -0,0 +1,114 @@
+#ifndef __MSMB_PPROC_H
+#define __MSMB_PPROC_H
+
+#ifdef MSM_CAMERA_BIONIC
+#include <sys/types.h>
+#endif
+#include <linux/videodev2.h>
+#include <linux/types.h>
+
+/* Should be same as VIDEO_MAX_PLANES in videodev2.h */
+#define MAX_PLANES VIDEO_MAX_PLANES
+
+#define MAX_NUM_CPP_STRIPS 8
+
+enum msm_cpp_frame_type {
+ MSM_CPP_OFFLINE_FRAME,
+ MSM_CPP_REALTIME_FRAME,
+};
+
+struct msm_cpp_frame_strip_info {
+ int scale_v_en;
+ int scale_h_en;
+
+ int upscale_v_en;
+ int upscale_h_en;
+
+ int src_start_x;
+ int src_end_x;
+ int src_start_y;
+ int src_end_y;
+
+ /* Padding is required for upscaler because it does not
+ * pad internally like other blocks, also needed for rotation
+ * rotation expects all the blocks in the stripe to be the same size
+ * Padding is done such that all the extra padded pixels
+ * are on the right and bottom
+ */
+ int pad_bottom;
+ int pad_top;
+ int pad_right;
+ int pad_left;
+
+ int v_init_phase;
+ int h_init_phase;
+ int h_phase_step;
+ int v_phase_step;
+
+ int prescale_crop_width_first_pixel;
+ int prescale_crop_width_last_pixel;
+ int prescale_crop_height_first_line;
+ int prescale_crop_height_last_line;
+
+ int postscale_crop_height_first_line;
+ int postscale_crop_height_last_line;
+ int postscale_crop_width_first_pixel;
+ int postscale_crop_width_last_pixel;
+
+ int dst_start_x;
+ int dst_end_x;
+ int dst_start_y;
+ int dst_end_y;
+
+ int bytes_per_pixel;
+ unsigned int source_address;
+ unsigned int destination_address;
+ unsigned int src_stride;
+ unsigned int dst_stride;
+ int rotate_270;
+ int horizontal_flip;
+ int vertical_flip;
+ int scale_output_width;
+ int scale_output_height;
+ int prescale_crop_en;
+ int postscale_crop_en;
+};
+
+struct msm_cpp_frame_info_t {
+ int32_t frame_id;
+ uint32_t inst_id;
+ uint32_t client_id;
+ enum msm_cpp_frame_type frame_type;
+ uint32_t num_strips;
+ struct msm_cpp_frame_strip_info *strip_info;
+ uint32_t msg_len;
+ uint32_t *cpp_cmd_msg;
+ int src_fd;
+ int dst_fd;
+};
+
+struct msm_ver_num_info {
+ uint32_t main;
+ uint32_t minor;
+ uint32_t rev;
+};
+
+#define VIDIOC_MSM_CPP_CFG \
+ _IOWR('V', BASE_VIDIOC_PRIVATE, struct msm_camera_v4l2_ioctl_t)
+
+#define VIDIOC_MSM_CPP_GET_EVENTPAYLOAD \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 1, struct msm_camera_v4l2_ioctl_t)
+
+#define VIDIOC_MSM_CPP_GET_INST_INFO \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 2, struct msm_camera_v4l2_ioctl_t)
+
+#define V4L2_EVENT_CPP_FRAME_DONE (V4L2_EVENT_PRIVATE_START + 0)
+
+struct msm_camera_v4l2_ioctl_t {
+ uint32_t id;
+ uint32_t len;
+ uint32_t trans_code;
+ void __user *ioctl_ptr;
+};
+
+#endif /* __MSMB_PPROC_H */
diff --git a/kernel/arch/arm/configs/omap3_beagle_android_defconfig b/kernel/arch/arm/configs/omap3_beagle_android_defconfig
deleted file mode 100644
index 4fc62c4fa..0000000
--- a/kernel/arch/arm/configs/omap3_beagle_android_defconfig
+++ /dev/null
@@ -1,2419 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux/arm 2.6.37 Kernel Configuration
-# Mon Apr 16 13:58:06 2012
-#
-CONFIG_ARM=y
-CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-CONFIG_GENERIC_GPIO=y
-# CONFIG_ARCH_USES_GETTIMEOFFSET is not set
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_HAVE_PROC_CPU=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_STACKTRACE_SUPPORT=y
-CONFIG_HAVE_LATENCYTOP_SUPPORT=y
-CONFIG_LOCKDEP_SUPPORT=y
-CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_ARCH_HAS_CPUFREQ=y
-CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
-CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_ARM_L1_CACHE_SHIFT_6=y
-CONFIG_VECTORS_BASE=0xffff0000
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-CONFIG_CONSTRUCTORS=y
-CONFIG_HAVE_IRQ_WORK=y
-CONFIG_IRQ_WORK=y
-
-#
-# General setup
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-CONFIG_CROSS_COMPILE=""
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_HAVE_KERNEL_GZIP=y
-CONFIG_HAVE_KERNEL_LZMA=y
-CONFIG_HAVE_KERNEL_LZO=y
-CONFIG_KERNEL_GZIP=y
-# CONFIG_KERNEL_LZMA is not set
-# CONFIG_KERNEL_LZO is not set
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-CONFIG_SYSVIPC_SYSCTL=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_POSIX_MQUEUE_SYSCTL=y
-CONFIG_BSD_PROCESS_ACCT=y
-# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-# CONFIG_TASKSTATS is not set
-# CONFIG_AUDIT is not set
-# CONFIG_HAVE_GENERIC_HARDIRQS is not set
-# CONFIG_SPARSE_IRQ is not set
-
-#
-# RCU Subsystem
-#
-CONFIG_TINY_RCU=y
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=16
-# CONFIG_CGROUPS is not set
-# CONFIG_NAMESPACES is not set
-# CONFIG_SYSFS_DEPRECATED is not set
-# CONFIG_RELAY is not set
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_RD_GZIP=y
-# CONFIG_RD_BZIP2 is not set
-# CONFIG_RD_LZMA is not set
-# CONFIG_RD_LZO is not set
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_SYSCTL=y
-CONFIG_ANON_INODES=y
-CONFIG_PANIC_TIMEOUT=0
-CONFIG_EMBEDDED=y
-CONFIG_UID16=y
-# CONFIG_SYSCTL_SYSCALL is not set
-CONFIG_KALLSYMS=y
-CONFIG_KALLSYMS_EXTRA_PASS=y
-CONFIG_HOTPLUG=y
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_ELF_CORE=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_SIGNALFD=y
-CONFIG_TIMERFD=y
-CONFIG_EVENTFD=y
-CONFIG_SHMEM=y
-CONFIG_ASHMEM=y
-CONFIG_AIO=y
-CONFIG_HAVE_PERF_EVENTS=y
-CONFIG_PERF_USE_VMALLOC=y
-
-#
-# Kernel Performance Events And Counters
-#
-CONFIG_PERF_EVENTS=y
-# CONFIG_PERF_COUNTERS is not set
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_COMPAT_BRK=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
-# CONFIG_SLOB is not set
-CONFIG_PROFILING=y
-CONFIG_TRACEPOINTS=y
-CONFIG_OPROFILE=y
-CONFIG_HAVE_OPROFILE=y
-CONFIG_KPROBES=y
-CONFIG_KRETPROBES=y
-CONFIG_HAVE_KPROBES=y
-CONFIG_HAVE_KRETPROBES=y
-CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
-CONFIG_HAVE_CLK=y
-CONFIG_HAVE_HW_BREAKPOINT=y
-
-#
-# GCOV-based kernel profiling
-#
-# CONFIG_GCOV_KERNEL is not set
-CONFIG_HAVE_GENERIC_DMA_COHERENT=y
-CONFIG_SLABINFO=y
-CONFIG_RT_MUTEXES=y
-CONFIG_BASE_SMALL=0
-CONFIG_MODULES=y
-# CONFIG_MODULE_FORCE_LOAD is not set
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_BLOCK=y
-CONFIG_LBDAF=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_BLK_DEV_INTEGRITY is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_DEADLINE is not set
-CONFIG_DEFAULT_CFQ=y
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="cfq"
-# CONFIG_INLINE_SPIN_TRYLOCK is not set
-# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
-# CONFIG_INLINE_SPIN_LOCK is not set
-# CONFIG_INLINE_SPIN_LOCK_BH is not set
-# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
-# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
-CONFIG_INLINE_SPIN_UNLOCK=y
-# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
-CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
-# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
-# CONFIG_INLINE_READ_TRYLOCK is not set
-# CONFIG_INLINE_READ_LOCK is not set
-# CONFIG_INLINE_READ_LOCK_BH is not set
-# CONFIG_INLINE_READ_LOCK_IRQ is not set
-# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
-CONFIG_INLINE_READ_UNLOCK=y
-# CONFIG_INLINE_READ_UNLOCK_BH is not set
-CONFIG_INLINE_READ_UNLOCK_IRQ=y
-# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
-# CONFIG_INLINE_WRITE_TRYLOCK is not set
-# CONFIG_INLINE_WRITE_LOCK is not set
-# CONFIG_INLINE_WRITE_LOCK_BH is not set
-# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
-# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
-CONFIG_INLINE_WRITE_UNLOCK=y
-# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
-CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
-# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
-# CONFIG_MUTEX_SPIN_ON_OWNER is not set
-CONFIG_FREEZER=y
-
-#
-# System Type
-#
-CONFIG_MMU=y
-# CONFIG_ARCH_AAEC2000 is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_REALVIEW is not set
-# CONFIG_ARCH_VERSATILE is not set
-# CONFIG_ARCH_VEXPRESS is not set
-# CONFIG_ARCH_AT91 is not set
-# CONFIG_ARCH_BCMRING is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CNS3XXX is not set
-# CONFIG_ARCH_GEMINI is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_EP93XX is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_MXC is not set
-# CONFIG_ARCH_STMP3XXX is not set
-# CONFIG_ARCH_NETX is not set
-# CONFIG_ARCH_H720X is not set
-# CONFIG_ARCH_IOP13XX is not set
-# CONFIG_ARCH_IOP32X is not set
-# CONFIG_ARCH_IOP33X is not set
-# CONFIG_ARCH_IXP23XX is not set
-# CONFIG_ARCH_IXP2000 is not set
-# CONFIG_ARCH_IXP4XX is not set
-# CONFIG_ARCH_DOVE is not set
-# CONFIG_ARCH_KIRKWOOD is not set
-# CONFIG_ARCH_LOKI is not set
-# CONFIG_ARCH_LPC32XX is not set
-# CONFIG_ARCH_MV78XX0 is not set
-# CONFIG_ARCH_ORION5X is not set
-# CONFIG_ARCH_MMP is not set
-# CONFIG_ARCH_KS8695 is not set
-# CONFIG_ARCH_NS9XXX is not set
-# CONFIG_ARCH_W90X900 is not set
-# CONFIG_ARCH_NUC93X is not set
-# CONFIG_ARCH_TEGRA is not set
-# CONFIG_ARCH_PNX4008 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_MSM is not set
-# CONFIG_ARCH_SHMOBILE is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_S3C2410 is not set
-# CONFIG_ARCH_S3C64XX is not set
-# CONFIG_ARCH_S5P64X0 is not set
-# CONFIG_ARCH_S5P6442 is not set
-# CONFIG_ARCH_S5PC100 is not set
-# CONFIG_ARCH_S5PV210 is not set
-# CONFIG_ARCH_S5PV310 is not set
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_TCC_926 is not set
-# CONFIG_ARCH_LH7A40X is not set
-# CONFIG_ARCH_U300 is not set
-# CONFIG_ARCH_U8500 is not set
-# CONFIG_ARCH_NOMADIK is not set
-# CONFIG_ARCH_DAVINCI is not set
-CONFIG_ARCH_OMAP=y
-# CONFIG_PLAT_SPEAR is not set
-
-#
-# TI OMAP Common Features
-#
-CONFIG_ARCH_OMAP_OTG=y
-# CONFIG_ARCH_OMAP1 is not set
-CONFIG_ARCH_OMAP2PLUS=y
-
-#
-# OMAP Feature Selections
-#
-CONFIG_OMAP_SMARTREFLEX=y
-CONFIG_OMAP_SMARTREFLEX_CLASS3=y
-CONFIG_OMAP_RESET_CLOCKS=y
-CONFIG_OMAP_MUX=y
-CONFIG_OMAP_MUX_DEBUG=y
-CONFIG_OMAP_MUX_WARNINGS=y
-CONFIG_OMAP_MCBSP=y
-# CONFIG_OMAP_MBOX_FWK is not set
-CONFIG_OMAP_IOMMU=y
-# CONFIG_OMAP_IOMMU_DEBUG is not set
-# CONFIG_OMAP_MPU_TIMER is not set
-CONFIG_OMAP_32K_TIMER=y
-# CONFIG_OMAP3_L2_AUX_SECURE_SAVE_RESTORE is not set
-CONFIG_OMAP_32K_TIMER_HZ=128
-CONFIG_OMAP_DM_TIMER=y
-# CONFIG_OMAP_PM_NONE is not set
-CONFIG_OMAP_PM_NOOP=y
-
-#
-# TI OMAP2/3/4 Specific Features
-#
-CONFIG_ARCH_OMAP2PLUS_TYPICAL=y
-# CONFIG_ARCH_OMAP2 is not set
-CONFIG_ARCH_OMAP3=y
-# CONFIG_ARCH_OMAP4 is not set
-# CONFIG_ARCH_TI81XX is not set
-CONFIG_ARCH_OMAP3430=y
-CONFIG_OMAP_PACKAGE_CBB=y
-
-#
-# OMAP Board Type
-#
-CONFIG_MACH_OMAP3_BEAGLE=y
-# CONFIG_MACH_DEVKIT8000 is not set
-# CONFIG_MACH_OMAP_LDP is not set
-# CONFIG_MACH_OMAP3530_LV_SOM is not set
-# CONFIG_MACH_OMAP3_TORPEDO is not set
-# CONFIG_MACH_OVERO is not set
-# CONFIG_MACH_OMAP3EVM is not set
-# CONFIG_MACH_FLASHBOARD is not set
-# CONFIG_MACH_OMAP3517EVM is not set
-# CONFIG_MACH_CRANEBOARD is not set
-# CONFIG_MACH_OMAP3_PANDORA is not set
-# CONFIG_MACH_OMAP3_TOUCHBOOK is not set
-# CONFIG_MACH_OMAP_3430SDP is not set
-# CONFIG_MACH_NOKIA_RM680 is not set
-# CONFIG_MACH_NOKIA_RX51 is not set
-# CONFIG_MACH_OMAP_ZOOM2 is not set
-# CONFIG_MACH_OMAP_ZOOM3 is not set
-# CONFIG_MACH_CM_T35 is not set
-# CONFIG_MACH_CM_T3517 is not set
-# CONFIG_MACH_IGEP0020 is not set
-# CONFIG_MACH_IGEP0030 is not set
-# CONFIG_MACH_SBC3530 is not set
-# CONFIG_MACH_OMAP_3630SDP is not set
-# CONFIG_OMAP3_EMU is not set
-CONFIG_OMAP3_PM_DISABLE_VT_SWITCH=y
-# CONFIG_OMAP3_SDRC_AC_TIMING is not set
-
-#
-# Processor Type
-#
-CONFIG_CPU_32v6K=y
-CONFIG_CPU_V7=y
-CONFIG_CPU_32v7=y
-CONFIG_CPU_ABRT_EV7=y
-CONFIG_CPU_PABRT_V7=y
-CONFIG_CPU_CACHE_V7=y
-CONFIG_CPU_CACHE_VIPT=y
-CONFIG_CPU_COPY_V6=y
-CONFIG_CPU_TLB_V7=y
-CONFIG_CPU_HAS_ASID=y
-CONFIG_CPU_CP15=y
-CONFIG_CPU_CP15_MMU=y
-
-#
-# Processor Features
-#
-CONFIG_ARM_THUMB=y
-CONFIG_ARM_THUMBEE=y
-# CONFIG_CPU_ICACHE_DISABLE is not set
-# CONFIG_CPU_DCACHE_DISABLE is not set
-# CONFIG_CPU_BPREDICT_DISABLE is not set
-CONFIG_ARM_L1_CACHE_SHIFT=6
-CONFIG_ARM_DMA_MEM_BUFFERABLE=y
-# CONFIG_ARM_ERRATA_430973 is not set
-# CONFIG_ARM_ERRATA_458693 is not set
-# CONFIG_ARM_ERRATA_460075 is not set
-# CONFIG_ARM_ERRATA_743622 is not set
-CONFIG_COMMON_CLKDEV=y
-# CONFIG_FIQ_DEBUGGER is not set
-
-#
-# Bus support
-#
-# CONFIG_PCI_SYSCALL is not set
-# CONFIG_ARCH_SUPPORTS_MSI is not set
-# CONFIG_PCCARD is not set
-
-#
-# Kernel Features
-#
-CONFIG_TICK_ONESHOT=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
-CONFIG_VMSPLIT_3G=y
-# CONFIG_VMSPLIT_2G is not set
-# CONFIG_VMSPLIT_1G is not set
-CONFIG_PAGE_OFFSET=0xC0000000
-CONFIG_PREEMPT_NONE=y
-# CONFIG_PREEMPT_VOLUNTARY is not set
-# CONFIG_PREEMPT is not set
-CONFIG_HZ=128
-# CONFIG_THUMB2_KERNEL is not set
-CONFIG_AEABI=y
-CONFIG_OABI_COMPAT=y
-CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y
-# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
-# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
-# CONFIG_HIGHMEM is not set
-CONFIG_SELECT_MEMORY_MODEL=y
-CONFIG_FLATMEM_MANUAL=y
-CONFIG_FLATMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-CONFIG_HAVE_MEMBLOCK=y
-CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_PHYS_ADDR_T_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=0
-CONFIG_VIRT_TO_BUS=y
-# CONFIG_KSM is not set
-CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
-CONFIG_NEED_PER_CPU_KM=y
-CONFIG_FORCE_MAX_ZONEORDER=11
-# CONFIG_LEDS is not set
-CONFIG_ALIGNMENT_TRAP=y
-# CONFIG_UACCESS_WITH_MEMCPY is not set
-# CONFIG_SECCOMP is not set
-# CONFIG_CC_STACKPROTECTOR is not set
-# CONFIG_DEPRECATED_PARAM_STRUCT is not set
-
-#
-# Boot options
-#
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="root=/dev/mmcblk0p2 rootwait console=ttyO2,115200"
-# CONFIG_CMDLINE_FORCE is not set
-# CONFIG_XIP_KERNEL is not set
-CONFIG_KEXEC=y
-CONFIG_ATAGS_PROC=y
-# CONFIG_AUTO_ZRELADDR is not set
-
-#
-# CPU Power Management
-#
-CONFIG_CPU_FREQ=y
-CONFIG_CPU_FREQ_TABLE=y
-# CONFIG_CPU_FREQ_DEBUG is not set
-CONFIG_CPU_FREQ_STAT=y
-CONFIG_CPU_FREQ_STAT_DETAILS=y
-CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
-# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
-# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
-# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
-# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
-# CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE is not set
-CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
-# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
-CONFIG_CPU_FREQ_GOV_USERSPACE=y
-CONFIG_CPU_FREQ_GOV_ONDEMAND=y
-# CONFIG_CPU_FREQ_GOV_INTERACTIVE is not set
-# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
-CONFIG_CPU_IDLE=y
-CONFIG_CPU_IDLE_GOV_LADDER=y
-CONFIG_CPU_IDLE_GOV_MENU=y
-
-#
-# Floating point emulation
-#
-
-#
-# At least one emulation must be selected
-#
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_NWFPE_XP is not set
-# CONFIG_FPE_FASTFPE is not set
-CONFIG_VFP=y
-CONFIG_VFPv3=y
-CONFIG_NEON=y
-
-#
-# Userspace binary formats
-#
-CONFIG_BINFMT_ELF=y
-CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
-CONFIG_HAVE_AOUT=y
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_MISC=y
-
-#
-# Power management options
-#
-CONFIG_PM=y
-CONFIG_PM_DEBUG=y
-# CONFIG_PM_ADVANCED_DEBUG is not set
-# CONFIG_PM_VERBOSE is not set
-CONFIG_CAN_PM_TRACE=y
-CONFIG_PM_SLEEP=y
-CONFIG_SUSPEND_NVS=y
-CONFIG_SUSPEND=y
-# CONFIG_PM_TEST_SUSPEND is not set
-CONFIG_SUSPEND_FREEZER=y
-CONFIG_HAS_WAKELOCK=y
-CONFIG_HAS_EARLYSUSPEND=y
-CONFIG_WAKELOCK=y
-CONFIG_WAKELOCK_STAT=y
-CONFIG_USER_WAKELOCK=y
-CONFIG_EARLYSUSPEND=y
-# CONFIG_NO_USER_SPACE_SCREEN_ACCESS_CONTROL is not set
-# CONFIG_CONSOLE_EARLYSUSPEND is not set
-CONFIG_FB_EARLYSUSPEND=y
-# CONFIG_APM_EMULATION is not set
-CONFIG_PM_RUNTIME=y
-CONFIG_PM_OPS=y
-CONFIG_ARCH_HAS_OPP=y
-CONFIG_PM_OPP=y
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=y
-# CONFIG_XFRM_SUB_POLICY is not set
-CONFIG_XFRM_MIGRATE=y
-# CONFIG_XFRM_STATISTICS is not set
-CONFIG_NET_KEY=y
-CONFIG_NET_KEY_MIGRATE=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_FIB_HASH=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE_DEMUX is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_XFRM_TUNNEL is not set
-CONFIG_INET_TUNNEL=y
-CONFIG_INET_XFRM_MODE_TRANSPORT=y
-CONFIG_INET_XFRM_MODE_TUNNEL=y
-CONFIG_INET_XFRM_MODE_BEET=y
-# CONFIG_INET_LRO is not set
-CONFIG_INET_DIAG=y
-CONFIG_INET_TCP_DIAG=y
-# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_CUBIC=y
-CONFIG_DEFAULT_TCP_CONG="cubic"
-# CONFIG_TCP_MD5SIG is not set
-CONFIG_IPV6=y
-# CONFIG_IPV6_PRIVACY is not set
-# CONFIG_IPV6_ROUTER_PREF is not set
-# CONFIG_IPV6_OPTIMISTIC_DAD is not set
-# CONFIG_INET6_AH is not set
-# CONFIG_INET6_ESP is not set
-# CONFIG_INET6_IPCOMP is not set
-# CONFIG_IPV6_MIP6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
-CONFIG_INET6_XFRM_MODE_TRANSPORT=y
-CONFIG_INET6_XFRM_MODE_TUNNEL=y
-CONFIG_INET6_XFRM_MODE_BEET=y
-# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
-CONFIG_IPV6_SIT=y
-# CONFIG_IPV6_SIT_6RD is not set
-CONFIG_IPV6_NDISC_NODETYPE=y
-# CONFIG_IPV6_TUNNEL is not set
-# CONFIG_IPV6_MULTIPLE_TABLES is not set
-# CONFIG_IPV6_MROUTE is not set
-# CONFIG_NETLABEL is not set
-CONFIG_ANDROID_PARANOID_NETWORK=y
-CONFIG_NET_ACTIVITY_STATS=y
-# CONFIG_NETWORK_SECMARK is not set
-# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
-# CONFIG_NETFILTER is not set
-# CONFIG_IP_DCCP is not set
-# CONFIG_IP_SCTP is not set
-# CONFIG_RDS is not set
-# CONFIG_TIPC is not set
-# CONFIG_ATM is not set
-# CONFIG_L2TP is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_NET_DSA is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_PHONET is not set
-# CONFIG_IEEE802154 is not set
-# CONFIG_NET_SCHED is not set
-# CONFIG_DCB is not set
-CONFIG_DNS_RESOLVER=y
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NET_TCPPROBE is not set
-# CONFIG_NET_DROP_MONITOR is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_CAN is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-# CONFIG_AF_RXRPC is not set
-CONFIG_WIRELESS=y
-CONFIG_WIRELESS_EXT=y
-CONFIG_WEXT_CORE=y
-CONFIG_WEXT_PROC=y
-# CONFIG_CFG80211 is not set
-CONFIG_WIRELESS_EXT_SYSFS=y
-# CONFIG_LIB80211 is not set
-
-#
-# CFG80211 needs to be enabled for MAC80211
-#
-
-#
-# Some wireless drivers require a rate control algorithm
-#
-# CONFIG_WIMAX is not set
-# CONFIG_RFKILL is not set
-# CONFIG_NET_9P is not set
-# CONFIG_CAIF is not set
-# CONFIG_CEPH_LIB is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-# CONFIG_DEVTMPFS is not set
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=y
-CONFIG_FIRMWARE_IN_KERNEL=y
-CONFIG_EXTRA_FIRMWARE=""
-# CONFIG_SYS_HYPERVISOR is not set
-# CONFIG_CONNECTOR is not set
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG is not set
-# CONFIG_MTD_TESTS is not set
-CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_REDBOOT_PARTS is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-# CONFIG_MTD_AFS_PARTS is not set
-# CONFIG_MTD_AR7_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLKDEVS=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-# CONFIG_RFD_FTL is not set
-# CONFIG_SSFDC is not set
-# CONFIG_SM_FTL is not set
-CONFIG_MTD_OOPS=y
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_GEN_PROBE=y
-# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-CONFIG_MTD_CFI_INTELEXT=y
-# CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_CFI_STAA is not set
-CONFIG_MTD_CFI_UTIL=y
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_PLATRAM is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_DATAFLASH is not set
-# CONFIG_MTD_M25P80 is not set
-# CONFIG_MTD_SST25L is not set
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_PHRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLOCK2MTD is not set
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-CONFIG_MTD_NAND_IDS=y
-CONFIG_MTD_NAND_ECC=y
-# CONFIG_MTD_NAND_ECC_SMC is not set
-CONFIG_MTD_NAND=y
-# CONFIG_MTD_NAND_VERIFY_WRITE is not set
-# CONFIG_MTD_SM_COMMON is not set
-# CONFIG_MTD_NAND_MUSEUM_IDS is not set
-# CONFIG_MTD_NAND_GPIO is not set
-CONFIG_MTD_NAND_OMAP2=y
-# CONFIG_MTD_NAND_DISKONCHIP is not set
-# CONFIG_MTD_NAND_NANDSIM is not set
-# CONFIG_MTD_NAND_PLATFORM is not set
-# CONFIG_MTD_ALAUDA is not set
-CONFIG_MTD_ONENAND=y
-CONFIG_MTD_ONENAND_VERIFY_WRITE=y
-# CONFIG_MTD_ONENAND_GENERIC is not set
-CONFIG_MTD_ONENAND_OMAP2=y
-# CONFIG_MTD_ONENAND_OTP is not set
-# CONFIG_MTD_ONENAND_2X_PROGRAM is not set
-# CONFIG_MTD_ONENAND_SIM is not set
-
-#
-# LPDDR flash memory drivers
-#
-# CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_UBI is not set
-# CONFIG_PARPORT is not set
-CONFIG_BLK_DEV=y
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-
-#
-# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
-#
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_UB is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=16384
-# CONFIG_BLK_DEV_XIP is not set
-# CONFIG_CDROM_PKTCDVD is not set
-# CONFIG_ATA_OVER_ETH is not set
-# CONFIG_MG_DISK is not set
-# CONFIG_BLK_DEV_RBD is not set
-# CONFIG_MISC_DEVICES is not set
-CONFIG_HAVE_IDE=y
-# CONFIG_IDE is not set
-
-#
-# SCSI device support
-#
-CONFIG_SCSI_MOD=y
-# CONFIG_RAID_ATTRS is not set
-CONFIG_SCSI=y
-CONFIG_SCSI_DMA=y
-# CONFIG_SCSI_TGT is not set
-# CONFIG_SCSI_NETLINK is not set
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=y
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-# CONFIG_BLK_DEV_SR is not set
-# CONFIG_CHR_DEV_SG is not set
-# CONFIG_CHR_DEV_SCH is not set
-CONFIG_SCSI_MULTI_LUN=y
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-CONFIG_SCSI_SCAN_ASYNC=y
-CONFIG_SCSI_WAIT_SCAN=m
-
-#
-# SCSI Transports
-#
-# CONFIG_SCSI_SPI_ATTRS is not set
-# CONFIG_SCSI_FC_ATTRS is not set
-# CONFIG_SCSI_ISCSI_ATTRS is not set
-# CONFIG_SCSI_SAS_ATTRS is not set
-# CONFIG_SCSI_SAS_LIBSAS is not set
-# CONFIG_SCSI_SRP_ATTRS is not set
-CONFIG_SCSI_LOWLEVEL=y
-# CONFIG_ISCSI_TCP is not set
-# CONFIG_ISCSI_BOOT_SYSFS is not set
-# CONFIG_LIBFC is not set
-# CONFIG_LIBFCOE is not set
-# CONFIG_SCSI_DEBUG is not set
-# CONFIG_SCSI_DH is not set
-# CONFIG_SCSI_OSD_INITIATOR is not set
-# CONFIG_ATA is not set
-CONFIG_MD=y
-# CONFIG_BLK_DEV_MD is not set
-CONFIG_BLK_DEV_DM=y
-# CONFIG_DM_DEBUG is not set
-CONFIG_DM_CRYPT=y
-# CONFIG_DM_SNAPSHOT is not set
-# CONFIG_DM_MIRROR is not set
-# CONFIG_DM_ZERO is not set
-# CONFIG_DM_MULTIPATH is not set
-# CONFIG_DM_DELAY is not set
-CONFIG_DM_UEVENT=y
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_MACVLAN is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_VETH is not set
-CONFIG_MII=y
-CONFIG_PHYLIB=y
-
-#
-# MII PHY device drivers
-#
-# CONFIG_MARVELL_PHY is not set
-# CONFIG_DAVICOM_PHY is not set
-# CONFIG_QSEMI_PHY is not set
-# CONFIG_LXT_PHY is not set
-# CONFIG_CICADA_PHY is not set
-# CONFIG_VITESSE_PHY is not set
-CONFIG_SMSC_PHY=y
-# CONFIG_BROADCOM_PHY is not set
-# CONFIG_BCM63XX_PHY is not set
-# CONFIG_ICPLUS_PHY is not set
-# CONFIG_REALTEK_PHY is not set
-# CONFIG_NATIONAL_PHY is not set
-# CONFIG_STE10XP is not set
-# CONFIG_LSI_ET1011C_PHY is not set
-# CONFIG_MICREL_PHY is not set
-# CONFIG_FIXED_PHY is not set
-# CONFIG_MDIO_BITBANG is not set
-CONFIG_NET_ETHERNET=y
-# CONFIG_AX88796 is not set
-# CONFIG_SMC91X is not set
-# CONFIG_DM9000 is not set
-# CONFIG_ENC28J60 is not set
-# CONFIG_ETHOC is not set
-CONFIG_SMC911X=y
-CONFIG_SMSC911X=y
-# CONFIG_SMSC911X_ARCH_HOOKS is not set
-# CONFIG_DNET is not set
-# CONFIG_IBM_NEW_EMAC_ZMII is not set
-# CONFIG_IBM_NEW_EMAC_RGMII is not set
-# CONFIG_IBM_NEW_EMAC_TAH is not set
-# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
-# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
-# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
-# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
-# CONFIG_B44 is not set
-# CONFIG_KS8851 is not set
-# CONFIG_KS8851_MLL is not set
-CONFIG_NETDEV_1000=y
-CONFIG_TI_DAVINCI_EMAC=y
-CONFIG_TI_DAVINCI_MDIO=y
-CONFIG_TI_DAVINCI_CPDMA=y
-# CONFIG_STMMAC_ETH is not set
-CONFIG_NETDEV_10000=y
-CONFIG_WLAN=y
-# CONFIG_USB_ZD1201 is not set
-# CONFIG_BCM4329 is not set
-# CONFIG_HOSTAP is not set
-CONFIG_WL12XX_PLATFORM_DATA=y
-
-#
-# Enable WiMAX (Networking options) to see the WiMAX drivers
-#
-
-#
-# USB Network Adapters
-#
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RTL8150 is not set
-CONFIG_USB_USBNET=y
-CONFIG_USB_NET_AX8817X=y
-CONFIG_USB_NET_CDCETHER=y
-# CONFIG_USB_NET_CDC_EEM is not set
-# CONFIG_USB_NET_DM9601 is not set
-# CONFIG_USB_NET_SMSC75XX is not set
-CONFIG_USB_NET_SMSC95XX=y
-# CONFIG_USB_NET_GL620A is not set
-CONFIG_USB_NET_NET1080=y
-# CONFIG_USB_NET_PLUSB is not set
-# CONFIG_USB_NET_MCS7830 is not set
-# CONFIG_USB_NET_RNDIS_HOST is not set
-CONFIG_USB_NET_CDC_SUBSET=y
-CONFIG_USB_ALI_M5632=y
-CONFIG_USB_AN2720=y
-CONFIG_USB_BELKIN=y
-CONFIG_USB_ARMLINUX=y
-CONFIG_USB_EPSON2888=y
-CONFIG_USB_KC2190=y
-CONFIG_USB_NET_ZAURUS=y
-# CONFIG_USB_NET_CX82310_ETH is not set
-# CONFIG_USB_NET_INT51X1 is not set
-# CONFIG_USB_IPHETH is not set
-# CONFIG_USB_SIERRA_NET is not set
-# CONFIG_WAN is not set
-
-#
-# CAIF transport drivers
-#
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-# CONFIG_NETCONSOLE is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_ISDN is not set
-# CONFIG_PHONE is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
-# CONFIG_INPUT_POLLDEV is not set
-# CONFIG_INPUT_SPARSEKMAP is not set
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-CONFIG_INPUT_JOYDEV=y
-CONFIG_INPUT_EVDEV=y
-# CONFIG_INPUT_EVBUG is not set
-# CONFIG_INPUT_KEYRESET is not set
-
-#
-# Input Device Drivers
-#
-CONFIG_INPUT_KEYBOARD=y
-# CONFIG_KEYBOARD_ADP5588 is not set
-CONFIG_KEYBOARD_ATKBD=y
-# CONFIG_KEYBOARD_QT2160 is not set
-# CONFIG_KEYBOARD_LKKBD is not set
-CONFIG_KEYBOARD_GPIO=y
-# CONFIG_KEYBOARD_GPIO_POLLED is not set
-# CONFIG_KEYBOARD_TCA6416 is not set
-# CONFIG_KEYBOARD_MATRIX is not set
-# CONFIG_KEYBOARD_MAX7359 is not set
-# CONFIG_KEYBOARD_MCS is not set
-# CONFIG_KEYBOARD_NEWTON is not set
-# CONFIG_KEYBOARD_OPENCORES is not set
-# CONFIG_KEYBOARD_STOWAWAY is not set
-# CONFIG_KEYBOARD_SUNKBD is not set
-CONFIG_KEYBOARD_TWL4030=y
-# CONFIG_KEYBOARD_XTKBD is not set
-CONFIG_INPUT_MOUSE=y
-CONFIG_MOUSE_PS2=y
-CONFIG_MOUSE_PS2_ALPS=y
-CONFIG_MOUSE_PS2_LOGIPS2PP=y
-CONFIG_MOUSE_PS2_SYNAPTICS=y
-CONFIG_MOUSE_PS2_TRACKPOINT=y
-# CONFIG_MOUSE_PS2_ELANTECH is not set
-# CONFIG_MOUSE_PS2_SENTELIC is not set
-# CONFIG_MOUSE_PS2_TOUCHKIT is not set
-# CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_APPLETOUCH is not set
-# CONFIG_MOUSE_BCM5974 is not set
-# CONFIG_MOUSE_VSXXXAA is not set
-# CONFIG_MOUSE_GPIO is not set
-# CONFIG_MOUSE_SYNAPTICS_I2C is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TABLET is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-# CONFIG_TOUCHSCREEN_ADS7846 is not set
-# CONFIG_TOUCHSCREEN_AD7877 is not set
-# CONFIG_TOUCHSCREEN_AD7879 is not set
-# CONFIG_TOUCHSCREEN_BU21013 is not set
-# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set
-# CONFIG_TOUCHSCREEN_DYNAPRO is not set
-# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set
-# CONFIG_TOUCHSCREEN_EETI is not set
-# CONFIG_TOUCHSCREEN_FUJITSU is not set
-# CONFIG_TOUCHSCREEN_GUNZE is not set
-# CONFIG_TOUCHSCREEN_ELO is not set
-# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
-# CONFIG_TOUCHSCREEN_MCS5000 is not set
-# CONFIG_TOUCHSCREEN_MTOUCH is not set
-# CONFIG_TOUCHSCREEN_INEXIO is not set
-# CONFIG_TOUCHSCREEN_MK712 is not set
-# CONFIG_TOUCHSCREEN_PENMOUNT is not set
-# CONFIG_TOUCHSCREEN_QT602240 is not set
-CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=y
-CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI4_DEV=y
-CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE=y
-# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
-# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
-# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
-# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
-# CONFIG_TOUCHSCREEN_TSC2007 is not set
-# CONFIG_TOUCHSCREEN_TSC2004 is not set
-# CONFIG_TOUCHSCREEN_W90X900 is not set
-# CONFIG_TOUCHSCREEN_TPS6507X is not set
-CONFIG_INPUT_MISC=y
-# CONFIG_INPUT_AD714X is not set
-# CONFIG_INPUT_ATI_REMOTE is not set
-# CONFIG_INPUT_ATI_REMOTE2 is not set
-# CONFIG_INPUT_KEYCHORD is not set
-# CONFIG_INPUT_KEYSPAN_REMOTE is not set
-# CONFIG_INPUT_POWERMATE is not set
-# CONFIG_INPUT_YEALINK is not set
-# CONFIG_INPUT_CM109 is not set
-CONFIG_INPUT_TWL4030_PWRBUTTON=y
-# CONFIG_INPUT_TWL4030_VIBRA is not set
-# CONFIG_INPUT_UINPUT is not set
-# CONFIG_INPUT_GPIO is not set
-# CONFIG_INPUT_PCF8574 is not set
-# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
-# CONFIG_INPUT_ADXL34X is not set
-
-#
-# Hardware I/O ports
-#
-CONFIG_SERIO=y
-CONFIG_SERIO_SERPORT=y
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-# CONFIG_SERIO_ALTERA_PS2 is not set
-# CONFIG_SERIO_PS2MULT is not set
-# CONFIG_GAMEPORT is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_CONSOLE_TRANSLATIONS=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-CONFIG_VT_HW_CONSOLE_BINDING=y
-CONFIG_DEVMEM=y
-CONFIG_DEVKMEM=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_N_GSM is not set
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=32
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_MANY_PORTS=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-CONFIG_SERIAL_8250_DETECT_IRQ=y
-CONFIG_SERIAL_8250_RSA=y
-
-#
-# Non-8250 serial port support
-#
-# CONFIG_SERIAL_MAX3100 is not set
-# CONFIG_SERIAL_MAX3107 is not set
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_SERIAL_OMAP=y
-CONFIG_SERIAL_OMAP_CONSOLE=y
-# CONFIG_SERIAL_TIMBERDALE is not set
-# CONFIG_SERIAL_ALTERA_JTAGUART is not set
-# CONFIG_SERIAL_ALTERA_UART is not set
-CONFIG_UNIX98_PTYS=y
-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_TTY_PRINTK is not set
-# CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=y
-# CONFIG_HW_RANDOM_TIMERIOMEM is not set
-# CONFIG_R3964 is not set
-# CONFIG_RAW_DRIVER is not set
-# CONFIG_TCG_TPM is not set
-# CONFIG_TI81XX_HDMI is not set
-# CONFIG_DCC_TTY is not set
-# CONFIG_RAMOOPS is not set
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_COMPAT=y
-CONFIG_I2C_CHARDEV=y
-# CONFIG_I2C_MUX is not set
-CONFIG_I2C_HELPER_AUTO=y
-
-#
-# I2C Hardware Bus support
-#
-
-#
-# I2C system bus drivers (mostly embedded / system-on-chip)
-#
-# CONFIG_I2C_DESIGNWARE is not set
-# CONFIG_I2C_GPIO is not set
-# CONFIG_I2C_OCORES is not set
-CONFIG_I2C_OMAP=y
-# CONFIG_I2C_PCA_PLATFORM is not set
-# CONFIG_I2C_SIMTEC is not set
-# CONFIG_I2C_XILINX is not set
-
-#
-# External I2C/SMBus adapter drivers
-#
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_TAOS_EVM is not set
-# CONFIG_I2C_TINY_USB is not set
-
-#
-# Other I2C/SMBus bus drivers
-#
-# CONFIG_I2C_STUB is not set
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-CONFIG_SPI=y
-CONFIG_SPI_MASTER=y
-
-#
-# SPI Master Controller Drivers
-#
-# CONFIG_SPI_BITBANG is not set
-# CONFIG_SPI_GPIO is not set
-CONFIG_SPI_OMAP24XX=y
-# CONFIG_SPI_XILINX is not set
-# CONFIG_SPI_DESIGNWARE is not set
-
-#
-# SPI Protocol Masters
-#
-# CONFIG_SPI_SPIDEV is not set
-# CONFIG_SPI_TLE62X0 is not set
-
-#
-# PPS support
-#
-# CONFIG_PPS is not set
-CONFIG_ARCH_REQUIRE_GPIOLIB=y
-CONFIG_GPIOLIB=y
-CONFIG_GPIO_SYSFS=y
-
-#
-# Memory mapped GPIO expanders:
-#
-# CONFIG_GPIO_BASIC_MMIO is not set
-# CONFIG_GPIO_IT8761E is not set
-# CONFIG_GPIO_VX855 is not set
-
-#
-# I2C GPIO expanders:
-#
-# CONFIG_GPIO_MAX7300 is not set
-# CONFIG_GPIO_MAX732X is not set
-# CONFIG_GPIO_PCA953X is not set
-# CONFIG_GPIO_PCF857X is not set
-# CONFIG_GPIO_SX150X is not set
-CONFIG_GPIO_TWL4030=y
-# CONFIG_GPIO_ADP5588 is not set
-
-#
-# PCI GPIO expanders:
-#
-
-#
-# SPI GPIO expanders:
-#
-# CONFIG_GPIO_MAX7301 is not set
-# CONFIG_GPIO_MCP23S08 is not set
-# CONFIG_GPIO_MC33880 is not set
-# CONFIG_GPIO_74X164 is not set
-
-#
-# AC97 GPIO expanders:
-#
-
-#
-# MODULbus GPIO expanders:
-#
-# CONFIG_W1 is not set
-CONFIG_POWER_SUPPLY=y
-# CONFIG_POWER_SUPPLY_DEBUG is not set
-# CONFIG_PDA_POWER is not set
-# CONFIG_TEST_POWER is not set
-# CONFIG_BATTERY_DS2782 is not set
-# CONFIG_BATTERY_BQ20Z75 is not set
-# CONFIG_BATTERY_BQ27x00 is not set
-# CONFIG_BATTERY_MAX17040 is not set
-# CONFIG_CHARGER_ISP1704 is not set
-# CONFIG_CHARGER_TWL4030 is not set
-CONFIG_HWMON=y
-# CONFIG_HWMON_VID is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
-
-#
-# Native drivers
-#
-# CONFIG_SENSORS_AD7414 is not set
-# CONFIG_SENSORS_AD7418 is not set
-# CONFIG_SENSORS_ADCXX is not set
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ADM1025 is not set
-# CONFIG_SENSORS_ADM1026 is not set
-# CONFIG_SENSORS_ADM1029 is not set
-# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ADM9240 is not set
-# CONFIG_SENSORS_ADT7411 is not set
-# CONFIG_SENSORS_ADT7462 is not set
-# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7475 is not set
-# CONFIG_SENSORS_ASC7621 is not set
-# CONFIG_SENSORS_ATXP1 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_F71882FG is not set
-# CONFIG_SENSORS_F75375S is not set
-# CONFIG_SENSORS_G760A is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_GL520SM is not set
-# CONFIG_SENSORS_GPIO_FAN is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_JC42 is not set
-# CONFIG_SENSORS_LM63 is not set
-# CONFIG_SENSORS_LM70 is not set
-# CONFIG_SENSORS_LM73 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM77 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM87 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_LM92 is not set
-# CONFIG_SENSORS_LM93 is not set
-# CONFIG_SENSORS_LTC4215 is not set
-# CONFIG_SENSORS_LTC4245 is not set
-# CONFIG_SENSORS_LTC4261 is not set
-# CONFIG_SENSORS_LM95241 is not set
-# CONFIG_SENSORS_MAX1111 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_MAX6650 is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_PC87427 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_SHT15 is not set
-# CONFIG_SENSORS_SMM665 is not set
-# CONFIG_SENSORS_DME1737 is not set
-# CONFIG_SENSORS_EMC1403 is not set
-# CONFIG_SENSORS_EMC2103 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_SMSC47M192 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
-# CONFIG_SENSORS_ADS7828 is not set
-# CONFIG_SENSORS_ADS7871 is not set
-# CONFIG_SENSORS_AMC6821 is not set
-# CONFIG_SENSORS_THMC50 is not set
-# CONFIG_SENSORS_TMP102 is not set
-# CONFIG_SENSORS_TMP401 is not set
-# CONFIG_SENSORS_TMP421 is not set
-# CONFIG_SENSORS_VT1211 is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83791D is not set
-# CONFIG_SENSORS_W83792D is not set
-# CONFIG_SENSORS_W83793 is not set
-# CONFIG_SENSORS_W83795 is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83L786NG is not set
-# CONFIG_SENSORS_W83627HF is not set
-# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_SENSORS_LIS3_SPI is not set
-# CONFIG_SENSORS_LIS3_I2C is not set
-# CONFIG_THERMAL is not set
-CONFIG_WATCHDOG=y
-# CONFIG_WATCHDOG_NOWAYOUT is not set
-
-#
-# Watchdog Device Drivers
-#
-# CONFIG_SOFT_WATCHDOG is not set
-CONFIG_OMAP_WATCHDOG=y
-CONFIG_TWL4030_WATCHDOG=y
-# CONFIG_MAX63XX_WATCHDOG is not set
-
-#
-# USB-based Watchdog Cards
-#
-# CONFIG_USBPCWATCHDOG is not set
-CONFIG_SSB_POSSIBLE=y
-
-#
-# Sonics Silicon Backplane
-#
-# CONFIG_SSB is not set
-CONFIG_MFD_SUPPORT=y
-CONFIG_MFD_CORE=y
-# CONFIG_MFD_88PM860X is not set
-# CONFIG_MFD_SM501 is not set
-# CONFIG_MFD_ASIC3 is not set
-# CONFIG_HTC_EGPIO is not set
-# CONFIG_HTC_PASIC3 is not set
-# CONFIG_HTC_I2CPLD is not set
-# CONFIG_TPS65010 is not set
-# CONFIG_TPS6507X is not set
-CONFIG_TWL4030_CORE=y
-CONFIG_TWL4030_POWER=y
-CONFIG_TWL4030_SCRIPT=y
-CONFIG_TWL4030_CODEC=y
-# CONFIG_TWL6030_PWM is not set
-# CONFIG_MFD_STMPE is not set
-# CONFIG_MFD_TC35892 is not set
-# CONFIG_MFD_TMIO is not set
-# CONFIG_MFD_T7L66XB is not set
-# CONFIG_MFD_TC6387XB is not set
-# CONFIG_MFD_TC6393XB is not set
-# CONFIG_PMIC_DA903X is not set
-# CONFIG_PMIC_ADP5520 is not set
-# CONFIG_MFD_MAX8925 is not set
-# CONFIG_MFD_MAX8998 is not set
-# CONFIG_MFD_WM8400 is not set
-# CONFIG_MFD_WM831X_I2C is not set
-# CONFIG_MFD_WM831X_SPI is not set
-# CONFIG_MFD_WM8350_I2C is not set
-# CONFIG_MFD_WM8994 is not set
-# CONFIG_MFD_PCF50633 is not set
-# CONFIG_MFD_MC13XXX is not set
-# CONFIG_ABX500_CORE is not set
-# CONFIG_EZX_PCAP is not set
-# CONFIG_MFD_TPS6586X is not set
-CONFIG_REGULATOR=y
-# CONFIG_REGULATOR_DEBUG is not set
-CONFIG_REGULATOR_DUMMY=y
-# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
-# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
-# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
-# CONFIG_REGULATOR_BQ24022 is not set
-# CONFIG_REGULATOR_MAX1586 is not set
-# CONFIG_REGULATOR_MAX8649 is not set
-# CONFIG_REGULATOR_MAX8660 is not set
-# CONFIG_REGULATOR_MAX8952 is not set
-CONFIG_REGULATOR_TWL4030=y
-# CONFIG_REGULATOR_LP3971 is not set
-# CONFIG_REGULATOR_LP3972 is not set
-# CONFIG_REGULATOR_TPS65023 is not set
-# CONFIG_REGULATOR_TPS6507X is not set
-# CONFIG_REGULATOR_ISL6271A is not set
-# CONFIG_REGULATOR_AD5398 is not set
-CONFIG_MEDIA_SUPPORT=y
-
-#
-# Multimedia core support
-#
-CONFIG_MEDIA_CONTROLLER=y
-CONFIG_VIDEO_DEV=y
-CONFIG_VIDEO_V4L2_COMMON=y
-CONFIG_VIDEO_ALLOW_V4L1=y
-CONFIG_VIDEO_V4L1_COMPAT=y
-CONFIG_VIDEO_V4L2_SUBDEV_API=y
-# CONFIG_DVB_CORE is not set
-CONFIG_VIDEO_MEDIA=y
-
-#
-# Multimedia drivers
-#
-# CONFIG_IR_CORE is not set
-# CONFIG_MEDIA_ATTACH is not set
-CONFIG_MEDIA_TUNER=y
-# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
-CONFIG_MEDIA_TUNER_SIMPLE=y
-CONFIG_MEDIA_TUNER_TDA8290=y
-CONFIG_MEDIA_TUNER_TDA827X=y
-CONFIG_MEDIA_TUNER_TDA18271=y
-CONFIG_MEDIA_TUNER_TDA9887=y
-CONFIG_MEDIA_TUNER_TEA5761=y
-CONFIG_MEDIA_TUNER_TEA5767=y
-CONFIG_MEDIA_TUNER_MT20XX=y
-CONFIG_MEDIA_TUNER_XC2028=y
-CONFIG_MEDIA_TUNER_XC5000=y
-CONFIG_MEDIA_TUNER_MC44S803=y
-CONFIG_VIDEO_V4L2=y
-CONFIG_VIDEO_V4L1=y
-CONFIG_VIDEOBUF_GEN=y
-CONFIG_VIDEOBUF_DMA_CONTIG=y
-CONFIG_VIDEO_CAPTURE_DRIVERS=y
-# CONFIG_VIDEO_ADV_DEBUG is not set
-# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
-# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
-
-#
-# Encoders/decoders and other helper chips
-#
-
-#
-# Audio decoders
-#
-# CONFIG_VIDEO_TVAUDIO is not set
-# CONFIG_VIDEO_TDA7432 is not set
-# CONFIG_VIDEO_TDA9840 is not set
-# CONFIG_VIDEO_TDA9875 is not set
-# CONFIG_VIDEO_TEA6415C is not set
-# CONFIG_VIDEO_TEA6420 is not set
-# CONFIG_VIDEO_MSP3400 is not set
-# CONFIG_VIDEO_CS5345 is not set
-# CONFIG_VIDEO_CS53L32A is not set
-# CONFIG_VIDEO_M52790 is not set
-# CONFIG_VIDEO_TLV320AIC23B is not set
-# CONFIG_VIDEO_WM8775 is not set
-# CONFIG_VIDEO_WM8739 is not set
-# CONFIG_VIDEO_VP27SMPX is not set
-
-#
-# RDS decoders
-#
-# CONFIG_VIDEO_SAA6588 is not set
-
-#
-# Video decoders
-#
-# CONFIG_VIDEO_ADV7180 is not set
-# CONFIG_VIDEO_BT819 is not set
-# CONFIG_VIDEO_BT856 is not set
-# CONFIG_VIDEO_BT866 is not set
-# CONFIG_VIDEO_KS0127 is not set
-# CONFIG_VIDEO_OV7670 is not set
-# CONFIG_VIDEO_MT9T001 is not set
-CONFIG_VIDEO_MT9V011=y
-# CONFIG_VIDEO_MT9V032 is not set
-CONFIG_VIDEO_MT9V113=y
-# CONFIG_VIDEO_MT9T111 is not set
-# CONFIG_VIDEO_TCM825X is not set
-# CONFIG_VIDEO_SAA7110 is not set
-# CONFIG_VIDEO_SAA711X is not set
-# CONFIG_VIDEO_SAA717X is not set
-# CONFIG_VIDEO_SAA7191 is not set
-# CONFIG_VIDEO_TVP514X is not set
-# CONFIG_VIDEO_TVP5150 is not set
-# CONFIG_VIDEO_TVP7002 is not set
-# CONFIG_VIDEO_VPX3220 is not set
-
-#
-# Video and audio decoders
-#
-# CONFIG_VIDEO_CX25840 is not set
-
-#
-# MPEG video encoders
-#
-# CONFIG_VIDEO_CX2341X is not set
-
-#
-# Video encoders
-#
-# CONFIG_VIDEO_SAA7127 is not set
-# CONFIG_VIDEO_SAA7185 is not set
-# CONFIG_VIDEO_ADV7170 is not set
-# CONFIG_VIDEO_ADV7175 is not set
-# CONFIG_VIDEO_THS7303 is not set
-# CONFIG_VIDEO_ADV7343 is not set
-# CONFIG_VIDEO_AK881X is not set
-
-#
-# Video improvement chips
-#
-# CONFIG_VIDEO_UPD64031A is not set
-# CONFIG_VIDEO_UPD64083 is not set
-# CONFIG_VIDEO_VPSS_SYSTEM is not set
-# CONFIG_VIDEO_VPFE_CAPTURE is not set
-CONFIG_VIDEO_OMAP2_VOUT=y
-# CONFIG_VIDEO_CPIA2 is not set
-# CONFIG_VIDEO_SR030PC30 is not set
-CONFIG_VIDEO_OMAP3=y
-CONFIG_VIDEO_OMAP3_DEBUG=y
-# CONFIG_SOC_CAMERA is not set
-CONFIG_V4L_USB_DRIVERS=y
-CONFIG_USB_VIDEO_CLASS=y
-CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
-# CONFIG_USB_GSPCA is not set
-# CONFIG_VIDEO_PVRUSB2 is not set
-# CONFIG_VIDEO_HDPVR is not set
-# CONFIG_VIDEO_USBVISION is not set
-# CONFIG_USB_VICAM is not set
-# CONFIG_USB_IBMCAM is not set
-# CONFIG_USB_KONICAWC is not set
-# CONFIG_USB_ET61X251 is not set
-# CONFIG_USB_SE401 is not set
-# CONFIG_USB_SN9C102 is not set
-# CONFIG_USB_PWC is not set
-# CONFIG_USB_ZR364XX is not set
-# CONFIG_USB_STKWEBCAM is not set
-# CONFIG_USB_S2255 is not set
-# CONFIG_V4L_MEM2MEM_DRIVERS is not set
-# CONFIG_RADIO_ADAPTERS is not set
-# CONFIG_DAB is not set
-
-#
-# Graphics support
-#
-# CONFIG_DRM is not set
-# CONFIG_VGASTATE is not set
-# CONFIG_VIDEO_OUTPUT_CONTROL is not set
-CONFIG_FB=y
-CONFIG_FIRMWARE_EDID=y
-# CONFIG_FB_DDC is not set
-# CONFIG_FB_BOOT_VESA_SUPPORT is not set
-CONFIG_FB_CFB_FILLRECT=y
-CONFIG_FB_CFB_COPYAREA=y
-CONFIG_FB_CFB_IMAGEBLIT=y
-# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
-# CONFIG_FB_SYS_FILLRECT is not set
-# CONFIG_FB_SYS_COPYAREA is not set
-# CONFIG_FB_SYS_IMAGEBLIT is not set
-# CONFIG_FB_FOREIGN_ENDIAN is not set
-# CONFIG_FB_SYS_FOPS is not set
-# CONFIG_FB_SVGALIB is not set
-# CONFIG_FB_MACMODES is not set
-# CONFIG_FB_BACKLIGHT is not set
-CONFIG_FB_MODE_HELPERS=y
-CONFIG_FB_TILEBLITTING=y
-
-#
-# Frame buffer hardware drivers
-#
-# CONFIG_FB_S1D13XXX is not set
-# CONFIG_FB_TMIO is not set
-# CONFIG_FB_VIRTUAL is not set
-# CONFIG_FB_METRONOME is not set
-# CONFIG_FB_MB862XX is not set
-# CONFIG_FB_BROADSHEET is not set
-# CONFIG_FB_OMAP_BOOTLOADER_INIT is not set
-CONFIG_OMAP2_VRAM=y
-CONFIG_OMAP2_VRFB=y
-CONFIG_OMAP2_DSS=y
-CONFIG_OMAP2_VRAM_SIZE=4
-CONFIG_OMAP2_DSS_DEBUG_SUPPORT=y
-# CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS is not set
-CONFIG_OMAP2_DSS_DPI=y
-# CONFIG_OMAP2_DSS_RFBI is not set
-CONFIG_OMAP2_DSS_VENC=y
-CONFIG_OMAP2_VENC_OUT_TYPE_SVIDEO=y
-# CONFIG_OMAP2_VENC_OUT_TYPE_COMPOSITE is not set
-# CONFIG_OMAP2_DSS_SDI is not set
-CONFIG_OMAP2_DSS_DSI=y
-CONFIG_OMAP2_DSS_USE_DSI_PLL=y
-# CONFIG_OMAP2_DSS_FAKE_VSYNC is not set
-CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=1
-CONFIG_FB_OMAP2=y
-CONFIG_FB_OMAP2_DEBUG_SUPPORT=y
-CONFIG_FB_OMAP2_NUM_FBS=1
-
-#
-# OMAP2/3 Display Device Drivers
-#
-CONFIG_PANEL_GENERIC=y
-# CONFIG_PANEL_LGPHILIPS_LB035Q02 is not set
-# CONFIG_PANEL_SAMSUNG_LTE430WQ_F0C is not set
-CONFIG_PANEL_SHARP_LS037V7DW01=y
-# CONFIG_PANEL_SHARP_LQ043T1DG01 is not set
-# CONFIG_PANEL_SAMSUNG_LMS700KF23 is not set
-# CONFIG_PANEL_TAAL is not set
-# CONFIG_PANEL_TOPPOLY_TDO35S is not set
-# CONFIG_PANEL_TPO_TD043MTEA1 is not set
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-CONFIG_LCD_CLASS_DEVICE=y
-# CONFIG_LCD_L4F00242T03 is not set
-# CONFIG_LCD_LMS283GF05 is not set
-# CONFIG_LCD_LTV350QV is not set
-# CONFIG_LCD_TDO24M is not set
-# CONFIG_LCD_VGG2432A4 is not set
-CONFIG_LCD_PLATFORM=y
-# CONFIG_LCD_S6E63M0 is not set
-CONFIG_BACKLIGHT_CLASS_DEVICE=y
-CONFIG_BACKLIGHT_GENERIC=m
-# CONFIG_BACKLIGHT_ADP8860 is not set
-
-#
-# Display device support
-#
-CONFIG_DISPLAY_SUPPORT=y
-
-#
-# Display hardware drivers
-#
-
-#
-# Console display driver support
-#
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_FRAMEBUFFER_CONSOLE is not set
-CONFIG_LOGO=y
-CONFIG_LOGO_LINUX_MONO=y
-CONFIG_LOGO_LINUX_VGA16=y
-CONFIG_LOGO_LINUX_CLUT224=y
-CONFIG_SOUND=y
-# CONFIG_SOUND_OSS_CORE is not set
-CONFIG_SND=y
-CONFIG_SND_TIMER=y
-CONFIG_SND_PCM=y
-CONFIG_SND_HWDEP=y
-CONFIG_SND_RAWMIDI=y
-CONFIG_SND_JACK=y
-# CONFIG_SND_SEQUENCER is not set
-# CONFIG_SND_MIXER_OSS is not set
-# CONFIG_SND_PCM_OSS is not set
-# CONFIG_SND_HRTIMER is not set
-# CONFIG_SND_DYNAMIC_MINORS is not set
-CONFIG_SND_SUPPORT_OLD_API=y
-CONFIG_SND_VERBOSE_PROCFS=y
-# CONFIG_SND_VERBOSE_PRINTK is not set
-# CONFIG_SND_DEBUG is not set
-# CONFIG_SND_RAWMIDI_SEQ is not set
-# CONFIG_SND_OPL3_LIB_SEQ is not set
-# CONFIG_SND_OPL4_LIB_SEQ is not set
-# CONFIG_SND_SBAWE_SEQ is not set
-# CONFIG_SND_EMU10K1_SEQ is not set
-CONFIG_SND_DRIVERS=y
-# CONFIG_SND_DUMMY is not set
-# CONFIG_SND_ALOOP is not set
-# CONFIG_SND_MTPAV is not set
-# CONFIG_SND_SERIAL_U16550 is not set
-# CONFIG_SND_MPU401 is not set
-CONFIG_SND_ARM=y
-CONFIG_SND_SPI=y
-CONFIG_SND_USB=y
-CONFIG_SND_USB_AUDIO=y
-# CONFIG_SND_USB_UA101 is not set
-# CONFIG_SND_USB_CAIAQ is not set
-CONFIG_SND_SOC=y
-CONFIG_SND_OMAP_SOC=y
-CONFIG_SND_OMAP_SOC_MCBSP=y
-CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE=y
-CONFIG_SND_SOC_I2C_AND_SPI=y
-# CONFIG_SND_SOC_ALL_CODECS is not set
-CONFIG_SND_SOC_TWL4030=y
-# CONFIG_SND_SOC_WL1271BT is not set
-# CONFIG_SOUND_PRIME is not set
-CONFIG_HID_SUPPORT=y
-CONFIG_HID=y
-# CONFIG_HIDRAW is not set
-
-#
-# USB Input Devices
-#
-CONFIG_USB_HID=y
-# CONFIG_HID_PID is not set
-# CONFIG_USB_HIDDEV is not set
-
-#
-# Special HID drivers
-#
-# CONFIG_HID_3M_PCT is not set
-# CONFIG_HID_A4TECH is not set
-# CONFIG_HID_ACRUX_FF is not set
-# CONFIG_HID_APPLE is not set
-# CONFIG_HID_BELKIN is not set
-# CONFIG_HID_CANDO is not set
-# CONFIG_HID_CHERRY is not set
-# CONFIG_HID_CHICONY is not set
-# CONFIG_HID_PRODIKEYS is not set
-# CONFIG_HID_CYPRESS is not set
-# CONFIG_HID_DRAGONRISE is not set
-# CONFIG_HID_EGALAX is not set
-# CONFIG_HID_EZKEY is not set
-# CONFIG_HID_KYE is not set
-# CONFIG_HID_UCLOGIC is not set
-# CONFIG_HID_WALTOP is not set
-# CONFIG_HID_GYRATION is not set
-# CONFIG_HID_TWINHAN is not set
-# CONFIG_HID_KENSINGTON is not set
-# CONFIG_HID_LOGITECH is not set
-# CONFIG_HID_MICROSOFT is not set
-# CONFIG_HID_MOSART is not set
-# CONFIG_HID_MONTEREY is not set
-# CONFIG_HID_NTRIG is not set
-# CONFIG_HID_ORTEK is not set
-# CONFIG_HID_PANTHERLORD is not set
-# CONFIG_HID_PETALYNX is not set
-# CONFIG_HID_PICOLCD is not set
-# CONFIG_HID_QUANTA is not set
-# CONFIG_HID_ROCCAT is not set
-# CONFIG_HID_ROCCAT_KONE is not set
-# CONFIG_HID_ROCCAT_PYRA is not set
-# CONFIG_HID_SAMSUNG is not set
-# CONFIG_HID_SONY is not set
-# CONFIG_HID_STANTUM is not set
-# CONFIG_HID_SUNPLUS is not set
-# CONFIG_HID_GREENASIA is not set
-# CONFIG_HID_SMARTJOYPLUS is not set
-# CONFIG_HID_TOPSEED is not set
-# CONFIG_HID_THRUSTMASTER is not set
-# CONFIG_HID_ZEROPLUS is not set
-# CONFIG_HID_ZYDACRON is not set
-CONFIG_USB_SUPPORT=y
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
-CONFIG_USB_ARCH_HAS_EHCI=y
-CONFIG_USB=y
-# CONFIG_USB_DEBUG is not set
-CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
-
-#
-# Miscellaneous USB options
-#
-# CONFIG_USB_DEVICEFS is not set
-# CONFIG_USB_DEVICE_CLASS is not set
-# CONFIG_USB_DYNAMIC_MINORS is not set
-CONFIG_USB_SUSPEND=y
-CONFIG_USB_OTG=y
-# CONFIG_USB_OTG_WHITELIST is not set
-# CONFIG_USB_OTG_BLACKLIST_HUB is not set
-CONFIG_USB_MON=y
-# CONFIG_USB_WUSB is not set
-# CONFIG_USB_WUSB_CBAF is not set
-
-#
-# USB Host Controller Drivers
-#
-# CONFIG_USB_C67X00_HCD is not set
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_ROOT_HUB_TT=y
-CONFIG_USB_EHCI_TT_NEWSCHED=y
-# CONFIG_USB_OXU210HP_HCD is not set
-# CONFIG_USB_ISP116X_HCD is not set
-# CONFIG_USB_ISP1760_HCD is not set
-# CONFIG_USB_ISP1362_HCD is not set
-# CONFIG_USB_OHCI_HCD is not set
-# CONFIG_USB_SL811_HCD is not set
-# CONFIG_USB_R8A66597_HCD is not set
-# CONFIG_USB_HWA_HCD is not set
-CONFIG_USB_MUSB_HDRC=y
-
-#
-# Platform Glue Layer
-#
-# CONFIG_USB_MUSB_TUSB6010_GLUE is not set
-CONFIG_USB_MUSB_OMAP2PLUS_GLUE=y
-# CONFIG_USB_MUSB_AM35X_GLUE is not set
-# CONFIG_USB_MUSB_DAVINCI is not set
-# CONFIG_USB_MUSB_DA8XX is not set
-# CONFIG_USB_MUSB_TUSB6010 is not set
-CONFIG_USB_MUSB_OMAP2PLUS=y
-# CONFIG_USB_MUSB_AM35X is not set
-# CONFIG_USB_MUSB_TI81XX is not set
-# CONFIG_USB_MUSB_BLACKFIN is not set
-# CONFIG_USB_MUSB_UX500 is not set
-# CONFIG_USB_MUSB_HOST is not set
-# CONFIG_USB_MUSB_PERIPHERAL is not set
-CONFIG_USB_MUSB_OTG=y
-CONFIG_USB_GADGET_MUSB_HDRC=y
-CONFIG_USB_MUSB_HDRC_HCD=y
-# CONFIG_MUSB_PIO_ONLY is not set
-CONFIG_USB_INVENTRA_DMA_HW=y
-# CONFIG_USB_TI_CPPI_DMA_HW is not set
-# CONFIG_USB_TI_CPPI41_DMA_HW is not set
-CONFIG_USB_INVENTRA_DMA=y
-CONFIG_MUSB_USE_SYSTEM_DMA_WORKAROUND=y
-# CONFIG_USB_TI_CPPI_DMA is not set
-# CONFIG_USB_TI_CPPI41_DMA is not set
-# CONFIG_USB_TUSB_OMAP_DMA is not set
-# CONFIG_USB_MUSB_DEBUG is not set
-
-#
-# USB Device Class drivers
-#
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-# CONFIG_USB_WDM is not set
-# CONFIG_USB_TMC is not set
-
-#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
-#
-
-#
-# also be needed; see USB_STORAGE Help for more info
-#
-CONFIG_USB_STORAGE=y
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_USBAT is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_SDDR55 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_STORAGE_ALAUDA is not set
-# CONFIG_USB_STORAGE_ONETOUCH is not set
-# CONFIG_USB_STORAGE_KARMA is not set
-# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
-# CONFIG_USB_UAS is not set
-# CONFIG_USB_LIBUSUAL is not set
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_MICROTEK is not set
-
-#
-# USB port drivers
-#
-# CONFIG_USB_SERIAL is not set
-
-#
-# USB Miscellaneous drivers
-#
-# CONFIG_USB_EMI62 is not set
-# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_ADUTUX is not set
-# CONFIG_USB_SEVSEG is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_LEGOTOWER is not set
-# CONFIG_USB_LCD is not set
-# CONFIG_USB_LED is not set
-# CONFIG_USB_CYPRESS_CY7C63 is not set
-# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_IDMOUSE is not set
-# CONFIG_USB_FTDI_ELAN is not set
-# CONFIG_USB_APPLEDISPLAY is not set
-# CONFIG_USB_SISUSBVGA is not set
-# CONFIG_USB_LD is not set
-# CONFIG_USB_TRANCEVIBRATOR is not set
-# CONFIG_USB_IOWARRIOR is not set
-# CONFIG_USB_TEST is not set
-# CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_YUREX is not set
-CONFIG_USB_GADGET=y
-# CONFIG_USB_GADGET_DEBUG_FILES is not set
-# CONFIG_USB_GADGET_DEBUG_FS is not set
-CONFIG_USB_GADGET_VBUS_DRAW=2
-CONFIG_USB_GADGET_SELECTED=y
-# CONFIG_USB_GADGET_OMAP is not set
-# CONFIG_USB_GADGET_R8A66597 is not set
-# CONFIG_USB_GADGET_M66592 is not set
-# CONFIG_USB_GADGET_DUMMY_HCD is not set
-CONFIG_USB_GADGET_DUALSPEED=y
-# CONFIG_USB_ZERO is not set
-# CONFIG_USB_AUDIO is not set
-# CONFIG_USB_ETH is not set
-# CONFIG_USB_GADGETFS is not set
-# CONFIG_USB_FUNCTIONFS is not set
-# CONFIG_USB_FILE_STORAGE is not set
-# CONFIG_USB_MASS_STORAGE is not set
-# CONFIG_USB_G_SERIAL is not set
-# CONFIG_USB_MIDI_GADGET is not set
-# CONFIG_USB_G_PRINTER is not set
-CONFIG_USB_ANDROID=y
-# CONFIG_USB_ANDROID_ACM is not set
-CONFIG_USB_ANDROID_ADB=y
-CONFIG_USB_ANDROID_MASS_STORAGE=y
-# CONFIG_USB_ANDROID_MTP is not set
-# CONFIG_USB_ANDROID_RNDIS is not set
-# CONFIG_USB_CDC_COMPOSITE is not set
-# CONFIG_USB_G_MULTI is not set
-# CONFIG_USB_G_HID is not set
-# CONFIG_USB_G_DBGP is not set
-# CONFIG_USB_G_WEBCAM is not set
-
-#
-# OTG and related infrastructure
-#
-CONFIG_USB_OTG_UTILS=y
-# CONFIG_USB_GPIO_VBUS is not set
-# CONFIG_ISP1301_OMAP is not set
-# CONFIG_USB_ULPI is not set
-CONFIG_TWL4030_USB=y
-# CONFIG_NOP_USB_XCEIV is not set
-CONFIG_MMC=y
-# CONFIG_MMC_DEBUG is not set
-CONFIG_MMC_UNSAFE_RESUME=y
-# CONFIG_MMC_EMBEDDED_SDIO is not set
-# CONFIG_MMC_PARANOID_SD_INIT is not set
-
-#
-# MMC/SD/SDIO Card Drivers
-#
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_BLOCK_MINORS=8
-CONFIG_MMC_BLOCK_BOUNCE=y
-# CONFIG_MMC_BLOCK_DEFERRED_RESUME is not set
-CONFIG_SDIO_UART=y
-# CONFIG_MMC_TEST is not set
-
-#
-# MMC/SD/SDIO Host Controller Drivers
-#
-# CONFIG_MMC_SDHCI is not set
-CONFIG_MMC_OMAP=y
-CONFIG_MMC_OMAP_HS=y
-# CONFIG_MMC_SPI is not set
-# CONFIG_MMC_USHC is not set
-# CONFIG_MEMSTICK is not set
-# CONFIG_NEW_LEDS is not set
-CONFIG_SWITCH=y
-# CONFIG_SWITCH_GPIO is not set
-# CONFIG_ACCESSIBILITY is not set
-CONFIG_RTC_LIB=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_HCTOSYS=y
-CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
-# CONFIG_RTC_DEBUG is not set
-
-#
-# RTC interfaces
-#
-CONFIG_RTC_INTF_SYSFS=y
-CONFIG_RTC_INTF_PROC=y
-CONFIG_RTC_INTF_DEV=y
-# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
-CONFIG_RTC_INTF_ALARM=y
-CONFIG_RTC_INTF_ALARM_DEV=y
-# CONFIG_RTC_DRV_TEST is not set
-
-#
-# I2C RTC drivers
-#
-# CONFIG_RTC_DRV_DS1307 is not set
-# CONFIG_RTC_DRV_DS1374 is not set
-# CONFIG_RTC_DRV_DS1672 is not set
-# CONFIG_RTC_DRV_DS3232 is not set
-# CONFIG_RTC_DRV_MAX6900 is not set
-# CONFIG_RTC_DRV_RS5C372 is not set
-# CONFIG_RTC_DRV_ISL1208 is not set
-# CONFIG_RTC_DRV_ISL12022 is not set
-# CONFIG_RTC_DRV_X1205 is not set
-# CONFIG_RTC_DRV_PCF8563 is not set
-# CONFIG_RTC_DRV_PCF8583 is not set
-# CONFIG_RTC_DRV_M41T80 is not set
-# CONFIG_RTC_DRV_BQ32K is not set
-CONFIG_RTC_DRV_TWL4030=y
-# CONFIG_RTC_DRV_S35390A is not set
-# CONFIG_RTC_DRV_FM3130 is not set
-# CONFIG_RTC_DRV_RX8581 is not set
-# CONFIG_RTC_DRV_RX8025 is not set
-
-#
-# SPI RTC drivers
-#
-# CONFIG_RTC_DRV_M41T94 is not set
-# CONFIG_RTC_DRV_DS1305 is not set
-# CONFIG_RTC_DRV_DS1390 is not set
-# CONFIG_RTC_DRV_MAX6902 is not set
-# CONFIG_RTC_DRV_R9701 is not set
-# CONFIG_RTC_DRV_RS5C348 is not set
-# CONFIG_RTC_DRV_DS3234 is not set
-# CONFIG_RTC_DRV_PCF2123 is not set
-
-#
-# Platform RTC drivers
-#
-# CONFIG_RTC_DRV_CMOS is not set
-# CONFIG_RTC_DRV_DS1286 is not set
-# CONFIG_RTC_DRV_DS1511 is not set
-# CONFIG_RTC_DRV_DS1553 is not set
-# CONFIG_RTC_DRV_DS1742 is not set
-# CONFIG_RTC_DRV_STK17TA8 is not set
-# CONFIG_RTC_DRV_M48T86 is not set
-# CONFIG_RTC_DRV_M48T35 is not set
-# CONFIG_RTC_DRV_M48T59 is not set
-# CONFIG_RTC_DRV_MSM6242 is not set
-# CONFIG_RTC_DRV_BQ4802 is not set
-# CONFIG_RTC_DRV_RP5C01 is not set
-# CONFIG_RTC_DRV_V3020 is not set
-
-#
-# on-CPU RTC drivers
-#
-# CONFIG_DMADEVICES is not set
-# CONFIG_AUXDISPLAY is not set
-# CONFIG_UIO is not set
-CONFIG_STAGING=y
-# CONFIG_STAGING_EXCLUDE_BUILD is not set
-# CONFIG_VIDEO_CPIA is not set
-# CONFIG_USB_IP_COMMON is not set
-# CONFIG_ECHO is not set
-# CONFIG_BRCM80211 is not set
-# CONFIG_RT2870 is not set
-# CONFIG_COMEDI is not set
-# CONFIG_ASUS_OLED is not set
-# CONFIG_R8712U is not set
-# CONFIG_TRANZPORT is not set
-
-#
-# Android
-#
-CONFIG_ANDROID=y
-CONFIG_ANDROID_BINDER_IPC=y
-CONFIG_ANDROID_LOGGER=y
-CONFIG_ANDROID_RAM_CONSOLE=y
-CONFIG_ANDROID_RAM_CONSOLE_ENABLE_VERBOSE=y
-CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION=y
-CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_DATA_SIZE=128
-CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_ECC_SIZE=16
-CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE=8
-CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_POLYNOMIAL=0x11d
-# CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT is not set
-CONFIG_ANDROID_TIMED_OUTPUT=y
-CONFIG_ANDROID_TIMED_GPIO=y
-CONFIG_ANDROID_LOW_MEMORY_KILLER=y
-# CONFIG_POHMELFS is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_LINE6_USB is not set
-# CONFIG_VT6656 is not set
-# CONFIG_FB_UDL is not set
-# CONFIG_IIO is not set
-# CONFIG_ZRAM is not set
-# CONFIG_BATMAN_ADV is not set
-# CONFIG_FB_SM7XX is not set
-
-#
-# Texas Instruments shared transport line discipline
-#
-# CONFIG_ADIS16255 is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_EASYCAP is not set
-# CONFIG_TIDSPBRIDGE is not set
-# CONFIG_WESTBRIDGE is not set
-CONFIG_WESTBRIDGE_HAL_SELECTED=y
-CONFIG_MACH_OMAP3_WESTBRIDGE_AST_PNAND_HAL=y
-# CONFIG_MACH_NO_WESTBRIDGE is not set
-# CONFIG_ATH6K_LEGACY is not set
-# CONFIG_USB_ENESTORAGE is not set
-# CONFIG_BCM_WIMAX is not set
-# CONFIG_FT1000 is not set
-
-#
-# Speakup console speech
-#
-# CONFIG_SPEAKUP is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT2_FS_XIP is not set
-CONFIG_EXT3_FS=y
-CONFIG_EXT3_DEFAULTS_TO_ORDERED=y
-# CONFIG_EXT3_FS_XATTR is not set
-CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_XATTR=y
-# CONFIG_EXT4_FS_POSIX_ACL is not set
-# CONFIG_EXT4_FS_SECURITY is not set
-# CONFIG_EXT4_DEBUG is not set
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-CONFIG_FS_POSIX_ACL=y
-# CONFIG_XFS_FS is not set
-# CONFIG_GFS2_FS is not set
-# CONFIG_OCFS2_FS is not set
-# CONFIG_BTRFS_FS is not set
-# CONFIG_NILFS2_FS is not set
-CONFIG_FILE_LOCKING=y
-CONFIG_FSNOTIFY=y
-CONFIG_DNOTIFY=y
-CONFIG_INOTIFY_USER=y
-# CONFIG_FANOTIFY is not set
-CONFIG_QUOTA=y
-# CONFIG_QUOTA_NETLINK_INTERFACE is not set
-CONFIG_PRINT_QUOTA_WARNING=y
-# CONFIG_QUOTA_DEBUG is not set
-CONFIG_QUOTA_TREE=y
-# CONFIG_QFMT_V1 is not set
-CONFIG_QFMT_V2=y
-CONFIG_QUOTACTL=y
-# CONFIG_AUTOFS4_FS is not set
-# CONFIG_FUSE_FS is not set
-
-#
-# Caches
-#
-# CONFIG_FSCACHE is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_SYSCTL=y
-CONFIG_PROC_PAGE_MONITOR=y
-CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-# CONFIG_TMPFS_POSIX_ACL is not set
-# CONFIG_HUGETLB_PAGE is not set
-# CONFIG_CONFIGFS_FS is not set
-CONFIG_MISC_FILESYSTEMS=y
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_ECRYPT_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_YAFFS_FS is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-CONFIG_JFFS2_FS_WRITEBUFFER=y
-# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
-CONFIG_JFFS2_SUMMARY=y
-CONFIG_JFFS2_FS_XATTR=y
-CONFIG_JFFS2_FS_POSIX_ACL=y
-CONFIG_JFFS2_FS_SECURITY=y
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_JFFS2_ZLIB=y
-CONFIG_JFFS2_LZO=y
-CONFIG_JFFS2_RTIME=y
-CONFIG_JFFS2_RUBIN=y
-# CONFIG_JFFS2_CMODE_NONE is not set
-CONFIG_JFFS2_CMODE_PRIORITY=y
-# CONFIG_JFFS2_CMODE_SIZE is not set
-# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
-# CONFIG_LOGFS is not set
-CONFIG_CRAMFS=y
-# CONFIG_SQUASHFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_OMFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-CONFIG_NETWORK_FILESYSTEMS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_NFS_V3_ACL=y
-CONFIG_NFS_V4=y
-# CONFIG_NFS_V4_1 is not set
-CONFIG_ROOT_NFS=y
-CONFIG_NFS_USE_LEGACY_DNS=y
-# CONFIG_NFS_USE_NEW_IDMAPPER is not set
-# CONFIG_NFSD is not set
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_NFS_ACL_SUPPORT=y
-CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=y
-CONFIG_SUNRPC_GSS=y
-CONFIG_RPCSEC_GSS_KRB5=y
-# CONFIG_CEPH_FS is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_KARMA_PARTITION is not set
-# CONFIG_EFI_PARTITION is not set
-# CONFIG_SYSV68_PARTITION is not set
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=y
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_ASCII is not set
-CONFIG_NLS_ISO8859_1=y
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
-# CONFIG_DLM is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_PRINTK_TIME is not set
-CONFIG_ENABLE_WARN_DEPRECATED=y
-CONFIG_ENABLE_MUST_CHECK=y
-CONFIG_FRAME_WARN=1024
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_STRIP_ASM_SYMS is not set
-# CONFIG_UNUSED_SYMBOLS is not set
-CONFIG_DEBUG_FS=y
-# CONFIG_HEADERS_CHECK is not set
-# CONFIG_DEBUG_KERNEL is not set
-# CONFIG_HARDLOCKUP_DETECTOR is not set
-CONFIG_BKL=y
-# CONFIG_SPARSE_RCU_POINTER is not set
-CONFIG_STACKTRACE=y
-CONFIG_DEBUG_BUGVERBOSE=y
-# CONFIG_DEBUG_MEMORY_INIT is not set
-CONFIG_FRAME_POINTER=y
-# CONFIG_LKDTM is not set
-# CONFIG_SYSCTL_SYSCALL_CHECK is not set
-CONFIG_NOP_TRACER=y
-CONFIG_HAVE_FUNCTION_TRACER=y
-CONFIG_HAVE_DYNAMIC_FTRACE=y
-CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-CONFIG_RING_BUFFER=y
-CONFIG_EVENT_TRACING=y
-CONFIG_CONTEXT_SWITCH_TRACER=y
-CONFIG_RING_BUFFER_ALLOW_SWAP=y
-CONFIG_TRACING=y
-CONFIG_TRACING_SUPPORT=y
-CONFIG_FTRACE=y
-# CONFIG_FUNCTION_TRACER is not set
-# CONFIG_IRQSOFF_TRACER is not set
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_ENABLE_DEFAULT_TRACERS is not set
-CONFIG_BRANCH_PROFILE_NONE=y
-# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
-# CONFIG_PROFILE_ALL_BRANCHES is not set
-# CONFIG_STACK_TRACER is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-CONFIG_KPROBE_EVENT=y
-# CONFIG_RING_BUFFER_BENCHMARK is not set
-# CONFIG_DYNAMIC_DEBUG is not set
-# CONFIG_ATOMIC64_SELFTEST is not set
-# CONFIG_SAMPLES is not set
-CONFIG_HAVE_ARCH_KGDB=y
-# CONFIG_STRICT_DEVMEM is not set
-# CONFIG_ARM_UNWIND is not set
-# CONFIG_DEBUG_USER is not set
-# CONFIG_OC_ETM is not set
-
-#
-# Security options
-#
-CONFIG_KEYS=y
-# CONFIG_KEYS_DEBUG_PROC_KEYS is not set
-# CONFIG_SECURITY_DMESG_RESTRICT is not set
-CONFIG_SECURITY=y
-# CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_NETWORK is not set
-# CONFIG_SECURITY_PATH is not set
-# CONFIG_SECURITY_TOMOYO is not set
-# CONFIG_SECURITY_APPARMOR is not set
-# CONFIG_IMA is not set
-CONFIG_DEFAULT_SECURITY_DAC=y
-CONFIG_DEFAULT_SECURITY=""
-CONFIG_CRYPTO=y
-
-#
-# Crypto core or helper
-#
-CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_ALGAPI2=y
-CONFIG_CRYPTO_AEAD2=y
-CONFIG_CRYPTO_BLKCIPHER=y
-CONFIG_CRYPTO_BLKCIPHER2=y
-CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_HASH2=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_PCOMP2=y
-CONFIG_CRYPTO_MANAGER=y
-CONFIG_CRYPTO_MANAGER2=y
-CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
-# CONFIG_CRYPTO_GF128MUL is not set
-# CONFIG_CRYPTO_NULL is not set
-CONFIG_CRYPTO_WORKQUEUE=y
-# CONFIG_CRYPTO_CRYPTD is not set
-# CONFIG_CRYPTO_AUTHENC is not set
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Authenticated Encryption with Associated Data
-#
-# CONFIG_CRYPTO_CCM is not set
-# CONFIG_CRYPTO_GCM is not set
-# CONFIG_CRYPTO_SEQIV is not set
-
-#
-# Block modes
-#
-CONFIG_CRYPTO_CBC=y
-# CONFIG_CRYPTO_CTR is not set
-# CONFIG_CRYPTO_CTS is not set
-# CONFIG_CRYPTO_ECB is not set
-# CONFIG_CRYPTO_LRW is not set
-# CONFIG_CRYPTO_PCBC is not set
-# CONFIG_CRYPTO_XTS is not set
-
-#
-# Hash modes
-#
-# CONFIG_CRYPTO_HMAC is not set
-# CONFIG_CRYPTO_XCBC is not set
-# CONFIG_CRYPTO_VMAC is not set
-
-#
-# Digest
-#
-CONFIG_CRYPTO_CRC32C=y
-# CONFIG_CRYPTO_GHASH is not set
-# CONFIG_CRYPTO_MD4 is not set
-CONFIG_CRYPTO_MD5=y
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_RMD128 is not set
-# CONFIG_CRYPTO_RMD160 is not set
-# CONFIG_CRYPTO_RMD256 is not set
-# CONFIG_CRYPTO_RMD320 is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_TGR192 is not set
-# CONFIG_CRYPTO_WP512 is not set
-
-#
-# Ciphers
-#
-# CONFIG_CRYPTO_AES is not set
-# CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_ARC4 is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_CAMELLIA is not set
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
-CONFIG_CRYPTO_DES=y
-# CONFIG_CRYPTO_FCRYPT is not set
-# CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_SALSA20 is not set
-# CONFIG_CRYPTO_SEED is not set
-# CONFIG_CRYPTO_SERPENT is not set
-# CONFIG_CRYPTO_TEA is not set
-CONFIG_CRYPTO_TWOFISH=y
-CONFIG_CRYPTO_TWOFISH_COMMON=y
-
-#
-# Compression
-#
-# CONFIG_CRYPTO_DEFLATE is not set
-# CONFIG_CRYPTO_ZLIB is not set
-# CONFIG_CRYPTO_LZO is not set
-
-#
-# Random Number Generation
-#
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
-CONFIG_CRYPTO_HW=y
-# CONFIG_CRYPTO_DEV_OMAP_SHAM is not set
-# CONFIG_CRYPTO_DEV_OMAP_AES is not set
-CONFIG_BINARY_PRINTF=y
-
-#
-# Library routines
-#
-CONFIG_BITREVERSE=y
-CONFIG_GENERIC_FIND_LAST_BIT=y
-CONFIG_CRC_CCITT=y
-# CONFIG_CRC16 is not set
-# CONFIG_CRC_T10DIF is not set
-# CONFIG_CRC_ITU_T is not set
-CONFIG_CRC32=y
-# CONFIG_CRC7 is not set
-CONFIG_LIBCRC32C=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_DECOMPRESS_GZIP=y
-CONFIG_REED_SOLOMON=y
-CONFIG_REED_SOLOMON_ENC8=y
-CONFIG_REED_SOLOMON_DEC8=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-CONFIG_HAS_DMA=y
-CONFIG_NLATTR=y
diff --git a/kernel/arch/arm/configs/panda_defconfig b/kernel/arch/arm/configs/panda_defconfig
deleted file mode 100644
index 4c5e56c..0000000
--- a/kernel/arch/arm/configs/panda_defconfig
+++ /dev/null
@@ -1,331 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_CGROUPS=y
-CONFIG_CGROUP_DEBUG=y
-CONFIG_CGROUP_FREEZER=y
-CONFIG_CGROUP_CPUACCT=y
-CONFIG_RESOURCE_COUNTERS=y
-CONFIG_CGROUP_SCHED=y
-CONFIG_RT_GROUP_SCHED=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_KALLSYMS_ALL=y
-CONFIG_PANIC_TIMEOUT=5
-CONFIG_ASHMEM=y
-# CONFIG_AIO is not set
-CONFIG_EMBEDDED=y
-# CONFIG_SLUB_DEBUG is not set
-CONFIG_MODULES=y
-CONFIG_MODULE_FORCE_LOAD=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_ARCH_OMAP=y
-CONFIG_OMAP_RESET_CLOCKS=y
-# CONFIG_ARCH_OMAP2 is not set
-# CONFIG_ARCH_OMAP3 is not set
-# CONFIG_MACH_OMAP_4430SDP is not set
-CONFIG_ARM_THUMBEE=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_SMP=y
-# CONFIG_SMP_ON_UP is not set
-CONFIG_NR_CPUS=2
-CONFIG_PREEMPT=y
-CONFIG_CMDLINE="console=ttyO2,115200n8 mem=1G androidboot.console=ttyO2"
-CONFIG_CMDLINE_EXTEND=y
-CONFIG_CPU_FREQ=y
-CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y
-CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
-CONFIG_CPU_FREQ_GOV_POWERSAVE=y
-CONFIG_CPU_FREQ_GOV_USERSPACE=y
-CONFIG_CPU_FREQ_GOV_ONDEMAND=y
-CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
-CONFIG_CPU_IDLE=y
-CONFIG_OMAP_SMARTREFLEX=y
-CONFIG_OMAP_SMARTREFLEX_CLASS1P5=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-CONFIG_BINFMT_MISC=y
-CONFIG_WAKELOCK=y
-CONFIG_PM_DEBUG=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_INET_ESP=y
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-CONFIG_IPV6=y
-CONFIG_IPV6_PRIVACY=y
-CONFIG_IPV6_ROUTER_PREF=y
-CONFIG_IPV6_OPTIMISTIC_DAD=y
-CONFIG_INET6_AH=y
-CONFIG_INET6_ESP=y
-CONFIG_INET6_IPCOMP=y
-CONFIG_IPV6_MIP6=y
-CONFIG_IPV6_TUNNEL=y
-CONFIG_IPV6_MULTIPLE_TABLES=y
-CONFIG_NETFILTER=y
-CONFIG_NETFILTER_NETLINK_LOG=y
-CONFIG_NETFILTER_TPROXY=y
-CONFIG_NF_CONNTRACK=y
-CONFIG_NF_CONNTRACK_EVENTS=y
-CONFIG_NF_CT_PROTO_DCCP=y
-CONFIG_NF_CT_PROTO_SCTP=y
-CONFIG_NF_CT_PROTO_UDPLITE=y
-CONFIG_NF_CONNTRACK_AMANDA=y
-CONFIG_NF_CONNTRACK_FTP=y
-CONFIG_NF_CONNTRACK_H323=y
-CONFIG_NF_CONNTRACK_IRC=y
-CONFIG_NF_CONNTRACK_NETBIOS_NS=y
-CONFIG_NF_CONNTRACK_PPTP=y
-CONFIG_NF_CONNTRACK_SANE=y
-CONFIG_NF_CONNTRACK_TFTP=y
-CONFIG_NF_CT_NETLINK=y
-CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
-CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
-CONFIG_NETFILTER_XT_TARGET_MARK=y
-CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
-CONFIG_NETFILTER_XT_MATCH_COMMENT=y
-CONFIG_NETFILTER_XT_MATCH_CONNBYTES=y
-CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
-CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
-CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
-CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
-CONFIG_NETFILTER_XT_MATCH_HELPER=y
-CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
-CONFIG_NETFILTER_XT_MATCH_LENGTH=y
-CONFIG_NETFILTER_XT_MATCH_LIMIT=y
-CONFIG_NETFILTER_XT_MATCH_MAC=y
-CONFIG_NETFILTER_XT_MATCH_MARK=y
-CONFIG_NETFILTER_XT_MATCH_POLICY=y
-CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
-CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
-CONFIG_NETFILTER_XT_MATCH_QUOTA=y
-CONFIG_NETFILTER_XT_MATCH_QUOTA2=y
-CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y
-CONFIG_NETFILTER_XT_MATCH_SOCKET=y
-CONFIG_NETFILTER_XT_MATCH_STATE=y
-CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
-CONFIG_NETFILTER_XT_MATCH_STRING=y
-CONFIG_NETFILTER_XT_MATCH_TIME=y
-CONFIG_NETFILTER_XT_MATCH_U32=y
-CONFIG_NF_CONNTRACK_IPV4=y
-CONFIG_NF_CONNTRACK_IPV6=y
-CONFIG_IP_NF_IPTABLES=y
-CONFIG_IP_NF_MATCH_AH=y
-CONFIG_IP_NF_MATCH_ECN=y
-CONFIG_IP_NF_MATCH_TTL=y
-CONFIG_IP_NF_FILTER=y
-CONFIG_IP_NF_TARGET_REJECT=y
-CONFIG_IP_NF_TARGET_REJECT_SKERR=y
-CONFIG_IP_NF_TARGET_LOG=y
-CONFIG_NF_NAT=y
-CONFIG_IP_NF_MANGLE=y
-CONFIG_IP_NF_TARGET_MASQUERADE=y
-CONFIG_IP_NF_TARGET_NETMAP=y
-CONFIG_IP_NF_TARGET_REDIRECT=y
-CONFIG_IP_NF_RAW=y
-CONFIG_IP_NF_ARPTABLES=y
-CONFIG_IP_NF_ARPFILTER=y
-CONFIG_IP_NF_ARP_MANGLE=y
-CONFIG_IP6_NF_IPTABLES=y
-CONFIG_IP6_NF_TARGET_LOG=y
-CONFIG_IP6_NF_FILTER=y
-CONFIG_IP6_NF_TARGET_REJECT=y
-CONFIG_IP6_NF_TARGET_REJECT_SKERR=y
-CONFIG_IP6_NF_MANGLE=y
-CONFIG_IP6_NF_RAW=y
-CONFIG_PHONET=y
-CONFIG_NET_SCHED=y
-CONFIG_NET_SCH_HTB=y
-CONFIG_NET_SCH_INGRESS=y
-CONFIG_NET_CLS_U32=y
-CONFIG_NET_EMATCH=y
-CONFIG_NET_EMATCH_U32=y
-CONFIG_NET_CLS_ACT=y
-CONFIG_NET_ACT_POLICE=y
-CONFIG_NET_ACT_GACT=y
-CONFIG_NET_ACT_MIRRED=y
-CONFIG_BT=y
-CONFIG_BT_BNEP=y
-CONFIG_BT_L2CAP=y
-CONFIG_BT_SCO=y
-CONFIG_BT_RFCOMM=y
-CONFIG_BT_RFCOMM_TTY=y
-CONFIG_BT_HCIUART=y
-CONFIG_BT_HCIUART_H4=y
-CONFIG_BT_WILINK=y
-CONFIG_RFKILL=y
-CONFIG_RFKILL_INPUT=y
-CONFIG_MTD=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_NAND_IDS=y
-CONFIG_MTD_ONENAND=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_MISC_DEVICES=y
-# CONFIG_ANDROID_PMEM is not set
-CONFIG_KERNEL_DEBUGGER_CORE=y
-CONFIG_UID_STAT=y
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_MD=y
-CONFIG_BLK_DEV_DM=y
-CONFIG_DM_DEBUG=y
-CONFIG_DM_CRYPT=y
-CONFIG_DM_UEVENT=y
-CONFIG_NETDEVICES=y
-CONFIG_IFB=y
-CONFIG_USB_USBNET=y
-CONFIG_USB_NET_SMSC95XX=y
-CONFIG_PPP=y
-CONFIG_PPP_DEFLATE=y
-CONFIG_PPP_BSDCOMP=y
-CONFIG_PPP_MPPE=y
-CONFIG_PPPOLAC=y
-CONFIG_PPPOPNS=y
-CONFIG_INPUT_EVDEV=y
-CONFIG_INPUT_KEYRESET=y
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=y
-CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI4_DEV=y
-CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE=y
-CONFIG_INPUT_MISC=y
-CONFIG_INPUT_KEYCHORD=y
-CONFIG_INPUT_UINPUT=y
-CONFIG_INPUT_GPIO=y
-# CONFIG_VT is not set
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_HW_RANDOM=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_GPIO=y
-CONFIG_SPI=y
-CONFIG_SPI_GPIO=y
-CONFIG_GPIO_SYSFS=y
-CONFIG_GPIO_TWL4030=y
-CONFIG_POWER_SUPPLY=y
-# CONFIG_HWMON is not set
-CONFIG_TWL6030_PWM=y
-CONFIG_REGULATOR_TWL4030=y
-CONFIG_MEDIA_SUPPORT=y
-CONFIG_PVR_SGX=y
-CONFIG_PVR_NEED_PVR_DPF=y
-CONFIG_PVR_NEED_PVR_ASSERT=y
-CONFIG_PVR_USSE_EDM_STATUS_DEBUG=y
-CONFIG_FB=y
-CONFIG_OMAP2_DSS=y
-# CONFIG_OMAP2_DSS_VENC is not set
-CONFIG_FB_OMAP2=y
-CONFIG_FB_OMAP2_NUM_FBS=2
-CONFIG_OMAP2_VRAM_SIZE=16
-CONFIG_PANEL_GENERIC_DPI=y
-CONFIG_DISPLAY_SUPPORT=y
-CONFIG_USB=y
-CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_SUSPEND=y
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_MUSB_HDRC=y
-CONFIG_USB_MUSB_OMAP2PLUS=y
-CONFIG_USB_MUSB_PERIPHERAL=y
-CONFIG_USB_GADGET_MUSB_HDRC=y
-CONFIG_USB_ACM=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_SERIAL=y
-CONFIG_USB_SERIAL_KEYSPAN=y
-CONFIG_USB_SERIAL_KEYSPAN_MPR=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19=y
-CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
-CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
-CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
-CONFIG_USB_GADGET=y
-CONFIG_USB_GADGET_VBUS_DRAW=500
-CONFIG_USB_G_ANDROID=y
-CONFIG_MMC=y
-CONFIG_MMC_UNSAFE_RESUME=y
-CONFIG_MMC_EMBEDDED_SDIO=y
-CONFIG_MMC_PARANOID_SD_INIT=y
-CONFIG_MMC_OMAP=y
-CONFIG_MMC_OMAP_HS=y
-CONFIG_SWITCH=y
-CONFIG_SWITCH_GPIO=y
-CONFIG_RTC_CLASS=y
-CONFIG_STAGING=y
-CONFIG_ANDROID=y
-CONFIG_ANDROID_BINDER_IPC=y
-CONFIG_ANDROID_LOGGER=y
-CONFIG_ANDROID_RAM_CONSOLE=y
-CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION=y
-CONFIG_ANDROID_TIMED_GPIO=y
-CONFIG_ANDROID_LOW_MEMORY_KILLER=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT4_FS=y
-# CONFIG_EXT4_FS_XATTR is not set
-# CONFIG_DNOTIFY is not set
-CONFIG_FUSE_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
-# CONFIG_NETWORK_FILESYSTEMS is not set
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_EFI_PARTITION=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ASCII=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_PRINTK_TIME=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DETECT_HUNG_TASK=y
-# CONFIG_DEBUG_PREEMPT is not set
-CONFIG_DEBUG_RT_MUTEXES=y
-CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_MUTEXES=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
-CONFIG_DEBUG_INFO=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
-# CONFIG_ARM_UNWIND is not set
-CONFIG_DEBUG_USER=y
-CONFIG_CRYPTO_TWOFISH=y
-CONFIG_CRC_CCITT=y
-CONFIG_SOUND=y
-CONFIG_SND=y
-CONFIG_SND_SOC=y
-CONFIG_SND_OMAP_SOC=y
-CONFIG_SND_OMAP_SOC_SDP4430=y
-CONFIG_SND_OMAP_SOC_OMAP4_HDMI=y
-CONFIG_OMAP_HSI=y
-CONFIG_OMAP_HSI_DEVICE=y
-CONFIG_CFG80211=y
-CONFIG_NL80211_TESTMODE=y
-CONFIG_LIB80211=y
-CONFIG_MAC80211=y
-CONFIG_MAC80211_LEDS=y
-CONFIG_MAC80211_DEBUGFS=y
-CONFIG_USB_ZD1201=y
-CONFIG_WL12XX_MENU=y
-CONFIG_WL12XX=y
-CONFIG_WL12XX_SDIO=y
-CONFIG_CRYPTO_PCBC=y
-CONFIG_CRYPTO_MD4=y
-CONFIG_CRYPTO_MICHAEL_MIC=y
-CONFIG_CRYPTO_SHA256=y
-CONFIG_OMAP_TEMP_SENSOR=y
-CONFIG_OMAP_DIE_TEMP_SENSOR=y
-CONFIG_TI_ST=y
-CONFIG_KEYBOARD_GPIO=y
diff --git a/kernel/arch/arm/mach-omap2/board-omap3beagle.c b/kernel/arch/arm/mach-omap2/board-omap3beagle.c
deleted file mode 100644
index b3d1b81..0000000
--- a/kernel/arch/arm/mach-omap2/board-omap3beagle.c
+++ /dev/null
@@ -1,1038 +0,0 @@
-/*
- * linux/arch/arm/mach-omap2/board-omap3beagle.c
- *
- * Copyright (C) 2008 Texas Instruments
- *
- * Modified from mach-omap2/board-3430sdp.c
- *
- * Initial code: Syed Mohammed Khasim
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/leds.h>
-#include <linux/gpio.h>
-#include <linux/input.h>
-#include <linux/gpio_keys.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-#include <linux/mtd/nand.h>
-#include <linux/mmc/host.h>
-
-#include <linux/usb/android_composite.h>
-
-#include <linux/regulator/machine.h>
-#include <linux/i2c/twl.h>
-
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/flash.h>
-
-#include <plat/board.h>
-#include <plat/common.h>
-#include <plat/display.h>
-#include <plat/gpmc.h>
-#include <plat/nand.h>
-#include <plat/usb.h>
-
-#include "mux.h"
-#include "hsmmc.h"
-#include "timer-gp.h"
-#include "board-flash.h"
-
-#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4
-#include <linux/input/synaptics_dsx.h>
-
-#define TM_SAMPLE1 (1) // 2D only
-#define TM_SAMPLE2 (2) // 2D + 0D x 2
-#define TM_SAMPLE3 (3) // 2D + 0D x 4
-#define SYNAPTICS_MODULE TM_SAMPLE1
-#endif
-
-#define NAND_BLOCK_SIZE SZ_128K
-
-#ifdef CONFIG_USB_ANDROID
-#define GOOGLE_VENDOR_ID 0x18d1
-#define GOOGLE_PRODUCT_ID 0x9018
-#define GOOGLE_ADB_PRODUCT_ID 0x9015
-#endif
-
-/* Synaptics Thin Driver */
-#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4
-static int synaptics_gpio_setup(unsigned gpio, bool configure)
-{
- int retval=0;
- if (configure)
- {
- retval = gpio_request(gpio, "rmi4_attn");
- if (retval) {
- pr_err("%s: Failed to get attn gpio %d. Code: %d.",
- __func__, gpio, retval);
- return retval;
- }
- omap_mux_init_signal("sdmmc2_clk.gpio_130", OMAP_PIN_INPUT_PULLUP);
-
- retval = gpio_direction_input(gpio);
- if (retval) {
- pr_err("%s: Failed to setup attn gpio %d. Code: %d.",
- __func__, gpio, retval);
- gpio_free(gpio);
- }
- } else {
- pr_warn("%s: No way to deconfigure gpio %d.",
- __func__, gpio);
- }
-
- return retval;
-}
-
- #if (SYNAPTICS_MODULE == TM_SAMPLE1)
-#define TM_SAMPLE1_ADDR 0x20
-#define TM_SAMPLE1_ATTN 130
-
-static unsigned char TM_SAMPLE1_f1a_button_codes[] = {};
-
-static struct synaptics_rmi4_capacitance_button_map TM_SAMPLE1_capacitance_button_map = {
- .nbuttons = ARRAY_SIZE(TM_SAMPLE1_f1a_button_codes),
- .map = TM_SAMPLE1_f1a_button_codes,
-};
-
-static struct synaptics_rmi4_platform_data rmi4_platformdata = {
- .irq_flags = IRQF_TRIGGER_FALLING,
- .irq_gpio = TM_SAMPLE1_ATTN,
- .gpio_config = synaptics_gpio_setup,
- .capacitance_button_map = &TM_SAMPLE1_capacitance_button_map,
-};
-
-static struct i2c_board_info bus2_i2c_devices[] = {
- {
- I2C_BOARD_INFO("synaptics_rmi4_i2c", TM_SAMPLE1_ADDR),
- .platform_data = &rmi4_platformdata,
- },
-};
-
-#elif (SYNAPTICS_MODULE == TM_SAMPLE2)
-#define TM_SAMPLE2_ADDR 0x20
-#define TM_SAMPLE2_ATTN 130
-
-static unsigned char TM_SAMPLE2_f1a_button_codes[] = {KEY_MENU, KEY_BACK};
-
-static struct synaptics_rmi4_capacitance_button_map TM_SAMPLE2_capacitance_button_map = {
- .nbuttons = ARRAY_SIZE(TM_SAMPLE2_f1a_button_codes),
- .map = TM_SAMPLE2_f1a_button_codes,
-};
-
-static struct synaptics_rmi4_platform_data rmi4_platformdata = {
- .irq_flags = IRQF_TRIGGER_FALLING,
- .irq_gpio = TM_SAMPLE2_ATTN,
- .gpio_config = synaptics_gpio_setup,
- .capacitance_button_map = &TM_SAMPLE2_capacitance_button_map,
-};
-
-static struct i2c_board_info bus2_i2c_devices[] = {
- {
- I2C_BOARD_INFO("synaptics_rmi4_i2c", TM_SAMPLE2_ADDR),
- .platform_data = &rmi4_platformdata,
- },
-};
-
-#elif (SYNAPTICS_MODULE == TM_SAMPLE3)
-#define TM_SAMPLE3_ADDR 0x20
-#define TM_SAMPLE3_ATTN 130
-
-static unsigned char TM_SAMPLE3_f1a_button_codes[] = {KEY_MENU, KEY_HOME,KEY_BACK,KEY_SEARCH};
-
-static struct synaptics_rmi4_capacitance_button_map TM_SAMPLE3_capacitance_button_map = {
- .nbuttons = ARRAY_SIZE(TM_SAMPLE3_f1a_button_codes),
- .map = TM_SAMPLE3_f1a_button_codes,
-};
-
-static struct synaptics_rmi4_platform_data rmi4_platformdata = {
- .irq_flags = IRQF_TRIGGER_FALLING,
- .irq_gpio = TM_SAMPLE3_ATTN,
- .gpio_config = synaptics_gpio_setup,
- .capacitance_button_map = &TM_SAMPLE3_capacitance_button_map,
-};
-
-static struct i2c_board_info bus2_i2c_devices[] = {
- {
- I2C_BOARD_INFO("synaptics_rmi4_i2c", TM_SAMPLE3_ADDR),
- .platform_data = &rmi4_platformdata,
- },
-};
-#endif
-
-void __init i2c_device_setup(void)
-{
- pr_info(">>>>I2C device setup.");
- if (ARRAY_SIZE(bus2_i2c_devices)) {
- i2c_register_board_info(2, bus2_i2c_devices,
- ARRAY_SIZE(bus2_i2c_devices));
- }
-}
-
-/* End of Synaptics change for beagle board */
-
-static char *usb_functions_adb[] = {
- "adb",
-};
-
-static char *usb_functions_mass_storage[] = {
- "usb_mass_storage",
-};
-static char *usb_functions_ums_adb[] = {
- "usb_mass_storage",
- "adb",
-};
-
-static char *usb_functions_all[] = {
- "adb", "usb_mass_storage",
-};
-
-static struct android_usb_product usb_products[] = {
- {
- .product_id = GOOGLE_PRODUCT_ID,
- .num_functions = ARRAY_SIZE(usb_functions_adb),
- .functions = usb_functions_adb,
- },
- {
- .product_id = GOOGLE_PRODUCT_ID,
- .num_functions = ARRAY_SIZE(usb_functions_mass_storage),
- .functions = usb_functions_mass_storage,
- },
- {
- .product_id = GOOGLE_PRODUCT_ID,
- .num_functions = ARRAY_SIZE(usb_functions_ums_adb),
- .functions = usb_functions_ums_adb,
- },
-};
-
-static struct usb_mass_storage_platform_data mass_storage_pdata = {
- .nluns = 1,
- .vendor = "rowboat",
- .product = "rowboat gadget",
- .release = 0x100,
-};
-
-static struct platform_device usb_mass_storage_device = {
- .name = "usb_mass_storage",
- .id = -1,
- .dev = {
- .platform_data = &mass_storage_pdata,
- },
-};
-
-static struct android_usb_platform_data android_usb_pdata = {
- .vendor_id = GOOGLE_VENDOR_ID,
- .product_id = GOOGLE_PRODUCT_ID,
- .functions = usb_functions_all,
- .products = usb_products,
- .num_products = ARRAY_SIZE(usb_products),
- .version = 0x0100,
- .product_name = "rowboat gadget",
- .manufacturer_name = "rowboat",
- .serial_number = "20100720",
- .num_functions = ARRAY_SIZE(usb_functions_all),
-};
-
-static struct platform_device androidusb_device = {
- .name = "android_usb",
- .id = -1,
- .dev = {
- .platform_data = &android_usb_pdata,
- },
-};
-
-static void omap3beagle_android_gadget_init(void)
-{
- platform_device_register(&androidusb_device);
-}
-#endif
-/*
- * OMAP3 Beagle revision
- * Run time detection of Beagle revision is done by reading GPIO.
- * GPIO ID -
- * AXBX = GPIO173, GPIO172, GPIO171: 1 1 1
- * C1_3 = GPIO173, GPIO172, GPIO171: 1 1 0
- * C4 = GPIO173, GPIO172, GPIO171: 1 0 1
- * XM = GPIO173, GPIO172, GPIO171: 0 0 0
- */
-enum {
- OMAP3BEAGLE_BOARD_UNKN = 0,
- OMAP3BEAGLE_BOARD_AXBX,
- OMAP3BEAGLE_BOARD_C1_3,
- OMAP3BEAGLE_BOARD_C4,
- OMAP3BEAGLE_BOARD_XM,
- OMAP3BEAGLE_BOARD_XMC,
-};
-
-extern void omap_pm_sys_offmode_select(int);
-extern void omap_pm_sys_offmode_pol(int);
-extern void omap_pm_sys_clkreq_pol(int);
-extern void omap_pm_auto_off(int);
-extern void omap_pm_auto_ret(int);
-
-static u8 omap3_beagle_version;
-
-static u8 omap3_beagle_get_rev(void)
-{
- return omap3_beagle_version;
-}
-
-/**
- * Board specific initialization of PM components
- */
-static void __init omap3_beagle_pm_init(void)
-{
- /* Use sys_offmode signal */
- omap_pm_sys_offmode_select(1);
-
- /* sys_clkreq - active high */
- omap_pm_sys_clkreq_pol(1);
-
- /* sys_offmode - active low */
- omap_pm_sys_offmode_pol(0);
-
- /* Automatically send OFF command */
- omap_pm_auto_off(1);
-
- /* Automatically send RET command */
- omap_pm_auto_ret(1);
-}
-
-static void __init omap3_beagle_init_rev(void)
-{
- int ret;
- u16 beagle_rev = 0;
-
- omap_mux_init_gpio(171, OMAP_PIN_INPUT_PULLUP);
- omap_mux_init_gpio(172, OMAP_PIN_INPUT_PULLUP);
- omap_mux_init_gpio(173, OMAP_PIN_INPUT_PULLUP);
-
- ret = gpio_request(171, "rev_id_0");
- if (ret < 0)
- goto fail0;
-
- ret = gpio_request(172, "rev_id_1");
- if (ret < 0)
- goto fail1;
-
- ret = gpio_request(173, "rev_id_2");
- if (ret < 0)
- goto fail2;
-
- gpio_direction_input(171);
- gpio_direction_input(172);
- gpio_direction_input(173);
-
- beagle_rev = gpio_get_value(171) | (gpio_get_value(172) << 1)
- | (gpio_get_value(173) << 2);
-
- switch (beagle_rev) {
- case 7:
- printk(KERN_INFO "OMAP3 Beagle Rev: Ax/Bx\n");
- omap3_beagle_version = OMAP3BEAGLE_BOARD_AXBX;
- break;
- case 6:
- printk(KERN_INFO "OMAP3 Beagle Rev: C1/C2/C3\n");
- omap3_beagle_version = OMAP3BEAGLE_BOARD_C1_3;
- break;
- case 5:
- printk(KERN_INFO "OMAP3 Beagle Rev: C4\n");
- omap3_beagle_version = OMAP3BEAGLE_BOARD_C4;
- break;
- case 2:
- printk(KERN_INFO "OMAP3 Beagle Rev: xM C\n");
- omap3_beagle_version = OMAP3BEAGLE_BOARD_XMC;
- break;
- case 0:
- printk(KERN_INFO "OMAP3 Beagle Rev: xM\n");
- omap3_beagle_version = OMAP3BEAGLE_BOARD_XM;
- break;
- default:
- printk(KERN_INFO "OMAP3 Beagle Rev: unknown %hd\n", beagle_rev);
- omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN;
- }
-
- return;
-
-fail2:
- gpio_free(172);
-fail1:
- gpio_free(171);
-fail0:
- printk(KERN_ERR "Unable to get revision detection GPIO pins\n");
- omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN;
-
- return;
-}
-
-static struct mtd_partition omap3beagle_nand_partitions[] = {
- /* All the partition sizes are listed in terms of NAND block size */
- {
- .name = "X-Loader",
- .offset = 0,
- .size = 4 * NAND_BLOCK_SIZE,
- .mask_flags = MTD_WRITEABLE, /* force read-only */
- },
- {
- .name = "U-Boot",
- .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */
- .size = 15 * NAND_BLOCK_SIZE,
- .mask_flags = MTD_WRITEABLE, /* force read-only */
- },
- {
- .name = "U-Boot Env",
- .offset = MTDPART_OFS_APPEND, /* Offset = 0x260000 */
- .size = 1 * NAND_BLOCK_SIZE,
- },
- {
- .name = "Kernel",
- .offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */
- .size = 32 * NAND_BLOCK_SIZE,
- },
- {
- .name = "File System",
- .offset = MTDPART_OFS_APPEND, /* Offset = 0x680000 */
- .size = MTDPART_SIZ_FULL,
- },
-};
-
-/* DSS */
-
-static int beagle_enable_dvi(struct omap_dss_device *dssdev)
-{
- if (gpio_is_valid(dssdev->reset_gpio))
- gpio_set_value(dssdev->reset_gpio, 1);
-
- return 0;
-}
-
-static void beagle_disable_dvi(struct omap_dss_device *dssdev)
-{
- if (gpio_is_valid(dssdev->reset_gpio))
- gpio_set_value(dssdev->reset_gpio, 0);
-}
-
-static struct omap_dss_device beagle_dvi_device = {
- .type = OMAP_DISPLAY_TYPE_DPI,
- .name = "dvi",
- .driver_name = "generic_panel",
- .phy.dpi.data_lines = 24,
- .reset_gpio = -EINVAL,
- .platform_enable = beagle_enable_dvi,
- .platform_disable = beagle_disable_dvi,
-};
-
-static struct omap_dss_device beagle_tv_device = {
- .name = "tv",
- .driver_name = "venc",
- .type = OMAP_DISPLAY_TYPE_VENC,
- .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
-};
-
-static struct omap_dss_device *beagle_dss_devices[] = {
- &beagle_dvi_device,
- &beagle_tv_device,
-};
-
-static struct omap_dss_board_info beagle_dss_data = {
- .num_devices = ARRAY_SIZE(beagle_dss_devices),
- .devices = beagle_dss_devices,
- .default_device = &beagle_dvi_device,
-};
-
-static struct platform_device beagle_dss_device = {
- .name = "omapdss",
- .id = -1,
- .dev = {
- .platform_data = &beagle_dss_data,
- },
-};
-
-static struct regulator_consumer_supply beagle_vdac_supply =
- REGULATOR_SUPPLY("vdda_dac", "omapdss");
-
-static struct regulator_consumer_supply beagle_vdvi_supply =
- REGULATOR_SUPPLY("vdds_dsi", "omapdss");
-
-static void __init beagle_display_init(void)
-{
- int r;
-
- r = gpio_request(beagle_dvi_device.reset_gpio, "DVI reset");
- if (r < 0) {
- printk(KERN_ERR "Unable to get DVI reset GPIO\n");
- return;
- }
-
- gpio_direction_output(beagle_dvi_device.reset_gpio, 0);
-}
-
-#include "sdram-micron-mt46h32m32lf-6.h"
-
-static struct omap2_hsmmc_info mmc[] = {
- {
- .mmc = 1,
- .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
- .gpio_wp = 29,
- },
- {} /* Terminator */
-};
-
-static struct regulator_consumer_supply beagle_vmmc1_supply = {
- .supply = "vmmc",
-};
-
-static struct regulator_consumer_supply beagle_vsim_supply = {
- .supply = "vmmc_aux",
-};
-
-static struct regulator_consumer_supply beagle_vaux3_supply = {
- .supply = "cam_1v8",
-};
-
-static struct regulator_consumer_supply beagle_vaux4_supply = {
- .supply = "cam_2v8",
-};
-
-static struct gpio_led gpio_leds[];
-
-static int beagle_twl_gpio_setup(struct device *dev,
- unsigned gpio, unsigned ngpio)
-{
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM || omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XMC) {
- mmc[0].gpio_wp = -EINVAL;
- } else if ((omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C1_3) ||
- (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C4)) {
- omap_mux_init_gpio(23, OMAP_PIN_INPUT);
- mmc[0].gpio_wp = 23;
- } else {
- omap_mux_init_gpio(29, OMAP_PIN_INPUT);
- }
- /* gpio + 0 is "mmc0_cd" (input/IRQ) */
- mmc[0].gpio_cd = gpio + 0;
- omap2_hsmmc_init(mmc);
-
- /* link regulators to MMC adapters */
- beagle_vmmc1_supply.dev = mmc[0].dev;
- beagle_vsim_supply.dev = mmc[0].dev;
-
- /* REVISIT: need ehci-omap hooks for external VBUS
- * power switch and overcurrent detect
- */
- if (omap3_beagle_get_rev() != OMAP3BEAGLE_BOARD_XM || omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XMC) {
- gpio_request(gpio + 1, "EHCI_nOC");
- gpio_direction_input(gpio + 1);
- }
-
- /*
- * TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, XM active
- * high / others active low)
- */
- gpio_request(gpio + TWL4030_GPIO_MAX, "nEN_USB_PWR");
- gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0);
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM)
- gpio_direction_output(gpio + TWL4030_GPIO_MAX, 1);
- else
- gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0);
-
- /* DVI reset GPIO is different between beagle revisions */
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM || omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XMC)
- beagle_dvi_device.reset_gpio = 129;
- else
- beagle_dvi_device.reset_gpio = 170;
-
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
- /* Power on camera interface */
- gpio_request(gpio + 2, "CAM_EN");
- gpio_direction_output(gpio + 2, 1);
-
- /* TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, active low) */
- gpio_request(gpio + TWL4030_GPIO_MAX, "nEN_USB_PWR");
- gpio_direction_output(gpio + TWL4030_GPIO_MAX, 1);
- } else {
- gpio_request(gpio + 1, "EHCI_nOC");
- gpio_direction_input(gpio + 1);
-
- /* TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, active low) */
- gpio_request(gpio + TWL4030_GPIO_MAX, "nEN_USB_PWR");
- gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0);
- }
- /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
- gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
-
- /*
- * gpio + 1 on Xm controls the TFP410's enable line (active low)
- * gpio + 2 control varies depending on the board rev as follows:
- * P7/P8 revisions(prototype): Camera EN
- * A2+ revisions (production): LDO (supplies DVI, serial, led blocks)
- */
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM || omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XMC) {
- gpio_request(gpio + 1, "nDVI_PWR_EN");
- gpio_direction_output(gpio + 1, 0);
- gpio_request(gpio + 2, "DVI_LDO_EN");
- gpio_direction_output(gpio + 2, 1);
- }
-
- return 0;
-}
-
-static struct twl4030_gpio_platform_data beagle_gpio_data = {
- .gpio_base = OMAP_MAX_GPIO_LINES,
- .irq_base = TWL4030_GPIO_IRQ_BASE,
- .irq_end = TWL4030_GPIO_IRQ_END,
- .use_leds = true,
- .pullups = BIT(1),
- .pulldowns = BIT(2) | BIT(6) | BIT(7) | BIT(8) | BIT(13)
- | BIT(15) | BIT(16) | BIT(17),
- .setup = beagle_twl_gpio_setup,
-};
-
-/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
-static struct regulator_init_data beagle_vmmc1 = {
- .constraints = {
- .min_uV = 1850000,
- .max_uV = 3150000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
- | REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
- .num_consumer_supplies = 1,
- .consumer_supplies = &beagle_vmmc1_supply,
-};
-
-/* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */
-static struct regulator_init_data beagle_vsim = {
- .constraints = {
- .min_uV = 1800000,
- .max_uV = 3000000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
- | REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
- .num_consumer_supplies = 1,
- .consumer_supplies = &beagle_vsim_supply,
-};
-
-/* VDAC for DSS driving S-Video (8 mA unloaded, max 65 mA) */
-static struct regulator_init_data beagle_vdac = {
- .constraints = {
- .min_uV = 1800000,
- .max_uV = 1800000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
- .num_consumer_supplies = 1,
- .consumer_supplies = &beagle_vdac_supply,
-};
-
-/* VPLL2 for digital video outputs */
-static struct regulator_init_data beagle_vpll2 = {
- .constraints = {
- .name = "VDVI",
- .min_uV = 1800000,
- .max_uV = 1800000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
- .num_consumer_supplies = 1,
- .consumer_supplies = &beagle_vdvi_supply,
-};
-
-/* VAUX3 for CAM_1V8 */
-static struct regulator_init_data beagle_vaux3 = {
- .constraints = {
- .min_uV = 1800000,
- .max_uV = 1800000,
- .apply_uV = true,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
- .num_consumer_supplies = 1,
- .consumer_supplies = &beagle_vaux3_supply,
-};
-
- /* VAUX4 for CAM_2V8 */
-static struct regulator_init_data beagle_vaux4 = {
- .constraints = {
- .min_uV = 1800000,
- .max_uV = 1800000,
- .apply_uV = true,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
- .num_consumer_supplies = 1,
- .consumer_supplies = &beagle_vaux4_supply,
-};
-
-static struct twl4030_usb_data beagle_usb_data = {
- .usb_mode = T2_USB_MODE_ULPI,
-};
-
-/**
- * Macro to configure resources
- */
-#define TWL4030_RESCONFIG(res,grp,typ1,typ2,state) \
- { \
- .resource = res, \
- .devgroup = grp, \
- .type = typ1, \
- .type2 = typ2, \
- .remap_sleep = state \
- }
-
-static struct twl4030_resconfig __initdata board_twl4030_rconfig[] = {
- TWL4030_RESCONFIG(RES_VPLL1, DEV_GRP_P1, 3, 1, RES_STATE_OFF), /* ? */
- TWL4030_RESCONFIG(RES_VINTANA1, DEV_GRP_ALL, 1, 2, RES_STATE_SLEEP),
- TWL4030_RESCONFIG(RES_VINTANA2, DEV_GRP_ALL, 0, 2, RES_STATE_SLEEP),
- TWL4030_RESCONFIG(RES_VINTDIG, DEV_GRP_ALL, 1, 2, RES_STATE_SLEEP),
- TWL4030_RESCONFIG(RES_VIO, DEV_GRP_ALL, 2, 2, RES_STATE_SLEEP),
- TWL4030_RESCONFIG(RES_VDD1, DEV_GRP_P1, 4, 1, RES_STATE_OFF), /* ? */
- TWL4030_RESCONFIG(RES_VDD2, DEV_GRP_P1, 3, 1, RES_STATE_OFF), /* ? */
- TWL4030_RESCONFIG(RES_REGEN, DEV_GRP_ALL, 2, 1, RES_STATE_SLEEP),
- TWL4030_RESCONFIG(RES_NRES_PWRON, DEV_GRP_ALL, 0, 1, RES_STATE_SLEEP),
- TWL4030_RESCONFIG(RES_CLKEN, DEV_GRP_ALL, 3, 2, RES_STATE_SLEEP),
- TWL4030_RESCONFIG(RES_SYSEN, DEV_GRP_ALL, 6, 1, RES_STATE_SLEEP),
- TWL4030_RESCONFIG(RES_HFCLKOUT, DEV_GRP_P3, 0, 2, RES_STATE_SLEEP), /* ? */
- TWL4030_RESCONFIG(0, 0, 0, 0, 0),
-};
-
-/**
- * Optimized 'Active to Sleep' sequence
- */
-static struct twl4030_ins omap3beagle_sleep_seq[] __initdata = {
- { MSG_SINGULAR(DEV_GRP_NULL, RES_HFCLKOUT, RES_STATE_SLEEP), 20},
- { MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1, RES_STATE_SLEEP), 2 },
- { MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2, RES_STATE_SLEEP), 2 },
-};
-
-static struct twl4030_script omap3beagle_sleep_script __initdata = {
- .script = omap3beagle_sleep_seq,
- .size = ARRAY_SIZE(omap3beagle_sleep_seq),
- .flags = TWL4030_SLEEP_SCRIPT,
-};
-
-/**
- * Optimized 'Sleep to Active (P12)' sequence
- */
-static struct twl4030_ins omap3beagle_wake_p12_seq[] __initdata = {
- { MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1, RES_STATE_ACTIVE), 2 }
-};
-
-static struct twl4030_script omap3beagle_wake_p12_script __initdata = {
- .script = omap3beagle_wake_p12_seq,
- .size = ARRAY_SIZE(omap3beagle_wake_p12_seq),
- .flags = TWL4030_WAKEUP12_SCRIPT,
-};
-
-/**
- * Optimized 'Sleep to Active' (P3) sequence
- */
-static struct twl4030_ins omap3beagle_wake_p3_seq[] __initdata = {
- { MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2, RES_STATE_ACTIVE), 2 }
-};
-
-static struct twl4030_script omap3beagle_wake_p3_script __initdata = {
- .script = omap3beagle_wake_p3_seq,
- .size = ARRAY_SIZE(omap3beagle_wake_p3_seq),
- .flags = TWL4030_WAKEUP3_SCRIPT,
-};
-
-/**
- * Optimized warm reset sequence (for less power surge)
- */
-static struct twl4030_ins omap3beagle_wrst_seq[] __initdata = {
- { MSG_SINGULAR(DEV_GRP_NULL, RES_RESET, RES_STATE_OFF), 0x2 },
- { MSG_SINGULAR(DEV_GRP_NULL, RES_MAIN_REF, RES_STATE_WRST), 2 },
- { MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2, RES_STATE_WRST), 0x2},
- { MSG_SINGULAR(DEV_GRP_NULL, RES_VUSB_3V1, RES_STATE_WRST), 0x2 },
- { MSG_SINGULAR(DEV_GRP_NULL, RES_VPLL1, RES_STATE_WRST), 0x2 },
- { MSG_SINGULAR(DEV_GRP_NULL, RES_VDD2, RES_STATE_WRST), 0x7 },
- { MSG_SINGULAR(DEV_GRP_NULL, RES_VDD1, RES_STATE_WRST), 0x25 },
- { MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_RC, RES_TYPE_ALL, RES_TYPE2_R0, RES_STATE_WRST), 0x2 },
- { MSG_SINGULAR(DEV_GRP_NULL, RES_RESET, RES_STATE_ACTIVE), 0x2 },
-
-};
-
-static struct twl4030_script omap3beagle_wrst_script __initdata = {
- .script = omap3beagle_wrst_seq,
- .size = ARRAY_SIZE(omap3beagle_wrst_seq),
- .flags = TWL4030_WRST_SCRIPT,
-};
-
-static struct twl4030_script __initdata *board_twl4030_scripts[] = {
- &omap3beagle_wake_p12_script,
- &omap3beagle_wake_p3_script,
- &omap3beagle_sleep_script,
- &omap3beagle_wrst_script
-};
-
-static struct twl4030_power_data __initdata omap3beagle_script_data = {
- .scripts = board_twl4030_scripts,
- .num = ARRAY_SIZE(board_twl4030_scripts),
- .resource_config = board_twl4030_rconfig,
-};
-
-static struct twl4030_codec_audio_data beagle_audio_data = {
- .audio_mclk = 26000000,
- .digimic_delay = 1,
- .ramp_delay_value = 1,
- .offset_cncl_path = 1,
- .check_defaults = false,
- .reset_registers = false,
- .reset_registers = false,
-};
-
-static struct twl4030_codec_data beagle_codec_data = {
- .audio_mclk = 26000000,
- .audio = &beagle_audio_data,
-};
-
-static struct twl4030_platform_data beagle_twldata = {
- .irq_base = TWL4030_IRQ_BASE,
- .irq_end = TWL4030_IRQ_END,
-
- /* platform_data for children goes here */
- .usb = &beagle_usb_data,
- .gpio = &beagle_gpio_data,
- .codec = &beagle_codec_data,
- .vmmc1 = &beagle_vmmc1,
- .vsim = &beagle_vsim,
- .vdac = &beagle_vdac,
- .vpll2 = &beagle_vpll2,
- .vaux3 = &beagle_vaux3,
- .vaux4 = &beagle_vaux4,
- .power = &omap3beagle_script_data,
-};
-
-static struct i2c_board_info __initdata beagle_i2c_boardinfo[] = {
- {
- I2C_BOARD_INFO("twl4030", 0x48),
- .flags = I2C_CLIENT_WAKE,
- .irq = INT_34XX_SYS_NIRQ,
- .platform_data = &beagle_twldata,
- },
-};
-
-static struct i2c_board_info __initdata beagle_i2c_eeprom[] = {
- {
- I2C_BOARD_INFO("eeprom", 0x50),
- },
-};
-
-static int __init omap3_beagle_i2c_init(void)
-{
- omap_register_i2c_bus(1, 2600, beagle_i2c_boardinfo,
- ARRAY_SIZE(beagle_i2c_boardinfo));
-
- /* Bus 2 is used for Camera/Sensor interface */
- if (ARRAY_SIZE(bus2_i2c_devices))
- omap_register_i2c_bus(2, 400, bus2_i2c_devices,
- ARRAY_SIZE(bus2_i2c_devices));
- else
- omap_register_i2c_bus(2, 400, NULL, 0);
-
- /* Bus 3 is attached to the DVI port where devices like the pico DLP
- * projector don't work reliably with 400kHz */
- omap_register_i2c_bus(3, 100, beagle_i2c_eeprom, ARRAY_SIZE(beagle_i2c_eeprom));
-
- return 0;
-}
-
-static struct gpio_led gpio_leds[] = {
- {
- .name = "beagleboard::usr0",
- .default_trigger = "heartbeat",
- .gpio = 150,
- },
- {
- .name = "beagleboard::usr1",
- .default_trigger = "mmc0",
- .gpio = 149,
- },
- {
- .name = "beagleboard::pmu_stat",
- .gpio = -EINVAL, /* gets replaced */
- .active_low = true,
- },
-};
-
-static struct gpio_led_platform_data gpio_led_info = {
- .leds = gpio_leds,
- .num_leds = ARRAY_SIZE(gpio_leds),
-};
-
-static struct platform_device leds_gpio = {
- .name = "leds-gpio",
- .id = -1,
- .dev = {
- .platform_data = &gpio_led_info,
- },
-};
-
-static struct gpio_keys_button gpio_buttons[] = {
- {
- .code = KEY_POWER,
- .gpio = 4,
- .desc = "user",
- .wakeup = 1,
- },
-};
-
-static struct gpio_keys_platform_data gpio_key_info = {
- .buttons = gpio_buttons,
- .nbuttons = ARRAY_SIZE(gpio_buttons),
-};
-
-static struct platform_device keys_gpio = {
- .name = "gpio-keys",
- .id = -1,
- .dev = {
- .platform_data = &gpio_key_info,
- },
-};
-
-static void __init omap3_beagle_init_irq(void)
-{
- omap2_init_common_infrastructure();
- omap2_init_common_devices(mt46h32m32lf6_sdrc_params,
- mt46h32m32lf6_sdrc_params);
- omap_init_irq();
- gpmc_init();
-#ifdef CONFIG_OMAP_32K_TIMER
- if (omap3_beagle_version == OMAP3BEAGLE_BOARD_AXBX)
- omap2_gp_clockevent_set_gptimer(12);
- else
- omap2_gp_clockevent_set_gptimer(1);
-#endif
-}
-
-static struct platform_device *omap3_beagle_devices[] __initdata = {
- &leds_gpio,
- &keys_gpio,
- &beagle_dss_device,
- &usb_mass_storage_device,
-};
-
-static void __init omap3beagle_flash_init(void)
-{
- u8 cs = 0;
- u8 nandcs = GPMC_CS_NUM + 1;
-
- /* find out the chip-select on which NAND exists */
- while (cs < GPMC_CS_NUM) {
- u32 ret = 0;
- ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
-
- if ((ret & 0xC00) == 0x800) {
- printk(KERN_INFO "Found NAND on CS%d\n", cs);
- if (nandcs > GPMC_CS_NUM)
- nandcs = cs;
- }
- cs++;
- }
-
- if (nandcs > GPMC_CS_NUM) {
- printk(KERN_INFO "NAND: Unable to find configuration "
- "in GPMC\n ");
- return;
- }
-
- if (nandcs < GPMC_CS_NUM) {
- printk(KERN_INFO "Registering NAND on CS%d\n", nandcs);
- board_nand_init(omap3beagle_nand_partitions,
- ARRAY_SIZE(omap3beagle_nand_partitions),
- nandcs, NAND_BUSWIDTH_16);
- }
-}
-
-static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
-
- .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
- .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
- .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
-
- .phy_reset = true,
- .reset_gpio_port[0] = -EINVAL,
- .reset_gpio_port[1] = 147,
- .reset_gpio_port[2] = -EINVAL
-};
-
-#ifdef CONFIG_OMAP_MUX
-static struct omap_board_mux board_mux[] __initdata = {
- OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP |
- OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW |
- OMAP_PIN_OFF_WAKEUPENABLE),
- { .reg_offset = OMAP_MUX_TERMINATOR },
-};
-#endif
-
-static struct omap_musb_board_data musb_board_data = {
- .interface_type = MUSB_INTERFACE_ULPI,
- .mode = MUSB_OTG,
- .power = 100,
-};
-
-static void __init omap3_beagle_init(void)
-{
- omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
- omap3_beagle_init_rev();
- omap3_beagle_i2c_init();
- platform_add_devices(omap3_beagle_devices,
- ARRAY_SIZE(omap3_beagle_devices));
- omap_serial_init();
-
- omap_mux_init_gpio(170, OMAP_PIN_INPUT);
- gpio_request(170, "DVI_nPD");
- /* REVISIT leave DVI powered down until it's needed ... */
- gpio_direction_output(170, true);
-
- usb_musb_init(&musb_board_data);
- usb_ehci_init(&ehci_pdata);
- omap3beagle_flash_init();
-
- /* Ensure SDRC pins are mux'd for self-refresh */
- omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
- omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
-
- beagle_display_init();
-#ifdef CONFIG_USB_ANDROID
- omap3beagle_android_gadget_init();
-#endif
- omap3_beagle_pm_init();
-}
-
-MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board")
- /* Maintainer: Syed Mohammed Khasim - http://beagleboard.org */
- .boot_params = 0x80000100,
- .map_io = omap3_map_io,
- .reserve = omap_reserve,
- .init_irq = omap3_beagle_init_irq,
- .init_machine = omap3_beagle_init,
- .timer = &omap_timer,
-MACHINE_END
diff --git a/kernel/arch/arm/mach-omap2/board-omap4panda.c b/kernel/arch/arm/mach-omap2/board-omap4panda.c
deleted file mode 100644
index 4f8c79d..0000000
--- a/kernel/arch/arm/mach-omap2/board-omap4panda.c
+++ /dev/null
@@ -1,1053 +0,0 @@
-/*
- * Board support file for OMAP4430 based PandaBoard.
- *
- * Copyright (C) 2010 Texas Instruments
- *
- * Author: David Anders <x0132446@ti.com>
- *
- * Based on mach-omap2/board-4430sdp.c
- *
- * Author: Santosh Shilimkar <santosh.shilimkar@ti.com>
- *
- * Based on mach-omap2/board-3430sdp.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/clk.h>
-#include <linux/input.h>
-#include <linux/io.h>
-#include <linux/leds.h>
-#include <linux/gpio.h>
-#include <linux/gpio_keys.h>
-#include <linux/omapfb.h>
-#include <linux/reboot.h>
-#include <linux/usb/otg.h>
-#include <linux/i2c/twl.h>
-#include <linux/regulator/machine.h>
-#include <linux/regulator/fixed.h>
-#include <linux/wl12xx.h>
-#include <linux/memblock.h>
-#include <linux/skbuff.h>
-#include <linux/ti_wilink_st.h>
-#include <linux/platform_data/ram_console.h>
-
-#include <mach/hardware.h>
-#include <mach/omap4-common.h>
-#include <mach/emif.h>
-#include <mach/lpddr2-elpida.h>
-#include <mach/dmm.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <video/omapdss.h>
-
-#include <plat/board.h>
-#include <plat/common.h>
-#include <plat/usb.h>
-#include <plat/mmc.h>
-#include <plat/remoteproc.h>
-#include <plat/vram.h>
-#include <video/omap-panel-generic-dpi.h>
-#include "timer-gp.h"
-
-#include "hsmmc.h"
-#include "control.h"
-#include "mux.h"
-#include "common-board-devices.h"
-#include "prm-regbits-44xx.h"
-#include "prm44xx.h"
-#include "pm.h"
-#include "resetreason.h"
-
-#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4
-#include <linux/input/synaptics_dsx.h>
-#define TM_SAMPLE1 (1) // 2D only
-#define TM_SAMPLE2 (2) // 2D + 0D x 2
-#define TM_SAMPLE3 (3) // 2D + 0D x 4
-#define SYNAPTICS_MODULE TM_SAMPLE1
-#endif
-
-#define PANDA_RAMCONSOLE_START (PLAT_PHYS_OFFSET + SZ_512M)
-#define PANDA_RAMCONSOLE_SIZE SZ_2M
-
-#define GPIO_HUB_POWER 1
-#define GPIO_HUB_NRESET 62
-#define GPIO_WIFI_PMENA 43
-#define GPIO_WIFI_IRQ 53
-#define HDMI_GPIO_CT_CP_HPD 60
-#define HDMI_GPIO_HPD 63 /* Hot plug pin for HDMI */
-#define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */
-#define TPS62361_GPIO 7 /* VCORE1 power control */
-#define PANDA_BT_GPIO 46
-
-
-#define PHYS_ADDR_SMC_SIZE (SZ_1M * 3)
-#define PHYS_ADDR_SMC_MEM (0x80000000 + SZ_1G - PHYS_ADDR_SMC_SIZE)
-#define OMAP_ION_HEAP_SECURE_INPUT_SIZE (SZ_1M * 90)
-#define PHYS_ADDR_DUCATI_SIZE (SZ_1M * 105)
-#define PHYS_ADDR_DUCATI_MEM (PHYS_ADDR_SMC_MEM - PHYS_ADDR_DUCATI_SIZE - \
- OMAP_ION_HEAP_SECURE_INPUT_SIZE)
-
-#define WILINK_UART_DEV_NAME "/dev/ttyO1"
-
-
-/* Synaptics changes for PandaBoard */
-#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4
-static int synaptics_gpio_setup(unsigned gpio, bool configure)
-{
- int retval = 0;
-
- if (configure) {
- retval = gpio_request(gpio, "rmi4_attn");
- if (retval) {
- pr_err("%s: Failed to get attn gpio %d (code: %d)",
- __func__, gpio, retval);
- return retval;
- }
- omap_mux_init_signal("gpmc_ad15.gpio_39", OMAP_PIN_INPUT_PULLUP);
-
- retval = gpio_direction_input(gpio);
- if (retval) {
- pr_err("%s: Failed to setup attn gpio %d (code: %d)",
- __func__, gpio, retval);
- gpio_free(gpio);
- }
- } else {
- pr_warn("%s: No way to deconfigure gpio %d",
- __func__, gpio);
- }
-
- return retval;
-}
-
- #if (SYNAPTICS_MODULE == TM_SAMPLE1)
-#define TM_SAMPLE1_ADDR 0x20
-#define TM_SAMPLE1_ATTN 130
-
-static unsigned char TM_SAMPLE1_f1a_button_codes[] = {};
-
-static struct synaptics_rmi4_capacitance_button_map TM_SAMPLE1_capacitance_button_map = {
- .nbuttons = ARRAY_SIZE(TM_SAMPLE1_f1a_button_codes),
- .map = TM_SAMPLE1_f1a_button_codes,
-};
-
-static struct synaptics_rmi4_platform_data rmi4_platformdata = {
- .irq_flags = IRQF_TRIGGER_FALLING,
- .irq_gpio = TM_SAMPLE1_ATTN,
- .gpio_config = synaptics_gpio_setup,
- .capacitance_button_map = &TM_SAMPLE1_capacitance_button_map,
-};
-
-static struct i2c_board_info bus4_i2c_devices[] = {
- {
- I2C_BOARD_INFO("synaptics_rmi4_i2c", TM_SAMPLE1_ADDR),
- .platform_data = &rmi4_platformdata,
- },
-};
-
-#elif (SYNAPTICS_MODULE == TM_SAMPLE2)
-#define TM_SAMPLE2_ADDR 0x20
-#define TM_SAMPLE2_ATTN 130
-
-static unsigned char TM_SAMPLE2_f1a_button_codes[] = {KEY_MENU, KEY_BACK};
-
-static struct synaptics_rmi4_capacitance_button_map TM_SAMPLE2_capacitance_button_map = {
- .nbuttons = ARRAY_SIZE(TM_SAMPLE2_f1a_button_codes),
- .map = TM_SAMPLE2_f1a_button_codes,
-};
-
-static struct synaptics_rmi4_platform_data rmi4_platformdata = {
- .irq_flags = IRQF_TRIGGER_FALLING,
- .irq_gpio = TM_SAMPLE2_ATTN,
- .gpio_config = synaptics_gpio_setup,
- .capacitance_button_map = &TM_SAMPLE2_capacitance_button_map,
-};
-
-static struct i2c_board_info bus4_i2c_devices[] = {
- {
- I2C_BOARD_INFO("synaptics_rmi4_i2c", TM_SAMPLE2_ADDR),
- .platform_data = &rmi4_platformdata,
- },
-};
-};
-
-#elif (SYNAPTICS_MODULE == TM_SAMPLE3)
-#define TM_SAMPLE3_ADDR 0x20
-#define TM_SAMPLE3_ATTN 130
-
-static unsigned char TM_SAMPLE3_f1a_button_codes[] = {KEY_MENU, KEY_HOME,KEY_BACK,KEY_SEARCH};
-
-static struct synaptics_rmi4_capacitance_button_map TM_SAMPLE3_capacitance_button_map = {
- .nbuttons = ARRAY_SIZE(TM_SAMPLE3_f1a_button_codes),
- .map = TM_SAMPLE3_f1a_button_codes,
-};
-
-static struct synaptics_rmi4_platform_data rmi4_platformdata = {
- .irq_flags = IRQF_TRIGGER_FALLING,
- .irq_gpio = TM_SAMPLE3_ATTN,
- .gpio_config = synaptics_gpio_setup,
- .capacitance_button_map = &TM_SAMPLE3_capacitance_button_map,
-};
-
-static struct i2c_board_info bus4_i2c_devices[] = {
- {
- I2C_BOARD_INFO("synaptics_rmi4_i2c", TM_SAMPLE3_ADDR),
- .platform_data = &rmi4_platformdata,
- },
-};
-#endif
-
-void __init i2c_device_setup(void)
-{
- pr_info(">>>>I2C device setup");
- if (ARRAY_SIZE(bus4_i2c_devices)) {
- i2c_register_board_info(4, bus4_i2c_devices,
- ARRAY_SIZE(bus4_i2c_devices));
- }
-}
-#endif
-/* End of Synaptics changes for PandaBoard */
-
-static struct gpio_led gpio_leds[] = {
- {
- .name = "pandaboard::status1",
- .default_trigger = "heartbeat",
- .gpio = 7,
- },
- {
- .name = "pandaboard::status2",
- .default_trigger = "mmc0",
- .gpio = 8,
- },
-};
-
-static struct gpio_led_platform_data gpio_led_info = {
- .leds = gpio_leds,
- .num_leds = ARRAY_SIZE(gpio_leds),
-};
-
-static struct platform_device leds_gpio = {
- .name = "leds-gpio",
- .id = -1,
- .dev = {
- .platform_data = &gpio_led_info,
- },
-};
-
-/* GPIO_KEY for the panda */
-static struct gpio_keys_button panda_gpio_keys_buttons[] = {
- [0] = {
- .code = KEY_HOME,
- .gpio = 113,
- .desc = "user_button",
- .active_low = 1,
- .debounce_interval = 5,
- },
-};
-
-static struct gpio_keys_platform_data panda_gpio_keys = {
- .buttons = panda_gpio_keys_buttons,
- .nbuttons = ARRAY_SIZE(panda_gpio_keys_buttons),
- .rep = 0,
-};
-
-static struct platform_device panda_gpio_keys_device = {
- .name = "gpio-keys",
- .id = -1,
- .dev = {
- .platform_data = &panda_gpio_keys,
- },
-};
-
-/* TODO: handle suspend/resume here.
- * Upon every suspend, make sure the wilink chip is
- * capable enough to wake-up the OMAP host.
- */
-static int plat_wlink_kim_suspend(struct platform_device *pdev, pm_message_t
- state)
-{
- return 0;
-}
-
-static int plat_wlink_kim_resume(struct platform_device *pdev)
-{
- return 0;
-}
-
-/* wl128x BT, FM, GPS connectivity chip */
-static struct ti_st_plat_data wilink_pdata = {
- .nshutdown_gpio = PANDA_BT_GPIO,
- .dev_name = WILINK_UART_DEV_NAME,
- .flow_cntrl = 1,
- .baud_rate = 3686400,
- .suspend = plat_wlink_kim_suspend,
- .resume = plat_wlink_kim_resume,
-};
-
-static struct platform_device btwilink_device = {
- .name = "btwilink",
- .id = -1,
-};
-
-/* wl127x BT, FM, GPS connectivity chip */
-static struct platform_device wl1271_device = {
- .name = "kim",
- .id = -1,
- .dev.platform_data = &wilink_pdata,
-};
-
-
-static struct platform_device *panda_devices[] __initdata = {
- &leds_gpio,
- &wl1271_device,
- &btwilink_device,
- &panda_gpio_keys_device,
-};
-
-static void __init omap4_panda_init_early(void)
-{
- omap2_init_common_infrastructure();
- omap2_init_common_devices(NULL, NULL);
-}
-
-static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
- .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
- .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED,
- .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
- .phy_reset = false,
- .reset_gpio_port[0] = -EINVAL,
- .reset_gpio_port[1] = -EINVAL,
- .reset_gpio_port[2] = -EINVAL
-};
-
-static struct gpio panda_ehci_gpios[] __initdata = {
- { GPIO_HUB_POWER, GPIOF_OUT_INIT_LOW, "hub_power" },
- { GPIO_HUB_NRESET, GPIOF_OUT_INIT_LOW, "hub_nreset" },
-};
-
-static void __init omap4_ehci_init(void)
-{
- int ret;
- struct clk *phy_ref_clk;
-
- /* FREF_CLK3 provides the 19.2 MHz reference clock to the PHY */
- phy_ref_clk = clk_get(NULL, "auxclk3_ck");
- if (IS_ERR(phy_ref_clk)) {
- pr_err("Cannot request auxclk3\n");
- return;
- }
- clk_set_rate(phy_ref_clk, 19200000);
- clk_enable(phy_ref_clk);
-
- /* disable the power to the usb hub prior to init and reset phy+hub */
- ret = gpio_request_array(panda_ehci_gpios,
- ARRAY_SIZE(panda_ehci_gpios));
- if (ret) {
- pr_err("Unable to initialize EHCI power/reset\n");
- return;
- }
-
- gpio_export(GPIO_HUB_POWER, 0);
- gpio_export(GPIO_HUB_NRESET, 0);
- gpio_set_value(GPIO_HUB_NRESET, 1);
-
- usbhs_init(&usbhs_bdata);
-
- /* enable power to hub */
- gpio_set_value(GPIO_HUB_POWER, 1);
-}
-
-static struct omap_musb_board_data musb_board_data = {
- .interface_type = MUSB_INTERFACE_UTMI,
-#ifdef CONFIG_USB_GADGET_MUSB_HDRC
- .mode = MUSB_PERIPHERAL,
-#else
- .mode = MUSB_OTG,
-#endif
- .power = 100,
-};
-
-static struct twl4030_usb_data omap4_usbphy_data = {
- .phy_init = omap4430_phy_init,
- .phy_exit = omap4430_phy_exit,
- .phy_power = omap4430_phy_power,
- .phy_set_clock = omap4430_phy_set_clk,
- .phy_suspend = omap4430_phy_suspend,
-};
-
-static struct omap2_hsmmc_info mmc[] = {
- {
- .mmc = 1,
- .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
- .gpio_wp = -EINVAL,
- .gpio_cd = -EINVAL,
- },
- {
- .name = "wl1271",
- .mmc = 5,
- .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD,
- .gpio_wp = -EINVAL,
- .gpio_cd = -EINVAL,
- .ocr_mask = MMC_VDD_165_195,
- .nonremovable = true,
- },
- {} /* Terminator */
-};
-
-static struct regulator_consumer_supply omap4_panda_vmmc_supply[] = {
- {
- .supply = "vmmc",
- .dev_name = "omap_hsmmc.0",
- },
-};
-
-static struct regulator_consumer_supply omap4_panda_vmmc5_supply = {
- .supply = "vmmc",
- .dev_name = "omap_hsmmc.4",
-};
-
-static struct regulator_init_data panda_vmmc5 = {
- .constraints = {
- .valid_ops_mask = REGULATOR_CHANGE_STATUS,
- },
- .num_consumer_supplies = 1,
- .consumer_supplies = &omap4_panda_vmmc5_supply,
-};
-
-static struct fixed_voltage_config panda_vwlan = {
- .supply_name = "vwl1271",
- .microvolts = 1800000, /* 1.8V */
- .gpio = GPIO_WIFI_PMENA,
- .startup_delay = 70000, /* 70msec */
- .enable_high = 1,
- .enabled_at_boot = 0,
- .init_data = &panda_vmmc5,
-};
-
-static struct platform_device omap_vwlan_device = {
- .name = "reg-fixed-voltage",
- .id = 1,
- .dev = {
- .platform_data = &panda_vwlan,
- },
-};
-
-struct wl12xx_platform_data omap_panda_wlan_data __initdata = {
- .irq = OMAP_GPIO_IRQ(GPIO_WIFI_IRQ),
- /* PANDA ref clock is 38.4 MHz */
- .board_ref_clock = 2,
-};
-
-static int omap4_twl6030_hsmmc_late_init(struct device *dev)
-{
- int ret = 0;
- struct platform_device *pdev = container_of(dev,
- struct platform_device, dev);
- struct omap_mmc_platform_data *pdata = dev->platform_data;
-
- if (!pdata) {
- dev_err(dev, "%s: NULL platform data\n", __func__);
- return -EINVAL;
- }
- /* Setting MMC1 Card detect Irq */
- if (pdev->id == 0) {
- ret = twl6030_mmc_card_detect_config();
- if (ret)
- dev_err(dev, "%s: Error card detect config(%d)\n",
- __func__, ret);
- else
- pdata->slots[0].card_detect = twl6030_mmc_card_detect;
- }
- return ret;
-}
-
-static __init void omap4_twl6030_hsmmc_set_late_init(struct device *dev)
-{
- struct omap_mmc_platform_data *pdata;
-
- /* dev can be null if CONFIG_MMC_OMAP_HS is not set */
- if (!dev) {
- pr_err("Failed omap4_twl6030_hsmmc_set_late_init\n");
- return;
- }
- pdata = dev->platform_data;
-
- pdata->init = omap4_twl6030_hsmmc_late_init;
-}
-
-static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
-{
- struct omap2_hsmmc_info *c;
-
- omap2_hsmmc_init(controllers);
- for (c = controllers; c->mmc; c++)
- omap4_twl6030_hsmmc_set_late_init(c->dev);
-
- return 0;
-}
-
-static struct regulator_init_data omap4_panda_vaux2 = {
- .constraints = {
- .min_uV = 1200000,
- .max_uV = 2800000,
- .apply_uV = true,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
- | REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
-};
-
-static struct regulator_init_data omap4_panda_vaux3 = {
- .constraints = {
- .min_uV = 1000000,
- .max_uV = 3000000,
- .apply_uV = true,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
- | REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
-};
-
-/* VMMC1 for MMC1 card */
-static struct regulator_init_data omap4_panda_vmmc = {
- .constraints = {
- .min_uV = 1200000,
- .max_uV = 3000000,
- .apply_uV = true,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
- | REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
- .num_consumer_supplies = 1,
- .consumer_supplies = omap4_panda_vmmc_supply,
-};
-
-static struct regulator_init_data omap4_panda_vpp = {
- .constraints = {
- .min_uV = 1800000,
- .max_uV = 2500000,
- .apply_uV = true,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
- | REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
-};
-
-static struct regulator_init_data omap4_panda_vana = {
- .constraints = {
- .min_uV = 2100000,
- .max_uV = 2100000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
-};
-
-static struct regulator_init_data omap4_panda_vcxio = {
- .constraints = {
- .min_uV = 1800000,
- .max_uV = 1800000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
-};
-
-static struct regulator_consumer_supply panda_vdac_supply[] = {
- {
- .supply = "hdmi_vref",
- },
-};
-
-static struct regulator_init_data omap4_panda_vdac = {
- .constraints = {
- .min_uV = 1800000,
- .max_uV = 1800000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
- .num_consumer_supplies = ARRAY_SIZE(panda_vdac_supply),
- .consumer_supplies = panda_vdac_supply,
-};
-
-static struct regulator_init_data omap4_panda_vusb = {
- .constraints = {
- .min_uV = 3300000,
- .max_uV = 3300000,
- .apply_uV = true,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
-};
-
-static struct regulator_init_data omap4_panda_clk32kg = {
- .constraints = {
- .valid_ops_mask = REGULATOR_CHANGE_STATUS,
- .always_on = true,
- },
-};
-
-static void omap4_audio_conf(void)
-{
- /* twl6040 naudint */
- omap_mux_init_signal("sys_nirq2.sys_nirq2", \
- OMAP_PIN_INPUT_PULLUP);
-}
-
-static struct twl4030_codec_audio_data twl6040_audio = {
- /* single-step ramp for headset and handsfree */
- .hs_left_step = 0x0f,
- .hs_right_step = 0x0f,
- .hf_left_step = 0x1d,
- .hf_right_step = 0x1d,
- .hs_switch_dev = 0x1,
- .hs_forced_hs_state = 0x1
-};
-
-static struct twl4030_codec_data twl6040_codec = {
- .audio = &twl6040_audio,
- .audpwron_gpio = 127,
- .naudint_irq = OMAP44XX_IRQ_SYS_2N,
- .irq_base = TWL6040_CODEC_IRQ_BASE,
-};
-
-static struct twl4030_platform_data omap4_panda_twldata = {
- .irq_base = TWL6030_IRQ_BASE,
- .irq_end = TWL6030_IRQ_END,
-
- /* Regulators */
- .vmmc = &omap4_panda_vmmc,
- .vpp = &omap4_panda_vpp,
- .vana = &omap4_panda_vana,
- .vcxio = &omap4_panda_vcxio,
- .vdac = &omap4_panda_vdac,
- .vusb = &omap4_panda_vusb,
- .vaux2 = &omap4_panda_vaux2,
- .vaux3 = &omap4_panda_vaux3,
- .clk32kg = &omap4_panda_clk32kg,
- .usb = &omap4_usbphy_data,
-
- /* children */
- .codec = &twl6040_codec,
-};
-
-/*
- * Display monitor features are burnt in their EEPROM as EDID data. The EEPROM
- * is connected as I2C slave device, and can be accessed at address 0x50
- */
-static struct i2c_board_info __initdata panda_i2c_eeprom[] = {
- {
- I2C_BOARD_INFO("eeprom", 0x50),
- },
-};
-
-static int __init omap4_panda_i2c_init(void)
-{
- omap4_pmic_init("twl6030", &omap4_panda_twldata);
- omap_register_i2c_bus(2, 400, NULL, 0);
- /*
- * Bus 3 is attached to the DVI port where devices like the pico DLP
- * projector don't work reliably with 400kHz
- */
- omap_register_i2c_bus(3, 100, panda_i2c_eeprom,
- ARRAY_SIZE(panda_i2c_eeprom));
- if(ARRAY_SIZE(bus4_i2c_devices))
- omap_register_i2c_bus(4, 400, bus4_i2c_devices, ARRAY_SIZE(bus4_i2c_devices));
- else
- omap_register_i2c_bus(4, 400, NULL, 0);
- return 0;
-}
-
-#ifdef CONFIG_OMAP_MUX
-static struct omap_board_mux board_mux[] __initdata = {
- /* WLAN IRQ - GPIO 53 */
- OMAP4_MUX(GPMC_NCS3, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
- /* WLAN POWER ENABLE - GPIO 43 */
- OMAP4_MUX(GPMC_A19, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT),
- /* WLAN SDIO: MMC5 CMD */
- OMAP4_MUX(SDMMC5_CMD, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
- /* WLAN SDIO: MMC5 CLK */
- OMAP4_MUX(SDMMC5_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
- /* WLAN SDIO: MMC5 DAT[0-3] */
- OMAP4_MUX(SDMMC5_DAT0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
- OMAP4_MUX(SDMMC5_DAT1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
- OMAP4_MUX(SDMMC5_DAT2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
- OMAP4_MUX(SDMMC5_DAT3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
- /* gpio 0 - TFP410 PD */
- OMAP4_MUX(KPD_COL1, OMAP_PIN_OUTPUT | OMAP_MUX_MODE3),
- /* dispc2_data23 */
- OMAP4_MUX(USBB2_ULPITLL_STP, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data22 */
- OMAP4_MUX(USBB2_ULPITLL_DIR, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data21 */
- OMAP4_MUX(USBB2_ULPITLL_NXT, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data20 */
- OMAP4_MUX(USBB2_ULPITLL_DAT0, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data19 */
- OMAP4_MUX(USBB2_ULPITLL_DAT1, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data18 */
- OMAP4_MUX(USBB2_ULPITLL_DAT2, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data15 */
- OMAP4_MUX(USBB2_ULPITLL_DAT3, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data14 */
- OMAP4_MUX(USBB2_ULPITLL_DAT4, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data13 */
- OMAP4_MUX(USBB2_ULPITLL_DAT5, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data12 */
- OMAP4_MUX(USBB2_ULPITLL_DAT6, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data11 */
- OMAP4_MUX(USBB2_ULPITLL_DAT7, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data10 */
- OMAP4_MUX(DPM_EMU3, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data9 */
- OMAP4_MUX(DPM_EMU4, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data16 */
- OMAP4_MUX(DPM_EMU5, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data17 */
- OMAP4_MUX(DPM_EMU6, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_hsync */
- OMAP4_MUX(DPM_EMU7, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_pclk */
- OMAP4_MUX(DPM_EMU8, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_vsync */
- OMAP4_MUX(DPM_EMU9, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_de */
- OMAP4_MUX(DPM_EMU10, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data8 */
- OMAP4_MUX(DPM_EMU11, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data7 */
- OMAP4_MUX(DPM_EMU12, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data6 */
- OMAP4_MUX(DPM_EMU13, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data5 */
- OMAP4_MUX(DPM_EMU14, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data4 */
- OMAP4_MUX(DPM_EMU15, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data3 */
- OMAP4_MUX(DPM_EMU16, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data2 */
- OMAP4_MUX(DPM_EMU17, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data1 */
- OMAP4_MUX(DPM_EMU18, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data0 */
- OMAP4_MUX(DPM_EMU19, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- { .reg_offset = OMAP_MUX_TERMINATOR },
-};
-
-static inline void __init board_serial_init(void)
-{
- omap_serial_init();
-}
-#else
-#define board_mux NULL
-
-static inline void __init board_serial_init(void)
-{
- omap_serial_init();
-}
-#endif
-
-/* Display DVI */
-#define PANDA_DVI_TFP410_POWER_DOWN_GPIO 0
-
-static int omap4_panda_enable_dvi(struct omap_dss_device *dssdev)
-{
- gpio_set_value(dssdev->reset_gpio, 1);
- return 0;
-}
-
-static void omap4_panda_disable_dvi(struct omap_dss_device *dssdev)
-{
- gpio_set_value(dssdev->reset_gpio, 0);
-}
-
-/* Using generic display panel */
-static struct panel_generic_dpi_data omap4_dvi_panel = {
- .name = "generic_720p",
- .platform_enable = omap4_panda_enable_dvi,
- .platform_disable = omap4_panda_disable_dvi,
-};
-
-struct omap_dss_device omap4_panda_dvi_device = {
- .type = OMAP_DISPLAY_TYPE_DPI,
- .name = "dvi",
- .driver_name = "generic_dpi_panel",
- .data = &omap4_dvi_panel,
- .phy.dpi.data_lines = 24,
- .reset_gpio = PANDA_DVI_TFP410_POWER_DOWN_GPIO,
- .channel = OMAP_DSS_CHANNEL_LCD2,
-};
-
-int __init omap4_panda_dvi_init(void)
-{
- int r;
-
- /* Requesting TFP410 DVI GPIO and disabling it, at bootup */
- r = gpio_request_one(omap4_panda_dvi_device.reset_gpio,
- GPIOF_OUT_INIT_LOW, "DVI PD");
- if (r)
- pr_err("Failed to get DVI powerdown GPIO\n");
-
- return r;
-}
-
-static struct gpio panda_hdmi_gpios[] = {
- { HDMI_GPIO_CT_CP_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_hpd" },
- { HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" },
-};
-
-static void omap4_panda_hdmi_mux_init(void)
-{
- u32 r;
- int status;
- /* PAD0_HDMI_HPD_PAD1_HDMI_CEC */
- omap_mux_init_signal("hdmi_hpd.hdmi_hpd",
- OMAP_PIN_INPUT_PULLUP);
- omap_mux_init_signal("gpmc_wait2.gpio_100",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hdmi_cec.hdmi_cec",
- OMAP_PIN_INPUT_PULLUP);
- /* PAD0_HDMI_DDC_SCL_PAD1_HDMI_DDC_SDA */
- omap_mux_init_signal("hdmi_ddc_scl.hdmi_ddc_scl",
- OMAP_PIN_INPUT_PULLUP);
- omap_mux_init_signal("hdmi_ddc_sda.hdmi_ddc_sda",
- OMAP_PIN_INPUT_PULLUP);
-
- /* strong pullup on DDC lines using unpublished register */
- r = ((1 << 24) | (1 << 28)) ;
- omap4_ctrl_pad_writel(r, OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_I2C_1);
-
- gpio_request(HDMI_GPIO_HPD, NULL);
- omap_mux_init_gpio(HDMI_GPIO_HPD, OMAP_PIN_INPUT | OMAP_PULL_ENA);
- gpio_direction_input(HDMI_GPIO_HPD);
-
- status = gpio_request_array(panda_hdmi_gpios,
- ARRAY_SIZE(panda_hdmi_gpios));
- if (status)
- pr_err("%s: Cannot request HDMI GPIOs %x \n", __func__, status);
-}
-
-static struct omap_dss_device omap4_panda_hdmi_device = {
- .name = "hdmi",
- .driver_name = "hdmi_panel",
- .type = OMAP_DISPLAY_TYPE_HDMI,
- .clocks = {
- .dispc = {
- .dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK,
- },
- .hdmi = {
- .regn = 15,
- .regm2 = 1,
- },
- },
- .hpd_gpio = HDMI_GPIO_HPD,
- .channel = OMAP_DSS_CHANNEL_DIGIT,
-};
-
-static struct omap_dss_device *omap4_panda_dss_devices[] = {
- &omap4_panda_dvi_device,
- &omap4_panda_hdmi_device,
-};
-
-static struct omap_dss_board_info omap4_panda_dss_data = {
- .num_devices = ARRAY_SIZE(omap4_panda_dss_devices),
- .devices = omap4_panda_dss_devices,
- .default_device = &omap4_panda_dvi_device,
-};
-
-/*
- * LPDDR2 Configeration Data:
- * The memory organisation is as below :
- * EMIF1 - CS0 - 2 Gb
- * CS1 - 2 Gb
- * EMIF2 - CS0 - 2 Gb
- * CS1 - 2 Gb
- * --------------------
- * TOTAL - 8 Gb
- *
- * Same devices installed on EMIF1 and EMIF2
- */
-static __initdata struct emif_device_details emif_devices = {
- .cs0_device = &lpddr2_elpida_2G_S4_dev,
- .cs1_device = &lpddr2_elpida_2G_S4_dev
-};
-
-void omap4_panda_display_init(void)
-{
- int r;
-
- r = omap4_panda_dvi_init();
- if (r)
- pr_err("error initializing panda DVI\n");
-
- omap4_panda_hdmi_mux_init();
- omap_display_init(&omap4_panda_dss_data);
-}
-
-static int panda_notifier_call(struct notifier_block *this,
- unsigned long code, void *cmd)
-{
- void __iomem *sar_base;
- u32 v = OMAP4430_RST_GLOBAL_COLD_SW_MASK;
-
- sar_base = omap4_get_sar_ram_base();
-
- if (!sar_base)
- return notifier_from_errno(-ENOMEM);
-
- if ((code == SYS_RESTART) && (cmd != NULL)) {
- /* cmd != null; case: warm boot */
- if (!strcmp(cmd, "bootloader")) {
- /* Save reboot mode in scratch memory */
- strcpy(sar_base + 0xA0C, cmd);
- v |= OMAP4430_RST_GLOBAL_WARM_SW_MASK;
- } else if (!strcmp(cmd, "recovery")) {
- /* Save reboot mode in scratch memory */
- strcpy(sar_base + 0xA0C, cmd);
- v |= OMAP4430_RST_GLOBAL_WARM_SW_MASK;
- } else {
- v |= OMAP4430_RST_GLOBAL_COLD_SW_MASK;
- }
- }
-
- omap4_prm_write_inst_reg(0xfff, OMAP4430_PRM_DEVICE_INST,
- OMAP4_RM_RSTST);
- omap4_prm_write_inst_reg(v, OMAP4430_PRM_DEVICE_INST, OMAP4_RM_RSTCTRL);
- v = omap4_prm_read_inst_reg(WKUP_MOD, OMAP4_RM_RSTCTRL);
-
- return NOTIFY_DONE;
-}
-
-static struct notifier_block panda_reboot_notifier = {
- .notifier_call = panda_notifier_call,
-};
-
-#define PANDA_FB_RAM_SIZE SZ_16M /* 1920?1080*4 * 2 */
-static struct omapfb_platform_data panda_fb_pdata = {
- .mem_desc = {
- .region_cnt = 1,
- .region = {
- [0] = {
- .size = PANDA_FB_RAM_SIZE,
- },
- },
- },
-};
-
-static struct resource ramconsole_resources[] = {
- {
- .flags = IORESOURCE_MEM,
- .start = PANDA_RAMCONSOLE_START,
- .end = PANDA_RAMCONSOLE_START + PANDA_RAMCONSOLE_SIZE - 1,
- },
-};
-
-static struct ram_console_platform_data ramconsole_pdata;
-
-static struct platform_device ramconsole_device = {
- .name = "ram_console",
- .id = -1,
- .num_resources = ARRAY_SIZE(ramconsole_resources),
- .resource = ramconsole_resources,
- .dev = {
- .platform_data = &ramconsole_pdata,
- },
-};
-
-extern void __init omap4_panda_android_init(void);
-
-static void __init omap4_panda_init(void)
-{
- int package = OMAP_PACKAGE_CBS;
- int status;
-
- omap_emif_setup_device_details(&emif_devices, &emif_devices);
-
- if (omap_rev() == OMAP4430_REV_ES1_0)
- package = OMAP_PACKAGE_CBL;
- omap4_mux_init(board_mux, NULL, package);
-
- if (wl12xx_set_platform_data(&omap_panda_wlan_data))
- pr_err("error setting wl12xx data\n");
-
- register_reboot_notifier(&panda_reboot_notifier);
- ramconsole_pdata.bootinfo = omap4_get_resetreason();
- platform_device_register(&ramconsole_device);
- omap4_panda_i2c_init();
- omap4_audio_conf();
-
- if (cpu_is_omap4430())
- panda_gpio_keys_buttons[0].gpio = 121;
-
- platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices));
- platform_device_register(&omap_vwlan_device);
- board_serial_init();
- omap4_twl6030_hsmmc_init(mmc);
- omap4_ehci_init();
- usb_musb_init(&musb_board_data);
-
- omap_dmm_init();
- omap_vram_set_sdram_vram(PANDA_FB_RAM_SIZE, 0);
- omapfb_set_platform_data(&panda_fb_pdata);
- omap4_panda_display_init();
-
- if (cpu_is_omap446x()) {
- /* Vsel0 = gpio, vsel1 = gnd */
- status = omap_tps6236x_board_setup(true, TPS62361_GPIO, -1,
- OMAP_PIN_OFF_OUTPUT_HIGH, -1);
- if (status)
- pr_err("TPS62361 initialization failed: %d\n", status);
- }
- omap_enable_smartreflex_on_init();
-}
-
-static void __init omap4_panda_map_io(void)
-{
- omap2_set_globals_443x();
- omap44xx_map_common_io();
-}
-
-static void __init omap4_panda_reserve(void)
-{
- /* do the static reservations first */
- memblock_remove(PANDA_RAMCONSOLE_START, PANDA_RAMCONSOLE_SIZE);
- memblock_remove(PHYS_ADDR_SMC_MEM, PHYS_ADDR_SMC_SIZE);
- memblock_remove(PHYS_ADDR_DUCATI_MEM, PHYS_ADDR_DUCATI_SIZE);
- /* ipu needs to recognize secure input buffer area as well */
- omap_ipu_set_static_mempool(PHYS_ADDR_DUCATI_MEM, PHYS_ADDR_DUCATI_SIZE +
- OMAP_ION_HEAP_SECURE_INPUT_SIZE);
-
- omap_reserve();
-}
-
-MACHINE_START(OMAP4_PANDA, "OMAP4 Panda board")
- /* Maintainer: David Anders - Texas Instruments Inc */
- .boot_params = 0x80000100,
- .reserve = omap4_panda_reserve,
- .map_io = omap4_panda_map_io,
- .init_early = omap4_panda_init_early,
- .init_irq = gic_init_irq,
- .init_machine = omap4_panda_init,
- .timer = &omap_timer,
-MACHINE_END
diff --git a/kernel/drivers/input/touchscreen/Kconfig b/kernel/drivers/input/touchscreen/Kconfig
deleted file mode 100644
index 18655c0..0000000
--- a/kernel/drivers/input/touchscreen/Kconfig
+++ /dev/null
@@ -1,721 +0,0 @@
-#
-# Touchscreen driver configuration
-#
-menuconfig INPUT_TOUCHSCREEN
- bool "Touchscreens"
- help
- Say Y here, and a list of supported touchscreens will be displayed.
- This option doesn't affect the kernel.
-
- If unsure, say Y.
-
-if INPUT_TOUCHSCREEN
-
-config TOUCHSCREEN_88PM860X
- tristate "Marvell 88PM860x touchscreen"
- depends on MFD_88PM860X
- help
- Say Y here if you have a 88PM860x PMIC and want to enable
- support for the built-in touchscreen.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called 88pm860x-ts.
-
-config TOUCHSCREEN_ADS7846
- tristate "ADS7846/TSC2046/AD7873 and AD(S)7843 based touchscreens"
- depends on SPI_MASTER
- depends on HWMON = n || HWMON
- help
- Say Y here if you have a touchscreen interface using the
- ADS7846/TSC2046/AD7873 or ADS7843/AD7843 controller,
- and your board-specific setup code includes that in its
- table of SPI devices.
-
- If HWMON is selected, and the driver is told the reference voltage
- on your board, you will also get hwmon interfaces for the voltage
- (and on ads7846/tsc2046/ad7873, temperature) sensors of this chip.
-
- If unsure, say N (but it's safe to say "Y").
-
- To compile this driver as a module, choose M here: the
- module will be called ads7846.
-
-config TOUCHSCREEN_AD7877
- tristate "AD7877 based touchscreens"
- depends on SPI_MASTER
- help
- Say Y here if you have a touchscreen interface using the
- AD7877 controller, and your board-specific initialization
- code includes that in its table of SPI devices.
-
- If unsure, say N (but it's safe to say "Y").
-
- To compile this driver as a module, choose M here: the
- module will be called ad7877.
-
-config TOUCHSCREEN_AD7879
- tristate "Analog Devices AD7879-1/AD7889-1 touchscreen interface"
- help
- Say Y here if you want to support a touchscreen interface using
- the AD7879-1/AD7889-1 controller.
-
- You should select a bus connection too.
-
- To compile this driver as a module, choose M here: the
- module will be called ad7879.
-
-config TOUCHSCREEN_AD7879_I2C
- tristate "support I2C bus connection"
- depends on TOUCHSCREEN_AD7879 && I2C
- help
- Say Y here if you have AD7879-1/AD7889-1 hooked to an I2C bus.
-
- To compile this driver as a module, choose M here: the
- module will be called ad7879-i2c.
-
-config TOUCHSCREEN_AD7879_SPI
- tristate "support SPI bus connection"
- depends on TOUCHSCREEN_AD7879 && SPI_MASTER
- help
- Say Y here if you have AD7879-1/AD7889-1 hooked to a SPI bus.
-
- If unsure, say N (but it's safe to say "Y").
-
- To compile this driver as a module, choose M here: the
- module will be called ad7879-spi.
-
-config TOUCHSCREEN_BITSY
- tristate "Compaq iPAQ H3600 (Bitsy) touchscreen"
- depends on SA1100_BITSY
- select SERIO
- help
- Say Y here if you have the h3600 (Bitsy) touchscreen.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called h3600_ts_input.
-
-config TOUCHSCREEN_BU21013
- tristate "BU21013 based touch panel controllers"
- depends on I2C
- help
- Say Y here if you have a bu21013 touchscreen connected to
- your system.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called bu21013_ts.
-
-config TOUCHSCREEN_CY8CTMG110
- tristate "cy8ctmg110 touchscreen"
- depends on I2C
- depends on GPIOLIB
-
- help
- Say Y here if you have a cy8ctmg110 capacitive touchscreen on
- an AAVA device.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called cy8ctmg110_ts.
-
-config TOUCHSCREEN_DA9034
- tristate "Touchscreen support for Dialog Semiconductor DA9034"
- depends on PMIC_DA903X
- default y
- help
- Say Y here to enable the support for the touchscreen found
- on Dialog Semiconductor DA9034 PMIC.
-
-config TOUCHSCREEN_DYNAPRO
- tristate "Dynapro serial touchscreen"
- select SERIO
- help
- Say Y here if you have a Dynapro serial touchscreen connected to
- your system.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called dynapro.
-
-config TOUCHSCREEN_HAMPSHIRE
- tristate "Hampshire serial touchscreen"
- select SERIO
- help
- Say Y here if you have a Hampshire serial touchscreen connected to
- your system.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called hampshire.
-
-config TOUCHSCREEN_EETI
- tristate "EETI touchscreen panel support"
- depends on I2C
- help
- Say Y here to enable support for I2C connected EETI touch panels.
-
- To compile this driver as a module, choose M here: the
- module will be called eeti_ts.
-
-config TOUCHSCREEN_FUJITSU
- tristate "Fujitsu serial touchscreen"
- select SERIO
- help
- Say Y here if you have the Fujitsu touchscreen (such as one
- installed in Lifebook P series laptop) connected to your
- system.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called fujitsu-ts.
-
-config TOUCHSCREEN_S3C2410
- tristate "Samsung S3C2410/generic touchscreen input driver"
- depends on ARCH_S3C2410 || SAMSUNG_DEV_TS
- select S3C_ADC
- help
- Say Y here if you have the s3c2410 touchscreen.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called s3c2410_ts.
-
-config TOUCHSCREEN_GUNZE
- tristate "Gunze AHL-51S touchscreen"
- select SERIO
- help
- Say Y here if you have the Gunze AHL-51 touchscreen connected to
- your system.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called gunze.
-
-config TOUCHSCREEN_ELO
- tristate "Elo serial touchscreens"
- select SERIO
- help
- Say Y here if you have an Elo serial touchscreen connected to
- your system.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called elo.
-
-config TOUCHSCREEN_WACOM_W8001
- tristate "Wacom W8001 penabled serial touchscreen"
- select SERIO
- help
- Say Y here if you have an Wacom W8001 penabled serial touchscreen
- connected to your system.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called wacom_w8001.
-
-config TOUCHSCREEN_LPC32XX
- tristate "LPC32XX touchscreen controller"
- depends on ARCH_LPC32XX
- help
- Say Y here if you have a LPC32XX device and want
- to support the built-in touchscreen.
-
- To compile this driver as a module, choose M here: the
- module will be called lpc32xx_ts.
-
-config TOUCHSCREEN_MCS5000
- tristate "MELFAS MCS-5000 touchscreen"
- depends on I2C
- help
- Say Y here if you have the MELFAS MCS-5000 touchscreen controller
- chip in your system.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called mcs5000_ts.
-
-config TOUCHSCREEN_MTOUCH
- tristate "MicroTouch serial touchscreens"
- select SERIO
- help
- Say Y here if you have a MicroTouch (3M) serial touchscreen connected to
- your system.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called mtouch.
-
-config TOUCHSCREEN_INEXIO
- tristate "iNexio serial touchscreens"
- select SERIO
- help
- Say Y here if you have an iNexio serial touchscreen connected to
- your system.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called inexio.
-
-config TOUCHSCREEN_INTEL_MID
- tristate "Intel MID platform resistive touchscreen"
- depends on INTEL_SCU_IPC
- help
- Say Y here if you have a Intel MID based touchscreen in
- your system.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called intel_mid_touch.
-
-config TOUCHSCREEN_MK712
- tristate "ICS MicroClock MK712 touchscreen"
- help
- Say Y here if you have the ICS MicroClock MK712 touchscreen
- controller chip in your system.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called mk712.
-
-config TOUCHSCREEN_HP600
- tristate "HP Jornada 6xx touchscreen"
- depends on SH_HP6XX && SH_ADC
- help
- Say Y here if you have a HP Jornada 620/660/680/690 and want to
- support the built-in touchscreen.
-
- To compile this driver as a module, choose M here: the
- module will be called hp680_ts_input.
-
-config TOUCHSCREEN_HP7XX
- tristate "HP Jornada 7xx touchscreen"
- depends on SA1100_JORNADA720_SSP
- help
- Say Y here if you have a HP Jornada 710/720/728 and want
- to support the built-in touchscreen.
-
- To compile this driver as a module, choose M here: the
- module will be called jornada720_ts.
-
-config TOUCHSCREEN_HTCPEN
- tristate "HTC Shift X9500 touchscreen"
- depends on ISA
- help
- Say Y here if you have an HTC Shift UMPC also known as HTC X9500
- Clio / Shangrila and want to support the built-in touchscreen.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called htcpen.
-
-config TOUCHSCREEN_PENMOUNT
- tristate "Penmount serial touchscreen"
- select SERIO
- help
- Say Y here if you have a Penmount serial touchscreen connected to
- your system.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called penmount.
-
-config TOUCHSCREEN_QT602240
- tristate "QT602240 I2C Touchscreen"
- depends on I2C
- help
- Say Y here if you have the AT42QT602240/ATMXT224 I2C touchscreen
- connected to your system.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called qt602240_ts.
-
-config TOUCHSCREEN_MIGOR
- tristate "Renesas MIGO-R touchscreen"
- depends on SH_MIGOR && I2C
- help
- Say Y here to enable MIGO-R touchscreen support.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called migor_ts.
-
-config TOUCHSCREEN_TNETV107X
- tristate "TI TNETV107X touchscreen support"
- depends on ARCH_DAVINCI_TNETV107X
- help
- Say Y here if you want to use the TNETV107X touchscreen.
-
- To compile this driver as a module, choose M here: the
- module will be called tnetv107x-ts.
-
-config TOUCHSCREEN_SYNAPTICS_I2C_RMI4
- tristate "Synaptics DSX I2C touchscreen"
- depends on I2C
- help
- Say Y here if you have a Synaptics DSX I2C touchscreen
- connected to your system.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called synaptics_i2c_rmi4.
-
-config TOUCHSCREEN_SYNAPTICS_DSX_RMI4_DEV
- tristate "Synaptics I2C touchscreen rmi device"
- depends on TOUCHSCREEN_SYNAPTICS_I2C_RMI4
- help
- This enables support for character device channel for Synaptics RMI
- touchscreens.
-
-config TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE
- tristate "Synaptics I2C touchscreen firmware update"
- depends on TOUCHSCREEN_SYNAPTICS_I2C_RMI4
- help
- This enables support for firmware update for Synaptics RMI
- touchscreens.
-
-config TOUCHSCREEN_TOUCHRIGHT
- tristate "Touchright serial touchscreen"
- select SERIO
- help
- Say Y here if you have a Touchright serial touchscreen connected to
- your system.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called touchright.
-
-config TOUCHSCREEN_TOUCHWIN
- tristate "Touchwin serial touchscreen"
- select SERIO
- help
- Say Y here if you have a Touchwin serial touchscreen connected to
- your system.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called touchwin.
-
-config TOUCHSCREEN_ATMEL_TSADCC
- tristate "Atmel Touchscreen Interface"
- depends on ARCH_AT91SAM9RL || ARCH_AT91SAM9G45
- help
- Say Y here if you have a 4-wire touchscreen connected to the
- ADC Controller on your Atmel SoC (such as the AT91SAM9RL).
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called atmel_tsadcc.
-
-config TOUCHSCREEN_UCB1400
- tristate "Philips UCB1400 touchscreen"
- depends on AC97_BUS
- depends on UCB1400_CORE
- help
- This enables support for the Philips UCB1400 touchscreen interface.
- The UCB1400 is an AC97 audio codec. The touchscreen interface
- will be initialized only after the ALSA subsystem has been
- brought up and the UCB1400 detected. You therefore have to
- configure ALSA support as well (either built-in or modular,
- independently of whether this driver is itself built-in or
- modular) for this driver to work.
-
- To compile this driver as a module, choose M here: the
- module will be called ucb1400_ts.
-
-config TOUCHSCREEN_WM97XX
- tristate "Support for WM97xx AC97 touchscreen controllers"
- depends on AC97_BUS
- help
- Say Y here if you have a Wolfson Microelectronics WM97xx
- touchscreen connected to your system. Note that this option
- only enables core driver, you will also need to select
- support for appropriate chip below.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called wm97xx-ts.
-
-config TOUCHSCREEN_WM9705
- bool "WM9705 Touchscreen interface support"
- depends on TOUCHSCREEN_WM97XX
- default y
- help
- Say Y here to enable support for the Wolfson Microelectronics
- WM9705 touchscreen controller.
-
-config TOUCHSCREEN_WM9712
- bool "WM9712 Touchscreen interface support"
- depends on TOUCHSCREEN_WM97XX
- default y
- help
- Say Y here to enable support for the Wolfson Microelectronics
- WM9712 touchscreen controller.
-
-config TOUCHSCREEN_WM9713
- bool "WM9713 Touchscreen interface support"
- depends on TOUCHSCREEN_WM97XX
- default y
- help
- Say Y here to enable support for the Wolfson Microelectronics
- WM9713 touchscreen controller.
-
-config TOUCHSCREEN_WM97XX_ATMEL
- tristate "WM97xx Atmel accelerated touch"
- depends on TOUCHSCREEN_WM97XX && (AVR32 || ARCH_AT91)
- help
- Say Y here for support for streaming mode with WM97xx touchscreens
- on Atmel AT91 or AVR32 systems with an AC97C module.
-
- Be aware that this will use channel B in the controller for
- streaming data, this must not conflict with other AC97C drivers.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the module will
- be called atmel-wm97xx.
-
-config TOUCHSCREEN_WM97XX_MAINSTONE
- tristate "WM97xx Mainstone/Palm accelerated touch"
- depends on TOUCHSCREEN_WM97XX && ARCH_PXA
- help
- Say Y here for support for streaming mode with WM97xx touchscreens
- on Mainstone, Palm Tungsten T5, TX and LifeDrive systems.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called mainstone-wm97xx.
-
-config TOUCHSCREEN_WM97XX_ZYLONITE
- tristate "Zylonite accelerated touch"
- depends on TOUCHSCREEN_WM97XX && MACH_ZYLONITE
- select TOUCHSCREEN_WM9713
- help
- Say Y here for support for streaming mode with the touchscreen
- on Zylonite systems.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called zylonite-wm97xx.
-
-config TOUCHSCREEN_USB_COMPOSITE
- tristate "USB Touchscreen Driver"
- depends on USB_ARCH_HAS_HCD
- select USB
- help
- USB Touchscreen driver for:
- - eGalax Touchkit USB (also includes eTurboTouch CT-410/510/700)
- - PanJit TouchSet USB
- - 3M MicroTouch USB (EX II series)
- - ITM
- - some other eTurboTouch
- - Gunze AHL61
- - DMC TSC-10/25
- - IRTOUCHSYSTEMS/UNITOP
- - IdealTEK URTC1000
- - GoTop Super_Q2/GogoPen/PenPower tablets
- - JASTEC USB Touch Controller/DigiTech DTR-02U
- - Zytronic controllers
-
- Have a look at <http://linux.chapter7.ch/touchkit/> for
- a usage description and the required user-space stuff.
-
- To compile this driver as a module, choose M here: the
- module will be called usbtouchscreen.
-
-config TOUCHSCREEN_MC13783
- tristate "Freescale MC13783 touchscreen input driver"
- depends on MFD_MC13783
- help
- Say Y here if you have an Freescale MC13783 PMIC on your
- board and want to use its touchscreen
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called mc13783_ts.
-
-config TOUCHSCREEN_USB_EGALAX
- default y
- bool "eGalax, eTurboTouch CT-410/510/700 device support" if EMBEDDED
- depends on TOUCHSCREEN_USB_COMPOSITE
-
-config TOUCHSCREEN_USB_PANJIT
- default y
- bool "PanJit device support" if EMBEDDED
- depends on TOUCHSCREEN_USB_COMPOSITE
-
-config TOUCHSCREEN_USB_3M
- default y
- bool "3M/Microtouch EX II series device support" if EMBEDDED
- depends on TOUCHSCREEN_USB_COMPOSITE
-
-config TOUCHSCREEN_USB_ITM
- default y
- bool "ITM device support" if EMBEDDED
- depends on TOUCHSCREEN_USB_COMPOSITE
-
-config TOUCHSCREEN_USB_ETURBO
- default y
- bool "eTurboTouch (non-eGalax compatible) device support" if EMBEDDED
- depends on TOUCHSCREEN_USB_COMPOSITE
-
-config TOUCHSCREEN_USB_GUNZE
- default y
- bool "Gunze AHL61 device support" if EMBEDDED
- depends on TOUCHSCREEN_USB_COMPOSITE
-
-config TOUCHSCREEN_USB_DMC_TSC10
- default y
- bool "DMC TSC-10/25 device support" if EMBEDDED
- depends on TOUCHSCREEN_USB_COMPOSITE
-
-config TOUCHSCREEN_USB_IRTOUCH
- default y
- bool "IRTOUCHSYSTEMS/UNITOP device support" if EMBEDDED
- depends on TOUCHSCREEN_USB_COMPOSITE
-
-config TOUCHSCREEN_USB_IDEALTEK
- default y
- bool "IdealTEK URTC1000 device support" if EMBEDDED
- depends on TOUCHSCREEN_USB_COMPOSITE
-
-config TOUCHSCREEN_USB_GENERAL_TOUCH
- default y
- bool "GeneralTouch Touchscreen device support" if EMBEDDED
- depends on TOUCHSCREEN_USB_COMPOSITE
-
-config TOUCHSCREEN_USB_GOTOP
- default y
- bool "GoTop Super_Q2/GogoPen/PenPower tablet device support" if EMBEDDED
- depends on TOUCHSCREEN_USB_COMPOSITE
-
-config TOUCHSCREEN_USB_JASTEC
- default y
- bool "JASTEC/DigiTech DTR-02U USB touch controller device support" if EMBEDDED
- depends on TOUCHSCREEN_USB_COMPOSITE
-
-config TOUCHSCREEN_USB_E2I
- default y
- bool "e2i Touchscreen controller (e.g. from Mimo 740)"
- depends on TOUCHSCREEN_USB_COMPOSITE
-
-config TOUCHSCREEN_USB_ZYTRONIC
- default y
- bool "Zytronic controller" if EMBEDDED
- depends on TOUCHSCREEN_USB_COMPOSITE
-
-config TOUCHSCREEN_USB_ETT_TC45USB
- default y
- bool "ET&T USB series TC4UM/TC5UH touchscreen controler support" if EMBEDDED
- depends on TOUCHSCREEN_USB_COMPOSITE
-
-config TOUCHSCREEN_USB_NEXIO
- default y
- bool "NEXIO/iNexio device support" if EMBEDDED
- depends on TOUCHSCREEN_USB_COMPOSITE
-
-config TOUCHSCREEN_TOUCHIT213
- tristate "Sahara TouchIT-213 touchscreen"
- select SERIO
- help
- Say Y here if you have a Sahara TouchIT-213 Tablet PC.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called touchit213.
-
-config TOUCHSCREEN_TSC2007
- tristate "TSC2007 based touchscreens"
- depends on I2C
- help
- Say Y here if you have a TSC2007 based touchscreen.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called tsc2007.
-
-config TOUCHSCREEN_TSC2004
- tristate "TSC2004 based touchscreens"
- depends on I2C
- help
- Say Y here if you have a TSC2004 based touchscreen.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called tsc2004.
-
-config TOUCHSCREEN_W90X900
- tristate "W90P910 touchscreen driver"
- depends on HAVE_CLK
- help
- Say Y here if you have a W90P910 based touchscreen.
-
- To compile this driver as a module, choose M here: the
- module will be called w90p910_ts.
-
-config TOUCHSCREEN_PCAP
- tristate "Motorola PCAP touchscreen"
- depends on EZX_PCAP
- help
- Say Y here if you have a Motorola EZX telephone and
- want to enable support for the built-in touchscreen.
-
- To compile this driver as a module, choose M here: the
- module will be called pcap_ts.
-
-config TOUCHSCREEN_TPS6507X
- tristate "TPS6507x based touchscreens"
- depends on I2C
- help
- Say Y here if you have a TPS6507x based touchscreen
- controller.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called tps6507x_ts.
-
-config TOUCHSCREEN_STMPE
- tristate "STMicroelectronics STMPE touchscreens"
- depends on MFD_STMPE
- help
- Say Y here if you want support for STMicroelectronics
- STMPE touchscreen controllers.
-
- To compile this driver as a module, choose M here: the
- module will be called stmpe-ts.
-
-endif
diff --git a/kernel/drivers/input/touchscreen/Makefile b/kernel/drivers/input/touchscreen/Makefile
deleted file mode 100644
index a6c7d9f..0000000
--- a/kernel/drivers/input/touchscreen/Makefile
+++ /dev/null
@@ -1,68 +0,0 @@
-#
-# Makefile for the touchscreen drivers.
-#
-
-# Each configuration option enables a list of files.
-
-wm97xx-ts-y := wm97xx-core.o
-
-obj-$(CONFIG_TOUCHSCREEN_88PM860X) += 88pm860x-ts.o
-obj-$(CONFIG_TOUCHSCREEN_AD7877) += ad7877.o
-obj-$(CONFIG_TOUCHSCREEN_AD7879) += ad7879.o
-obj-$(CONFIG_TOUCHSCREEN_AD7879_I2C) += ad7879-i2c.o
-obj-$(CONFIG_TOUCHSCREEN_AD7879_SPI) += ad7879-spi.o
-obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o
-obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) += atmel_tsadcc.o
-obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o
-obj-$(CONFIG_TOUCHSCREEN_BU21013) += bu21013_ts.o
-obj-$(CONFIG_TOUCHSCREEN_CY8CTMG110) += cy8ctmg110_ts.o
-obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o
-obj-$(CONFIG_TOUCHSCREEN_DYNAPRO) += dynapro.o
-obj-$(CONFIG_TOUCHSCREEN_HAMPSHIRE) += hampshire.o
-obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o
-obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o
-obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o
-obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o
-obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o
-obj-$(CONFIG_TOUCHSCREEN_INTEL_MID) += intel-mid-touch.o
-obj-$(CONFIG_TOUCHSCREEN_LPC32XX) += lpc32xx_ts.o
-obj-$(CONFIG_TOUCHSCREEN_MC13783) += mc13783_ts.o
-obj-$(CONFIG_TOUCHSCREEN_MCS5000) += mcs5000_ts.o
-obj-$(CONFIG_TOUCHSCREEN_MIGOR) += migor_ts.o
-obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o
-obj-$(CONFIG_TOUCHSCREEN_MK712) += mk712.o
-obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o
-obj-$(CONFIG_TOUCHSCREEN_HP7XX) += jornada720_ts.o
-obj-$(CONFIG_TOUCHSCREEN_HTCPEN) += htcpen.o
-obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE) += usbtouchscreen.o
-obj-$(CONFIG_TOUCHSCREEN_PCAP) += pcap_ts.o
-obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o
-obj-$(CONFIG_TOUCHSCREEN_QT602240) += qt602240_ts.o
-obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o
-obj-$(CONFIG_TOUCHSCREEN_STMPE) += stmpe-ts.o
-obj-$(CONFIG_TOUCHSCREEN_TNETV107X) += tnetv107x-ts.o
-obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += synaptics_i2c_rmi4.o
-obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI4_DEV) += synaptics_rmi_dev.o
-obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE) += synaptics_fw_update.o
-obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o
-obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o
-obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o
-obj-$(CONFIG_TOUCHSCREEN_TSC2007) += tsc2007.o
-obj-$(CONFIG_TOUCHSCREEN_TSC2004) += tsc2004.o
-obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o
-obj-$(CONFIG_TOUCHSCREEN_WACOM_W8001) += wacom_w8001.o
-obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o
-wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o
-wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9712) += wm9712.o
-wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9713) += wm9713.o
-obj-$(CONFIG_TOUCHSCREEN_WM97XX_ATMEL) += atmel-wm97xx.o
-obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o
-obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o
-obj-$(CONFIG_TOUCHSCREEN_W90X900) += w90p910_ts.o
-obj-$(CONFIG_TOUCHSCREEN_TPS6507X) += tps6507x-ts.o
-
-all:
-make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
-
-clean:
-make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 6e42cc2..d6dd07a 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -913,12 +913,14 @@
* This array describes the order lists are fallen back to when
* the free lists for the desirable migrate type are depleted
*/
-static int fallbacks[MIGRATE_TYPES][3] = {
+static int fallbacks[MIGRATE_TYPES][4] = {
[MIGRATE_UNMOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_MOVABLE, MIGRATE_RESERVE },
[MIGRATE_RECLAIMABLE] = { MIGRATE_UNMOVABLE, MIGRATE_MOVABLE, MIGRATE_RESERVE },
- [MIGRATE_MOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_UNMOVABLE, MIGRATE_RESERVE },
#ifdef CONFIG_CMA
+ [MIGRATE_MOVABLE] = { MIGRATE_CMA, MIGRATE_RECLAIMABLE, MIGRATE_UNMOVABLE, MIGRATE_RESERVE },
[MIGRATE_CMA] = { MIGRATE_RESERVE }, /* Never used */
+#else
+ [MIGRATE_MOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_UNMOVABLE, MIGRATE_RESERVE },
#endif
[MIGRATE_RESERVE] = { MIGRATE_RESERVE }, /* Never used */
[MIGRATE_ISOLATE] = { MIGRATE_RESERVE }, /* Never used */
@@ -1041,10 +1043,17 @@
* pages to the preferred allocation list. If falling
* back for a reclaimable kernel allocation, be more
* aggressive about taking ownership of free pages
+ *
+ * On the other hand, never change migration
+ * type of MIGRATE_CMA pageblocks nor move CMA
+ * pages on different free lists. We don't
+ * want unmovable pages to be allocated from
+ * MIGRATE_CMA areas.
*/
- if (unlikely(current_order >= pageblock_order / 2) ||
- start_migratetype == MIGRATE_RECLAIMABLE ||
- page_group_by_mobility_disabled) {
+ if (!is_migrate_cma(migratetype) &&
+ (unlikely(current_order >= pageblock_order / 2) ||
+ start_migratetype == MIGRATE_RECLAIMABLE ||
+ page_group_by_mobility_disabled)) {
int pages;
pages = move_freepages_block(zone, page,
start_migratetype);
@@ -1063,12 +1072,14 @@
rmv_page_order(page);
/* Take ownership for orders >= pageblock_order */
- if (current_order >= pageblock_order)
+ if (current_order >= pageblock_order &&
+ !is_migrate_cma(migratetype))
change_pageblock_range(page, current_order,
start_migratetype);
expand(zone, page, order, current_order, area,
- start_migratetype);
+ is_migrate_cma(migratetype)
+ ? migratetype : start_migratetype);
trace_mm_page_alloc_extfrag(page, order, current_order,
start_migratetype, migratetype);
@@ -1089,27 +1100,52 @@
{
struct page *page;
-#ifdef CONFIG_CMA
- if (migratetype == MIGRATE_MOVABLE)
- migratetype = MIGRATE_CMA;
-#endif
+retry_reserve:
+ page = __rmqueue_smallest(zone, order, migratetype);
- for(;;) {
- page = __rmqueue_smallest(zone, order, migratetype);
- if (likely(page) || migratetype == MIGRATE_RESERVE)
- break;
-
- if (is_migrate_cma(migratetype)) {
- migratetype = MIGRATE_MOVABLE;
- continue;
- }
-
+ if (unlikely(!page) && migratetype != MIGRATE_RESERVE) {
page = __rmqueue_fallback(zone, order, migratetype);
- if (page)
- break;
- /* Use MIGRATE_RESERVE rather than fail an allocation. */
- migratetype = MIGRATE_RESERVE;
+ /*
+ * Use MIGRATE_RESERVE rather than fail an allocation. goto
+ * is used because __rmqueue_smallest is an inline function
+ * and we want just one call site
+ */
+ if (!page) {
+ migratetype = MIGRATE_RESERVE;
+ goto retry_reserve;
+ }
+ }
+
+ trace_mm_page_alloc_zone_locked(page, order, migratetype);
+ return page;
+}
+
+static struct page *__rmqueue_cma(struct zone *zone, unsigned int order,
+ int migratetype)
+{
+ struct page *page = 0;
+#ifdef CONFIG_CMA
+ if (migratetype == MIGRATE_MOVABLE && !zone->cma_alloc)
+ page = __rmqueue_smallest(zone, order, MIGRATE_CMA);
+ else
+#endif
+retry_reserve :
+ page = __rmqueue_smallest(zone, order, migratetype);
+
+
+ if (unlikely(!page) && migratetype != MIGRATE_RESERVE) {
+ page = __rmqueue_fallback(zone, order, migratetype);
+
+ /*
+ * Use MIGRATE_RESERVE rather than fail an allocation. goto
+ * is used because __rmqueue_smallest is an inline function
+ * and we want just one call site
+ */
+ if (!page) {
+ migratetype = MIGRATE_RESERVE;
+ goto retry_reserve;
+ }
}
trace_mm_page_alloc_zone_locked(page, order, migratetype);
@@ -1123,13 +1159,17 @@
*/
static int rmqueue_bulk(struct zone *zone, unsigned int order,
unsigned long count, struct list_head *list,
- int migratetype, int cold)
+ int migratetype, int cold, int cma)
{
int mt = migratetype, i;
spin_lock(&zone->lock);
for (i = 0; i < count; ++i) {
- struct page *page = __rmqueue(zone, order, migratetype);
+ struct page *page;
+ if (cma)
+ page = __rmqueue_cma(zone, order, migratetype);
+ else
+ page = __rmqueue(zone, order, migratetype);
if (unlikely(page == NULL))
break;
@@ -1333,7 +1373,8 @@
* excessively into the page allocator
*/
if (migratetype >= MIGRATE_PCPTYPES) {
- if (unlikely(migratetype == MIGRATE_ISOLATE)) {
+ if (unlikely(migratetype == MIGRATE_ISOLATE) ||
+ is_migrate_cma(migratetype)) {
free_one_page(zone, page, 0, migratetype);
goto out;
}
@@ -1475,7 +1516,8 @@
if (list_empty(list)) {
pcp->count += rmqueue_bulk(zone, 0,
pcp->batch, list,
- migratetype, cold);
+ migratetype, cold,
+ gfp_flags & __GFP_CMA);
if (unlikely(list_empty(list)))
goto failed;
}
@@ -1502,7 +1544,10 @@
WARN_ON_ONCE(order > 1);
}
spin_lock_irqsave(&zone->lock, flags);
- page = __rmqueue(zone, order, migratetype);
+ if (gfp_flags & __GFP_CMA)
+ page = __rmqueue_cma(zone, order, migratetype);
+ else
+ page = __rmqueue(zone, order, migratetype);
spin_unlock(&zone->lock);
if (!page)
goto failed;
@@ -5879,6 +5924,8 @@
if (ret)
goto done;
+ zone->cma_alloc = 1;
+
ret = __alloc_contig_migrate_range(start, end);
if (ret)
goto done;
@@ -5943,6 +5990,7 @@
done:
undo_isolate_page_range(pfn_max_align_down(start),
pfn_max_align_up(end), migratetype);
+ zone->cma_alloc = 0;
return ret;
}
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..4bcea07
--- /dev/null
+++ b/sound/soc/codecs/msm8x10-wcd.c
@@ -0,0 +1,2427 @@
+/* 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 MSM8X10_WCD_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
+
+#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;
+};
+
+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_S8_TLV("RX1 Digital Volume",
+ MSM8X10_WCD_A_CDC_RX1_VOL_CTL_B2_CTL,
+ -84, 40, digital_gain),
+ SOC_SINGLE_S8_TLV("RX2 Digital Volume",
+ MSM8X10_WCD_A_CDC_RX2_VOL_CTL_B2_CTL,
+ -84, 40, digital_gain),
+ SOC_SINGLE_S8_TLV("RX3 Digital Volume",
+ MSM8X10_WCD_A_CDC_RX3_VOL_CTL_B2_CTL,
+ -84, 40, digital_gain),
+
+ SOC_SINGLE_S8_TLV("DEC1 Volume",
+ MSM8X10_WCD_A_CDC_TX1_VOL_CTL_GAIN,
+ -84, 40, digital_gain),
+ SOC_SINGLE_S8_TLV("DEC2 Volume",
+ MSM8X10_WCD_A_CDC_TX2_VOL_CTL_GAIN,
+ -84, 40, digital_gain),
+
+ SOC_SINGLE_S8_TLV("IIR1 INP1 Volume",
+ MSM8X10_WCD_A_CDC_IIR1_GAIN_B1_CTL,
+ -84, 40, digital_gain),
+ SOC_SINGLE_S8_TLV("IIR1 INP2 Volume",
+ MSM8X10_WCD_A_CDC_IIR1_GAIN_B2_CTL,
+ -84, 40, digital_gain),
+ SOC_SINGLE_S8_TLV("IIR1 INP3 Volume",
+ MSM8X10_WCD_A_CDC_IIR1_GAIN_B3_CTL,
+ -84, 40, digital_gain),
+ SOC_SINGLE_S8_TLV("IIR1 INP4 Volume",
+ MSM8X10_WCD_A_CDC_IIR1_GAIN_B4_CTL,
+ -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;
+}
+
+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_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"},
+};
+
+
+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);
+ }
+}
+
+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;
+}
+
+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},
+ {}
+};
+
+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");
+MODULE_DEVICE_TABLE(i2c, msm8x10_wcd_id_table);
+
diff --git a/sound/soc/codecs/msm8x10-wcd.h b/sound/soc/codecs/msm8x10-wcd.h
new file mode 100644
index 0000000..365d526
--- /dev/null
+++ b/sound/soc/codecs/msm8x10-wcd.h
@@ -0,0 +1,226 @@
+/* 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..a10f31f
--- /dev/null
+++ b/sound/soc/codecs/msm8x10_wcd_registers.h
@@ -0,0 +1,641 @@
+ /* 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_REGISTERS_H
+#define MSM8X10_WCD_REGISTERS_H
+
+#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)
+#endif
diff --git a/sound/soc/codecs/wcd9320.c b/sound/soc/codecs/wcd9320.c
index 28be822..1746502 100644
--- a/sound/soc/codecs/wcd9320.c
+++ b/sound/soc/codecs/wcd9320.c
@@ -2169,45 +2169,44 @@
{
struct snd_soc_codec *codec = w->codec;
struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
- u16 micb_int_reg;
+ u16 micb_int_reg = 0, micb_ctl_reg = 0;
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 TAIKO_A_MICB_1_CTL:
+ pr_debug("%s: w->name %s event %d\n", __func__, w->name, event);
+ if (strnstr(w->name, "MIC BIAS1", sizeof("MIC BIAS1"))) {
+ micb_ctl_reg = TAIKO_A_MICB_1_CTL;
micb_int_reg = TAIKO_A_MICB_1_INT_RBIAS;
cfilt_sel_val = taiko->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;
- case TAIKO_A_MICB_2_CTL:
+ } else if (strnstr(w->name, "MIC BIAS2", sizeof("MIC BIAS2"))) {
+ micb_ctl_reg = TAIKO_A_MICB_2_CTL;
micb_int_reg = TAIKO_A_MICB_2_INT_RBIAS;
cfilt_sel_val = taiko->resmgr.pdata->micbias.bias2_cfilt_sel;
e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_2_ON;
e_post_on = WCD9XXX_EVENT_POST_MICBIAS_2_ON;
e_post_off = WCD9XXX_EVENT_POST_MICBIAS_2_OFF;
- break;
- case TAIKO_A_MICB_3_CTL:
+ } else if (strnstr(w->name, "MIC BIAS3", sizeof("MIC BIAS3"))) {
+ micb_ctl_reg = TAIKO_A_MICB_2_CTL;
micb_int_reg = TAIKO_A_MICB_3_INT_RBIAS;
cfilt_sel_val = taiko->resmgr.pdata->micbias.bias3_cfilt_sel;
e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_3_ON;
e_post_on = WCD9XXX_EVENT_POST_MICBIAS_3_ON;
e_post_off = WCD9XXX_EVENT_POST_MICBIAS_3_OFF;
- break;
- case TAIKO_A_MICB_4_CTL:
+ } else if (strnstr(w->name, "MIC BIAS4", sizeof("MIC BIAS4"))) {
+ micb_ctl_reg = TAIKO_A_MICB_2_CTL;
micb_int_reg = taiko->resmgr.reg_addr->micb_4_int_rbias;
cfilt_sel_val = taiko->resmgr.pdata->micbias.bias4_cfilt_sel;
e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_4_ON;
e_post_on = WCD9XXX_EVENT_POST_MICBIAS_4_ON;
e_post_off = WCD9XXX_EVENT_POST_MICBIAS_4_OFF;
- break;
- default:
- pr_err("%s: Error, invalid micbias register\n", __func__);
+ } else {
+ pr_err("%s: Error, invalid micbias %s\n", __func__, w->name);
return -EINVAL;
}
@@ -2226,6 +2225,16 @@
else if (strnstr(w->name, internal3_text, 30))
snd_soc_update_bits(codec, micb_int_reg, 0x3, 0x3);
+ if (micb_ctl_reg == TAIKO_A_MICB_2_CTL) {
+ WCD9XXX_BCL_LOCK(&taiko->resmgr);
+ wcd9xxx_resmgr_add_cond_update_bits(&taiko->resmgr,
+ WCD9XXX_COND_HPH_MIC,
+ micb_ctl_reg, w->shift,
+ false);
+ WCD9XXX_BCL_UNLOCK(&taiko->resmgr);
+ } else
+ snd_soc_update_bits(codec, micb_ctl_reg, 1 << w->shift,
+ 1 << w->shift);
break;
case SND_SOC_DAPM_POST_PMU:
usleep_range(20000, 20000);
@@ -2233,6 +2242,16 @@
wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_post_on);
break;
case SND_SOC_DAPM_POST_PMD:
+ if (micb_ctl_reg == TAIKO_A_MICB_2_CTL) {
+ WCD9XXX_BCL_LOCK(&taiko->resmgr);
+ wcd9xxx_resmgr_rm_cond_update_bits(&taiko->resmgr,
+ WCD9XXX_COND_HPH_MIC,
+ micb_ctl_reg, 7, false);
+ WCD9XXX_BCL_UNLOCK(&taiko->resmgr);
+ } else
+ snd_soc_update_bits(codec, micb_ctl_reg, 1 << w->shift,
+ 0);
+
/* Let MBHC module know so micbias switch to be off */
wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_post_off);
@@ -4220,15 +4239,18 @@
SND_SOC_DAPM_INPUT("AMIC1"),
- SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 External", TAIKO_A_MICB_1_CTL, 7, 0,
- taiko_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", TAIKO_A_MICB_1_CTL, 7, 0,
- taiko_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", TAIKO_A_MICB_1_CTL, 7, 0,
- taiko_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 External", SND_SOC_NOPM, 7, 0,
+ taiko_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", SND_SOC_NOPM, 7, 0,
+ taiko_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", SND_SOC_NOPM, 7, 0,
+ taiko_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, TAIKO_A_TX_1_2_EN, 7, 0,
taiko_codec_enable_adc, SND_SOC_DAPM_PRE_PMU |
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
@@ -4311,31 +4333,38 @@
SND_SOC_DAPM_MUX("ANC1 FB MUX", SND_SOC_NOPM, 0, 0, &anc1_fb_mux),
SND_SOC_DAPM_INPUT("AMIC2"),
- SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 External", TAIKO_A_MICB_2_CTL, 7, 0,
- taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal1", TAIKO_A_MICB_2_CTL, 7, 0,
- taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal2", TAIKO_A_MICB_2_CTL, 7, 0,
- taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal3", TAIKO_A_MICB_2_CTL, 7, 0,
- taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 External", TAIKO_A_MICB_3_CTL, 7, 0,
- taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal1", TAIKO_A_MICB_3_CTL, 7, 0,
- taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal2", TAIKO_A_MICB_3_CTL, 7, 0,
- taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_MICBIAS_E("MIC BIAS4 External", TAIKO_A_MICB_4_CTL, 7,
- 0, taiko_codec_enable_micbias,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
- SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 External", SND_SOC_NOPM, 7, 0,
+ taiko_codec_enable_micbias,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal1", SND_SOC_NOPM, 7, 0,
+ taiko_codec_enable_micbias,
+ SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal2", SND_SOC_NOPM, 7, 0,
+ taiko_codec_enable_micbias,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal3", SND_SOC_NOPM, 7, 0,
+ taiko_codec_enable_micbias,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 External", SND_SOC_NOPM, 7, 0,
+ taiko_codec_enable_micbias,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal1", SND_SOC_NOPM, 7, 0,
+ taiko_codec_enable_micbias,
+ SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal2", SND_SOC_NOPM, 7, 0,
+ taiko_codec_enable_micbias,
+ SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MICBIAS_E("MIC BIAS4 External", SND_SOC_NOPM, 7,
+ 0, taiko_codec_enable_micbias,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_ADC_E("ADC2", NULL, TAIKO_A_TX_1_2_EN, 3, 0,
taiko_codec_enable_adc, SND_SOC_DAPM_PRE_PMU |
diff --git a/sound/soc/codecs/wcd9xxx-mbhc.c b/sound/soc/codecs/wcd9xxx-mbhc.c
index c1a1aa1..b3549cc 100644
--- a/sound/soc/codecs/wcd9xxx-mbhc.c
+++ b/sound/soc/codecs/wcd9xxx-mbhc.c
@@ -83,6 +83,7 @@
#define VDDIO_MICBIAS_MV 1800
#define WCD9XXX_HPHL_STATUS_READY_WAIT_US 1000
+#define WCD9XXX_MUX_SWITCH_READY_WAIT_US 100
#define WCD9XXX_MEAS_DELTA_MAX_MV 50
#define WCD9XXX_GM_SWAP_THRES_MIN_MV 150
#define WCD9XXX_GM_SWAP_THRES_MAX_MV 500
@@ -373,8 +374,14 @@
}
}
-static void wcd9xxx_jack_report(struct snd_soc_jack *jack, int status, int mask)
+static void wcd9xxx_jack_report(struct wcd9xxx_mbhc *mbhc,
+ struct snd_soc_jack *jack, int status, int mask)
{
+ if (jack == &mbhc->headset_jack)
+ wcd9xxx_resmgr_cond_update_cond(mbhc->resmgr,
+ WCD9XXX_COND_HPH_MIC,
+ status & SND_JACK_MICROPHONE);
+
snd_soc_jack_report_no_dapm(jack, status, mask);
}
@@ -387,7 +394,7 @@
codec = mbhc->codec;
if (mbhc->hph_status & jack_status) {
mbhc->hph_status &= ~jack_status;
- wcd9xxx_jack_report(&mbhc->headset_jack,
+ wcd9xxx_jack_report(mbhc, &mbhc->headset_jack,
mbhc->hph_status, WCD9XXX_JACK_MASK);
snd_soc_update_bits(codec, WCD9XXX_A_RX_HPH_OCP_CTL, 0x10,
0x00);
@@ -617,14 +624,14 @@
else if (mbhc->buttons_pressed) {
pr_debug("%s: release of button press%d\n",
__func__, jack_type);
- wcd9xxx_jack_report(&mbhc->button_jack, 0,
+ wcd9xxx_jack_report(mbhc, &mbhc->button_jack, 0,
mbhc->buttons_pressed);
mbhc->buttons_pressed &=
~WCD9XXX_JACK_BUTTON_MASK;
}
pr_debug("%s: Reporting removal %d(%x)\n", __func__,
jack_type, mbhc->hph_status);
- wcd9xxx_jack_report(&mbhc->headset_jack, mbhc->hph_status,
+ wcd9xxx_jack_report(mbhc, &mbhc->headset_jack, mbhc->hph_status,
WCD9XXX_JACK_MASK);
wcd9xxx_set_and_turnoff_hph_padac(mbhc);
hphrocp_off_report(mbhc, SND_JACK_OC_HPHR);
@@ -637,7 +644,7 @@
if (mbhc->hph_status && mbhc->hph_status != jack_type) {
pr_debug("%s: Reporting removal (%x)\n",
__func__, mbhc->hph_status);
- wcd9xxx_jack_report(&mbhc->headset_jack,
+ wcd9xxx_jack_report(mbhc, &mbhc->headset_jack,
0, WCD9XXX_JACK_MASK);
mbhc->hph_status = 0;
}
@@ -657,7 +664,7 @@
}
pr_debug("%s: Reporting insertion %d(%x)\n", __func__,
jack_type, mbhc->hph_status);
- wcd9xxx_jack_report(&mbhc->headset_jack,
+ wcd9xxx_jack_report(mbhc, &mbhc->headset_jack,
mbhc->hph_status, WCD9XXX_JACK_MASK);
wcd9xxx_clr_and_turnon_hph_padac(mbhc);
}
@@ -1605,6 +1612,14 @@
pr_debug("%s: enter, removal interrupt\n", __func__);
WCD9XXX_BCL_LOCK(mbhc->resmgr);
+ /*
+ * While we don't know whether MIC is there or not, let the resmgr know
+ * so micbias can be disabled temporarily
+ */
+ if (mbhc->current_plug == PLUG_TYPE_HEADSET)
+ wcd9xxx_resmgr_cond_update_cond(mbhc->resmgr,
+ WCD9XXX_COND_HPH_MIC, false);
+
vddio = (mbhc->mbhc_data.micb_mv != VDDIO_MICBIAS_MV &&
mbhc->mbhc_micbias_switched);
if (vddio)
@@ -1623,6 +1638,10 @@
*/
if (vddio && (mbhc->current_plug == PLUG_TYPE_HEADSET))
__wcd9xxx_switch_micbias(mbhc, 1, true, true);
+
+ if (mbhc->current_plug == PLUG_TYPE_HEADSET)
+ wcd9xxx_resmgr_cond_update_cond(mbhc->resmgr,
+ WCD9XXX_COND_HPH_MIC, true);
WCD9XXX_BCL_UNLOCK(mbhc->resmgr);
return IRQ_HANDLED;
@@ -1678,7 +1697,7 @@
pr_debug("%s: STA: %d, DCE: %d\n", __func__, sta_mv, dce_mv);
pr_debug("%s: Reporting long button press event\n", __func__);
- wcd9xxx_jack_report(&mbhc->button_jack, mbhc->buttons_pressed,
+ wcd9xxx_jack_report(mbhc, &mbhc->button_jack, mbhc->buttons_pressed,
mbhc->buttons_pressed);
pr_debug("%s: leave\n", __func__);
@@ -2356,7 +2375,7 @@
if (ret == 0) {
pr_debug("%s: Reporting long button release event\n",
__func__);
- wcd9xxx_jack_report(&mbhc->button_jack, 0,
+ wcd9xxx_jack_report(mbhc, &mbhc->button_jack, 0,
mbhc->buttons_pressed);
} else {
if (wcd9xxx_is_fake_press(mbhc)) {
@@ -2369,12 +2388,14 @@
} else {
pr_debug("%s: Reporting btn press\n",
__func__);
- wcd9xxx_jack_report(&mbhc->button_jack,
+ wcd9xxx_jack_report(mbhc,
+ &mbhc->button_jack,
mbhc->buttons_pressed,
mbhc->buttons_pressed);
pr_debug("%s: Reporting btn release\n",
__func__);
- wcd9xxx_jack_report(&mbhc->button_jack,
+ wcd9xxx_jack_report(mbhc,
+ &mbhc->button_jack,
0, mbhc->buttons_pressed);
}
}
@@ -2413,7 +2434,7 @@
WCD9XXX_IRQ_HPH_PA_OCPL_FAULT);
mbhc->hphlocp_cnt = 0;
mbhc->hph_status |= SND_JACK_OC_HPHL;
- wcd9xxx_jack_report(&mbhc->headset_jack,
+ wcd9xxx_jack_report(mbhc, &mbhc->headset_jack,
mbhc->hph_status,
WCD9XXX_JACK_MASK);
}
@@ -2442,7 +2463,7 @@
WCD9XXX_IRQ_HPH_PA_OCPR_FAULT);
mbhc->hphrocp_cnt = 0;
mbhc->hph_status |= SND_JACK_OC_HPHR;
- wcd9xxx_jack_report(&mbhc->headset_jack,
+ wcd9xxx_jack_report(mbhc, &mbhc->headset_jack,
mbhc->hph_status, WCD9XXX_JACK_MASK);
}
@@ -2515,6 +2536,7 @@
static void wcd9xxx_mbhc_cal(struct wcd9xxx_mbhc *mbhc)
{
u8 cfilt_mode;
+ u16 reg0, reg1;
struct snd_soc_codec *codec = mbhc->codec;
pr_debug("%s: enter\n", __func__);
@@ -2544,15 +2566,28 @@
snd_soc_write(codec, WCD9XXX_A_TX_7_MBHC_TEST_CTL, 0x78);
snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B1_CTL, 0x04, 0x04);
- /* DCE measurement for 0 volts */
+ /* Pull down micbias to ground */
+ reg0 = snd_soc_read(codec, mbhc->mbhc_bias_regs.ctl_reg);
+ snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.ctl_reg, 1, 1);
+ /* Disconnect override from micbias */
+ reg1 = snd_soc_read(codec, WCD9XXX_A_MAD_ANA_CTRL);
+ snd_soc_update_bits(codec, WCD9XXX_A_MAD_ANA_CTRL, 1 << 4, 1 << 0);
+ /* Connect the MUX to micbias */
+ snd_soc_write(codec, WCD9XXX_A_MBHC_SCALING_MUX_1, 0x82);
+ usleep_range(WCD9XXX_MUX_SWITCH_READY_WAIT_US,
+ WCD9XXX_MUX_SWITCH_READY_WAIT_US +
+ WCD9XXX_USLEEP_RANGE_MARGIN_US);
+ /* DCE measurement for 0 voltage */
snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x0A);
- snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_EN_CTL, 0x04);
snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x02);
- snd_soc_write(codec, WCD9XXX_A_MBHC_SCALING_MUX_1, 0x81);
- usleep_range(100, 100);
- snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_EN_CTL, 0x04);
- usleep_range(mbhc->mbhc_data.t_dce, mbhc->mbhc_data.t_dce);
- mbhc->mbhc_data.dce_z = wcd9xxx_read_dce_result(codec);
+ mbhc->mbhc_data.dce_z = __wcd9xxx_codec_sta_dce(mbhc, 1, true, false);
+ /* STA measurement for 0 voltage */
+ snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x0A);
+ snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x02);
+ mbhc->mbhc_data.sta_z = __wcd9xxx_codec_sta_dce(mbhc, 0, true, false);
+ /* Restore registers */
+ snd_soc_write(codec, mbhc->mbhc_bias_regs.ctl_reg, reg0);
+ snd_soc_write(codec, WCD9XXX_A_MAD_ANA_CTRL, reg1);
/* DCE measurment for MB voltage */
snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x0A);
@@ -2563,17 +2598,10 @@
usleep_range(mbhc->mbhc_data.t_dce, mbhc->mbhc_data.t_dce);
mbhc->mbhc_data.dce_mb = wcd9xxx_read_dce_result(codec);
- /* STA measuremnt for 0 volts */
+ /* STA Measurement for MB Voltage */
snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x0A);
snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_EN_CTL, 0x02);
snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x02);
- snd_soc_write(codec, WCD9XXX_A_MBHC_SCALING_MUX_1, 0x81);
- usleep_range(100, 100);
- snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_EN_CTL, 0x02);
- usleep_range(mbhc->mbhc_data.t_sta, mbhc->mbhc_data.t_sta);
- mbhc->mbhc_data.sta_z = wcd9xxx_read_sta_result(codec);
-
- /* STA Measurement for MB Voltage */
snd_soc_write(codec, WCD9XXX_A_MBHC_SCALING_MUX_1, 0x82);
usleep_range(100, 100);
snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_EN_CTL, 0x02);
diff --git a/sound/soc/codecs/wcd9xxx-resmgr.c b/sound/soc/codecs/wcd9xxx-resmgr.c
index 17edd4a..2011346 100644
--- a/sound/soc/codecs/wcd9xxx-resmgr.c
+++ b/sound/soc/codecs/wcd9xxx-resmgr.c
@@ -94,6 +94,14 @@
"WCD9XXX_EVENT_LAST",
};
+struct wcd9xxx_resmgr_cond_entry {
+ unsigned short reg;
+ int shift;
+ bool invert;
+ enum wcd9xxx_resmgr_cond cond;
+ struct list_head list;
+};
+
static enum wcd9xxx_clock_type wcd9xxx_save_clock(struct wcd9xxx_resmgr
*resmgr);
static void wcd9xxx_restore_clock(struct wcd9xxx_resmgr *resmgr,
@@ -640,6 +648,93 @@
return rc;
}
+void wcd9xxx_resmgr_cond_trigger_cond(struct wcd9xxx_resmgr *resmgr,
+ enum wcd9xxx_resmgr_cond cond)
+{
+ struct list_head *l;
+ struct wcd9xxx_resmgr_cond_entry *e;
+ bool set;
+
+ pr_debug("%s: enter\n", __func__);
+ WCD9XXX_BCL_ASSERT_LOCKED(resmgr);
+ set = !!test_bit(cond, &resmgr->cond_flags);
+ list_for_each(l, &resmgr->update_bit_cond_h) {
+ e = list_entry(l, struct wcd9xxx_resmgr_cond_entry, list);
+ if (e->cond == cond)
+ snd_soc_update_bits(resmgr->codec, e->reg,
+ 1 << e->shift,
+ (set ? !e->invert : e->invert)
+ << e->shift);
+ }
+ pr_debug("%s: leave\n", __func__);
+}
+
+void wcd9xxx_resmgr_cond_update_cond(struct wcd9xxx_resmgr *resmgr,
+ enum wcd9xxx_resmgr_cond cond, bool set)
+{
+ WCD9XXX_BCL_ASSERT_LOCKED(resmgr);
+ if ((set && !test_and_set_bit(cond, &resmgr->cond_flags)) ||
+ (!set && test_and_clear_bit(cond, &resmgr->cond_flags))) {
+ pr_debug("%s: Resource %d condition changed to %s\n", __func__,
+ cond, set ? "set" : "clear");
+ wcd9xxx_resmgr_cond_trigger_cond(resmgr, cond);
+ }
+}
+
+int wcd9xxx_resmgr_add_cond_update_bits(struct wcd9xxx_resmgr *resmgr,
+ enum wcd9xxx_resmgr_cond cond,
+ unsigned short reg, int shift,
+ bool invert)
+{
+ struct wcd9xxx_resmgr_cond_entry *entry;
+
+ WCD9XXX_BCL_ASSERT_LOCKED(resmgr);
+ entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+ if (!entry)
+ return -ENOMEM;
+
+ entry->cond = cond;
+ entry->reg = reg;
+ entry->shift = shift;
+ entry->invert = invert;
+ list_add_tail(&entry->list, &resmgr->update_bit_cond_h);
+
+ wcd9xxx_resmgr_cond_trigger_cond(resmgr, cond);
+
+ return 0;
+}
+
+/*
+ * wcd9xxx_resmgr_rm_cond_update_bits :
+ * Clear bit and remove from the conditional bit update list
+ */
+int wcd9xxx_resmgr_rm_cond_update_bits(struct wcd9xxx_resmgr *resmgr,
+ enum wcd9xxx_resmgr_cond cond,
+ unsigned short reg, int shift,
+ bool invert)
+{
+ struct list_head *l, *next;
+ struct wcd9xxx_resmgr_cond_entry *e = NULL;
+
+ pr_debug("%s: enter\n", __func__);
+ WCD9XXX_BCL_ASSERT_LOCKED(resmgr);
+ list_for_each_safe(l, next, &resmgr->update_bit_cond_h) {
+ e = list_entry(l, struct wcd9xxx_resmgr_cond_entry, list);
+ if (e->reg == reg && e->shift == shift && e->invert == invert) {
+ snd_soc_update_bits(resmgr->codec, e->reg,
+ 1 << e->shift,
+ e->invert << e->shift);
+ list_del(&e->list);
+ kfree(e);
+ return 0;
+ }
+ }
+ pr_err("%s: Cannot find update bit entry reg 0x%x, shift %d\n",
+ __func__, e ? e->reg : 0, e ? e->shift : 0);
+
+ return -EINVAL;
+}
+
int wcd9xxx_resmgr_register_notifier(struct wcd9xxx_resmgr *resmgr,
struct notifier_block *nblock)
{
@@ -669,6 +764,8 @@
resmgr->pdata = pdata;
resmgr->reg_addr = reg_addr;
+ INIT_LIST_HEAD(&resmgr->update_bit_cond_h);
+
BLOCKING_INIT_NOTIFIER_HEAD(&resmgr->notifier);
mutex_init(&resmgr->codec_resource_lock);
diff --git a/sound/soc/codecs/wcd9xxx-resmgr.h b/sound/soc/codecs/wcd9xxx-resmgr.h
index 6c30eeb..53c48f6 100644
--- a/sound/soc/codecs/wcd9xxx-resmgr.h
+++ b/sound/soc/codecs/wcd9xxx-resmgr.h
@@ -125,6 +125,9 @@
/* Notifier needs mbhc pointer with resmgr */
struct wcd9xxx_mbhc *mbhc;
+ unsigned long cond_flags;
+ struct list_head update_bit_cond_h;
+
/*
* Currently, only used for mbhc purpose, to protect
* concurrent execution of mbhc threaded irq handlers and
@@ -189,4 +192,18 @@
void wcd9xxx_resmgr_notifier_call(struct wcd9xxx_resmgr *resmgr,
const enum wcd9xxx_notify_event e);
+enum wcd9xxx_resmgr_cond {
+ WCD9XXX_COND_HPH_MIC = 1,
+};
+int wcd9xxx_resmgr_rm_cond_update_bits(struct wcd9xxx_resmgr *resmgr,
+ enum wcd9xxx_resmgr_cond cond,
+ unsigned short reg, int shift,
+ bool invert);
+int wcd9xxx_resmgr_add_cond_update_bits(struct wcd9xxx_resmgr *resmgr,
+ enum wcd9xxx_resmgr_cond cond,
+ unsigned short reg, int shift,
+ bool invert);
+void wcd9xxx_resmgr_cond_update_cond(struct wcd9xxx_resmgr *resmgr,
+ enum wcd9xxx_resmgr_cond cond, bool set);
+
#endif /* __WCD9XXX_COMMON_H__ */
diff --git a/sound/soc/msm/msm-pcm-voip.c b/sound/soc/msm/msm-pcm-voip.c
index 41e4c60..22bc9e1 100644
--- a/sound/soc/msm/msm-pcm-voip.c
+++ b/sound/soc/msm/msm-pcm-voip.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. 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 version 2 and
@@ -155,7 +155,8 @@
};
static int voip_get_media_type(uint32_t mode, uint32_t rate_type,
- unsigned int samp_rate);
+ unsigned int samp_rate,
+ uint32_t *media_type);
static int voip_get_rate_type(uint32_t mode,
uint32_t rate,
uint32_t *rate_type);
@@ -934,12 +935,12 @@
goto done;
}
prtd->rate_type = rate_type;
- media_type = voip_get_media_type(prtd->mode,
- prtd->rate_type,
- prtd->play_samp_rate);
- if (media_type < 0) {
+ ret = voip_get_media_type(prtd->mode,
+ prtd->rate_type,
+ prtd->play_samp_rate,
+ &media_type);
+ if (ret < 0) {
pr_err("fail at getting media_type\n");
- ret = -EINVAL;
goto done;
}
pr_debug(" media_type=%d, rate_type=%d\n", media_type,
@@ -1210,49 +1211,50 @@
}
static int voip_get_media_type(uint32_t mode, uint32_t rate_type,
- unsigned int samp_rate)
+ unsigned int samp_rate,
+ uint32_t *media_type)
{
- uint32_t media_type;
+ int ret = 0;
pr_debug("%s: mode=%d, samp_rate=%d\n", __func__,
mode, samp_rate);
switch (mode) {
case MODE_AMR:
- media_type = VSS_MEDIA_ID_AMR_NB_MODEM;
+ *media_type = VSS_MEDIA_ID_AMR_NB_MODEM;
break;
case MODE_AMR_WB:
- media_type = VSS_MEDIA_ID_AMR_WB_MODEM;
+ *media_type = VSS_MEDIA_ID_AMR_WB_MODEM;
break;
case MODE_PCM:
if (samp_rate == 8000)
- media_type = VSS_MEDIA_ID_PCM_NB;
+ *media_type = VSS_MEDIA_ID_PCM_NB;
else
- media_type = VSS_MEDIA_ID_PCM_WB;
+ *media_type = VSS_MEDIA_ID_PCM_WB;
break;
case MODE_IS127: /* EVRC-A */
- media_type = VSS_MEDIA_ID_EVRC_MODEM;
+ *media_type = VSS_MEDIA_ID_EVRC_MODEM;
break;
case MODE_4GV_NB: /* EVRC-B */
- media_type = VSS_MEDIA_ID_4GV_NB_MODEM;
+ *media_type = VSS_MEDIA_ID_4GV_NB_MODEM;
break;
case MODE_4GV_WB: /* EVRC-WB */
- media_type = VSS_MEDIA_ID_4GV_WB_MODEM;
+ *media_type = VSS_MEDIA_ID_4GV_WB_MODEM;
break;
case MODE_G711:
case MODE_G711A:
if (rate_type == MVS_G711A_MODE_MULAW)
- media_type = VSS_MEDIA_ID_G711_MULAW;
+ *media_type = VSS_MEDIA_ID_G711_MULAW;
else
- media_type = VSS_MEDIA_ID_G711_ALAW;
+ *media_type = VSS_MEDIA_ID_G711_ALAW;
break;
default:
pr_debug(" input mode is not supported\n");
- media_type = -EINVAL;
+ ret = -EINVAL;
}
- pr_debug("%s: media_type is 0x%x\n", __func__, media_type);
+ pr_debug("%s: media_type is 0x%x\n", __func__, *media_type);
- return media_type;
+ return ret;
}
diff --git a/sound/soc/msm/msm8974.c b/sound/soc/msm/msm8974.c
index b7f8714..7c5e599 100644
--- a/sound/soc/msm/msm8974.c
+++ b/sound/soc/msm/msm8974.c
@@ -1041,18 +1041,18 @@
btn_low[0] = -50;
btn_high[0] = 20;
btn_low[1] = 21;
- btn_high[1] = 63;
- btn_low[2] = 64;
- btn_high[2] = 106;
- btn_low[3] = 107;
- btn_high[3] = 146;
- btn_low[4] = 146;
- btn_high[4] = 186;
- btn_low[5] = 187;
- btn_high[5] = 221;
- btn_low[6] = 222;
- btn_high[6] = 253;
- btn_low[7] = 254;
+ btn_high[1] = 61;
+ btn_low[2] = 62;
+ btn_high[2] = 104;
+ btn_low[3] = 105;
+ btn_high[3] = 148;
+ btn_low[4] = 149;
+ btn_high[4] = 189;
+ btn_low[5] = 190;
+ btn_high[5] = 228;
+ btn_low[6] = 229;
+ btn_high[6] = 269;
+ btn_low[7] = 270;
btn_high[7] = 500;
n_ready = wcd9xxx_mbhc_cal_btn_det_mp(btn_cfg, MBHC_BTN_DET_N_READY);
n_ready[0] = 80;
diff --git a/sound/soc/msm/qdsp6v2/audio_ocmem.c b/sound/soc/msm/qdsp6v2/audio_ocmem.c
index 145f095..1969fe8 100644
--- a/sound/soc/msm/qdsp6v2/audio_ocmem.c
+++ b/sound/soc/msm/qdsp6v2/audio_ocmem.c
@@ -30,6 +30,15 @@
#define AUDIO_OCMEM_BUF_SIZE (512 * SZ_1K)
+#define _BIT_MASK_\
+ ((1 << OCMEM_STATE_EXIT) |\
+ (1 << OCMEM_STATE_GROW) |\
+ (1 << OCMEM_STATE_SHRINK))
+
+#define set_bit_pos(x, y) (atomic_set(&x, (atomic_read(&x) | (1 << y))))
+#define clear_bit_pos(x, y) (atomic_set(&x, (atomic_read(&x) & (~(1 << y)))))
+#define test_bit_pos(x, y) ((atomic_read(&x)) & (1 << y))
+
static int enable_ocmem_audio_voice = 1;
module_param(enable_ocmem_audio_voice, int,
S_IRUGO | S_IWUSR | S_IWGRP);
@@ -48,6 +57,8 @@
OCMEM_STATE_MAP_FAIL,
OCMEM_STATE_UNMAP_FAIL,
OCMEM_STATE_EXIT,
+ OCMEM_STATE_SSR,
+ OCMEM_STATE_DISABLE,
};
static void audio_ocmem_process_workdata(struct work_struct *work);
@@ -74,6 +85,7 @@
atomic_t audio_cond;
atomic_t audio_exit;
spinlock_t audio_lock;
+ struct mutex protect_lock;
struct workqueue_struct *audio_ocmem_workqueue;
struct workqueue_struct *voice_ocmem_workqueue;
bool ocmem_en;
@@ -81,7 +93,6 @@
static struct audio_ocmem_prv audio_ocmem_lcl;
-
static int audio_ocmem_client_cb(struct notifier_block *this,
unsigned long event1, void *data)
{
@@ -97,7 +108,9 @@
switch (event1) {
case OCMEM_MAP_DONE:
pr_debug("%s: map done\n", __func__);
- atomic_set(&audio_ocmem_lcl.audio_state, OCMEM_STATE_MAP_COMPL);
+ clear_bit_pos(audio_ocmem_lcl.audio_state,
+ OCMEM_STATE_MAP_TRANSITION);
+ set_bit_pos(audio_ocmem_lcl.audio_state, OCMEM_STATE_MAP_COMPL);
break;
case OCMEM_MAP_FAIL:
pr_debug("%s: map fail\n", __func__);
@@ -105,7 +118,9 @@
break;
case OCMEM_UNMAP_DONE:
pr_debug("%s: unmap done\n", __func__);
- atomic_set(&audio_ocmem_lcl.audio_state,
+ clear_bit_pos(audio_ocmem_lcl.audio_state,
+ OCMEM_STATE_UNMAP_TRANSITION);
+ set_bit_pos(audio_ocmem_lcl.audio_state,
OCMEM_STATE_UNMAP_COMPL);
break;
case OCMEM_UNMAP_FAIL:
@@ -115,13 +130,13 @@
break;
case OCMEM_ALLOC_GROW:
rbuf = data;
- if (rbuf->len == AUDIO_OCMEM_BUF_SIZE) {
+ if ((rbuf->len == AUDIO_OCMEM_BUF_SIZE)) {
audio_ocmem_lcl.buf = data;
pr_debug("%s: Alloc grow request received buf->addr: 0x%08lx\n",
__func__,
(audio_ocmem_lcl.buf)->addr);
- atomic_set(&audio_ocmem_lcl.audio_state,
- OCMEM_STATE_GROW);
+ set_bit_pos(audio_ocmem_lcl.audio_state,
+ OCMEM_STATE_GROW);
} else {
pr_debug("%s: Alloc grow request with size: %ld",
__func__,
@@ -132,19 +147,33 @@
break;
case OCMEM_ALLOC_SHRINK:
pr_debug("%s: Alloc shrink request received\n", __func__);
- atomic_set(&audio_ocmem_lcl.audio_state, OCMEM_STATE_SHRINK);
+ set_bit_pos(audio_ocmem_lcl.audio_state, OCMEM_STATE_SHRINK);
break;
default:
pr_err("%s: Invalid event[%ld]\n", __func__, event1);
break;
}
spin_unlock_irqrestore(&audio_ocmem_lcl.audio_lock, flags);
- if (!vwait && (atomic_read(&audio_ocmem_lcl.audio_cond))) {
atomic_set(&audio_ocmem_lcl.audio_cond, 0);
wake_up(&audio_ocmem_lcl.audio_wait);
- }
return rc;
}
+int get_state_to_process(atomic_t *state)
+{
+
+ if (test_bit_pos((*state), OCMEM_STATE_SHRINK)) {
+ pr_debug("%s: returning shrink state\n", __func__);
+ return OCMEM_STATE_SHRINK;
+ } else if (test_bit_pos((*state), OCMEM_STATE_GROW)) {
+ pr_debug("%s: returning grow state\n", __func__);
+ return OCMEM_STATE_GROW;
+ } else if (test_bit_pos((*state), OCMEM_STATE_EXIT)) {
+ pr_debug("%s: returning exit state\n", __func__);
+ return OCMEM_STATE_EXIT;
+ } else
+ return -EINVAL;
+
+}
/**
* audio_ocmem_enable() - Exercise OCMEM for audio
@@ -159,36 +188,12 @@
{
int ret;
int i, j;
+ int state_bit;
struct ocmem_buf *buf = NULL;
struct avcs_cmd_rsp_get_low_power_segments_info_t *lp_segptr;
pr_debug("%s\n", __func__);
- /* Non-blocking ocmem allocate (asynchronous) */
- buf = ocmem_allocate_nb(cid, AUDIO_OCMEM_BUF_SIZE);
- if (IS_ERR_OR_NULL(buf)) {
- pr_err("%s: failed: %d\n", __func__, cid);
- return -ENOMEM;
- }
- atomic_set(&audio_ocmem_lcl.audio_state, OCMEM_STATE_ALLOC);
-
- audio_ocmem_lcl.buf = buf;
- atomic_set(&audio_ocmem_lcl.audio_exit, 0);
- atomic_set(&audio_ocmem_lcl.audio_cond, 1);
- pr_debug("%s: buf->len: %ld\n", __func__, buf->len);
- if (!buf->len) {
- pr_debug("%s: buf.len is 0, waiting for ocmem region\n",
- __func__);
- wait_event_interruptible(audio_ocmem_lcl.audio_wait,
- (atomic_read(&audio_ocmem_lcl.audio_cond) == 0) ||
- (atomic_read(&audio_ocmem_lcl.audio_exit) == 1));
- if (atomic_read(&audio_ocmem_lcl.audio_exit)) {
- pr_err("%s: audio playback ended while waiting for ocmem\n",
- __func__);
- ret = -EINVAL;
- goto fail_cmd;
- }
- }
- pr_debug("%s: buf->len: %ld\n", __func__, (audio_ocmem_lcl.buf)->len);
+ atomic_set(&audio_ocmem_lcl.audio_state, OCMEM_STATE_DEFAULT);
if (audio_ocmem_lcl.lp_memseg_ptr == NULL) {
/* Retrieve low power segments */
ret = core_get_low_power_segments(
@@ -213,6 +218,42 @@
(uint32_t)audio_ocmem_lcl.mlist.chunks[j].ddr_paddr,
(uint32_t)audio_ocmem_lcl.mlist.chunks[j].size);
}
+ /* Non-blocking ocmem allocate (asynchronous) */
+ buf = ocmem_allocate_nb(cid, AUDIO_OCMEM_BUF_SIZE);
+ if (IS_ERR_OR_NULL(buf)) {
+ pr_err("%s: failed: %d\n", __func__, cid);
+ return -ENOMEM;
+ }
+
+ set_bit_pos(audio_ocmem_lcl.audio_state, OCMEM_STATE_ALLOC);
+
+ audio_ocmem_lcl.buf = buf;
+ atomic_set(&audio_ocmem_lcl.audio_exit, 0);
+ atomic_set(&audio_ocmem_lcl.audio_cond, 1);
+ pr_debug("%s: buf->len: %ld\n", __func__, buf->len);
+ if (!buf->len) {
+ pr_debug("%s: buf.len is 0, waiting for ocmem region\n",
+ __func__);
+ mutex_unlock(&audio_ocmem_lcl.protect_lock);
+ wait_event_interruptible(audio_ocmem_lcl.audio_wait,
+ (atomic_read(&audio_ocmem_lcl.audio_cond) == 0) ||
+ (atomic_read(&audio_ocmem_lcl.audio_exit) == 1));
+ if (atomic_read(&audio_ocmem_lcl.audio_exit)) {
+ ret = ocmem_free(OCMEM_LP_AUDIO, audio_ocmem_lcl.buf);
+ if (ret) {
+ pr_err("%s: ocmem_free failed, state[%d]\n",
+ __func__,
+ atomic_read(&audio_ocmem_lcl.audio_state));
+ }
+ pr_info("%s: audio playback ended while waiting for ocmem\n",
+ __func__);
+ ret = 0;
+ goto fail_cmd;
+ }
+ clear_bit_pos(audio_ocmem_lcl.audio_state, OCMEM_STATE_GROW);
+ mutex_trylock(&audio_ocmem_lcl.protect_lock);
+ }
+ pr_debug("%s: buf->len: %ld\n", __func__, (audio_ocmem_lcl.buf)->len);
/* vote for ocmem bus bandwidth */
ret = msm_bus_scale_client_update_request(
@@ -221,7 +262,7 @@
if (ret)
pr_err("%s: failed to vote for bus bandwidth\n", __func__);
- atomic_set(&audio_ocmem_lcl.audio_state, OCMEM_STATE_MAP_TRANSITION);
+ set_bit_pos(audio_ocmem_lcl.audio_state, OCMEM_STATE_MAP_TRANSITION);
pr_debug("%s: buf->addr: 0x%08lx, len: %ld, audio_state[0x%x]\n",
__func__,
@@ -236,16 +277,25 @@
atomic_set(&audio_ocmem_lcl.audio_state, OCMEM_STATE_MAP_FAIL);
}
+ wait_event_interruptible(audio_ocmem_lcl.audio_wait,
+ test_bit_pos(audio_ocmem_lcl.audio_state,
+ OCMEM_STATE_MAP_COMPL) != 0);
+ atomic_set(&audio_ocmem_lcl.audio_cond, 1);
+
+ mutex_unlock(&audio_ocmem_lcl.protect_lock);
pr_debug("%s: audio_cond[%d] audio_state[0x%x]\n", __func__,
atomic_read(&audio_ocmem_lcl.audio_cond),
atomic_read(&audio_ocmem_lcl.audio_state));
- while ((atomic_read(&audio_ocmem_lcl.audio_state) !=
- OCMEM_STATE_EXIT)) {
+
+ while ((test_bit_pos(audio_ocmem_lcl.audio_state,
+ OCMEM_STATE_DISABLE)) == 0) {
wait_event_interruptible(audio_ocmem_lcl.audio_wait,
- atomic_read(&audio_ocmem_lcl.audio_cond) == 0);
+ (atomic_read(&audio_ocmem_lcl.audio_state) &
+ _BIT_MASK_) != 0);
- switch (atomic_read(&audio_ocmem_lcl.audio_state)) {
+ state_bit = get_state_to_process(&audio_ocmem_lcl.audio_state);
+ switch (state_bit) {
case OCMEM_STATE_MAP_COMPL:
pr_debug("%s: audio_cond[0x%x], audio_state[0x%x]\n",
__func__, atomic_read(&audio_ocmem_lcl.audio_cond),
@@ -258,6 +308,10 @@
pr_debug("%s: ocmem shrink request process\n",
__func__);
atomic_set(&audio_ocmem_lcl.audio_cond, 1);
+ clear_bit_pos(audio_ocmem_lcl.audio_state,
+ OCMEM_STATE_MAP_COMPL);
+ set_bit_pos(audio_ocmem_lcl.audio_state,
+ OCMEM_STATE_UNMAP_TRANSITION);
ret = ocmem_unmap(cid, audio_ocmem_lcl.buf,
&audio_ocmem_lcl.mlist);
if (ret) {
@@ -267,12 +321,9 @@
goto fail_cmd;
}
- atomic_set(&audio_ocmem_lcl.audio_state,
- OCMEM_STATE_UNMAP_TRANSITION);
wait_event_interruptible(audio_ocmem_lcl.audio_wait,
- atomic_read(&audio_ocmem_lcl.audio_cond) == 0);
- atomic_set(&audio_ocmem_lcl.audio_state,
- OCMEM_STATE_UNMAP_COMPL);
+ test_bit_pos(audio_ocmem_lcl.audio_state,
+ OCMEM_STATE_UNMAP_COMPL) != 0);
ret = ocmem_shrink(cid, audio_ocmem_lcl.buf, 0);
if (ret) {
pr_err("%s: ocmem_shrink failed, state[%d]\n",
@@ -281,11 +332,18 @@
goto fail_cmd;
}
atomic_set(&audio_ocmem_lcl.audio_cond, 1);
+ clear_bit_pos(audio_ocmem_lcl.audio_state,
+ OCMEM_STATE_SHRINK);
+ pr_debug("%s:shrink process complete\n", __func__);
break;
case OCMEM_STATE_GROW:
pr_debug("%s: ocmem grow request process\n",
__func__);
atomic_set(&audio_ocmem_lcl.audio_cond, 1);
+ clear_bit_pos(audio_ocmem_lcl.audio_state,
+ OCMEM_STATE_UNMAP_COMPL);
+ set_bit_pos(audio_ocmem_lcl.audio_state,
+ OCMEM_STATE_MAP_TRANSITION);
ret = ocmem_map(cid, audio_ocmem_lcl.buf,
&audio_ocmem_lcl.mlist);
if (ret) {
@@ -294,14 +352,102 @@
atomic_read(&audio_ocmem_lcl.audio_state));
goto fail_cmd;
}
- atomic_set(&audio_ocmem_lcl.audio_state,
- OCMEM_STATE_MAP_TRANSITION);
wait_event_interruptible(audio_ocmem_lcl.audio_wait,
- atomic_read(&audio_ocmem_lcl.audio_cond) == 0);
- atomic_set(&audio_ocmem_lcl.audio_state,
- OCMEM_STATE_MAP_COMPL);
+ test_bit_pos(audio_ocmem_lcl.audio_state,
+ OCMEM_STATE_MAP_COMPL) != 0);
+
+ clear_bit_pos(audio_ocmem_lcl.audio_state,
+ OCMEM_STATE_GROW);
atomic_set(&audio_ocmem_lcl.audio_cond, 1);
break;
+ case OCMEM_STATE_EXIT:
+ if (test_bit_pos(audio_ocmem_lcl.audio_state,
+ OCMEM_STATE_MAP_COMPL)) {
+ clear_bit_pos(audio_ocmem_lcl.audio_state,
+ OCMEM_STATE_MAP_COMPL);
+ set_bit_pos(audio_ocmem_lcl.audio_state,
+ OCMEM_STATE_UNMAP_TRANSITION);
+ ret = ocmem_unmap(cid, audio_ocmem_lcl.buf,
+ &audio_ocmem_lcl.mlist);
+ if (ret) {
+ pr_err("%s: ocmem_unmap failed, state[0x%x]\n",
+ __func__,
+ atomic_read(&audio_ocmem_lcl.audio_state));
+ goto fail_cmd;
+ }
+ wait_event_interruptible(
+ audio_ocmem_lcl.audio_wait,
+ test_bit_pos(audio_ocmem_lcl.audio_state,
+ OCMEM_STATE_UNMAP_COMPL) != 0);
+ }
+
+ if (test_bit_pos(audio_ocmem_lcl.audio_state,
+ OCMEM_STATE_SHRINK)) {
+ pr_debug("%s: SHRINK while exiting\n",
+ __func__);
+ ret = ocmem_shrink(cid, audio_ocmem_lcl.buf,
+ 0);
+ if (ret) {
+ pr_err("%s: ocmem_shrink failed, state[0x%x]\n",
+ __func__,
+ atomic_read(&audio_ocmem_lcl.audio_state));
+ goto fail_cmd;
+ }
+ clear_bit_pos(audio_ocmem_lcl.audio_state,
+ OCMEM_STATE_SHRINK);
+
+ }
+
+ pr_debug("%s: calling ocmem free\n", __func__);
+ ret = ocmem_free(OCMEM_LP_AUDIO, audio_ocmem_lcl.buf);
+ if (ret == -EAGAIN) {
+ pr_debug("%s: received EAGAIN\n", __func__);
+ if (test_bit_pos(audio_ocmem_lcl.audio_state,
+ OCMEM_STATE_SHRINK)) {
+ ret = ocmem_shrink(cid,
+ audio_ocmem_lcl.buf,
+ 0);
+ if (ret) {
+ pr_err("%s: ocmem_shrink failed, state[0x%x]\n",
+ __func__,
+ atomic_read(&audio_ocmem_lcl.audio_state));
+ goto fail_cmd;
+ }
+ pr_debug("calling free after EAGAIN");
+ ret = ocmem_free(OCMEM_LP_AUDIO,
+ audio_ocmem_lcl.buf);
+ if (ret) {
+ pr_err("%s: ocmem_free failed\n",
+ __func__);
+ goto fail_cmd;
+ }
+ } else {
+ pr_debug("%s: shrink callback already processed\n",
+ __func__);
+ goto fail_cmd;
+ }
+ } else if (ret) {
+ pr_err("%s: ocmem_free failed, state[0x%x], ret:%d\n",
+ __func__,
+ atomic_read(&audio_ocmem_lcl.audio_state),
+ ret);
+ goto fail_cmd;
+ }
+ pr_debug("%s: ocmem_free success\n", __func__);
+ msm_bus_scale_client_update_request(
+ audio_ocmem_lcl.audio_ocmem_bus_client,
+ 0);
+ set_bit_pos(audio_ocmem_lcl.audio_state,
+ OCMEM_STATE_DISABLE);
+ break;
+
+
+ case -EINVAL:
+ pr_info("%s: audio_cond[%d] audio_state[0x%x]\n",
+ __func__,
+ atomic_read(&audio_ocmem_lcl.audio_cond),
+ atomic_read(&audio_ocmem_lcl.audio_state));
+ break;
}
}
ret = 0;
@@ -320,64 +466,17 @@
*/
int audio_ocmem_disable(int cid)
{
- int ret;
- int cur_state;
-
- pr_debug("%s: disable\n", __func__);
- cur_state = atomic_read(&audio_ocmem_lcl.audio_state);
- if (atomic_cmpxchg(&audio_ocmem_lcl.audio_cond, 1, 0)) {
- atomic_set(&audio_ocmem_lcl.audio_state, OCMEM_STATE_EXIT);
- wake_up(&audio_ocmem_lcl.audio_wait);
- }
pr_debug("%s: audio_cond[0x%x], audio_state[0x%x]\n", __func__,
atomic_read(&audio_ocmem_lcl.audio_cond),
atomic_read(&audio_ocmem_lcl.audio_state));
- switch (cur_state) {
- case OCMEM_STATE_MAP_COMPL:
- atomic_set(&audio_ocmem_lcl.audio_cond, 1);
- ret = ocmem_unmap(cid, audio_ocmem_lcl.buf,
- &audio_ocmem_lcl.mlist);
- if (ret) {
- pr_err("%s: ocmem_unmap failed, state[%d]\n",
- __func__,
- atomic_read(&audio_ocmem_lcl.audio_state));
- goto fail_cmd;
- }
+ set_bit_pos(audio_ocmem_lcl.audio_state,
+ OCMEM_STATE_EXIT);
+ wake_up(&audio_ocmem_lcl.audio_wait);
- atomic_set(&audio_ocmem_lcl.audio_state, OCMEM_STATE_EXIT);
-
- wait_event_interruptible(audio_ocmem_lcl.audio_wait,
- atomic_read(&audio_ocmem_lcl.audio_cond) == 0);
- case OCMEM_STATE_UNMAP_COMPL:
- case OCMEM_STATE_MAP_FAIL:
- case OCMEM_STATE_MAP_TRANSITION:
- case OCMEM_STATE_ALLOC:
- ret = ocmem_free(OCMEM_LP_AUDIO, audio_ocmem_lcl.buf);
- if (ret) {
- pr_err("%s: ocmem_free failed, state[%d]\n",
- __func__,
- atomic_read(&audio_ocmem_lcl.audio_state));
- goto fail_cmd;
- }
- pr_debug("%s: state=%d", __func__,
- atomic_read(&audio_ocmem_lcl.audio_state));
- atomic_set(&audio_ocmem_lcl.audio_state, OCMEM_STATE_EXIT);
- pr_debug("%s: ocmem_free success\n", __func__);
- break;
-
- default:
- pr_debug("%s:error: state=%d", __func__,
- atomic_read(&audio_ocmem_lcl.audio_state));
- break;
-
- }
- msm_bus_scale_client_update_request(
- audio_ocmem_lcl.audio_ocmem_bus_client,
- 0);
+ mutex_unlock(&audio_ocmem_lcl.protect_lock);
+ pr_debug("%s: exit\n", __func__);
return 0;
-fail_cmd:
- return ret;
}
static void voice_ocmem_process_workdata(struct work_struct *work)
@@ -497,6 +596,10 @@
container_of(work, struct audio_ocmem_workdata, work);
en = audio_ocm_work->en;
+ mutex_lock(&audio_ocmem_lcl.protect_lock);
+ /* if previous work waiting for ocmem - signal it to exit */
+ atomic_set(&audio_ocmem_lcl.audio_exit, 1);
+ pr_debug("%s: acquired mutex for %d\n", __func__, en);
switch (audio_ocm_work->id) {
case AUDIO:
cid = OCMEM_LP_AUDIO;
@@ -548,9 +651,6 @@
workdata->id = id;
workdata->en = enable;
- /* if previous work waiting for ocmem - signal it to exit */
- atomic_set(&audio_ocmem_lcl.audio_exit, 1);
-
INIT_WORK(&workdata->work, audio_ocmem_process_workdata);
queue_work(audio_ocmem_lcl.audio_ocmem_workqueue,
&workdata->work);
@@ -611,6 +711,7 @@
atomic_set(&audio_ocmem_lcl.audio_state, OCMEM_STATE_DEFAULT);
atomic_set(&audio_ocmem_lcl.audio_exit, 0);
spin_lock_init(&audio_ocmem_lcl.audio_lock);
+ mutex_init(&audio_ocmem_lcl.protect_lock);
audio_ocmem_lcl.ocmem_en = true;
/* populate platform data */
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c
index 49f1d70..b5ce28f 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.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
@@ -140,7 +140,8 @@
};
static int voip_get_media_type(uint32_t mode,
- unsigned int samp_rate);
+ unsigned int samp_rate,
+ unsigned int *media_type);
static int voip_get_rate_type(uint32_t mode,
uint32_t rate,
uint32_t *rate_type);
@@ -782,11 +783,11 @@
goto done;
}
prtd->rate_type = rate_type;
- media_type = voip_get_media_type(prtd->mode,
- prtd->play_samp_rate);
- if (media_type < 0) {
+ ret = voip_get_media_type(prtd->mode,
+ prtd->play_samp_rate,
+ &media_type);
+ if (ret < 0) {
pr_err("fail at getting media_type\n");
- ret = -EINVAL;
goto done;
}
pr_debug(" media_type=%d, rate_type=%d\n", media_type,
@@ -1058,42 +1059,43 @@
}
static int voip_get_media_type(uint32_t mode,
- unsigned int samp_rate)
+ unsigned int samp_rate,
+ unsigned int *media_type)
{
- uint32_t media_type;
+ int ret = 0;
pr_debug("%s: mode=%d, samp_rate=%d\n", __func__,
mode, samp_rate);
switch (mode) {
case MODE_AMR:
- media_type = VSS_MEDIA_ID_AMR_NB_MODEM;
+ *media_type = VSS_MEDIA_ID_AMR_NB_MODEM;
break;
case MODE_AMR_WB:
- media_type = VSS_MEDIA_ID_AMR_WB_MODEM;
+ *media_type = VSS_MEDIA_ID_AMR_WB_MODEM;
break;
case MODE_PCM:
if (samp_rate == 8000)
- media_type = VSS_MEDIA_ID_PCM_NB;
+ *media_type = VSS_MEDIA_ID_PCM_NB;
else
- media_type = VSS_MEDIA_ID_PCM_WB;
+ *media_type = VSS_MEDIA_ID_PCM_WB;
break;
case MODE_IS127: /* EVRC-A */
- media_type = VSS_MEDIA_ID_EVRC_MODEM;
+ *media_type = VSS_MEDIA_ID_EVRC_MODEM;
break;
case MODE_4GV_NB: /* EVRC-B */
- media_type = VSS_MEDIA_ID_4GV_NB_MODEM;
+ *media_type = VSS_MEDIA_ID_4GV_NB_MODEM;
break;
case MODE_4GV_WB: /* EVRC-WB */
- media_type = VSS_MEDIA_ID_4GV_WB_MODEM;
+ *media_type = VSS_MEDIA_ID_4GV_WB_MODEM;
break;
default:
pr_debug(" input mode is not supported\n");
- media_type = -EINVAL;
+ ret = -EINVAL;
}
- pr_debug("%s: media_type is 0x%x\n", __func__, media_type);
+ pr_debug("%s: media_type is 0x%x\n", __func__, *media_type);
- return media_type;
+ return ret;
}