Merge "msm: mdss: Fix assertive display HW range checks"
diff --git a/Documentation/devicetree/bindings/arm/msm/cpr-regulator.txt b/Documentation/devicetree/bindings/arm/msm/cpr-regulator.txt
index 40abc5f..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
@@ -140,7 +137,15 @@
1 => equal to PVS corner ceiling voltage
2 => equal to slow speed corner ceiling
3 => equal to qcom,vdd-mx-vmax
+ 4 => equal to VDD_APC corner mapped vdd-mx voltage
This is required when vdd-mx-supply is present.
+- qcom,vdd-mx-corner-map: Array of 3 elements which defines the mapping from VDD_APC
+ fuse voltage corners to vdd-mx-supply voltages.
+ The 3 elements with index[0..2] are:
+ [0] => voltage to set for vdd-mx when VDD_APC is running at SVS corner
+ [1] => voltage to set for vdd-mx when VDD_APC is running at NOM corner
+ [2] => voltage to set for vdd-mx when VDD_APC is running at TURBO corner
+ This is required when the qcom,vdd-mx-vmin-method property has a value of 4.
- qcom,cpr-fuse-redun-bp-cpr-disable: Redundant bit position of the bit to indicate if CPR should be disable
- qcom,cpr-fuse-redun-bp-scheme: Redundant bit position of the bit to indicate if it's a global/local scheme
This property is required if cpr-fuse-redun-bp-cpr-disable
@@ -235,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/arm/msm/lpm-levels.txt b/Documentation/devicetree/bindings/arm/msm/lpm-levels.txt
index 0696730..7f52be8 100644
--- a/Documentation/devicetree/bindings/arm/msm/lpm-levels.txt
+++ b/Documentation/devicetree/bindings/arm/msm/lpm-levels.txt
@@ -58,6 +58,9 @@
- qcom,min-cpu-mode: The min cpu sleep mode at which the given system level is
valid. All cpus should have entered this low power mode before
this system level can be chosen.
+- qcom,send-rpm-sleep-set: The system mode notifies RPM of Apps sleep and should
+ send the current sleep set votes and configure MPM before
+ entering this low power mode.
Example:
qcom,lpm-levels {
diff --git a/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt b/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt
index d689d70..ae6f8ef 100644
--- a/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt
+++ b/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt
@@ -159,15 +159,9 @@
1 = TE through TE gpio pin. (default)
- qcom,mdss-dsi-te-dcs-command: Inserts the dcs command.
1 = default value.
-- qcom,mdss-dsi-te-v-sync-rd-ptr-irq-line: Configures the scan line number that the dsi
- pixel transfer will start on. Rasing this number
- will result in delaying the start of the pixel
- transfer.
+- qcom,mdss-dsi-wr-mem-start: DCS command for write_memory_start.
0x2c = default value.
-- qcom,mdss-dsi-te-v-sync-continue-lines: Represents the difference in number of lines
- between estimated read pointer and write pointer
- to allow the updating of all the lines except
- the first line of the frame.
+- qcom,mdss-dsi-wr-mem-continue: DCS command for write_memory_continue.
0x3c = default value.
- qcom,mdss-dsi-h-sync-pulse: Specifies the pulse mode option for the panel.
0 = Don't send hsa/he following vs/ve packet(default)
@@ -310,8 +304,8 @@
qcom,mdss-dsi-te-check-enable;
qcom,mdss-dsi-te-using-te-pin;
qcom,mdss-dsi-te-dcs-command = <1>;
- qcom,mdss-dsi-te-v-sync-continue-lines = <0x3c>;
- qcom,mdss-dsi-te-v-sync-rd-ptr-irq-line = <0x2c>;
+ qcom,mdss-dsi-wr-mem-continue = <0x3c>;
+ qcom,mdss-dsi-wr-mem-start = <0x2c>;
qcom,mdss-dsi-te-pin-select = <1>;
qcom,mdss-dsi-h-sync-pulse = <1>;
qcom,mdss-dsi-hfp-power-mode;
diff --git a/Documentation/devicetree/bindings/hwmon/qpnp-adc-current.txt b/Documentation/devicetree/bindings/hwmon/qpnp-adc-current.txt
index 31bf540..d0cad52 100644
--- a/Documentation/devicetree/bindings/hwmon/qpnp-adc-current.txt
+++ b/Documentation/devicetree/bindings/hwmon/qpnp-adc-current.txt
@@ -9,7 +9,12 @@
Required properties:
- compatible : should be "qcom,qpnp-iadc" for Current ADC driver.
-- reg : offset and length of the PMIC Aribter register map.
+- reg : offset and length of the PMIC Arbiter register map.
+- reg-names : resource names used for the physical base address of the PMIC IADC
+ peripheral, the SMBB_BAT_IF_TRIM_CNST_RDS register.
+ Should be "iadc-base" for the PMIC IADC peripheral base register.
+ Should be "batt-id-trim-cnst-rds" for reading the
+ SMBB_BAT_IF_TRIM_CNST_RDS register.
- address-cells : Must be one.
- size-cells : Must be zero.
- interrupts : The USR bank peripheral IADC interrupt.
@@ -21,6 +26,13 @@
- qcom,rsense : Use this property when external rsense should be used
for current calculation and specify the units in nano-ohms.
- qcom,iadc-poll-eoc: Use polling instead of interrupts for End of Conversion completion.
+- qcom,use-default-rds-trim : Add this property to check if certain conditions are to be checked
+ reading the SMBB_BAT_IF_CNST_RDS, IADC_RDS trim register and
+ manufacturer type. Check the driver for conditions that each of the type.
+ 0 : Select this type to read the IADC and SMBB trim register and
+ apply the default RSENSE if conditions are met.
+ 1 : Select this type to read the IADC, SMBB trim register and
+ manufacturer type and apply the default RSENSE if conditions are met.
Channel node
NOTE: Atleast one Channel node is required.
diff --git a/Documentation/devicetree/bindings/input/touchscreen/gt9xx/gt9xx.txt b/Documentation/devicetree/bindings/input/touchscreen/gt9xx/gt9xx.txt
index d0c2b7d..ba61a2f 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/gt9xx/gt9xx.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/gt9xx/gt9xx.txt
@@ -52,6 +52,12 @@
- goodix,cfg-data5 : Touch screen controller config data group 5. Ask vendor
to provide that.
- goodix,fw-name : Touch screen controller firmware file name.
+ - goodix,slide-wakeup : To specify slide-wakeup property is enabled or not.
+ - goodix,dbl-clk-wakeup : To specify dbl-clk-wakeup property is enabled or not.
+ - goodix,change-x2y : To specify change-x2y property is enabled or not.
+ - goodix,driver-send-cfg : To specify driver-send-cfg property is enabled or not.
+ - goodix,have-touch-key : To specify have-touch-key property is enabled or not.
+ - goodix,with-pen : To specify with-pen property is enabled or not.
Example:
i2c@f9927000 {
goodix@5d {
@@ -87,5 +93,7 @@
FF FF FF FF FF FF FF 22 22 22
22 22 22 FF 07 01];
goodix,fw_name = "gtp_fw.bin";
+ goodix,have-touch-key;
+ goodix,driver-send-cfg;
};
};
diff --git a/Documentation/devicetree/bindings/media/video/msm-cci.txt b/Documentation/devicetree/bindings/media/video/msm-cci.txt
index 317c078..f256d78 100644
--- a/Documentation/devicetree/bindings/media/video/msm-cci.txt
+++ b/Documentation/devicetree/bindings/media/video/msm-cci.txt
@@ -48,6 +48,7 @@
Required properties:
- compatible : should be manufacturer name followed by sensor name
+ - "qcom,camera"
- "qcom,s5k3l1yx"
- "sne,imx134"
- "qcom,imx135"
@@ -153,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
@@ -208,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/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
index 6277054..e672a14 100644
--- a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
+++ b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
@@ -461,7 +461,11 @@
codec.
- qcom,mbhc-bias-internal: Flag to indicate if internal micbias should be used
for headset detection.
-
+- qcom,mbhc-audio-jack-type : String to indicate the jack type on the hardware.
+ Possible Values:
+ 4-pole-jack : Jack on the hardware is 4-pole.
+ 5-pole-jack : Jack on the hardware is 5-pole.
+ 6-pole-jack : Jack on the hardware is 6-pole.
* APQ8074 ASoC Machine driver
Required properties:
@@ -518,6 +522,7 @@
qcom,sec-auxpcm-gpio-sync = <&msmgpio 80 0>;
qcom,sec-auxpcm-gpio-din = <&msmgpio 81 0>;
qcom,sec-auxpcm-gpio-dout = <&msmgpio 82 0>;
+ qcom,mbhc-audio-jack-type = "4-pole-jack";
};
* msm-dai-mi2s
diff --git a/Documentation/devicetree/bindings/thermal/qpnp-adc-tm.txt b/Documentation/devicetree/bindings/thermal/qpnp-adc-tm.txt
index e4e05d1..415a3ef 100644
--- a/Documentation/devicetree/bindings/thermal/qpnp-adc-tm.txt
+++ b/Documentation/devicetree/bindings/thermal/qpnp-adc-tm.txt
@@ -26,6 +26,12 @@
to set temperature thresholds and receive notification when the temperature
crosses a set threshold, read temperature and enable/set trip types supported
by the thermal framework.
+- qcom,meas-interval-timer-idx: If present select from the following timer index to choose
+ a preset configurable measurement interval timer value. The driver defaults
+ to timer 1 with a measurement interval of 1 second if the property is not present.
+ 0 : Select Timer 1 for a measurement polling interval of 1 second.
+ 1 : Select Timer 2 for a measurement polling interval of 500ms.
+ 2 : Select Timer 3 for a measurement polling interval of 4 seconds.
Client required property:
- qcom,<consumer name>-adc_tm : The phandle to the corresponding adc_tm device.
diff --git a/Documentation/devicetree/bindings/usb/msm-hsusb.txt b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
index 623a23c..7d3d435 100644
--- a/Documentation/devicetree/bindings/usb/msm-hsusb.txt
+++ b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
@@ -93,6 +93,8 @@
enable this feature without proper bus voting.
-qcom,disable-retention-with-vdd-min: If present dont allow phy retention but allow
vdd min.
+- qcom,usbin-vadc: Corresponding vadc device's phandle to read usbin voltage using VADC.
+ This will be used to get value of usb power supply's VOLTAGE_NOW property.
Example HSUSB OTG controller device node :
usb@f9690000 {
@@ -120,6 +122,7 @@
qcom,disable-retention-with-vdd-min;
qcom,hsusb-otg-dpsehv-int = <49>;
qcom,hsusb-otg-dmsehv-int = <58>;
+ qcom,usbin-vadc = <&pm8226_vadc>;
qcom,msm_bus,name = "usb2";
qcom,msm_bus,num_cases = <2>;
qcom,msm_bus,active_only = <0>;
diff --git a/Documentation/devicetree/bindings/usb/msm-ssusb.txt b/Documentation/devicetree/bindings/usb/msm-ssusb.txt
index a7a646d..bfa9abe 100644
--- a/Documentation/devicetree/bindings/usb/msm-ssusb.txt
+++ b/Documentation/devicetree/bindings/usb/msm-ssusb.txt
@@ -58,6 +58,8 @@
for TX fifo allocation in QDSS composition
- qcom,dwc-ssphy-deemphasis-value: This property if present represents ss phy
deemphasis value to be used for overriding into SSPHY register.
+- qcom,usbin-vadc: Corresponding vadc device's phandle to read usbin voltage using VADC.
+ This will be used to get value of usb power supply's VOLTAGE_NOW property,
Sub nodes:
- Sub node for "DWC3- USB3 controller".
@@ -85,6 +87,7 @@
qcom,dwc-usb3-msm-tx-fifo-size = <29696>;
qcom,dwc-usb3-msm-qdss-tx-fifo-size = <16384>;
qcom,dwc-ssphy-deemphasis-value = <26>;
+ qcom,usbin-vadc = <&pm8941_vadc>;
qcom,msm_bus,name = "usb3";
qcom,msm_bus,num_cases = <2>;
diff --git a/arch/arm/boot/dts/apq8084-camera-sensor-cdp.dtsi b/arch/arm/boot/dts/apq8084-camera-sensor-cdp.dtsi
new file mode 100644
index 0000000..5577d16
--- /dev/null
+++ b/arch/arm/boot/dts/apq8084-camera-sensor-cdp.dtsi
@@ -0,0 +1,159 @@
+/*
+ * 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+&cci {
+
+ actuator0: qcom,actuator@36 {
+ cell-index = <1>;
+ reg = <0x36>;
+ compatible = "qcom,actuator";
+ qcom,cci-master = <0>;
+ };
+
+ qcom,camera@20 {
+ compatible = "qcom,imx135";
+ reg = <0x20>;
+ qcom,slave-id = <0x20 0x0016 0x0135>;
+ qcom,csiphy-sd-index = <0>;
+ qcom,csid-sd-index = <0>;
+ qcom,mount-angle = <90>;
+ qcom,sensor-name = "imx135";
+ qcom,actuator-src = <&actuator0>;
+ cam_vdig-supply = <&pma8084_l27>;
+ cam_vio-supply = <&pma8084_lvs4>;
+ cam_vana-supply = <&pma8084_l17>;
+ cam_vaf-supply = <&pma8084_l23>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-type = <0 1 0 0>;
+ qcom,cam-vreg-min-voltage = <1050000 0 2800000 2700000>;
+ qcom,cam-vreg-max-voltage = <1050000 0 2800000 2700000>;
+ qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+ qcom,gpio-no-mux = <0>;
+ gpios = <&msmgpio 15 0>,
+ <&msmgpio 36 0>,
+ <&msmgpio 35 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET1",
+ "CAM_STANDBY";
+ qcom,gpio-set-tbl-num = <1 1>;
+ qcom,gpio-set-tbl-flags = <0 2>;
+ qcom,gpio-set-tbl-delay = <1000 30000>;
+ qcom,csi-lane-assign = <0x4320>;
+ qcom,csi-lane-mask = <0x1F>;
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
+ qcom,sensor-type = <0>;
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
+
+ qcom,camera@6d {
+ compatible = "qcom,imx132";
+ reg = <0x6d>;
+ qcom,slave-id = <0x6c 0x0 0x0132>;
+ qcom,csiphy-sd-index = <2>;
+ qcom,csid-sd-index = <2>;
+ qcom,mount-angle = <270>;
+ qcom,sensor-name = "imx132";
+ cam_vana-supply = <&pma8084_l17>;
+ cam_vdig-supply = <&pma8084_l15>;
+ cam_vio-supply = <&pma8084_lvs4>;
+ qcom,cam-vreg-name = "cam_vana", "cam_vdig", "cam_vio";
+ qcom,cam-vreg-type = <0 0 1>;
+ qcom,cam-vreg-min-voltage = <2800000 1200000 0>;
+ qcom,cam-vreg-max-voltage = <2800000 1200000 0>;
+ qcom,cam-vreg-op-mode = <80000 105000 0>;
+ qcom,gpio-no-mux = <0>;
+ gpios = <&msmgpio 17 0>,
+ <&msmgpio 25 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-req-tbl-num = <0 1>;
+ qcom,gpio-req-tbl-flags = <1 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
+ "CAM_XSHUTDOWN";
+ qcom,gpio-set-tbl-num = <1 1>;
+ qcom,gpio-set-tbl-flags = <0 2>;
+ qcom,gpio-set-tbl-delay = <1000 4000>;
+ qcom,csi-lane-assign = <0x4320>;
+ qcom,csi-lane-mask = <0x7>;
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <1>;
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
+
+ qcom,camera@0 {
+ cell-index = <0>;
+ compatible = "qcom,camera";
+ reg = <0x00>;
+ qcom,csiphy-sd-index = <0>;
+ qcom,csid-sd-index = <0>;
+ qcom,actuator-src = <&actuator0>;
+ cam_vdig-supply = <&pma8084_l27>;
+ cam_vio-supply = <&pma8084_lvs4>;
+ cam_vana-supply = <&pma8084_l17>;
+ cam_vaf-supply = <&pma8084_l23>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-type = <0 1 0 0>;
+ qcom,cam-vreg-min-voltage = <1050000 0 2800000 2700000>;
+ qcom,cam-vreg-max-voltage = <1050000 0 2800000 2700000>;
+ qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+ qcom,gpio-no-mux = <0>;
+ gpios = <&msmgpio 15 0>,
+ <&msmgpio 36 0>,
+ <&msmgpio 35 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET1",
+ "CAM_STANDBY";
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
+
+ qcom,camera@1 {
+ cell-index = <1>;
+ compatible = "qcom,camera";
+ reg = <0x01>;
+ qcom,slave-id = <0x6c 0x0 0x0132>;
+ qcom,csiphy-sd-index = <2>;
+ qcom,csid-sd-index = <2>;
+ qcom,mount-angle = <270>;
+ cam_vana-supply = <&pma8084_l17>;
+ cam_vdig-supply = <&pma8084_l15>;
+ cam_vio-supply = <&pma8084_lvs4>;
+ qcom,cam-vreg-name = "cam_vana", "cam_vdig", "cam_vio";
+ qcom,cam-vreg-type = <0 0 1>;
+ qcom,cam-vreg-min-voltage = <2850000 1225000 0>;
+ qcom,cam-vreg-max-voltage = <2850000 1225000 0>;
+ qcom,cam-vreg-op-mode = <80000 105000 0>;
+ qcom,gpio-no-mux = <0>;
+ gpios = <&msmgpio 17 0>,
+ <&msmgpio 25 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-req-tbl-num = <0 1>;
+ qcom,gpio-req-tbl-flags = <1 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
+ "CAM_XSHUTDOWN";
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
+};
diff --git a/arch/arm/boot/dts/apq8084-camera-sensor-mtp.dtsi b/arch/arm/boot/dts/apq8084-camera-sensor-mtp.dtsi
new file mode 100644
index 0000000..02d8b59
--- /dev/null
+++ b/arch/arm/boot/dts/apq8084-camera-sensor-mtp.dtsi
@@ -0,0 +1,159 @@
+/*
+ * 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+&cci {
+
+ actuator0: qcom,actuator@36 {
+ cell-index = <1>;
+ reg = <0x36>;
+ compatible = "qcom,actuator";
+ qcom,cci-master = <0>;
+ };
+
+ qcom,camera@20 {
+ compatible = "qcom,imx135";
+ reg = <0x20>;
+ qcom,slave-id = <0x20 0x0016 0x0135>;
+ qcom,csiphy-sd-index = <0>;
+ qcom,csid-sd-index = <0>;
+ qcom,mount-angle = <90>;
+ qcom,sensor-name = "imx135";
+ qcom,actuator-src = <&actuator0>;
+ cam_vdig-supply = <&pma8084_l27>;
+ cam_vio-supply = <&pma8084_lvs4>;
+ cam_vana-supply = <&pma8084_l17>;
+ cam_vaf-supply = <&pma8084_l23>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-type = <0 1 0 0>;
+ qcom,cam-vreg-min-voltage = <1050000 0 2800000 2700000>;
+ qcom,cam-vreg-max-voltage = <1050000 0 2800000 2700000>;
+ qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+ qcom,gpio-no-mux = <0>;
+ gpios = <&msmgpio 15 0>,
+ <&msmgpio 36 0>,
+ <&msmgpio 35 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET1",
+ "CAM_STANDBY";
+ qcom,gpio-set-tbl-num = <1 1>;
+ qcom,gpio-set-tbl-flags = <0 2>;
+ qcom,gpio-set-tbl-delay = <1000 30000>;
+ qcom,csi-lane-assign = <0x4320>;
+ qcom,csi-lane-mask = <0x1F>;
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
+ qcom,sensor-type = <0>;
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
+
+ qcom,camera@6d {
+ compatible = "qcom,imx132";
+ reg = <0x6d>;
+ qcom,slave-id = <0x6c 0x0 0x0132>;
+ qcom,csiphy-sd-index = <2>;
+ qcom,csid-sd-index = <2>;
+ qcom,mount-angle = <90>;
+ qcom,sensor-name = "imx132";
+ cam_vana-supply = <&pma8084_l17>;
+ cam_vdig-supply = <&pma8084_l15>;
+ cam_vio-supply = <&pma8084_lvs4>;
+ qcom,cam-vreg-name = "cam_vana", "cam_vdig", "cam_vio";
+ qcom,cam-vreg-type = <0 0 1>;
+ qcom,cam-vreg-min-voltage = <2800000 1200000 0>;
+ qcom,cam-vreg-max-voltage = <2800000 1200000 0>;
+ qcom,cam-vreg-op-mode = <80000 105000 0>;
+ qcom,gpio-no-mux = <0>;
+ gpios = <&msmgpio 17 0>,
+ <&msmgpio 25 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-req-tbl-num = <0 1>;
+ qcom,gpio-req-tbl-flags = <1 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
+ "CAM_XSHUTDOWN";
+ qcom,gpio-set-tbl-num = <1 1>;
+ qcom,gpio-set-tbl-flags = <0 2>;
+ qcom,gpio-set-tbl-delay = <1000 4000>;
+ qcom,csi-lane-assign = <0x4320>;
+ qcom,csi-lane-mask = <0x7>;
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <1>;
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
+
+ qcom,camera@0 {
+ cell-index = <0>;
+ compatible = "qcom,camera";
+ reg = <0x00>;
+ qcom,csiphy-sd-index = <0>;
+ qcom,csid-sd-index = <0>;
+ qcom,mount-angle = <90>;
+ qcom,actuator-src = <&actuator0>;
+ cam_vdig-supply = <&pma8084_l27>;
+ cam_vio-supply = <&pma8084_lvs4>;
+ cam_vana-supply = <&pma8084_l17>;
+ cam_vaf-supply = <&pma8084_l23>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-type = <0 1 0 0>;
+ qcom,cam-vreg-min-voltage = <1050000 0 2800000 2700000>;
+ qcom,cam-vreg-max-voltage = <1050000 0 2800000 2700000>;
+ qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+ qcom,gpio-no-mux = <0>;
+ gpios = <&msmgpio 15 0>,
+ <&msmgpio 36 0>,
+ <&msmgpio 35 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET1",
+ "CAM_STANDBY";
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
+
+ qcom,camera@1 {
+ cell-index = <1>;
+ compatible = "qcom,camera";
+ reg = <0x01>;
+ qcom,csiphy-sd-index = <2>;
+ qcom,csid-sd-index = <2>;
+ qcom,mount-angle = <270>;
+ cam_vana-supply = <&pma8084_l17>;
+ cam_vdig-supply = <&pma8084_l15>;
+ cam_vio-supply = <&pma8084_lvs4>;
+ qcom,cam-vreg-name = "cam_vana", "cam_vdig", "cam_vio";
+ qcom,cam-vreg-type = <0 0 1>;
+ qcom,cam-vreg-min-voltage = <2850000 1225000 0>;
+ qcom,cam-vreg-max-voltage = <2850000 1225000 0>;
+ qcom,cam-vreg-op-mode = <80000 105000 0>;
+ qcom,gpio-no-mux = <0>;
+ gpios = <&msmgpio 17 0>,
+ <&msmgpio 25 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-req-tbl-num = <0 1>;
+ qcom,gpio-req-tbl-flags = <1 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
+ "CAM_XSHUTDOWN";
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
+};
diff --git a/arch/arm/boot/dts/dsi-panel-generic-720p-cmd.dtsi b/arch/arm/boot/dts/dsi-panel-generic-720p-cmd.dtsi
index 17e6e94..14d4c35 100644
--- a/arch/arm/boot/dts/dsi-panel-generic-720p-cmd.dtsi
+++ b/arch/arm/boot/dts/dsi-panel-generic-720p-cmd.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
@@ -59,8 +59,8 @@
qcom,mdss-dsi-lane-2-state;
qcom,mdss-dsi-lane-3-state;
qcom,mdss-dsi-te-pin-select = <1>;
- qcom,mdss-dsi-te-v-sync-rd-ptr-irq-line = <0x2c>;
- qcom,mdss-dsi-te-v-sync-continues-lines = <0x3c>;
+ qcom,mdss-dsi-wr-mem-start = <0x2c>;
+ qcom,mdss-dsi-wr-mem-continue = <0x3c>;
qcom,mdss-dsi-te-dcs-command = <1>;
qcom,mdss-dsi-te-check-enable;
qcom,mdss-dsi-te-using-te-pin;
diff --git a/arch/arm/boot/dts/dsi-panel-jdi-dualmipi0-cmd.dtsi b/arch/arm/boot/dts/dsi-panel-jdi-dualmipi0-cmd.dtsi
new file mode 100644
index 0000000..d8bf36f
--- /dev/null
+++ b/arch/arm/boot/dts/dsi-panel-jdi-dualmipi0-cmd.dtsi
@@ -0,0 +1,91 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+&mdss_mdp {
+ dsi_dual_jdi_cmd_0: qcom,mdss_dsi_jdi_qhd_dualmipi0_cmd{
+ qcom,mdss-dsi-panel-name = "Dual 0 cmd mode dsi panel";
+ qcom,mdss-dsi-panel-controller = <&mdss_dsi0>;
+ qcom,mdss-dsi-panel-type = "dsi_cmd_mode";
+ qcom,mdss-dsi-panel-destination = "display_1";
+ qcom,mdss-dsi-panel-framerate = <60>;
+ qcom,mdss-dsi-virtual-channel-id = <0>;
+ qcom,mdss-dsi-stream = <0>;
+ qcom,mdss-dsi-panel-width = <1280>;
+ qcom,mdss-dsi-panel-height = <1440>;
+ qcom,mdss-dsi-h-front-porch = <120>;
+ qcom,mdss-dsi-h-back-porch = <44>;
+ qcom,mdss-dsi-h-pulse-width = <16>;
+ qcom,mdss-dsi-h-sync-skew = <0>;
+ qcom,mdss-dsi-v-back-porch = <4>;
+ qcom,mdss-dsi-v-front-porch = <8>;
+ qcom,mdss-dsi-v-pulse-width = <4>;
+ qcom,mdss-dsi-h-left-border = <0>;
+ qcom,mdss-dsi-h-right-border = <0>;
+ qcom,mdss-dsi-v-top-border = <0>;
+ qcom,mdss-dsi-v-bottom-border = <0>;
+ qcom,mdss-dsi-bpp = <24>;
+ qcom,mdss-dsi-color-order = "rgb_swap_rgb";
+ qcom,mdss-dsi-underflow-color = <0xff>;
+ qcom,mdss-dsi-border-color = <0>;
+ qcom,mdss-dsi-h-sync-pulse = <0>;
+ qcom,mdss-dsi-traffic-mode = "non_burst_sync_event";
+ qcom,mdss-dsi-lane-map = "lane_map_0123";
+ qcom,mdss-dsi-bllp-eof-power-mode;
+ qcom,mdss-dsi-bllp-power-mode;
+ qcom,mdss-dsi-panel-broadcast-mode;
+ qcom,mdss-dsi-lane-0-state;
+ qcom,mdss-dsi-lane-1-state;
+ qcom,mdss-dsi-lane-2-state;
+ qcom,mdss-dsi-lane-3-state;
+ qcom,mdss-dsi-panel-timings = [cd 32 22 00 60 64 26 34 29 03
+ 04 00];
+ qcom,mdss-dsi-reset-sequence = <1 200>, <0 200>, <1 20>;
+ qcom,mdss-dsi-t-clk-post = <0x03>;
+ qcom,mdss-dsi-t-clk-pre = <0x27>;
+ qcom,mdss-dsi-bl-max-level = <4095>;
+ qcom,mdss-dsi-dma-trigger = "trigger_sw";
+ qcom,mdss-dsi-mdp-trigger = "none";
+ qcom,mdss-dsi-te-pin-select = <1>;
+ qcom,mdss-dsi-te-v-sync-rd-ptr-irq-line = <0x2c>;
+ qcom,mdss-dsi-te-v-sync-continues-lines = <0x3c>;
+ qcom,mdss-dsi-te-dcs-command = <1>;
+ qcom,mdss-dsi-te-check-enable;
+ qcom,mdss-dsi-te-using-te-pin;
+ qcom,mdss-dsi-on-command = [29 01 00 00 00 00 02 b0 03
+ 05 01 00 00 0a 00 01 00
+ /* Soft reset, wait 10ms */
+ 15 01 00 00 0a 00 02 3a 77
+ /* Set Pixel format (24 bpp) */
+ 39 01 00 00 0a 00 05 2a 00 00 04 ff
+ /* Set Column address */
+ 39 01 00 00 0a 00 05 2b 00 00 05 9f
+ /* Set page address */
+ 15 01 00 00 0a 00 02 35 00
+ /* Set tear on */
+ 39 01 00 00 0a 00 03 44 00 00
+ /* Set tear scan line */
+ 15 01 00 00 0a 00 02 51 ff
+ /* write display brightness */
+ 15 01 00 00 0a 00 02 53 24
+ /* write control brightness */
+ 15 01 00 00 0a 00 02 55 00
+ /* CABC brightness */
+ 05 01 00 00 78 00 01 11
+ /* exit sleep mode, wait 120ms */
+ 05 01 00 00 10 00 01 29];
+ /* Set display on, wait 16ms */
+ qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
+ qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00
+ 05 01 00 00 78 00 02 10 00];
+ qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
+ };
+};
diff --git a/arch/arm/boot/dts/dsi-panel-jdi-dualmipi0-video.dtsi b/arch/arm/boot/dts/dsi-panel-jdi-dualmipi0-video.dtsi
new file mode 100644
index 0000000..5cf88f9
--- /dev/null
+++ b/arch/arm/boot/dts/dsi-panel-jdi-dualmipi0-video.dtsi
@@ -0,0 +1,92 @@
+/* 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+&mdss_mdp {
+ dsi_dual_jdi_video_0: qcom,dsi_jdi_qhd_video_0 {
+ qcom,mdss-dsi-panel-name = "Dual 0 video mode dsi panel";
+ qcom,mdss-dsi-panel-controller = <&mdss_dsi0>;
+ qcom,mdss-dsi-panel-type = "dsi_video_mode";
+ qcom,mdss-dsi-panel-destination = "display_1";
+ qcom,mdss-dsi-panel-framerate = <60>;
+ qcom,mdss-dsi-virtual-channel-id = <0>;
+ qcom,mdss-dsi-stream = <0>;
+ qcom,mdss-dsi-panel-width = <1280>;
+ qcom,mdss-dsi-panel-height = <1440>;
+ qcom,mdss-dsi-h-front-porch = <120>;
+ qcom,mdss-dsi-h-back-porch = <44>;
+ qcom,mdss-dsi-h-pulse-width = <16>;
+ qcom,mdss-dsi-h-sync-skew = <0>;
+ qcom,mdss-dsi-v-back-porch = <4>;
+ qcom,mdss-dsi-v-front-porch = <8>;
+ qcom,mdss-dsi-v-pulse-width = <4>;
+ qcom,mdss-dsi-h-left-border = <0>;
+ qcom,mdss-dsi-h-right-border = <0>;
+ qcom,mdss-dsi-v-top-border = <0>;
+ qcom,mdss-dsi-v-bottom-border = <0>;
+ qcom,mdss-dsi-bpp = <24>;
+ qcom,mdss-dsi-underflow-color = <0xff>;
+ qcom,mdss-dsi-border-color = <0>;
+ qcom,mdss-dsi-h-sync-pulse = <0>;
+ qcom,mdss-dsi-traffic-mode = "non_burst_sync_event";
+ qcom,mdss-dsi-bllp-eof-power-mode;
+ qcom,mdss-dsi-bllp-power-mode;
+ qcom,mdss-dsi-panel-broadcast-mode;
+ qcom,mdss-dsi-lane-0-state;
+ qcom,mdss-dsi-lane-1-state;
+ qcom,mdss-dsi-lane-2-state;
+ qcom,mdss-dsi-lane-3-state;
+ qcom,mdss-dsi-panel-timings = [cd 32 22 00 60 64 26 34 29 03
+ 04 00];
+ qcom,mdss-dsi-t-clk-post = <0x03>;
+ qcom,mdss-dsi-t-clk-pre = <0x27>;
+ qcom,mdss-dsi-bl-max-level = <4095>;
+ qcom,mdss-dsi-dma-trigger = "trigger_sw";
+ qcom,mdss-dsi-mdp-trigger = "none";
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_pwm";
+ qcom,mdss-dsi-on-command = [05 01 00 00 0a 00 01 00
+ /* Soft reset, wait 10ms */
+ 15 01 00 00 0a 00 02 3a 77
+ /* Set Pixel format (24 bpp) */
+ 39 01 00 00 0a 00 05 2a 00 00 04 ff
+ /* Set Column address */
+ 39 01 00 00 0a 00 05 2b 00 00 05 9f
+ /* Set page address */
+ 15 01 00 00 0a 00 02 35 00
+ /* Set tear on */
+ 39 01 00 00 0a 00 03 44 00 00
+ /* Set tear scan line */
+ 15 01 00 00 0a 00 02 51 ff
+ /* write display brightness */
+ 15 01 00 00 0a 00 02 53 24
+ /* write control brightness */
+ 15 01 00 00 0a 00 02 55 00
+ /* CABC brightness */
+ 05 01 00 00 78 00 01 11
+ /* exit sleep mode, wait 120ms */
+ 23 01 00 00 0a 00 02 b0 00
+ /* MCAP */
+ 29 01 00 00 0a 00 02 b3 14
+ /* Interface setting */
+ 29 01 00 00 0a 00 14 ce 7d 40 48 56 67
+ 78 88 98 a7 b5 c3 d1 de e9 f2 fa ff 04
+ 00 /* Backlight control 4 */
+ 23 01 00 00 0a 00 02 b0 03
+ /* MCAP */
+ 05 01 00 00 10 00 01 29];
+ /* Set display on, wait 16ms */
+ qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
+ qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00
+ 05 01 00 00 78 00 02 10 00];
+ qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
+ qcom,mdss-dsi-reset-sequence = <1 20>, <0 200>, <1 20>;
+ };
+};
diff --git a/arch/arm/boot/dts/dsi-panel-jdi-dualmipi1-cmd.dtsi b/arch/arm/boot/dts/dsi-panel-jdi-dualmipi1-cmd.dtsi
new file mode 100644
index 0000000..e1473ca
--- /dev/null
+++ b/arch/arm/boot/dts/dsi-panel-jdi-dualmipi1-cmd.dtsi
@@ -0,0 +1,91 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+&mdss_mdp {
+ dsi_dual_jdi_cmd_1: qcom,mdss_dsi_jdi_qhd_dualmipi1_cmd{
+ qcom,mdss-dsi-panel-name = "Dual 1 cmd mode dsi panel";
+ qcom,mdss-dsi-panel-controller = <&mdss_dsi1>;
+ qcom,mdss-dsi-panel-type = "dsi_cmd_mode";
+ qcom,mdss-dsi-panel-destination = "display_2";
+ qcom,mdss-dsi-panel-framerate = <60>;
+ qcom,mdss-dsi-virtual-channel-id = <0>;
+ qcom,mdss-dsi-stream = <0>;
+ qcom,mdss-dsi-panel-width = <1280>;
+ qcom,mdss-dsi-panel-height = <1440>;
+ qcom,mdss-dsi-h-front-porch = <120>;
+ qcom,mdss-dsi-h-back-porch = <44>;
+ qcom,mdss-dsi-h-pulse-width = <16>;
+ qcom,mdss-dsi-h-sync-skew = <0>;
+ qcom,mdss-dsi-v-back-porch = <4>;
+ qcom,mdss-dsi-v-front-porch = <8>;
+ qcom,mdss-dsi-v-pulse-width = <4>;
+ qcom,mdss-dsi-h-left-border = <0>;
+ qcom,mdss-dsi-h-right-border = <0>;
+ qcom,mdss-dsi-v-top-border = <0>;
+ qcom,mdss-dsi-v-bottom-border = <0>;
+ qcom,mdss-dsi-bpp = <24>;
+ qcom,mdss-dsi-color-order = "rgb_swap_rgb";
+ qcom,mdss-dsi-underflow-color = <0xff>;
+ qcom,mdss-dsi-border-color = <0>;
+ qcom,mdss-dsi-h-sync-pulse = <0>;
+ qcom,mdss-dsi-traffic-mode = "non_burst_sync_event";
+ qcom,mdss-dsi-lane-map = "lane_map_0123";
+ qcom,mdss-dsi-bllp-eof-power-mode;
+ qcom,mdss-dsi-bllp-power-mode;
+ qcom,mdss-dsi-panel-broadcast-mode;
+ qcom,mdss-dsi-lane-0-state;
+ qcom,mdss-dsi-lane-1-state;
+ qcom,mdss-dsi-lane-2-state;
+ qcom,mdss-dsi-lane-3-state;
+ qcom,mdss-dsi-panel-timings = [cd 32 22 00 60 64 26 34 29 03
+ 04 00];
+ qcom,mdss-dsi-reset-sequence = <1 200>, <0 200>, <1 20>;
+ qcom,mdss-dsi-t-clk-post = <0x03>;
+ qcom,mdss-dsi-t-clk-pre = <0x27>;
+ qcom,mdss-dsi-bl-max-level = <4095>;
+ qcom,mdss-dsi-dma-trigger = "trigger_sw";
+ qcom,mdss-dsi-mdp-trigger = "none";
+ qcom,mdss-dsi-te-pin-select = <1>;
+ qcom,mdss-dsi-te-v-sync-rd-ptr-irq-line = <0x2c>;
+ qcom,mdss-dsi-te-v-sync-continues-lines = <0x3c>;
+ qcom,mdss-dsi-te-dcs-command = <1>;
+ qcom,mdss-dsi-te-check-enable;
+ qcom,mdss-dsi-te-using-te-pin;
+ qcom,mdss-dsi-on-command = [29 01 00 00 00 00 02 b0 03
+ 05 01 00 00 0a 00 01 00
+ /* Soft reset, wait 10ms */
+ 15 01 00 00 0a 00 02 3a 77
+ /* Set Pixel format (24 bpp) */
+ 39 01 00 00 0a 00 05 2a 00 00 04 ff
+ /* Set Column address */
+ 39 01 00 00 0a 00 05 2b 00 00 05 9f
+ /* Set page address */
+ 15 01 00 00 0a 00 02 35 00
+ /* Set tear on */
+ 39 01 00 00 0a 00 03 44 00 00
+ /* Set tear scan line */
+ 15 01 00 00 0a 00 02 51 ff
+ /* write display brightness */
+ 15 01 00 00 0a 00 02 53 24
+ /* write control brightness */
+ 15 01 00 00 0a 00 02 55 00
+ /* CABC brightness */
+ 05 01 00 00 78 00 01 11
+ /* exit sleep mode, wait 120ms */
+ 05 01 00 00 10 00 01 29];
+ /* Set display on, wait 16ms */
+ qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
+ qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00
+ 05 01 00 00 78 00 02 10 00];
+ qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
+ };
+};
diff --git a/arch/arm/boot/dts/dsi-panel-jdi-dualmipi1-video.dtsi b/arch/arm/boot/dts/dsi-panel-jdi-dualmipi1-video.dtsi
new file mode 100644
index 0000000..a405bff
--- /dev/null
+++ b/arch/arm/boot/dts/dsi-panel-jdi-dualmipi1-video.dtsi
@@ -0,0 +1,92 @@
+/* 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+&mdss_mdp {
+ dsi_dual_jdi_video_1: qcom,dsi_jdi_qhd_video_1 {
+ qcom,mdss-dsi-panel-name = "Dual 1 video mode dsi panel";
+ qcom,mdss-dsi-panel-controller = <&mdss_dsi1>;
+ qcom,mdss-dsi-panel-type = "dsi_video_mode";
+ qcom,mdss-dsi-panel-destination = "display_2";
+ qcom,mdss-dsi-panel-framerate = <60>;
+ qcom,mdss-dsi-virtual-channel-id = <0>;
+ qcom,mdss-dsi-stream = <0>;
+ qcom,mdss-dsi-panel-width = <1280>;
+ qcom,mdss-dsi-panel-height = <1440>;
+ qcom,mdss-dsi-h-front-porch = <120>;
+ qcom,mdss-dsi-h-back-porch = <44>;
+ qcom,mdss-dsi-h-pulse-width = <16>;
+ qcom,mdss-dsi-h-sync-skew = <0>;
+ qcom,mdss-dsi-v-back-porch = <4>;
+ qcom,mdss-dsi-v-front-porch = <8>;
+ qcom,mdss-dsi-v-pulse-width = <4>;
+ qcom,mdss-dsi-h-left-border = <0>;
+ qcom,mdss-dsi-h-right-border = <0>;
+ qcom,mdss-dsi-v-top-border = <0>;
+ qcom,mdss-dsi-v-bottom-border = <0>;
+ qcom,mdss-dsi-bpp = <24>;
+ qcom,mdss-dsi-underflow-color = <0xff>;
+ qcom,mdss-dsi-border-color = <0>;
+ qcom,mdss-dsi-h-sync-pulse = <0>;
+ qcom,mdss-dsi-traffic-mode = "non_burst_sync_event";
+ qcom,mdss-dsi-bllp-eof-power-mode;
+ qcom,mdss-dsi-bllp-power-mode;
+ qcom,mdss-dsi-lane-0-state;
+ qcom,mdss-dsi-lane-1-state;
+ qcom,mdss-dsi-lane-2-state;
+ qcom,mdss-dsi-lane-3-state;
+ qcom,mdss-dsi-panel-broadcast-mode;
+ qcom,mdss-dsi-panel-timings = [cd 32 22 00 60 64 26 34 29 03
+ 04 00];
+ qcom,mdss-dsi-t-clk-post = <0x03>;
+ qcom,mdss-dsi-t-clk-pre = <0x27>;
+ qcom,mdss-dsi-bl-min-level = <1>;
+ qcom,mdss-dsi-bl-max-level = <4095>;
+ qcom,mdss-dsi-dma-trigger = "trigger_sw";
+ qcom,mdss-dsi-mdp-trigger = "none";
+ qcom,mdss-dsi-on-command = [05 01 00 00 0a 00 01 00
+ /* Soft reset, wait 10ms */
+ 15 01 00 00 0a 00 02 3a 77
+ /* Set Pixel format (24 bpp) */
+ 39 01 00 00 0a 00 05 2a 00 00 04 ff
+ /* Set Column address */
+ 39 01 00 00 0a 00 05 2b 00 00 05 9f
+ /* Set page address */
+ 15 01 00 00 0a 00 02 35 00
+ /* Set tear on */
+ 39 01 00 00 0a 00 03 44 00 00
+ /* Set tear scan line */
+ 15 01 00 00 0a 00 02 51 ff
+ /* write display brightness */
+ 15 01 00 00 0a 00 02 53 24
+ /* write control brightness */
+ 15 01 00 00 0a 00 02 55 00
+ /* CABC brightness */
+ 05 01 00 00 78 00 01 11
+ /* exit sleep mode, wait 120ms */
+ 23 01 00 00 0a 00 02 b0 00
+ /* MCAP */
+ 29 01 00 00 0a 00 02 b3 14
+ /* Interface setting */
+ 29 01 00 00 0a 00 14 ce 7d 40 48 56 67
+ 78 88 98 a7 b5 c3 d1 de e9 f2 fa ff 04
+ 00 /* Backlight control 4 */
+ 23 01 00 00 0a 00 02 b0 03
+ /* MCAP */
+ 05 01 00 00 10 00 01 29];
+ /* Set display on, wait 16ms */
+ qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
+ qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00
+ 05 01 00 00 78 00 02 10 00];
+ qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
+ qcom,mdss-dsi-reset-sequence = <1 20>, <0 200>, <1 20>;
+ };
+};
diff --git a/arch/arm/boot/dts/dsi-panel-nt35590-720p-cmd.dtsi b/arch/arm/boot/dts/dsi-panel-nt35590-720p-cmd.dtsi
index d3547d8..cbc38f2 100644
--- a/arch/arm/boot/dts/dsi-panel-nt35590-720p-cmd.dtsi
+++ b/arch/arm/boot/dts/dsi-panel-nt35590-720p-cmd.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
@@ -517,7 +517,7 @@
qcom,mdss-dsi-lane-2-state;
qcom,mdss-dsi-lane-3-state;
qcom,mdss-dsi-te-pin-select = <1>;
- qcom,mdss-dsi-te-v-sync-rd-ptr-irq-line = <0x2c>;
+ qcom,mdss-dsi-wr-mem-start = <0x2c>;
qcom,mdss-dsi-te-dcs-command = <1>;
qcom,mdss-dsi-te-check-enable;
qcom,mdss-dsi-te-using-te-pin;
diff --git a/arch/arm/boot/dts/dsi-panel-truly-wvga-cmd.dtsi b/arch/arm/boot/dts/dsi-panel-truly-wvga-cmd.dtsi
index 4cd1563..3106cd4 100644
--- a/arch/arm/boot/dts/dsi-panel-truly-wvga-cmd.dtsi
+++ b/arch/arm/boot/dts/dsi-panel-truly-wvga-cmd.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
@@ -151,8 +151,8 @@
qcom,mdss-dsi-lane-0-state;
qcom,mdss-dsi-lane-1-state;
qcom,mdss-dsi-te-pin-select = <1>;
- qcom,mdss-dsi-te-v-sync-rd-ptr-irq-line = <0x2c>;
- qcom,mdss-dsi-te-v-sync-continues-lines = <0x3c>;
+ qcom,mdss-dsi-wr-mem-start = <0x2c>;
+ qcom,mdss-dsi-wr-mem-continue = <0x3c>;
qcom,mdss-dsi-te-dcs-command = <1>;
qcom,mdss-dsi-te-check-enable;
qcom,mdss-dsi-te-using-te-pin;
diff --git a/arch/arm/boot/dts/msm-pm8110.dtsi b/arch/arm/boot/dts/msm-pm8110.dtsi
index 20e8a96..9adbf81 100644
--- a/arch/arm/boot/dts/msm-pm8110.dtsi
+++ b/arch/arm/boot/dts/msm-pm8110.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
@@ -256,7 +256,9 @@
pm8110_iadc: iadc@3600 {
compatible = "qcom,qpnp-iadc";
- reg = <0x3600 0x100>;
+ reg = <0x3600 0x100>,
+ <0x12f1 0x1>;
+ reg-names = "iadc-base", "batt-id-trim-cnst-rds";
#address-cells = <1>;
#size-cells = <0>;
interrupts = <0x0 0x36 0x0>;
@@ -265,6 +267,7 @@
qcom,adc-vdd-reference = <1800>;
qcom,iadc-vadc = <&pm8110_vadc>;
qcom,iadc-poll-eoc;
+ qcom,use-default-rds-trim = <1>;
chan@0 {
label = "internal_rsense";
diff --git a/arch/arm/boot/dts/msm-pm8226.dtsi b/arch/arm/boot/dts/msm-pm8226.dtsi
index a13e66a..41897da 100644
--- a/arch/arm/boot/dts/msm-pm8226.dtsi
+++ b/arch/arm/boot/dts/msm-pm8226.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
@@ -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";
@@ -414,7 +412,9 @@
pm8226_iadc: iadc@3600 {
compatible = "qcom,qpnp-iadc";
- reg = <0x3600 0x100>;
+ reg = <0x3600 0x100>,
+ <0x12f1 0x1>;
+ reg-names = "iadc-base", "batt-id-trim-cnst-rds";
#address-cells = <1>;
#size-cells = <0>;
interrupts = <0x0 0x36 0x0>;
@@ -422,6 +422,8 @@
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 {
label = "internal_rsense";
diff --git a/arch/arm/boot/dts/msm-pm8941.dtsi b/arch/arm/boot/dts/msm-pm8941.dtsi
index 520decd..94a4e83 100644
--- a/arch/arm/boot/dts/msm-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm-pm8941.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
@@ -812,7 +812,9 @@
pm8941_iadc: iadc@3600 {
compatible = "qcom,qpnp-iadc";
- reg = <0x3600 0x100>;
+ reg = <0x3600 0x100>,
+ <0x12f1 0x1>;
+ reg-names = "iadc-base", "batt-id-trim-cnst-rds";
#address-cells = <1>;
#size-cells = <0>;
interrupts = <0x0 0x36 0x0>;
@@ -821,6 +823,7 @@
qcom,adc-vdd-reference = <1800>;
qcom,iadc-vadc = <&pm8941_vadc>;
qcom,iadc-poll-eoc;
+ qcom,use-default-rds-trim = <0>;
chan@0 {
label = "internal_rsense";
@@ -872,6 +875,7 @@
qcom,hw-settle-time = <2>;
qcom,fast-avg-setup = <3>;
qcom,btm-channel-number = <0x68>;
+ qcom,meas-interval-timer-idx = <2>;
};
chan@8 {
diff --git a/arch/arm/boot/dts/msm8226-1080p-cdp.dtsi b/arch/arm/boot/dts/msm8226-1080p-cdp.dtsi
index bb66538..4163b95 100644
--- a/arch/arm/boot/dts/msm8226-1080p-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8226-1080p-cdp.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
@@ -31,6 +31,7 @@
synaptics,i2c-pull-up;
synaptics,power-down;
synaptics,disable-gpios;
+ synaptics,fw-image-name = "PR1469074-s3408bt_001F010D.img";
};
};
@@ -129,6 +130,7 @@
qcom,cdc-mclk-gpios = <&pm8226_gpios 1 0>;
qcom,cdc-vdd-spkr-gpios = <&pm8226_gpios 2 0>;
qcom,headset-jack-type-NC;
+ qcom,mbhc-audio-jack-type = "6-pole-jack";
};
sound-9302 {
diff --git a/arch/arm/boot/dts/msm8226-1080p-mtp.dtsi b/arch/arm/boot/dts/msm8226-1080p-mtp.dtsi
index 31624de..a99df65 100644
--- a/arch/arm/boot/dts/msm8226-1080p-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8226-1080p-mtp.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
@@ -31,6 +31,7 @@
synaptics,i2c-pull-up;
synaptics,power-down;
synaptics,disable-gpios;
+ synaptics,fw-image-name = "PR1469074-s3408bt_001F010D.img";
};
};
diff --git a/arch/arm/boot/dts/msm8226-720p-cdp.dtsi b/arch/arm/boot/dts/msm8226-720p-cdp.dtsi
index 9a1eb36..00e90f3 100644
--- a/arch/arm/boot/dts/msm8226-720p-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8226-720p-cdp.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
@@ -106,6 +106,7 @@
qcom,cdc-mclk-gpios = <&pm8226_gpios 1 0>;
qcom,cdc-vdd-spkr-gpios = <&pm8226_gpios 2 0>;
qcom,headset-jack-type-NC;
+ qcom,mbhc-audio-jack-type = "6-pole-jack";
};
sound-9302 {
diff --git a/arch/arm/boot/dts/msm8226-camera-sensor-cdp.dtsi b/arch/arm/boot/dts/msm8226-camera-sensor-cdp.dtsi
index 20bb2aa..4170255 100644
--- a/arch/arm/boot/dts/msm8226-camera-sensor-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8226-camera-sensor-cdp.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -192,4 +192,63 @@
qcom,sensor-mode = <1>;
qcom,cci-master = <0>;
};
+ qcom,camera@0 {
+ cell-index = <0>;
+ compatible = "qcom,camera";
+ reg = <0x0>;
+ qcom,csiphy-sd-index = <0>;
+ qcom,csid-sd-index = <0>;
+ qcom,actuator-src = <&actuator0>;
+ qcom,led-flash-src = <&led_flash0>;
+ cam_vdig-supply = <&pm8226_l5>;
+ cam_vana-supply = <&pm8226_l19>;
+ cam_vio-supply = <&pm8226_lvs1>;
+ cam_vaf-supply = <&pm8226_l15>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-type = <0 1 0 0>;
+ qcom,cam-vreg-min-voltage = <1200000 0 2850000 2800000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2850000 2800000>;
+ qcom,cam-vreg-op-mode = <200000 0 80000 100000>;
+ gpios = <&msmgpio 26 0>,
+ <&msmgpio 37 0>,
+ <&msmgpio 36 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET1",
+ "CAM_STANDBY";
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
+
+ qcom,camera@1 {
+ cell-index = <1>;
+ compatible = "qcom,camera";
+ reg = <0x1>;
+ qcom,csiphy-sd-index = <1>;
+ qcom,csid-sd-index = <1>;
+ cam_vdig-supply = <&pm8226_l5>;
+ cam_vana-supply = <&pm8226_l19>;
+ cam_vio-supply = <&pm8226_lvs1>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana";
+ qcom,cam-vreg-type = <0 1 0>;
+ qcom,cam-vreg-min-voltage = <1200000 0 2850000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2850000>;
+ qcom,cam-vreg-op-mode = <200000 0 80000>;
+ gpios = <&msmgpio 26 0>,
+ <&msmgpio 28 0>,
+ <&msmgpio 35 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET",
+ "CAM_STANDBY";
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
};
diff --git a/arch/arm/boot/dts/msm8226-camera-sensor-mtp.dtsi b/arch/arm/boot/dts/msm8226-camera-sensor-mtp.dtsi
index 07a4383..97e7dff 100644
--- a/arch/arm/boot/dts/msm8226-camera-sensor-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8226-camera-sensor-mtp.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -106,4 +106,67 @@
qcom,cci-master = <0>;
status = "ok";
};
+ qcom,camera@0 {
+ cell-index = <0>;
+ compatible = "qcom,camera";
+ reg = <0x0>;
+ qcom,csiphy-sd-index = <0>;
+ qcom,csid-sd-index = <0>;
+ qcom,mount-angle = <0>;
+ qcom,actuator-src = <&actuator0>;
+ qcom,led-flash-src = <&led_flash0>;
+ cam_vdig-supply = <&pm8226_l5>;
+ cam_vana-supply = <&pm8226_l19>;
+ cam_vio-supply = <&pm8226_lvs1>;
+ cam_vaf-supply = <&pm8226_l15>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-type = <0 1 0 0>;
+ qcom,cam-vreg-min-voltage = <1200000 0 2850000 2800000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2850000 2800000>;
+ qcom,cam-vreg-op-mode = <200000 0 80000 100000>;
+ qcom,gpio-no-mux = <0>;
+ gpios = <&msmgpio 26 0>,
+ <&msmgpio 37 0>,
+ <&msmgpio 35 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET1",
+ "CAM_STANDBY";
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
+
+ qcom,camera@1 {
+ cell-index = <1>;
+ compatible = "qcom,camera";
+ reg = <0x1>;
+ qcom,csiphy-sd-index = <1>;
+ qcom,csid-sd-index = <1>;
+ qcom,mount-angle = <270>;
+ cam_vdig-supply = <&pm8226_l5>;
+ cam_vana-supply = <&pm8226_l19>;
+ cam_vio-supply = <&pm8226_lvs1>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana";
+ qcom,cam-vreg-type = <0 1 0>;
+ qcom,cam-vreg-min-voltage = <1200000 0 2850000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2850000>;
+ qcom,cam-vreg-op-mode = <200000 0 80000>;
+ qcom,gpio-no-mux = <0>;
+ gpios = <&msmgpio 26 0>,
+ <&msmgpio 28 0>,
+ <&msmgpio 36 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET",
+ "CAM_STANDBY";
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
};
diff --git a/arch/arm/boot/dts/msm8226-camera-sensor-qrd.dtsi b/arch/arm/boot/dts/msm8226-camera-sensor-qrd.dtsi
index 0436600..a553918 100644
--- a/arch/arm/boot/dts/msm8226-camera-sensor-qrd.dtsi
+++ b/arch/arm/boot/dts/msm8226-camera-sensor-qrd.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -442,4 +442,81 @@
qcom,cci-master = <0>;
status = "ok";
};
+ qcom,camera@0 {
+ cell-index = <0>;
+ compatible = "qcom,camera";
+ reg = <0x0>;
+ qcom,csiphy-sd-index = <0>;
+ qcom,csid-sd-index = <0>;
+ qcom,mount-angle = <270>;
+ qcom,actuator-src = <&actuator0>;
+ qcom,eeprom-src = <&eeprom0>;
+ qcom,led-flash-src = <&led_flash0>;
+ cam_vdig-supply = <&pm8226_l5>;
+ cam_vana-supply = <&pm8226_l19>;
+ cam_vio-supply = <&pm8226_lvs1>;
+ cam_vaf-supply = <&pm8226_l15>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-type = <0 1 0 0>;
+ qcom,cam-vreg-min-voltage = <1200000 0 2850000 2800000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2850000 2800000>;
+ qcom,cam-vreg-op-mode = <200000 0 80000 100000>;
+ qcom,gpio-no-mux = <0>;
+ gpios = <&msmgpio 26 0>,
+ <&msmgpio 37 0>,
+ <&msmgpio 36 0>,
+ <&msmgpio 22 0>,
+ <&msmgpio 34 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-vdig = <3>;
+ qcom,gpio-af-pwdm = <4>;
+ qcom,gpio-req-tbl-num = <0 1 2 3 4>;
+ qcom,gpio-req-tbl-flags = <1 0 0 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET1",
+ "CAM_STANDBY",
+ "CAM_VDIG",
+ "CAM_AF_PWDM";
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
+
+ qcom,camera@1 {
+ cell-index = <1>;
+ compatible = "qcom,camera";
+ reg = <0x1>;
+ qcom,csiphy-sd-index = <1>;
+ qcom,csid-sd-index = <1>;
+ qcom,eeprom-src = <&eeprom2>;
+ qcom,mount-angle = <270>;
+ cam_vdig-supply = <&pm8226_l5>;
+ cam_vana-supply = <&pm8226_l19>;
+ cam_vio-supply = <&pm8226_lvs1>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana";
+ qcom,cam-vreg-type = <0 1 0>;
+ qcom,cam-vreg-min-voltage = <1200000 0 2850000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2850000>;
+ qcom,cam-vreg-op-mode = <200000 0 80000>;
+ qcom,gpio-no-mux = <0>;
+ gpios = <&msmgpio 26 0>,
+ <&msmgpio 28 0>,
+ <&msmgpio 35 0>,
+ <&msmgpio 21 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-vdig = <3>;
+ qcom,gpio-req-tbl-num = <0 1 2 3>;
+ qcom,gpio-req-tbl-flags = <1 0 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET",
+ "CAM_STANDBY",
+ "CAM_VDIG";
+ qcom,gpio-set-tbl-num = <1 1>;
+ qcom,gpio-set-tbl-flags = <0 2>;
+ qcom,gpio-set-tbl-delay = <1000 4000>;
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
};
diff --git a/arch/arm/boot/dts/msm8226-qrd-skuf.dtsi b/arch/arm/boot/dts/msm8226-qrd-skuf.dtsi
index c3fcedb..42de953 100755
--- a/arch/arm/boot/dts/msm8226-qrd-skuf.dtsi
+++ b/arch/arm/boot/dts/msm8226-qrd-skuf.dtsi
@@ -125,6 +125,8 @@
FF FF FF FF FF FF FF FF FF FF
FF FF FF FF 3E 01];
goodix,fw_name = "gtp_fw.bin";
+ goodix,have-touch-key;
+ goodix,driver-send-cfg;
};
};
};
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 0146367..5e890d3 100644
--- a/arch/arm/boot/dts/msm8226-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8226-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
@@ -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 = <12>;
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>;
- 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-pm.dtsi b/arch/arm/boot/dts/msm8226-v1-pm.dtsi
index a1a8480..6e79e8a 100644
--- a/arch/arm/boot/dts/msm8226-v1-pm.dtsi
+++ b/arch/arm/boot/dts/msm8226-v1-pm.dtsi
@@ -145,16 +145,6 @@
compatible = "qcom,system-modes";
qcom,system-modes@0 {
- qcom,l2 = "l2_cache_gdhs";
- qcom,latency-us = <10700>;
- qcom,ss-power = <372>;
- qcom,energy-overhead = <738750>;
- qcom,time-overhead = <1410>;
- qcom,min-cpu-mode= "pc";
- qcom,sync-cpus;
- };
-
- qcom,system-modes@1 {
qcom,l2 = "l2_cache_pc_no_rpm";
qcom,latency-us = <1000>;
qcom,ss-power = <315>;
@@ -164,7 +154,7 @@
qcom,sync-cpus;
};
- qcom,system-modes@2 {
+ qcom,system-modes@1 {
qcom,l2 = "l2_cache_pc";
qcom,latency-us = <12700>;
qcom,ss-power = <315>;
@@ -172,6 +162,7 @@
qcom,time-overhead = <2400>;
qcom,min-cpu-mode= "pc";
qcom,sync-cpus;
+ qcom,send-rpm-sleep-set;
};
};
};
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-pm.dtsi b/arch/arm/boot/dts/msm8226-v2-pm.dtsi
index 2e9f6db..7753562 100644
--- a/arch/arm/boot/dts/msm8226-v2-pm.dtsi
+++ b/arch/arm/boot/dts/msm8226-v2-pm.dtsi
@@ -96,7 +96,7 @@
qcom,phase-port = <0x1>;
qcom,pfm-port = <0x2>;
qcom,saw2-spm-cmd-ret = [00 03 00 0f];
- qcom,saw2-spm-cmd-gdhs = [00 20 32 6b c0 e0 d0 42 07 50
+ qcom,saw2-spm-cmd-gdhs = [00 20 32 6b c0 e0 d0 42 03 50
4e 02 02 d0 e0 c0 22 6b 02 32 50 0f];
qcom,saw2-spm-cmd-pc-no-rpm = [00 32 b0 10 e0 d0 6b c0 42 f0
11 03 01 b0 50 4e 02 02 c0 d0 12 e0 6b 02 32
@@ -148,11 +148,11 @@
qcom,system-modes@0 {
qcom,l2 = "l2_cache_gdhs";
- qcom,latency-us = <10700>;
+ qcom,latency-us = <700>;
qcom,ss-power = <372>;
qcom,energy-overhead = <738750>;
qcom,time-overhead = <1410>;
- qcom,min-cpu-mode= "pc";
+ qcom,min-cpu-mode= "standalone_pc";
qcom,sync-cpus;
};
@@ -174,6 +174,7 @@
qcom,time-overhead = <2400>;
qcom,min-cpu-mode= "pc";
qcom,sync-cpus;
+ qcom,send-rpm-sleep-set;
};
};
};
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 a285ec9..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>,
@@ -100,6 +84,20 @@
<1401600000 10>,
<1497600000 11>,
<1593600000 12>;
+ qcom,speed5-bin-v2 =
+ < 0 0>,
+ < 384000000 2>,
+ < 787200000 4>,
+ < 998400000 5>,
+ <1094400000 6>,
+ <1190400000 7>,
+ <1305600000 8>,
+ <1344000000 9>,
+ <1401600000 10>,
+ <1497600000 11>,
+ <1593600000 12>,
+ <1689600000 13>,
+ <1785600000 14>;
};
};
diff --git a/arch/arm/boot/dts/msm8226.dtsi b/arch/arm/boot/dts/msm8226.dtsi
index a712ea7..eb97c8d 100644
--- a/arch/arm/boot/dts/msm8226.dtsi
+++ b/arch/arm/boot/dts/msm8226.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
@@ -284,6 +284,7 @@
qcom,hsusb-otg-otg-control = <2>;
qcom,dp-manual-pullup;
qcom,ahb-async-bridge-bypass;
+ qcom,usbin-vadc = <&pm8226_vadc>;
qcom,msm-bus,name = "usb";
qcom,msm-bus,num-cases = <3>;
@@ -1013,9 +1014,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>;
};
@@ -1045,7 +1046,9 @@
< 1344000 4066 >,
< 1401600 4066 >,
< 1497600 4066 >,
- < 1593600 4066 >;
+ < 1593600 4066 >,
+ < 1689600 4066 >,
+ < 1785600 4066 >;
};
qcom,ocmem@fdd00000 {
@@ -1305,15 +1308,16 @@
qcom,disk-encrypt-pipe-pair = <2>;
qcom,hlos-ce-hw-instance = <0>;
qcom,qsee-ce-hw-instance = <0>;
+ qcom,support-bus-scaling;
qcom,msm-bus,name = "qseecom-noc";
qcom,msm-bus,num-cases = <4>;
qcom,msm-bus,active-only = <0>;
qcom,msm-bus,num-paths = <1>;
qcom,msm-bus,vectors-KBps =
<55 512 0 0>,
- <55 512 3936000 393600>,
- <55 512 3936000 393600>,
- <55 512 3936000 393600>;
+ <55 512 0 0>,
+ <55 512 120000 1200000>,
+ <55 512 393600 3936000>;
};
qcom,qcrypto@fd404000 {
@@ -1505,6 +1509,7 @@
qcom,hw-settle-time = <2>;
qcom,fast-avg-setup = <3>;
qcom,btm-channel-number = <0x48>;
+ qcom,meas-interval-timer-idx = <2>;
};
chan@8 {
diff --git a/arch/arm/boot/dts/msm8610-bus.dtsi b/arch/arm/boot/dts/msm8610-bus.dtsi
index 54c698c..d26d660 100644
--- a/arch/arm/boot/dts/msm8610-bus.dtsi
+++ b/arch/arm/boot/dts/msm8610-bus.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
@@ -41,8 +41,8 @@
qcom,qport = <0>;
qcom,ws = <10000>;
qcom,mas-hw-id = <8>;
- qcom,prio1 = <2>;
- qcom,prio0 = <2>;
+ qcom,prio1 = <3>;
+ qcom,prio0 = <3>;
};
mas-vfe {
diff --git a/arch/arm/boot/dts/msm8610-camera-sensor-cdp-mtp.dtsi b/arch/arm/boot/dts/msm8610-camera-sensor-cdp-mtp.dtsi
index bdcab77..7f4197f 100644
--- a/arch/arm/boot/dts/msm8610-camera-sensor-cdp-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8610-camera-sensor-cdp-mtp.dtsi
@@ -261,5 +261,66 @@
qcom,sensor-mode = <1>;
qcom,cci-master = <0>;
};
+ qcom,camera@0 {
+ cell-index = <0>;
+ compatible = "qcom,camera";
+ reg = <0x0>;
+ qcom,csiphy-sd-index = <0>;
+ qcom,csid-sd-index = <0>;
+ qcom,mount-angle = <90>;
+ qcom,actuator-src = <&actuator0>;
+ qcom,led-flash-src = <&led_flash0>;
+ cam_vdig-supply = <&pm8110_l2>;
+ cam_vana-supply = <&pm8110_l19>;
+ cam_vio-supply = <&pm8110_l14>;
+ cam_vaf-supply = <&pm8110_l16>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-type = <0 0 0 0>;
+ qcom,cam-vreg-min-voltage = <1200000 1800000 2850000 3000000>;
+ qcom,cam-vreg-max-voltage = <1200000 1800000 2850000 3000000>;
+ qcom,cam-vreg-op-mode = <200000 8000 80000 100000>;
+ qcom,gpio-no-mux = <0>;
+ gpios = <&msmgpio 13 0>,
+ <&msmgpio 21 0>,
+ <&msmgpio 20 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET1",
+ "CAM_STANDBY";
+ status = "ok";
+ };
+
+ qcom,camera@1 {
+ cell-index = <1>;
+ compatible = "qcom,camera";
+ reg = <0x1>;
+ qcom,csiphy-sd-index = <1>;
+ qcom,csid-sd-index = <1>;
+ qcom,mount-angle = <90>;
+ cam_vdig-supply = <&pm8110_l4>;
+ cam_vana-supply = <&pm8110_l19>;
+ cam_vio-supply = <&pm8110_l14>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana";
+ qcom,cam-vreg-type = <0 1 0>;
+ qcom,cam-vreg-min-voltage = <1200000 0 2850000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2850000>;
+ qcom,cam-vreg-op-mode = <200000 0 80000>;
+ qcom,gpio-no-mux = <0>;
+ gpios = <&msmgpio 14 0>,
+ <&msmgpio 15 0>,
+ <&msmgpio 8 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET",
+ "CAM_STANDBY";
+ status = "ok";
+ };
};
diff --git a/arch/arm/boot/dts/msm8610-qrd-skuab.dtsi b/arch/arm/boot/dts/msm8610-qrd-skuab.dtsi
index c7fa9db..1554575 100644
--- a/arch/arm/boot/dts/msm8610-qrd-skuab.dtsi
+++ b/arch/arm/boot/dts/msm8610-qrd-skuab.dtsi
@@ -88,6 +88,8 @@
00 FF FF FF FF FF FF FF 00 00
00 FF FF FF FF FF FF FF FF FF
F8 FF FF FF E4 01];
+ goodix,have-touch-key;
+ goodix,driver-send-cfg;
};
};
gen-vkeys {
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/msm8610-v1-pm.dtsi b/arch/arm/boot/dts/msm8610-v1-pm.dtsi
index e075c71..5fb406b 100644
--- a/arch/arm/boot/dts/msm8610-v1-pm.dtsi
+++ b/arch/arm/boot/dts/msm8610-v1-pm.dtsi
@@ -145,16 +145,6 @@
compatible = "qcom,system-modes";
qcom,system-modes@0 {
- qcom,l2 = "l2_cache_gdhs";
- qcom,latency-us = <10700>;
- qcom,ss-power = <372>;
- qcom,energy-overhead = <738750>;
- qcom,time-overhead = <1410>;
- qcom,min-cpu-mode= "pc";
- qcom,sync-cpus;
- };
-
- qcom,system-modes@1 {
qcom,l2 = "l2_cache_pc_no_rpm";
qcom,latency-us = <1000>;
qcom,ss-power = <315>;
@@ -164,7 +154,7 @@
qcom,sync-cpus;
};
- qcom,system-modes@2 {
+ qcom,system-modes@1 {
qcom,l2 = "l2_cache_pc";
qcom,latency-us = <12700>;
qcom,ss-power = <315>;
@@ -172,6 +162,7 @@
qcom,time-overhead = <2400>;
qcom,min-cpu-mode= "pc";
qcom,sync-cpus;
+ qcom,send-rpm-sleep-set;
};
};
};
diff --git a/arch/arm/boot/dts/msm8610-v2-pm.dtsi b/arch/arm/boot/dts/msm8610-v2-pm.dtsi
index 447290d..331e344 100644
--- a/arch/arm/boot/dts/msm8610-v2-pm.dtsi
+++ b/arch/arm/boot/dts/msm8610-v2-pm.dtsi
@@ -96,7 +96,7 @@
qcom,phase-port = <0x1>;
qcom,pfm-port = <0x2>;
qcom,saw2-spm-cmd-ret = [00 03 00 0f];
- qcom,saw2-spm-cmd-gdhs = [00 20 32 6b c0 e0 d0 42 07 50
+ qcom,saw2-spm-cmd-gdhs = [00 20 32 6b c0 e0 d0 42 03 50
4e 02 02 d0 e0 c0 22 6b 02 32 50 0f];
qcom,saw2-spm-cmd-pc = [00 32 b0 10 e0 d0 6b c0 42 f0
11 07 01 b0 50 4e 02 02 c0 d0 12 e0 6b 02 32
@@ -148,11 +148,11 @@
qcom,system-modes@0 {
qcom,l2 = "l2_cache_gdhs";
- qcom,latency-us = <10700>;
+ qcom,latency-us = <700>;
qcom,ss-power = <372>;
qcom,energy-overhead = <738750>;
qcom,time-overhead = <1410>;
- qcom,min-cpu-mode= "pc";
+ qcom,min-cpu-mode= "standalone_pc";
qcom,sync-cpus;
};
@@ -174,6 +174,7 @@
qcom,time-overhead = <2400>;
qcom,min-cpu-mode= "pc";
qcom,sync-cpus;
+ qcom,send-rpm-sleep-set;
};
};
};
diff --git a/arch/arm/boot/dts/msm8610.dtsi b/arch/arm/boot/dts/msm8610.dtsi
index 61fa6bc..f152ceb 100644
--- a/arch/arm/boot/dts/msm8610.dtsi
+++ b/arch/arm/boot/dts/msm8610.dtsi
@@ -1168,6 +1168,7 @@
qcom,hw-settle-time = <2>;
qcom,fast-avg-setup = <3>;
qcom,btm-channel-number = <0x48>;
+ qcom,meas-interval-timer-idx = <2>;
};
chan@8 {
diff --git a/arch/arm/boot/dts/msm8612-qrd-camera-sensor.dtsi b/arch/arm/boot/dts/msm8612-qrd-camera-sensor.dtsi
index 205e749..4d50b36 100644
--- a/arch/arm/boot/dts/msm8612-qrd-camera-sensor.dtsi
+++ b/arch/arm/boot/dts/msm8612-qrd-camera-sensor.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -95,4 +95,61 @@
qcom,cci-master = <0>;
status = "ok";
};
+ qcom,camera@1 {
+ cell-index = <0>;
+ compatible = "qcom,camera";
+ reg = <0x01>;
+ qcom,csiphy-sd-index = <0>;
+ qcom,csid-sd-index = <0>;
+ qcom,mount-angle = <90>;
+ cam_vdig-supply = <&pm8110_l2>;
+ cam_vana-supply = <&pm8110_l19>;
+ cam_vio-supply = <&pm8110_l14>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana";
+ qcom,cam-vreg-type = <0 0 0>;
+ qcom,cam-vreg-min-voltage = <1200000 1800000 2850000>;
+ qcom,cam-vreg-max-voltage = <1200000 1800000 2850000>;
+ qcom,cam-vreg-op-mode = <200000 8000 80000>;
+ qcom,gpio-no-mux = <0>;
+ gpios = <&msmgpio 13 0>,
+ <&msmgpio 21 0>,
+ <&msmgpio 20 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET1",
+ "CAM_STANDBY";
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
+ qcom,camera@2 {
+ cell-index = <1>;
+ compatible = "qcom,camera";
+ reg = <0x02>;
+ qcom,csiphy-sd-index = <1>;
+ qcom,csid-sd-index = <1>;
+ qcom,mount-angle = <270>;
+ cam_vdig-supply = <&pm8110_l14>;
+ cam_vana-supply = <&pm8110_l19>;
+ cam_vio-supply = <&pm8110_l14>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana";
+ qcom,cam-vreg-type = <0 1 0>;
+ qcom,cam-vreg-min-voltage = <1800000 1800000 2850000>;
+ qcom,cam-vreg-max-voltage = <1800000 1800000 2850000>;
+ qcom,cam-vreg-op-mode = <200000 0 80000>;
+ qcom,gpio-no-mux = <0>;
+ gpios = <&msmgpio 14 0>,
+ <&msmgpio 15 0>,
+ <&msmgpio 85 0>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET",
+ "CAM_STANDBY";
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
};
diff --git a/arch/arm/boot/dts/msm8926-camera-sensor-qrd.dtsi b/arch/arm/boot/dts/msm8926-camera-sensor-qrd.dtsi
index ac2d908..8e053a9 100644
--- a/arch/arm/boot/dts/msm8926-camera-sensor-qrd.dtsi
+++ b/arch/arm/boot/dts/msm8926-camera-sensor-qrd.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -229,4 +229,74 @@
qcom,cci-master = <0>;
status = "ok";
};
+
+ qcom,camera@0 {
+ cell-index = <0>;
+ compatible = "qcom,camera";
+ reg = <0x00>;
+ qcom,csiphy-sd-index = <0>;
+ qcom,csid-sd-index = <0>;
+ qcom,actuator-src = <&actuator0>;
+ qcom,led-flash-src = <&led_flash0>;
+ qcom,mount-angle = <90>;
+ cam_vdig-supply = <&pm8226_l5>;
+ cam_vana-supply = <&pm8226_l19>;
+ cam_vio-supply = <&pm8226_lvs1>;
+ cam_vaf-supply = <&pm8226_l15>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-type = <0 1 0 0>;
+ qcom,cam-vreg-min-voltage = <1200000 0 2850000 2800000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2850000 2800000>;
+ qcom,cam-vreg-op-mode = <200000 0 80000 100000>;
+ qcom,gpio-no-mux = <0>;
+ gpios = <&msmgpio 26 0>,
+ <&msmgpio 37 0>,
+ <&msmgpio 36 0>,
+ <&msmgpio 15 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-af-pwdm = <3>;
+ qcom,gpio-req-tbl-num = <0 1 2 3>;
+ qcom,gpio-req-tbl-flags = <1 0 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET1",
+ "CAM_STANDBY",
+ "CAM_AF_PWDM";
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
+
+ qcom,camera@1 {
+ cell-index = <1>;
+ compatible = "qcom,camera";
+ reg = <0x01>;
+ qcom,csiphy-sd-index = <1>;
+ qcom,csid-sd-index = <1>;
+ qcom,mount-angle = <270>;
+ cam_vdig-supply = <&pm8226_l5>;
+ cam_vana-supply = <&pm8226_l19>;
+ cam_vio-supply = <&pm8226_lvs1>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana";
+ qcom,cam-vreg-type = <0 1 0>;
+ qcom,cam-vreg-min-voltage = <1200000 0 2850000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2850000>;
+ qcom,cam-vreg-op-mode = <200000 0 80000>;
+ qcom,gpio-no-mux = <0>;
+ gpios = <&msmgpio 26 0>,
+ <&msmgpio 28 0>,
+ <&msmgpio 35 0>,
+ <&msmgpio 23 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-vdig = <3>;
+ qcom,gpio-req-tbl-num = <0 1 2 3>;
+ qcom,gpio-req-tbl-flags = <1 0 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET",
+ "CAM_STANDBY",
+ "CAM_VDIG";
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
};
diff --git a/arch/arm/boot/dts/msm8926-v2-ext-buck.dtsi b/arch/arm/boot/dts/msm8926-v2-ext-buck.dtsi
index 07d91a8..e5e496e 100644
--- a/arch/arm/boot/dts/msm8926-v2-ext-buck.dtsi
+++ b/arch/arm/boot/dts/msm8926-v2-ext-buck.dtsi
@@ -12,6 +12,45 @@
/include/ "msm8926-v2.dtsi"
+&i2c_0 {
+ qcom,sda-gpio = <&msmgpio 14 0>;
+ qcom,scl-gpio = <&msmgpio 15 0>;
+
+ ncp6335d: ncp6335d-regulator@1c {
+ compatible = "onnn,ncp6335d-regulator";
+ reg = <0x1c>;
+ onnn,vsel = <0>;
+ onnn,slew-ns = <2666>;
+ onnn,step-size = <10000>;
+ onnn,min-slew-ns = <333>;
+ onnn,max-slew-ns = <2666>;
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1350000>;
+ onnn,min-setpoint = <600000>;
+ onnn,vsel-gpio = <&msmgpio 2 1>;
+ onnn,discharge-enable;
+ onnn,restore-reg;
+ onnn,tlmm-config = <0x80 0x0>;
+ };
+
+ fan53555: fan53555-regulator@60 {
+ compatible = "fairchild,fan53555-regulator";
+ reg = <0x60>;
+ fairchild,backup-vsel = <1>;
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-ramp-delay = <8000>;
+ fairchild,vsel-gpio = <&msmgpio 2 1>;
+ fairchild,restore-reg;
+ fairchild,disable-suspend;
+ };
+};
+
+&apc_vreg_corner {
+ vdd-apc-optional-prim-supply = <&ncp6335d>;
+ vdd-apc-supply = <&fan53555>;
+};
+
&soc {
};
diff --git a/arch/arm/boot/dts/msm8926-v2.dtsi b/arch/arm/boot/dts/msm8926-v2.dtsi
index db8e02f..1322573 100644
--- a/arch/arm/boot/dts/msm8926-v2.dtsi
+++ b/arch/arm/boot/dts/msm8926-v2.dtsi
@@ -66,6 +66,28 @@
};
};
+&pm8226_l3 {
+ regulator-max-microvolt = <1287500>;
+};
+
+&pm8226_l3_ao {
+ regulator-max-microvolt = <1287500>;
+};
+
+&pm8226_l3_so {
+ regulator-max-microvolt = <1287500>;
+};
+
&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 2bb202f..d6619a7 100644
--- a/arch/arm/boot/dts/msm8926.dtsi
+++ b/arch/arm/boot/dts/msm8926.dtsi
@@ -24,40 +24,6 @@
compatible = "qcom,msm8926";
};
-&i2c_0 {
- qcom,sda-gpio = <&msmgpio 14 0>;
- qcom,scl-gpio = <&msmgpio 15 0>;
-
- ncp6335d: ncp6335d-regulator@1c {
- compatible = "onnn,ncp6335d-regulator";
- reg = <0x1c>;
- onnn,vsel = <0>;
- onnn,slew-ns = <2666>;
- onnn,step-size = <10000>;
- onnn,min-slew-ns = <333>;
- onnn,max-slew-ns = <2666>;
- regulator-min-microvolt = <1050000>;
- regulator-max-microvolt = <1350000>;
- onnn,min-setpoint = <600000>;
- onnn,vsel-gpio = <&msmgpio 2 1>;
- onnn,discharge-enable;
- onnn,restore-reg;
- onnn,tlmm-config = <0x80 0x0>;
- };
-
- fan53555: fan53555-regulator@60 {
- compatible = "fairchild,fan53555-regulator";
- reg = <0x60>;
- fairchild,backup-vsel = <1>;
- regulator-min-microvolt = <1050000>;
- regulator-max-microvolt = <1350000>;
- regulator-ramp-delay = <8000>;
- fairchild,vsel-gpio = <&msmgpio 2 1>;
- fairchild,restore-reg;
- fairchild,disable-suspend;
- };
-};
-
&soc {
qcom,mss@fc880000 {
reg = <0xfc880000 0x100>,
@@ -73,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>,
@@ -95,6 +66,20 @@
<1401600000 10>,
<1497600000 11>,
<1593600000 12>;
+ qcom,speed5-bin-v1 =
+ < 0 0>,
+ < 384000000 2>,
+ < 787200000 4>,
+ < 998400000 5>,
+ <1094400000 6>,
+ <1190400000 7>,
+ <1305600000 8>,
+ <1344000000 9>,
+ <1401600000 10>,
+ <1497600000 11>,
+ <1593600000 12>,
+ <1689600000 13>,
+ <1785600000 14>;
};
qcom,msm-thermal {
@@ -147,44 +132,21 @@
};
};
-&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>;
- vdd-apc-optional-prim-supply = <&ncp6335d>;
- vdd-apc-optional-sec-supply = <&fan53555>;
};
&tsens {
diff --git a/arch/arm/boot/dts/msm8974-camera-sensor-cdp.dtsi b/arch/arm/boot/dts/msm8974-camera-sensor-cdp.dtsi
index 9948833..bdc3bef 100644
--- a/arch/arm/boot/dts/msm8974-camera-sensor-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8974-camera-sensor-cdp.dtsi
@@ -1,5 +1,5 @@
/*
- * 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
@@ -178,4 +178,97 @@
qcom,sensor-mode = <1>;
qcom,cci-master = <0>;
};
+ qcom,camera@0 {
+ cell-index = <0>;
+ compatible = "qcom,camera";
+ reg = <0x0>;
+ qcom,csiphy-sd-index = <0>;
+ qcom,csid-sd-index = <0>;
+ qcom,actuator-src = <&actuator0>;
+ qcom,vdd-cx-supply = <&pm8841_s2>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
+ cam_vdig-supply = <&pm8941_l3>;
+ cam_vana-supply = <&pm8941_l17>;
+ cam_vio-supply = <&pm8941_lvs3>;
+ cam_vaf-supply = <&pm8941_l23>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-type = <0 1 0 0>;
+ qcom,cam-vreg-min-voltage = <1225000 0 2850000 3000000>;
+ qcom,cam-vreg-max-voltage = <1225000 0 2850000 3000000>;
+ qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+ qcom,gpio-no-mux = <0>;
+ gpios = <&msmgpio 15 0>,
+ <&msmgpio 90 0>,
+ <&msmgpio 89 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET1",
+ "CAM_STANDBY";
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
+
+ qcom,camera@1 {
+ cell-index = <1>;
+ compatible = "qcom,camera";
+ reg = <0x1>;
+ qcom,csiphy-sd-index = <1>;
+ qcom,csid-sd-index = <0>;
+ qcom,vdd-cx-supply = <&pm8841_s2>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
+ cam_vdig-supply = <&pm8941_l3>;
+ cam_vana-supply = <&pm8941_l17>;
+ cam_vio-supply = <&pm8941_lvs3>;
+ cam_vaf-supply = <&pm8941_l23>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-type = <0 1 0 0>;
+ qcom,cam-vreg-min-voltage = <1225000 0 2850000 3000000>;
+ qcom,cam-vreg-max-voltage = <1225000 0 2850000 3000000>;
+ qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+ gpios = <&msmgpio 16 0>,
+ <&msmgpio 92 0>,
+ <&msmgpio 91 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET1",
+ "CAM_STANDBY";
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
+
+ qcom,camera@2 {
+ cell-index = <2>;
+ compatible = "qcom,camera";
+ reg = <0x2>;
+ qcom,csiphy-sd-index = <2>;
+ qcom,csid-sd-index = <2>;
+ qcom,vdd-cx-supply = <&pm8841_s2>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
+ cam_vdig-supply = <&pm8941_l3>;
+ cam_vana-supply = <&pm8941_l17>;
+ cam_vio-supply = <&pm8941_lvs3>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vana", "cam_vio";
+ qcom,cam-vreg-type = <0 0 1>;
+ qcom,cam-vreg-min-voltage = <1225000 2850000 0>;
+ qcom,cam-vreg-max-voltage = <1225000 2850000 0>;
+ qcom,cam-vreg-op-mode = <105000 80000 0>;
+ qcom,gpio-no-mux = <0>;
+ gpios = <&msmgpio 17 0>,
+ <&msmgpio 18 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-req-tbl-num = <0 1>;
+ qcom,gpio-req-tbl-flags = <1 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET1";
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
};
diff --git a/arch/arm/boot/dts/msm8974-camera-sensor-dragonboard.dtsi b/arch/arm/boot/dts/msm8974-camera-sensor-dragonboard.dtsi
index 2f8e558..43b0d75 100644
--- a/arch/arm/boot/dts/msm8974-camera-sensor-dragonboard.dtsi
+++ b/arch/arm/boot/dts/msm8974-camera-sensor-dragonboard.dtsi
@@ -1,5 +1,5 @@
/*
- * 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
@@ -185,4 +185,100 @@
qcom,sensor-mode = <1>;
qcom,cci-master = <0>;
};
+ qcom,camera@0 {
+ cell-index = <0>;
+ compatible = "qcom,camera";
+ reg = <0x0>;
+ qcom,csiphy-sd-index = <0>;
+ qcom,csid-sd-index = <0>;
+ qcom,mount-angle = <0>;
+ qcom,actuator-src = <&actuator0>;
+ qcom,vdd-cx-supply = <&pm8841_s2>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
+ cam_vana-supply = <&pm8941_l17>;
+ cam_vio-supply = <&pm8941_lvs3>;
+ cam_vaf-supply = <&pm8941_l23>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-type = <0 1 0 0>;
+ qcom,cam-vreg-min-voltage = <1225000 0 2850000 3000000>;
+ qcom,cam-vreg-max-voltage = <1225000 0 2850000 3000000>;
+ qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+ gpios = <&msmgpio 15 0>,
+ <&msmgpio 90 0>,
+ <&msmgpio 89 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET1",
+ "CAM_STANDBY";
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
+
+ qcom,camera@1 {
+ cell-index = <1>;
+ compatible = "qcom,camera";
+ reg = <0x1>;
+ qcom,csiphy-sd-index = <1>;
+ qcom,csid-sd-index = <1>;
+ qcom,mount-angle = <180>;
+ qcom,vdd-cx-supply = <&pm8841_s2>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
+ cam_vdig-supply = <&pm8941_l3>;
+ cam_vana-supply = <&pm8941_l17>;
+ cam_vio-supply = <&pm8941_lvs3>;
+ cam_vaf-supply = <&pm8941_l23>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-type = <0 1 0 0>;
+ qcom,cam-vreg-min-voltage = <1225000 0 2850000 3000000>;
+ qcom,cam-vreg-max-voltage = <1225000 0 2850000 3000000>;
+ qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+ gpios = <&msmgpio 16 0>,
+ <&msmgpio 92 0>,
+ <&msmgpio 91 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET1",
+ "CAM_STANDBY";
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
+
+ qcom,camera@2 {
+ cell-index = <2>;
+ compatible = "qcom,camera";
+ reg = <0x2>;
+ qcom,csiphy-sd-index = <2>;
+ qcom,csid-sd-index = <2>;
+ qcom,vdd-cx-supply = <&pm8841_s2>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
+ cam_vdig-supply = <&pm8941_l3>;
+ cam_vana-supply = <&pm8941_l17>;
+ cam_vio-supply = <&pm8941_lvs3>;
+ cam_vaf-supply = <&pm8941_l23>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-type = <0 1 0 0>;
+ qcom,cam-vreg-min-voltage = <1225000 0 2850000 3000000>;
+ qcom,cam-vreg-max-voltage = <1225000 0 2850000 3000000>;
+ qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+ qcom,gpio-no-mux = <0>;
+ gpios = <&msmgpio 17 0>,
+ <&msmgpio 18 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET1";
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
};
diff --git a/arch/arm/boot/dts/msm8974-camera-sensor-fluid.dtsi b/arch/arm/boot/dts/msm8974-camera-sensor-fluid.dtsi
index 07eb311..529d3ba 100644
--- a/arch/arm/boot/dts/msm8974-camera-sensor-fluid.dtsi
+++ b/arch/arm/boot/dts/msm8974-camera-sensor-fluid.dtsi
@@ -1,5 +1,5 @@
/*
- * 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
@@ -190,4 +190,100 @@
qcom,sensor-mode = <1>;
qcom,cci-master = <0>;
};
+ qcom,camera@0 {
+ cell-index = <0>;
+ compatible = "qcom,camera";
+ reg = <0x0>;
+ qcom,csiphy-sd-index = <0>;
+ qcom,csid-sd-index = <0>;
+ qcom,mount-angle = <270>;
+ qcom,actuator-src = <&actuator0>;
+ qcom,led-flash-src = <&led_flash0>;
+ qcom,vdd-cx-supply = <&pm8841_s2>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
+ cam_vdig-supply = <&pm8941_l3>;
+ cam_vana-supply = <&pm8941_l17>;
+ cam_vio-supply = <&pm8941_lvs3>;
+ cam_vaf-supply = <&pm8941_l23>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-type = <0 1 0 0>;
+ qcom,cam-vreg-min-voltage = <1225000 0 2850000 3000000>;
+ qcom,cam-vreg-max-voltage = <1225000 0 2850000 3000000>;
+ qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+ gpios = <&msmgpio 15 0>,
+ <&msmgpio 90 0>,
+ <&msmgpio 89 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET1",
+ "CAM_STANDBY";
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
+
+ qcom,camera@1 {
+ cell-index = <1>;
+ compatible = "qcom,camera";
+ reg = <0x1>;
+ qcom,csiphy-sd-index = <1>;
+ qcom,csid-sd-index = <1>;
+ qcom,mount-angle = <90>;
+ qcom,vdd-cx-supply = <&pm8841_s2>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
+ cam_vdig-supply = <&pm8941_l3>;
+ cam_vana-supply = <&pm8941_l17>;
+ cam_vio-supply = <&pm8941_lvs3>;
+ cam_vaf-supply = <&pm8941_l23>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-type = <0 1 0 0>;
+ qcom,cam-vreg-min-voltage = <1225000 0 2850000 3000000>;
+ qcom,cam-vreg-max-voltage = <1225000 0 2850000 3000000>;
+ qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+ gpios = <&msmgpio 17 0>,
+ <&msmgpio 18 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-req-tbl-num = <0 1>;
+ qcom,gpio-req-tbl-flags = <1 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET1";
+ qcom,cci-master = <1>;
+ status = "ok";
+ };
+
+ qcom,camera@2 {
+ cell-index = <2>;
+ compatible = "qcom,camera";
+ reg = <0x2>;
+ qcom,csiphy-sd-index = <2>;
+ qcom,csid-sd-index = <2>;
+ qcom,vdd-cx-supply = <&pm8841_s2>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
+ cam_vdig-supply = <&pm8941_l3>;
+ cam_vana-supply = <&pm8941_l17>;
+ cam_vio-supply = <&pm8941_lvs3>;
+ cam_vaf-supply = <&pm8941_l23>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-type = <0 1 0 0>;
+ qcom,cam-vreg-min-voltage = <1225000 0 2850000 3000000>;
+ qcom,cam-vreg-max-voltage = <1225000 0 2850000 3000000>;
+ qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+ gpios = <&msmgpio 17 0>,
+ <&msmgpio 18 0>,
+ <&msmgpio 28 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET1",
+ "CAM_STANDBY";
+ qcom,cci-master = <1>;
+ status = "ok";
+ };
};
diff --git a/arch/arm/boot/dts/msm8974-camera-sensor-liquid.dtsi b/arch/arm/boot/dts/msm8974-camera-sensor-liquid.dtsi
index bf7f492..854e8f7 100644
--- a/arch/arm/boot/dts/msm8974-camera-sensor-liquid.dtsi
+++ b/arch/arm/boot/dts/msm8974-camera-sensor-liquid.dtsi
@@ -1,6 +1,6 @@
/*
- * 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
@@ -179,4 +179,98 @@
qcom,sensor-mode = <1>;
qcom,cci-master = <0>;
};
+ qcom,camera@0 {
+ cell-index = <0>;
+ compatible = "qcom,camera";
+ reg = <0x0>;
+ qcom,csiphy-sd-index = <0>;
+ qcom,csid-sd-index = <0>;
+ qcom,mount-angle = <0>;
+ qcom,actuator-src = <&actuator0>;
+ qcom,vdd-cx-supply = <&pm8841_s2>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
+ cam_vdig-supply = <&pm8941_l3>;
+ cam_vana-supply = <&pm8941_l17>;
+ cam_vio-supply = <&pm8941_lvs2>;
+ cam_vaf-supply = <&pm8941_l23>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-type = <0 1 0 0>;
+ qcom,cam-vreg-min-voltage = <1225000 0 2850000 3000000>;
+ qcom,cam-vreg-max-voltage = <1225000 0 2850000 3000000>;
+ qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+ gpios = <&msmgpio 15 0>,
+ <&msmgpio 90 0>,
+ <&msmgpio 89 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET1",
+ "CAM_STANDBY";
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
+
+ qcom,camera@1 {
+ cell-index = <1>;
+ compatible = "qcom,camera";
+ reg = <0x1>;
+ qcom,csiphy-sd-index = <1>;
+ qcom,csid-sd-index = <1>;
+ qcom,mount-angle = <180>;
+ qcom,vdd-cx-supply = <&pm8841_s2>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
+ cam_vdig-supply = <&pm8941_l3>;
+ cam_vana-supply = <&pm8941_l17>;
+ cam_vio-supply = <&pm8941_lvs2>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vana", "cam_vio";
+ qcom,cam-vreg-type = <0 0 1>;
+ qcom,cam-vreg-min-voltage = <1225000 2850000 0>;
+ qcom,cam-vreg-max-voltage = <1225000 2850000 0>;
+ qcom,cam-vreg-op-mode = <105000 80000 0>;
+ qcom,gpio-no-mux = <0>;
+ gpios = <&msmgpio 17 0>,
+ <&msmgpio 18 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-req-tbl-num = <0 1>;
+ qcom,gpio-req-tbl-flags = <1 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET1";
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
+
+ qcom,camera@2 {
+ cell-index = <2>;
+ compatible = "qcom,camera";
+ reg = <0x2>;
+ qcom,csiphy-sd-index = <2>;
+ qcom,csid-sd-index = <2>;
+ qcom,vdd-cx-supply = <&pm8841_s2>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
+ cam_vdig-supply = <&pm8941_l3>;
+ cam_vana-supply = <&pm8941_l17>;
+ cam_vio-supply = <&pm8941_lvs3>;
+ cam_vaf-supply = <&pm8941_l23>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-type = <0 1 0 0>;
+ qcom,cam-vreg-min-voltage = <1225000 0 2850000 3000000>;
+ qcom,cam-vreg-max-voltage = <1225000 0 2850000 3000000>;
+ qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+ gpios = <&msmgpio 17 0>,
+ <&msmgpio 18 0>,
+ <&msmgpio 28 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET1",
+ "CAM_STANDBY";
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
};
diff --git a/arch/arm/boot/dts/msm8974-camera-sensor-mtp.dtsi b/arch/arm/boot/dts/msm8974-camera-sensor-mtp.dtsi
index 29e2aaa..59e1a7c 100644
--- a/arch/arm/boot/dts/msm8974-camera-sensor-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8974-camera-sensor-mtp.dtsi
@@ -1,5 +1,5 @@
/*
- * 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
@@ -191,4 +191,95 @@
qcom,sensor-mode = <1>;
qcom,cci-master = <0>;
};
+ qcom,camera@0 {
+ cell-index = <0>;
+ compatible = "qcom,camera";
+ reg = <0x0>;
+ qcom,csiphy-sd-index = <0>;
+ qcom,csid-sd-index = <0>;
+ qcom,mount-angle = <90>;
+ qcom,actuator-src = <&actuator0>;
+ qcom,led-flash-src = <&led_flash0>;
+ qcom,vdd-cx-supply = <&pm8841_s2>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
+ cam_vdig-supply = <&pm8941_l3>;
+ cam_vana-supply = <&pm8941_l17>;
+ cam_vio-supply = <&pm8941_lvs3>;
+ cam_vaf-supply = <&pm8941_l23>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-type = <0 1 0 0>;
+ qcom,cam-vreg-min-voltage = <1225000 0 2850000 3000000>;
+ qcom,cam-vreg-max-voltage = <1225000 0 2850000 3000000>;
+ qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+ gpios = <&msmgpio 15 0>,
+ <&msmgpio 90 0>,
+ <&msmgpio 89 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET1",
+ "CAM_STANDBY";
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
+
+ qcom,camera@1 {
+ cell-index = <1>;
+ compatible = "qcom,camera";
+ reg = <0x1>;
+ qcom,csiphy-sd-index = <1>;
+ qcom,csid-sd-index = <1>;
+ qcom,mount-angle = <90>;
+ qcom,vdd-cx-supply = <&pm8841_s2>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
+ cam_vdig-supply = <&pm8941_l3>;
+ cam_vana-supply = <&pm8941_l17>;
+ cam_vio-supply = <&pm8941_lvs3>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-type = <0 1 0 0>;
+ qcom,cam-vreg-min-voltage = <1225000 0 2850000 3000000>;
+ qcom,cam-vreg-max-voltage = <1225000 0 2850000 3000000>;
+ qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+ gpios = <&msmgpio 17 0>,
+ <&msmgpio 18 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-req-tbl-num = <0 1>;
+ qcom,gpio-req-tbl-flags = <1 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET1";
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
+
+ qcom,camera@2 {
+ cell-index = <2>;
+ compatible = "qcom,camera";
+ reg = <0x02>;
+ qcom,csiphy-sd-index = <2>;
+ qcom,csid-sd-index = <2>;
+ qcom,mount-angle = <90>;
+ cam_vdig-supply = <&pm8941_l3>;
+ cam_vana-supply = <&pm8941_l17>;
+ cam_vio-supply = <&pm8941_lvs3>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vana", "cam_vio";
+ qcom,cam-vreg-type = <0 0 1>;
+ qcom,cam-vreg-min-voltage = <1225000 2850000 0>;
+ qcom,cam-vreg-max-voltage = <1225000 2850000 0>;
+ qcom,cam-vreg-op-mode = <105000 80000 0>;
+ qcom,gpio-no-mux = <0>;
+ gpios = <&msmgpio 17 0>,
+ <&msmgpio 18 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-req-tbl-num = <0 1>;
+ qcom,gpio-req-tbl-flags = <1 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET1";
+ qcom,cci-master = <1>;
+ status = "ok";
+ };
+
};
diff --git a/arch/arm/boot/dts/msm8974-cdp.dtsi b/arch/arm/boot/dts/msm8974-cdp.dtsi
index 27536db..3b4c881 100644
--- a/arch/arm/boot/dts/msm8974-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8974-cdp.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
@@ -220,6 +220,7 @@
qcom,hdmi-audio-rx;
qcom,us-euro-gpios = <&pm8941_gpios 20 0>;
qcom,cdc-micbias2-headset-only;
+ qcom,mbhc-audio-jack-type = "6-pole-jack";
};
usb2_otg_sw: regulator-tpd4s214 {
@@ -765,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-fluid.dtsi b/arch/arm/boot/dts/msm8974-fluid.dtsi
index f4b4d4a..eb5a5b6 100644
--- a/arch/arm/boot/dts/msm8974-fluid.dtsi
+++ b/arch/arm/boot/dts/msm8974-fluid.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
@@ -271,6 +271,7 @@
qcom,hdmi-audio-rx;
qcom,ext-ult-lo-amp-gpio = <&pm8941_gpios 6 0>;
qcom,cdc-micbias2-headset-only;
+ qcom,mbhc-audio-jack-type = "6-pole-jack";
};
};
diff --git a/arch/arm/boot/dts/msm8974-liquid.dtsi b/arch/arm/boot/dts/msm8974-liquid.dtsi
index 397e10e..942aba4 100644
--- a/arch/arm/boot/dts/msm8974-liquid.dtsi
+++ b/arch/arm/boot/dts/msm8974-liquid.dtsi
@@ -318,7 +318,7 @@
compatible = "qca,ar3002";
qca,bt-reset-gpio = <&pm8941_gpios 34 0>;
qca,bt-chip-pwd-supply = <&ath_chip_pwd_l>;
- qca,bt-vdd-io-supply = <&pm8941_s3>;
+ qca,bt-vdd-io-supply = <&pm8941_l10>;
qca,bt-vdd-pa-supply = <&pm8941_l19>;
};
@@ -380,47 +380,34 @@
qcom,prim-auxpcm-gpio-set = "prim-gpio-tert";
};
- hsic_hub {
- compatible = "qcom,hsic-smsc-hub";
- smsc,model-id = <3503>;
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
- smsc,reset-gpio = <&pm8941_gpios 8 0x00>;
- smsc,refclk-gpio = <&pm8941_gpios 16 0x00>;
- smsc,int-gpio = <&msmgpio 50 0x00>;
- hub_int-supply = <&pm8941_l10>;
- hub_vbus-supply = <&ext_5v>;
+ hsic_host: hsic@f9a00000 {
+ compatible = "qcom,hsic-host";
+ reg = <0xf9a00000 0x400>;
+ #address-cells = <0>;
+ interrupt-parent = <&hsic_host>;
+ interrupts = <0 1 2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 136 0
+ 1 &intc 0 148 0
+ 2 &msmgpio 144 0x8>;
+ interrupt-names = "core_irq", "async_irq", "wakeup";
+ hsic_vdd_dig-supply = <&pm8841_s2_corner>;
+ HSIC_GDSC-supply = <&gdsc_usb_hsic>;
+ hsic,strobe-gpio = <&msmgpio 144 0x00>;
+ hsic,data-gpio = <&msmgpio 145 0x00>;
+ hsic,ignore-cal-pad-config;
+ hsic,strobe-pad-offset = <0x2050>;
+ hsic,data-pad-offset = <0x2054>;
+ qcom,phy-susp-sof-workaround;
+ hsic,vdd-voltage-level = <1 5 7>;
- hsic_host: hsic@f9a00000 {
- compatible = "qcom,hsic-host";
- reg = <0xf9a00000 0x400>;
- #address-cells = <0>;
- interrupt-parent = <&hsic_host>;
- interrupts = <0 1 2>;
- #interrupt-cells = <1>;
- interrupt-map-mask = <0xffffffff>;
- interrupt-map = <0 &intc 0 136 0
- 1 &intc 0 148 0
- 2 &msmgpio 144 0x8>;
- interrupt-names = "core_irq", "async_irq", "wakeup";
- hsic_vdd_dig-supply = <&pm8841_s2_corner>;
- HSIC_GDSC-supply = <&gdsc_usb_hsic>;
- hsic,strobe-gpio = <&msmgpio 144 0x00>;
- hsic,data-gpio = <&msmgpio 145 0x00>;
- hsic,ignore-cal-pad-config;
- hsic,strobe-pad-offset = <0x2050>;
- hsic,data-pad-offset = <0x2054>;
- qcom,phy-susp-sof-workaround;
- hsic,vdd-voltage-level = <1 5 7>;
-
- qcom,msm-bus,name = "hsic";
- qcom,msm-bus,num-cases = <2>;
- qcom,msm-bus,num-paths = <1>;
- qcom,msm-bus,vectors-KBps =
- <85 512 0 0>,
- <85 512 40000 160000>;
- };
+ qcom,msm-bus,name = "hsic";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <85 512 0 0>,
+ <85 512 40000 160000>;
};
wlan0: qca,wlan {
@@ -445,6 +432,38 @@
qcom,msm-bus,name = "wlan_sdio";
qca,wifi-chip-pwd-supply = <&ath_chip_pwd_l>;
};
+
+ qcom,pronto@fb21b000 {
+ status = "disabled";
+ };
+
+ qcom,iris-fm {
+ status = "disabled";
+ };
+
+ qcom,wcnss-wlan@fb000000 {
+ status = "disabled";
+ };
+
+ qcom,smd-wcnss {
+ status = "disabled";
+ };
+
+ qcom,smsm-wcnss {
+ status = "disabled";
+ };
+};
+
+&pm8941_l19 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ qcom,init-voltage = <3300000>;
+};
+
+&pm8941_l10 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,init-voltage = <1800000>;
};
&mdss_fb0 {
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/boot/dts/msm8974-mtp.dtsi b/arch/arm/boot/dts/msm8974-mtp.dtsi
index 6cc49c4..d118d51 100644
--- a/arch/arm/boot/dts/msm8974-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8974-mtp.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
@@ -214,6 +214,7 @@
sound {
qcom,model = "msm8974-taiko-mtp-snd-card";
qcom,cdc-micbias2-headset-only;
+ qcom,mbhc-audio-jack-type = "6-pole-jack";
};
};
@@ -707,6 +708,7 @@
taiko_codec {
qcom,cdc-micbias1-ext-cap;
qcom,cdc-micbias2-ext-cap;
+ qcom,cdc-micbias3-ext-cap;
qcom,cdc-micbias4-ext-cap;
};
};
diff --git a/arch/arm/boot/dts/msm8974-v1.dtsi b/arch/arm/boot/dts/msm8974-v1.dtsi
index 556e912..6146454 100644
--- a/arch/arm/boot/dts/msm8974-v1.dtsi
+++ b/arch/arm/boot/dts/msm8974-v1.dtsi
@@ -149,6 +149,10 @@
qcom,hsusb-otg-pnoc-errata-fix;
};
+&usb3 {
+ qcom,usbin-vadc = <&pm8941_vadc>;
+};
+
&gdsc_venus {
qcom,skip-logic-collapse;
qcom,retain-periph;
diff --git a/arch/arm/boot/dts/msm8974-v2-pm.dtsi b/arch/arm/boot/dts/msm8974-v2-pm.dtsi
index 5e6efb9..84a8c2d 100644
--- a/arch/arm/boot/dts/msm8974-v2-pm.dtsi
+++ b/arch/arm/boot/dts/msm8974-v2-pm.dtsi
@@ -172,12 +172,13 @@
qcom,system-mode@0 {
qcom,l2 = "l2_cache_gdhs";
- qcom,latency-us = <20000>;
+ qcom,latency-us = <500>;
qcom,ss-power = <163>;
- qcom,energy-overhead = <1577736>;
- qcom,time-overhead = <5067>;
- qcom,min-cpu-mode= "pc";
+ qcom,energy-overhead = <577736>;
+ qcom,time-overhead = <1000>;
+ qcom,min-cpu-mode= "standalone_pc";
qcom,sync-cpus;
+
};
qcom,system-mode@1 {
@@ -188,6 +189,7 @@
qcom,time-overhead = <6605>;
qcom,min-cpu-mode = "pc";
qcom,sync-cpus;
+ qcom,send-rpm-sleep-set;
};
};
};
diff --git a/arch/arm/boot/dts/msm8974-v2.dtsi b/arch/arm/boot/dts/msm8974-v2.dtsi
index 5607257..7e102fe 100644
--- a/arch/arm/boot/dts/msm8974-v2.dtsi
+++ b/arch/arm/boot/dts/msm8974-v2.dtsi
@@ -49,6 +49,10 @@
};
};
+&usb3 {
+ qcom,usbin-vadc = <&pm8941_vadc>;
+};
+
/* GPU overrides */
&msm_gpu {
/* Updated chip ID */
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index 030a1f3..23ddc8c 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -745,7 +745,7 @@
qcom,cdc-micbias-ldoh-v = <0x3>;
qcom,cdc-micbias-cfilt1-mv = <1800>;
qcom,cdc-micbias-cfilt2-mv = <2700>;
- qcom,cdc-micbias-cfilt3-mv = <1800>;
+ qcom,cdc-micbias-cfilt3-mv = <2700>;
qcom,cdc-micbias1-cfilt-sel = <0x0>;
qcom,cdc-micbias2-cfilt-sel = <0x1>;
qcom,cdc-micbias3-cfilt-sel = <0x2>;
@@ -2012,7 +2012,7 @@
qcom,disk-encrypt-pipe-pair = <2>;
qcom,hlos-ce-hw-instance = <1>;
qcom,qsee-ce-hw-instance = <0>;
- qcom,support-bus-scaling = <1>;
+ qcom,support-bus-scaling;
qcom,msm-bus,name = "qseecom-noc";
qcom,msm-bus,num-cases = <4>;
qcom,msm-bus,num-paths = <1>;
@@ -2133,9 +2133,13 @@
interrupts = <0 236 0>;
qcom,bam-pipe-pair = <2>;
qcom,ce-hw-instance = <1>;
+ qcom,clk-mgmt-sus-res;
qcom,msm-bus,name = "qcrypto-noc";
qcom,msm-bus,num-cases = <2>;
qcom,msm-bus,num-paths = <1>;
+ qcom,use-sw-aes-cbc-ecb-ctr-algo;
+ qcom,use-sw-aes-xts-algo;
+ qcom,use-sw-ahash-algo;
qcom,msm-bus,vectors-KBps =
<56 512 0 0>,
<56 512 3936000 393600>;
diff --git a/arch/arm/boot/dts/msm8974pro-ab-pm8941-cdp.dts b/arch/arm/boot/dts/msm8974pro-ab-pm8941-cdp.dts
index b6a6fcb..5a01945 100644
--- a/arch/arm/boot/dts/msm8974pro-ab-pm8941-cdp.dts
+++ b/arch/arm/boot/dts/msm8974pro-ab-pm8941-cdp.dts
@@ -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
@@ -20,3 +20,8 @@
compatible = "qcom,msm8974-cdp", "qcom,msm8974", "qcom,cdp";
qcom,board-id = <1 0>;
};
+
+&sdhc_1 {
+ qcom,pad-pull-on = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
+ qcom,pad-pull-off = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
+};
diff --git a/arch/arm/boot/dts/msm8974pro-ab-pm8941-fluid-hbtp.dts b/arch/arm/boot/dts/msm8974pro-ab-pm8941-fluid-hbtp.dts
index f4f7968..6ba8b5e 100644
--- a/arch/arm/boot/dts/msm8974pro-ab-pm8941-fluid-hbtp.dts
+++ b/arch/arm/boot/dts/msm8974pro-ab-pm8941-fluid-hbtp.dts
@@ -40,3 +40,8 @@
*/
status = "disabled";
};
+
+&sdhc_1 {
+ qcom,pad-pull-on = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
+ qcom,pad-pull-off = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
+};
diff --git a/arch/arm/boot/dts/msm8974pro-ab-pm8941-fluid.dts b/arch/arm/boot/dts/msm8974pro-ab-pm8941-fluid.dts
index be298d1..010a4ad 100644
--- a/arch/arm/boot/dts/msm8974pro-ab-pm8941-fluid.dts
+++ b/arch/arm/boot/dts/msm8974pro-ab-pm8941-fluid.dts
@@ -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
@@ -20,3 +20,8 @@
compatible = "qcom,msm8974-fluid", "qcom,msm8974", "qcom,fluid";
qcom,board-id = <3 0>;
};
+
+&sdhc_1 {
+ qcom,pad-pull-on = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
+ qcom,pad-pull-off = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
+};
diff --git a/arch/arm/boot/dts/msm8974pro-ab-pm8941-liquid.dts b/arch/arm/boot/dts/msm8974pro-ab-pm8941-liquid.dts
index 49c3df0..0192f56 100644
--- a/arch/arm/boot/dts/msm8974pro-ab-pm8941-liquid.dts
+++ b/arch/arm/boot/dts/msm8974pro-ab-pm8941-liquid.dts
@@ -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
@@ -20,3 +20,8 @@
compatible = "qcom,msm8974-liquid", "qcom,msm8974", "qcom,liquid";
qcom,board-id = <9 0>;
};
+
+&sdhc_1 {
+ qcom,pad-pull-on = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
+ qcom,pad-pull-off = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
+};
diff --git a/arch/arm/boot/dts/msm8974pro-ab-pm8941-mtp.dts b/arch/arm/boot/dts/msm8974pro-ab-pm8941-mtp.dts
index d4bb37b..f80551e 100644
--- a/arch/arm/boot/dts/msm8974pro-ab-pm8941-mtp.dts
+++ b/arch/arm/boot/dts/msm8974pro-ab-pm8941-mtp.dts
@@ -22,5 +22,7 @@
};
&sdhc_1 {
+ qcom,pad-pull-on = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
+ qcom,pad-pull-off = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
qcom,pad-drv-on = <0x4 0x4 0x4>; /* 10mA, 10mA, 10mA */
};
diff --git a/arch/arm/boot/dts/msm8974pro-ac-pm8941-cdp.dts b/arch/arm/boot/dts/msm8974pro-ac-pm8941-cdp.dts
index 3e0feda..08ef393 100644
--- a/arch/arm/boot/dts/msm8974pro-ac-pm8941-cdp.dts
+++ b/arch/arm/boot/dts/msm8974pro-ac-pm8941-cdp.dts
@@ -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
@@ -20,3 +20,8 @@
compatible = "qcom,msm8974-cdp", "qcom,msm8974", "qcom,cdp";
qcom,board-id = <1 0>;
};
+
+&sdhc_1 {
+ qcom,pad-pull-on = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
+ qcom,pad-pull-off = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
+};
diff --git a/arch/arm/boot/dts/msm8974pro-ac-pm8941-liquid.dts b/arch/arm/boot/dts/msm8974pro-ac-pm8941-liquid.dts
index 7b88abe..8118e48 100644
--- a/arch/arm/boot/dts/msm8974pro-ac-pm8941-liquid.dts
+++ b/arch/arm/boot/dts/msm8974pro-ac-pm8941-liquid.dts
@@ -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
@@ -20,3 +20,8 @@
compatible = "qcom,msm8974-liquid", "qcom,msm8974", "qcom,liquid";
qcom,board-id = <9 0>;
};
+
+&sdhc_1 {
+ qcom,pad-pull-on = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
+ qcom,pad-pull-off = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
+};
diff --git a/arch/arm/boot/dts/msm8974pro-ac-pm8941-mtp.dts b/arch/arm/boot/dts/msm8974pro-ac-pm8941-mtp.dts
index f79d361..76d0121 100644
--- a/arch/arm/boot/dts/msm8974pro-ac-pm8941-mtp.dts
+++ b/arch/arm/boot/dts/msm8974pro-ac-pm8941-mtp.dts
@@ -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
@@ -22,9 +22,6 @@
};
&sdhc_1 {
- qcom,clk-rates = <400000 20000000 25000000 50000000 100000000 192000000 384000000>;
- qcom,bus-speed-mode = "HS400_1p8v", "HS200_1p8v", "DDR_1p8v";
-
qcom,pad-pull-on = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
qcom,pad-pull-off = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
};
diff --git a/arch/arm/boot/dts/msm8974pro-ac-pm8941.dtsi b/arch/arm/boot/dts/msm8974pro-ac-pm8941.dtsi
index cdcfecb..694049a 100644
--- a/arch/arm/boot/dts/msm8974pro-ac-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm8974pro-ac-pm8941.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
@@ -18,7 +18,3 @@
<213 0x10000>,
<216 0x10000>;
};
-
-&sdhc_1 {
- reg = <0xf9824900 0x1a0>, <0xf9824000 0x800>;
-};
diff --git a/arch/arm/boot/dts/msm8974pro-ac-pma8084-pm8941.dtsi b/arch/arm/boot/dts/msm8974pro-ac-pma8084-pm8941.dtsi
index dc438bb..bc7ecd2 100644
--- a/arch/arm/boot/dts/msm8974pro-ac-pma8084-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm8974pro-ac-pma8084-pm8941.dtsi
@@ -102,6 +102,7 @@
vbus_dwc3-supply = <&pm8941_mvs1>;
qcom,misc-ref = <&pm8941_misc>;
dwc_usb3-adc_tm = <&pm8941_adc_tm>;
+ qcom,usbin-vadc = <&pm8941_vadc>;
interrupt-map-mask = <0x0 0xffffffff>;
interrupt-map = <0x0 0 &intc 0 133 0
0x0 1 &spmi_bus 0x0 0x2 0x9 0x0>;
diff --git a/arch/arm/boot/dts/msm8974pro-ac-pma8084.dtsi b/arch/arm/boot/dts/msm8974pro-ac-pma8084.dtsi
index 4b7ed1d..46fae99 100644
--- a/arch/arm/boot/dts/msm8974pro-ac-pma8084.dtsi
+++ b/arch/arm/boot/dts/msm8974pro-ac-pma8084.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
@@ -18,7 +18,3 @@
<213 0x10000>,
<216 0x10000>;
};
-
-&sdhc_1 {
- reg = <0xf9824900 0x1a0>, <0xf9824000 0x800>;
-};
diff --git a/arch/arm/boot/dts/msm8974pro-pm.dtsi b/arch/arm/boot/dts/msm8974pro-pm.dtsi
index a1e981e..34ae372 100644
--- a/arch/arm/boot/dts/msm8974pro-pm.dtsi
+++ b/arch/arm/boot/dts/msm8974pro-pm.dtsi
@@ -174,11 +174,11 @@
qcom,system-mode@0 {
qcom,l2 = "l2_cache_gdhs";
- qcom,latency-us = <20000>;
+ qcom,latency-us = <500>;
qcom,ss-power = <163>;
- qcom,energy-overhead = <1577736>;
- qcom,time-overhead = <5067>;
- qcom,min-cpu-mode= "pc";
+ qcom,energy-overhead = <577736>;
+ qcom,time-overhead = <1000>;
+ qcom,min-cpu-mode= "standalone_pc";
qcom,sync-cpus;
};
@@ -190,6 +190,7 @@
qcom,time-overhead = <6605>;
qcom,min-cpu-mode = "pc";
qcom,sync-cpus;
+ qcom,send-rpm-sleep-set;
};
};
};
diff --git a/arch/arm/boot/dts/msm8974pro-pm8941.dtsi b/arch/arm/boot/dts/msm8974pro-pm8941.dtsi
index 8b13c9f..decd444 100644
--- a/arch/arm/boot/dts/msm8974pro-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm8974pro-pm8941.dtsi
@@ -64,6 +64,10 @@
qcom,init-smps-mode = <0>; /* Allow AUTO mode for VDD_CX. */
};
+&usb3 {
+ qcom,usbin-vadc = <&pm8941_vadc>;
+};
+
&krait_regulator_pmic {
status = "ok";
diff --git a/arch/arm/boot/dts/msm8974pro-pma8084-mtp.dtsi b/arch/arm/boot/dts/msm8974pro-pma8084-mtp.dtsi
old mode 100755
new mode 100644
index a22d806..680674d
--- a/arch/arm/boot/dts/msm8974pro-pma8084-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8974pro-pma8084-mtp.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
@@ -42,6 +42,37 @@
cam_vana-supply = <&pma8084_l17>;
cam_vio-supply = <&pma8084_lvs4>;
};
+
+
+ qcom,camera@0 {
+ qcom,vdd-cx-supply = <&pma8084_s2>;
+ cam_vdig-supply = <&pma8084_l3>;
+ cam_vana-supply = <&pma8084_l17>;
+ cam_vio-supply = <&pma8084_lvs4>;
+ cam_vaf-supply = <&pma8084_l23>;
+ };
+
+ qcom,camera@1 {
+ qcom,vdd-cx-supply = <&pma8084_s2>;
+ cam_vdig-supply = <&pma8084_l3>;
+ cam_vana-supply = <&pma8084_l17>;
+ cam_vio-supply = <&pma8084_lvs4>;
+ cam_vaf-supply = <&pma8084_l23>;
+ };
+
+ qcom,camera@2 {
+ qcom,vdd-cx-supply = <&pma8084_s2>;
+ cam_vdig-supply = <&pma8084_l3>;
+ cam_vana-supply = <&pma8084_l17>;
+ cam_vio-supply = <&pma8084_lvs4>;
+ };
+
+ qcom,camera@3 {
+ qcom,vdd-cx-supply = <&pma8084_s2>;
+ cam_vdig-supply = <&pma8084_l3>;
+ cam_vana-supply = <&pma8084_l17>;
+ cam_vio-supply = <&pma8084_lvs4>;
+ };
};
&soc {
@@ -106,9 +137,6 @@
vdd-supply = <&pma8084_l20>;
vdd-io-supply = <&pma8084_s4>;
- qcom,clk-rates = <400000 20000000 25000000 50000000 100000000 192000000 384000000>;
- qcom,bus-speed-mode = "HS400_1p8v", "HS200_1p8v", "DDR_1p8v";
-
qcom,pad-pull-on = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
qcom,pad-pull-off = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
};
diff --git a/arch/arm/boot/dts/msm8974pro.dtsi b/arch/arm/boot/dts/msm8974pro.dtsi
old mode 100755
new mode 100644
index f9cdb6e..a72ebb2
--- a/arch/arm/boot/dts/msm8974pro.dtsi
+++ b/arch/arm/boot/dts/msm8974pro.dtsi
@@ -1755,3 +1755,10 @@
&gdsc_venus {
qcom,skip-logic-collapse;
};
+
+&sdhc_1 {
+ reg = <0xf9824900 0x1a0>, <0xf9824000 0x800>;
+
+ qcom,clk-rates = <400000 20000000 25000000 50000000 100000000 192000000 384000000>;
+ qcom,bus-speed-mode = "HS400_1p8v", "HS200_1p8v", "DDR_1p8v";
+};
diff --git a/arch/arm/boot/dts/msmsamarium-camera-sensor-cdp-interposer.dtsi b/arch/arm/boot/dts/msmsamarium-camera-sensor-cdp-interposer.dtsi
new file mode 100644
index 0000000..81640f8
--- /dev/null
+++ b/arch/arm/boot/dts/msmsamarium-camera-sensor-cdp-interposer.dtsi
@@ -0,0 +1,171 @@
+/*
+ * 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+&cci {
+ actuator0: qcom,actuator@18 {
+ cell-index = <0>;
+ reg = <0x18>;
+ compatible = "qcom,actuator";
+ qcom,cci-master = <0>;
+ };
+
+ actuator1: qcom,actuator@36 {
+ cell-index = <1>;
+ reg = <0x36>;
+ compatible = "qcom,actuator";
+ qcom,cci-master = <0>;
+ };
+
+ qcom,camera@20 {
+ compatible = "qcom,imx135";
+ reg = <0x20>;
+ qcom,slave-id = <0x20 0x0016 0x0135>;
+ qcom,csiphy-sd-index = <0>;
+ qcom,csid-sd-index = <0>;
+ qcom,mount-angle = <90>;
+ qcom,sensor-name = "imx135";
+ qcom,vdd-cx-supply = <&pma8084_s2>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
+ cam_vdig-supply = <&pma8084_l27>;
+ cam_vana-supply = <&pma8084_l17>;
+ cam_vio-supply = <&pma8084_lvs4>;
+ cam_vaf-supply = <&pma8084_l23>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-type = <0 1 0 0>;
+ qcom,cam-vreg-min-voltage = <1050000 0 2850000 2850000>;
+ qcom,cam-vreg-max-voltage = <1050000 0 2850000 2850000>;
+ qcom,cam-vreg-op-mode = <135000 0 44000 124000>;
+ qcom,gpio-no-mux = <0>;
+ gpios = <&msmgpio 15 0>,
+ <&msmgpio 81 0>,
+ <&msmgpio 80 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET1",
+ "CAM_STANDBY";
+ qcom,gpio-set-tbl-num = <1 1>;
+ qcom,gpio-set-tbl-flags = <0 2>;
+ qcom,gpio-set-tbl-delay = <1000 30000>;
+ qcom,csi-lane-assign = <0x4320>;
+ qcom,csi-lane-mask = <0x1F>;
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
+ qcom,sensor-type = <0>;
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
+
+ qcom,camera@6d {
+ compatible = "qcom,imx132";
+ reg = <0x6d>;
+ qcom,slave-id = <0x6c 0x0 0x0132>;
+ qcom,csiphy-sd-index = <1>;
+ qcom,csid-sd-index = <1>;
+ qcom,mount-angle = <270>;
+ qcom,sensor-name = "imx132";
+ qcom,vdd-cx-supply = <&pma8084_s2>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
+ cam_vdig-supply = <&pma8084_l3>;
+ cam_vana-supply = <&pma8084_l17>;
+ cam_vio-supply = <&pma8084_lvs4>;
+ qcom,cam-vreg-name = "cam_vana", "cam_vdig", "cam_vio";
+ qcom,cam-vreg-type = <0 0 1>;
+ qcom,cam-vreg-min-voltage = <2850000 1200000 0>;
+ qcom,cam-vreg-max-voltage = <2850000 1200000 0>;
+ qcom,cam-vreg-op-mode = <44000 98000 0>;
+ qcom,gpio-no-mux = <0>;
+ gpios = <&msmgpio 16 0>,
+ <&msmgpio 18 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-req-tbl-num = <0 1>;
+ qcom,gpio-req-tbl-flags = <1 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
+ "CAM_XSHUTDOWN";
+ qcom,gpio-set-tbl-num = <1 1>;
+ qcom,gpio-set-tbl-flags = <0 2>;
+ qcom,gpio-set-tbl-delay = <1000 4000>;
+ qcom,csi-lane-assign = <0x4320>;
+ qcom,csi-lane-mask = <0x7>;
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <1>;
+ qcom,cci-master = <0>;
+ };
+
+ qcom,camera@0 {
+ cell-index = <0>;
+ compatible = "qcom,camera";
+ reg = <0x00>;
+ qcom,csiphy-sd-index = <0>;
+ qcom,csid-sd-index = <0>;
+ qcom,mount-angle = <90>;
+ qcom,vdd-cx-supply = <&pma8084_s2>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
+ cam_vdig-supply = <&pma8084_l27>;
+ cam_vana-supply = <&pma8084_l17>;
+ cam_vio-supply = <&pma8084_lvs4>;
+ cam_vaf-supply = <&pma8084_l23>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-type = <0 1 0 0>;
+ qcom,cam-vreg-min-voltage = <1050000 0 2850000 2850000>;
+ qcom,cam-vreg-max-voltage = <1050000 0 2850000 2850000>;
+ qcom,cam-vreg-op-mode = <135000 0 44000 124000>;
+ qcom,gpio-no-mux = <0>;
+ gpios = <&msmgpio 15 0>,
+ <&msmgpio 81 0>,
+ <&msmgpio 80 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET1",
+ "CAM_STANDBY";
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
+
+ qcom,camera@1 {
+ cell-index = <0>;
+ compatible = "qcom,camera";
+ reg = <0x01>;
+ qcom,slave-id = <0x6c 0x0 0x0132>;
+ qcom,csiphy-sd-index = <1>;
+ qcom,csid-sd-index = <1>;
+ qcom,mount-angle = <270>;
+ qcom,vdd-cx-supply = <&pma8084_s2>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
+ cam_vdig-supply = <&pma8084_l3>;
+ cam_vana-supply = <&pma8084_l17>;
+ cam_vio-supply = <&pma8084_lvs4>;
+ qcom,cam-vreg-name = "cam_vana", "cam_vdig", "cam_vio";
+ qcom,cam-vreg-type = <0 0 1>;
+ qcom,cam-vreg-min-voltage = <2850000 1200000 0>;
+ qcom,cam-vreg-max-voltage = <2850000 1200000 0>;
+ qcom,cam-vreg-op-mode = <44000 98000 0>;
+ qcom,gpio-no-mux = <0>;
+ gpios = <&msmgpio 16 0>,
+ <&msmgpio 18 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-req-tbl-num = <0 1>;
+ qcom,gpio-req-tbl-flags = <1 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
+ "CAM_XSHUTDOWN";
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
+};
diff --git a/arch/arm/boot/dts/msmsamarium-camera-sensor-cdp.dtsi b/arch/arm/boot/dts/msmsamarium-camera-sensor-cdp.dtsi
new file mode 100644
index 0000000..27f4a99
--- /dev/null
+++ b/arch/arm/boot/dts/msmsamarium-camera-sensor-cdp.dtsi
@@ -0,0 +1,172 @@
+/*
+ * 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+&cci {
+
+ actuator0: qcom,actuator@18 {
+ cell-index = <0>;
+ reg = <0x18>;
+ compatible = "qcom,actuator";
+ qcom,cci-master = <0>;
+ };
+
+ actuator1: qcom,actuator@36 {
+ cell-index = <1>;
+ reg = <0x36>;
+ compatible = "qcom,actuator";
+ qcom,cci-master = <0>;
+ };
+
+ qcom,camera@20 {
+ compatible = "qcom,imx135";
+ reg = <0x20>;
+ qcom,slave-id = <0x20 0x0016 0x0135>;
+ qcom,csiphy-sd-index = <0>;
+ qcom,csid-sd-index = <0>;
+ qcom,mount-angle = <90>;
+ qcom,sensor-name = "imx135";
+ qcom,vdd-cx-supply = <&pma8084_s2_corner>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
+ cam_vdig-supply = <&pma8084_l27>;
+ cam_vana-supply = <&pma8084_l17>;
+ cam_vio-supply = <&pma8084_lvs4>;
+ cam_vaf-supply = <&pma8084_l23>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-type = <0 1 0 0>;
+ qcom,cam-vreg-min-voltage = <1050000 0 2850000 2850000>;
+ qcom,cam-vreg-max-voltage = <1050000 0 2850000 2850000>;
+ qcom,cam-vreg-op-mode = <135000 0 44000 124000>;
+ qcom,gpio-no-mux = <0>;
+ gpios = <&msmgpio 15 0>,
+ <&msmgpio 30 0>,
+ <&msmgpio 29 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET1",
+ "CAM_STANDBY";
+ qcom,gpio-set-tbl-num = <1 1>;
+ qcom,gpio-set-tbl-flags = <0 2>;
+ qcom,gpio-set-tbl-delay = <1000 30000>;
+ qcom,csi-lane-assign = <0x4320>;
+ qcom,csi-lane-mask = <0x1F>;
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
+ qcom,sensor-type = <0>;
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
+
+ qcom,camera@6d {
+ compatible = "qcom,imx132";
+ reg = <0x6d>;
+ qcom,slave-id = <0x6c 0x0 0x0132>;
+ qcom,csiphy-sd-index = <1>;
+ qcom,csid-sd-index = <1>;
+ qcom,mount-angle = <270>;
+ qcom,sensor-name = "imx132";
+ qcom,vdd-cx-supply = <&pma8084_s2_corner>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
+ cam_vdig-supply = <&pma8084_l3>;
+ cam_vana-supply = <&pma8084_l17>;
+ cam_vio-supply = <&pma8084_lvs4>;
+ qcom,cam-vreg-name = "cam_vana", "cam_vdig", "cam_vio";
+ qcom,cam-vreg-type = <0 0 1>;
+ qcom,cam-vreg-min-voltage = <2850000 1200000 0>;
+ qcom,cam-vreg-max-voltage = <2850000 1200000 0>;
+ qcom,cam-vreg-op-mode = <44000 98000 0>;
+ qcom,gpio-no-mux = <0>;
+ gpios = <&msmgpio 16 0>,
+ <&msmgpio 18 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-req-tbl-num = <0 1>;
+ qcom,gpio-req-tbl-flags = <1 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
+ "CAM_XSHUTDOWN";
+ qcom,gpio-set-tbl-num = <1 1>;
+ qcom,gpio-set-tbl-flags = <0 2>;
+ qcom,gpio-set-tbl-delay = <1000 4000>;
+ qcom,csi-lane-assign = <0x4320>;
+ qcom,csi-lane-mask = <0x7>;
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <1>;
+ qcom,cci-master = <0>;
+ };
+
+ qcom,camera@0 {
+ cell-index = <0>;
+ compatible = "qcom,camera";
+ reg = <0x00>;
+ qcom,csiphy-sd-index = <0>;
+ qcom,csid-sd-index = <0>;
+ qcom,mount-angle = <90>;
+ qcom,vdd-cx-supply = <&pma8084_s2_corner>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
+ cam_vdig-supply = <&pma8084_l27>;
+ cam_vana-supply = <&pma8084_l17>;
+ cam_vio-supply = <&pma8084_lvs4>;
+ cam_vaf-supply = <&pma8084_l23>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-type = <0 1 0 0>;
+ qcom,cam-vreg-min-voltage = <1050000 0 2850000 2850000>;
+ qcom,cam-vreg-max-voltage = <1050000 0 2850000 2850000>;
+ qcom,cam-vreg-op-mode = <135000 0 44000 124000>;
+ qcom,gpio-no-mux = <0>;
+ gpios = <&msmgpio 15 0>,
+ <&msmgpio 30 0>,
+ <&msmgpio 29 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET1",
+ "CAM_STANDBY";
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
+
+ qcom,camera@1 {
+ cell-index = <1>;
+ compatible = "qcom,camera";
+ reg = <0x01>;
+ qcom,csiphy-sd-index = <1>;
+ qcom,csid-sd-index = <1>;
+ qcom,mount-angle = <270>;
+ qcom,vdd-cx-supply = <&pma8084_s2_corner>;
+ qcom,vdd-cx-name = "qcom,vdd-cx";
+ cam_vdig-supply = <&pma8084_l3>;
+ cam_vana-supply = <&pma8084_l17>;
+ cam_vio-supply = <&pma8084_lvs4>;
+ qcom,cam-vreg-name = "cam_vana", "cam_vdig", "cam_vio";
+ qcom,cam-vreg-type = <0 0 1>;
+ qcom,cam-vreg-min-voltage = <2850000 1200000 0>;
+ qcom,cam-vreg-max-voltage = <2850000 1200000 0>;
+ qcom,cam-vreg-op-mode = <44000 98000 0>;
+ qcom,gpio-no-mux = <0>;
+ gpios = <&msmgpio 16 0>,
+ <&msmgpio 18 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-req-tbl-num = <0 1>;
+ qcom,gpio-req-tbl-flags = <1 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
+ "CAM_XSHUTDOWN";
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
+};
+
diff --git a/arch/arm/mach-msm/clock-8226.c b/arch/arm/mach-msm/clock-8226.c
index 1336ec3..798a33d 100644
--- a/arch/arm/mach-msm/clock-8226.c
+++ b/arch/arm/mach-msm/clock-8226.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
@@ -2846,6 +2846,8 @@
F_APCS_PLL(1401600000, 73, 0x0, 0x1, 0x0, 0x0, 0x0),
F_APCS_PLL(1497600000, 78, 0x0, 0x1, 0x0, 0x0, 0x0),
F_APCS_PLL(1593600000, 83, 0x0, 0x1, 0x0, 0x0, 0x0),
+ F_APCS_PLL(1689600000, 88, 0x0, 0x1, 0x0, 0x0, 0x0),
+ F_APCS_PLL(1785600000, 93, 0x0, 0x1, 0x0, 0x0, 0x0),
PLL_F_END
};
@@ -3426,6 +3428,10 @@
CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "6a.qcom,camera"),
CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "6c.qcom,camera"),
CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "20.qcom,camera"),
+ CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "0.qcom,camera"),
+ CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "1.qcom,camera"),
+ CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "0.qcom,camera"),
+ CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "1.qcom,camera"),
/* eeprom clocks */
CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "6c.qcom,eeprom"),
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 d51e6f7..acfbfc7 100755
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-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
@@ -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),
@@ -4891,6 +4887,12 @@
CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "20.qcom,camera"),
CLK_LOOKUP("cam_clk", camss_mclk2_clk.c, "6c.qcom,camera"),
CLK_LOOKUP("cam_clk", camss_mclk1_clk.c, "90.qcom,camera"),
+ CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "0.qcom,camera"),
+ CLK_LOOKUP("cam_src_clk", mclk1_clk_src.c, "1.qcom,camera"),
+ CLK_LOOKUP("cam_src_clk", mclk2_clk_src.c, "2.qcom,camera"),
+ CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "0.qcom,camera"),
+ CLK_LOOKUP("cam_clk", camss_mclk1_clk.c, "1.qcom,camera"),
+ CLK_LOOKUP("cam_clk", camss_mclk2_clk.c, "2.qcom,camera"),
};
static struct clk_lookup msm_clocks_8974_only[] __initdata = {
@@ -4902,6 +4904,12 @@
CLK_LOOKUP("cam_clk", camss_gp0_clk.c, "20.qcom,camera"),
CLK_LOOKUP("cam_clk", gcc_gp1_clk.c, "6c.qcom,camera"),
CLK_LOOKUP("cam_clk", camss_gp1_clk.c, "90.qcom,camera"),
+ CLK_LOOKUP("cam_src_clk", mmss_gp0_clk_src.c, "0.qcom,camera"),
+ CLK_LOOKUP("cam_src_clk", gp1_clk_src.c, "2.qcom,camera"),
+ CLK_LOOKUP("cam_src_clk", mmss_gp1_clk_src.c, "1.qcom,camera"),
+ CLK_LOOKUP("cam_clk", camss_gp0_clk.c, "0.qcom,camera"),
+ CLK_LOOKUP("cam_clk", gcc_gp1_clk.c, "2.qcom,camera"),
+ CLK_LOOKUP("cam_clk", camss_gp1_clk.c, "1.qcom,camera"),
};
static struct clk_lookup msm_clocks_8974_common[] __initdata = {
@@ -5778,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/clock-samarium.c b/arch/arm/mach-msm/clock-samarium.c
new file mode 100644
index 0000000..4c5c0c7
--- /dev/null
+++ b/arch/arm/mach-msm/clock-samarium.c
@@ -0,0 +1,3919 @@
+/* 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/ctype.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/iopoll.h>
+#include <linux/regulator/consumer.h>
+
+#include <mach/rpm-regulator-smd.h>
+#include <mach/rpm-smd.h>
+#include <mach/clock-generic.h>
+
+#include "clock-local2.h"
+#include "clock-pll.h"
+#include "clock-rpm.h"
+#include "clock-voter.h"
+#include "clock.h"
+#include "clock-krait.h"
+#include "clock-mdss-8974.h"
+
+enum {
+ GCC_BASE,
+ MMSS_BASE,
+ LPASS_BASE,
+ APCS_BASE,
+ N_BASES,
+};
+
+static void __iomem *virt_bases[N_BASES];
+
+#define GCC_REG_BASE(x) (void __iomem *)(virt_bases[GCC_BASE] + (x))
+#define MMSS_REG_BASE(x) (void __iomem *)(virt_bases[MMSS_BASE] + (x))
+#define LPASS_REG_BASE(x) (void __iomem *)(virt_bases[LPASS_BASE] + (x))
+#define APCS_REG_BASE(x) (void __iomem *)(virt_bases[APCS_BASE] + (x))
+
+#define xo_source_val 0
+#define gpll0_source_val 1
+#define gpll4_source_val 5
+#define xo_mm_source_val 0
+#define mmpll0_mm_source_val 1
+#define mmpll1_mm_source_val 2
+#define mmpll3_mm_source_val 3
+#define mmpll4_mm_source_val 3
+#define gpll0_mm_source_val 5
+#define dsipll0_pixel_mm_source_val 1
+#define dsipll0_byte_mm_source_val 1
+
+#define FIXDIV(div) (div ? (2 * (div) - 1) : (0))
+
+#define F(f, s, div, m, n) \
+ { \
+ .freq_hz = (f), \
+ .src_clk = &s.c, \
+ .m_val = (m), \
+ .n_val = ~((n)-(m)) * !!(n), \
+ .d_val = ~(n),\
+ .div_src_val = BVAL(4, 0, (int)(2*(div) - 1)) \
+ | BVAL(10, 8, s##_source_val), \
+ }
+
+#define F_MM(f, s, div, m, n) \
+ { \
+ .freq_hz = (f), \
+ .src_clk = &s.c, \
+ .m_val = (m), \
+ .n_val = ~((n)-(m)) * !!(n), \
+ .d_val = ~(n),\
+ .div_src_val = BVAL(4, 0, (int)(2*(div) - 1)) \
+ | BVAL(10, 8, s##_mm_source_val), \
+ }
+
+#define VDD_DIG_FMAX_MAP1(l1, f1) \
+ .vdd_class = &vdd_dig, \
+ .fmax = (unsigned long[VDD_DIG_NUM]) { \
+ [VDD_DIG_##l1] = (f1), \
+ }, \
+ .num_fmax = VDD_DIG_NUM
+#define VDD_DIG_FMAX_MAP2(l1, f1, l2, f2) \
+ .vdd_class = &vdd_dig, \
+ .fmax = (unsigned long[VDD_DIG_NUM]) { \
+ [VDD_DIG_##l1] = (f1), \
+ [VDD_DIG_##l2] = (f2), \
+ }, \
+ .num_fmax = VDD_DIG_NUM
+#define VDD_DIG_FMAX_MAP3(l1, f1, l2, f2, l3, f3) \
+ .vdd_class = &vdd_dig, \
+ .fmax = (unsigned long[VDD_DIG_NUM]) { \
+ [VDD_DIG_##l1] = (f1), \
+ [VDD_DIG_##l2] = (f2), \
+ [VDD_DIG_##l3] = (f3), \
+ }, \
+ .num_fmax = VDD_DIG_NUM
+
+enum vdd_dig_levels {
+ VDD_DIG_NONE,
+ VDD_DIG_LOW,
+ VDD_DIG_NOMINAL,
+ VDD_DIG_HIGH,
+ VDD_DIG_NUM
+};
+
+static int vdd_corner[] = {
+ RPM_REGULATOR_CORNER_NONE, /* VDD_DIG_NONE */
+ RPM_REGULATOR_CORNER_SVS_SOC, /* VDD_DIG_LOW */
+ RPM_REGULATOR_CORNER_NORMAL, /* VDD_DIG_NOMINAL */
+ RPM_REGULATOR_CORNER_SUPER_TURBO, /* VDD_DIG_HIGH */
+};
+
+static DEFINE_VDD_REGULATORS(vdd_dig, VDD_DIG_NUM, 1, vdd_corner, NULL);
+
+#define RPM_MISC_CLK_TYPE 0x306b6c63
+#define RPM_BUS_CLK_TYPE 0x316b6c63
+#define RPM_MEM_CLK_TYPE 0x326b6c63
+
+#define CXO_ID 0x0
+#define QDSS_ID 0x1
+#define PNOC_ID 0x0
+#define SNOC_ID 0x1
+#define CNOC_ID 0x2
+#define BIMC_ID 0x0
+#define OCMEM_ID 0x2
+#define OXILI_ID 0x1
+#define MMSSNOC_AHB_ID 0x3
+
+#define BB_CLK1_ID 1
+#define BB_CLK2_ID 2
+#define RF_CLK1_ID 4
+#define RF_CLK2_ID 5
+#define RF_CLK3_ID 6
+#define DIFF_CLK1_ID 7
+#define DIV_CLK1_ID 11
+#define DIV_CLK2_ID 12
+#define DIV_CLK3_ID 13
+
+#define GPLL0_STATUS (0x001C)
+#define GPLL4_STATUS (0x1DDC)
+#define MSS_CFG_AHB_CBCR (0x0280)
+#define MSS_Q6_BIMC_AXI_CBCR (0x0284)
+#define USB_HS_BCR (0x0480)
+#define USB_HS_SYSTEM_CBCR (0x0484)
+#define USB_HS_AHB_CBCR (0x0488)
+#define USB_HS_SYSTEM_CMD_RCGR (0x0490)
+#define USB2A_PHY_SLEEP_CBCR (0x04AC)
+#define SDCC1_APPS_CMD_RCGR (0x04D0)
+#define SDCC1_APPS_CBCR (0x04C4)
+#define SDCC1_AHB_CBCR (0x04C8)
+#define SDCC1_CDCCAL_SLEEP_CBCR (0x04E4)
+#define SDCC1_CDCCAL_FF_CBCR (0x04E8)
+#define SDCC2_APPS_CMD_RCGR (0x0510)
+#define SDCC2_APPS_CBCR (0x0504)
+#define SDCC2_AHB_CBCR (0x0508)
+#define SDCC3_APPS_CMD_RCGR (0x0550)
+#define SDCC3_APPS_CBCR (0x0544)
+#define SDCC3_AHB_CBCR (0x0548)
+#define SDCC4_APPS_CMD_RCGR (0x0590)
+#define SDCC4_APPS_CBCR (0x0584)
+#define SDCC4_AHB_CBCR (0x0588)
+#define BLSP1_AHB_CBCR (0x05C4)
+#define BLSP1_QUP1_SPI_APPS_CBCR (0x0644)
+#define BLSP1_QUP1_I2C_APPS_CBCR (0x0648)
+#define BLSP1_QUP1_I2C_APPS_CMD_RCGR (0x0660)
+#define BLSP1_QUP2_I2C_APPS_CMD_RCGR (0x06E0)
+#define BLSP1_QUP3_I2C_APPS_CMD_RCGR (0x0760)
+#define BLSP1_QUP4_I2C_APPS_CMD_RCGR (0x07E0)
+#define BLSP2_QUP1_I2C_APPS_CMD_RCGR (0x09A0)
+#define BLSP2_QUP2_I2C_APPS_CMD_RCGR (0x0A20)
+#define BLSP2_QUP3_I2C_APPS_CMD_RCGR (0x0AA0)
+#define BLSP2_QUP4_I2C_APPS_CMD_RCGR (0x0B20)
+#define BLSP1_QUP1_SPI_APPS_CMD_RCGR (0x064C)
+#define BLSP1_UART1_APPS_CBCR (0x0684)
+#define BLSP1_UART1_APPS_CMD_RCGR (0x068C)
+#define BLSP1_QUP2_SPI_APPS_CBCR (0x06C4)
+#define BLSP1_QUP2_I2C_APPS_CBCR (0x06C8)
+#define BLSP1_QUP2_SPI_APPS_CMD_RCGR (0x06CC)
+#define BLSP1_UART2_APPS_CBCR (0x0704)
+#define BLSP1_UART2_APPS_CMD_RCGR (0x070C)
+#define BLSP1_QUP3_SPI_APPS_CBCR (0x0744)
+#define BLSP1_QUP3_I2C_APPS_CBCR (0x0748)
+#define BLSP1_QUP3_SPI_APPS_CMD_RCGR (0x074C)
+#define BLSP1_UART3_APPS_CBCR (0x0784)
+#define BLSP1_UART3_APPS_CMD_RCGR (0x078C)
+#define BLSP1_QUP4_SPI_APPS_CBCR (0x07C4)
+#define BLSP1_QUP4_I2C_APPS_CBCR (0x07C8)
+#define BLSP1_QUP4_SPI_APPS_CMD_RCGR (0x07CC)
+#define BLSP1_UART4_APPS_CBCR (0x0804)
+#define BLSP1_UART4_APPS_CMD_RCGR (0x080C)
+#define BLSP2_AHB_CBCR (0x0944)
+#define BLSP2_QUP1_SPI_APPS_CBCR (0x0984)
+#define BLSP2_QUP1_I2C_APPS_CBCR (0x0988)
+#define BLSP2_QUP1_SPI_APPS_CMD_RCGR (0x098C)
+#define BLSP2_UART1_APPS_CBCR (0x09C4)
+#define BLSP2_UART1_APPS_CMD_RCGR (0x09CC)
+#define BLSP2_QUP2_SPI_APPS_CBCR (0x0A04)
+#define BLSP2_QUP2_I2C_APPS_CBCR (0x0A08)
+#define BLSP2_QUP2_SPI_APPS_CMD_RCGR (0x0A0C)
+#define BLSP2_UART2_APPS_CBCR (0x0A44)
+#define BLSP2_UART2_APPS_CMD_RCGR (0x0A4C)
+#define BLSP2_QUP3_SPI_APPS_CBCR (0x0A84)
+#define BLSP2_QUP3_I2C_APPS_CBCR (0x0A88)
+#define BLSP2_QUP3_SPI_APPS_CMD_RCGR (0x0A8C)
+#define BLSP2_UART3_APPS_CBCR (0x0AC4)
+#define BLSP2_UART3_APPS_CMD_RCGR (0x0ACC)
+#define BLSP2_QUP4_SPI_APPS_CBCR (0x0B04)
+#define BLSP2_QUP4_I2C_APPS_CBCR (0x0B08)
+#define BLSP2_QUP4_SPI_APPS_CMD_RCGR (0x0B0C)
+#define BLSP2_UART4_APPS_CBCR (0x0B44)
+#define BLSP2_UART4_APPS_CMD_RCGR (0x0B4C)
+#define PDM_AHB_CBCR (0x0CC4)
+#define PDM2_CBCR (0x0CCC)
+#define PDM2_CMD_RCGR (0x0CD0)
+#define PRNG_AHB_CBCR (0x0D04)
+#define BAM_DMA_AHB_CBCR (0x0D44)
+#define TSIF_AHB_CBCR (0x0D84)
+#define TSIF_REF_CBCR (0x0D88)
+#define TSIF_REF_CMD_RCGR (0x0D90)
+#define BOOT_ROM_AHB_CBCR (0x0E04)
+#define RPM_MISC (0x0F24)
+#define CE1_CMD_RCGR (0x1050)
+#define CE1_CBCR (0x1044)
+#define CE1_AXI_CBCR (0x1048)
+#define CE1_AHB_CBCR (0x104C)
+#define GCC_XO_DIV4_CBCR (0x10C8)
+#define LPASS_Q6_AXI_CBCR (0x11C0)
+#define LPASS_SYS_NOC_MPORT_CBCR (0x11C4)
+#define LPASS_SYS_NOC_SWAY_CBCR (0x11C8)
+#define APCS_GPLL_ENA_VOTE (0x1480)
+#define APCS_CLOCK_BRANCH_ENA_VOTE (0x1484)
+#define GCC_DEBUG_CLK_CTL (0x1880)
+#define CLOCK_FRQ_MEASURE_CTL (0x1884)
+#define CLOCK_FRQ_MEASURE_STATUS (0x1888)
+#define PLLTEST_PAD_CFG (0x188C)
+#define GP1_CBCR (0x1900)
+#define GP1_CMD_RCGR (0x1904)
+#define GLB_CLK_DIAG (0x001C)
+#define SLEEP_CBCR (0x0038)
+#define L2_CBCR (0x004C)
+#define MMPLL0_MODE (0x0000)
+#define MMPLL0_L_VAL (0x0004)
+#define MMPLL0_M_VAL (0x0008)
+#define MMPLL0_N_VAL (0x000C)
+#define MMPLL0_USER_CTL (0x0010)
+#define MMPLL0_STATUS (0x001C)
+#define MMPLL1_MODE (0x0040)
+#define MMPLL1_L_VAL (0x0044)
+#define MMPLL1_M_VAL (0x0048)
+#define MMPLL1_N_VAL (0x004C)
+#define MMPLL1_USER_CTL (0x0050)
+#define MMPLL1_STATUS (0x005C)
+#define MMPLL3_MODE (0x0080)
+#define MMPLL3_L_VAL (0x0084)
+#define MMPLL3_M_VAL (0x0088)
+#define MMPLL3_N_VAL (0x008C)
+#define MMPLL3_USER_CTL (0x0090)
+#define MMPLL3_STATUS (0x009C)
+#define MMPLL4_MODE (0x00A0)
+#define MMPLL4_L_VAL (0x00A4)
+#define MMPLL4_M_VAL (0x00A8)
+#define MMPLL4_N_VAL (0x00AC)
+#define MMPLL4_USER_CTL (0x00B0)
+#define MMPLL4_STATUS (0x00BC)
+#define MMSS_PLL_VOTE_APCS (0x0100)
+#define VCODEC0_CMD_RCGR (0x1000)
+#define VENUS0_VCODEC0_CBCR (0x1028)
+#define VENUS0_AHB_CBCR (0x1030)
+#define VENUS0_AXI_CBCR (0x1034)
+#define VENUS0_OCMEMNOC_CBCR (0x1038)
+#define PCLK0_CMD_RCGR (0x2000)
+#define MDP_CMD_RCGR (0x2040)
+#define VSYNC_CMD_RCGR (0x2080)
+#define BYTE0_CMD_RCGR (0x2120)
+#define ESC0_CMD_RCGR (0x2160)
+#define MDSS_AHB_CBCR (0x2308)
+#define MDSS_AXI_CBCR (0x2310)
+#define MDSS_PCLK0_CBCR (0x2314)
+#define MDSS_MDP_CBCR (0x231C)
+#define MDSS_MDP_LUT_CBCR (0x2320)
+#define MDSS_VSYNC_CBCR (0x2328)
+#define MDSS_BYTE0_CBCR (0x233C)
+#define MDSS_ESC0_CBCR (0x2344)
+#define CSI0PHYTIMER_CMD_RCGR (0x3000)
+#define CAMSS_PHY0_CSI0PHYTIMER_CBCR (0x3024)
+#define CSI1PHYTIMER_CMD_RCGR (0x3030)
+#define CAMSS_PHY1_CSI1PHYTIMER_CBCR (0x3054)
+#define CSI0_CMD_RCGR (0x3090)
+#define CAMSS_CSI0_CBCR (0x30B4)
+#define CAMSS_CSI0_AHB_CBCR (0x30BC)
+#define CAMSS_CSI0PHY_CBCR (0x30C4)
+#define CAMSS_CSI0RDI_CBCR (0x30D4)
+#define CAMSS_CSI0PIX_CBCR (0x30E4)
+#define CSI1_CMD_RCGR (0x3100)
+#define CAMSS_CSI1_CBCR (0x3124)
+#define CAMSS_CSI1_AHB_CBCR (0x3128)
+#define CAMSS_CSI1PHY_CBCR (0x3134)
+#define CAMSS_CSI1RDI_CBCR (0x3144)
+#define CAMSS_CSI1PIX_CBCR (0x3154)
+#define CSI2_CMD_RCGR (0x3160)
+#define CAMSS_CSI2_CBCR (0x3184)
+#define CAMSS_CSI2_AHB_CBCR (0x3188)
+#define CAMSS_CSI2PHY_CBCR (0x3194)
+#define CAMSS_CSI2RDI_CBCR (0x31A4)
+#define CAMSS_CSI2PIX_CBCR (0x31B4)
+#define CAMSS_ISPIF_AHB_CBCR (0x3224)
+#define CCI_CMD_RCGR (0x3300)
+#define CAMSS_CCI_CCI_CBCR (0x3344)
+#define CAMSS_CCI_CCI_AHB_CBCR (0x3348)
+#define MCLK0_CMD_RCGR (0x3360)
+#define CAMSS_MCLK0_CBCR (0x3384)
+#define MCLK1_CMD_RCGR (0x3390)
+#define CAMSS_MCLK1_CBCR (0x33B4)
+#define MCLK2_CMD_RCGR (0x33C0)
+#define CAMSS_MCLK2_CBCR (0x33E4)
+#define MMSS_GP0_CMD_RCGR (0x3420)
+#define CAMSS_GP0_CBCR (0x3444)
+#define MMSS_GP1_CMD_RCGR (0x3450)
+#define CAMSS_GP1_CBCR (0x3474)
+#define CAMSS_TOP_AHB_CBCR (0x3484)
+#define CAMSS_AHB_CBCR (0x348C)
+#define CAMSS_MICRO_BCR (0x3490)
+#define CAMSS_MICRO_AHB_CBCR (0x3494)
+#define JPEG0_CMD_RCGR (0x3500)
+#define CAMSS_JPEG_JPEG0_CBCR (0x35A8)
+#define CAMSS_JPEG_JPEG_AHB_CBCR (0x35B4)
+#define CAMSS_JPEG_JPEG_AXI_CBCR (0x35B8)
+#define VFE0_CMD_RCGR (0x3600)
+#define VFE1_CMD_RCGR (0x3620)
+#define CPP_CMD_RCGR (0x3640)
+#define CAMSS_VFE_VFE0_CBCR (0x36A8)
+#define CAMSS_VFE_VFE1_CBCR (0x36AC)
+#define CAMSS_VFE_CPP_CBCR (0x36B0)
+#define CAMSS_VFE_CPP_AHB_CBCR (0x36B4)
+#define CAMSS_VFE_VFE_AHB_CBCR (0x36B8)
+#define CAMSS_VFE_VFE_AXI_CBCR (0x36BC)
+#define CAMSS_CSI_VFE0_CBCR (0x3704)
+#define CAMSS_CSI_VFE1_CBCR (0x3714)
+#define OXILI_GFX3D_CBCR (0x4028)
+#define OXILICX_AHB_CBCR (0x403C)
+#define OCMEMCX_OCMEMNOC_CBCR (0x4058)
+#define MMSS_MISC_AHB_CBCR (0x502C)
+#define AXI_CMD_RCGR (0x5040)
+#define MMSS_S0_AXI_CBCR (0x5064)
+#define MMSS_MMSSNOC_AXI_CBCR (0x506C)
+#define OCMEMNOC_CMD_RCGR (0x5090)
+#define MMSS_DEBUG_CLK_CTL (0x0900)
+#define LPASS_DBG_CLK (0x32000)
+
+DEFINE_CLK_RPM_SMD_BRANCH(xo, xo_a_clk, RPM_MISC_CLK_TYPE, CXO_ID, 19200000);
+DEFINE_CLK_RPM_SMD(cnoc, cnoc_a_clk, RPM_BUS_CLK_TYPE, CNOC_ID, NULL);
+DEFINE_CLK_RPM_SMD(pnoc, pnoc_a_clk, RPM_BUS_CLK_TYPE, PNOC_ID, NULL);
+DEFINE_CLK_RPM_SMD(snoc, snoc_a_clk, RPM_BUS_CLK_TYPE, SNOC_ID, NULL);
+DEFINE_CLK_RPM_SMD(bimc, bimc_a_clk, RPM_MEM_CLK_TYPE, BIMC_ID, NULL);
+DEFINE_CLK_RPM_SMD_QDSS(qdss, qdss_a_clk, RPM_MISC_CLK_TYPE, QDSS_ID);
+DEFINE_CLK_RPM_SMD(gfx3d, gfx3d_a_clk, RPM_MEM_CLK_TYPE, OXILI_ID, NULL);
+DEFINE_CLK_RPM_SMD(mmssnoc_ahb, mmssnoc_ahb_a_clk, RPM_BUS_CLK_TYPE,
+ MMSSNOC_AHB_ID, NULL);
+DEFINE_CLK_RPM_SMD(ocmemgx, ocmemgx_a_clk, RPM_MEM_CLK_TYPE, OCMEM_ID, NULL);
+
+DEFINE_CLK_RPM_SMD_XO_BUFFER(bb_clk1, bb_clk1_a, BB_CLK1_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER(bb_clk2, bb_clk2_a, BB_CLK2_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER(rf_clk1, rf_clk1_a, RF_CLK1_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER(rf_clk2, rf_clk2_a, RF_CLK2_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER(rf_clk3, rf_clk3_a, RF_CLK3_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER(diff_clk1, diff_clk1_a, DIFF_CLK1_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER(div_clk1, div_clk1_a, DIV_CLK1_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER(div_clk2, div_clk2_a, DIV_CLK2_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER(div_clk3, div_clk3_a, DIV_CLK3_ID);
+
+DEFINE_CLK_RPM_SMD_XO_BUFFER_PINCTRL(bb_clk1_pin, bb_clk1_a_pin, BB_CLK1_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER_PINCTRL(bb_clk2_pin, bb_clk2_a_pin, BB_CLK2_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER_PINCTRL(rf_clk1_pin, rf_clk1_a_pin, RF_CLK1_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER_PINCTRL(rf_clk2_pin, rf_clk2_a_pin, RF_CLK2_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER_PINCTRL(rf_clk3_pin, rf_clk3_a_pin, RF_CLK3_ID);
+
+static DEFINE_CLK_VOTER(pnoc_msmbus_clk, &pnoc.c, LONG_MAX);
+static DEFINE_CLK_VOTER(snoc_msmbus_clk, &snoc.c, LONG_MAX);
+static DEFINE_CLK_VOTER(cnoc_msmbus_clk, &cnoc.c, LONG_MAX);
+static DEFINE_CLK_VOTER(pnoc_msmbus_a_clk, &pnoc_a_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(snoc_msmbus_a_clk, &snoc_a_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(cnoc_msmbus_a_clk, &cnoc_a_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(bimc_msmbus_clk, &bimc.c, LONG_MAX);
+static DEFINE_CLK_VOTER(bimc_msmbus_a_clk, &bimc_a_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(oxili_gfx3d_clk_src, &gfx3d.c, LONG_MAX);
+static DEFINE_CLK_VOTER(ocmemgx_msmbus_clk, &ocmemgx.c, LONG_MAX);
+static DEFINE_CLK_VOTER(ocmemgx_msmbus_a_clk, &ocmemgx_a_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(ocmemgx_core_clk, &ocmemgx.c, LONG_MAX);
+
+static DEFINE_CLK_VOTER(pnoc_keepalive_a_clk, &pnoc_a_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(pnoc_sps_clk, &pnoc.c, 0);
+
+static DEFINE_CLK_BRANCH_VOTER(xo_otg_clk, &xo.c);
+static DEFINE_CLK_BRANCH_VOTER(xo_pil_lpass_clk, &xo.c);
+static DEFINE_CLK_BRANCH_VOTER(xo_pil_mss_clk, &xo.c);
+static DEFINE_CLK_BRANCH_VOTER(xo_wlan_clk, &xo.c);
+static DEFINE_CLK_BRANCH_VOTER(xo_pil_pronto_clk, &xo.c);
+static DEFINE_CLK_BRANCH_VOTER(xo_ehci_host_clk, &xo.c);
+static DEFINE_CLK_BRANCH_VOTER(xo_lpm_clk, &xo.c);
+
+/*
+ * RPM manages gcc_bimc_gpu_clk automatically. This clock is created
+ * for measurement only.
+ */
+DEFINE_CLK_DUMMY(bimc_gpu, 0);
+
+static unsigned int soft_vote_gpll0;
+
+static struct pll_vote_clk gpll0 = {
+ .en_reg = (void __iomem *)APCS_GPLL_ENA_VOTE,
+ .en_mask = BIT(0),
+ .status_reg = (void __iomem *)GPLL0_STATUS,
+ .status_mask = BIT(17),
+ .soft_vote = &soft_vote_gpll0,
+ .soft_vote_mask = PLL_SOFT_VOTE_PRIMARY,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .rate = 600000000,
+ .parent = &xo.c,
+ .dbg_name = "gpll0",
+ .ops = &clk_ops_pll_acpu_vote,
+ CLK_INIT(gpll0.c),
+ },
+};
+
+static struct pll_vote_clk gpll0_ao = {
+ .en_reg = (void __iomem *)APCS_GPLL_ENA_VOTE,
+ .en_mask = BIT(0),
+ .status_reg = (void __iomem *)GPLL0_STATUS,
+ .status_mask = BIT(17),
+ .soft_vote = &soft_vote_gpll0,
+ .soft_vote_mask = PLL_SOFT_VOTE_ACPU,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .rate = 600000000,
+ .parent = &xo_a_clk.c,
+ .dbg_name = "gpll0_ao",
+ .ops = &clk_ops_pll_acpu_vote,
+ CLK_INIT(gpll0_ao.c),
+ },
+};
+
+static struct pll_vote_clk gpll4 = {
+ .en_reg = (void __iomem *)APCS_GPLL_ENA_VOTE,
+ .en_mask = BIT(4),
+ .status_reg = (void __iomem *)GPLL4_STATUS,
+ .status_mask = BIT(17),
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .rate = 768000000,
+ .parent = &xo.c,
+ .dbg_name = "gpll4",
+ .ops = &clk_ops_pll_vote,
+ CLK_INIT(gpll4.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk[] = {
+ F( 19200000, xo, 1, 0, 0),
+ F( 37500000, gpll0, 16, 0, 0),
+ F( 50000000, gpll0, 12, 0, 0),
+ F_END
+};
+
+static struct rcg_clk blsp1_qup1_i2c_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_QUP1_I2C_APPS_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_qup1_i2c_apps_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP1(LOW, 50000000),
+ CLK_INIT(blsp1_qup1_i2c_apps_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_gcc_blsp1_2_qup1_4_spi_apps_clk[] = {
+ F( 960000, xo, 10, 1, 2),
+ F( 4800000, xo, 4, 0, 0),
+ F( 9600000, xo, 2, 0, 0),
+ F( 15000000, gpll0, 10, 1, 4),
+ F( 19200000, xo, 1, 0, 0),
+ F( 25000000, gpll0, 12, 1, 2),
+ F( 50000000, gpll0, 12, 0, 0),
+ F_END
+};
+
+static struct rcg_clk blsp1_qup1_spi_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_QUP1_SPI_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_4_spi_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_qup1_spi_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+ CLK_INIT(blsp1_qup1_spi_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp1_qup2_i2c_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_QUP2_I2C_APPS_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_qup2_i2c_apps_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP1(LOW, 50000000),
+ CLK_INIT(blsp1_qup2_i2c_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp1_qup2_spi_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_QUP2_SPI_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_4_spi_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_qup2_spi_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+ CLK_INIT(blsp1_qup2_spi_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp1_qup3_i2c_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_QUP3_I2C_APPS_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_qup3_i2c_apps_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP1(LOW, 50000000),
+ CLK_INIT(blsp1_qup3_i2c_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp1_qup3_spi_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_QUP3_SPI_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_4_spi_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_qup3_spi_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+ CLK_INIT(blsp1_qup3_spi_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp1_qup4_i2c_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_QUP4_I2C_APPS_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_qup4_i2c_apps_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP1(LOW, 50000000),
+ CLK_INIT(blsp1_qup4_i2c_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp1_qup4_spi_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_QUP4_SPI_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_4_spi_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_qup4_spi_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+ CLK_INIT(blsp1_qup4_spi_apps_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_gcc_blsp1_2_uart1_4_apps_clk[] = {
+ F( 3686400, gpll0, 1, 96, 15625),
+ F( 7372800, gpll0, 1, 192, 15625),
+ F( 14745600, gpll0, 1, 384, 15625),
+ F( 16000000, gpll0, 5, 2, 15),
+ F( 19200000, xo, 1, 0, 0),
+ F( 24000000, gpll0, 5, 1, 5),
+ F( 32000000, gpll0, 1, 4, 75),
+ F( 40000000, gpll0, 15, 0, 0),
+ F( 46400000, gpll0, 1, 29, 375),
+ F( 48000000, gpll0, 12.5, 0, 0),
+ F( 51200000, gpll0, 1, 32, 375),
+ F( 56000000, gpll0, 1, 7, 75),
+ F( 58982400, gpll0, 1, 1536, 15625),
+ F( 60000000, gpll0, 10, 0, 0),
+ F( 63160000, gpll0, 9.5, 0, 0),
+ F_END
+};
+
+static struct rcg_clk blsp1_uart1_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_UART1_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_2_uart1_4_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_uart1_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+ CLK_INIT(blsp1_uart1_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp1_uart2_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_UART2_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_2_uart1_4_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_uart2_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+ CLK_INIT(blsp1_uart2_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp1_uart3_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_UART3_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_2_uart1_4_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_uart3_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+ CLK_INIT(blsp1_uart3_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp1_uart4_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_UART4_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_2_uart1_4_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_uart4_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+ CLK_INIT(blsp1_uart4_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp2_qup1_i2c_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP2_QUP1_I2C_APPS_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp2_qup1_i2c_apps_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP1(LOW, 50000000),
+ CLK_INIT(blsp2_qup1_i2c_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp2_qup1_spi_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP2_QUP1_SPI_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_4_spi_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp2_qup1_spi_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+ CLK_INIT(blsp2_qup1_spi_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp2_qup2_i2c_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP2_QUP2_I2C_APPS_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp2_qup2_i2c_apps_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP1(LOW, 50000000),
+ CLK_INIT(blsp2_qup2_i2c_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp2_qup2_spi_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP2_QUP2_SPI_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_4_spi_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp2_qup2_spi_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+ CLK_INIT(blsp2_qup2_spi_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp2_qup3_i2c_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP2_QUP3_I2C_APPS_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp2_qup3_i2c_apps_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP1(LOW, 50000000),
+ CLK_INIT(blsp2_qup3_i2c_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp2_qup3_spi_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP2_QUP3_SPI_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_4_spi_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp2_qup3_spi_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+ CLK_INIT(blsp2_qup3_spi_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp2_qup4_i2c_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP2_QUP4_I2C_APPS_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp2_qup4_i2c_apps_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP1(LOW, 50000000),
+ CLK_INIT(blsp2_qup4_i2c_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp2_qup4_spi_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP2_QUP4_SPI_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_4_spi_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp2_qup4_spi_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+ CLK_INIT(blsp2_qup4_spi_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp2_uart1_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP2_UART1_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_2_uart1_4_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp2_uart1_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+ CLK_INIT(blsp2_uart1_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp2_uart2_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP2_UART2_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_2_uart1_4_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp2_uart2_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+ CLK_INIT(blsp2_uart2_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp2_uart3_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP2_UART3_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_2_uart1_4_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp2_uart3_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+ CLK_INIT(blsp2_uart3_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp2_uart4_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP2_UART4_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_2_uart1_4_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp2_uart4_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+ CLK_INIT(blsp2_uart4_apps_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_gcc_ce1_clk[] = {
+ F( 75000000, gpll0, 8, 0, 0),
+ F( 171430000, gpll0, 3.5, 0, 0),
+ F_END
+};
+
+static struct rcg_clk ce1_clk_src = {
+ .cmd_rcgr_reg = CE1_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_gcc_ce1_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "ce1_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP2(LOW, 75000000, NOMINAL, 171430000),
+ CLK_INIT(ce1_clk_src.c),
+ },
+};
+
+static DEFINE_CLK_VOTER(scm_ce1_clk_src, &ce1_clk_src.c, 171430000);
+
+static struct clk_freq_tbl ftbl_gcc_pdm2_clk[] = {
+ F( 60000000, gpll0, 10, 0, 0),
+ F_END
+};
+
+static struct rcg_clk pdm2_clk_src = {
+ .cmd_rcgr_reg = PDM2_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_gcc_pdm2_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "pdm2_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP1(LOW, 60000000),
+ CLK_INIT(pdm2_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_gcc_sdcc1_apps_clk[] = {
+ F( 144000, xo, 16, 3, 25),
+ F( 400000, xo, 12, 1, 4),
+ F( 20000000, gpll0, 15, 1, 2),
+ F( 25000000, gpll0, 12, 1, 2),
+ F( 50000000, gpll0, 12, 0, 0),
+ F( 100000000, gpll0, 6, 0, 0),
+ F( 192000000, gpll4, 4, 0, 0),
+ F( 384000000, gpll4, 2, 0, 0),
+ F_END
+};
+
+static struct clk_freq_tbl ftbl_gcc_sdcc2_4_apps_clk[] = {
+ F( 144000, xo, 16, 3, 25),
+ F( 400000, xo, 12, 1, 4),
+ F( 20000000, gpll0, 15, 1, 2),
+ F( 25000000, gpll0, 12, 1, 2),
+ F( 50000000, gpll0, 12, 0, 0),
+ F( 100000000, gpll0, 6, 0, 0),
+ F( 200000000, gpll0, 3, 0, 0),
+ F_END
+};
+
+static struct rcg_clk sdcc1_apps_clk_src = {
+ .cmd_rcgr_reg = SDCC1_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_sdcc1_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "sdcc1_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 50000000, NOMINAL, 400000000),
+ CLK_INIT(sdcc1_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk sdcc2_apps_clk_src = {
+ .cmd_rcgr_reg = SDCC2_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_sdcc2_4_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "sdcc2_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 50000000, NOMINAL, 200000000),
+ CLK_INIT(sdcc2_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk sdcc3_apps_clk_src = {
+ .cmd_rcgr_reg = SDCC3_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_sdcc2_4_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "sdcc3_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 50000000, NOMINAL, 100000000),
+ CLK_INIT(sdcc3_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk sdcc4_apps_clk_src = {
+ .cmd_rcgr_reg = SDCC4_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_sdcc2_4_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "sdcc4_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 50000000, NOMINAL, 100000000),
+ CLK_INIT(sdcc4_apps_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_gcc_tsif_ref_clk[] = {
+ F( 105000, xo, 2, 1, 91),
+ F_END
+};
+
+static struct rcg_clk tsif_ref_clk_src = {
+ .cmd_rcgr_reg = TSIF_REF_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_tsif_ref_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "tsif_ref_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP1(LOW, 105500),
+ CLK_INIT(tsif_ref_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_gcc_usb_hs_system_clk[] = {
+ F( 75000000, gpll0, 8, 0, 0),
+ F_END
+};
+
+static struct rcg_clk usb_hs_system_clk_src = {
+ .cmd_rcgr_reg = USB_HS_SYSTEM_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_gcc_usb_hs_system_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "usb_hs_system_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP2(LOW, 37500000, NOMINAL, 75000000),
+ CLK_INIT(usb_hs_system_clk_src.c),
+ },
+};
+
+static struct local_vote_clk gcc_bam_dma_ahb_clk = {
+ .cbcr_reg = BAM_DMA_AHB_CBCR,
+ .vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+ .en_mask = BIT(12),
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_bam_dma_ahb_clk",
+ .ops = &clk_ops_vote,
+ CLK_INIT(gcc_bam_dma_ahb_clk.c),
+ },
+};
+
+static struct local_vote_clk gcc_blsp1_ahb_clk = {
+ .cbcr_reg = BLSP1_AHB_CBCR,
+ .vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+ .en_mask = BIT(17),
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp1_ahb_clk",
+ .ops = &clk_ops_vote,
+ CLK_INIT(gcc_blsp1_ahb_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_qup1_i2c_apps_clk = {
+ .cbcr_reg = BLSP1_QUP1_I2C_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp1_qup1_i2c_apps_clk",
+ .parent = &blsp1_qup1_i2c_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_qup1_i2c_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_qup1_spi_apps_clk = {
+ .cbcr_reg = BLSP1_QUP1_SPI_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp1_qup1_spi_apps_clk",
+ .parent = &blsp1_qup1_spi_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_qup1_spi_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_qup2_i2c_apps_clk = {
+ .cbcr_reg = BLSP1_QUP2_I2C_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp1_qup2_i2c_apps_clk",
+ .parent = &blsp1_qup2_i2c_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_qup2_i2c_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_qup2_spi_apps_clk = {
+ .cbcr_reg = BLSP1_QUP2_SPI_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp1_qup2_spi_apps_clk",
+ .parent = &blsp1_qup2_spi_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_qup2_spi_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_qup3_i2c_apps_clk = {
+ .cbcr_reg = BLSP1_QUP3_I2C_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp1_qup3_i2c_apps_clk",
+ .parent = &blsp1_qup3_i2c_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_qup3_i2c_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_qup3_spi_apps_clk = {
+ .cbcr_reg = BLSP1_QUP3_SPI_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp1_qup3_spi_apps_clk",
+ .parent = &blsp1_qup3_spi_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_qup3_spi_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_qup4_i2c_apps_clk = {
+ .cbcr_reg = BLSP1_QUP4_I2C_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp1_qup4_i2c_apps_clk",
+ .parent = &blsp1_qup4_i2c_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_qup4_i2c_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_qup4_spi_apps_clk = {
+ .cbcr_reg = BLSP1_QUP4_SPI_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp1_qup4_spi_apps_clk",
+ .parent = &blsp1_qup4_spi_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_qup4_spi_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_uart1_apps_clk = {
+ .cbcr_reg = BLSP1_UART1_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp1_uart1_apps_clk",
+ .parent = &blsp1_uart1_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_uart1_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_uart2_apps_clk = {
+ .cbcr_reg = BLSP1_UART2_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp1_uart2_apps_clk",
+ .parent = &blsp1_uart2_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_uart2_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_uart3_apps_clk = {
+ .cbcr_reg = BLSP1_UART3_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp1_uart3_apps_clk",
+ .parent = &blsp1_uart3_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_uart3_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_uart4_apps_clk = {
+ .cbcr_reg = BLSP1_UART4_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp1_uart4_apps_clk",
+ .parent = &blsp1_uart4_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_uart4_apps_clk.c),
+ },
+};
+
+static struct local_vote_clk gcc_blsp2_ahb_clk = {
+ .cbcr_reg = BLSP2_AHB_CBCR,
+ .vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+ .en_mask = BIT(15),
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp2_ahb_clk",
+ .ops = &clk_ops_vote,
+ CLK_INIT(gcc_blsp2_ahb_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp2_qup1_i2c_apps_clk = {
+ .cbcr_reg = BLSP2_QUP1_I2C_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp2_qup1_i2c_apps_clk",
+ .parent = &blsp2_qup1_i2c_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp2_qup1_i2c_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp2_qup1_spi_apps_clk = {
+ .cbcr_reg = BLSP2_QUP1_SPI_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp2_qup1_spi_apps_clk",
+ .parent = &blsp2_qup1_spi_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp2_qup1_spi_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp2_qup2_i2c_apps_clk = {
+ .cbcr_reg = BLSP2_QUP2_I2C_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp2_qup2_i2c_apps_clk",
+ .parent = &blsp2_qup2_i2c_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp2_qup2_i2c_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp2_qup2_spi_apps_clk = {
+ .cbcr_reg = BLSP2_QUP2_SPI_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp2_qup2_spi_apps_clk",
+ .parent = &blsp2_qup2_spi_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp2_qup2_spi_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp2_qup3_i2c_apps_clk = {
+ .cbcr_reg = BLSP2_QUP3_I2C_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp2_qup3_i2c_apps_clk",
+ .parent = &blsp2_qup3_i2c_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp2_qup3_i2c_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp2_qup3_spi_apps_clk = {
+ .cbcr_reg = BLSP2_QUP3_SPI_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp2_qup3_spi_apps_clk",
+ .parent = &blsp2_qup3_spi_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp2_qup3_spi_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp2_qup4_i2c_apps_clk = {
+ .cbcr_reg = BLSP2_QUP4_I2C_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp2_qup4_i2c_apps_clk",
+ .parent = &blsp2_qup4_i2c_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp2_qup4_i2c_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp2_qup4_spi_apps_clk = {
+ .cbcr_reg = BLSP2_QUP4_SPI_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp2_qup4_spi_apps_clk",
+ .parent = &blsp2_qup4_spi_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp2_qup4_spi_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp2_uart1_apps_clk = {
+ .cbcr_reg = BLSP2_UART1_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp2_uart1_apps_clk",
+ .parent = &blsp2_uart1_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp2_uart1_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp2_uart2_apps_clk = {
+ .cbcr_reg = BLSP2_UART2_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp2_uart2_apps_clk",
+ .parent = &blsp2_uart2_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp2_uart2_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp2_uart3_apps_clk = {
+ .cbcr_reg = BLSP2_UART3_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp2_uart3_apps_clk",
+ .parent = &blsp2_uart3_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp2_uart3_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp2_uart4_apps_clk = {
+ .cbcr_reg = BLSP2_UART4_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp2_uart4_apps_clk",
+ .parent = &blsp2_uart4_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp2_uart4_apps_clk.c),
+ },
+};
+
+static struct local_vote_clk gcc_boot_rom_ahb_clk = {
+ .cbcr_reg = BOOT_ROM_AHB_CBCR,
+ .vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+ .en_mask = BIT(10),
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_boot_rom_ahb_clk",
+ .ops = &clk_ops_vote,
+ CLK_INIT(gcc_boot_rom_ahb_clk.c),
+ },
+};
+
+static struct local_vote_clk gcc_ce1_ahb_clk = {
+ .cbcr_reg = CE1_AHB_CBCR,
+ .vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+ .en_mask = BIT(3),
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_ce1_ahb_clk",
+ .ops = &clk_ops_vote,
+ CLK_INIT(gcc_ce1_ahb_clk.c),
+ },
+};
+
+static struct local_vote_clk gcc_ce1_axi_clk = {
+ .cbcr_reg = CE1_AXI_CBCR,
+ .vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+ .en_mask = BIT(4),
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_ce1_axi_clk",
+ .ops = &clk_ops_vote,
+ CLK_INIT(gcc_ce1_axi_clk.c),
+ },
+};
+
+static struct local_vote_clk gcc_ce1_clk = {
+ .cbcr_reg = CE1_CBCR,
+ .vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+ .en_mask = BIT(5),
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_ce1_clk",
+ .parent = &ce1_clk_src.c,
+ .ops = &clk_ops_vote,
+ CLK_INIT(gcc_ce1_clk.c),
+ },
+};
+
+static struct branch_clk gcc_lpass_q6_axi_clk = {
+ .cbcr_reg = LPASS_Q6_AXI_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_lpass_q6_axi_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_lpass_q6_axi_clk.c),
+ },
+};
+
+static struct branch_clk gcc_lpass_sys_noc_mport_clk = {
+ .cbcr_reg = LPASS_SYS_NOC_MPORT_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_lpass_sys_noc_mport_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_lpass_sys_noc_mport_clk.c),
+ },
+};
+
+static struct branch_clk gcc_lpass_sys_noc_sway_clk = {
+ .cbcr_reg = LPASS_SYS_NOC_SWAY_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_lpass_sys_noc_sway_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_lpass_sys_noc_sway_clk.c),
+ },
+};
+
+static struct branch_clk gcc_mss_cfg_ahb_clk = {
+ .cbcr_reg = MSS_CFG_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_mss_cfg_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_mss_cfg_ahb_clk.c),
+ },
+};
+
+static struct branch_clk gcc_mss_q6_bimc_axi_clk = {
+ .cbcr_reg = MSS_Q6_BIMC_AXI_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_mss_q6_bimc_axi_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_mss_q6_bimc_axi_clk.c),
+ },
+};
+
+static struct branch_clk gcc_pdm2_clk = {
+ .cbcr_reg = PDM2_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_pdm2_clk",
+ .parent = &pdm2_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_pdm2_clk.c),
+ },
+};
+
+static struct branch_clk gcc_pdm_ahb_clk = {
+ .cbcr_reg = PDM_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_pdm_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_pdm_ahb_clk.c),
+ },
+};
+
+static struct local_vote_clk gcc_prng_ahb_clk = {
+ .cbcr_reg = PRNG_AHB_CBCR,
+ .vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+ .en_mask = BIT(13),
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_prng_ahb_clk",
+ .ops = &clk_ops_vote,
+ CLK_INIT(gcc_prng_ahb_clk.c),
+ },
+};
+
+static struct branch_clk gcc_sdcc1_ahb_clk = {
+ .cbcr_reg = SDCC1_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_sdcc1_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_sdcc1_ahb_clk.c),
+ },
+};
+
+static struct branch_clk gcc_sdcc1_apps_clk = {
+ .cbcr_reg = SDCC1_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_sdcc1_apps_clk",
+ .parent = &sdcc1_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_sdcc1_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_sdcc1_cdccal_ff_clk = {
+ .cbcr_reg = SDCC1_CDCCAL_FF_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_sdcc1_cdccal_ff_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_sdcc1_cdccal_ff_clk.c),
+ },
+};
+
+static struct branch_clk gcc_sdcc1_cdccal_sleep_clk = {
+ .cbcr_reg = SDCC1_CDCCAL_SLEEP_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_sdcc1_cdccal_sleep_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_sdcc1_cdccal_sleep_clk.c),
+ },
+};
+
+static struct branch_clk gcc_sdcc2_ahb_clk = {
+ .cbcr_reg = SDCC2_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_sdcc2_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_sdcc2_ahb_clk.c),
+ },
+};
+
+static struct branch_clk gcc_sdcc2_apps_clk = {
+ .cbcr_reg = SDCC2_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_sdcc2_apps_clk",
+ .parent = &sdcc2_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_sdcc2_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_sdcc3_ahb_clk = {
+ .cbcr_reg = SDCC3_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_sdcc3_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_sdcc3_ahb_clk.c),
+ },
+};
+
+static struct branch_clk gcc_sdcc3_apps_clk = {
+ .cbcr_reg = SDCC3_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_sdcc3_apps_clk",
+ .parent = &sdcc3_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_sdcc3_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_sdcc4_ahb_clk = {
+ .cbcr_reg = SDCC4_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_sdcc4_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_sdcc4_ahb_clk.c),
+ },
+};
+
+static struct branch_clk gcc_sdcc4_apps_clk = {
+ .cbcr_reg = SDCC4_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_sdcc4_apps_clk",
+ .parent = &sdcc4_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_sdcc4_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_tsif_ahb_clk = {
+ .cbcr_reg = TSIF_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_tsif_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_tsif_ahb_clk.c),
+ },
+};
+
+static struct branch_clk gcc_tsif_ref_clk = {
+ .cbcr_reg = TSIF_REF_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_tsif_ref_clk",
+ .parent = &tsif_ref_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_tsif_ref_clk.c),
+ },
+};
+
+static struct branch_clk gcc_usb2a_phy_sleep_clk = {
+ .cbcr_reg = USB2A_PHY_SLEEP_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_usb2a_phy_sleep_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_usb2a_phy_sleep_clk.c),
+ },
+};
+
+static struct branch_clk gcc_usb_hs_ahb_clk = {
+ .cbcr_reg = USB_HS_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_usb_hs_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_usb_hs_ahb_clk.c),
+ },
+};
+
+static struct branch_clk gcc_usb_hs_system_clk = {
+ .cbcr_reg = USB_HS_SYSTEM_CBCR,
+ .bcr_reg = USB_HS_BCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_usb_hs_system_clk",
+ .parent = &usb_hs_system_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_usb_hs_system_clk.c),
+ },
+};
+
+static struct pll_vote_clk mmpll0 = {
+ .en_reg = (void __iomem *)MMSS_PLL_VOTE_APCS,
+ .en_mask = BIT(0),
+ .status_reg = (void __iomem *)MMPLL0_STATUS,
+ .status_mask = BIT(17),
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .rate = 800000000,
+ .parent = &xo.c,
+ .dbg_name = "mmpll0",
+ .ops = &clk_ops_pll_vote,
+ CLK_INIT(mmpll0.c),
+ },
+};
+
+static struct pll_vote_clk mmpll1 = {
+ .en_reg = (void __iomem *)MMSS_PLL_VOTE_APCS,
+ .en_mask = BIT(1),
+ .status_reg = (void __iomem *)MMPLL1_STATUS,
+ .status_mask = BIT(17),
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .rate = 900000000,
+ .parent = &xo.c,
+ .dbg_name = "mmpll1",
+ .ops = &clk_ops_pll_vote,
+ CLK_INIT(mmpll1.c),
+ },
+};
+
+static struct pll_clk mmpll4 = {
+ .mode_reg = (void __iomem *)MMPLL4_MODE,
+ .status_reg = (void __iomem *)MMPLL4_STATUS,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "mmpll4",
+ .parent = &xo.c,
+ .rate = 930000000,
+ .ops = &clk_ops_local_pll,
+ CLK_INIT(mmpll4.c),
+ },
+};
+
+static struct pll_clk mmpll3 = {
+ .mode_reg = (void __iomem *)MMPLL3_MODE,
+ .status_reg = (void __iomem *)MMPLL3_STATUS,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "mmpll3",
+ .parent = &xo.c,
+ .rate = 930000000,
+ .ops = &clk_ops_local_pll,
+ CLK_INIT(mmpll3.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_mmss_mmssnoc_axi_clk[] = {
+ F_MM( 19200000, xo, 1, 0, 0),
+ F_MM( 37500000, gpll0, 16, 0, 0),
+ F_MM( 50000000, gpll0, 12, 0, 0),
+ F_MM( 75000000, gpll0, 8, 0, 0),
+ F_MM( 100000000, gpll0, 6, 0, 0),
+ F_MM( 133330000, gpll0, 4.5, 0, 0),
+ F_MM( 266670000, mmpll0, 3, 0, 0),
+ F_MM( 300000000, mmpll1, 3, 0, 0),
+ F_END
+};
+
+static struct rcg_clk axi_clk_src = {
+ .cmd_rcgr_reg = AXI_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_mmss_mmssnoc_axi_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "axi_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP3(LOW, 133330000, NOMINAL, 266670000, HIGH,
+ 300000000),
+ CLK_INIT(axi_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_camss_csi0_2_clk[] = {
+ F_MM( 100000000, gpll0, 6, 0, 0),
+ F_MM( 200000000, mmpll0, 4, 0, 0),
+ F_END
+};
+
+static struct rcg_clk csi0_clk_src = {
+ .cmd_rcgr_reg = CSI0_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_camss_csi0_2_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "csi0_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+ CLK_INIT(csi0_clk_src.c),
+ },
+};
+
+static struct rcg_clk csi1_clk_src = {
+ .cmd_rcgr_reg = CSI1_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_camss_csi0_2_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "csi1_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+ CLK_INIT(csi1_clk_src.c),
+ },
+};
+
+static struct rcg_clk csi2_clk_src = {
+ .cmd_rcgr_reg = CSI2_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_camss_csi0_2_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "csi2_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+ CLK_INIT(csi2_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_camss_vfe_vfe0_1_clk[] = {
+ F_MM( 37500000, gpll0, 16, 0, 0),
+ F_MM( 50000000, gpll0, 12, 0, 0),
+ F_MM( 60000000, gpll0, 10, 0, 0),
+ F_MM( 80000000, gpll0, 7.5, 0, 0),
+ F_MM( 100000000, gpll0, 6, 0, 0),
+ F_MM( 109090000, gpll0, 5.5, 0, 0),
+ F_MM( 133330000, gpll0, 4.5, 0, 0),
+ F_MM( 150000000, gpll0, 4, 0, 0),
+ F_MM( 200000000, gpll0, 3, 0, 0),
+ F_MM( 228570000, mmpll0, 3.5, 0, 0),
+ F_MM( 266670000, mmpll0, 3, 0, 0),
+ F_MM( 320000000, mmpll0, 2.5, 0, 0),
+ F_MM( 400000000, mmpll0, 2, 0, 0),
+ F_MM( 465000000, mmpll4, 2, 0, 0),
+ F_END
+};
+
+static struct rcg_clk vfe0_clk_src = {
+ .cmd_rcgr_reg = VFE0_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_camss_vfe_vfe0_1_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "vfe0_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP3(LOW, 150000000, NOMINAL, 320000000, HIGH,
+ 465000000),
+ CLK_INIT(vfe0_clk_src.c),
+ },
+};
+
+static struct rcg_clk vfe1_clk_src = {
+ .cmd_rcgr_reg = VFE1_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_camss_vfe_vfe0_1_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "vfe1_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP3(LOW, 133330000, NOMINAL, 266670000, HIGH,
+ 320000000),
+ CLK_INIT(vfe1_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_mdss_mdp_clk[] = {
+ F_MM( 37500000, gpll0, 16, 0, 0),
+ F_MM( 60000000, gpll0, 10, 0, 0),
+ F_MM( 75000000, gpll0, 8, 0, 0),
+ F_MM( 85710000, gpll0, 7, 0, 0),
+ F_MM( 100000000, gpll0, 6, 0, 0),
+ F_MM( 150000000, gpll0, 4, 0, 0),
+ F_MM( 160000000, mmpll0, 5, 0, 0),
+ F_MM( 200000000, mmpll0, 4, 0, 0),
+ F_MM( 228570000, mmpll0, 3.5, 0, 0),
+ F_MM( 266670000, mmpll0, 3, 0, 0),
+ F_MM( 320000000, mmpll0, 2.5, 0, 0),
+ F_END
+};
+
+static struct rcg_clk mdp_clk_src = {
+ .cmd_rcgr_reg = MDP_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_mdss_mdp_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "mdp_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP3(LOW, 150000000, NOMINAL, 266670000, HIGH,
+ 320000000),
+ CLK_INIT(mdp_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_camss_jpeg_jpeg0_clk[] = {
+ F_MM( 75000000, gpll0, 8, 0, 0),
+ F_MM( 133330000, gpll0, 4.5, 0, 0),
+ F_MM( 200000000, gpll0, 3, 0, 0),
+ F_MM( 228570000, mmpll0, 3.5, 0, 0),
+ F_MM( 266670000, mmpll0, 3, 0, 0),
+ F_MM( 320000000, mmpll0, 2.5, 0, 0),
+ F_END
+};
+
+static struct rcg_clk jpeg0_clk_src = {
+ .cmd_rcgr_reg = JPEG0_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_camss_jpeg_jpeg0_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "jpeg0_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP3(LOW, 133330000, NOMINAL, 266670000, HIGH,
+ 320000000),
+ CLK_INIT(jpeg0_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl pixel_freq_tbl[] = {
+ {
+ .src_clk = &pixel_clk_src_samarium.c,
+ .div_src_val = BVAL(10, 8, dsipll0_pixel_mm_source_val)
+ | BVAL(4, 0, 0),
+ },
+ F_END
+};
+
+static struct rcg_clk pclk0_clk_src = {
+ .cmd_rcgr_reg = PCLK0_CMD_RCGR,
+ .current_freq = pixel_freq_tbl,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .parent = &pixel_clk_src_samarium.c,
+ .dbg_name = "pclk0_clk_src",
+ .ops = &clk_ops_pixel,
+ VDD_DIG_FMAX_MAP2(LOW, 148500000, NOMINAL, 250000000),
+ CLK_INIT(pclk0_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_ocmemcx_ocmemnoc_clk[] = {
+ F_MM( 19200000, xo, 1, 0, 0),
+ F_MM( 37500000, gpll0, 16, 0, 0),
+ F_MM( 50000000, gpll0, 12, 0, 0),
+ F_MM( 75000000, gpll0, 8, 0, 0),
+ F_MM( 109090000, gpll0, 5.5, 0, 0),
+ F_MM( 150000000, gpll0, 4, 0, 0),
+ F_MM( 266670000, mmpll0, 3, 0, 0),
+ F_MM( 300000000, mmpll1, 3, 0, 0),
+ F_END
+};
+
+static struct rcg_clk ocmemnoc_clk_src = {
+ .cmd_rcgr_reg = OCMEMNOC_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_ocmemcx_ocmemnoc_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "ocmemnoc_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP3(LOW, 133330000, NOMINAL, 266670000, HIGH,
+ 300000000),
+ CLK_INIT(ocmemnoc_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_camss_cci_cci_clk[] = {
+ F_MM( 19200000, xo, 1, 0, 0),
+ F_END
+};
+
+static struct rcg_clk cci_clk_src = {
+ .cmd_rcgr_reg = CCI_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_camss_cci_cci_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "cci_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP1(LOW, 19200000),
+ CLK_INIT(cci_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_camss_gp0_1_clk[] = {
+ F_MM( 10000, xo, 16, 1, 120),
+ F_MM( 24000, xo, 16, 1, 50),
+ F_MM( 6000000, gpll0, 10, 1, 10),
+ F_MM( 12000000, gpll0, 10, 1, 5),
+ F_MM( 13000000, gpll0, 4, 13, 150),
+ F_MM( 24000000, gpll0, 5, 1, 5),
+ F_END
+};
+
+static struct rcg_clk mmss_gp0_clk_src = {
+ .cmd_rcgr_reg = MMSS_GP0_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_camss_gp0_1_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "mmss_gp0_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+ CLK_INIT(mmss_gp0_clk_src.c),
+ },
+};
+
+static struct rcg_clk mmss_gp1_clk_src = {
+ .cmd_rcgr_reg = MMSS_GP1_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_camss_gp0_1_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "mmss_gp1_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+ CLK_INIT(mmss_gp1_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_camss_mclk0_2_clk[] = {
+ F_MM( 4800000, xo, 4, 0, 0),
+ F_MM( 6000000, gpll0, 10, 1, 10),
+ F_MM( 8000000, gpll0, 15, 1, 5),
+ F_MM( 9600000, xo, 2, 0, 0),
+ F_MM( 16000000, gpll0, 12.5, 1, 3),
+ F_MM( 19200000, xo, 1, 0, 0),
+ F_MM( 24000000, gpll0, 5, 1, 5),
+ F_MM( 32000000, mmpll0, 5, 1, 5),
+ F_MM( 48000000, gpll0, 12.5, 0, 0),
+ F_MM( 64000000, mmpll0, 12.5, 0, 0),
+ F_MM( 66670000, gpll0, 9, 0, 0),
+ F_END
+};
+
+static struct rcg_clk mclk0_clk_src = {
+ .cmd_rcgr_reg = MCLK0_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_camss_mclk0_2_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "mclk0_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP1(LOW, 66670000),
+ CLK_INIT(mclk0_clk_src.c),
+ },
+};
+
+static struct rcg_clk mclk1_clk_src = {
+ .cmd_rcgr_reg = MCLK1_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_camss_mclk0_2_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "mclk1_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP1(LOW, 66670000),
+ CLK_INIT(mclk1_clk_src.c),
+ },
+};
+
+static struct rcg_clk mclk2_clk_src = {
+ .cmd_rcgr_reg = MCLK2_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_camss_mclk0_2_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "mclk2_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP1(LOW, 66670000),
+ CLK_INIT(mclk2_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_camss_phy0_1_csi0_1phytimer_clk[] = {
+ F_MM( 100000000, gpll0, 6, 0, 0),
+ F_MM( 200000000, mmpll0, 4, 0, 0),
+ F_END
+};
+
+static struct rcg_clk csi0phytimer_clk_src = {
+ .cmd_rcgr_reg = CSI0PHYTIMER_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_camss_phy0_1_csi0_1phytimer_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "csi0phytimer_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+ CLK_INIT(csi0phytimer_clk_src.c),
+ },
+};
+
+static struct rcg_clk csi1phytimer_clk_src = {
+ .cmd_rcgr_reg = CSI1PHYTIMER_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_camss_phy0_1_csi0_1phytimer_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "csi1phytimer_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+ CLK_INIT(csi1phytimer_clk_src.c),
+ },
+};
+
+static struct branch_clk camss_vfe_vfe0_clk = {
+ .cbcr_reg = CAMSS_VFE_VFE0_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_vfe_vfe0_clk",
+ .parent = &vfe0_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_vfe_vfe0_clk.c),
+ },
+};
+
+static struct branch_clk camss_vfe_vfe1_clk = {
+ .cbcr_reg = CAMSS_VFE_VFE1_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_vfe_vfe1_clk",
+ .parent = &vfe1_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_vfe_vfe1_clk.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_camss_vfe_cpp_clk[] = {
+ F_MM( 150000000, gpll0, 4, 0, 0),
+ F_MM( 266670000, mmpll0, 3, 0, 0),
+ F_MM( 320000000, mmpll0, 2.5, 0, 0),
+ F_MM( 400000000, mmpll0, 2, 0, 0),
+ F_MM( 465000000, mmpll4, 2, 0, 0),
+ F_END
+};
+
+static struct rcg_clk cpp_clk_src = {
+ .cmd_rcgr_reg = CPP_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_camss_vfe_cpp_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "cpp_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP3(LOW, 150000000, NOMINAL, 320000000, HIGH,
+ 465000000),
+ CLK_INIT(cpp_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl byte_freq_tbl[] = {
+ {
+ .src_clk = &byte_clk_src_samarium.c,
+ .div_src_val = BVAL(10, 8, dsipll0_byte_mm_source_val),
+ },
+ F_END
+};
+
+static struct rcg_clk byte0_clk_src = {
+ .cmd_rcgr_reg = BYTE0_CMD_RCGR,
+ .current_freq = byte_freq_tbl,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .parent = &byte_clk_src_samarium.c,
+ .dbg_name = "byte0_clk_src",
+ .ops = &clk_ops_byte,
+ VDD_DIG_FMAX_MAP2(LOW, 111370000, NOMINAL, 187500000),
+ CLK_INIT(byte0_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_mdss_esc0_clk[] = {
+ F_MM( 19200000, xo, 1, 0, 0),
+ F_END
+};
+
+static struct rcg_clk esc0_clk_src = {
+ .cmd_rcgr_reg = ESC0_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_mdss_esc0_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "esc0_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP1(LOW, 19200000),
+ CLK_INIT(esc0_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_mdss_vsync_clk[] = {
+ F_MM( 19200000, xo, 1, 0, 0),
+ F_END
+};
+
+static struct rcg_clk vsync_clk_src = {
+ .cmd_rcgr_reg = VSYNC_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_mdss_vsync_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "vsync_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP1(LOW, 19200000),
+ CLK_INIT(vsync_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_venus0_vcodec0_clk[] = {
+ F_MM( 50000000, gpll0, 12, 0, 0),
+ F_MM( 100000000, gpll0, 6, 0, 0),
+ F_MM( 133330000, mmpll0, 6, 0, 0),
+ F_MM( 200000000, mmpll0, 4, 0, 0),
+ F_MM( 266670000, mmpll0, 3, 0, 0),
+ F_END
+};
+
+static struct rcg_clk vcodec0_clk_src = {
+ .cmd_rcgr_reg = VCODEC0_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_venus0_vcodec0_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "vcodec0_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 133330000, NOMINAL, 266670000),
+ CLK_INIT(vcodec0_clk_src.c),
+ },
+};
+
+static struct branch_clk camss_ahb_clk = {
+ .cbcr_reg = CAMSS_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_ahb_clk.c),
+ },
+};
+
+static struct branch_clk camss_cci_cci_ahb_clk = {
+ .cbcr_reg = CAMSS_CCI_CCI_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_cci_cci_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_cci_cci_ahb_clk.c),
+ },
+};
+
+static struct branch_clk camss_cci_cci_clk = {
+ .cbcr_reg = CAMSS_CCI_CCI_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_cci_cci_clk",
+ .parent = &cci_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_cci_cci_clk.c),
+ },
+};
+
+static struct branch_clk camss_csi0_ahb_clk = {
+ .cbcr_reg = CAMSS_CSI0_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_csi0_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_csi0_ahb_clk.c),
+ },
+};
+
+static struct branch_clk camss_csi0_clk = {
+ .cbcr_reg = CAMSS_CSI0_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_csi0_clk",
+ .parent = &csi0_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_csi0_clk.c),
+ },
+};
+
+static struct branch_clk camss_csi0phy_clk = {
+ .cbcr_reg = CAMSS_CSI0PHY_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_csi0phy_clk",
+ .parent = &csi0_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_csi0phy_clk.c),
+ },
+};
+
+static struct branch_clk camss_csi0pix_clk = {
+ .cbcr_reg = CAMSS_CSI0PIX_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_csi0pix_clk",
+ .parent = &csi0_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_csi0pix_clk.c),
+ },
+};
+
+static struct branch_clk camss_csi0rdi_clk = {
+ .cbcr_reg = CAMSS_CSI0RDI_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_csi0rdi_clk",
+ .parent = &csi0_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_csi0rdi_clk.c),
+ },
+};
+
+static struct branch_clk camss_csi1_ahb_clk = {
+ .cbcr_reg = CAMSS_CSI1_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_csi1_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_csi1_ahb_clk.c),
+ },
+};
+
+static struct branch_clk camss_csi1_clk = {
+ .cbcr_reg = CAMSS_CSI1_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_csi1_clk",
+ .parent = &csi1_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_csi1_clk.c),
+ },
+};
+
+static struct branch_clk camss_csi1phy_clk = {
+ .cbcr_reg = CAMSS_CSI1PHY_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_csi1phy_clk",
+ .parent = &csi1_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_csi1phy_clk.c),
+ },
+};
+
+static struct branch_clk camss_csi1pix_clk = {
+ .cbcr_reg = CAMSS_CSI1PIX_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_csi1pix_clk",
+ .parent = &csi1_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_csi1pix_clk.c),
+ },
+};
+
+static struct branch_clk camss_csi1rdi_clk = {
+ .cbcr_reg = CAMSS_CSI1RDI_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_csi1rdi_clk",
+ .parent = &csi1_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_csi1rdi_clk.c),
+ },
+};
+
+static struct branch_clk camss_csi2_ahb_clk = {
+ .cbcr_reg = CAMSS_CSI2_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_csi2_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_csi2_ahb_clk.c),
+ },
+};
+
+static struct branch_clk camss_csi2_clk = {
+ .cbcr_reg = CAMSS_CSI2_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_csi2_clk",
+ .parent = &csi2_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_csi2_clk.c),
+ },
+};
+
+static struct branch_clk camss_csi2phy_clk = {
+ .cbcr_reg = CAMSS_CSI2PHY_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_csi2phy_clk",
+ .parent = &csi2_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_csi2phy_clk.c),
+ },
+};
+
+static struct branch_clk camss_csi2pix_clk = {
+ .cbcr_reg = CAMSS_CSI2PIX_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_csi2pix_clk",
+ .parent = &csi2_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_csi2pix_clk.c),
+ },
+};
+
+static struct branch_clk camss_csi2rdi_clk = {
+ .cbcr_reg = CAMSS_CSI2RDI_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_csi2rdi_clk",
+ .parent = &csi2_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_csi2rdi_clk.c),
+ },
+};
+
+static struct branch_clk camss_csi_vfe0_clk = {
+ .cbcr_reg = CAMSS_CSI_VFE0_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_csi_vfe0_clk",
+ .parent = &vfe0_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_csi_vfe0_clk.c),
+ },
+};
+
+static struct branch_clk camss_csi_vfe1_clk = {
+ .cbcr_reg = CAMSS_CSI_VFE1_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_csi_vfe1_clk",
+ .parent = &vfe1_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_csi_vfe1_clk.c),
+ },
+};
+
+static struct branch_clk camss_gp0_clk = {
+ .cbcr_reg = CAMSS_GP0_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_gp0_clk",
+ .parent = &mmss_gp0_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_gp0_clk.c),
+ },
+};
+
+static struct branch_clk camss_gp1_clk = {
+ .cbcr_reg = CAMSS_GP1_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_gp1_clk",
+ .parent = &mmss_gp1_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_gp1_clk.c),
+ },
+};
+
+static struct branch_clk camss_ispif_ahb_clk = {
+ .cbcr_reg = CAMSS_ISPIF_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_ispif_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_ispif_ahb_clk.c),
+ },
+};
+
+static struct branch_clk camss_jpeg_jpeg0_clk = {
+ .cbcr_reg = CAMSS_JPEG_JPEG0_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_jpeg_jpeg0_clk",
+ .parent = &jpeg0_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_jpeg_jpeg0_clk.c),
+ },
+};
+
+static struct branch_clk camss_jpeg_jpeg_ahb_clk = {
+ .cbcr_reg = CAMSS_JPEG_JPEG_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_jpeg_jpeg_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_jpeg_jpeg_ahb_clk.c),
+ },
+};
+
+static struct branch_clk camss_jpeg_jpeg_axi_clk = {
+ .cbcr_reg = CAMSS_JPEG_JPEG_AXI_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_jpeg_jpeg_axi_clk",
+ .parent = &axi_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_jpeg_jpeg_axi_clk.c),
+ },
+};
+
+static struct branch_clk camss_mclk0_clk = {
+ .cbcr_reg = CAMSS_MCLK0_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_mclk0_clk",
+ .parent = &mclk0_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_mclk0_clk.c),
+ },
+};
+
+static struct branch_clk camss_mclk1_clk = {
+ .cbcr_reg = CAMSS_MCLK1_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_mclk1_clk",
+ .parent = &mclk1_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_mclk1_clk.c),
+ },
+};
+
+static struct branch_clk camss_mclk2_clk = {
+ .cbcr_reg = CAMSS_MCLK2_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_mclk2_clk",
+ .parent = &mclk2_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_mclk2_clk.c),
+ },
+};
+
+static struct branch_clk camss_micro_ahb_clk = {
+ .cbcr_reg = CAMSS_MICRO_AHB_CBCR,
+ .bcr_reg = CAMSS_MICRO_BCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_micro_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_micro_ahb_clk.c),
+ },
+};
+
+static struct branch_clk camss_phy0_csi0phytimer_clk = {
+ .cbcr_reg = CAMSS_PHY0_CSI0PHYTIMER_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_phy0_csi0phytimer_clk",
+ .parent = &csi0phytimer_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_phy0_csi0phytimer_clk.c),
+ },
+};
+
+static struct branch_clk camss_phy1_csi1phytimer_clk = {
+ .cbcr_reg = CAMSS_PHY1_CSI1PHYTIMER_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_phy1_csi1phytimer_clk",
+ .parent = &csi1phytimer_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_phy1_csi1phytimer_clk.c),
+ },
+};
+
+static struct branch_clk camss_top_ahb_clk = {
+ .cbcr_reg = CAMSS_TOP_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_top_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_top_ahb_clk.c),
+ },
+};
+
+static struct branch_clk camss_vfe_cpp_ahb_clk = {
+ .cbcr_reg = CAMSS_VFE_CPP_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_vfe_cpp_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_vfe_cpp_ahb_clk.c),
+ },
+};
+
+static struct branch_clk camss_vfe_cpp_clk = {
+ .cbcr_reg = CAMSS_VFE_CPP_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_vfe_cpp_clk",
+ .parent = &cpp_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_vfe_cpp_clk.c),
+ },
+};
+
+static struct branch_clk camss_vfe_vfe_ahb_clk = {
+ .cbcr_reg = CAMSS_VFE_VFE_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_vfe_vfe_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_vfe_vfe_ahb_clk.c),
+ },
+};
+
+static struct branch_clk camss_vfe_vfe_axi_clk = {
+ .cbcr_reg = CAMSS_VFE_VFE_AXI_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "camss_vfe_vfe_axi_clk",
+ .parent = &axi_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(camss_vfe_vfe_axi_clk.c),
+ },
+};
+
+static struct branch_clk mdss_ahb_clk = {
+ .cbcr_reg = MDSS_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "mdss_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(mdss_ahb_clk.c),
+ },
+};
+
+static struct branch_clk mdss_axi_clk = {
+ .cbcr_reg = MDSS_AXI_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "mdss_axi_clk",
+ .parent = &axi_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(mdss_axi_clk.c),
+ },
+};
+
+static struct branch_clk mdss_byte0_clk = {
+ .cbcr_reg = MDSS_BYTE0_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "mdss_byte0_clk",
+ .parent = &byte0_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(mdss_byte0_clk.c),
+ },
+};
+
+static struct branch_clk mdss_esc0_clk = {
+ .cbcr_reg = MDSS_ESC0_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "mdss_esc0_clk",
+ .parent = &esc0_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(mdss_esc0_clk.c),
+ },
+};
+
+static struct branch_clk mdss_mdp_clk = {
+ .cbcr_reg = MDSS_MDP_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "mdss_mdp_clk",
+ .parent = &mdp_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(mdss_mdp_clk.c),
+ },
+};
+
+static struct branch_clk mdss_mdp_lut_clk = {
+ .cbcr_reg = MDSS_MDP_LUT_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "mdss_mdp_lut_clk",
+ .parent = &mdp_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(mdss_mdp_lut_clk.c),
+ },
+};
+
+static struct branch_clk mdss_pclk0_clk = {
+ .cbcr_reg = MDSS_PCLK0_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "mdss_pclk0_clk",
+ .parent = &pclk0_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(mdss_pclk0_clk.c),
+ },
+};
+
+static struct branch_clk mdss_vsync_clk = {
+ .cbcr_reg = MDSS_VSYNC_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "mdss_vsync_clk",
+ .parent = &vsync_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(mdss_vsync_clk.c),
+ },
+};
+
+static struct branch_clk mmss_misc_ahb_clk = {
+ .cbcr_reg = MMSS_MISC_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "mmss_misc_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(mmss_misc_ahb_clk.c),
+ },
+};
+
+static struct branch_clk mmss_mmssnoc_axi_clk = {
+ .cbcr_reg = MMSS_MMSSNOC_AXI_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "mmss_mmssnoc_axi_clk",
+ .parent = &axi_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(mmss_mmssnoc_axi_clk.c),
+ },
+};
+
+static struct branch_clk mmss_s0_axi_clk = {
+ .cbcr_reg = MMSS_S0_AXI_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "mmss_s0_axi_clk",
+ .parent = &axi_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(mmss_s0_axi_clk.c),
+ .depends = &mmss_mmssnoc_axi_clk.c,
+ },
+};
+
+static struct branch_clk ocmemcx_ocmemnoc_clk = {
+ .cbcr_reg = OCMEMCX_OCMEMNOC_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "ocmemcx_ocmemnoc_clk",
+ .parent = &ocmemnoc_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(ocmemcx_ocmemnoc_clk.c),
+ },
+};
+
+static struct branch_clk oxili_gfx3d_clk = {
+ .cbcr_reg = OXILI_GFX3D_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "oxili_gfx3d_clk",
+ .parent = &oxili_gfx3d_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(oxili_gfx3d_clk.c),
+ },
+};
+
+static struct branch_clk oxilicx_ahb_clk = {
+ .cbcr_reg = OXILICX_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "oxilicx_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(oxilicx_ahb_clk.c),
+ },
+};
+
+static struct branch_clk venus0_ahb_clk = {
+ .cbcr_reg = VENUS0_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "venus0_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(venus0_ahb_clk.c),
+ },
+};
+
+static struct branch_clk venus0_axi_clk = {
+ .cbcr_reg = VENUS0_AXI_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "venus0_axi_clk",
+ .parent = &axi_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(venus0_axi_clk.c),
+ },
+};
+
+static struct branch_clk venus0_ocmemnoc_clk = {
+ .cbcr_reg = VENUS0_OCMEMNOC_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "venus0_ocmemnoc_clk",
+ .parent = &ocmemnoc_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(venus0_ocmemnoc_clk.c),
+ },
+};
+
+static struct branch_clk venus0_vcodec0_clk = {
+ .cbcr_reg = VENUS0_VCODEC0_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "venus0_vcodec0_clk",
+ .parent = &vcodec0_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(venus0_vcodec0_clk.c),
+ },
+};
+
+#ifdef CONFIG_DEBUG_FS
+enum {
+ M_ACPU0 = 0,
+ M_ACPU1,
+ M_ACPU2,
+ M_ACPU3,
+ M_L2,
+};
+
+struct measure_mux_entry {
+ struct clk *c;
+ int base;
+ u32 debug_mux;
+};
+
+static struct measure_mux_entry measure_mux[] = {
+ {&snoc.c, GCC_BASE, 0x0000},
+ {&cnoc.c, GCC_BASE, 0x0008},
+ {&pnoc.c, GCC_BASE, 0x0010},
+ {&bimc.c, GCC_BASE, 0x0155},
+ {&bimc_gpu.c, GCC_BASE, 0x015c},
+ {&mmssnoc_ahb.c, MMSS_BASE, 0x0001},
+
+ {&gcc_mss_cfg_ahb_clk.c, GCC_BASE, 0x0030},
+ {&gcc_mss_q6_bimc_axi_clk.c, GCC_BASE, 0x0031},
+ {&gcc_usb_hs_system_clk.c, GCC_BASE, 0x0060},
+ {&gcc_usb_hs_ahb_clk.c, GCC_BASE, 0x0061},
+ {&gcc_usb2a_phy_sleep_clk.c, GCC_BASE, 0x0063},
+ {&gcc_sdcc1_apps_clk.c, GCC_BASE, 0x0068},
+ {&gcc_sdcc1_ahb_clk.c, GCC_BASE, 0x0069},
+ {&gcc_sdcc1_cdccal_sleep_clk.c, GCC_BASE, 0x006a},
+ {&gcc_sdcc1_cdccal_ff_clk.c, GCC_BASE, 0x006b},
+ {&gcc_sdcc2_apps_clk.c, GCC_BASE, 0x0070},
+ {&gcc_sdcc2_ahb_clk.c, GCC_BASE, 0x0071},
+ {&gcc_sdcc3_apps_clk.c, GCC_BASE, 0x0078},
+ {&gcc_sdcc3_ahb_clk.c, GCC_BASE, 0x0079},
+ {&gcc_sdcc4_apps_clk.c, GCC_BASE, 0x0080},
+ {&gcc_sdcc4_ahb_clk.c, GCC_BASE, 0x0081},
+ {&gcc_blsp1_ahb_clk.c, GCC_BASE, 0x0088},
+ {&gcc_blsp1_qup1_spi_apps_clk.c, GCC_BASE, 0x008a},
+ {&gcc_blsp1_qup1_i2c_apps_clk.c, GCC_BASE, 0x008b},
+ {&gcc_blsp1_uart1_apps_clk.c, GCC_BASE, 0x008c},
+ {&gcc_blsp1_qup2_spi_apps_clk.c, GCC_BASE, 0x008e},
+ {&gcc_blsp1_qup2_i2c_apps_clk.c, GCC_BASE, 0x0090},
+ {&gcc_blsp1_uart2_apps_clk.c, GCC_BASE, 0x0091},
+ {&gcc_blsp1_qup3_spi_apps_clk.c, GCC_BASE, 0x0093},
+ {&gcc_blsp1_qup3_i2c_apps_clk.c, GCC_BASE, 0x0094},
+ {&gcc_blsp1_uart3_apps_clk.c, GCC_BASE, 0x0095},
+ {&gcc_blsp1_qup4_spi_apps_clk.c, GCC_BASE, 0x0098},
+ {&gcc_blsp1_qup4_i2c_apps_clk.c, GCC_BASE, 0x0099},
+ {&gcc_blsp1_uart4_apps_clk.c, GCC_BASE, 0x009a},
+ {&gcc_blsp2_ahb_clk.c, GCC_BASE, 0x00a8},
+ {&gcc_blsp2_qup1_spi_apps_clk.c, GCC_BASE, 0x00aa},
+ {&gcc_blsp2_qup1_i2c_apps_clk.c, GCC_BASE, 0x00ab},
+ {&gcc_blsp2_uart1_apps_clk.c, GCC_BASE, 0x00ac},
+ {&gcc_blsp2_qup2_spi_apps_clk.c, GCC_BASE, 0x00ae},
+ {&gcc_blsp2_qup2_i2c_apps_clk.c, GCC_BASE, 0x00b0},
+ {&gcc_blsp2_uart2_apps_clk.c, GCC_BASE, 0x00b1},
+ {&gcc_blsp2_qup3_spi_apps_clk.c, GCC_BASE, 0x00b3},
+ {&gcc_blsp2_qup3_i2c_apps_clk.c, GCC_BASE, 0x00b4},
+ {&gcc_blsp2_uart3_apps_clk.c, GCC_BASE, 0x00b5},
+ {&gcc_blsp2_qup4_spi_apps_clk.c, GCC_BASE, 0x00b8},
+ {&gcc_blsp2_qup4_i2c_apps_clk.c, GCC_BASE, 0x00b9},
+ {&gcc_blsp2_uart4_apps_clk.c, GCC_BASE, 0x00ba},
+ {&gcc_pdm_ahb_clk.c, GCC_BASE, 0x00d0},
+ {&gcc_pdm2_clk.c, GCC_BASE, 0x00d2},
+ {&gcc_prng_ahb_clk.c, GCC_BASE, 0x00d8},
+ {&gcc_bam_dma_ahb_clk.c, GCC_BASE, 0x00e0},
+ {&gcc_tsif_ahb_clk.c, GCC_BASE, 0x00e8},
+ {&gcc_tsif_ref_clk.c, GCC_BASE, 0x00e9},
+ {&gcc_boot_rom_ahb_clk.c, GCC_BASE, 0x00f8},
+ {&gcc_ce1_clk.c, GCC_BASE, 0x0138},
+ {&gcc_ce1_axi_clk.c, GCC_BASE, 0x0139},
+ {&gcc_ce1_ahb_clk.c, GCC_BASE, 0x013a},
+ {&gcc_lpass_q6_axi_clk.c, GCC_BASE, 0x0160},
+ {&gcc_lpass_sys_noc_mport_clk.c, GCC_BASE, 0x0162},
+ {&gcc_lpass_sys_noc_sway_clk.c, GCC_BASE, 0x0163},
+
+ {&mmss_misc_ahb_clk.c, MMSS_BASE, 0x0003},
+ {&mmss_mmssnoc_axi_clk.c, MMSS_BASE, 0x0004},
+ {&mmss_s0_axi_clk.c, MMSS_BASE, 0x0005},
+ {&ocmemcx_ocmemnoc_clk.c, MMSS_BASE, 0x0007},
+ {&oxilicx_ahb_clk.c, MMSS_BASE, 0x000a},
+ {&oxili_gfx3d_clk.c, MMSS_BASE, 0x000b},
+ {&venus0_vcodec0_clk.c, MMSS_BASE, 0x000c},
+ {&venus0_axi_clk.c, MMSS_BASE, 0x000d},
+ {&venus0_ocmemnoc_clk.c, MMSS_BASE, 0x000e},
+ {&venus0_ahb_clk.c, MMSS_BASE, 0x000f},
+ {&mdss_mdp_clk.c, MMSS_BASE, 0x0012},
+ {&mdss_mdp_lut_clk.c, MMSS_BASE, 0x0013},
+ {&mdss_pclk0_clk.c, MMSS_BASE, 0x0014},
+ {&mdss_vsync_clk.c, MMSS_BASE, 0x0015},
+ {&mdss_byte0_clk.c, MMSS_BASE, 0x0016},
+ {&mdss_esc0_clk.c, MMSS_BASE, 0x0017},
+ {&mdss_ahb_clk.c, MMSS_BASE, 0x0018},
+ {&mdss_axi_clk.c, MMSS_BASE, 0x0019},
+ {&camss_top_ahb_clk.c, MMSS_BASE, 0x001a},
+ {&camss_micro_ahb_clk.c, MMSS_BASE, 0x001b},
+ {&camss_gp0_clk.c, MMSS_BASE, 0x001c},
+ {&camss_gp1_clk.c, MMSS_BASE, 0x001d},
+ {&camss_mclk0_clk.c, MMSS_BASE, 0x001e},
+ {&camss_mclk1_clk.c, MMSS_BASE, 0x001f},
+ {&camss_mclk2_clk.c, MMSS_BASE, 0x0020},
+ {&camss_cci_cci_clk.c, MMSS_BASE, 0x0021},
+ {&camss_cci_cci_ahb_clk.c, MMSS_BASE, 0x0022},
+ {&camss_phy0_csi0phytimer_clk.c, MMSS_BASE, 0x0023},
+ {&camss_phy1_csi1phytimer_clk.c, MMSS_BASE, 0x0024},
+ {&camss_jpeg_jpeg0_clk.c, MMSS_BASE, 0x0025},
+ {&camss_jpeg_jpeg_ahb_clk.c, MMSS_BASE, 0x0026},
+ {&camss_jpeg_jpeg_axi_clk.c, MMSS_BASE, 0x0027},
+ {&camss_vfe_vfe0_clk.c, MMSS_BASE, 0x0028},
+ {&camss_vfe_cpp_clk.c, MMSS_BASE, 0x0029},
+ {&camss_vfe_cpp_ahb_clk.c, MMSS_BASE, 0x002a},
+ {&camss_vfe_vfe_ahb_clk.c, MMSS_BASE, 0x002b},
+ {&camss_vfe_vfe_axi_clk.c, MMSS_BASE, 0x002c},
+ {&camss_ispif_ahb_clk.c, MMSS_BASE, 0x002d},
+ {&camss_csi_vfe0_clk.c, MMSS_BASE, 0x002e},
+ {&camss_csi0_clk.c, MMSS_BASE, 0x002f},
+ {&camss_csi0_ahb_clk.c, MMSS_BASE, 0x0030},
+ {&camss_csi0phy_clk.c, MMSS_BASE, 0x0031},
+ {&camss_csi0rdi_clk.c, MMSS_BASE, 0x0032},
+ {&camss_csi0pix_clk.c, MMSS_BASE, 0x0033},
+ {&camss_csi1_clk.c, MMSS_BASE, 0x0034},
+ {&camss_csi1_ahb_clk.c, MMSS_BASE, 0x0035},
+ {&camss_csi1phy_clk.c, MMSS_BASE, 0x0036},
+ {&camss_csi1rdi_clk.c, MMSS_BASE, 0x0037},
+ {&camss_csi1pix_clk.c, MMSS_BASE, 0x0038},
+ {&camss_csi2_clk.c, MMSS_BASE, 0x0039},
+ {&camss_csi2_ahb_clk.c, MMSS_BASE, 0x003a},
+ {&camss_csi2phy_clk.c, MMSS_BASE, 0x003b},
+ {&camss_csi2rdi_clk.c, MMSS_BASE, 0x003c},
+ {&camss_csi2pix_clk.c, MMSS_BASE, 0x003d},
+ {&camss_csi_vfe1_clk.c, MMSS_BASE, 0x0053},
+ {&camss_vfe_vfe1_clk.c, MMSS_BASE, 0x0055},
+ {&camss_ahb_clk.c, MMSS_BASE, 0x0056},
+
+ {&krait0_clk.c, APCS_BASE, M_ACPU0},
+ {&krait1_clk.c, APCS_BASE, M_ACPU1},
+ {&krait2_clk.c, APCS_BASE, M_ACPU2},
+ {&krait3_clk.c, APCS_BASE, M_ACPU3},
+ {&l2_clk.c, APCS_BASE, M_L2},
+
+ {&dummy_clk, N_BASES, 0x0000},
+};
+
+static int measure_clk_set_parent(struct clk *c, struct clk *parent)
+{
+ struct measure_clk *clk = to_measure_clk(c);
+ unsigned long flags;
+ u32 regval, clk_sel, i;
+
+ if (!parent)
+ return -EINVAL;
+
+ for (i = 0; i < (ARRAY_SIZE(measure_mux) - 1); i++)
+ if (measure_mux[i].c == parent)
+ break;
+
+ if (measure_mux[i].c == &dummy_clk)
+ return -EINVAL;
+
+ spin_lock_irqsave(&local_clock_reg_lock, flags);
+ /*
+ * Program the test vector, measurement period (sample_ticks)
+ * and scaling multiplier.
+ */
+ clk->sample_ticks = 0x10000;
+ clk->multiplier = 1;
+
+ switch (measure_mux[i].base) {
+
+ case GCC_BASE:
+ writel_relaxed(0, GCC_REG_BASE(GCC_DEBUG_CLK_CTL));
+ clk_sel = measure_mux[i].debug_mux;
+ break;
+
+ case MMSS_BASE:
+ writel_relaxed(0, MMSS_REG_BASE(MMSS_DEBUG_CLK_CTL));
+ clk_sel = 0x02C;
+ regval = BVAL(11, 0, measure_mux[i].debug_mux);
+ writel_relaxed(regval, MMSS_REG_BASE(MMSS_DEBUG_CLK_CTL));
+
+ /* Activate debug clock output */
+ regval |= BIT(16);
+ writel_relaxed(regval, MMSS_REG_BASE(MMSS_DEBUG_CLK_CTL));
+ break;
+
+ case LPASS_BASE:
+ writel_relaxed(0, LPASS_REG_BASE(LPASS_DBG_CLK));
+ clk_sel = 0x161;
+ regval = BVAL(11, 0, measure_mux[i].debug_mux);
+ writel_relaxed(regval, LPASS_REG_BASE(LPASS_DBG_CLK));
+
+ /* Activate debug clock output */
+ regval |= BIT(20);
+ writel_relaxed(regval, LPASS_REG_BASE(LPASS_DBG_CLK));
+ break;
+
+ case APCS_BASE:
+ clk->multiplier = 4;
+ clk_sel = 0x16A;
+
+ if (measure_mux[i].debug_mux == M_L2)
+ regval = BIT(12);
+ else
+ regval = measure_mux[i].debug_mux << 8;
+ writel_relaxed(BIT(0), APCS_REG_BASE(L2_CBCR));
+ writel_relaxed(regval, APCS_REG_BASE(GLB_CLK_DIAG));
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ /* Set debug mux clock index */
+ regval = BVAL(8, 0, clk_sel);
+ writel_relaxed(regval, GCC_REG_BASE(GCC_DEBUG_CLK_CTL));
+
+ /* Activate debug clock output */
+ regval |= BIT(16);
+ writel_relaxed(regval, GCC_REG_BASE(GCC_DEBUG_CLK_CTL));
+
+ /* Make sure test vector is set before starting measurements. */
+ mb();
+ spin_unlock_irqrestore(&local_clock_reg_lock, flags);
+
+ return 0;
+}
+
+/* Sample clock for 'ticks' reference clock ticks. */
+static u32 run_measurement(unsigned ticks)
+{
+ /* Stop counters and set the XO4 counter start value. */
+ writel_relaxed(ticks, GCC_REG_BASE(CLOCK_FRQ_MEASURE_CTL));
+
+ /* Wait for timer to become ready. */
+ while ((readl_relaxed(GCC_REG_BASE(CLOCK_FRQ_MEASURE_STATUS)) &
+ BIT(25)) != 0)
+ cpu_relax();
+
+ /* Run measurement and wait for completion. */
+ writel_relaxed(BIT(20)|ticks, GCC_REG_BASE(CLOCK_FRQ_MEASURE_CTL));
+ while ((readl_relaxed(GCC_REG_BASE(CLOCK_FRQ_MEASURE_STATUS)) &
+ BIT(25)) == 0)
+ cpu_relax();
+
+ /* Return measured ticks. */
+ return readl_relaxed(GCC_REG_BASE(CLOCK_FRQ_MEASURE_STATUS)) &
+ BM(24, 0);
+}
+
+/*
+ * Perform a hardware rate measurement for a given clock.
+ * FOR DEBUG USE ONLY: Measurements take ~15 ms!
+ */
+static unsigned long measure_clk_get_rate(struct clk *c)
+{
+ unsigned long flags;
+ u32 gcc_xo4_reg_backup;
+ u64 raw_count_short, raw_count_full;
+ struct measure_clk *clk = to_measure_clk(c);
+ unsigned ret;
+
+ ret = clk_prepare_enable(&xo.c);
+ if (ret) {
+ pr_warn("CXO clock failed to enable. Can't measure\n");
+ return 0;
+ }
+
+ spin_lock_irqsave(&local_clock_reg_lock, flags);
+
+ /* Enable CXO/4 and RINGOSC branch. */
+ gcc_xo4_reg_backup = readl_relaxed(GCC_REG_BASE(GCC_XO_DIV4_CBCR));
+ writel_relaxed(0x1, GCC_REG_BASE(GCC_XO_DIV4_CBCR));
+
+ /*
+ * The ring oscillator counter will not reset if the measured clock
+ * is not running. To detect this, run a short measurement before
+ * the full measurement. If the raw results of the two are the same
+ * then the clock must be off.
+ */
+
+ /* Run a short measurement. (~1 ms) */
+ raw_count_short = run_measurement(0x1000);
+ /* Run a full measurement. (~14 ms) */
+ raw_count_full = run_measurement(clk->sample_ticks);
+
+ writel_relaxed(gcc_xo4_reg_backup, GCC_REG_BASE(GCC_XO_DIV4_CBCR));
+
+ /* Return 0 if the clock is off. */
+ if (raw_count_full == raw_count_short) {
+ ret = 0;
+ } else {
+ /* Compute rate in Hz. */
+ raw_count_full = ((raw_count_full * 10) + 15) * 4800000;
+ do_div(raw_count_full, ((clk->sample_ticks * 10) + 35));
+ ret = (raw_count_full * clk->multiplier);
+ }
+
+ writel_relaxed(0x51A00, GCC_REG_BASE(PLLTEST_PAD_CFG));
+ spin_unlock_irqrestore(&local_clock_reg_lock, flags);
+
+ clk_disable_unprepare(&xo.c);
+
+ return ret;
+}
+#else /* !CONFIG_DEBUG_FS */
+static int measure_clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ return -EINVAL;
+}
+
+static unsigned long measure_clk_get_rate(struct clk *clk)
+{
+ return 0;
+}
+#endif /* CONFIG_DEBUG_FS */
+
+static struct clk_ops clk_ops_measure = {
+ .set_parent = measure_clk_set_parent,
+ .get_rate = measure_clk_get_rate,
+};
+
+static struct measure_clk measure_clk = {
+ .c = {
+ .dbg_name = "measure_clk",
+ .ops = &clk_ops_measure,
+ CLK_INIT(measure_clk.c),
+ },
+ .multiplier = 1,
+};
+
+static struct clk_lookup msm_clocks_samarium_rumi[] = {
+ CLK_DUMMY("xo", cxo_pil_lpass_clk, "fe200000.qcom,lpass", OFF),
+ CLK_DUMMY("core_clk", q6ss_xo_clk, "fe200000.qcom,lpass", OFF),
+ CLK_DUMMY("bus_clk", gcc_lpass_q6_axi_clk, "fe200000.qcom,lpass", OFF),
+ CLK_DUMMY("iface_clk", q6ss_ahb_lfabif_clk, "fe200000.qcom,lpass", OFF),
+ CLK_DUMMY("reg_clk", q6ss_ahbm_clk, "fe200000.qcom,lpass", OFF),
+
+ CLK_DUMMY("core_clk", venus_vcodec0_clk, "fdce0000.qcom,venus", OFF),
+ CLK_DUMMY("iface_clk", venus_ahb_clk, "fdce0000.qcom,venus", OFF),
+ CLK_DUMMY("bus_clk", venus_axi_clk, "fdce0000.qcom,venus", OFF),
+ CLK_DUMMY("mem_clk", venus_ocmemnoc_clk, "fdce0000.qcom,venus", OFF),
+ CLK_DUMMY("core_clk", venus_vcodec0_clk, "fd8c1024.qcom,gdsc", OFF),
+
+ CLK_DUMMY("xo", CXO_CLK, "fc880000.qcom,mss", OFF),
+ CLK_DUMMY("bus_clk", MSS_BIMC_Q6_CLK, "fc880000.qcom,mss", OFF),
+ CLK_DUMMY("iface_clk", MSS_CFG_AHB_CLK, "fc880000.qcom,mss", OFF),
+ CLK_DUMMY("mem_clk", BOOT_ROM_AHB_CLK, "fc880000.qcom,mss", OFF),
+ CLK_DUMMY("xo", XO_CLK, "fb21b000.qcom,pronto", OFF),
+ CLK_DUMMY("core_clk", BLSP1_UART_CLK, "f991f000.serial", OFF),
+ CLK_DUMMY("iface_clk", BLSP1_UART_CLK, "f991f000.serial", OFF),
+ CLK_DUMMY("core_clk", BLSP1_UART_CLK, "f991e000.serial", OFF),
+ CLK_DUMMY("iface_clk", BLSP1_UART_CLK, "f991e000.serial", OFF),
+ CLK_DUMMY("core_clk", SDC1_CLK, "msm_sdcc.1", OFF),
+ CLK_DUMMY("iface_clk", SDC1_P_CLK, "msm_sdcc.1", OFF),
+ CLK_DUMMY("core_clk", SDC2_CLK, "msm_sdcc.2", OFF),
+ CLK_DUMMY("iface_clk", SDC2_P_CLK, "msm_sdcc.2", OFF),
+ CLK_DUMMY("core_clk", USB_HS_SYSTEM_CLK, "msm_otg", OFF),
+ CLK_DUMMY("iface_clk", USB_HS_AHB_CLK, "msm_otg", OFF),
+ CLK_DUMMY("xo", CXO_OTG_CLK, "msm_otg", OFF),
+ CLK_DUMMY("dfab_clk", DFAB_CLK, "msm_sps", OFF),
+ CLK_DUMMY("dma_bam_pclk", DMA_BAM_P_CLK, "msm_sps", OFF),
+ CLK_DUMMY("core_clk", SPI_CLK, "spi_qsd.1", OFF),
+ CLK_DUMMY("iface_clk", SPI_P_CLK, "spi_qsd.1", OFF),
+ CLK_DUMMY("core_clk", gcc_prng_ahb_clk.c, "f9bff000.qcom,msm-rng", OFF),
+ CLK_DUMMY("core_clk", I2C_CLK, "f9924000.i2c", OFF),
+ CLK_DUMMY("iface_clk", I2C_P_CLK, "f9924000.i2c", OFF),
+
+ /* CoreSight clocks */
+ CLK_DUMMY("core_clk", qdss_clk.c, "fc326000.tmc", OFF),
+ CLK_DUMMY("core_clk", qdss_clk.c, "fc320000.tpiu", OFF),
+ CLK_DUMMY("core_clk", qdss_clk.c, "fc324000.replicator", OFF),
+ CLK_DUMMY("core_clk", qdss_clk.c, "fc325000.tmc", OFF),
+ CLK_DUMMY("core_clk", qdss_clk.c, "fc323000.funnel", OFF),
+ CLK_DUMMY("core_clk", qdss_clk.c, "fc321000.funnel", OFF),
+ CLK_DUMMY("core_clk", qdss_clk.c, "fc322000.funnel", OFF),
+ CLK_DUMMY("core_clk", qdss_clk.c, "fc355000.funnel", OFF),
+ CLK_DUMMY("core_clk", qdss_clk.c, "fc36c000.funnel", OFF),
+ CLK_DUMMY("core_clk", qdss_clk.c, "fc302000.stm", OFF),
+ CLK_DUMMY("core_clk", qdss_clk.c, "fc34c000.etm", OFF),
+ CLK_DUMMY("core_clk", qdss_clk.c, "fc34d000.etm", OFF),
+ CLK_DUMMY("core_clk", qdss_clk.c, "fc34e000.etm", OFF),
+ CLK_DUMMY("core_clk", qdss_clk.c, "fc34f000.etm", OFF),
+ CLK_DUMMY("core_clk", qdss_clk.c, "fc310000.cti", OFF),
+ CLK_DUMMY("core_clk", qdss_clk.c, "fc311000.cti", OFF),
+ CLK_DUMMY("core_clk", qdss_clk.c, "fc312000.cti", OFF),
+ CLK_DUMMY("core_clk", qdss_clk.c, "fc313000.cti", OFF),
+ CLK_DUMMY("core_clk", qdss_clk.c, "fc314000.cti", OFF),
+ CLK_DUMMY("core_clk", qdss_clk.c, "fc315000.cti", OFF),
+ CLK_DUMMY("core_clk", qdss_clk.c, "fc316000.cti", OFF),
+ CLK_DUMMY("core_clk", qdss_clk.c, "fc317000.cti", OFF),
+ CLK_DUMMY("core_clk", qdss_clk.c, "fc318000.cti", OFF),
+ CLK_DUMMY("core_clk", qdss_clk.c, "fc351000.cti", OFF),
+ CLK_DUMMY("core_clk", qdss_clk.c, "fc352000.cti", OFF),
+ CLK_DUMMY("core_clk", qdss_clk.c, "fc353000.cti", OFF),
+ CLK_DUMMY("core_clk", qdss_clk.c, "fc354000.cti", OFF),
+ CLK_DUMMY("core_clk", qdss_clk.c, "fc350000.cti", OFF),
+ CLK_DUMMY("core_clk", qdss_clk.c, "fc330000.cti", OFF),
+ CLK_DUMMY("core_clk", qdss_clk.c, "fc33c000.cti", OFF),
+ CLK_DUMMY("core_clk", qdss_clk.c, "fc360000.cti", OFF),
+ CLK_DUMMY("core_clk", qdss_clk.c, "fc330000.cti", OFF),
+ CLK_DUMMY("core_clk", qdss_clk.c, "fc33c000.cti", OFF),
+ CLK_DUMMY("core_clk", qdss_clk.c, "fc360000.cti", OFF),
+ CLK_DUMMY("core_clk", qdss_clk.c, "fd828018.hwevent", OFF),
+
+ CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc326000.tmc", OFF),
+ CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc320000.tpiu", OFF),
+ CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc324000.replicator", OFF),
+ CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc325000.tmc", OFF),
+ CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc323000.funnel", OFF),
+ CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc321000.funnel", OFF),
+ CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc322000.funnel", OFF),
+ CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc355000.funnel", OFF),
+ CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc36c000.funnel", OFF),
+ CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc302000.stm", OFF),
+ CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc34c000.etm", OFF),
+ CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc34d000.etm", OFF),
+ CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc34e000.etm", OFF),
+ CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc34f000.etm", OFF),
+ CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc310000.cti", OFF),
+ CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc311000.cti", OFF),
+ CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc312000.cti", OFF),
+ CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc313000.cti", OFF),
+ CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc314000.cti", OFF),
+ CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc315000.cti", OFF),
+ CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc316000.cti", OFF),
+ CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc317000.cti", OFF),
+ CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc318000.cti", OFF),
+ CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc351000.cti", OFF),
+ CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc352000.cti", OFF),
+ CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc353000.cti", OFF),
+ CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc354000.cti", OFF),
+ CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc350000.cti", OFF),
+ CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc330000.cti", OFF),
+ CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc33c000.cti", OFF),
+ CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc360000.cti", OFF),
+ CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc330000.cti", OFF),
+ CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc33c000.cti", OFF),
+ CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc360000.cti", OFF),
+ CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fd828018.hwevent", OFF),
+
+ CLK_DUMMY("core_mmss_clk", mmss_misc_ahb_clk.c, "fd828018.hwevent",
+ OFF),
+ CLK_DUMMY("core_clk", gcc_ce1_clk.c, "qseecom", OFF),
+ CLK_DUMMY("iface_clk", gcc_ce1_ahb_clk.c, "qseecom", OFF),
+ CLK_DUMMY("bus_clk", gcc_ce1_axi_clk.c, "qseecom", OFF),
+ CLK_DUMMY("core_clk_src", qseecom_ce1_clk_src.c, "qseecom", OFF),
+};
+
+static struct clk_lookup msm_clocks_samarium[] = {
+ /* XO and PLL */
+ CLK_LOOKUP("", xo.c, ""),
+ CLK_LOOKUP("hfpll_src", xo_a_clk.c, "f9016000.qcom,clock-krait"),
+ CLK_LOOKUP("", gpll0.c, ""),
+ CLK_LOOKUP("aux_clk", gpll0_ao.c, "f9016000.qcom,clock-krait"),
+ CLK_LOOKUP("", gpll4.c, ""),
+ CLK_LOOKUP("", mmpll0.c, ""),
+ CLK_LOOKUP("", mmpll1.c, ""),
+ CLK_LOOKUP("", mmpll3.c, ""),
+ CLK_LOOKUP("", mmpll4.c, ""),
+
+ /* measure */
+ CLK_LOOKUP("measure", measure_clk.c, "debug"),
+
+ /* RPM and voter */
+ CLK_LOOKUP("xo", xo_otg_clk.c, "msm_otg"),
+ CLK_LOOKUP("xo", xo_pil_lpass_clk.c, "fe200000.qcom,lpass"),
+ CLK_LOOKUP("xo", xo_pil_mss_clk.c, "fc880000.qcom,mss"),
+ CLK_LOOKUP("xo", xo_wlan_clk.c, "fb000000.qcom,wcnss-wlan"),
+ CLK_LOOKUP("rf_clk", rf_clk3.c, "fb000000.qcom,wcnss-wlan"),
+ CLK_LOOKUP("xo", xo_pil_pronto_clk.c, "fb21b000.qcom,pronto"),
+ CLK_LOOKUP("xo", xo_ehci_host_clk.c, "msm_ehci_host"),
+ CLK_LOOKUP("xo", xo_lpm_clk.c, "fc4281d0.qcom,mpm"),
+
+ CLK_LOOKUP("", bb_clk1.c, ""),
+ CLK_LOOKUP("", bb_clk1_a.c, ""),
+ CLK_LOOKUP("", bb_clk2.c, ""),
+ CLK_LOOKUP("", bb_clk2_a.c, ""),
+ CLK_LOOKUP("", rf_clk1.c, ""),
+ CLK_LOOKUP("", rf_clk1_a.c, ""),
+ CLK_LOOKUP("", rf_clk2.c, ""),
+ CLK_LOOKUP("", rf_clk2_a.c, ""),
+ CLK_LOOKUP("", rf_clk3_a.c, ""),
+ CLK_LOOKUP("", div_clk1.c, ""),
+ CLK_LOOKUP("", div_clk1_a.c, ""),
+ CLK_LOOKUP("", div_clk2.c, ""),
+ CLK_LOOKUP("", div_clk2_a.c, ""),
+ CLK_LOOKUP("", div_clk3.c, ""),
+ CLK_LOOKUP("", div_clk3_a.c, ""),
+ CLK_LOOKUP("", diff_clk1.c, ""),
+ CLK_LOOKUP("", diff_clk1_a.c, ""),
+ CLK_LOOKUP("", bb_clk1_pin.c, ""),
+ CLK_LOOKUP("", bb_clk1_a_pin.c, ""),
+ CLK_LOOKUP("", bb_clk2_pin.c, ""),
+ CLK_LOOKUP("ref_clk", bb_clk2_a_pin.c, "3-000e"),
+ CLK_LOOKUP("", rf_clk1_pin.c, ""),
+ CLK_LOOKUP("", rf_clk1_a_pin.c, ""),
+ CLK_LOOKUP("", rf_clk2_pin.c, ""),
+ CLK_LOOKUP("", rf_clk2_a_pin.c, ""),
+ CLK_LOOKUP("", rf_clk3_pin.c, ""),
+ CLK_LOOKUP("", rf_clk3_a_pin.c, ""),
+ CLK_LOOKUP("", cnoc.c, ""),
+ CLK_LOOKUP("", cnoc_a_clk.c, ""),
+ CLK_LOOKUP("", pnoc.c, ""),
+ CLK_LOOKUP("", pnoc_a_clk.c, ""),
+ CLK_LOOKUP("dfab_clk", pnoc_sps_clk.c, "msm_sps"),
+ CLK_LOOKUP("", snoc.c, ""),
+ CLK_LOOKUP("", snoc_a_clk.c, ""),
+ CLK_LOOKUP("", bimc.c, ""),
+ CLK_LOOKUP("", bimc_a_clk.c, ""),
+ CLK_LOOKUP("", bimc_gpu.c, ""),
+ CLK_LOOKUP("", pnoc_keepalive_a_clk.c, ""),
+ CLK_LOOKUP("", mmssnoc_ahb.c, ""),
+ CLK_LOOKUP("", mmssnoc_ahb_a_clk.c, ""),
+
+ /* Bus driver */
+ CLK_LOOKUP("bus_clk", cnoc_msmbus_clk.c, "msm_config_noc"),
+ CLK_LOOKUP("bus_a_clk", cnoc_msmbus_a_clk.c, "msm_config_noc"),
+ CLK_LOOKUP("bus_clk", snoc_msmbus_clk.c, "msm_sys_noc"),
+ CLK_LOOKUP("bus_a_clk", snoc_msmbus_a_clk.c, "msm_sys_noc"),
+ CLK_LOOKUP("bus_clk", pnoc_msmbus_clk.c, "msm_periph_noc"),
+ CLK_LOOKUP("bus_a_clk", pnoc_msmbus_a_clk.c, "msm_periph_noc"),
+ CLK_LOOKUP("mem_clk", bimc_msmbus_clk.c, "msm_bimc"),
+ CLK_LOOKUP("mem_a_clk", bimc_msmbus_a_clk.c, "msm_bimc"),
+ CLK_LOOKUP("ocmem_clk", ocmemgx_msmbus_clk.c, "msm_bus"),
+ CLK_LOOKUP("ocmem_a_clk", ocmemgx_msmbus_a_clk.c, "msm_bus"),
+ CLK_LOOKUP("bus_clk", mmss_s0_axi_clk.c, "msm_mmss_noc"),
+ CLK_LOOKUP("bus_a_clk", mmss_s0_axi_clk.c, "msm_mmss_noc"),
+
+ /* CoreSight clocks */
+ CLK_LOOKUP("core_clk", qdss.c, "fc326000.tmc"),
+ CLK_LOOKUP("core_clk", qdss.c, "fc320000.tpiu"),
+ CLK_LOOKUP("core_clk", qdss.c, "fc324000.replicator"),
+ CLK_LOOKUP("core_clk", qdss.c, "fc325000.tmc"),
+ CLK_LOOKUP("core_clk", qdss.c, "fc323000.funnel"),
+ CLK_LOOKUP("core_clk", qdss.c, "fc321000.funnel"),
+ CLK_LOOKUP("core_clk", qdss.c, "fc322000.funnel"),
+ CLK_LOOKUP("core_clk", qdss.c, "fc355000.funnel"),
+ CLK_LOOKUP("core_clk", qdss.c, "fc36c000.funnel"),
+ CLK_LOOKUP("core_clk", qdss.c, "fc302000.stm"),
+ CLK_LOOKUP("core_clk", qdss.c, "fc34c000.etm"),
+ CLK_LOOKUP("core_clk", qdss.c, "fc34d000.etm"),
+ CLK_LOOKUP("core_clk", qdss.c, "fc34e000.etm"),
+ CLK_LOOKUP("core_clk", qdss.c, "fc34f000.etm"),
+ CLK_LOOKUP("core_clk", qdss.c, "fc310000.cti"),
+ CLK_LOOKUP("core_clk", qdss.c, "fc311000.cti"),
+ CLK_LOOKUP("core_clk", qdss.c, "fc312000.cti"),
+ CLK_LOOKUP("core_clk", qdss.c, "fc313000.cti"),
+ CLK_LOOKUP("core_clk", qdss.c, "fc314000.cti"),
+ CLK_LOOKUP("core_clk", qdss.c, "fc315000.cti"),
+ CLK_LOOKUP("core_clk", qdss.c, "fc316000.cti"),
+ CLK_LOOKUP("core_clk", qdss.c, "fc317000.cti"),
+ CLK_LOOKUP("core_clk", qdss.c, "fc318000.cti"),
+ CLK_LOOKUP("core_clk", qdss.c, "fc351000.cti"),
+ CLK_LOOKUP("core_clk", qdss.c, "fc352000.cti"),
+ CLK_LOOKUP("core_clk", qdss.c, "fc353000.cti"),
+ CLK_LOOKUP("core_clk", qdss.c, "fc354000.cti"),
+ CLK_LOOKUP("core_clk", qdss.c, "fc350000.cti"),
+ CLK_LOOKUP("core_clk", qdss.c, "fc330000.cti"),
+ CLK_LOOKUP("core_clk", qdss.c, "fc33c000.cti"),
+ CLK_LOOKUP("core_clk", qdss.c, "fc360000.cti"),
+ CLK_LOOKUP("core_clk", qdss.c, "fd828018.hwevent"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc326000.tmc"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc320000.tpiu"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc324000.replicator"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc325000.tmc"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc323000.funnel"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc321000.funnel"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc322000.funnel"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc355000.funnel"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc36c000.funnel"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc302000.stm"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc34c000.etm"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc34d000.etm"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc34e000.etm"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc34f000.etm"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc310000.cti"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc311000.cti"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc312000.cti"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc313000.cti"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc314000.cti"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc315000.cti"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc316000.cti"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc317000.cti"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc318000.cti"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc351000.cti"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc352000.cti"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc353000.cti"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc354000.cti"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc350000.cti"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc330000.cti"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc33c000.cti"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc360000.cti"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fd828018.hwevent"),
+
+ CLK_LOOKUP("osr_clk", div_clk1.c, "msm-dai-q6-dev.16384"),
+
+ /* BLSP */
+ CLK_LOOKUP("iface_clk", gcc_blsp1_ahb_clk.c, "f991f000.serial"),
+ CLK_LOOKUP("iface_clk", gcc_blsp1_ahb_clk.c, "f9924000.i2c"),
+ CLK_LOOKUP("iface_clk", gcc_blsp1_ahb_clk.c, "f991e000.serial"),
+ CLK_LOOKUP("iface_clk", gcc_blsp1_ahb_clk.c, "f9923000.i2c"),
+ CLK_LOOKUP("core_clk", gcc_blsp1_qup1_i2c_apps_clk.c, "f9923000.i2c"),
+ CLK_LOOKUP("iface_clk", gcc_blsp2_ahb_clk.c, "f9963000.i2c"),
+ CLK_LOOKUP("core_clk", gcc_blsp2_qup1_i2c_apps_clk.c, "f9963000.i2c"),
+ CLK_LOOKUP("iface_clk", gcc_blsp2_ahb_clk.c, "f9964000.i2c"),
+ CLK_LOOKUP("core_clk", gcc_blsp2_qup2_i2c_apps_clk.c, "f9964000.i2c"),
+ CLK_LOOKUP("", gcc_blsp1_qup1_spi_apps_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_blsp1_qup2_i2c_apps_clk.c, "f9924000.i2c"),
+ CLK_LOOKUP("", gcc_blsp1_qup2_spi_apps_clk.c, ""),
+ CLK_LOOKUP("", gcc_blsp1_qup3_i2c_apps_clk.c, ""),
+ CLK_LOOKUP("", gcc_blsp1_qup3_spi_apps_clk.c, ""),
+ CLK_LOOKUP("", gcc_blsp1_qup4_i2c_apps_clk.c, ""),
+ CLK_LOOKUP("", gcc_blsp1_qup4_spi_apps_clk.c, ""),
+ CLK_LOOKUP("", gcc_blsp1_uart1_apps_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_blsp1_uart2_apps_clk.c, "f991e000.serial"),
+ CLK_LOOKUP("core_clk", gcc_blsp1_uart3_apps_clk.c, "f991f000.serial"),
+ CLK_LOOKUP("", gcc_blsp1_uart4_apps_clk.c, ""),
+ CLK_LOOKUP("", gcc_blsp2_ahb_clk.c, ""),
+ CLK_LOOKUP("", gcc_blsp2_qup1_i2c_apps_clk.c, ""),
+ CLK_LOOKUP("", gcc_blsp2_qup1_spi_apps_clk.c, ""),
+ CLK_LOOKUP("", gcc_blsp2_qup2_i2c_apps_clk.c, ""),
+ CLK_LOOKUP("", gcc_blsp2_qup2_spi_apps_clk.c, ""),
+ CLK_LOOKUP("", gcc_blsp2_qup3_i2c_apps_clk.c, ""),
+ CLK_LOOKUP("", gcc_blsp2_qup3_spi_apps_clk.c, ""),
+ CLK_LOOKUP("", gcc_blsp2_qup4_i2c_apps_clk.c, ""),
+ CLK_LOOKUP("", gcc_blsp2_qup4_spi_apps_clk.c, ""),
+ CLK_LOOKUP("", gcc_blsp2_uart1_apps_clk.c, ""),
+ CLK_LOOKUP("", gcc_blsp2_uart2_apps_clk.c, ""),
+ CLK_LOOKUP("", gcc_blsp2_uart3_apps_clk.c, ""),
+ CLK_LOOKUP("", gcc_blsp2_uart4_apps_clk.c, ""),
+
+ /* SDCC */
+ CLK_LOOKUP("iface_clk", gcc_sdcc1_ahb_clk.c, "msm_sdcc.1"),
+ CLK_LOOKUP("core_clk", gcc_sdcc1_apps_clk.c, "msm_sdcc.1"),
+ CLK_LOOKUP("cal_clk", gcc_sdcc1_cdccal_ff_clk.c, "msm_sdcc.1"),
+ CLK_LOOKUP("sleep_clk", gcc_sdcc1_cdccal_sleep_clk.c, "msm_sdcc.1"),
+ CLK_LOOKUP("iface_clk", gcc_sdcc2_ahb_clk.c, "msm_sdcc.2"),
+ CLK_LOOKUP("core_clk", gcc_sdcc2_apps_clk.c, "msm_sdcc.2"),
+ CLK_LOOKUP("iface_clk", gcc_sdcc3_ahb_clk.c, "msm_sdcc.3"),
+ CLK_LOOKUP("core_clk", gcc_sdcc3_apps_clk.c, "msm_sdcc.3"),
+ CLK_LOOKUP("iface_clk", gcc_sdcc4_ahb_clk.c, "msm_sdcc.4"),
+ CLK_LOOKUP("core_clk", gcc_sdcc4_apps_clk.c, "msm_sdcc.4"),
+
+ /* SCM PAS */
+ CLK_LOOKUP("core_clk", gcc_ce1_clk.c, "scm"),
+ CLK_LOOKUP("iface_clk", gcc_ce1_ahb_clk.c, "scm"),
+ CLK_LOOKUP("bus_clk", gcc_ce1_axi_clk.c, "scm"),
+ CLK_LOOKUP("core_clk_src", scm_ce1_clk_src.c, "scm"),
+
+ /* Misc GCC branch */
+ CLK_LOOKUP("", ce1_clk_src.c, ""),
+ CLK_LOOKUP("dma_bam_pclk", gcc_bam_dma_ahb_clk.c, "msm_sps"),
+ CLK_LOOKUP("mem_clk", gcc_boot_rom_ahb_clk.c, "fc880000.qcom,mss"),
+ CLK_LOOKUP("", gcc_ce1_ahb_clk.c, ""),
+ CLK_LOOKUP("", gcc_ce1_axi_clk.c, ""),
+ CLK_LOOKUP("", gcc_ce1_clk.c, ""),
+ CLK_LOOKUP("bus_clk", gcc_lpass_q6_axi_clk.c, "fe200000.qcom,lpass"),
+ CLK_LOOKUP("mport_clk", gcc_lpass_sys_noc_mport_clk.c,
+ "fe200000.qcom,lpass"),
+ CLK_LOOKUP("sway_clk", gcc_lpass_sys_noc_sway_clk.c,
+ "fe200000.qcom,lpass"),
+ CLK_LOOKUP("core_clk", dummy_clk, "fe200000.qcom,lpass"),
+ CLK_LOOKUP("iface_clk", dummy_clk, "fe200000.qcom,lpass"),
+ CLK_LOOKUP("reg_clk", dummy_clk, "fe200000.qcom,lpass"),
+ CLK_LOOKUP("iface_clk", gcc_mss_cfg_ahb_clk.c, "fc880000.qcom,mss"),
+ CLK_LOOKUP("bus_clk", gcc_mss_q6_bimc_axi_clk.c, "fc880000.qcom,mss"),
+ CLK_LOOKUP("", gcc_pdm2_clk.c, ""),
+ CLK_LOOKUP("", gcc_pdm_ahb_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_prng_ahb_clk.c, "f9bff000.qcom,msm-rng"),
+ CLK_LOOKUP("", gcc_tsif_ref_clk.c, ""),
+ CLK_LOOKUP("", gcc_tsif_ahb_clk.c, ""),
+ CLK_LOOKUP("", gcc_usb2a_phy_sleep_clk.c, ""),
+ CLK_LOOKUP("iface_clk", gcc_usb_hs_ahb_clk.c, "msm_otg"),
+ CLK_LOOKUP("core_clk", gcc_usb_hs_system_clk.c, "msm_otg"),
+
+ /* MM sensor clocks */
+ CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "6e.qcom,camera"),
+ CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "20.qcom,camera"),
+ CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "0.qcom,camera"),
+ CLK_LOOKUP("cam_src_clk", mclk1_clk_src.c, "90.qcom,camera"),
+ CLK_LOOKUP("cam_src_clk", mclk1_clk_src.c, "6d.qcom,camera"),
+ CLK_LOOKUP("cam_src_clk", mclk1_clk_src.c, "1.qcom,camera"),
+ CLK_LOOKUP("cam_src_clk", mclk2_clk_src.c, "6c.qcom,camera"),
+ CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "6e.qcom,camera"),
+ CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "20.qcom,camera"),
+ CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "0.qcom,camera"),
+ CLK_LOOKUP("cam_clk", camss_mclk1_clk.c, "90.qcom,camera"),
+ CLK_LOOKUP("cam_clk", camss_mclk1_clk.c, "6d.qcom,camera"),
+ CLK_LOOKUP("cam_clk", camss_mclk1_clk.c, "1.qcom,camera"),
+ CLK_LOOKUP("cam_clk", camss_mclk2_clk.c, "6c.qcom,camera"),
+
+ /* CCI clocks */
+ CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
+ "fda0c000.qcom,cci"),
+ CLK_LOOKUP("cci_ahb_clk", camss_cci_cci_ahb_clk.c, "fda0c000.qcom,cci"),
+ CLK_LOOKUP("cci_src_clk", cci_clk_src.c, "fda0c000.qcom,cci"),
+ CLK_LOOKUP("cci_clk", camss_cci_cci_clk.c, "fda0c000.qcom,cci"),
+
+ /* CSIPHY clocks */
+ CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
+ "fda0ac00.qcom,csiphy"),
+ CLK_LOOKUP("ispif_ahb_clk", camss_ispif_ahb_clk.c,
+ "fda0ac00.qcom,csiphy"),
+ CLK_LOOKUP("csiphy_timer_src_clk", csi0phytimer_clk_src.c,
+ "fda0ac00.qcom,csiphy"),
+ CLK_LOOKUP("csiphy_timer_clk", camss_phy0_csi0phytimer_clk.c,
+ "fda0ac00.qcom,csiphy"),
+ CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
+ "fda0b000.qcom,csiphy"),
+ CLK_LOOKUP("ispif_ahb_clk", camss_ispif_ahb_clk.c,
+ "fda0b000.qcom,csiphy"),
+ CLK_LOOKUP("csiphy_timer_src_clk", csi1phytimer_clk_src.c,
+ "fda0b000.qcom,csiphy"),
+ CLK_LOOKUP("csiphy_timer_clk", camss_phy1_csi1phytimer_clk.c,
+ "fda0b000.qcom,csiphy"),
+
+ /* CSID clocks */
+ CLK_LOOKUP("ispif_ahb_clk", camss_ispif_ahb_clk.c,
+ "fda08000.qcom,csid"),
+ CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
+ "fda08000.qcom,csid"),
+ CLK_LOOKUP("csi_ahb_clk", camss_csi0_ahb_clk.c, "fda08000.qcom,csid"),
+ CLK_LOOKUP("csi_src_clk", csi0_clk_src.c, "fda08000.qcom,csid"),
+ CLK_LOOKUP("csi_phy_clk", camss_csi0phy_clk.c, "fda08000.qcom,csid"),
+ CLK_LOOKUP("csi_clk", camss_csi0_clk.c, "fda08000.qcom,csid"),
+ CLK_LOOKUP("csi_pix_clk", camss_csi0pix_clk.c, "fda08000.qcom,csid"),
+ CLK_LOOKUP("csi_rdi_clk", camss_csi0rdi_clk.c, "fda08000.qcom,csid"),
+
+ CLK_LOOKUP("ispif_ahb_clk", camss_ispif_ahb_clk.c,
+ "fda08400.qcom,csid"),
+ CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
+ "fda08400.qcom,csid"),
+ CLK_LOOKUP("csi_ahb_clk", camss_csi1_ahb_clk.c, "fda08400.qcom,csid"),
+ CLK_LOOKUP("csi_src_clk", csi1_clk_src.c, "fda08400.qcom,csid"),
+ CLK_LOOKUP("csi_phy_clk", camss_csi1phy_clk.c, "fda08400.qcom,csid"),
+ CLK_LOOKUP("csi_clk", camss_csi1_clk.c, "fda08400.qcom,csid"),
+ CLK_LOOKUP("csi_pix_clk", camss_csi1pix_clk.c, "fda08400.qcom,csid"),
+ CLK_LOOKUP("csi_rdi_clk", camss_csi1rdi_clk.c, "fda08400.qcom,csid"),
+
+ CLK_LOOKUP("ispif_ahb_clk", camss_ispif_ahb_clk.c,
+ "fda08800.qcom,csid"),
+ CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
+ "fda08800.qcom,csid"),
+ CLK_LOOKUP("csi_ahb_clk", camss_csi2_ahb_clk.c, "fda08800.qcom,csid"),
+ CLK_LOOKUP("csi_src_clk", csi2_clk_src.c, "fda08800.qcom,csid"),
+ CLK_LOOKUP("csi_phy_clk", camss_csi2phy_clk.c, "fda08800.qcom,csid"),
+ CLK_LOOKUP("csi_clk", camss_csi2_clk.c, "fda08800.qcom,csid"),
+ CLK_LOOKUP("csi_pix_clk", camss_csi2pix_clk.c, "fda08800.qcom,csid"),
+ CLK_LOOKUP("csi_rdi_clk", camss_csi2rdi_clk.c, "fda08800.qcom,csid"),
+
+ /* ISPIF clocks */
+ CLK_LOOKUP("ispif_ahb_clk", camss_ispif_ahb_clk.c,
+ "fda0a000.qcom,ispif"),
+ CLK_LOOKUP("vfe0_clk_src", vfe0_clk_src.c, "fda0a000.qcom,ispif"),
+ CLK_LOOKUP("camss_vfe_vfe0_clk", camss_vfe_vfe0_clk.c,
+ "fda0a000.qcom,ispif"),
+ CLK_LOOKUP("camss_csi_vfe0_clk", camss_csi_vfe0_clk.c,
+ "fda0a000.qcom,ispif"),
+ CLK_LOOKUP("vfe1_clk_src", vfe1_clk_src.c, "fda0a000.qcom,ispif"),
+ CLK_LOOKUP("camss_vfe_vfe1_clk", camss_vfe_vfe1_clk.c,
+ "fda0a000.qcom,ispif"),
+ CLK_LOOKUP("camss_csi_vfe1_clk", camss_csi_vfe1_clk.c,
+ "fda0a000.qcom,ispif"),
+ CLK_LOOKUP("csi0_src_clk", csi0_clk_src.c, "fda0a000.qcom,ispif"),
+ CLK_LOOKUP("csi0_clk", camss_csi0_clk.c, "fda0a000.qcom,ispif"),
+ CLK_LOOKUP("csi0_pix_clk", camss_csi0pix_clk.c,
+ "fda0a000.qcom,ispif"),
+ CLK_LOOKUP("csi0_rdi_clk", camss_csi0rdi_clk.c,
+ "fda0a000.qcom,ispif"),
+
+ /* CPP clocks */
+ CLK_LOOKUP("micro_iface_clk", camss_micro_ahb_clk.c,
+ "fda04000.qcom,cpp"),
+ CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
+ "fda04000.qcom,cpp"),
+ CLK_LOOKUP("cpp_iface_clk", camss_vfe_cpp_ahb_clk.c,
+ "fda04000.qcom,cpp"),
+ CLK_LOOKUP("cpp_core_clk", camss_vfe_cpp_clk.c, "fda04000.qcom,cpp"),
+ CLK_LOOKUP("cpp_bus_clk", camss_vfe_vfe_axi_clk.c, "fda04000.qcom,cpp"),
+ CLK_LOOKUP("vfe_clk_src", vfe0_clk_src.c, "fda04000.qcom,cpp"),
+ CLK_LOOKUP("camss_vfe_vfe_clk", camss_vfe_vfe0_clk.c,
+ "fda04000.qcom,cpp"),
+ CLK_LOOKUP("iface_clk", camss_vfe_vfe_ahb_clk.c, "fda04000.qcom,cpp"),
+
+ /* GDSC */
+ CLK_LOOKUP("core_clk", venus0_vcodec0_clk.c, "fd8c1024.qcom,gdsc"),
+ CLK_LOOKUP("core0_clk", camss_vfe_vfe0_clk.c, "fd8c36a4.qcom,gdsc"),
+ CLK_LOOKUP("cpp_clk", camss_vfe_cpp_clk.c, "fd8c36a4.qcom,gdsc"),
+ CLK_LOOKUP("core_clk", oxili_gfx3d_clk.c, "fd8c4024.qcom,gdsc"),
+ CLK_LOOKUP("core_clk", mdss_mdp_clk.c, "fd8c2304.qcom,gdsc"),
+ CLK_LOOKUP("lut_clk", mdss_mdp_lut_clk.c, "fd8c2304.qcom,gdsc"),
+
+ /* DSI PLL clocks */
+ CLK_LOOKUP("", dsi_vco_clk_samarium.c, ""),
+ CLK_LOOKUP("", analog_postdiv_clk_samarium.c, ""),
+ CLK_LOOKUP("", indirect_path_div2_clk_samarium.c, ""),
+ CLK_LOOKUP("", pixel_clk_src_samarium.c, ""),
+ CLK_LOOKUP("", byte_mux_samarium.c, ""),
+ CLK_LOOKUP("", byte_clk_src_samarium.c, ""),
+
+ /* MMSS */
+ CLK_LOOKUP("", axi_clk_src.c, ""),
+ CLK_LOOKUP("", camss_ahb_clk.c, ""),
+ CLK_LOOKUP("", camss_gp0_clk.c, ""),
+ CLK_LOOKUP("", camss_gp1_clk.c, ""),
+ CLK_LOOKUP("", camss_jpeg_jpeg0_clk.c, ""),
+ CLK_LOOKUP("", camss_jpeg_jpeg_ahb_clk.c, ""),
+ CLK_LOOKUP("", camss_jpeg_jpeg_axi_clk.c, ""),
+ CLK_LOOKUP("", gfx3d.c, ""),
+ CLK_LOOKUP("", gfx3d_a_clk.c, ""),
+ CLK_LOOKUP("", jpeg0_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", mdp_clk_src.c, "fd900000.qcom,mdss_mdp"),
+ CLK_LOOKUP("iface_clk", mdss_ahb_clk.c, "fd922800.qcom,mdss_dsi"),
+ CLK_LOOKUP("iface_clk", mdss_ahb_clk.c, "fd900000.qcom,mdss_mdp"),
+ CLK_LOOKUP("iface_clk", mdss_ahb_clk.c, "fd928000.qcom,iommu"),
+ CLK_LOOKUP("bus_clk", mdss_axi_clk.c, "fd922800.qcom,mdss_dsi"),
+ CLK_LOOKUP("core_clk", mdss_axi_clk.c, "fd928000.qcom,iommu"),
+ CLK_LOOKUP("bus_clk", mdss_axi_clk.c, "fd900000.qcom,mdss_mdp"),
+ CLK_LOOKUP("", byte0_clk_src.c, ""),
+ CLK_LOOKUP("", pclk0_clk_src.c, ""),
+ CLK_LOOKUP("byte_clk", mdss_byte0_clk.c, "fd922800.qcom,mdss_dsi"),
+ CLK_LOOKUP("core_clk", mdss_esc0_clk.c, "fd922800.qcom,mdss_dsi"),
+ CLK_LOOKUP("core_clk", mdss_mdp_clk.c, "fd900000.qcom,mdss_mdp"),
+ CLK_LOOKUP("mdp_core_clk", mdss_mdp_clk.c, "fd922800.qcom,mdss_dsi"),
+ CLK_LOOKUP("core_clk", mdss_mdp_clk.c, "fd8c2304.qcom,gdsc"),
+ CLK_LOOKUP("lut_clk", mdss_mdp_lut_clk.c, "fd900000.qcom,mdss_mdp"),
+ CLK_LOOKUP("lut_clk", mdss_mdp_lut_clk.c, "fd8c2304.qcom,gdsc"),
+ CLK_LOOKUP("pixel_clk", mdss_pclk0_clk.c, "fd922800.qcom,mdss_dsi"),
+ CLK_LOOKUP("vsync_clk", mdss_vsync_clk.c, "fd900000.qcom,mdss_mdp"),
+ CLK_LOOKUP("core_mmss_clk", mmss_misc_ahb_clk.c, "fd828018.hwevent"),
+ CLK_LOOKUP("", mmss_mmssnoc_axi_clk.c, ""),
+ CLK_LOOKUP("", ocmemgx.c, ""),
+ CLK_LOOKUP("", ocmemgx_a_clk.c, ""),
+ CLK_LOOKUP("core_clk", ocmemgx_core_clk.c, "fdd00000.qcom,ocmem"),
+ CLK_LOOKUP("iface_clk", ocmemcx_ocmemnoc_clk.c, "fdd00000.qcom,ocmem"),
+ CLK_LOOKUP("", ocmemnoc_clk_src.c, ""),
+ CLK_LOOKUP("core_clk", oxili_gfx3d_clk.c, "fdb00000.qcom,kgsl-3d0"),
+ CLK_LOOKUP("iface_clk", oxilicx_ahb_clk.c, "fdb00000.qcom,kgsl-3d0"),
+ CLK_LOOKUP("iface_clk", venus0_ahb_clk.c, "fdce0000.qcom,venus"),
+ CLK_LOOKUP("bus_clk", venus0_axi_clk.c, "fdce0000.qcom,venus"),
+ CLK_LOOKUP("mem_clk", venus0_ocmemnoc_clk.c, "fdce0000.qcom,venus"),
+ CLK_LOOKUP("core_clk", venus0_vcodec0_clk.c, "fdce0000.qcom,venus"),
+ CLK_LOOKUP("core_clk", venus0_vcodec0_clk.c, "fdc00000.qcom,vidc"),
+ CLK_LOOKUP("iface_clk", venus0_ahb_clk.c, "fdc00000.qcom,vidc"),
+ CLK_LOOKUP("bus_clk", venus0_axi_clk.c, "fdc00000.qcom,vidc"),
+ CLK_LOOKUP("mem_clk", venus0_ocmemnoc_clk.c, "fdc00000.qcom,vidc"),
+
+ CLK_LOOKUP("iface_clk", oxilicx_ahb_clk.c, "fdb10000.qcom,iommu"),
+ CLK_LOOKUP("core_clk", oxili_gfx3d_clk.c, "fdb10000.qcom,iommu"),
+ CLK_LOOKUP("iface_clk", mdss_ahb_clk.c, "fd928000.qcom,iommu"),
+ CLK_LOOKUP("core_clk", mdss_axi_clk.c, "fd928000.qcom,iommu"),
+ CLK_LOOKUP("iface_clk", camss_vfe_vfe_ahb_clk.c, "fda44000.qcom,iommu"),
+ CLK_LOOKUP("core_clk", camss_vfe_vfe_axi_clk.c, "fda44000.qcom,iommu"),
+ CLK_LOOKUP("alt_iface_clk", camss_ahb_clk.c, "fda44000.qcom,iommu"),
+ CLK_LOOKUP("alt_core_clk", camss_top_ahb_clk.c, "fda44000.qcom,iommu"),
+ CLK_LOOKUP("iface_clk", venus0_ahb_clk.c, "fdc84000.qcom,iommu"),
+ CLK_LOOKUP("alt_core_clk", venus0_vcodec0_clk.c, "fdc84000.qcom,iommu"),
+ CLK_LOOKUP("core_clk", venus0_axi_clk.c, "fdc84000.qcom,iommu"),
+ CLK_LOOKUP("iface_clk", camss_jpeg_jpeg_ahb_clk.c,
+ "fda64000.qcom,iommu"),
+ CLK_LOOKUP("core_clk", camss_jpeg_jpeg_axi_clk.c,
+ "fda64000.qcom,iommu"),
+ CLK_LOOKUP("alt_iface_clk", camss_ahb_clk.c, "fda64000.qcom,iommu"),
+ CLK_LOOKUP("alt_core_clk", camss_top_ahb_clk.c, "fda64000.qcom,iommu"),
+};
+
+static struct pll_config_regs mmpll0_regs __initdata = {
+ .l_reg = (void __iomem *)MMPLL0_L_VAL,
+ .m_reg = (void __iomem *)MMPLL0_M_VAL,
+ .n_reg = (void __iomem *)MMPLL0_N_VAL,
+ .config_reg = (void __iomem *)MMPLL0_USER_CTL,
+ .mode_reg = (void __iomem *)MMPLL0_MODE,
+ .base = &virt_bases[MMSS_BASE],
+};
+
+/* MMPLL0 at 800 MHz, main output enabled. */
+static struct pll_config mmpll0_config __initdata = {
+ .l = 41,
+ .m = 2,
+ .n = 3,
+ .vco_val = 0x0,
+ .vco_mask = BM(21, 20),
+ .pre_div_val = 0x0,
+ .pre_div_mask = BM(14, 12),
+ .post_div_val = 0x0,
+ .post_div_mask = BM(9, 8),
+ .mn_ena_val = BIT(24),
+ .mn_ena_mask = BIT(24),
+ .main_output_val = BIT(0),
+ .main_output_mask = BIT(0),
+};
+
+static struct pll_config_regs mmpll1_regs __initdata = {
+ .l_reg = (void __iomem *)MMPLL1_L_VAL,
+ .m_reg = (void __iomem *)MMPLL1_M_VAL,
+ .n_reg = (void __iomem *)MMPLL1_N_VAL,
+ .config_reg = (void __iomem *)MMPLL1_USER_CTL,
+ .mode_reg = (void __iomem *)MMPLL1_MODE,
+ .base = &virt_bases[MMSS_BASE],
+};
+
+/* MMPLL1 at 900MHz, main output enabled. */
+static struct pll_config mmpll1_config __initdata = {
+ .l = 46,
+ .m = 7,
+ .n = 8,
+ .vco_val = 0x0,
+ .vco_mask = BM(21, 20),
+ .pre_div_val = 0x0,
+ .pre_div_mask = BM(14, 12),
+ .post_div_val = 0x0,
+ .post_div_mask = BM(9, 8),
+ .mn_ena_val = BIT(24),
+ .mn_ena_mask = BIT(24),
+ .main_output_val = BIT(0),
+ .main_output_mask = BIT(0),
+};
+
+static struct pll_config_regs mmpll3_regs __initdata = {
+ .l_reg = (void __iomem *)MMPLL3_L_VAL,
+ .m_reg = (void __iomem *)MMPLL3_M_VAL,
+ .n_reg = (void __iomem *)MMPLL3_N_VAL,
+ .config_reg = (void __iomem *)MMPLL3_USER_CTL,
+ .mode_reg = (void __iomem *)MMPLL3_MODE,
+ .base = &virt_bases[MMSS_BASE],
+};
+
+/* MMPLL3 at 930 MHz, main output enabled. */
+static struct pll_config mmpll3_config __initdata = {
+ .l = 48,
+ .m = 7,
+ .n = 16,
+ .vco_val = 0x0,
+ .vco_mask = BM(21, 20),
+ .pre_div_val = 0x0,
+ .pre_div_mask = BM(14, 12),
+ .post_div_val = 0x0,
+ .post_div_mask = BM(9, 8),
+ .mn_ena_val = BIT(24),
+ .mn_ena_mask = BIT(24),
+ .main_output_val = BIT(0),
+ .main_output_mask = BIT(0),
+};
+
+static struct pll_config_regs mmpll4_regs __initdata = {
+ .l_reg = (void __iomem *)MMPLL4_L_VAL,
+ .m_reg = (void __iomem *)MMPLL4_M_VAL,
+ .n_reg = (void __iomem *)MMPLL4_N_VAL,
+ .config_reg = (void __iomem *)MMPLL4_USER_CTL,
+ .mode_reg = (void __iomem *)MMPLL4_MODE,
+ .base = &virt_bases[MMSS_BASE],
+};
+
+/* MMPLL4 at 930 MHz, main output enabled. */
+static struct pll_config mmpll4_config __initdata = {
+ .l = 48,
+ .m = 7,
+ .n = 16,
+ .vco_val = 0x0,
+ .vco_mask = BM(21, 20),
+ .pre_div_val = 0x0,
+ .pre_div_mask = BM(14, 12),
+ .post_div_val = 0x0,
+ .post_div_mask = BM(9, 8),
+ .mn_ena_val = BIT(24),
+ .mn_ena_mask = BIT(24),
+ .main_output_val = BIT(0),
+ .main_output_mask = BIT(0),
+};
+
+static void __init reg_init(void)
+{
+ u32 regval;
+
+ /* MMPLL init */
+ configure_sr_hpm_lp_pll(&mmpll0_config, &mmpll0_regs, 1);
+ configure_sr_hpm_lp_pll(&mmpll1_config, &mmpll1_regs, 1);
+ configure_sr_hpm_lp_pll(&mmpll3_config, &mmpll3_regs, 0);
+ configure_sr_hpm_lp_pll(&mmpll4_config, &mmpll4_regs, 0);
+
+ /* Vote for GPLL0 to turn on. Needed by acpuclock. */
+ regval = readl_relaxed(GCC_REG_BASE(APCS_GPLL_ENA_VOTE));
+ regval |= BIT(0);
+ writel_relaxed(regval, GCC_REG_BASE(APCS_GPLL_ENA_VOTE));
+
+ /* Vote for LPASS and MMSS controller to use GPLL0 */
+ regval = readl_relaxed(GCC_REG_BASE(APCS_CLOCK_BRANCH_ENA_VOTE));
+ writel_relaxed(regval | BIT(26) | BIT(25),
+ GCC_REG_BASE(APCS_CLOCK_BRANCH_ENA_VOTE));
+}
+
+static void __init msmsamarium_clock_post_init(void)
+{
+ /*
+ * Hold an active set vote at a rate of 40MHz for the MMSS NOC AHB
+ * source. Sleep set vote is 0.
+ */
+ /* enable for MMSS */
+ clk_set_rate(&mmssnoc_ahb_a_clk.c, 40000000);
+ clk_prepare_enable(&mmssnoc_ahb_a_clk.c);
+
+ /*
+ * Hold an active set vote for the PNOC AHB source. Sleep set vote is 0.
+ */
+ clk_set_rate(&pnoc_keepalive_a_clk.c, 19200000);
+ clk_prepare_enable(&pnoc_keepalive_a_clk.c);
+
+ /*
+ * Hold an active set vote for CXO; this is because CXO is expected
+ * to remain on whenever CPUs aren't power collapsed.
+ */
+ clk_prepare_enable(&xo_a_clk.c);
+}
+
+#define GCC_CC_PHYS 0xFC400000
+#define GCC_CC_SIZE SZ_8K
+
+#define MMSS_CC_PHYS 0xFD8C0000
+#define MMSS_CC_SIZE SZ_32K
+
+#define APCS_GCC_CC_PHYS 0xF9011000
+#define APCS_GCC_CC_SIZE SZ_4K
+
+static void __init msmsamarium_clock_pre_init(void)
+{
+ virt_bases[GCC_BASE] = ioremap(GCC_CC_PHYS, GCC_CC_SIZE);
+ if (!virt_bases[GCC_BASE])
+ panic("clock-samarium: Unable to ioremap GCC memory!");
+
+ virt_bases[MMSS_BASE] = ioremap(MMSS_CC_PHYS, MMSS_CC_SIZE);
+ if (!virt_bases[MMSS_BASE])
+ panic("clock-samarium: Unable to ioremap MMSS_CC memory!");
+
+ virt_bases[APCS_BASE] = ioremap(APCS_GCC_CC_PHYS, APCS_GCC_CC_SIZE);
+ if (!virt_bases[APCS_BASE])
+ panic("clock-samarium: Unable to ioremap APCS_GCC_CC memory!");
+
+ vdd_dig.regulator[0] = regulator_get(NULL, "vdd_dig");
+ if (IS_ERR(vdd_dig.regulator[0]))
+ panic("clock-samarium: Unable to get the vdd_dig regulator!");
+
+ enable_rpm_scaling();
+
+ reg_init();
+
+ /*
+ * MDSS needs the ahb clock and needs to init before we register the
+ * lookup table.
+ */
+ mdss_clk_ctrl_pre_init(&mdss_ahb_clk.c);
+}
+
+static void __init msmsamarium_rumi_clock_pre_init(void)
+{
+ virt_bases[GCC_BASE] = ioremap(GCC_CC_PHYS, GCC_CC_SIZE);
+ if (!virt_bases[GCC_BASE])
+ panic("clock-samarium: Unable to ioremap GCC memory!");
+
+ vdd_dig.regulator[0] = regulator_get(NULL, "vdd_dig");
+ if (IS_ERR(vdd_dig.regulator[0]))
+ panic("clock-samarium: Unable to get the vdd_dig regulator!");
+}
+
+struct clock_init_data msmsamarium_rumi_clock_init_data __initdata = {
+ .table = msm_clocks_samarium_rumi,
+ .size = ARRAY_SIZE(msm_clocks_samarium_rumi),
+ .pre_init = msmsamarium_rumi_clock_pre_init,
+};
+
+struct clock_init_data msmsamarium_clock_init_data __initdata = {
+ .table = msm_clocks_samarium,
+ .size = ARRAY_SIZE(msm_clocks_samarium),
+ .pre_init = msmsamarium_clock_pre_init,
+ .post_init = msmsamarium_clock_post_init,
+};
diff --git a/arch/arm/mach-msm/cpr-regulator.c b/arch/arm/mach-msm/cpr-regulator.c
index 08285aa..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;
@@ -180,6 +178,7 @@
int vdd_mx_vmax;
int vdd_mx_vmin_method;
int vdd_mx_vmin;
+ int vdd_mx_corner_map[CPR_FUSE_CORNER_MAX];
/* CPR parameters */
u64 cpr_fuse_bits;
@@ -494,12 +493,14 @@
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;
break;
+ case VDD_MX_VMIN_APC_CORNER_MAP:
+ vdd_mx = cpr_vreg->vdd_mx_corner_map[fuse_corner];
+ break;
default:
vdd_mx = 0;
break;
@@ -838,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,
@@ -1063,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);
@@ -1078,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;
}
@@ -1092,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);
@@ -1131,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) {
@@ -1146,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;
}
@@ -1234,11 +1246,23 @@
pr_err("vdd-mx-vmin-method missing: rc=%d\n", rc);
return rc;
}
- if (cpr_vreg->vdd_mx_vmin_method > VDD_MX_VMIN_MX_VMAX) {
+ if (cpr_vreg->vdd_mx_vmin_method > VDD_MX_VMIN_APC_CORNER_MAP) {
pr_err("Invalid vdd-mx-vmin-method(%d)\n",
cpr_vreg->vdd_mx_vmin_method);
return -EINVAL;
}
+
+ rc = of_property_read_u32_array(of_node,
+ "qcom,vdd-mx-corner-map",
+ &cpr_vreg->vdd_mx_corner_map[1],
+ CPR_FUSE_CORNER_MAX - 1);
+ if (rc && cpr_vreg->vdd_mx_vmin_method ==
+ VDD_MX_VMIN_APC_CORNER_MAP) {
+ pr_err("qcom,vdd-mx-corner-map missing: rc=%d\n",
+ rc);
+ return rc;
+ }
+
}
return 0;
@@ -1555,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;
@@ -1802,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;
}
@@ -1842,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 46505e0..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;
@@ -259,7 +262,7 @@
init_completion(&cpu_work->complete);
/* synchronous cpus share the same policy */
- if (!cpu_clk[policy->cpu])
+ if (is_clk && !cpu_clk[policy->cpu])
return 0;
if (cpufreq_frequency_table_cpuinfo(policy, table)) {
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 a9da79e..0ce5213 100644
--- a/arch/arm/mach-msm/include/mach/camera2.h
+++ b/arch/arm/mach-msm/include/mach/camera2.h
@@ -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
@@ -37,12 +37,6 @@
S_EXIT
};
-enum cci_i2c_master_t {
- MASTER_0,
- MASTER_1,
- MASTER_MAX,
-};
-
struct msm_camera_slave_info {
uint16_t sensor_slave_addr;
uint16_t sensor_id_reg_addr;
@@ -68,19 +62,32 @@
uint16_t order;
};
-struct msm_camera_sensor_board_info {
- const char *sensor_name;
- struct msm_camera_slave_info *slave_info;
- struct msm_camera_csi_lane_params *csi_lane_params;
+struct msm_camera_power_ctrl_t {
+ 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;
- struct msm_camera_sensor_strobe_flash_data *strobe_flash_data;
- struct msm_camera_gpio_conf *gpio_conf;
- struct msm_actuator_info *actuator_info;
struct msm_camera_i2c_conf *i2c_conf;
+ struct msm_cam_clk_info *clk_info;
+ uint16_t clk_info_size;
+};
+
+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;
+ struct msm_actuator_info *actuator_info;
struct msm_sensor_info_t *sensor_info;
- struct msm_sensor_init_params *sensor_init_params;
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 {
@@ -112,31 +119,32 @@
uint32_t delay;
};
-struct eeprom_memory_map_t {
+struct msm_eeprom_memory_map_t {
struct eeprom_map_t page;
struct eeprom_map_t pageen;
struct eeprom_map_t poll;
struct eeprom_map_t mem;
};
-struct msm_camera_power_ctrl_t {
- struct device *dev;
- struct msm_sensor_power_setting *power_setting;
- uint16_t power_setting_size;
- struct msm_camera_gpio_conf *gpio_conf;
- struct camera_vreg_t *cam_vreg;
- int num_vreg;
- struct msm_camera_i2c_conf *i2c_conf;
- struct msm_cam_clk_info *clk_info;
- uint16_t clk_info_size;
+struct msm_eeprom_memory_block_t {
+ struct msm_eeprom_memory_map_t *map;
+ uint32_t num_map; /* number of map blocks */
+ uint8_t *mapdata;
+ 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;
- uint32_t num_blocks;
- struct eeprom_memory_map_t *eeprom_map;
struct msm_camera_power_ctrl_t power_info;
+ struct msm_eeprom_mm_t mm_data;
};
#endif
diff --git a/arch/arm/mach-msm/include/mach/qseecomi.h b/arch/arm/mach-msm/include/mach/qseecomi.h
index 222a171..cb850c2 100644
--- a/arch/arm/mach-msm/include/mach/qseecomi.h
+++ b/arch/arm/mach-msm/include/mach/qseecomi.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -27,6 +27,7 @@
#define QSEOS_RESULT_FAIL_KS_ALREADY_DONE -69
#define QSEOS_RESULT_FAIL_KEY_ID_DNE -70
#define QSEOS_RESULT_FAIL_INCORRECT_PSWD -71
+#define QSEOS_RESULT_FAIL_MAX_ATTEMPT -72
enum qseecom_command_scm_resp_type {
QSEOS_APP_ID = 0xEE01,
diff --git a/arch/arm/mach-msm/lpm_levels.c b/arch/arm/mach-msm/lpm_levels.c
index 7553f82..2370bec 100644
--- a/arch/arm/mach-msm/lpm_levels.c
+++ b/arch/arm/mach-msm/lpm_levels.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
@@ -341,7 +341,8 @@
const struct cpumask *nextcpu;
spin_lock(&system_state->sync_lock);
- if (num_powered_cores != system_state->num_cores_in_sync) {
+ if (index < 0 ||
+ num_powered_cores != system_state->num_cores_in_sync) {
spin_unlock(&system_state->sync_lock);
return;
}
@@ -418,7 +419,7 @@
system_lvl->num_cpu_votes--;
}
- if (!first_core_up)
+ if (!first_core_up || index < 0)
goto unlock_and_return;
if (default_l2_mode != system_state->system_level[index].l2_mode)
@@ -429,6 +430,7 @@
msm_mpm_exit_sleep(from_idle);
}
unlock_and_return:
+ system_state->last_entered_cluster_index = -1;
spin_unlock(&system_state->sync_lock);
}
@@ -724,8 +726,7 @@
idx = lpm_system_select(system_state, cpu_index, from_idle);
- if (idx >= 0)
- lpm_system_prepare(system_state, idx, from_idle);
+ lpm_system_prepare(system_state, idx, from_idle);
msm_cpu_pm_enter_sleep(cpu_level->mode, from_idle);
@@ -967,9 +968,8 @@
goto fail;
}
- if (l->l2_mode == MSM_SPM_L2_MODE_GDHS ||
- l->l2_mode == MSM_SPM_L2_MODE_POWER_COLLAPSE)
- l->notify_rpm = true;
+ key = "qcom,send-rpm-sleep-set";
+ l->notify_rpm = of_property_read_bool(node, key);
if (l->l2_mode >= MSM_SPM_L2_MODE_GDHS)
l->sync = true;
@@ -1011,6 +1011,7 @@
}
sys_state.system_level = level;
sys_state.num_system_levels = num_levels;
+ sys_state.last_entered_cluster_index = -1;
return ret;
fail:
kfree(level);
diff --git a/arch/arm/mach-msm/msm-buspm-dev.h b/arch/arm/mach-msm/msm-buspm-dev.h
index a951093..45282c1 100644
--- a/arch/arm/mach-msm/msm-buspm-dev.h
+++ b/arch/arm/mach-msm/msm-buspm-dev.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, 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
@@ -23,7 +23,7 @@
/* Read/write data into kernel buffer */
struct buspm_xfer_req {
- int size; /* Size of this request, in bytes */
+ unsigned int size; /* Size of this request, in bytes */
void *data; /* Data buffer to transfer data to/from */
};
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_bimc.c b/arch/arm/mach-msm/msm_bus/msm_bus_bimc.c
index a76c29b..5747f79 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_bimc.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_bimc.c
@@ -1932,13 +1932,9 @@
ports = hop->node_info->num_sports;
MSM_BUS_DBG("BIMC: ID: %d, Sports: %d\n", hop->node_info->priv_id,
ports);
- if (ports)
- bw = INTERLEAVED_BW(fab_pdata, add_bw, ports);
- else
- return;
for (i = 0; i < ports; i++) {
- sel_cd->slv[hop->node_info->slavep[i]].bw += bw;
+ sel_cd->slv[hop->node_info->slavep[i]].bw += add_bw;
sel_cd->slv[hop->node_info->slavep[i]].hw_id =
hop->node_info->slv_hw_id;
MSM_BUS_DBG("BIMC: Update slave_bw: ID: %d -> %llu\n",
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_noc.c b/arch/arm/mach-msm/msm_bus/msm_bus_noc.c
index 479826e..988d720 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_noc.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_noc.c
@@ -586,14 +586,8 @@
skip_mas_bw:
ports = hop->node_info->num_sports;
- if (ports == 0) {
- MSM_BUS_DBG("\nDIVIDE BY 0, hop: %d\n",
- hop->node_info->priv_id);
- return;
- }
- bw = INTERLEAVED_BW(fab_pdata, add_bw, ports);
for (i = 0; i < ports; i++) {
- sel_cd->slv[hop->node_info->slavep[i]].bw += bw;
+ sel_cd->slv[hop->node_info->slavep[i]].bw += add_bw;
sel_cd->slv[hop->node_info->slavep[i]].hw_id =
hop->node_info->slv_hw_id;
MSM_BUS_DBG("NOC: Update slave_bw for ID: %d -> %llu\n",
diff --git a/arch/arm/mach-msm/peripheral-loader.c b/arch/arm/mach-msm/peripheral-loader.c
index 157dc01..285c02a 100644
--- a/arch/arm/mach-msm/peripheral-loader.c
+++ b/arch/arm/mach-msm/peripheral-loader.c
@@ -515,7 +515,7 @@
}
}
-#define IOMAP_SIZE SZ_4M
+#define IOMAP_SIZE SZ_1M
static int pil_load_seg(struct pil_desc *desc, struct pil_seg *seg)
{
diff --git a/arch/arm/mach-msm/pil-pronto.c b/arch/arm/mach-msm/pil-pronto.c
index 69df3ae..a7fc204 100644
--- a/arch/arm/mach-msm/pil-pronto.c
+++ b/arch/arm/mach-msm/pil-pronto.c
@@ -85,6 +85,7 @@
bool crash;
struct delayed_work cancel_vote_work;
struct ramdump_device *ramdump_dev;
+ struct work_struct wcnss_wdog_bite_work;
};
static int pil_pronto_make_proxy_vote(struct pil_desc *pil)
@@ -322,6 +323,16 @@
return IRQ_HANDLED;
}
+static void wcnss_wdog_bite_work_hdlr(struct work_struct *wcnss_work)
+{
+ struct pronto_data *drv = container_of(wcnss_work, struct pronto_data,
+ wcnss_wdog_bite_work);
+
+ wcnss_log_debug_regs_on_bite();
+
+ restart_wcnss(drv);
+}
+
static irqreturn_t wcnss_wdog_bite_irq_hdlr(int irq, void *dev_id)
{
struct pronto_data *drv = subsys_to_drv(dev_id);
@@ -334,10 +345,9 @@
pr_err("Ignoring wcnss bite irq, restart in progress\n");
return IRQ_HANDLED;
}
- wcnss_log_debug_regs_on_bite();
drv->restart_inprogress = true;
- restart_wcnss(drv);
+ schedule_work(&drv->wcnss_wdog_bite_work);
return IRQ_HANDLED;
}
@@ -490,6 +500,7 @@
drv->subsys_desc.wdog_bite_handler = wcnss_wdog_bite_irq_hdlr;
INIT_DELAYED_WORK(&drv->cancel_vote_work, wcnss_post_bootup);
+ INIT_WORK(&drv->wcnss_wdog_bite_work, wcnss_wdog_bite_work_hdlr);
drv->subsys = subsys_register(&drv->subsys_desc);
if (IS_ERR(drv->subsys)) {
diff --git a/arch/arm/mach-msm/qdsp6v2/msm_audio_ion.c b/arch/arm/mach-msm/qdsp6v2/msm_audio_ion.c
index fc6de64..399e073 100644
--- a/arch/arm/mach-msm/qdsp6v2/msm_audio_ion.c
+++ b/arch/arm/mach-msm/qdsp6v2/msm_audio_ion.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -391,7 +391,9 @@
int msm_audio_ion_free_legacy(struct ion_client *client,
struct ion_handle *handle)
{
- /* To add condition for SMMU enabled */
+ if (msm_audio_ion_data.smmu_enabled)
+ ion_unmap_iommu(client, handle,
+ msm_audio_ion_data.domain_id, 0);
ion_unmap_kernel(client, handle);
ion_free(client, handle);
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 9e49b3e..e13fb5f 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -125,14 +125,20 @@
cur_time = jiffies;
devfreq->time_in_state[lev] +=
cur_time - devfreq->last_stat_updated;
- if (freq != devfreq->previous_freq) {
- prev_lev = devfreq_get_freq_level(devfreq,
- devfreq->previous_freq);
+ devfreq->last_stat_updated = cur_time;
+
+ if (freq == devfreq->previous_freq)
+ return 0;
+
+ prev_lev = devfreq_get_freq_level(devfreq, devfreq->previous_freq);
+ if (prev_lev < 0)
+ return 0;
+
+ if (lev != prev_lev) {
devfreq->trans_table[(prev_lev *
devfreq->profile->max_state) + lev]++;
devfreq->total_trans++;
}
- devfreq->last_stat_updated = cur_time;
return 0;
}
diff --git a/drivers/gpu/ion/ion_system_heap.c b/drivers/gpu/ion/ion_system_heap.c
index be1a89c..cfdd5f4 100644
--- a/drivers/gpu/ion/ion_system_heap.c
+++ b/drivers/gpu/ion/ion_system_heap.c
@@ -2,7 +2,7 @@
* drivers/gpu/ion/ion_system_heap.c
*
* Copyright (C) 2011 Google, Inc.
- * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-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
@@ -34,7 +34,7 @@
__GFP_NO_KSWAPD) & ~__GFP_WAIT;
static unsigned int low_order_gfp_flags = (GFP_HIGHUSER | __GFP_ZERO |
__GFP_NOWARN);
-static const unsigned int orders[] = {8, 4, 0};
+static const unsigned int orders[] = {9, 8, 4, 0};
static const int num_orders = ARRAY_SIZE(orders);
static int order_to_index(unsigned int order)
{
@@ -362,7 +362,7 @@
struct ion_page_pool *pool;
gfp_t gfp_flags = low_order_gfp_flags;
- if (orders[i] > 4)
+ if (orders[i])
gfp_flags = high_order_gfp_flags;
pool = ion_page_pool_create(gfp_flags, orders[i]);
if (!pool)
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 0d88689..7717829 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -1205,9 +1205,11 @@
* after the command has been retired
*/
if (result)
- kgsl_mmu_disable_clk_on_ts(&device->mmu, 0, false);
+ kgsl_mmu_disable_clk(&device->mmu,
+ KGSL_IOMMU_CONTEXT_USER);
else
- kgsl_mmu_disable_clk_on_ts(&device->mmu, rb->global_ts, true);
+ kgsl_mmu_disable_clk_on_ts(&device->mmu, rb->global_ts,
+ KGSL_IOMMU_CONTEXT_USER);
done:
kgsl_context_put(context);
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index 800caf1..0f1e01d 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -20,6 +20,8 @@
#include "kgsl_iommu.h"
#include <mach/ocmem.h>
+#include "a3xx_reg.h"
+
#define DEVICE_3D_NAME "kgsl-3d"
#define DEVICE_3D0_NAME "kgsl-3d0"
@@ -895,4 +897,48 @@
return result;
}
+/*
+ * adreno_set_protected_registers() - Protect the specified range of registers
+ * from being accessed by the GPU
+ * @device: pointer to the KGSL device
+ * @index: Pointer to the index of the protect mode register to write to
+ * @reg: Starting dword register to write
+ * @mask_len: Size of the mask to protect (# of registers = 2 ** mask_len)
+ *
+ * Add the range of registers to the list of protected mode registers that will
+ * cause an exception if the GPU accesses them. There are 16 available
+ * protected mode registers. Index is used to specify which register to write
+ * to - the intent is to call this function multiple times with the same index
+ * pointer for each range and the registers will be magically programmed in
+ * incremental fashion
+ */
+static inline void adreno_set_protected_registers(struct kgsl_device *device,
+ unsigned int *index, unsigned int reg, int mask_len)
+{
+ struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+ unsigned int val;
+
+ /* This function is only for adreno A3XX and beyond */
+ BUG_ON(adreno_is_a2xx(adreno_dev));
+
+ /* There are only 16 registers available */
+ BUG_ON(*index >= 16);
+
+ val = 0x60000000 | ((mask_len & 0x1F) << 24) | ((reg << 2) & 0x1FFFF);
+
+ /*
+ * Write the protection range to the next available protection
+ * register
+ */
+
+ kgsl_regwrite(device, A3XX_CP_PROTECT_REG_0 + *index, val);
+ *index = *index + 1;
+}
+
+#ifdef CONFIG_DEBUG_FS
+void adreno_debugfs_init(struct kgsl_device *device);
+#else
+static inline void adreno_debugfs_init(struct kgsl_device *device) { }
+#endif
+
#endif /*__ADRENO_H */
diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c
index 3d4c66a..eed11c3 100644
--- a/drivers/gpu/msm/adreno_a3xx.c
+++ b/drivers/gpu/msm/adreno_a3xx.c
@@ -3029,8 +3029,8 @@
GSL_RB_WRITE(rb->device, cmds, cmds_gpu, 0x00000001);
GSL_RB_WRITE(rb->device, cmds, cmds_gpu, 0x00000000);
GSL_RB_WRITE(rb->device, cmds, cmds_gpu, 0x00000000);
- /* Protected mode control - turned off for A3XX */
- GSL_RB_WRITE(rb->device, cmds, cmds_gpu, 0x00000000);
+ /* Enable protected mode */
+ GSL_RB_WRITE(rb->device, cmds, cmds_gpu, 0x20000000);
GSL_RB_WRITE(rb->device, cmds, cmds_gpu, 0x00000000);
GSL_RB_WRITE(rb->device, cmds, cmds_gpu, 0x00000000);
@@ -3092,9 +3092,16 @@
case A3XX_INT_CP_HW_FAULT:
err = "ringbuffer hardware fault";
break;
- case A3XX_INT_CP_REG_PROTECT_FAULT:
- err = "ringbuffer protected mode error interrupt";
- break;
+ case A3XX_INT_CP_REG_PROTECT_FAULT: {
+ unsigned int reg;
+ kgsl_regread(device, A3XX_CP_PROTECT_STATUS, ®);
+
+ KGSL_DRV_CRIT(device,
+ "CP | Protected mode error| %s | addr=%x\n",
+ reg & (1 << 24) ? "WRITE" : "READ",
+ (reg & 0x1FFFF) >> 2);
+ goto done;
+ }
case A3XX_INT_CP_AHB_ERROR_HALT:
err = "ringbuffer AHB error interrupt";
break;
@@ -4115,29 +4122,35 @@
*/
static void a3xx_protect_init(struct kgsl_device *device)
{
+ int index = 0;
+
/* enable access protection to privileged registers */
kgsl_regwrite(device, A3XX_CP_PROTECT_CTRL, 0x00000007);
/* RBBM registers */
- kgsl_regwrite(device, A3XX_CP_PROTECT_REG_0, 0x63000040);
- kgsl_regwrite(device, A3XX_CP_PROTECT_REG_1, 0x62000080);
- kgsl_regwrite(device, A3XX_CP_PROTECT_REG_2, 0x600000CC);
- kgsl_regwrite(device, A3XX_CP_PROTECT_REG_3, 0x60000108);
- kgsl_regwrite(device, A3XX_CP_PROTECT_REG_4, 0x64000140);
- kgsl_regwrite(device, A3XX_CP_PROTECT_REG_5, 0x66000400);
+ adreno_set_protected_registers(device, &index, 0x18, 0);
+ adreno_set_protected_registers(device, &index, 0x20, 2);
+ adreno_set_protected_registers(device, &index, 0x33, 0);
+ adreno_set_protected_registers(device, &index, 0x42, 0);
+ adreno_set_protected_registers(device, &index, 0x50, 4);
+ adreno_set_protected_registers(device, &index, 0x63, 0);
+ adreno_set_protected_registers(device, &index, 0x100, 4);
/* CP registers */
- kgsl_regwrite(device, A3XX_CP_PROTECT_REG_6, 0x65000700);
- kgsl_regwrite(device, A3XX_CP_PROTECT_REG_7, 0x610007D8);
- kgsl_regwrite(device, A3XX_CP_PROTECT_REG_8, 0x620007E0);
- kgsl_regwrite(device, A3XX_CP_PROTECT_REG_9, 0x61001178);
- kgsl_regwrite(device, A3XX_CP_PROTECT_REG_A, 0x64001180);
+ adreno_set_protected_registers(device, &index, 0x1C0, 5);
+ adreno_set_protected_registers(device, &index, 0x1F6, 1);
+ adreno_set_protected_registers(device, &index, 0x1F8, 2);
+ adreno_set_protected_registers(device, &index, 0x45E, 2);
+ adreno_set_protected_registers(device, &index, 0x460, 4);
/* RB registers */
- kgsl_regwrite(device, A3XX_CP_PROTECT_REG_B, 0x60003300);
+ adreno_set_protected_registers(device, &index, 0xCC0, 0);
/* VBIF registers */
- kgsl_regwrite(device, A3XX_CP_PROTECT_REG_C, 0x6B00C000);
+ adreno_set_protected_registers(device, &index, 0x3000, 6);
+
+ /* SMMU registers */
+ adreno_set_protected_registers(device, &index, 0x4000, 14);
}
static void a3xx_start(struct adreno_device *adreno_dev)
diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c
index 8d7b803..9aae497 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.c
+++ b/drivers/gpu/msm/adreno_ringbuffer.c
@@ -696,7 +696,7 @@
/* Add space for the power on shader fixup if we need it */
if (flags & KGSL_CMD_FLAGS_PWRON_FIXUP)
- total_sizedwords += 5;
+ total_sizedwords += 9;
ringcmds = adreno_ringbuffer_allocspace(rb, drawctxt, total_sizedwords);
@@ -718,6 +718,11 @@
}
if (flags & KGSL_CMD_FLAGS_PWRON_FIXUP) {
+ /* Disable protected mode for the fixup */
+ GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu,
+ cp_type3_packet(CP_SET_PROTECTED_MODE, 1));
+ GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu, 0);
+
GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu, cp_nop_packet(1));
GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu,
KGSL_PWRON_FIXUP_IDENTIFIER);
@@ -727,6 +732,11 @@
adreno_dev->pwron_fixup.gpuaddr);
GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu,
adreno_dev->pwron_fixup_dwords);
+
+ /* Re-enable protected mode */
+ GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu,
+ cp_type3_packet(CP_SET_PROTECTED_MODE, 1));
+ GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu, 1);
}
/* Add any IB required for profiling if it is enabled */
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index 0a7ba30..2af8d27 100755
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -461,7 +461,7 @@
* Disables iommu clocks
* Return - void
*/
-static void kgsl_iommu_disable_clk(struct kgsl_mmu *mmu)
+static void kgsl_iommu_disable_clk(struct kgsl_mmu *mmu, int ctx_id)
{
struct kgsl_iommu *iommu = mmu->priv;
struct msm_iommu_drvdata *iommu_drvdata;
@@ -470,8 +470,15 @@
for (i = 0; i < iommu->unit_count; i++) {
struct kgsl_iommu_unit *iommu_unit = &iommu->iommu_units[i];
for (j = 0; j < iommu_unit->dev_count; j++) {
- if (!iommu_unit->dev[j].clk_enabled)
+ if (ctx_id != iommu_unit->dev[j].ctx_id)
continue;
+ atomic_dec(&iommu_unit->dev[j].clk_enable_count);
+ BUG_ON(
+ atomic_read(&iommu_unit->dev[j].clk_enable_count) < 0);
+ /*
+ * the clock calls have a refcount so call them on every
+ * enable/disable call
+ */
iommu_drvdata = dev_get_drvdata(
iommu_unit->dev[j].dev->parent);
if (iommu_drvdata->aclk)
@@ -479,7 +486,6 @@
if (iommu_drvdata->clk)
clk_disable_unprepare(iommu_drvdata->clk);
clk_disable_unprepare(iommu_drvdata->pclk);
- iommu_unit->dev[j].clk_enabled = false;
}
}
}
@@ -500,32 +506,14 @@
unsigned int id, unsigned int ts,
u32 type)
{
- struct kgsl_mmu *mmu = data;
- struct kgsl_iommu *iommu = mmu->priv;
+ struct kgsl_iommu_disable_clk_param *param = data;
- if (!iommu->clk_event_queued) {
- if (0 > timestamp_cmp(ts, iommu->iommu_last_cmd_ts))
- KGSL_DRV_ERR(device,
- "IOMMU disable clock event being cancelled, "
- "iommu_last_cmd_ts: %x, retired ts: %x\n",
- iommu->iommu_last_cmd_ts, ts);
- return;
- }
-
- if (0 <= timestamp_cmp(ts, iommu->iommu_last_cmd_ts)) {
- kgsl_iommu_disable_clk(mmu);
- iommu->clk_event_queued = false;
- } else {
- /* add new event to fire when ts is reached, this can happen
- * if we queued an event and someone requested the clocks to
- * be disbaled on a later timestamp */
- if (kgsl_add_event(device, id, iommu->iommu_last_cmd_ts,
- kgsl_iommu_clk_disable_event, mmu, mmu)) {
- KGSL_DRV_ERR(device,
- "Failed to add IOMMU disable clk event\n");
- iommu->clk_event_queued = false;
- }
- }
+ if ((0 <= timestamp_cmp(ts, param->ts)) ||
+ (KGSL_EVENT_CANCELLED == type))
+ kgsl_iommu_disable_clk(param->mmu, param->ctx_id);
+ else
+ /* something went wrong with the event handling mechanism */
+ BUG_ON(1);
}
/*
@@ -535,6 +523,8 @@
* @ts_valid - Indicates whether ts parameter is valid, if this parameter
* is false then it means that the calling function wants to disable the
* IOMMU clocks immediately without waiting for any timestamp
+ * @ctx_id: Context id of the IOMMU context for which clocks are to be
+ * turned off
*
* Creates an event to disable the IOMMU clocks on timestamp and if event
* already exists then updates the timestamp of disabling the IOMMU clocks
@@ -543,28 +533,25 @@
* Return - void
*/
static void
-kgsl_iommu_disable_clk_on_ts(struct kgsl_mmu *mmu, unsigned int ts,
- bool ts_valid)
+kgsl_iommu_disable_clk_on_ts(struct kgsl_mmu *mmu,
+ unsigned int ts, int ctx_id)
{
- struct kgsl_iommu *iommu = mmu->priv;
+ struct kgsl_iommu_disable_clk_param *param;
- if (iommu->clk_event_queued) {
- if (ts_valid && (0 <
- timestamp_cmp(ts, iommu->iommu_last_cmd_ts)))
- iommu->iommu_last_cmd_ts = ts;
- } else {
- if (ts_valid) {
- iommu->iommu_last_cmd_ts = ts;
- iommu->clk_event_queued = true;
- if (kgsl_add_event(mmu->device, KGSL_MEMSTORE_GLOBAL,
- ts, kgsl_iommu_clk_disable_event, mmu, mmu)) {
- KGSL_DRV_ERR(mmu->device,
- "Failed to add IOMMU disable clk event\n");
- iommu->clk_event_queued = false;
- }
- } else {
- kgsl_iommu_disable_clk(mmu);
- }
+ param = kzalloc(sizeof(*param), GFP_KERNEL);
+ if (!param) {
+ KGSL_CORE_ERR("kzalloc(%d) failed\n", sizeof(*param));
+ return;
+ }
+ param->mmu = mmu;
+ param->ctx_id = ctx_id;
+ param->ts = ts;
+
+ if (kgsl_add_event(mmu->device, KGSL_MEMSTORE_GLOBAL,
+ ts, kgsl_iommu_clk_disable_event, param, mmu)) {
+ KGSL_DRV_ERR(mmu->device,
+ "Failed to add IOMMU disable clk event\n");
+ kfree(param);
}
}
@@ -587,8 +574,7 @@
for (i = 0; i < iommu->unit_count; i++) {
struct kgsl_iommu_unit *iommu_unit = &iommu->iommu_units[i];
for (j = 0; j < iommu_unit->dev_count; j++) {
- if (iommu_unit->dev[j].clk_enabled ||
- ctx_id != iommu_unit->dev[j].ctx_id)
+ if (ctx_id != iommu_unit->dev[j].ctx_id)
continue;
iommu_drvdata =
dev_get_drvdata(iommu_unit->dev[j].dev->parent);
@@ -614,12 +600,25 @@
goto done;
}
}
- iommu_unit->dev[j].clk_enabled = true;
+ atomic_inc(&iommu_unit->dev[j].clk_enable_count);
}
}
done:
- if (ret)
- kgsl_iommu_disable_clk(mmu);
+ if (ret) {
+ struct kgsl_iommu_unit *iommu_unit;
+ if (iommu->unit_count == i)
+ i--;
+ iommu_unit = &iommu->iommu_units[i];
+ do {
+ for (j--; j >= 0; j--)
+ kgsl_iommu_disable_clk(mmu, ctx_id);
+ i--;
+ if (i >= 0) {
+ iommu_unit = &iommu->iommu_units[i];
+ j = iommu_unit->dev_count;
+ }
+ } while (i >= 0);
+ }
return ret;
}
@@ -848,6 +847,9 @@
ret = -EINVAL;
goto done;
}
+ atomic_set(
+ &(iommu_unit->dev[iommu_unit->dev_count].clk_enable_count),
+ 0);
iommu_unit->dev[iommu_unit->dev_count].dev =
msm_iommu_get_ctx(data->iommu_ctxs[i].iommu_ctx_name);
@@ -1674,6 +1676,7 @@
}
status = kgsl_iommu_enable_clk(mmu, KGSL_IOMMU_CONTEXT_PRIV);
if (status) {
+ kgsl_iommu_disable_clk(mmu, KGSL_IOMMU_CONTEXT_USER);
KGSL_CORE_ERR("clk enable failed\n");
goto done;
}
@@ -1728,14 +1731,11 @@
KGSL_IOMMU_SETSTATE_NOP_OFFSET,
cp_nop_packet(1), sizeof(unsigned int));
- kgsl_iommu_disable_clk_on_ts(mmu, 0, false);
+ kgsl_iommu_disable_clk(mmu, KGSL_IOMMU_CONTEXT_USER);
+ kgsl_iommu_disable_clk(mmu, KGSL_IOMMU_CONTEXT_PRIV);
mmu->flags |= KGSL_FLAGS_STARTED;
done:
- if (status) {
- kgsl_iommu_disable_clk_on_ts(mmu, 0, false);
- kgsl_detach_pagetable_iommu_domain(mmu);
- }
return status;
}
@@ -1858,6 +1858,7 @@
iommu_unit,
iommu_unit->dev[j].ctx_id,
FSR, 0);
+ kgsl_iommu_disable_clk(mmu, j);
_iommu_unlock(iommu);
iommu_unit->dev[j].fault = 0;
}
@@ -1870,7 +1871,6 @@
static void kgsl_iommu_stop(struct kgsl_mmu *mmu)
{
- struct kgsl_iommu *iommu = mmu->priv;
/*
* stop device mmu
*
@@ -1886,9 +1886,7 @@
kgsl_iommu_pagefault_resume(mmu);
}
/* switch off MMU clocks and cancel any events it has queued */
- iommu->clk_event_queued = false;
kgsl_cancel_events(mmu->device, mmu);
- kgsl_iommu_disable_clk(mmu);
}
static int kgsl_iommu_close(struct kgsl_mmu *mmu)
@@ -1938,10 +1936,10 @@
return 0;
/* Return the current pt base by reading IOMMU pt_base register */
kgsl_iommu_enable_clk(mmu, KGSL_IOMMU_CONTEXT_USER);
- pt_base = KGSL_IOMMU_GET_CTX_REG(iommu, (&iommu->iommu_units[0]),
- KGSL_IOMMU_CONTEXT_USER,
- TTBR0);
- kgsl_iommu_disable_clk_on_ts(mmu, 0, false);
+ pt_base = KGSL_IOMMU_GET_CTX_REG(iommu,
+ (&iommu->iommu_units[0]),
+ KGSL_IOMMU_CONTEXT_USER, TTBR0);
+ kgsl_iommu_disable_clk(mmu, KGSL_IOMMU_CONTEXT_USER);
return pt_base & KGSL_IOMMU_CTX_TTBR0_ADDR_MASK;
}
@@ -1969,7 +1967,6 @@
phys_addr_t pt_val;
ret = kgsl_iommu_enable_clk(mmu, KGSL_IOMMU_CONTEXT_USER);
-
if (ret) {
KGSL_DRV_ERR(mmu->device, "Failed to enable iommu clocks\n");
return ret;
@@ -2056,7 +2053,7 @@
_iommu_unlock(iommu);
/* Disable smmu clock */
- kgsl_iommu_disable_clk_on_ts(mmu, 0, false);
+ kgsl_iommu_disable_clk(mmu, KGSL_IOMMU_CONTEXT_USER);
return ret;
}
diff --git a/drivers/gpu/msm/kgsl_iommu.h b/drivers/gpu/msm/kgsl_iommu.h
index 7dca40e..3878107 100644
--- a/drivers/gpu/msm/kgsl_iommu.h
+++ b/drivers/gpu/msm/kgsl_iommu.h
@@ -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
@@ -143,6 +143,7 @@
* are on, else the clocks are off
* fault: Flag when set indicates that this iommu device has caused a page
* fault
+ * @clk_enable_count: The ref count of clock enable calls
*/
struct kgsl_iommu_device {
struct device *dev;
@@ -152,6 +153,7 @@
bool clk_enabled;
struct kgsl_device *kgsldev;
int fault;
+ atomic_t clk_enable_count;
};
/*
@@ -182,10 +184,6 @@
* iommu contexts owned by graphics cores
* @unit_count: Number of IOMMU units that are available for this
* instance of the IOMMU driver
- * @iommu_last_cmd_ts: The timestamp of last command submitted that
- * aceeses iommu registers
- * @clk_event_queued: Indicates whether an event to disable clocks
- * is already queued or not
* @device: Pointer to kgsl device
* @ctx_offset: The context offset to be added to base address when
* accessing IOMMU registers
@@ -201,8 +199,6 @@
struct kgsl_iommu {
struct kgsl_iommu_unit iommu_units[KGSL_IOMMU_MAX_UNITS];
unsigned int unit_count;
- unsigned int iommu_last_cmd_ts;
- bool clk_event_queued;
struct kgsl_device *device;
unsigned int ctx_offset;
struct kgsl_iommu_register_list *iommu_reg_list;
@@ -222,4 +218,18 @@
struct kgsl_iommu *iommu;
};
+/*
+ * struct kgsl_iommu_disable_clk_param - Parameter struct for disble clk event
+ * @mmu: The mmu pointer
+ * @rb_level: the rb level in which the timestamp of the event belongs to
+ * @ctx_id: The IOMMU context whose clock is to be turned off
+ * @ts: Timestamp on which clock is to be disabled
+ */
+struct kgsl_iommu_disable_clk_param {
+ struct kgsl_mmu *mmu;
+ int rb_level;
+ int ctx_id;
+ unsigned int ts;
+};
+
#endif
diff --git a/drivers/gpu/msm/kgsl_mmu.h b/drivers/gpu/msm/kgsl_mmu.h
index 040a3a7..5e3386a 100644
--- a/drivers/gpu/msm/kgsl_mmu.h
+++ b/drivers/gpu/msm/kgsl_mmu.h
@@ -144,11 +144,12 @@
void (*mmu_pagefault_resume)
(struct kgsl_mmu *mmu);
void (*mmu_disable_clk_on_ts)
- (struct kgsl_mmu *mmu, uint32_t ts, bool ts_valid);
+ (struct kgsl_mmu *mmu,
+ uint32_t ts, int ctx_id);
int (*mmu_enable_clk)
(struct kgsl_mmu *mmu, int ctx_id);
void (*mmu_disable_clk)
- (struct kgsl_mmu *mmu);
+ (struct kgsl_mmu *mmu, int ctx_id);
phys_addr_t (*mmu_get_default_ttbr0)(struct kgsl_mmu *mmu,
unsigned int unit_id,
enum kgsl_iommu_context_id ctx_id);
@@ -327,17 +328,18 @@
return 0;
}
-static inline void kgsl_mmu_disable_clk(struct kgsl_mmu *mmu)
+static inline void kgsl_mmu_disable_clk(struct kgsl_mmu *mmu, int ctx_id)
{
if (mmu->mmu_ops && mmu->mmu_ops->mmu_disable_clk)
- mmu->mmu_ops->mmu_disable_clk(mmu);
+ mmu->mmu_ops->mmu_disable_clk(mmu, ctx_id);
}
static inline void kgsl_mmu_disable_clk_on_ts(struct kgsl_mmu *mmu,
- unsigned int ts, bool ts_valid)
+ unsigned int ts,
+ int ctx_id)
{
if (mmu->mmu_ops && mmu->mmu_ops->mmu_disable_clk_on_ts)
- mmu->mmu_ops->mmu_disable_clk_on_ts(mmu, ts, ts_valid);
+ mmu->mmu_ops->mmu_disable_clk_on_ts(mmu, ts, ctx_id);
}
static inline unsigned int kgsl_mmu_get_int_mask(void)
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index 96ff1b8..c00e978 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -1430,8 +1430,6 @@
break;
}
- kgsl_mmu_disable_clk_on_ts(&device->mmu, 0, false);
-
return 0;
}
diff --git a/drivers/hwmon/qpnp-adc-current.c b/drivers/hwmon/qpnp-adc-current.c
index 32c94dc..067a887 100644
--- a/drivers/hwmon/qpnp-adc-current.c
+++ b/drivers/hwmon/qpnp-adc-current.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
@@ -129,6 +129,12 @@
#define QPNP_BIT_SHIFT_8 8
#define QPNP_RSENSE_MSB_SIGN_CHECK 0x80
#define QPNP_ADC_COMPLETION_TIMEOUT HZ
+#define SMBB_BAT_IF_TRIM_CNST_RDS_MASK 0x7
+#define SMBB_BAT_IF_TRIM_CNST_RDS_MASK_CONST 2
+#define QPNP_IADC1_USR_TRIM2_ADC_FULLSCALE1_CONST 127
+#define QPNP_IADC_RSENSE_DEFAULT_VALUE 7800000
+#define QPNP_IADC_RSENSE_DEFAULT_TYPEB_GF 9000000
+#define QPNP_IADC_RSENSE_DEFAULT_TYPEB_SMIC 9700000
struct qpnp_iadc_comp {
bool ext_rsense;
@@ -143,6 +149,7 @@
struct qpnp_adc_drv *adc;
int32_t rsense;
bool external_rsense;
+ bool default_internal_rsense;
struct device *iadc_hwmon;
struct list_head list;
int64_t die_temp;
@@ -153,11 +160,20 @@
struct work_struct trigger_completion_work;
bool skip_auto_calibrations;
bool iadc_poll_eoc;
+ u16 batt_id_trim_cnst_rds;
+ int rds_trim_default_type;
+ bool rds_trim_default_check;
+ int32_t rsense_workaround_value;
struct sensor_device_attribute sens_attr[0];
};
LIST_HEAD(qpnp_iadc_device_list);
+enum qpnp_iadc_rsense_rds_workaround {
+ QPNP_IADC_RDS_DEFAULT_TYPEA,
+ QPNP_IADC_RDS_DEFAULT_TYPEB,
+};
+
static int32_t qpnp_iadc_read_reg(struct qpnp_iadc_chip *iadc,
uint32_t reg, u8 *data)
{
@@ -573,6 +589,67 @@
}
EXPORT_SYMBOL(qpnp_iadc_comp_result);
+static int qpnp_iadc_rds_trim_update_check(struct qpnp_iadc_chip *iadc)
+{
+ int rc = 0;
+ u8 trim2_val = 0, smbb_batt_trm_data = 0;
+
+ if (!iadc->rds_trim_default_check) {
+ pr_debug("No internal rds trim check needed\n");
+ return 0;
+ }
+
+ rc = qpnp_iadc_read_reg(iadc, QPNP_IADC_NOMINAL_RSENSE, &trim2_val);
+ if (rc < 0) {
+ pr_err("qpnp adc trim2_fullscale1 reg read failed %d\n", rc);
+ return rc;
+ }
+
+ rc = spmi_ext_register_readl(iadc->adc->spmi->ctrl, iadc->adc->slave,
+ iadc->batt_id_trim_cnst_rds, &smbb_batt_trm_data, 1);
+ if (rc < 0) {
+ pr_err("batt_id trim_cnst rds reg read failed %d\n", rc);
+ return rc;
+ }
+
+ pr_debug("n_trim:0x%x smb_trm:0x%x\n", trim2_val, smbb_batt_trm_data);
+
+ if (iadc->rds_trim_default_type == QPNP_IADC_RDS_DEFAULT_TYPEA) {
+ if (((smbb_batt_trm_data & SMBB_BAT_IF_TRIM_CNST_RDS_MASK) ==
+ SMBB_BAT_IF_TRIM_CNST_RDS_MASK_CONST) &&
+ (trim2_val == QPNP_IADC1_USR_TRIM2_ADC_FULLSCALE1_CONST)) {
+ iadc->rsense_workaround_value =
+ QPNP_IADC_RSENSE_DEFAULT_VALUE;
+ iadc->default_internal_rsense = true;
+ }
+ } else if (iadc->rds_trim_default_type ==
+ QPNP_IADC_RDS_DEFAULT_TYPEB) {
+ if (((smbb_batt_trm_data & SMBB_BAT_IF_TRIM_CNST_RDS_MASK) >=
+ SMBB_BAT_IF_TRIM_CNST_RDS_MASK_CONST) &&
+ (trim2_val == QPNP_IADC1_USR_TRIM2_ADC_FULLSCALE1_CONST)) {
+ iadc->rsense_workaround_value =
+ QPNP_IADC_RSENSE_DEFAULT_VALUE;
+ iadc->default_internal_rsense = true;
+ } else if (((smbb_batt_trm_data &
+ SMBB_BAT_IF_TRIM_CNST_RDS_MASK)
+ < SMBB_BAT_IF_TRIM_CNST_RDS_MASK_CONST) &&
+ (trim2_val ==
+ QPNP_IADC1_USR_TRIM2_ADC_FULLSCALE1_CONST)) {
+ if (iadc->iadc_comp.id == COMP_ID_GF) {
+ iadc->rsense_workaround_value =
+ QPNP_IADC_RSENSE_DEFAULT_TYPEB_GF;
+ iadc->default_internal_rsense = true;
+ } else if (iadc->iadc_comp.id == COMP_ID_SMIC) {
+ iadc->rsense_workaround_value =
+ QPNP_IADC_RSENSE_DEFAULT_TYPEB_SMIC;
+ iadc->default_internal_rsense = true;
+ }
+ }
+ }
+
+ return 0;
+}
+
static int32_t qpnp_iadc_comp_info(struct qpnp_iadc_chip *iadc)
{
int rc = 0;
@@ -948,6 +1025,11 @@
return rc;
}
+ if (iadc->default_internal_rsense) {
+ *rsense = iadc->rsense_workaround_value;
+ return rc;
+ }
+
rc = qpnp_iadc_read_reg(iadc, QPNP_IADC_NOMINAL_RSENSE, &rslt_rsense);
if (rc < 0) {
pr_err("qpnp adc rsense read failed with %d\n", rc);
@@ -968,6 +1050,8 @@
*rsense = QPNP_IADC_INTERNAL_RSENSE_N_OHMS_FACTOR +
(rslt_rsense * QPNP_IADC_RSENSE_LSB_N_OHMS_PER_BIT);
+ pr_debug("rsense value is %d\n", *rsense);
+
return rc;
}
EXPORT_SYMBOL(qpnp_iadc_get_rsense);
@@ -1258,6 +1342,7 @@
struct qpnp_adc_drv *adc_qpnp;
struct device_node *node = spmi->dev.of_node;
struct device_node *child;
+ struct resource *res;
int rc, count_adc_channel_list = 0, i = 0;
for_each_child_of_node(node, child)
@@ -1292,6 +1377,22 @@
return rc;
}
+ res = spmi_get_resource_byname(spmi, NULL, IORESOURCE_MEM,
+ "batt-id-trim-cnst-rds");
+ if (!res) {
+ dev_err(&spmi->dev, "failed to read batt_id trim register\n");
+ return -EINVAL;
+ }
+ iadc->batt_id_trim_cnst_rds = res->start;
+ rc = of_property_read_u32(node, "qcom,use-default-rds-trim",
+ &iadc->rds_trim_default_type);
+ if (rc)
+ pr_debug("No trim workaround needed\n");
+ else {
+ pr_debug("Use internal RDS trim workaround\n");
+ iadc->rds_trim_default_check = true;
+ }
+
iadc->vadc_dev = qpnp_get_vadc(&spmi->dev, "iadc");
if (IS_ERR(iadc->vadc_dev)) {
rc = PTR_ERR(iadc->vadc_dev);
@@ -1345,6 +1446,12 @@
goto fail;
}
+ rc = qpnp_iadc_rds_trim_update_check(iadc);
+ if (rc) {
+ dev_err(&spmi->dev, "Rds trim update failed!\n");
+ goto fail;
+ }
+
dev_set_drvdata(&spmi->dev, iadc);
list_add(&iadc->list, &qpnp_iadc_device_list);
rc = qpnp_iadc_calibrate_for_trim(iadc, true);
diff --git a/drivers/input/touchscreen/gt9xx/gt9xx.c b/drivers/input/touchscreen/gt9xx/gt9xx.c
index 91d787f..0d75869 100644
--- a/drivers/input/touchscreen/gt9xx/gt9xx.c
+++ b/drivers/input/touchscreen/gt9xx/gt9xx.c
@@ -77,12 +77,6 @@
#define GTP_MAX_TOUCH 5
#define GTP_ESD_CHECK_CIRCLE_MS 2000
-#if GTP_HAVE_TOUCH_KEY
-static const u16 touch_key_array[] = {KEY_MENU, KEY_HOMEPAGE, KEY_BACK};
-#define GTP_MAX_KEY_NUM (sizeof(touch_key_array)/sizeof(touch_key_array[0]))
-
-#endif
-
static void gtp_int_sync(struct goodix_ts_data *ts, int ms);
static int gtp_i2c_test(struct i2c_client *client);
static int goodix_power_off(struct goodix_ts_data *ts);
@@ -105,15 +99,14 @@
static int gtp_init_ext_watchdog(struct i2c_client *client);
#endif
-#if GTP_SLIDE_WAKEUP
-enum doze_status {
+enum doze {
DOZE_DISABLED = 0,
DOZE_ENABLED = 1,
DOZE_WAKEUP = 2,
};
-static enum doze_status = DOZE_DISABLED;
+static enum doze doze_status = DOZE_DISABLED;
static s8 gtp_enter_doze(struct goodix_ts_data *ts);
-#endif
+
bool init_done;
static u8 chip_gt9xxs; /* true if ic is gt9xxs, like gt915s */
u8 grp_cfg_version;
@@ -163,11 +156,11 @@
dev_err(&client->dev, "I2C retry: %d\n", retries + 1);
}
if (retries == GTP_I2C_RETRY_5) {
-#if GTP_SLIDE_WAKEUP
- /* reset chip would quit doze mode */
- if (DOZE_ENABLED == doze_status)
- return ret;
-#endif
+ if (ts->pdata->slide_wakeup)
+ /* reset chip would quit doze mode */
+ if (DOZE_ENABLED == doze_status)
+ return ret;
+
if (init_done)
gtp_reset_guitar(ts, 10);
else
@@ -209,10 +202,10 @@
dev_err(&client->dev, "I2C retry: %d\n", retries + 1);
}
if ((retries == GTP_I2C_RETRY_5)) {
-#if GTP_SLIDE_WAKEUP
- if (DOZE_ENABLED == doze_status)
- return ret;
-#endif
+ if (ts->pdata->slide_wakeup)
+ if (DOZE_ENABLED == doze_status)
+ return ret;
+
if (init_done)
gtp_reset_guitar(ts, 10);
else
@@ -278,24 +271,25 @@
*********************************************************/
int gtp_send_cfg(struct goodix_ts_data *ts)
{
- int ret;
-#if GTP_DRIVER_SEND_CFG
- int retry = 0;
+ int ret = 0;
+ int retry;
- if (ts->fixed_cfg) {
- dev_dbg(&ts->client->dev,
- "Ic fixed config, no config sent!");
- ret = 2;
- } else {
- for (retry = 0; retry < GTP_I2C_RETRY_5; retry++) {
- ret = gtp_i2c_write(ts->client,
- ts->config_data,
- GTP_CONFIG_MAX_LENGTH + GTP_ADDR_LENGTH);
- if (ret > 0)
- break;
+ if (ts->pdata->driver_send_cfg) {
+ if (ts->fixed_cfg) {
+ dev_dbg(&ts->client->dev,
+ "Ic fixed config, no config sent!");
+ ret = 2;
+ } else {
+ for (retry = 0; retry < GTP_I2C_RETRY_5; retry++) {
+ ret = gtp_i2c_write(ts->client,
+ ts->config_data,
+ GTP_CONFIG_MAX_LENGTH +
+ GTP_ADDR_LENGTH);
+ if (ret > 0)
+ break;
+ }
}
}
-#endif
return ret;
}
@@ -355,9 +349,8 @@
static void gtp_touch_down(struct goodix_ts_data *ts, int id, int x, int y,
int w)
{
-#if GTP_CHANGE_X2Y
- swap(x, y);
-#endif
+ if (ts->pdata->change_x2y)
+ swap(x, y);
input_mt_slot(ts->input_dev, id);
input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);
@@ -402,9 +395,7 @@
u8 finger = 0;
static u16 pre_touch;
static u8 pre_key;
-#if GTP_WITH_PEN
static u8 pre_pen;
-#endif
u8 key_value = 0;
u8 *coor_data = NULL;
s32 input_x = 0;
@@ -414,10 +405,7 @@
s32 i = 0;
int ret = -1;
struct goodix_ts_data *ts = NULL;
-
-#if GTP_SLIDE_WAKEUP
u8 doze_buf[3] = {0x81, 0x4B};
-#endif
ts = container_of(work, struct goodix_ts_data, work);
#ifdef CONFIG_GT9XX_TOUCHPANEL_UPDATE
@@ -425,55 +413,59 @@
return;
#endif
-#if GTP_SLIDE_WAKEUP
- if (DOZE_ENABLED == doze_status) {
- ret = gtp_i2c_read(ts->client, doze_buf, 3);
- if (ret > 0) {
- if (doze_buf[2] == 0xAA) {
- dev_dbg(&ts->client->dev,
- "Slide(0xAA) To Light up the screen!");
- doze_status = DOZE_WAKEUP;
- input_report_key(
- ts->input_dev, KEY_POWER, 1);
- input_sync(ts->input_dev);
- input_report_key(
- ts->input_dev, KEY_POWER, 0);
- input_sync(ts->input_dev);
- /* clear 0x814B */
- doze_buf[2] = 0x00;
- gtp_i2c_write(ts->client, doze_buf, 3);
- } else if (doze_buf[2] == 0xBB) {
- dev_dbg(&ts->client->dev,
- "Slide(0xBB) To Light up the screen!");
- doze_status = DOZE_WAKEUP;
- input_report_key(ts->input_dev, KEY_POWER, 1);
- input_sync(ts->input_dev);
- input_report_key(ts->input_dev, KEY_POWER, 0);
- input_sync(ts->input_dev);
- /* clear 0x814B*/
- doze_buf[2] = 0x00;
- gtp_i2c_write(ts->client, doze_buf, 3);
- } else if (0xC0 == (doze_buf[2] & 0xC0)) {
- dev_dbg(&ts->client->dev,
- "double click to light up the screen!");
- doze_status = DOZE_WAKEUP;
- input_report_key(ts->input_dev, KEY_POWER, 1);
- input_sync(ts->input_dev);
- input_report_key(ts->input_dev, KEY_POWER, 0);
- input_sync(ts->input_dev);
- /* clear 0x814B */
- doze_buf[2] = 0x00;
- gtp_i2c_write(ts->client, doze_buf, 3);
- } else {
- gtp_enter_doze(ts);
+ if (ts->pdata->slide_wakeup) {
+ if (DOZE_ENABLED == doze_status) {
+ ret = gtp_i2c_read(ts->client, doze_buf, 3);
+ if (ret > 0) {
+ if (doze_buf[2] == 0xAA) {
+ dev_dbg(&ts->client->dev,
+ "Slide(0xAA) To Light up the screen!");
+ doze_status = DOZE_WAKEUP;
+ input_report_key(
+ ts->input_dev, KEY_POWER, 1);
+ input_sync(ts->input_dev);
+ input_report_key(
+ ts->input_dev, KEY_POWER, 0);
+ input_sync(ts->input_dev);
+ /* clear 0x814B */
+ doze_buf[2] = 0x00;
+ gtp_i2c_write(ts->client, doze_buf, 3);
+ } else if (doze_buf[2] == 0xBB) {
+ dev_dbg(&ts->client->dev,
+ "Slide(0xBB) To Light up the screen!");
+ doze_status = DOZE_WAKEUP;
+ input_report_key(ts->input_dev,
+ KEY_POWER, 1);
+ input_sync(ts->input_dev);
+ input_report_key(ts->input_dev,
+ KEY_POWER, 0);
+ input_sync(ts->input_dev);
+ /* clear 0x814B*/
+ doze_buf[2] = 0x00;
+ gtp_i2c_write(ts->client, doze_buf, 3);
+ } else if (0xC0 == (doze_buf[2] & 0xC0)) {
+ dev_dbg(&ts->client->dev,
+ "double click to light up the screen!");
+ doze_status = DOZE_WAKEUP;
+ input_report_key(ts->input_dev,
+ KEY_POWER, 1);
+ input_sync(ts->input_dev);
+ input_report_key(ts->input_dev,
+ KEY_POWER, 0);
+ input_sync(ts->input_dev);
+ /* clear 0x814B */
+ doze_buf[2] = 0x00;
+ gtp_i2c_write(ts->client, doze_buf, 3);
+ } else {
+ gtp_enter_doze(ts);
+ }
}
- }
- if (ts->use_irq)
- gtp_irq_enable(ts);
+ if (ts->use_irq)
+ gtp_irq_enable(ts);
- return;
+ return;
+ }
}
-#endif
ret = gtp_i2c_read(ts->client, point_data, 12);
if (ret < 0) {
@@ -514,15 +506,16 @@
pre_key = key_value;
-#if GTP_WITH_PEN
- if (pre_pen && (touch_num == 0)) {
- dev_dbg(&ts->client->dev, "Pen touch UP(Slot)!");
- input_report_key(ts->input_dev, BTN_TOOL_PEN, 0);
- input_mt_slot(ts->input_dev, 5);
- input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, -1);
- pre_pen = 0;
+ if (ts->pdata->with_pen) {
+ if (pre_pen && (touch_num == 0)) {
+ dev_dbg(&ts->client->dev, "Pen touch UP(Slot)!");
+ input_report_key(ts->input_dev, BTN_TOOL_PEN, 0);
+ input_mt_slot(ts->input_dev, 5);
+ input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, -1);
+ pre_pen = 0;
+ }
}
-#endif
+
if (pre_touch || touch_num) {
s32 pos = 0;
u16 touch_index = 0;
@@ -530,45 +523,45 @@
coor_data = &point_data[3];
if (touch_num) {
id = coor_data[pos] & 0x0F;
-#if GTP_WITH_PEN
- id = coor_data[pos];
- if (id == 128) {
- dev_dbg(&ts->client->dev,
- "Pen touch DOWN(Slot)!");
- input_x = coor_data[pos + 1]
- | (coor_data[pos + 2] << 8);
- input_y = coor_data[pos + 3]
- | (coor_data[pos + 4] << 8);
- input_w = coor_data[pos + 5]
- | (coor_data[pos + 6] << 8);
+ if (ts->pdata->with_pen) {
+ id = coor_data[pos];
+ if (id == 128) {
+ dev_dbg(&ts->client->dev,
+ "Pen touch DOWN(Slot)!");
+ input_x = coor_data[pos + 1]
+ | (coor_data[pos + 2] << 8);
+ input_y = coor_data[pos + 3]
+ | (coor_data[pos + 4] << 8);
+ input_w = coor_data[pos + 5]
+ | (coor_data[pos + 6] << 8);
- input_report_key(ts->input_dev,
- BTN_TOOL_PEN, 1);
- input_mt_slot(ts->input_dev, 5);
- input_report_abs(ts->input_dev,
- ABS_MT_TRACKING_ID, 5);
- input_report_abs(ts->input_dev,
- ABS_MT_POSITION_X, input_x);
- input_report_abs(ts->input_dev,
- ABS_MT_POSITION_Y, input_y);
- input_report_abs(ts->input_dev,
- ABS_MT_TOUCH_MAJOR, input_w);
- dev_dbg(&ts->client->dev,
- "Pen/Stylus: (%d, %d)[%d]",
- input_x, input_y, input_w);
- pre_pen = 1;
- pre_touch = 0;
+ input_report_key(ts->input_dev,
+ BTN_TOOL_PEN, 1);
+ input_mt_slot(ts->input_dev, 5);
+ input_report_abs(ts->input_dev,
+ ABS_MT_TRACKING_ID, 5);
+ input_report_abs(ts->input_dev,
+ ABS_MT_POSITION_X, input_x);
+ input_report_abs(ts->input_dev,
+ ABS_MT_POSITION_Y, input_y);
+ input_report_abs(ts->input_dev,
+ ABS_MT_TOUCH_MAJOR, input_w);
+ dev_dbg(&ts->client->dev,
+ "Pen/Stylus: (%d, %d)[%d]",
+ input_x, input_y, input_w);
+ pre_pen = 1;
+ pre_touch = 0;
+ }
}
-#endif
touch_index |= (0x01<<id);
}
for (i = 0; i < GTP_MAX_TOUCH; i++) {
-#if GTP_WITH_PEN
- if (pre_pen == 1)
- break;
-#endif
+ if (ts->pdata->with_pen)
+ if (pre_pen == 1)
+ break;
+
if (touch_index & (0x01<<i)) {
input_x = coor_data[pos + 1] |
coor_data[pos + 2] << 8;
@@ -673,7 +666,6 @@
}
#if defined(CONFIG_HAS_EARLYSUSPEND) || defined(CONFIG_FB)
-#if GTP_SLIDE_WAKEUP
/*******************************************************
Function:
Enter doze mode for sliding wakeup.
@@ -690,9 +682,9 @@
(u8)(GTP_REG_SLEEP >> 8),
(u8)GTP_REG_SLEEP, 8};
-#if GTP_DBL_CLK_WAKEUP
- i2c_control_buf[2] = 0x09;
-#endif
+ if (ts->pdata->dbl_clk_wakeup)
+ i2c_control_buf[2] = 0x09;
+
gtp_irq_disable(ts);
while (retry++ < GTP_I2C_RETRY_3) {
@@ -721,7 +713,6 @@
gtp_irq_enable(ts);
return ret;
}
-#else
/**
* gtp_enter_sleep - Enter sleep mode
* @ts: driver private data
@@ -767,7 +758,6 @@
return ret;
}
}
-#endif /* !GTP_SLIDE_WAKEUP */
/*******************************************************
Function:
@@ -813,33 +803,33 @@
"Wakeup sleep send config success.");
} else {
err_retry:
-#if GTP_SLIDE_WAKEUP
- /* wakeup not by slide */
- if (DOZE_WAKEUP != doze_status)
- gtp_reset_guitar(ts, 10);
- else
- /* wakeup by slide */
- doze_status = DOZE_DISABLED;
-#else
- if (chip_gt9xxs == 1) {
- gtp_reset_guitar(ts, 10);
+ if (ts->pdata->slide_wakeup) { /* wakeup not by slide */
+ if (DOZE_WAKEUP != doze_status)
+ gtp_reset_guitar(ts, 10);
+ else
+ /* wakeup by slide */
+ doze_status = DOZE_DISABLED;
} else {
- ret = gpio_direction_output(ts->pdata->irq_gpio, 1);
- usleep(5000);
+ if (chip_gt9xxs == 1) {
+ gtp_reset_guitar(ts, 10);
+ } else {
+ ret = gpio_direction_output(
+ ts->pdata->irq_gpio, 1);
+ usleep(5000);
+ }
}
-#endif
ret = gtp_i2c_test(ts->client);
if (ret == 2) {
dev_dbg(&ts->client->dev, "GTP wakeup sleep.");
-#if (!GTP_SLIDE_WAKEUP)
- if (chip_gt9xxs == 0) {
- gtp_int_sync(ts, 25);
- msleep(20);
+ if (!ts->pdata->slide_wakeup) {
+ if (chip_gt9xxs == 0) {
+ gtp_int_sync(ts, 25);
+ msleep(20);
#if GTP_ESD_PROTECT
- gtp_init_ext_watchdog(ts->client);
+ gtp_init_ext_watchdog(ts->client);
#endif
+ }
}
-#endif
return ret;
}
gtp_reset_guitar(ts, 20);
@@ -863,123 +853,126 @@
static int gtp_init_panel(struct goodix_ts_data *ts)
{
struct i2c_client *client = ts->client;
- unsigned char *config_data;
+ unsigned char *config_data = NULL;
int ret = -EIO;
-
-#if GTP_DRIVER_SEND_CFG
int i;
u8 check_sum = 0;
u8 opr_buf[16];
u8 sensor_id = 0;
- for (i = 0; i < GOODIX_MAX_CFG_GROUP; i++)
- dev_dbg(&client->dev, "Config Groups(%d) Lengths: %d",
- i, ts->pdata->config_data_len[i]);
+ if (ts->pdata->driver_send_cfg) {
+ for (i = 0; i < GOODIX_MAX_CFG_GROUP; i++)
+ dev_dbg(&client->dev, "Config Groups(%d) Lengths: %d",
+ i, ts->pdata->config_data_len[i]);
- ret = gtp_i2c_read_dbl_check(ts->client, 0x41E4, opr_buf, 1);
- if (SUCCESS == ret) {
- if (opr_buf[0] != 0xBE) {
- ts->fw_error = 1;
+ ret = gtp_i2c_read_dbl_check(ts->client, 0x41E4, opr_buf, 1);
+ if (SUCCESS == ret) {
+ if (opr_buf[0] != 0xBE) {
+ ts->fw_error = 1;
+ dev_err(&client->dev,
+ "Firmware error, no config sent!");
+ return -EINVAL;
+ }
+ }
+
+ for (i = 1; i < GOODIX_MAX_CFG_GROUP; i++) {
+ if (ts->pdata->config_data_len[i])
+ break;
+ }
+
+ if (i == GOODIX_MAX_CFG_GROUP) {
+ sensor_id = 0;
+ } else {
+ ret = gtp_i2c_read_dbl_check(ts->client,
+ GTP_REG_SENSOR_ID, &sensor_id, 1);
+ if (SUCCESS == ret) {
+ if (sensor_id >= GOODIX_MAX_CFG_GROUP) {
+ dev_err(&client->dev,
+ "Invalid sensor_id(0x%02X), No Config Sent!",
+ sensor_id);
+ return -EINVAL;
+ }
+ } else {
+ dev_err(&client->dev,
+ "Failed to get sensor_id, No config sent!");
+ return -EINVAL;
+ }
+ }
+
+ dev_info(&client->dev, "Sensor ID selected: %d", sensor_id);
+
+ if (ts->pdata->config_data_len[sensor_id] <
+ GTP_CONFIG_MIN_LENGTH ||
+ !ts->pdata->config_data[sensor_id]) {
dev_err(&client->dev,
- "Firmware error, no config sent!");
+ "Sensor_ID(%d) matches with NULL or invalid config group!\n",
+ sensor_id);
return -EINVAL;
}
- }
- for (i = 1; i < GOODIX_MAX_CFG_GROUP; i++) {
- if (ts->pdata->config_data_len[i])
- break;
- }
- if (i == GOODIX_MAX_CFG_GROUP) {
- sensor_id = 0;
- } else {
- ret = gtp_i2c_read_dbl_check(ts->client, GTP_REG_SENSOR_ID,
- &sensor_id, 1);
- if (SUCCESS == ret) {
- if (sensor_id >= GOODIX_MAX_CFG_GROUP) {
- dev_err(&client->dev,
- "Invalid sensor_id(0x%02X), No Config Sent!",
- sensor_id);
- return -EINVAL;
+ ret = gtp_i2c_read_dbl_check(ts->client, GTP_REG_CONFIG_DATA,
+ &opr_buf[0], 1);
+ if (ret == SUCCESS) {
+ if (opr_buf[0] < 90) {
+ /* backup group config version */
+ grp_cfg_version =
+ ts->pdata->
+ config_data[sensor_id][GTP_ADDR_LENGTH];
+ ts->pdata->
+ config_data[sensor_id][GTP_ADDR_LENGTH]
+ = 0x00;
+ ts->fixed_cfg = 0;
+ } else {
+ /* treated as fixed config, not send config */
+ dev_warn(&client->dev,
+ "Ic fixed config with config version(%d, 0x%02X)",
+ opr_buf[0], opr_buf[0]);
+ ts->fixed_cfg = 1;
}
} else {
dev_err(&client->dev,
- "Failed to get sensor_id, No config sent!");
+ "Failed to get ic config version!No config sent!");
return -EINVAL;
}
- }
- dev_info(&client->dev, "Sensor ID selected: %d", sensor_id);
-
- if (ts->pdata->config_data_len[sensor_id] < GTP_CONFIG_MIN_LENGTH ||
- !ts->pdata->config_data[sensor_id]) {
- dev_err(&client->dev,
- "Sensor_ID(%d) matches with NULL or invalid config group!\n",
- sensor_id);
- return -EINVAL;
- }
-
- ret = gtp_i2c_read_dbl_check(ts->client, GTP_REG_CONFIG_DATA,
- &opr_buf[0], 1);
- if (ret == SUCCESS) {
- if (opr_buf[0] < 90) {
- /* backup group config version */
- grp_cfg_version =
- ts->pdata->config_data[sensor_id][GTP_ADDR_LENGTH];
- ts->pdata->config_data[sensor_id][GTP_ADDR_LENGTH] =
- 0x00;
- ts->fixed_cfg = 0;
- } else {
- /* treated as fixed config, not send config */
- dev_warn(&client->dev,
- "Ic fixed config with config version(%d, 0x%02X)",
- opr_buf[0], opr_buf[0]);
- ts->fixed_cfg = 1;
- }
- } else {
- dev_err(&client->dev,
- "Failed to get ic config version!No config sent!");
- return -EINVAL;
- }
-
- config_data = ts->pdata->config_data[sensor_id];
- ts->config_data = ts->pdata->config_data[sensor_id];
- ts->gtp_cfg_len = ts->pdata->config_data_len[sensor_id];
+ config_data = ts->pdata->config_data[sensor_id];
+ ts->config_data = ts->pdata->config_data[sensor_id];
+ ts->gtp_cfg_len = ts->pdata->config_data_len[sensor_id];
#if GTP_CUSTOM_CFG
- config_data[RESOLUTION_LOC] =
- (unsigned char)(GTP_MAX_WIDTH && 0xFF);
- config_data[RESOLUTION_LOC + 1] =
- (unsigned char)(GTP_MAX_WIDTH >> 8);
- config_data[RESOLUTION_LOC + 2] =
- (unsigned char)(GTP_MAX_HEIGHT && 0xFF);
- config_data[RESOLUTION_LOC + 3] =
- (unsigned char)(GTP_MAX_HEIGHT >> 8);
+ config_data[RESOLUTION_LOC] =
+ (unsigned char)(GTP_MAX_WIDTH && 0xFF);
+ config_data[RESOLUTION_LOC + 1] =
+ (unsigned char)(GTP_MAX_WIDTH >> 8);
+ config_data[RESOLUTION_LOC + 2] =
+ (unsigned char)(GTP_MAX_HEIGHT && 0xFF);
+ config_data[RESOLUTION_LOC + 3] =
+ (unsigned char)(GTP_MAX_HEIGHT >> 8);
- if (GTP_INT_TRIGGER == 0)
- config_data[TRIGGER_LOC] &= 0xfe;
- else if (GTP_INT_TRIGGER == 1)
- config_data[TRIGGER_LOC] |= 0x01;
+ if (GTP_INT_TRIGGER == 0)
+ config_data[TRIGGER_LOC] &= 0xfe;
+ else if (GTP_INT_TRIGGER == 1)
+ config_data[TRIGGER_LOC] |= 0x01;
#endif /* !GTP_CUSTOM_CFG */
- check_sum = 0;
- for (i = GTP_ADDR_LENGTH; i < ts->gtp_cfg_len; i++)
- check_sum += config_data[i];
+ check_sum = 0;
+ for (i = GTP_ADDR_LENGTH; i < ts->gtp_cfg_len; i++)
+ check_sum += config_data[i];
- config_data[ts->gtp_cfg_len] = (~check_sum) + 1;
+ config_data[ts->gtp_cfg_len] = (~check_sum) + 1;
-#else /* DRIVER NOT SEND CONFIG */
- ts->gtp_cfg_len = GTP_CONFIG_MAX_LENGTH;
- ret = gtp_i2c_read(ts->client, config_data,
+ } else { /* DRIVER NOT SEND CONFIG */
+ ts->gtp_cfg_len = GTP_CONFIG_MAX_LENGTH;
+ ret = gtp_i2c_read(ts->client, config_data,
ts->gtp_cfg_len + GTP_ADDR_LENGTH);
- if (ret < 0) {
- dev_err(&client->dev,
+ if (ret < 0) {
+ dev_err(&client->dev,
"Read Config Failed, Using DEFAULT Resolution & INT Trigger!\n");
- ts->abs_x_max = GTP_MAX_WIDTH;
- ts->abs_y_max = GTP_MAX_HEIGHT;
- ts->int_trigger_type = GTP_INT_TRIGGER;
- }
-#endif /* !DRIVER NOT SEND CONFIG */
+ ts->abs_x_max = GTP_MAX_WIDTH;
+ ts->abs_y_max = GTP_MAX_HEIGHT;
+ ts->int_trigger_type = GTP_INT_TRIGGER;
+ }
+ } /* !DRIVER NOT SEND CONFIG */
if ((ts->abs_x_max == 0) && (ts->abs_y_max == 0)) {
ts->abs_x_max = (config_data[RESOLUTION_LOC + 1] << 8)
@@ -1213,9 +1206,7 @@
{
int ret;
char phys[PHY_BUF_SIZE];
-#if GTP_HAVE_TOUCH_KEY
int index = 0;
-#endif
ts->input_dev = input_allocate_device();
if (ts->input_dev == NULL) {
@@ -1230,27 +1221,24 @@
__set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit);
input_mt_init_slots(ts->input_dev, 10);/* in case of "out of memory" */
-
- for (index = 0; index < ts->pdata->num_button; index++) {
- input_set_capability(ts->input_dev,
+ if (ts->pdata->have_touch_key) {
+ for (index = 0; index < ts->pdata->num_button; index++) {
+ input_set_capability(ts->input_dev,
EV_KEY, ts->pdata->button_map[index]);
+ }
}
+ if (ts->pdata->slide_wakeup)
+ input_set_capability(ts->input_dev, EV_KEY, KEY_POWER);
-#if GTP_SLIDE_WAKEUP
- input_set_capability(ts->input_dev, EV_KEY, KEY_POWER);
-#endif
+ if (ts->pdata->with_pen) { /* pen support */
+ __set_bit(BTN_TOOL_PEN, ts->input_dev->keybit);
+ __set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit);
+ __set_bit(INPUT_PROP_POINTER, ts->input_dev->propbit);
+ }
-#if GTP_WITH_PEN
- /* pen support */
- __set_bit(BTN_TOOL_PEN, ts->input_dev->keybit);
- __set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit);
- __set_bit(INPUT_PROP_POINTER, ts->input_dev->propbit);
-#endif
-
-#if GTP_CHANGE_X2Y
- swap(ts->abs_x_max, ts->abs_y_max);
-#endif
+ if (ts->pdata->change_x2y)
+ swap(ts->abs_x_max, ts->abs_y_max);
input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X,
0, ts->abs_x_max, 0, 0);
@@ -1850,6 +1838,25 @@
pdata->enable_power_off = of_property_read_bool(np,
"goodix,enable-power-off");
+
+ pdata->have_touch_key = of_property_read_bool(np,
+ "goodix,have-touch-key");
+
+ pdata->driver_send_cfg = of_property_read_bool(np,
+ "goodix,driver-send-cfg");
+
+ pdata->change_x2y = of_property_read_bool(np,
+ "goodix,change-x2y");
+
+ pdata->with_pen = of_property_read_bool(np,
+ "goodix,with-pen");
+
+ pdata->slide_wakeup = of_property_read_bool(np,
+ "goodix,slide-wakeup");
+
+ pdata->dbl_clk_wakeup = of_property_read_bool(np,
+ "goodix,dbl_clk_wakeup");
+
/* reset, irq gpio info */
pdata->reset_gpio = of_get_named_gpio_flags(np, "reset-gpios",
0, &pdata->reset_gpio_flags);
@@ -2113,8 +2120,6 @@
#endif
if (ts->use_irq)
free_irq(client->irq, ts);
- else
- hrtimer_cancel(&ts->timer);
cancel_work_sync(&ts->work);
flush_workqueue(ts->goodix_wq);
destroy_workqueue(ts->goodix_wq);
@@ -2178,8 +2183,6 @@
if (ts) {
if (ts->use_irq)
free_irq(client->irq, ts);
- else
- hrtimer_cancel(&ts->timer);
cancel_work_sync(&ts->work);
flush_workqueue(ts->goodix_wq);
@@ -2237,23 +2240,21 @@
gtp_esd_switch(ts->client, SWITCH_OFF);
#endif
-#if GTP_SLIDE_WAKEUP
- ret = gtp_enter_doze(ts);
-#else
- if (ts->use_irq)
- gtp_irq_disable(ts);
- else
- hrtimer_cancel(&ts->timer);
+ if (ts->pdata->slide_wakeup) {
+ ret = gtp_enter_doze(ts);
+ } else {
+ if (ts->use_irq)
+ gtp_irq_disable(ts);
- for (i = 0; i < GTP_MAX_TOUCH; i++)
- gtp_touch_up(ts, i);
+ for (i = 0; i < GTP_MAX_TOUCH; i++)
+ gtp_touch_up(ts, i);
- input_sync(ts->input_dev);
+ input_sync(ts->input_dev);
- ret = gtp_enter_sleep(ts);
-#endif
- if (ret < 0)
- dev_err(&ts->client->dev, "GTP early suspend failed.\n");
+ ret = gtp_enter_sleep(ts);
+ if (ret < 0)
+ dev_err(&ts->client->dev, "GTP early suspend failed.\n");
+ }
/* to avoid waking up while not sleeping,
* delay 48 + 10ms to ensure reliability
*/
@@ -2285,18 +2286,14 @@
mutex_lock(&ts->lock);
ret = gtp_wakeup_sleep(ts);
-#if GTP_SLIDE_WAKEUP
- doze_status = DOZE_DISABLED;
-#endif
+ if (ts->pdata->slide_wakeup)
+ doze_status = DOZE_DISABLED;
if (ret <= 0)
dev_err(&ts->client->dev, "GTP resume failed.\n");
if (ts->use_irq)
gtp_irq_enable(ts);
- else
- hrtimer_start(&ts->timer,
- ktime_set(1, 0), HRTIMER_MODE_REL);
#if GTP_ESD_PROTECT
gtp_esd_switch(ts->client, SWITCH_ON);
diff --git a/drivers/input/touchscreen/gt9xx/gt9xx.h b/drivers/input/touchscreen/gt9xx/gt9xx.h
index 0ba6895..3cedf26 100644
--- a/drivers/input/touchscreen/gt9xx/gt9xx.h
+++ b/drivers/input/touchscreen/gt9xx/gt9xx.h
@@ -63,6 +63,12 @@
u8 *config_data[GOODIX_MAX_CFG_GROUP];
u32 button_map[MAX_BUTTONS];
u8 num_button;
+ bool have_touch_key;
+ bool driver_send_cfg;
+ bool change_x2y;
+ bool with_pen;
+ bool slide_wakeup;
+ bool dbl_clk_wakeup;
};
struct goodix_ts_data {
spinlock_t irq_lock;
@@ -111,16 +117,7 @@
/***************************PART1:ON/OFF define*******************************/
#define GTP_CUSTOM_CFG 0
-#define GTP_CHANGE_X2Y 0
-#define GTP_DRIVER_SEND_CFG 1
-#define GTP_HAVE_TOUCH_KEY 1
#define GTP_ESD_PROTECT 0
-#define GTP_WITH_PEN 0
-
-/* This cannot work when enable-power-off is on */
-#define GTP_SLIDE_WAKEUP 0
-/* double-click wakeup, function together with GTP_SLIDE_WAKEUP */
-#define GTP_DBL_CLK_WAKEUP 0
#define GTP_IRQ_TAB {\
IRQ_TYPE_EDGE_RISING,\
diff --git a/drivers/iommu/msm_iommu_dev-v1.c b/drivers/iommu/msm_iommu_dev-v1.c
index bbbe77b..a9d164e 100644
--- a/drivers/iommu/msm_iommu_dev-v1.c
+++ b/drivers/iommu/msm_iommu_dev-v1.c
@@ -208,10 +208,14 @@
ret = of_platform_populate(pdev->dev.of_node,
msm_iommu_v1_ctx_match_table,
NULL, &pdev->dev);
- if (ret)
+ if (ret) {
pr_err("Failed to create iommu context device\n");
+ goto fail;
+ }
msm_iommu_add_drv(drvdata);
+ return 0;
+
fail:
__put_bus_vote_client(drvdata);
return ret;
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/msm.c b/drivers/media/platform/msm/camera_v2/msm.c
index 67f7c2b..f8f5110 100644
--- a/drivers/media/platform/msm/camera_v2/msm.c
+++ b/drivers/media/platform/msm/camera_v2/msm.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
@@ -29,6 +29,8 @@
#include "msm.h"
#include "msm_vb2.h"
#include "msm_sd.h"
+#include <media/msmb_generic_buf_mgr.h>
+
static struct v4l2_device *msm_v4l2_dev;
static struct list_head ordered_sd_list;
@@ -504,6 +506,7 @@
int msm_destroy_session(unsigned int session_id)
{
struct msm_session *session;
+ struct v4l2_subdev *buf_mgr_subdev;
session = msm_queue_find(msm_session_q, struct msm_session,
list, __msm_queue_find_session, &session_id);
@@ -515,6 +518,12 @@
mutex_destroy(&session->lock);
msm_delete_entry(msm_session_q, struct msm_session,
list, session);
+ buf_mgr_subdev = msm_buf_mngr_get_subdev();
+ if (buf_mgr_subdev) {
+ v4l2_subdev_call(buf_mgr_subdev, core, ioctl,
+ MSM_SD_SHUTDOWN, NULL);
+ } else
+ pr_err("%s: Buff manger device node is NULL\n", __func__);
return 0;
}
diff --git a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c
index 6994258..81d4eff 100644
--- a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c
+++ b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c
@@ -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
@@ -129,7 +129,6 @@
rc = -ENODEV;
return rc;
}
- buf_mngr_dev->msm_buf_mngr_open_cnt++;
return rc;
}
@@ -143,9 +142,6 @@
rc = -ENODEV;
return rc;
}
- buf_mngr_dev->msm_buf_mngr_open_cnt--;
- if (buf_mngr_dev->msm_buf_mngr_open_cnt == 0)
- msm_buf_mngr_sd_shutdown(buf_mngr_dev);
return rc;
}
diff --git a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.h b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.h
index 49fad22..82ea21f 100644
--- a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.h
+++ b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.h
@@ -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
@@ -36,6 +36,5 @@
spinlock_t buf_q_spinlock;
struct msm_sd_subdev subdev;
struct msm_sd_req_vb2_q vb2_ops;
- uint32_t msm_buf_mngr_open_cnt;
};
#endif
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/Makefile b/drivers/media/platform/msm/camera_v2/sensor/Makefile
index 280a9a0..d1ec5d8e 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/Makefile
+++ b/drivers/media/platform/msm/camera_v2/sensor/Makefile
@@ -4,7 +4,7 @@
ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/io
ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/cci
obj-$(CONFIG_MSMB_CAMERA) += cci/ io/ csiphy/ csid/ actuator/ flash/ eeprom/
-obj-$(CONFIG_MSM_CAMERA_SENSOR) += msm_sensor.o
+obj-$(CONFIG_MSM_CAMERA_SENSOR) += msm_sensor_init.o msm_sensor_driver.o msm_sensor.o
obj-$(CONFIG_S5K3L1YX) += s5k3l1yx.o
obj-$(CONFIG_IMX135) += imx135.o
obj-$(CONFIG_IMX134) += imx134.o
diff --git a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
index ea16ebd..ef8b996 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
@@ -411,6 +411,43 @@
return rc;
}
+static int32_t msm_actuator_set_position(
+ struct msm_actuator_ctrl_t *a_ctrl,
+ struct msm_actuator_set_position_t *set_pos)
+{
+ int32_t rc = 0;
+ int32_t index;
+ uint16_t next_lens_position;
+ uint16_t delay;
+ uint32_t hw_params = 0;
+ struct msm_camera_i2c_reg_setting reg_setting;
+ CDBG("%s Enter %d\n", __func__, __LINE__);
+ if (set_pos->number_of_steps == 0)
+ return rc;
+
+ a_ctrl->i2c_tbl_index = 0;
+ for (index = 0; index < set_pos->number_of_steps; index++) {
+ next_lens_position = set_pos->pos[index];
+ delay = set_pos->delay[index];
+ a_ctrl->func_tbl->actuator_parse_i2c_params(a_ctrl,
+ next_lens_position, hw_params, delay);
+
+ reg_setting.reg_setting = a_ctrl->i2c_reg_tbl;
+ reg_setting.size = a_ctrl->i2c_tbl_index;
+ reg_setting.data_type = a_ctrl->i2c_data_type;
+
+ rc = a_ctrl->i2c_client.i2c_func_tbl->i2c_write_table_w_microdelay(
+ &a_ctrl->i2c_client, ®_setting);
+ if (rc < 0) {
+ pr_err("%s Failed I2C write Line %d\n", __func__, __LINE__);
+ return rc;
+ }
+ a_ctrl->i2c_tbl_index = 0;
+ }
+ CDBG("%s exit %d\n", __func__, __LINE__);
+ return rc;
+}
+
static int32_t msm_actuator_init(struct msm_actuator_ctrl_t *a_ctrl,
struct msm_actuator_set_info_t *set_info) {
struct reg_settings_t *init_settings = NULL;
@@ -565,6 +602,12 @@
pr_err("move focus failed %d\n", rc);
break;
+ case CFG_SET_POSITION:
+ rc = a_ctrl->func_tbl->actuator_set_position(a_ctrl,
+ &cdata->cfg.setpos);
+ if (rc < 0)
+ pr_err("actuator_set_position failed %d\n", rc);
+ break;
default:
break;
}
@@ -919,6 +962,7 @@
.actuator_set_default_focus = msm_actuator_set_default_focus,
.actuator_init_focus = msm_actuator_init_focus,
.actuator_parse_i2c_params = msm_actuator_parse_i2c_params,
+ .actuator_set_position = msm_actuator_set_position,
},
};
diff --git a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.h b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.h
index 809c9cf..7ec9a49 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.h
+++ b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.h
@@ -43,6 +43,8 @@
struct damping_params_t *,
int8_t,
int16_t);
+ int32_t (*actuator_set_position)(struct msm_actuator_ctrl_t *,
+ struct msm_actuator_set_position_t *);
};
struct msm_actuator {
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 69c1faa..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
@@ -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
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/of_gpio.h>
#include <linux/delay.h>
+#include <linux/crc32.h>
#include "msm_sd.h"
#include "msm_cci.h"
#include "msm_eeprom.h"
@@ -26,17 +27,130 @@
DEFINE_MSM_MUTEX(msm_eeprom_mutex);
-int32_t msm_eeprom_config(struct msm_eeprom_ctrl_t *e_ctrl,
- void __user *argp)
+
+
+/**
+ * msm_eeprom_verify_sum - verify crc32 checksum
+ * @mem: data buffer
+ * @size: size of data buffer
+ * @sum: expected checksum
+ *
+ * Returns 0 if checksum match, -EINVAL otherwise.
+ */
+static int msm_eeprom_verify_sum(const char *mem, uint32_t size, uint32_t sum)
+{
+ uint32_t crc = ~0UL;
+
+ /* check overflow */
+ if (size > crc - sizeof(uint32_t))
+ return -EINVAL;
+
+ crc = crc32_le(crc, mem, size);
+ if (~crc != sum) {
+ CDBG("%s: expect 0x%x, result 0x%x\n", __func__, sum, ~crc);
+ return -EINVAL;
+ }
+ CDBG("%s: checksum pass 0x%x\n", __func__, sum);
+ return 0;
+}
+
+/**
+ * msm_eeprom_match_crc - verify multiple regions using crc
+ * @data: data block to be verified
+ *
+ * Iterates through all regions stored in @data. Regions with odd index
+ * are treated as data, and its next region is treated as checksum. Thus
+ * regions of even index must have valid_size of 4 or 0 (skip verification).
+ * Returns a bitmask of verified regions, starting from LSB. 1 indicates
+ * a checksum match, while 0 indicates checksum mismatch or not verified.
+ */
+static uint32_t msm_eeprom_match_crc(struct msm_eeprom_memory_block_t *data)
+{
+ int j, rc;
+ uint32_t *sum;
+ uint32_t ret = 0;
+ uint8_t *memptr;
+ struct msm_eeprom_memory_map_t *map;
+
+ if (!data) {
+ pr_err("%s data is NULL", __func__);
+ return -EINVAL;
+ }
+ map = data->map;
+ memptr = data->mapdata;
+
+ for (j = 0; j + 1 < data->num_map; j += 2) {
+ /* empty table or no checksum */
+ if (!map[j].mem.valid_size || !map[j+1].mem.valid_size) {
+ memptr += map[j].mem.valid_size
+ + map[j+1].mem.valid_size;
+ continue;
+ }
+ if (map[j+1].mem.valid_size != sizeof(uint32_t)) {
+ CDBG("%s: malformatted data mapping\n", __func__);
+ return -EINVAL;
+ }
+ sum = (uint32_t *) (memptr + map[j].mem.valid_size);
+ rc = msm_eeprom_verify_sum(memptr, map[j].mem.valid_size,
+ *sum);
+ if (!rc)
+ ret |= 1 << (j/2);
+ memptr += map[j].mem.valid_size + map[j+1].mem.valid_size;
+ }
+ 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)
+{
+ int rc;
+
+ /* check range */
+ if (cdata->cfg.read_data.num_bytes >
+ e_ctrl->cal_data.num_data) {
+ CDBG("%s: Invalid size. exp %u, req %u\n", __func__,
+ e_ctrl->cal_data.num_data,
+ cdata->cfg.read_data.num_bytes);
+ return -EINVAL;
+ }
+ if (!e_ctrl->cal_data.mapdata)
+ return -EFAULT;
+
+ rc = copy_to_user(cdata->cfg.read_data.dbuffer,
+ e_ctrl->cal_data.mapdata,
+ cdata->cfg.read_data.num_bytes);
+
+ /* should only be called once. free kernel resource */
+ if (!rc) {
+ kfree(e_ctrl->cal_data.mapdata);
+ kfree(e_ctrl->cal_data.map);
+ memset(&e_ctrl->cal_data, 0, sizeof(e_ctrl->cal_data));
+ }
+ return rc;
+}
+
+static int msm_eeprom_config(struct msm_eeprom_ctrl_t *e_ctrl,
+ void __user *argp)
{
struct msm_eeprom_cfg_data *cdata =
(struct msm_eeprom_cfg_data *)argp;
- int32_t rc = 0;
+ int rc = 0;
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,
@@ -45,25 +159,26 @@
case CFG_EEPROM_GET_CAL_DATA:
CDBG("%s E CFG_EEPROM_GET_CAL_DATA\n", __func__);
cdata->cfg.get_data.num_bytes =
- e_ctrl->num_bytes;
+ e_ctrl->cal_data.num_data;
break;
case CFG_EEPROM_READ_CAL_DATA:
- if (cdata->cfg.read_data.num_bytes <= e_ctrl->num_bytes) {
- CDBG("%s E CFG_EEPROM_READ_CAL_DATA\n", __func__);
- rc = copy_to_user(cdata->cfg.read_data.dbuffer,
- e_ctrl->memory_data,
- cdata->cfg.read_data.num_bytes);
- }
+ 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;
}
- CDBG("%s X\n", __func__);
+ CDBG("%s X rc: %d\n", __func__, rc);
return rc;
}
-static int32_t msm_eeprom_get_subdev_id(
- struct msm_eeprom_ctrl_t *e_ctrl, void *arg)
+
+static int msm_eeprom_get_subdev_id(struct msm_eeprom_ctrl_t *e_ctrl,
+ void *arg)
{
uint32_t *subdev_id = (uint32_t *)arg;
CDBG("%s E\n", __func__);
@@ -154,24 +269,28 @@
.open = msm_eeprom_open,
.close = msm_eeprom_close,
};
-
-int32_t read_eeprom_memory(struct msm_eeprom_ctrl_t *e_ctrl)
+/**
+ * read_eeprom_memory() - read map data into buffer
+ * @e_ctrl: eeprom control struct
+ * @block: block to be read
+ *
+ * This function iterates through blocks stored in block->map, reads each
+ * region and concatenate them into the pre-allocated block->mapdata
+ */
+static int read_eeprom_memory(struct msm_eeprom_ctrl_t *e_ctrl,
+ struct msm_eeprom_memory_block_t *block)
{
int rc = 0;
int j;
- uint8_t *memptr = NULL;
- struct msm_eeprom_board_info *eb_info = NULL;
- struct eeprom_memory_map_t *emap = NULL;
+ struct msm_eeprom_memory_map_t *emap = block->map;
+ uint8_t *memptr = block->mapdata;
+
if (!e_ctrl) {
pr_err("%s e_ctrl is NULL", __func__);
- rc = -1;
- return rc;
+ return -EINVAL;
}
- memptr = e_ctrl->memory_data;
- eb_info = e_ctrl->eboard_info;
- emap = eb_info->eeprom_map;
- for (j = 0; j < eb_info->num_blocks; j++) {
+ for (j = 0; j < block->num_map; j++) {
if (emap[j].page.valid_size) {
e_ctrl->i2c_client.addr_type = emap[j].page.addr_t;
rc = e_ctrl->i2c_client.i2c_func_tbl->i2c_write(
@@ -230,157 +349,85 @@
}
return rc;
}
-
-static int msm_eeprom_get_dt_data(struct msm_eeprom_ctrl_t *e_ctrl)
-{
- int rc = 0, i = 0;
- struct msm_eeprom_board_info *eb_info;
- struct msm_camera_power_ctrl_t *power_info =
- &e_ctrl->eboard_info->power_info;
- struct device_node *of_node = NULL;
- struct msm_camera_gpio_conf *gconf = NULL;
- uint16_t gpio_array_size = 0;
- uint16_t *gpio_array = NULL;
-
- eb_info = e_ctrl->eboard_info;
- if (e_ctrl->eeprom_device_type == MSM_CAMERA_SPI_DEVICE)
- of_node = e_ctrl->i2c_client.
- spi_client->spi_master->dev.of_node;
- else if (e_ctrl->eeprom_device_type == MSM_CAMERA_PLATFORM_DEVICE)
- of_node = e_ctrl->pdev->dev.of_node;
- else if (e_ctrl->eeprom_device_type == MSM_CAMERA_I2C_DEVICE)
- of_node = e_ctrl->i2c_client.client->dev.of_node;
-
- rc = msm_camera_get_dt_vreg_data(of_node, &power_info->cam_vreg,
- &power_info->num_vreg);
- if (rc < 0)
- return rc;
-
- 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);
- if (rc < 0)
- goto error1;
-
- power_info->gpio_conf = kzalloc(sizeof(struct msm_camera_gpio_conf),
- GFP_KERNEL);
- if (!power_info->gpio_conf) {
- rc = -ENOMEM;
- goto error2;
- }
- gconf = power_info->gpio_conf;
- gpio_array_size = of_gpio_count(of_node);
- CDBG("%s gpio count %d\n", __func__, gpio_array_size);
-
- if (gpio_array_size) {
- gpio_array = kzalloc(sizeof(uint16_t) * gpio_array_size,
- GFP_KERNEL);
- if (!gpio_array) {
- pr_err("%s failed %d\n", __func__, __LINE__);
- goto error3;
- }
- for (i = 0; i < gpio_array_size; i++) {
- gpio_array[i] = of_get_gpio(of_node, i);
- CDBG("%s gpio_array[%d] = %d\n", __func__, i,
- gpio_array[i]);
- }
-
- rc = msm_camera_get_dt_gpio_req_tbl(of_node, gconf,
- gpio_array, gpio_array_size);
- if (rc < 0) {
- pr_err("%s failed %d\n", __func__, __LINE__);
- goto error4;
- }
-
- rc = msm_camera_init_gpio_pin_tbl(of_node, gconf,
- gpio_array, gpio_array_size);
- if (rc < 0) {
- pr_err("%s failed %d\n", __func__, __LINE__);
- goto error4;
- }
- kfree(gpio_array);
- }
-
- return rc;
-error4:
- kfree(gpio_array);
-error3:
- kfree(power_info->gpio_conf);
-error2:
- kfree(power_info->cam_vreg);
-error1:
- kfree(power_info->power_setting);
- return rc;
-}
-
-static int msm_eeprom_alloc_memory_map(struct msm_eeprom_ctrl_t *e_ctrl,
- struct device_node *of)
+/**
+ * msm_eeprom_parse_memory_map() - parse memory map in device node
+ * @of: device node
+ * @data: memory block for output
+ *
+ * This functions parses @of to fill @data. It allocates map itself, parses
+ * the @of node, calculate total data length, and allocates required buffer.
+ * It only fills the map, but does not perform actual reading.
+ */
+static int msm_eeprom_parse_memory_map(struct device_node *of,
+ struct msm_eeprom_memory_block_t *data)
{
int i, rc = 0;
- char property[14];
+ char property[PROPERTY_MAXSIZE];
uint32_t count = 6;
- struct msm_eeprom_board_info *eb = e_ctrl->eboard_info;
+ struct msm_eeprom_memory_map_t *map;
- rc = of_property_read_u32(of, "qcom,num-blocks", &eb->num_blocks);
- CDBG("%s: qcom,num_blocks %d\n", __func__, eb->num_blocks);
+ snprintf(property, PROPERTY_MAXSIZE, "qcom,num-blocks");
+ rc = of_property_read_u32(of, property, &data->num_map);
+ CDBG("%s: %s %d\n", __func__, property, data->num_map);
if (rc < 0) {
pr_err("%s failed rc %d\n", __func__, rc);
return rc;
}
- eb->eeprom_map = kzalloc((sizeof(struct eeprom_memory_map_t)
- * eb->num_blocks), GFP_KERNEL);
-
- if (!eb->eeprom_map) {
+ map = kzalloc((sizeof(*map) * data->num_map), GFP_KERNEL);
+ if (!map) {
pr_err("%s failed line %d\n", __func__, __LINE__);
return -ENOMEM;
}
+ data->map = map;
- for (i = 0; i < eb->num_blocks; i++) {
- snprintf(property, 12, "qcom,page%d", i);
+ for (i = 0; i < data->num_map; i++) {
+ snprintf(property, PROPERTY_MAXSIZE, "qcom,page%d", i);
rc = of_property_read_u32_array(of, property,
- (uint32_t *) &eb->eeprom_map[i].page, count);
+ (uint32_t *) &map[i].page, count);
if (rc < 0) {
pr_err("%s: failed %d\n", __func__, __LINE__);
- goto out;
+ goto ERROR;
}
- snprintf(property, 14, "qcom,pageen%d", i);
+ snprintf(property, PROPERTY_MAXSIZE,
+ "qcom,pageen%d", i);
rc = of_property_read_u32_array(of, property,
- (uint32_t *) &eb->eeprom_map[i].pageen, count);
+ (uint32_t *) &map[i].pageen, count);
if (rc < 0)
pr_err("%s: pageen not needed\n", __func__);
- snprintf(property, 12, "qcom,poll%d", i);
+ snprintf(property, PROPERTY_MAXSIZE, "qcom,poll%d", i);
rc = of_property_read_u32_array(of, property,
- (uint32_t *) &eb->eeprom_map[i].poll, count);
+ (uint32_t *) &map[i].poll, count);
if (rc < 0) {
pr_err("%s failed %d\n", __func__, __LINE__);
- goto out;
+ goto ERROR;
}
- snprintf(property, 12, "qcom,mem%d", i);
+ snprintf(property, PROPERTY_MAXSIZE, "qcom,mem%d", i);
rc = of_property_read_u32_array(of, property,
- (uint32_t *) &eb->eeprom_map[i].mem, count);
+ (uint32_t *) &map[i].mem, count);
if (rc < 0) {
pr_err("%s failed %d\n", __func__, __LINE__);
- goto out;
+ goto ERROR;
}
- e_ctrl->num_bytes += eb->eeprom_map[i].mem.valid_size;
+ data->num_data += map[i].mem.valid_size;
}
- CDBG("%s num_bytes %d\n", __func__, e_ctrl->num_bytes);
+ CDBG("%s num_bytes %d\n", __func__, data->num_data);
- e_ctrl->memory_data = kzalloc(e_ctrl->num_bytes, GFP_KERNEL);
- if (!e_ctrl->memory_data) {
+ data->mapdata = kzalloc(data->num_data, GFP_KERNEL);
+ if (!data->mapdata) {
pr_err("%s failed line %d\n", __func__, __LINE__);
rc = -ENOMEM;
- goto out;
+ goto ERROR;
}
return rc;
-out:
- kfree(eb->eeprom_map);
+ERROR:
+ kfree(data->map);
+ memset(data, 0, sizeof(*data));
return rc;
}
@@ -401,28 +448,20 @@
.core = &msm_eeprom_subdev_core_ops,
};
-int32_t msm_eeprom_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id) {
+static int msm_eeprom_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
int rc = 0;
- int32_t j = 0;
- uint32_t temp = 0;
struct msm_eeprom_ctrl_t *e_ctrl = NULL;
struct msm_camera_power_ctrl_t *power_info = NULL;
- struct device_node *of_node = client->dev.of_node;
CDBG("%s E\n", __func__);
-
- if (!of_node) {
- pr_err("%s of_node NULL\n", __func__);
- return -EINVAL;
- }
-
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
pr_err("%s i2c_check_functionality failed\n", __func__);
goto probe_failure;
}
- e_ctrl = kzalloc(sizeof(struct msm_eeprom_ctrl_t), GFP_KERNEL);
+ e_ctrl = kzalloc(sizeof(*e_ctrl), GFP_KERNEL);
if (!e_ctrl) {
pr_err("%s:%d kzalloc failed\n", __func__, __LINE__);
return -ENOMEM;
@@ -430,23 +469,14 @@
e_ctrl->eeprom_v4l2_subdev_ops = &msm_eeprom_subdev_ops;
e_ctrl->eeprom_mutex = &msm_eeprom_mutex;
CDBG("%s client = %x\n", __func__, (unsigned int)client);
- e_ctrl->eboard_info = kzalloc(sizeof(
- struct msm_eeprom_board_info), GFP_KERNEL);
+ e_ctrl->eboard_info = (struct msm_eeprom_board_info *)(id->driver_data);
if (!e_ctrl->eboard_info) {
pr_err("%s:%d board info NULL\n", __func__, __LINE__);
- return -EINVAL;
+ rc = -EINVAL;
+ goto ectrl_free;
}
-
- rc = of_property_read_u32(of_node, "qcom,slave-addr", &temp);
- if (rc < 0) {
- pr_err("%s failed rc %d\n", __func__, rc);
- return rc;
- }
-
power_info = &e_ctrl->eboard_info->power_info;
- e_ctrl->eboard_info->i2c_slaveaddr = temp;
e_ctrl->i2c_client.client = client;
- e_ctrl->is_supported = 0;
/* Set device type as I2C */
e_ctrl->eeprom_device_type = MSM_CAMERA_I2C_DEVICE;
@@ -459,45 +489,6 @@
power_info->clk_info_size = ARRAY_SIZE(cam_8960_clk_info);
power_info->dev = &client->dev;
- rc = of_property_read_string(of_node, "qcom,eeprom-name",
- &e_ctrl->eboard_info->eeprom_name);
- CDBG("%s qcom,eeprom-name %s, rc %d\n", __func__,
- e_ctrl->eboard_info->eeprom_name, rc);
- if (rc < 0) {
- pr_err("%s failed %d\n", __func__, __LINE__);
- goto board_free;
- }
-
- rc = msm_eeprom_get_dt_data(e_ctrl);
- if (rc)
- goto board_free;
-
- rc = msm_eeprom_alloc_memory_map(e_ctrl, of_node);
- if (rc)
- goto board_free;
-
- rc = msm_camera_power_up(power_info, e_ctrl->eeprom_device_type,
- &e_ctrl->i2c_client);
- if (rc) {
- pr_err("%s failed power up %d\n", __func__, __LINE__);
- goto memdata_free;
- }
- rc = read_eeprom_memory(e_ctrl);
- if (rc < 0) {
- pr_err("%s read_eeprom_memory failed\n", __func__);
- goto power_down;
- }
-
- for (j = 0; j < e_ctrl->num_bytes; j++)
- CDBG("memory_data[%d] = 0x%X\n", j, e_ctrl->memory_data[j]);
-
- rc = msm_camera_power_down(power_info, e_ctrl->eeprom_device_type,
- &e_ctrl->i2c_client);
- if (rc) {
- pr_err("failed rc %d\n", rc);
- goto power_down;
- }
-
/*IMPLEMENT READING PART*/
/* Initialize sub device */
v4l2_i2c_subdev_init(&e_ctrl->msm_sd.sd,
@@ -510,24 +501,17 @@
e_ctrl->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
e_ctrl->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_EEPROM;
msm_sd_register(&e_ctrl->msm_sd);
- e_ctrl->is_supported = 1;
CDBG("%s success result=%d X\n", __func__, rc);
return rc;
-power_down:
- msm_camera_power_down(power_info, e_ctrl->eeprom_device_type,
- &e_ctrl->i2c_client);
-memdata_free:
- kfree(e_ctrl->memory_data);
- kfree(e_ctrl->eboard_info->eeprom_map);
-board_free:
- kfree(e_ctrl->eboard_info);
+ectrl_free:
+ kfree(e_ctrl);
probe_failure:
pr_err("%s failed! rc = %d\n", __func__, rc);
return rc;
}
-static int32_t msm_eeprom_i2c_remove(struct i2c_client *client)
+static int msm_eeprom_i2c_remove(struct i2c_client *client)
{
struct v4l2_subdev *sd = i2c_get_clientdata(client);
struct msm_eeprom_ctrl_t *e_ctrl;
@@ -542,12 +526,12 @@
return 0;
}
- kfree(e_ctrl->memory_data);
+ kfree(e_ctrl->cal_data.mapdata);
+ kfree(e_ctrl->cal_data.map);
if (e_ctrl->eboard_info) {
kfree(e_ctrl->eboard_info->power_info.gpio_conf);
- kfree(e_ctrl->eboard_info->eeprom_map);
+ kfree(e_ctrl->eboard_info);
}
- kfree(e_ctrl->eboard_info);
kfree(e_ctrl);
return 0;
}
@@ -585,23 +569,133 @@
return 0;
}
-static int msm_eeprom_check_id(struct msm_eeprom_ctrl_t *e_ctrl)
+static int msm_eeprom_match_id(struct msm_eeprom_ctrl_t *e_ctrl)
{
int rc;
struct msm_camera_i2c_client *client = &e_ctrl->i2c_client;
uint8_t id[2];
rc = msm_camera_spi_query_id(client, 0, &id[0], 2);
- if (rc)
+ if (rc < 0)
return rc;
+ CDBG("%s: read 0x%x 0x%x, check 0x%x 0x%x\n", __func__, id[0],
+ id[1], client->spi_client->mfr_id, client->spi_client->device_id);
if (id[0] != client->spi_client->mfr_id
- || id[1] != client->spi_client->device_id) {
- CDBG("%s: read 0x%x 0x%x, check 0x%x 0x%x\n", __func__, id[0],
- id[1], client->spi_client->mfr_id,
- client->spi_client->device_id);
+ || id[1] != client->spi_client->device_id)
return -ENODEV;
+
+ return 0;
+}
+
+static int msm_eeprom_get_dt_data(struct msm_eeprom_ctrl_t *e_ctrl)
+{
+ int rc = 0, i = 0;
+ struct msm_eeprom_board_info *eb_info;
+ struct msm_camera_power_ctrl_t *power_info =
+ &e_ctrl->eboard_info->power_info;
+ struct device_node *of_node = NULL;
+ struct msm_camera_gpio_conf *gconf = NULL;
+ uint16_t gpio_array_size = 0;
+ uint16_t *gpio_array = NULL;
+
+ eb_info = e_ctrl->eboard_info;
+ if (e_ctrl->eeprom_device_type == MSM_CAMERA_SPI_DEVICE)
+ of_node = e_ctrl->i2c_client.
+ spi_client->spi_master->dev.of_node;
+ else if (e_ctrl->eeprom_device_type == MSM_CAMERA_PLATFORM_DEVICE)
+ of_node = e_ctrl->pdev->dev.of_node;
+
+ rc = msm_camera_get_dt_vreg_data(of_node, &power_info->cam_vreg,
+ &power_info->num_vreg);
+ if (rc < 0)
+ return rc;
+
+ rc = msm_camera_get_dt_power_setting_data(of_node,
+ power_info->cam_vreg, power_info->num_vreg,
+ power_info);
+ if (rc < 0)
+ goto ERROR1;
+
+ power_info->gpio_conf = kzalloc(sizeof(struct msm_camera_gpio_conf),
+ GFP_KERNEL);
+ if (!power_info->gpio_conf) {
+ rc = -ENOMEM;
+ goto ERROR2;
+ }
+ gconf = power_info->gpio_conf;
+ gpio_array_size = of_gpio_count(of_node);
+ CDBG("%s gpio count %d\n", __func__, gpio_array_size);
+
+ if (gpio_array_size) {
+ gpio_array = kzalloc(sizeof(uint16_t) * gpio_array_size,
+ GFP_KERNEL);
+ if (!gpio_array) {
+ pr_err("%s failed %d\n", __func__, __LINE__);
+ goto ERROR3;
+ }
+ for (i = 0; i < gpio_array_size; i++) {
+ gpio_array[i] = of_get_gpio(of_node, i);
+ CDBG("%s gpio_array[%d] = %d\n", __func__, i,
+ gpio_array[i]);
+ }
+
+ rc = msm_camera_get_dt_gpio_req_tbl(of_node, gconf,
+ gpio_array, gpio_array_size);
+ if (rc < 0) {
+ pr_err("%s failed %d\n", __func__, __LINE__);
+ goto ERROR4;
+ }
+
+ rc = msm_camera_init_gpio_pin_tbl(of_node, gconf,
+ gpio_array, gpio_array_size);
+ if (rc < 0) {
+ pr_err("%s failed %d\n", __func__, __LINE__);
+ goto ERROR4;
+ }
+ kfree(gpio_array);
}
+ return rc;
+ERROR4:
+ kfree(gpio_array);
+ERROR3:
+ kfree(power_info->gpio_conf);
+ERROR2:
+ kfree(power_info->cam_vreg);
+ERROR1:
+ kfree(power_info->power_setting);
+ 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;
}
@@ -614,7 +708,7 @@
struct msm_camera_power_ctrl_t *power_info = NULL;
int rc = 0;
- e_ctrl = kzalloc(sizeof(struct msm_eeprom_ctrl_t), GFP_KERNEL);
+ e_ctrl = kzalloc(sizeof(*e_ctrl), GFP_KERNEL);
if (!e_ctrl) {
pr_err("%s:%d kzalloc failed\n", __func__, __LINE__);
return -ENOMEM;
@@ -624,7 +718,7 @@
client = &e_ctrl->i2c_client;
e_ctrl->is_supported = 0;
- spi_client = kzalloc(sizeof(spi_client), GFP_KERNEL);
+ spi_client = kzalloc(sizeof(*spi_client), GFP_KERNEL);
if (!spi_client) {
pr_err("%s:%d kzalloc failed\n", __func__, __LINE__);
kfree(e_ctrl);
@@ -634,7 +728,7 @@
rc = of_property_read_u32(spi->dev.of_node, "cell-index",
&e_ctrl->subdev_id);
CDBG("cell-index %d, rc %d\n", e_ctrl->subdev_id, rc);
- if (rc) {
+ if (rc < 0) {
pr_err("failed rc %d\n", rc);
return rc;
}
@@ -645,7 +739,7 @@
client->i2c_func_tbl = &msm_eeprom_spi_func_tbl;
client->addr_type = MSM_CAMERA_I2C_3B_ADDR;
- eb_info = kzalloc(sizeof(eb_info), GFP_KERNEL);
+ eb_info = kzalloc(sizeof(*eb_info), GFP_KERNEL);
if (!eb_info)
goto spi_free;
e_ctrl->eboard_info = eb_info;
@@ -657,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;
@@ -664,48 +764,56 @@
power_info->dev = &spi->dev;
rc = msm_eeprom_get_dt_data(e_ctrl);
- if (rc)
+ if (rc < 0)
goto board_free;
/* set spi instruction info */
spi_client->retry_delay = 1;
spi_client->retries = 0;
- if (msm_eeprom_spi_parse_of(spi_client)) {
+ rc = msm_eeprom_spi_parse_of(spi_client);
+ if (rc < 0) {
dev_err(&spi->dev,
"%s: Error parsing device properties\n", __func__);
goto board_free;
}
- rc = msm_eeprom_alloc_memory_map(e_ctrl, spi->dev.of_node);
- if (rc)
- goto board_free;
+ /* prepare memory buffer */
+ rc = msm_eeprom_parse_memory_map(spi->dev.of_node,
+ &e_ctrl->cal_data);
+ if (rc < 0)
+ CDBG("%s: no cal memory map\n", __func__);
+ /* power up eeprom for reading */
rc = msm_camera_power_up(power_info, e_ctrl->eeprom_device_type,
&e_ctrl->i2c_client);
- if (rc) {
+ if (rc < 0) {
pr_err("failed rc %d\n", rc);
- goto memmap_free;
+ goto caldata_free;
}
/* check eeprom id */
- rc = msm_eeprom_check_id(e_ctrl);
- if (rc) {
+ rc = msm_eeprom_match_id(e_ctrl);
+ if (rc < 0) {
CDBG("%s: eeprom not matching %d\n", __func__, rc);
goto power_down;
}
/* read eeprom */
- rc = read_eeprom_memory(e_ctrl);
- if (rc) {
- dev_err(&spi->dev, "%s: read eeprom memory failed\n", __func__);
- goto power_down;
+ if (e_ctrl->cal_data.map) {
+ rc = read_eeprom_memory(e_ctrl, &e_ctrl->cal_data);
+ if (rc < 0) {
+ pr_err("%s: read cal data failed\n", __func__);
+ goto power_down;
+ }
+ e_ctrl->is_supported |= msm_eeprom_match_crc(
+ &e_ctrl->cal_data);
}
rc = msm_camera_power_down(power_info, e_ctrl->eeprom_device_type,
&e_ctrl->i2c_client);
- if (rc) {
+ if (rc < 0) {
pr_err("failed rc %d\n", rc);
- goto memmap_free;
+ goto caldata_free;
}
/* initiazlie subdev */
@@ -719,21 +827,23 @@
e_ctrl->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
e_ctrl->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_EEPROM;
msm_sd_register(&e_ctrl->msm_sd);
- e_ctrl->is_supported = 1;
- CDBG("%s success result=%d X\n", __func__, rc);
+ e_ctrl->is_supported = (e_ctrl->is_supported << 1) | 1;
+ CDBG("%s success result=%d supported=%x X\n", __func__, rc,
+ e_ctrl->is_supported);
return 0;
power_down:
msm_camera_power_down(power_info, e_ctrl->eeprom_device_type,
&e_ctrl->i2c_client);
-memmap_free:
- kfree(e_ctrl->eboard_info->eeprom_map);
- kfree(e_ctrl->memory_data);
+caldata_free:
+ kfree(e_ctrl->cal_data.mapdata);
+ kfree(e_ctrl->cal_data.map);
board_free:
kfree(e_ctrl->eboard_info);
spi_free:
kfree(spi_client);
+ kfree(e_ctrl);
return rc;
}
@@ -751,14 +861,14 @@
cpha = (spi->mode & SPI_CPHA) ? 1 : 0;
cpol = (spi->mode & SPI_CPOL) ? 1 : 0;
cs_high = (spi->mode & SPI_CS_HIGH) ? 1 : 0;
- dev_info(&spi->dev, "irq[%d] cs[%x] CPHA[%x] CPOL[%x] CS_HIGH[%x]\n",
- irq, cs, cpha, cpol, cs_high);
- dev_info(&spi->dev, "max_speed[%u]\n", spi->max_speed_hz);
+ CDBG("%s: irq[%d] cs[%x] CPHA[%x] CPOL[%x] CS_HIGH[%x]\n",
+ __func__, irq, cs, cpha, cpol, cs_high);
+ CDBG("%s: max_speed[%u]\n", __func__, spi->max_speed_hz);
return msm_eeprom_spi_setup(spi);
}
-static int32_t msm_eeprom_spi_remove(struct spi_device *sdev)
+static int msm_eeprom_spi_remove(struct spi_device *sdev)
{
struct v4l2_subdev *sd = spi_get_drvdata(sdev);
struct msm_eeprom_ctrl_t *e_ctrl;
@@ -774,20 +884,20 @@
}
kfree(e_ctrl->i2c_client.spi_client);
- kfree(e_ctrl->memory_data);
+ kfree(e_ctrl->cal_data.mapdata);
+ kfree(e_ctrl->cal_data.map);
if (e_ctrl->eboard_info) {
kfree(e_ctrl->eboard_info->power_info.gpio_conf);
- kfree(e_ctrl->eboard_info->eeprom_map);
+ kfree(e_ctrl->eboard_info);
}
- kfree(e_ctrl->eboard_info);
kfree(e_ctrl);
return 0;
}
-static int32_t msm_eeprom_platform_probe(struct platform_device *pdev)
+static int msm_eeprom_platform_probe(struct platform_device *pdev)
{
- int32_t rc = 0;
- int32_t j = 0;
+ int rc = 0;
+ int j = 0;
uint32_t temp;
struct msm_camera_cci_client *cci_client = NULL;
@@ -798,7 +908,7 @@
CDBG("%s E\n", __func__);
- e_ctrl = kzalloc(sizeof(struct msm_eeprom_ctrl_t), GFP_KERNEL);
+ e_ctrl = kzalloc(sizeof(*e_ctrl), GFP_KERNEL);
if (!e_ctrl) {
pr_err("%s:%d kzalloc failed\n", __func__, __LINE__);
return -ENOMEM;
@@ -884,12 +994,16 @@
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;
- rc = msm_eeprom_alloc_memory_map(e_ctrl, of_node);
- if (rc)
+ rc = msm_eeprom_parse_memory_map(of_node, &e_ctrl->cal_data);
+ if (rc < 0)
goto board_free;
rc = msm_camera_power_up(power_info, e_ctrl->eeprom_device_type,
@@ -898,14 +1012,16 @@
pr_err("failed rc %d\n", rc);
goto memdata_free;
}
- rc = read_eeprom_memory(e_ctrl);
+ rc = read_eeprom_memory(e_ctrl, &e_ctrl->cal_data);
if (rc < 0) {
pr_err("%s read_eeprom_memory failed\n", __func__);
goto power_down;
}
- pr_err("%s line %d\n", __func__, __LINE__);
- for (j = 0; j < e_ctrl->num_bytes; j++)
- CDBG("memory_data[%d] = 0x%X\n", j, e_ctrl->memory_data[j]);
+ for (j = 0; j < e_ctrl->cal_data.num_data; j++)
+ CDBG("memory_data[%d] = 0x%X\n", j,
+ e_ctrl->cal_data.mapdata[j]);
+
+ e_ctrl->is_supported |= msm_eeprom_match_crc(&e_ctrl->cal_data);
rc = msm_camera_power_down(power_info, e_ctrl->eeprom_device_type,
&e_ctrl->i2c_client);
@@ -926,8 +1042,7 @@
e_ctrl->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_EEPROM;
msm_sd_register(&e_ctrl->msm_sd);
-
- e_ctrl->is_supported = 1;
+ e_ctrl->is_supported = (e_ctrl->is_supported << 1) | 1;
CDBG("%s X\n", __func__);
return rc;
@@ -935,8 +1050,8 @@
msm_camera_power_down(power_info, e_ctrl->eeprom_device_type,
&e_ctrl->i2c_client);
memdata_free:
- kfree(e_ctrl->memory_data);
- kfree(eb_info->eeprom_map);
+ kfree(e_ctrl->cal_data.mapdata);
+ kfree(e_ctrl->cal_data.map);
board_free:
kfree(e_ctrl->eboard_info);
cciclient_free:
@@ -945,7 +1060,7 @@
return rc;
}
-static int32_t msm_eeprom_platform_remove(struct platform_device *pdev)
+static int msm_eeprom_platform_remove(struct platform_device *pdev)
{
struct v4l2_subdev *sd = platform_get_drvdata(pdev);
struct msm_eeprom_ctrl_t *e_ctrl;
@@ -961,12 +1076,12 @@
}
kfree(e_ctrl->i2c_client.cci_client);
- kfree(e_ctrl->memory_data);
+ kfree(e_ctrl->cal_data.mapdata);
+ kfree(e_ctrl->cal_data.map);
if (e_ctrl->eboard_info) {
kfree(e_ctrl->eboard_info->power_info.gpio_conf);
- kfree(e_ctrl->eboard_info->eeprom_map);
+ kfree(e_ctrl->eboard_info);
}
- kfree(e_ctrl->eboard_info);
kfree(e_ctrl);
return 0;
}
@@ -1013,7 +1128,7 @@
static int __init msm_eeprom_init_module(void)
{
- int32_t rc = 0;
+ int rc = 0;
CDBG("%s E\n", __func__);
rc = platform_driver_probe(&msm_eeprom_platform_driver,
msm_eeprom_platform_probe);
diff --git a/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.h b/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.h
index cebe585..e978824 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.h
+++ b/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.h
@@ -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
@@ -27,6 +27,8 @@
#define DEFINE_MSM_MUTEX(mutexname) \
static struct mutex mutexname = __MUTEX_INITIALIZER(mutexname)
+#define PROPERTY_MAXSIZE 32
+
struct msm_eeprom_ctrl_t {
struct platform_device *pdev;
struct mutex *eeprom_mutex;
@@ -38,8 +40,7 @@
enum cci_i2c_master_t cci_master;
struct msm_camera_i2c_client i2c_client;
- uint32_t num_bytes;
- uint8_t *memory_data;
+ struct msm_eeprom_memory_block_t cal_data;
uint8_t is_supported;
struct msm_eeprom_board_info *eboard_info;
uint32_t subdev_id;
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 9caa270..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
@@ -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
@@ -95,27 +95,30 @@
{
int rc = 0;
struct msm_camera_sensor_board_info *flashdata = NULL;
+ struct msm_camera_power_ctrl_t *power_info = NULL;
CDBG("%s:%d called\n", __func__, __LINE__);
flashdata = fctrl->flashdata;
- if (flashdata->gpio_conf->cam_gpiomux_conf_tbl != NULL) {
+ power_info = &flashdata->power_info;
+ if (power_info->gpio_conf->cam_gpiomux_conf_tbl != NULL) {
pr_err("%s:%d mux install\n", __func__, __LINE__);
msm_gpiomux_install(
(struct msm_gpiomux_config *)
- flashdata->gpio_conf->cam_gpiomux_conf_tbl,
- flashdata->gpio_conf->cam_gpiomux_conf_tbl_size);
+ power_info->gpio_conf->cam_gpiomux_conf_tbl,
+ power_info->gpio_conf->cam_gpiomux_conf_tbl_size);
}
rc = msm_camera_request_gpio_table(
- flashdata->gpio_conf->cam_gpio_req_tbl,
- flashdata->gpio_conf->cam_gpio_req_tbl_size, 1);
+ power_info->gpio_conf->cam_gpio_req_tbl,
+ power_info->gpio_conf->cam_gpio_req_tbl_size, 1);
if (rc < 0) {
pr_err("%s: request gpio failed\n", __func__);
return rc;
}
msleep(20);
gpio_set_value_cansleep(
- flashdata->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) {
@@ -133,22 +136,26 @@
{
int rc = 0;
struct msm_camera_sensor_board_info *flashdata = NULL;
+ struct msm_camera_power_ctrl_t *power_info = NULL;
flashdata = fctrl->flashdata;
+ power_info = &flashdata->power_info;
CDBG("%s:%d called\n", __func__, __LINE__);
if (!fctrl) {
pr_err("%s:%d fctrl NULL\n", __func__, __LINE__);
return -EINVAL;
}
gpio_set_value_cansleep(
- flashdata->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(
- flashdata->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(
- flashdata->gpio_conf->cam_gpio_req_tbl,
- flashdata->gpio_conf->cam_gpio_req_tbl_size, 0);
+ power_info->gpio_conf->cam_gpio_req_tbl,
+ power_info->gpio_conf->cam_gpio_req_tbl_size, 0);
if (rc < 0) {
pr_err("%s: request gpio failed\n", __func__);
return rc;
@@ -160,8 +167,10 @@
{
int rc = 0;
struct msm_camera_sensor_board_info *flashdata = NULL;
+ struct msm_camera_power_ctrl_t *power_info = NULL;
flashdata = fctrl->flashdata;
+ power_info = &flashdata->power_info;
CDBG("%s:%d called\n", __func__, __LINE__);
if (!fctrl) {
pr_err("%s:%d fctrl NULL\n", __func__, __LINE__);
@@ -175,7 +184,8 @@
pr_err("%s:%d failed\n", __func__, __LINE__);
}
gpio_set_value_cansleep(
- flashdata->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;
@@ -185,15 +195,19 @@
{
int rc = 0;
struct msm_camera_sensor_board_info *flashdata = NULL;
+ struct msm_camera_power_ctrl_t *power_info = NULL;
CDBG("%s:%d called\n", __func__, __LINE__);
flashdata = fctrl->flashdata;
+ power_info = &flashdata->power_info;
gpio_set_value_cansleep(
- flashdata->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(
- flashdata->gpio_conf->gpio_num_info->gpio_num[1],
+ power_info->gpio_conf->gpio_num_info->
+ gpio_num[SENSOR_GPIO_FL_NOW],
GPIO_OUT_HIGH);
@@ -212,15 +226,19 @@
{
int rc = 0;
struct msm_camera_sensor_board_info *flashdata = NULL;
+ struct msm_camera_power_ctrl_t *power_info = NULL;
CDBG("%s:%d called\n", __func__, __LINE__);
flashdata = fctrl->flashdata;
+ power_info = &flashdata->power_info;
gpio_set_value_cansleep(
- flashdata->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(
- flashdata->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) {
@@ -234,61 +252,6 @@
return rc;
}
-static int32_t msm_flash_init_gpio_pin_tbl(struct device_node *of_node,
- struct msm_camera_gpio_conf *gconf, uint16_t *gpio_array,
- uint16_t gpio_array_size)
-{
- int32_t rc = 0;
- int32_t val = 0;
-
- gconf->gpio_num_info = kzalloc(sizeof(struct msm_camera_gpio_num_info),
- GFP_KERNEL);
- if (!gconf->gpio_num_info) {
- pr_err("%s failed %d\n", __func__, __LINE__);
- rc = -ENOMEM;
- return rc;
- }
-
- 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;
- }
- /*index 0 is for qcom,gpio-flash-en */
- gconf->gpio_num_info->gpio_num[0] =
- gpio_array[val];
- CDBG("%s qcom,gpio-flash-en %d\n", __func__,
- gconf->gpio_num_info->gpio_num[0]);
-
- 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;
- }
- /*index 1 is for qcom,gpio-flash-now */
- gconf->gpio_num_info->gpio_num[1] =
- gpio_array[val];
- CDBG("%s qcom,gpio-flash-now %d\n", __func__,
- gconf->gpio_num_info->gpio_num[1]);
-
- return rc;
-
-ERROR:
- kfree(gconf->gpio_num_info);
- gconf->gpio_num_info = NULL;
- return rc;
-}
-
static int32_t msm_led_get_dt_data(struct device_node *of_node,
struct msm_led_flash_ctrl_t *fctrl)
{
@@ -296,6 +259,7 @@
struct msm_camera_gpio_conf *gconf = NULL;
struct device_node *flash_src_node = NULL;
struct msm_camera_sensor_board_info *flashdata = NULL;
+ struct msm_camera_power_ctrl_t *power_info = NULL;
uint32_t count = 0;
uint16_t *gpio_array = NULL;
uint16_t gpio_array_size = 0;
@@ -317,13 +281,7 @@
}
flashdata = fctrl->flashdata;
-
- flashdata->sensor_init_params = kzalloc(sizeof(
- struct msm_sensor_init_params), GFP_KERNEL);
- if (!flashdata->sensor_init_params) {
- pr_err("%s failed %d\n", __func__, __LINE__);
- return -ENOMEM;
- }
+ power_info = &flashdata->power_info;
rc = of_property_read_u32(of_node, "cell-index", &fctrl->subdev_id);
if (rc < 0) {
@@ -389,15 +347,15 @@
}
} else { /*Handle LED Flash Ctrl by GPIO*/
- flashdata->gpio_conf =
+ power_info->gpio_conf =
kzalloc(sizeof(struct msm_camera_gpio_conf),
GFP_KERNEL);
- if (!flashdata->gpio_conf) {
+ if (!power_info->gpio_conf) {
pr_err("%s failed %d\n", __func__, __LINE__);
rc = -ENOMEM;
return rc;
}
- gconf = flashdata->gpio_conf;
+ gconf = power_info->gpio_conf;
gpio_array_size = of_gpio_count(of_node);
CDBG("%s gpio count %d\n", __func__, gpio_array_size);
@@ -416,21 +374,21 @@
gpio_array[i]);
}
- rc = msm_sensor_get_dt_gpio_req_tbl(of_node, gconf,
+ rc = msm_camera_get_dt_gpio_req_tbl(of_node, gconf,
gpio_array, gpio_array_size);
if (rc < 0) {
pr_err("%s failed %d\n", __func__, __LINE__);
goto ERROR4;
}
- rc = msm_sensor_get_dt_gpio_set_tbl(of_node, gconf,
+ rc = msm_camera_get_dt_gpio_set_tbl(of_node, gconf,
gpio_array, gpio_array_size);
if (rc < 0) {
pr_err("%s failed %d\n", __func__, __LINE__);
goto ERROR5;
}
- rc = msm_flash_init_gpio_pin_tbl(of_node, gconf,
+ rc = msm_camera_init_gpio_pin_tbl(of_node, gconf,
gpio_array, gpio_array_size);
if (rc < 0) {
pr_err("%s failed %d\n", __func__, __LINE__);
@@ -462,7 +420,7 @@
ERROR9:
kfree(fctrl->flashdata->slave_info);
ERROR8:
- kfree(fctrl->flashdata->gpio_conf->gpio_num_info);
+ kfree(fctrl->flashdata->power_info.gpio_conf->gpio_num_info);
ERROR6:
kfree(gconf->cam_gpio_set_tbl);
ERROR5:
diff --git a/drivers/media/platform/msm/camera_v2/sensor/gc0339.c b/drivers/media/platform/msm/camera_v2/sensor/gc0339.c
index 8288ad0..e233b8d 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/gc0339.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/gc0339.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
@@ -120,21 +120,23 @@
struct msm_sensor_power_setting_array *power_setting_array = NULL;
struct msm_sensor_power_setting *power_setting = NULL;
struct msm_camera_sensor_board_info *data = s_ctrl->sensordata;
+ struct msm_camera_power_ctrl_t *power_info = &data->power_info;
+ struct msm_camera_gpio_conf *gpio_conf = power_info->gpio_conf;
CDBG("%s:%d\n", __func__, __LINE__);
power_setting_array = &s_ctrl->power_setting_array;
- if (data->gpio_conf->cam_gpiomux_conf_tbl != NULL) {
+ if (gpio_conf->cam_gpiomux_conf_tbl != NULL) {
pr_err("%s:%d mux install\n", __func__, __LINE__);
msm_gpiomux_install(
(struct msm_gpiomux_config *)
- data->gpio_conf->cam_gpiomux_conf_tbl,
- data->gpio_conf->cam_gpiomux_conf_tbl_size);
+ gpio_conf->cam_gpiomux_conf_tbl,
+ gpio_conf->cam_gpiomux_conf_tbl_size);
}
rc = msm_camera_request_gpio_table(
- data->gpio_conf->cam_gpio_req_tbl,
- data->gpio_conf->cam_gpio_req_tbl_size, 1);
+ gpio_conf->cam_gpio_req_tbl,
+ gpio_conf->cam_gpio_req_tbl_size, 1);
if (rc < 0) {
pr_err("%s: request gpio failed\n", __func__);
return rc;
@@ -145,20 +147,21 @@
CDBG("%s type %d\n", __func__, power_setting->seq_type);
switch (power_setting->seq_type) {
case SENSOR_CLK:
- if (power_setting->seq_val >= s_ctrl->clk_info_size) {
+ if (power_setting->seq_val >=
+ power_info->clk_info_size) {
pr_err("%s clk index %d >= max %d\n", __func__,
power_setting->seq_val,
- s_ctrl->clk_info_size);
+ power_info->clk_info_size);
goto power_up_failed;
}
if (power_setting->config_val)
- s_ctrl->clk_info[power_setting->seq_val].
+ power_info->clk_info[power_setting->seq_val].
clk_rate = power_setting->config_val;
- rc = msm_cam_clk_enable(s_ctrl->dev,
- &s_ctrl->clk_info[0],
+ rc = msm_cam_clk_enable(power_info->dev,
+ &power_info->clk_info[0],
(struct clk **)&power_setting->data[0],
- s_ctrl->clk_info_size,
+ power_info->clk_info_size,
1);
if (rc < 0) {
pr_err("%s: clk enable failed\n",
@@ -168,19 +171,19 @@
break;
case SENSOR_GPIO:
if (power_setting->seq_val >= SENSOR_GPIO_MAX ||
- !data->gpio_conf->gpio_num_info) {
+ !gpio_conf->gpio_num_info) {
pr_err("%s gpio index %d >= max %d\n", __func__,
power_setting->seq_val,
SENSOR_GPIO_MAX);
goto power_up_failed;
}
pr_debug("%s:%d gpio set val %d\n", __func__, __LINE__,
- data->gpio_conf->gpio_num_info->gpio_num
+ gpio_conf->gpio_num_info->gpio_num
[power_setting->seq_val]);
- if (data->gpio_conf->gpio_num_info->gpio_num
+ if (gpio_conf->gpio_num_info->gpio_num
[power_setting->seq_val])
gpio_set_value_cansleep(
- data->gpio_conf->gpio_num_info->gpio_num
+ gpio_conf->gpio_num_info->gpio_num
[power_setting->seq_val],
power_setting->config_val);
break;
@@ -191,8 +194,8 @@
SENSOR_GPIO_MAX);
goto power_up_failed;
}
- msm_camera_config_single_vreg(s_ctrl->dev,
- &data->cam_vreg[power_setting->seq_val],
+ msm_camera_config_single_vreg(power_info->dev,
+ &power_info->cam_vreg[power_setting->seq_val],
(struct regulator **)&power_setting->data[0],
1);
break;
@@ -247,23 +250,23 @@
CDBG("%s type %d\n", __func__, power_setting->seq_type);
switch (power_setting->seq_type) {
case SENSOR_CLK:
- msm_cam_clk_enable(s_ctrl->dev,
- &s_ctrl->clk_info[0],
+ msm_cam_clk_enable(power_info->dev,
+ &power_info->clk_info[0],
(struct clk **)&power_setting->data[0],
- s_ctrl->clk_info_size,
+ power_info->clk_info_size,
0);
break;
case SENSOR_GPIO:
- if (data->gpio_conf->gpio_num_info->gpio_num
+ if (gpio_conf->gpio_num_info->gpio_num
[power_setting->seq_val])
gpio_set_value_cansleep(
- data->gpio_conf->gpio_num_info->gpio_num
+ gpio_conf->gpio_num_info->gpio_num
[power_setting->seq_val],
GPIOF_OUT_INIT_LOW);
break;
case SENSOR_VREG:
- msm_camera_config_single_vreg(s_ctrl->dev,
- &data->cam_vreg[power_setting->seq_val],
+ msm_camera_config_single_vreg(power_info->dev,
+ &power_info->cam_vreg[power_setting->seq_val],
(struct regulator **)&power_setting->data[0],
0);
break;
@@ -280,8 +283,8 @@
}
}
msm_camera_request_gpio_table(
- data->gpio_conf->cam_gpio_req_tbl,
- data->gpio_conf->cam_gpio_req_tbl_size, 0);
+ gpio_conf->cam_gpio_req_tbl,
+ gpio_conf->cam_gpio_req_tbl_size, 0);
return rc;
}
@@ -291,6 +294,8 @@
struct msm_sensor_power_setting_array *power_setting_array = NULL;
struct msm_sensor_power_setting *power_setting = NULL;
struct msm_camera_sensor_board_info *data = s_ctrl->sensordata;
+ struct msm_camera_power_ctrl_t *power_info = &data->power_info;
+ struct msm_camera_gpio_conf *gpio_conf = power_info->gpio_conf;
CDBG("%s:%d\n", __func__, __LINE__);
power_setting_array = &s_ctrl->power_setting_array;
@@ -311,24 +316,24 @@
CDBG("%s type %d\n", __func__, power_setting->seq_type);
switch (power_setting->seq_type) {
case SENSOR_CLK:
- msm_cam_clk_enable(s_ctrl->dev,
- &s_ctrl->clk_info[0],
+ msm_cam_clk_enable(power_info->dev,
+ &power_info->clk_info[0],
(struct clk **)&power_setting->data[0],
- s_ctrl->clk_info_size,
+ power_info->clk_info_size,
0);
break;
case SENSOR_GPIO:
if (power_setting->seq_val >= SENSOR_GPIO_MAX ||
- !data->gpio_conf->gpio_num_info) {
+ !gpio_conf->gpio_num_info) {
pr_err("%s gpio index %d >= max %d\n", __func__,
power_setting->seq_val,
SENSOR_GPIO_MAX);
continue;
}
- if (data->gpio_conf->gpio_num_info->gpio_num
+ if (gpio_conf->gpio_num_info->gpio_num
[power_setting->seq_val])
gpio_set_value_cansleep(
- data->gpio_conf->gpio_num_info->gpio_num
+ gpio_conf->gpio_num_info->gpio_num
[power_setting->seq_val],
GPIOF_OUT_INIT_LOW);
break;
@@ -339,8 +344,8 @@
SENSOR_GPIO_MAX);
continue;
}
- msm_camera_config_single_vreg(s_ctrl->dev,
- &data->cam_vreg[power_setting->seq_val],
+ msm_camera_config_single_vreg(power_info->dev,
+ &power_info->cam_vreg[power_setting->seq_val],
(struct regulator **)&power_setting->data[0],
0);
break;
@@ -357,8 +362,8 @@
}
}
msm_camera_request_gpio_table(
- data->gpio_conf->cam_gpio_req_tbl,
- data->gpio_conf->cam_gpio_req_tbl_size, 0);
+ gpio_conf->cam_gpio_req_tbl,
+ gpio_conf->cam_gpio_req_tbl_size, 0);
CDBG("%s exit\n", __func__);
return 0;
}
@@ -409,11 +414,18 @@
for (i = 0; i < SUB_MODULE_MAX; i++)
CDBG("%s:%d subdev_id[%d] %d\n", __func__, __LINE__, i,
cdata->cfg.sensor_info.subdev_id[i]);
+ CDBG("%s:%d mount angle valid %d value %d\n", __func__,
+ __LINE__, cdata->cfg.sensor_info.is_mount_angle_valid,
+ cdata->cfg.sensor_info.sensor_mount_angle);
break;
case CFG_GET_SENSOR_INIT_PARAMS:
- cdata->cfg.sensor_init_params =
- *s_ctrl->sensordata->sensor_init_params;
+ cdata->cfg.sensor_init_params.modes_supported =
+ s_ctrl->sensordata->sensor_info->modes_supported;
+ cdata->cfg.sensor_init_params.position =
+ s_ctrl->sensordata->sensor_info->position;
+ cdata->cfg.sensor_init_params.sensor_mount_angle =
+ s_ctrl->sensordata->sensor_info->sensor_mount_angle;
CDBG("%s:%d init params mode %d pos %d mount %d\n", __func__,
__LINE__,
cdata->cfg.sensor_init_params.modes_supported,
@@ -462,7 +474,6 @@
rc = -EFAULT;
break;
}
- s_ctrl->free_power_setting = true;
CDBG("%s sensor id %x\n", __func__,
sensor_slave_info.slave_addr);
CDBG("%s sensor addr type %d\n", __func__,
diff --git a/drivers/media/platform/msm/camera_v2/sensor/hi256.c b/drivers/media/platform/msm/camera_v2/sensor/hi256.c
index a10d60e..2b1024e 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/hi256.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/hi256.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
@@ -1788,6 +1788,10 @@
for (i = 0; i < SUB_MODULE_MAX; i++)
CDBG("%s:%d subdev_id[%d] %d\n", __func__, __LINE__, i,
cdata->cfg.sensor_info.subdev_id[i]);
+ CDBG("%s:%d mount angle valid %d value %d\n", __func__,
+ __LINE__, cdata->cfg.sensor_info.is_mount_angle_valid,
+ cdata->cfg.sensor_info.sensor_mount_angle);
+
break;
case CFG_SET_INIT_SETTING:
CDBG("init setting");
@@ -1823,8 +1827,12 @@
ARRAY_SIZE(hi256_start_settings));
break;
case CFG_GET_SENSOR_INIT_PARAMS:
- cdata->cfg.sensor_init_params =
- *s_ctrl->sensordata->sensor_init_params;
+ cdata->cfg.sensor_init_params.modes_supported =
+ s_ctrl->sensordata->sensor_info->modes_supported;
+ cdata->cfg.sensor_init_params.position =
+ s_ctrl->sensordata->sensor_info->position;
+ cdata->cfg.sensor_init_params.sensor_mount_angle =
+ s_ctrl->sensordata->sensor_info->sensor_mount_angle;
CDBG("%s:%d init params mode %d pos %d mount %d\n", __func__,
__LINE__,
cdata->cfg.sensor_init_params.modes_supported,
@@ -1874,7 +1882,6 @@
rc = -EFAULT;
break;
}
- s_ctrl->free_power_setting = true;
CDBG("%s sensor id %x\n", __func__,
sensor_slave_info.slave_addr);
CDBG("%s sensor addr type %d\n", __func__,
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 336c922..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
@@ -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
@@ -16,6 +16,7 @@
#include "msm_camera_i2c_mux.h"
#include "msm_cci.h"
+/*#define CONFIG_MSM_CAMERA_DT_DEBUG*/
#undef CDBG
#ifdef CONFIG_MSM_CAMERA_DT_DEBUG
#define CDBG(fmt, args...) pr_err(fmt, ##args)
@@ -23,10 +24,330 @@
#define CDBG(fmt, args...) do { } while (0)
#endif
+int msm_camera_fill_vreg_params(struct camera_vreg_t *cam_vreg,
+ int num_vreg, struct msm_sensor_power_setting *power_setting,
+ uint16_t power_setting_size)
+{
+ uint16_t i = 0;
+ int j = 0;
+
+ /* Validate input parameters */
+ if (!cam_vreg || !power_setting) {
+ pr_err("%s:%d failed: cam_vreg %p power_setting %p", __func__,
+ __LINE__, cam_vreg, power_setting);
+ return -EINVAL;
+ }
+
+ /* Validate size of num_vreg */
+ if (num_vreg <= 0) {
+ pr_err("failed: num_vreg %d", num_vreg);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < power_setting_size; i++) {
+ if (power_setting[i].seq_type != SENSOR_VREG)
+ continue;
+
+ switch (power_setting[i].seq_val) {
+ case CAM_VDIG:
+ for (j = 0; j < num_vreg; j++) {
+ if (!strcmp(cam_vreg[j].reg_name, "cam_vdig")) {
+ pr_err("%s:%d i %d j %d cam_vdig\n",
+ __func__, __LINE__, i, j);
+ power_setting[i].seq_val = j;
+ break;
+ }
+ }
+ break;
+
+ case CAM_VIO:
+ for (j = 0; j < num_vreg; j++) {
+ if (!strcmp(cam_vreg[j].reg_name, "cam_vio")) {
+ pr_err("%s:%d i %d j %d cam_vio\n",
+ __func__, __LINE__, i, j);
+ power_setting[i].seq_val = j;
+ break;
+ }
+ }
+ break;
+
+ case CAM_VANA:
+ for (j = 0; j < num_vreg; j++) {
+ if (!strcmp(cam_vreg[j].reg_name, "cam_vana")) {
+ pr_err("%s:%d i %d j %d cam_vana\n",
+ __func__, __LINE__, i, j);
+ power_setting[i].seq_val = j;
+ break;
+ }
+ }
+ break;
+
+ case CAM_VAF:
+ for (j = 0; j < num_vreg; j++) {
+ if (!strcmp(cam_vreg[j].reg_name, "cam_vaf")) {
+ pr_err("%s:%d i %d j %d cam_vaf\n",
+ __func__, __LINE__, i, j);
+ power_setting[i].seq_val = j;
+ break;
+ }
+ }
+ break;
+
+ default:
+ pr_err("%s:%d invalid seq_val %d\n", __func__,
+ __LINE__, power_setting[i].seq_val);
+ break;
+ }
+ }
+
+ return 0;
+}
+
+int msm_sensor_get_sub_module_index(struct device_node *of_node,
+ struct msm_sensor_info_t **s_info)
+{
+ int rc = 0, i = 0;
+ uint32_t val = 0, count = 0;
+ uint32_t *val_array = NULL;
+ struct device_node *src_node = NULL;
+ struct msm_sensor_info_t *sensor_info;
+
+ sensor_info = kzalloc(sizeof(*sensor_info), GFP_KERNEL);
+ if (!sensor_info) {
+ pr_err("%s:%d failed\n", __func__, __LINE__);
+ return -ENOMEM;
+ }
+ for (i = 0; i < SUB_MODULE_MAX; i++)
+ sensor_info->subdev_id[i] = -1;
+
+ 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__);
+ goto ERROR;
+ }
+ sensor_info->subdev_id[SUB_MODULE_ACTUATOR] = val;
+ of_node_put(src_node);
+ src_node = NULL;
+ }
+
+ src_node = of_parse_phandle(of_node, "qcom,eeprom-src", 0);
+ if (!src_node) {
+ CDBG("%s:%d eeprom src_node NULL\n", __func__, __LINE__);
+ } else {
+ 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("%s failed %d\n", __func__, __LINE__);
+ goto ERROR;
+ }
+ sensor_info->subdev_id[SUB_MODULE_EEPROM] = val;
+ of_node_put(src_node);
+ src_node = NULL;
+ }
+
+ if (of_property_read_bool(of_node, "qcom,eeprom-sd-index") ==
+ true) {
+ rc = of_property_read_u32(of_node, "qcom,eeprom-sd-index",
+ &val);
+ CDBG("%s qcom,eeprom-sd-index %d, rc %d\n", __func__, val, rc);
+ if (rc < 0) {
+ pr_err("%s:%d failed rc %d\n", __func__, __LINE__, rc);
+ goto ERROR;
+ }
+ sensor_info->subdev_id[SUB_MODULE_EEPROM] = val;
+ }
+
+ src_node = of_parse_phandle(of_node, "qcom,led-flash-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,led flash cell index %d, rc %d\n", __func__,
+ val, rc);
+ if (rc < 0) {
+ pr_err("%s:%d failed %d\n", __func__, __LINE__, rc);
+ goto ERROR;
+ }
+ sensor_info->subdev_id[SUB_MODULE_LED_FLASH] = val;
+ of_node_put(src_node);
+ src_node = NULL;
+ }
+
+ if (of_property_read_bool(of_node, "qcom,strobe-flash-sd-index") ==
+ true) {
+ rc = of_property_read_u32(of_node, "qcom,strobe-flash-sd-index",
+ &val);
+ CDBG("%s qcom,strobe-flash-sd-index %d, rc %d\n", __func__,
+ val, rc);
+ if (rc < 0) {
+ pr_err("%s:%d failed rc %d\n", __func__, __LINE__, rc);
+ goto ERROR;
+ }
+ sensor_info->subdev_id[SUB_MODULE_STROBE_FLASH] = val;
+ }
+
+ if (of_get_property(of_node, "qcom,csiphy-sd-index", &count)) {
+ count /= sizeof(uint32_t);
+ if (count > 2) {
+ pr_err("%s qcom,csiphy-sd-index count %d > 2\n",
+ __func__, count);
+ goto ERROR;
+ }
+ val_array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
+ if (!val_array) {
+ pr_err("%s failed %d\n", __func__, __LINE__);
+ rc = -ENOMEM;
+ goto ERROR;
+ }
+
+ rc = of_property_read_u32_array(of_node, "qcom,csiphy-sd-index",
+ val_array, count);
+ if (rc < 0) {
+ pr_err("%s failed %d\n", __func__, __LINE__);
+ kfree(val_array);
+ goto ERROR;
+ }
+ for (i = 0; i < count; i++) {
+ sensor_info->subdev_id[SUB_MODULE_CSIPHY + i] =
+ val_array[i];
+ CDBG("%s csiphy_core[%d] = %d\n",
+ __func__, i, val_array[i]);
+ }
+ kfree(val_array);
+ } else {
+ pr_err("%s:%d qcom,csiphy-sd-index not present\n", __func__,
+ __LINE__);
+ rc = -EINVAL;
+ goto ERROR;
+ }
+
+ if (of_get_property(of_node, "qcom,csid-sd-index", &count)) {
+ count /= sizeof(uint32_t);
+ if (count > 2) {
+ pr_err("%s qcom,csid-sd-index count %d > 2\n",
+ __func__, count);
+ rc = -EINVAL;
+ goto ERROR;
+ }
+ val_array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
+ if (!val_array) {
+ pr_err("%s failed %d\n", __func__, __LINE__);
+ rc = -ENOMEM;
+ goto ERROR;
+ }
+
+ rc = of_property_read_u32_array(of_node, "qcom,csid-sd-index",
+ val_array, count);
+ if (rc < 0) {
+ pr_err("%s failed %d\n", __func__, __LINE__);
+ kfree(val_array);
+ goto ERROR;
+ }
+ for (i = 0; i < count; i++) {
+ sensor_info->subdev_id
+ [SUB_MODULE_CSID + i] = val_array[i];
+ CDBG("%s csid_core[%d] = %d\n",
+ __func__, i, val_array[i]);
+ }
+ kfree(val_array);
+ } else {
+ pr_err("%s:%d qcom,csid-sd-index not present\n", __func__,
+ __LINE__);
+ rc = -EINVAL;
+ goto ERROR;
+ }
+
+ *s_info = sensor_info;
+ return rc;
+ERROR:
+ kfree(sensor_info);
+ return rc;
+}
+
+int msm_sensor_get_dt_actuator_data(struct device_node *of_node,
+ struct msm_actuator_info **act_info)
+{
+ int rc = 0;
+ uint32_t val = 0;
+ struct msm_actuator_info *actuator_info;
+
+ rc = of_property_read_u32(of_node, "qcom,actuator-cam-name", &val);
+ CDBG("%s qcom,actuator-cam-name %d, rc %d\n", __func__, val, rc);
+ if (rc < 0)
+ return 0;
+
+ actuator_info = kzalloc(sizeof(*actuator_info), GFP_KERNEL);
+ if (!actuator_info) {
+ pr_err("%s failed %d\n", __func__, __LINE__);
+ rc = -ENOMEM;
+ goto ERROR;
+ }
+
+ actuator_info->cam_name = val;
+
+ rc = of_property_read_u32(of_node, "qcom,actuator-vcm-pwd", &val);
+ CDBG("%s qcom,actuator-vcm-pwd %d, rc %d\n", __func__, val, rc);
+ if (!rc)
+ actuator_info->vcm_pwd = val;
+
+ rc = of_property_read_u32(of_node, "qcom,actuator-vcm-enable", &val);
+ CDBG("%s qcom,actuator-vcm-enable %d, rc %d\n", __func__, val, rc);
+ if (!rc)
+ actuator_info->vcm_enable = val;
+
+ *act_info = actuator_info;
+ return 0;
+ERROR:
+ kfree(actuator_info);
+ return rc;
+}
+
+int msm_sensor_get_dt_csi_data(struct device_node *of_node,
+ struct msm_camera_csi_lane_params **csi_lane_params)
+{
+ int rc = 0;
+ uint32_t val = 0;
+ struct msm_camera_csi_lane_params *clp;
+
+ clp = kzalloc(sizeof(*clp), GFP_KERNEL);
+ if (!clp) {
+ pr_err("%s failed %d\n", __func__, __LINE__);
+ return -ENOMEM;
+ }
+ *csi_lane_params = clp;
+
+ rc = of_property_read_u32(of_node, "qcom,csi-lane-assign", &val);
+ CDBG("%s qcom,csi-lane-assign %x, rc %d\n", __func__, val, rc);
+ if (rc < 0) {
+ pr_err("%s failed %d\n", __func__, __LINE__);
+ goto ERROR;
+ }
+ clp->csi_lane_assign = val;
+
+ rc = of_property_read_u32(of_node, "qcom,csi-lane-mask", &val);
+ CDBG("%s qcom,csi-lane-mask %x, rc %d\n", __func__, val, rc);
+ if (rc < 0) {
+ pr_err("%s failed %d\n", __func__, __LINE__);
+ goto ERROR;
+ }
+ clp->csi_lane_mask = val;
+
+ return rc;
+ERROR:
+ kfree(clp);
+ return rc;
+}
+
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;
@@ -34,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)
@@ -49,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,
@@ -180,7 +509,6 @@
}
kfree(array);
return rc;
-
ERROR2:
kfree(array);
ERROR1:
@@ -273,7 +601,91 @@
return rc;
}
-int32_t msm_camera_init_gpio_pin_tbl(struct device_node *of_node,
+int msm_camera_get_dt_gpio_set_tbl(struct device_node *of_node,
+ struct msm_camera_gpio_conf *gconf, uint16_t *gpio_array,
+ uint16_t gpio_array_size)
+{
+ int rc = 0, i = 0;
+ uint32_t count = 0;
+ uint32_t *val_array = NULL;
+
+ if (!of_get_property(of_node, "qcom,gpio-set-tbl-num", &count))
+ return 0;
+
+ count /= sizeof(uint32_t);
+ if (!count) {
+ pr_err("%s qcom,gpio-set-tbl-num 0\n", __func__);
+ return 0;
+ }
+
+ val_array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
+ if (!val_array) {
+ pr_err("%s failed %d\n", __func__, __LINE__);
+ return -ENOMEM;
+ }
+
+ gconf->cam_gpio_set_tbl = kzalloc(sizeof(struct msm_gpio_set_tbl) *
+ count, GFP_KERNEL);
+ if (!gconf->cam_gpio_set_tbl) {
+ pr_err("%s failed %d\n", __func__, __LINE__);
+ rc = -ENOMEM;
+ goto ERROR1;
+ }
+ gconf->cam_gpio_set_tbl_size = count;
+
+ rc = of_property_read_u32_array(of_node, "qcom,gpio-set-tbl-num",
+ val_array, count);
+ if (rc < 0) {
+ pr_err("%s failed %d\n", __func__, __LINE__);
+ goto ERROR2;
+ }
+ for (i = 0; i < count; i++) {
+ if (val_array[i] >= gpio_array_size) {
+ pr_err("%s gpio set tbl index %d invalid\n",
+ __func__, val_array[i]);
+ return -EINVAL;
+ }
+ gconf->cam_gpio_set_tbl[i].gpio = gpio_array[val_array[i]];
+ CDBG("%s cam_gpio_set_tbl[%d].gpio = %d\n", __func__, i,
+ gconf->cam_gpio_set_tbl[i].gpio);
+ }
+
+ rc = of_property_read_u32_array(of_node, "qcom,gpio-set-tbl-flags",
+ val_array, count);
+ if (rc < 0) {
+ pr_err("%s failed %d\n", __func__, __LINE__);
+ goto ERROR2;
+ }
+ for (i = 0; i < count; i++) {
+ gconf->cam_gpio_set_tbl[i].flags = val_array[i];
+ CDBG("%s cam_gpio_set_tbl[%d].flags = %ld\n", __func__, i,
+ gconf->cam_gpio_set_tbl[i].flags);
+ }
+
+ rc = of_property_read_u32_array(of_node, "qcom,gpio-set-tbl-delay",
+ val_array, count);
+ if (rc < 0) {
+ pr_err("%s failed %d\n", __func__, __LINE__);
+ goto ERROR2;
+ }
+ for (i = 0; i < count; i++) {
+ gconf->cam_gpio_set_tbl[i].delay = val_array[i];
+ CDBG("%s cam_gpio_set_tbl[%d].delay = %d\n", __func__, i,
+ gconf->cam_gpio_set_tbl[i].delay);
+ }
+
+ kfree(val_array);
+ return rc;
+
+ERROR2:
+ kfree(gconf->cam_gpio_set_tbl);
+ERROR1:
+ kfree(val_array);
+ gconf->cam_gpio_set_tbl_size = 0;
+ return rc;
+}
+
+int msm_camera_init_gpio_pin_tbl(struct device_node *of_node,
struct msm_camera_gpio_conf *gconf, uint16_t *gpio_array,
uint16_t gpio_array_size)
{
@@ -300,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]);
}
@@ -317,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]);
}
@@ -334,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:
@@ -529,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]);
@@ -589,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],
@@ -597,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);
@@ -629,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) {
@@ -647,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)
@@ -691,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 fee2a4c..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
@@ -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
@@ -18,28 +18,44 @@
#include <linux/of.h>
#include "msm_camera_i2c.h"
-int32_t msm_camera_get_dt_power_setting_data(struct device_node *of_node,
+int msm_sensor_get_sub_module_index(struct device_node *of_node,
+ struct msm_sensor_info_t **s_info);
+
+int msm_sensor_get_dt_actuator_data(struct device_node *of_node,
+ struct msm_actuator_info **act_info);
+
+int msm_sensor_get_dt_csi_data(struct device_node *of_node,
+ struct msm_camera_csi_lane_params **csi_lane_params);
+
+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);
-int32_t msm_camera_get_dt_gpio_req_tbl(struct device_node *of_node,
+int msm_camera_get_dt_gpio_req_tbl(struct device_node *of_node,
struct msm_camera_gpio_conf *gconf, uint16_t *gpio_array,
uint16_t gpio_array_size);
-int32_t msm_camera_init_gpio_pin_tbl(struct device_node *of_node,
+int msm_camera_get_dt_gpio_set_tbl(struct device_node *of_node,
struct msm_camera_gpio_conf *gconf, uint16_t *gpio_array,
uint16_t gpio_array_size);
-int32_t msm_camera_get_dt_vreg_data(struct device_node *of_node,
+int msm_camera_init_gpio_pin_tbl(struct device_node *of_node,
+ struct msm_camera_gpio_conf *gconf, uint16_t *gpio_array,
+ uint16_t gpio_array_size);
+
+int msm_camera_get_dt_vreg_data(struct device_node *of_node,
struct camera_vreg_t **cam_vreg, int *num_vreg);
-int32_t msm_camera_power_up(struct msm_camera_power_ctrl_t *ctrl,
+int msm_camera_power_up(struct msm_camera_power_ctrl_t *ctrl,
enum msm_camera_device_type_t device_type,
struct msm_camera_i2c_client *sensor_i2c_client);
-int32_t msm_camera_power_down(struct msm_camera_power_ctrl_t *ctrl,
+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 msm_camera_fill_vreg_params(struct camera_vreg_t *cam_vreg,
+ int num_vreg, struct msm_sensor_power_setting *power_setting,
+ uint16_t power_setting_size);
+
#endif
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 7e84e7b..87ad994 100755
--- a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c
@@ -20,6 +20,7 @@
#include <mach/rpm-regulator-smd.h>
#include <linux/regulator/consumer.h>
+/*#define CONFIG_MSMB_CAMERA_DEBUG*/
#undef CDBG
#ifdef CONFIG_MSMB_CAMERA_DEBUG
#define CDBG(fmt, args...) pr_err(fmt, ##args)
@@ -27,674 +28,76 @@
#define CDBG(fmt, args...) do { } while (0)
#endif
-static int32_t msm_sensor_enable_i2c_mux(struct msm_camera_i2c_conf *i2c_conf)
+static int32_t msm_camera_get_power_settimgs_from_sensor_lib(
+ struct msm_camera_power_ctrl_t *power_info,
+ struct msm_sensor_power_setting_array *power_setting_array)
{
- struct v4l2_subdev *i2c_mux_sd =
- dev_get_drvdata(&i2c_conf->mux_dev->dev);
- v4l2_subdev_call(i2c_mux_sd, core, ioctl,
- VIDIOC_MSM_I2C_MUX_INIT, NULL);
- v4l2_subdev_call(i2c_mux_sd, core, ioctl,
- VIDIOC_MSM_I2C_MUX_CFG, (void *)&i2c_conf->i2c_mux_mode);
- return 0;
-}
+ int32_t rc = 0;
+ uint32_t size;
+ struct msm_sensor_power_setting *ps;
+ bool need_reverse = 0;
-static int32_t msm_sensor_disable_i2c_mux(struct msm_camera_i2c_conf *i2c_conf)
-{
- struct v4l2_subdev *i2c_mux_sd =
- dev_get_drvdata(&i2c_conf->mux_dev->dev);
- v4l2_subdev_call(i2c_mux_sd, core, ioctl,
- VIDIOC_MSM_I2C_MUX_RELEASE, NULL);
- return 0;
-}
+ if ((NULL == power_info->power_setting) ||
+ (0 == power_info->power_setting_size)) {
-static int32_t msm_sensor_get_sub_module_index(struct device_node *of_node,
- struct msm_camera_sensor_board_info *sensordata)
-{
- int32_t rc = 0, i = 0;
- uint32_t val = 0, count = 0;
- uint32_t *val_array = NULL;
- struct device_node *src_node = NULL;
-
- sensordata->sensor_info = kzalloc(sizeof(struct msm_sensor_info_t),
- GFP_KERNEL);
- if (!sensordata->sensor_info) {
- pr_err("%s:%d failed\n", __func__, __LINE__);
- return -ENOMEM;
- }
- for (i = 0; i < SUB_MODULE_MAX; i++)
- sensordata->sensor_info->subdev_id[i] = -1;
-
- 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) {
+ ps = power_setting_array->power_setting;
+ size = power_setting_array->size;
+ if ((NULL == ps) || (0 == size)) {
pr_err("%s failed %d\n", __func__, __LINE__);
- goto ERROR;
- }
- sensordata->sensor_info->
- subdev_id[SUB_MODULE_ACTUATOR] = val;
- of_node_put(src_node);
- src_node = NULL;
- }
-
- src_node = of_parse_phandle(of_node, "qcom,eeprom-src", 0);
- if (!src_node) {
- CDBG("%s:%d eeprom src_node NULL\n", __func__, __LINE__);
- } else {
- 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("%s failed %d\n", __func__, __LINE__);
- goto ERROR;
- }
- sensordata->sensor_info->
- subdev_id[SUB_MODULE_EEPROM] = val;
- of_node_put(src_node);
- src_node = NULL;
- }
-
- if (of_property_read_bool(of_node, "qcom,eeprom-sd-index") ==
- true) {
- rc = of_property_read_u32(of_node, "qcom,eeprom-sd-index",
- &val);
- CDBG("%s qcom,eeprom-sd-index %d, rc %d\n", __func__, val, rc);
- if (rc < 0) {
- pr_err("%s:%d failed rc %d\n", __func__, __LINE__, rc);
- goto ERROR;
- }
- sensordata->sensor_info->subdev_id[SUB_MODULE_EEPROM] = val;
- }
-
- src_node = of_parse_phandle(of_node, "qcom,led-flash-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,led flash cell index %d, rc %d\n", __func__,
- val, rc);
- if (rc < 0) {
- pr_err("%s:%d failed %d\n", __func__, __LINE__, rc);
- goto ERROR;
- }
- sensordata->sensor_info->
- subdev_id[SUB_MODULE_LED_FLASH] = val;
- of_node_put(src_node);
- src_node = NULL;
- }
-
- if (of_property_read_bool(of_node, "qcom,strobe-flash-sd-index") ==
- true) {
- rc = of_property_read_u32(of_node, "qcom,strobe-flash-sd-index",
- &val);
- CDBG("%s qcom,strobe-flash-sd-index %d, rc %d\n", __func__,
- val, rc);
- if (rc < 0) {
- pr_err("%s:%d failed rc %d\n", __func__, __LINE__, rc);
- goto ERROR;
- }
- sensordata->sensor_info->subdev_id[SUB_MODULE_STROBE_FLASH] =
- val;
- }
-
- if (of_get_property(of_node, "qcom,csiphy-sd-index", &count)) {
- count /= sizeof(uint32_t);
- if (count > 2) {
- pr_err("%s qcom,csiphy-sd-index count %d > 2\n",
- __func__, count);
- goto ERROR;
- }
- val_array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
- if (!val_array) {
- pr_err("%s failed %d\n", __func__, __LINE__);
- rc = -ENOMEM;
- goto ERROR;
- }
-
- rc = of_property_read_u32_array(of_node, "qcom,csiphy-sd-index",
- val_array, count);
- if (rc < 0) {
- pr_err("%s failed %d\n", __func__, __LINE__);
- kfree(val_array);
- goto ERROR;
- }
- for (i = 0; i < count; i++) {
- sensordata->sensor_info->subdev_id
- [SUB_MODULE_CSIPHY + i] = val_array[i];
- CDBG("%s csiphy_core[%d] = %d\n",
- __func__, i, val_array[i]);
- }
- kfree(val_array);
- } else {
- pr_err("%s:%d qcom,csiphy-sd-index not present\n", __func__,
- __LINE__);
- rc = -EINVAL;
- goto ERROR;
- }
-
- if (of_get_property(of_node, "qcom,csid-sd-index", &count)) {
- count /= sizeof(uint32_t);
- if (count > 2) {
- pr_err("%s qcom,csid-sd-index count %d > 2\n",
- __func__, count);
rc = -EINVAL;
- goto ERROR;
+ goto FAILED_1;
}
- val_array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
- if (!val_array) {
+
+ power_info->power_setting =
+ kzalloc(sizeof(*ps) * size, GFP_KERNEL);
+ if (!power_info->power_setting) {
pr_err("%s failed %d\n", __func__, __LINE__);
rc = -ENOMEM;
- goto ERROR;
+ goto FAILED_1;
}
-
- rc = of_property_read_u32_array(of_node, "qcom,csid-sd-index",
- val_array, count);
- if (rc < 0) {
- pr_err("%s failed %d\n", __func__, __LINE__);
- kfree(val_array);
- goto ERROR;
- }
- for (i = 0; i < count; i++) {
- sensordata->sensor_info->subdev_id
- [SUB_MODULE_CSID + i] = val_array[i];
- CDBG("%s csid_core[%d] = %d\n",
- __func__, i, val_array[i]);
- }
- kfree(val_array);
- } else {
- pr_err("%s:%d qcom,csid-sd-index not present\n", __func__,
- __LINE__);
- rc = -EINVAL;
- goto ERROR;
+ memcpy(power_info->power_setting,
+ power_setting_array->power_setting,
+ sizeof(*ps) * size);
+ power_info->power_setting_size = size;
}
- return rc;
-ERROR:
- kfree(sensordata->sensor_info);
- sensordata->sensor_info = NULL;
- return rc;
-}
-static int32_t msm_sensor_get_dt_csi_data(struct device_node *of_node,
- struct msm_camera_sensor_board_info *sensordata)
-{
- int32_t rc = 0;
- uint32_t val = 0;
+ 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;
+ }
- sensordata->csi_lane_params = kzalloc(
- sizeof(struct msm_camera_csi_lane_params), GFP_KERNEL);
- if (!sensordata->csi_lane_params) {
+ 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__);
- rc = -ENOMEM;
- goto ERROR1;
+ goto FREE_UP;
}
+ memcpy(power_info->power_down_setting,
+ ps,
+ sizeof(*ps) * size);
+ power_info->power_down_setting_size = size;
- rc = of_property_read_u32(of_node, "qcom,csi-lane-assign", &val);
- CDBG("%s qcom,csi-lane-assign %x, rc %d\n", __func__, val, rc);
- if (rc < 0) {
- pr_err("%s failed %d\n", __func__, __LINE__);
- goto ERROR2;
- }
- sensordata->csi_lane_params->csi_lane_assign = val;
-
- rc = of_property_read_u32(of_node, "qcom,csi-lane-mask", &val);
- CDBG("%s qcom,csi-lane-mask %x, rc %d\n", __func__, val, rc);
- if (rc < 0) {
- pr_err("%s failed %d\n", __func__, __LINE__);
- goto ERROR2;
- }
- sensordata->csi_lane_params->csi_lane_mask = val;
-
- return rc;
-ERROR2:
- kfree(sensordata->csi_lane_params);
-ERROR1:
- return rc;
-}
-
-static int32_t msm_sensor_get_dt_vreg_data(struct device_node *of_node,
- struct msm_camera_sensor_board_info *sensordata)
-{
- int32_t rc = 0, i = 0;
- uint32_t count = 0;
- uint32_t *vreg_array = NULL;
-
- count = of_property_count_strings(of_node, "qcom,cam-vreg-name");
- CDBG("%s qcom,cam-vreg-name count %d\n", __func__, count);
-
- if (!count)
- return 0;
-
- sensordata->cam_vreg = kzalloc(sizeof(struct camera_vreg_t) * count,
- GFP_KERNEL);
- if (!sensordata->cam_vreg) {
- pr_err("%s failed %d\n", __func__, __LINE__);
- return -ENOMEM;
- }
-
- sensordata->num_vreg = count;
- for (i = 0; i < count; i++) {
- rc = of_property_read_string_index(of_node,
- "qcom,cam-vreg-name", i,
- &sensordata->cam_vreg[i].reg_name);
- CDBG("%s reg_name[%d] = %s\n", __func__, i,
- sensordata->cam_vreg[i].reg_name);
- if (rc < 0) {
- pr_err("%s failed %d\n", __func__, __LINE__);
- goto ERROR1;
+ 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--;
}
}
- vreg_array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
- if (!vreg_array) {
- pr_err("%s failed %d\n", __func__, __LINE__);
- rc = -ENOMEM;
- goto ERROR1;
- }
-
- rc = of_property_read_u32_array(of_node, "qcom,cam-vreg-type",
- vreg_array, count);
- if (rc < 0) {
- pr_err("%s failed %d\n", __func__, __LINE__);
- goto ERROR2;
- }
- for (i = 0; i < count; i++) {
- sensordata->cam_vreg[i].type = vreg_array[i];
- CDBG("%s cam_vreg[%d].type = %d\n", __func__, i,
- sensordata->cam_vreg[i].type);
- }
-
- rc = of_property_read_u32_array(of_node, "qcom,cam-vreg-min-voltage",
- vreg_array, count);
- if (rc < 0) {
- pr_err("%s failed %d\n", __func__, __LINE__);
- goto ERROR2;
- }
- for (i = 0; i < count; i++) {
- sensordata->cam_vreg[i].min_voltage = vreg_array[i];
- CDBG("%s cam_vreg[%d].min_voltage = %d\n", __func__,
- i, sensordata->cam_vreg[i].min_voltage);
- }
-
- rc = of_property_read_u32_array(of_node, "qcom,cam-vreg-max-voltage",
- vreg_array, count);
- if (rc < 0) {
- pr_err("%s failed %d\n", __func__, __LINE__);
- goto ERROR2;
- }
- for (i = 0; i < count; i++) {
- sensordata->cam_vreg[i].max_voltage = vreg_array[i];
- CDBG("%s cam_vreg[%d].max_voltage = %d\n", __func__,
- i, sensordata->cam_vreg[i].max_voltage);
- }
-
- rc = of_property_read_u32_array(of_node, "qcom,cam-vreg-op-mode",
- vreg_array, count);
- if (rc < 0) {
- pr_err("%s failed %d\n", __func__, __LINE__);
- goto ERROR2;
- }
- for (i = 0; i < count; i++) {
- sensordata->cam_vreg[i].op_mode = vreg_array[i];
- CDBG("%s cam_vreg[%d].op_mode = %d\n", __func__, i,
- sensordata->cam_vreg[i].op_mode);
- }
-
- kfree(vreg_array);
- return rc;
-ERROR2:
- kfree(vreg_array);
-ERROR1:
- kfree(sensordata->cam_vreg);
- sensordata->num_vreg = 0;
- return rc;
-}
-
-int32_t msm_sensor_get_dt_gpio_req_tbl(struct device_node *of_node,
- struct msm_camera_gpio_conf *gconf, uint16_t *gpio_array,
- uint16_t gpio_array_size)
-{
- int32_t rc = 0, i = 0;
- uint32_t count = 0;
- uint32_t *val_array = NULL;
-
- if (!of_get_property(of_node, "qcom,gpio-req-tbl-num", &count))
- return 0;
-
- count /= sizeof(uint32_t);
- if (!count) {
- pr_err("%s qcom,gpio-req-tbl-num 0\n", __func__);
- return 0;
- }
-
- val_array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
- if (!val_array) {
- pr_err("%s failed %d\n", __func__, __LINE__);
- return -ENOMEM;
- }
-
- gconf->cam_gpio_req_tbl = kzalloc(sizeof(struct gpio) * count,
- GFP_KERNEL);
- if (!gconf->cam_gpio_req_tbl) {
- pr_err("%s failed %d\n", __func__, __LINE__);
- rc = -ENOMEM;
- goto ERROR1;
- }
- gconf->cam_gpio_req_tbl_size = count;
-
- rc = of_property_read_u32_array(of_node, "qcom,gpio-req-tbl-num",
- val_array, count);
- if (rc < 0) {
- pr_err("%s failed %d\n", __func__, __LINE__);
- goto ERROR2;
- }
- for (i = 0; i < count; i++) {
- if (val_array[i] >= gpio_array_size) {
- pr_err("%s gpio req tbl index %d invalid\n",
- __func__, val_array[i]);
- return -EINVAL;
- }
- gconf->cam_gpio_req_tbl[i].gpio = gpio_array[val_array[i]];
- CDBG("%s cam_gpio_req_tbl[%d].gpio = %d\n", __func__, i,
- gconf->cam_gpio_req_tbl[i].gpio);
- }
-
- rc = of_property_read_u32_array(of_node, "qcom,gpio-req-tbl-flags",
- val_array, count);
- if (rc < 0) {
- pr_err("%s failed %d\n", __func__, __LINE__);
- goto ERROR2;
- }
- for (i = 0; i < count; i++) {
- gconf->cam_gpio_req_tbl[i].flags = val_array[i];
- CDBG("%s cam_gpio_req_tbl[%d].flags = %ld\n", __func__, i,
- gconf->cam_gpio_req_tbl[i].flags);
- }
-
- for (i = 0; i < count; i++) {
- rc = of_property_read_string_index(of_node,
- "qcom,gpio-req-tbl-label", i,
- &gconf->cam_gpio_req_tbl[i].label);
- CDBG("%s cam_gpio_req_tbl[%d].label = %s\n", __func__, i,
- gconf->cam_gpio_req_tbl[i].label);
- if (rc < 0) {
- pr_err("%s failed %d\n", __func__, __LINE__);
- goto ERROR2;
- }
- }
-
- kfree(val_array);
- return rc;
-
-ERROR2:
- kfree(gconf->cam_gpio_req_tbl);
-ERROR1:
- kfree(val_array);
- gconf->cam_gpio_req_tbl_size = 0;
- return rc;
-}
-
-int32_t msm_sensor_get_dt_gpio_set_tbl(struct device_node *of_node,
- struct msm_camera_gpio_conf *gconf, uint16_t *gpio_array,
- uint16_t gpio_array_size)
-{
- int32_t rc = 0, i = 0;
- uint32_t count = 0;
- uint32_t *val_array = NULL;
-
- if (!of_get_property(of_node, "qcom,gpio-set-tbl-num", &count))
- return 0;
-
- count /= sizeof(uint32_t);
- if (!count) {
- pr_err("%s qcom,gpio-set-tbl-num 0\n", __func__);
- return 0;
- }
-
- val_array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
- if (!val_array) {
- pr_err("%s failed %d\n", __func__, __LINE__);
- return -ENOMEM;
- }
-
- gconf->cam_gpio_set_tbl = kzalloc(sizeof(struct msm_gpio_set_tbl) *
- count, GFP_KERNEL);
- if (!gconf->cam_gpio_set_tbl) {
- pr_err("%s failed %d\n", __func__, __LINE__);
- rc = -ENOMEM;
- goto ERROR1;
- }
- gconf->cam_gpio_set_tbl_size = count;
-
- rc = of_property_read_u32_array(of_node, "qcom,gpio-set-tbl-num",
- val_array, count);
- if (rc < 0) {
- pr_err("%s failed %d\n", __func__, __LINE__);
- goto ERROR2;
- }
- for (i = 0; i < count; i++) {
- if (val_array[i] >= gpio_array_size) {
- pr_err("%s gpio set tbl index %d invalid\n",
- __func__, val_array[i]);
- return -EINVAL;
- }
- gconf->cam_gpio_set_tbl[i].gpio = gpio_array[val_array[i]];
- CDBG("%s cam_gpio_set_tbl[%d].gpio = %d\n", __func__, i,
- gconf->cam_gpio_set_tbl[i].gpio);
- }
-
- rc = of_property_read_u32_array(of_node, "qcom,gpio-set-tbl-flags",
- val_array, count);
- if (rc < 0) {
- pr_err("%s failed %d\n", __func__, __LINE__);
- goto ERROR2;
- }
- for (i = 0; i < count; i++) {
- gconf->cam_gpio_set_tbl[i].flags = val_array[i];
- CDBG("%s cam_gpio_set_tbl[%d].flags = %ld\n", __func__, i,
- gconf->cam_gpio_set_tbl[i].flags);
- }
-
- rc = of_property_read_u32_array(of_node, "qcom,gpio-set-tbl-delay",
- val_array, count);
- if (rc < 0) {
- pr_err("%s failed %d\n", __func__, __LINE__);
- goto ERROR2;
- }
- for (i = 0; i < count; i++) {
- gconf->cam_gpio_set_tbl[i].delay = val_array[i];
- CDBG("%s cam_gpio_set_tbl[%d].delay = %d\n", __func__, i,
- gconf->cam_gpio_set_tbl[i].delay);
- }
-
- kfree(val_array);
- return rc;
-
-ERROR2:
- kfree(gconf->cam_gpio_set_tbl);
-ERROR1:
- kfree(val_array);
- gconf->cam_gpio_set_tbl_size = 0;
- return rc;
-}
-
-int32_t msm_sensor_init_gpio_pin_tbl(struct device_node *of_node,
- struct msm_camera_gpio_conf *gconf, uint16_t *gpio_array,
- uint16_t gpio_array_size)
-{
- int32_t rc = 0;
- int32_t val = 0;
-
- gconf->gpio_num_info = kzalloc(sizeof(struct msm_camera_gpio_num_info),
- GFP_KERNEL);
- if (!gconf->gpio_num_info) {
- pr_err("%s failed %d\n", __func__, __LINE__);
- rc = -ENOMEM;
- return rc;
- }
-
- if (of_property_read_bool(of_node, "qcom,gpio-reset") == true) {
- rc = of_property_read_u32(of_node, "qcom,gpio-reset", &val);
- if (rc < 0) {
- pr_err("%s:%d read qcom,gpio-reset failed rc %d\n",
- __func__, __LINE__, rc);
- goto ERROR;
- } else if (val >= gpio_array_size) {
- pr_err("%s:%d qcom,gpio-reset invalid %d\n",
- __func__, __LINE__, val);
- goto ERROR;
- }
- gconf->gpio_num_info->gpio_num[SENSOR_GPIO_RESET] =
- gpio_array[val];
- CDBG("%s qcom,gpio-reset %d\n", __func__,
- gconf->gpio_num_info->gpio_num[SENSOR_GPIO_RESET]);
- }
-
- if (of_property_read_bool(of_node, "qcom,gpio-standby") == true) {
- rc = of_property_read_u32(of_node, "qcom,gpio-standby", &val);
- if (rc < 0) {
- pr_err("%s:%d read qcom,gpio-standby failed rc %d\n",
- __func__, __LINE__, rc);
- goto ERROR;
- } else if (val >= gpio_array_size) {
- pr_err("%s:%d qcom,gpio-standby invalid %d\n",
- __func__, __LINE__, val);
- goto ERROR;
- }
- gconf->gpio_num_info->gpio_num[SENSOR_GPIO_STANDBY] =
- gpio_array[val];
- CDBG("%s qcom,gpio-reset %d\n", __func__,
- gconf->gpio_num_info->gpio_num[SENSOR_GPIO_STANDBY]);
- }
-
- rc = of_property_read_u32(of_node, "qcom,gpio-vio", &val);
- if (!rc) {
- if (val >= gpio_array_size) {
- pr_err("%s:%d qcom,gpio-vio invalid %d\n",
- __func__, __LINE__, val);
- goto ERROR;
- }
- gconf->gpio_num_info->gpio_num[SENSOR_GPIO_VIO] =
- gpio_array[val];
- CDBG("%s qcom,gpio-vio %d\n", __func__,
- gconf->gpio_num_info->gpio_num[SENSOR_GPIO_VIO]);
- } else if (rc != -EINVAL) {
- pr_err("%s:%d read qcom,gpio-vio failed rc %d\n",
- __func__, __LINE__, rc);
- goto ERROR;
- }
-
- rc = of_property_read_u32(of_node, "qcom,gpio-vana", &val);
- if (!rc) {
- if (val >= gpio_array_size) {
- pr_err("%s:%d qcom,gpio-vana invalid %d\n",
- __func__, __LINE__, val);
- goto ERROR;
- }
- gconf->gpio_num_info->gpio_num[SENSOR_GPIO_VANA] =
- gpio_array[val];
- CDBG("%s qcom,gpio-vana %d\n", __func__,
- gconf->gpio_num_info->gpio_num[SENSOR_GPIO_VANA]);
- } else if (rc != -EINVAL) {
- pr_err("%s:%d read qcom,gpio-vana failed rc %d\n",
- __func__, __LINE__, rc);
- goto ERROR;
- }
-
- rc = of_property_read_u32(of_node, "qcom,gpio-vdig", &val);
- if (!rc) {
- if (val >= gpio_array_size) {
- pr_err("%s:%d qcom,gpio-vdig invalid %d\n",
- __func__, __LINE__, val);
- goto ERROR;
- }
- gconf->gpio_num_info->gpio_num[SENSOR_GPIO_VDIG] =
- gpio_array[val];
- CDBG("%s qcom,gpio-vdig %d\n", __func__,
- gconf->gpio_num_info->gpio_num[SENSOR_GPIO_VDIG]);
- } else if (rc != -EINVAL) {
- pr_err("%s:%d read qcom,gpio-vdig failed rc %d\n",
- __func__, __LINE__, rc);
- goto ERROR;
- }
-
- rc = of_property_read_u32(of_node, "qcom,gpio-vaf", &val);
- if (!rc) {
- if (val >= gpio_array_size) {
- pr_err("%s:%d qcom,gpio-vaf invalid %d\n",
- __func__, __LINE__, val);
- goto ERROR;
- }
- gconf->gpio_num_info->gpio_num[SENSOR_GPIO_VAF] =
- gpio_array[val];
- CDBG("%s qcom,gpio-vaf %d\n", __func__,
- gconf->gpio_num_info->gpio_num[SENSOR_GPIO_VAF]);
- } else if (rc != -EINVAL) {
- pr_err("%s:%d read qcom,gpio-vaf failed rc %d\n",
- __func__, __LINE__, rc);
- goto ERROR;
- }
-
- rc = of_property_read_u32(of_node, "qcom,gpio-af-pwdm", &val);
- if (!rc) {
- if (val >= gpio_array_size) {
- pr_err("%s:%d qcom,gpio-af-pwdm invalid %d\n",
- __func__, __LINE__, val);
- goto ERROR;
- }
- gconf->gpio_num_info->gpio_num[SENSOR_GPIO_AF_PWDM] =
- gpio_array[val];
- CDBG("%s qcom,gpio-af-pwdm %d\n", __func__,
- gconf->gpio_num_info->gpio_num[SENSOR_GPIO_AF_PWDM]);
- } else if (rc != -EINVAL) {
- pr_err("%s:%d read qcom,gpio-af-pwdm failed rc %d\n",
- __func__, __LINE__, rc);
- goto ERROR;
- }
- return 0;
-
-ERROR:
- kfree(gconf->gpio_num_info);
- gconf->gpio_num_info = NULL;
- return rc;
-}
-
-static int32_t msm_sensor_get_dt_actuator_data(struct device_node *of_node,
- struct msm_camera_sensor_board_info *sensordata)
-{
- int32_t rc = 0;
- uint32_t val = 0;
-
- rc = of_property_read_u32(of_node, "qcom,actuator-cam-name", &val);
- CDBG("%s qcom,actuator-cam-name %d, rc %d\n", __func__, val, rc);
- if (rc < 0)
- return 0;
-
- sensordata->actuator_info = kzalloc(sizeof(struct msm_actuator_info),
- GFP_KERNEL);
- if (!sensordata->actuator_info) {
- pr_err("%s failed %d\n", __func__, __LINE__);
- rc = -ENOMEM;
- goto ERROR;
- }
-
- sensordata->actuator_info->cam_name = val;
-
- rc = of_property_read_u32(of_node, "qcom,actuator-vcm-pwd", &val);
- CDBG("%s qcom,actuator-vcm-pwd %d, rc %d\n", __func__, val, rc);
- if (!rc)
- sensordata->actuator_info->vcm_pwd = val;
-
- rc = of_property_read_u32(of_node, "qcom,actuator-vcm-enable", &val);
- CDBG("%s qcom,actuator-vcm-enable %d, rc %d\n", __func__, val, rc);
- if (!rc)
- sensordata->actuator_info->vcm_enable = val;
-
return 0;
-ERROR:
+FREE_UP:
+ kfree(power_info->power_setting);
+FAILED_1:
return rc;
}
@@ -718,48 +121,13 @@
sensordata = s_ctrl->sensordata;
- sensordata->sensor_init_params = kzalloc(sizeof(
- struct msm_sensor_init_params), GFP_KERNEL);
- if (!sensordata->sensor_init_params) {
- pr_err("%s failed %d\n", __func__, __LINE__);
- return -ENOMEM;
- }
-
rc = of_property_read_string(of_node, "qcom,sensor-name",
&sensordata->sensor_name);
CDBG("%s qcom,sensor-name %s, rc %d\n", __func__,
sensordata->sensor_name, rc);
if (rc < 0) {
pr_err("%s failed %d\n", __func__, __LINE__);
- goto ERROR1;
- }
-
- rc = of_property_read_u32(of_node, "qcom,sensor-mode",
- &sensordata->sensor_init_params->modes_supported);
- CDBG("%s qcom,sensor-mode %d, rc %d\n", __func__,
- sensordata->sensor_init_params->modes_supported, rc);
- if (rc < 0) {
- pr_err("%s failed %d\n", __func__, __LINE__);
- goto ERROR1;
- }
-
- rc = of_property_read_u32(of_node, "qcom,sensor-position",
- &sensordata->sensor_init_params->position);
- CDBG("%s qcom,sensor-position %d, rc %d\n", __func__,
- sensordata->sensor_init_params->position, rc);
- if (rc < 0) {
- pr_err("%s failed %d\n", __func__, __LINE__);
- goto ERROR1;
- }
-
- rc = of_property_read_u32(of_node, "qcom,mount-angle",
- &sensordata->sensor_init_params->sensor_mount_angle);
- CDBG("%s qcom,mount-angle %d, rc %d\n", __func__,
- sensordata->sensor_init_params->sensor_mount_angle, rc);
- if (rc < 0) {
- /* Set default mount angle */
- sensordata->sensor_init_params->sensor_mount_angle = 0;
- rc = 0;
+ goto FREE_SENSORDATA;
}
rc = of_property_read_u32(of_node, "qcom,cci-master",
@@ -772,32 +140,86 @@
rc = 0;
}
- rc = msm_sensor_get_sub_module_index(of_node, sensordata);
+ rc = msm_sensor_get_sub_module_index(of_node, &sensordata->sensor_info);
if (rc < 0) {
pr_err("%s failed %d\n", __func__, __LINE__);
- goto ERROR1;
+ goto FREE_SENSORDATA;
}
- rc = msm_sensor_get_dt_csi_data(of_node, sensordata);
+ /* Get sensor mount angle */
+ rc = of_property_read_u32(of_node, "qcom,mount-angle",
+ &sensordata->sensor_info->sensor_mount_angle);
+ CDBG("%s qcom,mount-angle %d, rc %d\n", __func__,
+ sensordata->sensor_info->sensor_mount_angle, rc);
+ if (rc < 0) {
+ /* Invalidate mount angle flag */
+ pr_err("%s Default sensor mount angle %d\n",
+ __func__, __LINE__);
+ sensordata->sensor_info->is_mount_angle_valid = 0;
+ sensordata->sensor_info->sensor_mount_angle = 0;
+ rc = 0;
+ } else {
+ sensordata->sensor_info->is_mount_angle_valid = 1;
+ }
+
+ rc = of_property_read_u32(of_node, "qcom,sensor-position",
+ &sensordata->sensor_info->position);
+ CDBG("%s qcom,sensor-position %d, rc %d\n", __func__,
+ sensordata->sensor_info->position, rc);
+ if (rc < 0) {
+ pr_err("%s Default sensor position %d\n", __func__, __LINE__);
+ sensordata->sensor_info->position = 0;
+ }
+
+ rc = of_property_read_u32(of_node, "qcom,sensor-mode",
+ &sensordata->sensor_info->modes_supported);
+ CDBG("%s qcom,sensor-mode %d, rc %d\n", __func__,
+ sensordata->sensor_info->modes_supported, rc);
+ if (rc < 0) {
+ pr_err("%s Default sensor mode %d\n", __func__, __LINE__);
+ sensordata->sensor_info->modes_supported = 0;
+ }
+
+ rc = msm_sensor_get_dt_csi_data(of_node, &sensordata->csi_lane_params);
if (rc < 0) {
pr_err("%s failed %d\n", __func__, __LINE__);
- goto ERROR1;
+ goto FREE_SENSOR_INFO;
}
- rc = msm_sensor_get_dt_vreg_data(of_node, sensordata);
+ rc = msm_camera_get_dt_vreg_data(of_node,
+ &sensordata->power_info.cam_vreg,
+ &sensordata->power_info.num_vreg);
+ if (rc < 0)
+ goto FREE_CSI;
+
+ rc = msm_camera_get_dt_power_setting_data(of_node,
+ sensordata->power_info.cam_vreg,
+ sensordata->power_info.num_vreg,
+ &sensordata->power_info);
+
+
if (rc < 0) {
pr_err("%s failed %d\n", __func__, __LINE__);
- goto ERROR2;
+ goto FREE_VREG;
}
- sensordata->gpio_conf = kzalloc(sizeof(struct msm_camera_gpio_conf),
- GFP_KERNEL);
- if (!sensordata->gpio_conf) {
+
+ rc = msm_camera_get_power_settimgs_from_sensor_lib(
+ &sensordata->power_info,
+ &s_ctrl->power_setting_array);
+ if (rc < 0) {
+ pr_err("%s failed %d\n", __func__, __LINE__);
+ goto FREE_VREG;
+ }
+
+ sensordata->power_info.gpio_conf = kzalloc(
+ sizeof(struct msm_camera_gpio_conf), GFP_KERNEL);
+ if (!sensordata->power_info.gpio_conf) {
pr_err("%s failed %d\n", __func__, __LINE__);
rc = -ENOMEM;
- goto ERROR3;
+ goto FREE_PS;
}
- gconf = sensordata->gpio_conf;
+ gconf = sensordata->power_info.gpio_conf;
gpio_array_size = of_gpio_count(of_node);
CDBG("%s gpio count %d\n", __func__, gpio_array_size);
@@ -807,7 +229,7 @@
GFP_KERNEL);
if (!gpio_array) {
pr_err("%s failed %d\n", __func__, __LINE__);
- goto ERROR4;
+ goto FREE_GPIO_CONF;
}
for (i = 0; i < gpio_array_size; i++) {
gpio_array[i] = of_get_gpio(of_node, i);
@@ -815,31 +237,32 @@
gpio_array[i]);
}
- rc = msm_sensor_get_dt_gpio_req_tbl(of_node, gconf,
+ rc = msm_camera_get_dt_gpio_req_tbl(of_node, gconf,
gpio_array, gpio_array_size);
if (rc < 0) {
pr_err("%s failed %d\n", __func__, __LINE__);
- goto ERROR4;
+ goto FREE_GPIO_CONF;
}
- rc = msm_sensor_get_dt_gpio_set_tbl(of_node, gconf,
+ rc = msm_camera_get_dt_gpio_set_tbl(of_node, gconf,
gpio_array, gpio_array_size);
if (rc < 0) {
pr_err("%s failed %d\n", __func__, __LINE__);
- goto ERROR5;
+ goto FREE_GPIO_REQ_TBL;
}
- rc = msm_sensor_init_gpio_pin_tbl(of_node, gconf,
+ rc = msm_camera_init_gpio_pin_tbl(of_node, gconf,
gpio_array, gpio_array_size);
if (rc < 0) {
pr_err("%s failed %d\n", __func__, __LINE__);
- goto ERROR6;
+ goto FREE_GPIO_SET_TBL;
}
}
- rc = msm_sensor_get_dt_actuator_data(of_node, sensordata);
+ rc = msm_sensor_get_dt_actuator_data(of_node,
+ &sensordata->actuator_info);
if (rc < 0) {
pr_err("%s failed %d\n", __func__, __LINE__);
- goto ERROR7;
+ goto FREE_GPIO_PIN_TBL;
}
sensordata->slave_info = kzalloc(sizeof(struct msm_camera_slave_info),
@@ -847,19 +270,23 @@
if (!sensordata->slave_info) {
pr_err("%s failed %d\n", __func__, __LINE__);
rc = -ENOMEM;
- goto ERROR8;
+ goto FREE_ACTUATOR_INFO;
}
rc = of_property_read_u32_array(of_node, "qcom,slave-id",
id_info, 3);
if (rc < 0) {
pr_err("%s failed %d\n", __func__, __LINE__);
- goto ERROR9;
+ goto FREE_SLAVE_INFO;
}
sensordata->slave_info->sensor_slave_addr = id_info[0];
sensordata->slave_info->sensor_id_reg_addr = id_info[1];
sensordata->slave_info->sensor_id = id_info[2];
+ CDBG("%s:%d slave addr %x sensor reg %x id %x\n", __func__, __LINE__,
+ sensordata->slave_info->sensor_slave_addr,
+ sensordata->slave_info->sensor_id_reg_addr,
+ sensordata->slave_info->sensor_id);
/*Optional property, don't return error if absent */
ret = of_property_read_string(of_node, "qcom,vdd-cx-name",
@@ -871,23 +298,28 @@
return rc;
-ERROR9:
+FREE_SLAVE_INFO:
kfree(s_ctrl->sensordata->slave_info);
-ERROR8:
+FREE_ACTUATOR_INFO:
kfree(s_ctrl->sensordata->actuator_info);
-ERROR7:
- kfree(s_ctrl->sensordata->gpio_conf->gpio_num_info);
-ERROR6:
- kfree(s_ctrl->sensordata->gpio_conf->cam_gpio_set_tbl);
-ERROR5:
- kfree(s_ctrl->sensordata->gpio_conf->cam_gpio_req_tbl);
-ERROR4:
- kfree(s_ctrl->sensordata->gpio_conf);
-ERROR3:
- kfree(s_ctrl->sensordata->cam_vreg);
-ERROR2:
+FREE_GPIO_PIN_TBL:
+ kfree(s_ctrl->sensordata->power_info.gpio_conf->gpio_num_info);
+FREE_GPIO_SET_TBL:
+ kfree(s_ctrl->sensordata->power_info.gpio_conf->cam_gpio_set_tbl);
+FREE_GPIO_REQ_TBL:
+ kfree(s_ctrl->sensordata->power_info.gpio_conf->cam_gpio_req_tbl);
+FREE_GPIO_CONF:
+ 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:
kfree(s_ctrl->sensordata->csi_lane_params);
-ERROR1:
+FREE_SENSOR_INFO:
+ kfree(s_ctrl->sensordata->sensor_info);
+FREE_SENSORDATA:
kfree(s_ctrl->sensordata);
kfree(gpio_array);
return rc;
@@ -930,20 +362,21 @@
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->gpio_conf->gpio_num_info);
- kfree(s_ctrl->sensordata->gpio_conf->cam_gpio_set_tbl);
- kfree(s_ctrl->sensordata->gpio_conf->cam_gpio_req_tbl);
- kfree(s_ctrl->sensordata->gpio_conf);
- kfree(s_ctrl->sensordata->cam_vreg);
+ kfree(s_ctrl->sensordata->power_info.gpio_conf->gpio_num_info);
+ kfree(s_ctrl->sensordata->power_info.gpio_conf->cam_gpio_set_tbl);
+ kfree(s_ctrl->sensordata->power_info.gpio_conf->cam_gpio_req_tbl);
+ kfree(s_ctrl->sensordata->power_info.gpio_conf);
+ kfree(s_ctrl->sensordata->power_info.cam_vreg);
+ 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->sensor_init_params);
+ kfree(s_ctrl->sensordata->power_info.clk_info);
kfree(s_ctrl->sensordata);
- kfree(s_ctrl->clk_info);
return 0;
}
@@ -961,278 +394,105 @@
[SENSOR_CAM_CLK] = {"cam_clk", 0},
};
-int32_t msm_sensor_power_up(struct msm_sensor_ctrl_t *s_ctrl)
+int msm_sensor_power_down(struct msm_sensor_ctrl_t *s_ctrl)
{
- int32_t rc = 0, index = 0;
- struct msm_sensor_power_setting_array *power_setting_array = NULL;
- struct msm_sensor_power_setting *power_setting = NULL;
- struct msm_camera_sensor_board_info *data = s_ctrl->sensordata;
- uint32_t retry = 0;
- s_ctrl->stop_setting_valid = 0;
+ struct msm_camera_power_ctrl_t *power_info;
+ enum msm_camera_device_type_t sensor_device_type;
+ struct msm_camera_i2c_client *sensor_i2c_client;
- CDBG("%s:%d\n", __func__, __LINE__);
- power_setting_array = &s_ctrl->power_setting_array;
-
- if (data->gpio_conf->cam_gpiomux_conf_tbl != NULL) {
- pr_err("%s:%d mux install\n", __func__, __LINE__);
- msm_gpiomux_install(
- (struct msm_gpiomux_config *)
- data->gpio_conf->cam_gpiomux_conf_tbl,
- data->gpio_conf->cam_gpiomux_conf_tbl_size);
+ if (!s_ctrl) {
+ pr_err("%s:%d failed: s_ctrl %p\n",
+ __func__, __LINE__, s_ctrl);
+ return -EINVAL;
}
- rc = msm_camera_request_gpio_table(
- data->gpio_conf->cam_gpio_req_tbl,
- data->gpio_conf->cam_gpio_req_tbl_size, 1);
- if (rc < 0) {
- pr_err("%s: request gpio failed\n", __func__);
+ power_info = &s_ctrl->sensordata->power_info;
+ sensor_device_type = s_ctrl->sensor_device_type;
+ sensor_i2c_client = s_ctrl->sensor_i2c_client;
+
+ if (!power_info || !sensor_i2c_client) {
+ pr_err("%s:%d failed: power_info %p sensor_i2c_client %p\n",
+ __func__, __LINE__, power_info, sensor_i2c_client);
+ return -EINVAL;
+ }
+ return msm_camera_power_down(power_info, sensor_device_type,
+ sensor_i2c_client);
+}
+
+int msm_sensor_power_up(struct msm_sensor_ctrl_t *s_ctrl)
+{
+ int rc;
+ struct msm_camera_power_ctrl_t *power_info;
+ struct msm_camera_i2c_client *sensor_i2c_client;
+ struct msm_camera_slave_info *slave_info;
+ const char *sensor_name;
+
+ if (!s_ctrl) {
+ pr_err("%s:%d failed: %p\n",
+ __func__, __LINE__, s_ctrl);
+ return -EINVAL;
+ }
+
+ power_info = &s_ctrl->sensordata->power_info;
+ sensor_i2c_client = s_ctrl->sensor_i2c_client;
+ slave_info = s_ctrl->sensordata->slave_info;
+ sensor_name = s_ctrl->sensordata->sensor_name;
+
+ if (!power_info || !sensor_i2c_client || !slave_info ||
+ !sensor_name) {
+ pr_err("%s:%d failed: %p %p %p %p\n",
+ __func__, __LINE__, power_info,
+ sensor_i2c_client, slave_info, sensor_name);
+ return -EINVAL;
+ }
+
+ rc = msm_camera_power_up(power_info, s_ctrl->sensor_device_type,
+ sensor_i2c_client);
+ if (rc < 0)
return rc;
- }
- for (index = 0; index < power_setting_array->size; index++) {
- CDBG("%s index %d\n", __func__, index);
- power_setting = &power_setting_array->power_setting[index];
- CDBG("%s type %d\n", __func__, power_setting->seq_type);
- switch (power_setting->seq_type) {
- case SENSOR_CLK:
- if (power_setting->seq_val >= s_ctrl->clk_info_size) {
- pr_err("%s clk index %d >= max %d\n", __func__,
- power_setting->seq_val,
- s_ctrl->clk_info_size);
- goto power_up_failed;
- }
- if (power_setting->config_val)
- s_ctrl->clk_info[power_setting->seq_val].
- clk_rate = power_setting->config_val;
+ rc = msm_sensor_check_id(s_ctrl);
+ if (rc < 0)
+ msm_camera_power_down(power_info, s_ctrl->sensor_device_type,
+ sensor_i2c_client);
- rc = msm_cam_clk_enable(s_ctrl->dev,
- &s_ctrl->clk_info[0],
- (struct clk **)&power_setting->data[0],
- s_ctrl->clk_info_size,
- 1);
- if (rc < 0) {
- pr_err("%s: clk enable failed\n",
- __func__);
- goto power_up_failed;
- }
- break;
- case SENSOR_GPIO:
- if (power_setting->seq_val >= SENSOR_GPIO_MAX ||
- !data->gpio_conf->gpio_num_info) {
- pr_err("%s gpio index %d >= max %d\n", __func__,
- power_setting->seq_val,
- SENSOR_GPIO_MAX);
- goto power_up_failed;
- }
- pr_debug("%s:%d gpio set val %d\n", __func__, __LINE__,
- data->gpio_conf->gpio_num_info->gpio_num
- [power_setting->seq_val]);
- gpio_set_value_cansleep(
- data->gpio_conf->gpio_num_info->gpio_num
- [power_setting->seq_val],
- power_setting->config_val);
- break;
- case SENSOR_VREG:
- if (power_setting->seq_val >= CAM_VREG_MAX) {
- pr_err("%s vreg index %d >= max %d\n", __func__,
- power_setting->seq_val,
- SENSOR_GPIO_MAX);
- goto power_up_failed;
- }
- msm_camera_config_single_vreg(s_ctrl->dev,
- &data->cam_vreg[power_setting->seq_val],
- (struct regulator **)&power_setting->data[0],
- 1);
- break;
- case SENSOR_I2C_MUX:
- if (data->i2c_conf && data->i2c_conf->use_i2c_mux)
- msm_sensor_enable_i2c_mux(data->i2c_conf);
- break;
- default:
- pr_err("%s error power seq type %d\n", __func__,
- power_setting->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 (s_ctrl->sensor_device_type == MSM_CAMERA_PLATFORM_DEVICE) {
- rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_util(
- s_ctrl->sensor_i2c_client, MSM_CCI_INIT);
- if (rc < 0) {
- pr_err("%s cci_init failed\n", __func__);
- goto power_up_failed;
- }
- }
-
- for (retry = 0; retry < 3; retry++)
- {
- if (s_ctrl->func_tbl->sensor_match_id)
- rc = s_ctrl->func_tbl->sensor_match_id(s_ctrl);
- else
- rc = msm_sensor_match_id(s_ctrl);
- if (rc < 0) {
- if (retry < 2) {
- continue;
- } else {
- pr_err("%s:%d match id failed rc %d\n", __func__, __LINE__, rc);
- goto power_up_failed;
- }
- } else {
- break;
- }
- }
-
- CDBG("%s exit\n", __func__);
- return 0;
-power_up_failed:
- pr_err("%s:%d failed\n", __func__, __LINE__);
- if (s_ctrl->sensor_device_type == MSM_CAMERA_PLATFORM_DEVICE) {
- s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_util(
- s_ctrl->sensor_i2c_client, MSM_CCI_RELEASE);
- }
-
- for (index--; index >= 0; index--) {
- CDBG("%s index %d\n", __func__, index);
- power_setting = &power_setting_array->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(s_ctrl->dev,
- &s_ctrl->clk_info[0],
- (struct clk **)&power_setting->data[0],
- s_ctrl->clk_info_size,
- 0);
- break;
- case SENSOR_GPIO:
- gpio_set_value_cansleep(
- data->gpio_conf->gpio_num_info->gpio_num
- [power_setting->seq_val], GPIOF_OUT_INIT_LOW);
- break;
- case SENSOR_VREG:
- msm_camera_config_single_vreg(s_ctrl->dev,
- &data->cam_vreg[power_setting->seq_val],
- (struct regulator **)&power_setting->data[0],
- 0);
- break;
- case SENSOR_I2C_MUX:
- if (data->i2c_conf && data->i2c_conf->use_i2c_mux)
- msm_sensor_disable_i2c_mux(data->i2c_conf);
- break;
- default:
- pr_err("%s error power seq type %d\n", __func__,
- power_setting->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);
- }
- }
- msm_camera_request_gpio_table(
- data->gpio_conf->cam_gpio_req_tbl,
- data->gpio_conf->cam_gpio_req_tbl_size, 0);
return rc;
}
-int32_t msm_sensor_power_down(struct msm_sensor_ctrl_t *s_ctrl)
+int msm_sensor_match_id(struct msm_sensor_ctrl_t *s_ctrl)
{
- int32_t index = 0;
- struct msm_sensor_power_setting_array *power_setting_array = NULL;
- struct msm_sensor_power_setting *power_setting = NULL;
- struct msm_camera_sensor_board_info *data = s_ctrl->sensordata;
- s_ctrl->stop_setting_valid = 0;
-
- CDBG("%s:%d\n", __func__, __LINE__);
- power_setting_array = &s_ctrl->power_setting_array;
-
- if (s_ctrl->sensor_device_type == MSM_CAMERA_PLATFORM_DEVICE) {
- s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_util(
- s_ctrl->sensor_i2c_client, MSM_CCI_RELEASE);
- }
-
- for (index = (power_setting_array->size - 1); index >= 0; index--) {
- CDBG("%s index %d\n", __func__, index);
- power_setting = &power_setting_array->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(s_ctrl->dev,
- &s_ctrl->clk_info[0],
- (struct clk **)&power_setting->data[0],
- s_ctrl->clk_info_size,
- 0);
- break;
- case SENSOR_GPIO:
- if (power_setting->seq_val >= SENSOR_GPIO_MAX ||
- !data->gpio_conf->gpio_num_info) {
- pr_err("%s gpio index %d >= max %d\n", __func__,
- power_setting->seq_val,
- SENSOR_GPIO_MAX);
- continue;
- }
- gpio_set_value_cansleep(
- data->gpio_conf->gpio_num_info->gpio_num
- [power_setting->seq_val], GPIOF_OUT_INIT_LOW);
- break;
- case SENSOR_VREG:
- if (power_setting->seq_val >= CAM_VREG_MAX) {
- pr_err("%s vreg index %d >= max %d\n", __func__,
- power_setting->seq_val,
- SENSOR_GPIO_MAX);
- continue;
- }
- msm_camera_config_single_vreg(s_ctrl->dev,
- &data->cam_vreg[power_setting->seq_val],
- (struct regulator **)&power_setting->data[0],
- 0);
- break;
- case SENSOR_I2C_MUX:
- if (data->i2c_conf && data->i2c_conf->use_i2c_mux)
- msm_sensor_disable_i2c_mux(data->i2c_conf);
- break;
- default:
- pr_err("%s error power seq type %d\n", __func__,
- power_setting->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);
- }
- }
- msm_camera_request_gpio_table(
- data->gpio_conf->cam_gpio_req_tbl,
- data->gpio_conf->cam_gpio_req_tbl_size, 0);
- CDBG("%s exit\n", __func__);
- return 0;
-}
-
-int32_t msm_sensor_match_id(struct msm_sensor_ctrl_t *s_ctrl)
-{
- int32_t rc = 0;
+ int rc = 0;
uint16_t chipid = 0;
- rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_read(
- s_ctrl->sensor_i2c_client,
- s_ctrl->sensordata->slave_info->sensor_id_reg_addr,
- &chipid, MSM_CAMERA_I2C_WORD_DATA);
+ struct msm_camera_i2c_client *sensor_i2c_client;
+ struct msm_camera_slave_info *slave_info;
+ const char *sensor_name;
+
+ if (!s_ctrl) {
+ pr_err("%s:%d failed: %p\n",
+ __func__, __LINE__, s_ctrl);
+ return -EINVAL;
+ }
+ sensor_i2c_client = s_ctrl->sensor_i2c_client;
+ slave_info = s_ctrl->sensordata->slave_info;
+ sensor_name = s_ctrl->sensordata->sensor_name;
+
+ if (!sensor_i2c_client || !slave_info || !sensor_name) {
+ pr_err("%s:%d failed: %p %p %p\n",
+ __func__, __LINE__, sensor_i2c_client, slave_info,
+ sensor_name);
+ return -EINVAL;
+ }
+
+ rc = sensor_i2c_client->i2c_func_tbl->i2c_read(
+ sensor_i2c_client, slave_info->sensor_id_reg_addr,
+ &chipid, MSM_CAMERA_I2C_WORD_DATA);
if (rc < 0) {
- pr_err("%s: %s: read id failed\n", __func__,
- s_ctrl->sensordata->sensor_name);
+ pr_err("%s: %s: read id failed\n", __func__, sensor_name);
return rc;
}
CDBG("%s: read id: %x expected id %x:\n", __func__, chipid,
- s_ctrl->sensordata->slave_info->sensor_id);
- if (chipid != s_ctrl->sensordata->slave_info->sensor_id) {
+ slave_info->sensor_id);
+ if (chipid != slave_info->sensor_id) {
pr_err("msm_sensor_match_id chip id doesnot match\n");
return -ENODEV;
}
@@ -1291,12 +551,11 @@
}
}
-int32_t msm_sensor_config(struct msm_sensor_ctrl_t *s_ctrl,
- void __user *argp)
+int msm_sensor_config(struct msm_sensor_ctrl_t *s_ctrl, void __user *argp)
{
struct sensorb_cfg_data *cdata = (struct sensorb_cfg_data *)argp;
long rc = 0;
- int32_t i = 0;
+ int i = 0;
mutex_lock(s_ctrl->msm_sensor_mutex);
CDBG("%s:%d %s cfgtype = %d\n", __func__, __LINE__,
s_ctrl->sensordata->sensor_name, cdata->cfgtype);
@@ -1310,6 +569,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__,
@@ -1317,11 +580,18 @@
for (i = 0; i < SUB_MODULE_MAX; i++)
CDBG("%s:%d subdev_id[%d] %d\n", __func__, __LINE__, i,
cdata->cfg.sensor_info.subdev_id[i]);
+ CDBG("%s:%d mount angle valid %d value %d\n", __func__,
+ __LINE__, cdata->cfg.sensor_info.is_mount_angle_valid,
+ cdata->cfg.sensor_info.sensor_mount_angle);
break;
case CFG_GET_SENSOR_INIT_PARAMS:
- cdata->cfg.sensor_init_params =
- *s_ctrl->sensordata->sensor_init_params;
+ cdata->cfg.sensor_init_params.modes_supported =
+ s_ctrl->sensordata->sensor_info->modes_supported;
+ cdata->cfg.sensor_init_params.position =
+ s_ctrl->sensordata->sensor_info->position;
+ cdata->cfg.sensor_init_params.sensor_mount_angle =
+ s_ctrl->sensordata->sensor_info->sensor_mount_angle;
CDBG("%s:%d init params mode %d pos %d mount %d\n", __func__,
__LINE__,
cdata->cfg.sensor_init_params.modes_supported,
@@ -1330,11 +600,12 @@
break;
case CFG_SET_SLAVE_INFO: {
struct msm_camera_sensor_slave_info sensor_slave_info;
- struct msm_sensor_power_setting_array *power_setting_array;
- int slave_index = 0;
+ struct msm_camera_power_ctrl_t *p_ctrl;
+ uint16_t size;
+ int s_index = 0;
if (copy_from_user(&sensor_slave_info,
- (void *)cdata->cfg.setting,
- sizeof(struct msm_camera_sensor_slave_info))) {
+ (void *)cdata->cfg.setting,
+ sizeof(sensor_slave_info))) {
pr_err("%s:%d failed\n", __func__, __LINE__);
rc = -EFAULT;
break;
@@ -1348,37 +619,34 @@
/* Update sensor address type */
s_ctrl->sensor_i2c_client->addr_type =
sensor_slave_info.addr_type;
+ p_ctrl = &s_ctrl->sensordata->power_info;
- /* Update power up / down sequence */
- s_ctrl->power_setting_array =
- sensor_slave_info.power_setting_array;
- power_setting_array = &s_ctrl->power_setting_array;
-
- if (!power_setting_array->size) {
- pr_err("%s:%d failed\n", __func__, __LINE__);
- rc = -EFAULT;
- break;
+ /* 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;
+ 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_setting);
+ p_ctrl->power_setting = tmp;
}
+ p_ctrl->power_setting_size = size;
- power_setting_array->power_setting = kzalloc(
- power_setting_array->size *
- sizeof(struct msm_sensor_power_setting), GFP_KERNEL);
- if (!power_setting_array->power_setting) {
- pr_err("%s:%d failed\n", __func__, __LINE__);
- rc = -ENOMEM;
- break;
- }
- if (copy_from_user(power_setting_array->power_setting,
- (void *)
+
+ rc = copy_from_user(p_ctrl->power_setting, (void *)
sensor_slave_info.power_setting_array.power_setting,
- power_setting_array->size *
- sizeof(struct msm_sensor_power_setting))) {
+ size * sizeof(struct msm_sensor_power_setting));
+ if (rc) {
pr_err("%s:%d failed\n", __func__, __LINE__);
- kfree(power_setting_array->power_setting);
+ kfree(sensor_slave_info.power_setting_array.
+ power_setting);
rc = -EFAULT;
break;
}
- s_ctrl->free_power_setting = true;
CDBG("%s sensor id %x\n", __func__,
sensor_slave_info.slave_addr);
CDBG("%s sensor addr type %d\n", __func__,
@@ -1387,19 +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 <
- power_setting_array->size; slave_index++) {
- CDBG("%s i %d power setting %d %d %ld %d\n", __func__,
- slave_index,
- power_setting_array->power_setting[slave_index].
- seq_type,
- power_setting_array->power_setting[slave_index].
- seq_val,
- power_setting_array->power_setting[slave_index].
- config_val,
- power_setting_array->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: {
@@ -1663,8 +974,7 @@
if (s_ctrl->sensordata->misc_regulator)
msm_sensor_misc_regulator(s_ctrl, 0);
- rc = s_ctrl->func_tbl->sensor_power_down(
- s_ctrl);
+ rc = s_ctrl->func_tbl->sensor_power_down(s_ctrl);
if (rc < 0) {
pr_err("%s:%d failed rc %ld\n", __func__,
__LINE__, rc);
@@ -1689,7 +999,7 @@
rc = -EFAULT;
break;
}
- s_ctrl->stop_setting_valid = 1;
+
reg_setting = stop_setting->reg_setting;
if (!stop_setting->size) {
@@ -1727,7 +1037,20 @@
return rc;
}
-static int32_t msm_sensor_power(struct v4l2_subdev *sd, int on)
+int msm_sensor_check_id(struct msm_sensor_ctrl_t *s_ctrl)
+{
+ int rc;
+
+ if (s_ctrl->func_tbl->sensor_match_id)
+ rc = s_ctrl->func_tbl->sensor_match_id(s_ctrl);
+ else
+ rc = msm_sensor_match_id(s_ctrl);
+ if (rc < 0)
+ pr_err("%s:%d match id failed rc %d\n", __func__, __LINE__, rc);
+ return rc;
+}
+
+static int msm_sensor_power(struct v4l2_subdev *sd, int on)
{
int rc = 0;
struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(sd);
@@ -1736,15 +1059,11 @@
s_ctrl->func_tbl->sensor_power_down(s_ctrl);
s_ctrl->sensor_state = MSM_SENSOR_POWER_DOWN;
}
- if (s_ctrl->free_power_setting == true) {
- kfree(s_ctrl->power_setting_array.power_setting);
- s_ctrl->free_power_setting = false;
- }
mutex_unlock(s_ctrl->msm_sensor_mutex);
return rc;
}
-static int32_t msm_sensor_v4l2_enum_fmt(struct v4l2_subdev *sd,
+static int msm_sensor_v4l2_enum_fmt(struct v4l2_subdev *sd,
unsigned int index, enum v4l2_mbus_pixelcode *code)
{
struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(sd);
@@ -1802,7 +1121,7 @@
int32_t msm_sensor_platform_probe(struct platform_device *pdev, void *data)
{
- int32_t rc = 0;
+ int rc = 0;
struct msm_sensor_ctrl_t *s_ctrl =
(struct msm_sensor_ctrl_t *)data;
struct msm_camera_cci_client *cci_client = NULL;
@@ -1810,7 +1129,6 @@
unsigned long mount_pos;
s_ctrl->pdev = pdev;
- s_ctrl->dev = &pdev->dev;
CDBG("%s called data %p\n", __func__, data);
CDBG("%s pdev name %s\n", __func__, pdev->id_entry->name);
if (pdev->dev.of_node) {
@@ -1820,6 +1138,7 @@
return rc;
}
}
+ s_ctrl->sensordata->power_info.dev = &pdev->dev;
s_ctrl->sensor_device_type = MSM_CAMERA_PLATFORM_DEVICE;
s_ctrl->sensor_i2c_client->cci_client = kzalloc(sizeof(
struct msm_camera_cci_client), GFP_KERNEL);
@@ -1842,20 +1161,22 @@
&msm_sensor_cci_func_tbl;
if (!s_ctrl->sensor_v4l2_subdev_ops)
s_ctrl->sensor_v4l2_subdev_ops = &msm_sensor_subdev_ops;
- s_ctrl->clk_info = kzalloc(sizeof(cam_8974_clk_info),
- GFP_KERNEL);
- if (!s_ctrl->clk_info) {
+ s_ctrl->sensordata->power_info.clk_info =
+ kzalloc(sizeof(cam_8974_clk_info), GFP_KERNEL);
+ if (!s_ctrl->sensordata->power_info.clk_info) {
pr_err("%s:%d failed nomem\n", __func__, __LINE__);
kfree(cci_client);
return -ENOMEM;
}
- memcpy(s_ctrl->clk_info, cam_8974_clk_info, sizeof(cam_8974_clk_info));
- s_ctrl->clk_info_size = ARRAY_SIZE(cam_8974_clk_info);
+ memcpy(s_ctrl->sensordata->power_info.clk_info, cam_8974_clk_info,
+ sizeof(cam_8974_clk_info));
+ s_ctrl->sensordata->power_info.clk_info_size =
+ ARRAY_SIZE(cam_8974_clk_info);
rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
if (rc < 0) {
pr_err("%s %s power up failed\n", __func__,
s_ctrl->sensordata->sensor_name);
- kfree(s_ctrl->clk_info);
+ kfree(s_ctrl->sensordata->power_info.clk_info);
kfree(cci_client);
return rc;
}
@@ -1875,9 +1196,9 @@
s_ctrl->msm_sd.sd.entity.name =
s_ctrl->msm_sd.sd.name;
- mount_pos = s_ctrl->sensordata->sensor_init_params->position << 16;
- mount_pos = mount_pos | ((s_ctrl->sensordata->sensor_init_params->
- sensor_mount_angle / 90) << 8);
+ mount_pos = s_ctrl->sensordata->sensor_info->position << 16;
+ mount_pos = mount_pos |
+ ((s_ctrl->sensordata->sensor_info->sensor_mount_angle / 90) << 8);
s_ctrl->msm_sd.sd.entity.flags = mount_pos | MEDIA_ENT_FL_DEFAULT;
rc = camera_init_v4l2(&s_ctrl->pdev->dev, &session_id);
@@ -1892,7 +1213,7 @@
return rc;
}
-int32_t msm_sensor_i2c_probe(struct i2c_client *client,
+int msm_sensor_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id, struct msm_sensor_ctrl_t *s_ctrl)
{
int rc = 0;
@@ -1933,7 +1254,7 @@
if (s_ctrl->sensor_i2c_client != NULL) {
s_ctrl->sensor_i2c_client->client = client;
- s_ctrl->dev = &client->dev;
+ s_ctrl->sensordata->power_info.dev = &client->dev;
if (s_ctrl->sensordata->slave_info->sensor_slave_addr)
s_ctrl->sensor_i2c_client->client->addr =
s_ctrl->sensordata->slave_info->
@@ -1954,31 +1275,33 @@
s_ctrl->sensor_v4l2_subdev_ops = &msm_sensor_subdev_ops;
if (!client->dev.of_node) {
- s_ctrl->clk_info = kzalloc(sizeof(cam_8960_clk_info),
- GFP_KERNEL);
- if (!s_ctrl->clk_info) {
+ s_ctrl->sensordata->power_info.clk_info =
+ kzalloc(sizeof(cam_8960_clk_info), GFP_KERNEL);
+ if (!s_ctrl->sensordata->power_info.clk_info) {
pr_err("%s:%d failed nomem\n", __func__, __LINE__);
return -ENOMEM;
}
- memcpy(s_ctrl->clk_info, cam_8960_clk_info,
- sizeof(cam_8960_clk_info));
- s_ctrl->clk_info_size = ARRAY_SIZE(cam_8960_clk_info);
+ memcpy(s_ctrl->sensordata->power_info.clk_info,
+ cam_8960_clk_info, sizeof(cam_8960_clk_info));
+ s_ctrl->sensordata->power_info.clk_info_size =
+ ARRAY_SIZE(cam_8960_clk_info);
} else {
- s_ctrl->clk_info = kzalloc(sizeof(cam_8610_clk_info),
- GFP_KERNEL);
- if (!s_ctrl->clk_info) {
+ s_ctrl->sensordata->power_info.clk_info =
+ kzalloc(sizeof(cam_8610_clk_info), GFP_KERNEL);
+ if (!s_ctrl->sensordata->power_info.clk_info) {
pr_err("%s:%d failed nomem\n", __func__, __LINE__);
return -ENOMEM;
}
- memcpy(s_ctrl->clk_info, cam_8610_clk_info,
- sizeof(cam_8610_clk_info));
- s_ctrl->clk_info_size = ARRAY_SIZE(cam_8610_clk_info);
+ memcpy(s_ctrl->sensordata->power_info.clk_info,
+ cam_8610_clk_info, sizeof(cam_8610_clk_info));
+ s_ctrl->sensordata->power_info.clk_info_size =
+ ARRAY_SIZE(cam_8610_clk_info);
}
rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
if (rc < 0) {
pr_err("%s %s power up failed\n", __func__, client->name);
- kfree(s_ctrl->clk_info);
+ kfree(s_ctrl->sensordata->power_info.clk_info);
return rc;
}
@@ -1995,9 +1318,9 @@
s_ctrl->msm_sd.sd.entity.name =
s_ctrl->msm_sd.sd.name;
- mount_pos = s_ctrl->sensordata->sensor_init_params->position << 16;
- mount_pos = mount_pos | ((s_ctrl->sensordata->sensor_init_params->
- sensor_mount_angle / 90) << 8);
+ mount_pos = s_ctrl->sensordata->sensor_info->position << 16;
+ mount_pos = mount_pos |
+ ((s_ctrl->sensordata->sensor_info->sensor_mount_angle / 90) << 8);
s_ctrl->msm_sd.sd.entity.flags = mount_pos | MEDIA_ENT_FL_DEFAULT;
rc = camera_init_v4l2(&s_ctrl->sensor_i2c_client->client->dev,
@@ -2011,3 +1334,77 @@
s_ctrl->func_tbl->sensor_power_down(s_ctrl);
return rc;
}
+
+int32_t msm_sensor_init_default_params(struct msm_sensor_ctrl_t *s_ctrl)
+{
+ int32_t rc = -ENOMEM;
+ struct msm_camera_cci_client *cci_client = NULL;
+ struct msm_cam_clk_info *clk_info = NULL;
+
+ /* Validate input parameters */
+ if (!s_ctrl) {
+ pr_err("%s:%d failed: invalid params s_ctrl %p\n", __func__,
+ __LINE__, s_ctrl);
+ return -EINVAL;
+ }
+
+ 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);
+ return -EINVAL;
+ }
+
+ /* Initialize cci_client */
+ s_ctrl->sensor_i2c_client->cci_client = kzalloc(sizeof(
+ struct msm_camera_cci_client), GFP_KERNEL);
+ if (!s_ctrl->sensor_i2c_client->cci_client) {
+ pr_err("%s:%d failed: no memory cci_client %p\n", __func__,
+ __LINE__, s_ctrl->sensor_i2c_client->cci_client);
+ return -ENOMEM;
+ }
+
+ 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();
+
+ /* 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 v4l2 subdev ops table */
+ if (!s_ctrl->sensor_v4l2_subdev_ops)
+ s_ctrl->sensor_v4l2_subdev_ops = &msm_sensor_subdev_ops;
+
+ /* Initialize clock info */
+ clk_info = kzalloc(sizeof(cam_8974_clk_info), GFP_KERNEL);
+ if (!clk_info) {
+ pr_err("%s:%d failed no memory clk_info %p\n", __func__,
+ __LINE__, clk_info);
+ rc = -ENOMEM;
+ goto FREE_CCI_CLIENT;
+ }
+ memcpy(clk_info, cam_8974_clk_info, sizeof(cam_8974_clk_info));
+ s_ctrl->sensordata->power_info.clk_info = clk_info;
+ s_ctrl->sensordata->power_info.clk_info_size =
+ ARRAY_SIZE(cam_8974_clk_info);
+
+ return 0;
+
+FREE_CCI_CLIENT:
+ kfree(cci_client);
+ return rc;
+}
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 a53d448..0f77567 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.h
+++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.h
@@ -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
@@ -30,6 +30,7 @@
#include <media/msm_cam_sensor.h>
#include <media/v4l2-subdev.h>
#include "msm_camera_i2c.h"
+#include "msm_camera_dt_util.h"
#include "msm_sd.h"
#define DEFINE_MSM_MUTEX(mutexname) \
@@ -44,53 +45,57 @@
struct msm_sensor_fn_t {
int (*sensor_config) (struct msm_sensor_ctrl_t *, void __user *);
- int (*sensor_power_down)
- (struct msm_sensor_ctrl_t *);
+ int (*sensor_power_down) (struct msm_sensor_ctrl_t *);
int (*sensor_power_up) (struct msm_sensor_ctrl_t *);
- int32_t (*sensor_match_id)(struct msm_sensor_ctrl_t *s_ctrl);
+ int (*sensor_match_id) (struct msm_sensor_ctrl_t *);
};
+
struct msm_sensor_ctrl_t {
struct platform_device *pdev;
- enum msm_camera_device_type_t sensor_device_type;
- enum cci_i2c_master_t cci_i2c_master;
- struct msm_camera_sensor_board_info *sensordata;
- struct msm_sensor_power_setting_array power_setting_array;
struct mutex *msm_sensor_mutex;
- struct msm_camera_i2c_client *sensor_i2c_client;
- struct device *dev;
-
+ enum msm_camera_device_type_t sensor_device_type;
+ struct msm_camera_sensor_board_info *sensordata;
+ struct msm_sensor_power_setting_array power_setting_array;
+ struct msm_sensor_packed_cfg_t *cfg_override;
struct msm_sd_subdev msm_sd;
+ enum cci_i2c_master_t cci_i2c_master;
+
+ struct msm_camera_i2c_client *sensor_i2c_client;
struct v4l2_subdev_info *sensor_v4l2_subdev_info;
uint8_t sensor_v4l2_subdev_info_size;
struct v4l2_subdev_ops *sensor_v4l2_subdev_ops;
struct msm_sensor_fn_t *func_tbl;
struct msm_camera_i2c_reg_setting stop_setting;
- bool stop_setting_valid;
- bool free_power_setting;
- struct msm_cam_clk_info *clk_info;
- uint16_t clk_info_size;
void *misc_regulator;
enum msm_sensor_state_t sensor_state;
+ uint8_t is_probe_succeed;
+ uint32_t id;
+ struct device_node *of_node;
};
-int32_t msm_sensor_config(struct msm_sensor_ctrl_t *s_ctrl,
- void __user *argp);
+int msm_sensor_config(struct msm_sensor_ctrl_t *s_ctrl, void __user *argp);
-int32_t msm_sensor_power_up(struct msm_sensor_ctrl_t *s_ctrl);
+int msm_sensor_power_up(struct msm_sensor_ctrl_t *s_ctrl);
-int32_t msm_sensor_power_down(struct msm_sensor_ctrl_t *s_ctrl);
+int msm_sensor_power_down(struct msm_sensor_ctrl_t *s_ctrl);
-int32_t msm_sensor_match_id(struct msm_sensor_ctrl_t *s_ctrl);
+int msm_sensor_check_id(struct msm_sensor_ctrl_t *s_ctrl);
+
+int msm_sensor_match_id(struct msm_sensor_ctrl_t *s_ctrl);
int32_t msm_sensor_platform_probe(struct platform_device *pdev,
void *data);
-int32_t msm_sensor_i2c_probe(struct i2c_client *client,
+int msm_sensor_update_cfg(struct msm_sensor_ctrl_t *s_ctrl);
+
+int msm_sensor_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id, struct msm_sensor_ctrl_t *s_ctrl);
-int32_t msm_sensor_free_sensor_data(struct msm_sensor_ctrl_t *s_ctrl);
+int msm_sensor_free_sensor_data(struct msm_sensor_ctrl_t *s_ctrl);
+
+int32_t msm_sensor_init_default_params(struct msm_sensor_ctrl_t *s_ctrl);
int32_t msm_sensor_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_driver.c b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c
new file mode 100644
index 0000000..f5be347
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c
@@ -0,0 +1,941 @@
+/* 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#define SENSOR_DRIVER_I2C "camera"
+/* Header file declaration */
+#include "msm_sensor.h"
+#include "msm_sd.h"
+#include "camera.h"
+#include "msm_cci.h"
+#include "msm_camera_dt_util.h"
+
+/* Logging macro */
+/*#define MSM_SENSOR_DRIVER_DEBUG*/
+#undef CDBG
+#ifdef MSM_SENSOR_DRIVER_DEBUG
+#define CDBG(fmt, args...) pr_err(fmt, ##args)
+#else
+#define CDBG(fmt, args...) pr_debug(fmt, ##args)
+#endif
+
+/* Static declaration */
+static struct msm_sensor_ctrl_t *g_sctrl[MAX_CAMERAS];
+
+static int msm_sensor_platform_remove(struct platform_device *pdev)
+{
+ struct msm_sensor_ctrl_t *s_ctrl;
+
+ pr_err("%s: sensor FREE\n", __func__);
+
+ s_ctrl = g_sctrl[pdev->id];
+ if (!s_ctrl) {
+ pr_err("%s: sensor device is NULL\n", __func__);
+ return 0;
+ }
+
+ msm_sensor_free_sensor_data(s_ctrl);
+ kfree(s_ctrl->msm_sensor_mutex);
+ kfree(s_ctrl->sensor_i2c_client);
+ kfree(s_ctrl);
+ g_sctrl[pdev->id] = NULL;
+
+ return 0;
+}
+
+
+static const struct of_device_id msm_sensor_driver_dt_match[] = {
+ {.compatible = "qcom,camera"},
+ {}
+};
+
+MODULE_DEVICE_TABLE(of, msm_sensor_driver_dt_match);
+
+static struct platform_driver msm_sensor_platform_driver = {
+ .driver = {
+ .name = "qcom,camera",
+ .owner = THIS_MODULE,
+ .of_match_table = msm_sensor_driver_dt_match,
+ },
+ .remove = msm_sensor_platform_remove,
+};
+
+static struct v4l2_subdev_info msm_sensor_driver_subdev_info[] = {
+ {
+ .code = V4L2_MBUS_FMT_SBGGR10_1X10,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .fmt = 1,
+ .order = 0,
+ },
+};
+
+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, 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) {
+ pr_err("failed: slave_info %p", setting);
+ return -EINVAL;
+ }
+
+ /* Allocate memory for slave info */
+ slave_info = kzalloc(sizeof(*slave_info), GFP_KERNEL);
+ if (!slave_info) {
+ pr_err("failed: no memory slave_info %p", slave_info);
+ return -ENOMEM;
+ }
+
+ if (copy_from_user(slave_info, (void *)setting, sizeof(*slave_info))) {
+ pr_err("failed: copy_from_user");
+ rc = -EFAULT;
+ goto FREE_SLAVE_INFO;
+ }
+
+ /* Print slave info */
+ CDBG("camera id %d", slave_info->camera_id);
+ CDBG("slave_addr %x", slave_info->slave_addr);
+ CDBG("addr_type %d", slave_info->addr_type);
+ 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 %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) {
+ pr_err("failed: invalid camera id %d max %d",
+ slave_info->camera_id, MAX_CAMERAS);
+ rc = -EINVAL;
+ goto FREE_POWER_SETTING;
+ }
+
+ /* Extract s_ctrl from camera id */
+ s_ctrl = g_sctrl[slave_info->camera_id];
+ if (!s_ctrl) {
+ pr_err("failed: s_ctrl %p for camera_id %d", s_ctrl,
+ slave_info->camera_id);
+ rc = -EINVAL;
+ goto FREE_POWER_SETTING;
+ }
+
+ CDBG("s_ctrl[%d] %p", slave_info->camera_id, s_ctrl);
+
+ if (s_ctrl->is_probe_succeed == 1) {
+ /*
+ * Different sensor on this camera slot has been connected
+ * and probe already succeeded for that sensor. Ignore this
+ * probe
+ */
+ pr_err("slot %d has some other sensor", slave_info->camera_id);
+ kfree(slave_info);
+ return 0;
+ }
+
+ size = slave_info->power_setting_array.size;
+ /* 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);
+ rc = -ENOMEM;
+ goto FREE_SLAVE_INFO;
+ }
+
+ if (copy_from_user(power_setting,
+ (void *)slave_info->power_setting_array.power_setting,
+ sizeof(*power_setting) * size)) {
+ pr_err("failed: copy_from_user");
+ rc = -EFAULT;
+ goto FREE_POWER_SETTING;
+ }
+
+ /* Print power setting */
+ for (i = 0; i < size; i++) {
+ 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_DOWN_SETTING;
+
+ }
+
+ /* Fill power up setting and power up setting size */
+ 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;
+
+ /* Fill sensor slave info */
+ camera_info->sensor_slave_addr = slave_info->slave_addr;
+ camera_info->sensor_id_reg_addr =
+ slave_info->sensor_id_info.sensor_id_reg_addr;
+ camera_info->sensor_id = slave_info->sensor_id_info.sensor_id;
+
+ /* Fill CCI master, slave address and CCI default params */
+ if (!s_ctrl->sensor_i2c_client) {
+ pr_err("failed: sensor_i2c_client %p",
+ s_ctrl->sensor_i2c_client);
+ rc = -EINVAL;
+ 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_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 for powerup settings */
+ rc = msm_camera_fill_vreg_params(
+ power_info->cam_vreg,
+ power_info->num_vreg,
+ power_info->power_setting,
+ power_info->power_setting_size);
+ if (rc < 0) {
+ pr_err("failed: msm_camera_get_dt_power_setting_data rc %d",
+ rc);
+ goto FREE_CAMERA_INFO;
+ }
+
+ /* 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_CAMERA_INFO;
+ }
+
+ pr_err("%s probe succeeded", slave_info->sensor_name);
+
+ /*
+ Set probe succeeded flag to 1 so that no other camera shall
+ * probed on this slot
+ */
+ s_ctrl->is_probe_succeed = 1;
+
+ /*
+ * Create /dev/videoX node, comment for now until dummy /dev/videoX
+ * node is created and used by HAL
+ */
+
+ 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:
+ kfree(slave_info);
+ return rc;
+}
+
+static int32_t msm_sensor_driver_get_gpio_data(
+ struct msm_camera_sensor_board_info *sensordata,
+ struct device_node *of_node)
+{
+ int32_t rc = 0, i = 0;
+ struct msm_camera_gpio_conf *gconf = NULL;
+ uint16_t *gpio_array = NULL;
+ uint16_t gpio_array_size = 0;
+
+ /* Validate input paramters */
+ if (!sensordata || !of_node) {
+ pr_err("failed: invalid params sensordata %p of_node %p",
+ sensordata, of_node);
+ return -EINVAL;
+ }
+
+ sensordata->power_info.gpio_conf = kzalloc(
+ sizeof(struct msm_camera_gpio_conf), GFP_KERNEL);
+ if (!sensordata->power_info.gpio_conf) {
+ pr_err("failed");
+ return -ENOMEM;
+ }
+ gconf = sensordata->power_info.gpio_conf;
+
+ gpio_array_size = of_gpio_count(of_node);
+ CDBG("gpio count %d", gpio_array_size);
+ if (!gpio_array_size)
+ return 0;
+
+ gpio_array = kzalloc(sizeof(uint16_t) * gpio_array_size, GFP_KERNEL);
+ if (!gpio_array) {
+ pr_err("failed");
+ goto FREE_GPIO_CONF;
+ }
+ for (i = 0; i < gpio_array_size; i++) {
+ gpio_array[i] = of_get_gpio(of_node, i);
+ CDBG("gpio_array[%d] = %d", i, gpio_array[i]);
+ }
+
+ rc = msm_camera_get_dt_gpio_req_tbl(of_node, gconf, gpio_array,
+ gpio_array_size);
+ if (rc < 0) {
+ pr_err("failed");
+ goto FREE_GPIO_CONF;
+ }
+
+ rc = msm_camera_init_gpio_pin_tbl(of_node, gconf, gpio_array,
+ gpio_array_size);
+ if (rc < 0) {
+ pr_err("failed");
+ goto FREE_GPIO_REQ_TBL;
+ }
+
+ kfree(gpio_array);
+ return rc;
+
+FREE_GPIO_REQ_TBL:
+ kfree(sensordata->power_info.gpio_conf->cam_gpio_req_tbl);
+FREE_GPIO_CONF:
+ kfree(sensordata->power_info.gpio_conf);
+ kfree(gpio_array);
+ return rc;
+}
+
+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 = s_ctrl->of_node;
+ uint32_t cell_id;
+
+ s_ctrl->sensordata = kzalloc(sizeof(*sensordata), GFP_KERNEL);
+ if (!s_ctrl->sensordata) {
+ pr_err("failed: no memory");
+ return -ENOMEM;
+ }
+
+ sensordata = s_ctrl->sensordata;
+
+ /*
+ * 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", &cell_id);
+ if (rc < 0) {
+ pr_err("failed: cell-index rc %d", rc);
+ goto FREE_SENSOR_DATA;
+ }
+ s_ctrl->id = cell_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 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;
+ }
+
+ /* Read subdev info */
+ rc = msm_sensor_get_sub_module_index(of_node, &sensordata->sensor_info);
+ if (rc < 0) {
+ pr_err("failed");
+ goto FREE_SENSOR_DATA;
+ }
+
+ /* Read vreg information */
+ rc = msm_camera_get_dt_vreg_data(of_node,
+ &sensordata->power_info.cam_vreg,
+ &sensordata->power_info.num_vreg);
+ if (rc < 0) {
+ pr_err("failed: msm_camera_get_dt_vreg_data rc %d", rc);
+ goto FREE_SUB_MODULE_DATA;
+ }
+
+ /* Read gpio information */
+ rc = msm_sensor_driver_get_gpio_data(sensordata, of_node);
+ if (rc < 0) {
+ pr_err("failed: msm_sensor_driver_get_gpio_data rc %d", rc);
+ goto FREE_VREG_DATA;
+ }
+
+ /* Get CCI master */
+ rc = of_property_read_u32(of_node, "qcom,cci-master",
+ &s_ctrl->cci_i2c_master);
+ CDBG("qcom,cci-master %d, rc %d", s_ctrl->cci_i2c_master, rc);
+ if (rc < 0) {
+ /* Set default master 0 */
+ s_ctrl->cci_i2c_master = MASTER_0;
+ rc = 0;
+ }
+
+ /* Get mount angle */
+
+ rc = of_property_read_u32(of_node, "qcom,mount-angle",
+ &sensordata->sensor_info->sensor_mount_angle);
+ CDBG("%s qcom,mount-angle %d, rc %d\n", __func__,
+ sensordata->sensor_info->sensor_mount_angle, rc);
+ if (rc < 0) {
+ /* Invalidate mount angle flag */
+ sensordata->sensor_info->is_mount_angle_valid = 0;
+ sensordata->sensor_info->sensor_mount_angle = 0;
+ rc = 0;
+ } else {
+ sensordata->sensor_info->is_mount_angle_valid = 1;
+ }
+
+ /* Get vdd-cx regulator */
+ /*Optional property, don't return error if absent */
+ of_property_read_string(of_node, "qcom,vdd-cx-name",
+ &sensordata->misc_regulator);
+ CDBG("qcom,misc_regulator %s", sensordata->misc_regulator);
+
+ return rc;
+
+FREE_VREG_DATA:
+ kfree(sensordata->power_info.cam_vreg);
+FREE_SUB_MODULE_DATA:
+ kfree(sensordata->sensor_info);
+FREE_SENSOR_DATA:
+ kfree(sensordata);
+ return rc;
+}
+
+static int32_t msm_sensor_driver_parse(struct msm_sensor_ctrl_t *s_ctrl)
+{
+ int32_t rc = 0;
+
+ CDBG("Enter");
+ /* Validate input parameters */
+
+
+ /* Allocate memory for sensor_i2c_client */
+ s_ctrl->sensor_i2c_client = kzalloc(sizeof(*s_ctrl->sensor_i2c_client),
+ GFP_KERNEL);
+ if (!s_ctrl->sensor_i2c_client) {
+ pr_err("failed: no memory sensor_i2c_client %p",
+ s_ctrl->sensor_i2c_client);
+ return -ENOMEM;
+ }
+
+ /* Allocate memory for mutex */
+ s_ctrl->msm_sensor_mutex = kzalloc(sizeof(*s_ctrl->msm_sensor_mutex),
+ GFP_KERNEL);
+ if (!s_ctrl->msm_sensor_mutex) {
+ pr_err("failed: no memory msm_sensor_mutex %p",
+ s_ctrl->msm_sensor_mutex);
+ goto FREE_SENSOR_I2C_CLIENT;
+ }
+
+ /* Parse dt information and store in sensor control structure */
+ rc = msm_sensor_driver_get_dt_data(s_ctrl);
+ if (rc < 0) {
+ pr_err("failed: rc %d", rc);
+ goto FREE_MUTEX;
+ }
+
+ /* Initialize mutex */
+ mutex_init(s_ctrl->msm_sensor_mutex);
+
+ /* Initilize v4l2 subdev info */
+ s_ctrl->sensor_v4l2_subdev_info = msm_sensor_driver_subdev_info;
+ s_ctrl->sensor_v4l2_subdev_info_size =
+ ARRAY_SIZE(msm_sensor_driver_subdev_info);
+
+ /* Initialize default parameters */
+ rc = msm_sensor_init_default_params(s_ctrl);
+ if (rc < 0) {
+ pr_err("failed: msm_sensor_init_default_params rc %d", rc);
+ goto FREE_DT_DATA;
+ }
+
+ /* Store sensor control structure in static database */
+ g_sctrl[s_ctrl->id] = s_ctrl;
+ pr_err("g_sctrl[%d] %p", s_ctrl->id, g_sctrl[s_ctrl->id]);
+
+ return rc;
+
+FREE_DT_DATA:
+ kfree(s_ctrl->sensordata->power_info.gpio_conf->gpio_num_info);
+ kfree(s_ctrl->sensordata->power_info.gpio_conf->cam_gpio_req_tbl);
+ kfree(s_ctrl->sensordata->power_info.gpio_conf);
+ kfree(s_ctrl->sensordata->power_info.cam_vreg);
+ kfree(s_ctrl->sensordata);
+FREE_MUTEX:
+ kfree(s_ctrl->msm_sensor_mutex);
+FREE_SENSOR_I2C_CLIENT:
+ kfree(s_ctrl->sensor_i2c_client);
+ 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_platform_probe);
+ if (!rc) {
+ CDBG("probe success");
+ return rc;
+ } else {
+ CDBG("probe i2c");
+ rc = i2c_add_driver(&msm_sensor_driver_i2c);
+ }
+
+ return rc;
+}
+
+
+static void __exit msm_sensor_driver_exit(void)
+{
+ CDBG("Enter");
+ platform_driver_unregister(&msm_sensor_platform_driver);
+ i2c_del_driver(&msm_sensor_driver_i2c);
+ return;
+}
+
+module_init(msm_sensor_driver_init);
+module_exit(msm_sensor_driver_exit);
+MODULE_DESCRIPTION("msm_sensor_driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.h b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.h
new file mode 100644
index 0000000..0394387
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.h
@@ -0,0 +1,20 @@
+/* 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MSM_SENSOR_DRIVER_H
+#define MSM_SENSOR_DRIVER_H
+
+#include "msm_sensor.h"
+
+int32_t msm_sensor_driver_probe(void *setting);
+
+#endif
diff --git a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_init.c b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_init.c
new file mode 100644
index 0000000..bc96eb8
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_init.c
@@ -0,0 +1,177 @@
+/* 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#define pr_fmt(fmt) "MSM-SENSOR-INIT %s:%d " fmt "\n", __func__, __LINE__
+
+/* Header files */
+#include <mach/gpiomux.h>
+#include "msm_sensor_init.h"
+#include "msm_sensor_driver.h"
+#include "msm_sensor.h"
+#include "msm_sd.h"
+
+/* Logging macro */
+/*#define CONFIG_MSMB_CAMERA_DEBUG*/
+#undef CDBG
+#ifdef CONFIG_MSMB_CAMERA_DEBUG
+#define CDBG(fmt, args...) pr_err(fmt, ##args)
+#else
+#define CDBG(fmt, args...) do { } while (0)
+#endif
+
+static struct msm_sensor_init_t *s_init;
+
+/* Static function declaration */
+static long msm_sensor_init_subdev_ioctl(struct v4l2_subdev *sd,
+ unsigned int cmd, void *arg);
+
+/* Static structure declaration */
+static struct v4l2_subdev_core_ops msm_sensor_init_subdev_core_ops = {
+ .ioctl = msm_sensor_init_subdev_ioctl,
+};
+
+static struct v4l2_subdev_ops msm_sensor_init_subdev_ops = {
+ .core = &msm_sensor_init_subdev_core_ops,
+};
+
+static const struct v4l2_subdev_internal_ops msm_sensor_init_internal_ops;
+
+static int msm_sensor_wait_for_probe_done(struct msm_sensor_init_t *s_init)
+{
+ int rc;
+
+ if (s_init->module_init_status == 1) {
+ pr_err("msm_cam_get_module_init_status -2\n");
+ return 0;
+ }
+
+ while (1) {
+ rc = wait_event_interruptible(s_init->state_wait,
+ (s_init->module_init_status == 1));
+ if (rc == -ETIMEDOUT)
+ continue;
+ else if (rc == 0)
+ break;
+ }
+ return 0;
+}
+
+/* Static function definition */
+static long msm_sensor_driver_cmd(struct msm_sensor_init_t *s_init, void *arg)
+{
+ int32_t rc = 0;
+ struct sensor_init_cfg_data *cfg = (struct sensor_init_cfg_data *)arg;
+
+ /* Validate input parameters */
+ if (!s_init || !cfg) {
+ pr_err("failed: s_init %p cfg %p", s_init, cfg);
+ return -EINVAL;
+ }
+
+ switch (cfg->cfgtype) {
+ case CFG_SINIT_PROBE:
+ mutex_lock(&s_init->imutex);
+ s_init->module_init_status = 0;
+ rc = msm_sensor_driver_probe(cfg->cfg.setting);
+ mutex_unlock(&s_init->imutex);
+ if (rc < 0)
+ pr_err("failed: msm_sensor_driver_probe rc %d", rc);
+ break;
+
+ case CFG_SINIT_PROBE_DONE:
+ s_init->module_init_status = 1;
+ wake_up(&s_init->state_wait);
+ break;
+
+ case CFG_SINIT_PROBE_WAIT_DONE:
+ msm_sensor_wait_for_probe_done(s_init);
+ break;
+
+ default:
+ pr_err("default");
+ break;
+ }
+
+ return rc;
+}
+
+static long msm_sensor_init_subdev_ioctl(struct v4l2_subdev *sd,
+ unsigned int cmd, void *arg)
+{
+ int32_t rc = 0;
+ struct msm_sensor_init_t *s_init = v4l2_get_subdevdata(sd);
+ CDBG("Enter");
+
+ /* Validate input parameters */
+ if (!s_init) {
+ pr_err("failed: s_init %p", s_init);
+ return -EINVAL;
+ }
+
+ switch (cmd) {
+ case VIDIOC_MSM_SENSOR_INIT_CFG:
+ rc = msm_sensor_driver_cmd(s_init, arg);
+ break;
+
+ default:
+ pr_err("default");
+ break;
+ }
+
+ return 0;
+}
+
+static int __init msm_sensor_init_module(void)
+{
+ /* Allocate memory for msm_sensor_init control structure */
+ s_init = kzalloc(sizeof(struct msm_sensor_init_t), GFP_KERNEL);
+ if (!s_init) {
+ pr_err("failed: no memory s_init %p", NULL);
+ return -ENOMEM;
+ }
+
+ pr_err("MSM_SENSOR_INIT_MODULE %p", NULL);
+
+ /* Initialize mutex */
+ mutex_init(&s_init->imutex);
+
+ /* Create /dev/v4l-subdevX for msm_sensor_init */
+ v4l2_subdev_init(&s_init->msm_sd.sd, &msm_sensor_init_subdev_ops);
+ snprintf(s_init->msm_sd.sd.name, sizeof(s_init->msm_sd.sd.name), "%s",
+ "msm_sensor_init");
+ v4l2_set_subdevdata(&s_init->msm_sd.sd, s_init);
+ s_init->msm_sd.sd.internal_ops = &msm_sensor_init_internal_ops;
+ s_init->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ media_entity_init(&s_init->msm_sd.sd.entity, 0, NULL, 0);
+ s_init->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+ s_init->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_SENSOR_INIT;
+ s_init->msm_sd.sd.entity.name = s_init->msm_sd.sd.name;
+ s_init->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x6;
+ msm_sd_register(&s_init->msm_sd);
+
+ init_waitqueue_head(&s_init->state_wait);
+
+ return 0;
+}
+
+static void __exit msm_sensor_exit_module(void)
+{
+ msm_sd_unregister(&s_init->msm_sd);
+ mutex_destroy(&s_init->imutex);
+ kfree(s_init);
+ return;
+}
+
+module_init(msm_sensor_init_module);
+module_exit(msm_sensor_exit_module);
+MODULE_DESCRIPTION("msm_sensor_init");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_init.h b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_init.h
new file mode 100644
index 0000000..256b0a1
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_init.h
@@ -0,0 +1,25 @@
+/* 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MSM_SENSOR_INIT_H
+#define MSM_SENSOR_INIT_H
+
+#include "msm_sensor.h"
+
+struct msm_sensor_init_t {
+ struct mutex imutex;
+ struct msm_sd_subdev msm_sd;
+ int module_init_status;
+ wait_queue_head_t state_wait;
+};
+
+#endif
diff --git a/drivers/media/platform/msm/camera_v2/sensor/mt9m114.c b/drivers/media/platform/msm/camera_v2/sensor/mt9m114.c
index de4fcd0..1d58490 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/mt9m114.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/mt9m114.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
@@ -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__,
@@ -1198,6 +1202,9 @@
for (i = 0; i < SUB_MODULE_MAX; i++)
CDBG("%s:%d subdev_id[%d] %d\n", __func__, __LINE__, i,
cdata->cfg.sensor_info.subdev_id[i]);
+ CDBG("%s:%d mount angle valid %d value %d\n", __func__,
+ __LINE__, cdata->cfg.sensor_info.is_mount_angle_valid,
+ cdata->cfg.sensor_info.sensor_mount_angle);
break;
case CFG_SET_INIT_SETTING:
@@ -1233,8 +1240,12 @@
MSM_CAMERA_I2C_WORD_DATA);
break;
case CFG_GET_SENSOR_INIT_PARAMS:
- cdata->cfg.sensor_init_params =
- *s_ctrl->sensordata->sensor_init_params;
+ cdata->cfg.sensor_init_params.modes_supported =
+ s_ctrl->sensordata->sensor_info->modes_supported;
+ cdata->cfg.sensor_init_params.position =
+ s_ctrl->sensordata->sensor_info->position;
+ cdata->cfg.sensor_init_params.sensor_mount_angle =
+ s_ctrl->sensordata->sensor_info->sensor_mount_angle;
CDBG("%s:%d init params mode %d pos %d mount %d\n", __func__,
__LINE__,
cdata->cfg.sensor_init_params.modes_supported,
@@ -1243,11 +1254,12 @@
break;
case CFG_SET_SLAVE_INFO: {
struct msm_camera_sensor_slave_info sensor_slave_info;
- struct msm_sensor_power_setting_array *power_setting_array;
+ struct msm_camera_power_ctrl_t *p_ctrl;
+ uint16_t size;
int slave_index = 0;
if (copy_from_user(&sensor_slave_info,
- (void *)cdata->cfg.setting,
- sizeof(struct msm_camera_sensor_slave_info))) {
+ (void *)cdata->cfg.setting,
+ sizeof(struct msm_camera_sensor_slave_info))) {
pr_err("%s:%d failed\n", __func__, __LINE__);
rc = -EFAULT;
break;
@@ -1263,27 +1275,30 @@
sensor_slave_info.addr_type;
/* Update power up / down sequence */
- s_ctrl->power_setting_array =
- sensor_slave_info.power_setting_array;
- power_setting_array = &s_ctrl->power_setting_array;
- power_setting_array->power_setting = kzalloc(
- power_setting_array->size *
- sizeof(struct msm_sensor_power_setting), GFP_KERNEL);
- if (!power_setting_array->power_setting) {
- pr_err("%s:%d failed\n", __func__, __LINE__);
- rc = -ENOMEM;
- break;
+ p_ctrl = &s_ctrl->sensordata->power_info;
+ size = sensor_slave_info.power_setting_array.size;
+ if (p_ctrl->power_setting_size < size) {
+ struct msm_sensor_power_setting *tmp;
+ tmp = kmalloc(sizeof(struct msm_sensor_power_setting)
+ * size, GFP_KERNEL);
+ if (!tmp) {
+ pr_err("%s: failed to alloc mem\n", __func__);
+ rc = -ENOMEM;
+ break;
+ }
+ kfree(p_ctrl->power_setting);
+ p_ctrl->power_setting = tmp;
}
- if (copy_from_user(power_setting_array->power_setting,
- (void *)sensor_slave_info.power_setting_array.power_setting,
- power_setting_array->size *
- sizeof(struct msm_sensor_power_setting))) {
- kfree(power_setting_array->power_setting);
+ p_ctrl->power_setting_size = size;
+
+ rc = copy_from_user(p_ctrl->power_setting, (void *)
+ sensor_slave_info.power_setting_array.power_setting,
+ size * sizeof(struct msm_sensor_power_setting));
+ if (rc) {
pr_err("%s:%d failed\n", __func__, __LINE__);
rc = -EFAULT;
break;
}
- s_ctrl->free_power_setting = true;
CDBG("%s sensor id %x\n", __func__,
sensor_slave_info.slave_addr);
CDBG("%s sensor addr type %d\n", __func__,
@@ -1293,19 +1308,14 @@
CDBG("%s sensor id %x\n", __func__,
sensor_slave_info.sensor_id_info.sensor_id);
for (slave_index = 0; slave_index <
- power_setting_array->size; slave_index++) {
+ p_ctrl->power_setting_size; slave_index++) {
CDBG("%s i %d power setting %d %d %ld %d\n", __func__,
slave_index,
- power_setting_array->power_setting[slave_index].
- seq_type,
- power_setting_array->power_setting[slave_index].
- seq_val,
- power_setting_array->power_setting[slave_index].
- config_val,
- power_setting_array->power_setting[slave_index].
- delay);
+ 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);
}
- kfree(power_setting_array->power_setting);
break;
}
case CFG_WRITE_I2C_ARRAY: {
@@ -1388,8 +1398,7 @@
case CFG_POWER_DOWN:
if (s_ctrl->func_tbl->sensor_power_down)
- rc = s_ctrl->func_tbl->sensor_power_down(
- s_ctrl);
+ rc = s_ctrl->func_tbl->sensor_power_down(s_ctrl);
else
rc = -EFAULT;
break;
diff --git a/drivers/media/platform/msm/camera_v2/sensor/sp1628.c b/drivers/media/platform/msm/camera_v2/sensor/sp1628.c
index 9a422c0..d4e4cdf 100755
--- a/drivers/media/platform/msm/camera_v2/sensor/sp1628.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/sp1628.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
@@ -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__,
@@ -644,6 +648,9 @@
for (i = 0; i < SUB_MODULE_MAX; i++)
CDBG("%s:%d subdev_id[%d] %d\n", __func__, __LINE__, i,
cdata->cfg.sensor_info.subdev_id[i]);
+ CDBG("%s:%d mount angle valid %d value %d\n", __func__,
+ __LINE__, cdata->cfg.sensor_info.is_mount_angle_valid,
+ cdata->cfg.sensor_info.sensor_mount_angle);
break;
case CFG_SET_INIT_SETTING:
@@ -674,8 +681,12 @@
MSM_CAMERA_I2C_BYTE_DATA);
break;
case CFG_GET_SENSOR_INIT_PARAMS:
- cdata->cfg.sensor_init_params =
- *s_ctrl->sensordata->sensor_init_params;
+ cdata->cfg.sensor_init_params.modes_supported =
+ s_ctrl->sensordata->sensor_info->modes_supported;
+ cdata->cfg.sensor_init_params.position =
+ s_ctrl->sensordata->sensor_info->position;
+ cdata->cfg.sensor_init_params.sensor_mount_angle =
+ s_ctrl->sensordata->sensor_info->sensor_mount_angle;
CDBG("%s:%d init params mode %d pos %d mount %d\n", __func__,
__LINE__,
cdata->cfg.sensor_init_params.modes_supported,
@@ -724,7 +735,6 @@
rc = -EFAULT;
break;
}
- s_ctrl->free_power_setting = true;
CDBG("%s sensor id %x\n", __func__,
sensor_slave_info.slave_addr);
CDBG("%s sensor addr type %d\n", __func__,
diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c
index 71ad080..ea7d670 100644
--- a/drivers/media/platform/msm/vidc/msm_vdec.c
+++ b/drivers/media/platform/msm/vidc/msm_vdec.c
@@ -21,7 +21,7 @@
#define MSM_VDEC_DVC_NAME "msm_vdec_8974"
#define MIN_NUM_OUTPUT_BUFFERS 4
-#define MAX_NUM_OUTPUT_BUFFERS 6
+#define MAX_NUM_OUTPUT_BUFFERS VIDEO_MAX_FRAME
#define DEFAULT_VIDEO_CONCEAL_COLOR_BLACK 0x8080
#define TZ_DYNAMIC_BUFFER_FEATURE_ID 12
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
index b01a507..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,
@@ -468,6 +476,26 @@
.cluster = MSM_VENC_CTRL_CLUSTER_QP,
},
{
+ .id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_MIN_QP,
+ .name = "VP8 Minimum QP",
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 1,
+ .maximum = 128,
+ .default_value = 1,
+ .step = 1,
+ .cluster = MSM_VENC_CTRL_CLUSTER_QP,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_MAX_QP,
+ .name = "VP8 Maximum QP",
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 1,
+ .maximum = 128,
+ .default_value = 128,
+ .step = 1,
+ .cluster = MSM_VENC_CTRL_CLUSTER_QP,
+ },
+ {
.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE,
.name = "Slice Mode",
.type = V4L2_CTRL_TYPE_MENU,
@@ -546,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,
},
{
@@ -1752,6 +1781,26 @@
pdata = &qp_range;
break;
}
+ case V4L2_CID_MPEG_VIDC_VIDEO_VP8_MIN_QP: {
+ struct v4l2_ctrl *qp_max;
+ qp_max = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_VP8_MAX_QP);
+ property_id = HAL_PARAM_VENC_SESSION_QP_RANGE;
+ qp_range.layer_id = 0;
+ qp_range.max_qp = qp_max->val;
+ qp_range.min_qp = ctrl->val;
+ pdata = &qp_range;
+ break;
+ }
+ case V4L2_CID_MPEG_VIDC_VIDEO_VP8_MAX_QP: {
+ struct v4l2_ctrl *qp_min;
+ qp_min = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_VP8_MIN_QP);
+ property_id = HAL_PARAM_VENC_SESSION_QP_RANGE;
+ qp_range.layer_id = 0;
+ qp_range.max_qp = ctrl->val;
+ qp_range.min_qp = qp_min->val;
+ pdata = &qp_range;
+ break;
+ }
case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: {
int temp = 0;
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/mfd/wcd9xxx-core.c b/drivers/mfd/wcd9xxx-core.c
index 1c42431..5eb359e 100644
--- a/drivers/mfd/wcd9xxx-core.c
+++ b/drivers/mfd/wcd9xxx-core.c
@@ -555,7 +555,6 @@
{WCD9XXX_IRQ_EAR_PA_OCPL_FAULT, false},
{WCD9XXX_IRQ_HPH_L_PA_STARTUP, false},
{WCD9XXX_IRQ_HPH_R_PA_STARTUP, false},
- {WCD9320_IRQ_EAR_PA_STARTUP, false},
{WCD9XXX_IRQ_RESERVED_0, false},
{WCD9XXX_IRQ_RESERVED_1, false},
{WCD9XXX_IRQ_MAD_AUDIO, false},
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index aad7fb3..1839d07 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -1,6 +1,6 @@
/*Qualcomm Secure Execution Environment Communicator (QSEECOM) driver
*
- * 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
@@ -2647,7 +2647,7 @@
if (ret) {
pr_err("scm call to generate key failed : %d\n", ret);
__qseecom_disable_clk(CLK_QSEE);
- return ret;
+ return -EFAULT;
}
switch (resp.result) {
@@ -2698,7 +2698,7 @@
if (ret) {
pr_err("scm call to delete key failed : %d\n", ret);
__qseecom_disable_clk(CLK_QSEE);
- return ret;
+ return -EFAULT;
}
switch (resp.result) {
@@ -2706,9 +2706,18 @@
break;
case QSEOS_RESULT_INCOMPLETE:
ret = __qseecom_process_incomplete_cmd(data, &resp);
- if (ret)
+ if (ret) {
pr_err("process_incomplete_cmd FAILED, resp.result %d\n",
resp.result);
+ if (resp.result == QSEOS_RESULT_FAIL_MAX_ATTEMPT) {
+ pr_debug("Max attempts to input password reached.\n");
+ ret = -ERANGE;
+ }
+ }
+ break;
+ case QSEOS_RESULT_FAIL_MAX_ATTEMPT:
+ pr_debug("Max attempts to input password reached.\n");
+ ret = -ERANGE;
break;
case QSEOS_RESULT_FAILURE:
default:
@@ -2746,7 +2755,7 @@
__qseecom_disable_clk(CLK_QSEE);
if (qseecom.qsee.instance != qseecom.ce_drv.instance)
__qseecom_disable_clk(CLK_CE_DRV);
- return ret;
+ return -EFAULT;
}
switch (resp.result) {
@@ -2754,9 +2763,18 @@
break;
case QSEOS_RESULT_INCOMPLETE:
ret = __qseecom_process_incomplete_cmd(data, &resp);
- if (ret)
+ if (ret) {
pr_err("process_incomplete_cmd FAILED, resp.result %d\n",
resp.result);
+ if (resp.result == QSEOS_RESULT_FAIL_MAX_ATTEMPT) {
+ pr_debug("Max attempts to input password reached.\n");
+ ret = -ERANGE;
+ }
+ }
+ break;
+ case QSEOS_RESULT_FAIL_MAX_ATTEMPT:
+ pr_debug("Max attempts to input password reached.\n");
+ ret = -ERANGE;
break;
case QSEOS_RESULT_FAILURE:
default:
@@ -2796,7 +2814,7 @@
__qseecom_disable_clk(CLK_QSEE);
if (qseecom.qsee.instance != qseecom.ce_drv.instance)
__qseecom_disable_clk(CLK_CE_DRV);
- return ret;
+ return -EFAULT;
}
switch (resp.result) {
@@ -2862,7 +2880,7 @@
&generate_key_ireq);
if (ret) {
pr_err("Failed to generate key on storage: %d\n", ret);
- return -EFAULT;
+ return ret;
}
set_key_ireq.qsee_command_id = QSEOS_SET_KEY;
@@ -2885,7 +2903,7 @@
if (ret) {
pr_err("Failed to create key: pipe %d, ce %d: %d\n",
pipe, ce_hw, ret);
- return -EFAULT;
+ return ret;
}
return ret;
@@ -2992,7 +3010,7 @@
&ireq);
if (ret) {
pr_err("Failed to update key info: %d\n", ret);
- return -EFAULT;
+ return ret;
}
return ret;
@@ -3996,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",
@@ -4006,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/mmc/card/block.c b/drivers/mmc/card/block.c
index 3eedc32..6add807 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -3077,6 +3077,9 @@
MMC_FIXUP(CID_NAME_ANY, CID_MANFID_HYNIX, CID_OEMID_ANY, add_quirk_mmc,
MMC_QUIRK_BROKEN_DATA_TIMEOUT),
+ /* Disable cache for this cards */
+ MMC_FIXUP("H8G2d", CID_MANFID_HYNIX, CID_OEMID_ANY, add_quirk_mmc,
+ MMC_QUIRK_CACHE_DISABLE),
END_FIXUP
};
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index cd94960..c496077 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -3356,7 +3356,8 @@
struct mmc_host *host = card->host;
int err = 0, rc;
- if (!(host->caps2 & MMC_CAP2_CACHE_CTRL))
+ if (!(host->caps2 & MMC_CAP2_CACHE_CTRL) ||
+ (card->quirks & MMC_QUIRK_CACHE_DISABLE))
return err;
if (mmc_card_mmc(card) &&
@@ -3395,7 +3396,8 @@
int err = 0, rc;
if (!(host->caps2 & MMC_CAP2_CACHE_CTRL) ||
- mmc_card_is_removable(host))
+ mmc_card_is_removable(host) ||
+ (card->quirks & MMC_QUIRK_CACHE_DISABLE))
return err;
if (card && mmc_card_mmc(card) &&
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index b295bb8..885d0d2 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1557,7 +1557,8 @@
* If HPI is not supported then cache shouldn't be enabled.
*/
if ((host->caps2 & MMC_CAP2_CACHE_CTRL) &&
- (card->ext_csd.cache_size > 0) && card->ext_csd.hpi_en) {
+ (card->ext_csd.cache_size > 0) && card->ext_csd.hpi_en &&
+ ((card->quirks & MMC_QUIRK_CACHE_DISABLE) == 0)) {
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
EXT_CSD_CACHE_CTRL, 1,
card->ext_csd.generic_cmd6_time);
@@ -1577,6 +1578,11 @@
card->ext_csd.cache_ctrl = 1;
}
}
+ if (card->quirks & MMC_QUIRK_CACHE_DISABLE) {
+ pr_warn("%s: This is Hynix card, cache disabled!\n",
+ mmc_hostname(card->host));
+ card->ext_csd.cache_ctrl = 0;
+ }
if ((host->caps2 & MMC_CAP2_PACKED_WR &&
card->ext_csd.max_packed_writes > 0) ||
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 3648d88..d4d7c18 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -851,6 +851,7 @@
((*rocr & 0x41000000) == 0x41000000)) {
err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180, true);
if (err) {
+ mmc_power_cycle(host);
ocr &= ~SD_OCR_S18R;
goto try_again;
}
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/power/qpnp-charger.c b/drivers/power/qpnp-charger.c
index 40c5568..4439881 100644
--- a/drivers/power/qpnp-charger.c
+++ b/drivers/power/qpnp-charger.c
@@ -904,21 +904,21 @@
return rc;
}
-#define QPNP_CHG_VINMIN_MIN_MV 4200
+#define QPNP_CHG_VINMIN_MIN_MV 4000
#define QPNP_CHG_VINMIN_HIGH_MIN_MV 5600
#define QPNP_CHG_VINMIN_HIGH_MIN_VAL 0x2B
#define QPNP_CHG_VINMIN_MAX_MV 9600
#define QPNP_CHG_VINMIN_STEP_MV 50
#define QPNP_CHG_VINMIN_STEP_HIGH_MV 200
#define QPNP_CHG_VINMIN_MASK 0x3F
-#define QPNP_CHG_VINMIN_MIN_VAL 0x10
+#define QPNP_CHG_VINMIN_MIN_VAL 0x0C
static int
qpnp_chg_vinmin_set(struct qpnp_chg_chip *chip, int voltage)
{
u8 temp;
- if (voltage < QPNP_CHG_VINMIN_MIN_MV
- || voltage > QPNP_CHG_VINMIN_MAX_MV) {
+ if ((voltage < QPNP_CHG_VINMIN_MIN_MV)
+ || (voltage > QPNP_CHG_VINMIN_MAX_MV)) {
pr_err("bad mV=%d asked to set\n", voltage);
return -EINVAL;
}
@@ -1595,27 +1595,30 @@
qpnp_chg_bat_if_batt_temp_irq_handler(int irq, void *_chip)
{
struct qpnp_chg_chip *chip = _chip;
- int batt_temp_good, rc;
+ int batt_temp_good, batt_present, rc;
batt_temp_good = qpnp_chg_is_batt_temp_ok(chip);
pr_debug("batt-temp triggered: %d\n", batt_temp_good);
- rc = qpnp_chg_masked_write(chip,
- chip->buck_base + SEC_ACCESS,
- 0xFF,
- 0xA5, 1);
- if (rc) {
- pr_err("failed to write SEC_ACCESS rc=%d\n", rc);
- return rc;
- }
+ batt_present = qpnp_chg_is_batt_present(chip);
+ if (batt_present) {
+ rc = qpnp_chg_masked_write(chip,
+ chip->buck_base + SEC_ACCESS,
+ 0xFF,
+ 0xA5, 1);
+ if (rc) {
+ pr_err("failed to write SEC_ACCESS rc=%d\n", rc);
+ return rc;
+ }
- rc = qpnp_chg_masked_write(chip,
- chip->buck_base + TEST_EN_SMBC_LOOP,
- IBAT_REGULATION_DISABLE,
- batt_temp_good ? 0 : IBAT_REGULATION_DISABLE, 1);
- if (rc) {
- pr_err("failed to write COMP_OVR1 rc=%d\n", rc);
- return rc;
+ rc = qpnp_chg_masked_write(chip,
+ chip->buck_base + TEST_EN_SMBC_LOOP,
+ IBAT_REGULATION_DISABLE,
+ batt_temp_good ? 0 : IBAT_REGULATION_DISABLE, 1);
+ if (rc) {
+ pr_err("failed to write COMP_OVR1 rc=%d\n", rc);
+ return rc;
+ }
}
pr_debug("psy changed batt_psy\n");
@@ -1627,15 +1630,51 @@
qpnp_chg_bat_if_batt_pres_irq_handler(int irq, void *_chip)
{
struct qpnp_chg_chip *chip = _chip;
- int batt_present;
+ int batt_present, batt_temp_good, rc;
batt_present = qpnp_chg_is_batt_present(chip);
pr_debug("batt-pres triggered: %d\n", batt_present);
if (chip->batt_present ^ batt_present) {
if (batt_present) {
+ batt_temp_good = qpnp_chg_is_batt_temp_ok(chip);
+ rc = qpnp_chg_masked_write(chip,
+ chip->buck_base + SEC_ACCESS,
+ 0xFF,
+ 0xA5, 1);
+ if (rc) {
+ pr_err("failed to write SEC_ACCESS: %d\n", rc);
+ return rc;
+ }
+
+ rc = qpnp_chg_masked_write(chip,
+ chip->buck_base + TEST_EN_SMBC_LOOP,
+ IBAT_REGULATION_DISABLE,
+ batt_temp_good
+ ? 0 : IBAT_REGULATION_DISABLE, 1);
+ if (rc) {
+ pr_err("failed to write COMP_OVR1 rc=%d\n", rc);
+ return rc;
+ }
schedule_work(&chip->insertion_ocv_work);
} else {
+ rc = qpnp_chg_masked_write(chip,
+ chip->buck_base + SEC_ACCESS,
+ 0xFF,
+ 0xA5, 1);
+ if (rc) {
+ pr_err("failed to write SEC_ACCESS: %d\n", rc);
+ return rc;
+ }
+
+ rc = qpnp_chg_masked_write(chip,
+ chip->buck_base + TEST_EN_SMBC_LOOP,
+ IBAT_REGULATION_DISABLE,
+ 0, 1);
+ if (rc) {
+ pr_err("failed to write COMP_OVR1 rc=%d\n", rc);
+ return rc;
+ }
chip->insertion_ocv_uv = 0;
qpnp_chg_charge_en(chip, 0);
}
diff --git a/drivers/rtc/qpnp-rtc.c b/drivers/rtc/qpnp-rtc.c
index bfbae78..d64b577 100644
--- a/drivers/rtc/qpnp-rtc.c
+++ b/drivers/rtc/qpnp-rtc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-13, 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
@@ -102,6 +102,7 @@
int rc;
unsigned long secs, irq_flags;
u8 value[4], reg = 0, alarm_enabled = 0, ctrl_reg;
+ u8 rtc_disabled = 0, rtc_ctrl_reg;
struct qpnp_rtc *rtc_dd = dev_get_drvdata(dev);
rtc_tm_to_time(tm, &secs);
@@ -152,6 +153,22 @@
* write operation
*/
+ /* Disable RTC H/w before writing on RTC register*/
+ rtc_ctrl_reg = rtc_dd->rtc_ctrl_reg;
+ if (rtc_ctrl_reg & BIT_RTC_ENABLE) {
+ rtc_disabled = 1;
+ rtc_ctrl_reg &= ~BIT_RTC_ENABLE;
+ rc = qpnp_write_wrapper(rtc_dd, &rtc_ctrl_reg,
+ rtc_dd->rtc_base + REG_OFFSET_RTC_CTRL, 1);
+ if (rc) {
+ dev_err(dev,
+ "Disabling of RTC control reg failed"
+ " with error:%d\n", rc);
+ goto rtc_rw_fail;
+ }
+ rtc_dd->rtc_ctrl_reg = rtc_ctrl_reg;
+ }
+
/* Clear WDATA[0] */
reg = 0x0;
rc = qpnp_write_wrapper(rtc_dd, ®,
@@ -177,6 +194,20 @@
goto rtc_rw_fail;
}
+ /* Enable RTC H/w after writing on RTC register*/
+ if (rtc_disabled) {
+ rtc_ctrl_reg |= BIT_RTC_ENABLE;
+ rc = qpnp_write_wrapper(rtc_dd, &rtc_ctrl_reg,
+ rtc_dd->rtc_base + REG_OFFSET_RTC_CTRL, 1);
+ if (rc) {
+ dev_err(dev,
+ "Enabling of RTC control reg failed"
+ " with error:%d\n", rc);
+ goto rtc_rw_fail;
+ }
+ rtc_dd->rtc_ctrl_reg = rtc_ctrl_reg;
+ }
+
if (alarm_enabled) {
ctrl_reg |= BIT_RTC_ALARM_ENABLE;
rc = qpnp_write_wrapper(rtc_dd, &ctrl_reg,
diff --git a/drivers/spi/spi_qsd.c b/drivers/spi/spi_qsd.c
index 45400cb..39e81fa 100644
--- a/drivers/spi/spi_qsd.c
+++ b/drivers/spi/spi_qsd.c
@@ -1167,10 +1167,8 @@
if ((!dd->read_buf || op & SPI_OP_MAX_INPUT_DONE_FLAG) &&
(!dd->write_buf || op & SPI_OP_MAX_OUTPUT_DONE_FLAG)) {
msm_spi_ack_transfer(dd);
- if (dd->rx_unaligned_len == 0) {
if (atomic_inc_return(&dd->rx_irq_called) == 1)
return IRQ_HANDLED;
- }
msm_spi_complete(dd);
return IRQ_HANDLED;
}
diff --git a/drivers/thermal/msm_thermal.c b/drivers/thermal/msm_thermal.c
index 891eb2f..73513ec 100644
--- a/drivers/thermal/msm_thermal.c
+++ b/drivers/thermal/msm_thermal.c
@@ -1769,6 +1769,18 @@
int ret = 0;
uint32_t cpu;
+ for_each_possible_cpu(cpu) {
+ cpus[cpu].cpu = cpu;
+ cpus[cpu].offline = 0;
+ cpus[cpu].user_offline = 0;
+ cpus[cpu].hotplug_thresh_clear = false;
+ cpus[cpu].max_freq = false;
+ cpus[cpu].user_max_freq = UINT_MAX;
+ cpus[cpu].user_min_freq = 0;
+ cpus[cpu].limited_max_freq = UINT_MAX;
+ cpus[cpu].limited_min_freq = 0;
+ cpus[cpu].freq_thresh_clear = false;
+ }
BUG_ON(!pdata);
tsens_get_max_sensor_num(&max_tsens_num);
memcpy(&msm_thermal_info, pdata, sizeof(struct msm_thermal_data));
@@ -1779,10 +1791,6 @@
return -EINVAL;
enabled = 1;
- for_each_possible_cpu(cpu) {
- cpus[cpu].limited_max_freq = UINT_MAX;
- cpus[cpu].limited_min_freq = 0;
- }
ret = cpufreq_register_notifier(&msm_thermal_cpufreq_notifier,
CPUFREQ_POLICY_NOTIFIER);
if (ret)
@@ -2433,10 +2441,6 @@
}
for_each_possible_cpu(cpu) {
- cpus[cpu].cpu = cpu;
- cpus[cpu].offline = 0;
- cpus[cpu].user_offline = 0;
- cpus[cpu].hotplug_thresh_clear = false;
ret = of_property_read_string_index(node, key, cpu,
&cpus[cpu].sensor_type);
if (ret)
@@ -2470,7 +2474,6 @@
{
char *key = NULL;
int ret = 0;
- uint32_t cpu;
key = "qcom,freq-mitigation-temp";
ret = of_property_read_u32(node, key, &data->freq_mitig_temp_degc);
@@ -2494,14 +2497,6 @@
goto PROBE_FREQ_EXIT;
freq_mitigation_enabled = 1;
- for_each_possible_cpu(cpu) {
- cpus[cpu].max_freq = false;
- cpus[cpu].user_max_freq = UINT_MAX;
- cpus[cpu].user_min_freq = 0;
- cpus[cpu].limited_max_freq = UINT_MAX;
- cpus[cpu].limited_min_freq = 0;
- cpus[cpu].freq_thresh_clear = false;
- }
PROBE_FREQ_EXIT:
if (ret) {
diff --git a/drivers/thermal/qpnp-adc-tm.c b/drivers/thermal/qpnp-adc-tm.c
index efb87a9..eb647fa 100644
--- a/drivers/thermal/qpnp-adc-tm.c
+++ b/drivers/thermal/qpnp-adc-tm.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
@@ -471,16 +471,30 @@
struct qpnp_adc_tm_chip *chip, uint32_t btm_chan,
struct qpnp_vadc_chan_properties *chan_prop)
{
- int rc;
- u8 meas_interval_timer2 = 0;
+ int rc, chan_idx = 0, i = 0;
+ bool chan_found = false;
+ u8 meas_interval_timer2 = 0, timer_interval_store = 0;
uint32_t btm_chan_idx = 0;
- /* Configure kernel clients to timer1 */
- switch (chan_prop->timer_select) {
+ while (i < chip->max_channels_available) {
+ if (chip->sensor[i].btm_channel_num == btm_chan) {
+ chan_idx = i;
+ chan_found = true;
+ i++;
+ } else
+ i++;
+ }
+
+ if (!chan_found) {
+ pr_err("Channel not found\n");
+ return -EINVAL;
+ }
+
+ switch (chip->sensor[chan_idx].timer_select) {
case ADC_MEAS_TIMER_SELECT1:
rc = qpnp_adc_tm_write_reg(chip,
QPNP_ADC_TM_MEAS_INTERVAL_CTL,
- chan_prop->meas_interval1);
+ chip->sensor[chan_idx].meas_interval);
if (rc < 0) {
pr_err("timer1 configure failed\n");
return rc;
@@ -495,9 +509,10 @@
pr_err("timer2 configure read failed\n");
return rc;
}
- meas_interval_timer2 |=
- (chan_prop->meas_interval2 <<
- QPNP_ADC_TM_MEAS_INTERVAL_CTL2_SHIFT);
+ timer_interval_store = chip->sensor[chan_idx].meas_interval;
+ timer_interval_store <<= QPNP_ADC_TM_MEAS_INTERVAL_CTL2_SHIFT;
+ timer_interval_store &= QPNP_ADC_TM_MEAS_INTERVAL_CTL2_MASK;
+ meas_interval_timer2 |= timer_interval_store;
rc = qpnp_adc_tm_write_reg(chip,
QPNP_ADC_TM_MEAS_INTERVAL_CTL2,
meas_interval_timer2);
@@ -514,8 +529,9 @@
pr_err("timer3 read failed\n");
return rc;
}
- chan_prop->meas_interval2 = ADC_MEAS3_INTERVAL_1S;
- meas_interval_timer2 |= chan_prop->meas_interval2;
+ timer_interval_store = chip->sensor[chan_idx].meas_interval;
+ timer_interval_store &= QPNP_ADC_TM_MEAS_INTERVAL_CTL3_MASK;
+ meas_interval_timer2 |= timer_interval_store;
rc = qpnp_adc_tm_write_reg(chip,
QPNP_ADC_TM_MEAS_INTERVAL_CTL2,
meas_interval_timer2);
@@ -535,7 +551,18 @@
pr_err("Invalid btm channel idx\n");
return rc;
}
- adc_tm_data[btm_chan_idx].meas_interval_ctl = chan_prop->timer_select;
+ rc = qpnp_adc_tm_write_reg(chip,
+ adc_tm_data[btm_chan_idx].meas_interval_ctl,
+ chip->sensor[chan_idx].timer_select);
+ if (rc < 0) {
+ pr_err("TM channel timer configure failed\n");
+ return rc;
+ }
+
+ pr_debug("timer select:%d, timer_value_within_select:%d, channel:%x\n",
+ chip->sensor[chan_idx].timer_select,
+ chip->sensor[chan_idx].meas_interval,
+ btm_chan);
return rc;
}
@@ -954,10 +981,6 @@
chip->adc->adc_channels[channel].fast_avg_setup;
chip->adc->amux_prop->mode_sel =
ADC_OP_MEASUREMENT_INTERVAL << QPNP_OP_MODE_SHIFT;
- chip->adc->amux_prop->chan_prop->timer_select =
- ADC_MEAS_TIMER_SELECT1;
- chip->adc->amux_prop->chan_prop->meas_interval1 =
- ADC_MEAS1_INTERVAL_1S;
chip->adc->amux_prop->chan_prop->low_thr = adc_tm->low_thr;
chip->adc->amux_prop->chan_prop->high_thr = adc_tm->high_thr;
chip->adc->amux_prop->chan_prop->tm_channel_select =
@@ -1673,8 +1696,6 @@
chip->adc->adc_channels[dt_index].fast_avg_setup;
chip->adc->amux_prop->mode_sel =
ADC_OP_MEASUREMENT_INTERVAL << QPNP_OP_MODE_SHIFT;
- chip->adc->amux_prop->chan_prop->meas_interval1 =
- ADC_MEAS1_INTERVAL_1S;
adc_tm_rscale_fn[scale_type].chan(chip->vadc_dev, param,
&chip->adc->amux_prop->chan_prop->low_thr,
&chip->adc->amux_prop->chan_prop->high_thr);
@@ -1682,8 +1703,6 @@
chip->adc->amux_prop->chan_prop);
chip->adc->amux_prop->chan_prop->tm_channel_select =
chip->sensor[dt_index].btm_channel_num;
- chip->adc->amux_prop->chan_prop->timer_select =
- ADC_MEAS_TIMER_SELECT1;
chip->adc->amux_prop->chan_prop->state_request =
param->state_request;
rc = qpnp_adc_tm_configure(chip, chip->adc->amux_prop);
@@ -1880,7 +1899,7 @@
for_each_child_of_node(node, child) {
char name[25];
- int btm_channel_num;
+ int btm_channel_num, timer_select = 0;
rc = of_property_read_u32(child,
"qcom,btm-channel-number", &btm_channel_num);
@@ -1888,6 +1907,28 @@
pr_err("Invalid btm channel number\n");
goto fail;
}
+ rc = of_property_read_u32(child,
+ "qcom,meas-interval-timer-idx", &timer_select);
+ if (rc) {
+ pr_debug("Default to timer1 with interval of 1 sec\n");
+ chip->sensor[sen_idx].timer_select =
+ ADC_MEAS_TIMER_SELECT1;
+ chip->sensor[sen_idx].meas_interval =
+ ADC_MEAS1_INTERVAL_1S;
+ } else {
+ if (timer_select >= ADC_MEAS_TIMER_NUM) {
+ pr_err("Invalid timer selection number\n");
+ goto fail;
+ }
+ chip->sensor[sen_idx].timer_select = timer_select;
+ if (timer_select == ADC_MEAS_TIMER_SELECT2)
+ chip->sensor[sen_idx].meas_interval =
+ ADC_MEAS2_INTERVAL_500MS;
+ if (timer_select == ADC_MEAS_TIMER_SELECT3)
+ chip->sensor[sen_idx].meas_interval =
+ ADC_MEAS3_INTERVAL_4S;
+ }
+
chip->sensor[sen_idx].btm_channel_num = btm_channel_num;
chip->sensor[sen_idx].vadc_channel_num =
chip->adc->adc_channels[sen_idx].channel_num;
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index a783d53..0470194 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -640,38 +640,58 @@
return 0;
}
-static const struct vm_operations_struct uio_vm_ops = {
+static const struct vm_operations_struct uio_logical_vm_ops = {
.open = uio_vma_open,
.close = uio_vma_close,
.fault = uio_vma_fault,
};
+static int uio_mmap_logical(struct vm_area_struct *vma)
+{
+ vma->vm_flags |= VM_DONTEXPAND | VM_NODUMP;
+ vma->vm_ops = &uio_logical_vm_ops;
+ uio_vma_open(vma);
+ return 0;
+}
+
+static const struct vm_operations_struct uio_physical_vm_ops = {
+#ifdef CONFIG_HAVE_IOREMAP_PROT
+ .access = generic_access_phys,
+#endif
+};
+
static int uio_mmap_physical(struct vm_area_struct *vma)
{
struct uio_device *idev = vma->vm_private_data;
int mi = uio_find_mem_index(vma);
+ struct uio_mem *mem;
if (mi < 0)
return -EINVAL;
+ mem = idev->info->mem + mi;
- vma->vm_flags |= VM_IO | VM_RESERVED;
+ if (vma->vm_end - vma->vm_start > mem->size)
+ return -EINVAL;
+ vma->vm_ops = &uio_physical_vm_ops;
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ /*
+ * We cannot use the vm_iomap_memory() helper here,
+ * because vma->vm_pgoff is the map index we looked
+ * up above in uio_find_mem_index(), rather than an
+ * actual page offset into the mmap.
+ *
+ * So we just do the physical mmap without a page
+ * offset.
+ */
+
return remap_pfn_range(vma,
vma->vm_start,
- idev->info->mem[mi].addr >> PAGE_SHIFT,
+ mem->addr >> PAGE_SHIFT,
vma->vm_end - vma->vm_start,
vma->vm_page_prot);
}
-static int uio_mmap_logical(struct vm_area_struct *vma)
-{
- vma->vm_flags |= VM_RESERVED;
- vma->vm_ops = &uio_vm_ops;
- uio_vma_open(vma);
- return 0;
-}
-
static int uio_mmap(struct file *filep, struct vm_area_struct *vma)
{
struct uio_listener *listener = filep->private_data;
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index 667a8a2..0e371d5 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -217,6 +217,7 @@
struct qpnp_adc_tm_chip *adc_tm_dev;
struct delayed_work init_adc_work;
bool id_adc_detect;
+ struct qpnp_vadc_chip *vadc_dev;
u8 dcd_retries;
u32 bus_perf_client;
struct msm_bus_scale_pdata *bus_scale_table;
@@ -2258,6 +2259,27 @@
return IRQ_HANDLED;
}
+static int
+get_prop_usbin_voltage_now(struct dwc3_msm *mdwc)
+{
+ int rc = 0;
+ struct qpnp_vadc_result results;
+
+ if (IS_ERR_OR_NULL(mdwc->vadc_dev)) {
+ mdwc->vadc_dev = qpnp_get_vadc(mdwc->dev, "usbin");
+ if (IS_ERR(mdwc->vadc_dev))
+ return PTR_ERR(mdwc->vadc_dev);
+ }
+
+ rc = qpnp_vadc_read(mdwc->vadc_dev, USBIN, &results);
+ if (rc) {
+ pr_err("Unable to read usbin rc=%d\n", rc);
+ return 0;
+ } else {
+ return results.physical;
+ }
+}
+
static int dwc3_msm_power_get_property_usb(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
@@ -2283,6 +2305,9 @@
case POWER_SUPPLY_PROP_TYPE:
val->intval = psy->type;
break;
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ val->intval = get_prop_usbin_voltage_now(mdwc);
+ break;
default:
return -EINVAL;
}
@@ -2391,6 +2416,7 @@
POWER_SUPPLY_PROP_CURRENT_MAX,
POWER_SUPPLY_PROP_TYPE,
POWER_SUPPLY_PROP_SCOPE,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
};
static void dwc3_init_adc_work(struct work_struct *w);
@@ -2635,6 +2661,30 @@
pm_runtime_put(mdwc->dev);
}
break;
+ case MSM_USB_EXT_CHG_VOLTAGE_INFO:
+ if (get_user(val, (int __user *)arg)) {
+ pr_err("%s: get_user failed\n\n", __func__);
+ ret = -EFAULT;
+ break;
+ }
+
+ if (val == USB_REQUEST_5V)
+ pr_debug("%s:voting 5V voltage request\n", __func__);
+ else if (val == USB_REQUEST_9V)
+ pr_debug("%s:voting 9V voltage request\n", __func__);
+ break;
+ case MSM_USB_EXT_CHG_RESULT:
+ if (get_user(val, (int __user *)arg)) {
+ pr_err("%s: get_user failed\n\n", __func__);
+ ret = -EFAULT;
+ break;
+ }
+
+ if (!val)
+ pr_debug("%s:voltage request successful\n", __func__);
+ else
+ pr_debug("%s:voltage request failed\n", __func__);
+ break;
default:
ret = -EINVAL;
}
diff --git a/drivers/usb/dwc3/dwc3_otg.c b/drivers/usb/dwc3/dwc3_otg.c
index cacd635..8a034d6 100644
--- a/drivers/usb/dwc3/dwc3_otg.c
+++ b/drivers/usb/dwc3/dwc3_otg.c
@@ -197,6 +197,14 @@
if (on) {
dev_dbg(otg->phy->dev, "%s: turn on host\n", __func__);
+ dwc3_otg_notify_host_mode(otg, on);
+ ret = regulator_enable(dotg->vbus_otg);
+ if (ret) {
+ dev_err(otg->phy->dev, "unable to enable vbus_otg\n");
+ dwc3_otg_notify_host_mode(otg, 0);
+ return ret;
+ }
+
/*
* This should be revisited for more testing post-silicon.
* In worst case we may need to disconnect the root hub
@@ -222,14 +230,8 @@
dev_err(otg->phy->dev,
"%s: failed to add XHCI pdev ret=%d\n",
__func__, ret);
- return ret;
- }
-
- dwc3_otg_notify_host_mode(otg, on);
- ret = regulator_enable(dotg->vbus_otg);
- if (ret) {
- dev_err(otg->phy->dev, "unable to enable vbus_otg\n");
- platform_device_del(dwc->xhci);
+ regulator_disable(dotg->vbus_otg);
+ dwc3_otg_notify_host_mode(otg, 0);
return ret;
}
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..15a9ab0 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -41,6 +41,7 @@
#include <linux/mfd/pm8xxx/pm8921-charger.h>
#include <linux/mfd/pm8xxx/misc.h>
#include <linux/mhl_8334.h>
+#include <linux/qpnp/qpnp-adc.h>
#include <mach/scm.h>
#include <mach/clk.h>
@@ -455,8 +456,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 +1170,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;
}
@@ -3641,6 +3646,27 @@
return count;
}
+static int
+otg_get_prop_usbin_voltage_now(struct msm_otg *motg)
+{
+ int rc = 0;
+ struct qpnp_vadc_result results;
+
+ if (IS_ERR_OR_NULL(motg->vadc_dev)) {
+ motg->vadc_dev = qpnp_get_vadc(motg->phy.dev, "usbin");
+ if (IS_ERR(motg->vadc_dev))
+ return PTR_ERR(motg->vadc_dev);
+ }
+
+ rc = qpnp_vadc_read(motg->vadc_dev, USBIN, &results);
+ if (rc) {
+ pr_err("Unable to read usbin rc=%d\n", rc);
+ return 0;
+ } else {
+ return results.physical;
+ }
+}
+
static int otg_power_get_property_usb(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
@@ -3670,6 +3696,9 @@
case POWER_SUPPLY_PROP_HEALTH:
val->intval = motg->usbin_health;
break;
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ val->intval = otg_get_prop_usbin_voltage_now(motg);
+ break;
default:
return -EINVAL;
}
@@ -3740,6 +3769,7 @@
POWER_SUPPLY_PROP_CURRENT_MAX,
POWER_SUPPLY_PROP_SCOPE,
POWER_SUPPLY_PROP_TYPE,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
};
const struct file_operations msm_otg_bus_fops = {
@@ -4023,6 +4053,30 @@
pm_runtime_put(motg->phy.dev);
}
break;
+ case MSM_USB_EXT_CHG_VOLTAGE_INFO:
+ if (get_user(val, (int __user *)arg)) {
+ pr_err("%s: get_user failed\n\n", __func__);
+ ret = -EFAULT;
+ break;
+ }
+
+ if (val == USB_REQUEST_5V)
+ pr_debug("%s:voting 5V voltage request\n", __func__);
+ else if (val == USB_REQUEST_9V)
+ pr_debug("%s:voting 9V voltage request\n", __func__);
+ break;
+ case MSM_USB_EXT_CHG_RESULT:
+ if (get_user(val, (int __user *)arg)) {
+ pr_err("%s: get_user failed\n\n", __func__);
+ ret = -EFAULT;
+ break;
+ }
+
+ if (!val)
+ pr_debug("%s:voltage request successful\n", __func__);
+ else
+ pr_debug("%s:voltage request failed\n", __func__);
+ break;
default:
ret = -EINVAL;
}
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c
index ffbce45..1d8d91a 100644
--- a/drivers/video/au1100fb.c
+++ b/drivers/video/au1100fb.c
@@ -375,39 +375,13 @@
int au1100fb_fb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
{
struct au1100fb_device *fbdev;
- unsigned int len;
- unsigned long start=0, off;
fbdev = to_au1100fb_device(fbi);
- if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) {
- return -EINVAL;
- }
-
- start = fbdev->fb_phys & PAGE_MASK;
- len = PAGE_ALIGN((start & ~PAGE_MASK) + fbdev->fb_len);
-
- off = vma->vm_pgoff << PAGE_SHIFT;
-
- if ((vma->vm_end - vma->vm_start + off) > len) {
- return -EINVAL;
- }
-
- off += start;
- vma->vm_pgoff = off >> PAGE_SHIFT;
-
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
pgprot_val(vma->vm_page_prot) |= (6 << 9); //CCA=6
- vma->vm_flags |= VM_IO;
-
- if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
- vma->vm_end - vma->vm_start,
- vma->vm_page_prot)) {
- return -EAGAIN;
- }
-
- return 0;
+ return vm_iomap_memory(vma, fbdev->fb_phys, fbdev->fb_len);
}
static struct fb_ops au1100fb_ops =
diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c
index 7ca79f0..768f372 100644
--- a/drivers/video/au1200fb.c
+++ b/drivers/video/au1200fb.c
@@ -1235,36 +1235,12 @@
static int au1200fb_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
- unsigned int len;
- unsigned long start=0, off;
struct au1200fb_device *fbdev = info->par;
- if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) {
- return -EINVAL;
- }
-
- start = fbdev->fb_phys & PAGE_MASK;
- len = PAGE_ALIGN((start & ~PAGE_MASK) + fbdev->fb_len);
-
- off = vma->vm_pgoff << PAGE_SHIFT;
-
- if ((vma->vm_end - vma->vm_start + off) > len) {
- return -EINVAL;
- }
-
- off += start;
- vma->vm_pgoff = off >> PAGE_SHIFT;
-
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
pgprot_val(vma->vm_page_prot) |= _CACHE_MASK; /* CCA=7 */
- vma->vm_flags |= VM_IO;
-
- return io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
- vma->vm_end - vma->vm_start,
- vma->vm_page_prot);
-
- return 0;
+ return vm_iomap_memory(vma, fbdev->fb_phys, fbdev->fb_len);
}
static void set_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata)
diff --git a/drivers/video/msm/mdss/mdp3_ctrl.c b/drivers/video/msm/mdss/mdp3_ctrl.c
index 8b390ca..e4d8d0f 100644
--- a/drivers/video/msm/mdss/mdp3_ctrl.c
+++ b/drivers/video/msm/mdss/mdp3_ctrl.c
@@ -426,10 +426,10 @@
return format;
}
-static int mdp3_ctrl_get_pack_pattern(struct msm_fb_data_type *mfd)
+static int mdp3_ctrl_get_pack_pattern(u32 imgType)
{
int packPattern = MDP3_DMA_OUTPUT_PACK_PATTERN_RGB;
- if (mfd->fb_imgType == MDP_RGBA_8888)
+ if (imgType == MDP_RGBA_8888)
packPattern = MDP3_DMA_OUTPUT_PACK_PATTERN_BGR;
return packPattern;
}
@@ -530,7 +530,7 @@
outputConfig.out_sel = mdp3_ctrl_get_intf_type(mfd);
outputConfig.bit_mask_polarity = 0;
outputConfig.color_components_flip = 0;
- outputConfig.pack_pattern = mdp3_ctrl_get_pack_pattern(mfd);
+ outputConfig.pack_pattern = mdp3_ctrl_get_pack_pattern(mfd->fb_imgType);
outputConfig.pack_align = MDP3_DMA_OUTPUT_PACK_ALIGN_LSB;
outputConfig.color_comp_out_bits = (MDP3_DMA_OUTPUT_COMP_BITS_8 << 4) |
(MDP3_DMA_OUTPUT_COMP_BITS_8 << 2)|
@@ -895,6 +895,8 @@
dma->source_config.format != format) {
dma->source_config.format = format;
dma->source_config.stride = stride;
+ dma->output_config.pack_pattern =
+ mdp3_ctrl_get_pack_pattern(req->src.format);
mdp3_clk_enable(1, 0);
mdp3_session->dma->dma_config_source(dma);
mdp3_clk_enable(0, 0);
@@ -924,6 +926,8 @@
struct mdp3_dma *dma = mdp3_session->dma;
dma->source_config.format = format;
dma->source_config.stride = fix->line_length;
+ dma->output_config.pack_pattern =
+ mdp3_ctrl_get_pack_pattern(mfd->fb_imgType);
mdp3_clk_enable(1, 0);
mdp3_session->dma->dma_config_source(dma);
mdp3_clk_enable(0, 0);
diff --git a/drivers/video/msm/mdss/mdp3_dma.c b/drivers/video/msm/mdss/mdp3_dma.c
index 36d5cf1..800c4b3 100644
--- a/drivers/video/msm/mdss/mdp3_dma.c
+++ b/drivers/video/msm/mdss/mdp3_dma.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
@@ -339,6 +339,8 @@
dma_p_cfg_reg = MDP3_REG_READ(MDP3_REG_DMA_P_CONFIG);
dma_p_cfg_reg &= ~MDP3_DMA_IBUF_FORMAT_MASK;
dma_p_cfg_reg |= source_config->format << 25;
+ dma_p_cfg_reg &= ~MDP3_DMA_PACK_PATTERN_MASK;
+ dma_p_cfg_reg |= dma->output_config.pack_pattern << 8;
dma_p_size = source_config->width | (source_config->height << 16);
diff --git a/drivers/video/msm/mdss/mdp3_hwio.h b/drivers/video/msm/mdss/mdp3_hwio.h
index 39690ef..c40ee47 100644
--- a/drivers/video/msm/mdss/mdp3_hwio.h
+++ b/drivers/video/msm/mdss/mdp3_hwio.h
@@ -120,6 +120,7 @@
/*DMA MASK*/
#define MDP3_DMA_IBUF_FORMAT_MASK 0x06000000
+#define MDP3_DMA_PACK_PATTERN_MASK 0x00003f00
/*MISR*/
#define MDP3_REG_MODE_CLK 0x000D0000
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_dsi_panel.c b/drivers/video/msm/mdss/mdss_dsi_panel.c
index 6e44099..76e6d1b 100644
--- a/drivers/video/msm/mdss/mdss_dsi_panel.c
+++ b/drivers/video/msm/mdss/mdss_dsi_panel.c
@@ -815,11 +815,11 @@
pinfo->mipi.insert_dcs_cmd =
(!rc ? tmp : 1);
rc = of_property_read_u32(np,
- "qcom,mdss-dsi-te-v-sync-continue-lines", &tmp);
+ "qcom,mdss-dsi-wr-mem-continue", &tmp);
pinfo->mipi.wr_mem_continue =
(!rc ? tmp : 0x3c);
rc = of_property_read_u32(np,
- "qcom,mdss-dsi-te-v-sync-rd-ptr-irq-line", &tmp);
+ "qcom,mdss-dsi-wr-mem-start", &tmp);
pinfo->mipi.wr_mem_start =
(!rc ? tmp : 0x2c);
rc = of_property_read_u32(np,
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
index 41aaf61..1df2903 100644
--- a/drivers/video/msm/mdss/mdss_fb.c
+++ b/drivers/video/msm/mdss/mdss_fb.c
@@ -2309,13 +2309,6 @@
return -EEXIST;
}
- if ((fb_pdata->panel_info.type != MIPI_VIDEO_PANEL) ||
- (pdata->panel_info.type != MIPI_VIDEO_PANEL)) {
- pr_err("Split panel not supported for panel type %d\n",
- pdata->panel_info.type);
- return -EINVAL;
- }
-
fb_pdata->next = pdata;
return 0;
diff --git a/drivers/video/msm/mdss/mdss_hdmi_edid.c b/drivers/video/msm/mdss/mdss_hdmi_edid.c
index a45876b..d0b89a3 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_edid.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_edid.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-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
@@ -1120,7 +1120,7 @@
u8 i = 0, offset = 0, std_blk = 0;
u32 video_format = HDMI_VFRMT_640x480p60_4_3;
u32 has480p = false;
- u8 len;
+ u8 len = 0;
int rc;
const u8 *edid_blk0 = NULL;
const u8 *edid_blk1 = NULL;
@@ -1140,7 +1140,7 @@
hdmi_edid_find_block(data_buf+0x80, DBC_START_OFFSET,
VIDEO_DATA_BLOCK, &len) : NULL;
- if (svd == NULL || len == 0 || len > MAX_DATA_BLOCK_SIZE) {
+ if (num_of_cea_blocks && (len == 0 || len > MAX_DATA_BLOCK_SIZE)) {
DEV_DBG("%s: No/Invalid Video Data Block\n",
__func__);
return;
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..3ba851d 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -156,6 +156,9 @@
pr_err("Invalid decimation factors horz=%d vert=%d\n",
req->horz_deci, req->vert_deci);
return -EINVAL;
+ } else if (req->flags & MDP_BWC_EN) {
+ pr_err("Decimation can't be enabled with BWC\n");
+ return -EINVAL;
}
}
@@ -272,7 +275,8 @@
* requirement by applying vertical decimation and reduce
* mdp clock requirement
*/
- if (mdata->has_decimation && (pipe->vert_deci < MAX_DECIMATION))
+ if (mdata->has_decimation && (pipe->vert_deci < MAX_DECIMATION)
+ && !pipe->bwc_mode)
pipe->vert_deci++;
else
return -EPERM;
@@ -682,6 +686,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 +700,7 @@
break;
}
}
+ mdss_bus_bandwidth_ctrl(0);
data->num_planes = i;
@@ -704,8 +710,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;
@@ -1095,7 +1104,7 @@
struct mdss_mdp_pipe *pipe;
struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
u32 pipe_ndx, unset_ndx = 0;
- int i;
+ int i, destroy_pipe;
for (i = 0; unset_ndx != ndx && i < MDSS_MDP_MAX_SSPP; i++) {
pipe_ndx = BIT(i);
@@ -1106,16 +1115,22 @@
pr_warn("unknown pipe ndx=%x\n", pipe_ndx);
continue;
}
+
mutex_lock(&mfd->lock);
pipe->pid = 0;
+ destroy_pipe = pipe->play_cnt == 0;
+
if (!list_empty(&pipe->used_list)) {
list_del_init(&pipe->used_list);
- list_add(&pipe->cleanup_list,
- &mdp5_data->pipes_cleanup);
+ if (!destroy_pipe)
+ list_add(&pipe->cleanup_list,
+ &mdp5_data->pipes_cleanup);
}
mutex_unlock(&mfd->lock);
mdss_mdp_mixer_pipe_unstage(pipe);
mdss_mdp_pipe_unmap(pipe);
+ if (destroy_pipe)
+ mdss_mdp_pipe_destroy(pipe);
}
}
return 0;
@@ -2540,14 +2555,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_pipe.c b/drivers/video/msm/mdss/mdss_mdp_pipe.c
index 4999103..6db3eb6 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pipe.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pipe.c
@@ -672,16 +672,20 @@
pr_debug("ndx=%x pnum=%d ref_cnt=%d\n", pipe->ndx, pipe->num,
atomic_read(&pipe->ref_cnt));
- mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
- mdss_mdp_pipe_sspp_term(pipe);
- mdss_mdp_smp_free(pipe);
+ if (pipe->play_cnt) {
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
+ mdss_mdp_pipe_sspp_term(pipe);
+ mdss_mdp_smp_free(pipe);
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
+ } else {
+ mdss_mdp_smp_unreserve(pipe);
+ }
+
pipe->flags = 0;
pipe->bwc_mode = 0;
pipe->mfd = NULL;
memset(&pipe->scale, 0, sizeof(struct mdp_scale_data));
- mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
-
return 0;
}
@@ -815,6 +819,7 @@
pipe->src_fmt->bpp);
pipe->is_handed_off = true;
+ pipe->play_cnt = 1;
atomic_inc(&pipe->ref_cnt);
error:
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/diagchar.h b/include/linux/diagchar.h
index d525e84..f78d418 100644
--- a/include/linux/diagchar.h
+++ b/include/linux/diagchar.h
@@ -119,10 +119,10 @@
/* This needs to be modified manually now, when we add
a new RANGE of SSIDs to the msg_mask_tbl */
#define MSG_MASK_TBL_CNT 24
-#define EVENT_LAST_ID 0x09CB
+#define EVENT_LAST_ID 0x09F6
#define MSG_SSID_0 0
-#define MSG_SSID_0_LAST 97
+#define MSG_SSID_0_LAST 101
#define MSG_SSID_1 500
#define MSG_SSID_1_LAST 506
#define MSG_SSID_2 1000
@@ -138,7 +138,7 @@
#define MSG_SSID_7 4600
#define MSG_SSID_7_LAST 4614
#define MSG_SSID_8 5000
-#define MSG_SSID_8_LAST 5030
+#define MSG_SSID_8_LAST 5031
#define MSG_SSID_9 5500
#define MSG_SSID_9_LAST 5516
#define MSG_SSID_10 6000
@@ -154,7 +154,7 @@
#define MSG_SSID_15 8000
#define MSG_SSID_15_LAST 8000
#define MSG_SSID_16 8500
-#define MSG_SSID_16_LAST 8523
+#define MSG_SSID_16_LAST 8524
#define MSG_SSID_17 9000
#define MSG_SSID_17_LAST 9008
#define MSG_SSID_18 9500
@@ -166,7 +166,7 @@
#define MSG_SSID_21 10300
#define MSG_SSID_21_LAST 10300
#define MSG_SSID_22 10350
-#define MSG_SSID_22_LAST 10374
+#define MSG_SSID_22_LAST 10377
#define MSG_SSID_23 0xC000
#define MSG_SSID_23_LAST 0xC063
@@ -182,6 +182,7 @@
MSG_LVL_LOW,
MSG_LVL_ERROR,
MSG_LVL_LOW,
+ MSG_LVL_LOW,
MSG_LVL_MED,
MSG_LVL_MED,
MSG_LVL_HIGH,
@@ -280,7 +281,7 @@
MSG_LVL_LOW,
MSG_LVL_LOW,
MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL,
- MSG_LVL_MED,
+ MSG_LVL_LOW,
MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL,
MSG_LVL_LOW,
MSG_LVL_MED,
@@ -292,6 +293,10 @@
MSG_LVL_LOW,
MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL,
MSG_LVL_MED,
+ MSG_LVL_HIGH,
+ MSG_LVL_LOW,
+ MSG_LVL_HIGH,
+ MSG_LVL_HIGH
};
static const uint32_t msg_bld_masks_1[] = {
@@ -321,7 +326,8 @@
MSG_LVL_MED,
MSG_LVL_MED,
MSG_LVL_MED,
- MSG_LVL_MED,
+ MSG_LVL_MED|MSG_MASK_5|MSG_MASK_6|MSG_MASK_7|
+ MSG_MASK_8|MSG_MASK_9|MSG_MASK_10,
MSG_LVL_MED,
MSG_LVL_MED,
MSG_LVL_MED
@@ -439,6 +445,7 @@
MSG_LVL_MED,
MSG_LVL_MED,
MSG_LVL_MED,
+ MSG_LVL_MED,
MSG_LVL_MED
};
@@ -632,6 +639,7 @@
MSG_LVL_LOW,
MSG_LVL_LOW,
MSG_LVL_LOW,
+ MSG_LVL_LOW,
};
static const uint32_t msg_bld_masks_17[] = {
@@ -722,13 +730,16 @@
MSG_LVL_LOW,
MSG_LVL_LOW,
MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
MSG_LVL_LOW
};
/* LOG CODES */
static const uint32_t log_code_last_tbl[] = {
0x0, /* EQUIP ID 0 */
- 0x182F, /* EQUIP ID 1 */
+ 0x184A, /* EQUIP ID 1 */
0x0, /* EQUIP ID 2 */
0x0, /* EQUIP ID 3 */
0x4910, /* EQUIP ID 4 */
diff --git a/include/linux/input.h b/include/linux/input.h
index 558178b..77fc253 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -850,6 +850,7 @@
#define SW_HPHL_OVERCURRENT 0x0e /* set = over current on left hph */
#define SW_HPHR_OVERCURRENT 0x0f /* set = over current on right hph */
#define SW_UNSUPPORT_INSERT 0x10 /* set = unsupported device inserted */
+#define SW_MICROPHONE2_INSERT 0x11 /* set = inserted */
#define SW_MAX 0x20
#define SW_CNT (SW_MAX+1)
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 1740576..272fe77 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -355,6 +355,7 @@
/* Skip data-timeout advertised by card */
#define MMC_QUIRK_BROKEN_DATA_TIMEOUT (1<<12)
+#define MMC_QUIRK_CACHE_DISABLE (1 << 14) /* prevent cache enable */
unsigned int erase_size; /* erase size in sectors */
unsigned int erase_shift; /* if erase unit is power 2 */
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/qpnp/qpnp-adc.h b/include/linux/qpnp/qpnp-adc.h
index 2b47b88..13eb461 100644
--- a/include/linux/qpnp/qpnp-adc.h
+++ b/include/linux/qpnp/qpnp-adc.h
@@ -574,12 +574,10 @@
/**
* enum qpnp_adc_meas_timer_select - Selects the timer for which
* the appropriate polling frequency is set.
- * %ADC_MEAS_TIMER_SELECT1 - Select this timer if the client is USB_ID.
- * %ADC_MEAS_TIMER_SELECT2 - Select this timer if the client is batt_therm.
- * %ADC_MEAS_TIMER_SELECT3 - The timer is added only for completion. It is
- * not used by kernel space clients and user space clients cannot set
- * the polling frequency. The driver will set a appropriate polling
- * frequency to measure the user space clients from qpnp_adc_meas_timer_3.
+ * %ADC_MEAS_TIMER_SELECT1 - Select this timer for measurement polling interval
+ * for 1 second.
+ * %ADC_MEAS_TIMER_SELECT2 - Select this timer for 500ms measurement interval.
+ * %ADC_MEAS_TIMER_SELECT3 - Select this timer for 5 second interval.
*/
enum qpnp_adc_meas_timer_select {
ADC_MEAS_TIMER_SELECT1 = 0,
diff --git a/include/linux/regulator/cpr-regulator.h b/include/linux/regulator/cpr-regulator.h
index 3b23d17..9d06a8c 100644
--- a/include/linux/regulator/cpr-regulator.h
+++ b/include/linux/regulator/cpr-regulator.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -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,33 +67,21 @@
};
/**
- * 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
* %VDD_MX_VMIN_APC_SLOW_CORNER_CEILING:
* Equal to slow speed corner ceiling
* %VDD_MX_VMIN_MX_VMAX: Equal to specified vdd-mx-vmax voltage
+ * %VDD_MX_VMIN_APC_CORNER_MAP: Equal to the APC corner mapped MX
+ * voltage
*/
enum vdd_mx_vmin_method {
VDD_MX_VMIN_APC,
VDD_MX_VMIN_APC_CORNER_CEILING,
VDD_MX_VMIN_APC_SLOW_CORNER_CEILING,
VDD_MX_VMIN_MX_VMAX,
+ VDD_MX_VMIN_APC_CORNER_MAP,
};
#ifdef CONFIG_MSM_CPR_REGULATOR
diff --git a/include/linux/usb/msm_ext_chg.h b/include/linux/usb/msm_ext_chg.h
index dcc786d..596ab49 100644
--- a/include/linux/usb/msm_ext_chg.h
+++ b/include/linux/usb/msm_ext_chg.h
@@ -6,6 +6,8 @@
#define USB_CHG_BLOCK_ULPI 1
#define USB_CHG_BLOCK_QSCRATCH 2
+#define USB_REQUEST_5V 1
+#define USB_REQUEST_9V 2
/**
* struct msm_usb_chg_info - MSM USB charger block details.
* @chg_block_type: The type of charger block. QSCRATCH/ULPI.
@@ -28,4 +30,10 @@
/* Vote against USB hardware low power mode */
#define MSM_USB_EXT_CHG_BLOCK_LPM _IOW('M', 1, int)
+/* To tell kernel about voltage being voted */
+#define MSM_USB_EXT_CHG_VOLTAGE_INFO _IOW('M', 2, int)
+
+/* To tell kernel about voltage request result */
+#define MSM_USB_EXT_CHG_RESULT _IOW('M', 3, int)
+
#endif /* __LINUX_USB_MSM_EXT_CHG_H */
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 862a0cc..d16448a 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -464,6 +464,7 @@
struct completion ext_chg_wait;
int ui_enabled;
bool pm_done;
+ struct qpnp_vadc_chip *vadc_dev;
};
struct ci13xxx_platform_data {
diff --git a/include/media/msm_cam_sensor.h b/include/media/msm_cam_sensor.h
index 38d3aab..e301d8f 100644
--- a/include/media/msm_cam_sensor.h
+++ b/include/media/msm_cam_sensor.h
@@ -47,6 +47,7 @@
#define MAX_EEPROM_NAME 32
#define MAX_AF_ITERATIONS 3
+#define MAX_NUMBER_OF_STEPS 47
enum flash_type {
LED_FLASH = 1,
@@ -93,6 +94,8 @@
SENSOR_GPIO_VANA,
SENSOR_GPIO_VDIG,
SENSOR_GPIO_VAF,
+ SENSOR_GPIO_FL_EN,
+ SENSOR_GPIO_FL_NOW,
SENSOR_GPIO_MAX,
};
@@ -220,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 {
@@ -227,7 +232,25 @@
uint16_t sensor_id;
};
+enum msm_sensor_camera_id_t {
+ CAMERA_0,
+ CAMERA_1,
+ CAMERA_2,
+ CAMERA_3,
+ MAX_CAMERAS,
+};
+
+enum cci_i2c_master_t {
+ MASTER_0,
+ MASTER_1,
+ MASTER_MAX,
+};
+
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;
struct msm_sensor_id_info_t sensor_id_info;
@@ -317,10 +340,19 @@
uint8_t csi_phy_sel;
};
+enum camb_position_t {
+ BACK_CAMERA_B,
+ FRONT_CAMERA_B,
+};
+
struct msm_sensor_info_t {
- char sensor_name[MAX_SENSOR_NAME];
- int32_t session_id;
- int32_t subdev_id[SUB_MODULE_MAX];
+ char sensor_name[MAX_SENSOR_NAME];
+ int32_t session_id;
+ int32_t subdev_id[SUB_MODULE_MAX];
+ uint8_t is_mount_angle_valid;
+ uint32_t sensor_mount_angle;
+ int modes_supported;
+ enum camb_position_t position;
};
struct camera_vreg_t {
@@ -332,11 +364,6 @@
uint32_t delay;
};
-enum camb_position_t {
- BACK_CAMERA_B,
- FRONT_CAMERA_B,
-};
-
enum camerab_mode_t {
CAMERA_MODE_2D_B = (1<<0),
CAMERA_MODE_3D_B = (1<<1)
@@ -381,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 {
@@ -397,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;
@@ -405,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;
};
@@ -440,6 +475,7 @@
CFG_GET_ACTUATOR_INFO,
CFG_SET_ACTUATOR_INFO,
CFG_SET_DEFAULT_FOCUS,
+ CFG_SET_POSITION,
CFG_MOVE_FOCUS,
};
@@ -538,6 +574,13 @@
ACTUATOR_WEB_CAM_2,
};
+
+struct msm_actuator_set_position_t {
+ uint16_t number_of_steps;
+ uint16_t pos[MAX_NUMBER_OF_STEPS];
+ uint16_t delay[MAX_NUMBER_OF_STEPS];
+};
+
struct msm_actuator_cfg_data {
int cfgtype;
uint8_t is_af_supported;
@@ -545,6 +588,7 @@
struct msm_actuator_move_params_t move;
struct msm_actuator_set_info_t set_info;
struct msm_actuator_get_info_t get_info;
+ struct msm_actuator_set_position_t setpos;
enum af_camera_name cam_name;
} cfg;
};
@@ -576,6 +620,20 @@
uint32_t flash_current[2];
};
+/* sensor init structures and enums */
+enum msm_sensor_init_cfg_type_t {
+ CFG_SINIT_PROBE,
+ CFG_SINIT_PROBE_DONE,
+ CFG_SINIT_PROBE_WAIT_DONE,
+};
+
+struct sensor_init_cfg_data {
+ enum msm_sensor_init_cfg_type_t cfgtype;
+ union {
+ void *setting;
+ } cfg;
+};
+
#define VIDIOC_MSM_SENSOR_CFG \
_IOWR('V', BASE_VIDIOC_PRIVATE + 1, struct sensorb_cfg_data)
@@ -603,6 +661,9 @@
#define VIDIOC_MSM_SENSOR_GET_AF_STATUS \
_IOWR('V', BASE_VIDIOC_PRIVATE + 9, uint32_t)
+#define VIDIOC_MSM_SENSOR_INIT_CFG \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 10, struct sensor_init_cfg_data)
+
#define MSM_V4L2_PIX_FMT_META v4l2_fourcc('M', 'E', 'T', 'A') /* META */
#endif /* __LINUX_MSM_CAM_SENSOR_H */
diff --git a/include/media/msmb_camera.h b/include/media/msmb_camera.h
index 62e7b27..a4f5a01 100644
--- a/include/media/msmb_camera.h
+++ b/include/media/msmb_camera.h
@@ -36,6 +36,7 @@
#define MSM_CAMERA_SUBDEV_LED_FLASH 11
#define MSM_CAMERA_SUBDEV_STROBE_FLASH 12
#define MSM_CAMERA_SUBDEV_BUF_MNGR 13
+#define MSM_CAMERA_SUBDEV_SENSOR_INIT 14
#define MSM_MAX_CAMERA_SENSORS 5
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/include/net/ipv6.h b/include/net/ipv6.h
index e4170a2..a5a9e4d 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -252,6 +252,14 @@
atomic_dec(&fl->users);
}
+extern void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info);
+
+int icmpv6_push_pending_frames(struct sock *sk, struct flowi6 *fl6,
+ struct icmp6hdr *thdr, int len);
+
+struct dst_entry *icmpv6_route_lookup(struct net *net, struct sk_buff *skb,
+ struct sock *sk, struct flowi6 *fl6);
+
extern int ip6_ra_control(struct sock *sk, int sel);
extern int ipv6_parse_hopopts(struct sk_buff *skb);
@@ -294,6 +302,18 @@
return __ipv6_addr_src_scope(__ipv6_addr_type(addr));
}
+static inline bool __ipv6_addr_needs_scope_id(int type)
+{
+ return type & IPV6_ADDR_LINKLOCAL ||
+ (type & IPV6_ADDR_MULTICAST &&
+ (type & (IPV6_ADDR_LOOPBACK|IPV6_ADDR_LINKLOCAL)));
+}
+
+static inline __u32 ipv6_iface_scope_id(const struct in6_addr *addr, int iface)
+{
+ return __ipv6_addr_needs_scope_id(__ipv6_addr_type(addr)) ? iface : 0;
+}
+
static inline int ipv6_addr_cmp(const struct in6_addr *a1, const struct in6_addr *a2)
{
return memcmp(a1, a2, sizeof(struct in6_addr));
diff --git a/include/net/ping.h b/include/net/ping.h
index 682b5ae..b1717ae 100644
--- a/include/net/ping.h
+++ b/include/net/ping.h
@@ -13,6 +13,7 @@
#ifndef _PING_H
#define _PING_H
+#include <net/icmp.h>
#include <net/netns/hash.h>
/* PING_HTABLE_SIZE must be power of 2 */
@@ -28,6 +29,18 @@
*/
#define GID_T_MAX (((gid_t)~0U) >> 1)
+/* Compatibility glue so we can support IPv6 when it's compiled as a module */
+struct pingv6_ops {
+ int (*ipv6_recv_error)(struct sock *sk, struct msghdr *msg, int len);
+ int (*datagram_recv_ctl)(struct sock *sk, struct msghdr *msg,
+ struct sk_buff *skb);
+ int (*icmpv6_err_convert)(u8 type, u8 code, int *err);
+ void (*ipv6_icmp_error)(struct sock *sk, struct sk_buff *skb, int err,
+ __be16 port, u32 info, u8 *payload);
+ int (*ipv6_chk_addr)(struct net *net, const struct in6_addr *addr,
+ struct net_device *dev, int strict);
+};
+
struct ping_table {
struct hlist_nulls_head hash[PING_HTABLE_SIZE];
rwlock_t lock;
@@ -39,10 +52,40 @@
};
extern struct proto ping_prot;
+extern struct ping_table ping_table;
+#if IS_ENABLED(CONFIG_IPV6)
+extern struct pingv6_ops pingv6_ops;
+#endif
+struct pingfakehdr {
+ struct icmphdr icmph;
+ struct iovec *iov;
+ sa_family_t family;
+ __wsum wcheck;
+};
-extern void ping_rcv(struct sk_buff *);
-extern void ping_err(struct sk_buff *, u32 info);
+int ping_get_port(struct sock *sk, unsigned short ident);
+void ping_hash(struct sock *sk);
+void ping_unhash(struct sock *sk);
+
+int ping_init_sock(struct sock *sk);
+void ping_close(struct sock *sk, long timeout);
+int ping_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len);
+void ping_err(struct sk_buff *skb, int offset, u32 info);
+void ping_v4_err(struct sk_buff *skb, u32 info);
+int ping_getfrag(void *from, char *to, int offset, int fraglen, int odd,
+ struct sk_buff *);
+
+int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
+ size_t len, int noblock, int flags, int *addr_len);
+int ping_common_sendmsg(int family, struct msghdr *msg, size_t len,
+ void *user_icmph, size_t icmph_len);
+int ping_v4_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
+ size_t len);
+int ping_v6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
+ size_t len);
+int ping_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);
+void ping_rcv(struct sk_buff *skb);
#ifdef CONFIG_PROC_FS
extern int __init ping_proc_init(void);
@@ -50,6 +93,7 @@
#endif
void __init ping_init(void);
-
+int __init pingv6_init(void);
+void pingv6_exit(void);
#endif /* _PING_H */
diff --git a/include/net/transp_v6.h b/include/net/transp_v6.h
index 498433d..48b42ea 100644
--- a/include/net/transp_v6.h
+++ b/include/net/transp_v6.h
@@ -11,6 +11,7 @@
extern struct proto udpv6_prot;
extern struct proto udplitev6_prot;
extern struct proto tcpv6_prot;
+extern struct proto pingv6_prot;
struct flowi6;
@@ -21,6 +22,8 @@
extern void ipv6_frag_exit(void);
/* transport protocols */
+extern int pingv6_init(void);
+extern void pingv6_exit(void);
extern int rawv6_init(void);
extern void rawv6_exit(void);
extern int udpv6_init(void);
diff --git a/include/sound/jack.h b/include/sound/jack.h
index 8e8c133..4a88c22 100644
--- a/include/sound/jack.h
+++ b/include/sound/jack.h
@@ -47,6 +47,9 @@
SND_JACK_OC_HPHL = 0x0000040,
SND_JACK_OC_HPHR = 0x0000080,
SND_JACK_UNSUPPORTED = 0x0000100,
+ SND_JACK_MICROPHONE2 = 0x0000200,
+ SND_JACK_ANC_HEADPHONE = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE |
+ SND_JACK_MICROPHONE2,
/* Kept separate from switches to facilitate implementation */
SND_JACK_BTN_0 = 0x4000000,
SND_JACK_BTN_1 = 0x2000000,
diff --git a/include/sound/q6asm-v2.h b/include/sound/q6asm-v2.h
index a78c333..1635fc3 100644
--- a/include/sound/q6asm-v2.h
+++ b/include/sound/q6asm-v2.h
@@ -72,6 +72,7 @@
#define SYNC_IO_MODE 0x0001
#define ASYNC_IO_MODE 0x0002
#define COMPRESSED_IO 0x0040
+#define COMPRESSED_STREAM_IO 0x0080
#define NT_MODE 0x0400
#define NO_TIMESTAMP 0xFF00
@@ -399,4 +400,8 @@
int q6asm_send_meta_data(struct audio_client *ac, uint32_t initial_samples,
uint32_t trailing_samples);
+/* Send the stream meta data to remove initial and trailing silence */
+int q6asm_stream_send_meta_data(struct audio_client *ac, uint32_t stream_id,
+ uint32_t initial_samples, uint32_t trailing_samples);
+
#endif /* __Q6_ASM_H__ */
diff --git a/lib/scatterlist.c b/lib/scatterlist.c
index 6096e89..547a01f 100644
--- a/lib/scatterlist.c
+++ b/lib/scatterlist.c
@@ -228,12 +228,14 @@
struct scatterlist *sg, *prv;
unsigned int left;
+ memset(table, 0, sizeof(*table));
+
+ if (nents == 0)
+ return -EINVAL;
#ifndef ARCH_HAS_SG_CHAIN
BUG_ON(nents > max_ents);
#endif
- memset(table, 0, sizeof(*table));
-
left = nents;
prv = NULL;
do {
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index a5e8dc2..d012c75 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -190,6 +190,18 @@
zone_reclaimable_pages(z) - z->dirty_balance_reserve;
}
/*
+ * Unreclaimable memory (kernel memory or anonymous memory
+ * without swap) can bring down the dirtyable pages below
+ * the zone's dirty balance reserve and the above calculation
+ * will underflow. However we still want to add in nodes
+ * which are below threshold (negative values) to get a more
+ * accurate calculation but make sure that the total never
+ * underflows.
+ */
+ if ((long)x < 0)
+ x = 0;
+
+ /*
* Make sure that the number of highmem pages is never larger
* than the number of the total dirtyable memory. This can only
* occur in very strange VM situations but we want to make sure
@@ -211,8 +223,8 @@
{
unsigned long x;
- x = global_page_state(NR_FREE_PAGES) + global_reclaimable_pages() -
- dirty_balance_reserve;
+ x = global_page_state(NR_FREE_PAGES) + global_reclaimable_pages();
+ x -= min(x, dirty_balance_reserve);
if (!vm_highmem_is_dirtyable)
x -= highmem_dirtyable_memory(x);
@@ -279,9 +291,12 @@
* highmem zone can hold its share of dirty pages, so we don't
* care about vm_highmem_is_dirtyable here.
*/
- return zone_page_state(zone, NR_FREE_PAGES) +
- zone_reclaimable_pages(zone) -
- zone->dirty_balance_reserve;
+ unsigned long nr_pages = zone_page_state(zone, NR_FREE_PAGES) +
+ zone_reclaimable_pages(zone);
+
+ /* don't allow this to underflow */
+ nr_pages -= min(nr_pages, zone->dirty_balance_reserve);
+ return nr_pages;
}
/**
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index f20b5cc..b848d6f 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1559,7 +1559,7 @@
static const struct net_protocol icmp_protocol = {
.handler = icmp_rcv,
- .err_handler = ping_err,
+ .err_handler = ping_v4_err,
.no_policy = 1,
.netns_ok = 1,
};
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 2cb2bf8..2e109ff 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -788,7 +788,7 @@
if (iph->protocol == IPPROTO_ICMP &&
iph->ihl >= 5 &&
pskb_may_pull(skb, (iph->ihl<<2)+8)) {
- ping_err(skb, icmp_hdr(skb)->un.gateway);
+ ping_v4_err(skb, icmp_hdr(skb)->un.gateway);
}
out:
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index 50009c7..7f38d35 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -33,7 +33,6 @@
#include <linux/netdevice.h>
#include <net/snmp.h>
#include <net/ip.h>
-#include <net/ipv6.h>
#include <net/icmp.h>
#include <net/protocol.h>
#include <linux/skbuff.h>
@@ -46,8 +45,18 @@
#include <net/inet_common.h>
#include <net/checksum.h>
+#if IS_ENABLED(CONFIG_IPV6)
+#include <linux/in6.h>
+#include <linux/icmpv6.h>
+#include <net/addrconf.h>
+#include <net/ipv6.h>
+#include <net/transp_v6.h>
+#endif
-static struct ping_table ping_table;
+
+struct ping_table ping_table;
+struct pingv6_ops pingv6_ops;
+EXPORT_SYMBOL_GPL(pingv6_ops);
static u16 ping_port_rover;
@@ -57,6 +66,7 @@
pr_debug("hash(%d) = %d\n", num, res);
return res;
}
+EXPORT_SYMBOL_GPL(ping_hash);
static inline struct hlist_nulls_head *ping_hashslot(struct ping_table *table,
struct net *net, unsigned num)
@@ -64,7 +74,7 @@
return &table->hash[ping_hashfn(net, num, PING_HTABLE_MASK)];
}
-static int ping_v4_get_port(struct sock *sk, unsigned short ident)
+int ping_get_port(struct sock *sk, unsigned short ident)
{
struct hlist_nulls_node *node;
struct hlist_nulls_head *hlist;
@@ -102,6 +112,10 @@
ping_portaddr_for_each_entry(sk2, node, hlist) {
isk2 = inet_sk(sk2);
+ /* BUG? Why is this reuse and not reuseaddr? ping.c
+ * doesn't turn off SO_REUSEADDR, and it doesn't expect
+ * that other ping processes can steal its packets.
+ */
if ((isk2->inet_num == ident) &&
(sk2 != sk) &&
(!sk2->sk_reuse || !sk->sk_reuse))
@@ -124,17 +138,18 @@
write_unlock_bh(&ping_table.lock);
return 1;
}
+EXPORT_SYMBOL_GPL(ping_get_port);
-static void ping_v4_hash(struct sock *sk)
+void ping_hash(struct sock *sk)
{
- pr_debug("ping_v4_hash(sk->port=%u)\n", inet_sk(sk)->inet_num);
+ pr_debug("ping_hash(sk->port=%u)\n", inet_sk(sk)->inet_num);
BUG(); /* "Please do not press this button again." */
}
-static void ping_v4_unhash(struct sock *sk)
+void ping_unhash(struct sock *sk)
{
struct inet_sock *isk = inet_sk(sk);
- pr_debug("ping_v4_unhash(isk=%p,isk->num=%u)\n", isk, isk->inet_num);
+ pr_debug("ping_unhash(isk=%p,isk->num=%u)\n", isk, isk->inet_num);
if (sk_hashed(sk)) {
write_lock_bh(&ping_table.lock);
hlist_nulls_del(&sk->sk_nulls_node);
@@ -145,31 +160,61 @@
write_unlock_bh(&ping_table.lock);
}
}
+EXPORT_SYMBOL_GPL(ping_unhash);
-static struct sock *ping_v4_lookup(struct net *net, __be32 saddr, __be32 daddr,
- u16 ident, int dif)
+static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident)
{
struct hlist_nulls_head *hslot = ping_hashslot(&ping_table, net, ident);
struct sock *sk = NULL;
struct inet_sock *isk;
struct hlist_nulls_node *hnode;
+ int dif = skb->dev->ifindex;
- pr_debug("try to find: num = %d, daddr = %pI4, dif = %d\n",
- (int)ident, &daddr, dif);
+ if (skb->protocol == htons(ETH_P_IP)) {
+ pr_debug("try to find: num = %d, daddr = %pI4, dif = %d\n",
+ (int)ident, &ip_hdr(skb)->daddr, dif);
+#if IS_ENABLED(CONFIG_IPV6)
+ } else if (skb->protocol == htons(ETH_P_IPV6)) {
+ pr_debug("try to find: num = %d, daddr = %pI6c, dif = %d\n",
+ (int)ident, &ipv6_hdr(skb)->daddr, dif);
+#endif
+ }
+
read_lock_bh(&ping_table.lock);
ping_portaddr_for_each_entry(sk, hnode, hslot) {
isk = inet_sk(sk);
- pr_debug("found: %p: num = %d, daddr = %pI4, dif = %d\n", sk,
- (int)isk->inet_num, &isk->inet_rcv_saddr,
- sk->sk_bound_dev_if);
-
pr_debug("iterate\n");
if (isk->inet_num != ident)
continue;
- if (isk->inet_rcv_saddr && isk->inet_rcv_saddr != daddr)
- continue;
+
+ if (skb->protocol == htons(ETH_P_IP) &&
+ sk->sk_family == AF_INET) {
+ pr_debug("found: %p: num=%d, daddr=%pI4, dif=%d\n", sk,
+ (int) isk->inet_num, &isk->inet_rcv_saddr,
+ sk->sk_bound_dev_if);
+
+ if (isk->inet_rcv_saddr &&
+ isk->inet_rcv_saddr != ip_hdr(skb)->daddr)
+ continue;
+#if IS_ENABLED(CONFIG_IPV6)
+ } else if (skb->protocol == htons(ETH_P_IPV6) &&
+ sk->sk_family == AF_INET6) {
+ struct ipv6_pinfo *np = inet6_sk(sk);
+
+ pr_debug("found: %p: num=%d, daddr=%pI6c, dif=%d\n", sk,
+ (int) isk->inet_num,
+ &inet6_sk(sk)->rcv_saddr,
+ sk->sk_bound_dev_if);
+
+ if (!ipv6_addr_any(&np->rcv_saddr) &&
+ !ipv6_addr_equal(&np->rcv_saddr,
+ &ipv6_hdr(skb)->daddr))
+ continue;
+#endif
+ }
+
if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif)
continue;
@@ -198,7 +243,7 @@
}
-static int ping_init_sock(struct sock *sk)
+int ping_init_sock(struct sock *sk)
{
struct net *net = sock_net(sk);
gid_t group = current_egid();
@@ -224,8 +269,9 @@
return -EACCES;
}
+EXPORT_SYMBOL_GPL(ping_init_sock);
-static void ping_close(struct sock *sk, long timeout)
+void ping_close(struct sock *sk, long timeout)
{
pr_debug("ping_close(sk=%p,sk->num=%u)\n",
inet_sk(sk), inet_sk(sk)->inet_num);
@@ -233,36 +279,122 @@
sk_common_release(sk);
}
+EXPORT_SYMBOL_GPL(ping_close);
+/* Checks the bind address and possibly modifies sk->sk_bound_dev_if. */
+int ping_check_bind_addr(struct sock *sk, struct inet_sock *isk,
+ struct sockaddr *uaddr, int addr_len) {
+ struct net *net = sock_net(sk);
+ if (sk->sk_family == AF_INET) {
+ struct sockaddr_in *addr = (struct sockaddr_in *) uaddr;
+ int chk_addr_ret;
+
+ if (addr_len < sizeof(*addr))
+ return -EINVAL;
+
+ pr_debug("ping_check_bind_addr(sk=%p,addr=%pI4,port=%d)\n",
+ sk, &addr->sin_addr.s_addr, ntohs(addr->sin_port));
+
+ chk_addr_ret = inet_addr_type(net, addr->sin_addr.s_addr);
+
+ if (addr->sin_addr.s_addr == htonl(INADDR_ANY))
+ chk_addr_ret = RTN_LOCAL;
+
+ if ((sysctl_ip_nonlocal_bind == 0 &&
+ isk->freebind == 0 && isk->transparent == 0 &&
+ chk_addr_ret != RTN_LOCAL) ||
+ chk_addr_ret == RTN_MULTICAST ||
+ chk_addr_ret == RTN_BROADCAST)
+ return -EADDRNOTAVAIL;
+
+#if IS_ENABLED(CONFIG_IPV6)
+ } else if (sk->sk_family == AF_INET6) {
+ struct sockaddr_in6 *addr = (struct sockaddr_in6 *) uaddr;
+ int addr_type, scoped, has_addr;
+ struct net_device *dev = NULL;
+
+ if (addr_len < sizeof(*addr))
+ return -EINVAL;
+
+ pr_debug("ping_check_bind_addr(sk=%p,addr=%pI6c,port=%d)\n",
+ sk, addr->sin6_addr.s6_addr, ntohs(addr->sin6_port));
+
+ addr_type = ipv6_addr_type(&addr->sin6_addr);
+ scoped = __ipv6_addr_needs_scope_id(addr_type);
+ if ((addr_type != IPV6_ADDR_ANY &&
+ !(addr_type & IPV6_ADDR_UNICAST)) ||
+ (scoped && !addr->sin6_scope_id))
+ return -EINVAL;
+
+ rcu_read_lock();
+ if (addr->sin6_scope_id) {
+ dev = dev_get_by_index_rcu(net, addr->sin6_scope_id);
+ if (!dev) {
+ rcu_read_unlock();
+ return -ENODEV;
+ }
+ }
+ has_addr = pingv6_ops.ipv6_chk_addr(net, &addr->sin6_addr, dev,
+ scoped);
+ rcu_read_unlock();
+
+ if (!(isk->freebind || isk->transparent || has_addr ||
+ addr_type == IPV6_ADDR_ANY))
+ return -EADDRNOTAVAIL;
+
+ if (scoped)
+ sk->sk_bound_dev_if = addr->sin6_scope_id;
+#endif
+ } else {
+ return -EAFNOSUPPORT;
+ }
+ return 0;
+}
+
+void ping_set_saddr(struct sock *sk, struct sockaddr *saddr)
+{
+ if (saddr->sa_family == AF_INET) {
+ struct inet_sock *isk = inet_sk(sk);
+ struct sockaddr_in *addr = (struct sockaddr_in *) saddr;
+ isk->inet_rcv_saddr = isk->inet_saddr = addr->sin_addr.s_addr;
+#if IS_ENABLED(CONFIG_IPV6)
+ } else if (saddr->sa_family == AF_INET6) {
+ struct sockaddr_in6 *addr = (struct sockaddr_in6 *) saddr;
+ struct ipv6_pinfo *np = inet6_sk(sk);
+ np->rcv_saddr = np->saddr = addr->sin6_addr;
+#endif
+ }
+}
+
+void ping_clear_saddr(struct sock *sk, int dif)
+{
+ sk->sk_bound_dev_if = dif;
+ if (sk->sk_family == AF_INET) {
+ struct inet_sock *isk = inet_sk(sk);
+ isk->inet_rcv_saddr = isk->inet_saddr = 0;
+#if IS_ENABLED(CONFIG_IPV6)
+ } else if (sk->sk_family == AF_INET6) {
+ struct ipv6_pinfo *np = inet6_sk(sk);
+ memset(&np->rcv_saddr, 0, sizeof(np->rcv_saddr));
+ memset(&np->saddr, 0, sizeof(np->saddr));
+#endif
+ }
+}
/*
* We need our own bind because there are no privileged id's == local ports.
* Moreover, we don't allow binding to multi- and broadcast addresses.
*/
-static int ping_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
+int ping_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
{
- struct sockaddr_in *addr = (struct sockaddr_in *)uaddr;
struct inet_sock *isk = inet_sk(sk);
unsigned short snum;
- int chk_addr_ret;
int err;
+ int dif = sk->sk_bound_dev_if;
- if (addr_len < sizeof(struct sockaddr_in))
- return -EINVAL;
-
- pr_debug("ping_v4_bind(sk=%p,sa_addr=%08x,sa_port=%d)\n",
- sk, addr->sin_addr.s_addr, ntohs(addr->sin_port));
-
- chk_addr_ret = inet_addr_type(sock_net(sk), addr->sin_addr.s_addr);
- if (addr->sin_addr.s_addr == htonl(INADDR_ANY))
- chk_addr_ret = RTN_LOCAL;
-
- if ((sysctl_ip_nonlocal_bind == 0 &&
- isk->freebind == 0 && isk->transparent == 0 &&
- chk_addr_ret != RTN_LOCAL) ||
- chk_addr_ret == RTN_MULTICAST ||
- chk_addr_ret == RTN_BROADCAST)
- return -EADDRNOTAVAIL;
+ err = ping_check_bind_addr(sk, isk, uaddr, addr_len);
+ if (err)
+ return err;
lock_sock(sk);
@@ -271,42 +403,50 @@
goto out;
err = -EADDRINUSE;
- isk->inet_rcv_saddr = isk->inet_saddr = addr->sin_addr.s_addr;
- snum = ntohs(addr->sin_port);
- if (ping_v4_get_port(sk, snum) != 0) {
- isk->inet_saddr = isk->inet_rcv_saddr = 0;
+ ping_set_saddr(sk, uaddr);
+ snum = ntohs(((struct sockaddr_in *)uaddr)->sin_port);
+ if (ping_get_port(sk, snum) != 0) {
+ ping_clear_saddr(sk, dif);
goto out;
}
- pr_debug("after bind(): num = %d, daddr = %pI4, dif = %d\n",
+ pr_debug("after bind(): num = %d, dif = %d\n",
(int)isk->inet_num,
- &isk->inet_rcv_saddr,
(int)sk->sk_bound_dev_if);
err = 0;
- if (isk->inet_rcv_saddr)
+ if ((sk->sk_family == AF_INET && isk->inet_rcv_saddr) ||
+ (sk->sk_family == AF_INET6 &&
+ !ipv6_addr_any(&inet6_sk(sk)->rcv_saddr)))
sk->sk_userlocks |= SOCK_BINDADDR_LOCK;
+
if (snum)
sk->sk_userlocks |= SOCK_BINDPORT_LOCK;
isk->inet_sport = htons(isk->inet_num);
isk->inet_daddr = 0;
isk->inet_dport = 0;
+
+#if IS_ENABLED(CONFIG_IPV6)
+ if (sk->sk_family == AF_INET6)
+ memset(&inet6_sk(sk)->daddr, 0, sizeof(inet6_sk(sk)->daddr));
+#endif
+
sk_dst_reset(sk);
out:
release_sock(sk);
pr_debug("ping_v4_bind -> %d\n", err);
return err;
}
+EXPORT_SYMBOL_GPL(ping_bind);
/*
* Is this a supported type of ICMP message?
*/
-static inline int ping_supported(int type, int code)
+static inline int ping_supported(int family, int type, int code)
{
- if (type == ICMP_ECHO && code == 0)
- return 1;
- return 0;
+ return (family == AF_INET && type == ICMP_ECHO && code == 0) ||
+ (family == AF_INET6 && type == ICMPV6_ECHO_REQUEST && code == 0);
}
/*
@@ -314,30 +454,44 @@
* sort of error condition.
*/
-static int ping_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);
-
-void ping_err(struct sk_buff *skb, u32 info)
+void ping_err(struct sk_buff *skb, int offset, u32 info)
{
- struct iphdr *iph = (struct iphdr *)skb->data;
- struct icmphdr *icmph = (struct icmphdr *)(skb->data+(iph->ihl<<2));
+ int family;
+ struct icmphdr *icmph;
struct inet_sock *inet_sock;
- int type = icmph->type;
- int code = icmph->code;
+ int type;
+ int code;
struct net *net = dev_net(skb->dev);
struct sock *sk;
int harderr;
int err;
+ if (skb->protocol == htons(ETH_P_IP)) {
+ struct iphdr *iph = (struct iphdr *)skb->data;
+ offset = iph->ihl << 2;
+ family = AF_INET;
+ type = icmp_hdr(skb)->type;
+ code = icmp_hdr(skb)->code;
+ icmph = (struct icmphdr *)(skb->data + offset);
+ } else if (skb->protocol == htons(ETH_P_IPV6)) {
+ family = AF_INET6;
+ type = icmp6_hdr(skb)->icmp6_type;
+ code = icmp6_hdr(skb)->icmp6_code;
+ icmph = (struct icmphdr *) (skb->data + offset);
+ } else {
+ BUG();
+ }
+
/* We assume the packet has already been checked by icmp_unreach */
- if (!ping_supported(icmph->type, icmph->code))
+ if (!ping_supported(family, icmph->type, icmph->code))
return;
- pr_debug("ping_err(type=%04x,code=%04x,id=%04x,seq=%04x)\n", type,
- code, ntohs(icmph->un.echo.id), ntohs(icmph->un.echo.sequence));
+ pr_debug("ping_err(proto=0x%x,type=%d,code=%d,id=%04x,seq=%04x)\n",
+ skb->protocol, type, code, ntohs(icmph->un.echo.id),
+ ntohs(icmph->un.echo.sequence));
- sk = ping_v4_lookup(net, iph->daddr, iph->saddr,
- ntohs(icmph->un.echo.id), skb->dev->ifindex);
+ sk = ping_lookup(net, skb, ntohs(icmph->un.echo.id));
if (sk == NULL) {
pr_debug("no socket, dropping\n");
return; /* No socket for error */
@@ -348,70 +502,85 @@
harderr = 0;
inet_sock = inet_sk(sk);
- switch (type) {
- default:
- case ICMP_TIME_EXCEEDED:
- err = EHOSTUNREACH;
- break;
- case ICMP_SOURCE_QUENCH:
- /* This is not a real error but ping wants to see it.
- * Report it with some fake errno. */
- err = EREMOTEIO;
- break;
- case ICMP_PARAMETERPROB:
- err = EPROTO;
- harderr = 1;
- break;
- case ICMP_DEST_UNREACH:
- if (code == ICMP_FRAG_NEEDED) { /* Path MTU discovery */
- if (inet_sock->pmtudisc != IP_PMTUDISC_DONT) {
- err = EMSGSIZE;
- harderr = 1;
- break;
+ if (skb->protocol == htons(ETH_P_IP)) {
+ switch (type) {
+ default:
+ case ICMP_TIME_EXCEEDED:
+ err = EHOSTUNREACH;
+ break;
+ case ICMP_SOURCE_QUENCH:
+ /* This is not a real error but ping wants to see it.
+ * Report it with some fake errno. */
+ err = EREMOTEIO;
+ break;
+ case ICMP_PARAMETERPROB:
+ err = EPROTO;
+ harderr = 1;
+ break;
+ case ICMP_DEST_UNREACH:
+ if (code == ICMP_FRAG_NEEDED) { /* Path MTU discovery */
+ if (inet_sock->pmtudisc != IP_PMTUDISC_DONT) {
+ err = EMSGSIZE;
+ harderr = 1;
+ break;
+ }
+ goto out;
}
- goto out;
+ err = EHOSTUNREACH;
+ if (code <= NR_ICMP_UNREACH) {
+ harderr = icmp_err_convert[code].fatal;
+ err = icmp_err_convert[code].errno;
+ }
+ break;
+ case ICMP_REDIRECT:
+ /* See ICMP_SOURCE_QUENCH */
+ err = EREMOTEIO;
+ break;
}
- err = EHOSTUNREACH;
- if (code <= NR_ICMP_UNREACH) {
- harderr = icmp_err_convert[code].fatal;
- err = icmp_err_convert[code].errno;
- }
- break;
- case ICMP_REDIRECT:
- /* See ICMP_SOURCE_QUENCH */
- err = EREMOTEIO;
- break;
+#if IS_ENABLED(CONFIG_IPV6)
+ } else if (skb->protocol == htons(ETH_P_IPV6)) {
+ harderr = pingv6_ops.icmpv6_err_convert(type, code, &err);
+#endif
}
/*
* RFC1122: OK. Passes ICMP errors back to application, as per
* 4.1.3.3.
*/
- if (!inet_sock->recverr) {
+ if ((family == AF_INET && !inet_sock->recverr) ||
+ (family == AF_INET6 && !inet6_sk(sk)->recverr)) {
if (!harderr || sk->sk_state != TCP_ESTABLISHED)
goto out;
} else {
- ip_icmp_error(sk, skb, err, 0 /* no remote port */,
- info, (u8 *)icmph);
+ if (family == AF_INET) {
+ ip_icmp_error(sk, skb, err, 0 /* no remote port */,
+ info, (u8 *)icmph);
+#if IS_ENABLED(CONFIG_IPV6)
+ } else if (family == AF_INET6) {
+ pingv6_ops.ipv6_icmp_error(sk, skb, err, 0,
+ info, (u8 *)icmph);
+#endif
+ }
}
sk->sk_err = err;
sk->sk_error_report(sk);
out:
sock_put(sk);
}
+EXPORT_SYMBOL_GPL(ping_err);
+
+void ping_v4_err(struct sk_buff *skb, u32 info)
+{
+ ping_err(skb, 0, info);
+}
/*
- * Copy and checksum an ICMP Echo packet from user space into a buffer.
+ * Copy and checksum an ICMP Echo packet from user space into a buffer
+ * starting from the payload.
*/
-struct pingfakehdr {
- struct icmphdr icmph;
- struct iovec *iov;
- __wsum wcheck;
-};
-
-static int ping_getfrag(void *from, char * to,
- int offset, int fraglen, int odd, struct sk_buff *skb)
+int ping_getfrag(void *from, char *to,
+ int offset, int fraglen, int odd, struct sk_buff *skb)
{
struct pingfakehdr *pfh = (struct pingfakehdr *)from;
@@ -422,20 +591,33 @@
pfh->iov, 0, fraglen - sizeof(struct icmphdr),
&pfh->wcheck))
return -EFAULT;
-
- return 0;
+ } else if (offset < sizeof(struct icmphdr)) {
+ BUG();
+ } else {
+ if (csum_partial_copy_fromiovecend
+ (to, pfh->iov, offset - sizeof(struct icmphdr),
+ fraglen, &pfh->wcheck))
+ return -EFAULT;
}
- if (offset < sizeof(struct icmphdr))
- BUG();
- if (csum_partial_copy_fromiovecend
- (to, pfh->iov, offset - sizeof(struct icmphdr),
- fraglen, &pfh->wcheck))
- return -EFAULT;
+
+#if IS_ENABLED(CONFIG_IPV6)
+ /* For IPv6, checksum each skb as we go along, as expected by
+ * icmpv6_push_pending_frames. For IPv4, accumulate the checksum in
+ * wcheck, it will be finalized in ping_v4_push_pending_frames.
+ */
+ if (pfh->family == AF_INET6) {
+ skb->csum = pfh->wcheck;
+ skb->ip_summed = CHECKSUM_NONE;
+ pfh->wcheck = 0;
+ }
+#endif
+
return 0;
}
+EXPORT_SYMBOL_GPL(ping_getfrag);
-static int ping_push_pending_frames(struct sock *sk, struct pingfakehdr *pfh,
- struct flowi4 *fl4)
+static int ping_v4_push_pending_frames(struct sock *sk, struct pingfakehdr *pfh,
+ struct flowi4 *fl4)
{
struct sk_buff *skb = skb_peek(&sk->sk_write_queue);
@@ -447,24 +629,9 @@
return ip_push_pending_frames(sk, fl4);
}
-static int ping_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
- size_t len)
-{
- struct net *net = sock_net(sk);
- struct flowi4 fl4;
- struct inet_sock *inet = inet_sk(sk);
- struct ipcm_cookie ipc;
- struct icmphdr user_icmph;
- struct pingfakehdr pfh;
- struct rtable *rt = NULL;
- struct ip_options_data opt_copy;
- int free = 0;
- __be32 saddr, daddr, faddr;
- u8 tos;
- int err;
-
- pr_debug("ping_sendmsg(sk=%p,sk->num=%u)\n", inet, inet->inet_num);
-
+int ping_common_sendmsg(int family, struct msghdr *msg, size_t len,
+ void *user_icmph, size_t icmph_len) {
+ u8 type, code;
if (len > 0xFFFF)
return -EMSGSIZE;
@@ -479,15 +646,53 @@
/*
* Fetch the ICMP header provided by the userland.
- * iovec is modified!
+ * iovec is modified! The ICMP header is consumed.
*/
-
- if (memcpy_fromiovec((u8 *)&user_icmph, msg->msg_iov,
- sizeof(struct icmphdr)))
+ if (memcpy_fromiovec(user_icmph, msg->msg_iov, icmph_len))
return -EFAULT;
- if (!ping_supported(user_icmph.type, user_icmph.code))
+
+ if (family == AF_INET) {
+ type = ((struct icmphdr *) user_icmph)->type;
+ code = ((struct icmphdr *) user_icmph)->code;
+#if IS_ENABLED(CONFIG_IPV6)
+ } else if (family == AF_INET6) {
+ type = ((struct icmp6hdr *) user_icmph)->icmp6_type;
+ code = ((struct icmp6hdr *) user_icmph)->icmp6_code;
+#endif
+ } else {
+ BUG();
+ }
+
+ if (!ping_supported(family, type, code))
return -EINVAL;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(ping_common_sendmsg);
+
+int ping_v4_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
+ size_t len)
+{
+ struct net *net = sock_net(sk);
+ struct flowi4 fl4;
+ struct inet_sock *inet = inet_sk(sk);
+ struct ipcm_cookie ipc;
+ struct icmphdr user_icmph;
+ struct pingfakehdr pfh;
+ struct rtable *rt = NULL;
+ struct ip_options_data opt_copy;
+ int free = 0;
+ __be32 saddr, daddr, faddr;
+ u8 tos;
+ int err;
+
+ pr_debug("ping_v4_sendmsg(sk=%p,sk->num=%u)\n", inet, inet->inet_num);
+
+ err = ping_common_sendmsg(AF_INET, msg, len, &user_icmph,
+ sizeof(user_icmph));
+ if (err)
+ return err;
+
/*
* Get and verify the address.
*/
@@ -593,13 +798,14 @@
pfh.icmph.un.echo.sequence = user_icmph.un.echo.sequence;
pfh.iov = msg->msg_iov;
pfh.wcheck = 0;
+ pfh.family = AF_INET;
err = ip_append_data(sk, &fl4, ping_getfrag, &pfh, len,
0, &ipc, &rt, msg->msg_flags);
if (err)
ip_flush_pending_frames(sk);
else
- err = ping_push_pending_frames(sk, &pfh, &fl4);
+ err = ping_v4_push_pending_frames(sk, &pfh, &fl4);
release_sock(sk);
out:
@@ -620,11 +826,13 @@
goto out;
}
-static int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
- size_t len, int noblock, int flags, int *addr_len)
+int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
+ size_t len, int noblock, int flags, int *addr_len)
{
struct inet_sock *isk = inet_sk(sk);
- struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name;
+ int family = sk->sk_family;
+ struct sockaddr_in *sin;
+ struct sockaddr_in6 *sin6;
struct sk_buff *skb;
int copied, err;
@@ -634,11 +842,22 @@
if (flags & MSG_OOB)
goto out;
- if (addr_len)
- *addr_len = sizeof(*sin);
+ if (addr_len) {
+ if (family == AF_INET)
+ *addr_len = sizeof(*sin);
+ else if (family == AF_INET6 && addr_len)
+ *addr_len = sizeof(*sin6);
+ }
- if (flags & MSG_ERRQUEUE)
- return ip_recv_error(sk, msg, len);
+ if (flags & MSG_ERRQUEUE) {
+ if (family == AF_INET) {
+ return ip_recv_error(sk, msg, len);
+#if IS_ENABLED(CONFIG_IPV6)
+ } else if (family == AF_INET6) {
+ return pingv6_ops.ipv6_recv_error(sk, msg, len);
+#endif
+ }
+ }
skb = skb_recv_datagram(sk, flags, noblock, &err);
if (!skb)
@@ -657,15 +876,41 @@
sock_recv_timestamp(msg, sk, skb);
- /* Copy the address. */
- if (sin) {
+ /* Copy the address and add cmsg data. */
+ if (family == AF_INET) {
+ sin = (struct sockaddr_in *) msg->msg_name;
sin->sin_family = AF_INET;
sin->sin_port = 0 /* skb->h.uh->source */;
sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
+
+ if (isk->cmsg_flags)
+ ip_cmsg_recv(msg, skb);
+
+#if IS_ENABLED(CONFIG_IPV6)
+ } else if (family == AF_INET6) {
+ struct ipv6_pinfo *np = inet6_sk(sk);
+ struct ipv6hdr *ip6 = ipv6_hdr(skb);
+ sin6 = (struct sockaddr_in6 *) msg->msg_name;
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_port = 0;
+ sin6->sin6_addr = ip6->saddr;
+
+ if (np->sndflow)
+ sin6->sin6_flowinfo =
+ *(__be32 *)ip6 & IPV6_FLOWINFO_MASK;
+
+ if (__ipv6_addr_needs_scope_id(
+ ipv6_addr_type(&sin6->sin6_addr)))
+ sin6->sin6_scope_id = IP6CB(skb)->iif;
+
+ if (inet6_sk(sk)->rxopt.all)
+ pingv6_ops.datagram_recv_ctl(sk, msg, skb);
+#endif
+ } else {
+ BUG();
}
- if (isk->cmsg_flags)
- ip_cmsg_recv(msg, skb);
+
err = copied;
done:
@@ -674,8 +919,9 @@
pr_debug("ping_recvmsg -> %d\n", err);
return err;
}
+EXPORT_SYMBOL_GPL(ping_recvmsg);
-static int ping_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
+int ping_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
{
pr_debug("ping_queue_rcv_skb(sk=%p,sk->num=%d,skb=%p)\n",
inet_sk(sk), inet_sk(sk)->inet_num, skb);
@@ -686,6 +932,7 @@
}
return 0;
}
+EXPORT_SYMBOL_GPL(ping_queue_rcv_skb);
/*
@@ -696,10 +943,7 @@
{
struct sock *sk;
struct net *net = dev_net(skb->dev);
- struct iphdr *iph = ip_hdr(skb);
struct icmphdr *icmph = icmp_hdr(skb);
- __be32 saddr = iph->saddr;
- __be32 daddr = iph->daddr;
/* We assume the packet has already been checked by icmp_rcv */
@@ -709,8 +953,7 @@
/* Push ICMP header back */
skb_push(skb, skb->data - (u8 *)icmph);
- sk = ping_v4_lookup(net, saddr, daddr, ntohs(icmph->un.echo.id),
- skb->dev->ifindex);
+ sk = ping_lookup(net, skb, ntohs(icmph->un.echo.id));
if (sk != NULL) {
pr_debug("rcv on socket %p\n", sk);
ping_queue_rcv_skb(sk, skb_get(skb));
@@ -721,6 +964,7 @@
/* We're called from icmp_rcv(). kfree_skb() is done there. */
}
+EXPORT_SYMBOL_GPL(ping_rcv);
struct proto ping_prot = {
.name = "PING",
@@ -731,13 +975,13 @@
.disconnect = udp_disconnect,
.setsockopt = ip_setsockopt,
.getsockopt = ip_getsockopt,
- .sendmsg = ping_sendmsg,
+ .sendmsg = ping_v4_sendmsg,
.recvmsg = ping_recvmsg,
.bind = ping_bind,
.backlog_rcv = ping_queue_rcv_skb,
- .hash = ping_v4_hash,
- .unhash = ping_v4_unhash,
- .get_port = ping_v4_get_port,
+ .hash = ping_hash,
+ .unhash = ping_unhash,
+ .get_port = ping_get_port,
.obj_size = sizeof(struct inet_sock),
};
EXPORT_SYMBOL(ping_prot);
diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile
index 686934a..753be5d 100644
--- a/net/ipv6/Makefile
+++ b/net/ipv6/Makefile
@@ -7,7 +7,7 @@
ipv6-objs := af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o \
addrlabel.o \
route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o udplite.o \
- raw.o protocol.o icmp.o mcast.o reassembly.o tcp_ipv6.o \
+ raw.o protocol.o icmp.o mcast.o reassembly.o tcp_ipv6.o ping.o \
exthdrs.o datagram.o ip6_flowlabel.o inet6_connection_sock.o
ipv6-$(CONFIG_SYSCTL) = sysctl_net_ipv6.o
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 29625e9..22ebbb9 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -49,6 +49,7 @@
#include <net/udplite.h>
#include <net/tcp.h>
#include <net/ipip.h>
+#include <net/ping.h>
#include <net/protocol.h>
#include <net/inet_common.h>
#include <net/route.h>
@@ -1130,6 +1131,9 @@
if (err)
goto out_unregister_udplite_proto;
+ err = proto_register(&pingv6_prot, 1);
+ if (err)
+ goto out_unregister_ping_proto;
/* We MUST register RAW sockets before we create the ICMP6,
* IGMP6, or NDISC control sockets.
@@ -1225,6 +1229,10 @@
if (err)
goto ipv6_packet_fail;
+ err = pingv6_init();
+ if (err)
+ goto pingv6_fail;
+
#ifdef CONFIG_SYSCTL
err = ipv6_sysctl_register();
if (err)
@@ -1237,6 +1245,8 @@
sysctl_fail:
ipv6_packet_cleanup();
#endif
+pingv6_fail:
+ pingv6_exit();
ipv6_packet_fail:
tcpv6_exit();
tcpv6_fail:
@@ -1284,6 +1294,8 @@
rtnl_unregister_all(PF_INET6);
out_sock_register_fail:
rawv6_exit();
+out_unregister_ping_proto:
+ proto_unregister(&pingv6_prot);
out_unregister_raw_proto:
proto_unregister(&rawv6_prot);
out_unregister_udplite_proto:
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 27ac95a..ba0c147 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -55,6 +55,7 @@
#include <net/ipv6.h>
#include <net/ip6_checksum.h>
+#include <net/ping.h>
#include <net/protocol.h>
#include <net/raw.h>
#include <net/rawv6.h>
@@ -79,10 +80,22 @@
return net->ipv6.icmp_sk[smp_processor_id()];
}
+static void icmpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
+ u8 type, u8 code, int offset, __be32 info)
+{
+ /* icmpv6_notify checks 8 bytes can be pulled, icmp6hdr is 8 bytes */
+ struct icmp6hdr *icmp6 = (struct icmp6hdr *) (skb->data + offset);
+
+ if (!(type & ICMPV6_INFOMSG_MASK))
+ if (icmp6->icmp6_type == ICMPV6_ECHO_REQUEST)
+ ping_err(skb, offset, info);
+}
+
static int icmpv6_rcv(struct sk_buff *skb);
static const struct inet6_protocol icmpv6_protocol = {
.handler = icmpv6_rcv,
+ .err_handler = icmpv6_err,
.flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
};
@@ -217,7 +230,8 @@
return (*op & 0xC0) == 0x80;
}
-static int icmpv6_push_pending_frames(struct sock *sk, struct flowi6 *fl6, struct icmp6hdr *thdr, int len)
+int icmpv6_push_pending_frames(struct sock *sk, struct flowi6 *fl6,
+ struct icmp6hdr *thdr, int len)
{
struct sk_buff *skb;
struct icmp6hdr *icmp6h;
@@ -300,8 +314,8 @@
static inline void mip6_addr_swap(struct sk_buff *skb) {}
#endif
-static struct dst_entry *icmpv6_route_lookup(struct net *net, struct sk_buff *skb,
- struct sock *sk, struct flowi6 *fl6)
+struct dst_entry *icmpv6_route_lookup(struct net *net, struct sk_buff *skb,
+ struct sock *sk, struct flowi6 *fl6)
{
struct dst_entry *dst, *dst2;
struct flowi6 fl2;
@@ -594,7 +608,7 @@
icmpv6_xmit_unlock(sk);
}
-static void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info)
+void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info)
{
const struct inet6_protocol *ipprot;
int inner_offset;
@@ -687,7 +701,8 @@
skb->csum = ~csum_unfold(csum_ipv6_magic(saddr, daddr, skb->len,
IPPROTO_ICMPV6, 0));
if (__skb_checksum_complete(skb)) {
- LIMIT_NETDEBUG(KERN_DEBUG "ICMPv6 checksum failed [%pI6 > %pI6]\n",
+ LIMIT_NETDEBUG(KERN_DEBUG
+ "ICMPv6 checksum failed [%pI6c > %pI6c]\n",
saddr, daddr);
goto discard_it;
}
@@ -708,7 +723,7 @@
break;
case ICMPV6_ECHO_REPLY:
- /* we couldn't care less */
+ ping_rcv(skb);
break;
case ICMPV6_PKT_TOOBIG:
diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c
new file mode 100644
index 0000000..f46e315
--- /dev/null
+++ b/net/ipv6/ping.c
@@ -0,0 +1,222 @@
+/*
+ * INET An implementation of the TCP/IP protocol suite for the LINUX
+ * operating system. INET is implemented using the BSD Socket
+ * interface as the means of communication with the user level.
+ *
+ * "Ping" sockets
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Based on ipv4/ping.c code.
+ *
+ * Authors: Lorenzo Colitti (IPv6 support)
+ * Vasiliy Kulikov / Openwall (IPv4 implementation, for Linux 2.6),
+ * Pavel Kankovsky (IPv4 implementation, for Linux 2.4.32)
+ *
+ */
+
+#include <net/addrconf.h>
+#include <net/ipv6.h>
+#include <net/ip6_route.h>
+#include <net/protocol.h>
+#include <net/udp.h>
+#include <net/transp_v6.h>
+#include <net/ping.h>
+#include <linux/module.h>
+
+struct proto pingv6_prot = {
+ .name = "PINGv6",
+ .owner = THIS_MODULE,
+ .init = ping_init_sock,
+ .close = ping_close,
+ .connect = ip6_datagram_connect,
+ .disconnect = udp_disconnect,
+ .setsockopt = ipv6_setsockopt,
+ .getsockopt = ipv6_getsockopt,
+ .sendmsg = ping_v6_sendmsg,
+ .recvmsg = ping_recvmsg,
+ .bind = ping_bind,
+ .backlog_rcv = ping_queue_rcv_skb,
+ .hash = ping_hash,
+ .unhash = ping_unhash,
+ .get_port = ping_get_port,
+ .obj_size = sizeof(struct raw6_sock),
+};
+EXPORT_SYMBOL_GPL(pingv6_prot);
+
+static struct inet_protosw pingv6_protosw = {
+ .type = SOCK_DGRAM,
+ .protocol = IPPROTO_ICMPV6,
+ .prot = &pingv6_prot,
+ .ops = &inet6_dgram_ops,
+ .no_check = UDP_CSUM_DEFAULT,
+ .flags = INET_PROTOSW_REUSE,
+};
+
+
+/* Compatibility glue so we can support IPv6 when it's compiled as a module */
+int dummy_ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
+{
+ return -EAFNOSUPPORT;
+}
+int dummy_datagram_recv_ctl(struct sock *sk, struct msghdr *msg,
+ struct sk_buff *skb)
+{
+ return -EAFNOSUPPORT;
+}
+int dummy_icmpv6_err_convert(u8 type, u8 code, int *err)
+{
+ return -EAFNOSUPPORT;
+}
+void dummy_ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err,
+ __be16 port, u32 info, u8 *payload) {}
+int dummy_ipv6_chk_addr(struct net *net, const struct in6_addr *addr,
+ struct net_device *dev, int strict)
+{
+ return 0;
+}
+
+int __init pingv6_init(void)
+{
+ pingv6_ops.ipv6_recv_error = ipv6_recv_error;
+ pingv6_ops.datagram_recv_ctl = datagram_recv_ctl;
+ pingv6_ops.icmpv6_err_convert = icmpv6_err_convert;
+ pingv6_ops.ipv6_icmp_error = ipv6_icmp_error;
+ pingv6_ops.ipv6_chk_addr = ipv6_chk_addr;
+ return inet6_register_protosw(&pingv6_protosw);
+}
+
+/* This never gets called because it's not possible to unload the ipv6 module,
+ * but just in case.
+ */
+void pingv6_exit(void)
+{
+ pingv6_ops.ipv6_recv_error = dummy_ipv6_recv_error;
+ pingv6_ops.datagram_recv_ctl = dummy_datagram_recv_ctl;
+ pingv6_ops.icmpv6_err_convert = dummy_icmpv6_err_convert;
+ pingv6_ops.ipv6_icmp_error = dummy_ipv6_icmp_error;
+ pingv6_ops.ipv6_chk_addr = dummy_ipv6_chk_addr;
+ inet6_unregister_protosw(&pingv6_protosw);
+}
+
+int ping_v6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
+ size_t len)
+{
+ struct inet_sock *inet = inet_sk(sk);
+ struct ipv6_pinfo *np = inet6_sk(sk);
+ struct icmp6hdr user_icmph;
+ int addr_type;
+ struct in6_addr *daddr;
+ int iif = 0;
+ struct flowi6 fl6;
+ int err;
+ int hlimit;
+ struct dst_entry *dst;
+ struct rt6_info *rt;
+ struct pingfakehdr pfh;
+
+ pr_debug("ping_v6_sendmsg(sk=%p,sk->num=%u)\n", inet, inet->inet_num);
+
+ err = ping_common_sendmsg(AF_INET6, msg, len, &user_icmph,
+ sizeof(user_icmph));
+ if (err)
+ return err;
+
+ if (msg->msg_name) {
+ struct sockaddr_in6 *u = (struct sockaddr_in6 *) msg->msg_name;
+ if (msg->msg_namelen < sizeof(struct sockaddr_in6) ||
+ u->sin6_family != AF_INET6) {
+ return -EINVAL;
+ }
+ if (sk->sk_bound_dev_if &&
+ sk->sk_bound_dev_if != u->sin6_scope_id) {
+ return -EINVAL;
+ }
+ daddr = &(u->sin6_addr);
+ iif = u->sin6_scope_id;
+ } else {
+ if (sk->sk_state != TCP_ESTABLISHED)
+ return -EDESTADDRREQ;
+ daddr = &np->daddr;
+ }
+
+ if (!iif)
+ iif = sk->sk_bound_dev_if;
+
+ addr_type = ipv6_addr_type(daddr);
+ if (__ipv6_addr_needs_scope_id(addr_type) && !iif)
+ return -EINVAL;
+ if (addr_type & IPV6_ADDR_MAPPED)
+ return -EINVAL;
+
+ /* TODO: use ip6_datagram_send_ctl to get options from cmsg */
+
+ memset(&fl6, 0, sizeof(fl6));
+
+ fl6.flowi6_proto = IPPROTO_ICMPV6;
+ fl6.saddr = np->saddr;
+ fl6.daddr = *daddr;
+ fl6.fl6_icmp_type = user_icmph.icmp6_type;
+ fl6.fl6_icmp_code = user_icmph.icmp6_code;
+ security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
+
+ if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr))
+ fl6.flowi6_oif = np->mcast_oif;
+ else if (!fl6.flowi6_oif)
+ fl6.flowi6_oif = np->ucast_oif;
+
+ dst = ip6_sk_dst_lookup_flow(sk, &fl6, daddr, 1);
+ if (IS_ERR(dst))
+ return PTR_ERR(dst);
+ rt = (struct rt6_info *) dst;
+
+ np = inet6_sk(sk);
+ if (!np)
+ return -EBADF;
+
+ if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr))
+ fl6.flowi6_oif = np->mcast_oif;
+ else if (!fl6.flowi6_oif)
+ fl6.flowi6_oif = np->ucast_oif;
+
+ pfh.icmph.type = user_icmph.icmp6_type;
+ pfh.icmph.code = user_icmph.icmp6_code;
+ pfh.icmph.checksum = 0;
+ pfh.icmph.un.echo.id = inet->inet_sport;
+ pfh.icmph.un.echo.sequence = user_icmph.icmp6_sequence;
+ pfh.iov = msg->msg_iov;
+ pfh.wcheck = 0;
+ pfh.family = AF_INET6;
+
+ if (ipv6_addr_is_multicast(&fl6.daddr))
+ hlimit = np->mcast_hops;
+ else
+ hlimit = np->hop_limit;
+ if (hlimit < 0)
+ hlimit = ip6_dst_hoplimit(dst);
+
+ lock_sock(sk);
+ err = ip6_append_data(sk, ping_getfrag, &pfh, len,
+ 0, hlimit,
+ np->tclass, NULL, &fl6, rt,
+ MSG_DONTWAIT, np->dontfrag);
+
+ if (err) {
+ ICMP6_INC_STATS_BH(sock_net(sk), rt->rt6i_idev,
+ ICMP6_MIB_OUTERRORS);
+ ip6_flush_pending_frames(sk);
+ } else {
+ err = icmpv6_push_pending_frames(sk, &fl6,
+ (struct icmp6hdr *) &pfh.icmph,
+ len);
+ }
+ release_sock(sk);
+
+ if (err)
+ return err;
+
+ return len;
+}
diff --git a/net/wireless/db.txt b/net/wireless/db.txt
index 0e44fa8..c27f165 100644
--- a/net/wireless/db.txt
+++ b/net/wireless/db.txt
@@ -295,6 +295,12 @@
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
+country ET: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 80), (N/A, 20)
+ (5250 - 5330 @ 80), (N/A, 20), DFS
+ (5490 - 5710 @ 80), (N/A, 27), DFS
+
country FI: DFS-ETSI
(2402 - 2482 @ 40), (N/A, 20)
(5170 - 5250 @ 80), (N/A, 20)
@@ -410,7 +416,7 @@
country ID:
# ref: http://www.postel.go.id/content/ID/regulasi/standardisasi/kepdir/bwa%205,8%20ghz.pdf
- (2402 - 2482 @ 40), (N/A, 20)
+ (2402 - 2482 @ 20), (N/A, 20)
(5735 - 5815 @ 20), (N/A, 23)
country IE: DFS-ETSI
@@ -485,6 +491,13 @@
(5250 - 5330 @ 80), (N/A, 20), DFS
(5490 - 5710 @ 80), (N/A, 27), DFS
+country KY:
+ (2402 - 2472 @ 40), (N/A, 27)
+ (5170 - 5250 @ 80), (3, 17)
+ (5250 - 5330 @ 80), (3, 24), DFS
+ (5490 - 5710 @ 80), (3, 24), DFS
+ (5735 - 5835 @ 80), (3, 30)
+
country KP:
(2402 - 2482 @ 20), (N/A, 20)
(5170 - 5330 @ 20), (6, 20)
@@ -825,6 +838,12 @@
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
+country SR: DFS-ETSI
+ (2400 - 2483.5 @ 40), (N/A, 100 mW)
+ (5150 - 5250 @ 80), (N/A, 100 mW), NO-OUTDOOR
+ (5250 - 5350 @ 80), (N/A, 100 mW), NO-OUTDOOR, DFS
+ (5470 - 5725 @ 80), (N/A, 500 mW), DFS
+
country SV:
(2402 - 2482 @ 40), (N/A, 20)
(5170 - 5250 @ 20), (3, 17)
@@ -947,6 +966,12 @@
(5470 - 5725 @ 80), (6, 24), DFS
(5725 - 5850 @ 80), (6, 30)
+country WS: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 20), (3, 17)
+ (5250 - 5330 @ 80), (3, 24), DFS
+ (5490 - 5710 @ 80), (3, 24), DFS
+
country YE:
(2402 - 2482 @ 40), (N/A, 20)
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index b094741..78aa256 100755
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -1184,7 +1184,10 @@
enum nl80211_reg_initiator setby)
{
mutex_lock(®_mutex);
- wiphy_update_regulatory(wiphy, setby);
+ if (last_request)
+ wiphy_update_regulatory(wiphy, last_request->initiator);
+ else
+ wiphy_update_regulatory(wiphy, setby);
mutex_unlock(®_mutex);
}
diff --git a/sound/core/jack.c b/sound/core/jack.c
index 9e2e085..6e2dbdb 100644
--- a/sound/core/jack.c
+++ b/sound/core/jack.c
@@ -35,6 +35,7 @@
SW_HPHL_OVERCURRENT,
SW_HPHR_OVERCURRENT,
SW_UNSUPPORT_INSERT,
+ SW_MICROPHONE2_INSERT,
};
static int snd_jack_dev_free(struct snd_device *device)
diff --git a/sound/soc/codecs/msm8x10-wcd.c b/sound/soc/codecs/msm8x10-wcd.c
index 7706e3e..452bbab 100644
--- a/sound/soc/codecs/msm8x10-wcd.c
+++ b/sound/soc/codecs/msm8x10-wcd.c
@@ -167,6 +167,10 @@
"cdc-vdda-cp",
};
+static int on_demand_regulator_control(struct on_demand_supply *supply,
+ bool enable,
+ u8 shift);
+
struct msm8x10_wcd_priv {
struct snd_soc_codec *codec;
u32 adc_count;
@@ -178,7 +182,6 @@
/* mbhc module */
struct wcd9xxx_mbhc mbhc;
- struct delayed_work hs_detect_work;
struct wcd9xxx_mbhc_config *mbhc_cfg;
/*
@@ -186,6 +189,7 @@
* end of impedance measurement
*/
struct list_head reg_save_restore;
+ u32 micb_en_count;
};
static unsigned short rx_digital_gain_reg[] = {
@@ -298,7 +302,6 @@
return ret;
}
}
- pr_debug("write sucess register = %x val = %x\n", reg, data[1]);
return 0;
}
@@ -347,7 +350,6 @@
}
}
}
- pr_debug("%s: reg 0x%x = 0x%x\n", __func__, reg, *dest);
return 0;
}
@@ -479,8 +481,8 @@
__func__, reg);
else
dev_dbg(msm8x10_wcd->dev,
- "%s: Write %x to R%d(0x%x)\n",
- __func__, val, reg, reg);
+ "%s: Write 0x%x to 0x%x\n",
+ __func__, val, reg);
return ret;
}
@@ -516,8 +518,6 @@
* Registers lower than 0x100 are top level registers which can be
* written by the Taiko core driver.
*/
- dev_dbg(codec->dev, "%s: reg 0x%x\n", __func__, reg);
-
if ((reg >= MSM8X10_WCD_A_CDC_MBHC_EN_CTL) || (reg < 0x100))
return 1;
@@ -553,7 +553,7 @@
unsigned int value)
{
int ret;
- dev_dbg(codec->dev, "%s: Write from reg 0x%x\n", __func__, reg);
+ dev_dbg(codec->dev, "%s: Write to reg 0x%x\n", __func__, reg);
if (reg == SND_SOC_NOPM)
return 0;
@@ -784,6 +784,39 @@
return NULL;
}
+static int on_demand_regulator_control(struct on_demand_supply *supply,
+ bool enable,
+ u8 shift)
+{
+ int ret = 0;
+
+ if (!supply || !supply->supply)
+ return 0;
+
+ if (enable) {
+ if (atomic_inc_return(&supply->ref) == 1)
+ ret = regulator_enable(supply->supply);
+ if (ret)
+ pr_err("%s: Failed to enable %s\n",
+ __func__,
+ on_demand_supply_name[shift]);
+ } else {
+ if (atomic_read(&supply->ref) == 0) {
+ pr_debug("%s: %s supply has been disabled.\n",
+ __func__, on_demand_supply_name[shift]);
+ return 0;
+ }
+ if (atomic_dec_return(&supply->ref) == 0)
+ ret = regulator_disable(supply->supply);
+ if (ret)
+ pr_err("%s: Failed to disable %s\n",
+ __func__,
+ on_demand_supply_name[shift]);
+ }
+
+ return ret;
+}
+
static int msm8x10_wcd_codec_enable_on_demand_supply(
struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
@@ -809,25 +842,14 @@
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
- if (atomic_inc_return(&supply->ref) == 1)
- ret = regulator_enable(supply->supply);
- if (ret)
- dev_err(codec->dev, "%s: Failed to enable %s\n",
- __func__,
- on_demand_supply_name[w->shift]);
+ ret = on_demand_regulator_control(supply,
+ true,
+ w->shift);
break;
case SND_SOC_DAPM_POST_PMD:
- if (atomic_read(&supply->ref) == 0) {
- dev_dbg(codec->dev, "%s: %s supply has been disabled.\n",
- __func__, on_demand_supply_name[w->shift]);
- goto out;
- }
- if (atomic_dec_return(&supply->ref) == 0)
- ret = regulator_disable(supply->supply);
- if (ret)
- dev_err(codec->dev, "%s: Failed to disable %s\n",
- __func__,
- on_demand_supply_name[w->shift]);
+ ret = on_demand_regulator_control(supply,
+ false,
+ w->shift);
break;
default:
break;
@@ -1676,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);
@@ -1683,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 */
@@ -2600,8 +2629,6 @@
/* Disable internal biasing path which can cause leakage */
MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_BIAS_CURR_CTL_2, 0x04),
- /* Enable pulldown to reduce leakage */
- MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_MICB_1_CTL, 0x82),
MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_TX_COM_BIAS, 0xE0),
/* Keep the same default gain settings for TX paths */
MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_TX_1_EN, 0x32),
@@ -2740,18 +2767,33 @@
}
static int msm8x10_wcd_enable_ext_mb_source(struct snd_soc_codec *codec,
- bool turn_on)
+ bool turn_on,
+ bool use_dapm)
{
int ret = 0;
- if (turn_on)
- ret = snd_soc_dapm_force_enable_pin(&codec->dapm,
- "MICBIAS_REGULATOR");
- else
- ret = snd_soc_dapm_disable_pin(&codec->dapm,
- "MICBIAS_REGULATOR");
+ if (use_dapm) {
+ if (turn_on)
+ ret = snd_soc_dapm_force_enable_pin(&codec->dapm,
+ "MICBIAS_REGULATOR");
+ else
+ ret = snd_soc_dapm_disable_pin(&codec->dapm,
+ "MICBIAS_REGULATOR");
- snd_soc_dapm_sync(&codec->dapm);
+ snd_soc_dapm_sync(&codec->dapm);
+ } else {
+ struct on_demand_supply *supply;
+ struct msm8x10_wcd_priv *msm8x10_wcd =
+ snd_soc_codec_get_drvdata(codec);
+
+ supply = &msm8x10_wcd->on_demand_list[ON_DEMAND_MICBIAS];
+ if (!supply || !supply->supply || !msm8x10_wcd)
+ return 0;
+
+ ret = on_demand_regulator_control(supply,
+ turn_on,
+ ON_DEMAND_MICBIAS);
+ }
if (ret)
dev_err(codec->dev, "%s: Failed to %s external micbias source\n",
@@ -2764,20 +2806,33 @@
}
static int msm8x10_wcd_enable_mbhc_micbias(struct snd_soc_codec *codec,
- bool enable)
+ bool enable,
+ 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;
+ goto err;
+ }
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__,
enable ? "enable" : "disable");
@@ -3037,33 +3092,18 @@
.compute_impedance = msm8x10_wcd_compute_impedance,
};
-static void delayed_hs_detect_fn(struct work_struct *work)
-{
- struct delayed_work *delayed_work;
- struct msm8x10_wcd_priv *wcd_priv;
-
- delayed_work = to_delayed_work(work);
- wcd_priv = container_of(delayed_work, struct msm8x10_wcd_priv,
- hs_detect_work);
-
- if (!wcd_priv) {
- pr_err("%s: Invalid private data for codec\n", __func__);
- return;
- }
-
- wcd9xxx_mbhc_start(&wcd_priv->mbhc, wcd_priv->mbhc_cfg);
-}
-
-
int msm8x10_wcd_hs_detect(struct snd_soc_codec *codec,
struct wcd9xxx_mbhc_config *mbhc_cfg)
{
struct msm8x10_wcd_priv *wcd = snd_soc_codec_get_drvdata(codec);
+ if (!wcd) {
+ dev_err(codec->dev, "%s: Invalid private data for codec\n",
+ __func__);
+ return -EINVAL;
+ }
wcd->mbhc_cfg = mbhc_cfg;
- schedule_delayed_work(&wcd->hs_detect_work,
- msecs_to_jiffies(5000));
- return 0;
+ return wcd9xxx_mbhc_start(&wcd->mbhc, wcd->mbhc_cfg);
}
EXPORT_SYMBOL_GPL(msm8x10_wcd_hs_detect);
@@ -3230,8 +3270,6 @@
msm8x10_wcd = codec->control_data;
msm8x10_wcd->pdino_base = ioremap(MSM8X10_DINO_CODEC_BASE_ADDR,
MSM8X10_DINO_CODEC_REG_SIZE);
- INIT_DELAYED_WORK(&msm8x10_wcd_priv->hs_detect_work,
- delayed_hs_detect_fn);
pdata = dev_get_platdata(msm8x10_wcd->dev);
if (!pdata) {
@@ -3267,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 07f4a5b..dd50020 100644
--- a/sound/soc/codecs/wcd9306.c
+++ b/sound/soc/codecs/wcd9306.c
@@ -2284,16 +2284,23 @@
}
/* called under codec_resource_lock acquisition */
-static int tapan_enable_mbhc_micbias(struct snd_soc_codec *codec, bool enable)
+static int tapan_enable_mbhc_micbias(struct snd_soc_codec *codec, bool enable,
+ enum wcd9xxx_micbias_num micb_num)
{
int rc;
+ const char *micbias;
+
+ if (micb_num == MBHC_MICBIAS2)
+ micbias = DAPM_MICBIAS2_EXTERNAL_STANDALONE;
+ else
+ return -EINVAL;
if (enable)
rc = snd_soc_dapm_force_enable_pin(&codec->dapm,
- DAPM_MICBIAS2_EXTERNAL_STANDALONE);
+ micbias);
else
rc = snd_soc_dapm_disable_pin(&codec->dapm,
- DAPM_MICBIAS2_EXTERNAL_STANDALONE);
+ micbias);
if (!rc)
snd_soc_dapm_sync(&codec->dapm);
pr_debug("%s: leave ret %d\n", __func__, rc);
@@ -5516,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 f874c43..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
@@ -48,6 +48,7 @@
#define TAIKO_HPH_PA_SETTLE_COMP_OFF 13000
#define DAPM_MICBIAS2_EXTERNAL_STANDALONE "MIC BIAS2 External Standalone"
+#define DAPM_MICBIAS3_EXTERNAL_STANDALONE "MIC BIAS3 External Standalone"
/* RX_HPH_CNP_WG_TIME increases by 0.24ms */
#define TAIKO_WG_TIME_FACTOR_US 240
@@ -2823,16 +2824,26 @@
}
/* called under codec_resource_lock acquisition */
-static int taiko_enable_mbhc_micbias(struct snd_soc_codec *codec, bool enable)
+static int taiko_enable_mbhc_micbias(struct snd_soc_codec *codec, bool enable,
+ enum wcd9xxx_micbias_num micb_num)
{
int rc;
+ const char *micbias;
+
+ if (micb_num != MBHC_MICBIAS3 &&
+ micb_num != MBHC_MICBIAS2)
+ return -EINVAL;
+
+ micbias = (micb_num == MBHC_MICBIAS3) ?
+ DAPM_MICBIAS3_EXTERNAL_STANDALONE :
+ DAPM_MICBIAS2_EXTERNAL_STANDALONE;
if (enable)
rc = snd_soc_dapm_force_enable_pin(&codec->dapm,
- DAPM_MICBIAS2_EXTERNAL_STANDALONE);
+ micbias);
else
rc = snd_soc_dapm_disable_pin(&codec->dapm,
- DAPM_MICBIAS2_EXTERNAL_STANDALONE);
+ micbias);
if (!rc)
snd_soc_dapm_sync(&codec->dapm);
pr_debug("%s: leave ret %d\n", __func__, rc);
@@ -4013,6 +4024,7 @@
{"MIC BIAS3 External", NULL, "LDO_H"},
{"MIC BIAS4 External", NULL, "LDO_H"},
{DAPM_MICBIAS2_EXTERNAL_STANDALONE, NULL, "LDO_H Standalone"},
+ {DAPM_MICBIAS3_EXTERNAL_STANDALONE, NULL, "LDO_H Standalone"},
};
static int taiko_readable(struct snd_soc_codec *ssc, unsigned int reg)
@@ -5135,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)
{
@@ -5535,6 +5565,10 @@
taiko_codec_enable_micbias,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS3_EXTERNAL_STANDALONE, SND_SOC_NOPM,
+ 7, 0, taiko_codec_enable_micbias,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 External", SND_SOC_NOPM, 7, 0,
taiko_codec_enable_micbias,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
@@ -5629,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 */
@@ -6466,7 +6506,7 @@
__wr(WCD9XXX_A_CDC_MBHC_TIMER_B5_CTL, 0xFF, 0x10);
/* Reset MBHC and set it up for STA */
__wr(WCD9XXX_A_CDC_MBHC_CLK_CTL, 0xFF, 0x0A);
- __wr(WCD9XXX_A_CDC_MBHC_EN_CTL, 0xFF, 0x02);
+ snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_EN_CTL, 0x2);
__wr(WCD9XXX_A_CDC_MBHC_CLK_CTL, 0xFF, 0x02);
/* Set HPH_MBHC for zdet */
@@ -6497,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/codecs/wcd9xxx-mbhc.c b/sound/soc/codecs/wcd9xxx-mbhc.c
index 32ca0c6..4426e4a 100644
--- a/sound/soc/codecs/wcd9xxx-mbhc.c
+++ b/sound/soc/codecs/wcd9xxx-mbhc.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
@@ -43,7 +43,7 @@
#define WCD9XXX_JACK_MASK (SND_JACK_HEADSET | SND_JACK_OC_HPHL | \
SND_JACK_OC_HPHR | SND_JACK_LINEOUT | \
- SND_JACK_UNSUPPORTED)
+ SND_JACK_UNSUPPORTED | SND_JACK_MICROPHONE2)
#define WCD9XXX_JACK_BUTTON_MASK (SND_JACK_BTN_0 | SND_JACK_BTN_1 | \
SND_JACK_BTN_2 | SND_JACK_BTN_3 | \
SND_JACK_BTN_4 | SND_JACK_BTN_5 | \
@@ -64,6 +64,7 @@
#define STATUS_REL_DETECTION 0x0C
#define HS_DETECT_PLUG_TIME_MS (5 * 1000)
+#define ANC_HPH_DETECT_PLUG_TIME_MS (5 * 1000)
#define HS_DETECT_PLUG_INERVAL_MS 100
#define SWCH_REL_DEBOUNCE_TIME_MS 50
#define SWCH_IRQ_DEBOUNCE_TIME_US 5000
@@ -179,7 +180,10 @@
uint32_t *zr);
static s16 wcd9xxx_get_current_v(struct wcd9xxx_mbhc *mbhc,
const enum wcd9xxx_current_v_idx idx);
-static void wcd9xxx_get_z(struct wcd9xxx_mbhc *mbhc, s16 *dce_z, s16 *sta_z);
+static void wcd9xxx_get_z(struct wcd9xxx_mbhc *mbhc, s16 *dce_z, s16 *sta_z,
+ struct mbhc_micbias_regs *micb_regs,
+ bool norel);
+
static void wcd9xxx_mbhc_calc_thres(struct wcd9xxx_mbhc *mbhc);
static bool wcd9xxx_mbhc_polling(struct wcd9xxx_mbhc *mbhc)
@@ -610,13 +614,23 @@
}
static void wcd9xxx_get_mbhc_micbias_regs(struct wcd9xxx_mbhc *mbhc,
- struct mbhc_micbias_regs *micbias_regs)
+ enum wcd9xxx_mbhc_micbias_type mb_type)
{
unsigned int cfilt;
struct wcd9xxx_micbias_setting *micbias_pdata =
mbhc->resmgr->micbias_pdata;
+ struct mbhc_micbias_regs *micbias_regs;
+ enum wcd9xxx_micbias_num mb_num;
- switch (mbhc->mbhc_cfg->micbias) {
+ if (mb_type == MBHC_ANC_MIC_MB) {
+ micbias_regs = &mbhc->mbhc_anc_bias_regs;
+ mb_num = mbhc->mbhc_cfg->anc_micbias;
+ } else {
+ micbias_regs = &mbhc->mbhc_bias_regs;
+ mb_num = mbhc->mbhc_cfg->micbias;
+ }
+
+ switch (mb_num) {
case MBHC_MICBIAS1:
cfilt = micbias_pdata->bias1_cfilt_sel;
micbias_regs->mbhc_reg = WCD9XXX_A_MICB_1_MBHC;
@@ -654,19 +668,31 @@
case WCD9XXX_CFILT1_SEL:
micbias_regs->cfilt_val = WCD9XXX_A_MICB_CFILT_1_VAL;
micbias_regs->cfilt_ctl = WCD9XXX_A_MICB_CFILT_1_CTL;
- mbhc->mbhc_data.micb_mv = micbias_pdata->cfilt1_mv;
break;
case WCD9XXX_CFILT2_SEL:
micbias_regs->cfilt_val = WCD9XXX_A_MICB_CFILT_2_VAL;
micbias_regs->cfilt_ctl = WCD9XXX_A_MICB_CFILT_2_CTL;
- mbhc->mbhc_data.micb_mv = micbias_pdata->cfilt2_mv;
break;
case WCD9XXX_CFILT3_SEL:
micbias_regs->cfilt_val = WCD9XXX_A_MICB_CFILT_3_VAL;
micbias_regs->cfilt_ctl = WCD9XXX_A_MICB_CFILT_3_CTL;
- mbhc->mbhc_data.micb_mv = micbias_pdata->cfilt3_mv;
break;
}
+
+ if (mb_type == MBHC_PRIMARY_MIC_MB) {
+ switch (cfilt) {
+ case WCD9XXX_CFILT1_SEL:
+ mbhc->mbhc_data.micb_mv = micbias_pdata->cfilt1_mv;
+ break;
+ case WCD9XXX_CFILT2_SEL:
+ mbhc->mbhc_data.micb_mv = micbias_pdata->cfilt2_mv;
+ break;
+ case WCD9XXX_CFILT3_SEL:
+ mbhc->mbhc_data.micb_mv = micbias_pdata->cfilt3_mv;
+ break;
+ }
+ }
+
}
static void wcd9xxx_clr_and_turnon_hph_padac(struct wcd9xxx_mbhc *mbhc)
@@ -819,7 +845,8 @@
if (mbhc->micbias_enable && mbhc->micbias_enable_cb) {
pr_debug("%s: Disabling micbias\n", __func__);
- mbhc->micbias_enable_cb(mbhc->codec, false);
+ mbhc->micbias_enable_cb(mbhc->codec, false,
+ mbhc->mbhc_cfg->micbias);
mbhc->micbias_enable = false;
}
mbhc->zl = mbhc->zr = 0;
@@ -845,7 +872,8 @@
if (mbhc->micbias_enable && mbhc->micbias_enable_cb &&
mbhc->hph_status == SND_JACK_HEADSET) {
pr_debug("%s: Disabling micbias\n", __func__);
- mbhc->micbias_enable_cb(mbhc->codec, false);
+ mbhc->micbias_enable_cb(mbhc->codec, false,
+ mbhc->mbhc_cfg->micbias);
mbhc->micbias_enable = false;
}
@@ -855,8 +883,10 @@
wcd9xxx_jack_report(mbhc, &mbhc->headset_jack,
0, WCD9XXX_JACK_MASK);
mbhc->hph_status &= ~(SND_JACK_HEADSET |
- SND_JACK_LINEOUT);
+ SND_JACK_LINEOUT |
+ SND_JACK_ANC_HEADPHONE);
}
+
/* Report insertion */
mbhc->hph_status |= jack_type;
@@ -870,11 +900,15 @@
mbhc->update_z = true;
} else if (jack_type == SND_JACK_LINEOUT) {
mbhc->current_plug = PLUG_TYPE_HIGH_HPH;
+ } else if (jack_type == SND_JACK_ANC_HEADPHONE) {
+ mbhc->polling_active = BUTTON_POLLING_SUPPORTED;
+ mbhc->current_plug = PLUG_TYPE_ANC_HEADPHONE;
}
if (mbhc->micbias_enable && mbhc->micbias_enable_cb) {
pr_debug("%s: Enabling micbias\n", __func__);
- mbhc->micbias_enable_cb(mbhc->codec, true);
+ mbhc->micbias_enable_cb(mbhc->codec, true,
+ mbhc->mbhc_cfg->micbias);
}
if (mbhc->impedance_detect && impedance_detect_en)
@@ -1041,7 +1075,14 @@
static short wcd9xxx_codec_sta_dce(struct wcd9xxx_mbhc *mbhc, int dce,
bool norel)
{
- return __wcd9xxx_codec_sta_dce(mbhc, dce, false, norel);
+ bool override_bypass;
+
+ /* Bypass override if it is already enabled */
+ override_bypass = (snd_soc_read(mbhc->codec,
+ WCD9XXX_A_CDC_MBHC_B1_CTL) &
+ 0x04) ? true : false;
+
+ return __wcd9xxx_codec_sta_dce(mbhc, dce, override_bypass, norel);
}
static s32 __wcd9xxx_codec_sta_dce_v(struct wcd9xxx_mbhc *mbhc, s8 dce,
@@ -1094,7 +1135,8 @@
/* called only from interrupt which is under codec_resource_lock acquisition */
static short wcd9xxx_mbhc_setup_hs_polling(struct wcd9xxx_mbhc *mbhc,
- bool is_cs_enable)
+ struct mbhc_micbias_regs *mbhc_micb_regs,
+ bool is_cs_enable)
{
struct snd_soc_codec *codec = mbhc->codec;
short bias_value;
@@ -1115,7 +1157,7 @@
btn_det = WCD9XXX_MBHC_CAL_BTN_DET_PTR(mbhc->mbhc_cfg->calibration);
/* Enable external voltage source to micbias if present */
if (mbhc->mbhc_cb && mbhc->mbhc_cb->enable_mb_source)
- mbhc->mbhc_cb->enable_mb_source(codec, true);
+ mbhc->mbhc_cb->enable_mb_source(codec, true, true);
/*
* setup internal micbias if codec uses internal micbias for
@@ -1132,15 +1174,19 @@
snd_soc_update_bits(codec, WCD9XXX_A_CLK_BUFF_EN1, 0x05, 0x01);
/* Make sure CFILT is in fast mode, save current mode */
- cfilt_mode = snd_soc_read(codec, mbhc->mbhc_bias_regs.cfilt_ctl);
+ cfilt_mode = snd_soc_read(codec, mbhc_micb_regs->cfilt_ctl);
if (mbhc->mbhc_cb && mbhc->mbhc_cb->cfilt_fast_mode)
mbhc->mbhc_cb->cfilt_fast_mode(codec, mbhc);
else
- snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.cfilt_ctl,
+ snd_soc_update_bits(codec, mbhc_micb_regs->cfilt_ctl,
0x70, 0x00);
snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x2, 0x2);
- snd_soc_write(codec, WCD9XXX_A_MBHC_SCALING_MUX_1, 0x04);
+ snd_soc_write(codec, WCD9XXX_A_MBHC_SCALING_MUX_1,
+ mbhc->scaling_mux_in);
+ pr_debug("%s: scaling_mux_input: %d\n", __func__,
+ mbhc->scaling_mux_in);
+
if (mbhc->mbhc_cb && mbhc->mbhc_cb->enable_mux_bias_block)
mbhc->mbhc_cb->enable_mux_bias_block(codec);
else
@@ -1165,7 +1211,7 @@
/* don't flip override */
bias_value = __wcd9xxx_codec_sta_dce(mbhc, 1, true, true);
- snd_soc_write(codec, mbhc->mbhc_bias_regs.cfilt_ctl, cfilt_mode);
+ snd_soc_write(codec, mbhc_micb_regs->cfilt_ctl, cfilt_mode);
snd_soc_update_bits(codec, WCD9XXX_A_MBHC_HPH, 0x13, 0x00);
if (mbhc->mbhc_cfg->do_recalibration) {
@@ -1173,7 +1219,7 @@
reg = snd_soc_read(codec, WCD9XXX_A_CDC_MBHC_B1_CTL);
change = snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B1_CTL,
0x78, btn_det->mbhc_nsc << 3);
- wcd9xxx_get_z(mbhc, &dce_z, &sta_z);
+ wcd9xxx_get_z(mbhc, &dce_z, &sta_z, mbhc_micb_regs, true);
if (change)
snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_B1_CTL, reg);
if (dce_z && sta_z) {
@@ -1197,7 +1243,8 @@
snd_soc_update_bits(mbhc->codec,
WCD9XXX_A_CDC_MBHC_B1_CTL,
0x78, WCD9XXX_MBHC_NSC_CS << 3);
- wcd9xxx_get_z(mbhc, &dce_z, NULL);
+ wcd9xxx_get_z(mbhc, &dce_z, NULL, mbhc_micb_regs,
+ true);
snd_soc_write(mbhc->codec, WCD9XXX_A_CDC_MBHC_B1_CTL,
reg);
if (dce_z) {
@@ -1253,7 +1300,7 @@
/* Disable external voltage source to micbias if present */
if (mbhc->mbhc_cb && mbhc->mbhc_cb->enable_mb_source)
- mbhc->mbhc_cb->enable_mb_source(mbhc->codec, false);
+ mbhc->mbhc_cb->enable_mb_source(mbhc->codec, false, true);
mbhc->polling_active = false;
mbhc->mbhc_state = MBHC_STATE_NONE;
@@ -1664,10 +1711,10 @@
return 0;
}
-void wcd9xxx_turn_onoff_current_source(struct wcd9xxx_mbhc *mbhc, bool on,
- bool highhph)
+void wcd9xxx_turn_onoff_current_source(struct wcd9xxx_mbhc *mbhc,
+ struct mbhc_micbias_regs *mbhc_micb_regs,
+ bool on, bool highhph)
{
-
struct snd_soc_codec *codec;
struct wcd9xxx_mbhc_btn_detect_cfg *btn_det;
const struct wcd9xxx_mbhc_plug_detect_cfg *plug_det =
@@ -1682,7 +1729,7 @@
snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B1_CTL,
0x78, 0x48);
/* pull down diode bit to 0 */
- snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.mbhc_reg,
+ snd_soc_update_bits(codec, mbhc_micb_regs->mbhc_reg,
0x01, 0x00);
/*
* Keep the low power insertion/removal
@@ -1697,7 +1744,7 @@
* (INS_DET_ISRC_EN__ENABLE)
* MICB_2_MBHC__SCHT_TRIG_EN to 1
*/
- snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.mbhc_reg,
+ snd_soc_update_bits(codec, mbhc_micb_regs->mbhc_reg,
0xF0, 0xF0);
/* Disconnect MBHC Override from MicBias and LDOH */
snd_soc_update_bits(codec, WCD9XXX_A_MAD_ANA_CTRL, 0x10, 0x00);
@@ -1706,16 +1753,16 @@
/* Connect MBHC Override from MicBias and LDOH */
snd_soc_update_bits(codec, WCD9XXX_A_MAD_ANA_CTRL, 0x10, 0x10);
/* INS_DET_ISRC_CTL to acdb value */
- snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.mbhc_reg,
+ snd_soc_update_bits(codec, mbhc_micb_regs->mbhc_reg,
0x60, plug_det->mic_current << 5);
if (!highhph) {
/* INS_DET_ISRC_EN__ENABLE to 0 */
snd_soc_update_bits(codec,
- mbhc->mbhc_bias_regs.mbhc_reg,
+ mbhc_micb_regs->mbhc_reg,
0x80, 0x00);
/* MICB_2_MBHC__SCHT_TRIG_EN to 0 */
snd_soc_update_bits(codec,
- mbhc->mbhc_bias_regs.mbhc_reg,
+ mbhc_micb_regs->mbhc_reg,
0x10, 0x00);
}
/* Nsc to acdb value */
@@ -1742,7 +1789,8 @@
rt[0].vddio = false;
rt[0].hwvalue = true;
rt[0].hphl_status = wcd9xxx_hphl_status(mbhc);
- rt[0].dce = wcd9xxx_mbhc_setup_hs_polling(mbhc, true);
+ rt[0].dce = wcd9xxx_mbhc_setup_hs_polling(mbhc, &mbhc->mbhc_bias_regs,
+ true);
rt[0].mic_bias = false;
for (i = 1; i < NUM_DCE_PLUG_INS_DETECT - 1; i++) {
@@ -1754,11 +1802,15 @@
wcd9xxx_codec_hphr_gnd_switch(codec, true);
if (rt[i].mic_bias)
- wcd9xxx_turn_onoff_current_source(mbhc, false, false);
+ wcd9xxx_turn_onoff_current_source(mbhc,
+ &mbhc->mbhc_bias_regs,
+ false, false);
rt[i].dce = __wcd9xxx_codec_sta_dce(mbhc, 1, !highhph, true);
if (rt[i].mic_bias)
- wcd9xxx_turn_onoff_current_source(mbhc, true, false);
+ wcd9xxx_turn_onoff_current_source(mbhc,
+ &mbhc->mbhc_bias_regs,
+ true, false);
if (rt[i].swap_gnd)
wcd9xxx_codec_hphr_gnd_switch(codec, false);
}
@@ -1811,7 +1863,8 @@
wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, true);
rt[0].hphl_status = wcd9xxx_hphl_status(mbhc);
- rt[0].dce = wcd9xxx_mbhc_setup_hs_polling(mbhc, false);
+ rt[0].dce = wcd9xxx_mbhc_setup_hs_polling(mbhc, &mbhc->mbhc_bias_regs,
+ false);
rt[0].swap_gnd = false;
rt[0].vddio = false;
rt[0].hwvalue = true;
@@ -2004,10 +2057,178 @@
return 0;
}
+/*
+ * Function to determine whether anc microphone is preset or not.
+ * Return true if anc microphone is detected or false if not detected.
+ */
+static bool wcd9xxx_detect_anc_plug_type(struct wcd9xxx_mbhc *mbhc)
+{
+ struct wcd9xxx_mbhc_detect rt[NUM_DCE_PLUG_INS_DETECT - 1];
+ bool anc_mic_found = true;
+ int i, mb_mv;
+ const struct wcd9xxx_mbhc_plug_type_cfg *plug_type =
+ WCD9XXX_MBHC_CAL_PLUG_TYPE_PTR(mbhc->mbhc_cfg->calibration);
+ s16 hs_max, dce_z;
+ s16 no_mic;
+ bool override_en;
+ bool timedout;
+ unsigned long timeout, retry = 0;
+ enum wcd9xxx_mbhc_plug_type type;
+ bool cs_enable;
+
+ if (mbhc->mbhc_cfg->anc_micbias != MBHC_MICBIAS3 &&
+ mbhc->mbhc_cfg->anc_micbias != MBHC_MICBIAS2)
+ return false;
+
+ pr_debug("%s: enter\n", __func__);
+
+ override_en = (snd_soc_read(mbhc->codec, WCD9XXX_A_CDC_MBHC_B1_CTL) &
+ 0x04) ? true : false;
+ cs_enable = ((mbhc->mbhc_cfg->cs_enable_flags &
+ (1 << MBHC_CS_ENABLE_DET_ANC)) != 0) &&
+ (!(snd_soc_read(mbhc->codec,
+ mbhc->mbhc_anc_bias_regs.ctl_reg) & 0x80)) &&
+ (mbhc->mbhc_cfg->micbias != mbhc->mbhc_cfg->anc_micbias);
+
+ if (cs_enable) {
+ wcd9xxx_turn_onoff_current_source(mbhc,
+ &mbhc->mbhc_anc_bias_regs,
+ true, false);
+ } else {
+ if (mbhc->mbhc_cfg->anc_micbias == MBHC_MICBIAS3) {
+ if (mbhc->micbias_enable_cb)
+ mbhc->micbias_enable_cb(mbhc->codec, true,
+ mbhc->mbhc_cfg->anc_micbias);
+ else
+ return false;
+ } else {
+ /* Enable override */
+ if (!override_en)
+ wcd9xxx_turn_onoff_override(mbhc, true);
+ }
+ }
+
+ if (!cs_enable) {
+ hs_max = plug_type->v_hs_max;
+ no_mic = plug_type->v_no_mic;
+ dce_z = mbhc->mbhc_data.dce_z;
+ mb_mv = mbhc->mbhc_data.micb_mv;
+ } else {
+ hs_max = WCD9XXX_V_CS_HS_MAX;
+ no_mic = WCD9XXX_V_CS_NO_MIC;
+ mb_mv = VDDIO_MICBIAS_MV;
+ dce_z = mbhc->mbhc_data.dce_nsc_cs_z;
+ }
+
+ wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, true);
+
+ timeout = jiffies + msecs_to_jiffies(ANC_HPH_DETECT_PLUG_TIME_MS);
+ anc_mic_found = true;
+
+ while (!(timedout = time_after(jiffies, timeout))) {
+ retry++;
+
+ if (wcd9xxx_swch_level_remove(mbhc)) {
+ pr_debug("%s: Switch level is low\n", __func__);
+ anc_mic_found = false;
+ break;
+ }
+
+ pr_debug("%s: Retry attempt %lu", __func__, retry - 1);
+
+ rt[0].hphl_status = wcd9xxx_hphl_status(mbhc);
+ rt[0].dce = wcd9xxx_mbhc_setup_hs_polling(mbhc,
+ &mbhc->mbhc_anc_bias_regs,
+ cs_enable);
+ rt[0]._vdces = __wcd9xxx_codec_sta_dce_v(mbhc, true, rt[0].dce,
+ dce_z, (u32)mb_mv);
+
+ if (rt[0]._vdces >= no_mic && rt[0]._vdces < hs_max)
+ rt[0]._type = PLUG_TYPE_HEADSET;
+ else if (rt[0]._vdces < no_mic)
+ rt[0]._type = PLUG_TYPE_HEADPHONE;
+ else
+ rt[0]._type = PLUG_TYPE_HIGH_HPH;
+
+ pr_debug("%s: DCE #%d, V %04d, HPHL %d TYPE %d\n",
+ __func__, 0, rt[0]._vdces,
+ rt[0].hphl_status & 0x01,
+ rt[0]._type);
+
+ for (i = 1; i < NUM_DCE_PLUG_INS_DETECT - 1; i++) {
+ rt[i].dce = __wcd9xxx_codec_sta_dce(mbhc, 1,
+ true, true);
+ rt[i]._vdces = __wcd9xxx_codec_sta_dce_v(mbhc, true,
+ rt[i].dce, dce_z,
+ (u32) mb_mv);
+
+ if (rt[i]._vdces >= no_mic && rt[i]._vdces < hs_max)
+ rt[i]._type = PLUG_TYPE_HEADSET;
+ else if (rt[i]._vdces < no_mic)
+ rt[i]._type = PLUG_TYPE_HEADPHONE;
+ else
+ rt[i]._type = PLUG_TYPE_HIGH_HPH;
+
+ rt[i].hphl_status = wcd9xxx_hphl_status(mbhc);
+
+ pr_debug("%s: DCE #%d, V %04d, HPHL %d TYPE %d\n",
+ __func__, i, rt[i]._vdces,
+ rt[i].hphl_status & 0x01,
+ rt[i]._type);
+ }
+
+ /*
+ * Check for the "type" of all the 4 measurements
+ * If all 4 measurements have the Type as PLUG_TYPE_HEADSET
+ * then it is proper mic and declare that the plug has two mics
+ */
+ for (i = 0; i < NUM_DCE_PLUG_INS_DETECT - 1; i++) {
+ if (i > 0 && (rt[i - 1]._type != rt[i]._type)) {
+ type = PLUG_TYPE_INVALID;
+ break;
+ } else {
+ type = rt[0]._type;
+ }
+ }
+
+ pr_debug("%s: Plug type found in ANC detection :%d",
+ __func__, type);
+
+ if (type != PLUG_TYPE_HEADSET)
+ anc_mic_found = false;
+ if (anc_mic_found || (type == PLUG_TYPE_HEADPHONE &&
+ mbhc->mbhc_cfg->hw_jack_type == FIVE_POLE_JACK) ||
+ (type == PLUG_TYPE_HIGH_HPH &&
+ mbhc->mbhc_cfg->hw_jack_type == SIX_POLE_JACK))
+ break;
+ }
+
+ wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, false);
+ if (cs_enable) {
+ wcd9xxx_turn_onoff_current_source(mbhc,
+ &mbhc->mbhc_anc_bias_regs,
+ false, false);
+ } else {
+ if (mbhc->mbhc_cfg->anc_micbias == MBHC_MICBIAS3) {
+ if (mbhc->micbias_enable_cb)
+ mbhc->micbias_enable_cb(mbhc->codec, false,
+ mbhc->mbhc_cfg->anc_micbias);
+ } else {
+ /* Disable override */
+ if (!override_en)
+ wcd9xxx_turn_onoff_override(mbhc, false);
+ }
+ }
+ pr_debug("%s: leave\n", __func__);
+ return anc_mic_found;
+}
+
/* called under codec_resource_lock acquisition */
static void wcd9xxx_find_plug_and_report(struct wcd9xxx_mbhc *mbhc,
enum wcd9xxx_mbhc_plug_type plug_type)
{
+ bool anc_mic_found = false;
+
pr_debug("%s: enter current_plug(%d) new_plug(%d)\n",
__func__, mbhc->current_plug, plug_type);
@@ -2033,25 +2254,50 @@
wcd9xxx_report_plug(mbhc, 1, SND_JACK_UNSUPPORTED);
wcd9xxx_cleanup_hs_polling(mbhc);
} else if (plug_type == PLUG_TYPE_HEADSET) {
- /*
- * If Headphone was reported previously, this will
- * only report the mic line
- */
- wcd9xxx_report_plug(mbhc, 1, SND_JACK_HEADSET);
+
+ if (mbhc->mbhc_cfg->enable_anc_mic_detect) {
+ /*
+ * Do not report Headset, because at this point
+ * it could be a ANC headphone having two mics.
+ * So, proceed further to detect if there is a
+ * second mic.
+ */
+ mbhc->scaling_mux_in = 0x08;
+ anc_mic_found = wcd9xxx_detect_anc_plug_type(mbhc);
+ }
+
+ if (anc_mic_found) {
+ /* Report ANC headphone */
+ wcd9xxx_report_plug(mbhc, 1, SND_JACK_ANC_HEADPHONE);
+ } else {
+ /*
+ * If Headphone was reported previously, this will
+ * only report the mic line
+ */
+ wcd9xxx_report_plug(mbhc, 1, SND_JACK_HEADSET);
+ }
/* Button detection required RC oscillator */
wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, true);
+ /*
+ * sleep so that audio path completely tears down
+ * before report plug insertion to the user space
+ */
msleep(100);
- /* if PA is already on, switch micbias source to VDDIO */
+ /*
+ * if PA is already on, switch micbias
+ * source to VDDIO
+ */
if (mbhc->event_state &
- (1 << MBHC_EVENT_PA_HPHL | 1 << MBHC_EVENT_PA_HPHR |
- 1 << MBHC_EVENT_PRE_TX_1_3_ON))
- __wcd9xxx_switch_micbias(mbhc, 1, false, false);
+ (1 << MBHC_EVENT_PA_HPHL | 1 << MBHC_EVENT_PA_HPHR))
+ __wcd9xxx_switch_micbias(mbhc, 1, false,
+ false);
wcd9xxx_start_hs_polling(mbhc);
} else if (plug_type == PLUG_TYPE_HIGH_HPH) {
if (mbhc->mbhc_cfg->detect_extn_cable) {
/* High impedance device found. Report as LINEOUT*/
- wcd9xxx_report_plug(mbhc, 1, SND_JACK_LINEOUT);
+ if (mbhc->current_plug == PLUG_TYPE_NONE)
+ wcd9xxx_report_plug(mbhc, 1, SND_JACK_LINEOUT);
wcd9xxx_cleanup_hs_polling(mbhc);
pr_debug("%s: setup mic trigger for further detection\n",
__func__);
@@ -2095,10 +2341,14 @@
(!(snd_soc_read(mbhc->codec,
mbhc->mbhc_bias_regs.ctl_reg) & 0x80)));
+ mbhc->scaling_mux_in = 0x04;
+
if (current_source_enable) {
- wcd9xxx_turn_onoff_current_source(mbhc, true, false);
+ wcd9xxx_turn_onoff_current_source(mbhc, &mbhc->mbhc_bias_regs,
+ true, false);
plug_type = wcd9xxx_codec_cs_get_plug_type(mbhc, false);
- wcd9xxx_turn_onoff_current_source(mbhc, false, false);
+ wcd9xxx_turn_onoff_current_source(mbhc, &mbhc->mbhc_bias_regs,
+ false, false);
} else {
wcd9xxx_turn_onoff_override(mbhc, true);
plug_type = wcd9xxx_codec_get_plug_type(mbhc, true);
@@ -2223,7 +2473,8 @@
(!(snd_soc_read(mbhc->codec,
mbhc->mbhc_bias_regs.ctl_reg) & 0x80)));
if (cs_enable)
- wcd9xxx_turn_onoff_current_source(mbhc, true, false);
+ wcd9xxx_turn_onoff_current_source(mbhc, &mbhc->mbhc_bias_regs,
+ true, false);
timeout = jiffies + msecs_to_jiffies(HS_DETECT_PLUG_TIME_MS);
while (!(timedout = time_after(jiffies, timeout))) {
@@ -2291,7 +2542,8 @@
}
if (cs_enable)
- wcd9xxx_turn_onoff_current_source(mbhc, false, false);
+ wcd9xxx_turn_onoff_current_source(mbhc, &mbhc->mbhc_bias_regs,
+ false, false);
if (timedout)
pr_debug("%s: Microphone did not settle in %d seconds\n",
@@ -2322,7 +2574,8 @@
u32 mb_mv;
pr_debug("%s: enter\n", __func__);
- if (mbhc->current_plug != PLUG_TYPE_HEADSET) {
+ if (mbhc->current_plug != PLUG_TYPE_HEADSET &&
+ mbhc->current_plug != PLUG_TYPE_ANC_HEADPHONE) {
pr_debug("%s(): Headset is not inserted, ignore removal\n",
__func__);
snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL,
@@ -2339,7 +2592,8 @@
(!(snd_soc_read(codec,
mbhc->mbhc_bias_regs.ctl_reg) & 0x80)));
if (cs_enable)
- wcd9xxx_turn_onoff_current_source(mbhc, true, false);
+ wcd9xxx_turn_onoff_current_source(mbhc, &mbhc->mbhc_bias_regs,
+ true, false);
timeout = jiffies + msecs_to_jiffies(FAKE_REMOVAL_MIN_PERIOD_MS);
do {
@@ -2370,7 +2624,8 @@
removed ? "" : "not ");
if (cs_enable)
- wcd9xxx_turn_onoff_current_source(mbhc, false, false);
+ wcd9xxx_turn_onoff_current_source(mbhc, &mbhc->mbhc_bias_regs,
+ false, false);
if (removed) {
if (mbhc->mbhc_cfg->detect_extn_cable) {
@@ -2752,8 +3007,8 @@
* headphone detection.
*/
if (current_source_enable)
- wcd9xxx_turn_onoff_current_source(mbhc, true,
- false);
+ wcd9xxx_turn_onoff_current_source(mbhc, &mbhc->mbhc_bias_regs,
+ true, false);
else
wcd9xxx_turn_onoff_override(mbhc, true);
@@ -2811,6 +3066,14 @@
} else if (plug_type == PLUG_TYPE_HIGH_HPH) {
pr_debug("%s: High HPH detected, continue polling\n",
__func__);
+ if (mbhc->mbhc_cfg->detect_extn_cable) {
+ if (mbhc->current_plug != plug_type)
+ wcd9xxx_report_plug(mbhc, 1,
+ SND_JACK_LINEOUT);
+ } else if (mbhc->current_plug == PLUG_TYPE_NONE) {
+ wcd9xxx_report_plug(mbhc, 1,
+ SND_JACK_HEADPHONE);
+ }
} else {
if (plug_type == PLUG_TYPE_GND_MIC_SWAP) {
pt_gnd_mic_swap_cnt++;
@@ -2837,8 +3100,9 @@
WCD9XXX_BCL_LOCK(mbhc->resmgr);
/* Turn off override/current source */
if (current_source_enable)
- wcd9xxx_turn_onoff_current_source(mbhc, false,
- false);
+ wcd9xxx_turn_onoff_current_source(mbhc,
+ &mbhc->mbhc_bias_regs,
+ false, false);
else
wcd9xxx_turn_onoff_override(mbhc, false);
/*
@@ -2864,7 +3128,8 @@
}
if (!correction && current_source_enable)
- wcd9xxx_turn_onoff_current_source(mbhc, false, highhph);
+ wcd9xxx_turn_onoff_current_source(mbhc, &mbhc->mbhc_bias_regs,
+ false, highhph);
else if (!correction)
wcd9xxx_turn_onoff_override(mbhc, false);
@@ -2906,16 +3171,15 @@
if (wcd9xxx_cancel_btn_work(mbhc))
pr_debug("%s: button press is canceled\n", __func__);
- /* cancel detect plug */
- wcd9xxx_cancel_hs_detect_plug(mbhc,
- &mbhc->correct_plug_swch);
-
insert = !wcd9xxx_swch_level_remove(mbhc);
pr_debug("%s: Current plug type %d, insert %d\n", __func__,
mbhc->current_plug, insert);
if ((mbhc->current_plug == PLUG_TYPE_NONE) && insert) {
mbhc->lpi_enabled = false;
wmb();
+ /* cancel detect plug */
+ wcd9xxx_cancel_hs_detect_plug(mbhc,
+ &mbhc->correct_plug_swch);
if ((mbhc->current_plug != PLUG_TYPE_NONE) &&
!(snd_soc_read(codec, WCD9XXX_A_MBHC_INSERT_DETECT) &
@@ -2930,6 +3194,9 @@
} else if ((mbhc->current_plug != PLUG_TYPE_NONE) && !insert) {
mbhc->lpi_enabled = false;
wmb();
+ /* cancel detect plug */
+ wcd9xxx_cancel_hs_detect_plug(mbhc,
+ &mbhc->correct_plug_swch);
if (mbhc->current_plug == PLUG_TYPE_HEADPHONE) {
wcd9xxx_report_plug(mbhc, 0, SND_JACK_HEADPHONE);
@@ -2946,6 +3213,12 @@
} else if (mbhc->current_plug == PLUG_TYPE_HIGH_HPH) {
wcd9xxx_report_plug(mbhc, 0, SND_JACK_LINEOUT);
is_removed = true;
+ } else if (mbhc->current_plug == PLUG_TYPE_ANC_HEADPHONE) {
+ wcd9xxx_pause_hs_polling(mbhc);
+ wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, false);
+ wcd9xxx_cleanup_hs_polling(mbhc);
+ wcd9xxx_report_plug(mbhc, 0, SND_JACK_ANC_HEADPHONE);
+ is_removed = true;
}
if (is_removed) {
@@ -3106,7 +3379,9 @@
return mask;
}
-static void wcd9xxx_get_z(struct wcd9xxx_mbhc *mbhc, s16 *dce_z, s16 *sta_z)
+static void wcd9xxx_get_z(struct wcd9xxx_mbhc *mbhc, s16 *dce_z, s16 *sta_z,
+ struct mbhc_micbias_regs *micb_regs,
+ bool norel_detection)
{
s16 reg0, reg1;
int change;
@@ -3114,21 +3389,21 @@
WCD9XXX_BCL_ASSERT_LOCKED(mbhc->resmgr);
/* Pull down micbias to ground and disconnect vddio switch */
- reg0 = snd_soc_read(codec, mbhc->mbhc_bias_regs.ctl_reg);
- snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.ctl_reg, 0x81, 0x1);
- reg1 = snd_soc_read(codec, mbhc->mbhc_bias_regs.mbhc_reg);
- snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.mbhc_reg, 1 << 7, 0);
+ reg0 = snd_soc_read(codec, micb_regs->ctl_reg);
+ snd_soc_update_bits(codec, micb_regs->ctl_reg, 0x81, 0x1);
+ reg1 = snd_soc_read(codec, micb_regs->mbhc_reg);
+ snd_soc_update_bits(codec, micb_regs->mbhc_reg, 1 << 7, 0);
/* Disconnect override from micbias */
change = snd_soc_update_bits(codec, WCD9XXX_A_MAD_ANA_CTRL, 1 << 4,
1 << 0);
usleep_range(1000, 1000 + 1000);
if (sta_z) {
- *sta_z = wcd9xxx_codec_sta_dce(mbhc, 0, false);
+ *sta_z = wcd9xxx_codec_sta_dce(mbhc, 0, norel_detection);
pr_debug("%s: sta_z 0x%x\n", __func__, *sta_z & 0xFFFF);
}
if (dce_z) {
- *dce_z = wcd9xxx_codec_sta_dce(mbhc, 1, false);
+ *dce_z = wcd9xxx_codec_sta_dce(mbhc, 1, norel_detection);
pr_debug("%s: dce_z 0x%x\n", __func__, *dce_z & 0xFFFF);
}
@@ -3137,16 +3412,22 @@
snd_soc_update_bits(codec, WCD9XXX_A_MAD_ANA_CTRL, 1 << 4,
1 << 4);
/* Disable pull down micbias to ground */
- snd_soc_write(codec, mbhc->mbhc_bias_regs.mbhc_reg, reg1);
- snd_soc_write(codec, mbhc->mbhc_bias_regs.ctl_reg, reg0);
+ snd_soc_write(codec, micb_regs->mbhc_reg, reg1);
+ snd_soc_write(codec, micb_regs->ctl_reg, reg0);
}
+/*
+ * This function recalibrates dce_z and sta_z parameters.
+ * No release detection will be false when this function is
+ * used.
+ */
void wcd9xxx_update_z(struct wcd9xxx_mbhc *mbhc)
{
const u16 sta_z = mbhc->mbhc_data.sta_z;
const u16 dce_z = mbhc->mbhc_data.dce_z;
- wcd9xxx_get_z(mbhc, &mbhc->mbhc_data.dce_z, &mbhc->mbhc_data.sta_z);
+ wcd9xxx_get_z(mbhc, &mbhc->mbhc_data.dce_z, &mbhc->mbhc_data.sta_z,
+ &mbhc->mbhc_bias_regs, false);
pr_debug("%s: sta_z 0x%x,dce_z 0x%x -> sta_z 0x%x,dce_z 0x%x\n",
__func__, sta_z & 0xFFFF, dce_z & 0xFFFF,
mbhc->mbhc_data.sta_z & 0xFFFF,
@@ -3593,7 +3874,7 @@
* turn on the external voltage source for Calibration.
*/
if (mbhc->mbhc_cb && mbhc->mbhc_cb->enable_mb_source)
- mbhc->mbhc_cb->enable_mb_source(codec, true);
+ mbhc->mbhc_cb->enable_mb_source(codec, true, false);
cfilt_mode = snd_soc_read(codec, mbhc->mbhc_bias_regs.cfilt_ctl);
if (mbhc->mbhc_cb && mbhc->mbhc_cb->cfilt_fast_mode)
@@ -3715,7 +3996,7 @@
usleep_range(100, 100);
if (mbhc->mbhc_cb && mbhc->mbhc_cb->enable_mb_source)
- mbhc->mbhc_cb->enable_mb_source(codec, false);
+ mbhc->mbhc_cb->enable_mb_source(codec, false, false);
wcd9xxx_enable_irq(mbhc->resmgr->core_res,
mbhc->intr_ids->dce_est_complete);
@@ -4063,7 +4344,10 @@
mbhc->mbhc_cfg = mbhc_cfg;
/* Get HW specific mbhc registers' address */
- wcd9xxx_get_mbhc_micbias_regs(mbhc, &mbhc->mbhc_bias_regs);
+ wcd9xxx_get_mbhc_micbias_regs(mbhc, MBHC_PRIMARY_MIC_MB);
+
+ /* Get HW specific mbhc registers' address for anc */
+ wcd9xxx_get_mbhc_micbias_regs(mbhc, MBHC_ANC_MIC_MB);
/* Put CFILT in fast mode by default */
if (mbhc->mbhc_cb && mbhc->mbhc_cb->cfilt_fast_mode)
@@ -4278,7 +4562,7 @@
}
if (mbhc->micbias_enable && mbhc->polling_active &&
!(snd_soc_read(mbhc->codec, mbhc->mbhc_bias_regs.ctl_reg)
- & 0x80)) {
+ & 0x80)) {
pr_debug("%s:Micbias turned off by recording, set up again",
__func__);
snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.ctl_reg,
@@ -4439,6 +4723,7 @@
s16 *z[] = {
&l[0], &r[0], &r[1], &l[1], &l[2], &r[2],
};
+ bool override_en;
struct snd_soc_codec *codec = mbhc->codec;
const int mux_wait_us = 25;
const struct wcd9xxx_reg_mask_val reg_set_mux[] = {
@@ -4475,7 +4760,10 @@
wcd9xxx_onoff_ext_mclk(mbhc, true);
- wcd9xxx_turn_onoff_override(mbhc, true);
+ override_en = (snd_soc_read(codec, WCD9XXX_A_CDC_MBHC_B1_CTL) & 0x04) ?
+ true : false;
+ if (!override_en)
+ wcd9xxx_turn_onoff_override(mbhc, true);
pr_debug("%s: Setting impedance detection\n", __func__);
/* Codec specific setup for L0, R0, L1 and R1 measurements */
@@ -4523,7 +4811,8 @@
wcd9xxx_onoff_ext_mclk(mbhc, false);
- wcd9xxx_turn_onoff_override(mbhc, false);
+ if (!override_en)
+ wcd9xxx_turn_onoff_override(mbhc, false);
mbhc->mbhc_cb->compute_impedance(l, r, zl, zr);
pr_debug("%s: L0: 0x%x(%d), L1: 0x%x(%d), L2: 0x%x(%d)\n",
@@ -4541,10 +4830,8 @@
int wcd9xxx_mbhc_get_impedance(struct wcd9xxx_mbhc *mbhc, uint32_t *zl,
uint32_t *zr)
{
- WCD9XXX_BCL_LOCK(mbhc->resmgr);
*zl = mbhc->zl;
*zr = mbhc->zr;
- WCD9XXX_BCL_UNLOCK(mbhc->resmgr);
if (*zl && *zr)
return 0;
@@ -4559,7 +4846,8 @@
*/
int wcd9xxx_mbhc_init(struct wcd9xxx_mbhc *mbhc, struct wcd9xxx_resmgr *resmgr,
struct snd_soc_codec *codec,
- int (*micbias_enable_cb) (struct snd_soc_codec*, bool),
+ int (*micbias_enable_cb) (struct snd_soc_codec*, bool,
+ enum wcd9xxx_micbias_num),
const struct wcd9xxx_mbhc_cb *mbhc_cb,
const struct wcd9xxx_mbhc_intr *mbhc_cdc_intr_ids,
int rco_clk_rate,
diff --git a/sound/soc/codecs/wcd9xxx-mbhc.h b/sound/soc/codecs/wcd9xxx-mbhc.h
index b5031a6..cf25798 100644
--- a/sound/soc/codecs/wcd9xxx-mbhc.h
+++ b/sound/soc/codecs/wcd9xxx-mbhc.h
@@ -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
@@ -78,6 +78,12 @@
PLUG_TYPE_HEADPHONE,
PLUG_TYPE_HIGH_HPH,
PLUG_TYPE_GND_MIC_SWAP,
+ PLUG_TYPE_ANC_HEADPHONE,
+};
+
+enum wcd9xxx_mbhc_micbias_type {
+ MBHC_PRIMARY_MIC_MB,
+ MBHC_ANC_MIC_MB,
};
enum wcd9xxx_micbias_num {
@@ -88,6 +94,12 @@
MBHC_MICBIAS4,
};
+enum hw_jack_type {
+ FOUR_POLE_JACK = 0,
+ FIVE_POLE_JACK,
+ SIX_POLE_JACK,
+};
+
enum wcd9xx_mbhc_micbias_enable_bits {
MBHC_MICBIAS_ENABLE_THRESHOLD_HEADSET,
MBHC_MICBIAS_ENABLE_REGULAR_HEADSET,
@@ -97,6 +109,7 @@
MBHC_CS_ENABLE_POLLING,
MBHC_CS_ENABLE_INSERTION,
MBHC_CS_ENABLE_REMOVAL,
+ MBHC_CS_ENABLE_DET_ANC,
};
enum wcd9xxx_mbhc_state {
@@ -217,6 +230,7 @@
*/
void *calibration;
enum wcd9xxx_micbias_num micbias;
+ enum wcd9xxx_micbias_num anc_micbias;
int (*mclk_cb_fn) (struct snd_soc_codec*, int, bool);
unsigned int mclk_rate;
unsigned int gpio;
@@ -232,6 +246,8 @@
bool use_int_rbias;
bool do_recalibration;
bool use_vddio_meas;
+ bool enable_anc_mic_detect;
+ enum hw_jack_type hw_jack_type;
};
struct wcd9xxx_cfilt_mode {
@@ -266,7 +282,7 @@
enum mbhc_impedance_detect_stages stage);
void (*compute_impedance) (s16 *, s16 *, uint32_t *, uint32_t *);
void (*enable_mbhc_txfe) (struct snd_soc_codec *, bool);
- int (*enable_mb_source) (struct snd_soc_codec *, bool);
+ int (*enable_mb_source) (struct snd_soc_codec *, bool, bool);
void (*setup_int_rbias) (struct snd_soc_codec *, bool);
void (*pull_mb_to_vddio) (struct snd_soc_codec *, bool);
};
@@ -283,6 +299,8 @@
struct mbhc_internal_cal_data mbhc_data;
struct mbhc_micbias_regs mbhc_bias_regs;
+ struct mbhc_micbias_regs mbhc_anc_bias_regs;
+
bool mbhc_micbias_switched;
u32 hph_status; /* track headhpone status */
@@ -331,7 +349,8 @@
struct notifier_block nblock;
bool micbias_enable;
- int (*micbias_enable_cb) (struct snd_soc_codec*, bool);
+ int (*micbias_enable_cb) (struct snd_soc_codec*, bool,
+ enum wcd9xxx_micbias_num);
bool impedance_detect;
/* impedance of hphl and hphr */
@@ -340,6 +359,8 @@
u32 rco_clk_rate;
bool update_z;
+
+ u8 scaling_mux_in;
/* Holds codec specific interrupt mapping */
const struct wcd9xxx_mbhc_intr *intr_ids;
@@ -409,7 +430,8 @@
void wcd9xxx_mbhc_stop(struct wcd9xxx_mbhc *mbhc);
int wcd9xxx_mbhc_init(struct wcd9xxx_mbhc *mbhc, struct wcd9xxx_resmgr *resmgr,
struct snd_soc_codec *codec,
- int (*micbias_enable_cb) (struct snd_soc_codec*, bool),
+ int (*micbias_enable_cb) (struct snd_soc_codec*, bool,
+ enum wcd9xxx_micbias_num),
const struct wcd9xxx_mbhc_cb *mbhc_cb,
const struct wcd9xxx_mbhc_intr *mbhc_cdc_intr_ids,
int rco_clk_rate,
diff --git a/sound/soc/msm/apq8074.c b/sound/soc/msm/apq8074.c
index 5b12b9c..4e79109 100644
--- a/sound/soc/msm/apq8074.c
+++ b/sound/soc/msm/apq8074.c
@@ -1812,7 +1812,7 @@
.name = "MSM8974 Compr",
.stream_name = "COMPR",
.cpu_dai_name = "MultiMedia4",
- .platform_name = "msm-compr-dsp",
+ .platform_name = "msm-compress-dsp",
.dynamic = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
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/msm8226.c b/sound/soc/msm/msm8226.c
index b4ae0a4..be0cb7f 100644
--- a/sound/soc/msm/msm8226.c
+++ b/sound/soc/msm/msm8226.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
@@ -82,6 +82,7 @@
.read_fw_bin = false,
.calibration = NULL,
.micbias = MBHC_MICBIAS2,
+ .anc_micbias = MBHC_MICBIAS2,
.mclk_cb_fn = msm_snd_enable_codec_ext_clk,
.mclk_rate = TAPAN_EXT_CLK_RATE,
.gpio = 0,
@@ -93,9 +94,12 @@
.swap_gnd_mic = NULL,
.cs_enable_flags = (1 << MBHC_CS_ENABLE_POLLING |
1 << MBHC_CS_ENABLE_INSERTION |
- 1 << MBHC_CS_ENABLE_REMOVAL),
+ 1 << MBHC_CS_ENABLE_REMOVAL |
+ 1 << MBHC_CS_ENABLE_DET_ANC),
.do_recalibration = true,
.use_vddio_meas = true,
+ .enable_anc_mic_detect = false,
+ .hw_jack_type = FOUR_POLE_JACK,
};
struct msm_auxpcm_gpio {
@@ -2042,6 +2046,8 @@
struct msm8226_asoc_mach_data *pdata;
int ret;
const char *auxpcm_pri_gpio_set = NULL;
+ const char *mbhc_audio_jack_type = NULL;
+ size_t n = strlen("4-pole-jack");
if (!pdev->dev.of_node) {
dev_err(&pdev->dev, "No platform supplied from device tree\n");
@@ -2107,6 +2113,35 @@
mbhc_cfg.gpio_level_insert = of_property_read_bool(pdev->dev.of_node,
"qcom,headset-jack-type-NC");
+ ret = of_property_read_string(pdev->dev.of_node,
+ "qcom,mbhc-audio-jack-type", &mbhc_audio_jack_type);
+ if (ret) {
+ dev_dbg(&pdev->dev, "Looking up %s property in node %s failed",
+ "qcom,mbhc-audio-jack-type",
+ pdev->dev.of_node->full_name);
+ mbhc_cfg.hw_jack_type = FOUR_POLE_JACK;
+ mbhc_cfg.enable_anc_mic_detect = false;
+ dev_dbg(&pdev->dev, "Jack type properties set to default");
+ } else {
+ if (!strncmp(mbhc_audio_jack_type, "4-pole-jack", n)) {
+ mbhc_cfg.hw_jack_type = FOUR_POLE_JACK;
+ mbhc_cfg.enable_anc_mic_detect = false;
+ dev_dbg(&pdev->dev, "This hardware has 4 pole jack");
+ } else if (!strncmp(mbhc_audio_jack_type, "5-pole-jack", n)) {
+ mbhc_cfg.hw_jack_type = FIVE_POLE_JACK;
+ mbhc_cfg.enable_anc_mic_detect = true;
+ dev_dbg(&pdev->dev, "This hardware has 5 pole jack");
+ } else if (!strncmp(mbhc_audio_jack_type, "6-pole-jack", n)) {
+ mbhc_cfg.hw_jack_type = SIX_POLE_JACK;
+ mbhc_cfg.enable_anc_mic_detect = true;
+ dev_dbg(&pdev->dev, "This hardware has 6 pole jack");
+ } else {
+ mbhc_cfg.hw_jack_type = FOUR_POLE_JACK;
+ mbhc_cfg.enable_anc_mic_detect = false;
+ dev_dbg(&pdev->dev, "Unknown value, hence setting to default");
+ }
+ }
+
ret = snd_soc_register_card(card);
if (ret == -EPROBE_DEFER)
goto err;
diff --git a/sound/soc/msm/msm8974.c b/sound/soc/msm/msm8974.c
index 9c00e95..0eea842 100644
--- a/sound/soc/msm/msm8974.c
+++ b/sound/soc/msm/msm8974.c
@@ -117,6 +117,7 @@
.read_fw_bin = false,
.calibration = NULL,
.micbias = MBHC_MICBIAS2,
+ .anc_micbias = MBHC_MICBIAS2,
.mclk_cb_fn = msm_snd_enable_codec_ext_clk,
.mclk_rate = TAIKO_EXT_CLK_RATE,
.gpio = 0,
@@ -128,9 +129,12 @@
.swap_gnd_mic = NULL,
.cs_enable_flags = (1 << MBHC_CS_ENABLE_POLLING |
1 << MBHC_CS_ENABLE_INSERTION |
- 1 << MBHC_CS_ENABLE_REMOVAL),
+ 1 << MBHC_CS_ENABLE_REMOVAL |
+ 1 << MBHC_CS_ENABLE_DET_ANC),
.do_recalibration = true,
.use_vddio_meas = true,
+ .enable_anc_mic_detect = false,
+ .hw_jack_type = SIX_POLE_JACK,
};
struct msm_auxpcm_gpio {
@@ -2713,6 +2717,8 @@
int ret;
const char *auxpcm_pri_gpio_set = NULL;
const char *prop_name_ult_lo_gpio = "qcom,ext-ult-lo-amp-gpio";
+ const char *mbhc_audio_jack_type = NULL;
+ size_t n = strlen("4-pole-jack");
struct resource *pri_muxsel;
struct resource *sec_muxsel;
@@ -2772,6 +2778,34 @@
if (ret)
goto err;
+ ret = of_property_read_string(pdev->dev.of_node,
+ "qcom,mbhc-audio-jack-type", &mbhc_audio_jack_type);
+ if (ret) {
+ dev_dbg(&pdev->dev, "Looking up %s property in node %s failed",
+ "qcom,mbhc-audio-jack-type",
+ pdev->dev.of_node->full_name);
+ mbhc_cfg.hw_jack_type = FOUR_POLE_JACK;
+ mbhc_cfg.enable_anc_mic_detect = false;
+ dev_dbg(&pdev->dev, "Jack type properties set to default");
+ } else {
+ if (!strncmp(mbhc_audio_jack_type, "4-pole-jack", n)) {
+ mbhc_cfg.hw_jack_type = FOUR_POLE_JACK;
+ mbhc_cfg.enable_anc_mic_detect = false;
+ dev_dbg(&pdev->dev, "This hardware has 4 pole jack");
+ } else if (!strncmp(mbhc_audio_jack_type, "5-pole-jack", n)) {
+ mbhc_cfg.hw_jack_type = FIVE_POLE_JACK;
+ mbhc_cfg.enable_anc_mic_detect = true;
+ dev_dbg(&pdev->dev, "This hardware has 5 pole jack");
+ } else if (!strncmp(mbhc_audio_jack_type, "6-pole-jack", n)) {
+ mbhc_cfg.hw_jack_type = SIX_POLE_JACK;
+ mbhc_cfg.enable_anc_mic_detect = true;
+ dev_dbg(&pdev->dev, "This hardware has 6 pole jack");
+ } else {
+ mbhc_cfg.hw_jack_type = FOUR_POLE_JACK;
+ mbhc_cfg.enable_anc_mic_detect = false;
+ dev_dbg(&pdev->dev, "Unknown value, hence setting to default");
+ }
+ }
if (of_property_read_bool(pdev->dev.of_node, "qcom,hdmi-audio-rx")) {
dev_info(&pdev->dev, "%s(): hdmi audio support present\n",
__func__);
diff --git a/sound/soc/msm/msm8x10.c b/sound/soc/msm/msm8x10.c
index 4eab965..7b3a028 100644
--- a/sound/soc/msm/msm8x10.c
+++ b/sound/soc/msm/msm8x10.c
@@ -106,6 +106,7 @@
1 << MBHC_CS_ENABLE_REMOVAL),
.do_recalibration = false,
.use_vddio_meas = false,
+ .hw_jack_type = FOUR_POLE_JACK,
};
/*
@@ -1050,6 +1051,8 @@
static __devinit int msm8x10_asoc_machine_probe(struct platform_device *pdev)
{
struct snd_soc_card *card = &snd_soc_card_msm8x10;
+ const char *mbhc_audio_jack_type = NULL;
+ size_t n = strlen("4-pole-jack");
int ret;
dev_dbg(&pdev->dev, "%s\n", __func__);
@@ -1087,6 +1090,35 @@
mbhc_cfg.use_int_rbias = of_property_read_bool(pdev->dev.of_node,
"qcom,mbhc-bias-internal");
+ ret = of_property_read_string(pdev->dev.of_node,
+ "qcom,mbhc-audio-jack-type", &mbhc_audio_jack_type);
+ if (ret) {
+ dev_dbg(&pdev->dev, "Looking up %s property in node %s failed",
+ "qcom,mbhc-audio-jack-type",
+ pdev->dev.of_node->full_name);
+ mbhc_cfg.hw_jack_type = FOUR_POLE_JACK;
+ mbhc_cfg.enable_anc_mic_detect = false;
+ dev_dbg(&pdev->dev, "Jack type properties set to default");
+ } else {
+ if (!strncmp(mbhc_audio_jack_type, "4-pole-jack", n)) {
+ mbhc_cfg.hw_jack_type = FOUR_POLE_JACK;
+ mbhc_cfg.enable_anc_mic_detect = false;
+ dev_dbg(&pdev->dev, "This hardware has 4 pole jack");
+ } else if (!strncmp(mbhc_audio_jack_type, "5-pole-jack", n)) {
+ mbhc_cfg.hw_jack_type = FIVE_POLE_JACK;
+ mbhc_cfg.enable_anc_mic_detect = true;
+ dev_dbg(&pdev->dev, "This hardware has 5 pole jack");
+ } else if (!strncmp(mbhc_audio_jack_type, "6-pole-jack", n)) {
+ mbhc_cfg.hw_jack_type = SIX_POLE_JACK;
+ mbhc_cfg.enable_anc_mic_detect = true;
+ dev_dbg(&pdev->dev, "This hardware has 6 pole jack");
+ } else {
+ mbhc_cfg.hw_jack_type = FOUR_POLE_JACK;
+ mbhc_cfg.enable_anc_mic_detect = false;
+ dev_dbg(&pdev->dev, "Unknown value, hence setting to default");
+ }
+ }
+
spdev = pdev;
ret = snd_soc_register_card(card);
diff --git a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
index d2352ff..41ef3e3 100644
--- a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
@@ -66,9 +66,22 @@
const DECLARE_TLV_DB_LINEAR(msm_compr_vol_gain, 0,
COMPRESSED_LR_VOL_MAX_STEPS);
+/*
+ * LSB 8 bits is used as stream id for some DSP
+ * commands for compressed playback.
+ */
+#define STREAM_ID_FROM_TOKEN(i) (i & 0xFF)
+
+/* Stream id switches between 1 and 2 */
+#define NEXT_STREAM_ID(stream_id) ((stream_id & 1) + 1)
+
+#define STREAM_ARRAY_INDEX(stream_id) (stream_id - 1)
+
+#define MAX_NUMBER_OF_STREAMS 2
+
struct msm_compr_gapless_state {
bool set_next_stream_id;
- int32_t stream_opened[2];
+ int32_t stream_opened[MAX_NUMBER_OF_STREAMS];
uint32_t initial_samples_drop;
uint32_t trailing_samples_drop;
uint32_t gapless_transition;
@@ -97,8 +110,10 @@
uint32_t app_pointer;
uint32_t buffer_size;
uint32_t byte_offset;
- uint32_t copied_total;
- uint32_t bytes_received;
+ uint32_t copied_total; /* bytes consumed by DSP */
+ uint32_t bytes_received; /* from userspace */
+ uint32_t bytes_sent; /* to DSP */
+
int32_t first_buffer;
int32_t last_buffer;
int32_t partial_drain_delay;
@@ -208,7 +223,8 @@
pr_debug("%s: bytes_received = %d copied_total = %d\n",
__func__, prtd->bytes_received, prtd->copied_total);
if (prtd->first_buffer && prtd->gapless_state.use_dsp_gapless_mode)
- q6asm_send_meta_data(prtd->audio_client,
+ q6asm_stream_send_meta_data(prtd->audio_client,
+ prtd->audio_client->stream_id,
prtd->gapless_state.initial_samples_drop,
prtd->gapless_state.trailing_samples_drop);
@@ -241,6 +257,7 @@
if (q6asm_async_write(prtd->audio_client, ¶m) < 0) {
pr_err("%s:q6asm_async_write failed\n", __func__);
} else {
+ prtd->bytes_sent += buffer_length;
if (prtd->first_buffer)
prtd->first_buffer = 0;
}
@@ -257,6 +274,7 @@
uint32_t chan_mode = 0;
uint32_t sample_rate = 0;
int bytes_available, stream_id;
+ uint32_t stream_index;
pr_debug("%s opcode =%08x\n", __func__, opcode);
switch (opcode) {
@@ -314,8 +332,10 @@
spin_unlock(&prtd->lock);
break;
case ASM_DATA_EVENT_RENDERED_EOS:
- pr_debug("ASM_DATA_CMDRSP_EOS\n");
spin_lock(&prtd->lock);
+ pr_debug("%s: ASM_DATA_CMDRSP_EOS token 0x%x,stream id %d\n",
+ __func__, token, STREAM_ID_FROM_TOKEN(token));
+ stream_id = STREAM_ID_FROM_TOKEN(token);
if (atomic_read(&prtd->eos) &&
!prtd->gapless_state.set_next_stream_id) {
pr_debug("ASM_DATA_CMDRSP_EOS wake up\n");
@@ -323,13 +343,22 @@
wake_up(&prtd->eos_wait);
}
atomic_set(&prtd->eos, 0);
- stream_id = ac->stream_id^1; /*prev stream */
+ stream_index = STREAM_ARRAY_INDEX(stream_id);
+ if (stream_index >= MAX_NUMBER_OF_STREAMS ||
+ stream_index < 0) {
+ pr_err("%s: Invalid stream index %d", __func__,
+ stream_index);
+ spin_unlock(&prtd->lock);
+ break;
+ }
+
if (prtd->gapless_state.set_next_stream_id &&
- prtd->gapless_state.stream_opened[stream_id]) {
- q6asm_stream_cmd_nowait(prtd->audio_client,
- CMD_CLOSE, stream_id);
+ prtd->gapless_state.stream_opened[stream_index]) {
+ pr_debug("%s: CMD_CLOSE stream_id %d\n",
+ __func__, stream_id);
+ q6asm_stream_cmd_nowait(ac, CMD_CLOSE, stream_id);
atomic_set(&prtd->close, 1);
- prtd->gapless_state.stream_opened[stream_id] = 0;
+ prtd->gapless_state.stream_opened[stream_index] = 0;
prtd->gapless_state.set_next_stream_id = false;
}
if (prtd->gapless_state.gapless_transition)
@@ -355,7 +384,7 @@
spin_lock(&prtd->lock);
/* FIXME: A state is a much better way of dealing with this */
- if (!prtd->copied_total) {
+ if (prtd->bytes_sent == 0) {
bytes_available = prtd->bytes_received - prtd->copied_total;
if (bytes_available < cstream->runtime->fragment_size) {
pr_debug("CMD_RUN_V2 Insufficient data to send. break out\n");
@@ -366,25 +395,35 @@
spin_unlock(&prtd->lock);
break;
case ASM_STREAM_CMD_FLUSH:
- pr_debug("ASM_STREAM_CMD_FLUSH\n");
+ pr_debug("%s: ASM_STREAM_CMD_FLUSH:", __func__);
+ pr_debug("token 0x%x, stream id %d\n", token,
+ STREAM_ID_FROM_TOKEN(token));
prtd->cmd_ack = 1;
wake_up(&prtd->flush_wait);
break;
case ASM_DATA_CMD_REMOVE_INITIAL_SILENCE:
- pr_debug("ASM_DATA_CMD_REMOVE_INITIAL_SILENCE\n");
+ pr_debug("%s: ASM_DATA_CMD_REMOVE_INITIAL_SILENCE:",
+ __func__);
+ pr_debug("token 0x%x, stream id = %d\n", token,
+ STREAM_ID_FROM_TOKEN(token));
break;
case ASM_DATA_CMD_REMOVE_TRAILING_SILENCE:
- pr_debug("ASM_DATA_CMD_REMOVE_TRAILING_SILENCE\n");
+ pr_debug("%s: ASM_DATA_CMD_REMOVE_TRAILING_SILENCE:",
+ __func__);
+ pr_debug("token = 0x%x, stream id = %d\n", token,
+ STREAM_ID_FROM_TOKEN(token));
break;
case ASM_STREAM_CMD_CLOSE:
- pr_debug("ASM_DATA_CMD_CLOSE\n");
+ pr_debug("%s: ASM_DATA_CMD_CLOSE:", __func__);
+ pr_debug("token 0x%x, stream id %d\n", token,
+ STREAM_ID_FROM_TOKEN(token));
/*
* wakeup wait for stream avail on stream 3
* after stream 1 ends.
*/
if (prtd->next_stream) {
pr_debug("%s:CLOSE:wakeup wait for stream\n",
- __func__);
+ __func__);
prtd->stream_available = 1;
wake_up(&prtd->wait_for_stream_avail);
prtd->next_stream = 0;
@@ -402,10 +441,12 @@
break;
}
case ASM_SESSION_CMDRSP_GET_SESSIONTIME_V3:
- pr_debug("ASM_SESSION_CMDRSP_GET_SESSIONTIME_V3\n");
+ pr_debug("%s: ASM_SESSION_CMDRSP_GET_SESSIONTIME_V3\n",
+ __func__);
break;
case RESET_EVENTS:
- pr_err("Received reset events CB, move to error state");
+ pr_err("%s: Received reset events CB, move to error state",
+ __func__);
spin_lock(&prtd->lock);
snd_compr_fragment_elapsed(cstream);
prtd->copied_total = prtd->bytes_received;
@@ -413,7 +454,8 @@
spin_unlock(&prtd->lock);
break;
default:
- pr_debug("Not Supported Event opcode[0x%x]\n", opcode);
+ pr_debug("%s: Not Supported Event opcode[0x%x]\n",
+ __func__, opcode);
break;
}
}
@@ -483,6 +525,7 @@
uint16_t bits_per_sample = 16;
int dir = IN, ret = 0;
struct audio_client *ac = prtd->audio_client;
+ uint32_t stream_index;
struct asm_softpause_params softpause = {
.enable = SOFT_PAUSE_ENABLE,
.period = SOFT_PAUSE_PERIOD,
@@ -495,7 +538,7 @@
.rampingcurve = SOFT_VOLUME_CURVE_LINEAR,
};
- pr_debug("%s\n", __func__);
+ pr_debug("%s: stream_id %d\n", __func__, ac->stream_id);
ret = q6asm_stream_open_write_v2(ac,
prtd->codec, bits_per_sample,
ac->stream_id,
@@ -505,7 +548,13 @@
return -ENOMEM;
}
- prtd->gapless_state.stream_opened[ac->stream_id] = 1;
+ stream_index = STREAM_ARRAY_INDEX(ac->stream_id);
+ if (stream_index >= MAX_NUMBER_OF_STREAMS || stream_index < 0) {
+ pr_err("%s: Invalid stream index:%d", __func__, stream_index);
+ return -EINVAL;
+ }
+
+ prtd->gapless_state.stream_opened[stream_index] = 1;
pr_debug("%s be_id %d\n", __func__, soc_prtd->dai_link->be_id);
msm_pcm_routing_reg_phy_stream(soc_prtd->dai_link->be_id,
ac->perf_mode,
@@ -526,7 +575,7 @@
pr_err("%s: Send SoftVolume Param failed ret=%d\n",
__func__, ret);
- ret = q6asm_set_io_mode(ac, (COMPRESSED_IO | ASYNC_IO_MODE));
+ ret = q6asm_set_io_mode(ac, (COMPRESSED_STREAM_IO | ASYNC_IO_MODE));
if (ret < 0) {
pr_err("%s: Set IO mode failed\n", __func__);
return -EINVAL;
@@ -549,6 +598,7 @@
prtd->copied_total = 0;
prtd->app_pointer = 0;
prtd->bytes_received = 0;
+ prtd->bytes_sent = 0;
prtd->buffer = ac->port[dir].buf[0].data;
prtd->buffer_paddr = ac->port[dir].buf[0].phys;
prtd->buffer_size = runtime->fragments * runtime->fragment_size;
@@ -607,6 +657,7 @@
prtd->session_id = prtd->audio_client->session;
prtd->codec = FORMAT_MP3;
prtd->bytes_received = 0;
+ prtd->bytes_sent = 0;
prtd->copied_total = 0;
prtd->byte_offset = 0;
prtd->sample_rate = 44100;
@@ -668,6 +719,7 @@
struct audio_client *ac = prtd->audio_client;
int dir = IN, ret = 0, stream_id;
unsigned long flags;
+ uint32_t stream_index;
pr_debug("%s\n", __func__);
@@ -688,13 +740,19 @@
spin_lock_irqsave(&prtd->lock, flags);
stream_id = ac->stream_id;
- if (prtd->gapless_state.stream_opened[stream_id^1]) {
+ stream_index = STREAM_ARRAY_INDEX(NEXT_STREAM_ID(stream_id));
+
+ if ((stream_index < MAX_NUMBER_OF_STREAMS && stream_index >= 0) &&
+ (prtd->gapless_state.stream_opened[stream_index])) {
spin_unlock_irqrestore(&prtd->lock, flags);
- pr_debug(" close stream %d", stream_id^1);
- q6asm_stream_cmd(ac, CMD_CLOSE, stream_id^1);
+ pr_debug(" close stream %d", NEXT_STREAM_ID(stream_id));
+ q6asm_stream_cmd(ac, CMD_CLOSE, NEXT_STREAM_ID(stream_id));
spin_lock_irqsave(&prtd->lock, flags);
}
- if (prtd->gapless_state.stream_opened[stream_id]) {
+
+ stream_index = STREAM_ARRAY_INDEX(stream_id);
+ if ((stream_index < MAX_NUMBER_OF_STREAMS && stream_index >= 0) &&
+ (prtd->gapless_state.stream_opened[stream_index])) {
spin_unlock_irqrestore(&prtd->lock, flags);
pr_debug("close stream %d", stream_id);
q6asm_stream_cmd(ac, CMD_CLOSE, stream_id);
@@ -714,8 +772,6 @@
pr_debug("%s: ocmem_req: %d\n", __func__,
atomic_read(&pdata->audio_ocmem_req));
- /* client buf alloc was with stream id 0, so free with the same */
- ac->stream_id = 0;
q6asm_audio_client_buf_free_contiguous(dir, ac);
q6asm_audio_client_free(ac);
@@ -887,6 +943,7 @@
int bytes_to_write;
unsigned long flags;
int stream_id;
+ uint32_t stream_index;
if (cstream->direction != SND_COMPRESS_PLAYBACK) {
pr_err("%s: Unsupported stream type\n", __func__);
@@ -939,9 +996,9 @@
atomic_set(&prtd->drain, 0);
}
prtd->last_buffer = 0;
- pr_debug("issue CMD_FLUSH\n");
prtd->cmd_ack = 0;
if (!prtd->gapless_state.gapless_transition) {
+ pr_debug("issue CMD_FLUSH stream_id %d\n", stream_id);
spin_unlock_irqrestore(&prtd->lock, flags);
rc = q6asm_stream_cmd(
prtd->audio_client, CMD_FLUSH, stream_id);
@@ -967,6 +1024,8 @@
prtd->copied_total = 0;
prtd->app_pointer = 0;
prtd->bytes_received = 0;
+ prtd->bytes_sent = 0;
+
atomic_set(&prtd->xrun, 0);
spin_unlock_irqrestore(&prtd->lock, flags);
break;
@@ -974,7 +1033,9 @@
pr_debug("SNDRV_PCM_TRIGGER_PAUSE_PUSH transition %d\n",
prtd->gapless_state.gapless_transition);
if (!prtd->gapless_state.gapless_transition) {
- q6asm_cmd_nowait(prtd->audio_client, CMD_PAUSE);
+ pr_debug("issue CMD_PAUSE stream_id %d\n",
+ ac->stream_id);
+ q6asm_stream_cmd_nowait(ac, CMD_PAUSE, ac->stream_id);
atomic_set(&prtd->start, 0);
}
break;
@@ -1050,7 +1111,8 @@
/* send EOS */
prtd->cmd_ack = 0;
- q6asm_cmd_nowait(prtd->audio_client, CMD_EOS);
+ pr_debug("issue CMD_EOS stream_id %d\n", ac->stream_id);
+ q6asm_stream_cmd_nowait(ac, CMD_EOS, ac->stream_id);
pr_info("PARTIAL DRAIN, do not wait for EOS ack\n");
/* send a zero length buffer */
@@ -1087,8 +1149,9 @@
}
/* move to next stream and reset vars */
- pr_debug("%s: Moving to next stream in gapless\n", __func__);
- ac->stream_id ^= 1;
+ pr_debug("%s: Moving to next stream in gapless\n",
+ __func__);
+ ac->stream_id = NEXT_STREAM_ID(ac->stream_id);
prtd->byte_offset = 0;
prtd->app_pointer = 0;
prtd->first_buffer = 1;
@@ -1115,11 +1178,11 @@
stream can be used for gapless playback
*/
prtd->gapless_state.set_next_stream_id = false;
- pr_debug("%s: CMD_EOS\n", __func__);
+ pr_debug("%s:CMD_EOS stream_id %d\n", __func__, ac->stream_id);
prtd->cmd_ack = 0;
atomic_set(&prtd->eos, 1);
- q6asm_cmd_nowait(prtd->audio_client, CMD_EOS);
+ q6asm_stream_cmd_nowait(ac, CMD_EOS, ac->stream_id);
spin_unlock_irqrestore(&prtd->lock, flags);
@@ -1131,7 +1194,8 @@
if (rc < 0)
pr_err("%s: EOS wait failed\n", __func__);
- pr_debug("%s: SNDRV_COMPRESS_DRAIN out of wait for EOS\n", __func__);
+ pr_debug("%s: SNDRV_COMPRESS_DRAIN out of wait for EOS\n",
+ __func__);
if (prtd->cmd_interrupt)
rc = -EINTR;
@@ -1143,12 +1207,14 @@
* so prepare the current stream in session for gapless playback
*/
spin_lock_irqsave(&prtd->lock, flags);
- pr_debug("%s: issue CMD_PAUSE ", __func__);
- q6asm_cmd_nowait(prtd->audio_client, CMD_PAUSE);
+ pr_debug("%s:issue CMD_PAUSE stream_id %d",
+ __func__, ac->stream_id);
+ q6asm_stream_cmd_nowait(ac, CMD_PAUSE, ac->stream_id);
prtd->cmd_ack = 0;
spin_unlock_irqrestore(&prtd->lock, flags);
- pr_debug("%s: issue CMD_FLUSH", __func__);
- q6asm_cmd(prtd->audio_client, CMD_FLUSH);
+ pr_debug("%s:issue CMD_FLUSH ac->stream_id %d",
+ __func__, ac->stream_id);
+ q6asm_stream_cmd(ac, CMD_FLUSH, ac->stream_id);
wait_event_timeout(prtd->flush_wait,
prtd->cmd_ack, 1 * HZ / 4);
@@ -1160,8 +1226,11 @@
in the next avail() ioctl
prtd->copied_total = 0;
prtd->bytes_received = 0;
+ do not reset prtd->bytes_sent as well as the same
+ session is used for gapless playback
*/
prtd->byte_offset = 0;
+
prtd->app_pointer = 0;
prtd->first_buffer = 1;
prtd->last_buffer = 0;
@@ -1181,14 +1250,25 @@
pr_debug("%s: SND_COMPR_TRIGGER_NEXT_TRACK\n", __func__);
spin_lock_irqsave(&prtd->lock, flags);
rc = 0;
- stream_id = ac->stream_id^1; /*next stream in gapless*/
+ /* next stream in gapless */
+ stream_id = NEXT_STREAM_ID(ac->stream_id);
/*
* Wait if stream 1 has not completed before honoring next
* track for stream 3. Scenario happens if second clip is
* small and fills in one buffer so next track will be
* called immediately.
*/
- if (prtd->gapless_state.stream_opened[stream_id]) {
+ stream_index = STREAM_ARRAY_INDEX(stream_id);
+ if (stream_index >= MAX_NUMBER_OF_STREAMS ||
+ stream_index < 0) {
+ pr_err("%s: Invalid stream index: %d", __func__,
+ stream_index);
+ spin_unlock_irqrestore(&prtd->lock, flags);
+ rc = -EINVAL;
+ break;
+ }
+
+ if (prtd->gapless_state.stream_opened[stream_index]) {
if (prtd->gapless_state.gapless_transition) {
rc = msm_compr_wait_for_stream_avail(prtd,
&flags);
@@ -1219,6 +1299,7 @@
}
break;
}
+ pr_debug("%s: open_write stream_id %d", __func__, stream_id);
rc = q6asm_stream_open_write_v2(prtd->audio_client,
prtd->codec, 16,
stream_id,
@@ -1235,7 +1316,7 @@
break;
}
spin_lock_irqsave(&prtd->lock, flags);
- prtd->gapless_state.stream_opened[stream_id] = 1;
+ prtd->gapless_state.stream_opened[stream_index] = 1;
prtd->gapless_state.set_next_stream_id = true;
spin_unlock_irqrestore(&prtd->lock, flags);
break;
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 ee26f2e..7e0d03e 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -81,6 +81,7 @@
static int q6asm_map_channels(u8 *channel_mapping, uint32_t channels);
void *q6asm_mmap_apr_reg(void);
+static int q6asm_is_valid_session(struct apr_client_data *data, void *priv);
/* for ASM custom topology */
static struct audio_buffer common_buf[2];
@@ -132,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);
@@ -177,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,
@@ -292,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)
@@ -817,6 +839,8 @@
ac->io_mode = SYNC_IO_MODE;
ac->perf_mode = LEGACY_PCM_MODE;
ac->fptr_cache_ops = NULL;
+ /* DSP expects stream id from 1 */
+ ac->stream_id = 1;
ac->apr = apr_register("ADSP", "ASM", \
(apr_fn)q6asm_callback,\
((ac->session) << 8 | 0x0001),\
@@ -1213,6 +1237,7 @@
unsigned long dsp_flags;
uint32_t *payload;
uint32_t wakeup_flag = 1;
+ int32_t ret = 0;
if ((ac == NULL) || (data == NULL)) {
@@ -1279,11 +1304,10 @@
case ASM_SESSION_CMD_REGISTER_FORX_OVERFLOW_EVENTS:
case ASM_STREAM_CMD_FLUSH_READBUFS:
pr_debug("%s:Payload = [0x%x]\n", __func__, payload[0]);
- if (token != ac->session) {
- pr_err("%s:Invalid session[%d] rxed expected[%d]",
- __func__, token, ac->session);
- return -EINVAL;
- }
+ ret = q6asm_is_valid_session(data, priv);
+ if (ret != 0)
+ return ret;
+
case ASM_STREAM_CMD_OPEN_READ_V3:
case ASM_STREAM_CMD_OPEN_WRITE_V3:
case ASM_STREAM_CMD_OPEN_READWRITE_V2:
@@ -1590,8 +1614,8 @@
hdr->src_domain = APR_DOMAIN_APPS;
hdr->dest_svc = APR_SVC_ASM;
hdr->dest_domain = APR_DOMAIN_ADSP;
- hdr->src_port = ((ac->session << 8) & 0xFF00) | (stream_id+1);
- hdr->dest_port = ((ac->session << 8) & 0xFF00) | (stream_id+1);
+ hdr->src_port = ((ac->session << 8) & 0xFF00) | (stream_id);
+ hdr->dest_port = ((ac->session << 8) & 0xFF00) | (stream_id);
if (cmd_flg) {
hdr->token = ac->session;
atomic_set(&ac->cmd_state, 1);
@@ -1631,8 +1655,8 @@
hdr->src_domain = APR_DOMAIN_APPS;
hdr->dest_svc = APR_SVC_ASM;
hdr->dest_domain = APR_DOMAIN_ADSP;
- hdr->src_port = ((ac->session << 8) & 0xFF00) | (stream_id+1);
- hdr->dest_port = ((ac->session << 8) & 0xFF00) | (stream_id+1);
+ hdr->src_port = ((ac->session << 8) & 0xFF00) | (stream_id);
+ hdr->dest_port = ((ac->session << 8) & 0xFF00) | (stream_id);
if (cmd_flg) {
hdr->token = ac->session;
atomic_set(&ac->cmd_state, 1);
@@ -1810,6 +1834,17 @@
q6asm_stream_add_hdr(ac, &open.hdr, sizeof(open), TRUE, stream_id);
+ /*
+ * Updated the token field with stream/session for compressed playback
+ * Platform driver must know the the stream with which the command is
+ * associated
+ */
+ if (ac->io_mode & COMPRESSED_STREAM_IO)
+ open.hdr.token = ((ac->session << 8) & 0xFFFF00) |
+ (stream_id & 0xFF);
+
+ pr_debug("%s: token = 0x%x, stream_id %d, session 0x%x\n",
+ __func__, open.hdr.token, stream_id, ac->session);
open.hdr.opcode = ASM_STREAM_CMD_OPEN_WRITE_V3;
open.mode_flags = 0x00;
if (ac->perf_mode == ULTRA_LOW_LATENCY_PCM_MODE)
@@ -2765,6 +2800,17 @@
q6asm_stream_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE, stream_id);
+ /*
+ * Updated the token field with stream/session for compressed playback
+ * Platform driver must know the the stream with which the command is
+ * associated
+ */
+ if (ac->io_mode & COMPRESSED_STREAM_IO)
+ fmt.hdr.token = ((ac->session << 8) & 0xFFFF00) |
+ (stream_id & 0xFF);
+
+ pr_debug("%s: token = 0x%x, stream_id %d, session 0x%x\n",
+ __func__, fmt.hdr.token, stream_id, ac->session);
fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2;
fmt.fmt_blk.fmt_blk_size = sizeof(fmt) - sizeof(fmt.hdr) -
sizeof(fmt.fmt_blk);
@@ -3409,8 +3455,6 @@
vol.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2;
vol.param.data_payload_addr_lsw = 0;
vol.param.data_payload_addr_msw = 0;
-
-
vol.param.mem_map_handle = 0;
vol.param.data_payload_size = sizeof(vol) -
sizeof(vol.hdr) - sizeof(vol.param);
@@ -3440,6 +3484,7 @@
fail_cmd:
return rc;
}
+
int q6asm_set_softpause(struct audio_client *ac,
struct asm_softpause_params *pause_param)
{
@@ -3759,13 +3804,15 @@
u32 lbuf_addr_lsw;
u32 liomode;
u32 io_compressed;
+ u32 io_compressed_stream;
if (!ac || ac->apr == NULL) {
pr_err("%s: APR handle NULL\n", __func__);
return -EINVAL;
}
- q6asm_add_hdr_async(ac, &write.hdr, sizeof(write), FALSE);
+ q6asm_stream_add_hdr_async(
+ ac, &write.hdr, sizeof(write), FALSE, ac->stream_id);
port = &ac->port[IN];
ab = &port->buf[port->dsp_buf];
@@ -3780,10 +3827,12 @@
write.timestamp_lsw = param->lsw_ts;
liomode = (ASYNC_IO_MODE | NT_MODE);
io_compressed = (ASYNC_IO_MODE | COMPRESSED_IO);
+ io_compressed_stream = (ASYNC_IO_MODE | COMPRESSED_STREAM_IO);
if (ac->io_mode == liomode)
lbuf_addr_lsw = (write.buf_addr_lsw - 32);
- else if (ac->io_mode == io_compressed)
+ else if (ac->io_mode == io_compressed ||
+ ac->io_mode == io_compressed_stream)
lbuf_addr_lsw = (write.buf_addr_lsw - param->metadata_len);
else
lbuf_addr_lsw = write.buf_addr_lsw;
@@ -4113,6 +4162,17 @@
return -EINVAL;
}
q6asm_stream_add_hdr(ac, &hdr, sizeof(hdr), TRUE, stream_id);
+
+ /*
+ * Updated the token field with stream/session for compressed playback
+ * Platform driver must know the the stream with which the command is
+ * associated
+ */
+ if (ac->io_mode & COMPRESSED_STREAM_IO)
+ hdr.token = ((ac->session << 8) & 0xFFFF00) |
+ (stream_id & 0xFF);
+ pr_debug("%s: token = 0x%x, stream_id %d, session 0x%x\n",
+ __func__, hdr.token, stream_id, ac->session);
switch (cmd) {
case CMD_PAUSE:
pr_debug("%s:CMD_PAUSE\n", __func__);
@@ -4211,6 +4271,18 @@
return -EINVAL;
}
q6asm_stream_add_hdr_async(ac, &hdr, sizeof(hdr), TRUE, stream_id);
+
+ /*
+ * Updated the token field with stream/session for compressed playback
+ * Platform driver must know the the stream with which the command is
+ * associated
+ */
+ if (ac->io_mode & COMPRESSED_STREAM_IO)
+ hdr.token = ((ac->session << 8) & 0xFFFF00) |
+ (stream_id & 0xFF);
+
+ pr_debug("%s: token = 0x%x, stream_id %d, session 0x%x\n",
+ __func__, hdr.token, stream_id, ac->session);
switch (cmd) {
case CMD_PAUSE:
pr_debug("%s:CMD_PAUSE\n", __func__);
@@ -4257,17 +4329,30 @@
return __q6asm_cmd_nowait(ac, cmd, stream_id);
}
-int q6asm_send_meta_data(struct audio_client *ac, uint32_t initial_samples,
- uint32_t trailing_samples)
+int __q6asm_send_meta_data(struct audio_client *ac, uint32_t stream_id,
+ uint32_t initial_samples, uint32_t trailing_samples)
{
struct asm_data_cmd_remove_silence silence;
int rc = 0;
+
if (!ac || ac->apr == NULL) {
pr_err("APR handle NULL\n");
return -EINVAL;
}
pr_debug("%s session[%d]", __func__, ac->session);
- q6asm_add_hdr_async(ac, &silence.hdr, sizeof(silence), FALSE);
+ q6asm_stream_add_hdr_async(ac, &silence.hdr, sizeof(silence), FALSE,
+ stream_id);
+
+ /*
+ * Updated the token field with stream/session for compressed playback
+ * Platform driver must know the the stream with which the command is
+ * associated
+ */
+ if (ac->io_mode & COMPRESSED_STREAM_IO)
+ silence.hdr.token = ((ac->session << 8) & 0xFFFF00) |
+ (stream_id & 0xFF);
+ pr_debug("%s: token = 0x%x, stream_id %d, session 0x%x\n",
+ __func__, silence.hdr.token, stream_id, ac->session);
silence.hdr.opcode = ASM_DATA_CMD_REMOVE_INITIAL_SILENCE;
silence.num_samples_to_remove = initial_samples;
@@ -4292,6 +4377,20 @@
return -EINVAL;
}
+int q6asm_stream_send_meta_data(struct audio_client *ac, uint32_t stream_id,
+ uint32_t initial_samples, uint32_t trailing_samples)
+{
+ return __q6asm_send_meta_data(ac, stream_id, initial_samples,
+ trailing_samples);
+}
+
+int q6asm_send_meta_data(struct audio_client *ac, uint32_t initial_samples,
+ uint32_t trailing_samples)
+{
+ return __q6asm_send_meta_data(ac, ac->stream_id, initial_samples,
+ trailing_samples);
+}
+
static void q6asm_reset_buf_state(struct audio_client *ac)
{
int cnt = 0;
@@ -4395,6 +4494,34 @@
}
+static int q6asm_is_valid_session(struct apr_client_data *data, void *priv)
+{
+
+ struct audio_client *ac = (struct audio_client *)priv;
+ uint32_t token = data->token;
+
+ /*
+ * Some commands for compressed playback has token as session and
+ * other commands has session|stream. Check for both conditions
+ * before deciding if the callback was for a invalud session.
+ */
+ if (ac->io_mode & COMPRESSED_STREAM_IO) {
+ if ((token & 0xFFFFFF00) != ((ac->session << 8) & 0xFFFFFF00)
+ && (token != ac->session)) {
+ pr_err("%s:Invalid compr session[%d] rxed expected[%d]",
+ __func__, token, ac->session);
+ return -EINVAL;
+ }
+ } else {
+ if (token != ac->session) {
+ pr_err("%s:Invalid session[%d] rxed expected[%d]",
+ __func__, token, ac->session);
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
+
static int __init q6asm_init(void)
{
int lcnt;
diff --git a/sound/soc/msm/qdsp6v2/q6core.c b/sound/soc/msm/qdsp6v2/q6core.c
index e9352df..496a5ef 100644
--- a/sound/soc/msm/qdsp6v2/q6core.c
+++ b/sound/soc/msm/qdsp6v2/q6core.c
@@ -41,6 +41,11 @@
uint32_t nseg;
int i, j;
+ if (data == NULL) {
+ pr_err("%s: data argument is null\n", __func__);
+ return -EINVAL;
+ }
+
pr_debug("core msg: payload len = %u, apr resp opcode = 0x%X\n",
data->payload_size, data->opcode);
diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c
index 06ee692..61a262f 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.c
+++ b/sound/soc/msm/qdsp6v2/q6voice.c
@@ -3438,6 +3438,10 @@
mvm_handle = voice_get_mvm_handle(v);
cvp_handle = voice_get_cvp_handle(v);
+ /* disable slowtalk if st_enable is set */
+ if (v->st_enable)
+ voice_send_set_pp_enable_cmd(v, MODULE_ID_VOICE_MODULE_ST, 0);
+
/* stop playback or recording */
v->music_info.force = 1;
voice_cvs_stop_playback(v);
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
index 0970a83..4792719 100644
--- a/sound/soc/soc-compress.c
+++ b/sound/soc/soc-compress.c
@@ -475,7 +475,6 @@
struct snd_soc_pcm_runtime *fe = cstream->private_data;
struct snd_pcm_substream *fe_substream = fe->pcm->streams[0].substream;
struct snd_soc_platform *platform = fe->platform;
- struct snd_pcm_hw_params *hw_params;
int ret = 0, stream;
if (cstream->direction == SND_COMPRESS_PLAYBACK)
@@ -483,10 +482,6 @@
else
stream = SNDRV_PCM_STREAM_CAPTURE;
- hw_params = kzalloc(sizeof(*hw_params), GFP_KERNEL);
- if (hw_params == NULL)
- return -ENOMEM;
-
mutex_lock(&fe->card->dpcm_mutex);
/* first we call set_params for the platform driver
* this should configure the soc side