Merge "arm/dt: msm8974: Use corner voltages for VDDCX"
diff --git a/Documentation/devicetree/bindings/input/touchscreen/synaptics_i2c_rmi4.txt b/Documentation/devicetree/bindings/input/touchscreen/synaptics_i2c_rmi4.txt
index b31ec30..d24139b 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/synaptics_i2c_rmi4.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/synaptics_i2c_rmi4.txt
@@ -20,6 +20,7 @@
- synaptics,y-flip : modify orientation of the y axis
- synaptics,panel-x : panel x dimension
- synaptics,panel-y : panel y dimension
+ - synaptics,fw-image-name : name of firmware .img file in /etc/firmware
Example:
i2c@f9927000 { /* BLSP1 QUP5 */
diff --git a/arch/arm/boot/dts/msm8226-pm.dtsi b/arch/arm/boot/dts/msm8226-pm.dtsi
index 99f0631..329439e 100644
--- a/arch/arm/boot/dts/msm8226-pm.dtsi
+++ b/arch/arm/boot/dts/msm8226-pm.dtsi
@@ -157,6 +157,8 @@
qcom,vdd-mem-lower-bound = <3>; /* NORMAL */
qcom,vdd-dig-upper-bound = <5>; /* SUPER TURBO */
qcom,vdd-dig-lower-bound = <3>; /* NORMAL */
+ qcom,irqs-detectable;
+ qcom,gpio-detectable;
qcom,latency-us = <1>;
qcom,ss-power = <784>;
qcom,energy-overhead = <190000>;
@@ -165,22 +167,6 @@
qcom,lpm-level@1 {
reg = <0x1>;
- qcom,mode = "retention";
- qcom,xo = "xo_on";
- qcom,l2 = "l2_cache_active";
- qcom,vdd-mem-upper-bound = <5>; /* SUPER TURBO */
- qcom,vdd-mem-lower-bound = <3>; /* NORMAL */
- qcom,vdd-dig-upper-bound = <5>; /* SUPER TURBO */
- qcom,vdd-dig-lower-bound = <3>; /* NORMAL */
- qcom,latency-us = <75>;
- qcom,ss-power = <735>;
- qcom,energy-overhead = <77341>;
- qcom,time-overhead = <105>;
- };
-
-
- qcom,lpm-level@2 {
- reg = <0x2>;
qcom,mode = "standalone_pc";
qcom,xo = "xo_on";
qcom,l2 = "l2_cache_active";
@@ -188,29 +174,33 @@
qcom,vdd-mem-lower-bound = <3>; /* NORMAL */
qcom,vdd-dig-upper-bound = <5>; /* SUPER TURBO */
qcom,vdd-dig-lower-bound = <3>; /* NORMAL */
- qcom,latency-us = <95>;
+ qcom,irqs-detectable;
+ qcom,gpio-detectable;
+ qcom,latency-us = <3000>;
qcom,ss-power = <725>;
qcom,energy-overhead = <99500>;
- qcom,time-overhead = <130>;
+ qcom,time-overhead = <3130>;
};
- qcom,lpm-level@3 {
- reg = <0x3>;
+ qcom,lpm-level@2 {
+ reg = <0x2>;
qcom,mode = "pc";
qcom,xo = "xo_on";
- qcom,l2 = "l2_cache_gdhs";
+ qcom,l2 = "l2_cache_retention";
qcom,vdd-mem-upper-bound = <5>; /* SUPER TURBO */
qcom,vdd-mem-lower-bound = <3>; /* NORMAL */
qcom,vdd-dig-upper-bound = <5>; /* SUPER TURBO */
qcom,vdd-dig-lower-bound = <3>; /* NORMAL */
- qcom,latency-us = <2000>;
+ qcom,irqs-detectable;
+ qcom,gpio-detectable;
+ qcom,latency-us = <8000>;
qcom,ss-power = <138>;
qcom,energy-overhead = <1208400>;
- qcom,time-overhead = <3200>;
+ qcom,time-overhead = <9200>;
};
- qcom,lpm-level@4 {
- reg = <0x4>;
+ qcom,lpm-level@3 {
+ reg = <0x3>;
qcom,mode = "pc";
qcom,xo = "xo_on";
qcom,l2 = "l2_cache_pc";
@@ -218,25 +208,42 @@
qcom,vdd-mem-lower-bound = <2>; /* SVS SOC */
qcom,vdd-dig-upper-bound = <3>; /* NORMAL */
qcom,vdd-dig-lower-bound = <2>; /* SVS SOC */
- qcom,latency-us = <3000>;
+ qcom,irqs-detectable;
+ qcom,gpio-detectable;
+ qcom,latency-us = <9000>;
qcom,ss-power = <110>;
qcom,energy-overhead = <1250300>;
- qcom,time-overhead = <3500>;
+ qcom,time-overhead = <9500>;
+ };
+
+ qcom,lpm-level@4 {
+ reg = <0x4>;
+ qcom,mode = "pc";
+ qcom,xo = "xo_off";
+ qcom,l2 = "l2_cache_pc";
+ qcom,vdd-mem-upper-bound = <5>; /* SUPER TURBO */
+ qcom,vdd-mem-lower-bound = <3>; /* NORMAL */
+ qcom,vdd-dig-upper-bound = <5>; /* SUPER TURBO */
+ qcom,vdd-dig-lower-bound = <3>; /* NORMAL */
+ qcom,latency-us = <16300>;
+ qcom,ss-power = <63>;
+ qcom,energy-overhead = <2128000>;
+ qcom,time-overhead = <24200>;
};
qcom,lpm-level@5 {
reg = <0x5>;
qcom,mode = "pc";
qcom,xo = "xo_off";
- qcom,l2 = "l2_cache_gdhs";
- qcom,vdd-mem-upper-bound = <5>; /* SUPER TURBO */
- qcom,vdd-mem-lower-bound = <3>; /* NORMAL */
- qcom,vdd-dig-upper-bound = <5>; /* SUPER TURBO */
- qcom,vdd-dig-lower-bound = <3>; /* NORMAL */
- qcom,latency-us = <3000>;
- qcom,ss-power = <68>;
- qcom,energy-overhead = <1350200>;
- qcom,time-overhead = <4000>;
+ qcom,l2 = "l2_cache_pc";
+ qcom,vdd-mem-upper-bound = <3>; /* NORMAL */
+ qcom,vdd-mem-lower-bound = <2>; /* SVS SOC */
+ qcom,vdd-dig-upper-bound = <3>; /* NORMAL */
+ qcom,vdd-dig-lower-bound = <2>; /* SVS SOC */
+ qcom,latency-us = <24000>;
+ qcom,ss-power = <10>;
+ qcom,energy-overhead = <3202600>;
+ qcom,time-overhead = <33000>;
};
qcom,lpm-level@6 {
@@ -244,44 +251,14 @@
qcom,mode = "pc";
qcom,xo = "xo_off";
qcom,l2 = "l2_cache_pc";
- qcom,vdd-mem-upper-bound = <5>; /* SUPER TURBO */
- qcom,vdd-mem-lower-bound = <3>; /* NORMAL */
- qcom,vdd-dig-upper-bound = <5>; /* SUPER TURBO */
- qcom,vdd-dig-lower-bound = <3>; /* NORMAL */
- qcom,latency-us = <10300>;
- qcom,ss-power = <63>;
- qcom,energy-overhead = <2128000>;
- qcom,time-overhead = <18200>;
- };
-
- qcom,lpm-level@7 {
- reg = <0x7>;
- qcom,mode = "pc";
- qcom,xo = "xo_off";
- qcom,l2 = "l2_cache_pc";
- qcom,vdd-mem-upper-bound = <3>; /* NORMAL */
- qcom,vdd-mem-lower-bound = <2>; /* SVS SOC */
- qcom,vdd-dig-upper-bound = <3>; /* NORMAL */
- qcom,vdd-dig-lower-bound = <2>; /* SVS SOC */
- qcom,latency-us = <18000>;
- qcom,ss-power = <10>;
- qcom,energy-overhead = <3202600>;
- qcom,time-overhead = <27000>;
- };
-
- qcom,lpm-level@8 {
- reg = <0x8>;
- qcom,mode = "pc";
- qcom,xo = "xo_off";
- qcom,l2 = "l2_cache_pc";
qcom,vdd-mem-upper-bound = <2>; /* SVS SOC */
qcom,vdd-mem-lower-bound = <0>; /* RETENTION */
qcom,vdd-dig-upper-bound = <2>; /* SVS SOC */
qcom,vdd-dig-lower-bound = <0>; /* RETENTION */
- qcom,latency-us = <20000>;
+ qcom,latency-us = <26000>;
qcom,ss-power = <2>;
qcom,energy-overhead = <4252000>;
- qcom,time-overhead = <32000>;
+ qcom,time-overhead = <38000>;
};
};
diff --git a/arch/arm/boot/dts/msm8610-pm.dtsi b/arch/arm/boot/dts/msm8610-pm.dtsi
index 27af9a9..c3adb2c 100644
--- a/arch/arm/boot/dts/msm8610-pm.dtsi
+++ b/arch/arm/boot/dts/msm8610-pm.dtsi
@@ -21,13 +21,13 @@
qcom,core-id = <0>;
qcom,saw2-ver-reg = <0xfd0>;
qcom,saw2-cfg = <0x01>;
- qcom,saw2-spm-dly= <0x20000400>;
- qcom,saw2-spm-ctl = <0x1>;
- qcom,saw2-spm-cmd-wfi = [60 03 60 76 76 0b 0f];
- qcom,saw2-spm-cmd-spc = [00 20 10 80 90 5b 60 03 60 3b 76 76 94
- 5b 80 10 2b 30 06 26 30 0f];
- qcom,saw2-spm-cmd-pc = [00 20 10 80 90 5b 60 07 3b 76 76 0b 94
- 5b 80 10 2b 30 06 26 30 0f];
+ qcom,saw2-spm-dly= <0x3c102800>;
+ qcom,saw2-spm-ctl = <0x0>;
+ qcom,saw2-spm-cmd-wfi = [60 03 60 0b 0f];
+ qcom,saw2-spm-cmd-spc = [00 20 10 80 30 90 5b 60 03 60 3b 76 76
+ 0b 94 5b 80 10 06 26 30 0f];
+ qcom,saw2-spm-cmd-pc = [00 20 10 80 30 90 5b 60 07 60 3b 76 76
+ 0b 94 5b 80 10 06 26 30 0f];
};
qcom,spm@f9099000 {
@@ -38,13 +38,13 @@
qcom,core-id = <1>;
qcom,saw2-ver-reg = <0xfd0>;
qcom,saw2-cfg = <0x01>;
- qcom,saw2-spm-dly= <0x20000400>;
- qcom,saw2-spm-ctl = <0x1>;
- qcom,saw2-spm-cmd-wfi = [60 03 60 76 76 0b 0f];
- qcom,saw2-spm-cmd-spc = [00 20 10 80 90 5b 60 03 60 3b 76 76 94
- 5b 80 10 2b 30 06 26 30 0f];
- qcom,saw2-spm-cmd-pc = [00 20 10 80 90 5b 60 07 3b 76 76 0b 94
- 5b 80 10 2b 30 06 26 30 0f];
+ qcom,saw2-spm-dly= <0x3c102800>;
+ qcom,saw2-spm-ctl = <0x0>;
+ qcom,saw2-spm-cmd-wfi = [60 03 60 0b 0f];
+ qcom,saw2-spm-cmd-spc = [00 20 10 80 30 90 5b 60 03 60 3b 76 76
+ 0b 94 5b 80 10 06 26 30 0f];
+ qcom,saw2-spm-cmd-pc = [00 20 10 80 30 90 5b 60 07 60 3b 76 76
+ 0b 94 5b 80 10 06 26 30 0f];
};
qcom,spm@f90a9000 {
@@ -55,13 +55,13 @@
qcom,core-id = <2>;
qcom,saw2-ver-reg = <0xfd0>;
qcom,saw2-cfg = <0x01>;
- qcom,saw2-spm-dly= <0x20000400>;
- qcom,saw2-spm-ctl = <0x1>;
- qcom,saw2-spm-cmd-wfi = [60 03 60 76 76 0b 0f];
- qcom,saw2-spm-cmd-spc = [00 20 10 80 90 5b 60 03 60 3b 76 76 94
- 5b 80 10 2b 30 06 26 30 0f];
- qcom,saw2-spm-cmd-pc = [00 20 10 80 90 5b 60 07 3b 76 76 0b 94
- 5b 80 10 2b 30 06 26 30 0f];
+ qcom,saw2-spm-dly= <0x3c102800>;
+ qcom,saw2-spm-ctl = <0x0>;
+ qcom,saw2-spm-cmd-wfi = [60 03 60 0b 0f];
+ qcom,saw2-spm-cmd-spc = [00 20 10 80 30 90 5b 60 03 60 3b 76 76
+ 0b 94 5b 80 10 06 26 30 0f];
+ qcom,saw2-spm-cmd-pc = [00 20 10 80 30 90 5b 60 07 60 3b 76 76
+ 0b 94 5b 80 10 06 26 30 0f];
};
qcom,spm@f90b9000 {
@@ -72,13 +72,13 @@
qcom,core-id = <3>;
qcom,saw2-ver-reg = <0xfd0>;
qcom,saw2-cfg = <0x01>;
- qcom,saw2-spm-dly= <0x20000400>;
- qcom,saw2-spm-ctl = <0x1>;
- qcom,saw2-spm-cmd-wfi = [60 03 60 76 76 0b 0f];
- qcom,saw2-spm-cmd-spc = [00 20 10 80 90 5b 60 03 60 3b 76 76 94
- 5b 80 10 2b 30 06 26 30 0f];
- qcom,saw2-spm-cmd-pc = [00 20 10 80 90 5b 60 07 3b 76 76 0b 94
- 5b 80 10 2b 30 06 26 30 0f];
+ qcom,saw2-spm-dly= <0x3c102800>;
+ qcom,saw2-spm-ctl = <0x0>;
+ qcom,saw2-spm-cmd-wfi = [60 03 60 0b 0f];
+ qcom,saw2-spm-cmd-spc = [00 20 10 80 30 90 5b 60 03 60 3b 76 76
+ 0b 94 5b 80 10 06 26 30 0f];
+ qcom,saw2-spm-cmd-pc = [00 20 10 80 30 90 5b 60 07 60 3b 76 76
+ 0b 94 5b 80 10 06 26 30 0f];
};
qcom,spm@f9012000 {
@@ -89,21 +89,18 @@
qcom,core-id = <0xffff>; /* L2/APCS SAW */
qcom,saw2-ver-reg = <0xfd0>;
qcom,saw2-cfg = <0x14>;
- qcom,saw2-spm-dly= <0x20000400>;
- qcom,saw2-spm-ctl = <0x1>;
+ qcom,saw2-spm-dly= <0x3c102800>;
+ qcom,saw2-spm-ctl = <0x0>;
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 = [0b 00 03 00 7b 0f];
- qcom,saw2-spm-cmd-gdhs = [00 20 32 60 70 80 0b 6b c0 e0 d0 42 07
- 78 1f 80 4e d0 e0 c0 22 6b 50 4b 60 02 32 50 7b
- 0f];
- qcom,saw2-spm-cmd-pc = [00 32 60 70 80 b0 0b 10 e0 d0 6b c0
- 42 f0 11 07 01 b0 78 1f 80 4e c0 d0 12 e0 6b 50 4b
- 60 02 32 50 f0 7b 0f]; /*APCS_PMIC_OFF_L2RAM_OFF*/
+ qcom,saw2-spm-cmd-ret = [00 03 00 7b 0f];
+ qcom,saw2-spm-cmd-pc = [00 32 b0 10 e0 d0 6b c0 42 f0
+ 11 07 01 b0 4e c0 d0 12 e0 6b 50 02 32
+ 50 f0 7b 0f]; /*APCS_PMIC_OFF_L2RAM_OFF*/
};
qcom,lpm-resources {
@@ -114,8 +111,8 @@
qcom,lpm-resources@0 {
reg = <0x0>;
qcom,name = "vdd-dig";
- qcom,type = <0x62706d73>; /* "smpb" */
- qcom,id = <0x02>;
+ qcom,type = <0x61706d73>; /* "smpa" */
+ qcom,id = <0x01>;
qcom,key = <0x6e726f63>; /* "corn" */
qcom,init-value = <5>; /* Super Turbo */
};
@@ -123,10 +120,10 @@
qcom,lpm-resources@1 {
reg = <0x1>;
qcom,name = "vdd-mem";
- qcom,type = <0x62706d73>; /* "smpb" */
- qcom,id = <0x01>;
- qcom,key = <0x7675>; /* "uv" */
- qcom,init-value = <1050000>; /* Super Turbo */
+ qcom,type = <0x616F646C>; /* "ldoa" */
+ qcom,id = <0x03>;
+ qcom,key = <0x6e726f63>; /* "corn" */
+ qcom,init-value = <3>; /* Active */
};
qcom,lpm-resources@2 {
@@ -156,10 +153,10 @@
qcom,mode = "wfi";
qcom,xo = "xo_on";
qcom,l2 = "l2_cache_active";
- qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
- qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
- qcom,vdd-dig-upper-bound = <5>; /* MAX */
- qcom,vdd-dig-lower-bound = <3>; /* ACTIVE */
+ qcom,vdd-mem-upper-bound = <5>; /* SUPER TURBO */
+ qcom,vdd-mem-lower-bound = <3>; /* NORMAL */
+ qcom,vdd-dig-upper-bound = <5>; /* SUPER TURBO */
+ qcom,vdd-dig-lower-bound = <3>; /* NORMAL */
qcom,latency-us = <1>;
qcom,ss-power = <784>;
qcom,energy-overhead = <190000>;
@@ -171,10 +168,10 @@
qcom,mode = "retention";
qcom,xo = "xo_on";
qcom,l2 = "l2_cache_active";
- qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
- qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
- qcom,vdd-dig-upper-bound = <5>; /* MAX */
- qcom,vdd-dig-lower-bound = <3>; /* ACTIVE */
+ qcom,vdd-mem-upper-bound = <5>; /* SUPER TURBO */
+ qcom,vdd-mem-lower-bound = <3>; /* NORMAL */
+ qcom,vdd-dig-upper-bound = <5>; /* SUPER TURBO */
+ qcom,vdd-dig-lower-bound = <3>; /* NORMAL */
qcom,latency-us = <75>;
qcom,ss-power = <735>;
qcom,energy-overhead = <77341>;
@@ -187,10 +184,10 @@
qcom,mode = "standalone_pc";
qcom,xo = "xo_on";
qcom,l2 = "l2_cache_active";
- qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
- qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
- qcom,vdd-dig-upper-bound = <5>; /* MAX */
- qcom,vdd-dig-lower-bound = <3>; /* ACTIVE */
+ qcom,vdd-mem-upper-bound = <5>; /* SUPER TURBO */
+ qcom,vdd-mem-lower-bound = <3>; /* NORMAL */
+ qcom,vdd-dig-upper-bound = <5>; /* SUPER TURBO */
+ qcom,vdd-dig-lower-bound = <3>; /* NORMAL */
qcom,latency-us = <95>;
qcom,ss-power = <725>;
qcom,energy-overhead = <99500>;
@@ -202,10 +199,10 @@
qcom,mode = "pc";
qcom,xo = "xo_on";
qcom,l2 = "l2_cache_gdhs";
- qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
- qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
- qcom,vdd-dig-upper-bound = <5>; /* MAX */
- qcom,vdd-dig-lower-bound = <3>; /* ACTIVE */
+ qcom,vdd-mem-upper-bound = <5>; /* SUPER TURBO */
+ qcom,vdd-mem-lower-bound = <3>; /* NORMAL */
+ qcom,vdd-dig-upper-bound = <5>; /* SUPER TURBO */
+ qcom,vdd-dig-lower-bound = <3>; /* NORMAL */
qcom,latency-us = <2000>;
qcom,ss-power = <138>;
qcom,energy-overhead = <1208400>;
@@ -217,10 +214,10 @@
qcom,mode = "pc";
qcom,xo = "xo_on";
qcom,l2 = "l2_cache_pc";
- qcom,vdd-mem-upper-bound = <1050000>; /* ACTIVE */
- qcom,vdd-mem-lower-bound = <750000>; /* RETENTION HIGH */
- qcom,vdd-dig-upper-bound = <3>; /* ACTIVE */
- qcom,vdd-dig-lower-bound = <2>; /* RETENTION HIGH */
+ qcom,vdd-mem-upper-bound = <3>; /* NORMAL */
+ qcom,vdd-mem-lower-bound = <2>; /* SVS SOC */
+ qcom,vdd-dig-upper-bound = <3>; /* NORMAL */
+ qcom,vdd-dig-lower-bound = <2>; /* SVS SOC */
qcom,latency-us = <3000>;
qcom,ss-power = <110>;
qcom,energy-overhead = <1250300>;
@@ -232,10 +229,10 @@
qcom,mode = "pc";
qcom,xo = "xo_off";
qcom,l2 = "l2_cache_gdhs";
- qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
- qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
- qcom,vdd-dig-upper-bound = <5>; /* MAX */
- qcom,vdd-dig-lower-bound = <3>; /* ACTIVE */
+ qcom,vdd-mem-upper-bound = <5>; /* SUPER TURBO */
+ qcom,vdd-mem-lower-bound = <3>; /* NORMAL */
+ qcom,vdd-dig-upper-bound = <5>; /* SUPER TURBO */
+ qcom,vdd-dig-lower-bound = <3>; /* NORMAL */
qcom,latency-us = <3000>;
qcom,ss-power = <68>;
qcom,energy-overhead = <1350200>;
@@ -247,10 +244,10 @@
qcom,mode = "pc";
qcom,xo = "xo_off";
qcom,l2 = "l2_cache_pc";
- qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
- qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
- qcom,vdd-dig-upper-bound = <5>; /* MAX */
- qcom,vdd-dig-lower-bound = <3>; /* ACTIVE */
+ qcom,vdd-mem-upper-bound = <5>; /* SUPER TURBO */
+ qcom,vdd-mem-lower-bound = <3>; /* NORMAL */
+ qcom,vdd-dig-upper-bound = <5>; /* SUPER TURBO */
+ qcom,vdd-dig-lower-bound = <3>; /* NORMAL */
qcom,latency-us = <10300>;
qcom,ss-power = <63>;
qcom,energy-overhead = <2128000>;
@@ -262,10 +259,10 @@
qcom,mode = "pc";
qcom,xo = "xo_off";
qcom,l2 = "l2_cache_pc";
- qcom,vdd-mem-upper-bound = <1050000>; /* ACTIVE */
- qcom,vdd-mem-lower-bound = <750000>; /* RETENTION HIGH */
- qcom,vdd-dig-upper-bound = <3>; /* ACTIVE */
- qcom,vdd-dig-lower-bound = <2>; /* RETIONTION HIGH */
+ qcom,vdd-mem-upper-bound = <3>; /* NORMAL */
+ qcom,vdd-mem-lower-bound = <2>; /* SVS SOC */
+ qcom,vdd-dig-upper-bound = <3>; /* NORMAL */
+ qcom,vdd-dig-lower-bound = <2>; /* SVS SOC */
qcom,latency-us = <18000>;
qcom,ss-power = <10>;
qcom,energy-overhead = <3202600>;
@@ -277,10 +274,10 @@
qcom,mode = "pc";
qcom,xo = "xo_off";
qcom,l2 = "l2_cache_pc";
- qcom,vdd-mem-upper-bound = <750000>; /* RETENTION HIGH */
- qcom,vdd-mem-lower-bound = <750000>; /* RETENTION LOW */
- qcom,vdd-dig-upper-bound = <2>; /* RETENTION HIGH */
- qcom,vdd-dig-lower-bound = <0>; /* RETENTION LOW */
+ qcom,vdd-mem-upper-bound = <2>; /* SVS SOC */
+ qcom,vdd-mem-lower-bound = <0>; /* RETENTION */
+ qcom,vdd-dig-upper-bound = <2>; /* SVS SOC */
+ qcom,vdd-dig-lower-bound = <0>; /* RETENTION */
qcom,latency-us = <20000>;
qcom,ss-power = <2>;
qcom,energy-overhead = <4252000>;
diff --git a/arch/arm/boot/dts/msm8610.dtsi b/arch/arm/boot/dts/msm8610.dtsi
index 91dfdbe..6469bf7 100644
--- a/arch/arm/boot/dts/msm8610.dtsi
+++ b/arch/arm/boot/dts/msm8610.dtsi
@@ -456,6 +456,12 @@
qcom,is-loadable;
qcom,firmware-name = "mba";
qcom,pil-self-auth;
+
+ /* 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,lpass@fe200000 {
diff --git a/arch/arm/boot/dts/msm8974-bus.dtsi b/arch/arm/boot/dts/msm8974-bus.dtsi
index 828e7ae..cebb907 100644
--- a/arch/arm/boot/dts/msm8974-bus.dtsi
+++ b/arch/arm/boot/dts/msm8974-bus.dtsi
@@ -296,6 +296,9 @@
qcom,mode = "Fixed";
qcom,qport = <1>;
qcom,mas-hw-id = <19>;
+ qcom,prio-rd = <1>;
+ qcom,prio-wr = <1>;
+ qcom,hw-sel = "NoC";
};
mas-snoc-cfg {
@@ -432,6 +435,9 @@
qcom,qport = <10>;
qcom,mode = "Fixed";
qcom,mas-hw-id = <31>;
+ qcom,prio-rd = <1>;
+ qcom,prio-wr = <1>;
+ qcom,hw-sel = "NoC";
};
mas-usb3 {
@@ -442,8 +448,8 @@
qcom,mode = "Fixed";
qcom,qport = <11>;
qcom,mas-hw-id = <32>;
- qcom,prio-rd = <2>;
- qcom,prio-wr = <2>;
+ qcom,prio-rd = <1>;
+ qcom,prio-wr = <1>;
qcom,hw-sel = "NoC";
qcom,iface-clk-node = "msm_usb3";
};
diff --git a/arch/arm/configs/msm8610_defconfig b/arch/arm/configs/msm8610_defconfig
index a429b3d..8a974c4 100644
--- a/arch/arm/configs/msm8610_defconfig
+++ b/arch/arm/configs/msm8610_defconfig
@@ -216,6 +216,7 @@
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_UINPUT=y
CONFIG_INPUT_GPIO=m
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index dc8b675..1c14ac6 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -5,7 +5,7 @@
obj-y += timer.o
endif
obj-y += clock.o clock-voter.o clock-dummy.o
-obj-y += modem_notifier.o subsystem_map.o
+obj-y += modem_notifier.o
obj-$(CONFIG_USE_OF) += board-dt.o
obj-$(CONFIG_CPU_FREQ_MSM) += cpufreq.o
obj-$(CONFIG_DEBUG_FS) += nohlt.o clock-debug.o
diff --git a/arch/arm/mach-msm/acpuclock-8226.c b/arch/arm/mach-msm/acpuclock-8226.c
index 6e93c57..799d629 100644
--- a/arch/arm/mach-msm/acpuclock-8226.c
+++ b/arch/arm/mach-msm/acpuclock-8226.c
@@ -17,6 +17,7 @@
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/io.h>
+#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/regulator/cpr-regulator.h>
@@ -82,17 +83,21 @@
.update_mask = RCG_CONFIG_UPDATE_BIT,
.poll_mask = RCG_CONFIG_UPDATE_BIT,
},
+ .power_collapse_khz = 300000,
+ .wait_for_irq_khz = 300000,
};
static int __init acpuclk_a7_probe(struct platform_device *pdev)
{
struct resource *res;
+ u32 i;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rcg_base");
if (!res)
return -EINVAL;
- drv_data.apcs_rcg_cmd = ioremap(res->start, resource_size(res));
+ drv_data.apcs_rcg_cmd = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
if (!drv_data.apcs_rcg_cmd)
return -ENOMEM;
@@ -110,6 +115,21 @@
return PTR_ERR(drv_data.vdd_mem);
}
+ for (i = 0; i < NUM_SRC; i++) {
+ if (!drv_data.src_clocks[i].name)
+ continue;
+ drv_data.src_clocks[i].clk =
+ devm_clk_get(&pdev->dev, drv_data.src_clocks[i].name);
+ if (IS_ERR(drv_data.src_clocks[i].clk)) {
+ dev_err(&pdev->dev, "Unable to get clock %s\n",
+ drv_data.src_clocks[i].name);
+ return -EPROBE_DEFER;
+ }
+ }
+
+ /* Enable the always on source */
+ clk_prepare_enable(drv_data.src_clocks[PLL0].clk);
+
return acpuclk_cortex_init(pdev, &drv_data);
}
diff --git a/arch/arm/mach-msm/acpuclock-9625.c b/arch/arm/mach-msm/acpuclock-9625.c
index 34952fb..42659f9 100644
--- a/arch/arm/mach-msm/acpuclock-9625.c
+++ b/arch/arm/mach-msm/acpuclock-9625.c
@@ -16,6 +16,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/io.h>
+#include <linux/clk.h>
#include <linux/errno.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
@@ -80,18 +81,21 @@
.update_mask = RCG_CONFIG_PGM_DATA_BIT | RCG_CONFIG_PGM_ENA_BIT,
.poll_mask = RCG_CONFIG_PGM_DATA_BIT,
},
+ .power_collapse_khz = 19200,
+ .wait_for_irq_khz = 19200,
};
static int __init acpuclk_9625_probe(struct platform_device *pdev)
{
struct resource *res;
- u32 regval;
+ u32 regval, i;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rcg_base");
if (!res)
return -EINVAL;
- drv_data.apcs_rcg_config = ioremap(res->start, resource_size(res));
+ drv_data.apcs_rcg_config = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
if (!drv_data.apcs_rcg_config)
return -ENOMEM;
@@ -117,6 +121,18 @@
return PTR_ERR(drv_data.vdd_mem);
}
+ for (i = 0; i < NUM_SRC; i++) {
+ if (!drv_data.src_clocks[i].name)
+ continue;
+ drv_data.src_clocks[i].clk =
+ devm_clk_get(&pdev->dev, drv_data.src_clocks[i].name);
+ if (IS_ERR(drv_data.src_clocks[i].clk)) {
+ dev_err(&pdev->dev, "Unable to get clock %s\n",
+ drv_data.src_clocks[i].name);
+ return -EPROBE_DEFER;
+ }
+ }
+
/* Disable hardware gating of gpll0 to A5SS */
regval = readl_relaxed(drv_data.apcs_cpu_pwr_ctl);
regval |= GPLL0_TO_A5_ALWAYS_ENABLE;
diff --git a/arch/arm/mach-msm/acpuclock-cortex.c b/arch/arm/mach-msm/acpuclock-cortex.c
index 88bf919..ca7fc2b 100644
--- a/arch/arm/mach-msm/acpuclock-cortex.c
+++ b/arch/arm/mach-msm/acpuclock-cortex.c
@@ -317,8 +317,6 @@
static struct acpuclk_data acpuclk_cortex_data = {
.set_rate = acpuclk_cortex_set_rate,
.get_rate = acpuclk_cortex_get_rate,
- .power_collapse_khz = 19200,
- .wait_for_irq_khz = 19200,
};
int __init acpuclk_cortex_init(struct platform_device *pdev,
@@ -330,20 +328,15 @@
priv = data;
mutex_init(&priv->lock);
+ acpuclk_cortex_data.power_collapse_khz = priv->wait_for_irq_khz;
+ acpuclk_cortex_data.wait_for_irq_khz = priv->wait_for_irq_khz;
+
bus_perf_client = msm_bus_scale_register_client(priv->bus_scale);
if (!bus_perf_client) {
pr_err("Unable to register bus client\n");
BUG();
}
- for (i = 0; i < NUM_SRC; i++) {
- if (!priv->src_clocks[i].name)
- continue;
- priv->src_clocks[i].clk =
- devm_clk_get(&pdev->dev, priv->src_clocks[i].name);
- BUG_ON(IS_ERR(priv->src_clocks[i].clk));
- }
-
/* Improve boot time by ramping up CPU immediately */
for (i = 0; priv->freq_tbl[i].khz != 0; i++)
if (priv->freq_tbl[i].use_for_scaling)
diff --git a/arch/arm/mach-msm/acpuclock-cortex.h b/arch/arm/mach-msm/acpuclock-cortex.h
index 2db3987..89a0a84 100644
--- a/arch/arm/mach-msm/acpuclock-cortex.h
+++ b/arch/arm/mach-msm/acpuclock-cortex.h
@@ -63,6 +63,8 @@
unsigned long vdd_max_mem;
struct src_clock src_clocks[NUM_SRC];
struct acpuclk_reg_data reg_data;
+ unsigned long power_collapse_khz;
+ unsigned long wait_for_irq_khz;
};
/* Instantaneous bandwidth requests in MB/s. */
diff --git a/arch/arm/mach-msm/include/mach/msm_subsystem_map.h b/arch/arm/mach-msm/include/mach/msm_subsystem_map.h
deleted file mode 100644
index 3119023..0000000
--- a/arch/arm/mach-msm/include/mach/msm_subsystem_map.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2011, 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 __ARCH_MACH_MSM_SUBSYSTEM_MAP_H
-#define __ARCH_MACH_MSM_SUBSYSTEM_MAP_H
-
-#include <linux/iommu.h>
-#include <mach/iommu_domains.h>
-
-/* map the physical address in the kernel vaddr space */
-#define MSM_SUBSYSTEM_MAP_KADDR 0x1
-/* map the physical address in the iova address space */
-#define MSM_SUBSYSTEM_MAP_IOVA 0x2
-/* ioremaps in the kernel address space are cached */
-#define MSM_SUBSYSTEM_MAP_CACHED 0x4
-/* ioremaps in the kernel address space are uncached */
-#define MSM_SUBSYSTEM_MAP_UNCACHED 0x8
-/*
- * Will map 2x the length requested.
- */
-#define MSM_SUBSYSTEM_MAP_IOMMU_2X 0x10
-
-/*
- * Shortcut flags for alignment.
- * The flag must be equal to the alignment requested.
- * e.g. for 8k alignment the flags must be (0x2000 | other flags)
- */
-#define MSM_SUBSYSTEM_ALIGN_IOVA_8K SZ_8K
-#define MSM_SUBSYSTEM_ALIGN_IOVA_1M SZ_1M
-
-
-enum msm_subsystem_id {
- INVALID_SUBSYS_ID = -1,
- MSM_SUBSYSTEM_VIDEO,
- MSM_SUBSYSTEM_VIDEO_FWARE,
- MSM_SUBSYSTEM_CAMERA,
- MSM_SUBSYSTEM_DISPLAY,
- MSM_SUBSYSTEM_ROTATOR,
- MAX_SUBSYSTEM_ID
-};
-
-static inline int msm_subsystem_check_id(int subsys_id)
-{
- return subsys_id > INVALID_SUBSYS_ID && subsys_id < MAX_SUBSYSTEM_ID;
-}
-
-struct msm_mapped_buffer {
- /*
- * VA mapped in the kernel address space. This field shall be NULL if
- * MSM_SUBSYSTEM_MAP_KADDR was not passed to the map buffer function.
- */
- void *vaddr;
- /*
- * iovas mapped in the iommu address space. The ith entry of this array
- * corresponds to the iova mapped in the ith subsystem in the array
- * pased in to msm_subsystem_map_buffer. This field shall be NULL if
- * MSM_SUBSYSTEM_MAP_IOVA was not passed to the map buffer function,
- */
- unsigned long *iova;
-};
-
-extern struct msm_mapped_buffer *msm_subsystem_map_buffer(
- unsigned long phys,
- unsigned int length,
- unsigned int flags,
- int *subsys_ids,
- unsigned int nsubsys);
-
-extern int msm_subsystem_unmap_buffer(struct msm_mapped_buffer *buf);
-
-extern phys_addr_t msm_subsystem_check_iova_mapping(int subsys_id,
- unsigned long iova);
-
-#endif /* __ARCH_MACH_MSM_SUBSYSTEM_MAP_H */
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/q6core.h b/arch/arm/mach-msm/include/mach/qdsp6v2/q6core.h
index ea345fb..91e4ef1 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/q6core.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/q6core.h
@@ -53,10 +53,19 @@
uint8_t model_ID[128];
};
+#define ADSP_CMD_SET_DOLBY_MANUFACTURER_ID 0x00012918
+
+struct adsp_dolby_manufacturer_id {
+ struct apr_hdr hdr;
+ int manufacturer_id;
+};
+
int core_req_bus_bandwith(u16 bus_id, u32 ab_bps, u32 ib_bps);
uint32_t core_get_adsp_version(void);
uint32_t core_set_dts_model_id(uint32_t id_size, uint8_t *id);
+uint32_t core_set_dolby_manufacturer_id(int manufacturer_id);
+
#endif /* __Q6CORE_H__ */
diff --git a/arch/arm/mach-msm/include/mach/qseecomi.h b/arch/arm/mach-msm/include/mach/qseecomi.h
index 3a13af8..ea02425 100644
--- a/arch/arm/mach-msm/include/mach/qseecomi.h
+++ b/arch/arm/mach-msm/include/mach/qseecomi.h
@@ -36,6 +36,8 @@
QSEOS_UNLOAD_SERV_IMAGE_COMMAND,
QSEOS_APP_REGION_NOTIFICATION,
QSEOS_REGISTER_LOG_BUF_COMMAND,
+ QSEE_RPMB_PROVISION_KEY_COMMAND,
+ QSEE_RPMB_ERASE_COMMAND,
QSEOS_CMD_MAX = 0xEFFFFFFF
};
@@ -127,4 +129,17 @@
unsigned int data;
};
+struct qseecom_rpmb_provision_key {
+ uint32_t key_type;
+};
+
+__packed struct qseecom_client_send_service_ireq {
+ uint32_t qsee_cmd_id;
+ uint32_t key_type; /* in */
+ unsigned int req_len; /* in */
+ void *rsp_ptr; /* in/out */
+ unsigned int rsp_len; /* in/out */
+};
+
+
#endif /* __QSEECOMI_H_ */
diff --git a/arch/arm/mach-msm/include/mach/sps.h b/arch/arm/mach-msm/include/mach/sps.h
index c20576a..662655b 100644
--- a/arch/arm/mach-msm/include/mach/sps.h
+++ b/arch/arm/mach-msm/include/mach/sps.h
@@ -146,6 +146,8 @@
SPS_O_WRITE_NWD = 0x00040000,
/* Options to enable software features */
+ /* Do not disable a pipe during disconnection */
+ SPS_O_NO_DISABLE = 0x00800000,
/* Transfer operation should be polled */
SPS_O_POLL = 0x01000000,
/* Disable queuing of transfer events for the connection end point */
diff --git a/arch/arm/mach-msm/qdsp6v2/q6core.c b/arch/arm/mach-msm/qdsp6v2/q6core.c
index f23ba67..6594b08 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6core.c
+++ b/arch/arm/mach-msm/qdsp6v2/q6core.c
@@ -413,6 +413,32 @@
return rc;
}
+uint32_t core_set_dolby_manufacturer_id(int manufacturer_id)
+{
+ struct adsp_dolby_manufacturer_id payload;
+ int rc = 0;
+ pr_debug("%s manufacturer_id :%d\n", __func__, manufacturer_id);
+ core_open();
+ if (core_handle_q) {
+ payload.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_EVENT,
+ APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+ payload.hdr.pkt_size =
+ sizeof(struct adsp_dolby_manufacturer_id);
+ payload.hdr.src_port = 0;
+ payload.hdr.dest_port = 0;
+ payload.hdr.token = 0;
+ payload.hdr.opcode = ADSP_CMD_SET_DOLBY_MANUFACTURER_ID;
+ payload.manufacturer_id = manufacturer_id;
+ pr_debug("Send Dolby security opcode=%x manufacturer ID = %d\n",
+ payload.hdr.opcode, payload.manufacturer_id);
+ rc = apr_send_pkt(core_handle_q, (uint32_t *)&payload);
+ if (rc < 0)
+ pr_err("%s: SET_DOLBY_MANUFACTURER_ID failed op[0x%x]rc[%d]\n",
+ __func__, payload.hdr.opcode, rc);
+ }
+ return rc;
+}
+
static const struct file_operations apr_debug_fops = {
.write = apr_debug_write,
.open = apr_debug_open,
diff --git a/arch/arm/mach-msm/smd_tty.c b/arch/arm/mach-msm/smd_tty.c
index 8a2c23f..0b270b7 100644
--- a/arch/arm/mach-msm/smd_tty.c
+++ b/arch/arm/mach-msm/smd_tty.c
@@ -63,7 +63,6 @@
struct tty_port port;
struct device *device_ptr;
struct wake_lock wake_lock;
- int open_count;
struct tasklet_struct tty_tsklt;
struct timer_list buf_req_timer;
struct completion ch_allocated;
@@ -333,112 +332,106 @@
mutex_lock(&smd_tty_lock);
tty->driver_data = info;
- if (info->open_count++ == 0) {
- peripheral = smd_edge_to_subsystem(smd_tty[n].smd->edge);
- if (peripheral) {
- info->pil = subsystem_get(peripheral);
- if (IS_ERR(info->pil)) {
- SMD_TTY_INFO(
- "%s failed on smd_tty device :%s subsystem_get failed for %s",
- __func__, smd_tty[n].smd->port_name,
- peripheral);
- /*
- * Sleep, inorder to reduce the frequency of
- * retry by user-space modules and to avoid
- * possible watchdog bite.
- */
- msleep((smd_tty[n].open_wait * 1000));
- res = PTR_ERR(info->pil);
- goto out;
- }
-
- /* Wait for the modem SMSM to be inited for the SMD
- * Loopback channel to be allocated at the modem. Since
- * the wait need to be done atmost once, using msleep
- * doesn't degrade the performance.
- */
- if (n == LOOPBACK_IDX) {
- if (!is_modem_smsm_inited())
- msleep(5000);
- smsm_change_state(SMSM_APPS_STATE,
- 0, SMSM_SMD_LOOPBACK);
- msleep(100);
- }
-
+ peripheral = smd_edge_to_subsystem(smd_tty[n].smd->edge);
+ if (peripheral) {
+ info->pil = subsystem_get(peripheral);
+ if (IS_ERR(info->pil)) {
+ SMD_TTY_INFO(
+ "%s failed on smd_tty device :%s subsystem_get failed for %s",
+ __func__, smd_tty[n].smd->port_name,
+ peripheral);
/*
- * Wait for a channel to be allocated so we know
- * the modem is ready enough.
+ * Sleep, inorder to reduce the frequency of
+ * retry by user-space modules and to avoid
+ * possible watchdog bite.
*/
- if (smd_tty[n].open_wait) {
- res = wait_for_completion_interruptible_timeout(
+ msleep((smd_tty[n].open_wait * 1000));
+ res = PTR_ERR(info->pil);
+ goto out;
+ }
+
+ /* Wait for the modem SMSM to be inited for the SMD
+ * Loopback channel to be allocated at the modem. Since
+ * the wait need to be done atmost once, using msleep
+ * doesn't degrade the performance.
+ */
+ if (n == LOOPBACK_IDX) {
+ if (!is_modem_smsm_inited())
+ msleep(5000);
+ smsm_change_state(SMSM_APPS_STATE,
+ 0, SMSM_SMD_LOOPBACK);
+ msleep(100);
+ }
+
+ /*
+ * Wait for a channel to be allocated so we know
+ * the modem is ready enough.
+ */
+ if (smd_tty[n].open_wait) {
+ res = wait_for_completion_interruptible_timeout(
&info->ch_allocated,
msecs_to_jiffies(smd_tty[n].open_wait *
1000));
- if (res == 0) {
- SMD_TTY_INFO(
- "Timed out waiting for SMD channel %s",
- smd_tty[n].smd->port_name);
- res = -ETIMEDOUT;
- goto release_pil;
- } else if (res < 0) {
- SMD_TTY_INFO(
- "Error waiting for SMD channel %s : %d\n",
- smd_tty[n].smd->port_name, res);
- goto release_pil;
- }
-
- res = 0;
- }
- }
-
- tasklet_init(&info->tty_tsklt, smd_tty_read,
- (unsigned long)info);
- wake_lock_init(&info->wake_lock, WAKE_LOCK_SUSPEND,
- smd_tty[n].smd->port_name);
- scnprintf(info->ra_wake_lock_name,
- MAX_RA_WAKE_LOCK_NAME_LEN,
- "SMD_TTY_%s_RA", smd_tty[n].smd->port_name);
- wake_lock_init(&info->ra_wake_lock, WAKE_LOCK_SUSPEND,
- info->ra_wake_lock_name);
- if (!info->ch) {
- res = smd_named_open_on_edge(smd_tty[n].smd->port_name,
- smd_tty[n].smd->edge,
- &info->ch, info,
- smd_tty_notify);
- if (res < 0) {
+ if (res == 0) {
SMD_TTY_INFO(
- "%s: %s open failed %d\n",
- __func__, smd_tty[n].smd->port_name,
- res);
- goto release_pil;
- }
-
- res = wait_event_interruptible_timeout(
- info->ch_opened_wait_queue,
- info->is_open, (2 * HZ));
- if (res == 0)
+ "Timed out waiting for SMD channel %s",
+ smd_tty[n].smd->port_name);
res = -ETIMEDOUT;
- if (res < 0) {
+ goto release_pil;
+ } else if (res < 0) {
SMD_TTY_INFO(
- "%s: wait for %s smd_open failed %d\n",
- __func__, smd_tty[n].smd->port_name,
- res);
+ "Error waiting for SMD channel %s : %d\n",
+ smd_tty[n].smd->port_name, res);
goto release_pil;
}
- res = 0;
- SMD_TTY_INFO("%s with PID %u opened port %s",
- current->comm, current->pid,
- smd_tty[n].smd->port_name);
}
}
+ tasklet_init(&info->tty_tsklt, smd_tty_read, (unsigned long)info);
+ wake_lock_init(&info->wake_lock, WAKE_LOCK_SUSPEND,
+ smd_tty[n].smd->port_name);
+ scnprintf(info->ra_wake_lock_name, MAX_RA_WAKE_LOCK_NAME_LEN,
+ "SMD_TTY_%s_RA", smd_tty[n].smd->port_name);
+ wake_lock_init(&info->ra_wake_lock, WAKE_LOCK_SUSPEND,
+ info->ra_wake_lock_name);
+
+ res = smd_named_open_on_edge(smd_tty[n].smd->port_name,
+ smd_tty[n].smd->edge, &info->ch, info,
+ smd_tty_notify);
+ if (res < 0) {
+ SMD_TTY_INFO("%s: %s open failed %d\n",
+ __func__, smd_tty[n].smd->port_name, res);
+ goto release_wl_tl;
+ }
+
+ res = wait_event_interruptible_timeout(info->ch_opened_wait_queue,
+ info->is_open, (2 * HZ));
+ if (res == 0)
+ res = -ETIMEDOUT;
+ if (res < 0) {
+ SMD_TTY_INFO("%s: wait for %s smd_open failed %d\n",
+ __func__, smd_tty[n].smd->port_name, res);
+ goto close_ch;
+ }
+ SMD_TTY_INFO("%s with PID %u opened port %s",
+ current->comm, current->pid, smd_tty[n].smd->port_name);
+ smd_disable_read_intr(info->ch);
+ mutex_unlock(&smd_tty_lock);
+ return 0;
+
+close_ch:
+ smd_close(info->ch);
+ info->ch = NULL;
+
+release_wl_tl:
+ tasklet_kill(&info->tty_tsklt);
+ wake_lock_destroy(&info->wake_lock);
+ wake_lock_destroy(&info->ra_wake_lock);
+
release_pil:
- if (res < 0)
- subsystem_put(info->pil);
- else
- smd_disable_read_intr(info->ch);
+ subsystem_put(info->pil);
out:
mutex_unlock(&smd_tty_lock);
@@ -458,26 +451,25 @@
}
mutex_lock(&smd_tty_lock);
- if (--info->open_count == 0) {
- spin_lock_irqsave(&info->reset_lock, flags);
- info->is_open = 0;
- spin_unlock_irqrestore(&info->reset_lock, flags);
- if (tty) {
- tasklet_kill(&info->tty_tsklt);
- wake_lock_destroy(&info->wake_lock);
- wake_lock_destroy(&info->ra_wake_lock);
- }
- SMD_TTY_INFO("%s with PID %u closed port %s",
- current->comm, current->pid,
- info->smd->port_name);
- tty->driver_data = 0;
- del_timer(&info->buf_req_timer);
- if (info->ch) {
- smd_close(info->ch);
- info->ch = 0;
- subsystem_put(info->pil);
- }
- }
+
+ spin_lock_irqsave(&info->reset_lock, flags);
+ info->is_open = 0;
+ spin_unlock_irqrestore(&info->reset_lock, flags);
+
+ tasklet_kill(&info->tty_tsklt);
+ wake_lock_destroy(&info->wake_lock);
+ wake_lock_destroy(&info->ra_wake_lock);
+
+ SMD_TTY_INFO("%s with PID %u closed port %s",
+ current->comm, current->pid,
+ info->smd->port_name);
+ tty->driver_data = NULL;
+ del_timer(&info->buf_req_timer);
+
+ smd_close(info->ch);
+ info->ch = NULL;
+ subsystem_put(info->pil);
+
mutex_unlock(&smd_tty_lock);
tty_kref_put(tty);
}
diff --git a/arch/arm/mach-msm/subsystem_map.c b/arch/arm/mach-msm/subsystem_map.c
deleted file mode 100644
index 116fc2e..0000000
--- a/arch/arm/mach-msm/subsystem_map.c
+++ /dev/null
@@ -1,555 +0,0 @@
-/* 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
- * 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/io.h>
-#include <linux/types.h>
-#include <linux/err.h>
-#include <linux/slab.h>
-#include <linux/memory_alloc.h>
-#include <linux/module.h>
-#include <mach/iommu.h>
-#include <mach/iommu_domains.h>
-#include <mach/msm_subsystem_map.h>
-
-struct msm_buffer_node {
- struct rb_node rb_node_all_buffer;
- struct rb_node rb_node_paddr;
- struct msm_mapped_buffer *buf;
- unsigned long length;
- unsigned int *subsystems;
- unsigned int nsubsys;
- unsigned int phys;
-};
-
-static struct rb_root buffer_root;
-static struct rb_root phys_root;
-DEFINE_MUTEX(msm_buffer_mutex);
-
-static unsigned long subsystem_to_domain_tbl[] = {
- VIDEO_DOMAIN,
- VIDEO_DOMAIN,
- CAMERA_DOMAIN,
- DISPLAY_READ_DOMAIN,
- DISPLAY_WRITE_DOMAIN,
- ROTATOR_SRC_DOMAIN,
- ROTATOR_DST_DOMAIN,
- 0xFFFFFFFF
-};
-
-static struct msm_buffer_node *find_buffer(void *key)
-{
- struct rb_root *root = &buffer_root;
- struct rb_node *p = root->rb_node;
-
- mutex_lock(&msm_buffer_mutex);
-
- while (p) {
- struct msm_buffer_node *node;
-
- node = rb_entry(p, struct msm_buffer_node, rb_node_all_buffer);
- if (node->buf->vaddr) {
- if (key < node->buf->vaddr)
- p = p->rb_left;
- else if (key > node->buf->vaddr)
- p = p->rb_right;
- else {
- mutex_unlock(&msm_buffer_mutex);
- return node;
- }
- } else {
- if (key < (void *)node->buf)
- p = p->rb_left;
- else if (key > (void *)node->buf)
- p = p->rb_right;
- else {
- mutex_unlock(&msm_buffer_mutex);
- return node;
- }
- }
- }
- mutex_unlock(&msm_buffer_mutex);
- return NULL;
-}
-
-static struct msm_buffer_node *find_buffer_phys(unsigned int phys)
-{
- struct rb_root *root = &phys_root;
- struct rb_node *p = root->rb_node;
-
- mutex_lock(&msm_buffer_mutex);
-
- while (p) {
- struct msm_buffer_node *node;
-
- node = rb_entry(p, struct msm_buffer_node, rb_node_paddr);
- if (phys < node->phys)
- p = p->rb_left;
- else if (phys > node->phys)
- p = p->rb_right;
- else {
- mutex_unlock(&msm_buffer_mutex);
- return node;
- }
- }
- mutex_unlock(&msm_buffer_mutex);
- return NULL;
-
-}
-
-static int add_buffer(struct msm_buffer_node *node)
-{
- struct rb_root *root = &buffer_root;
- struct rb_node **p = &root->rb_node;
- struct rb_node *parent = NULL;
- void *key;
-
- if (node->buf->vaddr)
- key = node->buf->vaddr;
- else
- key = node->buf;
-
- mutex_lock(&msm_buffer_mutex);
- while (*p) {
- struct msm_buffer_node *tmp;
- parent = *p;
-
- tmp = rb_entry(parent, struct msm_buffer_node,
- rb_node_all_buffer);
-
- if (tmp->buf->vaddr) {
- if (key < tmp->buf->vaddr)
- p = &(*p)->rb_left;
- else if (key > tmp->buf->vaddr)
- p = &(*p)->rb_right;
- else {
- WARN(1, "tried to add buffer twice! buf = %p"
- " vaddr = %p iova = %p", tmp->buf,
- tmp->buf->vaddr,
- tmp->buf->iova);
- mutex_unlock(&msm_buffer_mutex);
- return -EINVAL;
-
- }
- } else {
- if (key < (void *)tmp->buf)
- p = &(*p)->rb_left;
- else if (key > (void *)tmp->buf)
- p = &(*p)->rb_right;
- else {
- WARN(1, "tried to add buffer twice! buf = %p"
- " vaddr = %p iova = %p", tmp->buf,
- tmp->buf->vaddr,
- tmp->buf->iova);
- mutex_unlock(&msm_buffer_mutex);
- return -EINVAL;
- }
- }
- }
- rb_link_node(&node->rb_node_all_buffer, parent, p);
- rb_insert_color(&node->rb_node_all_buffer, root);
- mutex_unlock(&msm_buffer_mutex);
- return 0;
-}
-
-static int add_buffer_phys(struct msm_buffer_node *node)
-{
- struct rb_root *root = &phys_root;
- struct rb_node **p = &root->rb_node;
- struct rb_node *parent = NULL;
-
- mutex_lock(&msm_buffer_mutex);
- while (*p) {
- struct msm_buffer_node *tmp;
- parent = *p;
-
- tmp = rb_entry(parent, struct msm_buffer_node, rb_node_paddr);
-
- if (node->phys < tmp->phys)
- p = &(*p)->rb_left;
- else if (node->phys > tmp->phys)
- p = &(*p)->rb_right;
- else {
- WARN(1, "tried to add buffer twice! buf = %p"
- " vaddr = %p iova = %p", tmp->buf,
- tmp->buf->vaddr,
- tmp->buf->iova);
- mutex_unlock(&msm_buffer_mutex);
- return -EINVAL;
-
- }
- }
- rb_link_node(&node->rb_node_paddr, parent, p);
- rb_insert_color(&node->rb_node_paddr, root);
- mutex_unlock(&msm_buffer_mutex);
- return 0;
-}
-
-static int remove_buffer(struct msm_buffer_node *victim_node)
-{
- struct rb_root *root = &buffer_root;
-
- if (!victim_node)
- return -EINVAL;
-
- mutex_lock(&msm_buffer_mutex);
- rb_erase(&victim_node->rb_node_all_buffer, root);
- mutex_unlock(&msm_buffer_mutex);
- return 0;
-}
-
-static int remove_buffer_phys(struct msm_buffer_node *victim_node)
-{
- struct rb_root *root = &phys_root;
-
- if (!victim_node)
- return -EINVAL;
-
- mutex_lock(&msm_buffer_mutex);
- rb_erase(&victim_node->rb_node_paddr, root);
- mutex_unlock(&msm_buffer_mutex);
- return 0;
-}
-
-static unsigned long msm_subsystem_get_domain_no(int subsys_id)
-{
- if (subsys_id > INVALID_SUBSYS_ID && subsys_id <= MAX_SUBSYSTEM_ID &&
- subsys_id < ARRAY_SIZE(subsystem_to_domain_tbl))
- return subsystem_to_domain_tbl[subsys_id];
- else
- return subsystem_to_domain_tbl[MAX_SUBSYSTEM_ID];
-}
-
-static unsigned long msm_subsystem_get_partition_no(int subsys_id)
-{
- switch (subsys_id) {
- case MSM_SUBSYSTEM_VIDEO_FWARE:
- return VIDEO_FIRMWARE_POOL;
- case MSM_SUBSYSTEM_VIDEO:
- return VIDEO_MAIN_POOL;
- case MSM_SUBSYSTEM_CAMERA:
- case MSM_SUBSYSTEM_DISPLAY:
- case MSM_SUBSYSTEM_ROTATOR:
- return GEN_POOL;
- default:
- return 0xFFFFFFFF;
- }
-}
-
-phys_addr_t msm_subsystem_check_iova_mapping(int subsys_id, unsigned long iova)
-{
- struct iommu_domain *subsys_domain;
-
- if (!msm_use_iommu())
- /*
- * If there is no iommu, Just return the iova in this case.
- */
- return iova;
-
- subsys_domain = msm_get_iommu_domain(msm_subsystem_get_domain_no
- (subsys_id));
- if (!subsys_domain)
- return -EINVAL;
-
- return iommu_iova_to_phys(subsys_domain, iova);
-}
-EXPORT_SYMBOL(msm_subsystem_check_iova_mapping);
-
-struct msm_mapped_buffer *msm_subsystem_map_buffer(unsigned long phys,
- unsigned int length,
- unsigned int flags,
- int *subsys_ids,
- unsigned int nsubsys)
-{
- struct msm_mapped_buffer *buf, *err;
- struct msm_buffer_node *node;
- int i = 0, j = 0, ret;
- unsigned long iova_start = 0, temp_phys, temp_va = 0;
- struct iommu_domain *d = NULL;
- int map_size = length;
-
- if (!((flags & MSM_SUBSYSTEM_MAP_KADDR) ||
- (flags & MSM_SUBSYSTEM_MAP_IOVA))) {
- pr_warn("%s: no mapping flag was specified. The caller"
- " should explicitly specify what to map in the"
- " flags.\n", __func__);
- err = ERR_PTR(-EINVAL);
- goto outret;
- }
-
- buf = kzalloc(sizeof(*buf), GFP_ATOMIC);
- if (!buf) {
- err = ERR_PTR(-ENOMEM);
- goto outret;
- }
-
- node = kzalloc(sizeof(*node), GFP_ATOMIC);
- if (!node) {
- err = ERR_PTR(-ENOMEM);
- goto outkfreebuf;
- }
-
- node->phys = phys;
-
- if (flags & MSM_SUBSYSTEM_MAP_KADDR) {
- struct msm_buffer_node *old_buffer;
-
- old_buffer = find_buffer_phys(phys);
-
- if (old_buffer) {
- WARN(1, "%s: Attempting to map %lx twice in the kernel"
- " virtual space. Don't do that!\n", __func__,
- phys);
- err = ERR_PTR(-EINVAL);
- goto outkfreenode;
- }
-
- if (flags & MSM_SUBSYSTEM_MAP_CACHED)
- buf->vaddr = ioremap(phys, length);
- else if (flags & MSM_SUBSYSTEM_MAP_KADDR)
- buf->vaddr = ioremap_nocache(phys, length);
- else {
- pr_warn("%s: no cachability flag was indicated. Caller"
- " must specify a cachability flag.\n",
- __func__);
- err = ERR_PTR(-EINVAL);
- goto outkfreenode;
- }
-
- if (!buf->vaddr) {
- pr_err("%s: could not ioremap\n", __func__);
- err = ERR_PTR(-EINVAL);
- goto outkfreenode;
- }
-
- if (add_buffer_phys(node)) {
- err = ERR_PTR(-EINVAL);
- goto outiounmap;
- }
- }
-
- if ((flags & MSM_SUBSYSTEM_MAP_IOVA) && subsys_ids) {
- int min_align;
-
- length = round_up(length, SZ_4K);
-
- if (flags & MSM_SUBSYSTEM_MAP_IOMMU_2X)
- map_size = 2 * length;
- else
- map_size = length;
-
- buf->iova = kzalloc(sizeof(unsigned long)*nsubsys, GFP_ATOMIC);
- if (!buf->iova) {
- err = ERR_PTR(-ENOMEM);
- goto outremovephys;
- }
-
- /*
- * The alignment must be specified as the exact value wanted
- * e.g. 8k alignment must pass (0x2000 | other flags)
- */
- min_align = flags & ~(SZ_4K - 1);
-
- for (i = 0; i < nsubsys; i++) {
- unsigned int domain_no, partition_no;
-
- if (!msm_use_iommu()) {
- buf->iova[i] = phys;
- continue;
- }
-
- d = msm_get_iommu_domain(
- msm_subsystem_get_domain_no(subsys_ids[i]));
-
- if (!d) {
- pr_err("%s: could not get domain for subsystem"
- " %d\n", __func__, subsys_ids[i]);
- continue;
- }
-
- domain_no = msm_subsystem_get_domain_no(subsys_ids[i]);
- partition_no = msm_subsystem_get_partition_no(
- subsys_ids[i]);
-
- ret = msm_allocate_iova_address(domain_no,
- partition_no,
- map_size,
- max(min_align, SZ_4K),
- &iova_start);
-
- if (ret) {
- pr_err("%s: could not allocate iova address\n",
- __func__);
- continue;
- }
-
- temp_phys = phys;
- temp_va = iova_start;
- for (j = length; j > 0; j -= SZ_4K,
- temp_phys += SZ_4K,
- temp_va += SZ_4K) {
- ret = iommu_map(d, temp_va, temp_phys,
- SZ_4K,
- (IOMMU_READ | IOMMU_WRITE));
- if (ret) {
- pr_err("%s: could not map iommu for"
- " domain %p, iova %lx,"
- " phys %lx\n", __func__, d,
- temp_va, temp_phys);
- err = ERR_PTR(-EINVAL);
- goto outdomain;
- }
- }
- buf->iova[i] = iova_start;
-
- if (flags & MSM_SUBSYSTEM_MAP_IOMMU_2X)
- msm_iommu_map_extra
- (d, temp_va, phys, length, SZ_4K,
- IOMMU_READ);
- }
-
- }
-
- node->buf = buf;
- node->subsystems = subsys_ids;
- node->length = map_size;
- node->nsubsys = nsubsys;
-
- if (add_buffer(node)) {
- err = ERR_PTR(-EINVAL);
- goto outiova;
- }
-
- return buf;
-
-outiova:
- if (flags & MSM_SUBSYSTEM_MAP_IOVA) {
- if (d)
- iommu_unmap(d, temp_va, SZ_4K);
- }
-outdomain:
- if (flags & MSM_SUBSYSTEM_MAP_IOVA) {
- /* Unmap the rest of the current domain, i */
- if (d) {
- for (j -= SZ_4K, temp_va -= SZ_4K;
- j > 0; temp_va -= SZ_4K, j -= SZ_4K)
- iommu_unmap(d, temp_va, SZ_4K);
- }
- /* Unmap all the other domains */
- for (i--; i >= 0; i--) {
- unsigned int domain_no, partition_no;
- if (!msm_use_iommu())
- continue;
- domain_no = msm_subsystem_get_domain_no(subsys_ids[i]);
- partition_no = msm_subsystem_get_partition_no(
- subsys_ids[i]);
-
- d = msm_get_iommu_domain(domain_no);
-
- if (d) {
- temp_va = buf->iova[i];
- for (j = length; j > 0; j -= SZ_4K,
- temp_va += SZ_4K)
- iommu_unmap(d, temp_va, SZ_4K);
- }
- msm_free_iova_address(buf->iova[i], domain_no,
- partition_no, length);
- }
-
- kfree(buf->iova);
- }
-
-outremovephys:
- if (flags & MSM_SUBSYSTEM_MAP_KADDR)
- remove_buffer_phys(node);
-outiounmap:
- if (flags & MSM_SUBSYSTEM_MAP_KADDR)
- iounmap(buf->vaddr);
-outkfreenode:
- kfree(node);
-outkfreebuf:
- kfree(buf);
-outret:
- return err;
-}
-EXPORT_SYMBOL(msm_subsystem_map_buffer);
-
-int msm_subsystem_unmap_buffer(struct msm_mapped_buffer *buf)
-{
- struct msm_buffer_node *node;
- int i, j, ret;
- unsigned long temp_va;
-
- if (IS_ERR_OR_NULL(buf))
- goto out;
-
- if (buf->vaddr)
- node = find_buffer(buf->vaddr);
- else
- node = find_buffer(buf);
-
- if (!node)
- goto out;
-
- if (node->buf != buf) {
- pr_err("%s: caller must pass in the same buffer structure"
- " returned from map_buffer when freeding\n", __func__);
- goto out;
- }
-
- if (buf->iova) {
- if (msm_use_iommu())
- for (i = 0; i < node->nsubsys; i++) {
- struct iommu_domain *subsys_domain;
- unsigned int domain_no, partition_no;
-
- subsys_domain = msm_get_iommu_domain(
- msm_subsystem_get_domain_no(
- node->subsystems[i]));
-
- if (!subsys_domain)
- continue;
-
- domain_no = msm_subsystem_get_domain_no(
- node->subsystems[i]);
- partition_no = msm_subsystem_get_partition_no(
- node->subsystems[i]);
-
- temp_va = buf->iova[i];
- for (j = node->length; j > 0; j -= SZ_4K,
- temp_va += SZ_4K) {
- ret = iommu_unmap(subsys_domain,
- temp_va,
- SZ_4K);
- WARN(ret, "iommu_unmap returned a "
- " non-zero value.\n");
- }
- msm_free_iova_address(buf->iova[i], domain_no,
- partition_no, node->length);
- }
- kfree(buf->iova);
-
- }
-
- if (buf->vaddr) {
- remove_buffer_phys(node);
- iounmap(buf->vaddr);
- }
-
- remove_buffer(node);
- kfree(node);
- kfree(buf);
-
- return 0;
-out:
- return -EINVAL;
-}
-EXPORT_SYMBOL(msm_subsystem_unmap_buffer);
diff --git a/drivers/hwmon/qpnp-adc-current.c b/drivers/hwmon/qpnp-adc-current.c
index 1fd4fee..a4937d7 100644
--- a/drivers/hwmon/qpnp-adc-current.c
+++ b/drivers/hwmon/qpnp-adc-current.c
@@ -125,7 +125,6 @@
#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;
@@ -136,7 +135,6 @@
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];
};
@@ -254,7 +252,7 @@
return rc;
}
- pr_err("EOC not set with status:%x, dig:%x, ch:%x, mode:%x, en:%x\n",
+ pr_debug("EOC not set with status:%x, dig:%x, ch:%x, mode:%x, en:%x\n",
status1, dig, chan, mode, en);
rc = qpnp_iadc_enable(false);
@@ -495,16 +493,12 @@
int rc = 0;
rc = qpnp_iadc_calibrate_for_trim();
- if (rc) {
- pr_err("periodic IADC calibration failed\n");
- iadc->iadc_err_cnt++;
- }
-
- if (iadc->iadc_err_cnt < QPNP_IADC_ERR_CHK_RATELIMIT)
+ if (rc)
+ pr_debug("periodic IADC calibration failed\n");
+ else
schedule_delayed_work(&iadc->iadc_work,
round_jiffies_relative(msecs_to_jiffies
(QPNP_IADC_CALIB_SECONDS)));
-
return;
}
@@ -857,7 +851,6 @@
mutex_init(&iadc->iadc_vadc_lock);
INIT_DELAYED_WORK(&iadc->iadc_work, qpnp_iadc_work);
- iadc->iadc_err_cnt = 0;
iadc->iadc_initialized = true;
rc = qpnp_iadc_calibrate_for_trim();
diff --git a/drivers/hwmon/qpnp-adc-voltage.c b/drivers/hwmon/qpnp-adc-voltage.c
index e268541..d296a47 100644
--- a/drivers/hwmon/qpnp-adc-voltage.c
+++ b/drivers/hwmon/qpnp-adc-voltage.c
@@ -90,6 +90,7 @@
#define QPNP_VADC_CONV_TIME_MIN 2000
#define QPNP_VADC_CONV_TIME_MAX 2100
#define QPNP_ADC_COMPLETION_TIMEOUT HZ
+#define QPNP_VADC_ERR_COUNT 5
struct qpnp_vadc_drv {
struct qpnp_adc_drv *adc;
@@ -434,7 +435,7 @@
{
struct qpnp_vadc_drv *vadc = qpnp_vadc;
struct qpnp_adc_amux_properties conv;
- int rc, calib_read_1, calib_read_2;
+ int rc, calib_read_1, calib_read_2, count = 0;
u8 status1 = 0;
conv.amux_channel = REF_125V;
@@ -456,6 +457,11 @@
status1 &= QPNP_VADC_STATUS1_REQ_STS_EOC_MASK;
usleep_range(QPNP_VADC_CONV_TIME_MIN,
QPNP_VADC_CONV_TIME_MAX);
+ count++;
+ if (count > QPNP_VADC_ERR_COUNT) {
+ rc = -ENODEV;
+ goto calib_fail;
+ }
}
rc = qpnp_vadc_read_conversion_result(&calib_read_1);
@@ -476,6 +482,7 @@
}
status1 = 0;
+ count = 0;
while (status1 != QPNP_VADC_STATUS1_EOC) {
rc = qpnp_vadc_read_reg(QPNP_VADC_STATUS1, &status1);
if (rc < 0)
@@ -483,6 +490,11 @@
status1 &= QPNP_VADC_STATUS1_REQ_STS_EOC_MASK;
usleep_range(QPNP_VADC_CONV_TIME_MIN,
QPNP_VADC_CONV_TIME_MAX);
+ count++;
+ if (count > QPNP_VADC_ERR_COUNT) {
+ rc = -ENODEV;
+ goto calib_fail;
+ }
}
rc = qpnp_vadc_read_conversion_result(&calib_read_2);
@@ -516,6 +528,7 @@
}
status1 = 0;
+ count = 0;
while (status1 != QPNP_VADC_STATUS1_EOC) {
rc = qpnp_vadc_read_reg(QPNP_VADC_STATUS1, &status1);
if (rc < 0)
@@ -523,6 +536,11 @@
status1 &= QPNP_VADC_STATUS1_REQ_STS_EOC_MASK;
usleep_range(QPNP_VADC_CONV_TIME_MIN,
QPNP_VADC_CONV_TIME_MAX);
+ count++;
+ if (count > QPNP_VADC_ERR_COUNT) {
+ rc = -ENODEV;
+ goto calib_fail;
+ }
}
rc = qpnp_vadc_read_conversion_result(&calib_read_1);
@@ -543,6 +561,7 @@
}
status1 = 0;
+ count = 0;
while (status1 != QPNP_VADC_STATUS1_EOC) {
rc = qpnp_vadc_read_reg(QPNP_VADC_STATUS1, &status1);
if (rc < 0)
@@ -550,6 +569,11 @@
status1 &= QPNP_VADC_STATUS1_REQ_STS_EOC_MASK;
usleep_range(QPNP_VADC_CONV_TIME_MIN,
QPNP_VADC_CONV_TIME_MAX);
+ count++;
+ if (count > QPNP_VADC_ERR_COUNT) {
+ rc = -ENODEV;
+ goto calib_fail;
+ }
}
rc = qpnp_vadc_read_conversion_result(&calib_read_2);
diff --git a/drivers/input/touchscreen/synaptics_fw_update.c b/drivers/input/touchscreen/synaptics_fw_update.c
index 5d66241..986c062 100644
--- a/drivers/input/touchscreen/synaptics_fw_update.c
+++ b/drivers/input/touchscreen/synaptics_fw_update.c
@@ -30,7 +30,6 @@
#define DEBUG_FW_UPDATE
#define SHOW_PROGRESS
-#define FW_IMAGE_NAME "PR1063486-s7301_00000000.img"
#define MAX_FIRMWARE_ID_LEN 10
#define FORCE_UPDATE false
#define INSIDE_FIRMWARE_UPDATE
@@ -585,7 +584,8 @@
deviceFirmwareID = extract_uint(firmware_id);
/* .img firmware id */
- strptr = strstr(FW_IMAGE_NAME, "PR");
+ strptr = strnstr(fwu->rmi4_data->fw_image_name, "PR",
+ sizeof(fwu->rmi4_data->fw_image_name));
if (!strptr) {
dev_err(&i2c_client->dev,
"No valid PR number (PRxxxxxxx)" \
@@ -1219,19 +1219,28 @@
pr_notice("%s: Start of reflash process\n", __func__);
+ if (!fwu->rmi4_data->fw_image_name) {
+ retval = 0;
+ dev_err(&fwu->rmi4_data->i2c_client->dev,
+ "Firmware image name not given, skipping update\n");
+ goto exit;
+ }
+
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);
+ __func__, fwu->rmi4_data->fw_image_name);
- retval = request_firmware(&fw_entry, FW_IMAGE_NAME,
+ retval = request_firmware(&fw_entry,
+ fwu->rmi4_data->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);
+ __func__,
+ fwu->rmi4_data->fw_image_name);
retval = -EINVAL;
goto exit;
}
diff --git a/drivers/input/touchscreen/synaptics_i2c_rmi4.c b/drivers/input/touchscreen/synaptics_i2c_rmi4.c
index e1b3884..417ef83 100644
--- a/drivers/input/touchscreen/synaptics_i2c_rmi4.c
+++ b/drivers/input/touchscreen/synaptics_i2c_rmi4.c
@@ -1006,6 +1006,13 @@
rmi4_pdata->panel_y = temp_val;
}
+ rc = of_property_read_string(np, "synaptics,fw-image-name",
+ &rmi4_pdata->fw_image_name);
+ if (rc && (rc != -EINVAL)) {
+ dev_err(dev, "Unable to read fw image name\n");
+ return rc;
+ }
+
/* reset, irq gpio info */
rmi4_pdata->reset_gpio = of_get_named_gpio_flags(np,
"synaptics,reset-gpio", 0, &rmi4_pdata->reset_flags);
@@ -2030,6 +2037,8 @@
rmi4_data->flip_x = rmi4_data->board->x_flip;
rmi4_data->flip_y = rmi4_data->board->y_flip;
+ rmi4_data->fw_image_name = rmi4_data->board->fw_image_name;
+
rmi4_data->input_dev->name = DRIVER_NAME;
rmi4_data->input_dev->phys = INPUT_PHYS_NAME;
rmi4_data->input_dev->id.bustype = BUS_I2C;
diff --git a/drivers/input/touchscreen/synaptics_i2c_rmi4.h b/drivers/input/touchscreen/synaptics_i2c_rmi4.h
index 9356937..16b1f8f 100644
--- a/drivers/input/touchscreen/synaptics_i2c_rmi4.h
+++ b/drivers/input/touchscreen/synaptics_i2c_rmi4.h
@@ -198,6 +198,7 @@
#ifdef CONFIG_HAS_EARLYSUSPEND
struct early_suspend early_suspend;
#endif
+ const char *fw_image_name;
unsigned char current_page;
unsigned char button_0d_enabled;
unsigned char full_pm_cycle;
diff --git a/drivers/iommu/msm_iommu-v1.c b/drivers/iommu/msm_iommu-v1.c
index fa5ca8c..8a26003 100644
--- a/drivers/iommu/msm_iommu-v1.c
+++ b/drivers/iommu/msm_iommu-v1.c
@@ -232,8 +232,6 @@
SET_GFAR(base, 0);
SET_GFSRRESTORE(base, 0);
SET_TLBIALLNSNH(base, 0);
- SET_SCR1(base, 0);
- SET_SSDR_N(base, 0, 0);
smt_size = GET_IDR0_NUMSMRG(base);
for (i = 0; i < smt_size; i++)
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 ad8aa82..1b762ea 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
@@ -33,7 +33,7 @@
#define MAX_NUM_COMPOSITE_MASK 4
#define MAX_NUM_STATS_COMP_MASK 2
#define MAX_INIT_FRAME_DROP 31
-#define ISP_SUB(a) ((a > 0) ? a-1 : 0)
+#define ISP_Q2 (1 << 2)
#define VFE_PING_FLAG 0xFFFFFFFF
#define VFE_PONG_FLAG 0x0
@@ -183,6 +183,7 @@
struct msm_vfe_hardware_info {
int num_iommu_ctx;
+ int vfe_clk_idx;
struct msm_vfe_ops vfe_ops;
struct msm_vfe_axi_hardware_info *axi_hw_info;
struct msm_vfe_stats_hardware_info *stats_hw_info;
@@ -206,6 +207,7 @@
PAUSE,
START_PENDING,
STOP_PENDING,
+ STARTING,
STOPPING,
PAUSE_PENDING,
};
@@ -246,9 +248,16 @@
uint32_t burst_frame_count;/*number of sof before burst stop*/
uint8_t framedrop_update;
+ /*Bandwidth calculation info*/
+ uint32_t max_width;
+ /*Based on format plane size in Q2. e.g NV12 = 1.5*/
+ uint32_t format_factor;
+ uint32_t bandwidth;
+
/*Run time update variables*/
uint32_t runtime_init_frame_drop;
uint32_t runtime_burst_frame_count;/*number of sof before burst stop*/
+ uint32_t runtime_num_burst_capture;
uint8_t runtime_framedrop_update;
};
@@ -263,6 +272,8 @@
uint8_t pix_stream_count;
uint8_t raw_stream_count;
enum msm_vfe_inputmux input_mux;
+ uint32_t width;
+ long pixel_clock;
};
enum msm_wm_ub_cfg_type {
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 b981653..31fa39e 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
@@ -39,42 +39,7 @@
(VFE32_STATS_BASE(idx) + 0x4 * \
(~(ping_pong >> (idx + VFE32_STATS_PING_PONG_OFFSET)) & 0x1))
-/*Temporary use fixed bus vectors in VFE */
-static struct msm_bus_vectors msm_vfe32_init_vectors[] = {
- {
- .src = MSM_BUS_MASTER_VFE,
- .dst = MSM_BUS_SLAVE_EBI_CH0,
- .ab = 0,
- .ib = 0,
- },
-};
-
-static struct msm_bus_vectors msm_vfe32_preview_vectors[] = {
- {
- .src = MSM_BUS_MASTER_VFE,
- .dst = MSM_BUS_SLAVE_EBI_CH0,
- .ab = 1027648000,
- .ib = 1105920000,
- },
-};
-
-static struct msm_bus_paths msm_vfe32_bus_client_config[] = {
- {
- ARRAY_SIZE(msm_vfe32_init_vectors),
- msm_vfe32_init_vectors,
- },
- {
- ARRAY_SIZE(msm_vfe32_preview_vectors),
- msm_vfe32_preview_vectors,
- },
-};
-
-static struct msm_bus_scale_pdata msm_vfe32_bus_client_pdata = {
- msm_vfe32_bus_client_config,
- ARRAY_SIZE(msm_vfe32_bus_client_config),
- .name = "msm_camera_vfe",
-};
-
+#define VFE32_CLK_IDX 0
static struct msm_cam_clk_info msm_vfe32_clk_info[] = {
{"vfe_clk", 266667000},
{"vfe_pclk", -1},
@@ -84,15 +49,11 @@
static int msm_vfe32_init_hardware(struct vfe_device *vfe_dev)
{
int rc = -1;
-
- vfe_dev->bus_perf_client =
- msm_bus_scale_register_client(&msm_vfe32_bus_client_pdata);
- if (!vfe_dev->bus_perf_client) {
- pr_err("%s: Registration Failed!\n", __func__);
- vfe_dev->bus_perf_client = 0;
+ rc = msm_isp_init_bandwidth_mgr(ISP_VFE0 + vfe_dev->pdev->id);
+ if (rc < 0) {
+ pr_err("%s: Bandwidth registration Failed!\n", __func__);
goto bus_scale_register_failed;
}
- msm_bus_scale_client_update_request(vfe_dev->bus_perf_client, 1);
if (vfe_dev->fs_vfe) {
rc = regulator_enable(vfe_dev->fs_vfe);
@@ -131,8 +92,7 @@
clk_enable_failed:
regulator_disable(vfe_dev->fs_vfe);
fs_failed:
- msm_bus_scale_client_update_request(vfe_dev->bus_perf_client, 0);
- msm_bus_scale_unregister_client(vfe_dev->bus_perf_client);
+ msm_isp_deinit_bandwidth_mgr(ISP_VFE0 + vfe_dev->pdev->id);
bus_scale_register_failed:
return rc;
}
@@ -145,8 +105,7 @@
msm_cam_clk_enable(&vfe_dev->pdev->dev, msm_vfe32_clk_info,
vfe_dev->vfe_clk, ARRAY_SIZE(msm_vfe32_clk_info), 0);
regulator_disable(vfe_dev->fs_vfe);
- msm_bus_scale_client_update_request(vfe_dev->bus_perf_client, 0);
- msm_bus_scale_unregister_client(vfe_dev->bus_perf_client);
+ msm_isp_deinit_bandwidth_mgr(ISP_VFE0 + vfe_dev->pdev->id);
}
static void msm_vfe32_init_hardware_reg(struct vfe_device *vfe_dev)
@@ -1021,6 +980,7 @@
struct msm_vfe_hardware_info vfe32_hw_info = {
.num_iommu_ctx = 2,
+ .vfe_clk_idx = VFE32_CLK_IDX,
.vfe_ops = {
.irq_ops = {
.read_irq_status = msm_vfe32_read_irq_status,
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 a786750..256d136 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
@@ -77,42 +77,7 @@
#define VFE40_BUS_BDG_QOS_CFG_6 0x000002DC
#define VFE40_BUS_BDG_QOS_CFG_7 0x000002E0
-/*Temporary use fixed bus vectors in VFE */
-static struct msm_bus_vectors msm_vfe40_init_vectors[] = {
- {
- .src = MSM_BUS_MASTER_VFE,
- .dst = MSM_BUS_SLAVE_EBI_CH0,
- .ab = 0,
- .ib = 0,
- },
-};
-
-static struct msm_bus_vectors msm_vfe40_preview_vectors[] = {
- {
- .src = MSM_BUS_MASTER_VFE,
- .dst = MSM_BUS_SLAVE_EBI_CH0,
- .ab = 2027648000U,
- .ib = 2805920000U,
- },
-};
-
-static struct msm_bus_paths msm_vfe40_bus_client_config[] = {
- {
- ARRAY_SIZE(msm_vfe40_init_vectors),
- msm_vfe40_init_vectors,
- },
- {
- ARRAY_SIZE(msm_vfe40_preview_vectors),
- msm_vfe40_preview_vectors,
- },
-};
-
-static struct msm_bus_scale_pdata msm_vfe40_bus_client_pdata = {
- msm_vfe40_bus_client_config,
- ARRAY_SIZE(msm_vfe40_bus_client_config),
- .name = "msm_camera_vfe",
-};
-
+#define VFE40_CLK_IDX 1
static struct msm_cam_clk_info msm_vfe40_clk_info[] = {
{"camss_top_ahb_clk", -1},
{"vfe_clk_src", 266670000},
@@ -223,16 +188,11 @@
static int msm_vfe40_init_hardware(struct vfe_device *vfe_dev)
{
int rc = -1;
-
- vfe_dev->bus_perf_client =
- msm_bus_scale_register_client(&msm_vfe40_bus_client_pdata);
- if (!vfe_dev->bus_perf_client) {
- pr_err("%s: Registration Failed!\n", __func__);
- vfe_dev->bus_perf_client = 0;
+ rc = msm_isp_init_bandwidth_mgr(ISP_VFE0 + vfe_dev->pdev->id);
+ if (rc < 0) {
+ pr_err("%s: Bandwidth registration Failed!\n", __func__);
goto bus_scale_register_failed;
}
- msm_bus_scale_client_update_request(
- vfe_dev->bus_perf_client, 1);
if (vfe_dev->fs_vfe) {
rc = regulator_enable(vfe_dev->fs_vfe);
@@ -280,8 +240,7 @@
clk_enable_failed:
regulator_disable(vfe_dev->fs_vfe);
fs_failed:
- msm_bus_scale_client_update_request(vfe_dev->bus_perf_client, 0);
- msm_bus_scale_unregister_client(vfe_dev->bus_perf_client);
+ msm_isp_deinit_bandwidth_mgr(ISP_VFE0 + vfe_dev->pdev->id);
bus_scale_register_failed:
return rc;
}
@@ -295,8 +254,7 @@
msm_cam_clk_enable(&vfe_dev->pdev->dev, msm_vfe40_clk_info,
vfe_dev->vfe_clk, ARRAY_SIZE(msm_vfe40_clk_info), 0);
regulator_disable(vfe_dev->fs_vfe);
- msm_bus_scale_client_update_request(vfe_dev->bus_perf_client, 0);
- msm_bus_scale_unregister_client(vfe_dev->bus_perf_client);
+ msm_isp_deinit_bandwidth_mgr(ISP_VFE0 + vfe_dev->pdev->id);
}
static void msm_vfe40_init_hardware_reg(struct vfe_device *vfe_dev)
@@ -1288,6 +1246,7 @@
struct msm_vfe_hardware_info vfe40_hw_info = {
.num_iommu_ctx = 1,
+ .vfe_clk_idx = VFE40_CLK_IDX,
.vfe_ops = {
.irq_ops = {
.read_irq_status = msm_vfe40_read_irq_status,
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 f1bfd68..477985d 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
@@ -18,6 +18,8 @@
((src < RDI_INTF_0) ? VFE_PIX_0 : \
(VFE_RAW_0 + src - RDI_INTF_0))
+#define HANDLE_TO_IDX(handle) (handle & 0xFF)
+
int msm_isp_axi_create_stream(
struct msm_vfe_axi_shared_data *axi_data,
struct msm_vfe_axi_stream_request_cmd *stream_cfg_cmd)
@@ -67,7 +69,7 @@
int rc = -1, i;
struct msm_vfe_axi_stream *stream_info =
&axi_data->stream_info[
- (stream_cfg_cmd->axi_stream_handle & 0xFF)];
+ HANDLE_TO_IDX(stream_cfg_cmd->axi_stream_handle)];
switch (stream_cfg_cmd->output_format) {
case V4L2_PIX_FMT_SBGGR8:
@@ -95,12 +97,14 @@
case V4L2_PIX_FMT_QGRBG12:
case V4L2_PIX_FMT_QRGGB12:
stream_info->num_planes = 1;
+ stream_info->format_factor = ISP_Q2;
break;
case V4L2_PIX_FMT_NV12:
case V4L2_PIX_FMT_NV21:
case V4L2_PIX_FMT_NV16:
case V4L2_PIX_FMT_NV61:
stream_info->num_planes = 2;
+ stream_info->format_factor = 1.5 * ISP_Q2;
break;
/*TD: Add more image format*/
default:
@@ -131,9 +135,12 @@
return rc;
}
- for (i = 0; i < stream_info->num_planes; i++)
+ for (i = 0; i < stream_info->num_planes; i++) {
stream_info->plane_offset[i] =
stream_cfg_cmd->plane_cfg[i].plane_addr_offset;
+ stream_info->max_width = max(stream_info->max_width,
+ stream_cfg_cmd->plane_cfg[i].output_width);
+ }
stream_info->stream_src = stream_cfg_cmd->stream_src;
stream_info->frame_based = stream_cfg_cmd->frame_base;
@@ -209,7 +216,7 @@
int i, j;
struct msm_vfe_axi_stream *stream_info =
&axi_data->stream_info[
- (stream_cfg_cmd->axi_stream_handle & 0xFF)];
+ HANDLE_TO_IDX(stream_cfg_cmd->axi_stream_handle)];
for (i = 0; i < stream_info->num_planes; i++) {
for (j = 0; j < axi_data->hw_info->num_wm; j++) {
@@ -245,7 +252,7 @@
uint8_t comp_mask = 0;
struct msm_vfe_axi_stream *stream_info =
&axi_data->stream_info[
- (stream_cfg_cmd->axi_stream_handle & 0xFF)];
+ HANDLE_TO_IDX(stream_cfg_cmd->axi_stream_handle)];
for (i = 0; i < stream_info->num_planes; i++)
comp_mask |= 1 << stream_info->wm[i];
@@ -285,7 +292,7 @@
for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
stream_info = &axi_data->stream_info[
- (stream_cfg_cmd->stream_handle[i] & 0xFF)];
+ HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])];
if (stream_info->state != valid_state) {
pr_err("%s: Invalid stream state\n", __func__);
rc = -EINVAL;
@@ -344,6 +351,8 @@
stream_info->runtime_init_frame_drop = stream_info->init_frame_drop;
stream_info->runtime_burst_frame_count =
stream_info->burst_frame_count;
+ stream_info->runtime_num_burst_capture =
+ stream_info->num_burst_capture;
stream_info->runtime_framedrop_update = stream_info->framedrop_update;
vfe_dev->hw_info->vfe_ops.axi_ops.cfg_framedrop(vfe_dev, stream_info);
}
@@ -411,7 +420,7 @@
{
struct msm_vfe_axi_stream *stream_info =
&axi_data->stream_info[
- (stream_cfg_cmd->axi_stream_handle & 0xFF)];
+ HANDLE_TO_IDX(stream_cfg_cmd->axi_stream_handle)];
uint32_t framedrop_period = msm_isp_get_framedrop_period(
stream_cfg_cmd->frame_skip_pattern);
@@ -443,6 +452,23 @@
}
}
+void msm_isp_calculate_bandwidth(
+ struct msm_vfe_axi_shared_data *axi_data,
+ struct msm_vfe_axi_stream *stream_info)
+{
+ if (stream_info->stream_src < RDI_INTF_0) {
+ stream_info->bandwidth =
+ (axi_data->src_info[VFE_PIX_0].pixel_clock /
+ axi_data->src_info[VFE_PIX_0].width) *
+ stream_info->max_width;
+ stream_info->bandwidth = stream_info->bandwidth *
+ stream_info->format_factor / ISP_Q2;
+ } else {
+ int rdi = SRC_TO_INTF(stream_info->stream_src);
+ stream_info->bandwidth = axi_data->src_info[rdi].pixel_clock;
+ }
+}
+
int msm_isp_request_axi_stream(struct vfe_device *vfe_dev, void *arg)
{
int rc = 0, i;
@@ -461,13 +487,12 @@
if (rc) {
pr_err("%s: Request validation failed\n", __func__);
msm_isp_axi_destroy_stream(&vfe_dev->axi_data,
- (stream_cfg_cmd->axi_stream_handle & 0xFF));
+ HANDLE_TO_IDX(stream_cfg_cmd->axi_stream_handle));
return rc;
}
- stream_info =
- &vfe_dev->axi_data.
- stream_info[(stream_cfg_cmd->axi_stream_handle & 0xFF)];
+ stream_info = &vfe_dev->axi_data.
+ stream_info[HANDLE_TO_IDX(stream_cfg_cmd->axi_stream_handle)];
msm_isp_axi_reserve_wm(&vfe_dev->axi_data, stream_cfg_cmd);
if (stream_cfg_cmd->stream_src == CAMIF_RAW ||
@@ -504,7 +529,7 @@
struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
struct msm_vfe_axi_stream *stream_info =
&axi_data->stream_info[
- (stream_release_cmd->stream_handle & 0xFF)];
+ HANDLE_TO_IDX(stream_release_cmd->stream_handle)];
struct msm_vfe_axi_stream_cfg_cmd stream_cfg;
if (stream_info->state == AVALIABLE) {
@@ -538,79 +563,70 @@
msm_isp_axi_free_wm(axi_data, stream_info);
msm_isp_axi_destroy_stream(&vfe_dev->axi_data,
- (stream_release_cmd->stream_handle & 0xFF));
+ HANDLE_TO_IDX(stream_release_cmd->stream_handle));
return rc;
}
-void msm_isp_axi_stream_enable_cfg(
+static void msm_isp_axi_stream_enable_cfg(
struct vfe_device *vfe_dev,
- struct msm_vfe_axi_stream *stream_info,
- uint32_t *wm_reload_mask)
+ struct msm_vfe_axi_stream *stream_info)
{
int i;
struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
if (stream_info->state == INACTIVE)
return;
for (i = 0; i < stream_info->num_planes; i++) {
- /*TD: Frame base command*/
if (stream_info->state == START_PENDING)
vfe_dev->hw_info->vfe_ops.axi_ops.
enable_wm(vfe_dev, stream_info->wm[i], 1);
else
vfe_dev->hw_info->vfe_ops.axi_ops.
enable_wm(vfe_dev, stream_info->wm[i], 0);
-
- *wm_reload_mask |= (1 << stream_info->wm[i]);
}
- if (stream_info->state == START_PENDING) {
+ if (stream_info->state == START_PENDING)
axi_data->num_active_stream++;
- stream_info->state = ACTIVE;
- } else {
+ else
axi_data->num_active_stream--;
- stream_info->state = INACTIVE;
- }
}
void msm_isp_axi_stream_update(struct vfe_device *vfe_dev)
{
int i;
struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
- uint32_t wm_reload_mask = 0x0;
for (i = 0; i < MAX_NUM_STREAM; i++) {
if (axi_data->stream_info[i].state == START_PENDING ||
axi_data->stream_info[i].state ==
STOP_PENDING) {
msm_isp_axi_stream_enable_cfg(
- vfe_dev, &axi_data->stream_info[i],
- &wm_reload_mask);
- if (axi_data->stream_info[i].state == STOP_PENDING)
- axi_data->stream_info[i].state = STOPPING;
+ vfe_dev, &axi_data->stream_info[i]);
+ axi_data->stream_info[i].state =
+ axi_data->stream_info[i].state ==
+ START_PENDING ? STARTING : STOPPING;
+ } else if (axi_data->stream_info[i].state == STARTING ||
+ axi_data->stream_info[i].state == STOPPING) {
+ axi_data->stream_info[i].state =
+ axi_data->stream_info[i].state == STARTING ?
+ ACTIVE : INACTIVE;
}
}
- /*Reload AXI*/
- vfe_dev->hw_info->vfe_ops.axi_ops.
- reload_wm(vfe_dev, wm_reload_mask);
- if (vfe_dev->axi_data.stream_update) {
- vfe_dev->hw_info->vfe_ops.core_ops.reg_update(vfe_dev);
- ISP_DBG("%s: send update complete\n", __func__);
- vfe_dev->axi_data.stream_update = 0;
+ vfe_dev->axi_data.stream_update--;
+ if (vfe_dev->axi_data.stream_update == 0)
complete(&vfe_dev->stream_config_complete);
- }
}
static void msm_isp_cfg_pong_address(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info)
{
int i;
- struct msm_isp_buffer *buf = stream_info->buf[1];
+ struct msm_isp_buffer *buf = stream_info->buf[0];
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 +
+ VFE_PONG_FLAG, buf->mapped_info[i].paddr +
stream_info->plane_offset[i]);
- stream_info->buf[0] = buf;
+ stream_info->buf[1] = buf;
}
static void msm_isp_get_done_buf(struct vfe_device *vfe_dev,
@@ -636,7 +652,7 @@
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;
+ uint32_t stream_idx = HANDLE_TO_IDX(stream_info->stream_handle);
rc = vfe_dev->buf_mgr->ops->get_buf(vfe_dev->buf_mgr,
vfe_dev->pdev->id, bufq_handle, &buf);
@@ -673,7 +689,7 @@
{
int rc;
struct msm_isp_event_data buf_event;
- uint32_t stream_idx = stream_info->stream_handle & 0xFF;
+ uint32_t stream_idx = HANDLE_TO_IDX(stream_info->stream_handle);
uint32_t frame_id = vfe_dev->axi_data.
src_info[SRC_TO_INTF(stream_info->stream_src)].frame_id;
@@ -724,7 +740,7 @@
for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
stream_info =
&axi_data->stream_info[
- (stream_cfg_cmd->stream_handle[i] & 0xFF)];
+ HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])];
if (stream_info->stream_src < RDI_INTF_0)
pix_stream_cnt++;
if (stream_info->stream_src == PIX_ENCODER ||
@@ -793,16 +809,193 @@
ISP_DBG("%s\n", line_str);
}
-int msm_isp_cfg_axi_stream(struct vfe_device *vfe_dev, void *arg)
+/*Factor in Q2 format*/
+#define ISP_DEFAULT_FORMAT_FACTOR 6
+#define ISP_BUS_UTILIZATION_FACTOR 6
+static int msm_isp_update_stream_bandwidth(struct vfe_device *vfe_dev)
{
- int rc = 0, i;
- struct msm_vfe_axi_stream_cfg_cmd *stream_cfg_cmd = arg;
+ int i, rc = 0;
+ struct msm_vfe_axi_stream *stream_info;
+ struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
+ uint32_t total_pix_bandwidth = 0, total_rdi_bandwidth = 0;
+ uint32_t num_pix_streams = 0;
+ uint64_t total_bandwidth = 0;
+
+ for (i = 0; i < MAX_NUM_STREAM; i++) {
+ stream_info = &axi_data->stream_info[i];
+ if (stream_info->state == ACTIVE ||
+ stream_info->state == START_PENDING) {
+ if (stream_info->stream_src < RDI_INTF_0) {
+ total_pix_bandwidth += stream_info->bandwidth;
+ num_pix_streams++;
+ } else {
+ total_rdi_bandwidth += stream_info->bandwidth;
+ }
+ }
+ }
+ if (num_pix_streams > 0)
+ total_pix_bandwidth = total_pix_bandwidth /
+ num_pix_streams * (num_pix_streams - 1) +
+ axi_data->src_info[VFE_PIX_0].pixel_clock *
+ ISP_DEFAULT_FORMAT_FACTOR / ISP_Q2;
+ total_bandwidth = total_pix_bandwidth + total_rdi_bandwidth;
+
+ rc = msm_isp_update_bandwidth(ISP_VFE0 + vfe_dev->pdev->id,
+ total_bandwidth, total_bandwidth *
+ ISP_BUS_UTILIZATION_FACTOR / ISP_Q2);
+ if (rc < 0)
+ pr_err("%s: update failed\n", __func__);
+
+ return rc;
+}
+
+static int msm_isp_axi_wait_for_cfg_done(struct vfe_device *vfe_dev)
+{
+ int rc;
+ unsigned long flags;
+ spin_lock_irqsave(&vfe_dev->shared_data_lock, flags);
+ init_completion(&vfe_dev->stream_config_complete);
+ vfe_dev->axi_data.stream_update = 2;
+ spin_unlock_irqrestore(&vfe_dev->shared_data_lock, flags);
+ rc = wait_for_completion_interruptible_timeout(
+ &vfe_dev->stream_config_complete,
+ msecs_to_jiffies(500));
+ if (rc == 0) {
+ pr_err("%s: wait timeout\n", __func__);
+ rc = -1;
+ } else {
+ rc = 0;
+ }
+ return rc;
+}
+
+static int msm_isp_init_stream_ping_pong_reg(
+ struct vfe_device *vfe_dev,
+ struct msm_vfe_axi_stream *stream_info)
+{
+ int rc = 0;
+ /*Set address for both PING & PONG register */
+ rc = msm_isp_cfg_ping_pong_address(vfe_dev,
+ stream_info, VFE_PING_FLAG);
+ if (rc < 0) {
+ pr_err("%s: No free buffer for ping\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->runtime_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_PONG_FLAG);
+ if (rc < 0) {
+ pr_err("%s: No free buffer for pong\n",
+ __func__);
+ return rc;
+ }
+ }
+ return rc;
+}
+
+static void msm_isp_get_stream_wm_mask(
+ struct msm_vfe_axi_stream *stream_info,
+ uint32_t *wm_reload_mask)
+{
+ int i;
+ for (i = 0; i < stream_info->num_planes; i++)
+ *wm_reload_mask |= (1 << stream_info->wm[i]);
+}
+
+static int msm_isp_start_axi_stream(struct vfe_device *vfe_dev,
+ struct msm_vfe_axi_stream_cfg_cmd *stream_cfg_cmd,
+ enum msm_isp_camif_update_state camif_update)
+{
+ int i, rc = 0;
+ uint8_t src_state, wait_for_complete = 0;
uint32_t wm_reload_mask = 0x0;
struct msm_vfe_axi_stream *stream_info;
struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
- uint8_t src_state;
+ for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
+ stream_info = &axi_data->stream_info[
+ HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])];
+ src_state = axi_data->src_info[
+ SRC_TO_INTF(stream_info->stream_src)].active;
+
+ msm_isp_calculate_bandwidth(axi_data, stream_info);
+ msm_isp_reset_framedrop(vfe_dev, stream_info);
+ msm_isp_get_stream_wm_mask(stream_info, &wm_reload_mask);
+ rc = msm_isp_init_stream_ping_pong_reg(vfe_dev, stream_info);
+ if (rc < 0) {
+ pr_err("%s: No buffer for stream%d\n", __func__,
+ HANDLE_TO_IDX(
+ stream_cfg_cmd->stream_handle[i]));
+ return rc;
+ }
+
+ stream_info->state = START_PENDING;
+ if (src_state) {
+ wait_for_complete = 1;
+ } else {
+ if (vfe_dev->dump_reg)
+ msm_camera_io_dump_2(vfe_dev->vfe_base, 0x900);
+
+ /*Configure AXI start bits to start immediately*/
+ msm_isp_axi_stream_enable_cfg(vfe_dev, stream_info);
+ stream_info->state = ACTIVE;
+ }
+ }
+ msm_isp_update_stream_bandwidth(vfe_dev);
+ vfe_dev->hw_info->vfe_ops.axi_ops.reload_wm(vfe_dev, wm_reload_mask);
+ vfe_dev->hw_info->vfe_ops.core_ops.reg_update(vfe_dev);
+
+ if (camif_update == ENABLE_CAMIF)
+ vfe_dev->hw_info->vfe_ops.core_ops.
+ update_camif_state(vfe_dev, camif_update);
+
+ if (wait_for_complete)
+ rc = msm_isp_axi_wait_for_cfg_done(vfe_dev);
+
+ return rc;
+}
+
+static int msm_isp_stop_axi_stream(struct vfe_device *vfe_dev,
+ struct msm_vfe_axi_stream_cfg_cmd *stream_cfg_cmd,
+ enum msm_isp_camif_update_state camif_update)
+{
+ int i, rc = 0;
+ struct msm_vfe_axi_stream *stream_info;
+ struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
+ for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
+ stream_info = &axi_data->stream_info[
+ HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])];
+ stream_info->state = STOP_PENDING;
+ }
+
+ rc = msm_isp_axi_wait_for_cfg_done(vfe_dev);
+ if (rc < 0) {
+ pr_err("%s: wait for config done failed\n", __func__);
+ return rc;
+ }
+ msm_isp_update_stream_bandwidth(vfe_dev);
+ if (camif_update == DISABLE_CAMIF)
+ vfe_dev->hw_info->vfe_ops.core_ops.
+ update_camif_state(vfe_dev, DISABLE_CAMIF);
+ return rc;
+}
+
+
+int msm_isp_cfg_axi_stream(struct vfe_device *vfe_dev, void *arg)
+{
+ int rc = 0;
+ struct msm_vfe_axi_stream_cfg_cmd *stream_cfg_cmd = arg;
+ struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
enum msm_isp_camif_update_state camif_update;
- uint8_t wait_for_complete = 0;
+
rc = msm_isp_axi_check_stream_state(vfe_dev, stream_cfg_cmd);
if (rc < 0) {
pr_err("%s: Invalid stream state\n", __func__);
@@ -813,104 +1006,18 @@
/*Configure UB*/
vfe_dev->hw_info->vfe_ops.axi_ops.cfg_ub(vfe_dev);
}
-
camif_update =
msm_isp_update_camif_output_count(vfe_dev, stream_cfg_cmd);
- if (camif_update == DISABLE_CAMIF)
- vfe_dev->hw_info->vfe_ops.core_ops.
- update_camif_state(vfe_dev, DISABLE_CAMIF);
+ if (stream_cfg_cmd->cmd == START_STREAM)
+ rc = msm_isp_start_axi_stream(
+ vfe_dev, stream_cfg_cmd, camif_update);
+ else
+ rc = msm_isp_stop_axi_stream(
+ vfe_dev, stream_cfg_cmd, camif_update);
- /*
- * Stream start either immediately or at reg update
- * Depends on whether the stream src is active
- * If source is on, start and stop have to be done during reg update
- * If source is off, start can happen immediately or during reg update
- * stop has to be done immediately.
- */
- for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
- stream_info =
- &axi_data->stream_info[
- (stream_cfg_cmd->stream_handle[i] & 0xFF)];
-
- if (stream_info->stream_src < RDI_INTF_0)
- src_state = axi_data->src_info[0].active;
- else
- src_state = axi_data->src_info[
- (stream_info->stream_src - RDI_INTF_0)].active;
-
- stream_info->state = (stream_cfg_cmd->cmd == START_STREAM) ?
- START_PENDING : STOP_PENDING;
-
- if (stream_cfg_cmd->cmd == START_STREAM) {
- /*Configure framedrop*/
- msm_isp_reset_framedrop(vfe_dev, stream_info);
-
- /*Set address for both PING & PONG register */
- rc = msm_isp_cfg_ping_pong_address(vfe_dev,
- 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 */
- wait_for_complete = 1;
- } else {
- if (vfe_dev->dump_reg &&
- stream_cfg_cmd->cmd == START_STREAM)
- msm_camera_io_dump_2(vfe_dev->vfe_base, 0x900);
- /*Configure AXI start bits to start immediately*/
- msm_isp_axi_stream_enable_cfg(
- vfe_dev, stream_info, &wm_reload_mask);
- }
- }
- if (!wait_for_complete) {
- /*Reload AXI*/
- if (stream_cfg_cmd->cmd == START_STREAM)
- vfe_dev->hw_info->vfe_ops.axi_ops.
- reload_wm(vfe_dev, wm_reload_mask);
-
- vfe_dev->hw_info->vfe_ops.core_ops.
- reg_update(vfe_dev);
-
- if (camif_update == ENABLE_CAMIF)
- vfe_dev->hw_info->vfe_ops.core_ops.
- update_camif_state(vfe_dev, camif_update);
- } else {
- unsigned long flags;
- spin_lock_irqsave(&vfe_dev->shared_data_lock, flags);
- init_completion(&vfe_dev->stream_config_complete);
- axi_data->stream_update = 1;
- spin_unlock_irqrestore(&vfe_dev->shared_data_lock, flags);
- /*Reload AXI*/
- if (stream_cfg_cmd->cmd == START_STREAM)
- vfe_dev->hw_info->vfe_ops.axi_ops.
- reload_wm(vfe_dev, wm_reload_mask);
- vfe_dev->hw_info->vfe_ops.core_ops.reg_update(vfe_dev);
- rc = wait_for_completion_interruptible_timeout(
- &vfe_dev->stream_config_complete,
- msecs_to_jiffies(500));
- if (rc == 0) {
- pr_err("%s: wait timeout\n", __func__);
- rc = -1;
- } else {
- rc = 0;
- }
- }
+ if (rc < 0)
+ pr_err("%s: start/stop stream failed\n", __func__);
return rc;
}
@@ -921,7 +1028,7 @@
struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
struct msm_vfe_axi_stream_update_cmd *update_cmd = arg;
stream_info = &axi_data->stream_info[
- (update_cmd->stream_handle & 0xFF)];
+ HANDLE_TO_IDX(update_cmd->stream_handle)];
if (stream_info->state != ACTIVE && stream_info->state != INACTIVE) {
pr_err("%s: Invalid stream state\n", __func__);
return -EINVAL;
@@ -984,18 +1091,25 @@
pr_err("%s: Invalid handle for composite irq\n",
__func__);
} else {
- stream_idx = comp_info->stream_handle & 0xFF;
+ stream_idx =
+ HANDLE_TO_IDX(comp_info->stream_handle);
stream_info =
&axi_data->stream_info[stream_idx];
ISP_DBG("%s: stream%d frame id: 0x%x\n",
__func__,
stream_idx, stream_info->frame_id);
stream_info->frame_id++;
+
+ if (stream_info->stream_type == BURST_STREAM)
+ stream_info->
+ runtime_num_burst_capture--;
+
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) {
+ stream_info->
+ runtime_num_burst_capture > 1) {
rc = msm_isp_cfg_ping_pong_address(
vfe_dev, stream_info,
pingpong_status);
@@ -1015,16 +1129,20 @@
__func__);
continue;
}
- stream_idx = axi_data->free_wm[i] & 0xFF;
+ stream_idx = HANDLE_TO_IDX(axi_data->free_wm[i]);
stream_info = &axi_data->stream_info[stream_idx];
ISP_DBG("%s: stream%d frame id: 0x%x\n",
__func__,
stream_idx, stream_info->frame_id);
stream_info->frame_id++;
+
+ if (stream_info->stream_type == BURST_STREAM)
+ stream_info->runtime_num_burst_capture--;
+
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) {
+ stream_info->runtime_num_burst_capture > 1) {
rc = msm_isp_cfg_ping_pong_address(vfe_dev,
stream_info, pingpong_status);
}
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 ba845bc..f592a60 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
@@ -46,10 +46,6 @@
int msm_isp_release_axi_stream(struct vfe_device *vfe_dev, void *arg);
int msm_isp_update_axi_stream(struct vfe_device *vfe_dev, void *arg);
-void msm_isp_axi_stream_enable_cfg(struct vfe_device *vfe_dev,
- struct msm_vfe_axi_stream *stream_info,
- uint32_t *wm_reload_mask);
-
void msm_isp_axi_stream_update(struct vfe_device *vfe_dev);
void msm_isp_update_framedrop_reg(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 3035d93..9fd87f3 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
@@ -9,6 +9,7 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
+#include <linux/mutex.h>
#include <linux/io.h>
#include <media/v4l2-subdev.h>
@@ -19,6 +20,139 @@
#include "msm_camera_io_util.h"
#define MAX_ISP_V4l2_EVENTS 100
+static DEFINE_MUTEX(bandwidth_mgr_mutex);
+static struct msm_isp_bandwidth_mgr isp_bandwidth_mgr;
+
+#define MSM_ISP_MIN_AB 300000000
+#define MSM_ISP_MIN_IB 450000000
+
+static struct msm_bus_vectors msm_isp_init_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_VFE,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 0,
+ .ib = 0,
+ },
+};
+
+static struct msm_bus_vectors msm_isp_ping_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_VFE,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = MSM_ISP_MIN_AB,
+ .ib = MSM_ISP_MIN_IB,
+ },
+};
+
+static struct msm_bus_vectors msm_isp_pong_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_VFE,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = MSM_ISP_MIN_AB,
+ .ib = MSM_ISP_MIN_IB,
+ },
+};
+
+static struct msm_bus_paths msm_isp_bus_client_config[] = {
+ {
+ ARRAY_SIZE(msm_isp_init_vectors),
+ msm_isp_init_vectors,
+ },
+ {
+ ARRAY_SIZE(msm_isp_ping_vectors),
+ msm_isp_ping_vectors,
+ },
+ {
+ ARRAY_SIZE(msm_isp_pong_vectors),
+ msm_isp_pong_vectors,
+ },
+};
+
+static struct msm_bus_scale_pdata msm_isp_bus_client_pdata = {
+ msm_isp_bus_client_config,
+ ARRAY_SIZE(msm_isp_bus_client_config),
+ .name = "msm_camera_isp",
+};
+
+int msm_isp_init_bandwidth_mgr(enum msm_isp_hw_client client)
+{
+ int rc = 0;
+ mutex_lock(&bandwidth_mgr_mutex);
+ isp_bandwidth_mgr.client_info[client].active = 1;
+ if (isp_bandwidth_mgr.use_count++) {
+ mutex_unlock(&bandwidth_mgr_mutex);
+ return rc;
+ }
+ isp_bandwidth_mgr.bus_client =
+ msm_bus_scale_register_client(&msm_isp_bus_client_pdata);
+ if (!isp_bandwidth_mgr.bus_client) {
+ pr_err("%s: client register failed\n", __func__);
+ mutex_unlock(&bandwidth_mgr_mutex);
+ return -EINVAL;
+ }
+
+ isp_bandwidth_mgr.bus_vector_active_idx = 1;
+ msm_bus_scale_client_update_request(
+ isp_bandwidth_mgr.bus_client,
+ isp_bandwidth_mgr.bus_vector_active_idx);
+
+ mutex_unlock(&bandwidth_mgr_mutex);
+ return 0;
+}
+
+int msm_isp_update_bandwidth(enum msm_isp_hw_client client,
+ uint64_t ab, uint64_t ib)
+{
+ int i;
+ struct msm_bus_paths *path;
+ mutex_lock(&bandwidth_mgr_mutex);
+ if (!isp_bandwidth_mgr.use_count ||
+ !isp_bandwidth_mgr.bus_client) {
+ pr_err("%s: bandwidth manager inactive\n", __func__);
+ return -EINVAL;
+ }
+
+ isp_bandwidth_mgr.client_info[client].ab = ab;
+ isp_bandwidth_mgr.client_info[client].ib = ib;
+ ALT_VECTOR_IDX(isp_bandwidth_mgr.bus_vector_active_idx);
+ path =
+ &(msm_isp_bus_client_pdata.usecase[
+ isp_bandwidth_mgr.bus_vector_active_idx]);
+ path->vectors[0].ab = MSM_ISP_MIN_AB;
+ path->vectors[0].ib = MSM_ISP_MIN_IB;
+ for (i = 0; i < MAX_ISP_CLIENT; i++) {
+ if (isp_bandwidth_mgr.client_info[client].active) {
+ path->vectors[0].ab +=
+ isp_bandwidth_mgr.client_info[i].ab;
+ path->vectors[0].ib +=
+ isp_bandwidth_mgr.client_info[i].ib;
+ }
+ }
+ msm_bus_scale_client_update_request(isp_bandwidth_mgr.bus_client,
+ isp_bandwidth_mgr.bus_vector_active_idx);
+ mutex_unlock(&bandwidth_mgr_mutex);
+ return 0;
+}
+
+void msm_isp_deinit_bandwidth_mgr(enum msm_isp_hw_client client)
+{
+ mutex_lock(&bandwidth_mgr_mutex);
+ memset(&isp_bandwidth_mgr.client_info[client], 0,
+ sizeof(struct msm_isp_bandwidth_info));
+ if (--isp_bandwidth_mgr.use_count) {
+ mutex_unlock(&bandwidth_mgr_mutex);
+ return;
+ }
+
+ if (!isp_bandwidth_mgr.bus_client)
+ return;
+
+ msm_bus_scale_client_update_request(
+ isp_bandwidth_mgr.bus_client, 0);
+ msm_bus_scale_unregister_client(isp_bandwidth_mgr.bus_client);
+ isp_bandwidth_mgr.bus_client = 0;
+ mutex_unlock(&bandwidth_mgr_mutex);
+}
static inline void msm_isp_get_timestamp(struct msm_isp_timestamp *time_stamp)
{
@@ -68,28 +202,67 @@
return rc;
}
-int msm_isp_cfg_pix(struct vfe_device *vfe_dev,
- struct msm_vfe_pix_cfg *pix_cfg)
+static int msm_isp_set_clk_rate(struct vfe_device *vfe_dev, uint32_t rate)
{
int rc = 0;
- /*TD Validate config info
- * should check if all streams are off */
+ int clk_idx = vfe_dev->hw_info->vfe_clk_idx;
+ long round_rate =
+ clk_round_rate(vfe_dev->vfe_clk[clk_idx], rate);
+ if (round_rate < 0) {
+ pr_err("%s: Invalid vfe clock rate\n", __func__);
+ return round_rate;
+ }
- vfe_dev->axi_data.src_info[VFE_PIX_0].input_mux = pix_cfg->input_mux;
+ rc = clk_set_rate(vfe_dev->vfe_clk[clk_idx], round_rate);
+ if (rc < 0) {
+ pr_err("%s: Vfe set rate error\n", __func__);
+ return rc;
+ }
+ return 0;
+}
- vfe_dev->hw_info->vfe_ops.core_ops.cfg_camif(vfe_dev, pix_cfg);
+int msm_isp_cfg_pix(struct vfe_device *vfe_dev,
+ struct msm_vfe_input_cfg *input_cfg)
+{
+ int rc = 0;
+ if (vfe_dev->axi_data.src_info[VFE_PIX_0].active) {
+ pr_err("%s: pixel path is active\n", __func__);
+ return -EINVAL;
+ }
+
+ vfe_dev->axi_data.src_info[VFE_PIX_0].pixel_clock =
+ input_cfg->input_pix_clk;
+ vfe_dev->axi_data.src_info[VFE_PIX_0].input_mux =
+ input_cfg->d.pix_cfg.input_mux;
+ vfe_dev->axi_data.src_info[VFE_PIX_0].width =
+ input_cfg->d.pix_cfg.camif_cfg.pixels_per_line;
+
+ rc = msm_isp_set_clk_rate(vfe_dev,
+ vfe_dev->axi_data.src_info[VFE_PIX_0].pixel_clock);
+ if (rc < 0) {
+ pr_err("%s: clock set rate failed\n", __func__);
+ return rc;
+ }
+
+ vfe_dev->hw_info->vfe_ops.core_ops.cfg_camif(
+ vfe_dev, &input_cfg->d.pix_cfg);
return rc;
}
int msm_isp_cfg_rdi(struct vfe_device *vfe_dev,
- struct msm_vfe_rdi_cfg *rdi_cfg, enum msm_vfe_input_src input_src)
+ struct msm_vfe_input_cfg *input_cfg)
{
int rc = 0;
- /*TD Validate config info
- * should check if all streams are off */
+ if (vfe_dev->axi_data.src_info[input_cfg->input_src].active) {
+ pr_err("%s: RAW%d path is active\n", __func__,
+ input_cfg->input_src - VFE_RAW_0);
+ return -EINVAL;
+ }
- vfe_dev->hw_info->vfe_ops.core_ops.
- cfg_rdi_reg(vfe_dev, rdi_cfg, input_src);
+ vfe_dev->axi_data.src_info[input_cfg->input_src].pixel_clock =
+ input_cfg->input_pix_clk;
+ vfe_dev->hw_info->vfe_ops.core_ops.cfg_rdi_reg(
+ vfe_dev, &input_cfg->d.rdi_cfg, input_cfg->input_src);
return rc;
}
@@ -100,16 +273,16 @@
switch (input_cfg->input_src) {
case VFE_PIX_0:
- msm_isp_cfg_pix(vfe_dev, &input_cfg->d.pix_cfg);
+ rc = msm_isp_cfg_pix(vfe_dev, input_cfg);
break;
case VFE_RAW_0:
case VFE_RAW_1:
case VFE_RAW_2:
- msm_isp_cfg_rdi(vfe_dev, &input_cfg->d.rdi_cfg,
- input_cfg->input_src);
+ rc = msm_isp_cfg_rdi(vfe_dev, input_cfg);
break;
- case VFE_SRC_MAX:
- break;
+ default:
+ pr_err("%s: Invalid input source\n", __func__);
+ rc = -EINVAL;
}
return rc;
}
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.h
index 3dac7e0..7934f26 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.h
@@ -22,6 +22,32 @@
#define ISP_DBG(fmt, args...) pr_debug(fmt, ##args)
#endif
+#define ALT_VECTOR_IDX(x) {x = 3 - x; }
+struct msm_isp_bandwidth_info {
+ uint32_t active;
+ uint64_t ab;
+ uint64_t ib;
+};
+
+enum msm_isp_hw_client {
+ ISP_VFE0,
+ ISP_VFE1,
+ ISP_CPP,
+ MAX_ISP_CLIENT,
+};
+
+struct msm_isp_bandwidth_mgr {
+ uint32_t bus_client;
+ uint32_t bus_vector_active_idx;
+ uint32_t use_count;
+ struct msm_isp_bandwidth_info client_info[MAX_ISP_CLIENT];
+};
+
+int msm_isp_init_bandwidth_mgr(enum msm_isp_hw_client client);
+int msm_isp_update_bandwidth(enum msm_isp_hw_client client,
+ uint64_t ab, uint64_t ib);
+void msm_isp_deinit_bandwidth_mgr(enum msm_isp_hw_client client);
+
int msm_isp_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
struct v4l2_event_subscription *sub);
diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
index d30afb2..f209330 100644
--- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
+++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
@@ -380,6 +380,8 @@
data = msm_camera_io_r(ispif->base + ISPIF_VFE_m_CTRL_0(vfe_intf));
data |= (1 << (intftype + 7));
+ if (intftype == PIX0)
+ data |= 1 << PIX0_LINE_BUF_EN_BIT;
msm_camera_io_w(data,
ispif->base + ISPIF_VFE_m_CTRL_0(vfe_intf));
diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v1.h b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v1.h
index afd91d1..9f8b2fa 100644
--- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v1.h
+++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v1.h
@@ -16,6 +16,7 @@
/* common registers */
#define ISPIF_RST_CMD_ADDR 0x0000
#define ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR 0x0124
+#define PIX0_LINE_BUF_EN_BIT 0
#define ISPIF_VFE(m) (0x0)
diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v2.h b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v2.h
index 80b32d4..5e61a4d 100644
--- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v2.h
+++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v2.h
@@ -17,6 +17,7 @@
#define ISPIF_RST_CMD_ADDR 0x008
#define ISPIF_RST_CMD_1_ADDR 0x00C
#define ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR 0x01C
+#define PIX0_LINE_BUF_EN_BIT 6
#define ISPIF_VFE(m) ((m) * 0x200)
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/Makefile b/drivers/media/platform/msm/camera_v2/pproc/cpp/Makefile
index 2f969d2..c793ef6 100644
--- a/drivers/media/platform/msm/camera_v2/pproc/cpp/Makefile
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/Makefile
@@ -1,3 +1,4 @@
ccflags-y += -Idrivers/media/platform/msm/camera_v2
+ccflags-y += -Idrivers/media/platform/msm/camera_v2/isp/
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
index 2598b07..1203d17 100644
--- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
@@ -34,6 +34,7 @@
#include <media/msmb_pproc.h>
#include <media/msmb_generic_buf_mgr.h>
#include "msm_cpp.h"
+#include "msm_isp_util.h"
#include "msm_camera_io_util.h"
#define MSM_CPP_DRV_NAME "msm_cpp"
@@ -582,6 +583,12 @@
static int cpp_init_hardware(struct cpp_device *cpp_dev)
{
int rc = 0;
+ rc = msm_isp_init_bandwidth_mgr(ISP_CPP);
+ if (rc < 0) {
+ pr_err("%s: Bandwidth registration Failed!\n", __func__);
+ goto bus_scale_register_failed;
+ }
+ msm_isp_update_bandwidth(ISP_CPP, 981345600, 1600020000);
if (cpp_dev->fs_cpp == NULL) {
cpp_dev->fs_cpp =
@@ -667,6 +674,9 @@
regulator_disable(cpp_dev->fs_cpp);
regulator_put(cpp_dev->fs_cpp);
fs_failed:
+ msm_isp_update_bandwidth(ISP_CPP, 0, 0);
+ msm_isp_deinit_bandwidth_mgr(ISP_CPP);
+bus_scale_register_failed:
return rc;
}
@@ -688,6 +698,8 @@
regulator_put(cpp_dev->fs_cpp);
cpp_dev->fs_cpp = NULL;
}
+ msm_isp_update_bandwidth(ISP_CPP, 0, 0);
+ msm_isp_deinit_bandwidth_mgr(ISP_CPP);
}
static void cpp_load_fw(struct cpp_device *cpp_dev, char *fw_name_bin)
diff --git a/drivers/media/platform/msm/dvb/video/mpq_dvb_video.c b/drivers/media/platform/msm/dvb/video/mpq_dvb_video.c
index b9fdc5e..45a9dd5 100644
--- a/drivers/media/platform/msm/dvb/video/mpq_dvb_video.c
+++ b/drivers/media/platform/msm/dvb/video/mpq_dvb_video.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -31,7 +31,7 @@
#include <linux/clk.h>
#include <linux/timer.h>
-#include <mach/msm_subsystem_map.h>
+#include <mach/iommu_domains.h>
#include <media/msm/vidc_type.h>
#include <media/msm/vcd_api.h>
#include <media/msm/vidc_init.h>
@@ -1188,9 +1188,6 @@
if (!client_ctx)
return -EINVAL;
- if (client_ctx->vcd_h264_mv_buffer.client_data)
- msm_subsystem_unmap_buffer((struct msm_mapped_buffer *)
- client_ctx->vcd_h264_mv_buffer.client_data);
vcd_property_hdr.prop_id = VCD_I_FREE_H264_MV_BUFFER;
vcd_property_hdr.sz = sizeof(struct vcd_property_buffer_size);
diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c
index 102e1ec..91fb514 100644
--- a/drivers/media/platform/msm/vidc/hfi_response_handler.c
+++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c
@@ -1003,12 +1003,6 @@
return;
}
- sess_close = (struct hal_session *)pkt->session_id;
- dprintk(VIDC_INFO, "deleted the session: 0x%x",
- sess_close->session_id);
- list_del(&sess_close->list);
- kfree(sess_close);
-
memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
cmd_done.device_id = device_id;
cmd_done.session_id =
@@ -1016,6 +1010,11 @@
cmd_done.status = hfi_map_err_status((u32)pkt->error_type);
cmd_done.data = NULL;
cmd_done.size = 0;
+ sess_close = (struct hal_session *)pkt->session_id;
+ dprintk(VIDC_INFO, "deleted the session: 0x%x",
+ sess_close->session_id);
+ list_del(&sess_close->list);
+ kfree(sess_close);
callback(SESSION_END_DONE, &cmd_done);
}
diff --git a/drivers/media/platform/msm/vidc/msm_smem.c b/drivers/media/platform/msm/vidc/msm_smem.c
index 3b12a26..79a492e 100644
--- a/drivers/media/platform/msm/vidc/msm_smem.c
+++ b/drivers/media/platform/msm/vidc/msm_smem.c
@@ -152,16 +152,7 @@
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;
- }
+ goto fail_device_address;
}
mem->flags = ionflags;
@@ -184,9 +175,6 @@
mem->device_addr, mem->size);
return rc;
fail_device_address:
- if (mem->kvaddr)
- ion_unmap_kernel(client->clnt, hndl);
-fail_map:
ion_free(client->clnt, hndl);
fail_import_fd:
return rc;
@@ -366,20 +354,14 @@
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,
+ rc = msm_ion_do_cache_op(client->clnt,
+ (struct ion_handle *)mem->smem_priv,
+ 0, (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");
+ goto cache_op_failed;
}
}
cache_op_failed:
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index 2cf9928..adf6dec 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -1449,7 +1449,7 @@
"Failed to send close\n");
goto exit;
}
- change_inst_state(inst, MSM_VIDC_OPEN);
+ change_inst_state(inst, MSM_VIDC_CLOSE);
exit:
return rc;
}
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 7d76b43..362a391 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -52,6 +52,7 @@
#define QSEEE_VERSION_00 0x400000
#define QSEE_VERSION_01 0x401000
#define QSEE_VERSION_02 0x402000
+#define QSEE_VERSION_03 0x403000
#define QSEOS_CHECK_VERSION_CMD 0x00001803
@@ -65,6 +66,13 @@
CLK_SFPB,
};
+enum qseecom_client_handle_type {
+ QSEECOM_CLIENT_APP = 0,
+ QSEECOM_LISTENER_SERVICE,
+ QSEECOM_SECURE_SERVICE,
+ QSEECOM_GENERIC,
+};
+
static struct class *driver_class;
static dev_t qseecom_device_no;
static struct cdev qseecom_cdev;
@@ -152,7 +160,7 @@
static struct qseecom_control qseecom;
struct qseecom_dev_handle {
- bool service;
+ enum qseecom_client_handle_type type;
union {
struct qseecom_client_handle client;
struct qseecom_listener_handle listener;
@@ -307,7 +315,7 @@
return ret;
}
data->listener.id = 0;
- data->service = true;
+ data->type = QSEECOM_LISTENER_SERVICE;
if (!__qseecom_is_svc_unique(data, &rcvd_lstnr)) {
pr_err("Service is not unique and is already registered\n");
data->released = true;
@@ -544,13 +552,14 @@
sizeof(*resp));
if (ret) {
pr_err("scm_call() failed with err: %d (app_id = %d)\n",
- ret, data->client.app_id);
+ ret, data->client.app_id);
return ret;
}
- if (resp->result == QSEOS_RESULT_FAILURE) {
- pr_err("Response result %d FAIL (app_id = %d)\n",
- resp->result, data->client.app_id);
- return -EINVAL;
+ if ((resp->result != QSEOS_RESULT_SUCCESS) &&
+ (resp->result != QSEOS_RESULT_INCOMPLETE)) {
+ pr_err("fail:resp res= %d,app_id = %d,lstr = %d\n",
+ resp->result, data->client.app_id, lstnr);
+ ret = -EINVAL;
}
}
if (rc)
@@ -754,6 +763,17 @@
return 1;
}
+static int qseecom_unmap_ion_allocated_memory(struct qseecom_dev_handle *data)
+{
+ int ret = 0;
+ if (!IS_ERR_OR_NULL(data->client.ihandle)) {
+ ion_unmap_kernel(qseecom.ion_clnt, data->client.ihandle);
+ ion_free(qseecom.ion_clnt, data->client.ihandle);
+ data->client.ihandle = NULL;
+ }
+ return ret;
+}
+
static int qseecom_unload_app(struct qseecom_dev_handle *data)
{
unsigned long flags;
@@ -836,11 +856,7 @@
}
}
}
- if (!IS_ERR_OR_NULL(data->client.ihandle)) {
- ion_unmap_kernel(qseecom.ion_clnt, data->client.ihandle);
- ion_free(qseecom.ion_clnt, data->client.ihandle);
- data->client.ihandle = NULL;
- }
+ qseecom_unmap_ion_allocated_memory(data);
data->released = true;
return ret;
}
@@ -943,6 +959,96 @@
return ret;
}
+int __qseecom_process_rpmb_svc_cmd(struct qseecom_dev_handle *data_ptr,
+ struct qseecom_send_svc_cmd_req *req_ptr,
+ struct qseecom_client_send_service_ireq *send_svc_ireq_ptr)
+{
+ int ret = 0;
+ if ((req_ptr == NULL) || (send_svc_ireq_ptr == NULL)) {
+ pr_err("Error with pointer: req_ptr = %p, send_svc_ptr = %p\n",
+ req_ptr, send_svc_ireq_ptr);
+ return -EINVAL;
+ }
+ send_svc_ireq_ptr->qsee_cmd_id = req_ptr->cmd_id;
+ send_svc_ireq_ptr->key_type =
+ ((struct qseecom_rpmb_provision_key *)req_ptr->cmd_req_buf)->key_type;
+ send_svc_ireq_ptr->req_len = req_ptr->cmd_req_len;
+ send_svc_ireq_ptr->rsp_ptr = (void *)(__qseecom_uvirt_to_kphys(data_ptr,
+ (uint32_t)req_ptr->resp_buf));
+ send_svc_ireq_ptr->rsp_len = req_ptr->resp_len;
+
+ pr_debug("CMD ID (%x), KEY_TYPE (%d)\n", send_svc_ireq_ptr->qsee_cmd_id,
+ ((struct qseecom_rpmb_provision_key *)req_ptr->cmd_req_buf)->key_type);
+ return ret;
+}
+
+static int qseecom_send_service_cmd(struct qseecom_dev_handle *data,
+ void __user *argp)
+{
+ int ret = 0;
+ struct qseecom_client_send_service_ireq send_svc_ireq;
+ struct qseecom_command_scm_resp resp;
+ struct qseecom_send_svc_cmd_req req;
+ /*struct qseecom_command_scm_resp resp;*/
+
+ if (__copy_from_user(&req,
+ (void __user *)argp,
+ sizeof(req))) {
+ pr_err("copy_from_user failed\n");
+ return -EFAULT;
+ }
+
+ if (req.resp_buf == NULL) {
+ pr_err("cmd buffer or response buffer is null\n");
+ return -EINVAL;
+ }
+
+ data->type = QSEECOM_SECURE_SERVICE;
+
+ switch (req.cmd_id) {
+ case QSEE_RPMB_PROVISION_KEY_COMMAND:
+ case QSEE_RPMB_ERASE_COMMAND:
+ if (__qseecom_process_rpmb_svc_cmd(data, &req,
+ &send_svc_ireq))
+ return -EINVAL;
+ break;
+ default:
+ pr_err("Unsupported cmd_id %d\n", req.cmd_id);
+ return -EINVAL;
+ }
+
+ ret = scm_call(SCM_SVC_TZSCHEDULER, 1, (const void *) &send_svc_ireq,
+ sizeof(send_svc_ireq),
+ &resp, sizeof(resp));
+ if (ret) {
+ pr_err("qseecom_scm_call failed with err: %d\n", ret);
+ return ret;
+ }
+
+ switch (resp.result) {
+ case QSEOS_RESULT_SUCCESS:
+ break;
+ case QSEOS_RESULT_INCOMPLETE:
+ pr_err("qseos_result_incomplete\n");
+ ret = __qseecom_process_incomplete_cmd(data, &resp);
+ if (ret) {
+ pr_err("process_incomplete_cmd fail: err: %d\n",
+ ret);
+ }
+ break;
+ case QSEOS_RESULT_FAILURE:
+ pr_err("process_incomplete_cmd failed err: %d\n", ret);
+ break;
+ default:
+ pr_err("Response result %d not supported\n",
+ resp.result);
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+
+}
+
static int __qseecom_send_cmd(struct qseecom_dev_handle *data,
struct qseecom_send_cmd_req *req)
{
@@ -1504,7 +1610,7 @@
return -ENOMEM;
}
data->abort = 0;
- data->service = false;
+ data->type = QSEECOM_CLIENT_APP;
data->released = false;
data->client.app_id = ret;
data->client.sb_length = size;
@@ -2352,6 +2458,19 @@
mutex_unlock(&app_access_lock);
break;
}
+ case QSEECOM_IOCTL_SEND_CMD_SERVICE_REQ: {
+ if (qseecom.qsee_version < QSEE_VERSION_03) {
+ pr_err("SEND_CMD_SERVICE_REQ: Invalid qsee version %u\n",
+ qseecom.qsee_version);
+ return -EINVAL;
+ }
+ mutex_lock(&app_access_lock);
+ atomic_inc(&data->ioctl_count);
+ ret = qseecom_send_service_cmd(data, argp);
+ atomic_dec(&data->ioctl_count);
+ mutex_unlock(&app_access_lock);
+ break;
+ }
default:
return -EINVAL;
}
@@ -2370,7 +2489,7 @@
}
file->private_data = data;
data->abort = 0;
- data->service = false;
+ data->type = QSEECOM_GENERIC;
data->released = false;
init_waitqueue_head(&data->abort_wq);
atomic_set(&data->ioctl_count, 0);
@@ -2401,15 +2520,27 @@
if (data->released == false) {
pr_warn("data->released == false\n");
- if (data->service)
+ switch (data->type) {
+ case QSEECOM_LISTENER_SERVICE:
ret = qseecom_unregister_listener(data);
- else
+ break;
+ case QSEECOM_CLIENT_APP:
ret = qseecom_unload_app(data);
- if (ret) {
- pr_err("Close failed\n");
- return ret;
+ break;
+ case QSEECOM_SECURE_SERVICE:
+ ret = qseecom_unmap_ion_allocated_memory(data);
+ if (ret) {
+ pr_err("Close failed\n");
+ return ret;
+ }
+ break;
+ default:
+ pr_err("Unsupported clnt_handle_type %d",
+ data->type);
+ break;
}
}
+
if (data->client.fast_load_enabled == true)
qsee_disable_clock_vote(data, CLK_SFPB);
if (data->client.perf_enabled == true)
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 38b453b..fc7c399 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -3600,6 +3600,20 @@
EXPORT_SYMBOL(mmc_set_embedded_sdio_data);
#endif
+#ifdef CONFIG_PM_RUNTIME
+void mmc_dump_dev_pm_state(struct mmc_host *host, struct device *dev)
+{
+ pr_err("%s: %s: err: runtime_error: %d\n", dev_name(dev),
+ mmc_hostname(host), dev->power.runtime_error);
+ pr_err("%s: %s: disable_depth: %d runtime_status: %d idle_notification: %d\n",
+ dev_name(dev), mmc_hostname(host), dev->power.disable_depth,
+ dev->power.runtime_status,
+ dev->power.idle_notification);
+ pr_err("%s: %s: request_pending: %d, request: %d\n",
+ dev_name(dev), mmc_hostname(host),
+ dev->power.request_pending, dev->power.request);
+}
+
void mmc_rpm_hold(struct mmc_host *host, struct device *dev)
{
int ret = 0;
@@ -3608,13 +3622,16 @@
return;
ret = pm_runtime_get_sync(dev);
- if (ret < 0) {
- pr_err("%s: %s: %s: error resuming device: %d\n",
+ if ((ret < 0) &&
+ (dev->power.runtime_error || (dev->power.disable_depth > 0))) {
+ pr_err("%s: %s: %s: pm_runtime_get_sync: err: %d\n",
dev_name(dev), mmc_hostname(host), __func__, ret);
+ mmc_dump_dev_pm_state(host, dev);
if (pm_runtime_suspended(dev))
BUG_ON(1);
}
}
+
EXPORT_SYMBOL(mmc_rpm_hold);
void mmc_rpm_release(struct mmc_host *host, struct device *dev)
@@ -3625,11 +3642,22 @@
return;
ret = pm_runtime_put_sync(dev);
- if (ret < 0 && ret != -EBUSY)
- pr_err("%s: %s: %s: put sync ret: %d\n",
+ if ((ret < 0) &&
+ (dev->power.runtime_error || (dev->power.disable_depth > 0))) {
+ pr_err("%s: %s: %s: pm_runtime_put_sync: err: %d\n",
dev_name(dev), mmc_hostname(host), __func__, ret);
+ mmc_dump_dev_pm_state(host, dev);
+ }
}
+
EXPORT_SYMBOL(mmc_rpm_release);
+#else
+void mmc_rpm_hold(struct mmc_host *host, struct device *dev) {}
+EXPORT_SYMBOL(mmc_rpm_hold);
+
+void mmc_rpm_release(struct mmc_host *host, struct device *dev) {}
+EXPORT_SYMBOL(mmc_rpm_release);
+#endif
/**
* mmc_init_context_info() - init synchronization context
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 3b1384d..2038d3d 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -1187,9 +1187,12 @@
static unsigned int sdhci_get_bw_required(struct sdhci_host *host,
struct mmc_ios *ios)
{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct sdhci_msm_host *msm_host = pltfm_host->priv;
+
unsigned int bw;
- bw = host->clock;
+ bw = msm_host->clk_rate;
/*
* For DDR mode, SDCC controller clock will be at
* the double rate than the actual clock that goes to card.
diff --git a/drivers/mtd/devices/msm_qpic_nand.c b/drivers/mtd/devices/msm_qpic_nand.c
index c37a4a4..570c257 100644
--- a/drivers/mtd/devices/msm_qpic_nand.c
+++ b/drivers/mtd/devices/msm_qpic_nand.c
@@ -28,8 +28,9 @@
#include <linux/bitrev.h>
#include <linux/mutex.h>
#include <linux/of.h>
+#include <linux/ctype.h>
#include <mach/sps.h>
-
+#include <mach/msm_smsm.h>
#define PAGE_SIZE_2K 2048
#define PAGE_SIZE_4K 4096
#define WRITE 1
@@ -285,6 +286,34 @@
uint16_t integrity_crc;
} __attribute__((__packed__));
+#define FLASH_PART_MAGIC1 0x55EE73AA
+#define FLASH_PART_MAGIC2 0xE35EBDDB
+#define FLASH_PTABLE_V3 3
+#define FLASH_PTABLE_V4 4
+#define FLASH_PTABLE_MAX_PARTS_V3 16
+#define FLASH_PTABLE_MAX_PARTS_V4 32
+#define FLASH_PTABLE_HDR_LEN (4*sizeof(uint32_t))
+#define FLASH_PTABLE_ENTRY_NAME_SIZE 16
+
+struct flash_partition_entry {
+ char name[FLASH_PTABLE_ENTRY_NAME_SIZE];
+ u32 offset; /* Offset in blocks from beginning of device */
+ u32 length; /* Length of the partition in blocks */
+ u8 attr; /* Flags for this partition */
+};
+
+struct flash_partition_table {
+ u32 magic1;
+ u32 magic2;
+ u32 version;
+ u32 numparts;
+ struct flash_partition_entry part_entry[FLASH_PTABLE_MAX_PARTS_V4];
+};
+
+static struct flash_partition_table ptable;
+
+static struct mtd_partition mtd_part[FLASH_PTABLE_MAX_PARTS_V4];
+
/*
* Get the DMA memory for requested amount of size. It returns the pointer
* to free memory available from the allocated pool. Returns NULL if there
@@ -660,6 +689,14 @@
if (ret < 0)
goto free_dma;
+ /* Lookup the 'APPS' partition's first page address */
+ for (i = 0; i < FLASH_PTABLE_MAX_PARTS_V4; i++) {
+ if (!strncmp("apps", ptable.part_entry[i].name,
+ strlen(ptable.part_entry[i].name))) {
+ page_address = ptable.part_entry[i].offset << 6;
+ break;
+ }
+ }
data.cfg.cmd = MSM_NAND_CMD_PAGE_READ_ALL;
data.exec = 1;
data.cfg.addr0 = (page_address << 16) |
@@ -2338,6 +2375,75 @@
}
+#ifdef CONFIG_MSM_SMD
+static int msm_nand_parse_smem_ptable(int *nr_parts)
+{
+
+ uint32_t i, j;
+ uint32_t len = FLASH_PTABLE_HDR_LEN;
+ struct flash_partition_entry *pentry;
+ char *delimiter = ":";
+
+ pr_info("Parsing partition table info from SMEM\n");
+ /* Read only the header portion of ptable */
+ ptable = *(struct flash_partition_table *)
+ (smem_get_entry(SMEM_AARM_PARTITION_TABLE, &len));
+ /* Verify ptable magic */
+ if (ptable.magic1 != FLASH_PART_MAGIC1 ||
+ ptable.magic2 != FLASH_PART_MAGIC2) {
+ pr_err("Partition table magic verification failed\n");
+ goto out;
+ }
+ /* Ensure that # of partitions is less than the max we have allocated */
+ if (ptable.numparts > FLASH_PTABLE_MAX_PARTS_V4) {
+ pr_err("Partition numbers exceed the max limit\n");
+ goto out;
+ }
+ /* Find out length of partition data based on table version. */
+ if (ptable.version <= FLASH_PTABLE_V3) {
+ len = FLASH_PTABLE_HDR_LEN + FLASH_PTABLE_MAX_PARTS_V3 *
+ sizeof(struct flash_partition_entry);
+ } else if (ptable.version == FLASH_PTABLE_V4) {
+ len = FLASH_PTABLE_HDR_LEN + FLASH_PTABLE_MAX_PARTS_V4 *
+ sizeof(struct flash_partition_entry);
+ } else {
+ pr_err("Unknown ptable version (%d)", ptable.version);
+ goto out;
+ }
+
+ *nr_parts = ptable.numparts;
+ ptable = *(struct flash_partition_table *)
+ (smem_get_entry(SMEM_AARM_PARTITION_TABLE, &len));
+ for (i = 0; i < ptable.numparts; i++) {
+ pentry = &ptable.part_entry[i];
+ if (pentry->name == '\0')
+ continue;
+ /* Convert name to lower case and discard the initial chars */
+ mtd_part[i].name = pentry->name;
+ for (j = 0; j < strlen(mtd_part[i].name); j++)
+ *(mtd_part[i].name + j) =
+ tolower(*(mtd_part[i].name + j));
+ strsep(&(mtd_part[i].name), delimiter);
+ mtd_part[i].offset = pentry->offset;
+ mtd_part[i].mask_flags = pentry->attr;
+ mtd_part[i].size = pentry->length;
+ pr_debug("%d: %s offs=0x%08x size=0x%08x attr:0x%08x\n",
+ i, pentry->name, pentry->offset, pentry->length,
+ pentry->attr);
+ }
+ pr_info("SMEM partition table found: ver: %d len: %d\n",
+ ptable.version, ptable.numparts);
+ return 0;
+out:
+ return -EINVAL;
+}
+#else
+static int msm_nand_parse_smem_ptable(int *nr_parts)
+{
+ return -ENODEV;
+}
+#endif
+
/*
* This function gets called when its device named msm-nand is added to
* device tree .dts file with all its resources such as physical addresses
@@ -2352,26 +2458,13 @@
{
struct msm_nand_info *info;
struct resource *res;
- int err;
- struct device_node *pnode;
- struct mtd_part_parser_data parser_data;
-
- if (!pdev->dev.of_node) {
- pr_err("No valid device tree info for NANDc\n");
- err = -ENODEV;
- goto out;
- }
+ int i, err, nr_parts;
/*
* The partition information can also be passed from kernel command
* line. Also, the MTD core layer supports adding the whole device as
* one MTD device when no partition information is available at all.
- * Hence, do not bail out when partition information is not availabe
- * in device tree.
*/
- pnode = of_find_node_by_path("/qcom,mtd-partitions");
- if (!pnode)
- pr_info("No partition info available in device tree\n");
info = devm_kzalloc(&pdev->dev, sizeof(struct msm_nand_info),
GFP_KERNEL);
if (!info) {
@@ -2379,7 +2472,6 @@
err = -ENOMEM;
goto out;
}
-
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
"nand_phys");
if (!res || !res->start) {
@@ -2438,14 +2530,22 @@
pr_err("Failed to enable DMA in NANDc\n");
goto free_bam;
}
+ err = msm_nand_parse_smem_ptable(&nr_parts);
+ if (err < 0) {
+ pr_err("Failed to parse partition table in SMEM\n");
+ goto free_bam;
+ }
if (msm_nand_scan(&info->mtd)) {
pr_err("No nand device found\n");
err = -ENXIO;
goto free_bam;
}
- parser_data.of_node = pnode;
- err = mtd_device_parse_register(&info->mtd, NULL, &parser_data,
- NULL, 0);
+ for (i = 0; i < nr_parts; i++) {
+ mtd_part[i].offset *= info->mtd.erasesize;
+ mtd_part[i].size *= info->mtd.erasesize;
+ }
+ err = mtd_device_parse_register(&info->mtd, NULL, NULL,
+ &mtd_part[0], nr_parts);
if (err < 0) {
pr_err("Unable to register MTD partitions %d\n", err);
goto free_bam;
diff --git a/drivers/net/ethernet/msm/msm_rmnet_smux.c b/drivers/net/ethernet/msm/msm_rmnet_smux.c
index 7b27b73..5fe724e 100644
--- a/drivers/net/ethernet/msm/msm_rmnet_smux.c
+++ b/drivers/net/ethernet/msm/msm_rmnet_smux.c
@@ -804,7 +804,7 @@
for (i = 0; i < RMNET_SMUX_DEVICE_COUNT; i++) {
p = netdev_priv(netdevs[i]);
- if ((p != NULL) && (p->device_state == DEVICE_INACTIVE)) {
+ if (p != NULL) {
r = msm_smux_open(p->ch_id,
netdevs[i],
rmnet_smux_notify,
@@ -828,7 +828,7 @@
for (i = 0; i < RMNET_SMUX_DEVICE_COUNT; i++) {
p = netdev_priv(netdevs[i]);
- if ((p != NULL) && (p->device_state == DEVICE_ACTIVE)) {
+ if (p != NULL) {
r = msm_smux_close(p->ch_id);
if (r < 0) {
diff --git a/drivers/platform/msm/sps/sps_bam.c b/drivers/platform/msm/sps/sps_bam.c
index 31d1a78..3ebb1cd 100644
--- a/drivers/platform/msm/sps/sps_bam.c
+++ b/drivers/platform/msm/sps/sps_bam.c
@@ -827,9 +827,14 @@
}
if (bam_pipe_is_enabled(dev->base, pipe_index)) {
- SPS_ERR("sps:BAM 0x%x pipe %d sharing violation",
- BAM_ID(dev), pipe_index);
- return SPS_ERROR;
+ if (params->options & SPS_O_NO_DISABLE)
+ SPS_DBG("sps:BAM 0x%x pipe %d is already enabled\n",
+ BAM_ID(dev), pipe_index);
+ else {
+ SPS_ERR("sps:BAM 0x%x pipe %d sharing violation\n",
+ BAM_ID(dev), pipe_index);
+ return SPS_ERROR;
+ }
}
if (bam_pipe_init(dev->base, pipe_index, &hw_params, dev->props.ee)) {
@@ -882,8 +887,13 @@
bam_pipe->state |= BAM_STATE_INIT;
result = 0;
exit_err:
- if (result)
- bam_pipe_exit(dev->base, pipe_index, dev->props.ee);
+ if (result) {
+ if (params->options & SPS_O_NO_DISABLE)
+ SPS_DBG("sps:BAM 0x%x pipe %d connection exits\n",
+ BAM_ID(dev), pipe_index);
+ else
+ bam_pipe_exit(dev->base, pipe_index, dev->props.ee);
+ }
exit_init_err:
if (result) {
/* Clear the client pipe state */
@@ -916,7 +926,11 @@
dev->pipe_active_mask &= ~(1UL << pipe_index);
}
dev->pipe_remote_mask &= ~(1UL << pipe_index);
- bam_pipe_exit(dev->base, pipe_index, dev->props.ee);
+ if (pipe->connect.options & SPS_O_NO_DISABLE)
+ SPS_DBG("sps:BAM 0x%x pipe %d exits\n", BAM_ID(dev),
+ pipe_index);
+ else
+ bam_pipe_exit(dev->base, pipe_index, dev->props.ee);
if (pipe->sys.desc_cache != NULL) {
u32 size = pipe->num_descs * sizeof(void *);
if (pipe->desc_size + size <= PAGE_SIZE)
@@ -1114,7 +1128,12 @@
struct sps_pipe *pipe = dev->pipes[pipe_index];
/* Disable the BAM pipe */
- bam_pipe_disable(dev->base, pipe_index);
+ if (pipe->connect.options & SPS_O_NO_DISABLE)
+ SPS_DBG("sps:BAM 0x%x pipe %d enters disable state\n",
+ BAM_ID(dev), pipe_index);
+ else
+ bam_pipe_disable(dev->base, pipe_index);
+
pipe->state &= ~BAM_STATE_ENABLED;
return 0;
diff --git a/drivers/power/qpnp-bms.c b/drivers/power/qpnp-bms.c
index 37ac7b5..210964e 100644
--- a/drivers/power/qpnp-bms.c
+++ b/drivers/power/qpnp-bms.c
@@ -194,6 +194,8 @@
int prev_voltage_based_soc;
bool use_voltage_soc;
+ int prev_batt_terminal_uv;
+
int ocv_high_threshold_uv;
int ocv_low_threshold_uv;
unsigned long last_recalc_time;
@@ -651,6 +653,7 @@
chip->last_cc_uah = INT_MIN;
chip->last_ocv_temp = batt_temp;
chip->last_soc_invalid = true;
+ chip->prev_batt_terminal_uv = 0;
}
#define OCV_RAW_UNINITIALIZED 0xFFFF
@@ -1296,11 +1299,13 @@
pr_debug("CC_TO_CV ibat_ua = %d CHG SOC %d\n",
ibat_ua, soc);
}
+
+ chip->prev_batt_terminal_uv = batt_terminal_uv;
return soc;
}
/*
- * battery is in CV phase - begin liner inerpolation of soc based on
+ * battery is in CV phase - begin linear interpolation of soc based on
* battery charge current
*/
@@ -1308,10 +1313,11 @@
* if voltage lessened (possibly because of a system load)
* keep reporting the prev chg soc
*/
- if (batt_terminal_uv <= chip->max_voltage_uv - 10000) {
+ if (batt_terminal_uv <= chip->prev_batt_terminal_uv) {
pr_debug("batt_terminal_uv %d < (max = %d - 10000); CC CHG SOC %d\n",
- batt_terminal_uv,
- chip->max_voltage_uv, chip->prev_chg_soc);
+ batt_terminal_uv, chip->prev_batt_terminal_uv,
+ chip->prev_chg_soc);
+ chip->prev_batt_terminal_uv = batt_terminal_uv;
return chip->prev_chg_soc;
}
@@ -1334,6 +1340,7 @@
}
pr_debug("Reporting CHG SOC %d\n", chip->prev_chg_soc);
+ chip->prev_batt_terminal_uv = batt_terminal_uv;
return chip->prev_chg_soc;
}
diff --git a/drivers/video/msm/mdss/Makefile b/drivers/video/msm/mdss/Makefile
index 7fafbc64..de765ea 100644
--- a/drivers/video/msm/mdss/Makefile
+++ b/drivers/video/msm/mdss/Makefile
@@ -7,7 +7,6 @@
mdss-mdp-objs += mdss_mdp_overlay.o
mdss-mdp-objs += mdss_mdp_wb.o
obj-$(CONFIG_FB_MSM_MDSS) += mdss-mdp.o
-obj-$(CONFIG_FB_MSM_MDSS) += mdss_fb.o
ifeq ($(CONFIG_FB_MSM_MDSS),y)
obj-$(CONFIG_DEBUG_FS) += mdss_debug.o
@@ -31,3 +30,5 @@
mdss-qpic-objs := mdss_qpic.o mdss_fb.o mdss_qpic_panel.o
obj-$(CONFIG_FB_MSM_QPIC) += mdss-qpic.o
obj-$(CONFIG_FB_MSM_QPIC_ILI_QVGA_PANEL) += qpic_panel_ili_qvga.o
+
+obj-$(CONFIG_FB_MSM_MDSS) += mdss_fb.o
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
index ed730b3..a5903cf 100644
--- a/drivers/video/msm/mdss/mdss_fb.c
+++ b/drivers/video/msm/mdss/mdss_fb.c
@@ -1729,4 +1729,4 @@
return 0;
}
-device_initcall_sync(mdss_fb_init);
+module_init(mdss_fb_init);
diff --git a/drivers/video/msm/mdss/mdss_hdmi_tx.c b/drivers/video/msm/mdss/mdss_hdmi_tx.c
index 94c0da2..66936e5 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_tx.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_tx.c
@@ -397,13 +397,133 @@
return ret;
} /* hdmi_tx_sysfs_wta_hpd */
+static ssize_t hdmi_tx_sysfs_wta_vendor_name(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ ssize_t ret;
+ u8 *s = (u8 *) buf;
+ u8 *d = NULL;
+ struct hdmi_tx_ctrl *hdmi_ctrl =
+ hdmi_tx_get_drvdata_from_sysfs_dev(dev);
+
+ if (!hdmi_ctrl) {
+ DEV_ERR("%s: invalid input\n", __func__);
+ return -EINVAL;
+ }
+
+ d = hdmi_ctrl->spd_vendor_name;
+ ret = strnlen(buf, PAGE_SIZE);
+ ret = (ret > 8) ? 8 : ret;
+
+ memset(hdmi_ctrl->spd_vendor_name, 0, 8);
+ while (*s) {
+ if (*s & 0x60 && *s ^ 0x7f) {
+ *d = *s;
+ } else {
+ /* stop copying if control character found */
+ break;
+ }
+
+ if (++s > (u8 *) (buf + ret))
+ break;
+
+ d++;
+ }
+
+ DEV_DBG("%s: '%s'\n", __func__, hdmi_ctrl->spd_vendor_name);
+
+ return ret;
+} /* hdmi_tx_sysfs_wta_vendor_name */
+
+static ssize_t hdmi_tx_sysfs_rda_vendor_name(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ ssize_t ret;
+ struct hdmi_tx_ctrl *hdmi_ctrl =
+ hdmi_tx_get_drvdata_from_sysfs_dev(dev);
+
+ if (!hdmi_ctrl) {
+ DEV_ERR("%s: invalid input\n", __func__);
+ return -EINVAL;
+ }
+
+ ret = snprintf(buf, PAGE_SIZE, "%s\n", hdmi_ctrl->spd_vendor_name);
+ DEV_DBG("%s: '%s'\n", __func__, hdmi_ctrl->spd_vendor_name);
+
+ return ret;
+} /* hdmi_tx_sysfs_rda_vendor_name */
+
+static ssize_t hdmi_tx_sysfs_wta_product_description(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ ssize_t ret;
+ u8 *s = (u8 *) buf;
+ u8 *d = NULL;
+ struct hdmi_tx_ctrl *hdmi_ctrl =
+ hdmi_tx_get_drvdata_from_sysfs_dev(dev);
+
+ if (!hdmi_ctrl) {
+ DEV_ERR("%s: invalid input\n", __func__);
+ return -EINVAL;
+ }
+
+ d = hdmi_ctrl->spd_product_description;
+ ret = strnlen(buf, PAGE_SIZE);
+ ret = (ret > 16) ? 16 : ret;
+
+ memset(hdmi_ctrl->spd_product_description, 0, 16);
+ while (*s) {
+ if (*s & 0x60 && *s ^ 0x7f) {
+ *d = *s;
+ } else {
+ /* stop copying if control character found */
+ break;
+ }
+
+ if (++s > (u8 *) (buf + ret))
+ break;
+
+ d++;
+ }
+
+ DEV_DBG("%s: '%s'\n", __func__, hdmi_ctrl->spd_product_description);
+
+ return ret;
+} /* hdmi_tx_sysfs_wta_product_description */
+
+static ssize_t hdmi_tx_sysfs_rda_product_description(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ ssize_t ret;
+ struct hdmi_tx_ctrl *hdmi_ctrl =
+ hdmi_tx_get_drvdata_from_sysfs_dev(dev);
+
+ if (!hdmi_ctrl) {
+ DEV_ERR("%s: invalid input\n", __func__);
+ return -EINVAL;
+ }
+
+ ret = snprintf(buf, PAGE_SIZE, "%s\n",
+ hdmi_ctrl->spd_product_description);
+ DEV_DBG("%s: '%s'\n", __func__, hdmi_ctrl->spd_product_description);
+
+ return ret;
+} /* hdmi_tx_sysfs_rda_product_description */
+
static DEVICE_ATTR(connected, S_IRUGO, hdmi_tx_sysfs_rda_connected, NULL);
static DEVICE_ATTR(hpd, S_IRUGO | S_IWUSR, hdmi_tx_sysfs_rda_hpd,
hdmi_tx_sysfs_wta_hpd);
+static DEVICE_ATTR(vendor_name, S_IRUGO | S_IWUSR,
+ hdmi_tx_sysfs_rda_vendor_name, hdmi_tx_sysfs_wta_vendor_name);
+static DEVICE_ATTR(product_description, S_IRUGO | S_IWUSR,
+ hdmi_tx_sysfs_rda_product_description,
+ hdmi_tx_sysfs_wta_product_description);
static struct attribute *hdmi_tx_fs_attrs[] = {
&dev_attr_connected.attr,
&dev_attr_hpd.attr,
+ &dev_attr_vendor_name.attr,
+ &dev_attr_product_description.attr,
NULL,
};
static struct attribute_group hdmi_tx_fs_attrs_group = {
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h
index 69120e8..b6dc085 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h
@@ -14,7 +14,6 @@
#ifndef _VCD_DDL_H_
#define _VCD_DDL_H_
-#include <mach/msm_subsystem_map.h>
#include "vcd_ddl_api.h"
#include "vcd_ddl_core.h"
#include "vcd_ddl_utils.h"
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
index 61099b0..54b256d 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -12,7 +12,7 @@
*/
#include <linux/memory_alloc.h>
#include <linux/delay.h>
-#include <mach/msm_subsystem_map.h>
+#include <mach/iommu_domains.h>
#include <mach/subsystem_restart.h>
#include "vcd_ddl_utils.h"
#include "vcd_ddl.h"
@@ -25,8 +25,6 @@
};
static struct time_data proc_time[MAX_TIME_DATA];
#define DDL_MSG_TIME(x...) printk(KERN_DEBUG x)
-static unsigned int vidc_mmu_subsystem[] = {
- MSM_SUBSYSTEM_VIDEO, MSM_SUBSYSTEM_VIDEO_FWARE};
#ifdef DDL_BUF_LOG
static void ddl_print_buffer(struct ddl_context *ddl_context,
@@ -39,13 +37,10 @@
void *ddl_pmem_alloc(struct ddl_buf_addr *addr, size_t sz, u32 alignment)
{
u32 alloc_size, offset = 0 ;
- u32 index = 0;
struct ddl_context *ddl_context;
- struct msm_mapped_buffer *mapped_buffer = NULL;
unsigned long iova = 0;
unsigned long buffer_size = 0;
unsigned long *kernel_vaddr = NULL;
- unsigned long flags = 0;
int ret = 0;
ion_phys_addr_t phyaddr = 0;
size_t len = 0;
@@ -128,51 +123,10 @@
addr->align_virtual_addr = addr->virtual_base_addr + offset;
addr->buffer_size = alloc_size;
} else {
- addr->alloced_phys_addr = (phys_addr_t)
- allocate_contiguous_memory_nomap(alloc_size,
- res_trk_get_mem_type(), SZ_4K);
- if (!addr->alloced_phys_addr) {
- DDL_MSG_ERROR("%s() : acm alloc failed (%d)\n",
- __func__, alloc_size);
- goto bail_out;
- }
- flags = MSM_SUBSYSTEM_MAP_IOVA | MSM_SUBSYSTEM_MAP_KADDR;
- if (alignment == DDL_KILO_BYTE(128))
- index = 1;
- else if (alignment > SZ_4K)
- flags |= MSM_SUBSYSTEM_ALIGN_IOVA_8K;
-
- addr->mapped_buffer =
- msm_subsystem_map_buffer((unsigned long)addr->alloced_phys_addr,
- alloc_size, flags, &vidc_mmu_subsystem[index],
- sizeof(vidc_mmu_subsystem[index])/sizeof(unsigned int));
- if (IS_ERR(addr->mapped_buffer)) {
- pr_err(" %s() buffer map failed", __func__);
- goto free_acm_alloc;
- }
- mapped_buffer = addr->mapped_buffer;
- if (!mapped_buffer->vaddr || !mapped_buffer->iova[0]) {
- pr_err("%s() map buffers failed\n", __func__);
- goto free_map_buffers;
- }
- addr->physical_base_addr = (u8 *)mapped_buffer->iova[0];
- addr->virtual_base_addr = mapped_buffer->vaddr;
- addr->align_physical_addr = (u8 *) DDL_ALIGN((u32)
- addr->physical_base_addr, alignment);
- offset = (u32)(addr->align_physical_addr -
- addr->physical_base_addr);
- addr->align_virtual_addr = addr->virtual_base_addr + offset;
- addr->buffer_size = sz;
+ pr_err("ION must be enabled.");
+ goto bail_out;
}
return addr->virtual_base_addr;
-free_map_buffers:
- msm_subsystem_unmap_buffer(addr->mapped_buffer);
- addr->mapped_buffer = NULL;
-free_acm_alloc:
- free_contiguous_memory_by_paddr(
- (unsigned long)addr->alloced_phys_addr);
- addr->alloced_phys_addr = (phys_addr_t)NULL;
- return NULL;
unmap_ion_alloc:
ion_unmap_kernel(ddl_context->video_ion_client,
addr->alloc_handle);
@@ -207,12 +161,6 @@
ion_free(ddl_context->video_ion_client,
addr->alloc_handle);
}
- } else {
- if (addr->mapped_buffer)
- msm_subsystem_unmap_buffer(addr->mapped_buffer);
- if (addr->alloced_phys_addr)
- free_contiguous_memory_by_paddr(
- (unsigned long)addr->alloced_phys_addr);
}
memset(addr, 0, sizeof(struct ddl_buf_addr));
}
diff --git a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
index c15218d..5c15d9a 100644
--- a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
+++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
@@ -18,6 +18,7 @@
#include <linux/pm_runtime.h>
#include <mach/clk.h>
#include <mach/msm_memtypes.h>
+#include <mach/iommu_domains.h>
#include <linux/interrupt.h>
#include <linux/memory_alloc.h>
#include <asm/sizes.h>
@@ -30,8 +31,6 @@
static unsigned int vidc_clk_table[5] = {
48000000, 133330000, 200000000, 228570000, 266670000,
};
-static unsigned int restrk_mmu_subsystem[] = {
- MSM_SUBSYSTEM_VIDEO, MSM_SUBSYSTEM_VIDEO_FWARE};
static struct res_trk_context resource_context;
#define VIDC_FW "vidc_1080p.fw"
@@ -56,10 +55,8 @@
static void *res_trk_pmem_map
(struct ddl_buf_addr *addr, size_t sz, u32 alignment)
{
- u32 offset = 0, flags = 0;
- u32 index = 0;
+ u32 offset = 0;
struct ddl_context *ddl_context;
- struct msm_mapped_buffer *mapped_buffer = NULL;
int ret = 0;
unsigned long iova = 0;
unsigned long buffer_size = 0;
@@ -100,53 +97,11 @@
addr->align_virtual_addr = addr->virtual_base_addr + offset;
addr->buffer_size = buffer_size;
} else {
- if (!res_trk_check_for_sec_session()) {
- if (!addr->alloced_phys_addr) {
- pr_err(" %s() alloced addres NULL", __func__);
- goto bail_out;
- }
- flags = MSM_SUBSYSTEM_MAP_IOVA |
- MSM_SUBSYSTEM_MAP_KADDR;
- if (alignment == DDL_KILO_BYTE(128))
- index = 1;
- else if (alignment > SZ_4K)
- flags |= MSM_SUBSYSTEM_ALIGN_IOVA_8K;
- addr->mapped_buffer =
- msm_subsystem_map_buffer(
- (unsigned long)addr->alloced_phys_addr,
- sz, flags, &restrk_mmu_subsystem[index],
- sizeof(restrk_mmu_subsystem[index])/
- sizeof(unsigned int));
- if (IS_ERR(addr->mapped_buffer)) {
- pr_err(" %s() buffer map failed", __func__);
- goto bail_out;
- }
- mapped_buffer = addr->mapped_buffer;
- if (!mapped_buffer->vaddr || !mapped_buffer->iova[0]) {
- pr_err("%s() map buffers failed\n", __func__);
- goto bail_out;
- }
- addr->physical_base_addr =
- (u8 *)mapped_buffer->iova[0];
- addr->virtual_base_addr =
- mapped_buffer->vaddr;
- } else {
- addr->physical_base_addr =
- (u8 *) addr->alloced_phys_addr;
- addr->virtual_base_addr =
- (u8 *)addr->alloced_phys_addr;
- }
- addr->align_physical_addr = (u8 *) DDL_ALIGN((u32)
- addr->physical_base_addr, alignment);
- offset = (u32)(addr->align_physical_addr -
- addr->physical_base_addr);
- addr->align_virtual_addr = addr->virtual_base_addr + offset;
- addr->buffer_size = sz;
+ pr_err("ION must be enabled.");
+ goto bail_out;
}
return addr->virtual_base_addr;
bail_out:
- if (IS_ERR(addr->mapped_buffer))
- msm_subsystem_unmap_buffer(addr->mapped_buffer);
return NULL;
ion_unmap_bail_out:
if (!IS_ERR_OR_NULL(addr->alloc_handle)) {
@@ -171,12 +126,6 @@
addr->alloc_handle);
addr->alloc_handle = NULL;
}
- } else {
- if (addr->mapped_buffer)
- msm_subsystem_unmap_buffer(addr->mapped_buffer);
- if (addr->alloced_phys_addr)
- free_contiguous_memory_by_paddr(
- (unsigned long)addr->alloced_phys_addr);
}
memset(addr, 0 , sizeof(struct ddl_buf_addr));
}
@@ -263,8 +212,7 @@
addr->virtual_base_addr = NULL;
addr->physical_base_addr = NULL;
}
- } else if (addr->mapped_buffer)
- msm_subsystem_unmap_buffer(addr->mapped_buffer);
+ }
addr->mapped_buffer = NULL;
}
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.c
index 672c049..edc8112 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -87,11 +87,9 @@
void ddl_pmem_alloc(struct ddl_buf_addr *buff_addr, size_t sz, u32 align)
{
u32 guard_bytes, align_mask;
- u32 physical_addr;
u32 align_offset;
- u32 alloc_size, flags = 0;
+ u32 alloc_size;
struct ddl_context *ddl_context;
- struct msm_mapped_buffer *mapped_buffer = NULL;
unsigned long *kernel_vaddr = NULL;
ion_phys_addr_t phyaddr = 0;
size_t len = 0;
@@ -155,36 +153,8 @@
(u32)buff_addr->virtual_base_addr,
alloc_size, align, len);
} else {
- physical_addr = (u32)
- allocate_contiguous_memory_nomap(alloc_size,
- ddl_context->memtype, SZ_4K);
- if (!physical_addr) {
- ERR("\n%s(): DDL pmem allocate failed\n",
- __func__);
- goto bailout;
- }
- buff_addr->physical_base_addr = (u32 *) physical_addr;
- flags = MSM_SUBSYSTEM_MAP_KADDR;
- buff_addr->mapped_buffer =
- msm_subsystem_map_buffer((unsigned long)physical_addr,
- alloc_size, flags, NULL, 0);
- if (IS_ERR(buff_addr->mapped_buffer)) {
- ERR("\n%s() buffer map failed\n", __func__);
- goto free_pmem_buffer;
- }
- mapped_buffer = buff_addr->mapped_buffer;
- if (!mapped_buffer->vaddr) {
- ERR("\n%s() mapped virtual address is NULL\n",
- __func__);
- goto unmap_pmem_buffer;
- }
- buff_addr->virtual_base_addr = mapped_buffer->vaddr;
- DBG("ddl_pmem_alloc: mem_type(0x%x), phys(0x%x),"\
- " virt(0x%x), sz(%u), align(%u)",
- (u32)buff_addr->mem_type,
- (u32)buff_addr->physical_base_addr,
- (u32)buff_addr->virtual_base_addr,
- alloc_size, SZ_4K);
+ pr_err("ION must be enabled.");
+ goto bailout;
}
memset(buff_addr->virtual_base_addr, 0 , sz + guard_bytes);
@@ -205,16 +175,6 @@
(u32)buff_addr->align_virtual_addr);
return;
-unmap_pmem_buffer:
- if (buff_addr->mapped_buffer)
- msm_subsystem_unmap_buffer(buff_addr->mapped_buffer);
-free_pmem_buffer:
- if (buff_addr->physical_base_addr)
- free_contiguous_memory_by_paddr((unsigned long)
- buff_addr->physical_base_addr);
- memset(buff_addr, 0, sizeof(struct ddl_buf_addr));
- return;
-
unmap_ion_buffer:
if (ddl_context->video_ion_client) {
if (buff_addr->alloc_handle)
@@ -253,13 +213,6 @@
ion_free(ddl_context->video_ion_client,
buff_addr->alloc_handle);
}
- } else {
- if (buff_addr->mapped_buffer)
- msm_subsystem_unmap_buffer(
- buff_addr->mapped_buffer);
- if (buff_addr->physical_base_addr)
- free_contiguous_memory_by_paddr((unsigned long)
- buff_addr->physical_base_addr);
}
memset(buff_addr, 0, sizeof(struct ddl_buf_addr));
}
diff --git a/drivers/video/msm/vidc/common/dec/vdec.c b/drivers/video/msm/vidc/common/dec/vdec.c
index 1c69d8f..ec27b00 100644
--- a/drivers/video/msm/vidc/common/dec/vdec.c
+++ b/drivers/video/msm/vidc/common/dec/vdec.c
@@ -28,10 +28,10 @@
#include <linux/clk.h>
#include <linux/timer.h>
-#include <mach/msm_subsystem_map.h>
#include <media/msm/vidc_type.h>
#include <media/msm/vcd_api.h>
#include <media/msm/vidc_init.h>
+#include <mach/iommu_domains.h>
#include "vcd_res_tracker_api.h"
#include "vdec_internal.h"
@@ -1241,13 +1241,6 @@
if (!client_ctx)
return false;
- if (client_ctx->vcd_meta_buffer.client_data)
- msm_subsystem_unmap_buffer((struct msm_mapped_buffer *)
- client_ctx->vcd_meta_buffer.client_data);
-
- if (client_ctx->vcd_meta_buffer.client_data_iommu)
- msm_subsystem_unmap_buffer((struct msm_mapped_buffer *)
- client_ctx->vcd_meta_buffer.client_data_iommu);
vcd_property_hdr.prop_id = VCD_I_FREE_EXT_METABUFFER;
vcd_property_hdr.sz = sizeof(struct vcd_property_buffer_size);
@@ -1300,9 +1293,6 @@
if (!client_ctx)
return false;
- if (client_ctx->vcd_h264_mv_buffer.client_data)
- msm_subsystem_unmap_buffer((struct msm_mapped_buffer *)
- client_ctx->vcd_h264_mv_buffer.client_data);
vcd_property_hdr.prop_id = VCD_I_FREE_H264_MV_BUFFER;
vcd_property_hdr.sz = sizeof(struct vcd_property_buffer_size);
diff --git a/drivers/video/msm/vidc/common/enc/venc_internal.c b/drivers/video/msm/vidc/common/enc/venc_internal.c
index 3dae4be1..06b690d 100644
--- a/drivers/video/msm/vidc/common/enc/venc_internal.c
+++ b/drivers/video/msm/vidc/common/enc/venc_internal.c
@@ -27,10 +27,10 @@
#include <linux/workqueue.h>
#include <linux/clk.h>
-#include <mach/msm_subsystem_map.h>
#include <media/msm/vidc_type.h>
#include <media/msm/vcd_api.h>
#include <media/msm/vidc_init.h>
+#include <mach/iommu_domains.h>
#include "vcd_res_tracker_api.h"
#include "venc_internal.h"
@@ -1948,9 +1948,6 @@
venc_recon->pbuffer);
return false;
}
- if (control->client_data)
- msm_subsystem_unmap_buffer((struct msm_mapped_buffer *)
- control->client_data);
vcd_property_hdr.prop_id = VCD_I_FREE_RECON_BUFFERS;
vcd_property_hdr.sz = sizeof(struct vcd_property_buffer_size);
diff --git a/drivers/video/msm/vidc/common/init/vidc_init.c b/drivers/video/msm/vidc/common/init/vidc_init.c
index 72a1d5f..cf01622 100644
--- a/drivers/video/msm/vidc/common/init/vidc_init.c
+++ b/drivers/video/msm/vidc/common/init/vidc_init.c
@@ -30,7 +30,7 @@
#include <linux/debugfs.h>
#include <mach/clk.h>
#include <linux/pm_runtime.h>
-#include <mach/msm_subsystem_map.h>
+#include <mach/iommu_domains.h>
#include <media/msm/vcd_api.h>
#include <media/msm/vidc_init.h>
#include "vidc_init_internal.h"
@@ -420,12 +420,6 @@
if (!client_ctx->user_ion_client)
goto bail_out_cleanup;
for (i = 0; i < *num_of_buffers; ++i) {
- if (buf_addr_table[i].client_data) {
- msm_subsystem_unmap_buffer(
- (struct msm_mapped_buffer *)
- buf_addr_table[i].client_data);
- buf_addr_table[i].client_data = NULL;
- }
if (!IS_ERR_OR_NULL(buf_addr_table[i].buff_ion_handle)) {
if (!IS_ERR_OR_NULL(client_ctx->user_ion_client)) {
ion_unmap_kernel(client_ctx->user_ion_client,
@@ -448,11 +442,6 @@
}
}
}
- if (client_ctx->vcd_h264_mv_buffer.client_data) {
- msm_subsystem_unmap_buffer((struct msm_mapped_buffer *)
- client_ctx->vcd_h264_mv_buffer.client_data);
- client_ctx->vcd_h264_mv_buffer.client_data = NULL;
- }
if (!IS_ERR_OR_NULL(client_ctx->h264_mv_ion_handle)) {
if (!IS_ERR_OR_NULL(client_ctx->user_ion_client)) {
ion_unmap_kernel(client_ctx->user_ion_client,
@@ -608,7 +597,7 @@
} else {
if (!vcd_get_ion_status()) {
pr_err("PMEM not available\n");
- return false;
+ goto bail_out_add;
} else {
buff_ion_handle = ion_import_dma_buf(
client_ctx->user_ion_client, pmem_fd);
@@ -808,11 +797,6 @@
__func__, client_ctx, user_vaddr);
goto bail_out_del;
}
- if (buf_addr_table[i].client_data) {
- msm_subsystem_unmap_buffer(
- (struct msm_mapped_buffer *)buf_addr_table[i].client_data);
- buf_addr_table[i].client_data = NULL;
- }
*kernel_vaddr = buf_addr_table[i].kernel_vaddr;
if (buf_addr_table[i].buff_ion_handle) {
ion_unmap_kernel(client_ctx->user_ion_client,
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_sub.c b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
index 09cd91d..f7424ed 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_sub.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
@@ -11,9 +11,9 @@
*
*/
#include <linux/memory_alloc.h>
-#include <mach/msm_subsystem_map.h>
#include <asm/div64.h>
#include <media/msm/vidc_type.h>
+#include <mach/iommu_domains.h>
#include "vcd.h"
#include "vdec_internal.h"
@@ -24,19 +24,17 @@
struct vcd_msm_map_buffer {
phys_addr_t phy_addr;
- struct msm_mapped_buffer *mapped_buffer;
+ void *vaddr;
struct ion_handle *alloc_handle;
u32 in_use;
};
static struct vcd_msm_map_buffer msm_mapped_buffer_table[MAP_TABLE_SZ];
-static unsigned int vidc_mmu_subsystem[] = {MSM_SUBSYSTEM_VIDEO};
static int vcd_pmem_alloc(size_t sz, u8 **kernel_vaddr, u8 **phy_addr,
struct vcd_clnt_ctxt *cctxt)
{
- u32 memtype, i = 0, flags = 0;
+ u32 memtype, i = 0;
struct vcd_msm_map_buffer *map_buffer = NULL;
- struct msm_mapped_buffer *mapped_buffer = NULL;
unsigned long iova = 0;
unsigned long buffer_size = 0;
int ret = 0;
@@ -64,31 +62,8 @@
res_trk_set_mem_type(DDL_MM_MEM);
memtype = res_trk_get_mem_type();
if (!cctxt->vcd_enable_ion) {
- map_buffer->phy_addr = (phys_addr_t)
- allocate_contiguous_memory_nomap(sz, memtype, SZ_4K);
- if (!map_buffer->phy_addr) {
- pr_err("%s() acm alloc failed", __func__);
- goto free_map_table;
- }
- flags = MSM_SUBSYSTEM_MAP_IOVA | MSM_SUBSYSTEM_MAP_KADDR;
- map_buffer->mapped_buffer =
- msm_subsystem_map_buffer((unsigned long)map_buffer->phy_addr,
- sz, flags, vidc_mmu_subsystem,
- sizeof(vidc_mmu_subsystem)/sizeof(unsigned int));
- if (IS_ERR(map_buffer->mapped_buffer)) {
- pr_err(" %s() buffer map failed", __func__);
- goto free_acm_alloc;
- }
- mapped_buffer = map_buffer->mapped_buffer;
- if (!mapped_buffer->vaddr || !mapped_buffer->iova[0]) {
- pr_err("%s() map buffers failed", __func__);
- goto free_map_buffers;
- }
- *phy_addr = (u8 *) mapped_buffer->iova[0];
- *kernel_vaddr = (u8 *) mapped_buffer->vaddr;
- VCD_MSG_LOW("vcd_pmem_alloc: phys(0x%x), virt(0x%x), "\
- "sz(%u), flags(0x%x)", (u32)*phy_addr,
- (u32)*kernel_vaddr, sz, (u32)flags);
+ pr_err("ION must be enabled\n");
+ goto free_map_table;
} else {
map_buffer->alloc_handle = ion_alloc(
cctxt->vcd_ion_client, sz, SZ_4K,
@@ -106,6 +81,7 @@
*kernel_vaddr = (u8 *) ion_map_kernel(
cctxt->vcd_ion_client,
map_buffer->alloc_handle);
+ map_buffer->vaddr = *kernel_vaddr;
if (!(*kernel_vaddr)) {
pr_err("%s() ION map failed", __func__);
goto ion_free_bailout;
@@ -143,8 +119,6 @@
goto free_map_table;
}
*phy_addr = (u8 *)map_buffer->phy_addr;
- mapped_buffer = NULL;
- map_buffer->mapped_buffer = NULL;
VCD_MSG_LOW("vcd_ion_alloc: phys(0x%x), virt(0x%x), "\
"sz(%u), ionflags(0x%x)", (u32)*phy_addr,
(u32)*kernel_vaddr, sz, (u32)ionflag);
@@ -152,15 +126,6 @@
return 0;
-free_map_buffers:
- if (map_buffer->mapped_buffer)
- msm_subsystem_unmap_buffer(map_buffer->mapped_buffer);
-free_acm_alloc:
- if (!cctxt->vcd_enable_ion) {
- free_contiguous_memory_by_paddr(
- (unsigned long)map_buffer->phy_addr);
- }
- return -ENOMEM;
ion_map_bailout:
ion_unmap_kernel(cctxt->vcd_ion_client, map_buffer->alloc_handle);
ion_free_bailout:
@@ -183,8 +148,7 @@
}
for (i = 0; i < MAP_TABLE_SZ; i++) {
if (msm_mapped_buffer_table[i].in_use &&
- (msm_mapped_buffer_table[i]
- .mapped_buffer->vaddr == kernel_vaddr)) {
+ (msm_mapped_buffer_table[i].vaddr == kernel_vaddr)) {
map_buffer = &msm_mapped_buffer_table[i];
map_buffer->in_use = 0;
break;
@@ -194,8 +158,6 @@
pr_err("%s() Entry not found", __func__);
goto bailout;
}
- if (map_buffer->mapped_buffer)
- msm_subsystem_unmap_buffer(map_buffer->mapped_buffer);
if (cctxt->vcd_enable_ion) {
VCD_MSG_LOW("vcd_ion_free: phys(0x%x), virt(0x%x)",
(u32)phy_addr, (u32)kernel_vaddr);
diff --git a/include/linux/input/synaptics_dsx.h b/include/linux/input/synaptics_dsx.h
index 56616d7..f90f59e 100644
--- a/include/linux/input/synaptics_dsx.h
+++ b/include/linux/input/synaptics_dsx.h
@@ -55,6 +55,7 @@
unsigned reset_gpio;
unsigned panel_x;
unsigned panel_y;
+ const char *fw_image_name;
int (*gpio_config)(unsigned gpio, bool configure);
struct synaptics_rmi4_capacitance_button_map *capacitance_button_map;
};
diff --git a/include/linux/qseecom.h b/include/linux/qseecom.h
index b0f089b..d29d2fd 100644
--- a/include/linux/qseecom.h
+++ b/include/linux/qseecom.h
@@ -117,6 +117,14 @@
int app_id; /* out */
};
+struct qseecom_send_svc_cmd_req {
+ uint32_t cmd_id;
+ void *cmd_req_buf; /* in */
+ unsigned int cmd_req_len; /* in */
+ void *resp_buf; /* in/out */
+ unsigned int resp_len; /* in/out */
+};
+
#define QSEECOM_IOC_MAGIC 0x97
@@ -165,5 +173,8 @@
#define QSEECOM_IOCTL_APP_LOADED_QUERY_REQ \
_IOWR(QSEECOM_IOC_MAGIC, 15, struct qseecom_qseos_app_load_query)
+#define QSEECOM_IOCTL_SEND_CMD_SERVICE_REQ \
+ _IOWR(QSEECOM_IOC_MAGIC, 16, struct qseecom_send_svc_cmd_req)
+
#endif /* __QSEECOM_H_ */
diff --git a/include/media/msmb_isp.h b/include/media/msmb_isp.h
index 7f70a01..6fb1a65 100644
--- a/include/media/msmb_isp.h
+++ b/include/media/msmb_isp.h
@@ -109,6 +109,7 @@
struct msm_vfe_rdi_cfg rdi_cfg;
} d;
enum msm_vfe_input_src input_src;
+ uint32_t input_pix_clk;
};
struct msm_vfe_axi_plane_cfg {
diff --git a/include/media/msmb_ispif.h b/include/media/msmb_ispif.h
index f0f015e..c9eb12a 100644
--- a/include/media/msmb_ispif.h
+++ b/include/media/msmb_ispif.h
@@ -20,6 +20,8 @@
RDI2,
INTF_MAX
};
+#define MAX_PARAM_ENTRIES (INTF_MAX * 2)
+
#define PIX0_MASK (1 << PIX0)
#define PIX1_MASK (1 << PIX1)
#define RDI0_MASK (1 << RDI0)
@@ -76,7 +78,7 @@
struct msm_ispif_param_data {
uint32_t num;
- struct msm_ispif_params_entry entries[INTF_MAX];
+ struct msm_ispif_params_entry entries[MAX_PARAM_ENTRIES];
};
struct msm_isp_info {
diff --git a/include/sound/apr_audio-v2.h b/include/sound/apr_audio-v2.h
index 04e683f..fa4dedc 100644
--- a/include/sound/apr_audio-v2.h
+++ b/include/sound/apr_audio-v2.h
@@ -335,6 +335,7 @@
/* Payload an #ADM_CMD_GET_PP_PARAMS_V5 command.
*/
struct adm_cmd_get_pp_params_v5 {
+ struct apr_hdr hdr;
u32 data_payload_addr_lsw;
/* LSW of parameter data payload address.*/
@@ -2593,6 +2594,14 @@
} __packed;
+/* @brief Dolby Digital Plus end point configuration structure
+ */
+struct asm_dec_ddp_endp_param_v2 {
+ struct apr_hdr hdr;
+ struct asm_stream_cmd_set_encdec_param encdec;
+ int endp_param_value;
+} __packed;
+
/* @brief Multichannel PCM encoder configuration structure used
* in the #ASM_STREAM_CMD_OPEN_READ_V2 command.
*/
@@ -6913,4 +6922,7 @@
struct afe_port_cmd_set_param_v2 param;
} __packed;
+/* Dolby DAP topology */
+#define DOLBY_ADM_COPP_TOPOLOGY_ID 0x0001033B
+
#endif /*_APR_AUDIO_V2_H_ */
diff --git a/include/sound/compress_params.h b/include/sound/compress_params.h
index b95fa3c..f5ab179 100644
--- a/include/sound/compress_params.h
+++ b/include/sound/compress_params.h
@@ -89,6 +89,8 @@
#define SND_AUDIOCODEC_PASS_THROUGH ((__u32) 0x00000015)
#define SND_AUDIOCODEC_MP2 ((__u32) 0x00000016)
#define SND_AUDIOCODEC_DTS_LBR_PASS_THROUGH ((__u32) 0x00000017)
+#define SND_AUDIOCODEC_EAC3 ((__u32) 0x00000018)
+#define SND_AUDIOCODEC_MAX SND_AUDIOCODEC_EAC3
/*
* Profile and modes are listed with bit masks. This allows for a
* more compact representation of fields that will not evolve
@@ -337,7 +339,12 @@
__u32 modelIdLength;
__u8 *modelId;
};
-
+struct snd_dec_ddp {
+ __u32 params_length;
+ __u8 *params;
+ __u32 params_id[18];
+ __u32 params_value[18];
+};
union snd_codec_options {
struct snd_enc_wma wma;
struct snd_enc_vorbis vorbis;
@@ -345,6 +352,7 @@
struct snd_enc_flac flac;
struct snd_enc_generic generic;
struct snd_dec_dts dts;
+ struct snd_dec_ddp ddp;
};
/** struct snd_codec_desc - description of codec capabilities
diff --git a/include/sound/q6adm-v2.h b/include/sound/q6adm-v2.h
index 77a805c..4bea1e1 100644
--- a/include/sound/q6adm-v2.h
+++ b/include/sound/q6adm-v2.h
@@ -32,6 +32,12 @@
int adm_open(int port, int path, int rate, int mode, int topology,
bool perf_mode, uint16_t bits_per_sample);
+int adm_dolby_dap_get_params(int port_id, uint32_t module_id, uint32_t param_id,
+ uint32_t params_length, char *params);
+
+int adm_dolby_dap_send_params(int port_id, char *params,
+ uint32_t params_length);
+
int adm_multi_ch_copp_open(int port, int path, int rate, int mode,
int topology, bool perf_mode, uint16_t bits_per_sample);
diff --git a/include/sound/q6asm-v2.h b/include/sound/q6asm-v2.h
index 0d0670e..0dd14e6 100644
--- a/include/sound/q6asm-v2.h
+++ b/include/sound/q6asm-v2.h
@@ -41,6 +41,8 @@
#define FORMAT_AMR_WB_PLUS 0x0010
#define FORMAT_MPEG4_MULTI_AAC 0x0011
#define FORMAT_MULTI_CHANNEL_LINEAR_PCM 0x0012
+#define FORMAT_AC3 0x0013
+#define FORMAT_EAC3 0x0014
#define ENCDEC_SBCBITRATE 0x0001
#define ENCDEC_IMMEDIATE_DECODE 0x0002
@@ -295,6 +297,10 @@
int q6asm_media_format_block_amrwbplus(struct audio_client *ac,
struct asm_amrwbplus_cfg *cfg);
+
+int q6asm_ds1_set_endp_params(struct audio_client *ac,
+ int param_id, int param_value);
+
/* PP specific */
int q6asm_equalizer(struct audio_client *ac, void *eq);
diff --git a/sound/soc/msm/Kconfig b/sound/soc/msm/Kconfig
index 35a9646..66c475f 100644
--- a/sound/soc/msm/Kconfig
+++ b/sound/soc/msm/Kconfig
@@ -163,6 +163,16 @@
OCMEM gets exercised for low-power
audio and voice use cases.
+config DOLBY_DAP
+ bool "Enable Dolby DAP"
+ depends on SND_SOC_MSM8974
+ help
+ To add support for dolby DAP post processing.
+ This support is to configure the post processing parameters
+ to DSP. The configuration includes sending the end point
+ device, end point dependent post processing parameters and
+ the various posrt processing parameters
+
config SND_SOC_MSM8974
tristate "SoC Machine driver for MSM8974 boards"
depends on ARCH_MSM8974
@@ -173,6 +183,7 @@
select SND_SOC_MSM_HDMI_CODEC_RX
select SND_DYNAMIC_MINORS
select AUDIO_OCMEM
+ select DOLBY_DAP
help
To add support for SoC audio on MSM8974.
This will enable sound soc drivers which
diff --git a/sound/soc/msm/Makefile b/sound/soc/msm/Makefile
index c26eafc..ebde90b 100644
--- a/sound/soc/msm/Makefile
+++ b/sound/soc/msm/Makefile
@@ -62,12 +62,13 @@
snd-soc-qdsp6-objs += msm-pcm-lpa.o msm-pcm-afe.o
obj-$(CONFIG_SND_SOC_QDSP6) += snd-soc-qdsp6.o
+snd-soc-hostless-pcm-objs := msm-pcm-hostless.o
+obj-$(CONFIG_SND_SOC_MSM_HOSTLESS_PCM) += snd-soc-hostless-pcm.o
+
snd-soc-msm8960-objs := msm8960.o apq8064.o msm8930.o mpq8064.o apq8064-i2s.o
obj-$(CONFIG_SND_SOC_MSM8960) += snd-soc-msm8960.o
# Generic MSM drivers
-snd-soc-hostless-pcm-objs := msm-pcm-hostless.o
-obj-$(CONFIG_SND_SOC_MSM_HOSTLESS_PCM) += snd-soc-hostless-pcm.o
snd-soc-msm8660-apq-objs := msm8660-apq-wm8903.o
obj-$(CONFIG_SND_SOC_MSM8660_APQ) += snd-soc-msm8660-apq.o
diff --git a/sound/soc/msm/apq8064-i2s.c b/sound/soc/msm/apq8064-i2s.c
index f9e0402..99defcd 100644
--- a/sound/soc/msm/apq8064-i2s.c
+++ b/sound/soc/msm/apq8064-i2s.c
@@ -2636,6 +2636,7 @@
pr_info("%s: Not APQ8064 in I2S mode\n", __func__);
return -ENODEV;
}
+ mutex_init(&cdc_mclk_mutex);
pr_debug("%s: APQ8064 is in I2S mode\n", __func__);
mbhc_cfg.calibration = def_tabla_mbhc_cal();
if (!mbhc_cfg.calibration) {
@@ -2680,7 +2681,6 @@
return ret;
}
- mutex_init(&cdc_mclk_mutex);
atomic_set(&mi2s_rsc_ref, 0);
atomic_set(&auxpcm_rsc_ref, 0);
return ret;
diff --git a/sound/soc/msm/apq8064.c b/sound/soc/msm/apq8064.c
index cafc5c3..7960f13 100644
--- a/sound/soc/msm/apq8064.c
+++ b/sound/soc/msm/apq8064.c
@@ -2187,6 +2187,8 @@
if (socinfo_get_pmic_model() == PMIC_MODEL_PM8917)
bottom_spk_pamp_gpio = PM8921_GPIO_PM_TO_SYS(16);
+ mutex_init(&cdc_mclk_mutex);
+
mbhc_cfg.calibration = def_tabla_mbhc_cal();
if (!mbhc_cfg.calibration) {
pr_err("Calibration data allocation failed\n");
@@ -2208,7 +2210,6 @@
return ret;
}
- mutex_init(&cdc_mclk_mutex);
atomic_set(&auxpcm_rsc_ref, 0);
return ret;
diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c
index 734bd39..8db13f6 100644
--- a/sound/soc/msm/msm-dai-fe.c
+++ b/sound/soc/msm/msm-dai-fe.c
@@ -25,7 +25,7 @@
/* Conventional and unconventional sample rate supported */
static unsigned int supported_sample_rates[] = {
8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000,
- 96000
+ 96000, 192000
};
static struct snd_pcm_hw_constraint_list constraints_sample_rates = {
@@ -53,14 +53,14 @@
.playback = {
.stream_name = "Multimedia1 Playback",
.aif_name = "MM_DL1",
- .rates = (SNDRV_PCM_RATE_8000_96000|
+ .rates = (SNDRV_PCM_RATE_8000_192000|
SNDRV_PCM_RATE_KNOT),
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE),
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 96000,
+ .rate_max = 192000,
},
.capture = {
.stream_name = "Multimedia1 Capture",
@@ -80,14 +80,14 @@
.playback = {
.stream_name = "Multimedia2 Playback",
.aif_name = "MM_DL2",
- .rates = (SNDRV_PCM_RATE_8000_96000|
+ .rates = (SNDRV_PCM_RATE_8000_192000|
SNDRV_PCM_RATE_KNOT),
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE),
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 96000,
+ .rate_max = 192000,
},
.capture = {
.stream_name = "Multimedia2 Capture",
@@ -157,14 +157,14 @@
.playback = {
.stream_name = "MultiMedia3 Playback",
.aif_name = "MM_DL3",
- .rates = (SNDRV_PCM_RATE_8000_96000 |
+ .rates = (SNDRV_PCM_RATE_8000_192000 |
SNDRV_PCM_RATE_KNOT),
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE),
.channels_min = 1,
.channels_max = 6,
.rate_min = 8000,
- .rate_max = 96000,
+ .rate_max = 192000,
},
.ops = &msm_fe_Multimedia_dai_ops,
.name = "MultiMedia3",
@@ -173,14 +173,14 @@
.playback = {
.stream_name = "MultiMedia4 Playback",
.aif_name = "MM_DL4",
- .rates = (SNDRV_PCM_RATE_8000_96000 |
+ .rates = (SNDRV_PCM_RATE_8000_192000 |
SNDRV_PCM_RATE_KNOT),
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE),
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 96000,
+ .rate_max = 192000,
},
.capture = {
.stream_name = "MultiMedia4 Capture",
@@ -200,14 +200,14 @@
.playback = {
.stream_name = "MultiMedia5 Playback",
.aif_name = "MM_DL5",
- .rates = (SNDRV_PCM_RATE_8000_96000 |
+ .rates = (SNDRV_PCM_RATE_8000_192000 |
SNDRV_PCM_RATE_KNOT),
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE),
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 96000,
+ .rate_max = 192000,
},
.capture = {
.stream_name = "MultiMedia5 Capture",
@@ -227,14 +227,14 @@
.playback = {
.stream_name = "MultiMedia6 Playback",
.aif_name = "MM_DL6",
- .rates = (SNDRV_PCM_RATE_8000_96000 |
+ .rates = (SNDRV_PCM_RATE_8000_192000 |
SNDRV_PCM_RATE_KNOT),
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE),
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 96000,
+ .rate_max = 192000,
},
.ops = &msm_fe_Multimedia_dai_ops,
.name = "MultiMedia6",
@@ -243,14 +243,14 @@
.playback = {
.stream_name = "MultiMedia7 Playback",
.aif_name = "MM_DL7",
- .rates = (SNDRV_PCM_RATE_8000_96000 |
+ .rates = (SNDRV_PCM_RATE_8000_192000 |
SNDRV_PCM_RATE_KNOT),
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE),
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 96000,
+ .rate_max = 192000,
},
.ops = &msm_fe_Multimedia_dai_ops,
.name = "MultiMedia7",
@@ -259,14 +259,14 @@
.playback = {
.stream_name = "MultiMedia8 Playback",
.aif_name = "MM_DL8",
- .rates = (SNDRV_PCM_RATE_8000_96000 |
+ .rates = (SNDRV_PCM_RATE_8000_192000 |
SNDRV_PCM_RATE_KNOT),
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE),
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 96000,
+ .rate_max = 192000,
},
.ops = &msm_fe_Multimedia_dai_ops,
.name = "MultiMedia8",
@@ -276,7 +276,7 @@
.playback = {
.stream_name = "SLIMBUS0 Hostless Playback",
.aif_name = "SLIM0_DL_HL",
- .rates = SNDRV_PCM_RATE_8000_96000,
+ .rates = SNDRV_PCM_RATE_8000_192000,
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE),
.channels_min = 1,
@@ -301,13 +301,13 @@
.playback = {
.stream_name = "SLIMBUS1 Hostless Playback",
.aif_name = "SLIM1_DL_HL",
- .rates = SNDRV_PCM_RATE_8000_96000,
+ .rates = SNDRV_PCM_RATE_8000_192000,
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE),
.channels_min = 1,
.channels_max = 2,
.rate_min = 8000,
- .rate_max = 96000,
+ .rate_max = 192000,
},
.capture = {
.stream_name = "SLIMBUS1 Hostless Capture",
@@ -326,13 +326,13 @@
.playback = {
.stream_name = "SLIMBUS3 Hostless Playback",
.aif_name = "SLIM3_DL_HL",
- .rates = SNDRV_PCM_RATE_8000_48000,
+ .rates = SNDRV_PCM_RATE_8000_192000,
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE),
.channels_min = 1,
.channels_max = 2,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 192000,
},
.capture = {
.stream_name = "SLIMBUS3 Hostless Capture",
@@ -351,13 +351,13 @@
.playback = {
.stream_name = "SLIMBUS4 Hostless Playback",
.aif_name = "SLIM4_DL_HL",
- .rates = SNDRV_PCM_RATE_8000_96000,
+ .rates = SNDRV_PCM_RATE_8000_192000,
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE),
.channels_min = 1,
.channels_max = 2,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 192000,
},
.capture = {
.stream_name = "SLIMBUS4 Hostless Capture",
diff --git a/sound/soc/msm/msm8960.c b/sound/soc/msm/msm8960.c
index 65b3a57..c7fbc43 100644
--- a/sound/soc/msm/msm8960.c
+++ b/sound/soc/msm/msm8960.c
@@ -1778,6 +1778,7 @@
return -ENODEV ;
}
+ mutex_init(&cdc_mclk_mutex);
mbhc_cfg.calibration = def_tabla_mbhc_cal();
if (!mbhc_cfg.calibration) {
pr_err("Calibration data allocation failed\n");
@@ -1837,7 +1838,6 @@
__func__);
}
- mutex_init(&cdc_mclk_mutex);
atomic_set(&auxpcm_rsc_ref, 0);
return ret;
diff --git a/sound/soc/msm/msm8974.c b/sound/soc/msm/msm8974.c
index 30e9629..8905125 100644
--- a/sound/soc/msm/msm8974.c
+++ b/sound/soc/msm/msm8974.c
@@ -48,6 +48,7 @@
#define SAMPLING_RATE_48KHZ 48000
#define SAMPLING_RATE_96KHZ 96000
+#define SAMPLING_RATE_192KHZ 192000
static int msm8974_auxpcm_rate = 8000;
#define LO_1_SPK_AMP 0x1
@@ -577,13 +578,8 @@
static char const *hdmi_rx_ch_text[] = {"Two", "Three", "Four", "Five",
"Six", "Seven", "Eight"};
static char const *rx_bit_format_text[] = {"S16_LE", "S24_LE"};
-static char const *slim0_rx_sample_rate_text[] = {"KHZ_48", "KHZ_96"};
-
-static const struct soc_enum msm_enum[] = {
- SOC_ENUM_SINGLE_EXT(2, spk_function),
- SOC_ENUM_SINGLE_EXT(2, slim0_rx_ch_text),
- SOC_ENUM_SINGLE_EXT(4, slim0_tx_ch_text),
-};
+static char const *slim0_rx_sample_rate_text[] = {"KHZ_48", "KHZ_96",
+ "KHZ_192"};
static const char *const btsco_rate_text[] = {"8000", "16000"};
static const struct soc_enum msm_btsco_enum[] = {
@@ -596,6 +592,10 @@
int sample_rate_val = 0;
switch (slim0_rx_sample_rate) {
+ case SAMPLING_RATE_192KHZ:
+ sample_rate_val = 2;
+ break;
+
case SAMPLING_RATE_96KHZ:
sample_rate_val = 1;
break;
@@ -620,6 +620,9 @@
ucontrol->value.integer.value[0]);
switch (ucontrol->value.integer.value[0]) {
+ case 2:
+ slim0_rx_sample_rate = SAMPLING_RATE_192KHZ;
+ break;
case 1:
slim0_rx_sample_rate = SAMPLING_RATE_96KHZ;
break;
@@ -1092,7 +1095,7 @@
SOC_ENUM_SINGLE_EXT(4, slim0_tx_ch_text),
SOC_ENUM_SINGLE_EXT(7, hdmi_rx_ch_text),
SOC_ENUM_SINGLE_EXT(2, rx_bit_format_text),
- SOC_ENUM_SINGLE_EXT(2, slim0_rx_sample_rate_text),
+ SOC_ENUM_SINGLE_EXT(3, slim0_rx_sample_rate_text),
};
static const struct snd_kcontrol_new msm_snd_controls[] = {
diff --git a/sound/soc/msm/qdsp6v2/Makefile b/sound/soc/msm/qdsp6v2/Makefile
index 391b3da..f3dcf95 100644
--- a/sound/soc/msm/qdsp6v2/Makefile
+++ b/sound/soc/msm/qdsp6v2/Makefile
@@ -5,6 +5,7 @@
msm-lsm-client.o
obj-$(CONFIG_SND_SOC_QDSP6V2) += snd-soc-qdsp6v2.o msm-pcm-dtmf-v2.o \
msm-dai-stub-v2.o
+obj-$(CONFIG_DOLBY_DAP) += msm-dolby-dap-config.o
obj-y += q6adm.o q6afe.o q6asm.o q6audio-v2.o q6voice.o q6core.o audio_acdb.o \
rtac.o q6lsm.o
ocmem-audio-objs += audio_ocmem.o
diff --git a/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c
index 5dc5f96..9359ed7 100644
--- a/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c
@@ -321,6 +321,23 @@
}
}
+static int msm_compr_send_ddp_cfg(struct audio_client *ac,
+ struct snd_dec_ddp *ddp)
+{
+ int i, rc;
+ pr_debug("%s\n", __func__);
+ for (i = 0; i < ddp->params_length/2; i++) {
+ rc = q6asm_ds1_set_endp_params(ac, ddp->params_id[i],
+ ddp->params_value[i]);
+ if (rc) {
+ pr_err("sending params_id: %d failed\n",
+ ddp->params_id[i]);
+ return rc;
+ }
+ }
+ return 0;
+}
+
static int msm_compr_playback_prepare(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
@@ -358,6 +375,24 @@
if (ret < 0)
pr_err("%s: CMD Format block failed\n", __func__);
break;
+ case SND_AUDIOCODEC_AC3: {
+ struct snd_dec_ddp *ddp =
+ &compr->info.codec_param.codec.options.ddp;
+ pr_debug("%s: SND_AUDIOCODEC_AC3\n", __func__);
+ ret = msm_compr_send_ddp_cfg(prtd->audio_client, ddp);
+ if (ret < 0)
+ pr_err("%s: DDP CMD CFG failed\n", __func__);
+ break;
+ }
+ case SND_AUDIOCODEC_EAC3: {
+ struct snd_dec_ddp *ddp =
+ &compr->info.codec_param.codec.options.ddp;
+ pr_debug("%s: SND_AUDIOCODEC_EAC3\n", __func__);
+ ret = msm_compr_send_ddp_cfg(prtd->audio_client, ddp);
+ if (ret < 0)
+ pr_err("%s: DDP CMD CFG failed\n", __func__);
+ break;
+ }
default:
return -EINVAL;
}
@@ -511,13 +546,15 @@
{
pr_debug("%s\n", __func__);
/* MP3 Block */
- compr->info.compr_cap.num_codecs = 2;
+ compr->info.compr_cap.num_codecs = 4;
compr->info.compr_cap.min_fragment_size = runtime->hw.period_bytes_min;
compr->info.compr_cap.max_fragment_size = runtime->hw.period_bytes_max;
compr->info.compr_cap.min_fragments = runtime->hw.periods_min;
compr->info.compr_cap.max_fragments = runtime->hw.periods_max;
compr->info.compr_cap.codecs[0] = SND_AUDIOCODEC_MP3;
compr->info.compr_cap.codecs[1] = SND_AUDIOCODEC_AAC;
+ compr->info.compr_cap.codecs[2] = SND_AUDIOCODEC_AC3;
+ compr->info.compr_cap.codecs[3] = SND_AUDIOCODEC_EAC3;
/* Add new codecs here */
}
@@ -897,7 +934,7 @@
}
return 0;
case SNDRV_COMPRESS_SET_PARAMS:
- pr_debug("SNDRV_COMPRESS_SET_PARAMS: ");
+ pr_debug("SNDRV_COMPRESS_SET_PARAMS:\n");
if (copy_from_user(&compr->info.codec_param, (void *) arg,
sizeof(struct snd_compr_params))) {
rc = -EFAULT;
@@ -914,6 +951,68 @@
pr_debug("SND_AUDIOCODEC_AAC\n");
compr->codec = FORMAT_MPEG4_AAC;
break;
+ case SND_AUDIOCODEC_AC3: {
+ char params_value[18*2*sizeof(int)];
+ int *params_value_data = (int *)params_value;
+ /* 36 is the max param length for ddp */
+ int i;
+ struct snd_dec_ddp *ddp =
+ &compr->info.codec_param.codec.options.ddp;
+ int params_length = ddp->params_length*sizeof(int);
+ pr_debug("SND_AUDIOCODEC_AC3\n");
+ compr->codec = FORMAT_AC3;
+ if (copy_from_user(params_value, (void *)ddp->params,
+ params_length))
+ pr_err("%s: ERROR: copy ddp params value\n",
+ __func__);
+ pr_debug("params_length: %d\n", ddp->params_length);
+ for (i = 0; i < params_length; i++)
+ pr_debug("params_value[%d]: %x\n", i,
+ params_value_data[i]);
+ for (i = 0; i < ddp->params_length/2; i++) {
+ ddp->params_id[i] = params_value_data[2*i];
+ ddp->params_value[i] = params_value_data[2*i+1];
+ }
+ if (atomic_read(&prtd->start)) {
+ rc = msm_compr_send_ddp_cfg(prtd->audio_client,
+ ddp);
+ if (rc < 0)
+ pr_err("%s: DDP CMD CFG failed\n",
+ __func__);
+ }
+ break;
+ }
+ case SND_AUDIOCODEC_EAC3: {
+ char params_value[18*2*sizeof(int)];
+ int *params_value_data = (int *)params_value;
+ /* 36 is the max param length for ddp */
+ int i;
+ struct snd_dec_ddp *ddp =
+ &compr->info.codec_param.codec.options.ddp;
+ int params_length = ddp->params_length*sizeof(int);
+ pr_debug("SND_AUDIOCODEC_EAC3\n");
+ compr->codec = FORMAT_EAC3;
+ if (copy_from_user(params_value, (void *)ddp->params,
+ params_length))
+ pr_err("%s: ERROR: copy ddp params value\n",
+ __func__);
+ pr_debug("params_length: %d\n", ddp->params_length);
+ for (i = 0; i < ddp->params_length; i++)
+ pr_debug("params_value[%d]: %x\n", i,
+ params_value_data[i]);
+ for (i = 0; i < ddp->params_length/2; i++) {
+ ddp->params_id[i] = params_value_data[2*i];
+ ddp->params_value[i] = params_value_data[2*i+1];
+ }
+ if (atomic_read(&prtd->start)) {
+ rc = msm_compr_send_ddp_cfg(prtd->audio_client,
+ ddp);
+ if (rc < 0)
+ pr_err("%s: DDP CMD CFG failed\n",
+ __func__);
+ }
+ break;
+ }
default:
pr_debug("FORMAT_LINEAR_PCM\n");
compr->codec = FORMAT_LINEAR_PCM;
diff --git a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
index 5b18311..c08e164 100644
--- a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
@@ -941,12 +941,13 @@
static struct snd_soc_dai_driver msm_dai_q6_slimbus_1_rx_dai = {
.playback = {
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000,
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_192000,
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
.channels_min = 1,
.channels_max = 2,
.rate_min = 8000,
- .rate_max = 96000,
+ .rate_max = 192000,
},
.ops = &msm_dai_q6_ops,
.probe = msm_dai_q6_dai_probe,
diff --git a/sound/soc/msm/qdsp6v2/msm-dolby-dap-config.c b/sound/soc/msm/qdsp6v2/msm-dolby-dap-config.c
new file mode 100644
index 0000000..b43c3bd
--- /dev/null
+++ b/sound/soc/msm/qdsp6v2/msm-dolby-dap-config.c
@@ -0,0 +1,707 @@
+/* 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/init.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/platform_device.h>
+#include <linux/bitops.h>
+#include <linux/mutex.h>
+#include <linux/of_device.h>
+#include <linux/slab.h>
+#include <sound/core.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/pcm.h>
+#include <sound/initval.h>
+#include <sound/control.h>
+#include <sound/q6adm-v2.h>
+#include <sound/q6asm-v2.h>
+#include <sound/q6afe-v2.h>
+
+#include "msm-dolby-dap-config.h"
+
+/* dolby endp based parameters */
+struct dolby_dap_endp_params_s {
+ int device;
+ int device_ch_caps;
+ int dap_device;
+ int params_id[DOLBY_NUM_ENDP_DEPENDENT_PARAMS];
+ int params_len[DOLBY_NUM_ENDP_DEPENDENT_PARAMS];
+ int params_offset[DOLBY_NUM_ENDP_DEPENDENT_PARAMS];
+ int params_val[DOLBY_ENDDEP_PARAM_LENGTH];
+};
+
+const struct dolby_dap_endp_params_s
+ dolby_dap_endp_params[NUM_DOLBY_ENDP_DEVICE] = {
+ {EARPIECE, 2, DOLBY_ENDP_EXT_SPEAKERS,
+ {DOLBY_PARAM_ID_DVLO}, {DOLBY_ENDDEP_PARAM_DVLO_LENGTH},
+ {DOLBY_ENDDEP_PARAM_DVLO_OFFSET}, {-320} },
+ {SPEAKER, 2, DOLBY_ENDP_INT_SPEAKERS,
+ {DOLBY_PARAM_ID_DVLO}, {DOLBY_ENDDEP_PARAM_DVLO_LENGTH},
+ {DOLBY_ENDDEP_PARAM_DVLO_OFFSET}, {-320} },
+ {WIRED_HEADSET, 2, DOLBY_ENDP_HEADPHONES,
+ {DOLBY_PARAM_ID_DVLO}, {DOLBY_ENDDEP_PARAM_DVLO_LENGTH},
+ {DOLBY_ENDDEP_PARAM_DVLO_OFFSET}, {-320} },
+ {WIRED_HEADPHONE, 2, DOLBY_ENDP_HEADPHONES,
+ {DOLBY_PARAM_ID_DVLO}, {DOLBY_ENDDEP_PARAM_DVLO_LENGTH},
+ {DOLBY_ENDDEP_PARAM_DVLO_OFFSET}, {-320} },
+ {BLUETOOTH_SCO, 2, DOLBY_ENDP_EXT_SPEAKERS,
+ {DOLBY_PARAM_ID_DVLO}, {DOLBY_ENDDEP_PARAM_DVLO_LENGTH},
+ {DOLBY_ENDDEP_PARAM_DVLO_OFFSET}, {-320} },
+ {BLUETOOTH_SCO_HEADSET, 2, DOLBY_ENDP_EXT_SPEAKERS,
+ {DOLBY_PARAM_ID_DVLO}, {DOLBY_ENDDEP_PARAM_DVLO_LENGTH},
+ {DOLBY_ENDDEP_PARAM_DVLO_OFFSET}, {-320} },
+ {BLUETOOTH_SCO_CARKIT, 2, DOLBY_ENDP_EXT_SPEAKERS,
+ {DOLBY_PARAM_ID_DVLO}, {DOLBY_ENDDEP_PARAM_DVLO_LENGTH},
+ {DOLBY_ENDDEP_PARAM_DVLO_OFFSET}, {-320} },
+ {BLUETOOTH_A2DP, 2, DOLBY_ENDP_EXT_SPEAKERS,
+ {DOLBY_PARAM_ID_DVLO}, {DOLBY_ENDDEP_PARAM_DVLO_LENGTH},
+ {DOLBY_ENDDEP_PARAM_DVLO_OFFSET}, {-320} },
+ {BLUETOOTH_A2DP_HEADPHONES, 2, DOLBY_ENDP_HEADPHONES,
+ {DOLBY_PARAM_ID_DVLO}, {DOLBY_ENDDEP_PARAM_DVLO_LENGTH},
+ {DOLBY_ENDDEP_PARAM_DVLO_OFFSET}, {-320} },
+ {BLUETOOTH_A2DP_SPEAKER, 2, DOLBY_ENDP_EXT_SPEAKERS,
+ {DOLBY_PARAM_ID_DVLO}, {DOLBY_ENDDEP_PARAM_DVLO_LENGTH},
+ {DOLBY_ENDDEP_PARAM_DVLO_OFFSET}, {-320} },
+ {AUX_DIGITAL, 2, DOLBY_ENDP_HDMI,
+ {DOLBY_PARAM_ID_DVLO}, {DOLBY_ENDDEP_PARAM_DVLO_LENGTH},
+ {DOLBY_ENDDEP_PARAM_DVLO_OFFSET}, {-640} },
+ {AUX_DIGITAL, 6, DOLBY_ENDP_HDMI,
+ {DOLBY_PARAM_ID_DVLO}, {DOLBY_ENDDEP_PARAM_DVLO_LENGTH},
+ {DOLBY_ENDDEP_PARAM_DVLO_OFFSET}, {-640} },
+ {AUX_DIGITAL, 8, DOLBY_ENDP_HDMI,
+ {DOLBY_PARAM_ID_DVLO}, {DOLBY_ENDDEP_PARAM_DVLO_LENGTH},
+ {DOLBY_ENDDEP_PARAM_DVLO_OFFSET}, {-640} },
+ {ANLG_DOCK_HEADSET, 2, DOLBY_ENDP_HEADPHONES,
+ {DOLBY_PARAM_ID_DVLO}, {DOLBY_ENDDEP_PARAM_DVLO_LENGTH},
+ {DOLBY_ENDDEP_PARAM_DVLO_OFFSET}, {-320} },
+ {DGTL_DOCK_HEADSET, 2, DOLBY_ENDP_HEADPHONES,
+ {DOLBY_PARAM_ID_DVLO}, {DOLBY_ENDDEP_PARAM_DVLO_LENGTH},
+ {DOLBY_ENDDEP_PARAM_DVLO_OFFSET}, {-320} },
+ {USB_ACCESSORY, 2, DOLBY_ENDP_EXT_SPEAKERS,
+ {DOLBY_PARAM_ID_DVLO}, {DOLBY_ENDDEP_PARAM_DVLO_LENGTH},
+ {DOLBY_ENDDEP_PARAM_DVLO_OFFSET}, {-320} },
+ {USB_DEVICE, 2, DOLBY_ENDP_EXT_SPEAKERS,
+ {DOLBY_PARAM_ID_DVLO}, {DOLBY_ENDDEP_PARAM_DVLO_LENGTH},
+ {DOLBY_ENDDEP_PARAM_DVLO_OFFSET}, {-320} },
+ {REMOTE_SUBMIX, 2, DOLBY_ENDP_EXT_SPEAKERS,
+ {DOLBY_PARAM_ID_DVLO}, {DOLBY_ENDDEP_PARAM_DVLO_LENGTH},
+ {DOLBY_ENDDEP_PARAM_DVLO_OFFSET}, {-320} },
+ {ANC_HEADSET, 2, DOLBY_ENDP_HEADPHONES,
+ {DOLBY_PARAM_ID_DVLO}, {DOLBY_ENDDEP_PARAM_DVLO_LENGTH},
+ {DOLBY_ENDDEP_PARAM_DVLO_OFFSET}, {-320} },
+ {ANC_HEADPHONE, 2, DOLBY_ENDP_HEADPHONES,
+ {DOLBY_PARAM_ID_DVLO}, {DOLBY_ENDDEP_PARAM_DVLO_LENGTH},
+ {DOLBY_ENDDEP_PARAM_DVLO_OFFSET}, {-320} },
+ {PROXY, 2, DOLBY_ENDP_EXT_SPEAKERS,
+ {DOLBY_PARAM_ID_DVLO}, {DOLBY_ENDDEP_PARAM_DVLO_LENGTH},
+ {DOLBY_ENDDEP_PARAM_DVLO_OFFSET}, {-320} },
+ {FM, 2, DOLBY_ENDP_EXT_SPEAKERS,
+ {DOLBY_PARAM_ID_DVLO}, {DOLBY_ENDDEP_PARAM_DVLO_LENGTH},
+ {DOLBY_ENDDEP_PARAM_DVLO_OFFSET}, {-320} },
+ {FM_TX, 2, DOLBY_ENDP_EXT_SPEAKERS,
+ {DOLBY_PARAM_ID_DVLO}, {DOLBY_ENDDEP_PARAM_DVLO_LENGTH},
+ {DOLBY_ENDDEP_PARAM_DVLO_OFFSET}, {-320} },
+};
+
+/* dolby param ids to/from dsp */
+static uint32_t dolby_dap_params_id[ALL_DOLBY_PARAMS] = {
+ DOLBY_PARAM_ID_VDHE, DOLBY_PARAM_ID_VSPE, DOLBY_PARAM_ID_DSSF,
+ DOLBY_PARAM_ID_DVLI, DOLBY_PARAM_ID_DVLO, DOLBY_PARAM_ID_DVLE,
+ DOLBY_PARAM_ID_DVMC, DOLBY_PARAM_ID_DVME, DOLBY_PARAM_ID_IENB,
+ DOLBY_PARAM_ID_IEBF, DOLBY_PARAM_ID_IEON, DOLBY_PARAM_ID_DEON,
+ DOLBY_PARAM_ID_NGON, DOLBY_PARAM_ID_GEON, DOLBY_PARAM_ID_GENB,
+ DOLBY_PARAM_ID_GEBF, DOLBY_PARAM_ID_AONB, DOLBY_PARAM_ID_AOBF,
+ DOLBY_PARAM_ID_AOBG, DOLBY_PARAM_ID_AOON, DOLBY_PARAM_ID_ARNB,
+ DOLBY_PARAM_ID_ARBF, DOLBY_PARAM_ID_PLB, DOLBY_PARAM_ID_PLMD,
+ DOLBY_PARAM_ID_DHSB, DOLBY_PARAM_ID_DHRG, DOLBY_PARAM_ID_DSSB,
+ DOLBY_PARAM_ID_DSSA, DOLBY_PARAM_ID_DVLA, DOLBY_PARAM_ID_IEBT,
+ DOLBY_PARAM_ID_IEA, DOLBY_PARAM_ID_DEA, DOLBY_PARAM_ID_DED,
+ DOLBY_PARAM_ID_GEBG, DOLBY_PARAM_ID_AOCC, DOLBY_PARAM_ID_ARBI,
+ DOLBY_PARAM_ID_ARBL, DOLBY_PARAM_ID_ARBH, DOLBY_PARAM_ID_AROD,
+ DOLBY_PARAM_ID_ARTP, DOLBY_PARAM_ID_VMON, DOLBY_PARAM_ID_VMB,
+ DOLBY_PARAM_ID_VCNB, DOLBY_PARAM_ID_VCBF, DOLBY_PARAM_ID_PREG,
+ DOLBY_PARAM_ID_VEN, DOLBY_PARAM_ID_PSTG, DOLBY_COMMIT_ALL_TO_DSP,
+ DOLBY_COMMIT_TO_DSP, DOLBY_USE_CACHE, DOLBY_AUTO_ENDP,
+ DOLBY_AUTO_ENDDEP_PARAMS
+};
+
+/* modifed state: 0x00000000 - Not updated
+* > 0x00000000 && < 0x00010000
+* Updated and not commited to DSP
+* 0x00010001 - Updated and commited to DSP
+* > 0x00010001 - Modified the commited value
+*/
+static int dolby_dap_params_modified[MAX_DOLBY_PARAMS] = { 0 };
+/* param offset */
+static uint32_t dolby_dap_params_offset[MAX_DOLBY_PARAMS] = {
+ DOLBY_PARAM_VDHE_OFFSET, DOLBY_PARAM_VSPE_OFFSET,
+ DOLBY_PARAM_DSSF_OFFSET, DOLBY_PARAM_DVLI_OFFSET,
+ DOLBY_PARAM_DVLO_OFFSET, DOLBY_PARAM_DVLE_OFFSET,
+ DOLBY_PARAM_DVMC_OFFSET, DOLBY_PARAM_DVME_OFFSET,
+ DOLBY_PARAM_IENB_OFFSET, DOLBY_PARAM_IEBF_OFFSET,
+ DOLBY_PARAM_IEON_OFFSET, DOLBY_PARAM_DEON_OFFSET,
+ DOLBY_PARAM_NGON_OFFSET, DOLBY_PARAM_GEON_OFFSET,
+ DOLBY_PARAM_GENB_OFFSET, DOLBY_PARAM_GEBF_OFFSET,
+ DOLBY_PARAM_AONB_OFFSET, DOLBY_PARAM_AOBF_OFFSET,
+ DOLBY_PARAM_AOBG_OFFSET, DOLBY_PARAM_AOON_OFFSET,
+ DOLBY_PARAM_ARNB_OFFSET, DOLBY_PARAM_ARBF_OFFSET,
+ DOLBY_PARAM_PLB_OFFSET, DOLBY_PARAM_PLMD_OFFSET,
+ DOLBY_PARAM_DHSB_OFFSET, DOLBY_PARAM_DHRG_OFFSET,
+ DOLBY_PARAM_DSSB_OFFSET, DOLBY_PARAM_DSSA_OFFSET,
+ DOLBY_PARAM_DVLA_OFFSET, DOLBY_PARAM_IEBT_OFFSET,
+ DOLBY_PARAM_IEA_OFFSET, DOLBY_PARAM_DEA_OFFSET,
+ DOLBY_PARAM_DED_OFFSET, DOLBY_PARAM_GEBG_OFFSET,
+ DOLBY_PARAM_AOCC_OFFSET, DOLBY_PARAM_ARBI_OFFSET,
+ DOLBY_PARAM_ARBL_OFFSET, DOLBY_PARAM_ARBH_OFFSET,
+ DOLBY_PARAM_AROD_OFFSET, DOLBY_PARAM_ARTP_OFFSET,
+ DOLBY_PARAM_VMON_OFFSET, DOLBY_PARAM_VMB_OFFSET,
+ DOLBY_PARAM_VCNB_OFFSET, DOLBY_PARAM_VCBF_OFFSET,
+ DOLBY_PARAM_PREG_OFFSET, DOLBY_PARAM_VEN_OFFSET,
+ DOLBY_PARAM_PSTG_OFFSET
+};
+/* param_length */
+static uint32_t dolby_dap_params_length[MAX_DOLBY_PARAMS] = {
+ DOLBY_PARAM_VDHE_LENGTH, DOLBY_PARAM_VSPE_LENGTH,
+ DOLBY_PARAM_DSSF_LENGTH, DOLBY_PARAM_DVLI_LENGTH,
+ DOLBY_PARAM_DVLO_LENGTH, DOLBY_PARAM_DVLE_LENGTH,
+ DOLBY_PARAM_DVMC_LENGTH, DOLBY_PARAM_DVME_LENGTH,
+ DOLBY_PARAM_IENB_LENGTH, DOLBY_PARAM_IEBF_LENGTH,
+ DOLBY_PARAM_IEON_LENGTH, DOLBY_PARAM_DEON_LENGTH,
+ DOLBY_PARAM_NGON_LENGTH, DOLBY_PARAM_GEON_LENGTH,
+ DOLBY_PARAM_GENB_LENGTH, DOLBY_PARAM_GEBF_LENGTH,
+ DOLBY_PARAM_AONB_LENGTH, DOLBY_PARAM_AOBF_LENGTH,
+ DOLBY_PARAM_AOBG_LENGTH, DOLBY_PARAM_AOON_LENGTH,
+ DOLBY_PARAM_ARNB_LENGTH, DOLBY_PARAM_ARBF_LENGTH,
+ DOLBY_PARAM_PLB_LENGTH, DOLBY_PARAM_PLMD_LENGTH,
+ DOLBY_PARAM_DHSB_LENGTH, DOLBY_PARAM_DHRG_LENGTH,
+ DOLBY_PARAM_DSSB_LENGTH, DOLBY_PARAM_DSSA_LENGTH,
+ DOLBY_PARAM_DVLA_LENGTH, DOLBY_PARAM_IEBT_LENGTH,
+ DOLBY_PARAM_IEA_LENGTH, DOLBY_PARAM_DEA_LENGTH,
+ DOLBY_PARAM_DED_LENGTH, DOLBY_PARAM_GEBG_LENGTH,
+ DOLBY_PARAM_AOCC_LENGTH, DOLBY_PARAM_ARBI_LENGTH,
+ DOLBY_PARAM_ARBL_LENGTH, DOLBY_PARAM_ARBH_LENGTH,
+ DOLBY_PARAM_AROD_LENGTH, DOLBY_PARAM_ARTP_LENGTH,
+ DOLBY_PARAM_VMON_LENGTH, DOLBY_PARAM_VMB_LENGTH,
+ DOLBY_PARAM_VCNB_LENGTH, DOLBY_PARAM_VCBF_LENGTH,
+ DOLBY_PARAM_PREG_LENGTH, DOLBY_PARAM_VEN_LENGTH,
+ DOLBY_PARAM_PSTG_LENGTH
+};
+
+/* param_value */
+static uint32_t dolby_dap_params_value[TOTAL_LENGTH_DOLBY_PARAM] = {0};
+
+struct dolby_dap_params_get_s {
+ int32_t port_id;
+ uint32_t device_id;
+ uint32_t param_id;
+ uint32_t offset;
+ uint32_t length;
+};
+
+struct dolby_dap_params_states_s {
+ bool use_cache;
+ bool auto_endp;
+ bool enddep_params;
+ int port_id;
+ int port_open_count;
+ int port_ids_dolby_can_be_enabled;
+ int device;
+};
+
+static struct dolby_dap_params_get_s dolby_dap_params_get = {-1, DEVICE_OUT_ALL,
+ 0, 0, 0};
+static struct dolby_dap_params_states_s dolby_dap_params_states = { true, true,
+ true, DOLBY_INVALID_PORT_ID,
+ 0, DEVICE_OUT_ALL, 0 };
+/*
+port_ids_dolby_can_be_enabled is set to 0x7FFFFFFF.
+this needs to be removed after interface validation
+*/
+
+static int map_device_to_dolby_endpoint(int device)
+{
+ int i, dolby_dap_device = DOLBY_ENDP_INT_SPEAKERS;
+ for (i = 0; i < NUM_DOLBY_ENDP_DEVICE; i++) {
+ if (dolby_dap_endp_params[i].device == device) {
+ dolby_dap_device = dolby_dap_endp_params[i].dap_device;
+ break;
+ }
+ }
+ /* default the endpoint to speaker if corresponding device entry */
+ /* not found */
+ if (i >= NUM_DOLBY_ENDP_DEVICE)
+ dolby_dap_params_states.device = SPEAKER;
+ return dolby_dap_device;
+}
+
+static int dolby_dap_send_end_point(int port_id)
+{
+ int rc = 0;
+ char *params_value;
+ int *update_params_value;
+ uint32_t params_length = (DOLBY_PARAM_INT_ENDP_LENGTH +
+ DOLBY_PARAM_PAYLOAD_SIZE) * sizeof(uint32_t);
+
+ pr_debug("%s\n", __func__);
+ params_value = kzalloc(params_length, GFP_KERNEL);
+ if (!params_value) {
+ pr_err("%s, params memory alloc failed", __func__);
+ return -ENOMEM;
+ }
+ update_params_value = (int *)params_value;
+ *update_params_value++ = DOLBY_BUNDLE_MODULE_ID;
+ *update_params_value++ = DOLBY_PARAM_ID_INIT_ENDP;
+ *update_params_value++ = DOLBY_PARAM_INT_ENDP_LENGTH * sizeof(uint32_t);
+ *update_params_value++ =
+ map_device_to_dolby_endpoint(dolby_dap_params_states.device);
+ rc = adm_dolby_dap_send_params(port_id, params_value, params_length);
+ if (rc) {
+ pr_err("%s: send dolby params failed\n", __func__);
+ rc = -EINVAL;
+ }
+ kfree(params_value);
+ return rc;
+}
+
+static int dolby_dap_send_enddep_params(int port_id, int device_channels)
+{
+ int i, j, rc = 0, idx, offset;
+ char *params_value;
+ int *update_params_value;
+ uint32_t params_length = (DOLBY_ENDDEP_PARAM_LENGTH +
+ DOLBY_NUM_ENDP_DEPENDENT_PARAMS *
+ DOLBY_PARAM_PAYLOAD_SIZE) *
+ sizeof(uint32_t);
+
+ pr_debug("%s\n", __func__);
+ params_value = kzalloc(params_length, GFP_KERNEL);
+ if (!params_value) {
+ pr_err("%s, params memory alloc failed", __func__);
+ return -ENOMEM;
+ }
+ update_params_value = (int *)params_value;
+ for (idx = 0; idx < NUM_DOLBY_ENDP_DEVICE; idx++) {
+ if (dolby_dap_endp_params[idx].device ==
+ dolby_dap_params_states.device) {
+ if (dolby_dap_params_states.device == AUX_DIGITAL) {
+ if (dolby_dap_endp_params[idx].device_ch_caps ==
+ device_channels)
+ break;
+ } else {
+ break;
+ }
+ }
+ }
+ if (idx >= NUM_DOLBY_ENDP_DEVICE) {
+ pr_err("%s: device is not set accordingly\n", __func__);
+ return -EINVAL;
+ }
+ for (i = 0; i < DOLBY_ENDDEP_PARAM_LENGTH; i++) {
+ *update_params_value++ = DOLBY_BUNDLE_MODULE_ID;
+ *update_params_value++ =
+ dolby_dap_endp_params[idx].params_id[i];
+ *update_params_value++ =
+ dolby_dap_endp_params[idx].params_len[i] *
+ sizeof(uint32_t);
+ offset = dolby_dap_endp_params[idx].params_offset[i];
+ for (j = 0; j < dolby_dap_endp_params[idx].params_len[i]; j++)
+ *update_params_value++ =
+ dolby_dap_endp_params[idx].params_val[offset+j];
+ }
+ rc = adm_dolby_dap_send_params(port_id, params_value, params_length);
+ if (rc) {
+ pr_err("%s: send dolby params failed\n", __func__);
+ rc = -EINVAL;
+ }
+ kfree(params_value);
+ return rc;
+}
+
+static int dolby_dap_send_cached_params(int port_id, int commit)
+{
+ char *params_value;
+ int *update_params_value, rc = 0;
+ uint32_t index_offset, i, j;
+ uint32_t params_length = (TOTAL_LENGTH_DOLBY_PARAM +
+ MAX_DOLBY_PARAMS * DOLBY_PARAM_PAYLOAD_SIZE) *
+ sizeof(uint32_t);
+
+ params_value = kzalloc(params_length, GFP_KERNEL);
+ if (!params_value) {
+ pr_err("%s, params memory alloc failed\n", __func__);
+ return -ENOMEM;
+ }
+ update_params_value = (int *)params_value;
+ params_length = 0;
+ for (i = 0; i < MAX_DOLBY_PARAMS; i++) {
+ if ((dolby_dap_params_modified[i] == 0) ||
+ ((commit) &&
+ ((dolby_dap_params_modified[i] & 0x00010000) &&
+ ((dolby_dap_params_modified[i] & 0x0000FFFF) <= 1))))
+ continue;
+ *update_params_value++ = DOLBY_BUNDLE_MODULE_ID;
+ *update_params_value++ = dolby_dap_params_id[i];
+ *update_params_value++ = dolby_dap_params_length[i] *
+ sizeof(uint32_t);
+ index_offset = dolby_dap_params_offset[i];
+ for (j = 0; j < dolby_dap_params_length[i]; j++)
+ *update_params_value++ =
+ dolby_dap_params_value[index_offset+j];
+ params_length += (DOLBY_PARAM_PAYLOAD_SIZE +
+ dolby_dap_params_length[i]) * sizeof(uint32_t);
+ }
+ pr_debug("%s, valid param length: %d", __func__, params_length);
+ if (params_length) {
+ rc = adm_dolby_dap_send_params(port_id, params_value,
+ params_length);
+ if (rc) {
+ pr_err("%s: send dolby params failed\n", __func__);
+ return -EINVAL;
+ }
+ for (i = 0; i < MAX_DOLBY_PARAMS; i++) {
+ if ((dolby_dap_params_modified[i] == 0) ||
+ ((commit) &&
+ ((dolby_dap_params_modified[i] & 0x00010000) &&
+ ((dolby_dap_params_modified[i] & 0x0000FFFF) <= 1))
+ ))
+ continue;
+ dolby_dap_params_modified[i] = 0x00010001;
+ }
+ }
+ kfree(params_value);
+ return 0;
+}
+
+int dolby_dap_init(int port_id, int channels)
+{
+ int ret = 0;
+ if ((port_id != DOLBY_INVALID_PORT_ID) &&
+ (port_id &
+ dolby_dap_params_states.port_ids_dolby_can_be_enabled)) {
+ dolby_dap_params_states.port_id = port_id;
+ dolby_dap_params_states.port_open_count++;
+ if (dolby_dap_params_states.auto_endp) {
+ ret = dolby_dap_send_end_point(port_id);
+ if (ret) {
+ pr_err("%s: err sending endppoint\n", __func__);
+ return ret;
+ }
+ }
+ if (dolby_dap_params_states.use_cache) {
+ ret = dolby_dap_send_cached_params(port_id, 0);
+ if (ret) {
+ pr_err("%s: err sending cached params\n",
+ __func__);
+ return ret;
+ }
+ }
+ if (dolby_dap_params_states.enddep_params) {
+ dolby_dap_send_enddep_params(port_id,
+ channels);
+ if (ret) {
+ pr_err("%s: err sending endp dependent params\n",
+ __func__);
+ return ret;
+ }
+ }
+ }
+ return ret;
+}
+
+void dolby_dap_deinit(int port_id)
+{
+ dolby_dap_params_states.port_open_count--;
+ if ((dolby_dap_params_states.port_id == port_id) &&
+ (!dolby_dap_params_states.port_open_count))
+ dolby_dap_params_states.port_id = DOLBY_INVALID_PORT_ID;
+}
+
+static int map_device_to_port_id(int device)
+{
+ int port_id = SLIMBUS_0_RX;
+ device = DEVICE_OUT_ALL;
+ /*update the device when single stream to multiple device is handled*/
+ if (device == DEVICE_OUT_ALL) {
+ port_id = PRIMARY_I2S_RX | SLIMBUS_0_RX | HDMI_RX |
+ INT_BT_SCO_RX | INT_FM_RX |
+ RT_PROXY_PORT_001_RX | PCM_RX |
+ MI2S_RX | SECONDARY_I2S_RX |
+ SLIMBUS_1_RX | SLIMBUS_4_RX | SLIMBUS_3_RX |
+ AFE_PORT_ID_SECONDARY_MI2S_RX;
+ } else {
+ /* update port_id based on the device */
+ }
+ return port_id;
+}
+
+int msm_routing_get_dolby_dap_param_to_set_control(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol) {
+ /* not used while setting the parameters */
+ return 0;
+}
+
+int msm_routing_put_dolby_dap_param_to_set_control(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol) {
+ int rc = 0;
+ uint32_t idx, j;
+ uint32_t device = ucontrol->value.integer.value[0];
+ uint32_t param_id = ucontrol->value.integer.value[1];
+ uint32_t offset = ucontrol->value.integer.value[2];
+ uint32_t length = ucontrol->value.integer.value[3];
+
+ int port_id = dolby_dap_params_states.port_id;
+
+ dolby_dap_params_states.port_ids_dolby_can_be_enabled =
+ map_device_to_port_id(device);
+ for (idx = 0; idx < ALL_DOLBY_PARAMS; idx++) {
+ /*paramid from user space*/
+ if (param_id == dolby_dap_params_id[idx])
+ break;
+ }
+ if (idx > ALL_DOLBY_PARAMS-1) {
+ pr_err("%s: invalid param id 0x%x to set\n", __func__,
+ param_id);
+ return -EINVAL;
+ }
+ switch (idx) {
+ case DOLBY_COMMIT_ALL_IDX: {
+ /* COMIIT ALL: Send all parameters to DSP */
+ pr_debug("%s: COMMIT_ALL recvd\n", __func__);
+ if (port_id != DOLBY_INVALID_PORT_ID)
+ rc = dolby_dap_send_cached_params(port_id, 0);
+ }
+ break;
+ case DOLBY_COMMIT_IDX: {
+ pr_debug("%s: COMMIT recvd\n", __func__);
+ /* COMMIT: Send only modified paramters to DSP */
+ if (port_id != DOLBY_INVALID_PORT_ID)
+ rc = dolby_dap_send_cached_params(port_id, 1);
+ }
+ break;
+ case DOLBY_USE_CACHE_IDX: {
+ pr_debug("%s: USE CACHE recvd val: %ld\n", __func__,
+ ucontrol->value.integer.value[4]);
+ dolby_dap_params_states.use_cache =
+ ucontrol->value.integer.value[4];
+ }
+ break;
+ case DOLBY_AUTO_ENDP_IDX: {
+ pr_debug("%s: AUTO_ENDP recvd val: %ld\n", __func__,
+ ucontrol->value.integer.value[4]);
+ dolby_dap_params_states.auto_endp =
+ ucontrol->value.integer.value[4];
+ }
+ break;
+ case DOLBY_AUTO_ENDDEP_IDX: {
+ pr_debug("%s: USE_ENDDEP_PARAMS recvd val: %ld\n",
+ __func__, ucontrol->value.integer.value[4]);
+ dolby_dap_params_states.enddep_params =
+ ucontrol->value.integer.value[4];
+ }
+ break;
+ default: {
+ /* cache the parameters */
+ dolby_dap_params_modified[idx] += 1;
+ dolby_dap_params_length[idx] = length;
+ pr_debug("%s: param recvd deviceId=0x%x paramId=0x%x offset=%d length=%d\n",
+ __func__, device, param_id, offset, length);
+ for (j = 0; j < length; j++) {
+ dolby_dap_params_value[
+ dolby_dap_params_offset[idx] +
+ offset + j]
+ = ucontrol->value.integer.value[4+j];
+ pr_debug("value[%d]: %ld\n", j,
+ ucontrol->value.integer.value[4+j]);
+ }
+ }
+ }
+
+ return rc;
+}
+
+int msm_routing_get_dolby_dap_param_to_get_control(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol) {
+ int rc = 0, i;
+ char *params_value;
+ int *update_params_value;
+ uint32_t params_length = DOLBY_MAX_LENGTH_INDIVIDUAL_PARAM *
+ sizeof(uint32_t);
+ uint32_t param_payload_len =
+ DOLBY_PARAM_PAYLOAD_SIZE * sizeof(uint32_t);
+ int port_id = dolby_dap_params_states.port_id;
+
+ if (port_id == DOLBY_INVALID_PORT_ID) {
+ pr_err("%s, port_id not set, returning error", __func__);
+ return -EINVAL;
+ }
+ params_value = kzalloc(params_length, GFP_KERNEL);
+ if (!params_value) {
+ pr_err("%s, params memory alloc failed\n", __func__);
+ return -ENOMEM;
+ }
+ if (DOLBY_PARAM_ID_VER == dolby_dap_params_get.param_id) {
+ rc = adm_dolby_dap_get_params(dolby_dap_params_get.port_id,
+ DOLBY_BUNDLE_MODULE_ID,
+ DOLBY_PARAM_ID_VER,
+ params_length +
+ param_payload_len,
+ params_value);
+ } else {
+ for (i = 0; i < MAX_DOLBY_PARAMS; i++)
+ if (dolby_dap_params_id[i] ==
+ dolby_dap_params_get.param_id)
+ break;
+ if (i > MAX_DOLBY_PARAMS-1) {
+ pr_err("%s: invalid param id to set", __func__);
+ rc = -EINVAL;
+ } else {
+ params_length = (dolby_dap_params_length[i] +
+ DOLBY_PARAM_PAYLOAD_SIZE) *
+ sizeof(uint32_t);
+ rc = adm_dolby_dap_get_params(
+ dolby_dap_params_get.port_id,
+ DOLBY_BUNDLE_MODULE_ID,
+ dolby_dap_params_id[i],
+ params_length +
+ param_payload_len,
+ params_value);
+ }
+ }
+ if (rc) {
+ pr_err("%s: get parameters failed\n", __func__);
+ kfree(params_value);
+ rc = -EINVAL;
+ }
+ update_params_value = (int *)params_value;
+ ucontrol->value.integer.value[0] = dolby_dap_params_get.device_id;
+ ucontrol->value.integer.value[1] = dolby_dap_params_get.param_id;
+ ucontrol->value.integer.value[2] = dolby_dap_params_get.offset;
+ ucontrol->value.integer.value[3] = dolby_dap_params_get.length;
+
+ pr_debug("%s: FROM DSP value[0] 0x%x value[1] %d value[2] 0x%x\n",
+ __func__, update_params_value[0],
+ update_params_value[1], update_params_value[2]);
+ for (i = 0; i < dolby_dap_params_get.length; i++) {
+ ucontrol->value.integer.value[DOLBY_PARAM_PAYLOAD_SIZE+i] =
+ update_params_value[i];
+ pr_debug("value[%d]:%d\n", i, update_params_value[i]);
+ }
+ pr_debug("%s: Returning param_id=0x%x offset=%d length=%d\n",
+ __func__, dolby_dap_params_get.param_id,
+ dolby_dap_params_get.offset,
+ dolby_dap_params_get.length);
+ kfree(params_value);
+ return 0;
+}
+
+int msm_routing_put_dolby_dap_param_to_get_control(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol) {
+ dolby_dap_params_get.device_id = ucontrol->value.integer.value[0];
+ dolby_dap_params_get.port_id =
+ (dolby_dap_params_get.device_id == DEVICE_OUT_ALL) ?
+ dolby_dap_params_states.port_id :
+ map_device_to_port_id(dolby_dap_params_get.device_id);
+ dolby_dap_params_get.param_id = ucontrol->value.integer.value[1];
+ dolby_dap_params_get.offset = ucontrol->value.integer.value[2];
+ dolby_dap_params_get.length = ucontrol->value.integer.value[3];
+ pr_debug("%s: param_id=0x%x offset=%d length=%d\n", __func__,
+ dolby_dap_params_get.param_id, dolby_dap_params_get.offset,
+ dolby_dap_params_get.length);
+ return 0;
+}
+
+int msm_routing_get_dolby_dap_param_visualizer_control(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol) {
+ uint32_t length = dolby_dap_params_value[DOLBY_PARAM_VCNB_OFFSET];
+ char *visualizer_data;
+ int i, rc;
+ int *update_visualizer_data;
+ uint32_t offset, params_length =
+ (2*length + DOLBY_VIS_PARAM_HEADER_SIZE)*sizeof(uint32_t);
+ uint32_t param_payload_len =
+ DOLBY_PARAM_PAYLOAD_SIZE * sizeof(uint32_t);
+ int port_id = dolby_dap_params_states.port_id;
+ if (port_id == DOLBY_INVALID_PORT_ID) {
+ pr_err("%s, port_id not set, returning error", __func__);
+ ucontrol->value.integer.value[0] = 0;
+ return -EINVAL;
+ }
+ visualizer_data = kzalloc(params_length, GFP_KERNEL);
+ if (!visualizer_data) {
+ pr_err("%s, params memory alloc failed\n", __func__);
+ return -ENOMEM;
+ }
+ offset = 0;
+ params_length = length * sizeof(uint32_t);
+ rc = adm_dolby_dap_get_params(dolby_dap_params_states.port_id,
+ DOLBY_BUNDLE_MODULE_ID,
+ DOLBY_PARAM_ID_VCBG,
+ params_length + param_payload_len,
+ visualizer_data + offset);
+ if (rc) {
+ pr_err("%s: get parameters failed\n", __func__);
+ kfree(visualizer_data);
+ return -EINVAL;
+ }
+
+ offset = length * sizeof(uint32_t);
+ rc = adm_dolby_dap_get_params(dolby_dap_params_states.port_id,
+ DOLBY_BUNDLE_MODULE_ID,
+ DOLBY_PARAM_ID_VCBE,
+ params_length + param_payload_len,
+ visualizer_data + offset);
+ if (rc) {
+ pr_err("%s: get parameters failed\n", __func__);
+ kfree(visualizer_data);
+ return -EINVAL;
+ }
+
+ ucontrol->value.integer.value[0] = 2*length;
+ pr_debug("%s: visualizer data length %ld\n", __func__,
+ ucontrol->value.integer.value[0]);
+ update_visualizer_data = (int *)visualizer_data;
+ for (i = 0; i < 2*length; i++) {
+ ucontrol->value.integer.value[1+i] = update_visualizer_data[i];
+ pr_debug("value[%d] %d\n", i, update_visualizer_data[i]);
+ }
+ kfree(visualizer_data);
+ return 0;
+}
+
+int msm_routing_put_dolby_dap_param_visualizer_control(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol) {
+ /* not used while getting the visualizer data */
+ return 0;
+}
+
+int msm_routing_get_dolby_dap_endpoint_control(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol) {
+ /* not used while setting the endpoint */
+ return 0;
+}
+
+int msm_routing_put_dolby_dap_endpoint_control(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol) {
+ int device = ucontrol->value.integer.value[0];
+ dolby_dap_params_states.device = device;
+ return 0;
+}
diff --git a/sound/soc/msm/qdsp6v2/msm-dolby-dap-config.h b/sound/soc/msm/qdsp6v2/msm-dolby-dap-config.h
new file mode 100644
index 0000000..58ea36d
--- /dev/null
+++ b/sound/soc/msm/qdsp6v2/msm-dolby-dap-config.h
@@ -0,0 +1,348 @@
+/* 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_DOLBY_DAP_CONFIG_H_
+#define _MSM_DOLBY_DAP_CONFIG_H_
+
+#ifdef CONFIG_DOLBY_DAP
+/* DOLBY DOLBY GUIDS */
+#define DOLBY_ADM_COPP_TOPOLOGY_ID 0x0001033B
+#define DOLBY_BUNDLE_MODULE_ID 0x00010723
+#define DOLBY_VISUALIZER_MODULE_ID 0x0001072B
+
+#define DOLBY_PARAM_ID_VDHE 0x0001074D
+#define DOLBY_PARAM_ID_VSPE 0x00010750
+#define DOLBY_PARAM_ID_DSSF 0x00010753
+#define DOLBY_PARAM_ID_DVLI 0x0001073E
+#define DOLBY_PARAM_ID_DVLO 0x0001073F
+#define DOLBY_PARAM_ID_DVLE 0x0001073C
+#define DOLBY_PARAM_ID_DVMC 0x00010741
+#define DOLBY_PARAM_ID_DVME 0x00010740
+#define DOLBY_PARAM_ID_IENB 0x00010744
+#define DOLBY_PARAM_ID_IEBF 0x00010745
+#define DOLBY_PARAM_ID_IEON 0x00010743
+#define DOLBY_PARAM_ID_DEON 0x00010738
+#define DOLBY_PARAM_ID_NGON 0x00010736
+#define DOLBY_PARAM_ID_GEON 0x00010748
+#define DOLBY_PARAM_ID_GENB 0x00010749
+#define DOLBY_PARAM_ID_GEBF 0x0001074A
+#define DOLBY_PARAM_ID_AONB 0x0001075B
+#define DOLBY_PARAM_ID_AOBF 0x0001075C
+#define DOLBY_PARAM_ID_AOBG 0x0001075D
+#define DOLBY_PARAM_ID_AOON 0x00010759
+#define DOLBY_PARAM_ID_ARNB 0x0001075F
+#define DOLBY_PARAM_ID_ARBF 0x00010760
+#define DOLBY_PARAM_ID_PLB 0x00010768
+#define DOLBY_PARAM_ID_PLMD 0x00010767
+#define DOLBY_PARAM_ID_DHSB 0x0001074E
+#define DOLBY_PARAM_ID_DHRG 0x0001074F
+#define DOLBY_PARAM_ID_DSSB 0x00010751
+#define DOLBY_PARAM_ID_DSSA 0x00010752
+#define DOLBY_PARAM_ID_DVLA 0x0001073D
+#define DOLBY_PARAM_ID_IEBT 0x00010746
+#define DOLBY_PARAM_ID_IEA 0x0001076A
+#define DOLBY_PARAM_ID_DEA 0x00010739
+#define DOLBY_PARAM_ID_DED 0x0001073A
+#define DOLBY_PARAM_ID_GEBG 0x0001074B
+#define DOLBY_PARAM_ID_AOCC 0x0001075A
+#define DOLBY_PARAM_ID_ARBI 0x00010761
+#define DOLBY_PARAM_ID_ARBL 0x00010762
+#define DOLBY_PARAM_ID_ARBH 0x00010763
+#define DOLBY_PARAM_ID_AROD 0x00010764
+#define DOLBY_PARAM_ID_ARTP 0x00010765
+#define DOLBY_PARAM_ID_VMON 0x00010756
+#define DOLBY_PARAM_ID_VMB 0x00010757
+#define DOLBY_PARAM_ID_VCNB 0x00010733
+#define DOLBY_PARAM_ID_VCBF 0x00010734
+#define DOLBY_PARAM_ID_PREG 0x00010728
+#define DOLBY_PARAM_ID_VEN 0x00010732
+#define DOLBY_PARAM_ID_PSTG 0x00010729
+#define DOLBY_PARAM_ID_INIT_ENDP 0x00010727
+
+/* Not Used with Set Param kcontrol, only to query using Get Param */
+#define DOLBY_PARAM_ID_VER 0x00010726
+
+#define DOLBY_PARAM_ID_VCBG 0x00010730
+#define DOLBY_PARAM_ID_VCBE 0x00010731
+
+/* DOLBY DAP control params */
+#define DOLBY_COMMIT_ALL_TO_DSP 0x70000001
+#define DOLBY_COMMIT_TO_DSP 0x70000002
+#define DOLBY_USE_CACHE 0x70000003
+#define DOLBY_AUTO_ENDP 0x70000004
+#define DOLBY_AUTO_ENDDEP_PARAMS 0x70000005
+
+/* DOLBY DAP offsets start */
+#define DOLBY_PARAM_VDHE_LENGTH 1
+#define DOLBY_PARAM_VDHE_OFFSET 0
+#define DOLBY_PARAM_VSPE_LENGTH 1
+#define DOLBY_PARAM_VSPE_OFFSET (DOLBY_PARAM_VDHE_OFFSET + \
+ DOLBY_PARAM_VDHE_LENGTH)
+#define DOLBY_PARAM_DSSF_LENGTH 1
+#define DOLBY_PARAM_DSSF_OFFSET (DOLBY_PARAM_VSPE_OFFSET + \
+ DOLBY_PARAM_VSPE_LENGTH)
+#define DOLBY_PARAM_DVLI_LENGTH 1
+#define DOLBY_PARAM_DVLI_OFFSET (DOLBY_PARAM_DSSF_OFFSET + \
+ DOLBY_PARAM_DSSF_LENGTH)
+#define DOLBY_PARAM_DVLO_LENGTH 1
+#define DOLBY_PARAM_DVLO_OFFSET (DOLBY_PARAM_DVLI_OFFSET + \
+ DOLBY_PARAM_DVLI_LENGTH)
+#define DOLBY_PARAM_DVLE_LENGTH 1
+#define DOLBY_PARAM_DVLE_OFFSET (DOLBY_PARAM_DVLO_OFFSET + \
+ DOLBY_PARAM_DVLO_LENGTH)
+#define DOLBY_PARAM_DVMC_LENGTH 1
+#define DOLBY_PARAM_DVMC_OFFSET (DOLBY_PARAM_DVLE_OFFSET + \
+ DOLBY_PARAM_DVLE_LENGTH)
+#define DOLBY_PARAM_DVME_LENGTH 1
+#define DOLBY_PARAM_DVME_OFFSET (DOLBY_PARAM_DVMC_OFFSET + \
+ DOLBY_PARAM_DVMC_LENGTH)
+#define DOLBY_PARAM_IENB_LENGTH 1
+#define DOLBY_PARAM_IENB_OFFSET (DOLBY_PARAM_DVME_OFFSET + \
+ DOLBY_PARAM_DVME_LENGTH)
+#define DOLBY_PARAM_IEBF_LENGTH 40
+#define DOLBY_PARAM_IEBF_OFFSET (DOLBY_PARAM_IENB_OFFSET + \
+ DOLBY_PARAM_IENB_LENGTH)
+#define DOLBY_PARAM_IEON_LENGTH 1
+#define DOLBY_PARAM_IEON_OFFSET (DOLBY_PARAM_IEBF_OFFSET + \
+ DOLBY_PARAM_IEBF_LENGTH)
+#define DOLBY_PARAM_DEON_LENGTH 1
+#define DOLBY_PARAM_DEON_OFFSET (DOLBY_PARAM_IEON_OFFSET + \
+ DOLBY_PARAM_IEON_LENGTH)
+#define DOLBY_PARAM_NGON_LENGTH 1
+#define DOLBY_PARAM_NGON_OFFSET (DOLBY_PARAM_DEON_OFFSET + \
+ DOLBY_PARAM_DEON_LENGTH)
+#define DOLBY_PARAM_GEON_LENGTH 1
+#define DOLBY_PARAM_GEON_OFFSET (DOLBY_PARAM_NGON_OFFSET + \
+ DOLBY_PARAM_NGON_LENGTH)
+#define DOLBY_PARAM_GENB_LENGTH 1
+#define DOLBY_PARAM_GENB_OFFSET (DOLBY_PARAM_GEON_OFFSET + \
+ DOLBY_PARAM_GEON_LENGTH)
+#define DOLBY_PARAM_GEBF_LENGTH 40
+#define DOLBY_PARAM_GEBF_OFFSET (DOLBY_PARAM_GENB_OFFSET + \
+ DOLBY_PARAM_GENB_LENGTH)
+#define DOLBY_PARAM_AONB_LENGTH 1
+#define DOLBY_PARAM_AONB_OFFSET (DOLBY_PARAM_GEBF_OFFSET + \
+ DOLBY_PARAM_GEBF_LENGTH)
+#define DOLBY_PARAM_AOBF_LENGTH 40
+#define DOLBY_PARAM_AOBF_OFFSET (DOLBY_PARAM_AONB_OFFSET + \
+ DOLBY_PARAM_AONB_LENGTH)
+#define DOLBY_PARAM_AOBG_LENGTH 329
+#define DOLBY_PARAM_AOBG_OFFSET (DOLBY_PARAM_AOBF_OFFSET + \
+ DOLBY_PARAM_AOBF_LENGTH)
+#define DOLBY_PARAM_AOON_LENGTH 1
+#define DOLBY_PARAM_AOON_OFFSET (DOLBY_PARAM_AOBG_OFFSET + \
+ DOLBY_PARAM_AOBG_LENGTH)
+#define DOLBY_PARAM_ARNB_LENGTH 1
+#define DOLBY_PARAM_ARNB_OFFSET (DOLBY_PARAM_AOON_OFFSET + \
+ DOLBY_PARAM_AOON_LENGTH)
+#define DOLBY_PARAM_ARBF_LENGTH 40
+#define DOLBY_PARAM_ARBF_OFFSET (DOLBY_PARAM_ARNB_OFFSET + \
+ DOLBY_PARAM_ARNB_LENGTH)
+#define DOLBY_PARAM_PLB_LENGTH 1
+#define DOLBY_PARAM_PLB_OFFSET (DOLBY_PARAM_ARBF_OFFSET + \
+ DOLBY_PARAM_ARBF_LENGTH)
+#define DOLBY_PARAM_PLMD_LENGTH 1
+#define DOLBY_PARAM_PLMD_OFFSET (DOLBY_PARAM_PLB_OFFSET + \
+ DOLBY_PARAM_PLB_LENGTH)
+#define DOLBY_PARAM_DHSB_LENGTH 1
+#define DOLBY_PARAM_DHSB_OFFSET (DOLBY_PARAM_PLMD_OFFSET + \
+ DOLBY_PARAM_PLMD_LENGTH)
+#define DOLBY_PARAM_DHRG_LENGTH 1
+#define DOLBY_PARAM_DHRG_OFFSET (DOLBY_PARAM_DHSB_OFFSET + \
+ DOLBY_PARAM_DHSB_LENGTH)
+#define DOLBY_PARAM_DSSB_LENGTH 1
+#define DOLBY_PARAM_DSSB_OFFSET (DOLBY_PARAM_DHRG_OFFSET + \
+ DOLBY_PARAM_DHRG_LENGTH)
+#define DOLBY_PARAM_DSSA_LENGTH 1
+#define DOLBY_PARAM_DSSA_OFFSET (DOLBY_PARAM_DSSB_OFFSET + \
+ DOLBY_PARAM_DSSB_LENGTH)
+#define DOLBY_PARAM_DVLA_LENGTH 1
+#define DOLBY_PARAM_DVLA_OFFSET (DOLBY_PARAM_DSSA_OFFSET + \
+ DOLBY_PARAM_DSSA_LENGTH)
+#define DOLBY_PARAM_IEBT_LENGTH 40
+#define DOLBY_PARAM_IEBT_OFFSET (DOLBY_PARAM_DVLA_OFFSET + \
+ DOLBY_PARAM_DVLA_LENGTH)
+#define DOLBY_PARAM_IEA_LENGTH 1
+#define DOLBY_PARAM_IEA_OFFSET (DOLBY_PARAM_IEBT_OFFSET + \
+ DOLBY_PARAM_IEBT_LENGTH)
+#define DOLBY_PARAM_DEA_LENGTH 1
+#define DOLBY_PARAM_DEA_OFFSET (DOLBY_PARAM_IEA_OFFSET + \
+ DOLBY_PARAM_IEA_LENGTH)
+#define DOLBY_PARAM_DED_LENGTH 1
+#define DOLBY_PARAM_DED_OFFSET (DOLBY_PARAM_DEA_OFFSET + \
+ DOLBY_PARAM_DEA_LENGTH)
+#define DOLBY_PARAM_GEBG_LENGTH 40
+#define DOLBY_PARAM_GEBG_OFFSET (DOLBY_PARAM_DED_OFFSET + \
+ DOLBY_PARAM_DED_LENGTH)
+#define DOLBY_PARAM_AOCC_LENGTH 1
+#define DOLBY_PARAM_AOCC_OFFSET (DOLBY_PARAM_GEBG_OFFSET + \
+ DOLBY_PARAM_GEBG_LENGTH)
+#define DOLBY_PARAM_ARBI_LENGTH 40
+#define DOLBY_PARAM_ARBI_OFFSET (DOLBY_PARAM_AOCC_OFFSET + \
+ DOLBY_PARAM_AOCC_LENGTH)
+#define DOLBY_PARAM_ARBL_LENGTH 40
+#define DOLBY_PARAM_ARBL_OFFSET (DOLBY_PARAM_ARBI_OFFSET + \
+ DOLBY_PARAM_ARBI_LENGTH)
+#define DOLBY_PARAM_ARBH_LENGTH 40
+#define DOLBY_PARAM_ARBH_OFFSET (DOLBY_PARAM_ARBL_OFFSET + \
+ DOLBY_PARAM_ARBL_LENGTH)
+#define DOLBY_PARAM_AROD_LENGTH 1
+#define DOLBY_PARAM_AROD_OFFSET (DOLBY_PARAM_ARBH_OFFSET + \
+ DOLBY_PARAM_ARBH_LENGTH)
+#define DOLBY_PARAM_ARTP_LENGTH 1
+#define DOLBY_PARAM_ARTP_OFFSET (DOLBY_PARAM_AROD_OFFSET + \
+ DOLBY_PARAM_AROD_LENGTH)
+#define DOLBY_PARAM_VMON_LENGTH 1
+#define DOLBY_PARAM_VMON_OFFSET (DOLBY_PARAM_ARTP_OFFSET + \
+ DOLBY_PARAM_ARTP_LENGTH)
+#define DOLBY_PARAM_VMB_LENGTH 1
+#define DOLBY_PARAM_VMB_OFFSET (DOLBY_PARAM_VMON_OFFSET + \
+ DOLBY_PARAM_VMON_LENGTH)
+#define DOLBY_PARAM_VCNB_LENGTH 1
+#define DOLBY_PARAM_VCNB_OFFSET (DOLBY_PARAM_VMB_OFFSET + \
+ DOLBY_PARAM_VMB_LENGTH)
+#define DOLBY_PARAM_VCBF_LENGTH 20
+#define DOLBY_PARAM_VCBF_OFFSET (DOLBY_PARAM_VCNB_OFFSET + \
+ DOLBY_PARAM_VCNB_LENGTH)
+#define DOLBY_PARAM_PREG_LENGTH 1
+#define DOLBY_PARAM_PREG_OFFSET (DOLBY_PARAM_VCBF_OFFSET + \
+ DOLBY_PARAM_VCBF_LENGTH)
+#define DOLBY_PARAM_VEN_LENGTH 1
+#define DOLBY_PARAM_VEN_OFFSET (DOLBY_PARAM_PREG_OFFSET + \
+ DOLBY_PARAM_PREG_LENGTH)
+#define DOLBY_PARAM_PSTG_LENGTH 1
+#define DOLBY_PARAM_PSTG_OFFSET (DOLBY_PARAM_VEN_OFFSET + \
+ DOLBY_PARAM_VEN_LENGTH)
+
+#define DOLBY_PARAM_INT_ENDP_LENGTH 1
+#define DOLBY_PARAM_PAYLOAD_SIZE 4
+#define DOLBY_MAX_LENGTH_INDIVIDUAL_PARAM 329
+
+#define DOLBY_NUM_ENDP_DEPENDENT_PARAMS 1
+#define DOLBY_ENDDEP_PARAM_DVLO_OFFSET 0
+#define DOLBY_ENDDEP_PARAM_DVLO_LENGTH 1
+#define DOLBY_ENDDEP_PARAM_LENGTH DOLBY_ENDDEP_PARAM_DVLO_LENGTH
+
+#define MAX_DOLBY_PARAMS 47
+#define MAX_DOLBY_CTRL_PARAMS 5
+#define ALL_DOLBY_PARAMS (MAX_DOLBY_PARAMS + \
+ MAX_DOLBY_CTRL_PARAMS)
+#define DOLBY_COMMIT_ALL_IDX MAX_DOLBY_PARAMS
+#define DOLBY_COMMIT_IDX (MAX_DOLBY_PARAMS+1)
+#define DOLBY_USE_CACHE_IDX (MAX_DOLBY_PARAMS+2)
+#define DOLBY_AUTO_ENDP_IDX (MAX_DOLBY_PARAMS+3)
+#define DOLBY_AUTO_ENDDEP_IDX (MAX_DOLBY_PARAMS+4)
+
+#define TOTAL_LENGTH_DOLBY_PARAM 745
+#define NUM_DOLBY_ENDP_DEVICE 23
+#define DOLBY_VIS_PARAM_HEADER_SIZE 25
+
+#define DOLBY_INVALID_PORT_ID -1
+/* DOLBY device definitions */
+enum {
+ DOLBY_ENDP_INT_SPEAKERS = 0,
+ DOLBY_ENDP_EXT_SPEAKERS,
+ DOLBY_ENDP_HEADPHONES,
+ DOLBY_ENDP_HDMI,
+ DOLBY_ENDP_SPDIF,
+ DOLBY_ENDP_DLNA,
+ DOLBY_ENDP_ANALOG,
+};
+
+enum {
+ DEVICE_NONE = 0x0,
+ /* output devices */
+ EARPIECE = 0x1,
+ SPEAKER = 0x2,
+ WIRED_HEADSET = 0x4,
+ WIRED_HEADPHONE = 0x8,
+ BLUETOOTH_SCO = 0x10,
+ BLUETOOTH_SCO_HEADSET = 0x20,
+ BLUETOOTH_SCO_CARKIT = 0x40,
+ BLUETOOTH_A2DP = 0x80,
+ BLUETOOTH_A2DP_HEADPHONES = 0x100,
+ BLUETOOTH_A2DP_SPEAKER = 0x200,
+ AUX_DIGITAL = 0x400,
+ ANLG_DOCK_HEADSET = 0x800,
+ DGTL_DOCK_HEADSET = 0x1000,
+ USB_ACCESSORY = 0x2000,
+ USB_DEVICE = 0x4000,
+ REMOTE_SUBMIX = 0x8000,
+ ANC_HEADSET = 0x10000,
+ ANC_HEADPHONE = 0x20000,
+ PROXY = 0x40000,
+ FM = 0x80000,
+ FM_TX = 0x100000,
+ DEVICE_OUT_ALL = 0x7FFFFFFF,
+};
+/* DOLBY device definitions end */
+
+struct dolby_dap_params {
+ uint32_t value[TOTAL_LENGTH_DOLBY_PARAM + MAX_DOLBY_PARAMS];
+} __packed;
+int dolby_dap_init(int port_id, int channels);
+int msm_routing_get_dolby_dap_param_to_set_control(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol);
+int msm_routing_put_dolby_dap_param_to_set_control(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol);
+int msm_routing_get_dolby_dap_param_to_get_control(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol);
+int msm_routing_put_dolby_dap_param_to_get_control(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol);
+int msm_routing_get_dolby_dap_param_visualizer_control(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol);
+int msm_routing_put_dolby_dap_param_visualizer_control(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol);
+int msm_routing_get_dolby_dap_endpoint_control(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol);
+int msm_routing_put_dolby_dap_endpoint_control(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol);
+void dolby_dap_deinit(int port_id);
+/* Dolby DOLBY end */
+#else
+int dolby_dap_init(int port_id, int channels) { return 0; }
+int msm_routing_get_dolby_dap_param_to_set_control(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol) { return 0; }
+int msm_routing_put_dolby_dap_param_to_set_control(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol) { return 0; }
+int msm_routing_get_dolby_dap_param_to_get_control(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol) { return 0; }
+int msm_routing_put_dolby_dap_param_to_get_control(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol) { return 0; }
+int msm_routing_get_dolby_dap_param_visualizer_control(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol) { return 0; }
+int msm_routing_put_dolby_dap_param_visualizer_control(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol) { return 0; }
+int msm_routing_get_dolby_dap_endpoint_control(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol) { return 0; }
+int msm_routing_put_dolby_dap_endpoint_control(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol) { return 0; }
+void dolby_dap_deinit(int port_id) { return; }
+#endif
+
+#endif
+
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
index ca91fe5..717e63b 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
@@ -82,9 +82,9 @@
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE),
- .rates = SNDRV_PCM_RATE_8000_96000,
+ .rates = SNDRV_PCM_RATE_8000_192000,
.rate_min = 8000,
- .rate_max = 96000,
+ .rate_max = 192000,
.channels_min = 1,
.channels_max = 8,
.buffer_bytes_max = PLAYBACK_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE,
@@ -98,7 +98,7 @@
/* Conventional and unconventional sample rate supported */
static unsigned int supported_sample_rates[] = {
8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000,
- 96000
+ 96000, 192000
};
static uint32_t in_frame_info[CAPTURE_NUM_PERIODS][2];
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index d8f2759..cb08ddc 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -10,7 +10,6 @@
* GNU General Public License for more details.
*/
-
#include <linux/init.h>
#include <linux/err.h>
#include <linux/module.h>
@@ -31,8 +30,10 @@
#include <sound/tlv.h>
#include <sound/asound.h>
#include <sound/pcm_params.h>
+#include <mach/qdsp6v2/q6core.h>
#include "msm-pcm-routing-v2.h"
+#include "msm-dolby-dap-config.h"
#include "q6voice.h"
struct msm_pcm_routing_bdai_data {
@@ -185,6 +186,20 @@
(void *)&msm_srs_trumedia_params[param_block_idx].srs_params.global);
}
+int get_topology(int path_type)
+{
+ int topology_id = 0;
+ if (path_type == ADM_PATH_PLAYBACK)
+ topology_id = get_adm_rx_topology();
+ else
+ topology_id = get_adm_tx_topology();
+
+ if (topology_id == 0)
+ topology_id = DEFAULT_COPP_TOPOLOGY;
+
+ return topology_id;
+}
+
#define SLIMBUS_EXTPROC_RX AFE_PORT_INVALID
static struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = {
{ PRIMARY_I2S_RX, 0, 0, 0, 0, 0},
@@ -318,7 +333,7 @@
void msm_pcm_routing_reg_phy_stream(int fedai_id, bool perf_mode,
int dspst_id, int stream_type)
{
- int i, session_type, path_type, port_type;
+ int i, session_type, path_type, port_type, port_id, topology;
struct route_payload payload;
u32 channels;
uint16_t bits_per_sample = 16;
@@ -346,6 +361,7 @@
/* re-enable EQ if active */
if (eq_data[fedai_id].enable)
msm_send_eq_values(fedai_id);
+ topology = get_topology(path_type);
for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) {
if (test_bit(fedai_id, &msm_bedais[i].fe_sessions))
msm_bedais[i].perf_mode = perf_mode;
@@ -361,27 +377,31 @@
else if (msm_bedais[i].format ==
SNDRV_PCM_FORMAT_S24_LE)
bits_per_sample = 24;
-
if ((stream_type == SNDRV_PCM_STREAM_PLAYBACK) &&
(channels > 0))
adm_multi_ch_copp_open(msm_bedais[i].port_id,
path_type,
msm_bedais[i].sample_rate,
msm_bedais[i].channel,
- DEFAULT_COPP_TOPOLOGY, msm_bedais[i].perf_mode,
+ topology, msm_bedais[i].perf_mode,
bits_per_sample);
else
adm_open(msm_bedais[i].port_id,
path_type,
msm_bedais[i].sample_rate,
msm_bedais[i].channel,
- DEFAULT_COPP_TOPOLOGY, false,
+ topology, false,
bits_per_sample);
payload.copp_ids[payload.num_copps++] =
msm_bedais[i].port_id;
- srs_port_id = msm_bedais[i].port_id;
+ port_id = srs_port_id = msm_bedais[i].port_id;
srs_send_params(srs_port_id, 1, 0);
+ if (DOLBY_ADM_COPP_TOPOLOGY_ID == topology)
+ if (dolby_dap_init(port_id,
+ msm_bedais[i].channel) < 0)
+ pr_err("%s: Err init dolby dap\n",
+ __func__);
}
}
if (payload.num_copps)
@@ -393,7 +413,7 @@
void msm_pcm_routing_dereg_phy_stream(int fedai_id, int stream_type)
{
- int i, port_type, session_type;
+ int i, port_type, session_type, path_type, topology;
if (fedai_id > MSM_FRONTEND_DAI_MM_MAX_ID) {
/* bad ID assigned in machine driver */
@@ -404,19 +424,24 @@
if (stream_type == SNDRV_PCM_STREAM_PLAYBACK) {
port_type = MSM_AFE_PORT_TYPE_RX;
session_type = SESSION_TYPE_RX;
+ path_type = ADM_PATH_PLAYBACK;
} else {
port_type = MSM_AFE_PORT_TYPE_TX;
session_type = SESSION_TYPE_TX;
+ path_type = ADM_PATH_LIVE_REC;
}
mutex_lock(&routing_lock);
-
+ topology = get_topology(path_type);
for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) {
if (!is_be_dai_extproc(i) &&
(afe_get_port_type(msm_bedais[i].port_id) == port_type) &&
(msm_bedais[i].active) &&
- (test_bit(fedai_id, &msm_bedais[i].fe_sessions)))
+ (test_bit(fedai_id, &msm_bedais[i].fe_sessions))) {
adm_close(msm_bedais[i].port_id);
+ if (DOLBY_ADM_COPP_TOPOLOGY_ID == topology)
+ dolby_dap_deinit(msm_bedais[i].port_id);
+ }
}
fe_dai_map[fedai_id][session_type] = INVALID_SESSION;
@@ -443,7 +468,7 @@
static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set)
{
- int session_type, path_type;
+ int session_type, path_type, port_id, topology;
u32 channels;
uint16_t bits_per_sample = 16;
@@ -465,7 +490,7 @@
}
mutex_lock(&routing_lock);
-
+ topology = get_topology(path_type);
if (set) {
if (!test_bit(val, &msm_bedais[reg].fe_sessions) &&
(msm_bedais[reg].port_id == VOICE_PLAYBACK_TX))
@@ -484,19 +509,23 @@
path_type,
msm_bedais[reg].sample_rate,
channels,
- DEFAULT_COPP_TOPOLOGY,
+ topology,
msm_bedais[reg].perf_mode,
bits_per_sample);
} else
adm_open(msm_bedais[reg].port_id,
path_type,
msm_bedais[reg].sample_rate, channels,
- DEFAULT_COPP_TOPOLOGY, false, bits_per_sample);
+ topology, false, bits_per_sample);
msm_pcm_routing_build_matrix(val,
fe_dai_map[val][session_type], path_type);
- srs_port_id = msm_bedais[reg].port_id;
+ port_id = srs_port_id = msm_bedais[reg].port_id;
srs_send_params(srs_port_id, 1, 0);
+ if (DOLBY_ADM_COPP_TOPOLOGY_ID == topology)
+ if (dolby_dap_init(port_id, channels) < 0)
+ pr_err("%s: Err init dolby dap\n",
+ __func__);
}
} else {
if (test_bit(val, &msm_bedais[reg].fe_sessions) &&
@@ -506,6 +535,8 @@
if (msm_bedais[reg].active && fe_dai_map[val][session_type] !=
INVALID_SESSION) {
adm_close(msm_bedais[reg].port_id);
+ if (DOLBY_ADM_COPP_TOPOLOGY_ID == topology)
+ dolby_dap_deinit(msm_bedais[reg].port_id);
msm_pcm_routing_build_matrix(val,
fe_dai_map[val][session_type], path_type);
}
@@ -2090,6 +2121,51 @@
}
};
+int msm_routing_get_dolby_security_control(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol) {
+ /* not used while setting the manfr id*/
+ return 0;
+}
+
+int msm_routing_put_dolby_security_control(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol) {
+ int manufacturer_id = ucontrol->value.integer.value[0];
+ core_set_dolby_manufacturer_id(manufacturer_id);
+ return 0;
+}
+
+static const struct snd_kcontrol_new dolby_security_controls[] = {
+ SOC_SINGLE_MULTI_EXT("DS1 Security", SND_SOC_NOPM, 0,
+ 0xFFFFFFFF, 0, 1, msm_routing_get_dolby_security_control,
+ msm_routing_put_dolby_security_control),
+};
+
+static const struct snd_kcontrol_new dolby_dap_param_to_set_controls[] = {
+ SOC_SINGLE_MULTI_EXT("DS1 DAP Set Param", SND_SOC_NOPM, 0, 0xFFFFFFFF,
+ 0, 128, msm_routing_get_dolby_dap_param_to_set_control,
+ msm_routing_put_dolby_dap_param_to_set_control),
+};
+
+static const struct snd_kcontrol_new dolby_dap_param_to_get_controls[] = {
+ SOC_SINGLE_MULTI_EXT("DS1 DAP Get Param", SND_SOC_NOPM, 0, 0xFFFFFFFF,
+ 0, 128, msm_routing_get_dolby_dap_param_to_get_control,
+ msm_routing_put_dolby_dap_param_to_get_control),
+};
+
+static const struct snd_kcontrol_new dolby_dap_param_visualizer_controls[] = {
+ SOC_SINGLE_MULTI_EXT("DS1 DAP Get Visualizer", SND_SOC_NOPM, 0,
+ 0xFFFFFFFF, 0, 41, msm_routing_get_dolby_dap_param_visualizer_control,
+ msm_routing_put_dolby_dap_param_visualizer_control),
+};
+
+static const struct snd_kcontrol_new dolby_dap_param_end_point_controls[] = {
+ SOC_SINGLE_MULTI_EXT("DS1 DAP Endpoint", SND_SOC_NOPM, 0,
+ 0xFFFFFFFF, 0, 1, msm_routing_get_dolby_dap_endpoint_control,
+ msm_routing_put_dolby_dap_endpoint_control),
+};
+
static const struct snd_kcontrol_new eq_enable_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia1 EQ Enable", SND_SOC_NOPM,
MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_eq_enable_mixer,
@@ -2941,7 +3017,7 @@
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
unsigned int be_id = rtd->dai_link->be_id;
- int i, session_type;
+ int i, session_type, path_type, topology;
struct msm_pcm_routing_bdai_data *bedai;
if (be_id >= MSM_BACKEND_DAI_MAX) {
@@ -2952,13 +3028,20 @@
bedai = &msm_bedais[be_id];
session_type = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
0 : 1);
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ path_type = ADM_PATH_PLAYBACK;
+ else
+ path_type = ADM_PATH_LIVE_REC;
mutex_lock(&routing_lock);
-
+ topology = get_topology(path_type);
for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MM_SIZE) {
- if (fe_dai_map[i][session_type] != INVALID_SESSION)
+ if (fe_dai_map[i][session_type] != INVALID_SESSION) {
adm_close(bedai->port_id);
srs_port_id = -1;
+ if (DOLBY_ADM_COPP_TOPOLOGY_ID == topology)
+ dolby_dap_deinit(bedai->port_id);
+ }
}
bedai->active = 0;
@@ -2974,7 +3057,7 @@
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
unsigned int be_id = rtd->dai_link->be_id;
- int i, path_type, session_type;
+ int i, path_type, session_type, port_id, topology;
struct msm_pcm_routing_bdai_data *bedai;
u32 channels;
bool playback, capture;
@@ -2996,7 +3079,7 @@
}
mutex_lock(&routing_lock);
-
+ topology = get_topology(path_type);
if (bedai->active == 1)
goto done; /* Ignore prepare if back-end already active */
@@ -3021,21 +3104,25 @@
path_type,
bedai->sample_rate,
channels,
- DEFAULT_COPP_TOPOLOGY, bedai->perf_mode,
+ topology, bedai->perf_mode,
bits_per_sample);
} else if (capture) {
adm_open(bedai->port_id,
path_type,
bedai->sample_rate,
channels,
- DEFAULT_COPP_TOPOLOGY, false,
+ topology, false,
bits_per_sample);
}
msm_pcm_routing_build_matrix(i,
fe_dai_map[i][session_type], path_type);
- srs_port_id = bedai->port_id;
+ port_id = srs_port_id = bedai->port_id;
srs_send_params(srs_port_id, 1, 0);
+ if (DOLBY_ADM_COPP_TOPOLOGY_ID == topology)
+ if (dolby_dap_init(port_id, channels) < 0)
+ pr_err("%s: Err init dolby dap\n",
+ __func__);
}
}
@@ -3130,6 +3217,27 @@
snd_soc_add_platform_controls(platform,
aanc_slim_0_rx_mux,
ARRAY_SIZE(aanc_slim_0_rx_mux));
+
+ snd_soc_add_platform_controls(platform,
+ dolby_security_controls,
+ ARRAY_SIZE(dolby_security_controls));
+
+ snd_soc_add_platform_controls(platform,
+ dolby_dap_param_to_set_controls,
+ ARRAY_SIZE(dolby_dap_param_to_set_controls));
+
+ snd_soc_add_platform_controls(platform,
+ dolby_dap_param_to_get_controls,
+ ARRAY_SIZE(dolby_dap_param_to_get_controls));
+
+ snd_soc_add_platform_controls(platform,
+ dolby_dap_param_visualizer_controls,
+ ARRAY_SIZE(dolby_dap_param_visualizer_controls));
+
+ snd_soc_add_platform_controls(platform,
+ dolby_dap_param_end_point_controls,
+ ARRAY_SIZE(dolby_dap_param_end_point_controls));
+
return 0;
}
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
index 1c1029c..bd5821f 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
@@ -141,4 +141,7 @@
int compressed_set_volume(unsigned volume);
+uint32_t get_adm_rx_topology(void);
+
+uint32_t get_adm_tx_topology(void);
#endif /*_MSM_PCM_H*/
diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c
index b1db277..1bd3eac 100644
--- a/sound/soc/msm/qdsp6v2/q6adm.c
+++ b/sound/soc/msm/qdsp6v2/q6adm.c
@@ -33,6 +33,7 @@
#define RESET_COPP_ID 99
#define INVALID_COPP_ID 0xFF
+#define ADM_GET_PARAMETER_LENGTH 350
struct adm_ctl {
void *apr;
@@ -64,6 +65,8 @@
{0, 0, 0, 0, 0, 0, 0, 0}
};
+static int adm_dolby_get_parameters[ADM_GET_PARAMETER_LENGTH];
+
int srs_trumedia_open(int port_id, int srs_tech_id, void *srs_params)
{
struct adm_cmd_set_pp_params_inband_v5 *adm_params = NULL;
@@ -266,6 +269,134 @@
return ret;
}
+int adm_dolby_dap_send_params(int port_id, char *params, uint32_t params_length)
+{
+ struct adm_cmd_set_pp_params_v5 *adm_params = NULL;
+ int sz, rc = 0, index = afe_get_port_index(port_id);
+
+ pr_debug("%s\n", __func__);
+ if (index < 0 || index >= AFE_MAX_PORTS) {
+ pr_err("%s: invalid port idx %d portid %#x\n",
+ __func__, index, port_id);
+ return -EINVAL;
+ }
+ sz = sizeof(struct adm_cmd_set_pp_params_v5) + params_length;
+ adm_params = kzalloc(sz, GFP_KERNEL);
+ if (!adm_params) {
+ pr_err("%s, adm params memory alloc failed", __func__);
+ return -ENOMEM;
+ }
+
+ memcpy(((u8 *)adm_params + sizeof(struct adm_cmd_set_pp_params_v5)),
+ params, params_length);
+ adm_params->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+ APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+ adm_params->hdr.pkt_size = sz;
+ adm_params->hdr.src_svc = APR_SVC_ADM;
+ adm_params->hdr.src_domain = APR_DOMAIN_APPS;
+ adm_params->hdr.src_port = port_id;
+ adm_params->hdr.dest_svc = APR_SVC_ADM;
+ adm_params->hdr.dest_domain = APR_DOMAIN_ADSP;
+ adm_params->hdr.dest_port = atomic_read(&this_adm.copp_id[index]);
+ adm_params->hdr.token = port_id;
+ adm_params->hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5;
+ adm_params->payload_addr_lsw = 0;
+ adm_params->payload_addr_msw = 0;
+ adm_params->mem_map_handle = 0;
+ adm_params->payload_size = params_length;
+
+ atomic_set(&this_adm.copp_stat[index], 0);
+ rc = apr_send_pkt(this_adm.apr, (uint32_t *)adm_params);
+ if (rc < 0) {
+ pr_err("%s: Set params failed port = %#x\n",
+ __func__, port_id);
+ rc = -EINVAL;
+ goto dolby_dap_send_param_return;
+ }
+ /* Wait for the callback */
+ rc = wait_event_timeout(this_adm.wait[index],
+ atomic_read(&this_adm.copp_stat[index]),
+ msecs_to_jiffies(TIMEOUT_MS));
+ if (!rc) {
+ pr_err("%s: Set params timed out port = %#x\n",
+ __func__, port_id);
+ rc = -EINVAL;
+ goto dolby_dap_send_param_return;
+ }
+ rc = 0;
+dolby_dap_send_param_return:
+ kfree(adm_params);
+ return rc;
+}
+
+int adm_dolby_dap_get_params(int port_id, uint32_t module_id, uint32_t param_id,
+ uint32_t params_length, char *params)
+{
+ struct adm_cmd_get_pp_params_v5 *adm_params = NULL;
+ int sz, rc = 0, i = 0, index = afe_get_port_index(port_id);
+ int *params_data = (int *)params;
+
+ if (index < 0 || index >= AFE_MAX_PORTS) {
+ pr_err("%s: invalid port idx %d portid %#x\n",
+ __func__, index, port_id);
+ return -EINVAL;
+ }
+ sz = sizeof(struct adm_cmd_set_pp_params_v5) + params_length;
+ adm_params = kzalloc(sz, GFP_KERNEL);
+ if (!adm_params) {
+ pr_err("%s, adm params memory alloc failed", __func__);
+ return -ENOMEM;
+ }
+
+ memcpy(((u8 *)adm_params + sizeof(struct adm_cmd_set_pp_params_v5)),
+ params, params_length);
+ adm_params->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+ APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+ adm_params->hdr.pkt_size = sz;
+ adm_params->hdr.src_svc = APR_SVC_ADM;
+ adm_params->hdr.src_domain = APR_DOMAIN_APPS;
+ adm_params->hdr.src_port = port_id;
+ adm_params->hdr.dest_svc = APR_SVC_ADM;
+ adm_params->hdr.dest_domain = APR_DOMAIN_ADSP;
+ adm_params->hdr.dest_port = atomic_read(&this_adm.copp_id[index]);
+ adm_params->hdr.token = port_id;
+ adm_params->hdr.opcode = ADM_CMD_GET_PP_PARAMS_V5;
+ adm_params->data_payload_addr_lsw = 0;
+ adm_params->data_payload_addr_msw = 0;
+ adm_params->mem_map_handle = 0;
+ adm_params->module_id = module_id;
+ adm_params->param_id = param_id;
+ adm_params->param_max_size = params_length;
+ adm_params->reserved = 0;
+
+ atomic_set(&this_adm.copp_stat[index], 0);
+ rc = apr_send_pkt(this_adm.apr, (uint32_t *)adm_params);
+ if (rc < 0) {
+ pr_err("%s: Failed to Get DOLBY Params on port %d\n", __func__,
+ port_id);
+ rc = -EINVAL;
+ goto dolby_dap_get_param_return;
+ }
+ /* Wait for the callback with copp id */
+ rc = wait_event_timeout(this_adm.wait[index],
+ atomic_read(&this_adm.copp_stat[index]),
+ msecs_to_jiffies(TIMEOUT_MS));
+ if (!rc) {
+ pr_err("%s: DOLBY get params timed out port = %d\n", __func__,
+ port_id);
+ rc = -EINVAL;
+ goto dolby_dap_get_param_return;
+ }
+ if (params_data) {
+ for (i = 0; i < adm_dolby_get_parameters[0]; i++)
+ params_data[i] = adm_dolby_get_parameters[1+i];
+ }
+ rc = 0;
+dolby_dap_get_param_return:
+ kfree(adm_params);
+ return rc;
+}
+
static void adm_callback_debug_print(struct apr_client_data *data)
{
uint32_t *payload;
@@ -428,6 +559,13 @@
__func__, payload[0]);
rtac_make_adm_callback(payload,
data->payload_size);
+ adm_dolby_get_parameters[0] = payload[3];
+ pr_debug("GET_PP PARAM:received parameter length: %x\n",
+ adm_dolby_get_parameters[0]);
+ for (i = 0; i < payload[3]; i++)
+ adm_dolby_get_parameters[1+i] = payload[4+i];
+ atomic_set(&this_adm.copp_stat[index], 1);
+ wake_up(&this_adm.wait[index]);
break;
case ADM_CMDRSP_SHARED_MEM_MAP_REGIONS:
pr_debug("%s: ADM_CMDRSP_SHARED_MEM_MAP_REGIONS\n",
@@ -807,20 +945,10 @@
open.endpoint_id_1 = tmp_port;
open.endpoint_id_2 = 0xFFFF;
- /* convert path to acdb path */
- if (path == ADM_PATH_PLAYBACK)
- open.topology_id = get_adm_rx_topology();
- else {
- open.topology_id = get_adm_tx_topology();
- if ((open.topology_id ==
- VPM_TX_SM_ECNS_COPP_TOPOLOGY) ||
- (open.topology_id ==
- VPM_TX_DM_FLUENCE_COPP_TOPOLOGY))
+ open.topology_id = topology;
+ if ((open.topology_id == VPM_TX_SM_ECNS_COPP_TOPOLOGY) ||
+ (open.topology_id == VPM_TX_DM_FLUENCE_COPP_TOPOLOGY))
rate = 16000;
- }
-
- if (open.topology_id == 0)
- open.topology_id = topology;
open.dev_num_channel = channel_mode & 0x00FF;
open.bit_width = bits_per_sample;
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index 3dbe49a..5d081f6 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -1569,6 +1569,12 @@
case FORMAT_MP3:
open.dec_fmt_id = ASM_MEDIA_FMT_MP3;
break;
+ case FORMAT_AC3:
+ open.dec_fmt_id = ASM_MEDIA_FMT_EAC3_DEC;
+ break;
+ case FORMAT_EAC3:
+ open.dec_fmt_id = ASM_MEDIA_FMT_EAC3_DEC;
+ break;
default:
pr_err("%s: Invalid format[%d]\n", __func__, format);
goto fail_cmd;
@@ -2570,6 +2576,40 @@
return -EINVAL;
}
+int q6asm_ds1_set_endp_params(struct audio_client *ac,
+ int param_id, int param_value)
+{
+ struct asm_dec_ddp_endp_param_v2 ddp_cfg;
+ int rc = 0;
+
+ pr_debug("%s: session[%d]param_id[%d]param_value[%d]", __func__,
+ ac->session, param_id, param_value);
+ q6asm_add_hdr(ac, &ddp_cfg.hdr, sizeof(ddp_cfg), TRUE);
+ ddp_cfg.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM;
+ ddp_cfg.encdec.param_id = param_id;
+ ddp_cfg.encdec.param_size = sizeof(struct asm_dec_ddp_endp_param_v2) -
+ (sizeof(struct apr_hdr) +
+ sizeof(struct asm_stream_cmd_set_encdec_param));
+ ddp_cfg.endp_param_value = param_value;
+ rc = apr_send_pkt(ac->apr, (uint32_t *) &ddp_cfg);
+ if (rc < 0) {
+ pr_err("%s:Command opcode[0x%x] failed\n",
+ __func__, ASM_STREAM_CMD_SET_ENCDEC_PARAM);
+ goto fail_cmd;
+ }
+ rc = wait_event_timeout(ac->cmd_wait,
+ (atomic_read(&ac->cmd_state) == 0), 5*HZ);
+ if (!rc) {
+ pr_err("%s:timeout opcode[0x%x]\n", __func__,
+ ddp_cfg.hdr.opcode);
+ rc = -ETIMEDOUT;
+ goto fail_cmd;
+ }
+ return 0;
+fail_cmd:
+ return rc;
+}
+
int q6asm_memory_map(struct audio_client *ac, uint32_t buf_add, int dir,
uint32_t bufsz, uint32_t bufcnt)
{