Merge "ASoC: msm: qdsp6v2: Check for null data pointer"
diff --git a/Documentation/devicetree/bindings/arm/msm/cpr-regulator.txt b/Documentation/devicetree/bindings/arm/msm/cpr-regulator.txt
index 0d3d3f7..1b881f0 100644
--- a/Documentation/devicetree/bindings/arm/msm/cpr-regulator.txt
+++ b/Documentation/devicetree/bindings/arm/msm/cpr-regulator.txt
@@ -22,16 +22,13 @@
should be 1 for SVS corner
- regulator-max-microvolt: Maximum corner value as max constraint, which
should be 4 for SUPER_TURBO or 3 for TURBO
-- qcom,pvs-init-voltage: A list of integers whose length is equal to 2
- to the power of qcom,pvs-fuse[num-of-bits]. The
- location or 0-based index of an element in the
- list corresponds to the bin number. The value of
- each integer corresponds to the initial voltage
- of the PVS bin in turbo mode in microvolts.
-- qcom,pvs-corner-ceiling-slow: Ceiling voltages of all corners for APC_PVS_SLOW
-- qcom,pvs-corner-ceiling-nom: Ceiling voltages of all corners for APC_PVS_NOM
-- qcom,pvs-corner-ceiling-fast: Ceiling voltages of all corners for APC_PVS_FAST
- The ceiling voltages for each of above three
+- qcom,pvs-voltage-table: Array of triples in which each triple indicates the initial voltage
+ of the PVS bin in SVS, NOM and Turbo corner in microvolts.
+ The location or 0-based index of an triple in the
+ list corresponds to the bin number.
+- qcom,cpr-voltage-ceiling: Ceiling voltages of SVS, NOM and TURBO corners respectively
+- qcom,cpr-voltage-floor: Floor voltages of SVS, NOM and TURBO corners respectively
+ The ceiling voltages for each of above two
properties may look like this:
0 (SVS voltage): 1050000 uV
1 (NORMAL voltage): 1150000 uV
@@ -243,23 +240,47 @@
interrupts = <0 15 0>;
regulator-name = "apc_corner";
regulator-min-microvolt = <1>;
- regulator-max-microvolt = <3>;
+ regulator-max-microvolt = <12>;
qcom,pvs-fuse = <22 6 5 1>;
qcom,pvs-fuse-redun-sel = <22 24 3 2 1>;
qcom,pvs-fuse-redun = <22 27 5 1>;
- qcom,pvs-init-voltage = <1330000 1330000 1330000 1320000
- 1310000 1300000 1290000 1280000
- 1270000 1260000 1250000 1240000
- 1230000 1220000 1210000 1200000
- 1190000 1180000 1170000 1160000
- 1150000 1140000 1140000 1140000
- 1140000 1140000 1140000 1140000
- 1140000 1140000 1140000 1140000>;
- qcom,pvs-corner-ceiling-slow = <1050000 1160000 1275000>;
- qcom,pvs-corner-ceiling-nom = <975000 1075000 1200000>;
- qcom,pvs-corner-ceiling-fast = <900000 1000000 1140000>;
+ qcom,pvs-voltage-table =
+ <1050000 1150000 1350000>,
+ <1050000 1150000 1340000>,
+ <1050000 1150000 1330000>,
+ <1050000 1150000 1320000>,
+ <1050000 1150000 1310000>,
+ <1050000 1150000 1300000>,
+ <1050000 1150000 1290000>,
+ <1050000 1150000 1280000>,
+ <1050000 1150000 1270000>,
+ <1050000 1140000 1260000>,
+ <1050000 1130000 1250000>,
+ <1050000 1120000 1240000>,
+ <1050000 1110000 1230000>,
+ <1050000 1100000 1220000>,
+ <1050000 1090000 1210000>,
+ <1050000 1080000 1200000>,
+ <1050000 1070000 1190000>,
+ <1050000 1060000 1180000>,
+ <1050000 1050000 1170000>,
+ <1050000 1050000 1160000>,
+ <1050000 1050000 1150000>,
+ <1050000 1050000 1140000>,
+ <1050000 1050000 1140000>,
+ <1050000 1050000 1140000>,
+ <1050000 1050000 1140000>,
+ <1050000 1050000 1140000>,
+ <1050000 1050000 1140000>,
+ <1050000 1050000 1140000>,
+ <1050000 1050000 1140000>,
+ <1050000 1050000 1140000>,
+ <1050000 1050000 1140000>,
+ <1050000 1050000 1140000>;
+ qcom,cpr-voltage-ceiling = <1050000 1150000 1280000>;
+ qcom,cpr-voltage-floor = <1050000 1050000 1100000>;
vdd-apc-supply = <&pm8226_s2>;
vdd-apc-optional-prim-supply = <&ncp6335d>;
vdd-apc-optional-sec-supply = <&fan53555>;
diff --git a/Documentation/devicetree/bindings/media/video/msm-cci.txt b/Documentation/devicetree/bindings/media/video/msm-cci.txt
index cdf4ae9..f256d78 100644
--- a/Documentation/devicetree/bindings/media/video/msm-cci.txt
+++ b/Documentation/devicetree/bindings/media/video/msm-cci.txt
@@ -154,6 +154,8 @@
- qcom,vdd-cx-supply : should contain regulator from which cx voltage is
supplied
- qcom,vdd-cx-name : should contain names of cx regulator
+- qcom,eeprom-src : if eeprom memory is supported by this sensor, this
+ property should contain phandle of respective eeprom nodes
* Qualcomm MSM ACTUATOR
@@ -209,6 +211,7 @@
qcom,csiphy-sd-index = <2>;
qcom,csid-sd-index = <0>;
qcom,actuator-src = <&actuator0>;
+ qcom,eeprom-src = <&eeprom0 &eeprom1>;
qcom,led-flash-src = <&led_flash0>;
qcom,mount-angle = <90>;
qcom,sensor-name = "s5k3l1yx";
diff --git a/Documentation/devicetree/bindings/media/video/msm-eeprom.txt b/Documentation/devicetree/bindings/media/video/msm-eeprom.txt
index c7821f5..6ed130c 100644
--- a/Documentation/devicetree/bindings/media/video/msm-eeprom.txt
+++ b/Documentation/devicetree/bindings/media/video/msm-eeprom.txt
@@ -58,6 +58,13 @@
data, data type, delay in ms. size 0 stand for not used.
- cam_vdig-supply : should contain regulator to be used for the digital vdd.
+Optional properties -EEPROM Camera Multimodule
+- qcom,mm-data-support - Camera Multimodule data capability flag.
+- qcom,mm-data-compressed - Camera Multimodule data compresion flag.
+- qcom,mm-data-offset - Camera Multimodule data start offset.
+- qcom,mm-data-size - Camera Multimodule data size.
+
+
Example:
eeprom0: qcom,eeprom@60 {
@@ -76,6 +83,11 @@
qcom,poll1 = <0 0x0 2 0 1 1>;
qcom,mem1 = <32 0x3000 2 0 1 0>;
+ qcom,mm-data-support;
+ qcom,mm-data-compressed;
+ qcom,mm-data-offset = 0;
+ qcom,mm-data-size = 0;
+
cam_vdig-supply = <&pm8226_l5>;
cam_vio-supply = <&pm8226_lvs1>;
qcom,cam-vreg-name = "cam_vdig", "cam_vio";
diff --git a/Documentation/devicetree/bindings/platform/msm/qpnp-power-on.txt b/Documentation/devicetree/bindings/platform/msm/qpnp-power-on.txt
index 83237f9..7b70369 100644
--- a/Documentation/devicetree/bindings/platform/msm/qpnp-power-on.txt
+++ b/Documentation/devicetree/bindings/platform/msm/qpnp-power-on.txt
@@ -36,6 +36,10 @@
to include it more than once.
- qcom,s3-debounce The debounce delay for stage3 reset trigger in
secs. The values range from 0 to 128.
+- qcom,s3-src The source for stage 3 reset. It can be one of
+ "kpdpwr", "resin", "kpdpwr-or-resin" or
+ "kpdpwr-and-resin". The default value is
+ "kpdpwr-and-resin".
All the below properties are in the sub-node section (properties of the child
node).
@@ -92,6 +96,7 @@
qcom,pon-dbc-delay = <15625>;
qcom,system-reset;
qcom,s3-debounce = <32>;
+ qcom,s3-src = "resin";
qcom,pon_1 {
qcom,pon-type = <0>;
diff --git a/arch/arm/boot/dts/msm-pm8226.dtsi b/arch/arm/boot/dts/msm-pm8226.dtsi
index 0558ee5..41897da 100644
--- a/arch/arm/boot/dts/msm-pm8226.dtsi
+++ b/arch/arm/boot/dts/msm-pm8226.dtsi
@@ -39,6 +39,7 @@
qcom,pon-dbc-delay = <15625>;
qcom,system-reset;
qcom,s3-debounce = <32>;
+ qcom,s3-src = "kpdpwr-and-resin";
qcom,pon_1 {
qcom,pon-type = <0>;
@@ -50,10 +51,6 @@
qcom,pon-type = <1>;
qcom,pull-up = <1>;
linux,code = <114>;
- qcom,s1-timer = <6720>;
- qcom,s2-timer = <2000>;
- qcom,s2-type = <7>;
- qcom,support-reset = <1>;
};
qcom,pon_3 {
@@ -366,6 +363,7 @@
interrupt-names = "eoc-int-en-set";
qcom,adc-bit-resolution = <15>;
qcom,adc-vdd-reference = <1800>;
+ qcom,vadc-poll-eoc;
chan@8 {
label = "die_temp";
@@ -424,6 +422,7 @@
qcom,adc-bit-resolution = <16>;
qcom,adc-vdd-reference = <1800>;
qcom,iadc-vadc = <&pm8226_vadc>;
+ qcom,iadc-poll-eoc;
qcom,use-default-rds-trim = <0>;
chan@0 {
diff --git a/arch/arm/boot/dts/msm8226-qrd.dtsi b/arch/arm/boot/dts/msm8226-qrd.dtsi
index 84e46ea..cd56da3 100644
--- a/arch/arm/boot/dts/msm8226-qrd.dtsi
+++ b/arch/arm/boot/dts/msm8226-qrd.dtsi
@@ -482,13 +482,6 @@
};
};
-&slim_msm {
- tapan_codec {
- qcom,cdc-micbias1-ext-cap;
- qcom,cdc-micbias3-ext-cap;
- };
-};
-
&pm8226_vadc {
chan@30 {
label = "batt_therm";
diff --git a/arch/arm/boot/dts/msm8226-regulator.dtsi b/arch/arm/boot/dts/msm8226-regulator.dtsi
index a76c4df..5e890d3 100644
--- a/arch/arm/boot/dts/msm8226-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8226-regulator.dtsi
@@ -19,7 +19,7 @@
regulator-name = "8226_s2";
reg = <0x1700 0x100>;
regulator-min-microvolt = <900000>;
- regulator-max-microvolt = <1275000>;
+ regulator-max-microvolt = <1350000>;
qcom,mode = "auto";
};
};
@@ -35,23 +35,46 @@
reg-names = "rbcpr", "rbcpr_clk", "efuse_addr";
interrupts = <0 15 0>;
regulator-name = "apc_corner";
- regulator-min-microvolt = <1>;
- regulator-max-microvolt = <14>;
qcom,pvs-fuse-redun-sel = <22 24 3 2 0>;
qcom,pvs-fuse = <22 6 5 0>;
qcom,pvs-fuse-redun = <22 27 5 0>;
- qcom,pvs-init-voltage = <1275000 1275000 1275000 1275000 1275000
- 1275000 1260000 1245000 1230000 1215000
- 1200000 1185000 1170000 1155000 1140000
- 1140000 1140000 1140000 1140000 1140000
- 1150000 1140000 1140000 1140000 1140000
- 1140000 1140000 1140000 1275000 1275000
- 1275000 1275000>;
- qcom,pvs-corner-ceiling-slow = <1050000 1150000 1275000>;
- qcom,pvs-corner-ceiling-nom = <1050000 1075000 1200000>;
- qcom,pvs-corner-ceiling-fast = <1050000 1050000 1100000>;
+ qcom,pvs-voltage-table =
+ <1050000 1150000 1350000>,
+ <1050000 1150000 1340000>,
+ <1050000 1150000 1330000>,
+ <1050000 1150000 1320000>,
+ <1050000 1150000 1310000>,
+ <1050000 1150000 1300000>,
+ <1050000 1150000 1290000>,
+ <1050000 1150000 1280000>,
+ <1050000 1150000 1270000>,
+ <1050000 1140000 1260000>,
+ <1050000 1130000 1250000>,
+ <1050000 1120000 1240000>,
+ <1050000 1110000 1230000>,
+ <1050000 1100000 1220000>,
+ <1050000 1090000 1210000>,
+ <1050000 1080000 1200000>,
+ <1050000 1070000 1190000>,
+ <1050000 1060000 1180000>,
+ <1050000 1050000 1170000>,
+ <1050000 1050000 1160000>,
+ <1050000 1050000 1150000>,
+ <1050000 1050000 1140000>,
+ <1050000 1050000 1140000>,
+ <1050000 1050000 1140000>,
+ <1050000 1050000 1140000>,
+ <1050000 1050000 1140000>,
+ <1050000 1050000 1140000>,
+ <1050000 1050000 1140000>,
+ <1050000 1050000 1140000>,
+ <1050000 1050000 1140000>,
+ <1050000 1050000 1140000>,
+ <1050000 1050000 1140000>;
+ qcom,cpr-voltage-ceiling = <1050000 1150000 1280000>;
+ qcom,cpr-voltage-floor = <1050000 1050000 1100000>;
vdd-apc-supply = <&pm8226_s2>;
vdd-mx-supply = <&pm8226_l3_ao>;
@@ -63,14 +86,12 @@
qcom,cpr-timer-cons-up = <0>;
qcom,cpr-timer-cons-down = <2>;
qcom,cpr-irq-line = <0>;
- qcom,cpr-step-quotient = <15>;
- qcom,cpr-up-threshold = <0>;
- qcom,cpr-down-threshold = <10>;
+ qcom,cpr-step-quotient = <30>;
qcom,cpr-idle-clocks = <0>;
qcom,cpr-gcnt-time = <1>;
qcom,vdd-apc-step-up-limit = <1>;
qcom,vdd-apc-step-down-limit = <1>;
- qcom,cpr-apc-volt-step = <5000>;
+ qcom,cpr-apc-volt-step = <10000>;
qcom,cpr-fuse-redun-sel = <138 57 1 1 0>;
qcom,cpr-fuse-row = <138 0>;
@@ -91,15 +112,6 @@
qcom,cpr-uplift-max-volt = <1350000>;
qcom,cpr-uplift-speed-bin = <1>;
qcom,speed-bin-fuse-sel = <22 0 3 0>;
- qcom,cpr-corner-map = <1 1 2 2 3 3 3 3 3 3 3 3 3 3>;
- qcom,cpr-quot-adjust-table =
- <1 5 450>,
- <1 6 375>,
- <1 7 300>,
- <1 8 225>,
- <1 9 187>,
- <1 10 150>,
- <1 11 75>;
};
};
@@ -198,7 +210,7 @@
pm8226_l3: regulator-l3 {
regulator-name = "8226_l3";
regulator-min-microvolt = <750000>;
- regulator-max-microvolt = <1275000>;
+ regulator-max-microvolt = <1337500>;
status = "okay";
};
pm8226_l3_ao: regulator-3-ao {
@@ -206,7 +218,7 @@
regulator-name = "8226_l3_ao";
qcom,set = <1>;
regulator-min-microvolt = <750000>;
- regulator-max-microvolt = <1275000>;
+ regulator-max-microvolt = <1337500>;
status = "okay";
};
pm8226_l3_so: regulator-l3-so {
@@ -214,7 +226,7 @@
regulator-name = "8226_l3_so";
qcom,set = <2>;
regulator-min-microvolt = <750000>;
- regulator-max-microvolt = <1275000>;
+ regulator-max-microvolt = <1337500>;
qcom,init-voltage = <750000>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/msm8226-v1-qrd-dvt.dts b/arch/arm/boot/dts/msm8226-v1-qrd-dvt.dts
index 7e9f91b..9bfd280 100644
--- a/arch/arm/boot/dts/msm8226-v1-qrd-dvt.dts
+++ b/arch/arm/boot/dts/msm8226-v1-qrd-dvt.dts
@@ -27,3 +27,10 @@
&dsi_hx8394a_720_vid {
qcom,cont-splash-enabled;
};
+
+&slim_msm {
+ tapan_codec {
+ qcom,cdc-micbias1-ext-cap;
+ qcom,cdc-micbias3-ext-cap;
+ };
+};
\ No newline at end of file
diff --git a/arch/arm/boot/dts/msm8226-v1-qrd-evt.dts b/arch/arm/boot/dts/msm8226-v1-qrd-evt.dts
index c93d9db..44dd280 100644
--- a/arch/arm/boot/dts/msm8226-v1-qrd-evt.dts
+++ b/arch/arm/boot/dts/msm8226-v1-qrd-evt.dts
@@ -27,3 +27,10 @@
&dsi_nt35590_720_vid {
qcom,cont-splash-enabled;
};
+
+&slim_msm {
+ tapan_codec {
+ qcom,cdc-micbias1-ext-cap;
+ qcom,cdc-micbias3-ext-cap;
+ };
+};
\ No newline at end of file
diff --git a/arch/arm/boot/dts/msm8226-v1-qrd-skuf-pvt.dts b/arch/arm/boot/dts/msm8226-v1-qrd-skuf-pvt.dts
index 43e1e21..75885a3 100644
--- a/arch/arm/boot/dts/msm8226-v1-qrd-skuf-pvt.dts
+++ b/arch/arm/boot/dts/msm8226-v1-qrd-skuf-pvt.dts
@@ -20,3 +20,9 @@
qcom,board-id = <0x2000b 2>;
};
+&slim_msm {
+ tapan_codec {
+ qcom,cdc-micbias1-ext-cap;
+ qcom,cdc-micbias3-ext-cap;
+ };
+};
\ No newline at end of file
diff --git a/arch/arm/boot/dts/msm8226-v1-qrd-skuf.dts b/arch/arm/boot/dts/msm8226-v1-qrd-skuf.dts
index b836928..d5df1d3 100644
--- a/arch/arm/boot/dts/msm8226-v1-qrd-skuf.dts
+++ b/arch/arm/boot/dts/msm8226-v1-qrd-skuf.dts
@@ -27,3 +27,10 @@
&pm8226_iadc {
qcom,rsense = <10000000>;
};
+
+&slim_msm {
+ tapan_codec {
+ qcom,cdc-micbias1-ext-cap;
+ qcom,cdc-micbias3-ext-cap;
+ };
+};
\ No newline at end of file
diff --git a/arch/arm/boot/dts/msm8226-v1.dtsi b/arch/arm/boot/dts/msm8226-v1.dtsi
index 7f2048f..b9455fb 100644
--- a/arch/arm/boot/dts/msm8226-v1.dtsi
+++ b/arch/arm/boot/dts/msm8226-v1.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -65,3 +65,63 @@
qcom,retain-periph;
qcom,retain-mem;
};
+
+&pm8226_s2 {
+ regulator-max-microvolt = <1275000>;
+};
+
+&pm8226_l3 {
+ regulator-max-microvolt = <1287500>;
+};
+
+&pm8226_l3_ao {
+ regulator-max-microvolt = <1287500>;
+};
+
+&pm8226_l3_so {
+ regulator-max-microvolt = <1287500>;
+};
+
+&apc_vreg_corner {
+ regulator-min-microvolt = <1>;
+ regulator-max-microvolt = <3>;
+ qcom,pvs-voltage-table =
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>;
+ qcom,cpr-voltage-ceiling = <1050000 1150000 1275000>;
+ qcom,cpr-voltage-floor = <1050000 1050000 1100000>;
+ qcom,cpr-step-quotient = <15>;
+ qcom,cpr-apc-volt-step = <5000>;
+ qcom,cpr-up-threshold = <0>;
+ qcom,cpr-down-threshold = <10>;
+};
diff --git a/arch/arm/boot/dts/msm8226-v2-qrd-dvt.dts b/arch/arm/boot/dts/msm8226-v2-qrd-dvt.dts
index 13402af..5fd1d3b 100644
--- a/arch/arm/boot/dts/msm8226-v2-qrd-dvt.dts
+++ b/arch/arm/boot/dts/msm8226-v2-qrd-dvt.dts
@@ -35,3 +35,10 @@
&pm8226_iadc {
qcom,rsense = <10000000>;
};
+
+&slim_msm {
+ tapan_codec {
+ qcom,cdc-micbias1-ext-cap;
+ qcom,cdc-micbias3-ext-cap;
+ };
+};
\ No newline at end of file
diff --git a/arch/arm/boot/dts/msm8226-v2-qrd-evt.dts b/arch/arm/boot/dts/msm8226-v2-qrd-evt.dts
index b707d1c..fedbb9a 100644
--- a/arch/arm/boot/dts/msm8226-v2-qrd-evt.dts
+++ b/arch/arm/boot/dts/msm8226-v2-qrd-evt.dts
@@ -27,3 +27,10 @@
&dsi_nt35590_720_vid {
qcom,cont-splash-enabled;
};
+
+&slim_msm {
+ tapan_codec {
+ qcom,cdc-micbias1-ext-cap;
+ qcom,cdc-micbias3-ext-cap;
+ };
+};
\ No newline at end of file
diff --git a/arch/arm/boot/dts/msm8226-v2-qrd-pvt.dts b/arch/arm/boot/dts/msm8226-v2-qrd-pvt.dts
index 4b6a1da..e78f24c 100644
--- a/arch/arm/boot/dts/msm8226-v2-qrd-pvt.dts
+++ b/arch/arm/boot/dts/msm8226-v2-qrd-pvt.dts
@@ -27,3 +27,10 @@
&dsi_nt35590_720_vid {
qcom,cont-splash-enabled;
};
+
+&slim_msm {
+ tapan_codec {
+ qcom,cdc-micbias1-ext-cap;
+ qcom,cdc-micbias3-ext-cap;
+ };
+};
\ No newline at end of file
diff --git a/arch/arm/boot/dts/msm8226-v2-qrd-skuf-pvt.dts b/arch/arm/boot/dts/msm8226-v2-qrd-skuf-pvt.dts
index f5ac301..ad1d077 100644
--- a/arch/arm/boot/dts/msm8226-v2-qrd-skuf-pvt.dts
+++ b/arch/arm/boot/dts/msm8226-v2-qrd-skuf-pvt.dts
@@ -20,3 +20,9 @@
qcom,board-id = <0x2000b 0x2>;
};
+&slim_msm {
+ tapan_codec {
+ qcom,cdc-micbias1-ext-cap;
+ qcom,cdc-micbias3-ext-cap;
+ };
+};
\ No newline at end of file
diff --git a/arch/arm/boot/dts/msm8226-v2-qrd-skuf.dts b/arch/arm/boot/dts/msm8226-v2-qrd-skuf.dts
index 9aa12f6..be6fb69 100644
--- a/arch/arm/boot/dts/msm8226-v2-qrd-skuf.dts
+++ b/arch/arm/boot/dts/msm8226-v2-qrd-skuf.dts
@@ -27,3 +27,10 @@
&pm8226_iadc {
qcom,rsense = <10000000>;
};
+
+&slim_msm {
+ tapan_codec {
+ qcom,cdc-micbias1-ext-cap;
+ qcom,cdc-micbias3-ext-cap;
+ };
+};
\ No newline at end of file
diff --git a/arch/arm/boot/dts/msm8226-v2.dtsi b/arch/arm/boot/dts/msm8226-v2.dtsi
index 5a670c2..6215740 100644
--- a/arch/arm/boot/dts/msm8226-v2.dtsi
+++ b/arch/arm/boot/dts/msm8226-v2.dtsi
@@ -31,41 +31,20 @@
<223 0x20000>;
};
-&pm8226_l3 {
- regulator-min-microvolt = <750000>;
- regulator-max-microvolt = <1337500>;
-};
-
-&pm8226_l3_ao {
- regulator-min-microvolt = <750000>;
- regulator-max-microvolt = <1337500>;
-};
-
-&pm8226_l3_so {
- regulator-min-microvolt = <750000>;
- regulator-max-microvolt = <1337500>;
-};
-
-&pm8226_s2 {
- regulator-min-microvolt = <900000>;
- regulator-max-microvolt = <1330000>;
-};
-
&apc_vreg_corner {
- qcom,pvs-init-voltage = <1330000 1330000 1330000 1320000 1310000
- 1300000 1290000 1280000 1270000 1260000
- 1250000 1240000 1230000 1220000 1210000
- 1200000 1190000 1180000 1170000 1160000
- 1150000 1140000 1140000 1140000 1140000
- 1140000 1140000 1140000 1140000 1140000
- 1140000 1140000>;
- qcom,pvs-corner-ceiling-slow = <1050000 1150000 1280000>;
- qcom,pvs-corner-ceiling-nom = <1050000 1080000 1200000>;
- qcom,pvs-corner-ceiling-fast = <1050000 1050000 1100000>;
- qcom,cpr-step-quotient = <30>;
+ regulator-min-microvolt = <1>;
+ regulator-max-microvolt = <14>;
qcom,cpr-up-threshold = <0>;
qcom,cpr-down-threshold = <5>;
- qcom,cpr-apc-volt-step = <10000>;
+ qcom,cpr-corner-map = <1 1 2 2 3 3 3 3 3 3 3 3 3 3>;
+ qcom,cpr-quot-adjust-table =
+ <1 5 450>,
+ <1 6 375>,
+ <1 7 300>,
+ <1 8 225>,
+ <1 9 187>,
+ <1 10 150>,
+ <1 11 75>;
};
&msm_gpu {
@@ -78,6 +57,11 @@
reg = <0xf9011050 0x8>,
<0xfc4b80b0 0x8>;
reg-names = "rcg-base", "efuse";
+ qcom,speed0-bin-v0 =
+ < 0 0>,
+ < 384000000 2>,
+ < 787200000 4>,
+ <1190400000 7>;
qcom,speed0-bin-v2 =
< 0 0>,
< 384000000 2>,
diff --git a/arch/arm/boot/dts/msm8226.dtsi b/arch/arm/boot/dts/msm8226.dtsi
index e7d8a4d..5d9db55 100644
--- a/arch/arm/boot/dts/msm8226.dtsi
+++ b/arch/arm/boot/dts/msm8226.dtsi
@@ -1013,9 +1013,9 @@
clock-names = "clk-4", "clk-5";
qcom,speed0-bin-v0 =
< 0 0>,
- < 384000000 2>,
- < 787200000 4>,
- <1190400000 7>;
+ < 384000000 1>,
+ < 787200000 2>,
+ <1190400000 3>;
cpu-vdd-supply = <&apc_vreg_corner>;
};
diff --git a/arch/arm/boot/dts/msm8610-regulator.dtsi b/arch/arm/boot/dts/msm8610-regulator.dtsi
index 30c557d..6639668 100644
--- a/arch/arm/boot/dts/msm8610-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8610-regulator.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -42,16 +42,41 @@
qcom,pvs-fuse = <23 6 5 1>;
qcom,pvs-fuse-redun = <61 47 5 1>;
- qcom,pvs-init-voltage = <1275000 1275000 1275000 1275000 1275000
- 1275000 1275000 1275000 1275000 1275000
- 1275000 1275000 1275000 1275000 1275000
- 1275000 1275000 1275000 1275000 1275000
- 1275000 1275000 1275000 1275000 1275000
- 1275000 1275000 1275000 1275000 1275000
- 1275000 1275000>;
- qcom,pvs-corner-ceiling-slow = <1050000 1150000 1275000>;
- qcom,pvs-corner-ceiling-nom = <1050000 1075000 1275000>;
- qcom,pvs-corner-ceiling-fast = <1050000 1050000 1275000>;
+ qcom,pvs-voltage-table =
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>,
+ <1050000 1150000 1275000>;
+ qcom,cpr-voltage-ceiling = <1050000 1150000 1275000>;
+ qcom,cpr-voltage-floor = <1050000 1050000 1275000>;
vdd-apc-supply = <&pm8110_s2>;
vdd-mx-supply = <&pm8110_l3_ao>;
diff --git a/arch/arm/boot/dts/msm8926-v2.dtsi b/arch/arm/boot/dts/msm8926-v2.dtsi
index 9d0c6db..1322573 100644
--- a/arch/arm/boot/dts/msm8926-v2.dtsi
+++ b/arch/arm/boot/dts/msm8926-v2.dtsi
@@ -80,6 +80,13 @@
&apc_vreg_corner {
/delete-property/ qcom,cpr-enable;
+ /delete-property/ qcom,cpr-fuse-cond-min-volt-sel;
+ /delete-property/ qcom,cpr-cond-min-voltage;
+ /delete-property/ qcom,cpr-fuse-uplift-sel;
+ /delete-property/ qcom,cpr-uplift-voltage;
+ /delete-property/ qcom,cpr-uplift-quotient;
+ /delete-property/ qcom,cpr-uplift-max-volt;
+ /delete-property/ qcom,cpr-uplift-speed-bin;
qcom,vdd-mx-vmax = <1287500>;
qcom,vdd-mx-vmin-method = <4>;
qcom,vdd-mx-corner-map = <1050000 1150000 1280000>;
diff --git a/arch/arm/boot/dts/msm8926.dtsi b/arch/arm/boot/dts/msm8926.dtsi
index c274d9f..d6619a7 100644
--- a/arch/arm/boot/dts/msm8926.dtsi
+++ b/arch/arm/boot/dts/msm8926.dtsi
@@ -39,6 +39,11 @@
reg = <0xf9011050 0x8>,
<0xfc4b80b0 0x8>;
reg-names = "rcg-base", "efuse";
+ qcom,speed0-bin-v0 =
+ < 0 0>,
+ < 384000000 2>,
+ < 787200000 4>,
+ <1190400000 7>;
qcom,speed0-bin-v1 =
< 0 0>,
< 384000000 2>,
@@ -127,41 +132,20 @@
};
};
-&pm8226_l3 {
- regulator-min-microvolt = <750000>;
- regulator-max-microvolt = <1350000>;
-};
-
-&pm8226_l3_ao {
- regulator-min-microvolt = <750000>;
- regulator-max-microvolt = <1350000>;
-};
-
-&pm8226_l3_so {
- regulator-min-microvolt = <750000>;
- regulator-max-microvolt = <1350000>;
-};
-
-&pm8226_s2 {
- regulator-min-microvolt = <900000>;
- regulator-max-microvolt = <1350000>;
-};
-
&apc_vreg_corner {
- qcom,pvs-init-voltage = <1350000 1340000 1330000 1320000 1310000
- 1300000 1290000 1280000 1270000 1260000
- 1250000 1240000 1230000 1220000 1210000
- 1200000 1190000 1180000 1170000 1160000
- 1150000 1140000 1140000 1140000 1140000
- 1140000 1140000 1140000 1140000 1140000
- 1140000 1140000>;
- qcom,pvs-corner-ceiling-slow = <1050000 1150000 1280000>;
- qcom,pvs-corner-ceiling-nom = <1050000 1080000 1200000>;
- qcom,pvs-corner-ceiling-fast = <1050000 1050000 1100000>;
- qcom,cpr-step-quotient = <30>;
qcom,cpr-up-threshold = <0>;
qcom,cpr-down-threshold = <2>;
- qcom,cpr-apc-volt-step = <10000>;
+ regulator-min-microvolt = <1>;
+ regulator-max-microvolt = <14>;
+ qcom,cpr-corner-map = <1 1 2 2 3 3 3 3 3 3 3 3 3 3>;
+ qcom,cpr-quot-adjust-table =
+ <1 5 450>,
+ <1 6 375>,
+ <1 7 300>,
+ <1 8 225>,
+ <1 9 187>,
+ <1 10 150>,
+ <1 11 75>;
qcom,cpr-quotient-adjustment = <0 72 72>;
};
diff --git a/arch/arm/boot/dts/msm8974-cdp.dtsi b/arch/arm/boot/dts/msm8974-cdp.dtsi
index da6d018..3b4c881 100644
--- a/arch/arm/boot/dts/msm8974-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8974-cdp.dtsi
@@ -766,3 +766,26 @@
&dsi_jdi_1080_vid {
qcom,cont-splash-enabled;
};
+
+&dsi_dual_jdi_video_0 {
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_pwm";
+ qcom,mdss-dsi-bl-pmic-pwm-frequency = <100>;
+ qcom,mdss-dsi-bl-pmic-bank-select = <7>;
+ qcom,cont-splash-enabled;
+};
+
+&dsi_dual_jdi_video_1 {
+ qcom,cont-splash-enabled;
+};
+
+&dsi_dual_jdi_cmd_0 {
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_pwm";
+ qcom,mdss-dsi-bl-pmic-pwm-frequency = <100>;
+ qcom,mdss-dsi-bl-pmic-bank-select = <7>;
+ qcom,cont-splash-enabled;
+};
+
+&dsi_dual_jdi_cmd_1 {
+ qcom,cont-splash-enabled;
+};
+
diff --git a/arch/arm/boot/dts/msm8974-mdss-panels.dtsi b/arch/arm/boot/dts/msm8974-mdss-panels.dtsi
index d405bf8..c11ef0a 100644
--- a/arch/arm/boot/dts/msm8974-mdss-panels.dtsi
+++ b/arch/arm/boot/dts/msm8974-mdss-panels.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -15,3 +15,7 @@
/include/ "dsi-panel-sharp-qhd-video.dtsi"
/include/ "dsi-panel-generic-720p-cmd.dtsi"
/include/ "dsi-panel-jdi-1080p-video.dtsi"
+/include/ "dsi-panel-jdi-dualmipi0-video.dtsi"
+/include/ "dsi-panel-jdi-dualmipi1-video.dtsi"
+/include/ "dsi-panel-jdi-dualmipi0-cmd.dtsi"
+/include/ "dsi-panel-jdi-dualmipi1-cmd.dtsi"
diff --git a/arch/arm/boot/dts/msm8974-mdss.dtsi b/arch/arm/boot/dts/msm8974-mdss.dtsi
index 89f4af8..7f63234 100644
--- a/arch/arm/boot/dts/msm8974-mdss.dtsi
+++ b/arch/arm/boot/dts/msm8974-mdss.dtsi
@@ -175,6 +175,47 @@
vdda-supply = <&pm8941_l2>;
qcom,mdss-fb-map = <&mdss_fb0>;
qcom,mdss-mdp = <&mdss_mdp>;
+ qcom,platform-strength-ctrl = [ff 06];
+ qcom,platform-bist-ctrl = [00 00 b1 ff 00 00];
+ qcom,platform-regulator-settings = [07 09 03 00 20 00 01];
+ qcom,platform-lane-config = [00 00 00 00 00 00 00 01 97
+ 00 00 00 00 05 00 00 01 97
+ 00 00 00 00 0a 00 00 01 97
+ 00 00 00 00 0f 00 00 01 97
+ 00 c0 00 00 00 00 00 01 bb];
+ qcom,platform-supply-entry1 {
+ qcom,supply-name = "vdd";
+ qcom,supply-min-voltage = <3000000>;
+ qcom,supply-max-voltage = <3000000>;
+ qcom,supply-enable-load = <100000>;
+ qcom,supply-disable-load = <100>;
+ qcom,supply-pre-on-sleep = <0>;
+ qcom,supply-post-on-sleep = <20>;
+ qcom,supply-pre-off-sleep = <0>;
+ qcom,supply-post-off-sleep = <0>;
+ };
+ qcom,platform-supply-entry2 {
+ qcom,supply-name = "vddio";
+ qcom,supply-min-voltage = <1800000>;
+ qcom,supply-max-voltage = <1800000>;
+ qcom,supply-enable-load = <100000>;
+ qcom,supply-disable-load = <100>;
+ qcom,supply-pre-on-sleep = <0>;
+ qcom,supply-post-on-sleep = <20>;
+ qcom,supply-pre-off-sleep = <0>;
+ qcom,supply-post-off-sleep = <0>;
+ };
+ qcom,platform-supply-entry3 {
+ qcom,supply-name = "vdda";
+ qcom,supply-min-voltage = <1200000>;
+ qcom,supply-max-voltage = <1200000>;
+ qcom,supply-enable-load = <100000>;
+ qcom,supply-disable-load = <100>;
+ qcom,supply-pre-on-sleep = <0>;
+ qcom,supply-post-on-sleep = <0>;
+ qcom,supply-pre-off-sleep = <0>;
+ qcom,supply-post-off-sleep = <0>;
+ };
};
mdss_hdmi_tx: qcom,hdmi_tx@fd922100 {
diff --git a/arch/arm/mach-msm/clock-8610.c b/arch/arm/mach-msm/clock-8610.c
index d68762a..8bd3bb5 100644
--- a/arch/arm/mach-msm/clock-8610.c
+++ b/arch/arm/mach-msm/clock-8610.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -3029,15 +3029,19 @@
/* MM sensor clocks */
CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "6-006f"),
CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "6-0034"),
+ CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "6-0001"),
CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "6-007d"),
CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "6-006d"),
+ CLK_LOOKUP("cam_src_clk", mclk1_clk_src.c, "6-0002"),
CLK_LOOKUP("cam_src_clk", mclk1_clk_src.c, "6-0078"),
CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "6-0020"),
CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "6-006a"),
CLK_LOOKUP("cam_clk", mclk0_clk.c, "6-006f"),
CLK_LOOKUP("cam_clk", mclk0_clk.c, "6-0034"),
+ CLK_LOOKUP("cam_clk", mclk0_clk.c, "6-0001"),
CLK_LOOKUP("cam_clk", mclk0_clk.c, "6-007d"),
CLK_LOOKUP("cam_clk", mclk0_clk.c, "6-006d"),
+ CLK_LOOKUP("cam_clk", mclk1_clk.c, "6-0002"),
CLK_LOOKUP("cam_clk", mclk1_clk.c, "6-0078"),
CLK_LOOKUP("cam_clk", mclk0_clk.c, "6-0020"),
CLK_LOOKUP("cam_clk", mclk0_clk.c, "6-006a"),
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index e8d1627..acfbfc7 100755
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -1546,7 +1546,7 @@
},
};
-/* This table is for MSM8974Pro AC SDCC1 */
+/* For MSM8974Pro SDCC1 */
static struct clk_freq_tbl ftbl_gcc_sdcc1_apps_clk_ac[] = {
F( 144000, cxo, 16, 3, 25),
F( 400000, cxo, 12, 1, 4),
@@ -1559,11 +1559,7 @@
F_END
};
-/*
- * This table is for:
- * 1) SDCC[1-4] on MSM8974Pro AB, MSM8974 v2 and before
- * 2) SDCC[2-4] on MSM8974Pro AC
- */
+/* For SDCC1 on MSM8974 v2 and SDCC[2-4] on all MSM8974 */
static struct clk_freq_tbl ftbl_gcc_sdcc1_4_apps_clk[] = {
F( 144000, cxo, 16, 3, 25),
F( 400000, cxo, 12, 1, 4),
@@ -5790,11 +5786,9 @@
ce2_clk_src.c.fmax[VDD_DIG_NOMINAL] = 150000000;
ce2_clk_src.freq_tbl = ftbl_gcc_ce2_pro_clk;
- if (cpu_is_msm8974pro_ac()) {
- sdcc1_apps_clk_src.c.fmax[VDD_DIG_LOW] = 200000000;
- sdcc1_apps_clk_src.c.fmax[VDD_DIG_NOMINAL] = 400000000;
- sdcc1_apps_clk_src.freq_tbl = ftbl_gcc_sdcc1_apps_clk_ac;
- }
+ sdcc1_apps_clk_src.c.fmax[VDD_DIG_LOW] = 200000000;
+ sdcc1_apps_clk_src.c.fmax[VDD_DIG_NOMINAL] = 400000000;
+ sdcc1_apps_clk_src.freq_tbl = ftbl_gcc_sdcc1_apps_clk_ac;
vfe0_clk_src.c.fmax[VDD_DIG_LOW] = 150000000;
vfe0_clk_src.c.fmax[VDD_DIG_NOMINAL] = 320000000;
diff --git a/arch/arm/mach-msm/cpr-regulator.c b/arch/arm/mach-msm/cpr-regulator.c
index c245079..8c26964 100644
--- a/arch/arm/mach-msm/cpr-regulator.c
+++ b/arch/arm/mach-msm/cpr-regulator.c
@@ -166,11 +166,9 @@
void __iomem *efuse_base;
/* Process voltage parameters */
- u32 pvs_init_v[CPR_PVS_EFUSE_BINS_MAX];
- u32 pvs_corner_v[NUM_APC_PVS][CPR_FUSE_CORNER_MAX];
+ u32 pvs_corner_v[CPR_FUSE_CORNER_MAX];
/* Process voltage variables */
u32 pvs_bin;
- u32 process;
u32 speed_bin;
/* APC voltage regulator */
struct regulator *vdd_apc;
@@ -495,8 +493,7 @@
vdd_mx = cpr_vreg->ceiling_volt[fuse_corner];
break;
case VDD_MX_VMIN_APC_SLOW_CORNER_CEILING:
- vdd_mx = cpr_vreg->pvs_corner_v[APC_PVS_SLOW]
- [CPR_FUSE_CORNER_TURBO];
+ vdd_mx = cpr_vreg->ceiling_volt[CPR_FUSE_CORNER_TURBO];
break;
case VDD_MX_VMIN_MX_VMAX:
vdd_mx = cpr_vreg->vdd_mx_vmax;
@@ -842,8 +839,7 @@
cpr_ctl_disable(cpr_vreg);
new_volt = cpr_vreg->last_volt[corner];
} else {
- new_volt = cpr_vreg->pvs_corner_v
- [cpr_vreg->process][fuse_corner];
+ new_volt = cpr_vreg->pvs_corner_v[fuse_corner];
}
cpr_debug("[corner:%d, fuse_corner:%d] = %d uV\n", corner, fuse_corner,
@@ -1067,7 +1063,7 @@
{
u32 uplift_voltage;
u32 uplift_max_volt = 0;
- int rc, i;
+ int rc;
rc = of_property_read_u32(of_node,
"qcom,cpr-uplift-voltage", &uplift_voltage);
@@ -1082,11 +1078,9 @@
return rc;
}
- for (i = 0; i < CPR_PVS_EFUSE_BINS_MAX; i++) {
- cpr_vreg->pvs_init_v[i] += uplift_voltage;
- if (cpr_vreg->pvs_init_v[i] > uplift_max_volt)
- cpr_vreg->pvs_init_v[i] = uplift_max_volt;
- }
+ cpr_vreg->pvs_corner_v[CPR_FUSE_CORNER_TURBO] += uplift_voltage;
+ if (cpr_vreg->pvs_corner_v[CPR_FUSE_CORNER_TURBO] > uplift_max_volt)
+ cpr_vreg->pvs_corner_v[CPR_FUSE_CORNER_TURBO] = uplift_max_volt;
return rc;
}
@@ -1096,11 +1090,11 @@
{
struct device_node *of_node = pdev->dev.of_node;
u64 efuse_bits;
- int rc, process;
+ int rc, i, stripe_size;
u32 pvs_fuse[4], pvs_fuse_redun_sel[5];
- u32 init_v;
bool redundant;
size_t pvs_bins;
+ u32 *tmp;
rc = of_property_read_u32_array(of_node, "qcom,pvs-fuse-redun-sel",
pvs_fuse_redun_sel, 5);
@@ -1135,13 +1129,26 @@
pvs_bins = 1 << pvs_fuse[2];
- rc = of_property_read_u32_array(of_node, "qcom,pvs-init-voltage",
- cpr_vreg->pvs_init_v, pvs_bins);
+ stripe_size = CPR_FUSE_CORNER_MAX - 1;
+ tmp = kzalloc(sizeof(u32) * pvs_bins * stripe_size, GFP_KERNEL);
+ if (!tmp) {
+ pr_err("memory alloc failed\n");
+ return -ENOMEM;
+ }
+
+ rc = of_property_read_u32_array(of_node, "qcom,pvs-voltage-table",
+ tmp, pvs_bins * stripe_size);
if (rc < 0) {
- pr_err("pvs-init-voltage missing: rc=%d\n", rc);
+ pr_err("pvs-voltage-table missing: rc=%d\n", rc);
+ kfree(tmp);
return rc;
}
+ for (i = CPR_FUSE_CORNER_SVS; i < CPR_FUSE_CORNER_MAX; i++)
+ cpr_vreg->pvs_corner_v[i] = tmp[cpr_vreg->pvs_bin *
+ stripe_size + i - 1];
+ kfree(tmp);
+
if (cpr_vreg->flags & FLAGS_UPLIFT_QUOT_VOLT) {
rc = cpr_voltage_uplift_wa_inc_volt(cpr_vreg, of_node);
if (rc < 0) {
@@ -1150,30 +1157,31 @@
}
}
- init_v = cpr_vreg->pvs_init_v[cpr_vreg->pvs_bin];
- for (process = NUM_APC_PVS - 1; process > APC_PVS_NO; process--) {
- if (init_v <= cpr_vreg->pvs_corner_v
- [process][CPR_FUSE_CORNER_TURBO])
- break;
- }
+ if (cpr_vreg->pvs_corner_v[CPR_FUSE_CORNER_TURBO] >
+ cpr_vreg->ceiling_volt[CPR_FUSE_CORNER_TURBO])
+ cpr_vreg->ceiling_volt[CPR_FUSE_CORNER_TURBO] =
+ cpr_vreg->pvs_corner_v[CPR_FUSE_CORNER_TURBO];
- if (process == APC_PVS_NO) {
- process = APC_PVS_SLOW;
- cpr_vreg->pvs_corner_v[process][CPR_FUSE_CORNER_TURBO] = init_v;
- cpr_vreg->ceiling_max = init_v;
- } else if (process == APC_PVS_FAST &&
- init_v < cpr_vreg->pvs_corner_v
- [APC_PVS_FAST][CPR_FUSE_CORNER_SVS]) {
- process = APC_PVS_SLOW;
- }
+ for (i = CPR_FUSE_CORNER_SVS; i < CPR_FUSE_CORNER_TURBO; i++)
+ if (cpr_vreg->pvs_corner_v[i] > cpr_vreg->ceiling_volt[i])
+ cpr_vreg->pvs_corner_v[i] = cpr_vreg->ceiling_volt[i];
+ else if (cpr_vreg->pvs_corner_v[i] < cpr_vreg->floor_volt[i])
+ cpr_vreg->pvs_corner_v[i] = cpr_vreg->floor_volt[i];
- pr_info("[row:%d] = 0x%llX, n_bits=%d, bin=%d (%d)",
- pvs_fuse[0], efuse_bits, pvs_fuse[2],
- cpr_vreg->pvs_bin, process);
- pr_info("pvs initial turbo voltage_= from %u to %u\n",
- init_v, cpr_vreg->pvs_corner_v[process][CPR_FUSE_CORNER_TURBO]);
+ cpr_vreg->ceiling_max = cpr_vreg->ceiling_volt[CPR_FUSE_CORNER_TURBO];
- cpr_vreg->process = process;
+ pr_info("pvs voltage: [%d %d %d] uV\n",
+ cpr_vreg->pvs_corner_v[CPR_FUSE_CORNER_SVS],
+ cpr_vreg->pvs_corner_v[CPR_FUSE_CORNER_NORMAL],
+ cpr_vreg->pvs_corner_v[CPR_FUSE_CORNER_TURBO]);
+ pr_info("ceiling voltage: [%d %d %d] uV\n",
+ cpr_vreg->ceiling_volt[CPR_FUSE_CORNER_SVS],
+ cpr_vreg->ceiling_volt[CPR_FUSE_CORNER_NORMAL],
+ cpr_vreg->ceiling_volt[CPR_FUSE_CORNER_TURBO]);
+ pr_info("floor voltage: [%d %d %d] uV\n",
+ cpr_vreg->floor_volt[CPR_FUSE_CORNER_SVS],
+ cpr_vreg->floor_volt[CPR_FUSE_CORNER_NORMAL],
+ cpr_vreg->floor_volt[CPR_FUSE_CORNER_TURBO]);
return 0;
}
@@ -1571,17 +1579,9 @@
if (!cpr_vreg->last_volt)
return -EINVAL;
- /* Construct CPR voltage limits */
- for (i = CPR_FUSE_CORNER_SVS; i < CPR_FUSE_CORNER_MAX; i++) {
- cpr_vreg->floor_volt[i] =
- cpr_vreg->pvs_corner_v[APC_PVS_FAST][i];
- cpr_vreg->ceiling_volt[i] =
- cpr_vreg->pvs_corner_v[APC_PVS_SLOW][i];
- }
-
for (i = 1; i < size; i++) {
cpr_vreg->last_volt[i] = cpr_vreg->pvs_corner_v
- [cpr_vreg->process][cpr_vreg->corner_map[i]];
+ [cpr_vreg->corner_map[i]];
}
return 0;
@@ -1818,33 +1818,22 @@
struct cpr_regulator *cpr_vreg)
{
struct device_node *of_node = pdev->dev.of_node;
- int rc, i, j;
+ int rc, i;
u32 min_uv = 0;
- rc = of_property_read_u32_array(of_node,
- "qcom,pvs-corner-ceiling-slow",
- &cpr_vreg->pvs_corner_v[APC_PVS_SLOW][CPR_FUSE_CORNER_SVS],
- CPR_FUSE_CORNER_MAX - CPR_FUSE_CORNER_SVS);
+ rc = of_property_read_u32_array(of_node, "qcom,cpr-voltage-ceiling",
+ &cpr_vreg->ceiling_volt[CPR_FUSE_CORNER_SVS],
+ CPR_FUSE_CORNER_MAX - 1);
if (rc < 0) {
- pr_err("pvs-corner-ceiling-slow missing: rc=%d\n", rc);
+ pr_err("cpr-voltage-ceiling missing: rc=%d\n", rc);
return rc;
}
- rc = of_property_read_u32_array(of_node,
- "qcom,pvs-corner-ceiling-nom",
- &cpr_vreg->pvs_corner_v[APC_PVS_NOM][CPR_FUSE_CORNER_SVS],
- CPR_FUSE_CORNER_MAX - CPR_FUSE_CORNER_SVS);
+ rc = of_property_read_u32_array(of_node, "qcom,cpr-voltage-floor",
+ &cpr_vreg->floor_volt[CPR_FUSE_CORNER_SVS],
+ CPR_FUSE_CORNER_MAX - 1);
if (rc < 0) {
- pr_err("pvs-corner-ceiling-norm missing: rc=%d\n", rc);
- return rc;
- }
-
- rc = of_property_read_u32_array(of_node,
- "qcom,pvs-corner-ceiling-fast",
- &cpr_vreg->pvs_corner_v[APC_PVS_FAST][CPR_FUSE_CORNER_SVS],
- CPR_FUSE_CORNER_MAX - CPR_FUSE_CORNER_SVS);
- if (rc < 0) {
- pr_err("pvs-corner-ceiling-fast missing: rc=%d\n", rc);
+ pr_err("cpr-voltage-floor missing: rc=%d\n", rc);
return rc;
}
@@ -1858,22 +1847,13 @@
if (cpr_vreg->flags & FLAGS_SET_MIN_VOLTAGE) {
of_property_read_u32(of_node, "qcom,cpr-cond-min-voltage",
&min_uv);
- for (i = APC_PVS_SLOW; i < NUM_APC_PVS; i++)
- for (j = CPR_FUSE_CORNER_SVS; j < CPR_FUSE_CORNER_MAX;
- j++)
- if (cpr_vreg->pvs_corner_v[i][j] < min_uv)
- cpr_vreg->pvs_corner_v[i][j] = min_uv;
- }
-
- /* Set ceiling max and use it for APC_PVS_NO */
- cpr_vreg->ceiling_max =
- cpr_vreg->pvs_corner_v[APC_PVS_SLOW][CPR_FUSE_CORNER_TURBO];
-
- for (i = APC_PVS_SLOW; i < NUM_APC_PVS; i++) {
- pr_info("[%d] [%d %d %d] uV\n", i,
- cpr_vreg->pvs_corner_v[i][CPR_FUSE_CORNER_SVS],
- cpr_vreg->pvs_corner_v[i][CPR_FUSE_CORNER_NORMAL],
- cpr_vreg->pvs_corner_v[i][CPR_FUSE_CORNER_TURBO]);
+ for (i = CPR_FUSE_CORNER_SVS; i < CPR_FUSE_CORNER_MAX; i++)
+ if (cpr_vreg->ceiling_volt[i] < min_uv) {
+ cpr_vreg->ceiling_volt[i] = min_uv;
+ cpr_vreg->floor_volt[i] = min_uv;
+ } else if (cpr_vreg->floor_volt[i] < min_uv) {
+ cpr_vreg->floor_volt[i] = min_uv;
+ }
}
return 0;
diff --git a/arch/arm/mach-msm/cpufreq.c b/arch/arm/mach-msm/cpufreq.c
index f1904de..c81720e 100644
--- a/arch/arm/mach-msm/cpufreq.c
+++ b/arch/arm/mach-msm/cpufreq.c
@@ -228,6 +228,9 @@
static unsigned int msm_cpufreq_get_freq(unsigned int cpu)
{
+ if (is_clk && is_sync)
+ cpu = 0;
+
if (is_clk)
return clk_get_rate(cpu_clk[cpu]) / 1000;
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index 47c07ff..89e3b51 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -183,7 +183,8 @@
};
struct msm_camera_gpio_num_info {
- uint16_t gpio_num[7];
+ uint16_t gpio_num[10];
+ uint8_t valid[10];
};
struct msm_camera_gpio_conf {
diff --git a/arch/arm/mach-msm/include/mach/camera2.h b/arch/arm/mach-msm/include/mach/camera2.h
index 7174d88..0ce5213 100644
--- a/arch/arm/mach-msm/include/mach/camera2.h
+++ b/arch/arm/mach-msm/include/mach/camera2.h
@@ -66,6 +66,8 @@
struct device *dev;
struct msm_sensor_power_setting *power_setting;
uint16_t power_setting_size;
+ struct msm_sensor_power_setting *power_down_setting;
+ uint16_t power_down_setting_size;
struct msm_camera_gpio_conf *gpio_conf;
struct camera_vreg_t *cam_vreg;
int num_vreg;
@@ -76,6 +78,8 @@
struct msm_camera_sensor_board_info {
const char *sensor_name;
+ const char *eeprom_name;
+ const char *actuator_name;
struct msm_camera_slave_info *slave_info;
struct msm_camera_csi_lane_params *csi_lane_params;
struct msm_camera_sensor_strobe_flash_data *strobe_flash_data;
@@ -83,6 +87,7 @@
struct msm_sensor_info_t *sensor_info;
const char *misc_regulator;
struct msm_camera_power_ctrl_t power_info;
+ struct msm_camera_sensor_slave_info *cam_slave_info;
};
enum msm_camera_i2c_cmd_type {
@@ -128,10 +133,18 @@
uint32_t num_data; /* size of total mapdata */
};
+struct msm_eeprom_mm_t {
+ uint32_t mm_support;
+ uint32_t mm_compression;
+ uint32_t mm_offset;
+ uint32_t mm_size;
+};
+
struct msm_eeprom_board_info {
const char *eeprom_name;
uint16_t i2c_slaveaddr;
struct msm_camera_power_ctrl_t power_info;
+ struct msm_eeprom_mm_t mm_data;
};
#endif
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index 6f9eb94..4f39838 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -139,7 +139,7 @@
unsigned int p;
for (p = 0; p < entity->num_pads; p++) {
- struct media_pad_desc pad;
+ struct media_pad_desc pad = {0};
media_device_kpad_to_upad(&entity->pads[p], &pad);
if (copy_to_user(&links.pads[p], &pad, sizeof(pad)))
return -EFAULT;
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 7347251..057e87f 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
@@ -482,7 +482,7 @@
break;
default:
- pr_err("%s: Invalid ISP command\n", __func__);
+ pr_err_ratelimited("%s: Invalid ISP command\n", __func__);
rc = -EINVAL;
}
return rc;
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 3f49f68..70042f2 100755
--- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
+++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
@@ -19,6 +19,7 @@
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/iopoll.h>
+#include <linux/ratelimit.h>
#include <media/msmb_isp.h>
#include "msm_ispif.h"
@@ -1050,7 +1051,8 @@
return 0;
}
default:
- pr_err("%s: invalid cmd 0x%x received\n", __func__, cmd);
+ pr_err_ratelimited("%s: invalid cmd 0x%x received\n",
+ __func__, cmd);
return -ENOIOCTLCMD;
}
}
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
old mode 100644
new mode 100755
index 10a0085..bba774d
--- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -823,7 +823,10 @@
/*Start firmware loading*/
msm_cpp_write(MSM_CPP_CMD_FW_LOAD, cpp_dev->base);
- msm_cpp_write(fw->size, cpp_dev->base);
+ if (fw)
+ msm_cpp_write(fw->size, cpp_dev->base);
+ else
+ msm_cpp_write(MSM_CPP_END_ADDRESS, cpp_dev->base);
msm_cpp_write(MSM_CPP_START_ADDRESS, cpp_dev->base);
if (ptr_bin) {
@@ -997,15 +1000,15 @@
static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev)
{
struct v4l2_event v4l2_evt;
- struct msm_queue_cmd *frame_qcmd;
- struct msm_queue_cmd *event_qcmd;
+ struct msm_queue_cmd *frame_qcmd = NULL;
+ struct msm_queue_cmd *event_qcmd = NULL;
struct msm_cpp_frame_info_t *processed_frame;
struct msm_device_queue *queue = &cpp_dev->processing_q;
struct msm_buf_mngr_info buff_mgr_info;
int rc = 0;
- if (queue->len > 0) {
- frame_qcmd = msm_dequeue(queue, list_frame);
+ frame_qcmd = msm_dequeue(queue, list_frame);
+ if (frame_qcmd) {
processed_frame = frame_qcmd->command;
do_gettimeofday(&(processed_frame->out_time));
kfree(frame_qcmd);
@@ -1468,6 +1471,7 @@
case VIDIOC_MSM_CPP_FLUSH_QUEUE:
rc = msm_cpp_flush_frames(cpp_dev);
break;
+ case VIDIOC_MSM_CPP_APPEND_STREAM_BUFF_INFO:
case VIDIOC_MSM_CPP_ENQUEUE_STREAM_BUFF_INFO: {
struct msm_cpp_stream_buff_info_t *u_stream_buff_info;
struct msm_cpp_stream_buff_info_t k_stream_buff_info;
@@ -1535,9 +1539,12 @@
return -EINVAL;
}
- rc = msm_cpp_add_buff_queue_entry(cpp_dev,
- ((k_stream_buff_info.identity >> 16) & 0xFFFF),
- (k_stream_buff_info.identity & 0xFFFF));
+ if (cmd != VIDIOC_MSM_CPP_APPEND_STREAM_BUFF_INFO) {
+ rc = msm_cpp_add_buff_queue_entry(cpp_dev,
+ ((k_stream_buff_info.identity >> 16) & 0xFFFF),
+ (k_stream_buff_info.identity & 0xFFFF));
+ }
+
if (!rc)
rc = msm_cpp_enqueue_buff_info_list(cpp_dev,
&k_stream_buff_info);
@@ -1583,18 +1590,23 @@
struct msm_queue_cmd *event_qcmd;
struct msm_cpp_frame_info_t *process_frame;
event_qcmd = msm_dequeue(queue, list_eventdata);
- process_frame = event_qcmd->command;
- CPP_DBG("fid %d\n", process_frame->frame_id);
- if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
- process_frame,
- sizeof(struct msm_cpp_frame_info_t))) {
- mutex_unlock(&cpp_dev->mutex);
- return -EINVAL;
- }
+ if(event_qcmd) {
+ process_frame = event_qcmd->command;
+ CPP_DBG("fid %d\n", process_frame->frame_id);
+ if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
+ process_frame,
+ sizeof(struct msm_cpp_frame_info_t))) {
+ mutex_unlock(&cpp_dev->mutex);
+ return -EINVAL;
+ }
- kfree(process_frame->cpp_cmd_msg);
- kfree(process_frame);
- kfree(event_qcmd);
+ kfree(process_frame->cpp_cmd_msg);
+ kfree(process_frame);
+ kfree(event_qcmd);
+ } else {
+ pr_err("Empty command list\n");
+ return -EFAULT;
+ }
break;
}
case MSM_SD_SHUTDOWN: {
@@ -1869,6 +1881,7 @@
rc = -ENOMEM;
goto ERROR3;
}
+
INIT_WORK((struct work_struct *)cpp_dev->work, msm_cpp_do_timeout_work);
cpp_dev->cpp_open_cnt = 0;
cpp_dev->is_firmware_loaded = 0;
diff --git a/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
index 229fdb2..981c210 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
@@ -13,6 +13,7 @@
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/ratelimit.h>
#include <linux/irqreturn.h>
#include "msm_csid.h"
#include "msm_csid_hwreg.h"
@@ -488,7 +489,7 @@
rc = msm_csid_release(csid_dev);
break;
default:
- pr_err("%s: %d failed\n", __func__, __LINE__);
+ pr_err_ratelimited("%s: %d failed\n", __func__, __LINE__);
rc = -ENOIOCTLCMD;
break;
}
diff --git a/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c
index d8608ae..9a7c057 100755
--- a/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c
@@ -15,6 +15,7 @@
#include <linux/io.h>
#include <linux/of.h>
#include <linux/module.h>
+#include <linux/ratelimit.h>
#include <linux/irqreturn.h>
#include <mach/vreg.h>
#include "msm_csiphy.h"
@@ -599,7 +600,7 @@
rc = msm_csiphy_release(csiphy_dev, &csi_lane_params);
break;
default:
- pr_err("%s: %d failed\n", __func__, __LINE__);
+ pr_err_ratelimited("%s: %d failed\n", __func__, __LINE__);
rc = -ENOIOCTLCMD;
break;
}
diff --git a/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c b/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c
index ca08530..5c0e6d5 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c
@@ -100,6 +100,17 @@
return ret;
}
+static int msm_eeprom_get_mm_data(struct msm_eeprom_ctrl_t *e_ctrl,
+ struct msm_eeprom_cfg_data *cdata)
+{
+ int rc = 0;
+ struct msm_eeprom_mm_t *mm_data = &e_ctrl->eboard_info->mm_data;
+ cdata->cfg.get_mm_data.mm_support = mm_data->mm_support;
+ cdata->cfg.get_mm_data.mm_compression = mm_data->mm_compression;
+ cdata->cfg.get_mm_data.mm_size = mm_data->mm_size;
+ return rc;
+}
+
static int eeprom_config_read_cal_data(struct msm_eeprom_ctrl_t *e_ctrl,
struct msm_eeprom_cfg_data *cdata)
{
@@ -139,7 +150,7 @@
CDBG("%s E\n", __func__);
switch (cdata->cfgtype) {
case CFG_EEPROM_GET_INFO:
- CDBG("%s E CFG_EEPROM_GET_INFO\n", __func__);
+ CDBG("%s E CFG_EEPROM_GET_INFO\n", __func__);
cdata->is_supported = e_ctrl->is_supported;
memcpy(cdata->cfg.eeprom_name,
e_ctrl->eboard_info->eeprom_name,
@@ -154,6 +165,10 @@
CDBG("%s E CFG_EEPROM_READ_CAL_DATA\n", __func__);
rc = eeprom_config_read_cal_data(e_ctrl, cdata);
break;
+ case CFG_EEPROM_GET_MM_INFO:
+ CDBG("%s E CFG_EEPROM_GET_MM_INFO\n", __func__);
+ rc = msm_eeprom_get_mm_data(e_ctrl, cdata);
+ break;
default:
break;
}
@@ -597,7 +612,7 @@
rc = msm_camera_get_dt_power_setting_data(of_node,
power_info->cam_vreg, power_info->num_vreg,
- &power_info->power_setting, &power_info->power_setting_size);
+ power_info);
if (rc < 0)
goto ERROR1;
@@ -652,6 +667,38 @@
return rc;
}
+static int msm_eeprom_mm_dts(struct msm_eeprom_board_info *eb_info,
+ struct device_node *of_node)
+{
+ int rc = 0;
+ struct msm_eeprom_mm_t *mm_data = &eb_info->mm_data;
+
+ mm_data->mm_support =
+ of_property_read_bool(of_node,"qcom,mm-data-support");
+ if (!mm_data->mm_support)
+ return -EINVAL;
+ mm_data->mm_compression =
+ of_property_read_bool(of_node,"qcom,mm-data-compressed");
+ if (!mm_data->mm_compression)
+ pr_err("No MM compression data\n");
+
+ rc = of_property_read_u32(of_node, "qcom,mm-data-offset",
+ &mm_data->mm_offset);
+ if (rc < 0)
+ pr_err("No MM offset data\n");
+
+ rc = of_property_read_u32(of_node, "qcom,mm-data-size",
+ &mm_data->mm_size);
+ if (rc < 0)
+ pr_err("No MM size data\n");
+
+ CDBG("mm_support: mm_compr %d, mm_offset %d, mm_size %d\n",
+ mm_data->mm_compression,
+ mm_data->mm_offset,
+ mm_data->mm_size);
+ return 0;
+}
+
static int msm_eeprom_spi_setup(struct spi_device *spi)
{
struct msm_eeprom_ctrl_t *e_ctrl = NULL;
@@ -704,6 +751,12 @@
pr_err("%s failed %d\n", __func__, __LINE__);
goto board_free;
}
+
+ rc = msm_eeprom_mm_dts(e_ctrl->eboard_info, spi->dev.of_node);
+ if (rc < 0) {
+ pr_err("%s MM data miss:%d\n", __func__, __LINE__);
+ }
+
power_info = &eb_info->power_info;
power_info->clk_info = cam_8974_clk_info;
@@ -941,6 +994,10 @@
goto board_free;
}
+ rc = msm_eeprom_mm_dts(e_ctrl->eboard_info, of_node);
+ if (rc < 0) {
+ pr_err("%s MM data miss:%d\n", __func__, __LINE__);
+ }
rc = msm_eeprom_get_dt_data(e_ctrl);
if (rc)
goto board_free;
diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.c b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.c
index 2de17c9..149d00c 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.c
@@ -46,7 +46,7 @@
*(int *)argp = MSM_CAMERA_LED_RELEASE;
return fctrl->func_tbl->flash_led_config(fctrl, argp);
default:
- pr_err("invalid cmd %d\n", cmd);
+ pr_err_ratelimited("invalid cmd %d\n", cmd);
return -ENOIOCTLCMD;
}
}
diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.h b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.h
index a4d7f15..87b65ca 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.h
+++ b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.h
@@ -15,6 +15,7 @@
#include <linux/leds.h>
#include <linux/platform_device.h>
+#include <linux/ratelimit.h>
#include <media/v4l2-subdev.h>
#include <media/msm_cam_sensor.h>
#include <mach/camera2.h>
diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_i2c_trigger.c b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_i2c_trigger.c
index aeed654..9cfab8f 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_i2c_trigger.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_i2c_trigger.c
@@ -117,7 +117,8 @@
}
msleep(20);
gpio_set_value_cansleep(
- power_info->gpio_conf->gpio_num_info->gpio_num[0],
+ power_info->gpio_conf->gpio_num_info->
+ gpio_num[SENSOR_GPIO_FL_EN],
GPIO_OUT_HIGH);
if (fctrl->flash_i2c_client && fctrl->reg_setting) {
@@ -145,10 +146,12 @@
return -EINVAL;
}
gpio_set_value_cansleep(
- power_info->gpio_conf->gpio_num_info->gpio_num[0],
+ power_info->gpio_conf->gpio_num_info->
+ gpio_num[SENSOR_GPIO_FL_EN],
GPIO_OUT_LOW);
gpio_set_value_cansleep(
- power_info->gpio_conf->gpio_num_info->gpio_num[1],
+ power_info->gpio_conf->gpio_num_info->
+ gpio_num[SENSOR_GPIO_FL_NOW],
GPIO_OUT_LOW);
rc = msm_camera_request_gpio_table(
power_info->gpio_conf->cam_gpio_req_tbl,
@@ -181,7 +184,8 @@
pr_err("%s:%d failed\n", __func__, __LINE__);
}
gpio_set_value_cansleep(
- power_info->gpio_conf->gpio_num_info->gpio_num[1],
+ power_info->gpio_conf->gpio_num_info->
+ gpio_num[SENSOR_GPIO_FL_NOW],
GPIO_OUT_LOW);
return rc;
@@ -197,11 +201,13 @@
flashdata = fctrl->flashdata;
power_info = &flashdata->power_info;
gpio_set_value_cansleep(
- power_info->gpio_conf->gpio_num_info->gpio_num[0],
+ power_info->gpio_conf->gpio_num_info->
+ gpio_num[SENSOR_GPIO_FL_EN],
GPIO_OUT_HIGH);
gpio_set_value_cansleep(
- power_info->gpio_conf->gpio_num_info->gpio_num[1],
+ power_info->gpio_conf->gpio_num_info->
+ gpio_num[SENSOR_GPIO_FL_NOW],
GPIO_OUT_HIGH);
@@ -226,11 +232,13 @@
flashdata = fctrl->flashdata;
power_info = &flashdata->power_info;
gpio_set_value_cansleep(
- power_info->gpio_conf->gpio_num_info->gpio_num[0],
+ power_info->gpio_conf->gpio_num_info->
+ gpio_num[SENSOR_GPIO_FL_EN],
GPIO_OUT_HIGH);
gpio_set_value_cansleep(
- power_info->gpio_conf->gpio_num_info->gpio_num[1],
+ power_info->gpio_conf->gpio_num_info->
+ gpio_num[SENSOR_GPIO_FL_NOW],
GPIO_OUT_HIGH);
if (fctrl->flash_i2c_client && fctrl->reg_setting) {
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.c
index 36f49fe..1fb113d 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.c
@@ -347,8 +347,7 @@
int msm_camera_get_dt_power_setting_data(struct device_node *of_node,
struct camera_vreg_t *cam_vreg, int num_vreg,
- struct msm_sensor_power_setting **power_setting,
- uint16_t *power_setting_size)
+ struct msm_camera_power_ctrl_t *power_info)
{
int rc = 0, i, j;
int count = 0;
@@ -356,11 +355,18 @@
uint32_t *array = NULL;
struct msm_sensor_power_setting *ps;
- if (!power_setting || !power_setting_size)
+ struct msm_sensor_power_setting *power_setting;
+ uint16_t *power_setting_size;
+
+ if (!power_info)
return -EINVAL;
+ power_setting = power_info->power_setting;
+ power_setting_size = &power_info->power_setting_size;
+
count = of_property_count_strings(of_node, "qcom,cam-power-seq-type");
*power_setting_size = count;
+
CDBG("%s qcom,cam-power-seq-type count %d\n", __func__, count);
if (count <= 0)
@@ -371,7 +377,8 @@
pr_err("%s failed %d\n", __func__, __LINE__);
return -ENOMEM;
}
- *power_setting = ps;
+ power_setting = ps;
+ power_info->power_setting = ps;
for (i = 0; i < count; i++) {
rc = of_property_read_string_index(of_node,
@@ -502,7 +509,6 @@
}
kfree(array);
return rc;
-
ERROR2:
kfree(array);
ERROR1:
@@ -706,6 +712,7 @@
}
gconf->gpio_num_info->gpio_num[SENSOR_GPIO_VDIG] =
gpio_array[val];
+ gconf->gpio_num_info->valid[SENSOR_GPIO_VDIG] = 1;
CDBG("%s qcom,gpio-reset %d\n", __func__,
gconf->gpio_num_info->gpio_num[SENSOR_GPIO_VDIG]);
}
@@ -723,6 +730,7 @@
}
gconf->gpio_num_info->gpio_num[SENSOR_GPIO_RESET] =
gpio_array[val];
+ gconf->gpio_num_info->valid[SENSOR_GPIO_RESET] = 1;
CDBG("%s qcom,gpio-reset %d\n", __func__,
gconf->gpio_num_info->gpio_num[SENSOR_GPIO_RESET]);
}
@@ -740,9 +748,47 @@
}
gconf->gpio_num_info->gpio_num[SENSOR_GPIO_STANDBY] =
gpio_array[val];
+ gconf->gpio_num_info->valid[SENSOR_GPIO_STANDBY] = 1;
CDBG("%s qcom,gpio-reset %d\n", __func__,
gconf->gpio_num_info->gpio_num[SENSOR_GPIO_STANDBY]);
}
+
+ if (of_property_read_bool(of_node, "qcom,gpio-flash-en") == true) {
+ rc = of_property_read_u32(of_node, "qcom,gpio-flash-en", &val);
+ if (rc < 0) {
+ pr_err("%s:%d read qcom,gpio-flash-en failed rc %d\n",
+ __func__, __LINE__, rc);
+ goto ERROR;
+ } else if (val >= gpio_array_size) {
+ pr_err("%s:%d qcom,gpio-flash-en invalid %d\n",
+ __func__, __LINE__, val);
+ goto ERROR;
+ }
+ gconf->gpio_num_info->gpio_num[SENSOR_GPIO_FL_EN] =
+ gpio_array[val];
+ gconf->gpio_num_info->valid[SENSOR_GPIO_FL_EN] = 1;
+ CDBG("%s qcom,gpio-flash-en %d\n", __func__,
+ gconf->gpio_num_info->gpio_num[SENSOR_GPIO_FL_EN]);
+ }
+
+ if (of_property_read_bool(of_node, "qcom,gpio-flash-now") == true) {
+ rc = of_property_read_u32(of_node, "qcom,gpio-flash-now", &val);
+ if (rc < 0) {
+ pr_err("%s:%d read qcom,gpio-flash-now failed rc %d\n",
+ __func__, __LINE__, rc);
+ goto ERROR;
+ } else if (val >= gpio_array_size) {
+ pr_err("%s:%d qcom,gpio-flash-now invalid %d\n",
+ __func__, __LINE__, val);
+ goto ERROR;
+ }
+ gconf->gpio_num_info->gpio_num[SENSOR_GPIO_FL_NOW] =
+ gpio_array[val];
+ gconf->gpio_num_info->valid[SENSOR_GPIO_FL_NOW] = 1;
+ CDBG("%s qcom,gpio-flash-now %d\n", __func__,
+ gconf->gpio_num_info->gpio_num[SENSOR_GPIO_FL_NOW]);
+ }
+
return rc;
ERROR:
@@ -935,6 +981,9 @@
SENSOR_GPIO_MAX);
goto power_up_failed;
}
+ if (!ctrl->gpio_conf->gpio_num_info->valid
+ [power_setting->seq_val])
+ continue;
CDBG("%s:%d gpio set val %d\n", __func__, __LINE__,
ctrl->gpio_conf->gpio_num_info->gpio_num
[power_setting->seq_val]);
@@ -995,6 +1044,7 @@
power_setting = &ctrl->power_setting[index];
CDBG("%s type %d\n", __func__, power_setting->seq_type);
switch (power_setting->seq_type) {
+
case SENSOR_CLK:
msm_cam_clk_enable(ctrl->dev,
&ctrl->clk_info[0],
@@ -1003,6 +1053,9 @@
0);
break;
case SENSOR_GPIO:
+ if (!ctrl->gpio_conf->gpio_num_info->valid
+ [power_setting->seq_val])
+ continue;
gpio_set_value_cansleep(
ctrl->gpio_conf->gpio_num_info->gpio_num
[power_setting->seq_val], GPIOF_OUT_INIT_LOW);
@@ -1035,12 +1088,34 @@
return rc;
}
+static struct msm_sensor_power_setting*
+msm_camera_get_power_settings(struct msm_camera_power_ctrl_t *ctrl,
+ enum msm_sensor_power_seq_type_t seq_type,
+ uint16_t seq_val)
+{
+ struct msm_sensor_power_setting *power_setting, *ps = NULL;
+ int idx;
+
+ for (idx = 0; idx < ctrl->power_setting_size; idx++) {
+ power_setting = &ctrl->power_setting[idx];
+ if (power_setting->seq_type == seq_type &&
+ power_setting->seq_val == seq_val) {
+ ps = power_setting;
+ return ps;
+ }
+
+ }
+ return ps;
+}
+
int msm_camera_power_down(struct msm_camera_power_ctrl_t *ctrl,
enum msm_camera_device_type_t device_type,
struct msm_camera_i2c_client *sensor_i2c_client)
{
int index = 0;
- struct msm_sensor_power_setting *power_setting = NULL;
+ struct msm_sensor_power_setting *pd = NULL;
+ struct msm_sensor_power_setting *ps;
+
CDBG("%s:%d\n", __func__, __LINE__);
if (!ctrl || !sensor_i2c_client) {
@@ -1053,43 +1128,64 @@
sensor_i2c_client->i2c_func_tbl->i2c_util(
sensor_i2c_client, MSM_CCI_RELEASE);
- for (index = (ctrl->power_setting_size - 1); index >= 0; index--) {
+ for (index = 0; index < ctrl->power_down_setting_size; index++) {
CDBG("%s index %d\n", __func__, index);
- power_setting = &ctrl->power_setting[index];
- CDBG("%s type %d\n", __func__, power_setting->seq_type);
- switch (power_setting->seq_type) {
+ pd = &ctrl->power_down_setting[index];
+ ps = NULL;
+ CDBG("%s type %d\n", __func__, pd->seq_type);
+ switch (pd->seq_type) {
case SENSOR_CLK:
- msm_cam_clk_enable(ctrl->dev,
- &ctrl->clk_info[0],
- (struct clk **)&power_setting->data[0],
- ctrl->clk_info_size,
- 0);
- break;
+
+ ps = msm_camera_get_power_settings(ctrl,
+ pd->seq_type,
+ pd->seq_val);
+ if (ps)
+ msm_cam_clk_enable(ctrl->dev,
+ &ctrl->clk_info[0],
+ (struct clk **)&ps->data[0],
+ ctrl->clk_info_size,
+ 0);
+ else
+ pr_err("%s error in power up/down seq data\n",
+ __func__);
+ break;
case SENSOR_GPIO:
- if (power_setting->seq_val >= SENSOR_GPIO_MAX ||
+ if (pd->seq_val >= SENSOR_GPIO_MAX ||
!ctrl->gpio_conf->gpio_num_info) {
pr_err("%s gpio index %d >= max %d\n", __func__,
- power_setting->seq_val,
+ pd->seq_val,
SENSOR_GPIO_MAX);
continue;
}
+ if (!ctrl->gpio_conf->gpio_num_info->valid
+ [pd->seq_val])
+ continue;
gpio_set_value_cansleep(
ctrl->gpio_conf->gpio_num_info->gpio_num
- [power_setting->seq_val],
+ [pd->seq_val],
ctrl->gpio_conf->gpio_num_info->gpio_num
- [power_setting->config_val]);
+ [pd->config_val]);
break;
case SENSOR_VREG:
- if (power_setting->seq_val >= CAM_VREG_MAX) {
+ if (pd->seq_val >= CAM_VREG_MAX) {
pr_err("%s vreg index %d >= max %d\n", __func__,
- power_setting->seq_val,
+ pd->seq_val,
SENSOR_GPIO_MAX);
continue;
}
- msm_camera_config_single_vreg(ctrl->dev,
- &ctrl->cam_vreg[power_setting->seq_val],
- (struct regulator **)&power_setting->data[0],
- 0);
+
+ ps = msm_camera_get_power_settings(ctrl,
+ pd->seq_type,
+ pd->seq_val);
+
+ if (ps)
+ msm_camera_config_single_vreg(ctrl->dev,
+ &ctrl->cam_vreg[pd->seq_val],
+ (struct regulator **)&ps->data[0],
+ 0);
+ else
+ pr_err("%s error in power up/down seq data\n",
+ __func__);
break;
case SENSOR_I2C_MUX:
if (ctrl->i2c_conf && ctrl->i2c_conf->use_i2c_mux)
@@ -1097,14 +1193,14 @@
break;
default:
pr_err("%s error power seq type %d\n", __func__,
- power_setting->seq_type);
+ pd->seq_type);
break;
}
- if (power_setting->delay > 20) {
- msleep(power_setting->delay);
- } else if (power_setting->delay) {
- usleep_range(power_setting->delay * 1000,
- (power_setting->delay * 1000) + 1000);
+ if (pd->delay > 20) {
+ msleep(pd->delay);
+ } else if (pd->delay) {
+ usleep_range(pd->delay * 1000,
+ (pd->delay * 1000) + 1000);
}
}
msm_camera_request_gpio_table(
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.h b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.h
index 84d53e7..d7f8507 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.h
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.h
@@ -29,8 +29,7 @@
int msm_camera_get_dt_power_setting_data(struct device_node *of_node,
struct camera_vreg_t *cam_vreg, int num_vreg,
- struct msm_sensor_power_setting **power_setting,
- uint16_t *power_setting_size);
+ struct msm_camera_power_ctrl_t *power_info);
int msm_camera_get_dt_gpio_req_tbl(struct device_node *of_node,
struct msm_camera_gpio_conf *gconf, uint16_t *gpio_array,
diff --git a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c
index 450985a..87ad994 100755
--- a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c
@@ -35,6 +35,7 @@
int32_t rc = 0;
uint32_t size;
struct msm_sensor_power_setting *ps;
+ bool need_reverse = 0;
if ((NULL == power_info->power_setting) ||
(0 == power_info->power_setting_size)) {
@@ -60,7 +61,42 @@
power_info->power_setting_size = size;
}
+ ps = power_setting_array->power_down_setting;
+ size = power_setting_array->size_down;
+ if (NULL == ps || 0 == size) {
+ ps = power_info->power_setting;
+ size = power_info->power_setting_size;
+ need_reverse = 1;
+ }
+
+ power_info->power_down_setting =
+ kzalloc(sizeof(*ps) * size, GFP_KERNEL);
+ if (!power_info->power_down_setting) {
+ pr_err("%s failed %d\n", __func__, __LINE__);
+ goto FREE_UP;
+ }
+ memcpy(power_info->power_down_setting,
+ ps,
+ sizeof(*ps) * size);
+ power_info->power_down_setting_size = size;
+
+ if (need_reverse) {
+ int c, end = size - 1;
+ struct msm_sensor_power_setting power_down_setting_t;
+ for (c = 0; c < size/2; c++) {
+ power_down_setting_t =
+ power_info->power_down_setting[c];
+ power_info->power_down_setting[c] =
+ power_info->power_down_setting[end];
+ power_info->power_down_setting[end] =
+ power_down_setting_t;
+ end--;
+ }
+ }
+
return 0;
+FREE_UP:
+ kfree(power_info->power_setting);
FAILED_1:
return rc;
}
@@ -159,8 +195,7 @@
rc = msm_camera_get_dt_power_setting_data(of_node,
sensordata->power_info.cam_vreg,
sensordata->power_info.num_vreg,
- &sensordata->power_info.power_setting,
- &sensordata->power_info.power_setting_size);
+ &sensordata->power_info);
if (rc < 0) {
@@ -277,6 +312,7 @@
kfree(s_ctrl->sensordata->power_info.gpio_conf);
FREE_PS:
kfree(s_ctrl->sensordata->power_info.power_setting);
+ kfree(s_ctrl->sensordata->power_info.power_down_setting);
FREE_VREG:
kfree(s_ctrl->sensordata->power_info.cam_vreg);
FREE_CSI:
@@ -326,9 +362,10 @@
int32_t msm_sensor_free_sensor_data(struct msm_sensor_ctrl_t *s_ctrl)
{
- if (!s_ctrl->pdev)
+ if (!s_ctrl->pdev && !s_ctrl->sensor_i2c_client->client)
return 0;
kfree(s_ctrl->sensordata->slave_info);
+ kfree(s_ctrl->sensordata->cam_slave_info);
kfree(s_ctrl->sensordata->actuator_info);
kfree(s_ctrl->sensordata->power_info.gpio_conf->gpio_num_info);
kfree(s_ctrl->sensordata->power_info.gpio_conf->cam_gpio_set_tbl);
@@ -338,8 +375,8 @@
kfree(s_ctrl->sensordata->power_info.power_setting);
kfree(s_ctrl->sensordata->csi_lane_params);
kfree(s_ctrl->sensordata->sensor_info);
- kfree(s_ctrl->sensordata);
kfree(s_ctrl->sensordata->power_info.clk_info);
+ kfree(s_ctrl->sensordata);
return 0;
}
@@ -565,7 +602,7 @@
struct msm_camera_sensor_slave_info sensor_slave_info;
struct msm_camera_power_ctrl_t *p_ctrl;
uint16_t size;
- int slave_index = 0;
+ int s_index = 0;
if (copy_from_user(&sensor_slave_info,
(void *)cdata->cfg.setting,
sizeof(sensor_slave_info))) {
@@ -582,9 +619,9 @@
/* Update sensor address type */
s_ctrl->sensor_i2c_client->addr_type =
sensor_slave_info.addr_type;
-
- /* Update power up / down sequence */
p_ctrl = &s_ctrl->sensordata->power_info;
+
+ /* Update power up sequence */
size = sensor_slave_info.power_setting_array.size;
if (p_ctrl->power_setting_size < size) {
struct msm_sensor_power_setting *tmp;
@@ -618,15 +655,62 @@
sensor_slave_info.sensor_id_info.sensor_id_reg_addr);
CDBG("%s sensor id %x\n", __func__,
sensor_slave_info.sensor_id_info.sensor_id);
- for (slave_index = 0; slave_index <
- p_ctrl->power_setting_size; slave_index++) {
- CDBG("%s i %d power setting %d %d %ld %d\n", __func__,
- slave_index,
- p_ctrl->power_setting[slave_index].seq_type,
- p_ctrl->power_setting[slave_index].seq_val,
- p_ctrl->power_setting[slave_index].config_val,
- p_ctrl->power_setting[slave_index].delay);
+ for (s_index = 0; s_index <
+ p_ctrl->power_setting_size; s_index++) {
+ CDBG("%s i %d power up setting %d %d %ld %d\n",
+ __func__,
+ s_index,
+ p_ctrl->power_setting[s_index].seq_type,
+ p_ctrl->power_setting[s_index].seq_val,
+ p_ctrl->power_setting[s_index].config_val,
+ p_ctrl->power_setting[s_index].delay);
}
+
+ /* Update power down sequence */
+ if (!sensor_slave_info.power_setting_array.power_down_setting ||
+ 0 == size) {
+ pr_err("%s: Missing dedicated power down sequence\n",
+ __func__);
+ break;
+ }
+ size = sensor_slave_info.power_setting_array.size_down;
+
+ if (p_ctrl->power_down_setting_size < size) {
+ struct msm_sensor_power_setting *tmp;
+ tmp = kmalloc(sizeof(*tmp) * size, GFP_KERNEL);
+ if (!tmp) {
+ pr_err("%s: failed to alloc mem\n", __func__);
+ rc = -ENOMEM;
+ break;
+ }
+ kfree(p_ctrl->power_down_setting);
+ p_ctrl->power_down_setting = tmp;
+ }
+ p_ctrl->power_down_setting_size = size;
+
+
+ rc = copy_from_user(p_ctrl->power_down_setting, (void *)
+ sensor_slave_info.power_setting_array.
+ power_down_setting,
+ size * sizeof(struct msm_sensor_power_setting));
+ if (rc) {
+ pr_err("%s:%d failed\n", __func__, __LINE__);
+ kfree(sensor_slave_info.power_setting_array.
+ power_down_setting);
+ rc = -EFAULT;
+ break;
+ }
+ for (s_index = 0; s_index <
+ p_ctrl->power_down_setting_size; s_index++) {
+ CDBG("%s i %d power DOWN setting %d %d %ld %d\n",
+ __func__,
+ s_index,
+ p_ctrl->power_down_setting[s_index].seq_type,
+ p_ctrl->power_down_setting[s_index].seq_val,
+ p_ctrl->power_down_setting[s_index].config_val,
+ p_ctrl->power_down_setting[s_index].delay);
+ }
+
break;
}
case CFG_WRITE_I2C_ARRAY: {
@@ -1264,9 +1348,6 @@
return -EINVAL;
}
- /* Initialize sensor device type */
- s_ctrl->sensor_device_type = MSM_CAMERA_PLATFORM_DEVICE;
-
if (!s_ctrl->sensor_i2c_client) {
pr_err("%s:%d failed: invalid params sensor_i2c_client %p\n",
__func__, __LINE__, s_ctrl->sensor_i2c_client);
@@ -1282,20 +1363,28 @@
return -ENOMEM;
}
- cci_client = s_ctrl->sensor_i2c_client->cci_client;
+ if (s_ctrl->sensor_device_type == MSM_CAMERA_PLATFORM_DEVICE) {
+ cci_client = s_ctrl->sensor_i2c_client->cci_client;
- /* Get CCI subdev */
- cci_client->cci_subdev = msm_cci_get_subdev();
+ /* Get CCI subdev */
+ cci_client->cci_subdev = msm_cci_get_subdev();
+
+ /* Update CCI / I2C function table */
+ if (!s_ctrl->sensor_i2c_client->i2c_func_tbl)
+ s_ctrl->sensor_i2c_client->i2c_func_tbl =
+ &msm_sensor_cci_func_tbl;
+ } else {
+ if (!s_ctrl->sensor_i2c_client->i2c_func_tbl) {
+ CDBG("%s:%d\n", __func__, __LINE__);
+ s_ctrl->sensor_i2c_client->i2c_func_tbl =
+ &msm_sensor_qup_func_tbl;
+ }
+ }
/* Update function table driven by ioctl */
if (!s_ctrl->func_tbl)
s_ctrl->func_tbl = &msm_sensor_func_tbl;
- /* Update CCI / I2C function table */
- if (!s_ctrl->sensor_i2c_client->i2c_func_tbl)
- s_ctrl->sensor_i2c_client->i2c_func_tbl =
- &msm_sensor_cci_func_tbl;
-
/* Update v4l2 subdev ops table */
if (!s_ctrl->sensor_v4l2_subdev_ops)
s_ctrl->sensor_v4l2_subdev_ops = &msm_sensor_subdev_ops;
diff --git a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.h b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.h
index 3a480a7..0f77567 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.h
+++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.h
@@ -71,6 +71,8 @@
void *misc_regulator;
enum msm_sensor_state_t sensor_state;
uint8_t is_probe_succeed;
+ uint32_t id;
+ struct device_node *of_node;
};
int msm_sensor_config(struct msm_sensor_ctrl_t *s_ctrl, void __user *argp);
diff --git a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c
index 58d2a4a..f5be347 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c
@@ -10,8 +10,7 @@
* GNU General Public License for more details.
*/
-#define pr_fmt(fmt) "MSM-SENSOR-DRIVER %s:%d " fmt "\n", __func__, __LINE__
-
+#define SENSOR_DRIVER_I2C "camera"
/* Header file declaration */
#include "msm_sensor.h"
#include "msm_sd.h"
@@ -78,18 +77,203 @@
},
};
+static int32_t msm_sensor_driver_create_i2c_v4l_subdev
+ (struct msm_sensor_ctrl_t *s_ctrl)
+{
+ int32_t rc = 0;
+ uint32_t session_id = 0;
+ struct i2c_client *client = s_ctrl->sensor_i2c_client->client;
+
+ CDBG("%s %s I2c probe succeeded\n", __func__, client->name);
+ rc = camera_init_v4l2(&client->dev, &session_id);
+ if (rc < 0) {
+ pr_err("failed: camera_init_i2c_v4l2 rc %d", rc);
+ return rc;
+ }
+ CDBG("%s rc %d session_id %d\n", __func__, rc, session_id);
+ snprintf(s_ctrl->msm_sd.sd.name,
+ sizeof(s_ctrl->msm_sd.sd.name), "%s",
+ s_ctrl->sensordata->sensor_name);
+ v4l2_i2c_subdev_init(&s_ctrl->msm_sd.sd, client,
+ s_ctrl->sensor_v4l2_subdev_ops);
+ v4l2_set_subdevdata(&s_ctrl->msm_sd.sd, client);
+ s_ctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ media_entity_init(&s_ctrl->msm_sd.sd.entity, 0, NULL, 0);
+ s_ctrl->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+ s_ctrl->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_SENSOR;
+ s_ctrl->msm_sd.sd.entity.name = s_ctrl->msm_sd.sd.name;
+ s_ctrl->sensordata->sensor_info->session_id = session_id;
+ s_ctrl->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x3;
+ msm_sd_register(&s_ctrl->msm_sd);
+ CDBG("%s:%d\n", __func__, __LINE__);
+ return rc;
+}
+
+static int32_t msm_sensor_driver_create_v4l_subdev
+ (struct msm_sensor_ctrl_t *s_ctrl)
+{
+ int32_t rc = 0;
+ uint32_t session_id = 0;
+
+ rc = camera_init_v4l2(&s_ctrl->pdev->dev, &session_id);
+ if (rc < 0) {
+ pr_err("failed: camera_init_v4l2 rc %d", rc);
+ return rc;
+ }
+ CDBG("rc %d session_id %d", rc, session_id);
+ s_ctrl->sensordata->sensor_info->session_id = session_id;
+
+ /* Create /dev/v4l-subdevX device */
+ v4l2_subdev_init(&s_ctrl->msm_sd.sd, s_ctrl->sensor_v4l2_subdev_ops);
+ snprintf(s_ctrl->msm_sd.sd.name, sizeof(s_ctrl->msm_sd.sd.name), "%s",
+ s_ctrl->sensordata->sensor_name);
+ v4l2_set_subdevdata(&s_ctrl->msm_sd.sd, s_ctrl->pdev);
+ s_ctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ media_entity_init(&s_ctrl->msm_sd.sd.entity, 0, NULL, 0);
+ s_ctrl->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+ s_ctrl->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_SENSOR;
+ s_ctrl->msm_sd.sd.entity.name = s_ctrl->msm_sd.sd.name;
+ s_ctrl->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x3;
+ msm_sd_register(&s_ctrl->msm_sd);
+ return rc;
+}
+
+static int32_t msm_sensor_fill_eeprom_subdevid_by_name(
+ struct msm_sensor_ctrl_t *s_ctrl)
+{
+ int32_t rc = 0;
+ const char *eeprom_name;
+ struct device_node *src_node = NULL;
+ uint32_t val = 0, count = 0, eeprom_name_len;
+ int i;
+ int32_t *eeprom_subdev_id;
+ struct msm_sensor_info_t *sensor_info;
+ struct device_node *of_node = s_ctrl->of_node;
+ const void *p;
+
+ if (!s_ctrl->sensordata->eeprom_name || !of_node)
+ return -EINVAL;
+
+ eeprom_name_len = strlen(s_ctrl->sensordata->eeprom_name);
+ if (eeprom_name_len >= MAX_SENSOR_NAME)
+ return -EINVAL;
+
+ sensor_info = s_ctrl->sensordata->sensor_info;
+ eeprom_subdev_id = &sensor_info->subdev_id[SUB_MODULE_EEPROM];
+ /*
+ * string for eeprom name is valid, set sudev id to -1
+ * and try to found new id
+ */
+ *eeprom_subdev_id = -1;
+
+ if (0 == eeprom_name_len)
+ return 0;
+
+ CDBG("Try to find eeprom subdev for %s\n",
+ s_ctrl->sensordata->eeprom_name);
+ p = of_get_property(of_node, "qcom,eeprom-src", &count);
+ if (!p || !count)
+ return 0;
+
+ count /= sizeof(uint32_t);
+ for (i = 0; i < count; i++) {
+ eeprom_name = NULL;
+ src_node = of_parse_phandle(of_node, "qcom,eeprom-src", i);
+ if (!src_node) {
+ pr_err("eeprom src node NULL\n");
+ continue;
+ }
+ rc = of_property_read_string(src_node, "qcom,eeprom-name",
+ &eeprom_name);
+ if (rc < 0) {
+ pr_err("failed\n");
+ of_node_put(src_node);
+ continue;
+ }
+ if (strcmp(eeprom_name, s_ctrl->sensordata->eeprom_name))
+ continue;
+
+ rc = of_property_read_u32(src_node, "cell-index", &val);
+
+ CDBG("%s qcom,eeprom cell index %d, rc %d\n", __func__,
+ val, rc);
+ if (rc < 0) {
+ pr_err("failed\n");
+ of_node_put(src_node);
+ continue;
+ }
+
+ *eeprom_subdev_id = val;
+ CDBG("Done. Eeprom subdevice id is %d\n", val);
+ of_node_put(src_node);
+ src_node = NULL;
+ break;
+ }
+
+ return rc;
+}
+
+static int32_t msm_sensor_fill_actuator_subdevid_by_name(
+ struct msm_sensor_ctrl_t *s_ctrl)
+{
+ int32_t rc = 0;
+ struct device_node *src_node = NULL;
+ uint32_t val = 0, actuator_name_len;
+ int32_t *actuator_subdev_id;
+ struct msm_sensor_info_t *sensor_info;
+ struct device_node *of_node = s_ctrl->of_node;
+
+ if (!s_ctrl->sensordata->actuator_name || !of_node)
+ return -EINVAL;
+
+ actuator_name_len = strlen(s_ctrl->sensordata->actuator_name);
+ if (actuator_name_len >= MAX_SENSOR_NAME)
+ return -EINVAL;
+
+ sensor_info = s_ctrl->sensordata->sensor_info;
+ actuator_subdev_id = &sensor_info->subdev_id[SUB_MODULE_ACTUATOR];
+ /*
+ * string for actuator name is valid, set sudev id to -1
+ * and try to found new id
+ */
+ *actuator_subdev_id = -1;
+
+ if (0 == actuator_name_len)
+ return 0;
+
+ src_node = of_parse_phandle(of_node, "qcom,actuator-src", 0);
+ if (!src_node) {
+ CDBG("%s:%d src_node NULL\n", __func__, __LINE__);
+ } else {
+ rc = of_property_read_u32(src_node, "cell-index", &val);
+ CDBG("%s qcom,actuator cell index %d, rc %d\n", __func__,
+ val, rc);
+ if (rc < 0) {
+ pr_err("%s failed %d\n", __func__, __LINE__);
+ return -EINVAL;
+ }
+ *actuator_subdev_id = val;
+ of_node_put(src_node);
+ src_node = NULL;
+ }
+
+ return rc;
+}
+
/* static function definition */
int32_t msm_sensor_driver_probe(void *setting)
{
int32_t rc = 0;
- uint16_t i = 0, size = 0;
- uint32_t session_id = 0;
+ uint16_t i = 0, size = 0, size_down = 0;
struct msm_sensor_ctrl_t *s_ctrl = NULL;
struct msm_camera_cci_client *cci_client = NULL;
struct msm_camera_sensor_slave_info *slave_info = NULL;
struct msm_sensor_power_setting *power_setting = NULL;
+ struct msm_sensor_power_setting *power_down_setting = NULL;
struct msm_camera_slave_info *camera_info = NULL;
struct msm_camera_power_ctrl_t *power_info = NULL;
+ int c, end;
+ struct msm_sensor_power_setting power_down_setting_t;
/* Validate input parameters */
if (!setting) {
@@ -117,7 +301,8 @@
CDBG("sensor_id_reg_addr %x",
slave_info->sensor_id_info.sensor_id_reg_addr);
CDBG("sensor_id %x", slave_info->sensor_id_info.sensor_id);
- CDBG("size %x", slave_info->power_setting_array.size);
+ CDBG("size %d", slave_info->power_setting_array.size);
+ CDBG("size down %d", slave_info->power_setting_array.size_down);
/* Validate camera id */
if (slave_info->camera_id >= MAX_CAMERAS) {
@@ -150,7 +335,7 @@
}
size = slave_info->power_setting_array.size;
- /* Allocate memory for power setting */
+ /* Allocate memory for power up setting */
power_setting = kzalloc(sizeof(*power_setting) * size, GFP_KERNEL);
if (!power_setting) {
pr_err("failed: no memory power_setting %p", power_setting);
@@ -168,15 +353,68 @@
/* Print power setting */
for (i = 0; i < size; i++) {
- CDBG("seq_type %d seq_val %d config_val %ld delay %d",
+ CDBG("UP seq_type %d seq_val %d config_val %ld delay %d",
power_setting[i].seq_type, power_setting[i].seq_val,
power_setting[i].config_val, power_setting[i].delay);
}
+ /*DOWN*/
+ size_down = slave_info->power_setting_array.size_down;
+ if (!size_down)
+ size_down = size;
+ /* Allocate memory for power down setting */
+ power_down_setting =
+ kzalloc(sizeof(*power_setting) * size_down, GFP_KERNEL);
+ if (!power_down_setting) {
+ pr_err("failed: no memory power_setting %p",
+ power_down_setting);
+ rc = -ENOMEM;
+ goto FREE_POWER_SETTING;
+ }
+
+ if (slave_info->power_setting_array.power_down_setting) {
+ if (copy_from_user(power_down_setting,
+ (void *)slave_info->power_setting_array.
+ power_down_setting,
+ sizeof(*power_down_setting) * size_down)) {
+ pr_err("failed: copy_from_user");
+ rc = -EFAULT;
+ goto FREE_POWER_DOWN_SETTING;
+ }
+ } else {
+ pr_err("failed: no power_down_setting");
+ if (copy_from_user(power_down_setting,
+ (void *)slave_info->power_setting_array.
+ power_setting,
+ sizeof(*power_down_setting) * size_down)) {
+ pr_err("failed: copy_from_user");
+ rc = -EFAULT;
+ goto FREE_POWER_DOWN_SETTING;
+ }
+
+ /*reverce*/
+ end = size_down - 1;
+ for (c = 0; c < size_down/2; c++) {
+ power_down_setting_t = power_down_setting[c];
+ power_down_setting[c] = power_down_setting[end];
+ power_down_setting[end] = power_down_setting_t;
+ end--;
+ }
+
+ }
+
+ /* Print power setting */
+ for (i = 0; i < size_down; i++) {
+ CDBG("DOWN seq_type %d seq_val %d config_val %ld delay %d",
+ power_down_setting[i].seq_type,
+ power_down_setting[i].seq_val,
+ power_down_setting[i].config_val,
+ power_down_setting[i].delay);
+ }
camera_info = kzalloc(sizeof(struct msm_camera_slave_info), GFP_KERNEL);
if (!camera_info) {
pr_err("failed: no memory slave_info %p", camera_info);
- goto FREE_POWER_SETTING;
+ goto FREE_POWER_DOWN_SETTING;
}
@@ -184,6 +422,8 @@
power_info = &s_ctrl->sensordata->power_info;
power_info->power_setting = power_setting;
power_info->power_setting_size = size;
+ power_info->power_down_setting = power_down_setting;
+ power_info->power_down_setting_size = size_down;
s_ctrl->sensordata->slave_info = camera_info;
@@ -198,22 +438,25 @@
pr_err("failed: sensor_i2c_client %p",
s_ctrl->sensor_i2c_client);
rc = -EINVAL;
- goto FREE_POWER_SETTING;
+ goto FREE_CAMERA_INFO;
}
/* Fill sensor address type */
s_ctrl->sensor_i2c_client->addr_type = slave_info->addr_type;
+ if (s_ctrl->sensor_i2c_client->client)
+ s_ctrl->sensor_i2c_client->client->addr =
+ camera_info->sensor_slave_addr;
cci_client = s_ctrl->sensor_i2c_client->cci_client;
if (!cci_client) {
pr_err("failed: cci_client %p", cci_client);
- goto FREE_POWER_SETTING;
+ goto FREE_CAMERA_INFO;
}
cci_client->cci_i2c_master = s_ctrl->cci_i2c_master;
cci_client->sid = slave_info->slave_addr >> 1;
cci_client->retries = 3;
cci_client->id_map = 0;
- /* Parse and fill vreg params */
+ /* Parse and fill vreg params for powerup settings */
rc = msm_camera_fill_vreg_params(
power_info->cam_vreg,
power_info->num_vreg,
@@ -222,17 +465,51 @@
if (rc < 0) {
pr_err("failed: msm_camera_get_dt_power_setting_data rc %d",
rc);
- goto FREE_POWER_SETTING;
+ goto FREE_CAMERA_INFO;
}
- /* Update sensor name in sensor control structure */
+ /* Parse and fill vreg params for powerdown settings*/
+ rc = msm_camera_fill_vreg_params(
+ power_info->cam_vreg,
+ power_info->num_vreg,
+ power_info->power_down_setting,
+ power_info->power_down_setting_size);
+ if (rc < 0) {
+ pr_err("failed: msm_camera_fill_vreg_params for PDOWN rc %d",
+ rc);
+ goto FREE_CAMERA_INFO;
+ }
+
+ /*
+ * Update sensor, actuator and eeprom name in
+ * sensor control structure.
+ */
s_ctrl->sensordata->sensor_name = slave_info->sensor_name;
+ s_ctrl->sensordata->eeprom_name = slave_info->eeprom_name;
+ s_ctrl->sensordata->actuator_name = slave_info->actuator_name;
+
+ /*
+ * Update eeporm subdevice Id by input eeprom name
+ */
+ rc = msm_sensor_fill_eeprom_subdevid_by_name(s_ctrl);
+ if (rc < 0) {
+ pr_err("%s failed %d\n", __func__, __LINE__);
+ goto FREE_POWER_SETTING;
+ }
+ /*
+ * Update actuator subdevice Id by input actuator name
+ */
+ rc = msm_sensor_fill_actuator_subdevid_by_name(s_ctrl);
+ if (rc < 0) {
+ pr_err("%s failed %d\n", __func__, __LINE__);
+ goto FREE_POWER_SETTING;
+ }
/* Power up and probe sensor */
rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
if (rc < 0) {
pr_err("%s power up failed", slave_info->sensor_name);
- goto FREE_POWER_SETTING;
+ goto FREE_CAMERA_INFO;
}
pr_err("%s probe succeeded", slave_info->sensor_name);
@@ -247,32 +524,30 @@
* Create /dev/videoX node, comment for now until dummy /dev/videoX
* node is created and used by HAL
*/
- rc = camera_init_v4l2(&s_ctrl->pdev->dev, &session_id);
- if (rc < 0) {
- pr_err("failed: camera_init_v4l2 rc %d", rc);
- goto FREE_POWER_SETTING;
- }
- CDBG("rc %d session_id %d", rc, session_id);
- s_ctrl->sensordata->sensor_info->session_id = session_id;
- /* Create /dev/v4l-subdevX device */
- v4l2_subdev_init(&s_ctrl->msm_sd.sd, s_ctrl->sensor_v4l2_subdev_ops);
- snprintf(s_ctrl->msm_sd.sd.name, sizeof(s_ctrl->msm_sd.sd.name), "%s",
- s_ctrl->sensordata->sensor_name);
- v4l2_set_subdevdata(&s_ctrl->msm_sd.sd, s_ctrl->pdev);
- s_ctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
- media_entity_init(&s_ctrl->msm_sd.sd.entity, 0, NULL, 0);
- s_ctrl->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
- s_ctrl->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_SENSOR;
- s_ctrl->msm_sd.sd.entity.name = s_ctrl->msm_sd.sd.name;
- s_ctrl->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x3;
- msm_sd_register(&s_ctrl->msm_sd);
+ if (s_ctrl->sensor_device_type == MSM_CAMERA_PLATFORM_DEVICE)
+ rc = msm_sensor_driver_create_v4l_subdev(s_ctrl);
+ else
+ rc = msm_sensor_driver_create_i2c_v4l_subdev(s_ctrl);
+ if (rc < 0) {
+ pr_err("failed: camera creat v4l2 rc %d", rc);
+ goto CAMERA_POWER_DOWN;
+ }
/* Power down */
s_ctrl->func_tbl->sensor_power_down(s_ctrl);
+ /*Save sensor info*/
+ s_ctrl->sensordata->cam_slave_info = slave_info;
+
return rc;
+CAMERA_POWER_DOWN:
+ s_ctrl->func_tbl->sensor_power_down(s_ctrl);
+FREE_CAMERA_INFO:
+ kfree(camera_info);
+FREE_POWER_DOWN_SETTING:
+ kfree(power_down_setting);
FREE_POWER_SETTING:
kfree(power_setting);
FREE_SLAVE_INFO:
@@ -344,12 +619,12 @@
return rc;
}
-static int32_t msm_sensor_driver_get_dt_data(struct msm_sensor_ctrl_t *s_ctrl,
- struct platform_device *pdev)
+static int32_t msm_sensor_driver_get_dt_data(struct msm_sensor_ctrl_t *s_ctrl)
{
int32_t rc = 0;
struct msm_camera_sensor_board_info *sensordata = NULL;
- struct device_node *of_node = pdev->dev.of_node;
+ struct device_node *of_node = s_ctrl->of_node;
+ uint32_t cell_id;
s_ctrl->sensordata = kzalloc(sizeof(*sensordata), GFP_KERNEL);
if (!s_ctrl->sensordata) {
@@ -363,22 +638,23 @@
* Read cell index - this cell index will be the camera slot where
* this camera will be mounted
*/
- rc = of_property_read_u32(of_node, "cell-index", &pdev->id);
+ rc = of_property_read_u32(of_node, "cell-index", &cell_id);
if (rc < 0) {
pr_err("failed: cell-index rc %d", rc);
goto FREE_SENSOR_DATA;
}
+ s_ctrl->id = cell_id;
- /* Validate pdev->id */
- if (pdev->id >= MAX_CAMERAS) {
- pr_err("failed: invalid pdev->id %d", pdev->id);
+ /* Validate cell_id */
+ if (cell_id >= MAX_CAMERAS) {
+ pr_err("failed: invalid cell_id %d", cell_id);
rc = -EINVAL;
goto FREE_SENSOR_DATA;
}
- /* Check whether g_sctrl is already filled for this pdev id */
- if (g_sctrl[pdev->id]) {
- pr_err("failed: sctrl already filled for id %d", pdev->id);
+ /* Check whether g_sctrl is already filled for this cell_id */
+ if (g_sctrl[cell_id]) {
+ pr_err("failed: sctrl already filled for cell_id %d", cell_id);
rc = -EINVAL;
goto FREE_SENSOR_DATA;
}
@@ -448,27 +724,13 @@
return rc;
}
-static int32_t msm_sensor_driver_parse(struct platform_device *pdev)
+static int32_t msm_sensor_driver_parse(struct msm_sensor_ctrl_t *s_ctrl)
{
int32_t rc = 0;
- struct msm_sensor_ctrl_t *s_ctrl = NULL;
CDBG("Enter");
/* Validate input parameters */
- if (!pdev || !pdev->dev.of_node) {
- pr_err("failed: invalid params");
- return -EINVAL;
- }
- /* Create sensor control structure */
- s_ctrl = kzalloc(sizeof(*s_ctrl), GFP_KERNEL);
- if (!s_ctrl) {
- pr_err("failed: no memory s_ctrl %p", s_ctrl);
- return -ENOMEM;
- }
-
- /* Fill platform device */
- s_ctrl->pdev = pdev;
/* Allocate memory for sensor_i2c_client */
s_ctrl->sensor_i2c_client = kzalloc(sizeof(*s_ctrl->sensor_i2c_client),
@@ -476,7 +738,7 @@
if (!s_ctrl->sensor_i2c_client) {
pr_err("failed: no memory sensor_i2c_client %p",
s_ctrl->sensor_i2c_client);
- goto FREE_SCTRL;
+ return -ENOMEM;
}
/* Allocate memory for mutex */
@@ -489,15 +751,12 @@
}
/* Parse dt information and store in sensor control structure */
- rc = msm_sensor_driver_get_dt_data(s_ctrl, pdev);
+ rc = msm_sensor_driver_get_dt_data(s_ctrl);
if (rc < 0) {
pr_err("failed: rc %d", rc);
goto FREE_MUTEX;
}
- /* Fill device in power info */
- s_ctrl->sensordata->power_info.dev = &pdev->dev;
-
/* Initialize mutex */
mutex_init(s_ctrl->msm_sensor_mutex);
@@ -514,8 +773,8 @@
}
/* Store sensor control structure in static database */
- g_sctrl[pdev->id] = s_ctrl;
- pr_err("g_sctrl[%d] %p", pdev->id, g_sctrl[pdev->id]);
+ g_sctrl[s_ctrl->id] = s_ctrl;
+ pr_err("g_sctrl[%d] %p", s_ctrl->id, g_sctrl[s_ctrl->id]);
return rc;
@@ -529,20 +788,141 @@
kfree(s_ctrl->msm_sensor_mutex);
FREE_SENSOR_I2C_CLIENT:
kfree(s_ctrl->sensor_i2c_client);
-FREE_SCTRL:
+ return rc;
+}
+
+static int32_t msm_sensor_driver_platform_probe(struct platform_device *pdev)
+{
+ int32_t rc = 0;
+ struct msm_sensor_ctrl_t *s_ctrl = NULL;
+
+
+ /* Create sensor control structure */
+ s_ctrl = kzalloc(sizeof(*s_ctrl), GFP_KERNEL);
+ if (!s_ctrl) {
+ pr_err("failed: no memory s_ctrl %p", s_ctrl);
+ return -ENOMEM;
+ }
+
+ platform_set_drvdata(pdev, s_ctrl);
+
+ /* Initialize sensor device type */
+ s_ctrl->sensor_device_type = MSM_CAMERA_PLATFORM_DEVICE;
+ s_ctrl->of_node = pdev->dev.of_node;
+
+ rc = msm_sensor_driver_parse(s_ctrl);
+ if (rc < 0) {
+ pr_err("failed: msm_sensor_driver_parse rc %d", rc);
+ goto FREE_S_CTRL;
+ }
+
+ /* Fill platform device */
+ pdev->id = s_ctrl->id;
+ s_ctrl->pdev = pdev;
+
+ /* Fill device in power info */
+ s_ctrl->sensordata->power_info.dev = &pdev->dev;
+
+ return rc;
+FREE_S_CTRL:
kfree(s_ctrl);
return rc;
}
+static int32_t msm_sensor_driver_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int32_t rc = 0;
+ struct msm_sensor_ctrl_t *s_ctrl;
+
+ CDBG("\n\nEnter: msm_sensor_driver_i2c_probe");
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ pr_err("%s %s i2c_check_functionality failed\n",
+ __func__, client->name);
+ rc = -EFAULT;
+ return rc;
+ }
+
+ /* Create sensor control structure */
+ s_ctrl = kzalloc(sizeof(*s_ctrl), GFP_KERNEL);
+ if (!s_ctrl) {
+ pr_err("failed: no memory s_ctrl %p", s_ctrl);
+ return -ENOMEM;
+ }
+
+ i2c_set_clientdata(client, s_ctrl);
+
+ /* Initialize sensor device type */
+ s_ctrl->sensor_device_type = MSM_CAMERA_I2C_DEVICE;
+ s_ctrl->of_node = client->dev.of_node;
+
+ rc = msm_sensor_driver_parse(s_ctrl);
+ if (rc < 0) {
+ pr_err("failed: msm_sensor_driver_parse rc %d", rc);
+ goto FREE_S_CTRL;
+ }
+
+ if (s_ctrl->sensor_i2c_client != NULL) {
+ s_ctrl->sensor_i2c_client->client = client;
+ s_ctrl->sensordata->power_info.dev = &client->dev;
+
+ }
+
+ return rc;
+FREE_S_CTRL:
+ kfree(s_ctrl);
+ return rc;
+}
+
+static int msm_sensor_driver_i2c_remove(struct i2c_client *client)
+{
+ struct msm_sensor_ctrl_t *s_ctrl = i2c_get_clientdata(client);
+
+ pr_err("%s: sensor FREE\n", __func__);
+
+ if (!s_ctrl) {
+ pr_err("%s: sensor device is NULL\n", __func__);
+ return 0;
+ }
+
+ g_sctrl[s_ctrl->id] = NULL;
+ msm_sensor_free_sensor_data(s_ctrl);
+ kfree(s_ctrl->msm_sensor_mutex);
+ kfree(s_ctrl->sensor_i2c_client);
+ kfree(s_ctrl);
+
+ return 0;
+}
+
+static const struct i2c_device_id i2c_id[] = {
+ {SENSOR_DRIVER_I2C, (kernel_ulong_t)NULL},
+ { }
+};
+
+static struct i2c_driver msm_sensor_driver_i2c = {
+ .id_table = i2c_id,
+ .probe = msm_sensor_driver_i2c_probe,
+ .remove = msm_sensor_driver_i2c_remove,
+ .driver = {
+ .name = SENSOR_DRIVER_I2C,
+ },
+};
+
static int __init msm_sensor_driver_init(void)
{
int32_t rc = 0;
CDBG("Enter");
rc = platform_driver_probe(&msm_sensor_platform_driver,
- msm_sensor_driver_parse);
- if (!rc)
- pr_info("probe success");
+ msm_sensor_driver_platform_probe);
+ if (!rc) {
+ CDBG("probe success");
+ return rc;
+ } else {
+ CDBG("probe i2c");
+ rc = i2c_add_driver(&msm_sensor_driver_i2c);
+ }
+
return rc;
}
@@ -551,6 +931,7 @@
{
CDBG("Enter");
platform_driver_unregister(&msm_sensor_platform_driver);
+ i2c_del_driver(&msm_sensor_driver_i2c);
return;
}
diff --git a/drivers/media/platform/msm/camera_v2/sensor/mt9m114.c b/drivers/media/platform/msm/camera_v2/sensor/mt9m114.c
index 68bb178..1d58490 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/mt9m114.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/mt9m114.c
@@ -1191,6 +1191,10 @@
for (i = 0; i < SUB_MODULE_MAX; i++)
cdata->cfg.sensor_info.subdev_id[i] =
s_ctrl->sensordata->sensor_info->subdev_id[i];
+ cdata->cfg.sensor_info.is_mount_angle_valid =
+ s_ctrl->sensordata->sensor_info->is_mount_angle_valid;
+ cdata->cfg.sensor_info.sensor_mount_angle =
+ s_ctrl->sensordata->sensor_info->sensor_mount_angle;
CDBG("%s:%d sensor name %s\n", __func__, __LINE__,
cdata->cfg.sensor_info.sensor_name);
CDBG("%s:%d session id %d\n", __func__, __LINE__,
diff --git a/drivers/media/platform/msm/camera_v2/sensor/sp1628.c b/drivers/media/platform/msm/camera_v2/sensor/sp1628.c
index 36df9fc..d4e4cdf 100755
--- a/drivers/media/platform/msm/camera_v2/sensor/sp1628.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/sp1628.c
@@ -637,6 +637,10 @@
for (i = 0; i < SUB_MODULE_MAX; i++)
cdata->cfg.sensor_info.subdev_id[i] =
s_ctrl->sensordata->sensor_info->subdev_id[i];
+ cdata->cfg.sensor_info.is_mount_angle_valid =
+ s_ctrl->sensordata->sensor_info->is_mount_angle_valid;
+ cdata->cfg.sensor_info.sensor_mount_angle =
+ s_ctrl->sensordata->sensor_info->sensor_mount_angle;
CDBG("%s:%d sensor name %s\n", __func__, __LINE__,
cdata->cfg.sensor_info.sensor_name);
CDBG("%s:%d session id %d\n", __func__, __LINE__,
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
index 4424c1f..d8b608437 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.c
+++ b/drivers/media/platform/msm/vidc/msm_venc.c
@@ -125,6 +125,14 @@
"Turbo"
};
+static const char *const intra_refresh_modes[] = {
+ "None",
+ "Cyclic",
+ "Adaptive",
+ "Cyclic Adaptive",
+ "Random"
+};
+
enum msm_venc_ctrl_cluster {
MSM_VENC_CTRL_CLUSTER_QP = 1 << 0,
MSM_VENC_CTRL_CLUSTER_INTRA_PERIOD = 1 << 1,
@@ -566,6 +574,7 @@
(1 << V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC_ADAPTIVE) |
(1 << V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOM)
),
+ .qmenu = intra_refresh_modes,
.cluster = MSM_VENC_CTRL_CLUSTER_INTRA_REFRESH,
},
{
diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c
index 59a1ec0..2c808ff 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc.c
@@ -525,7 +525,7 @@
if ((i == 0) && is_dynamic_output_buffer_mode(b, inst)) {
rc = buf_ref_get(inst, binfo);
if (rc < 0)
- return rc;
+ goto exit;
}
dprintk(VIDC_DBG,
"%s: [MAP] binfo = %p, handle[%d] = %p, device_addr = 0x%x, fd = %d, offset = %d, mapped = %d\n",
@@ -961,6 +961,13 @@
}
}
+ if (!buffer_info && inst->map_output_buffer) {
+ dprintk(VIDC_ERR,
+ "%s: error - no buffer info found in registered list\n",
+ __func__);
+ return -EINVAL;
+ }
+
if (is_dynamic_output_buffer_mode(b, inst)) {
mutex_lock(&inst->lock);
buffer_info->dequeued = true;
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
index 694335b..4fcd20e 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -3479,9 +3479,15 @@
&smem_block_size);
if (smem_table_ptr &&
((smem_image_index_venus + version_string_size) <=
- smem_block_size))
+ smem_block_size)) {
memcpy(version_info, smem_table_ptr + smem_image_index_venus,
version_string_size);
+ } else {
+ dprintk(VIDC_ERR,
+ "%s: failed to read version info from smem table\n",
+ __func__);
+ return -EINVAL;
+ }
while (version_info[i++] != 'V' && i < version_string_size)
;
diff --git a/drivers/media/platform/msm/wfd/mdp-5-subdev.c b/drivers/media/platform/msm/wfd/mdp-5-subdev.c
index 97204ae..a28cb1a 100644
--- a/drivers/media/platform/msm/wfd/mdp-5-subdev.c
+++ b/drivers/media/platform/msm/wfd/mdp-5-subdev.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -208,6 +208,7 @@
return -EINVAL;
}
+ msm_fb_writeback_iommu_ref(inst->mdp, true);
if (inst->secure) {
rc = msm_ion_secure_buffer(mmap->ion_client,
mregion->ion_handle, VIDEO_PIXEL, 0);
@@ -231,12 +232,15 @@
!inst->secure ? "non" : "", rc);
goto iommu_fail;
}
+ msm_fb_writeback_iommu_ref(inst->mdp, false);
return 0;
iommu_fail:
if (inst->secure)
msm_ion_unsecure_buffer(mmap->ion_client, mregion->ion_handle);
secure_fail:
+ msm_fb_writeback_iommu_ref(inst->mdp, false);
+
return rc;
}
@@ -251,10 +255,10 @@
WFD_MSG_ERR("Invalid argument\n");
return -EINVAL;
}
-
inst = mmap->cookie;
mregion = mmap->mregion;
+ msm_fb_writeback_iommu_ref(inst->mdp, true);
domain = msm_fb_get_iommu_domain(inst->mdp,
inst->secure ? MDP_IOMMU_DOMAIN_CP :
MDP_IOMMU_DOMAIN_NS);
@@ -264,6 +268,7 @@
if (inst->secure)
msm_ion_unsecure_buffer(mmap->ion_client, mregion->ion_handle);
+ msm_fb_writeback_iommu_ref(inst->mdp, false);
return 0;
}
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 99f6b5a..1839d07 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -4014,6 +4014,83 @@
return ret;
}
+static int qseecom_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ int ret = 0;
+ struct qseecom_clk *qclk;
+ qclk = &qseecom.qsee;
+
+ if (qseecom.cumulative_mode != INACTIVE) {
+ ret = __qseecom_set_msm_bus_request(INACTIVE);
+ if (ret)
+ pr_err("Fail to scale down bus\n");
+ }
+ mutex_lock(&clk_access_lock);
+ if (qclk->clk_access_cnt) {
+ if (qclk->ce_clk != NULL)
+ clk_disable_unprepare(qclk->ce_clk);
+ if (qclk->ce_core_clk != NULL)
+ clk_disable_unprepare(qclk->ce_core_clk);
+ if (qclk->ce_bus_clk != NULL)
+ clk_disable_unprepare(qclk->ce_bus_clk);
+ }
+ mutex_unlock(&clk_access_lock);
+ return 0;
+}
+
+static int qseecom_resume(struct platform_device *pdev)
+{
+ int mode = 0;
+ int ret = 0;
+ struct qseecom_clk *qclk;
+ qclk = &qseecom.qsee;
+
+ if (qseecom.cumulative_mode >= HIGH)
+ mode = HIGH;
+ else
+ mode = qseecom.cumulative_mode;
+
+ if (qseecom.cumulative_mode != INACTIVE) {
+ ret = __qseecom_set_msm_bus_request(mode);
+ if (ret)
+ pr_err("Fail to scale down bus\n");
+ }
+
+ mutex_lock(&clk_access_lock);
+ if (qclk->clk_access_cnt) {
+
+ ret = clk_prepare_enable(qclk->ce_core_clk);
+ if (ret) {
+ pr_err("Unable to enable/prepare CE core clk\n");
+ qclk->clk_access_cnt = 0;
+ goto err;
+ }
+
+ ret = clk_prepare_enable(qclk->ce_clk);
+ if (ret) {
+ pr_err("Unable to enable/prepare CE iface clk\n");
+ qclk->clk_access_cnt = 0;
+ goto ce_clk_err;
+ }
+
+ ret = clk_prepare_enable(qclk->ce_bus_clk);
+ if (ret) {
+ pr_err("Unable to enable/prepare CE bus clk\n");
+ qclk->clk_access_cnt = 0;
+ goto ce_bus_clk_err;
+ }
+ }
+ mutex_unlock(&clk_access_lock);
+ return 0;
+
+ce_bus_clk_err:
+ clk_disable_unprepare(qclk->ce_clk);
+ce_clk_err:
+ clk_disable_unprepare(qclk->ce_core_clk);
+err:
+ mutex_unlock(&clk_access_lock);
+ return -EIO;
+}
static struct of_device_id qseecom_match[] = {
{
.compatible = "qcom,qseecom",
@@ -4024,6 +4101,8 @@
static struct platform_driver qseecom_plat_driver = {
.probe = qseecom_probe,
.remove = qseecom_remove,
+ .suspend = qseecom_suspend,
+ .resume = qseecom_resume,
.driver = {
.name = "qseecom",
.owner = THIS_MODULE,
diff --git a/drivers/platform/msm/qpnp-power-on.c b/drivers/platform/msm/qpnp-power-on.c
index 507d02c..0ef2639 100644
--- a/drivers/platform/msm/qpnp-power-on.c
+++ b/drivers/platform/msm/qpnp-power-on.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -52,8 +52,15 @@
#define QPNP_PON_PS_HOLD_RST_CTL2(base) (base + 0x5B)
#define QPNP_PON_WD_RST_S2_CTL(base) (base + 0x56)
#define QPNP_PON_WD_RST_S2_CTL2(base) (base + 0x57)
-#define QPNP_PON_TRIGGER_EN(base) (base + 0x80)
+#define QPNP_PON_S3_SRC(base) (base + 0x74)
#define QPNP_PON_S3_DBC_CTL(base) (base + 0x75)
+#define QPNP_PON_TRIGGER_EN(base) (base + 0x80)
+
+#define QPNP_PON_S3_SRC_KPDPWR 0
+#define QPNP_PON_S3_SRC_RESIN 1
+#define QPNP_PON_S3_SRC_KPDPWR_OR_RESIN 2
+#define QPNP_PON_S3_SRC_KPDPWR_AND_RESIN 3
+#define QPNP_PON_S3_SRC_MASK 0x3
#define QPNP_PON_WARM_RESET_TFT BIT(4)
@@ -990,7 +997,17 @@
"Unable to config pon reset\n");
goto unreg_input_dev;
}
+ } else {
+ /* disable S2 reset */
+ rc = qpnp_pon_masked_write(pon, cfg->s2_cntl2_addr,
+ QPNP_PON_S2_CNTL_EN, 0);
+ if (rc) {
+ dev_err(&pon->spmi->dev,
+ "Unable to disable S2 reset\n");
+ goto unreg_input_dev;
+ }
}
+
rc = qpnp_pon_request_irqs(pon, cfg);
if (rc) {
dev_err(&pon->spmi->dev, "Unable to request-irq's\n");
@@ -1019,6 +1036,8 @@
u32 delay = 0, s3_debounce = 0;
int rc, sys_reset, index;
u8 pon_sts = 0;
+ const char *s3_src;
+ u8 s3_src_reg;
pon = devm_kzalloc(&spmi->dev, sizeof(struct qpnp_pon),
GFP_KERNEL);
@@ -1119,6 +1138,32 @@
}
}
+ /* program s3 source */
+ s3_src = "kpdpwr-and-resin";
+ rc = of_property_read_string(pon->spmi->dev.of_node,
+ "qcom,s3-src", &s3_src);
+ if (rc && rc != -EINVAL) {
+ dev_err(&pon->spmi->dev, "Unable to read s3 timer\n");
+ return rc;
+ }
+
+ if (!strcmp(s3_src, "kpdpwr"))
+ s3_src_reg = QPNP_PON_S3_SRC_KPDPWR;
+ else if (!strcmp(s3_src, "resin"))
+ s3_src_reg = QPNP_PON_S3_SRC_RESIN;
+ else if (!strcmp(s3_src, "kpdpwr-or-resin"))
+ s3_src_reg = QPNP_PON_S3_SRC_KPDPWR_OR_RESIN;
+ else /* default combination */
+ s3_src_reg = QPNP_PON_S3_SRC_KPDPWR_AND_RESIN;
+
+ rc = qpnp_pon_masked_write(pon, QPNP_PON_S3_SRC(pon->base),
+ QPNP_PON_S3_SRC_MASK, s3_src_reg);
+ if (rc) {
+ dev_err(&spmi->dev,
+ "Unable to program s3 source\n");
+ return rc;
+ }
+
dev_set_drvdata(&spmi->dev, pon);
INIT_DELAYED_WORK(&pon->bark_work, bark_work_func);
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c
index 734619f..a2bc2d9 100644
--- a/drivers/usb/gadget/u_ether.c
+++ b/drivers/usb/gadget/u_ether.c
@@ -532,7 +532,7 @@
spin_lock(&dev->req_lock);
list_add_tail(&req->list, &dev->tx_reqs);
- if (dev->port_usb->multi_pkt_xfer) {
+ if (dev->port_usb->multi_pkt_xfer && !req->context) {
dev->no_tx_req_used--;
req->length = 0;
in = dev->port_usb->in_ep;
@@ -598,6 +598,14 @@
}
} else {
skb = req->context;
+ /* Is aggregation already enabled and buffers allocated ? */
+ if (dev->port_usb->multi_pkt_xfer && dev->tx_req_bufsize) {
+ req->buf = kzalloc(dev->tx_req_bufsize, GFP_ATOMIC);
+ req->context = NULL;
+ } else {
+ req->buf = NULL;
+ }
+
spin_unlock(&dev->req_lock);
dev_kfree_skb_any(skb);
}
@@ -625,11 +633,14 @@
list_for_each(act, &dev->tx_reqs) {
req = container_of(act, struct usb_request, list);
- if (!req->buf)
+ if (!req->buf) {
req->buf = kzalloc(dev->tx_req_bufsize,
GFP_ATOMIC);
if (!req->buf)
goto free_buf;
+ }
+ /* req->context is not used for multi_pkt_xfers */
+ req->context = NULL;
}
return 0;
@@ -673,11 +684,15 @@
}
/* Allocate memory for tx_reqs to support multi packet transfer */
+ spin_lock_irqsave(&dev->req_lock, flags);
if (multi_pkt_xfer && !dev->tx_req_bufsize) {
retval = alloc_tx_buffer(dev);
- if (retval < 0)
+ if (retval < 0) {
+ spin_unlock_irqrestore(&dev->req_lock, flags);
return -ENOMEM;
+ }
}
+ spin_unlock_irqrestore(&dev->req_lock, flags);
/* apply outgoing CDC or RNDIS filters */
if (!is_promisc(cdc_filter)) {
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 47b8e59..3fa508c 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -455,8 +455,10 @@
dev_dbg(motg->phy.dev, "block_reset DEASSERT\n");
ret = clk_reset(motg->core_clk, CLK_RESET_DEASSERT);
ndelay(200);
- clk_prepare_enable(motg->core_clk);
- clk_prepare_enable(motg->pclk);
+ ret = clk_prepare_enable(motg->core_clk);
+ WARN(ret, "USB core_clk enable failed\n");
+ ret = clk_prepare_enable(motg->pclk);
+ WARN(ret, "USB pclk enable failed\n");
}
if (ret)
dev_err(motg->phy.dev, "usb hs_clk deassert failed\n");
@@ -1167,8 +1169,10 @@
}
if (motg->lpm_flags & CLOCKS_DOWN) {
- clk_prepare_enable(motg->core_clk);
- clk_prepare_enable(motg->pclk);
+ ret = clk_prepare_enable(motg->core_clk);
+ WARN(ret, "USB core_clk enable failed\n");
+ ret = clk_prepare_enable(motg->pclk);
+ WARN(ret, "USB pclk enable failed\n");
motg->lpm_flags &= ~CLOCKS_DOWN;
}
diff --git a/drivers/video/msm/mdss/mdss_dsi.c b/drivers/video/msm/mdss/mdss_dsi.c
index 44cc4a2..2efb973 100644
--- a/drivers/video/msm/mdss/mdss_dsi.c
+++ b/drivers/video/msm/mdss/mdss_dsi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -316,20 +316,10 @@
/* disable DSI controller */
mdss_dsi_controller_cfg(0, pdata);
- mdss_dsi_clk_ctrl(ctrl_pdata, 0);
-
- ret = mdss_dsi_enable_bus_clocks(ctrl_pdata);
- if (ret) {
- pr_err("%s: failed to enable bus clocks. rc=%d\n", __func__,
- ret);
- mdss_dsi_panel_power_on(pdata, 0);
- return ret;
- }
-
/* disable DSI phy */
- mdss_dsi_phy_enable(ctrl_pdata, 0);
+ mdss_dsi_phy_disable(ctrl_pdata);
- mdss_dsi_disable_bus_clocks(ctrl_pdata);
+ mdss_dsi_clk_ctrl(ctrl_pdata, 0);
ret = mdss_dsi_panel_power_on(pdata, 0);
if (ret) {
@@ -389,7 +379,7 @@
if (!pdata->panel_info.mipi.lp11_init)
mdss_dsi_panel_reset(pdata, 1);
- ret = mdss_dsi_enable_bus_clocks(ctrl_pdata);
+ ret = mdss_dsi_bus_clk_start(ctrl_pdata);
if (ret) {
pr_err("%s: failed to enable bus clocks. rc=%d\n", __func__,
ret);
@@ -400,7 +390,7 @@
mdss_dsi_phy_sw_reset((ctrl_pdata->ctrl_base));
mdss_dsi_phy_init(pdata);
- mdss_dsi_disable_bus_clocks(ctrl_pdata);
+ mdss_dsi_bus_clk_stop(ctrl_pdata);
mdss_dsi_clk_ctrl(ctrl_pdata, 1);
@@ -850,35 +840,39 @@
static struct device_node *mdss_dsi_find_panel_of_node(
struct platform_device *pdev, char *panel_cfg)
{
- int l;
- int ctrl_id = -1;
- char *panel_name;
+ int len, i;
+ int ctrl_id = pdev->id - 1;
+ char panel_name[MDSS_MAX_PANEL_LEN];
+ char ctrl_id_stream[3] = "0:";
+ char *stream = NULL, *pan = NULL;
struct device_node *dsi_pan_node = NULL, *mdss_node = NULL;
- l = strlen(panel_cfg);
- if (!l) {
+ len = strlen(panel_cfg);
+ if (!len) {
/* no panel cfg chg, parse dt */
pr_debug("%s:%d: no cmd line cfg present\n",
__func__, __LINE__);
- dsi_pan_node = mdss_dsi_pref_prim_panel(pdev);
+ goto end;
} else {
- if (panel_cfg[0] == '0') {
- pr_debug("%s:%d: DSI ctrl 1\n", __func__, __LINE__);
- ctrl_id = 0;
- } else if (panel_cfg[0] == '1') {
- pr_debug("%s:%d: DSI ctrl 2\n", __func__, __LINE__);
- ctrl_id = 1;
+ if (ctrl_id == 1)
+ strlcpy(ctrl_id_stream, "1:", 3);
+
+ stream = strnstr(panel_cfg, ctrl_id_stream, len);
+ if (!stream) {
+ pr_err("controller config is not present\n");
+ goto end;
}
- if ((pdev->id - 1) != ctrl_id) {
- pr_err("%s:%d:pdev_ID=[%d]\n",
- __func__, __LINE__, pdev->id);
- return NULL;
+ stream += 2;
+
+ pan = strnchr(stream, strlen(stream), ':');
+ if (!pan) {
+ strlcpy(panel_name, stream, MDSS_MAX_PANEL_LEN);
+ } else {
+ for (i = 0; (stream + i) < pan; i++)
+ panel_name[i] = *(stream + i);
+ panel_name[i] = 0;
}
- /*
- * skip first two chars '<dsi_ctrl_id>' and
- * ':' to get to the panel name
- */
- panel_name = panel_cfg + 2;
+
pr_debug("%s:%d:%s:%s\n", __func__, __LINE__,
panel_cfg, panel_name);
@@ -895,9 +889,12 @@
if (!dsi_pan_node) {
pr_err("%s: invalid pan node, selecting prim panel\n",
__func__);
- dsi_pan_node = mdss_dsi_pref_prim_panel(pdev);
+ goto end;
}
+ return dsi_pan_node;
}
+end:
+ dsi_pan_node = mdss_dsi_pref_prim_panel(pdev);
return dsi_pan_node;
}
diff --git a/drivers/video/msm/mdss/mdss_dsi.h b/drivers/video/msm/mdss/mdss_dsi.h
index b89a935..2c9c37d 100644
--- a/drivers/video/msm/mdss/mdss_dsi.h
+++ b/drivers/video/msm/mdss/mdss_dsi.h
@@ -227,6 +227,8 @@
#define DSI_EV_MDP_FIFO_UNDERFLOW 0x0002
#define DSI_EV_MDP_BUSY_RELEASE 0x80000000
+#define DSI_FLAG_CLOCK_MASTER 0x80000000
+
struct mdss_dsi_ctrl_pdata {
int ndx; /* panel_num */
int (*on) (struct mdss_panel_data *pdata);
@@ -238,6 +240,8 @@
unsigned char *ctrl_base;
int reg_size;
u32 clk_cnt;
+ int clk_cnt_sub;
+ u32 flags;
struct clk *mdp_core_clk;
struct clk *ahb_clk;
struct clk *axi_clk;
@@ -308,13 +312,20 @@
void mdss_dsi_cmd_mdp_start(struct mdss_dsi_ctrl_pdata *ctrl);
void mdss_dsi_cmd_bta_sw_trigger(struct mdss_panel_data *pdata);
void mdss_dsi_ack_err_status(struct mdss_dsi_ctrl_pdata *ctrl);
-int mdss_dsi_clk_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, int enable);
+void mdss_dsi_clk_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, int enable);
+int mdss_dsi_link_clk_start(struct mdss_dsi_ctrl_pdata *ctrl);
+void mdss_dsi_link_clk_stop(struct mdss_dsi_ctrl_pdata *ctrl);
+int mdss_dsi_bus_clk_start(struct mdss_dsi_ctrl_pdata *ctrl);
+void mdss_dsi_bus_clk_stop(struct mdss_dsi_ctrl_pdata *ctrl);
void mdss_dsi_clk_req(struct mdss_dsi_ctrl_pdata *ctrl,
int enable);
void mdss_dsi_controller_cfg(int enable,
struct mdss_panel_data *pdata);
void mdss_dsi_sw_reset(struct mdss_panel_data *pdata);
+struct mdss_dsi_ctrl_pdata *mdss_dsi_ctrl_slave(
+ struct mdss_dsi_ctrl_pdata *ctrl);
+
irqreturn_t mdss_dsi_isr(int irq, void *ptr);
void mdss_dsi_irq_handler_config(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
@@ -327,7 +338,7 @@
int mdss_dsi_enable_bus_clocks(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
void mdss_dsi_disable_bus_clocks(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
void mdss_dsi_panel_reset(struct mdss_panel_data *pdata, int enable);
-void mdss_dsi_phy_enable(struct mdss_dsi_ctrl_pdata *ctrl, int on);
+void mdss_dsi_phy_disable(struct mdss_dsi_ctrl_pdata *ctrl);
void mdss_dsi_phy_init(struct mdss_panel_data *pdata);
void mdss_dsi_phy_sw_reset(unsigned char *ctrl_base);
void mdss_dsi_cmd_test_pattern(struct mdss_dsi_ctrl_pdata *ctrl);
diff --git a/drivers/video/msm/mdss/mdss_dsi_host.c b/drivers/video/msm/mdss/mdss_dsi_host.c
index bd156fc..b4478ac 100644
--- a/drivers/video/msm/mdss/mdss_dsi_host.c
+++ b/drivers/video/msm/mdss/mdss_dsi_host.c
@@ -92,6 +92,10 @@
ctrl_list[ctrl->ndx] = ctrl; /* keep it */
+ if (ctrl->shared_pdata.broadcast_enable)
+ if (ctrl->ndx == DSI_CTRL_1)
+ ctrl->flags |= DSI_FLAG_CLOCK_MASTER;
+
if (mdss_register_irq(ctrl->dsi_hw))
pr_err("%s: mdss_register_irq failed.\n", __func__);
@@ -117,6 +121,22 @@
}
}
+struct mdss_dsi_ctrl_pdata *mdss_dsi_ctrl_slave(
+ struct mdss_dsi_ctrl_pdata *ctrl)
+{
+ int ndx;
+ struct mdss_dsi_ctrl_pdata *sctrl = NULL;
+
+ /* only two controllers */
+ ndx = ctrl->ndx;
+ ndx += 1;
+ ndx %= DSI_CTRL_MAX;
+ sctrl = ctrl_list[ndx];
+
+ return sctrl;
+
+}
+
void mdss_dsi_clk_req(struct mdss_dsi_ctrl_pdata *ctrl, int enable)
{
if (enable == 0) {
@@ -1460,10 +1480,10 @@
MIPI_OUTP(left_ctrl_pdata->ctrl_base + 0x0110, isr0);
}
- pr_debug("%s: isr=%x", __func__, isr);
+ pr_debug("%s: ndx=%d isr=%x\n", __func__, ctrl->ndx, isr);
if (isr & DSI_INTR_ERROR) {
- pr_err("%s: isr=%x %x", __func__, isr, (int)DSI_INTR_ERROR);
+ pr_err("%s: ndx=%d isr=%x\n", __func__, ctrl->ndx, isr);
mdss_dsi_error(ctrl);
}
diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c
index 088472f..eeb697b 100644
--- a/drivers/video/msm/mdss/mdss_mdp.c
+++ b/drivers/video/msm/mdss/mdss_mdp.c
@@ -1044,6 +1044,14 @@
return rc;
}
+/**
+ * mdss_mdp_footswitch_ctrl_splash() - clocks handoff for cont. splash screen
+ * @on: 1 to start handoff, 0 to complete the handoff after first frame update
+ *
+ * MDSS Clocks and GDSC are already on during continous splash screen, but
+ * increasing ref count will keep clocks from being turned off until handoff
+ * has properly happend after frame update.
+ */
void mdss_mdp_footswitch_ctrl_splash(int on)
{
struct mdss_data_type *mdata = mdss_mdp_get_mdata();
@@ -1052,9 +1060,11 @@
pr_debug("Enable MDP FS for splash.\n");
mdata->handoff_pending = true;
regulator_enable(mdata->fs);
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
mdss_hw_init(mdata);
} else {
pr_debug("Disable MDP FS for splash.\n");
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
regulator_disable(mdata->fs);
mdata->handoff_pending = false;
}
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index 1a4885c..18b6338 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -1085,8 +1085,21 @@
return 0;
}
+static inline struct mdss_mdp_ctl *mdss_mdp_get_split_ctl(
+ struct mdss_mdp_ctl *ctl)
+{
+ if (ctl && ctl->mixer_right && (ctl->mixer_right->ctl != ctl))
+ return ctl->mixer_right->ctl;
+
+ return NULL;
+}
+
int mdss_mdp_ctl_splash_finish(struct mdss_mdp_ctl *ctl, bool handoff)
{
+ struct mdss_mdp_ctl *sctl = mdss_mdp_get_split_ctl(ctl);
+ if (sctl)
+ sctl->panel_data->panel_info.cont_splash_enabled = 0;
+
switch (ctl->panel_data->panel_info.type) {
case MIPI_VIDEO_PANEL:
case EDP_PANEL:
@@ -1111,15 +1124,6 @@
return 0;
}
-static inline struct mdss_mdp_ctl *mdss_mdp_get_split_ctl(
- struct mdss_mdp_ctl *ctl)
-{
- if (ctl && ctl->mixer_right && (ctl->mixer_right->ctl != ctl))
- return ctl->mixer_right->ctl;
-
- return NULL;
-}
-
static int mdss_mdp_ctl_fbc_enable(int enable,
struct mdss_mdp_mixer *mixer, struct mdss_panel_info *pdata)
{
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
index ce0b757..79bdee2 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
@@ -435,7 +435,6 @@
pdata->panel_info.cont_splash_enabled = 0;
mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_PANEL_CLK_CTRL, (void *)0);
- mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
return ret;
}
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_video.c b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
index 7304694..55a4a4d 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_video.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
@@ -736,7 +736,6 @@
free_bootmem_late(mdp5_data->splash_mem_addr,
mdp5_data->splash_mem_size);
- mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
return ret;
}
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index 9365be8..baea509 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -682,6 +682,7 @@
if ((num_planes <= 0) || (num_planes > MAX_PLANES))
return -EINVAL;
+ mdss_bus_bandwidth_ctrl(1);
memset(data, 0, sizeof(*data));
for (i = 0; i < num_planes; i++) {
data->p[i].flags = flags;
@@ -695,6 +696,7 @@
break;
}
}
+ mdss_bus_bandwidth_ctrl(0);
data->num_planes = i;
@@ -704,8 +706,11 @@
int mdss_mdp_overlay_free_buf(struct mdss_mdp_data *data)
{
int i;
+
+ mdss_bus_bandwidth_ctrl(1);
for (i = 0; i < data->num_planes && data->p[i].len; i++)
mdss_mdp_put_img(&data->p[i]);
+ mdss_bus_bandwidth_ctrl(0);
data->num_planes = 0;
@@ -2540,14 +2545,9 @@
int mdss_panel_register_done(struct mdss_panel_data *pdata)
{
- /*
- * Clocks are already on if continuous splash is enabled,
- * increasing ref_cnt to help balance clocks once done.
- */
- if (pdata->panel_info.cont_splash_enabled) {
+ if (pdata->panel_info.cont_splash_enabled)
mdss_mdp_footswitch_ctrl_splash(1);
- mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
- }
+
return 0;
}
diff --git a/drivers/video/msm/mdss/mdss_mdp_wb.c b/drivers/video/msm/mdss/mdss_mdp_wb.c
index 6eb4d6e..454183d 100644
--- a/drivers/video/msm/mdss/mdss_mdp_wb.c
+++ b/drivers/video/msm/mdss/mdss_mdp_wb.c
@@ -894,3 +894,22 @@
return mdss_mdp_wb_set_secure(mfd, enable);
}
EXPORT_SYMBOL(msm_fb_writeback_set_secure);
+
+/**
+ * msm_fb_writeback_iommu_ref() - Power ON/OFF mdp clock
+ * @enable - true/false to Power ON/OFF mdp clock
+ *
+ * Call to enable mdp clock at start of mdp_mmap/mdp_munmap API and
+ * to disable mdp clock at end of these API's to ensure iommu is in
+ * proper state while driver map/un-map any buffers.
+ */
+int msm_fb_writeback_iommu_ref(struct fb_info *info, int enable)
+{
+ if (enable)
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
+ else
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
+
+ return 0;
+}
+EXPORT_SYMBOL(msm_fb_writeback_iommu_ref);
diff --git a/drivers/video/msm/mdss/msm_mdss_io_8974.c b/drivers/video/msm/mdss/msm_mdss_io_8974.c
index 5d4610c..6ebcdf6 100644
--- a/drivers/video/msm/mdss/msm_mdss_io_8974.c
+++ b/drivers/video/msm/mdss/msm_mdss_io_8974.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -247,10 +247,12 @@
return 0;
}
-int mdss_dsi_enable_bus_clocks(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
+int mdss_dsi_bus_clk_start(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
{
int rc = 0;
+ pr_debug("%s: ndx=%d\n", __func__, ctrl_pdata->ndx);
+
rc = clk_prepare_enable(ctrl_pdata->mdp_core_clk);
if (rc) {
pr_err("%s: failed to enable mdp_core_clock. rc=%d\n",
@@ -277,14 +279,14 @@
return rc;
}
-void mdss_dsi_disable_bus_clocks(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
+void mdss_dsi_bus_clk_stop(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
{
clk_disable_unprepare(ctrl_pdata->axi_clk);
clk_disable_unprepare(ctrl_pdata->ahb_clk);
clk_disable_unprepare(ctrl_pdata->mdp_core_clk);
}
-static int mdss_dsi_clk_prepare(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
+static int mdss_dsi_link_clk_prepare(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
{
int rc = 0;
@@ -316,7 +318,7 @@
return rc;
}
-static void mdss_dsi_clk_unprepare(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
+static void mdss_dsi_link_clk_unprepare(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
{
if (!ctrl_pdata) {
pr_err("%s: Invalid input data\n", __func__);
@@ -328,7 +330,7 @@
clk_unprepare(ctrl_pdata->esc_clk);
}
-static int mdss_dsi_clk_set_rate(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
+static int mdss_dsi_link_clk_set_rate(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
{
u32 esc_clk_rate = 19200000;
int rc = 0;
@@ -369,7 +371,7 @@
return rc;
}
-static int mdss_dsi_clk_enable(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
+static int mdss_dsi_link_clk_enable(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
{
int rc = 0;
@@ -378,6 +380,8 @@
return -EINVAL;
}
+ pr_debug("%s: ndx=%d\n", __func__, ctrl_pdata->ndx);
+
if (ctrl_pdata->mdss_dsi_clk_on) {
pr_info("%s: mdss_dsi_clks already ON\n", __func__);
return 0;
@@ -413,13 +417,15 @@
return rc;
}
-static void mdss_dsi_clk_disable(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
+static void mdss_dsi_link_clk_disable(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
{
if (!ctrl_pdata) {
pr_err("%s: Invalid input data\n", __func__);
return;
}
+ pr_debug("%s: ndx=%d\n", __func__, ctrl_pdata->ndx);
+
if (ctrl_pdata->mdss_dsi_clk_on == 0) {
pr_info("%s: mdss_dsi_clks already OFF\n", __func__);
return;
@@ -432,62 +438,110 @@
ctrl_pdata->mdss_dsi_clk_on = 0;
}
-int mdss_dsi_clk_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, int enable)
+int mdss_dsi_link_clk_start(struct mdss_dsi_ctrl_pdata *ctrl)
{
int rc = 0;
- mutex_lock(&ctrl->mutex);
+ rc = mdss_dsi_link_clk_set_rate(ctrl);
+ if (rc) {
+ pr_err("%s: failed to set clk rates. rc=%d\n",
+ __func__, rc);
+ goto error;
+ }
+
+ rc = mdss_dsi_link_clk_prepare(ctrl);
+ if (rc) {
+ pr_err("%s: failed to prepare clks. rc=%d\n",
+ __func__, rc);
+ goto error;
+ }
+
+ rc = mdss_dsi_link_clk_enable(ctrl);
+ if (rc) {
+ pr_err("%s: failed to enable clks. rc=%d\n",
+ __func__, rc);
+ mdss_dsi_link_clk_unprepare(ctrl);
+ goto error;
+ }
+
+error:
+ return rc;
+}
+
+void mdss_dsi_link_clk_stop(struct mdss_dsi_ctrl_pdata *ctrl)
+{
+ mdss_dsi_link_clk_disable(ctrl);
+ mdss_dsi_link_clk_unprepare(ctrl);
+}
+
+static void mdss_dsi_clk_ctrl_sub(struct mdss_dsi_ctrl_pdata *ctrl, int enable)
+{
+ int changed = 0;
+
if (enable) {
- if (ctrl->clk_cnt == 0) {
- rc = mdss_dsi_enable_bus_clocks(ctrl);
- if (rc) {
- pr_err("%s: failed to enable bus clks. rc=%d\n",
- __func__, rc);
- goto error;
- }
-
- rc = mdss_dsi_clk_set_rate(ctrl);
- if (rc) {
- pr_err("%s: failed to set clk rates. rc=%d\n",
- __func__, rc);
- mdss_dsi_disable_bus_clocks(ctrl);
- goto error;
- }
-
- rc = mdss_dsi_clk_prepare(ctrl);
- if (rc) {
- pr_err("%s: failed to prepare clks. rc=%d\n",
- __func__, rc);
- mdss_dsi_disable_bus_clocks(ctrl);
- goto error;
- }
-
- rc = mdss_dsi_clk_enable(ctrl);
- if (rc) {
- pr_err("%s: failed to enable clks. rc=%d\n",
- __func__, rc);
- mdss_dsi_clk_unprepare(ctrl);
- mdss_dsi_disable_bus_clocks(ctrl);
- goto error;
- }
+ if (ctrl->clk_cnt_sub == 0)
+ changed++;
+ ctrl->clk_cnt_sub++;
+ } else {
+ if (ctrl->clk_cnt_sub) {
+ ctrl->clk_cnt_sub--;
+ if (ctrl->clk_cnt_sub == 0)
+ changed++;
+ } else {
+ pr_debug("%s: Can not be turned off\n", __func__);
}
+ }
+
+ pr_debug("%s: ndx=%d clk_cnt_sub=%d changed=%d enable=%d\n",
+ __func__, ctrl->ndx, ctrl->clk_cnt_sub, changed, enable);
+ if (changed) {
+ if (enable) {
+ if (mdss_dsi_bus_clk_start(ctrl) == 0)
+ mdss_dsi_link_clk_start(ctrl);
+ } else {
+ mdss_dsi_link_clk_stop(ctrl);
+ mdss_dsi_bus_clk_stop(ctrl);
+ }
+ }
+}
+
+static DEFINE_MUTEX(dsi_clk_lock); /* per system */
+
+void mdss_dsi_clk_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, int enable)
+{
+ int changed = 0;
+ struct mdss_dsi_ctrl_pdata *sctrl = NULL;
+
+ mutex_lock(&dsi_clk_lock);
+ if (enable) {
+ if (ctrl->clk_cnt == 0)
+ changed++;
ctrl->clk_cnt++;
} else {
if (ctrl->clk_cnt) {
ctrl->clk_cnt--;
- if (ctrl->clk_cnt == 0) {
- mdss_dsi_clk_disable(ctrl);
- mdss_dsi_clk_unprepare(ctrl);
- mdss_dsi_disable_bus_clocks(ctrl);
- }
+ if (ctrl->clk_cnt == 0)
+ changed++;
+ } else {
+ pr_debug("%s: Can not be turned off\n", __func__);
}
}
- pr_debug("%s: ctrl ndx=%d enabled=%d clk_cnt=%d\n",
- __func__, ctrl->ndx, enable, ctrl->clk_cnt);
-error:
- mutex_unlock(&ctrl->mutex);
- return rc;
+ pr_debug("%s: ndx=%d clk_cnt=%d changed=%d enable=%d\n",
+ __func__, ctrl->ndx, ctrl->clk_cnt, changed, enable);
+ if (ctrl->flags & DSI_FLAG_CLOCK_MASTER)
+ sctrl = mdss_dsi_ctrl_slave(ctrl);
+
+ if (changed) {
+ if (enable && sctrl)
+ mdss_dsi_clk_ctrl_sub(sctrl, enable);
+
+ mdss_dsi_clk_ctrl_sub(ctrl, enable);
+
+ if (!enable && sctrl)
+ mdss_dsi_clk_ctrl_sub(sctrl, enable);
+ }
+ mutex_unlock(&dsi_clk_lock);
}
void mdss_dsi_phy_sw_reset(unsigned char *ctrl_base)
@@ -502,7 +556,7 @@
wmb();
}
-void mdss_dsi_phy_enable(struct mdss_dsi_ctrl_pdata *ctrl, int on)
+void mdss_dsi_phy_disable(struct mdss_dsi_ctrl_pdata *ctrl)
{
static struct mdss_dsi_ctrl_pdata *left_ctrl;
@@ -511,59 +565,28 @@
return;
}
- if (!left_ctrl
- && ctrl->shared_pdata.broadcast_enable)
- if ((ctrl->panel_data).panel_info.pdest
- == DISPLAY_1)
- left_ctrl = ctrl;
+ if (left_ctrl &&
+ (ctrl->panel_data.panel_info.pdest == DISPLAY_1))
+ return;
- if (on) {
- MIPI_OUTP(ctrl->ctrl_base + 0x03cc, 0x03);
- wmb();
- usleep(100);
- MIPI_OUTP(ctrl->ctrl_base + 0x0220, 0x006);
- wmb();
- usleep(100);
- MIPI_OUTP(ctrl->ctrl_base + 0x0268, 0x001);
- wmb();
- usleep(100);
- MIPI_OUTP(ctrl->ctrl_base + 0x0268, 0x000);
- wmb();
- usleep(100);
- MIPI_OUTP(ctrl->ctrl_base + 0x0220, 0x007);
- wmb();
- MIPI_OUTP(ctrl->ctrl_base + 0x03cc, 0x01);
- wmb();
- usleep(100);
-
- /* MMSS_DSI_0_PHY_DSIPHY_CTRL_0 */
- MIPI_OUTP(ctrl->ctrl_base + 0x0470, 0x07e);
- MIPI_OUTP(ctrl->ctrl_base + 0x0470, 0x06e);
- MIPI_OUTP(ctrl->ctrl_base + 0x0470, 0x06c);
- MIPI_OUTP(ctrl->ctrl_base + 0x0470, 0x064);
- MIPI_OUTP(ctrl->ctrl_base + 0x0470, 0x065);
- MIPI_OUTP(ctrl->ctrl_base + 0x0470, 0x075);
- MIPI_OUTP(ctrl->ctrl_base + 0x0470, 0x077);
- MIPI_OUTP(ctrl->ctrl_base + 0x0470, 0x07f);
- wmb();
- } else {
- if (left_ctrl &&
+ if (left_ctrl &&
(ctrl->panel_data.panel_info.pdest
- == DISPLAY_1))
- return;
-
- if (left_ctrl &&
- (ctrl->panel_data.panel_info.pdest
- == DISPLAY_2)) {
- MIPI_OUTP(left_ctrl->ctrl_base + 0x0220, 0x006);
- MIPI_OUTP(left_ctrl->ctrl_base + 0x0470, 0x000);
- MIPI_OUTP(left_ctrl->ctrl_base + 0x0598, 0x000);
- }
- MIPI_OUTP(ctrl->ctrl_base + 0x0220, 0x006);
- MIPI_OUTP(ctrl->ctrl_base + 0x0470, 0x000);
- MIPI_OUTP(ctrl->ctrl_base + 0x0598, 0x000);
- wmb();
+ ==
+ DISPLAY_2)) {
+ MIPI_OUTP(left_ctrl->ctrl_base + 0x0470,
+ 0x000);
+ MIPI_OUTP(left_ctrl->ctrl_base + 0x0598,
+ 0x000);
}
+
+ MIPI_OUTP(ctrl->ctrl_base + 0x0470, 0x000);
+ MIPI_OUTP(ctrl->ctrl_base + 0x0598, 0x000);
+
+ /*
+ * Wait for the registers writes to complete in order to
+ * ensure that the phy is completely disabled
+ */
+ wmb();
}
void mdss_dsi_phy_init(struct mdss_panel_data *pdata)
diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h
index f36ee04..45975f9 100644
--- a/include/linux/msm_mdp.h
+++ b/include/linux/msm_mdp.h
@@ -1,7 +1,7 @@
/* include/linux/msm_mdp.h
*
* Copyright (C) 2007 Google Incorporated
- * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -1063,6 +1063,7 @@
int msm_fb_writeback_stop(struct fb_info *info);
int msm_fb_writeback_terminate(struct fb_info *info);
int msm_fb_writeback_set_secure(struct fb_info *info, int enable);
+int msm_fb_writeback_iommu_ref(struct fb_info *info, int enable);
#endif
#endif /*_MSM_MDP_H_*/
diff --git a/include/linux/regulator/cpr-regulator.h b/include/linux/regulator/cpr-regulator.h
index e6a8f58..9d06a8c 100644
--- a/include/linux/regulator/cpr-regulator.h
+++ b/include/linux/regulator/cpr-regulator.h
@@ -18,9 +18,6 @@
#define CPR_REGULATOR_DRIVER_NAME "qcom,cpr-regulator"
-#define CPR_PVS_EFUSE_BITS_MAX 5
-#define CPR_PVS_EFUSE_BINS_MAX (1 << CPR_PVS_EFUSE_BITS_MAX)
-
/**
* enum cpr_fuse_corner_enum - CPR fuse corner enum values
* %CPR_FUSE_CORNER_SVS: Lowest voltage for APC
@@ -70,21 +67,6 @@
};
/**
- * enum pvs_process_enum - PVS process enum values
- * %APC_PVS_NO: No PVS
- * %APC_PVS_SLOW: Slow PVS process
- * %APC_PVS_NOM: Nominal PVS process
- * %APC_PVS_FAST: Fast PVS process
- */
-enum apc_pvs_process_enum {
- APC_PVS_NO,
- APC_PVS_SLOW,
- APC_PVS_NOM,
- APC_PVS_FAST,
- NUM_APC_PVS,
-};
-
-/**
* enum vdd_mx_vmin_method - Method to determine vmin for vdd-mx
* %VDD_MX_VMIN_APC: Equal to APC voltage
* %VDD_MX_VMIN_APC_CORNER_CEILING: Equal to PVS corner ceiling voltage
diff --git a/include/media/msm_cam_sensor.h b/include/media/msm_cam_sensor.h
index d87be94..e301d8f 100644
--- a/include/media/msm_cam_sensor.h
+++ b/include/media/msm_cam_sensor.h
@@ -94,6 +94,8 @@
SENSOR_GPIO_VANA,
SENSOR_GPIO_VDIG,
SENSOR_GPIO_VAF,
+ SENSOR_GPIO_FL_EN,
+ SENSOR_GPIO_FL_NOW,
SENSOR_GPIO_MAX,
};
@@ -221,6 +223,8 @@
struct msm_sensor_power_setting_array {
struct msm_sensor_power_setting *power_setting;
uint16_t size;
+ struct msm_sensor_power_setting *power_down_setting;
+ uint16_t size_down;
};
struct msm_sensor_id_info_t {
@@ -244,6 +248,8 @@
struct msm_camera_sensor_slave_info {
char sensor_name[32];
+ char eeprom_name[32];
+ char actuator_name[32];
enum msm_sensor_camera_id_t camera_id;
uint16_t slave_addr;
enum msm_camera_i2c_reg_addr_type addr_type;
@@ -402,6 +408,7 @@
CFG_EEPROM_GET_CAL_DATA,
CFG_EEPROM_READ_CAL_DATA,
CFG_EEPROM_WRITE_DATA,
+ CFG_EEPROM_GET_MM_INFO,
};
struct eeprom_get_t {
@@ -418,6 +425,12 @@
uint32_t num_bytes;
};
+struct eeprom_get_mm_t {
+ uint32_t mm_support;
+ uint32_t mm_compression;
+ uint32_t mm_size;
+};
+
struct msm_eeprom_cfg_data {
enum eeprom_cfg_type_t cfgtype;
uint8_t is_supported;
@@ -426,6 +439,7 @@
struct eeprom_get_t get_data;
struct eeprom_read_t read_data;
struct eeprom_write_t write_data;
+ struct eeprom_get_mm_t get_mm_data;
} cfg;
};
diff --git a/include/media/msmb_pproc.h b/include/media/msmb_pproc.h
index ed4ffa2..26c1048 100644
--- a/include/media/msmb_pproc.h
+++ b/include/media/msmb_pproc.h
@@ -229,6 +229,9 @@
#define VIDIOC_MSM_CPP_QUEUE_BUF \
_IOWR('V', BASE_VIDIOC_PRIVATE + 14, struct msm_camera_v4l2_ioctl_t)
+#define VIDIOC_MSM_CPP_APPEND_STREAM_BUFF_INFO \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 15, struct msm_camera_v4l2_ioctl_t)
+
#define V4L2_EVENT_CPP_FRAME_DONE (V4L2_EVENT_PRIVATE_START + 0)
#define V4L2_EVENT_VPE_FRAME_DONE (V4L2_EVENT_PRIVATE_START + 1)
diff --git a/sound/soc/codecs/msm8x10-wcd.c b/sound/soc/codecs/msm8x10-wcd.c
index fe4eb34..452bbab 100644
--- a/sound/soc/codecs/msm8x10-wcd.c
+++ b/sound/soc/codecs/msm8x10-wcd.c
@@ -189,6 +189,7 @@
* end of impedance measurement
*/
struct list_head reg_save_restore;
+ u32 micb_en_count;
};
static unsigned short rx_digital_gain_reg[] = {
@@ -1697,6 +1698,9 @@
snd_soc_update_bits(codec, micb_int_reg, 0x04, 0x04);
snd_soc_update_bits(codec, MSM8X10_WCD_A_MICB_1_CTL,
0x80, 0x80);
+ msm8x10_wcd->micb_en_count++;
+ pr_debug("%s micb_en_count : %d", __func__,
+ msm8x10_wcd->micb_en_count);
break;
case SND_SOC_DAPM_POST_PMU:
usleep_range(20000, 20100);
@@ -1704,6 +1708,10 @@
wcd9xxx_resmgr_notifier_call(&msm8x10_wcd->resmgr, e_post_on);
break;
case SND_SOC_DAPM_POST_PMD:
+ if (msm8x10_wcd->micb_en_count > 0)
+ msm8x10_wcd->micb_en_count--;
+ pr_debug("%s micb_en_count : %d", __func__,
+ msm8x10_wcd->micb_en_count);
snd_soc_update_bits(codec, MSM8X10_WCD_A_MICB_1_CTL,
0x80, 0x00);
/* Let MBHC module know so micbias switch to be off */
@@ -2802,6 +2810,7 @@
enum wcd9xxx_micbias_num micb_num)
{
int rc;
+ struct msm8x10_wcd_priv *msm8x10_wcd = snd_soc_codec_get_drvdata(codec);
if (micb_num != MBHC_MICBIAS1) {
rc = -EINVAL;
@@ -2811,13 +2820,18 @@
if (enable)
rc = snd_soc_dapm_force_enable_pin(&codec->dapm,
DAPM_MICBIAS_EXTERNAL_STANDALONE);
- else
+ else {
+ if (msm8x10_wcd->micb_en_count > 0) {
+ msm8x10_wcd->micb_en_count--;
+ pr_debug("%s micb_en_count : %d", __func__,
+ msm8x10_wcd->micb_en_count);
+ return 0;
+ }
rc = snd_soc_dapm_disable_pin(&codec->dapm,
DAPM_MICBIAS_EXTERNAL_STANDALONE);
+ }
snd_soc_dapm_sync(&codec->dapm);
- snd_soc_update_bits(codec, WCD9XXX_A_MICB_1_CTL,
- 0x80, enable ? 0x80 : 0x00);
err:
if (rc)
pr_debug("%s: Failed to force %s micbias", __func__,
@@ -3291,6 +3305,8 @@
on_demand_supply_name[ON_DEMAND_MICBIAS]);
atomic_set(&msm8x10_wcd_priv->on_demand_list[ON_DEMAND_MICBIAS].ref, 0);
+ msm8x10_wcd_priv->micb_en_count = 0;
+
ret = wcd9xxx_mbhc_init(&msm8x10_wcd_priv->mbhc,
&msm8x10_wcd_priv->resmgr,
codec, msm8x10_wcd_enable_mbhc_micbias,
diff --git a/sound/soc/codecs/wcd9306.c b/sound/soc/codecs/wcd9306.c
index e3c9ad3..dd50020 100644
--- a/sound/soc/codecs/wcd9306.c
+++ b/sound/soc/codecs/wcd9306.c
@@ -5523,7 +5523,8 @@
mux_wait_us + WCD9XXX_USLEEP_RANGE_MARGIN_US);
break;
case PA_DISABLE:
- wcd9xxx_enable_static_pa(mbhc, false);
+ if (!mbhc->hph_pa_dac_state)
+ wcd9xxx_enable_static_pa(mbhc, false);
wcd9xxx_restore_registers(codec, &tapan->reg_save_restore);
break;
}
diff --git a/sound/soc/codecs/wcd9320.c b/sound/soc/codecs/wcd9320.c
index cf33a9d..5dedec8 100644
--- a/sound/soc/codecs/wcd9320.c
+++ b/sound/soc/codecs/wcd9320.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -5147,6 +5147,24 @@
return 0;
}
+static int taiko_codec_iir_mux_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ pr_debug("%s: event = %d\n", __func__, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ snd_soc_write(codec, w->reg, snd_soc_read(codec, w->reg));
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ snd_soc_write(codec, w->reg, snd_soc_read(codec, w->reg));
+ break;
+ }
+ return 0;
+}
+
static int taiko_codec_dsm_mux_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
@@ -5645,10 +5663,16 @@
SND_SOC_DAPM_POST_PMD),
/* Sidetone */
- SND_SOC_DAPM_MUX("IIR1 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp1_mux),
+ SND_SOC_DAPM_MUX_E("IIR1 INP1 MUX", TAIKO_A_CDC_IIR1_GAIN_B1_CTL, 0, 0,
+ &iir1_inp1_mux, taiko_codec_iir_mux_event,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
SND_SOC_DAPM_MIXER("IIR1", TAIKO_A_CDC_CLK_SD_CTL, 0, 0, NULL, 0),
- SND_SOC_DAPM_MUX("IIR2 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir2_inp1_mux),
+ SND_SOC_DAPM_MUX_E("IIR2 INP1 MUX", TAIKO_A_CDC_IIR2_GAIN_B1_CTL, 0, 0,
+ &iir2_inp1_mux, taiko_codec_iir_mux_event,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
SND_SOC_DAPM_MIXER("IIR2", TAIKO_A_CDC_CLK_SD_CTL, 1, 0, NULL, 0),
/* AUX PGA */
@@ -6513,7 +6537,8 @@
/* Clean up starts */
/* Turn off PA ramp generator */
snd_soc_write(codec, WCD9XXX_A_CDC_PA_RAMP_B1_CTL, 0x0);
- wcd9xxx_enable_static_pa(mbhc, false);
+ if (!mbhc->hph_pa_dac_state)
+ wcd9xxx_enable_static_pa(mbhc, false);
wcd9xxx_restore_registers(codec, &taiko->reg_save_restore);
break;
}
diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c
index 6f94d99..12348f8 100644
--- a/sound/soc/msm/msm-dai-fe.c
+++ b/sound/soc/msm/msm-dai-fe.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -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, 192000
+ 88200, 96000, 176400, 192000
};
static struct snd_pcm_hw_constraint_list constraints_sample_rates = {
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
index 32eaebf..08448fe 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -99,7 +99,7 @@
/* Conventional and unconventional sample rate supported */
static unsigned int supported_sample_rates[] = {
8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000,
- 96000, 192000
+ 88200, 96000, 176400, 192000
};
static uint32_t in_frame_info[CAPTURE_MAX_NUM_PERIODS][2];
diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c
index 3e30290..2a6ce43 100644
--- a/sound/soc/msm/qdsp6v2/q6adm.c
+++ b/sound/soc/msm/qdsp6v2/q6adm.c
@@ -479,6 +479,12 @@
{
uint32_t *payload;
int i, index;
+
+ if (data == NULL) {
+ pr_err("%s: data paramter is null\n", __func__);
+ return -EINVAL;
+ }
+
payload = data->payload;
if (data->opcode == RESET_EVENTS) {
diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c
index acb8e70..774a33c 100644
--- a/sound/soc/msm/qdsp6v2/q6afe.c
+++ b/sound/soc/msm/qdsp6v2/q6afe.c
@@ -436,8 +436,9 @@
}
index = q6audio_get_port_index(port_id);
- if (index < 0) {
- pr_debug("%s: AFE port index invalid!\n", __func__);
+ if (index < 0 || index > AFE_MAX_PORTS) {
+ pr_debug("%s: AFE port index[%d] invalid!\n",
+ __func__, index);
goto done;
}
@@ -652,8 +653,9 @@
goto fail_cmd;
}
index = q6audio_get_port_index(port_id);
- if (index < 0) {
- pr_debug("%s: AFE port index invalid!\n", __func__);
+ if (index < 0 || index > AFE_MAX_PORTS) {
+ pr_debug("%s: AFE port index[%d] invalid!\n",
+ __func__, index);
goto fail_cmd;
}
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index 3dac1f9..7e0d03e 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -133,6 +133,10 @@
static ssize_t audio_output_latency_dbgfs_read(struct file *file,
char __user *buf, size_t count, loff_t *ppos)
{
+ if (out_buffer == NULL) {
+ pr_err("%s: out_buffer is null\n", __func__);
+ return 0;
+ }
snprintf(out_buffer, OUT_BUFFER_SIZE, "%ld,%ld,%ld,%ld,%ld,%ld,",\
out_cold_tv.tv_sec, out_cold_tv.tv_usec, out_warm_tv.tv_sec,\
out_warm_tv.tv_usec, out_cont_tv.tv_sec, out_cont_tv.tv_usec);
@@ -178,6 +182,10 @@
static ssize_t audio_input_latency_dbgfs_read(struct file *file,
char __user *buf, size_t count, loff_t *ppos)
{
+ if (in_buffer == NULL) {
+ pr_err("%s: in_buffer is null\n", __func__);
+ return 0;
+ }
snprintf(in_buffer, IN_BUFFER_SIZE, "%ld,%ld,",\
in_cont_tv.tv_sec, in_cont_tv.tv_usec);
return simple_read_from_buffer(buf, IN_BUFFER_SIZE, ppos,
@@ -293,17 +301,30 @@
static void config_debug_fs_init(void)
{
out_buffer = kmalloc(OUT_BUFFER_SIZE, GFP_KERNEL);
+ if (out_buffer == NULL) {
+ pr_err("%s: kmalloc() for out_buffer failed\n", __func__);
+ goto fail_1;
+ }
+ in_buffer = kmalloc(IN_BUFFER_SIZE, GFP_KERNEL);
+ if (in_buffer == NULL) {
+ pr_err("%s: kmalloc() for in_buffer failed\n", __func__);
+ goto fail_2;
+ }
out_dentry = debugfs_create_file("audio_out_latency_measurement_node",\
S_IRUGO | S_IWUSR | S_IWGRP,\
NULL, NULL, &audio_output_latency_debug_fops);
if (IS_ERR(out_dentry))
- pr_err("debugfs_create_file failed\n");
- in_buffer = kmalloc(IN_BUFFER_SIZE, GFP_KERNEL);
+ pr_err("%s: debugfs_create_file failed\n", __func__);
in_dentry = debugfs_create_file("audio_in_latency_measurement_node",\
S_IRUGO | S_IWUSR | S_IWGRP,\
NULL, NULL, &audio_input_latency_debug_fops);
if (IS_ERR(in_dentry))
- pr_err("debugfs_create_file failed\n");
+ pr_err("%s: debugfs_create_file failed\n", __func__);
+ return;
+fail_2:
+ kfree(out_buffer);
+fail_1:
+ return;
}
#else
static void config_debug_fs_write(struct audio_buffer *ab)